inbandbytestream.cpp

00001 /*
00002   Copyright (c) 2006-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 "inbandbytestream.h"
00015 #include "inbandbytestreamdatahandler.h"
00016 #include "messagesession.h"
00017 #include "disco.h"
00018 #include "clientbase.h"
00019 #include "base64.h"
00020 
00021 #include <sstream>
00022 
00023 namespace gloox
00024 {
00025 
00026   InBandBytestream::InBandBytestream( MessageSession *session, ClientBase *clientbase )
00027     : MessageFilter( session ), m_clientbase( clientbase ),
00028       m_inbandBytestreamDataHandler( 0 ), m_blockSize( 4096 ), m_sequence( -1 ),
00029       m_lastChunkReceived( -1 ), m_open( true )
00030   {
00031   }
00032 
00033   InBandBytestream::~InBandBytestream()
00034   {
00035     if( m_open )
00036       close();
00037 
00038     if( m_parent )
00039       m_parent->removeMessageFilter( this );
00040   }
00041 
00042   void InBandBytestream::decorate( Tag * /*tag*/ )
00043   {
00044   }
00045 
00046   void InBandBytestream::filter( Stanza *stanza )
00047   {
00048     if( !m_inbandBytestreamDataHandler || !m_open )
00049       return;
00050 
00051     if( stanza->subtype() == StanzaMessageError )
00052     {
00053       m_inbandBytestreamDataHandler->handleInBandError( m_sid, stanza->from(), stanza->error() );
00054       m_open = false;
00055     }
00056 
00057     Tag *data = 0;
00058     if( ( data = stanza->findChild( "data", "xmlns", XMLNS_IBB ) ) == 0 )
00059       return;
00060 
00061     const std::string& sid = data->findAttribute( "sid" );
00062     if( sid.empty() || sid != m_sid )
00063       return;
00064 
00065     const std::string& seq = data->findAttribute( "seq" );
00066     if( seq.empty() )
00067     {
00068       m_open = false;
00069       return;
00070     }
00071 
00072     std::stringstream str;
00073     int sequence = 0;
00074     str << seq;
00075     str >> sequence;
00076 
00077     if( m_lastChunkReceived + 1 != sequence )
00078     {
00079       m_open = false;
00080       return;
00081     }
00082     m_lastChunkReceived = sequence;
00083 
00084     if( !data->cdata().length() )
00085     {
00086       m_open = false;
00087       return;
00088     }
00089 
00090     m_inbandBytestreamDataHandler->handleInBandData( Base64::decode64( data->cdata() ), sid );
00091   }
00092 
00093   bool InBandBytestream::sendBlock( const std::string& data )
00094   {
00095     if( !m_open || !m_parent || !m_clientbase || data.length() > m_blockSize )
00096       return false;
00097 
00098     Tag *m = new Tag( "message" );
00099     m->addAttribute( "to", m_parent->target().full() );
00100     m->addAttribute( "id", m_clientbase->getID() );
00101     Tag *d = new Tag( m, "data", Base64::encode64( data ) );
00102     d->addAttribute( "sid", m_sid );
00103     d->addAttribute( "seq", ++m_sequence );
00104     d->addAttribute( "xmlns", XMLNS_IBB );
00105 
00106     // FIXME: hard-coded AMP
00107     Tag *a = new Tag( m, "amp" );
00108     a->addAttribute( "xmlns", XMLNS_AMP );
00109     Tag *r = new Tag( a, "rule" );
00110     r->addAttribute( "condition", "deliver-at" );
00111     r->addAttribute( "value", "stored" );
00112     r->addAttribute( "action", "error" );
00113     r = new Tag( a, "rule" );
00114     r->addAttribute( "condition", "match-resource" );
00115     r->addAttribute( "value", "exact" );
00116     r->addAttribute( "action", "error" );
00117 
00118     m_clientbase->send( m );
00119     return true;
00120   }
00121 
00122   void InBandBytestream::closed()
00123   {
00124     m_open = false;
00125 
00126     if( m_inbandBytestreamDataHandler )
00127       m_inbandBytestreamDataHandler->handleInBandClose( m_sid, m_parent->target() );
00128   }
00129 
00130   void InBandBytestream::close()
00131   {
00132     m_open = false;
00133 
00134     if( !m_parent )
00135       return;
00136 
00137     const std::string& id = m_clientbase->getID();
00138     Tag *iq = new Tag( "iq" );
00139     iq->addAttribute( "type", "set" );
00140     iq->addAttribute( "to", m_parent->target().full() );
00141     iq->addAttribute( "id", id );
00142     Tag *c = new Tag( iq, "close" );
00143     c->addAttribute( "sid", m_sid );
00144     c->addAttribute( "xmlns", XMLNS_IBB );
00145 
00146     m_clientbase->send( iq );
00147   }
00148 
00149   void InBandBytestream::registerInBandBytestreamDataHandler( InBandBytestreamDataHandler *ibbdh )
00150   {
00151     m_inbandBytestreamDataHandler = ibbdh;
00152   }
00153 
00154   void InBandBytestream::removeInBandBytestreamDataHandler()
00155   {
00156     m_inbandBytestreamDataHandler = 0;
00157   }
00158 
00159 }

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