Meshtastic-Android/docs/settings-validation.md
copilot-swe-agent[bot] b1b3f37b21
docs: address review feedback on settings-validation.md
Agent-Logs-Url: https://github.com/meshtastic/Meshtastic-Android/sessions/b9b68633-39b3-466b-b40c-e3a6bdd92e99

Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2026-04-19 00:27:13 +00:00

24 KiB
Raw Permalink Blame History

Settings Screen Validation Reference

This document describes the validation rules enforced on each radio configuration and module configuration settings screen. Constraints are sourced from two layers:

  1. Protobuf schema — field types, enums, and max_size annotations defined in the meshtastic/protobufs submodule.
  2. UI form layer — additional range checks, conditional visibility, and interval pickers implemented in feature/settings/src/commonMain/.../radio/component/.

Reusable components live in core/ui/.../component/. Each component enforces its own validation strategy (see UI Component Validation at the bottom).


Table of Contents


Device Config Screens

User (Config.UserConfig)

Field Type Validation Notes
long_name String maxSize: 39 bytes (proto max_size: 40) Required (non-blank)
short_name String maxSize: 4 bytes (proto max_size: 5) Required (non-blank)
is_licensed Boolean Toggle
is_unmessagable Boolean Toggle Enabled only when device capability canToggleUnmessageable is true or role is unmessageable

Device (Config.DeviceConfig)

Field Type Validation Notes
role Enum Dropdown: DeviceConfig.Role entries Router/ROUTER_LATE/REPEATER roles trigger a confirmation dialog
rebroadcast_mode Enum Dropdown: RebroadcastMode entries ALL, ALL_SKIP_DECODING, LOCAL_ONLY, KNOWN_ONLY, NONE, CORE_PORTNUMS_ONLY
node_info_broadcast_secs Interval Dropdown: NODE_INFO_BROADCAST intervals See Interval Configurations
double_tap_as_button_press Boolean Toggle
disable_triple_click Boolean Toggle (inverted) UI shows "enabled" when proto field is false
led_heartbeat_disabled Boolean Toggle (inverted) UI shows "enabled" when proto field is false
tzdef String maxSize: 64 bytes (proto max_size: 65) Clearable
button_gpio Integer Numeric input
buzzer_gpio Integer Numeric input

Position (Config.PositionConfig)

Field Type Validation Notes
position_broadcast_secs Interval Dropdown: POSITION_BROADCAST intervals
position_broadcast_smart_enabled Boolean Toggle Controls visibility of smart broadcast fields
broadcast_smart_minimum_interval_secs Interval Dropdown: SMART_BROADCAST_MINIMUM intervals Visible only when smart broadcast enabled
broadcast_smart_minimum_distance Integer Numeric input Visible only when smart broadcast enabled
fixed_position Boolean Toggle Controls visibility of lat/lon/alt vs GPS fields
latitude Double Range: 90.0 to +90.0 Visible only when fixed_position = true
longitude Double Range: 180.0 to +180.0 Visible only when fixed_position = true
altitude Integer Numeric input Visible only when fixed_position = true
gps_mode Enum Dropdown: GpsMode entries Visible only when fixed_position = false
gps_update_interval Interval Dropdown: GPS_UPDATE intervals Visible only when fixed_position = false
position_flags Bitwise Checkbox set: PositionFlags entries (excl. UNSET) Bitwise OR of selected flags
rx_gpio Integer Dropdown: GPIO pins 048
tx_gpio Integer Dropdown: GPIO pins 048
gps_en_gpio Integer Dropdown: GPIO pins 048

Power (Config.PowerConfig)

Field Type Validation Notes
is_power_saving Boolean Toggle
on_battery_shutdown_after_secs Interval Dropdown: ALL intervals
adc_multiplier_override Float Must be > 0.0 when enabled Checkbox + float input; float visible only when enabled
wait_bluetooth_secs Interval Dropdown: NAG_TIMEOUT intervals 0s60s
sds_secs Interval Dropdown: ALL intervals
min_wake_secs Interval Dropdown: NAG_TIMEOUT intervals 0s60s
device_battery_ina_address Integer Numeric input (I2C address)

Network (Config.NetworkConfig)

