1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "hitls_build.h"
17 #ifdef HITLS_BSL_SAL_TIME
18
19 #ifdef HITLS_BSL_ERR
20 #include "bsl_err_internal.h"
21 #endif
22 #include "bsl_sal.h"
23 #include "sal_timeimpl.h"
24 #include "bsl_errno.h"
25 #include "sal_time.h"
26
27 static BSL_SAL_TimeCallback g_timeCallback = {0};
28
SAL_TimeCallback_Ctrl(BSL_SAL_CB_FUNC_TYPE type,void * funcCb)29 int32_t SAL_TimeCallback_Ctrl(BSL_SAL_CB_FUNC_TYPE type, void *funcCb)
30 {
31
32 if (type > BSL_SAL_TIME_TICK_PER_SEC_CB_FUNC || type < BSL_SAL_TIME_GET_UTC_TIME_CB_FUNC) {
33 return BSL_SAL_TIME_NO_REG_FUNC;
34 }
35 uint32_t offset = (uint32_t)(type - BSL_SAL_TIME_GET_UTC_TIME_CB_FUNC);
36 ((void **)&g_timeCallback)[offset] = funcCb;
37 return BSL_SUCCESS;
38 }
39
BSL_SAL_SysTimeFuncReg(BslTimeFunc func)40 void BSL_SAL_SysTimeFuncReg(BslTimeFunc func)
41 {
42 if (func != NULL) {
43 g_timeCallback.pfGetSysTime = func;
44 }
45 return;
46 }
47
BSL_SysTimeFuncUnReg(void)48 void BSL_SysTimeFuncUnReg(void)
49 {
50 g_timeCallback.pfGetSysTime = NULL;
51 return;
52 }
53
BSL_IsLeapYear(uint32_t year)54 bool BSL_IsLeapYear(uint32_t year)
55 {
56 return ((((year % 4U) == 0U) && ((year % 100U) != 0U)) || ((year % 400U) == 0U));
57 }
58
BslMkTime64Get(const BSL_TIME * inputTime)59 static int64_t BslMkTime64Get(const BSL_TIME *inputTime)
60 {
61 int64_t result;
62 uint32_t i;
63 int32_t unixYear;
64 int32_t unixDay;
65 int32_t extraDay = 0;
66 int32_t year = inputTime->year;
67 int32_t month = inputTime->month - 1;
68 int32_t day = inputTime->day;
69 int32_t hour = inputTime->hour;
70 int32_t minute = inputTime->minute;
71 int32_t second = inputTime->second;
72 int32_t monthTable[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
73
74 for (i = BSL_TIME_SYSTEM_EPOCH_YEAR; (int32_t)i < year; i++) {
75 if (BSL_IsLeapYear(i) == true) {
76 extraDay++;
77 }
78 }
79
80 unixYear = year - (int32_t)BSL_TIME_SYSTEM_EPOCH_YEAR;
81 if (BSL_IsLeapYear((uint32_t)year) == true) {
82 for (i = BSL_MONTH_FEB; i < BSL_MONTH_DEC; i++) {
83 monthTable[i] = monthTable[i] + 1;
84 }
85 }
86
87 unixDay = (unixYear * (int32_t)BSL_TIME_DAY_PER_NONLEAP_YEAR) + monthTable[month] + (day - 1) + extraDay;
88 result = unixDay * (int64_t)86400; /* 86400 is the number of seconds in a day */
89 result = (hour * (int64_t)3600) + result; /* 3600 is the number of seconds in a hour */
90 result = (minute * (int64_t)60) + second + result; /* 60 is the number of seconds in a minute */
91
92 return result;
93 }
94
95 /**
96 * @brief Convert the given date structure to the number of seconds since January 1,1970
97 * @param inputTime [IN] Pointer to the date to be converted.
98 * @param utcTime [OUT] Pointer to the storage of the conversion result
99 * @return BSL_SUCCESS successfully executed.
100 * BSL_INTERNAL_EXCEPTION Execution Failure
101 */
BslUtcTimeGet(const BSL_TIME * inputTime,int64_t * utcTime)102 static uint32_t BslUtcTimeGet(const BSL_TIME *inputTime, int64_t *utcTime)
103 {
104 int64_t result;
105
106 if (inputTime == NULL || utcTime == NULL) {
107 return BSL_INTERNAL_EXCEPTION;
108 }
109 if (BSL_DateTimeCheck(inputTime) == false) {
110 return BSL_INTERNAL_EXCEPTION;
111 }
112 result = BslMkTime64Get(inputTime);
113 if (result < 0) {
114 *utcTime = -1;
115 return BSL_INTERNAL_EXCEPTION;
116 } else {
117 *utcTime = result;
118 return BSL_SUCCESS;
119 }
120 }
121
122 #define BSL_TIMESTR_MINLEN 26
123
BSL_DateToStrConvert(const BSL_TIME * dateTime,char * timeStr,size_t len)124 uint32_t BSL_DateToStrConvert(const BSL_TIME *dateTime, char *timeStr, size_t len)
125 {
126 if (dateTime == NULL || timeStr == NULL || len < BSL_TIMESTR_MINLEN) {
127 return BSL_INTERNAL_EXCEPTION;
128 }
129 if (BSL_DateTimeCheck(dateTime) != true) {
130 return BSL_INTERNAL_EXCEPTION;
131 }
132
133 if (g_timeCallback.pfDateToStrConvert != NULL && g_timeCallback.pfDateToStrConvert != BSL_DateToStrConvert) {
134 return g_timeCallback.pfDateToStrConvert(dateTime, timeStr, len);
135 }
136 #ifdef HITLS_BSL_SAL_LINUX
137 return TIME_DateToStrConvert(dateTime, timeStr, len);
138 #else
139 return BSL_SAL_TIME_NO_REG_FUNC;
140 #endif
141 }
142
BSL_SAL_CurrentSysTimeGet(void)143 int64_t BSL_SAL_CurrentSysTimeGet(void)
144 {
145 if (g_timeCallback.pfGetSysTime != NULL && g_timeCallback.pfGetSysTime != BSL_SAL_CurrentSysTimeGet) {
146 return g_timeCallback.pfGetSysTime();
147 }
148 #ifdef HITLS_BSL_SAL_LINUX
149 return TIME_GetSysTime();
150 #else
151 BSL_ERR_PUSH_ERROR(BSL_SAL_TIME_NO_REG_FUNC);
152 return 0;
153 #endif
154 }
155
BslDateTimeCmpCheck(const BSL_TIME * dateA,int64_t * utcTimeA,const BSL_TIME * dateB,int64_t * utcTimeB)156 static uint32_t BslDateTimeCmpCheck(const BSL_TIME *dateA, int64_t *utcTimeA,
157 const BSL_TIME *dateB, int64_t *utcTimeB)
158 {
159 if ((dateA == NULL) || (dateB == NULL)) {
160 return BSL_INTERNAL_EXCEPTION;
161 }
162
163 if (BslUtcTimeGet(dateA, utcTimeA) != BSL_SUCCESS) {
164 return BSL_INTERNAL_EXCEPTION;
165 }
166 if (BslUtcTimeGet(dateB, utcTimeB) != BSL_SUCCESS) {
167 return BSL_INTERNAL_EXCEPTION;
168 }
169
170 return BSL_SUCCESS;
171 }
172
BSL_SAL_DateTimeCompare(const BSL_TIME * dateA,const BSL_TIME * dateB,int64_t * diffSec)173 int32_t BSL_SAL_DateTimeCompare(const BSL_TIME *dateA, const BSL_TIME *dateB, int64_t *diffSec)
174 {
175 int64_t utcTimeA = 0;
176 int64_t utcTimeB = 0;
177 int64_t dTimeDiff;
178 uint32_t ret;
179
180 if (BslDateTimeCmpCheck(dateA, &utcTimeA, dateB, &utcTimeB) == BSL_SUCCESS) {
181 dTimeDiff = utcTimeA - utcTimeB;
182 if (diffSec != NULL) {
183 *diffSec = dTimeDiff;
184 }
185
186 if (dTimeDiff < 0) {
187 ret = (uint32_t)BSL_TIME_DATE_BEFORE;
188 } else if (dTimeDiff > 0) {
189 ret = (uint32_t)BSL_TIME_DATE_AFTER;
190 } else {
191 ret = (uint32_t)BSL_TIME_CMP_EQUAL;
192 }
193 } else {
194 ret = (uint32_t)BSL_TIME_CMP_ERROR;
195 }
196
197 return ret;
198 }
199
TimeCmp(uint32_t a,uint32_t b)200 static uint32_t TimeCmp(uint32_t a, uint32_t b)
201 {
202 if (a > b) {
203 return BSL_TIME_DATE_AFTER;
204 }
205 if (a < b) {
206 return BSL_TIME_DATE_BEFORE;
207 }
208 return BSL_TIME_CMP_EQUAL;
209 }
210
BSL_SAL_DateTimeCompareByUs(const BSL_TIME * dateA,const BSL_TIME * dateB)211 int32_t BSL_SAL_DateTimeCompareByUs(const BSL_TIME *dateA, const BSL_TIME *dateB)
212 {
213 int64_t diffSec = 0;
214 uint32_t ret;
215
216 ret = BSL_SAL_DateTimeCompare(dateA, dateB, &diffSec);
217 if (ret != BSL_TIME_CMP_EQUAL) {
218 return ret;
219 }
220
221 ret = TimeCmp(dateA->millSec, dateB->millSec);
222 if (ret != BSL_TIME_CMP_EQUAL) {
223 return ret;
224 }
225
226 return TimeCmp(dateA->microSec, dateB->microSec);
227 }
228
BSL_DateTimeAddUs(BSL_TIME * dateR,const BSL_TIME * dateA,uint32_t us)229 uint32_t BSL_DateTimeAddUs(BSL_TIME *dateR, const BSL_TIME *dateA, uint32_t us)
230 {
231 uint32_t ret;
232 int64_t utcTime = 0;
233
234 /* Convert the date into seconds. */
235 ret = BSL_SAL_DateToUtcTimeConvert(dateA, &utcTime);
236 if (ret != BSL_SUCCESS) {
237 return ret;
238 }
239
240 /* Convert the increased time to seconds */
241 uint32_t microSec = us + dateA->microSec;
242 uint32_t millSec = (microSec / BSL_SECOND_TRANSFER_RATIO) + dateA->millSec;
243 microSec %= BSL_SECOND_TRANSFER_RATIO;
244 uint32_t second = millSec / BSL_SECOND_TRANSFER_RATIO;
245 millSec %= BSL_SECOND_TRANSFER_RATIO;
246
247 /* Convert to the date after the number of seconds is added */
248 utcTime += (int64_t)second;
249 ret = BSL_SAL_UtcTimeToDateConvert(utcTime, dateR);
250 if (ret != BSL_SUCCESS) {
251 return ret;
252 }
253
254 /* Complete milliseconds and microseconds. */
255 dateR->millSec = (uint16_t)millSec;
256 dateR->microSec = microSec;
257 return BSL_SUCCESS;
258 }
259
BSL_SAL_DateToUtcTimeConvert(const BSL_TIME * dateTime,int64_t * utcTime)260 int32_t BSL_SAL_DateToUtcTimeConvert(const BSL_TIME *dateTime, int64_t *utcTime)
261 {
262 uint32_t ret = BSL_INTERNAL_EXCEPTION;
263
264 if ((dateTime != NULL) && (utcTime != NULL)) {
265 if (BSL_DateTimeCheck(dateTime) == true) {
266 ret = BslUtcTimeGet(dateTime, utcTime);
267 }
268 }
269
270 return ret;
271 }
272
BslFebDayValidCheck(uint16_t year,uint8_t day)273 static bool BslFebDayValidCheck(uint16_t year, uint8_t day)
274 {
275 bool ret;
276
277 if ((BSL_IsLeapYear(year) == true) && (day <= BSL_TIME_LEAP_FEBRUARY_DAY)) {
278 ret = true;
279 } else if ((BSL_IsLeapYear(year) == false) && (day <= BSL_TIME_NOLEAP_FEBRUARY_DAY)) {
280 ret = true;
281 } else {
282 ret = false;
283 }
284 return ret;
285 }
286
BslDayValidCheck(uint16_t year,uint8_t month,uint8_t day)287 static bool BslDayValidCheck(uint16_t year, uint8_t month, uint8_t day)
288 {
289 bool ret = true;
290
291 switch (month) {
292 case BSL_MONTH_JAN:
293 case BSL_MONTH_MAR:
294 case BSL_MONTH_MAY:
295 case BSL_MONTH_JUL:
296 case BSL_MONTH_AUG:
297 case BSL_MONTH_OCT:
298 case BSL_MONTH_DEC:
299 if (day > BSL_TIME_BIG_MONTH_DAY) {
300 ret = false;
301 }
302 break;
303
304 case BSL_MONTH_APR:
305 case BSL_MONTH_JUN:
306 case BSL_MONTH_SEM:
307 case BSL_MONTH_NOV:
308 if (day > BSL_TIME_SMALL_MONTH_DAY) {
309 ret = false;
310 }
311 break;
312
313 case BSL_MONTH_FEB:
314 ret = BslFebDayValidCheck(year, day);
315 break;
316
317 default:
318 ret = false;
319 break;
320 }
321 return ret;
322 }
323
BslYearMonthDayCheck(const BSL_TIME * dateTime)324 static bool BslYearMonthDayCheck(const BSL_TIME *dateTime)
325 {
326 if (dateTime->year < BSL_TIME_SYSTEM_EPOCH_YEAR) {
327 return false;
328 } else if ((dateTime->month < BSL_MONTH_JAN) || (dateTime->month > BSL_MONTH_DEC)) {
329 return false;
330 } else if (dateTime->day < BSL_MONTH_JAN) {
331 return false;
332 } else {
333 return BslDayValidCheck(dateTime->year, dateTime->month, dateTime->day);
334 }
335 }
336
BslHourMinSecCheck(const BSL_TIME * dateTime)337 static bool BslHourMinSecCheck(const BSL_TIME *dateTime)
338 {
339 bool ret;
340
341 if (dateTime->hour > 23U) {
342 ret = false;
343 } else if (dateTime->minute > 59U) {
344 ret = false;
345 } else if (dateTime->second > 59U) {
346 ret = false;
347 } else if (dateTime->millSec > 999U) {
348 ret = false;
349 } else if (dateTime->microSec > 999U) { /* microseconds does not exceed the maximum value 1000 */
350 ret = false;
351 } else {
352 ret = true;
353 }
354
355 return ret;
356 }
357
BSL_DateTimeCheck(const BSL_TIME * dateTime)358 bool BSL_DateTimeCheck(const BSL_TIME *dateTime)
359 {
360 bool ret = true;
361
362 if ((BslYearMonthDayCheck(dateTime) == false) ||
363 (BslHourMinSecCheck(dateTime) == false)) {
364 ret = false;
365 }
366
367 return ret;
368 }
369
BSL_SAL_UtcTimeToDateConvert(int64_t utcTime,BSL_TIME * sysTime)370 int32_t BSL_SAL_UtcTimeToDateConvert(int64_t utcTime, BSL_TIME *sysTime)
371 {
372 if (sysTime == NULL || utcTime > BSL_UTCTIME_MAX) {
373 return BSL_SAL_ERR_BAD_PARAM;
374 }
375 if (g_timeCallback.pfUtcTimeToDateConvert != NULL &&
376 g_timeCallback.pfUtcTimeToDateConvert != (BslSalUtcTimeToDateConvert)BSL_SAL_UtcTimeToDateConvert) {
377 return g_timeCallback.pfUtcTimeToDateConvert(utcTime, sysTime);
378 }
379 #ifdef HITLS_BSL_SAL_LINUX
380 return TIME_UtcTimeToDateConvert(utcTime, sysTime);
381 #else
382 return BSL_SAL_TIME_NO_REG_FUNC;
383 #endif
384 }
385
BSL_SAL_SysTimeGet(BSL_TIME * sysTime)386 int32_t BSL_SAL_SysTimeGet(BSL_TIME *sysTime)
387 {
388 if (sysTime == NULL) {
389 return BSL_SAL_ERR_BAD_PARAM;
390 }
391 if (g_timeCallback.pfSysTimeGet != NULL && g_timeCallback.pfSysTimeGet != (BslSalSysTimeGet)BSL_SAL_SysTimeGet) {
392 return g_timeCallback.pfSysTimeGet(sysTime);
393 }
394 #ifdef HITLS_BSL_SAL_LINUX
395 return TIME_SysTimeGet(sysTime);
396 #else
397 return BSL_SAL_TIME_NO_REG_FUNC;
398 #endif
399 }
400
BSL_SAL_Sleep(uint32_t time)401 void BSL_SAL_Sleep(uint32_t time)
402 {
403 if (g_timeCallback.pfSleep != NULL && g_timeCallback.pfSleep != BSL_SAL_Sleep) {
404 g_timeCallback.pfSleep(time);
405 return;
406 }
407 #ifdef HITLS_BSL_SAL_LINUX
408 SAL_Sleep(time);
409 #endif
410 }
411
BSL_SAL_Tick(void)412 long BSL_SAL_Tick(void)
413 {
414 if (g_timeCallback.pfTick != NULL && g_timeCallback.pfTick != BSL_SAL_Tick) {
415 return g_timeCallback.pfTick();
416 }
417 #ifdef HITLS_BSL_SAL_LINUX
418 return SAL_Tick();
419 #else
420 return BSL_SAL_TIME_NO_REG_FUNC;
421 #endif
422 }
423
BSL_SAL_TicksPerSec(void)424 long BSL_SAL_TicksPerSec(void)
425 {
426 if (g_timeCallback.pfTicksPerSec != NULL && g_timeCallback.pfTicksPerSec != BSL_SAL_TicksPerSec) {
427 return g_timeCallback.pfTicksPerSec();
428 }
429 #ifdef HITLS_BSL_SAL_LINUX
430 return SAL_TicksPerSec();
431 #else
432 return BSL_SAL_TIME_NO_REG_FUNC;
433 #endif
434 }
435
436 #endif /* HITLS_BSL_SAL_TIME */
437