home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / uucp / pk1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  6.4 KB  |  375 lines

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