1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# Copyright (c) 2021 Huawei Device Co., Ltd. 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16""" 17Description : Defining constants, common interface 18""" 19import argparse 20import json 21import os 22import shutil 23import tempfile 24from collections import OrderedDict 25import xmltodict 26import zipfile 27 28from cryptography.hazmat.primitives import hashes 29from log_exception import UPDATE_LOGGER 30from build_pkcs7 import sign_ota_package 31from copy import copy 32from ctypes import cdll 33 34operation_path = os.path.dirname(os.path.realpath(__file__)) 35PRODUCT = 'hi3516' 36BUILD_TOOLS_FILE_NAME = 'build_tools.zip' 37UPDATE_BIN_FILE_NAME = "update.bin" 38UPDATE_EXE_FILE_NAME = "updater_binary" 39 40SCRIPT_KEY_LIST = ['prelude', 'verse', 'refrain', 'ending'] 41TOTAL_SCRIPT_FILE_NAME = "loadScript.us" 42REGISTER_SCRIPT_FILE_NAME = "registerCmd.us" 43SCRIPT_FILE_NAME = '-script.us' 44 45UPDATER_CONFIG = "updater_config" 46XML_FILE_PATH = "updater_specified_config.xml" 47SO_PATH = os.path.join(operation_path, 'lib/libpackage.so') 48SO_PATH_L1 = os.path.join(operation_path, 'lib/libpackageL1.so') 49DIFF_EXE_PATH = os.path.join(operation_path, 'lib/diff') 50E2FSDROID_PATH = os.path.join(operation_path, 'lib/e2fsdroid') 51MISC_INFO_PATH = "misc_info.txt" 52VERSION_MBN_PATH = "VERSION.mbn" 53BOARD_LIST_PATH = "BOARD.list" 54EXTEND_COMPONENT_LIST = ["version_list", "board_list"] 55EXTEND_OPTIONAL_COMPONENT_LIST = ["partitions_file"] 56PARTITION_FILE = "partitions_file" 57IGNORED_PARTITION_LIST = ['fastboot', 'boot', 'kernel', 'misc', 58 'updater', 'userdata'] 59 60HASH_ALGORITHM_DICT = {'sha256': hashes.SHA256, 'sha384': hashes.SHA384} 61LINUX_HASH_ALGORITHM_DICT = {'sha256': 'sha256sum', 'sha384': 'sha384sum'} 62HASH_CONTENT_LEN_DICT = {'sha256': 64, 'sha384': 96} 63 64COMPONENT_INFO_INNIT = ['', '000', '00', '0', '0o00'] 65 66ON_SERVER = "ON_SERVER" 67 68EXTEND_VALUE = 512 69 70FILE_MAP_ZERO_KEY = "__ZERO" 71FILE_MAP_NONZERO_KEY = "__NONZERO" 72FILE_MAP_COPY_KEY = "__COPY" 73 74MAX_BLOCKS_PER_GROUP = BLOCK_LIMIT = 1024 75PER_BLOCK_SIZE = 4096 76 77VERSE_SCRIPT_EVENT = 0 78INC_IMAGE_EVENT = 1 79SIGN_PACKAGE_EVENT = 2 80CHECK_BINARY_EVENT = 3 81CONFIG_EVENT = 4 82EXTEND_PATH_EVENT = 5 83ZIP_EVENT = 6 84GENERATE_SIGNED_DATA_EVENT = 7 # sign build tools files to get hash_signed_data 85PARTITION_CHANGE_EVENT = 8 86DECOUPLED_EVENT = 9 87 88# Image file can not support update. 89FORBIDEN_UPDATE_IMAGE_SET = {"ptable"} 90 91# 1000000: max number of function recursion depth 92MAXIMUM_RECURSION_DEPTH = 1000000 93 94 95def singleton(cls): 96 _instance = {} 97 98 def _singleton(*args, **kargs): 99 if cls not in _instance: 100 _instance[cls] = cls(*args, **kargs) 101 return _instance[cls] 102 103 return _singleton 104 105 106class ExtInit: 107 """ 108 Init event for ext 109 """ 110 111 def __init__(self): 112 self.funs = [] 113 114 def reg_event(self, evevt_id, funs): 115 self.funs.append([evevt_id, funs]) 116 UPDATE_LOGGER.print_log( 117 'register event %s: %s' % (evevt_id, funs.__name__)) 118 119 def invoke_event(self, evevt_id): 120 UPDATE_LOGGER.print_log(self.funs) 121 for event in self.funs: 122 funs = event[1] 123 if event[0] == evevt_id and funs is not None: 124 UPDATE_LOGGER.print_log( 125 'invoke event %s: %s' % (evevt_id, funs.__name__)) 126 return funs 127 return False 128 129 130class BaseOptionsManager: 131 def __init__(self): 132 # Entry parameters 133 self.source_package = None 134 self.target_package = None 135 self.update_package = None 136 self.unpack_package_path = None 137 self.no_zip = False 138 self.partition_file = None 139 self.signing_algorithm = None 140 self.hash_algorithm = None 141 self.private_key = None 142 self.not_l2 = False 143 self.signing_length = 256 144 self.xml_path = None 145 self.sd_card = False 146 self.stream_update = False 147 self.chunk_limit = 11 # chunk size 11 * 4096 = 44KB 148 self.ab_partition_update = False 149 150 self.make_dir_path = None 151 152 153@singleton 154class OptionsManager(BaseOptionsManager): 155 """ 156 Options management class 157 """ 158 159 def __init__(self): 160 super().__init__() 161 162 self.init = ExtInit() 163 self.parser = argparse.ArgumentParser() 164 165 # Own parameters 166 self.product = None 167 168 169 # Parsed package parameters 170 self.target_package_dir = None 171 self.target_package_config_dir = None 172 self.target_package_temp_obj = None 173 self.misc_info_dict = {} 174 self.version_mbn_file_path = None 175 self.version_mbn_content = None 176 self.board_list_file_path = None 177 self.board_list_content = None 178 179 self.source_package_dir = None 180 self.source_package_temp_obj = None 181 182 # XML parsing parameters 183 self.head_info_list = [] 184 self.component_info_dict = {} 185 self.full_img_list = [] 186 self.full_img_name_list = [] 187 self.incremental_img_list = [] 188 self.incremental_img_name_list = [] 189 self.target_package_version = None 190 self.source_package_version = None 191 self.full_image_path_list = [] 192 193 self.partition_file_obj = None 194 195 # Full processing parameters 196 self.full_image_content_len_list = [] 197 self.full_image_file_obj_list = [] 198 # 全量流式升级 199 self.full_image_new_data = {} 200 self.full_chunk = {} 201 self.full_block_sets = {} 202 # 存放所有chunk 203 self.full_image_chunk_list = [] 204 205 # Incremental processing parameters 206 self.incremental_content_len_list = [] 207 self.incremental_image_file_obj_dict = {} 208 self.incremental_block_file_obj_dict = {} 209 self.incremental_temp_file_obj_list = [] 210 self.max_stash_size = 0 211 212 # 差分流式升级 213 # 定义一个transfer_list来存放image.transfer.list内容 214 self.image_transfer_dict_contents = {} 215 self.image_patch_dic = {} 216 self.image_new_dic = {} 217 self.diff_image_new_data = {} 218 # 差分流式本地升级 219 self.zip_offset = 0 220 221 # 存放镜像所有数据,以blcok为单位 222 self.all_blocks_data = {} 223 self.len_block = 0 224 225 # no map 文件 226 self.image_chunk = {} 227 self.image_block_sets = {} 228 self.no_map_file_list = [] 229 self.no_map_image_exist = False 230 231 # Script parameters 232 self.opera_script_file_name_dict = {} 233 for each in SCRIPT_KEY_LIST: 234 self.opera_script_file_name_dict[each] = [] 235 self.total_script_file_obj = None 236 237 self.register_script_file_obj = None 238 239 # Update package parameters 240 self.update_bin_obj = None 241 self.build_tools_zip_obj = None 242 self.update_package_file_path = None 243 self.signed_package = None 244 245OPTIONS_MANAGER = OptionsManager() 246 247 248def unzip_package(package_path, origin='target'): 249 """ 250 Decompress the zip package. 251 :param package_path: zip package path 252 :param origin: package origin, which indicates 253 whether the zip package is a source package or target package 254 :return: Temporary directory (tmp_dir) and zip_data package; 255 false if an exception occurs. 256 """ 257 try: 258 tmp_dir_obj = tempfile.TemporaryDirectory(prefix="%sfiles-" % origin) 259 tmp_dir = tmp_dir_obj.name 260 261 zf_obj = zipfile.ZipFile(package_path) 262 for name in zf_obj.namelist(): 263 if name.endswith('/'): 264 os.mkdir(os.path.join(tmp_dir, name)) 265 else: 266 ext_filename = os.path.join( 267 tmp_dir, name) 268 fd = os.open(ext_filename, os.O_RDWR | os.O_CREAT, 0o755) 269 with os.fdopen(fd, "wb") as f_w: 270 f_w.write(zf_obj.read(name)) 271 except OSError: 272 UPDATE_LOGGER.print_log( 273 "Unzip package failed! path: %s" % package_path, 274 log_type=UPDATE_LOGGER.ERROR_LOG) 275 return False, False 276 tmp_dir_list = os.listdir(tmp_dir) 277 if len(tmp_dir_list) == 1: 278 unzip_dir = os.path.join(tmp_dir, tmp_dir_list[0]) 279 if UPDATER_CONFIG not in \ 280 os.listdir(unzip_dir): 281 UPDATE_LOGGER.print_log( 282 'Unsupported zip package structure!', UPDATE_LOGGER.ERROR_LOG) 283 return False, False 284 elif UPDATER_CONFIG in tmp_dir_list: 285 unzip_dir = tmp_dir 286 else: 287 UPDATE_LOGGER.print_log( 288 'Unsupported zip package structure!', UPDATE_LOGGER.ERROR_LOG) 289 return False, False 290 UPDATE_LOGGER.print_log( 291 '%s package unzip complete! path: %s' % (origin.title(), unzip_dir)) 292 293 return tmp_dir_obj, unzip_dir 294 295 296def split_img_name(image_path): 297 """ 298 Split the image name by image path 299 :return image name 300 """ 301 tmp_path = image_path 302 str_list = tmp_path.split("/") 303 304 return str_list[-1] 305 306 307def get_update_config_softversion(mbn_dir, head_info_dict): 308 soft_version_file = head_info_dict.get('softVersionFile') 309 if soft_version_file is not None: 310 mbn_path = os.path.join(mbn_dir, soft_version_file) 311 if os.path.exists(mbn_path): 312 with open(mbn_path, 'r') as mbn_file: 313 head_info_dict['info']["@softVersion"] = mbn_file.read() 314 315 316def parse_update_config(xml_path): 317 """ 318 Parse the XML configuration file. 319 :param xml_path: XML configuration file path 320 :return head_info_dict: header information dict of the update package 321 component_info_dict: component information dict 322 full_img_list: full image list 323 incremental_img_list: incremental image list 324 """ 325 if os.path.exists(xml_path): 326 with open(xml_path, 'r') as xml_file: 327 xml_str = xml_file.read() 328 else: 329 UPDATE_LOGGER.print_log("XML file does not exist! xml path: %s" % xml_path, UPDATE_LOGGER.ERROR_LOG) 330 ret_params = [False, False, False, False, False, False, False] 331 return ret_params 332 xml_content_dict = xmltodict.parse(xml_str, encoding='utf-8') 333 package_dict = xml_content_dict.get('package', {}) 334 get_update_config_softversion(OPTIONS_MANAGER.target_package_dir, package_dict.get('head', {})) 335 head_dict = package_dict.get('head', {}).get('info') 336 package_version = head_dict.get("@softVersion") 337 # component 338 component_info = package_dict.get('group', {}).get('component') 339 head_list = list(head_dict.values()) 340 head_list.pop() 341 whole_list = [] 342 difference_list = [] 343 comp_dict = {} 344 full_image_path_list = [] 345 346 if not OPTIONS_MANAGER.not_l2: 347 expand_component(comp_dict) 348 if isinstance(component_info, OrderedDict) or isinstance(component_info, dict): 349 component_info = [component_info] 350 if component_info is None: 351 ret_params = [[], {}, [], [], '', [], False] 352 return ret_params 353 for component in component_info: 354 if component['@compAddr'] == 'userdata' and not OPTIONS_MANAGER.sd_card: 355 continue 356 component_list = list(component.values()) 357 component_list.pop() 358 comp_dict[component['@compAddr']] = component_list 359 360 if component['@compAddr'] in (whole_list + difference_list): 361 UPDATE_LOGGER.print_log("This component %s repeats!" % component['@compAddr'], UPDATE_LOGGER.ERROR_LOG) 362 ret_params = [False, False, False, False, False, False, False] 363 return ret_params 364 365 if component['@compType'] == '0': 366 whole_list.append(component['@compAddr']) 367 OPTIONS_MANAGER.full_img_name_list.append(split_img_name(component['#text'])) 368 tem_path = os.path.join(OPTIONS_MANAGER.target_package_dir, component.get("#text", None)) 369 full_image_path_list.append(tem_path) 370 comp_dict[component['@compAddr']] = component_list 371 elif component['@compType'] == '1': 372 difference_list.append(component['@compAddr']) 373 OPTIONS_MANAGER.incremental_img_name_list.append(split_img_name(component['#text'])) 374 375 ret_params = [head_list, comp_dict, whole_list, difference_list, package_version, full_image_path_list] 376 return ret_params 377 378 379def partitions_conversion(data): 380 """ 381 Convert the start or length data in the partition table through 382 multiply 1024 * 1024 and return the data. 383 :param data: start or length data 384 :return : 385 """ 386 if data == '0': 387 return 0 388 elif data.endswith('M'): 389 return int(data[0:-1]) * 1024 * 1024 // 512 390 else: 391 return False 392 393 394def parse_partition_file_xml(xml_path): 395 """ 396 Parse the XML configuration file. 397 :param xml_path: XML configuration file path 398 :return part_json: partition table information in JSON format 399 """ 400 if os.path.exists(xml_path): 401 with open(xml_path, 'r') as xml_file: 402 xml_str = xml_file.read() 403 else: 404 UPDATE_LOGGER.print_log("XML file does not exist! xml path: %s" % 405 xml_path, UPDATE_LOGGER.ERROR_LOG) 406 return False, False, False 407 partitions_list = [] 408 partitions_file_path_list = [] 409 xml_content_dict = xmltodict.parse(xml_str, encoding='utf-8') 410 part_list = xml_content_dict['Partition_Info']['Part'] 411 new_part_list = [] 412 for i, part in enumerate(part_list): 413 start_value = partitions_conversion(part.get('@Start')) 414 length_value = partitions_conversion(part.get('@Length')) 415 if start_value is False or length_value is False: 416 UPDATE_LOGGER.print_log( 417 "Partition file parsing failed! part_name: %s, xml_path: %s" % 418 (part.get('@PartitionName'), xml_path), 419 UPDATE_LOGGER.ERROR_LOG) 420 return False, False, False 421 422 if part.get('@PartitionName') not in IGNORED_PARTITION_LIST: 423 partitions_list.append(part.get('@PartitionName')) 424 partitions_file_path_list.append( 425 os.path.join(OPTIONS_MANAGER.target_package_dir, 426 "%s.img" % part.get('@PartitionName'))) 427 part_dict = {'start': start_value, 428 'length': length_value, 429 'partName': part.get('@PartitionName'), 430 'fsType': part.get('@FlashType')} 431 new_part_list.append(part_dict) 432 part_json = json.dumps(new_part_list) 433 part_json = '{"Partition": %s}' % part_json 434 file_obj = tempfile.NamedTemporaryFile( 435 dir=OPTIONS_MANAGER.target_package_dir, prefix="partition_file-", mode='wb') 436 file_obj.write(part_json.encode()) 437 file_obj.seek(0) 438 return file_obj, partitions_list, partitions_file_path_list 439 440 441def get_extend_path_list(): 442 get_config_list = OPTIONS_MANAGER.init.invoke_event(CONFIG_EVENT) 443 if get_config_list: 444 return get_config_list() 445 else: 446 return EXTEND_COMPONENT_LIST 447 448 449def expand_component(component_dict): 450 """ 451 Append components such as VERSION.mbn and board list. 452 :param component_dict: component information dict 453 :return: 454 """ 455 extend_path_list = get_extend_path_list() 456 if OPTIONS_MANAGER.partition_file is not None: 457 extend_component_list = \ 458 extend_path_list + EXTEND_OPTIONAL_COMPONENT_LIST 459 else: 460 extend_component_list = extend_path_list 461 for each in extend_component_list: 462 tmp_info_list = copy(COMPONENT_INFO_INNIT) 463 tmp_info_list[0] = each 464 component_dict[each] = tmp_info_list 465 466 467def clear_options(): 468 """ 469 Clear OPTIONS_MANAGER. 470 """ 471 OPTIONS_MANAGER.product = None 472 473 # Entry parameters 474 OPTIONS_MANAGER.source_package = None 475 OPTIONS_MANAGER.target_package = None 476 OPTIONS_MANAGER.update_package = None 477 OPTIONS_MANAGER.no_zip = False 478 OPTIONS_MANAGER.partition_file = None 479 OPTIONS_MANAGER.signing_algorithm = None 480 OPTIONS_MANAGER.hash_algorithm = None 481 OPTIONS_MANAGER.private_key = None 482 OPTIONS_MANAGER.not_l2 = False 483 OPTIONS_MANAGER.signing_length = 256 484 OPTIONS_MANAGER.xml_path = None 485 OPTIONS_MANAGER.sd_card = False 486 487 OPTIONS_MANAGER.stream_update = False 488 OPTIONS_MANAGER.chunk_limit = 11 489 490 OPTIONS_MANAGER.full_image_path_list = [] 491 492 OPTIONS_MANAGER.make_dir_path = None 493 494 # Parsed package parameters 495 OPTIONS_MANAGER.target_package_dir = None 496 OPTIONS_MANAGER.target_package_config_dir = None 497 OPTIONS_MANAGER.target_package_temp_obj = None 498 OPTIONS_MANAGER.misc_info_dict = {} 499 OPTIONS_MANAGER.version_mbn_file_path = None 500 OPTIONS_MANAGER.version_mbn_content = None 501 OPTIONS_MANAGER.board_list_file_path = None 502 OPTIONS_MANAGER.board_list_content = None 503 504 OPTIONS_MANAGER.source_package_dir = None 505 OPTIONS_MANAGER.source_package_temp_obj = None 506 507 # XML parsing parameters 508 OPTIONS_MANAGER.head_info_list = [] 509 OPTIONS_MANAGER.component_info_dict = {} 510 OPTIONS_MANAGER.full_img_list = [] 511 OPTIONS_MANAGER.incremental_img_list = [] 512 OPTIONS_MANAGER.target_package_version = None 513 OPTIONS_MANAGER.source_package_version = None 514 OPTIONS_MANAGER.partition_file_obj = None 515 516 # Global processing parameters 517 OPTIONS_MANAGER.full_image_content_len_list = [] 518 OPTIONS_MANAGER.full_image_file_obj_list = [] 519 520 # Incremental processing parameters 521 OPTIONS_MANAGER.incremental_content_len_list = [] 522 OPTIONS_MANAGER.incremental_temp_file_obj_list = [] 523 524 # Script parameters 525 OPTIONS_MANAGER.opera_script_file_name_dict = {} 526 for each in SCRIPT_KEY_LIST: 527 OPTIONS_MANAGER.opera_script_file_name_dict[each] = [] 528 OPTIONS_MANAGER.total_script_file_obj = None 529 530 OPTIONS_MANAGER.register_script_file_obj = None 531 532 # Update package parameters 533 OPTIONS_MANAGER.update_bin_obj = None 534 OPTIONS_MANAGER.build_tools_zip_obj = None 535 OPTIONS_MANAGER.update_package_file_path = None 536 537 538def clear_resource(err_clear=False): 539 """ 540 Clear resources, close temporary files, and clear temporary paths. 541 :param err_clear: whether to clear errors 542 :return: 543 """ 544 target_package_temp_obj = OPTIONS_MANAGER.target_package_temp_obj 545 if target_package_temp_obj is not None: 546 target_package_temp_obj.cleanup() 547 source_package_temp_obj = OPTIONS_MANAGER.source_package_temp_obj 548 if source_package_temp_obj is not None: 549 source_package_temp_obj.cleanup() 550 551 partition_file_obj = OPTIONS_MANAGER.partition_file_obj 552 if partition_file_obj is not None: 553 partition_file_obj.close() 554 555 build_tools_zip_obj = OPTIONS_MANAGER.build_tools_zip_obj 556 if build_tools_zip_obj is not None: 557 build_tools_zip_obj.close() 558 update_bin_obj = OPTIONS_MANAGER.update_bin_obj 559 if update_bin_obj is not None: 560 update_bin_obj.close() 561 total_script_file_obj = OPTIONS_MANAGER.total_script_file_obj 562 if total_script_file_obj is not None: 563 total_script_file_obj.close() 564 565 register_script_file_obj = OPTIONS_MANAGER.register_script_file_obj 566 if register_script_file_obj is not None: 567 register_script_file_obj.close() 568 569 full_image_file_obj_list = OPTIONS_MANAGER.full_image_file_obj_list 570 if len(full_image_file_obj_list) != 0: 571 for each_full_obj in full_image_file_obj_list: 572 each_full_obj.close() 573 574 clear_file_obj(err_clear) 575 clear_options() 576 577 578def clear_file_obj(err_clear): 579 """ 580 Clear resources and temporary file objects. 581 :param err_clear: whether to clear errors 582 :return: 583 """ 584 incremental_temp_file_obj_list = \ 585 OPTIONS_MANAGER.incremental_temp_file_obj_list 586 if len(incremental_temp_file_obj_list) != 0: 587 for each_incremental_temp_obj in incremental_temp_file_obj_list: 588 if each_incremental_temp_obj is not None: 589 each_incremental_temp_obj.close() 590 opera_script_file_name_dict = OPTIONS_MANAGER.opera_script_file_name_dict 591 for each_value in opera_script_file_name_dict.values(): 592 for each in each_value: 593 each[1].close() 594 if err_clear: 595 make_dir_path = OPTIONS_MANAGER.make_dir_path 596 if make_dir_path is not None and os.path.exists(make_dir_path): 597 shutil.rmtree(make_dir_path) 598 update_package_file_path = OPTIONS_MANAGER.update_package_file_path 599 if update_package_file_path is not None and \ 600 os.path.exists(update_package_file_path): 601 os.remove(update_package_file_path) 602 UPDATE_LOGGER.print_log( 603 'Exception occurred, Resource cleaning completed!') 604 else: 605 UPDATE_LOGGER.print_log('Resource cleaning completed!') 606 607 608def get_file_content(file_path, file_name=None): 609 """ 610 Read the file content. 611 :param file_path: file path 612 :param file_name: file name 613 :return: file content 614 """ 615 if not os.path.exists(file_path): 616 UPDATE_LOGGER.print_log( 617 "%s is not exist! path: %s" % (file_name, file_path), 618 log_type=UPDATE_LOGGER.ERROR_LOG) 619 return False 620 with open(file_path, 'r') as r_f: 621 file_content = r_f.read() 622 UPDATE_LOGGER.print_log( 623 "%s file parsing complete! path: %s" % (file_name, file_path)) 624 return file_content 625 626 627def get_update_info(): 628 """ 629 Parse the configuration file to obtain the update information. 630 :return: update information if any; false otherwise. 631 """ 632 if not OPTIONS_MANAGER.not_l2: 633 decouple_res = OPTIONS_MANAGER.init.invoke_event(DECOUPLED_EVENT) 634 OPTIONS_MANAGER.version_mbn_file_path = os.path.join( 635 OPTIONS_MANAGER.target_package_config_dir, VERSION_MBN_PATH) 636 version_mbn_content = \ 637 get_file_content( 638 OPTIONS_MANAGER.version_mbn_file_path, os.path.basename( 639 os.path.join(OPTIONS_MANAGER.target_package_config_dir, 640 VERSION_MBN_PATH))) 641 if version_mbn_content is False and decouple_res is False: 642 UPDATE_LOGGER.print_log( 643 "Get version mbn content failed!", 644 log_type=UPDATE_LOGGER.ERROR_LOG) 645 return False 646 OPTIONS_MANAGER.version_mbn_content = version_mbn_content 647 OPTIONS_MANAGER.board_list_file_path = os.path.join( 648 OPTIONS_MANAGER.target_package_config_dir, BOARD_LIST_PATH) 649 board_list_content = \ 650 get_file_content( 651 OPTIONS_MANAGER.board_list_file_path, os.path.basename( 652 os.path.join(OPTIONS_MANAGER.target_package_config_dir, 653 BOARD_LIST_PATH))) 654 if board_list_content is False: 655 UPDATE_LOGGER.print_log("Get board list content failed!", log_type=UPDATE_LOGGER.ERROR_LOG) 656 return False 657 OPTIONS_MANAGER.board_list_content = board_list_content 658 659 if OPTIONS_MANAGER.xml_path is None: 660 xml_file_path = os.path.join( 661 OPTIONS_MANAGER.target_package_config_dir, XML_FILE_PATH) 662 else: 663 xml_file_path = OPTIONS_MANAGER.xml_path 664 665 # Parse the XML configuration file. 666 head_info_list, component_info_dict, \ 667 full_img_list, incremental_img_list, \ 668 OPTIONS_MANAGER.target_package_version, \ 669 OPTIONS_MANAGER.full_image_path_list = \ 670 parse_update_config(xml_file_path) 671 UPDATE_LOGGER.print_log("XML file parsing completed!") 672 if head_info_list is False or component_info_dict is False or \ 673 full_img_list is False or incremental_img_list is False: 674 UPDATE_LOGGER.print_log("Get parse update config xml failed!", log_type=UPDATE_LOGGER.ERROR_LOG) 675 return False 676 OPTIONS_MANAGER.head_info_list, OPTIONS_MANAGER.component_info_dict, \ 677 OPTIONS_MANAGER.full_img_list, OPTIONS_MANAGER.incremental_img_list = \ 678 head_info_list, component_info_dict, \ 679 full_img_list, incremental_img_list 680 return True 681 682 683def sign_package(): 684 return sign_ota_package( 685 OPTIONS_MANAGER.update_package_file_path, 686 OPTIONS_MANAGER.signed_package, 687 OPTIONS_MANAGER.private_key)