Implement handling/sending RNR frames

Changes:

    * When handling RR commands with the P/F flag set, check to see if
      the socket file descriptor is currently being monitored; if so,
      reply RR, otherwise reply RNR

    * When handling RNR commands with the P/F flag set, apply the same
      aforementioned logic as used for handling RR commands

    * When handling RNR responses, clear the socket file descriptor so
      as to avoid infinite loop polling and to indicate that the remote
      station cannot receive packets currently
This commit is contained in:
XANTRONIX Development 2020-08-04 23:33:18 -04:00 committed by XANTRONIX Industrial
parent 6b603b6048
commit f96017bc10

View file

@ -1396,7 +1396,7 @@ reply_dm:
static int handle_rr(patty_ax25_server *server, static int handle_rr(patty_ax25_server *server,
patty_ax25_sock *sock, patty_ax25_sock *sock,
patty_ax25_frame *frame) { patty_ax25_frame *frame) {
if (sock == NULL || frame->pf == 0) { if (sock == NULL) {
return 0; return 0;
} }
@ -1404,10 +1404,17 @@ static int handle_rr(patty_ax25_server *server,
switch (frame->cr) { switch (frame->cr) {
case PATTY_AX25_FRAME_COMMAND: 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: case PATTY_AX25_FRAME_RESPONSE:
sock->vs = frame->nr; sock->vs = frame->nr;
fd_watch(server, sock->fd);
patty_timer_start(&sock->timer_t3, PATTY_AX25_SOCK_DEFAULT_KEEPALIVE); 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; 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, static int handle_rej(patty_ax25_server *server,
patty_ax25_sock *sock, patty_ax25_sock *sock,
patty_ax25_frame *frame) { patty_ax25_frame *frame) {
@ -1615,6 +1656,7 @@ static int handle_frame(patty_ax25_server *server,
switch (frame.type) { switch (frame.type) {
case PATTY_AX25_FRAME_I: return handle_i(server, iface, sock, &frame); 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_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_REJ: return handle_rej(server, sock, &frame);
case PATTY_AX25_FRAME_SREJ: return handle_srej(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); 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" * 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_stop(&sock->timer_t3);
patty_timer_start(&sock->timer_t1, sock->n_ack); 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" * NOTE: See AX.25 2.2, Section 6.4.1, "Sending I Frames"
*/ */
if (sock->vs + sock->n_window_tx == sock->vs) { if (sock->vs + sock->n_window_tx == sock->vs) {
fd_clear(server, sock->fd);
goto done; goto done;
} }
} }