Tbbs 2.3-16/Disk 1/README/TIPXPROT.DOC

38.8 KB c6f283337cc79944…
                    TIPX - TBBS/IPAD IPX protocol            Rev: 01/23/95

This protocol was designed by eSoft, Inc. and is released into the
public domain.  Feel free to use it for any purpose you wish.

Rather than use SPX to obtain a connection between computers, the TBBS/IPAD
IPX protocol uses only IPX itself.  It uses the minimal portion of the IPX
protocol in order that it may operate on the widest range of IPX network
hardware and software.  Note:  This protocol DOES count on any bridges or
internetwork IPX routers implementing SAP (Service Advertising Protocol).

A TBBS/IPAD server (i.e. a node which will accept one or more incoming
connections from other nodes) will advertise itself as a TYPE=9191h server.
Each server is located on the network (or internetwork) using the Service
Advertising Protocol (broadcast messages to the special socket 0452h) and
posts a server name which may be up to 48 characters in length.

A TBBS/IPAD client who wishes to locate a specific server name, should
broadcast a SAP query packet with a Query Type=3 and a Server Type=9191h.
It should then examine each SAP response packet it receives to find the
name of the server it wishes to connect with.  When it finds the name,
the same packet will give the full 12 byte IPX address (net:node:socket)
of that server and the client may proceed to attempt to open a circuit
directly with that IPX address.

The TBBS/IPAD IPX protocol uses standard IPX packets (type=4) with a maximum
data field length of 520 bytes (total packet size of 550 bytes).  The format
of the data within these packets is as follows:


                   TBBS/IPAD IPX packet data block format
      Offset
      dec hex
              ┌───────────────────────────────────────────────┐
        0   0 │       # of bytes in data field (High Order)   │
              ├───────────────────────────────────────────────┤
        1   1 │       # of bytes in data field (Low Order)    │
              ├───────────────────────────────────────────────┤
        2   2 │       Sequence Number (High Order)            │
              ├───────────────────────────────────────────────┤
        3   3 │       Sequence Number (Low Order)             │
              ├───────────────────────────────────────────────┤
        4   4 │       Packet Type                             │
              ├───────────────────────────────────────────────┤
        5   5 │       Circuit Number                          │
              ├───────────────────────────────────────────────┤
        6   6 │       Checksum (High Order)                   │
              ├───────────────────────────────────────────────┤
        7   7 │       Checksum (Low Order)                    │
              ├───────────────────────────────────────────────┤
        8   8 │       First byte of data field (may be absent)│
              ├───────────────────────────────────────────────┤
              │                . . .                          │
              ├───────────────────────────────────────────────┤
        n   n │       Last byte of data field (512 bytes max) │
              └───────────────────────────────────────────────┘

The checksum is calculated on all bytes in the data packet and IPX
header excepting the checksum bytes themselves.  It is a 16 bit number
formed by adding the bytes in the packet and ignoring carry out of
the 16 bits.  Note:  Data packets run a separate sequence number series
from all other packets to allow certainty as to how many data packets
have been received.
                  TBBS/IPAD Protocol Data Packet Types

Packet Type 0 - Request Connection

    Bytes 8-n: Text of Server Name a connection is requested with.

  This packet is always sent to the server's circuit 0.  The server will
  respond with a TYPE=1 packet to either grant or refuse the connection.


Packet Type 1 - Connection Request Response

       Byte 8: Circuit Number Opened (1-254).  If this circuit number is
               zero, then your request for a connection was refused.

    Byte 9-10: Sequence number of the Request Connection packet this
               is a response to (hi-lo order).

  Note:  This response is always sent to the client's circuit 0.

Packet Type 2 - ACK Packet(s)

     Byte 8-9: Sequence number of packet being acknowledged.
   Byte 10-11: Control Info per type 4 packet.  Bit 0 of byte 11
               has no meaning here.

  This packet indicates that the packet with the indicated sequence number
  has been received from the other end and has been processed.

  Note:  Receipt of an Ack for a sequence number, also acks all packets
         with a lower sequence number that are outstanding.

