Annotation of researchv10dc/630/src/precv.c, revision 1.1.1.1

1.1       root        1: /*
                      2: **     Process receiver buffers
                      3: */
                      4: 
                      5: #include       "pconfig.h"
                      6: #include       "proto.h"
                      7: #include       "packets.h"
                      8: #include       "pstats.h"
                      9: 
                     10: 
                     11: /* extern int  crc(); */
                     12: void   Reply(), Control();
                     13: int    Retry();
                     14: 
                     15: struct Pktstate precvpkt;
                     16: /* static */ Pkt_p     Pkp;
                     17: /* static */ char *    pbufp;
                     18: /* static */ char *    Sbufp;
                     19: /* static */ short     dcount;
                     20: /* static */ short     Scount;
                     21: 
                     22: #define        Pkt     precvpkt.pkt
                     23: #define        State   precvpkt.state
                     24: #define        Timo    precvpkt.timo
                     25: #define        Header  Pkt.header
                     26: #define        Dsize   Pkt.dsize
                     27: #define        Data    Pkp->data
                     28: 
                     29: #define        Ptyp    (Pkt.header & P_PTYPE)
                     30: #define        Cntl    (Pkt.header & P_CNTL)
                     31: #define        Channel P_channel(Pkt.header)
                     32: #define        Seq     P_seq(Pkt.header)
                     33: #define        Nextseq pconvs[Channel].rseq
                     34: 
                     35: 
                     36: 
                     37: void
                     38: #ifndef        Blit
                     39: precv(bufp, count)
                     40:        register char * bufp;
                     41:        register int    count;
                     42: {
                     43:        int             haveheader = 0;
                     44: 
                     45:        while ( count-- )
                     46: #else  Blit
                     47: precv(c)
                     48:        char            c;
                     49: #endif Blit
                     50:        {
                     51:                switch ( State )
                     52:                {
                     53:                 case PR_NULL:
                     54: #                      ifndef  Blit
                     55:                        Pkp = (Pkt_p)bufp;
                     56:                        haveheader++;
                     57:                        Header = *bufp++;
                     58: #                      else    Blit
                     59:                        Header = c;
                     60: #                      endif   Blit
                     61:                        if ( !Ptyp )
                     62:                        {
                     63:                                PSTATS(PS_BADHDR);
                     64:                                ptracepkt(Pkp, pstats[PS_BADHDR].descp);
                     65:                                break;
                     66:                        }
                     67:                        Timo = Prtimeout;
                     68:                        if ( !Ptflag )
                     69:                        {
                     70:                                Ptflag++;
                     71: #                              ifndef  Blit
                     72:                                (void)alarm(Pscanrate);
                     73: #                              endif
                     74:                        }
                     75:                        State = PR_SIZE;
                     76: #                      ifndef  Blit
                     77:                        continue;
                     78: #                      else
                     79:                        return;
                     80: #                      endif
                     81: 
                     82:                 case PR_SIZE:
                     83: #                      ifndef  Blit
                     84:                        Dsize = *bufp++;
                     85: #                      else
                     86:                        Dsize = c;
                     87: #                      endif
                     88:                        Scount = Dsize;
                     89:                        if ( Scount > MAXPKTDSIZE )
                     90:                        {
                     91:                                PSTATS(PS_BADSIZE);
                     92:                                ptracepkt((haveheader?Pkp:&Pkt), pstats[PS_BADSIZE].descp);
                     93:                                break;
                     94:                        }
                     95:                        dcount = Scount + EDSIZE;
                     96: #                      ifndef  Blit
                     97:                        if ( dcount <= count && haveheader )
                     98:                        {
                     99:                                /* Don't move data */
                    100:                                Sbufp = bufp;
                    101:                                bufp += dcount;
                    102:                                count -= dcount;
                    103:                                goto check;
                    104:                        }
                    105: #                      endif
                    106:                        Pkp = &Pkt;
                    107:                        Sbufp = (char *)Data;
                    108:                        pbufp = Sbufp;
                    109:                        State = PR_DATA;
                    110: #                      ifndef  Blit
                    111:                        continue;
                    112: #                      else
                    113:                        return;
                    114: #                      endif
                    115: 
                    116:                 case PR_DATA:
                    117: #                      ifndef  Blit
                    118:                        *pbufp++ = *bufp++;
                    119: #                      else
                    120:                        *pbufp++ = c;
                    121: #                      endif
                    122:                        if ( --dcount > 0 )
                    123: #                              ifndef  Blit
                    124:                                continue;
                    125: #                              else
                    126:                                return;
                    127: #                              endif
                    128: 
                    129: check:
                    130:                        /** Now at CRC **/
                    131: 
                    132:                        plogpkt(Pkp, PLOGIN);
                    133: 
                    134:                        if ( crc((uchar *)Pkp, (int)(Scount+2)) ) /* if bit fields were independent */
                    135:                        {
                    136:                                PSTATS(PS_BADCRC);
                    137:                                ptracepkt(Pkp, pstats[PS_BADCRC].descp);
                    138:                        }
                    139:                        else
                    140:                        {
                    141:                                if ( Cntl )
                    142:                                        Control();
                    143:                                else
                    144:                                {
                    145:                                        Pcdata = (uchar)0;
                    146:                                        if ( Seq == Nextseq )
                    147:                                        {
                    148:                                                if ( (*Prfuncp)(Channel, Sbufp, Scount) )
                    149:                                                {
                    150:                                                        PSTATS(PS_BUSY);
                    151:                                                        /* Better to let this timeout,
                    152:                                                        ** as a following sequence will
                    153:                                                        ** generate a second retransmission
                    154:                                                        */
                    155:                                                        Reply(NAK);
                    156:                                                }
                    157:                                                else
                    158:                                                {
                    159:                                                        Nextseq = (Nextseq+1) & (SEQMOD-1);     /* NB rseq is a byte, not a bit field, for efficiency */
                    160:                                                        PSTATS(PS_RPKTS);
                    161: #                                                      ifdef   PSTATISTICS
                    162:                                                        pstats[PS_RBYTES].count += Scount;
                    163: #                                                      endif
                    164:                                                        pconvs[Channel].cdata[Seq] = Pcdata;
                    165:                                                        Reply(ACK);
                    166:                                                }
                    167:                                        }
                    168:                                        else
                    169:                                        if ( Retry() )
                    170:                                        {
                    171:                                                PSTATS(PS_RDUP);
                    172:                                                Reply(ACK);
                    173:                                        }
                    174:                                        else
                    175:                                        {
                    176:                                                PSTATS(PS_OUTSEQ);
                    177:                                                Reply(NAK);
                    178:                                                pdumphist(pstats[PS_OUTSEQ].descp);
                    179:                                        }
                    180:                                }
                    181:                        }
                    182:                }
                    183: 
                    184:                Timo = 0;
                    185:                State = PR_NULL;
                    186: #ifndef        Blit
                    187:        }
                    188: #endif
                    189: }
                    190: 
                    191: 
                    192: 
                    193: /*
                    194: **     Deal with control packet
                    195: */
                    196: 
                    197: void
                    198: Control()
                    199: {
                    200:        register Pch_p  pcp = &pconvs[Channel];
                    201:        register Pks_p  psp = pcp->nextpkt;
                    202:        register Pbyte *lastseqp = &pseqtable[Seq+SEQMOD];
                    203:        register Pbyte *seqp = lastseqp - (NPCBUFS-1);
                    204:        register int    hit = 0;
                    205: #      ifdef   Blit
                    206:        register int    x = spl1();
                    207: #      endif
                    208: 
                    209:        if ( Scount == 0 )
                    210:                goto ack;
                    211: 
                    212:        switch ( Data[0] )
                    213:        {
                    214:         case ACK:
                    215:                /** This and all lesser sequenced packets ok **/
                    216: ack:
                    217:                do
                    218:                {
                    219:                        if ( *seqp == P_seq(psp->pkt.header) )
                    220:                        {
                    221:                                if ( psp->state != PX_WAIT )
                    222:                                {
                    223: #                                      if      PDEBUG == 1 || PSTATISTICS == 1
                    224:                                        if ( psp->state != PX_OK )
                    225:                                        {
                    226:                                                PSTATS(PS_BADXST);
                    227:                                                pdumphist(pstats[PS_BADXST].descp);
                    228:                                        }
                    229: #                                      endif
                    230:                                }
                    231:                                else
                    232:                                {
                    233:                                        psp->state = PX_OK;
                    234:                                        psp->timo = 0;
                    235:                                        hit++;
                    236:                                }
                    237:                                if ( ++psp >= &pcp->pkts[NPCBUFS] )
                    238:                                        psp = pcp->pkts;
                    239:                        }
                    240:                } while
                    241:                        ( ++seqp <= lastseqp );
                    242:                if ( hit )
                    243:                {
                    244:                        pcp->nextpkt = psp;
                    245:                        pcp->freepkts += hit;
                    246: #                      ifdef   PSTATISTICS
                    247:                        pstats[PS_XPKTS].count += hit;
                    248:                        if ( hit > 1 )
                    249:                                PSTATS(PS_LOSTACK);
                    250: #                      endif
                    251:                        break;
                    252:                }
                    253: #              if      PDEBUG == 1 || PSTATISTICS == 1
                    254:                PSTATS(PS_BADACK);
                    255:                pdumphist(pstats[PS_BADACK].descp);
                    256: #              endif
                    257: #              ifdef   Blit
                    258:                splx(x);
                    259: #              endif
                    260:                return;
                    261: 
                    262:         case NAK:
                    263:                /** Retransmit this and all lesser sequenced packets **/
                    264: 
                    265:                do
                    266:                {
                    267:                        if ( *seqp == P_seq(psp->pkt.header) )
                    268:                        {
                    269:                                if ( psp->state != PX_WAIT )
                    270:                                {
                    271: #                                      if      PSTATISTICS == 1 || PDEBUG == 1
                    272:                                        if ( psp->state != PX_OK )
                    273:                                        {
                    274:                                                PSTATS(PS_BADXST);
                    275:                                                pdumphist(pstats[PS_BADXST].descp);
                    276:                                        }
                    277: #                                      endif
                    278:                                }
                    279:                                else
                    280:                                {
                    281:                                        psp->timo = Pxtimeout;
                    282:                                        (void)Pxfunc(&psp->pkt, psp->size);
                    283:                                        PSTATS(PS_NAKPKT);
                    284:                                        hit++;
                    285:                                        plogpkt(&psp->pkt, PLOGOUT);
                    286:                                }
                    287:                                if ( ++psp >= &pcp->pkts[NPCBUFS] )
                    288:                                        psp = pcp->pkts;
                    289:                        }
                    290:                } while
                    291:                        ( ++seqp <= lastseqp );
                    292:                if ( !hit )
                    293:                {
                    294:                        PSTATS(PS_BADNAK);
                    295:                        pdumphist(pstats[PS_BADNAK].descp);
                    296: #                      ifdef   Blit
                    297:                        splx(x);
                    298: #                      endif
                    299:                        return;
                    300:                }
                    301:                break;
                    302: 
                    303:         case PCDATA:
                    304:                break;
                    305: 
                    306:         default:
                    307:                PSTATS(PS_BADCNTL);
                    308:                ptracepkt(Pkp, pstats[PS_BADCNTL].descp);
                    309: #              ifdef   Blit
                    310:                splx(x);
                    311: #              endif
                    312:                return;
                    313:        }
                    314: #      ifdef   Blit
                    315:        splx(x);
                    316: #      endif
                    317: 
                    318:        if ( --Scount > 0 )
                    319:        {
                    320:                (*Prcfuncp)(Channel, Sbufp+1, Scount);
                    321: #              ifdef   PSTATISTICS
                    322:                pstats[PS_RCBYTES].count += Scount;
                    323: #              endif
                    324:        }
                    325: }
                    326: 
                    327: 
                    328: 
                    329: /*
                    330: **     Reply to good packet
                    331: */
                    332: 
                    333: void
                    334: Reply(ctl)
                    335:        Pbyte           ctl;
                    336: {
                    337:        register int    count;
                    338: 
                    339:        Pkt.header |= P_CNTL;
                    340:        if ( Pcdata )
                    341:        {
                    342:                PSTATS(PS_XCBYTES);
                    343:                count = 2;
                    344:                Pkt.data[1] = Pcdata;
                    345:                Pkt.data[0] = ctl;
                    346:        }
                    347:        else
                    348:        if ( ctl != ACK )
                    349:        {
                    350:                count = 1;
                    351:                Pkt.data[0] = ctl;
                    352:        }
                    353:        else
                    354:                count = 0;
                    355:        Dsize = count;
                    356:        count += 2;     /* if bit fields were independent               */
                    357: 
                    358:        (void)crc((Pbyte *)&Pkt, count);
                    359:        count += EDSIZE;
                    360: 
                    361:        (void)Pxfunc(&Pkt, count);
                    362:        plogpkt(&Pkt, PLOGOUT);
                    363: }
                    364: 
                    365: 
                    366: 
                    367: /*
                    368: **     Non trivial sequence number validation:
                    369: **      is this a valid retransmission?
                    370: */
                    371: 
                    372: int
                    373: Retry()
                    374: {
                    375:        register Pbyte *lastseqp = &pseqtable[Nextseq+SEQMOD-1];
                    376:        register Pbyte *seqp = lastseqp - (NPCBUFS-1);
                    377: 
                    378:        do
                    379:                if ( *seqp == Seq )
                    380:                {
                    381:                        Pcdata = pconvs[Channel].cdata[Seq];
                    382:                        return 1;
                    383:                }
                    384:        while
                    385:                ( ++seqp <= lastseqp );
                    386: 
                    387:        return 0;
                    388: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.