From aaf5a57ea27302c2683cbf576d1b10483b0ede49 Mon Sep 17 00:00:00 2001 From: rongli Date: Mon, 17 Oct 2016 13:49:31 +0800 Subject: [PATCH] Cli: update 'keysequence' to make keyswithguardtime configurable (#815) * Cli: update 'keysequence' to make keyswithguardtime configurable --- doc/draft-spinel-protocol.html | 25 +++++++-- doc/draft-spinel-protocol.txt | 16 ++++-- .../spinel-example-sessions.md | 7 ++- doc/spinel-protocol-src/spinel-prop-net.md | 5 +- include/openthread-types.h | 2 +- include/openthread.h | 22 ++++++++ src/cli/README.md | 32 +++++++++-- src/cli/cli.cpp | 27 +++++++-- src/core/openthread.cpp | 10 ++++ src/core/thread/key_manager.cpp | 15 ++--- src/ncp/ncp_base.cpp | 55 ++++++++++++++++--- src/ncp/ncp_base.hpp | 7 ++- src/ncp/spinel.c | 8 ++- src/ncp/spinel.h | 6 +- .../Cert_5_8_01_KeySynchronization.py | 6 +- .../thread-cert/Cert_5_8_02_KeyIncrement.py | 6 +- .../Cert_5_8_03_KeyIncrementRollOver.py | 8 ++- .../thread-cert/Cert_6_6_01_KeyIncrement.py | 6 +- .../Cert_6_6_02_KeyIncrementRollOver.py | 8 ++- tests/scripts/thread-cert/node.py | 17 ++++-- tools/harness-thci/ARM.py | 27 ++++++++- tools/spinel-cli/spinel-cli.py | 38 ++++++++++--- tools/spinel-cli/spinel/codec.py | 7 ++- tools/spinel-cli/spinel/const.py | 3 +- tools/spinel-cli/spinel/test_codec.py | 2 +- 25 files changed, 289 insertions(+), 76 deletions(-) diff --git a/doc/draft-spinel-protocol.html b/doc/draft-spinel-protocol.html index 37113e74f..13067ffa5 100644 --- a/doc/draft-spinel-protocol.html +++ b/doc/draft-spinel-protocol.html @@ -451,8 +451,9 @@ - + + @@ -689,8 +690,9 @@
  • 5.6.5. PROP 68: PROP_NET_NETWORK_NAME
  • 5.6.6. PROP 69: PROP_NET_XPANID
  • 5.6.7. PROP 70: PROP_NET_MASTER_KEY
  • -
  • 5.6.8. PROP 71: PROP_NET_KEY_SEQUENCE
  • +
  • 5.6.8. PROP 71: PROP_NET_KEY_SEQUENCE_COUNTER
  • 5.6.9. PROP 72: PROP_NET_PARTITION_ID
  • +
  • 5.6.10. PROP 73: PROP_NET_KEY_SWITCH_GUARDTIME
  • 5.7. IPv6 Properties
  • -

    5.6.8. PROP 71: PROP_NET_KEY_SEQUENCE

    +

    5.6.8. PROP 71: PROP_NET_KEY_SEQUENCE_COUNTER

    diff --git a/doc/draft-spinel-protocol.txt b/doc/draft-spinel-protocol.txt index 4d2e6d02d..118c4cbbe 100644 --- a/doc/draft-spinel-protocol.txt +++ b/doc/draft-spinel-protocol.txt @@ -152,8 +152,9 @@ Quattlebaum Expires April 14, 2017 [Page 2] 5.6.5. PROP 68: PROP_NET_NETWORK_NAME . . . . . . . . . . . 35 5.6.6. PROP 69: PROP_NET_XPANID . . . . . . . . . . . . . . 35 5.6.7. PROP 70: PROP_NET_MASTER_KEY . . . . . . . . . . . . 35 - 5.6.8. PROP 71: PROP_NET_KEY_SEQUENCE . . . . . . . . . . . 35 + 5.6.8. PROP 71: PROP_NET_KEY_SEQUENCE_COUNTER. . . . . . . . 35 5.6.9. PROP 72: PROP_NET_PARTITION_ID . . . . . . . . . . . 35 + 5.6.10. PROP 73: PROP_NET_KEY_SWITCH_GUARDTIME . . . . . . . 35 5.7. IPv6 Properties . . . . . . . . . . . . . . . . . . . . . 35 5.7.1. PROP 96: PROP_IPV6_LL_ADDR . . . . . . . . . . . . . 35 5.7.2. PROP 97: PROP_IPV6_ML_ADDR . . . . . . . . . . . . . 36 @@ -1934,7 +1935,7 @@ Quattlebaum Expires April 14, 2017 [Page 34] o Type: Read-Write o Packed-Encoding: "D" -5.6.8. PROP 71: PROP_NET_KEY_SEQUENCE +5.6.8. PROP 71: PROP_NET_KEY_SEQUENCE_COUNTER o Type: Read-Write o Packed-Encoding: "L" @@ -1946,6 +1947,11 @@ Quattlebaum Expires April 14, 2017 [Page 34] The partition ID of the partition that this node is a member of. +5.6.10. PROP 73: PROP_NET_KEY_SWITCH_GUARDTIME + + o Type: Read-Write + o Packed-Encoding: "L" + 5.7. IPv6 Properties 5.7.1. PROP 96: PROP_IPV6_LL_ADDR @@ -3103,8 +3109,10 @@ F.2. Attaching to a network o CMD_VALUE_IS:PROP_NET_NETWORK_NAME o CMD_VALUE_SET:PROP_NET_MASTER_KEY o CMD_VALUE_IS:PROP_NET_MASTER_KEY - o CMD_VALUE_SET:PROP_NET_KEY_SEQUENCE - o CMD_VALUE_IS:PROP_NET_KEY_SEQUENCE + o CMD_VALUE_SET:PROP_NET_KEY_SEQUENCE_COUNTER + o CMD_VALUE_IS:PROP_NET_KEY_SEQUENCE_COUNTER + o CMD_VALUE_SET:PROP_NET_KEY_SWITCH_GUARDTIME + o CMD_VALUE_IS:PROP_NET_KEY_SWITCH_GUARDTIME Bring the network interface up: diff --git a/doc/spinel-protocol-src/spinel-example-sessions.md b/doc/spinel-protocol-src/spinel-example-sessions.md index 53223c8d5..4141c6774 100644 --- a/doc/spinel-protocol-src/spinel-example-sessions.md +++ b/doc/spinel-protocol-src/spinel-example-sessions.md @@ -59,8 +59,11 @@ Set the network properties, if they were not already set: * CMD_VALUE_SET:PROP_NET_MASTER_KEY * CMD_VALUE_IS:PROP_NET_MASTER_KEY -* CMD_VALUE_SET:PROP_NET_KEY_SEQUENCE -* CMD_VALUE_IS:PROP_NET_KEY_SEQUENCE +* CMD_VALUE_SET:PROP_NET_KEY_SEQUENCE_COUNTER +* CMD_VALUE_IS:PROP_NET_KEY_SEQUENCE_COUNTER + +* CMD_VALUE_SET:PROP_NET_KEY_SWITCH_GUARDTIME +* CMD_VALUE_IS:PROP_NET_KEY_SWITCH_GUARDTIME Bring the network interface up: diff --git a/doc/spinel-protocol-src/spinel-prop-net.md b/doc/spinel-protocol-src/spinel-prop-net.md index 91ca21022..a815ef598 100644 --- a/doc/spinel-protocol-src/spinel-prop-net.md +++ b/doc/spinel-protocol-src/spinel-prop-net.md @@ -46,7 +46,7 @@ Values: * Type: Read-Write * Packed-Encoding: `D` -### PROP 71: PROP_NET_KEY_SEQUENCE {#prop-net-key-sequence} +### PROP 71: PROP_NET_KEY_SEQUENCE_COUNTER {#prop-net-key-sequence-counter} * Type: Read-Write * Packed-Encoding: `L` @@ -56,5 +56,8 @@ Values: The partition ID of the partition that this node is a member of. +### PROP 73: PROP_NET_KEY_SWITCH_GUARDTIME {#prop-net-key-swtich-guardtime} +* Type: Read-Write +* Packed-Encoding: `L` diff --git a/include/openthread-types.h b/include/openthread-types.h index 8a1e4151d..b94af44db 100644 --- a/include/openthread-types.h +++ b/include/openthread-types.h @@ -514,7 +514,7 @@ enum OT_NET_ROLE = 1 << 3, ///< Device role (disabled, detached, child, router, leader) changed OT_NET_PARTITION_ID = 1 << 4, ///< Partition ID changed - OT_NET_KEY_SEQUENCE = 1 << 5, ///< Thread Key Sequence changed + OT_NET_KEY_SEQUENCE_COUNTER = 1 << 5, ///< Thread Key Sequence changed OT_THREAD_CHILD_ADDED = 1 << 6, ///< Child was added OT_THREAD_CHILD_REMOVED = 1 << 7, ///< Child was removed diff --git a/include/openthread.h b/include/openthread.h index 4464f42ec..9020fcc1b 100644 --- a/include/openthread.h +++ b/include/openthread.h @@ -1283,6 +1283,28 @@ uint32_t otGetKeySequenceCounter(otInstance *aInstance); */ void otSetKeySequenceCounter(otInstance *aInstance, uint32_t aKeySequenceCounter); +/** + * Get the thrKeySwitchGuardTime + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @returns The thrKeySwitchGuardTime value (in hours). + * + * @sa otSetKeySwitchGuardTime + */ +uint32_t otGetKeySwitchGuardTime(otInstance *aInstance); + +/** + * Set the thrKeySwitchGuardTime + * + * @param[in] aInstance A pointer to an OpenThread instance. + * @param[in] aKeySwitchGuardTime The thrKeySwitchGuardTime value (in hours). + * + * @sa otGetKeySwitchGuardTime + */ +void otSetKeySwitchGuardTime(otInstance *aInstance, uint32_t aKeySwitchGuardTime); + + /** * Get the NETWORK_ID_TIMEOUT parameter used in the Router role. * diff --git a/src/cli/README.md b/src/cli/README.md index 686bdd38e..71181daf2 100644 --- a/src/cli/README.md +++ b/src/cli/README.md @@ -804,22 +804,42 @@ Stop the Joiner role. Done ``` -### keysequence +### keysequence counter -Get the Thread Key Sequence. +Get the Thread Key Sequence Counter. ```bash -> keysequence +> keysequence counter 10 Done ``` -### keysequence \ +### keysequence counter \ -Set the Thread Key Sequence. +Set the Thread Key Sequence Counter. ```bash -> keysequence 10 +> keysequence counter 10 +Done +``` + +### keysequence guardtime + +Get Thread Key Switch Guard Time (in hours) + +```bash +> keysequence guardtime +0 +Done +``` + +### keysequence guardtime \ + +Set Thread Key Switch Guard Time (in hours) +0 means Thread Key Switch imediately if key index match + +```bash +> keysequence guardtime 0 Done ``` diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index a078a44ab..aad3f9e05 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -765,14 +765,31 @@ void Interpreter::ProcessKeySequence(int argc, char *argv[]) ThreadError error = kThreadError_None; long value; - if (argc == 0) + VerifyOrExit(argc == 1 || argc == 2, error = kThreadError_Parse); + + if (strcmp(argv[0], "counter") == 0) { - sServer->OutputFormat("%d\r\n", otGetKeySequenceCounter(mInstance)); + if (argc == 1) + { + sServer->OutputFormat("%d\r\n", otGetKeySequenceCounter(mInstance)); + } + else + { + SuccessOrExit(error = ParseLong(argv[1], value)); + otSetKeySequenceCounter(mInstance, static_cast(value)); + } } - else + else if (strcmp(argv[0], "guardtime") == 0) { - SuccessOrExit(error = ParseLong(argv[0], value)); - otSetKeySequenceCounter(mInstance, static_cast(value)); + if (argc == 1) + { + sServer->OutputFormat("%d\r\n", otGetKeySwitchGuardTime(mInstance)); + } + else + { + SuccessOrExit(error = ParseLong(argv[1], value)); + otSetKeySwitchGuardTime(mInstance, static_cast(value)); + } } exit: diff --git a/src/core/openthread.cpp b/src/core/openthread.cpp index b81dc2b18..4ec6a90e3 100644 --- a/src/core/openthread.cpp +++ b/src/core/openthread.cpp @@ -497,6 +497,16 @@ void otSetKeySequenceCounter(otInstance *aInstance, uint32_t aKeySequenceCounter aInstance->mThreadNetif.GetKeyManager().SetCurrentKeySequence(aKeySequenceCounter); } +uint32_t otGetKeySwitchGuardTime(otInstance *aInstance) +{ + return aInstance->mThreadNetif.GetKeyManager().GetKeySwitchGuardTime(); +} + +void otSetKeySwitchGuardTime(otInstance *aInstance, uint32_t aKeySwitchGuardTime) +{ + aInstance->mThreadNetif.GetKeyManager().SetKeySwitchGuardTime(aKeySwitchGuardTime); +} + uint8_t otGetNetworkIdTimeout(otInstance *aInstance) { return aInstance->mThreadNetif.GetMle().GetNetworkIdTimeout(); diff --git a/src/core/thread/key_manager.cpp b/src/core/thread/key_manager.cpp index bebde4519..577bbe68d 100644 --- a/src/core/thread/key_manager.cpp +++ b/src/core/thread/key_manager.cpp @@ -92,7 +92,7 @@ ThreadError KeyManager::SetMasterKey(const void *aKey, uint8_t aKeyLength) mKeySequence = 0; ComputeKey(mKeySequence, mKey); - mNetif.SetStateChangedFlags(OT_NET_KEY_SEQUENCE); + mNetif.SetStateChangedFlags(OT_NET_KEY_SEQUENCE_COUNTER); exit: return error; @@ -124,10 +124,6 @@ uint32_t KeyManager::GetCurrentKeySequence(void) const void KeyManager::SetCurrentKeySequence(uint32_t aKeySequence) { - uint32_t now; - uint32_t guardStartTimestamp; - uint32_t guardEndTimestamp; - if (aKeySequence == mKeySequence) { ExitNow(); @@ -135,12 +131,13 @@ void KeyManager::SetCurrentKeySequence(uint32_t aKeySequence) // Check if the guard timer has expired if key rotation is requested. if ((aKeySequence == (mKeySequence + 1)) && + (mKeySwitchGuardTime != 0) && mKeyRotationTimer.IsRunning() && mKeySwitchGuardEnabled) { - now = Timer::GetNow(); - guardStartTimestamp = mKeyRotationTimer.Gett0(); - guardEndTimestamp = guardStartTimestamp + Timer::HoursToMsec(mKeySwitchGuardTime); + uint32_t now = Timer::GetNow(); + uint32_t guardStartTimestamp = mKeyRotationTimer.Gett0(); + uint32_t guardEndTimestamp = guardStartTimestamp + Timer::HoursToMsec(mKeySwitchGuardTime); // Check for timer overflow if (guardEndTimestamp < mKeyRotationTimer.Gett0()) @@ -171,7 +168,7 @@ void KeyManager::SetCurrentKeySequence(uint32_t aKeySequence) mKeyRotationTimer.Start(Timer::HoursToMsec(mKeyRotationTime)); } - mNetif.SetStateChangedFlags(OT_NET_KEY_SEQUENCE); + mNetif.SetStateChangedFlags(OT_NET_KEY_SEQUENCE_COUNTER); exit: return; diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index dba8f6d58..9b96625f6 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -110,8 +110,9 @@ const NcpBase::GetPropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] = { SPINEL_PROP_NET_NETWORK_NAME, &NcpBase::GetPropertyHandler_NET_NETWORK_NAME }, { SPINEL_PROP_NET_XPANID, &NcpBase::GetPropertyHandler_NET_XPANID }, { SPINEL_PROP_NET_MASTER_KEY, &NcpBase::GetPropertyHandler_NET_MASTER_KEY }, - { SPINEL_PROP_NET_KEY_SEQUENCE, &NcpBase::GetPropertyHandler_NET_KEY_SEQUENCE }, + { SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER, &NcpBase::GetPropertyHandler_NET_KEY_SEQUENCE_COUNTER }, { SPINEL_PROP_NET_PARTITION_ID, &NcpBase::GetPropertyHandler_NET_PARTITION_ID }, + { SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME, &NcpBase::GetPropertyHandler_NET_KEY_SWITCH_GUARDTIME}, { SPINEL_PROP_THREAD_LEADER_ADDR, &NcpBase::GetPropertyHandler_THREAD_LEADER_ADDR }, { SPINEL_PROP_THREAD_PARENT, &NcpBase::GetPropertyHandler_THREAD_PARENT }, @@ -210,7 +211,8 @@ const NcpBase::SetPropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] = { SPINEL_PROP_NET_NETWORK_NAME, &NcpBase::SetPropertyHandler_NET_NETWORK_NAME }, { SPINEL_PROP_NET_XPANID, &NcpBase::SetPropertyHandler_NET_XPANID }, { SPINEL_PROP_NET_MASTER_KEY, &NcpBase::SetPropertyHandler_NET_MASTER_KEY }, - { SPINEL_PROP_NET_KEY_SEQUENCE, &NcpBase::SetPropertyHandler_NET_KEY_SEQUENCE }, + { SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER, &NcpBase::SetPropertyHandler_NET_KEY_SEQUENCE_COUNTER }, + { SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME, &NcpBase::SetPropertyHandler_NET_KEY_SWITCH_GUARDTIME}, { SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT, &NcpBase::SetPropertyHandler_THREAD_LOCAL_LEADER_WEIGHT }, { SPINEL_PROP_THREAD_ASSISTING_PORTS, &NcpBase::SetPropertyHandler_THREAD_ASSISTING_PORTS }, @@ -782,13 +784,13 @@ void NcpBase::UpdateChangedProps(void) )); mChangedFlags &= ~static_cast(OT_NET_PARTITION_ID); } - else if ((mChangedFlags & OT_NET_KEY_SEQUENCE) != 0) + else if ((mChangedFlags & OT_NET_KEY_SEQUENCE_COUNTER) != 0) { SuccessOrExit(HandleCommandPropertyGet( SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, - SPINEL_PROP_NET_KEY_SEQUENCE + SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER )); - mChangedFlags &= ~static_cast(OT_NET_KEY_SEQUENCE); + mChangedFlags &= ~static_cast(OT_NET_KEY_SEQUENCE_COUNTER); } else if ((mChangedFlags & (OT_IP6_ADDRESS_ADDED | OT_IP6_ADDRESS_REMOVED)) != 0) { @@ -1756,7 +1758,7 @@ ThreadError NcpBase::GetPropertyHandler_NET_MASTER_KEY(uint8_t header, spinel_pr ); } -ThreadError NcpBase::GetPropertyHandler_NET_KEY_SEQUENCE(uint8_t header, spinel_prop_key_t key) +ThreadError NcpBase::GetPropertyHandler_NET_KEY_SEQUENCE_COUNTER(uint8_t header, spinel_prop_key_t key) { return SendPropertyUpdate( header, @@ -1778,6 +1780,17 @@ ThreadError NcpBase::GetPropertyHandler_NET_PARTITION_ID(uint8_t header, spinel_ ); } +ThreadError NcpBase::GetPropertyHandler_NET_KEY_SWITCH_GUARDTIME(uint8_t header, spinel_prop_key_t key) +{ + return SendPropertyUpdate( + header, + SPINEL_CMD_PROP_VALUE_IS, + key, + SPINEL_DATATYPE_UINT32_S, + otGetKeySwitchGuardTime(mInstance) + ); +} + ThreadError NcpBase::GetPropertyHandler_THREAD_NETWORK_DATA_VERSION(uint8_t header, spinel_prop_key_t key) { return SendPropertyUpdate( @@ -3309,7 +3322,7 @@ ThreadError NcpBase::SetPropertyHandler_NET_MASTER_KEY(uint8_t header, spinel_pr return errorCode; } -ThreadError NcpBase::SetPropertyHandler_NET_KEY_SEQUENCE(uint8_t header, spinel_prop_key_t key, +ThreadError NcpBase::SetPropertyHandler_NET_KEY_SEQUENCE_COUNTER(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len) { @@ -3337,6 +3350,34 @@ ThreadError NcpBase::SetPropertyHandler_NET_KEY_SEQUENCE(uint8_t header, spinel_ return errorCode; } +ThreadError NcpBase::SetPropertyHandler_NET_KEY_SWITCH_GUARDTIME(uint8_t header, spinel_prop_key_t key, + const uint8_t *value_ptr, + uint16_t value_len) +{ + unsigned int i(0); + spinel_ssize_t parsedLength; + ThreadError errorCode = kThreadError_None; + + parsedLength = spinel_datatype_unpack( + value_ptr, + value_len, + SPINEL_DATATYPE_UINT32_S, + &i + ); + + if (parsedLength > 0) + { + otSetKeySwitchGuardTime(mInstance, i); + errorCode = HandleCommandPropertyGet(header, key); + } + else + { + errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR); + } + + return errorCode; +} + ThreadError NcpBase::SetPropertyHandler_THREAD_LOCAL_LEADER_WEIGHT(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len) { diff --git a/src/ncp/ncp_base.hpp b/src/ncp/ncp_base.hpp index c7a0a7d56..f1d56ecc2 100644 --- a/src/ncp/ncp_base.hpp +++ b/src/ncp/ncp_base.hpp @@ -298,8 +298,9 @@ private: ThreadError GetPropertyHandler_NET_NETWORK_NAME(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_NET_XPANID(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_NET_MASTER_KEY(uint8_t header, spinel_prop_key_t key); - ThreadError GetPropertyHandler_NET_KEY_SEQUENCE(uint8_t header, spinel_prop_key_t key); + ThreadError GetPropertyHandler_NET_KEY_SEQUENCE_COUNTER(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_NET_PARTITION_ID(uint8_t header, spinel_prop_key_t key); + ThreadError GetPropertyHandler_NET_KEY_SWITCH_GUARDTIME(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_THREAD_LEADER(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_IPV6_ML_PREFIX(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_IPV6_ML_ADDR(uint8_t header, spinel_prop_key_t key); @@ -368,7 +369,9 @@ private: uint16_t value_len); ThreadError SetPropertyHandler_NET_MASTER_KEY(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); - ThreadError SetPropertyHandler_NET_KEY_SEQUENCE(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, + ThreadError SetPropertyHandler_NET_KEY_SEQUENCE_COUNTER(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, + uint16_t value_len); + ThreadError SetPropertyHandler_NET_KEY_SWITCH_GUARDTIME(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); ThreadError SetPropertyHandler_STREAM_NET_INSECURE(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 21924ec4c..cc5463916 100644 --- a/src/ncp/spinel.c +++ b/src/ncp/spinel.c @@ -1028,14 +1028,18 @@ spinel_prop_key_to_cstr(spinel_prop_key_t prop_key) ret = "PROP_NET_MASTER_KEY"; break; - case SPINEL_PROP_NET_KEY_SEQUENCE: - ret = "PROP_NET_KEY_SEQUENCE"; + case SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER: + ret = "PROP_NET_KEY_SEQUENCE_COUNTER"; break; case SPINEL_PROP_NET_PARTITION_ID: ret = "PROP_NET_PARTITION_ID"; break; + case SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME: + ret = "PROP_NET_KEY_SWITCH_GUARDTIME"; + break; + case SPINEL_PROP_THREAD_LEADER_ADDR: ret = "PROP_THREAD_LEADER_ADDR"; break; diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h index 9e14a8f8b..196722ed6 100644 --- a/src/ncp/spinel.h +++ b/src/ncp/spinel.h @@ -394,7 +394,8 @@ typedef enum SPINEL_PROP_NET_NETWORK_NAME = SPINEL_PROP_NET__BEGIN + 4, ///< [U] SPINEL_PROP_NET_XPANID = SPINEL_PROP_NET__BEGIN + 5, ///< [D] SPINEL_PROP_NET_MASTER_KEY = SPINEL_PROP_NET__BEGIN + 6, ///< [D] - SPINEL_PROP_NET_KEY_SEQUENCE = SPINEL_PROP_NET__BEGIN + 7, ///< [L] + SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER + = SPINEL_PROP_NET__BEGIN + 7, ///< [L] SPINEL_PROP_NET_PARTITION_ID = SPINEL_PROP_NET__BEGIN + 8, ///< [L] /// Require Join Existing @@ -418,6 +419,9 @@ typedef enum SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING = SPINEL_PROP_NET__BEGIN + 9, + SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME + = SPINEL_PROP_NET__BEGIN + 10, ///< [L] + SPINEL_PROP_NET__END = 0x50, SPINEL_PROP_THREAD__BEGIN = 0x50, diff --git a/tests/scripts/thread-cert/Cert_5_8_01_KeySynchronization.py b/tests/scripts/thread-cert/Cert_5_8_01_KeySynchronization.py index 677ec8481..8857bdbc1 100755 --- a/tests/scripts/thread-cert/Cert_5_8_01_KeySynchronization.py +++ b/tests/scripts/thread-cert/Cert_5_8_01_KeySynchronization.py @@ -45,11 +45,13 @@ class Cert_5_8_1_KeySynchronization(unittest.TestCase): self.nodes[LEADER].set_mode('rsdn') self.nodes[LEADER].add_whitelist(self.nodes[ED].get_addr64()) self.nodes[LEADER].enable_whitelist() + self.nodes[LEADER].set_key_switch_guardtime(0) self.nodes[ED].set_panid(0xface) self.nodes[ED].set_mode('rsn') self.nodes[ED].add_whitelist(self.nodes[LEADER].get_addr64()) self.nodes[ED].enable_whitelist() + self.nodes[ED].set_key_switch_guardtime(0) def tearDown(self): for node in list(self.nodes.values()): @@ -70,8 +72,8 @@ class Cert_5_8_1_KeySynchronization(unittest.TestCase): if 'ff:fe00' not in addr: self.assertTrue(self.nodes[ED].ping(addr)) - key_sequence = self.nodes[ED].get_key_sequence() - self.nodes[ED].set_key_sequence(key_sequence + 10) + key_sequence_counter = self.nodes[ED].get_key_sequence_counter() + self.nodes[ED].set_key_sequence_counter(key_sequence_counter + 10) addrs = self.nodes[LEADER].get_addrs() for addr in addrs: diff --git a/tests/scripts/thread-cert/Cert_5_8_02_KeyIncrement.py b/tests/scripts/thread-cert/Cert_5_8_02_KeyIncrement.py index f99e4af5e..3684dcd62 100755 --- a/tests/scripts/thread-cert/Cert_5_8_02_KeyIncrement.py +++ b/tests/scripts/thread-cert/Cert_5_8_02_KeyIncrement.py @@ -44,12 +44,14 @@ class Cert_5_8_2_KeyIncrement(unittest.TestCase): self.nodes[LEADER].set_panid(0xface) self.nodes[LEADER].set_mode('rsdn') self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64()) + self.nodes[LEADER].set_key_switch_guardtime(0) self.nodes[LEADER].enable_whitelist() self.nodes[ROUTER].set_panid(0xface) self.nodes[ROUTER].set_mode('rsdn') self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64()) self.nodes[ROUTER].enable_whitelist() + self.nodes[ROUTER].set_key_switch_guardtime(0) self.nodes[ROUTER].set_router_selection_jitter(1) def tearDown(self): @@ -69,8 +71,8 @@ class Cert_5_8_2_KeyIncrement(unittest.TestCase): for addr in addrs: self.assertTrue(self.nodes[LEADER].ping(addr)) - key_sequence = self.nodes[LEADER].get_key_sequence() - self.nodes[LEADER].set_key_sequence(key_sequence + 1) + key_sequence_counter = self.nodes[LEADER].get_key_sequence_counter() + self.nodes[LEADER].set_key_sequence_counter(key_sequence_counter + 1) addrs = self.nodes[ROUTER].get_addrs() for addr in addrs: diff --git a/tests/scripts/thread-cert/Cert_5_8_03_KeyIncrementRollOver.py b/tests/scripts/thread-cert/Cert_5_8_03_KeyIncrementRollOver.py index c9440992d..5bf7b1dbf 100755 --- a/tests/scripts/thread-cert/Cert_5_8_03_KeyIncrementRollOver.py +++ b/tests/scripts/thread-cert/Cert_5_8_03_KeyIncrementRollOver.py @@ -45,12 +45,14 @@ class Cert_5_8_3_KeyIncrementRollOver(unittest.TestCase): self.nodes[LEADER].set_mode('rsdn') self.nodes[LEADER].add_whitelist(self.nodes[ROUTER].get_addr64()) self.nodes[LEADER].enable_whitelist() - self.nodes[LEADER].set_key_sequence(127) + self.nodes[LEADER].set_key_switch_guardtime(0) + self.nodes[LEADER].set_key_sequence_counter(127) self.nodes[ROUTER].set_panid(0xface) self.nodes[ROUTER].set_mode('rsdn') self.nodes[ROUTER].add_whitelist(self.nodes[LEADER].get_addr64()) self.nodes[ROUTER].enable_whitelist() + self.nodes[ROUTER].set_key_switch_guardtime(0) self.nodes[ROUTER].set_router_selection_jitter(1) def tearDown(self): @@ -71,8 +73,8 @@ class Cert_5_8_3_KeyIncrementRollOver(unittest.TestCase): for addr in addrs: self.assertTrue(self.nodes[LEADER].ping(addr)) - key_sequence = self.nodes[LEADER].get_key_sequence() - self.nodes[LEADER].set_key_sequence(key_sequence + 1) + key_sequence_counter = self.nodes[LEADER].get_key_sequence_counter() + self.nodes[LEADER].set_key_sequence_counter(key_sequence_counter + 1) addrs = self.nodes[ROUTER].get_addrs() for addr in addrs: diff --git a/tests/scripts/thread-cert/Cert_6_6_01_KeyIncrement.py b/tests/scripts/thread-cert/Cert_6_6_01_KeyIncrement.py index b59a79731..d2d1359df 100755 --- a/tests/scripts/thread-cert/Cert_6_6_01_KeyIncrement.py +++ b/tests/scripts/thread-cert/Cert_6_6_01_KeyIncrement.py @@ -45,11 +45,13 @@ class Cert_6_6_1_KeyIncrement(unittest.TestCase): self.nodes[LEADER].set_mode('rsdn') self.nodes[LEADER].add_whitelist(self.nodes[ED].get_addr64()) self.nodes[LEADER].enable_whitelist() + self.nodes[LEADER].set_key_switch_guardtime(0) self.nodes[ED].set_panid(0xface) self.nodes[ED].set_mode('rsn') self.nodes[ED].add_whitelist(self.nodes[LEADER].get_addr64()) self.nodes[ED].enable_whitelist() + self.nodes[ED].set_key_switch_guardtime(0) def tearDown(self): for node in list(self.nodes.values()): @@ -68,8 +70,8 @@ class Cert_6_6_1_KeyIncrement(unittest.TestCase): for addr in addrs: self.assertTrue(self.nodes[LEADER].ping(addr)) - key_sequence = self.nodes[LEADER].get_key_sequence() - self.nodes[LEADER].set_key_sequence(key_sequence + 1) + key_sequence_counter = self.nodes[LEADER].get_key_sequence_counter() + self.nodes[LEADER].set_key_sequence_counter(key_sequence_counter + 1) addrs = self.nodes[ED].get_addrs() for addr in addrs: diff --git a/tests/scripts/thread-cert/Cert_6_6_02_KeyIncrementRollOver.py b/tests/scripts/thread-cert/Cert_6_6_02_KeyIncrementRollOver.py index c0d625b2b..ec3957323 100755 --- a/tests/scripts/thread-cert/Cert_6_6_02_KeyIncrementRollOver.py +++ b/tests/scripts/thread-cert/Cert_6_6_02_KeyIncrementRollOver.py @@ -45,12 +45,14 @@ class Cert_6_6_2_KeyIncrement1(unittest.TestCase): self.nodes[LEADER].set_mode('rsdn') self.nodes[LEADER].add_whitelist(self.nodes[ED].get_addr64()) self.nodes[LEADER].enable_whitelist() - self.nodes[LEADER].set_key_sequence(127) + self.nodes[LEADER].set_key_switch_guardtime(0) + self.nodes[LEADER].set_key_sequence_counter(127) self.nodes[ED].set_panid(0xface) self.nodes[ED].set_mode('rsn') self.nodes[ED].add_whitelist(self.nodes[LEADER].get_addr64()) self.nodes[ED].enable_whitelist() + self.nodes[ED].set_key_switch_guardtime(0) def tearDown(self): for node in list(self.nodes.values()): @@ -70,8 +72,8 @@ class Cert_6_6_2_KeyIncrement1(unittest.TestCase): for addr in addrs: self.assertTrue(self.nodes[LEADER].ping(addr)) - key_sequence = self.nodes[LEADER].get_key_sequence() - self.nodes[LEADER].set_key_sequence(key_sequence + 1) + key_sequence_counter = self.nodes[LEADER].get_key_sequence_counter() + self.nodes[LEADER].set_key_sequence_counter(key_sequence_counter + 1) addrs = self.nodes[ED].get_addrs() for addr in addrs: diff --git a/tests/scripts/thread-cert/node.py b/tests/scripts/thread-cert/node.py index 0b1c8c635..6cb66b6ea 100755 --- a/tests/scripts/thread-cert/node.py +++ b/tests/scripts/thread-cert/node.py @@ -241,16 +241,21 @@ class Node: self.send_command(cmd) self.pexpect.expect('Done') - def get_key_sequence(self): - self.send_command('keysequence') + def get_key_sequence_counter(self): + self.send_command('keysequence counter') i = self.pexpect.expect('(\d+)\r\n') if i == 0: - key_sequence = int(self.pexpect.match.groups()[0]) + key_sequence_counter = int(self.pexpect.match.groups()[0]) self.pexpect.expect('Done') - return key_sequence + return key_sequence_counter - def set_key_sequence(self, key_sequence): - cmd = 'keysequence %d' % key_sequence + def set_key_sequence_counter(self, key_sequence_counter): + cmd = 'keysequence counter %d' % key_sequence_counter + self.send_command(cmd) + self.pexpect.expect('Done') + + def set_key_switch_guardtime(self, key_switch_guardtime): + cmd = 'keysequence guardtime %d' % key_switch_guardtime self.send_command(cmd) self.pexpect.expect('Done') diff --git a/tools/harness-thci/ARM.py b/tools/harness-thci/ARM.py index 96fa5d53e..d43d4a115 100644 --- a/tools/harness-thci/ARM.py +++ b/tools/harness-thci/ARM.py @@ -533,6 +533,28 @@ class ARM(IThci): except Exception, e: ModuleHelper.WriteIntoDebugLogger("setSecurityPolicy() Error: " + str(e)) + def __setKeySwitchGuardTime(self, iKeySwitchGuardTime): + """ set the Key switch guard time + + Args: + iKeySwitchGuardTime: key switch guard time + + Returns: + True: successful to set key switch guard time + False: fail to set key switch guard time + """ + print '%s call setKeySwitchGuardTime' % self.port + print iKeySwitchGuardTime + try: + cmd = 'keysequence guardtime %s' % str(iKeySwitchGuardTime) + if self.__sendCommand(cmd)[0] == 'Done': + time.sleep(1) + return True + else: + return False + except Exception, e: + ModuleHelper.WriteIntoDebugLogger("setKeySwitchGuardTime() Error; " + str(e)) + def closeConnection(self): """close current serial port connection""" print '%s call closeConnection' % self.port @@ -919,6 +941,7 @@ class ARM(IThci): # set Thread device with a given role self.__setDeviceRole(role) + self.__setKeySwitchGuardTime(0) # start OpenThread self.__startOpenThread() @@ -1381,7 +1404,7 @@ class ARM(IThci): print '%s call setKeySequenceCounter' % self.port print iKeySequenceValue try: - cmd = 'keysequence %s' % str(iKeySequenceValue) + cmd = 'keysequence counter %s' % str(iKeySequenceValue) if self.__sendCommand(cmd)[0] == 'Done': time.sleep(1) return True @@ -1394,7 +1417,7 @@ class ARM(IThci): """get current Thread Network key sequence""" print '%s call getKeySequenceCounter' % self.port keySequence = '' - keySequence = self.__sendCommand('keysequence')[0] + keySequence = self.__sendCommand('keysequence counter')[0] return keySequence def incrementKeySequenceCounter(self, iIncrementValue=1): diff --git a/tools/spinel-cli/spinel-cli.py b/tools/spinel-cli/spinel-cli.py index 995791699..9fb25d479 100755 --- a/tools/spinel-cli/spinel-cli.py +++ b/tools/spinel-cli/spinel-cli.py @@ -850,22 +850,46 @@ class SpinelCliCmd(Cmd, SpinelCodec): def do_keysequence(self, line): """ - keysequence + keysequence counter - Get the Thread Key Sequence. + Get the Thread Key Sequence Counter. - > keysequence + > keysequence counter 10 Done - keysequence + keysequence counter - Set the Thread Key Sequence. + Set the Thread Key Sequence Counter. - > keysequence 10 + > keysequence counter 10 + Done + + keysequence guardtime + + Get the thrKeySwitchGuardTime (in hours). + + > keysequence guardtime + 0 + Done + + keysequence guardtime + + Set the thrKeySwitchGuardTime (in hours). + + > keysequence guardtime 0 Done """ - self.handle_property(line, SPINEL.PROP_NET_KEY_SEQUENCE, 'L') + + args = line.split(" ") + + if args[0] == "counter": + newline = line.replace("counter","") + self.handle_property(newline, SPINEL.PROP_NET_KEY_SEQUENCE_COUNTER, 'L') + + elif args[0] == "guardtime": + newline = line.replace("guardtime","") + self.handle_property(newline, SPINEL.PROP_NET_KEY_SWITCH_GUARDTIME, 'L') def do_leaderdata(self, line): """ diff --git a/tools/spinel-cli/spinel/codec.py b/tools/spinel-cli/spinel/codec.py index 7a474c2ff..12102e121 100644 --- a/tools/spinel-cli/spinel/codec.py +++ b/tools/spinel-cli/spinel/codec.py @@ -339,10 +339,12 @@ class SpinelPropertyHandler(SpinelCodec): def NET_MASTER_KEY(self, _, payload): return self.parse_D(payload) - def NET_KEY_SEQUENCE(self, _, payload): return self.parse_L(payload) + def NET_KEY_SEQUENCE_COUNTER(self, _, payload): return self.parse_L(payload) def NET_PARTITION_ID(self, _, payload): return self.parse_L(payload) + def NET_KEY_SWITCH_GUARDTIME(self, _, payload): return self.parse_L(payload) + def THREAD_LEADER_ADDR(self, _, payload): return self.parse_6(payload) def THREAD_PARENT(self, _wpan_api, payload): pass @@ -658,8 +660,9 @@ SPINEL_PROP_DISPATCH = { SPINEL.PROP_NET_NETWORK_NAME: WPAN_PROP_HANDLER.NET_NETWORK_NAME, SPINEL.PROP_NET_XPANID: WPAN_PROP_HANDLER.NET_XPANID, SPINEL.PROP_NET_MASTER_KEY: WPAN_PROP_HANDLER.NET_MASTER_KEY, - SPINEL.PROP_NET_KEY_SEQUENCE: WPAN_PROP_HANDLER.NET_KEY_SEQUENCE, + SPINEL.PROP_NET_KEY_SEQUENCE_COUNTER: WPAN_PROP_HANDLER.NET_KEY_SEQUENCE_COUNTER, SPINEL.PROP_NET_PARTITION_ID: WPAN_PROP_HANDLER.NET_PARTITION_ID, + SPINEL.PROP_NET_KEY_SWITCH_GUARDTIME: WPAN_PROP_HANDLER.NET_KEY_SWITCH_GUARDTIME, SPINEL.PROP_THREAD_LEADER_ADDR: WPAN_PROP_HANDLER.THREAD_LEADER_ADDR, SPINEL.PROP_THREAD_PARENT: WPAN_PROP_HANDLER.THREAD_PARENT, diff --git a/tools/spinel-cli/spinel/const.py b/tools/spinel-cli/spinel/const.py index c86f0baa1..5355695b6 100644 --- a/tools/spinel-cli/spinel/const.py +++ b/tools/spinel-cli/spinel/const.py @@ -128,8 +128,9 @@ class SPINEL(object): PROP_NET_NETWORK_NAME = PROP_NET__BEGIN + 4 # < [U] PROP_NET_XPANID = PROP_NET__BEGIN + 5 # < [D] PROP_NET_MASTER_KEY = PROP_NET__BEGIN + 6 # < [D] - PROP_NET_KEY_SEQUENCE = PROP_NET__BEGIN + 7 # < [L] + PROP_NET_KEY_SEQUENCE_COUNTER = PROP_NET__BEGIN + 7 # < [L] PROP_NET_PARTITION_ID = PROP_NET__BEGIN + 8 # < [L] + PROP_NET_KEY_SWITCH_GUARDTIME = PROP_NET__BEGIN + 10 # < [L] PROP_NET__END = 0x50 PROP_THREAD__BEGIN = 0x50 diff --git a/tools/spinel-cli/spinel/test_codec.py b/tools/spinel-cli/spinel/test_codec.py index 654bed0c1..7b8d9f3e3 100644 --- a/tools/spinel-cli/spinel/test_codec.py +++ b/tools/spinel-cli/spinel/test_codec.py @@ -43,7 +43,7 @@ class TestCodec(unittest.TestCase): SPINEL.PROP_MAC_15_4_PANID: 65535, SPINEL.PROP_NCP_VERSION: "OPENTHREAD", SPINEL.PROP_NET_ROLE: 0, - SPINEL.PROP_NET_KEY_SEQUENCE: 5, + SPINEL.PROP_NET_KEY_SEQUENCE_COUNTER: 5, SPINEL.PROP_NET_NETWORK_NAME: "OpenThread", SPINEL.PROP_THREAD_MODE: 0xF, }