00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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 * )
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
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 if( m_inbandBytestreamDataHandler )
00125 m_inbandBytestreamDataHandler->handleInBandClose( m_sid, m_parent->target() );
00126
00127 m_open = false;
00128
00129 if( !m_parent )
00130 return;
00131 }
00132
00133 void InBandBytestream::close()
00134 {
00135 m_open = false;
00136
00137 if( !m_parent )
00138 return;
00139
00140 const std::string id = m_clientbase->getID();
00141 Tag *iq = new Tag( "iq" );
00142 iq->addAttribute( "type", "set" );
00143 iq->addAttribute( "to", m_parent->target().full() );
00144 iq->addAttribute( "id", id );
00145 Tag *c = new Tag( iq, "close" );
00146 c->addAttribute( "sid", m_sid );
00147 c->addAttribute( "xmlns", XMLNS_IBB );
00148
00149 m_clientbase->send( iq );
00150 }
00151
00152 void InBandBytestream::registerInBandBytestreamDataHandler( InBandBytestreamDataHandler *ibbdh )
00153 {
00154 m_inbandBytestreamDataHandler = ibbdh;
00155 }
00156
00157 void InBandBytestream::removeInBandBytestreamDataHandler()
00158 {
00159 m_inbandBytestreamDataHandler = 0;
00160 }
00161
00162 }