Major refactor WIP

This commit is contained in:
XANTRONIX Development 2020-06-07 02:46:12 -04:00 committed by XANTRONIX Industrial
parent b5ed9e9b61
commit a8db220bbd
14 changed files with 438 additions and 304 deletions

View file

@ -8,26 +8,29 @@
#include <patty/list.h>
#include <patty/dict.h>
typedef struct _patty_ax25 patty_ax25;
#pragma pack(push)
#pragma pack(1)
typedef struct _patty_ax25_addr {
uint8_t callsign[6];
uint8_t ssid;
} patty_ax25_addr;
#pragma pack(pop)
typedef struct _patty_ax25 patty_ax25;
typedef struct _patty_ax25_if patty_ax25_if;
#include <patty/ax25/macros.h>
#include <patty/ax25/proto.h>
#include <patty/ax25/address.h>
#include <patty/ax25/frame.h>
#include <patty/ax25/if.h>
#define PATTY_AX25_EVENT_QUEUE_SIZE 32
enum patty_ax25_event_type {
PATTY_AX25_EVENT_UNKNOWN,
PATTY_AX25_EVENT_RECV,
PATTY_AX25_EVENT_SEND,
PATTY_AX25_EVENT_READ,
PATTY_AX25_EVENT_WRITE,
PATTY_AX25_EVENT_ERROR
};
#define PATTY_AX25_ADDRESS_SIZE 7
#define PATTY_AX25_CALLSIGN_LEN 6
enum patty_ax25_sock_status {
PATTY_AX25_SOCK_CLOSED,
PATTY_AX25_SOCK_OPEN,
PATTY_AX25_SOCK_LISTENING,
PATTY_AX25_SOCK_ESTABLISHED
@ -59,57 +62,67 @@ typedef struct _patty_ax25_sock {
unsigned int seq_send,
seq_recv;
int fd;
patty_ax25_if *iface;
patty_ax25_address *local,
*remote;
patty_ax25_addr local,
remote,
repeaters[PATTY_AX25_MAX_HOPS];
unsigned int hops;
} patty_ax25_sock;
typedef struct _patty_ax25_event {
enum patty_ax25_event_type type;
patty_ax25_sock * sock;
} patty_ax25_event;
typedef struct _patty_ax25 {
patty_list *ifaces,
*socks;
patty_list *ifaces;
patty_dict *socks,
*socks_by_addrpair;
int fd,
current,
fdmax;
fd_set fds,
fds_pending_read,
fds_pending_write,
fds_pending_error;
patty_dict * fd_lookup;
fds_r,
fds_w;
} patty_ax25;
int patty_ax25_init(patty_ax25 *ax25);
void patty_ax25_stop(patty_ax25 *ax25);
int patty_ax25_pton(const char *callsign,
uint8_t ssid,
patty_ax25_addr *addr);
int patty_ax25_ntop(const patty_ax25_addr *addr,
char *dest,
uint8_t *ssid,
size_t len);
int patty_ax25_open(patty_ax25 *ax25, const char *ifname);
int patty_ax25_socket(patty_ax25 *ax25);
int patty_ax25_bind(patty_ax25 *ax25,
int socket, const char *callsign, int ssid);
int socket,
const char *callsign,
uint8_t ssid);
int patty_ax25_listen(patty_ax25 *ax25,
int socket, const char *callsign, int ssid);
int socket);
int patty_ax25_connect(patty_ax25 *ax25,
int socket, const char *callsign, int ssid);
int socket,
const char *callsign,
uint8_t ssid);
int patty_ax25_accept(patty_ax25 *ax25,
int socket);
int patty_ax25_accept(patty_ax25 *ax25, int socket);
int patty_ax25_close(patty_ax25 *ax25, int fd);
int patty_ax25_next_event(patty_ax25 *ax25,
patty_ax25_event *ev);
/*int patty_ax25_next_event(patty_ax25 *ax25,
patty_ax25_event *ev);*/
int patty_ax25_recv(patty_ax25 *ax25,
int fd, patty_ax25_frame *frame);

View file

@ -1,26 +0,0 @@
#ifndef _PATTY_AX25_ADDRESS_H
#define _PATTY_AX25_ADDRESS_H
#include <stdint.h>
#include <sys/types.h>
#define PATTY_AX25_ADDRESS_CALLSIGN_LEN 6
#define PATTY_AX25_ADDRESS_SIZE 7
typedef struct _patty_ax25_address {
char callsign[7];
uint8_t ssid,
last;
union {
uint8_t c,
repeated;
};
} patty_ax25_address;
patty_ax25_address *patty_ax25_address_create(const char *callsign, int ssid);
void patty_ax25_address_destroy(patty_ax25_address *address);
#endif /* _PATTY_AX25_ADDRESS_H */

