libcoap 4.3.5-develop-490e4e0
Loading...
Searching...
No Matches
coap_time.c
Go to the documentation of this file.
1/* coap_time.c -- Clock Handling
2 *
3 * Copyright (C) 2015,2023-2025 Olaf Bergmann <bergmann@tzi.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 *
7 * This file is part of the CoAP library libcoap. Please see
8 * README for terms of use.
9 */
10
17
18#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
19
20#ifdef HAVE_TIME_H
21#include <time.h>
22#endif /* HAVE_TIME_H */
23
24#ifdef HAVE_SYS_TIME_H
25#include <sys/time.h>
26#endif /* HAVE_SYS_TIME_H */
27
28#ifdef HAVE_UNISTD_H
29#include <unistd.h> /* _POSIX_TIMERS */
30#endif /* HAVE_UNISTD_H */
31
32#ifdef HAVE_WINSOCK2_H
33#include <winsock2.h>
34#include <stdint.h>
35#endif /* HAVE_WINSOCK2_H */
36
38
39#if _POSIX_TIMERS && !defined(__APPLE__) && !defined(__MINGW32__)
40/* _POSIX_TIMERS is > 0 when clock_gettime() is available */
41
42/* Use real-time clock for correct timestamps in coap_log(). */
43#define COAP_CLOCK CLOCK_REALTIME
44#endif /* _POSIX_TIMERS && ! __APPLE__ && ! __MINGW32__ */
45
46#if defined(HAVE_WINSOCK2_H) && !defined(__MINGW32__)
47static int
48gettimeofday(struct timeval *tp, TIME_ZONE_INFORMATION *tzp) {
49 (void)tzp;
50 static const uint64_t s_tUnixEpoch = 116444736000000000Ui64;
51
52 FILETIME file_time;
53 ULARGE_INTEGER time;
54 uint64_t tUsSinceUnicEpoch;
55
56 GetSystemTimeAsFileTime(&file_time);
57 time.LowPart = file_time.dwLowDateTime;
58 time.HighPart = file_time.dwHighDateTime;
59 tUsSinceUnicEpoch = (time.QuadPart - s_tUnixEpoch) / 10;
60
61 tp->tv_sec = (long)(tUsSinceUnicEpoch / 1000000);
62 tp->tv_usec = (long)(tUsSinceUnicEpoch % 1000000);
63 return 0;
64}
65#endif /* HAVE_WINSOCK2_H && !__MINGW32__ */
66
67void
69#ifdef COAP_CLOCK
70 struct timespec tv;
71 clock_gettime(COAP_CLOCK, &tv);
72#else /* _POSIX_TIMERS */
73 struct timeval tv;
74 gettimeofday(&tv, NULL);
75#endif /* not _POSIX_TIMERS */
76
77 coap_clock_offset = tv.tv_sec;
78}
79
80/* creates a Qx.frac from fval */
81#define Q(frac,fval) ((1 << (frac)) * (fval))
82
83/* number of frac bits for sub-seconds */
84#define FRAC 10
85
86/* rounds val up and right shifts by frac positions */
87#define SHR_FP(val,frac) (((coap_tick_t)((val) + (1 << ((frac) - 1)))) >> (frac))
88
89void
91 coap_tick_t tmp;
92
93#ifdef COAP_CLOCK
94 struct timespec tv;
95 clock_gettime(COAP_CLOCK, &tv);
96 /* Possible errors are (see clock_gettime(2)):
97 * EFAULT tp points outside the accessible address space.
98 * EINVAL The clk_id specified is not supported on this system.
99 * Both cases should not be possible here.
100 */
101
102 tmp = SHR_FP(tv.tv_nsec * Q(FRAC, (COAP_TICKS_PER_SECOND/1000000000.0)), FRAC);
103#else /* _POSIX_TIMERS */
104 /* Fall back to gettimeofday() */
105
106 struct timeval tv;
107 gettimeofday(&tv, NULL);
108 /* Possible errors are (see gettimeofday(2)):
109 * EFAULT One of tv or tz pointed outside the accessible address space.
110 * EINVAL Timezone (or something else) is invalid.
111 * Both cases should not be possible here.
112 */
113
114 tmp = SHR_FP(tv.tv_usec * Q(FRAC, (COAP_TICKS_PER_SECOND/1000000.0)), FRAC);
115#endif /* not _POSIX_TIMERS */
116
117 /* Finally, convert temporary FP representation to multiple of
118 * COAP_TICKS_PER_SECOND */
119 *t = tmp + (tv.tv_sec - coap_clock_offset) * COAP_TICKS_PER_SECOND;
120}
121
126
127uint64_t
129 return (uint64_t)coap_clock_offset * 1000000 + (uint64_t)t * 1000000 / COAP_TICKS_PER_SECOND;
130}
131
134 return (coap_tick_t)((t - (uint64_t)coap_clock_offset * 1000000) * COAP_TICKS_PER_SECOND / 1000000);
135}
136
137#undef Q
138#undef FRAC
139#undef SHR_FP
140
141#else /* WITH_LWIP || WITH_CONTIKI || RIOT_VERSION */
142
143#ifdef __clang__
144/* Make compilers happy that do not like empty modules. As this function is
145 * never used, we ignore -Wunused-function at the end of compiling this file
146 */
147#pragma GCC diagnostic ignored "-Wunused-function"
148#endif
150dummy(void) {
151}
152
153#endif /* WITH_LWIP || WITH_CONTIKI || RIOT_VERSION */
static void dummy(void)
Library specific build wrapper for coap_internal.h.
#define FRAC
Definition coap_time.c:84
#define SHR_FP(val, frac)
Definition coap_time.c:87
static coap_tick_t coap_clock_offset
Definition coap_time.c:37
#define Q(frac, fval)
Definition coap_time.c:81
coap_tick_t coap_ticks_from_rt_us(uint64_t t)
Helper function that converts POSIX wallclock time in us to coap ticks.
Definition coap_time.c:133
time_t coap_time_t
CoAP time in seconds since epoch.
Definition coap_time.h:156
void coap_clock_init(void)
Initializes the internal clock.
Definition coap_time.c:68
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
Definition coap_time.h:151
coap_time_t coap_ticks_to_rt(coap_tick_t t)
Helper function that converts coap ticks to wallclock time.
Definition coap_time.c:123
#define COAP_TICKS_PER_SECOND
Use ms resolution on POSIX systems.
Definition coap_time.h:166
uint64_t coap_ticks_to_rt_us(coap_tick_t t)
Helper function that converts coap ticks to POSIX wallclock time in us.
Definition coap_time.c:128
void coap_ticks(coap_tick_t *t)
Returns the current value of an internal tick counter.
Definition coap_time.c:90
#define COAP_STATIC_INLINE
Definition libcoap.h:57