• 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: UPG upgrade functions source file
15  */
16 
17 #include <stdint.h>
18 #include <stddef.h>
19 #include "common_def.h"
20 #include "upg_definitions.h"
21 #include "errcode.h"
22 #include "upg_lzmadec.h"
23 #include "upg_common.h"
24 #include "upg_common_porting.h"
25 #include "upg_alloc.h"
26 #include "partition.h"
27 #include "upg_porting.h"
28 #include "upg_patch.h"
29 #include "upg_config.h"
30 #include "upg_debug.h"
31 #include "securec.h"
32 #include "upg_encry.h"
33 
uapi_upg_lzma_ota_image(const upg_image_header_t * image,uint8_t * header,uint32_t head_len,uint32_t app_size,uint32_t read_offset)34 errcode_t uapi_upg_lzma_ota_image(const upg_image_header_t *image, uint8_t *header, uint32_t head_len,
35     uint32_t app_size, uint32_t read_offset)
36 {
37     errcode_t ret;
38     CLzmaDec p;
39     upg_lzma_decode2_data_t val_tmp = { 0 };
40 
41     ret = upg_lzma_init(&p, &val_tmp, header, head_len);
42     if (ret != ERRCODE_SUCC) {
43         return ret;
44     }
45 
46     val_tmp.image_id = image->image_id;
47     val_tmp.in_offset = read_offset;
48     val_tmp.out_offset = 0;
49     val_tmp.compress_len = image->image_len - head_len;
50 
51     if (app_size < val_tmp.decompress_len) {
52         upg_log_err("[UPG] app size is not enough! app_size = 0x%x, decompress_len = 0x%x\r\n",
53             app_size, val_tmp.decompress_len);
54         upg_lzma_deinit(&p, &val_tmp);
55         return ERRCODE_UPG_NO_ENOUGH_SPACE;
56     }
57 
58     ret = upg_lzma_decode(&p, &val_tmp, image);
59     if (ret != SZ_OK) {
60         upg_log_err("[UPG] upg_lzma_decode fail ret = 0x%x\r\n", ret);
61         ret = ERRCODE_UPG_DECOMPRESS_FAIL;
62     }
63     upg_lzma_deinit(&p, &val_tmp);
64     return ret;
65 }
66 
67 /* FOTA压缩升级 */
uapi_upg_compress_image_update(const upg_image_header_t * image)68 errcode_t uapi_upg_compress_image_update(const upg_image_header_t *image)
69 {
70     uint32_t read_offset = image->image_offset;
71     errcode_t ret;
72     uint8_t header[LZMA_HEAD_ALIGN_SIZE] = { 0 };
73     uint32_t read_len = (uint32_t)sizeof(header);
74     uint32_t app_address = 0;  /* 镜像所在分区 */
75     uint32_t app_size = 0;     /* 镜像大小 */
76 
77     /* 读压缩头 */
78     ret = upg_copy_pkg_image_data(image, 0, &read_len, header);
79     if (ret != ERRCODE_SUCC) {
80         return ret;
81     }
82 #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_COMPRESS_ENCRY
83     /* 初始化加解密配置 */
84     ret = upg_cryto_init(image);
85     if (ret != ERRCODE_SUCC) {
86         return ret;
87     }
88     /* 解密压缩头 */
89     ret = upg_decry_fota_pkt(header, read_len, image);
90     if (ret != ERRCODE_SUCC) {
91         goto destory;
92     }
93 #endif
94     read_offset += read_len;
95     ret = upg_get_partition_info(image->image_id, &app_address, &app_size);
96     if (ret != ERRCODE_SUCC) {
97         goto destory;
98     }
99 
100     ret = uapi_upg_lzma_ota_image(image, header, sizeof(header), app_size, read_offset);
101     if (ret != ERRCODE_SUCC) {
102         goto destory;
103     }
104 
105 destory:
106 #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_COMPRESS_ENCRY
107     upg_cryto_deinit(image);
108 #endif
109     return ret;
110 }
111 
112 /* FOTA差分升级 */
uapi_upg_diff_image_update(const upg_image_header_t * image)113 errcode_t uapi_upg_diff_image_update(const upg_image_header_t *image)
114 {
115 #if (UPG_CFG_DIFF_UPGRADE_SUPPORT == YES)
116     errcode_t ret = ERRCODE_SUCC;
117     ret = fota_pkg_task_apply_code_diff(image);
118 
119     return ret;
120 #else
121     unused(image);
122     return ERRCODE_UPG_NOT_SUPPORTED;
123 #endif
124 }
125 
126 /* FOTA全镜像升级 */
uapi_upg_full_image_update(const upg_image_header_t * image)127 errcode_t uapi_upg_full_image_update(const upg_image_header_t *image)
128 {
129     uint32_t read_offset = image->image_offset;
130     errcode_t ret;
131     uint32_t write_offset = 0;
132     uint32_t app_address = 0;
133     uint32_t app_size = 0;
134     errcode_t ret_val = upg_get_partition_info(image->image_id, &app_address, &app_size);
135     if (ret_val != ERRCODE_SUCC) {
136         return ret_val;
137     }
138 
139     if (app_size < image->image_len) {
140         return ERRCODE_FAIL;
141     }
142 
143     uint32_t read_len = 0;
144     uint32_t tmp_len = 0;
145 
146     uint8_t *buffer = upg_malloc(UPG_FLASH_PAGE_SIZE);
147     if (buffer == NULL) {
148         return ERRCODE_MALLOC;
149     }
150 
151     while (read_len < image->image_len) {
152         tmp_len = ((image->image_len - read_len) > UPG_FLASH_PAGE_SIZE) ?
153             UPG_FLASH_PAGE_SIZE : (image->image_len - read_len);
154         ret = upg_read_fota_pkg_data(read_offset + read_len, (uint8_t *)buffer, &tmp_len);
155         if (ret != ERRCODE_SUCC) {
156             upg_free(buffer);
157             return ret;
158         }
159 
160 #if defined(UPG_CFG_SUPPORT_ERASE_WHOLE_IMAGE) && defined(YES) && (UPG_CFG_SUPPORT_ERASE_WHOLE_IMAGE == YES)
161         ret = upg_write_new_image_data(write_offset + read_len, (uint8_t *)buffer, &tmp_len, image->image_id, false);
162 #else
163         ret = upg_write_new_image_data(write_offset + read_len, (uint8_t *)buffer, &tmp_len, image->image_id, true);
164 #endif
165         if (ret != ERRCODE_SUCC || tmp_len == 0) {
166             upg_free(buffer);
167             return ret;
168         }
169 
170         read_len += tmp_len;
171 
172         // 踢狗
173         upg_watchdog_kick();
174 
175         upg_calculate_and_notify_process(tmp_len);
176     }
177 
178     upg_free(buffer);
179     buffer = NULL;
180     return ERRCODE_SUCC;
181 }
182