inbandbytestreammanager.cpp

00001 /*
00002   Copyright (c) 2006-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 "inbandbytestreammanager.h"
00015 #include "inbandbytestreamhandler.h"
00016 #include "inbandbytestream.h"
00017 #include "clientbase.h"
00018 #include "disco.h"
00019 
00020 namespace gloox
00021 {
00022 
00023   InBandBytestreamManager::InBandBytestreamManager( ClientBase *parent )
00024     : m_parent( parent ), m_inbandBytestreamHandler( 0 ), m_syncInbandBytestreams( true ),
00025       m_blockSize( 4096 )
00026   {
00027     if( m_parent )
00028     {
00029       m_parent->registerIqHandler( this, XMLNS_IBB );
00030       m_parent->disco()->addFeature( XMLNS_IBB );
00031     }
00032   }
00033 
00034   InBandBytestreamManager::~InBandBytestreamManager()
00035   {
00036     if( m_parent )
00037     {
00038       m_parent->disco()->removeFeature( XMLNS_IBB );
00039       m_parent->removeIqHandler( XMLNS_IBB );
00040     }
00041 
00042     IBBMap::iterator it = m_ibbMap.begin();
00043     for( ; it != m_ibbMap.end(); ++it )
00044     {
00045       delete (*it).second;
00046       m_ibbMap.erase( it );
00047     }
00048   }
00049 
00050   bool InBandBytestreamManager::requestInBandBytestream( const JID& to, InBandBytestreamHandler *ibbh,
00051                                                          const std::string& sid )
00052   {
00053     if( !m_parent || !ibbh )
00054       return false;
00055 
00056     const std::string& msid = sid.empty() ? m_parent->getID() : sid;
00057     const std::string& id = m_parent->getID();
00058     Tag *iq = new Tag( "iq" );
00059     iq->addAttribute( "type", "set" );
00060     iq->addAttribute( "to", to.full() );
00061     iq->addAttribute( "id", id );
00062     Tag *o = new Tag( iq, "open" );
00063     o->addAttribute( "sid", msid );
00064     o->addAttribute( "block-size", m_blockSize );
00065     o->addAttribute( "xmlns", XMLNS_IBB );
00066 
00067     TrackItem item;
00068     item.sid = msid;
00069     item.ibbh = ibbh;
00070     m_trackMap[id] = item;
00071     m_parent->trackID( this, id, IBBOpenStream );
00072     m_parent->send( iq );
00073 
00074     return true;
00075   }
00076 
00077   bool InBandBytestreamManager::handleIq( Stanza *stanza )
00078   {
00079     Tag *o = 0;
00080     if( ( stanza->subtype() == StanzaIqSet ) &&
00081           ( ( o = stanza->findChild( "open", "xmlns", XMLNS_IBB ) ) != 0 ) )
00082     {
00083       InBandBytestream *ibb = new InBandBytestream( 0, m_parent );
00084       const std::string& sid = o->findAttribute( "sid" );
00085       ibb->setSid( sid );
00086 
00087       if( !m_inbandBytestreamHandler )
00088         rejectInBandBytestream( ibb, stanza->from(), stanza->id() );
00089 
00090       if( !m_syncInbandBytestreams )
00091       {
00092         AsyncIBBItem item;
00093         item.ibb = ibb;
00094         item.from = stanza->from();
00095         item.id = stanza->id();
00096         m_asyncTrackMap[sid] = item;
00097       }
00098 
00099       bool t = m_inbandBytestreamHandler->handleIncomingInBandBytestream( stanza->from(), ibb );
00100       if( m_syncInbandBytestreams && t )
00101       {
00102         acceptInBandBytestream( ibb, stanza->from(), stanza->id() );
00103       }
00104       else if( m_syncInbandBytestreams && !t )
00105       {
00106         rejectInBandBytestream( ibb, stanza->from(), stanza->id() );
00107       }
00108     }
00109     else if( ( stanza->subtype() == StanzaIqSet ) &&
00110                ( ( o = stanza->findChild( "close", "xmlns", XMLNS_IBB ) ) != 0 ) &&
00111                o->hasAttribute( "sid" ) )
00112     {
00113       IBBMap::iterator it = m_ibbMap.find( o->findAttribute( "sid" ) );
00114       if( it != m_ibbMap.end() )
00115       {
00116         (*it).second->closed();
00117 
00118         Tag *iq = new Tag( "iq" );
00119         iq->addAttribute( "type", "result" );
00120         iq->addAttribute( "to", stanza->from().full() );
00121         iq->addAttribute( "id", stanza->id() );
00122 
00123         m_parent->send( iq );
00124       }
00125     }
00126     else
00127     {
00128       return false;
00129     }
00130 
00131     return true;
00132   }
00133 
00134   void InBandBytestreamManager::acceptInBandBytestream( InBandBytestream *ibb )
00135   {
00136     if( m_syncInbandBytestreams )
00137       return;
00138 
00139     AsyncTrackMap::iterator it = m_asyncTrackMap.find( ibb->sid() );
00140     if( it != m_asyncTrackMap.end() )
00141     {
00142       acceptInBandBytestream( ibb, (*it).second.from, (*it).second.id );
00143       m_asyncTrackMap.erase( it );
00144     }
00145   }
00146 
00147   void InBandBytestreamManager::rejectInBandBytestream( InBandBytestream *ibb )
00148   {
00149     if( m_syncInbandBytestreams )
00150       return;
00151 
00152     AsyncTrackMap::iterator it = m_asyncTrackMap.find( ibb->sid() );
00153     if( it != m_asyncTrackMap.end() )
00154     {
00155       rejectInBandBytestream( ibb, (*it).second.from, (*it).second.id );
00156       m_asyncTrackMap.erase( it );
00157     }
00158   }
00159 
00160   void InBandBytestreamManager::acceptInBandBytestream( InBandBytestream *ibb,
00161       const JID& from, const std::string& id )
00162   {
00163     m_ibbMap[ibb->sid()] = ibb;
00164     Tag *iq = new Tag( "iq" );
00165     iq->addAttribute( "type", "result" );
00166     iq->addAttribute( "to", from.full() );
00167     iq->addAttribute( "id", id );
00168     m_parent->send( iq );
00169   }
00170 
00171   void InBandBytestreamManager::rejectInBandBytestream( InBandBytestream *ibb,
00172       const JID& from, const std::string& id )
00173   {
00174     delete ibb;
00175     Tag *iq = new Tag( "iq" );
00176     iq->addAttribute( "type", "error" );
00177     iq->addAttribute( "to", from.full() );
00178     iq->addAttribute( "id", id );
00179     Tag *e = new Tag( iq, "error" );
00180     e->addAttribute( "code", "501" );
00181     e->addAttribute( "type", "cancel" );
00182     Tag *f = new Tag( e, "feature-not-implemented" );
00183     f->addAttribute( "xmlns", XMLNS_XMPP_STANZAS );
00184     m_parent->send( iq );
00185   }
00186 
00187   bool InBandBytestreamManager::handleIqID( Stanza *stanza, int context )
00188   {
00189     switch( context )
00190     {
00191       case IBBOpenStream:
00192       {
00193         TrackMap::iterator it = m_trackMap.find( stanza->id() );
00194         if( it != m_trackMap.end() )
00195         {
00196           switch( stanza->subtype() )
00197           {
00198             case StanzaIqResult:
00199             {
00200               InBandBytestream *ibb = new InBandBytestream( 0, m_parent );
00201               ibb->setSid( (*it).second.sid );
00202               ibb->setBlockSize( m_blockSize );
00203               m_ibbMap[(*it).second.sid] = ibb;
00204               InBandBytestreamHandler *t = (*it).second.ibbh;
00205               m_trackMap.erase( it );
00206               t->handleOutgoingInBandBytestream( stanza->from(), ibb );
00207               break;
00208             }
00209             case StanzaIqError:
00210               (*it).second.ibbh->handleInBandBytestreamError( stanza->from(), stanza->error() );
00211               break;
00212             default:
00213               break;
00214           }
00215           m_trackMap.erase( it );
00216         }
00217         break;
00218       }
00219       default:
00220         break;
00221     }
00222 
00223     return false;
00224   }
00225 
00226   bool InBandBytestreamManager::dispose( InBandBytestream *ibb )
00227   {
00228     IBBMap::iterator it = m_ibbMap.find( ibb->sid() );
00229     if( it != m_ibbMap.end() )
00230     {
00231       delete ibb;
00232       m_ibbMap.erase( it );
00233       return true;
00234     }
00235 
00236     return false;
00237   }
00238 
00239   void InBandBytestreamManager::registerInBandBytestreamHandler( InBandBytestreamHandler *ibbh,
00240       bool sync )
00241   {
00242     m_inbandBytestreamHandler = ibbh;
00243     m_syncInbandBytestreams = sync;
00244   }
00245 
00246   void InBandBytestreamManager::removeInBandBytestreamHandler()
00247   {
00248     m_inbandBytestreamHandler = 0;
00249   }
00250 
00251 }

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