Implement better handling of command/response bits

Implement better handling of command/response bits whilst decoding and
encoding addresses

Changes:

    * Add an enum patty_ax25_frame_cr argument to functions in
      src/sock.c which send specific types of frames

    * Detect AX.25 version >2.0 based on the command/response SSID bits

    * Simplify address copying/encoding by usage of the new function
      patty_ax25_addr_copy()

    * Implement showing AX.25 version, command/response indicator for
      frames in src/print.c
This commit is contained in:
XANTRONIX Development 2020-07-14 17:04:49 -04:00 committed by XANTRONIX Industrial
parent 79d1393e74
commit 9066fe10da
6 changed files with 99 additions and 55 deletions

View file

@ -13,6 +13,7 @@ enum patty_ax25_frame_format {
};
enum patty_ax25_frame_cr {
PATTY_AX25_FRAME_OLD,
PATTY_AX25_FRAME_COMMAND,
PATTY_AX25_FRAME_RESPONSE
};
@ -72,7 +73,9 @@ typedef struct _patty_ax25_frame {
uint16_t control;
uint8_t nr, ns, pf;
enum patty_ax25_frame_cr cr;
enum patty_ax25_frame_type type;
enum patty_ax25_version version;
uint8_t proto;
void *info;

View file

@ -75,17 +75,22 @@ void patty_ax25_sock_seq_send_incr(patty_ax25_sock *sock);
void patty_ax25_sock_seq_recv_incr(patty_ax25_sock *sock);
ssize_t patty_ax25_sock_send(patty_ax25_sock *sock,
enum patty_ax25_frame_cr cr,
uint16_t control,
void *info,
size_t infolen);
ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock);
ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock,
enum patty_ax25_frame_cr cr);
ssize_t patty_ax25_sock_send_rnr(patty_ax25_sock *sock);
ssize_t patty_ax25_sock_send_rnr(patty_ax25_sock *sock,
enum patty_ax25_frame_cr cr);
ssize_t patty_ax25_sock_send_rej(patty_ax25_sock *sock);
ssize_t patty_ax25_sock_send_rej(patty_ax25_sock *sock,
enum patty_ax25_frame_cr cr);
ssize_t patty_ax25_sock_send_srej(patty_ax25_sock *sock);
ssize_t patty_ax25_sock_send_srej(patty_ax25_sock *sock,
enum patty_ax25_frame_cr cr);
ssize_t patty_ax25_sock_send_sabm(patty_ax25_sock *sock, int flag);

View file

