simanager.cpp

00001 /*
00002   Copyright (c) 2007 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       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 }

Generated on Sat Nov 10 08:50:27 2007 for gloox by  doxygen 1.5.3-20071008