#include "ufk.h"

/*
 *  s p a r
 *
 *  Fill the data array with my send-init parameters
 *
 */

spar(data,len)
char data[];
int  *len;
{
   data[0] = tochar(maxpacksiz);          /* Biggest packet I can receive */
   data[1] = tochar(mytime);              /* When I want to be timed out */
   data[2] = tochar(mypad);               /* How much padding I need */
   data[3] = ctl(mypchar);                /* Padding character I want */
   data[4] = tochar(myeol);               /* End-Of-Line character I want */
   data[5] = myquote;                     /* Control-Quote character I send */
   if ((data[6] = myeightquote) == 0)
      data[6] = 'N';                      /* No eight bit quoting */
   else if (config > 3)                   /* 8 bits link */
      data[6] = 'Y';                      /* 8th bit quoting on request */
   data[7] = myblock_check_type + '0';    /* Type of block check */
   if ((data[8] = myrptquote) == 0)       /* Repeat count quote character */
      data[8] = ' ';                      /* No repeat quoting done */
   *len = 10;
   if (allowattr)
      data[9] = tochar(0x08);             /* Set capability bit for attr */
   else
      data[9] = tochar(0);                /* Not used */
   if (maxpacksiz > 94)                   /* Use extended packet length ? */
   {
      data[0] = tochar(I_MYPACKSIZE);     /* Use default if long packets */
      data[9] = tochar(0x0a);             /* Set capability bit for this */
      data[10] = tochar(0);               /* No sliding windows */
      data[11] = tochar(maxpacksiz / 95); /* Send packet length */
      data[12] = tochar(maxpacksiz % 95);
      *len = 13;                          /* Count all this */
   }
   data[*len] = '\0';                     /* For debug printout */
}


/*  r p a r
 *
 *  Get the other host's send-init parameters
 *
 */

rpar(data,len)
char data[];
int  len;
{
   char c;

   if (len > 0)
      spsiz = unchar(data[0]);            /* Maximum send packet size */
   else
      spsiz = I_MYPACKSIZE;               /* Use default */
   if (len > 1)
      timint = unchar(data[1]);           /* When I should time out */
   else
      timint = I_MYTIME;
   if (len > 2)
      pad = unchar(data[2]);              /* Number of pads to send */
   else
      pad = I_MYPAD;
   if (len > 3)
      padchar = ctl(data[3]);             /* Padding character to send */
   else
      padchar = I_MYPCHAR;
   if (len > 4)
      eol = unchar(data[4]);              /* EOL character I must send */
   else
      eol = I_MYEOL;
   if (len > 5)
      quote = data[5];                    /* Incoming data quote character */
   else
      quote = I_MYQUOTE;
   if (len > 6)
   {
      if ((c = data[6]) == 'N')
         eight_quote = 0;                 /* Don't use eight_bit quoting */
      else if (c == 'Y')
      {
         if (config <= 3)                 /* 7 bits link */
            eight_quote = myeightquote;   /* Use default */
         else
            eight_quote = 0;              /* Don't use it */
      }
      else
         eight_quote = c;          /* Use this char for eight bit quoting */
   }
   else
      eight_quote = 0;                    /* Don't use it */
   if ((len > 7) && ((c = data[7] - '0') == myblock_check_type))
      block_check_type = c;               /* Setup block check type */
   else
      block_check_type = I_BLOCKCHECKTYPE;/* Set initial value */
   if ((len > 8) && ((c = data[8]) == myrptquote) && (c != ' '))
      repeat_quote = c;                   /* Setup repeat quote character */
   else
      repeat_quote = 0;                   /* Don't use repeat quoting */
   if (len > 9)
   {
      if ((unchar(data[9]) & 0x08) &&   /* Check for attribute packets */
          allowattr)
         attribute = TRUE;              /* We can handle it */
      if (unchar(data[9]) & 0x02)
      {            /* The remote kermit can handle extended length packets */
         c = 9;                         /* Check for more capability bytes */
         while (c < len)
            if (!(unchar(data[c++]) & 0x01))
               break;                     /* End of capability bytes */
         spsiz = maxpacksiz;              /* Use default */
         if (maxpacksiz > 94)             /* Do I want extended length ? */
         {                                /* Yes */
            if ((c == len) || (c == (len - 1))) /* No length specified */
               spsiz = I_DEFLONGSIZE;     /* Use default long size */
            else
            {
               c++;                   /* Skip window size (not implemented) */
               spsiz = 95 * unchar(data[c]) + /* Re-construct packet length */
                            unchar(data[c+1]);
            }
         }
      }
   }
   disp_params();                         /* Show all selected parameters */
}

