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:
parent
79d1393e74
commit
9066fe10da
6 changed files with 99 additions and 55 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
38
src/frame.c
38
src/frame.c
|
@ -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,
|
||||
|
|
40
src/print.c
40
src/print.c
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
56
src/sock.c
56
src/sock.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue