示例#1
0
    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)
示例#2
0
    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)
示例#3
0
    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)
示例#4
0
    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)