From 803ebd0048e26928ec743da6b78f5c5d170d8502 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Tue, 21 Jul 2020 01:33:00 -0400 Subject: [PATCH] Simplify frame encoding Changes: * Add 'format' member to patty_ax25_frame * Drop 'format' argument in patty_ax25_encode_reply_to() * Drop 'format' argument in patty_ax25_encode() * Consolidate private functions for encoding frame addresses to one much simpler function to perform encoding; simplify encoding of addresses in frames sent in reply to other frames --- include/patty/ax25/frame.h | 3 +- src/frame.c | 127 +++++++++++++++---------------------- src/server.c | 1 - 3 files changed, 51 insertions(+), 80 deletions(-) diff --git a/include/patty/ax25/frame.h b/include/patty/ax25/frame.h index f30c1a1..ba41e44 100644 --- a/include/patty/ax25/frame.h +++ b/include/patty/ax25/frame.h @@ -74,6 +74,7 @@ typedef struct _patty_ax25_frame { uint8_t nr, ns, pf; enum patty_ax25_frame_cr cr; enum patty_ax25_frame_type type; + enum patty_ax25_frame_format format; enum patty_ax25_version version; uint8_t proto; @@ -121,7 +122,6 @@ ssize_t patty_ax25_frame_decode_xid(patty_ax25_params *params, size_t len); ssize_t patty_ax25_frame_encode(patty_ax25_frame *frame, - enum patty_ax25_frame_format format, void *buf, size_t len); @@ -131,7 +131,6 @@ ssize_t patty_ax25_frame_encode_xid(patty_ax25_params *params, ssize_t patty_ax25_frame_encode_reply_to(patty_ax25_frame *frame, patty_ax25_frame *reply, - enum patty_ax25_frame_format format, void *buf, size_t len); diff --git a/src/frame.c b/src/frame.c index e729c60..20e3394 100644 --- a/src/frame.c +++ b/src/frame.c @@ -204,6 +204,8 @@ ssize_t patty_ax25_frame_decode_control(patty_ax25_frame *frame, break; } + frame->format = format; + if (PATTY_AX25_FRAME_CONTROL_I(frame->control)) { frame->type = PATTY_AX25_FRAME_I; frame->nr = decode_nr(frame->control, format); @@ -392,78 +394,49 @@ error_decode_xid_group: return -1; } -static ssize_t encode_address(void *buf, - patty_ax25_addr *dest, - patty_ax25_addr *src, - patty_ax25_addr *repeaters, - unsigned int hops, +static ssize_t encode_address(patty_ax25_frame *frame, + void *dest, + int reply, size_t len) { + uint8_t *buf = (uint8_t *)dest; size_t offset = 0; + + uint8_t flags_remote = 0x00, + flags_local = 0x00; + unsigned int i; - if (hops > PATTY_AX25_MAX_HOPS) { - hops = PATTY_AX25_MAX_HOPS; - } + if ((2 + frame->hops) * sizeof(patty_ax25_addr) > len) { + errno = EOVERFLOW; - if (len < (2 + hops) * sizeof(patty_ax25_addr)) { goto error_toobig; } - memcpy((uint8_t *)dest + offset, &dest, sizeof(patty_ax25_addr)); - offset += sizeof(patty_ax25_addr); - ((uint8_t *)dest)[offset-1] &= ~1; + switch (frame->cr) { + case PATTY_AX25_FRAME_COMMAND: flags_remote = 0x80; break; + case PATTY_AX25_FRAME_RESPONSE: flags_local = 0x80; break; + case PATTY_AX25_FRAME_OLD: break; + } - memcpy((uint8_t *)dest + offset, &src, sizeof(patty_ax25_addr)); - offset += sizeof(patty_ax25_addr); - ((uint8_t *)dest)[offset-1] &= ~1; + if (reply) { + offset += patty_ax25_addr_copy(buf + offset, &frame->src, flags_local); + offset += patty_ax25_addr_copy(buf + offset, &frame->dest, flags_remote); - for (i=0; ihops; i++) { + int n = frame->hops - 1 - i; + + offset += patty_ax25_addr_copy(buf + offset, &frame->repeaters[n], 0); } + } else { + offset += patty_ax25_addr_copy(buf + offset, &frame->dest, flags_remote); + offset += patty_ax25_addr_copy(buf + offset, &frame->src, flags_local); - memcpy((uint8_t *)dest + offset, - &repeaters[i], - sizeof(patty_ax25_addr)); - - offset += sizeof(patty_ax25_addr); - ((uint8_t *)dest)[offset-1] &= ~1; - } - - ((uint8_t *)dest)[offset-1] |= 1; - - return offset; - -error_toobig: - return -1; -} - -static ssize_t encode_reply_address(patty_ax25_frame *frame, - void *dest, - size_t len) { - size_t i, - offset = 0, - hops = frame->hops > PATTY_AX25_MAX_HOPS? - PATTY_AX25_MAX_HOPS: frame->hops; - - uint8_t *buf = dest; - - if ((2 + hops) * sizeof(patty_ax25_addr) > len) { - goto error_toobig; - } - - offset += patty_ax25_addr_copy(buf + offset, &frame->src, 0x00); - offset += patty_ax25_addr_copy(buf + offset, &frame->dest, 0x80); - - for (i=0; irepeaters[i].callsign[0] == '\0') { - break; + for (i=0; ihops; i++) { + offset += patty_ax25_addr_copy(buf + offset, &frame->repeaters[i], 0); } - - offset += patty_ax25_addr_copy(buf + offset, &frame->repeaters[hops-1-i], 0); } - ((uint8_t *)dest)[offset-1] |= 1; + ((uint8_t *)buf)[offset-1] |= 1; return offset; @@ -472,39 +445,41 @@ error_toobig: } ssize_t patty_ax25_frame_encode(patty_ax25_frame *frame, - enum patty_ax25_frame_format format, void *buf, size_t len) { - size_t offset; + size_t offset = 0; + ssize_t encoded; - if ((offset = encode_address(buf, - &frame->dest, - &frame->src, - frame->repeaters, - frame->hops, - len)) < 0) { - goto error_toobig; + if ((encoded = encode_address(frame, buf, 0, len)) < 0) { + goto error_encode_address; + } else { + offset += encoded; } - switch (format) { + switch (frame->format) { case PATTY_AX25_FRAME_NORMAL: ((uint8_t *)buf)[offset++] = frame->control; break; case PATTY_AX25_FRAME_EXTENDED: - ((uint8_t *)buf)[offset++] = (frame->control & 0xff00) >> 8; - ((uint8_t *)buf)[offset++] = frame->control & 0xf00ff; + ((uint8_t *)buf)[offset++] = frame->control & 0x00ff; + + if (!PATTY_AX25_FRAME_CONTROL_U(frame->control)) { + ((uint8_t *)buf)[offset++] = (frame->control & 0xff00) >> 8; + } break; } - if (PATTY_AX25_FRAME_CONTROL_I(frame->control) || PATTY_AX25_FRAME_CONTROL_UI(frame->control)) { + if (frame->info && frame->infolen) { if (1 + offset + frame->infolen > len) { goto error_toobig; } - ((uint8_t *)buf)[offset++] = frame->proto; + if (PATTY_AX25_FRAME_CONTROL_I(frame->control) || PATTY_AX25_FRAME_CONTROL_UI(frame->control)) { + ((uint8_t *)buf)[offset++] = frame->proto; + } memcpy((uint8_t *)buf + offset, frame->info, frame->infolen); @@ -514,6 +489,7 @@ ssize_t patty_ax25_frame_encode(patty_ax25_frame *frame, return offset; error_toobig: +error_encode_address: return -1; } @@ -620,16 +596,13 @@ error_encode_xid_param: ssize_t patty_ax25_frame_encode_reply_to(patty_ax25_frame *frame, patty_ax25_frame *reply, - enum patty_ax25_frame_format format, void *buf, size_t len) { size_t offset; - if ((offset = encode_reply_address(frame, buf, len)) < 0) { - goto error_toobig; - } + offset = encode_address(frame, buf, 1, len); - switch (format) { + switch (reply->format) { case PATTY_AX25_FRAME_NORMAL: ((uint8_t *)buf)[offset++] = reply->control; @@ -645,7 +618,7 @@ ssize_t patty_ax25_frame_encode_reply_to(patty_ax25_frame *frame, break; } - if (PATTY_AX25_FRAME_CONTROL_I(reply->control)) { + if (PATTY_AX25_FRAME_CONTROL_I(reply->control) || PATTY_AX25_FRAME_CONTROL_UI(reply->control)) { if (len < 1 + offset + reply->infolen) { goto error_toobig; } diff --git a/src/server.c b/src/server.c index fc210f5..68fe308 100644 --- a/src/server.c +++ b/src/server.c @@ -1000,7 +1000,6 @@ static int reply_to(patty_ax25_if *iface, if ((len = patty_ax25_frame_encode_reply_to(frame, reply, - PATTY_AX25_FRAME_NORMAL, iface->tx_buf, iface->mtu)) < 0) { goto error_toobig;