1: #ifndef lint
   2: static char sccsid[] = "@(#)pk1.c	5.1 (Berkeley) 7/2/83";
   3: #endif
   4: 
   5: extern  char    *malloc();
   6: 
   7: #define USER    1
   8: #include <stdio.h>
   9: #ifdef SYSIII
  10: #include <sys/types.h>
  11: #endif
  12: #include "pk.p"
  13: #include <sys/param.h>
  14: #include "pk.h"
  15: #include <sys/buf.h>
  16: #include <setjmp.h>
  17: #include <signal.h>
  18: 
  19: 
  20: #define PKMAXSTMSG 40
  21: #define PKTIME  25
  22: extern int Errorrate;
  23: int Connodata = 0;
  24: int Ntimeout = 0;
  25: #define CONNODATA 10
  26: #define NTIMEOUT 50
  27: /*
  28:  * packet driver support routines
  29:  *
  30:  */
  31: 
  32: struct pack *pklines[NPLINES];
  33: 
  34: /*
  35:  * start initial synchronization.
  36:  */
  37: 
  38: struct pack *
  39: pkopen(ifn, ofn)
  40: int ifn, ofn;
  41: {
  42:     register struct pack *pk;
  43:     register char **bp;
  44:     register int i;
  45: 
  46:     if (++pkactive >= NPLINES)
  47:         return(NULL);
  48:     if ((pk = (struct pack *) malloc(sizeof (struct pack))) == NULL)
  49:         return(NULL);
  50:     pkzero((caddr_t) pk, sizeof (struct pack));
  51:     pk->p_ifn = ifn;
  52:     pk->p_ofn = ofn;
  53:     pk->p_xsize = pk->p_rsize = PACKSIZE;
  54:     pk->p_rwindow = pk->p_swindow = WINDOWS;
  55:     /*  allocate input windows */
  56:     for (i = 0; i < pk->p_rwindow; i++) {
  57:         if ((bp = (char **) GETEPACK) == NULL)
  58:             break;
  59:         *bp = (char *) pk->p_ipool;
  60:         pk->p_ipool = bp;
  61:     }
  62:     if (i == 0)
  63:         return(NULL);
  64:     pk->p_rwindow = i;
  65: 
  66:     /* start synchronization */
  67:     pk->p_msg = pk->p_rmsg = M_INITA;
  68:     for (i = 0; i < NPLINES; i++) {
  69:         if (pklines[i] == NULL) {
  70:             pklines[i] = pk;
  71:             break;
  72:         }
  73:     }
  74:     if (i >= NPLINES)
  75:         return(NULL);
  76:     pkoutput(pk);
  77: 
  78:     for (i = 0; i < PKMAXSTMSG; i++) {
  79:         PKGETPKT(pk);
  80:         if ((pk->p_state & LIVE) != 0)
  81:             break;
  82:     }
  83:     if (i >= PKMAXSTMSG)
  84:         return(NULL);
  85: 
  86:     pkreset(pk);
  87:     return(pk);
  88: }
  89: 
  90: 
  91: /*
  92:  * input framing and block checking.
  93:  * frame layout for most devices is:
  94:  *
  95:  *	S|K|X|Y|C|Z|  ... data ... |
  96:  *
  97:  *	where 	S	== initial synch byte
  98:  *		K	== encoded frame size (indexes pksizes[])
  99:  *		X, Y	== block check bytes
 100:  *		C	== control byte
 101:  *		Z	== XOR of header (K^X^Y^C)
 102:  *		data	== 0 or more data bytes
 103:  *
 104:  */
 105: 
 106: int pksizes[] = {
 107:     1, 32, 64, 128, 256, 512, 1024, 2048, 4096, 1
 108: };
 109: 
 110: #define GETRIES 5
 111: /*
 112:  * Pseudo-dma byte collection.
 113:  */
 114: 
 115: pkgetpack(ipk)
 116: struct pack *ipk;
 117: {
 118:     int ret, k, tries;
 119:     register char *p;
 120:     register struct pack *pk;
 121:     register struct header *h;
 122:     unsigned short sum;
 123:     int ifn;
 124:     char **bp;
 125:     char hdchk;
 126: 
 127:     pk = PADDR;
 128:     if ((pk->p_state & DOWN) ||
 129:       Connodata > CONNODATA /* || Ntimeout > NTIMEOUT */)
 130:         pkfail();
 131:     ifn = pk->p_ifn;
 132: 
 133:     /* find HEADER */
 134:     for (tries = 0; tries < GETRIES; ) {
 135:         p = (caddr_t) &pk->p_ihbuf;
 136:         if ((ret = pkcget(ifn, p, 1)) < 0) {
 137:             /* set up retransmit or REJ */
 138:             tries++;
 139:             pk->p_msg |= pk->p_rmsg;
 140:             if (pk->p_msg == 0)
 141:                 pk->p_msg |= M_RR;
 142:             if ((pk->p_state & LIVE) == LIVE)
 143:                 pk->p_state |= RXMIT;
 144:             pkoutput(pk);
 145:             continue;
 146:         }
 147:         if (*p != SYN)
 148:             continue;
 149:         p++;
 150:         ret = pkcget(ifn, p, HDRSIZ - 1);
 151:         if (ret == -1)
 152:             continue;
 153:         break;
 154:     }
 155:     if (tries >= GETRIES) {
 156:         PKDEBUG(4, "tries = %d\n", tries);
 157:         pkfail();
 158:     }
 159: 
 160:     Connodata++;
 161:     h = (struct header * ) &pk->p_ihbuf;
 162:     p = (caddr_t) h;
 163:     hdchk = p[1] ^ p[2] ^ p[3] ^ p[4];
 164:     p += 2;
 165:     sum = (unsigned) *p++ & 0377;
 166:     sum |= (unsigned) *p << 8;
 167:     h->sum = sum;
 168:     PKDEBUG(7, "rec h->cntl %o\n", (unsigned) h->cntl);
 169:     k = h->ksize;
 170:     if (hdchk != h->ccntl) {
 171:         /* bad header */
 172:         PKDEBUG(7, "bad header %o,", hdchk);
 173:         PKDEBUG(7, "h->ccntl %o\n", h->ccntl);
 174:         return;
 175:     }
 176:     if (k == 9) {
 177:         if (((h->sum + h->cntl) & 0xffff) == CHECK) {
 178:             pkcntl(h->cntl, pk);
 179:             PKDEBUG(7, "state - %o\n", pk->p_state);
 180:         }
 181:         else {
 182:             /*  bad header */
 183:             PKDEBUG(7, "bad header (k==9) %o\n", h->cntl);
 184:             pk->p_state |= BADFRAME;
 185:         }
 186:         return;
 187:     }
 188:     if (k && pksizes[k] == pk->p_rsize) {
 189:         pk->p_rpr = h->cntl & MOD8;
 190:         pksack(pk);
 191:         Connodata = 0;
 192:         bp = pk->p_ipool;
 193:         pk->p_ipool = (char **) *bp;
 194:         if (bp == NULL) {
 195:             PKDEBUG(7, "bp NULL %s\n", "");
 196:         return;
 197:         }
 198:     }
 199:     else {
 200:         return;
 201:     }
 202:     ret = pkcget(pk->p_ifn, (char *) bp, pk->p_rsize);
 203:     if (ret == 0)
 204:         pkdata(h->cntl, h->sum, pk, (char **) bp);
 205:     return;
 206: }
 207: 
 208: 
 209: pkdata(c, sum, pk, bp)
 210: char c;
 211: unsigned short sum;
 212: register struct pack *pk;
 213: char **bp;
 214: {
 215: register x;
 216: int t;
 217: char m;
 218: 
 219:     if (pk->p_state & DRAINO || !(pk->p_state & LIVE)) {
 220:         pk->p_msg |= pk->p_rmsg;
 221:         pkoutput(pk);
 222:         goto drop;
 223:     }
 224:     t = next[pk->p_pr];
 225:     for(x=pk->p_pr; x!=t; x = (x-1)&7) {
 226:         if (pk->p_is[x] == 0)
 227:             goto slot;
 228:     }
 229: drop:
 230:     *bp = (char *)pk->p_ipool;
 231:     pk->p_ipool = bp;
 232:     return;
 233: 
 234: slot:
 235:     m = mask[x];
 236:     pk->p_imap |= m;
 237:     pk->p_is[x] = c;
 238:     pk->p_isum[x] = sum;
 239:     pk->p_ib[x] = (char *)bp;
 240:     return;
 241: }
 242: 
 243: 
 244: 
 245: /*
 246:  * setup input transfers
 247:  */
 248: pkrstart(pk)
 249: {}
 250: 
 251: #define PKMAXBUF 128
 252: /*
 253:  * Start transmission on output device associated with pk.
 254:  * For asynch devices (t_line==1) framing is
 255:  * imposed.  For devices with framing and crc
 256:  * in the driver (t_line==2) the transfer is
 257:  * passed on to the driver.
 258:  */
 259: pkxstart(pk, cntl, x)
 260: register struct pack *pk;
 261: char cntl;
 262: register x;
 263: {
 264:     register char *p;
 265:     int ret;
 266:     short checkword;
 267:     char hdchk;
 268: 
 269:     p = (caddr_t) &pk->p_ohbuf;
 270:     *p++ = SYN;
 271:     if (x < 0) {
 272:         *p++ = hdchk = 9;
 273:         checkword = cntl;
 274:     }
 275:     else {
 276:         *p++ = hdchk = pk->p_lpsize;
 277:         checkword = pk->p_osum[x] ^ (unsigned)(cntl & 0377);
 278:     }
 279:     checkword = CHECK - checkword;
 280:     *p = checkword;
 281:     hdchk ^= *p++;
 282:     *p = checkword>>8;
 283:     hdchk ^= *p++;
 284:     *p = cntl;
 285:     hdchk ^= *p++;
 286:     *p = hdchk;
 287:  /*  writes  */
 288: PKDEBUG(7, "send %o\n", (unsigned) cntl);
 289:     p = (caddr_t) & pk->p_ohbuf;
 290:     if (x < 0) {
 291: #ifdef PROTODEBUG
 292:         GENERROR(p, HDRSIZ);
 293: #endif
 294:         ret = write(pk->p_ofn, p, HDRSIZ);
 295:         PKASSERT(ret == HDRSIZ, "PKXSTART ret", "", ret);
 296:     }
 297:     else {
 298:         char buf[PKMAXBUF + HDRSIZ], *b;
 299:         int i;
 300:         for (i = 0, b = buf; i < HDRSIZ; i++)
 301:             *b++ = *p++;
 302:         for (i = 0, p = pk->p_ob[x]; i < pk->p_xsize; i++)
 303:             *b++ = *p++;
 304: #ifdef PROTODEBUG
 305:         GENERROR(buf, pk->p_xsize + HDRSIZ);
 306: #endif
 307:         ret = write(pk->p_ofn, buf, pk->p_xsize + HDRSIZ);
 308:         PKASSERT(ret == pk->p_xsize + HDRSIZ,
 309:           "PKXSTART ret", "", ret);
 310:         Connodata = 0;
 311:     }
 312:     if (pk->p_msg)
 313:         pkoutput(pk);
 314:     return;
 315: }
 316: 
 317: 
 318: pkmove(p1, p2, count, flag)
 319: char *p1, *p2;
 320: int count, flag;
 321: {
 322:     register char *s, *d;
 323:     register int i;
 324: 
 325:     if (flag == B_WRITE) {
 326:         s = p2;
 327:         d = p1;
 328:     }
 329:     else {
 330:         s = p1;
 331:         d = p2;
 332:     }
 333:     for (i = 0; i < count; i++)
 334:         *d++ = *s++;
 335:     return;
 336: }
 337: 
 338: 
 339: /***
 340:  *	pkcget(fn, b, n)	get n characters from input
 341:  *	char *b;		- buffer for characters
 342:  *	int fn;			- file descriptor
 343:  *	int n;			- requested number of characters
 344:  *
 345:  *	return codes:
 346:  *		n - number of characters returned
 347:  *		0 - end of file
 348:  */
 349: 
 350: jmp_buf Getjbuf;
 351: cgalarm() { longjmp(Getjbuf, 1); }
 352: 
 353: pkcget(fn, b, n)
 354: int fn, n;
 355: register char *b;
 356: {
 357:     register int nchars, ret;
 358: 
 359:     if (setjmp(Getjbuf)) {
 360:         Ntimeout++;
 361:         PKDEBUG(4, "alarm %d\n", Ntimeout);
 362:         return(-1);
 363:     }
 364:     signal(SIGALRM, cgalarm);
 365: 
 366:     alarm(PKTIME);
 367:     for (nchars = 0; nchars < n; nchars += ret) {
 368:         ret = read(fn, b, n - nchars);
 369:         if (ret == 0) {
 370:             alarm(0);
 371:             return(-1);
 372:         }
 373:         PKASSERT(ret > 0, "PKCGET READ", "", ret);
 374:         b += ret;
 375:         sleep(1);
 376:     }
 377:     alarm(0);
 378:     return(0);
 379: }
 380: 
 381: 
 382: #ifdef PROTODEBUG
 383: generror(p, s)
 384: char *p;
 385: int s;
 386: {
 387:     int r;
 388:     if (Errorrate != 0 && (rand() % Errorrate) == 0) {
 389:         r = rand() % s;
 390: fprintf(stderr, "gen err at %o, (%o), ", r, (unsigned) *(p + r));
 391:         *(p + r) += 1;
 392:     }
 393:     return;
 394: }
 395: 
 396: 
 397: #endif

Defined functions

cgalarm defined in line 351; used 1 times
generror defined in line 383; never used
pkcget defined in line 353; used 3 times
pkdata defined in line 209; used 1 times
pkgetpack defined in line 115; never used
pkmove defined in line 318; never used
pkopen defined in line 38; used 2 times
pkrstart defined in line 248; never used
pkxstart defined in line 259; used 2 times

Defined variables

Connodata defined in line 23; used 4 times
Getjbuf defined in line 350; used 2 times
Ntimeout defined in line 24; used 2 times
pklines defined in line 32; used 2 times
pksizes defined in line 106; used 3 times
sccsid defined in line 2; never used

Defined macros

CONNODATA defined in line 25; used 1 times
GETRIES defined in line 110; used 2 times
NTIMEOUT defined in line 26; never used
PKMAXBUF defined in line 251; used 1 times
PKMAXSTMSG defined in line 20; used 2 times
PKTIME defined in line 21; used 1 times
USER defined in line 7; never used
Last modified: 1983-07-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1080
Valid CSS Valid XHTML 1.0 Strict