From 92ddd38777358132050409ea2e58f631dbff4330 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Wed, 23 Feb 2022 19:58:59 -0800 Subject: [PATCH] [cli] use template `Process` to simplify handlers (#7412) This commit updates how the CLI command handlers are defined. A template `Process()` method is now used to process a CLI command where the `CommandId` is a `uint64` hash ID derived from the command string itself. This model helps simplify the CLI modules. With this change, there is no need to declare different process methods for every CLI command in the header files. It also makes the association between a CLI command and its command string explicit and simple (e.g., `"state"` command with `Process` method). --- src/cli/cli.cpp | 583 +++++++++++++++++++++++------------ src/cli/cli.hpp | 409 +----------------------- src/cli/cli_coap.cpp | 81 +++-- src/cli/cli_coap.hpp | 40 +-- src/cli/cli_commissioner.cpp | 60 ++-- src/cli/cli_commissioner.hpp | 24 +- src/cli/cli_dataset.cpp | 136 ++++---- src/cli/cli_dataset.hpp | 53 +--- src/cli/cli_history.cpp | 54 ++-- src/cli/cli_history.hpp | 26 +- src/cli/cli_joiner.cpp | 45 ++- src/cli/cli_joiner.hpp | 14 +- src/cli/cli_network_data.cpp | 55 ++-- src/cli/cli_network_data.hpp | 28 +- src/cli/cli_output.hpp | 100 +++++- src/cli/cli_srp_client.cpp | 87 +++--- src/cli/cli_srp_client.hpp | 29 +- 17 files changed, 773 insertions(+), 1051 deletions(-) diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index f74931c06..b5394f948 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -92,8 +92,6 @@ namespace ot { namespace Cli { -constexpr Interpreter::Command Interpreter::sCommands[]; - Interpreter *Interpreter::sInterpreter = nullptr; static OT_DEFINE_ALIGNED_VAR(sInterpreterRaw, sizeof(Interpreter), uint64_t); @@ -199,7 +197,7 @@ const char *Interpreter::LinkModeToString(const otLinkModeConfig &aLinkMode, cha } #if OPENTHREAD_CONFIG_DIAG_ENABLE -otError Interpreter::ProcessDiag(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error; char * args[kMaxArgs]; @@ -216,24 +214,7 @@ otError Interpreter::ProcessDiag(Arg aArgs[]) } #endif -otError Interpreter::ProcessHelp(Arg aArgs[]) -{ - OT_UNUSED_VARIABLE(aArgs); - - for (const Command &command : sCommands) - { - OutputLine(command.mName); - } - - for (uint8_t i = 0; i < mUserCommandsLength; i++) - { - OutputLine("%s", mUserCommands[i].mName); - } - - return OT_ERROR_NONE; -} - -otError Interpreter::ProcessVersion(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -253,7 +234,7 @@ otError Interpreter::ProcessVersion(Arg aArgs[]) return error; } -otError Interpreter::ProcessReset(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -264,9 +245,8 @@ otError Interpreter::ProcessReset(Arg aArgs[]) void Interpreter::ProcessLine(char *aBuf) { - Arg args[kMaxArgs + 1]; - const Command *command; - otError error = OT_ERROR_NONE; + Arg args[kMaxArgs + 1]; + otError error = OT_ERROR_NONE; OT_ASSERT(aBuf != nullptr); @@ -289,16 +269,7 @@ void Interpreter::ProcessLine(char *aBuf) } #endif - command = BinarySearch::Find(args[0].GetCString(), sCommands); - - if (command != nullptr) - { - error = (this->*command->mHandler)(args + 1); - } - else - { - error = ProcessUserCommands(args); - } + error = ProcessCommand(args); exit: if ((error != OT_ERROR_NONE) || !args[0].IsEmpty()) @@ -431,14 +402,14 @@ exit: #endif // OPENTHREAD_CONFIG_PING_SENDER_ENABLE #if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE -otError Interpreter::ProcessHistory(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return mHistory.Process(aArgs); } #endif #if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE -otError Interpreter::ProcessBorderAgent(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -470,7 +441,7 @@ otError Interpreter::ProcessBorderAgent(Arg aArgs[]) #endif // OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE -otError Interpreter::ProcessBorderRouting(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; bool enable; @@ -513,7 +484,7 @@ exit: #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) -otError Interpreter::ProcessBackboneRouter(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_INVALID_COMMAND; otBackboneRouterConfig config; @@ -729,7 +700,7 @@ exit: } #endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE -otError Interpreter::ProcessDomainName(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -747,7 +718,7 @@ exit: } #if OPENTHREAD_CONFIG_DUA_ENABLE -otError Interpreter::ProcessDua(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -786,7 +757,7 @@ exit: #endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) -otError Interpreter::ProcessBufferInfo(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -824,7 +795,7 @@ otError Interpreter::ProcessBufferInfo(Arg aArgs[]) return OT_ERROR_NONE; } -otError Interpreter::ProcessCcaThreshold(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; int8_t cca; @@ -845,7 +816,7 @@ exit: } #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE -otError Interpreter::ProcessCcm(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; bool enable; @@ -859,7 +830,7 @@ exit: return error; } -otError Interpreter::ProcessThreadVersionCheck(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; bool enable; @@ -875,7 +846,7 @@ exit: #endif -otError Interpreter::ProcessChannel(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -1012,7 +983,7 @@ exit: } #if OPENTHREAD_FTD -otError Interpreter::ProcessChild(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; otChildInfo childInfo; @@ -1100,7 +1071,7 @@ exit: return error; } -otError Interpreter::ProcessChildIp(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -1146,14 +1117,14 @@ otError Interpreter::ProcessChildIp(Arg aArgs[]) return error; } -otError Interpreter::ProcessChildMax(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return ProcessGetSet(aArgs, otThreadGetMaxAllowedChildren, otThreadSetMaxAllowedChildren); } #endif // OPENTHREAD_FTD #if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE -otError Interpreter::ProcessChildSupervision(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_INVALID_ARGS; @@ -1172,27 +1143,27 @@ otError Interpreter::ProcessChildSupervision(Arg aArgs[]) } #endif // OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE -otError Interpreter::ProcessChildTimeout(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return ProcessGetSet(aArgs, otThreadGetChildTimeout, otThreadSetChildTimeout); } #if OPENTHREAD_CONFIG_COAP_API_ENABLE -otError Interpreter::ProcessCoap(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return mCoap.Process(aArgs); } #endif #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE -otError Interpreter::ProcessCoapSecure(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return mCoapSecure.Process(aArgs); } #endif #if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE -otError Interpreter::ProcessCoexMetrics(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; bool enable; @@ -1267,13 +1238,13 @@ exit: #endif // OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE #if OPENTHREAD_FTD -otError Interpreter::ProcessContextIdReuseDelay(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return ProcessGetSet(aArgs, otThreadGetContextIdReuseDelay, otThreadSetContextIdReuseDelay); } #endif -otError Interpreter::ProcessCounters(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -1433,7 +1404,7 @@ otError Interpreter::ProcessCounters(Arg aArgs[]) } #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE -otError Interpreter::ProcessCsl(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -1466,7 +1437,7 @@ otError Interpreter::ProcessCsl(Arg aArgs[]) #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #if OPENTHREAD_FTD -otError Interpreter::ProcessDelayTimerMin(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -1490,7 +1461,7 @@ exit: } #endif -otError Interpreter::ProcessDiscover(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; uint32_t scanChannels = 0; @@ -1515,7 +1486,7 @@ exit: return error; } -otError Interpreter::ProcessDns(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -1800,7 +1771,7 @@ void Interpreter::OutputEidCacheEntry(const otCacheEntryInfo &aEntry) OutputLine(""); } -otError Interpreter::ProcessEidCache(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -1820,7 +1791,7 @@ exit: } #endif -otError Interpreter::ProcessEui64(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -1836,7 +1807,7 @@ exit: return error; } -otError Interpreter::ProcessExtAddress(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -1856,7 +1827,7 @@ exit: return error; } -otError Interpreter::ProcessLog(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -1895,7 +1866,7 @@ exit: return error; } -otError Interpreter::ProcessExtPanId(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -1915,7 +1886,7 @@ exit: return error; } -otError Interpreter::ProcessFactoryReset(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -1925,7 +1896,7 @@ otError Interpreter::ProcessFactoryReset(Arg aArgs[]) } #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE -otError Interpreter::ProcessFake(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_INVALID_COMMAND; @@ -1959,7 +1930,7 @@ exit: } #endif -otError Interpreter::ProcessFem(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -1996,7 +1967,7 @@ exit: return error; } -otError Interpreter::ProcessIfconfig(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -2045,7 +2016,7 @@ const char *Interpreter::AddressOriginToString(uint8_t aOrigin) return Stringify(aOrigin, kOriginStrings); } -otError Interpreter::ProcessIpAddr(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; bool verbose = false; @@ -2112,7 +2083,7 @@ exit: return error; } -otError Interpreter::ProcessIpMulticastAddr(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -2126,12 +2097,12 @@ otError Interpreter::ProcessIpMulticastAddr(Arg aArgs[]) } else if (aArgs[0] == "add") { + otIp6Address address; + aArgs++; do { - otIp6Address address; - SuccessOrExit(error = aArgs->ParseAsIp6Address(address)); SuccessOrExit(error = otIp6SubscribeMulticastAddress(GetInstancePtr(), &address)); } @@ -2179,7 +2150,7 @@ exit: return error; } -otError Interpreter::ProcessKeySequence(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_INVALID_ARGS; @@ -2195,7 +2166,7 @@ otError Interpreter::ProcessKeySequence(Arg aArgs[]) return error; } -otError Interpreter::ProcessLeaderData(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -2215,7 +2186,7 @@ exit: } #if OPENTHREAD_FTD -otError Interpreter::ProcessPartitionId(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_INVALID_COMMAND; @@ -2234,7 +2205,7 @@ otError Interpreter::ProcessPartitionId(Arg aArgs[]) return error; } -otError Interpreter::ProcessLeaderWeight(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return ProcessGetSet(aArgs, otThreadGetLocalLeaderWeight, otThreadSetLocalLeaderWeight); } @@ -2357,13 +2328,36 @@ const char *Interpreter::LinkMetricsStatusToStr(uint8_t aStatus) return str; } -otError Interpreter::ProcessLinkMetrics(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_INVALID_COMMAND; if (aArgs[0] == "query") { - error = ProcessLinkMetricsQuery(aArgs + 1); + otIp6Address address; + otLinkMetrics linkMetrics; + + SuccessOrExit(error = aArgs[1].ParseAsIp6Address(address)); + + if (aArgs[2] == "single") + { + VerifyOrExit(!aArgs[3].IsEmpty(), error = OT_ERROR_INVALID_ARGS); + SuccessOrExit(error = ParseLinkMetricsFlags(linkMetrics, aArgs[3])); + error = otLinkMetricsQuery(GetInstancePtr(), &address, /* aSeriesId */ 0, &linkMetrics, + &Interpreter::HandleLinkMetricsReport, this); + } + else if (aArgs[2] == "forward") + { + uint8_t seriesId; + + SuccessOrExit(error = aArgs[3].ParseAsUint8(seriesId)); + error = otLinkMetricsQuery(GetInstancePtr(), &address, seriesId, nullptr, + &Interpreter::HandleLinkMetricsReport, this); + } + else + { + error = OT_ERROR_INVALID_ARGS; + } } else if (aArgs[0] == "mgmt") { @@ -2371,38 +2365,15 @@ otError Interpreter::ProcessLinkMetrics(Arg aArgs[]) } else if (aArgs[0] == "probe") { - error = ProcessLinkMetricsProbe(aArgs + 1); - } - - return error; -} - -otError Interpreter::ProcessLinkMetricsQuery(Arg aArgs[]) -{ - otError error; - otIp6Address address; - otLinkMetrics linkMetrics; - - SuccessOrExit(error = aArgs[0].ParseAsIp6Address(address)); - - if (aArgs[1] == "single") - { - VerifyOrExit(!aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS); - SuccessOrExit(error = ParseLinkMetricsFlags(linkMetrics, aArgs[2])); - error = otLinkMetricsQuery(GetInstancePtr(), &address, /* aSeriesId */ 0, &linkMetrics, - &Interpreter::HandleLinkMetricsReport, this); - } - else if (aArgs[1] == "forward") - { - uint8_t seriesId; + otIp6Address address; + uint8_t seriesId; + uint8_t length; + SuccessOrExit(error = aArgs[1].ParseAsIp6Address(address)); SuccessOrExit(error = aArgs[2].ParseAsUint8(seriesId)); - error = otLinkMetricsQuery(GetInstancePtr(), &address, seriesId, nullptr, &Interpreter::HandleLinkMetricsReport, - this); - } - else - { - error = OT_ERROR_INVALID_ARGS; + SuccessOrExit(error = aArgs[3].ParseAsUint8(length)); + + error = otLinkMetricsSendLinkProbe(GetInstancePtr(), &address, seriesId, length); } exit: @@ -2546,27 +2517,11 @@ exit: return error; } -otError Interpreter::ProcessLinkMetricsProbe(Arg aArgs[]) -{ - otError error = OT_ERROR_INVALID_ARGS; - otIp6Address address; - uint8_t seriesId = 0; - uint8_t length = 0; - - SuccessOrExit(error = aArgs[0].ParseAsIp6Address(address)); - SuccessOrExit(error = aArgs[1].ParseAsUint8(seriesId)); - SuccessOrExit(error = aArgs[2].ParseAsUint8(length)); - - error = otLinkMetricsSendLinkProbe(GetInstancePtr(), &address, seriesId, length); - -exit: - return error; -} #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE #if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE -otError Interpreter::ProcessLocate(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_INVALID_ARGS; otIp6Address anycastAddress; @@ -2617,7 +2572,7 @@ exit: #endif // OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE #if OPENTHREAD_FTD -otError Interpreter::ProcessPskc(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; otPskc pskc; @@ -2653,7 +2608,7 @@ exit: } #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE -otError Interpreter::ProcessPskcRef(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -2684,7 +2639,7 @@ exit: #endif // OPENTHREAD_FTD #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE -otError Interpreter::ProcessMlIid(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; otIp6InterfaceIdentifier iid; @@ -2701,7 +2656,7 @@ exit: #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE -otError Interpreter::ProcessMlr(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_INVALID_COMMAND; @@ -2773,7 +2728,7 @@ void Interpreter::HandleMlrRegResult(otError aError, #endif // (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE) && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE -otError Interpreter::ProcessMode(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; otLinkModeConfig linkMode; @@ -2818,7 +2773,7 @@ exit: return error; } -otError Interpreter::ProcessMultiRadio(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -2906,7 +2861,7 @@ void Interpreter::OutputMultiRadioInfo(const otMultiRadioNeighborInfo &aMultiRad #endif // OPENTHREAD_CONFIG_MULTI_RADIO #if OPENTHREAD_FTD -otError Interpreter::ProcessNeighbor(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; otNeighborInfo neighborInfo; @@ -2963,7 +2918,7 @@ otError Interpreter::ProcessNeighbor(Arg aArgs[]) } #endif // OPENTHREAD_FTD -otError Interpreter::ProcessNetstat(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -2986,27 +2941,22 @@ otError Interpreter::ProcessNetstat(Arg aArgs[]) } #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE -otError Interpreter::ProcessServiceList(void) -{ - otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT; - otServiceConfig config; - - while (otServerGetNextService(GetInstancePtr(), &iterator, &config) == OT_ERROR_NONE) - { - mNetworkData.OutputService(config); - } - - return OT_ERROR_NONE; -} - -otError Interpreter::ProcessService(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_INVALID_COMMAND; otServiceConfig cfg; if (aArgs[0].IsEmpty()) { - error = ProcessServiceList(); + otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT; + otServiceConfig config; + + while (otServerGetNextService(GetInstancePtr(), &iterator, &config) == OT_ERROR_NONE) + { + mNetworkData.OutputService(config); + } + + error = OT_ERROR_NONE; } else { @@ -3042,19 +2992,19 @@ exit: } #endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE -otError Interpreter::ProcessNetworkData(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return mNetworkData.Process(aArgs); } #if OPENTHREAD_FTD -otError Interpreter::ProcessNetworkIdTimeout(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return ProcessGetSet(aArgs, otThreadGetNetworkIdTimeout, otThreadSetNetworkIdTimeout); } #endif -otError Interpreter::ProcessNetworkKey(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -3078,7 +3028,7 @@ exit: } #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE -otError Interpreter::ProcessNetworkKeyRef(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -3099,7 +3049,7 @@ exit: } #endif -otError Interpreter::ProcessNetworkName(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -3117,7 +3067,7 @@ exit: } #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE -otError Interpreter::ProcessNetworkTime(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -3167,7 +3117,7 @@ exit: } #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE -otError Interpreter::ProcessPanId(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -3183,7 +3133,7 @@ otError Interpreter::ProcessPanId(Arg aArgs[]) return error; } -otError Interpreter::ProcessParent(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -3203,14 +3153,14 @@ exit: } #if OPENTHREAD_FTD -otError Interpreter::ProcessParentPriority(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return ProcessGetSet(aArgs, otThreadGetParentPriority, otThreadSetParentPriority); } #endif #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE -otError Interpreter::ProcessRouterIdRange(Arg *aArgs) +template <> otError Interpreter::Process(Arg *aArgs) { uint8_t minRouterId; uint8_t maxRouterId; @@ -3280,7 +3230,7 @@ void Interpreter::HandlePingStatistics(const otPingSenderStatistics *aStatistics } } -otError Interpreter::ProcessPing(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; otPingSenderConfig config; @@ -3377,12 +3327,12 @@ exit: #endif // OPENTHREAD_CONFIG_PING_SENDER_ENABLE -otError Interpreter::ProcessPollPeriod(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return ProcessGetSet(aArgs, otLinkGetPollPeriod, otLinkSetPollPeriod); } -otError Interpreter::ProcessPromiscuous(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -3565,7 +3515,7 @@ exit: return error; } -otError Interpreter::ProcessPrefix(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -3617,14 +3567,14 @@ exit: #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE #if OPENTHREAD_FTD -otError Interpreter::ProcessPreferRouterId(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return ProcessSet(aArgs, otThreadSetPreferredRouterId); } #endif #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE && OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE -otError Interpreter::ProcessRadioFilter(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -3645,7 +3595,7 @@ exit: } #endif -otError Interpreter::ProcessRcp(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; const char *version = otPlatRadioGetVersionString(GetInstancePtr()); @@ -3665,7 +3615,7 @@ exit: return error; } -otError Interpreter::ProcessRegion(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; uint16_t regionCode; @@ -3689,13 +3639,13 @@ exit: } #if OPENTHREAD_FTD -otError Interpreter::ProcessReleaseRouterId(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return ProcessSet(aArgs, otThreadReleaseRouterId); } #endif -otError Interpreter::ProcessRloc16(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -3746,7 +3696,7 @@ exit: return error; } -otError Interpreter::ProcessRoute(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -3785,7 +3735,7 @@ exit: #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE #if OPENTHREAD_FTD -otError Interpreter::ProcessRouter(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; otRouterInfo routerInfo; @@ -3870,12 +3820,12 @@ exit: return error; } -otError Interpreter::ProcessRouterDowngradeThreshold(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return ProcessGetSet(aArgs, otThreadGetRouterDowngradeThreshold, otThreadSetRouterDowngradeThreshold); } -otError Interpreter::ProcessRouterEligible(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -3895,18 +3845,18 @@ exit: return error; } -otError Interpreter::ProcessRouterSelectionJitter(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return ProcessGetSet(aArgs, otThreadGetRouterSelectionJitter, otThreadSetRouterSelectionJitter); } -otError Interpreter::ProcessRouterUpgradeThreshold(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return ProcessGetSet(aArgs, otThreadGetRouterUpgradeThreshold, otThreadSetRouterUpgradeThreshold); } #endif // OPENTHREAD_FTD -otError Interpreter::ProcessScan(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; uint32_t scanChannels = 0; @@ -4019,7 +3969,7 @@ exit: return; } -otError Interpreter::ProcessSingleton(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -4029,7 +3979,7 @@ otError Interpreter::ProcessSingleton(Arg aArgs[]) } #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE -otError Interpreter::ProcessSntp(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; uint16_t port = OT_SNTP_DEFAULT_SERVER_PORT; @@ -4099,7 +4049,7 @@ void Interpreter::HandleSntpResponse(uint64_t aTime, otError aResult) #endif // OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE || OPENTHREAD_CONFIG_SRP_SERVER_ENABLE -otError Interpreter::ProcessSrp(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -4134,7 +4084,7 @@ exit: } #endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE || OPENTHREAD_CONFIG_SRP_SERVER_ENABLE -otError Interpreter::ProcessState(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -4168,7 +4118,7 @@ otError Interpreter::ProcessState(Arg aArgs[]) return error; } -otError Interpreter::ProcessThread(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -4192,12 +4142,12 @@ otError Interpreter::ProcessThread(Arg aArgs[]) return error; } -otError Interpreter::ProcessDataset(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return mDataset.Process(aArgs); } -otError Interpreter::ProcessTxPower(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; int8_t power; @@ -4218,18 +4168,18 @@ exit: } #if OPENTHREAD_CONFIG_TCP_ENABLE && OPENTHREAD_CONFIG_CLI_TCP_ENABLE -otError Interpreter::ProcessTcp(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return mTcp.Process(aArgs); } #endif -otError Interpreter::ProcessUdp(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return mUdp.Process(aArgs); } -otError Interpreter::ProcessUnsecurePort(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -4274,7 +4224,7 @@ otError Interpreter::ProcessUnsecurePort(Arg aArgs[]) } #if OPENTHREAD_CONFIG_UPTIME_ENABLE -otError Interpreter::ProcessUptime(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -4299,28 +4249,28 @@ otError Interpreter::ProcessUptime(Arg aArgs[]) #endif #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD -otError Interpreter::ProcessCommissioner(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return mCommissioner.Process(aArgs); } #endif #if OPENTHREAD_CONFIG_JOINER_ENABLE -otError Interpreter::ProcessJoiner(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return mJoiner.Process(aArgs); } #endif #if OPENTHREAD_FTD -otError Interpreter::ProcessJoinerPort(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { return ProcessGetSet(aArgs, otThreadGetJoinerUdpPort, otThreadSetJoinerUdpPort); } #endif #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE -otError Interpreter::ProcessMacFilter(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -4568,7 +4518,7 @@ const char *Interpreter::MacFilterAddressModeToString(otMacFilterAddressMode aMo #endif // OPENTHREAD_CONFIG_MAC_FILTER_ENABLE -otError Interpreter::ProcessMac(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -4619,7 +4569,7 @@ exit: } #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE -otError Interpreter::ProcessTrel(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; bool enable; @@ -4714,7 +4664,7 @@ exit: #endif #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE -otError Interpreter::ProcessNetworkDiagnostic(Arg aArgs[]) +template <> otError Interpreter::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; otIp6Address address; @@ -4997,6 +4947,251 @@ void Interpreter::SetCommandTimeout(uint32_t aTimeoutMilli) mTimer.Start(aTimeoutMilli); } +otError Interpreter::ProcessCommand(Arg aArgs[]) +{ +#define CmdEntry(aCommandString) \ + { \ + aCommandString, &Interpreter::Process \ + } + + static constexpr Command kCommands[] = { +#if OPENTHREAD_FTD || OPENTHREAD_MTD +#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE + CmdEntry("ba"), +#endif +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + CmdEntry("bbr"), +#endif +#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + CmdEntry("br"), +#endif + CmdEntry("bufferinfo"), + CmdEntry("ccathreshold"), +#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + CmdEntry("ccm"), +#endif + CmdEntry("channel"), +#if OPENTHREAD_FTD + CmdEntry("child"), + CmdEntry("childip"), + CmdEntry("childmax"), +#endif +#if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE + CmdEntry("childsupervision"), +#endif + CmdEntry("childtimeout"), +#if OPENTHREAD_CONFIG_COAP_API_ENABLE + CmdEntry("coap"), +#endif +#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE + CmdEntry("coaps"), +#endif +#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE + CmdEntry("coex"), +#endif +#if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD + CmdEntry("commissioner"), +#endif +#if OPENTHREAD_FTD + CmdEntry("contextreusedelay"), +#endif + CmdEntry("counters"), +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + CmdEntry("csl"), +#endif + CmdEntry("dataset"), +#if OPENTHREAD_FTD + CmdEntry("delaytimermin"), +#endif +#endif // OPENTHREAD_FTD || OPENTHREAD_MTD +#if OPENTHREAD_CONFIG_DIAG_ENABLE + CmdEntry("diag"), +#endif +#if OPENTHREAD_FTD || OPENTHREAD_MTD + CmdEntry("discover"), + CmdEntry("dns"), +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + CmdEntry("domainname"), +#endif +#if OPENTHREAD_CONFIG_DUA_ENABLE + CmdEntry("dua"), +#endif +#if OPENTHREAD_FTD + CmdEntry("eidcache"), +#endif + CmdEntry("eui64"), + CmdEntry("extaddr"), + CmdEntry("extpanid"), + CmdEntry("factoryreset"), +#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + CmdEntry("fake"), +#endif + CmdEntry("fem"), +#endif // OPENTHREAD_FTD || OPENTHREAD_MTD +#if OPENTHREAD_FTD || OPENTHREAD_MTD +#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE + CmdEntry("history"), +#endif + CmdEntry("ifconfig"), + CmdEntry("ipaddr"), + CmdEntry("ipmaddr"), +#if OPENTHREAD_CONFIG_JOINER_ENABLE + CmdEntry("joiner"), +#endif +#if OPENTHREAD_FTD + CmdEntry("joinerport"), +#endif + CmdEntry("keysequence"), + CmdEntry("leaderdata"), +#if OPENTHREAD_FTD + CmdEntry("leaderweight"), +#endif +#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE + CmdEntry("linkmetrics"), +#endif +#if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE + CmdEntry("locate"), +#endif + CmdEntry("log"), + CmdEntry("mac"), +#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE + CmdEntry("macfilter"), +#endif +#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + CmdEntry("mliid"), +#endif +#if (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE) && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE + CmdEntry("mlr"), +#endif + CmdEntry("mode"), + CmdEntry("multiradio"), +#if OPENTHREAD_FTD + CmdEntry("neighbor"), +#endif + CmdEntry("netdata"), + CmdEntry("netstat"), +#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE + CmdEntry("networkdiagnostic"), +#endif +#if OPENTHREAD_FTD + CmdEntry("networkidtimeout"), +#endif + CmdEntry("networkkey"), +#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE + CmdEntry("networkkeyref"), +#endif + CmdEntry("networkname"), +#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE + CmdEntry("networktime"), +#endif + CmdEntry("panid"), + CmdEntry("parent"), +#if OPENTHREAD_FTD + CmdEntry("parentpriority"), + CmdEntry("partitionid"), +#endif +#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE + CmdEntry("ping"), +#endif + CmdEntry("pollperiod"), +#if OPENTHREAD_FTD + CmdEntry("preferrouterid"), +#endif +#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE + CmdEntry("prefix"), +#endif + CmdEntry("promiscuous"), +#if OPENTHREAD_FTD + CmdEntry("pskc"), +#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE + CmdEntry("pskcref"), +#endif +#endif +#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE && OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE + CmdEntry("radiofilter"), +#endif + CmdEntry("rcp"), + CmdEntry("region"), +#if OPENTHREAD_FTD + CmdEntry("releaserouterid"), +#endif +#endif // OPENTHREAD_FTD || OPENTHREAD_MTD + CmdEntry("reset"), +#if OPENTHREAD_FTD || OPENTHREAD_MTD + CmdEntry("rloc16"), +#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE + CmdEntry("route"), +#endif +#if OPENTHREAD_FTD + CmdEntry("router"), + CmdEntry("routerdowngradethreshold"), + CmdEntry("routereligible"), +#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + CmdEntry("routeridrange"), +#endif + CmdEntry("routerselectionjitter"), + CmdEntry("routerupgradethreshold"), +#endif + CmdEntry("scan"), +#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE + CmdEntry("service"), +#endif + CmdEntry("singleton"), +#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE + CmdEntry("sntp"), +#endif +#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE || OPENTHREAD_CONFIG_SRP_SERVER_ENABLE + CmdEntry("srp"), +#endif + CmdEntry("state"), +#if OPENTHREAD_CONFIG_TCP_ENABLE && OPENTHREAD_CONFIG_CLI_TCP_ENABLE + CmdEntry("tcp"), +#endif + CmdEntry("thread"), +#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE + CmdEntry("trel"), +#endif +#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + CmdEntry("tvcheck"), +#endif + CmdEntry("txpower"), + CmdEntry("udp"), + CmdEntry("unsecureport"), +#if OPENTHREAD_CONFIG_UPTIME_ENABLE + CmdEntry("uptime"), +#endif +#endif // OPENTHREAD_FTD || OPENTHREAD_MTD + CmdEntry("version"), + }; + +#undef CmdEntry + + static_assert(BinarySearch::IsSorted(kCommands), "Command Table is not sorted"); + + otError error = OT_ERROR_NONE; + const Command *command = BinarySearch::Find(aArgs[0].GetCString(), kCommands); + + if (command != nullptr) + { + error = (this->*command->mHandler)(aArgs + 1); + } + else if (aArgs[0] == "help") + { + OutputCommandTable(kCommands); + + for (uint8_t i = 0; i < mUserCommandsLength; i++) + { + OutputLine("%s", mUserCommands[i].mName); + } + } + else + { + error = ProcessUserCommands(aArgs); + } + + return error; +} + extern "C" void otCliInit(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext) { Interpreter::Initialize(aInstance, aCallback, aContext); diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp index 439ea0899..ee46c994d 100644 --- a/src/cli/cli.hpp +++ b/src/cli/cli.hpp @@ -316,34 +316,15 @@ private: static otError ParseRoute(Arg aArgs[], otExternalRouteConfig &aConfig); #endif - // Process methods on FTD/MTD/RCP -#if OPENTHREAD_CONFIG_DIAG_ENABLE - otError ProcessDiag(Arg aArgs[]); -#endif - otError ProcessHelp(Arg aArgs[]); - otError ProcessHistory(Arg aArgs[]); - otError ProcessReset(Arg aArgs[]); + otError ProcessCommand(Arg aArgs[]); + + template otError Process(Arg aArgs[]); + otError ProcessUserCommands(Arg aArgs[]); - otError ProcessVersion(Arg aArgs[]); - // Process methods only on FTD/MTD #if OPENTHREAD_FTD || OPENTHREAD_MTD - otError ProcessCcaThreshold(Arg aArgs[]); -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE - otError ProcessCcm(Arg aArgs[]); - otError ProcessThreadVersionCheck(Arg aArgs[]); -#endif - otError ProcessBufferInfo(Arg aArgs[]); - otError ProcessChannel(Arg aArgs[]); -#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE - otError ProcessBorderAgent(Arg aArgs[]); -#endif -#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE - otError ProcessBorderRouting(Arg aArgs[]); -#endif -#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) - otError ProcessBackboneRouter(Arg aArgs[]); +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE otError ProcessBackboneRouterLocal(Arg aArgs[]); #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE @@ -351,86 +332,18 @@ private: void PrintMulticastListenersTable(void); #endif #endif - - otError ProcessDomainName(Arg aArgs[]); - -#if OPENTHREAD_CONFIG_DUA_ENABLE - otError ProcessDua(Arg aArgs[]); #endif -#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) - #if OPENTHREAD_FTD - otError ProcessChild(Arg aArgs[]); - otError ProcessChildIp(Arg aArgs[]); - otError ProcessChildMax(Arg aArgs[]); -#endif -#if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE - otError ProcessChildSupervision(Arg aArgs[]); -#endif - otError ProcessChildTimeout(Arg aArgs[]); -#if OPENTHREAD_CONFIG_COAP_API_ENABLE - otError ProcessCoap(Arg aArgs[]); -#endif -#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE - otError ProcessCoapSecure(Arg aArgs[]); -#endif -#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE - otError ProcessCoexMetrics(Arg aArgs[]); -#endif -#if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD - otError ProcessCommissioner(Arg aArgs[]); -#endif -#if OPENTHREAD_FTD - otError ProcessContextIdReuseDelay(Arg aArgs[]); -#endif - otError ProcessCounters(Arg aArgs[]); - otError ProcessCsl(Arg aArgs[]); -#if OPENTHREAD_FTD - otError ProcessDelayTimerMin(Arg aArgs[]); -#endif - otError ProcessDiscover(Arg aArgs[]); - otError ProcessDns(Arg aArgs[]); -#if OPENTHREAD_FTD - void OutputEidCacheEntry(const otCacheEntryInfo &aEntry); - otError ProcessEidCache(Arg aArgs[]); -#endif - otError ProcessEui64(Arg aArgs[]); - otError ProcessLog(Arg aArgs[]); - otError ProcessExtAddress(Arg aArgs[]); - otError ProcessExtPanId(Arg aArgs[]); - otError ProcessFactoryReset(Arg aArgs[]); -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE - otError ProcessFake(Arg aArgs[]); -#endif - otError ProcessFem(Arg aArgs[]); - otError ProcessIfconfig(Arg aArgs[]); - otError ProcessIpAddr(Arg aArgs[]); - otError ProcessIpMulticastAddr(Arg aArgs[]); -#if OPENTHREAD_CONFIG_JOINER_ENABLE - otError ProcessJoiner(Arg aArgs[]); -#endif -#if OPENTHREAD_FTD - otError ProcessJoinerPort(Arg aArgs[]); -#endif - otError ProcessKeySequence(Arg aArgs[]); - otError ProcessLeaderData(Arg aArgs[]); -#if OPENTHREAD_FTD - otError ProcessPartitionId(Arg aArgs[]); - otError ProcessLeaderWeight(Arg aArgs[]); -#endif -#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE - otError ProcessMlIid(Arg aArgs[]); + void OutputEidCacheEntry(const otCacheEntryInfo &aEntry); #endif #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE - otError ProcessLinkMetrics(Arg aArgs[]); otError ProcessLinkMetricsQuery(Arg aArgs[]); otError ProcessLinkMetricsMgmt(Arg aArgs[]); otError ProcessLinkMetricsProbe(Arg aArgs[]); otError ParseLinkMetricsFlags(otLinkMetrics &aLinkMetrics, const Arg &aFlags); #endif #if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE - otError ProcessLocate(Arg aArgs[]); static void HandleLocateResult(void * aContext, otError aError, const otIp6Address *aMeshLocalAddress, @@ -438,8 +351,6 @@ private: void HandleLocateResult(otError aError, const otIp6Address *aMeshLocalAddress, uint16_t aRloc16); #endif #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE - otError ProcessMlr(Arg aArgs[]); - static void HandleMlrRegResult(void * aContext, otError aError, uint8_t aMlrStatus, @@ -450,108 +361,17 @@ private: const otIp6Address *aFailedAddresses, uint8_t aFailedAddressNum); #endif - otError ProcessMode(Arg aArgs[]); - otError ProcessMultiRadio(Arg aArgs[]); #if OPENTHREAD_CONFIG_MULTI_RADIO void OutputMultiRadioInfo(const otMultiRadioNeighborInfo &aMultiRadioInfo); #endif -#if OPENTHREAD_FTD - otError ProcessNeighbor(Arg aArgs[]); -#endif - otError ProcessNetworkData(Arg aArgs[]); - otError ProcessNetstat(Arg aArgs[]); -#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE - otError ProcessService(Arg aArgs[]); - otError ProcessServiceList(void); -#endif -#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE - otError ProcessNetworkDiagnostic(Arg aArgs[]); -#endif -#if OPENTHREAD_FTD - otError ProcessNetworkIdTimeout(Arg aArgs[]); -#endif - otError ProcessNetworkKey(Arg aArgs[]); -#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE - otError ProcessNetworkKeyRef(Arg aArgs[]); -#endif - otError ProcessNetworkName(Arg aArgs[]); -#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE - otError ProcessNetworkTime(Arg aArgs[]); -#endif - otError ProcessPanId(Arg aArgs[]); - otError ProcessParent(Arg aArgs[]); -#if OPENTHREAD_FTD - otError ProcessParentPriority(Arg aArgs[]); -#endif -#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE - otError ProcessPing(Arg aArgs[]); -#endif - otError ProcessPollPeriod(Arg aArgs[]); -#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE - otError ProcessPrefix(Arg aArgs[]); -#endif - otError ProcessPromiscuous(Arg aArgs[]); -#if OPENTHREAD_FTD - otError ProcessPreferRouterId(Arg aArgs[]); - otError ProcessPskc(Arg aArgs[]); -#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE - otError ProcessPskcRef(Arg aArgs[]); -#endif -#endif -#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE && OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE - otError ProcessRadioFilter(Arg aArgs[]); -#endif - otError ProcessRcp(Arg aArgs[]); - otError ProcessRegion(Arg aArgs[]); -#if OPENTHREAD_FTD - otError ProcessReleaseRouterId(Arg aArgs[]); -#endif -#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE - otError ProcessRoute(Arg aArgs[]); -#endif -#if OPENTHREAD_FTD - otError ProcessRouter(Arg aArgs[]); - otError ProcessRouterDowngradeThreshold(Arg aArgs[]); - otError ProcessRouterEligible(Arg aArgs[]); - otError ProcessRouterSelectionJitter(Arg aArgs[]); - otError ProcessRouterUpgradeThreshold(Arg aArgs[]); -#endif - otError ProcessRloc16(Arg aArgs[]); - otError ProcessScan(Arg aArgs[]); - otError ProcessSingleton(Arg aArgs[]); -#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE - otError ProcessSntp(Arg aArgs[]); -#endif -#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE || OPENTHREAD_CONFIG_SRP_SERVER_ENABLE - otError ProcessSrp(Arg aArgs[]); -#endif - otError ProcessState(Arg aArgs[]); - otError ProcessThread(Arg aArgs[]); - otError ProcessDataset(Arg aArgs[]); - otError ProcessTxPower(Arg aArgs[]); -#if OPENTHREAD_CONFIG_TCP_ENABLE && OPENTHREAD_CONFIG_CLI_TCP_ENABLE - otError ProcessTcp(Arg aArgs[]); -#endif - otError ProcessUdp(Arg aArgs[]); - otError ProcessUnsecurePort(Arg aArgs[]); -#if OPENTHREAD_CONFIG_UPTIME_ENABLE - otError ProcessUptime(Arg aArgs[]); -#endif + #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE - otError ProcessMacFilter(Arg aArgs[]); void PrintMacFilter(void); otError ProcessMacFilterAddress(Arg aArgs[]); otError ProcessMacFilterRss(Arg aArgs[]); void OutputMacFilterEntry(const otMacFilterEntry &aEntry); static const char *MacFilterAddressModeToString(otMacFilterAddressMode aMode); #endif - otError ProcessMac(Arg aArgs[]); -#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE - otError ProcessTrel(Arg aArgs[]); -#endif -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE - otError ProcessRouterIdRange(Arg *aArgs); -#endif #if OPENTHREAD_CONFIG_PING_SENDER_ENABLE static void HandlePingReply(const otPingSenderReply *aReply, void *aContext); @@ -646,221 +466,6 @@ private: static void HandleTimer(Timer &aTimer); void HandleTimer(void); - // Commands supported by radio: - // [diag, help, reset, version] - static constexpr Command sCommands[] = { -#if OPENTHREAD_FTD || OPENTHREAD_MTD -#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE - {"ba", &Interpreter::ProcessBorderAgent}, -#endif -#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) - {"bbr", &Interpreter::ProcessBackboneRouter}, -#endif -#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE - {"br", &Interpreter::ProcessBorderRouting}, -#endif - {"bufferinfo", &Interpreter::ProcessBufferInfo}, - {"ccathreshold", &Interpreter::ProcessCcaThreshold}, -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE - {"ccm", &Interpreter::ProcessCcm}, -#endif - {"channel", &Interpreter::ProcessChannel}, -#if OPENTHREAD_FTD - {"child", &Interpreter::ProcessChild}, - {"childip", &Interpreter::ProcessChildIp}, - {"childmax", &Interpreter::ProcessChildMax}, -#endif -#if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE - {"childsupervision", &Interpreter::ProcessChildSupervision}, -#endif - {"childtimeout", &Interpreter::ProcessChildTimeout}, -#if OPENTHREAD_CONFIG_COAP_API_ENABLE - {"coap", &Interpreter::ProcessCoap}, -#endif -#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE - {"coaps", &Interpreter::ProcessCoapSecure}, -#endif -#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE - {"coex", &Interpreter::ProcessCoexMetrics}, -#endif -#if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD - {"commissioner", &Interpreter::ProcessCommissioner}, -#endif -#if OPENTHREAD_FTD - {"contextreusedelay", &Interpreter::ProcessContextIdReuseDelay}, -#endif - {"counters", &Interpreter::ProcessCounters}, -#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - {"csl", &Interpreter::ProcessCsl}, -#endif - {"dataset", &Interpreter::ProcessDataset}, -#if OPENTHREAD_FTD - {"delaytimermin", &Interpreter::ProcessDelayTimerMin}, -#endif -#endif // OPENTHREAD_FTD || OPENTHREAD_MTD -#if OPENTHREAD_CONFIG_DIAG_ENABLE - {"diag", &Interpreter::ProcessDiag}, -#endif -#if OPENTHREAD_FTD || OPENTHREAD_MTD - {"discover", &Interpreter::ProcessDiscover}, - {"dns", &Interpreter::ProcessDns}, -#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) - {"domainname", &Interpreter::ProcessDomainName}, -#endif -#if OPENTHREAD_CONFIG_DUA_ENABLE - {"dua", &Interpreter::ProcessDua}, -#endif -#if OPENTHREAD_FTD - {"eidcache", &Interpreter::ProcessEidCache}, -#endif - {"eui64", &Interpreter::ProcessEui64}, - {"extaddr", &Interpreter::ProcessExtAddress}, - {"extpanid", &Interpreter::ProcessExtPanId}, - {"factoryreset", &Interpreter::ProcessFactoryReset}, -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE - {"fake", &Interpreter::ProcessFake}, -#endif - {"fem", &Interpreter::ProcessFem}, -#endif // OPENTHREAD_FTD || OPENTHREAD_MTD - {"help", &Interpreter::ProcessHelp}, -#if OPENTHREAD_FTD || OPENTHREAD_MTD -#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE - {"history", &Interpreter::ProcessHistory}, -#endif - {"ifconfig", &Interpreter::ProcessIfconfig}, - {"ipaddr", &Interpreter::ProcessIpAddr}, - {"ipmaddr", &Interpreter::ProcessIpMulticastAddr}, -#if OPENTHREAD_CONFIG_JOINER_ENABLE - {"joiner", &Interpreter::ProcessJoiner}, -#endif -#if OPENTHREAD_FTD - {"joinerport", &Interpreter::ProcessJoinerPort}, -#endif - {"keysequence", &Interpreter::ProcessKeySequence}, - {"leaderdata", &Interpreter::ProcessLeaderData}, -#if OPENTHREAD_FTD - {"leaderweight", &Interpreter::ProcessLeaderWeight}, -#endif -#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE - {"linkmetrics", &Interpreter::ProcessLinkMetrics}, -#endif -#if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE - {"locate", &Interpreter::ProcessLocate}, -#endif - {"log", &Interpreter::ProcessLog}, - {"mac", &Interpreter::ProcessMac}, -#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE - {"macfilter", &Interpreter::ProcessMacFilter}, -#endif -#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE - {"mliid", &Interpreter::ProcessMlIid}, -#endif -#if (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE) && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE - {"mlr", &Interpreter::ProcessMlr}, -#endif - {"mode", &Interpreter::ProcessMode}, - {"multiradio", &Interpreter::ProcessMultiRadio}, -#if OPENTHREAD_FTD - {"neighbor", &Interpreter::ProcessNeighbor}, -#endif - {"netdata", &Interpreter::ProcessNetworkData}, - {"netstat", &Interpreter::ProcessNetstat}, -#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE - {"networkdiagnostic", &Interpreter::ProcessNetworkDiagnostic}, -#endif -#if OPENTHREAD_FTD - {"networkidtimeout", &Interpreter::ProcessNetworkIdTimeout}, -#endif - {"networkkey", &Interpreter::ProcessNetworkKey}, -#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE - {"networkkeyref", &Interpreter::ProcessNetworkKeyRef}, -#endif - {"networkname", &Interpreter::ProcessNetworkName}, -#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE - {"networktime", &Interpreter::ProcessNetworkTime}, -#endif - {"panid", &Interpreter::ProcessPanId}, - {"parent", &Interpreter::ProcessParent}, -#if OPENTHREAD_FTD - {"parentpriority", &Interpreter::ProcessParentPriority}, - {"partitionid", &Interpreter::ProcessPartitionId}, -#endif -#if OPENTHREAD_CONFIG_PING_SENDER_ENABLE - {"ping", &Interpreter::ProcessPing}, -#endif - {"pollperiod", &Interpreter::ProcessPollPeriod}, -#if OPENTHREAD_FTD - {"preferrouterid", &Interpreter::ProcessPreferRouterId}, -#endif -#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE - {"prefix", &Interpreter::ProcessPrefix}, -#endif - {"promiscuous", &Interpreter::ProcessPromiscuous}, -#if OPENTHREAD_FTD - {"pskc", &Interpreter::ProcessPskc}, -#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE - {"pskcref", &Interpreter::ProcessPskcRef}, -#endif -#endif -#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE && OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE - {"radiofilter", &Interpreter::ProcessRadioFilter}, -#endif - {"rcp", &Interpreter::ProcessRcp}, - {"region", &Interpreter::ProcessRegion}, -#if OPENTHREAD_FTD - {"releaserouterid", &Interpreter::ProcessReleaseRouterId}, -#endif -#endif // OPENTHREAD_FTD || OPENTHREAD_MTD - {"reset", &Interpreter::ProcessReset}, -#if OPENTHREAD_FTD || OPENTHREAD_MTD - {"rloc16", &Interpreter::ProcessRloc16}, -#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE - {"route", &Interpreter::ProcessRoute}, -#endif -#if OPENTHREAD_FTD - {"router", &Interpreter::ProcessRouter}, - {"routerdowngradethreshold", &Interpreter::ProcessRouterDowngradeThreshold}, - {"routereligible", &Interpreter::ProcessRouterEligible}, -#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE - {"routeridrange", &Interpreter::ProcessRouterIdRange}, -#endif - {"routerselectionjitter", &Interpreter::ProcessRouterSelectionJitter}, - {"routerupgradethreshold", &Interpreter::ProcessRouterUpgradeThreshold}, -#endif - {"scan", &Interpreter::ProcessScan}, -#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE - {"service", &Interpreter::ProcessService}, -#endif - {"singleton", &Interpreter::ProcessSingleton}, -#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE - {"sntp", &Interpreter::ProcessSntp}, -#endif -#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE || OPENTHREAD_CONFIG_SRP_SERVER_ENABLE - {"srp", &Interpreter::ProcessSrp}, -#endif - {"state", &Interpreter::ProcessState}, -#if OPENTHREAD_CONFIG_TCP_ENABLE && OPENTHREAD_CONFIG_CLI_TCP_ENABLE - {"tcp", &Interpreter::ProcessTcp}, -#endif - {"thread", &Interpreter::ProcessThread}, -#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE - {"trel", &Interpreter::ProcessTrel}, -#endif -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE - {"tvcheck", &Interpreter::ProcessThreadVersionCheck}, -#endif - {"txpower", &Interpreter::ProcessTxPower}, - {"udp", &Interpreter::ProcessUdp}, - {"unsecureport", &Interpreter::ProcessUnsecurePort}, -#if OPENTHREAD_CONFIG_UPTIME_ENABLE - {"uptime", &Interpreter::ProcessUptime}, -#endif -#endif // OPENTHREAD_FTD || OPENTHREAD_MTD - {"version", &Interpreter::ProcessVersion}, - }; - - static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted"); - const otCliCommand *mUserCommands; uint8_t mUserCommandsLength; void * mUserCommandsContext; diff --git a/src/cli/cli_coap.cpp b/src/cli/cli_coap.cpp index 20e88cf85..5d7c26098 100644 --- a/src/cli/cli_coap.cpp +++ b/src/cli/cli_coap.cpp @@ -44,8 +44,6 @@ namespace ot { namespace Cli { -constexpr Coap::Command Coap::sCommands[]; - Coap::Coap(Output &aOutput) : OutputWrapper(aOutput) , mUseDefaultRequestTxParameters(true) @@ -144,7 +142,7 @@ void Coap::PrintPayload(otMessage *aMessage) } #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE -otError Coap::ProcessCancel(Arg aArgs[]) +template <> otError Coap::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -152,19 +150,7 @@ otError Coap::ProcessCancel(Arg aArgs[]) } #endif -otError Coap::ProcessHelp(Arg aArgs[]) -{ - OT_UNUSED_VARIABLE(aArgs); - - for (const Command &command : sCommands) - { - OutputLine(command.mName); - } - - return OT_ERROR_NONE; -} - -otError Coap::ProcessResource(Arg aArgs[]) +template <> otError Coap::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -203,7 +189,7 @@ exit: return error; } -otError Coap::ProcessSet(Arg aArgs[]) +template <> otError Coap::Process(Arg aArgs[]) { #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE otMessage * notificationMessage = nullptr; @@ -264,14 +250,14 @@ exit: return error; } -otError Coap::ProcessStart(Arg aArgs[]) +template <> otError Coap::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); return otCoapStart(GetInstancePtr(), OT_DEFAULT_COAP_PORT); } -otError Coap::ProcessStop(Arg aArgs[]) +template <> otError Coap::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -284,7 +270,7 @@ otError Coap::ProcessStop(Arg aArgs[]) return otCoapStop(GetInstancePtr()); } -otError Coap::ProcessParameters(Arg aArgs[]) +template <> otError Coap::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; bool * defaultTxParameters; @@ -342,28 +328,28 @@ exit: return error; } -otError Coap::ProcessGet(Arg aArgs[]) +template <> otError Coap::Process(Arg aArgs[]) { return ProcessRequest(aArgs, OT_COAP_CODE_GET); } -otError Coap::ProcessPost(Arg aArgs[]) +template <> otError Coap::Process(Arg aArgs[]) { return ProcessRequest(aArgs, OT_COAP_CODE_POST); } -otError Coap::ProcessPut(Arg aArgs[]) +template <> otError Coap::Process(Arg aArgs[]) { return ProcessRequest(aArgs, OT_COAP_CODE_PUT); } -otError Coap::ProcessDelete(Arg aArgs[]) +template <> otError Coap::Process(Arg aArgs[]) { return ProcessRequest(aArgs, OT_COAP_CODE_DELETE); } #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE -otError Coap::ProcessObserve(Arg aArgs[]) +template <> otError Coap::Process(Arg aArgs[]) { return ProcessRequest(aArgs, OT_COAP_CODE_GET, /* aCoapObserve */ true); } @@ -577,17 +563,44 @@ exit: otError Coap::Process(Arg aArgs[]) { - otError error = OT_ERROR_INVALID_ARGS; - const Command *command; - - if (aArgs[0].IsEmpty()) - { - IgnoreError(ProcessHelp(aArgs)); - ExitNow(); +#define CmdEntry(aCommandString) \ + { \ + aCommandString, &Coap::Process \ } - command = BinarySearch::Find(aArgs[0].GetCString(), sCommands); - VerifyOrExit(command != nullptr, error = OT_ERROR_INVALID_COMMAND); + static constexpr Command kCommands[] = { +#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE + CmdEntry("cancel"), +#endif + CmdEntry("delete"), + CmdEntry("get"), +#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE + CmdEntry("observe"), +#endif + CmdEntry("parameters"), + CmdEntry("post"), + CmdEntry("put"), + CmdEntry("resource"), + CmdEntry("set"), + CmdEntry("start"), + CmdEntry("stop"), + }; + +#undef CmdEntry + + static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted"); + + otError error = OT_ERROR_INVALID_COMMAND; + const Command *command; + + if (aArgs[0].IsEmpty() || (aArgs[0] == "help")) + { + OutputCommandTable(kCommands); + ExitNow(error = aArgs[0].IsEmpty() ? OT_ERROR_INVALID_ARGS : OT_ERROR_NONE); + } + + command = BinarySearch::Find(aArgs[0].GetCString(), kCommands); + VerifyOrExit(command != nullptr); error = (this->*command->mHandler)(aArgs + 1); diff --git a/src/cli/cli_coap.hpp b/src/cli/cli_coap.hpp index 022bff0ba..afa56bfca 100644 --- a/src/cli/cli_coap.hpp +++ b/src/cli/cli_coap.hpp @@ -86,6 +86,8 @@ private: }; #endif + template otError Process(Arg aArgs[]); + #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE otError CancelResourceSubscription(void); void CancelSubscriber(void); @@ -93,23 +95,6 @@ private: void PrintPayload(otMessage *aMessage); - otError ProcessHelp(Arg aArgs[]); -#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE - otError ProcessCancel(Arg aArgs[]); -#endif - otError ProcessDelete(Arg aArgs[]); - otError ProcessGet(Arg aArgs[]); -#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE - otError ProcessObserve(Arg aArgs[]); -#endif - otError ProcessParameters(Arg aArgs[]); - otError ProcessPost(Arg aArgs[]); - otError ProcessPut(Arg aArgs[]); - otError ProcessResource(Arg aArgs[]); - otError ProcessSet(Arg aArgs[]); - otError ProcessStart(Arg aArgs[]); - otError ProcessStop(Arg aArgs[]); - #if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE otError ProcessRequest(Arg aArgs[], otCoapCode aCoapCode, bool aCoapObserve = false); #else @@ -161,27 +146,6 @@ private: return mUseDefaultResponseTxParameters ? nullptr : &mResponseTxParameters; } - static constexpr Command sCommands[] = { -#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE - {"cancel", &Coap::ProcessCancel}, -#endif - {"delete", &Coap::ProcessDelete}, - {"get", &Coap::ProcessGet}, - {"help", &Coap::ProcessHelp}, -#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE - {"observe", &Coap::ProcessObserve}, -#endif - {"parameters", &Coap::ProcessParameters}, - {"post", &Coap::ProcessPost}, - {"put", &Coap::ProcessPut}, - {"resource", &Coap::ProcessResource}, - {"set", &Coap::ProcessSet}, - {"start", &Coap::ProcessStart}, - {"stop", &Coap::ProcessStop}, - }; - - static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted"); - bool mUseDefaultRequestTxParameters; bool mUseDefaultResponseTxParameters; diff --git a/src/cli/cli_commissioner.cpp b/src/cli/cli_commissioner.cpp index e8596fc34..f9a6e3b40 100644 --- a/src/cli/cli_commissioner.cpp +++ b/src/cli/cli_commissioner.cpp @@ -40,21 +40,7 @@ namespace ot { namespace Cli { -constexpr Commissioner::Command Commissioner::sCommands[]; - -otError Commissioner::ProcessHelp(Arg aArgs[]) -{ - OT_UNUSED_VARIABLE(aArgs); - - for (const Command &command : sCommands) - { - OutputLine(command.mName); - } - - return OT_ERROR_NONE; -} - -otError Commissioner::ProcessAnnounce(Arg aArgs[]) +template <> otError Commissioner::Process(Arg aArgs[]) { otError error; uint32_t mask; @@ -73,7 +59,7 @@ exit: return error; } -otError Commissioner::ProcessEnergy(Arg aArgs[]) +template <> otError Commissioner::Process(Arg aArgs[]) { otError error; uint32_t mask; @@ -95,7 +81,7 @@ exit: return error; } -otError Commissioner::ProcessJoiner(Arg aArgs[]) +template <> otError Commissioner::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; otExtAddress addr; @@ -163,7 +149,7 @@ exit: return error; } -otError Commissioner::ProcessMgmtGet(Arg aArgs[]) +template <> otError Commissioner::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; uint8_t tlvs[32]; @@ -210,7 +196,7 @@ exit: return error; } -otError Commissioner::ProcessMgmtSet(Arg aArgs[]) +template <> otError Commissioner::Process(Arg aArgs[]) { otError error; otCommissioningDataset dataset; @@ -272,7 +258,7 @@ exit: return error; } -otError Commissioner::ProcessPanId(Arg aArgs[]) +template <> otError Commissioner::Process(Arg aArgs[]) { otError error; uint16_t panId; @@ -289,14 +275,14 @@ exit: return error; } -otError Commissioner::ProcessProvisioningUrl(Arg aArgs[]) +template <> otError Commissioner::Process(Arg aArgs[]) { // If aArgs[0] is empty, `GetCString() will return `nullptr` /// which will correctly clear the provisioning URL. return otCommissionerSetProvisioningUrl(GetInstancePtr(), aArgs[0].GetCString()); } -otError Commissioner::ProcessSessionId(Arg aArgs[]) +template <> otError Commissioner::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -305,7 +291,7 @@ otError Commissioner::ProcessSessionId(Arg aArgs[]) return OT_ERROR_NONE; } -otError Commissioner::ProcessStart(Arg aArgs[]) +template <> otError Commissioner::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -376,14 +362,14 @@ void Commissioner::HandleJoinerEvent(otCommissionerJoinerEvent aEvent, OutputLine(""); } -otError Commissioner::ProcessStop(Arg aArgs[]) +template <> otError Commissioner::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); return otCommissionerStop(GetInstancePtr()); } -otError Commissioner::ProcessState(Arg aArgs[]) +template <> otError Commissioner::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -394,16 +380,32 @@ otError Commissioner::ProcessState(Arg aArgs[]) otError Commissioner::Process(Arg aArgs[]) { +#define CmdEntry(aCommandString) \ + { \ + aCommandString, &Commissioner::Process \ + } + + static constexpr Command kCommands[] = { + CmdEntry("announce"), CmdEntry("energy"), CmdEntry("joiner"), + CmdEntry("mgmtget"), CmdEntry("mgmtset"), CmdEntry("panid"), + CmdEntry("provisioningurl"), CmdEntry("sessionid"), CmdEntry("start"), + CmdEntry("state"), CmdEntry("stop"), + }; + +#undef CmdEntry + + static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted"); + otError error = OT_ERROR_INVALID_COMMAND; const Command *command; - if (aArgs[0].IsEmpty()) + if (aArgs[0].IsEmpty() || (aArgs[0] == "help")) { - IgnoreError(ProcessHelp(aArgs)); - ExitNow(); + OutputCommandTable(kCommands); + ExitNow(error = aArgs[0].IsEmpty() ? error : OT_ERROR_NONE); } - command = BinarySearch::Find(aArgs[0].GetCString(), sCommands); + command = BinarySearch::Find(aArgs[0].GetCString(), kCommands); VerifyOrExit(command != nullptr); error = (this->*command->mHandler)(aArgs + 1); diff --git a/src/cli/cli_commissioner.hpp b/src/cli/cli_commissioner.hpp index 7360818e5..d63089d3d 100644 --- a/src/cli/cli_commissioner.hpp +++ b/src/cli/cli_commissioner.hpp @@ -81,18 +81,7 @@ private: using Command = CommandEntry; - otError ProcessHelp(Arg aArgs[]); - otError ProcessAnnounce(Arg aArgs[]); - otError ProcessEnergy(Arg aArgs[]); - otError ProcessJoiner(Arg aArgs[]); - otError ProcessMgmtGet(Arg aArgs[]); - otError ProcessMgmtSet(Arg aArgs[]); - otError ProcessPanId(Arg aArgs[]); - otError ProcessProvisioningUrl(Arg aArgs[]); - otError ProcessSessionId(Arg aArgs[]); - otError ProcessStart(Arg aArgs[]); - otError ProcessState(Arg aArgs[]); - otError ProcessStop(Arg aArgs[]); + template otError Process(Arg aArgs[]); static void HandleStateChanged(otCommissionerState aState, void *aContext); void HandleStateChanged(otCommissionerState aState); @@ -115,17 +104,6 @@ private: void HandlePanIdConflict(uint16_t aPanId, uint32_t aChannelMask); static const char *StateToString(otCommissionerState aState); - - static constexpr Command sCommands[] = { - {"announce", &Commissioner::ProcessAnnounce}, {"energy", &Commissioner::ProcessEnergy}, - {"help", &Commissioner::ProcessHelp}, {"joiner", &Commissioner::ProcessJoiner}, - {"mgmtget", &Commissioner::ProcessMgmtGet}, {"mgmtset", &Commissioner::ProcessMgmtSet}, - {"panid", &Commissioner::ProcessPanId}, {"provisioningurl", &Commissioner::ProcessProvisioningUrl}, - {"sessionid", &Commissioner::ProcessSessionId}, {"start", &Commissioner::ProcessStart}, - {"state", &Commissioner::ProcessState}, {"stop", &Commissioner::ProcessStop}, - }; - - static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted"); }; } // namespace Cli diff --git a/src/cli/cli_dataset.cpp b/src/cli/cli_dataset.cpp index 61641a243..29f3361c1 100644 --- a/src/cli/cli_dataset.cpp +++ b/src/cli/cli_dataset.cpp @@ -45,8 +45,7 @@ namespace ot { namespace Cli { -constexpr Dataset::Command Dataset::sCommands[]; -otOperationalDataset Dataset::sDataset; +otOperationalDataset Dataset::sDataset; otError Dataset::Print(otOperationalDataset &aDataset) { @@ -119,38 +118,7 @@ otError Dataset::Print(otOperationalDataset &aDataset) return OT_ERROR_NONE; } -otError Dataset::Process(Arg aArgs[]) -{ - otError error = OT_ERROR_INVALID_COMMAND; - const Command *command; - - if (aArgs[0].IsEmpty()) - { - ExitNow(error = Print(sDataset)); - } - - command = BinarySearch::Find(aArgs[0].GetCString(), sCommands); - VerifyOrExit(command != nullptr); - - error = (this->*command->mHandler)(aArgs + 1); - -exit: - return error; -} - -otError Dataset::ProcessHelp(Arg aArgs[]) -{ - OT_UNUSED_VARIABLE(aArgs); - - for (const Command &command : sCommands) - { - OutputLine(command.mName); - } - - return OT_ERROR_NONE; -} - -otError Dataset::ProcessInit(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_INVALID_ARGS; @@ -183,7 +151,7 @@ exit: return error; } -otError Dataset::ProcessActive(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_INVALID_ARGS; @@ -206,7 +174,7 @@ exit: return error; } -otError Dataset::ProcessPending(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_INVALID_ARGS; @@ -229,7 +197,7 @@ exit: return error; } -otError Dataset::ProcessActiveTimestamp(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -250,7 +218,7 @@ exit: return error; } -otError Dataset::ProcessChannel(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -271,7 +239,7 @@ exit: return error; } -otError Dataset::ProcessChannelMask(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -292,7 +260,7 @@ exit: return error; } -otError Dataset::ProcessClear(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -300,7 +268,7 @@ otError Dataset::ProcessClear(Arg aArgs[]) return OT_ERROR_NONE; } -otError Dataset::ProcessCommit(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_INVALID_ARGS; @@ -316,7 +284,7 @@ otError Dataset::ProcessCommit(Arg aArgs[]) return error; } -otError Dataset::ProcessDelay(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -337,7 +305,7 @@ exit: return error; } -otError Dataset::ProcessExtPanId(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -358,7 +326,7 @@ exit: return error; } -otError Dataset::ProcessMeshLocalPrefix(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -384,7 +352,7 @@ exit: return error; } -otError Dataset::ProcessNetworkKey(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -405,7 +373,7 @@ exit: return error; } -otError Dataset::ProcessNetworkName(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -426,7 +394,7 @@ exit: return error; } -otError Dataset::ProcessPanId(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -447,7 +415,7 @@ exit: return error; } -otError Dataset::ProcessPendingTimestamp(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -468,7 +436,7 @@ exit: return error; } -otError Dataset::ProcessMgmtSetCommand(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; otOperationalDataset dataset; @@ -583,7 +551,7 @@ exit: return error; } -otError Dataset::ProcessMgmtGetCommand(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; otOperationalDatasetComponents datasetComponents; @@ -676,7 +644,7 @@ exit: return error; } -otError Dataset::ProcessPskc(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -839,7 +807,7 @@ exit: return error; } -otError Dataset::ProcessSecurityPolicy(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -862,7 +830,7 @@ exit: return error; } -otError Dataset::ProcessSet(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; MeshCoP::Dataset::Type datasetType; @@ -907,7 +875,7 @@ exit: #if OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE && OPENTHREAD_FTD -otError Dataset::ProcessUpdater(Arg aArgs[]) +template <> otError Dataset::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -943,5 +911,65 @@ void Dataset::HandleDatasetUpdater(otError aError) #endif // OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE && OPENTHREAD_FTD +otError Dataset::Process(Arg aArgs[]) +{ +#define CmdEntry(aCommandString) \ + { \ + aCommandString, &Dataset::Process \ + } + + static constexpr Command kCommands[] = { + CmdEntry("active"), + CmdEntry("activetimestamp"), + CmdEntry("channel"), + CmdEntry("channelmask"), + CmdEntry("clear"), + CmdEntry("commit"), + CmdEntry("delay"), + CmdEntry("extpanid"), + CmdEntry("init"), + CmdEntry("meshlocalprefix"), + CmdEntry("mgmtgetcommand"), + CmdEntry("mgmtsetcommand"), + CmdEntry("networkkey"), + CmdEntry("networkname"), + CmdEntry("panid"), + CmdEntry("pending"), + CmdEntry("pendingtimestamp"), + CmdEntry("pskc"), + CmdEntry("securitypolicy"), + CmdEntry("set"), +#if OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE && OPENTHREAD_FTD + CmdEntry("updater"), +#endif + }; + +#undef CmdEntry + + static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted"); + + otError error = OT_ERROR_INVALID_COMMAND; + const Command *command; + + if (aArgs[0].IsEmpty()) + { + ExitNow(error = Print(sDataset)); + } + + if (aArgs[0] == "help") + { + OutputCommandTable(kCommands); + ExitNow(error = OT_ERROR_NONE); + } + + command = BinarySearch::Find(aArgs[0].GetCString(), kCommands); + VerifyOrExit(command != nullptr); + + error = (this->*command->mHandler)(aArgs + 1); + +exit: + return error; +} + } // namespace Cli } // namespace ot diff --git a/src/cli/cli_dataset.hpp b/src/cli/cli_dataset.hpp index d32afdd56..980bb5d10 100644 --- a/src/cli/cli_dataset.hpp +++ b/src/cli/cli_dataset.hpp @@ -70,29 +70,9 @@ public: private: using Command = CommandEntry; - otError Print(otOperationalDataset &aDataset); + template otError Process(Arg aArgs[]); - otError ProcessHelp(Arg aArgs[]); - otError ProcessActive(Arg aArgs[]); - otError ProcessActiveTimestamp(Arg aArgs[]); - otError ProcessChannel(Arg aArgs[]); - otError ProcessChannelMask(Arg aArgs[]); - otError ProcessClear(Arg aArgs[]); - otError ProcessCommit(Arg aArgs[]); - otError ProcessDelay(Arg aArgs[]); - otError ProcessExtPanId(Arg aArgs[]); - otError ProcessInit(Arg aArgs[]); - otError ProcessMeshLocalPrefix(Arg aArgs[]); - otError ProcessNetworkName(Arg aArgs[]); - otError ProcessNetworkKey(Arg aArgs[]); - otError ProcessPanId(Arg aArgs[]); - otError ProcessPending(Arg aArgs[]); - otError ProcessPendingTimestamp(Arg aArgs[]); - otError ProcessMgmtSetCommand(Arg aArgs[]); - otError ProcessMgmtGetCommand(Arg aArgs[]); - otError ProcessPskc(Arg aArgs[]); - otError ProcessSecurityPolicy(Arg aArgs[]); - otError ProcessSet(Arg aArgs[]); + otError Print(otOperationalDataset &aDataset); #if OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE && OPENTHREAD_FTD otError ProcessUpdater(Arg aArgs[]); @@ -103,35 +83,6 @@ private: void OutputSecurityPolicy(const otSecurityPolicy &aSecurityPolicy); otError ParseSecurityPolicy(otSecurityPolicy &aSecurityPolicy, Arg *&aArgs); - static constexpr Command sCommands[] = { - {"active", &Dataset::ProcessActive}, - {"activetimestamp", &Dataset::ProcessActiveTimestamp}, - {"channel", &Dataset::ProcessChannel}, - {"channelmask", &Dataset::ProcessChannelMask}, - {"clear", &Dataset::ProcessClear}, - {"commit", &Dataset::ProcessCommit}, - {"delay", &Dataset::ProcessDelay}, - {"extpanid", &Dataset::ProcessExtPanId}, - {"help", &Dataset::ProcessHelp}, - {"init", &Dataset::ProcessInit}, - {"meshlocalprefix", &Dataset::ProcessMeshLocalPrefix}, - {"mgmtgetcommand", &Dataset::ProcessMgmtGetCommand}, - {"mgmtsetcommand", &Dataset::ProcessMgmtSetCommand}, - {"networkkey", &Dataset::ProcessNetworkKey}, - {"networkname", &Dataset::ProcessNetworkName}, - {"panid", &Dataset::ProcessPanId}, - {"pending", &Dataset::ProcessPending}, - {"pendingtimestamp", &Dataset::ProcessPendingTimestamp}, - {"pskc", &Dataset::ProcessPskc}, - {"securitypolicy", &Dataset::ProcessSecurityPolicy}, - {"set", &Dataset::ProcessSet}, -#if OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE && OPENTHREAD_FTD - {"updater", &Dataset::ProcessUpdater}, -#endif - }; - - static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted"); - static otOperationalDataset sDataset; }; diff --git a/src/cli/cli_history.cpp b/src/cli/cli_history.cpp index 422ee6167..5f6095cc7 100644 --- a/src/cli/cli_history.cpp +++ b/src/cli/cli_history.cpp @@ -42,25 +42,11 @@ namespace ot { namespace Cli { -constexpr History::Command History::sCommands[]; - static const char *const kSimpleEventStrings[] = { "Added", // (0) OT_HISTORY_TRACKER_{NET_DATA_ENTRY/ADDRESSS_EVENT}_ADDED "Removed" // (1) OT_HISTORY_TRACKER_{NET_DATA_ENTRY/ADDRESS_EVENT}_REMOVED }; -otError History::ProcessHelp(Arg aArgs[]) -{ - OT_UNUSED_VARIABLE(aArgs); - - for (const Command &command : sCommands) - { - OutputLine(command.mName); - } - - return OT_ERROR_NONE; -} - otError History::ParseArgs(Arg aArgs[], bool &aIsList, uint16_t &aNumEntries) const { if (*aArgs == "list") @@ -85,7 +71,7 @@ otError History::ParseArgs(Arg aArgs[], bool &aIsList, uint16_t &aNumEntries) co return aArgs[0].IsEmpty() ? OT_ERROR_NONE : OT_ERROR_INVALID_ARGS; } -otError History::ProcessIpAddr(Arg aArgs[]) +template <> otError History::Process(Arg aArgs[]) { otError error; bool isList; @@ -146,7 +132,7 @@ exit: return error; } -otError History::ProcessIpMulticastAddr(Arg aArgs[]) +template <> otError History::Process(Arg aArgs[]) { static const char *const kEventStrings[] = { "Subscribed", // (0) OT_HISTORY_TRACKER_ADDRESS_EVENT_ADDED @@ -203,7 +189,7 @@ exit: return error; } -otError History::ProcessNeighbor(Arg aArgs[]) +template <> otError History::Process(Arg aArgs[]) { static const char *const kEventString[] = { /* (0) OT_HISTORY_TRACKER_NEIGHBOR_EVENT_ADDED -> */ "Added", @@ -268,7 +254,7 @@ exit: return error; } -otError History::ProcessNetInfo(Arg aArgs[]) +template <> otError History::Process(Arg aArgs[]) { otError error; bool isList; @@ -311,17 +297,17 @@ exit: return error; } -otError History::ProcessRx(Arg aArgs[]) +template <> otError History::Process(Arg aArgs[]) { return ProcessRxTxHistory(kRx, aArgs); } -otError History::ProcessRxTx(Arg aArgs[]) +template <> otError History::Process(Arg aArgs[]) { return ProcessRxTxHistory(kRxTx, aArgs); } -otError History::ProcessTx(Arg aArgs[]) +template <> otError History::Process(Arg aArgs[]) { return ProcessRxTxHistory(kTx, aArgs); } @@ -571,7 +557,7 @@ void History::OutputRxTxEntryTableFormat(const otHistoryTrackerMessageInfo &aInf OutputLine("| %20s | dst: %-70s |", "", addrString); } -otError History::ProcessPrefix(Arg aArgs[]) +template <> otError History::Process(Arg aArgs[]) { otError error; bool isList; @@ -621,7 +607,7 @@ exit: return error; } -otError History::ProcessRoute(Arg aArgs[]) +template <> otError History::Process(Arg aArgs[]) { otError error; bool isList; @@ -673,16 +659,30 @@ exit: otError History::Process(Arg aArgs[]) { +#define CmdEntry(aCommandString) \ + { \ + aCommandString, &History::Process \ + } + + static constexpr Command kCommands[] = { + CmdEntry("ipaddr"), CmdEntry("ipmaddr"), CmdEntry("neighbor"), CmdEntry("netinfo"), CmdEntry("prefix"), + CmdEntry("route"), CmdEntry("rx"), CmdEntry("rxtx"), CmdEntry("tx"), + }; + +#undef CmdEntry + + static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted"); + otError error = OT_ERROR_INVALID_COMMAND; const Command *command; - if (aArgs[0].IsEmpty()) + if (aArgs[0].IsEmpty() || (aArgs[0] == "help")) { - IgnoreError(ProcessHelp(aArgs)); - ExitNow(); + OutputCommandTable(kCommands); + ExitNow(error = aArgs[0].IsEmpty() ? error : OT_ERROR_NONE); } - command = BinarySearch::Find(aArgs[0].GetCString(), sCommands); + command = BinarySearch::Find(aArgs[0].GetCString(), kCommands); VerifyOrExit(command != nullptr); error = (this->*command->mHandler)(aArgs + 1); diff --git a/src/cli/cli_history.hpp b/src/cli/cli_history.hpp index b39a877f6..a17a667cd 100644 --- a/src/cli/cli_history.hpp +++ b/src/cli/cli_history.hpp @@ -88,16 +88,7 @@ private: kRxTx, }; - otError ProcessHelp(Arg aArgs[]); - otError ProcessIpAddr(Arg aArgs[]); - otError ProcessIpMulticastAddr(Arg aArgs[]); - otError ProcessNetInfo(Arg aArgs[]); - otError ProcessNeighbor(Arg aArgs[]); - otError ProcessPrefix(Arg aArgs[]); - otError ProcessRoute(Arg aArgs[]); - otError ProcessRx(Arg aArgs[]); - otError ProcessRxTx(Arg aArgs[]); - otError ProcessTx(Arg aArgs[]); + template otError Process(Arg aArgs[]); otError ParseArgs(Arg aArgs[], bool &aIsList, uint16_t &aNumEntries) const; otError ProcessRxTxHistory(RxTx aRxTx, Arg aArgs[]); @@ -107,21 +98,6 @@ private: static const char *MessagePriorityToString(uint8_t aPriority); static const char *RadioTypeToString(const otHistoryTrackerMessageInfo &aInfo); static const char *MessageTypeToString(const otHistoryTrackerMessageInfo &aInfo); - - static constexpr Command sCommands[] = { - {"help", &History::ProcessHelp}, - {"ipaddr", &History::ProcessIpAddr}, - {"ipmaddr", &History::ProcessIpMulticastAddr}, - {"neighbor", &History::ProcessNeighbor}, - {"netinfo", &History::ProcessNetInfo}, - {"prefix", &History::ProcessPrefix}, - {"route", &History::ProcessRoute}, - {"rx", &History::ProcessRx}, - {"rxtx", &History::ProcessRxTx}, - {"tx", &History::ProcessTx}, - }; - - static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted"); }; } // namespace Cli diff --git a/src/cli/cli_joiner.cpp b/src/cli/cli_joiner.cpp index a4c6e73b2..c4509fe6e 100644 --- a/src/cli/cli_joiner.cpp +++ b/src/cli/cli_joiner.cpp @@ -42,9 +42,7 @@ namespace ot { namespace Cli { -constexpr Joiner::Command Joiner::sCommands[]; - -otError Joiner::ProcessDiscerner(Arg aArgs[]) +template <> otError Joiner::Process(Arg aArgs[]) { otError error = OT_ERROR_INVALID_ARGS; @@ -79,19 +77,7 @@ exit: return error; } -otError Joiner::ProcessHelp(Arg aArgs[]) -{ - OT_UNUSED_VARIABLE(aArgs); - - for (const Command &command : sCommands) - { - OutputLine(command.mName); - } - - return OT_ERROR_NONE; -} - -otError Joiner::ProcessId(Arg aArgs[]) +template <> otError Joiner::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -100,7 +86,7 @@ otError Joiner::ProcessId(Arg aArgs[]) return OT_ERROR_NONE; } -otError Joiner::ProcessStart(Arg aArgs[]) +template <> otError Joiner::Process(Arg aArgs[]) { otError error; @@ -119,7 +105,7 @@ exit: return error; } -otError Joiner::ProcessStop(Arg aArgs[]) +template <> otError Joiner::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -128,7 +114,7 @@ otError Joiner::ProcessStop(Arg aArgs[]) return OT_ERROR_NONE; } -otError Joiner::ProcessState(Arg aArgs[]) +template <> otError Joiner::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -139,16 +125,29 @@ otError Joiner::ProcessState(Arg aArgs[]) otError Joiner::Process(Arg aArgs[]) { +#define CmdEntry(aCommandString) \ + { \ + aCommandString, &Joiner::Process \ + } + + static constexpr Command kCommands[] = { + CmdEntry("discerner"), CmdEntry("id"), CmdEntry("start"), CmdEntry("state"), CmdEntry("stop"), + }; + +#undef CmdEntry + + static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted"); + otError error = OT_ERROR_INVALID_COMMAND; const Command *command; - if (aArgs[0].IsEmpty()) + if (aArgs[0].IsEmpty() || (aArgs[0] == "help")) { - IgnoreError(ProcessHelp(aArgs)); - ExitNow(); + OutputCommandTable(kCommands); + ExitNow(error = aArgs[0].IsEmpty() ? error : OT_ERROR_NONE); } - command = BinarySearch::Find(aArgs[0].GetCString(), sCommands); + command = BinarySearch::Find(aArgs[0].GetCString(), kCommands); VerifyOrExit(command != nullptr); error = (this->*command->mHandler)(aArgs + 1); diff --git a/src/cli/cli_joiner.hpp b/src/cli/cli_joiner.hpp index f86a62dbb..d2bc640cb 100644 --- a/src/cli/cli_joiner.hpp +++ b/src/cli/cli_joiner.hpp @@ -76,22 +76,10 @@ public: private: using Command = CommandEntry; - otError ProcessDiscerner(Arg aArgs[]); - otError ProcessHelp(Arg aArgs[]); - otError ProcessId(Arg aArgs[]); - otError ProcessStart(Arg aArgs[]); - otError ProcessStop(Arg aArgs[]); - otError ProcessState(Arg aArgs[]); + template otError Process(Arg aArgs[]); static void HandleCallback(otError aError, void *aContext); void HandleCallback(otError aError); - - static constexpr Command sCommands[] = { - {"discerner", &Joiner::ProcessDiscerner}, {"help", &Joiner::ProcessHelp}, {"id", &Joiner::ProcessId}, - {"start", &Joiner::ProcessStart}, {"state", &Joiner::ProcessState}, {"stop", &Joiner::ProcessStop}, - }; - - static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted"); }; } // namespace Cli diff --git a/src/cli/cli_network_data.cpp b/src/cli/cli_network_data.cpp index 54a223939..ee02b1bbc 100644 --- a/src/cli/cli_network_data.cpp +++ b/src/cli/cli_network_data.cpp @@ -43,8 +43,6 @@ namespace ot { namespace Cli { -constexpr NetworkData::Command NetworkData::sCommands[]; - void NetworkData::PrefixFlagsToString(const otBorderRouterConfig &aConfig, FlagsString &aString) { char *flagsPtr = &aString[0]; @@ -186,20 +184,8 @@ void NetworkData::OutputService(const otServiceConfig &aConfig) OutputLine(" %04x", aConfig.mServerConfig.mRloc16); } -otError NetworkData::ProcessHelp(Arg aArgs[]) -{ - OT_UNUSED_VARIABLE(aArgs); - - for (const Command &command : sCommands) - { - OutputLine(command.mName); - } - - return OT_ERROR_NONE; -} - #if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE -otError NetworkData::ProcessPublish(Arg aArgs[]) +template <> otError NetworkData::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -261,7 +247,7 @@ exit: return error; } -otError NetworkData::ProcessUnpublish(Arg aArgs[]) +template <> otError NetworkData::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -293,7 +279,7 @@ exit: #endif // OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE -otError NetworkData::ProcessRegister(Arg aArgs[]) +template <> otError NetworkData::Process(Arg aArgs[]) { OT_UNUSED_VARIABLE(aArgs); @@ -310,7 +296,7 @@ exit: } #endif -otError NetworkData::ProcessSteeringData(Arg aArgs[]) +template <> otError NetworkData::Process(Arg aArgs[]) { otError error; otExtAddress addr; @@ -466,7 +452,7 @@ exit: return error; } -otError NetworkData::ProcessShow(Arg aArgs[]) +template <> otError NetworkData::Process(Arg aArgs[]) { otError error = OT_ERROR_INVALID_ARGS; bool local = false; @@ -506,16 +492,39 @@ exit: otError NetworkData::Process(Arg aArgs[]) { +#define CmdEntry(aCommandString) \ + { \ + aCommandString, &NetworkData::Process \ + } + + static constexpr Command kCommands[] = { +#if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE + CmdEntry("publish"), +#endif +#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE + CmdEntry("register"), +#endif + CmdEntry("show"), + CmdEntry("steeringdata"), +#if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE + CmdEntry("unpublish"), +#endif + }; + +#undef CmdEntry + + static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted"); + otError error = OT_ERROR_INVALID_COMMAND; const Command *command; - if (aArgs[0].IsEmpty()) + if (aArgs[0].IsEmpty() || (aArgs[0] == "help")) { - IgnoreError(ProcessHelp(aArgs)); - ExitNow(); + OutputCommandTable(kCommands); + ExitNow(error = aArgs[0].IsEmpty() ? error : OT_ERROR_NONE); } - command = BinarySearch::Find(aArgs[0].GetCString(), sCommands); + command = BinarySearch::Find(aArgs[0].GetCString(), kCommands); VerifyOrExit(command != nullptr); error = (this->*command->mHandler)(aArgs + 1); diff --git a/src/cli/cli_network_data.hpp b/src/cli/cli_network_data.hpp index 2efc3a7b6..0fb2098df 100644 --- a/src/cli/cli_network_data.hpp +++ b/src/cli/cli_network_data.hpp @@ -138,16 +138,7 @@ public: private: using Command = CommandEntry; - otError ProcessHelp(Arg aArgs[]); -#if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE - otError ProcessPublish(Arg aArgs[]); - otError ProcessUnpublish(Arg aArgs[]); -#endif -#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE - otError ProcessRegister(Arg aArgs[]); -#endif - otError ProcessShow(Arg aArgs[]); - otError ProcessSteeringData(Arg aArgs[]); + template otError Process(Arg aArgs[]); otError GetNextPrefix(otNetworkDataIterator *aIterator, otBorderRouterConfig *aConfig, bool aLocal); otError GetNextRoute(otNetworkDataIterator *aIterator, otExternalRouteConfig *aConfig, bool aLocal); @@ -157,23 +148,6 @@ private: void OutputPrefixes(bool aLocal); void OutputRoutes(bool aLocal); void OutputServices(bool aLocal); - - static constexpr Command sCommands[] = { - {"help", &NetworkData::ProcessHelp}, -#if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE - {"publish", &NetworkData::ProcessPublish}, -#endif -#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE - {"register", &NetworkData::ProcessRegister}, -#endif - {"show", &NetworkData::ProcessShow}, - {"steeringdata", &NetworkData::ProcessSteeringData}, -#if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE - {"unpublish", &NetworkData::ProcessUnpublish}, -#endif - }; - - static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted"); }; } // namespace Cli diff --git a/src/cli/cli_output.hpp b/src/cli/cli_output.hpp index a7aa402af..94b75a6e9 100644 --- a/src/cli/cli_output.hpp +++ b/src/cli/cli_output.hpp @@ -49,6 +49,25 @@ namespace ot { namespace Cli { +/** + * This type represents a ID number value associated with a CLI command string. + * + */ +typedef uint64_t CommandId; + +/** + * This `constexpr` function converts a CLI command string to its associated `CommandId` value. + * + * @param[in] aString The CLI command string. + * + * @returns The associated `CommandId` with @p aString. + * + */ +constexpr static CommandId Cmd(const char *aString) +{ + return (aString[0] == '\0') ? 0 : (static_cast(aString[0]) + Cmd(aString + 1) * 255u); +} + /** * This class is the base class for `Output` and `OutputWrapper` providing common helper methods. * @@ -56,6 +75,48 @@ namespace Cli { class OutputBase { public: + typedef Utils::CmdLineParser::Arg Arg; ///< An argument + + /** + * This structure represent a CLI command table entry, mapping a command with `aName` to a handler method. + * + * @tparam Cli The CLI module type. + * + */ + template struct CommandEntry + { + typedef otError (Cli::*Handler)(Arg aArgs[]); ///< The handler method pointer type. + + /** + * This method compares the entry's name with a given name. + * + * @param aName The name string to compare with. + * + * @return zero means perfect match, positive (> 0) indicates @p aName is larger than entry's name, and + * negative (< 0) indicates @p aName is smaller than entry's name. + * + */ + int Compare(const char *aName) const { return strcmp(aName, mName); } + + /** + * This `constexpr` method compares two entries to check if they are in order. + * + * @param[in] aFirst The first entry. + * @param[in] aSecond The second entry. + * + * @retval TRUE if @p aFirst and @p aSecond are in order, i.e. `aFirst < aSecond`. + * @retval FALSE if @p aFirst and @p aSecond are not in order, i.e. `aFirst >= aSecond`. + * + */ + constexpr static bool AreInOrder(const CommandEntry &aFirst, const CommandEntry &aSecond) + { + return AreStringsInOrder(aFirst.mName, aSecond.mName); + } + + const char *mName; ///< The command name. + Handler mHandler; ///< The handler method pointer. + }; + static const char kUnknownString[]; // Constant string "unknown". /** @@ -82,23 +143,6 @@ public: protected: OutputBase(void) = default; - - typedef Utils::CmdLineParser::Arg Arg; - - template struct CommandEntry - { - typedef otError (Cli::*Handler)(Arg aArgs[]); - - int Compare(const char *aName) const { return strcmp(aName, mName); } - - constexpr static bool AreInOrder(const CommandEntry &aFirst, const CommandEntry &aSecond) - { - return AreStringsInOrder(aFirst.mName, aSecond.mName); - } - - const char *mName; - Handler mHandler; - }; }; /** @@ -363,6 +407,23 @@ public: OutputTableSeparator(kTableNumColumns, &aWidths[0]); } + /** + * This method outputs the list of commands from a given command table. + * + * @tparam Cli The CLI module type. + * @tparam kLength The length of command table array. + * + * @param[in] aCommandTable The command table array. + * + */ + template void OutputCommandTable(const CommandEntry (&aCommandTable)[kLength]) + { + for (const CommandEntry &entry : aCommandTable) + { + OutputLine("%s", entry.mName); + } + } + protected: void OutputFormatV(const char *aFormat, va_list aArguments); @@ -463,6 +524,11 @@ protected: mOutput.OutputTableSeparator(aWidths); } + template void OutputCommandTable(const CommandEntry (&aCommandTable)[kLength]) + { + mOutput.OutputCommandTable(aCommandTable); + } + private: Output &mOutput; }; diff --git a/src/cli/cli_srp_client.cpp b/src/cli/cli_srp_client.cpp index 7ffa91c60..fa1b740b1 100644 --- a/src/cli/cli_srp_client.cpp +++ b/src/cli/cli_srp_client.cpp @@ -42,8 +42,6 @@ namespace ot { namespace Cli { -constexpr SrpClient::Command SrpClient::sCommands[]; - static otError CopyString(char *aDest, uint16_t aDestSize, const char *aSource) { // Copies a string from `aSource` to `aDestination` (char array), @@ -66,29 +64,9 @@ SrpClient::SrpClient(Output &aOutput) otSrpClientSetCallback(GetInstancePtr(), SrpClient::HandleCallback, this); } -otError SrpClient::Process(Arg aArgs[]) -{ - otError error = OT_ERROR_INVALID_COMMAND; - const Command *command; - - if (aArgs[0].IsEmpty()) - { - IgnoreError(ProcessHelp(aArgs)); - ExitNow(); - } - - command = BinarySearch::Find(aArgs[0].GetCString(), sCommands); - VerifyOrExit(command != nullptr); - - error = (this->*command->mHandler)(aArgs + 1); - -exit: - return error; -} - #if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE -otError SrpClient::ProcessAutoStart(Arg aArgs[]) +template <> otError SrpClient::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; bool enable; @@ -116,7 +94,7 @@ exit: #endif // OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE -otError SrpClient::ProcessCallback(Arg aArgs[]) +template <> otError SrpClient::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -132,19 +110,7 @@ exit: return error; } -otError SrpClient::ProcessHelp(Arg aArgs[]) -{ - OT_UNUSED_VARIABLE(aArgs); - - for (const Command &command : sCommands) - { - OutputLine(command.mName); - } - - return OT_ERROR_NONE; -} - -otError SrpClient::ProcessHost(Arg aArgs[]) +template <> otError SrpClient::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -265,18 +231,18 @@ exit: return error; } -otError SrpClient::ProcessLeaseInterval(Arg aArgs[]) +template <> otError SrpClient::Process(Arg aArgs[]) { return Interpreter::GetInterpreter().ProcessGetSet(aArgs, otSrpClientGetLeaseInterval, otSrpClientSetLeaseInterval); } -otError SrpClient::ProcessKeyLeaseInterval(Arg aArgs[]) +template <> otError SrpClient::Process(Arg aArgs[]) { return Interpreter::GetInterpreter().ProcessGetSet(aArgs, otSrpClientGetKeyLeaseInterval, otSrpClientSetKeyLeaseInterval); } -otError SrpClient::ProcessServer(Arg aArgs[]) +template <> otError SrpClient::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; const otSockAddr *serverSockAddr = otSrpClientGetServerAddress(GetInstancePtr()); @@ -306,7 +272,7 @@ exit: return error; } -otError SrpClient::ProcessService(Arg aArgs[]) +template <> otError SrpClient::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; bool isRemove; @@ -521,7 +487,7 @@ void SrpClient::OutputService(uint8_t aIndentSize, const otSrpClientService &aSe aService.mPort, aService.mPriority, aService.mWeight); } -otError SrpClient::ProcessStart(Arg aArgs[]) +template <> otError SrpClient::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; otSockAddr serverSockAddr; @@ -536,7 +502,7 @@ exit: return error; } -otError SrpClient::ProcessState(Arg aArgs[]) +template <> otError SrpClient::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -548,7 +514,7 @@ exit: return error; } -otError SrpClient::ProcessStop(Arg aArgs[]) +template <> otError SrpClient::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; @@ -602,6 +568,39 @@ void SrpClient::HandleCallback(otError aError, } } +otError SrpClient::Process(Arg aArgs[]) +{ +#define CmdEntry(aCommandString) \ + { \ + aCommandString, &SrpClient::Process \ + } + + static constexpr Command kCommands[] = { + CmdEntry("autostart"), CmdEntry("callback"), CmdEntry("host"), CmdEntry("keyleaseinterval"), + CmdEntry("leaseinterval"), CmdEntry("server"), CmdEntry("service"), CmdEntry("start"), + CmdEntry("state"), CmdEntry("stop"), + }; + + static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted"); + + otError error = OT_ERROR_INVALID_COMMAND; + const Command *command; + + if (aArgs[0].IsEmpty() || (aArgs[0] == "help")) + { + OutputCommandTable(kCommands); + ExitNow(error = aArgs[0].IsEmpty() ? error : OT_ERROR_NONE); + } + + command = BinarySearch::Find(aArgs[0].GetCString(), kCommands); + VerifyOrExit(command != nullptr); + + error = (this->*command->mHandler)(aArgs + 1); + +exit: + return error; +} + } // namespace Cli } // namespace ot diff --git a/src/cli/cli_srp_client.hpp b/src/cli/cli_srp_client.hpp index 5f73ae6f0..b868e6ff8 100644 --- a/src/cli/cli_srp_client.hpp +++ b/src/cli/cli_srp_client.hpp @@ -81,18 +81,9 @@ private: using Command = CommandEntry; - otError ProcessAutoStart(Arg aArgs[]); - otError ProcessCallback(Arg aArgs[]); - otError ProcessHelp(Arg aArgs[]); - otError ProcessHost(Arg aArgs[]); - otError ProcessLeaseInterval(Arg aArgs[]); - otError ProcessKeyLeaseInterval(Arg aArgs[]); - otError ProcessServer(Arg aArgs[]); - otError ProcessService(Arg aArgs[]); + template otError Process(Arg aArgs[]); + otError ProcessServiceAdd(Arg aArgs[]); - otError ProcessStart(Arg aArgs[]); - otError ProcessState(Arg aArgs[]); - otError ProcessStop(Arg aArgs[]); void OutputHostInfo(uint8_t aIndentSize, const otSrpClientHostInfo &aHostInfo); void OutputServiceList(uint8_t aIndentSize, const otSrpClientService *aServices); @@ -108,22 +99,6 @@ private: const otSrpClientService * aServices, const otSrpClientService * aRemovedServices); - static constexpr Command sCommands[] = { - {"autostart", &SrpClient::ProcessAutoStart}, - {"callback", &SrpClient::ProcessCallback}, - {"help", &SrpClient::ProcessHelp}, - {"host", &SrpClient::ProcessHost}, - {"keyleaseinterval", &SrpClient::ProcessKeyLeaseInterval}, - {"leaseinterval", &SrpClient::ProcessLeaseInterval}, - {"server", &SrpClient::ProcessServer}, - {"service", &SrpClient::ProcessService}, - {"start", &SrpClient::ProcessStart}, - {"state", &SrpClient::ProcessState}, - {"stop", &SrpClient::ProcessStop}, - }; - - static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted"); - bool mCallbackEnabled; };