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

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