diff --git a/include/patty/ax25/sock.h b/include/patty/ax25/sock.h index ac0fead..08407cd 100644 --- a/include/patty/ax25/sock.h +++ b/include/patty/ax25/sock.h @@ -58,6 +58,11 @@ enum patty_ax25_sock_mode { PATTY_AX25_SOCK_SABME }; +enum patty_ax25_sock_flow { + PATTY_AX25_SOCK_WAIT, + PATTY_AX25_SOCK_READY +}; + enum patty_ax25_sock_opt { PATTY_AX25_SOCK_IF }; @@ -68,6 +73,7 @@ typedef struct _patty_ax25_sock { enum patty_ax25_version version; enum patty_ax25_sock_status status; enum patty_ax25_sock_mode mode; + enum patty_ax25_sock_flow flow; size_t n_maxlen_tx, n_maxlen_rx, diff --git a/src/server.c b/src/server.c index fb13ec8..d2793ca 100644 --- a/src/server.c +++ b/src/server.c @@ -1416,6 +1416,7 @@ static int handle_rr(patty_ax25_server *server, case PATTY_AX25_FRAME_RESPONSE: sock->vs = frame->nr; + fd_watch(server, sock->fd); patty_timer_start(&sock->timer_t3, PATTY_AX25_SOCK_DEFAULT_KEEPALIVE); @@ -1447,7 +1448,9 @@ static int handle_rnr(patty_ax25_server *server, patty_ax25_sock_send_rnr(sock, PATTY_AX25_FRAME_RESPONSE, 1); case PATTY_AX25_FRAME_RESPONSE: - sock->vs = frame->nr; + sock->flow = PATTY_AX25_SOCK_WAIT; + sock->vs = frame->nr; + fd_clear(server, sock->fd); patty_timer_start(&sock->timer_t3, PATTY_AX25_SOCK_DEFAULT_KEEPALIVE); @@ -1833,7 +1836,7 @@ static int handle_sock(uint32_t key, if (patty_timer_expired(&sock->timer_t3)) { /* - * AX.25 v.2.2 Section 6.7.1.3 "Inactive Link Timer T3" + * AX.25 v.2.2 Section 6.7.1.3, "Inactive Link Timer T3" */ int ret = FD_ISSET(sock->fd, &server->fds_watch)? patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_COMMAND, 1): @@ -1854,13 +1857,21 @@ static int handle_sock(uint32_t key, } /* - * NOTE: See AX.25 2.2, Section 6.4.1, "Sending I Frames" + * AX.25 v2.2, Section 6.4.1, "Sending I Frames" */ - if (sock->vs + sock->n_window_tx == sock->vs) { - fd_clear(server, sock->fd); + if (sock->flow == PATTY_AX25_SOCK_READY) { + if (sock->vs % sock->n_window_tx == sock->n_window_tx - 1) { + sock->flow = PATTY_AX25_SOCK_WAIT; - return patty_ax25_sock_send_rnr(sock, PATTY_AX25_FRAME_COMMAND, 1); - goto done; + fd_clear(server, sock->fd); + + patty_timer_start(&sock->timer_t1, sock->n_ack); + patty_timer_stop(&sock->timer_t3); + + return patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_COMMAND, 1); + } + } else if (sock->flow == PATTY_AX25_SOCK_WAIT) { + sock->flow = PATTY_AX25_SOCK_READY; } if ((len = read(sock->fd, sock->rx_buf, sock->n_maxlen_rx)) < 0) { @@ -1882,7 +1893,7 @@ static int handle_sock(uint32_t key, } /* - * AX.25 v2.2, Section 6.4.1 "Sending I Frames" + * AX.25 v2.2, Section 6.4.1, "Sending I Frames" */ patty_timer_start(&sock->timer_t1, sock->n_ack); diff --git a/src/sock.c b/src/sock.c index 1c38559..6c50e7d 100644 --- a/src/sock.c +++ b/src/sock.c @@ -200,6 +200,7 @@ void patty_ax25_sock_destroy(patty_ax25_sock *sock) { void patty_ax25_sock_init(patty_ax25_sock *sock) { sock->status = PATTY_AX25_SOCK_CLOSED; sock->mode = PATTY_AX25_SOCK_DM; + sock->flow = PATTY_AX25_SOCK_WAIT; sock->n_maxlen_tx = PATTY_AX25_SOCK_DEFAULT_I_LEN; sock->n_maxlen_rx = PATTY_AX25_SOCK_DEFAULT_I_LEN; sock->n_window_tx = PATTY_AX25_SOCK_DEFAULT_WINDOW; @@ -211,9 +212,10 @@ void patty_ax25_sock_init(patty_ax25_sock *sock) { } /* - * AX.25 v2.2 Specification, Section 6.5 "Resetting Procedure" + * AX.25 v2.2, Section 6.5 "Resetting Procedure" */ void patty_ax25_sock_reset(patty_ax25_sock *sock) { + sock->flow = PATTY_AX25_SOCK_READY; sock->vs = 0; sock->vr = 0; sock->va = 0;