This is a slog with no real end

This commit is contained in:
XANTRONIX Development 2020-06-28 18:11:49 -04:00 committed by XANTRONIX Industrial
parent 89195bde69
commit b9c3568c43
5 changed files with 148 additions and 56 deletions

View file

@ -7,10 +7,10 @@
#define PATTY_AX25_FRAME_DEFAULT_MAXLEN 256
#define PATTY_AX25_FRAME_DEFAULT_WINDOW 8
#define PATTY_AX25_FRAME_SIZE(hops, mode, infolen) \
((sizeof(patty_ax25_addr) * (2 + hops)) \
+ (mode == PATTY_AX25_SOCK_SABME? 2: 1) \
+ (infolen > 0? 1 + infolen: 0))
#define PATTY_AX25_FRAME_SIZE(format, hops, c, infolen) \
(((2 + hops) * sizeof(patty_ax25_addr)) \
+ (format == PATTY_AX25_FRAME_EXTENDED? 2: 1) \
+ (PATTY_AX25_CONTROL_INFO(c)? 1 + infolen: 0))
enum patty_ax25_frame_format {
PATTY_AX25_FRAME_NORMAL,
@ -68,6 +68,10 @@ ssize_t patty_ax25_frame_decode(patty_ax25_frame *frame,
ssize_t patty_ax25_frame_encode(patty_ax25_frame *frame,
void *buf,
enum patty_ax25_frame_format format,
uint16_t control,
uint8_t proto,
void *info,
size_t infolen,
size_t len);
ssize_t patty_ax25_frame_encode_reply_to(patty_ax25_frame *frame,
@ -88,10 +92,4 @@ enum patty_ax25_frame_cr patty_ax25_frame_cr(patty_ax25_frame *frame);
ssize_t patty_ax25_frame_info(patty_ax25_frame *frame,
void **info);
void patty_ax25_frame_set(patty_ax25_frame *frame,
uint16_t control,
uint8_t proto,
void *info,
size_t infolen);
#endif /* _PATTY_AX25_FRAME_H */

View file

@ -51,10 +51,32 @@ typedef struct _patty_ax25_sock {
unsigned int hops;
} patty_ax25_sock;
#define PATTY_AX25_SOCK_CONTROL_SABM(sock, flag) \
(((sock->seq_recv & 07) << 7) | (flag << 4) | (sock->seq_send & 07))
#define PATTY_AX25_SOCK_CONTROL_SABME(sock, flag) \
(((sock->seq_recv & 0x7f) << 15) | (flag << 7) | (sock->seq_send & 0x7f))
#define PATTY_AX25_SOCK_CONTROL(sock, flag) \
(sock->mode == PATTY_AX25_SOCK_SABME? \
PATTY_AX25_SOCK_CONTROL_SABME(sock, flag): \
PATTY_AX25_SOCK_CONTROL_SABM(sock, flag))
patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_sock_type type);
void patty_ax25_sock_destroy(patty_ax25_sock *sock);
int patty_ax25_sock_send_sabm(patty_ax25_sock *sock);
ssize_t patty_ax25_sock_send(patty_ax25_sock *sock,
uint16_t control,
uint8_t proto,
void *info,
size_t infolen);
ssize_t patty_ax25_sock_send_sabm(patty_ax25_sock *sock, int poll);
ssize_t patty_ax25_sock_write(patty_ax25_sock *sock,
uint8_t proto,
void *buf,
size_t len);
#endif /* _PATTY_AX25_SOCK_H */

View file

@ -201,36 +201,42 @@ error_decode:
return -1;
}
static ssize_t encode_address(patty_ax25_frame *frame,
void *dest,
static ssize_t encode_address(void *buf,
patty_ax25_addr *dest,
patty_ax25_addr *src,
patty_ax25_addr *repeaters,
unsigned int hops,
size_t len) {
size_t i,
offset = 0,
hops = frame->hops > PATTY_AX25_MAX_HOPS?
PATTY_AX25_MAX_HOPS: frame->hops;
size_t offset = 0;
unsigned int i;
if ((2 + hops) * sizeof(patty_ax25_addr) > len) {
if (hops > PATTY_AX25_MAX_HOPS) {
hops = PATTY_AX25_MAX_HOPS;
}
if (len < (2 + hops) * sizeof(patty_ax25_addr)) {
goto error_toobig;
}
memcpy((uint8_t *)dest + offset, &frame->dest, sizeof(patty_ax25_addr));
memcpy((uint8_t *)dest + offset, &dest, sizeof(patty_ax25_addr));
offset += sizeof(patty_ax25_addr);
((uint8_t *)dest)[offset-1] &= ~1;
memcpy((uint8_t *)dest + offset, &frame->src, sizeof(patty_ax25_addr));
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 (frame->repeaters[i].callsign[0] == '\0') {
if (repeaters[i].callsign[0] == '\0') {
break;
}
memcpy((uint8_t *)dest + offset,
&frame->repeaters[i],
&repeaters[i],
sizeof(patty_ax25_addr));
offset += sizeof(patty_ax25_addr);
((uint8_t *)dest)[offset-1] &= ~1;
}
((uint8_t *)dest)[offset-1] |= 1;
@ -271,6 +277,7 @@ static ssize_t encode_reply_address(patty_ax25_frame *frame,
sizeof(patty_ax25_addr));
offset += sizeof(patty_ax25_addr);
((uint8_t *)dest)[offset-1] &= ~1;
}
((uint8_t *)dest)[offset-1] |= 1;
@ -284,10 +291,19 @@ error_toobig:
ssize_t patty_ax25_frame_encode(patty_ax25_frame *frame,
void *buf,
enum patty_ax25_frame_format format,
uint16_t control,
uint8_t proto,
void *info,
size_t infolen,
size_t len) {
size_t offset = 0;
offset = encode_address(frame, buf, len);
offset = encode_address(buf,
&frame->dest,
&frame->src,
frame->repeaters,
frame->hops,
len);
switch (format) {
case PATTY_AX25_FRAME_NORMAL:
@ -402,14 +418,3 @@ ssize_t patty_ax25_frame_info(patty_ax25_frame *frame,
error_invalid_args:
return -1;
}
void patty_ax25_frame_set(patty_ax25_frame *frame,
uint16_t control,
uint8_t proto,
void *info,
size_t infolen) {
frame->control = control;
frame->proto = proto;
frame->info = info;
frame->infolen = infolen;
}

View file

@ -834,7 +834,7 @@ static int server_connect(patty_ax25_server *server,
* timeout has been exceeded or the peer has sent a UA frame to
* acknowledge and establish the connection.
*/
if (patty_ax25_sock_send_sabm(sock) < 0) {
if (patty_ax25_sock_send_sabm(sock, 1) < 0) {
response.ret = -1;
response.eno = EIO;

View file

@ -29,37 +29,104 @@ void patty_ax25_sock_destroy(patty_ax25_sock *sock) {
free(sock);
}
static size_t copy_addr_to_buf(patty_ax25_sock *sock, uint8_t *buf, size_t offset) {
size_t i;
static size_t copy_addr_to_tx_buf(patty_ax25_sock *sock) {
void *buf = sock->iface->tx_buf;
memcpy(&buf[offset], &sock->remote, sizeof(patty_ax25_addr));
offset += sizeof(patty_ax25_addr);
buf[offset-1] &= ~1;
unsigned int i;
memcpy(&buf[offset], &sock->local, sizeof(patty_ax25_addr));
size_t offset = 0;
memcpy((uint8_t *)buf + offset, &sock->remote, sizeof(patty_ax25_addr));
offset += sizeof(patty_ax25_addr);
buf[offset-1] &= ~1;
((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;
for (i=0; i<sock->hops; i++) {
memcpy(&buf[offset], &sock->repeaters[i], sizeof(patty_ax25_addr));
memcpy((uint8_t *)buf + offset, &sock->repeaters[i], sizeof(patty_ax25_addr));
offset += sizeof(patty_ax25_addr);
((uint8_t *)buf)[offset-1] &= ~1;
}
buf[offset - 1] |= 0x01;
((uint8_t *)buf)[offset-1] |= 1;
return offset;
}
int patty_ax25_sock_send_sabm(patty_ax25_sock *sock) {
size_t offset = 0;
uint8_t *buf = (uint8_t *)(sock->iface->tx_buf);
offset = copy_addr_to_buf(sock, buf, offset);
buf[offset++] = 0x3f;
buf[offset++] = PATTY_AX25_PROTO_NONE;
return patty_ax25_if_send(sock->iface,
buf,
offset);
static inline int toobig(patty_ax25_sock *sock,
uint16_t control,
size_t infolen) {
return PATTY_AX25_FRAME_SIZE(sock->mode == PATTY_AX25_SOCK_SABME?
PATTY_AX25_FRAME_EXTENDED:
PATTY_AX25_FRAME_NORMAL,
sock->hops,
control,
infolen) > sock->iface->tx_bufsz? 1: 0;
}
ssize_t patty_ax25_sock_send(patty_ax25_sock *sock,
uint16_t control,
uint8_t proto,
void *info,
size_t infolen) {
size_t offset = 0;
ssize_t len;
if (toobig(sock, control, infolen)) {
goto error_toobig;
}
if ((len = copy_addr_to_tx_buf(sock)) < 0) {
goto error_toobig;
} else {
offset += len;
}
if (sock->mode == PATTY_AX25_SOCK_SABME) {
((uint8_t *)sock->iface->tx_buf)[offset++] = (control & 0xff00) >> 8;
((uint8_t *)sock->iface->tx_buf)[offset++] = control & 0x00ff;
} else {
((uint8_t *)sock->iface->tx_buf)[offset++] = control;
}
if (PATTY_AX25_CONTROL_INFO(control)) {
((uint8_t *)sock->iface->tx_buf)[offset++] = proto;
memcpy((uint8_t *)sock->iface->tx_buf + offset, info, infolen);
offset += infolen;
}
return offset;
error_toobig:
return -1;
}
ssize_t patty_ax25_sock_send_sabm(patty_ax25_sock *sock, int poll) {
return patty_ax25_sock_send(sock,
PATTY_AX25_FRAME_U_SABM
| PATTY_AX25_FRAME_U_POLL,
PATTY_AX25_PROTO_NONE,
NULL,
0);
}
ssize_t patty_ax25_sock_write(patty_ax25_sock *sock,
uint8_t proto,
void *buf,
size_t len) {
uint16_t control = sock->mode == PATTY_AX25_SOCK_SABME?
PATTY_AX25_SOCK_CONTROL_SABME(sock, 1):
PATTY_AX25_SOCK_CONTROL_SABM(sock, 1);
if (patty_ax25_sock_send(sock, control, proto, buf, len) < 0) {
goto error_send;
}
return len;
error_send:
return -1;
}