Files
ha-ninlight/tests_unit/images.py
T

38 lines
1.2 KiB
Python

"""Synthetic ninlight OTA images: 56-byte W600 header + gzip stream + 512-byte NINL trailer.
The layout mirrors ninlight-firmware/tools/mkimage/nl_mkimage.py and was checked against a real
image (spec §2). Tests build their own images instead of copying firmware binaries.
"""
from __future__ import annotations
import gzip
import hashlib
CONTENT_WITH_SSID = b"\x00boot\x00ninIOT\x00ninlight-%s\x00"
CONTENT_WITHOUT_SSID = b"\x00boot\x00ninlight-%s\x00"
def build_payload(content: bytes) -> bytes:
return b"\xab" * 56 + gzip.compress(content, mtime=0)
def build_image(
device_type: str = "gu10_rgb",
version: str = "0.3.8-47-g71a57",
*,
content: bytes = CONTENT_WITH_SSID,
payload: bytes | None = None,
magic: bytes = b"NINL",
fmt: int = 1,
corrupt_hash: bool = False,
) -> bytes:
body = payload if payload is not None else build_payload(content)
trailer = bytearray(b"\xff" * 512)
trailer[0:4] = magic
trailer[4] = fmt
trailer[5:21] = device_type.encode().ljust(16, b"\x00")
trailer[21:37] = version.encode().ljust(16, b"\x00")
trailer[37:69] = bytes(32) if corrupt_hash else hashlib.sha256(body).digest()
return body + bytes(trailer)