home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff294.lzh / DNet / unix / dnet / packet.c < prev    next >
C/C++ Source or Header  |  1989-12-11  |  6KB  |  359 lines

  1.  
  2. /*
  3.  *  PACKET.C
  4.  */
  5.  
  6. #include "dnet.h"
  7.  
  8. void BuildPacket();
  9.  
  10. #define Ascize(foo) (((foo) & 0x3F) | 0x40)
  11.  
  12. ubyte    RxTmp[MAXPACKET];
  13.  
  14. void
  15. BuildDataPacket(pkt, win, dbuf, actlen)
  16. PKT    *pkt;
  17. ubyte    win;
  18. ubyte    *dbuf;
  19. uword    actlen;
  20. {
  21.     ubyte *ptr;
  22.     ubyte *pend;
  23.     ubyte range = 0;
  24.     static ubyte BadCtl[32] = {
  25.     1, 1, 1, 1, 1, 1, 1, 1,
  26.     1, 1, 1, 1, 1, 1, 1, 1,
  27.     1, 1, 1, 1, 1, 1, 1, 1,
  28.     1, 1, 1, 1, 1, 1, 1, 1
  29.     };
  30.  
  31.     ptr = dbuf;
  32.     pend= dbuf + actlen;
  33.  
  34.     while (ptr < pend) {
  35.     if (*ptr < 0x20 && BadCtl[*ptr])
  36.         range |= 1;
  37.     if (*ptr >= 0x80)
  38.         range |= 2;
  39.     ++ptr;
  40.     }
  41.     if (Mode7 && range) {
  42.     uword buflen = Expand6(dbuf, pkt->data, actlen);
  43.     BuildPacket(pkt, PKCMD_WRITE6, win, pkt->data, actlen, buflen);
  44.     } else {
  45.     if (Mode7 || (range & 2)) {
  46.         BuildPacket(pkt, PKCMD_WRITE, win, dbuf, actlen, actlen);
  47.     } else {
  48.         uword buflen = Compress7(dbuf, pkt->data, actlen);
  49.         BuildPacket(pkt, PKCMD_WRITE7, win, pkt->data, actlen, buflen);
  50.     }
  51.     }
  52. }
  53.  
  54. PKT *
  55. BuildRestartAckPacket(dbuf, bytes)
  56. ubyte *dbuf;
  57. ubyte bytes;
  58. {
  59.     static PKT pkt;
  60.     BuildPacket(&pkt, PKCMD_ACKRSTART, 0, dbuf, bytes, bytes);
  61.     return(&pkt);
  62. }
  63.  
  64. void
  65. BuildPacket(pkt, ctl, win, dbuf, actlen, buflen)
  66. PKT    *pkt;
  67. ubyte    ctl;
  68. ubyte    *dbuf;
  69. uword    actlen;
  70. uword    buflen;
  71. {
  72.     pkt->buflen = buflen;
  73.     pkt->sync = SYNC;
  74.     pkt->ctl = ctl | win;
  75.     pkt->cchk = Ascize((pkt->sync << 1) ^ pkt->ctl);
  76.     if (actlen) {
  77.     uword chk = chkbuf(dbuf, buflen);
  78.     ubyte dchkh = chk >> 8;
  79.     ubyte dchkl = chk;
  80.  
  81.     pkt->lenh = Ascize(actlen >> 6);
  82.     pkt->lenl = Ascize(actlen);
  83.     pkt->dchkh= Ascize(dchkh);
  84.     pkt->dchkl= Ascize(dchkl);
  85.     if (dbuf != pkt->data)
  86.         bcopy(dbuf, pkt->data, buflen);
  87.     }
  88. }
  89.  
  90. void
  91. WritePacket(pkt)
  92. PKT *pkt;
  93. {
  94.     if (DDebug)
  95.     printf("SEND-PACKET %02x %d\n", pkt->ctl, pkt->buflen);
  96.  
  97.     if (pkt->buflen)
  98.     NetWrite(&pkt->sync, 7 + pkt->buflen);
  99.     else
  100.     NetWrite(&pkt->sync, 3);
  101.     switch(pkt->ctl) {
  102.     case PKCMD_WRITE:
  103.     case PKCMD_WRITE6:
  104.     case PKCMD_WRITE7:
  105.     case PKCMD_RESTART:
  106.     WTimeout(WTIME);
  107.     }
  108. }
  109.  
  110. void
  111. WriteCtlPacket(ctl, win)
  112. {
  113.     static CTLPKT pkt;
  114.  
  115.     NetWrite(NULL, 0);
  116.     BuildPacket(&pkt, ctl, win, NULL, 0, 0);
  117.     WritePacket(&pkt);
  118. }
  119.  
  120. void
  121. WriteNak(win)
  122. {
  123.     WriteCtlPacket(PKCMD_NAK, win);
  124. }
  125.  
  126. void
  127. WriteAck(win)
  128. {
  129.     WriteCtlPacket(PKCMD_ACK, win);
  130. }
  131.  
  132. void
  133. WriteChk(win)
  134. {
  135.     WriteCtlPacket(PKCMD_CHECK, win);
  136. }
  137.  
  138. void
  139. WriteRestart()
  140. {
  141.     WriteCtlPacket(PKCMD_RESTART, 0);
  142. }
  143.  
  144. /*
  145.  *    RECEIVE A PACKET
  146.  */
  147.  
  148. int
  149. RecvPacket(ptr, len)
  150. ubyte *ptr;
  151. long len;
  152. {
  153.     static uword ActLen;    /*    actual # bytes after decoding */
  154.     static uword BufLen;    /*    length of input data buffer   */
  155.     static uword DBLen;     /*    # bytes already in i.d.buf    */
  156.     static ubyte RState;
  157.     static PKT     Pkt;
  158.     ubyte  *dptr;
  159.     short expect;
  160.  
  161.     if (ptr == NULL) {
  162.     RState = 0;
  163.     return(3);
  164.     }
  165.  
  166.     while (len) {
  167.     switch(RState) {
  168.     case 0:
  169.         --len;
  170.         Pkt.sync = *ptr++;
  171.  
  172.         if (Pkt.sync == SYNC)
  173.         ++RState;
  174.         break;
  175.     case 1:     /*  CTL */
  176.         --len;
  177.         Pkt.ctl = *ptr++;
  178.  
  179.         if (Pkt.ctl < 0x20 || Pkt.ctl > 0x7F) {
  180.         RState = 0;
  181.         break;
  182.         }
  183.         ++RState;
  184.         break;
  185.     case 2:     /*  CCHK    */
  186.         --len;
  187.         Pkt.cchk = *ptr++;
  188.  
  189.         if (Ascize((SYNC<<1) ^ Pkt.ctl) != Pkt.cchk) {
  190.         RState = 0;
  191.         break;
  192.         }
  193.         switch(Pkt.ctl & PKF_MASK) {
  194.         case PKCMD_ACKRSTART:
  195.         case PKCMD_WRITE:
  196.         case PKCMD_WRITE6:
  197.         case PKCMD_WRITE7:
  198.         if (DDebug)
  199.             printf("Recv Header %02x\n", Pkt.ctl & PKF_MASK);
  200.         ++RState;
  201.         break;
  202.         default:
  203.         if (DDebug)
  204.             printf("Recv Control %02x\n", Pkt.ctl & PKF_MASK);
  205.         do_cmd(Pkt.ctl, NULL, 0);
  206.         RState = 0;
  207.         break;
  208.         }
  209.         break;
  210.     case 3:     /*  LENH    */
  211.         --len;
  212.         Pkt.lenh = *ptr++;
  213.  
  214.         ++RState;
  215.         if (Pkt.lenh < 0x20 || Pkt.lenh > 0x7F)
  216.         RState = 0;
  217.         break;
  218.     case 4:     /*  LENL    */
  219.         --len;
  220.         Pkt.lenl = *ptr++;
  221.  
  222.         if (Pkt.lenl < 0x20 || Pkt.lenl > 0x7F) {
  223.         RState = 0;
  224.         break;
  225.         }
  226.  
  227.         ++RState;
  228.  
  229.         ActLen = ((Pkt.lenh & 0x3F) << 6) | (Pkt.lenl & 0x3F);
  230.         DBLen = 0;
  231.  
  232.         switch(Pkt.ctl & PKF_MASK) {
  233.         case PKCMD_ACKRSTART:
  234.         case PKCMD_WRITE:
  235.         BufLen = ActLen;
  236.         break;
  237.         case PKCMD_WRITE6:
  238.         BufLen = (ActLen * 8 + 5) / 6;
  239.         break;
  240.         case PKCMD_WRITE7:
  241.         BufLen = (ActLen * 7 + 7) / 8;
  242.         break;
  243.         default:
  244.         puts("BaD");
  245.         break;
  246.         }
  247.  
  248.         if (ActLen > MAXPKT || BufLen > MAXPACKET) {
  249.         if (DDebug || DDebug)
  250.             printf("Packet Length Error %d %d\n", ActLen, BufLen);
  251.         RState = 0;
  252.         }
  253.         break;
  254.     case 5:     /*  DChkH   */
  255.         --len;
  256.         Pkt.dchkh = *ptr++;
  257.  
  258.         ++RState;
  259.         if (Pkt.dchkh < 0x20 || Pkt.dchkh > 0x7F)
  260.         RState = 0;
  261.         break;
  262.     case 6:     /*  DCHKL   */
  263.         --len;
  264.         Pkt.dchkl = *ptr++;
  265.  
  266.         ++RState;
  267.         if (Pkt.dchkl < 0x20 || Pkt.dchkl > 0x7F)
  268.         RState = 0;
  269.         break;
  270.     case 7:     /*  -DATA-  */
  271.         if (DBLen + len < BufLen) {     /*  not enough  */
  272.         bcopy(ptr, Pkt.data + DBLen, len);
  273.         DBLen += len;
  274.         len = 0;
  275.         break;
  276.         }
  277.  
  278.         /*
  279.          *    Enough data, check chk
  280.          */
  281.  
  282.         bcopy(ptr, Pkt.data + DBLen, BufLen - DBLen);
  283.         len -= BufLen - DBLen;
  284.         ptr += BufLen - DBLen;
  285.  
  286.         {
  287.         uword chk;
  288.         ubyte chkh;
  289.         ubyte chkl;
  290.  
  291.         chk = chkbuf(Pkt.data, BufLen);
  292.         chkh = Ascize(chk >> 8);
  293.         chkl = Ascize(chk);
  294.  
  295.         if (Pkt.dchkh != chkh || Pkt.dchkl != chkl) {
  296.             printf("Chksum failure %02x %02x %02x %02x\n",
  297.             Pkt.dchkh, chkh, Pkt.dchkl, chkl
  298.             );
  299.             RState = 0;
  300.             break;
  301.         }
  302.         }
  303.  
  304.         switch(Pkt.ctl & PKF_MASK) {
  305.         case PKCMD_ACKRSTART:
  306.         dptr = Pkt.data;
  307.         break;
  308.         case PKCMD_WRITE:
  309.         dptr = Pkt.data;
  310.         break;
  311.         case PKCMD_WRITE6:
  312.         UnExpand6(Pkt.data, RxTmp, ActLen);
  313.         dptr = RxTmp;
  314.         break;
  315.         case PKCMD_WRITE7:
  316.         UnCompress7(Pkt.data, RxTmp, ActLen);
  317.         dptr = RxTmp;
  318.         break;
  319.         default:
  320.         puts("BaD2");
  321.         dptr = Pkt.data;
  322.         break;
  323.         }
  324.         if (DDebug)
  325.         printf("Recv Body   %02x %ld bytes\n", Pkt.ctl, ActLen);
  326.  
  327.         do_cmd(Pkt.ctl, dptr, ActLen);
  328.  
  329.         RState = 0;
  330.         break;
  331.     }
  332.     }
  333.  
  334.     {
  335.     static short ExpAry[] = { 3, 2, 1, 4, 3, 2, 1, 0 };
  336.  
  337.     expect = ExpAry[RState];
  338.  
  339.     if (RState == 7)
  340.         expect = BufLen - DBLen;
  341.     }
  342. #ifdef NOTDEF
  343.     if (Rto_act) {
  344.     AbortIO((IOR *)&Rto);
  345.     WaitIO((IOR *)&Rto);
  346.     Rto_act = 0;
  347.     }
  348.     if (RState == 7) {
  349.     Rto.tr_time.tv_secs = 8;
  350.     Rto.tr_time.tv_micro= 0;
  351.     SendIO((IOR *)&Rto);
  352.     Rto_act = 1;
  353.     }
  354. #endif
  355.     do_cmd((uword)-1, NULL, 0);
  356.     return((int)expect);
  357. }
  358.  
  359.