diff --git a/include/openthread-types.h b/include/openthread-types.h index 849ee48cc..cbd19f05b 100644 --- a/include/openthread-types.h +++ b/include/openthread-types.h @@ -483,6 +483,7 @@ typedef enum otMeshcopTlvType OT_MESHCOP_TLV_NETWORKNAME = 3, ///< meshcop Network Name TLV OT_MESHCOP_TLV_PSKC = 4, ///< meshcop PSKc TLV OT_MESHCOP_TLV_MASTERKEY = 5, ///< meshcop Network Master Key TLV + OT_MESHCOP_TLV_NETWORK_KEY_SEQUENCE = 6, ///< meshcop Network Key Sequence TLV OT_MESHCOP_TLV_MESHLOCALPREFIX = 7, ///< meshcop Mesh Local Prefix TLV OT_MESHCOP_TLV_STEERING_DATA = 8, ///< meshcop Steering Data TLV OT_MESHCOP_TLV_BORDER_AGENT_RLOC = 9, ///< meshcop Border Agent Locator TLV diff --git a/src/core/meshcop/joiner.cpp b/src/core/meshcop/joiner.cpp index ec42c1cf5..29679d0fe 100644 --- a/src/core/meshcop/joiner.cpp +++ b/src/core/meshcop/joiner.cpp @@ -373,6 +373,7 @@ void Joiner::HandleJoinerEntrust(Coap::Header &aHeader, Message &aMessage, const ExtendedPanIdTlv extendedPanId; NetworkNameTlv networkName; ActiveTimestampTlv activeTimestamp; + NetworkKeySequenceTlv networkKeySeq; otLogFuncEntry(); @@ -398,7 +399,11 @@ void Joiner::HandleJoinerEntrust(Coap::Header &aHeader, Message &aMessage, const SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp)); VerifyOrExit(activeTimestamp.IsValid(), error = kThreadError_Parse); + SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kNetworkKeySequence, sizeof(networkKeySeq), networkKeySeq)); + VerifyOrExit(networkKeySeq.IsValid(), error = kThreadError_Parse); + mNetif.GetKeyManager().SetMasterKey(masterKey.GetNetworkMasterKey(), masterKey.GetLength()); + mNetif.GetKeyManager().SetCurrentKeySequence(networkKeySeq.GetNetworkKeySequence()); mNetif.GetMle().SetMeshLocalPrefix(meshLocalPrefix.GetMeshLocalPrefix()); mNetif.GetMac().SetExtendedPanId(extendedPanId.GetExtendedPanId()); mNetif.GetMac().SetNetworkName(networkName.GetNetworkName()); diff --git a/src/core/meshcop/joiner_router.cpp b/src/core/meshcop/joiner_router.cpp index b4a3e7721..2bed446a8 100644 --- a/src/core/meshcop/joiner_router.cpp +++ b/src/core/meshcop/joiner_router.cpp @@ -318,6 +318,7 @@ ThreadError JoinerRouter::SendJoinerEntrust(const Ip6::MessageInfo &aMessageInfo MeshLocalPrefixTlv meshLocalPrefix; ExtendedPanIdTlv extendedPanId; NetworkNameTlv networkName; + NetworkKeySequenceTlv networkKeySequence; Tlv *tlv; otLogFuncEntry(); @@ -389,6 +390,10 @@ ThreadError JoinerRouter::SendJoinerEntrust(const Ip6::MessageInfo &aMessageInfo SuccessOrExit(error = message->Append(&securityPolicy, sizeof(securityPolicy))); } + networkKeySequence.Init(); + networkKeySequence.SetNetworkKeySequence(mNetif.GetKeyManager().GetCurrentKeySequence()); + SuccessOrExit(error = message->Append(&networkKeySequence, networkKeySequence.GetSize())); + messageInfo = aMessageInfo; messageInfo.SetPeerPort(kCoapUdpPort); SuccessOrExit(error = mCoapClient.SendMessage(*message, messageInfo)); diff --git a/src/core/meshcop/tlvs.hpp b/src/core/meshcop/tlvs.hpp index 50f24fbe0..254bd3eb9 100644 --- a/src/core/meshcop/tlvs.hpp +++ b/src/core/meshcop/tlvs.hpp @@ -69,6 +69,7 @@ public: kNetworkName = OT_MESHCOP_TLV_NETWORKNAME, ///< Newtork Name TLV kPSKc = OT_MESHCOP_TLV_PSKC, ///< PSKc TLV kNetworkMasterKey = OT_MESHCOP_TLV_MASTERKEY, ///< Network Master Key TLV + kNetworkKeySequence = OT_MESHCOP_TLV_NETWORK_KEY_SEQUENCE, ///< Network Key Sequence TLV kMeshLocalPrefix = OT_MESHCOP_TLV_MESHLOCALPREFIX, ///< Mesh Local Prefix TLV kSteeringData = OT_MESHCOP_TLV_STEERING_DATA, ///< Steering Data TLV kBorderAgentLocator = OT_MESHCOP_TLV_BORDER_AGENT_RLOC, ///< Border Agent Locator TLV @@ -449,6 +450,49 @@ private: uint8_t mNetworkMasterKey[16]; } OT_TOOL_PACKED_END; +/** + * This class implements Network Key Sequence TLV generation and parsing. + * + */ +OT_TOOL_PACKED_BEGIN +class NetworkKeySequenceTlv: public Tlv +{ +public: + /** + * This method initializes the TLV. + * + */ + void Init(void) { SetType(kNetworkKeySequence); SetLength(sizeof(*this) - sizeof(Tlv)); } + + /** + * This method indicates whether or not the TLV appears to be well-formed. + * + * @retval TRUE If the TLV appears to be well-formed. + * @retval FALSE If the TLV does not appear to be well-formed. + * + */ + bool IsValid(void) const { return GetLength() == sizeof(*this) - sizeof(Tlv); } + + /** + * This method returns the Network Key Sequence value. + * + * @returns The Network Key Sequence value. + * + */ + uint32_t GetNetworkKeySequence(void) const { return HostSwap32(mNetworkKeySequence); } + + /** + * This method sets the Network Key Sequence value. + * + * @param[in] aNetworkKeySequence The Network Key Sequence value. + * + */ + void SetNetworkKeySequence(uint32_t aNetworkKeySequence) { mNetworkKeySequence = HostSwap32(aNetworkKeySequence); } + +private: + uint32_t mNetworkKeySequence; +} OT_TOOL_PACKED_END; + /** * This class implements Mesh Local Prefix TLV generation and parsing. *