From 4899aa4796a29674bc0e9a7292a19dc27054a70d Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Fri, 7 Aug 2020 18:17:36 -0400 Subject: [PATCH] Implement SOCK_DGRAM Implement PATTY_AX25_SOCK_DGRAM type sockets as a means of exchanging UI frames between stations without requiring calling code to encode and decode UI frames explicitly --- include/patty/ax25/frame.h | 3 +- include/patty/ax25/sock.h | 1 + src/frame.c | 2 +- src/server.c | 56 +++++++++++++++++++---------- src/sock.c | 72 +++++++++++++++++++++++++------------- 5 files changed, 89 insertions(+), 45 deletions(-) diff --git a/include/patty/ax25/frame.h b/include/patty/ax25/frame.h index ba41e44..72ea6b8 100644 --- a/include/patty/ax25/frame.h +++ b/include/patty/ax25/frame.h @@ -59,8 +59,7 @@ enum patty_ax25_frame_type { PATTY_AX25_FRAME_FRMR = 0x87, PATTY_AX25_FRAME_UI = 0x03, PATTY_AX25_FRAME_XID = 0xaf, - PATTY_AX25_FRAME_TEST = 0xe3, - PATTY_AX25_FRAME_UNKNOWN = 0xff + PATTY_AX25_FRAME_TEST = 0xe3 }; typedef struct _patty_ax25_frame { diff --git a/include/patty/ax25/sock.h b/include/patty/ax25/sock.h index c197c49..e45994c 100644 --- a/include/patty/ax25/sock.h +++ b/include/patty/ax25/sock.h @@ -39,6 +39,7 @@ enum patty_ax25_sock_type { PATTY_AX25_SOCK_STREAM, + PATTY_AX25_SOCK_DGRAM, PATTY_AX25_SOCK_RAW }; diff --git a/src/frame.c b/src/frame.c index f187f21..e532ffa 100644 --- a/src/frame.c +++ b/src/frame.c @@ -184,7 +184,7 @@ ssize_t patty_ax25_frame_decode_control(patty_ax25_frame *frame, frame->nr = 0; frame->ns = 0; frame->pf = 0; - frame->type = PATTY_AX25_FRAME_UNKNOWN; + frame->type = 0xff; frame->proto = PATTY_AX25_PROTO_UNKNOWN; frame->info = NULL; frame->infolen = 0; diff --git a/src/server.c b/src/server.c index 1e55b08..8a331c2 100644 --- a/src/server.c +++ b/src/server.c @@ -842,8 +842,6 @@ static int server_connect(patty_ax25_server *server, */ memcpy(&sock->remote, &request.peer, sizeof(request.peer)); - sock->state = PATTY_AX25_SOCK_PENDING_CONNECT; - if (sock_save_remote(server, sock) < 0) { goto error_sock_save_remote; } @@ -852,21 +850,34 @@ static int server_connect(patty_ax25_server *server, goto error_client_save_by_sock; } - /* - * Send an XID frame, to attempt to negotiate AX.25 v2.2 and its default - * parameters. - */ - if (patty_ax25_sock_send_xid(sock, PATTY_AX25_FRAME_COMMAND) < 0) { - return respond_connect(client, -1, errno); + switch (sock->type) { + case PATTY_AX25_SOCK_DGRAM: + sock->state = PATTY_AX25_SOCK_ESTABLISHED; + + break; + + case PATTY_AX25_SOCK_STREAM: + sock->state = PATTY_AX25_SOCK_PENDING_CONNECT; + + /* + * Send an XID frame, to attempt to negotiate AX.25 v2.2 and its + * default parameters. + */ + if (patty_ax25_sock_send_xid(sock, PATTY_AX25_FRAME_COMMAND) < 0) { + return respond_connect(client, -1, errno); + } + + /* + * At this point, we will wait for a DM, FRMR or XID response, which + * will help us determine what version of AX.25 to apply for this + * socket, or whether the peer is not accepting connections. + */ + patty_timer_start(&sock->timer_t1, sock->n_ack); + + default: + break; } - patty_timer_start(&sock->timer_t1, sock->n_ack); - - /* - * At this point, we will wait for a DM, FRMR or XID response, which - * will help us determine what version of AX.25 to apply for this socket, - * or whether the peer is not accepting connections. - */ return 0; error_client_save_by_sock: @@ -1396,6 +1407,17 @@ error_write: return -1; } +static int handle_ui(patty_ax25_server *server, + patty_ax25_if *iface, + patty_ax25_sock *sock, + patty_ax25_frame *frame) { + if (sock == NULL || sock->type != PATTY_AX25_SOCK_DGRAM) { + return 0; + } + + return write(sock->fd, frame->info, frame->infolen); +} + static int handle_disc(patty_ax25_server *server, patty_ax25_if *iface, patty_ax25_sock *sock, @@ -1690,6 +1712,7 @@ static int handle_frame(patty_ax25_server *server, switch (frame.type) { case PATTY_AX25_FRAME_I: return handle_i(server, iface, sock, &frame); + case PATTY_AX25_FRAME_UI: return handle_ui(server, iface, sock, &frame); case PATTY_AX25_FRAME_RR: return handle_rr(server, sock, &frame); case PATTY_AX25_FRAME_RNR: return handle_rnr(server, sock, &frame); case PATTY_AX25_FRAME_REJ: return handle_rej(server, sock, &frame); @@ -1702,9 +1725,6 @@ static int handle_frame(patty_ax25_server *server, case PATTY_AX25_FRAME_DM: return handle_dm(server, iface, sock, &frame); case PATTY_AX25_FRAME_DISC: return handle_disc(server, iface, sock, &frame); case PATTY_AX25_FRAME_FRMR: return handle_frmr(server, iface, sock, &frame); - - default: - break; } return 0; diff --git a/src/sock.c b/src/sock.c index ea26f63..55471e1 100644 --- a/src/sock.c +++ b/src/sock.c @@ -111,26 +111,28 @@ error_realloc_tx_buf: return -1; } -static patty_ax25_sock *init_raw(patty_ax25_sock *sock) { - if (bind_pty(sock) < 0) { - goto error_bind_pty; - } +static patty_ax25_sock *init_dgram(patty_ax25_sock *sock, + enum patty_ax25_proto proto) { + sock->proto = proto; + sock->type = PATTY_AX25_SOCK_DGRAM; + return sock; +} + +static patty_ax25_sock *init_raw(patty_ax25_sock *sock) { if ((sock->raw = patty_kiss_tnc_new_fd(sock->fd)) == NULL) { goto error_kiss_tnc_new_fd; } sock->proto = PATTY_AX25_PROTO_NONE; sock->type = PATTY_AX25_SOCK_RAW; + sock->state = PATTY_AX25_SOCK_ESTABLISHED; return sock; error_kiss_tnc_new_fd: (void)close(sock->fd); -error_bind_pty: - free(sock); - return NULL; } @@ -144,11 +146,20 @@ patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_proto proto, memset(sock, '\0', sizeof(*sock)); - if (type == PATTY_AX25_SOCK_RAW) { - return init_raw(sock); + if (bind_pty(sock) < 0) { + goto error_bind_pty; } - patty_ax25_sock_init(sock); + switch (type) { + case PATTY_AX25_SOCK_DGRAM: + return init_dgram(sock, proto); + + case PATTY_AX25_SOCK_RAW: + return init_raw(sock); + + case PATTY_AX25_SOCK_STREAM: + patty_ax25_sock_init(sock); + } sock->proto = proto; sock->type = type; @@ -160,18 +171,14 @@ patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_proto proto, goto error_init_bufs; } - if (bind_pty(sock) < 0) { - goto error_bind_pty; - } - return sock; -error_bind_pty: error_init_bufs: if (sock->tx_slots) free(sock->tx_slots); if (sock->rx_buf) free(sock->rx_buf); if (sock->tx_buf) free(sock->tx_buf); +error_bind_pty: free(sock); error_malloc_sock: @@ -577,6 +584,10 @@ static uint16_t control_i(patty_ax25_sock *sock, int flag) { } } +static uint16_t control_ui(int flag) { + return PATTY_AX25_FRAME_UI | (flag << 4); +} + static uint16_t control_s(patty_ax25_sock *sock, enum patty_ax25_frame_type type, int flag) { @@ -719,24 +730,37 @@ ssize_t patty_ax25_sock_write(patty_ax25_sock *sock, size_t len) { uint16_t control; - if (sock->type == PATTY_AX25_SOCK_RAW) { - return patty_ax25_if_send(sock->iface, buf, len); - } - if (sock->mode == PATTY_AX25_SOCK_DM) { errno = EBADF; goto error_invalid_mode; } - control = control_i(sock, 0); + switch (sock->type) { + case PATTY_AX25_SOCK_STREAM: + control = control_i(sock, 0); - if (frame_send(sock, PATTY_AX25_FRAME_COMMAND, control, buf, len) < 0) { - goto error_frame_send; + if (frame_send(sock, PATTY_AX25_FRAME_COMMAND, control, buf, len) < 0) { + goto error_frame_send; + } + + patty_ax25_sock_vs_incr(sock); + + break; + + case PATTY_AX25_SOCK_DGRAM: + control = control_ui(0); + + if (frame_send(sock, PATTY_AX25_FRAME_COMMAND, control, buf, len) < 0) { + goto error_frame_send; + } + + break; + + case PATTY_AX25_SOCK_RAW: + return patty_ax25_if_send(sock->iface, buf, len); } - patty_ax25_sock_vs_incr(sock); - return len; error_frame_send: