Implement generic timer functions in src/timer.c

Changes:

    * Implement patty_timer_expired() to determine if a timer has
      expired or has gone negative

    * Implement patty_timer_cancel() to set a timer to zero

    * Implement patty_timer_start() to initialize a timer, add a
      specified number of milliseconds, and ensure a target timer (such
      as the server timer) is set for at least that value as well

    * Implement patty_timer_tick() to subtract an elapsed time value
      from a timer

    * Remove functions specific to each timer in src/sock.c, as those
      can now be handled generically by src/timer.c

    * Replace calls to patty_ax25_sock_timer_t1_*() with patty_timer_*()
      calls instead; reference the struct timeval objects directly
      within the sock (for the time being, pending opaque structures)
This commit is contained in:
XANTRONIX Development 2020-07-30 01:26:55 -04:00 committed by XANTRONIX Industrial
parent 1060ff6ab8
commit e10ce6b8e1
6 changed files with 66 additions and 55 deletions

View file

@ -98,16 +98,6 @@ patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_proto proto,
void patty_ax25_sock_destroy(patty_ax25_sock *sock);
int patty_ax25_sock_timer_t1_expired(patty_ax25_sock *sock);
void patty_ax25_sock_timer_t1_cancel(patty_ax25_sock *sock);
void patty_ax25_sock_timer_t1_start(patty_ax25_sock *sock,
struct timeval *timer);
void patty_ax25_sock_timer_t1_sub(patty_ax25_sock *sock,
struct timeval *elapsed);
int patty_ax25_sock_reset(patty_ax25_sock *sock);
int patty_ax25_sock_upgrade(patty_ax25_sock *sock,

17
include/patty/timer.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef _PATTY_TIMER_H
#define _PATTY_TIMER_H
#include <sys/time.h>
int patty_timer_expired(struct timeval *timer);
void patty_timer_cancel(struct timeval *timer);
void patty_timer_start(struct timeval *timer,
struct timeval *target,
time_t ms);
void patty_timer_tick(struct timeval *timer,
struct timeval *elapsed);
#endif /* _PATTY_TIMER_H */

View file

@ -8,10 +8,12 @@ CFLAGS = $(CGFLAGS) -fPIC -Wall -O2 -I$(INCLUDE_PATH)
LDFLAGS =
HEADERS = kiss.h ax25.h ax25/if.h ax25/call.h ax25/frame.h ax25/sock.h \
ax25/route.h ax25/server.h list.h hash.h dict.h print.h
ax25/route.h ax25/server.h list.h hash.h dict.h timer.h \
print.h
OBJS = kiss.o ax25.o if.o call.o frame.o sock.o route.o server.o \
list.o hash.o dict.o print.o
OBJS = kiss.o ax25.o if.o call.o frame.o sock.o \
route.o server.o list.o hash.o dict.o timer.o \
print.o
VERSION_MAJOR = 0
VERSION_MINOR = 0.1

View file

@ -11,6 +11,7 @@
#include <patty/ax25.h>
#include <patty/hash.h>
#include <patty/timer.h>
typedef int (*patty_ax25_server_call)(patty_ax25_server *, int);
@ -829,7 +830,7 @@ static int server_connect(patty_ax25_server *server,
return respond_connect(client, -1, errno);
}
patty_ax25_sock_timer_t1_start(sock, &server->timer);
patty_timer_start(&sock->timer_t1, &server->timer, sock->n_ack);
/*
* At this point, we will wait for a DM, FRMR or XID response, which
@ -1152,7 +1153,7 @@ static int handle_frmr(patty_ax25_server *server,
if (sock->status == PATTY_AX25_SOCK_PENDING_CONNECT) {
int ret = patty_ax25_sock_send_sabm(sock, PATTY_AX25_FRAME_POLL);
patty_ax25_sock_timer_t1_start(sock, &server->timer);
patty_timer_start(&sock->timer_t1, &server->timer, sock->n_ack);
return ret;
}
@ -1250,7 +1251,7 @@ static int handle_ua(patty_ax25_server *server,
return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL);
}
patty_ax25_sock_timer_t1_cancel(sock);
patty_timer_cancel(&sock->timer_t1);
sock->status = PATTY_AX25_SOCK_ESTABLISHED;
@ -1452,7 +1453,7 @@ static int handle_xid(patty_ax25_server *server,
ret = patty_ax25_sock_send_sabm(remote, PATTY_AX25_FRAME_POLL);
patty_ax25_sock_timer_t1_start(remote, &server->timer);
patty_timer_start(&remote->timer_t1, &server->timer, remote->n_ack);
return ret;
}
@ -1629,11 +1630,11 @@ static int handle_sock(uint32_t key,
ssize_t len;
if (sock->status == PATTY_AX25_SOCK_PENDING_CONNECT) {
if (patty_ax25_sock_timer_t1_expired(sock)) {
if (patty_timer_expired(&sock->timer_t1)) {
if (sock->retries) {
int ret = patty_ax25_sock_send_sabm(sock, PATTY_AX25_FRAME_POLL);
patty_ax25_sock_timer_t1_start(sock, &server->timer);
patty_timer_start(&sock->timer_t1, &server->timer, sock->n_ack);
return ret;
} else {
@ -1642,7 +1643,7 @@ static int handle_sock(uint32_t key,
return sock_close(server, sock);
}
} else {
patty_ax25_sock_timer_t1_sub(sock, &server->elapsed);
patty_timer_tick(&sock->timer_t1, &server->elapsed);
}
goto done;

View file

@ -173,41 +173,6 @@ void patty_ax25_sock_destroy(patty_ax25_sock *sock) {
free(sock);
}
int patty_ax25_sock_timer_t1_expired(patty_ax25_sock *sock) {
return (sock->timer_t1.tv_sec <= 0 && sock->timer_t1.tv_usec == 0)? 1: 0;
}
void patty_ax25_sock_timer_t1_cancel(patty_ax25_sock *sock) {
sock->timer_t1.tv_sec = 0;
sock->timer_t1.tv_usec = 0;
}
/*
* AX.25 v2.2 Specification, Section 6.3.1 "AX.25 Link Connection Establishment"
*/
void patty_ax25_sock_timer_t1_start(patty_ax25_sock *sock,
struct timeval *timer) {
sock->timer_t1.tv_sec = sock->n_ack / 1000;
sock->timer_t1.tv_usec = (sock->n_ack % 1000) * 1000;
if (timercmp(&sock->timer_t1, timer, >)) {
struct timeval res;
timeradd(timer, &sock->timer_t1, &res);
memcpy(timer, &res, sizeof(*timer));
}
}
void patty_ax25_sock_timer_t1_sub(patty_ax25_sock *sock,
struct timeval *elapsed) {
struct timeval res;
timersub(&sock->timer_t1, elapsed, &res);
memcpy(&sock->timer_t1, &res, sizeof(sock->timer_t1));
}
/*
* AX.25 v2.2 Specification, Section 6.5 "Resetting Procedure"
*/

36
src/timer.c Normal file
View file

@ -0,0 +1,36 @@
#include <patty/timer.h>
int patty_timer_expired(struct timeval *timer) {
return (timer->tv_sec <= 0 && timer->tv_usec == 0)? 1: 0;
}
void patty_timer_cancel(struct timeval *timer) {
timer->tv_sec = 0;
timer->tv_usec = 0;
}
void patty_timer_start(struct timeval *timer,
struct timeval *target,
time_t ms) {
timer->tv_sec = ms / 1000;
timer->tv_usec = (ms % 1000) * 1000;
if (timercmp(timer, target, >)) {
struct timeval res;
timeradd(timer, target, &res);
timer->tv_sec = res.tv_sec;
timer->tv_usec = res.tv_usec;
}
}
void patty_timer_tick(struct timeval *timer,
struct timeval *elapsed) {
struct timeval res;
timersub(timer, elapsed, &res);
timer->tv_sec = res.tv_sec;
timer->tv_usec = res.tv_usec;
}