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:
parent
216bd91050
commit
803ebd0048
3 changed files with 51 additions and 80 deletions
|
@ -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);
|
||||
|
||||
|
|
127
src/frame.c
127
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; 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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue