From b9c3568c4334f48a4413e1e8bf485b44ed5ed60a Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Sun, 28 Jun 2020 18:11:49 -0400 Subject: [PATCH] This is a slog with no real end --- include/patty/ax25/frame.h | 18 +++--- include/patty/ax25/sock.h | 24 +++++++- src/frame.c | 51 +++++++++-------- src/server.c | 2 +- src/sock.c | 109 ++++++++++++++++++++++++++++++------- 5 files changed, 148 insertions(+), 56 deletions(-) diff --git a/include/patty/ax25/frame.h b/include/patty/ax25/frame.h index e03400e..cb1582a 100644 --- a/include/patty/ax25/frame.h +++ b/include/patty/ax25/frame.h @@ -7,10 +7,10 @@ #define PATTY_AX25_FRAME_DEFAULT_MAXLEN 256 #define PATTY_AX25_FRAME_DEFAULT_WINDOW 8 -#define PATTY_AX25_FRAME_SIZE(hops, mode, infolen) \ - ((sizeof(patty_ax25_addr) * (2 + hops)) \ - + (mode == PATTY_AX25_SOCK_SABME? 2: 1) \ - + (infolen > 0? 1 + infolen: 0)) +#define PATTY_AX25_FRAME_SIZE(format, hops, c, infolen) \ + (((2 + hops) * sizeof(patty_ax25_addr)) \ + + (format == PATTY_AX25_FRAME_EXTENDED? 2: 1) \ + + (PATTY_AX25_CONTROL_INFO(c)? 1 + infolen: 0)) enum patty_ax25_frame_format { PATTY_AX25_FRAME_NORMAL, @@ -68,6 +68,10 @@ ssize_t patty_ax25_frame_decode(patty_ax25_frame *frame, ssize_t patty_ax25_frame_encode(patty_ax25_frame *frame, void *buf, enum patty_ax25_frame_format format, + uint16_t control, + uint8_t proto, + void *info, + size_t infolen, size_t len); ssize_t patty_ax25_frame_encode_reply_to(patty_ax25_frame *frame, @@ -88,10 +92,4 @@ enum patty_ax25_frame_cr patty_ax25_frame_cr(patty_ax25_frame *frame); ssize_t patty_ax25_frame_info(patty_ax25_frame *frame, void **info); -void patty_ax25_frame_set(patty_ax25_frame *frame, - uint16_t control, - uint8_t proto, - void *info, - size_t infolen); - #endif /* _PATTY_AX25_FRAME_H */ diff --git a/include/patty/ax25/sock.h b/include/patty/ax25/sock.h index 0b42b88..1022e9f 100644 --- a/include/patty/ax25/sock.h +++ b/include/patty/ax25/sock.h @@ -51,10 +51,32 @@ typedef struct _patty_ax25_sock { unsigned int hops; } patty_ax25_sock; +#define PATTY_AX25_SOCK_CONTROL_SABM(sock, flag) \ + (((sock->seq_recv & 07) << 7) | (flag << 4) | (sock->seq_send & 07)) + +#define PATTY_AX25_SOCK_CONTROL_SABME(sock, flag) \ + (((sock->seq_recv & 0x7f) << 15) | (flag << 7) | (sock->seq_send & 0x7f)) + +#define PATTY_AX25_SOCK_CONTROL(sock, flag) \ + (sock->mode == PATTY_AX25_SOCK_SABME? \ + PATTY_AX25_SOCK_CONTROL_SABME(sock, flag): \ + PATTY_AX25_SOCK_CONTROL_SABM(sock, flag)) + patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_sock_type type); void patty_ax25_sock_destroy(patty_ax25_sock *sock); -int patty_ax25_sock_send_sabm(patty_ax25_sock *sock); +ssize_t patty_ax25_sock_send(patty_ax25_sock *sock, + uint16_t control, + uint8_t proto, + void *info, + size_t infolen); + +ssize_t patty_ax25_sock_send_sabm(patty_ax25_sock *sock, int poll); + +ssize_t patty_ax25_sock_write(patty_ax25_sock *sock, + uint8_t proto, + void *buf, + size_t len); #endif /* _PATTY_AX25_SOCK_H */ diff --git a/src/frame.c b/src/frame.c index 8783f8b..4d5def2 100644 --- a/src/frame.c +++ b/src/frame.c @@ -201,36 +201,42 @@ error_decode: return -1; } -static ssize_t encode_address(patty_ax25_frame *frame, - void *dest, +static ssize_t encode_address(void *buf, + patty_ax25_addr *dest, + patty_ax25_addr *src, + patty_ax25_addr *repeaters, + unsigned int hops, size_t len) { - size_t i, - offset = 0, - hops = frame->hops > PATTY_AX25_MAX_HOPS? - PATTY_AX25_MAX_HOPS: frame->hops; + size_t offset = 0; + unsigned int i; - if ((2 + hops) * sizeof(patty_ax25_addr) > len) { + if (hops > PATTY_AX25_MAX_HOPS) { + hops = PATTY_AX25_MAX_HOPS; + } + + if (len < (2 + hops) * sizeof(patty_ax25_addr)) { goto error_toobig; } - memcpy((uint8_t *)dest + offset, &frame->dest, sizeof(patty_ax25_addr)); + memcpy((uint8_t *)dest + offset, &dest, sizeof(patty_ax25_addr)); offset += sizeof(patty_ax25_addr); ((uint8_t *)dest)[offset-1] &= ~1; - memcpy((uint8_t *)dest + offset, &frame->src, sizeof(patty_ax25_addr)); + memcpy((uint8_t *)dest + offset, &src, sizeof(patty_ax25_addr)); offset += sizeof(patty_ax25_addr); ((uint8_t *)dest)[offset-1] &= ~1; for (i=0; irepeaters[i].callsign[0] == '\0') { + if (repeaters[i].callsign[0] == '\0') { break; } memcpy((uint8_t *)dest + offset, - &frame->repeaters[i], + &repeaters[i], sizeof(patty_ax25_addr)); offset += sizeof(patty_ax25_addr); + ((uint8_t *)dest)[offset-1] &= ~1; } ((uint8_t *)dest)[offset-1] |= 1; @@ -271,6 +277,7 @@ static ssize_t encode_reply_address(patty_ax25_frame *frame, sizeof(patty_ax25_addr)); offset += sizeof(patty_ax25_addr); + ((uint8_t *)dest)[offset-1] &= ~1; } ((uint8_t *)dest)[offset-1] |= 1; @@ -284,10 +291,19 @@ error_toobig: ssize_t patty_ax25_frame_encode(patty_ax25_frame *frame, void *buf, enum patty_ax25_frame_format format, + uint16_t control, + uint8_t proto, + void *info, + size_t infolen, size_t len) { size_t offset = 0; - offset = encode_address(frame, buf, len); + offset = encode_address(buf, + &frame->dest, + &frame->src, + frame->repeaters, + frame->hops, + len); switch (format) { case PATTY_AX25_FRAME_NORMAL: @@ -402,14 +418,3 @@ ssize_t patty_ax25_frame_info(patty_ax25_frame *frame, error_invalid_args: return -1; } - -void patty_ax25_frame_set(patty_ax25_frame *frame, - uint16_t control, - uint8_t proto, - void *info, - size_t infolen) { - frame->control = control; - frame->proto = proto; - frame->info = info; - frame->infolen = infolen; -} diff --git a/src/server.c b/src/server.c index 003c299..6412243 100644 --- a/src/server.c +++ b/src/server.c @@ -834,7 +834,7 @@ static int server_connect(patty_ax25_server *server, * timeout has been exceeded or the peer has sent a UA frame to * acknowledge and establish the connection. */ - if (patty_ax25_sock_send_sabm(sock) < 0) { + if (patty_ax25_sock_send_sabm(sock, 1) < 0) { response.ret = -1; response.eno = EIO; diff --git a/src/sock.c b/src/sock.c index 3755880..df95eef 100644 --- a/src/sock.c +++ b/src/sock.c @@ -29,37 +29,104 @@ void patty_ax25_sock_destroy(patty_ax25_sock *sock) { free(sock); } -static size_t copy_addr_to_buf(patty_ax25_sock *sock, uint8_t *buf, size_t offset) { - size_t i; +static size_t copy_addr_to_tx_buf(patty_ax25_sock *sock) { + void *buf = sock->iface->tx_buf; - memcpy(&buf[offset], &sock->remote, sizeof(patty_ax25_addr)); - offset += sizeof(patty_ax25_addr); - buf[offset-1] &= ~1; + unsigned int i; - memcpy(&buf[offset], &sock->local, sizeof(patty_ax25_addr)); + size_t offset = 0; + + memcpy((uint8_t *)buf + offset, &sock->remote, sizeof(patty_ax25_addr)); offset += sizeof(patty_ax25_addr); - buf[offset-1] &= ~1; + ((uint8_t *)buf)[offset-1] &= ~1; + + memcpy((uint8_t *)buf + offset, &sock->local, sizeof(patty_ax25_addr)); + offset += sizeof(patty_ax25_addr); + ((uint8_t *)buf)[offset-1] &= ~1; for (i=0; ihops; i++) { - memcpy(&buf[offset], &sock->repeaters[i], sizeof(patty_ax25_addr)); + memcpy((uint8_t *)buf + offset, &sock->repeaters[i], sizeof(patty_ax25_addr)); offset += sizeof(patty_ax25_addr); + ((uint8_t *)buf)[offset-1] &= ~1; } - buf[offset - 1] |= 0x01; + ((uint8_t *)buf)[offset-1] |= 1; return offset; } -int patty_ax25_sock_send_sabm(patty_ax25_sock *sock) { - size_t offset = 0; - uint8_t *buf = (uint8_t *)(sock->iface->tx_buf); - - offset = copy_addr_to_buf(sock, buf, offset); - - buf[offset++] = 0x3f; - buf[offset++] = PATTY_AX25_PROTO_NONE; - - return patty_ax25_if_send(sock->iface, - buf, - offset); +static inline int toobig(patty_ax25_sock *sock, + uint16_t control, + size_t infolen) { + return PATTY_AX25_FRAME_SIZE(sock->mode == PATTY_AX25_SOCK_SABME? + PATTY_AX25_FRAME_EXTENDED: + PATTY_AX25_FRAME_NORMAL, + sock->hops, + control, + infolen) > sock->iface->tx_bufsz? 1: 0; +} + +ssize_t patty_ax25_sock_send(patty_ax25_sock *sock, + uint16_t control, + uint8_t proto, + void *info, + size_t infolen) { + size_t offset = 0; + ssize_t len; + + if (toobig(sock, control, infolen)) { + goto error_toobig; + } + + if ((len = copy_addr_to_tx_buf(sock)) < 0) { + goto error_toobig; + } else { + offset += len; + } + + if (sock->mode == PATTY_AX25_SOCK_SABME) { + ((uint8_t *)sock->iface->tx_buf)[offset++] = (control & 0xff00) >> 8; + ((uint8_t *)sock->iface->tx_buf)[offset++] = control & 0x00ff; + } else { + ((uint8_t *)sock->iface->tx_buf)[offset++] = control; + } + + if (PATTY_AX25_CONTROL_INFO(control)) { + ((uint8_t *)sock->iface->tx_buf)[offset++] = proto; + + memcpy((uint8_t *)sock->iface->tx_buf + offset, info, infolen); + offset += infolen; + } + + return offset; + +error_toobig: + return -1; +} + +ssize_t patty_ax25_sock_send_sabm(patty_ax25_sock *sock, int poll) { + return patty_ax25_sock_send(sock, + PATTY_AX25_FRAME_U_SABM + | PATTY_AX25_FRAME_U_POLL, + PATTY_AX25_PROTO_NONE, + NULL, + 0); +} + +ssize_t patty_ax25_sock_write(patty_ax25_sock *sock, + uint8_t proto, + void *buf, + size_t len) { + uint16_t control = sock->mode == PATTY_AX25_SOCK_SABME? + PATTY_AX25_SOCK_CONTROL_SABME(sock, 1): + PATTY_AX25_SOCK_CONTROL_SABM(sock, 1); + + if (patty_ax25_sock_send(sock, control, proto, buf, len) < 0) { + goto error_send; + } + + return len; + +error_send: + return -1; }