From 1237288708180a5d3b975d75753e348376569cec Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Thu, 27 Jan 2022 00:45:37 -0800 Subject: [PATCH] Revert "add CLI tab-to-autocomplete ability and implement for nrfconnect (#13630)" (#14384) This reverts commit c62489bc08709e2932cc20565c7a133665d16291. --- .../src/binding-handler.cpp | 2 +- .../esp32/main/OnOffCommands.cpp | 4 +- .../cyw30739/src/AppShellCommands.cpp | 4 +- .../esp32/main/OTAProviderCommands.cpp | 4 +- .../esp32/shell_extension/heap_trace.cpp | 4 +- .../linux/CommissioneeShellCommands.cpp | 2 +- .../linux/ControllerShellCommands.cpp | 2 +- examples/shell/shell_common/cmd_misc.cpp | 2 +- examples/shell/shell_common/cmd_otcli.cpp | 2 +- examples/shell/shell_common/cmd_ping.cpp | 2 +- examples/shell/shell_common/cmd_send.cpp | 2 +- examples/shell/shell_common/cmd_server.cpp | 4 +- .../tv-app/linux/AppPlatformShellCommands.cpp | 2 +- src/lib/shell/Engine.cpp | 187 +++--------------- src/lib/shell/Engine.h | 78 +------- src/lib/shell/MainLoopZephyr.cpp | 95 +-------- src/lib/shell/commands/BLE.cpp | 4 +- src/lib/shell/commands/Base64.cpp | 4 +- src/lib/shell/commands/Config.cpp | 6 +- src/lib/shell/commands/Device.cpp | 4 +- src/lib/shell/commands/Dns.cpp | 6 +- src/lib/shell/commands/Meta.cpp | 2 +- src/lib/shell/commands/NFC.cpp | 2 +- src/lib/shell/commands/OnboardingCodes.cpp | 2 +- src/lib/shell/commands/Ota.cpp | 4 +- src/lib/shell/commands/WiFi.cpp | 4 +- 26 files changed, 72 insertions(+), 362 deletions(-) diff --git a/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp b/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp index 8979b3add9b301..15ec992bdd7789 100644 --- a/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp @@ -61,7 +61,7 @@ static CHIP_ERROR SwitchCommandHandler(int argc, char ** argv) static void RegisterSwitchCommands() { static const shell_command_t sSwitchCommand = { SwitchCommandHandler, "switch", "Switch commands. Usage: switch [on|off]" }; - Engine::Root().RegisterCommands(&sSwitchCommand, 1, nullptr); + Engine::Root().RegisterCommands(&sSwitchCommand, 1); return; } #endif // defined(ENABLE_CHIP_SHELL) diff --git a/examples/all-clusters-app/esp32/main/OnOffCommands.cpp b/examples/all-clusters-app/esp32/main/OnOffCommands.cpp index ff436de4861735..45a393548fcb3e 100644 --- a/examples/all-clusters-app/esp32/main/OnOffCommands.cpp +++ b/examples/all-clusters-app/esp32/main/OnOffCommands.cpp @@ -90,12 +90,12 @@ void OnOffCommands::Register() static const shell_command_t subCommands[] = { { &OnLightHandler, "on", "Usage: OnOff on endpoint-id" }, { &OffLightHandler, "off", "Usage: OnOff off endpoint-id" }, { &ToggleLightHandler, "toggle", "Usage: OnOff toggle endpoint-id" } }; - sSubShell.RegisterCommands(subCommands, ArraySize(subCommands), "OnOff"); + sSubShell.RegisterCommands(subCommands, ArraySize(subCommands)); // Register the root `OnOff` command in the top-level shell. static const shell_command_t onOffCommand = { &OnOffHandler, "OnOff", "OnOff commands" }; - Engine::Root().RegisterCommands(&onOffCommand, 1, nullptr); + Engine::Root().RegisterCommands(&onOffCommand, 1); } } // namespace Shell diff --git a/examples/lighting-app/cyw30739/src/AppShellCommands.cpp b/examples/lighting-app/cyw30739/src/AppShellCommands.cpp index 94f2b5e848faf2..84f7b74adefc94 100644 --- a/examples/lighting-app/cyw30739/src/AppShellCommands.cpp +++ b/examples/lighting-app/cyw30739/src/AppShellCommands.cpp @@ -50,9 +50,9 @@ void RegisterAppShellCommands(void) .cmd_help = "App commands", }; - sAppSubcommands.RegisterCommands(sAppSubCommands, ArraySize(sAppSubCommands), "app"); + sAppSubcommands.RegisterCommands(sAppSubCommands, ArraySize(sAppSubCommands)); - Engine::Root().RegisterCommands(&sAppCommand, 1, nullptr); + Engine::Root().RegisterCommands(&sAppCommand, 1); } CHIP_ERROR AppCommandHelpHandler(int argc, char * argv[]) diff --git a/examples/ota-provider-app/esp32/main/OTAProviderCommands.cpp b/examples/ota-provider-app/esp32/main/OTAProviderCommands.cpp index b209eff22c6179..58bf1ee1320f16 100644 --- a/examples/ota-provider-app/esp32/main/OTAProviderCommands.cpp +++ b/examples/ota-provider-app/esp32/main/OTAProviderCommands.cpp @@ -69,12 +69,12 @@ void OTAProviderCommands::Register() "Usage: OTAProvider delay " }, }; - sSubShell.RegisterCommands(subCommands, ArraySize(subCommands), "OTAProvider"); + sSubShell.RegisterCommands(subCommands, ArraySize(subCommands)); // Register the root `OTA Provider` command in the top-level shell. static const shell_command_t otaProviderCommand = { &OTAProviderHandler, "OTAProvider", "OTA Provider commands" }; - Engine::Root().RegisterCommands(&otaProviderCommand, 1, nullptr); + Engine::Root().RegisterCommands(&otaProviderCommand, 1); } // Set Example OTA provider diff --git a/examples/platform/esp32/shell_extension/heap_trace.cpp b/examples/platform/esp32/shell_extension/heap_trace.cpp index b052088ac19e4b..a2c508a370aea7 100644 --- a/examples/platform/esp32/shell_extension/heap_trace.cpp +++ b/examples/platform/esp32/shell_extension/heap_trace.cpp @@ -137,7 +137,7 @@ void RegisterHeapTraceCommands() { &HeapTraceTaskHandler, "task", "Dump heap usage of each task" }, #endif // CONFIG_HEAP_TASK_TRACKING }; - sShellHeapSubCommands.RegisterCommands(sHeapSubCommands, ArraySize(sHeapSubCommands), "heap-trace"); + sShellHeapSubCommands.RegisterCommands(sHeapSubCommands, ArraySize(sHeapSubCommands)); #if CONFIG_HEAP_TRACING_STANDALONE ESP_ERROR_CHECK(heap_trace_init_standalone(sTraceRecords, kNumHeapTraceRecords)); @@ -145,7 +145,7 @@ void RegisterHeapTraceCommands() #endif // CONFIG_HEAP_TRACING_STANDALONE static const shell_command_t sHeapCommand = { &HeapTraceDispatch, "heap-trace", "Heap debug tracing" }; - Engine::Root().RegisterCommands(&sHeapCommand, 1, nullptr); + Engine::Root().RegisterCommands(&sHeapCommand, 1); } } // namespace chip diff --git a/examples/platform/linux/CommissioneeShellCommands.cpp b/examples/platform/linux/CommissioneeShellCommands.cpp index fe10c7b56dd085..e256cb0fbecb72 100644 --- a/examples/platform/linux/CommissioneeShellCommands.cpp +++ b/examples/platform/linux/CommissioneeShellCommands.cpp @@ -148,7 +148,7 @@ void RegisterCommissioneeCommands() "Commissionee commands. Usage: commissionee [command_name]" }; // Register the root `device` command with the top-level shell. - Engine::Root().RegisterCommands(&sDeviceComand, 1, nullptr); + Engine::Root().RegisterCommands(&sDeviceComand, 1); return; } diff --git a/examples/platform/linux/ControllerShellCommands.cpp b/examples/platform/linux/ControllerShellCommands.cpp index 6c5604eada24ce..ff231eb5341c50 100644 --- a/examples/platform/linux/ControllerShellCommands.cpp +++ b/examples/platform/linux/ControllerShellCommands.cpp @@ -273,7 +273,7 @@ void RegisterControllerCommands() "Controller commands. Usage: controller [command_name]" }; // Register the root `device` command with the top-level shell. - Engine::Root().RegisterCommands(&sDeviceComand, 1, nullptr); + Engine::Root().RegisterCommands(&sDeviceComand, 1); return; } diff --git a/examples/shell/shell_common/cmd_misc.cpp b/examples/shell/shell_common/cmd_misc.cpp index 6fb98833b02955..ff8a5ad9739656 100644 --- a/examples/shell/shell_common/cmd_misc.cpp +++ b/examples/shell/shell_common/cmd_misc.cpp @@ -68,5 +68,5 @@ static shell_command_t cmds_misc[] = { void cmd_misc_init() { - Engine::Root().RegisterCommands(cmds_misc, ArraySize(cmds_misc), nullptr); + Engine::Root().RegisterCommands(cmds_misc, ArraySize(cmds_misc)); } diff --git a/examples/shell/shell_common/cmd_otcli.cpp b/examples/shell/shell_common/cmd_otcli.cpp index 296d238167ec78..dbb8128d265b6e 100644 --- a/examples/shell/shell_common/cmd_otcli.cpp +++ b/examples/shell/shell_common/cmd_otcli.cpp @@ -193,6 +193,6 @@ void cmd_otcli_init() #endif // Register the root otcli command with the top-level shell. - Engine::Root().RegisterCommands(&cmds_otcli_root, 1, nullptr); + Engine::Root().RegisterCommands(&cmds_otcli_root, 1); #endif // CHIP_ENABLE_OPENTHREAD } diff --git a/examples/shell/shell_common/cmd_ping.cpp b/examples/shell/shell_common/cmd_ping.cpp index b8740e59b183bb..6a8183d3de80b2 100644 --- a/examples/shell/shell_common/cmd_ping.cpp +++ b/examples/shell/shell_common/cmd_ping.cpp @@ -483,5 +483,5 @@ static shell_command_t cmds_ping[] = { void cmd_ping_init() { - Engine::Root().RegisterCommands(cmds_ping, ArraySize(cmds_ping), nullptr); + Engine::Root().RegisterCommands(cmds_ping, ArraySize(cmds_ping)); } diff --git a/examples/shell/shell_common/cmd_send.cpp b/examples/shell/shell_common/cmd_send.cpp index a48518102a364e..c216c57578297a 100644 --- a/examples/shell/shell_common/cmd_send.cpp +++ b/examples/shell/shell_common/cmd_send.cpp @@ -406,5 +406,5 @@ static shell_command_t cmds_send[] = { void cmd_send_init() { - Engine::Root().RegisterCommands(cmds_send, ArraySize(cmds_send), nullptr); + Engine::Root().RegisterCommands(cmds_send, ArraySize(cmds_send)); } diff --git a/examples/shell/shell_common/cmd_server.cpp b/examples/shell/shell_common/cmd_server.cpp index 4455d16fc4e99c..45a5b2460ada05 100644 --- a/examples/shell/shell_common/cmd_server.cpp +++ b/examples/shell/shell_common/cmd_server.cpp @@ -228,8 +228,8 @@ void cmd_app_server_init() std::atexit(CmdAppServerAtExit); // Register `server` subcommands with the local shell dispatcher. - sShellServerSubcommands.RegisterCommands(sServerSubCommands, ArraySize(sServerSubCommands), "server"); + sShellServerSubcommands.RegisterCommands(sServerSubCommands, ArraySize(sServerSubCommands)); // Register the root `server` command with the top-level shell. - Engine::Root().RegisterCommands(&sServerComand, 1, nullptr); + Engine::Root().RegisterCommands(&sServerComand, 1); } diff --git a/examples/tv-app/linux/AppPlatformShellCommands.cpp b/examples/tv-app/linux/AppPlatformShellCommands.cpp index 2b03bbd42d2284..96acfed6270709 100644 --- a/examples/tv-app/linux/AppPlatformShellCommands.cpp +++ b/examples/tv-app/linux/AppPlatformShellCommands.cpp @@ -192,7 +192,7 @@ void RegisterAppPlatformCommands() static const shell_command_t sDeviceComand = { &AppPlatformHandler, "app", "App commands. Usage: app [command_name]" }; // Register the root `device` command with the top-level shell. - Engine::Root().RegisterCommands(&sDeviceComand, 1, nullptr); + Engine::Root().RegisterCommands(&sDeviceComand, 1); return; } diff --git a/src/lib/shell/Engine.cpp b/src/lib/shell/Engine.cpp index 8723ecc051a895..10bb2dcfa6723a 100644 --- a/src/lib/shell/Engine.cpp +++ b/src/lib/shell/Engine.cpp @@ -21,9 +21,10 @@ * Source implementation for a generic shell API for CHIP examples. */ +#include + #include #include -#include #include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include using namespace chip::Logging; @@ -41,7 +43,6 @@ namespace chip { namespace Shell { Engine Engine::theEngineRoot; -shell_map * Engine::theShellMapListHead = NULL; int Engine::Init() { @@ -55,189 +56,47 @@ int Engine::Init() void Engine::ForEachCommand(shell_command_iterator_t * on_command, void * arg) { - for (unsigned i = 0; i < _commandCount; i++) + for (unsigned i = 0; i < _commandSetCount; i++) { - if (on_command(_commands[i], arg) != CHIP_NO_ERROR) + for (unsigned j = 0; j < _commandSetSize[i]; j++) { - return; - } - } -} - -void Engine::RegisterCommands(shell_command_t * command_set, unsigned count, const char * prefix) -{ - if (this == &Engine::Root() || prefix == nullptr) - { - prefix = ""; - } - - if (_commandCount + count > CHIP_SHELL_MAX_MODULES) - { - ChipLogError(Shell, "Max number of commands registered to this shell"); - assert(0); - } - - for (unsigned i = 0; i < count; i++) - { - _commands[_commandCount + i] = &command_set[i]; - } - _commandCount += count; - - Engine::InsertShellMap(prefix, this); -} - -void Engine::InsertShellMap(char const * prefix, Engine * shell) -{ - shell_map_t * map = Engine::theShellMapListHead; - while (map != NULL) - { - if (strcmp(prefix, map->prefix) == 0) - { - for (size_t i = 0; i < map->enginec; i++) + if (on_command(&_commandSet[i][j], arg) != CHIP_NO_ERROR) { - if (map->enginev[i] == shell) - { - return; - } + return; } - if (map->enginec == sizeof(map->enginev)) - { - ChipLogError(Shell, "Max number of shells registered under this prefix"); - assert(0); - } - map->enginev[map->enginec] = shell; - map->enginec++; - return; } - map = map->next; } - shell_map_t * new_map = new shell_map_t; - new_map->prefix = prefix; - new_map->enginev[0] = shell; - new_map->enginec = 1; - new_map->next = Engine::theShellMapListHead; - Engine::theShellMapListHead = new_map; } -CHIP_ERROR Engine::GetCommandCompletions(cmd_completion_context * context) +void Engine::RegisterCommands(shell_command_t * command_set, unsigned count) { - - if (Engine::theShellMapListHead == NULL) - { - ChipLogDetail(Shell, "There isn't any command registered yet."); - return CHIP_NO_ERROR; - } - const char * buf = context->line_buf; - if (buf == nullptr) + if (_commandSetCount >= CHIP_SHELL_MAX_MODULES) { - buf = ""; - } - - int last_space_idx = -1; - int buf_len = strlen(buf); - - // find space in buf - for (int i = buf_len - 1; i > -1; i--) - { - if (buf[i] == ' ') - { - last_space_idx = i; - break; - } - } - - // check whether the buf perfectly matches a prefix - bool perfect_match = false; - shell_map_t * map = Engine::theShellMapListHead; - - while (map != NULL) - { - - if (strcmp(buf, map->prefix) == 0) - { - perfect_match = true; - break; - } - map = map->next; - } - - char * prefix; - char * incomplete_cmd; - - if (perfect_match) - { - // If it's a perfect match - // - use the whole buf as the prefix - // - there is no "incomplete command" so set it to empty - prefix = new char[buf_len + 1]; - incomplete_cmd = new char[1]; - strncpy(prefix, buf, buf_len + 1); - strncpy(incomplete_cmd, "", 1); - } - else - { - // If it's not a perfect match: - // - prefix is up to the last space - // - incomplete_cmd is what's after the last space - bool no_space = (last_space_idx == -1) ? true : false; - prefix = new char[last_space_idx + 1 + no_space]; - incomplete_cmd = new char[buf_len - last_space_idx]; - strncpy(prefix, buf, last_space_idx + 1 + no_space); - strncpy(incomplete_cmd, &buf[last_space_idx + 1], buf_len - last_space_idx); - } - - // Array to pass arguments into the ForEachCommand call - void * lambda_args[] = { context, incomplete_cmd }; - map = Engine::theShellMapListHead; - - while (map != NULL && context->cmdc < CHIP_SHELL_MAX_CMD_COMPLETIONS) - { - if (strcmp(prefix, map->prefix) == 0) - { - context->ret_prefix = map->prefix; - for (unsigned i = 0; i < map->enginec; i++) - { - map->enginev[i]->ForEachCommand( - [](shell_command_t * cmd, void * arg) -> CHIP_ERROR { - cmd_completion_context * ctx = (cmd_completion_context *) ((void **) arg)[0]; - char * _incomplete_cmd = (char *) ((void **) arg)[1]; - // For end nodes like "ble adv", need to avoid duplicate returns. - // Return for prefix="ble adv" cmd=""; reject for prefix="ble" cmd="adv" - if ((strcmp(cmd->cmd_name, _incomplete_cmd) != 0 && - strncmp(cmd->cmd_name, _incomplete_cmd, strlen(_incomplete_cmd)) == 0) || - strcmp(_incomplete_cmd, "") == 0) - { - ctx->cmdc++; - ctx->cmdv[ctx->cmdc - 1] = cmd; - } - return CHIP_NO_ERROR; - }, - lambda_args); - } - break; - } - - map = map->next; + ChipLogError(Shell, "Max number of modules reached\n"); + assert(0); } - delete[] prefix; - delete[] incomplete_cmd; - - return CHIP_NO_ERROR; + _commandSet[_commandSetCount] = command_set; + _commandSetSize[_commandSetCount] = count; + ++_commandSetCount; } CHIP_ERROR Engine::ExecCommand(int argc, char * argv[]) { CHIP_ERROR retval = CHIP_ERROR_INVALID_ARGUMENT; + VerifyOrReturnError(argc > 0, retval); // Find the command - for (unsigned i = 0; i < _commandCount; i++) + for (unsigned i = 0; i < _commandSetCount; i++) { - if (strcmp(argv[0], _commands[i]->cmd_name) == 0) + for (unsigned j = 0; j < _commandSetSize[i]; j++) { - // Execute the command! - retval = _commands[i]->cmd_func(argc - 1, argv + 1); - break; + if (strcmp(argv[0], _commandSet[i][j].cmd_name) == 0) + { + // Execute the command! + retval = _commandSet[i][j].cmd_func(argc - 1, argv + 1); + break; + } } } diff --git a/src/lib/shell/Engine.h b/src/lib/shell/Engine.h index 7cbf51b7f4eeae..be65ed45c94dc0 100644 --- a/src/lib/shell/Engine.h +++ b/src/lib/shell/Engine.h @@ -25,9 +25,8 @@ #include "streamer.h" -#include -#include #include + #include #include @@ -47,10 +46,6 @@ #define CHIP_SHELL_MAX_TOKENS 10 #endif // CHIP_SHELL_MAX_TOKENS -#ifndef CHIP_SHELL_MAX_CMD_COMPLETIONS -#define CHIP_SHELL_MAX_CMD_COMPLETIONS 32 -#endif // CHIP_SHELL_MAX_CMD_COMPLETIONS - namespace chip { namespace Shell { @@ -98,76 +93,20 @@ typedef const struct shell_command shell_command_t; */ typedef CHIP_ERROR shell_command_iterator_t(shell_command_t * command, void * arg); -class Engine; - -/** - * A map of the Engine instances and the command prefix that they correspond to. - * The struct itself is a linked list node. - * - * prefix: The command prefix (until n-1th token of full command) e.g. "device", - * or "dns resolve". - * enginev: An array of the shells that have registered commands under the preifx. - * enginec: The number of shells that have registered commands under the preifx. - * next: The next shell in the list. - * - */ -typedef struct shell_map -{ - const char * prefix; - Engine * enginev[CHIP_SHELL_MAX_MODULES]; - size_t enginec = 0; - shell_map * next; -} shell_map_t; - -/** - * A context object for passing request and receiving results with GetCmdCompletion. - * - * line_buf: The user input command to request for completion. If the applications prepends - * "matter " to all matter commands, please remove the "matter " prefix from the buffer. - * ret_prefix: The returned command prefix (up until the last space, not included). - * cmdv: The command completion candidates unter the prefix in "ret_prefix". - * cmdc: The number of command completion candidates in cmdv. - * - * Initialization: - * - * cmd_completion_context context = cmd_completion_context("dns browse c"); - * - */ -typedef struct cmd_completion_context -{ - const char * line_buf; - const char * ret_prefix; - shell_command_t * cmdv[CHIP_SHELL_MAX_CMD_COMPLETIONS]; - size_t cmdc = 0; - - cmd_completion_context(){}; - cmd_completion_context(const char * _line_buf) { line_buf = _line_buf; }; -} cmd_completion_context; - class Engine { protected: static Engine theEngineRoot; - static shell_map_t * theShellMapListHead; - shell_command_t * _commands[CHIP_SHELL_MAX_MODULES]; - unsigned _commandCount; - static void InsertShellMap(char const * prefix, Engine * shell); + shell_command_t * _commandSet[CHIP_SHELL_MAX_MODULES]; + unsigned _commandSetSize[CHIP_SHELL_MAX_MODULES]; + unsigned _commandSetCount; public: - Engine(){}; + Engine() {} /** Return the root singleton for the Shell command hierarchy. */ - static Engine & Root() { return theEngineRoot; }; - - /** - * Get command completions by command prefix. - * - * @param context The command completion context to pass request and receive results. - * - * @return CHIP_ERROR error code. - */ - static CHIP_ERROR GetCommandCompletions(cmd_completion_context * context); + static Engine & Root() { return theEngineRoot; } /** * Registers a set of defaults commands (help) for all Shell and sub-Shell instances. @@ -202,11 +141,8 @@ class Engine * * @param command_set An array of commands to add to the shell. * @param count The number of commands in the command set array. - * @param prefix The prefix of this command set in the full command path. - * e.g. "matter base64" is prefix for "endcode" and "decode". - * Use double quoted empty string `""` or nullptr for root commands. */ - void RegisterCommands(shell_command_t * command_set, unsigned count, const char * prefix); + void RegisterCommands(shell_command_t * command_set, unsigned count); /** * Runs the shell mainloop. Will display the prompt and enable interaction. diff --git a/src/lib/shell/MainLoopZephyr.cpp b/src/lib/shell/MainLoopZephyr.cpp index 27240379356a9f..e70a29c52c9dce 100644 --- a/src/lib/shell/MainLoopZephyr.cpp +++ b/src/lib/shell/MainLoopZephyr.cpp @@ -14,20 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include #include #include -#include #include #include #include -#include -using chip::Shell::cmd_completion_context; using chip::Shell::Engine; -using chip::Shell::shell_command_t; -using chip::Shell::shell_map_t; static int cmd_matter(const struct shell * shell, size_t argc, char ** argv) { @@ -35,96 +29,15 @@ static int cmd_matter(const struct shell * shell, size_t argc, char ** argv) return (Engine::Root().ExecCommand(argc - 1, argv + 1) == CHIP_NO_ERROR) ? 0 : -ENOEXEC; } -/** - * This recursive function obtains all sub-commands (possbile completions) for a command node - * and build it into a tree of Zephyr's shell_static_entry structure. - * - * @param prefix The path/prefix until the root command node of the tree, without tailing space. - * e.g. "dns browse". Set to emptry string "" if building tree for a root-level command. - * @param syntax The single-word command name/syntax for the root node of the tree. e.g. "resolve". - * Set to emptry string "" if calling to build from the root (to include all commands). - * @param help The help text for the command at roote node of the tree. Set to NULL if none. - * - * @return The shell_static_entry structure tree that chains all the sub-commands from the - * requested command node. - * - */ -const struct shell_static_entry * build_command_tree(const char * prefix, const char * syntax, const char * help) -{ - - char * sub_prefix = new char[strlen(prefix) + strlen(syntax) + 2]; - size_t pos = 0; - if (strcmp(prefix, "") != 0) - { - strncpy(&sub_prefix[pos], prefix, strlen(prefix)); - pos += strlen(prefix); - strncpy(&sub_prefix[pos], " ", 1); - pos += 1; - } - strncpy(&sub_prefix[pos], syntax, strlen(syntax) + 1); - - cmd_completion_context context = cmd_completion_context(sub_prefix); - CHIP_ERROR ret = Engine::GetCommandCompletions(&context); - - const struct shell_static_entry * static_entry; - if (ret == CHIP_NO_ERROR && context.cmdc != 0) - { - const struct shell_static_entry * sub_static_entry = new shell_static_entry[context.cmdc + 1]; - for (size_t i = 0; i < context.cmdc; i++) - { - shell_command_t * subcmd = context.cmdv[i]; - const struct shell_static_entry * sub_entry = build_command_tree(sub_prefix, subcmd->cmd_name, subcmd->cmd_help); - if (sub_entry == nullptr) - { - // leaf node, the command should require no argument but can accept optional arguments - const struct shell_static_entry leaf_entry = { - .syntax = subcmd->cmd_name, .help = subcmd->cmd_help, .subcmd = NULL, .handler = NULL, .args = { 0, 10 } - }; - memcpy((shell_static_entry *) &sub_static_entry[i], &leaf_entry, sizeof(struct shell_static_entry)); - continue; - } - memcpy((shell_static_entry *) &sub_static_entry[i], sub_entry, sizeof(struct shell_static_entry)); - } - - // Zephyr's shell_cmd_entry.u.entry needs an additional NULL element to terminate the array. - memset((shell_static_entry *) &sub_static_entry[context.cmdc], 0, sizeof(struct shell_static_entry)); - - const struct shell_cmd_entry * sub_cmd_entry = - new const shell_cmd_entry{ .is_dynamic = false, - .u = { .entry = (const struct shell_static_entry *) sub_static_entry } }; - - // The non-leaf nodes should require at least 1 required argument (for its child) - // Set the root command to use syntax "matter" - // Only the root "matter" node should have a handler function in Zephry-shell, so that all commands are sent - // to be dispatched by their registered Engine instances. - static_entry = new const shell_static_entry{ .syntax = (strcmp(syntax, "") == 0) ? "matter" : syntax, - .help = help, - .subcmd = (const struct shell_cmd_entry *) sub_cmd_entry, - .handler = (strcmp(syntax, "") == 0) ? cmd_matter : NULL, - .args = { 1, 10 } }; - } - else - { - static_entry = nullptr; - } - delete[] sub_prefix; - return static_entry; -} - -static void register_matter_command_to_zephyr() -{ - static const struct shell_static_entry _shell_matter = *build_command_tree("", "", "Matter commands"); - static const struct shell_cmd_entry shell_cmd_matter __attribute__((section("." STRINGIFY(shell_root_cmd_matter)))) - __attribute__((used)) = { .is_dynamic = false, .u = { .entry = &_shell_matter } }; -} - static int RegisterCommands(const struct device * dev) { Engine::Root().RegisterDefaultCommands(); - register_matter_command_to_zephyr(); return 0; } -SYS_INIT(RegisterCommands, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); + +SYS_INIT(RegisterCommands, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); + +SHELL_CMD_ARG_REGISTER(matter, NULL, "Matter commands", cmd_matter, 1, 10); namespace chip { namespace Shell { diff --git a/src/lib/shell/commands/BLE.cpp b/src/lib/shell/commands/BLE.cpp index f52550096a1de3..9563e4c83054bb 100644 --- a/src/lib/shell/commands/BLE.cpp +++ b/src/lib/shell/commands/BLE.cpp @@ -111,10 +111,10 @@ void RegisterBLECommands() static const shell_command_t sBLECommand = { &BLEDispatch, "ble", "BLE transport commands" }; // Register `device` subcommands with the local shell dispatcher. - sShellDeviceSubcommands.RegisterCommands(sBLESubCommands, ArraySize(sBLESubCommands), "ble"); + sShellDeviceSubcommands.RegisterCommands(sBLESubCommands, ArraySize(sBLESubCommands)); // Register the root `btp` command with the top-level shell. - Engine::Root().RegisterCommands(&sBLECommand, 1, nullptr); + Engine::Root().RegisterCommands(&sBLECommand, 1); } } // namespace Shell diff --git a/src/lib/shell/commands/Base64.cpp b/src/lib/shell/commands/Base64.cpp index ecc9908305b13e..40d4432640352a 100644 --- a/src/lib/shell/commands/Base64.cpp +++ b/src/lib/shell/commands/Base64.cpp @@ -88,10 +88,10 @@ void RegisterBase64Commands() static const shell_command_t sBase64Command = { &Base64Dispatch, "base64", "Base64 encode / decode utilities" }; // Register `base64` subcommands with the local shell dispatcher. - sShellBase64Commands.RegisterCommands(sBase64SubCommands, ArraySize(sBase64SubCommands), "base64"); + sShellBase64Commands.RegisterCommands(sBase64SubCommands, ArraySize(sBase64SubCommands)); // Register the root `base64` command with the top-level shell. - Engine::Root().RegisterCommands(&sBase64Command, 1, nullptr); + Engine::Root().RegisterCommands(&sBase64Command, 1); } } // namespace Shell diff --git a/src/lib/shell/commands/Config.cpp b/src/lib/shell/commands/Config.cpp index c5e6ec6458f660..d8686c41bc5ba3 100644 --- a/src/lib/shell/commands/Config.cpp +++ b/src/lib/shell/commands/Config.cpp @@ -191,6 +191,7 @@ static CHIP_ERROR ConfigHandler(int argc, char ** argv) void RegisterConfigCommands() { + static const shell_command_t sConfigComand = { &ConfigHandler, "config", "Manage device configuration. Usage to dump value: config [param_name] and " "to set some values (discriminator): config [param_name] [param_value]." }; @@ -205,9 +206,10 @@ void RegisterConfigCommands() }; // Register `config` subcommands with the local shell dispatcher. - sShellConfigSubcommands.RegisterCommands(sConfigSubCommands, ArraySize(sConfigSubCommands), "config"); + sShellConfigSubcommands.RegisterCommands(sConfigSubCommands, ArraySize(sConfigSubCommands)); + // Register the root `config` command with the top-level shell. - Engine::Root().RegisterCommands(&sConfigComand, 1, nullptr); + Engine::Root().RegisterCommands(&sConfigComand, 1); return; } diff --git a/src/lib/shell/commands/Device.cpp b/src/lib/shell/commands/Device.cpp index 56c8b91f0df506..7e26a75a5c32fb 100644 --- a/src/lib/shell/commands/Device.cpp +++ b/src/lib/shell/commands/Device.cpp @@ -65,10 +65,10 @@ void RegisterDeviceCommands() static const shell_command_t sDeviceComand = { &DeviceHandler, "device", "Device management commands" }; // Register `device` subcommands with the local shell dispatcher. - sShellDeviceSubcommands.RegisterCommands(sDeviceSubCommands, ArraySize(sDeviceSubCommands), "device"); + sShellDeviceSubcommands.RegisterCommands(sDeviceSubCommands, ArraySize(sDeviceSubCommands)); // Register the root `device` command with the top-level shell. - Engine::Root().RegisterCommands(&sDeviceComand, 1, nullptr); + Engine::Root().RegisterCommands(&sDeviceComand, 1); } } // namespace Shell diff --git a/src/lib/shell/commands/Dns.cpp b/src/lib/shell/commands/Dns.cpp index 04c59026a2fefb..57c182da402598 100644 --- a/src/lib/shell/commands/Dns.cpp +++ b/src/lib/shell/commands/Dns.cpp @@ -250,13 +250,13 @@ void RegisterDnsCommands() static const shell_command_t sDnsCommand = { &DnsHandler, "dns", "Dns client commands" }; // Register `dns browse` subcommands - sShellDnsBrowseSubcommands.RegisterCommands(sDnsBrowseSubCommands, ArraySize(sDnsBrowseSubCommands), "dns browse"); + sShellDnsBrowseSubcommands.RegisterCommands(sDnsBrowseSubCommands, ArraySize(sDnsBrowseSubCommands)); // Register `dns` subcommands with the local shell dispatcher. - sShellDnsSubcommands.RegisterCommands(sDnsSubCommands, ArraySize(sDnsSubCommands), "dns"); + sShellDnsSubcommands.RegisterCommands(sDnsSubCommands, ArraySize(sDnsSubCommands)); // Register the root `dns` command with the top-level shell. - Engine::Root().RegisterCommands(&sDnsCommand, 1, nullptr); + Engine::Root().RegisterCommands(&sDnsCommand, 1); } } // namespace Shell diff --git a/src/lib/shell/commands/Meta.cpp b/src/lib/shell/commands/Meta.cpp index 5e061afc769951..7bf188de763e43 100644 --- a/src/lib/shell/commands/Meta.cpp +++ b/src/lib/shell/commands/Meta.cpp @@ -71,7 +71,7 @@ void RegisterMetaCommands() std::atexit(AtExitShell); - Engine::Root().RegisterCommands(sCmds, ArraySize(sCmds), nullptr); + Engine::Root().RegisterCommands(sCmds, ArraySize(sCmds)); } } // namespace Shell diff --git a/src/lib/shell/commands/NFC.cpp b/src/lib/shell/commands/NFC.cpp index 2f7d0dd588bfac..23b745b1901b90 100644 --- a/src/lib/shell/commands/NFC.cpp +++ b/src/lib/shell/commands/NFC.cpp @@ -90,7 +90,7 @@ void RegisterNFCCommands() "Start, stop or get nfc emulation state. Usage: nfc " }; // Register the root `device` command with the top-level shell. - Engine::Root().RegisterCommands(&sDeviceComand, 1, nullptr); + Engine::Root().RegisterCommands(&sDeviceComand, 1); } } // namespace Shell diff --git a/src/lib/shell/commands/OnboardingCodes.cpp b/src/lib/shell/commands/OnboardingCodes.cpp index 5cded64141a55f..83978e502519dd 100644 --- a/src/lib/shell/commands/OnboardingCodes.cpp +++ b/src/lib/shell/commands/OnboardingCodes.cpp @@ -169,7 +169,7 @@ void RegisterOnboardingCodesCommands() }; // Register the root `device` command with the top-level shell. - Engine::Root().RegisterCommands(&sDeviceComand, 1, nullptr); + Engine::Root().RegisterCommands(&sDeviceComand, 1); return; } diff --git a/src/lib/shell/commands/Ota.cpp b/src/lib/shell/commands/Ota.cpp index 7547d3d0f4279a..f0569d2c68bb24 100644 --- a/src/lib/shell/commands/Ota.cpp +++ b/src/lib/shell/commands/Ota.cpp @@ -198,12 +198,12 @@ void RegisterOtaCommands() { &ProgressHandler, "progress", "Gets progress of a current image update process. Usage: ota progress" } }; - sSubShell.RegisterCommands(subCommands, ArraySize(subCommands), "ota"); + sSubShell.RegisterCommands(subCommands, ArraySize(subCommands)); // Register the root `ota` command in the top-level shell. static const shell_command_t otaCommand = { &OtaHandler, "ota", "OTA commands" }; - Engine::Root().RegisterCommands(&otaCommand, 1, nullptr); + Engine::Root().RegisterCommands(&otaCommand, 1); } } // namespace Shell diff --git a/src/lib/shell/commands/WiFi.cpp b/src/lib/shell/commands/WiFi.cpp index 901845f5c0e8ca..ed531e6bf0bf20 100644 --- a/src/lib/shell/commands/WiFi.cpp +++ b/src/lib/shell/commands/WiFi.cpp @@ -138,8 +138,8 @@ void RegisterWiFiCommands() }; static const shell_command_t sWiFiCommand = { &WiFiDispatch, "wifi", "Usage: wifi " }; - sShellWiFiSubCommands.RegisterCommands(sWiFiSubCommands, ArraySize(sWiFiSubCommands), "wifi"); - Engine::Root().RegisterCommands(&sWiFiCommand, 1, nullptr); + sShellWiFiSubCommands.RegisterCommands(sWiFiSubCommands, ArraySize(sWiFiSubCommands)); + Engine::Root().RegisterCommands(&sWiFiCommand, 1); } } // namespace Shell