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

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