2015-07-25 00:26:23 -05:00
|
|
|
#include <stdio.h>
|
2015-07-24 21:49:57 -05:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include <patty/ax25.h>
|
|
|
|
|
|
|
|
static patty_ax25_if *create_tnc(const char *device) {
|
|
|
|
patty_ax25_if *iface;
|
|
|
|
|
2015-07-25 00:26:23 -05:00
|
|
|
static char * prefix = "kiss";
|
|
|
|
static int number = 0;
|
|
|
|
|
2015-07-24 21:49:57 -05:00
|
|
|
if ((iface = malloc(sizeof(*iface))) == NULL) {
|
|
|
|
goto error_malloc_iface;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(iface, '\0', sizeof(*iface));
|
|
|
|
|
2020-05-27 22:22:42 -04:00
|
|
|
if ((iface->tnc = patty_kiss_tnc_open(device)) == NULL) {
|
2015-07-24 21:49:57 -05:00
|
|
|
goto error_kiss_tnc_open;
|
|
|
|
}
|
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
iface->type = PATTY_AX25_IF_KISS_TNC;
|
2015-07-24 21:49:57 -05:00
|
|
|
|
2015-07-25 00:26:23 -05:00
|
|
|
snprintf(iface->name, sizeof(iface->name), "%s%d", prefix, number++);
|
|
|
|
|
2015-07-24 21:49:57 -05:00
|
|
|
return iface;
|
|
|
|
|
|
|
|
error_kiss_tnc_open:
|
|
|
|
free(iface);
|
|
|
|
|
|
|
|
error_malloc_iface:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void destroy_tnc(patty_ax25_if *iface) {
|
|
|
|
patty_kiss_tnc_close(iface->tnc);
|
|
|
|
}
|
|
|
|
|
|
|
|
patty_ax25_if *patty_ax25_if_create(int opts, void *info) {
|
|
|
|
patty_ax25_if *iface;
|
|
|
|
|
|
|
|
switch (PATTY_AX25_IF_OPT_TYPE(opts)) {
|
2020-06-07 02:46:12 -04:00
|
|
|
case PATTY_AX25_IF_KISS_TNC: {
|
2015-07-24 21:49:57 -05:00
|
|
|
iface = create_tnc((const char *)info);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default: {
|
|
|
|
errno = EINVAL;
|
|
|
|
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (iface == NULL) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
if ((iface->addrs = patty_list_new()) == NULL) {
|
2015-07-24 21:49:57 -05:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return iface;
|
|
|
|
|
|
|
|
error:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void patty_ax25_if_destroy(patty_ax25_if *iface) {
|
|
|
|
switch (iface->type) {
|
2020-06-07 02:46:12 -04:00
|
|
|
case PATTY_AX25_IF_KISS_TNC: {
|
2015-07-24 21:49:57 -05:00
|
|
|
destroy_tnc(iface); break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
}
|
2015-07-25 00:26:23 -05:00
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
int patty_ax25_if_each_addr(patty_ax25_if *iface,
|
|
|
|
int (*callback)(char *, uint8_t, void *), void *ctx) {
|
2015-07-25 00:26:23 -05:00
|
|
|
patty_list_iterator *iter;
|
2020-06-07 02:46:12 -04:00
|
|
|
patty_ax25_addr *addr;
|
2015-07-25 00:26:23 -05:00
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
if ((iter = patty_list_start(iface->addrs)) == NULL) {
|
2015-07-25 00:26:23 -05:00
|
|
|
goto error_list_start;
|
|
|
|
}
|
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
while ((addr = patty_list_next(iter)) != NULL) {
|
|
|
|
char buf[7];
|
|
|
|
uint8_t ssid;
|
|
|
|
|
|
|
|
if (patty_ax25_ntop(addr, buf, &ssid, sizeof(buf)) < 0) {
|
|
|
|
goto error_ntop;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (callback(buf, ssid, ctx) < 0) {
|
2015-07-25 00:26:23 -05:00
|
|
|
goto error_callback;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
patty_list_finish(iter);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error_callback:
|
2020-06-07 02:46:12 -04:00
|
|
|
error_ntop:
|
2015-07-25 00:26:23 -05:00
|
|
|
patty_list_finish(iter);
|
|
|
|
|
|
|
|
error_list_start:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
static patty_ax25_addr *find_addr(patty_ax25_if *iface,
|
|
|
|
const char *callsign,
|
|
|
|
uint8_t ssid) {
|
2015-07-25 00:26:23 -05:00
|
|
|
patty_list_iterator *iter;
|
2020-06-07 02:46:12 -04:00
|
|
|
patty_ax25_addr *addr;
|
2015-07-25 00:26:23 -05:00
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
if ((iter = patty_list_start(iface->addrs)) == NULL) {
|
2015-07-25 00:26:23 -05:00
|
|
|
goto error_list_start;
|
|
|
|
}
|
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
while ((addr = patty_list_next(iter)) != NULL) {
|
|
|
|
char buf[7];
|
|
|
|
uint8_t addr_ssid;
|
|
|
|
|
|
|
|
if (patty_ax25_ntop(addr, buf, &addr_ssid, sizeof(buf)) < 0) {
|
|
|
|
goto error_ntop;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strncmp(buf, callsign, sizeof(buf)) != 0) {
|
2015-07-25 00:26:23 -05:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
|
|
|
|
if (addr_ssid != ssid) {
|
2015-07-25 00:26:23 -05:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
patty_list_finish(iter);
|
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
return addr;
|
2015-07-25 00:26:23 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
patty_list_finish(iter);
|
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
error_ntop:
|
|
|
|
patty_list_finish(iter);
|
|
|
|
|
2015-07-25 00:26:23 -05:00
|
|
|
error_list_start:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
int patty_ax25_if_add_addr(patty_ax25_if *iface,
|
|
|
|
const char *callsign,
|
|
|
|
uint8_t ssid) {
|
|
|
|
patty_ax25_addr *addr;
|
2015-07-25 00:26:23 -05:00
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
if (find_addr(iface, callsign, ssid) != NULL) {
|
2015-07-25 00:26:23 -05:00
|
|
|
errno = EEXIST;
|
|
|
|
|
|
|
|
goto error_exists;
|
|
|
|
}
|
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
if ((addr = malloc(sizeof(*addr))) == NULL) {
|
|
|
|
goto error_malloc_addr;
|
2015-07-25 00:26:23 -05:00
|
|
|
}
|
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
if (patty_ax25_pton(callsign, ssid, addr) < 0) {
|
|
|
|
goto error_pton;
|
|
|
|
}
|
2015-07-25 00:26:23 -05:00
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
if ((patty_list_append(iface->addrs, addr)) == NULL) {
|
2015-07-25 00:26:23 -05:00
|
|
|
goto error_list_append;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error_list_append:
|
2020-06-07 02:46:12 -04:00
|
|
|
error_pton:
|
|
|
|
free(addr);
|
2015-07-25 00:26:23 -05:00
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
error_malloc_addr:
|
2015-07-25 00:26:23 -05:00
|
|
|
error_exists:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
int patty_ax25_if_delete_addr(patty_ax25_if *iface,
|
|
|
|
const char *callsign,
|
|
|
|
uint8_t ssid) {
|
|
|
|
patty_list_item *item = iface->addrs->first;
|
2015-07-25 00:26:23 -05:00
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
while (item) {
|
2020-06-07 02:46:12 -04:00
|
|
|
char buf[7];
|
|
|
|
uint8_t addr_ssid;
|
|
|
|
|
|
|
|
patty_ax25_addr *addr = item->value;
|
|
|
|
|
|
|
|
if (patty_ax25_ntop(addr, buf, &addr_ssid, sizeof(buf)) < 0) {
|
|
|
|
goto error_ntop;
|
|
|
|
}
|
2015-07-25 00:26:23 -05:00
|
|
|
|
2020-06-07 02:46:12 -04:00
|
|
|
if (strncmp(buf, callsign, sizeof(buf)) == 0 && addr_ssid == ssid) {
|
|
|
|
if (patty_list_splice(iface->addrs, i) == NULL) {
|
2015-07-25 00:26:23 -05:00
|
|
|
goto error_list_splice;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
item = item->next;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error_list_splice:
|
2020-06-07 02:46:12 -04:00
|
|
|
error_ntop:
|
2015-07-25 00:26:23 -05:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|