mirror of
https://github.com/espressif/openthread.git
synced 2026-07-30 15:47:46 +00:00
[cli] move a few static util methods to Cli::Utils class (#10138)
This commit moves a few static util methods from the `Interpreter` class to the `Cli::Utils` class. Since the `Interpreter` class and other classes for cli components inherit the `Cli::Utils`, they can still access these methods. Putting these methods in utils class is more intuitive. This change also makes other cli classes less dependent on the `Interpreter` class.
This commit is contained in:
-264
@@ -207,35 +207,6 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
const char *Interpreter::LinkModeToString(const otLinkModeConfig &aLinkMode, char (&aStringBuffer)[kLinkModeStringSize])
|
||||
{
|
||||
char *flagsPtr = &aStringBuffer[0];
|
||||
|
||||
if (aLinkMode.mRxOnWhenIdle)
|
||||
{
|
||||
*flagsPtr++ = 'r';
|
||||
}
|
||||
|
||||
if (aLinkMode.mDeviceType)
|
||||
{
|
||||
*flagsPtr++ = 'd';
|
||||
}
|
||||
|
||||
if (aLinkMode.mNetworkData)
|
||||
{
|
||||
*flagsPtr++ = 'n';
|
||||
}
|
||||
|
||||
if (flagsPtr == &aStringBuffer[0])
|
||||
{
|
||||
*flagsPtr++ = '-';
|
||||
}
|
||||
|
||||
*flagsPtr = '\0';
|
||||
|
||||
return aStringBuffer;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_DIAG_ENABLE
|
||||
template <> otError Interpreter::Process<Cmd("diag")>(Arg aArgs[])
|
||||
{
|
||||
@@ -416,101 +387,6 @@ otError Interpreter::SetUserCommands(const otCliCommand *aCommands, uint8_t aLen
|
||||
|
||||
#if OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||
|
||||
otError Interpreter::ParseJoinerDiscerner(Arg &aArg, otJoinerDiscerner &aDiscerner)
|
||||
{
|
||||
otError error;
|
||||
char *separator;
|
||||
|
||||
VerifyOrExit(!aArg.IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
separator = strstr(aArg.GetCString(), "/");
|
||||
|
||||
VerifyOrExit(separator != nullptr, error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
SuccessOrExit(error = ot::Utils::CmdLineParser::ParseAsUint8(separator + 1, aDiscerner.mLength));
|
||||
VerifyOrExit(aDiscerner.mLength > 0 && aDiscerner.mLength <= 64, error = OT_ERROR_INVALID_ARGS);
|
||||
*separator = '\0';
|
||||
error = aArg.ParseAsUint64(aDiscerner.mValue);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Interpreter::ParsePreference(const Arg &aArg, otRoutePreference &aPreference)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
if (aArg == "high")
|
||||
{
|
||||
aPreference = OT_ROUTE_PREFERENCE_HIGH;
|
||||
}
|
||||
else if (aArg == "med")
|
||||
{
|
||||
aPreference = OT_ROUTE_PREFERENCE_MED;
|
||||
}
|
||||
else if (aArg == "low")
|
||||
{
|
||||
aPreference = OT_ROUTE_PREFERENCE_LOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = OT_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
const char *Interpreter::PreferenceToString(signed int aPreference)
|
||||
{
|
||||
const char *str = "";
|
||||
|
||||
switch (aPreference)
|
||||
{
|
||||
case OT_ROUTE_PREFERENCE_LOW:
|
||||
str = "low";
|
||||
break;
|
||||
|
||||
case OT_ROUTE_PREFERENCE_MED:
|
||||
str = "med";
|
||||
break;
|
||||
|
||||
case OT_ROUTE_PREFERENCE_HIGH:
|
||||
str = "high";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
otError Interpreter::ParseToIp6Address(otInstance *aInstance,
|
||||
const Arg &aArg,
|
||||
otIp6Address &aAddress,
|
||||
bool &aSynthesized)
|
||||
{
|
||||
Error error = OT_ERROR_NONE;
|
||||
|
||||
VerifyOrExit(!aArg.IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
error = aArg.ParseAsIp6Address(aAddress);
|
||||
aSynthesized = false;
|
||||
|
||||
if (error != OT_ERROR_NONE)
|
||||
{
|
||||
// It might be an IPv4 address, let's have a try.
|
||||
otIp4Address ip4Address;
|
||||
|
||||
// Do not touch the error value if we failed to parse it as an IPv4 address.
|
||||
SuccessOrExit(aArg.ParseAsIp4Address(ip4Address));
|
||||
SuccessOrExit(error = otNat64SynthesizeIp6Address(aInstance, &ip4Address, &aAddress));
|
||||
aSynthesized = true;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
template <> otError Interpreter::Process<Cmd("history")>(Arg aArgs[]) { return mHistory.Process(aArgs); }
|
||||
#endif
|
||||
@@ -3277,23 +3153,6 @@ template <> otError Interpreter::Process<Cmd("instanceid")>(Arg aArgs[])
|
||||
return error;
|
||||
}
|
||||
|
||||
const char *Interpreter::AddressOriginToString(uint8_t aOrigin)
|
||||
{
|
||||
static const char *const kOriginStrings[4] = {
|
||||
"thread", // 0, OT_ADDRESS_ORIGIN_THREAD
|
||||
"slaac", // 1, OT_ADDRESS_ORIGIN_SLAAC
|
||||
"dhcp6", // 2, OT_ADDRESS_ORIGIN_DHCPV6
|
||||
"manual", // 3, OT_ADDRESS_ORIGIN_MANUAL
|
||||
};
|
||||
|
||||
static_assert(0 == OT_ADDRESS_ORIGIN_THREAD, "OT_ADDRESS_ORIGIN_THREAD value is incorrect");
|
||||
static_assert(1 == OT_ADDRESS_ORIGIN_SLAAC, "OT_ADDRESS_ORIGIN_SLAAC value is incorrect");
|
||||
static_assert(2 == OT_ADDRESS_ORIGIN_DHCPV6, "OT_ADDRESS_ORIGIN_DHCPV6 value is incorrect");
|
||||
static_assert(3 == OT_ADDRESS_ORIGIN_MANUAL, "OT_ADDRESS_ORIGIN_MANUAL value is incorrect");
|
||||
|
||||
return Stringify(aOrigin, kOriginStrings);
|
||||
}
|
||||
|
||||
template <> otError Interpreter::Process<Cmd("ipaddr")>(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
@@ -5853,80 +5712,6 @@ void Interpreter::HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx)
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
|
||||
otError Interpreter::ParsePrefix(Arg aArgs[], otBorderRouterConfig &aConfig)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
ClearAllBytes(aConfig);
|
||||
|
||||
SuccessOrExit(error = aArgs[0].ParseAsIp6Prefix(aConfig.mPrefix));
|
||||
aArgs++;
|
||||
|
||||
for (; !aArgs->IsEmpty(); aArgs++)
|
||||
{
|
||||
otRoutePreference preference;
|
||||
|
||||
if (ParsePreference(*aArgs, preference) == OT_ERROR_NONE)
|
||||
{
|
||||
aConfig.mPreference = preference;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (char *arg = aArgs->GetCString(); *arg != '\0'; arg++)
|
||||
{
|
||||
switch (*arg)
|
||||
{
|
||||
case 'p':
|
||||
aConfig.mPreferred = true;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
aConfig.mSlaac = true;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
aConfig.mDhcp = true;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
aConfig.mConfigure = true;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
aConfig.mDefaultRoute = true;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
aConfig.mOnMesh = true;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
aConfig.mStable = true;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
aConfig.mNdDns = true;
|
||||
break;
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
case 'D':
|
||||
aConfig.mDp = true;
|
||||
break;
|
||||
#endif
|
||||
case '-':
|
||||
break;
|
||||
|
||||
default:
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError Interpreter::Process<Cmd("prefix")>(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
@@ -6280,55 +6065,6 @@ template <> otError Interpreter::Process<Cmd("rloc16")>(Arg aArgs[])
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
|
||||
otError Interpreter::ParseRoute(Arg aArgs[], otExternalRouteConfig &aConfig)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
ClearAllBytes(aConfig);
|
||||
|
||||
SuccessOrExit(error = aArgs[0].ParseAsIp6Prefix(aConfig.mPrefix));
|
||||
aArgs++;
|
||||
|
||||
for (; !aArgs->IsEmpty(); aArgs++)
|
||||
{
|
||||
otRoutePreference preference;
|
||||
|
||||
if (ParsePreference(*aArgs, preference) == OT_ERROR_NONE)
|
||||
{
|
||||
aConfig.mPreference = preference;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (char *arg = aArgs->GetCString(); *arg != '\0'; arg++)
|
||||
{
|
||||
switch (*arg)
|
||||
{
|
||||
case 's':
|
||||
aConfig.mStable = true;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
aConfig.mNat64 = true;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
aConfig.mAdvPio = true;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
break;
|
||||
|
||||
default:
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError Interpreter::Process<Cmd("route")>(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
@@ -191,76 +191,6 @@ public:
|
||||
*/
|
||||
otError SetUserCommands(const otCliCommand *aCommands, uint8_t aLength, void *aContext);
|
||||
|
||||
static constexpr uint8_t kLinkModeStringSize = sizeof("rdn"); ///< Size of string buffer for a MLE Link Mode.
|
||||
|
||||
/**
|
||||
* Converts a given MLE Link Mode to flag string.
|
||||
*
|
||||
* The characters 'r', 'd', and 'n' are respectively used for `mRxOnWhenIdle`, `mDeviceType` and `mNetworkData`
|
||||
* flags. If all flags are `false`, then "-" is returned.
|
||||
*
|
||||
* @param[in] aLinkMode The MLE Link Mode to convert.
|
||||
* @param[out] aStringBuffer A reference to an string array to place the string.
|
||||
*
|
||||
* @returns A pointer @p aStringBuffer which contains the converted string.
|
||||
*
|
||||
*/
|
||||
static const char *LinkModeToString(const otLinkModeConfig &aLinkMode, char (&aStringBuffer)[kLinkModeStringSize]);
|
||||
|
||||
/**
|
||||
* Converts an IPv6 address origin `OT_ADDRESS_ORIGIN_*` value to human-readable string.
|
||||
*
|
||||
* @param[in] aOrigin The IPv6 address origin to convert.
|
||||
*
|
||||
* @returns A human-readable string representation of @p aOrigin.
|
||||
*
|
||||
*/
|
||||
static const char *AddressOriginToString(uint8_t aOrigin);
|
||||
|
||||
/**
|
||||
* Parses a given argument string as a route preference comparing it against "high", "med", or
|
||||
* "low".
|
||||
*
|
||||
* @param[in] aArg The argument string to parse.
|
||||
* @param[out] aPreference Reference to a `otRoutePreference` to return the parsed preference.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully parsed @p aArg and updated @p aPreference.
|
||||
* @retval OT_ERROR_INVALID_ARG @p aArg is not a valid preference string "high", "med", or "low".
|
||||
*
|
||||
*/
|
||||
static otError ParsePreference(const Arg &aArg, otRoutePreference &aPreference);
|
||||
|
||||
/**
|
||||
* Converts a route preference value to human-readable string.
|
||||
*
|
||||
* @param[in] aPreference The preference value to convert (`OT_ROUTE_PREFERENCE_*` values).
|
||||
*
|
||||
* @returns A string representation @p aPreference.
|
||||
*
|
||||
*/
|
||||
static const char *PreferenceToString(signed int aPreference);
|
||||
|
||||
/**
|
||||
* Parses the argument as an IP address.
|
||||
*
|
||||
* If the argument string is an IPv4 address, this method will try to synthesize an IPv6 address using preferred
|
||||
* NAT64 prefix in the network data.
|
||||
*
|
||||
* @param[in] aInstance A pointer to OpenThread instance.
|
||||
* @param[in] aArg The argument string to parse.
|
||||
* @param[out] aAddress A reference to an `otIp6Address` to output the parsed IPv6 address.
|
||||
* @param[out] aSynthesized Whether @p aAddress is synthesized from an IPv4 address.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The argument was parsed successfully.
|
||||
* @retval OT_ERROR_INVALID_ARGS The argument is empty or does not contain a valid IP address.
|
||||
* @retval OT_ERROR_INVALID_STATE No valid NAT64 prefix in the network data.
|
||||
*
|
||||
*/
|
||||
static otError ParseToIp6Address(otInstance *aInstance,
|
||||
const Arg &aArg,
|
||||
otIp6Address &aAddress,
|
||||
bool &aSynthesized);
|
||||
|
||||
protected:
|
||||
static Interpreter *sInterpreter;
|
||||
|
||||
@@ -280,11 +210,6 @@ private:
|
||||
void OutputPrompt(void);
|
||||
void OutputResult(otError aError);
|
||||
|
||||
static otError ParseJoinerDiscerner(Arg &aArg, otJoinerDiscerner &aDiscerner);
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
|
||||
static otError ParsePrefix(Arg aArgs[], otBorderRouterConfig &aConfig);
|
||||
static otError ParseRoute(Arg aArgs[], otExternalRouteConfig &aConfig);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
|
||||
void OutputBorderRouterCounters(void);
|
||||
#endif
|
||||
|
||||
+5
-6
@@ -233,7 +233,7 @@ template <> otError Br::Process<Cmd("omrprefix")>(Arg aArgs[])
|
||||
|
||||
OutputFormat("%s", outputPrefixTypes == kPrefixTypeFavored ? "" : "Favored: ");
|
||||
OutputIp6Prefix(favored);
|
||||
OutputLine(" prf:%s", Interpreter::PreferenceToString(preference));
|
||||
OutputLine(" prf:%s", PreferenceToString(preference));
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -365,7 +365,7 @@ template <> otError Br::Process<Cmd("nat64prefix")>(Arg aArgs[])
|
||||
|
||||
OutputFormat("%s", outputPrefixTypes == kPrefixTypeFavored ? "" : "Favored: ");
|
||||
OutputIp6Prefix(favored);
|
||||
OutputLine(" prf:%s", Interpreter::PreferenceToString(preference));
|
||||
OutputLine(" prf:%s", PreferenceToString(preference));
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -424,7 +424,7 @@ template <> otError Br::Process<Cmd("prefixtable")>(Arg aArgs[])
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputFormat("route-prf:%s, ", Interpreter::PreferenceToString(entry.mRoutePreference));
|
||||
OutputFormat("route-prf:%s, ", PreferenceToString(entry.mRoutePreference));
|
||||
}
|
||||
|
||||
OutputFormat("router:");
|
||||
@@ -594,8 +594,7 @@ template <> otError Br::Process<Cmd("rioprf")>(Arg aArgs[])
|
||||
*/
|
||||
if (aArgs[0].IsEmpty())
|
||||
{
|
||||
OutputLine("%s",
|
||||
Interpreter::PreferenceToString(otBorderRoutingGetRouteInfoOptionPreference(GetInstancePtr())));
|
||||
OutputLine("%s", PreferenceToString(otBorderRoutingGetRouteInfoOptionPreference(GetInstancePtr())));
|
||||
}
|
||||
/**
|
||||
* @cli br rioprf clear
|
||||
@@ -648,7 +647,7 @@ template <> otError Br::Process<Cmd("routeprf")>(Arg aArgs[])
|
||||
*/
|
||||
if (aArgs[0].IsEmpty())
|
||||
{
|
||||
OutputLine("%s", Interpreter::PreferenceToString(otBorderRoutingGetRoutePreference(GetInstancePtr())));
|
||||
OutputLine("%s", PreferenceToString(otBorderRoutingGetRoutePreference(GetInstancePtr())));
|
||||
}
|
||||
/**
|
||||
* @cli br routeprf clear
|
||||
|
||||
@@ -194,7 +194,7 @@ template <> otError Commissioner::Process<Cmd("joiner")>(Arg aArgs[])
|
||||
}
|
||||
else
|
||||
{
|
||||
error = Interpreter::ParseJoinerDiscerner(aArgs[1], discerner);
|
||||
error = ParseJoinerDiscerner(aArgs[1], discerner);
|
||||
|
||||
if (error == OT_ERROR_NOT_FOUND)
|
||||
{
|
||||
|
||||
+1
-2
@@ -422,8 +422,7 @@ otError Dns::GetDnsConfig(Arg aArgs[], otDnsQueryConfig *&aConfig)
|
||||
|
||||
VerifyOrExit(!aArgs[0].IsEmpty(), aConfig = nullptr);
|
||||
|
||||
SuccessOrExit(error = Interpreter::ParseToIp6Address(GetInstancePtr(), aArgs[0], aConfig->mServerSockAddr.mAddress,
|
||||
nat64Synth));
|
||||
SuccessOrExit(error = ParseToIp6Address(GetInstancePtr(), aArgs[0], aConfig->mServerSockAddr.mAddress, nat64Synth));
|
||||
if (nat64Synth)
|
||||
{
|
||||
OutputFormat("Synthesized IPv6 DNS server address: ");
|
||||
|
||||
@@ -1341,7 +1341,7 @@ template <> otError History::Process<Cmd("prefix")>(Arg aArgs[])
|
||||
OutputLine(isList ? "%s -> event:%s prefix:%s flags:%s pref:%s rloc16:0x%04x"
|
||||
: "| %20s | %-7s | %-43s | %-9s | %-4s | 0x%04x |",
|
||||
ageString, Stringify(info->mEvent, kSimpleEventStrings), prefixString, flagsString,
|
||||
Interpreter::PreferenceToString(info->mPrefix.mPreference), info->mPrefix.mRloc16);
|
||||
PreferenceToString(info->mPrefix.mPreference), info->mPrefix.mRloc16);
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -1430,7 +1430,7 @@ template <> otError History::Process<Cmd("route")>(Arg aArgs[])
|
||||
OutputLine(isList ? "%s -> event:%s route:%s flags:%s pref:%s rloc16:0x%04x"
|
||||
: "| %20s | %-7s | %-43s | %-9s | %-4s | 0x%04x |",
|
||||
ageString, Stringify(info->mEvent, kSimpleEventStrings), prefixString, flagsString,
|
||||
Interpreter::PreferenceToString(info->mRoute.mPreference), info->mRoute.mRloc16);
|
||||
PreferenceToString(info->mRoute.mPreference), info->mRoute.mRloc16);
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
@@ -108,7 +108,7 @@ template <> otError Joiner::Process<Cmd("discerner")>(Arg aArgs[])
|
||||
else
|
||||
{
|
||||
VerifyOrExit(aArgs[1].IsEmpty());
|
||||
SuccessOrExit(Interpreter::ParseJoinerDiscerner(aArgs[0], discerner));
|
||||
SuccessOrExit(ParseJoinerDiscerner(aArgs[0], discerner));
|
||||
error = otJoinerSetDiscerner(GetInstancePtr(), &discerner);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ void NetworkData::OutputPrefix(const otBorderRouterConfig &aConfig)
|
||||
OutputFormat(" %s", flagsString);
|
||||
}
|
||||
|
||||
OutputLine(" %s %04x", Interpreter::PreferenceToString(aConfig.mPreference), aConfig.mRloc16);
|
||||
OutputLine(" %s %04x", PreferenceToString(aConfig.mPreference), aConfig.mRloc16);
|
||||
}
|
||||
|
||||
void NetworkData::RouteFlagsToString(const otExternalRouteConfig &aConfig, FlagsString &aString)
|
||||
@@ -155,7 +155,7 @@ void NetworkData::OutputRoute(const otExternalRouteConfig &aConfig)
|
||||
OutputFormat(" %s", flagsString);
|
||||
}
|
||||
|
||||
OutputLine(" %s %04x", Interpreter::PreferenceToString(aConfig.mPreference), aConfig.mRloc16);
|
||||
OutputLine(" %s %04x", PreferenceToString(aConfig.mPreference), aConfig.mRloc16);
|
||||
}
|
||||
|
||||
void NetworkData::OutputService(const otServiceConfig &aConfig)
|
||||
@@ -343,7 +343,7 @@ template <> otError NetworkData::Process<Cmd("publish")>(Arg aArgs[])
|
||||
{
|
||||
otBorderRouterConfig config;
|
||||
|
||||
SuccessOrExit(error = Interpreter::ParsePrefix(aArgs + 1, config));
|
||||
SuccessOrExit(error = ParsePrefix(aArgs + 1, config));
|
||||
error = otNetDataPublishOnMeshPrefix(GetInstancePtr(), &config);
|
||||
ExitNow();
|
||||
}
|
||||
@@ -364,7 +364,7 @@ template <> otError NetworkData::Process<Cmd("publish")>(Arg aArgs[])
|
||||
{
|
||||
otExternalRouteConfig config;
|
||||
|
||||
SuccessOrExit(error = Interpreter::ParseRoute(aArgs + 1, config));
|
||||
SuccessOrExit(error = ParseRoute(aArgs + 1, config));
|
||||
error = otNetDataPublishExternalRoute(GetInstancePtr(), &config);
|
||||
ExitNow();
|
||||
}
|
||||
@@ -387,7 +387,7 @@ template <> otError NetworkData::Process<Cmd("publish")>(Arg aArgs[])
|
||||
otExternalRouteConfig config;
|
||||
|
||||
SuccessOrExit(error = aArgs[1].ParseAsIp6Prefix(prefix));
|
||||
SuccessOrExit(error = Interpreter::ParseRoute(aArgs + 2, config));
|
||||
SuccessOrExit(error = ParseRoute(aArgs + 2, config));
|
||||
error = otNetDataReplacePublishedExternalRoute(GetInstancePtr(), &prefix, &config);
|
||||
ExitNow();
|
||||
}
|
||||
@@ -493,7 +493,7 @@ template <> otError NetworkData::Process<Cmd("steeringdata")>(Arg aArgs[])
|
||||
|
||||
VerifyOrExit(aArgs[0] == "check", error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
error = Interpreter::ParseJoinerDiscerner(aArgs[1], discerner);
|
||||
error = ParseJoinerDiscerner(aArgs[1], discerner);
|
||||
|
||||
if (error == OT_ERROR_NOT_FOUND)
|
||||
{
|
||||
|
||||
@@ -96,7 +96,7 @@ otError PingSender::Process(Arg aArgs[])
|
||||
aArgs++;
|
||||
}
|
||||
|
||||
SuccessOrExit(error = Interpreter::ParseToIp6Address(GetInstancePtr(), aArgs[0], config.mDestination, nat64Synth));
|
||||
SuccessOrExit(error = ParseToIp6Address(GetInstancePtr(), aArgs[0], config.mDestination, nat64Synth));
|
||||
|
||||
if (nat64Synth)
|
||||
{
|
||||
|
||||
+1
-1
@@ -383,7 +383,7 @@ template <> otError TcpExample::Process<Cmd("connect")>(Arg aArgs[])
|
||||
|
||||
VerifyOrExit(mInitialized, error = OT_ERROR_INVALID_STATE);
|
||||
|
||||
SuccessOrExit(error = Interpreter::ParseToIp6Address(GetInstancePtr(), aArgs[0], sockaddr.mAddress, nat64Synth));
|
||||
SuccessOrExit(error = ParseToIp6Address(GetInstancePtr(), aArgs[0], sockaddr.mAddress, nat64Synth));
|
||||
|
||||
if (nat64Synth)
|
||||
{
|
||||
|
||||
+2
-3
@@ -134,7 +134,7 @@ template <> otError UdpExample::Process<Cmd("connect")>(Arg aArgs[])
|
||||
otSockAddr sockaddr;
|
||||
bool nat64Synth;
|
||||
|
||||
SuccessOrExit(error = Interpreter::ParseToIp6Address(GetInstancePtr(), aArgs[0], sockaddr.mAddress, nat64Synth));
|
||||
SuccessOrExit(error = ParseToIp6Address(GetInstancePtr(), aArgs[0], sockaddr.mAddress, nat64Synth));
|
||||
|
||||
if (nat64Synth)
|
||||
{
|
||||
@@ -269,8 +269,7 @@ template <> otError UdpExample::Process<Cmd("send")>(Arg aArgs[])
|
||||
{
|
||||
bool nat64Synth;
|
||||
|
||||
SuccessOrExit(
|
||||
error = Interpreter::ParseToIp6Address(GetInstancePtr(), aArgs[0], messageInfo.mPeerAddr, nat64Synth));
|
||||
SuccessOrExit(error = ParseToIp6Address(GetInstancePtr(), aArgs[0], messageInfo.mPeerAddr, nat64Synth));
|
||||
|
||||
if (nat64Synth)
|
||||
{
|
||||
|
||||
@@ -517,5 +517,270 @@ otError Utils::ProcessEnableDisable(Arg aArgs[],
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Utils::ParseJoinerDiscerner(Arg &aArg, otJoinerDiscerner &aDiscerner)
|
||||
{
|
||||
otError error;
|
||||
char *separator;
|
||||
|
||||
VerifyOrExit(!aArg.IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
separator = strstr(aArg.GetCString(), "/");
|
||||
|
||||
VerifyOrExit(separator != nullptr, error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
SuccessOrExit(error = ot::Utils::CmdLineParser::ParseAsUint8(separator + 1, aDiscerner.mLength));
|
||||
VerifyOrExit(aDiscerner.mLength > 0 && aDiscerner.mLength <= 64, error = OT_ERROR_INVALID_ARGS);
|
||||
*separator = '\0';
|
||||
error = aArg.ParseAsUint64(aDiscerner.mValue);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Utils::ParsePreference(const Arg &aArg, otRoutePreference &aPreference)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
if (aArg == "high")
|
||||
{
|
||||
aPreference = OT_ROUTE_PREFERENCE_HIGH;
|
||||
}
|
||||
else if (aArg == "med")
|
||||
{
|
||||
aPreference = OT_ROUTE_PREFERENCE_MED;
|
||||
}
|
||||
else if (aArg == "low")
|
||||
{
|
||||
aPreference = OT_ROUTE_PREFERENCE_LOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = OT_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
const char *Utils::PreferenceToString(signed int aPreference)
|
||||
{
|
||||
const char *str = "";
|
||||
|
||||
switch (aPreference)
|
||||
{
|
||||
case OT_ROUTE_PREFERENCE_LOW:
|
||||
str = "low";
|
||||
break;
|
||||
|
||||
case OT_ROUTE_PREFERENCE_MED:
|
||||
str = "med";
|
||||
break;
|
||||
|
||||
case OT_ROUTE_PREFERENCE_HIGH:
|
||||
str = "high";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||
otError Utils::ParseToIp6Address(otInstance *aInstance, const Arg &aArg, otIp6Address &aAddress, bool &aSynthesized)
|
||||
{
|
||||
Error error = OT_ERROR_NONE;
|
||||
|
||||
VerifyOrExit(!aArg.IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
error = aArg.ParseAsIp6Address(aAddress);
|
||||
aSynthesized = false;
|
||||
|
||||
if (error != OT_ERROR_NONE)
|
||||
{
|
||||
// It might be an IPv4 address, let's have a try.
|
||||
otIp4Address ip4Address;
|
||||
|
||||
// Do not touch the error value if we failed to parse it as an IPv4 address.
|
||||
SuccessOrExit(aArg.ParseAsIp4Address(ip4Address));
|
||||
SuccessOrExit(error = otNat64SynthesizeIp6Address(aInstance, &ip4Address, &aAddress));
|
||||
aSynthesized = true;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
|
||||
otError Utils::ParsePrefix(Arg aArgs[], otBorderRouterConfig &aConfig)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
ClearAllBytes(aConfig);
|
||||
|
||||
SuccessOrExit(error = aArgs[0].ParseAsIp6Prefix(aConfig.mPrefix));
|
||||
aArgs++;
|
||||
|
||||
for (; !aArgs->IsEmpty(); aArgs++)
|
||||
{
|
||||
otRoutePreference preference;
|
||||
|
||||
if (ParsePreference(*aArgs, preference) == OT_ERROR_NONE)
|
||||
{
|
||||
aConfig.mPreference = preference;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (char *arg = aArgs->GetCString(); *arg != '\0'; arg++)
|
||||
{
|
||||
switch (*arg)
|
||||
{
|
||||
case 'p':
|
||||
aConfig.mPreferred = true;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
aConfig.mSlaac = true;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
aConfig.mDhcp = true;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
aConfig.mConfigure = true;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
aConfig.mDefaultRoute = true;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
aConfig.mOnMesh = true;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
aConfig.mStable = true;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
aConfig.mNdDns = true;
|
||||
break;
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
case 'D':
|
||||
aConfig.mDp = true;
|
||||
break;
|
||||
#endif
|
||||
case '-':
|
||||
break;
|
||||
|
||||
default:
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Utils::ParseRoute(Arg aArgs[], otExternalRouteConfig &aConfig)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
ClearAllBytes(aConfig);
|
||||
|
||||
SuccessOrExit(error = aArgs[0].ParseAsIp6Prefix(aConfig.mPrefix));
|
||||
aArgs++;
|
||||
|
||||
for (; !aArgs->IsEmpty(); aArgs++)
|
||||
{
|
||||
otRoutePreference preference;
|
||||
|
||||
if (ParsePreference(*aArgs, preference) == OT_ERROR_NONE)
|
||||
{
|
||||
aConfig.mPreference = preference;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (char *arg = aArgs->GetCString(); *arg != '\0'; arg++)
|
||||
{
|
||||
switch (*arg)
|
||||
{
|
||||
case 's':
|
||||
aConfig.mStable = true;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
aConfig.mNat64 = true;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
aConfig.mAdvPio = true;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
break;
|
||||
|
||||
default:
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
|
||||
#endif // #if OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||
|
||||
const char *Utils::LinkModeToString(const otLinkModeConfig &aLinkMode, char (&aStringBuffer)[kLinkModeStringSize])
|
||||
{
|
||||
char *flagsPtr = &aStringBuffer[0];
|
||||
|
||||
if (aLinkMode.mRxOnWhenIdle)
|
||||
{
|
||||
*flagsPtr++ = 'r';
|
||||
}
|
||||
|
||||
if (aLinkMode.mDeviceType)
|
||||
{
|
||||
*flagsPtr++ = 'd';
|
||||
}
|
||||
|
||||
if (aLinkMode.mNetworkData)
|
||||
{
|
||||
*flagsPtr++ = 'n';
|
||||
}
|
||||
|
||||
if (flagsPtr == &aStringBuffer[0])
|
||||
{
|
||||
*flagsPtr++ = '-';
|
||||
}
|
||||
|
||||
*flagsPtr = '\0';
|
||||
|
||||
return aStringBuffer;
|
||||
}
|
||||
|
||||
const char *Utils::AddressOriginToString(uint8_t aOrigin)
|
||||
{
|
||||
static const char *const kOriginStrings[4] = {
|
||||
"thread", // 0, OT_ADDRESS_ORIGIN_THREAD
|
||||
"slaac", // 1, OT_ADDRESS_ORIGIN_SLAAC
|
||||
"dhcp6", // 2, OT_ADDRESS_ORIGIN_DHCPV6
|
||||
"manual", // 3, OT_ADDRESS_ORIGIN_MANUAL
|
||||
};
|
||||
|
||||
static_assert(0 == OT_ADDRESS_ORIGIN_THREAD, "OT_ADDRESS_ORIGIN_THREAD value is incorrect");
|
||||
static_assert(1 == OT_ADDRESS_ORIGIN_SLAAC, "OT_ADDRESS_ORIGIN_SLAAC value is incorrect");
|
||||
static_assert(2 == OT_ADDRESS_ORIGIN_DHCPV6, "OT_ADDRESS_ORIGIN_DHCPV6 value is incorrect");
|
||||
static_assert(3 == OT_ADDRESS_ORIGIN_MANUAL, "OT_ADDRESS_ORIGIN_MANUAL value is incorrect");
|
||||
|
||||
return Stringify(aOrigin, kOriginStrings);
|
||||
}
|
||||
|
||||
} // namespace Cli
|
||||
} // namespace ot
|
||||
|
||||
@@ -38,7 +38,11 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <openthread/border_router.h>
|
||||
#include <openthread/border_routing.h>
|
||||
#include <openthread/cli.h>
|
||||
#include <openthread/joiner.h>
|
||||
#include <openthread/thread.h>
|
||||
|
||||
#include "cli_config.h"
|
||||
|
||||
@@ -645,6 +649,114 @@ public:
|
||||
IsEnabledHandler aIsEnabledHandler,
|
||||
SetEnabledHandlerFailable aSetEnabledHandler);
|
||||
|
||||
/**
|
||||
* Parses a given argument string as a route preference comparing it against "high", "med", or
|
||||
* "low".
|
||||
*
|
||||
* @param[in] aArg The argument string to parse.
|
||||
* @param[out] aPreference Reference to a `otRoutePreference` to return the parsed preference.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully parsed @p aArg and updated @p aPreference.
|
||||
* @retval OT_ERROR_INVALID_ARG @p aArg is not a valid preference string "high", "med", or "low".
|
||||
*
|
||||
*/
|
||||
static otError ParsePreference(const Arg &aArg, otRoutePreference &aPreference);
|
||||
|
||||
/**
|
||||
* Converts a route preference value to human-readable string.
|
||||
*
|
||||
* @param[in] aPreference The preference value to convert (`OT_ROUTE_PREFERENCE_*` values).
|
||||
*
|
||||
* @returns A string representation @p aPreference.
|
||||
*
|
||||
*/
|
||||
static const char *PreferenceToString(signed int aPreference);
|
||||
|
||||
/**
|
||||
* Parses the argument as an IP address.
|
||||
*
|
||||
* If the argument string is an IPv4 address, this method will try to synthesize an IPv6 address using preferred
|
||||
* NAT64 prefix in the network data.
|
||||
*
|
||||
* @param[in] aInstance A pointer to OpenThread instance.
|
||||
* @param[in] aArg The argument string to parse.
|
||||
* @param[out] aAddress A reference to an `otIp6Address` to output the parsed IPv6 address.
|
||||
* @param[out] aSynthesized Whether @p aAddress is synthesized from an IPv4 address.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The argument was parsed successfully.
|
||||
* @retval OT_ERROR_INVALID_ARGS The argument is empty or does not contain a valid IP address.
|
||||
* @retval OT_ERROR_INVALID_STATE No valid NAT64 prefix in the network data.
|
||||
*
|
||||
*/
|
||||
static otError ParseToIp6Address(otInstance *aInstance,
|
||||
const Arg &aArg,
|
||||
otIp6Address &aAddress,
|
||||
bool &aSynthesized);
|
||||
|
||||
/**
|
||||
* Parses the argument as a Joiner Discerner.
|
||||
*
|
||||
* @param[in] aArg The argument string to parse.
|
||||
* @param[out] aDiscerner A reference to an `otJoinerDiscerner` to output the parsed discerner
|
||||
*
|
||||
* @retval OT_ERROR_NONE The argument was parsed successfully.
|
||||
* @retval OT_ERROR_INVALID_ARGS The argument is empty or does not contain a valid joiner discerner.
|
||||
*
|
||||
*/
|
||||
static otError ParseJoinerDiscerner(Arg &aArg, otJoinerDiscerner &aDiscerner);
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
|
||||
/**
|
||||
* Parses the argument as a Border Router configuration.
|
||||
*
|
||||
* @param[in] aArg The argument string to parse.
|
||||
* @param[out] aConfig A reference to an `otBorderRouterConfig` to output the configuration.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The argument was parsed successfully.
|
||||
* @retval OT_ERROR_INVALID_ARGS The argument is empty or does not contain a valid configuration.
|
||||
*
|
||||
*/
|
||||
static otError ParsePrefix(Arg aArgs[], otBorderRouterConfig &aConfig);
|
||||
|
||||
/**
|
||||
* Parses the argument as a External Route configuration.
|
||||
*
|
||||
* @param[in] aArg The argument string to parse.
|
||||
* @param[out] aConfig A reference to an `otExternalRouteConfig` to output the configuration.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The argument was parsed successfully.
|
||||
* @retval OT_ERROR_INVALID_ARGS The argument is empty or does not contain a valid configuration.
|
||||
*
|
||||
*/
|
||||
static otError ParseRoute(Arg aArgs[], otExternalRouteConfig &aConfig);
|
||||
#endif
|
||||
|
||||
static constexpr uint8_t kLinkModeStringSize = sizeof("rdn"); ///< Size of string buffer for a MLE Link Mode.
|
||||
|
||||
/**
|
||||
* Converts a given MLE Link Mode to flag string.
|
||||
*
|
||||
* The characters 'r', 'd', and 'n' are respectively used for `mRxOnWhenIdle`, `mDeviceType` and `mNetworkData`
|
||||
* flags. If all flags are `false`, then "-" is returned.
|
||||
*
|
||||
* @param[in] aLinkMode The MLE Link Mode to convert.
|
||||
* @param[out] aStringBuffer A reference to an string array to place the string.
|
||||
*
|
||||
* @returns A pointer @p aStringBuffer which contains the converted string.
|
||||
*
|
||||
*/
|
||||
static const char *LinkModeToString(const otLinkModeConfig &aLinkMode, char (&aStringBuffer)[kLinkModeStringSize]);
|
||||
|
||||
/**
|
||||
* Converts an IPv6 address origin `OT_ADDRESS_ORIGIN_*` value to human-readable string.
|
||||
*
|
||||
* @param[in] aOrigin The IPv6 address origin to convert.
|
||||
*
|
||||
* @returns A human-readable string representation of @p aOrigin.
|
||||
*
|
||||
*/
|
||||
static const char *AddressOriginToString(uint8_t aOrigin);
|
||||
|
||||
protected:
|
||||
void OutputFormatV(const char *aFormat, va_list aArguments);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user