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
This commit is contained in:
XANTRONIX Development 2020-07-21 01:33:00 -04:00 committed by XANTRONIX Industrial
parent 216bd91050
commit 803ebd0048
3 changed files with 51 additions and 80 deletions

View file

@ -74,6 +74,7 @@ typedef struct _patty_ax25_frame {
uint8_t nr, ns, pf; uint8_t nr, ns, pf;
enum patty_ax25_frame_cr cr; enum patty_ax25_frame_cr cr;
enum patty_ax25_frame_type type; enum patty_ax25_frame_type type;
enum patty_ax25_frame_format format;
enum patty_ax25_version version; enum patty_ax25_version version;
uint8_t proto; uint8_t proto;
@ -121,7 +122,6 @@ ssize_t patty_ax25_frame_decode_xid(patty_ax25_params *params,
size_t len); size_t len);
ssize_t patty_ax25_frame_encode(patty_ax25_frame *frame, ssize_t patty_ax25_frame_encode(patty_ax25_frame *frame,
enum patty_ax25_frame_format format,
void *buf, void *buf,
size_t len); 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, ssize_t patty_ax25_frame_encode_reply_to(patty_ax25_frame *frame,
patty_ax25_frame *reply, patty_ax25_frame *reply,
enum patty_ax25_frame_format format,
void *buf, void *buf,
size_t len); size_t len);

View file

