Add get bluetooth and set bluetooth on|off, with ble aliases. Require another active management connection before disabling Bluetooth unless off has a trailing force argument. Keep the toggle local to the current boot. Drain Bluetooth replies before disconnecting and recheck the remaining connection before applying a normal shutdown. Enabling Bluetooth cancels a pending shutdown. Document the commands and add compiled regression coverage to CI for native USB, HWCDC, UART, network clients, force, and timer rollover. Validation: CLI, Bluetooth, and USB regression tests passed. XIAO ESP32-S3 and RAK4631 Full Companion builds passed RAM, flash, and capability checks.
48 lines
1.9 KiB
C
48 lines
1.9 KiB
C
#pragma once
|
|
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
|
|
enum class CompanionBluetoothCommandSource { Other, Terminal, Framed };
|
|
enum class CompanionBluetoothCommand { None, Get, On, Off, ForceOff, Invalid };
|
|
|
|
inline const char* skipBluetoothCommandSpace(const char* text) {
|
|
while (*text == ' ' || *text == '\t') ++text;
|
|
return text;
|
|
}
|
|
|
|
inline bool bluetoothCommandWord(const char* text, const char* word) {
|
|
const size_t length = strlen(word);
|
|
return strncmp(text, word, length) == 0
|
|
&& *skipBluetoothCommandSpace(text + length) == 0;
|
|
}
|
|
|
|
inline CompanionBluetoothCommand parseCompanionBluetoothCommand(const char* text) {
|
|
if (!text) return CompanionBluetoothCommand::None;
|
|
text = skipBluetoothCommandSpace(text);
|
|
if (bluetoothCommandWord(text, "get bluetooth")
|
|
|| bluetoothCommandWord(text, "get ble")) return CompanionBluetoothCommand::Get;
|
|
const char* value = nullptr;
|
|
const char* const prefixes[] = {"set bluetooth", "set ble"};
|
|
for (const char* prefix : prefixes) {
|
|
const size_t length = strlen(prefix);
|
|
if (strncmp(text, prefix, length) == 0
|
|
&& (text[length] == 0 || text[length] == ' ' || text[length] == '\t')) {
|
|
value = skipBluetoothCommandSpace(text + length);
|
|
break;
|
|
}
|
|
}
|
|
if (!value) return CompanionBluetoothCommand::None;
|
|
if (bluetoothCommandWord(value, "on")) return CompanionBluetoothCommand::On;
|
|
if (bluetoothCommandWord(value, "off")) return CompanionBluetoothCommand::Off;
|
|
if (strncmp(value, "off", 3) == 0 && (value[3] == ' ' || value[3] == '\t')
|
|
&& bluetoothCommandWord(skipBluetoothCommandSpace(value + 3), "force")) {
|
|
return CompanionBluetoothCommand::ForceOff;
|
|
}
|
|
return CompanionBluetoothCommand::Invalid;
|
|
}
|
|
|
|
bool handleCompanionBluetoothCommand(
|
|
const char* command, char* reply, size_t reply_size,
|
|
CompanionBluetoothCommandSource source = CompanionBluetoothCommandSource::Other);
|