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