Add a saved override to keep USB packet logging continuous
This commit is contained in:
1 parent
1f2fcfc449
commit
05679aa741
18 files changed
+382
-39
No files matched your search
@@ -150,6 +150,9 @@ MESH_COMPANION_HELP_BEGIN
|
||||
#if MESH_USB_LOGGING_AVAILABLE
|
||||
" get/set usb.logging <on|off|stream> [reboot]\r\n"
|
||||
" get/set usb.debug <on|off>\r\n"
|
||||
#if !defined(MESH_DUAL_CDC_LOGGING)
|
||||
" get/set usb.logging.always <on|off>\r\n"
|
||||
#endif
|
||||
#if MESH_USB_CONSOLE_COOPERATIVE
|
||||
" get usb.watchdog.last\r\n"
|
||||
" get/set usb.watchdog <off|on|auto> (saved; default auto)\r\n"
|
||||
|
||||
@@ -1314,6 +1314,8 @@ bool DataStore::loadPrefsInt(const char *filename,
|
||||
if (success && file.read(static_cast<uint8_t*>(destination), field.length)
|
||||
!= field.length) success = false;
|
||||
}
|
||||
loaded_prefs.usb_logging_always = success
|
||||
&& pad[0] == CompanionNodePrefs::USB_LOGGING_ALWAYS_WIRE_ON;
|
||||
#else
|
||||
auto readField = [&file, &success](void* dest, size_t size) -> bool {
|
||||
if (!success
|
||||
@@ -1332,6 +1334,8 @@ bool DataStore::loadPrefsInt(const char *filename,
|
||||
readField(&loaded_prefs.airtime_factor, sizeof(float)); // 0
|
||||
readField(loaded_prefs.node_name, sizeof(loaded_prefs.node_name)); // 4
|
||||
readField(pad, 4); // 36
|
||||
loaded_prefs.usb_logging_always = success
|
||||
&& pad[0] == CompanionNodePrefs::USB_LOGGING_ALWAYS_WIRE_ON;
|
||||
readField(&loaded_lat, sizeof(loaded_lat)); // 40
|
||||
readField(&loaded_lon, sizeof(loaded_lon)); // 48
|
||||
readField(&loaded_prefs.freq, sizeof(loaded_prefs.freq)); // 56
|
||||
@@ -1542,7 +1546,8 @@ bool DataStore::savePrefs(const CompanionNodePrefs& _prefs, double node_lat, dou
|
||||
#endif
|
||||
#if defined(STM32_PLATFORM) && defined(__GNUC__)
|
||||
using namespace mesh::companion_prefs;
|
||||
const uint8_t pad[4] = {};
|
||||
const uint8_t pad[4] = {uint8_t(_prefs.usb_logging_always == 1
|
||||
? CompanionNodePrefs::USB_LOGGING_ALWAYS_WIRE_ON : 0), 0, 0, 0};
|
||||
size_t used = 0;
|
||||
for (const PrefField& field : PREF_FIELDS) {
|
||||
if (field.length > PREFS_PREFIX_SIZE - used) {
|
||||
@@ -1562,7 +1567,8 @@ bool DataStore::savePrefs(const CompanionNodePrefs& _prefs, double node_lat, dou
|
||||
// nRF52 retains streaming writes and its existing small stack footprint.
|
||||
// The table is the same validated wire order used by the scalar emitter.
|
||||
using namespace mesh::companion_prefs;
|
||||
const uint8_t pad[4] = {};
|
||||
const uint8_t pad[4] = {uint8_t(_prefs.usb_logging_always == 1
|
||||
? CompanionNodePrefs::USB_LOGGING_ALWAYS_WIRE_ON : 0), 0, 0, 0};
|
||||
bool success = true;
|
||||
for (const PrefField& field : PREF_FIELDS) {
|
||||
if (!success) break;
|
||||
@@ -1595,6 +1601,8 @@ bool DataStore::savePrefs(const CompanionNodePrefs& _prefs, double node_lat, dou
|
||||
#endif
|
||||
uint8_t pad[8];
|
||||
memset(pad, 0, sizeof(pad));
|
||||
pad[0] = _prefs.usb_logging_always == 1
|
||||
? CompanionNodePrefs::USB_LOGGING_ALWAYS_WIRE_ON : 0;
|
||||
|
||||
bool success = writeField((uint8_t *)&_prefs.airtime_factor, sizeof(float)); // 0
|
||||
success = success && writeField((uint8_t *)_prefs.node_name, sizeof(_prefs.node_name)); // 4
|
||||
@@ -1615,7 +1623,7 @@ bool DataStore::savePrefs(const CompanionNodePrefs& _prefs, double node_lat, dou
|
||||
success = success && writeField((uint8_t *)&_prefs.advert_loc_policy, sizeof(_prefs.advert_loc_policy)); // 76
|
||||
success = success && writeField((uint8_t *)&_prefs.multi_acks, sizeof(_prefs.multi_acks)); // 77
|
||||
success = success && writeField((uint8_t *)&_prefs.path_hash_mode, sizeof(_prefs.path_hash_mode)); // 78
|
||||
success = success && writeField(pad, 1); // 79
|
||||
success = success && writeField(pad + 1, 1); // 79
|
||||
success = success && writeField((uint8_t *)&_prefs.ble_pin, sizeof(_prefs.ble_pin)); // 80
|
||||
success = success && writeField((uint8_t *)&_prefs.buzzer_quiet, sizeof(_prefs.buzzer_quiet)); // 84
|
||||
success = success && writeField((uint8_t *)&_prefs.gps_enabled, sizeof(_prefs.gps_enabled)); // 85
|
||||
|
||||
@@ -3360,6 +3360,7 @@ void MyMesh::begin(bool has_display, bool radio_available,
|
||||
_prefs.wifi_enabled = constrain(_prefs.wifi_enabled, 0, 1);
|
||||
_prefs.usb_logging_enabled = constrain(_prefs.usb_logging_enabled, 0, 2);
|
||||
_prefs.usb_debug_enabled = _prefs.usb_debug_enabled == 1 ? 1 : 0;
|
||||
_prefs.usb_logging_always = _prefs.usb_logging_always == 1 ? 1 : 0;
|
||||
_prefs.cad_enabled = constrain(_prefs.cad_enabled, 0, 1);
|
||||
if (_prefs.cad_scan_timeout_ms != 0
|
||||
&& (_prefs.cad_scan_timeout_ms < mesh::CAD_SCAN_MIN_TIMEOUT_MS
|
||||
@@ -3383,6 +3384,9 @@ void MyMesh::begin(bool has_display, bool radio_available,
|
||||
const bool usb_logging_enabled = _prefs.usb_logging_enabled != 0;
|
||||
mesh::configureUsbLoggingPacketStream(_prefs.usb_logging_enabled == 2);
|
||||
mesh::setUsbDebugEnabled(_prefs.usb_debug_enabled != 0);
|
||||
#if !defined(MESH_DUAL_CDC_LOGGING)
|
||||
mesh::setUsbPacketLoggingAlways(_prefs.usb_logging_always != 0);
|
||||
#endif
|
||||
applyUsbLoggingState(usb_logging_enabled);
|
||||
if (!mesh::saveUsbLoggingBootPreference(usb_logging_enabled)) {
|
||||
MESH_DEBUG_PRINTLN("Unable to save next-boot USB logging interface state");
|
||||
@@ -4311,6 +4315,28 @@ bool MyMesh::handleLocalControlCommand(const char* command, char* reply,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MESH_USB_LOGGING_AVAILABLE && !defined(MESH_DUAL_CDC_LOGGING)
|
||||
if (strcmp(command, "get usb.logging.always") == 0) {
|
||||
snprintf(reply, reply_size, "usb.logging.always %s",
|
||||
mesh::isUsbPacketLoggingAlways() ? "on" : "off");
|
||||
return true;
|
||||
}
|
||||
if (strncmp(command, "set usb.logging.always", 22) == 0
|
||||
&& (command[22] == 0 || command[22] == ' ' || command[22] == '\t')) {
|
||||
const char* value = command + 22;
|
||||
while (*value == ' ' || *value == '\t') value++;
|
||||
if (strcmp(value, "on") != 0 && strcmp(value, "off") != 0) {
|
||||
mesh::cli::formatError(reply, reply_size, "use set usb.logging.always on|off");
|
||||
} else if (!savePreference(_prefs.usb_logging_always,
|
||||
uint8_t(strcmp(value, "on") == 0))) {
|
||||
mesh::cli::formatError(reply, reply_size, "USB logging policy could not be saved");
|
||||
} else {
|
||||
snprintf(reply, reply_size, "OK - usb.logging.always %s (saved)",
|
||||
_prefs.usb_logging_always ? "on" : "off");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#if MESH_USB_LOGGING_AVAILABLE
|
||||
if (strcmp(command, "get usb.debug") == 0) {
|
||||
snprintf(reply, reply_size, "usb.debug %s%s",
|
||||
|
||||
@@ -610,17 +610,23 @@ public:
|
||||
bool getChannel(int channel_idx, ChannelDetails& channel);
|
||||
bool setChannel(int channel_idx, const ChannelDetails& channel);
|
||||
bool savePrefs() {
|
||||
const uint8_t previous_usb_debug = _prefs.usb_debug_enabled;
|
||||
const uint8_t previous_tail_flags[] = {
|
||||
_prefs.usb_debug_enabled, _prefs.usb_logging_always};
|
||||
_prefs.usb_debug_enabled = _prefs.usb_debug_enabled == 1 ? 1 : 0;
|
||||
_prefs.usb_logging_always = _prefs.usb_logging_always == 1 ? 1 : 0;
|
||||
const bool saved =
|
||||
_store->savePrefs(_prefs, sensors.node_lat, sensors.node_lon);
|
||||
if (saved) {
|
||||
_prefs.clearDirty();
|
||||
#if MESH_USB_LOGGING_AVAILABLE
|
||||
mesh::setUsbDebugEnabled(_prefs.usb_debug_enabled != 0);
|
||||
#if !defined(MESH_DUAL_CDC_LOGGING)
|
||||
mesh::setUsbPacketLoggingAlways(_prefs.usb_logging_always != 0);
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
_prefs.usb_debug_enabled = previous_usb_debug;
|
||||
_prefs.usb_debug_enabled = previous_tail_flags[0];
|
||||
_prefs.usb_logging_always = previous_tail_flags[1];
|
||||
}
|
||||
return saved;
|
||||
}
|
||||
|
||||
@@ -138,6 +138,9 @@ public:
|
||||
#endif
|
||||
uint8_t tx_media = mesh::RADIO_TX_AUTO;
|
||||
uint8_t tx_ssh = mesh::RADIO_TX_AUTO;
|
||||
// Reserved wire byte 36; older writers stored zero here.
|
||||
uint8_t usb_logging_always = 0;
|
||||
static constexpr uint8_t USB_LOGGING_ALWAYS_WIRE_ON = 0xA1;
|
||||
|
||||
private:
|
||||
class RadioPrefs : public CommonRadioPrefs {
|
||||
@@ -168,6 +171,9 @@ private:
|
||||
def("rxps_level", _parent->rx_ps_level);
|
||||
def("rxps_preamble", _parent->rx_ps_preamble);
|
||||
def("usb_debug", _parent->usb_debug_enabled);
|
||||
#if !defined(MESH_DUAL_CDC_LOGGING)
|
||||
def("usb_log_always", _parent->usb_logging_always);
|
||||
#endif
|
||||
#ifdef TBEAM_1W
|
||||
def("fan", _parent->fan_mode, sizeof(_parent->fan_mode));
|
||||
def("fan_lo", _parent->fan_lo);
|
||||
@@ -183,25 +189,41 @@ private:
|
||||
}
|
||||
|
||||
bool getByKey(const char* key, char* value, size_t max_len) override {
|
||||
if (key != nullptr && strcmp(key, "usb_debug") == 0) {
|
||||
uint8_t* flag = &_parent->usb_debug_enabled;
|
||||
bool handled = key != nullptr && strcmp(key, "usb_debug") == 0;
|
||||
#if !defined(MESH_DUAL_CDC_LOGGING)
|
||||
if (key != nullptr && strcmp(key, "usb_log_always") == 0) {
|
||||
flag = &_parent->usb_logging_always;
|
||||
handled = true;
|
||||
}
|
||||
#endif
|
||||
if (handled) {
|
||||
if (value == nullptr || max_len == 0) return false;
|
||||
if (max_len < 2) {
|
||||
value[0] = 0;
|
||||
return false;
|
||||
}
|
||||
value[0] = _parent->usb_debug_enabled == 1 ? '1' : '0';
|
||||
value[0] = *flag == 1 ? '1' : '0';
|
||||
value[1] = 0;
|
||||
return true;
|
||||
}
|
||||
return CommonRadioPrefs::getByKey(key, value, max_len);
|
||||
}
|
||||
bool setByKey(const char* key, const char* value) override {
|
||||
if (key != nullptr && strcmp(key, "usb_debug") == 0) {
|
||||
uint8_t* flag = &_parent->usb_debug_enabled;
|
||||
bool handled = key != nullptr && strcmp(key, "usb_debug") == 0;
|
||||
#if !defined(MESH_DUAL_CDC_LOGGING)
|
||||
if (key != nullptr && strcmp(key, "usb_log_always") == 0) {
|
||||
flag = &_parent->usb_logging_always;
|
||||
handled = true;
|
||||
}
|
||||
#endif
|
||||
if (handled) {
|
||||
if (value == nullptr
|
||||
|| (strcmp(value, "0") != 0 && strcmp(value, "1") != 0)) {
|
||||
return false;
|
||||
}
|
||||
_parent->usb_debug_enabled = value[0] == '1' ? 1 : 0;
|
||||
*flag = value[0] == '1' ? 1 : 0;
|
||||
markDirty();
|
||||
return true;
|
||||
}
|
||||
@@ -289,23 +311,23 @@ public:
|
||||
// both live adapters untouched and a scratch snapshot's adapters local.
|
||||
bool copyPersistedValuesFrom(const CompanionNodePrefs& source) {
|
||||
if (&source == this) return true;
|
||||
const auto& last_value = tx_ssh;
|
||||
static_assert(sizeof(tx_ssh) == sizeof(uint8_t),
|
||||
"The last persisted traffic policy is one byte");
|
||||
const auto& last_value = usb_logging_always;
|
||||
static_assert(sizeof(usb_logging_always) == sizeof(uint8_t),
|
||||
"The last persisted preference is one byte");
|
||||
const uintptr_t first = reinterpret_cast<uintptr_t>(&airtime_factor);
|
||||
const uintptr_t last = reinterpret_cast<uintptr_t>(&last_value);
|
||||
if (last < first
|
||||
|| last - first > sizeof(*this) - sizeof(tx_ssh)) {
|
||||
|| last - first > sizeof(*this) - sizeof(usb_logging_always)) {
|
||||
return false;
|
||||
}
|
||||
const size_t size = static_cast<size_t>(last - first)
|
||||
+ sizeof(tx_ssh);
|
||||
+ sizeof(usb_logging_always);
|
||||
const auto bounded = [size](const CompanionNodePrefs& values) -> bool {
|
||||
const uintptr_t object = reinterpret_cast<uintptr_t>(&values);
|
||||
const uintptr_t begin =
|
||||
reinterpret_cast<uintptr_t>(&values.airtime_factor);
|
||||
const uintptr_t end = reinterpret_cast<uintptr_t>(
|
||||
&values.tx_ssh
|
||||
&values.usb_logging_always
|
||||
);
|
||||
const uintptr_t radio_begin = reinterpret_cast<uintptr_t>(&values.radio);
|
||||
const uintptr_t custom_begin = reinterpret_cast<uintptr_t>(&values.custom);
|
||||
@@ -314,7 +336,7 @@ public:
|
||||
return begin >= object && begin - object <= sizeof(values)
|
||||
&& size <= sizeof(values) - static_cast<size_t>(begin - object)
|
||||
&& end >= begin
|
||||
&& end - begin == size - sizeof(values.tx_ssh)
|
||||
&& end - begin == size - sizeof(values.usb_logging_always)
|
||||
&& radio_begin >= begin && size <= radio_begin - begin
|
||||
&& custom_begin >= begin && size <= custom_begin - begin;
|
||||
};
|
||||
|
||||
@@ -136,7 +136,8 @@ static const void* prefValue(const PrefField& field,
|
||||
const int8_t* timezone = nullptr) {
|
||||
if (field.offset == PrefsLat) return ⪫
|
||||
if (field.offset == PrefsLon) return &lon;
|
||||
if (field.offset == PrefsPad) return pad;
|
||||
// Byte 36 carries the always-log marker; the separate byte 79 stays zero.
|
||||
if (field.offset == PrefsPad) return pad + (field.length == 1);
|
||||
const void* value = reinterpret_cast<const uint8_t*>(&values) + field.offset;
|
||||
return timezone && value == &values.tz_offset_legacy ? timezone : value;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user