@ -204,6 +204,8 @@ ssize_t patty_ax25_frame_decode_control(patty_ax25_frame *frame,
break; break;
} }
frame->format = format;
if (PATTY_AX25_FRAME_CONTROL_I(frame->control)) { if (PATTY_AX25_FRAME_CONTROL_I(frame->control)) {
frame->type = PATTY_AX25_FRAME_I; frame->type = PATTY_AX25_FRAME_I;
frame->nr = decode_nr(frame->control, format); frame->nr = decode_nr(frame->control, format);
@ -392,78 +394,49 @@ error_decode_xid_group:
return -1; return -1;
} }
static ssize_t encode_address(void *buf, static ssize_t encode_address(patty_ax25_frame *frame,
patty_ax25_addr *dest, void *dest,
patty_ax25_addr *src, int reply,
patty_ax25_addr *repeaters,
unsigned int hops,
size_t len) { size_t len) {
uint8_t *buf = (uint8_t *)dest;
size_t offset = 0; size_t offset = 0;
uint8_t flags_remote = 0x00,
flags_local = 0x00;
unsigned int i; unsigned int i;
if (hops > PATTY_AX25_MAX_HOPS) { if ((2 + frame->hops) * sizeof(patty_ax25_addr) > len) {
hops = PATTY_AX25_MAX_HOPS; errno = EOVERFLOW;
}
if (len < (2 + hops) * sizeof(patty_ax25_addr)) {
goto error_toobig; goto error_toobig;
} }
memcpy((uint8_t *)dest + offset, &dest, sizeof(patty_ax25_addr)); switch (frame->cr) {
offset += sizeof(patty_ax25_addr); case PATTY_AX25_FRAME_COMMAND: flags_remote = 0x80; break;
((uint8_t *)dest)[offset-1] &= ~1; 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;
for (i=0; i<hops; i++) {
if (repeaters[i].callsign[0] == '\0') {
break;
} }
memcpy((uint8_t *)dest + offset, if (reply) {
&repeaters[i], offset += patty_ax25_addr_copy(buf + offset, &frame->src, flags_local);
sizeof(patty_ax25_addr)); offset += patty_ax25_addr_copy(buf + offset, &frame->dest, flags_remote);
offset += sizeof(patty_ax25_addr); for (i=0; i<frame->hops; i++) {
((uint8_t *)dest)[offset-1] &= ~1; 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);
for (i=0; i<frame->hops; i++) {
offset += patty_ax25_addr_copy(buf + offset, &frame->repeaters[i], 0);
}
} }
((uint8_t *)dest)[offset-1] |= 1; ((uint8_t *)buf)[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; i<hops; i++) {
if (frame->repeaters[i].callsign[0] == '\0') {
break;
}
offset += patty_ax25_addr_copy(buf + offset, &frame->repeaters[hops-1-i], 0);
}
((uint8_t *)dest)[offset-1] |= 1;
return offset; return offset;
@ -472,39 +445,41 @@ error_toobig:
} }
ssize_t patty_ax25_frame_encode(patty_ax25_frame *frame, ssize_t patty_ax25_frame_encode(patty_ax25_frame *frame,
enum patty_ax25_frame_format format,
void *buf, void *buf,
size_t len) { size_t len) {
size_t offset; size_t offset = 0;
ssize_t encoded;
if ((offset = encode_address(buf, if ((encoded = encode_address(frame, buf, 0, len)) < 0) {
&frame->dest, goto error_encode_address;
&frame->src, } else {
frame->repeaters, offset += encoded;
frame->hops,
len)) < 0) {
goto error_toobig;
} }
switch (format) { switch (frame->format) {
case PATTY_AX25_FRAME_NORMAL: case PATTY_AX25_FRAME_NORMAL:
((uint8_t *)buf)[offset++] = frame->control; ((uint8_t *)buf)[offset++] = frame->control;
break; break;
case PATTY_AX25_FRAME_EXTENDED: case PATTY_AX25_FRAME_EXTENDED:
((uint8_t *)buf)[offset++] = frame->control & 0x00ff;
if (!PATTY_AX25_FRAME_CONTROL_U(frame->control)) {
((uint8_t *)buf)[offset++] = (frame->control & 0xff00) >> 8; ((uint8_t *)buf)[offset++] = (frame->control & 0xff00) >> 8;
((uint8_t *)buf)[offset++] = frame->control & 0xf00ff; }
break; 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) { if (1 + offset + frame->infolen > len) {
goto error_toobig; goto error_toobig;
} }
if (PATTY_AX25_FRAME_CONTROL_I(frame->control) || PATTY_AX25_FRAME_CONTROL_UI(frame->control)) {
((uint8_t *)buf)[offset++] = frame->proto; ((uint8_t *)buf)[offset++] = frame->proto;
}
memcpy((uint8_t *)buf + offset, frame->info, frame->infolen); 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; return offset;
error_toobig: error_toobig:
error_encode_address:
return -1; return -1;
} }
@ -620,16 +596,13 @@ error_encode_xid_param:
ssize_t patty_ax25_frame_encode_reply_to(patty_ax25_frame *frame, ssize_t patty_ax25_frame_encode_reply_to(patty_ax25_frame *frame,
patty_ax25_frame *reply, patty_ax25_frame *reply,
enum patty_ax25_frame_format format,
void *buf, void *buf,
size_t len) { size_t len) {
size_t offset; size_t offset;
if ((offset = encode_reply_address(frame, buf, len)) < 0) { offset = encode_address(frame, buf, 1, len);
goto error_toobig;
}
switch (format) { switch (reply->format) {
case PATTY_AX25_FRAME_NORMAL: case PATTY_AX25_FRAME_NORMAL:
((uint8_t *)buf)[offset++] = reply->control; ((uint8_t *)buf)[offset++] = reply->control;
@ -645,7 +618,7 @@ ssize_t patty_ax25_frame_encode_reply_to(patty_ax25_frame *frame,
break; 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) { if (len < 1 + offset + reply->infolen) {
goto error_toobig; goto error_toobig;
} }

View file

@ -1000,7 +1000,6 @@ static int reply_to(patty_ax25_if *iface,
if ((len = patty_ax25_frame_encode_reply_to(frame, if ((len = patty_ax25_frame_encode_reply_to(frame,
reply, reply,
PATTY_AX25_FRAME_NORMAL,
iface->tx_buf, iface->tx_buf,
iface->mtu)) < 0) { iface->mtu)) < 0) {
goto error_toobig; goto error_toobig;