diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 06429b0bc..86d7be69a 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -133,6 +133,7 @@ const NcpBase::GetPropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] = { SPINEL_PROP_MAC_WHITELIST, &NcpBase::GetPropertyHandler_MAC_WHITELIST }, { SPINEL_PROP_MAC_WHITELIST_ENABLED, &NcpBase::GetPropertyHandler_MAC_WHITELIST_ENABLED }, { SPINEL_PROP_THREAD_MODE, &NcpBase::GetPropertyHandler_THREAD_MODE }, + { SPINEL_PROP_THREAD_CHILD_COUNT_MAX, &NcpBase::GetPropertyHandler_THREAD_CHILD_COUNT_MAX }, { 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 }, @@ -230,6 +231,7 @@ const NcpBase::SetPropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] = { SPINEL_PROP_MAC_WHITELIST, &NcpBase::SetPropertyHandler_MAC_WHITELIST }, { SPINEL_PROP_MAC_WHITELIST_ENABLED, &NcpBase::SetPropertyHandler_MAC_WHITELIST_ENABLED }, { SPINEL_PROP_THREAD_MODE, &NcpBase::SetPropertyHandler_THREAD_MODE }, + { SPINEL_PROP_THREAD_CHILD_COUNT_MAX, &NcpBase::SetPropertyHandler_THREAD_CHILD_COUNT_MAX }, { 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 }, @@ -2619,6 +2621,17 @@ ThreadError NcpBase::GetPropertyHandler_THREAD_MODE(uint8_t header, spinel_prop_ ); } +ThreadError NcpBase::GetPropertyHandler_THREAD_CHILD_COUNT_MAX(uint8_t header, spinel_prop_key_t key) +{ + return SendPropertyUpdate( + header, + SPINEL_CMD_PROP_VALUE_IS, + key, + SPINEL_DATATYPE_UINT8_S, + otGetMaxAllowedChildren(mInstance) + ); +} + ThreadError NcpBase::GetPropertyHandler_THREAD_CHILD_TIMEOUT(uint8_t header, spinel_prop_key_t key) { return SendPropertyUpdate( @@ -3981,6 +3994,33 @@ ThreadError NcpBase::SetPropertyHandler_THREAD_MODE(uint8_t header, spinel_prop_ return errorCode; } +ThreadError NcpBase::SetPropertyHandler_THREAD_CHILD_COUNT_MAX(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len) +{ + uint8_t n = 0; + spinel_ssize_t parsedLength; + ThreadError errorCode = kThreadError_None; + + parsedLength = spinel_datatype_unpack( + value_ptr, + value_len, + SPINEL_DATATYPE_UINT8_S, + &n + ); + + if (parsedLength > 0) + { + otSetMaxAllowedChildren(mInstance, n); + + errorCode = HandleCommandPropertyGet(header, key); + } + else + { + errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR); + } + + return errorCode; +} + ThreadError NcpBase::SetPropertyHandler_THREAD_CHILD_TIMEOUT(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 f1d56ecc2..935fb18fe 100644 --- a/src/ncp/ncp_base.hpp +++ b/src/ncp/ncp_base.hpp @@ -333,6 +333,7 @@ private: ThreadError GetPropertyHandler_MAC_WHITELIST(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_MAC_WHITELIST_ENABLED(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_THREAD_MODE(uint8_t header, spinel_prop_key_t key); + ThreadError GetPropertyHandler_THREAD_CHILD_COUNT_MAX(uint8_t header, spinel_prop_key_t key); 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); @@ -395,6 +396,7 @@ private: ThreadError SetPropertyHandler_MAC_WHITELIST(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); ThreadError SetPropertyHandler_MAC_WHITELIST_ENABLED(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); 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_COUNT_MAX(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); diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h index 196722ed6..e8c7ba6c7 100644 --- a/src/ncp/spinel.h +++ b/src/ncp/spinel.h @@ -520,13 +520,13 @@ typedef enum /** Format: `C` */ SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER - = SPINEL_PROP_THREAD_EXT__BEGIN + 9, + = SPINEL_PROP_THREAD_EXT__BEGIN + 9, /// Thread Preferred Router Id /** Format: `C` - Write only */ SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID - = SPINEL_PROP_THREAD_EXT__BEGIN + 10, + = SPINEL_PROP_THREAD_EXT__BEGIN + 10, /// Thread Neighbor Table /** Format: `A(T(ESLCcCbLL))` @@ -534,6 +534,11 @@ typedef enum */ SPINEL_PROP_THREAD_NEIGHBOR_TABLE = SPINEL_PROP_THREAD_EXT__BEGIN + 11, + /// Thread Max Child Count + /** Format: `C` + */ + SPINEL_PROP_THREAD_CHILD_COUNT_MAX = SPINEL_PROP_THREAD_EXT__BEGIN + 12, + SPINEL_PROP_THREAD_EXT__END = 0x1600, SPINEL_PROP_IPV6__BEGIN = 0x60, diff --git a/tests/scripts/thread-cert/Cert_5_1_07_MaxChildCount.py b/tests/scripts/thread-cert/Cert_5_1_07_MaxChildCount.py index 650480cf8..e1b8fb2e1 100755 --- a/tests/scripts/thread-cert/Cert_5_1_07_MaxChildCount.py +++ b/tests/scripts/thread-cert/Cert_5_1_07_MaxChildCount.py @@ -52,6 +52,7 @@ class Cert_5_1_07_MaxChildCount(unittest.TestCase): self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64()) self.nodes[ROUTER].enable_whitelist() self.nodes[ROUTER].set_router_selection_jitter(1) + self.nodes[ROUTER].set_max_children(10) self.nodes[ED].set_panid(0xface) self.nodes[ED].set_mode('rsn') diff --git a/tests/scripts/thread-cert/node.py b/tests/scripts/thread-cert/node.py index 6d9c743f5..70c2c8d55 100755 --- a/tests/scripts/thread-cert/node.py +++ b/tests/scripts/thread-cert/node.py @@ -345,6 +345,11 @@ class Node: self.send_command(cmd) self.pexpect.expect('Done') + def set_max_children(self, number): + cmd = 'childmax %d' % number + self.send_command(cmd) + self.pexpect.expect('Done') + def get_weight(self): self.send_command('leaderweight') i = self.pexpect.expect('(\d+)\r\n') diff --git a/tools/spinel-cli/spinel-cli.py b/tools/spinel-cli/spinel-cli.py index 874c57f3c..7d0aae31c 100755 --- a/tools/spinel-cli/spinel-cli.py +++ b/tools/spinel-cli/spinel-cli.py @@ -31,20 +31,21 @@ spinel-cli.py available commands (type help for more information): ============================================================ -channel diag-sleep keysequence q -child diag-start leaderdata quit -childtimeout diag-stats leaderweight releaserouterid -clear diag-stop masterkey rloc16 -commissioner discover mode route -contextreusedelay eidcache ncp-ll64 router -counter exit ncp-ml64 routerupgradethreshold -debug extaddr ncp-tun scan -debug-mem extpanid netdataregister state -diag h networkidtimeout thread -diag-channel help networkname tun -diag-power history panid v -diag-repeat ifconfig ping version -diag-send ipaddr prefix whitelist +channel diag-sleep leaderdata releaserouterid +child diag-start leaderweight rloc16 +childmax diag-stats masterkey route +childtimeout diag-stop mode router +clear discover ncp-ll64 routerupgradethreshold +commissioner eidcache ncp-ml64 scan +contextreusedelay exit ncp-tun state +counter extaddr netdataregister thread +debug extpanid networkidtimeout tun +debug-mem h networkname v +diag help panid version +diag-channel history ping whitelist +diag-power ifconfig prefix +diag-repeat ipaddr q +diag-send keysequence quit """ from __future__ import print_function @@ -146,6 +147,7 @@ class SpinelCliCmd(Cmd, SpinelCodec): 'help', 'channel', 'child', + 'childmax', 'childtimeout', 'commissioner', 'contextreusedelay', @@ -481,6 +483,26 @@ class SpinelCliCmd(Cmd, SpinelCodec): """ pass + def do_childmax(self, line): + """\033[1m + childmax + \033[0m + Get the Thread Child Count Max value. + \033[2m + > childmax + 10 + Done + \033[0m\033[1m + childmax + \033[0m + Set the Thread Child Count Max value. + \033[2m + > childmax 5 + Done + \033[0m + """ + self.handle_property(line, SPINEL.PROP_THREAD_CHILD_COUNT_MAX) + def do_childtimeout(self, line): """\033[1m childtimeout diff --git a/tools/spinel-cli/spinel/codec.py b/tools/spinel-cli/spinel/codec.py index 12102e121..304f4af92 100644 --- a/tools/spinel-cli/spinel/codec.py +++ b/tools/spinel-cli/spinel/codec.py @@ -484,6 +484,8 @@ class SpinelPropertyHandler(SpinelCodec): def THREAD_MODE(self, _, payload): return self.parse_C(payload) + def THREAD_CHILD_COUNT_MAX(self, _, payload): return self.parse_C(payload) + def THREAD_CHILD_TIMEOUT(self, _, payload): return self.parse_L(payload) def THREAD_RLOC16(self, _, payload): return self.parse_S(payload) @@ -681,6 +683,7 @@ SPINEL_PROP_DISPATCH = { SPINEL.PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE: WPAN_PROP_HANDLER.THREAD_ALLOW_LOCAL_NET_DATA_CHANGE, SPINEL.PROP_THREAD_MODE: WPAN_PROP_HANDLER.THREAD_MODE, + SPINEL.PROP_THREAD_CHILD_COUNT_MAX: WPAN_PROP_HANDLER.THREAD_CHILD_COUNT_MAX, SPINEL.PROP_THREAD_CHILD_TIMEOUT: WPAN_PROP_HANDLER.THREAD_CHILD_TIMEOUT, SPINEL.PROP_THREAD_RLOC16: WPAN_PROP_HANDLER.THREAD_RLOC16, SPINEL.PROP_THREAD_ROUTER_UPGRADE_THRESHOLD: WPAN_PROP_HANDLER.THREAD_ROUTER_UPGRADE_THRESHOLD, diff --git a/tools/spinel-cli/spinel/const.py b/tools/spinel-cli/spinel/const.py index 5355695b6..00aea278d 100644 --- a/tools/spinel-cli/spinel/const.py +++ b/tools/spinel-cli/spinel/const.py @@ -164,6 +164,9 @@ class SPINEL(object): PROP_THREAD_ROUTER_ROLE_ENABLED = PROP_THREAD_EXT__BEGIN + 7 # < [b] PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD = PROP_THREAD_EXT__BEGIN + 8 # < [C] PROP_THREAD_ROUTER_SELECTION_JITTER = PROP_THREAD_EXT__BEGIN + 9 # < [C] + PROP_THREAD_PREFERRED_ROUTER_ID = PROP_THREAD_EXT__BEGIN + 10 # < [C] + PROP_THREAD_NEIGHBOR_TABLE = PROP_THREAD_EXT__BEGIN + 11 # < [A(T(ESLCcCbLL))] + PROP_THREAD_CHILD_COUNT_MAX = PROP_THREAD_EXT__BEGIN + 12 # < [C] PROP_THREAD_EXT__END = 0x1600