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 int32_t ret = timer_delete(paramTimer->timerId);
109 if (ret < 0) {
110 PARAM_LOGE("Failed to delete timer, errno:%d", errno);
111 }
112 free(paramTimer);
113 }
114
115 #ifdef __LITEOS_A__
GetSharedMem(const char * fileName,MemHandle * handle,uint32_t spaceSize,int readOnly)116 INIT_LOCAL_API void *GetSharedMem(const char *fileName, MemHandle *handle, uint32_t spaceSize, int readOnly)
117 {
118 PARAM_CHECK(fileName != NULL && handle != NULL, return NULL, "Invalid filename or handle");
119 int mode = readOnly ? O_RDONLY : O_CREAT | O_RDWR;
120 void *areaAddr = NULL;
121 if (!readOnly) {
122 int fd = open(fileName, mode, S_IRWXU | S_IRWXG | S_IROTH);
123 PARAM_CHECK(fd >= 0, return NULL, "Open file %s mode %x fail error %d", fileName, mode, errno);
124 close(fd);
125 }
126 key_t key = ftok(fileName, 0x03); // 0x03 flags for shmget
127 PARAM_CHECK(key != -1, return NULL, "Invalid errno %d key for %s", errno, fileName);
128 handle->shmid = shmget(key, spaceSize, IPC_CREAT | IPC_EXCL | 0666); // 0666
129 if (handle->shmid == -1) {
130 handle->shmid = shmget(key, spaceSize, 0); // 0666
131 }
132 PARAM_CHECK(handle->shmid != -1, return NULL, "Invalid shmId errno %d for %s", errno, fileName);
133 areaAddr = (void *)shmat(handle->shmid, NULL, 0);
134 return areaAddr;
135 }
136
FreeSharedMem(const MemHandle * handle,void * mem,uint32_t dataSize)137 INIT_LOCAL_API void FreeSharedMem(const MemHandle *handle, void *mem, uint32_t dataSize)
138 {
139 PARAM_CHECK(mem != NULL && handle != NULL, return, "Invalid mem or handle");
140 shmdt(mem);
141 shmctl(handle->shmid, IPC_RMID, NULL);
142 }
143
paramMutexEnvInit(void)144 INIT_LOCAL_API void paramMutexEnvInit(void)
145 {
146 return;
147 }
148
ParamRWMutexCreate(ParamRWMutex * lock)149 INIT_LOCAL_API int ParamRWMutexCreate(ParamRWMutex *lock)
150 {
151 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
152 pthread_rwlockattr_t rwlockatt;
153 pthread_rwlockattr_init(&rwlockatt);
154 pthread_rwlockattr_setpshared(&rwlockatt, PTHREAD_PROCESS_SHARED);
155 pthread_rwlock_init(&lock->rwlock, &rwlockatt);
156 return 0;
157 }
158
ParamRWMutexWRLock(ParamRWMutex * lock)159 INIT_LOCAL_API int ParamRWMutexWRLock(ParamRWMutex *lock)
160 {
161 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
162 pthread_rwlock_wrlock(&lock->rwlock);
163 return 0;
164 }
ParamRWMutexRDLock(ParamRWMutex * lock)165 INIT_LOCAL_API int ParamRWMutexRDLock(ParamRWMutex *lock)
166 {
167 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
168 pthread_rwlock_rdlock(&lock->rwlock);
169 return 0;
170 }
ParamRWMutexUnlock(ParamRWMutex * lock)171 INIT_LOCAL_API int ParamRWMutexUnlock(ParamRWMutex *lock)
172 {
173 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
174 pthread_rwlock_unlock(&lock->rwlock);
175 return 0;
176 }
177
ParamRWMutexDelete(ParamRWMutex * lock)178 INIT_LOCAL_API int ParamRWMutexDelete(ParamRWMutex *lock)
179 {
180 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
181 uint32_t ret = pthread_rwlock_destroy(&lock->rwlock);
182 PARAM_CHECK(ret == 0, return -1, "Failed to mutex lock ret %d", ret);
183 return 0;
184 }
185
ParamMutexCreate(ParamMutex * mutex)186 INIT_LOCAL_API int ParamMutexCreate(ParamMutex *mutex)
187 {
188 PARAM_CHECK(mutex != NULL, return -1, "Invalid mutex");
189 pthread_mutexattr_t mutexattr;
190 pthread_mutexattr_init(&mutexattr);
191 pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
192 pthread_mutex_init(&mutex->mutex, &mutexattr);
193 return 0;
194 }
ParamMutexPend(ParamMutex * mutex)195 INIT_LOCAL_API int ParamMutexPend(ParamMutex *mutex)
196 {
197 PARAM_CHECK(mutex != NULL, return -1, "Invalid mutex");
198 if (pthread_mutex_lock(&mutex->mutex) != 0) {
199 PARAM_LOGE("Failed to batch begin to save param errno %d", errno);
200 return errno;
201 }
202 return 0;
203 }
ParamMutexPost(ParamMutex * mutex)204 INIT_LOCAL_API int ParamMutexPost(ParamMutex *mutex)
205 {
206 PARAM_CHECK(mutex != NULL, return -1, "Invalid mutex");
207 pthread_mutex_unlock(&mutex->mutex);
208 return 0;
209 }
210
ParamMutexDelete(ParamMutex * mutex)211 INIT_LOCAL_API int ParamMutexDelete(ParamMutex *mutex)
212 {
213 PARAM_CHECK(mutex != NULL, return -1, "Invalid lock");
214 uint32_t ret = pthread_mutex_destroy(&mutex->mutex);
215 PARAM_CHECK(ret == 0, return -1, "Failed to mutex lock ret %d", ret);
216 return 0;
217 }
218 #endif
219
220 #ifdef __LITEOS_M__
GetSysParamMem(uint32_t spaceSize)221 __attribute__((weak)) void* GetSysParamMem(uint32_t spaceSize)
222 {
223 return malloc(spaceSize);
224 }
225
FreeSysParamMem(void * mem)226 __attribute__((weak)) void FreeSysParamMem(void *mem)
227 {
228 if (mem == NULL) {
229 return;
230 }
231 free(mem);
232 }
233
GetSharedMem(const char * fileName,MemHandle * handle,uint32_t spaceSize,int readOnly)234 INIT_LOCAL_API void *GetSharedMem(const char *fileName, MemHandle *handle, uint32_t spaceSize, int readOnly)
235 {
236 PARAM_CHECK(spaceSize <= PARAM_WORKSPACE_MAX, return NULL, "Invalid spaceSize %u", spaceSize);
237 UNUSED(fileName);
238 UNUSED(handle);
239 UNUSED(readOnly);
240 return GetSysParamMem(spaceSize);
241 }
242
FreeSharedMem(const MemHandle * handle,void * mem,uint32_t dataSize)243 INIT_LOCAL_API void FreeSharedMem(const MemHandle *handle, void *mem, uint32_t dataSize)
244 {
245 PARAM_CHECK(mem != NULL && handle != NULL, return, "Invalid mem or handle");
246 UNUSED(handle);
247 UNUSED(dataSize);
248 FreeSysParamMem(mem);
249 }
250
paramMutexEnvInit(void)251 INIT_LOCAL_API void paramMutexEnvInit(void)
252 {
253 return;
254 }
255
ParamRWMutexCreate(ParamRWMutex * lock)256 INIT_LOCAL_API int ParamRWMutexCreate(ParamRWMutex *lock)
257 {
258 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
259 uint32_t ret = LOS_MuxCreate(&lock->mutex);
260 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to init mutex ret %d", ret);
261 return 0;
262 }
263
ParamRWMutexWRLock(ParamRWMutex * lock)264 INIT_LOCAL_API int ParamRWMutexWRLock(ParamRWMutex *lock)
265 {
266 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
267 uint32_t ret = LOS_MuxPend(lock->mutex, LOS_WAIT_FOREVER);
268 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to mutex lock ret %d %d", ret, lock->mutex);
269 return 0;
270 }
271
ParamRWMutexRDLock(ParamRWMutex * lock)272 INIT_LOCAL_API int ParamRWMutexRDLock(ParamRWMutex *lock)
273 {
274 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
275 uint32_t ret = LOS_MuxPend(lock->mutex, LOS_WAIT_FOREVER);
276 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to mutex lock ret %d %d", ret, lock->mutex);
277 return 0;
278 }
279
ParamRWMutexUnlock(ParamRWMutex * lock)280 INIT_LOCAL_API int ParamRWMutexUnlock(ParamRWMutex *lock)
281 {
282 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
283 uint32_t ret = LOS_MuxPost(lock->mutex);
284 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to mutex lock ret %d %d", ret, lock->mutex);
285 return 0;
286 }
287
ParamRWMutexDelete(ParamRWMutex * lock)288 INIT_LOCAL_API int ParamRWMutexDelete(ParamRWMutex *lock)
289 {
290 PARAM_CHECK(lock != NULL, return -1, "Invalid lock");
291 uint32_t ret = LOS_MuxDelete(lock->mutex);
292 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to mutex lock ret %d %d", ret, lock->mutex);
293 return 0;
294 }
295
ParamMutexCreate(ParamMutex * mutex)296 INIT_LOCAL_API int ParamMutexCreate(ParamMutex *mutex)
297 {
298 PARAM_CHECK(mutex != NULL, return -1, "Invalid lock");
299 uint32_t ret = LOS_MuxCreate(&mutex->mutex);
300 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to init mutex ret %d", ret);
301 return 0;
302 }
303
ParamMutexPend(ParamMutex * mutex)304 INIT_LOCAL_API int ParamMutexPend(ParamMutex *mutex)
305 {
306 PARAM_CHECK(mutex != NULL, return -1, "Invalid lock");
307 uint32_t ret = LOS_MuxPend(mutex->mutex, LOS_WAIT_FOREVER);
308 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to mutex lock ret %d %d", ret, mutex->mutex);
309 return 0;
310 }
311
ParamMutexPost(ParamMutex * mutex)312 INIT_LOCAL_API int ParamMutexPost(ParamMutex *mutex)
313 {
314 PARAM_CHECK(mutex != NULL, return -1, "Invalid lock");
315 uint32_t ret = LOS_MuxPost(mutex->mutex);
316 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to mutex lock ret %d %d", ret, mutex->mutex);
317 return 0;
318 }
319
ParamMutexDelete(ParamMutex * mutex)320 INIT_LOCAL_API int ParamMutexDelete(ParamMutex *mutex)
321 {
322 PARAM_CHECK(mutex != NULL, return -1, "Invalid mutex");
323 uint32_t ret = LOS_MuxDelete(mutex->mutex);
324 PARAM_CHECK(ret == LOS_OK, return -1, "Failed to delete mutex lock ret %d %d", ret, mutex->mutex);
325 return 0;
326 }
327 #endif
328
329