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 / amiga / dnet / packet.c < prev    next >
C/C++ Source or Header  |  1989-12-11  |  6KB  |  354 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, 0, 0, 1, 0, 0, 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.         BMov(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->ctl == PKCMD_WRITE)
  98.     ++Packets8Out;
  99.     if (pkt->ctl == PKCMD_WRITE6)
  100.     ++Packets6Out;
  101.     if (pkt->ctl == PKCMD_WRITE7)
  102.     ++Packets7Out;
  103.  
  104.     if (pkt->buflen)
  105.     NetWrite(&pkt->sync, 7 + pkt->buflen);
  106.     else
  107.     NetWrite(&pkt->sync, 3);
  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.         ++RState;
  199.         break;
  200.         default:
  201.         do_cmd(Pkt.ctl, NULL, 0);
  202.         RState = 0;
  203.         break;
  204.         }
  205.         break;
  206.     case 3:     /*  LENH    */
  207.         --len;
  208.         Pkt.lenh = *ptr++;
  209.  
  210.         ++RState;
  211.         if (Pkt.lenh < 0x20 || Pkt.lenh > 0x7F)
  212.         RState = 0;
  213.         break;
  214.     case 4:     /*  LENL    */
  215.         --len;
  216.         Pkt.lenl = *ptr++;
  217.  
  218.         if (Pkt.lenl < 0x20 || Pkt.lenl > 0x7F) {
  219.         RState = 0;
  220.         break;
  221.         }
  222.  
  223.         ++RState;
  224.  
  225.         ActLen = ((Pkt.lenh & 0x3F) << 6) | (Pkt.lenl & 0x3F);
  226.         DBLen = 0;
  227.  
  228.         switch(Pkt.ctl & PKF_MASK) {
  229.         case PKCMD_ACKRSTART:
  230.         case PKCMD_WRITE:
  231.         BufLen = ActLen;
  232.         break;
  233.         case PKCMD_WRITE6:
  234.         BufLen = (ActLen * 8 + 5) / 6;
  235.         break;
  236.         case PKCMD_WRITE7:
  237.         BufLen = (ActLen * 7 + 7) / 8;
  238.         break;
  239.         default:
  240.         puts("BaD");
  241.         break;
  242.         }
  243.  
  244.         if (ActLen > MAXPKT || BufLen > MAXPACKET) {
  245.         if (PDebug || DDebug)
  246.             printf("Packet Length Error %d %d\n", ActLen, BufLen);
  247.         RState = 0;
  248.         }
  249.         break;
  250.     case 5:     /*  DChkH   */
  251.         --len;
  252.         Pkt.dchkh = *ptr++;
  253.  
  254.         ++RState;
  255.         if (Pkt.dchkh < 0x20 || Pkt.dchkh > 0x7F)
  256.         RState = 0;
  257.         break;
  258.     case 6:     /*  DCHKL   */
  259.         --len;
  260.         Pkt.dchkl = *ptr++;
  261.  
  262.         ++RState;
  263.         if (Pkt.dchkl < 0x20 || Pkt.dchkl > 0x7F)
  264.         RState = 0;
  265.         break;
  266.     case 7:     /*  -DATA-  */
  267.         if (DBLen + len < BufLen) {     /*  not enough  */
  268.         BMov(ptr, Pkt.data + DBLen, len);
  269.         DBLen += len;
  270.         len = 0;
  271.         break;
  272.         }
  273.  
  274.         /*
  275.          *    Enough data, check chk
  276.          */
  277.  
  278.         BMov(ptr, Pkt.data + DBLen, BufLen - DBLen);
  279.         len -= BufLen - DBLen;
  280.         ptr += BufLen - DBLen;
  281.  
  282.         {
  283.         uword chk;
  284.         ubyte chkh;
  285.         ubyte chkl;
  286.  
  287.         chk = chkbuf(Pkt.data, BufLen);
  288.         chkh = Ascize(chk >> 8);
  289.         chkl = Ascize(chk);
  290.  
  291.         if (Pkt.dchkh != chkh || Pkt.dchkl != chkl) {
  292.             printf("Chksum failure %02x %02x %02x %02x\n",
  293.             Pkt.dchkh, chkh, Pkt.dchkl, chkl
  294.             );
  295.             RState = 0;
  296.             break;
  297.         }
  298.         }
  299.  
  300.         switch(Pkt.ctl & PKF_MASK) {
  301.         case PKCMD_ACKRSTART:
  302.         dptr = Pkt.data;
  303.         break;
  304.         case PKCMD_WRITE:
  305.         dptr = Pkt.data;
  306.         ++Packets8In;
  307.         break;
  308.         case PKCMD_WRITE6:
  309.         UnExpand6(Pkt.data, RxTmp, ActLen);
  310.         dptr = RxTmp;
  311.         ++Packets6In;
  312.         break;
  313.         case PKCMD_WRITE7:
  314.         UnCompress7(Pkt.data, RxTmp, ActLen);
  315.         dptr = RxTmp;
  316.         ++Packets7In;
  317.         break;
  318.         default:
  319.         puts("BaD2");
  320.         dptr = Pkt.data;
  321.         break;
  322.         }
  323.  
  324.         do_cmd(Pkt.ctl, dptr, ActLen);
  325.  
  326.         RState = 0;
  327.         break;
  328.     }
  329.     }
  330.  
  331.     {
  332.     static short ExpAry[] = { 3, 2, 1, 4, 3, 2, 1, 0 };
  333.  
  334.     expect = ExpAry[RState];
  335.  
  336.     if (RState == 7)
  337.         expect = BufLen - DBLen;
  338.     }
  339.     if (Rto_act) {
  340.     AbortIO((IOR *)&Rto);
  341.     WaitIO((IOR *)&Rto);
  342.     Rto_act = 0;
  343.     }
  344.     if (RState == 7) {
  345.     Rto.tr_time.tv_secs = 8;
  346.     Rto.tr_time.tv_micro= 0;
  347.     SendIO((IOR *)&Rto);
  348.     Rto_act = 1;
  349.     }
  350.     do_cmd((uword)-1, NULL, 0);
  351.     return((int)expect);
  352. }
  353.  
  354.