Expand and harden full companion profiles

This commit is contained in:
mikecarper committed 2026-08-24 01:57:38 -07:00
1 parent f2d4ffbb7e
commit dc92ee61ef
44 files changed
+1522 -226

No files matched your search

+43 -18
View File
@@ -381,10 +381,31 @@
/(?:^|[_-])(?:ps|femoff)(?=$|[_-])/.test(lowerTarget));
}
function omitNrf52TransportsReplacedByFull(profiles) {
function isDualCdcFullCompanion(profile) {
if (!profile || profile.role !== "companion" || profile.mode !== "full") {
return false;
}
if (profile.installKinds.includes("zip")) return true;
const target = String(profile.target || "").toLowerCase();
if (/^heltec_v4(?:_2_v4_3|_3)?(?:_r8)?(?:_tft)?_companion_radio_full(?:_|$)/
.test(target)) {
return true;
}
return [
"lilygo_tbeam_1w_companion_radio_full",
"station_g2_companion_radio_full",
"station_g3_esp32_companion_radio_full",
"xiao_s3_wio_companion_radio_full",
"heltec_tracker_v2_companion_radio_full_femon",
"meshnology_w12_companion_radio_full",
"nibble_screen_connect_companion_radio_full_",
"nibble_zero_connect_companion_radio_full_",
].includes(target);
}
function omitTransportsReplacedByDualCdcFull(profiles) {
const fullKeys = new Set((profiles || []).filter(function (profile) {
return profile.role === "companion" && profile.mode === "full" &&
profile.installKinds.includes("zip");
return isDualCdcFullCompanion(profile);
}).map(function (profile) {
return profile.hardware + "\n" + profile.variant;
}));
@@ -392,20 +413,19 @@
return (profiles || []).filter(function (profile) {
const key = profile.hardware + "\n" + profile.variant;
const replacedAttachedTransport = profile.role === "companion" &&
(profile.mode === "usb" || profile.mode === "ble");
(profile.mode === "usb" || profile.mode === "ble" ||
profile.mode === "wifi");
return !(replacedAttachedTransport && fullKeys.has(key));
});
}
function applyNrf52FullCompanionCapabilities(profiles) {
function applyDualCdcFullCompanionCapabilities(profiles) {
return (profiles || []).map(function (profile) {
const nativeNrf52Full = profile.role === "companion" &&
profile.mode === "full" && profile.installKinds.includes("zip");
if (!nativeNrf52Full) return profile;
if (!isDualCdcFullCompanion(profile)) return profile;
// Current nRF52 Full Companion images expose two CDC ACM interfaces:
// framed Companion traffic on interface 00 and plaintext logging on 02.
// The saved USB logging gate covers only the second interface.
// Supported Full Companion images always expose framed Companion traffic
// on interface 00. Logging defaults off; enabling it and rebooting adds
// the independent plaintext CDC interface 02.
profile.logging = "usb-runtime";
profile.loggingModes = ["none", "usb"];
profile.dedicatedUsbLogging = true;
@@ -512,8 +532,8 @@
}).filter(function (profile) {
return !isHiddenLegacyProfile(profile);
});
const profiles = omitNrf52TransportsReplacedByFull(
applyNrf52FullCompanionCapabilities(visibleProfiles)
const profiles = omitTransportsReplacedByDualCdcFull(
applyDualCdcFullCompanionCapabilities(visibleProfiles)
).sort(function (a, b) {
return a.target.localeCompare(b.target, undefined, {
numeric: true,
@@ -712,11 +732,11 @@
);
} else if (profile.logging === "usb-runtime") {
extra.push(
"Use get usb.logging and set usb.logging off|on to choose and save normal output-off or USB packet logging."
"Full Companion starts with USB logging off and only interface 00. Use get usb.logging, or set usb.logging on reboot to save logging on and reboot when needed; set usb.logging off reboot removes interface 02 again."
);
if (profile.dedicatedUsbLogging) {
extra.push(
"This nRF52 Full Companion exposes two serial ports on one USB cable: interface 00 carries Companion/terminal/mOTA traffic and interface 02 carries plaintext logging. Match services by USB interface number instead of assuming tty or COM numbering."
"Interface 00 always carries Companion/terminal/mOTA traffic. After logging is enabled and the node reboots, interface 02 carries plaintext logs. Match services by USB interface number instead of assuming tty or COM numbering."
);
}
}
@@ -757,7 +777,7 @@
if (profile.dedicatedUsbLogging) {
factRows.splice(3, 0, [
"USB port split",
"Interface 00 Companion; interface 02 logging",
"Interface 00 always; interface 02 after logging on + reboot",
]);
}
replaceFacts(facts, factRows);
@@ -1086,10 +1106,15 @@
flattenReleaseAssets: flattenReleaseAssets,
parseFirmwareAsset: parseFirmwareAsset,
parseTargetProfile: parseTargetProfile,
applyDualCdcFullCompanionCapabilities:
applyDualCdcFullCompanionCapabilities,
applyNrf52FullCompanionCapabilities:
applyNrf52FullCompanionCapabilities,
applyDualCdcFullCompanionCapabilities,
canonicalHardware: canonicalHardware,
omitNrf52TransportsReplacedByFull: omitNrf52TransportsReplacedByFull,
omitTransportsReplacedByDualCdcFull:
omitTransportsReplacedByDualCdcFull,
omitNrf52TransportsReplacedByFull:
omitTransportsReplacedByDualCdcFull,
hardwareFamilyFor: hardwareFamilyFor,
humanizeHardwareVariant: humanizeHardwareVariant,
buildCatalog: buildCatalog,
+14 -8
View File
@@ -41,7 +41,7 @@ retain 50 because their MQTT discovery tables are constrained by internal DRAM.
| ESP32 MQTT observer or ESP-NOW bridge | Always uses the expanded FULL partition profile. The build never substitutes a reduced CLI to fit the legacy application slot. |
| FULL ESP32 USB + WiFi | Uses the matching MQTT target with packet logging on, verbose debug off, and the complete command surface supported by that role and hardware. `get/set logging.output off\|usb\|wifi\|both` selects and persists the active output paths. |
| FULL ESP32 logging fallback | Uses the matching non-MQTT target only when no WiFi MQTT sibling exists, with debug and packet logging enabled and the complete command surface supported by that role and hardware. Its persistent USB gate also covers output-off operation, avoiding a second FULL ESP-NOW image. |
| nRF52 Full Companion | Uses one physical USB connection with interface `00` for framed Companion/terminal/mOTA traffic and interface `02` for plaintext logging. It also provides BLE and source-only LoRa OTA. `get/set usb.logging` persistently gates only the logging interface. |
| Dual-CDC Full Companion | nRF52 and qualified native-USB ESP32-S3 Full images use one physical USB connection. Fresh installs expose only interface `00` for framed Companion/terminal/mOTA traffic. Enabling logging and rebooting adds interface `02` for plaintext logs. They also provide BLE and source-only LoRa OTA; ESP32 additionally provides WiFi. `get/set usb.logging` persistently controls whether the logging interface is present. |
| `no_external_sensors` | Removes optional external-sensor drivers and their settings; it does not remove core repeater discovery or routing commands. GPS-preserving RAK nRF52 OTA profiles retain their GPS commands and provider. The RAK4631 Serial1 RS232 bridge remains GPS-off because both features require Serial1. |
`logging`, `OTA`, and `FULL` describe independent build features. Do not infer
@@ -61,19 +61,25 @@ available from a canonical image:
replaced by their ordinary Station target. G2 boosted receive gain is the
persisted `radio.rxgain on|off` setting; the G3 alias changed only the
advertised default name.
- When an nRF52 board has a generated Full Companion, that one artifact
replaces its separate USB, BLE, and USB packet-logging Companion artifacts.
It provides BLE plus two USB CDC interfaces: interface `00` carries framed
Companion/terminal/mOTA traffic and interface `02` carries plaintext logs.
- When a board has a dual-CDC Full Companion, that one artifact replaces its
separate USB, BLE, ordinary WiFi, and USB packet-logging Companion artifacts.
Current support includes nRF52 Full Companion plus qualified native-USB
ESP32-S3 Full targets: Heltec V4, T-Beam 1W, Station G2/G3, XIAO S3 WIO,
Heltec Tracker V2, Meshnology W12, and Nibble Screen/Zero Connect. RAK3112
and Heltec RC32 keep separate transport and logging artifacts pending live
hardware validation.
It provides BLE plus an always-present interface `00` for framed
Companion/terminal/mOTA traffic. Enabling logging and rebooting adds
interface `02` for plaintext logs.
Its LoRa OTA support is source-only: it can serve a host file to another node
but has no staging store and cannot update itself over LoRa.
The old aliases still work with `build-firmware` and
`build-matching-firmwares`. Dedicated repeater LoRa OTA receiver images are not
collapsed; they retain their exact storage, bootloader, role, and target
identity contracts. ESP32 USB, BLE, WiFi, and Full Companion images also remain
separate because Full changes partitions, RAM use, active transports, and power
behavior.
identity contracts. ESP32 boards without the tested dual-CDC Full profile keep
USB, BLE, WiFi, and Full Companion images separate because Full changes
partitions, RAM use, active transports, and power behavior.
## Complete CLI policy
+2 -2
View File
@@ -71,7 +71,7 @@ fix, no WiFi connection, an inactive bridge, or an nRF52 bootloader without
| Statistics | [`get telemetry.temp/volt`; optional GPS history; `get/set telemetry.tx`](cli_commands.md#read-repeater-telemetry-history) | Non-STM32 repeater; GPS commands require a GPS provider; remote access requires administrator | Yes | Yes | Yes |
| Logging | [`log start`; `log stop`; `log erase`](cli_commands.md#logging) | Storage-backed roles retain data; other roles can return empty data | Yes | Yes | Yes |
| Logging | [`log`](cli_commands.md#print-the-captured-log-to-the-serial-terminal) | Local serial | Serial | Serial | Serial |
| Logging | [`get/set usb.logging`; unified FULL `get/set logging.output`](cli_commands.md#control-live-usb-logging) | Logging artifacts; CommonCLI USB gate is persistent; unified ESP32 FULL selects off/USB/WiFi/both; nRF52 Full Companion gates its second USB port | No | Yes | No |
| Logging | [`get/set usb.logging`; unified FULL `get/set logging.output`](cli_commands.md#control-live-usb-logging) | Logging artifacts; CommonCLI USB gate is persistent; unified ESP32 FULL selects off/USB/WiFi/both; dual-CDC Full Companion adds/removes its second USB port after reboot | No | Yes | No |
| Radio | [`get radio`; `set radio ...`](cli_commands.md#view-or-change-this-nodes-radio-parameters) | All text CLI roles | Yes | Yes | Yes |
| Radio | [`get tx`; `set tx <dbm>`](cli_commands.md#view-or-change-this-nodes-transmit-power) | Board TX-power limits apply | Yes | Yes | Yes |
| Radio | [`tempradio ...`; `normalradio`](cli_commands.md#change-the-radio-parameters-for-a-set-duration) | Full parser | Yes | Yes | Yes |
@@ -233,7 +233,7 @@ fix, no WiFi connection, an inactive bridge, or an nRF52 bootloader without
| Statistics | [`get telemetry.temp/volt`; optional GPS history; `get/set telemetry.tx`](cli_commands.md#read-repeater-telemetry-history) | Non-STM32 repeater; GPS commands require a GPS provider; remote access requires administrator | Yes | Yes | Yes | Yes | Yes |
| Logging | [`log start`; `log stop`; `log erase`](cli_commands.md#logging) | Storage-backed roles retain data | Yes | Yes | Yes | Yes | Yes |
| Logging | [`log`](cli_commands.md#print-the-captured-log-to-the-serial-terminal) | Local serial | Serial | Serial | Serial | Serial | Serial |
| Logging | [`get/set usb.logging`; unified FULL `get/set logging.output`](cli_commands.md#control-live-usb-logging) | Logging artifacts; CommonCLI USB gate is persistent; unified ESP32 FULL selects off/USB/WiFi/both; nRF52 Full Companion gates its second USB port | No | Yes | No | No | Yes |
| Logging | [`get/set usb.logging`; unified FULL `get/set logging.output`](cli_commands.md#control-live-usb-logging) | Logging artifacts; CommonCLI USB gate is persistent; unified ESP32 FULL selects off/USB/WiFi/both; dual-CDC Full Companion adds/removes its second USB port after reboot | No | Yes | No | No | Yes |
| Radio | [`get radio`; `set radio ...`](cli_commands.md#view-or-change-this-nodes-radio-parameters) | All text CLI roles | Yes | Yes | Yes | Yes | Yes |
| Radio | [`get tx`; `set tx <dbm>`](cli_commands.md#view-or-change-this-nodes-transmit-power) | Board TX-power limits apply | Yes | Yes | Yes | Yes | Yes |
| Radio | [`tempradio ...`; `normalradio`](cli_commands.md#change-the-radio-parameters-for-a-set-duration) | Full parser | Yes | Yes | Yes | Yes | Yes |
+20 -3
View File
@@ -538,13 +538,30 @@ emitted only when that hardware/role has no matching WiFi MQTT environment.
get usb.logging
set usb.logging on
set usb.logging off
set usb.logging on reboot
set usb.logging off reboot
```
These commands are compiled into logging artifacts and control their live USB
debug and packet output. CommonCLI roles save the setting in `/com_prefs`, so
it survives reboot; first boot defaults to on. nRF52 Full Companion applies the
gate only to USB interface `02`, its dedicated plaintext logging port. USB
interface `00` continues carrying Companion, terminal, and serial mOTA traffic.
it survives reboot; their first boot defaults to on.
On Full Companion these lines belong to its text terminal, not `meshcli`'s
Binary `get/set` parameter namespace. Open interface `00`, send
`+++MESHCORE-TERM-START`, and then issue the command. Running
`meshcli ... get usb.logging` directly can instead return
`Unknown var usb.logging` because that is a different protocol operation.
Dual-CDC Full Companion instead defaults logging to off and enumerates only
USB interface `00`, which carries Companion, terminal, and serial mOTA traffic.
Enabling logging adds interface `02`, its dedicated plaintext logging port, on
the next boot. Disabling it removes interface `02` on the next boot. A command
without the optional `reboot` argument saves the choice and reports that a
reboot is required when the USB interface count must change. The exact
`set usb.logging on reboot` and `set usb.logging off reboot` forms save the
choice, send their reply, and reboot one second later only when needed. This
behavior includes nRF52 and qualified native-USB ESP32-S3 Full images.
Turning USB logging off does not disable CLI replies or Companion protocol
frames. It also does not change the node-storage capture controlled by `log
start` and `log stop`.
+52 -19
View File
@@ -11,6 +11,7 @@ firmware as an mOTA image.
| USB Binary Companion | Yes | Yes |
| BLE Binary Companion | Yes | Yes |
| USB ASCII terminal | Yes | Yes |
| Dedicated USB plaintext logging | Qualified native-USB ESP32-S3 profiles | Yes |
| Host-backed LoRa mOTA source | WiFi TCP 5001 | Exclusive USB mode |
| WiFi Companion/WebConfig | Yes | No - nRF52840 has no WiFi |
| LoRa self-update | No | No |
@@ -50,11 +51,12 @@ bash build.sh build-full-companion-firmwares \
Canonical Companion bulk builds also omit legacy `_ps` and `_femoff` aliases.
Power saving and controllable FEM receive gain are persisted runtime settings;
the old names remain available through an explicit `build-firmware` command
for compatibility. On nRF52, Full Companion replaces separate USB and BLE
normal release artifacts whenever the exact board has both recipes. It also
replaces the USB-only packet-logging artifact: one physical USB connection
enumerates separate Companion and logging serial ports, so plaintext logs
cannot corrupt binary frames. In WebConfig, use the
for compatibility. Dual-CDC Full Companion replaces separate USB, BLE,
ordinary WiFi, and USB-only packet-logging release artifacts whenever the
exact board supports the combined profile. This includes nRF52 Full Companion
and the qualified native-USB ESP32-S3 profiles listed below. One physical USB
connection can enumerate separate Companion and logging serial ports, so
plaintext logs cannot corrupt binary frames. In WebConfig, use the
**FEM RX boost** switch. From the text terminal (USB, or TCP 5002 on ESP32), use:
```text
@@ -248,30 +250,61 @@ The terminal supports Companion chat commands, including `channels`,
WiFi credential, status, WebConfig, CLI-tab, and power-save controls. Logging
artifacts additionally provide `get/set usb.logging`; turning it off
suppresses live USB diagnostics without disabling Companion frames or terminal
replies. nRF52 Full Companion saves this setting and applies it only to its
dedicated logging port.
replies. Dual-CDC Full Companion saves this setting and applies it only to its
dedicated logging port. It starts off on a fresh installation.
### nRF52 dual USB serial ports
### Dual USB serial ports
Current nRF52 Full Companion firmware exposes two CDC ACM serial interfaces on
one physical USB cable:
Current nRF52 Full Companion and qualified native-USB ESP32-S3 Full Companion
firmware can expose two CDC ACM serial interfaces on one physical USB cable:
- USB interface `00` is the normal Binary Companion, text terminal, and serial
mOTA source port.
- USB interface `02` is a write-only plaintext packet/debug logging port. Host
input on this interface is ignored and cannot invoke firmware commands.
mOTA source port. It is always present.
- USB interface `02` is the optional write-only plaintext packet/debug logging
port. Host input on this interface is ignored and cannot invoke firmware
commands.
On Linux these normally appear as two `/dev/ttyACM*` devices. Match the stable
A fresh Full Companion starts with USB logging off and therefore enumerates
only interface `00`. Use `set usb.logging on` to save logging on; the reply says
that a reboot is required. Use `set usb.logging on reboot` to save it and have
the node reboot automatically after the reply. The second interface appears
after that reboot. Likewise, `set usb.logging off reboot` removes interface
`02`. The optional `reboot` word is accepted only in these exact command forms
and triggers a reboot only when the descriptor actually needs to change.
These are Full Companion **text-terminal** commands. The superficially similar
`meshcli ... get usb.logging` command uses the Binary Companion parameter
registry and can report `Unknown var usb.logging`; it does not forward that
line to the text terminal. Enter terminal mode on interface `00` with the
`+++MESHCORE-TERM-START` token as described above, then issue the command.
When logging is on, Linux normally shows two `/dev/ttyACM*` devices. Match the stable
`/dev/serial/by-id/*-if00` and `*-if02` links, or use a udev rule matching
`ID_USB_INTERFACE_NUM`, rather than assuming which tty number is assigned. On
Windows they appear as two COM ports; identify them by USB interface instead of
depending on a particular COM number. The bootloader may temporarily expose
only its normal DFU serial interface while an update is active.
depending on a particular COM number. The nRF52 bootloader temporarily exposes
its normal DFU serial interface during an update. Qualified S3 boards
temporarily expose the ESP32-S3 ROM USB-JTAG serial port during a wired flash.
Qualified ESP32-S3 targets are Heltec V4, T-Beam 1W, Station G2/G3, XIAO S3
WIO, Heltec Tracker V2, Meshnology W12, and Nibble Screen/Zero Connect. The
base Heltec V4 profile has completed live two-interface, ROM-flashing, and
logging-off one-interface validation. RAK3112 and Heltec RC32 retain separate
transport and logging images pending hardware validation. Boards whose
connector terminates at an external USB-UART bridge also keep their
transport-specific images: firmware cannot add a second USB interface to that
bridge chip.
Every ESP32-S3 Full Companion image uses DIO flash mode, including the RAK3112
and RC32 profiles that do not expose dual CDC. The S3 ROM supports DIO while
loading the software bootloader, and some flash configurations fail before the
application starts when a merged image inherits QIO. DIO trades some maximum
flash-read throughput for compatibility; it does not change a board's PSRAM
type or any ordinary non-Full firmware profile.
Point MeshCore Companion software, `meshcli`, and `motatool` at interface `00`.
Point a plaintext reader or USB-connected MQTT service at interface `02`. Use
`set usb.logging off|on` through the Companion terminal to persist whether the
second port emits output.
When enabled and rebooted, point a plaintext reader or USB-connected MQTT
service at interface `02`.
ESP32 Full Companion exposes this same text terminal on TCP port 5002. Connect
with `nc DEVICE_IP 5002`; no USB control token is needed. USB terminal mode and
+23 -11
View File
@@ -168,12 +168,22 @@ next reboot or power cycle. An explicit administrator `start webconfig` remains
available as an override. A saved SSID switches to the normal indefinite
reconnect behavior instead.
Current nRF52 Full Companion profiles also use one binary for normal attached
Companion use and USB packet logging. One USB cable exposes interface `00` for
Binary Companion, terminal, and mOTA source traffic, plus interface `02` for
plaintext logging. The picker therefore omits the older separate nRF52 USB,
BLE, and USB-logging Companion choices when the matching Full artifact exists.
Use `set usb.logging off|on` to persist the second port's output state.
Current dual-CDC Full Companion profiles also use one binary for normal
attached Companion use and USB packet logging. This includes nRF52 and
qualified native-USB ESP32-S3 Full images. Fresh installs default to logging off and expose only
interface `00` for Binary Companion, terminal, and mOTA source traffic. Enabling
logging and rebooting adds interface `02` for plaintext logs. The picker
therefore omits older separate USB, BLE, ordinary WiFi, and USB-logging
Companion choices when the matching Full artifact exists. Use
`set usb.logging on reboot` or `set usb.logging off reboot` to persist the
choice and apply the corresponding USB interface count.
Qualified ESP32-S3 hardware currently includes Heltec V4, T-Beam 1W, Station
G2/G3, XIAO S3 WIO, Heltec Tracker V2, Meshnology W12, and Nibble Screen/Zero
Connect layouts. The base Heltec V4 profile has completed live two-interface,
ROM-flashing, and logging-off one-interface validation. RAK3112 and Heltec RC32
retain separate transport and logging images pending hardware validation, as do
Heltec V3/WSL3, ThinkNode M2/M5/M7/M9, classic ESP32, and ESP32-C3 targets.
## Installation methods
@@ -210,8 +220,10 @@ saving, controllable FEM receive gain, and radio-chip receive gain are saved
settings rather than separate recommended firmware files. Do not substitute a
similarly named physical target.
For nRF52 hardware with a Full Companion image, the picker recommends that one
normal image instead of separate USB, BLE, and USB-logging images. Full
Companion provides both attached transports and a dedicated plaintext logging
port without mixing logs into framed Companion traffic. Exact filename search
still finds old aliases from earlier releases.
For hardware with a dual-CDC Full Companion image, the picker recommends that
one normal image instead of separate USB, BLE, ordinary WiFi, and USB-logging
images. Full Companion provides the attached transports and a dedicated
plaintext logging port when enabled without mixing logs into framed Companion
traffic. Logging is off by default, so only the framed port appears until it is
enabled and the node reboots.
Exact filename search still finds old aliases from earlier releases.
+6 -4
View File
@@ -53,12 +53,14 @@ reopening the controller while `motatool` owns the source port. The script
rejects an attempt to use the same port for both.
The USB ASCII switch (`+++MESHCORE-TERM-START`) is the local control path, not
the mOTA data framing. On an nRF52 full Companion, the script uses that mode
the mOTA data framing. On a dual-CDC full Companion, the script uses that mode
briefly for `ota status` and TempRadio commands. It then closes the CLI and
starts `motatool`, whose existing `ota folder on` preamble switches the same
USB interface `00` into exclusive mOTA mode. Its separate USB interface `02`
continues to provide plaintext logging and is not a controller or source port.
On an ESP32 Full Companion with serial folder support,
USB interface `00` into exclusive mOTA mode. If USB logging was enabled and the
Full Companion rebooted, its separate interface `02` continues to provide
plaintext logging and is not a controller or source port. With default logging
off, interface `02` is not enumerated.
On a native-USB ESP32-S3 Full Companion with serial folder support,
`motatool --companion-terminal` keeps the ASCII session open
while the same link carries framed folder requests. BLE remains available.
+5 -3
View File
@@ -94,11 +94,13 @@ GPS idle behavior; it does not change LoRa RXPS or WiFi modem sleep.
```
get usb.logging
set usb.logging {on|off}
set usb.logging {on|off} [reboot]
```
Shows or changes live USB debug and packet output in a Companion logging
artifact. The setting lasts until reboot; logging starts on again at the next
boot. Companion protocol frames and terminal replies remain enabled.
artifact. The setting is persistent. Dual-CDC Full Companion defaults off;
changing its USB interface count requires a reboot, and the optional exact
`reboot` argument performs that reboot after sending the reply. Companion
protocol frames and terminal replies remain enabled on interface `00`.
```
get radio.rxps