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: UPG common functions source file
15 */
16
17 #include <stddef.h>
18 #include <stdint.h>
19 #include <stdbool.h>
20 #include "common_def.h"
21 #include "upg_config.h"
22 #if (UPG_CFG_SUPPORT_FILE_SYSTEM == YES)
23 #include "fcntl.h"
24 #include "unistd.h"
25 #include "sys/stat.h"
26 #include "sys/vfs.h"
27 #include "dfx_file_operation.h"
28 #endif /* (UPG_CFG_SUPPORT_FILE_SYSTEM == YES) */
29 #include "upg_common_porting.h"
30 #include "errcode.h"
31 #include "securec.h"
32 #include "partition.h"
33 #include "upg_alloc.h"
34 #include "upg_otp_reg.h"
35 #include "upg.h"
36 #include "upg_porting.h"
37 #include "upg_config.h"
38 #include "upg_debug.h"
39 #include "upg_common.h"
40
41 #define NOT_START_FLAG 0xFF
42 #define STARTED_FLAG 0x0F
43 #define FINISHED_FLAG 0x00
44 #define UPG_FINISH_HALF_FLAG 0xFFFF
45 #define UPG_FINISH_ALL_FLAG 0
46 #define UPG_ABNORMAL_FLAG 0x5a5a5a5a
47 #define PER_FILE_STORAGE_MAX_SIZE 4294967295
48
49 STATIC upg_storage_ctx_t g_upg_ctx = {0};
upg_get_ctx(void)50 upg_storage_ctx_t *upg_get_ctx(void)
51 {
52 return &g_upg_ctx;
53 }
54
55 /* 获取升级标记结构到RAM中 */
upg_alloc_and_get_upgrade_flag(fota_upgrade_flag_area_t ** upg_flag)56 errcode_t upg_alloc_and_get_upgrade_flag(fota_upgrade_flag_area_t **upg_flag)
57 {
58 uint32_t start_addr = 0;
59 errcode_t ret_val;
60
61 ret_val = upg_get_upgrade_flag_flash_start_addr(&start_addr);
62 if (ret_val != ERRCODE_SUCC) {
63 upg_log_err("[UPG] upg_get_upgrade_flag_flash_start_addr fail\r\n");
64 return ret_val;
65 }
66
67 *upg_flag = (fota_upgrade_flag_area_t*)upg_malloc(sizeof(fota_upgrade_flag_area_t));
68 if (*upg_flag == NULL) {
69 upg_log_err("[UPG] upg_alloc_and_get_upgrade_flag upg_malloc fail\r\n");
70 return ERRCODE_MALLOC;
71 }
72
73 ret_val = upg_flash_read(start_addr, sizeof(fota_upgrade_flag_area_t), (uint8_t *)(*upg_flag));
74 if (ret_val != ERRCODE_SUCC) {
75 upg_log_err("[UPG] upg_alloc_and_get_upgrade_flag read flash fail\r\n");
76 upg_free(*upg_flag);
77 *upg_flag = NULL;
78 return ret_val;
79 }
80
81 return ERRCODE_SUCC;
82 }
83
84 /*
85 * 获取在当前Flash上指定固件镜像的地址信息。该地址为flash上的相对地址,是相对flash基地址的偏移
86 * image_id 固件的镜像ID
87 * start_address 返回该镜像的起始地址
88 * size 返回该镜像区域的大小
89 */
upg_get_partition_info(uint32_t image_id,uint32_t * start_address,uint32_t * size)90 errcode_t upg_get_partition_info(uint32_t image_id, uint32_t *start_address, uint32_t *size)
91 {
92 errcode_t ret_val = ERRCODE_SUCC;
93 partition_information_t image_info = {0};
94
95 if (image_id == PARAMS_PARTITION_IMAGE_ID) {
96 /* 参数区地址信息 */
97 image_info.type = PARTITION_BY_ADDRESS;
98 image_info.part_info.addr_info.addr = PARAMS_PARTITION_START_ADDR;
99 image_info.part_info.addr_info.size = PARAMS_PARTITION_LENGTH;
100 #if UPG_CFG_SUPPORT_RESOURCES_FILE == YES
101 } else if (image_id == UPG_IMAGE_ID_RES_INDEX) {
102 image_info.type = PARTITION_BY_PATH;
103 #endif
104 } else {
105 ret_val = upg_get_image_info(image_id, &image_info);
106 if (ret_val != ERRCODE_SUCC) {
107 return ret_val;
108 }
109 }
110
111 if (image_info.type == PARTITION_BY_ADDRESS) {
112 *start_address = image_info.part_info.addr_info.addr;
113 *size = image_info.part_info.addr_info.size;
114 } else { /* PARTITION_BY_PATH */
115 *start_address = 0;
116 *size = uapi_upg_get_storage_size();
117 }
118
119 return ret_val;
120 }
121
upg_img_id_convert_to_partition_id(uint32_t image_id,partition_ids_t * item_id)122 STATIC errcode_t upg_img_id_convert_to_partition_id(uint32_t image_id, partition_ids_t *item_id)
123 {
124 upg_image_partition_ids_map_t *map = NULL;
125 uint32_t cnt = upg_get_ids_map(&map);
126 if (cnt == 0 || map == NULL || item_id == NULL) {
127 return ERRCODE_FAIL;
128 }
129 for (uint32_t i = 0; i < cnt; i++) {
130 if (map[i].image_id == image_id) {
131 *item_id = map[i].item_id;
132 return ERRCODE_SUCC;
133 }
134 }
135 return ERRCODE_FAIL;
136 }
137
upg_get_image_info(uint32_t image_id,partition_information_t * image_info)138 errcode_t upg_get_image_info(uint32_t image_id, partition_information_t *image_info)
139 {
140 partition_ids_t item_id;
141 if (image_info == NULL || upg_img_id_convert_to_partition_id(image_id, &item_id) != ERRCODE_SUCC) {
142 return ERRCODE_PARTITION_INVALID_PARAMS;
143 }
144
145 return uapi_partition_get_info(item_id, image_info);
146 }
147
148 #if (UPG_CFG_SUPPORT_FILE_SYSTEM == NO)
149 /*
150 * 读取升级包中的数据到buffer中
151 * read_offset 相对升级包开头的偏移
152 * buffer 读取数据buffer指针
153 * read_len 输入buffer的长度,输出实际读到的数据长度
154 */
upg_read_fota_pkg_data(uint32_t read_offset,uint8_t * buffer,uint32_t * read_len)155 errcode_t upg_read_fota_pkg_data(uint32_t read_offset, uint8_t *buffer, uint32_t *read_len)
156 {
157 errcode_t ret_val;
158 uint32_t start_addr = 0;
159 uint32_t size = 0;
160 uint32_t actual_len;
161
162 ret_val = upg_get_fota_partiton_area_addr(&start_addr, &size);
163 if (ret_val != ERRCODE_SUCC) {
164 return ret_val;
165 }
166
167 if (read_offset >= size || *read_len == 0) {
168 return ERRCODE_UPG_INVALID_PARAMETER;
169 }
170
171 actual_len = ((read_offset + *read_len) > size) ? (size - read_offset) : *read_len;
172 start_addr += read_offset;
173
174 ret_val = upg_flash_read(start_addr, actual_len, (uint8_t *)buffer);
175 if (ret_val != ERRCODE_SUCC) {
176 return ret_val;
177 }
178
179 *read_len = actual_len;
180 return ERRCODE_SUCC;
181 }
182
upg_package_get_storage_max_size(uint32_t * size)183 STATIC errcode_t upg_package_get_storage_max_size(uint32_t *size)
184 {
185 uint32_t start_addr = 0;
186 uint32_t fota_size = 0;
187 errcode_t ret = upg_get_fota_partiton_area_addr(&start_addr, &fota_size);
188 if (ret != ERRCODE_SUCC) {
189 return ret;
190 }
191
192 fota_size -= UPG_META_DATA_LENGTH + UPG_UPGRADE_FLAG_LENGTH;
193 *size = fota_size;
194 return ERRCODE_SUCC;
195 }
196 #else
upg_read_fota_pkg_data(uint32_t read_offset,uint8_t * buffer,uint32_t * read_len)197 errcode_t upg_read_fota_pkg_data(uint32_t read_offset, uint8_t *buffer, uint32_t *read_len)
198 {
199 uint32_t len = 0;
200 struct stat stat_buff = {0};
201 errcode_t ret_code = ERRCODE_SUCC;
202 uint32_t ret = (uint32_t)stat(upg_get_pkg_file_path(), &stat_buff);
203 if (ret != 0 || stat_buff.st_size == 0) {
204 return ERRCODE_UPG_EMPTY_FILE;
205 }
206
207 /* create ota image file */
208 int32_t rd_fd = open(upg_get_pkg_file_path(), O_RDONLY);
209 if (rd_fd < 0) {
210 return ERRCODE_UPG_FILE_OPEN_FAIL;
211 }
212
213 if ((long int)read_offset >= (long int)stat_buff.st_size) {
214 upg_log_err("[UPG] The read_offset is more than file size!\r\n");
215 ret_code = ERRCODE_UPG_FILE_READ_FAIL;
216 goto end;
217 }
218
219 long int left_len = ((long int)(read_offset + *read_len) > stat_buff.st_size) ?
220 stat_buff.st_size - (long int)read_offset : (long int)(*read_len);
221 ret = (uint32_t)lseek(rd_fd, read_offset, SEEK_SET);
222 if (ret != read_offset) {
223 ret_code = ERRCODE_UPG_FILE_SEEK_FAIL;
224 goto end;
225 }
226
227 while (left_len > 0) {
228 int32_t tmp = read(rd_fd, buffer + len, (size_t)left_len);
229 if (tmp <= 0) {
230 upg_log_err("[UPG] read_fota_pkg_data failed\r\n");
231 ret_code = ERRCODE_UPG_FILE_READ_FAIL;
232 goto end;
233 }
234 left_len -= tmp;
235 len += (uint32_t)tmp;
236 }
237
238 end:
239 *read_len = len;
240 (void)close(rd_fd);
241 return ret_code;
242 }
243
upg_package_get_storage_max_size(uint32_t * size)244 STATIC errcode_t upg_package_get_storage_max_size(uint32_t *size)
245 {
246 struct statfs sfs;
247 int result;
248 uint64_t free_size;
249 (void)memset_s(&sfs, sizeof(sfs), 0, sizeof(sfs));
250
251 result = statfs(upg_get_pkg_file_dir(), &sfs);
252 if (result != 0 || sfs.f_type == 0) {
253 upg_log_err("[UPG] statfs failed! Invalid argument!\r\n");
254 return ERRCODE_FAIL;
255 }
256
257 free_size = (uint64_t)sfs.f_bsize * sfs.f_bfree;
258 if (free_size <= PER_FILE_STORAGE_MAX_SIZE) {
259 *size = (uint32_t)free_size;
260 } else {
261 *size = PER_FILE_STORAGE_MAX_SIZE;
262 }
263 return ERRCODE_SUCC;
264 }
265 #endif
266
267 /*
268 * 获取本地存储空间可存储升级包的最大空间
269 * 返回最大空间
270 */
uapi_upg_get_storage_size(void)271 uint32_t uapi_upg_get_storage_size(void)
272 {
273 if (upg_is_inited() == false) {
274 return 0;
275 }
276
277 uint32_t size;
278 if (upg_package_get_storage_max_size(&size) != ERRCODE_SUCC) {
279 return 0;
280 }
281 return size;
282 }
283
284 /*
285 * 获取升级包包头结构指针
286 * pkg_header 返回升级包头结构指针,指针指向的空间在函数内分配,需要使用者使用完后调用upg_free释放。
287 * (如果采用直接访问flash的方式,返回升级包头所在的flash地址)
288 */
upg_get_package_header(upg_package_header_t ** pkg_header)289 errcode_t upg_get_package_header(upg_package_header_t **pkg_header)
290 {
291 #if (UPG_CFG_DIRECT_FLASH_ACCESS == NO)
292 errcode_t ret;
293 uint32_t actual_len = (uint32_t)sizeof(upg_package_header_t);
294
295 *pkg_header = upg_malloc(sizeof(upg_package_header_t));
296 if (*pkg_header == NULL) {
297 return ERRCODE_MALLOC;
298 }
299
300 ret = upg_read_fota_pkg_data(0, (uint8_t *)(*pkg_header), &actual_len);
301 if (ret != ERRCODE_SUCC || actual_len != sizeof(upg_package_header_t)) {
302 upg_free(*pkg_header);
303 *pkg_header = NULL;
304 return ret;
305 }
306 #else
307 uint32_t start_addr = 0;
308 uint32_t size = 0;
309 errcode_t ret;
310 ret = upg_get_fota_partiton_area_addr(&start_addr, &size);
311 if (ret != ERRCODE_SUCC) {
312 return ret;
313 }
314
315 *pkg_header = (upg_package_header_t*)(uintptr_t)(start_addr + upg_get_flash_base_addr());
316 #endif /* #if UPG_CFG_DIRECT_FLASH_ACCESS */
317
318 return ERRCODE_SUCC;
319 }
320
321 /*
322 * 获取镜像哈希表结构指针
323 * pkg_header 升级包头结构指针
324 * img_hash_table 返回对应的升级镜像HASH表头指针,指针指向的空间在函数内分配,需要使用者使用完后调用upg_free释放。
325 * (如果采用直接访问flash的方式,返回升级镜像哈希表所在的flash地址)
326 */
upg_get_pkg_image_hash_table(const upg_package_header_t * pkg_header,upg_image_hash_node_t ** img_hash_table)327 errcode_t upg_get_pkg_image_hash_table(const upg_package_header_t *pkg_header,
328 upg_image_hash_node_t **img_hash_table)
329 {
330 uint32_t offset;
331 errcode_t ret_val;
332
333 if (pkg_header->info_area.image_hash_table_addr == 0) {
334 offset = (uint32_t)sizeof(upg_package_header_t);
335 } else {
336 offset = pkg_header->info_area.image_hash_table_addr;
337 }
338
339 #if (UPG_CFG_DIRECT_FLASH_ACCESS == NO)
340 /* 由于ImageHashTable为了16字节对齐有填充字段,此处的长度不能使用image_num * sizeof(upg_image_hash_node_t)) */
341 uint32_t actual_len = pkg_header->info_area.image_hash_table_length;
342
343 *img_hash_table = upg_malloc(actual_len);
344 if (*img_hash_table == NULL) {
345 return ERRCODE_MALLOC;
346 }
347
348 ret_val = upg_read_fota_pkg_data(offset, (uint8_t *)(*img_hash_table), &actual_len);
349 if (ret_val != ERRCODE_SUCC || actual_len != pkg_header->info_area.image_hash_table_length) {
350 upg_free(*img_hash_table);
351 *img_hash_table = NULL;
352 return ret_val;
353 }
354
355 #else
356 uint32_t start_addr = 0;
357 uint32_t size = 0;
358
359 ret_val = upg_get_fota_partiton_area_addr(&start_addr, &size);
360 if (ret_val != ERRCODE_SUCC) {
361 return ret_val;
362 }
363
364 start_addr += offset;
365
366 *img_hash_table = (upg_image_hash_node_t*)(uintptr_t)(start_addr + upg_get_flash_base_addr());
367 #endif /* #if UPG_CFG_DIRECT_FLASH_ACCESS */
368
369 return ERRCODE_SUCC;
370 }
371
372 /*
373 * 获取升级镜像的头结构指针
374 * img_hash_table 升级镜像HASH表节点指针
375 * img_header 返回对应的升级镜像头指针,指针指向的空间在函数内分配,需要使用者使用完后调用upg_free释放。
376 * (如果采用直接访问flash的方式,返回镜像头所在的flash地址)
377 */
upg_get_pkg_image_header(const upg_image_hash_node_t * img_hash_table,upg_image_header_t ** img_header)378 errcode_t upg_get_pkg_image_header(const upg_image_hash_node_t *img_hash_table, upg_image_header_t **img_header)
379 {
380 #if (UPG_CFG_DIRECT_FLASH_ACCESS == NO)
381 errcode_t ret_val;
382 uint32_t actual_len = (uint32_t)sizeof(upg_image_header_t);
383
384 *img_header = upg_malloc(sizeof(upg_image_header_t));
385 if (*img_header == NULL) {
386 return ERRCODE_MALLOC;
387 }
388
389 ret_val = upg_read_fota_pkg_data(img_hash_table->image_addr, (uint8_t *)(*img_header), &actual_len);
390 if (ret_val != ERRCODE_SUCC || actual_len != sizeof(upg_image_header_t)) {
391 upg_free(*img_header);
392 *img_header = NULL;
393 return ret_val;
394 }
395 #else
396 uint32_t start_addr = 0;
397 uint32_t size = 0;
398 errcode_t ret_val;
399 ret_val = upg_get_fota_partiton_area_addr(&start_addr, &size);
400 if (ret_val != ERRCODE_SUCC) {
401 return ret_val;
402 }
403
404 start_addr += img_hash_table->image_addr;
405
406 *img_header = (upg_image_header_t*)(uintptr_t)(start_addr + upg_get_flash_base_addr());
407 #endif /* #if UPG_CFG_DIRECT_FLASH_ACCESS */
408
409 return ERRCODE_SUCC;
410 }
411
412 /*
413 * 获取升级镜像的数据指针
414 * img_header 升级镜像头结构指针
415 * data_offset 相对升级镜像数据开头的偏移
416 * data_len 输入要获取数据的长度,输出实际获取到的数据长度
417 * img_data 返回升级镜像数据的指针
418 如果未采用直接访问flash方式(即UPG_CFG_DIRECT_FLASH_ACCESS==NO),返回的指针指向的空间在函数内分配,使用者使用完后
419 必须调用upg_free释放。
420 * 如果采用直接访问flash的方式(即UPG_CFG_DIRECT_FLASH_ACCESS==YES),返回指针为数据所在的flash地址,使用者无需释放。
421 */
upg_get_pkg_image_data(const upg_image_header_t * img_header,uint32_t data_offset,uint32_t * data_len,uint8_t ** img_data)422 errcode_t upg_get_pkg_image_data(const upg_image_header_t *img_header,
423 uint32_t data_offset, uint32_t *data_len, uint8_t **img_data)
424 {
425 #if (UPG_CFG_DIRECT_FLASH_ACCESS == NO)
426 errcode_t ret_val;
427 *img_data = upg_malloc(*data_len);
428 if (*img_data == NULL) {
429 return ERRCODE_MALLOC;
430 }
431
432 ret_val = upg_copy_pkg_image_data(img_header, data_offset, data_len, *img_data);
433 if (ret_val != ERRCODE_SUCC) {
434 upg_free(*img_data);
435 *img_data = NULL;
436 return ret_val;
437 }
438 #else
439 uint32_t start_addr = 0;
440 uint32_t size = 0;
441 uint32_t actual_len;
442 errcode_t ret_val;
443 uint32_t aligned_image_len = upg_aligned(img_header->image_len, 16); /* 16-byte alignment */
444
445 ret_val = upg_get_fota_partiton_area_addr(&start_addr, &size);
446 if (ret_val != ERRCODE_SUCC) {
447 return ret_val;
448 }
449
450 if (data_offset >= aligned_image_len || img_data == NULL ||
451 data_len == NULL || *data_len == 0) {
452 return ERRCODE_UPG_INVALID_PARAMETER;
453 }
454
455 actual_len = (data_offset + *data_len > aligned_image_len) ? (aligned_image_len - data_offset) : *data_len;
456
457 start_addr += img_header->image_offset;
458 *img_data = (uint8_t*)(uintptr_t)(start_addr + data_offset + upg_get_flash_base_addr());
459 *data_len = actual_len;
460 #endif /* #if UPG_CFG_DIRECT_FLASH_ACCESS */
461 return ERRCODE_SUCC;
462 }
463
464 /*
465 * 拷贝升级镜像指定范围的数据至buffer中
466 * img_header 升级镜像头结构指针
467 * data_offset 相对升级镜像数据开头的偏移
468 * data_len 输出要拷贝的数据的长度,输出实际拷贝的数据长度
469 * img_data 保存数据的buffer指针,buffer的空间需要使用者分配
470 */
upg_copy_pkg_image_data(const upg_image_header_t * img_header,uint32_t data_offset,uint32_t * data_len,uint8_t * img_data)471 errcode_t upg_copy_pkg_image_data(const upg_image_header_t *img_header,
472 uint32_t data_offset, uint32_t *data_len, uint8_t *img_data)
473 {
474 errcode_t ret_val;
475 uint32_t aligned_image_len = upg_aligned(img_header->image_len, 16); /* 16-byte alignment */
476 uint32_t actual_len;
477
478 if (data_offset >= aligned_image_len || img_data == NULL ||
479 data_len == NULL || *data_len == 0) {
480 return ERRCODE_UPG_INVALID_PARAMETER;
481 }
482
483 actual_len = (data_offset + *data_len > aligned_image_len) ? (aligned_image_len - data_offset) : *data_len;
484
485 ret_val = upg_read_fota_pkg_data(img_header->image_offset + data_offset, img_data, &actual_len);
486 if (ret_val != ERRCODE_SUCC) {
487 return ret_val;
488 }
489
490 *data_len = actual_len;
491 return ERRCODE_SUCC;
492 }
493
494 #if UPG_CFG_SUPPORT_IMAGE_ON_FILE_SYSTEM == YES
upg_read_old_image_data_from_fs(const char * file_path,uint32_t read_offset,uint8_t * buffer,uint32_t * read_len)495 STATIC errcode_t upg_read_old_image_data_from_fs(const char *file_path, uint32_t read_offset,
496 uint8_t *buffer, uint32_t *read_len)
497 {
498 uint16_t len = 0;
499 struct stat stat_buff = {0};
500 uint32_t ret = stat(file_path, &stat_buff);
501 if (ret != 0 || stat_buff.st_size == 0) {
502 return ERRCODE_UPG_EMPTY_FILE;
503 }
504
505 /* create ota image file */
506 FILE *rd_fd = fopen(file_path, "rb");
507 if (rd_fd == NULL) {
508 upg_log_err("[UPG] open %s fail!\r\n", file_path);
509 return ERRCODE_UPG_FILE_OPEN_FAIL;
510 }
511
512 if ((long int)read_offset > stat_buff.st_size) {
513 upg_log_err("[UPG] The read_offset is more than file size!\r\n");
514 ret = ERRCODE_UPG_FILE_READ_FAIL;
515 goto end;
516 }
517
518 long int left_len = ((long int)(read_offset + *read_len) > stat_buff.st_size) ?
519 stat_buff.st_size - (long int)read_offset : (long int)(*read_len);
520 ret = fseek(rd_fd, read_offset, SEEK_SET);
521 if (ret != 0) {
522 upg_log_err("[UPG] seek file fail!\r\n");
523 ret = ERRCODE_UPG_FILE_SEEK_FAIL;
524 goto end;
525 }
526
527 while (left_len > 0) {
528 uint16_t tmp_read = fread(buffer + len, 1, left_len, rd_fd);
529 if (tmp_read == 0) {
530 if (ferror(rd_fd)) {
531 upg_log_err("[UPG] read file fail!\r\n");
532 ret = ERRCODE_UPG_FILE_READ_FAIL;
533 goto end;
534 }
535 }
536 left_len -= tmp_read;
537 len += tmp_read;
538 }
539
540 end:
541 *read_len = len;
542 (void)fclose(rd_fd);
543 return ret;
544 }
545 #endif
546
547 /*
548 * 从指定image_id的镜像所在的地址上读取数据到buffer中
549 * write_offset 相对镜像起始地址的偏移
550 * buffer 存储数据的buffer指针
551 * write_len buffer的长度
552 * image_id 镜像的ID
553 */
upg_read_old_image_data(uint32_t read_offset,uint8_t * buffer,uint32_t * read_len,uint32_t image_id)554 errcode_t upg_read_old_image_data(uint32_t read_offset, uint8_t *buffer, uint32_t *read_len, uint32_t image_id)
555 {
556 errcode_t ret_val;
557 partition_information_t image_info = {0};
558
559 if (image_id == PARAMS_PARTITION_IMAGE_ID) {
560 /* 参数区地址信息 */
561 image_info.type = PARTITION_BY_ADDRESS;
562 image_info.part_info.addr_info.size = PARAMS_PARTITION_LENGTH;
563 image_info.part_info.addr_info.addr = PARAMS_PARTITION_START_ADDR;
564 } else {
565 ret_val = upg_get_image_info(image_id, &image_info);
566 if (ret_val != ERRCODE_SUCC) {
567 return ret_val;
568 }
569 }
570
571 if (image_info.type == PARTITION_BY_ADDRESS) {
572 uint32_t app_address = image_info.part_info.addr_info.addr;
573 ret_val = upg_flash_read(app_address + read_offset, *read_len, (uint8_t *)buffer);
574 } else { /* 分区类型:PARTITION_BY_PATH */
575 #if UPG_CFG_SUPPORT_IMAGE_ON_FILE_SYSTEM == YES
576 ret_val = upg_read_old_image_data_from_fs(
577 (const char *)image_info.part_info.file_path, read_offset, buffer, read_len);
578 #else
579 ret_val = ERRCODE_UPG_INVALID_IMAGE_ID;
580 #endif
581 }
582 return ret_val;
583 }
584
upg_get_firmware_flag_address(uint32_t firmware_index,uint32_t current_loop,uint32_t * flag_addr)585 STATIC errcode_t upg_get_firmware_flag_address(uint32_t firmware_index, uint32_t current_loop, uint32_t *flag_addr)
586 {
587 uint32_t fota_flag_addr = 0;
588 uint32_t addr;
589
590 errcode_t ret = upg_get_upgrade_flag_flash_start_addr(&fota_flag_addr);
591 if (ret != ERRCODE_SUCC) {
592 return ret;
593 }
594
595 if (firmware_index == UPG_IMAGE_ID_NV) {
596 addr = fota_flag_addr + offsetof(fota_upgrade_flag_area_t, nv_flag);
597 addr += current_loop * (uint32_t)sizeof(uint8_t);
598 } else {
599 addr = fota_flag_addr + offsetof(fota_upgrade_flag_area_t, firmware_flag);
600 addr += (firmware_index * UPG_FLAG_RETYR_TIMES) + (current_loop * (uint32_t)sizeof(uint8_t));
601 }
602
603 *flag_addr = addr;
604 return ERRCODE_SUCC;
605 }
606
607 /*
608 * 设置指定固件的升级标记
609 * firmware_index为升级包中的固件(除NV之外的镜像)的序号
610 * 如升级包中包含 固件0、固件1、固件2、NV、固件3,其中固件3的序号为3而不是4
611 */
upg_set_firmware_update_status(fota_upgrade_flag_area_t * upg_flag,uint32_t firmware_index,upg_image_status_switch_t switch_status)612 errcode_t upg_set_firmware_update_status(fota_upgrade_flag_area_t *upg_flag,
613 uint32_t firmware_index, upg_image_status_switch_t switch_status)
614 {
615 uint32_t write_len = 0;
616 uint32_t flag_addr = 0;
617 uint8_t *firmware_flag;
618 uint32_t i;
619
620 if (firmware_index == UPG_IMAGE_ID_NV) {
621 firmware_flag = upg_flag->nv_flag;
622 } else {
623 firmware_flag = upg_flag->firmware_flag[firmware_index];
624 }
625
626 /* 获取第一个非0的flag, 即第i次重试的flag */
627 for (i = 0; i < UPG_FLAG_RETYR_TIMES; i++) {
628 if (firmware_flag[i] != 0) {
629 break;
630 }
631 }
632
633 if (i >= UPG_FLAG_RETYR_TIMES) {
634 return ERRCODE_SUCC;
635 }
636
637 errcode_t ret = upg_get_firmware_flag_address(firmware_index, i, &flag_addr);
638 if (ret != ERRCODE_SUCC) {
639 return ret;
640 }
641
642 if ((switch_status == UPG_IMAGE_STATUS_SWITCH_TO_STARTED) && (firmware_flag[i] == NOT_START_FLAG)) {
643 /* 当前flag为NOT_START, 要切换成STARTED */
644 write_len = 1;
645 firmware_flag[i] = STARTED_FLAG;
646 } else if ((switch_status == UPG_IMAGE_STATUS_SWITCH_TO_RETRY) && (firmware_flag[i] == STARTED_FLAG)) {
647 /* 当前flag为STARTED, 要切换成RETRY, 即当前flag置为0 */
648 write_len = 1;
649 firmware_flag[i] = FINISHED_FLAG;
650 } else if (switch_status == UPG_IMAGE_STATUS_SWITCH_TO_FINISHED) {
651 /* 要切换成FINISH,即全部flag置为0 */
652 write_len = UPG_FLAG_RETYR_TIMES - i;
653 (void)memset_s(&firmware_flag[i], write_len, FINISHED_FLAG, write_len);
654 } else {
655 /* 其他情况不做处理 */
656 return ERRCODE_SUCC;
657 }
658
659 ret = upg_flash_write(flag_addr, write_len, (uint8_t *)&(firmware_flag[i]), false);
660 if (ret != ERRCODE_SUCC) {
661 upg_log_err("[UPG] upg_flash_write upgrader flag fail. ret = 0x%x\r\n", ret);
662 return ret;
663 }
664
665 if (i >= UPG_FLAG_RETYR_TIMES - 1 && firmware_flag[i] == FINISHED_FLAG) {
666 upg_log_err("[UPG] retry times all failed\r\n");
667 upg_set_temporary_result(UPG_RESULT_RETRY_ALL_FAILED);
668 return ERRCODE_UPG_RETRY_ALL_FAIL;
669 }
670 return ERRCODE_SUCC;
671 }
672
673 /*
674 * 获取升级包中的升级镜像的升级标记状态(NOT_STARTED/STARTED/RETRY/FINISHED)
675 * firmware_index为升级包中的固件(除NV之外的镜像)的序号
676 * 如升级包中包含 固件0、固件1、固件2、NV、固件3,其中固件3的序号为3而不是4
677 * 如为NV镜像,firmware_index参数可忽略
678 */
upg_get_image_update_status(fota_upgrade_flag_area_t * upg_flag,uint32_t firmware_index,uint32_t image_id)679 upg_image_status_t upg_get_image_update_status(fota_upgrade_flag_area_t *upg_flag,
680 uint32_t firmware_index, uint32_t image_id)
681 {
682 uint8_t *firmware_flag;
683 uint8_t finished_flag[UPG_FLAG_RETYR_TIMES] = { FINISHED_FLAG, FINISHED_FLAG, FINISHED_FLAG };
684 uint8_t init_flag[UPG_FLAG_RETYR_TIMES] = { NOT_START_FLAG, NOT_START_FLAG, NOT_START_FLAG };
685 uint32_t i;
686
687 if (image_id == UPG_IMAGE_ID_NV) {
688 firmware_flag = upg_flag->nv_flag;
689 } else {
690 firmware_flag = upg_flag->firmware_flag[firmware_index];
691 }
692
693 if (memcmp(firmware_flag, finished_flag, UPG_FLAG_RETYR_TIMES) == 0) {
694 /* 3个flag都是0x00, 处理完成状态 */
695 return UPG_IMAGE_STATUS_FINISHED;
696 } else if (memcmp(firmware_flag, init_flag, UPG_FLAG_RETYR_TIMES) == 0) {
697 /* 3个flag都是0xFF, 未开始处理状态 */
698 return UPG_IMAGE_STATUS_NOT_STARTED;
699 } else {
700 /* 获取第一个非0的flag,即当前正在处理的第i次重试的flag */
701 for (i = 0; i < UPG_FLAG_RETYR_TIMES; i++) {
702 if (firmware_flag[i] != 0) {
703 break;
704 }
705 }
706
707 if (firmware_flag[i] == STARTED_FLAG) {
708 return UPG_IMAGE_STATUS_STARTED;
709 } else if (firmware_flag[i] == NOT_START_FLAG) {
710 return UPG_IMAGE_STATUS_RETRY;
711 } else {
712 return UPG_IMAGE_STATUS_INVALID;
713 }
714 }
715 }
716
717 /* 擦除metadata数据区 */
upg_flash_erase_metadata_pages(void)718 errcode_t upg_flash_erase_metadata_pages(void)
719 {
720 return ERRCODE_SUCC;
721 }
722
723 /* 设置升级结果(临时保存) */
upg_set_temporary_result(upg_result_t result)724 void upg_set_temporary_result(upg_result_t result)
725 {
726 upg_get_ctx()->temporary_result = result;
727 }
728
729 /* 获取临时保存的升级结果 */
upg_get_temporary_result(void)730 upg_result_t upg_get_temporary_result(void)
731 {
732 return upg_get_ctx()->temporary_result;
733 }
734
735 /* 将升级结果保存至Flash升级标记区 */
upg_set_update_result(upg_result_t result)736 void upg_set_update_result(upg_result_t result)
737 {
738 uint32_t fota_flag_addr = 0;
739 uint32_t result_tmp = (uint32_t)result;
740 errcode_t ret = upg_get_upgrade_flag_flash_start_addr(&fota_flag_addr);
741 if (ret != ERRCODE_SUCC) {
742 return;
743 }
744
745 uint32_t result_addr = fota_flag_addr + offsetof(fota_upgrade_flag_area_t, update_result);
746 ret = upg_flash_write(result_addr, sizeof(uint32_t), (uint8_t *)&(result_tmp), false);
747 if (ret != ERRCODE_SUCC) {
748 return;
749 }
750 return;
751 }
752
753 /* 检查是否所有镜像都已完成升级(包括升级失败但是已尝试最大次数) */
upg_check_image_update_complete(const fota_upgrade_flag_area_t * upg_flag,uint32_t image_num)754 bool upg_check_image_update_complete(const fota_upgrade_flag_area_t *upg_flag, uint32_t image_num)
755 {
756 uint32_t firmware_index;
757 const uint8_t *firmware_flag;
758 uint8_t finish_flag[UPG_FLAG_RETYR_TIMES] = {FINISHED_FLAG, FINISHED_FLAG, FINISHED_FLAG};
759
760 for (firmware_index = 0; firmware_index < upg_flag->firmware_num; firmware_index++) {
761 firmware_flag = upg_flag->firmware_flag[firmware_index];
762 /* 存在升级包未完成升级 */
763 if (memcmp(firmware_flag, finish_flag, UPG_FLAG_RETYR_TIMES) != 0) {
764 return false;
765 }
766 }
767
768 /* 存在nv升级包,并且nv升级准备工作未完成 */
769 if (upg_flag->firmware_num != image_num && upg_flag->nv_flag[0] != STARTED_FLAG) { /* index 0:start flag */
770 return false;
771 }
772 return true;
773 }
774
upg_write_complete_flag(uint32_t fota_flag_addr,uint32_t complete_flag)775 STATIC void upg_write_complete_flag(uint32_t fota_flag_addr, uint32_t complete_flag)
776 {
777 if (complete_flag != UPG_ABNORMAL_FLAG) {
778 uint32_t flag_addr = fota_flag_addr + offsetof(fota_upgrade_flag_area_t, complete_flag);
779 upg_log_info("[UPG] write complete: 0x%x\r\n", complete_flag);
780 if (upg_flash_write(flag_addr, sizeof(uint32_t), (uint8_t *)&(complete_flag), false) != ERRCODE_SUCC) {
781 return;
782 }
783 }
784
785 #if (UPG_CFG_SUPPORT_RESOURCES_FILE == YES)
786 if (complete_flag == 0) {
787 dfx_file_delete(upg_get_res_file_index_path());
788 }
789 #endif
790 }
791 /* 设置升级完成标记 */
upg_set_complete_flag(uint32_t image_num,errcode_t result,bool direct_finish)792 void upg_set_complete_flag(uint32_t image_num, errcode_t result, bool direct_finish)
793 {
794 uint32_t fota_flag_addr = 0;
795 uint32_t complete_flag = UPG_ABNORMAL_FLAG;
796 bool image_complete = false;
797
798 errcode_t ret = upg_get_upgrade_flag_flash_start_addr(&fota_flag_addr);
799 if (ret != ERRCODE_SUCC) {
800 return;
801 }
802
803 fota_upgrade_flag_area_t upg_flag;
804 ret = upg_flash_read(fota_flag_addr, sizeof(fota_upgrade_flag_area_t), (uint8_t *)(&upg_flag));
805 if (ret != ERRCODE_SUCC) {
806 upg_log_err("[UPG] upg_flash_read flag fail\r\n");
807 return;
808 }
809
810 do {
811 /*
812 * 1. 当前程序中升级流程返回失败,直接结束升级流程(如整包校验失败),
813 * 则升级流程失败,结束升级,将flag置成 UPG_FINISH_ALL_FLAG;
814 */
815 if (direct_finish && (upg_flag.complete_flag != UPG_FINISH_ALL_FLAG)) {
816 complete_flag = UPG_FINISH_ALL_FLAG;
817 /* 保存升级结果至升级标记区内 */
818 upg_set_update_result(upg_get_temporary_result());
819 break;
820 }
821
822 /*
823 * 2. 当前程序中升级流程返回成功,
824 * 即当前程序中支持升级的所有镜像成功升级,但存在还需要升级的镜像,则将flag置成 UPG_FINISH_HALF_FLAG;
825 */
826 image_complete = upg_check_image_update_complete(&upg_flag, image_num);
827 if (result == ERRCODE_SUCC && !image_complete) {
828 if (upg_flag.complete_flag != UPG_FINISH_HALF_FLAG) {
829 complete_flag = UPG_FINISH_HALF_FLAG;
830 }
831 } else if (image_complete && (upg_flag.complete_flag != UPG_FINISH_ALL_FLAG)) {
832 /*
833 * 3. 若升级包中所有镜像成功升级,将flag置成 UPG_FINISH_ALL_FLAG;
834 */
835 complete_flag = UPG_FINISH_ALL_FLAG;
836 if (result == ERRCODE_SUCC) {
837 upg_set_temporary_result(UPG_RESULT_UPDATE_SUCCESS);
838 }
839 /* 保存升级结果至升级标记区内 */
840 upg_set_update_result(upg_get_temporary_result());
841 } else if (upg_get_temporary_result() == UPG_RESULT_RETRY_ALL_FAILED &&
842 (upg_flag.complete_flag != UPG_FINISH_ALL_FLAG)) {
843 /*
844 * 4. 当前程序中升级流程返回失败,但最后一个已处理的镜像的3个flag全0,即已经重试最大次数,仍然失败,
845 * 则升级流程失败,结束升级,将flag置成 UPG_FINISH_ALL_FLAG;
846 */
847 complete_flag = UPG_FINISH_ALL_FLAG;
848 upg_set_update_result(upg_get_temporary_result());
849 }
850 } while (0);
851
852 /* 升级标记需要修改 */
853 upg_write_complete_flag(fota_flag_addr, complete_flag);
854 }
855
856 /* 获取升级结果 */
uapi_upg_get_result(upg_result_t * result,uint32_t * last_image_index)857 errcode_t uapi_upg_get_result(upg_result_t *result, uint32_t *last_image_index)
858 {
859 if (result == NULL || last_image_index == NULL) {
860 return ERRCODE_UPG_NULL_POINTER;
861 }
862 fota_upgrade_flag_area_t *upg_flag_info;
863 errcode_t ret = upg_alloc_and_get_upgrade_flag(&upg_flag_info);
864 if (ret != ERRCODE_SUCC || upg_flag_info == NULL) {
865 return ret;
866 }
867
868 *result = upg_flag_info->update_result;
869 *last_image_index = UINT32_MAX;
870 upg_free(upg_flag_info);
871 return ERRCODE_SUCC;
872 }
873
874 /* 获取注册函数列表 */
upg_get_func_list(void)875 upg_func_t *upg_get_func_list(void)
876 {
877 return &(g_upg_ctx.func_list);
878 }
879
upg_is_inited(void)880 bool upg_is_inited(void)
881 {
882 return g_upg_ctx.inited;
883 }
884
upg_get_status(void)885 STATIC upg_status_t upg_get_status(void)
886 {
887 uint8_t temp = 0;
888 upg_status_t status = UPG_STATUS_NONE;
889 uint32_t flag_addr = 0;
890 fota_upgrade_flag_area_t *upg_flag_info = NULL;
891 if (upg_alloc_and_get_upgrade_flag(&upg_flag_info) != ERRCODE_SUCC) {
892 return status;
893 }
894
895 do {
896 if (upg_flag_info->head_magic != UPG_HEAD_MAGIC || upg_flag_info->head_end_magic != UPG_END_MAGIC) {
897 status = UPG_STATUS_NONE;
898 break;
899 }
900
901 if (upg_flag_info->complete_flag != 0) {
902 status = UPG_STATUS_UPDATING;
903 break;
904 }
905
906 if (upg_flag_info->ver_change_flag == 0) {
907 status = UPG_STATUS_NONE;
908 break;
909 }
910
911 if (upg_flag_info->update_result == UPG_RESULT_UPDATE_SUCCESS) {
912 status = UPG_STATUS_SUCC;
913 } else {
914 status = UPG_STATUS_FAIL;
915 }
916 if (upg_get_upgrade_flag_flash_start_addr(&flag_addr) != ERRCODE_SUCC) {
917 status = UPG_STATUS_NONE;
918 break;
919 }
920
921 flag_addr += offsetof(fota_upgrade_flag_area_t, ver_change_flag);
922 if (upg_flash_write(flag_addr, sizeof(uint8_t), &temp, false) != ERRCODE_SUCC) {
923 status = UPG_STATUS_NONE;
924 }
925 } while (0);
926
927 upg_free(upg_flag_info);
928 return status;
929 }
930
uapi_upg_init(const upg_func_t * func_list)931 errcode_t uapi_upg_init(const upg_func_t *func_list)
932 {
933 if (upg_is_inited()) {
934 return ERRCODE_UPG_ALREADY_INIT;
935 }
936
937 if (func_list != NULL) {
938 g_upg_ctx.func_list.malloc = func_list->malloc;
939 g_upg_ctx.func_list.free = func_list->free;
940 g_upg_ctx.func_list.serial_putc = func_list->serial_putc;
941 }
942 g_upg_ctx.temporary_result = UPG_RESULT_MAX;
943 g_upg_ctx.packge_len = 0;
944 g_upg_ctx.inited = true;
945 g_upg_ctx.upg_status = upg_get_status();
946 return ERRCODE_SUCC;
947 }
948
949 #if (UPG_CFG_ANTI_ROLLBACK_SUPPORT == YES)
upg_anti_rollback_version_verify(const upg_package_header_t * pkg_header,const upg_image_header_t * img_header)950 errcode_t upg_anti_rollback_version_verify(
951 const upg_package_header_t *pkg_header, const upg_image_header_t *img_header)
952 {
953 // NV及资源文件不做防回滚
954 if (img_header->image_id == UPG_IMAGE_ID_NV || img_header->image_id == UPG_IMAGE_ID_RES_INDEX ||
955 img_header->image_id == UPG_IMAGE_ID_RES_DATA) {
956 return ERRCODE_SUCC;
957 }
958 uint32_t image_id = img_header->image_id;
959 uint32_t key_ver = pkg_header->key_area.fota_key_version_ext;
960 uint32_t code_ver = img_header->version_ext;
961 uint32_t otp_ver;
962
963 errcode_t ret = upg_get_board_rollback_version(image_id, &otp_ver);
964 if (ret != ERRCODE_SUCC) {
965 return ret;
966 }
967
968 uint32_t board_key_mask;
969 uint32_t board_code_mask;
970
971 ret = upg_get_board_version_mask(image_id, &board_key_mask, &board_code_mask);
972 if (ret != ERRCODE_SUCC) {
973 return ret;
974 }
975 if (((key_ver & board_key_mask) < (otp_ver & board_key_mask)) ||
976 ((code_ver & board_code_mask) < (otp_ver & board_code_mask))) {
977 return ERRCODE_FAIL;
978 }
979 upg_log_info("[UPG] upg verify: anti rollback version_verify ok. image_id = 0x%x\r\n", img_header->image_id);
980 return ERRCODE_SUCC;
981 }
982
upg_anti_rollback_version_update(const upg_image_header_t * img_header)983 errcode_t upg_anti_rollback_version_update(const upg_image_header_t *img_header)
984 {
985 // NV及资源文件不做防回滚
986 if (img_header->image_id == UPG_IMAGE_ID_NV || img_header->image_id == UPG_IMAGE_ID_RES_INDEX ||
987 img_header->image_id == UPG_IMAGE_ID_RES_DATA) {
988 return ERRCODE_SUCC;
989 }
990
991 uint32_t image_id = img_header->image_id;
992 uint32_t key_ver = 0;
993 uint32_t board_key_mask = 0;
994 uint32_t code_ver = 0;
995 uint32_t board_code_mask = 0;
996 uint32_t new_ver;
997 uint32_t old_ver;
998
999 errcode_t ret = upg_get_board_rollback_version(image_id, &old_ver);
1000 if (ret != ERRCODE_SUCC) {
1001 return ret;
1002 }
1003
1004 // 获取更新后的板端的掩码
1005 ret = upg_get_board_version_mask(image_id, &board_key_mask, &board_code_mask);
1006 if (ret != ERRCODE_SUCC) {
1007 return ret;
1008 }
1009 // 获取更新后的板端镜像版本
1010 ret = upg_get_board_version(image_id, &key_ver, &code_ver);
1011 if (ret != ERRCODE_SUCC) {
1012 return ret;
1013 }
1014 if ((code_ver & board_code_mask) < (old_ver & board_code_mask) ||
1015 (key_ver & board_key_mask) < (old_ver & board_key_mask)) {
1016 return ERRCODE_FAIL;
1017 }
1018
1019 new_ver = (code_ver & board_code_mask) | (key_ver & board_key_mask);
1020 return upg_set_board_rollback_version(image_id, &new_ver);
1021 }
1022 #endif
1023