• 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 "securec.h"
20 #include "common_def.h"
21 #include "upg_definitions.h"
22 #include "errcode.h"
23 #include "upg_lzmadec.h"
24 #include "upg_common.h"
25 #include "upg_common_porting.h"
26 #include "upg_alloc.h"
27 #include "upg_porting.h"
28 #include "upg_config.h"
29 #include "upg_debug.h"
30 #if (UPG_CFG_SUPPORT_RESOURCES_FILE == YES)
31 #include "dfx_file_operation.h"
32 
upg_resource_file_full(const upg_lzma_decode2_data_t * data,upg_resource_node_t * file_info)33 STATIC errcode_t upg_resource_file_full(const upg_lzma_decode2_data_t *data, upg_resource_node_t *file_info)
34 {
35     errcode_t ret = ERRCODE_SUCC;
36     uint32_t file_len = file_info->file_len;
37     uint32_t read_offset = data->in_offset + file_info->offset;
38     uint32_t file_offset = 0;
39 
40     int32_t write_fd = dfx_file_open_for_write((const char *)file_info->file_path);
41     if (write_fd < 0) {
42         return ERRCODE_UPG_FILE_OPEN_FAIL;
43     }
44 
45     while (file_len > 0) {
46         uint32_t tmp_len = file_len > UPG_FLASH_PAGE_SIZE ? UPG_FLASH_PAGE_SIZE : file_len;
47         (void)memset_s(data->buf.outbuf, UPG_FLASH_PAGE_SIZE, 0, UPG_FLASH_PAGE_SIZE);
48         ret = upg_read_fota_pkg_data(read_offset + file_offset, data->buf.outbuf, &tmp_len);
49         if (ret != ERRCODE_SUCC) {
50             break;
51         }
52 
53         if (dfx_file_write_fd(write_fd, file_offset, data->buf.outbuf, tmp_len) != (int32_t)tmp_len) {
54             ret = ERRCODE_UPG_FILE_WRITE_FAIL;
55             break;
56         }
57         file_len -= tmp_len;
58         file_offset += tmp_len;
59     }
60     upg_calculate_and_notify_process((uint32_t)file_offset);
61 
62     dfx_file_fsync(write_fd);
63     dfx_file_close(write_fd);
64     return ret;
65 }
66 
upg_resource_file_delete(const char * file_path)67 STATIC errcode_t upg_resource_file_delete(const char *file_path)
68 {
69     (void)dfx_file_delete(file_path);
70     return ERRCODE_SUCC;
71 }
72 
upg_resource_file_rmdir(const char * path)73 STATIC errcode_t upg_resource_file_rmdir(const char *path)
74 {
75     (void)dfx_file_rmdir(path);
76     return ERRCODE_SUCC;
77 }
78 
upg_resource_data_task(CLzmaDec * p,upg_lzma_decode2_data_t * data,const upg_image_header_t * image,upg_resource_node_t * file_info)79 STATIC errcode_t upg_resource_data_task(CLzmaDec *p, upg_lzma_decode2_data_t *data,
80                                         const upg_image_header_t *image, upg_resource_node_t *file_info)
81 {
82     if (file_info->operation_type != UPG_RESOURCE_ADD_FILE && file_info->operation_type != UPG_RESOURCE_AMEND_FILE) {
83         return ERRCODE_SUCC;
84     }
85 
86     if (file_info->file_len == 0) {
87         return ERRCODE_SUCC;
88     }
89 
90     if (image->decompress_flag == DECOMPRESS_FLAG_ZIP) {
91         upg_log_info("[UPG] decompress resource file\r\n");
92         return upg_resource_file_decode(p, data, file_info);
93     }
94 
95     upg_log_info("[UPG] full resource file\r\n");
96     return upg_resource_file_full(data, file_info);
97 }
98 
upg_resource_index_task(upg_resource_node_t * file_info)99 STATIC errcode_t upg_resource_index_task(upg_resource_node_t *file_info)
100 {
101     if (file_info->operation_type == UPG_RESOURCE_DELETE_FILE) {
102         upg_log_info("[UPG] delete resource file\r\n");
103         return upg_resource_file_delete(file_info->file_path);
104     } else if (file_info->operation_type == UPG_RESOURCE_REMOVE_DIR) {
105         upg_log_info("[UPG] remove resource dir\r\n");
106         return upg_resource_file_rmdir(file_info->file_path);
107     }
108 
109     return ERRCODE_SUCC;
110 }
111 
upg_resource_process_node(CLzmaDec * p,upg_lzma_decode2_data_t * data,const upg_image_header_t * image,bool is_index)112 STATIC errcode_t upg_resource_process_node(CLzmaDec *p, upg_lzma_decode2_data_t *data,
113                                            const upg_image_header_t *image, bool is_index)
114 {
115     errcode_t ret = ERRCODE_FAIL;
116     upg_resource_index_t resource_index = {0};
117     uint32_t read_len = sizeof(upg_resource_index_t);
118 
119     int32_t index_fd = dfx_file_open_for_read(upg_get_res_file_index_path());
120     if (index_fd < 0) {
121         return ERRCODE_UPG_FILE_OPEN_FAIL;
122     }
123 
124     if (dfx_file_read_fd(index_fd, 0, (uint8_t *)&resource_index, read_len, true) != (int32_t)read_len) {
125         dfx_file_close(index_fd);
126         return ERRCODE_UPG_FILE_READ_FAIL;
127     }
128 
129     upg_resource_node_t *file_info = (upg_resource_node_t *)upg_malloc(sizeof(upg_resource_node_t));
130     if (file_info == NULL) {
131         dfx_file_close(index_fd);
132         return ERRCODE_MALLOC;
133     }
134 
135     read_len = sizeof(upg_resource_node_t);
136     for (uint32_t i = 0; i < resource_index.file_num; i++) {
137         memset_s(file_info, sizeof(upg_resource_node_t), 0, sizeof(upg_resource_node_t));
138         uint32_t offset = sizeof(upg_resource_index_t) + (sizeof(upg_resource_node_t) * i);
139 
140         if (dfx_file_read_fd(index_fd, offset, (uint8_t *)file_info, read_len, true) != (int32_t)read_len) {
141             ret = ERRCODE_UPG_FILE_READ_FAIL;
142             break;
143         }
144 
145         if (is_index) {
146             ret = upg_resource_index_task(file_info);
147         } else {
148             ret = upg_resource_data_task(p, data, image, file_info);
149         }
150         if (ret != ERRCODE_SUCC) {
151             break;
152         }
153     }
154 
155     upg_free(file_info);
156     dfx_file_close(index_fd);
157     return ret;
158 }
159 
uapi_upg_resource_index_process(const upg_image_header_t * image)160 errcode_t uapi_upg_resource_index_process(const upg_image_header_t *image)
161 {
162     errcode_t ret;
163     upg_log_info("[UPG] resource index decompress_flag: 0x%x\r\n", image->decompress_flag);
164     if (image->decompress_flag == DECOMPRESS_FLAG_ZIP) {
165         /* 压缩升级 */
166         upg_log_info("[UPG] decompress upg\r\n");
167         ret = uapi_upg_compress_image_update(image);
168     } else {
169         /* 全镜像升级 */
170         upg_log_info("[UPG] full upg\r\n");
171         ret = uapi_upg_full_image_update(image);
172     }
173 
174     if (ret != ERRCODE_SUCC) {
175         return ret;
176     }
177 
178     return upg_resource_process_node(NULL, NULL, image, true);
179 }
180 
uapi_upg_resource_data_process(const upg_image_header_t * image)181 errcode_t uapi_upg_resource_data_process(const upg_image_header_t *image)
182 {
183     errcode_t ret;
184     CLzmaDec p;
185     upg_lzma_decode2_data_t val_tmp = { 0 };
186 
187     if (image->decompress_flag == DECOMPRESS_FLAG_ZIP) {
188         uint32_t read_offset = image->image_offset;
189         uint8_t header[LZMA_HEAD_ALIGN_SIZE]; /* lzma解压头长度 */
190         uint32_t read_len = (uint32_t)sizeof(header);
191 
192         ret = upg_copy_pkg_image_data(image, 0, &read_len, header);
193         if (ret != ERRCODE_SUCC) {
194             return ret;
195         }
196         read_offset += read_len;
197 
198         ret = upg_lzma_init(&p, &val_tmp, header, sizeof(header));
199         if (ret != ERRCODE_SUCC) {
200             return ret;
201         }
202 
203         val_tmp.image_id = image->image_id;
204         val_tmp.in_offset = read_offset;
205         val_tmp.out_offset = 0;
206         val_tmp.compress_len = image->image_len - (uint32_t)sizeof(header);
207     } else {
208         val_tmp.in_offset = image->image_offset;
209         val_tmp.buf.outbuf = upg_malloc(UPG_FLASH_PAGE_SIZE);
210         if (val_tmp.buf.outbuf == NULL) {
211             return ERRCODE_MALLOC;
212         }
213     }
214 
215     ret = upg_resource_process_node(&p, &val_tmp, image, false);
216     if (ret != ERRCODE_SUCC) {
217         upg_log_err("[UPG] upg_resource_process_node fail ret = 0x%x\r\n", ret);
218     }
219 
220     if (image->decompress_flag == DECOMPRESS_FLAG_ZIP) {
221         upg_lzma_deinit(&p, &val_tmp);
222     } else {
223         upg_free(val_tmp.buf.outbuf);
224     }
225 
226     return ret;
227 }
228 #endif /* (UPG_CFG_SUPPORT_RESOURCES_FILE == YES) */
229