[cli] add cli-radio build (#6769)

Background:

In an early stage of developing a new product, developers may want to
verify the Thread related hardware functionality, for example, send,
receive, etc.  However if the product uses the posix <-> RCP mode,
it's hard to verify it before the posix daemon can run on the
host. cli-ftd and cli-mtd could be an alternative. However, if the
product uses the posix <-> RCP mode, the space of the 802.15.4 radio
chip will be very small. For example, nRF52811 doesn't have enough
space to flash cli-ftd or cli-mtd firmware. So this PR creates a new
firmware ot-cli-radio which has very limited functionality for
verifying the hardware.

Basically, the ot-cli-radio consists of openthread-radio and
libopenthread-cli-radio.a. It supports very few cli commands. The most
important command is diag. Currently, there are: diag, help, reset,
version.

Currently, the diag commands have different implementation on RCP:

- For commands like diag start, the process function
  (Diags::ProcessStart) is first called on host. Then host sends an
  SPI frame to the RCP and Diags::ProcessStart (different
  implementation) is called again on RCP.

- For commands like diag send, Diags::ProcessSend is first called on
  host.  Then host sends an SPI frame to the RCP, directly calling
  send API. And there is no Diags::ProcessSend implemented on RCP.

Let's call the implementation of Diags::Process* currently on host as
native diag commands. When we run ot-cli-radio, we should use the
native diag commands because it won't interact with a posix daemon and
it processes the diag commands through the whole process. So this PR
adds a new option OPENTHREAD_CONFIG_DIAG_NATIVE_CMDS_ON_RCP to control
whether to use the native diag implementation on RCP. When we use a
normal RCP, the option should be disabled. While when use
ot-cli-radio, the option should be enabled.
This commit is contained in:
Li Cao 2021-09-19 00:51:35 +08:00 committed by GitHub
parent ee58635945
commit 097aa4f65d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 522 additions and 205 deletions

View File

@ -37,6 +37,7 @@ AM_DISTCHECK_CONFIGURE_FLAGS = \
--enable-mtd \
--enable-ncp \
--enable-radio-only \
--enable-radio-cli \
--with-examples=simulation \
$(NULL)

View File

@ -542,6 +542,30 @@ AC_ARG_ENABLE(radio-only,
AC_MSG_RESULT(${enable_radio_only})
AM_CONDITIONAL([OPENTHREAD_ENABLE_RADIO_ONLY], [test "${enable_radio_only}" = "yes"])
#
# Radio Cli Library
#
AC_MSG_CHECKING([whether to build radio-cli library])
AC_ARG_ENABLE(radio-cli,
[AS_HELP_STRING([--enable-radio-cli], [Build radio-cli library @<:@default=no@:>@.])],
[
case "${enableval}" in
no|yes)
enable_radio_cli=${enableval}
;;
*)
AC_MSG_ERROR([Invalid value ${enable_radio_cli} for --enable-radio-cli])
;;
esac
],
[enable_radio_cli=no])
AC_MSG_RESULT(${enable_radio_cli})
AM_CONDITIONAL([OPENTHREAD_ENABLE_RADIO_CLI], [test "${enable_radio_cli}" = "yes"])
#
# whether to build executables
#

View File

@ -39,3 +39,7 @@ endif()
if(OT_MTD)
include(mtd.cmake)
endif()
if(OT_RCP)
include(radio.cmake)
endif()

View File

@ -120,9 +120,40 @@ ot_cli_mtd_SOURCES = \
$(SOURCES_COMMON) \
$(NULL)
if OPENTHREAD_ENABLE_RADIO_CLI
bin_PROGRAMS += \
ot-cli-radio \
$(NULL)
endif
ot_cli_radio_CPPFLAGS = \
$(CPPFLAGS_COMMON) \
$(NULL)
ot_cli_radio_LDADD = \
$(top_builddir)/src/cli/libopenthread-cli-radio.a \
$(top_builddir)/src/core/libopenthread-radio-cli.a \
$(LDADD_COMMON) \
$(top_builddir)/src/core/libopenthread-radio-cli.a \
$(LDADD_COMMON) \
$(NULL)
ot_cli_radio_LDFLAGS = \
$(LDFLAGS_COMMON) \
$(NULL)
ot_cli_radio_LIBTOOLFLAGS = \
$(LIBTOOLFLAGS_COMMON) \
$(NULL)
ot_cli_radio_SOURCES = \
$(SOURCES_COMMON) \
$(NULL)
if OPENTHREAD_ENABLE_LINKER_MAP
ot_cli_ftd_LDFLAGS += -Wl,-Map=ot-cli-ftd.map
ot_cli_mtd_LDFLAGS += -Wl,-Map=ot-cli-mtd.map
ot_cli_radio_LDFLAGS += -Wl,-Map=ot-cli-radio.map
endif
if OPENTHREAD_BUILD_COVERAGE

