Implement ring buffer for sock sent frames
Implement ring buffer for frames sent in a SABM or SABME session, facilitating the ability to retransmit select frames upon request, retaining a copy of the full frame and its transmitted size
This commit is contained in:
parent
6df612b910
commit
c26c7509f4
3 changed files with 85 additions and 20 deletions
|
@ -1,7 +1,9 @@
|
|||
#ifndef _PATTY_AX25_SOCK_H
|
||||
#define _PATTY_AX25_SOCK_H
|
||||
|
||||
#define PATTY_AX25_SOCK_BUFSZ 4096
|
||||
#define PATTY_AX25_SOCK_BUFSZ 4096
|
||||
#define PATTY_AX25_SOCK_SLOTS_SABM 8
|
||||
#define PATTY_AX25_SOCK_SLOTS_SABME 128
|
||||
|
||||
enum patty_ax25_sock_type {
|
||||
PATTY_AX25_SOCK_STREAM,
|
||||
|
@ -26,6 +28,11 @@ enum patty_ax25_sock_opt {
|
|||
PATTY_AX25_SOCK_IF
|
||||
};
|
||||
|
||||
typedef struct _patty_ax25_sock_tx_slot {
|
||||
size_t len;
|
||||
uint8_t buf[PATTY_AX25_SOCK_BUFSZ];
|
||||
} patty_ax25_sock_tx_slot;
|
||||
|
||||
typedef struct _patty_ax25_sock {
|
||||
enum patty_ax25_proto proto;
|
||||
enum patty_ax25_sock_type type;
|
||||
|
@ -46,8 +53,8 @@ typedef struct _patty_ax25_sock {
|
|||
int fd;
|
||||
char path[PATTY_AX25_SOCK_PATH_SIZE];
|
||||
|
||||
void *buf;
|
||||
size_t bufsz;
|
||||
void *rx_buf;
|
||||
patty_ax25_sock_tx_slot *tx_slots;
|
||||
|
||||
patty_ax25_if *iface;
|
||||
|
||||
|
@ -65,6 +72,9 @@ void patty_ax25_sock_reset(patty_ax25_sock *sock);
|
|||
|
||||
void patty_ax25_sock_destroy(patty_ax25_sock *sock);
|
||||
|
||||
int patty_ax25_sock_mode_set(patty_ax25_sock *sock,
|
||||
enum patty_ax25_sock_mode mode);
|
||||
|
||||
char *patty_ax25_sock_pty(patty_ax25_sock *sock);
|
||||
|
||||
int patty_ax25_sock_bind_if(patty_ax25_sock *sock,
|
||||
|
@ -80,6 +90,9 @@ ssize_t patty_ax25_sock_send(patty_ax25_sock *sock,
|
|||
void *info,
|
||||
size_t infolen);
|
||||
|
||||
ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock,
|
||||
unsigned int seq);
|
||||
|
||||
ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock,
|
||||
enum patty_ax25_frame_cr cr);
|
||||
|
||||
|
|
17
src/server.c
17
src/server.c
|
@ -1047,6 +1047,8 @@ static int handle_sabm(patty_ax25_server *server,
|
|||
patty_ax25_sock *local, *remote;
|
||||
patty_ax25_call_accept_response response;
|
||||
|
||||
enum patty_ax25_sock_mode mode;
|
||||
|
||||
if ((local = sock_by_addr(server->socks_pending_accept,
|
||||
&frame->dest)) == NULL) {
|
||||
return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL);
|
||||
|
@ -1060,11 +1062,15 @@ static int handle_sabm(patty_ax25_server *server,
|
|||
goto error_sock_new;
|
||||
}
|
||||
|
||||
mode = (frame->type == PATTY_AX25_FRAME_SABM)?
|
||||
PATTY_AX25_SOCK_SABM: PATTY_AX25_SOCK_SABME;
|
||||
|
||||
remote->status = PATTY_AX25_SOCK_ESTABLISHED;
|
||||
remote->iface = iface;
|
||||
|
||||
remote->mode = (frame->type == PATTY_AX25_FRAME_SABM)?
|
||||
PATTY_AX25_SOCK_SABM: PATTY_AX25_SOCK_SABME;
|
||||
if (patty_ax25_sock_mode_set(remote, mode) < 0) {
|
||||
goto error_sock_set_mode;
|
||||
}
|
||||
|
||||
save_reply_addr(remote, frame);
|
||||
|
||||
|
@ -1111,6 +1117,7 @@ error_reply_ua:
|
|||
error_sock_delete_by_addr:
|
||||
error_sock_save_by_addrpair:
|
||||
error_sock_save_by_fd:
|
||||
error_sock_set_mode:
|
||||
patty_ax25_sock_destroy(remote);
|
||||
|
||||
error_sock_new:
|
||||
|
@ -1307,7 +1314,7 @@ static int handle_frame(patty_ax25_server *server,
|
|||
case PATTY_AX25_FRAME_SABME: return handle_sabm(server, iface, &frame);
|
||||
case PATTY_AX25_FRAME_DISC: return handle_disc(server, iface, &frame);
|
||||
case PATTY_AX25_FRAME_FRMR: return 0;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1380,7 +1387,7 @@ static int handle_sock(uint32_t key,
|
|||
goto done;
|
||||
}
|
||||
|
||||
if ((len = read(sock->fd, sock->buf, sock->bufsz)) < 0) {
|
||||
if ((len = read(sock->fd, sock->rx_buf, PATTY_AX25_SOCK_BUFSZ)) < 0) {
|
||||
if (errno == EIO) {
|
||||
(void)sock_close(server, sock);
|
||||
|
||||
|
@ -1394,7 +1401,7 @@ static int handle_sock(uint32_t key,
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (patty_ax25_sock_write(sock, sock->buf, len) < 0) {
|
||||
if (patty_ax25_sock_write(sock, sock->rx_buf, len) < 0) {
|
||||
goto error_sock_write;
|
||||
}
|
||||
|
||||
|
|
69
src/sock.c
69
src/sock.c
|
@ -64,15 +64,18 @@ patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_proto proto,
|
|||
|
||||
memset(sock, '\0', sizeof(*sock));
|
||||
|
||||
if ((sock->buf = malloc(PATTY_AX25_SOCK_BUFSZ)) == NULL) {
|
||||
goto error_malloc_buf;
|
||||
if ((sock->rx_buf = malloc(PATTY_AX25_SOCK_BUFSZ)) == NULL) {
|
||||
goto error_malloc_rx_buf;
|
||||
}
|
||||
|
||||
if ((sock->tx_slots = malloc(PATTY_AX25_SOCK_SLOTS_SABM * sizeof(patty_ax25_sock_tx_slot))) == NULL) {
|
||||
goto error_malloc_tx_slots;
|
||||
}
|
||||
|
||||
if (bind_pty(sock) < 0) {
|
||||
goto error_bind_pty;
|
||||
}
|
||||
|
||||
sock->bufsz = PATTY_AX25_SOCK_BUFSZ;
|
||||
sock->proto = proto;
|
||||
sock->type = type;
|
||||
sock->status = PATTY_AX25_SOCK_CLOSED;
|
||||
|
@ -83,9 +86,12 @@ patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_proto proto,
|
|||
return sock;
|
||||
|
||||
error_bind_pty:
|
||||
free(sock->buf);
|
||||
free(sock->tx_slots);
|
||||
|
||||
error_malloc_buf:
|
||||
error_malloc_tx_slots:
|
||||
free(sock->rx_buf);
|
||||
|
||||
error_malloc_rx_buf:
|
||||
free(sock);
|
||||
|
||||
error_malloc_sock:
|
||||
|
@ -114,10 +120,39 @@ void patty_ax25_sock_destroy(patty_ax25_sock *sock) {
|
|||
close(sock->fd);
|
||||
}
|
||||
|
||||
free(sock->buf);
|
||||
free(sock->rx_buf);
|
||||
free(sock->tx_slots);
|
||||
free(sock);
|
||||
}
|
||||
|
||||
int patty_ax25_sock_mode_set(patty_ax25_sock *sock,
|
||||
enum patty_ax25_sock_mode mode) {
|
||||
size_t slots = 0;
|
||||
|
||||
if (sock->mode == mode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case PATTY_AX25_SOCK_SABM: slots = PATTY_AX25_SOCK_SLOTS_SABM; break;
|
||||
case PATTY_AX25_SOCK_SABME: slots = PATTY_AX25_SOCK_SLOTS_SABME; break;
|
||||
case PATTY_AX25_SOCK_DM: goto done;
|
||||
}
|
||||
|
||||
if ((sock->tx_slots = realloc(sock->tx_slots,
|
||||
slots * sizeof(patty_ax25_sock_tx_slot))) == NULL) {
|
||||
goto error_malloc_tx_slots;
|
||||
}
|
||||
|
||||
done:
|
||||
sock->mode = mode;
|
||||
|
||||
return 0;
|
||||
|
||||
error_malloc_tx_slots:
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *patty_ax25_sock_pty(patty_ax25_sock *sock) {
|
||||
return sock->path;
|
||||
}
|
||||
|
@ -154,9 +189,10 @@ void patty_ax25_sock_seq_recv_incr(patty_ax25_sock *sock) {
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
static size_t addr_copy_to_buf(void *dest,
|
||||
patty_ax25_sock *sock,
|
||||
enum patty_ax25_frame_cr cr) {
|
||||
uint8_t *buf = (uint8_t *)dest;
|
||||
size_t offset = 0;
|
||||
|
||||
uint8_t flags_remote = 0x00,
|
||||
|
@ -190,7 +226,7 @@ static inline int toobig(patty_ax25_sock *sock,
|
|||
PATTY_AX25_FRAME_NORMAL,
|
||||
sock->hops,
|
||||
control,
|
||||
infolen) > sock->iface->tx_bufsz? 1: 0;
|
||||
infolen) > PATTY_AX25_SOCK_BUFSZ? 1: 0;
|
||||
}
|
||||
|
||||
ssize_t patty_ax25_sock_send(patty_ax25_sock *sock,
|
||||
|
@ -199,13 +235,13 @@ ssize_t patty_ax25_sock_send(patty_ax25_sock *sock,
|
|||
void *info,
|
||||
size_t infolen) {
|
||||
size_t offset;
|
||||
uint8_t *buf = (uint8_t *)sock->iface->tx_buf;
|
||||
uint8_t *buf = sock->tx_slots[sock->seq_send].buf;
|
||||
|
||||
if (toobig(sock, control, infolen)) {
|
||||
goto error_toobig;
|
||||
}
|
||||
|
||||
offset = addr_copy_to_tx_buf(sock, cr);
|
||||
offset = addr_copy_to_buf(buf, sock, cr);
|
||||
|
||||
if (sock->mode == PATTY_AX25_SOCK_SABME) {
|
||||
buf[offset++] = (control & 0xff00) >> 8;
|
||||
|
@ -221,12 +257,21 @@ ssize_t patty_ax25_sock_send(patty_ax25_sock *sock,
|
|||
offset += infolen;
|
||||
}
|
||||
|
||||
sock->tx_slots[sock->seq_send].len = offset;
|
||||
|
||||
return patty_ax25_if_send(sock->iface, buf, offset);
|
||||
|
||||
error_toobig:
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock,
|
||||
unsigned int seq) {
|
||||
patty_ax25_sock_tx_slot *slot = &sock->tx_slots[seq];
|
||||
|
||||
return patty_ax25_if_send(sock->iface, slot->buf, slot->len);
|
||||
}
|
||||
|
||||
static uint16_t control_i(patty_ax25_sock *sock, int flag) {
|
||||
switch (sock->mode) {
|
||||
case PATTY_AX25_SOCK_SABM:
|
||||
|
|
Loading…
Add table
Reference in a new issue