[cli] implement network data print (#5543)

- Print human-readable network data.
- Create network data sub-command.
This commit is contained in:
Jonathan Hui
2020-09-19 10:28:17 -07:00
committed by GitHub
parent 8fbcd22064
commit 0d8a99bd05
28 changed files with 792 additions and 247 deletions
+1
View File
@@ -372,6 +372,7 @@ LOCAL_SRC_FILES := \
src/cli/cli_console.cpp \
src/cli/cli_dataset.cpp \
src/cli/cli_joiner.cpp \
src/cli/cli_network_data.cpp \
src/cli/cli_uart.cpp \
src/cli/cli_udp.cpp \
$(NULL)
+1 -1
View File
@@ -80,7 +80,7 @@ keysequence
leaderweight
masterkey
mode
netdataregister
netdata register
networkidtimeout
networkname
panid
+1 -1
View File
@@ -95,7 +95,7 @@ keysequence
leaderweight
masterkey
mode
netdataregister
netdata register
networkidtimeout
networkname
panid
+1 -1
View File
@@ -96,7 +96,7 @@ keysequence
leaderweight
masterkey
mode
netdataregister
netdata register
networkidtimeout
networkname
panid
+1 -1
View File
@@ -80,7 +80,7 @@ keysequence
leaderweight
masterkey
mode
netdataregister
netdata register
networkidtimeout
networkname
panid
+1 -1
View File
@@ -138,7 +138,7 @@ In the J-Link Device drop-down list select the serial number of the device to fl
leaderweight
masterkey
mode
netdataregister
netdata register
networkidtimeout
networkname
panid
+1 -1
View File
@@ -151,7 +151,7 @@ In the J-Link Device drop-down list select the serial number of the device to fl
leaderweight
masterkey
mode
netdataregister
netdata register
networkidtimeout
networkname
panid
+1 -1
View File
@@ -144,7 +144,7 @@ In the J-Link Device drop-down list select the serial number of the device to fl
leaderweight
masterkey
mode
netdataregister
netdata register
networkidtimeout
networkname
panid
+1 -1
View File
@@ -103,7 +103,7 @@ keysequence
leaderweight
masterkey
mode
netdataregister
netdata register
networkidtimeout
networkname
panid
+1 -1
View File
@@ -54,7 +54,7 @@ keysequence
leaderweight
masterkey
mode
netdataregister
netdata register
networkidtimeout
networkname
panid
+1 -1
View File
@@ -97,7 +97,7 @@ $ (gdb) c
leaderweight
masterkey
mode
netdataregister
netdata register
networkidtimeout
networkname
panid
+1 -1
View File
@@ -54,7 +54,7 @@ keysequence
leaderweight
masterkey
mode
netdataregister
netdata register
networkidtimeout
networkname
panid
+2
View File
@@ -43,6 +43,8 @@ openthread_cli_sources = [
"cli_dataset.hpp",
"cli_joiner.cpp",
"cli_joiner.hpp",
"cli_network_data.cpp",
"cli_network_data.hpp",
"cli_uart.cpp",
"cli_uart.hpp",
"cli_udp.cpp",
+1
View File
@@ -78,6 +78,7 @@ set(COMMON_SOURCES
cli_console.cpp
cli_dataset.cpp
cli_joiner.cpp
cli_network_data.cpp
cli_uart.cpp
cli_udp.cpp
)
+2
View File
@@ -157,6 +157,7 @@ SOURCES_COMMON = \
cli_console.cpp \
cli_dataset.cpp \
cli_joiner.cpp \
cli_network_data.cpp \
cli_uart.cpp \
cli_udp.cpp \
$(NULL)
@@ -178,6 +179,7 @@ noinst_HEADERS = \
cli_console.hpp \
cli_dataset.hpp \
cli_joiner.hpp \
cli_network_data.hpp \
cli_uart.hpp \
cli_udp.hpp \
x509_cert_key.hpp \
+4 -41
View File
@@ -63,9 +63,7 @@ Done
- [mlr](#mlr-reg-ipaddr--timeout)
- [mode](#mode)
- [neighbor](#neighbor-list)
- [netdata](#netdata-steeringdata-check-eui64discerner)
- [netdataregister](#netdataregister)
- [netdatashow](#netdatashow)
- [netdata](README_NETDATA.md)
- [netstat](#netstat)
- [networkdiagnostic](#networkdiagnostic-get-addr-type-)
- [networkidtimeout](#networkidtimeout)
@@ -1177,41 +1175,6 @@ Print table of neighbors.
Done
```
### netdata steeringdata check \<eui64\>|\<discerner\>
Check whether the steering data includes a joiner.
- eui64: The IEEE EUI-64 of the Joiner.
- discerner: The Joiner discerner in format `number/length`.
```bash
> netdata steeringdata check d45e64fa83f81cf7
Done
> netdata steeringdata check 0xabc/12
Done
> netdata steeringdata check 0xdef/12
Error 23: NotFound
```
### netdataregister
Register local network data with Thread Leader.
```bash
> netdataregister
Done
```
### netdatashow
Show Thread Leader network data.
```bash
> netdatashow
08040b020000
Done
```
### netstat
List all UDP sockets.
@@ -2088,7 +2051,7 @@ Factory Diagnostics module is enabled only when building OpenThread with `OPENTH
### service
Module for controlling service registration in Network Data. Each change in service registration must be sent to leader by `netdataregister` command before taking effect.
Module for controlling service registration in Network Data. Each change in service registration must be sent to leader by `netdata register` command before taking effect.
### service add \<enterpriseNumber\> \<serviceData\> \<serverData\>
@@ -2097,7 +2060,7 @@ Add service to the Network Data.
```bash
> service add 44970 foo bar
Done
> netdataregister
> netdata register
Done
> ipaddr
fdde:ad00:beef:0:0:ff:fe00:fc10
@@ -2115,7 +2078,7 @@ Remove service from Network Data.
```bash
> service remove 44970 foo
Done
> netdataregister
> netdata register
Done
> ipaddr
fdde:ad00:beef:0:0:ff:fe00:fc00
+214
View File
@@ -0,0 +1,214 @@
# OpenThread CLI - Network Data
## Overview
Thread Network Data contains information about Border Routers and other servers available in the Thread network. Border Routers and devices offering services register their information with the Leader. The Leader collects and structures this information within the Thread Network Data and distributes the information to all devices in the Thread Network.
Border Routers may register prefixes assigned to the Thread Network and prefixes that they offer routes for. Services may register any information relevant to the service itself.
Border Router and service information may be stable or temporary. Stable Thread Network Data is distributed to all devices, including Sleepy End Devices (SEDs). Temporary Network Data is distributed to all nodes except SEDs.
## Quick Start
### Form Network and Configure Prefix
1. Generate and view new network configuration.
```bash
> dataset init new
Done
> dataset
Active Timestamp: 1
Channel: 13
Channel Mask: 0x07fff800
Ext PAN ID: d63e8e3e495ebbc3
Mesh Local Prefix: fd3d:b50b:f96d:722d::/64
Master Key: dfd34f0f05cad978ec4e32b0413038ff
Network Name: OpenThread-8f28
PAN ID: 0x8f28
PSKc: c23a76e98f1a6483639b1ac1271e2e27
Security Policy: 0, onrcb
Done
```
2. Commit new dataset to the Active Operational Dataset in non-volatile storage.
```bash
dataset commit active
Done
```
3. Enable Thread interface
```bash
> ifconfig up
Done
> thread start
Done
```
4. Observe IPv6 addresses assigned to the Thread inteface.
```bash
> ipaddr
fd3d:b50b:f96d:722d:0:ff:fe00:fc00
fd3d:b50b:f96d:722d:0:ff:fe00:dc00
fd3d:b50b:f96d:722d:393c:462d:e8d2:db32
fe80:0:0:0:a40b:197f:593d:ca61
Done
```
5. Register an IPv6 prefix assigned to the Thread network.
```bash
> prefix add fd00:dead:beef:cafe::/64 paros
Done
> netdata register
Done
```
6. Observe Thread Network Data.
```bash
> netdata show
Prefixes:
fd00:dead:beef:cafe::/64 paros med dc00
Routes:
Services:
Done
```
7. Observe IPv6 addresses assigned to the Thread interface.
```bash
> ipaddr
fd00:dead:beef:cafe:4da8:5234:4aa2:4cfa
fd3d:b50b:f96d:722d:0:ff:fe00:fc00
fd3d:b50b:f96d:722d:0:ff:fe00:dc00
fd3d:b50b:f96d:722d:393c:462d:e8d2:db32
fe80:0:0:0:a40b:197f:593d:ca61
Done
```
### Attach to Existing Network
Only the Master Key is required for a device to attach to a Thread network.
While not required, specifying the channel avoids the need to search across multiple channels, improving both latency and efficiency of the attach process.
After the device successfully attaches to a Thread network, the device will retrieve the complete Active Operational Dataset.
1. Create a partial Active Operational Dataset.
```bash
> dataset masterkey dfd34f0f05cad978ec4e32b0413038ff
Done
> dataset commit active
Done
```
2. Enable Thread interface.
```bash
> ifconfig up
Done
> thread start
Done
```
3. After attaching, observe Thread Network Data.
```bash
> netdata show
Prefixes:
fd00:dead:beef:cafe::/64 paros med dc00
Routes:
Services:
Done
```
4. Observe IPv6 addresses assigned to the Thread interface.
```bash
> ipaddr
fd00:dead:beef:cafe:4da8:5234:4aa2:4cfa
fd3d:b50b:f96d:722d:0:ff:fe00:fc00
fd3d:b50b:f96d:722d:0:ff:fe00:dc00
fd3d:b50b:f96d:722d:393c:462d:e8d2:db32
fe80:0:0:0:a40b:197f:593d:ca61
Done
```
## Command List
- [help](#help)
- [register](#register)
- [show](#show)
- [steeringdata](#steeringdata-check-eui64discerner)
## Command Details
### help
Usage: `netdata help`
Print netdata help menu.
```bash
> netdata help
help
register
show
steeringdata
Done
```
### register
Usage: `dataset register`
Register configured prefixes, routes, and services with the Leader.
```bash
> netdata register
Done
```
### show
Usage: `dataset show [-x]`
Print Network Data received from the Leader.
```bash
> netdata show
Prefixes:
fd00:dead:beef:cafe::/64 paros med dc00
Routes:
Services:
Done
```
Print Network Data as hex-encoded TLVs.
```bash
> netdata show -x
08040b02174703140040fd00deadbeefcafe0504dc00330007021140
Done
```
### netdata steeringdata check \<eui64\>|\<discerner\>
Check whether the steering data includes a joiner.
- eui64: The IEEE EUI-64 of the Joiner.
- discerner: The Joiner discerner in format `number/length`.
```bash
> netdata steeringdata check d45e64fa83f81cf7
Done
> netdata steeringdata check 0xabc/12
Done
> netdata steeringdata check 0xdef/12
Error 23: NotFound
```
+24 -172
View File
@@ -41,7 +41,6 @@
#include <openthread/icmp6.h>
#include <openthread/link.h>
#include <openthread/ncp.h>
#include <openthread/netdata.h>
#include <openthread/thread.h>
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
#include <openthread/network_time.h>
@@ -122,8 +121,9 @@ Interpreter::Interpreter(Instance *aInstance)
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
, mSntpQueryingInProgress(false)
#endif
, mUdp(*this)
, mDataset(*this)
, mNetworkData(*this)
, mUdp(*this)
#if OPENTHREAD_CONFIG_COAP_API_ENABLE
, mCoap(*this)
#endif
@@ -2132,24 +2132,6 @@ exit:
}
#endif
void Interpreter::ProcessNetworkDataShow(uint8_t aArgsLength, char *aArgs[])
{
OT_UNUSED_VARIABLE(aArgsLength);
OT_UNUSED_VARIABLE(aArgs);
otError error = OT_ERROR_NONE;
uint8_t data[255];
uint8_t len = sizeof(data);
SuccessOrExit(error = otNetDataGet(mInstance, false, data, &len));
OutputBytes(data, static_cast<uint8_t>(len));
OutputLine("");
exit:
OutputResult(error);
}
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
void Interpreter::ProcessNetif(uint8_t aArgsLength, char *aArgs[])
{
@@ -2232,13 +2214,28 @@ exit:
}
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
otError Interpreter::ProcessServiceList(void)
{
otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
otServiceConfig config;
while (otServerGetNextService(mInstance, &iterator, &config) == OT_ERROR_NONE)
{
mNetworkData.OutputService(config);
}
return OT_ERROR_NONE;
}
void Interpreter::ProcessService(uint8_t aArgsLength, char *aArgs[])
{
otError error = OT_ERROR_NONE;
VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
if (strcmp(aArgs[0], "add") == 0)
if (aArgsLength == 0)
{
SuccessOrExit(error = ProcessServiceList());
}
else if (strcmp(aArgs[0], "add") == 0)
{
otServiceConfig cfg;
long enterpriseNumber;
@@ -2288,63 +2285,10 @@ exit:
void Interpreter::ProcessNetworkData(uint8_t aArgsLength, char *aArgs[])
{
otError error;
if (aArgsLength > 2 && strcmp(aArgs[0], "steeringdata") == 0)
{
if (strcmp(aArgs[1], "check") == 0)
{
otExtAddress addr;
otJoinerDiscerner discerner;
discerner.mLength = 0;
error = Interpreter::ParseJoinerDiscerner(aArgs[2], discerner);
if (error == OT_ERROR_NOT_FOUND)
{
VerifyOrExit(Interpreter::Hex2Bin(aArgs[2], addr.m8, sizeof(addr)) == sizeof(addr),
error = OT_ERROR_INVALID_ARGS);
}
else if (error != OT_ERROR_NONE)
{
ExitNow();
}
if (discerner.mLength)
{
ExitNow(error = otNetDataSteeringDataCheckJoinerWithDiscerner(mInstance, &discerner));
}
else
{
ExitNow(error = otNetDataSteeringDataCheckJoiner(mInstance, &addr));
}
}
}
error = OT_ERROR_INVALID_COMMAND;
exit:
error = mNetworkData.Process(aArgsLength, aArgs);
OutputResult(error);
}
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
void Interpreter::ProcessNetworkDataRegister(uint8_t aArgsLength, char *aArgs[])
{
OT_UNUSED_VARIABLE(aArgsLength);
OT_UNUSED_VARIABLE(aArgs);
otError error = OT_ERROR_NONE;
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
SuccessOrExit(error = otBorderRouterRegister(mInstance));
#else
SuccessOrExit(error = otServerRegister(mInstance));
#endif
exit:
OutputResult(error);
}
#endif
#if OPENTHREAD_FTD
void Interpreter::ProcessNetworkIdTimeout(uint8_t aArgsLength, char *aArgs[])
{
@@ -2922,75 +2866,6 @@ exit:
return error;
}
void Interpreter::OutputPrefix(otBorderRouterConfig &aConfig)
{
OutputFormat("%x:%x:%x:%x::/%d ", HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[0]),
HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[1]), HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[2]),
HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[3]), aConfig.mPrefix.mLength);
if (aConfig.mPreferred)
{
OutputFormat("p");
}
if (aConfig.mSlaac)
{
OutputFormat("a");
}
if (aConfig.mDhcp)
{
OutputFormat("d");
}
if (aConfig.mConfigure)
{
OutputFormat("c");
}
if (aConfig.mDefaultRoute)
{
OutputFormat("r");
}
if (aConfig.mOnMesh)
{
OutputFormat("o");
}
if (aConfig.mStable)
{
OutputFormat("s");
}
if (aConfig.mNdDns)
{
OutputFormat("n");
}
if (aConfig.mDp)
{
OutputFormat("D");
}
switch (aConfig.mPreference)
{
case OT_ROUTE_PREFERENCE_LOW:
OutputFormat(" low");
break;
case OT_ROUTE_PREFERENCE_MED:
OutputFormat(" med");
break;
case OT_ROUTE_PREFERENCE_HIGH:
OutputFormat(" high");
break;
}
OutputLine("");
}
otError Interpreter::ProcessPrefixList(void)
{
otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
@@ -2998,7 +2873,7 @@ otError Interpreter::ProcessPrefixList(void)
while (otBorderRouterGetNextOnMeshPrefix(mInstance, &iterator, &config) == OT_ERROR_NONE)
{
OutputPrefix(config);
mNetworkData.OutputPrefix(config);
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
@@ -3006,7 +2881,7 @@ otError Interpreter::ProcessPrefixList(void)
{
SuccessOrExit(otBackboneRouterGetDomainPrefix(mInstance, &config));
OutputFormat("- ");
OutputPrefix(config);
mNetworkData.OutputPrefix(config);
}
// Else already printed via above while loop.
exit:
@@ -3210,30 +3085,7 @@ otError Interpreter::ProcessRouteList(void)
while (otBorderRouterGetNextRoute(mInstance, &iterator, &config) == OT_ERROR_NONE)
{
OutputFormat("%x:%x:%x:%x::/%d ", HostSwap16(config.mPrefix.mPrefix.mFields.m16[0]),
HostSwap16(config.mPrefix.mPrefix.mFields.m16[1]),
HostSwap16(config.mPrefix.mPrefix.mFields.m16[2]),
HostSwap16(config.mPrefix.mPrefix.mFields.m16[3]), config.mPrefix.mLength);
if (config.mStable)
{
OutputFormat("s");
}
switch (config.mPreference)
{
case OT_ROUTE_PREFERENCE_LOW:
OutputLine(" low");
break;
case OT_ROUTE_PREFERENCE_MED:
OutputLine(" med");
break;
case OT_ROUTE_PREFERENCE_HIGH:
OutputLine(" high");
break;
}
mNetworkData.OutputRoute(config);
}
return OT_ERROR_NONE;
+14 -12
View File
@@ -47,6 +47,7 @@
#include "cli/cli_commissioner.hpp"
#include "cli/cli_dataset.hpp"
#include "cli/cli_joiner.hpp"
#include "cli/cli_network_data.hpp"
#include "cli/cli_udp.hpp"
#if OPENTHREAD_CONFIG_COAP_API_ENABLE
@@ -87,6 +88,7 @@ class Interpreter
friend class Commissioner;
friend class Dataset;
friend class Joiner;
friend class NetworkData;
friend class UdpExample;
public:
@@ -383,17 +385,21 @@ private:
void ProcessNeighbor(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessNetworkData(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
void ProcessNetworkDataRegister(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessNetworkDataShow(uint8_t aArgsLength, char *aArgs[]);
void ProcessNetworkDataPrefix(void);
void ProcessNetworkDataRoute(void);
void ProcessNetworkDataService(void);
void OutputPrefix(const otBorderRouterConfig &aConfig);
void OutputRoute(const otExternalRouteConfig &aConfig);
void OutputService(const otServiceConfig &aConfig);
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
void ProcessNetif(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessNetstat(uint8_t aArgsLength, char *aArgs[]);
int OutputSocketAddress(const otSockAddr &aAddress);
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
void ProcessService(uint8_t aArgsLength, char *aArgs[]);
void ProcessService(uint8_t aArgsLength, char *aArgs[]);
otError ProcessServiceList(void);
#endif
#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
void ProcessNetworkDiagnostic(uint8_t aArgsLength, char *aArgs[]);
@@ -426,7 +432,6 @@ private:
otError ProcessPrefixAdd(uint8_t aArgsLength, char *aArgs[]);
otError ProcessPrefixRemove(uint8_t aArgsLength, char *aArgs[]);
otError ProcessPrefixList(void);
void OutputPrefix(otBorderRouterConfig &aConfig);
#endif
void ProcessPromiscuous(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_FTD
@@ -625,10 +630,6 @@ private:
{"neighbor", &Interpreter::ProcessNeighbor},
#endif
{"netdata", &Interpreter::ProcessNetworkData},
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
{"netdataregister", &Interpreter::ProcessNetworkDataRegister},
#endif
{"netdatashow", &Interpreter::ProcessNetworkDataShow},
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
{"netif", &Interpreter::ProcessNetif},
#endif
@@ -712,8 +713,9 @@ private:
bool mSntpQueryingInProgress;
#endif
UdpExample mUdp;
Dataset mDataset;
Dataset mDataset;
NetworkData mNetworkData;
UdpExample mUdp;
#if OPENTHREAD_CONFIG_COAP_API_ENABLE
Coap mCoap;
+343
View File
@@ -0,0 +1,343 @@
/*
* 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.
*/
/**
* @file
* This file implements CLI commands for Network Data.
*/
#include "cli_network_data.hpp"
#include <openthread/border_router.h>
#include <openthread/server.h>
#include "cli/cli.hpp"
#include "common/encoding.hpp"
using ot::Encoding::BigEndian::HostSwap16;
namespace ot {
namespace Cli {
const struct NetworkData::Command NetworkData::sCommands[] = {
{"help", &NetworkData::ProcessHelp},
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
{"register", &NetworkData::ProcessRegister},
#endif
{"show", &NetworkData::ProcessShow},
{"steeringdata", &NetworkData::ProcessSteeringData},
};
NetworkData::NetworkData(Interpreter &aInterpreter)
: mInterpreter(aInterpreter)
{
}
void NetworkData::OutputPrefix(const otBorderRouterConfig &aConfig)
{
mInterpreter.OutputFormat("%x:%x:%x:%x::/%d ", HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[0]),
HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[1]),
HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[2]),
HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[3]), aConfig.mPrefix.mLength);
if (aConfig.mPreferred)
{
mInterpreter.OutputFormat("p");
}
if (aConfig.mSlaac)
{
mInterpreter.OutputFormat("a");
}
if (aConfig.mDhcp)
{
mInterpreter.OutputFormat("d");
}
if (aConfig.mConfigure)
{
mInterpreter.OutputFormat("c");
}
if (aConfig.mDefaultRoute)
{
mInterpreter.OutputFormat("r");
}
if (aConfig.mOnMesh)
{
mInterpreter.OutputFormat("o");
}
if (aConfig.mStable)
{
mInterpreter.OutputFormat("s");
}
if (aConfig.mNdDns)
{
mInterpreter.OutputFormat("n");
}
if (aConfig.mDp)
{
mInterpreter.OutputFormat("D");
}
switch (aConfig.mPreference)
{
case OT_ROUTE_PREFERENCE_LOW:
mInterpreter.OutputFormat(" low");
break;
case OT_ROUTE_PREFERENCE_MED:
mInterpreter.OutputFormat(" med");
break;
case OT_ROUTE_PREFERENCE_HIGH:
mInterpreter.OutputFormat(" high");
break;
}
mInterpreter.OutputLine(" %04x", aConfig.mRloc16);
}
void NetworkData::OutputRoute(const otExternalRouteConfig &aConfig)
{
mInterpreter.OutputFormat("%x:%x:%x:%x::/%d ", HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[0]),
HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[1]),
HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[2]),
HostSwap16(aConfig.mPrefix.mPrefix.mFields.m16[3]), aConfig.mPrefix.mLength);
if (aConfig.mStable)
{
mInterpreter.OutputFormat("s ");
}
switch (aConfig.mPreference)
{
case OT_ROUTE_PREFERENCE_LOW:
mInterpreter.OutputFormat("low");
break;
case OT_ROUTE_PREFERENCE_MED:
mInterpreter.OutputFormat("med");
break;
case OT_ROUTE_PREFERENCE_HIGH:
mInterpreter.OutputFormat("high");
break;
}
mInterpreter.OutputLine(" %04x", aConfig.mRloc16);
}
void NetworkData::OutputService(const otServiceConfig &aConfig)
{
mInterpreter.OutputFormat("%u ", aConfig.mEnterpriseNumber);
mInterpreter.OutputBytes(aConfig.mServiceData, aConfig.mServiceDataLength);
mInterpreter.OutputFormat(" ");
mInterpreter.OutputBytes(aConfig.mServerConfig.mServerData, aConfig.mServerConfig.mServerDataLength);
if (aConfig.mServerConfig.mStable)
{
mInterpreter.OutputFormat(" s");
}
mInterpreter.OutputLine(" %04x", aConfig.mServerConfig.mRloc16);
}
otError NetworkData::ProcessHelp(uint8_t aArgsLength, char *aArgs[])
{
OT_UNUSED_VARIABLE(aArgsLength);
OT_UNUSED_VARIABLE(aArgs);
for (const Command &command : sCommands)
{
mInterpreter.OutputLine("%s", command.mName);
}
return OT_ERROR_NONE;
}
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
otError NetworkData::ProcessRegister(uint8_t aArgsLength, char *aArgs[])
{
OT_UNUSED_VARIABLE(aArgsLength);
OT_UNUSED_VARIABLE(aArgs);
otError error = OT_ERROR_NONE;
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
SuccessOrExit(error = otBorderRouterRegister(mInterpreter.mInstance));
#else
SuccessOrExit(error = otServerRegister(mInterpreter.mInstance));
#endif
exit:
return error;
}
#endif
otError NetworkData::ProcessSteeringData(uint8_t aArgsLength, char *aArgs[])
{
otError error = OT_ERROR_INVALID_ARGS;
otExtAddress addr;
otJoinerDiscerner discerner;
VerifyOrExit((aArgsLength > 1) && (strcmp(aArgs[0], "check") == 0), OT_NOOP);
discerner.mLength = 0;
error = Interpreter::ParseJoinerDiscerner(aArgs[1], discerner);
if (error == OT_ERROR_NOT_FOUND)
{
VerifyOrExit(Interpreter::Hex2Bin(aArgs[1], addr.m8, sizeof(addr)) == sizeof(addr), OT_NOOP);
}
else if (error != OT_ERROR_NONE)
{
ExitNow();
}
if (discerner.mLength)
{
error = otNetDataSteeringDataCheckJoinerWithDiscerner(mInterpreter.mInstance, &discerner);
}
else
{
error = otNetDataSteeringDataCheckJoiner(mInterpreter.mInstance, &addr);
}
exit:
return error;
}
void NetworkData::OutputPrefixes(void)
{
otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
otBorderRouterConfig config;
mInterpreter.OutputLine("Prefixes:");
while (otNetDataGetNextOnMeshPrefix(mInterpreter.mInstance, &iterator, &config) == OT_ERROR_NONE)
{
OutputPrefix(config);
}
}
void NetworkData::OutputRoutes(void)
{
otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
otExternalRouteConfig config;
mInterpreter.OutputLine("Routes:");
while (otNetDataGetNextRoute(mInterpreter.mInstance, &iterator, &config) == OT_ERROR_NONE)
{
OutputRoute(config);
}
}
void NetworkData::OutputServices(void)
{
otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
otServiceConfig config;
mInterpreter.OutputLine("Services:");
while (otNetDataGetNextService(mInterpreter.mInstance, &iterator, &config) == OT_ERROR_NONE)
{
OutputService(config);
}
}
otError NetworkData::OutputBinary(void)
{
otError error = OT_ERROR_NONE;
uint8_t data[255];
uint8_t len = sizeof(data);
SuccessOrExit(error = otNetDataGet(mInterpreter.mInstance, false, data, &len));
mInterpreter.OutputBytes(data, static_cast<uint8_t>(len));
mInterpreter.OutputLine("");
exit:
return error;
}
otError NetworkData::ProcessShow(uint8_t aArgsLength, char *aArgs[])
{
otError error;
if (aArgsLength == 0)
{
OutputPrefixes();
OutputRoutes();
OutputServices();
error = OT_ERROR_NONE;
}
else if (strcmp(aArgs[0], "-x") == 0)
{
error = OutputBinary();
}
else
{
error = OT_ERROR_INVALID_ARGS;
}
return error;
}
otError NetworkData::Process(uint8_t aArgsLength, char *aArgs[])
{
otError error = OT_ERROR_INVALID_COMMAND;
if (aArgsLength < 1)
{
IgnoreError(ProcessHelp(0, nullptr));
error = OT_ERROR_INVALID_ARGS;
}
else
{
for (const Command &command : sCommands)
{
if (strcmp(aArgs[0], command.mName) == 0)
{
error = (this->*command.mCommand)(aArgsLength - 1, aArgs + 1);
break;
}
}
}
return error;
}
} // namespace Cli
} // namespace ot
+120
View File
@@ -0,0 +1,120 @@
/*
* 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.
*/
/**
* @file
* This file contains definitions for Network Data CLI commands.
*/
#ifndef CLI_NETWORK_DATA_HPP_
#define CLI_NETWORK_DATA_HPP_
#include "openthread-core-config.h"
#include <openthread/netdata.h>
namespace ot {
namespace Cli {
class Interpreter;
/**
* This class implements the Network Data CLI.
*
*/
class NetworkData
{
public:
/**
* Constructor
*
* @param[in] aInterpreter The CLI interpreter.
*
*/
explicit NetworkData(Interpreter &aInterpreter);
/**
* 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, char *aArgs[]);
/**
* This method outputs the prefix config.
*
* @param[in] aConfig The prefix config.
*
*/
void OutputPrefix(const otBorderRouterConfig &aConfig);
/**
* This method outputs the route config.
*
* @param[in] aConfig The route config.
*
*/
void OutputRoute(const otExternalRouteConfig &aConfig);
/**
* This method outputs the service config.
*
* @param[in] aConfig The service config.
*
*/
void OutputService(const otServiceConfig &aConfig);
private:
struct Command
{
const char *mName;
otError (NetworkData::*mCommand)(uint8_t aArgsLength, char *aArgs[]);
};
otError ProcessHelp(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
otError ProcessRegister(uint8_t aArgsLength, char *aArgs[]);
#endif
otError ProcessShow(uint8_t aArgsLength, char *aArgs[]);
otError ProcessSteeringData(uint8_t aArgsLength, char *aArgs[]);
otError OutputBinary(void);
void OutputPrefixes(void);
void OutputRoutes(void);
void OutputServices(void);
static const Command sCommands[];
Interpreter & mInterpreter;
};
} // namespace Cli
} // namespace ot
#endif // CLI_NETWORK_DATA_HPP_
+1 -1
View File
@@ -40,7 +40,7 @@ keysequence
leaderweight
masterkey
mode
netdataregister
netdata register
networkidtimeout
networkname
panid
+1 -1
View File
@@ -37,7 +37,7 @@ set discerner "0xabc/12"
send "netdata typo check $discerner\n"
expect "InvalidCommand"
send "netdata steeringdata typo $discerner\n"
expect "InvalidCommand"
expect "InvalidArgs"
send "netdata steeringdata check $discerner/0\n"
expect "InvalidArgs"
send "netdata steeringdata check $discerner\n"
-3
View File
@@ -47,9 +47,6 @@ expect "Done"
send "bufferinfo\n"
expect "Done"
send "netdatashow\n"
expect "Done"
send "parent\n"
expect "Done"
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/expect -f
#
# 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.
#
source "tests/scripts/expect/_common.exp"
source "tests/scripts/expect/_multinode.exp"
setup_nodes
set spawn_id $spawn_1
send "netdata help\n"
expect "Done"
send "netdata register\n"
expect "Done"
send "netdata show\n"
expect "Done"
send "netdata show -x\n"
expect "Done"
dispose_nodes
+1 -1
View File
@@ -1021,7 +1021,7 @@ class Node:
self._expect('Done')
def register_netdata(self):
self.send_command('netdataregister')
self.send_command('netdata register')
self._expect('Done')
def send_network_diag_get(self, addr, tlv_types):
@@ -368,14 +368,14 @@ class OpenThreadController(threading.Thread):
"""
self._req('prefix add %s %s %s' % (prefix, flags, prf))
time.sleep(1)
self._req('netdataregister')
self._req('netdata register')
def remove_prefix(self, prefix):
"""Remove network prefix.
"""
self._req('prefix remove %s' % prefix)
time.sleep(1)
self._req('netdataregister')
self._req('netdata register')
def enable_denylist(self):
"""Enable denylist feature"""
+3 -3
View File
@@ -1473,7 +1473,7 @@ class OpenThreadTHCI(object):
print(cmd)
if self.__executeCommand(cmd)[-1] == 'Done':
# send server data ntf to leader
return self.__executeCommand('netdataregister')[-1] == 'Done'
return self.__executeCommand('netdata register')[-1] == 'Done'
else:
return False
except Exception as e:
@@ -1579,7 +1579,7 @@ class OpenThreadTHCI(object):
return True
else:
# send server data ntf to leader
return self.__executeCommand('netdataregister')[-1] == 'Done'
return self.__executeCommand('netdata register')[-1] == 'Done'
else:
return False
except Exception as e:
@@ -1743,7 +1743,7 @@ class OpenThreadTHCI(object):
if self.__executeCommand(cmd)[-1] == 'Done':
# send server data ntf to leader
return self.__executeCommand('netdataregister')[-1] == 'Done'
return self.__executeCommand('netdata register')[-1] == 'Done'
except Exception as e:
ModuleHelper.WriteIntoDebugLogger('configExternalRouter() Error: ' + str(e))