View File

@ -0,0 +1,48 @@
#
# Copyright (c) 2021, 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.
#
add_executable(ot-cli-radio
cli_uart.cpp
main.c
)
target_include_directories(ot-cli-radio PRIVATE ${COMMON_INCLUDES})
target_link_libraries(ot-cli-radio PRIVATE
openthread-cli-radio
${OT_PLATFORM_LIB}
openthread-radio-cli
${OT_PLATFORM_LIB}
openthread-cli-radio
${OT_MBEDTLS}
ot-config
)
install(TARGETS ot-cli-radio
DESTINATION bin
)

View File

@ -177,6 +177,7 @@ build_nest_common()
--enable-mtd \
--enable-ncp \
--enable-radio-only \
--enable-radio-cli \
--disable-docs \
--disable-tests \
--with-examples=simulation
@ -224,6 +225,7 @@ build_multi_radio_links()
--enable-mtd \
--enable-ncp \
--enable-radio-only \
--enable-radio-cli \
--with-examples=simulation \
--disable-docs \
--disable-tests
@ -252,6 +254,7 @@ build_multi_radio_links()
--enable-mtd \
--enable-ncp \
--enable-radio-only \
--enable-radio-cli \
--with-examples=simulation \
--disable-docs \
--disable-tests

View File

@ -42,6 +42,10 @@ build_all_features()
reset_source
"$(dirname "$0")"/cmake-build simulation -DOT_THREAD_VERSION=1.1
# Build Thread 1.1 cli-radio
reset_source
"$(dirname "$0")"/cmake-build simulation -DOT_THREAD_VERSION=1.1 -DOT_DIAGNOSTIC=ON -DOT_APP_CLI=ON -DOT_APP_NCP=OFF -DOT_APP_RCP=OFF -DOT_FTD=OFF -DOT_MTD=OFF
# Build Thread 1.2 with full features
reset_source
"$(dirname "$0")"/cmake-build simulation -DOT_OTNS=ON -DOT_SIMULATION_VIRTUAL_TIME=ON -DOT_THREAD_VERSION=1.2 -DOT_DUA=ON -DOT_MLR=ON -DOT_BACKBONE_ROUTER=ON -DOT_CSL_RECEIVER=ON

View File

@ -54,6 +54,10 @@ if(OT_MTD)
include(mtd.cmake)
endif()
if(OT_RCP)
include(radio.cmake)
endif()
set_property(SOURCE cli_joiner.cpp
APPEND PROPERTY COMPILE_DEFINITIONS "PACKAGE_VERSION=\"${OT_PACKAGE_VERSION}\""
)

View File

@ -118,6 +118,10 @@ if OPENTHREAD_ENABLE_MTD
lib_LIBRARIES += libopenthread-cli-mtd.a
endif
if OPENTHREAD_ENABLE_RADIO_CLI
lib_LIBRARIES += libopenthread-cli-radio.a
endif
CPPFLAGS_COMMON = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src \
@ -125,6 +129,13 @@ CPPFLAGS_COMMON = \
$(OPENTHREAD_TARGET_DEFINES) \
$(NULL)
libopenthread_cli_ftd_a_CPPFLAGS = \
-DOPENTHREAD_MTD=0 \
-DOPENTHREAD_FTD=1 \
-DOPENTHREAD_RADIO=0 \
$(CPPFLAGS_COMMON) \
$(NULL)
libopenthread_cli_mtd_a_CPPFLAGS = \
-DOPENTHREAD_MTD=1 \
-DOPENTHREAD_FTD=0 \
@ -132,10 +143,11 @@ libopenthread_cli_mtd_a_CPPFLAGS = \
$(CPPFLAGS_COMMON) \
$(NULL)
libopenthread_cli_ftd_a_CPPFLAGS = \
libopenthread_cli_radio_a_CPPFLAGS = \
-DOPENTHREAD_MTD=0 \
-DOPENTHREAD_FTD=1 \
-DOPENTHREAD_RADIO=0 \
-DOPENTHREAD_FTD=0 \
-DOPENTHREAD_RADIO=1 \
-DOPENTHREAD_RADIO_CLI=1 \
$(CPPFLAGS_COMMON) \
$(NULL)
@ -162,6 +174,10 @@ libopenthread_cli_mtd_a_SOURCES = \
$(SOURCES_COMMON) \
$(NULL)
libopenthread_cli_radio_a_SOURCES = \
cli.cpp \
$(NULL)
noinst_HEADERS = \
cli.hpp \
cli_coap.hpp \

