1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "power_mgr_timer_util.h"
17
18 #include <common.h>
19 #include <errno.h>
20 #include <securec.h>
21 #include <signal.h>
22 #include <stdint.h>
23 #include <string.h>
24
25 #include "hilog_wrapper.h"
26 #include "power_mgr_time_util.h"
27
28 typedef struct {
29 PowerTimer timerId;
30 BOOL isRunning;
31 int64_t whenMsec;
32 int64_t intervalMsec;
33 PowerTimerCallback timerCb;
34 void *data;
35 } PowerTimerInfo;
36
GetPowerTimerInfo(PowerTimer * timer)37 static inline PowerTimerInfo *GetPowerTimerInfo(PowerTimer *timer)
38 {
39 return GET_OBJECT(timer, PowerTimerInfo, timerId);
40 }
41
SetTimeSpec(struct timespec * ts,int64_t msec)42 static void SetTimeSpec(struct timespec *ts, int64_t msec)
43 {
44 ts->tv_sec = MsecToSec(msec);
45 msec -= SecToMsec(ts->tv_sec);
46 ts->tv_nsec = MsecToNsec(msec);
47 }
48
StartTimer(PowerTimer timer,int64_t whenMsec,int64_t intervalMsec)49 static BOOL StartTimer(PowerTimer timer, int64_t whenMsec, int64_t intervalMsec)
50 {
51 struct itimerspec ts;
52 SetTimeSpec(&ts.it_value, whenMsec);
53 SetTimeSpec(&ts.it_interval, intervalMsec);
54 int32_t ret = timer_settime(timer, 0, &ts, NULL);
55 if (ret < 0) {
56 POWER_HILOGE("Failed to start timer");
57 return FALSE;
58 }
59 return TRUE;
60 }
61
TimerHandle(union sigval v)62 static void TimerHandle(union sigval v)
63 {
64 PowerTimerInfo *info = (PowerTimerInfo *)v.sival_ptr;
65 if (info == NULL) {
66 POWER_HILOGE("Invalid timer info");
67 return;
68 }
69 if (info->timerCb != NULL) {
70 info->timerCb(info->data);
71 }
72 }
73
PowerMgrCreateTimer(int64_t whenMsec,int64_t intervalMsec,PowerTimerCallback cb)74 PowerTimer *PowerMgrCreateTimer(int64_t whenMsec, int64_t intervalMsec, PowerTimerCallback cb)
75 {
76 PowerTimerInfo *info = (PowerTimerInfo *)malloc(sizeof(PowerTimerInfo));
77 if (info == NULL) {
78 POWER_HILOGE("Failed allocate timer info");
79 return NULL;
80 }
81 (void)memset_s(info, sizeof(PowerTimerInfo), 0, sizeof(PowerTimerInfo));
82 info->isRunning = FALSE;
83 info->whenMsec = whenMsec;
84 info->intervalMsec = intervalMsec;
85 info->timerCb = cb;
86
87 struct sigevent evp;
88 (void)memset_s(&evp, sizeof(evp), 0, sizeof(evp));
89 evp.sigev_value.sival_ptr = info;
90 evp.sigev_notify = SIGEV_THREAD;
91 evp.sigev_notify_function = TimerHandle;
92 int32_t ret = timer_create(CLOCK_REALTIME, &evp, &info->timerId);
93 if (ret < 0) {
94 POWER_HILOGE("Failed to create timer");
95 free(info);
96 return NULL;
97 }
98 POWER_HILOGD("Succeed to create timer, id: %p", info->timerId);
99
100 return &info->timerId;
101 }
102
PowerMgrResetTimer(PowerTimer * timer,int64_t whenMsec,int64_t intervalMsec)103 BOOL PowerMgrResetTimer(PowerTimer *timer, int64_t whenMsec, int64_t intervalMsec)
104 {
105 if (timer == NULL) {
106 POWER_HILOGE("Invalid timer");
107 return FALSE;
108 }
109 PowerMgrStopTimer(timer);
110 PowerTimerInfo *info = GetPowerTimerInfo(timer);
111 info->whenMsec = whenMsec;
112 info->intervalMsec = intervalMsec;
113 return TRUE;
114 }
115
PowerMgrStartTimer(PowerTimer * timer,void * privateData)116 BOOL PowerMgrStartTimer(PowerTimer *timer, void *privateData)
117 {
118 if (timer == NULL) {
119 POWER_HILOGE("Invalid timer");
120 return FALSE;
121 }
122
123 PowerTimerInfo *info = GetPowerTimerInfo(timer);
124 info->data = privateData;
125 info->isRunning = TRUE;
126 return StartTimer(info->timerId, info->whenMsec, info->intervalMsec);
127 }
128
PowerMgrRestartTimer(PowerTimer * timer,void * privateData)129 BOOL PowerMgrRestartTimer(PowerTimer *timer, void *privateData)
130 {
131 if (timer == NULL) {
132 POWER_HILOGE("Invalid timer");
133 return FALSE;
134 }
135
136 return PowerMgrStartTimer(timer, privateData);
137 }
138
PowerMgrStopTimer(PowerTimer * timer)139 BOOL PowerMgrStopTimer(PowerTimer *timer)
140 {
141 if (timer == NULL) {
142 POWER_HILOGE("Invalid timer");
143 return FALSE;
144 }
145
146 PowerTimerInfo *info = GetPowerTimerInfo(timer);
147 info->isRunning = FALSE;
148 return StartTimer(info->timerId, 0, 0);
149 }
150
PowerMgrDestroyTimer(PowerTimer * timer)151 void PowerMgrDestroyTimer(PowerTimer *timer)
152 {
153 if (timer == NULL) {
154 POWER_HILOGE("Invalid timer");
155 return;
156 }
157
158 PowerTimerInfo *info = GetPowerTimerInfo(timer);
159 int32_t ret = timer_delete(info->timerId);
160 POWER_HILOGD("Destory timer: %d", ret);
161 free(info);
162 }
163