2015-07-20 23:21:45 -05:00
|
|
|
#include <stdlib.h>
|
2015-07-20 22:33:59 -05:00
|
|
|
#include <string.h>
|
2015-07-20 23:21:45 -05:00
|
|
|
#include <errno.h>
|
2015-07-20 22:33:59 -05:00
|
|
|
|
|
|
|
#include <patty/ax25.h>
|
|
|
|
|
|
|
|
int patty_ax25_init(patty_ax25 *ax25) {
|
|
|
|
memset(ax25, '\0', sizeof(*ax25));
|
|
|
|
|
2015-07-24 21:34:11 -05:00
|
|
|
if ((ax25->ifaces = patty_list_new()) == NULL) {
|
|
|
|
goto error_list_new_ifaces;
|
2015-07-20 22:33:59 -05:00
|
|
|
}
|
|
|
|
|
2015-07-26 01:23:23 -05:00
|
|
|
if ((ax25->socks = patty_list_new()) == NULL) {
|
|
|
|
goto error_list_new_socks;
|
2015-07-20 22:33:59 -05:00
|
|
|
}
|
|
|
|
|
2015-07-24 21:34:11 -05:00
|
|
|
if ((ax25->fd_lookup = patty_dict_new()) == NULL) {
|
|
|
|
goto error_dict_new_fd_lookup;
|
2015-07-21 21:49:53 +00:00
|
|
|
}
|
|
|
|
|
2015-07-24 21:34:11 -05:00
|
|
|
ax25->fd = 0;
|
2015-07-21 21:49:53 +00:00
|
|
|
|
2015-07-24 21:34:11 -05:00
|
|
|
return 0;
|
2015-07-21 21:49:53 +00:00
|
|
|
|
2015-07-24 21:34:11 -05:00
|
|
|
error_dict_new_fd_lookup:
|
2015-07-26 01:23:23 -05:00
|
|
|
patty_list_destroy(ax25->socks);
|
2015-07-21 21:49:53 +00:00
|
|
|
|
2015-07-26 01:23:23 -05:00
|
|
|
error_list_new_socks:
|
2015-07-24 21:34:11 -05:00
|
|
|
patty_list_destroy(ax25->ifaces);
|
2015-07-21 21:49:53 +00:00
|
|
|
|
2015-07-24 21:34:11 -05:00
|
|
|
error_list_new_ifaces:
|
|
|
|
return -1;
|
2015-07-21 21:49:53 +00:00
|
|
|
}
|
2015-07-21 23:01:49 -05:00
|
|
|
|
2015-07-28 02:16:56 +00:00
|
|
|
static int destroy_if(patty_ax25_if *iface, void *ctx) {
|
|
|
|
patty_ax25_if_destroy(iface);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-07-24 21:34:11 -05:00
|
|
|
void patty_ax25_stop(patty_ax25 *ax25) {
|
|
|
|
patty_dict_destroy(ax25->fd_lookup);
|
2015-07-26 01:23:23 -05:00
|
|
|
patty_list_destroy(ax25->socks);
|
2015-07-28 02:16:56 +00:00
|
|
|
|
|
|
|
patty_ax25_each_if(ax25, destroy_if, NULL);
|
2015-07-24 21:34:11 -05:00
|
|
|
patty_list_destroy(ax25->ifaces);
|
2015-07-21 23:01:49 -05:00
|
|
|
}
|
2015-07-25 14:43:45 -05:00
|
|
|
|
2015-07-28 02:16:56 +00:00
|
|
|
static void *fd_lookup(patty_ax25 *ax25, int fd) {
|
|
|
|
void *obj;
|
2015-07-25 14:43:45 -05:00
|
|
|
|
2015-07-28 02:16:56 +00:00
|
|
|
if ((obj = patty_dict_get(ax25->fd_lookup, &fd, sizeof(fd))) == NULL) {
|
|
|
|
errno = EBADF;
|
|
|
|
|
|
|
|
goto error_dict_get;
|
2015-07-25 14:43:45 -05:00
|
|
|
}
|
|
|
|
|
2015-07-28 02:16:56 +00:00
|
|
|
return obj;
|
|
|
|
|
|
|
|
error_dict_get:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-07-27 22:41:26 -05:00
|
|
|
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) {
|
2015-07-25 14:43:45 -05:00
|
|
|
goto error_dict_set;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ax25->fd++;
|
|
|
|
|
|
|
|
error_dict_set:
|
2015-07-28 02:16:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-07-28 00:13:43 -05:00
|
|
|
static void sock_init(patty_ax25_sock *sock) {
|
|
|
|
memset(sock, '\0', sizeof(*sock));
|
|
|
|
|
|
|
|
sock->status = PATTY_AX25_SOCK_OPEN;
|
2015-07-29 23:09:01 +00:00
|
|
|
sock->mode = PATTY_AX25_SOCK_DM;
|
2015-07-28 00:13:43 -05:00
|
|
|
sock->n_maxlen = PATTY_AX25_FRAME_DEFAULT_MAXLEN;
|
|
|
|
sock->n_window = PATTY_AX25_FRAME_DEFAULT_WINDOW;
|
|
|
|
}
|
|
|
|
|
2015-07-25 14:47:57 -05:00
|
|
|
int patty_ax25_socket(patty_ax25 *ax25) {
|
|
|
|
patty_ax25_sock *sock;
|
2015-07-28 02:16:56 +00:00
|
|
|
int fd;
|
2015-07-25 14:47:57 -05:00
|
|
|
|
|
|
|
if ((sock = malloc(sizeof(*sock))) == NULL) {
|
|
|
|
goto error_malloc_sock;
|
|
|
|
}
|
|
|
|
|
2015-07-28 00:13:43 -05:00
|
|
|
sock_init(sock);
|
2015-07-28 02:16:56 +00:00
|
|
|
|
|
|
|
if ((fd = fd_store(ax25, sock)) < 0) {
|
|
|
|
goto error_fd_store;
|
2015-07-25 14:47:57 -05:00
|
|
|
}
|
|
|
|
|
2015-07-28 02:16:56 +00:00
|
|
|
return fd;
|
2015-07-25 14:47:57 -05:00
|
|
|
|
2015-07-28 02:16:56 +00:00
|
|
|
error_fd_store:
|
2015-07-25 14:47:57 -05:00
|
|
|
free(sock);
|
|
|
|
|
|
|
|
error_malloc_sock:
|
|
|
|
return -1;
|
|
|
|
}
|
2015-07-25 19:39:35 -05:00
|
|
|
|
2015-07-27 22:41:26 -05:00
|
|
|
int patty_ax25_open(patty_ax25 *ax25, const char *ifname) {
|
|
|
|
patty_ax25_sock *sock;
|
|
|
|
|
|
|
|
if ((sock = malloc(sizeof(*sock))) == NULL) {
|
|
|
|
goto error_malloc_sock;
|
|
|
|
}
|
|
|
|
|
2015-07-28 00:13:43 -05:00
|
|
|
sock_init(sock);
|
2015-07-27 22:41:26 -05:00
|
|
|
|
|
|
|
if ((sock->iface = patty_ax25_get_if(ax25, ifname)) == NULL) {
|
|
|
|
goto error_get_if;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fd_store(ax25, sock);
|
|
|
|
|
|
|
|
error_get_if:
|
|
|
|
free(sock);
|
|
|
|
|
|
|
|
error_malloc_sock:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-07-26 01:35:40 -05:00
|
|
|
int patty_ax25_bind(patty_ax25 *ax25, int socket, const char *callsign, int ssid) {
|
2015-07-25 19:39:35 -05:00
|
|
|
patty_ax25_sock *sock;
|
|
|
|
|
2015-07-28 02:16:56 +00:00
|
|
|
if ((sock = fd_lookup(ax25, socket)) == NULL) {
|
|
|
|
goto error_fd_lookup;
|
2015-07-25 19:39:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2015-07-26 01:23:23 -05:00
|
|
|
* If there is already a local address associated with this socket, then
|
|
|
|
* that's a problem.
|
2015-07-25 19:39:35 -05:00
|
|
|
*/
|
2015-07-26 01:23:23 -05:00
|
|
|
if (sock->local != NULL) {
|
|
|
|
errno = EEXIST;
|
2015-07-25 19:39:35 -05:00
|
|
|
|
2015-07-26 01:23:23 -05:00
|
|
|
goto error_exists;
|
2015-07-25 19:39:35 -05:00
|
|
|
}
|
|
|
|
|
2015-07-26 01:31:38 -05:00
|
|
|
if ((sock->local = patty_ax25_address_create(callsign, ssid)) == NULL) {
|
|
|
|
goto error_address_create;
|
2015-07-25 19:39:35 -05:00
|
|
|
}
|
|
|
|
|
2015-07-26 01:23:23 -05:00
|
|
|
return 0;
|
2015-07-25 19:39:35 -05:00
|
|
|
|
2015-07-26 01:31:38 -05:00
|
|
|
error_address_create:
|
2015-07-26 01:23:23 -05:00
|
|
|
error_exists:
|
2015-07-28 02:16:56 +00:00
|
|
|
error_fd_lookup:
|
2015-07-25 19:39:35 -05:00
|
|
|
return -1;
|
|
|
|
}
|
2015-07-26 01:23:23 -05:00
|
|
|
|
2015-07-26 01:35:40 -05:00
|
|
|
int patty_ax25_listen(patty_ax25 *ax25, int socket, const char *callsign, int ssid) {
|
|
|
|
/*
|
|
|
|
* Stub
|
|
|
|
*/
|
|
|
|
return patty_ax25_bind(ax25, socket, callsign, ssid);
|
|
|
|
}
|
|
|
|
|
2015-07-26 01:23:23 -05:00
|
|
|
int patty_ax25_connect(patty_ax25 *ax25, int socket, const char *callsign, int ssid) {
|
2015-07-26 01:26:59 -05:00
|
|
|
patty_ax25_sock *sock;
|
|
|
|
|
2015-07-28 02:16:56 +00:00
|
|
|
if ((sock = fd_lookup(ax25, socket)) == NULL) {
|
|
|
|
goto error_fd_lookup;
|
2015-07-26 01:26:59 -05:00
|
|
|
}
|
|
|
|
|
2015-07-26 01:31:38 -05:00
|
|
|
if (sock->remote != NULL) {
|
|
|
|
errno = EEXIST;
|
2015-07-26 01:26:59 -05:00
|
|
|
|
2015-07-26 01:31:38 -05:00
|
|
|
goto error_exists;
|
|
|
|
}
|
2015-07-26 01:26:59 -05:00
|
|
|
|
2015-07-26 01:31:38 -05:00
|
|
|
if ((sock->remote = patty_ax25_address_create(callsign, ssid)) == NULL) {
|
|
|
|
goto error_address_create;
|
|
|
|
}
|
2015-07-26 01:26:59 -05:00
|
|
|
|
2015-07-26 01:23:23 -05:00
|
|
|
return 0;
|
2015-07-26 01:26:59 -05:00
|
|
|
|
2015-07-26 01:31:38 -05:00
|
|
|
error_address_create:
|
|
|
|
error_exists:
|
2015-07-28 02:16:56 +00:00
|
|
|
error_fd_lookup:
|
2015-07-26 01:26:59 -05:00
|
|
|
return -1;
|
2015-07-26 01:23:23 -05:00
|
|
|
}
|
2015-07-29 22:28:44 -05:00
|
|
|
|
|
|
|
int patty_ax25_next_event(patty_ax25 *ax25, enum patty_ax25_event *ev) {
|
|
|
|
return 0;
|
|
|
|
}
|