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

  1. /* User interface subroutines for AX.25
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4.  
  5. /****************************************************************************
  6. *    $Id: ax25user.c 1.3 93/07/16 11:42:52 ROOT_DOS Exp $
  7. *    15 Jul 93    1.2        GT    AX25 conditional.                                *
  8. ****************************************************************************/
  9.  
  10. #include "global.h"
  11. #include "mbuf.h"
  12. #include "timer.h"
  13. #include "iface.h"
  14. #include "lapb.h"
  15. #include "ax25.h"
  16. #include "lapb.h"
  17. #include <ctype.h>
  18. #include "ip.h"
  19. #include "config.h"
  20.  
  21. #if    AX25
  22.  
  23. /* Open an AX.25 connection */
  24. struct ax25_cb *
  25. open_ax25(iface,local,remote,mode,window,r_upcall,t_upcall,s_upcall,user)
  26. struct iface *iface;    /* Interface */
  27. char *local;        /* Local address */
  28. char *remote;        /* Remote address */
  29. int mode;        /* active/passive/server */
  30. int16 window;        /* Window size in bytes */
  31. void (*r_upcall)();    /* Receiver upcall handler */
  32. void (*t_upcall)();    /* Transmitter upcall handler */
  33. void (*s_upcall)();    /* State-change upcall handler */
  34. int user;        /* User linkage area */
  35. {
  36.     struct ax25_cb *axp;
  37.     char remtmp[AXALEN];
  38.  
  39.     if(remote == NULLCHAR){
  40.         remote = remtmp;
  41.         setcall(remote," ");
  42.     }
  43.     if((axp = find_ax25(remote)) != NULLAX25 && axp->state != LAPB_DISCONNECTED)
  44.         return NULLAX25;    /* Only one to a customer */
  45.     if(axp == NULLAX25 && (axp = cr_ax25(remote)) == NULLAX25)
  46.         return NULLAX25;
  47.     memcpy(axp->remote,remote,AXALEN);
  48.     memcpy(axp->local,local,AXALEN);
  49.     axp->iface = iface;
  50.     axp->window = window;
  51.     axp->r_upcall = r_upcall;
  52.     axp->t_upcall = t_upcall;
  53.     axp->s_upcall = s_upcall;
  54.     axp->user = user;
  55.  
  56.     switch(mode){
  57.     case AX_SERVER:
  58.         axp->flags.clone = 1;
  59.     case AX_PASSIVE:    /* Note fall-thru */
  60.         axp->state = LAPB_LISTEN;
  61.         return axp;
  62.     case AX_ACTIVE:
  63.         break;
  64.     }    
  65.     switch(axp->state){
  66.     case LAPB_DISCONNECTED:
  67.         est_link(axp);
  68.         lapbstate(axp,LAPB_SETUP);
  69.         break;
  70.     case LAPB_SETUP:
  71.         free_q(&axp->txq);
  72.         break;
  73.     case LAPB_DISCPENDING:    /* Ignore */
  74.         break;
  75.     case LAPB_RECOVERY:
  76.     case LAPB_CONNECTED:
  77.         free_q(&axp->txq);
  78.         est_link(axp);
  79.         lapbstate(axp,LAPB_SETUP);
  80.         break;
  81.     }
  82.     return axp;
  83. }
  84.  
  85. /* Send data on an AX.25 connection. Caller provides optional PID. If
  86.  * a PID is provided, then operate in stream mode, i.e., a large packet
  87.  * is automatically packetized into a series of paclen-sized data fields.
  88.  *
  89.  * If pid == -1, it is assumed the packet (which may actually be a queue
  90.  * of distinct packets) already has a PID on the front and it is passed
  91.  * through directly even if it is very large.
  92.  */
  93. int
  94. send_ax25(axp,bp,pid)
  95. struct ax25_cb *axp;
  96. struct mbuf *bp;
  97. int pid;
  98. {
  99.     struct mbuf *bp1;
  100.     int16 offset,len,size;
  101.  
  102.     if(axp == NULLAX25 || bp == NULLBUF)
  103.         return -1;
  104.  
  105.     if(pid != -1){
  106.         offset = 0;
  107.         len = len_p(bp);
  108.         /* It is important that all the pushdowns be done before
  109.          * any part of the original packet is freed.
  110.          * Otherwise the pushdown might erroneously overwrite
  111.          * a part of the packet that had been duped and freed.
  112.          */
  113.         while(len != 0){
  114.             size = min(len,axp->paclen);
  115.             dup_p(&bp1,bp,offset,size);
  116.             len -= size;
  117.             offset += size;
  118.             bp1 = pushdown(bp1,1);
  119.             bp1->data[0] = pid;
  120.             enqueue(&axp->txq,bp1);
  121.         }
  122.         free_p(bp);
  123.     } else {
  124.         enqueue(&axp->txq,bp);
  125.     }
  126.     return lapb_output(axp);
  127. }
  128.  
  129. /* Receive incoming data on an AX.25 connection */
  130. struct mbuf *
  131. recv_ax25(axp,cnt)
  132. struct ax25_cb *axp;
  133. int16 cnt;
  134. {
  135.     struct mbuf *bp;
  136.  
  137.     if(axp->rxq == NULLBUF)
  138.         return NULLBUF;
  139.  
  140.     if(cnt == 0){
  141.         /* This means we want it all */
  142.         bp = axp->rxq;
  143.         axp->rxq = NULLBUF;
  144.     } else {
  145.         bp = ambufw(cnt);
  146.         bp->cnt = pullup(&axp->rxq,bp->data,cnt);
  147.     }
  148.     /* If this has un-busied us, send a RR to reopen the window */
  149.     if(len_p(axp->rxq) < axp->window
  150.      && (len_p(axp->rxq) + bp->cnt) >= axp->window)
  151.         sendctl(axp,LAPB_RESPONSE,RR);
  152.  
  153.     return bp;
  154. }
  155.  
  156. /* Close an AX.25 connection */
  157. int disc_ax25(struct ax25_cb *axp)
  158. {
  159.     if(axp == NULLAX25)
  160.         return -1;
  161.     switch(axp->state){
  162.     case LAPB_DISCONNECTED:
  163.         break;        /* Ignored */
  164.     case LAPB_LISTEN:
  165.         del_ax25(axp);
  166.         break;
  167.     case LAPB_DISCPENDING:
  168.         lapbstate(axp,LAPB_DISCONNECTED);
  169.         break;
  170.     case LAPB_CONNECTED:
  171.     case LAPB_RECOVERY:
  172.         free_q(&axp->txq);
  173.         axp->retries = 0;
  174.         sendctl(axp,LAPB_COMMAND,DISC|PF);
  175.         stop_timer(&axp->t3);
  176.         start_timer(&axp->t1);
  177.         lapbstate(axp,LAPB_DISCPENDING);
  178.         break;
  179.     }
  180.     return 0;
  181. }
  182.  
  183. /* Verify that axp points to a valid ax25 control block */
  184. int ax25val(struct ax25_cb *axp)
  185. {
  186.     register struct ax25_cb *axp1;
  187.  
  188.     if(axp == NULLAX25)
  189.         return 0;    /* Null pointer can't be valid */
  190.     for(axp1 = Ax25_cb;axp1 != NULLAX25; axp1 = axp1->next)
  191.         if(axp1 == axp)
  192.             return 1;
  193.     return 0;
  194. }
  195.  
  196. /* Force a retransmission */
  197. int kick_ax25(struct ax25_cb *axp)
  198. {
  199.     if(!ax25val(axp))
  200.         return -1;
  201.     recover(axp);
  202.     return 0;
  203. }
  204.  
  205. /* Abruptly terminate an AX.25 connection */
  206. int
  207. reset_ax25(axp)
  208. struct ax25_cb *axp;
  209. {
  210.     void (*upcall)();
  211.  
  212.     if(axp == NULLAX25)
  213.         return -1;
  214.     upcall = axp->s_upcall;
  215.     lapbstate(axp,LAPB_DISCONNECTED);
  216.     /* Clean up if the standard upcall isn't in use */
  217.     if(upcall != s_ascall)
  218.         del_ax25(axp);
  219.     return 0;
  220. }
  221.  
  222. #endif    /* AX25 */
  223.