From f4f921e7aa064f1a9c5fe5a6b65c7ad17294e211 Mon Sep 17 00:00:00 2001 From: Matt Swann <3lemenopy@gmail.com> Date: Sat, 15 Nov 2025 11:45:41 -0800 Subject: [PATCH 1/3] Add get/set API for the "no store" channel flag --- src/meshcore/commands/device.py | 10 ++++++++++ src/meshcore/events.py | 1 + src/meshcore/packets.py | 1 + src/meshcore/reader.py | 7 +++++++ 4 files changed, 19 insertions(+) diff --git a/src/meshcore/commands/device.py b/src/meshcore/commands/device.py index 06be335..b6b7ec8 100644 --- a/src/meshcore/commands/device.py +++ b/src/meshcore/commands/device.py @@ -205,3 +205,13 @@ async def set_channel( async def export_private_key(self) -> Event: logger.debug("Requesting private key export") return await self.send(b"\x17", [EventType.PRIVATE_KEY, EventType.DISABLED, EventType.ERROR]) + + async def get_channel_flag_nostore(self, channel_idx: int) -> Event: + logger.debug(f"Getting channel flag nostore for channel {channel_idx}") + data = b"\x38" + channel_idx.to_bytes(1, "little") + return await self.send(data, [EventType.CHANNEL_FLAG_NOSTORE, EventType.ERROR]) + + async def set_channel_flag_nostore(self, channel_idx: int, no_store: bool) -> Event: + logger.debug(f"Setting channel flag nostore for channel {channel_idx} to {no_store}") + data = b"\x39" + channel_idx.to_bytes(1, "little") + no_store.to_bytes(1, "little") + return await self.send(data, [EventType.OK, EventType.ERROR]) \ No newline at end of file diff --git a/src/meshcore/events.py b/src/meshcore/events.py index ac523f7..9e6b10c 100644 --- a/src/meshcore/events.py +++ b/src/meshcore/events.py @@ -47,6 +47,7 @@ class EventType(Enum): CONTROL_DATA = "control_data" DISCOVER_RESPONSE = "discover_response" NEIGHBOURS_RESPONSE = "neighbours_response" + CHANNEL_FLAG_NOSTORE = "channel_flag_nostore" # Command response types OK = "command_ok" diff --git a/src/meshcore/packets.py b/src/meshcore/packets.py index 57c1755..39c8f49 100644 --- a/src/meshcore/packets.py +++ b/src/meshcore/packets.py @@ -36,6 +36,7 @@ class PacketType(Enum): SIGN_START = 19 SIGNATURE = 20 CUSTOM_VARS = 21 + CHANNEL_FLAG_NOSTORE = 24 BINARY_REQ = 50 FACTORY_RESET = 51 PATH_DISCOVERY = 52 diff --git a/src/meshcore/reader.py b/src/meshcore/reader.py index 828357f..1b16214 100644 --- a/src/meshcore/reader.py +++ b/src/meshcore/reader.py @@ -285,6 +285,13 @@ async def handle_rx(self, data: bytearray): res[psplit[0]] = psplit[1] logger.debug(f"got custom vars : {res}") await self.dispatcher.dispatch(Event(EventType.CUSTOM_VARS, res)) + + elif packet_type_value == PacketType.CHANNEL_FLAG_NOSTORE.value: + logger.debug(f"received channel flag nostore response: {data.hex()}") + res = {} + res["channel_flag_nostore"] = (bool)(dbuf.read(1)[0]) + logger.debug(f"got channel flags : {res}") + await self.dispatcher.dispatch(Event(EventType.CHANNEL_FLAG_NOSTORE, res)) elif packet_type_value == PacketType.CHANNEL_INFO.value: logger.debug(f"received channel info response: {data.hex()}") From be13905f3be0db177b650484aff92cfc7a914ff6 Mon Sep 17 00:00:00 2001 From: Matt Swann <3lemenopy@gmail.com> Date: Sat, 15 Nov 2025 11:52:59 -0800 Subject: [PATCH 2/3] Update API documentation --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 5296d87..9460e68 100644 --- a/README.md +++ b/README.md @@ -462,6 +462,7 @@ All events in MeshCore are represented by the `EventType` enum. These events are | `ACL_RESPONSE` | `"acl_response"` | Access Control List data | List of keys and permissions | | **Channel Events** ||| | `CHANNEL_INFO` | `"channel_info"` | Channel configuration | Channel name, secret, index | +| `CHANNEL_FLAG_NOSTORE` | `"channel_flag_nostore"` | State of no-store channel flag | Flag state | | **Raw Data Events** ||| | `RAW_DATA` | `"raw_data"` | Raw radio data | SNR, RSSI, payload hex | | `RX_LOG_DATA` | `"rx_log_data"` | RF log data | SNR, RSSI, raw payload | @@ -512,6 +513,8 @@ All commands are async methods that return `Event` objects. Commands are organiz | **Channel Management** |||| | `get_channel(channel_idx)` | `channel_idx: int` | `CHANNEL_INFO` | Get channel configuration | | `set_channel(channel_idx, name, secret)` | `channel_idx: int, name: str, secret: bytes` | `OK` | Configure channel (secret must be 16 bytes) | +| `get_channel_flag_nostore(channel_idx)` | `channel_idx: int` | `CHANNEL_FLAG_NOSTORE` | Get state of channel's no-store flag | +| `set_channel_flag_nostore(channel_idx, enabled)` | `channel_idx: int, enabled: bool` | `OK` | Set state of channel's no-store flag | | **Device Actions** |||| | `send_advert(flood=False)` | `flood: bool` | `OK` | Send advertisement (optionally flood network) | | `reboot()` | None | None | Reboot device (no response expected) | From 66d6e26940f73d543299ed5278a58a553d30211a Mon Sep 17 00:00:00 2001 From: Matt Swann <3lemenopy@gmail.com> Date: Sat, 29 Nov 2025 15:21:06 -0800 Subject: [PATCH 3/3] Update after merging latest changes --- src/meshcore/commands/device.py | 10 ++++++++++ src/meshcore/packets.py | 1 + 2 files changed, 11 insertions(+) diff --git a/src/meshcore/commands/device.py b/src/meshcore/commands/device.py index 958d4bc..2dc64b3 100644 --- a/src/meshcore/commands/device.py +++ b/src/meshcore/commands/device.py @@ -220,3 +220,13 @@ async def get_stats_packets(self) -> Event: logger.debug("Getting packet statistics") # CMD_GET_STATS (56) + STATS_TYPE_PACKETS (2) return await self.send(b"\x38\x02", [EventType.STATS_PACKETS, EventType.ERROR]) + + async def get_channel_flag_nostore(self, channel_idx: int) -> Event: + logger.debug(f"Getting channel flag nostore for channel {channel_idx}") + data = b"\x39" + channel_idx.to_bytes(1, "little") + return await self.send(data, [EventType.CHANNEL_FLAG_NOSTORE, EventType.ERROR]) + + async def set_channel_flag_nostore(self, channel_idx: int, no_store: bool) -> Event: + logger.debug(f"Setting channel flag nostore for channel {channel_idx} to {no_store}") + data = b"\x3a" + channel_idx.to_bytes(1, "little") + no_store.to_bytes(1, "little") + return await self.send(data, [EventType.OK, EventType.ERROR]) \ No newline at end of file diff --git a/src/meshcore/packets.py b/src/meshcore/packets.py index 7257c99..69b7d1b 100644 --- a/src/meshcore/packets.py +++ b/src/meshcore/packets.py @@ -37,6 +37,7 @@ class PacketType(Enum): SIGNATURE = 20 CUSTOM_VARS = 21 STATS = 24 + CHANNEL_FLAG_NOSTORE = 25 BINARY_REQ = 50 FACTORY_RESET = 51 PATH_DISCOVERY = 52