00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "simanager.h"
00015
00016 #include "siprofilehandler.h"
00017 #include "sihandler.h"
00018 #include "clientbase.h"
00019 #include "disco.h"
00020
00021 namespace gloox
00022 {
00023
00024 SIManager::SIManager( ClientBase* parent, bool advertise )
00025 : m_parent( parent ), m_advertise( advertise )
00026 {
00027 if( m_parent && m_advertise )
00028 {
00029 m_parent->registerIqHandler( this, XMLNS_SI );
00030 if( m_parent->disco() )
00031 m_parent->disco()->addFeature( XMLNS_SI );
00032 }
00033 }
00034
00035 SIManager::~SIManager()
00036 {
00037 if( m_parent && m_advertise )
00038 {
00039 m_parent->removeIqHandler( XMLNS_SI );
00040 m_parent->removeIDHandler( this );
00041 if( m_parent->disco() )
00042 m_parent->disco()->removeFeature( XMLNS_SI );
00043 }
00044 }
00045
00046 const std::string SIManager::requestSI( SIHandler* sih, const JID& to, const std::string& profile,
00047 Tag* child1, Tag* child2, const std::string& mimetype )
00048 {
00049 if( !m_parent || !sih )
00050 return std::string();
00051
00052 const std::string& id = m_parent->getID();
00053 const std::string& id2 = m_parent->getID();
00054
00055 Tag* iq = new Tag( "iq" );
00056 iq->addAttribute( "type", "set" );
00057 iq->addAttribute( "id", id );
00058 iq->addAttribute( "to", to.full() );
00059 Tag* si = new Tag( iq, "si" );
00060 si->addAttribute( "xmlns", XMLNS_SI );
00061 si->addAttribute( "id", id2 );
00062 if( mimetype.empty() )
00063 si->addAttribute( "mime-type", "binary/octet-stream" );
00064 else
00065 si->addAttribute( "mime-type", mimetype );
00066 si->addAttribute( "profile", profile );
00067
00068 si->addChild( child1 );
00069 si->addChild( child2 );
00070
00071 TrackStruct t;
00072 t.sid = id2;
00073 t.profile = profile;
00074 t.sih = sih;
00075 m_track[id] = t;
00076 m_parent->trackID( this, id, OfferSI );
00077 m_parent->send( iq );
00078
00079 return id2;
00080 }
00081
00082 void SIManager::acceptSI( const JID& to, const std::string& id, Tag* child1, Tag* child2 )
00083 {
00084 Tag* iq = new Tag( "iq" );
00085 iq->addAttribute( "id", id );
00086 iq->addAttribute( "to", to.full() );
00087 iq->addAttribute( "type", "result" );
00088 Tag* si = new Tag( iq, "si" );
00089 si->addAttribute( "xmlns", XMLNS_SI );
00090
00091 si->addChild( child1 );
00092 si->addChild( child2 );
00093
00094 m_parent->send( iq );
00095 }
00096
00097 void SIManager::declineSI( const JID& to, const std::string& id, SIError reason, const std::string& text )
00098 {
00099 Tag* iq = new Tag( "iq" );
00100 iq->addAttribute( "id", id );
00101 iq->addAttribute( "to", to.full() );
00102 iq->addAttribute( "type", "error" );
00103 Tag* error = new Tag( iq, "error" );
00104 if( reason == NoValidStreams || reason == BadProfile )
00105 {
00106 error->addAttribute( "code", "400" );
00107 error->addAttribute( "type", "cancel" );
00108 new Tag( error, "bad-request", "xmlns", XMLNS_XMPP_STANZAS );
00109 if( reason == NoValidStreams )
00110 new Tag( error, "no-valid-streams", "xmlns", XMLNS_SI );
00111 else if( reason == BadProfile )
00112 new Tag( error, "bad-profile", "xmlns", XMLNS_SI );
00113 }
00114 else
00115 {
00116 error->addAttribute( "code", "403" );
00117 error->addAttribute( "type", "cancel" );
00118 new Tag( error, "forbidden", "xmlns", XMLNS_XMPP_STANZAS );
00119 if( !text.empty() )
00120 {
00121 Tag* t = new Tag( error, "text", "xmlns", XMLNS_XMPP_STANZAS );
00122 t->setCData( text );
00123 }
00124 }
00125
00126 m_parent->send( iq );
00127 }
00128
00129 void SIManager::registerProfile( const std::string& profile, SIProfileHandler* sih )
00130 {
00131 if( !sih || profile.empty() )
00132 return;
00133
00134 m_handlers[profile] = sih;
00135
00136 if( m_parent && m_advertise && m_parent->disco() )
00137 m_parent->disco()->addFeature( profile );
00138 }
00139
00140 void SIManager::removeProfile( const std::string& profile )
00141 {
00142 if( profile.empty() )
00143 return;
00144
00145 m_handlers.erase( profile );
00146
00147 if( m_parent && m_advertise && m_parent->disco() )
00148 m_parent->disco()->removeFeature( profile );
00149 }
00150
00151 bool SIManager::handleIq( Stanza *stanza )
00152 {
00153 TrackMap::iterator it = m_track.find( stanza->id() );
00154 if( it != m_track.end() )
00155 return false;
00156
00157 Tag *si = stanza->findChild( "si", "xmlns", XMLNS_SI );
00158 if( si && si->hasAttribute( "profile" ) )
00159 {
00160 const std::string& profile = si->findAttribute( "profile" );
00161 HandlerMap::const_iterator it = m_handlers.find( profile );
00162 if( it != m_handlers.end() && (*it).second )
00163 {
00164 Tag* p = si->findChildWithAttrib( "xmlns", profile );
00165 Tag* f = si->findChild( "feature", "xmlns", XMLNS_FEATURE_NEG );
00166 (*it).second->handleSIRequest( stanza->from(), stanza->id(), profile, si, p, f );
00167 return true;
00168 }
00169 }
00170
00171 return false;
00172 }
00173
00174 bool SIManager::handleIqID( Stanza *stanza, int context )
00175 {
00176 switch( stanza->subtype() )
00177 {
00178 case StanzaIqResult:
00179 if( context == OfferSI )
00180 {
00181 TrackMap::iterator it = m_track.find( stanza->id() );
00182 if( it != m_track.end() )
00183 {
00184 Tag* si = stanza->findChild( "si", "xmlns", XMLNS_SI );
00185 Tag* ptag = 0;
00186 Tag* fneg = 0;
00187 if( si )
00188 {
00189 ptag = si->findChildWithAttrib( "xmlns", (*it).second.profile );
00190 fneg = si->findChild( "feature", "xmlns", XMLNS_FEATURE_NEG );
00191 }
00192 (*it).second.sih->handleSIRequestResult( stanza->from(), (*it).second.sid, si, ptag, fneg );
00193 m_track.erase( it );
00194 }
00195 return true;
00196 }
00197 break;
00198 case StanzaIqError:
00199 if( context == OfferSI )
00200 {
00201 TrackMap::iterator it = m_track.find( stanza->id() );
00202 if( it != m_track.end() )
00203 {
00204 (*it).second.sih->handleSIRequestError( stanza, (*it).second.sid );
00205 m_track.erase( it );
00206 }
00207 return true;
00208 }
00209 break;
00210 default:
00211 break;
00212 }
00213
00214 return false;
00215 }
00216
00217 }