@ -109,6 +109,18 @@ ssize_t patty_ax25_frame_decode_address(patty_ax25_frame *frame,
offset += decoded;
}
if (PATTY_AX25_ADDR_SSID_C(frame->dest.ssid) != PATTY_AX25_ADDR_SSID_C(frame->src.ssid)) {
frame->cr = PATTY_AX25_ADDR_SSID_C(frame->dest.ssid)?
PATTY_AX25_FRAME_COMMAND:
PATTY_AX25_FRAME_RESPONSE;
frame->version = PATTY_AX25_2_0;
} else {
frame->cr = PATTY_AX25_FRAME_OLD;
frame->version = PATTY_AX25_OLD;
}
/*
* If the source address is not the final address in the frame, begin
* decoding repeater addresses.
@ -313,29 +325,21 @@ static ssize_t encode_reply_address(patty_ax25_frame *frame,
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;
}
memcpy((uint8_t *)dest + offset, &frame->src, sizeof(patty_ax25_addr));
offset += sizeof(patty_ax25_addr);
((uint8_t *)dest)[offset-1] &= ~1;
memcpy((uint8_t *)dest + offset, &frame->dest, sizeof(patty_ax25_addr));
offset += sizeof(patty_ax25_addr);
((uint8_t *)dest)[offset-1] &= ~1;
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;
}
memcpy((uint8_t *)dest + offset,
&frame->repeaters[hops-1-i],
sizeof(patty_ax25_addr));
offset += sizeof(patty_ax25_addr);
((uint8_t *)dest)[offset-1] &= ~1;
offset += patty_ax25_addr_copy(buf + offset, &frame->repeaters[hops-1-i], 0);
}
((uint8_t *)dest)[offset-1] |= 1;
@ -435,9 +439,7 @@ error_toobig:
}
enum patty_ax25_version patty_ax25_frame_version(patty_ax25_frame *frame) {
return PATTY_AX25_ADDR_SSID_C(frame->src.ssid) ==
PATTY_AX25_ADDR_SSID_C(frame->dest.ssid)?
PATTY_AX25_2_0: PATTY_AX25_OLD;
return frame->version;
}
enum patty_ax25_frame_type patty_ax25_frame_type(patty_ax25_frame *frame) {
@ -445,9 +447,7 @@ enum patty_ax25_frame_type patty_ax25_frame_type(patty_ax25_frame *frame) {
}
enum patty_ax25_frame_cr patty_ax25_frame_cr(patty_ax25_frame *frame) {
return PATTY_AX25_ADDR_SSID_C(frame->src.ssid)?
PATTY_AX25_FRAME_RESPONSE:
PATTY_AX25_FRAME_COMMAND;
return frame->cr;
}
ssize_t patty_ax25_frame_info(patty_ax25_frame *frame,

View file

@ -7,7 +7,7 @@
#define printable(c) \
(c >= 0x20 && c < 0x7f)
static char *frame_type_name(enum patty_ax25_frame_type type) {
static char *frame_type(enum patty_ax25_frame_type type) {
switch (type) {
case PATTY_AX25_FRAME_I: return "I";
case PATTY_AX25_FRAME_RR: return "RR";
@ -31,6 +31,26 @@ static char *frame_type_name(enum patty_ax25_frame_type type) {
return "unknown";
}
static char *version(enum patty_ax25_version version) {
switch (version) {
case PATTY_AX25_2_0: return "v2.0";
case PATTY_AX25_2_2: return "v2.2";
case PATTY_AX25_OLD: return "old";
}
return "unknown";
}
static char *frame_cr(enum patty_ax25_frame_cr cr) {
switch (cr) {
case PATTY_AX25_FRAME_COMMAND: return "command";
case PATTY_AX25_FRAME_RESPONSE: return "response";
case PATTY_AX25_FRAME_OLD: return "?";
}
return "unknown";
}
int patty_print_hexdump(FILE *fh, void *data, size_t len) {
size_t i;
@ -128,8 +148,10 @@ int patty_print_frame(FILE *fh,
}
if (PATTY_AX25_FRAME_CONTROL_I(frame->control)) {
if (fprintf(fh, " type I (%s) nr %d ns %d pf %d info %zu bytes",
frame_type_name(frame->type),
if (fprintf(fh, " type I (%s) %s %s nr %d ns %d pf %d info %zu bytes",
frame_type(frame->type),
version(frame->version),
frame_cr(frame->cr),
(int)frame->nr,
(int)frame->ns,
(int)frame->pf,
@ -137,8 +159,10 @@ int patty_print_frame(FILE *fh,
goto error_io;
}
} else if (PATTY_AX25_FRAME_CONTROL_U(frame->control)) {
if (fprintf(fh, " type U (%s) pf %d",
frame_type_name(frame->type),
if (fprintf(fh, " type U (%s) %s %s pf %d",
frame_type(frame->type),
version(frame->version),
frame_cr(frame->cr),
(int)frame->pf) < 0) {
goto error_io;
}
@ -149,8 +173,10 @@ int patty_print_frame(FILE *fh,
}
}
} else if (PATTY_AX25_FRAME_CONTROL_S(frame->control)) {
if (fprintf(fh, " type S (%s) nr %d pf %d",
frame_type_name(frame->type),
if (fprintf(fh, " type S (%s) %s %s nr %d pf %d",
frame_type(frame->type),
version(frame->version),
frame_cr(frame->cr),
(int)frame->nr,
(int)frame->pf) < 0) {
goto error_io;

View file

@ -1244,7 +1244,7 @@ static int handle_i(patty_ax25_server *server,
if (sock->seq_recv == frame->ns) {
patty_ax25_sock_seq_recv_incr(sock);
} else {
return patty_ax25_sock_send_rej(sock);
return patty_ax25_sock_send_rej(sock, PATTY_AX25_FRAME_RESPONSE);
}
if (write(sock->fd, frame->info, frame->infolen) < 0) {
@ -1252,7 +1252,7 @@ static int handle_i(patty_ax25_server *server,
}
if (frame->pf) {
return patty_ax25_sock_send_rr(sock);
return patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_RESPONSE);
}
return 0;

View file

@ -154,29 +154,27 @@ void patty_ax25_sock_seq_recv_incr(patty_ax25_sock *sock) {
}
}
static size_t copy_addr_to_tx_buf(patty_ax25_sock *sock) {
void *buf = sock->iface->tx_buf;
static size_t addr_copy_to_tx_buf(patty_ax25_sock *sock,
enum patty_ax25_frame_cr cr) {
uint8_t *buf = sock->iface->tx_buf;
size_t offset = 0;
uint8_t flags_remote = 0x00,
flags_local = 0x00;
unsigned int i;
size_t offset = 0;
switch (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 *)buf + offset, &sock->remote, sizeof(patty_ax25_addr));
offset += sizeof(patty_ax25_addr);
((uint8_t *)buf)[offset-1] &= ~1;
memcpy((uint8_t *)buf + offset, &sock->local, sizeof(patty_ax25_addr));
offset += sizeof(patty_ax25_addr);
((uint8_t *)buf)[offset-1] &= ~1;
offset += patty_ax25_addr_copy(buf + offset, &sock->remote, flags_remote);
offset += patty_ax25_addr_copy(buf + offset, &sock->local, flags_local);
for (i=0; i<sock->hops; i++) {
memcpy((uint8_t *)buf + offset,
&sock->repeaters[i],
sizeof(patty_ax25_addr));
offset += sizeof(patty_ax25_addr);
((uint8_t *)buf)[offset-1] &= ~1;
offset += patty_ax25_addr_copy(buf + offset, &sock->repeaters[i], 0);
}
((uint8_t *)buf)[offset-1] |= 1;
@ -196,6 +194,7 @@ static inline int toobig(patty_ax25_sock *sock,
}
ssize_t patty_ax25_sock_send(patty_ax25_sock *sock,
enum patty_ax25_frame_cr cr,
uint16_t control,
void *info,
size_t infolen) {
@ -206,7 +205,7 @@ ssize_t patty_ax25_sock_send(patty_ax25_sock *sock,
goto error_toobig;
}
offset = copy_addr_to_tx_buf(sock);
offset = addr_copy_to_tx_buf(sock, cr);
if (sock->mode == PATTY_AX25_SOCK_SABME) {
buf[offset++] = (control & 0xff00) >> 8;
@ -270,29 +269,37 @@ static uint16_t control_u(enum patty_ax25_frame_type type,
| (flag << 4);
}
ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock) {
ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock,
enum patty_ax25_frame_cr cr) {
return patty_ax25_sock_send(sock,
cr,
control_s(sock, PATTY_AX25_FRAME_RR, 1),
NULL,
0);
}
ssize_t patty_ax25_sock_send_rnr(patty_ax25_sock *sock) {
ssize_t patty_ax25_sock_send_rnr(patty_ax25_sock *sock,
enum patty_ax25_frame_cr cr) {
return patty_ax25_sock_send(sock,
cr,
control_s(sock, PATTY_AX25_FRAME_RNR, 1),
NULL,
0);
}
ssize_t patty_ax25_sock_send_rej(patty_ax25_sock *sock) {
ssize_t patty_ax25_sock_send_rej(patty_ax25_sock *sock,
enum patty_ax25_frame_cr cr) {
return patty_ax25_sock_send(sock,
cr,
control_s(sock, PATTY_AX25_FRAME_REJ, 1),
NULL,
0);
}
ssize_t patty_ax25_sock_send_srej(patty_ax25_sock *sock) {
ssize_t patty_ax25_sock_send_srej(patty_ax25_sock *sock,
enum patty_ax25_frame_cr cr) {
return patty_ax25_sock_send(sock,
cr,
control_s(sock, PATTY_AX25_FRAME_SREJ, 1),
NULL,
0);
@ -300,6 +307,7 @@ ssize_t patty_ax25_sock_send_srej(patty_ax25_sock *sock) {
ssize_t patty_ax25_sock_send_sabm(patty_ax25_sock *sock, int flag) {
return patty_ax25_sock_send(sock,
PATTY_AX25_FRAME_COMMAND,
control_u(PATTY_AX25_FRAME_SABM, flag),
NULL,
0);
@ -307,6 +315,7 @@ ssize_t patty_ax25_sock_send_sabm(patty_ax25_sock *sock, int flag) {
ssize_t patty_ax25_sock_send_sabme(patty_ax25_sock *sock, int flag) {
return patty_ax25_sock_send(sock,
PATTY_AX25_FRAME_COMMAND,
control_u(PATTY_AX25_FRAME_SABME, flag),
NULL,
0);
@ -314,6 +323,7 @@ ssize_t patty_ax25_sock_send_sabme(patty_ax25_sock *sock, int flag) {
ssize_t patty_ax25_sock_send_disc(patty_ax25_sock *sock, int flag) {
return patty_ax25_sock_send(sock,
PATTY_AX25_FRAME_COMMAND,
control_u(PATTY_AX25_FRAME_DISC, flag),
NULL,
0);
@ -336,7 +346,7 @@ ssize_t patty_ax25_sock_write(patty_ax25_sock *sock,
control = control_i(sock, 0);
if (patty_ax25_sock_send(sock, control, buf, len) < 0) {
if (patty_ax25_sock_send(sock, PATTY_AX25_FRAME_RESPONSE, control, buf, len) < 0) {
goto error_send;
}