diff --git a/include/patty/ax25/sock.h b/include/patty/ax25/sock.h index a2c17ba..0caf556 100644 --- a/include/patty/ax25/sock.h +++ b/include/patty/ax25/sock.h @@ -232,8 +232,9 @@ ssize_t patty_ax25_sock_recv(patty_ax25_sock *sock, ssize_t patty_ax25_sock_recv_pending(patty_ax25_sock *sock); -ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock, - unsigned int seq); +ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock, int seq); + +void patty_ax25_sock_ack(patty_ax25_sock *sock, int seq); ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock, enum patty_ax25_frame_cr cr, diff --git a/src/server.c b/src/server.c index c4076e9..398fd62 100644 --- a/src/server.c +++ b/src/server.c @@ -1484,7 +1484,7 @@ static int handle_segment(patty_ax25_server *server, return 0; reply_rej: - return patty_ax25_sock_send_rej(sock, PATTY_AX25_FRAME_RESPONSE, 1); + return patty_ax25_sock_send_rej(sock, PATTY_AX25_FRAME_RESPONSE, 0); error_write: error_sock_assembler_read: @@ -1501,10 +1501,12 @@ static int handle_i(patty_ax25_server *server, return frame->pf? reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL): 0; } + patty_ax25_sock_ack(sock, frame->nr - 1); + if (sock->vr == frame->ns) { patty_ax25_sock_vr_incr(sock); } else { - return patty_ax25_sock_send_rej(sock, PATTY_AX25_FRAME_RESPONSE, 1); + return patty_ax25_sock_send_rej(sock, PATTY_AX25_FRAME_RESPONSE, 0); } if (frame->proto == PATTY_AX25_PROTO_FRAGMENT) { @@ -1591,6 +1593,8 @@ static int handle_rr(patty_ax25_server *server, return 0; } + patty_ax25_sock_ack(sock, frame->nr - 1); + patty_timer_stop(&sock->timer_t1); switch (frame->cr) { @@ -1604,7 +1608,6 @@ static int handle_rr(patty_ax25_server *server, patty_ax25_sock_send_rnr(sock, PATTY_AX25_FRAME_RESPONSE, 1); case PATTY_AX25_FRAME_RESPONSE: - sock->va = frame->nr; sock->retries = sock->n_retry; fd_watch(server, sock->fd); @@ -1627,6 +1630,8 @@ static int handle_rnr(patty_ax25_server *server, patty_timer_stop(&sock->timer_t1); + patty_ax25_sock_ack(sock, frame->nr - 1); + switch (frame->cr) { case PATTY_AX25_FRAME_COMMAND: if (frame->pf == 0) { @@ -1638,7 +1643,6 @@ 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->va = frame->nr; sock->flow = PATTY_AX25_SOCK_WAIT; sock->retries = sock->n_retry; @@ -1663,7 +1667,7 @@ static int handle_rej(patty_ax25_server *server, return 0; } - sock->va = frame->nr; + patty_ax25_sock_ack(sock, frame->nr - 1); end = sock->vs; @@ -1690,7 +1694,7 @@ static int handle_srej(patty_ax25_server *server, return 0; } - sock->va = frame->nr; + patty_ax25_sock_ack(sock, frame->nr - 1); /* * TODO: Read the fine print of section 4.3.2.4 @@ -2124,14 +2128,18 @@ static int handle_sock(uint32_t key, if (sock->flow == PATTY_AX25_SOCK_WAIT) { sock->flow = PATTY_AX25_SOCK_READY; } else if (patty_ax25_sock_flow_full(sock)) { + int ret; + sock->flow = PATTY_AX25_SOCK_WAIT; fd_clear(server, sock->fd); + ret = patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_COMMAND, 1); + patty_timer_stop(&sock->timer_t3); patty_timer_start(&sock->timer_t1, sock->n_ack); - return 0; + return ret; } if ((len = read(sock->fd, sock->rx_buf, sock->n_maxlen_rx)) < 0) { diff --git a/src/sock.c b/src/sock.c index 9d6ef11..e8a8579 100644 --- a/src/sock.c +++ b/src/sock.c @@ -11,6 +11,11 @@ #include +struct slot { + size_t len; + int ack; +}; + static int bind_pty(patty_ax25_sock *sock) { char *pty; @@ -52,30 +57,29 @@ static inline size_t rx_bufsz(patty_ax25_sock *sock) { } static inline size_t tx_slot_size(patty_ax25_sock *sock) { - return sizeof(size_t) + PATTY_AX25_FRAME_OVERHEAD + sock->n_maxlen_tx; + return sizeof(struct slot) + PATTY_AX25_FRAME_OVERHEAD + sock->n_maxlen_tx; } static inline size_t tx_slots_size(patty_ax25_sock *sock) { return sock->n_window_tx * tx_slot_size(sock); } -static inline void *tx_slot(patty_ax25_sock *sock, size_t seq) { +static inline int tx_seq(patty_ax25_sock *sock, int seq) { + return sock->mode == PATTY_AX25_SOCK_SABME? + (seq + 128) % 128: + (seq + 8) % 8; +} + +static inline struct slot *tx_slot(patty_ax25_sock *sock, int seq) { size_t win = sock->n_window_tx, - i = seq % win; + i = tx_seq(sock, seq) % win; - return (uint8_t *)sock->tx_slots + (i * tx_slot_size(sock)); + return (struct slot *) + ((uint8_t *)sock->tx_slots + (i * tx_slot_size(sock))); } -static inline void tx_slot_save_len(patty_ax25_sock *sock, - size_t seq, - size_t len) { - size_t *size = (size_t *)tx_slot(sock, seq); - - *size = len; -} - -static inline void *tx_slot_buf(patty_ax25_sock *sock, size_t seq) { - return (uint8_t *)tx_slot(sock, seq) + sizeof(size_t); +static inline void *tx_slot_buf(patty_ax25_sock *sock, int seq) { + return (uint8_t *)tx_slot(sock, seq) + sizeof(struct slot); } static int init_bufs(patty_ax25_sock *sock) { @@ -94,7 +98,9 @@ static int init_bufs(patty_ax25_sock *sock) { } for (i=0; in_window_tx; i++) { - tx_slot_save_len(sock, i, 0); + struct slot *slot = tx_slot(sock, i); + + slot->len = 0; } return 0; @@ -506,11 +512,7 @@ void *patty_ax25_sock_assembler_read(patty_ax25_sock *sock, } int patty_ax25_sock_flow_full(patty_ax25_sock *sock) { - if (sock->mode == PATTY_AX25_SOCK_SABME) { - return sock->vs == (sock->va + sock->n_window_tx) % 128? 1: 0; - } - - return sock->vs == (sock->va + sock->n_window_tx) % 8? 1: 0; + return sock->vs == tx_seq(sock, sock->va + sock->n_window_tx)? 1: 0; } static inline int toobig(patty_ax25_sock *sock, @@ -651,14 +653,17 @@ static ssize_t frame_send(patty_ax25_sock *sock, if (info && infolen) { if (PATTY_AX25_FRAME_CONTROL_I(control)) { + struct slot *slot = tx_slot(sock, sock->vs); + buf[offset++] = proto; + + slot->len = offset; + slot->ack = 0; } memcpy(buf + offset, info, infolen); offset += infolen; - - tx_slot_save_len(sock, sock->vs, offset); } return patty_ax25_if_send(sock->iface, buf, offset); @@ -670,14 +675,25 @@ error_noif: return -1; } -ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock, - unsigned int seq) { - void *slot = tx_slot(sock, seq); - void *buf = (uint8_t *)slot + sizeof(size_t); +ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock, int seq) { + struct slot *slot = tx_slot(sock, seq); + void *buf = tx_slot_buf(sock, seq); - size_t len = *((size_t *)slot); + return slot->len > 0? patty_ax25_if_send(sock->iface, buf, slot->len): 0; +} - return len > 0? patty_ax25_if_send(sock->iface, buf, len): 0; +void patty_ax25_sock_ack(patty_ax25_sock *sock, int seq) { + int i; + + for (i=0; in_window_tx; i++) { + struct slot *slot = tx_slot(sock, seq - i); + + if (slot->len > 0) { + slot->ack = 1; + } + } + + sock->va = seq; } static uint16_t control_i(patty_ax25_sock *sock, int flag) {