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 #include "error.h"
00021
00022 namespace gloox
00023 {
00024
00025
00026 SIManager::SI::SI( const Tag* tag )
00027 : StanzaExtension( ExtSI ), m_tag1( 0 ), m_tag2( 0 )
00028 {
00029 if( !tag || tag->name() != "si" || tag->xmlns() != XMLNS_SI )
00030 return;
00031
00032 m_valid = true;
00033
00034 m_id = tag->findAttribute( "id" );
00035 m_mimetype = tag->findAttribute( "mime-type" );
00036 m_profile = tag->findAttribute( "profile" );
00037
00038 Tag* c = tag->findChild( "file", "xmlns", XMLNS_SI_FT );
00039 if ( c )
00040 m_tag1 = c->clone();
00041 c = tag->findChild( "feature", "xmlns", XMLNS_FEATURE_NEG );
00042 if( c )
00043 m_tag2 = c->clone();
00044 }
00045
00046 SIManager::SI::SI( Tag* tag1, Tag* tag2, const std::string& id,
00047 const std::string& mimetype, const std::string& profile )
00048 : StanzaExtension( ExtSI ), m_tag1( tag1 ), m_tag2( tag2 ),
00049 m_id( id ), m_mimetype( mimetype ), m_profile( profile )
00050 {
00051 m_valid = true;
00052 }
00053
00054 SIManager::SI::~SI()
00055 {
00056 delete m_tag1;
00057 delete m_tag2;
00058 }
00059
00060 const std::string& SIManager::SI::filterString() const
00061 {
00062 static const std::string& filter = "/iq/si[@xmlns='" + XMLNS_SI + "']";
00063 return filter;
00064 }
00065
00066 Tag* SIManager::SI::tag() const
00067 {
00068 if( !m_valid )
00069 return 0;
00070
00071 Tag* t = new Tag( "si" );
00072 t->setXmlns( XMLNS_SI );
00073 if( !m_id.empty() )
00074 t->addAttribute( "id", m_id );
00075 if( !m_mimetype.empty() )
00076 t->addAttribute( "mime-type", m_mimetype.empty() ? "binary/octet-stream" : m_mimetype );
00077 if( !m_profile.empty() )
00078 t->addAttribute( "profile", m_profile );
00079 if( m_tag1 )
00080 t->addChildCopy( m_tag1 );
00081 if( m_tag2 )
00082 t->addChildCopy( m_tag2 );
00083
00084 return t;
00085 }
00086
00087
00088
00089 SIManager::SIManager( ClientBase* parent, bool advertise )
00090 : m_parent( parent ), m_advertise( advertise )
00091 {
00092 if( m_parent )
00093 {
00094 m_parent->registerStanzaExtension( new SI() );
00095 m_parent->registerIqHandler( this, ExtSI );
00096 if( m_parent->disco() && m_advertise )
00097 m_parent->disco()->addFeature( XMLNS_SI );
00098 }
00099 }
00100
00101 SIManager::~SIManager()
00102 {
00103 if( m_parent )
00104 {
00105 m_parent->removeIqHandler( this, ExtSI );
00106 m_parent->removeIDHandler( this );
00107 if( m_parent->disco() && m_advertise )
00108 m_parent->disco()->removeFeature( XMLNS_SI );
00109 }
00110 }
00111
00112 const std::string SIManager::requestSI( SIHandler* sih, const JID& to, const std::string& profile,
00113 Tag* child1, Tag* child2, const std::string& mimetype )
00114 {
00115 if( !m_parent || !sih )
00116 return EmptyString;
00117
00118 const std::string& id = m_parent->getID();
00119 const std::string& id2 = m_parent->getID();
00120
00121 IQ iq( IQ::Set, to, id );
00122 iq.addExtension( new SI( child1, child2, id2, mimetype, profile ) );
00123
00124 TrackStruct t;
00125 t.sid = id2;
00126 t.profile = profile;
00127 t.sih = sih;
00128 m_track[id] = t;
00129 m_parent->send( iq, this, OfferSI );
00130
00131 return id2;
00132 }
00133
00134 void SIManager::acceptSI( const JID& to, const std::string& id, Tag* child1, Tag* child2 )
00135 {
00136 IQ iq( IQ::Result, to, id );
00137 iq.addExtension( new SI( child1, child2 ) );
00138 m_parent->send( iq );
00139 }
00140
00141 void SIManager::declineSI( const JID& to, const std::string& id, SIError reason, const std::string& text )
00142 {
00143 IQ iq( IQ::Error, to, id );
00144 Error* error;
00145 if( reason == NoValidStreams || reason == BadProfile )
00146 {
00147 Tag* appError = 0;
00148 if( reason == NoValidStreams )
00149 appError = new Tag( "no-valid-streams", XMLNS, XMLNS_SI );
00150 else if( reason == BadProfile )
00151 appError = new Tag( "bad-profile", XMLNS, XMLNS_SI );
00152 error = new Error( StanzaErrorTypeCancel, StanzaErrorBadRequest, appError );
00153 }
00154 else
00155 {
00156 error = new Error( StanzaErrorTypeCancel, StanzaErrorForbidden );
00157 if( !text.empty() )
00158 error->text( text );
00159 }
00160
00161 iq.addExtension( error );
00162 m_parent->send( iq );
00163 }
00164
00165 void SIManager::registerProfile( const std::string& profile, SIProfileHandler* sih )
00166 {
00167 if( !sih || profile.empty() )
00168 return;
00169
00170 m_handlers[profile] = sih;
00171
00172 if( m_parent && m_advertise && m_parent->disco() )
00173 m_parent->disco()->addFeature( profile );
00174 }
00175
00176 void SIManager::removeProfile( const std::string& profile )
00177 {
00178 if( profile.empty() )
00179 return;
00180
00181 m_handlers.erase( profile );
00182
00183 if( m_parent && m_advertise && m_parent->disco() )
00184 m_parent->disco()->removeFeature( profile );
00185 }
00186
00187 bool SIManager::handleIq( const IQ& iq )
00188 {
00189 TrackMap::iterator itt = m_track.find( iq.id() );
00190 if( itt != m_track.end() )
00191 return false;
00192
00193 const SI* si = iq.findExtension<SI>( ExtSI );
00194 if( !si || si->profile().empty() )
00195 return false;
00196
00197 HandlerMap::const_iterator it = m_handlers.find( si->profile() );
00198 if( it != m_handlers.end() && (*it).second )
00199 {
00200
00201 (*it).second->handleSIRequest( iq.from(), iq.id(), *si );
00202 return true;
00203 }
00204
00205 return false;
00206 }
00207
00208 void SIManager::handleIqID( const IQ& iq, int context )
00209 {
00210 switch( iq.subtype() )
00211 {
00212 case IQ::Result:
00213 if( context == OfferSI )
00214 {
00215 TrackMap::iterator it = m_track.find( iq.id() );
00216 if( it != m_track.end() )
00217 {
00218 const SI* si = iq.findExtension<SI>( ExtSI );
00219 if( !si )
00220 return;
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 (*it).second.sih->handleSIRequestResult( iq.from(), (*it).second.sid, *si );
00234 m_track.erase( it );
00235 }
00236 }
00237 break;
00238 case IQ::Error:
00239 if( context == OfferSI )
00240 {
00241 TrackMap::iterator it = m_track.find( iq.id() );
00242 if( it != m_track.end() )
00243 {
00244 (*it).second.sih->handleSIRequestError( iq, (*it).second.sid );
00245 m_track.erase( it );
00246 }
00247 }
00248 break;
00249 default:
00250 break;
00251 }
00252 }
00253
00254 }