Field Type Validation Notes
wifi_enabled Boolean Toggle Controls visibility of Wi-Fi fields
wifi_ssid String maxSize: 32 bytes (proto max_size: 33) Visible when wifi_enabled = true
wifi_psk Password maxSize: 64 bytes (proto max_size: 65) Visible when wifi_enabled = true
eth_enabled Boolean Toggle Visible only when device hasEthernet = true
ntp_server String maxSize: 32 bytes (proto max_size: 33)
rsyslog_server String maxSize: 32 bytes (proto max_size: 33)
address_mode Enum Dropdown: AddressMode (DHCP, STATIC) Controls visibility of IPv4 fields
ipv4_config.ip IPv4 Regex: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} Visible when address_mode = STATIC
ipv4_config.gateway IPv4 Same regex Visible when address_mode = STATIC
ipv4_config.subnet IPv4 Same regex Visible when address_mode = STATIC
ipv4_config.dns IPv4 Same regex Visible when address_mode = STATIC

Display (Config.DisplayConfig)

Field Type Validation Notes
screen_on_secs Interval Dropdown: DISPLAY_SCREEN_ON intervals 15s Always On
auto_screen_carousel_secs Interval Dropdown: DISPLAY_CAROUSEL intervals 0 (disabled) 15 min
compass_north_top Boolean Toggle
use_12h_clock Boolean Toggle
heading_bold Boolean Toggle
units Enum Dropdown: DisplayUnits entries Metric / Imperial
wake_on_tap_or_motion Boolean Toggle
flip_screen Boolean Toggle
displaymode Enum Dropdown: DisplayMode entries
oled Enum Dropdown: OledType entries
compass_orientation Enum Dropdown: CompassOrientation entries

LoRa (Config.LoRaConfig)

Field Type Validation Notes
region Enum Dropdown: RegionInfo entries Regional frequency plans
use_preset Boolean Toggle Controls manual vs preset LoRa settings visibility
modem_preset Enum Dropdown: ChannelOption entries Visible only when use_preset = true
bandwidth Integer Numeric input Visible only when use_preset = false
spread_factor Integer Numeric input Visible only when use_preset = false
coding_rate Integer Numeric input Visible only when use_preset = false
hop_limit Integer Dropdown: 07
channel_num Integer Numeric input; must be ≤ numChannels
tx_enabled Boolean Toggle
tx_power Integer Signed integer input (dBm)
override_duty_cycle Boolean Toggle
override_frequency Float MHz value
sx126x_rx_boosted_gain Boolean Toggle
ignore_mqtt Boolean Toggle
config_ok_to_mqtt Boolean Toggle
pa_fan_disabled Boolean Toggle Visible only when device hasPaFan = true

Bluetooth (Config.BluetoothConfig)

Field Type Validation Notes
enabled Boolean Toggle
mode Enum Dropdown: PairingMode entries (excl. UNRECOGNIZED)
fixed_pin String Exactly 6 digits

Security (Config.SecurityConfig)

Field Type Validation Notes
public_key Base64 32 bytes; read-only Auto-derived from private key
private_key Base64 32 bytes Key generation applies bit masking: f[0] &= 0xF8, f[31] = (f[31] & 0x7F) ǀ 0x40
admin_key Base64 list maxCount: 3; each entry 32 bytes
serial_enabled Boolean Toggle
debug_log_api_enabled Boolean Toggle
admin_channel_enabled Boolean Toggle
is_managed Boolean Toggle Enabled only when admin_key list is non-empty

Module Config Screens

MQTT (ModuleConfig.MQTTConfig)

Field Type Validation Notes
enabled Boolean Toggle
address String maxSize: 63 bytes (proto max_size: 64) Non-blank required for connection test
username String maxSize: 63 bytes (proto max_size: 64)
password Password maxSize: 63 bytes (proto max_size: 64)
encryption_enabled Boolean Toggle
json_enabled Boolean Toggle
tls_enabled Boolean Toggle Auto-enforced when using default server with proxy
root String maxSize: 31 bytes (proto max_size: 32) MQTT root topic
proxy_to_client_enabled Boolean Toggle
map_reporting_enabled Boolean Toggle Controls visibility of map report fields
map_report_settings.publish_interval_secs Integer Minimum: 3600 seconds (1 hour)
map_report_settings.position_precision Integer Slider: 1215 bits