alloc_pkt(type)
char type;
{
   char *p, *q, *malloc();

   dealloc_pkt();                             /* Get rid of old memory */
   if (((p = malloc(BIG_SIZE)) == NULL) ||    /* Allocate packet buffers */
       ((q = malloc(SMALL_SIZE)) == NULL))    /* for send and receive */
   {
      prterr(ER_NOMEM);                       /* No memory */
      return(FALSE);
   }
   if (type == RECEIVE)
   {
      recpkt = p;                               /* Receive buffer is large */
      sndpkt = q;                               /* Send buffer is small */
   }
   else if (type == SEND)
   {
      recpkt = q;                               /* Receive buffer is small */
      sndpkt = p;                               /* Send buffer is large */
   }
   return (TRUE);
}

dealloc_pkt()
{
   if (recpkt)                          /* De-allocate use receive packet */
   {
      free(recpkt);
      recpkt = 0;
   }
   if (sndpkt)                          /* De-allocate used send packet */
   {
      free(sndpkt);
      sndpkt = 0;
   }
}

set_default_comm()
{
   eol = myeol;                           /* EOL for outgoing packets */
   quote = myquote;                       /* Standard control-quote char "#" */
   pad = mypad;                           /* No padding */
   padchar = mypchar;                     /* Use null if any padding wanted */
   timint = mytime;                       /* Timeout value */
   eight_quote = myeightquote;            /* Set eight_bit quote character */
   repeat_quote = myrptquote;             /* Set repeat quote character */
   block_check_type = I_BLOCKCHECKTYPE;   /* Set initial value */
   attribute = FALSE;                     /* No attribute packets yet */
   binfil = image;                        /* Reset file type */
}

disp_params()                             /* Show parameter settings */
{                                         /* After negotiation */
   char tmp1, tmp2;

   if (debug && screen && (sflg || rflg)) /* Only if sending or receiving */
   {
      posit(0,15);
      printf("Packet length: %4d   Timeout:       %2d   Block check type:  %d",
             spsiz, timint, block_check_type);
      posit(0,16);
  printf("End of line:     %02x   Padding char:  %02x   Pad count:        %2d",
             eol, padchar, pad);
      if ((tmp1 = repeat_quote) == 0)
         tmp1 = 'N';
      if ((tmp2 = eight_quote) == 0)
         tmp2 = 'N';
      posit(0,17);
    printf("Control quote:    %c   Repeat quote:   %c   Eight bit quote:   %c",
             quote, tmp1, tmp2);
   }
}

disp_size_transferred()
{
   float xmitted,
         percentage;

   if (!remote && (transmit_chr_count != 0) && screen && !nooutput)
   {
      xmitted = transmit_chr_count / 1024.; /* Size transferred so far in K */
      posit(18,4);
      printf("%6.2f K", xmitted);
      if (sflg || (rflg && attribute && (file_size != 0)))
      {
         percentage = 100. * ((float)transmit_chr_count / (float)file_size);
         posit(39,4);
         printf("%3.0f %%", percentage);
      }
   }
}

init_xfer()
{
   chr_sent = dchr_sent = chr_rec = dchr_rec = 0; /* zero counters */
   nak_sent = nak_rec = pack_sent = pack_rec = 0;
   data_rate = 0;
   start_time = time(0);
}

fin_xfer()
{
   int numbits;

   t_chr_sent += chr_sent;                /* adjust performance counters */
   t_dchr_sent += dchr_sent;
   t_nak_sent += nak_sent;
   t_pack_sent += pack_sent;
   t_chr_rec += chr_rec;
   t_dchr_rec += dchr_rec;
   t_nak_rec += nak_rec;
   t_pack_rec += pack_rec;

   end_time = time(0);              /* Get current time */

   /* calculate number of bits in transmission */

   numbits = (config == 2 || config == 3 || config == 5) ? 10 : 11;
   if (rflg)                        /* received data */
      data_rate = (chr_rec / (end_time - start_time)) * (100 / numbits);
   else if (sflg)                   /* transmitted data */
      data_rate = (chr_sent / (end_time - start_time)) * (100 / numbits);
   t_data_rate = (((t_data_rate == 0) ? data_rate : t_data_rate)
                 + data_rate) / 2;
}
