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 42static 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 51static 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 57static 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 71int 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 94int 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 104void 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__ 113INIT_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 134INIT_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 141INIT_LOCAL_API void paramMutexEnvInit(void) 142{ 143 return; 144} 145 146INIT_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 156INIT_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} 162INIT_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} 168INIT_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 175INIT_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 183INIT_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} 192INIT_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} 201INIT_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 208INIT_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__ 218__attribute__((weak)) void* GetSysParamMem(uint32_t spaceSize) 219{ 220 return malloc(spaceSize); 221} 222 223__attribute__((weak)) void FreeSysParamMem(void *mem) 224{ 225 if (mem == NULL) { 226 return; 227 } 228 free(mem); 229} 230 231INIT_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 240INIT_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 248INIT_LOCAL_API void paramMutexEnvInit(void) 249{ 250 return; 251} 252 253INIT_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 261INIT_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 269INIT_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 277INIT_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 285INIT_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 293INIT_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 301INIT_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 309INIT_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 317INIT_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