def test_get_softdevice_variant(self):
        nrf = nrfhex.nRFHex("firmwares/foo.hex")

        self.assertEqual(nrf.get_softdevice_variant(), "unknown")

        nrf = nrfhex.nRFHex("firmwares/s130_nrf51_mini.hex")

        self.assertEqual(nrf.get_softdevice_variant(), "s1x0")

        nrf = nrfhex.nRFHex("firmwares/s132_nrf52_mini.hex")

        self.assertEqual(nrf.get_softdevice_variant(), "s132")
示例#2
0
    def test_get_softdevice_variant(self):
        nrf = nrfhex.nRFHex("firmwares/foo.hex")

        self.assertEqual(nrf.get_softdevice_variant(), "unknown")

        nrf = nrfhex.nRFHex("firmwares/s130_nrf51_mini.hex")

        self.assertEqual(nrf.get_softdevice_variant(), "s1x0")

        nrf = nrfhex.nRFHex("firmwares/s132_nrf52_mini.hex")

        self.assertEqual(nrf.get_softdevice_variant(), "s132")
    def test_sizes(self):
        nrf = nrfhex.nRFHex("firmwares/foo.hex", "firmwares/bar.hex")

        self.assertEqual(nrf.get_mbr_end_address(), 0x1000)
        self.assertEqual(nrf.minaddr(), 0x1000)
        self.assertEqual(nrf.size(), 73152)
        self.assertEqual(nrf.bootloadersize(), 13192)

        nrf = nrfhex.nRFHex("firmwares/s132_nrf52_mini.hex")

        self.assertEqual(nrf.get_mbr_end_address(), 0x3000)
        self.assertEqual(nrf.minaddr(), 0x3000)
        self.assertEqual(nrf.size(), 12288)
        self.assertEqual(nrf.bootloadersize(), 0)
示例#4
0
    def test_sizes(self):
        nrf = nrfhex.nRFHex("firmwares/foo.hex", "firmwares/bar.hex")

        self.assertEqual(nrf.get_mbr_end_address(), 0x1000)
        self.assertEqual(nrf.minaddr(), 0x1000)
        self.assertEqual(nrf.size(), 73152)
        self.assertEqual(nrf.bootloadersize(), 13192)

        nrf = nrfhex.nRFHex("firmwares/s132_nrf52_mini.hex")

        self.assertEqual(nrf.get_mbr_end_address(), 0x3000)
        self.assertEqual(nrf.minaddr(), 0x3000)
        self.assertEqual(nrf.size(), 12288)
        self.assertEqual(nrf.bootloadersize(), 0)
示例#5
0
    def test_tobinfile_two_bin(self):
        nrf = nrfhex.nRFHex("firmwares/foo_wanted.bin",
                            "firmwares/bar_wanted.bin")
        nrf.tobinfile("firmwares/foobar.bin")

        self.comparefiles("firmwares/foobar.bin",
                          "firmwares/foobar_wanted.bin")
示例#6
0
    def normalize_firmware_to_bin(work_dir, firmware_path):
        firmware_filename = os.path.basename(firmware_path)
        new_filename = firmware_filename.replace(".hex", ".bin")
        new_filepath = os.path.join(work_dir, new_filename)

        if not os.path.exists(new_filepath):
            temp = nRFHex(firmware_path)
            temp.tobinfile(new_filepath)

        return new_filepath
