Skip to content

Commit

Permalink
[cli] simplify argument processing (openthread#6767)
Browse files Browse the repository at this point in the history
This commit changes `ParseCmd()` such that as `aArgs` array entries
are populated with parsed arguments from a command line string, the
remaining unused `aArgs` entries in the array are marked as "empty".
We also ensure that the `aArgs[]` array always end with an "empty"
`Arg` which  indicates end of the list (this is similar to how C
string ends with a null '\0' character). This commit also changes
different methods of `Arg` class (`Arg::ParseAs{Type}()` or overload
of operator `==`, etc) to check and handle when `Arg` is marked
as "empty".

These changes help simplify how the arguments are processed in CLI
modules. In `Cli::Process{Command}()` methods we can just pass the
`aArgs[]` array and do not need to pass a separate args length
parameter. In many cases the args length checks can be removed since
it will be checked from `ParseAs{Type}()` call.
  • Loading branch information
abtink authored Jun 29, 2021
1 parent 57d072d commit 0a6a0b6
Show file tree
Hide file tree
Showing 23 changed files with 1,286 additions and 1,416 deletions.
1,004 changes: 439 additions & 565 deletions src/cli/cli.cpp

Large diffs are not rendered by default.

278 changes: 131 additions & 147 deletions src/cli/cli.hpp

Large diffs are not rendered by default.

71 changes: 33 additions & 38 deletions src/cli/cli_coap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,18 +145,16 @@ void Coap::PrintPayload(otMessage *aMessage) const
}

#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
otError Coap::ProcessCancel(uint8_t aArgsLength, Arg aArgs[])
otError Coap::ProcessCancel(Arg aArgs[])
{
OT_UNUSED_VARIABLE(aArgsLength);
OT_UNUSED_VARIABLE(aArgs);

return CancelResourceSubscription();
}
#endif

otError Coap::ProcessHelp(uint8_t aArgsLength, Arg aArgs[])
otError Coap::ProcessHelp(Arg aArgs[])
{
OT_UNUSED_VARIABLE(aArgsLength);
OT_UNUSED_VARIABLE(aArgs);

for (const Command &command : sCommands)
Expand All @@ -167,11 +165,11 @@ otError Coap::ProcessHelp(uint8_t aArgsLength, Arg aArgs[])
return OT_ERROR_NONE;
}