Serial (ModuleConfig.SerialConfig)

Field Type Validation Notes
enabled Boolean Toggle
echo Boolean Toggle
rxd Integer Numeric input (GPIO)
txd Integer Numeric input (GPIO)
baud Enum Dropdown: Serial_Baud entries
timeout Integer Numeric input
mode Enum Dropdown: Serial_Mode entries
override_console_serial_port Boolean Toggle

External Notification (ModuleConfig.ExternalNotificationConfig)

Field Type Validation Notes
enabled Boolean Toggle
alert_message Boolean Toggle
alert_message_buzzer Boolean Toggle
alert_message_vibra Boolean Toggle
alert_bell Boolean Toggle
alert_bell_buzzer Boolean Toggle
alert_bell_vibra Boolean Toggle
output Integer Dropdown: GPIO pins 048 Shows active field when ≠ 0
active Boolean Toggle Visible when output ≠ 0
output_buzzer Integer Dropdown: GPIO pins 048 Shows use_pwm field when ≠ 0
use_pwm Boolean Toggle Visible when output_buzzer ≠ 0
output_vibra Integer Dropdown: GPIO pins 048
output_ms Interval Dropdown: OUTPUT intervals 0s10s
nag_timeout Interval Dropdown: NAG_TIMEOUT intervals 0s60s
ringtone String maxSize: 230 bytes RTTTL format
use_i2s_as_buzzer Boolean Toggle

Store & Forward (ModuleConfig.StoreForwardConfig)

Field Type Validation Notes
enabled Boolean Toggle
heartbeat Boolean Toggle
records Integer Numeric input
history_return_max Integer Numeric input
history_return_window Integer Numeric input (seconds)
is_server Boolean Toggle

Range Test (ModuleConfig.RangeTestConfig)

Field Type Validation Notes
enabled Boolean Toggle
sender Interval Dropdown: RANGE_TEST_SENDER intervals 0 (disabled) 1 hour
save Boolean Toggle

Telemetry (ModuleConfig.TelemetryConfig)

Field Type Validation Notes
device_telemetry_enabled Boolean Toggle Visible only when canToggleTelemetryEnabled capability
device_update_interval Interval Dropdown: BROADCAST_SHORT intervals 30 min 72 hours
environment_measurement_enabled Boolean Toggle
environment_update_interval Interval Dropdown: BROADCAST_SHORT intervals 30 min 72 hours
environment_screen_enabled Boolean Toggle
environment_display_fahrenheit Boolean Toggle
air_quality_enabled Boolean Toggle
air_quality_interval Interval Dropdown: BROADCAST_SHORT intervals 30 min 72 hours
power_measurement_enabled Boolean Toggle
power_update_interval Interval Dropdown: BROADCAST_SHORT intervals 30 min 72 hours
power_screen_enabled Boolean Toggle

Canned Message (ModuleConfig.CannedMessageConfig)

Field Type Validation Notes
enabled Boolean Toggle
rotary1_enabled Boolean Toggle
inputbroker_pin_a Integer Numeric input (GPIO)
inputbroker_pin_b Integer Numeric input (GPIO)
inputbroker_pin_press Integer Numeric input (GPIO)
inputbroker_event_press Enum Dropdown: InputEventChar entries
inputbroker_event_cw Enum Dropdown: InputEventChar entries
inputbroker_event_ccw Enum Dropdown: InputEventChar entries
updown1_enabled Boolean Toggle
allow_input_source String maxSize: 63 bytes (proto max_size: 16; UI intentionally allows more)
send_bell Boolean Toggle
messages String maxSize: 200 bytes (proto max_size: 201) Pipe-delimited canned messages

Audio (ModuleConfig.AudioConfig)

Field Type Validation Notes
codec2_enabled Boolean Toggle
ptt_pin Integer Numeric input (GPIO)
bitrate Enum Dropdown: Audio_Baud entries
i2s_ws Integer Numeric input (GPIO)
i2s_sd Integer Numeric input (GPIO)
i2s_din Integer Numeric input (GPIO)
i2s_sck Integer Numeric input (GPIO)

Remote Hardware (ModuleConfig.RemoteHardwareConfig)

