Handle USB mode queries in the existing getter paths

This commit is contained in:
mikecarper committed 2026-10-28 03:21:36 -07:00
1 parent 749ee1e2e5
commit f0bcb10ff0
5 files changed
+38 -25

No files matched your search

+2 -4
View File
@@ -1785,7 +1785,7 @@ bool MyMesh::resolveChannelAlias(ChannelDetails& channel) const {
})) return false;
const auto kind = parseCompanionChannelAlias(channel.name).kind;
#if MESH_ENABLE_MESHTEXT_CHAT
if (kind == CompanionChannelKind::Meshtext) channel.channel.tx_radio = mesh::RADIO_TX_OFF;
if (isMeshtextChannel(channel)) channel.channel.tx_radio = mesh::RADIO_TX_OFF;
#endif
if (isAliasRadio2Defined()
&& (kind == CompanionChannelKind::Radio2 || kind == CompanionChannelKind::Meshtext)) {
@@ -4078,11 +4078,11 @@ bool MyMesh::handleTxRoutingCommand(const char* command, char* reply, size_t rep
return true;
}
__attribute__((noinline, cold))
bool MyMesh::handleLocalControlCommand(const char* command, char* reply,
size_t reply_size) {
if (!command || !reply || reply_size == 0) return false;
while (*command == ' ') command++;
if (mesh::handleUsbModeCommand(command, reply, reply_size, Serial)) return true;
#if defined(ESP32_PLATFORM) && defined(WIFI_SSID)
if (strncmp(command, "password", 8) == 0
&& (command[8] == 0 || command[8] == ' ' || command[8] == '\t')) {
@@ -11139,8 +11139,6 @@ bool MyMesh::handleCommand(const char* command, uint32_t sender_timestamp,
while (*command == ' ' || *command == '\t') command++;
}
if (mesh::handleUsbModeCommand(command, reply, reply_capacity, Serial)) return true;
#if defined(ESP32_PLATFORM)
// Catch remote requests before the direct-transport router below. That
// router is also used by USB/BLE/browser commands without a timestamp.
+1 -1
View File
@@ -3560,7 +3560,6 @@ bool CommonCLI::handleUDPBridgeCommand(uint32_t sender_timestamp,
void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* reply) {
PrefsSaveReplyGuard save_reply(_prefs_save_failures, reply);
mesh::cli::normalizeCommandVerb(command);
if (mesh::handleUsbModeCommand(command, reply, 160, Serial)) return;
#if MESH_ENABLE_HOST_KISS
if (mesh::hostkiss::handleCommand(command, reply, 157, sender_timestamp == 0)) return;
#endif
@@ -5992,6 +5991,7 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep
}
void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* reply) {
if (mesh::handleUsbModeCommand(command, reply, 160, Serial)) return;
const char* config = &command[4];
#if defined(RAK_4631)
if (mesh::peripherals::handleCommand(_prefs->peripherals_shared, command,
+3 -6
View File
@@ -34,12 +34,9 @@ inline CompanionChannelAlias parseCompanionChannelAlias(const char* name) {
// Only exact named radio2 aliases request RF setup. Ordinary channels and
// arbitrary r2 labels keep the operator's existing profile.
inline const char* companionChannelRadio2Preset(const char* name) {
if (!name) return nullptr;
if (*name == '#') ++name;
if (strncmp(name, "r2-", 3)) return nullptr;
name += 3;
// An exact preset tail also excludes every invalid/nested alias form.
return mesh::cli::radio2PresetTuple(name) ? name : nullptr;
const auto alias = parseCompanionChannelAlias(name);
return alias.kind == CompanionChannelKind::Radio2
&& mesh::cli::radio2PresetTuple(alias.tail) ? alias.tail : nullptr;
}
inline bool companionChannelCanonicalName(const char* name, char* out, size_t size) {
+1
View File
@@ -6,6 +6,7 @@
#include <string>
#include <vector>
#include "helpers/radiolib/RXPowerSaving.h"
#include "usb_mode_console.h"
struct Radio {
bool supported = true;
+31 -14
View File
@@ -127,18 +127,26 @@ class UsbModeTests(unittest.TestCase):
self.compile_and_run(directory, "alias" + str(index), flags, expected, primary=primary)
def test_actual_common_and_companion_dispatch_including_v14_request_prefix(self):
common = method((ROOT / "src/helpers/CommonCLI.cpp").read_text(),
"void CommonCLI::handleCommand(")
companion = method((ROOT / "examples/companion_radio/MyMesh.cpp").read_text(),
"bool MyMesh::handleCommand(")
call = "if (mesh::handleUsbModeCommand(command, reply, reply_capacity, Serial)) return true;"
self.assertIn(call, companion)
# Execute the real early dispatch bodies, before unrelated board/radio
# services. The framed V14 command path invokes this same handleCommand.
common = common.split("#if MESH_ENABLE_HOST_KISS", 1)[0] + "\n}"
companion = companion[:companion.index(call) + len(call)] + "\nreturn false;\n}"
# The omitted unrelated dispatch branches normally use this argument.
common_source = (ROOT / "src/helpers/CommonCLI.cpp").read_text()
companion_source = (ROOT / "examples/companion_radio/MyMesh.cpp").read_text()
common = method(common_source, "void CommonCLI::handleCommand(")
getter = method(common_source, "void CommonCLI::handleGetCmd(")
companion = method(companion_source, "bool MyMesh::handleCommand(")
control = method(companion_source, "bool MyMesh::handleLocalControlCommand(")
self.assertNotIn("handleUsbModeCommand", common)
self.assertNotIn("handleUsbModeCommand", companion)
self.assertIn("handleUsbModeCommand", getter)
self.assertIn("handleUsbModeCommand", control)
# Execute each actual entry and getter registration, retaining the V14
# prefix/capacity handling while omitting unrelated hardware branches.
common = common.split("#if MESH_ENABLE_HOST_KISS", 1)[0] + method(
common, 'if (memcmp(command, "get ", 4) == 0)') + "\n}"
getter = getter[:getter.index(" const char* config")] + "\n}"
control = control[:control.index("#if defined(ESP32_PLATFORM)")] + "return false;\n}"
companion = companion[:companion.index("#if defined(ESP32_PLATFORM)")]
companion += " return handleLocalControlCommand(command, reply, reply_capacity);\n}"
common = common.replace("{", "{ (void)sender_timestamp;", 1)
getter = getter.replace("{", "{ (void)sender_timestamp;", 1)
companion = companion.replace("{", "{ (void)sender_timestamp;", 1)
dispatch = r'''
struct PrefsSaveReplyGuard {
@@ -148,8 +156,12 @@ namespace mesh { namespace cli { void normalizeCommandVerb(char*) {} } }
struct CommonCLI {
unsigned _prefs_save_failures = 0;
void handleCommand(uint32_t, char*, char*);
void handleGetCmd(uint32_t, char*, char*);
};
struct MyMesh {
bool handleCommand(const char*, uint32_t, char*);
bool handleLocalControlCommand(const char*, char*, size_t);
};
struct MyMesh { bool handleCommand(const char*, uint32_t, char*); };
'''
cases = r'''
CommonCLI common;
@@ -164,8 +176,13 @@ struct MyMesh { bool handleCommand(const char*, uint32_t, char*); };
assert(!companion.handleCommand("set usb.mode tinyusb", 0, reply));
'''
with tempfile.TemporaryDirectory(prefix="meshcore-usb-mode-dispatch-") as directory:
self.compile_and_run(directory, "dispatch", ["ESP32", "ARDUINO_USB_MODE=1",
"ARDUINO_USB_CDC_ON_BOOT=1"], "hardware-cdc-jtag", dispatch + common + companion, cases)
for index, (flags, expected) in enumerate((
(["ESP32", "ARDUINO_USB_MODE=1", "ARDUINO_USB_CDC_ON_BOOT=1"], "hardware-cdc-jtag"),
(["ESP32", "ARDUINO_USB_MODE=0", "ARDUINO_USB_CDC_ON_BOOT=1"], "tinyusb"),
(["NRF52_PLATFORM", "USE_TINYUSB", "MESH_DUAL_CDC_LOGGING"], "tinyusb"),
(["STM32_PLATFORM"], "unknown"))):
self.compile_and_run(directory, "dispatch" + str(index), flags, expected,
dispatch + getter + control + common + companion, cases)
full = (ROOT / "examples/companion_radio/MyMesh.cpp").read_text()
frame = full[full.index("mesh::companion::isRunCliFrame"):]
self.assertIn("handleCommand(text, 0, reply_buf)", frame)