summaryrefslogtreecommitdiffstats
path: root/kopete/protocols/oscar/liboscar/oscarclientstream.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitbcb704366cb5e333a626c18c308c7e0448a8e69f (patch)
treef0d6ab7d78ecdd9207cf46536376b44b91a1ca71 /kopete/protocols/oscar/liboscar/oscarclientstream.cpp
downloadtdenetwork-bcb704366cb5e333a626c18c308c7e0448a8e69f.tar.gz
tdenetwork-bcb704366cb5e333a626c18c308c7e0448a8e69f.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdenetwork@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kopete/protocols/oscar/liboscar/oscarclientstream.cpp')
-rw-r--r--kopete/protocols/oscar/liboscar/oscarclientstream.cpp437
1 files changed, 437 insertions, 0 deletions
diff --git a/kopete/protocols/oscar/liboscar/oscarclientstream.cpp b/kopete/protocols/oscar/liboscar/oscarclientstream.cpp
new file mode 100644
index 00000000..e607a24b
--- /dev/null
+++ b/kopete/protocols/oscar/liboscar/oscarclientstream.cpp
@@ -0,0 +1,437 @@
+/*
+ oscarclientstream.cpp - Kopete Oscar Protocol
+
+ Copyright (c) 2004 Matt Rogers <mattr@kde.org>
+
+ Based on code Copyright (c) 2004 SuSE Linux AG <http://www.suse.com>
+ Based on Iris, Copyright (C) 2003 Justin Karneges
+
+ Kopete (c) 2002-2004 by the Kopete developers <kopete-devel@kde.org>
+
+ *************************************************************************
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2 of the License, or (at your option) any later version. *
+ * *
+ *************************************************************************
+*/
+
+#include "oscarclientstream.h"
+
+#include <qguardedptr.h>
+#include <qobject.h>
+#include <qptrqueue.h>
+#include <qtimer.h>
+
+#include <kdebug.h>
+
+#include "bytestream.h"
+#include "connection.h"
+#include "connector.h"
+#include "coreprotocol.h"
+#include "rateclassmanager.h"
+#include "transfer.h"
+
+#define LIBOSCAR_DEBUG 0
+
+void cs_dump( const QByteArray &bytes );
+
+enum {
+ Idle,
+ Connecting,
+ Active,
+ Closing
+};
+
+enum {
+ ClientMode,
+ ServerMode
+};
+
+class ClientStream::Private
+{
+public:
+ Private()
+ {
+ conn = 0;
+ bs = 0;
+ connection = 0;
+
+ username = QString::null;
+ password = QString::null;
+ server = QString::null;
+ haveLocalAddr = false;
+ doBinding = true;
+
+ reset();
+ }
+ void reset()
+ {
+ state = Idle;
+ notify = 0;
+ newTransfers = false;
+ }
+
+ QString username;
+ QString password;
+ QString server;
+ bool doAuth; //send the initial login sequences to get the cookie
+ bool haveLocalAddr;
+ QHostAddress localAddr;
+ Q_UINT16 localPort;
+ bool doBinding;
+
+ Connector *conn;
+ ByteStream *bs;
+ CoreProtocol client;
+ Connection* connection;
+
+ QString defRealm;
+
+ int mode;
+ int state;
+ int notify;
+ bool newTransfers;
+
+ int errCond;
+ QString errText;
+
+ QPtrQueue<Transfer> in;
+
+ QTimer noopTimer; // used to send icq keepalive
+ int noop_time;
+};
+
+ClientStream::ClientStream(Connector *conn, QObject *parent)
+:Stream(parent)
+{
+ //qDebug("CLIENTSTREAM::ClientStream");
+
+ d = new Private;
+ d->mode = ClientMode;
+ d->conn = conn;
+ connect( d->conn, SIGNAL(connected()), SLOT(cr_connected()) );
+ connect( d->conn, SIGNAL(error()), SLOT(cr_error()) );
+ connect( &d->client, SIGNAL( outgoingData( const QByteArray& ) ), SLOT ( cp_outgoingData( const QByteArray & ) ) );
+ connect( &d->client, SIGNAL( incomingData() ), SLOT ( cp_incomingData() ) );
+
+ d->noop_time = 0;
+ connect(&d->noopTimer, SIGNAL(timeout()), SLOT(doNoop()));
+}
+
+ClientStream::~ClientStream()
+{
+ reset();
+ delete d;
+}
+
+void ClientStream::reset(bool all)
+{
+ d->reset();
+ d->noopTimer.stop();
+
+ // client
+ if(d->mode == ClientMode)
+ {
+ // reset connector
+ if ( d->bs )
+ {
+ d->bs->close();
+ d->bs = 0;
+ }
+ if ( d->conn )
+ d->conn->done();
+
+ // reset state machine
+ d->client.reset();
+ }
+ if(all)
+ d->in.clear();
+}
+
+void ClientStream::connectToServer(const QString& server, bool auth)
+{
+ reset(true);
+ d->state = Connecting;
+ d->doAuth = auth;
+ d->server = server;
+
+ d->conn->connectToServer( d->server );
+}
+
+void ClientStream::continueAfterWarning()
+{
+/* unneeded?
+ if(d->state == WaitVersion) {
+ d->state = Connecting;
+ processNext();
+ }
+ else if(d->state == WaitTLS) {
+ d->state = Connecting;
+ processNext();
+ }
+*/
+}
+
+void ClientStream::accept()
+{
+
+}
+
+bool ClientStream::isActive() const
+{
+ return (d->state != Idle);
+}
+
+bool ClientStream::isAuthenticated() const
+{
+ return (d->state == Active);
+}
+
+void ClientStream::setNoopTime(int mills)
+{
+ d->noop_time = mills;
+
+ if(d->noop_time == 0) {
+ d->noopTimer.stop();
+ return;
+ }
+
+ if( d->state != Active )
+ return;
+
+ d->noopTimer.start( d->noop_time );
+}
+
+void ClientStream::setLocalAddr(const QHostAddress &addr, Q_UINT16 port)
+{
+ d->haveLocalAddr = true;
+ d->localAddr = addr;
+ d->localPort = port;
+}
+
+int ClientStream::errorCondition() const
+{
+ return d->errCond;
+}
+
+QString ClientStream::errorText() const
+{
+ return d->errText;
+}
+
+void ClientStream::close()
+{
+ if(d->state == Active) {
+ d->state = Closing;
+// d->client.shutdown();
+ processNext();
+ }
+ else if(d->state != Idle && d->state != Closing) {
+ reset();
+ }
+}
+
+void ClientStream::setConnection( Connection *c )
+{
+ d->connection = c;
+}
+
+Connection* ClientStream::connection() const
+{
+ return d->connection;
+}
+
+
+bool ClientStream::transfersAvailable() const
+{
+ return ( !d->in.isEmpty() );
+}
+
+Transfer* ClientStream::read()
+{
+ if(d->in.isEmpty())
+ return 0; //first from queue...
+ else
+ return d->in.dequeue();
+}
+
+void ClientStream::write( Transfer *request )
+{
+ d->client.outgoingTransfer( request );
+}
+
+void cs_dump( const QByteArray &bytes )
+{
+#if 0
+ qDebug( "contains: %i bytes ", bytes.count() );
+ uint count = 0;
+ while ( count < bytes.count() )
+ {
+ int dword = 0;
+ for ( int i = 0; i < 8; ++i )
+ {
+ if ( count + i < bytes.count() )
+ printf( "%02x ", bytes[ count + i ] );
+ else
+ printf( " " );
+ if ( i == 3 )
+ printf( " " );
+ }
+ printf(" | ");
+ dword = 0;
+ for ( int i = 0; i < 8; ++i )
+ {
+ if ( count + i < bytes.count() )
+ {
+ int j = bytes [ count + i ];
+ if ( j >= 0x20 && j <= 0x7e )
+ printf( "%2c ", j );
+ else
+ printf( "%2c ", '.' );
+ }
+ else
+ printf( " " );
+ if ( i == 3 )
+ printf( " " );
+ }
+ printf( "\n" );
+ count += 8;
+ }
+ printf( "\n" );
+#endif
+ Q_UNUSED( bytes );
+}
+
+void ClientStream::cp_outgoingData( const QByteArray& outgoingBytes )
+{
+ // take formatted bytes from CoreProtocol and put them on the wire
+ d->bs->write( outgoingBytes );
+}
+
+void ClientStream::cp_incomingData()
+{
+ Transfer * incoming = d->client.incomingTransfer();
+ if ( incoming )
+ {
+ d->in.enqueue( incoming );
+ d->newTransfers = true;
+ doReadyRead();
+ }
+ else
+ kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo <<
+ "client signalled incomingData but none was available, state is: " <<
+ d->client.state() << endl;
+}
+
+void ClientStream::cr_connected()
+{
+ d->bs = d->conn->stream();
+ connect(d->bs, SIGNAL(connectionClosed()), SLOT(bs_connectionClosed()));
+ connect(d->bs, SIGNAL(delayedCloseFinished()), SLOT(bs_delayedCloseFinished()));
+ connect(d->bs, SIGNAL(readyRead()), SLOT(bs_readyRead()));
+ connect(d->bs, SIGNAL(bytesWritten(int)), SLOT(bs_bytesWritten(int)));
+ connect(d->bs, SIGNAL(error(int)), SLOT(bs_error(int)));
+
+ d->state = Active;
+ if ( d->noop_time )
+ d->noopTimer.start( d->noop_time );
+
+ QByteArray spare = d->bs->read();
+
+ QGuardedPtr<QObject> self = this;
+ emit connected();
+ if(!self)
+ return;
+}
+
+void ClientStream::cr_error()
+{
+ kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << endl;
+ reset();
+ emit error(ErrConnection);
+}
+
+void ClientStream::bs_connectionClosed()
+{
+ reset();
+ emit connectionClosed();
+}
+
+void ClientStream::bs_delayedCloseFinished()
+{
+ // we don't care about this (we track all important data ourself)
+}
+
+void ClientStream::bs_error(int)
+{
+ // TODO
+}
+
+void ClientStream::bs_readyRead()
+{
+ QByteArray a;
+ //qDebug( "size of storage for incoming data is %i bytes.", a.size() );
+ a = d->bs->read();
+
+#if LIBOSCAR_DEBUG
+ QCString cs(a.data(), a.size()+1);
+ kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "recv: " << a.size() << "bytes" << endl;
+ cs_dump( a );
+#endif
+
+ d->client.addIncomingData(a);
+}
+
+void ClientStream::bs_bytesWritten(int bytes)
+{
+#if LIBOSCAR_DEBUG
+ kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << bytes << " bytes written" << endl;
+ Q_UNUSED( bytes );
+#else
+ Q_UNUSED( bytes );
+#endif
+}
+
+void ClientStream::srvProcessNext()
+{
+}
+
+void ClientStream::doReadyRead()
+{
+ emit readyRead();
+}
+
+void ClientStream::processNext()
+{
+ if( !d->in.isEmpty() )
+ {
+ QTimer::singleShot(0, this, SLOT(doReadyRead()));
+ }
+}
+
+bool ClientStream::handleNeed()
+{
+ return false;
+}
+
+void ClientStream::doNoop()
+{
+ if ( d->state != Active )
+ return;
+
+ FLAP f = { 0x05, d->connection->flapSequence(), 0 };
+ Buffer* b = new Buffer(); //deleted in Transfer destructor
+ Transfer* t = new FlapTransfer( f, b ); //deleted after being sent
+ write( t );
+}
+
+void ClientStream::handleError()
+{
+}
+
+#include "oscarclientstream.moc"
+
+//kate: tab-width 4; indent-mode csands;