1060ff233Sopenharmony_ci/*
2060ff233Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3060ff233Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4060ff233Sopenharmony_ci * you may not use this file except in compliance with the License.
5060ff233Sopenharmony_ci * You may obtain a copy of the License at
6060ff233Sopenharmony_ci *
7060ff233Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8060ff233Sopenharmony_ci *
9060ff233Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10060ff233Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11060ff233Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12060ff233Sopenharmony_ci * See the License for the specific language governing permissions and
13060ff233Sopenharmony_ci * limitations under the License.
14060ff233Sopenharmony_ci */
15060ff233Sopenharmony_ci
16060ff233Sopenharmony_ci#include "softbus_adapter_timer.h"
17060ff233Sopenharmony_ci
18060ff233Sopenharmony_ci#include <errno.h>
19060ff233Sopenharmony_ci#include <signal.h>
20060ff233Sopenharmony_ci#include <sys/stat.h>
21060ff233Sopenharmony_ci#include <sys/time.h>
22060ff233Sopenharmony_ci#include <time.h>
23060ff233Sopenharmony_ci#include <unistd.h>
24060ff233Sopenharmony_ci
25060ff233Sopenharmony_ci#include "comm_log.h"
26060ff233Sopenharmony_ci#include "securec.h"
27060ff233Sopenharmony_ci#include "softbus_def.h"
28060ff233Sopenharmony_ci#include "softbus_errcode.h"
29060ff233Sopenharmony_ci
30060ff233Sopenharmony_ci#define MS_PER_SECOND 1000
31060ff233Sopenharmony_ci#define US_PER_MSECOND 1000
32060ff233Sopenharmony_ci#define NS_PER_USECOND 1000
33060ff233Sopenharmony_ci#define DATE_TIME_BUFF_LEN 24 // yyyy-MM-dd HH:mm:ss.SSS
34060ff233Sopenharmony_ci
35060ff233Sopenharmony_cistatic unsigned int g_timerType;
36060ff233Sopenharmony_ci__attribute__((no_sanitize("hwaddress"))) static TimerFunc g_timerFunc = NULL;
37060ff233Sopenharmony_cistatic _Thread_local char g_dateTimeBuff[DATE_TIME_BUFF_LEN] = {0};
38060ff233Sopenharmony_ci
39060ff233Sopenharmony_ci__attribute__((no_sanitize("hwaddress"))) static void HandleTimeoutAdapterFun(union sigval para)
40060ff233Sopenharmony_ci{
41060ff233Sopenharmony_ci    (void)para;
42060ff233Sopenharmony_ci    if (g_timerFunc != NULL) {
43060ff233Sopenharmony_ci        g_timerFunc();
44060ff233Sopenharmony_ci    }
45060ff233Sopenharmony_ci}
46060ff233Sopenharmony_ci
47060ff233Sopenharmony_ci__attribute__((no_sanitize("hwaddress"))) void SetTimerFunc(TimerFunc func)
48060ff233Sopenharmony_ci{
49060ff233Sopenharmony_ci    g_timerFunc = func;
50060ff233Sopenharmony_ci}
51060ff233Sopenharmony_ci
52060ff233Sopenharmony_civoid *SoftBusCreateTimer(void **timerId, unsigned int type)
53060ff233Sopenharmony_ci{
54060ff233Sopenharmony_ci    if (timerId == NULL) {
55060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "timerId is null");
56060ff233Sopenharmony_ci        return NULL;
57060ff233Sopenharmony_ci    }
58060ff233Sopenharmony_ci    struct sigevent envent;
59060ff233Sopenharmony_ci    (void)memset_s(&envent, sizeof(envent), 0, sizeof(envent));
60060ff233Sopenharmony_ci    envent.sigev_notify = SIGEV_THREAD;
61060ff233Sopenharmony_ci    envent.sigev_notify_function = HandleTimeoutAdapterFun;
62060ff233Sopenharmony_ci    envent.sigev_notify_attributes = NULL;
63060ff233Sopenharmony_ci
64060ff233Sopenharmony_ci    g_timerType = type;
65060ff233Sopenharmony_ci    if (timer_create(CLOCK_REALTIME, &envent, timerId) != 0) {
66060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "timer create error, errnoCode=%{public}d", errno);
67060ff233Sopenharmony_ci        return NULL;
68060ff233Sopenharmony_ci    }
69060ff233Sopenharmony_ci
70060ff233Sopenharmony_ci    return *timerId;
71060ff233Sopenharmony_ci}
72060ff233Sopenharmony_ci
73060ff233Sopenharmony_ciint SoftBusStartTimer(void *timerId, unsigned int tickets)
74060ff233Sopenharmony_ci{
75060ff233Sopenharmony_ci    if (timerId == NULL) {
76060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "timerId is null");
77060ff233Sopenharmony_ci        return SOFTBUS_ERR;
78060ff233Sopenharmony_ci    }
79060ff233Sopenharmony_ci    struct itimerspec value;
80060ff233Sopenharmony_ci    (void)memset_s(&value, sizeof(value), 0, sizeof(value));
81060ff233Sopenharmony_ci    value.it_value.tv_sec = tickets / MS_PER_SECOND;
82060ff233Sopenharmony_ci    value.it_value.tv_nsec = 0;
83060ff233Sopenharmony_ci    if (g_timerType == TIMER_TYPE_ONCE) {
84060ff233Sopenharmony_ci        value.it_interval.tv_sec = 0;
85060ff233Sopenharmony_ci        value.it_interval.tv_nsec = 0;
86060ff233Sopenharmony_ci    } else {
87060ff233Sopenharmony_ci        value.it_interval.tv_sec = tickets / MS_PER_SECOND;
88060ff233Sopenharmony_ci        value.it_interval.tv_nsec = 0;
89060ff233Sopenharmony_ci    }
90060ff233Sopenharmony_ci
91060ff233Sopenharmony_ci    if (timer_settime(timerId, 0, &value, NULL) != 0) {
92060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "timer start error, errnoCode=%{public}d", errno);
93060ff233Sopenharmony_ci        return SOFTBUS_ERR;
94060ff233Sopenharmony_ci    }
95060ff233Sopenharmony_ci
96060ff233Sopenharmony_ci    return SOFTBUS_OK;
97060ff233Sopenharmony_ci}
98060ff233Sopenharmony_ci
99060ff233Sopenharmony_ciint SoftBusDeleteTimer(void *timerId)
100060ff233Sopenharmony_ci{
101060ff233Sopenharmony_ci    if (timerId == NULL) {
102060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "timerId is null");
103060ff233Sopenharmony_ci        return SOFTBUS_ERR;
104060ff233Sopenharmony_ci    }
105060ff233Sopenharmony_ci
106060ff233Sopenharmony_ci    if (timer_delete(timerId) != 0) {
107060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "timer delete err, errnoCode=%{public}d", errno);
108060ff233Sopenharmony_ci        return SOFTBUS_ERR;
109060ff233Sopenharmony_ci    }
110060ff233Sopenharmony_ci
111060ff233Sopenharmony_ci    return SOFTBUS_OK;
112060ff233Sopenharmony_ci}
113060ff233Sopenharmony_ci
114060ff233Sopenharmony_ciint SoftBusSleepMs(unsigned int ms)
115060ff233Sopenharmony_ci{
116060ff233Sopenharmony_ci    int ret;
117060ff233Sopenharmony_ci    struct timeval tm;
118060ff233Sopenharmony_ci    tm.tv_sec = ms / MS_PER_SECOND;
119060ff233Sopenharmony_ci    tm.tv_usec = (ms % MS_PER_SECOND) * US_PER_MSECOND;
120060ff233Sopenharmony_ci
121060ff233Sopenharmony_ci    do {
122060ff233Sopenharmony_ci        ret = select(0, NULL, NULL, NULL, &tm);
123060ff233Sopenharmony_ci    } while ((ret == -1) && (errno == EINTR));
124060ff233Sopenharmony_ci
125060ff233Sopenharmony_ci    return SOFTBUS_ERR;
126060ff233Sopenharmony_ci}
127060ff233Sopenharmony_ci
128060ff233Sopenharmony_ciint32_t SoftBusGetTime(SoftBusSysTime *sysTime)
129060ff233Sopenharmony_ci{
130060ff233Sopenharmony_ci    if (sysTime == NULL) {
131060ff233Sopenharmony_ci        COMM_LOGI(COMM_ADAPTER, "sysTime is null");
132060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
133060ff233Sopenharmony_ci    }
134060ff233Sopenharmony_ci    struct timespec time = {0};
135060ff233Sopenharmony_ci    (void)clock_gettime(CLOCK_MONOTONIC, &time);
136060ff233Sopenharmony_ci
137060ff233Sopenharmony_ci    sysTime->sec = time.tv_sec;
138060ff233Sopenharmony_ci    sysTime->usec = time.tv_nsec / NS_PER_USECOND;
139060ff233Sopenharmony_ci    return SOFTBUS_OK;
140060ff233Sopenharmony_ci}
141060ff233Sopenharmony_ci
142060ff233Sopenharmony_ciint32_t SoftBusGetRealTime(SoftBusSysTime *sysTime)
143060ff233Sopenharmony_ci{
144060ff233Sopenharmony_ci    if (sysTime == NULL) {
145060ff233Sopenharmony_ci        COMM_LOGW(COMM_ADAPTER, "sysTime is null");
146060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
147060ff233Sopenharmony_ci    }
148060ff233Sopenharmony_ci    struct timespec time = {0};
149060ff233Sopenharmony_ci    (void)clock_gettime(CLOCK_BOOTTIME, &time);
150060ff233Sopenharmony_ci    sysTime->sec = time.tv_sec;
151060ff233Sopenharmony_ci    sysTime->usec = time.tv_nsec / NS_PER_USECOND;
152060ff233Sopenharmony_ci    return SOFTBUS_OK;
153060ff233Sopenharmony_ci}
154060ff233Sopenharmony_ci
155060ff233Sopenharmony_ciuint64_t SoftBusGetSysTimeMs(void)
156060ff233Sopenharmony_ci{
157060ff233Sopenharmony_ci    struct timeval time;
158060ff233Sopenharmony_ci    time.tv_sec = 0;
159060ff233Sopenharmony_ci    time.tv_usec = 0;
160060ff233Sopenharmony_ci    if (gettimeofday(&time, NULL) != 0) {
161060ff233Sopenharmony_ci        COMM_LOGI(COMM_ADAPTER, "get sys time fail");
162060ff233Sopenharmony_ci        return 0;
163060ff233Sopenharmony_ci    }
164060ff233Sopenharmony_ci    return (uint64_t)time.tv_sec * MS_PER_SECOND + (uint64_t)time.tv_usec / US_PER_MSECOND;
165060ff233Sopenharmony_ci}
166060ff233Sopenharmony_ci
167060ff233Sopenharmony_ciconst char *SoftBusFormatTimestamp(uint64_t timestamp)
168060ff233Sopenharmony_ci{
169060ff233Sopenharmony_ci    uint32_t milliseconds = timestamp % MS_PER_SECOND;
170060ff233Sopenharmony_ci    time_t seconds = (time_t)(timestamp / MS_PER_SECOND);
171060ff233Sopenharmony_ci    struct tm formatedDateTime;
172060ff233Sopenharmony_ci
173060ff233Sopenharmony_ci#if (defined( __WINDOWS__ ))
174060ff233Sopenharmony_ci    if (localtime_s(&formatedDateTime, &seconds) != 0) {
175060ff233Sopenharmony_ci#else
176060ff233Sopenharmony_ci    if (localtime_r(&seconds, &formatedDateTime) == NULL) {
177060ff233Sopenharmony_ci#endif // __WINDOWS__
178060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "get localtime failed");
179060ff233Sopenharmony_ci        return NULL;
180060ff233Sopenharmony_ci    }
181060ff233Sopenharmony_ci
182060ff233Sopenharmony_ci    const int32_t BASE_YEAR = 1900;
183060ff233Sopenharmony_ci    const int32_t BASE_MONTH = 1;
184060ff233Sopenharmony_ci    int32_t ret = sprintf_s(g_dateTimeBuff, DATE_TIME_BUFF_LEN, "%04d-%02d-%02d %02d:%02d:%02d.%03u",
185060ff233Sopenharmony_ci        formatedDateTime.tm_year + BASE_YEAR, formatedDateTime.tm_mon + BASE_MONTH, formatedDateTime.tm_mday,
186060ff233Sopenharmony_ci        formatedDateTime.tm_hour, formatedDateTime.tm_min, formatedDateTime.tm_sec, milliseconds);
187060ff233Sopenharmony_ci    if (ret < 0) {
188060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "sprintf failed, ret=%{public}d", ret);
189060ff233Sopenharmony_ci        return NULL;
190060ff233Sopenharmony_ci    }
191060ff233Sopenharmony_ci
192060ff233Sopenharmony_ci    g_dateTimeBuff[DATE_TIME_BUFF_LEN - 1] = '\0';
193060ff233Sopenharmony_ci    return g_dateTimeBuff;
194060ff233Sopenharmony_ci}
195