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

  1. /* Low level AX.25 routines:
  2.  *  callsign conversion
  3.  *  control block management
  4.  *
  5.  * Copyright 1991 Phil Karn, KA9Q
  6.  */
  7.  
  8. /****************************************************************************
  9. *    $Id: ax25subr.c 1.2 93/07/16 11:42:47 ROOT_DOS Exp $
  10. *    15 Jul 93    1.2        GT    AX25 conditional.                                *
  11. ****************************************************************************/
  12.  
  13. #include <stdio.h>
  14. #include "global.h"
  15. #include "mbuf.h"
  16. #include "timer.h"
  17. #include "ax25.h"
  18. #include "lapb.h"
  19. #include <ctype.h>
  20. #include "ip.h"
  21. #include "config.h"
  22.  
  23. #if    AX25
  24.  
  25. struct ax25_cb *Ax25_cb;
  26.  
  27. /* Default AX.25 parameters */
  28. int32 T3init = 0;        /* No keep-alive polling */
  29. int16 Maxframe = 1;        /* Stop and wait */
  30. int16 N2 = 10;            /* 10 retries */
  31. int16 Axwindow = 2048;        /* 2K incoming text before RNR'ing */
  32. int16 Paclen = 256;        /* 256-byte I fields */
  33. int16 Pthresh = 128;        /* Send polls for packets larger than this */
  34. int32 Axirtt = 5000;        /* Initial round trip estimate, ms */
  35. int16 Axversion = V1;        /* Protocol version */
  36. int32 Blimit = 30;        /* Retransmission backoff limit */
  37.  
  38. /* Look up entry in connection table */
  39. struct ax25_cb *
  40. find_ax25(addr)
  41. register char *addr;
  42. {
  43.     register struct ax25_cb *axp;
  44.     struct ax25_cb *axlast = NULLAX25;
  45.  
  46.     /* Search list */
  47.     for(axp = Ax25_cb; axp != NULLAX25; axlast=axp,axp = axp->next){
  48.         if(addreq(axp->remote,addr)){
  49.             if(axlast != NULLAX25){
  50.                 /* Move entry to top of list to speed
  51.                  * future searches
  52.                  */
  53.                 axlast->next = axp->next;
  54.                 axp->next = Ax25_cb;
  55.                 Ax25_cb = axp;
  56.             }
  57.             return axp;
  58.         }
  59.     }
  60.     return NULLAX25;
  61. }
  62.  
  63. /* Remove entry from connection table */
  64. void
  65. del_ax25(conn)
  66. struct ax25_cb *conn;
  67. {
  68.     register struct ax25_cb *axp;
  69.     struct ax25_cb *axlast = NULLAX25;
  70.  
  71.     for(axp = Ax25_cb; axp != NULLAX25; axlast=axp,axp = axp->next){
  72.         if(axp == conn)
  73.             break;
  74.     }
  75.     if(axp == NULLAX25)
  76.         return;    /* Not found */
  77.  
  78.     /* Remove from list */
  79.     if(axlast != NULLAX25)
  80.         axlast->next = axp->next;
  81.     else
  82.         Ax25_cb = axp->next;
  83.  
  84.     /* Timers should already be stopped, but just in case... */
  85.     stop_timer(&axp->t1);
  86.     stop_timer(&axp->t3);
  87.  
  88.     /* Free allocated resources */
  89.     free_q(&axp->txq);
  90.     free_q(&axp->rxasm);
  91.     free_q(&axp->rxq);
  92.     free((char *)axp);
  93. }
  94.  
  95. /* Create an ax25 control block. Allocate a new structure, if necessary,
  96.  * and fill it with all the defaults. The caller
  97.  * is still responsible for filling in the reply address
  98.  */
  99. struct ax25_cb *
  100. cr_ax25(addr)
  101. char *addr;
  102. {
  103.     register struct ax25_cb *axp;
  104.  
  105.     if(addr == NULLCHAR)
  106.         return NULLAX25;
  107.  
  108.     if((axp = find_ax25(addr)) == NULLAX25){
  109.         /* Not already in table; create an entry
  110.          * and insert it at the head of the chain
  111.          */
  112.         axp = (struct ax25_cb *)callocw(1,sizeof(struct ax25_cb));
  113.         axp->next = Ax25_cb;
  114.         Ax25_cb = axp;
  115.     }
  116.     axp->user = -1;
  117.     axp->state = LAPB_DISCONNECTED;
  118.     axp->maxframe = Maxframe;
  119.     axp->window = Axwindow;
  120.     axp->paclen = Paclen;
  121.     axp->proto = Axversion;    /* Default, can be changed by other end */
  122.     axp->pthresh = Pthresh;
  123.     axp->n2 = N2;
  124.     axp->srt = Axirtt;
  125.     set_timer(&axp->t1,2*axp->srt);
  126.     axp->t1.func = recover;
  127.     axp->t1.arg = axp;
  128.  
  129.     set_timer(&axp->t3,T3init);
  130.     axp->t3.func = pollthem;
  131.     axp->t3.arg = axp;
  132.  
  133.     /* Always to a receive and state upcall as default */
  134.     axp->r_upcall = s_arcall;
  135.     axp->s_upcall = s_ascall;
  136.  
  137.     return axp;
  138. }
  139.  
  140. /*
  141.  * setcall - convert callsign plus substation ID of the form
  142.  * "KA9Q-0" to AX.25 (shifted) address format
  143.  *   Address extension bit is left clear
  144.  *   Return -1 on error, 0 if OK
  145.  */
  146. int
  147. setcall(out,call)
  148. char *out;
  149. char *call;
  150. {
  151.     int csize;
  152.     unsigned ssid;
  153.     register int i;
  154.     register char *dp;
  155.     char c;
  156.  
  157.     if(out == NULLCHAR || call == NULLCHAR || *call == '\0')
  158.         return -1;
  159.  
  160.     /* Find dash, if any, separating callsign from ssid
  161.      * Then compute length of callsign field and make sure
  162.      * it isn't excessive
  163.      */
  164.     dp = strchr(call,'-');
  165.     if(dp == NULLCHAR)
  166.         csize = strlen(call);
  167.     else
  168.         csize = dp - call;
  169.     if(csize > ALEN)
  170.         return -1;
  171.     /* Now find and convert ssid, if any */
  172.     if(dp != NULLCHAR){
  173.         dp++;    /* skip dash */
  174.         ssid = atoi(dp);
  175.         if(ssid > 15)
  176.             return -1;
  177.     } else
  178.         ssid = 0;
  179.     /* Copy upper-case callsign, left shifted one bit */
  180.     for(i=0;i<csize;i++){
  181.         c = *call++;
  182.         if(islower(c))
  183.             c = toupper(c);
  184.         *out++ = c << 1;
  185.     }
  186.     /* Pad with shifted spaces if necessary */
  187.     for(;i<ALEN;i++)
  188.         *out++ = ' ' << 1;
  189.     
  190.     /* Insert substation ID field and set reserved bits */
  191.     *out = 0x60 | (ssid << 1);
  192.     return 0;
  193. }
  194. int
  195. addreq(a,b)
  196. register char *a,*b;
  197. {
  198.     if(memcmp(a,b,ALEN) != 0 || ((a[ALEN] ^ b[ALEN]) & SSID) != 0)
  199.         return 0;
  200.     else
  201.         return 1;
  202. }
  203. /* Convert encoded AX.25 address to printable string */
  204. char *
  205. pax25(e,addr)
  206. char *e;
  207. char *addr;
  208. {
  209.     register int i;
  210.     char c;
  211.     char *cp;
  212.  
  213.     cp = e;
  214.     for(i=ALEN;i != 0;i--){
  215.         c = (*addr++ >> 1) & 0x7f;
  216.         if(c != ' ')
  217.             *cp++ = c;
  218.     }
  219.     if((*addr & SSID) != 0)
  220.         sprintf(cp,"-%d",(*addr >> 1) & 0xf);    /* ssid */
  221.     else
  222.         *cp = '\0';
  223.     return e;
  224. }
  225.  
  226. /* Figure out the frame type from the control field
  227.  * This is done by masking out any sequence numbers and the
  228.  * poll/final bit after determining the general class (I/S/U) of the frame
  229.  */
  230. int16
  231. ftype(control)
  232. register int control;
  233. {
  234.     if((control & 1) == 0)    /* An I-frame is an I-frame... */
  235.         return I;
  236.     if(control & 2)        /* U-frames use all except P/F bit for type */
  237.         return (int16)(uchar(control) & ~PF);
  238.     else            /* S-frames use low order 4 bits for type */
  239.         return (int16)(uchar(control) & 0xf);
  240. }
  241.  
  242. void
  243. lapb_garbage(red)
  244. int red;
  245. {
  246.     register struct ax25_cb *axp;
  247.  
  248.     for(axp=Ax25_cb;axp != NULLAX25;axp = axp->next){
  249.         mbuf_crunch(&axp->rxq);
  250.         mbuf_crunch(&axp->rxasm);
  251.     }
  252. }
  253.  
  254. #endif    /* AX25 */
  255.