Skip to content

PhoneAPI: add missing tak_tag case + skip reserved gap in module-config iteration#10256

Merged
thebentern merged 2 commits into
meshtastic:developfrom
nightjoker7:fix/phoneapi-missing-tak-config
Apr 23, 2026
Merged

PhoneAPI: add missing tak_tag case + skip reserved gap in module-config iteration#10256
thebentern merged 2 commits into
meshtastic:developfrom
nightjoker7:fix/phoneapi-missing-tak-config

Conversation

@nightjoker7

Copy link
Copy Markdown
Contributor

Summary

Two related fixes in PhoneAPI::handleToRadio / STATE_SEND_MODULECONFIG:

  1. Add missing case meshtastic_ModuleConfig_tak_tag:moduleConfig.tak exists in the firmware struct and is persisted by NodeDB, but PhoneAPI never sends it to the phone. Android ATAK plugin clients can't round-trip TAK (Team Awareness Kit) settings as a result.
  2. Add case 14: break; for the reserved gap in the ModuleConfig oneof tag numbering. Without this case, every phone reconnect walks through config_state=14 and hits LOG_ERROR("Unknown module config type %d", config_state).

Also: dropped the default: from LOG_ERROR to LOG_DEBUG. This path is routine (fires on every phone reconnect). A truly new unknown tag would be caught via the phone UI, not via an error log.

Root cause

STATE_SEND_MODULECONFIG iterates config_state from _MODULECONFIG_MIN + 1 = 1 through _MAX + 1 = 16 inclusive. The switch inside checks against meshtastic_ModuleConfig_*_tag values from module_config.pb.h:

#define meshtastic_ModuleConfig_paxcounter_tag          13
// no tag 14 — reserved gap in oneof
#define meshtastic_ModuleConfig_traffic_management_tag  15
#define meshtastic_ModuleConfig_tak_tag                 16

Before this patch the switch handled 1..13 and 15, but silently fell through to the LOG_ERROR default at 14 and 16.

Impact (observed)

On a Station G2 fleet running develop over a 24-hour window:

1427 LOG_ERROR  "Unknown module config type 14"
1403 LOG_ERROR  "Unknown module config type 16"

Together ~2800 ERROR-level lines per device per day, entirely from routine phone reconnects. That's the majority of the ERROR-level log traffic on the node.

And the functional half: Android ATAK plugin users have no way to read TAK module config from the firmware — the phone has no idea what team / role is persisted on the device.

Risk

  • TAK case: very low. moduleConfig.tak is already a real, persisted struct (see module_config.pb.h line 453+). The added case mirrors exactly how every other module-config case works (paxcounter, traffic_management, etc.) — copies moduleConfig.tak into fromRadioScratch.moduleConfig.payload_variant.tak. No new memory paths, no new allocations.
  • Gap case 14: zero risk, just an explicit break; that replaces a benign LOG_ERROR with silence.
  • Log level drop: hygiene only, matches patterns elsewhere in the codebase.

Testing

Phone-side config-dump on a patched node shows one additional ModuleConfig message sent (the tak variant). Log volume on phone-reconnect drops by ~2800 lines/day.

Follow-up not in this PR

AdminModule.cpp handles SET_MODULE_CONFIG for TAK via the enum value TAK_CONFIG — but there's no matching GET path visible. Worth a follow-up PR to confirm the set path is wired and the AdminModule similarly has tak handling where needed. Not blocking this PR.

…ig iteration

The STATE_SEND_MODULECONFIG state machine iterates config_state through
ModuleConfigType enum values (1..MAX+1 = 16) and switches on
meshtastic_ModuleConfig_*_tag values. Two of the resulting tag values
land in the default / LOG_ERROR path:

1. `tak_tag` (16) — the meshtastic_ModuleConfig_TAKConfig struct exists
   in the protobuf and has a `.tak` member in payload_variant, but no
   PhoneAPI case ever sends it to the phone. As a result, Android
   clients can't read the persisted TAK (Team Awareness Kit) module
   config at all. Added case that sends moduleConfig.tak, matching the
   pattern used for all other module-config tags (paxcounter,
   traffic_management, etc.). NodeDB already persists the struct via
   the moduleConfig protobuf save; this just wires the read path to
   the phone.

2. Tag 14 — reserved gap in the oneof numbering. No payload_variant
   member exists at tag 14. Without this patch, every phone reconnect
   walks through config_state=14 and hits
   `LOG_ERROR("Unknown module config type %d", config_state)`. On an
   active deployment that's ~1,400 LOG_ERROR lines per day per node —
   burying real errors. Added explicit `case 14: break;` so the gap
   is silently skipped.

