From f7af3d4ead594a7af0569fa6a3f5629febb80a11 Mon Sep 17 00:00:00 2001 From: nomdetom Date: Sat, 29 Aug 2026 00:58:20 +0100 Subject: [PATCH] Add a beacon frequency slot and move the offer channel to an index BroadcastTarget gains an optional frequency_slot so a target can pin the slot it transmits on instead of only deriving one from its channel name. 1-based, to match Config.LoRaConfig.channel_num; unset still derives, so a region with a mandated slot and a mesh on the default name hash both keep working untouched. MeshBeaconConfig gains the same for the advertised offer. broadcast_offer_channel, an inline ChannelSettings, becomes broadcast_offer_channel_index, matching what broadcast_targets already does. One entry point for channel data, free referential validation, and the admin round-trip stops carrying a second copy of a name and PSK. That more than pays for the new fields: ModuleConfig drops 244 -> 227 even with frequency_slot added, and a fully populated admin message encodes to 173 of the 233-byte LoRa ceiling, against 219 before. MeshBeacon gains offer_frequency_slot for the on-air side, omitted whenever a receiver could derive the slot from the region, channel name and preset it is already being sent. Tag 3 on BroadcastTarget was only a comment gap; make it a formal reserved. --- meshtastic/mesh_beacon.proto | 11 +++++++++ meshtastic/module_config.options | 2 -- meshtastic/module_config.proto | 41 +++++++++++++++++++++++++++----- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/meshtastic/mesh_beacon.proto b/meshtastic/mesh_beacon.proto index c6005ab71..a1c9cbe4f 100644 --- a/meshtastic/mesh_beacon.proto +++ b/meshtastic/mesh_beacon.proto @@ -39,4 +39,15 @@ message MeshBeacon { * Combined with offer_region, tells a client "there is a mesh on this preset/region". */ optional Config.LoRaConfig.ModemPreset offer_preset = 4; + + /* + * Frequency slot this mesh uses, 1-based, matching Config.LoRaConfig.channel_num. + * OMITTED when a receiver can derive the slot itself from offer_region, offer_channel's + * name and offer_preset - an unset offer_preset means the region's default preset. That + * covers both a region with a mandated slot and a mesh on the default name hash. + * PRESENT means this mesh deliberately deviates from what derivation would produce; a + * client should still validate the result against its own region before offering to join. + * Do not send 0 - it is the same as omitting the field. + */ + optional uint32 offer_frequency_slot = 5; } diff --git a/meshtastic/module_config.options b/meshtastic/module_config.options index c825a5b44..1bddb6831 100644 --- a/meshtastic/module_config.options +++ b/meshtastic/module_config.options @@ -31,6 +31,4 @@ *StatusMessageConfig.node_status max_size:80 *MeshBeaconConfig.broadcast_message max_size:101 -*MeshBeaconConfig.broadcast_offer_channel.name max_size:12 -*MeshBeaconConfig.broadcast_offer_channel.psk max_size:32 *MeshBeaconConfig.broadcast_targets max_count:4 diff --git a/meshtastic/module_config.proto b/meshtastic/module_config.proto index 9c5d712ba..a03278f7f 100644 --- a/meshtastic/module_config.proto +++ b/meshtastic/module_config.proto @@ -3,7 +3,6 @@ syntax = "proto3"; package meshtastic; import "meshtastic/atak.proto"; -import "meshtastic/channel.proto"; import "meshtastic/config.proto"; option csharp_namespace = "Meshtastic.Protobufs"; @@ -880,10 +879,18 @@ message ModuleConfig { */ string broadcast_message = 4; + // Tag 5 was broadcast_offer_channel, an inline ChannelSettings. Replaced by + // broadcast_offer_channel_index (tag 12): one entry point for channel data, and the + // admin message no longer carries a second copy of a name and PSK. + reserved 5; + reserved "broadcast_offer_channel"; + /* - * Optional channel (name + PSK) to advertise in the MeshBeacon offer_channel field. + * Index into the device's channel table of the channel to advertise. The slot must be + * configured and NOT Role_DISABLED - a disabled slot retains the settings of a deleted + * channel, and advertising it would broadcast a retired PSK. */ - ChannelSettings broadcast_offer_channel = 5; + optional uint32 broadcast_offer_channel_index = 12; /* * Optional region to advertise in the MeshBeacon offer_region field. @@ -909,6 +916,7 @@ message ModuleConfig { */ uint32 broadcast_interval_secs = 11; + /* * One entry in the broadcast destination list. * Each entry names one set of radio settings to send a beacon copy on. @@ -925,16 +933,29 @@ message ModuleConfig { */ Config.LoRaConfig.RegionCode region = 2; - // Tag 3 was an embedded ChannelSettings; replaced by channel_index (tag 4) to keep - // ModuleConfig within the BLE FromRadio size budget. Branch unreleased, so tag 3 is a gap. + // Tag 3 was an embedded ChannelSettings; replaced by channel_index (tag 4). + reserved 3; /* * Index into the device's channel table (0..MAX_NUM_CHANNELS-1) of the channel to * transmit this target's beacon on. The referenced channel must already be configured - * on the node (its key is needed to encrypt). If unset, the default channel for the + * on the node (its key is needed to encrypt) and must NOT be Role_DISABLED - a disabled + * slot retains the settings of a deleted channel. If unset, the default channel for the * preset is used. */ optional uint32 channel_index = 4; + + /* + * Frequency slot to transmit this target's beacon on, 1-based, matching + * Config.LoRaConfig.channel_num. Unset means derive it the way any node on this + * channel would: the region's override slot if it has one, otherwise the hash of the + * target channel's name. Do not send 0 - it is the same as unset. + * Explicit modem parameters and a verbatim override frequency are deliberately not + * offered here; if they are added later this field becomes one arm of a oneof with + * override_frequency, which keeps the tag and wire format but changes the C API. + */ + optional uint32 frequency_slot = 5; + } /* @@ -946,6 +967,14 @@ message ModuleConfig { * Entries that resolve to the same effective preset, region and channel are deduplicated, so * a duplicate entry does not produce a second transmission. */ + /* + * Frequency slot to advertise, 1-based, matching Config.LoRaConfig.channel_num. + * Unset means the receiver can derive it from the advertised region, channel name and + * preset - which covers a region that mandates a slot, and a mesh on the default hash. + * Set it only where the mesh deliberately pins a non-default slot. Do not send 0. + */ + optional uint32 broadcast_offer_frequency_slot = 14; + repeated BroadcastTarget broadcast_targets = 13; }