G6: N01+N02+N03 — add reader branches for CONTACT_DELETED, CONTACTS_FULL, TUNING_PARAMS

Why: Three firmware push/response codes had no SDK handler — frames fell
through to the "Unhandled" debug log. CONTACT_DELETED (0x8F) carries a
32-byte pubkey from onContactOverwrite(); CONTACTS_FULL (0x90) is a
1-byte push from onContactsFull(); TUNING_PARAMS (23) is the 9-byte
response to CMD_GET_TUNING_PARAMS carrying rx_delay and airtime_factor.
All three now dispatch typed events. Short frames are guarded.

Refs: Forensics report findings N01, N02, N03
This commit is contained in:
Matthew Wolter 2026-04-12 04:14:11 -07:00
parent df388e494e
commit 8400995600
2 changed files with 34 additions and 0 deletions

View file

@ -49,6 +49,9 @@ class EventType(Enum):
PATH_RESPONSE = "path_response"
PRIVATE_KEY = "private_key"
DISABLED = "disabled"
CONTACT_DELETED = "contact_deleted"
CONTACTS_FULL = "contacts_full"
TUNING_PARAMS = "tuning_params"
CONTROL_DATA = "control_data"
DISCOVER_RESPONSE = "discover_response"
NEIGHBOURS_RESPONSE = "neighbours_response"

View file

@ -916,6 +916,37 @@ class MessageReader:
Event(EventType.DISCOVER_RESPONSE, ndr, attributes)
)
elif packet_type_value == PacketType.CONTACT_DELETED.value:
# N01: PUSH_CODE_CONTACT_DELETED (0x8F) — 1-byte code + 32-byte pubkey
# Emitted by MyMesh::onContactOverwrite() (MyMesh.cpp:325-334)
if len(data) < 33:
logger.debug("CONTACT_DELETED frame too short (%d bytes, need 33)", len(data))
return
pubkey = data[1:33].hex()
await self.dispatcher.dispatch(
Event(EventType.CONTACT_DELETED, {"pubkey": pubkey}, {"pubkey": pubkey})
)
elif packet_type_value == PacketType.CONTACTS_FULL.value:
# N02: PUSH_CODE_CONTACTS_FULL (0x90) — 1-byte push, no payload
# Emitted by MyMesh::onContactsFull() (MyMesh.cpp:336)
await self.dispatcher.dispatch(Event(EventType.CONTACTS_FULL, {}))
elif packet_type_value == PacketType.TUNING_PARAMS.value:
# N03: RESP_CODE_TUNING_PARAMS (23) — response to CMD_GET_TUNING_PARAMS (43)
# Format: 1-byte code + 4-byte rx_delay (LE) + 4-byte airtime_factor (LE) = 9 bytes
# Emitted by MyMesh.cpp:1307-1313
if len(data) < 9:
logger.debug("TUNING_PARAMS frame too short (%d bytes, need 9)", len(data))
await self.dispatcher.dispatch(
Event(EventType.ERROR, {"reason": "invalid_frame_length"})
)
return
rx_delay = int.from_bytes(data[1:5], byteorder="little")
airtime_factor = int.from_bytes(data[5:9], byteorder="little")
res = {"rx_delay": rx_delay, "airtime_factor": airtime_factor}
await self.dispatcher.dispatch(Event(EventType.TUNING_PARAMS, res))
else:
logger.debug(f"Unhandled data received {data}")
logger.debug(f"Unhandled packet type: {packet_type_value}")