[cli] use template Process<Cmd("command")> to simplify handlers (#7412)

This commit updates how the CLI command handlers are defined. A
template `Process<CommandId>()` 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<Cmd("state")>` method).
This commit is contained in:
Abtin Keshavarzian
2022-02-23 19:58:59 -08:00
committed by GitHub
parent bdec466cee
commit 92ddd38777
17 changed files with 773 additions and 1051 deletions
+82 -54
View File
@@ -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<Cmd("init")>(Arg aArgs[])
{
otError error = OT_ERROR_INVALID_ARGS;
@@ -183,7 +151,7 @@ exit:
return error;
}
otError Dataset::ProcessActive(Arg aArgs[])
template <> otError Dataset::Process<Cmd("active")>(Arg aArgs[])
{
otError error = OT_ERROR_INVALID_ARGS;
@@ -206,7 +174,7 @@ exit:
return error;
}
otError Dataset::ProcessPending(Arg aArgs[])
template <> otError Dataset::Process<Cmd("pending")>(Arg aArgs[])
{
otError error = OT_ERROR_INVALID_ARGS;
@@ -229,7 +197,7 @@ exit:
return error;
}
otError Dataset::ProcessActiveTimestamp(Arg aArgs[])
template <> otError Dataset::Process<Cmd("activetimestamp")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
@@ -250,7 +218,7 @@ exit:
return error;
}
otError Dataset::ProcessChannel(Arg aArgs[])
template <> otError Dataset::Process<Cmd("channel")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
@@ -271,7 +239,7 @@ exit:
return error;
}
otError Dataset::ProcessChannelMask(Arg aArgs[])
template <> otError Dataset::Process<Cmd("channelmask")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
@@ -292,7 +260,7 @@ exit:
return error;
}
otError Dataset::ProcessClear(Arg aArgs[])
template <> otError Dataset::Process<Cmd("clear")>(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<Cmd("commit")>(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<Cmd("delay")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
@@ -337,7 +305,7 @@ exit:
return error;
}
otError Dataset::ProcessExtPanId(Arg aArgs[])
template <> otError Dataset::Process<Cmd("extpanid")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
@@ -358,7 +326,7 @@ exit:
return error;
}
otError Dataset::ProcessMeshLocalPrefix(Arg aArgs[])
template <> otError Dataset::Process<Cmd("meshlocalprefix")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
@@ -384,7 +352,7 @@ exit:
return error;
}
otError Dataset::ProcessNetworkKey(Arg aArgs[])
template <> otError Dataset::Process<Cmd("networkkey")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
@@ -405,7 +373,7 @@ exit:
return error;
}
otError Dataset::ProcessNetworkName(Arg aArgs[])
template <> otError Dataset::Process<Cmd("networkname")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
@@ -426,7 +394,7 @@ exit:
return error;
}
otError Dataset::ProcessPanId(Arg aArgs[])
template <> otError Dataset::Process<Cmd("panid")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
@@ -447,7 +415,7 @@ exit:
return error;
}
otError Dataset::ProcessPendingTimestamp(Arg aArgs[])
template <> otError Dataset::Process<Cmd("pendingtimestamp")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
@@ -468,7 +436,7 @@ exit:
return error;
}
otError Dataset::ProcessMgmtSetCommand(Arg aArgs[])
template <> otError Dataset::Process<Cmd("mgmtsetcommand")>(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<Cmd("mgmtgetcommand")>(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<Cmd("pskc")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
@@ -839,7 +807,7 @@ exit:
return error;
}
otError Dataset::ProcessSecurityPolicy(Arg aArgs[])
template <> otError Dataset::Process<Cmd("securitypolicy")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
@@ -862,7 +830,7 @@ exit:
return error;
}
otError Dataset::ProcessSet(Arg aArgs[])
template <> otError Dataset::Process<Cmd("set")>(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<Cmd("updater")>(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<Cmd(aCommandString)> \
}
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