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

  1. /* code to allow nos to talk directly to bpqcode
  2.  *
  3.  * by paul h launspach n5faz
  4.  * (c) 1993,1994 FazCom
  5.  * 4-13-93
  6.  */
  7. /* $Id: bpq.c 1.4 1994/03/11 14:46:16 fz-phl Exp $ */
  8. /* $Log: bpq.c $
  9.  * Revision 1.4  1994/03/11  14:46:16  fz-phl
  10.  * added ifdef BPQJNOS for printf -> tprintf macro and
  11.  * for different dump and net_route calls.
  12.  *
  13.  * Revision 1.3  1994/03/11  14:36:32  Johan
  14.  * changed printf's to tprintf's
  15.  *
  16.  * Revision 1.2  1994/03/11  14:29:02  fz-phl
  17.  * added ifdef BPQSOCK and changed dump and netroute
  18.  * calls for jnos.
  19.  *
  20.  * Revision 1.1  1994/03/11  02:24:15  fz-phl
  21.  * Initial revision
  22.  *
  23.  */
  24.   
  25. #include <stdio.h>
  26. #include <dos.h>
  27. #include "global.h"
  28. #include "mbuf.h"
  29. #include "ax25.h"
  30. #include "iface.h"
  31. #include "trace.h"
  32. #include "pktdrvr.h"
  33. #include "config.h"
  34. #ifdef BPQ
  35. #include "bpq.h"
  36.   
  37. #ifdef BPQJNOS          /* change printf to tprintf for jnos etc */
  38. #define printf tprintf
  39. #endif
  40.   
  41. static int bpq_stop (struct iface *iface);
  42. static int bpq_raw (struct iface *iface, struct mbuf *bp);
  43.   
  44.   
  45. struct bpqinfo Bpqinfo = {0};
  46. extern int32 Ip_addr;
  47.   
  48. /* attach an interface to bpqcode
  49.  *
  50.  * init bpq:
  51.  * argv[0] = bpq
  52.  * argv[1] = init
  53.  * argv[2] = bpq_host intrupt vec in hex
  54.  * argv[3] = bpq_host stream number
  55.  * argv[4] = number of outgoing bpq_host sessions optional
  56.  *
  57.  * attach an iface:
  58.  * argv[0] = bpq
  59.  * argv[1] = bpq radio port number
  60.  * argv[2] = lable
  61.  * argv[3] = mtu optional
  62.  * argv[4] = callsign optional
  63.  *
  64.  */
  65. int
  66. bpq_attach(argc,argv,p)
  67. int argc;
  68. char *argv[];
  69. void *p;
  70. {
  71.     char vec;
  72.     char streem;
  73.     int port;
  74.     int users = 0;
  75.     uint16 mtu;
  76.     char hwaddr[AXALEN];
  77.     struct iface *ifp;
  78.     char *cp;
  79.     char buffer[6];
  80.     static char g8bpq[] = "G8BPQ";
  81.   
  82.     if(strncmp(argv[1],"init",strlen(argv[1])) == 0){
  83.         if(argc < 4){
  84. #ifdef BPQSOCK
  85.             printf("Usage: attach bpq init <vec> <stream> [<sessions>]\n");
  86. #else
  87.             printf("Usage: attach bpq init <vec> <stream>\n");
  88. #endif
  89.             return -1;
  90.         }
  91.         vec = htoi(argv[2]);
  92.         streem = atoi(argv[3]);
  93. #ifdef BPQSOCK
  94.         users = argc > 4 ? atoi(argv[4]) : 0;
  95. #endif
  96.         if(!Bpqinfo.vec){
  97.             /* check that bpqcode is loaded */
  98.             long vector = (long)getvect(vec);
  99.             movblock(FP_OFF(vector)-7, FP_SEG(vector),
  100.             FP_OFF(buffer),FP_SEG(buffer),strlen(g8bpq));
  101.             if(strncmp(buffer,g8bpq,strlen(g8bpq))){
  102.                 printf("Bpqcode not found !\n");
  103.                 return -1;
  104.             }
  105.             if(streem < 1 || streem > BPQMAXSTREAM){
  106.                 printf("Stream must be between 1 and %d.\n",BPQMAXSTREAM);
  107.                 return -1;
  108.             }
  109. #ifdef BPQSOCK
  110.             if(users < 0 || streem + users >= BPQMAXSTREAM){
  111.                 printf("Stream plus sessions must be less than %u.\n",
  112.                 BPQMAXSTREAM);
  113.                 return -1;
  114.             }
  115. #endif
  116.             Bpqinfo.vec = vec;
  117.             Bpqinfo.monstream = streem;
  118.             Bpqinfo.maxstream = streem + users;
  119.             Bpqinfo.window = BPQWINDOW;
  120.             Bpqinfo.minfree = bpq_int(BPQ_BUF,1,0,NULLCHAR);
  121. #ifdef BPQSOCK
  122.             Bpqinfo.rxproc = newproc("Bpq recieve",256,bpqrxp,0,NULL,NULL,0);
  123. #endif
  124.         } else {
  125.             printf("Bpq already initalized");
  126.             return -1;
  127.         }
  128.         return 0;
  129.     }
  130.   
  131.     if(!Bpqinfo.vec){
  132.         printf("Bpq must be initilized with: attach bpq init <vec> <stream>\n");
  133.         return 1;
  134.     }
  135.     port = atoi(argv[1]);
  136.     mtu = (argc >3) ? max(256,atoi(argv[3])) : Paclen;
  137.     if(port > BPQMAXPORT){
  138.         printf("Port must be between 1 and %d.\n",BPQMAXPORT);
  139.         return -1;
  140.     }
  141.     if(Bpqinfo.ports[port-1] != NULLIF){
  142.         printf("Port already used");
  143.         return -1;
  144.     }
  145.     if(if_lookup(argv[2]) != NULLIF){
  146.         printf("Interface %s already exists\n",argv[2]);
  147.         return -1;
  148.     }
  149.   
  150.   
  151.     ifp = (struct iface *)callocw(1,sizeof(struct iface));
  152.     ifp->name = strdup(argv[2]);
  153.     ifp->addr = Ip_addr;
  154.     ifp->mtu = mtu;
  155.     ifp->dev = port;
  156.     ifp->raw = bpq_raw;
  157.     ifp->stop = bpq_stop;
  158.     setencap(ifp,"AX25");
  159.     ifp->hwaddr = mallocw(AXALEN);
  160.     if(argc > 4 && setcall(hwaddr,argv[4]) == 0)
  161.         memcpy(ifp->hwaddr,hwaddr,AXALEN);
  162.     else
  163.         memcpy(ifp->hwaddr,Mycall,AXALEN);
  164.     Bpqinfo.ports[port-1] = ifp;
  165.     Bpqinfo.maxport++;
  166.     ifp->next = Ifaces;
  167.     Ifaces = ifp;
  168.     cp = if_name(ifp," tx");
  169. #ifdef BPQSOCK
  170.     ifp->txproc = newproc(cp,768,if_tx,0,ifp,NULL,0);
  171. #endif
  172.     /* tell bpqcode to send us any recieved frames */
  173.     bpq_int(BPQ_SET,Bpqinfo.monstream,0x80,NULLCHAR);
  174.     return 0;
  175. }
  176.   
  177. /* detach a bpq interface
  178.  */
  179. static int
  180. bpq_stop(iface)
  181. struct iface *iface;
  182. {
  183.     int port = iface->dev;
  184.     Bpqinfo.ports[port-1] = NULLIF;
  185.     if(--Bpqinfo.maxport == 0){
  186.         /* stop bpqcode sending us frames */
  187.         bpq_int(BPQ_SET,Bpqinfo.monstream,0,NULLCHAR);
  188.     }
  189.     return 0;
  190. }
  191.   
  192.   
  193. /* raw send
  194.  */
  195. static int
  196. bpq_raw(iface,bp)
  197. struct iface *iface;
  198. struct mbuf *bp;
  199. {
  200.   
  201.     if(iface == NULLIF || bp == NULLBUF)
  202.         return -1;
  203.   
  204.     iface->rawsndcnt++;
  205.     iface->lastsent = secclock();
  206.   
  207.     if(bp->next != NULLBUF){
  208.         /* Copy to contiguous buffer */
  209.         struct mbuf *bp1 = copy_p(bp,len_p(bp));
  210.         free_p(bp);
  211.         if((bp = bp1) == NULLBUF)
  212.             return -1;
  213.     }
  214.     Bpqinfo.sendcnt++;
  215.     bpq_int(BPQ_TX,iface->dev,bp->cnt,bp->data);
  216.     free_p(bp);
  217.     return 0;
  218. }
  219.   
  220. /* bpq raw recieve handler
  221.  * called every tick
  222.  */
  223. void
  224. bpqtimer(void)
  225. {
  226.     char port;
  227.     int txf;
  228.   
  229.   
  230.     /* no bpq ports in use  */
  231.     if(!Bpqinfo.maxport)
  232.         return;
  233.   
  234.     for(;;){
  235.         /* get a mbuf to put recieved frame in  */
  236.         if(Bpqinfo.buffer == NULLBUF)
  237.             if((Bpqinfo.buffer = alloc_mbuf(BPQSIZE +
  238.                 sizeof(struct iface))) == NULLBUF)
  239.                 return;
  240.             else
  241.                 Bpqinfo.buffer->data += sizeof(struct iface);
  242.   
  243.         /* no more frames at this time so return */
  244.         if((Bpqinfo.buffer->cnt = bpq_int(BPQ_RX,Bpqinfo.monstream,0,
  245.             Bpqinfo.buffer->data)) == 0)
  246.             return;
  247.   
  248.         port = Bpqinfo.buffer->data[2]; /* get port number from bpqheader */
  249.   
  250.         txf =port & 0x80;    /* this is a transmited frame so get another */
  251.         port &= 0x7f;        /* mask off is tx frame bit */
  252.   
  253.         /* recieved frame not on a port we want so get another */
  254.         if(port > BPQMAXPORT || Bpqinfo.ports[--port] == NULLIF)
  255.             continue;
  256.   
  257.         Bpqinfo.buffer->data += BPQHEADER;  /* move past the 5 byte */
  258.         Bpqinfo.buffer->cnt -= BPQHEADER;  /* header bpq sends us */
  259.   
  260.         /* trace any tx frames */
  261.         if(txf){
  262. #ifdef BPQJNOS
  263.             dump(Bpqinfo.ports[port],IF_TRACE_OUT,CL_AX25,Bpqinfo.buffer);
  264. #else
  265.             dump(Bpqinfo.ports[port],IF_TRACE_OUT,Bpqinfo.buffer);
  266. #endif
  267.             continue;
  268.         }
  269. #ifdef BPQJNOS
  270.         net_route(Bpqinfo.ports[port],CL_AX25,Bpqinfo.buffer);
  271. #else
  272.         net_route(Bpqinfo.ports[port],Bpqinfo.buffer);
  273. #endif
  274.         Bpqinfo.buffer = NULLBUF;
  275.         Bpqinfo.recvcnt++;
  276.     }
  277. }
  278.   
  279.   
  280. /* common interupt routine for all bpq_host calls
  281.  */
  282. uint16
  283. bpq_int(command,stream,flag,bp)
  284. char command;
  285. char stream;
  286. int flag;
  287. char *bp;
  288. {
  289.     union REGS regs;
  290.     struct SREGS sregs;
  291.     uint16 rval;
  292.   
  293.     segread(&sregs);
  294.     regs.h.ah = command;
  295.     regs.h.al =  stream;
  296.     switch(command){
  297.         case BPQ_SET:
  298.         case BPQ_CONNECT:
  299.             regs.h.ch = regs.h.dh = 0;
  300.             regs.h.dl = hibyte(flag);   /* appl mask */
  301.             regs.h.cl = lobyte(flag);   /* appl flags */
  302.             Bpqinfo.contcnt++;
  303.             break;
  304.         case BPQ_SEND:
  305.         case BPQ_TX:
  306.             regs.x.cx = flag;
  307.             sregs.es = FP_SEG(bp);
  308.             regs.x.si = FP_OFF(bp);
  309.             Bpqinfo.txcnt++;
  310.             break;
  311.         case BPQ_RECV:
  312.         case BPQ_RX:
  313.             regs.x.di = FP_OFF(bp);
  314.             sregs.es = FP_SEG(bp);
  315.             Bpqinfo.rxcnt++;
  316.             break;
  317.         case BPQ_BUF:
  318.         case BPQ_UNACK:
  319.         case BPQ_RECVQUE:
  320.             regs.h.ah = BPQ_BUF;
  321.             Bpqinfo.contcnt++;
  322.             break;
  323.         case BPQ_USERCALL:
  324.         case BPQ_PACLEN:
  325.         case BPQ_MAXFR:
  326.             regs.h.ah = BPQ_USERCALL;
  327.             sregs.es = FP_SEG(bp);
  328.             regs.x.di = FP_OFF(bp);
  329.             Bpqinfo.contcnt++;
  330.             break;
  331.         case BPQ_BEACON:
  332.             regs.x.dx = 1;
  333.             sregs.es = FP_SEG(bp);
  334.             regs.x.si = FP_OFF(bp);
  335.             regs.x.cx = flag;
  336.         case BPQ_STATE:
  337.         case BPQ_ACKSTATE:
  338.         case BPQ_TIME:
  339.             Bpqinfo.contcnt++;
  340.             break;
  341.         default:
  342.             return -1;
  343.     }
  344.     int86x(Bpqinfo.vec,®s,®s,&sregs);
  345.     switch(command){
  346.         case BPQ_USERCALL:
  347.             bp[10] = '\0';
  348.         case BPQ_TIME:
  349.             rval = regs.x.ax;
  350.             break;
  351.         case BPQ_PACLEN:
  352.         case BPQ_RECVQUE:
  353.             rval = regs.x.bx;
  354.             break;
  355.         case BPQ_RECV:
  356.         case BPQ_RX:
  357.         case BPQ_UNACK:
  358.             rval = regs.x.cx;
  359.             break;
  360.         case BPQ_BUF:
  361.             rval = regs.x.dx;
  362.             break;
  363.         case BPQ_MAXFR:
  364.             rval = max(regs.x.cx,regs.x.dx);
  365.             break;
  366.         case BPQ_STATE:
  367.             rval  = (regs.x.dx << 8) | regs.x.cx;
  368.             break;
  369.         default:
  370.             rval = 0;
  371.     }
  372.     return rval;
  373. }
  374.   
  375. #endif /* BPQ */
  376.   
  377.