Skip to content

v0.4.1 — MeshCore 1.16, full companion command set, message-sync fixes

Choose a tag to compare

@laserir laserir released this 25 Jun 11:41

MeshCore 1.16 upgrade, the full companion command set (status/trace, anon-req, explicit-unscoped), and companion message-sync fixes. Update over WiFi (Admin → WiFi → Check for updates) or via the web flasher.

Added

  • Manage rooms and channels from the companion app. The companion protocol gained the standard write/action
    commands the official MeshCore app uses, so things that previously failed against MCLite now work:

    • Room login (CMD_SEND_LOGIN): log into a configured room or repeater from the app. A blank password field
      uses the password already in the device config, and a wrong password instantly retries with the stored one.
      Thanks to the reporters (#32).
    • Add / remove channels (CMD_SET_CHANNEL): join a Public, hashtag, or private channel — or remove one —
      from the app. Adding applies instantly with no reboot — the channel is usable right away and its share QR
      shows the real key, not zeros, with the session staying connected. Removing a channel still reboots to
      apply (a known limitation — MeshCore offers no way to remove a channel from the running radio, so the device
      rebuilds its channel table from config at boot; the app reconnects on its own). Gated by the
      permissions.conversation_management setting, so a locked-down device still refuses it (#31).
    • Add / edit / remove contacts (CMD_ADD_UPDATE_CONTACT, CMD_REMOVE_CONTACT): add a contact, rename one,
      or delete one (and its chat history) straight from the app. Adding and renaming apply instantly (the app
      stays connected); removing reboots to apply (the app reconnects) — see the consistent add/remove model
      below. Editing maps to the contact's display name; per-contact permission flags stay device-owner settings
      (the config tool / on-device Admin), and the app's own contact flags remain app-local. Gated by
      permissions.conversation_management (#33).
    • Share a contact (CMD_SHARE_CONTACT) re-broadcasts a contact's advert so a nearby device can add them,
      and reboot (CMD_REBOOT) is now honoured from the app's button.
    • The app's Local vs Flood advert buttons were already handled; confirmed during this work.
      With this, the companion can fully manage rooms, channels, and contacts (#31, #32, #33 all closed). A consistent
      rule across both contacts and channels: adding and editing apply instantly; removing reboots to apply (the
      app reconnects on its own). The reboot on removal is required for channels — MeshCore has no way to drop a
      channel from the running radio — and kept for contacts so the behaviour is uniform and predictable. Live changes
      are reflected on the device's own UI too — a contact/channel added or renamed from the app shows up in the
      on-device conversation list and Admin screens right away, no reboot. In-place editing of a contact's permission
      flags / a channel's settings still arrives alongside on-device editing.
  • Change device settings from the companion app. With permissions.settings set to full, a connected app
    can now set the device name, radio parameters (frequency / spreading factor / bandwidth / coding rate),
    TX power, the BLE pairing PIN, and the path-hash mode (1/2/3 bytes per hop). Values are range-checked;
    the device name applies instantly to mesh adverts (the Bluetooth scan name refreshes on the next reboot), while
    radio / TX / PIN / path-hash save and apply on a quick reboot (the app reconnects). Path-hash mode is
    especially useful on large meshes — it lets app users match a 3-byte network
    without hand-editing config.json (see #36). A device left at restricted or none refuses these. Identity
    keys, advert location (MCLite advertises GPS at the configured precision), and auto-add stay device-managed by
    design and are rejected.

  • Set the region/scope from the companion app. The companion now honours CMD_SET_DEFAULT_FLOOD_SCOPE (set the
    persistent region), CMD_GET_DEFAULT_FLOOD_SCOPE (read it), and CMD_SET_FLOOD_SCOPE_KEY (a temporary session
    override), gated by permissions.settings = full. Together with the existing path-hash command, the radio's
    region and path-hash size are now both configurable from the app — the two settings a large 3-byte mesh needs.
    A public #region round-trips exactly (MCLite derives the same transport key MeshCore does); a custom/private key
    that isn't derivable from the name is refused.

  • On-device contact/channel/room actions. Tapping a contact in Admin now offers Reset path (force flood
    rediscovery of the route) beside Delete; tapping a channel or room offers Set scope (edit that entry's own
    region override, blank = inherit the global one) beside Delete. A configured override is shown as [scope:…] on
    the row in both the manage and read-only views.

  • Edit region and path-hash size on the device. Admin → Radio now lets you change the region/scope and the
    path-hash size (1/2/3 bytes per hop) directly on-device (a roller for the size, a text editor for the region),
    gated by permissions.settings = full. Both apply on a quick reboot. Handy for matching a large 3-byte mesh
    without the config tool. A blank region means none (*); a bare name like region is treated as #region. The
    other radio params (frequency / SF / BW / CR / TX) stay on the existing region-preset picker + TX slider.

  • More companion commands: reset a contact's path (CMD_RESET_PATH — forces flood rediscovery of the
    route), export a contact (CMD_EXPORT_CONTACT — your own or a known contact's signed advert, as a portable
    blob), and import a contact (CMD_IMPORT_CONTACT — the imported advert appears in Heard Adverts to review
    and save, keeping the contact list curated). Import is gated by permissions.conversation_management.

  • Explicit un-scoped flood scope from the app. The companion app can now force flood sends out un-scoped,
    independent of the configured region (CMD_SET_FLOOD_SCOPE_KEY explicit-unscoped variant). Session-only —
    reverts to the configured scope on reboot. Gated by permissions.settings == "full".

  • Send a request to a node that isn't a contact (CMD_SEND_ANON_REQ). The companion app can query a node
    addressed only by its public key — without adding it as a contact first — and the reply is forwarded back to
    the app. The temporary node is never saved to the contact list. Gated by permissions.settings == "full".
    With this, MCLite now advertises companion firmware-version 13 so apps surface both this and the
    un-scoped-scope option above.

  • Node status and path-trace from the app. Two more standard companion commands: status request
    (CMD_SEND_STATUS_REQ — ask a repeater/node for its status, e.g. uptime and counters) and trace path
    (CMD_SEND_TRACE_PATH — trace the route to a node and report per-hop signal). This completes the companion
    command set MCLite supports.

Changed

  • Updated the MeshCore library 1.15 → 1.16. Brings RadioLib 7.6, an SF-dependent preamble (32 symbols for
    SF ≤ 8, matching the rest of the network for better low-SF link reliability), and upstream fixes (EU
    client-repeat frequency, WiFi reconnect, repeater neighbor-discovery when path-hash mode ≠ 0). Confirmed
    interoperable with 1.16 nodes — including message ACKs — at SF8.

Fixed

  • Companion message sync no longer drops messages on connect. Two issues fixed: the on-connect history
    replay was capped (about two dozen messages) and walked oldest-first, so an active chat could lose its newest
    messages and other chats could sync nothing; and over WiFi a full transport send-queue could silently drop a
    message frame. Sync now streams the full stored history with no cap (newest included, all chats) and only
    removes a message once the transport confirms it was sent — so reconnecting shows everything you received.
    Works the same over WiFi and Bluetooth. (Note: messages you type on the device still don't appear in the
    app — the MeshCore companion protocol has no outgoing-message frame; see the README.)
  • Region scope without a leading # now matches MeshCore. A region/flood-scope written as a bare name (e.g.
    region instead of #region) was hashed literally, producing a different transport key than the rest of the
    network. MCLite now prepends # to a bare name before deriving the key — mirroring MeshCore's implicit-hashtag
    behavior — so region and #region are the same region and interoperate. (#/$ prefixes pass through
    unchanged; explicit #region configs are unaffected.)
  • Custom canned-message list (global) was lost on save. A canned_messages array configured at the messaging
    level was serialized back as a bare true, so the custom list vanished on the next boot — and with the new
    companion config writes, almost any settings change triggered it. Serialization now writes the array faithfully
    (and honors the on/off toggle, so a disabled state also persists). Per-conversation canned lists
    (per contact/channel/room) were always stored separately and were never affected. Thanks @jason-s13r (#34).
  • Non-English devices ignored a configured global canned list in the chat quick-reply picker. The picker only
    honored a custom canned_messages array when the UI language was English; on other languages it always showed
    the translated defaults. A configured custom array is an explicit, language-independent choice and now wins
    regardless of language (translated defaults still apply when no custom array is set). Thanks @jason-s13r (#34).

Full changelog: https://github.com/laserir/MCLite/blob/v0.4.1/CHANGELOG.md