Implement additional socket flow control
Implement the SOCK_WAIT and SOCK_READY socket flow control states to indicate a Receive Ready or Receive Not Ready state on the remote end Other changes: * Fix issue wherein flow control was never halted when the remote end has received k (window) number of frames without the sending station asking for acknowledgment
This commit is contained in:
parent
36f98bf7f0
commit
4d47b62f5f
3 changed files with 28 additions and 9 deletions
|
@ -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,
|
||||
|
|
27
src/server.c
27
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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue