1 /*
2 * Copyright (C) 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 <stdio.h>
17 #include <stdlib.h>
18 #include <stdint.h>
19 #include "attest_utils.h"
20 #include "attest_utils_log.h"
21 #include "attest_utils_timer.h"
22
AttestFunction(union sigval attestTimer)23 static void AttestFunction(union sigval attestTimer)
24 {
25 AttestTimerInfo *tmpTimerInfo = (AttestTimerInfo *)attestTimer.sival_ptr;
26 if (tmpTimerInfo->type == ATTEST_TIMER_TYPE_ONCE) {
27 tmpTimerInfo->status = ATTEST_TIMER_STATUS_STOP;
28 }
29 tmpTimerInfo->func(tmpTimerInfo->arg);
30 }
31
AttestMs2TimeSpec(struct timespec * tp,uint32_t ms)32 static void AttestMs2TimeSpec(struct timespec *tp, uint32_t ms)
33 {
34 if (tp == NULL) {
35 ATTEST_LOG_ERROR("[AttestMs2TimeSpec] tp is null");
36 return;
37 }
38 tp->tv_sec = (time_t)(ms / LOSCFG_BASE_CORE_MS_PER_SECOND);
39 ms -= (uint32_t)(tp->tv_sec * LOSCFG_BASE_CORE_MS_PER_SECOND);
40 tp->tv_nsec = (long)(((unsigned long long)ms * OS_SYS_NS_PER_SECOND) / LOSCFG_BASE_CORE_MS_PER_SECOND);
41 }
42
AttestTimerCreate(TimerCallbackFunc func,AttestTimerType type,void * arg,uint32_t milliseconds)43 static ATTEST_TIMER_ID AttestTimerCreate(TimerCallbackFunc func, AttestTimerType type, void *arg, uint32_t milliseconds)
44 {
45 if ((func == NULL) || (type != ATTEST_TIMER_TYPE_ONCE && type != ATTEST_TIMER_TYPE_PERIOD)) {
46 ATTEST_LOG_ERROR("[AttestTimerCreate] something is wrong");
47 return NULL;
48 }
49 AttestTimerInfo *timerInfo = (AttestTimerInfo *)ATTEST_MEM_MALLOC(sizeof(AttestTimerInfo));
50 if (timerInfo == NULL) {
51 ATTEST_LOG_ERROR("[AttestTimerCreate] TimerInfo malloc fail");
52 return NULL;
53 }
54
55 timerInfo->type = type;
56 timerInfo->milliseconds = milliseconds;
57 timerInfo->func = func;
58 timerInfo->arg = arg;
59 timerInfo->status = ATTEST_TIMER_STATUS_STOP;
60
61 timer_t timerId;
62 struct sigevent sigEvp = { 0 };
63 sigEvp.sigev_notify = SIGEV_THREAD;
64 sigEvp.sigev_notify_function = AttestFunction;
65 sigEvp.sigev_value.sival_ptr = timerInfo;
66 int32_t ret = timer_create(CLOCK_REALTIME, &sigEvp, &timerId);
67 if (ret != 0) {
68 ATTEST_MEM_FREE(timerInfo);
69 ATTEST_LOG_ERROR("[AttestTimerCreate] TimerCreate fail");
70 return NULL;
71 }
72 timerInfo->timerId = timerId;
73 return (ATTEST_TIMER_ID)timerInfo;
74 }
75
AttestTimerStart(ATTEST_TIMER_ID attestTimerId)76 static int32_t AttestTimerStart(ATTEST_TIMER_ID attestTimerId)
77 {
78 if (attestTimerId == NULL) {
79 ATTEST_LOG_ERROR("[AttestTimerStart] attestTimerId is null");
80 return ATTEST_ERR;
81 }
82 struct itimerspec timerSpec = { 0 };
83 AttestTimerInfo *tmpTimerInfo = (AttestTimerInfo *)attestTimerId;
84
85 AttestMs2TimeSpec(&timerSpec.it_value, tmpTimerInfo->milliseconds);
86 if (tmpTimerInfo->type == ATTEST_TIMER_TYPE_PERIOD) {
87 AttestMs2TimeSpec(&timerSpec.it_interval, tmpTimerInfo->milliseconds);
88 }
89 int32_t ret = timer_settime(tmpTimerInfo->timerId, 0, &timerSpec, NULL);
90 if (ret != 0) {
91 ATTEST_LOG_ERROR("[AttestTimerStart] failed to settime");
92 return ATTEST_ERR;
93 }
94 if (tmpTimerInfo->milliseconds != 0) {
95 tmpTimerInfo->status = ATTEST_TIMER_STATUS_RUNNING;
96 }
97 return ATTEST_OK;
98 }
99
AttestStopTimerTask(const ATTEST_TIMER_ID attestTimerId)100 int32_t AttestStopTimerTask(const ATTEST_TIMER_ID attestTimerId)
101 {
102 if (attestTimerId == NULL) {
103 ATTEST_LOG_ERROR("[AttestStopTimerTask] attestTimerId is null");
104 return ATTEST_ERR;
105 }
106 AttestTimerInfo *tmpTimerInfo = (AttestTimerInfo *)attestTimerId;
107 int32_t ret = timer_delete(tmpTimerInfo->timerId);
108 ATTEST_MEM_FREE(tmpTimerInfo);
109 return (ret != 0) ? ATTEST_ERR : ATTEST_OK;
110 }
111
AttestCreateTimerTask(AttestTimerType isOnce,uint32_t milliseconds,void * func,void * arg,ATTEST_TIMER_ID * timerHandle)112 int32_t AttestCreateTimerTask(AttestTimerType isOnce, uint32_t milliseconds,
113 void *func, void *arg, ATTEST_TIMER_ID *timerHandle)
114 {
115 if (func == NULL || timerHandle == NULL) {
116 ATTEST_LOG_ERROR("[AttestCreateTimerTask] callBackFunc or timerHandle is null");
117 return ATTEST_ERR;
118 }
119 if (*timerHandle != NULL) {
120 AttestTimerInfo *tmpTimerInfo = (AttestTimerInfo *)timerHandle;
121 if (tmpTimerInfo->timerId != 0) {
122 ATTEST_LOG_ERROR("[AttestCreateTimerTask] timerId[%d] already exists", tmpTimerInfo->timerId);
123 return ATTEST_ERR;
124 }
125 }
126
127 AttestTimerType type = (isOnce == ATTEST_TIMER_TYPE_ONCE) ? ATTEST_TIMER_TYPE_ONCE : ATTEST_TIMER_TYPE_PERIOD;
128 ATTEST_TIMER_ID attestTimerId = AttestTimerCreate((TimerCallbackFunc)func, type, arg, milliseconds);
129 if (attestTimerId == NULL) {
130 ATTEST_LOG_ERROR("[AttestCreateTimerTask] failed to create timerHandle");
131 return ATTEST_ERR;
132 }
133
134 if (AttestTimerStart(attestTimerId) != ATTEST_OK) {
135 if (AttestStopTimerTask(attestTimerId) == ATTEST_OK) {
136 attestTimerId = NULL;
137 }
138 ATTEST_LOG_ERROR("[AttestCreateTimerTask] failed to start timerHandle");
139 return ATTEST_ERR;
140 }
141 *timerHandle = attestTimerId;
142 return ATTEST_OK;
143 }
144