Skip to content

Commit

Permalink
Add new properties related to multi radio link feature
Browse files Browse the repository at this point in the history
  • Loading branch information
abtink committed Feb 18, 2020
1 parent 5157992 commit 923598d
Show file tree
Hide file tree
Showing 4 changed files with 302 additions and 12 deletions.
171 changes: 167 additions & 4 deletions src/ncp-spinel/SpinelNCPInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ SpinelNCPInstance::handle_ncp_log_stream(const uint8_t *data_in, int data_len)
len = spinel_datatype_unpack(
data_in,
data_len,
(
SPINEL_DATATYPE_UINT8_S
(
SPINEL_DATATYPE_UINT8_S
SPINEL_DATATYPE_UINT_PACKED_S
),
&log_level,
Expand All @@ -240,7 +240,7 @@ SpinelNCPInstance::handle_ncp_log_stream(const uint8_t *data_in, int data_len)
&log_timestamp
);
require(len >= 0, bail);

snprintf(
prefix_string,
sizeof(prefix_string),
Expand Down Expand Up @@ -508,11 +508,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 @@ -1466,6 +1471,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 @@ -2080,6 +2229,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 @@ -2407,6 +2559,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 @@ -2512,6 +2668,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 @@ -3268,6 +3428,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 Expand Up @@ -3334,7 +3497,7 @@ SpinelNCPInstance::regsiter_all_set_handlers(void)
kWPANTUNDProperty_OpenThreadLogTimestampBase,
SPINEL_CAP_OPENTHREAD_LOG_METADATA,
SPINEL_PROP_DEBUG_LOG_TIMESTAMP_BASE, SPINEL_DATATYPE_UINT64_C);

// Properties with a `ValueConverter`
register_set_handler_capability_spinel(
kWPANTUNDProperty_CommissionerState,
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
79 changes: 76 additions & 3 deletions third_party/openthread/src/ncp/spinel.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,22 @@
#define ENOMEM 1
#endif

#ifndef SPINEL_PLATFORM_SHOULD_LOG_ASSERTS
#define SPINEL_PLATFORM_SHOULD_LOG_ASSERTS 0
#endif

#ifndef SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
#define SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR 0
#endif

#ifndef SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
#define SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF 0
#endif

#ifndef SPINEL_SELF_TEST
#define SPINEL_SELF_TEST 0
#endif

#if defined(errno) && SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
#error "SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR is set but errno is already defined."
#endif
Expand Down Expand Up @@ -131,6 +147,22 @@ static int spinel_errno_workaround_;
#define require(c, l) require_action(c, l, {})
#endif

#ifndef strnlen
static size_t spinel_strnlen(const char *s, size_t maxlen)
{
size_t ret;

for (ret = 0; (ret < maxlen) && (s[ret] != 0); ret++)
{
// Empty loop.
}

return ret;
}
#else
#define spinel_strnlen strnlen
#endif

typedef struct
{
va_list obj;
Expand Down Expand Up @@ -522,7 +554,7 @@ static spinel_ssize_t spinel_datatype_vunpack_(bool in_place,
// Add 1 for zero termination. If not zero terminated,
// len will then be data_len+1, which we will detect
// in the next check.
len = strnlen((const char *)data_in, data_len) + 1;
len = spinel_strnlen((const char *)data_in, data_len) + 1;

// Verify that the string is zero terminated.
require_action(len <= data_len, bail, (ret = -1, errno = EOVERFLOW));
Expand Down Expand Up @@ -1951,6 +1983,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 @@ -2210,11 +2250,15 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
case SPINEL_PROP_DEBUG_TEST_WATCHDOG:
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 @@ -2619,6 +2663,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 @@ -2666,6 +2714,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
Loading

0 comments on commit 923598d

Please sign in to comment.