Commit Graph
1553 Commits
Author SHA1 Message Date
mikecarper 623d2377ec Give dual-profile companion screens manual R2 pages 2026-09-26 01:38:40 -07:00
mikecarper 5802732811 Avoid missing Preferences namespaces on fresh ESP32 boot 2026-09-26 01:14:47 -07:00
mikecarper 20efcea770 Restore Companion text terminal after USB mOTA sender exits 2026-09-25 17:51:38 -07:00
mikecarper 284a67b9ec Drain companion queue on explicit OTA entry 2026-09-25 12:06:18 -07:00
mikecarper 40a9843c24 Merge branch 'keymindCascade' of github.com:mikecarper/MeshCore into keymindCascade
# Conflicts:
#	test/test_nrf52_ble_startup.py
2026-09-24 17:36:09 -07:00
mikecarper 307e7bec02 Complete ESP32 partition expander and adaptive LoRa OTA pacing 2026-09-24 17:13:22 -07:00
mikecarper 640facd5a2 Safely hand off expanded ESP32 LoRa bridge without resume record 2026-09-24 12:17:49 -07:00
mikecarper c0ef07a968 Add LoRa partition migration recipes for ESP32 infrastructure boards 2026-09-24 10:40:32 -07:00
mikecarper e7f6d529a0 Expand ESP32 OTA partition migration across infrastructure roles 2026-09-24 10:01:14 -07:00
mikecarper 1e8ef78a2e Merge observer firmware branch into keymindCascade
Integrate compatible observer board, preset, WebConfig, display, CI, and policy updates. Preserve the checkout's newer MQTT binary preferences and WiFi bridge runtime where the forked implementations conflict. Keep ThinkNode observer networking WiFi-based until the Ethernet transport is wired into that runtime.
2026-09-24 01:20:56 -07:00
mikecarper c31a0e5ed5 Merge upstream dev into keymindCascade 2026-09-24 00:51:07 -07:00
mikecarper 1bc900c33e Select registered OTA slots and verify LoRa staging geometry 2026-09-23 23:33:29 -07:00
mikecarper c55022b001 Add in-place ESP32 Wi-Fi and LoRa partition migration packages 2026-09-23 22:12:45 -07:00
mikecarper dd0ce36176 Refresh nRF52 Companion BLE name without reboot 2026-09-23 14:12:37 -07:00
mikecarper 503bd76d10 fix(build): clear matrix failures while preserving features 2026-09-22 23:23:25 -07:00
mikecarper fe9ab91c99 Fix fallback RNG seed for recoverable Companions 2026-09-22 16:35:44 -07:00
mikecarper 47af95b4b2 Harden nRF52 filesystem recovery and flash writes 2026-09-22 15:17:39 -07:00
mikecarper 7e1f87dfbc Fix nRF52 flash completion and preserve recoverable ExtraFS 2026-09-22 09:29:05 -07:00
mikecarper b7b5b49e71 fix(usb): preserve platform startup ordering 2026-09-22 07:49:40 -07:00
mikecarper 4ff84db400 fix(t1000e): restore single-port usb logging 2026-09-22 07:46:11 -07:00
mikecarper 3282b7898e fix(nrf52): stabilize full companion bluetooth 2026-09-22 05:54:46 -07:00
Scott Powell 560fb847d5 missing board.loop() in companion, room server, kiss modem. 2026-09-22 18:01:15 +10:00
mikecarper 04697db82e feat(radio): calibrate dual-profile preambles from live switch timing 2026-09-22 00:09:37 -07:00
ripplebiz a76d511ff4 Merge pull request #3131 from liekmarflow/feature/board-api-hooks
Add board loop hook for periodic work
2026-09-22 16:43:18 +10:00
Wolfram Keil 61be70849a Add board loop hook for periodic work 2026-09-22 08:01:48 +02:00
mikecarper b089b745fa feat(ui): page radio and system status 2026-09-21 15:35:46 -07:00
Blake Latchford 0c3fe356d0 Constrain agc.reset.interval and allow intervals > 255s 2026-09-21 12:26:36 -04:00
ripplebiz 65737d48f4 Merge pull request #3402 from meshcore-dev/sensor-improvements
Sensor improvements
2026-09-21 19:03:18 +10:00
mikecarper 7657840d38 feat(kiss): add dual-profile radio2 support for OpenHop 2026-09-20 07:59:43 -07:00
ripplebiz b37e7dd955 Merge pull request #3431 from meshcore-dev/abstract-ui-overhaul
Abstract UI overhaul
2026-09-20 18:08:29 +10:00
mikecarper 66b605a49d Add Wi-Fi OTA partition migration support 2026-09-19 20:14:37 -07:00
liamcottle 73afe3a0f5 allow fetching configured wifi password via companion cli 2026-09-20 14:22:13 +12:00
agessaman 7523ac742d fix(network): rebuild the DHCP hostname when the node is renamed
The hostname was built once in begin() from the node name, so `set name` left
the node advertising its old name to DHCP until the next reflash. It is now
rebuilt on rename through a new CommonCLICallbacks::onNodeNameChanged() hook,
and begin() shares the same helper.

