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