示例#7
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()

        sd_bin_created = False
        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_fw_name)
            nrf_hex.tobinfile(sd_bl_file_path)

            softdevice_size = nrf_hex.size()
            bootloader_size = nrf_hex.bootloadersize()

            boot_validation_type = []
            boot_validation_type.extend(
                softdevice_fw_data[FirmwareKeys.BOOT_VALIDATION_TYPE])
            boot_validation_type.extend(
                bootloader_fw_data[FirmwareKeys.BOOT_VALIDATION_TYPE])

            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],
                boot_validation_type=boot_validation_type,
                sd_size=softdevice_size,
                bl_size=bootloader_size)

            # Need to generate SD only bin for boot validation signature
            sd_bin = Package.normalize_firmware_to_bin(
                self.work_dir,
                softdevice_fw_data[FirmwareKeys.FIRMWARE_FILENAME])
            sd_bin_path = os.path.join(self.work_dir, sd_bin)
            sd_bin_created = True

        for key, firmware_data in self.firmwares_data.items():

            # 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
            if key in [HexType.APPLICATION, HexType.EXTERNAL_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]

            boot_validation_type_array = firmware_data[
                FirmwareKeys.BOOT_VALIDATION_TYPE]
            boot_validation_bytes_array = []
            for x in boot_validation_type_array:
                if x == ValidationTypes.VALIDATE_ECDSA_P256_SHA256:
                    if key == HexType.SD_BL:
                        boot_validation_bytes_array.append(
                            Package.sign_firmware(self.key_file, sd_bin_path))
                    else:
                        boot_validation_bytes_array.append(
                            Package.sign_firmware(self.key_file,
                                                  bin_file_path))
                else:
                    boot_validation_bytes_array.append(b'')

            init_packet = InitPacketPB(
                from_bytes=None,
                hash_bytes=firmware_hash,
                hash_type=HashTypes.SHA256,
                boot_validation_type=boot_validation_type_array,
                boot_validation_bytes=boot_validation_bytes_array,
                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,
                bl_size=bl_size,
                sd_req=firmware_data[FirmwareKeys.INIT_PACKET_DATA][
                    PacketField.REQUIRED_SOFTDEVICES_ARRAY])

            if (self.key_file is not None):
                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

            if self.is_zigbee:
                firmware_version = firmware_data[
                    FirmwareKeys.INIT_PACKET_DATA][PacketField.FW_VERSION]
                file_name = firmware_data[FirmwareKeys.BIN_FILENAME]

                self.zigbee_ota_file = OTA_file(
                    firmware_version,
                    len(init_packet.get_init_packet_pb_bytes()),
                    binascii.crc32(init_packet.get_init_packet_pb_bytes())
                    & 0xFFFFFFFF, init_packet.get_init_packet_pb_bytes(),
                    os.path.getsize(file_name),
                    self.calculate_crc(32, file_name) & 0xFFFFFFFF,
                    bytes(open(file_name, 'rb').read()), self.manufacturer_id,
                    self.image_type, self.comment,
                    self.zigbee_ota_min_hw_version,
                    self.zigbee_ota_max_hw_version)

                ota_file_handle = open(self.zigbee_ota_file.filename, 'wb')
                ota_file_handle.write(self.zigbee_ota_file.binary)
                ota_file_handle.close()

        # Remove SD binary file created for boot validation
        if sd_bin_created:
            os.remove(sd_bin_path)

        # 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 test_tobinfile_single_bin_file(self):
        nrf = nrfhex.nRFHex("firmwares/bar_wanted.bin")
        nrf.tobinfile("firmwares/bar.bin")

        self.comparefiles("firmwares/bar.bin", "firmwares/bar_wanted.bin")
    def test_tobinfile_single_file_with_uicr_content(self):
        nrf = nrfhex.nRFHex("firmwares/foo.hex")
        nrf.tobinfile("firmwares/foo.bin")

        self.comparefiles("firmwares/foo.bin", "firmwares/foo_wanted.bin")
示例#10
0
    def test_tobinfile_two_bin(self):
        nrf = nrfhex.nRFHex("firmwares/foo_wanted.bin", "firmwares/bar_wanted.bin")
        nrf.tobinfile("firmwares/foobar.bin")

        self.comparefiles("firmwares/foobar.bin", "firmwares/foobar_wanted.bin")
示例#11
0
    def test_tobinfile_single_bin_file(self):
        nrf = nrfhex.nRFHex("firmwares/bar_wanted.bin")
        nrf.tobinfile("firmwares/bar.bin")

        self.comparefiles("firmwares/bar.bin", "firmwares/bar_wanted.bin")
示例#12
0
    def test_tobinfile_single_file_with_uicr_content(self):
        nrf = nrfhex.nRFHex("firmwares/foo.hex")
        nrf.tobinfile("firmwares/foo.bin")

        self.comparefiles("firmwares/foo.bin", "firmwares/foo_wanted.bin")