Skip to content

Commit

Permalink
Add new properties related to multi radio link and TREL features
Browse files Browse the repository at this point in the history
  • Loading branch information
abtink committed Nov 24, 2020
1 parent f2e1501 commit 8db2a71
Show file tree
Hide file tree
Showing 4 changed files with 256 additions and 0 deletions.
163 changes: 163 additions & 0 deletions src/ncp-spinel/SpinelNCPInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,11 +509,16 @@ SpinelNCPInstance::get_supported_property_keys()const
properties.insert(kWPANTUNDProperty_ThreadActiveDataset);
properties.insert(kWPANTUNDProperty_ThreadPendingDataset);
properties.insert(kWPANTUNDProperty_ThreadAddressCacheTable);
properties.insert(kWPANTUNDProperty_OpenThreadSupportedRadioLinks);

if (mCapabilities.count(SPINEL_CAP_ERROR_RATE_TRACKING)) {
properties.insert(kWPANTUNDProperty_ThreadNeighborTableErrorRates);
}

if (mCapabilities.count(SPINEL_CAP_MULTI_RADIO)) {
properties.insert(kWPANTUNDProperty_OpenThreadNeighborTableMultiRadioInfo);
}

if (mCapabilities.count(SPINEL_CAP_THREAD_COMMISSIONER)) {
properties.insert(kWPANTUNDProperty_CommissionerState);
properties.insert(kWPANTUNDProperty_CommissionerProvisioningUrl);
Expand Down Expand Up @@ -1667,6 +1672,150 @@ unpack_address_cache_table(const uint8_t *data_in, spinel_size_t data_len, boost
return ret;
}

static int
unpack_supported_radio_links(const uint8_t *data_in, spinel_size_t data_len, boost::any &value)
{
std::list<std::string> result;
int ret = kWPANTUNDStatus_Ok;

while (data_len > 0) {
spinel_ssize_t len;
unsigned int value;

len = spinel_packed_uint_decode(data_in, data_len, &value);
require_action(len > 0, bail, ret = kWPANTUNDStatus_Failure);

data_in += len;
data_len -= len;

result.push_back(std::string(spinel_radio_link_to_cstr(value)));
}

value = result;

bail:
return ret;
}
static int
unpack_neighbor_table_multi_radio_info(const uint8_t *data_in, spinel_size_t data_len, boost::any &value)
{
int ret = kWPANTUNDStatus_Ok;
std::list<std::string> result;
char c_string[200];
int index;

while (data_len > 0) {
spinel_ssize_t len = 0;
const uint8_t *entry_data;
spinel_size_t entry_len;
const spinel_eui64_t *eui64 = NULL;
uint16_t rloc16;
bool first_radio;

len = spinel_datatype_unpack(
data_in,
data_len,
SPINEL_DATATYPE_DATA_WLEN_S,
&entry_data,
&entry_len
);

require_action(len > 0, bail, ret = kWPANTUNDStatus_Failure);

data_in += len;
data_len -= len;

// Parse the entry_data (which contains info about a neighbor)

len = spinel_datatype_unpack(
entry_data,
entry_len,
(
SPINEL_DATATYPE_EUI64_S // EUI64 Address
SPINEL_DATATYPE_UINT16_S // Rloc16
),
&eui64,
&rloc16
);

require_action(len > 0, bail, ret = kWPANTUNDStatus_Failure);

index = 0;

index += snprintf(c_string + index, sizeof(c_string) - index,
"%02X%02X%02X%02X%02X%02X%02X%02X, RLOC16:%04x, Radios:[",
eui64->bytes[0], eui64->bytes[1], eui64->bytes[2], eui64->bytes[3],
eui64->bytes[4], eui64->bytes[5], eui64->bytes[6], eui64->bytes[7],
rloc16
);

require_action(index < sizeof(c_string), bail, ret = kWPANTUNDStatus_Failure);

entry_data += len;
entry_len -= len;

first_radio = true;

while (entry_len > 0) {
const uint8_t *struct_data;
spinel_size_t struct_len;
unsigned int radio;
uint8_t preference;

len = spinel_datatype_unpack(
entry_data,
entry_len,
SPINEL_DATATYPE_DATA_WLEN_S,
&struct_data,
&struct_len
);

require_action(len > 0, bail, ret = kWPANTUNDStatus_Failure);

entry_data += len;
entry_len -= len;

// Parse struct_data (contains info about a supported radio link type)

len = spinel_datatype_unpack(
struct_data,
struct_len,
(
SPINEL_DATATYPE_UINT_PACKED_S // Radio link
SPINEL_DATATYPE_UINT8_S // Preference
),
&radio,
&preference
);

require_action(len > 0, bail, ret = kWPANTUNDStatus_Failure);

struct_data += len;
struct_len -= len;

index += snprintf(c_string + index, sizeof(c_string) - index,
"%s%s(%d)",
first_radio ? "" : ", ",
spinel_radio_link_to_cstr(radio),
preference
);

require_action(index < sizeof(c_string), bail, ret = kWPANTUNDStatus_Failure);
first_radio = false;
}

index += snprintf(c_string + index, sizeof(c_string) - index, "]");
require_action(index < sizeof(c_string), bail, ret = kWPANTUNDStatus_Failure);

result.push_back(std::string(c_string));
}

value = result;

bail:
return ret;
}

static int
unpack_mesh_local_prefix(const uint8_t *data_in, spinel_size_t data_len, boost::any &value)
{
Expand Down Expand Up @@ -2316,6 +2465,9 @@ SpinelNCPInstance::regsiter_all_get_handlers(void)
register_get_handler_spinel_simple(
kWPANTUNDProperty_OpenThreadLogTimestampBase,
SPINEL_PROP_DEBUG_LOG_TIMESTAMP_BASE, SPINEL_DATATYPE_UINT64_S);
register_get_handler_spinel_simple(
kWPANTUNDProperty_OpenThreadTrelTestModeEnable,
SPINEL_PROP_DEBUG_TREL_TEST_MODE_ENABLE, SPINEL_DATATYPE_BOOL_S);

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Properties requiring capability check and associated with a spinel property
Expand Down Expand Up @@ -2643,6 +2795,10 @@ SpinelNCPInstance::regsiter_all_get_handlers(void)
kWPANTUNDProperty_ThreadAddressCacheTableAsValMap,
SPINEL_PROP_THREAD_ADDRESS_CACHE_TABLE,
boost::bind(unpack_address_cache_table, _1, _2, _3, /* as_val_map */ true));
register_get_handler_spinel_unpacker(
kWPANTUNDProperty_OpenThreadSupportedRadioLinks,
SPINEL_PROP_SUPPORTED_RADIO_LINKS,
unpack_supported_radio_links);

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Properties requiring capability check and associated with a spinel property
Expand Down Expand Up @@ -2756,6 +2912,10 @@ SpinelNCPInstance::regsiter_all_get_handlers(void)
kWPANTUNDProperty_NCPCoexMetricsAsValMap,
SPINEL_CAP_RADIO_COEX,
SPINEL_PROP_RADIO_COEX_METRICS, boost::bind(unpack_coex_metrics, _1, _2, _3, true));
register_get_handler_capability_spinel_unpacker(
kWPANTUNDProperty_OpenThreadNeighborTableMultiRadioInfo,
SPINEL_CAP_MULTI_RADIO,
SPINEL_PROP_NEIGHBOR_TABLE_MULTI_RADIO_INFO, boost::bind(unpack_neighbor_table_multi_radio_info, _1, _2, _3));

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Properties with a dedicated handler method
Expand Down Expand Up @@ -3522,6 +3682,9 @@ SpinelNCPInstance::regsiter_all_set_handlers(void)
register_set_handler_spinel(
kWPANTUNDProperty_ThreadRouterDowngradeThreshold,
SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD, SPINEL_DATATYPE_UINT8_C);
register_set_handler_spinel(
kWPANTUNDProperty_OpenThreadTrelTestModeEnable,
SPINEL_PROP_DEBUG_TREL_TEST_MODE_ENABLE, SPINEL_DATATYPE_BOOL_C);

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Properties requiring persistence (saving in settings) and associated with a
Expand Down
3 changes: 3 additions & 0 deletions src/wpantund/wpan-properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@
#define kWPANTUNDProperty_POSIXAppRCPVersion "POSIXApp:RCPVersion"
#define kWPANTUNDProperty_POSIXAppRCPVersionCached "POSIXApp:RCPVersion:Cached"

