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

  1. /* Routines for AX.25 encapsulation in KISS TNC
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Modified by G1EMM 19/11/90 to support multi-port KISS mode.
  5.  */
  6.  /* Mods by G1EMM */
  7.   
  8. #include "global.h"
  9. #include "mbuf.h"
  10. #include "iface.h"
  11. #include "kiss.h"
  12. #include "devparam.h"
  13. #include "slip.h"
  14. #include "asy.h"
  15. #include "ax25.h"
  16. #include "pktdrvr.h"
  17.   
  18. /* Send raw data packet on KISS TNC */
  19. int
  20. kiss_raw(iface,data)
  21. struct iface *iface;
  22. struct mbuf *data;
  23. {
  24.     register struct mbuf *bp;
  25.   
  26.     /* Put type field for KISS TNC on front */
  27.     if((bp = pushdown(data,1)) == NULLBUF){
  28.         free_p(data);
  29.         return -1;
  30.     }
  31.     bp->data[0] = PARAM_DATA;
  32.     bp->data[0] |= (iface->port << 4);
  33.     if(iface->port){
  34.         iface->rawsndcnt++;
  35.         iface->lastsent = secclock();
  36.     }
  37.     /* slip_raw also increments sndrawcnt */
  38.     slip_raw(Slip[iface->xdev].iface,bp);
  39.     return 0;
  40. }
  41.   
  42. /* Process incoming KISS TNC frame */
  43. void
  44. kiss_recv(iface,bp)
  45. struct iface *iface;
  46. struct mbuf *bp;
  47. {
  48.     char kisstype;
  49.     struct iface *kissif;
  50.     int port;
  51.   
  52.     kisstype = PULLCHAR(&bp);
  53.     port = kisstype >> 4;
  54.   
  55. #ifdef notdef
  56.     if(iface->xdev) {
  57.         if((kissif = Slip[iface->xdev].kiss[port]) == NULLIF && port != 0) {
  58.             free_p(bp);
  59.             return;
  60.         }
  61.     } else {
  62.         kissif = iface;
  63.     }
  64. #endif
  65.   
  66.     if((kissif = Slip[iface->xdev].kiss[port]) == NULLIF) {
  67.         free_p(bp);
  68.         return;
  69.     }
  70.   
  71.     switch(kisstype & 0xf){
  72.         case PARAM_DATA:
  73.             ax_recv(kissif,bp);
  74.             break;
  75.         default:
  76.             free_p(bp);
  77.             break;
  78.     }
  79. }
  80. /* Perform device control on KISS TNC by sending control messages */
  81. int32
  82. kiss_ioctl(iface,cmd,set,val)
  83. struct iface *iface;
  84. int cmd;
  85. int set;
  86. int32 val;
  87. {
  88.     struct mbuf *hbp;
  89.     char *cp;
  90.     int32 rval = 0L;
  91.   
  92.     /* At present, only certain parameters are supported by
  93.      * stock KISS TNCs. As additional params are implemented,
  94.      * this will have to be edited
  95.      */
  96.     switch(cmd){
  97.         case PARAM_RETURN:
  98.         case PARAM_RETURN2:
  99.             set = 1;    /* Note fall-thru */
  100.         case PARAM_TXDELAY:
  101.         case PARAM_PERSIST:
  102.         case PARAM_SLOTTIME:
  103.         case PARAM_TXTAIL:
  104.         case PARAM_FULLDUP:
  105.         case PARAM_HW:
  106.             if(!set){
  107.                 rval = -1;  /* Can't read back */
  108.                 break;
  109.             }
  110.         /* Allocate space for cmd and arg */
  111.             if((hbp = alloc_mbuf(2)) == NULLBUF){
  112.                 free_p(hbp);
  113.                 rval = -1;
  114.                 break;
  115.             }
  116.             cp = hbp->data;
  117.             *cp++ = cmd;
  118.             *cp = val;
  119.             hbp->cnt = 2;
  120.             if(hbp->data[0] != (char) PARAM_RETURN)
  121.                 hbp->data[0] |= (iface->port << 4);
  122.             if(iface->port){
  123.                 iface->rawsndcnt++;
  124.                 iface->lastsent = secclock();
  125.             }
  126.         /* Even more "raw" than kiss_raw */
  127.             slip_raw(Slip[iface->xdev].iface,hbp);
  128. /*      slip_raw(iface,hbp);    / * Even more "raw" than kiss_raw */
  129.             rval = val;
  130.             break;
  131.         case PARAM_SPEED:   /* These go to the local asy driver */
  132.         case PARAM_DTR:
  133.         case PARAM_RTS:
  134.         case PARAM_UP:
  135.         case PARAM_DOWN:
  136.             rval = asy_ioctl(iface,cmd,set,val);
  137.             break;
  138.         default:        /* Not implemented */
  139.             rval = -1;
  140.             break;
  141.     }
  142.     return rval;
  143. }
  144.   
  145. #ifdef KISS
  146.   
  147. int
  148. kiss_stop(iface)
  149. struct iface *iface;
  150. {
  151.     Slip[iface->xdev].kiss[iface->port] = NULLIF;
  152.     return 0;
  153. }
  154.   
  155. /* Attach a kiss interface to an existing asy interface in the system
  156.  * argv[0]: hardware type, must be "kiss"
  157.  * argv[1]: master interface, e.g., "ax4"
  158.  * argv[2]: kiss port, e.g., "4"
  159.  * argv[3]: interface label, e.g., "ax0"
  160.  * argv[4]: maximum transmission unit, bytes
  161.  */
  162. int
  163. kiss_attach(argc,argv,p)
  164. int argc;
  165. char *argv[];
  166. void *p;
  167. {
  168.     struct iface *if_asy, *if_kiss;
  169.     int port;
  170.   
  171.     if((if_asy = if_lookup(argv[1])) == NULLIF){
  172.         tprintf("Interface %s does not exist\n",argv[1]);
  173.         return -1;
  174.     }
  175.   
  176.     /* Check for ASY type interface ! - WG7J */
  177.     if(if_asy->type != CL_AX25) {
  178.         tprintf("Multidrop KISS not allowed in interface: %s\n",argv[1]);
  179.         return -1;
  180.     }
  181.   
  182.     if(if_lookup(argv[3]) != NULLIF){
  183.         tprintf("Interface %s already exists\n",argv[4]);
  184.         return -1;
  185.     }
  186.   
  187.     if((port = atoi(argv[2])) == 0){
  188.         tprintf("Port 0 automatically assigned to interface %s\n",argv[1]);
  189.         return -1;
  190.     }
  191.   
  192.     if(port < 1 || port > 15){
  193.         tputs("Ports 1 to 15 only\n");
  194.         return -1;
  195.     }
  196.   
  197.     if(Slip[if_asy->xdev].kiss[port] != NULLIF){
  198.         tprintf("Port %d already allocated on interface %s\n", port, argv[1]);
  199.         return -1;
  200.     }
  201.     /* Create interface structure and fill in details */
  202.     if_kiss = (struct iface *)callocw(1,sizeof(struct iface));
  203.     if_kiss->addr = if_asy->addr;
  204.     if_kiss->name = strdup(argv[3]);
  205.   
  206.     if(argc >= 5){
  207.         if_kiss->mtu = atoi(argv[4]);
  208.     } else {
  209.         if_kiss->mtu = if_asy->mtu;
  210.     }
  211.   
  212.     if_kiss->dev = if_asy->dev;
  213.     if_kiss->stop = kiss_stop;
  214.     setencap(if_kiss,"AX25");
  215.     if_kiss->ioctl = kiss_ioctl;
  216.     if_kiss->raw = kiss_raw;
  217.     if(if_kiss->hwaddr == NULLCHAR)
  218.         if_kiss->hwaddr = mallocw(AXALEN);
  219.     memcpy(if_kiss->hwaddr,Mycall,AXALEN);
  220.     if_kiss->xdev = if_asy->xdev;
  221.     if_kiss->next = Ifaces;
  222.     Ifaces = if_kiss;
  223.     if_kiss->port = port;
  224.     Slip[if_kiss->xdev].kiss[if_kiss->port] = if_kiss;
  225.     return 0;
  226. }
  227.   
  228. #endif /* KISS */
  229.