diff options
Diffstat (limited to 'kopete/protocols/yahoo/libkyahoo/yahooclientstream.cpp')
-rw-r--r-- | kopete/protocols/yahoo/libkyahoo/yahooclientstream.cpp | 418 |
1 files changed, 418 insertions, 0 deletions
diff --git a/kopete/protocols/yahoo/libkyahoo/yahooclientstream.cpp b/kopete/protocols/yahoo/libkyahoo/yahooclientstream.cpp new file mode 100644 index 00000000..548140b1 --- /dev/null +++ b/kopete/protocols/yahoo/libkyahoo/yahooclientstream.cpp @@ -0,0 +1,418 @@ +/* + oscarclientstream.cpp - Kopete Oscar Protocol + + Copyright (c) 2004 Matt Rogers <[email protected]> + + 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 <[email protected]> + + ************************************************************************* + * * + * 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 <qapplication.h> // for qdebug +#include <qguardedptr.h> +#include <qobject.h> +#include <qptrqueue.h> +#include <qtimer.h> + +#include <kdebug.h> + +#include "bytestream.h" +#include "connector.h" +#include "coreprotocol.h" +#include "transfer.h" + +#include "yahooclientstream.h" +#include "yahootypes.h" + +void cs_dump( const QByteArray &bytes ); + +enum { + Idle, + Connecting, + Active, + Closing +}; + +enum { + Client, + Server +}; + +class ClientStream::Private +{ +public: + Private() + { + conn = 0; + bs = 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; + + 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) +{ + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl; + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl; + + d = new Private; + d->mode = Client; + 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) +{ + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl; + d->reset(); + d->noopTimer.stop(); + + // client + if(d->mode == Client) { + + // reset connector + if(d->bs) { + d->bs->close(); + d->bs = 0; + } + d->conn->done(); + + // reset state machine + d->client.reset(); + } + if(all) + d->in.clear(); +} + +void ClientStream::connectToServer(const QString& server, bool auth) +{ + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl; + reset(true); + d->state = Connecting; + d->doAuth = auth; + d->server = server; + + d->conn->connectToServer( d->server ); +} + +void ClientStream::continueAfterWarning() +{ + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl; +/* 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->state != Active) + return; + + if(d->noop_time == 0) { + d->noopTimer.stop(); + 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(); + } +} + +bool ClientStream::transfersAvailable() const +{ + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl; + 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 ) +{ + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl; + // pass to CoreProtocol for transformation into wire format + 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 + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << "[data size: " << outgoingBytes.size() << "]" << endl; + //cs_dump( outgoingBytes ); + d->bs->write( outgoingBytes ); +} + +void ClientStream::cp_incomingData() +{ + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl; + Transfer * incoming = d->client.incomingTransfer(); + if ( incoming ) + { + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " - got a new transfer" << endl; + d->in.enqueue( incoming ); + d->newTransfers = true; + emit doReadyRead(); + } + else + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " - client signalled incomingData but none was available, state is: "<< d->client.state() << endl; +} + +/* Connector connected */ +void ClientStream::cr_connected() +{ + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl; + + 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))); + + QByteArray spare = d->bs->read(); + + QGuardedPtr<QObject> self = this; + emit connected(); + if(!self) + return; +} + +void ClientStream::cr_error() +{ + kdDebug(YAHOO_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) +{ + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl; + // TODO +} + +void ClientStream::bs_readyRead() +{ + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl; + QByteArray a; + //qDebug( "size of storage for incoming data is %i bytes.", a.size() ); + a = d->bs->read(); + + //QCString cs(a.data(), a.size()+1); + //qDebug("ClientStream: recv: %d [%s]\n", a.size(), cs.data()); + //kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " recv: " << a.size() <<" bytes" <<endl; + //cs_dump( a ); + + d->client.addIncomingData(a); +} + +void ClientStream::bs_bytesWritten(int bytes) +{ + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << " written: " << bytes <<" bytes" <<endl; +} + +void ClientStream::srvProcessNext() +{ +} + +void ClientStream::doReadyRead() +{ + kdDebug(YAHOO_RAW_DEBUG) << k_funcinfo << endl; + emit readyRead(); +} + +void ClientStream::processNext() +{ + if( !d->in.isEmpty() ) + { + QTimer::singleShot(0, this, SLOT(doReadyRead())); + } +} + +bool ClientStream::handleNeed() +{ + return false; +} + + +void ClientStream::doNoop() +{ +} + +void ClientStream::handleError() +{ +} + +#include "yahooclientstream.moc" |