Checked 2026-09-29, against the 40 nRF52 variant families resolving to 26
-board configurations in this checkout. This concerns get bootloader.ver, not
-bootloader installation or OTA eligibility. No devices were flashed, and no
-features, storage sizes, or partitions were changed.
-
Result
-
The real firmware reader successfully reads 26 distinct manufacturer-published
-bootloader images from 32 artifact records, including older RAK revisions,
-current and historical LilyGO images, and vendor HEX, UF2 and DFU ZIP packages.
-Repeated copies and identical normalized bootloader images are counted once.
-These are publicly supplied stock/recovery images, not proof that every
-manufacturing batch shipped identical bytes. No untouched live unit was read
-in this audit.
-
One format gap was fixed: Seeed's T1000-E LoRaWAN development-board bootloader
-declares UF2 Bootloader 1.00. The reader now accepts that two-component version
-and returns 1.00 unchanged. It does not invent 1.00.0. That development image
-is separate from Seeed's Meshtastic/MeshCore recovery image, which reports
-0.9.1-5-g488711a and already worked.
-
All other tested images already expose a readable UF2 bootloader record.
-Generic bare dotted-number searches remain deliberately unsupported: TinyUSB,
-nrfx, and SoftDevice can embed their own versions inside the same bootloader.
-The bounded standalone fallback still requires the explicit OTAFIX version
-shape. Ambiguous records, invalid vectors, and corrupt canonical OTAFIX metadata
-retain the existing rejection rules.
-
Published images actually tested
-
The exact source URLs, download hashes, normalized-image hashes, extraction
-layout and expected strings are pinned in
-stock_images.json.
-
-
-
-
Manufacturer image family
-
Version captured from the image
-
-
-
-
-
RAK4631/RAK4630 Arduino bootloader, historical through current
LilyGO T-Echo Lite, Card, T-Impulse Plus (including historical builds)
-
0.9.2-dirty
-
-
-
Seeed XIAO nRF52840 and Sense
-
0.6.1
-
-
-
Seeed XIAO nRF52840 Plus and Sense Plus
-
0.9.2-29-g6a9a6a3
-
-
-
Seeed Wio Tracker 1110 SDK/conversion bootloader
-
0.6.2-26-g949425a-dirty
-
-
-
Seeed Wio Tracker L1 vendor recovery ZIP
-
0.7.0-22-g277a0c8
-
-
-
Seeed T1000-E Meshtastic/MeshCore recovery ZIP
-
0.9.1-5-g488711a
-
-
-
Seeed T1000-E LoRaWAN development-board HEX
-
1.00 (newly supported)
-
-
-
Seeed MeshTracker X1 recovery ZIP
-
0.10.0-18-gb93789f
-
-
-
MTools Tec MeshTiny vendor bootloader UF2
-
0.4.5
-
-
-
BQ/Unit Engineering Nano G2 Ultra vendor HEX ZIP
-
0.6.4-dirty
-
-
-
Muzi Works R1 Neo release HEX
-
0.9.2-31-g990aa7f-dirty
-
-
-
-
Use the embedded version, not the filename. For example, Seeed's XIAO file
-named ...bootloader-0.6.2...hex reports 0.6.1, and its L1 ZIP named
-...bootloader-0.10.0...zip reports 0.7.0-22-g277a0c8. These are actual tested
-bytes, not renamed or inferred release numbers.
-
All these normalized images use the Adafruit nRF52840 F4000..FE000 bootloader
-window. HEX/UF2 address records identify the bytes. The boot-only Seeed DFU
-packages omit MBR/UICR address words; their bootloader binary is extracted using
-the manifest's sd_size/bl_size and the
-Adafruit nRF52840 linker layout.
-The runtime reader independently selects the installed MBR/UICR boot address;
-this audit does not hardcode that layout into the firmware getter.
-
Coverage of every variant family
-
-
Image verified: a published bootloader for that named product/module was
- tested. Factory batch identification still requires reading the actual unit.
-
Representative only: a related module/SDK bootloader was tested; its exact
- factory image was not obtained. Shared build configuration alone does not
- establish identical factory bootloaders.
-
Unverified: no accessible factory bootloader image was obtained. This is
- not a demonstrated reader failure.
-
-
-
-
-
Variant family
-
Status
-
Evidence or remaining gap
-
-
-
-
-
gat562_30s_mesh_kit
-
Unverified
-
GAT documentation/firmware repository checked; no product-specific stock bootloader found.
-
-
-
gat562_mesh_evb_pro
-
Unverified
-
Same GAT gap; RAK board configuration is not factory-image proof.
-
-
-
gat562_mesh_tracker_pro
-
Unverified
-
Same GAT gap; custom vendor/OTAFIX builds also exist.
-
-
-
gat562_mesh_watch13
-
Unverified
-
Same GAT gap.
-
-
-
heltec_mesh_solar
-
Representative only
-
HT-n5262 SDK image passes; Solar downloads found application images, not a board-specific stock bootloader.
-
-
-
heltec_t096
-
Representative only
-
HT-n5262 SDK image passes; T096 factory revision not established.
HT-n5262 SDK image passes; exact Pocket factory revision not established.
-
-
-
meshtiny
-
Image verified
-
Direct manufacturer bootloader UF2 passes; newer ADV/factory revisions require their actual image.
-
-
-
meshtracker_x1
-
Image verified
-
Seeed product-specific recovery ZIP passes.
-
-
-
minewsemi_me25ls01
-
Unverified
-
Manufacturer module page lists firmware as none; no stock bootloader binary found. OEM/dev-kit installations can differ.
-
-
-
muzi_base
-
Unverified
-
Manufacturer publishes bootloader source, but its release assets found were for R1 Neo, not BASE.
-
-
-
muziworks_r1_neo
-
Image verified
-
Manufacturer R1 Neo release HEX passes; do not substitute a generic RAK version.
-
-
-
nano_g2_ultra
-
Image verified
-
Manufacturer's preinstalled-bootloader recovery HEX ZIP passes.
-
-
-
promicro
-
Unverified
-
Nologo documents a Nice!Nano UF2 drive; its linked download requires Baidu access. Generic clones need separate factory images.
-
-
-
rak3401
-
Representative only
-
RAK4631 Arduino images pass; RAK3401-specific untouched image not obtained.
-
-
-
rak4631
-
Image verified
-
Five distinct published stock Arduino bootloader revisions pass. RAK4631-R/RUI3 is a different bootloader family.
-
-
-
rak_wismesh_tag
-
Representative only
-
RAK core images pass; exact Tag factory image not obtained.
-
-
-
sensecap_solar
-
Representative only
-
Seeed documentation identifies XIAO DFU; XIAO images pass, exact Solar factory image not obtained.
-
-
-
t1000-e
-
Image verified
-
Both vendor recovery ZIP and separate LoRaWAN development-board HEX pass.
-
-
-
thinknode_m1
-
Unverified
-
Manufacturer repository checked; no factory bootloader binary found.
-
-
-
thinknode_m3
-
Unverified
-
Published factory UF2 is application-only (26000..52BFF), not a bootloader image.
-
-
-
thinknode_m4
-
Unverified
-
Published factory UF2 is application-only (26000..521FF).
-
-
-
thinknode_m6
-
Unverified
-
Published factory UF2 is application-only (26000..46CFF).
-
-
-
thinknode_m8
-
Unverified
-
No accessible product-specific factory bootloader binary found.
-
-
-
wio-tracker-l1
-
Image verified
-
Seeed's L1 recovery ZIP passes.
-
-
-
wio-tracker-l1-1w
-
Representative only
-
L1 recovery image passes; exact 1W/ADV factory revision not established.
-
-
-
wio-tracker-l1-eink
-
Representative only
-
L1 recovery image passes; exact e-ink factory revision not established.
-
-
-
wio_wm1110
-
Representative only
-
Published Wio Tracker 1110 and XIAO SDK images pass; the variant's XIAO config does not prove the shipped module's image.
-
-
-
xiao_nrf52
-
Image verified
-
XIAO, Sense, Plus and Sense Plus vendor images pass.
-
-
-
-
Representative/unverified products use the same shared reader and should report
-a version if their installed bootloader exposes one of the recognized records.
-There is no evidence yet for claiming an exact version or success on every
-untouched unit. ESP32, RP2040 and STM32 are outside this nRF52 flash reader;
-their getters were not changed and this report does not claim stock-version
-capture on those architectures.
-
Reproduce the artifact tests
-
Normal tests are offline and include all observed version strings, malformed and
-conflicting versions, dependency-version false positives, region/vector bounds,
-and the existing OTAFIX metadata/CRC/fallback cases:
This checks the exact download SHA-256, extracts only the bootloader window,
-checks the normalized-image SHA-256, and invokes the actual C++ reader with an
-exact expected version. It never downloads automatically or flashes a device.
-The ordinary regression cases cover every captured format even without the
-optional cached artifacts. RAK4631 and T1000-E repeater firmware builds passed.
-
What is needed to close the remaining gaps
-
For each untouched unit, collect its DFU drive's INFO_UF2.TXT if present.
-To prove the application's flash reader can capture that exact revision, also
-obtain a read-only bootloader dump plus the MBR word at 0xFF8, UICR NRFFW[0],
-and flash geometry (or a full vendor HEX including those address records).
-Keep the bootloader unchanged while collecting this evidence. Only the identified
-bootloader region is needed; private application keys/configuration are not.
-If no version bytes or startup register value exist, report unknown; a regex
-cannot recover a version that was never embedded.
Hardware test on September 12, 2026 (America/Los_Angeles). Heltec V4 transmitter; XIAO ESP32-S3 with Wio SX1262 receiver. Both used standalone diagnostic firmware.
-
The best tested scan setting was four channels with four-symbol RX-preamble windows. Three-symbol windows were unreliable even in the single-channel re-arm control. In the longer four-symbol runs, four channels received 80/80 packets, five received 79/80, and six received 52/60. These are measured limits of this implementation and test setup, not universal SX1262 channel-count limits.
-
Configuration and counting
-
SF5, 125 kHz, coding rate 4/5, explicit header, payload CRC, and 32 preamble symbols. The programmed preamble is 8.192 ms. Channels start at 909.5 MHz and increase in 1 MHz steps; tests use the first N channels, up to 920.5 MHz. Test packets are transmitted individually with varied timing relative to the scanner. There are no overlapping transmitters in this experiment.
-
A success requires a CRC-valid packet with the expected sequence, channel, length, and test payload. Every included transmission has its own successful transmitter acknowledgement; delayed serial acknowledgements are recovered by sequence, without retransmitting. The one exploratory RX scan trial with shifted acknowledgements is excluded.
-
Completed trials
-
-
-
-
Trial
-
Method/window
-
Channels
-
Payload bytes
-
Received / sent
-
Mean complete scan
-
-
-
-
-
baseline-fixed
-
Fixed-channel RX
-
4
-
64
-
16 / 16
-
—
-
-
-
cad-standard
-
CAD + software RX
-
4
-
64
-
7 / 32
-
14.469 ms
-
-
-
cad-auto
-
CAD + automatic RX
-
4
-
64
-
16 / 32
-
14.468 ms
-
-
-
rxfast-4
-
rxfast 4
-
4
-
64
-
32 / 32
-
6.100 ms
-
-
-
rxfast-4-maxpayload
-
rxfast 4
-
4
-
255
-
35 / 35
-
6.098 ms
-
-
-
matrix-cad1-1
-
cad 1
-
1
-
64
-
7 / 8
-
2.643 ms
-
-
-
matrix-cad1-10
-
cad 1
-
10
-
64
-
2 / 20
-
28.389 ms
-
-
-
matrix-cad1-11
-
cad 1
-
11
-
64
-
5 / 22
-
31.297 ms
-
-
-
matrix-cad1-12
-
cad 1
-
12
-
64
-
3 / 24
-
34.145 ms
-
-
-
matrix-cad2-10
-
cad 2
-
10
-
64
-
3 / 40
-
31.040 ms
-
-
-
matrix-fixed-12
-
Fixed-channel RX
-
12
-
64
-
24 / 24
-
—
-
-
-
matrix-rx1-10
-
rxfast 1
-
10
-
64
-
0 / 20
-
7.555 ms
-
-
-
matrix-rx1-11
-
rxfast 1
-
11
-
64
-
0 / 22
-
8.316 ms
-
-
-
matrix-rx1-12
-
rxfast 1
-
12
-
64
-
0 / 24
-
9.072 ms
-
-
-
matrix-rx2-10
-
rxfast 2
-
10
-
64
-
0 / 40
-
10.133 ms
-
-
-
matrix-rx3-7
-
rxfast 3
-
7
-
64
-
2 / 35
-
8.892 ms
-
-
-
matrix-rx3-8
-
rxfast 3
-
8
-
64
-
1 / 40
-
10.160 ms
-
-
-
matrix-rx4-5
-
rxfast 4
-
5
-
64
-
39 / 40
-
7.630 ms
-
-
-
boundary-rx3-1
-
rxfast 3
-
1
-
64
-
4 / 24
-
1.268 ms
-
-
-
boundary-rx3-4
-
rxfast 3
-
4
-
64
-
2 / 24
-
5.080 ms
-
-
-
boundary-rx3-5
-
rxfast 3
-
5
-
64
-
0 / 25
-
6.350 ms
-
-
-
boundary-rx3-6
-
rxfast 3
-
6
-
64
-
2 / 30
-
7.621 ms
-
-
-
boundary-rx4-4
-
rxfast 4
-
4
-
64
-
80 / 80
-
6.104 ms
-
-
-
boundary-rx4-5
-
rxfast 4
-
5
-
64
-
79 / 80
-
7.630 ms
-
-
-
boundary-rx4-6
-
rxfast 4
-
6
-
64
-
52 / 60
-
9.158 ms
-
-
-
-
rxfast N means a continuous-RX preamble observation window of N symbols, with minimal reconfiguration between frequencies. It is not CAD. cad N uses the SX1262 CAD detector with N symbols and automatic handoff to RX. CAD has no three-symbol mode.
-
Scan times describe uninterrupted sweeps. When reception starts, the radio stays on that frequency through the packet and cannot hear packets on the other frequencies. Serial status requests can add occasional timing outliers.
-
The maximum-payload trial ended after 35 confirmed transmissions when a serial acknowledgement was delayed. Its last TX acknowledgement and matching RX were subsequently recovered from the serial logs; all 35 were received. It is not a completed 64-packet trial.
-
Interpretation and limits
-
The initial four-channel fast-RX test received 32/32 64-byte packets and 35/35 255-byte packets. That is a successful strong-signal bench result, not a guarantee of zero loss. Ordinary four-symbol CAD took approximately 14.47 ms to cover four frequencies and was unreliable with an 8.192 ms preamble.
-
Reducing the observation window also reduces the time available for the modem to recognize a preamble. Dividing preamble duration by scan duration alone overestimates the number of usable channels. One- and two-symbol RX windows produced no preamble detections in the tested high-channel-count cases.
-
The three-symbol single-channel control repeatedly re-arms RX, just as a scan would, and received only 4/24 packets. It is distinct from continuous fixed-channel reception, which passed its baseline. This isolates a detection-window limitation even without a long multi-channel sweep.
-
CAD detection peak 18 and minimum 10 were held constant. These are the datasheet four-symbol SF5 thresholds; the one- and two-symbol CAD tests do not establish optimized thresholds or weak-signal sensitivity. CAD activity followed by no decoded packet can be a late packet detection, not necessarily a noise false positive.
-
Received signals were strong. These tests do not establish weak-signal range, adjacent-channel rejection, simultaneous-packet capacity, production firmware scheduling performance, power consumption, FCC compliance, or months of uptime.
-
Reproduction and evidence
-
See the test harness. Compact validated results, timing counters, and final firmware/source hashes are in cad_scan_results.json. Detailed sequence-level logs and private lab transport helpers are retained locally under out/cad-scan/.
@@ -3171,7 +3463,7 @@ ordinary LoRa packets to verify both RX and TX recovery.
The reproducible bench receiver that provides this live reading is
tools/hil/cw_observer.cpp, built with tools/hil/cw_observer.ini on a
separate RAK4631. It never transmits on its own.
-See the hardware validation for measured results,
+See the hardware validation for measured results,
reproduction steps, and the tested preamble settings.
Tested on the MercerWoodMesh lab Pi on September 14, 2026 (Pacific), using
-base commit 9241ccc253ad2f8ac2c9a2fe756f59ba2f52505d plus the CW changes.
-Test images are marked v1.17.1.6-cw-test-9241ccc2; they are development images.
-
A separate RAK4631 sampled live received signal strength (RSSI) about every
-10 ms, without needing to decode a packet.
-The transmitting boards ran the Full V4 repeater and Full T1000-E Companion
-builds. Both were configured for −9 dBm chip TX power, with profiles at
-909.5 and 919.5 MHz, BW125, SF7, CR5, and 32-symbol preambles.
-
-
-
-
Check
-
V4 / SX1262
-
T1000-E / LR1110
-
-
-
-
-
cw on 0.25 measured duration
-
0.25 s
-
0.25 s
-
-
-
cw on 1.25 measured duration
-
1.25 s
-
1.25 s
-
-
-
Manual stop approximately 1 s into a 5 s request
-
1.01 s
-
1.01 s
-
-
-
cw on 1.25 after enabling RXPS
-
1.26 s
-
1.25 s
-
-
-
cw2 on 1.25 on the second frequency
-
1.25 s
-
1.25 s
-
-
-
Primary-frequency RSSI change while CW2 transmits
-
0 dB
-
0 dB
-
-
-
Paired RX and TX recovery checks
-
5/5 passed
-
5/5 passed
-
-
-
-
The observer saw roughly −56 to −57 dBm during V4 carriers and −67 to
-−71 dBm during T1000-E carriers, against a −112 to −113 dBm baseline.
-Readings returned to baseline after timeout and manual stop. These are
-received signal readings, not calibrated transmitter output measurements.
-
RX recovery used CRC-valid LoRa test payloads and the DUT's receive counter.
-TX recovery used each DUT's MeshCore advertisement, received with valid CRC
-by the observer. Both DUTs finished in RX, with CW and radio2 disabled and
-no outbound packet pending. The observer has no autonomous transmission.
-
Software checks
-
-
1,436 native tests passed, including new checks that CW holds queued packets,
- services its deadline, and prevents transmission in the same loop where a
- received command starts CW.
-
Compiled production-method tests cover fractional input, malformed durations,
- bounds, timer rollover, busy/IRQ rejection, RXPS cleanup, board TX/RX callbacks,
- profile selection and replacement, failed TX entry, stop retries, and failed
- RX restart. An ESP32 sleep test covers a carrier with USB disconnected.
-
Full V4 repeater, Full T1000-E Companion, and ordinary STM32
- RAK_3x72_companion_radio_usb builds passed. The STM32 build is a compilation
- check, not an RF test of that board.
-
An additional existing OTA sleep test still expects the old
- ota::ota_ctx().apply_pending spelling. It fails against unchanged HEAD
- src/Mesh.cpp and test-file contents; the actual implementation uses
- ota_context_if_active(). This is separate from the CW changes.
-
-
SX1276 follow-up
-
The SX1276 carrier feature from PR #11
-is included alongside SX1262 and LR1110 support. It switches to FSK with zero
-deviation, applies the board's calibrated TX power, and rebuilds the runtime
-LoRa configuration when stopped. External-PA settings pass through the same
-DAC/drive-power mapping used for packets, including RFO selection.
-
The normal TX power command can adjust a running carrier for meter sweeps.
-RadioLib's SX1276 power setter enters standby, so the carrier is restarted
-afterward without extending the deadline. Failed power changes stop the
-carrier and restore the previous cached power.
-
Follow-up checks use base 9dd9881d520b4b791600a00fff1f8e1436921054 plus the
-SX1276 changes. Production-method regression tests cover both profiles,
-zero deviation, external-PA calibration, RFO, power sweeps, timeout, failed
-FSK entry, failed restoration, retry guards, and return to LoRa. The native
-CW paths and existing radio/profile/sleep/PA checks pass as well.
-Both GEPRC_Linkflow_900_repeater (external PA) and
-Heltec_v2_companion_radio_usb firmware builds pass, including size checks.
-
SX1276 RF output has not been measured in this follow-up. The physical RF
-results above apply to SX1262 and LR1110.
-
Bench qualifications
-
The first CW2 request arrived before radio2's existing delayed activation.
-The harness now polls get radio2.status for the active mode before testing.
-
An initial V4 dual-profile packet probe used a 120-symbol preamble against
-32-symbol profiles. A comparison around another CW2 burst received 0/8
-before and 1/8 afterward with that mismatched probe, versus 8/8 before
-and 8/8 afterward with a matching 32-symbol probe. The configured preamble
-also sets the driver's preamble-detection hold timeout, so a much longer
-incoming preamble can outlast that hold and be interrupted by scanning.
-The final dual-profile recovery checks use matched preambles. This finding
-does not establish general packet-loss performance for every scan combination.
-
These checks establish RF activity, selected-frequency behavior, and recovery
-on the tested boards. They do not measure spectral purity, frequency error,
-SWR, calibrated power, or months of uptime. Carrier timeouts are serviced by
-the main loop and depend on that loop remaining responsive.
-
Reproduction
-
Append tools/hil/cw_observer.ini to extra_configs in platformio.local.ini,
-preserving existing entries, and build pio run -e cw_observer_rak4631.
-Flash that application onto a separate lab RAK4631. Do not run PlatformIO
-concurrently with another build or upload in the checkout.
-
Configure the lab DUT's primary profile as above, disable radio2, set TX power
-to −9 dBm, and reboot to apply saved primary settings. Then run:
Use --role companion for the T1000-E. The harness changes lab radio2/RXPS
-settings and emits short RF bursts and packet probes. It is for test boards.
Verify with get powersaving (expect off) and get usb.logging (expect on).
Both settings are saved; disabling logging later does not restore power
-saving. This works around the released USB sleep bug.
+saving. This works around the released USB sleep bug.
nRF52 does not need this ESP32 workaround.
These commands are compiled into ordinary USB-loggable artifacts and every
Full Companion. They control live USB debug and packet output. CommonCLI roles
@@ -8842,7 +9134,7 @@ Station G2/G3 targets default to off.
- state: on or off.
Notes:
- get rxps.wd reports the radio watchdogs' soft and hard recovery counts.
- See receive calibration and recovery for
+ See receive calibration and recovery for
noise sampling, CAD handling, and the continuous-RX mode check.
- get radio.rxps.config adds the persisted level and preamble assumption to
the on/off and timing values. Deployment tools use it to restore a
@@ -9448,7 +9740,7 @@ minutes when the terminal is closed, even with a computer attached. The
source fix blocks ESP32 light sleep while a native USB host is attached or
live USB logging is enabled; ordinary CPU idle/yield remains available.
The G3 button also wakes the device for at least two minutes. See the
-G3 release note
+G3 release note
for verification steps and the distinction between the fix and the published
binaries.
Companion firmware defaults this setting to on. Full Companion accepts the command from its local USB terminal and exposes the same setting in WebConfig. On ESP32, it lowers the CPU clock to 80 MHz, enables idle yielding, and enables the configured GPS duty cycle. USB and each active wireless transport remain available; SenseCAP Indicator Full keeps only its selected BLE or infrastructure-WiFi secondary transport active. set powersaving off restores the board's normal CPU clock and disables the GPS duty cycle. This device setting is separate from LoRa RXPS (radio.rxps) and WiFi modem power save (wifi.powersave). Infrastructure uses the same commands; its hardware and active-service sleep guards determine when the node can sleep.
@@ -9525,7 +9817,7 @@ binaries.
1.17.1.5 infrastructure bug: affected Repeater, Room Server, and Sensor
images accept get path.hash.mode but report unknown config for the setter.
The command was not renamed. The source correction restores the setter;
-installed images need an updated build. See the setting-dispatch audit.
Usage:
- get path.hash.mode
- set path.hash.mode <value>
@@ -11679,7 +11971,7 @@ version field shared by every third-party bootloader. This is diagnostic only:
displaying a version neither grants OTA capability nor bypasses install checks.
The fix is in MeshCore application firmware; installing another bootloader alone
does not update an older application's version reader.
-
The 1.17.1.5 source retained get path.hash.mode in CommonCLI but lost its
-setter when radio preferences moved into CommonRadioPrefs. Infrastructure
-roles call CommonCLI directly, so the shared parser's setter was unreachable.
-The correction restores set path.hash.mode 0|1|2 there, validates the value,
-and saves accepted changes. Missing/invalid values report a value error and
-leave the setting unchanged.
-
The other radio setters removed by the original refactor had already been
-restored. A feature-guarded check found a second mismatch: get extra.sf exposed
-stored data on non-LR2021 radios while its setter was compiled out. Both
-commands now return Error: extra.sf requires an LR2021 radio there. Supported
-LR2021 set/get behavior is preserved. These are source corrections; existing
-release binaries need rebuilding/updating to receive them.
-
Coverage
-
-
-
-
Surface
-
Check
-
-
-
-
-
Common infrastructure CLI
-
72 literal setter keys and 84 query keys; every query has a setter or an explicitly reviewed read-only/alternate-command exception
-
-
-
MQTT/observer CLI
-
33 literal setter keys and 39 query keys, including Wi-Fi, timezone, alerts, display and watchdog settings
-
-
-
MQTT slots
-
All nine writable slot subkeys have query/set coverage; diag is intentionally read-only
-
-
-
Repeater, Room Server, Sensor
-
Shared CLI delegation and role-specific query/set coverage
-
-
-
Companion
-
Shared-radio allowlist and parser agreement, persistence wiring, terminal-specific setters, and role query exceptions
-
-
-
Radio settings moved by the refactor
-
All 13 shared setters remain present in infrastructure dispatch
-
-
-
Literal command comparisons
-
Checks key lengths so a setter cannot accidentally compare its value against the key's terminating NUL
-
-
-
Feature guards
-
Preprocesses common and observer handlers for minimal, nRF52 GPS/SD, ESP32 WebConfig, ESP32 MQTT, RS232/GPS, ESP-NOW, and LR2021 profiles before comparing query/set coverage
-
-
-
-
Read-only exceptions include runtime connection status, diagnostics, firmware
-role, bootloader identity and reset information. Alternate-command exceptions
-include the password command and set battery.alert on <region>. These
-exceptions are explicit in the test, rather than silently allowing all missing
-setters. Dynamic/delegated command families and hardware-specific features
-continue to use their dedicated tests; the inventory is not a claim that every
-build has every feature enabled.
-
Executed behavior tests
-
The native C++ fixture compiles the production get/set dispatch branches and
-the real setting bodies for 14 radio-related settings: radio, freq, af,
-dutycycle, int.thresh, cad, radio.rxgain, tx, rxdelay,
-agc.reset.interval, path.hash.mode, multi.acks, txdelay, and
-direct.txdelay. It runs local and authenticated on-air caller timestamps,
-checks round-trip values and save calls, preserves AGC interval rounding, and
-checks that rejected hardware applies do not save or change preferences.
-Hardware callbacks are mocked; these are not live-radio or flash-durability
-tests. The fixture also runs with and without USE_LR2021, checking supported
-extra.sf set/query/clear behavior, invalid values, and the unsupported-radio
-error.
-
The focused hash-mode test checks all valid modes, missing values, negative and
-out-of-range values, overflow, malformed numbers, whitespace, and similarly
-named unknown keys. Existing transport tests exercise Companion local/framed
-and on-air dispatch, local-only secret reads, and browser/stream routing under
-AddressSanitizer and UndefinedBehaviorSanitizer on Linux.
-
Run the CI checks locally with a host C++ compiler (Linux is required for the
-existing sanitizer-enabled transport suite):
All 14 tests passed on the Linux VM. The workflow runs these commands on future
-pushes and pull requests. The new inventory and native radio tests also passed
-with the Windows host compiler.
-
pio run -e heltec_v4_repeater passed after both corrections, including the
-firmware's flash-size and runtime-RAM checks. The initial audit used host tests
-and build checks; subsequent hardware checks are recorded in the
-dual-profile validation.
@@ -3282,7 +3574,7 @@ USB/BLE profiles, keep 16 outgoing paths
and 16 shared secrets in RAM. Every contact remains in the contact table;
selecting a different contact loads its saved path as needed. This recovers
about 25.4 KiB of internal RAM in the 350-contact ESP32 qualification builds.
-
See the qualification results for the
six-board RAM comparison, physical tests, and shared-secret timings.
PSRAM boards retain their existing complete contact table in external RAM.
Most legacy USB/BLE/WiFi Companion profiles retain inline paths and secrets.
@@ -3408,7 +3700,7 @@ contact caches, and the shared mOTA queue at 350 contacts, 40 channels a
The ordinary six constrained release recipes still use their established
150-contact limits pending wider hardware qualification.
Enable platformio.nimble.ini as described in the
-NimBLE trial guide, then build one environment at
+NimBLE trial guide, then build one environment at
a time. For example: