Commit Graph
1182 Commits
Author SHA1 Message Date
agessaman 480c540bf8 feat(repeater): set ADC multiplier during MyMesh initialization 2026-10-18 14:42:53 -07:00
Adam Gessaman 021f45aa36 Merge upstream/dev (v1.18.0) into observer-firmware-dev 2026-10-15 17:30:23 -07:00
Scott Powell 07a833bbbe * version 1.18.0 2026-10-15 19:42:01 +11:00
Liam Cottle 2586f7abe3 Merge pull request #3591 from liamcottle/feature/companion-ble-wifi
Add WiFi support to Heltec v3 and v4 BLE variants
2026-10-14 20:23:11 +13:00
liamcottle a0fc769660 rework companion ui for ip address so it fits in multi interface variants 2026-10-14 16:29:41 +13:00
agessaman 14b487da81 Merge upstream/dev into observer-firmware-dev
Preserve observer discovery when forwarding is disabled while honoring hidden-node settings. Keep GPS power ownership paired and incorporate upstream GPS diagnostics.
2026-10-13 19:10:10 -07:00
Scott Powell 481f72cae7 * only 'repeat on' now intercepted 2026-10-14 12:21:38 +11:00
Scott Powell 8579c66747 * Room: "set repeat" CLI now deprecated 2026-10-14 11:48:58 +11:00
Scott Powell f19733e478 * don't respond to DISCOVER requests if node has adverts turned off. (isHiddenNode()) 2026-10-04 15:02:00 +11:00
agessaman baf01a5c16 Merge branch 'feat/ota-branch-switch' into merge/ota-branch-into-observer-firmware-dev
# Conflicts:
#	examples/simple_repeater/MyMesh.cpp
2026-10-03 15:47:01 -07:00
agessaman f652e7d185 fix(ota): flash the channel ota update checked, not a later ota branch
The deferred flash re-read the channel preference ~2.5 s after ota update
acknowledged its target; capture it when the update is scheduled.
2026-10-03 15:37:49 -07:00
agessaman ee88192acb Merge branch 'feat/ota-branch-switch' into merge/ota-branch-into-observer-firmware-dev
# Conflicts:
#	.github/workflows/build-observer-firmwares.yml
#	examples/simple_repeater/MyMesh.cpp
#	examples/simple_room_server/MyMesh.cpp
#	src/helpers/ESP32Board.cpp
#	src/helpers/ESP32Board.h
#	test/test_config_serializer/test_config_serializer.cpp
2026-10-03 15:24:33 -07:00
Elektr0Vodka 942a19eb63 feat(ota): pass runtime manifest base through otaFromManifest
(cherry picked from commit 0bee84c0546780b2e7147148c32087e92d894ac0)
2026-10-03 15:17:36 -07:00
Huw Duddy 37a71d9381 Merge pull request #3495 from meshcore-dev/increase-max-search-results
increased MAX_SEARCH_RESULTS to 24. (was 8)
2026-09-29 20:42:48 +10:00
agessaman 6baffa753c Merge upstream/dev into observer-firmware-dev
Picks up 35 upstream commits through 988d017a: board loop() hook,
sensor SUBSCRIBE/telemetry push, companion MyMesh::Listener UI refactor,
agc.reset.interval widened to uint16, LR1121 DC-DC, ThinkNode M4 and
Muzi Base boards, M7 companion WiFi.
2026-09-26 09:32:09 -07:00
Scott Powell b204f9a114 * changed onUnhandledResponse() to return true if handled/consumed
* unhandled responses (eg. push telemetry) now sent to app as PUSH_CODE_BINARY_RESPONSE frames
2026-09-24 13:49:57 +10:00
Scott Powell f9e70426ae increased MAX_SEARCH_RESULTS to 24. (was 8)
Closes #3243
2026-09-24 13:35:27 +10:00
Scott Powell 560fb847d5 missing board.loop() in companion, room server, kiss modem. 2026-09-22 18:01:15 +10: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
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
ripplebiz b37e7dd955 Merge pull request #3431 from meshcore-dev/abstract-ui-overhaul
Abstract UI overhaul
2026-09-20 18:08:29 +10:00
liamcottle 73afe3a0f5 allow fetching configured wifi password via companion cli 2026-09-20 14:22:13 +12:00
agessaman da6406e92f 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 25f26c3058 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 16562621a2 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 d180f097ea 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 f50a6a3940 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 3c39908720 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 eb39ca59e7 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 4c683b13b3 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 ad65f64156 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
Scott Powell 843598724c * fix for X1 2026-09-18 19:03:20 +10: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 d42c4249a5 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
Scott Powell b3b17025e3 * more MyMesh::Listener interface hooks 2026-09-17 17:33:36 +10:00
Scott Powell 30dd723c26 * MyMesh::begin() refactor, removing last display concepts 2026-09-17 14:25:41 +10:00
Scott Powell 5c3d9281ff * refactored the UI_DISCOVER_* feature 2026-09-17 13:45:33 +10:00
Scott Powell 3caf033de2 * refactor: removed UITask dependency from MyMesh. New MyMesh::Listener interface
* UITask's are now a MyMesh task Listener
2026-09-16 21:03:44 +10:00
Scott Powell 53b6476409 Merge branch 'dev' into wio-tracker-L1-1W 2026-09-15 18:24:52 +10:00
Scott Powell 3819a0bd89 * subscribe response now returns expiry_secs (not timestamp) 2026-09-15 17:17:48 +10:00
Scott Powell bc8ccefafe * fix for telemHasChanged() 2026-09-14 20:23:10 +10:00
Scott Powell df82dc2339 * min_deltas now mandatory 2026-09-13 11:05:38 +10:00
Scott Powell d69ae98b5a * telemHasChanged() mod, so that only _specified_ min_delta values are considered. 2026-09-12 16:53:45 +10:00
ripplebiz 0984111d62 Merge pull request #3395 from jbrazio/fix/serial-command-clamp
[HIGH] Ensure command buffers stay NUL-terminated to prevent overflow
2026-09-11 14:09:24 +10:00