From fb291010500db105dda4efa9d00706d081610658 Mon Sep 17 00:00:00 2001 From: Kamil Zulewski <kamil.zulewski@iopsys.eu> Date: Mon, 13 Nov 2023 16:46:31 +0100 Subject: [PATCH] Move time related utility functions to timer.h --- src/backhaul_topology.c | 1 + src/backhaul_topology_dbg.c | 2 +- src/cntlr_cmdu.c | 1 + src/timer.c | 189 +++++++++++++++++++++++++++++++++++- src/timer.h | 20 ++++ src/utils/utils.c | 163 ------------------------------- src/utils/utils.h | 11 --- src/wifi_opclass.c | 2 +- 8 files changed, 210 insertions(+), 179 deletions(-) diff --git a/src/backhaul_topology.c b/src/backhaul_topology.c index febfa780..66d2f300 100644 --- a/src/backhaul_topology.c +++ b/src/backhaul_topology.c @@ -1,6 +1,7 @@ #include "backhaul_topology.h" #include "backhaul_topology_dbg.h" +#include "timer.h" #include "utils/debug.h" #include "utils/utils.h" diff --git a/src/backhaul_topology_dbg.c b/src/backhaul_topology_dbg.c index aa3800a5..23471cba 100644 --- a/src/backhaul_topology_dbg.c +++ b/src/backhaul_topology_dbg.c @@ -1,7 +1,7 @@ #include "backhaul_topology_dbg.h" #include "backhaul_topology.h" #include "utils/debug.h" -#include "utils/utils.h" +#include "timer.h" #include <easy/easy.h> #include <libubox/list.h> diff --git a/src/cntlr_cmdu.c b/src/cntlr_cmdu.c index 166e43a8..273c3538 100644 --- a/src/cntlr_cmdu.c +++ b/src/cntlr_cmdu.c @@ -44,6 +44,7 @@ #include "utils/utils.h" #include "utils/debug.h" #include "utils/liblist.h" +#include "timer.h" #include "config.h" #if (EASYMESH_VERSION > 2) #include "dpp.h" diff --git a/src/timer.c b/src/timer.c index 7643da79..0a0829a0 100644 --- a/src/timer.c +++ b/src/timer.c @@ -9,14 +9,15 @@ * */ +#define _DEFAULT_SOURCE +#define _XOPEN_SOURCE + #include <stdio.h> #include <stdint.h> #include <stdlib.h> +#include <string.h> #include <time.h> #include <sys/time.h> -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif #include "timer.h" @@ -77,3 +78,185 @@ int timer_remaining_ms(atimer_t *t) return res.tv_sec + res.tv_usec / 1000; } + +void timestamp_reset(struct timespec *ts) +{ + ts->tv_sec = 0; + ts->tv_nsec = 0; +} + +void timestamp_update(struct timespec *ts) +{ + if (clock_gettime(CLOCK_REALTIME, ts) < 0) { + ts->tv_sec = 0; + ts->tv_nsec = 0; + } +} + +int timestamp_invalid(struct timespec *ts) +{ + return ts->tv_sec == 0 && ts->tv_nsec == 0; +} + +/* Time difference in seconds */ +uint32_t timestamp_elapsed_sec(const struct timespec *ts) +{ + struct timespec now; + uint32_t elapsed; + + if (ts->tv_sec == 0) + return -1; + + /* seconds and nanoseconds since the Epoch */ + if (clock_gettime(CLOCK_REALTIME, &now) < 0) + now.tv_sec = 0; + + elapsed = now.tv_sec - ts->tv_sec; + + return (elapsed > 0) ? elapsed : 0; +} + +/* check if timestamp expired */ +int timestamp_expired(struct timespec *a, unsigned int tmo_ms) +{ + struct timespec now; + unsigned long diff_ns = 0, diff_s = 0; + + /* seconds and nanoseconds since the Epoch */ + if (clock_gettime(CLOCK_REALTIME, &now) < 0) + return -1; + + diff_s = now.tv_sec - a->tv_sec; + diff_ns = now.tv_nsec - a->tv_nsec; + if ((long)diff_ns < 0) { + diff_ns += 1000000000UL; + diff_s--; + } + + if (diff_s * 1000 + diff_ns / 1000000 >= tmo_ms) + return 1; + + return 0; +} + +char *time_to_timestamp(const time_t *t, char *tsp) +{ + char tmpbuf[64] = {0}; + struct tm res; + char sign; + long int toff, toff_hour, toff_min; + + if (!tsp) + return NULL; + + /* E.g. "2019-02-11T06:42:31.23039-08:00" */ + + localtime_r(t, &res); + tzset(); + toff = timezone; + sign = toff > 0 ? '-' : '+'; + toff *= -1L; + + toff_hour = toff / 3600; + toff_min = (toff % 3600) / 60; + + snprintf(tmpbuf, sizeof(tmpbuf), "%04d-%02d-%02dT%02d:%02d:%02d%c%02ld:%02ld", + res.tm_year + 1900, res.tm_mon + 1, res.tm_mday, + res.tm_hour, res.tm_min, res.tm_sec, + sign, toff_hour, toff_min); + + snprintf(tsp, 64, "%s", tmpbuf); + return tsp; +} + +/* get time adjustment seconds (time(tzone) - time(UTC) secs) */ +static long int timestamp_get_off_sec(const char *tsp) +{ + char *tzone; + long int toff = 0, sign; + int toff_hour, toff_min; + + /* Example timestamp: "2019-02-11T06:42:31-08:00" */ + + tzone = strchr(tsp, '+'); + if (!tzone) { + tzone = strrchr(tsp, '-'); /* last occurence */ + sign = -1L; + } else { + sign = +1L; + } + + if (tzone) { + sscanf(tzone+1, "%02d:%02d", &toff_hour, &toff_min); + toff = toff_hour * 3600 + toff_min * 60; // seconds + toff *= -sign; + } + + return toff; +} + +/* Returns time alligned to UTC+0 */ +time_t timestamp_to_time(const char *tsp) +{ + struct tm tm_time; + time_t res; + + /* Example timestamp: "2019-02-11T06:42:31-08:00" */ + memset(&tm_time, 0, sizeof(tm_time)); + strptime(tsp, "%Y-%m-%dT%H:%M:%S", &tm_time); + + tzset(); + res = mktime(&tm_time); + + /* Allign by toff to get UTC+0 */ + res += timestamp_get_off_sec(tsp); + + return res; +} + +struct timespec time_to_timespec(time_t t) +{ + struct timespec res = {}; + + res.tv_sec = t; + res.tv_nsec = 0; + + return res; +} + +/* converts timestamp string to timespec struct + * adj_rtime true: adjust for realtime (ignore off time) + */ +struct timespec timestamp_to_timespec(const char *tsp, bool adj_rtime) +{ + time_t tt = 0; + + tt = timestamp_to_time(tsp); + if (adj_rtime) + tt -= timestamp_get_off_sec(tsp); + + return time_to_timespec(tt); +} + +bool timestamp_less_than(const struct timespec *lhs, const struct timespec *rhs) +{ + if (lhs->tv_sec == rhs->tv_sec) + return lhs->tv_nsec < rhs->tv_nsec; + else + return lhs->tv_sec < rhs->tv_sec; +} + +bool timestamp_greater_than(const struct timespec *lhs, const struct timespec *rhs) +{ + return timestamp_less_than(rhs, lhs); +} + +bool timestamp_greater_or_equal(const struct timespec *lhs, const struct timespec *rhs) +{ + return !timestamp_less_than(lhs, rhs); +} + +bool timestamp_less_or_equal(const struct timespec *lhs, const struct timespec *rhs) +{ + return !timestamp_less_than(rhs, lhs); +} diff --git a/src/timer.h b/src/timer.h index 51a590df..ac1f1889 100644 --- a/src/timer.h +++ b/src/timer.h @@ -19,10 +19,30 @@ #error "atimer_t not defined!" #endif +#include <stdbool.h> +#include <time.h> + void timer_init(atimer_t *t, void (*function)(atimer_t *)); int timer_set(atimer_t *t, uint32_t tmo_ms); int timer_del(atimer_t *t); int timer_pending(atimer_t *t); int timer_remaining_ms(atimer_t *t); +void timestamp_reset(struct timespec *ts); +void timestamp_update(struct timespec *ts); +int timestamp_invalid(struct timespec *ts); + +bool timestamp_less_than(const struct timespec *lhs, const struct timespec *rhs); +bool timestamp_greater_than(const struct timespec *lhs, const struct timespec *rhs); +bool timestamp_greater_or_equal(const struct timespec *lhs, const struct timespec *rhs); +bool timestamp_less_or_equal(const struct timespec *lhs, const struct timespec *rhs); + +uint32_t timestamp_elapsed_sec(const struct timespec *ts); +int timestamp_expired(struct timespec *a, unsigned int tmo_ms); +char *time_to_timestamp(const time_t *t, char *tsp); +time_t timestamp_to_time(const char *tsp); +struct timespec time_to_timespec(time_t t); +struct timespec timestamp_to_timespec(const char *tsp, bool adj_rtime); + + #endif /* ATIMER_H */ diff --git a/src/utils/utils.c b/src/utils/utils.c index 7756efcb..bce0128a 100644 --- a/src/utils/utils.c +++ b/src/utils/utils.c @@ -7,12 +7,9 @@ * */ -#define _DEFAULT_SOURCE -#define _XOPEN_SOURCE #include <stdio.h> #include <string.h> #include <signal.h> -#include <time.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> @@ -151,166 +148,6 @@ int hwaddr_from_ip(char *ifname, char *ipstr, unsigned char *hw) return 0; } -void timestamp_reset(struct timespec *ts) -{ - ts->tv_sec = 0; - ts->tv_nsec = 0; -} - -void timestamp_update(struct timespec *ts) -{ - if (clock_gettime(CLOCK_REALTIME, ts) < 0) { - ts->tv_sec = 0; - ts->tv_nsec = 0; - } -} - -int timestamp_invalid(struct timespec *ts) -{ - return ts->tv_sec == 0 && ts->tv_nsec == 0; -} - -/* Time difference in seconds */ -uint32_t timestamp_elapsed_sec(const struct timespec *ts) -{ - struct timespec now; - uint32_t elapsed; - - if (ts->tv_sec == 0) - return -1; - - /* seconds and nanoseconds since the Epoch */ - if (clock_gettime(CLOCK_REALTIME, &now) < 0) - now.tv_sec = 0; - - elapsed = now.tv_sec - ts->tv_sec; - - return (elapsed > 0) ? elapsed : 0; -} - -/* check if timestamp expired */ -int timestamp_expired(struct timespec *a, unsigned int tmo_ms) -{ - struct timespec now; - unsigned long diff_ns = 0, diff_s = 0; - - /* seconds and nanoseconds since the Epoch */ - if (clock_gettime(CLOCK_REALTIME, &now) < 0) - return -1; - - diff_s = now.tv_sec - a->tv_sec; - diff_ns = now.tv_nsec - a->tv_nsec; - if ((long)diff_ns < 0) { - diff_ns += 1000000000UL; - diff_s--; - } - - if (diff_s * 1000 + diff_ns / 1000000 >= tmo_ms) - return 1; - - return 0; -} - -char *time_to_timestamp(const time_t *t, char *tsp) -{ - char tmpbuf[64] = {0}; - struct tm res; - char sign; - long int toff, toff_hour, toff_min; - - if (!tsp) - return NULL; - - /* E.g. "2019-02-11T06:42:31.23039-08:00" */ - - localtime_r(t, &res); - tzset(); - toff = timezone; - sign = toff > 0 ? '-' : '+'; - toff *= -1L; - - toff_hour = toff / 3600; - toff_min = (toff % 3600) / 60; - - snprintf(tmpbuf, sizeof(tmpbuf), "%04d-%02d-%02dT%02d:%02d:%02d%c%02ld:%02ld", - res.tm_year + 1900, res.tm_mon + 1, res.tm_mday, - res.tm_hour, res.tm_min, res.tm_sec, - sign, toff_hour, toff_min); - - snprintf(tsp, 64, "%s", tmpbuf); - return tsp; -} - -/* get time adjustment seconds (time(tzone) - time(UTC) secs) */ -static long int timestamp_get_off_sec(const char *tsp) -{ - char *tzone; - long int toff = 0, sign; - int toff_hour, toff_min; - - /* Example timestamp: "2019-02-11T06:42:31-08:00" */ - - tzone = strchr(tsp, '+'); - if (!tzone) { - tzone = strrchr(tsp, '-'); /* last occurence */ - sign = -1L; - } else { - sign = +1L; - } - - if (tzone) { - sscanf(tzone+1, "%02d:%02d", &toff_hour, &toff_min); - toff = toff_hour * 3600 + toff_min * 60; // seconds - toff *= -sign; - } - - return toff; -} - -/* Returns time alligned to UTC+0 */ -time_t timestamp_to_time(const char *tsp) -{ - struct tm tm_time; - time_t res; - - /* Example timestamp: "2019-02-11T06:42:31-08:00" */ - memset(&tm_time, 0, sizeof(tm_time)); - strptime(tsp, "%Y-%m-%dT%H:%M:%S", &tm_time); - - tzset(); - res = mktime(&tm_time); - - /* Allign by toff to get UTC+0 */ - res += timestamp_get_off_sec(tsp); - - return res; -} - -struct timespec time_to_timespec(time_t t) -{ - struct timespec res = {}; - - res.tv_sec = t; - res.tv_nsec = 0; - - return res; -} - -/* converts timestamp string to timespec struct - * adj_rtime true: adjust for realtime (ignore off time) - */ -struct timespec timestamp_to_timespec(const char *tsp, bool adj_rtime) -{ - time_t tt = 0; - - tt = timestamp_to_time(tsp); - if (adj_rtime) - tt -= timestamp_get_off_sec(tsp); - - return time_to_timespec(tt); -} - - /** list utility functions */ /** * list_num_entries - gets number of entries on the list diff --git a/src/utils/utils.h b/src/utils/utils.h index 154c5031..98a7e9c2 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -10,7 +10,6 @@ #ifndef UTILS_H #define UTILS_H -#include <time.h> #include <stdbool.h> #include <json-c/json.h> #include <libubox/list.h> @@ -42,16 +41,6 @@ unsigned char *hwaddr_aton(const char *macstr, unsigned char *mac); char *hwaddr_ntoa(const unsigned char *mac, char *macstr); int hwaddr_from_ip(char *ifname, char *ipstr, unsigned char *hw); -void timestamp_reset(struct timespec *ts); -void timestamp_update(struct timespec *ts); -int timestamp_invalid(struct timespec *ts); -uint32_t timestamp_elapsed_sec(const struct timespec *ts); -int timestamp_expired(struct timespec *a, unsigned int tmo_ms); -char *time_to_timestamp(const time_t *t, char *tsp); -time_t timestamp_to_time(const char *tsp); -struct timespec time_to_timespec(time_t *t); -struct timespec timestamp_to_timespec(const char *tsp, bool adj_rtime); - /* bytes from-to hexstring helper functions */ int hex2byte(const char *hex); unsigned char *strtob(char *str, int len, unsigned char *bytes); diff --git a/src/wifi_opclass.c b/src/wifi_opclass.c index ba6048b5..3b7fec49 100644 --- a/src/wifi_opclass.c +++ b/src/wifi_opclass.c @@ -8,7 +8,7 @@ #include <easymesh.h> #include <wifidefs.h> -#include "utils/utils.h" +#include "timer.h" #include "utils/debug.h" #include "wifi_dataelements.h" #include "wifi_opclass.h" -- GitLab