1 /*
2 * Copyright (c) 2023 Nordic Semiconductor ASA
3 *
4 * This software may be distributed under the terms of the BSD license.
5 * See README for more details.
6 */
7
8 #include <zephyr/posix/time.h>
9 #include <zephyr/posix/sys/time.h>
10
11 /* The clock_gettime() would be found in <zephyr/posix/time.h> but
12 * that will cause conflict with picolib definition.
13 */
14 int clock_gettime(clockid_t clock_id, struct timespec *ts);
15
16 #include <zephyr/random/random.h>
17
18 #include "includes.h"
19 #include "os.h"
20
os_sleep(os_time_t sec,os_time_t usec)21 void os_sleep(os_time_t sec, os_time_t usec)
22 {
23 k_sleep(K_USEC(usec + USEC_PER_SEC * sec));
24 }
25
os_get_time(struct os_time * t)26 int os_get_time(struct os_time *t)
27 {
28 int res;
29 struct timeval tv;
30
31 res = gettimeofday(&tv, NULL);
32 t->sec = (os_time_t)tv.tv_sec;
33 t->usec = (os_time_t)tv.tv_usec;
34 return res;
35 }
36
os_get_reltime(struct os_reltime * t)37 int os_get_reltime(struct os_reltime *t)
38 {
39 #if defined(CLOCK_BOOTTIME)
40 static clockid_t clock_id = CLOCK_BOOTTIME;
41 #elif defined(CLOCK_MONOTONIC)
42 static clockid_t clock_id = CLOCK_MONOTONIC;
43 #else
44 static clockid_t clock_id = CLOCK_REALTIME;
45 #endif
46 struct timespec ts;
47 int res;
48
49 if (TEST_FAIL()) {
50 return -1;
51 }
52
53 while (1) {
54 res = clock_gettime(clock_id, &ts);
55 if (res == 0) {
56 t->sec = ts.tv_sec;
57 t->usec = ts.tv_nsec / 1000;
58 return 0;
59 }
60 switch (clock_id) {
61 #ifdef CLOCK_BOOTTIME
62 case CLOCK_BOOTTIME:
63 clock_id = CLOCK_MONOTONIC;
64 break;
65 #endif
66 #ifdef CLOCK_MONOTONIC
67 case CLOCK_MONOTONIC:
68 clock_id = CLOCK_REALTIME;
69 break;
70 #endif
71 case CLOCK_REALTIME:
72 return -1;
73 }
74 }
75 }
76
os_mktime(int year,int month,int day,int hour,int min,int sec,os_time_t * t)77 int os_mktime(int year, int month, int day, int hour, int min, int sec,
78 os_time_t *t)
79 {
80 struct tm tm, *tm1;
81 time_t t_local, t1, t2;
82 os_time_t tz_offset;
83
84 if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
85 hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 ||
86 sec > 60) {
87 return -1;
88 }
89
90 memset(&tm, 0, sizeof(tm));
91 tm.tm_year = year - 1900;
92 tm.tm_mon = month - 1;
93 tm.tm_mday = day;
94 tm.tm_hour = hour;
95 tm.tm_min = min;
96 tm.tm_sec = sec;
97
98 t_local = mktime(&tm);
99
100 /* figure out offset to UTC */
101 tm1 = localtime(&t_local);
102 if (tm1) {
103 t1 = mktime(tm1);
104 tm1 = gmtime(&t_local);
105 if (tm1) {
106 t2 = mktime(tm1);
107 tz_offset = t2 - t1;
108 } else {
109 tz_offset = 0;
110 }
111 } else {
112 tz_offset = 0;
113 }
114
115 *t = (os_time_t)t_local - tz_offset;
116 return 0;
117 }
118
os_gmtime(os_time_t t,struct os_tm * tm)119 int os_gmtime(os_time_t t, struct os_tm *tm)
120 {
121 struct tm *tm2;
122 time_t t2 = t;
123
124 tm2 = gmtime(&t2);
125 if (tm2 == NULL) {
126 return -1;
127 }
128 tm->sec = tm2->tm_sec;
129 tm->min = tm2->tm_min;
130 tm->hour = tm2->tm_hour;
131 tm->day = tm2->tm_mday;
132 tm->month = tm2->tm_mon + 1;
133 tm->year = tm2->tm_year + 1900;
134 return 0;
135 }
136
os_daemonize(const char * pid_file)137 int os_daemonize(const char *pid_file)
138 {
139 return -1;
140 }
141
os_daemonize_terminate(const char * pid_file)142 void os_daemonize_terminate(const char *pid_file)
143 {
144 }
145
os_get_random(unsigned char * buf,size_t len)146 int os_get_random(unsigned char *buf, size_t len)
147 {
148 #if defined(CONFIG_ENTROPY_HAS_DRIVER)
149 return sys_csrand_get(buf, len);
150 #else
151 sys_rand_get(buf, len);
152
153 return 0;
154 #endif
155 }
156
os_random(void)157 unsigned long os_random(void)
158 {
159 return sys_rand32_get();
160 }
161
os_rel2abs_path(const char * rel_path)162 char *os_rel2abs_path(const char *rel_path)
163 {
164 return NULL; /* strdup(rel_path) can be used here */
165 }
166
os_program_init(void)167 int os_program_init(void)
168 {
169 return 0;
170 }
171
os_program_deinit(void)172 void os_program_deinit(void)
173 {
174 }
175
os_setenv(const char * name,const char * value,int overwrite)176 int os_setenv(const char *name, const char *value, int overwrite)
177 {
178 return -1;
179 }
180
os_unsetenv(const char * name)181 int os_unsetenv(const char *name)
182 {
183 return -1;
184 }
185
os_readfile(const char * name,size_t * len)186 char *os_readfile(const char *name, size_t *len)
187 {
188 return NULL;
189 }
190
os_fdatasync(FILE * stream)191 int os_fdatasync(FILE *stream)
192 {
193 return 0;
194 }
195
os_strdup(const char * s)196 char *os_strdup(const char *s)
197 {
198 size_t len;
199 char *d;
200
201 len = os_strlen(s);
202 d = os_malloc(len + 1);
203 if (d == NULL) {
204 return NULL;
205 }
206 os_memcpy(d, s, len);
207 d[len] = '\0';
208 return d;
209 }
210
os_memdup(const void * src,size_t len)211 void *os_memdup(const void *src, size_t len)
212 {
213 void *r = os_malloc(len);
214
215 if (r && src) {
216 os_memcpy(r, src, len);
217 }
218 return r;
219 }
220
os_malloc(size_t size)221 void *os_malloc(size_t size)
222 {
223 return k_malloc(size);
224 }
225
os_free(void * ptr)226 void os_free(void *ptr)
227 {
228 k_free(ptr);
229 }
230
os_realloc(void * ptr,size_t newsize)231 void *os_realloc(void *ptr, size_t newsize)
232 {
233 void *p;
234
235 if (newsize == 0) {
236 os_free(ptr);
237 return NULL;
238 }
239
240 if (ptr == NULL) {
241 return os_malloc(newsize);
242 }
243
244 p = os_zalloc(newsize);
245
246 if (p) {
247 if (ptr != NULL) {
248 memcpy(p, ptr, newsize);
249 os_free(ptr);
250 }
251 }
252
253 return p;
254 }
255
os_zalloc(size_t size)256 void *os_zalloc(size_t size)
257 {
258 void *p = k_malloc(size);
259
260 if (p != NULL) {
261 (void)memset(p, 0, size);
262 }
263 return p;
264 }
265
os_strlcpy(char * dest,const char * src,size_t siz)266 size_t os_strlcpy(char *dest, const char *src, size_t siz)
267 {
268 const char *s = src;
269 size_t left = siz;
270
271 if (left) {
272 /* Copy string up to the maximum size of the dest buffer */
273 while (--left != 0) {
274 if ((*dest++ = *s++) == '\0') {
275 break;
276 }
277 }
278 }
279
280 if (left == 0) {
281 /* Not enough room for the string; force NUL-termination */
282 if (siz != 0) {
283 *dest = '\0';
284 }
285 while (*s++) {
286 ; /* determine total src string length */
287 }
288 }
289
290 return s - src - 1;
291 }
292
os_exec(const char * program,const char * arg,int wait_completion)293 int os_exec(const char *program, const char *arg, int wait_completion)
294 {
295 return -1;
296 }
297
os_memcmp_const(const void * a,const void * b,size_t len)298 int os_memcmp_const(const void *a, const void *b, size_t len)
299 {
300 return memcmp(a, b, len);
301 }
302
os_strcasecmp(const char * s1,const char * s2)303 int os_strcasecmp(const char *s1, const char *s2)
304 {
305 /*
306 * Ignoring case is not required for main functionality, so just use
307 * the case sensitive version of the function.
308 */
309 return os_strcmp(s1, s2);
310 }
311
os_strncasecmp(const char * s1,const char * s2,size_t n)312 int os_strncasecmp(const char *s1, const char *s2, size_t n)
313 {
314 /*
315 * Ignoring case is not required for main functionality, so just use
316 * the case sensitive version of the function.
317 */
318 return os_strncmp(s1, s2, n);
319 }
320