From da023ae4c9de7b6f92f84b2f8855d2589b925bff Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Wed, 8 Nov 2023 12:00:49 -0500 Subject: [PATCH 1/7] Reformat and add options processing - Run the code through clang-format - Teach axdigi about the following options: - --enable-beacon (-b) - --beacon-dest (-d) - --beacon-text (-t) - --beacon-interval (-i) --- axdigi2018.c | 740 +++++++++++++++++++++++++++------------------------ hexdump.c | 55 ++-- 2 files changed, 414 insertions(+), 381 deletions(-) diff --git a/axdigi2018.c b/axdigi2018.c index 582c652..e46d387 100644 --- a/axdigi2018.c +++ b/axdigi2018.c @@ -1,6 +1,6 @@ -/* +/* * axdigi: Cross and straight port digipeater program - * Copyright (C) 1995 Craig Small VK2XLZ + * Copyright (C) 1995 Craig Small VK2XLZ * 2017 Gabor Mayer HG5OAP * * This program is free software; you can redistribute it and/or modify @@ -18,36 +18,43 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include +#include #include +#include #include -#include -#include +#include +#include #include #include #include -#include -#include -#include +#include #include -#include + +#include #include "hexdump.h" #define VERSION "2017-DEC-06" -#define BEACON_INTERVAL 300 -#define BEACON_DEST "BEACON" +#define DEFAULT_BEACON_INTERVAL 300 +#define DEFAULT_BEACON_DEST "BEACON" +#define DEFAULT_BEACON_TEXT \ + "axdigi2018 || AX.25 packet radio digipeater || " \ + "https://github.com/iddq/axdigi2018" #define BEACON_PATH "WIDE1-1", "RFONLY" -#define BEACON_TEXT "axdigi2018 || AX.25 packet radio digipeater || https://github.com/iddq/axdigi2018" #define AXALEN 7 -#define CALLSTRLEN AXALEN + 3 /* callsign + SSID including the terminating zero, "HG5OAP-11\0" */ +#define CALLSTRLEN \ + AXALEN + 3 /* callsign + SSID including the terminating zero, "HG5OAP-11\0" \ + */ -/* Address extension bit The extension bit of each octet is set to zero, to indicate the next octet contains more address information */ -#define E_BIT 0x01 /* Address extension */ -#define RR_BIT 0x60 /* Reserved bits in SSID field */ -#define C_BIT 0x80 /* C bit in destination and source SSID field */ -#define REPEATED 0x80 /* Has-been-repeated bit in digipeater field */ +/* Address extension bit The extension bit of each octet is set to zero, to + * indicate the next octet contains more address information */ +#define E_BIT 0x01 /* Address extension */ +#define RR_BIT 0x60 /* Reserved bits in SSID field */ +#define C_BIT 0x80 /* C bit in destination and source SSID field */ +#define REPEATED 0x80 /* Has-been-repeated bit in digipeater field */ #define MAX_PORTS 16 @@ -62,405 +69,432 @@ int port_count = 0; typedef char callsign_t[CALLSTRLEN]; struct ax25port_s { - int ifIndex; - char ifName[IF_NAMESIZE]; - unsigned char addr[AXALEN]; - callsign_t callsign; + int ifIndex; + char ifName[IF_NAMESIZE]; + unsigned char addr[AXALEN]; + callsign_t callsign; } ax25ports[MAX_PORTS]; struct ax25_header_s { - callsign_t dst; - callsign_t src; - callsign_t digi[AX25_MAX_DIGIS]; - unsigned char control; - unsigned char pid; - unsigned char ndigi; - unsigned char nrepeated; - int repeated[AX25_MAX_DIGIS]; + callsign_t dst; + callsign_t src; + callsign_t digi[AX25_MAX_DIGIS]; + unsigned char control; + unsigned char pid; + unsigned char ndigi; + unsigned char nrepeated; + int repeated[AX25_MAX_DIGIS]; } ax25header; -void ax25_addr2call(unsigned char *bptr, char *callsign) -{ - - unsigned char ssid = (bptr[6] >> 1) & 0xf; - - int i; - - memset(callsign, '\0', CALLSTRLEN); - - for (i=0; i> 1; - } +#define OPT_ENABLE_BEACON 'b' +#define OPT_BEACON_INTERVAL 'i' +#define OPT_BEACON_TEXT 't' +#define OPT_BEACON_DEST 'd' +#define OPT_HELP 'h' +#define OPT_VERSION 'v' +#define OPTSTRING "bi:t:hvd:" + +struct option options[] = { + {"enable-beacon", 0, NULL, OPT_ENABLE_BEACON}, + {"beacon-interval", 1, NULL, OPT_BEACON_INTERVAL}, + {"beacon-text", 1, NULL, OPT_BEACON_TEXT}, + {"beacon-dest", 1, NULL, OPT_BEACON_DEST}, + {"help", 0, NULL, OPT_HELP}, + {"version", 0, NULL, OPT_VERSION}, +}; + +struct config_s { + int beacon_enabled; + int beacon_interval; + callsign_t beacon_dest; + char beacon_text[1024]; +} config; + +void config_init(struct config_s *cfg) { + cfg->beacon_enabled = 0; + cfg->beacon_interval = DEFAULT_BEACON_INTERVAL; + strncpy(cfg->beacon_dest, DEFAULT_BEACON_DEST, sizeof(cfg->beacon_dest)); + strncpy(cfg->beacon_text, DEFAULT_BEACON_TEXT, sizeof(cfg->beacon_text)); +} + +void ax25_addr2call(unsigned char *bptr, char *callsign) { + + unsigned char ssid = (bptr[6] >> 1) & 0xf; + + int i; - snprintf(callsign + i, 4, ssid ? "-%d" : "", ssid); + memset(callsign, '\0', CALLSTRLEN); + for (i = 0; i < AXALEN - 1; i++) { + if (bptr[i] == ' ' << 1) + break; + callsign[i] = bptr[i] >> 1; + } + + snprintf(callsign + i, 4, ssid ? "-%d" : "", ssid); } void ax25_call2addr(callsign_t *callsign, unsigned char bptr[]) { - int i; - - memset(bptr, ' ' << 1, AXALEN-1); - bptr[AXALEN-1] = 0; // ssid = 0 - - for (i=0; idst); - bptr += AXALEN; - ax25_addr2call(bptr, (char *)&pheader->src); - bptr += AXALEN; - - //printf("parse_ax25_header: %s -> %s\n", pheader->src, pheader->dst); - - prev_repeated = 1; - - while (pheader->ndigi < AX25_MAX_DIGIS && !(bptr[-1] & E_BIT)) { - size -= AXALEN; - if (size<0) - return -1; - - ax25_addr2call(bptr, (char *)&pheader->digi[pheader->ndigi]); - - repeated = ((bptr[6] & REPEATED) != 0); - - if (!prev_repeated && repeated) - return -1; - - if (repeated) { - pheader->repeated[pheader->ndigi] = repeated; - pheader->nrepeated++; - } - - prev_repeated = repeated; - - //printf("parse_ax25_header: digi #%02d: %s, repeated: %d\n", pheader->ndigi, pheader->digi[pheader->ndigi], repeated); - - pheader->ndigi++; - bptr += AXALEN; + memset(pheader, 0, sizeof(struct ax25_header_s)); + + size -= 2 * AXALEN; + if (size < 0) + return -1; + + ax25_addr2call(bptr, (char *)&pheader->dst); + bptr += AXALEN; + ax25_addr2call(bptr, (char *)&pheader->src); + bptr += AXALEN; + + prev_repeated = 1; + + while (pheader->ndigi < AX25_MAX_DIGIS && !(bptr[-1] & E_BIT)) { + size -= AXALEN; + if (size < 0) + return -1; + + ax25_addr2call(bptr, (char *)&pheader->digi[pheader->ndigi]); + + repeated = ((bptr[6] & REPEATED) != 0); + + if (!prev_repeated && repeated) + return -1; + + if (repeated) { + pheader->repeated[pheader->ndigi] = repeated; + pheader->nrepeated++; } - - size -= 1; - if (size<0) - return -1; - - pheader->control = *bptr++; - //printf("parse_ax25_header: control: 0x%02x\n", pheader->control); - - //size -= 1; - //if (size<0) - // return -1; - - pheader->pid = *bptr++; - //printf("parse_ax25_header: pid: 0x%02x\n", pheader->pid); - - return 0; - + + prev_repeated = repeated; + pheader->ndigi++; + bptr += AXALEN; + } + + size -= 1; + if (size < 0) + return -1; + + pheader->control = *bptr++; + pheader->pid = *bptr++; + + return 0; } void add_port(int ifIndex, char *ifName, unsigned char *ax25_addr) { - if (port_count < MAX_PORTS) - { - ax25ports[port_count].ifIndex = ifIndex; - strncpy(ax25ports[port_count].ifName, ifName, IF_NAMESIZE); - memcpy(ax25ports[port_count].addr, ax25_addr, AXALEN); - - ax25_addr2call(ax25ports[port_count].addr, ax25ports[port_count].callsign); - - printf("port[%d]: interface: %s, index: %d, callsign: %s\n", port_count, ax25ports[port_count].ifName, - ax25ports[port_count].ifIndex, ax25ports[port_count].callsign); - fflush(stdout); - port_count++; - } + if (port_count < MAX_PORTS) { + ax25ports[port_count].ifIndex = ifIndex; + strncpy(ax25ports[port_count].ifName, ifName, IF_NAMESIZE); + memcpy(ax25ports[port_count].addr, ax25_addr, AXALEN); + + ax25_addr2call(ax25ports[port_count].addr, ax25ports[port_count].callsign); + + printf("port[%d]: interface: %s, index: %d, callsign: %s\n", port_count, + ax25ports[port_count].ifName, ax25ports[port_count].ifIndex, + ax25ports[port_count].callsign); + fflush(stdout); + port_count++; + } } -unsigned char *get_addr_by_ifindex(int ifIndex) -{ - int i; +unsigned char *get_addr_by_ifindex(int ifIndex) { + int i; - for(i = 0; i < port_count; i++) - { - if (ax25ports[i].ifIndex == ifIndex) { - return ax25ports[i].addr; - } + for (i = 0; i < port_count; i++) { + if (ax25ports[i].ifIndex == ifIndex) { + return ax25ports[i].addr; } + } - return (unsigned char*)NULL; + return (unsigned char *)NULL; } -int get_ifindex_by_addr(unsigned char *addr) -{ - int i; - - for(i = 0; i < port_count; i++) - { - if ((bcmp(addr, ax25ports[i].addr, AXALEN-1) == 0) && ((addr[6] & 0b00011110) == ax25ports[i].addr[6])) - return ax25ports[i].ifIndex; - } +int get_ifindex_by_addr(unsigned char *addr) { + int i; - return -1; + for (i = 0; i < port_count; i++) { + if ((bcmp(addr, ax25ports[i].addr, AXALEN - 1) == 0) && + ((addr[6] & 0b00011110) == ax25ports[i].addr[6])) + return ax25ports[i].ifIndex; + } + + return -1; } +int digipeat(unsigned char *bptr, struct ax25_header_s *pHeader, int ifIndex) { + unsigned char *in_interface_ax25_addr; + int outIfIndex = -1; -int digipeat(unsigned char *bptr, struct ax25_header_s *pHeader, int ifIndex) -{ - unsigned char *in_interface_ax25_addr; - int outIfIndex = -1; - - if ((in_interface_ax25_addr = get_addr_by_ifindex(ifIndex)) == NULL) - return -1; + if ((in_interface_ax25_addr = get_addr_by_ifindex(ifIndex)) == NULL) + return -1; - bptr += 2 * AXALEN + (pHeader->nrepeated * AXALEN); + bptr += 2 * AXALEN + (pHeader->nrepeated * AXALEN); - if ( (outIfIndex = get_ifindex_by_addr(bptr)) > 0) { - //printf("repeat: outIfIndex: %d\n", outIfIndex); - memcpy(bptr, in_interface_ax25_addr, AXALEN-1); - bptr[AXALEN-1] &= 0b11100001; - bptr[AXALEN-1] |= in_interface_ax25_addr[AXALEN-1] & 0b00011110; - bptr[AXALEN-1] |= REPEATED; - } + if ((outIfIndex = get_ifindex_by_addr(bptr)) > 0) { + memcpy(bptr, in_interface_ax25_addr, AXALEN - 1); + bptr[AXALEN - 1] &= 0b11100001; + bptr[AXALEN - 1] |= in_interface_ax25_addr[AXALEN - 1] & 0b00011110; + bptr[AXALEN - 1] |= REPEATED; + } - return outIfIndex; + return outIfIndex; } -void print_path(struct ax25_header_s *p) -{ - int i; - - if (p->ndigi == 0) { - printf("%s -> %s\n", p->src, p->dst); - } else { - printf("%s -> %s via ", p->src, p->dst); - for (i=0; indigi; i++) { - if (i==0) - printf(p->repeated[i] ? "%s*" : "%s", p->digi[i]); - else - printf(p->repeated[i] ? ", %s*" : ", %s", p->digi[i]); - } +void print_path(struct ax25_header_s *p) { + int i; + + if (p->ndigi == 0) { + printf("%s -> %s\n", p->src, p->dst); + } else { + printf("%s -> %s via ", p->src, p->dst); + for (i = 0; i < p->ndigi; i++) { + if (i == 0) + printf(p->repeated[i] ? "%s*" : "%s", p->digi[i]); + else + printf(p->repeated[i] ? ", %s*" : ", %s", p->digi[i]); } - printf("\n"); - fflush(stdout); + } + printf("\n"); + fflush(stdout); } -void get_interfaces(int skt) -{ - struct if_nameindex *if_ni, *i; - struct ifreq sifreq; - struct ifreq *ifr; - - ifr = &sifreq; - - if_ni = if_nameindex(); - if (if_ni == NULL) { - perror("if_nameindex"); - exit(EXIT_FAILURE); - } +void get_interfaces(int skt) { + struct if_nameindex *if_ni, *i; + struct ifreq sifreq; + struct ifreq *ifr; - for (i = if_ni; ! (i->if_index == 0 && i->if_name == NULL); i++) { - - //printf("%u: %s\n", i->if_index, i->if_name); - - strncpy(ifr->ifr_name, i->if_name, IF_NAMESIZE); - ioctl(skt, SIOCGIFHWADDR, ifr); - - //printf("sa_familiy: %d\n", sifreq.ifr_ifru.ifru_addr.sa_family); - - if (sifreq.ifr_ifru.ifru_addr.sa_family != ARPHRD_AX25) - continue; - - add_port(i->if_index, i->if_name, (unsigned char*)ifr->ifr_hwaddr.sa_data); - } - - if_freenameindex(if_ni); - -} + ifr = &sifreq; + if_ni = if_nameindex(); + if (if_ni == NULL) { + perror("if_nameindex"); + exit(EXIT_FAILURE); + } -void alarm_handler(int sig) -{ - unsigned char *p; - int i; - - signal(SIGALRM, SIG_IGN); /* ignore this signal */ - - for (i=0; i<1; i++) { - p = beaconbuf + 1 + AXALEN; - memcpy(p, ax25ports[i].addr, AXALEN); - p[6] |= RR_BIT; - - //hexdump(beaconbuf, beaconsize); - - saddr_ll2.sll_ifindex = ax25ports[i].ifIndex; - - if (sendto(skt, beaconbuf, beaconsize, 0, (struct sockaddr *)&saddr_ll2, sizeof(saddr_ll2)) == -1) - perror("sendto"); - } + for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) { + + strncpy(ifr->ifr_name, i->if_name, IF_NAMESIZE); + ioctl(skt, SIOCGIFHWADDR, ifr); - signal(SIGALRM, alarm_handler); /* reinstall the handler */ - alarm(BEACON_INTERVAL); + if (sifreq.ifr_ifru.ifru_addr.sa_family != ARPHRD_AX25) + continue; + + add_port(i->if_index, i->if_name, (unsigned char *)ifr->ifr_hwaddr.sa_data); + } + + if_freenameindex(if_ni); } +void alarm_handler(int sig) { + unsigned char *p; + int i; + + signal(SIGALRM, SIG_IGN); /* ignore this signal */ + + for (i = 0; i < 1; i++) { + p = beaconbuf + 1 + AXALEN; + memcpy(p, ax25ports[i].addr, AXALEN); + p[6] |= RR_BIT; + + saddr_ll2.sll_ifindex = ax25ports[i].ifIndex; + + if (sendto(skt, beaconbuf, beaconsize, 0, (struct sockaddr *)&saddr_ll2, + sizeof(saddr_ll2)) == -1) + perror("sendto"); + } + + signal(SIGALRM, alarm_handler); /* reinstall the handler */ + alarm(config.beacon_interval); +} int beacon_init(unsigned char *buf) { - struct ax25_header_s beacon = { BEACON_DEST, "" , { BEACON_PATH }, 0x03, 0xf0 } ; - //struct ax25_header_s beacon2; - - const char text[] = BEACON_TEXT; - int size = 0; - int i; - - *buf = 0; - size++; - - ax25_call2addr(&beacon.dst, buf + size); - buf[size + 6] |= C_BIT | RR_BIT; - size += AXALEN; - - ax25_call2addr(&beacon.src, buf + size); - buf[size + 6] |= RR_BIT; - size += AXALEN; - - for (i=0; i 1) - { - if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "-h") ==0) - { - printf("axdigi comes with ABSOLUTELY NO WARRANTY.\n"); - printf("This is free software, and you are welcome to redistribute it\n"); - printf("under the terms of GNU General Public Licence as published\n"); - printf("by Free Software Foundation; either version 2 of the License, or\n"); - printf("(at your option) any later version.\n"); - return 0; - } - } +void show_usage(FILE *out) { + fprintf(out, "axdigi: usage: axdigi [ --enable-beacon ] [ --beacon-text=text ] [ --beacon-dest=callsign ] [ --beacon-interval=interval ]\n"); +} - if ((skt = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) - { - perror("socket"); - return(1); +int main(int argc, char *argv[]) { + int size; + int outIfIndex; + unsigned char buf[2000]; + socklen_t asize; + struct sockaddr_ll saddr_ll; + + int ch; + int optind; + + printf("axdigi2018 (%s). Copyright (C) 1995 Craig Small VK2XLZ, 2017 Gabor " + "Mayer HG5OAP\n\n", + VERSION); + + config_init(&config); + while ((ch = getopt_long(argc, argv, OPTSTRING, options, &optind)) != -1) { + switch (ch) { + case OPT_HELP: + show_usage(stdout); + exit(0); + break; + + case OPT_VERSION: + show_license(stdout); + exit(0); + break; + + case OPT_ENABLE_BEACON: + config.beacon_enabled = 1; + break; + + case OPT_BEACON_INTERVAL: + config.beacon_interval = atoi(optarg); + break; + + case OPT_BEACON_TEXT: + strncpy(config.beacon_text, optarg, sizeof(config.beacon_text)); + break; + + case OPT_BEACON_DEST: + strncpy(config.beacon_dest, optarg, sizeof(config.beacon_dest)); + break; + + default: + show_usage(stderr); + exit(2); } + } - get_interfaces(skt); - - if (port_count < 1) - { - printf("No ax25 interface found.\n"); - exit(EXIT_FAILURE); - } + if ((skt = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) { + perror("socket"); + return (1); + } + + get_interfaces(skt); + + if (port_count < 1) { + printf("No ax25 interface found.\n"); + exit(EXIT_FAILURE); + } + if (config.beacon_enabled) { beaconsize = beacon_init(beaconbuf); - //hexdump(beaconbuf, beaconsize); signal(SIGALRM, alarm_handler); - alarm(BEACON_INTERVAL); - - while(1) - { - asize=sizeof(saddr_ll); - if ((size = recvfrom(skt, buf, sizeof(buf), 0, (struct sockaddr *)&saddr_ll, &asize)) == -1) - { - perror("recv"); - exit(EXIT_FAILURE); - } else { - if (saddr_ll.sll_protocol != htons(ETH_P_AX25)) - continue; - } - - //hexdump(buf, size); - - if (parse_ax25_header(buf+1, size-1, &ax25header) < 0) - continue; - - if (ax25header.ndigi == ax25header.nrepeated) - continue; - -#ifdef DO_NOT_FORWARD_APRS_PACKET - if ((ax25header.control | 0x10) == 0x13 && ax25header.pid == 0xf0) // UI frame, PID = Text - continue; -#endif + alarm(config.beacon_interval); + } + + while (1) { + asize = sizeof(saddr_ll); + if ((size = recvfrom(skt, buf, sizeof(buf), 0, (struct sockaddr *)&saddr_ll, + &asize)) == -1) { + perror("recv"); + exit(EXIT_FAILURE); + } else { + if (saddr_ll.sll_protocol != htons(ETH_P_AX25)) + continue; + } - //print_path(&ax25header); + if (parse_ax25_header(buf + 1, size - 1, &ax25header) < 0) + continue; - outIfIndex = digipeat(buf+1, &ax25header, saddr_ll.sll_ifindex); + if (ax25header.ndigi == ax25header.nrepeated) + continue; - if (outIfIndex > 0) - { - parse_ax25_header(buf+1, size-1, &ax25header); // re-parse packet header - print_path(&ax25header); - saddr_ll.sll_ifindex = outIfIndex; - if (sendto(skt, buf, size, 0, (struct sockaddr *)&saddr_ll, sizeof(saddr_ll)) == -1) - perror("sendto"); - } +#ifdef DO_NOT_FORWARD_APRS_PACKET + if ((ax25header.control | 0x10) == 0x13 && + ax25header.pid == 0xf0) // UI frame, PID = Text + continue; +#endif - } /* while(1) */ + outIfIndex = digipeat(buf + 1, &ax25header, saddr_ll.sll_ifindex); + + if (outIfIndex > 0) { + parse_ax25_header(buf + 1, size - 1, + &ax25header); // re-parse packet header + print_path(&ax25header); + saddr_ll.sll_ifindex = outIfIndex; + if (sendto(skt, buf, size, 0, (struct sockaddr *)&saddr_ll, + sizeof(saddr_ll)) == -1) + perror("sendto"); + } + } /* while(1) */ } diff --git a/hexdump.c b/hexdump.c index 9bf0192..c31fb48 100644 --- a/hexdump.c +++ b/hexdump.c @@ -1,34 +1,33 @@ #include void hexdump(unsigned char *buf, int size) { - unsigned char *p; - int i; - - p = buf; - - while (p < buf + size) { - - for (i = 0; i<16; i++) { - if (p + i >= buf + size) - printf(" "); - else - printf("%02x ", p[i]); - } - - for (i = 0; i<16; i++) { - if (p + i >= buf + size) { - printf(" "); - continue; - } - - if (p[i] > 31 && p[i] < 127) - printf("%c", p[i]); - else - printf("."); - } + unsigned char *p; + int i; - printf("\n"); - p += 16; + p = buf; + + while (p < buf + size) { + + for (i = 0; i < 16; i++) { + if (p + i >= buf + size) + printf(" "); + else + printf("%02x ", p[i]); + } + + for (i = 0; i < 16; i++) { + if (p + i >= buf + size) { + printf(" "); + continue; + } + + if (p[i] > 31 && p[i] < 127) + printf("%c", p[i]); + else + printf("."); } - + + printf("\n"); + p += 16; + } } \ No newline at end of file From b2c8bca6545451e5fb579933c4c22e50b4e83e4a Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Wed, 8 Nov 2023 12:11:45 -0500 Subject: [PATCH 2/7] Restructure Makefile --- Makefile | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5ee401f..0492aaf 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,13 @@ -all: - $(CC) -DDO_NOT_FORWARD_APRS_PACKET -Wall -g -oaxdigi2018 axdigi2018.c hexdump.c +CFLAGS = -g -Wall + +SRCS = \ + axdigi2018.c +OBJS = $(SRCS:.c=.o) + +all: axdigi2018 + +axdigi2018: $(OBJS) + $(CC) -o $@ $(OBJS) + +clean: + rm -f axdigi2018 $(OBJS) From bdb49d01886e42e687f9497d22aa4dfad6c0d9c4 Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Wed, 8 Nov 2023 12:14:58 -0500 Subject: [PATCH 3/7] Use git rev for version by default --- Makefile | 2 ++ axdigi2018.c | 13 ++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 0492aaf..8b91c58 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,6 @@ +VERSION = $(shell git rev-parse --short HEAD) CFLAGS = -g -Wall +CPPFLAGS = -DVERSION="\"$(VERSION)\"" SRCS = \ axdigi2018.c diff --git a/axdigi2018.c b/axdigi2018.c index e46d387..4e8e6b9 100644 --- a/axdigi2018.c +++ b/axdigi2018.c @@ -35,7 +35,9 @@ #include "hexdump.h" -#define VERSION "2017-DEC-06" +#ifndef VERSION +#define VERSION "development" +#endif // VERSION #define DEFAULT_BEACON_INTERVAL 300 #define DEFAULT_BEACON_DEST "BEACON" @@ -391,7 +393,8 @@ void show_license(FILE *out) { } void show_usage(FILE *out) { - fprintf(out, "axdigi: usage: axdigi [ --enable-beacon ] [ --beacon-text=text ] [ --beacon-dest=callsign ] [ --beacon-interval=interval ]\n"); + fprintf(out, "axdigi: usage: axdigi [ --enable-beacon ] [ --beacon-text=text " + "] [ --beacon-dest=callsign ] [ --beacon-interval=interval ]\n"); } int main(int argc, char *argv[]) { @@ -412,9 +415,9 @@ int main(int argc, char *argv[]) { while ((ch = getopt_long(argc, argv, OPTSTRING, options, &optind)) != -1) { switch (ch) { case OPT_HELP: - show_usage(stdout); - exit(0); - break; + show_usage(stdout); + exit(0); + break; case OPT_VERSION: show_license(stdout); From 846ca6775325100a6b447272b2ed3aba346ff06f Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Thu, 9 Nov 2023 20:19:12 -0500 Subject: [PATCH 4/7] Teach axdigi2018 about --beacon-path option --- axdigi2018.c | 48 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/axdigi2018.c b/axdigi2018.c index 4e8e6b9..f3e8fbf 100644 --- a/axdigi2018.c +++ b/axdigi2018.c @@ -44,7 +44,7 @@ #define DEFAULT_BEACON_TEXT \ "axdigi2018 || AX.25 packet radio digipeater || " \ "https://github.com/iddq/axdigi2018" -#define BEACON_PATH "WIDE1-1", "RFONLY" +#define DEFAULT_BEACON_PATH "WIDE1-1", "RFONLY" #define AXALEN 7 #define CALLSTRLEN \ @@ -92,15 +92,17 @@ struct ax25_header_s { #define OPT_BEACON_INTERVAL 'i' #define OPT_BEACON_TEXT 't' #define OPT_BEACON_DEST 'd' +#define OPT_BEACON_PATH 'p' #define OPT_HELP 'h' #define OPT_VERSION 'v' -#define OPTSTRING "bi:t:hvd:" +#define OPTSTRING "bi:t:hvd:p:" struct option options[] = { {"enable-beacon", 0, NULL, OPT_ENABLE_BEACON}, {"beacon-interval", 1, NULL, OPT_BEACON_INTERVAL}, {"beacon-text", 1, NULL, OPT_BEACON_TEXT}, {"beacon-dest", 1, NULL, OPT_BEACON_DEST}, + {"beacon-path", 1, NULL, OPT_BEACON_PATH}, {"help", 0, NULL, OPT_HELP}, {"version", 0, NULL, OPT_VERSION}, }; @@ -110,13 +112,35 @@ struct config_s { int beacon_interval; callsign_t beacon_dest; char beacon_text[1024]; + callsign_t beacon_path[AX25_MAX_DIGIS]; + int beacon_path_count; } config; void config_init(struct config_s *cfg) { + callsign_t _beacon_path[] = {DEFAULT_BEACON_PATH}; + int i; + + cfg->beacon_path_count = sizeof(_beacon_path) / sizeof(callsign_t); + cfg->beacon_enabled = 0; cfg->beacon_interval = DEFAULT_BEACON_INTERVAL; strncpy(cfg->beacon_dest, DEFAULT_BEACON_DEST, sizeof(cfg->beacon_dest)); strncpy(cfg->beacon_text, DEFAULT_BEACON_TEXT, sizeof(cfg->beacon_text)); + memset(cfg->beacon_path, 0, sizeof(cfg->beacon_path)); + for (i = 0; i < cfg->beacon_path_count; i++) { + strncpy(cfg->beacon_path[i], _beacon_path[i], sizeof(callsign_t)); + } +} + +void config_set_beacon_path(struct config_s *cfg, char *arg) { + char *tok; + int i = 0; + + tok = strtok(arg, ","); + while (tok != NULL) { + strncpy(cfg->beacon_path[i++], tok, sizeof(callsign_t)); + tok = strtok(NULL, ","); + } } void ax25_addr2call(unsigned char *bptr, char *callsign) { @@ -338,13 +362,15 @@ void alarm_handler(int sig) { } int beacon_init(unsigned char *buf) { - - struct ax25_header_s beacon = {"", "", {BEACON_PATH}, 0x03, 0xf0}; - strncpy(beacon.dst, config.beacon_dest, sizeof(beacon.dst)); - int size = 0; int i; + struct ax25_header_s beacon = {"", "", {}, 0x03, 0xf0}; + strncpy(beacon.dst, config.beacon_dest, sizeof(beacon.dst)); + for (i = 0; i < config.beacon_path_count; i++) { + strncpy(beacon.digi[i], config.beacon_path[i], sizeof(callsign_t)); + } + *buf = 0; size++; @@ -393,8 +419,10 @@ void show_license(FILE *out) { } void show_usage(FILE *out) { - fprintf(out, "axdigi: usage: axdigi [ --enable-beacon ] [ --beacon-text=text " - "] [ --beacon-dest=callsign ] [ --beacon-interval=interval ]\n"); + fprintf(out, + "axdigi: usage: axdigi [ --enable-beacon ] [ --beacon-text=text ]" + " [ --beacon-dest=callsign ] [ --beacon-interval=interval ]" + " [ --beacon-path=digi1,digi2,... ]\n"); } int main(int argc, char *argv[]) { @@ -440,6 +468,10 @@ int main(int argc, char *argv[]) { strncpy(config.beacon_dest, optarg, sizeof(config.beacon_dest)); break; + case OPT_BEACON_PATH: + config_set_beacon_path(&config, optarg); + break; + default: show_usage(stderr); exit(2); From 35b1d27ab17bc6137e39b1ce7c7113b0ac00d70d Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Thu, 9 Nov 2023 20:25:16 -0500 Subject: [PATCH 5/7] Update README --- README.md | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8fa5f28..6a66e46 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,31 @@ # axdigi2018 + AX.25 packet radio digipeater for linux -features: +## Features + - cross port digipeating - aprs digipeater interworking - periodical beacons -easy install and run: -* make -* ./axdigi2018 +## Building + +To build `axdigi2018`: + +``` +make +``` + +To run with default options: + +``` +./axdigi2018 +``` + +## Options +- `--enable-beacon`, `-b` -- enable a periodic beacon every `--beacon-interval` seconds +- `--beacon-text`, `-t` *text* -- set beacon text +- `--beacon-dest`, `-d` *callsign* -- set beacon destination +- `--beacon-interval`, `-i` *seconds* -- set beacon interval (default 300) +- `--beacon-path`, `-p` *digi1,digi2,...* -- set beacon path From 4dabcdfe556c6112b646bf915f4611ceafcb55f3 Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Thu, 9 Nov 2023 20:25:49 -0500 Subject: [PATCH 6/7] Ignore generated files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9998e40 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/axdigi2018 +*.o From 6f4c6ab70e2ea891a1c5cfbba1377385189a8c42 Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Thu, 9 Nov 2023 20:33:02 -0500 Subject: [PATCH 7/7] Add lint and build workflows --- .github/workflows/build.yaml | 16 ++++++++++++++++ .github/workflows/pre-commit.yaml | 14 ++++++++++++++ .pre-commit-config.yaml | 5 +++++ 3 files changed, 35 insertions(+) create mode 100644 .github/workflows/build.yaml create mode 100644 .github/workflows/pre-commit.yaml create mode 100644 .pre-commit-config.yaml diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..1836f3c --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,16 @@ +name: build + +on: + pull_request: + push: + branches: [master] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - run: | + make + ./axdigi2018 --help diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml new file mode 100644 index 0000000..f46e01d --- /dev/null +++ b/.github/workflows/pre-commit.yaml @@ -0,0 +1,14 @@ +name: pre-commit + +on: + pull_request: + push: + branches: [master] + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - uses: pre-commit/action@v3.0.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..368a921 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,5 @@ +repos: +- repo: https://github.com/pre-commit/mirrors-clang-format + rev: v17.0.4 + hooks: + - id: clang-format