def generate_package(self, filename, preserve_work_directory=False): """ Generates a Nordic DFU package. The package is a zip file containing firmware(s) and metadata required for Nordic DFU applications to perform DFU onn nRF5X devices. :param str filename: Filename for generated package. :param bool preserve_work_directory: True to preserve the temporary working directory. Useful for debugging of a package, and if the user wants to look at the generated package without having to unzip it. :return: None """ work_directory = self.__create_temp_workspace() if Package._is_bootloader_softdevice_combination(self.firmwares_data): # Removing softdevice and bootloader data from dictionary and adding the combined later softdevice_fw_data = self.firmwares_data.pop(HexType.SOFTDEVICE) bootloader_fw_data = self.firmwares_data.pop(HexType.BOOTLOADER) softdevice_fw_name = softdevice_fw_data[ FirmwareKeys.FIRMWARE_FILENAME] bootloader_fw_name = bootloader_fw_data[ FirmwareKeys.FIRMWARE_FILENAME] new_filename = "sd_bl.bin" sd_bl_file_path = os.path.join(work_directory, new_filename) nrf_hex = nRFHex(softdevice_fw_name, bootloader_fw_name) nrf_hex.tobinfile(sd_bl_file_path) softdevice_size = nrf_hex.size() bootloader_size = nrf_hex.bootloadersize() self.__add_firmware_info( HexType.SD_BL, sd_bl_file_path, softdevice_fw_data[FirmwareKeys.INIT_PACKET_DATA], softdevice_size, bootloader_size) for key, firmware_data in self.firmwares_data.iteritems(): # Normalize the firmware file and store it in the work directory firmware_data[FirmwareKeys.BIN_FILENAME] = \ Package.normalize_firmware_to_bin(work_directory, firmware_data[FirmwareKeys.FIRMWARE_FILENAME]) # Calculate the hash for the .bin file located in the work directory bin_file_path = os.path.join( work_directory, firmware_data[FirmwareKeys.BIN_FILENAME]) firmware_hash = Package.calculate_sha256_hash(bin_file_path) bin_length = int(Package.calculate_file_size(bin_file_path)) sd_size = 0 bl_size = 0 app_size = 0 if key == HexType.APPLICATION: app_size = bin_length elif key == HexType.SOFTDEVICE: sd_size = bin_length elif key == HexType.BOOTLOADER: bl_size = bin_length elif key == HexType.SD_BL: bl_size = firmware_data[FirmwareKeys.BL_SIZE] sd_size = firmware_data[FirmwareKeys.SD_SIZE] init_packet = InitPacketPB( hash_bytes=firmware_hash, dfu_type=HexTypeToInitPacketFwTypemap[key], hash_type=HashTypes.SHA256, app_size=app_size, sd_size=sd_size, bl_size=bl_size, fw_version=firmware_data[FirmwareKeys.INIT_PACKET_DATA][ PacketField.APP_VERSION], hw_version=firmware_data[FirmwareKeys.INIT_PACKET_DATA][ PacketField.DEVICE_REVISION], sd_req=firmware_data[FirmwareKeys.INIT_PACKET_DATA][ PacketField.REQUIRED_SOFTDEVICES_ARRAY]) signer = Signing() signer.load_key(self.key_file) signature = signer.sign(init_packet.get_init_command_bytes()) init_packet.set_signature(signature, SigningTypes.ECDSA_P256_SHA256) # Store the .dat file in the work directory init_packet_filename = firmware_data[ FirmwareKeys.BIN_FILENAME].replace(".bin", ".dat") with open(os.path.join(work_directory, init_packet_filename), 'wb') as init_packet_file: init_packet_file.write(init_packet.get_init_packet_pb_bytes()) firmware_data[FirmwareKeys.DAT_FILENAME] = \ init_packet_filename # Store the manifest to manifest.json manifest = self.create_manifest() with open(os.path.join(work_directory, Package.MANIFEST_FILENAME), "w") as manifest_file: manifest_file.write(manifest) # Package the work_directory to a zip file Package.create_zip_package(work_directory, filename) # Delete the temporary directory if not preserve_work_directory: shutil.rmtree(work_directory)
def generate_package(self, filename, preserve_work_dir=False): """ Generates a Nordic DFU package. The package is a zip file containing firmware(s) and metadata required for Nordic DFU applications to perform DFU onn nRF5X devices. :param str filename: Filename for generated package. :param bool preserve_work_dir: True to preserve the temporary working directory. Useful for debugging of a package, and if the user wants to look at the generated package without having to unzip it. :return: None """ self.zip_file = filename self.work_dir = self.__create_temp_workspace() if Package._is_bootloader_softdevice_combination(self.firmwares_data): # Removing softdevice and bootloader data from dictionary and adding the combined later softdevice_fw_data = self.firmwares_data.pop(HexType.SOFTDEVICE) bootloader_fw_data = self.firmwares_data.pop(HexType.BOOTLOADER) softdevice_fw_name = softdevice_fw_data[FirmwareKeys.FIRMWARE_FILENAME] bootloader_fw_name = bootloader_fw_data[FirmwareKeys.FIRMWARE_FILENAME] new_filename = "sd_bl.bin" sd_bl_file_path = os.path.join(self.work_dir, new_filename) nrf_hex = nRFHex(softdevice_fw_name, bootloader=bootloader_fw_name) nrf_hex.tobinfile(sd_bl_file_path) softdevice_size = nrf_hex.size() bootloader_size = nrf_hex.bootloadersize() self.__add_firmware_info(firmware_type=HexType.SD_BL, firmware_version=bootloader_fw_data[FirmwareKeys.INIT_PACKET_DATA][PacketField.FW_VERSION], # use bootloader version in combination with SD filename=sd_bl_file_path, init_packet_data=softdevice_fw_data[FirmwareKeys.INIT_PACKET_DATA], sd_size=softdevice_size, bl_size=bootloader_size) elif Package._is_application_softdevice_combination(self.firmwares_data): # Removing softdevice and bootloader data from dictionary and adding the combined later softdevice_fw_data = self.firmwares_data.pop(HexType.SOFTDEVICE) application_fw_data = self.firmwares_data.pop(HexType.APPLICATION) softdevice_fw_name = softdevice_fw_data[FirmwareKeys.FIRMWARE_FILENAME] application_fw_name = application_fw_data[FirmwareKeys.FIRMWARE_FILENAME] application_address = application_fw_data[FirmwareKeys.APP_ADDR] new_filename = "sd_app.bin" sd_app_file_path = os.path.join(self.work_dir, new_filename) nrf_hex = nRFHex(softdevice_fw_name, application=application_fw_name) nrf_hex.tobinfile(sd_app_file_path) softdevice_size = nrf_hex.size() application_size = nrf_hex.applicationsize() self.__add_firmware_info(firmware_type=HexType.SD_APP, firmware_version=application_fw_data[FirmwareKeys.INIT_PACKET_DATA][PacketField.FW_VERSION], # use application version in combination with SD filename=sd_app_file_path, init_packet_data=softdevice_fw_data[FirmwareKeys.INIT_PACKET_DATA], sd_size=softdevice_size, app_size=application_size, app_addr=application_address) for key, firmware_data in self.firmwares_data.iteritems(): # Normalize the firmware file and store it in the work directory firmware_data[FirmwareKeys.BIN_FILENAME] = \ Package.normalize_firmware_to_bin(self.work_dir, firmware_data[FirmwareKeys.FIRMWARE_FILENAME]) # Calculate the hash for the .bin file located in the work directory bin_file_path = os.path.join(self.work_dir, firmware_data[FirmwareKeys.BIN_FILENAME]) firmware_hash = Package.calculate_sha256_hash(bin_file_path) bin_length = int(Package.calculate_file_size(bin_file_path)) sd_size = 0 bl_size = 0 app_size = 0 app_addr = 0 if key == HexType.APPLICATION: app_size = bin_length elif key == HexType.SOFTDEVICE: sd_size = bin_length elif key == HexType.BOOTLOADER: bl_size = bin_length elif key == HexType.SD_BL: bl_size = firmware_data[FirmwareKeys.BL_SIZE] sd_size = firmware_data[FirmwareKeys.SD_SIZE] elif key == HexType.SD_APP: app_size = firmware_data[FirmwareKeys.APP_SIZE] sd_size = firmware_data[FirmwareKeys.SD_SIZE] app_addr = firmware_data[FirmwareKeys.APP_ADDR] init_packet = InitPacketPB( from_bytes=None, hash_bytes=firmware_hash, hash_type=HashTypes.SHA256, dfu_type=HexTypeToInitPacketFwTypemap[key], is_debug=firmware_data[FirmwareKeys.INIT_PACKET_DATA][PacketField.DEBUG_MODE], fw_version=firmware_data[FirmwareKeys.INIT_PACKET_DATA][PacketField.FW_VERSION], hw_version=firmware_data[FirmwareKeys.INIT_PACKET_DATA][PacketField.HW_VERSION], sd_size=sd_size, app_size=app_size, app_addr=app_addr, bl_size=bl_size, sd_req=firmware_data[FirmwareKeys.INIT_PACKET_DATA][PacketField.REQUIRED_SOFTDEVICES_ARRAY]) signer = Signing() signer.load_key(self.key_file) signature = signer.sign(init_packet.get_init_command_bytes()) init_packet.set_signature(signature, SigningTypes.ECDSA_P256_SHA256) # Store the .dat file in the work directory init_packet_filename = firmware_data[FirmwareKeys.BIN_FILENAME].replace(".bin", ".dat") with open(os.path.join(self.work_dir, init_packet_filename), 'wb') as init_packet_file: init_packet_file.write(init_packet.get_init_packet_pb_bytes()) firmware_data[FirmwareKeys.DAT_FILENAME] = \ init_packet_filename # Store the manifest to manifest.json manifest = self.create_manifest() with open(os.path.join(self.work_dir, Package.MANIFEST_FILENAME), "w") as manifest_file: manifest_file.write(manifest) # Package the work_dir to a zip file Package.create_zip_package(self.work_dir, filename) # Delete the temporary directory self.rm_work_dir(preserve_work_dir)
def generate_package(self, filename, preserve_work_directory=False): """ Generates a Nordic DFU package. The package is a zip file containing firmware(s) and metadata required for Nordic DFU applications to perform DFU onn nRF5X devices. :param str filename: Filename for generated package. :param bool preserve_work_directory: True to preserve the temporary working directory. Useful for debugging of a package, and if the user wants to look at the generated package without having to unzip it. :return: None """ work_directory = self.__create_temp_workspace() if Package._is_bootloader_softdevice_combination(self.firmwares_data): # Removing softdevice and bootloader data from dictionary and adding the combined later softdevice_fw_data = self.firmwares_data.pop(HexType.SOFTDEVICE) bootloader_fw_data = self.firmwares_data.pop(HexType.BOOTLOADER) softdevice_fw_name = softdevice_fw_data[FirmwareKeys.FIRMWARE_FILENAME] bootloader_fw_name = bootloader_fw_data[FirmwareKeys.FIRMWARE_FILENAME] new_filename = "sd_bl.bin" sd_bl_file_path = os.path.join(work_directory, new_filename) nrf_hex = nRFHex(softdevice_fw_name, bootloader_fw_name) nrf_hex.tobinfile(sd_bl_file_path) softdevice_size = nrf_hex.size() bootloader_size = nrf_hex.bootloadersize() self.__add_firmware_info( HexType.SD_BL, sd_bl_file_path, softdevice_fw_data[FirmwareKeys.INIT_PACKET_DATA], softdevice_size, bootloader_size, ) for key in self.firmwares_data: firmware = self.firmwares_data[key] # Normalize the firmware file and store it in the work directory firmware[FirmwareKeys.BIN_FILENAME] = Package.normalize_firmware_to_bin( work_directory, firmware[FirmwareKeys.FIRMWARE_FILENAME] ) # Calculate the hash for the .bin file located in the work directory bin_file_path = os.path.join(work_directory, firmware[FirmwareKeys.BIN_FILENAME]) init_packet_data = firmware[FirmwareKeys.INIT_PACKET_DATA] if self.dfu_ver <= 0.5: firmware_hash = Package.calculate_crc16(bin_file_path) init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_CRC16] = firmware_hash elif self.dfu_ver == 0.6: init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID] = INIT_PACKET_USES_CRC16 firmware_hash = Package.calculate_crc16(bin_file_path) init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_CRC16] = firmware_hash elif self.dfu_ver == 0.7: init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID] = INIT_PACKET_USES_HASH init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_LENGTH] = int( Package.calculate_file_size(bin_file_path) ) firmware_hash = Package.calculate_sha256_hash(bin_file_path) init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_HASH] = firmware_hash elif self.dfu_ver == 0.8: init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID] = INIT_PACKET_EXT_USES_ECDS firmware_hash = Package.calculate_sha256_hash(bin_file_path) init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_LENGTH] = int( Package.calculate_file_size(bin_file_path) ) init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_HASH] = firmware_hash temp_packet = self._create_init_packet(firmware) signer = Signing() signer.load_key(self.key_file) signature = signer.sign(temp_packet) init_packet_data[PacketField.NORDIC_PROPRIETARY_OPT_DATA_INIT_PACKET_ECDS] = signature # Store the .dat file in the work directory init_packet = self._create_init_packet(firmware) init_packet_filename = firmware[FirmwareKeys.BIN_FILENAME].replace(".bin", ".dat") with open(os.path.join(work_directory, init_packet_filename), "wb") as init_packet_file: init_packet_file.write(init_packet) firmware[FirmwareKeys.DAT_FILENAME] = init_packet_filename # Store the manifest to manifest.json manifest = self.create_manifest() with open(os.path.join(work_directory, Package.MANIFEST_FILENAME), "w") as manifest_file: manifest_file.write(manifest) # Package the work_directory to a zip file Package.create_zip_package(work_directory, filename) # Delete the temporary directory if not preserve_work_directory: shutil.rmtree(work_directory)
def generate_package(self, filename, preserve_work_directory=False): """ Generates a Nordic DFU package. The package is a zip file containing firmware(s) and metadata required for Nordic DFU applications to perform DFU onn nRF5X devices. :param str filename: Filename for generated package. :param bool preserve_work_directory: True to preserve the temporary working directory. Useful for debugging of a package, and if the user wants to look at the generated package without having to unzip it. :return: None """ work_directory = self.__create_temp_workspace() if Package._is_bootloader_softdevice_combination(self.firmwares_data): # Removing softdevice and bootloader data from dictionary and adding the combined later softdevice_fw_data = self.firmwares_data.pop(HexType.SOFTDEVICE) bootloader_fw_data = self.firmwares_data.pop(HexType.BOOTLOADER) softdevice_fw_name = softdevice_fw_data[ FirmwareKeys.FIRMWARE_FILENAME] bootloader_fw_name = bootloader_fw_data[ FirmwareKeys.FIRMWARE_FILENAME] new_filename = "sd_bl.bin" sd_bl_file_path = os.path.join(work_directory, new_filename) nrf_hex = nRFHex(softdevice_fw_name, bootloader_fw_name) nrf_hex.tobinfile(sd_bl_file_path) softdevice_size = nrf_hex.size() bootloader_size = nrf_hex.bootloadersize() self.__add_firmware_info( HexType.SD_BL, sd_bl_file_path, softdevice_fw_data[FirmwareKeys.INIT_PACKET_DATA], softdevice_size, bootloader_size) for key in self.firmwares_data: firmware = self.firmwares_data[key] # Normalize the firmware file and store it in the work directory firmware[FirmwareKeys.BIN_FILENAME] = \ Package.normalize_firmware_to_bin(work_directory, firmware[FirmwareKeys.FIRMWARE_FILENAME]) # Calculate the hash for the .bin file located in the work directory bin_file_path = os.path.join(work_directory, firmware[FirmwareKeys.BIN_FILENAME]) init_packet_data = firmware[FirmwareKeys.INIT_PACKET_DATA] if self.dfu_ver <= 0.5: firmware_hash = Package.calculate_crc16(bin_file_path) init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_CRC16] = firmware_hash elif self.dfu_ver == 0.6: init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID] = INIT_PACKET_USES_CRC16 firmware_hash = Package.calculate_crc16(bin_file_path) init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_CRC16] = firmware_hash elif self.dfu_ver == 0.7: init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID] = INIT_PACKET_USES_HASH init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_LENGTH] = int( Package.calculate_file_size(bin_file_path)) firmware_hash = Package.calculate_sha256_hash(bin_file_path) init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_HASH] = firmware_hash elif self.dfu_ver == 0.8: init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_EXT_PACKET_ID] = INIT_PACKET_EXT_USES_ECDS firmware_hash = Package.calculate_sha256_hash(bin_file_path) init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_LENGTH] = int( Package.calculate_file_size(bin_file_path)) init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_FIRMWARE_HASH] = firmware_hash temp_packet = self._create_init_packet(firmware) signer = Signing() signer.load_key(self.key_file) signature = signer.sign(temp_packet) init_packet_data[ PacketField. NORDIC_PROPRIETARY_OPT_DATA_INIT_PACKET_ECDS] = signature # Store the .dat file in the work directory init_packet = self._create_init_packet(firmware) init_packet_filename = firmware[FirmwareKeys.BIN_FILENAME].replace( ".bin", ".dat") with open(os.path.join(work_directory, init_packet_filename), 'wb') as init_packet_file: init_packet_file.write(init_packet) firmware[FirmwareKeys.DAT_FILENAME] = \ init_packet_filename # Store the manifest to manifest.json manifest = self.create_manifest() with open(os.path.join(work_directory, Package.MANIFEST_FILENAME), "w") as manifest_file: manifest_file.write(manifest) # Package the work_directory to a zip file Package.create_zip_package(work_directory, filename) # Delete the temporary directory if not preserve_work_directory: shutil.rmtree(work_directory)