Report the running firmware USB mode without disturbing logging

This commit is contained in:
mikecarper committed 2026-10-28 02:14:11 -07:00
1 parent 744692fb93
commit b18ba8288a
8 files changed
+278 -3

No files matched your search

+2
View File
@@ -5,6 +5,7 @@
#include <helpers/sensors/SolarXiaoPower.h>
#include <helpers/LedSettings.h>
#include <Arduino.h>
#include "UsbMode.h"
#include "CarrierTools.h"
#include "PacketFileLoggingConfig.h"
#include "CommonCLI.h"
@@ -3553,6 +3554,7 @@ 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
+2 -1
View File
@@ -1303,7 +1303,8 @@ void noteUsbConsoleCommand(const char* command) {
if (command == nullptr || isUsbPacketLoggingAlways()
|| hasDedicatedUsbLoggingPort() || isUsbLoggingPacketStream()) return;
while (*command == ' ' || *command == '\t' || *command == '\r' || *command == '\n') ++command;
if (*command == 0 || isUsbLoggingStatsCommand(command)) return;
if (*command == 0 || isUsbLoggingStatsCommand(command)
|| isUsbModeDetectionCommand(command)) return;
for (const unsigned char* p = reinterpret_cast<const unsigned char*>(command); *p; ++p) {
if ((*p < 32 && *p != '\t') || *p >= 127) return;
}
+16
View File
@@ -11,6 +11,22 @@ namespace mesh {
// not identify a particular application or prove MQTT/disk health.
constexpr uint32_t USB_LOGGING_CLIENT_LEASE_MS = 15UL * 60UL * 1000UL;
// Firmware detection is passive even before the role strips an optional
// two-byte Companion request prefix or normalizes an uppercase GET verb.
// Unlike stats polling, this query must not establish a logging-reader lease.
inline bool isUsbModeDetectionCommand(const char* command) {
if (!command) return false;
while (*command == ' ' || *command == '\t') ++command;
if (command[0] && command[1] && command[2] == '|' && command[3]) {
command += 3;
while (*command == ' ' || *command == '\t') ++command;
}
return (command[0] == 'g' || command[0] == 'G')
&& (command[1] == 'e' || command[1] == 'E')
&& (command[2] == 't' || command[2] == 'T')
&& strcmp(command + 3, " usb.mode") == 0;
}
inline bool isUsbLoggingStatsCommand(const char* command) {
if (!command) return false;
while (*command == ' ' || *command == '\t') ++command;
+46
View File
@@ -0,0 +1,46 @@
#pragma once
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <type_traits>
namespace mesh {
// Describe the primary Serial backend selected by this application build,
// not its board name, host port name, USB VID/PID or optional logging CDC.
// Include after Arduino.h. The caller supplies decltype(Serial), after any
// board-specific alias is visible, so a custom primary UART cannot inherit a
// native-USB claim merely because the unused USB peripheral has those flags.
template <typename SerialType>
inline const char* usbModeName() {
#if defined(ESP32) || defined(ESP32_PLATFORM)
if (std::is_same<SerialType, HardwareSerial>::value) return "uart";
#if defined(ARDUINO_USB_CDC_ON_BOOT) && ARDUINO_USB_CDC_ON_BOOT
#if defined(ARDUINO_USB_MODE) && ARDUINO_USB_MODE == 1
if (std::is_same<SerialType, HWCDC>::value) return "hardware-cdc-jtag";
#elif defined(ARDUINO_USB_MODE) && ARDUINO_USB_MODE == 0
if (std::is_same<SerialType, USBCDC>::value) return "tinyusb";
#endif
#endif
#elif defined(NRF52_PLATFORM) && defined(USE_TINYUSB)
if (std::is_same<SerialType, Adafruit_USBD_CDC>::value) return "tinyusb";
#endif
return "unknown";
}
inline bool isUsbModeCommand(const char* command) {
return command != nullptr && strcmp(command, "get usb.mode") == 0;
}
// Read-only, bounded and independent of diagnostic/logging build flags.
// No setter: changing a USB backend requires installing another application.
template <typename SerialType>
inline bool handleUsbModeCommand(const char* command, char* reply,
size_t capacity, const SerialType&) {
if (!isUsbModeCommand(command) || reply == nullptr || capacity == 0) return false;
snprintf(reply, capacity, "usb.mode %s", usbModeName<SerialType>());
return true;
}
} // namespace mesh