15static const char*
TAG =
"CMDREGS";
32 authCheck_ = authCheck;
47 for (
size_t i = 0; i < count_; i++) {
48 if (strcasecmp(commands_[i].
name, cmd.
name) == 0) {
54 commands_[count_++] = cmd;
65 if (!moduleName)
return;
68 for (
size_t readIdx = 0; readIdx < count_; readIdx++) {
69 if (commands_[readIdx].moduleName &&
70 strcmp(commands_[readIdx].moduleName, moduleName) == 0) {
74 if (writeIdx != readIdx) {
75 commands_[writeIdx] = commands_[readIdx];
88 lineInterceptor_ = interceptor;
92 byteInterceptor_ = interceptor;
96 return byteInterceptor_;
105 if (!line || !*line)
return false;
108 if (lineInterceptor_ && lineInterceptor_(line)) {
115 while (*line && !isspace(*line) && cmdLen <
sizeof(cmdBuf) - 1) {
116 cmdBuf[cmdLen++] = *line++;
118 cmdBuf[cmdLen] =
'\0';
121 while (*line && isspace(*line)) line++;
123#if FEATURE_SECURE_SERIAL
127 if (
pm.isBadgeBlocked()) {
128 if (strcasecmp(cmdBuf,
"PING") != 0) {
129 if (
pm.isLockoutActive()) {
130 uint32_t remainingSec =
pm.getLockoutRemainingMs() / 1000;
132 (
unsigned long)remainingSec);
142 bool isAllowedWithoutAuth = (strcasecmp(cmdBuf,
"PING") == 0 ||
143 strcasecmp(cmdBuf,
"AUTH") == 0);
144 if (!isAllowedWithoutAuth && authCheck_ && !authCheck_()) {
145 Console::printf(
"ERROR: Not authenticated. Use AUTH <pin> to login.\r\n");
152 for (
size_t i = 0; i < count_; i++) {
153 if (strcasecmp(commands_[i].
name, cmdBuf) == 0) {
156 if (commands_[i].requiresAuth && authCheck_ && !authCheck_()) {
157 Console::printf(
"ERROR: Authentication required. Use AUTH <pin> first.\r\n");
160 if (commands_[i].handler) {
161 commands_[i].handler(line);
164 if (onCommandExecuted_) {
165 onCommandExecuted_();
184 const char* currentModule =
nullptr;
186 for (
size_t i = 0; i < count_; i++) {
187 const char* module = commands_[i].moduleName ? commands_[i].moduleName :
"system";
189 if (!currentModule || strcmp(currentModule, module) != 0) {
191 currentModule =
module;
196 commands_[i].help ? commands_[i].help :
"");
198 if (!commands_[i].subCommands)
continue;
199 for (
const SubCommand* e = commands_[i].subCommands; e->
name; ++e) {
201 if (e->args && *e->args) {
202 std::snprintf(head,
sizeof(head),
"%s %s", e->name, e->args);
204 std::snprintf(head,
sizeof(head),
"%s", e->name);
207 head, e->help ? e->help :
"");
229 onCommandExecuted_ = callback;
235 bool (*authCheck_)() =
nullptr;
236 void (*onCommandExecuted_)() =
nullptr;
247 return *g_commandRegistry;
char name[cdc::hal::ISecureElement::RMEM_NAME_LEN]
CDC Log: logging over TinyUSB CDC and UART.
#define LOG_W(tag, fmt,...)
#define LOG_I(tag, fmt,...)
static PinManager & instance()
Returns singleton PIN manager instance.
ByteInterceptor getByteInterceptor() const override
bool processCommand(const char *line) override
Parses and executes one command line.
void showHelp() override
Prints grouped help for all registered commands.
void setLineInterceptor(LineInterceptor interceptor) override
Sets optional line interceptor for multiline modes.
void setOnCommandExecuted(void(*callback)()) override
Sets callback fired after successful command execution.
void unregisterModule(const char *moduleName) override
Unregisters all commands belonging to one module.
void setAuthProvider(bool(*authCheck)()) override
Sets external authentication status provider.
bool registerCommand(const Command &cmd) override
Registers a command in the dispatch table.
void setByteInterceptor(ByteInterceptor interceptor) override
size_t getCommandCount() const override
Returns count of currently registered commands.
static void flush()
Flushes pending console output.
static void printf(const char *format,...) __attribute__((format(printf
Prints formatted text to console.
void(*)(uint8_t byte) ByteInterceptor
bool(*)(const char *line) LineInterceptor
constexpr size_t kSubCommandHeadBufSize
Buffer size for the "<name> <args>" column built during HELP rendering.
ICommandRegistry & getCommandRegistry()
Returns singleton command-registry interface.
static constexpr size_t MAX_COMMANDS
Maximum number of commands that can be registered.
const char * moduleName
Module that registered the command (used for HELP grouping).
const char * name
Top-level command (e.g. "TOTP" or "PING").
const char * name
Sub-command keyword, e.g. "LIST". nullptr terminates the array.