Packet Type 3 - NAK Packet

     Byte 8-9: Sequence number of packet being negatively acknowledged.

   Byte 10-11: Reason for rejection.

               0=data error.  Packet was malformed or failed checksum.

           8000h=data error.  Packet reassembly timed out.

               1=closed circuit.  Data, Control, or ACK/NAK packet was
                 sent to a circuit > 0, and that circuit was not open
                 to the sender's IPX address.

               2=Protocol Error.  The packet was valid, but was not
                 valid here based on the protocol.

               3=Data Packet outside of window.  The "naking" program
                 is holding unacknowledged data which makes its window
                 too small to accept this packet.

  This packet indicates that the packet with the indicated sequence number
  has been received from the other end, but had an error and should be resent.

  Note:  Receipt of an NAK for a sequence number, implies Acks for all packets
         with a lower sequence number that are outstanding.
Packet Type 4 - Circuit Control

      Byte 8: Control Flags as follows:

              Bit 7: 1 = may send more data, 0 = flow control halt data (RTS)
              Bit 6: 1 = Circuit active, 0 = Circuit inactive (CD)
              Bit 5: 1 = Circuit connected.
              Bits 4-0: reserved, always 0.

      Byte 9: Bits 7-1: Reserved, Always 0.
                 Bit 0: 0=original, 1=ACK of rcvd control packet.

   Note:  Receipt of a flow control packet is always given an ACK packet.
          Receipt of a circuit inactive packet when the circuit is active
          is always "acknowledged" with a return circuit inactive packet,
          indicating your end is changing state to disconnected.  If you
          already see the circuit as disconnected, respond with an ACK.


Packet Type 5 - Data Packet

    Up to 512 bytes of data to be transferred on the indicated circuit.

    Note:  Data packets should be responded to with an ACK packet.
                    Protocol State Tables

