Implement patty_ax25_sock_ack()
Implement patty_ax25_sock_ack() to keep track of I frames sent which have been successfully acknowledged by a peer
This commit is contained in:
parent
301e58c6e9
commit
f26e977bfc
3 changed files with 62 additions and 37 deletions
|
@ -232,8 +232,9 @@ ssize_t patty_ax25_sock_recv(patty_ax25_sock *sock,
|
||||||
|
|
||||||
ssize_t patty_ax25_sock_recv_pending(patty_ax25_sock *sock);
|
ssize_t patty_ax25_sock_recv_pending(patty_ax25_sock *sock);
|
||||||
|
|
||||||
ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock,
|
ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock, int seq);
|
||||||
unsigned int seq);
|
|
||||||
|
void patty_ax25_sock_ack(patty_ax25_sock *sock, int seq);
|
||||||
|
|
||||||
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,
|
enum patty_ax25_frame_cr cr,
|
||||||
|
|
22
src/server.c
22
src/server.c
|
@ -1484,7 +1484,7 @@ static int handle_segment(patty_ax25_server *server,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
reply_rej:
|
reply_rej:
|
||||||
return patty_ax25_sock_send_rej(sock, PATTY_AX25_FRAME_RESPONSE, 1);
|
return patty_ax25_sock_send_rej(sock, PATTY_AX25_FRAME_RESPONSE, 0);
|
||||||
|
|
||||||
error_write:
|
error_write:
|
||||||
error_sock_assembler_read:
|
error_sock_assembler_read:
|
||||||
|
@ -1501,10 +1501,12 @@ static int handle_i(patty_ax25_server *server,
|
||||||
return frame->pf? reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL): 0;
|
return frame->pf? reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL): 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
patty_ax25_sock_ack(sock, frame->nr - 1);
|
||||||
|
|
||||||
if (sock->vr == frame->ns) {
|
if (sock->vr == frame->ns) {
|
||||||
patty_ax25_sock_vr_incr(sock);
|
patty_ax25_sock_vr_incr(sock);
|
||||||
} else {
|
} else {
|
||||||
return patty_ax25_sock_send_rej(sock, PATTY_AX25_FRAME_RESPONSE, 1);
|
return patty_ax25_sock_send_rej(sock, PATTY_AX25_FRAME_RESPONSE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame->proto == PATTY_AX25_PROTO_FRAGMENT) {
|
if (frame->proto == PATTY_AX25_PROTO_FRAGMENT) {
|
||||||
|
@ -1591,6 +1593,8 @@ static int handle_rr(patty_ax25_server *server,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
patty_ax25_sock_ack(sock, frame->nr - 1);
|
||||||
|
|
||||||
patty_timer_stop(&sock->timer_t1);
|
patty_timer_stop(&sock->timer_t1);
|
||||||
|
|
||||||
switch (frame->cr) {
|
switch (frame->cr) {
|
||||||
|
@ -1604,7 +1608,6 @@ static int handle_rr(patty_ax25_server *server,
|
||||||
patty_ax25_sock_send_rnr(sock, PATTY_AX25_FRAME_RESPONSE, 1);
|
patty_ax25_sock_send_rnr(sock, PATTY_AX25_FRAME_RESPONSE, 1);
|
||||||
|
|
||||||
case PATTY_AX25_FRAME_RESPONSE:
|
case PATTY_AX25_FRAME_RESPONSE:
|
||||||
sock->va = frame->nr;
|
|
||||||
sock->retries = sock->n_retry;
|
sock->retries = sock->n_retry;
|
||||||
|
|
||||||
fd_watch(server, sock->fd);
|
fd_watch(server, sock->fd);
|
||||||
|
@ -1627,6 +1630,8 @@ static int handle_rnr(patty_ax25_server *server,
|
||||||
|
|
||||||
patty_timer_stop(&sock->timer_t1);
|
patty_timer_stop(&sock->timer_t1);
|
||||||
|
|
||||||
|
patty_ax25_sock_ack(sock, frame->nr - 1);
|
||||||
|
|
||||||
switch (frame->cr) {
|
switch (frame->cr) {
|
||||||
case PATTY_AX25_FRAME_COMMAND:
|
case PATTY_AX25_FRAME_COMMAND:
|
||||||
if (frame->pf == 0) {
|
if (frame->pf == 0) {
|
||||||
|
@ -1638,7 +1643,6 @@ static int handle_rnr(patty_ax25_server *server,
|
||||||
patty_ax25_sock_send_rnr(sock, PATTY_AX25_FRAME_RESPONSE, 1);
|
patty_ax25_sock_send_rnr(sock, PATTY_AX25_FRAME_RESPONSE, 1);
|
||||||
|
|
||||||
case PATTY_AX25_FRAME_RESPONSE:
|
case PATTY_AX25_FRAME_RESPONSE:
|
||||||
sock->va = frame->nr;
|
|
||||||
sock->flow = PATTY_AX25_SOCK_WAIT;
|
sock->flow = PATTY_AX25_SOCK_WAIT;
|
||||||
sock->retries = sock->n_retry;
|
sock->retries = sock->n_retry;
|
||||||
|
|
||||||
|
@ -1663,7 +1667,7 @@ static int handle_rej(patty_ax25_server *server,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sock->va = frame->nr;
|
patty_ax25_sock_ack(sock, frame->nr - 1);
|
||||||
|
|
||||||
end = sock->vs;
|
end = sock->vs;
|
||||||
|
|
||||||
|
@ -1690,7 +1694,7 @@ static int handle_srej(patty_ax25_server *server,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sock->va = frame->nr;
|
patty_ax25_sock_ack(sock, frame->nr - 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: Read the fine print of section 4.3.2.4
|
* TODO: Read the fine print of section 4.3.2.4
|
||||||
|
@ -2124,14 +2128,18 @@ static int handle_sock(uint32_t key,
|
||||||
if (sock->flow == PATTY_AX25_SOCK_WAIT) {
|
if (sock->flow == PATTY_AX25_SOCK_WAIT) {
|
||||||
sock->flow = PATTY_AX25_SOCK_READY;
|
sock->flow = PATTY_AX25_SOCK_READY;
|
||||||
} else if (patty_ax25_sock_flow_full(sock)) {
|
} else if (patty_ax25_sock_flow_full(sock)) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
sock->flow = PATTY_AX25_SOCK_WAIT;
|
sock->flow = PATTY_AX25_SOCK_WAIT;
|
||||||
|
|
||||||
fd_clear(server, sock->fd);
|
fd_clear(server, sock->fd);
|
||||||
|
|
||||||
|
ret = patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_COMMAND, 1);
|
||||||
|
|
||||||
patty_timer_stop(&sock->timer_t3);
|
patty_timer_stop(&sock->timer_t3);
|
||||||
patty_timer_start(&sock->timer_t1, sock->n_ack);
|
patty_timer_start(&sock->timer_t1, sock->n_ack);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((len = read(sock->fd, sock->rx_buf, sock->n_maxlen_rx)) < 0) {
|
if ((len = read(sock->fd, sock->rx_buf, sock->n_maxlen_rx)) < 0) {
|
||||||
|
|
72
src/sock.c
72
src/sock.c
|
@ -11,6 +11,11 @@
|
||||||
|
|
||||||
#include <patty/ax25.h>
|
#include <patty/ax25.h>
|
||||||
|
|
||||||
|
struct slot {
|
||||||
|
size_t len;
|
||||||
|
int ack;
|
||||||
|
};
|
||||||
|
|
||||||
static int bind_pty(patty_ax25_sock *sock) {
|
static int bind_pty(patty_ax25_sock *sock) {
|
||||||
char *pty;
|
char *pty;
|
||||||
|
|
||||||
|
@ -52,30 +57,29 @@ static inline size_t rx_bufsz(patty_ax25_sock *sock) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t tx_slot_size(patty_ax25_sock *sock) {
|
static inline size_t tx_slot_size(patty_ax25_sock *sock) {
|
||||||
return sizeof(size_t) + PATTY_AX25_FRAME_OVERHEAD + sock->n_maxlen_tx;
|
return sizeof(struct slot) + PATTY_AX25_FRAME_OVERHEAD + sock->n_maxlen_tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t tx_slots_size(patty_ax25_sock *sock) {
|
static inline size_t tx_slots_size(patty_ax25_sock *sock) {
|
||||||
return sock->n_window_tx * tx_slot_size(sock);
|
return sock->n_window_tx * tx_slot_size(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *tx_slot(patty_ax25_sock *sock, size_t seq) {
|
static inline int tx_seq(patty_ax25_sock *sock, int seq) {
|
||||||
|
return sock->mode == PATTY_AX25_SOCK_SABME?
|
||||||
|
(seq + 128) % 128:
|
||||||
|
(seq + 8) % 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct slot *tx_slot(patty_ax25_sock *sock, int seq) {
|
||||||
size_t win = sock->n_window_tx,
|
size_t win = sock->n_window_tx,
|
||||||
i = seq % win;
|
i = tx_seq(sock, seq) % win;
|
||||||
|
|
||||||
return (uint8_t *)sock->tx_slots + (i * tx_slot_size(sock));
|
return (struct slot *)
|
||||||
|
((uint8_t *)sock->tx_slots + (i * tx_slot_size(sock)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void tx_slot_save_len(patty_ax25_sock *sock,
|
static inline void *tx_slot_buf(patty_ax25_sock *sock, int seq) {
|
||||||
size_t seq,
|
return (uint8_t *)tx_slot(sock, seq) + sizeof(struct slot);
|
||||||
size_t len) {
|
|
||||||
size_t *size = (size_t *)tx_slot(sock, seq);
|
|
||||||
|
|
||||||
*size = len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void *tx_slot_buf(patty_ax25_sock *sock, size_t seq) {
|
|
||||||
return (uint8_t *)tx_slot(sock, seq) + sizeof(size_t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int init_bufs(patty_ax25_sock *sock) {
|
static int init_bufs(patty_ax25_sock *sock) {
|
||||||
|
@ -94,7 +98,9 @@ static int init_bufs(patty_ax25_sock *sock) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<sock->n_window_tx; i++) {
|
for (i=0; i<sock->n_window_tx; i++) {
|
||||||
tx_slot_save_len(sock, i, 0);
|
struct slot *slot = tx_slot(sock, i);
|
||||||
|
|
||||||
|
slot->len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -506,11 +512,7 @@ void *patty_ax25_sock_assembler_read(patty_ax25_sock *sock,
|
||||||
}
|
}
|
||||||
|
|
||||||
int patty_ax25_sock_flow_full(patty_ax25_sock *sock) {
|
int patty_ax25_sock_flow_full(patty_ax25_sock *sock) {
|
||||||
if (sock->mode == PATTY_AX25_SOCK_SABME) {
|
return sock->vs == tx_seq(sock, sock->va + sock->n_window_tx)? 1: 0;
|
||||||
return sock->vs == (sock->va + sock->n_window_tx) % 128? 1: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sock->vs == (sock->va + sock->n_window_tx) % 8? 1: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int toobig(patty_ax25_sock *sock,
|
static inline int toobig(patty_ax25_sock *sock,
|
||||||
|
@ -651,14 +653,17 @@ static ssize_t frame_send(patty_ax25_sock *sock,
|
||||||
|
|
||||||
if (info && infolen) {
|
if (info && infolen) {
|
||||||
if (PATTY_AX25_FRAME_CONTROL_I(control)) {
|
if (PATTY_AX25_FRAME_CONTROL_I(control)) {
|
||||||
|
struct slot *slot = tx_slot(sock, sock->vs);
|
||||||
|
|
||||||
buf[offset++] = proto;
|
buf[offset++] = proto;
|
||||||
|
|
||||||
|
slot->len = offset;
|
||||||
|
slot->ack = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buf + offset, info, infolen);
|
memcpy(buf + offset, info, infolen);
|
||||||
|
|
||||||
offset += infolen;
|
offset += infolen;
|
||||||
|
|
||||||
tx_slot_save_len(sock, sock->vs, offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return patty_ax25_if_send(sock->iface, buf, offset);
|
return patty_ax25_if_send(sock->iface, buf, offset);
|
||||||
|
@ -670,14 +675,25 @@ error_noif:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock,
|
ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock, int seq) {
|
||||||
unsigned int seq) {
|
struct slot *slot = tx_slot(sock, seq);
|
||||||
void *slot = tx_slot(sock, seq);
|
void *buf = tx_slot_buf(sock, seq);
|
||||||
void *buf = (uint8_t *)slot + sizeof(size_t);
|
|
||||||
|
|
||||||
size_t len = *((size_t *)slot);
|
return slot->len > 0? patty_ax25_if_send(sock->iface, buf, slot->len): 0;
|
||||||
|
}
|
||||||
|
|
||||||
return len > 0? patty_ax25_if_send(sock->iface, buf, len): 0;
|
void patty_ax25_sock_ack(patty_ax25_sock *sock, int seq) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; i<sock->n_window_tx; i++) {
|
||||||
|
struct slot *slot = tx_slot(sock, seq - i);
|
||||||
|
|
||||||
|
if (slot->len > 0) {
|
||||||
|
slot->ack = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sock->va = seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t control_i(patty_ax25_sock *sock, int flag) {
|
static uint16_t control_i(patty_ax25_sock *sock, int flag) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue