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;
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);

View file

@ -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; i<hops; i++) {
if (repeaters[i].callsign[0] == '\0') {
break;
for (i=0; i<frame->hops; 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; i<hops; i++) {
if (frame->repeaters[i].callsign[0] == '\0') {
break;
for (i=0; i<frame->hops; 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;
}

View file

@ -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;