The TBBS/IPAD protocol state tables presume the following:

   1.  That general IPX initialization has been done.

   2.  That received packets are processed via an ESR at interrupt
       level, while outgoing packets are sent from a pool of ECBs
       which are not released until the ACK or Time Out tasks
       do so.  That is, the packets are sent, and the sending task
       is finished with all IPX duties.

   3.  The overall protocol transaction follows this sequence.

       a.  A client will locate a server it wishes to connect to, using
           the Service Advertising Protocol (SAP) "Find Sever" process.

       b.  The client will then request of that server to open a
           data circuit using the "Open Circuit" process.

       c.  The client and server will then use the data circuit
           until one of them closes it, at which time the total
           client/server transaction has ended.  A new transaction
           between this client and server may begin at either
           (1) or (2) above as required.

   4.  Any packets received by either a client or server from an IPX
       address not currently assigned to this circuit will be NAK'd
       with "circuit not open" responses if they are valid TBBS/IPAD
       protocol format packets, or silently discarded if they are not
       TBBS/IPAD protocol format packets.

   5.  Although the protocol is designed with an eye towards allowing
       sliding windows, at this time all implementations have a
       window size of 1.

   6.  Security items such as verifying that the incoming source address
       matches the address assigned to an open circuit before processing
       a packet are assumed to occur in ESR entry, and are not reflected
       in these state tables.

   "Find Server" Client SAP query transaction

   ┌─────┬──────────┬─────────────────────────┬─────────────────────────┬─────┐
   │State│ State    │ Predicate(s)            │ Action(s)               │ Next│
   │  #  │ Name     │                         │                         │ St  │
   ├─────┼──────────┼─────────────────────────┼─────────────────────────┼─────┤
   │ FS0 │ SQInit   │                         │ Open any IPX socket,    │ FS1 │
   │     │          │                         │ Set retry count.        │     │
   ├─────┼──────────┼─────────────────────────┼─────────────────────────┼─────┤
   │ FS1 │ SndQuery │                         │ Set T/O timer, Send     │ FS2 │
   │     │          │                         │ SAP query packet to     │     │
   │     │          │                         │ FFFF:FFFFFF:0452 (from  │     │
   │     │          │                         │ socket opened in FS0).  │     │
   ├─────┼──────────┼─┬───────────────────────┼─────────────────────────┼─────┤
   │ FS2 │ WtServer │1│ Rcv SAP response Pkt  │ store name/address,     │ exit│
   │     │          │ │ with desired server's │ set "server found"      │     │
   │     │          │ │ name and address      │                         │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Rcv SAP response Pkt  │ discard packet          │ FS2 │
   │     │          │ │ with another server's │                         │     │
   │     │          │ │ name and address      │                         │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │3│ Rcv packet that is    │ discard packet          │ FS2 │
   │     │          │ │ not SAP response pkt  │                         │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │4│ T/O Timer expires     │ Decrement Retry Counter │ FS3 │
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ FS3 │ QryAgain │1│ Retry counter > 0     │                         │ FS1 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Retry counter = 0     │ Set "server not found"  │ exit│
   └─────┴──────────┴─┴───────────────────────┴─────────────────────────┴─────┘
   "SAP server" - Server SAP response transaction

   ┌─────┬──────────┬─────────────────────────┬─────────────────────────┬─────┐
   │State│ State    │ Predicate(s)            │ Action(s)               │ Next│
   │  #  │ Name     │                         │                         │ St  │
   ├─────┼──────────┼─────────────────────────┼─────────────────────────┼─────┤
   │ SS0 │ SSInit   │                         │ Open Socket 0452h       │ SS1 │
   ├─────┼──────────┼─┬───────────────────────┼─────────────────────────┼─────┤
   │ SS1 │ SSInit2  │1│ Socket "in use" open  │ Bridge/Router doing     │ exit│
   │     │          │ │ failure               │ this function for us    │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Socket Opened         │ Post SAP receive ECBs   │ SS2 │
   │     │          │ │                       │ and buffers to listen   │     │
   │     │          │ │                       │ on socket 0452h         │     │
   ├─────┼──────────┼─┴───────────────────────┼─────────────────────────┼─────┤
   │ SS2 │ SSResp   │ Rcv SAP query on socket │ Send our SAP Advert pkt │ SS2 │
   │     │          │ 0452h                   │ to the IPX address in   │     │
   │     │          │                         │ the query's IPX header  │     │
   │     │          │                         │ "source" field.         │     │
   └─────┴──────────┴─────────────────────────┴─────────────────────────┴─────┘

Note:  Every 60 seconds a server should broadcast its SAP Advertising
       Packet to FFFF:FFFFFF:0452h from its own socket (obtained in FS0).
       This will tell any bridges or routers about the server's presence.
       This should be done unconditionally, whether socket 0452h can be
       opened or not.
             Opening a Data Circuit (Client makes request)


Client:  Sends Request for Connection (Type 0) packet to server on
         Circuit 0.

Server:  Sends Connection Request Response (Type 1) to client on
         Circuit 0.

Client:  Sends an ACK to the server on Circuit 0.

         1. If Circuit Number given in response is 0, client's request
            has been refused.  The client cannot have a connection
            with the server at this time.

         2. If the Circuit Number is > 0, then the server is inviting
            the client to open the indicated circuit.  In this case
            the client has 5 seconds to complete the following transaction:

Client:  Sends a Circuit Control (Type 4) packet with "Circuit connected".
         "May send data" and "Circuit Active" Bits indicate initial state
         of the circuit, and may be set to any initial conditions the
         client program desires. This packet is sent to the circuit number
         just granted.

         Note:  All packets on this circuit now must have the circuit
                number in the packet header.

Server:  Sends a Circuit Control (Type 4) packet with "Circuit connected".
         "May send data" and "Circuit Active" Bits indicate initial state
         of the circuit from the server's perspective.

