diff --git a/src/lib/shell/BUILD.gn b/src/lib/shell/BUILD.gn index 46981b83bb6bb0..8a9f6233a476f6 100644 --- a/src/lib/shell/BUILD.gn +++ b/src/lib/shell/BUILD.gn @@ -20,9 +20,13 @@ import("${chip_root}/src/platform/device.gni") source_set("shell_core") { sources = [ + "Command.h", + "CommandSet.cpp", + "CommandSet.h", "Commands.h", "Engine.cpp", "Engine.h", + "SubShellCommand.h", "streamer.cpp", "streamer.h", ] diff --git a/src/lib/shell/Command.h b/src/lib/shell/Command.h new file mode 100644 index 00000000000000..0b4e3002e38d34 --- /dev/null +++ b/src/lib/shell/Command.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace chip { +namespace Shell { + +/** + * Shell command descriptor structure. + * + * Typically a set of commands is defined as an array of this structure and registered + * at the shell root using the @c Shell::Engine::Root().RegisterCommands() method, or + * used to construct a @c CommandSet. + * + * Usage example: + * + * @code + * static Shell::Command cmds[] = { + * { &cmd_echo, "echo", "Echo back provided inputs" }, + * { &cmd_exit, "exit", "Exit the shell application" }, + * { &cmd_help, "help", "List out all top level commands" }, + * { &cmd_version, "version", "Output the software version" }, + * }; + * @endcode + */ +struct Command +{ + /** + * Shell command handler function type. + * + * @param argc Number of arguments in argv. + * @param argv Array of arguments in the tokenized command line to execute. + */ + using Handler = CHIP_ERROR (*)(int argc, char * argv[]); + + Handler cmd_func; + const char * cmd_name; + const char * cmd_help; +}; + +// DEPRECATED: +// shell_command_t is used in many examples, so keep it for backwards compatibility +using shell_command_t = const Command; + +} // namespace Shell +} // namespace chip diff --git a/src/lib/shell/CommandSet.cpp b/src/lib/shell/CommandSet.cpp new file mode 100644 index 00000000000000..7a6efd9db467da --- /dev/null +++ b/src/lib/shell/CommandSet.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +namespace chip { +namespace Shell { + +CHIP_ERROR CommandSet::ExecCommand(int argc, char * argv[]) const +{ + if (argc == 0 || strcmp(argv[0], "help") == 0) + { + ShowHelp(); + return CHIP_NO_ERROR; + } + + for (const Command & command : mCommands) + { + if (strcmp(argv[0], command.cmd_name) == 0) + { + return command.cmd_func(argc - 1, argv + 1); + } + } + + return CHIP_ERROR_INVALID_ARGUMENT; +} + +void CommandSet::ShowHelp() const +{ + for (const Command & command : mCommands) + { + streamer_printf(streamer_get(), " %-15s %s\r\n", command.cmd_name, command.cmd_help); + } +} + +} // namespace Shell +} // namespace chip diff --git a/src/lib/shell/CommandSet.h b/src/lib/shell/CommandSet.h new file mode 100644 index 00000000000000..eef0b69180f8dd --- /dev/null +++ b/src/lib/shell/CommandSet.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace chip { +namespace Shell { + +/** + * Shell command set. + * + * The shell command set is a thin wrapper for the span of commands. + * It facilitates executing a matching shell command for the given input arguments. + */ +class CommandSet +{ +public: + template + constexpr CommandSet(const Command (&commands)[N]) : mCommands(commands) + {} + + /** + * Dispatch and execute the command for the given argument list. + * + * The first argument is used to select the command to be executed and + * the remaining arguments are forwarded to the command's handler. + * If no argument has been provided or the first argument is "help", then + * the function prints help text for each command and returns no error. + * + * @param argc Number of arguments in argv. + * @param argv Array of arguments in the tokenized command line to execute. + */ + CHIP_ERROR ExecCommand(int argc, char * argv[]) const; + +private: + void ShowHelp() const; + + Span mCommands; +}; + +} // namespace Shell +} // namespace chip diff --git a/src/lib/shell/Engine.h b/src/lib/shell/Engine.h index be65ed45c94dc0..a0d7cfa6fa71fe 100644 --- a/src/lib/shell/Engine.h +++ b/src/lib/shell/Engine.h @@ -26,6 +26,7 @@ #include "streamer.h" #include +#include #include #include @@ -49,40 +50,6 @@ namespace chip { namespace Shell { -/** - * Callback to execute an individual shell command. - * - * @param argc Number of arguments passed. - * @param argv Array of option strings. The command name is not included. - * - * @return 0 on success; CHIP_ERROR[...] on failure. - */ -typedef CHIP_ERROR shell_command_fn(int argc, char * argv[]); - -/** - * Descriptor structure for a single command. - * - * Typically a set of commands are defined as an array of this structure - * and passed to the `shell_register()` during application initialization. - * - * An example command set definition follows: - * - * static shell_command_t cmds[] = { - * { &cmd_echo, "echo", "Echo back provided inputs" }, - * { &cmd_exit, "exit", "Exit the shell application" }, - * { &cmd_help, "help", "List out all top level commands" }, - * { &cmd_version, "version", "Output the software version" }, - * }; - */ -struct shell_command -{ - shell_command_fn * cmd_func; - const char * cmd_name; - const char * cmd_help; -}; - -typedef const struct shell_command shell_command_t; - /** * Execution callback for a shell command. * diff --git a/src/lib/shell/SubShellCommand.h b/src/lib/shell/SubShellCommand.h new file mode 100644 index 00000000000000..2f5008a2407b93 --- /dev/null +++ b/src/lib/shell/SubShellCommand.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace chip { +namespace Shell { + +/** + * Templatized shell command handler that runs one of the provided subcommands. + * + * The array of subcommands is provided as a non-type template parameter. + * + * The first argument is used to select the subcommand to be executed and + * the remaining arguments are forwarded to the subcommand's handler. + * If no argument has been provided or the first argument is "help", then + * the function prints help text for each subcommand and returns no error. + * + * Usage example: + * @code + * constexpr Command subCommands[3] = { + * {handler_a, "cmd_a", "command a help text"}, + * {handler_b, "cmd_b", "command b help text"}, + * {handler_c, "cmd_c", "command c help text"}, + * }; + * + * // Execute the matching subcommand + * SubShellCommand<3, subCommands>(argc, argv); + * @endcode + * + * @param argc Number of arguments in argv. + * @param argv Array of arguments in the tokenized command line to execute. + */ +template +inline CHIP_ERROR SubShellCommand(int argc, char ** argv) +{ + static constexpr CommandSet commandSet(C); + + return commandSet.ExecCommand(argc, argv); +} + +} // namespace Shell +} // namespace chip diff --git a/src/lib/shell/commands/BLE.cpp b/src/lib/shell/commands/BLE.cpp index f12c2101561b6d..9647f7fc5c6f3e 100644 --- a/src/lib/shell/commands/BLE.cpp +++ b/src/lib/shell/commands/BLE.cpp @@ -21,7 +21,7 @@ #include #endif #include -#include +#include #include #include #include @@ -31,21 +31,12 @@ using chip::DeviceLayer::ConnectivityMgr; namespace chip { namespace Shell { -static chip::Shell::Engine sShellDeviceSubcommands; - -CHIP_ERROR BLEHelpHandler(int argc, char ** argv) -{ - sShellDeviceSubcommands.ForEachCommand(PrintCommandHelp, nullptr); - return CHIP_NO_ERROR; -} - CHIP_ERROR BLEAdvertiseHandler(int argc, char ** argv) { - CHIP_ERROR error = CHIP_NO_ERROR; streamer_t * sout = streamer_get(); bool adv_enabled; - VerifyOrReturnError(argc == 1, error = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(argc == 1, CHIP_ERROR_INVALID_ARGUMENT); adv_enabled = ConnectivityMgr().IsBLEAdvertisingEnabled(); if (strcmp(argv[0], "start") == 0) @@ -86,33 +77,18 @@ CHIP_ERROR BLEAdvertiseHandler(int argc, char ** argv) return CHIP_ERROR_INVALID_ARGUMENT; } - return error; -} - -CHIP_ERROR BLEDispatch(int argc, char ** argv) -{ - if (argc == 0) - { - BLEHelpHandler(argc, argv); - return CHIP_NO_ERROR; - } - return sShellDeviceSubcommands.ExecCommand(argc, argv); + return CHIP_NO_ERROR; } void RegisterBLECommands() { - static const shell_command_t sBLESubCommands[] = { - { &BLEHelpHandler, "help", "Usage: ble " }, - { &BLEAdvertiseHandler, "adv", "Enable or disable advertisement. Usage: ble adv " }, + static constexpr Command subCommands[] = { + { &BLEAdvertiseHandler, "adv", "Manage BLE advertising. Usage: ble adv " }, }; - static const shell_command_t sBLECommand = { &BLEDispatch, "ble", "BLE transport commands" }; - - // Register `device` subcommands with the local shell dispatcher. - sShellDeviceSubcommands.RegisterCommands(sBLESubCommands, ArraySize(sBLESubCommands)); + static constexpr Command bleCommand = { &SubShellCommand, "ble", "Bluetooth LE commands" }; - // Register the root `btp` command with the top-level shell. - Engine::Root().RegisterCommands(&sBLECommand, 1); + Engine::Root().RegisterCommands(&bleCommand, 1); } } // namespace Shell diff --git a/src/lib/shell/commands/Config.cpp b/src/lib/shell/commands/Config.cpp index ae1274a599bb16..e1452f9b35ba67 100644 --- a/src/lib/shell/commands/Config.cpp +++ b/src/lib/shell/commands/Config.cpp @@ -17,9 +17,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -28,19 +28,9 @@ #include #include -using chip::DeviceLayer::ConfigurationMgr; - namespace chip { namespace Shell { -static chip::Shell::Engine sShellConfigSubcommands; - -CHIP_ERROR ConfigHelpHandler(int argc, char ** argv) -{ - sShellConfigSubcommands.ForEachCommand(PrintCommandHelp, nullptr); - return CHIP_NO_ERROR; -} - static CHIP_ERROR ConfigGetVendorId(bool printHeader) { streamer_t * sout = streamer_get(); @@ -182,28 +172,7 @@ static CHIP_ERROR PrintAllConfigs() static CHIP_ERROR ConfigHandler(int argc, char ** argv) { - switch (argc) - { - case 0: - return PrintAllConfigs(); - case 1: - if ((strcmp(argv[0], "help") == 0) || (strcmp(argv[0], "-h") == 0)) - { - return ConfigHelpHandler(argc, argv); - } - } - return sShellConfigSubcommands.ExecCommand(argc, 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]." }; - - static const shell_command_t sConfigSubCommands[] = { - { &ConfigHelpHandler, "help", "Usage: config " }, + static constexpr Command subCommands[] = { { &ConfigVendorId, "vendorid", "Get VendorId. Usage: config vendorid" }, { &ConfigProductId, "productid", "Get ProductId. Usage: config productid" }, { &ConfigHardwareVersion, "hardwarever", "Get HardwareVersion. Usage: config hardwarever" }, @@ -211,11 +180,18 @@ void RegisterConfigCommands() { &ConfigDiscriminator, "discriminator", "Get/Set commissioning discriminator. Usage: config discriminator [value]" }, }; - // Register `config` subcommands with the local shell dispatcher. - sShellConfigSubcommands.RegisterCommands(sConfigSubCommands, ArraySize(sConfigSubCommands)); + static constexpr CommandSet subShell(subCommands); + + return argc ? subShell.ExecCommand(argc, argv) : PrintAllConfigs(); +} + +void RegisterConfigCommands() +{ + static constexpr Command configCommand = { &ConfigHandler, "config", + "Manage device configuration. Usage to dump value: config [param_name] and " + "to set some values (discriminator): config [param_name] [param_value]." }; - // Register the root `config` command with the top-level shell. - Engine::Root().RegisterCommands(&sConfigComand, 1); + Engine::Root().RegisterCommands(&configCommand, 1); } } // namespace Shell diff --git a/src/lib/shell/commands/Device.cpp b/src/lib/shell/commands/Device.cpp index 7e26a75a5c32fb..de11f4d2e7a25d 100644 --- a/src/lib/shell/commands/Device.cpp +++ b/src/lib/shell/commands/Device.cpp @@ -15,30 +15,15 @@ * limitations under the License. */ -#include #include -#if CONFIG_DEVICE_LAYER -#include -#endif #include -#include -#include -#include +#include #include - -using chip::DeviceLayer::ConnectivityMgr; +#include namespace chip { namespace Shell { -static chip::Shell::Engine sShellDeviceSubcommands; - -int DeviceHelpHandler(int argc, char ** argv) -{ - sShellDeviceSubcommands.ForEachCommand(PrintCommandHelp, nullptr); - return 0; -} - static CHIP_ERROR FactoryResetHandler(int argc, char ** argv) { streamer_printf(streamer_get(), "Performing factory reset ... \r\n"); @@ -46,29 +31,16 @@ static CHIP_ERROR FactoryResetHandler(int argc, char ** argv) return CHIP_NO_ERROR; } -static CHIP_ERROR DeviceHandler(int argc, char ** argv) -{ - if (argc == 0) - { - DeviceHelpHandler(argc, argv); - return CHIP_NO_ERROR; - } - return sShellDeviceSubcommands.ExecCommand(argc, argv); -} - void RegisterDeviceCommands() { - static const shell_command_t sDeviceSubCommands[] = { + static constexpr Command subCommands[] = { { &FactoryResetHandler, "factoryreset", "Performs device factory reset" }, }; - static const shell_command_t sDeviceComand = { &DeviceHandler, "device", "Device management commands" }; - - // Register `device` subcommands with the local shell dispatcher. - sShellDeviceSubcommands.RegisterCommands(sDeviceSubCommands, ArraySize(sDeviceSubCommands)); + static constexpr Command deviceComand = { &SubShellCommand, "device", + "Device management commands" }; - // Register the root `device` command with the top-level shell. - Engine::Root().RegisterCommands(&sDeviceComand, 1); + Engine::Root().RegisterCommands(&deviceComand, 1); } } // namespace Shell diff --git a/src/lib/shell/commands/Dns.cpp b/src/lib/shell/commands/Dns.cpp index c6a93657ca7440..65b3f7bc9cc537 100644 --- a/src/lib/shell/commands/Dns.cpp +++ b/src/lib/shell/commands/Dns.cpp @@ -19,13 +19,12 @@ #include #include #include -#include #include #include #include #include #include -#include +#include #include #include #include @@ -36,8 +35,6 @@ namespace Shell { namespace { -Shell::Engine sShellDnsBrowseSubcommands; -Shell::Engine sShellDnsSubcommands; Dnssd::ResolverProxy sResolverProxy; class DnsShellResolverDelegate : public Dnssd::DiscoverNodeDelegate, public AddressResolve::NodeListener @@ -232,6 +229,9 @@ CHIP_ERROR BrowseCommissionableHandler(int argc, char ** argv) streamer_printf(streamer_get(), "Browsing commissionable nodes...\r\n"); + sResolverProxy.Init(DeviceLayer::UDPEndPointManager()); + sResolverProxy.SetDiscoveryDelegate(&sDnsShellResolverDelegate); + return sResolverProxy.DiscoverCommissionableNodes(filter); } @@ -242,6 +242,9 @@ CHIP_ERROR BrowseCommissionerHandler(int argc, char ** argv) streamer_printf(streamer_get(), "Browsing commissioners...\r\n"); + sResolverProxy.Init(DeviceLayer::UDPEndPointManager()); + sResolverProxy.SetDiscoveryDelegate(&sDnsShellResolverDelegate); + return sResolverProxy.DiscoverCommissioners(filter); } @@ -252,63 +255,32 @@ CHIP_ERROR BrowseOperationalHandler(int argc, char ** argv) streamer_printf(streamer_get(), "Browsing operational...\r\n"); - return sResolverProxy.DiscoverOperationalNodes(filter); -} - -CHIP_ERROR BrowseHandler(int argc, char ** argv) -{ - if (argc == 0) - { - sShellDnsBrowseSubcommands.ForEachCommand(PrintCommandHelp, nullptr); - return CHIP_NO_ERROR; - } - sResolverProxy.Init(DeviceLayer::UDPEndPointManager()); sResolverProxy.SetDiscoveryDelegate(&sDnsShellResolverDelegate); - return sShellDnsBrowseSubcommands.ExecCommand(argc, argv); -} - -CHIP_ERROR DnsHandler(int argc, char ** argv) -{ - if (argc == 0) - { - sShellDnsSubcommands.ForEachCommand(PrintCommandHelp, nullptr); - return CHIP_NO_ERROR; - } - - return sShellDnsSubcommands.ExecCommand(argc, argv); + return sResolverProxy.DiscoverOperationalNodes(filter); } } // namespace void RegisterDnsCommands() { - static const shell_command_t sDnsBrowseSubCommands[] = { + static constexpr Command browseSubCommands[] = { { &BrowseCommissionableHandler, "commissionable", - "Browse Matter commissionable nodes. Usage: dns browse commissionable [subtype]" }, - { &BrowseCommissionerHandler, "commissioner", - "Browse Matter commissioner nodes. Usage: dns browse commissioner [subtype]" }, + "Browse Matter commissionables. Usage: dns browse commissionable [subtype]" }, + { &BrowseCommissionerHandler, "commissioner", "Browse Matter commissioners. Usage: dns browse commissioner [subtype]" }, { &BrowseOperationalHandler, "operational", "Browse Matter operational nodes. Usage: dns browse operational" }, }; - static const shell_command_t sDnsSubCommands[] = { + static constexpr Command subCommands[] = { { &ResolveHandler, "resolve", - "Resolve the DNS service. Usage: dns resolve (e.g. dns resolve 5544332211 1)" }, - { &BrowseHandler, "browse", - "Browse DNS services published by Matter nodes. Usage: dns browse " }, + "Resolve Matter operational service. Usage: dns resolve fabricid nodeid (e.g. dns resolve 5544332211 1)" }, + { &SubShellCommand, "browse", "Browse Matter DNS services" }, }; - static const shell_command_t sDnsCommand = { &DnsHandler, "dns", "Dns client commands" }; - - // Register `dns browse` subcommands - sShellDnsBrowseSubcommands.RegisterCommands(sDnsBrowseSubCommands, ArraySize(sDnsBrowseSubCommands)); - - // Register `dns` subcommands with the local shell dispatcher. - sShellDnsSubcommands.RegisterCommands(sDnsSubCommands, ArraySize(sDnsSubCommands)); + static constexpr Command dnsCommand = { &SubShellCommand, "dns", "DNS client commands" }; - // Register the root `dns` command with the top-level shell. - Engine::Root().RegisterCommands(&sDnsCommand, 1); + Engine::Root().RegisterCommands(&dnsCommand, 1); } } // namespace Shell diff --git a/src/lib/shell/commands/NFC.cpp b/src/lib/shell/commands/NFC.cpp index 23b745b1901b90..78d2cc841b66df 100644 --- a/src/lib/shell/commands/NFC.cpp +++ b/src/lib/shell/commands/NFC.cpp @@ -22,9 +22,6 @@ #endif #include #include -#include -#include -#include #include using chip::DeviceLayer::ConnectivityMgr; @@ -86,11 +83,10 @@ static CHIP_ERROR NFCHandler(int argc, char ** argv) void RegisterNFCCommands() { - static const shell_command_t sDeviceComand = { &NFCHandler, "nfc", - "Start, stop or get nfc emulation state. Usage: nfc " }; + static constexpr Command nfcComand = { &NFCHandler, "nfc", + "Start, stop or get nfc emulation state. Usage: nfc " }; - // Register the root `device` command with the top-level shell. - Engine::Root().RegisterCommands(&sDeviceComand, 1); + Engine::Root().RegisterCommands(&nfcComand, 1); } } // namespace Shell diff --git a/src/lib/shell/commands/OnboardingCodes.cpp b/src/lib/shell/commands/OnboardingCodes.cpp index 1ecb791904280b..1e17812d183a3f 100644 --- a/src/lib/shell/commands/OnboardingCodes.cpp +++ b/src/lib/shell/commands/OnboardingCodes.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -170,14 +169,12 @@ static CHIP_ERROR OnboardingHandler(int argc, char ** argv) void RegisterOnboardingCodesCommands() { - - static const shell_command_t sDeviceComand = { + static constexpr Command deviceComand = { &OnboardingHandler, "onboardingcodes", "Dump device onboarding codes. Usage: onboardingcodes none|softap|ble|onnetwork [qrcode|qrcodeurl|manualpairingcode]" }; - // Register the root `device` command with the top-level shell. - Engine::Root().RegisterCommands(&sDeviceComand, 1); + Engine::Root().RegisterCommands(&deviceComand, 1); } } // namespace Shell diff --git a/src/lib/shell/commands/Ota.cpp b/src/lib/shell/commands/Ota.cpp index 729d1b9b059466..2be0619151e2d0 100644 --- a/src/lib/shell/commands/Ota.cpp +++ b/src/lib/shell/commands/Ota.cpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include using namespace chip::DeviceLayer; @@ -28,8 +28,6 @@ namespace chip { namespace Shell { namespace { -Shell::Engine sSubShell; - CHIP_ERROR QueryImageHandler(int argc, char ** argv) { VerifyOrReturnError(GetRequestorInstance() != nullptr, CHIP_ERROR_INCORRECT_STATE); @@ -96,31 +94,15 @@ CHIP_ERROR ProgressHandler(int argc, char ** argv) return CHIP_NO_ERROR; } -CHIP_ERROR OtaHandler(int argc, char ** argv) -{ - if (argc == 0) - { - sSubShell.ForEachCommand(PrintCommandHelp, nullptr); - return CHIP_NO_ERROR; - } - - return sSubShell.ExecCommand(argc, argv); -} } // namespace void RegisterOtaCommands() { - // Register subcommands of the `ota` commands. - static const shell_command_t subCommands[] = { - { &QueryImageHandler, "query", "Query for a new image. Usage: ota query" }, - { &StateHandler, "state", "Gets state of a current image update process. Usage: ota state" }, - { &ProgressHandler, "progress", "Gets progress of a current image update process. Usage: ota progress" } - }; - - sSubShell.RegisterCommands(subCommands, ArraySize(subCommands)); + static constexpr Command subCommands[] = { { &QueryImageHandler, "query", "Query for a new image" }, + { &StateHandler, "state", "Get current image update state" }, + { &ProgressHandler, "progress", "Get current image update progress" } }; - // Register the root `ota` command in the top-level shell. - static const shell_command_t otaCommand = { &OtaHandler, "ota", "OTA commands" }; + static constexpr Command otaCommand = { &SubShellCommand, "ota", "OTA commands" }; Engine::Root().RegisterCommands(&otaCommand, 1); } diff --git a/src/lib/shell/commands/Stat.cpp b/src/lib/shell/commands/Stat.cpp index 88262e1e8daa1a..cf1799c8a71db8 100644 --- a/src/lib/shell/commands/Stat.cpp +++ b/src/lib/shell/commands/Stat.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -35,8 +36,6 @@ namespace chip { namespace Shell { namespace { -Shell::Engine sSubShell; - CHIP_ERROR StatPeakHandler(int argc, char ** argv) { auto labels = System::Stats::GetStrings(); @@ -88,24 +87,16 @@ CHIP_ERROR StatResetHandler(int argc, char ** argv) return CHIP_NO_ERROR; } -CHIP_ERROR StatHandler(int argc, char ** argv) -{ - return sSubShell.ExecCommand(argc, argv); -} } // namespace void RegisterStatCommands() { - // Register subcommands of the `stat` commands. - static const shell_command_t subCommands[] = { - { &StatPeakHandler, "peak", "Print peak usage of system resources. Usage: stat peak" }, - { &StatResetHandler, "reset", "Reset peak usage of system resources. Usage: stat reset" }, + static constexpr Command subCommands[] = { + { &StatPeakHandler, "peak", "Print peak usage of system resources" }, + { &StatResetHandler, "reset", "Reset peak usage of system resources" }, }; - sSubShell.RegisterCommands(subCommands, ArraySize(subCommands)); - - // Register the root `stat` command in the top-level shell. - static const shell_command_t statCommand = { &StatHandler, "stat", "Statistics commands" }; + static constexpr Command statCommand = { &SubShellCommand, "stat", "Statistics commands" }; Engine::Root().RegisterCommands(&statCommand, 1); } diff --git a/src/lib/shell/commands/WiFi.cpp b/src/lib/shell/commands/WiFi.cpp index 35ab5e26ae23a2..f2076a72decdba 100644 --- a/src/lib/shell/commands/WiFi.cpp +++ b/src/lib/shell/commands/WiFi.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include @@ -32,15 +32,8 @@ using namespace chip::DeviceLayer::NetworkCommissioning; namespace chip { namespace Shell { -static Shell::Engine sShellWiFiSubCommands; static DeviceLayer::NetworkCommissioning::WiFiDriver * sDriver; -static CHIP_ERROR WiFiHelpHandler(int argc, char ** argv) -{ - sShellWiFiSubCommands.ForEachCommand(PrintCommandHelp, nullptr); - return CHIP_NO_ERROR; -} - static CHIP_ERROR PrintWiFiMode() { streamer_t * sout = streamer_get(); @@ -143,15 +136,6 @@ static CHIP_ERROR WiFiDisconnectHandler(int argc, char ** argv) return ConnectivityMgr().DisconnectNetwork(); } -static CHIP_ERROR WiFiDispatch(int argc, char ** argv) -{ - if (argc == 0) - { - return WiFiHelpHandler(argc, argv); - } - return sShellWiFiSubCommands.ExecCommand(argc, argv); -} - void SetWiFiDriver(WiFiDriver * driver) { sDriver = driver; @@ -164,17 +148,15 @@ WiFiDriver * GetWiFiDriver() void RegisterWiFiCommands() { - /// Subcommands for root command: `device ` - static const shell_command_t sWiFiSubCommands[] = { - { &WiFiHelpHandler, "help", "" }, + static constexpr Command subCommands[] = { { &WiFiModeHandler, "mode", "Get/Set wifi mode. Usage: wifi mode [disable|ap|sta]" }, { &WiFiConnectHandler, "connect", "Connect to AP. Usage: wifi connect " }, { &WiFiDisconnectHandler, "disconnect", "Disconnect device from AP. Usage: wifi disconnect" }, }; - static const shell_command_t sWiFiCommand = { &WiFiDispatch, "wifi", "Usage: wifi " }; - sShellWiFiSubCommands.RegisterCommands(sWiFiSubCommands, ArraySize(sWiFiSubCommands)); - Engine::Root().RegisterCommands(&sWiFiCommand, 1); + static constexpr Command wifiCommand = { &SubShellCommand, "wifi", "Wi-Fi commands" }; + + Engine::Root().RegisterCommands(&wifiCommand, 1); } } // namespace Shell