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:
parent
6b603b6048
commit
f96017bc10
1 changed files with 49 additions and 3 deletions
52
src/server.c
52
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue