diff --git a/src/server.c b/src/server.c index f779992..1001757 100644 --- a/src/server.c +++ b/src/server.c @@ -1396,7 +1396,7 @@ reply_dm: static int handle_rr(patty_ax25_server *server, patty_ax25_sock *sock, patty_ax25_frame *frame) { - if (sock == NULL || frame->pf == 0) { + if (sock == NULL) { return 0; } @@ -1404,10 +1404,17 @@ static int handle_rr(patty_ax25_server *server, switch (frame->cr) { case PATTY_AX25_FRAME_COMMAND: - return patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_RESPONSE, 1); + if (frame->pf == 0) { + break; + } + + return FD_ISSET(sock->fd, &server->fds_watch)? + patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_RESPONSE, 1): + patty_ax25_sock_send_rnr(sock, PATTY_AX25_FRAME_RESPONSE, 1); 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); @@ -1418,6 +1425,40 @@ static int handle_rr(patty_ax25_server *server, return 0; } +static int handle_rnr(patty_ax25_server *server, + patty_ax25_sock *sock, + patty_ax25_frame *frame) { + if (sock == NULL) { + return 0; + } + + patty_timer_stop(&sock->timer_t1); + + switch (frame->cr) { + case PATTY_AX25_FRAME_COMMAND: + if (frame->pf == 0) { + break; + } + + return FD_ISSET(sock->fd, &server->fds_watch)? + patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_RESPONSE, 1): + patty_ax25_sock_send_rnr(sock, PATTY_AX25_FRAME_RESPONSE, 1); + + case PATTY_AX25_FRAME_RESPONSE: + sock->vs = frame->nr; + fd_clear(server, sock->fd); + + patty_timer_start(&sock->timer_t3, PATTY_AX25_SOCK_DEFAULT_KEEPALIVE); + + break; + + default: + break; + } + + return 0; +} + static int handle_rej(patty_ax25_server *server, patty_ax25_sock *sock, patty_ax25_frame *frame) { @@ -1615,6 +1656,7 @@ static int handle_frame(patty_ax25_server *server, switch (frame.type) { case PATTY_AX25_FRAME_I: return handle_i(server, iface, sock, &frame); case PATTY_AX25_FRAME_RR: return handle_rr(server, sock, &frame); + case PATTY_AX25_FRAME_RNR: return handle_rnr(server, sock, &frame); case PATTY_AX25_FRAME_REJ: return handle_rej(server, sock, &frame); case PATTY_AX25_FRAME_SREJ: return handle_srej(server, sock, &frame); case PATTY_AX25_FRAME_XID: return handle_xid(server, iface, &frame, buf, offset, len); @@ -1761,7 +1803,9 @@ static int handle_sock(uint32_t key, /* * AX.25 v.2.2 Section 6.7.1.3 "Inactive Link Timer T3" */ - int ret = patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_COMMAND, 1); + int ret = FD_ISSET(sock->fd, &server->fds_watch)? + patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_COMMAND, 1): + patty_ax25_sock_send_rnr(sock, PATTY_AX25_FRAME_COMMAND, 1); patty_timer_stop(&sock->timer_t3); patty_timer_start(&sock->timer_t1, sock->n_ack); @@ -1782,6 +1826,8 @@ static int handle_sock(uint32_t key, * NOTE: See AX.25 2.2, Section 6.4.1, "Sending I Frames" */ if (sock->vs + sock->n_window_tx == sock->vs) { + fd_clear(server, sock->fd); + goto done; } }