inbandbytestreammanager.cpp

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

Generated on Tue May 1 14:20:20 2007 for gloox by  doxygen 1.5.1