Major refactor WIP
This commit is contained in:
parent
b5ed9e9b61
commit
a8db220bbd
14 changed files with 438 additions and 304 deletions
|
@ -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);
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
334
src/ax25.c
334
src/ax25.c
|
@ -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;
|
||||
}
|
||||
|
|
18
src/decode.c
18
src/decode.c
|
@ -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) \
|
||||
|
|
16
src/dict.c
16
src/dict.c
|
@ -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;
|
||||
|
|
64
src/frame.c
64
src/frame.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
106
src/if.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
12
src/iflist.c
12
src/iflist.c
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue