Session.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "Qt.h"
00024 #include "Session.h"
00025 #include "Imports.cpp"
00026
00027 namespace Protocols {
00028 namespace BitTorrent {
00029 namespace Transfers {
00030 namespace Constants {
00031
00032 const QByteArray ProtocolVersion = "BitTorrent protocol";
00033 const QByteArray ProtocolReservedBytes = QByteArray (8, '\0');
00034 const uchar ProtocolVersionLength = (uchar) ProtocolVersion.length();
00035 const int ReservedBytesCount = 8;
00036 const int RawSha1HashLength = 20;
00037 const int PeerIdLength = 20;
00038 const int HandshakeLength = sizeof (ProtocolVersionLength) +
00039 ProtocolVersionLength +
00040 ReservedBytesCount +
00041 RawSha1HashLength + PeerIdLength;
00042
00043 }
00044 }
00045 }
00046 }
00047
00048 Session::Session (Transport &t, SessionStatus &s, const PeerInfo &lpi)
00049 : transport (t), status (s), localPeerInfo (lpi),
00050 fileId (QByteArray (Constants::RawSha1HashLength, '\0')),
00051 state (DisconnectedTransport)
00052 {
00053 }
00054
00055 Session::~Session()
00056 {
00057 }
00058
00059 void Session::establish (const PeerInfo &pi, const FileId &fi)
00060 {
00061 state = EstablishingSession;
00062 remotePeerInfo = pi;
00063 fileId = fi;
00064 status.establishingSession();
00065 writeHandshake();
00066 if (readHandshake()) {
00067 state = ExchangingPackets;
00068 status.sessionEstablished();
00069
00070 }
00071 }
00072
00073 void Session::waitRequest()
00074 {
00075 state = AwaitingRequest;
00076 status.establishingSession();
00077 if (readHandshake()) {
00078 state = AwaitingAccept;
00079 status.sessionRequestedFor (fileId);
00080 }
00081 }
00082
00083 void Session::accept()
00084 {
00085 Q_ASSERT (state == AwaitingAccept);
00086 writeHandshake();
00087 state = ExchangingPackets;
00088 status.sessionEstablished();
00089
00090 }
00091
00092 void Session::connected()
00093 {
00094 Q_ASSERT (false);
00095 }
00096
00097 void Session::readyRead()
00098 {
00099 Q_ASSERT (state != DisconnectedTransport);
00100 switch (state)
00101 {
00102 case EstablishingSession:
00103 if (!readHandshake())
00104 break;
00105 state = ExchangingPackets;
00106 status.sessionEstablished();
00107
00108 break;
00109 case AwaitingRequest:
00110 if (!readHandshake())
00111 break;
00112 state = AwaitingAccept;
00113 status.sessionRequestedFor (fileId);
00114 break;
00115 case AwaitingAccept:
00116
00117 break;
00118 case ExchangingPackets:
00119 readPacket();
00120 break;
00121 case DisconnectedTransport:
00122 Q_ASSERT (false);
00123 break;
00124 }
00125 }
00126
00127 void Session::readyWrite()
00128 {
00129 }
00130
00131 void Session::disconnected()
00132 {
00133 state = DisconnectedTransport;
00134 status.sessionClosed();
00135 }
00136
00138
00146 bool Session::readHandshake()
00147 {
00148 using namespace Constants;
00149 QByteArray handshakeBytes = transport.read (HandshakeLength);
00150
00151 if (handshakeBytes.size() == 0)
00152 return false;
00153
00154 BinaryReader reader (handshakeBytes, BinaryReader::BigEndian);
00155
00156 uchar protocolVersionLength = reader.readByte();
00157 if (protocolVersionLength != ProtocolVersionLength)
00158 return false;
00159 QByteArray protocol = reader.readBytes (ProtocolVersionLength);
00160 if (protocol != ProtocolVersion)
00161 return false;
00162 QByteArray reserved = reader.readBytes (ReservedBytesCount);
00163 fileId = reader.readBytes (RawSha1HashLength);
00164 remotePeerInfo.id = reader.readBytes (PeerIdLength);
00165
00166 return true;
00167 }
00168
00170 void Session::writeHandshake()
00171 {
00172 using namespace Constants;
00173
00174
00175 BinaryWriter writer (BinaryWriter::BigEndian);
00176 writer.reserve (HandshakeLength);
00177
00178 writer.writeByte (ProtocolVersionLength);
00179 writer.writeBytes (ProtocolVersion);
00180 writer.writeBytes (ProtocolReservedBytes);
00181 writer.writeBytes (fileId);
00182 writer.writeBytes (localPeerInfo.id);
00183 Q_ASSERT (writer.hasWrittenAll() && !writer.hasWrittenPastEnd());
00184
00185 bool hasWritten = transport.write (writer.buffer());
00186
00187 Q_ASSERT (hasWritten == true);
00188 }
00189
00190 void Session::readPacket()
00191 {
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 }
00204
00205 void Session::writePacket()
00206 {
00207 }