home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * GIO.C WINDOWED G PROTOCOL
- *
- * written from scratch, except the checksum routine which was
- * rewritten but based on the old one.
- *
- * WINDOW SIZE: When changing the window size be sure there
- * are enough buffers available for pending txs.
- *
- * GIO.C (c)Copyright 1989, Matthew Dillon, All Rights Reserved
- * extended to window size of 7 by Jack J. Rouse
- */
-
- #include "includes.h"
-
- typedef unsigned char ubyte;
- typedef unsigned short uword;
-
- typedef struct {
- ubyte Dle; /* Literal ASCII DLE */
- ubyte K; /* data size 2^(K+4) except K=0 means no data */
- ubyte CL,CH; /* MAGIC - chksum(data) ^ C */
- ubyte C;
- ubyte X; /* K ^ C0 ^ C1 ^ C */
- } Frame;
-
- typedef struct {
- ubyte CType; /* bits 7-6 of C */
- ubyte CCmd; /* bits 5-3 of C */
- ubyte CSeq; /* bits 2-0 of C */
- ubyte PLen; /* pre-data (2 bytes) for SHORTDATA type */
- ubyte *Data; /* implies CType=LONGDATA or SHORTDATA */
- uword DLen; /* length of data */
- } Packet;
-
- Prototype int gwrdata(FILE *);
- Prototype int gwrmsg(char *);
- Prototype int grddata(FILE *);
- Prototype int grdmsg(char *, int);
- Prototype int gturnon(int);
- Prototype int gturnoff(void);
- Prototype void ResetGIO(void);
-
- Local char *GetTxBuf(void);
- Local int SendDataPacket(unsigned char *, int);
- Local int RecvDataPacket(char **);
- Local int GetData(int, Packet *);
- Local int RecvdAck(char);
- Local int WriteCtlPacket(int);
- Local int WritePacket(Packet *, int);
- Local int ReadPacket(Packet *, int);
- Local int CheckSum(unsigned char *, int);
- Local void FrameToPacket(Frame *, Packet *, unsigned char *);
- Local int LenToK(unsigned short);
-
- extern int debug;
- extern int WindowOne;
-
- #define SUCCESS 0
- #define FAIL 1
-
- #define MAGIC 0125252
- #define DLE 0x10
- #define WINDOWSIZE 7
- #define SEGSIZEK 2 /* 64 bytes ?? */
-
- #define SUB1(var) (((var)-1)&7)
-
-
- #define CT_CONTROL (0 << 6)
- #define CT_ALTCHN (1 << 6)
- #define CT_LONGDATA (2 << 6)
- #define CT_SHORTDATA (3 << 6)
- #define CT_MASK (3 << 6)
-
- #define CC_CLOSE (1 << 3)
- #define CC_RJ (2 << 3)
- #define CC_SRJ (3 << 3)
- #define CC_RR (4 << 3)
- #define CC_INITC (5 << 3)
- #define CC_INITB (6 << 3)
- #define CC_INITA (7 << 3)
- #define CC_MASK (7 << 3)
-
- #define SEQ_MASK 7
-
- #define WAIT_ACK 1
- #define WAIT_DATA 2
- #define WAIT_CONTROL 3
-
- #define MaxPktSize 4096
-
- char RxBuf[MaxPktSize+4];
- char *TxBuf[8];
-
- /* TRANSMIT STAGE */
- char TxSeq = 0; /* Last send packet */
- char TxPend= 0; /* hasn't been acked yet */
- uword TxWinSize; /* 1 or 2 (max 7) */
- uword TxSegSize; /* maximum segment size */
- char TxSegK; /* K for TxSegSize */
- Packet TxPacket[8]; /* contents of last packet */
-
- /* RECEIVE STAGE */
- char RxSeq = 0; /* Last valid recv pkt */
- char RxRdy = 0; /* Has come in.. */
- char RxRetry = 8;
- char RxNotAcked = 0; /* We have yet to ack it */
- Packet RxPacket; /* The packet that has come in */
-
- void
- ResetGIO()
- {
- TxSeq = 0;
- TxPend= 0;
- TxWinSize = 0;
- TxSegSize = 0;
- TxSegK = 0;
- RxSeq = 0;
- RxRdy = 0;
- RxRetry = 8;
- RxNotAcked = 0;
- }
-
- /*
- * Get Transmit Buffer. Note that some space to the left is available
- */
-
- Local
- char *
- GetTxBuf()
- {
- static int index = 0;
-
- if (++index > TxWinSize)
- index = 0;
- if (TxBuf[index] == NULL
- && (TxBuf[index] = (char *)malloc(MaxPktSize+4)) == NULL)
- {
- printf("Out of memory in GetTxBuf.");
- /* could handle this case better, but it should be rare */
- xexit(1);
- }
- return(TxBuf[index] + 2);
- }
-
- int
- gwrdata(fi)
- FILE *fi;
- {
- int bytes;
-
- if (debug > 7)
- printf("GWRDATA: ");
-
- for (;;) {
- char *buf = GetTxBuf();
- if ((bytes = fread(buf, 1, TxSegSize, fi)) <= 0)
- break;
- if (SendDataPacket(buf, bytes) != SUCCESS) {
- if (debug > 7)
- printf("GWR Failed\n");
- return(FAIL);
- }
- if (debug > 7)
- printf("\nGWROK ");
- }
- {
- char *buf = GetTxBuf();
- if (SendDataPacket(buf, 0) != SUCCESS) {
- if (debug > 7)
- printf("GWR Failed (last)\n");
- return(FAIL);
- }
- }
- if (debug > 7)
- printf("\nGWFile Last Ack\n");
- while (TxPend) {
- if (GetData(WAIT_ACK, NULL) == FAIL)
- return(FAIL);
- }
- if (debug > 7)
- printf("success\n");
- return (SUCCESS);
- }
-
- /*
- * Write message to the other guy.
- *
- * NOTE: LONGDATA packets used exclusively and \0 fill to end.
- */
-
- int
- gwrmsg(str)
- char *str;
- {
- int len = strlen(str) + 1; /* type + str + \0 */
-
- if (debug > 7)
- printf("GWRMSG: %s\n", str);
-
- while (len > TxSegSize) {
- char *buf = GetTxBuf();
- movmem(str, buf, TxSegSize);
- if (debug > 7)
- printf("GWR-SEND %d\n", TxSegSize);
- if (SendDataPacket(buf, TxSegSize) != SUCCESS)
- return(FAIL);
- len -= TxSegSize;
- str += TxSegSize;
- }
-
- /*
- * Find optimal packet size (remember, we must force LONGDATA
- *
- * Apparently packet sizes less than the agreed upon size are
- * not allowed ???
- */
-
- {
- short siz = TxSegSize;
- char *buf = GetTxBuf();
- #ifdef NOTDEF
- short k = TxSegK;
-
- while (k > 1 && (siz >> 1) >= len) {
- --k;
- siz >>= 1;
- }
- #endif
- if (debug > 7)
- printf("GWR-FNL %d %d\n", len, siz);
-
- movmem(str, buf, len);
- setmem(buf + len, siz - len, 0);
- if (SendDataPacket(buf, siz) != SUCCESS) {
- if (debug > 7)
- printf("GWR-FAIL\n");
- return(FAIL);
- }
- }
- if (debug > 7)
- printf("GWR Last Ack\n");
- while (TxPend) {
- if (GetData(WAIT_ACK, NULL) == FAIL)
- return(FAIL);
- }
- if (debug > 7)
- printf("success\n");
- return (SUCCESS);
- }
-
- int
- grddata(fi)
- FILE *fi;
- {
- int bytes;
- char *buf;
-
- if (debug > 7)
- printf("GRDDATA\n");
- while ((bytes = RecvDataPacket(&buf)) > 0) {
- if (debug > 7)
- printf("GRDDATA blk %d\n", bytes);
- fwrite(buf, 1, bytes, fi);
- }
- if (debug > 7)
- printf("GRDDATA end %d\n", bytes);
- if (bytes < 0)
- return(FAIL);
- else
- return(SUCCESS);
- }
-
- int
- grdmsg(buf, maxlen)
- char *buf;
- {
- short i;
- short n;
- short slen;
- char *ptr;
-
- i = 0;
- if (debug > 7)
- printf("GRDMSG\n");
- while ((n = RecvDataPacket(&ptr)) > 0) {
- ptr[n] = 0;
- slen = strlen(ptr);
- if (slen > maxlen - 1) {
- printf("GRDMSG: Buffer overflow!\n");
- return (FAIL);
- }
- movmem(ptr, buf + i, slen);
- buf[i + slen] = 0;
- if (slen != n)
- break;
- i += slen;
- maxlen -= slen;
- }
- if (debug > 7)
- printf("GRDMSGEND %d (%d) %s\n", n, i, buf);
- if (n < 0) {
- buf[0] = 0;
- return(FAIL);
- }
- return(SUCCESS);
- }
-
- Local
- int
- SendDataPacket(buf, bytes)
- ubyte *buf;
- int bytes;
- {
- Packet P;
-
- /*
- * If window exhausted we must wait for at least one ack.
- */
-
- while (TxPend == TxWinSize) {
- if (GetData(WAIT_ACK, NULL) == FAIL)
- return(FAIL);
- }
-
- TxSeq = (TxSeq + 1) & 7; /* next Tx packet */
-
- /*
- * Figure out best fit packet size. Apparently packets smaller
- * then the agreed upon size are not allowed ???
- */
-
- #ifdef NOTDEF
- {
- short k = TxSegK;
- P.DLen = TxSegSize;
- while (k > 1 && P.DLen && (P.DLen >> 1) >= bytes) {
- --k;
- P.DLen >>= 1;
- }
- }
- #else
- P.DLen = TxSegSize;
- #endif
-
- if (bytes < P.DLen) {
- uword extra = P.DLen - bytes;
- setmem(buf + bytes, extra, 0);
- if (extra <= 127) {
- P.PLen = 1;
- buf[-1] = extra;
- } else {
- P.PLen = 2;
- buf[-2] = 0x80 | extra;
- buf[-1] = (extra >> 7);
- }
- P.CType = CT_SHORTDATA;
- } else {
- P.PLen = 0;
- P.CType = CT_LONGDATA;
- }
- P.CCmd = TxSeq << 3; /* transmit sequence number */
- P.CSeq = RxSeq; /* last valid received pkt */
- P.Data = buf;
-
- if (debug > 7)
- printf("WRITE DATA PACKET txseq=%d rxack=%d\n", TxSeq, P.CSeq);
-
- RxNotAcked = 0; /* We've acked the rx packet */
-
- TxPacket[TxSeq] = P;
- ++TxPend;
-
- WritePacket(&TxPacket[TxSeq], 1);
-
- return(SUCCESS);
- }
-
- Local
- int
- RecvDataPacket(pbuf)
- char **pbuf;
- {
- if (RxRdy == 0) {
- if (GetData(WAIT_DATA, NULL) != SUCCESS)
- return(-1);
- }
- *pbuf = RxPacket.Data;
- RxRdy = 0;
- return((int)RxPacket.DLen);
- }
-
- int
- gturnon(master)
- int master;
- {
- Packet P;
- short retry = 5;
- short windowsize = WINDOWSIZE; /* our prefered window size */
- short segsize = SEGSIZEK; /* our prefered segment size */
-
- if (WindowOne)
- windowsize = 1;
-
- if (master) {
- while (retry > 0) {
- WriteCtlPacket(CC_INITA | windowsize);
- if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITA) {
- if (P.CSeq && P.CSeq < windowsize)
- windowsize = P.CSeq;
- break;
- }
- --retry;
- }
- while (retry > 0) {
- WriteCtlPacket(CC_INITB | (segsize - 1));
- if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITB) {
- if (P.CSeq < segsize - 1)
- segsize = P.CSeq + 1;
- break;
- }
- --retry;
- }
- while (retry > 0) {
- WriteCtlPacket(CC_INITC | windowsize);
- if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITC) {
- if (P.CSeq && P.CSeq < windowsize)
- windowsize = P.CSeq;
- break;
- }
- --retry;
- }
- } else {
- while (retry > 0) {
- if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITA) {
- WriteCtlPacket(CC_INITA | windowsize);
- if (P.CSeq && windowsize > P.CSeq)
- windowsize = P.CSeq;
- break;
- }
- --retry;
- }
- while (retry > 0) {
- if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITB) {
- WriteCtlPacket(CC_INITB | (segsize - 1));
- if (P.CSeq < segsize - 1)
- segsize = P.CSeq + 1;
- break;
- }
- --retry;
- }
- while (retry > 0) {
- if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITC) {
- WriteCtlPacket(CC_INITC | windowsize);
- if (P.CSeq && windowsize > P.CSeq)
- windowsize = P.CSeq;
- break;
- }
- --retry;
- }
- }
- TxSegK = segsize;
- TxSegSize = 1 << (TxSegK + 4);
- TxWinSize = windowsize;
- if (debug > 0)
- printf("Window Size is %d\n", TxWinSize);
-
- if (retry == 0)
- return(FAIL);
- return(SUCCESS);
- }
-
- int
- gturnoff()
- {
- Packet P;
-
- WriteCtlPacket(CC_CLOSE);
- if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_CLOSE) {
- WriteCtlPacket(CC_RR | RxSeq);
- return (SUCCESS);
- }
- return (FAIL);
- }
-
- /*
- * GetData()
- *
- * This is the core of the packet protocol. As soon as we get a satisfactory
- * terminating condition we return. However, on unsatisfactory conditions
- * such as having to send a reject, we attempt to drain any pending data
- * (i.e. multiple returned rejects) so we do not do multiple resends.
- *
- * The resend flag only applies on a failure return.
- */
-
- Local
- int
- GetData(waitfor, p)
- int waitfor;
- Packet *p;
- {
- Packet P;
- short timeout;
- short drainmode = 0;
-
- /*
- * If we haven't acked the last packet we received we must do
- * so now before we can expect to receive another one!
- */
-
- if (debug > 7)
- printf("Get-Data waitfor %s\n", (waitfor == WAIT_ACK) ? "WAIT_ACK" : "WAIT_DATA");
- if (waitfor == WAIT_ACK)
- timeout = 5;
- else if (waitfor == WAIT_DATA)
- timeout = 20;
- else
- timeout = 20;
-
- for (;;) {
- if (RxNotAcked) { /* good, send ack for rx'd pkt */
- WriteCtlPacket(CC_RR | RxSeq);
- RxNotAcked = 0;
- } /* bad, timeout on read */
- if (ReadPacket(&P, (drainmode) ? 0 : timeout) == FAIL) {
- drainmode = 0;
-
- /*
- * If we have timed out waiting for data then send a reject
- */
-
- if (waitfor == WAIT_DATA) {
- if (RxRetry) {
- --RxRetry;
- if (debug > 7)
- printf("\nWAIT-DATA, TIMEOUT, SEND RJ\n");
- WriteCtlPacket(CC_RJ | RxSeq);
- continue;
- }
- }
-
- /*
- * If we have timed out waiting for an ack send the entire
- * window. We must send the window sometime and it might as
- * well be now.
- */
-
- if (waitfor == WAIT_ACK) {
- if (RxRetry) {
- int i;
-
- if (debug > 7)
- printf("RESEND %d packets\n", TxPend);
- for (i = 1; i <= TxPend; ++i) {
- Packet *p = &TxPacket[(TxSeq - TxPend + i) & 7];
- p->CSeq = RxSeq;
- WritePacket(p, 1);
- }
- --RxRetry;
- continue;
- }
- }
- if (debug > 7)
- printf("COMPLETE FAILURE RxRetry = %d\n", RxRetry);
- return(FAIL);
- }
-
- /*
- * valid packet, terminating condition?
- */
-
- RxRetry = 8;
- switch(P.CType) {
- case CT_CONTROL:
- switch(P.CCmd) {
- case CC_CLOSE: /* End of communication ... not an ACK! */
- if (waitfor == WAIT_CONTROL) {
- *p = P;
- return(SUCCESS);
- }
- return(FAIL);
- case CC_RJ: /* Reject packet (P.CSeq == last good packet) */
- (void)RecvdAck(P.CSeq);
- drainmode = 1;
- break;
- case CC_SRJ: /* Selective Reject (P.CSeq == bad packet # ) */
- return(FAIL);
- case CC_RR: /* Ack to packet (P.CSeq == packet # acked) */
- #ifdef NOTDEF
- if (P.CSeq == ((TxSeq - TxPend) & 7)) {
- /*
- * The CSeq packet was previously acknowledged
- * The receiver apparently has not seen anything since.
- * This is the same as a rejection.
- */
- goto resend;
- }
- #endif
- if (RecvdAck(P.CSeq) == SUCCESS && waitfor == WAIT_ACK)
- return(SUCCESS);
- break;
- case CC_INITC:
- case CC_INITB:
- case CC_INITA:
- if (waitfor == WAIT_CONTROL) {
- *p = P;
- return(SUCCESS);
- }
- return(FAIL);
- }
- break;
- case CT_ALTCHN:
- printf("ALTCHN packet ??\n");
- break;
- case CT_LONGDATA:
- case CT_SHORTDATA:
- {
- char rxseq = P.CCmd >> 3;
- char txack = P.CSeq;
-
- if (RxRdy == 1) {
- printf("Got two receive packets without me acking!\n");
- }
-
- if (rxseq == RxSeq) { /* already got this packet */
- RxNotAcked = 1;
- continue;
- /* expected packet? */
- } else if (rxseq != ((RxSeq + 1) & 7)) {
- drainmode = 1;
- printf("Received sequence %d, expected %d\n", rxseq, (RxSeq + 1) & 7);
- break;
- }
- if (debug > 6)
- printf("RECV SEQUENCE %d\n", rxseq);
-
- RecvdAck(txack); /* woa */
-
- /*
- * Delay sending the ACK back in case we can combine
- * it with the next transmitted packet.
- */
-
- RxNotAcked = 1; /* we haven't ack'd the rx packet */
-
- RxSeq = (RxSeq + 1) & 7;
- RxRdy = 1;
- RxPacket = P;
- if (waitfor == WAIT_DATA)
- return(SUCCESS);
- if (TxPend == 0 && waitfor == WAIT_ACK)
- return(SUCCESS);
- }
- break;
- }
- }
- }
-
- Local
- int
- RecvdAck(seq)
- char seq;
- {
- short i;
-
- /*
- * which packet was acked?
- */
-
- for (i = 0; i < TxPend; ++i) {
- if (seq == ((TxSeq - i) & 7))
- break;
- }
- if (i && i == TxPend) {
- if (seq != ((TxSeq - TxPend) & 7))
- printf("He acked the wrong packet! %d expected %d\n", seq, TxSeq);
- return(FAIL);
- }
- if (debug > 7)
- printf("TxPend %d -> %d\n", TxPend, i);
- TxPend = i;
- return(SUCCESS);
- }
-
- Local
- int
- WriteCtlPacket(cc)
- int cc;
- {
- Packet pk;
-
- pk.CType = CT_CONTROL;
- pk.CCmd = cc & CC_MASK;
- pk.CSeq = cc & SEQ_MASK;
- pk.PLen = 0;
- pk.DLen = 0;
- WritePacket(&pk, 0);
- return(SUCCESS);
- }
-
- Local
- int
- WritePacket(pk, async)
- Packet *pk;
- int async;
- {
- Frame F;
- uword sum;
-
- F.Dle = DLE;
- F.C = pk->CType | pk->CCmd | pk->CSeq;
- F.K = 9;
-
- if (pk->CType == CT_SHORTDATA || pk->CType == CT_LONGDATA)
- F.K = LenToK(pk->DLen);
- else
- pk->DLen = 0;
-
- sum = MAGIC - (CheckSum(pk->Data - pk->PLen, pk->DLen) ^ F.C);
-
- F.CH = sum >> 8;
- F.CL = sum;
- F.X = F.K ^ F.CH ^ F.CL ^ F.C;
-
- if (debug > 7)
- printf("WritePacket: F.K = %d F.C = %d.%d.%d\n", F.K, F.C >> 6, (F.C >> 3) & 7, F.C & 7);
-
- if (async)
- xwritea(&F, sizeof(F));
- else
- xwrite(&F, sizeof(F)); /* write header */
- if (pk->DLen) { /* write data */
- if (async)
- xwritea(pk->Data - pk->PLen, pk->DLen);
- else
- xwrite(pk->Data - pk->PLen, pk->DLen);
- }
- return(SUCCESS);
- }
-
- Local
- int
- ReadPacket(pk, timeout)
- Packet *pk;
- int timeout;
- {
- Frame F;
- short c;
- short i = 0;
-
- pk->Data = RxBuf;
- pk->CType = 0xFF;
- pk->CCmd = 0;
- pk->CSeq = 0;
-
- if (debug > 7)
- printf("ReadPacket\n");
- while ((c = xgetc(timeout)) != EOF) {
- if (debug > 8)
- printf("RP %d %02x\n", i, c);
-
- switch(i) {
- case 0:
- if (c == DLE) {
- F.Dle = c;
- ++i;
- if (timeout == 0)
- timeout = 1;
- }
- break;
- case 1:
- F.K = c;
- ++i;
- if (c == DLE) { /* K only valid 1-9 */
- F.Dle = c;
- i = 1;
- }
- else if (c == 0 || c > 9)
- i = 0;
- break;
- case 2:
- F.CL = c;
- ++i;
- break;
- case 3:
- F.CH = c;
- ++i;
- break;
- case 4:
- F.C = c;
- ++i;
- break;
- case 5:
- F.X = c;
- if (F.X != (F.K ^ F.CH ^ F.CL ^ F.C)) {
- printf("F.X failed: %02x %02x\n", F.X, (F.K ^ F.CH ^ F.CL ^ F.C));
- i = 0;
- } else { /* get data segment if any */
- ++i;
- }
- break;
- }
- if (i == 6)
- break;
- }
- if (debug > 7) {
- if (i)
- printf("RP Hdr i = %d, F.K = %d F.C = %d.%d.%d\n", i, F.K, F.C >> 6, (F.C >> 3) & 7, F.C & 7);
- else
- printf("RP Hdr <rx timeout>\n");
- }
-
- if (i == 6) { /* Receive Data Portion */
- uword pktsize = 1 << (F.K + 4);
- uword n;
-
- if (F.K == 9)
- pktsize = 0;
-
- if (pktsize > MaxPktSize) {
- printf("Protocol failure pktsize %d/%d/%d\n", pktsize, TxSegSize, MaxPktSize);
- return (FAIL);
- }
- for (n = 0; n < pktsize; ++n) {
- if ((c = xgetc(4)) == EOF)
- break;
- pk->Data[n] = c;
- }
- if (c != EOF) {
- uword hissum;
- uword oursum;
- hissum = (F.CH << 8) | F.CL;
- oursum = MAGIC - (CheckSum(pk->Data, pktsize) ^ F.C);
- if (debug > 7)
- printf("Got Data, checking: %04x %04x\n", hissum, oursum);
- if (hissum == oursum) {
- FrameToPacket(&F, pk, pk->Data);
- return (SUCCESS);
- }
- } else {
- FrameToPacket(&F, pk, pk->Data); /* mainly for pk->CType */
- return (FAIL);
- }
- }
- /*
- * Timeout, retry?
- */
- return (FAIL);
- }
-
- Local
- int
- CheckSum(s, n)
- ubyte *s;
- int n;
- {
- uword sum;
- uword x;
- uword t;
-
- if (n == 0)
- return(0);
- sum = -1;
- x = 0;
-
- while (n) {
- if (sum & 0x8000)
- sum = (sum << 1) | 1;
- else
- sum = (sum << 1);
-
- t = sum;
- sum += *s++;
- x += sum ^ n;
- if (sum <= t)
- sum ^= x;
- --n;
- }
- return((int)sum);
- }
-
- Local
- void
- FrameToPacket(fr, pk, data)
- Frame *fr;
- Packet *pk;
- ubyte *data;
- {
- pk->CType = fr->C & CT_MASK;
- pk->CCmd = fr->C & CC_MASK;
- pk->CSeq = fr->C & SEQ_MASK;
- switch(pk->CType) {
- case CT_LONGDATA:
- pk->DLen = 1 << (fr->K + 4);
- break;
- case CT_SHORTDATA:
- pk->DLen = 1 << (fr->K + 4);
- if (pk->Data[0] & 0x80) {
- pk->DLen -= (pk->Data[0] & 0x7F) | (pk->Data[1] << 7);
- if (pk->DLen < 0) {
- printf("DLEN ERROR %d\n", pk->DLen);
- pk->DLen = 0;
- }
- pk->Data += 2;
- } else {
- pk->DLen -= *pk->Data;
- ++pk->Data;
- }
- break;
- default:
- pk->DLen = 0;
- break;
- }
- }
-
- Local
- int
- LenToK(bytes)
- uword bytes;
- {
- uword n = 32;
- uword k = 1;
-
- while (n < bytes) {
- n <<= 1;
- ++k;
- }
- if (k > 8) {
- printf("Soft error, LenToK: %d %d %d\n", bytes, n, k);
- k = 8;
- }
- return((int)k);
- }
-
-