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 #include "param_osadp.h"
16
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <pthread.h>
20 #include <string.h>
21 #ifdef __LITEOS_A__
22 #include <sys/ipc.h>
23 #include <sys/mman.h>
24 #include <sys/shm.h>
25 #else
26 #include "los_task.h"
27 #include "los_mux.h"
28 #endif
29 #include <sys/stat.h>
30 #include <sys/time.h>
31 #include <sys/types.h>
32 #include <unistd.h>
33 #include <signal.h>
34 #include <time.h>
35
36 #include "param_security.h"
37 #include "securec.h"
38
39 #define NSEC_PER_MSEC 1000000LL
40 #define MSEC_PER_SEC 1000LL
41
TimerHandle(union sigval v)42 static void TimerHandle(union sigval v)
43 {
44 ParamTimer *timer = (ParamTimer *)v.sival_ptr;
45 PARAM_CHECK(timer != NULL, return, "Invalid timer");
46 if (timer->timeProcessor != NULL) {
47 timer->timeProcessor(timer, timer->context);
48 }
49 }
50
SetTimeSpec(struct timespec * ts,int64_t msec)51 static void SetTimeSpec(struct timespec *ts, int64_t msec)
52 {
53 ts->tv_sec = msec / MSEC_PER_SEC; // 1000LL ms --> m
54 ts->tv_nsec = (msec - ts->tv_sec * MSEC_PER_SEC) * NSEC_PER_MSEC;
55 }
56
StartTimer(const ParamTimer * paramTimer,int64_t whenMsec,int64_t repeat)57 static int StartTimer(const ParamTimer *paramTimer, int64_t whenMsec, int64_t repeat)
58 {
59 UNUSED(repeat);
60 struct itimerspec ts;
61 SetTimeSpec(&ts.it_value, whenMsec);
62 SetTimeSpec(&ts.it_interval, whenMsec);
63 int32_t ret = timer_settime(paramTimer->timerId, 0, &ts, NULL);
64 if (ret < 0) {
65 PARAM_LOGE("Failed to start timer");
66 return -1;
67 }
68 return 0;
69 }
70
ParamTimerCreate(ParamTaskPtr * timer,ProcessTimer process,void * context)71 int ParamTimerCreate(ParamTaskPtr *timer, ProcessTimer process, void *context)
72 {
73 PARAM_CHECK(timer != NULL && process != NULL, return -1, "Invalid timer");
74 ParamTimer *paramTimer = malloc(sizeof(ParamTimer));
75 PARAM_CHECK(paramTimer != NULL, return -1, "Failed to create timer");
76 paramTimer->timeProcessor = process;
77 paramTimer->context = context;
78
79 struct sigevent evp;
80 (void)memset_s(&evp, sizeof(evp), 0, sizeof(evp));
81 evp.sigev_value.sival_ptr = paramTimer;
82 evp.sigev_notify = SIGEV_THREAD;
83 evp.sigev_notify_function = TimerHandle;
84 int32_t ret = timer_create(CLOCK_REALTIME, &evp, ¶mTimer->timerId);
85 if (ret < 0) {
86 PARAM_LOGE("Failed to create timer");
87 free(paramTimer);
88 return -1;
89 }
90 *timer = paramTimer;
91 return 0;
92 }
93
ParamTimerStart(const ParamTaskPtr timer,uint64_t timeout,uint64_t repeat)94 int ParamTimerStart(const ParamTaskPtr timer, uint64_t timeout, uint64_t repeat)
95 {
96 PARAM_CHECK(timer != NULL, return -1, "Invalid timer");
97 ParamTimer *paramTimer = (ParamTimer *)timer;
98 PARAM_LOGV("ParamTimerStart timeout %llu ", timeout);
99 int32_t ret = StartTimer(paramTimer, timeout, repeat);
100 PARAM_CHECK(ret >= 0, return -1, "Failed to start timer");
101 return 0;
102 }
103
ParamTimerClose(ParamTaskPtr timer)104 void ParamTimerClose(ParamTaskPtr timer)
105 {
106 PARAM_CHECK(timer != NULL, return, "Invalid timer");
107 ParamTimer *paramTimer = (ParamTimer *)timer;
108 timer_delete(paramTimer->timerId);
109 free(paramTimer);
110 }
111
112 #ifdef __LITEOS_A__
GetSharedMem(const char * fileName,MemHandle * handle,uint32_t spaceSize,int readOnly)113 INIT_LOCAL_API void *GetSharedMem(const char *fileName, MemHandle *handle, uint32_t spaceSize, int readOnly)
114 {
115 PARAM_CHECK(fileName != NULL && handle != NULL, return NULL, "Invalid filename or handle");
116 int mode = readOnly ? O_RDONLY : O_CREAT | O_RDWR;
117 void *areaAddr = NULL;
118 if (!readOnly) {
119 int fd = open(fileName, mode, S_IRWXU | S_IRWXG | S_IROTH);
120 PARAM_CHECK(fd >= 0, return NULL, "Open file %s mode %x fail error %d", fileName, mode, errno);
121 close(fd);
122 }
123 key_t key = ftok(fileName, 0x03); // 0x03 flags for shmget
124 PARAM_CHECK(key != -1, return NULL, "Invalid errno %d key for %s", errno, fileName);
125 handle->shmid = shmget(key, spaceSize, IPC_CREAT | IPC_EXCL | 0666); // 0666
126 if (handle->shmid == -1) {
127 handle->shmid = shmget(key, spaceSize, 0); // 0666
128 }
129 PARAM_CHECK(handle->shmid != -1, return NULL, "Invalid shmId errno %d for %s", errno, fileName);
130 areaAddr = (void *)shmat(handle->shmid, NULL, 0);
131 return areaAddr;
132 }
133
FreeSharedMem(const MemHandle * handle,void * mem,uint32_t dataSize)134 INIT_LOCAL_API void FreeSharedMem(const MemHandle *handle, void *mem, uint32_t dataSize)
135 {
136 PARAM_CHECK(mem != NULL && handle != NULL, return, "Invalid mem or handle");
137 shmdt(mem);
138 shmctl(handle->shmid, IPC_RMID, NULL);
139 }
140
paramMutexEnvInit(void)141 INIT_LOCAL_API void paramMutexEnvInit(void)
142 {
143 return;
144 }
145
ParamRWMutexCreate(ParamRWMutex * lock)146 INIT_LOCAL_API int ParamRWMutexCreate(ParamRWMutex *lock)
147 {
148 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
149 pthread_rwlockattr_t rwlockatt;
150 pthread_rwlockattr_init(&rwlockatt);
151 pthread_rwlockattr_setpshared(&rwlockatt, PTHREAD_PROCESS_SHARED);
152 pthread_rwlock_init(&lock->rwlock, &rwlockatt);
153 return 0;
154 }
155
ParamRWMutexWRLock(ParamRWMutex * lock)156 INIT_LOCAL_API int ParamRWMutexWRLock(ParamRWMutex *lock)
157 {
158 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
159 pthread_rwlock_wrlock(&lock->rwlock);
160 return 0;
161 }
ParamRWMutexRDLock(ParamRWMutex * lock)162 INIT_LOCAL_API int ParamRWMutexRDLock(ParamRWMutex *lock)
163 {
164 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
165 pthread_rwlock_rdlock(&lock->rwlock);
166 return 0;
167 }
ParamRWMutexUnlock(ParamRWMutex * lock)168 INIT_LOCAL_API int ParamRWMutexUnlock(ParamRWMutex *lock)
169 {
170 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
171 pthread_rwlock_unlock(&lock->rwlock);
172 return 0;
173 }
174
ParamRWMutexDelete(ParamRWMutex * lock)175 INIT_LOCAL_API int ParamRWMutexDelete(ParamRWMutex *lock)
176 {
177 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
178 uint32_t ret = pthread_rwlock_destroy(&lock->rwlock);
179 PARAM_CHECK(ret == 0, return -1, "Failed to mutex lock ret %d", ret);
180 return 0;
181 }
182
ParamMutexCreate(ParamMutex * mutex)183 INIT_LOCAL_API int ParamMutexCreate(ParamMutex *mutex)
184 {
185 PARAM_CHECK(mutex != NULL, return -1, "Invalid mutex");
186 pthread_mutexattr_t mutexattr;
187 pthread_mutexattr_init(&mutexattr);
188 pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
189 pthread_mutex_init(&mutex->mutex, &mutexattr);
190 return 0;
191 }
ParamMutexPend(ParamMutex * mutex)192 INIT_LOCAL_API int ParamMutexPend(ParamMutex *mutex)
193 {
194 PARAM_CHECK(mutex != NULL, return -1, "Invalid mutex");
195 if (pthread_mutex_lock(&mutex->mutex) != 0) {
196 PARAM_LOGE("Failed to batch begin to save param errno %d", errno);
197 return errno;
198 }
199 return 0;
200 }
ParamMutexPost(ParamMutex * mutex)201 INIT_LOCAL_API int ParamMutexPost(ParamMutex *mutex)
202 {
203 PARAM_CHECK(mutex != NULL, return -1, "Invalid mutex");
204 pthread_mutex_unlock(&mutex->mutex);
205 return 0;
206 }
207
ParamMutexDelete(ParamMutex * mutex)208 INIT_LOCAL_API int ParamMutexDelete(ParamMutex *mutex)
209 {
210 PARAM_CHECK(mutex != NULL, return -1, "Invalid lock");
211 uint32_t ret = pthread_mutex_destroy(&mutex->mutex);
212 PARAM_CHECK(ret == 0, return -1, "Failed to mutex lock ret %d", ret);
213 return 0;
214 }
215 #endif
216
217 #ifdef __LITEOS_M__
GetSysParamMem(uint32_t spaceSize)218 __attribute__((weak)) void* GetSysParamMem(uint32_t spaceSize)
219 {
220 return malloc(spaceSize);
221 }
222
FreeSysParamMem(void * mem)223 __attribute__((weak)) void FreeSysParamMem(void *mem)
224 {
225 if (mem == NULL) {
226 return;
227 }
228 free(mem);
229 }
230
GetSharedMem(const char * fileName,MemHandle * handle,uint32_t spaceSize,int readOnly)231 INIT_LOCAL_API void *GetSharedMem(const char *fileName, MemHandle *handle, uint32_t spaceSize, int readOnly)
232 {
233 PARAM_CHECK(spaceSize <= PARAM_WORKSPACE_MAX, return NULL, "Invalid spaceSize %u", spaceSize);
234 UNUSED(fileName);
235 UNUSED(handle);
236 UNUSED(readOnly);
237 return GetSysParamMem(spaceSize);
238 }
239
FreeSharedMem(const MemHandle * handle,void * mem,uint32_t dataSize)240 INIT_LOCAL_API void FreeSharedMem(const MemHandle *handle, void *mem, uint32_t dataSize)
241 {
242 PARAM_CHECK(mem != NULL && handle != NULL, return, "Invalid mem or handle");
243 UNUSED(handle);
244 UNUSED(dataSize);
245 FreeSysParamMem(mem);
246 }
247
paramMutexEnvInit(void)248 INIT_LOCAL_API void paramMutexEnvInit(void)
249 {
250 return;
251 }
252
ParamRWMutexCreate(ParamRWMutex * lock)253 INIT_LOCAL_API int ParamRWMutexCreate(ParamRWMutex *lock)
254 {
255 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
256 uint32_t ret = LOS_MuxCreate(&lock->mutex);
257 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to init mutex ret %d", ret);
258 return 0;
259 }
260
ParamRWMutexWRLock(ParamRWMutex * lock)261 INIT_LOCAL_API int ParamRWMutexWRLock(ParamRWMutex *lock)
262 {
263 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
264 uint32_t ret = LOS_MuxPend(lock->mutex, LOS_WAIT_FOREVER);
265 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to mutex lock ret %d %d", ret, lock->mutex);
266 return 0;
267 }
268
ParamRWMutexRDLock(ParamRWMutex * lock)269 INIT_LOCAL_API int ParamRWMutexRDLock(ParamRWMutex *lock)
270 {
271 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
272 uint32_t ret = LOS_MuxPend(lock->mutex, LOS_WAIT_FOREVER);
273 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to mutex lock ret %d %d", ret, lock->mutex);
274 return 0;
275 }
276
ParamRWMutexUnlock(ParamRWMutex * lock)277 INIT_LOCAL_API int ParamRWMutexUnlock(ParamRWMutex *lock)
278 {
279 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
280 uint32_t ret = LOS_MuxPost(lock->mutex);
281 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to mutex lock ret %d %d", ret, lock->mutex);
282 return 0;
283 }
284
ParamRWMutexDelete(ParamRWMutex * lock)285 INIT_LOCAL_API int ParamRWMutexDelete(ParamRWMutex *lock)
286 {
287 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
288 uint32_t ret = LOS_MuxDelete(lock->mutex);
289 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to mutex lock ret %d %d", ret, lock->mutex);
290 return 0;
291 }
292
ParamMutexCreate(ParamMutex * mutex)293 INIT_LOCAL_API int ParamMutexCreate(ParamMutex *mutex)
294 {
295 PARAM_CHECK(mutex != NULL, return -1, "Invalid lock");
296 uint32_t ret = LOS_MuxCreate(&mutex->mutex);
297 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to init mutex ret %d", ret);
298 return 0;
299 }
300
ParamMutexPend(ParamMutex * mutex)301 INIT_LOCAL_API int ParamMutexPend(ParamMutex *mutex)
302 {
303 PARAM_CHECK(mutex != NULL, return -1, "Invalid lock");
304 uint32_t ret = LOS_MuxPend(mutex->mutex, LOS_WAIT_FOREVER);
305 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to mutex lock ret %d %d", ret, mutex->mutex);
306 return 0;
307 }
308
ParamMutexPost(ParamMutex * mutex)309 INIT_LOCAL_API int ParamMutexPost(ParamMutex *mutex)
310 {
311 PARAM_CHECK(mutex != NULL, return -1, "Invalid lock");
312 uint32_t ret = LOS_MuxPost(mutex->mutex);
313 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to mutex lock ret %d %d", ret, mutex->mutex);
314 return 0;
315 }
316
ParamMutexDelete(ParamMutex * mutex)317 INIT_LOCAL_API int ParamMutexDelete(ParamMutex *mutex)
318 {
319 PARAM_CHECK(mutex != NULL, return -1, "Invalid mutex");
320 uint32_t ret = LOS_MuxDelete(mutex->mutex);
321 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to delete mutex lock ret %d %d", ret, mutex->mutex);
322 return 0;
323 }
324 #endif
325
326