1 /*
2 * Copyright (c) 2020 Huawei Device Co., Ltd.
3 * Copyright (C) 2022 Beken Corporation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "hal_file.h"
18 #include "utils_file.h"
19
20 #include "easyflash.h"
21 #include <stdlib.h>
22 #include <string.h>
23
24 struct file_info {
25 const char *file_name;
26 int fd;
27 char *content;
28 unsigned int len;
29 unsigned int offset;
30 };
31
32 #define INVALID_FD -1
33 #define FILE_ERR_GENERAL -1
34
35 #define MAX_FILE_CNT 32
36
37 static struct file_info infos[MAX_FILE_CNT] = {
38 [0 ... (MAX_FILE_CNT-1)] = {NULL, INVALID_FD, NULL, 0},
39 };
40
41 #define ESC_CHAR1 '\0'
42 //#define ESC_CHAR2 0xFE
43 #define ESC_CHAR2 0xDB
44
45 #define REP_CHAR1 0xDC
46 #define REP_CHAR2 0xDD
47
48 #define MAX_FILE_NAME_LEN 63 //31
49 #define MAX_FILE_LENGTH 1024
50 #define MAX_FILE_TIMER_LENGTH 3072
51 char file_long_file_fg = 0;//LONG FILE="timer.cfg"/"config.cfg" /"config_bak.cfg"
52 #define MAGIC_CHAR '&'
53 #define MAGIC_LEN 1
54
file_encode(const unsigned char * buf_in,unsigned int len,unsigned char * buf_out)55 static unsigned int file_encode(const unsigned char *buf_in, unsigned int len, unsigned char *buf_out)
56 {
57 int i;
58 int j;
59
60 if (!buf_in || !buf_out || (len == 0))
61 return 0;
62
63 for (i = 0, j = 0; i < len; i++) {
64 if (buf_in[i] == ESC_CHAR1) {
65 buf_out[j++] = ESC_CHAR2;
66 buf_out[j++] = REP_CHAR1;
67 } else if (buf_in[i] == ESC_CHAR2) {
68 buf_out[j++] = ESC_CHAR2;
69 buf_out[j++] = REP_CHAR2;
70 } else {
71 buf_out[j++] = buf_in[i];
72 }
73 }
74
75 return j;
76 }
77
file_decode(unsigned char * buf_in,unsigned int len,unsigned char * buf_out)78 static unsigned int file_decode(unsigned char *buf_in, unsigned int len, unsigned char *buf_out)
79 {
80 int i;
81 int j;
82
83 if (!buf_in || !buf_out || (len == 0))
84 return 0;
85
86 for (i = 0, j = 0; i < len; i++) {
87 if (buf_in[i] == ESC_CHAR2) {
88 if (i+1 < len) {
89 if (buf_in[i+1] == REP_CHAR1) {
90 buf_out[j++] = ESC_CHAR1;
91 } else if (buf_in[i+1] == REP_CHAR2) {
92 buf_out[j++] = ESC_CHAR2;
93 } else {
94 return 0; //err
95 }
96 i++; //skip it
97 } else {
98 return 0; //err
99 }
100 } else {
101 buf_out[j++] = buf_in[i];
102 }
103 }
104
105 return j;
106 }
107
init_ef(void)108 static void init_ef(void)
109 {
110 static int inited = 0;
111 int ret;
112
113 if (!inited) {
114 inited = 1;
115 ret = easyflash_init();
116 ret = ret;
117 //printf("easyflash_init : ret=%d\n", ret);
118 }
119 }
120
file_exist(const char * key)121 static int file_exist(const char *key)
122 {
123 char *value;
124
125 init_ef();
126
127 value = ef_get_env(key);
128 if (value)
129 return 1;
130 else
131 return 0;
132 }
133
file_load(const char * key,char * value_out,unsigned int * len_out)134 static int file_load(const char *key, char *value_out, unsigned int *len_out)
135 {
136 char *value;
137 unsigned int len;
138
139 init_ef();
140
141 value = ef_get_env(key);
142 if (!value || value[0] != MAGIC_CHAR) {
143 *len_out = 0;
144 return FILE_ERR_GENERAL;
145 }
146
147 value += MAGIC_LEN; //skip MAGIC_CHAR
148
149 len = file_decode(value, strlen(value), value_out);
150 *len_out = len;
151
152 return 0;
153 }
154
file_save(const char * key,const char * value,unsigned int len)155 static int file_save(const char *key, const char *value, unsigned int len)
156 {
157 char *buffer;
158 char *buffer2;
159 unsigned int len2;
160 int ret;
161
162 init_ef();
163
164 if (!value) { //for delete
165 ef_set_and_save_env(key, NULL);
166 return 0;
167 }
168
169 buffer = malloc(len * 2 + 1 + 1);
170 if (!buffer)
171 return FILE_ERR_GENERAL;
172
173 buffer[0] = MAGIC_CHAR;
174 buffer2 = buffer + MAGIC_LEN;
175
176 len2 = file_encode(value, len, buffer2);
177 buffer2[len2] = '\0';
178
179 ret = ef_set_and_save_env(key, buffer);
180 free(buffer);
181
182 if (ret != 0)
183 return FILE_ERR_GENERAL;
184 return 0;
185 }
186
file_get_info(int fd)187 static struct file_info* file_get_info(int fd)
188 {
189 int i;
190 struct file_info *info;
191
192 if (fd <= 0 || fd > MAX_FILE_CNT)
193 return NULL;
194
195 info = &infos[fd -1];
196 if (info->fd != fd)
197 return NULL;
198
199 return info;
200 }
201
HalFileOpen(const char * path,int oflag,int mode)202 int HalFileOpen(const char* path, int oflag, int mode)
203 {
204 int i;
205 int exist;
206 struct file_info *info;
207
208 for (i = 0; i < MAX_FILE_CNT; i++) {
209 if (infos[i].fd == INVALID_FD)
210 break;
211 }
212
213 if (i >= MAX_FILE_CNT)
214 return FILE_ERR_GENERAL;
215
216 if (strlen(path) > MAX_FILE_NAME_LEN)
217 return FILE_ERR_GENERAL;
218
219 exist = file_exist(path);
220 //printf("xxx %s exist=%d\n", path, exist);
221 if (!(oflag & O_CREAT_FS) && !exist) {
222 return FILE_ERR_GENERAL;
223 }
224
225 if ((oflag & O_EXCL_FS) && exist) {
226 return FILE_ERR_GENERAL;
227 }
228
229 info = &infos[i];
230
231 if(strstr(path,"config.cfg")!=NULL
232 ||strstr(path,"config_bak.cfg")!=NULL
233 ||strstr(path,"timer.cfg")!=NULL
234 ||strstr(path,"hilink_timer")!=NULL
235 ||strstr(path,"hilink_running")!=NULL){
236 file_long_file_fg = 1;
237 }else{
238 file_long_file_fg = 0;
239 }
240
241 if(file_long_file_fg)
242 info->content = malloc(MAX_FILE_TIMER_LENGTH);
243 else
244 info->content = malloc(MAX_FILE_LENGTH);
245
246 if (!info->content)
247 return FILE_ERR_GENERAL;
248
249 info->file_name = malloc(strlen(path) + 1);
250 if (!info->file_name) {
251 free(info->content);
252 return FILE_ERR_GENERAL;
253 }
254 strcpy(info->file_name, path);
255
256 if (oflag & O_TRUNC_FS) {
257 info->len = 0;
258 } else {
259 file_load(path, info->content, &info->len);
260 }
261
262 if (oflag & O_APPEND_FS) {
263 info->offset = info->len;
264 } else {
265 info->offset = 0;
266 }
267
268 info->fd = i + 1;
269 return info->fd;
270 }
271
HalFileClose(int fd)272 int HalFileClose(int fd)
273 {
274 struct file_info *info;
275 int ret;
276
277 info = file_get_info(fd);
278 if (!info)
279 return FILE_ERR_GENERAL;
280
281 ret = file_save(info->file_name, info->content, info->len);
282
283 free(info->file_name);
284 free(info->content);
285 info->fd = INVALID_FD;
286
287 return 0;
288 }
289
HalFileRead(int fd,char * buf,unsigned int len)290 int HalFileRead(int fd, char *buf, unsigned int len)
291 {
292 struct file_info *info;
293 int ret;
294
295 info = file_get_info(fd);
296 if (!info)
297 return FILE_ERR_GENERAL;
298
299 if (!buf)
300 return FILE_ERR_GENERAL;
301
302 if (info->offset + len > info->len)
303 len = info->len - info->offset;
304
305 if (len) {
306 memcpy(buf, info->content + info->offset, len);
307 info->offset += len;
308 }
309
310 return len;
311 }
312
HalFileWrite(int fd,const char * buf,unsigned int len)313 int HalFileWrite(int fd, const char *buf, unsigned int len)
314 {
315 struct file_info *info;
316 int ret;
317
318 info = file_get_info(fd);
319 if (!info)
320 return FILE_ERR_GENERAL;
321
322 if (!buf)
323 return FILE_ERR_GENERAL;
324
325 if(file_long_file_fg == 0)
326 {
327 if (info->offset + len > MAX_FILE_LENGTH) {
328 printf("HalFileWrite warning : offset=%d, more size=%d\n", info->offset, len);
329 len = MAX_FILE_LENGTH - info->offset;
330 }
331 }else{
332 if (info->offset + len > MAX_FILE_TIMER_LENGTH){
333 printf("HalFileWrite long warning : offset=%d, more size=%d\n", info->offset, len);
334 len = MAX_FILE_TIMER_LENGTH - info->offset;
335 }
336 }
337 if (len) {
338 memcpy(info->content + info->offset, buf, len);
339 info->offset += len;
340 if (info->len < info->offset)
341 info->len = info->offset;
342 }
343 return len;
344 }
345
HalFileDelete(const char * path)346 int HalFileDelete(const char *path)
347 {
348 int exist;
349
350 exist = file_exist(path);
351 if (!exist)
352 return FILE_ERR_GENERAL;
353
354 file_save(path, NULL, 0); //value==NULL means to delete
355 return 0;
356 }
357
HalFileStat(const char * path,unsigned int * fileSize)358 int HalFileStat(const char *path, unsigned int *fileSize)
359 {
360 int fd;
361 struct file_info *info;
362
363 if (!fileSize)
364 return FILE_ERR_GENERAL;
365
366 fd = HalFileOpen(path, O_RDONLY_FS, 0);
367 if (fd <= 0)
368 return FILE_ERR_GENERAL;
369
370 info = file_get_info(fd);
371 if (!info) {
372 HalFileClose(fd);
373 return FILE_ERR_GENERAL;
374 }
375
376 *fileSize = info->len;
377 HalFileClose(fd);
378 return 0;
379 }
380
HalFileSeek(int fd,int offset,unsigned int whence)381 int HalFileSeek(int fd, int offset, unsigned int whence)
382 {
383 struct file_info *info;
384 //int ret;
385 int pos;
386 info = file_get_info(fd);
387 if (!info)
388 return FILE_ERR_GENERAL;
389
390 if (whence == SEEK_SET_FS)
391 pos = 0;
392 else if (whence == SEEK_CUR_FS)
393 pos = info->offset;
394 else if (whence == SEEK_END_FS)
395 pos = info->len;
396 else
397 return FILE_ERR_GENERAL;
398
399 if (pos + offset < 0)
400 return FILE_ERR_GENERAL;
401
402 if (pos + offset > info->len)
403 return FILE_ERR_GENERAL;
404
405 info->offset = pos + offset;
406 return info->offset;
407 }
408
409
410
411 /*
412 * Read data from file or flash
413 *
414 * filename: The path name of the file
415 * offset: param reserved for future use
416 * buf: The buffer used to store the content readed from the file
417 * len: The size count in buffer trying to read from the file
418 * return < 0 read error, return > 0 real read length,
419 * return == 0 secret key information does not exist in storage media
420 */
421
FileRead(const char * filename,unsigned int offset,char * buf,unsigned int len)422 int FileRead(const char *filename, unsigned int offset, char *buf, unsigned int len)
423 {
424 //printf("FileRead:%s,buf:0x%x,len:%d,offset:%d\r\n",filename,buf,len,offset);
425 int fd;
426 int read_len = 0;
427 fd = HalFileOpen(filename, O_CREAT_FS, 0);
428 if (fd <= 0)
429 return FILE_ERR_GENERAL;
430
431 read_len = HalFileRead(fd,buf,len);
432 HalFileClose(fd);
433 return read_len;
434
435 }
436 //int32_t (*read)(const char *file_name, uint32_t offset,
437 // uint8_t *buf, uint32_t len);
438
439 /*
440 * Write data into file or flash
441 *
442 * filename: The path name of the file
443 * offset: param reserved for future use
444 * buf: The content which you want write into the file
445 * len: The size of the content
446 * return == 0 write ok, return < 0 other error
447 */
448
FileWrite(const char * filename,unsigned int offset,const char * buf,unsigned int len)449 int FileWrite(const char *filename, unsigned int offset, const char *buf, unsigned int len)
450 {
451 int fd;
452 fd = HalFileOpen(filename, O_CREAT_FS, 0);
453
454 HalFileWrite(fd,buf,len);
455
456 HalFileClose(fd);
457 }
458 //int32_t (*write)(const char *file_name, uint32_t offset,
459 // const uint8_t *buf, uint32_t len);
460
461 /*
462 * Get file size
463 *
464 * filename: The path name of the file
465 * return < 0 error, >= 0 The size of the file
466 * flash can return a fixed value of 4096
467 */
468
FileSize(const char * filename)469 int FileSize(const char *filename)
470 {
471 int fd;
472 struct file_info *info;
473 int32_t file_size;
474
475
476 fd = HalFileOpen(filename, O_RDONLY_FS, 0);
477 if (fd <= 0)
478 return FILE_ERR_GENERAL;
479
480 info = file_get_info(fd);
481 if (!info) {
482 HalFileClose(fd);
483 return FILE_ERR_GENERAL;
484 }
485
486 file_size = info->len;
487 HalFileClose(fd);
488
489 return file_size;
490
491 }
492 //int32_t (*file_size)(const char *file_name);
493
494 /*
495 int _open(const char *path, int oflag, ...)
496 {
497 int ret;
498 ret = HalFileOpen(path, oflag,0);
499 return ret;
500 }
501
502 int _close(int fd)
503 {
504 return HalFileClose(fd);
505 }
506
507 size_t _read(int fd, void *buf, size_t nbyte)
508 {
509 return HalFileRead(fd, buf, (unsigned int)nbyte);
510 }
511
512 size_t _write(int fd, const void *buf, size_t nbyte)
513 {
514 return HalFileWrite(fd, buf, (unsigned int)nbyte);
515 }
516
517 int _lseek(int fd, int offset, int whence)
518 {
519 return HalFileSeek(fd, offset, (unsigned int)whence);
520 }
521
522 //int _unlink(const char *path)
523 //{
524 // return LOS_Unlink(path);
525 //}
526
527 int _fstat(int fd, struct stat *buf)
528 {
529 // struct file_info *info;
530 // info = file_get_info(fd);
531 // if (!info) {
532 // HalFileClose(fd);
533 // return FILE_ERR_GENERAL;
534 // }
535
536 // *buf = info->len;
537 printf("not adapt fstat()");
538 HalFileClose(fd);
539 return 0;
540 }
541
542 int _stat(const char *path, struct stat *buf)
543 {
544 printf("not adapt stat()");
545 int fd;
546 struct file_info *info;
547 fd = HalFileOpen(path, O_RDONLY_FS, 0);
548 if (fd <= 0)
549 return FILE_ERR_GENERAL;
550
551 info = file_get_info(fd);
552 if (!info) {
553 HalFileClose(fd);
554 return FILE_ERR_GENERAL;
555 }
556 HalFileClose(fd);
557 return 0;
558 }
559
560 int fsync(int fd)
561 {
562 return HalFileClose(fd);
563 }
564
565
566 */
567