diff --git a/include/patty/ax25/sock.h b/include/patty/ax25/sock.h index c3507a9..da7c9aa 100644 --- a/include/patty/ax25/sock.h +++ b/include/patty/ax25/sock.h @@ -55,10 +55,6 @@ typedef struct _patty_ax25_sock { enum patty_ax25_sock_status status; enum patty_ax25_sock_mode mode; - struct timeval timer_ack, - timer_response, - timer_keepalive; - size_t n_maxlen_tx, n_maxlen_rx, n_window_tx, @@ -66,12 +62,18 @@ typedef struct _patty_ax25_sock { n_ack, n_retry; - unsigned int seq_send, - seq_recv; + struct timeval timer_ack, /* Timer T1 */ + timer_response, + timer_keepalive; uint32_t flags_classes, flags_hdlc; + unsigned int seq_send, + seq_recv; + + size_t retries; + int fd; char pty[PATTY_AX25_SOCK_PATH_SIZE]; @@ -96,6 +98,15 @@ patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_proto proto, void patty_ax25_sock_destroy(patty_ax25_sock *sock); +void patty_ax25_sock_timer_ack_restart(patty_ax25_sock *sock); + +void patty_ax25_sock_timer_ack_cancel(patty_ax25_sock *sock); + +void patty_ax25_sock_timer_ack_sub(patty_ax25_sock *sock, + struct timeval *elapsed); + +int patty_ax25_sock_timer_ack_expired(patty_ax25_sock *sock); + int patty_ax25_sock_reset(patty_ax25_sock *sock); int patty_ax25_sock_upgrade(patty_ax25_sock *sock, diff --git a/src/sock.c b/src/sock.c index fc4c882..9f34dd4 100644 --- a/src/sock.c +++ b/src/sock.c @@ -179,12 +179,43 @@ void patty_ax25_sock_destroy(patty_ax25_sock *sock) { free(sock); } +/* + * AX.25 v2.2 Specification, Section 6.3.1 "AX.25 Link Connection Establishment" + */ +void patty_ax25_sock_timer_ack_restart(patty_ax25_sock *sock) { + sock->timer_ack.tv_sec = sock->n_ack / 1000; + sock->timer_ack.tv_usec = (sock->n_ack % 1000) * 1000; +} + +void patty_ax25_sock_timer_ack_cancel(patty_ax25_sock *sock) { + sock->timer_ack.tv_sec = 0; + sock->timer_ack.tv_usec = 0; +} + +void patty_ax25_sock_timer_ack_sub(patty_ax25_sock *sock, + struct timeval *elapsed) { + struct timeval res; + + timersub(&sock->timer_ack, elapsed, &res); + + memcpy(&sock->timer_ack, &res, sizeof(sock->timer_ack)); +} + +int patty_ax25_sock_timer_ack_expired(patty_ax25_sock *sock) { + return (sock->timer_ack.tv_sec <= 0 && sock->timer_ack.tv_usec == 0)? 1: 0; +} + /* * AX.25 v2.2 Specification, Section 6.5 "Resetting Procedure" */ int patty_ax25_sock_reset(patty_ax25_sock *sock) { sock->seq_send = 0; sock->seq_recv = 0; + sock->retries = sock->n_retry; + + memset(&sock->timer_ack, '\0', sizeof(sock->timer_ack)); + memset(&sock->timer_response, '\0', sizeof(sock->timer_response)); + memset(&sock->timer_keepalive, '\0', sizeof(sock->timer_keepalive)); return 0; }