1d9f0492fSopenharmony_ci/* 2d9f0492fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License. 5d9f0492fSopenharmony_ci * You may obtain a copy of the License at 6d9f0492fSopenharmony_ci * 7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d9f0492fSopenharmony_ci * 9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and 13d9f0492fSopenharmony_ci * limitations under the License. 14d9f0492fSopenharmony_ci */ 15d9f0492fSopenharmony_ci 16d9f0492fSopenharmony_ci#include <ctype.h> 17d9f0492fSopenharmony_ci#include <errno.h> 18d9f0492fSopenharmony_ci#include <fcntl.h> 19d9f0492fSopenharmony_ci#include <time.h> 20d9f0492fSopenharmony_ci#include <unistd.h> 21d9f0492fSopenharmony_ci 22d9f0492fSopenharmony_ci#include "init_utils.h" 23d9f0492fSopenharmony_ci#include "param_manager.h" 24d9f0492fSopenharmony_ci#include "param_persist.h" 25d9f0492fSopenharmony_ci#include "param_utils.h" 26d9f0492fSopenharmony_ci#include "securec.h" 27d9f0492fSopenharmony_ci#include "utils_file.h" 28d9f0492fSopenharmony_ci 29d9f0492fSopenharmony_ci// for linux, no mutex 30d9f0492fSopenharmony_cistatic ParamMutex g_saveMutex = {0}; 31d9f0492fSopenharmony_ci#ifdef PARAM_SUPPORT_POSIX 32d9f0492fSopenharmony_ci#define MODE_READ O_RDONLY 33d9f0492fSopenharmony_ci#define MODE_APPEND (O_RDWR | O_CREAT | O_APPEND) 34d9f0492fSopenharmony_ci#define MODE_CREATE (O_RDWR | O_CREAT | O_TRUNC) 35d9f0492fSopenharmony_ci#else 36d9f0492fSopenharmony_ci#define MODE_READ O_RDONLY_FS 37d9f0492fSopenharmony_ci#define MODE_APPEND (O_RDWR_FS | O_CREAT_FS | O_APPEND_FS) 38d9f0492fSopenharmony_ci#define MODE_CREATE (O_RDWR_FS | O_CREAT_FS | O_TRUNC_FS) 39d9f0492fSopenharmony_ci#endif 40d9f0492fSopenharmony_ci 41d9f0492fSopenharmony_cistatic int ParamFileOpen(const char* path, int oflag, int mode) 42d9f0492fSopenharmony_ci{ 43d9f0492fSopenharmony_ci#ifdef PARAM_SUPPORT_POSIX 44d9f0492fSopenharmony_ci return open(path, oflag, mode); 45d9f0492fSopenharmony_ci#else 46d9f0492fSopenharmony_ci return UtilsFileOpen(path, oflag, mode); 47d9f0492fSopenharmony_ci#endif 48d9f0492fSopenharmony_ci} 49d9f0492fSopenharmony_ci 50d9f0492fSopenharmony_cistatic int ParamFileClose(int fd) 51d9f0492fSopenharmony_ci{ 52d9f0492fSopenharmony_ci#ifdef PARAM_SUPPORT_POSIX 53d9f0492fSopenharmony_ci return close(fd); 54d9f0492fSopenharmony_ci#else 55d9f0492fSopenharmony_ci return UtilsFileClose(fd); 56d9f0492fSopenharmony_ci#endif 57d9f0492fSopenharmony_ci} 58d9f0492fSopenharmony_ci 59d9f0492fSopenharmony_cistatic int ParamFileRead(int fd, char* buf, unsigned int len) 60d9f0492fSopenharmony_ci{ 61d9f0492fSopenharmony_ci#ifdef PARAM_SUPPORT_POSIX 62d9f0492fSopenharmony_ci return read(fd, buf, len); 63d9f0492fSopenharmony_ci#else 64d9f0492fSopenharmony_ci return UtilsFileRead(fd, buf, len); 65d9f0492fSopenharmony_ci#endif 66d9f0492fSopenharmony_ci} 67d9f0492fSopenharmony_ci 68d9f0492fSopenharmony_cistatic int ParamFileWrite(int fd, const char* buf, unsigned int len) 69d9f0492fSopenharmony_ci{ 70d9f0492fSopenharmony_ci#ifdef PARAM_SUPPORT_POSIX 71d9f0492fSopenharmony_ci return write(fd, buf, len); 72d9f0492fSopenharmony_ci#else 73d9f0492fSopenharmony_ci return UtilsFileWrite(fd, buf, len); 74d9f0492fSopenharmony_ci#endif 75d9f0492fSopenharmony_ci} 76d9f0492fSopenharmony_ci 77d9f0492fSopenharmony_cistatic int ParamFileDelete(const char* path) 78d9f0492fSopenharmony_ci{ 79d9f0492fSopenharmony_ci#ifdef PARAM_SUPPORT_POSIX 80d9f0492fSopenharmony_ci return unlink(path); 81d9f0492fSopenharmony_ci#else 82d9f0492fSopenharmony_ci return UtilsFileDelete(path); 83d9f0492fSopenharmony_ci#endif 84d9f0492fSopenharmony_ci} 85d9f0492fSopenharmony_ci 86d9f0492fSopenharmony_cistatic int ParamFileStat(const char* path, unsigned int* fileSize) 87d9f0492fSopenharmony_ci{ 88d9f0492fSopenharmony_ci#ifdef PARAM_SUPPORT_POSIX 89d9f0492fSopenharmony_ci int fd = open(path, O_RDONLY); 90d9f0492fSopenharmony_ci if (fd < 0) { 91d9f0492fSopenharmony_ci return -1; 92d9f0492fSopenharmony_ci } 93d9f0492fSopenharmony_ci *fileSize = lseek(fd, 0, SEEK_END); 94d9f0492fSopenharmony_ci lseek(fd, 0, SEEK_SET); 95d9f0492fSopenharmony_ci close(fd); 96d9f0492fSopenharmony_ci return 0; 97d9f0492fSopenharmony_ci#else 98d9f0492fSopenharmony_ci return UtilsFileStat(path, fileSize); 99d9f0492fSopenharmony_ci#endif 100d9f0492fSopenharmony_ci} 101d9f0492fSopenharmony_ci 102d9f0492fSopenharmony_cistatic void ParamFileSync(int ft) 103d9f0492fSopenharmony_ci{ 104d9f0492fSopenharmony_ci#ifdef PARAM_SUPPORT_POSIX 105d9f0492fSopenharmony_ci fsync(ft); 106d9f0492fSopenharmony_ci#else 107d9f0492fSopenharmony_ci (void)ft; 108d9f0492fSopenharmony_ci#endif 109d9f0492fSopenharmony_ci} 110d9f0492fSopenharmony_ci 111d9f0492fSopenharmony_cistatic int LoadOnePersistParam_(const uint32_t *context, const char *name, const char *value) 112d9f0492fSopenharmony_ci{ 113d9f0492fSopenharmony_ci (void)context; 114d9f0492fSopenharmony_ci uint32_t dataIndex = 0; 115d9f0492fSopenharmony_ci int ret = WriteParam(name, value, &dataIndex, 0); 116d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return ret, "Failed to write param %d name:%s %s", ret, name, value); 117d9f0492fSopenharmony_ci return 0; 118d9f0492fSopenharmony_ci} 119d9f0492fSopenharmony_ci 120d9f0492fSopenharmony_cistatic int LoadPersistParam(void) 121d9f0492fSopenharmony_ci{ 122d9f0492fSopenharmony_ci const char *path = PARAM_PERSIST_SAVE_TMP_PATH; 123d9f0492fSopenharmony_ci CheckAndCreateDir(path); 124d9f0492fSopenharmony_ci char *buffer = NULL; 125d9f0492fSopenharmony_ci int fd = -1; 126d9f0492fSopenharmony_ci uint32_t paramNum = 0; 127d9f0492fSopenharmony_ci do { 128d9f0492fSopenharmony_ci fd = ParamFileOpen(path, MODE_READ, 0); 129d9f0492fSopenharmony_ci if (fd < 0) { 130d9f0492fSopenharmony_ci path = PARAM_PERSIST_SAVE_PATH; 131d9f0492fSopenharmony_ci fd = ParamFileOpen(path, MODE_READ, 0); 132d9f0492fSopenharmony_ci PARAM_LOGI("LoadPersistParam open file %s", path); 133d9f0492fSopenharmony_ci } 134d9f0492fSopenharmony_ci PARAM_CHECK(fd >= 0, break, "No valid persist parameter file %s", path); 135d9f0492fSopenharmony_ci // read file 136d9f0492fSopenharmony_ci uint32_t fileSize = 0; 137d9f0492fSopenharmony_ci int ret = ParamFileStat(path, &fileSize); 138d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, break, "Failed to get file state %s", path); 139d9f0492fSopenharmony_ci buffer = calloc(fileSize, sizeof(char)); 140d9f0492fSopenharmony_ci PARAM_CHECK(buffer != NULL, break, "Failed to get file"); 141d9f0492fSopenharmony_ci ret = ParamFileRead(fd, buffer, fileSize); 142d9f0492fSopenharmony_ci PARAM_CHECK(ret >= 0, break, "Failed to read file %s", path); 143d9f0492fSopenharmony_ci 144d9f0492fSopenharmony_ci uint32_t currLen = 0; 145d9f0492fSopenharmony_ci char *tmp = buffer; 146d9f0492fSopenharmony_ci while (currLen < fileSize) { 147d9f0492fSopenharmony_ci if (buffer[currLen] == '\n') { // split line 148d9f0492fSopenharmony_ci buffer[currLen] = '\0'; 149d9f0492fSopenharmony_ci ret = SplitParamString(tmp, NULL, 0, LoadOnePersistParam_, NULL); 150d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, continue, "Failed to set param %d %s", ret, buffer); 151d9f0492fSopenharmony_ci paramNum++; 152d9f0492fSopenharmony_ci if (currLen + 1 >= fileSize) { 153d9f0492fSopenharmony_ci break; 154d9f0492fSopenharmony_ci } 155d9f0492fSopenharmony_ci tmp = buffer + currLen + 1; 156d9f0492fSopenharmony_ci } 157d9f0492fSopenharmony_ci currLen++; 158d9f0492fSopenharmony_ci } 159d9f0492fSopenharmony_ci } while (0); 160d9f0492fSopenharmony_ci if (fd > 0) { 161d9f0492fSopenharmony_ci ParamFileClose(fd); 162d9f0492fSopenharmony_ci } 163d9f0492fSopenharmony_ci if (buffer != NULL) { 164d9f0492fSopenharmony_ci free(buffer); 165d9f0492fSopenharmony_ci } 166d9f0492fSopenharmony_ci PARAM_LOGI("LoadPersistParam paramNum %d", paramNum); 167d9f0492fSopenharmony_ci return 0; 168d9f0492fSopenharmony_ci} 169d9f0492fSopenharmony_ci 170d9f0492fSopenharmony_cistatic int PersistWrite(int fd, const char *name, const char *value) 171d9f0492fSopenharmony_ci{ 172d9f0492fSopenharmony_ci int ret = ParamFileWrite(fd, name, strlen(name)); 173d9f0492fSopenharmony_ci if (ret <= 0) { 174d9f0492fSopenharmony_ci PARAM_LOGE("Failed to save persist param %s", name); 175d9f0492fSopenharmony_ci } 176d9f0492fSopenharmony_ci ret = ParamFileWrite(fd, "=", strlen("=")); 177d9f0492fSopenharmony_ci if (ret <= 0) { 178d9f0492fSopenharmony_ci PARAM_LOGE("Failed to save persist param %s", name); 179d9f0492fSopenharmony_ci } 180d9f0492fSopenharmony_ci ret = ParamFileWrite(fd, value, strlen(value)); 181d9f0492fSopenharmony_ci if (ret <= 0) { 182d9f0492fSopenharmony_ci PARAM_LOGE("Failed to save persist param %s", name); 183d9f0492fSopenharmony_ci } 184d9f0492fSopenharmony_ci ret = ParamFileWrite(fd, "\n", strlen("\n")); 185d9f0492fSopenharmony_ci if (ret <= 0) { 186d9f0492fSopenharmony_ci PARAM_LOGE("Failed to save persist param %s", name); 187d9f0492fSopenharmony_ci } 188d9f0492fSopenharmony_ci return 0; 189d9f0492fSopenharmony_ci} 190d9f0492fSopenharmony_ci 191d9f0492fSopenharmony_cistatic int SavePersistParam(const char *name, const char *value) 192d9f0492fSopenharmony_ci{ 193d9f0492fSopenharmony_ci ParamMutexPend(&g_saveMutex); 194d9f0492fSopenharmony_ci int ret = -1; 195d9f0492fSopenharmony_ci int fd = ParamFileOpen(PARAM_PERSIST_SAVE_PATH, MODE_APPEND, 0); 196d9f0492fSopenharmony_ci if (fd > 0) { 197d9f0492fSopenharmony_ci ret = PersistWrite(fd, name, value); 198d9f0492fSopenharmony_ci ParamFileSync(fd); 199d9f0492fSopenharmony_ci ParamFileClose(fd); 200d9f0492fSopenharmony_ci } 201d9f0492fSopenharmony_ci if (ret != 0) { 202d9f0492fSopenharmony_ci PARAM_LOGE("SavePersistParam %s errno %d", name, errno); 203d9f0492fSopenharmony_ci } 204d9f0492fSopenharmony_ci ParamMutexPost(&g_saveMutex); 205d9f0492fSopenharmony_ci return ret; 206d9f0492fSopenharmony_ci} 207d9f0492fSopenharmony_ci 208d9f0492fSopenharmony_cistatic int BatchSavePersistParamBegin(PERSIST_SAVE_HANDLE *handle) 209d9f0492fSopenharmony_ci{ 210d9f0492fSopenharmony_ci ParamMutexPend(&g_saveMutex); 211d9f0492fSopenharmony_ci int fd = ParamFileOpen(PARAM_PERSIST_SAVE_PATH, MODE_CREATE, 0); 212d9f0492fSopenharmony_ci if (fd < 0) { 213d9f0492fSopenharmony_ci ParamMutexPost(&g_saveMutex); 214d9f0492fSopenharmony_ci PARAM_LOGE("Open file %s fail error %d", PARAM_PERSIST_SAVE_PATH, errno); 215d9f0492fSopenharmony_ci return -1; 216d9f0492fSopenharmony_ci } 217d9f0492fSopenharmony_ci *handle = (PERSIST_SAVE_HANDLE)fd; 218d9f0492fSopenharmony_ci return 0; 219d9f0492fSopenharmony_ci} 220d9f0492fSopenharmony_ci 221d9f0492fSopenharmony_cistatic int BatchSavePersistParam(PERSIST_SAVE_HANDLE handle, const char *name, const char *value) 222d9f0492fSopenharmony_ci{ 223d9f0492fSopenharmony_ci int fd = (int)handle; 224d9f0492fSopenharmony_ci int ret = PersistWrite(fd, name, value); 225d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return -1, "Failed to write param %s", name); 226d9f0492fSopenharmony_ci PARAM_LOGV("BatchSavePersistParam %s=%s", name, value); 227d9f0492fSopenharmony_ci return 0; 228d9f0492fSopenharmony_ci} 229d9f0492fSopenharmony_ci 230d9f0492fSopenharmony_cistatic void BatchSavePersistParamEnd(PERSIST_SAVE_HANDLE handle) 231d9f0492fSopenharmony_ci{ 232d9f0492fSopenharmony_ci int ret; 233d9f0492fSopenharmony_ci int fd = (int)handle; 234d9f0492fSopenharmony_ci ParamFileSync(fd); 235d9f0492fSopenharmony_ci ret = ParamFileClose(fd); 236d9f0492fSopenharmony_ci ParamMutexPost(&g_saveMutex); 237d9f0492fSopenharmony_ci PARAM_CHECK(ret == 0, return, "BatchSavePersistParamEnd fail error %d", errno); 238d9f0492fSopenharmony_ci} 239d9f0492fSopenharmony_ci 240d9f0492fSopenharmony_ciint RegisterPersistParamOps(PersistParamOps *ops) 241d9f0492fSopenharmony_ci{ 242d9f0492fSopenharmony_ci ParamMutexCreate(&g_saveMutex); 243d9f0492fSopenharmony_ci PARAM_CHECK(ops != NULL, return -1, "Invalid ops"); 244d9f0492fSopenharmony_ci ops->save = SavePersistParam; 245d9f0492fSopenharmony_ci ops->load = LoadPersistParam; 246d9f0492fSopenharmony_ci ops->batchSaveBegin = BatchSavePersistParamBegin; 247d9f0492fSopenharmony_ci ops->batchSave = BatchSavePersistParam; 248d9f0492fSopenharmony_ci ops->batchSaveEnd = BatchSavePersistParamEnd; 249d9f0492fSopenharmony_ci return 0; 250d9f0492fSopenharmony_ci} 251