simanager.cpp

00001 /*
00002   Copyright (c) 2007-2008 by Jakob Schroeter <js@camaya.net>
00003   This file is part of the gloox library. http://camaya.net/gloox
00004 
00005   This software is distributed under a license. The full license
00006   agreement can be found in the file LICENSE in this distribution.
00007   This software may not be copied, modified, sold or distributed
00008   other than expressed in the named license agreement.
00009 
00010   This software is distributed without any warranty.
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 }

Generated on Mon Dec 7 13:28:19 2009 for gloox by  doxygen 1.6.1