From 18134dde49d2ff5028dc2967657a87a5f9ff5b32 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Thu, 16 Jul 2020 23:02:38 -0400 Subject: [PATCH] Implement patty_ax25_frame_decode_xid() Implement patty_ax25_frame_decode_xid() to decode XID frame data, adhering to the basic structure of ISO 8885 as closely as possible --- include/patty/ax25/frame.h | 36 ++++++++++++++++++++++++++ src/frame.c | 53 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/include/patty/ax25/frame.h b/include/patty/ax25/frame.h index 576f552..ae6131b 100644 --- a/include/patty/ax25/frame.h +++ b/include/patty/ax25/frame.h @@ -82,6 +82,37 @@ typedef struct _patty_ax25_frame { size_t infolen; } patty_ax25_frame; +#pragma pack(push) +#pragma pack(1) + +typedef struct _patty_ax25_frame_xid_element { + uint8_t format, + group; + + uint16_t len; +} patty_ax25_frame_xid_element; + +typedef struct _patty_ax25_frame_xid_param { + uint8_t id, len; +} patty_ax25_frame_xid_param; + +enum patty_ax25_frame_xid_param_type { + PATTY_AX25_FRAME_XID_PARAM_CLASS = 2, + PATTY_AX25_FRAME_XID_PARAM_HDLC = 3, + PATTY_AX25_FRAME_XID_PARAM_INFO_TX = 5, + PATTY_AX25_FRAME_XID_PARAM_INFO_RX = 6, + PATTY_AX25_FRAME_XID_PARAM_WINDOW_TX = 7, + PATTY_AX25_FRAME_XID_PARAM_WINDOW_RX = 8, + PATTY_AX25_FRAME_XID_PARAM_ACK = 9 +}; + +#pragma pack(pop) + +typedef int (*patty_ax25_frame_xid_callback)(enum patty_ax25_frame_xid_param_type type, + size_t len, + uint8_t *data, + void *ctx); + ssize_t patty_ax25_frame_decode_address(patty_ax25_frame *frame, void *buf, size_t len); @@ -92,6 +123,11 @@ ssize_t patty_ax25_frame_decode_control(patty_ax25_frame *frame, size_t offset, size_t len); +ssize_t patty_ax25_frame_decode_xid(patty_ax25_frame_xid_callback callback, + void *data, + size_t offset, + size_t len, + void *ctx); ssize_t patty_ax25_frame_encode(patty_ax25_frame *frame, enum patty_ax25_frame_format format, diff --git a/src/frame.c b/src/frame.c index 71c4ed3..dc17ca5 100644 --- a/src/frame.c +++ b/src/frame.c @@ -271,6 +271,59 @@ error: return -1; } +ssize_t patty_ax25_frame_decode_xid(patty_ax25_frame_xid_callback callback, + void *data, + size_t offset, + size_t len, + void *ctx) { + size_t start = offset; + + patty_ax25_frame_xid_element *elem = ((patty_ax25_frame_xid_element *) + (uint8_t *)data + offset); + + if (elem->format != 0x82 || elem->group != 0x80) { + errno = EIO; + + goto error; + } + + if (be16toh(elem->len) != len - offset) { + errno = EIO; + + goto error; + } + + offset += sizeof(*elem); + + while (offset < start + len) { + patty_ax25_frame_xid_param *param = (patty_ax25_frame_xid_param *) + ((uint8_t *)data + offset); + + if (callback(param->id, + (size_t)param->len, + (uint8_t *)(param + 1), + ctx) < 0) { + goto error_callback; + } + + offset += sizeof(*param) + param->len; + } + + if (offset != start + len) { + errno = EIO; + + goto error; + } + + errno = 0; + + return offset - start; + +error_callback: +error: + return -1; +} + static ssize_t encode_address(void *buf, patty_ax25_addr *dest, patty_ax25_addr *src,