otError Coap::ProcessResource(uint8_t aArgsLength, Arg aArgs[])
otError Coap::ProcessResource(Arg aArgs[])
{
otError error = OT_ERROR_NONE;

if (aArgsLength > 0)
if (!aArgs[0].IsEmpty())
{
VerifyOrExit(aArgs[0].GetLength() < kMaxUriLength, error = OT_ERROR_INVALID_ARGS);

Expand All @@ -183,7 +181,7 @@ otError Coap::ProcessResource(uint8_t aArgsLength, Arg aArgs[])
mResource.mReceiveHook = &Coap::BlockwiseReceiveHook;
mResource.mTransmitHook = &Coap::BlockwiseTransmitHook;

if (aArgsLength > 1)
if (!aArgs[1].IsEmpty())
{
SuccessOrExit(error = aArgs[1].ParseAsUint32(mBlockCount));
}
Expand All @@ -206,15 +204,15 @@ otError Coap::ProcessResource(uint8_t aArgsLength, Arg aArgs[])
return error;
}

otError Coap::ProcessSet(uint8_t aArgsLength, Arg aArgs[])
otError Coap::ProcessSet(Arg aArgs[])
{
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
otMessage * notificationMessage = nullptr;
otMessageInfo messageInfo;
#endif
otError error = OT_ERROR_NONE;

if (aArgsLength > 0)
if (!aArgs[0].IsEmpty())
{
VerifyOrExit(aArgs[0].GetLength() < sizeof(mResourceContent), error = OT_ERROR_INVALID_ARGS);
strncpy(mResourceContent, aArgs[0].GetCString(), sizeof(mResourceContent));
Expand Down Expand Up @@ -268,17 +266,15 @@ otError Coap::ProcessSet(uint8_t aArgsLength, Arg aArgs[])
return error;
}

otError Coap::ProcessStart(uint8_t aArgsLength, Arg aArgs[])
otError Coap::ProcessStart(Arg aArgs[])
{
OT_UNUSED_VARIABLE(aArgsLength);
OT_UNUSED_VARIABLE(aArgs);

return otCoapStart(mInterpreter.mInstance, OT_DEFAULT_COAP_PORT);
}

otError Coap::ProcessStop(uint8_t aArgsLength, Arg aArgs[])
otError Coap::ProcessStop(Arg aArgs[])
{
OT_UNUSED_VARIABLE(aArgsLength);
OT_UNUSED_VARIABLE(aArgs);

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
Expand All @@ -290,14 +286,12 @@ otError Coap::ProcessStop(uint8_t aArgsLength, Arg aArgs[])
return otCoapStop(mInterpreter.mInstance);
}

otError Coap::ProcessParameters(uint8_t aArgsLength, Arg aArgs[])
otError Coap::ProcessParameters(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
bool * defaultTxParameters;
otCoapTxParameters *txParameters;

VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);

if (aArgs[0] == "request")
{
txParameters = &mRequestTxParameters;
Expand All @@ -313,16 +307,14 @@ otError Coap::ProcessParameters(uint8_t aArgsLength, Arg aArgs[])
ExitNow(error = OT_ERROR_INVALID_ARGS);
}

if (aArgsLength > 1)
if (!aArgs[1].IsEmpty())
{
if (aArgs[1] == "default")
{
*defaultTxParameters = true;
}
else
{
VerifyOrExit(aArgsLength >= 5, error = OT_ERROR_INVALID_ARGS);

SuccessOrExit(error = aArgs[1].ParseAsUint32(txParameters->mAckTimeout));
SuccessOrExit(error = aArgs[2].ParseAsUint8(txParameters->mAckRandomFactorNumerator));
SuccessOrExit(error = aArgs[3].ParseAsUint8(txParameters->mAckRandomFactorDenominator));
Expand Down Expand Up @@ -352,37 +344,37 @@ otError Coap::ProcessParameters(uint8_t aArgsLength, Arg aArgs[])
return error;
}

otError Coap::ProcessGet(uint8_t aArgsLength, Arg aArgs[])
otError Coap::ProcessGet(Arg aArgs[])
{
return ProcessRequest(aArgsLength, aArgs, OT_COAP_CODE_GET);
return ProcessRequest(aArgs, OT_COAP_CODE_GET);
}

otError Coap::ProcessPost(uint8_t aArgsLength, Arg aArgs[])
otError Coap::ProcessPost(Arg aArgs[])
{
return ProcessRequest(aArgsLength, aArgs, OT_COAP_CODE_POST);
return ProcessRequest(aArgs, OT_COAP_CODE_POST);
}

otError Coap::ProcessPut(uint8_t aArgsLength, Arg aArgs[])
otError Coap::ProcessPut(Arg aArgs[])
{
return ProcessRequest(aArgsLength, aArgs, OT_COAP_CODE_PUT);
return ProcessRequest(aArgs, OT_COAP_CODE_PUT);
}

otError Coap::ProcessDelete(uint8_t aArgsLength, Arg aArgs[])
otError Coap::ProcessDelete(Arg aArgs[])
{
return ProcessRequest(aArgsLength, aArgs, OT_COAP_CODE_DELETE);
return ProcessRequest(aArgs, OT_COAP_CODE_DELETE);
}

#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
otError Coap::ProcessObserve(uint8_t aArgsLength, Arg aArgs[])
otError Coap::ProcessObserve(Arg aArgs[])
{
return ProcessRequest(aArgsLength, aArgs, OT_COAP_CODE_GET, /* aCoapObserve */ true);
return ProcessRequest(aArgs, OT_COAP_CODE_GET, /* aCoapObserve */ true);
}
#endif

#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
otError Coap::ProcessRequest(uint8_t aArgsLength, Arg aArgs[], otCoapCode aCoapCode, bool aCoapObserve)
otError Coap::ProcessRequest(Arg aArgs[], otCoapCode aCoapCode, bool aCoapObserve)
#else
otError Coap::ProcessRequest(uint8_t aArgsLength, Arg aArgs[], otCoapCode aCoapCode)
otError Coap::ProcessRequest(Arg aArgs[], otCoapCode aCoapCode)
#endif
{
otError error = OT_ERROR_NONE;
Expand All @@ -407,15 +399,14 @@ otError Coap::ProcessRequest(uint8_t aArgsLength, Arg aArgs[], otCoapCode aCoapC
}
#endif

VerifyOrExit(aArgsLength > 1, error = OT_ERROR_INVALID_ARGS);

SuccessOrExit(error = aArgs[0].ParseAsIp6Address(coapDestinationIp));

VerifyOrExit(!aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(aArgs[1].GetLength() < kMaxUriLength, error = OT_ERROR_INVALID_ARGS);
strncpy(coapUri, aArgs[1].GetCString(), sizeof(coapUri) - 1);

// CoAP-Type
if (aArgsLength > 2)
if (!aArgs[2].IsEmpty())
{
if (aArgs[2] == "con")
{
Expand Down Expand Up @@ -504,7 +495,7 @@ otError Coap::ProcessRequest(uint8_t aArgsLength, Arg aArgs[], otCoapCode aCoapC
}
#endif

if (aArgsLength > 3)
if (!aArgs[3].IsEmpty())
{
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
if (coapBlock)
Expand Down Expand Up @@ -585,17 +576,21 @@ otError Coap::ProcessRequest(uint8_t aArgsLength, Arg aArgs[], otCoapCode aCoapC
return error;
}

otError Coap::Process(uint8_t aArgsLength, Arg aArgs[])
otError Coap::Process(Arg aArgs[])
{
otError error = OT_ERROR_INVALID_ARGS;
const Command *command;

VerifyOrExit(aArgsLength != 0, IgnoreError(ProcessHelp(0, nullptr)));
if (aArgs[0].IsEmpty())
{
IgnoreError(ProcessHelp(aArgs));
ExitNow();
}

command = Utils::LookupTable::Find(aArgs[0].GetCString(), sCommands);
VerifyOrExit(command != nullptr, error = OT_ERROR_INVALID_COMMAND);

error = (this->*command->mHandler)(aArgsLength - 1, aArgs + 1);
error = (this->*command->mHandler)(aArgs + 1);

exit:
return error;
Expand Down
33 changes: 16 additions & 17 deletions src/cli/cli_coap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,10 @@ class Coap
/**
* This method interprets a list of CLI arguments.
*
* @param[in] aArgsLength The number of elements in @p aArgs.
* @param[in] aArgs An array of command line arguments.
*
*/
otError Process(uint8_t aArgsLength, Arg aArgs[]);
otError Process(Arg aArgs[]);

private:
enum
Expand All @@ -84,7 +83,7 @@ class Coap
struct Command
{
const char *mName;
otError (Coap::*mHandler)(uint8_t aArgsLength, Arg aArgs[]);
otError (Coap::*mHandler)(Arg aArgs[]);
};

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
Expand All @@ -102,27 +101,27 @@ class Coap

void PrintPayload(otMessage *aMessage) const;

otError ProcessHelp(uint8_t aArgsLength, Arg aArgs[]);
otError ProcessHelp(Arg aArgs[]);
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
otError ProcessCancel(uint8_t aArgsLength, Arg aArgs[]);
otError ProcessCancel(Arg aArgs[]);
#endif
otError ProcessDelete(uint8_t aArgsLength, Arg aArgs[]);
otError ProcessGet(uint8_t aArgsLength, Arg aArgs[]);
otError ProcessDelete(Arg aArgs[]);
otError ProcessGet(Arg aArgs[]);
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
otError ProcessObserve(uint8_t aArgsLength, Arg aArgs[]);
otError ProcessObserve(Arg aArgs[]);
#endif
otError ProcessParameters(uint8_t aArgsLength, Arg aArgs[]);
otError ProcessPost(uint8_t aArgsLength, Arg aArgs[]);
otError ProcessPut(uint8_t aArgsLength, Arg aArgs[]);
otError ProcessResource(uint8_t aArgsLength, Arg aArgs[]);
otError ProcessSet(uint8_t aArgsLength, Arg aArgs[]);
otError ProcessStart(uint8_t aArgsLength, Arg aArgs[]);
otError ProcessStop(uint8_t aArgsLength, Arg aArgs[]);
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(uint8_t aArgsLength, Arg aArgs[], otCoapCode aCoapCode, bool aCoapObserve = false);
otError ProcessRequest(Arg aArgs[], otCoapCode aCoapCode, bool aCoapObserve = false);
#else
otError ProcessRequest(uint8_t aArgsLength, Arg aArgs[], otCoapCode aCoapCode);
otError ProcessRequest(Arg aArgs[], otCoapCode aCoapCode);
#endif

static void HandleRequest(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
Expand Down
Loading

0 comments on commit 0a6a0b6

Please sign in to comment.