home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3 / hamradioversion3.0examsandprograms1992.iso / packet / n17jsrc / asy.c < prev    next >
C/C++ Source or Header  |  1991-10-18  |  7KB  |  305 lines

  1. /* Generic serial line interface routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4.  /* Mods by G1EMM */
  5. #include <stdio.h>
  6. #include "global.h"
  7. #include "config.h"
  8. #include "proc.h"
  9. #include "iface.h"
  10. #include "netuser.h"
  11. #include "slhc.h"
  12. #include "8250.h"
  13. #include "asy.h"
  14. #include "ax25.h"
  15. #include "kiss.h"
  16. #include "pktdrvr.h"
  17. #include "ppp.h"
  18. #include "slip.h"
  19. #include "nrs.h"
  20. #include "commands.h"
  21. #include "mbuf.h"
  22.  
  23. static int asy_detach __ARGS((struct iface *ifp));
  24.  
  25.  
  26. /* Attach a serial interface to the system
  27.  * argv[0]: hardware type, must be "asy"
  28.  * argv[1]: I/O address, e.g., "0x3f8"
  29.  * argv[2]: vector, e.g., "4"
  30.  * argv[3]: mode, may be:
  31.  *        "slip" (point-to-point SLIP)
  32.  *        "ax25" (AX.25 frame format in SLIP for raw TNC)
  33.  *        "nrs" (NET/ROM format serial protocol)
  34.  *        "ppp" (Point-to-Point Protocol, RFC1171, RFC1172)
  35.  * argv[4]: interface label, e.g., "sl0"
  36.  * argv[5]: receiver ring buffer size in bytes
  37.  * argv[6]: maximum transmission unit, bytes
  38.  * argv[7]: interface speed, e.g, "9600"
  39.  * argv[8]: optional flags,
  40.  *        'c' for cts flow control;
  41.  *        'r' for RLSD (RS232 pin 8, CD) physical link up/down;
  42.  *        'v' for Van Jacobson TCP header compression (SLIP only,
  43.  *            use ppp command for VJ compression with PPP);
  44.  */
  45. int
  46. asy_attach(argc,argv,p)
  47. int argc;
  48. char *argv[];
  49. void *p;
  50. {
  51.     register struct iface *ifp;
  52.     struct asy *asyp;
  53.     char *ifn;
  54.     int dev;
  55.     int xdev;
  56.     int trigchar = -1;
  57.     char cts = FALSE;
  58.     char rlsd = FALSE;
  59. #if    defined(SLIP) || defined(AX25)
  60.     struct slip *sp;
  61. #endif
  62. #ifdef    NRS
  63.     struct nrs *np;
  64. #endif
  65.  
  66.     if(if_lookup(argv[4]) != NULLIF){
  67.         tprintf("Interface %s already exists\n",argv[4]);
  68.         return -1;
  69.     }
  70.     /* Find unused asy control block */
  71.     for(dev=0;dev < ASY_MAX;dev++){
  72.         asyp = &Asy[dev];
  73.         if(asyp->iface == NULLIF)
  74.             break;
  75.     }
  76.     if(dev >= ASY_MAX){
  77.         tprintf("Too many async controllers\n");
  78.         return -1;
  79.     }
  80.  
  81.     /* Create interface structure and fill in details */
  82.     ifp = (struct iface *)callocw(1,sizeof(struct iface));
  83.     ifp->addr = Ip_addr;
  84.     ifp->name = strdup(argv[4]);
  85.     ifp->mtu = atoi(argv[6]);
  86.     ifp->dev = dev;
  87.     ifp->stop = asy_detach;
  88.  
  89. #ifdef    SLIP
  90.     if(stricmp(argv[3],"SLIP") == 0) {
  91.         for(xdev = 0;xdev < SLIP_MAX;xdev++){
  92.             sp = &Slip[xdev];
  93.             if(sp->iface == NULLIF)
  94.                 break;
  95.         }
  96.         if(xdev >= SLIP_MAX) {
  97.             tprintf("Too many slip devices\n");
  98.             free(ifp->name);
  99.             free((char *)ifp);
  100.             return -1;
  101.         }
  102.         setencap(ifp,"SLIP");
  103.         ifp->ioctl = asy_ioctl;
  104.         ifp->raw = slip_raw;
  105.         ifp->status = slip_status;
  106.         ifp->flags = 0;
  107.         ifp->xdev = xdev;
  108.  
  109.         sp->iface = ifp;
  110.         sp->send = asy_send;
  111.         sp->get = get_asy;
  112.         sp->type = CL_SERIAL_LINE;
  113.         trigchar = FR_END;
  114. #ifdef VJCOMPRESS
  115.         if((argc > 8) && (strchr(argv[8],'v') != NULLCHAR)) {
  116.             sp->escaped |= SLIP_VJCOMPR;
  117.             sp->slcomp = slhc_init(16,16);
  118.         }
  119. #else
  120.         sp->slcomp = NULL;
  121. #endif    /* VJCOMPRESS */
  122.         ifp->rxproc = newproc( ifn = if_name( ifp, " rx" ),
  123.             256,asy_rx,xdev,NULL,NULL,0);
  124.         free(ifn);
  125.     } else
  126. #endif
  127. #ifdef    AX25
  128.     if(stricmp(argv[3],"AX25") == 0) {
  129.         /* Set up a SLIP link to use AX.25 */
  130.         for(xdev = 0;xdev < SLIP_MAX;xdev++){
  131.             sp = &Slip[xdev];
  132.             if(sp->iface == NULLIF)
  133.                 break;
  134.         }
  135.         if(xdev >= SLIP_MAX) {
  136.             tprintf("Too many ax25 devices\n");
  137.             free(ifp->name);
  138.             free((char *)ifp);
  139.             return -1;
  140.         }
  141.         setencap(ifp,"AX25");
  142.         ifp->ioctl = kiss_ioctl;
  143.         ifp->raw = kiss_raw;
  144.         ifp->status = slip_status;
  145.         ifp->port = 0;            /* G1EMM */
  146.         if(ifp->hwaddr == NULLCHAR)
  147.             ifp->hwaddr = mallocw(AXALEN);
  148.         memcpy(ifp->hwaddr,Mycall,AXALEN);
  149.         ifp->xdev = xdev;
  150.  
  151.         sp->iface = ifp;
  152.         sp->send = asy_send;
  153.         sp->kiss[ifp->port] = ifp;    /* G1EMM */
  154.         sp->get = get_asy;
  155.         sp->type = CL_KISS;
  156.         trigchar = FR_END;
  157.         ifp->rxproc = newproc( ifn = if_name( ifp, " rx" ),
  158.             256,asy_rx,xdev,NULL,NULL,0);
  159.         free(ifn);
  160.     } else
  161. #endif
  162. #ifdef    NRS
  163.     if(stricmp(argv[3],"NRS") == 0) {
  164.         /* Set up a net/rom serial iface */
  165.         for(xdev = 0;xdev < SLIP_MAX;xdev++){
  166.             np = &Nrs[xdev];
  167.             if(np->iface == NULLIF)
  168.                 break;
  169.         }
  170.         if(xdev >= SLIP_MAX) {
  171.             tprintf("Too many nrs devices\n");
  172.             free(ifp->name);
  173.             free((char *)ifp);
  174.             return -1;
  175.         }
  176.         /* no call supplied? */
  177.         setencap(ifp,"AX25");
  178.         ifp->ioctl = asy_ioctl;
  179.         ifp->raw = nrs_raw;
  180. /*        ifp->status = nrs_status; */
  181.         ifp->hwaddr = mallocw(AXALEN);
  182.         memcpy(ifp->hwaddr,Mycall,AXALEN);
  183.         ifp->xdev = xdev;
  184.         np->iface = ifp;
  185.         np->send = asy_send;
  186.         np->get = get_asy;
  187.         trigchar = ETX;
  188.         ifp->rxproc = newproc( ifn = if_name( ifp, " nrs" ),
  189.             256,nrs_recv,xdev,NULL,NULL,0);
  190.         free(ifn);
  191.     } else
  192. #endif
  193. #ifdef    PPP
  194.     if(stricmp(argv[3],"PPP") == 0) {
  195.         /* Setup for Point-to-Point Protocol */
  196.  
  197.         trigchar = HDLC_FLAG;
  198.         setencap(ifp,"PPP");
  199.         ifp->ioctl = asy_ioctl;
  200.         ifp->flags = FALSE;
  201.         /* Initialize parameters for various PPP phases/protocols */
  202.         if((argc > 8) && (strchr(argv[8],'r') != NULLCHAR))
  203.             rlsd = TRUE;
  204.         if (ppp_init(ifp) != 0) {
  205.             tprintf("Cannot allocate PPP control block\n");
  206.             free(ifp->name);
  207.             free((char *)ifp);
  208.             return -1;
  209.         }
  210.     } else
  211. #endif /* PPP */
  212.     {
  213.         tprintf("Mode %s unknown for interface %s\n",
  214.             argv[3],argv[4]);
  215.         free(ifp->name);
  216.         free((char *)ifp);
  217.         return -1;
  218.     }
  219.  
  220.     /* Link in the interface */
  221.     ifp->next = Ifaces;
  222.     Ifaces = ifp;
  223.     if((argc > 8) && (strchr(argv[8],'c') != NULLCHAR))
  224.         cts = TRUE;
  225.     asy_init(dev,ifp,argv[1],argv[2],(int16)atol(argv[5]),
  226.         trigchar,cts,rlsd,(int16)atol(argv[7]));
  227.     return 0;
  228. }
  229.  
  230. static int
  231. asy_detach(ifp)
  232. struct iface *ifp;
  233. {
  234.     asy_stop(ifp);
  235.  
  236. #ifdef    SLIP
  237.     if(stricmp(ifp->iftype->name,"SLIP") == 0) {
  238.         Slip[ifp->xdev].iface = NULLIF;
  239. #ifdef VJCOMPRESS
  240.         slhc_free( Slip[ifp->xdev].slcomp );
  241.         Slip[ifp->xdev].slcomp = NULL;
  242. #endif    /* VJCOMPRESS */
  243.     } else
  244. #endif
  245. #ifdef    AX25
  246.     if(stricmp(ifp->iftype->name,"AX25") == 0
  247.      && Slip[ifp->xdev].iface == ifp ) {
  248.         Slip[ifp->xdev].iface = NULLIF;
  249.     } else
  250. #endif
  251. #ifdef    NRS
  252.     if(stricmp(ifp->iftype->name,"AX25") == 0
  253.      && Nrs[ifp->xdev].iface == ifp ) {
  254.         Nrs[ifp->xdev].iface = NULLIF;
  255.     } else
  256. #endif
  257. #ifdef    PPP
  258.     if(stricmp(ifp->iftype->name,"PPP") == 0) {
  259.         ppp_free(ifp);
  260.     } else
  261. #endif
  262.     {
  263.         tprintf("invalid type %s for interface %s\n",
  264.             ifp->iftype->name, ifp->name);
  265.         free(ifp->name);
  266.         free(ifp);
  267.         return -1;
  268.     }
  269.     return 0;
  270. }
  271.  
  272. /* Execute user comm command */
  273. int
  274. doasycomm(argc,argv,p)
  275. int argc;
  276. char *argv[];
  277. void *p;
  278. {
  279.     register struct iface *ifp;
  280.     register struct asy *ap;
  281.     int dev;
  282.     int c;
  283.     struct mbuf *bp;
  284.     
  285.     if((ifp = if_lookup(argv[1])) == NULLIF){
  286.         tprintf("Interface %s unknown\n",argv[1]);
  287.         return 1;
  288.     }
  289.     for(dev=0,ap = Asy;dev < ASY_MAX;dev++,ap++)
  290.         if(ap->iface == ifp)
  291.             break;
  292.     if(dev == ASY_MAX){
  293.         tprintf("Interface %s not asy port\n",argv[1]);
  294.         return 1;
  295.     }
  296.  
  297.     bp = pushdown(NULLBUF,strlen(argv[2]) + 2 );
  298.     strcpy(bp->data,argv[2]);
  299.     strcat(bp->data,"\r");
  300.     bp->cnt = strlen(argv[2]) + 1;
  301.     asy_send(dev,bp);
  302.     return 0;
  303. }
  304.  
  305.