Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | Related Pages

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 #include "error.h"
00021 
00022 namespace gloox
00023 {
00024 
00025   // ---- SIManager::SI ----
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   // ---- ~SIManager::SI ----
00087 
00088   // ---- SIManager ----
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       // FIXME: don't pass si->tag()!
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 /*|| si->profile().empty()*/ )
00220               return;
00221 
00222 //             Tag* si = iq.query();
00223 //             Tag* ptag = 0;
00224 //             Tag* fneg = 0;
00225 //             if( si && si->name() == "si" && si->xmlns() == XMLNS_SI )
00226 //             {
00227 //               ptag = si->findChildWithAttrib( XMLNS, (*it).second.profile );
00228 //               fneg = si->findChild( "feature", XMLNS, XMLNS_FEATURE_NEG );
00229 //             }
00230 
00231             // FIXME: remove above commented code and
00232             // check corectness of last 3 params!
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 }

Generated on Sun Dec 28 22:10:18 2008 for gloox by  doxygen 1.4.1