Field Type Validation Notes
enabled Boolean Toggle
allow_undefined_pin_access Boolean Toggle
available_pins Pin list maxCount: 4 Each pin: gpio 0255, name maxSize 14 bytes, type RemoteHardwarePinType enum

Neighbor Info (ModuleConfig.NeighborInfoConfig)

Field Type Validation Notes
enabled Boolean Toggle
update_interval Integer Numeric input (seconds)
transmit_over_lora Boolean Toggle

Ambient Lighting (ModuleConfig.AmbientLightingConfig)

Field Type Validation Notes
led_state Boolean Toggle
current Integer Numeric input
red Integer Numeric input (0255)
green Integer Numeric input (0255)
blue Integer Numeric input (0255)

Detection Sensor (ModuleConfig.DetectionSensorConfig)

Field Type Validation Notes
enabled Boolean Toggle
minimum_broadcast_secs Interval Dropdown: DETECTION_SENSOR_MINIMUM intervals 0 (unset) 72 hours
state_broadcast_secs Interval Dropdown: DETECTION_SENSOR_STATE intervals 0 (unset) 72 hours
send_bell Boolean Toggle
name String maxSize: 19 bytes (proto max_size: 20)
monitor_pin Integer Dropdown: GPIO pins 048
detection_trigger_type Enum Dropdown: TriggerType entries
use_pullup Boolean Toggle

Paxcounter (ModuleConfig.PaxcounterConfig)

Field Type Validation Notes
enabled Boolean Toggle
paxcounter_update_interval Interval Dropdown: PAX_COUNTER intervals 15 min 72 hours
wifi_threshold Integer Signed integer (RSSI dBm) Default: 80
ble_threshold Integer Signed integer (RSSI dBm) Default: 80

Status Message (ModuleConfig.StatusMessageConfig)

Field Type Validation Notes
node_status String maxSize: 80 bytes Clearable; requires supportsStatusMessage capability

Traffic Management (ModuleConfig.TrafficManagementConfig)

Field Type Validation Notes
enabled Boolean Toggle Requires supportsTrafficManagementConfig capability
position_dedup_enabled Boolean Toggle
position_precision_bits Integer Numeric input
position_min_interval_secs Integer Numeric input (seconds)
nodeinfo_direct_response Boolean Toggle
nodeinfo_direct_response_max_hops Integer Numeric input
rate_limit_enabled Boolean Toggle
rate_limit_window_secs Integer Numeric input (seconds)
rate_limit_max_packets Integer Numeric input
drop_unknown_enabled Boolean Toggle
unknown_packet_threshold Integer Numeric input
exhaust_hop_telemetry Boolean Toggle
exhaust_hop_position Boolean Toggle
router_preserve_hops Boolean Toggle

TAK (ModuleConfig.TAKConfig)

Field Type Validation Notes
team Enum Dropdown with custom colors/labels Only shown when device role is TAK or TAK_TRACKER
role Enum Dropdown with custom labels Only shown when device role is TAK or TAK_TRACKER

Channel Config

Channel editing is handled by EditChannelDialog.

Field Type Validation Notes
name String maxSize: 11 bytes Empty name falls back to modem preset name
psk ByteString Must be exactly 0, 16, or 32 bytes Pre-shared key for encryption

Interval Configurations

Time-based fields use predefined interval sets from IntervalConfiguration. Each configuration context restricts the available choices to a specific subset of FixedUpdateIntervals.

