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 *************************************************************************
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. *
15 *************************************************************************
18 #include "transport.h"
19 #include "messageformatter.h"
25 #include <kclientsocketbase.h>
27 #include <kstreamsocket.h>
30 //BEGIN Using Directives
31 using namespace KNetwork
;
34 #include "msnswitchboardsocket.h"
36 namespace PeerToPeer
{
38 Transport::Transport(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
];
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());
76 QObject::connect(bridge
, SIGNAL(readyRead(const QByteArray
&)), SLOT(slotOnReceive(const QByteArray
&)));
82 void Transport::setDefaultBridge(MSNSwitchBoardSocket
* mss
)
85 QObject::connect((MSNSwitchBoardSocket
*)mDefaultBridge
, SIGNAL(messageReceived(const QString
&, const QByteArray
&)), SLOT(slotOnReceive(const QString
&, const QByteArray
&)));
90 //BEGIN Private Slot Methods
92 // void Transport::slotOnReceive(Message& message)
96 void Transport::slotOnReceive(const QString
& contact
, const QByteArray
& bytes
)
98 kDebug (14140) << " >> RECEIVED " << bytes
.size() << " bytes.";
99 // Message message = mFormatter->readMessage(bytes);
107 TransportBridge::TransportBridge(const KNetwork::KInetSocketAddress
& to
, MessageFormatter
* formatter
, QObject
* parent
)
111 mFormatter
= formatter
;
114 TransportBridge::TransportBridge(KNetwork::KClientSocketBase
* socket
, MessageFormatter
* formatter
, QObject
* parent
)
118 mAddress
= mSocket
->peerAddress();
121 TransportBridge::~TransportBridge()
125 //BEGIN Public Methods
127 void TransportBridge::connect()
132 void TransportBridge::disconnect()
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()
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)));
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()
197 kDebug(14140) << "Bridge (" << name() << ") ALREADY CONNECTED " << mSocket
->peerAddress().toString() << " <-> " << mSocket
->localAddress().toString();
201 KStreamSocket
*socket
= static_cast<KStreamSocket
*>(mSocket
);
202 socket
->setTimeout(5000);
203 QObject::connect(socket
, SIGNAL(timeOut()), SLOT(slotOnSocketConnectTimeout()));
207 void TcpTransportBridge::slotOnDisconnect()
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()));
219 mSocket
->disconnect();
222 mSocket
->deleteLater();
226 void TcpTransportBridge::slotOnSocketClose()
228 mSocket
->disconnect();
229 kDebug(14140) << "Bridge (" << name() << ") DISCONNECTED {" << mSocket
->peerAddress().toString() << " <-> " << mSocket
->localAddress().toString() << "}";
231 mSocket
->deleteLater();
234 emit
bridgeDisconnect();
237 void TcpTransportBridge::slotOnSocketConnect()
239 kDebug(14140) << "Bridge (" << name() << ") CONNECTED to " << mSocket
->peerAddress().toString() << " from "
240 << mSocket
->localAddress().toString() << endl
;
243 QObject::connect(mSocket
, SIGNAL(readyRead()), SLOT(slotOnSocketReceive()));
244 QObject::connect(mSocket
, SIGNAL(closed()), SLOT(slotOnSocketClose()));
247 QString foo
= "foo\0";
248 mSocket
->write(foo
.toAscii(), foo
.length());
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.";
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
);
287 // Message message = mFormatter->readMessage(bytes, true);
288 // emit messageReceived(message);
292 kDebug (14140) << "Bridge (" << name() << ") waiting for " << mLength
<< " bytes.";
300 //BEGIN Private Slot Methods
302 void TcpTransportBridge::slotOnSocketConnectTimeout()
304 kDebug (14140) << "Bridge (" << name() << ") CONNECT timeout.";
305 emit
bridgeConnectTimeout();
306 mSocket
->deleteLater();
315 TcpTransportBridge::Buffer::Buffer(quint32 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();
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
);
356 #include "transport.moc"