What this cannot do is rename a live lease. IDF 4.4 states that a hostname
changed after the interface is up "would only be reflected once the interface
restarts/reconnects", and Arduino 2.x's WiFi.setHostname() does not touch a
running netif at all — it writes a static string that the netif reads at
bring-up. Forcing the issue would mean bouncing the link, which costs every
MQTT slot a reconnect; that is not a reasonable price for a rename, so the new
name lands at the next reconnect or boot instead.

Only automatic (Ethernet-preferred) links carry a hostname today, exactly as
before. Giving plain Wi-Fi observers one would change the DHCP identity of the
existing fleet and is a separate decision.
2026-09-19 15:57:45 -07:00
agessaman 7f28231b25 Merge fix/mqtt-review-2026-09-09 into feat/abstract-networking
#54 lands first, so the network abstraction is reworked on top of the
per-slot client ownership model instead of alongside it.

Two resolutions are semantic, not textual:

- Link-transition teardown goes through the ownership API. It called
  softDisconnect() on every started client, which bypassed client_state and
  ignored the typed result. A slot that is still Starting now gets a real
  stop: softDisconnect() returns immediately on a client that is not yet
  connected, so its attempt would otherwise complete against the old route and
  deliver a CONNECTED event indistinguishable from the new one's (F04). On a
  medium switch the old route can still be briefly usable, so that is not
  hypothetical. A connected client keeps the cheap bounded path, and a
  quarantined one is left alone.

- NetworkLink::applyPowerPrefs() adopts WifiPowerSavePolicy. Its local
  `2 ? MAX : NONE` mapping would have reintroduced F11 and read the new stored
  value 3 (explicit `min`) as none. It also applies the setting when the link
  starts already associated, which is the case the bridge used to cover.

The NTP probe from #54 keeps its validation and its one-attempt-per-server
bound, but resolves and gates on the selected link rather than on WiFi, so it
works on an Ethernet-preferred node.
2026-09-19 15:15:07 -07:00
agessaman 172ef36843 fix(mqtt): gate room-server OTA on an unproven stop; reap late acks
- The room server checked canFlashAfterStop() only when the bridge was
  running at OTA time. After a timed-out restart the bridge reads as
  stopped while its unacknowledged task may still own TLS/client state,
  so an OTA could erase and write flash under it. It now refuses while
  the stop is unproven, after first reaping any late ack. The repeater
  already gated unconditionally.
- MyMesh::loop() now reaps a late stop acknowledgement whenever it lands,
  releasing the withheld queue and buffers, and restarts only when a
  resume is pending and the bridge is enabled. Before, a bridge disabled
  during StopUnproven kept those resources until re-enabled or rebooted.
  pollLateStopAck() is public for this.
- The wrapper's destructor no longer stops an already-stopped client:
  destroySlotClients() had just stopped it, so every shutdown logged five
  spurious "esp_mqtt_client_stop failed: ESP_FAIL" errors.

