Port things from MSN to WLM plugin:
[kdenetwork.git] / kopete / protocols / msn / transport.cpp
blob71fe51ca92769c9dd75ebcfba768585b09b4dcd0
1 /*
2 transport.cpp - Peer to peer transport
4 Copyright (c) 2005 by Gregg Edghill <gregg.edghill@gmail.com>
6 Kopete (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org>
8 *************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 *************************************************************************
18 #include "transport.h"
19 #include "messageformatter.h"
21 //BEGIN QT Includes
22 //END
24 //BEGIN KDE Includes
25 #include <kclientsocketbase.h>
26 #include <kdebug.h>
27 #include <kstreamsocket.h>
28 //END
30 //BEGIN Using Directives
31 using namespace KNetwork;
32 //END
34 #include "msnswitchboardsocket.h"
36 namespace PeerToPeer {
38 Transport::Transport(QObject* parent)
39 : QObject(parent)
41 mFormatter = new PeerToPeer::MessageFormatter(this);
45 Transport::~Transport()
49 //BEGIN Public Methods
51 TransportBridge* Transport::getBridge (const QString& to, quint16 port, TransportBridgeType type, const QString& identifier)
53 TransportBridge *bridge = 0l;
54 KInetSocketAddress address;
55 if (mAddresses.contains(to))
57 address = mAddresses[to];
59 else
61 address = KInetSocketAddress(KIpAddress(to), port);
62 mAddresses[to] = address;
65 if (PeerToPeer::Tcp == type){
66 bridge = new TcpTransportBridge(address, mFormatter, this, identifier.ascii());
69 if (PeerToPeer::Udp == type){
70 // TODO Add class UdpTransportBridge
71 // bridge = new UdpTransportBridge(address, this, mFormatter, identifier.ascii());
74 if (bridge != 0l)
76 QObject::connect(bridge, SIGNAL(readyRead(const QByteArray&)), SLOT(slotOnReceive(const QByteArray&)));
79 return 0l;
82 void Transport::setDefaultBridge(MSNSwitchBoardSocket* mss)
84 mDefaultBridge = mss;
85 QObject::connect((MSNSwitchBoardSocket*)mDefaultBridge, SIGNAL(messageReceived(const QString&, const QByteArray&)), SLOT(slotOnReceive(const QString&, const QByteArray&)));
88 //END
90 //BEGIN Private Slot Methods
92 // void Transport::slotOnReceive(Message& message)
93 // {
94 // }
96 void Transport::slotOnReceive(const QString& contact, const QByteArray& bytes)
98 kDebug (14140) << " >> RECEIVED " << bytes.size() << " bytes.";
99 // Message message = mFormatter->readMessage(bytes);
102 //END
107 TransportBridge::TransportBridge(const KNetwork::KInetSocketAddress& to, MessageFormatter* formatter, QObject* parent)
108 : QObject(parent)
110 mAddress = to;
111 mFormatter = formatter;
114 TransportBridge::TransportBridge(KNetwork::KClientSocketBase* socket, MessageFormatter* formatter, QObject* parent)
115 : QObject(parent)
117 mSocket = socket;
118 mAddress = mSocket->peerAddress();
121 TransportBridge::~TransportBridge()
125 //BEGIN Public Methods
127 void TransportBridge::connect()
129 slotOnConnect();
132 void TransportBridge::disconnect()
134 slotOnDisconnect();
137 //END
139 //BEGIN Protected Slot Methods
141 void TransportBridge::slotOnConnect()
145 void TransportBridge::slotOnDisconnect()
149 void TransportBridge::slotOnError(int)
153 void TransportBridge::slotOnSocketClose()
157 void TransportBridge::slotOnSocketConnect()
161 void TransportBridge::slotOnSocketReceive()
166 //END
170 TcpTransportBridge::TcpTransportBridge(const KNetwork::KInetSocketAddress& to, MessageFormatter* formatter, QObject* parent)
171 : TransportBridge(to, formatter, parent)
173 mSocket = new KStreamSocket(mAddress.ipAddress().toString(), QString::number(mAddress.port()), this);
174 mSocket->setBlocking(false);
175 QObject::connect(mSocket, SIGNAL(connected(const KResolverEntry&)), SLOT(slotOnSocketConnect()));
176 QObject::connect(mSocket, SIGNAL(gotError(int)), SLOT(slotOnError(int)));
177 mConnected = false;
180 TcpTransportBridge::TcpTransportBridge(KNetwork::KClientSocketBase* socket, MessageFormatter* formatter, QObject* parent)
181 : TransportBridge(socket, formatter, parent)
183 mConnected = (mSocket->state() == KStreamSocket::Open) ? true : false;
184 mSocket->setBlocking(false);
187 TcpTransportBridge::~TcpTransportBridge()
191 //BEGIN Protected Slot Methods
193 void TcpTransportBridge::slotOnConnect()
195 if (mConnected)
197 kDebug(14140) << "Bridge (" << name() << ") ALREADY CONNECTED " << mSocket->peerAddress().toString() << " <-> " << mSocket->localAddress().toString();
198 return;
201 KStreamSocket *socket = static_cast<KStreamSocket*>(mSocket);
202 socket->setTimeout(5000);
203 QObject::connect(socket, SIGNAL(timeOut()), SLOT(slotOnSocketConnectTimeout()));
204 mSocket->connect();
207 void TcpTransportBridge::slotOnDisconnect()
209 if (mConnected){
210 mSocket->close();
214 void TcpTransportBridge::slotOnError(int errorCode)
216 kDebug(14140) << "Bridge (" << name() << ") ERROR occurred on {" << mSocket->localAddress().toString() << " <-> " << mSocket->peerAddress().toString() << "} - " << mSocket->errorString();
217 emit bridgeError(QString("Bridge ERROR %1: %2").arg(errorCode).arg(mSocket->errorString()));
218 if (mConnected){
219 mSocket->disconnect();
220 mConnected = false;
222 mSocket->deleteLater();
223 mSocket = 0l;
226 void TcpTransportBridge::slotOnSocketClose()
228 mSocket->disconnect();
229 kDebug(14140) << "Bridge (" << name() << ") DISCONNECTED {" << mSocket->peerAddress().toString() << " <-> " << mSocket->localAddress().toString() << "}";
230 mConnected = false;
231 mSocket->deleteLater();
232 mSocket = 0l;
234 emit bridgeDisconnect();
237 void TcpTransportBridge::slotOnSocketConnect()
239 kDebug(14140) << "Bridge (" << name() << ") CONNECTED to " << mSocket->peerAddress().toString() << " from "
240 << mSocket->localAddress().toString() << endl;
241 mConnected = true;
243 QObject::connect(mSocket, SIGNAL(readyRead()), SLOT(slotOnSocketReceive()));
244 QObject::connect(mSocket, SIGNAL(closed()), SLOT(slotOnSocketClose()));
246 mVerified = true;
247 QString foo = "foo\0";
248 mSocket->write(foo.toAscii(), foo.length());
249 foo.clear();
251 emit bridgeConnect();
254 void TcpTransportBridge::slotOnSocketReceive()
256 kDebug (14140) << "Bridge (" << name() << ") RECEIVED " << mSocket->bytesAvailable() << " bytes.";
258 QByteArray bytes(mSocket->bytesAvailable());
259 mSocket->read(bytes.data(), bytes.size());
260 // Write the data to the buffer.
261 mBuffer.write(bytes);
263 if (mVerified == false && mBuffer.size() >= 4)
265 QByteArray foo = mBuffer.read(4);
266 if (QString(foo) == "foo"){
267 kDebug (14140) << "Bridge (" << name() << ") CONNECTION verified.";
268 mVerified = true;
272 while(mBuffer.size() > 0)
274 if (mBuffer.size() >= 4 && mLength == 0)
276 QByteArray array = mBuffer.read(4);
277 for (int i=0; i < 4; i++){
278 ((char*)mLength)[i] = array[i];
282 if (mLength > 0 && mBuffer.size() >= mLength)
284 kDebug (14140) << "Bridge (" << name() << ") read " << mLength << " bytes.";
285 bytes = mBuffer.read(mLength);
286 mLength = 0;
287 // Message message = mFormatter->readMessage(bytes, true);
288 // emit messageReceived(message);
290 else
292 kDebug (14140) << "Bridge (" << name() << ") waiting for " << mLength << " bytes.";
293 break;
298 //END
300 //BEGIN Private Slot Methods
302 void TcpTransportBridge::slotOnSocketConnectTimeout()
304 kDebug (14140) << "Bridge (" << name() << ") CONNECT timeout.";
305 emit bridgeConnectTimeout();
306 mSocket->deleteLater();
307 mSocket = 0l;
310 //END
315 TcpTransportBridge::Buffer::Buffer(quint32 length)
316 : QByteArray(length)
320 TcpTransportBridge::Buffer::~Buffer()
324 //BEGIN Public Methods
326 void TcpTransportBridge::Buffer::write(const QByteArray& bytes)
328 resize(size() + bytes.size());
329 for (uint i=0; i < bytes.size(); i++){
330 (*this)[size() + i] = bytes[i];
334 QByteArray TcpTransportBridge::Buffer::read(quint32 length)
336 if (length >= size()) return QByteArray();
338 QByteArray buffer;
339 buffer.duplicate(data(), length);
341 char *bytes = new char[size() - length];
342 for(uint i=0; i < size() - length; i++){
343 bytes[i] = data()[length + i];
346 duplicate(bytes, size() - length);
347 delete[] bytes;
349 return buffer;
352 //END
356 #include "transport.moc"