1: #define USER    1
   2: #include <stdio.h>
   3: #include <sys/pk.p>
   4: #include <sys/param.h>
   5: #include <sys/pk.h>
   6: #include <sys/buf.h>
   7: 
   8: /*
   9:  * packet driver
  10:  */
  11: 
  12: char next[8]    ={ 1,2,3,4,5,6,7,0};    /* packet sequence numbers */
  13: char mask[8]    ={ 1,2,4,010,020,040,0100,0200 };
  14: 
  15: struct pack *pklines[NPLINES];
  16: 
  17: 
  18: 
  19: /*
  20:  * receive control messages
  21:  */
  22: pkcntl(c, pk)
  23: register struct pack *pk;
  24: {
  25: register cntl, val;
  26: 
  27:     val = c & MOD8;
  28:     cntl = (c>>3) & MOD8;
  29: 
  30:     if ( ! ISCNTL(c) ) {
  31:         fprintf(stderr, "not cntl\n");
  32:         return;
  33:     }
  34: 
  35:     if (pk->p_mode & 02)
  36:         fprintf(stderr, "%o ",c);
  37:     switch(cntl) {
  38: 
  39:     case INITB:
  40:         val++;
  41:         pk->p_xsize = pksizes[val];
  42:         pk->p_lpsize = val;
  43:         pk->p_bits = DTOM(pk->p_xsize);
  44:         if (pk->p_state & LIVE) {
  45:             pk->p_msg |= M_INITC;
  46:             break;
  47:         }
  48:         pk->p_state |= INITb;
  49:         if ((pk->p_state & INITa)==0) {
  50:             break;
  51:         }
  52:         pk->p_rmsg &= ~M_INITA;
  53:         pk->p_msg |= M_INITC;
  54:         break;
  55: 
  56:     case INITC:
  57:         if ((pk->p_state&INITab)==INITab) {
  58:             pk->p_state = LIVE;
  59:             WAKEUP(&pk->p_state);
  60:             pk->p_rmsg &= ~M_INITB;
  61:         } else
  62:             pk->p_msg |= M_INITB;
  63:         if (val)
  64:             pk->p_swindow = val;
  65:         break;
  66:     case INITA:
  67:         if (val==0 && pk->p_state&LIVE) {
  68:             fprintf(stderr, "alloc change not implemented\n");
  69:             break;
  70:         }
  71:         if (val) {
  72:             pk->p_state |= INITa;
  73:             pk->p_msg |= M_INITB;
  74:             pk->p_rmsg |= M_INITB;
  75:             pk->p_swindow = val;
  76:         }
  77:         break;
  78:     case RJ:
  79:         pk->p_state |= RXMIT;
  80:         pk->p_msg |= M_RR;
  81:     case RR:
  82:         pk->p_rpr = val;
  83:         if (pksack(pk)==0) {
  84:             WAKEUP(&pk->p_ps);
  85:         }
  86:         break;
  87:     case SRJ:
  88:         fprintf(stderr, "srj not implemented\n");
  89:         break;
  90:     case CLOSE:
  91:         pk->p_state = DOWN+RCLOSE;
  92:         SIGNAL;
  93:         WAKEUP(&pk->p_pr);
  94:         WAKEUP(&pk->p_ps);
  95:         WAKEUP(&pk->p_state);
  96:         return;
  97:     }
  98: out:
  99:     if (pk->p_msg)
 100:         pkoutput(pk);
 101: }
 102: 
 103: 
 104: 
 105: pkaccept(pk)
 106: register struct pack *pk;
 107: {
 108: register x,seq;
 109: char m, cntl, *p, imask, **bp;
 110: int bad,accept,skip,s,t,h,cc;
 111: unsigned short sum;
 112: 
 113:     bad = accept = skip = 0;
 114:     /*
 115: 	 * wait for input
 116: 	 */
 117:     LOCK;
 118:     x = next[pk->p_pr];
 119:     while ((imask=pk->p_imap) == 0 && pk->p_rcount==0) {
 120:         PKGETPKT(pk);
 121:         SLEEP(&pk->p_pr, PKIPRI);
 122:     }
 123:     pk->p_imap = 0;
 124:     UNLOCK;
 125: 
 126: 
 127:     /*
 128: 	 * determine input window in m.
 129: 	 */
 130:     t = (~(-1<<pk->p_rwindow)) <<x;
 131:     m = t;
 132:     m |= t>>8;
 133: 
 134: 
 135:     /*
 136: 	 * mark newly accepted input buffers
 137: 	 */
 138:     for(x=0; x<8; x++) {
 139: 
 140:         if ((imask & mask[x]) == 0)
 141:             continue;
 142: 
 143:         if (((cntl=pk->p_is[x])&0200)==0) {
 144:             bad++;
 145: free:
 146:             bp = (char **)pk->p_ib[x];
 147:             LOCK;
 148:             *bp = (char *)pk->p_ipool;
 149:             pk->p_ipool = bp;
 150:             pk->p_is[x] = 0;
 151:             UNLOCK;
 152:             continue;
 153:         }
 154: 
 155:         pk->p_is[x] = ~(B_COPY+B_MARK);
 156:         sum = (unsigned)chksum(pk->p_ib[x], pk->p_rsize) ^ (unsigned)cntl;
 157:         sum += pk->p_isum[x];
 158:         if (sum == CHECK) {
 159:             seq = (cntl>>3) & MOD8;
 160:             if (m & mask[seq]) {
 161:                 if (pk->p_is[seq] & (B_COPY | B_MARK)) {
 162:                 dup:
 163:                     pk->p_msg |= M_RR;
 164:                     skip++;
 165:                     goto free;
 166:                 }
 167:                 if (x != seq) {
 168:                     LOCK;
 169:                     p = pk->p_ib[x];
 170:                     pk->p_ib[x] = pk->p_ib[seq];
 171:                     pk->p_is[x] = pk->p_is[seq];
 172:                     pk->p_ib[seq] = p;
 173:                     UNLOCK;
 174:                 }
 175:                 pk->p_is[seq] = B_MARK;
 176:                 accept++;
 177:                 cc = 0;
 178:                 if (cntl&B_SHORT) {
 179:                     pk->p_is[seq] = B_MARK+B_SHORT;
 180:                     p = pk->p_ib[seq];
 181:                     cc = (unsigned)*p++;
 182:                     if (cc & 0200) {
 183:                         cc &= 0177;
 184:                         cc |= *p << 7;
 185:                     }
 186:                 }
 187:                 pk->p_isum[seq] = pk->p_rsize - cc;
 188:             } else {
 189:                 goto dup;
 190:             }
 191:         } else {
 192:             bad++;
 193:             goto free;
 194:         }
 195:     }
 196: 
 197:     /*
 198: 	 * scan window again turning marked buffers into
 199: 	 * COPY buffers and looking for missing sequence
 200: 	 * numbers.
 201: 	 */
 202:     accept = 0;
 203:     for(x=next[pk->p_pr],t=h= -1; m & mask[x]; x = next[x]) {
 204:         if (pk->p_is[x] & B_MARK)
 205:             pk->p_is[x] |= B_COPY;
 206:     /*  hole code
 207: 		if (pk->p_is[x] & B_COPY) {
 208: 			if (h<0 && t>=0)
 209: 				h = x;
 210: 		} else {
 211: 			if (t<0)
 212: 				t = x;
 213: 		}
 214: 	*/
 215:         if (pk->p_is[x] & B_COPY) {
 216:             if (t >= 0) {
 217:                 bp = (char **)pk->p_ib[x];
 218:                 LOCK;
 219:                 *bp = (char *)pk->p_ipool;
 220:                 pk->p_ipool = bp;
 221:                 pk->p_is[x] = 0;
 222:                 UNLOCK;
 223:                 skip++;
 224:             } else
 225:                 accept++;
 226:         } else {
 227:             if (t<0)
 228:                 t = x;
 229:         }
 230:     }
 231: 
 232:     if (bad) {
 233:         pk->p_msg |= M_RJ;
 234:     }
 235: 
 236:     if (skip) {
 237:         pk->p_msg |= M_RR;
 238:     }
 239: 
 240:     pk->p_rcount = accept;
 241:     return(accept);
 242: }
 243: 
 244: 
 245: pkread(S)
 246: SDEF;
 247: {
 248: register struct pack *pk;
 249: register x,s;
 250: int is,cc,xfr,count;
 251: char *cp, **bp;
 252: 
 253:     pk = PADDR;
 254:     xfr = 0;
 255:     count = 0;
 256:     while (pkaccept(pk)==0);
 257: 
 258: 
 259:     while (UCOUNT) {
 260: 
 261:         x = next[pk->p_pr];
 262:         is = pk->p_is[x];
 263: 
 264:         if (is & B_COPY) {
 265:             cc = MIN(pk->p_isum[x], UCOUNT);
 266:             if (cc==0 && xfr) {
 267:                 break;
 268:             }
 269:             if (is & B_RESID)
 270:                 cp = pk->p_rptr;
 271:             else {
 272:                 cp = pk->p_ib[x];
 273:                 if (is & B_SHORT) {
 274:                     if (*cp++ & 0200)
 275:                         *cp++;
 276:                 }
 277:             }
 278:             IOMOVE(cp,cc,B_READ);
 279:             count += cc;
 280:             xfr++;
 281:             pk->p_isum[x] -= cc;
 282:             if (pk->p_isum[x] == 0) {
 283:                 pk->p_pr = x;
 284:                 bp = (char **)pk->p_ib[x];
 285:                 LOCK;
 286:                 *bp = (char *)pk->p_ipool;
 287:                 pk->p_ipool = bp;
 288:                 pk->p_is[x] = 0;
 289:                 pk->p_rcount--;
 290:                 UNLOCK;
 291:                 pk->p_msg |= M_RR;
 292:             } else {
 293:                 pk->p_rptr = cp+cc;
 294:                 pk->p_is[x] |= B_RESID;
 295:             }
 296:             if (cc==0)
 297:                 break;
 298:         } else
 299:             break;
 300:     }
 301:     pkoutput(pk);
 302:     return(count);
 303: }
 304: 
 305: 
 306: 
 307: 
 308: pkwrite(S)
 309: SDEF;
 310: {
 311: register struct pack *pk;
 312: register x;
 313: int partial;
 314: caddr_t cp;
 315: int cc, s, fc, count;
 316: int pktimeout();
 317: 
 318:     pk = PADDR;
 319:     if (pk->p_state&DOWN || !pk->p_state&LIVE) {
 320:         SETERROR;
 321:         return(-1);
 322:     }
 323: 
 324:     count = UCOUNT;
 325:     do {
 326:         LOCK;
 327:         while (pk->p_xcount>=pk->p_swindow)  {
 328:             pkoutput(pk);
 329:             PKGETPKT(pk);
 330:             SLEEP(&pk->p_ps,PKOPRI);
 331:         }
 332:         x = next[pk->p_pscopy];
 333:         while (pk->p_os[x]!=B_NULL)  {
 334:             PKGETPKT(pk);
 335:             SLEEP(&pk->p_ps,PKOPRI);
 336:         }
 337:         pk->p_os[x] = B_MARK;
 338:         pk->p_pscopy = x;
 339:         pk->p_xcount++;
 340:         UNLOCK;
 341: 
 342:         cp = pk->p_ob[x] = GETEPACK;
 343:         partial = 0;
 344:         if ((int)UCOUNT < pk->p_xsize) {
 345:             cc = UCOUNT;
 346:             fc = pk->p_xsize - cc;
 347:             *cp = fc&0177;
 348:             if (fc > 127) {
 349:                 *cp++ |= 0200;
 350:                 *cp++ = fc>>7;
 351:             } else
 352:                 cp++;
 353:             partial = B_SHORT;
 354:         } else
 355:             cc = pk->p_xsize;
 356:         IOMOVE(cp,cc,B_WRITE);
 357:         pk->p_osum[x] = chksum(pk->p_ob[x], pk->p_xsize);
 358:         pk->p_os[x] = B_READY+partial;
 359:         pkoutput(pk);
 360:     } while (UCOUNT);
 361: 
 362:     return(count);
 363: }
 364: 
 365: pksack(pk)
 366: register struct pack *pk;
 367: {
 368: register x, i;
 369: 
 370:     i = 0;
 371:     for(x=pk->p_ps; x!=pk->p_rpr; ) {
 372:         x = next[x];
 373:         if (pk->p_os[x]&B_SENT) {
 374:             i++;
 375:             pk->p_os[x] = B_NULL;
 376:             pk->p_state &= ~WAITO;
 377:             pk->p_xcount--;
 378:             FREEPACK(pk->p_ob[x], pk->p_bits);
 379:             pk->p_ps = x;
 380:             WAKEUP(&pk->p_ps);
 381:         }
 382:     }
 383:     return(i);
 384: }
 385: 
 386: 
 387: 
 388: pkoutput(pk)
 389: register struct pack *pk;
 390: {
 391: register x,rx;
 392: int s;
 393: char bstate;
 394: int i;
 395: SDEF;
 396: int flag;
 397: 
 398:     flag = 0;
 399:     ISYSTEM;
 400:     LOCK;
 401:     if (pk->p_obusy++ || OBUSY) {
 402:         pk->p_obusy--;
 403:         UNLOCK;
 404:         return;
 405:     }
 406:     UNLOCK;
 407: 
 408: 
 409:     /*
 410: 	 * find seq number and buffer state
 411: 	 * of next output packet
 412: 	 */
 413:     if (pk->p_state&RXMIT)  {
 414:         pk->p_nxtps = next[pk->p_rpr];
 415:         flag++;
 416:     }
 417:     x = pk->p_nxtps;
 418:     bstate = pk->p_os[x];
 419: 
 420: 
 421:     /*
 422: 	 * Send control packet if indicated
 423: 	 */
 424:     if (pk->p_msg) {
 425:         if (pk->p_msg & ~M_RR || !(bstate&B_READY) ) {
 426:             x = pk->p_msg;
 427:             for(i=0; i<8; i++)
 428:                 if (x&1)
 429:                     break; else
 430:                 x >>= 1;
 431:             x = i;
 432:             x <<= 3;
 433:             switch(i) {
 434:             case CLOSE:
 435:                 break;
 436:             case RJ:
 437:             case RR:
 438:                 x += pk->p_pr;
 439:                 break;
 440:             case SRJ:
 441:                 break;
 442:             case INITB:
 443:                 x += pksize(pk->p_rsize);
 444:                 break;
 445:             case INITC:
 446:                 x += pk->p_rwindow;
 447:                 break;
 448:             case INITA:
 449:                 x += pk->p_rwindow;
 450:                 break;
 451:             }
 452: 
 453:             pk->p_msg &= ~mask[i];
 454:             pkxstart(pk, x, -1);
 455:             goto out;
 456:         }
 457:     }
 458: 
 459: 
 460:     /*
 461: 	 * Don't send data packets if line is marked dead.
 462: 	 */
 463:     if (pk->p_state&DOWN) {
 464:         WAKEUP(&pk->p_ps);
 465:         goto out;
 466:     }
 467:     /*
 468: 	 * Start transmission (or retransmission) of data packets.
 469: 	 */
 470:     if (bstate & (B_READY|B_SENT)) {
 471:         char seq;
 472: 
 473:         bstate |= B_SENT;
 474:         seq = x;
 475:         pk->p_nxtps = next[x];
 476: 
 477:         x = 0200+pk->p_pr+(seq<<3);
 478:         if (bstate & B_SHORT)
 479:             x |= 0100;
 480:         pkxstart(pk, x, seq);
 481:         pk->p_os[seq] = bstate;
 482:         pk->p_state &= ~RXMIT;
 483:         pk->p_nout++;
 484:         goto out;
 485:     }
 486:     /*
 487: 	 * enable timeout if there's nothing to send
 488: 	 * and transmission buffers are languishing
 489: 	 */
 490:     if (pk->p_xcount) {
 491:         pk->p_timer = 2;
 492:         pk->p_state |= WAITO;
 493:     } else
 494:         pk->p_state &= ~WAITO;
 495:     WAKEUP(&pk->p_ps);
 496: out:
 497:     pk->p_obusy = 0;
 498: }
 499: 
 500: 
 501: /*
 502:  * shut down line by
 503:  *	ignoring new input
 504:  *	letting output drain
 505:  *	releasing space and turning off line discipline
 506:  */
 507: pkclose(S)
 508: SDEF;
 509: {
 510: register struct pack *pk;
 511: register i,s,rbits;
 512: char **bp;
 513: int rcheck;
 514: char *p;
 515: 
 516: 
 517:     pk = PADDR;
 518:     pk->p_state |= DRAINO;
 519: 
 520: 
 521:     /*
 522: 	 * try to flush output
 523: 	 */
 524:     i = 0;
 525:     LOCK;
 526:     pk->p_timer = 2;
 527:     while (pk->p_xcount && pk->p_state&LIVE) {
 528:         if (pk->p_state&(RCLOSE+DOWN) || ++i > 2)
 529:             break;
 530:         pkoutput(pk);
 531:         SLEEP(&pk->p_ps,PKOPRI);
 532:     }
 533:     pk->p_timer = 0;
 534:     pk->p_state |= DOWN;
 535:     UNLOCK;
 536: 
 537: 
 538:     /*
 539: 	 * try to exchange CLOSE messages
 540: 	 */
 541:     i = 0;
 542:     while ((pk->p_state&RCLOSE)==0 && i<2) {
 543:         pk->p_msg = M_CLOSE;
 544:         pk->p_timer = 2;
 545:         pkoutput(pk);
 546:         SLEEP(&pk->p_ps, PKOPRI);
 547:         i++;
 548:     }
 549: 
 550: 
 551:     for(i=0;i<NPLINES;i++)
 552:         if (pklines[i]==pk)  {
 553:             pklines[i] = NULL;
 554:         }
 555:     TURNOFF;
 556: 
 557: 
 558:     /*
 559: 	 * free space
 560: 	 */
 561:     rbits = DTOM(pk->p_rsize);
 562:     rcheck = 0;
 563:     for (i=0;i<8;i++) {
 564:         if (pk->p_os[i]!=B_NULL) {
 565:             FREEPACK(pk->p_ob[i],pk->p_bits);
 566:             pk->p_xcount--;
 567:         }
 568:         if (pk->p_is[i]!=B_NULL)  {
 569:             FREEPACK(pk->p_ib[i],rbits);
 570:             rcheck++;
 571:         }
 572:     }
 573:     LOCK;
 574:     while (pk->p_ipool != NULL) {
 575:         bp = pk->p_ipool;
 576:         pk->p_ipool = (char **)*bp;
 577:         rcheck++;
 578:         FREEPACK(bp, rbits);
 579:     }
 580:     UNLOCK;
 581:     if (rcheck  != pk->p_rwindow) {
 582:         fprintf(stderr, "r short %d want %d\n",rcheck,pk->p_rwindow);
 583:         fprintf(stderr, "rcount = %d\n",pk->p_rcount);
 584:         fprintf(stderr, "xcount = %d\n",pk->p_xcount);
 585:     }
 586:     FREEPACK((caddr_t)pk, npbits);
 587: }
 588: 
 589: 
 590: 
 591: pkreset(pk)
 592: register struct pack *pk;
 593: {
 594: 
 595:     pk->p_ps = pk->p_pr =  pk->p_rpr = 0;
 596:     pk->p_nxtps = 1;
 597: }
 598: 
 599: chksum(s,n)
 600: register char *s;
 601: register n;
 602: {
 603:     register short sum;
 604:     register unsigned t;
 605:     register x;
 606: 
 607:     sum = -1;
 608:     x = 0;
 609: 
 610:     do {
 611:         if (sum<0) {
 612:             sum <<= 1;
 613:             sum++;
 614:         } else
 615:             sum <<= 1;
 616:         t = sum;
 617:         sum += (unsigned)*s++;
 618:         x += sum^n;
 619:         if ((unsigned)sum <= t) {
 620:             sum ^= x;
 621:         }
 622:     } while (--n > 0);
 623: 
 624:     return(sum);
 625: }
 626: 
 627: pkline(pk)
 628: register struct pack *pk;
 629: {
 630: register i;
 631:     for(i=0;i<NPLINES;i++) {
 632:         if (pklines[i]==pk)
 633:             return(i);
 634:     }
 635:     return(-i);
 636: }
 637: 
 638: pkzero(s,n)
 639: register char *s;
 640: register n;
 641: {
 642:     while (n--)
 643:         *s++ = 0;
 644: }
 645: 
 646: pksize(n)
 647: register n;
 648: {
 649: register k;
 650: 
 651:     n >>= 5;
 652:     for(k=0; n >>= 1; k++);
 653:     return(k);
 654: }

Defined functions

chksum defined in line 599; used 2 times
pkaccept defined in line 105; used 1 times
pkclose defined in line 507; used 1 times
pkcntl defined in line 22; used 1 times
pkline defined in line 627; never used
pkoutput defined in line 388; used 10 times
pkread defined in line 245; used 2 times
pkreset defined in line 591; used 1 times
pksack defined in line 365; used 2 times
pksize defined in line 646; used 1 times
pkwrite defined in line 308; used 1 times
pkzero defined in line 638; used 1 times

Defined variables

mask defined in line 13; used 4 times
next defined in line 12; used 8 times
pklines defined in line 15; used 3 times

Defined macros

USER defined in line 1; never used
Last modified: 1979-01-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1478
Valid CSS Valid XHTML 1.0 Strict