/* The boolean type.  */
typedef int boolean;
#define TRUE (1)
#define FALSE (0)

/* Names for the bytes in the frame header.  */
#define IFRAME_DLE (0)
#define IFRAME_K (1)
#define IFRAME_CHECKLOW (2)
#define IFRAME_CHECKHIGH (3)
#define IFRAME_CONTROL (4)
#define IFRAME_XOR (5)

/* Length of the frame header.  */
#define CFRAMELEN (6)

/* Macros to break apart the control bytes.  */
#define CONTROL_TT(b) ((int)(((b) >> 6) & 03))
#define CONTROL_XXX(b) ((int)(((b) >> 3) & 07))
#define CONTROL_YYY(b) ((int)((b) & 07))

/* DLE value.  */
#define DLE ('\020')

/* Get the length of a packet given a pointer to the header.  */
#define CPACKLEN(z) (1 << ((z)[IFRAME_K] + 4))

/* <k> field value for a control message.  */
#define KCONTROL (9)

/* Get the next sequence number given a sequence number.  */
#define INEXTSEQ(i) ((i + 1) & 07)

/* Compute i1 - i2 modulo 8.  */
#define CSEQDIFF(i1, i2) (((i1) + 8 - (i2)) & 07)

/* Packet types.  These are from the TT field.  */
#define CONTROL (0)
#define ALTCHAN (1)
#define DATA (2)
#define SHORTDATA (3)

/* Control types.  These are from the XXX field if the type (tt field)
   is CONTROL.  */
#define CLOSE (1)
#define RJ (2)
#define SRJ (3)
#define RR (4)
#define INITC (5)
#define INITB (6)
#define INITA (7)

/* Maximum amount of data in a single packet.  */
#define CMAXDATAINDEX (8)
#define CMAXDATA (1 << (CMAXDATAINDEX + 4))

/* Maximum window size.  */
#define CMAXWINDOW (7)

/* The timeout to use when waiting for a packet.  Protocol parameter
   ``timeout''.  */
#define CTIMEOUT (10)

/* The number of times to retry waiting for a packet.  Each time the
   timeout fails we send a copy of our last data packet or a reject
   message for the packet we expect from the other side, depending on
   whether we have any unacknowledged data.  This is the number of
   times we try doing that and then waiting again.  Protocol parameter
   ``retries''.  */
#define CRETRIES (6)

/* Next sequence number to send.  */
int iGsendseq = 1;

/* Last sequence number that has been acked.  */
int iGremote_ack = 0;

/* Last sequence number to be retransmitted.  */
int iGretransmit_seq = -1;

/* Last sequence number we have received.  */
static int iGrecseq;

/* Remote segment size (set during protocol initialization).  This is
   one less than the value in a packet header.  */
int iGremote_segsize;

/* Remote packet size (set based on iGremote_segsize).  */
int iGremote_packsize;

/* Remote window size (set during handshake).  */
static int iGremote_winsize;

/* Timeout (seconds) for receiving a data packet.  Protocol parameter
   ``timeout''.  */
static int cGtimeout = CTIMEOUT;

/* Maximum number of timeouts when receiving a data packet or
   acknowledgement.  Protocol parameter ``retries''.  */
static int cGretries = CRETRIES;

/* Get a packet.  This is called to wait for a packet to come in when
   there is nothing to send.  If freturncontrol is TRUE, this will
   return after getting any control packet.  Otherwise, it will
   continue to receive packets until a complete file or a complete
   command has been received.  The timeout and the number of retries
   are arguments.  The function returns FALSE if an error occurs or if
   cretries timeouts of ctimeout seconds were exceeded.  */
boolean fgwait_for_packet (boolean freturncontrol, int ctimeout,
			   int cretries);

/* Send data to the other system.  If the fdoread argument is TRUE,
   this will also read data into abPrecbuf; fdoread is passed as TRUE
   if the protocol expects data to be coming back, to make sure the
   input buffer does not fill up.  Returns FALSE on error.  */
boolean fsend_data (const char *zsend, int csend, boolean fdoread);