View file

@ -20,11 +20,11 @@ enum patty_ax25_frame_cr {
};
typedef struct _patty_ax25_frame {
patty_ax25_address dest;
patty_ax25_address src;
patty_ax25_address repeaters[7];
patty_ax25_addr dest,
src,
repeaters[7];
uint8_t hops;
unsigned int hops;
enum patty_ax25_version version;
enum patty_ax25_frame_type type;
@ -45,7 +45,7 @@ ssize_t patty_ax25_frame_info(patty_ax25_frame *frame,
void **info);
int patty_ax25_frame_addresed_to(patty_ax25_frame *frame,
char *station,
const char *callsign,
uint8_t ssid);
#endif /* _PATTY_AX25_FRAME_H */

View file

@ -12,12 +12,9 @@
((n) & PATTY_AX25_IF_OPT_TYPE_MASK)
enum patty_ax25_if_type {
PATTY_AX25_IF_UNKNOWN = 0x00,
PATTY_AX25_IF_KISS_TNC_TTY = 0x01,
PATTY_AX25_IF_KISS_TNC_PORT = 0x02,
PATTY_AX25_IF_KISS_TNC_I2C = 0x04,
PATTY_AX25_IF_KISS_TNC_SPI = 0x08,
PATTY_AX25_IF_SOFT_TNC = 0x10
PATTY_AX25_IF_UNKNOWN,
PATTY_AX25_IF_KISS_TNC,
PATTY_AX25_IF_HDLC
};
typedef struct _patty_ax25_if_stats {
@ -29,31 +26,31 @@ typedef struct _patty_ax25_if_stats {
} patty_ax25_if_stats;
typedef struct _patty_ax25_if {
enum patty_ax25_if_type type;
patty_ax25_if_stats stats;
enum patty_ax25_if_type type;
patty_ax25_if_stats stats;
char name[8];
patty_kiss_tnc * tnc;
patty_list * addresses;
patty_kiss_tnc *tnc;
patty_list *addrs;
} patty_ax25_if;
patty_ax25_if *patty_ax25_if_create(int opts, void *info);
void patty_ax25_if_destroy(patty_ax25_if *iface);
int patty_ax25_if_each_address(patty_ax25_if *iface,
int (*callback)(patty_ax25_address *, void *), void *ctx);
int patty_ax25_if_each_addr(patty_ax25_if *iface,
int (*callback)(char *, uint8_t, void *), void *ctx);
int patty_ax25_if_add_address(patty_ax25_if *iface,
const char *callsign, int ssid);
int patty_ax25_if_add_addr(patty_ax25_if *iface,
const char *callsign, uint8_t ssid);
int patty_ax25_if_delete_address(patty_ax25_if *iface,
const char *callsign, int ssid);
int patty_ax25_if_delete_addr(patty_ax25_if *iface,
const char *callsign, uint8_t ssid);
patty_ax25_if *patty_ax25_get_if(patty_ax25 *ax25, const char *name);
int patty_ax25_each_if(patty_ax25 *ax25,
int patty_ax25_if_each(patty_ax25 *ax25,
int (*callback)(patty_ax25_if *, void *), void *ctx);
int patty_ax25_add_if(patty_ax25 *ax25, patty_ax25_if *iface);

View file

@ -39,8 +39,16 @@ int patty_dict_each(patty_dict *dict, patty_dict_callback callback, void *ctx);
void *patty_dict_get(patty_dict *dict, void *key, size_t keysz);
void *patty_dict_set_with_hash(patty_dict *dict,
void *key,
size_t keysz,
void *value,
uint32_t hash);
void *patty_dict_set(patty_dict *dict, void *key, size_t keysz, void *value);
void *patty_dict_delete_with_hash(patty_dict *dict, void *key, size_t keysz);
void *patty_dict_delete(patty_dict *dict, void *key, size_t keysz);
void patty_dict_destroy(patty_dict *dict);

View file

@ -8,9 +8,9 @@ CFLAGS = $(CGFLAGS) -fPIC -Wall -O2 -I$(INCLUDE_PATH)
LDFLAGS =
HEADERS = kiss.h ax25.h ax25/if.h ax25/macros.h ax25/proto.h \
ax25/address.h ax25/frame.h list.h hash.h dict.h
ax25/frame.h list.h hash.h dict.h
OBJS = kiss.o ax25.o if.o address.o frame.o \
OBJS = kiss.o ax25.o if.o frame.o \
list.o hash.o dict.o
EXAMPLES = iflist decode ptmx

View file

@ -1,30 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <patty/ax25/address.h>
patty_ax25_address *patty_ax25_address_create(const char *callsign, int ssid) {
patty_ax25_address *addr;
if ((addr = malloc(sizeof(*addr))) == NULL) {
goto error_malloc_addr;
}
memset(addr, '\0', sizeof(*addr));
memcpy(addr->callsign, callsign, sizeof(addr->callsign));
addr->ssid = ssid;
addr->last = 0;
addr->c = 0;
return addr;
error_malloc_addr:
return NULL;
}
void patty_ax25_address_destroy(patty_ax25_address *address) {
free(address);
}

View file

@ -13,20 +13,20 @@ int patty_ax25_init(patty_ax25 *ax25) {
goto error_list_new_ifaces;
}
if ((ax25->socks = patty_list_new()) == NULL) {
goto error_list_new_socks;
if ((ax25->socks = patty_dict_new()) == NULL) {
goto error_dict_new_socks;
}
if ((ax25->fd_lookup = patty_dict_new()) == NULL) {
goto error_dict_new_fd_lookup;
if ((ax25->socks_by_addrpair = patty_dict_new()) == NULL) {
goto error_dict_new_socks_by_addrpair;
}
return 0;
error_dict_new_fd_lookup:
patty_list_destroy(ax25->socks);
error_dict_new_socks_by_addrpair:
patty_dict_destroy(ax25->socks);
error_list_new_socks:
error_dict_new_socks:
patty_list_destroy(ax25->ifaces);
error_list_new_ifaces:
@ -40,34 +40,113 @@ static int destroy_if(patty_ax25_if *iface, void *ctx) {
}
void patty_ax25_stop(patty_ax25 *ax25) {
patty_dict_destroy(ax25->fd_lookup);
patty_list_destroy(ax25->socks);
patty_dict_destroy(ax25->socks_by_addrpair);
patty_dict_destroy(ax25->socks);
patty_ax25_each_if(ax25, destroy_if, NULL);
patty_ax25_if_each(ax25, destroy_if, NULL);
patty_list_destroy(ax25->ifaces);
}
static void *fd_lookup(patty_ax25 *ax25, int fd) {
void *obj;
static patty_ax25_sock *sock_by_fd(patty_ax25 *ax25, int fd) {
patty_ax25_sock *sock;
if ((obj = patty_dict_get(ax25->fd_lookup, &fd, sizeof(fd))) == NULL) {
if ((sock = patty_dict_get(ax25->socks, &fd, sizeof(fd))) == NULL) {
errno = EBADF;
goto error_dict_get;
}
return obj;
return sock;
error_dict_get:
return NULL;
}
static int fd_store(patty_ax25 *ax25, patty_ax25_sock *sock) {
if (patty_dict_set(ax25->fd_lookup, &ax25->fd, sizeof(ax25->fd), sock) == NULL) {
static inline void hash_init(uint32_t *hash) {
*hash = 0xffffffdf;
}
static inline void hash_byte(uint32_t *hash, uint8_t c) {
*hash += c;
*hash += (*hash << 10);
*hash ^= (*hash >> 6);
}
static inline void hash_addr(uint32_t *hash, patty_ax25_addr *addr) {
int i;
for (i=0; i<PATTY_AX25_CALLSIGN_LEN; i++) {
hash_byte(hash, addr->callsign[i] >> 1);
}
hash_byte(hash, PATTY_AX25_ADDRESS_SSID_NUMBER(addr->ssid));
}
static inline void hash_end(uint32_t *hash) {
*hash += (*hash << 3);
*hash ^= (*hash >> 11);
*hash += (*hash << 15);
}
static uint32_t hash_addrpair(patty_ax25_addr *local,
patty_ax25_addr *remote) {
uint32_t hash;
hash_init(&hash);
hash_addr(&hash, local);
hash_addr(&hash, remote);
hash_end(&hash);
return hash;
}
static patty_ax25_sock *sock_get_fd(patty_ax25 *ax25,
int fd) {
return patty_dict_get(ax25->socks,
fd,
sizeof(fd));
}
static patty_ax25_sock *sock_get_addrpair(patty_ax25 *ax25,
patty_ax25_addr *local,
patty_ax25_addr *remote) {
patty_dict_slot *slot;
uint32_t hash = hash_addrpair(local, remote);
if ((slot = patty_dict_slot_find(ax25->socks_by_addrpair, hash)) == NULL) {
errno = EBADF;
goto error_dict_slot_find;
}
return (patty_ax25_sock *)slot->value;
error_dict_slot_find:
return NULL;
}
static int sock_save(patty_ax25 *ax25, patty_ax25_sock *sock) {
uint32_t hash = hash_addrpair(&sock->local, &sock->remote);
if (patty_dict_set(ax25->socks,
sock->fd,
sizeof(sock->fd),
sock) == NULL) {
goto error_dict_set;
}
return ax25->fd++;
if (patty_dict_set_with_hash(ax25->socks_by_addrpair,
sock->fd,
sizeof(sock->fd),
sock,
hash) == NULL) {
goto error_dict_set;
}
return sock->fd;
error_dict_set:
return -1;
@ -84,7 +163,6 @@ static void sock_init(patty_ax25_sock *sock) {
int patty_ax25_socket(patty_ax25 *ax25) {
patty_ax25_sock *sock;
int fd;
if ((sock = malloc(sizeof(*sock))) == NULL) {
goto error_malloc_sock;
@ -92,19 +170,107 @@ int patty_ax25_socket(patty_ax25 *ax25) {
sock_init(sock);
if ((fd = fd_store(ax25, sock)) < 0) {
goto error_fd_store;
sock->fd = ax25->fd++;
if (sock_save(ax25, sock) < 0) {
goto error_sock_save;
}
return fd;
return sock->fd;
error_fd_store:
error_sock_save:
free(sock);
error_malloc_sock:
return -1;
}
int patty_ax25_pton(const char *callsign,
uint8_t ssid,
patty_ax25_addr *addr) {
int i,
end = 0;
for (i=0; i<PATTY_AX25_CALLSIGN_LEN; i++) {
if (callsign[i] == '\0') {
if (i == 0) {
errno = EINVAL;
goto error_invalid_callsign;
}
end = 1;
} else {
if (!PATTY_AX25_ADDRESS_CHAR_VALID(callsign[i])) {
errno = EINVAL;
goto error_invalid_callsign;
}
}
addr->callsign[i] = ((end? ' ': callsign[i]) & 0x7f) << 1;
}
addr->ssid = (ssid & 0x0f) << 1;
return 0;
error_invalid_callsign:
return -1;
}
int patty_ax25_ntop(const patty_ax25_addr *addr,
char *dest,
uint8_t *ssid,
size_t len) {
int i, o, space = 0;
if (addr == NULL || dest == NULL || ssid == NULL) {
errno = EINVAL;
goto error_invalid_args;
}
for (i=0, o=0; i<PATTY_AX25_CALLSIGN_LEN; i++) {
uint8_t c;
if (o == len) {
break;
}
if (PATTY_AX25_ADDRESS_OCTET_LAST(addr->callsign[i])) {
errno = EINVAL;
goto error_invalid_args;
}
c = (addr->callsign[i] & 0xfe) >> 1;
if (!PATTY_AX25_ADDRESS_CHAR_VALID(c)) {
errno = EINVAL;
goto error_invalid_args;
} else if (c == ' ' && !space) {
space = 1;
} else if (space) {
errno = EINVAL;
goto error_invalid_args;
}
dest[o++] = c;
}
dest[o] = '\0';
*ssid = (addr->ssid & 0x1e) >> 1;
return 0;
error_invalid_args:
return -1;
}
int patty_ax25_open(patty_ax25 *ax25, const char *ifname) {
patty_ax25_sock *sock;
@ -118,7 +284,7 @@ int patty_ax25_open(patty_ax25 *ax25, const char *ifname) {
goto error_get_if;
}
return fd_store(ax25, sock);
return sock_save(ax25, sock);
error_get_if:
free(sock);
@ -127,113 +293,87 @@ error_malloc_sock:
return -1;
}
int patty_ax25_bind(patty_ax25 *ax25, int socket, const char *callsign, int ssid) {
int patty_ax25_bind(patty_ax25 *ax25,
int socket,
const char *callsign,
uint8_t ssid) {
patty_ax25_sock *sock;
if ((sock = fd_lookup(ax25, socket)) == NULL) {
goto error_fd_lookup;
if ((sock = sock_get_fd(ax25, socket)) == NULL) {
goto error_sock_get_fd;
}
/*
* If there is already a local address associated with this socket, then
* that's a problem.
*/
if (sock->local != NULL) {
errno = EEXIST;
if (sock->local.callsign[0] != '\0') {
errno = EADDRINUSE;
goto error_exists;
}
if ((sock->local = patty_ax25_address_create(callsign, ssid)) == NULL) {
goto error_address_create;
if (patty_ax25_pton(callsign, ssid, &sock->local) < 0) {
goto error_pton;
}
return 0;
error_address_create:
error_pton:
error_exists:
error_fd_lookup:
error_sock_get_fd:
return -1;
}
int patty_ax25_listen(patty_ax25 *ax25, int socket, const char *callsign, int ssid) {
/*
* Stub
*/
return patty_ax25_bind(ax25, socket, callsign, ssid);
}
int patty_ax25_connect(patty_ax25 *ax25, int socket, const char *callsign, int ssid) {
int patty_ax25_listen(patty_ax25 *ax25,
int socket) {
patty_ax25_sock *sock;
if ((sock = fd_lookup(ax25, socket)) == NULL) {
goto error_fd_lookup;
if ((sock = sock_get_fd(ax25, socket)) == NULL) {
errno = EBADF;
goto error_sock_get_fd;
}
if (sock->remote != NULL) {
if (sock->local.callsign[0] == '\0') {
errno = EINVAL;
goto error_invalid_fd;
}
errno = ENOSYS;
error_invalid_fd:
error_sock_get_fd:
return -1;
}
int patty_ax25_connect(patty_ax25 *ax25,
int socket,
const char *callsign,
uint8_t ssid) {
patty_ax25_sock *sock;
if ((sock = sock_get_fd(ax25, socket)) == NULL) {
goto error_sock_get_fd;
}
if (sock->remote.callsign[0] != '\0') {
errno = EEXIST;
goto error_exists;
}
if ((sock->remote = patty_ax25_address_create(callsign, ssid)) == NULL) {
goto error_address_create;
if (patty_ax25_pton(callsign, ssid, &sock->remote) < 0) {
errno = EINVAL;
goto error_pton;
}
return 0;
error_address_create:
error_pton:
error_exists:
error_fd_lookup:
return -1;
}
static int next_fd_event(patty_ax25 *ax25, enum patty_ax25_event_type *type) {
int fd;
if (ax25->current == 0) {
memcpy(&ax25->fds_pending_read, &ax25->fds, sizeof(ax25->fds));
memcpy(&ax25->fds_pending_write, &ax25->fds, sizeof(ax25->fds));
memcpy(&ax25->fds_pending_error, &ax25->fds, sizeof(ax25->fds));
if (select(ax25->fdmax,
&ax25->fds_pending_read,
&ax25->fds_pending_write,
&ax25->fds_pending_error, NULL) < 0) {
goto error_select;
}
}
for (fd=ax25->current; fd<ax25->fdmax; fd++) {
if (FD_ISSET(fd, &ax25->fds_pending_read)) {
*type = PATTY_AX25_EVENT_RECV;
FD_CLR(fd, &ax25->fds_pending_read);
return fd;
}
if (FD_ISSET(fd, &ax25->fds_pending_write)) {
*type = PATTY_AX25_EVENT_SEND;
FD_CLR(fd, &ax25->fds_pending_write);
return fd;
}
if (FD_ISSET(fd, &ax25->fds_pending_error)) {
*type = PATTY_AX25_EVENT_ERROR;
FD_CLR(fd, &ax25->fds_pending_error);
return fd;
}
}
ax25->current = 0;
return 0;
error_select:
error_sock_get_fd:
return -1;
}

View file

@ -22,14 +22,24 @@ static void usage(int argc, char **argv, const char *message, ...) {
exit(1);
}
static int callsign_fprint(FILE *stream, const patty_ax25_address *address) {
fprintf(stream, "%s", address->callsign);
static int callsign_fprint(FILE *stream, const patty_ax25_addr *addr) {
char buf[7];
uint8_t ssid;
if (address->ssid) {
fprintf(stream, "/%d", address->ssid);
if (patty_ax25_ntop(addr, buf, &ssid, sizeof(buf)) < 0) {
goto error_ntop;
}
fprintf(stream, "%s", buf);
if (ssid) {
fprintf(stream, "/%d", ssid);
}
return 0;
error_ntop:
return -1;
}
#define printable(c) \

View file

@ -108,11 +108,13 @@ void *patty_dict_get(patty_dict *dict, void *key, size_t keysz) {
return slot->value;
}
void *patty_dict_set(patty_dict *dict, void *key, size_t keysz, void *value) {
void *patty_dict_set_with_hash(patty_dict *dict,
void *key,
size_t keysz,
void *value,
uint32_t hash) {
patty_dict_bucket *bucket = &dict->bucket;
uint32_t hash = patty_hash(key, keysz);
int collisions;
for (collisions = 0; collisions < 7; collisions++) {
@ -164,6 +166,14 @@ error_malloc_bucket:
return NULL;
}
void *patty_dict_set(patty_dict *dict, void *key, size_t keysz, void *value) {
return patty_dict_set_with_hash(dict,
key,
keysz,
value,
patty_hash(key, keysz));
}
void *patty_dict_delete(patty_dict *dict, void *key, size_t keysz) {
patty_dict_slot *slot;
void *value;

View file

@ -3,17 +3,11 @@
#include <patty/ax25.h>
static ssize_t decode_station(patty_ax25_address *address,
void *data,
off_t offset) {
static ssize_t validate_station(void *data,
off_t offset) {
int i, space = 0;
uint8_t ssid = ((uint8_t *)data + offset)[6];
/*
* First, unpack each callsign octet, ensuring all are within the 7 bit
* ASCII space and do not have the extended bit set to 1.
*/
for (i=0; i<PATTY_AX25_ADDRESS_CALLSIGN_LEN; i++) {
for (i=0; i<PATTY_AX25_CALLSIGN_LEN; i++) {
uint8_t b = ((uint8_t *)data + offset)[i];
uint8_t c = b >> 1;
@ -23,36 +17,15 @@ static ssize_t decode_station(patty_ax25_address *address,
goto error;
}
if (c == ' ') {
/*
* Take note if we have reached the end of the call sign.
*/
if (c == ' ' && !space) {
space = 1;
} else if (space) {
errno = EINVAL;
address->callsign[i] = '\0';
} else {
/*
* If we have already reached the end of the callsign, and a
* non-space character is encountered, then the address is
* erroneous.
*/
if (space) {
errno = EINVAL;
goto error;
}
address->callsign[i] = c;
goto error;
}
}
/*
* Now, unpack the data from the SSID field.
*/
address->c = PATTY_AX25_ADDRESS_SSID_C(ssid);
address->ssid = PATTY_AX25_ADDRESS_SSID_NUMBER(ssid);
address->last = PATTY_AX25_ADDRESS_OCTET_LAST(ssid);
return PATTY_AX25_ADDRESS_SIZE;
error:
@ -67,12 +40,16 @@ static ssize_t decode_hops(patty_ax25_frame *frame,
int i;
patty_ax25_addr *addr = NULL;
/*
* Try to decode the AX.25-specified maximum number of hops in the current
* Try to count the AX.25-specified maximum number of hops in the current
* frame.
*/
for (i=0; i<PATTY_AX25_MAX_HOPS; i++) {
if ((decoded = decode_station(&frame->repeaters[i], data, offset)) < 0) {
addr = (patty_ax25_addr *)((uint8_t *)data + offset);
if ((decoded = validate_station(data, offset)) < 0) {
goto error;
} else {
offset += decoded;
@ -80,7 +57,7 @@ static ssize_t decode_hops(patty_ax25_frame *frame,
frame->hops++;
if (frame->repeaters[i].last) {
if (PATTY_AX25_ADDRESS_OCTET_LAST(addr->ssid)) {
break;
}
}
@ -89,7 +66,7 @@ static ssize_t decode_hops(patty_ax25_frame *frame,
* If the last hop does not have the address extension bit set, then
* that's a big problem.
*/
if (frame->hops && !frame->repeaters[frame->hops-1].last) {
if (addr && PATTY_AX25_ADDRESS_OCTET_LAST(addr->ssid)) {
errno = EINVAL;
goto error;
@ -107,13 +84,13 @@ static ssize_t decode_address(patty_ax25_frame *frame,
off_t offset = start;
ssize_t decoded;
if ((decoded = decode_station(&frame->dest, data, offset)) < 0) {
if ((decoded = validate_station(data, offset)) < 0) {
goto error;
} else {
offset += decoded;
}
if ((decoded = decode_station(&frame->src, data, offset)) < 0) {
if ((decoded = validate_station(data, offset)) < 0) {
goto error;
} else {
offset += decoded;
@ -137,7 +114,7 @@ static ssize_t decode_address(patty_ax25_frame *frame,
* If the source address is not the final address in the frame, begin
* decoding repeater addresses.
*/
if (!frame->src.last) {
if (!PATTY_AX25_ADDRESS_OCTET_LAST(frame->src.ssid)) {
if ((decoded = decode_hops(frame, data, offset)) < 0) {
goto error;
} else {
@ -259,10 +236,11 @@ error_invalid_args:
}
int patty_ax25_frame_addresed_to(patty_ax25_frame *frame,
char *station,
const char *station,
uint8_t ssid) {
return strncmp(frame->dest.callsign,
station,
PATTY_AX25_ADDRESS_CALLSIGN_LEN) == 0
PATTY_AX25_CALLSIGN_LEN) == 0
&& frame->dest.ssid == ssid;
}

View file

@ -12,7 +12,7 @@ uint32_t patty_hash(void *key, size_t size) {
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);

106
src/if.c
View file

@ -21,7 +21,7 @@ static patty_ax25_if *create_tnc(const char *device) {
goto error_kiss_tnc_open;
}
iface->type = PATTY_AX25_IF_KISS_TNC_TTY;
iface->type = PATTY_AX25_IF_KISS_TNC;
snprintf(iface->name, sizeof(iface->name), "%s%d", prefix, number++);
@ -42,7 +42,7 @@ patty_ax25_if *patty_ax25_if_create(int opts, void *info) {
patty_ax25_if *iface;
switch (PATTY_AX25_IF_OPT_TYPE(opts)) {
case PATTY_AX25_IF_KISS_TNC_TTY: {
case PATTY_AX25_IF_KISS_TNC: {
iface = create_tnc((const char *)info);
break;
@ -59,7 +59,7 @@ patty_ax25_if *patty_ax25_if_create(int opts, void *info) {
goto error;
}
if ((iface->addresses = patty_list_new()) == NULL) {
if ((iface->addrs = patty_list_new()) == NULL) {
goto error;
}
@ -71,7 +71,7 @@ error:
void patty_ax25_if_destroy(patty_ax25_if *iface) {
switch (iface->type) {
case PATTY_AX25_IF_KISS_TNC_TTY: {
case PATTY_AX25_IF_KISS_TNC: {
destroy_tnc(iface); break;
}
@ -79,16 +79,24 @@ void patty_ax25_if_destroy(patty_ax25_if *iface) {
}
}
int patty_ax25_if_each_address(patty_ax25_if *iface, int (*callback)(patty_ax25_address *, void *), void *ctx) {
int patty_ax25_if_each_addr(patty_ax25_if *iface,
int (*callback)(char *, uint8_t, void *), void *ctx) {
patty_list_iterator *iter;
patty_ax25_address *address;
patty_ax25_addr *addr;
if ((iter = patty_list_start(iface->addresses)) == NULL) {
if ((iter = patty_list_start(iface->addrs)) == NULL) {
goto error_list_start;
}
while ((address = patty_list_next(iter)) != NULL) {
if (callback(address, ctx) < 0) {
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) {
goto error_callback;
}
}
@ -98,81 +106,106 @@ int patty_ax25_if_each_address(patty_ax25_if *iface, int (*callback)(patty_ax25_
return 0;
error_callback:
error_ntop:
patty_list_finish(iter);
error_list_start:
return -1;
}
static patty_ax25_address *find_address(patty_ax25_if *iface, const char *callsign, int ssid) {
static patty_ax25_addr *find_addr(patty_ax25_if *iface,
const char *callsign,
uint8_t ssid) {
patty_list_iterator *iter;
patty_ax25_address *address;
patty_ax25_addr *addr;
if ((iter = patty_list_start(iface->addresses)) == NULL) {
if ((iter = patty_list_start(iface->addrs)) == NULL) {
goto error_list_start;
}
while ((address = patty_list_next(iter)) != NULL) {
if (strncmp(address->callsign, callsign, sizeof(address->callsign)) != 0) {
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) {
continue;
}
if (address->ssid != ssid) {
if (addr_ssid != ssid) {
continue;
}
patty_list_finish(iter);
return address;
return addr;
}
patty_list_finish(iter);
error_ntop:
patty_list_finish(iter);
error_list_start:
return NULL;
}
int patty_ax25_if_add_address(patty_ax25_if *iface, const char *callsign, int ssid) {
patty_ax25_address *address;
int patty_ax25_if_add_addr(patty_ax25_if *iface,
const char *callsign,
uint8_t ssid) {
patty_ax25_addr *addr;
if (find_address(iface, callsign, ssid) != NULL) {
if (find_addr(iface, callsign, ssid) != NULL) {
errno = EEXIST;
goto error_exists;
}
if ((address = malloc(sizeof(*address))) == NULL) {
goto error_malloc_address;
if ((addr = malloc(sizeof(*addr))) == NULL) {
goto error_malloc_addr;
}
memset(address, '\0', sizeof(*address));
memcpy(address->callsign, callsign, sizeof(address->callsign));
if (patty_ax25_pton(callsign, ssid, addr) < 0) {
goto error_pton;
}
address->ssid = ssid;
if ((patty_list_append(iface->addresses, address)) == NULL) {
if ((patty_list_append(iface->addrs, addr)) == NULL) {
goto error_list_append;
}
return 0;
error_list_append:
free(address);
error_pton:
free(addr);
error_malloc_address:
error_malloc_addr:
error_exists:
return -1;
}
int patty_ax25_if_delete_address(patty_ax25_if *iface, const char *callsign, int ssid) {
patty_list_item *item = iface->addresses->first;
int patty_ax25_if_delete_addr(patty_ax25_if *iface,
const char *callsign,
uint8_t ssid) {
patty_list_item *item = iface->addrs->first;
int i = 0;
while (item) {
patty_ax25_address *address = item->value;
char buf[7];
uint8_t addr_ssid;
if (strncmp(address->callsign, callsign, sizeof(address->callsign)) == 0 && address->ssid == ssid) {
if (patty_list_splice(iface->addresses, i) == NULL) {
patty_ax25_addr *addr = item->value;
if (patty_ax25_ntop(addr, buf, &addr_ssid, sizeof(buf)) < 0) {
goto error_ntop;
}
if (strncmp(buf, callsign, sizeof(buf)) == 0 && addr_ssid == ssid) {
if (patty_list_splice(iface->addrs, i) == NULL) {
goto error_list_splice;
}
}
@ -184,6 +217,7 @@ int patty_ax25_if_delete_address(patty_ax25_if *iface, const char *callsign, int
return 0;
error_list_splice:
error_ntop:
return -1;
}
@ -209,7 +243,7 @@ error_list_start:
return NULL;
}
int patty_ax25_each_if(patty_ax25 *ax25, int (*callback)(patty_ax25_if *, void *), void *ctx) {
int patty_ax25_if_each(patty_ax25 *ax25, int (*callback)(patty_ax25_if *, void *), void *ctx) {
patty_list_iterator *iter;
patty_ax25_if *iface;
@ -245,7 +279,7 @@ int patty_ax25_add_if(patty_ax25 *ax25, patty_ax25_if *iface) {
}
}
if (patty_dict_set(ax25->fd_lookup, &fd, sizeof(fd), iface) == NULL) {
if (patty_dict_set(ax25->socks, fd, sizeof(fd), iface) == NULL) {
goto error_dict_set;
}
@ -285,7 +319,7 @@ int patty_ax25_delete_if(patty_ax25 *ax25, patty_ax25_if *iface) {
ax25->fdmax--;
}
if (patty_dict_delete(ax25->fd_lookup, &fd, sizeof(fd)) == NULL) {
if (patty_dict_delete(ax25->socks, fd, sizeof(fd)) == NULL) {
goto error_dict_delete;
}
}

View file

@ -22,14 +22,14 @@ static void usage(int argc, char **argv, const char *message, ...) {
exit(1);
}
int address_callback(patty_ax25_address *address, void *ctx) {
return printf(" %s/%d\n", address->callsign, address->ssid);
int addr_callback(char *callsign, uint8_t ssid, void *ctx) {
return printf(" %s/%d\n", callsign, ssid);
}
int iface_callback(patty_ax25_if *iface, void *ctx) {
printf("%s:\n", iface->name);
return patty_ax25_if_each_address(iface, address_callback, ctx);
return patty_ax25_if_each_addr(iface, addr_callback, ctx);
}
int main(int argc, char **argv) {
@ -48,13 +48,13 @@ int main(int argc, char **argv) {
exit(127);
}
if ((iface = patty_ax25_if_create(PATTY_AX25_IF_KISS_TNC_TTY, argv[1])) == NULL) {
if ((iface = patty_ax25_if_create(PATTY_AX25_IF_KISS_TNC, argv[1])) == NULL) {
perror("Unable to create interface");
exit(127);
}
if (patty_ax25_if_add_address(iface, "WX3RKR", 0) < 0) {
if (patty_ax25_if_add_addr(iface, "WX3RKR", 0) < 0) {
perror("Unable to add address");
exit(127);
@ -66,7 +66,7 @@ int main(int argc, char **argv) {
exit(127);
}
patty_ax25_each_if(&ax25, iface_callback, NULL);
patty_ax25_if_each(&ax25, iface_callback, NULL);
patty_ax25_stop(&ax25);