From 829ed0cf2da1de4bbde1a8386652fccaa63ac19b Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Thu, 12 Feb 2026 11:01:37 +1000 Subject: [PATCH 1/2] tools: native_bt: handle `InvalidTag` exception Handle decryption failures without crashing. Signed-off-by: Jordan Yates --- src/infuse_iot/tools/native_bt.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/infuse_iot/tools/native_bt.py b/src/infuse_iot/tools/native_bt.py index 9253a07..1877eb6 100644 --- a/src/infuse_iot/tools/native_bt.py +++ b/src/infuse_iot/tools/native_bt.py @@ -15,6 +15,7 @@ from bleak.backends.characteristic import BleakGATTCharacteristic from bleak.backends.device import BLEDevice from bleak.backends.scanner import AdvertisementData +from cryptography.exceptions import InvalidTag from infuse_iot.commands import InfuseCommand from infuse_iot.common import InfuseBluetoothUUID, InfuseType @@ -248,6 +249,8 @@ def simple_callback(self, device: BLEDevice, data: AdvertisementData): self.unknown_networks.add(network_id) Console.log_info(f"Unknown network 0x{network_id:06x}") return + except InvalidTag as _e: + Console.log_info(f"Failed to decrypt packet from {device}") self.bleak_mapping[hdr.device_id] = device hop = HopReceived( From 71b6dc960227ac1dcbca8cdca612e41c49ba7d30 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Thu, 12 Feb 2026 11:02:16 +1000 Subject: [PATCH 2/2] rpc_wrappers: file_write_basic: print expected values Print the expected data CRC and length if the returned response does not match. Signed-off-by: Jordan Yates --- src/infuse_iot/rpc_wrappers/file_write_basic.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/infuse_iot/rpc_wrappers/file_write_basic.py b/src/infuse_iot/rpc_wrappers/file_write_basic.py index e3abff1..832c5bd 100644 --- a/src/infuse_iot/rpc_wrappers/file_write_basic.py +++ b/src/infuse_iot/rpc_wrappers/file_write_basic.py @@ -89,12 +89,13 @@ def __init__(self, args): with open(self.file, "rb") as f: self.payload = f.read() + self._expected_crc = binascii.crc32(self.payload) def auth_level(self): return Auth.NETWORK def request_struct(self): - return self.request(self.action, binascii.crc32(self.payload)) + return self.request(self.action, self._expected_crc) def data_payload(self): print("Preparing for file upload...") @@ -112,6 +113,11 @@ def handle_response(self, return_code, response): if return_code != 0: print(f"Failed to write file ({errno.strerror(-return_code)})") return - print("File written") - print(f"\tLength: {response.recv_len}") - print(f"\t CRC: 0x{response.recv_crc:08x}") + if (response.recv_len != len(self.payload)) or (response.recv_crc != self._expected_crc): + print("Unexpected write contents") + print(f"\tLength: {response.recv_len} (Expected {len(self.payload)})") + print(f"\t CRC: 0x{response.recv_crc:08x} (Expected 0x{self._expected_crc:08x})") + else: + print("File written") + print(f"\tLength: {response.recv_len}") + print(f"\t CRC: 0x{response.recv_crc:08x}")