View File

@ -105,6 +105,8 @@ Interpreter::Interpreter(Instance *aInstance, otCliOutputCallback aCallback, voi
, mUserCommands(nullptr)
, mUserCommandsLength(0)
, mCommandIsPending(false)
, mTimer(*aInstance, HandleTimer, this)
#if OPENTHREAD_FTD || OPENTHREAD_MTD
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
, mSntpQueryingInProgress(false)
#endif
@ -114,7 +116,6 @@ Interpreter::Interpreter(Instance *aInstance, otCliOutputCallback aCallback, voi
#if OPENTHREAD_CONFIG_TCP_ENABLE && OPENTHREAD_CONFIG_CLI_TCP_ENABLE
, mTcp(*this)
#endif
, mTimer(*aInstance, HandleTimer, this)
#if OPENTHREAD_CONFIG_COAP_API_ENABLE
, mCoap(*this)
#endif
@ -143,6 +144,7 @@ Interpreter::Interpreter(Instance *aInstance, otCliOutputCallback aCallback, voi
#if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE
, mLocateInProgress(false)
#endif
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
{
#if OPENTHREAD_FTD
otThreadSetDiscoveryRequestCallback(mInstance, &Interpreter::HandleDiscoveryRequest, this);
@ -216,6 +218,7 @@ void Interpreter::OutputEnabledDisabledStatus(bool aEnabled)
OutputLine(aEnabled ? "Enabled" : "Disabled");
}
#if OPENTHREAD_FTD || OPENTHREAD_MTD
int Interpreter::OutputIp6Address(const otIp6Address &aAddress)
{
char string[OT_IP6_ADDRESS_STRING_SIZE];
@ -268,7 +271,154 @@ void Interpreter::OutputTableSeperator(uint8_t aNumColumns, const uint8_t aWidth
OutputLine("+");
}
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
#if OPENTHREAD_CONFIG_DIAG_ENABLE
otError Interpreter::ProcessDiag(Arg aArgs[])
{
otError error;
char * args[kMaxArgs];
char output[OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE];
// all diagnostics related features are processed within diagnostics module
Arg::CopyArgsToStringArray(aArgs, args);
error = otDiagProcessCmd(mInstance, Arg::GetArgsLength(aArgs), args, output, sizeof(output));
OutputFormat("%s", output);
return error;
}
#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[])
{
otError error = OT_ERROR_NONE;
if (aArgs[0].IsEmpty())
{
OutputLine("%s", otGetVersionString());
ExitNow();
}
if (aArgs[0] == "api")
{
OutputLine("%d", OPENTHREAD_API_VERSION);
}
else
{
ExitNow(error = OT_ERROR_INVALID_COMMAND);
}
exit:
return error;
}
otError Interpreter::ProcessReset(Arg aArgs[])
{
OT_UNUSED_VARIABLE(aArgs);
otInstanceReset(mInstance);
return OT_ERROR_NONE;
}
void Interpreter::ProcessLine(char *aBuf)
{
Arg args[kMaxArgs + 1];
const Command *command;
otError error = OT_ERROR_NONE;
OT_ASSERT(aBuf != nullptr);
// 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);
#if OPENTHREAD_CONFIG_CLI_LOG_INPUT_OUTPUT_ENABLE
otLogNoteCli("Input: %s", aBuf);
#endif
SuccessOrExit(error = Utils::CmdLineParser::ParseCmd(aBuf, args, kMaxArgs));
VerifyOrExit(!args[0].IsEmpty(), mCommandIsPending = false);
#if OPENTHREAD_CONFIG_DIAG_ENABLE
if (otDiagIsEnabled(mInstance) && (args[0] != "diag"))
{
OutputLine("under diagnostics mode, execute 'diag stop' before running any other commands.");
ExitNow(error = OT_ERROR_INVALID_STATE);
}
#endif
command = Utils::LookupTable::Find(args[0].GetCString(), sCommands);
if (command != nullptr)
{
error = (this->*command->mHandler)(args + 1);
}
else
{
error = ProcessUserCommands(args);
}
exit:
if ((error != OT_ERROR_NONE) || !args[0].IsEmpty())
{
OutputResult(error);
}
else if (!mCommandIsPending)
{
OutputPrompt();
}
}
otError Interpreter::ProcessUserCommands(Arg aArgs[])
{
otError error = OT_ERROR_INVALID_COMMAND;
for (uint8_t i = 0; i < mUserCommandsLength; i++)
{
if (aArgs[0] == mUserCommands[i].mName)
{
char *args[kMaxArgs];
Arg::CopyArgsToStringArray(aArgs, args);
mUserCommands[i].mCommand(mUserCommandsContext, Arg::GetArgsLength(aArgs) - 1, args + 1);
error = OT_ERROR_NONE;
break;
}
}
return error;
}
void Interpreter::SetUserCommands(const otCliCommand *aCommands, uint8_t aLength, void *aContext)
{
mUserCommands = aCommands;
mUserCommandsLength = aLength;
mUserCommandsContext = aContext;
}
#if OPENTHREAD_FTD || OPENTHREAD_MTD
otError Interpreter::ParseEnableOrDisable(const Arg &aArg, bool &aEnable)
{
otError error = OT_ERROR_NONE;
@ -360,23 +510,6 @@ exit:
#endif // OPENTHREAD_CONFIG_PING_SENDER_ENABLE
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;
}
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
otError Interpreter::ProcessHistory(Arg aArgs[])
{
@ -3679,15 +3812,6 @@ otError Interpreter::ProcessReleaseRouterId(Arg aArgs[])
}
#endif
otError Interpreter::ProcessReset(Arg aArgs[])
{
OT_UNUSED_VARIABLE(aArgs);
otInstanceReset(mInstance);
return OT_ERROR_NONE;
}
otError Interpreter::ProcessRloc16(Arg aArgs[])
{
OT_UNUSED_VARIABLE(aArgs);
@ -4331,29 +4455,6 @@ otError Interpreter::ProcessUptime(Arg aArgs[])
}
#endif
otError Interpreter::ProcessVersion(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
if (aArgs[0].IsEmpty())
{
OutputLine("%s", otGetVersionString());
ExitNow();
}
if (aArgs[0] == "api")
{
OutputLine("%d", OPENTHREAD_API_VERSION);
}
else
{
ExitNow(error = OT_ERROR_INVALID_COMMAND);
}
exit:
return error;
}
#if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
otError Interpreter::ProcessCommissioner(Arg aArgs[])
{
@ -4725,95 +4826,6 @@ exit:
}
#endif
#if OPENTHREAD_CONFIG_DIAG_ENABLE
otError Interpreter::ProcessDiag(Arg aArgs[])
{
otError error;
char * args[kMaxArgs];
char output[OPENTHREAD_CONFIG_DIAG_OUTPUT_BUFFER_SIZE];
// all diagnostics related features are processed within diagnostics module
Arg::CopyArgsToStringArray(aArgs, args);
error = otDiagProcessCmd(mInstance, Arg::GetArgsLength(aArgs), args, output, sizeof(output));
OutputFormat("%s", output);
return error;
}
#endif
void Interpreter::ProcessLine(char *aBuf)
{
Arg args[kMaxArgs + 1];
const Command *command;
otError error = OT_ERROR_NONE;
OT_ASSERT(aBuf != nullptr);
// 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);
#if OPENTHREAD_CONFIG_CLI_LOG_INPUT_OUTPUT_ENABLE
otLogNoteCli("Input: %s", aBuf);
#endif
SuccessOrExit(error = Utils::CmdLineParser::ParseCmd(aBuf, args, kMaxArgs));
VerifyOrExit(!args[0].IsEmpty(), mCommandIsPending = false);
#if OPENTHREAD_CONFIG_DIAG_ENABLE
if (otDiagIsEnabled(mInstance) && (args[0] != "diag"))
{
OutputLine("under diagnostics mode, execute 'diag stop' before running any other commands.");
ExitNow(error = OT_ERROR_INVALID_STATE);
}
#endif
command = Utils::LookupTable::Find(args[0].GetCString(), sCommands);
if (command != nullptr)
{
error = (this->*command->mHandler)(args + 1);
}
else
{
error = ProcessUserCommands(args);
}
exit:
if ((error != OT_ERROR_NONE) || !args[0].IsEmpty())
{
OutputResult(error);
}
else if (!mCommandIsPending)
{
OutputPrompt();
}
}
otError Interpreter::ProcessUserCommands(Arg aArgs[])
{
otError error = OT_ERROR_INVALID_COMMAND;
for (uint8_t i = 0; i < mUserCommandsLength; i++)
{
if (aArgs[0] == mUserCommands[i].mName)
{
char *args[kMaxArgs];
Arg::CopyArgsToStringArray(aArgs, args);
mUserCommands[i].mCommand(mUserCommandsContext, Arg::GetArgsLength(aArgs) - 1, args + 1);
error = OT_ERROR_NONE;
break;
}
}
return error;
}
void Interpreter::OutputPrefix(const otMeshLocalPrefix &aPrefix)
{
OutputFormat("%x:%x:%x:%x::/64", (aPrefix.m8[0] << 8) | aPrefix.m8[1], (aPrefix.m8[2] << 8) | aPrefix.m8[3],
@ -5058,13 +5070,6 @@ void Interpreter::OutputChildTableEntry(uint8_t aIndentSize, const otNetworkDiag
}
#endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
void Interpreter::SetUserCommands(const otCliCommand *aCommands, uint8_t aLength, void *aContext)
{
mUserCommands = aCommands;
mUserCommandsLength = aLength;
mUserCommandsContext = aContext;
}
void Interpreter::HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo &aInfo)
{
OutputFormat("~ Discovery Request from ");
@ -5072,6 +5077,8 @@ void Interpreter::HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo &aIn
OutputLine(": version=%u,joiner=%d", aInfo.mVersion, aInfo.mIsJoiner);
}
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
int Interpreter::OutputFormat(const char *aFormat, ...)
{
int rval;

View File

@ -46,6 +46,7 @@
#include <openthread/instance.h>
#include <openthread/ip6.h>
#include <openthread/link.h>
#include <openthread/ping_sender.h>
#include <openthread/sntp.h>
#if OPENTHREAD_CONFIG_TCP_ENABLE && OPENTHREAD_CONFIG_CLI_TCP_ENABLE
#include <openthread/tcp.h>
@ -97,6 +98,7 @@ extern "C" void otCliPlatLogLine(otLogLevel, otLogRegion, const char *);
*/
class Interpreter
{
#if OPENTHREAD_FTD || OPENTHREAD_MTD
friend class Coap;
friend class CoapSecure;
friend class Commissioner;
@ -108,6 +110,7 @@ class Interpreter
friend class SrpServer;
friend class TcpExample;
friend class UdpExample;
#endif
friend void otCliPlatLogv(otLogLevel, otLogRegion, const char *, va_list);
friend void otCliPlatLogLine(otLogLevel, otLogRegion, const char *);
@ -445,9 +448,18 @@ private:
static otError ParseRoute(Arg aArgs[], otExternalRouteConfig &aConfig);
#endif
otError ProcessUserCommands(Arg aArgs[]);
// 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 ProcessUserCommands(Arg aArgs[]);
otError ProcessVersion(Arg aArgs[]);
// Process methods only on FTD/MTD
#if OPENTHREAD_FTD || OPENTHREAD_MTD
otError ProcessCcaThreshold(Arg aArgs[]);
otError ProcessBufferInfo(Arg aArgs[]);
otError ProcessChannel(Arg aArgs[]);
@ -504,9 +516,6 @@ private:
otError ProcessCsl(Arg aArgs[]);
#if OPENTHREAD_FTD
otError ProcessDelayTimerMin(Arg aArgs[]);
#endif
#if OPENTHREAD_CONFIG_DIAG_ENABLE
otError ProcessDiag(Arg aArgs[]);
#endif
otError ProcessDiscover(Arg aArgs[]);
otError ProcessDns(Arg aArgs[]);
@ -641,7 +650,6 @@ private:
#if OPENTHREAD_FTD
otError ProcessReleaseRouterId(Arg aArgs[]);
#endif
otError ProcessReset(Arg aArgs[]);
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
otError ProcessRoute(Arg aArgs[]);
otError ProcessRouteAdd(Arg aArgs[]);
@ -676,7 +684,6 @@ private:
#if OPENTHREAD_CONFIG_UPTIME_ENABLE
otError ProcessUptime(Arg aArgs[]);
#endif
otError ProcessVersion(Arg aArgs[]);
#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
otError ProcessMacFilter(Arg aArgs[]);
void PrintMacFilter(void);
@ -701,7 +708,7 @@ private:
static void HandleEnergyScanResult(otEnergyScanResult *aResult, void *aContext);
static void HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx, void *aContext);
#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
#if OPENTHREAD_FTD || (OPENTHREAD_MTD && OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE)
void HandleDiagnosticGetResponse(otError aError, const otMessage *aMessage, const Ip6::MessageInfo *aMessageInfo);
static void HandleDiagnosticGetResponse(otError aError,
otMessage * aMessage,
@ -780,6 +787,8 @@ private:
}
void HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo &aInfo);
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
#if OPENTHREAD_CONFIG_CLI_LOG_INPUT_OUTPUT_ENABLE
bool IsLogging(void) const { return mIsLogging; }
void SetIsLogging(bool aIsLogging) { mIsLogging = aIsLogging; }
@ -789,7 +798,10 @@ 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
@ -834,9 +846,11 @@ private:
#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)
@ -856,7 +870,9 @@ private:
{"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
@ -940,7 +956,9 @@ private:
#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},
@ -977,6 +995,7 @@ private:
#if OPENTHREAD_CONFIG_UPTIME_ENABLE
{"uptime", &Interpreter::ProcessUptime},
#endif
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
{"version", &Interpreter::ProcessVersion},
};
@ -989,6 +1008,10 @@ private:
uint8_t mUserCommandsLength;
void * mUserCommandsContext;
bool mCommandIsPending;
TimerMilliContext mTimer;
#if OPENTHREAD_FTD || OPENTHREAD_MTD
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
bool mSntpQueryingInProgress;
#endif
@ -1001,8 +1024,6 @@ private:
TcpExample mTcp;
#endif
TimerMilliContext mTimer;
#if OPENTHREAD_CONFIG_COAP_API_ENABLE
Coap mCoap;
#endif
@ -1030,6 +1051,7 @@ private:
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
History mHistory;
#endif
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
#if OPENTHREAD_CONFIG_CLI_LOG_INPUT_OUTPUT_ENABLE
char mOutputString[OPENTHREAD_CONFIG_CLI_LOG_INPUT_OUTPUT_LOG_STRING_SIZE];

54
src/cli/radio.cmake Normal file
View File

@ -0,0 +1,54 @@
#
# Copyright (c) 2021, 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.
#
add_library(openthread-cli-radio)
target_compile_definitions(openthread-cli-radio
PRIVATE
OPENTHREAD_RADIO=1
OPENTHREAD_RADIO_CLI=1
)
target_compile_options(openthread-cli-radio PRIVATE
${OT_CFLAGS}
)
target_include_directories(openthread-cli-radio PUBLIC ${OT_PUBLIC_INCLUDES} PRIVATE ${COMMON_INCLUDES})
target_sources(openthread-cli-radio
PRIVATE
cli.cpp
)
target_link_libraries(openthread-cli-radio
PUBLIC
openthread-radio
PRIVATE
${OT_MBEDTLS}
ot-config
)

View File

@ -230,6 +230,40 @@ set(COMMON_SOURCES
utils/srp_client_buffers.cpp
)
set(RADIO_COMMON_SOURCES
api/diags_api.cpp
api/error_api.cpp
api/instance_api.cpp
api/link_raw_api.cpp
api/logging_api.cpp
api/random_noncrypto_api.cpp
api/tasklet_api.cpp
common/error.cpp
common/instance.cpp
common/logging.cpp
common/random_manager.cpp
common/string.cpp
common/tasklet.cpp
common/timer.cpp
common/uptime.cpp
crypto/aes_ccm.cpp
crypto/aes_ecb.cpp
crypto/crypto_platform.cpp
crypto/storage.cpp
diags/factory_diags.cpp
mac/link_raw.cpp
mac/mac_frame.cpp
mac/mac_types.cpp
mac/sub_mac.cpp
mac/sub_mac_callbacks.cpp
radio/radio.cpp
radio/radio_callbacks.cpp
radio/radio_platform.cpp
thread/link_quality.cpp
utils/lookup_table.cpp
utils/parse_cmdline.cpp
)
set(OT_VENDOR_EXTENSION "" CACHE STRING "specify a C++ source file built as part of OpenThread core library")
if(OT_VENDOR_EXTENSION)
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_ENABLE_VENDOR_EXTENSION=1")
@ -246,6 +280,9 @@ endif()
if(OT_RCP)
include(radio.cmake)
if (OT_APP_CLI)
include(radio_cli.cmake)
endif()
endif()
set_property(SOURCE api/instance_api.cpp

View File

@ -42,6 +42,10 @@ if OPENTHREAD_ENABLE_RADIO_ONLY
lib_LIBRARIES += libopenthread-radio.a
endif
if OPENTHREAD_ENABLE_RADIO_CLI
lib_LIBRARIES += libopenthread-radio-cli.a
endif
CPPFLAGS_COMMON = \
-I$(top_srcdir)/include \
$(OPENTHREAD_TARGET_DEFINES) \
@ -52,6 +56,15 @@ libopenthread_radio_a_CPPFLAGS = \
-DOPENTHREAD_MTD=0 \
-DOPENTHREAD_FTD=0 \
-DOPENTHREAD_RADIO=1 \
-DOPENTHREAD_RADIO_CLI=0 \
$(NULL)
libopenthread_radio_cli_a_CPPFLAGS = \
$(CPPFLAGS_COMMON) \
-DOPENTHREAD_MTD=0 \
-DOPENTHREAD_FTD=0 \
-DOPENTHREAD_RADIO=1 \
-DOPENTHREAD_RADIO_CLI=1 \
$(NULL)
libopenthread_ftd_a_CPPFLAGS = \
@ -307,14 +320,9 @@ SOURCES_COMMON = \
utils/srp_client_buffers.cpp \
$(NULL)
EXTRA_DIST = \
common/extension_example.cpp \
$(NULL)
libopenthread_radio_a_SOURCES = \
RADIO_SOURCES_COMMON = \
api/diags_api.cpp \
api/error_api.cpp \
api/heap_api.cpp \
api/instance_api.cpp \
api/link_raw_api.cpp \
api/logging_api.cpp \
@ -346,6 +354,18 @@ libopenthread_radio_a_SOURCES = \
utils/parse_cmdline.cpp \
$(NULL)
EXTRA_DIST = \
common/extension_example.cpp \
$(NULL)
libopenthread_radio_a_SOURCES = \
$(RADIO_SOURCES_COMMON) \
$(NULL)
libopenthread_radio_cli_a_SOURCES = \
$(RADIO_SOURCES_COMMON) \
$(NULL)
libopenthread_mtd_a_SOURCES = \
$(SOURCES_COMMON) \
$(NULL)
@ -374,6 +394,10 @@ nodist_libopenthread_radio_a_SOURCES = \
vendor_extension_temp.cpp \
$(NULL)
nodist_libopenthread_radio_cli_a_SOURCES = \
vendor_extension_temp.cpp \
$(NULL)
endif # OPENTHREAD_ENABLE_VENDOR_EXTENSION
HEADERS_COMMON = \

View File

@ -190,7 +190,7 @@ inline mbedtls_ctr_drbg_context *MbedTlsContextGet(void)
} // namespace Crypto
#endif // OPENTHREAD_RADIO
#endif // !OPENTHREAD_RADIO
} // namespace Random
} // namespace ot

View File

@ -66,7 +66,7 @@ otError otPlatDiagProcess(otInstance *aInstance,
namespace ot {
namespace FactoryDiags {
#if OPENTHREAD_RADIO
#if OPENTHREAD_RADIO && !OPENTHREAD_RADIO_CLI
const struct Diags::Command Diags::sCommands[] = {
{"channel", &Diags::ProcessChannel},
@ -142,8 +142,8 @@ extern "C" void otPlatDiagAlarmFired(otInstance *aInstance)
otPlatDiagAlarmCallback(aInstance);
}
#else // OPENTHREAD_RADIO
#else // OPENTHREAD_RADIO && !OPENTHREAD_RADIO_CLI
// For OPENTHREAD_FTD, OPENTHREAD_MTD, OPENTHREAD_RADIO_CLI
const struct Diags::Command Diags::sCommands[] = {
{"channel", &Diags::ProcessChannel}, {"power", &Diags::ProcessPower}, {"radio", &Diags::ProcessRadio},
{"repeat", &Diags::ProcessRepeat}, {"send", &Diags::ProcessSend}, {"start", &Diags::ProcessStart},
@ -291,7 +291,9 @@ Error Diags::ProcessStart(uint8_t aArgsLength, char *aArgs[], char *aOutput, siz
Error error = kErrorNone;
#if OPENTHREAD_FTD || OPENTHREAD_MTD
VerifyOrExit(!Get<ThreadNetif>().IsUp(), error = kErrorInvalidState);
#endif
otPlatDiagChannelSet(mChannel);
otPlatDiagTxPowerSet(mTxPower);

View File

@ -159,7 +159,7 @@ private:
static const struct Command sCommands[];
#if !OPENTHREAD_RADIO
#if OPENTHREAD_FTD || OPENTHREAD_MTD || (OPENTHREAD_RADIO && OPENTHREAD_RADIO_CLI)
Stats mStats;
otRadioFrame *mTxPacket;

View File

@ -51,6 +51,11 @@ namespace Mac {
LinkRaw::LinkRaw(Instance &aInstance)
: InstanceLocator(aInstance)
, mReceiveChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL)
, mPanId(kPanIdBroadcast)
, mReceiveDoneCallback(nullptr)
, mTransmitDoneCallback(nullptr)
, mEnergyScanDoneCallback(nullptr)
#if OPENTHREAD_RADIO
, mSubMac(aInstance)
#elif OPENTHREAD_CONFIG_LINK_RAW_ENABLE

View File

@ -30,6 +30,7 @@ add_library(openthread-radio)
target_compile_definitions(openthread-radio PRIVATE
OPENTHREAD_RADIO=1
OPENTHREAD_RADIO_CLI=0
)
target_compile_options(openthread-radio PRIVATE
@ -39,38 +40,7 @@ target_compile_options(openthread-radio PRIVATE
target_include_directories(openthread-radio PUBLIC ${OT_PUBLIC_INCLUDES} PRIVATE ${COMMON_INCLUDES})
target_sources(openthread-radio PRIVATE
api/diags_api.cpp
api/error_api.cpp
api/instance_api.cpp
api/link_raw_api.cpp
api/logging_api.cpp
api/random_noncrypto_api.cpp
api/tasklet_api.cpp
common/error.cpp
common/instance.cpp
common/logging.cpp
common/random_manager.cpp
common/string.cpp
common/tasklet.cpp
common/timer.cpp
common/uptime.cpp
crypto/aes_ccm.cpp
crypto/aes_ecb.cpp
crypto/crypto_platform.cpp
crypto/hmac_sha256.cpp
crypto/storage.cpp
diags/factory_diags.cpp
mac/link_raw.cpp
mac/mac_frame.cpp
mac/mac_types.cpp
mac/sub_mac.cpp
mac/sub_mac_callbacks.cpp
radio/radio.cpp
radio/radio_callbacks.cpp
radio/radio_platform.cpp
thread/link_quality.cpp
utils/lookup_table.cpp
utils/parse_cmdline.cpp
${RADIO_COMMON_SOURCES}
)
if(OT_VENDOR_EXTENSION)

View File

@ -61,20 +61,20 @@ void Radio::Callbacks::HandleEnergyScanDone(int8_t aMaxRssi)
#if OPENTHREAD_CONFIG_DIAG_ENABLE
void Radio::Callbacks::HandleDiagsReceiveDone(Mac::RxFrame *aFrame, Error aError)
{
#if OPENTHREAD_RADIO
#if OPENTHREAD_RADIO && !OPENTHREAD_RADIO_CLI
// Pass it to notify OpenThread `Diags` module on host side.
HandleReceiveDone(aFrame, aError);
#else
#else // For OPENTHREAD_FTD, OPENTHREAD_MTD and OPENTHREAD_RADIO(CLI)
Get<FactoryDiags::Diags>().ReceiveDone(aFrame, aError);
#endif
}
void Radio::Callbacks::HandleDiagsTransmitDone(Mac::TxFrame &aFrame, Error aError)
{
#if OPENTHREAD_RADIO
#if OPENTHREAD_RADIO && !OPENTHREAD_RADIO_CLI
// Pass it to notify OpenThread `Diags` module on host side.
HandleTransmitDone(aFrame, nullptr, aError);
#else
#else // For OPENTHREAD_FTD, OPENTHREAD_MTD and OPENTHREAD_RADIO(CLI)
OT_UNUSED_VARIABLE(aFrame);
Get<FactoryDiags::Diags>().TransmitDone(aError);
#endif

54
src/core/radio_cli.cmake Normal file
View File

@ -0,0 +1,54 @@
#
# Copyright (c) 2020, 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.
#
add_library(openthread-radio-cli)
target_compile_definitions(openthread-radio-cli PRIVATE
OPENTHREAD_RADIO=1
OPENTHREAD_RADIO_CLI=1
)
target_compile_options(openthread-radio-cli PRIVATE
${OT_CFLAGS}
)
target_include_directories(openthread-radio-cli PUBLIC ${OT_PUBLIC_INCLUDES} PRIVATE ${COMMON_INCLUDES})
target_sources(openthread-radio-cli PRIVATE
${RADIO_COMMON_SOURCES}
)
if(OT_VENDOR_EXTENSION)
target_sources(openthread-radio-cli PRIVATE ${OT_VENDOR_EXTENSION})
endif()
target_link_libraries(openthread-radio-cli
PRIVATE
${OT_MBEDTLS}
ot-config
)

View File

@ -79,6 +79,7 @@ libopenthread_ncp_ftd_a_CPPFLAGS = \
libopenthread_rcp_a_CPPFLAGS = \
-DOPENTHREAD_RADIO=1 \
-DOPENTHREAD_RADIO_CLI=0 \
-DOPENTHREAD_FTD=0 \
-DOPENTHREAD_MTD=0 \
-DOPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=0 \

View File

@ -30,6 +30,7 @@ add_library(openthread-rcp)
target_compile_definitions(openthread-rcp PRIVATE
OPENTHREAD_RADIO=1
OPENTHREAD_RADIO_CLI=0
OPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1
)

View File

@ -39,6 +39,10 @@
#define OPENTHREAD_RADIO 0
#endif
#ifndef OPENTHREAD_RADIO
#define OPENTHREAD_RADIO_CLI 0
#endif
/**
* @def OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
*

View File

@ -53,6 +53,7 @@ AM_CPPFLAGS = \
-DOPENTHREAD_FTD=1 \
-DOPENTHREAD_MTD=0 \
-DOPENTHREAD_RADIO=0 \
-DOPENTHREAD_RADIO_CLI=0 \
-DOPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=1 \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src \