• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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