Hardware (Heltec V4, 1 s test stop deadline): restart -> StopUnproven ->
`set bridge.enabled off`; the late ack was reaped ("releasing withheld
resources"), status read "not running", and `set bridge.enabled on`
started cleanly without a second release.
2026-09-19 14:22:00 -07:00
agessaman 0b75cb9314 fix(mqtt): an explicit bridge stop cancels a pending late-ack resume
setBridgeState(false) returned early when the bridge was already down,
so `set bridge.enabled off` after a timed-out restart left the resume
pending and MQTT restarted against the operator's choice once the task
acknowledged. Disabling now clears the pending resume before that early
return, and the resume also requires bridge_enabled. The StopUnproven
log and `get mqtt.status` no longer say only "reboot to recover", since
a late ack now recovers on its own.

Hardware (Heltec V4, 5 live slots, 1 s test stop deadline): a restart
went StopUnproven, the task acknowledged 27 s later and the bridge
resumed with all slots reconnecting; with `set bridge.enabled off` in
between it stayed stopped until `set bridge.enabled on`.
2026-09-19 13:58:49 -07:00
agessaman 3c03254aa2 fix(mqtt): resume after a late stop ack; bound the hourly NTP refresh
- A stop that timed out into StopUnproven refused begin(), and only a
  later begin() honoured the task's late acknowledgement. Nothing called
  it, so restartBridge() (any `set mqtt...` restart) or an aborted OTA left
  the observer offline for the rest of the boot. MyMesh now records that a
  start was refused and restarts the bridge once stopAcknowledgedLate()
  reports the ack. The OTA-abort alert no longer claims "bridge resumed"
  when the restart was refused.
- refreshNTP() now runs the validated probe with one attempt per server.
  With two attempts and a 1 s pause it blocked the MQTT task ~18 s every
  hour on networks that drop UDP/123, where the old async SNTP cost
  nothing. Loop comment and docs updated to match.
2026-09-19 11:27:01 -07:00
agessaman 44c46ab67f fix(webconfig): read the LAN address after pinning the route
startLanMode() took the caller's IP, read before the route lock. A
Wi-Fi/Ethernet switch in between left WebConfig locked to the new link
while advertising the old link's address. It now reads the selected
link's address after lockSwitching(), as startOTAUpdate() already does.
2026-09-19 10:53:39 -07:00
agessaman b443aabe6b fix(webconfig): persist the admin password before completing Ethernet onboarding
The upstream `password` command saves /prefs.json without reporting the
result, and WebConfig overwrites its reply with "OK". If that write failed
while the later /mqtt.json write succeeded, wifi.setup_complete was set and
the factory password came back after reboot with first-run setup
suppressed. onInitialSetupComplete() now re-saves /prefs.json and records
completion only when it succeeds; otherwise the batch fails, setup stays
open, and no reboot is queued.
2026-09-19 10:35:49 -07:00
agessaman a129420804 fix(network): pre-merge review fixes
- Guard the boot-time link bootstrap to observer ESP32 builds. It ran
  unconditionally in MyMesh::begin(), breaking every non-observer
  repeater/room server build (ESP32 and nRF52).
- Rename NetworkInterface -> NetworkLink (class, accessor, files).
  Arduino-ESP32 3.x ships its own NetworkInterface class and header,
  which broke the ESP32-C6 builds. Drop WiFi.setAutoConnect(), a no-op
  on 2.x and removed in 3.x.
- Refresh stored Wi-Fi credentials every bridge tick so the STA
  reconnect loop picks up `set wifi.ssid` / `set wifi.pwd` without a
  reboot, as the bridge did before the link moved out of it. Skip
  reconnects while the SSID is empty.
- Restore the "WiFi connected: <ip>" / "WiFi disconnected: reason N"
  debug lines the bridge used to print.
- Alert on Ethernet only once it has held a lease this boot or when no
  Wi-Fi is configured; Wi-Fi-only installs of an Ethernet-preferred
  image keep Wi-Fi alerts instead of reporting "Ethernet down".
- Record wifi.setup_complete only for Ethernet LAN onboarding, so
  Wi-Fi builds keep the SSID-based first-boot portal rule.
- Use seq_cst for the route-switch lock/mutation flag handshake.
- Docs: SNMP RSSI sentinel is -127; describe link-return vs medium-switch
  reconnect behavior accurately; note runtime credential pickup.
- Test: unknown keys inside a known /mqtt.json group are ignored, which
  keeps wifi.setup_complete downgrade-safe.
2026-09-19 10:14:16 -07:00
agessaman 8ab6a988aa Merge branch 'observer-firmware-dev' into feat/abstract-networking 2026-09-19 09:23:32 -07:00
Scott Powell 64434c5326 * misc 2026-09-19 20:13:18 +10:00
Kevin Le c425648bfc Off LED before powering off for repeater 2026-09-19 11:26:42 +07:00
mikecarper a37c345dbe Fit Wio companion USB logging 2026-09-18 11:24:18 -07:00
Scott Powell 843598724c * fix for X1 2026-09-18 19:03:20 +10:00
mikecarper 5f7d03373c Fix capacity matrix build regressions 2026-09-17 23:54:11 -07:00
Liam Cottle 166f75c1b6 Merge pull request #3442 from liamcottle/feature/companion-cli-commands
added reboot, shutdown and poweroff to companion cli commands
2026-09-18 18:25:33 +12:00
liamcottle 242e401a2c added reboot, shutdown and poweroff to companion cli commands 2026-09-18 18:17:52 +12:00
agessaman 77398bfc89 Merge upstream/dev into observer-firmware-dev 2026-09-17 21:19:23 -07:00
Blake Latchford 1077331e31 Extend WiFi disconnect logging to specify reason
Today if a user builds firmware with an incorrect WiFi SSID or password,
they get a generic `WiFi disconnected.` error message.

Extend logging to descirbe the reason that WiFi was disconnected.

I gathered the updated logs for the 3 scenarios below.

```
WiFi: Attempting manual WiFi reconnect...
WiFi: WiFi disconnected (reason=ASSOC_LEAVE). Flagging for reconnect...
WiFi: WiFi disconnected (reason=4WAY_HANDSHAKE_TIMEOUT). Flagging for reconnect...
WiFi: WiFi disconnected (reason=4WAY_HANDSHAKE_TIMEOUT). Flagging for reconnect...
WiFi: WiFi disconnected (reason=4WAY_HANDSHAKE_TIMEOUT). Flagging for reconnect...
```

```
WiFi: WiFi disconnected (reason=NO_AP_FOUND). Flagging for reconnect...
```

```
WiFi: WiFi connected successfully!
WiFi: Got connection
```
2026-09-17 19:39:51 -04:00