home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / pub / uniflex / ufpack.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  13KB  |  395 lines

  1. #include "ufk.h"
  2. #include <setjmp.h>
  3.  
  4. jmp_buf rp_env;
  5.  
  6. /*
  7.  *  s p a c k
  8.  *
  9.  *  Send a Packet
  10.  */
  11.  
  12. spack(type,num,len,data,offset,check)
  13. char  type, *data,
  14.       num, check;
  15. int   len,
  16.       offset;
  17. {
  18.    int   i;                               /* Temporary variable */
  19.    char  buffer[7];                       /* Packet help buffer */
  20.    unsigned int crc, chksum, ck1, ck2, ck3,/* CRC value and checksum */
  21.                 calc_crc();
  22.    register char *p, *bufp;               /* Buffer pointer */
  23.    char *q;                               /* Temp pointer */
  24.  
  25.    prtdbgf("Packet transmitted: %d, Type: %c, Length: %d\n",num,type,len);
  26.    if (!remote && !nooutput)
  27.    {
  28.       if (screen)
  29.       {
  30.          posit(20,7);
  31.          printf("%2d",num);
  32.       }
  33.       else
  34.          printf("Xmit: %d\r",num);
  35.    }
  36.    if (debug)                       /* Display outgoing packet */
  37.    {
  38.       if (screen)
  39.       {
  40.          clreol(0,12);              /* Clear out data area */
  41.          clreol(20,11);
  42.       }
  43.       if ((debug >= 1) && !remote)
  44.       {
  45.          if (screen)
  46.          {
  47.             posit(33,7);
  48.             printf("%c",type);
  49.             posit(45,7);
  50.             printf("%4d",len);
  51.          }
  52.          else
  53.             printf("Type: %c Length: %d\n\l",type,len);
  54.       }
  55.       if (len != 0)
  56.       {
  57.          if ((debug >= 1) && !remote)
  58.          {
  59.             if (screen)
  60.             {
  61.                posit(20,11);
  62.                printf("\"%.58s\"",&data[offset]);
  63.                if (len > 58)
  64.                {
  65.                   posit(20,12);
  66.                   printf("\"%.58s\"",&data[58+offset]);
  67.                }
  68.             }
  69.             else
  70.                printf("Data transmitted: \"%.94s\"\n\l",&data[offset]);
  71.          }
  72.          prtdbgf("Data transmitted: \"%.94s\"\n",data);
  73.       }
  74.    }
  75.  
  76.    purgeline(ttyfd);                      /* Eat old input */
  77.    if (sflg || rflg)
  78.       pack_sent++;                        /* Count packet */
  79.    bufp = buffer;                         /* Set up buffer pointer */
  80.  
  81.    zero_crc();                            /* Initialize CRC calculation */
  82.    *bufp++ = mypackstart;                 /* Packet marker */
  83.    if (len > 91)
  84.       i = 0;                              /* Use long packet format */
  85.    else
  86.       i = len + check + 2;                /* Use normal length */
  87.    *bufp++ = tochar(i);                   /* Send the character count */
  88.    chksum  = tochar(i);                   /* Initialize the checksum */
  89.    calc_crc(tochar(i));                   /* Calculate CRC */
  90.    *bufp++ = tochar(num);                 /* Packet number */
  91.    chksum += tochar(num);                 /* Update checksum */
  92.    calc_crc(tochar(num));                 /* Calculate CRC */
  93.    *bufp++ = type;                        /* Packet type */
  94.    chksum += type;                        /* Update checksum */
  95.    crc = calc_crc(type);                  /* Calculate CRC */
  96.    if (i == 0)
  97.    {
  98.       i = len + check;            /* account for header and normal checksum */
  99.       *bufp = tochar(i / 95);
  100.       chksum += *bufp;                    /* Update checksum */
  101.       calc_crc(*bufp++);                  /* Calculate CRC */
  102.       *bufp = tochar(i % 95);
  103.       chksum += *bufp;                    /* Update checksum */
  104.       calc_crc(*bufp++);                  /* Calculate CRC */
  105.       *bufp = tochar((chksum+((chksum & 0300) >> 6)) & 077);/* Hdr checksum */
  106.       chksum += *bufp;                    /* Update checksum */
  107.       crc = calc_crc(*bufp++);            /* Calculate CRC */
  108.    }
  109.    if ((type == 'N') && (sflg || rflg))
  110.       nak_sent++;                         /* Count nak */
  111.  
  112.    p = data + offset;
  113.    q = p + len;
  114.    while (p < q)                          /* Loop for all data characters */
  115.    {
  116.       chksum += (unsigned char) *p;       /* Update checksum */
  117.       crc = calc_crc(*p++);               /* Calculate CRC */
  118.    }
  119.    chksum &= 0x0fff;                      /* Prevent overflow */
  120.    for (i = 0;i < pad; i++)
  121.       kwrite(ttyfd,&padchar,1);           /* Issue any padding */
  122.    kwrite(ttyfd,buffer,bufp-buffer);      /* Send start of packet */
  123.    if (len != 0)
  124.       kwrite(ttyfd, &data[offset], len);  /* Send the data if any */
  125.    bufp = buffer;                         /* Reset pointer */
  126.    switch (check)
  127.    {
  128.       case 1:                             /* One character checksum */
  129.               chksum = (((chksum & 0300) >> 6) + chksum) & 077;
  130.               *bufp++ = (ck1 = tochar(chksum)); /* Put it in the packet */
  131.               break;
  132.       case 2:                             /* Two character checksum */
  133.               *bufp++ = (ck1 = tochar((chksum >> 6) & 077));
  134.               *bufp++ = (ck2 = tochar(chksum & 077));
  135.               break;
  136.       case 3:                             /* Three character CRC */
  137.               *bufp++ = (ck1 = tochar((crc >> 12) & 017));
  138.               *bufp++ = (ck2 = tochar((crc >> 6) & 077));
  139.               *bufp++ = (ck3 = tochar(crc & 077));
  140.    }
  141.    *bufp++ = eol;                         /* Extra-packet line terminator */
  142.    kwrite(ttyfd, buffer,bufp-buffer);     /* Send the rest of the packet */
  143.    if (sflg || rflg)
  144.       dchr_sent += len;                   /* Adjust character counters */
  145.  
  146.    if (debug)
  147.    {
  148.       if (debug >= 1)
  149.          if (screen)
  150.             posit(60,7);
  151.          else
  152.             fputs("Checksum: ",stdout);
  153.       prtdbgf("Checksum: ");
  154.       switch(check)
  155.       {
  156.          case 1:
  157.                prtdbg("%02x\n",unchar(ck1));
  158.                break;
  159.          case 2:
  160.                prtdbg("%02x%02x\n",unchar(ck1),unchar(ck2));
  161.                break;
  162.          case 3:
  163.                prtdbg("%02x%02x%02x\n",unchar(ck1),unchar(ck2),unchar(ck3));
  164.       }
  165.       if (!screen)
  166.          fputs("\l",stdout);
  167.    }
  168.    if (sflg)
  169.       disp_size_transferred();            /* Show how far we've got */
  170. }
  171.  
  172. /*
  173.  *  r p a c k
  174.  *
  175.  *  Read a Packet
  176.  */
  177.  
  178. rpack(len,num,data,check)
  179. char  *num, check,                        /* number, checksum type */
  180.       *data;                              /* Packet data */
  181. int   *len;                               /* Length */
  182. {
  183.    int   done,
  184.          s;
  185.    unsigned int cchksum,                  /* Checksums */
  186.          rchksum,
  187.          ck1, ck2, ck3,
  188.          crc;                             /* and CRC */
  189.    char  t,                               /* Current input character */
  190.          type,                            /* Packet type */
  191.          type0,                           /* Type 0 packet type */
  192.          *p;
  193.  
  194.    do                                     /* Wait for packet header */
  195.    {
  196.       if (kread(ttyfd,&t,1) == TIMEOUT)
  197.          return ('T');                    /* Return timeout */
  198.       t &= 0177;                          /* Handle parity */
  199.    }
  200.    while (t != mypackstart);
  201.  
  202.    done = FALSE;                          /* Got packet start, init loop */
  203.    while (!done)                          /* Loop to get a packet */
  204.    {
  205.       if (setjmp(rp_env))
  206.          return('T');                     /* Return if timeout */
  207.       zero_crc();                         /* Start new CRC calculation */
  208.       cchksum = 0;
  209.       if (getpck(&t,&cchksum,&crc))
  210.          continue;                        /* Resynch if start of packet */
  211.  
  212.       if (unchar(t) == 0)
  213.          type0 = TRUE;                    /* Type 0 extended header */
  214.       else if ((unchar(t) == 1) ||
  215.                (unchar(t) == 2))
  216.          return(FALSE);                   /* Invalid packet length */
  217.       else
  218.       {
  219.          type0 = FALSE;
  220.          *len = unchar(t)-check-2;        /* Character count */
  221.       }
  222.       if (getpck(&t,&cchksum,&crc))
  223.          continue;                        /* Resynch if start of packet */
  224.       *num = unchar(t);                   /* Packet number */
  225.  
  226.       if (getpck(&t,&cchksum,&crc))
  227.          continue;                        /* Resynch if start of packet */
  228.       type = t;                           /* Packet type */
  229.       if ((type == 'N') && (sflg || rflg))
  230.          nak_rec++;                       /* Count received nak */
  231.  
  232.       if (type0)
  233.       {
  234.          if (getpck(&t,&cchksum,&crc))
  235.             continue;                     /* Resynch if start of packet */
  236.          *len = 95 * unchar(t);           /* First part of length */
  237.          if (getpck(&t,&cchksum,&crc))
  238.             continue;                     /* Resynch if start of packet */
  239.          *len += unchar(t);               /* Second part of length */
  240.          *len -= check;                   /* Correction */
  241.          s = cchksum;
  242.          if (getpck(&t,&cchksum,&crc))
  243.             continue;                     /* Resynch if start of packet */
  244.          if (t != tochar((s + ((s & 0300) >> 6)) & 077))
  245.             return(FALSE);                /* Header checksum error */
  246.       }
  247.       p = data;
  248.       while (p < data + *len)             /* The data itself, if any */
  249.       {                                   /* Loop for character count */
  250.          if (kread(ttyfd,&t,1) == TIMEOUT)/* Get character */
  251.             return ('T');
  252.          if (!binfil)                     /* Handle parity */
  253.             t &= 0177;
  254.          if (t == mypackstart)            /* Resynch if start of packet */
  255.             continue;
  256.          cchksum += (unsigned char) t;    /* Update checksum */
  257.          crc = calc_crc(t);               /* Calculate CRC */
  258.          *p++ = t;                        /* Put it in the data buffer */
  259.       }
  260.       cchksum &= 0x0fff;                  /* Prevent overflow */
  261.       *p = '\0';                          /* Mark the end of the data */
  262.  
  263.       if (kread(ttyfd,&t,1) == TIMEOUT)   /* Get character */
  264.          return ('T');
  265.       if (check == 1)
  266.          rchksum = (ck1 = unchar(t));     /* Convert to numeric */
  267.       else if (check == 2)
  268.       {
  269.          rchksum = (ck1 = unchar(t)) << 6;
  270.          if (kread(ttyfd,&t,1) == TIMEOUT)/* Get character */
  271.             return ('T');
  272.          rchksum += (ck2 = unchar(t));
  273.       }
  274.       else if (check == 3)
  275.       {
  276.          rchksum = (ck1 = unchar(t)) << 12;
  277.          if (kread(ttyfd,&t,1) == TIMEOUT)/* Get character */
  278.             return ('T');
  279.          rchksum += (ck2 = unchar(t)) << 6;
  280.          if (kread(ttyfd,&t,1) == TIMEOUT)/* Get character */
  281.             return ('T');
  282.          rchksum += (ck3 = unchar(t));
  283.       }
  284.       if (kread(ttyfd,&t,1) == TIMEOUT)   /* get EOL character and toss it */
  285.          return ('T');
  286.       t &= 0177;                          /* Handle parity */
  287.       if (t == mypackstart)               /* Resynch if start of packet */
  288.          continue;
  289.       done = TRUE;                        /* Got checksum, done */
  290.    }
  291.  
  292.    if (sflg || rflg)
  293.    {
  294.       dchr_rec += *len;                   /* Count received data characters */
  295.       pack_rec++;                         /* Count packet */
  296.    }
  297.    if (check == 3)
  298.       cchksum = crc;                      /* Set calculated value */
  299.    else if (check == 2)
  300.       cchksum &= 07777;                   /* Strip result to 12 bits */
  301.    if (check == 1)
  302.       cchksum = (((cchksum & 0300) >> 6) + cchksum) & 077; /* Final checksum */
  303.  
  304.    prtdbgf("Packet received: %d, Type: %c, Length: %d\n",*num,type,*len);
  305.    if (!remote && !nooutput)
  306.    {
  307.       if (screen)
  308.       {
  309.          posit(20,6);
  310.          printf("%2d",*num);
  311.       }
  312.       else
  313.          printf("Rcv:  %d\r",*num);
  314.    }
  315.    if (debug)                             /* Display incoming packet */
  316.    {
  317.       if ((debug >= 1) && !remote)
  318.       {
  319.          if (screen)
  320.          {
  321.             posit(33,6);
  322.             printf("%c",type);
  323.             posit(45,6);
  324.             printf("%4d",*len);
  325.             posit(60,6);
  326.          }
  327.          else
  328.             printf("Type: %c Length: %d\n\l",type,*len);
  329.       }
  330.       prtdbgf("Checksum: ");
  331.       if (!screen)
  332.          fputs("Checksum: ",stdout);
  333.       switch(check)
  334.       {
  335.          case 1:
  336.                prtdbg("%02x\n",ck1);
  337.                break;
  338.          case 2:
  339.                prtdbg("%02x%02x\n",ck1,ck2);
  340.                break;
  341.          case 3:
  342.                prtdbg("%02x%02x%02x\n",ck1,ck2,ck3);
  343.       }
  344.       if (!screen)
  345.          fputs("\l",stdout);
  346.       if (screen)
  347.       {
  348.          clreol(20,9);
  349.          clreol(0,10);
  350.       }
  351.       if (*len != 0)
  352.       {
  353.          if ((debug >= 1) && !remote)
  354.          {
  355.             if (screen)
  356.             {
  357.                posit(20,9);
  358.                printf("\"%.58s\"",data);
  359.                if (*len > 58)
  360.                {
  361.                   posit(20,10);
  362.                   printf("\"%.58s\"",&data[58]);
  363.                }
  364.             }
  365.             else
  366.                printf("Data received: \"%.94s\"\n\l",data);
  367.          }
  368.          prtdbgf("Data received: \"%.94s\"\n",data);
  369.       }
  370.    }
  371.  
  372.    if (rflg)
  373.       disp_size_transferred();            /* Show how far we've got */
  374.    if (cchksum != rchksum)
  375.       return(FALSE);                      /* Checksum error */
  376.    else
  377.       return(type);                       /* All OK, return packet type */
  378. }
  379.  
  380. getpck(t,cks,crc)
  381. char *t;
  382. unsigned int *cks,*crc;
  383. {
  384.    if (kread(ttyfd,t,1) == TIMEOUT)       /* Get character */
  385.       longjmp(rp_env,TRUE);
  386.    *t &= 0177;                            /* Handle parity */
  387.    *cks &= 0x0fff;                        /* Prevent overflow */
  388.    *cks += *t;                            /* Update checksum */
  389.    *crc = calc_crc(*t);                   /* Calculate CRC */
  390.    if (*t == mypackstart)
  391.       return(TRUE);                       /* New start of packet received */
  392.    else
  393.       return(FALSE);
  394. }
  395.