Exemplo n.º 1
0
    async def fetch_image(self) -> Optional[OTAImage]:
        async with aiohttp.ClientSession() as req:
            LOGGER.debug("Downloading %s for %s", self.url, self.key)
            async with req.get(self.url) as rsp:
                data = await rsp.read()

        img, _ = parse_ota_image(data)
        assert img.header.key == self.key

        LOGGER.debug(
            "%s: version: %s, hw_ver: (%s, %s), OTA string: %s",
            img.header.key,
            img.header.file_version,
            img.header.minimum_hardware_version,
            img.header.maximum_hardware_version,
            img.header.header_string,
        )

        LOGGER.debug(
            "Finished downloading %s bytes from %s for %s ver %s",
            self.image_size,
            self.url,
            self.key,
            self.version,
        )
        return img
Exemplo n.º 2
0
def test_parse_ota_hue():
    data = create_hue_ota(b"test") + b"rest"
    img, rest = firmware.parse_ota_image(data)

    assert isinstance(img, firmware.HueSBLOTAImage)
    assert rest == b"rest"
    assert img.data == b"\x2A\x00\x01" + b"test"
    assert img.serialize() + b"rest" == data
Exemplo n.º 3
0
def test_legrand_container_unwrapping(image):
    # Unwrapped size prefix and 1 + 16 byte suffix
    data = (
        t.uint32_t(len(image.serialize())).serialize()
        + image.serialize()
        + b"\x01"
        + b"abcdabcdabcdabcd"
    )

    with pytest.raises(ValueError):
        firmware.parse_ota_image(data[:-1])

    with pytest.raises(ValueError):
        firmware.parse_ota_image(b"\xFF" + data[1:])

    img, rest = firmware.parse_ota_image(data)
    assert not rest
    assert img == image
Exemplo n.º 4
0
def test_parse_ota_ikea_trailing(image):
    data = wrap_ikea(image.serialize() + b"trailing")

    parsed, remaining = firmware.parse_ota_image(data)
    assert not remaining

    assert parsed.header.image_size == len(image.serialize() + b"trailing")
    assert parsed.subelements[0].data == b"data" + b"trailing"

    parsed2, remaining2 = firmware.OTAImage.deserialize(parsed.serialize())
    assert not remaining2
Exemplo n.º 5
0
    def _fetch_image(self) -> Optional[BaseOTAImage]:
        """Loads full OTA Image from the file."""
        try:
            with open(self.file_name, mode="rb") as f:
                data = f.read()
                img, _ = parse_ota_image(data)

                return img
        except (OSError, ValueError):
            LOGGER.debug("Couldn't load '%s' OTA image",
                         self.file_name,
                         exc_info=True)
        return None
Exemplo n.º 6
0
def test_parse_ota_hue_invalid():
    data = create_hue_ota(b"test")
    firmware.parse_ota_image(data)

    with pytest.raises(ValueError):
        firmware.parse_ota_image(data[:-1])

    header, rest = firmware.OTAImageHeader.deserialize(data)
    assert data == header.serialize() + rest

    with pytest.raises(ValueError):
        # Three byte sequence must be the first thing after the header
        firmware.parse_ota_image(header.serialize() + b"\xFF" + rest[1:])

    with pytest.raises(ValueError):
        # Only Hue is known to use these images
        firmware.parse_ota_image(header.replace(manufacturer_id=12).serialize() + rest)
Exemplo n.º 7
0
    async def fetch_image(self) -> Optional[OTAImage]:
        async with aiohttp.ClientSession() as req:
            LOGGER.debug("Downloading %s for %s", self.url, self.key)
            async with req.get(self.url) as rsp:
                data = await rsp.read()

        ota_image, _ = parse_ota_image(data)
        assert ota_image.header.key == self.key

        LOGGER.debug(
            "Finished downloading %s bytes from %s for %s ver %s",
            self.image_size,
            self.url,
            self.key,
            self.version,
        )
        return ota_image
Exemplo n.º 8
0
    async def fetch_image(self) -> BaseOTAImage | None:
        async with aiohttp.ClientSession() as req:
            LOGGER.debug("Downloading %s for %s", self.url, self.key)
            async with req.get(self.url) as rsp:
                data = await rsp.read()
            img_tgz = io.BytesIO(data)
            with tarfile.open(fileobj=img_tgz) as tar:  # Unpack tar
                for item in tar:
                    if item.name.endswith(".ota"):
                        f = tar.extractfile(item)
                        if f is None:
                            raise ValueError(
                                f"Issue extracting {item.name} from {self.url}"
                            )
                        else:
                            file_bytes = f.read()
                        break
            img, _ = parse_ota_image(file_bytes)

            LOGGER.debug(
                "%s: version: %s, hw_ver: (%s, %s), OTA string: %s",
                img.header.key,
                img.header.file_version,
                img.header.minimum_hardware_version,
                img.header.maximum_hardware_version,
                img.header.header_string,
            )
            assert img.header.manufacturer_id == self.manufacturer_id
            # we can't check assert img.header.key == self.key because
            # self.key does not include any valid image_type data for salus
            # devices.  It is not known at the point of generating the FW
            # list cache, so it can't be checked here (Ikea and ledvance have
            # this listed in the JSON, so they already know and can do this).

        LOGGER.debug(
            "Finished downloading %s bytes from %s for %s ver %s",
            self.image_size,
            self.url,
            self.key,
            self.version,
        )
        return img
Exemplo n.º 9
0
    def scan_image(cls, file_name: str):
        """Check the header of the image."""
        try:
            with open(file_name, mode="rb") as f:
                parsed_image, _ = parse_ota_image(f.read())
                img = cls(file_name=file_name, header=parsed_image.header)

                LOGGER.debug(
                    "%s: %s, version: %s, hw_ver: (%s, %s), OTA string: %s",
                    img.key,
                    img.file_name,
                    img.version,
                    img.header.minimum_hardware_version,
                    img.header.maximum_hardware_version,
                    img.header.header_string,
                )
                return img
        except (OSError, ValueError):
            LOGGER.debug("File '%s' doesn't appear to be a OTA image",
                         file_name,
                         exc_info=True)
        return None
Exemplo n.º 10
0
def test_parse_ota_ikea_truncated(data):
    with pytest.raises(ValueError):
        firmware.parse_ota_image(data)
Exemplo n.º 11
0
def test_parse_ota_ikea(image):
    data = wrap_ikea(image.serialize())
    assert firmware.parse_ota_image(data) == (image, b"")
Exemplo n.º 12
0
def test_parse_ota_normal(image):
    assert firmware.parse_ota_image(image.serialize()) == (image, b"")