From 625e4adde448b8640355906954617f0694a689e6 Mon Sep 17 00:00:00 2001 From: Martin Turon Date: Tue, 27 Sep 2016 18:19:47 -0700 Subject: [PATCH] spinel-cli: Add router timing commands. (#705) Adds support for routerselectionjitter, routerdowngradethreshold, and masterkey to fixe the slew of ncp-sim failures from recent thread-cert test updates. Also added missing otInstance parameter to the new APIs.. Added otInstance to new APIs. --- .travis.yml | 2 - doc/spinel-protocol-src/spinel-tech-thread.md | 11 +++ include/openthread.h | 8 +- src/cli/cli.cpp | 8 +- src/core/openthread.cpp | 8 +- src/ncp/ncp_base.cpp | 80 +++++++++++++++++++ src/ncp/ncp_base.hpp | 4 + src/ncp/spinel.c | 8 ++ src/ncp/spinel.h | 12 +++ tools/spinel-cli/spinel-cli.py | 73 +++++++++++++++-- 10 files changed, 194 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5f6d824ed..07233db87 100644 --- a/.travis.yml +++ b/.travis.yml @@ -66,5 +66,3 @@ matrix: - env: BUILD_TARGET="posix-ncp" VERBOSE=1 compiler: gcc os: linux - allow_failures: - - env: BUILD_TARGET="posix-ncp" VERBOSE=1 diff --git a/doc/spinel-protocol-src/spinel-tech-thread.md b/doc/spinel-protocol-src/spinel-tech-thread.md index be1798409..dbde87460 100644 --- a/doc/spinel-protocol-src/spinel-tech-thread.md +++ b/doc/spinel-protocol-src/spinel-tech-thread.md @@ -172,3 +172,14 @@ Default value is `false`. Allow the HOST to indicate whether or not the router role is enabled. If current role is a router, setting this property to `false` starts a re-attach process as an end-device. + +### PROP 5384: PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD +* Type: Read-Write +* Packed-Encoding: `C` + +### PROP 5385: PROP_THREAD_ROUTER_SELECTION_JITTER +* Type: Read-Write +* Packed-Encoding: `C` + +Specifies the self imposed random delay in seconds a REED waits before +registering to become an Active Router. \ No newline at end of file diff --git a/include/openthread.h b/include/openthread.h index f085d2312..c67c326c2 100644 --- a/include/openthread.h +++ b/include/openthread.h @@ -1543,7 +1543,7 @@ void otPlatformReset(otInstance *aInstance); * * @sa otSetRouterDowngradeThreshold */ -uint8_t otGetRouterDowngradeThreshold(void); +uint8_t otGetRouterDowngradeThreshold(otInstance *aInstance); /** * Set the ROUTER_DOWNGRADE_THRESHOLD parameter used in the Leader role. @@ -1552,7 +1552,7 @@ uint8_t otGetRouterDowngradeThreshold(void); * * @sa otGetRouterDowngradeThreshold */ -void otSetRouterDowngradeThreshold(uint8_t aThreshold); +void otSetRouterDowngradeThreshold(otInstance *aInstance, uint8_t aThreshold); /** * Get the ROUTER_SELECTION_JITTER parameter used in the REED/Router role. @@ -1561,7 +1561,7 @@ void otSetRouterDowngradeThreshold(uint8_t aThreshold); * * @sa otSetRouterSelectionJitter */ -uint8_t otGetRouterSelectionJitter(void); +uint8_t otGetRouterSelectionJitter(otInstance *aInstance); /** * Set the ROUTER_SELECTION_JITTER parameter used in the REED/Router role. @@ -1570,7 +1570,7 @@ uint8_t otGetRouterSelectionJitter(void); * * @sa otGetRouterSelectionJitter */ -void otSetRouterSelectionJitter(uint8_t aRouterJitter); +void otSetRouterSelectionJitter(otInstance *aInstance, uint8_t aRouterJitter); /** * @} diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 84a124efa..065c367b8 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -1743,12 +1743,12 @@ void Interpreter::ProcessRouterDowngradeThreshold(int argc, char *argv[]) if (argc == 0) { - sServer->OutputFormat("%d\r\n", otGetRouterDowngradeThreshold()); + sServer->OutputFormat("%d\r\n", otGetRouterDowngradeThreshold(mInstance)); } else { SuccessOrExit(error = ParseLong(argv[0], value)); - otSetRouterDowngradeThreshold(static_cast(value)); + otSetRouterDowngradeThreshold(mInstance, static_cast(value)); } exit: @@ -1794,12 +1794,12 @@ void Interpreter::ProcessRouterSelectionJitter(int argc, char *argv[]) if (argc == 0) { - sServer->OutputFormat("%d\r\n", otGetRouterSelectionJitter()); + sServer->OutputFormat("%d\r\n", otGetRouterSelectionJitter(mInstance)); } else { SuccessOrExit(error = ParseLong(argv[0], value)); - otSetRouterSelectionJitter(static_cast(value)); + otSetRouterSelectionJitter(mInstance, static_cast(value)); } exit: diff --git a/src/core/openthread.cpp b/src/core/openthread.cpp index ae55f6c62..782b3e466 100644 --- a/src/core/openthread.cpp +++ b/src/core/openthread.cpp @@ -684,22 +684,22 @@ void otPlatformReset(otInstance *aInstance) otPlatReset(aInstance); } -uint8_t otGetRouterDowngradeThreshold(void) +uint8_t otGetRouterDowngradeThreshold(otInstance *) { return sThreadNetif->GetMle().GetRouterDowngradeThreshold(); } -void otSetRouterDowngradeThreshold(uint8_t aThreshold) +void otSetRouterDowngradeThreshold(otInstance *, uint8_t aThreshold) { sThreadNetif->GetMle().SetRouterDowngradeThreshold(aThreshold); } -uint8_t otGetRouterSelectionJitter(void) +uint8_t otGetRouterSelectionJitter(otInstance *) { return sThreadNetif->GetMle().GetRouterSelectionJitter(); } -void otSetRouterSelectionJitter(uint8_t aRouterJitter) +void otSetRouterSelectionJitter(otInstance *, uint8_t aRouterJitter) { sThreadNetif->GetMle().SetRouterSelectionJitter(aRouterJitter); } diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 07d741d98..8c9dcdc2d 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -134,10 +134,12 @@ const NcpBase::GetPropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] = { SPINEL_PROP_THREAD_CHILD_TIMEOUT, &NcpBase::GetPropertyHandler_THREAD_CHILD_TIMEOUT }, { SPINEL_PROP_THREAD_RLOC16, &NcpBase::GetPropertyHandler_THREAD_RLOC16 }, { SPINEL_PROP_THREAD_ROUTER_UPGRADE_THRESHOLD, &NcpBase::GetPropertyHandler_THREAD_ROUTER_UPGRADE_THRESHOLD }, + { SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD, &NcpBase::GetPropertyHandler_THREAD_ROUTER_DOWNGRADE_THRESHOLD }, { SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY, &NcpBase::GetPropertyHandler_THREAD_CONTEXT_REUSE_DELAY }, { SPINEL_PROP_THREAD_NETWORK_ID_TIMEOUT, &NcpBase::GetPropertyHandler_THREAD_NETWORK_ID_TIMEOUT }, { SPINEL_PROP_THREAD_ON_MESH_NETS, &NcpBase::NcpBase::GetPropertyHandler_THREAD_ON_MESH_NETS }, { SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING, &NcpBase::GetPropertyHandler_NET_REQUIRE_JOIN_EXISTING }, + { SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER, &NcpBase::GetPropertyHandler_THREAD_ROUTER_SELECTION_JITTER }, { SPINEL_PROP_IPV6_ML_PREFIX, &NcpBase::GetPropertyHandler_IPV6_ML_PREFIX }, { SPINEL_PROP_IPV6_ML_ADDR, &NcpBase::GetPropertyHandler_IPV6_ML_ADDR }, @@ -227,8 +229,10 @@ const NcpBase::SetPropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] = { SPINEL_PROP_THREAD_MODE, &NcpBase::SetPropertyHandler_THREAD_MODE }, { SPINEL_PROP_THREAD_CHILD_TIMEOUT, &NcpBase::SetPropertyHandler_THREAD_CHILD_TIMEOUT }, { SPINEL_PROP_THREAD_ROUTER_UPGRADE_THRESHOLD, &NcpBase::SetPropertyHandler_THREAD_ROUTER_UPGRADE_THRESHOLD }, + { SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD, &NcpBase::SetPropertyHandler_THREAD_ROUTER_DOWNGRADE_THRESHOLD }, { SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY, &NcpBase::SetPropertyHandler_THREAD_CONTEXT_REUSE_DELAY }, { SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING, &NcpBase::SetPropertyHandler_NET_REQUIRE_JOIN_EXISTING }, + { SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER, &NcpBase::SetPropertyHandler_THREAD_ROUTER_SELECTION_JITTER }, #if OPENTHREAD_ENABLE_DIAG { SPINEL_PROP_NEST_STREAM_MFG, &NcpBase::SetPropertyHandler_NEST_STREAM_MFG }, @@ -2560,6 +2564,28 @@ ThreadError NcpBase::GetPropertyHandler_THREAD_ROUTER_UPGRADE_THRESHOLD(uint8_t ); } +ThreadError NcpBase::GetPropertyHandler_THREAD_ROUTER_DOWNGRADE_THRESHOLD(uint8_t header, spinel_prop_key_t key) +{ + return SendPropertyUpdate( + header, + SPINEL_CMD_PROP_VALUE_IS, + key, + SPINEL_DATATYPE_UINT8_S, + otGetRouterDowngradeThreshold(mInstance) + ); +} + +ThreadError NcpBase::GetPropertyHandler_THREAD_ROUTER_SELECTION_JITTER(uint8_t header, spinel_prop_key_t key) +{ + return SendPropertyUpdate( + header, + SPINEL_CMD_PROP_VALUE_IS, + key, + SPINEL_DATATYPE_UINT8_S, + otGetRouterSelectionJitter(mInstance) + ); +} + ThreadError NcpBase::GetPropertyHandler_THREAD_CONTEXT_REUSE_DELAY(uint8_t header, spinel_prop_key_t key) { return SendPropertyUpdate( @@ -3893,6 +3919,60 @@ ThreadError NcpBase::SetPropertyHandler_THREAD_ROUTER_UPGRADE_THRESHOLD(uint8_t return errorCode; } +ThreadError NcpBase::SetPropertyHandler_THREAD_ROUTER_DOWNGRADE_THRESHOLD(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len) +{ + uint8_t i = 0; + spinel_ssize_t parsedLength; + ThreadError errorCode = kThreadError_None; + + parsedLength = spinel_datatype_unpack( + value_ptr, + value_len, + SPINEL_DATATYPE_UINT8_S, + &i + ); + + if (parsedLength > 0) + { + otSetRouterDowngradeThreshold(mInstance, i); + + errorCode = HandleCommandPropertyGet(header, key); + } + else + { + errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR); + } + + return errorCode; +} + +ThreadError NcpBase::SetPropertyHandler_THREAD_ROUTER_SELECTION_JITTER(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len) +{ + uint8_t i = 0; + spinel_ssize_t parsedLength; + ThreadError errorCode = kThreadError_None; + + parsedLength = spinel_datatype_unpack( + value_ptr, + value_len, + SPINEL_DATATYPE_UINT8_S, + &i + ); + + if (parsedLength > 0) + { + otSetRouterSelectionJitter(mInstance, i); + + errorCode = HandleCommandPropertyGet(header, key); + } + else + { + errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR); + } + + return errorCode; +} + ThreadError NcpBase::SetPropertyHandler_THREAD_CONTEXT_REUSE_DELAY(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len) { uint32_t i = 0; diff --git a/src/ncp/ncp_base.hpp b/src/ncp/ncp_base.hpp index 297b41b26..1423633d6 100644 --- a/src/ncp/ncp_base.hpp +++ b/src/ncp/ncp_base.hpp @@ -334,6 +334,8 @@ private: ThreadError GetPropertyHandler_THREAD_CHILD_TIMEOUT(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_THREAD_RLOC16(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_THREAD_ROUTER_UPGRADE_THRESHOLD(uint8_t header, spinel_prop_key_t key); + ThreadError GetPropertyHandler_THREAD_ROUTER_DOWNGRADE_THRESHOLD(uint8_t header, spinel_prop_key_t key); + ThreadError GetPropertyHandler_THREAD_ROUTER_SELECTION_JITTER(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_THREAD_CONTEXT_REUSE_DELAY(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_THREAD_NETWORK_ID_TIMEOUT(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_THREAD_ON_MESH_NETS(uint8_t header, spinel_prop_key_t key); @@ -391,6 +393,8 @@ private: ThreadError SetPropertyHandler_THREAD_MODE(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); ThreadError SetPropertyHandler_THREAD_CHILD_TIMEOUT(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); ThreadError SetPropertyHandler_THREAD_ROUTER_UPGRADE_THRESHOLD(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); + ThreadError SetPropertyHandler_THREAD_ROUTER_DOWNGRADE_THRESHOLD(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); + ThreadError SetPropertyHandler_THREAD_ROUTER_SELECTION_JITTER(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); ThreadError SetPropertyHandler_THREAD_CONTEXT_REUSE_DELAY(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); ThreadError SetPropertyHandler_THREAD_NETWORK_ID_TIMEOUT(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); diff --git a/src/ncp/spinel.c b/src/ncp/spinel.c index 7b7e78605..5626b3773 100644 --- a/src/ncp/spinel.c +++ b/src/ncp/spinel.c @@ -1140,6 +1140,14 @@ spinel_prop_key_to_cstr(spinel_prop_key_t prop_key) ret = "PROP_THREAD_ROUTER_UPGRADE_THRESHOLD"; break; + case SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD: + ret = "PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD"; + break; + + case SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER: + ret = "PROP_THREAD_ROUTER_SELECTION_JITTER"; + break; + case SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY: ret = "PROP_THREAD_CONTEXT_REUSE_DELAY"; break; diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h index 91655c828..2e0cbf1b9 100644 --- a/src/ncp/spinel.h +++ b/src/ncp/spinel.h @@ -508,6 +508,18 @@ typedef enum SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED = SPINEL_PROP_THREAD_EXT__BEGIN + 7, + /// Thread Router Downgrade Threshold + /** Format: `C` + */ + SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD + = SPINEL_PROP_THREAD_EXT__BEGIN + 8, + + /// Thread Router Selection Jitter + /** Format: `C` + */ + SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER + = SPINEL_PROP_THREAD_EXT__BEGIN + 9, + SPINEL_PROP_THREAD_EXT__END = 0x1600, SPINEL_PROP_IPV6__BEGIN = 0x60, diff --git a/tools/spinel-cli/spinel-cli.py b/tools/spinel-cli/spinel-cli.py index 7bab537c8..e13dde715 100755 --- a/tools/spinel-cli/spinel-cli.py +++ b/tools/spinel-cli/spinel-cli.py @@ -88,6 +88,7 @@ import shlex import base64 import textwrap import ipaddress +import binascii import logging import logging.config @@ -281,6 +282,9 @@ SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY = SPINEL_PROP_THREAD_EXT__BEGIN + 3 #< [L SPINEL_PROP_THREAD_NETWORK_ID_TIMEOUT = SPINEL_PROP_THREAD_EXT__BEGIN + 4 #< [b] SPINEL_PROP_THREAD_ACTIVE_ROUTER_IDS = SPINEL_PROP_THREAD_EXT__BEGIN + 5 #< [A(b)] SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU = SPINEL_PROP_THREAD_EXT__BEGIN + 6 #< [b] +SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED = SPINEL_PROP_THREAD_EXT__BEGIN + 7 #< [b] +SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD = SPINEL_PROP_THREAD_EXT__BEGIN + 8 #< [C] +SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER = SPINEL_PROP_THREAD_EXT__BEGIN + 9 #< [C] SPINEL_PROP_THREAD_EXT__END = 0x1600, @@ -515,6 +519,8 @@ def hexify_bytes(data): return str(map(hexify_chr,data)) def hexify_str(s,delim=':'): return delim.join(x.encode('hex') for x in s) +def pack_bytes(packet): return pack("%dB" % len(packet), *packet) + def asciify_int(i): return "%c" % (i) def hex_to_bytes(s): @@ -932,7 +938,7 @@ class SpinelPropertyHandler(SpinelCodec): prefixes = [] slaacPrefixSet = set() while (len(pay) >= 22): - (structlen) = unpack('>H', pay[:2]) + (structlen) = unpack(' masterkey 00112233445566778899aabbccddeeff Done """ - pass + self.handle_property(line, SPINEL_PROP_NET_MASTER_KEY, 'D') def do_mode(self, line): """ @@ -2639,6 +2661,26 @@ class SpinelCliCmd(Cmd, SpinelCodec): """ pass + + def do_routerselectionjitter(self, line): + """ + routerselectionjitter + + Get the ROUTER_SELECTION_JITTER value. + + > routerselectionjitter + 120 + Done + + routerselectionjitter + + Set the ROUTER_SELECTION_JITTER value. + + > routerselectionjitter 120 + Done + """ + self.handle_property(line, SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER) + def do_routerupgradethreshold(self, line): """ routerupgradethreshold @@ -2658,6 +2700,25 @@ class SpinelCliCmd(Cmd, SpinelCodec): """ self.handle_property(line, SPINEL_PROP_THREAD_ROUTER_UPGRADE_THRESHOLD) + def do_routerdowngradethreshold(self, line): + """ + routerdowngradethreshold + + Get the ROUTER_DOWNGRADE_THRESHOLD value. + + > routerdowngradethreshold + 16 + Done + + routerdowngradethreshold + + Set the ROUTER_DOWNGRADE_THRESHOLD value. + + > routerdowngradethreshold 16 + Done + """ + self.handle_property(line, SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD) + def do_scan(self, line): """ scan [channel]