Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new properties related to multi radio link feature #461

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
45 changes: 45 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,31 @@ 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_TOBLE:
ret = "TOBLE";
break;

case SPINEL_RADIO_LINK_TREL_UDP6:
ret = "TREL_UDP6";
break;

default:
break;
}

return ret;
}

// LCOV_EXCL_STOP

/* -------------------------------------------------------------------------- */
Expand Down
50 changes: 50 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,13 @@ 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_TOBLE = 1,
SPINEL_RADIO_LINK_TREL_UDP6 = 2,
};

typedef struct
{
uint8_t bytes[8];
Expand Down Expand Up @@ -1091,6 +1098,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 +3538,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 +4095,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 +4298,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