Skip to content

Commit

Permalink
[cli] add debug command (openthread#9587)
Browse files Browse the repository at this point in the history
This commit adds cli `debug` command. This command is specifically
designed for testing and debugging purposes. It executes a series of
CLI commands to gather information about the device and thread
network.
  • Loading branch information
abtink authored Dec 8, 2023
1 parent 70128e0 commit acd1602
Show file tree
Hide file tree
Showing 4 changed files with 229 additions and 10 deletions.
47 changes: 47 additions & 0 deletions src/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Done
- [counters](#counters)
- [csl](#csl)
- [dataset](README_DATASET.md)
- [debug](#debug)
- [delaytimermin](#delaytimermin)
- [detach](#detach)
- [deviceprops](#deviceprops)
Expand Down Expand Up @@ -1049,6 +1050,52 @@ Set time sync parameters
Done
```
### debug
Executes a series of CLI commands to gather information about the device and thread network. This is intended for debugging.
The output will display each executed CLI command preceded by "\$", followed by the corresponding command's generated output.
The generated output encompasses the following information:
- Version
- Current state
- RLOC16, extended MAC address
- Unicast and multicast IPv6 address list
- Channel
- PAN ID and extended PAN ID
- Network Data
- Partition ID
- Leader Data
If the device is operating as FTD:
- Child and neighbor table
- Router table and next hop Info
- Address cache table
- Registered MTD child IPv6 address
- Device properties
If the device supports and acts as an SRP client:
- SRP client state
- SRP client services and host info
If the device supports and acts as an SRP sever:
- SRP server state and address mode
- SRP server registered hosts and services
If the device supports TREL:
- TREL status and peer table
If the device supports and acts as a border router:
- BR state
- BR prefixes (OMR, on-link, NAT64)
- Discovered prefix table
### delaytimermin
Get the minimal delay timer (in seconds).
Expand Down
156 changes: 146 additions & 10 deletions src/cli/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ Interpreter::Interpreter(Instance *aInstance, otCliOutputCallback aCallback, voi
: OutputImplementer(aCallback, aContext)
, Output(aInstance, *this)
, mCommandIsPending(false)
, mInternalDebugCommand(false)
, mTimer(*aInstance, HandleTimer, this)
#if OPENTHREAD_FTD || OPENTHREAD_MTD
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
Expand Down Expand Up @@ -166,6 +167,16 @@ Interpreter::Interpreter(Instance *aInstance, otCliOutputCallback aCallback, voi

void Interpreter::OutputResult(otError aError)
{
if (mInternalDebugCommand)
{
if (aError != OT_ERROR_NONE)
{
OutputLine("Error %u: %s", aError, otThreadErrorToString(aError));
}

ExitNow();
}

OT_ASSERT(mCommandIsPending);

VerifyOrExit(aError != OT_ERROR_PENDING);
Expand Down Expand Up @@ -314,24 +325,30 @@ void Interpreter::ProcessLine(char *aBuf)

OT_ASSERT(aBuf != nullptr);

// Ignore the command if another command is pending.
VerifyOrExit(!mCommandIsPending, args[0].Clear());
mCommandIsPending = true;
if (!mInternalDebugCommand)
{
// Ignore the command if another command is pending.
VerifyOrExit(!mCommandIsPending, args[0].Clear());
mCommandIsPending = true;

VerifyOrExit(StringLength(aBuf, kMaxLineLength) <= kMaxLineLength - 1, error = OT_ERROR_PARSE);
VerifyOrExit(StringLength(aBuf, kMaxLineLength) <= kMaxLineLength - 1, error = OT_ERROR_PARSE);
}

SuccessOrExit(error = Utils::CmdLineParser::ParseCmd(aBuf, args, kMaxArgs));
VerifyOrExit(!args[0].IsEmpty(), mCommandIsPending = false);

LogInput(args);
if (!mInternalDebugCommand)
{
LogInput(args);

#if OPENTHREAD_CONFIG_DIAG_ENABLE
if (otDiagIsEnabled(GetInstancePtr()) && (args[0] != "diag") && (args[0] != "factoryreset"))
{
OutputLine("under diagnostics mode, execute 'diag stop' before running any other commands.");
ExitNow(error = OT_ERROR_INVALID_STATE);
}
if (otDiagIsEnabled(GetInstancePtr()) && (args[0] != "diag") && (args[0] != "factoryreset"))
{
OutputLine("under diagnostics mode, execute 'diag stop' before running any other commands.");
ExitNow(error = OT_ERROR_INVALID_STATE);
}
#endif
}

error = ProcessCommand(args);

Expand Down Expand Up @@ -7243,6 +7260,124 @@ template <> otError Interpreter::Process<Cmd("txpower")>(Arg aArgs[])
return error;
}

/**
* @cli debug
* @par
* Executes a series of CLI commands to gather information about the device and thread network. This is intended for
* debugging.
* The output will display each executed CLI command preceded by `$`, followed by the corresponding command's
* generated output.
* The generated output encompasses the following information:
* - Version
* - Current state
* - RLOC16, extended MAC address
* - Unicast and multicast IPv6 address list
* - Channel
* - PAN ID and extended PAN ID
* - Network Data
* - Partition ID
* - Leader Data
* @par
* If the device is operating as FTD:
* - Child and neighbor table
* - Router table and next hop info
* - Address cache table
* - Registered MTD child IPv6 address
* - Device properties
* @par
* If the device supports and acts as an SRP client:
* - SRP client state
* - SRP client services and host info
* @par
* If the device supports and acts as an SRP sever:
* - SRP server state and address mode
* - SRP server registered hosts and services
* @par
* If the device supports TREL:
* - TREL status and peer table
* @par
* If the device supports and acts as a border router:
* - BR state
* - BR prefixes (OMR, on-link, NAT64)
* - Discovered prefix table
*/
template <> otError Interpreter::Process<Cmd("debug")>(Arg aArgs[])
{
static constexpr uint16_t kMaxDebugCommandSize = 30;

static const char *const kDebugCommands[] = {
"version",
"state",
"rloc16",
"extaddr",
"ipaddrs",
"ipmaddrs",
"channel",
"panid",
"extpanid",
"netdata show",
"netdata show -x",
"partitionid",
"leaderdata",
#if OPENTHREAD_FTD
"child table",
"childip",
"neighbor table",
"router table",
"nexthop",
"eidcache",
#if OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE
"deviceprops",
#endif
#endif // OPENTHREAD_FTD
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
"srp client state",
"srp client host",
"srp client service",
"srp client server",
#endif
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
"srp server state",
"srp server addrmode",
"srp server host",
"srp server service",
#endif
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
"trel",
"trel peers",
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
"br state",
"br omrprefix",
"br onlinkprefix",
"br prefixtable",
#if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
"br nat64prefix",
#endif
#endif
"bufferinfo",
};

char commandString[kMaxDebugCommandSize];

OT_UNUSED_VARIABLE(aArgs);

mInternalDebugCommand = true;

for (const char *debugCommand : kDebugCommands)
{
strncpy(commandString, debugCommand, sizeof(commandString) - 1);
commandString[sizeof(commandString) - 1] = '\0';

OutputLine("$ %s", commandString);
ProcessLine(commandString);
}

mInternalDebugCommand = false;

return OT_ERROR_NONE;
}

#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE && OPENTHREAD_CONFIG_CLI_BLE_SECURE_ENABLE
template <> otError Interpreter::Process<Cmd("tcat")>(Arg aArgs[]) { return mTcat.Process(aArgs); }
#endif
Expand Down Expand Up @@ -8345,6 +8480,7 @@ otError Interpreter::ProcessCommand(Arg aArgs[])
CmdEntry("csl"),
#endif
CmdEntry("dataset"),
CmdEntry("debug"),
#if OPENTHREAD_FTD
CmdEntry("delaytimermin"),
#endif
Expand Down
1 change: 1 addition & 0 deletions src/cli/cli.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,7 @@ class Interpreter : public OutputImplementer, public Output

UserCommandsEntry mUserCommands[kMaxUserCommandEntries];
bool mCommandIsPending;
bool mInternalDebugCommand;

TimerMilliContext mTimer;

Expand Down
35 changes: 35 additions & 0 deletions tests/scripts/expect/cli-debug.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/expect -f
#
# Copyright (c) 2023, The OpenThread Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of the copyright holder nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#

source "tests/scripts/expect/_common.exp"

spawn_node 1

send "debug\n"
expect_line "Done"

0 comments on commit acd1602

Please sign in to comment.