TransferSessionImpl.h

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2006-2007 by Peter Dimov.
00004 
00005 This file is part of Calitko (http://www.calitko.org).
00006 
00007 Calitko is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 Calitko is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Calitko; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 */
00022 
00023 #ifndef PROTOCOLS__BIT_TORRENT__TRANSFERS__TRANSFER_SESSION_IMPL_H
00024 #define PROTOCOLS__BIT_TORRENT__TRANSFERS__TRANSFER_SESSION_IMPL_H
00025 
00026 #include "Imports.h"
00027 #include "PacketSession.h"
00028 #include "TransferSession.h"
00029 #include "TransferSessionStatus.h"
00030 
00031 namespace Protocols {
00032 namespace BitTorrent {
00033 namespace Transfers {
00034 
00051 class IntegerResetStopwatch
00052 {
00053     CALITKO_MOCKABLE
00054 
00055 public:
00056     virtual                 ~IntegerResetStopwatch() {}
00057     virtual void            reset() = 0;
00058     virtual qint64          elapsedSeconds() const = 0;
00059 };
00060 
00061 struct Handshake // \ŧodo : public Data
00062 {
00063     enum ProtocolVersion
00064     {
00065         ProtocolVersion1            = 0,
00066         ProtocolVersionUnknown      = 1
00067     };
00068 
00069     typedef QByteArray PeerId; // \todo reuse the FixedSizeByteArray declaration?
00070 
00071     ProtocolVersion protocolVersion;
00072     bool            hasFastExtension; // extension bit 62
00073     PeerId          peerId;
00074     int             numberPieces; // \todo use Torrent instead? It would contain InfoHash and other data
00075 
00076     Handshake (ProtocolVersion v, bool f, const PeerId &p, int n)
00077     : protocolVersion (v), hasFastExtension (f), peerId (p), numberPieces (n) {}
00078 };
00079 
00081 
00092 class TransferSessionImpl : public TransferSession, public SessionStatus
00093 {
00094     CALITKO_TESTABLE
00095     REFERENCE_OBJECT (TransferSessionImpl)
00096 
00097 public:
00098                 TransferSessionImpl (Session *, const Handshake &,
00099                                      IntegerResetStopwatch *downloadStopwatch,
00100                                      IntegerResetStopwatch *uploadStopwatch,
00101                                      TransferSessionStatus *);
00102 
00103     // Interface TransferSession implementation:
00104     void        sendPacket (const Packet &);
00105     void        close();
00106 
00107     bool        areWeChoked() const;
00108     bool        areWeInterested() const;
00109     bool        areWeSnubbed() const;
00110     bool        areWeSeeder() const;
00111     bool        isPeerChoked() const;
00112     bool        isPeerInterested() const;
00113     bool        isPeerSnubbed() const;
00114     bool        isPeerSeeder() const;
00115 
00116     qint64      totalDownloaded() const;
00117     qint64      totalUploaded() const;
00118     qint64      currentDownloadSpeed() const;
00119     qint64      currentUploadSpeed() const;
00120 
00121     QBitArray   peerPiecesAvailable() const;
00122     QBitArray   wePiecesAvailable() const;
00123 
00124     // Interface SessionStatus implementation:
00125     void        sessionReceivedData (Session *, const Data &);
00126     void        sessionSendingData (Session *, const Data &);
00127     void        sessionClosing (Session *);
00128     void        sessionClosed (Session *);
00129 
00130 private:
00131     void        receivedChoke (const Choke &);
00132     void        receivedUnchoke (const Unchoke &);
00133     void        receivedInterested (const Interested &);
00134     void        receivedNotInterested (const NotInterested &);
00135     void        receivedPiece (const Piece &);
00136     void        receivedBitField (const BitField &);
00137     void        receivedHaveAll (const HaveAll &);
00138     void        receivedHaveNone (const HaveNone &);
00139     void        receivedHave (const Have &);
00140     void        receivedUnhandled (const PacketBase &);
00141 
00142     void        sentChoke (const Choke &);
00143     void        sentUnchoke (const Unchoke &);
00144     void        sentInterested (const Interested &);
00145     void        sentNotInterested (const NotInterested &);
00146     void        sentPiece (const Piece &);
00147     void        sentBitField (const BitField &);
00148     void        sentHaveAll (const HaveAll &);
00149     void        sentHaveNone (const HaveNone &);
00150     void        sentHave (const Have &);
00151     void        sentUnhandled (const PacketBase &);
00152 
00153     void            updateDownloadSpeed (int pieceLength) const;
00154     void            updateUploadSpeed (int pieceLength) const;
00155     static void     shiftList (QList <qint64> &list, qint64 count);
00156     static qint64   calculateAverage (const QList <qint64> &list);
00157     static void     setPiecesAvailable (QBitArray &piecesAvailable,
00158                                         const QByteArray &bitField);
00159     void            unregisterBitFieldHaveAllHaveNoneReceiveHandlers();
00160     void            unregisterBitFieldHaveAllHaveNoneSendHandlers();
00161 
00162 private:
00163     typedef ObjectDispatcher <PacketBase> PacketDispatcher;
00164 
00166     static const int        SpeedMovingAverageDuration = 20;
00168     static const int        SnubbedTimeout = 20;
00169 
00170     Session                 *session_;
00171     Handshake               handshake_;
00172     TransferSessionStatus   *status_;
00173     PacketDispatcher        inPacketDispatcher_;
00174     PacketDispatcher        outPacketDispatcher_;
00175 
00176     bool                    areWeChoked_;
00177     bool                    areWeInterested_;
00178     bool                    areWeSeeder_;
00179     bool                    isPeerChoked_;
00180     bool                    isPeerInterested_;
00181     bool                    isPeerSeeder_;
00182 
00183     qint64                  totalDownloaded_;
00184     qint64                  totalUploaded_;
00185     IntegerResetStopwatch   *downloadStopwatch_;
00186     IntegerResetStopwatch   *uploadStopwatch_;
00187     mutable QList <qint64>  downloadHistory_;
00188     mutable QList <qint64>  uploadHistory_;
00189 
00190     QBitArray               peerPiecesAvailable_;
00191     QBitArray               wePiecesAvailable_;
00192 };
00193 
00194 } // namespace Transfers
00195 } // namespace BitTorrent
00196 } // namespace Protocols
00197 
00198 #endif // PROTOCOLS__BIT_TORRENT__TRANSFERS__TRANSFER_SESSION_IMPL_H