#define kWPANTUNDProperty_OpenThreadSupportedRadioLinks "OpenThread:SupportedRadioLinks"
#define kWPANTUNDProperty_OpenThreadNeighborTableMultiRadioInfo "OpenThread:NeighborTable::MultiRadioInfo"
#define kWPANTUNDProperty_OpenThreadLogLevel "OpenThread:LogLevel"
#define kWPANTUNDProperty_OpenThreadLogTimestampBase "OpenThread:LogTimestampBase"
#define kWPANTUNDProperty_OpenThreadSLAACEnabled "OpenThread:SLAAC:Enabled"
Expand All @@ -182,6 +184,7 @@
#define kWPANTUNDProperty_OpenThreadMsgBufferCountersAsString "OpenThread:MsgBufferCounters:AsString"
#define kWPANTUNDProperty_OpenThreadDebugTestAssert "OpenThread:Debug:TestAssert"
#define kWPANTUNDProperty_OpenThreadDebugTestWatchdog "OpenThread:Debug:TestWatchdog"
#define kWPANTUNDProperty_OpenThreadTrelTestModeEnable "OpenThread:Trel:TestMode:Enable"

#define kWPANTUNDProperty_DebugIPv6GlobalIPAddressList "Debug:IPv6:GlobalIPAddressList"

