This is a slog with no real end
This commit is contained in:
parent
89195bde69
commit
b9c3568c43
5 changed files with 148 additions and 56 deletions
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
51
src/frame.c
51
src/frame.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
109
src/sock.c
109
src/sock.c
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue