home *** CD-ROM | disk | FTP | other *** search
- /*
- ax25subr.c -- General AX.25 subroutines
-
- Poor Man's Packet (PMP)
- Copyright (c) 1991 by Andrew C. Payne All Rights Reserved.
-
- Permission to use, copy, modify, and distribute this software and its
- documentation without fee for NON-COMMERCIAL AMATEUR RADIO USE ONLY is hereby
- granted, provided that the above copyright notice appear in all copies.
- The author makes no representations about the suitability of this software
- for any purpose. It is provided "as is" without express or implied warranty.
-
- Andrew C. Payne
- */
- /* ----- Includes ------ */
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #include <alloc.h>
- #include <bios.h>
- #include <mem.h>
- #include <ctype.h>
- #include "pmp.h"
-
- /* ----- Address Manipulation ----- */
-
- /* SetAX25Addr(addr,s)
- Given a string s in the form 'N8KEI-3', converts to ax25_addr format.
- Returns TRUE if error.
- */
- int SetAX25Addr(struct ax25_addr *a, char *s)
- {
- struct ax25_addr t;
- int i;
-
- /* check for empty string */
- if(*s == NULL)
- return TRUE;
-
- for(i=0; i<MAXCLEN; i++) {
- if(*s && *s != '-' && !isspace(*s))
- t.call[i] = toupper(*s++) << 1;
- else
- t.call[i] = ' ' << 1; /* pad w/ spaces */
- }
-
- if(i > MAXCLEN && *s && *s != '-') /* call too long */
- return TRUE;
-
- if(*s == '-') {
- i = atoi(s+1);
- if(i > 15)
- return TRUE; /* invalid ssid */
- } else
- i = 0; /* default */
-
- t.ssid = 0x60 | (i << 1);
-
- /* all is well, copy it into 'a' */
- memcpy(a,&t,sizeof(struct ax25_addr));
- return FALSE;
- }
-
- /* GetAX25Addr(addr)
- Given a pointer to an ax25_addr record, returns an ASCII string of
- the address in human readable form: 'N8KEI-3'
- */
- char *GetAX25Addr(struct ax25_addr *a)
- {
- static char s[MAXCLEN+5];
- char *p;
- char c;
- int i;
-
- /* translate callsign */
- p = s;
- for(i=0; i<MAXCLEN; i++) {
- c = (a->call[i] >> 1) & 0x7f;
- if(c == ' ')
- break;
- else
- *p++ = c;
- }
-
- /* copy ssid if non-zero */
- i = (a->ssid >> 1) & 0x0f;
- if(i)
- sprintf(p,"-%d",i);
- else
- *p = '\0';
-
- return s; /* return pointer to string */
- }
-
- /* CompAX25Addr(a1,a2)
- Compares two AX.25 addresses. Returns TRUE if they are not equal.
- */
- int CompAX25Addr(struct ax25_addr *a1, struct ax25_addr *a2)
- {
- /* compare the calls */
- if(memcmp(a1->call,a2->call,sizeof(struct ax25_addr)-1))
- return TRUE;
-
- /* compare the SSIDs */
- return (a1->ssid & 0x1e) != (a2->ssid & 0x1e);
- }
-
- /* ----- Address/Path Parsing ----- */
-
- /* SetAX25Path(s)
- Given a path string in the form "KC3BQ-3 v W2CXM-1,WB2EMS-1",
- and a pointer to a ax25_packet structure, sets the destination
- address records.
-
- Returns TRUE if successful, FALSE if error.
- */
- int SetAX25Path(char *s, struct ax25_packet *a)
- {
- char *p;
- char t[80];
- int i;
-
- /* extract the destination callsign */
- p = extract(s,t);
- if(SetAX25Addr(&a->dest,t))
- return FALSE;
-
- /* Is there a digi path? */
- a->ndigis = i = 0;
- if(*p == '\0')
- return TRUE; /* end of string, no digi path */
-
- p = extract(p,t);
- if(*t != 'v') /* expect VIA */
- return FALSE;
-
- /* extract digi path */
- while(*p && i < MAXDIGIS) {
- p = extract(p,t);
- if(SetAX25Addr(a->digis+i,t))
- return FALSE;
-
- i++;
- }
-
- a->ndigis = i;
- return i < MAXDIGIS;
- }
-
- /* GetAX25Path(*packet)
- Given a pointer to a level 2 packet, parses, and returns a pointer to
- a human readable string in the form:
-
- "N8KEI [via WB2EMS]"
- */
- char *GetAX25Path(struct ax25_packet *p)
- {
- static char s[80];
- int i;
- struct ax25_addr *ad;
-
- /* copy in the destination call */
- strcpy(s,GetAX25Addr(&p->dest));
-
- /* copy in the digi path */
- if(i = p->ndigis) {
- strcat(s," [via ");
- strcat(s,GetAX25Addr(p->digis));
- ad = p->digis + 1;
- while(i > 1) {
- strcat(s,",");
- strcat(s,GetAX25Addr(ad++));
- i--;
- }
- strcat(s,"]");
- }
-
- return s;
- }
-
- /* ----- Reverse Path ----- */
-
- /* ReversePath(p1,p2)
- Given two AX.25 Level 2 packets, constructs the path in p1 as the
- reverse of the path in p2.
- */
- void ReversePath(struct ax25_packet *p1, struct ax25_packet *p2)
- {
- int i;
-
- memcpy(&p1->dest,&p2->source,sizeof(struct ax25_addr));
- memcpy(&p1->source,&p2->dest,sizeof(struct ax25_addr));
-
- if(p1->ndigis = p2->ndigis) {
- for(i=0; i<p2->ndigis; i++)
- memcpy(p1->digis+i,p2->digis+(p2->ndigis - i - 1),
- sizeof(struct ax25_addr));
- }
- }
-
- /* ----- AX25 Packet Transmission ----- */
-
- /* FrameType(control)
- Given the control byte, returns the type of the frame.
- */
- int FrameType(byte c)
- {
- if(!(c & 1))
- return I; /* Information */
-
- if(c & 2)
- return c & ~PF; /* U frames, strip PF */
- else
- return c & 0xf; /* S frames */
- }
-
- /* CmdResp(p)
- Given a pointer to a level1 packet, returns the command/response
- type.
- */
- int CmdResp(struct ax25_level1 *p)
- {
- byte *d;
-
- d = p->data;
-
- /* figure out control/response bits */
- if(d[MAXCLEN + sizeof(struct ax25_addr)] & 0x80) {
- if(d[MAXCLEN] & 0x80)
- return UNKNOWN;
- else
- return RESPONSE;
- } else {
- if(d[MAXCLEN] & 0x80)
- return COMMAND;
- else
- return UNKNOWN;
- }
- }
-
- /* ----- Beacon ----- */
-
- /* SendBeacon()
- Sends the beacon message in 'btext' to the destination/path in
- 'baddr'.
- */
- void SendBeacon(void)
- {
- struct ax25_packet *p;
-
- /* allocate an ax25_packet structure */
- if((p = malloc(sizeof(struct ax25_packet) + strlen(btext))) == NULL)
- OutOfMemory();
-
- /* build UI packet with beacon text */
- memcpy(&p->source, &MyCall, sizeof(struct ax25_addr));
- p->pid = PID_TEXT;
- p->cont = UI;
- SetAX25Path(baddr, p);
- strcpy(p->data, btext);
- p->dlen = strlen(btext);
-
- SendAX25(p);
- free(p);
- }
-
- /* StartBeacon()
- If 'BeaconInt' is non-zero, starts the beacon timing interval.
- */
- void StartBeacon(void)
- {
- if(BeaconInt)
- BeaconEnd = BiosTime() + (BIOSSEC * BeaconInt);
- else
- BeaconEnd = 0;
- }
-
- /* ----- Send Welcome message ----- */
-
- /* SendWelcome()
- Sends the welcome message specified in CTEXT to incoming connects.
- */
- void SendWelcome(void)
- {
- int i;
-
- if(nctexts) {
- for(i=0; i<nctexts; i++)
- LinkSend(ctext[i],strlen(ctext[i]));
- }
- }