Expand Down
41 changes: 41 additions & 0 deletions third_party/openthread/src/ncp/spinel.c
Original file line number Diff line number Diff line change
Expand Up @@ -1987,6 +1987,14 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
ret = "SLAAC_ENABLED";
break;

case SPINEL_PROP_SUPPORTED_RADIO_LINKS:
ret = "SUPPORTED_RADIO_LINKS";
break;

case SPINEL_PROP_NEIGHBOR_TABLE_MULTI_RADIO_INFO:
ret = "NEIGHBOR_TABLE_MULTI_RADIO_INFO";
break;

case SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE:
ret = "SERVER_ALLOW_LOCAL_DATA_CHANGE";
break;
Expand Down Expand Up @@ -2247,6 +2255,14 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
ret = "DEBUG_TEST_WATCHDOG";
break;

case SPINEL_PROP_DEBUG_LOG_TIMESTAMP_BASE:
ret = "DEBUG_LOG_TIMESTAMP_BASE";
break;

case SPINEL_PROP_DEBUG_TREL_TEST_MODE_ENABLE:
ret = "DEBUG_TREL_TEST_MODE_ENABLE";
break;

default:
break;
}
Expand Down Expand Up @@ -2651,6 +2667,10 @@ const char *spinel_capability_to_cstr(spinel_capability_t capability)
ret = "MAC_RETRY_HISTOGRAM";
break;

case SPINEL_CAP_MULTI_RADIO:
ret = "MULTI_RADIO";
break;

case SPINEL_CAP_ERROR_RATE_TRACKING:
ret = "ERROR_RATE_TRACKING";
break;
Expand Down Expand Up @@ -2698,6 +2718,27 @@ const char *spinel_capability_to_cstr(spinel_capability_t capability)
return ret;
}

const char *spinel_radio_link_to_cstr(uint32_t radio)
{
const char *ret = "UNKNOWN";

switch (radio)
{
case SPINEL_RADIO_LINK_IEEE_802_15_4:
ret = "IEEE_802_15_4";
break;

case SPINEL_RADIO_LINK_TREL_UDP6:
ret = "TREL_UDP6";
break;

default:
break;
}

return ret;
}

// LCOV_EXCL_STOP

