• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
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  * Description: HiLinkKV harmonyos file实现源文件(此文件为DEMO,需集成方适配修改)
15  */
16 
17 #include "hilink_kv_adapter.h"
18 #include <stdbool.h>
19 #include "hilink_sal_defines.h"
20 #include "securec.h"
21 #include "hilink_str_adapter.h"
22 #include "lfs.h"
23 #include "fcntl.h"
24 #include "sfc.h"
25 #include "securec.h"
26 #include "soc_osal.h"
27 #include "littlefs_config.h"
28 #include "securec.h"
29 #include "partition.h"
30 #include "littlefs_adapt.h"
31 
32 #if defined(HILINK_SDK_BUILD_IN) && defined(HI_3861)
33 #define MAX_PATH_LEN        16
34 #define MAX_FILENAME_LEN    16
35 #else
36 #define MAX_PATH_LEN        32
37 #define MAX_FILENAME_LEN    32
38 #endif
39 
40 static bool g_isKVInit = false;
41 static char g_filePath[MAX_PATH_LEN];
42 
43 typedef struct KeyNameItem {
44     const char *hilinkKey;
45     const char *fileName;
46 } KeyNameItem;
47 
48 /* 需要对key进行转换,防止key变更导致无法前向兼容 */
49 static const KeyNameItem KEY_NAME_LIST[] = {
50     {
51         "hilink_running",
52         "running"
53     },
54     {
55         "hilink_timer",
56         "timer"
57     },
58 
59     {
60         "hilink_ble_sensitive",
61         "sensitive"
62     },
63     {
64         "hilink_ble_regstate",
65         "regstate"
66     },
67     {
68         "hilink_cert",
69         "cert"
70     },
71 };
72 
73 #ifdef DUAL_FILE_BACKUP
74 /* 使用双备份后对于非预置文件,以.bak为后缀做备份 */
75 static const char *BACKUP_FILE_SUFFIX = ".bak";
76 static const char *PRESET_FILE[] = {"hilink.cfg", "hilink_bak.cfg"};
77 
IsPresetFile(const char * fileName)78 static bool IsPresetFile(const char *fileName)
79 {
80     for (unsigned int i = 0; i < sizeof(PRESET_FILE) / sizeof(char *); ++i) {
81         if (HILINK_Strcmp(fileName, PRESET_FILE[i]) == 0) {
82             return true;
83         }
84     }
85     return false;
86 }
87 
GetBackupFileName(const char * fileName,char * buf,unsigned int len)88 static const char *GetBackupFileName(const char *fileName, char *buf, unsigned int len)
89 {
90     if (sprintf_s(buf, len, "%s%s", fileName, BACKUP_FILE_SUFFIX) <= 0) {
91         HILINK_SAL_WARN("sprintf error\r\n");
92         return NULL;
93     }
94     return buf;
95 }
96 #endif
97 
FindFileName(const char * key)98 static const char *FindFileName(const char *key)
99 {
100     for (unsigned int i = 0; i < (sizeof(KEY_NAME_LIST) / sizeof(KEY_NAME_LIST[0])); ++i) {
101         if (HILINK_Strcmp(key, KEY_NAME_LIST[i].hilinkKey) == 0) {
102             return KEY_NAME_LIST[i].fileName;
103         }
104     }
105     return NULL;
106 }
107 
SetConfigInfoPath(const char * path)108 static int SetConfigInfoPath(const char *path)
109 {
110     if (HILINK_Strlen(path) >= MAX_PATH_LEN) {
111         HILINK_SAL_WARN("path too long: %s\r\n", path);
112         return HILINK_SAL_KV_INTI_ERR;
113     }
114 
115     (void)memset_s(g_filePath, MAX_PATH_LEN, 0, MAX_PATH_LEN);
116     /* 长度为0保存在根目录下 */
117     if (HILINK_Strlen(path) == 0) {
118         HILINK_SAL_NOTICE("empty path\r\n");
119         return HILINK_SAL_OK;
120     }
121     if (strcpy_s(g_filePath, MAX_PATH_LEN, path) != EOK) {
122         HILINK_SAL_WARN("strncpy_s error\r\n");
123         return HILINK_SAL_STRCPY_ERR;
124     }
125     if (g_filePath[HILINK_Strlen(path) - 1] == '/') {
126         g_filePath[HILINK_Strlen(path) - 1] = '\0';
127     }
128 
129     return HILINK_SAL_OK;
130 }
131 
CreateFileIfNotExists(const char * filePath)132 static int CreateFileIfNotExists(const char *filePath)
133 {
134     if (filePath == NULL) {
135         HILINK_SAL_ERROR("Create filepath is null.\r\n");
136         return HILINK_SAL_KV_INTI_ERR;
137     }
138 
139     HILINK_SAL_DEBUG("Create file [%s]\r\n", filePath);
140     int fp = fs_adapt_open(filePath, O_RDWR | O_CREAT);
141     if (fp < 0) {
142         HILINK_SAL_ERROR("Create file failed.\r\n");
143         return HILINK_SAL_KV_INTI_ERR;
144     }
145 
146     int ret = fs_adapt_close(fp);
147     if (ret < LFS_ERR_OK) {
148         HILINK_SAL_ERROR("close file %s failed\n", filePath);
149         return HILINK_SAL_NOK;
150     }
151 
152     HILINK_SAL_DEBUG("Create file %s SUCCESS\r\n", filePath);
153 
154     return HILINK_SAL_OK;
155 }
156 
ReadFile(const char * filePath,unsigned int offset,unsigned char * value,unsigned int len)157 static int ReadFile(const char *filePath, unsigned int offset, unsigned char *value, unsigned int len)
158 {
159     if ((filePath == NULL) || (filePath[0] == '\0')) {
160         HILINK_SAL_ERROR("invalid path\r\n");
161         return HILINK_SAL_PARAM_INVALID;
162     }
163     HILINK_SAL_DEBUG("read %s, read len %u, offset %u\r\n", filePath, len, offset);
164 
165     int fp = fs_adapt_open(filePath, O_RDWR);
166     if (fp < 0) {
167         HILINK_SAL_ERROR("open %s failed\r\n", filePath);
168         return HILINK_SAL_NOK;
169     }
170 
171     int ret = fs_adapt_seek(fp, (int)offset, LFS_SEEK_SET);
172     if (ret < LFS_ERR_OK) {
173         HILINK_SAL_ERROR("set file %s offset %u failed\n", filePath, offset);
174         goto unnormal_close;
175     }
176 
177     ret = fs_adapt_read(fp, (char *)value, len);
178     if (ret < 0) {
179         HILINK_SAL_ERROR("read file %s failed\n", filePath);
180         goto unnormal_close;
181     }
182 
183     ret = fs_adapt_close(fp);
184     if (ret < LFS_ERR_OK) {
185         HILINK_SAL_ERROR("close file %s failed\n", filePath);
186         return HILINK_SAL_NOK;
187     }
188 
189     return HILINK_SAL_OK;
190 
191 unnormal_close:
192     ret = fs_adapt_close(fp);
193     if (ret < LFS_ERR_OK) {
194         HILINK_SAL_ERROR("close file %s failed\n", filePath);
195     }
196 
197     return HILINK_SAL_NOK;
198 }
199 
WritFile(const char * filePath,unsigned int offset,const unsigned char * value,unsigned int len)200 static int WritFile(const char *filePath, unsigned int offset, const unsigned char *value, unsigned int len)
201 {
202     HILINK_SAL_DEBUG("write %s, write len %u, offset %u\r\n", filePath, len, offset);
203 
204     int fp = fs_adapt_open(filePath, O_RDWR | O_CREAT);
205     if (fp < 0) {
206         HILINK_SAL_ERROR("open %s failed\r\n", filePath);
207         return HILINK_SAL_NOK;
208     }
209 
210     int ret = fs_adapt_seek(fp, (int)offset, LFS_SEEK_SET);
211     if (ret < LFS_ERR_OK) {
212         HILINK_SAL_ERROR("set file %s offset %u failed\n", filePath, offset);
213         goto unnormal_close;
214     }
215 
216     ret = fs_adapt_write(fp, (char *)value, len);
217     if (ret < 0) {
218         HILINK_SAL_ERROR("write file %s failed\n", filePath);
219         goto unnormal_close;
220     }
221 
222     ret = fs_adapt_close(fp);
223     if (ret < LFS_ERR_OK) {
224         HILINK_SAL_ERROR("close file %s failed\n", filePath);
225         return HILINK_SAL_NOK;
226     }
227 
228     return HILINK_SAL_OK;
229 
230 unnormal_close:
231     ret = fs_adapt_close(fp);
232     if (ret < LFS_ERR_OK) {
233         HILINK_SAL_ERROR("close file %s failed\n", filePath);
234     }
235 
236     return HILINK_SAL_NOK;
237 }
238 
CreateEmptyFileAfterDelete(const char * filePath)239 static int CreateEmptyFileAfterDelete(const char *filePath)
240 {
241     HILINK_SAL_NOTICE("delete %s\r\n", filePath);
242     return HILINK_SAL_OK;
243 }
244 
GetFilePathByKey(const char * key,char * buf,unsigned int len)245 static int GetFilePathByKey(const char *key, char *buf, unsigned int len)
246 {
247     const char *fileName = NULL;
248 
249     fileName = FindFileName(key);
250     if (fileName == NULL) {
251         HILINK_SAL_ERROR("get file path failed\n");
252         return HILINK_SAL_NOK;
253     }
254 
255     if (memcpy_s(buf, len - 1, fileName, strlen(fileName)) != EOK) {
256         HILINK_SAL_ERROR("memcpy_s error\n");
257         return HILINK_SAL_NOK;
258     }
259 
260     return HILINK_SAL_OK;
261 }
262 
263 #if defined(HILINK_SDK_BUILD_IN) && defined(DUAL_FILE_BACKUP)
GetBakFilePathByKey(const char * key,char * buf,unsigned int len)264 static const char *GetBakFilePathByKey(const char *key, char *buf, unsigned int len)
265 {
266     const char *fileName = FindFileName(key);
267     /* 预置文件不做备份 */
268     if (IsPresetFile(fileName)) {
269         return NULL;
270     }
271     char bakFileName[MAX_FILENAME_LEN] = {0};
272     if (GetBackupFileName(fileName, bakFileName, sizeof(bakFileName)) == NULL) {
273         return NULL;
274     }
275 
276     return GetFullFilePath(bakFileName, buf, len);
277 }
278 #endif
279 
DeleteFileByKey(const char * key)280 static void DeleteFileByKey(const char *key)
281 {
282     char filePath[MAX_PATH_LEN + MAX_FILENAME_LEN] = {0};
283     if (GetFilePathByKey(key, filePath, sizeof(filePath)) != HILINK_SAL_OK) {
284         return;
285     }
286     (void)CreateEmptyFileAfterDelete(filePath);
287 #if defined(HILINK_SDK_BUILD_IN) && defined(DUAL_FILE_BACKUP)
288     (void)memset_s(filePath, sizeof(filePath), 0, sizeof(filePath));
289     if (GetBakFilePathByKey(key, filePath, sizeof(filePath)) != NULL) {
290         CreateEmptyFileAfterDelete(filePath);
291     }
292 #endif
293 }
294 
ReadFileByKey(const char * key,unsigned int offset,unsigned char * value,unsigned int len)295 static int ReadFileByKey(const char *key, unsigned int offset, unsigned char *value, unsigned int len)
296 {
297     char filePath[MAX_PATH_LEN + MAX_FILENAME_LEN] = {0};
298     if (GetFilePathByKey(key, filePath, sizeof(filePath)) != HILINK_SAL_OK) {
299         return HILINK_SAL_KV_GET_ITEM_ERR;
300     }
301     int ret = ReadFile(filePath, offset, value, len);
302     if (ret == HILINK_SAL_OK) {
303         return HILINK_SAL_OK;
304     }
305 #if defined(HILINK_SDK_BUILD_IN) && defined(DUAL_FILE_BACKUP)
306     (void)memset_s(filePath, sizeof(filePath), 0, sizeof(filePath));
307     if (GetBakFilePathByKey(key, filePath, sizeof(filePath)) != NULL) {
308         ret = ReadFile(filePath, offset, value, len);
309         if (ret == HILINK_SAL_OK) {
310             return HILINK_SAL_OK;
311         }
312     }
313 #endif
314     return ret;
315 }
316 
WriteFileByKey(const char * key,unsigned int offset,const unsigned char * value,unsigned int len)317 static int WriteFileByKey(const char *key, unsigned int offset, const unsigned char *value, unsigned int len)
318 {
319     char filePath[MAX_PATH_LEN + MAX_FILENAME_LEN] = {0};
320     if (GetFilePathByKey(key, filePath, sizeof(filePath)) != HILINK_SAL_OK) {
321         return HILINK_SAL_KV_SET_ITEM_ERR;
322     }
323     int ret = WritFile(filePath, offset, value, len);
324     if (ret != HILINK_SAL_OK) {
325         return ret;
326     }
327 
328 #if defined(HILINK_SDK_BUILD_IN) && defined(DUAL_FILE_BACKUP)
329     (void)memset_s(filePath, sizeof(filePath), 0, sizeof(filePath));
330     if (GetBakFilePathByKey(key, filePath, sizeof(filePath)) != NULL) {
331         ret = WritFile(filePath, offset, value, len);
332         if (ret != HILINK_SAL_OK) {
333             return ret;
334         }
335     }
336 #endif
337     return HILINK_SAL_OK;
338 }
339 
InitFileByKey(const char * key)340 static int InitFileByKey(const char *key)
341 {
342     if ((key == NULL) || (key[0] == '\0')) {
343         HILINK_SAL_WARN("invalid parm\r\n");
344         return HILINK_SAL_PARAM_INVALID;
345     }
346 
347     char filePath[MAX_PATH_LEN + MAX_FILENAME_LEN] = {0};
348     if (GetFilePathByKey(key, filePath, sizeof(filePath)) != HILINK_SAL_OK) {
349         return HILINK_SAL_KV_INTI_ERR;
350     }
351 
352     int ret = CreateFileIfNotExists(filePath);
353     if (ret != 0) {
354         return ret;
355     }
356 
357 #if defined(HILINK_SDK_BUILD_IN) && defined(DUAL_FILE_BACKUP)
358     (void)memset_s(filePath, sizeof(filePath), 0, sizeof(filePath));
359     if (GetBakFilePathByKey(key, filePath, sizeof(filePath)) == NULL) {
360         return HILINK_SAL_KV_INTI_ERR;
361     }
362     ret = CreateFileIfNotExists(filePath);
363     if (ret != 0) {
364         return ret;
365     }
366 #endif
367     return HILINK_SAL_OK;
368 }
369 
HILINK_KVStoreInit(const char * path,const char * key[],unsigned int num)370 int HILINK_KVStoreInit(const char *path, const char *key[], unsigned int num)
371 {
372     if ((key == NULL) || (num == 0) || (path == NULL)) {
373         HILINK_SAL_WARN("invalid parm\r\n");
374         return HILINK_SAL_PARAM_INVALID;
375     }
376 
377     HILINK_SAL_DEBUG("HILINK_KVStoreInit path[%s], num %d\r\n", path, num);
378     if (SetConfigInfoPath(path) != HILINK_SAL_OK) {
379         HILINK_SAL_WARN("set config path error\r\n");
380         return HILINK_SAL_KV_INTI_ERR;
381     }
382     int ret;
383     for (unsigned int i = 0; i < num; ++i) {
384         HILINK_SAL_DEBUG("HILINK_KVStoreInit key [%s]\r\n", key[i]);
385         ret = InitFileByKey(key[i]);
386         if (ret != HILINK_SAL_OK) {
387             return ret;
388         }
389     }
390     g_isKVInit = true;
391     return HILINK_SAL_OK;
392 }
393 
HILINK_SetValue(const char * key,unsigned int offset,const unsigned char * value,unsigned int len)394 int HILINK_SetValue(const char *key, unsigned int offset, const unsigned char *value, unsigned int len)
395 {
396     if ((key == NULL)  || (key[0] == '\0') || (value == NULL) || (len == 0)) {
397         HILINK_SAL_WARN("invalid parm\r\n");
398         return HILINK_SAL_PARAM_INVALID;
399     }
400 
401     if (!g_isKVInit) {
402         HILINK_SAL_WARN("not init\r\n");
403         return HILINK_SAL_NOT_INIT;
404     }
405 
406     return WriteFileByKey(key, offset, value, len);
407 }
408 
HILINK_GetValue(const char * key,unsigned int offset,unsigned char * value,unsigned int len)409 int HILINK_GetValue(const char *key, unsigned int offset, unsigned char *value, unsigned int len)
410 {
411     if ((key == NULL) || (key[0] == '\0') || (value == NULL) || (len == 0)) {
412         HILINK_SAL_WARN("invalid parm\r\n");
413         return HILINK_SAL_PARAM_INVALID;
414     }
415 
416     if (!g_isKVInit) {
417         HILINK_SAL_WARN("not init\r\n");
418         return HILINK_SAL_NOT_INIT;
419     }
420 
421     return ReadFileByKey(key, offset, value, len);
422 }
423 
HILINK_DeleteValue(const char * key)424 void HILINK_DeleteValue(const char * key)
425 {
426     if ((key == NULL) || (key[0] == '\0')) {
427         HILINK_SAL_NOTICE("invalid parm\r\n");
428         return;
429     }
430 
431     if (!g_isKVInit) {
432         HILINK_SAL_WARN("not init\r\n");
433         return;
434     }
435 
436     DeleteFileByKey(key);
437 }
438 
HILINK_GetFileName(const char * key,char * out,unsigned int len)439 int HILINK_GetFileName(const char *key, char *out, unsigned int len)
440 {
441     if (key == NULL || out == NULL || len < MAX_FILENAME_LEN) {
442         HILINK_SAL_WARN("invalid parm\r\n");
443         return HILINK_SAL_PARAM_INVALID;
444     }
445     const char *fileName = key;
446 #ifdef HILINK_SDK_BUILD_IN
447     fileName = FindFileName(key);
448 #endif
449     if (strcpy_s(out, len, fileName) != EOK) {
450         HILINK_SAL_WARN("cpy file name err\n");
451         return HILINK_SAL_NOK;
452     }
453     return HILINK_SAL_OK;
454 }
455