org.klomp.snark

## Class PeerState

- java.lang.Object
- - org.klomp.snark.PeerState

- All Implemented Interfaces:
    DataLoader

      class PeerState
      extends Object
      implements DataLoader

  Manages the state and protocol logic for a BitTorrent peer connection.
  This class tracks peer interest/choking status, piece availability, request queues, and handles all BitTorrent protocol message processing.

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `(package private) BitField` | `bitfield` the pieces the peer has.
    `(package private) boolean` | `choked`
    `(package private) boolean` | `choking`
    `(package private) PeerConnectionIn` | `in`
    `(package private) boolean` | `interested`
    `(package private) boolean` | `interesting`
    `(package private) PeerListener` | `listener` Fixme, used by Peer.disconnect() to get to the coordinator
    `static int` | `MAX_PIPELINE`
    `static int` | `MIN_PIPELINE`
    `(package private) PeerConnectionOut` | `out`
    `static int` | `PARTSIZE`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `PeerState(Peer peer, PeerListener listener, BandwidthListener bwl, MetaInfo metainfo, PeerConnectionIn in, PeerConnectionOut out)`

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `(package private) void` | `addRequest()` Adds a new request to the outstanding requests list.
    `(package private) void` | `allowedFastMessage(int piece)` BEP 6 Ignored for now
    `(package private) void` | `bitfieldMessage(byte[] bitmap)`
    `(package private) void` | `cancelMessage(int piece, int begin, int length)`
    `(package private) void` | `cancelPiece(int piece)` Tell the other side that we are no longer interested in any of the outstanding requests (if any) for this piece.
    `(package private) void` | `chokeMessage(boolean choke)`
    `(package private) void` | `extensionMessage(int id, byte[] bs)`
    `(package private) BandwidthListener` | `getBandwidthListener()`
    `(package private) Request` | `getOutstandingRequest(int piece, int begin, int length)` Called when a piece message is being processed by the incoming connection.
    `(package private) String` | `getRequests()` debug
    `(package private) void` | `haveMessage(boolean isAll)` BEP 6
    `(package private) void` | `haveMessage(int piece)`
    `(package private) void` | `havePiece(int piece)` We now have this piece.
    `(package private) void` | `interestedMessage(boolean interest)`
    `(package private) void` | `keepAlive()`
    `(package private) void` | `keepAliveMessage()`
    `ByteArray` | `loadData(int piece, int begin, int length)` This is the callback that PeerConnectionOut calls
    `(package private) void` | `pieceMessage(Request req)` Called when a full chunk (i.e.
    `(package private) void` | `portMessage(int port)` Unused
    `(package private) void` | `rejectMessage(int piece, int begin, int length)` BEP 6
    `(package private) void` | `requestMessage(int piece, int begin, int length)`
    `(package private) void` | `retransmitRequests()`
    `(package private) List<Request>` | `returnPartialPieces()` Get partial pieces, give them back to PeerCoordinator.
    `(package private) void` | `setChoking(boolean choke)`
    `(package private) void` | `setInteresting(boolean interest)`
    `void` | `setMetaInfo(MetaInfo meta)` Switch from magnet mode to normal mode.
    `(package private) void` | `suggestMessage(int piece)` BEP 6 Treated as "have" for now
    `(package private) void` | `unknownMessage(int type, byte[] bs)`
    `(package private) void` | `uploaded(int size)` Called when some bytes have left the outgoing connection.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### bitfield

          BitField bitfield

      the pieces the peer has. locking: this

    - #### choked

          volatile boolean choked

    - #### choking

          volatile boolean choking

    - #### in

          final PeerConnectionIn in

    - #### interested

          volatile boolean interested

    - #### interesting

          volatile boolean interesting

    - #### listener

          final PeerListener listener

      Fixme, used by Peer.disconnect() to get to the coordinator

    - #### MAX_PIPELINE

          public static final int MAX_PIPELINE

      See Also:
        Constant Field Values

    - #### MIN_PIPELINE

          public static final int MIN_PIPELINE

      See Also:
        Constant Field Values

    - #### out

          final PeerConnectionOut out

    - #### PARTSIZE

          public static final int PARTSIZE

      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### PeerState

          PeerState(Peer peer,
                    PeerListener listener,
                    BandwidthListener bwl,
                    MetaInfo metainfo,
                    PeerConnectionIn in,
                    PeerConnectionOut out)

      Parameters:
        `metainfo` - null if in magnet mode

  - ### Method Detail

    - #### addRequest

          void addRequest()

      Adds a new request to the outstanding requests list. Then send interested if we weren't. Then send new requests if not choked. If nothing to request, send not interested if we were.

      This is called from several places:

             By getOutstandingRequest() when the first part of a chunk comes in
             By havePiece() when somebody got a new piece completed
             By chokeMessage() when we receive an unchoke
             By setInteresting() when we are now interested
             By PeerCoordinator.updatePiecePriorities()

    - #### allowedFastMessage

          void allowedFastMessage(int piece)

      BEP 6 Ignored for now

    - #### bitfieldMessage

          void bitfieldMessage(byte[] bitmap)

    - #### cancelMessage

          void cancelMessage(int piece,
                             int begin,
                             int length)

    - #### cancelPiece

          void cancelPiece(int piece)

      Tell the other side that we are no longer interested in any of the outstanding requests (if any) for this piece.

    - #### chokeMessage

          void chokeMessage(boolean choke)

    - #### extensionMessage

          void extensionMessage(int id,
                                byte[] bs)

    - #### getBandwidthListener

          BandwidthListener getBandwidthListener()

    - #### getOutstandingRequest

          Request getOutstandingRequest(int piece,
                                        int begin,
                                        int length)

      Called when a piece message is being processed by the incoming connection. That is, when the header of the piece message was received. Returns null when there was no such request. It also requeues/sends requests when it thinks that they must have been lost.

    - #### getRequests

          String getRequests()

      debug
      Returns:
        string or null

    - #### haveMessage

          void haveMessage(boolean isAll)

      BEP 6
      Parameters:
        `isAll` - true for have_all, false for have_none

    - #### haveMessage

          void haveMessage(int piece)

    - #### havePiece

          void havePiece(int piece)

      We now have this piece. Tell the peer and cancel any requests for the piece.

    - #### interestedMessage

          void interestedMessage(boolean interest)

    - #### keepAlive

          void keepAlive()

    - #### keepAliveMessage

          void keepAliveMessage()

    - #### loadData

          public ByteArray loadData(int piece,
                                    int begin,
                                    int length)

      This is the callback that PeerConnectionOut calls
      Specified by:
        `loadData` in interface `DataLoader`
      Returns:
        bytes or null for errors such as not having the piece yet
      Throws:
        `RuntimeException` - on IOE getting the data

    - #### pieceMessage

          void pieceMessage(Request req)

      Called when a full chunk (i.e. a piece message) has been received by PeerConnectionIn.

      This may block quite a while if it is the last chunk for a piece, as it calls the listener, who stores the piece and then calls havePiece for every peer on the torrent (including us).

    - #### portMessage

          void portMessage(int port)

      Unused

    - #### rejectMessage

          void rejectMessage(int piece,
                             int begin,
                             int length)

      BEP 6

    - #### requestMessage

          void requestMessage(int piece,
                              int begin,
                              int length)

    - #### retransmitRequests

          void retransmitRequests()

    - #### returnPartialPieces

          List<Request> returnPartialPieces()

      Get partial pieces, give them back to PeerCoordinator. Clears the request queue.
      Returns:
        List of PartialPieces, even those with an offset == 0, or empty list

    - #### setChoking

          void setChoking(boolean choke)

    - #### setInteresting

          void setInteresting(boolean interest)

    - #### setMetaInfo

          public void setMetaInfo(MetaInfo meta)

      Switch from magnet mode to normal mode. If we already have the metainfo, this does nothing.
      Parameters:
        `meta` - non-null

    - #### suggestMessage

          void suggestMessage(int piece)

      BEP 6 Treated as "have" for now

    - #### unknownMessage

          void unknownMessage(int type,
                              byte[] bs)

    - #### uploaded

          void uploaded(int size)

      Called when some bytes have left the outgoing connection. XXX - Should indicate whether it was a real piece or overhead.