/* -------------------------------------------------------------------------- */
Expand Down
49 changes: 49 additions & 0 deletions third_party/openthread/src/ncp/spinel.h
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,12 @@ enum
SPINEL_ADDRESS_CACHE_ENTRY_STATE_RETRY_QUERY = 3, // Entry is in retry mode (a prior query did not a response).
};

enum
{
SPINEL_RADIO_LINK_IEEE_802_15_4 = 0,
SPINEL_RADIO_LINK_TREL_UDP6 = 1,
};

typedef struct
{
uint8_t bytes[8];
Expand Down Expand Up @@ -1091,6 +1097,7 @@ enum
SPINEL_CAP_SLAAC = (SPINEL_CAP_OPENTHREAD__BEGIN + 10),
SPINEL_CAP_RADIO_COEX = (SPINEL_CAP_OPENTHREAD__BEGIN + 11),
SPINEL_CAP_MAC_RETRY_HISTOGRAM = (SPINEL_CAP_OPENTHREAD__BEGIN + 12),
SPINEL_CAP_MULTI_RADIO = (SPINEL_CAP_OPENTHREAD__BEGIN + 13),
SPINEL_CAP_OPENTHREAD__END = 640,

SPINEL_CAP_THREAD__BEGIN = 1024,
Expand Down Expand Up @@ -3530,6 +3537,34 @@ enum
*/
SPINEL_PROP_SLAAC_ENABLED = SPINEL_PROP_OPENTHREAD__BEGIN + 14,

// Supported Radio Links (by device)
/**
* Format `A(i)` - Read only
*
* This property returns list of supported radio links by the device itself. Enumeration `SPINEL_RADIO_LINK_{TYPE}`
* values indicate different radio link types.
*
*/
SPINEL_PROP_SUPPORTED_RADIO_LINKS = SPINEL_PROP_OPENTHREAD__BEGIN + 15,

/// Neighbor Table Multi Radio Link Info
/** Format: `A(t(ESA(t(iC))))` - Read only
* Required capability: `SPINEL_CAP_MULTI_RADIO`.
*
* Each item represents info about a neighbor:
*
* `E`: Neighbor's Extended Address
* `S`: Neighbor's RLOC16
*
* This is then followed by an array of radio link info structures indicating which radio links are supported by
* the neighbor:
*
* `i` : Radio link type (enumeration `SPINEL_RADIO_LINK_{TYPE}`).
* `C` : Preference value associated with radio link.
*
*/
SPINEL_PROP_NEIGHBOR_TABLE_MULTI_RADIO_INFO = SPINEL_PROP_OPENTHREAD__BEGIN + 16,

SPINEL_PROP_OPENTHREAD__END = 0x2000,

SPINEL_PROP_SERVER__BEGIN = 0xA0,
Expand Down Expand Up @@ -4059,6 +4094,18 @@ enum
*/
SPINEL_PROP_DEBUG_LOG_TIMESTAMP_BASE = SPINEL_PROP_DEBUG__BEGIN + 3,

/// TREL Radio Link - test mode enable
/** Format `b` (read-write)
*
* This property is intended for testing TREL (Thread Radio Encapsulation Link) radio type only (during simulation).
* It allows the TREL interface to be temporarily disabled and (re)enabled. While disabled all traffic through
* TREL interface is dropped silently (to emulate a radio/interface down scenario).
*
* This property is only available when the TREL radio link type is supported.
*
*/
SPINEL_PROP_DEBUG_TREL_TEST_MODE_ENABLE = SPINEL_PROP_DEBUG__BEGIN + 4,

SPINEL_PROP_DEBUG__END = 0x4400,

SPINEL_PROP_EXPERIMENTAL__BEGIN = 2000000,
Expand Down Expand Up @@ -4250,6 +4297,8 @@ SPINEL_API_EXTERN const char *spinel_status_to_cstr(spinel_status_t status);

SPINEL_API_EXTERN const char *spinel_capability_to_cstr(spinel_capability_t capability);

SPINEL_API_EXTERN const char *spinel_radio_link_to_cstr(uint32_t radio);

// ----------------------------------------------------------------------------

#if defined(__cplusplus)
Expand Down

0 comments on commit 8db2a71

Please sign in to comment.