Implement Response Delay Timer T2

Implement AX.25 v2.2 Section 6.7.1.2 "Response Delay Timer T2" as per
specification; do not acknowledge several sequential I frames until a
certain period of time has passed since the receipt of the most recent I
frame
This commit is contained in:
XANTRONIX Development 2020-07-31 01:14:11 -04:00 committed by XANTRONIX Industrial
parent 05cac588f2
commit aa2fd9b06d
3 changed files with 45 additions and 19 deletions

View file

@ -72,7 +72,8 @@ typedef struct _patty_ax25_sock {
unsigned int seq_send,
seq_recv;
size_t retries;
size_t retries,
pending;
int fd;
char pty[PATTY_AX25_SOCK_PATH_SIZE];

View file

@ -1314,8 +1314,16 @@ static int handle_i(patty_ax25_server *server,
goto error_write;
}
return frame->pf?
patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_RESPONSE, 0): 0;
if (++sock->pending == sock->n_window_rx / 2) {
sock->pending = 0;
patty_timer_cancel(&sock->timer_t2);
return patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_RESPONSE, 0);
} else {
patty_timer_start(&sock->timer_t2, &server->timer, 3000);
}
return 0;
error_write:
return -1;
@ -1628,24 +1636,40 @@ static int handle_sock(uint32_t key,
ssize_t len;
if (sock->status == PATTY_AX25_SOCK_PENDING_CONNECT) {
if (patty_timer_expired(&sock->timer_t1)) {
if (sock->retries) {
int ret = patty_ax25_sock_send_sabm(sock, PATTY_AX25_FRAME_POLL);
patty_timer_start(&sock->timer_t1, &server->timer, sock->n_ack);
return ret;
} else {
(void)sock_shutdown(server, sock);
return sock_close(server, sock);
}
} else {
switch (sock->status) {
case PATTY_AX25_SOCK_PENDING_CONNECT:
patty_timer_tick(&sock->timer_t1, &server->elapsed);
}
goto done;
if (patty_timer_expired(&sock->timer_t1)) {
if (sock->retries) {
int ret = patty_ax25_sock_send_sabm(sock, PATTY_AX25_FRAME_POLL);
sock->retries--;
patty_timer_start(&sock->timer_t1, &server->timer, sock->n_ack);
return ret;
} else {
(void)sock_shutdown(server, sock);
return sock_close(server, sock);
}
}
goto done;
case PATTY_AX25_SOCK_ESTABLISHED:
patty_timer_tick(&sock->timer_t2, &server->elapsed);
if (patty_timer_expired(&sock->timer_t2)) {
if (sock->pending) {
sock->pending = 0;
return patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_RESPONSE, 0);
}
}
default:
break;
}
if (!FD_ISSET(sock->fd, &server->fds_r)) {

View file

@ -180,6 +180,7 @@ int patty_ax25_sock_reset(patty_ax25_sock *sock) {
sock->seq_send = 0;
sock->seq_recv = 0;
sock->retries = sock->n_retry;
sock->pending = 0;
timerclear(&sock->timer_t1);
timerclear(&sock->timer_t2);