Client:  Sends ACK for the Server's Circuit Control packet.

         The circuit is now open.  Normal traffic on an open circuit is
         data packets, control packets and acks or naks.
                Closing a Data Circuit Disconnection

If the Client initiates the circuit close:


Client:  Sends Circuit Control packet (type 4) with "Circuit Connected" Bit
         set to zero (circuit # in header = this circuit).

         Note:  Until the circuit is shut down, the client should continue
                to ACK data packets normally.

Server:  Responds with Circuit Control packet (type 4) with "Circuit
         Connected" bit set to zero (circuit # in header = this circuit).

Client:  Responds with ACK for server's Circuit Control packet and the
         circuit is disconnected (circuit # in header = this circuit).


If Server initiates the circuit close:

Server:  Sends Circuit Control packet (type 4) with "Circuit Connected" Bit
         set to zero (circuit # in header = this circuit).

         Note:  Until the circuit is shut down, the server should continue
                to ACK data packets normally.

Client:  Responds with Circuit Control packet (type 4) with "Circuit
         Connected" bit set to zero (circuit # in header = this circuit).

Server:  Responds with ACK for Client's Circuit Control packet and the
         circuit is disconnected (circuit # in header = this circuit).
   Receive a packet on Circuit 0 - client

   ┌─────┬──────────┬─────────────────────────┬─────────────────────────┬─────┐
   │State│ State    │ Predicate(s)            │ Action(s)               │ Next│
   │  #  │ Name     │                         │                         │ St  │
   ├─────┼──────────┼─┬───────────────────────┼─────────────────────────┼─────┤
   │ CR0 │ WtC0Rcv  │1│ Rcv Type 0 pkt        │ Send NAK, protocol err  │ CR0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Rcv Type 1 pkt        │ Post for CO2            │ CR0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │3│ Rcv Type 2 (ACK) pkt  │ Discard Pkt             │ CR0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │4│ Rcv Type 3 (NAK) pkt  │ Discard Pkt, post reason│ CR0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │5│ Rcv Type 4 (CTL) pkt  │ Send NAK, protocol err  │ CR0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │6│ Rcv Type 5 (DATA) pkt │ Send NAK, protocol err  │ CR0 │
   └─────┴──────────┴─┴───────────────────────┴─────────────────────────┴─────┘

   Receive a packet on Circuit 0 - server

   ┌─────┬──────────┬─────────────────────────┬─────────────────────────┬─────┐
   │State│ State    │ Predicate(s)            │ Action(s)               │ Next│
   │  #  │ Name     │                         │                         │ St  │
   ├─────┼──────────┼─┬───────────────────────┼─────────────────────────┼─────┤
   │ SR0 │ WtS0Rcv  │1│ Rcv Type 0 pkt        │                         │ SO0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Rcv Type 1 pkt        │ Send NAK, protocol err  │ SR0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │3│ Rcv Type 2 (ACK) pkt  │ Post for SO4            │ SR0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │4│ Rcv Type 3 (NAK) pkt  │ Discard Pkt, post reason│ SR0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │5│ Rcv Type 4 (CTL) pkt  │ Send NAK, protocol err  │ SR0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │6│ Rcv Type 5 (DATA) pkt │ Send NAK, protocol err  │ SR0 │
   └─────┴──────────┴─┴───────────────────────┴─────────────────────────┴─────┘

Note:  In a combination client/server, these two tables are combined
       into a single Circuit 0 receive packet handler.
   "Open Circuit" - Client transaction

   ┌─────┬──────────┬─────────────────────────┬─────────────────────────┬─────┐
   │State│ State    │ Predicate(s)            │ Action(s)               │ Next│
   │  #  │ Name     │                         │                         │ St  │
   ├─────┼──────────┼─────────────────────────┼─────────────────────────┼─────┤
   │ CO0 │ COInit   │                         │ Set retry counter       │ CO1 │
   ├─────┼──────────┼─────────────────────────┼─────────────────────────┼─────┤
   │ CO1 │ COQuery  │                         │ Set T/O timer, Send     │ CO2 │
   │     │          │                         │ Circuit Request Pkt     │     │
   │     │          │                         │ to server (from socket  │     │
   │     │          │                         │ opened in FS0).         │     │
   ├─────┼──────────┼─┬───────────────────────┼─────────────────────────┼─────┤
   │ CO2 │ WtCirc   │1│ T/O timer expires     │ Decrement Retry counter │ CO3 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Rcv circuit response  │ Send ACK packet (on     │ CO4 │
   │     │          │ │ packet                │ circuit 0)              │     │
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ CO3 │ COQrtry  │1│ Retry counter > 0     │                         │ CO1 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Retry counter = 0     │ Set "server timed out"  │ exit│
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ CO4 │ CORcvd   │1│ Rcv circuit 0 in the  │ Set "server busy"       │ exit│
   │     │          │ │ response pkt          │                         │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Rcv circuit "n" in    │ Set Retry counter       │ CO5 │
   │     │          │ │ the response pkt      │                         │     │
   ├─────┼──────────┼─┴───────────────────────┼─────────────────────────┼─────┤
   │ CO5 │ COAsgn   │                         │ Set Circuit "n" seq #   │ CO6 │
   │     │          │                         │ to 0001, Set T/O timer, │     │
   │     │          │                         │ Send circuit control    │     │
   │     │          │                         │ pkt with "circuit       │     │
   │     │          │                         │ connected" set          │     │
   ├─────┼──────────┼─┬───────────────────────┼─────────────────────────┼─────┤
   │ CO6 │ COWtOpn  │1│ T/O timer expires     │ Decrement Retry counter │ CO7 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Rcv circuit control   │ Mark Circuit Open       │ exit│
   │     │          │ │ pkt w/"circuit        │                         │     │
   │     │          │ │ connected" set        │                         │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │3│ Rcv circuit control   │ Mark Circuit Closed,    │ exit│
   │     │          │ │ pkt w/"circuit        │ set "circuit closed by  │     │
   │     │          │ │ connected" reset      │ server"                 │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │4│ Rcv NAK, circuit not  │ Mark Circuit Closed,    │ exit│
   │     │          │ │ open                  │ set "circuit closed by  │     │
   │     │          │ │                       │ server"                 │     │
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ CO7 │ COWtRty  │1│ Retry counter > 0     │                         │ CO5 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Retry counter = 0     │ Set "server timed out"  │ exit│
   └─────┴──────────┴─┴───────────────────────┴─────────────────────────┴─────┘
   "Open Circuit" - Server transaction

   ┌─────┬──────────┬─────────────────────────┬─────────────────────────┬─────┐
   │State│ State    │ Predicate(s)            │ Action(s)               │ Next│
   │  #  │ Name     │                         │                         │ St  │
   ├─────┼──────────┼─────────────────────────┼─────────────────────────┼─────┤
   │ SO0 │ SOInit   │ Rcv Circuit Request pkt │ Set retry counter       │ SO1 │
   ├─────┼──────────┼─┬───────────────────────┼─────────────────────────┼─────┤
   │ SO1 │ SOAssign │1│ Circuit not avail     │ Send Response Pkt with  │ SO2 │
   │     │          │ │                       │ Circuit=0,              │     │
   │     │          │ │                       │ Set T/O timer           │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Circuit is avail      │ Send Response Pkt with  │ SO4 │
   │     │          │ │                       │ Circuit="n",            │     │
   │     │          │ │                       │ Mark circuit "opening", │     │
   │     │          │ │                       │ Set T/O timer           │     │
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ SO2 │ SOWtRej  │1│ Rcv ACK pkt           │                         │ exit│
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ T/O timer expires     │ Decrement retry counter │ SO3 │
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ SO3 │ SORetry1 │1│ Retry counter > 0     │ Re-send Response pkt,   │ SO2 │
   │     │          │ │                       │ Set T/O Timer           │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Retry counter = 0     │ Mark circuit avail      │ exit│
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ SO4 │ SOWtACK  │1│ Rcv ACK and circuit   │ Mark circuit "assigned",│ SO6 │
   │     │          │ │ marked "opening"      │ Set T/O timer           │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Rcv ACK and circuit   │ Circuit now active      │ exit│
   │     │          │ │ marked "open"         │                         │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │3│ T/O timer expires     │ Decrement retry counter │ SO5 │
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ SO5 │ SOWAT0   │1│ Circuit marked "open" │ Lost ACK, but all is OK │ exit│
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Retry counter > 0     │ Resend response pkt,    │ SO4 │
   │     │          │ │                       │ Set T/O timer           │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │3│ Retry counter = 0     │ Mark Circuit "avail"    │ exit│
   ├─────┼──────────┼─┴───────────────────────┼─────────────────────────┼─────┤
   │ SO6 │ SOWAT1   │ T/O timer expires       │                         │ SO7 │
   ├─────┼──────────┼─┬───────────────────────┼─────────────────────────┼─────┤
   │ SO7 │ SOMBO    │1│ Circuit marked "open" │                         │ exit│
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Circuit not marked    │ Mark circuit "avail"    │ exit│
   │     │          │ │ "open"                │                         │     │
   └─────┴──────────┴─┴───────────────────────┴─────────────────────────┴─────┘

Note:  A circuit marked "avail" on a server, is also assumed to be marked
       "closed" for any test of condition.
   Receive a packet on Circuit "n" - client or server (n > 0)

   ┌─────┬──────────┬─────────────────────────┬─────────────────────────┬─────┐
   │State│ State    │ Predicate(s)            │ Action(s)               │ Next│
   │  #  │ Name     │                         │                         │ St  │
   ├─────┼──────────┼─┬───────────────────────┼─────────────────────────┼─────┤
   │ NR0 │ WtCnRcv  │1│ Rcv Type 0 or 1 pkt   │ Send NAK, protocol err  │ NR0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Rcv Type 2 (ACK) pkt  │                         │ RA0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │3│ Rcv Type 3 (NAK) pkt  │                         │ RN0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │4│ Rcv Type 4 (CTL) pkt  │                         │ RC0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │5│ Rcv Type 5 (DATA) pkt │                         │ RD0 │
   └─────┴──────────┴─┴───────────────────────┴─────────────────────────┴─────┘


   Rcvd Control Packet on circuit "n" (client or server)

   ┌─────┬──────────┬─────────────────────────┬─────────────────────────┬─────┐
   │State│ State    │ Predicate(s)            │ Action(s)               │ Next│
   │  #  │ Name     │                         │                         │ St  │
   ├─────┼──────────┼─┬───────────────────────┼─────────────────────────┼─────┤
   │ RC0 │ RcvCtl0  │1│ Circuit "n" not closed│                         │ RC1 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Circuit "n" closed,   │ Send NAK, circuit not   │ NR0 │
   │     │          │ │ & "Circuit Connected" │ open                    │     │
   │     │          │ │ in rcvd pkt = set     │                         │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │3│ Circuit "n" closed,   │ Send Circuit Control    │ NR0 │
   │     │          │ │ & "Circuit Connected" │ pkt w/circuit connected │     │
   │     │          │ │ in rcvd pkt = reset   │ reset, ACK=1            │     │
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ RC1 │ RcvCtl1  │1│ "Circuit Connected"   │ Mark circuit "open" and │ RC2 │
   │     │          │ │ in rcvd packet = set  │ post other packet       │     │
   │     │          │ │                       │ control bits.           │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Circuit Connected in  │ Mark circuit "closed"   │ RC2 │
   │     │          │ │ rcvd packet = reset   │                         │     │
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ RC2 │ RcvCtl2  │1│ "ACK" bit = 1 in      │                         │ NR0 │
   │     │          │ │ rcvd packet           │                         │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ "ACK" bit = 0 in      │ Send Circuit Control    │ NR0 │
   │     │          │ │ rcvd packet           │ pkt w/circuit connected │     │
   │     │          │ │                       │ same as rcvd packet,    │     │
   │     │          │ │                       │ other bits per current  │     │
   │     │          │ │                       │ states, ACK=1           │     │
   └─────┴──────────┴─┴───────────────────────┴─────────────────────────┴─────┘
   Rcvd ACK Packet on circuit "n" (client or server)

   ┌─────┬──────────┬─────────────────────────┬─────────────────────────┬─────┐
   │State│ State    │ Predicate(s)            │ Action(s)               │ Next│
   │  #  │ Name     │                         │                         │ St  │
   ├─────┼──────────┼─┬───────────────────────┼─────────────────────────┼─────┤
   │ RA0 │ RcvACK0  │1│ Circuit "n" not closed│                         │ RA1 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Circuit "n" closed    │ discard ACK pkt         │ NR0 │
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ RA1 │ RcvACK1  │1│ ACK seq # is within   │ Mark all pkts sent with │ NR0 │
   │     │          │ │ the "window" of sent  │ this sequence number or │     │
   │     │          │ │ packets               │ older seq number as     │     │
   │     │          │ │                       │ sent, release their     │     │
   │     │          │ │                       │ ECBs and buffers        │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ ACK seq # is outside  │ discard ACK packet      │ NR0 │
   │     │          │ │ the "window" of sent  │                         │     │
   │     │          │ │ packets               │                         │     │
   └─────┴──────────┴─┴───────────────────────┴─────────────────────────┴─────┘


   Rcvd NAK Packet on circuit "n" (client or server)

   ┌─────┬──────────┬─────────────────────────┬─────────────────────────┬─────┐
   │State│ State    │ Predicate(s)            │ Action(s)               │ Next│
   │  #  │ Name     │                         │                         │ St  │
   ├─────┼──────────┼─┬───────────────────────┼─────────────────────────┼─────┤
   │ RN0 │ RcvNAK0  │1│ Circuit "n" not closed│                         │ RN1 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Circuit "n" closed    │ Discard NAK pkt  (?)    │ NR0 │
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ RN1 │ RcvNAK1  │1│ Reason = Data out of  │ Reset seq# to NAK RSN,  │ RN2 │
   │     │          │ │ window                │ Re-send all un-ack'd    │     │
   │     │          │ │                       │ data pkts w/new seq #s  │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Reason = Pkt data err │                         │ RN4 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │3│ Reason = Other        │ Report Reason           │ RN3 │
   ├─────┼──────────┼─┴───────────────────────┼─────────────────────────┼─────┤
   │ RN2 │ RcvNAK2  │                         │ Mark Any pkts in range  │ NR0 │
   │     │          │                         │ RSN-WIN < # < RSN-1     │     │
   │     │          │                         │ as sent, release their  │     │
   │     │          │                         │ ECBs and buffers        │     │
   ├─────┼──────────┼─────────────────────────┼─────────────────────────┼─────┤
   │ RN3 │ RcvNAK3  │                         │ Mark Any pkts in range  │ NR0 │
   │     │          │                         │ RSN-WIN < # < RSN       │     │
   │     │          │                         │ as sent, release their  │     │
   │     │          │                         │ ECBs and buffers        │     │
   ├─────┼──────────┼─┬───────────────────────┼─────────────────────────┼─────┤
   │ RN4 │ RcvNDErr │1│ RSN outside send      │ Discard NAK pkt         │ NR0 │
   │     │          │ │ window                │                         │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ RSN inside send window│ Resend RSN packet       │ RN2 │
   └─────┴──────────┴─┴───────────────────────┴─────────────────────────┴─────┘
   Rcvd DATA Packet on circuit "n" (client or server)

   ┌─────┬──────────┬─────────────────────────┬─────────────────────────┬─────┐
   │State│ State    │ Predicate(s)            │ Action(s)               │ Next│
   │  #  │ Name     │                         │                         │ St  │
   ├─────┼──────────┼─┬───────────────────────┼─────────────────────────┼─────┤
   │ RD0 │ RcvDATA0 │1│ Circuit "n" not closed│                         │ RD1 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Circuit "n" closed    │ Send NAK, circuit not   │ NR0 │
   │     │          │ │                       │ active                  │     │
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ RD1 │ RcvDATA1 │1│ Seq # = next in order │ Send ACK, process data  │ NR0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Seq # > next, but is  │ Hold Packet, set T/O    │ RD2 │
   │     │          │ │ within window range   │ timer                   │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │3│ Seq # > next and NOT  │ Send NAK on "next" seq  │ NR0 │
   │     │          │ │ within window range,  │ number, discard pkt     │     │
   │     │          │ │ or Seq# < next-win-1  │                         │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │4│ Seq # < next          │ Send ACK, discard pkt   │ NR0 │
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ RD2 │ RcvDATA2 │1│ T/O timer expires     │ discard all held, out   │ NR0 │
   │     │          │ │                       │ of order pkts, release  │     │
   │     │          │ │                       │ their ECBs and buffers, │     │
   │     │          │ │                       │ Send NAK on "next" seq  │     │
   │     │          │ │                       │ #, "reassembly timeout" │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Rcv Seq # > next, but │ Hold Packet             │ RD2 │
   │     │          │ │ within window range   │                         │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │3│ Seq # > next and NOT  │ Send NAK on "next" seq  │ RD2 │
   │     │          │ │ within window range,  │ number, discard pkt     │     │
   │     │          │ │ or Seq# < next-win-1  │                         │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │4│ Seq # < next          │ Send ACK, discard pkt   │ RD2 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │5│ Seq # = next in order │ Process all pkts which  │ RD3 │
   │     │          │ │                       │ have been received in   │     │
   │     │          │ │                       │ order, send ACK on the  │     │
   │     │          │ │                       │ highest pkt # processed │     │
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ RD3 │ RcvDATA3 │1│ Still have held pkts  │ Set T/O timer           │ RD2 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ No held pkts remain   │ Turn off T/O timer      │ NR0 │
   └─────┴──────────┴─┴───────────────────────┴─────────────────────────┴─────┘
   Send DATA packet on circuit "n" (client or server, n > 0)

   ┌─────┬──────────┬─────────────────────────┬─────────────────────────┬─────┐
   │State│ State    │ Predicate(s)            │ Action(s)               │ Next│
   │  #  │ Name     │                         │                         │ St  │
   ├─────┼──────────┼─────────────────────────┼─────────────────────────┼─────┤
   │ SD0 │ SndDATA0 │                         │ Set retry counter       │ SD1 │
   ├─────┼──────────┼─────────────────────────┼─────────────────────────┼─────┤
   │ SD1 │ SndDATA1 │                         │ Send Packet,            │ SD2 │
   │     │          │                         │ Set T/O Timer           │     │
   ├─────┼──────────┼─┬───────────────────────┼─────────────────────────┼─────┤
   │ SD2 │ SndDATA2 │1│ Rcv ACK on packet     │ (handled by RAn table)  │ NR0 │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ T/O timer expires     │ Decrement Retry Counter │ SD3 │
   ├─────┼──────────┼─┼───────────────────────┼─────────────────────────┼─────┤
   │ SD3 │ SndDATA3 │1│ Retry Counter > 0     │ Resend Oldest Packet,   │ SD2 │
   │     │          │ │                       │ Set T/O Timer           │     │
   │     │          ├─┼───────────────────────┼─────────────────────────┼─────┤
   │     │          │2│ Retry Counter = 0     │ Close circuit internally│ NR0 │
   │     │          │ │                       │ and report "other guy   │     │
   │     │          │ │                       │ timed out"              │     │
   └─────┴──────────┴─┴───────────────────────┴─────────────────────────┴─────┘