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:
parent
05cac588f2
commit
aa2fd9b06d
3 changed files with 45 additions and 19 deletions
|
@ -72,7 +72,8 @@ typedef struct _patty_ax25_sock {
|
||||||
unsigned int seq_send,
|
unsigned int seq_send,
|
||||||
seq_recv;
|
seq_recv;
|
||||||
|
|
||||||
size_t retries;
|
size_t retries,
|
||||||
|
pending;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
char pty[PATTY_AX25_SOCK_PATH_SIZE];
|
char pty[PATTY_AX25_SOCK_PATH_SIZE];
|
||||||
|
|
60
src/server.c
60
src/server.c
|
@ -1314,8 +1314,16 @@ static int handle_i(patty_ax25_server *server,
|
||||||
goto error_write;
|
goto error_write;
|
||||||
}
|
}
|
||||||
|
|
||||||
return frame->pf?
|
if (++sock->pending == sock->n_window_rx / 2) {
|
||||||
patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_RESPONSE, 0): 0;
|
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:
|
error_write:
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1628,24 +1636,40 @@ static int handle_sock(uint32_t key,
|
||||||
|
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
if (sock->status == PATTY_AX25_SOCK_PENDING_CONNECT) {
|
switch (sock->status) {
|
||||||
if (patty_timer_expired(&sock->timer_t1)) {
|
case PATTY_AX25_SOCK_PENDING_CONNECT:
|
||||||
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 {
|
|
||||||
patty_timer_tick(&sock->timer_t1, &server->elapsed);
|
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)) {
|
if (!FD_ISSET(sock->fd, &server->fds_r)) {
|
||||||
|
|
|
@ -180,6 +180,7 @@ int patty_ax25_sock_reset(patty_ax25_sock *sock) {
|
||||||
sock->seq_send = 0;
|
sock->seq_send = 0;
|
||||||
sock->seq_recv = 0;
|
sock->seq_recv = 0;
|
||||||
sock->retries = sock->n_retry;
|
sock->retries = sock->n_retry;
|
||||||
|
sock->pending = 0;
|
||||||
|
|
||||||
timerclear(&sock->timer_t1);
|
timerclear(&sock->timer_t1);
|
||||||
timerclear(&sock->timer_t2);
|
timerclear(&sock->timer_t2);
|
||||||
|
|
Loading…
Add table
Reference in a new issue