From 4d6da86c6e7d012e7090b2189193d1e43c9984c8 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 11 Jul 2026 06:07:05 +0000 Subject: [PATCH 01/11] Default ANZ region to ShortFast on slot 16 (918.875 MHz) New Zealand's mesh standard is ShortFast on frequency slot 16, which lands on 918.875 MHz in the 915-928 MHz ANZ band. Set the region's default preset to SHORT_FAST and pin the default frequency slot with an explicit overrideSlot of 16 instead of the channel-name hash. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01ToW4ouBGLnJEo6wQDobdJc --- src/mesh/RadioInterface.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 84d0f79062b..60ed951516c 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -132,8 +132,9 @@ const RegionInfo regions[] = { https://www.iot.org.au/wp/wp-content/uploads/2016/12/IoTSpectrumFactSheet.pdf https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf Also used in Brazil. + Default is ShortFast on slot 16 (918.875 MHz), the New Zealand mesh standard. */ - RDEF(ANZ, 915.0f, 928.0f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), + RDEF(ANZ, 915.0f, 928.0f, 100, 30, false, false, PROFILE_STD, PRESET(SHORT_FAST), 16), /* 433.05 - 434.79 MHz, 25mW EIRP max, No duty cycle restrictions From bddc6d138f611ec2426e9d4d8a86727982b5efa1 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 11 Jul 2026 08:15:01 +0000 Subject: [PATCH 02/11] Move NZ ShortFast default to a userPrefs build variant Revert the ANZ region-table change: ANZ is shared with Australia (and historically Brazil), so changing its default preset there would alter defaults for everyone, not just New Zealand. Instead, bake the NZ community defaults into firmware built from this repo via userPrefs.jsonc: region ANZ and modem preset SHORT_FAST. No frequency-slot override is needed - the default channel name ("ShortFast") hashes to slot 16, which is 918.875 MHz, the NZ mesh standard. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01ToW4ouBGLnJEo6wQDobdJc --- src/mesh/RadioInterface.cpp | 3 +-- userPrefs.jsonc | 7 +++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 60ed951516c..84d0f79062b 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -132,9 +132,8 @@ const RegionInfo regions[] = { https://www.iot.org.au/wp/wp-content/uploads/2016/12/IoTSpectrumFactSheet.pdf https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf Also used in Brazil. - Default is ShortFast on slot 16 (918.875 MHz), the New Zealand mesh standard. */ - RDEF(ANZ, 915.0f, 928.0f, 100, 30, false, false, PROFILE_STD, PRESET(SHORT_FAST), 16), + RDEF(ANZ, 915.0f, 928.0f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), /* 433.05 - 434.79 MHz, 25mW EIRP max, No duty cycle restrictions diff --git a/userPrefs.jsonc b/userPrefs.jsonc index a132eb90674..43e7336cf03 100644 --- a/userPrefs.jsonc +++ b/userPrefs.jsonc @@ -19,7 +19,10 @@ // "USERPREFS_CONFIG_GPS_MODE": "meshtastic_Config_PositionConfig_GpsMode_ENABLED", // "USERPREFS_CONFIG_LORA_IGNORE_MQTT": "true", // "USERPREFS_LORA_TX_DISABLED": "1", // If set, forces config.lora.tx_enabled=false during lora bootstrap - // "USERPREFS_CONFIG_LORA_REGION": "meshtastic_Config_LoRaConfig_RegionCode_US", + // NZ community build: ANZ region defaulting to ShortFast. With the default + // channel name ("ShortFast") the frequency-slot hash lands on slot 16 = + // 918.875 MHz, the New Zealand mesh standard. No channel_num override needed. + "USERPREFS_CONFIG_LORA_REGION": "meshtastic_Config_LoRaConfig_RegionCode_ANZ", // "USERPREFS_CONFIG_OWNER_LONG_NAME": "My Long Name", // "USERPREFS_CONFIG_OWNER_SHORT_NAME": "MLN", // "USERPREFS_CONFIG_DEVICE_ROLE": "meshtastic_Config_DeviceConfig_Role_CLIENT", // Defaults to CLIENT. ROUTER*, and LOST AND FOUND roles are restricted. @@ -39,7 +42,7 @@ // "USERPREFS_CONFIG_ENVIRONMENT_MEASUREMENT_ENABLED": "1", // Force BMP280/sensor reads + LoRa broadcast on first boot // "USERPREFS_LORACONFIG_CHANNEL_NUM": "31", // "USERPREFS_LORACONFIG_TX_POWER": "0", - // "USERPREFS_LORACONFIG_MODEM_PRESET": "meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST", + "USERPREFS_LORACONFIG_MODEM_PRESET": "meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST", // "USERPREFS_USE_ADMIN_KEY_0": "{ 0xcd, 0xc0, 0xb4, 0x3c, 0x53, 0x24, 0xdf, 0x13, 0xca, 0x5a, 0xa6, 0x0c, 0x0d, 0xec, 0x85, 0x5a, 0x4c, 0xf6, 0x1a, 0x96, 0x04, 0x1a, 0x3e, 0xfc, 0xbb, 0x8e, 0x33, 0x71, 0xe5, 0xfc, 0xff, 0x3c }", // "USERPREFS_USE_ADMIN_KEY_1": "{}", // "USERPREFS_USE_ADMIN_KEY_2": "{}", From 112e1059eae9559981ab14836370aaf08394f203 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 11 Jul 2026 15:37:56 +0100 Subject: [PATCH 03/11] Update protobufs (#24) Co-authored-by: NomDeTom <116762865+NomDeTom@users.noreply.github.com> --- src/mesh/generated/meshtastic/admin.pb.h | 6 +-- src/mesh/generated/meshtastic/atak.pb.h | 46 +++++++++---------- src/mesh/generated/meshtastic/mesh.pb.h | 18 ++++---- .../generated/meshtastic/mesh_beacon.pb.h | 2 +- .../generated/meshtastic/module_config.pb.h | 4 +- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/mesh/generated/meshtastic/admin.pb.h b/src/mesh/generated/meshtastic/admin.pb.h index 4c00a568cf0..38829148781 100644 --- a/src/mesh/generated/meshtastic/admin.pb.h +++ b/src/mesh/generated/meshtastic/admin.pb.h @@ -186,7 +186,7 @@ typedef struct _meshtastic_LockdownAuth { token at unlock time: the client-supplied boots_remaining when non-zero, otherwise the firmware default (TOKEN_DEFAULT_BOOTS). Note that boots_remaining == 0 in this message means "use firmware - default", NOT "zero boots" - a client computing the ceiling for + default", NOT "zero boots" — a client computing the ceiling for display should mirror that resolution rather than multiplying the raw request value. @@ -196,7 +196,7 @@ typedef struct _meshtastic_LockdownAuth { Uses millis() (CPU uptime), not wall-clock time, so the cap is immune to GPS spoofing, RTC backup-battery removal, and Faraday - cage isolation - none of those move the uptime counter. The only + cage isolation — none of those move the uptime counter. The only way to reset the session clock is a reboot, which costs a boot from the on-flash, HMAC-bound counter. */ uint32_t max_session_seconds; @@ -213,7 +213,7 @@ typedef struct _meshtastic_LockdownAuth { NOT reversed by this operation: APPROTECT. Once the debug port lockout has been burned (on silicon where it is effective) it is - permanent - disabling lockdown decrypts your data and removes the + permanent — disabling lockdown decrypts your data and removes the access gates, but the SWD/JTAG port stays locked for the life of the device (recoverable only via a full chip erase over a debug probe, which destroys all data). Clients should make this diff --git a/src/mesh/generated/meshtastic/atak.pb.h b/src/mesh/generated/meshtastic/atak.pb.h index e0dab865904..6ea298f9ed7 100644 --- a/src/mesh/generated/meshtastic/atak.pb.h +++ b/src/mesh/generated/meshtastic/atak.pb.h @@ -332,7 +332,7 @@ typedef enum _meshtastic_CotType { /* y-: TAKTALK room/membership broadcast. Payload carried via the TakTalkRoomData typed variant (sender_callsign, room_id, room_name, participants). The CoT type literally has a trailing dash and no - second atom - not a typo. */ + second atom — not a typo. */ meshtastic_CotType_CotType_y = 126 } meshtastic_CotType; @@ -380,7 +380,7 @@ typedef enum _meshtastic_DrawnShape_Kind { /* u-r-b-bullseye: Bullseye ring with range rings and bearing reference */ meshtastic_DrawnShape_Kind_Kind_Bullseye = 7, /* u-d-c-e: Ellipse with distinct major/minor axes (same storage as - Kind_Circle - uses major_cm/minor_cm/angle_deg - but receivers + Kind_Circle — uses major_cm/minor_cm/angle_deg — but receivers render it as a non-circular ellipse rather than a round circle). */ meshtastic_DrawnShape_Kind_Kind_Ellipse = 8, /* u-d-v: 2D vehicle outline drawn on the map. Vertices carry the @@ -400,7 +400,7 @@ typedef enum _meshtastic_DrawnShape_Kind { end of parse; builder uses it to decide which of / to emit in the reconstructed XML. */ typedef enum _meshtastic_DrawnShape_StyleMode { - /* Unspecified - receiver infers from which color fields are non-zero. */ + /* Unspecified — receiver infers from which color fields are non-zero. */ meshtastic_DrawnShape_StyleMode_StyleMode_Unspecified = 0, /* Stroke only. No in the source XML. Used for polylines, ranging lines, bullseye rings. */ @@ -417,7 +417,7 @@ typedef enum _meshtastic_DrawnShape_StyleMode { alone is ambiguous (e.g. a-u-G could be a 2525 symbol or a custom icon depending on the iconset path). */ typedef enum _meshtastic_Marker_Kind { - /* Unspecified - fall back to TAKPacketV2.cot_type_id */ + /* Unspecified — fall back to TAKPacketV2.cot_type_id */ meshtastic_Marker_Kind_Kind_Unspecified = 0, /* b-m-p-s-m: Spot map marker */ meshtastic_Marker_Kind_Kind_Spot = 1, @@ -680,10 +680,10 @@ typedef struct _meshtastic_AircraftTrack { hundred meters of the anchor has per-vertex deltas in the ±10^4 range. Under sint32+zigzag those encode as 2 bytes each (tag+varint), versus the 4 bytes that sfixed32 would always require. At 32 vertices that is ~128 - bytes of savings - the difference between fitting under the LoRa MTU or + bytes of savings — the difference between fitting under the LoRa MTU or not. Absolute coordinates (values ~10^9) would cost sint32 varint 5 bytes per field, which is why TAKPacketV2's top-level latitude_i / longitude_i - stay sfixed32 - only small values win with sint32. */ + stay sfixed32 — only small values win with sint32. */ typedef struct _meshtastic_CotGeoPoint { /* Latitude delta from TAKPacketV2.latitude_i, in 1e-7 degree units. Add to the enclosing event's latitude_i to recover the absolute latitude. */ @@ -791,7 +791,7 @@ typedef struct _meshtastic_Marker { Covers CoT type u-rb-a. The anchor position is on TAKPacketV2.latitude_i/longitude_i; the target endpoint is carried as a - CotGeoPoint - same delta-from-anchor encoding used by DrawnShape.vertices + CotGeoPoint — same delta-from-anchor encoding used by DrawnShape.vertices so a self-anchored RAB (common case) encodes in zero bytes. */ typedef struct _meshtastic_RangeAndBearing { /* Target/anchor endpoint (delta-encoded from TAKPacketV2.latitude_i/longitude_i). */ @@ -899,12 +899,12 @@ typedef struct _meshtastic_CasevacReport { same as the envelope callsign but ATAK sometimes carries a distinct ops-number here. */ pb_callback_t title; - /* Primary medline free-text - the single most clinically important line + /* Primary medline free-text — the single most clinically important line on a MEDLINE form (e.g. "2 urgent litter patients, smoke on approach"). MUST be preserved under MTU pressure as long as any casevac is sent. */ pb_callback_t medline_remarks; /* Line 3 (newer ATAK format): patient counts by precedence level. - Coexists with the enum-style `precedence` field (tag 1) - older ATAK + Coexists with the enum-style `precedence` field (tag 1) — older ATAK emits a single enum, newer ATAK emits these counts, and both can be set simultaneously. Senders populate whichever style(s) the source XML had; receivers prefer counts when non-zero. */ @@ -946,19 +946,19 @@ typedef struct _meshtastic_CasevacReport { (e.g. "Primary HLZ is soccer field"). */ pb_callback_t hlz_remarks; /* Per-patient clinical records. Each entry is one patient's ZMIST card - (Zap number / Mechanism / Injuries / Signs / Treatment). Repeatable - + (Zap number / Mechanism / Injuries / Signs / Treatment). Repeatable — a mass-casualty event can carry 1-6 entries in practice, limited by the 237 B LoRa MTU. */ pb_callback_t zmist; } meshtastic_CasevacReport; -/* Per-patient clinical summary record - one entry per patient in a CASEVAC. +/* Per-patient clinical summary record — one entry per patient in a CASEVAC. Maps directly to ATAK's child element inside . All fields are optional free-text; senders populate what they have. */ typedef struct _meshtastic_ZMistEntry { /* Patient identifier / sequence label (e.g. "ZMIST-1", "ZMIST-2"). */ pb_callback_t title; - /* Zap number - unique patient tracking ID (often a terse code like + /* Zap number — unique patient tracking ID (often a terse code like "Gunshot" or a serial). */ pb_callback_t z; /* Mechanism of injury (e.g. "Penetrating trauma", "Blast injury"). */ @@ -997,7 +997,7 @@ typedef struct _meshtastic_EmergencyAlert { creation time; the fields below carry structured metadata the raw-detail fallback currently loses. - Fields are deliberately lean - this variant is closer to the MTU ceiling + Fields are deliberately lean — this variant is closer to the MTU ceiling than the others, so every string is capped in options. */ typedef struct _meshtastic_TaskRequest { /* Short tag for the task category (e.g. "engage", "observe", "recon", @@ -1017,7 +1017,7 @@ typedef struct _meshtastic_TaskRequest { /* Weather annotation from CoT detail element. - Attaches to any TAKPacketV2 regardless of payload_variant - an Aircraft, + Attaches to any TAKPacketV2 regardless of payload_variant — an Aircraft, PLI, or Marker can all carry observed conditions at the emitting station. ATAK-CIV ships an XSD for but no dedicated handler, so the element round-trips through the generic detail pipeline; this message @@ -1026,7 +1026,7 @@ typedef struct _meshtastic_TaskRequest { Target wire cost: ~6-8 bytes compressed with a fully populated instance. Named `TAKEnvironment` (not just `Environment`) because the bare name - collides with `SwiftUI.Environment` - every SwiftUI view in a consuming + collides with `SwiftUI.Environment` — every SwiftUI view in a consuming iOS app uses the `@Environment` property wrapper, and importing the generated proto module would make `Environment` ambiguous in every one of those files. The `TAK` prefix matches the convention used by the @@ -1055,7 +1055,7 @@ typedef struct _meshtastic_TAKEnvironment { The receiving ATAK client restores those from its own defaults, same as every other CoT carried over Meshtastic today. - Attaches to any TAKPacketV2 - a PLI with a sensor on the operator's head, + Attaches to any TAKPacketV2 — a PLI with a sensor on the operator's head, an Aircraft with a FLIR turret, a Marker dropped on a UAV. Target wire cost: ~7-14 bytes compressed (dominated by model string). */ typedef struct _meshtastic_SensorFov { @@ -1065,30 +1065,30 @@ typedef struct _meshtastic_SensorFov { SensorDetailHandler default (270°) and save varint bytes over centi-deg. */ uint32_t azimuth_deg; /* Maximum range of the cone in meters. - Optional - if unset, receivers should use the ATAK-CIV default of 100m. */ + Optional — if unset, receivers should use the ATAK-CIV default of 100m. */ bool has_range_m; uint32_t range_m; /* Horizontal field of view in whole degrees (cone's angular width). ATAK-CIV default is 45°. */ uint32_t fov_horizontal_deg; /* Vertical field of view in whole degrees. ATAK-CIV default is 45°. - Optional - a value of 0 means "not set / use horizontal FOV". */ + Optional — a value of 0 means "not set / use horizontal FOV". */ uint32_t fov_vertical_deg; /* Elevation angle in whole degrees. Positive = up, negative = down. Range -90 to +90. sint32 for varint efficiency on small negatives. */ int32_t elevation_deg; /* Roll (camera tilt) in whole degrees, -180 to +180. - Optional - use 0 if the sensor doesn't track roll. */ + Optional — use 0 if the sensor doesn't track roll. */ int32_t roll_deg; /* Free-form device model identifier, e.g. "FLIR-Boson-640", "SEEK". - Optional - empty string means "unknown model" (ATAK-CIV default). */ + Optional — empty string means "unknown model" (ATAK-CIV default). */ pb_callback_t model; } meshtastic_SensorFov; /* TAKTALK chat message payload (CoT type m-t-t). TAKTALK is an ATAK plugin for voice + text team messaging. The voice - audio stream goes over UDP/RTP and is NOT carried by the mesh - only + audio stream goes over UDP/RTP and is NOT carried by the mesh — only the text envelope (this message) is. `from_voice` marks messages sent via push-to-talk speech-to-text so receivers can render a mic icon next to the text. @@ -1122,7 +1122,7 @@ typedef struct _meshtastic_TakTalkMessage { Announces a TAKTALK chatroom's friendly name and roster so peers can resolve room UUIDs (used in TakTalkMessage.chatroom_id and GeoChat.room_id) to a display name and participant list. Not a chat - message itself - these events are emitted by TAKTALK when rooms are + message itself — these events are emitted by TAKTALK when rooms are created or memberships change. */ typedef struct _meshtastic_TakTalkRoomData { /* Callsign of the device broadcasting the room state (typically the @@ -1161,7 +1161,7 @@ typedef struct _meshtastic_Marti { primary-vs-cc distinction the same way ATAK does. If dest_callsign is [TAKPacketV2.callsign] (self-addressed, unusual but - legal - e.g. ATAK echoing back to its own room), the builder still emits + legal — e.g. ATAK echoing back to its own room), the builder still emits the element so loopback shapes round-trip cleanly. */ pb_callback_t dest_callsign; } meshtastic_Marti; diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index 98798173c85..3020a0f1be3 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -1250,15 +1250,15 @@ typedef struct _meshtastic_LockdownStatus { /* Current lockdown state being reported. */ meshtastic_LockdownStatus_State state; /* For LOCKED: machine-readable reason. Known values: - "needs_auth" - storage already unlocked, client must auth - "token_missing" - no boot token on flash - "token_expired" - boot token wall-clock TTL elapsed - "token_boots_zero" - boot token boot-count TTL exhausted - "token_hmac_fail" - token tampered or wrong device - "token_dek_fail" - token DEK decrypt failed - "token_wrong_size" - token file corrupted - "token_bad_magic" - token file corrupted - "not_provisioned" - should generally use NEEDS_PROVISION state instead + "needs_auth" — storage already unlocked, client must auth + "token_missing" — no boot token on flash + "token_expired" — boot token wall-clock TTL elapsed + "token_boots_zero" — boot token boot-count TTL exhausted + "token_hmac_fail" — token tampered or wrong device + "token_dek_fail" — token DEK decrypt failed + "token_wrong_size" — token file corrupted + "token_bad_magic" — token file corrupted + "not_provisioned" — should generally use NEEDS_PROVISION state instead Other values may be added; clients should treat unknown values as "locked, ask for passphrase". */ char lock_reason[32]; diff --git a/src/mesh/generated/meshtastic/mesh_beacon.pb.h b/src/mesh/generated/meshtastic/mesh_beacon.pb.h index 94312eb1e99..028d8269f50 100644 --- a/src/mesh/generated/meshtastic/mesh_beacon.pb.h +++ b/src/mesh/generated/meshtastic/mesh_beacon.pb.h @@ -15,7 +15,7 @@ /* Payload for MESH_BEACON_APP packets. Periodically broadcast by nodes in beacon mode. Listeners deliver the text message to the local inbox and cache any offered - channel/preset for the client app to act on - the firmware never auto-applies them. */ + channel/preset for the client app to act on — the firmware never auto-applies them. */ typedef struct _meshtastic_MeshBeacon { /* Human-readable beacon message. Max 100 bytes enforced by firmware on send. */ char message[101]; diff --git a/src/mesh/generated/meshtastic/module_config.pb.h b/src/mesh/generated/meshtastic/module_config.pb.h index 713a9114014..b04c358fc41 100644 --- a/src/mesh/generated/meshtastic/module_config.pb.h +++ b/src/mesh/generated/meshtastic/module_config.pb.h @@ -497,7 +497,7 @@ typedef struct _meshtastic_ModuleConfig_MeshBeaconConfig { /* Single-target TX channel: channel settings (name + PSK) to send beacons on. If unset, beacons go out on the primary channel. Used only when broadcast_targets is empty. NOTE: the single-target path embeds the ChannelSettings inline here, whereas a - broadcast_targets entry references a channel-table slot by channel_index instead - see + broadcast_targets entry references a channel-table slot by channel_index instead — see BroadcastTarget. The two paths are equal, first-class options; only this representation differs. */ bool has_broadcast_on_channel; meshtastic_ChannelSettings broadcast_on_channel; @@ -514,7 +514,7 @@ typedef struct _meshtastic_ModuleConfig_MeshBeaconConfig { each temporarily switching the radio to that entry's preset/region/channel. When empty, the broadcaster uses the scalar broadcast_on_preset / broadcast_on_region / broadcast_on_channel fields instead (the single-target path). - Single- and multi-target are equal, first-class options - neither is preferred or + Single- and multi-target are equal, first-class options — neither is preferred or deprecated. They differ only in how the TX channel is named: broadcast_on_channel embeds a ChannelSettings inline, while a target references an existing channel-table slot by channel_index (see BroadcastTarget). */ From 4c978b031c5b98a40a9bd59c7042dfe9ca46560b Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 11 Jul 2026 14:44:47 +0000 Subject: [PATCH 04/11] Point protobufs submodule at NZ_924 fork branch, regen nanopb sources .gitmodules now tracks NomDeTom/MeshtasticProtobufs @ nz-sf, rebased onto upstream meshtastic/protobufs master (adds NZ_924 as a new RegionCode value, additive/non-breaking). Regenerated the nanopb C sources from that commit, which also incidentally picks up the MEDIUM_TURBO modem preset added upstream in the same rebase window. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01ToW4ouBGLnJEo6wQDobdJc --- .gitmodules | 3 ++- protobufs | 2 +- src/mesh/generated/meshtastic/config.pb.h | 9 ++++++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.gitmodules b/.gitmodules index 7c54ad51393..993adde7ead 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,7 @@ [submodule "protobufs"] path = protobufs - url = https://github.com/meshtastic/protobufs.git + url = https://github.com/NomDeTom/MeshtasticProtobufs.git + branch = nz-sf [submodule "meshtestic"] path = meshtestic url = https://github.com/meshtastic/meshTestic diff --git a/protobufs b/protobufs index 9d589c13214..a0ed789681a 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 9d589c1321478193885d6cecf852bf02d14fc92b +Subproject commit a0ed789681adee29fdca69213ade31fb8c77fe65 diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index 0778a9bc51f..d7275e11497 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -313,7 +313,10 @@ typedef enum _meshtastic_Config_LoRaConfig_RegionCode { /* ITU Region 2 Amateur Radio 1.25m '125cm' band (220-225 MHz) Note: Some countries do not allocate 220-222 MHz (Ex: USA/Canada). Check local law! */ - meshtastic_Config_LoRaConfig_RegionCode_ITU2_125CM = 37 + meshtastic_Config_LoRaConfig_RegionCode_ITU2_125CM = 37, + /* New Zealand 924MHz + Same band as ANZ, for use with the Short Fast modem preset */ + meshtastic_Config_LoRaConfig_RegionCode_NZ_924 = 38 } meshtastic_Config_LoRaConfig_RegionCode; /* Standard predefined channel settings @@ -767,8 +770,8 @@ extern "C" { #define _meshtastic_Config_DisplayConfig_CompassOrientation_ARRAYSIZE ((meshtastic_Config_DisplayConfig_CompassOrientation)(meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED+1)) #define _meshtastic_Config_LoRaConfig_RegionCode_MIN meshtastic_Config_LoRaConfig_RegionCode_UNSET -#define _meshtastic_Config_LoRaConfig_RegionCode_MAX meshtastic_Config_LoRaConfig_RegionCode_ITU2_125CM -#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_ITU2_125CM+1)) +#define _meshtastic_Config_LoRaConfig_RegionCode_MAX meshtastic_Config_LoRaConfig_RegionCode_NZ_924 +#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_NZ_924+1)) #define _meshtastic_Config_LoRaConfig_ModemPreset_MIN meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST #define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_TURBO From 449e80a7971eb705ecafab0ed6e3aea86bf00e7f Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 11 Jul 2026 14:49:56 +0000 Subject: [PATCH 05/11] Add NZ_924 region table entry defaulting to ShortFast Same 915-928 MHz band and PROFILE_STD as ANZ, but defaults to SHORT_FAST instead of LONG_FAST. Frequency slot is left on the default channel-name hash (overrideSlot 0), which for the "ShortFast" channel name lands on slot 16 = 918.875 MHz, the New Zealand mesh standard. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01ToW4ouBGLnJEo6wQDobdJc --- src/mesh/RadioInterface.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 84d0f79062b..80c59121132 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -135,6 +135,12 @@ const RegionInfo regions[] = { */ RDEF(ANZ, 915.0f, 928.0f, 100, 30, false, false, PROFILE_STD, PRESET(LONG_FAST), 0), + /* + Same band as ANZ, for New Zealand nodes wanting ShortFast as their default preset + instead of LongFast. https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf + */ + RDEF(NZ_924, 915.0f, 928.0f, 100, 30, false, false, PROFILE_STD, PRESET(SHORT_FAST), 0), + /* 433.05 - 434.79 MHz, 25mW EIRP max, No duty cycle restrictions AU Low Interference Potential https://www.acma.gov.au/licences/low-interference-potential-devices-lipd-class-licence From 522a82a87c3fe7e9aac0a236335113d51028582c Mon Sep 17 00:00:00 2001 From: nomdetom Date: Tue, 14 Jul 2026 02:33:55 +0100 Subject: [PATCH 06/11] emdash --- src/mesh/generated/meshtastic/admin.pb.h | 6 +-- src/mesh/generated/meshtastic/atak.pb.h | 46 +++++++++---------- src/mesh/generated/meshtastic/mesh.pb.h | 18 ++++---- .../generated/meshtastic/mesh_beacon.pb.h | 2 +- .../generated/meshtastic/module_config.pb.h | 4 +- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/mesh/generated/meshtastic/admin.pb.h b/src/mesh/generated/meshtastic/admin.pb.h index 38829148781..4c00a568cf0 100644 --- a/src/mesh/generated/meshtastic/admin.pb.h +++ b/src/mesh/generated/meshtastic/admin.pb.h @@ -186,7 +186,7 @@ typedef struct _meshtastic_LockdownAuth { token at unlock time: the client-supplied boots_remaining when non-zero, otherwise the firmware default (TOKEN_DEFAULT_BOOTS). Note that boots_remaining == 0 in this message means "use firmware - default", NOT "zero boots" — a client computing the ceiling for + default", NOT "zero boots" - a client computing the ceiling for display should mirror that resolution rather than multiplying the raw request value. @@ -196,7 +196,7 @@ typedef struct _meshtastic_LockdownAuth { Uses millis() (CPU uptime), not wall-clock time, so the cap is immune to GPS spoofing, RTC backup-battery removal, and Faraday - cage isolation — none of those move the uptime counter. The only + cage isolation - none of those move the uptime counter. The only way to reset the session clock is a reboot, which costs a boot from the on-flash, HMAC-bound counter. */ uint32_t max_session_seconds; @@ -213,7 +213,7 @@ typedef struct _meshtastic_LockdownAuth { NOT reversed by this operation: APPROTECT. Once the debug port lockout has been burned (on silicon where it is effective) it is - permanent — disabling lockdown decrypts your data and removes the + permanent - disabling lockdown decrypts your data and removes the access gates, but the SWD/JTAG port stays locked for the life of the device (recoverable only via a full chip erase over a debug probe, which destroys all data). Clients should make this diff --git a/src/mesh/generated/meshtastic/atak.pb.h b/src/mesh/generated/meshtastic/atak.pb.h index 6ea298f9ed7..e0dab865904 100644 --- a/src/mesh/generated/meshtastic/atak.pb.h +++ b/src/mesh/generated/meshtastic/atak.pb.h @@ -332,7 +332,7 @@ typedef enum _meshtastic_CotType { /* y-: TAKTALK room/membership broadcast. Payload carried via the TakTalkRoomData typed variant (sender_callsign, room_id, room_name, participants). The CoT type literally has a trailing dash and no - second atom — not a typo. */ + second atom - not a typo. */ meshtastic_CotType_CotType_y = 126 } meshtastic_CotType; @@ -380,7 +380,7 @@ typedef enum _meshtastic_DrawnShape_Kind { /* u-r-b-bullseye: Bullseye ring with range rings and bearing reference */ meshtastic_DrawnShape_Kind_Kind_Bullseye = 7, /* u-d-c-e: Ellipse with distinct major/minor axes (same storage as - Kind_Circle — uses major_cm/minor_cm/angle_deg — but receivers + Kind_Circle - uses major_cm/minor_cm/angle_deg - but receivers render it as a non-circular ellipse rather than a round circle). */ meshtastic_DrawnShape_Kind_Kind_Ellipse = 8, /* u-d-v: 2D vehicle outline drawn on the map. Vertices carry the @@ -400,7 +400,7 @@ typedef enum _meshtastic_DrawnShape_Kind { end of parse; builder uses it to decide which of / to emit in the reconstructed XML. */ typedef enum _meshtastic_DrawnShape_StyleMode { - /* Unspecified — receiver infers from which color fields are non-zero. */ + /* Unspecified - receiver infers from which color fields are non-zero. */ meshtastic_DrawnShape_StyleMode_StyleMode_Unspecified = 0, /* Stroke only. No in the source XML. Used for polylines, ranging lines, bullseye rings. */ @@ -417,7 +417,7 @@ typedef enum _meshtastic_DrawnShape_StyleMode { alone is ambiguous (e.g. a-u-G could be a 2525 symbol or a custom icon depending on the iconset path). */ typedef enum _meshtastic_Marker_Kind { - /* Unspecified — fall back to TAKPacketV2.cot_type_id */ + /* Unspecified - fall back to TAKPacketV2.cot_type_id */ meshtastic_Marker_Kind_Kind_Unspecified = 0, /* b-m-p-s-m: Spot map marker */ meshtastic_Marker_Kind_Kind_Spot = 1, @@ -680,10 +680,10 @@ typedef struct _meshtastic_AircraftTrack { hundred meters of the anchor has per-vertex deltas in the ±10^4 range. Under sint32+zigzag those encode as 2 bytes each (tag+varint), versus the 4 bytes that sfixed32 would always require. At 32 vertices that is ~128 - bytes of savings — the difference between fitting under the LoRa MTU or + bytes of savings - the difference between fitting under the LoRa MTU or not. Absolute coordinates (values ~10^9) would cost sint32 varint 5 bytes per field, which is why TAKPacketV2's top-level latitude_i / longitude_i - stay sfixed32 — only small values win with sint32. */ + stay sfixed32 - only small values win with sint32. */ typedef struct _meshtastic_CotGeoPoint { /* Latitude delta from TAKPacketV2.latitude_i, in 1e-7 degree units. Add to the enclosing event's latitude_i to recover the absolute latitude. */ @@ -791,7 +791,7 @@ typedef struct _meshtastic_Marker { Covers CoT type u-rb-a. The anchor position is on TAKPacketV2.latitude_i/longitude_i; the target endpoint is carried as a - CotGeoPoint — same delta-from-anchor encoding used by DrawnShape.vertices + CotGeoPoint - same delta-from-anchor encoding used by DrawnShape.vertices so a self-anchored RAB (common case) encodes in zero bytes. */ typedef struct _meshtastic_RangeAndBearing { /* Target/anchor endpoint (delta-encoded from TAKPacketV2.latitude_i/longitude_i). */ @@ -899,12 +899,12 @@ typedef struct _meshtastic_CasevacReport { same as the envelope callsign but ATAK sometimes carries a distinct ops-number here. */ pb_callback_t title; - /* Primary medline free-text — the single most clinically important line + /* Primary medline free-text - the single most clinically important line on a MEDLINE form (e.g. "2 urgent litter patients, smoke on approach"). MUST be preserved under MTU pressure as long as any casevac is sent. */ pb_callback_t medline_remarks; /* Line 3 (newer ATAK format): patient counts by precedence level. - Coexists with the enum-style `precedence` field (tag 1) — older ATAK + Coexists with the enum-style `precedence` field (tag 1) - older ATAK emits a single enum, newer ATAK emits these counts, and both can be set simultaneously. Senders populate whichever style(s) the source XML had; receivers prefer counts when non-zero. */ @@ -946,19 +946,19 @@ typedef struct _meshtastic_CasevacReport { (e.g. "Primary HLZ is soccer field"). */ pb_callback_t hlz_remarks; /* Per-patient clinical records. Each entry is one patient's ZMIST card - (Zap number / Mechanism / Injuries / Signs / Treatment). Repeatable — + (Zap number / Mechanism / Injuries / Signs / Treatment). Repeatable - a mass-casualty event can carry 1-6 entries in practice, limited by the 237 B LoRa MTU. */ pb_callback_t zmist; } meshtastic_CasevacReport; -/* Per-patient clinical summary record — one entry per patient in a CASEVAC. +/* Per-patient clinical summary record - one entry per patient in a CASEVAC. Maps directly to ATAK's child element inside . All fields are optional free-text; senders populate what they have. */ typedef struct _meshtastic_ZMistEntry { /* Patient identifier / sequence label (e.g. "ZMIST-1", "ZMIST-2"). */ pb_callback_t title; - /* Zap number — unique patient tracking ID (often a terse code like + /* Zap number - unique patient tracking ID (often a terse code like "Gunshot" or a serial). */ pb_callback_t z; /* Mechanism of injury (e.g. "Penetrating trauma", "Blast injury"). */ @@ -997,7 +997,7 @@ typedef struct _meshtastic_EmergencyAlert { creation time; the fields below carry structured metadata the raw-detail fallback currently loses. - Fields are deliberately lean — this variant is closer to the MTU ceiling + Fields are deliberately lean - this variant is closer to the MTU ceiling than the others, so every string is capped in options. */ typedef struct _meshtastic_TaskRequest { /* Short tag for the task category (e.g. "engage", "observe", "recon", @@ -1017,7 +1017,7 @@ typedef struct _meshtastic_TaskRequest { /* Weather annotation from CoT detail element. - Attaches to any TAKPacketV2 regardless of payload_variant — an Aircraft, + Attaches to any TAKPacketV2 regardless of payload_variant - an Aircraft, PLI, or Marker can all carry observed conditions at the emitting station. ATAK-CIV ships an XSD for but no dedicated handler, so the element round-trips through the generic detail pipeline; this message @@ -1026,7 +1026,7 @@ typedef struct _meshtastic_TaskRequest { Target wire cost: ~6-8 bytes compressed with a fully populated instance. Named `TAKEnvironment` (not just `Environment`) because the bare name - collides with `SwiftUI.Environment` — every SwiftUI view in a consuming + collides with `SwiftUI.Environment` - every SwiftUI view in a consuming iOS app uses the `@Environment` property wrapper, and importing the generated proto module would make `Environment` ambiguous in every one of those files. The `TAK` prefix matches the convention used by the @@ -1055,7 +1055,7 @@ typedef struct _meshtastic_TAKEnvironment { The receiving ATAK client restores those from its own defaults, same as every other CoT carried over Meshtastic today. - Attaches to any TAKPacketV2 — a PLI with a sensor on the operator's head, + Attaches to any TAKPacketV2 - a PLI with a sensor on the operator's head, an Aircraft with a FLIR turret, a Marker dropped on a UAV. Target wire cost: ~7-14 bytes compressed (dominated by model string). */ typedef struct _meshtastic_SensorFov { @@ -1065,30 +1065,30 @@ typedef struct _meshtastic_SensorFov { SensorDetailHandler default (270°) and save varint bytes over centi-deg. */ uint32_t azimuth_deg; /* Maximum range of the cone in meters. - Optional — if unset, receivers should use the ATAK-CIV default of 100m. */ + Optional - if unset, receivers should use the ATAK-CIV default of 100m. */ bool has_range_m; uint32_t range_m; /* Horizontal field of view in whole degrees (cone's angular width). ATAK-CIV default is 45°. */ uint32_t fov_horizontal_deg; /* Vertical field of view in whole degrees. ATAK-CIV default is 45°. - Optional — a value of 0 means "not set / use horizontal FOV". */ + Optional - a value of 0 means "not set / use horizontal FOV". */ uint32_t fov_vertical_deg; /* Elevation angle in whole degrees. Positive = up, negative = down. Range -90 to +90. sint32 for varint efficiency on small negatives. */ int32_t elevation_deg; /* Roll (camera tilt) in whole degrees, -180 to +180. - Optional — use 0 if the sensor doesn't track roll. */ + Optional - use 0 if the sensor doesn't track roll. */ int32_t roll_deg; /* Free-form device model identifier, e.g. "FLIR-Boson-640", "SEEK". - Optional — empty string means "unknown model" (ATAK-CIV default). */ + Optional - empty string means "unknown model" (ATAK-CIV default). */ pb_callback_t model; } meshtastic_SensorFov; /* TAKTALK chat message payload (CoT type m-t-t). TAKTALK is an ATAK plugin for voice + text team messaging. The voice - audio stream goes over UDP/RTP and is NOT carried by the mesh — only + audio stream goes over UDP/RTP and is NOT carried by the mesh - only the text envelope (this message) is. `from_voice` marks messages sent via push-to-talk speech-to-text so receivers can render a mic icon next to the text. @@ -1122,7 +1122,7 @@ typedef struct _meshtastic_TakTalkMessage { Announces a TAKTALK chatroom's friendly name and roster so peers can resolve room UUIDs (used in TakTalkMessage.chatroom_id and GeoChat.room_id) to a display name and participant list. Not a chat - message itself — these events are emitted by TAKTALK when rooms are + message itself - these events are emitted by TAKTALK when rooms are created or memberships change. */ typedef struct _meshtastic_TakTalkRoomData { /* Callsign of the device broadcasting the room state (typically the @@ -1161,7 +1161,7 @@ typedef struct _meshtastic_Marti { primary-vs-cc distinction the same way ATAK does. If dest_callsign is [TAKPacketV2.callsign] (self-addressed, unusual but - legal — e.g. ATAK echoing back to its own room), the builder still emits + legal - e.g. ATAK echoing back to its own room), the builder still emits the element so loopback shapes round-trip cleanly. */ pb_callback_t dest_callsign; } meshtastic_Marti; diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index 3020a0f1be3..98798173c85 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -1250,15 +1250,15 @@ typedef struct _meshtastic_LockdownStatus { /* Current lockdown state being reported. */ meshtastic_LockdownStatus_State state; /* For LOCKED: machine-readable reason. Known values: - "needs_auth" — storage already unlocked, client must auth - "token_missing" — no boot token on flash - "token_expired" — boot token wall-clock TTL elapsed - "token_boots_zero" — boot token boot-count TTL exhausted - "token_hmac_fail" — token tampered or wrong device - "token_dek_fail" — token DEK decrypt failed - "token_wrong_size" — token file corrupted - "token_bad_magic" — token file corrupted - "not_provisioned" — should generally use NEEDS_PROVISION state instead + "needs_auth" - storage already unlocked, client must auth + "token_missing" - no boot token on flash + "token_expired" - boot token wall-clock TTL elapsed + "token_boots_zero" - boot token boot-count TTL exhausted + "token_hmac_fail" - token tampered or wrong device + "token_dek_fail" - token DEK decrypt failed + "token_wrong_size" - token file corrupted + "token_bad_magic" - token file corrupted + "not_provisioned" - should generally use NEEDS_PROVISION state instead Other values may be added; clients should treat unknown values as "locked, ask for passphrase". */ char lock_reason[32]; diff --git a/src/mesh/generated/meshtastic/mesh_beacon.pb.h b/src/mesh/generated/meshtastic/mesh_beacon.pb.h index 028d8269f50..94312eb1e99 100644 --- a/src/mesh/generated/meshtastic/mesh_beacon.pb.h +++ b/src/mesh/generated/meshtastic/mesh_beacon.pb.h @@ -15,7 +15,7 @@ /* Payload for MESH_BEACON_APP packets. Periodically broadcast by nodes in beacon mode. Listeners deliver the text message to the local inbox and cache any offered - channel/preset for the client app to act on — the firmware never auto-applies them. */ + channel/preset for the client app to act on - the firmware never auto-applies them. */ typedef struct _meshtastic_MeshBeacon { /* Human-readable beacon message. Max 100 bytes enforced by firmware on send. */ char message[101]; diff --git a/src/mesh/generated/meshtastic/module_config.pb.h b/src/mesh/generated/meshtastic/module_config.pb.h index b04c358fc41..713a9114014 100644 --- a/src/mesh/generated/meshtastic/module_config.pb.h +++ b/src/mesh/generated/meshtastic/module_config.pb.h @@ -497,7 +497,7 @@ typedef struct _meshtastic_ModuleConfig_MeshBeaconConfig { /* Single-target TX channel: channel settings (name + PSK) to send beacons on. If unset, beacons go out on the primary channel. Used only when broadcast_targets is empty. NOTE: the single-target path embeds the ChannelSettings inline here, whereas a - broadcast_targets entry references a channel-table slot by channel_index instead — see + broadcast_targets entry references a channel-table slot by channel_index instead - see BroadcastTarget. The two paths are equal, first-class options; only this representation differs. */ bool has_broadcast_on_channel; meshtastic_ChannelSettings broadcast_on_channel; @@ -514,7 +514,7 @@ typedef struct _meshtastic_ModuleConfig_MeshBeaconConfig { each temporarily switching the radio to that entry's preset/region/channel. When empty, the broadcaster uses the scalar broadcast_on_preset / broadcast_on_region / broadcast_on_channel fields instead (the single-target path). - Single- and multi-target are equal, first-class options — neither is preferred or + Single- and multi-target are equal, first-class options - neither is preferred or deprecated. They differ only in how the TX channel is named: broadcast_on_channel embeds a ChannelSettings inline, while a target references an existing channel-table slot by channel_index (see BroadcastTarget). */ From f55a232cc3a8885ee4699684ed4f58e740f55011 Mon Sep 17 00:00:00 2001 From: nomdetom Date: Tue, 14 Jul 2026 02:36:40 +0100 Subject: [PATCH 07/11] userprefs --- userPrefs.jsonc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/userPrefs.jsonc b/userPrefs.jsonc index 43e7336cf03..a132eb90674 100644 --- a/userPrefs.jsonc +++ b/userPrefs.jsonc @@ -19,10 +19,7 @@ // "USERPREFS_CONFIG_GPS_MODE": "meshtastic_Config_PositionConfig_GpsMode_ENABLED", // "USERPREFS_CONFIG_LORA_IGNORE_MQTT": "true", // "USERPREFS_LORA_TX_DISABLED": "1", // If set, forces config.lora.tx_enabled=false during lora bootstrap - // NZ community build: ANZ region defaulting to ShortFast. With the default - // channel name ("ShortFast") the frequency-slot hash lands on slot 16 = - // 918.875 MHz, the New Zealand mesh standard. No channel_num override needed. - "USERPREFS_CONFIG_LORA_REGION": "meshtastic_Config_LoRaConfig_RegionCode_ANZ", + // "USERPREFS_CONFIG_LORA_REGION": "meshtastic_Config_LoRaConfig_RegionCode_US", // "USERPREFS_CONFIG_OWNER_LONG_NAME": "My Long Name", // "USERPREFS_CONFIG_OWNER_SHORT_NAME": "MLN", // "USERPREFS_CONFIG_DEVICE_ROLE": "meshtastic_Config_DeviceConfig_Role_CLIENT", // Defaults to CLIENT. ROUTER*, and LOST AND FOUND roles are restricted. @@ -42,7 +39,7 @@ // "USERPREFS_CONFIG_ENVIRONMENT_MEASUREMENT_ENABLED": "1", // Force BMP280/sensor reads + LoRa broadcast on first boot // "USERPREFS_LORACONFIG_CHANNEL_NUM": "31", // "USERPREFS_LORACONFIG_TX_POWER": "0", - "USERPREFS_LORACONFIG_MODEM_PRESET": "meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST", + // "USERPREFS_LORACONFIG_MODEM_PRESET": "meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST", // "USERPREFS_USE_ADMIN_KEY_0": "{ 0xcd, 0xc0, 0xb4, 0x3c, 0x53, 0x24, 0xdf, 0x13, 0xca, 0x5a, 0xa6, 0x0c, 0x0d, 0xec, 0x85, 0x5a, 0x4c, 0xf6, 0x1a, 0x96, 0x04, 0x1a, 0x3e, 0xfc, 0xbb, 0x8e, 0x33, 0x71, 0xe5, 0xfc, 0xff, 0x3c }", // "USERPREFS_USE_ADMIN_KEY_1": "{}", // "USERPREFS_USE_ADMIN_KEY_2": "{}", From 2b35ced922b75fe56050b757c56570ed487760b7 Mon Sep 17 00:00:00 2001 From: nomdetom Date: Tue, 14 Jul 2026 02:48:14 +0100 Subject: [PATCH 08/11] bufs --- protobufs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protobufs b/protobufs index a0ed789681a..341b5af67a1 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit a0ed789681adee29fdca69213ade31fb8c77fe65 +Subproject commit 341b5af67a12118a70de03731b6a3d307c8ec6ca From e7ba9e959554a6010750ded0040c71205b5e95dd Mon Sep 17 00:00:00 2001 From: nomdetom Date: Tue, 14 Jul 2026 13:03:17 +0100 Subject: [PATCH 09/11] sensible name change --- protobufs | 2 +- src/mesh/RadioInterface.cpp | 2 +- src/mesh/generated/meshtastic/config.pb.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/protobufs b/protobufs index 341b5af67a1..b942055bb28 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 341b5af67a12118a70de03731b6a3d307c8ec6ca +Subproject commit b942055bb28cbbb97f644c81112313cd740e764b diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 80c59121132..4d43f37713c 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -139,7 +139,7 @@ const RegionInfo regions[] = { Same band as ANZ, for New Zealand nodes wanting ShortFast as their default preset instead of LongFast. https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf */ - RDEF(NZ_924, 915.0f, 928.0f, 100, 30, false, false, PROFILE_STD, PRESET(SHORT_FAST), 0), + RDEF(NZ_915, 915.0f, 928.0f, 100, 30, false, false, PROFILE_STD, PRESET(SHORT_FAST), 0), /* 433.05 - 434.79 MHz, 25mW EIRP max, No duty cycle restrictions diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index d7275e11497..088bfbecd4d 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -316,7 +316,7 @@ typedef enum _meshtastic_Config_LoRaConfig_RegionCode { meshtastic_Config_LoRaConfig_RegionCode_ITU2_125CM = 37, /* New Zealand 924MHz Same band as ANZ, for use with the Short Fast modem preset */ - meshtastic_Config_LoRaConfig_RegionCode_NZ_924 = 38 + meshtastic_Config_LoRaConfig_RegionCode_NZ_915 = 38 } meshtastic_Config_LoRaConfig_RegionCode; /* Standard predefined channel settings @@ -770,8 +770,8 @@ extern "C" { #define _meshtastic_Config_DisplayConfig_CompassOrientation_ARRAYSIZE ((meshtastic_Config_DisplayConfig_CompassOrientation)(meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED+1)) #define _meshtastic_Config_LoRaConfig_RegionCode_MIN meshtastic_Config_LoRaConfig_RegionCode_UNSET -#define _meshtastic_Config_LoRaConfig_RegionCode_MAX meshtastic_Config_LoRaConfig_RegionCode_NZ_924 -#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_NZ_924+1)) +#define _meshtastic_Config_LoRaConfig_RegionCode_MAX meshtastic_Config_LoRaConfig_RegionCode_NZ_915 +#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_NZ_915+1)) #define _meshtastic_Config_LoRaConfig_ModemPreset_MIN meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST #define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_TURBO From 8f11f346eb0b4c38c96d116e211be3b5ace230fd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 13:11:51 +0100 Subject: [PATCH 10/11] Update protobufs (#25) Co-authored-by: NomDeTom <116762865+NomDeTom@users.noreply.github.com> --- src/mesh/generated/meshtastic/admin.pb.h | 6 +- src/mesh/generated/meshtastic/atak.pb.h | 46 +-- src/mesh/generated/meshtastic/config.pb.h | 2 +- .../generated/meshtastic/interdevice.pb.cpp | 26 +- .../generated/meshtastic/interdevice.pb.h | 379 +++++++++++++++--- src/mesh/generated/meshtastic/mesh.pb.h | 18 +- .../generated/meshtastic/mesh_beacon.pb.h | 2 +- .../generated/meshtastic/module_config.pb.h | 4 +- 8 files changed, 394 insertions(+), 89 deletions(-) diff --git a/src/mesh/generated/meshtastic/admin.pb.h b/src/mesh/generated/meshtastic/admin.pb.h index 4c00a568cf0..38829148781 100644 --- a/src/mesh/generated/meshtastic/admin.pb.h +++ b/src/mesh/generated/meshtastic/admin.pb.h @@ -186,7 +186,7 @@ typedef struct _meshtastic_LockdownAuth { token at unlock time: the client-supplied boots_remaining when non-zero, otherwise the firmware default (TOKEN_DEFAULT_BOOTS). Note that boots_remaining == 0 in this message means "use firmware - default", NOT "zero boots" - a client computing the ceiling for + default", NOT "zero boots" — a client computing the ceiling for display should mirror that resolution rather than multiplying the raw request value. @@ -196,7 +196,7 @@ typedef struct _meshtastic_LockdownAuth { Uses millis() (CPU uptime), not wall-clock time, so the cap is immune to GPS spoofing, RTC backup-battery removal, and Faraday - cage isolation - none of those move the uptime counter. The only + cage isolation — none of those move the uptime counter. The only way to reset the session clock is a reboot, which costs a boot from the on-flash, HMAC-bound counter. */ uint32_t max_session_seconds; @@ -213,7 +213,7 @@ typedef struct _meshtastic_LockdownAuth { NOT reversed by this operation: APPROTECT. Once the debug port lockout has been burned (on silicon where it is effective) it is - permanent - disabling lockdown decrypts your data and removes the + permanent — disabling lockdown decrypts your data and removes the access gates, but the SWD/JTAG port stays locked for the life of the device (recoverable only via a full chip erase over a debug probe, which destroys all data). Clients should make this diff --git a/src/mesh/generated/meshtastic/atak.pb.h b/src/mesh/generated/meshtastic/atak.pb.h index e0dab865904..6ea298f9ed7 100644 --- a/src/mesh/generated/meshtastic/atak.pb.h +++ b/src/mesh/generated/meshtastic/atak.pb.h @@ -332,7 +332,7 @@ typedef enum _meshtastic_CotType { /* y-: TAKTALK room/membership broadcast. Payload carried via the TakTalkRoomData typed variant (sender_callsign, room_id, room_name, participants). The CoT type literally has a trailing dash and no - second atom - not a typo. */ + second atom — not a typo. */ meshtastic_CotType_CotType_y = 126 } meshtastic_CotType; @@ -380,7 +380,7 @@ typedef enum _meshtastic_DrawnShape_Kind { /* u-r-b-bullseye: Bullseye ring with range rings and bearing reference */ meshtastic_DrawnShape_Kind_Kind_Bullseye = 7, /* u-d-c-e: Ellipse with distinct major/minor axes (same storage as - Kind_Circle - uses major_cm/minor_cm/angle_deg - but receivers + Kind_Circle — uses major_cm/minor_cm/angle_deg — but receivers render it as a non-circular ellipse rather than a round circle). */ meshtastic_DrawnShape_Kind_Kind_Ellipse = 8, /* u-d-v: 2D vehicle outline drawn on the map. Vertices carry the @@ -400,7 +400,7 @@ typedef enum _meshtastic_DrawnShape_Kind { end of parse; builder uses it to decide which of / to emit in the reconstructed XML. */ typedef enum _meshtastic_DrawnShape_StyleMode { - /* Unspecified - receiver infers from which color fields are non-zero. */ + /* Unspecified — receiver infers from which color fields are non-zero. */ meshtastic_DrawnShape_StyleMode_StyleMode_Unspecified = 0, /* Stroke only. No in the source XML. Used for polylines, ranging lines, bullseye rings. */ @@ -417,7 +417,7 @@ typedef enum _meshtastic_DrawnShape_StyleMode { alone is ambiguous (e.g. a-u-G could be a 2525 symbol or a custom icon depending on the iconset path). */ typedef enum _meshtastic_Marker_Kind { - /* Unspecified - fall back to TAKPacketV2.cot_type_id */ + /* Unspecified — fall back to TAKPacketV2.cot_type_id */ meshtastic_Marker_Kind_Kind_Unspecified = 0, /* b-m-p-s-m: Spot map marker */ meshtastic_Marker_Kind_Kind_Spot = 1, @@ -680,10 +680,10 @@ typedef struct _meshtastic_AircraftTrack { hundred meters of the anchor has per-vertex deltas in the ±10^4 range. Under sint32+zigzag those encode as 2 bytes each (tag+varint), versus the 4 bytes that sfixed32 would always require. At 32 vertices that is ~128 - bytes of savings - the difference between fitting under the LoRa MTU or + bytes of savings — the difference between fitting under the LoRa MTU or not. Absolute coordinates (values ~10^9) would cost sint32 varint 5 bytes per field, which is why TAKPacketV2's top-level latitude_i / longitude_i - stay sfixed32 - only small values win with sint32. */ + stay sfixed32 — only small values win with sint32. */ typedef struct _meshtastic_CotGeoPoint { /* Latitude delta from TAKPacketV2.latitude_i, in 1e-7 degree units. Add to the enclosing event's latitude_i to recover the absolute latitude. */ @@ -791,7 +791,7 @@ typedef struct _meshtastic_Marker { Covers CoT type u-rb-a. The anchor position is on TAKPacketV2.latitude_i/longitude_i; the target endpoint is carried as a - CotGeoPoint - same delta-from-anchor encoding used by DrawnShape.vertices + CotGeoPoint — same delta-from-anchor encoding used by DrawnShape.vertices so a self-anchored RAB (common case) encodes in zero bytes. */ typedef struct _meshtastic_RangeAndBearing { /* Target/anchor endpoint (delta-encoded from TAKPacketV2.latitude_i/longitude_i). */ @@ -899,12 +899,12 @@ typedef struct _meshtastic_CasevacReport { same as the envelope callsign but ATAK sometimes carries a distinct ops-number here. */ pb_callback_t title; - /* Primary medline free-text - the single most clinically important line + /* Primary medline free-text — the single most clinically important line on a MEDLINE form (e.g. "2 urgent litter patients, smoke on approach"). MUST be preserved under MTU pressure as long as any casevac is sent. */ pb_callback_t medline_remarks; /* Line 3 (newer ATAK format): patient counts by precedence level. - Coexists with the enum-style `precedence` field (tag 1) - older ATAK + Coexists with the enum-style `precedence` field (tag 1) — older ATAK emits a single enum, newer ATAK emits these counts, and both can be set simultaneously. Senders populate whichever style(s) the source XML had; receivers prefer counts when non-zero. */ @@ -946,19 +946,19 @@ typedef struct _meshtastic_CasevacReport { (e.g. "Primary HLZ is soccer field"). */ pb_callback_t hlz_remarks; /* Per-patient clinical records. Each entry is one patient's ZMIST card - (Zap number / Mechanism / Injuries / Signs / Treatment). Repeatable - + (Zap number / Mechanism / Injuries / Signs / Treatment). Repeatable — a mass-casualty event can carry 1-6 entries in practice, limited by the 237 B LoRa MTU. */ pb_callback_t zmist; } meshtastic_CasevacReport; -/* Per-patient clinical summary record - one entry per patient in a CASEVAC. +/* Per-patient clinical summary record — one entry per patient in a CASEVAC. Maps directly to ATAK's child element inside . All fields are optional free-text; senders populate what they have. */ typedef struct _meshtastic_ZMistEntry { /* Patient identifier / sequence label (e.g. "ZMIST-1", "ZMIST-2"). */ pb_callback_t title; - /* Zap number - unique patient tracking ID (often a terse code like + /* Zap number — unique patient tracking ID (often a terse code like "Gunshot" or a serial). */ pb_callback_t z; /* Mechanism of injury (e.g. "Penetrating trauma", "Blast injury"). */ @@ -997,7 +997,7 @@ typedef struct _meshtastic_EmergencyAlert { creation time; the fields below carry structured metadata the raw-detail fallback currently loses. - Fields are deliberately lean - this variant is closer to the MTU ceiling + Fields are deliberately lean — this variant is closer to the MTU ceiling than the others, so every string is capped in options. */ typedef struct _meshtastic_TaskRequest { /* Short tag for the task category (e.g. "engage", "observe", "recon", @@ -1017,7 +1017,7 @@ typedef struct _meshtastic_TaskRequest { /* Weather annotation from CoT detail element. - Attaches to any TAKPacketV2 regardless of payload_variant - an Aircraft, + Attaches to any TAKPacketV2 regardless of payload_variant — an Aircraft, PLI, or Marker can all carry observed conditions at the emitting station. ATAK-CIV ships an XSD for but no dedicated handler, so the element round-trips through the generic detail pipeline; this message @@ -1026,7 +1026,7 @@ typedef struct _meshtastic_TaskRequest { Target wire cost: ~6-8 bytes compressed with a fully populated instance. Named `TAKEnvironment` (not just `Environment`) because the bare name - collides with `SwiftUI.Environment` - every SwiftUI view in a consuming + collides with `SwiftUI.Environment` — every SwiftUI view in a consuming iOS app uses the `@Environment` property wrapper, and importing the generated proto module would make `Environment` ambiguous in every one of those files. The `TAK` prefix matches the convention used by the @@ -1055,7 +1055,7 @@ typedef struct _meshtastic_TAKEnvironment { The receiving ATAK client restores those from its own defaults, same as every other CoT carried over Meshtastic today. - Attaches to any TAKPacketV2 - a PLI with a sensor on the operator's head, + Attaches to any TAKPacketV2 — a PLI with a sensor on the operator's head, an Aircraft with a FLIR turret, a Marker dropped on a UAV. Target wire cost: ~7-14 bytes compressed (dominated by model string). */ typedef struct _meshtastic_SensorFov { @@ -1065,30 +1065,30 @@ typedef struct _meshtastic_SensorFov { SensorDetailHandler default (270°) and save varint bytes over centi-deg. */ uint32_t azimuth_deg; /* Maximum range of the cone in meters. - Optional - if unset, receivers should use the ATAK-CIV default of 100m. */ + Optional — if unset, receivers should use the ATAK-CIV default of 100m. */ bool has_range_m; uint32_t range_m; /* Horizontal field of view in whole degrees (cone's angular width). ATAK-CIV default is 45°. */ uint32_t fov_horizontal_deg; /* Vertical field of view in whole degrees. ATAK-CIV default is 45°. - Optional - a value of 0 means "not set / use horizontal FOV". */ + Optional — a value of 0 means "not set / use horizontal FOV". */ uint32_t fov_vertical_deg; /* Elevation angle in whole degrees. Positive = up, negative = down. Range -90 to +90. sint32 for varint efficiency on small negatives. */ int32_t elevation_deg; /* Roll (camera tilt) in whole degrees, -180 to +180. - Optional - use 0 if the sensor doesn't track roll. */ + Optional — use 0 if the sensor doesn't track roll. */ int32_t roll_deg; /* Free-form device model identifier, e.g. "FLIR-Boson-640", "SEEK". - Optional - empty string means "unknown model" (ATAK-CIV default). */ + Optional — empty string means "unknown model" (ATAK-CIV default). */ pb_callback_t model; } meshtastic_SensorFov; /* TAKTALK chat message payload (CoT type m-t-t). TAKTALK is an ATAK plugin for voice + text team messaging. The voice - audio stream goes over UDP/RTP and is NOT carried by the mesh - only + audio stream goes over UDP/RTP and is NOT carried by the mesh — only the text envelope (this message) is. `from_voice` marks messages sent via push-to-talk speech-to-text so receivers can render a mic icon next to the text. @@ -1122,7 +1122,7 @@ typedef struct _meshtastic_TakTalkMessage { Announces a TAKTALK chatroom's friendly name and roster so peers can resolve room UUIDs (used in TakTalkMessage.chatroom_id and GeoChat.room_id) to a display name and participant list. Not a chat - message itself - these events are emitted by TAKTALK when rooms are + message itself — these events are emitted by TAKTALK when rooms are created or memberships change. */ typedef struct _meshtastic_TakTalkRoomData { /* Callsign of the device broadcasting the room state (typically the @@ -1161,7 +1161,7 @@ typedef struct _meshtastic_Marti { primary-vs-cc distinction the same way ATAK does. If dest_callsign is [TAKPacketV2.callsign] (self-addressed, unusual but - legal - e.g. ATAK echoing back to its own room), the builder still emits + legal — e.g. ATAK echoing back to its own room), the builder still emits the element so loopback shapes round-trip cleanly. */ pb_callback_t dest_callsign; } meshtastic_Marti; diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index 088bfbecd4d..2093965b77e 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -314,7 +314,7 @@ typedef enum _meshtastic_Config_LoRaConfig_RegionCode { Note: Some countries do not allocate 220-222 MHz (Ex: USA/Canada). Check local law! */ meshtastic_Config_LoRaConfig_RegionCode_ITU2_125CM = 37, - /* New Zealand 924MHz + /* New Zealand 915MHz-928MHz Same band as ANZ, for use with the Short Fast modem preset */ meshtastic_Config_LoRaConfig_RegionCode_NZ_915 = 38 } meshtastic_Config_LoRaConfig_RegionCode; diff --git a/src/mesh/generated/meshtastic/interdevice.pb.cpp b/src/mesh/generated/meshtastic/interdevice.pb.cpp index e3913f78c9d..208fae22049 100644 --- a/src/mesh/generated/meshtastic/interdevice.pb.cpp +++ b/src/mesh/generated/meshtastic/interdevice.pb.cpp @@ -6,10 +6,32 @@ #error Regenerate this file with the current version of nanopb generator. #endif -PB_BIND(meshtastic_SensorData, meshtastic_SensorData, AUTO) +PB_BIND(meshtastic_FileTransfer, meshtastic_FileTransfer, 4) + + +PB_BIND(meshtastic_DirectoryListing, meshtastic_DirectoryListing, 4) + + +PB_BIND(meshtastic_I2CTransaction, meshtastic_I2CTransaction, 2) + + +PB_BIND(meshtastic_SdCardInfo, meshtastic_SdCardInfo, AUTO) + + +PB_BIND(meshtastic_I2CResult, meshtastic_I2CResult, 2) + + +PB_BIND(meshtastic_InterdeviceMessage, meshtastic_InterdeviceMessage, 4) + + + + + + + + -PB_BIND(meshtastic_InterdeviceMessage, meshtastic_InterdeviceMessage, 2) diff --git a/src/mesh/generated/meshtastic/interdevice.pb.h b/src/mesh/generated/meshtastic/interdevice.pb.h index c381438ebe6..bf4c28c2309 100644 --- a/src/mesh/generated/meshtastic/interdevice.pb.h +++ b/src/mesh/generated/meshtastic/interdevice.pb.h @@ -10,38 +10,178 @@ #endif /* Enum definitions */ -typedef enum _meshtastic_MessageType { - meshtastic_MessageType_ACK = 0, - meshtastic_MessageType_COLLECT_INTERVAL = 160, /* in ms */ - meshtastic_MessageType_BEEP_ON = 161, /* duration ms */ - meshtastic_MessageType_BEEP_OFF = 162, /* cancel prematurely */ - meshtastic_MessageType_SHUTDOWN = 163, - meshtastic_MessageType_POWER_ON = 164, - meshtastic_MessageType_SCD41_TEMP = 176, - meshtastic_MessageType_SCD41_HUMIDITY = 177, - meshtastic_MessageType_SCD41_CO2 = 178, - meshtastic_MessageType_AHT20_TEMP = 179, - meshtastic_MessageType_AHT20_HUMIDITY = 180, - meshtastic_MessageType_TVOC_INDEX = 181 -} meshtastic_MessageType; +/* Version of the interdevice protocol spoken on the link. Both sides send + theirs in the ping/pong handshake; a peer reporting a different one runs + firmware that does not match and is not talked to. + + On a change that breaks the other side (renumbered fields, changed + semantics, removed messages), raise the value of CURRENT. Do not add + another entry: this enum carries a single constant, not a history. */ +typedef enum _meshtastic_InterdeviceVersion { + meshtastic_InterdeviceVersion_INTERDEVICE_VERSION_UNSPECIFIED = 0, + /* Never use 1: ping/pong were bools before the handshake existed, and a + bool true is the same varint on the wire as the number 1, so firmware + predating the handshake would pass it. */ + meshtastic_InterdeviceVersion_INTERDEVICE_VERSION_CURRENT = 2 +} meshtastic_InterdeviceVersion; + +/* Defines the supported file operations */ +typedef enum _meshtastic_FileOperation { + meshtastic_FileOperation_GET = 0, + meshtastic_FileOperation_POST = 1, + meshtastic_FileOperation_PUT = 2, + meshtastic_FileOperation_DELETE = 3 +} meshtastic_FileOperation; + +/* Outcome of a file or directory operation. The requester must be able to + tell a transient condition from a definitive one: BUSY is worth another + try, NOT_FOUND is not. */ +typedef enum _meshtastic_FileStatus { + meshtastic_FileStatus_FILE_UNSPECIFIED = 0, + meshtastic_FileStatus_FILE_OK = 1, + /* Retry later: the co-processor is doing card maintenance (mount, + free space scan) and cannot serve the request right now */ + meshtastic_FileStatus_FILE_BUSY = 2, + meshtastic_FileStatus_FILE_NO_CARD = 3, + meshtastic_FileStatus_FILE_NOT_FOUND = 4, + /* PUT only: offset did not match the current end of the file. file_size + carries the size the file actually has, so the writer can resync (or + recognize its own chunk as already written after a lost response). */ + meshtastic_FileStatus_FILE_OFFSET_CONFLICT = 5, + meshtastic_FileStatus_FILE_IO_ERROR = 6, + meshtastic_FileStatus_FILE_NOT_A_FILE = 7 /* path is a directory (GET) or not one (listing) */ +} meshtastic_FileStatus; + +typedef enum _meshtastic_SdCardInfo_CardType { + meshtastic_SdCardInfo_CardType_NONE = 0, + meshtastic_SdCardInfo_CardType_MMC = 1, + meshtastic_SdCardInfo_CardType_SD = 2, + meshtastic_SdCardInfo_CardType_SDHC = 3, + meshtastic_SdCardInfo_CardType_SDXC = 4, + meshtastic_SdCardInfo_CardType_UNKNOWN_CARD = 5 +} meshtastic_SdCardInfo_CardType; + +typedef enum _meshtastic_SdCardInfo_FatType { + meshtastic_SdCardInfo_FatType_UNKNOWN_FAT = 0, + meshtastic_SdCardInfo_FatType_FAT16 = 1, + meshtastic_SdCardInfo_FatType_FAT32 = 2, + meshtastic_SdCardInfo_FatType_EXFAT = 3 +} meshtastic_SdCardInfo_FatType; + +typedef enum _meshtastic_I2CResult_Status { + /* Never sent: an all-defaults (e.g. accidentally empty) message must + not decode as a successful transaction */ + meshtastic_I2CResult_Status_UNSPECIFIED = 0, + meshtastic_I2CResult_Status_OK = 1, + meshtastic_I2CResult_Status_NACK_ADDRESS = 2, + meshtastic_I2CResult_Status_NACK_DATA = 3, + meshtastic_I2CResult_Status_ERROR = 4 +} meshtastic_I2CResult_Status; /* Struct definitions */ -typedef struct _meshtastic_SensorData { - /* The message type */ - meshtastic_MessageType type; - pb_size_t which_data; - union { - float float_value; - uint32_t uint32_value; - } data; -} meshtastic_SensorData; +typedef PB_BYTES_ARRAY_T(4096) meshtastic_FileTransfer_filedata_t; +/* Message for file operations */ +typedef struct _meshtastic_FileTransfer { + meshtastic_FileOperation operation; /* File operation (GET, POST, PUT, DELETE) */ + char filepath[256]; /* Path of the file on the SD card */ + meshtastic_FileTransfer_filedata_t filedata; /* Chunk content (POST/PUT request, GET response) */ + meshtastic_FileStatus status; /* Response: outcome of the operation */ + char message[255]; /* Response: human readable detail, may be empty */ + uint64_t offset; /* Byte offset of this chunk within the file (ranged GET/PUT) */ + /* GET request: number of bytes to read, 0 = max chunk size. A response + carries at most the filedata max_size (see interdevice.options) per + chunk; larger requests are truncated, visible in the filedata length. */ + uint32_t length; + uint64_t file_size; /* GET response: total size of the file */ +} meshtastic_FileTransfer; + +/* Message for structured directory listing */ +typedef struct _meshtastic_DirectoryListing { + char directory[256]; /* Path of the directory */ + /* One page of entry names, full FAT LFN length. Subdirectories carry a + trailing slash. Note that a name whose directory prefix pushes the + combined path past the FileTransfer.filepath limit cannot round-trip. + Page size is the max_count in interdevice.options; page through with + offset and total_count. */ + pb_size_t filenames_count; + char filenames[16][256]; + meshtastic_FileStatus status; /* Response: outcome of the operation */ + char message[255]; /* Response: human readable detail, may be empty */ + uint32_t offset; /* Request: skip this many entries (paging) */ + uint32_t total_count; /* Response: total number of entries in the directory */ +} meshtastic_DirectoryListing; + +typedef PB_BYTES_ARRAY_T(256) meshtastic_I2CTransaction_write_data_t; +/* A single I2C transaction: an optional write followed by an optional + read with repeated start, matching the TwoWire usage of sensor drivers + (beginTransmission/write.../endTransmission(false)/requestFrom) */ +typedef struct _meshtastic_I2CTransaction { + uint32_t address; /* 7-bit device address */ + meshtastic_I2CTransaction_write_data_t write_data; /* Bytes to write, may be empty */ + /* Number of bytes to read after the write, 0 = write-only. Bounded by + the read_data max_size of I2CResult (see interdevice.options); larger + requests are truncated, visible in the returned byte count. */ + uint32_t read_len; +} meshtastic_I2CTransaction; + +/* SD card statistics */ +typedef struct _meshtastic_SdCardInfo { + /* Card initialized and usable. False while `busy` is set does not mean + there is no card: the co-processor does not know yet. */ + bool present; + meshtastic_SdCardInfo_CardType card_type; + meshtastic_SdCardInfo_FatType fat_type; + uint64_t card_size; /* Filesystem size in bytes */ + uint64_t used_bytes; /* Used bytes (may be expensive to compute on FAT32) */ + uint64_t free_bytes; /* Free bytes */ + /* used_bytes/free_bytes are only meaningful when true: the scan behind + them runs in the background after mount and can take a while, and a + full card is otherwise indistinguishable from a scan in progress */ + bool stats_valid; + /* The co-processor is mounting a card right now, so whether one is + present is not decided yet. Ask again rather than concluding the slot + is empty. */ + bool busy; +} meshtastic_SdCardInfo; + +typedef PB_BYTES_ARRAY_T(256) meshtastic_I2CResult_read_data_t; +/* Result of an I2CTransaction */ +typedef struct _meshtastic_I2CResult { + meshtastic_I2CResult_Status status; + meshtastic_I2CResult_read_data_t read_data; /* Data read from the device, empty for write-only transactions */ +} meshtastic_I2CResult; +typedef PB_BYTES_ARRAY_T(128) meshtastic_InterdeviceMessage_i2c_scan_result_t; +/* Main message for interdevice communication */ typedef struct _meshtastic_InterdeviceMessage { pb_size_t which_data; union { char nmea[1024]; - meshtastic_SensorData sensor; + uint16_t beep; + meshtastic_I2CTransaction i2c_transaction; + meshtastic_I2CResult i2c_result; + bool i2c_scan; /* Request: scan the secondary I2C bus */ + meshtastic_InterdeviceMessage_i2c_scan_result_t i2c_scan_result; /* Response: 7-bit addresses of discovered devices */ + meshtastic_FileTransfer file_transfer; + meshtastic_DirectoryListing directory_listing; + bool get_sd_info; /* Request: SD card statistics */ + meshtastic_SdCardInfo sd_info; /* Response */ + /* Link liveness probe and version handshake. The receiver answers ping + with pong, echoing the id. Touches no peripherals, so it works with + nothing attached. Both carry the version the sender speaks; a peer + that answers with a different one speaks another protocol and must + not be used. */ + meshtastic_InterdeviceVersion ping; + meshtastic_InterdeviceVersion pong; + /* Response: the request could not be decoded or is of an unhandled + type, so the requester fails fast instead of burning its timeout. + Echoes the id when known, 0 when the frame was undecodable. Never + sent in reaction to a nack. */ + bool nack; } data; + /* Correlates a response with its request: responses echo the id of the + request they answer. 0 for unsolicited messages (e.g. the nmea stream). */ + uint32_t id; } meshtastic_InterdeviceMessage; @@ -50,53 +190,196 @@ extern "C" { #endif /* Helper constants for enums */ -#define _meshtastic_MessageType_MIN meshtastic_MessageType_ACK -#define _meshtastic_MessageType_MAX meshtastic_MessageType_TVOC_INDEX -#define _meshtastic_MessageType_ARRAYSIZE ((meshtastic_MessageType)(meshtastic_MessageType_TVOC_INDEX+1)) +#define _meshtastic_InterdeviceVersion_MIN meshtastic_InterdeviceVersion_INTERDEVICE_VERSION_UNSPECIFIED +#define _meshtastic_InterdeviceVersion_MAX meshtastic_InterdeviceVersion_INTERDEVICE_VERSION_CURRENT +#define _meshtastic_InterdeviceVersion_ARRAYSIZE ((meshtastic_InterdeviceVersion)(meshtastic_InterdeviceVersion_INTERDEVICE_VERSION_CURRENT+1)) -#define meshtastic_SensorData_type_ENUMTYPE meshtastic_MessageType +#define _meshtastic_FileOperation_MIN meshtastic_FileOperation_GET +#define _meshtastic_FileOperation_MAX meshtastic_FileOperation_DELETE +#define _meshtastic_FileOperation_ARRAYSIZE ((meshtastic_FileOperation)(meshtastic_FileOperation_DELETE+1)) +#define _meshtastic_FileStatus_MIN meshtastic_FileStatus_FILE_UNSPECIFIED +#define _meshtastic_FileStatus_MAX meshtastic_FileStatus_FILE_NOT_A_FILE +#define _meshtastic_FileStatus_ARRAYSIZE ((meshtastic_FileStatus)(meshtastic_FileStatus_FILE_NOT_A_FILE+1)) + +#define _meshtastic_SdCardInfo_CardType_MIN meshtastic_SdCardInfo_CardType_NONE +#define _meshtastic_SdCardInfo_CardType_MAX meshtastic_SdCardInfo_CardType_UNKNOWN_CARD +#define _meshtastic_SdCardInfo_CardType_ARRAYSIZE ((meshtastic_SdCardInfo_CardType)(meshtastic_SdCardInfo_CardType_UNKNOWN_CARD+1)) + +#define _meshtastic_SdCardInfo_FatType_MIN meshtastic_SdCardInfo_FatType_UNKNOWN_FAT +#define _meshtastic_SdCardInfo_FatType_MAX meshtastic_SdCardInfo_FatType_EXFAT +#define _meshtastic_SdCardInfo_FatType_ARRAYSIZE ((meshtastic_SdCardInfo_FatType)(meshtastic_SdCardInfo_FatType_EXFAT+1)) + +#define _meshtastic_I2CResult_Status_MIN meshtastic_I2CResult_Status_UNSPECIFIED +#define _meshtastic_I2CResult_Status_MAX meshtastic_I2CResult_Status_ERROR +#define _meshtastic_I2CResult_Status_ARRAYSIZE ((meshtastic_I2CResult_Status)(meshtastic_I2CResult_Status_ERROR+1)) + +#define meshtastic_FileTransfer_operation_ENUMTYPE meshtastic_FileOperation +#define meshtastic_FileTransfer_status_ENUMTYPE meshtastic_FileStatus + +#define meshtastic_DirectoryListing_status_ENUMTYPE meshtastic_FileStatus + + +#define meshtastic_SdCardInfo_card_type_ENUMTYPE meshtastic_SdCardInfo_CardType +#define meshtastic_SdCardInfo_fat_type_ENUMTYPE meshtastic_SdCardInfo_FatType + +#define meshtastic_I2CResult_status_ENUMTYPE meshtastic_I2CResult_Status + +#define meshtastic_InterdeviceMessage_data_ping_ENUMTYPE meshtastic_InterdeviceVersion +#define meshtastic_InterdeviceMessage_data_pong_ENUMTYPE meshtastic_InterdeviceVersion /* Initializer values for message structs */ -#define meshtastic_SensorData_init_default {_meshtastic_MessageType_MIN, 0, {0}} -#define meshtastic_InterdeviceMessage_init_default {0, {""}} -#define meshtastic_SensorData_init_zero {_meshtastic_MessageType_MIN, 0, {0}} -#define meshtastic_InterdeviceMessage_init_zero {0, {""}} +#define meshtastic_FileTransfer_init_default {_meshtastic_FileOperation_MIN, "", {0, {0}}, _meshtastic_FileStatus_MIN, "", 0, 0, 0} +#define meshtastic_DirectoryListing_init_default {"", 0, {"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}, _meshtastic_FileStatus_MIN, "", 0, 0} +#define meshtastic_I2CTransaction_init_default {0, {0, {0}}, 0} +#define meshtastic_SdCardInfo_init_default {0, _meshtastic_SdCardInfo_CardType_MIN, _meshtastic_SdCardInfo_FatType_MIN, 0, 0, 0, 0, 0} +#define meshtastic_I2CResult_init_default {_meshtastic_I2CResult_Status_MIN, {0, {0}}} +#define meshtastic_InterdeviceMessage_init_default {0, {""}, 0} +#define meshtastic_FileTransfer_init_zero {_meshtastic_FileOperation_MIN, "", {0, {0}}, _meshtastic_FileStatus_MIN, "", 0, 0, 0} +#define meshtastic_DirectoryListing_init_zero {"", 0, {"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}, _meshtastic_FileStatus_MIN, "", 0, 0} +#define meshtastic_I2CTransaction_init_zero {0, {0, {0}}, 0} +#define meshtastic_SdCardInfo_init_zero {0, _meshtastic_SdCardInfo_CardType_MIN, _meshtastic_SdCardInfo_FatType_MIN, 0, 0, 0, 0, 0} +#define meshtastic_I2CResult_init_zero {_meshtastic_I2CResult_Status_MIN, {0, {0}}} +#define meshtastic_InterdeviceMessage_init_zero {0, {""}, 0} /* Field tags (for use in manual encoding/decoding) */ -#define meshtastic_SensorData_type_tag 1 -#define meshtastic_SensorData_float_value_tag 2 -#define meshtastic_SensorData_uint32_value_tag 3 +#define meshtastic_FileTransfer_operation_tag 1 +#define meshtastic_FileTransfer_filepath_tag 2 +#define meshtastic_FileTransfer_filedata_tag 3 +#define meshtastic_FileTransfer_status_tag 4 +#define meshtastic_FileTransfer_message_tag 5 +#define meshtastic_FileTransfer_offset_tag 6 +#define meshtastic_FileTransfer_length_tag 7 +#define meshtastic_FileTransfer_file_size_tag 8 +#define meshtastic_DirectoryListing_directory_tag 1 +#define meshtastic_DirectoryListing_filenames_tag 2 +#define meshtastic_DirectoryListing_status_tag 3 +#define meshtastic_DirectoryListing_message_tag 4 +#define meshtastic_DirectoryListing_offset_tag 5 +#define meshtastic_DirectoryListing_total_count_tag 6 +#define meshtastic_I2CTransaction_address_tag 1 +#define meshtastic_I2CTransaction_write_data_tag 2 +#define meshtastic_I2CTransaction_read_len_tag 3 +#define meshtastic_SdCardInfo_present_tag 1 +#define meshtastic_SdCardInfo_card_type_tag 2 +#define meshtastic_SdCardInfo_fat_type_tag 3 +#define meshtastic_SdCardInfo_card_size_tag 4 +#define meshtastic_SdCardInfo_used_bytes_tag 5 +#define meshtastic_SdCardInfo_free_bytes_tag 6 +#define meshtastic_SdCardInfo_stats_valid_tag 7 +#define meshtastic_SdCardInfo_busy_tag 8 +#define meshtastic_I2CResult_status_tag 1 +#define meshtastic_I2CResult_read_data_tag 2 #define meshtastic_InterdeviceMessage_nmea_tag 1 -#define meshtastic_InterdeviceMessage_sensor_tag 2 +#define meshtastic_InterdeviceMessage_beep_tag 2 +#define meshtastic_InterdeviceMessage_i2c_transaction_tag 3 +#define meshtastic_InterdeviceMessage_i2c_result_tag 4 +#define meshtastic_InterdeviceMessage_i2c_scan_tag 5 +#define meshtastic_InterdeviceMessage_i2c_scan_result_tag 6 +#define meshtastic_InterdeviceMessage_file_transfer_tag 7 +#define meshtastic_InterdeviceMessage_directory_listing_tag 8 +#define meshtastic_InterdeviceMessage_get_sd_info_tag 9 +#define meshtastic_InterdeviceMessage_sd_info_tag 10 +#define meshtastic_InterdeviceMessage_ping_tag 11 +#define meshtastic_InterdeviceMessage_pong_tag 12 +#define meshtastic_InterdeviceMessage_nack_tag 13 +#define meshtastic_InterdeviceMessage_id_tag 15 /* Struct field encoding specification for nanopb */ -#define meshtastic_SensorData_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UENUM, type, 1) \ -X(a, STATIC, ONEOF, FLOAT, (data,float_value,data.float_value), 2) \ -X(a, STATIC, ONEOF, UINT32, (data,uint32_value,data.uint32_value), 3) -#define meshtastic_SensorData_CALLBACK NULL -#define meshtastic_SensorData_DEFAULT NULL +#define meshtastic_FileTransfer_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UENUM, operation, 1) \ +X(a, STATIC, SINGULAR, STRING, filepath, 2) \ +X(a, STATIC, SINGULAR, BYTES, filedata, 3) \ +X(a, STATIC, SINGULAR, UENUM, status, 4) \ +X(a, STATIC, SINGULAR, STRING, message, 5) \ +X(a, STATIC, SINGULAR, UINT64, offset, 6) \ +X(a, STATIC, SINGULAR, UINT32, length, 7) \ +X(a, STATIC, SINGULAR, UINT64, file_size, 8) +#define meshtastic_FileTransfer_CALLBACK NULL +#define meshtastic_FileTransfer_DEFAULT NULL + +#define meshtastic_DirectoryListing_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, STRING, directory, 1) \ +X(a, STATIC, REPEATED, STRING, filenames, 2) \ +X(a, STATIC, SINGULAR, UENUM, status, 3) \ +X(a, STATIC, SINGULAR, STRING, message, 4) \ +X(a, STATIC, SINGULAR, UINT32, offset, 5) \ +X(a, STATIC, SINGULAR, UINT32, total_count, 6) +#define meshtastic_DirectoryListing_CALLBACK NULL +#define meshtastic_DirectoryListing_DEFAULT NULL + +#define meshtastic_I2CTransaction_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT32, address, 1) \ +X(a, STATIC, SINGULAR, BYTES, write_data, 2) \ +X(a, STATIC, SINGULAR, UINT32, read_len, 3) +#define meshtastic_I2CTransaction_CALLBACK NULL +#define meshtastic_I2CTransaction_DEFAULT NULL + +#define meshtastic_SdCardInfo_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, BOOL, present, 1) \ +X(a, STATIC, SINGULAR, UENUM, card_type, 2) \ +X(a, STATIC, SINGULAR, UENUM, fat_type, 3) \ +X(a, STATIC, SINGULAR, UINT64, card_size, 4) \ +X(a, STATIC, SINGULAR, UINT64, used_bytes, 5) \ +X(a, STATIC, SINGULAR, UINT64, free_bytes, 6) \ +X(a, STATIC, SINGULAR, BOOL, stats_valid, 7) \ +X(a, STATIC, SINGULAR, BOOL, busy, 8) +#define meshtastic_SdCardInfo_CALLBACK NULL +#define meshtastic_SdCardInfo_DEFAULT NULL + +#define meshtastic_I2CResult_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UENUM, status, 1) \ +X(a, STATIC, SINGULAR, BYTES, read_data, 2) +#define meshtastic_I2CResult_CALLBACK NULL +#define meshtastic_I2CResult_DEFAULT NULL #define meshtastic_InterdeviceMessage_FIELDLIST(X, a) \ X(a, STATIC, ONEOF, STRING, (data,nmea,data.nmea), 1) \ -X(a, STATIC, ONEOF, MESSAGE, (data,sensor,data.sensor), 2) +X(a, STATIC, ONEOF, UINT32, (data,beep,data.beep), 2) \ +X(a, STATIC, ONEOF, MESSAGE, (data,i2c_transaction,data.i2c_transaction), 3) \ +X(a, STATIC, ONEOF, MESSAGE, (data,i2c_result,data.i2c_result), 4) \ +X(a, STATIC, ONEOF, BOOL, (data,i2c_scan,data.i2c_scan), 5) \ +X(a, STATIC, ONEOF, BYTES, (data,i2c_scan_result,data.i2c_scan_result), 6) \ +X(a, STATIC, ONEOF, MESSAGE, (data,file_transfer,data.file_transfer), 7) \ +X(a, STATIC, ONEOF, MESSAGE, (data,directory_listing,data.directory_listing), 8) \ +X(a, STATIC, ONEOF, BOOL, (data,get_sd_info,data.get_sd_info), 9) \ +X(a, STATIC, ONEOF, MESSAGE, (data,sd_info,data.sd_info), 10) \ +X(a, STATIC, ONEOF, UENUM, (data,ping,data.ping), 11) \ +X(a, STATIC, ONEOF, UENUM, (data,pong,data.pong), 12) \ +X(a, STATIC, ONEOF, BOOL, (data,nack,data.nack), 13) \ +X(a, STATIC, SINGULAR, UINT32, id, 15) #define meshtastic_InterdeviceMessage_CALLBACK NULL #define meshtastic_InterdeviceMessage_DEFAULT NULL -#define meshtastic_InterdeviceMessage_data_sensor_MSGTYPE meshtastic_SensorData +#define meshtastic_InterdeviceMessage_data_i2c_transaction_MSGTYPE meshtastic_I2CTransaction +#define meshtastic_InterdeviceMessage_data_i2c_result_MSGTYPE meshtastic_I2CResult +#define meshtastic_InterdeviceMessage_data_file_transfer_MSGTYPE meshtastic_FileTransfer +#define meshtastic_InterdeviceMessage_data_directory_listing_MSGTYPE meshtastic_DirectoryListing +#define meshtastic_InterdeviceMessage_data_sd_info_MSGTYPE meshtastic_SdCardInfo -extern const pb_msgdesc_t meshtastic_SensorData_msg; +extern const pb_msgdesc_t meshtastic_FileTransfer_msg; +extern const pb_msgdesc_t meshtastic_DirectoryListing_msg; +extern const pb_msgdesc_t meshtastic_I2CTransaction_msg; +extern const pb_msgdesc_t meshtastic_SdCardInfo_msg; +extern const pb_msgdesc_t meshtastic_I2CResult_msg; extern const pb_msgdesc_t meshtastic_InterdeviceMessage_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ -#define meshtastic_SensorData_fields &meshtastic_SensorData_msg +#define meshtastic_FileTransfer_fields &meshtastic_FileTransfer_msg +#define meshtastic_DirectoryListing_fields &meshtastic_DirectoryListing_msg +#define meshtastic_I2CTransaction_fields &meshtastic_I2CTransaction_msg +#define meshtastic_SdCardInfo_fields &meshtastic_SdCardInfo_msg +#define meshtastic_I2CResult_fields &meshtastic_I2CResult_msg #define meshtastic_InterdeviceMessage_fields &meshtastic_InterdeviceMessage_msg /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_INTERDEVICE_PB_H_MAX_SIZE meshtastic_InterdeviceMessage_size -#define meshtastic_InterdeviceMessage_size 1026 -#define meshtastic_SensorData_size 9 +#define meshtastic_DirectoryListing_size 4657 +#define meshtastic_FileTransfer_size 4646 +#define meshtastic_I2CResult_size 261 +#define meshtastic_I2CTransaction_size 271 +#define meshtastic_InterdeviceMessage_size 4666 +#define meshtastic_SdCardInfo_size 43 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index 98798173c85..3020a0f1be3 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -1250,15 +1250,15 @@ typedef struct _meshtastic_LockdownStatus { /* Current lockdown state being reported. */ meshtastic_LockdownStatus_State state; /* For LOCKED: machine-readable reason. Known values: - "needs_auth" - storage already unlocked, client must auth - "token_missing" - no boot token on flash - "token_expired" - boot token wall-clock TTL elapsed - "token_boots_zero" - boot token boot-count TTL exhausted - "token_hmac_fail" - token tampered or wrong device - "token_dek_fail" - token DEK decrypt failed - "token_wrong_size" - token file corrupted - "token_bad_magic" - token file corrupted - "not_provisioned" - should generally use NEEDS_PROVISION state instead + "needs_auth" — storage already unlocked, client must auth + "token_missing" — no boot token on flash + "token_expired" — boot token wall-clock TTL elapsed + "token_boots_zero" — boot token boot-count TTL exhausted + "token_hmac_fail" — token tampered or wrong device + "token_dek_fail" — token DEK decrypt failed + "token_wrong_size" — token file corrupted + "token_bad_magic" — token file corrupted + "not_provisioned" — should generally use NEEDS_PROVISION state instead Other values may be added; clients should treat unknown values as "locked, ask for passphrase". */ char lock_reason[32]; diff --git a/src/mesh/generated/meshtastic/mesh_beacon.pb.h b/src/mesh/generated/meshtastic/mesh_beacon.pb.h index 94312eb1e99..028d8269f50 100644 --- a/src/mesh/generated/meshtastic/mesh_beacon.pb.h +++ b/src/mesh/generated/meshtastic/mesh_beacon.pb.h @@ -15,7 +15,7 @@ /* Payload for MESH_BEACON_APP packets. Periodically broadcast by nodes in beacon mode. Listeners deliver the text message to the local inbox and cache any offered - channel/preset for the client app to act on - the firmware never auto-applies them. */ + channel/preset for the client app to act on — the firmware never auto-applies them. */ typedef struct _meshtastic_MeshBeacon { /* Human-readable beacon message. Max 100 bytes enforced by firmware on send. */ char message[101]; diff --git a/src/mesh/generated/meshtastic/module_config.pb.h b/src/mesh/generated/meshtastic/module_config.pb.h index 713a9114014..b04c358fc41 100644 --- a/src/mesh/generated/meshtastic/module_config.pb.h +++ b/src/mesh/generated/meshtastic/module_config.pb.h @@ -497,7 +497,7 @@ typedef struct _meshtastic_ModuleConfig_MeshBeaconConfig { /* Single-target TX channel: channel settings (name + PSK) to send beacons on. If unset, beacons go out on the primary channel. Used only when broadcast_targets is empty. NOTE: the single-target path embeds the ChannelSettings inline here, whereas a - broadcast_targets entry references a channel-table slot by channel_index instead - see + broadcast_targets entry references a channel-table slot by channel_index instead — see BroadcastTarget. The two paths are equal, first-class options; only this representation differs. */ bool has_broadcast_on_channel; meshtastic_ChannelSettings broadcast_on_channel; @@ -514,7 +514,7 @@ typedef struct _meshtastic_ModuleConfig_MeshBeaconConfig { each temporarily switching the radio to that entry's preset/region/channel. When empty, the broadcaster uses the scalar broadcast_on_preset / broadcast_on_region / broadcast_on_channel fields instead (the single-target path). - Single- and multi-target are equal, first-class options - neither is preferred or + Single- and multi-target are equal, first-class options — neither is preferred or deprecated. They differ only in how the TX channel is named: broadcast_on_channel embeds a ChannelSettings inline, while a target references an existing channel-table slot by channel_index (see BroadcastTarget). */ From feaff8c53d28a8867672c032c2dbd6a133b50599 Mon Sep 17 00:00:00 2001 From: nomdetom Date: Tue, 14 Jul 2026 13:18:17 +0100 Subject: [PATCH 11/11] menu handled --- protobufs | 2 +- src/graphics/draw/MenuHandler.cpp | 1 + .../InkHUD/Applets/System/Menu/MenuAction.h | 1 + .../InkHUD/Applets/System/Menu/MenuApplet.cpp | 5 ++ src/mesh/generated/meshtastic/admin.pb.h | 6 +-- src/mesh/generated/meshtastic/atak.pb.h | 46 +++++++++---------- src/mesh/generated/meshtastic/mesh.pb.h | 18 ++++---- .../generated/meshtastic/mesh_beacon.pb.h | 2 +- .../generated/meshtastic/module_config.pb.h | 4 +- 9 files changed, 46 insertions(+), 39 deletions(-) diff --git a/protobufs b/protobufs index b942055bb28..1153d23b9dd 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit b942055bb28cbbb97f644c81112313cd740e764b +Subproject commit 1153d23b9dd66c3c6efc77b3f784cdfb83db9e9c diff --git a/src/graphics/draw/MenuHandler.cpp b/src/graphics/draw/MenuHandler.cpp index 23e0c7b5fd6..35e934bbd50 100644 --- a/src/graphics/draw/MenuHandler.cpp +++ b/src/graphics/draw/MenuHandler.cpp @@ -239,6 +239,7 @@ void menuHandler::LoraRegionPicker(uint32_t duration) {"RU", OptionsAction::Select, meshtastic_Config_LoRaConfig_RegionCode_RU}, {"IN", OptionsAction::Select, meshtastic_Config_LoRaConfig_RegionCode_IN}, {"NZ_865", OptionsAction::Select, meshtastic_Config_LoRaConfig_RegionCode_NZ_865}, + {"NZ_915", OptionsAction::Select, meshtastic_Config_LoRaConfig_RegionCode_NZ_915}, {"TH", OptionsAction::Select, meshtastic_Config_LoRaConfig_RegionCode_TH}, {"LORA_24", OptionsAction::Select, meshtastic_Config_LoRaConfig_RegionCode_LORA_24}, {"UA_433", OptionsAction::Select, meshtastic_Config_LoRaConfig_RegionCode_UA_433}, diff --git a/src/graphics/niche/InkHUD/Applets/System/Menu/MenuAction.h b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuAction.h index 26befddc6ca..35ff09675b7 100644 --- a/src/graphics/niche/InkHUD/Applets/System/Menu/MenuAction.h +++ b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuAction.h @@ -54,6 +54,7 @@ enum MenuAction { SET_REGION_RU, SET_REGION_IN, SET_REGION_NZ_865, + SET_REGION_NZ_915, SET_REGION_TH, SET_REGION_LORA_24, SET_REGION_UA_433, diff --git a/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.cpp b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.cpp index 6c1a1c79eab..c602d486612 100644 --- a/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.cpp +++ b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.cpp @@ -823,6 +823,10 @@ void InkHUD::MenuApplet::execute(MenuItem item) applyLoRaRegion(meshtastic_Config_LoRaConfig_RegionCode_NZ_865); break; + case SET_REGION_NZ_915: + applyLoRaRegion(meshtastic_Config_LoRaConfig_RegionCode_NZ_915); + break; + case SET_REGION_TH: applyLoRaRegion(meshtastic_Config_LoRaConfig_RegionCode_TH); break; @@ -1732,6 +1736,7 @@ void InkHUD::MenuApplet::showPage(MenuPage page) items.push_back(MenuItem("RU", MenuAction::SET_REGION_RU, MenuPage::EXIT)); items.push_back(MenuItem("IN", MenuAction::SET_REGION_IN, MenuPage::EXIT)); items.push_back(MenuItem("NZ 865", MenuAction::SET_REGION_NZ_865, MenuPage::EXIT)); + items.push_back(MenuItem("NZ 915", MenuAction::SET_REGION_NZ_915, MenuPage::EXIT)); items.push_back(MenuItem("TH", MenuAction::SET_REGION_TH, MenuPage::EXIT)); items.push_back(MenuItem("LoRa 2.4", MenuAction::SET_REGION_LORA_24, MenuPage::EXIT)); items.push_back(MenuItem("UA 433", MenuAction::SET_REGION_UA_433, MenuPage::EXIT)); diff --git a/src/mesh/generated/meshtastic/admin.pb.h b/src/mesh/generated/meshtastic/admin.pb.h index 38829148781..4c00a568cf0 100644 --- a/src/mesh/generated/meshtastic/admin.pb.h +++ b/src/mesh/generated/meshtastic/admin.pb.h @@ -186,7 +186,7 @@ typedef struct _meshtastic_LockdownAuth { token at unlock time: the client-supplied boots_remaining when non-zero, otherwise the firmware default (TOKEN_DEFAULT_BOOTS). Note that boots_remaining == 0 in this message means "use firmware - default", NOT "zero boots" — a client computing the ceiling for + default", NOT "zero boots" - a client computing the ceiling for display should mirror that resolution rather than multiplying the raw request value. @@ -196,7 +196,7 @@ typedef struct _meshtastic_LockdownAuth { Uses millis() (CPU uptime), not wall-clock time, so the cap is immune to GPS spoofing, RTC backup-battery removal, and Faraday - cage isolation — none of those move the uptime counter. The only + cage isolation - none of those move the uptime counter. The only way to reset the session clock is a reboot, which costs a boot from the on-flash, HMAC-bound counter. */ uint32_t max_session_seconds; @@ -213,7 +213,7 @@ typedef struct _meshtastic_LockdownAuth { NOT reversed by this operation: APPROTECT. Once the debug port lockout has been burned (on silicon where it is effective) it is - permanent — disabling lockdown decrypts your data and removes the + permanent - disabling lockdown decrypts your data and removes the access gates, but the SWD/JTAG port stays locked for the life of the device (recoverable only via a full chip erase over a debug probe, which destroys all data). Clients should make this diff --git a/src/mesh/generated/meshtastic/atak.pb.h b/src/mesh/generated/meshtastic/atak.pb.h index 6ea298f9ed7..e0dab865904 100644 --- a/src/mesh/generated/meshtastic/atak.pb.h +++ b/src/mesh/generated/meshtastic/atak.pb.h @@ -332,7 +332,7 @@ typedef enum _meshtastic_CotType { /* y-: TAKTALK room/membership broadcast. Payload carried via the TakTalkRoomData typed variant (sender_callsign, room_id, room_name, participants). The CoT type literally has a trailing dash and no - second atom — not a typo. */ + second atom - not a typo. */ meshtastic_CotType_CotType_y = 126 } meshtastic_CotType; @@ -380,7 +380,7 @@ typedef enum _meshtastic_DrawnShape_Kind { /* u-r-b-bullseye: Bullseye ring with range rings and bearing reference */ meshtastic_DrawnShape_Kind_Kind_Bullseye = 7, /* u-d-c-e: Ellipse with distinct major/minor axes (same storage as - Kind_Circle — uses major_cm/minor_cm/angle_deg — but receivers + Kind_Circle - uses major_cm/minor_cm/angle_deg - but receivers render it as a non-circular ellipse rather than a round circle). */ meshtastic_DrawnShape_Kind_Kind_Ellipse = 8, /* u-d-v: 2D vehicle outline drawn on the map. Vertices carry the @@ -400,7 +400,7 @@ typedef enum _meshtastic_DrawnShape_Kind { end of parse; builder uses it to decide which of / to emit in the reconstructed XML. */ typedef enum _meshtastic_DrawnShape_StyleMode { - /* Unspecified — receiver infers from which color fields are non-zero. */ + /* Unspecified - receiver infers from which color fields are non-zero. */ meshtastic_DrawnShape_StyleMode_StyleMode_Unspecified = 0, /* Stroke only. No in the source XML. Used for polylines, ranging lines, bullseye rings. */ @@ -417,7 +417,7 @@ typedef enum _meshtastic_DrawnShape_StyleMode { alone is ambiguous (e.g. a-u-G could be a 2525 symbol or a custom icon depending on the iconset path). */ typedef enum _meshtastic_Marker_Kind { - /* Unspecified — fall back to TAKPacketV2.cot_type_id */ + /* Unspecified - fall back to TAKPacketV2.cot_type_id */ meshtastic_Marker_Kind_Kind_Unspecified = 0, /* b-m-p-s-m: Spot map marker */ meshtastic_Marker_Kind_Kind_Spot = 1, @@ -680,10 +680,10 @@ typedef struct _meshtastic_AircraftTrack { hundred meters of the anchor has per-vertex deltas in the ±10^4 range. Under sint32+zigzag those encode as 2 bytes each (tag+varint), versus the 4 bytes that sfixed32 would always require. At 32 vertices that is ~128 - bytes of savings — the difference between fitting under the LoRa MTU or + bytes of savings - the difference between fitting under the LoRa MTU or not. Absolute coordinates (values ~10^9) would cost sint32 varint 5 bytes per field, which is why TAKPacketV2's top-level latitude_i / longitude_i - stay sfixed32 — only small values win with sint32. */ + stay sfixed32 - only small values win with sint32. */ typedef struct _meshtastic_CotGeoPoint { /* Latitude delta from TAKPacketV2.latitude_i, in 1e-7 degree units. Add to the enclosing event's latitude_i to recover the absolute latitude. */ @@ -791,7 +791,7 @@ typedef struct _meshtastic_Marker { Covers CoT type u-rb-a. The anchor position is on TAKPacketV2.latitude_i/longitude_i; the target endpoint is carried as a - CotGeoPoint — same delta-from-anchor encoding used by DrawnShape.vertices + CotGeoPoint - same delta-from-anchor encoding used by DrawnShape.vertices so a self-anchored RAB (common case) encodes in zero bytes. */ typedef struct _meshtastic_RangeAndBearing { /* Target/anchor endpoint (delta-encoded from TAKPacketV2.latitude_i/longitude_i). */ @@ -899,12 +899,12 @@ typedef struct _meshtastic_CasevacReport { same as the envelope callsign but ATAK sometimes carries a distinct ops-number here. */ pb_callback_t title; - /* Primary medline free-text — the single most clinically important line + /* Primary medline free-text - the single most clinically important line on a MEDLINE form (e.g. "2 urgent litter patients, smoke on approach"). MUST be preserved under MTU pressure as long as any casevac is sent. */ pb_callback_t medline_remarks; /* Line 3 (newer ATAK format): patient counts by precedence level. - Coexists with the enum-style `precedence` field (tag 1) — older ATAK + Coexists with the enum-style `precedence` field (tag 1) - older ATAK emits a single enum, newer ATAK emits these counts, and both can be set simultaneously. Senders populate whichever style(s) the source XML had; receivers prefer counts when non-zero. */ @@ -946,19 +946,19 @@ typedef struct _meshtastic_CasevacReport { (e.g. "Primary HLZ is soccer field"). */ pb_callback_t hlz_remarks; /* Per-patient clinical records. Each entry is one patient's ZMIST card - (Zap number / Mechanism / Injuries / Signs / Treatment). Repeatable — + (Zap number / Mechanism / Injuries / Signs / Treatment). Repeatable - a mass-casualty event can carry 1-6 entries in practice, limited by the 237 B LoRa MTU. */ pb_callback_t zmist; } meshtastic_CasevacReport; -/* Per-patient clinical summary record — one entry per patient in a CASEVAC. +/* Per-patient clinical summary record - one entry per patient in a CASEVAC. Maps directly to ATAK's child element inside . All fields are optional free-text; senders populate what they have. */ typedef struct _meshtastic_ZMistEntry { /* Patient identifier / sequence label (e.g. "ZMIST-1", "ZMIST-2"). */ pb_callback_t title; - /* Zap number — unique patient tracking ID (often a terse code like + /* Zap number - unique patient tracking ID (often a terse code like "Gunshot" or a serial). */ pb_callback_t z; /* Mechanism of injury (e.g. "Penetrating trauma", "Blast injury"). */ @@ -997,7 +997,7 @@ typedef struct _meshtastic_EmergencyAlert { creation time; the fields below carry structured metadata the raw-detail fallback currently loses. - Fields are deliberately lean — this variant is closer to the MTU ceiling + Fields are deliberately lean - this variant is closer to the MTU ceiling than the others, so every string is capped in options. */ typedef struct _meshtastic_TaskRequest { /* Short tag for the task category (e.g. "engage", "observe", "recon", @@ -1017,7 +1017,7 @@ typedef struct _meshtastic_TaskRequest { /* Weather annotation from CoT detail element. - Attaches to any TAKPacketV2 regardless of payload_variant — an Aircraft, + Attaches to any TAKPacketV2 regardless of payload_variant - an Aircraft, PLI, or Marker can all carry observed conditions at the emitting station. ATAK-CIV ships an XSD for but no dedicated handler, so the element round-trips through the generic detail pipeline; this message @@ -1026,7 +1026,7 @@ typedef struct _meshtastic_TaskRequest { Target wire cost: ~6-8 bytes compressed with a fully populated instance. Named `TAKEnvironment` (not just `Environment`) because the bare name - collides with `SwiftUI.Environment` — every SwiftUI view in a consuming + collides with `SwiftUI.Environment` - every SwiftUI view in a consuming iOS app uses the `@Environment` property wrapper, and importing the generated proto module would make `Environment` ambiguous in every one of those files. The `TAK` prefix matches the convention used by the @@ -1055,7 +1055,7 @@ typedef struct _meshtastic_TAKEnvironment { The receiving ATAK client restores those from its own defaults, same as every other CoT carried over Meshtastic today. - Attaches to any TAKPacketV2 — a PLI with a sensor on the operator's head, + Attaches to any TAKPacketV2 - a PLI with a sensor on the operator's head, an Aircraft with a FLIR turret, a Marker dropped on a UAV. Target wire cost: ~7-14 bytes compressed (dominated by model string). */ typedef struct _meshtastic_SensorFov { @@ -1065,30 +1065,30 @@ typedef struct _meshtastic_SensorFov { SensorDetailHandler default (270°) and save varint bytes over centi-deg. */ uint32_t azimuth_deg; /* Maximum range of the cone in meters. - Optional — if unset, receivers should use the ATAK-CIV default of 100m. */ + Optional - if unset, receivers should use the ATAK-CIV default of 100m. */ bool has_range_m; uint32_t range_m; /* Horizontal field of view in whole degrees (cone's angular width). ATAK-CIV default is 45°. */ uint32_t fov_horizontal_deg; /* Vertical field of view in whole degrees. ATAK-CIV default is 45°. - Optional — a value of 0 means "not set / use horizontal FOV". */ + Optional - a value of 0 means "not set / use horizontal FOV". */ uint32_t fov_vertical_deg; /* Elevation angle in whole degrees. Positive = up, negative = down. Range -90 to +90. sint32 for varint efficiency on small negatives. */ int32_t elevation_deg; /* Roll (camera tilt) in whole degrees, -180 to +180. - Optional — use 0 if the sensor doesn't track roll. */ + Optional - use 0 if the sensor doesn't track roll. */ int32_t roll_deg; /* Free-form device model identifier, e.g. "FLIR-Boson-640", "SEEK". - Optional — empty string means "unknown model" (ATAK-CIV default). */ + Optional - empty string means "unknown model" (ATAK-CIV default). */ pb_callback_t model; } meshtastic_SensorFov; /* TAKTALK chat message payload (CoT type m-t-t). TAKTALK is an ATAK plugin for voice + text team messaging. The voice - audio stream goes over UDP/RTP and is NOT carried by the mesh — only + audio stream goes over UDP/RTP and is NOT carried by the mesh - only the text envelope (this message) is. `from_voice` marks messages sent via push-to-talk speech-to-text so receivers can render a mic icon next to the text. @@ -1122,7 +1122,7 @@ typedef struct _meshtastic_TakTalkMessage { Announces a TAKTALK chatroom's friendly name and roster so peers can resolve room UUIDs (used in TakTalkMessage.chatroom_id and GeoChat.room_id) to a display name and participant list. Not a chat - message itself — these events are emitted by TAKTALK when rooms are + message itself - these events are emitted by TAKTALK when rooms are created or memberships change. */ typedef struct _meshtastic_TakTalkRoomData { /* Callsign of the device broadcasting the room state (typically the @@ -1161,7 +1161,7 @@ typedef struct _meshtastic_Marti { primary-vs-cc distinction the same way ATAK does. If dest_callsign is [TAKPacketV2.callsign] (self-addressed, unusual but - legal — e.g. ATAK echoing back to its own room), the builder still emits + legal - e.g. ATAK echoing back to its own room), the builder still emits the element so loopback shapes round-trip cleanly. */ pb_callback_t dest_callsign; } meshtastic_Marti; diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index 3020a0f1be3..98798173c85 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -1250,15 +1250,15 @@ typedef struct _meshtastic_LockdownStatus { /* Current lockdown state being reported. */ meshtastic_LockdownStatus_State state; /* For LOCKED: machine-readable reason. Known values: - "needs_auth" — storage already unlocked, client must auth - "token_missing" — no boot token on flash - "token_expired" — boot token wall-clock TTL elapsed - "token_boots_zero" — boot token boot-count TTL exhausted - "token_hmac_fail" — token tampered or wrong device - "token_dek_fail" — token DEK decrypt failed - "token_wrong_size" — token file corrupted - "token_bad_magic" — token file corrupted - "not_provisioned" — should generally use NEEDS_PROVISION state instead + "needs_auth" - storage already unlocked, client must auth + "token_missing" - no boot token on flash + "token_expired" - boot token wall-clock TTL elapsed + "token_boots_zero" - boot token boot-count TTL exhausted + "token_hmac_fail" - token tampered or wrong device + "token_dek_fail" - token DEK decrypt failed + "token_wrong_size" - token file corrupted + "token_bad_magic" - token file corrupted + "not_provisioned" - should generally use NEEDS_PROVISION state instead Other values may be added; clients should treat unknown values as "locked, ask for passphrase". */ char lock_reason[32]; diff --git a/src/mesh/generated/meshtastic/mesh_beacon.pb.h b/src/mesh/generated/meshtastic/mesh_beacon.pb.h index 028d8269f50..94312eb1e99 100644 --- a/src/mesh/generated/meshtastic/mesh_beacon.pb.h +++ b/src/mesh/generated/meshtastic/mesh_beacon.pb.h @@ -15,7 +15,7 @@ /* Payload for MESH_BEACON_APP packets. Periodically broadcast by nodes in beacon mode. Listeners deliver the text message to the local inbox and cache any offered - channel/preset for the client app to act on — the firmware never auto-applies them. */ + channel/preset for the client app to act on - the firmware never auto-applies them. */ typedef struct _meshtastic_MeshBeacon { /* Human-readable beacon message. Max 100 bytes enforced by firmware on send. */ char message[101]; diff --git a/src/mesh/generated/meshtastic/module_config.pb.h b/src/mesh/generated/meshtastic/module_config.pb.h index b04c358fc41..713a9114014 100644 --- a/src/mesh/generated/meshtastic/module_config.pb.h +++ b/src/mesh/generated/meshtastic/module_config.pb.h @@ -497,7 +497,7 @@ typedef struct _meshtastic_ModuleConfig_MeshBeaconConfig { /* Single-target TX channel: channel settings (name + PSK) to send beacons on. If unset, beacons go out on the primary channel. Used only when broadcast_targets is empty. NOTE: the single-target path embeds the ChannelSettings inline here, whereas a - broadcast_targets entry references a channel-table slot by channel_index instead — see + broadcast_targets entry references a channel-table slot by channel_index instead - see BroadcastTarget. The two paths are equal, first-class options; only this representation differs. */ bool has_broadcast_on_channel; meshtastic_ChannelSettings broadcast_on_channel; @@ -514,7 +514,7 @@ typedef struct _meshtastic_ModuleConfig_MeshBeaconConfig { each temporarily switching the radio to that entry's preset/region/channel. When empty, the broadcaster uses the scalar broadcast_on_preset / broadcast_on_region / broadcast_on_channel fields instead (the single-target path). - Single- and multi-target are equal, first-class options — neither is preferred or + Single- and multi-target are equal, first-class options - neither is preferred or deprecated. They differ only in how the TX channel is named: broadcast_on_channel embeds a ChannelSettings inline, while a target references an existing channel-table slot by channel_index (see BroadcastTarget). */