Refactor patty_ax25_frame_decode_xid()

Refactor patty_ax25_frame_decode_xid() to support the remote possibility
of multiple ISO 8885 groups
This commit is contained in:
XANTRONIX Development 2020-07-17 16:38:32 -04:00 committed by XANTRONIX Industrial
parent 199d641d6f
commit c7410cb2a4
2 changed files with 99 additions and 37 deletions

View file

@ -79,21 +79,13 @@ typedef struct _patty_ax25_frame {
size_t infolen; size_t infolen;
} patty_ax25_frame; } patty_ax25_frame;
#pragma pack(push) enum patty_ax25_frame_xid_group_format {
#pragma pack(1) PATTY_AX25_FRAME_XID_GROUP_ISO8885 = 0x82
};
typedef struct _patty_ax25_frame_xid_element { enum patty_ax25_frame_xid_group_type {
uint8_t format, PATTY_AX25_FRAME_XID_GROUP_PARAMS = 0x80
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;
#pragma pack(pop)
enum patty_ax25_frame_xid_param_type { enum patty_ax25_frame_xid_param_type {
PATTY_AX25_FRAME_XID_PARAM_CLASS = 2, PATTY_AX25_FRAME_XID_PARAM_CLASS = 2,
@ -105,9 +97,40 @@ enum patty_ax25_frame_xid_param_type {
PATTY_AX25_FRAME_XID_PARAM_ACK = 9 PATTY_AX25_FRAME_XID_PARAM_ACK = 9
}; };
enum patty_ax25_frame_xid_param_class_flags {
PATTY_AX25_FRAME_XID_PARAM_CLASS_ABM = (1 << 1),
PATTY_AX25_FRAME_XID_PARAM_CLASS_HALF_DUPLEX = (1 << 6),
PATTY_AX25_FRAME_XID_PARAM_CLASS_FULL_DUPLEX = (1 << 7)
};
enum patty_ax25_frame_xid_param_hdlc_flags {
PATTY_AX25_FRAME_XID_PARAM_HDLC_REJ = (1 << 1),
PATTY_AX25_FRAME_XID_PARAM_HDLC_SREJ = (1 << 2),
PATTY_AX25_FRAME_XID_PARAM_HDLC_XADDR = (1 << 8),
PATTY_AX25_FRAME_XID_PARAM_HDLC_MODULO_8 = (1 << 11),
PATTY_AX25_FRAME_XID_PARAM_HDLC_MODULO_128 = (1 << 12),
PATTY_AX25_FRAME_XID_PARAM_HDLC_TEST = (1 << 14),
PATTY_AX25_FRAME_XID_PARAM_HDLC_SYNC_TX = (1 << 18)
};
#pragma pack(push)
#pragma pack(1)
typedef struct _patty_ax25_frame_xid_group {
uint8_t format,
type;
uint16_t len;
} patty_ax25_frame_xid_group;
typedef struct _patty_ax25_frame_xid_param {
uint8_t id, len;
} patty_ax25_frame_xid_param;
#pragma pack(pop)
typedef int (*patty_ax25_frame_xid_callback)(enum patty_ax25_frame_xid_param_type type, typedef int (*patty_ax25_frame_xid_callback)(enum patty_ax25_frame_xid_param_type type,
size_t len, uint32_t value,
uint8_t *data,
void *ctx); void *ctx);
ssize_t patty_ax25_frame_decode_address(patty_ax25_frame *frame, ssize_t patty_ax25_frame_decode_address(patty_ax25_frame *frame,

View file

@ -271,37 +271,45 @@ error:
return -1; return -1;
} }
ssize_t patty_ax25_frame_decode_xid(patty_ax25_frame_xid_callback callback, ssize_t decode_xid_group(patty_ax25_frame_xid_callback callback,
void *data, void *data,
size_t offset, size_t offset,
size_t len, size_t len,
void *ctx) { void *ctx) {
size_t start = offset; patty_ax25_frame_xid_group *group = (patty_ax25_frame_xid_group *)
patty_ax25_frame_xid_element *elem = (patty_ax25_frame_xid_element *)
((uint8_t *)data + offset); ((uint8_t *)data + offset);
if (elem->format != 0x82 || elem->group != 0x80) { size_t grouplen,
errno = EIO; start = offset;
if (len - offset < sizeof(*group)) {
goto error; goto error;
} }
if (be16toh(elem->len) != len - sizeof(*elem) - offset) { grouplen = be16toh(group->len);
errno = EIO;
goto error; offset += sizeof(*group);
if (group->format != PATTY_AX25_FRAME_XID_GROUP_ISO8885
|| group->type != PATTY_AX25_FRAME_XID_GROUP_PARAMS) {
offset += grouplen;
goto done;
} }
offset += sizeof(*elem); while (offset - start < sizeof(*group) + grouplen) {
while (offset < len) {
patty_ax25_frame_xid_param *param = (patty_ax25_frame_xid_param *) patty_ax25_frame_xid_param *param = (patty_ax25_frame_xid_param *)
((uint8_t *)data + offset); ((uint8_t *)data + offset);
uint32_t value = 0;
size_t i;
for (i=0; i<param->len; i++) {
value |= ((uint8_t *)(param + 1))[param->len-1-i] << (i << 3);
}
if (callback(param->id, if (callback(param->id,
(size_t)param->len, value,
(uint8_t *)(param + 1),
ctx) < 0) { ctx) < 0) {
goto error_callback; goto error_callback;
} }
@ -309,9 +317,38 @@ ssize_t patty_ax25_frame_decode_xid(patty_ax25_frame_xid_callback callback,
offset += sizeof(*param) + param->len; offset += sizeof(*param) + param->len;
} }
if (offset != len) { if (offset != start + sizeof(*group) + grouplen) {
goto error;
}
done:
return offset - start;
error:
errno = EIO; errno = EIO;
error_callback:
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;
while (offset < len) {
ssize_t decoded;
if ((decoded = decode_xid_group(callback, data, offset, len, ctx)) < 0) {
goto error_decode_xid_group;
} else {
offset += decoded;
}
}
if (offset != len) {
goto error; goto error;
} }
@ -319,8 +356,10 @@ ssize_t patty_ax25_frame_decode_xid(patty_ax25_frame_xid_callback callback,
return offset - start; return offset - start;
error_callback:
error: error:
errno = EIO;
error_decode_xid_group:
return -1; return -1;
} }