218 lines
6.7 KiB
C
218 lines
6.7 KiB
C
/*
|
|
* Copyright (c) @CompanyNameMagicTag 2021-2021. All rights reserved.
|
|
* Description: UPG upgrade functions source file
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include "securec.h"
|
|
#include "common_def.h"
|
|
#include "upg_definitions.h"
|
|
#include "errcode.h"
|
|
#include "upg_lzmadec.h"
|
|
#include "upg_common.h"
|
|
#include "upg_common_porting.h"
|
|
#include "upg_alloc.h"
|
|
#include "upg_porting.h"
|
|
#include "upg_config.h"
|
|
#include "upg_debug.h"
|
|
#if (UPG_CFG_SUPPORT_RESOURCES_FILE == YES)
|
|
#include "dfx_file_operation.h"
|
|
|
|
STATIC errcode_t upg_resource_file_full(const upg_lzma_decode2_data_t *data, upg_resource_node_t *file_info)
|
|
{
|
|
errcode_t ret = ERRCODE_SUCC;
|
|
uint32_t file_len = file_info->file_len;
|
|
uint32_t read_offset = data->in_offset + file_info->offset;
|
|
uint32_t file_offset = 0;
|
|
|
|
int32_t write_fd = dfx_file_open_for_write(file_info->file_path);
|
|
if (write_fd < 0) {
|
|
return ERRCODE_UPG_FILE_OPEN_FAIL;
|
|
}
|
|
|
|
while (file_len > 0) {
|
|
uint32_t tmp_len = file_len > UPG_FLASH_PAGE_SIZE ? UPG_FLASH_PAGE_SIZE : file_len;
|
|
(void)memset_s(data->outbuf, UPG_FLASH_PAGE_SIZE, 0, UPG_FLASH_PAGE_SIZE);
|
|
ret = upg_read_fota_pkg_data(read_offset + file_offset, data->outbuf, &tmp_len);
|
|
if (ret != ERRCODE_SUCC) {
|
|
break;
|
|
}
|
|
|
|
if (dfx_file_write_fd(write_fd, file_offset, data->outbuf, tmp_len) != (int32_t)tmp_len) {
|
|
ret = ERRCODE_UPG_FILE_WRITE_FAIL;
|
|
break;
|
|
}
|
|
file_len -= tmp_len;
|
|
file_offset += tmp_len;
|
|
}
|
|
upg_calculate_and_notify_process((uint32_t)file_offset);
|
|
|
|
dfx_file_fsync(write_fd);
|
|
dfx_file_close(write_fd);
|
|
return ret;
|
|
}
|
|
|
|
STATIC errcode_t upg_resource_file_delete(const char *file_path)
|
|
{
|
|
(void)dfx_file_delete(file_path);
|
|
return ERRCODE_SUCC;
|
|
}
|
|
|
|
STATIC errcode_t upg_resource_file_rmdir(const char *path)
|
|
{
|
|
(void)dfx_file_rmdir(path);
|
|
return ERRCODE_SUCC;
|
|
}
|
|
|
|
STATIC errcode_t upg_resource_data_task(CLzmaDec *p, upg_lzma_decode2_data_t *data,
|
|
const upg_image_header_t *image, upg_resource_node_t *file_info)
|
|
{
|
|
if (file_info->operation_type != UPG_RESOURCE_ADD_FILE && file_info->operation_type != UPG_RESOURCE_AMEND_FILE) {
|
|
return ERRCODE_SUCC;
|
|
}
|
|
|
|
if (file_info->file_len == 0) {
|
|
return ERRCODE_SUCC;
|
|
}
|
|
|
|
if (image->decompress_flag == DECOMPRESS_FLAG_ZIP) {
|
|
upg_msg0("decompress resource file");
|
|
return upg_resource_file_decode(p, data, file_info);
|
|
}
|
|
|
|
upg_msg0("full resource file");
|
|
return upg_resource_file_full(data, file_info);
|
|
}
|
|
|
|
STATIC errcode_t upg_resource_index_task(upg_resource_node_t *file_info)
|
|
{
|
|
if (file_info->operation_type == UPG_RESOURCE_DELETE_FILE) {
|
|
upg_msg0("delete file");
|
|
return upg_resource_file_delete(file_info->file_path);
|
|
} else if (file_info->operation_type == UPG_RESOURCE_REMOVE_DIR) {
|
|
upg_msg0("remove dir");
|
|
return upg_resource_file_rmdir(file_info->file_path);
|
|
}
|
|
|
|
return ERRCODE_SUCC;
|
|
}
|
|
|
|
STATIC errcode_t upg_resource_process_node(CLzmaDec *p, upg_lzma_decode2_data_t *data,
|
|
const upg_image_header_t *image, bool is_index)
|
|
{
|
|
errcode_t ret = ERRCODE_FAIL;
|
|
upg_resource_index_t resource_index = {0};
|
|
uint32_t read_len = sizeof(upg_resource_index_t);
|
|
|
|
int32_t index_fd = dfx_file_open_for_read(upg_get_res_file_index_path());
|
|
if (index_fd < 0) {
|
|
return ERRCODE_UPG_FILE_OPEN_FAIL;
|
|
}
|
|
|
|
if (dfx_file_read_fd(index_fd, 0, (uint8_t *)&resource_index, read_len, true) != (int32_t)read_len) {
|
|
dfx_file_close(index_fd);
|
|
return ERRCODE_UPG_FILE_READ_FAIL;
|
|
}
|
|
|
|
upg_resource_node_t *file_info = (upg_resource_node_t *)upg_malloc(sizeof(upg_resource_node_t));
|
|
if (file_info == NULL) {
|
|
dfx_file_close(index_fd);
|
|
return ERRCODE_MALLOC;
|
|
}
|
|
|
|
read_len = sizeof(upg_resource_node_t);
|
|
for (uint32_t i = 0; i < resource_index.file_num; i++) {
|
|
memset_s(file_info, sizeof(upg_resource_node_t), 0, sizeof(upg_resource_node_t));
|
|
uint32_t offset = sizeof(upg_resource_index_t) + (sizeof(upg_resource_node_t) * i);
|
|
|
|
if (dfx_file_read_fd(index_fd, offset, (uint8_t *)file_info, read_len, true) != (int32_t)read_len) {
|
|
ret = ERRCODE_UPG_FILE_READ_FAIL;
|
|
break;
|
|
}
|
|
|
|
if (is_index) {
|
|
ret = upg_resource_index_task(file_info);
|
|
} else {
|
|
ret = upg_resource_data_task(p, data, image, file_info);
|
|
}
|
|
if (ret != ERRCODE_SUCC) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
upg_free(file_info);
|
|
dfx_file_close(index_fd);
|
|
return ret;
|
|
}
|
|
|
|
errcode_t uapi_upg_resource_index_process(const upg_image_header_t *image)
|
|
{
|
|
errcode_t ret;
|
|
upg_msg1("resource index decompress_flag: ", image->decompress_flag);
|
|
if (image->decompress_flag == DECOMPRESS_FLAG_ZIP) {
|
|
/* 压缩升级 */
|
|
upg_msg0("decompress upg\r\n");
|
|
ret = uapi_upg_compress_image_update(image);
|
|
} else {
|
|
/* 全镜像升级 */
|
|
upg_msg0("full upg\r\n");
|
|
ret = uapi_upg_full_image_update(image);
|
|
}
|
|
|
|
if (ret != ERRCODE_SUCC) {
|
|
return ret;
|
|
}
|
|
|
|
return upg_resource_process_node(NULL, NULL, image, true);
|
|
}
|
|
|
|
errcode_t uapi_upg_resource_data_process(const upg_image_header_t *image)
|
|
{
|
|
errcode_t ret;
|
|
CLzmaDec p;
|
|
upg_lzma_decode2_data_t val_tmp = { 0 };
|
|
|
|
if (image->decompress_flag == DECOMPRESS_FLAG_ZIP) {
|
|
uint32_t read_offset = image->image_offset;
|
|
/* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */
|
|
uint8_t header[LZMA_PROPS_SIZE + 8]; /* 8: lzma解压算法固定长度 */
|
|
uint32_t read_len = (uint32_t)sizeof(header);
|
|
|
|
ret = upg_copy_pkg_image_data(image, 0, &read_len, header);
|
|
if (ret != ERRCODE_SUCC) {
|
|
return ret;
|
|
}
|
|
read_offset += read_len;
|
|
|
|
ret = upg_lzma_init(&p, &val_tmp, header, sizeof(header));
|
|
if (ret != ERRCODE_SUCC) {
|
|
return ret;
|
|
}
|
|
|
|
val_tmp.image_id = image->image_id;
|
|
val_tmp.in_offset = read_offset;
|
|
val_tmp.out_offset = 0;
|
|
val_tmp.compress_len = image->image_len - (uint32_t)sizeof(header);
|
|
} else {
|
|
val_tmp.in_offset = image->image_offset;
|
|
val_tmp.outbuf = upg_malloc(UPG_FLASH_PAGE_SIZE);
|
|
if (val_tmp.outbuf == NULL) {
|
|
return ERRCODE_MALLOC;
|
|
}
|
|
}
|
|
|
|
ret = upg_resource_process_node(&p, &val_tmp, image, false);
|
|
if (ret != ERRCODE_SUCC) {
|
|
upg_msg1("upg_resource_process_node fail ret = ", ret);
|
|
}
|
|
|
|
if (image->decompress_flag == DECOMPRESS_FLAG_ZIP) {
|
|
upg_lzma_deinit(&p, &val_tmp);
|
|
} else {
|
|
upg_free(val_tmp.outbuf);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
#endif /* (UPG_CFG_SUPPORT_RESOURCES_FILE == YES) */ |