home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / ASY.C < prev    next >
C/C++ Source or Header  |  1994-08-26  |  10KB  |  349 lines

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