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 "TransferSessionImpl.h"
00025 #include "Imports.cpp"
00026
00028
00039 TransferSessionImpl::TransferSessionImpl (
00040 Session *session,
00041 const Handshake &handshake,
00042 IntegerResetStopwatch *downloadStopwatch,
00043 IntegerResetStopwatch *uploadStopwatch,
00044 TransferSessionStatus *status)
00045 : session_ (session), handshake_ (handshake), status_ (status),
00046 inPacketDispatcher_(), outPacketDispatcher_(),
00047 areWeChoked_ (true), areWeInterested_ (false), areWeSeeder_ (false),
00048 isPeerChoked_ (true), isPeerInterested_ (false), isPeerSeeder_ (false),
00049 totalDownloaded_ (0), totalUploaded_ (0),
00050 downloadStopwatch_ (downloadStopwatch), uploadStopwatch_ (uploadStopwatch),
00051 downloadHistory_(), uploadHistory_(),
00052 peerPiecesAvailable_ (handshake.numberPieces),
00053 wePiecesAvailable_ (handshake.numberPieces)
00054 {
00055 inPacketDispatcher_.registerTypeHandler (
00056 Callable <void (const Choke &)> (
00057 this, &TransferSessionImpl::receivedChoke));
00058 inPacketDispatcher_.registerTypeHandler (
00059 Callable <void (const Unchoke &)> (
00060 this, &TransferSessionImpl::receivedUnchoke));
00061 inPacketDispatcher_.registerTypeHandler (
00062 Callable <void (const Interested &)> (
00063 this, &TransferSessionImpl::receivedInterested));
00064 inPacketDispatcher_.registerTypeHandler (
00065 Callable <void (const NotInterested &)> (
00066 this, &TransferSessionImpl::receivedNotInterested));
00067 inPacketDispatcher_.registerTypeHandler (
00068 Callable <void (const Piece &)> (
00069 this, &TransferSessionImpl::receivedPiece));
00070 inPacketDispatcher_.registerTypeHandler (
00071 Callable <void (const BitField &)> (
00072 this, &TransferSessionImpl::receivedBitField));
00073 inPacketDispatcher_.registerTypeHandler (
00074 Callable <void (const Have &)> (
00075 this, &TransferSessionImpl::receivedHave));
00076 if (handshake_.hasFastExtension) {
00077 inPacketDispatcher_.registerTypeHandler (
00078 Callable <void (const HaveAll &)> (
00079 this, &TransferSessionImpl::receivedHaveAll));
00080 inPacketDispatcher_.registerTypeHandler (
00081 Callable <void (const HaveNone &)> (
00082 this, &TransferSessionImpl::receivedHaveNone));
00083 }
00084 inPacketDispatcher_.registerNotHandledHandler (
00085 Callable <void (const PacketBase &)> (
00086 this, &TransferSessionImpl::receivedUnhandled));
00087
00088 outPacketDispatcher_.registerTypeHandler (
00089 Callable <void (const Choke &)> (
00090 this, &TransferSessionImpl::sentChoke));
00091 outPacketDispatcher_.registerTypeHandler (
00092 Callable <void (const Unchoke &)> (
00093 this, &TransferSessionImpl::sentUnchoke));
00094 outPacketDispatcher_.registerTypeHandler (
00095 Callable <void (const Interested &)> (
00096 this, &TransferSessionImpl::sentInterested));
00097 outPacketDispatcher_.registerTypeHandler (
00098 Callable <void (const NotInterested &)> (
00099 this, &TransferSessionImpl::sentNotInterested));
00100 outPacketDispatcher_.registerTypeHandler (
00101 Callable <void (const Piece &)> (
00102 this, &TransferSessionImpl::sentPiece));
00103 outPacketDispatcher_.registerTypeHandler (
00104 Callable <void (const BitField &)> (
00105 this, &TransferSessionImpl::sentBitField));
00106 outPacketDispatcher_.registerTypeHandler (
00107 Callable <void (const Have &)> (
00108 this, &TransferSessionImpl::sentHave));
00109 if (handshake_.hasFastExtension) {
00110 outPacketDispatcher_.registerTypeHandler (
00111 Callable <void (const HaveAll &)> (
00112 this, &TransferSessionImpl::sentHaveAll));
00113 outPacketDispatcher_.registerTypeHandler (
00114 Callable <void (const HaveNone &)> (
00115 this, &TransferSessionImpl::sentHaveNone));
00116 }
00117 outPacketDispatcher_.registerNotHandledHandler (
00118 Callable <void (const PacketBase &)> (
00119 this, &TransferSessionImpl::sentUnhandled));
00120
00121 for (int i = SpeedMovingAverageDuration; i > 0; --i) {
00122 downloadHistory_.append (0);
00123 uploadHistory_.append (0);
00124 }
00125 }
00126
00128
00131 void TransferSessionImpl::sendPacket (const Packet &packet)
00132 {
00133 status_->transferSessionSendingPacket (this, packet);
00134 outPacketDispatcher_.dispatch (*packet);
00135 session_->send (packet);
00136 }
00137
00139 void TransferSessionImpl::close()
00140 {
00141 session_->close();
00142 }
00143
00145 bool TransferSessionImpl::areWeChoked() const
00146 {
00147 return areWeChoked_;
00148 }
00149
00151 bool TransferSessionImpl::areWeInterested() const
00152 {
00153 return areWeInterested_;
00154 }
00155
00157 bool TransferSessionImpl::areWeSnubbed() const
00158 {
00159 return downloadStopwatch_->elapsedSeconds() > SnubbedTimeout
00160 && !isPeerChoked();
00161 }
00162
00164 bool TransferSessionImpl::areWeSeeder() const
00165 {
00166 return areWeSeeder_;
00167 }
00168
00170 bool TransferSessionImpl::isPeerChoked() const
00171 {
00172 return isPeerChoked_;
00173 }
00174
00176 bool TransferSessionImpl::isPeerInterested() const
00177 {
00178 return isPeerInterested_;
00179 }
00180
00182 bool TransferSessionImpl::isPeerSnubbed() const
00183 {
00184 return uploadStopwatch_->elapsedSeconds() > SnubbedTimeout
00185 && !areWeChoked();
00186 }
00187
00189 bool TransferSessionImpl::isPeerSeeder() const
00190 {
00191 return isPeerSeeder_;
00192 }
00193
00195 qint64 TransferSessionImpl::totalDownloaded() const
00196 {
00197 return totalDownloaded_;
00198 }
00199
00201 qint64 TransferSessionImpl::totalUploaded() const
00202 {
00203 return totalUploaded_;
00204 }
00205
00207 qint64 TransferSessionImpl::currentDownloadSpeed() const
00208 {
00209 updateDownloadSpeed (0);
00210 return calculateAverage (downloadHistory_);
00211 }
00212
00214 qint64 TransferSessionImpl::currentUploadSpeed() const
00215 {
00216 updateUploadSpeed (0);
00217 return calculateAverage (uploadHistory_);
00218 }
00219
00221 QBitArray TransferSessionImpl::peerPiecesAvailable() const
00222 {
00223 return peerPiecesAvailable_;
00224 }
00225
00227 QBitArray TransferSessionImpl::wePiecesAvailable() const
00228 {
00229 return wePiecesAvailable_;
00230 }
00231
00233
00241 void TransferSessionImpl::sessionReceivedData (Session *, const Data &data)
00242 {
00243 Packet packet = data;
00244 if (inPacketDispatcher_.dispatch (*packet))
00245 status_->transferSessionReceivedPacket (this, packet);
00246 }
00247
00249
00253 void TransferSessionImpl::sessionSendingData (Session *, const Data &)
00254 {
00255
00256 }
00257
00259
00262 void TransferSessionImpl::sessionClosing (Session *)
00263 {
00264 status_->transferSessionClosing (this);
00265 }
00266
00268
00271 void TransferSessionImpl::sessionClosed (Session *)
00272 {
00273 status_->transferSessionClosed (this);
00274 }
00275
00277 void TransferSessionImpl::receivedChoke (const Choke &)
00278 {
00279 areWeChoked_ = true;
00280 }
00281
00283 void TransferSessionImpl::receivedUnchoke (const Unchoke &)
00284 {
00285 areWeChoked_ = false;
00286 }
00287
00289 void TransferSessionImpl::receivedInterested (const Interested &)
00290 {
00291 isPeerInterested_ = true;
00292 }
00293
00295 void TransferSessionImpl::receivedNotInterested (const NotInterested &)
00296 {
00297 isPeerInterested_ = false;
00298 }
00299
00301 void TransferSessionImpl::receivedPiece (const Piece &piece)
00302 {
00303 int length = piece.pieceBytes().length();
00304 totalDownloaded_ += length;
00305 updateDownloadSpeed (length);
00306 }
00307
00309 void TransferSessionImpl::receivedBitField (const BitField &bitField)
00310 {
00311 setPiecesAvailable (peerPiecesAvailable_, bitField.bitField());
00312 unregisterBitFieldHaveAllHaveNoneReceiveHandlers();
00313 }
00314
00316 void TransferSessionImpl::receivedHaveAll (const HaveAll &)
00317 {
00318 peerPiecesAvailable_.fill (true);
00319 isPeerSeeder_ = true;
00320 unregisterBitFieldHaveAllHaveNoneReceiveHandlers();
00321 }
00322
00324 void TransferSessionImpl::receivedHaveNone (const HaveNone &)
00325 {
00326 peerPiecesAvailable_.fill (false);
00327 isPeerSeeder_ = false;
00328 unregisterBitFieldHaveAllHaveNoneReceiveHandlers();
00329 }
00330
00332 void TransferSessionImpl::receivedHave (const Have &have)
00333 {
00334 peerPiecesAvailable_.setBit (have.pieceIndex(), true);
00335 if (peerPiecesAvailable_.size() == peerPiecesAvailable_.count (true))
00336 isPeerSeeder_ = true;
00337 }
00338
00340
00346 void TransferSessionImpl::receivedUnhandled (const PacketBase &)
00347 {
00348 session_->close();
00349 }
00350
00352 void TransferSessionImpl::sentChoke (const Choke &)
00353 {
00354 isPeerChoked_ = true;
00355 }
00356
00358 void TransferSessionImpl::sentUnchoke (const Unchoke &)
00359 {
00360 isPeerChoked_ = false;
00361 }
00362
00364 void TransferSessionImpl::sentInterested (const Interested &)
00365 {
00366 areWeInterested_ = true;
00367 }
00368
00370 void TransferSessionImpl::sentNotInterested (const NotInterested &)
00371 {
00372 areWeInterested_ = false;
00373 }
00374
00376 void TransferSessionImpl::sentPiece (const Piece &piece)
00377 {
00378 int length = piece.pieceBytes().length();
00379 totalUploaded_ += length;
00380 updateUploadSpeed (length);
00381 }
00382
00384 void TransferSessionImpl::sentBitField (const BitField &bitField)
00385 {
00386 setPiecesAvailable (wePiecesAvailable_, bitField.bitField());
00387 unregisterBitFieldHaveAllHaveNoneSendHandlers();
00388 }
00389
00391 void TransferSessionImpl::sentHaveAll (const HaveAll &)
00392 {
00393 wePiecesAvailable_.fill (true);
00394 areWeSeeder_ = true;
00395 unregisterBitFieldHaveAllHaveNoneSendHandlers();
00396 }
00397
00399 void TransferSessionImpl::sentHaveNone (const HaveNone &)
00400 {
00401 wePiecesAvailable_.fill (false);
00402 areWeSeeder_ = false;
00403 unregisterBitFieldHaveAllHaveNoneSendHandlers();
00404 }
00405
00407 void TransferSessionImpl::sentHave (const Have &have)
00408 {
00409 wePiecesAvailable_.setBit (have.pieceIndex(), true);
00410 if (wePiecesAvailable_.size() == wePiecesAvailable_.count (true))
00411 areWeSeeder_ = true;
00412 }
00413
00415
00421 void TransferSessionImpl::sentUnhandled (const PacketBase &)
00422 {
00423 Q_ASSERT (false);
00424 }
00425
00427
00434 void TransferSessionImpl::updateDownloadSpeed (int pieceLength) const
00435 {
00436 qint64 delay = downloadStopwatch_->elapsedSeconds();
00437 shiftList (downloadHistory_, delay);
00438 downloadHistory_.front() += pieceLength;
00439 downloadStopwatch_->reset();
00440 }
00441
00443
00450 void TransferSessionImpl::updateUploadSpeed (int pieceLength) const
00451 {
00452 qint64 delay = uploadStopwatch_->elapsedSeconds();
00453 shiftList (uploadHistory_, delay);
00454 uploadHistory_.front() += pieceLength;
00455 uploadStopwatch_->reset();
00456 }
00457
00459 void TransferSessionImpl::shiftList (QList <qint64> &list, qint64 count)
00460 {
00461 count = qMin (count, static_cast <qint64> (SpeedMovingAverageDuration));
00462 for (qint64 i = count; i > 0; --i) {
00463 list.prepend (0);
00464 list.takeLast();
00465 }
00466 }
00467
00469 qint64 TransferSessionImpl::calculateAverage (const QList <qint64> &list)
00470 {
00471 Q_ASSERT (list.size() != 0);
00472 qint64 sum = std::accumulate (list.begin(), list.end(), 0);
00473 return sum / list.size();
00474 }
00475
00477 void TransferSessionImpl::setPiecesAvailable (QBitArray &piecesAvailable,
00478 const QByteArray &bitField)
00479 {
00480 int index = 0;
00481 int last = piecesAvailable.size();
00482 foreach (const char &ch, bitField)
00483 for (uchar mask = 0x80; mask != 0 && index < last; mask >>= 1, ++index)
00484 piecesAvailable.setBit (index, ch & mask);
00485 }
00486
00488
00500 void TransferSessionImpl::unregisterBitFieldHaveAllHaveNoneReceiveHandlers()
00501 {
00502 inPacketDispatcher_.unregisterTypeHandler (
00503 Callable <void (const BitField &)> (
00504 this, &TransferSessionImpl::receivedBitField));
00505 inPacketDispatcher_.unregisterTypeHandler (
00506 Callable <void (const HaveAll &)> (
00507 this, &TransferSessionImpl::receivedHaveAll));
00508 inPacketDispatcher_.unregisterTypeHandler (
00509 Callable <void (const HaveNone &)> (
00510 this, &TransferSessionImpl::receivedHaveNone));
00511 }
00512
00514
00519 void TransferSessionImpl::unregisterBitFieldHaveAllHaveNoneSendHandlers()
00520 {
00521 outPacketDispatcher_.unregisterTypeHandler (
00522 Callable <void (const BitField &)> (
00523 this, &TransferSessionImpl::sentBitField));
00524 outPacketDispatcher_.unregisterTypeHandler (
00525 Callable <void (const HaveAll &)> (
00526 this, &TransferSessionImpl::sentHaveAll));
00527 outPacketDispatcher_.unregisterTypeHandler (
00528 Callable <void (const HaveNone &)> (
00529 this, &TransferSessionImpl::sentHaveNone));
00530 }