home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR3 / KA9Q212.ZIP / NRS.C < prev    next >
C/C++ Source or Header  |  1993-07-16  |  6KB  |  235 lines

  1. /* This module implements the serial line framing method used by
  2.  * net/rom nodes.  This allows the net/rom software to talk to
  3.  * an actual net/rom over its serial interface, which is useful
  4.  * if we want to do packet switching for multi-line wormholes.
  5.  *
  6.  * Copyright 1989 Dan Frank, W9NK
  7.  */
  8.  
  9. /****************************************************************************
  10. *    $Id: nrs.c 1.2 93/07/16 11:48:12 ROOT_DOS Exp $
  11. *    14 Jul 93    1.2        GT    Fix warnings.                                    *
  12. ****************************************************************************/
  13.  
  14. #include <stdio.h>
  15. #include "global.h"
  16. #include "mbuf.h"
  17. #include "iface.h"
  18. #include "pktdrvr.h"
  19. #include "ax25.h"
  20. #include "nrs.h"
  21. #include "asy.h"
  22. #include "trace.h"
  23. #include "commands.h"
  24. #include "ip.h"
  25.  
  26. #if    NRS
  27.  
  28. static struct mbuf *nrs_encode __ARGS((struct mbuf *bp));
  29. static struct mbuf *nrs_decode __ARGS((int dev,char c));
  30.  
  31. /* control structures, sort of overlayed on async control blocks */
  32. struct nrs Nrs[ASY_MAX];
  33.  
  34. /* Send a raw net/rom serial frame */
  35. int
  36. nrs_raw(iface,bp)
  37. struct iface *iface;
  38. struct mbuf *bp;
  39. {
  40.     struct mbuf *bp1;
  41.  
  42.     dump(iface,IF_TRACE_OUT,CL_AX25,bp);
  43.     iface->rawsndcnt++;
  44.     iface->lastsent = secclock();
  45.  
  46.     if((bp1 = nrs_encode(bp)) == NULLBUF){
  47.         free_p(bp);
  48.         return -1;
  49.     }
  50.     return Nrs[iface->xdev].send(iface->dev,bp1);
  51. }
  52.  
  53. /* Encode a packet in net/rom serial format */
  54. static struct mbuf *
  55. nrs_encode(bp)
  56. struct mbuf *bp;
  57. {
  58.     struct mbuf *lbp;    /* Mbuf containing line-ready packet */
  59.     register char *cp;
  60.     int c;
  61.     unsigned char csum = 0;
  62.  
  63.     /* Allocate output mbuf that's twice as long as the packet.
  64.      * This is a worst-case guess (consider a packet full of STX's!)
  65.      * Add five bytes for STX, ETX, checksum, and two nulls.
  66.      */
  67.     lbp = alloc_mbuf((int16)(2*len_p(bp) + 5));
  68.     if(lbp == NULLBUF){
  69.         /* No space; drop */
  70.         free_p(bp);
  71.         return NULLBUF;
  72.     }
  73.     cp = lbp->data;
  74.  
  75.     *cp++ = STX;
  76.  
  77.     /* Copy input to output, escaping special characters */
  78.     while((c = PULLCHAR(&bp)) != -1){
  79.         switch(c){
  80.         case STX:
  81.         case ETX:
  82.         case DLE:
  83.             *cp++ = DLE;
  84.             /* notice drop through to default */
  85.         default:
  86.             *cp++ = c;
  87.         }
  88.         csum += c;
  89.     }
  90.     *cp++ = ETX;
  91.     *cp++ = csum;
  92.     *cp++ = NUL;
  93.     *cp++ = NUL;
  94.     
  95.     lbp->cnt = cp - lbp->data;
  96.     return lbp;
  97. }
  98. /* Process incoming bytes in net/rom serial format
  99.  * When a buffer is complete, return it; otherwise NULLBUF
  100.  */
  101. static struct mbuf *
  102. nrs_decode(dev,c)
  103. int dev;    /* net/rom unit number */
  104. char c;        /* Incoming character */
  105. {
  106.     struct mbuf *bp;
  107.     register struct nrs *sp;
  108.  
  109.     sp = &Nrs[dev];
  110.     switch(sp->state) {
  111.         case NRS_INTER:
  112.             if(uchar(c) == STX) {    /* look for start of frame */
  113.                 sp->state = NRS_INPACK;    /* we're in a packet */
  114.                 sp->csum = 0;                /* reset checksum */
  115.             }
  116.             return NULLBUF;
  117.         case NRS_CSUM:
  118.             bp = sp->rbp;
  119.             sp->rbp = NULLBUF;
  120.             sp->rcnt = 0;
  121.             sp->state = NRS_INTER;    /* go back to inter-packet state */
  122.             if(sp->csum == uchar(c)) {
  123.                 sp->packets++;
  124.             } else {
  125.                 free_p(bp);    /* drop packet with bad checksum */
  126.                 bp = NULLBUF;
  127.                 sp->errors++;    /* increment error count */
  128.             }
  129.             return bp;
  130.         case NRS_ESCAPE:
  131.             sp->state = NRS_INPACK;    /* end of escape */
  132.             break;            /* this will drop through to char processing */
  133.         case NRS_INPACK:
  134.             switch (uchar(c)) {
  135.             /* If we see an STX in a packet, assume that previous */
  136.             /* packet was trashed, and start a new packet */
  137.             case STX:
  138.                 free_p(sp->rbp);
  139.                 sp->rbp = NULLBUF;
  140.                 sp->rcnt = 0;
  141.                 sp->csum = 0;
  142.                 sp->errors++;
  143.                 return NULLBUF;
  144.             case ETX:
  145.                 sp->state = NRS_CSUM;    /* look for checksum */
  146.                 return NULLBUF;
  147.             case DLE:
  148.                 sp->state = NRS_ESCAPE;
  149.                 return NULLBUF;
  150.             }
  151.     }
  152.     /* If we get to here, it's with a character that's part of the packet.
  153.      * Make sure there's space for it.
  154.      */
  155.     if(sp->rbp == NULLBUF){
  156.         /* Allocate first mbuf for new packet */
  157.         if((sp->rbp1 = sp->rbp = alloc_mbuf(NRS_ALLOC)) == NULLBUF) {
  158.             sp->state = NRS_INTER;
  159.             return NULLBUF; /* No memory, drop */
  160.         }
  161.         sp->rcp = sp->rbp->data;
  162.     } else if(sp->rbp1->cnt == NRS_ALLOC){
  163.         /* Current mbuf is full; link in another */
  164.         if((sp->rbp1->next = alloc_mbuf(NRS_ALLOC)) == NULLBUF){
  165.             /* No memory, drop whole thing */
  166.             free_p(sp->rbp);
  167.             sp->rbp = NULLBUF;
  168.             sp->rcnt = 0;
  169.             sp->state = NRS_INTER;
  170.             return NULLBUF;
  171.         }
  172.         sp->rbp1 = sp->rbp1->next;
  173.         sp->rcp = sp->rbp1->data;
  174.     }
  175.     /* Store the character, increment fragment and total
  176.      * byte counts
  177.      */
  178.     *sp->rcp++ = c;
  179.     sp->rbp1->cnt++;
  180.     sp->rcnt++;
  181.     sp->csum += uchar(c);    /* add to checksum */
  182.     return NULLBUF;
  183. }
  184.  
  185. /* Process net/rom serial line I/O */
  186. void
  187. nrs_recv(dev,v1,v2)
  188. int dev;
  189. void *v1;
  190. void *v2;
  191. {
  192.     char c;
  193.     struct mbuf *bp,*nbp;
  194.     struct phdr phdr;
  195.  
  196.     /* Process any pending input */
  197.     for(;;){
  198.         c = Nrs[dev].get(Nrs[dev].iface->dev);
  199.         if((bp = nrs_decode(dev,c)) == NULLBUF)
  200.             continue;
  201.         if((nbp = pushdown(bp,sizeof(phdr))) == NULLBUF){
  202.             free_p(bp);
  203.             continue;
  204.         }
  205.         phdr.iface = Nrs[dev].iface;
  206.         phdr.type = CL_AX25;
  207.         memcpy(&nbp->data[0],(char *)&phdr,sizeof(phdr));
  208.         enqueue(&Hopper,nbp);
  209.     }
  210.  
  211. }
  212. /* donrstat:  display status of active net/rom serial interfaces */
  213. int
  214. donrstat(argc,argv,p)
  215. int argc;
  216. char *argv[];
  217. void *p;
  218. {
  219.     register struct nrs *np;
  220.     register int i;
  221.  
  222.     tprintf("Interface   RcvB  NumReceived  CSumErrors\n");
  223.  
  224.     for(i = 0, np = Nrs; i < ASY_MAX; i++, np++)
  225.         if(np->iface != NULLIF)
  226.             if(tprintf(" %8s   %4d   %10lu  %10lu\n",
  227.              np->iface->name, np->rcnt,
  228.              np->packets, np->errors) == EOF)
  229.                 break;
  230.  
  231.     return 0;
  232. }
  233.  
  234. #endif    /* NRS */
  235.