Configuration Range Values (seconds)
ALL 0 2147483647 0, 1, 2, 3, 4, 5, 8, 10, 15, 20, 30, 40, 45, 60, 80, 90, 120, 300, 600, 900, 1800, 3600, 7200, 10800, 14400, 18000, 21600, 43200, 64800, 86400, 129600, 172800, 259200, 2147483647
BROADCAST_SHORT 30 min 72 hr 1800, 3600, 7200, 10800, 14400, 18000, 21600, 43200, 64800, 86400, 129600, 172800, 259200
BROADCAST_MEDIUM 1 hr 72 hr 3600, 7200, 10800, 14400, 18000, 21600, 43200, 64800, 86400, 129600, 172800, 259200
BROADCAST_LONG 3 hr 72 hr 10800, 14400, 18000, 21600, 43200, 64800, 86400, 129600, 172800, 259200
NODE_INFO_BROADCAST 0 (unset), 3 hr 72 hr 0, 10800, 14400, 18000, 21600, 43200, 64800, 86400, 129600, 172800, 259200
NAG_TIMEOUT 0 60 s 0, 1, 5, 10, 15, 30, 60
OUTPUT 0 10 s 0, 1, 2, 3, 4, 5, 10
PAX_COUNTER 15 min 72 hr 900, 1800, 3600, 7200, 10800, 14400, 18000, 21600, 43200, 64800, 86400, 129600, 172800, 259200
POSITION 1 s 1 hr 1, 2, 5, 10, 15, 20, 30, 45, 60, 120, 300, 600, 900, 1800, 3600
POSITION_BROADCAST 0 (unset), 1 min 72 hr 0, 60, 90, 300, 900, 3600, 7200, 10800, 14400, 18000, 21600, 43200, 64800, 86400, 129600, 172800, 259200
GPS_UPDATE 0 (unset), 8 s 24 hr 0, 8, 20, 40, 60, 80, 120, 300, 600, 900, 1800, 3600, 21600, 43200, 86400
RANGE_TEST_SENDER 0 (disabled) 1 hr 0, 15, 30, 45, 60, 300, 600, 900, 1800, 3600
SMART_BROADCAST_MINIMUM 15 s 1 hr 15, 30, 45, 60, 300, 600, 900, 1800, 3600
DETECTION_SENSOR_MINIMUM 0 (unset), 15 s 72 hr 0, 15, 30, 60, 120, 300, 600, 900, 1800, 3600, 7200, 10800, 14400, 18000, 21600, 43200, 64800, 86400, 129600, 172800, 259200
DETECTION_SENSOR_STATE 0 (unset), 15 min 72 hr 0, 900, 1800, 3600, 7200, 10800, 14400, 18000, 21600, 43200, 64800, 86400, 129600, 172800, 259200
DISPLAY_SCREEN_ON 15 s Always On 15, 30, 60, 300, 600, 900, 1800, 3600, 2147483647
DISPLAY_CAROUSEL 0 (disabled) 15 min 0, 15, 30, 60, 300, 600, 900

Shared Constants

  • GPIO Pins: 048 (inclusive)
  • Hop Limits: 07 (inclusive)

UI Component Validation

The reusable Compose components in core/ui/.../component/ provide the actual enforcement layer. Each component accepts validation parameters and rejects or flags invalid input.

EditTextPreference

  • String mode: Enforces maxSize in UTF-8 bytes via encodeToByteArray().size <= maxSize. Shows a live byte counter when focused.
  • Int mode: Validates with toIntOrNull(); sets error icon on failure.
  • Float mode: Validates with toFloatOrNull().
  • Double mode: Validates with toDoubleOrNull(); supports international decimal separators (., ,, ٫, , ·).

SignedIntegerEditTextPreference

  • Validates with toIntOrNull(); shows error icon on invalid input.

DropDownPreference

  • Closed-set selection only — no free-form input.
  • Automatically filters UNRECOGNIZED and deprecated enum entries.

SwitchPreference

  • Binary toggle; inherently valid. Disabled state shown at reduced opacity.

SliderPreference

  • Discrete steps only; values clamped with coerceIn() and rounded to the nearest valid index.

EditIPv4Preference

  • Regex validation: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}.
  • Stored as a little-endian Int; displayed as dotted-decimal.

EditPasswordPreference

  • Delegates to EditTextPreference with maxSize enforcement and password visibility toggle.

EditBase64Preference

  • Validates Base64 encoding on input.
  • Flags all-zero 32-byte values as errors (empty/unset key).

BitwisePreference

  • Closed checkbox set; toggles individual bit flags via XOR.
  • "Clear" button resets to 0.

EditListPreference

  • Enforces maxCount for list length.
  • Per-element validation varies by type: Int range 0255 for GPIO pins, ByteString via Base64 parsing, composite RemoteHardwarePin with nested field rules.

PositionPrecisionPreference

  • State machine with three modes: disabled (0), precision range (1019), full precision (32).
  • Slider constrained to 1019 with 8 discrete steps.

ConfigState

  • Generic wrapper that tracks isDirty (current value ≠ initial value).
  • Changes are only persisted on explicit save; cancel reverts to the initial snapshot.