summaryrefslogtreecommitdiffstats
path: root/kopete/protocols/msn/transport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kopete/protocols/msn/transport.cpp')
-rw-r--r--kopete/protocols/msn/transport.cpp356
1 files changed, 356 insertions, 0 deletions
diff --git a/kopete/protocols/msn/transport.cpp b/kopete/protocols/msn/transport.cpp
new file mode 100644
index 00000000..492117b6
--- /dev/null
+++ b/kopete/protocols/msn/transport.cpp
@@ -0,0 +1,356 @@
+/*
+ transport.cpp - Peer to peer transport
+
+ Copyright (c) 2005 by Gregg Edghill <gregg.edghill@gmail.com>
+
+ Kopete (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org>
+
+ *************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; version 2 of the License. *
+ * *
+ *************************************************************************
+*/
+
+#include "transport.h"
+#include "messageformatter.h"
+
+//BEGIN QT Includes
+//END
+
+//BEGIN KDE Includes
+#include <kclientsocketbase.h>
+#include <kdebug.h>
+#include <kstreamsocket.h>
+//END
+
+//BEGIN Using Directives
+using namespace KNetwork;
+//END
+
+#include "msnswitchboardsocket.h"
+
+namespace PeerToPeer {
+
+Transport::Transport(QObject* parent, const char* name)
+ : QObject(parent, name)
+{
+ mFormatter = new PeerToPeer::MessageFormatter(this);
+}
+
+
+Transport::~Transport()
+{
+}
+
+//BEGIN Public Methods
+
+TransportBridge* Transport::getBridge (const QString& to, Q_UINT16 port, TransportBridgeType type, const QString& identifier)
+{
+ TransportBridge *bridge = 0l;
+ KInetSocketAddress address;
+ if (mAddresses.contains(to))
+ {
+ address = mAddresses[to];
+ }
+ else
+ {
+ address = KInetSocketAddress(KIpAddress(to), port);
+ mAddresses[to] = address;
+ }
+
+ if (PeerToPeer::Tcp == type){
+ bridge = new TcpTransportBridge(address, mFormatter, this, identifier.ascii());
+ }
+
+ if (PeerToPeer::Udp == type){
+// TODO Add class UdpTransportBridge
+// bridge = new UdpTransportBridge(address, this, mFormatter, identifier.ascii());
+ }
+
+ if (bridge != 0l)
+ {
+ QObject::connect(bridge, SIGNAL(readyRead(const QByteArray&)), SLOT(slotOnReceive(const QByteArray&)));
+ }
+
+ return 0l;
+}
+
+void Transport::setDefaultBridge(MSNSwitchBoardSocket* mss)
+{
+ mDefaultBridge = mss;
+ QObject::connect((MSNSwitchBoardSocket*)mDefaultBridge, SIGNAL(messageReceived(const QString&, const QByteArray&)), SLOT(slotOnReceive(const QString&, const QByteArray&)));
+}
+
+//END
+
+//BEGIN Private Slot Methods
+
+// void Transport::slotOnReceive(Message& message)
+// {
+// }
+
+void Transport::slotOnReceive(const QString& contact, const QByteArray& bytes)
+{
+ kdDebug (14140) << k_funcinfo << " >> RECEIVED " << bytes.size() << " bytes." << endl;
+// Message message = mFormatter->readMessage(bytes);
+}
+
+//END
+
+
+
+
+TransportBridge::TransportBridge(const KNetwork::KInetSocketAddress& to, MessageFormatter* formatter, QObject* parent, const char* name)
+: QObject(parent, name)
+{
+ mAddress = to;
+ mFormatter = formatter;
+}
+
+TransportBridge::TransportBridge(KNetwork::KClientSocketBase* socket, MessageFormatter* formatter, QObject* parent, const char* name)
+: QObject(parent, name)
+{
+ mSocket = socket;
+ mAddress = mSocket->peerAddress();
+}
+
+TransportBridge::~TransportBridge()
+{
+}
+
+//BEGIN Public Methods
+
+void TransportBridge::connect()
+{
+ slotOnConnect();
+}
+
+void TransportBridge::disconnect()
+{
+ slotOnDisconnect();
+}
+
+//END
+
+//BEGIN Protected Slot Methods
+
+void TransportBridge::slotOnConnect()
+{
+}
+
+void TransportBridge::slotOnDisconnect()
+{
+}
+
+void TransportBridge::slotOnError(int)
+{
+}
+
+void TransportBridge::slotOnSocketClose()
+{
+}
+
+void TransportBridge::slotOnSocketConnect()
+{
+}
+
+void TransportBridge::slotOnSocketReceive()
+{
+}
+
+
+//END
+
+
+
+TcpTransportBridge::TcpTransportBridge(const KNetwork::KInetSocketAddress& to, MessageFormatter* formatter, QObject* parent, const char* name)
+: TransportBridge(to, formatter, parent, name)
+{
+ mSocket = new KStreamSocket(mAddress.ipAddress().toString(), QString::number(mAddress.port()), this);
+ mSocket->setBlocking(false);
+ QObject::connect(mSocket, SIGNAL(connected(const KResolverEntry&)), SLOT(slotOnSocketConnect()));
+ QObject::connect(mSocket, SIGNAL(gotError(int)), SLOT(slotOnError(int)));
+ mConnected = false;
+}
+
+TcpTransportBridge::TcpTransportBridge(KNetwork::KClientSocketBase* socket, MessageFormatter* formatter, QObject* parent, const char* name)
+: TransportBridge(socket, formatter, parent, name)
+{
+ mConnected = (mSocket->state() == KStreamSocket::Open) ? true : false;
+ mSocket->setBlocking(false);
+}
+
+TcpTransportBridge::~TcpTransportBridge()
+{
+}
+
+//BEGIN Protected Slot Methods
+
+void TcpTransportBridge::slotOnConnect()
+{
+ if (mConnected)
+ {
+ kdDebug(14140) << k_funcinfo << "Bridge (" << name() << ") ALREADY CONNECTED " << mSocket->peerAddress().toString() << " <-> " << mSocket->localAddress().toString() << endl;
+ return;
+ }
+
+ KStreamSocket *socket = static_cast<KStreamSocket*>(mSocket);
+ socket->setTimeout(5000);
+ QObject::connect(socket, SIGNAL(timeOut()), SLOT(slotOnSocketConnectTimeout()));
+ mSocket->connect();
+}
+
+void TcpTransportBridge::slotOnDisconnect()
+{
+ if (mConnected){
+ mSocket->close();
+ }
+}
+
+void TcpTransportBridge::slotOnError(int errorCode)
+{
+ kdDebug(14140) << k_funcinfo << "Bridge (" << name() << ") ERROR occurred on {" << mSocket->localAddress().toString() << " <-> " << mSocket->peerAddress().toString() << "} - " << mSocket->errorString() << endl;
+ emit bridgeError(QString("Bridge ERROR %1: %2").arg(errorCode).arg(mSocket->errorString()));
+ if (mConnected){
+ mSocket->disconnect();
+ mConnected = false;
+ }
+ mSocket->deleteLater();
+ mSocket = 0l;
+}
+
+void TcpTransportBridge::slotOnSocketClose()
+{
+ mSocket->disconnect();
+ kdDebug(14140) << k_funcinfo << "Bridge (" << name() << ") DISCONNECTED {" << mSocket->peerAddress().toString() << " <-> " << mSocket->localAddress().toString() << "}" << endl;
+ mConnected = false;
+ mSocket->deleteLater();
+ mSocket = 0l;
+
+ emit bridgeDisconnect();
+}
+
+void TcpTransportBridge::slotOnSocketConnect()
+{
+ kdDebug(14140) << k_funcinfo << "Bridge (" << name() << ") CONNECTED to " << mSocket->peerAddress().toString() << " from "
+ << mSocket->localAddress().toString() << endl;
+ mConnected = true;
+
+ QObject::connect(mSocket, SIGNAL(readyRead()), SLOT(slotOnSocketReceive()));
+ QObject::connect(mSocket, SIGNAL(closed()), SLOT(slotOnSocketClose()));
+
+ mVerified = true;
+ QString foo = "foo\0";
+ mSocket->writeBlock(foo.ascii(), foo.length());
+ foo = QString::null;
+
+ emit bridgeConnect();
+}
+
+void TcpTransportBridge::slotOnSocketReceive()
+{
+ kdDebug (14140) << k_funcinfo << "Bridge (" << name() << ") RECEIVED " << mSocket->bytesAvailable() << " bytes." << endl;
+
+ QByteArray bytes(mSocket->bytesAvailable());
+ mSocket->readBlock(bytes.data(), bytes.size());
+ // Write the data to the buffer.
+ mBuffer.write(bytes);
+
+ if (mVerified == false && mBuffer.size() >= 4)
+ {
+ QByteArray foo = mBuffer.read(4);
+ if (QString(foo) == "foo"){
+ kdDebug (14140) << k_funcinfo << "Bridge (" << name() << ") CONNECTION verified." << endl;
+ mVerified = true;
+ }
+ }
+
+ while(mBuffer.size() > 0)
+ {
+ if (mBuffer.size() >= 4 && mLength == 0)
+ {
+ QByteArray array = mBuffer.read(4);
+ for (int i=0; i < 4; i++){
+ ((char*)mLength)[i] = array[i];
+ }
+ }
+
+ if (mLength > 0 && mBuffer.size() >= mLength)
+ {
+ kdDebug (14140) << k_funcinfo << "Bridge (" << name() << ") read " << mLength << " bytes." << endl;
+ bytes = mBuffer.read(mLength);
+ mLength = 0;
+// Message message = mFormatter->readMessage(bytes, true);
+// emit messageReceived(message);
+ }
+ else
+ {
+ kdDebug (14140) << k_funcinfo << "Bridge (" << name() << ") waiting for " << mLength << " bytes." << endl;
+ break;
+ }
+ }
+}
+
+//END
+
+//BEGIN Private Slot Methods
+
+void TcpTransportBridge::slotOnSocketConnectTimeout()
+{
+ kdDebug (14140) << k_funcinfo << "Bridge (" << name() << ") CONNECT timeout." << endl;
+ emit bridgeConnectTimeout();
+ mSocket->deleteLater();
+ mSocket = 0l;
+}
+
+//END
+
+
+
+
+TcpTransportBridge::Buffer::Buffer(Q_UINT32 length)
+: QByteArray(length)
+{
+}
+
+TcpTransportBridge::Buffer::~Buffer()
+{
+}
+
+//BEGIN Public Methods
+
+void TcpTransportBridge::Buffer::write(const QByteArray& bytes)
+{
+ resize(size() + bytes.size());
+ for (uint i=0; i < bytes.size(); i++){
+ (*this)[size() + i] = bytes[i];
+ }
+}
+
+QByteArray TcpTransportBridge::Buffer::read(Q_UINT32 length)
+{
+ if (length >= size()) return QByteArray();
+
+ QByteArray buffer;
+ buffer.duplicate(data(), length);
+
+ char *bytes = new char[size() - length];
+ for(uint i=0; i < size() - length; i++){
+ bytes[i] = data()[length + i];
+ }
+
+ duplicate(bytes, size() - length);
+ delete[] bytes;
+
+ return buffer;
+}
+
+//END
+
+}
+
+#include "transport.moc"
+