Also: lowered the `default:` log level from LOG_ERROR to LOG_DEBUG. A
truly-new unknown type number would indicate firmware lagging the
protobuf — annoying but not an error event worth LOG_ERROR, especially
since this path runs on every phone handshake. If a new ModuleConfig
tag appears, devs will notice via the phone UI missing it, not via log.

Observed on a Station G2 fleet: 1403 "Unknown module config type 16"
and 1427 "Unknown module config type 14" LOG_ERROR lines in 24 hours
from routine phone reconnects.
@github-actions github-actions Bot added the bugfix Pull request that fixes bugs label Apr 23, 2026
@thebentern thebentern merged commit 55bf8c2 into meshtastic:develop Apr 23, 2026
1 check passed
nightjoker7 added a commit to nightjoker7/firmware that referenced this pull request Apr 23, 2026
…ig iteration (meshtastic#10256)

* PhoneAPI: add missing tak_tag case + skip reserved gap in module-config iteration

The STATE_SEND_MODULECONFIG state machine iterates config_state through
ModuleConfigType enum values (1..MAX+1 = 16) and switches on
meshtastic_ModuleConfig_*_tag values. Two of the resulting tag values
land in the default / LOG_ERROR path:

1. `tak_tag` (16) — the meshtastic_ModuleConfig_TAKConfig struct exists
   in the protobuf and has a `.tak` member in payload_variant, but no
   PhoneAPI case ever sends it to the phone. As a result, Android
   clients can't read the persisted TAK (Team Awareness Kit) module
   config at all. Added case that sends moduleConfig.tak, matching the
   pattern used for all other module-config tags (paxcounter,
   traffic_management, etc.). NodeDB already persists the struct via
   the moduleConfig protobuf save; this just wires the read path to
   the phone.

2. Tag 14 — reserved gap in the oneof numbering. No payload_variant
   member exists at tag 14. Without this patch, every phone reconnect
   walks through config_state=14 and hits
   `LOG_ERROR("Unknown module config type %d", config_state)`. On an
   active deployment that's ~1,400 LOG_ERROR lines per day per node —
   burying real errors. Added explicit `case 14: break;` so the gap
   is silently skipped.

Also: lowered the `default:` log level from LOG_ERROR to LOG_DEBUG. A
truly-new unknown type number would indicate firmware lagging the
protobuf — annoying but not an error event worth LOG_ERROR, especially
since this path runs on every phone handshake. If a new ModuleConfig
tag appears, devs will notice via the phone UI missing it, not via log.

Observed on a Station G2 fleet: 1403 "Unknown module config type 16"
and 1427 "Unknown module config type 14" LOG_ERROR lines in 24 hours
from routine phone reconnects.

* Get rid of the placeholder

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
mariotti pushed a commit to mariotti/firmware that referenced this pull request May 6, 2026
…ig iteration (meshtastic#10256)

* PhoneAPI: add missing tak_tag case + skip reserved gap in module-config iteration

The STATE_SEND_MODULECONFIG state machine iterates config_state through
ModuleConfigType enum values (1..MAX+1 = 16) and switches on
meshtastic_ModuleConfig_*_tag values. Two of the resulting tag values
land in the default / LOG_ERROR path:

1. `tak_tag` (16) — the meshtastic_ModuleConfig_TAKConfig struct exists
   in the protobuf and has a `.tak` member in payload_variant, but no
   PhoneAPI case ever sends it to the phone. As a result, Android
   clients can't read the persisted TAK (Team Awareness Kit) module
   config at all. Added case that sends moduleConfig.tak, matching the
   pattern used for all other module-config tags (paxcounter,
   traffic_management, etc.). NodeDB already persists the struct via
   the moduleConfig protobuf save; this just wires the read path to
   the phone.

2. Tag 14 — reserved gap in the oneof numbering. No payload_variant
   member exists at tag 14. Without this patch, every phone reconnect
   walks through config_state=14 and hits
   `LOG_ERROR("Unknown module config type %d", config_state)`. On an
   active deployment that's ~1,400 LOG_ERROR lines per day per node —
   burying real errors. Added explicit `case 14: break;` so the gap
   is silently skipped.

Also: lowered the `default:` log level from LOG_ERROR to LOG_DEBUG. A
truly-new unknown type number would indicate firmware lagging the
protobuf — annoying but not an error event worth LOG_ERROR, especially
since this path runs on every phone handshake. If a new ModuleConfig
tag appears, devs will notice via the phone UI missing it, not via log.

Observed on a Station G2 fleet: 1403 "Unknown module config type 16"
and 1427 "Unknown module config type 14" LOG_ERROR lines in 24 hours
from routine phone reconnects.

* Get rid of the placeholder

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Pull request that fixes bugs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants