From 4b51be41b5565b961cfc2ab1ab1c11e56c424bfd Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Wed, 21 Sep 2016 10:50:44 -0700 Subject: [PATCH] Implement Joiner Router Locator TLV. (#645) --- include/openthread-types.h | 1 + src/core/meshcop/commissioner.cpp | 17 ++++++++++-- src/core/meshcop/commissioner.hpp | 2 +- src/core/meshcop/joiner_router.cpp | 5 ++++ src/core/thread/meshcop_tlvs.hpp | 44 ++++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+), 4 deletions(-) diff --git a/include/openthread-types.h b/include/openthread-types.h index 236617f20..207139fb9 100644 --- a/include/openthread-types.h +++ b/include/openthread-types.h @@ -400,6 +400,7 @@ typedef enum otMeshcopTlvType OT_MESHCOP_TLV_JOINER_DTLS = 17, ///< meshcop Joiner DTLS Encapsulation TLV OT_MESHCOP_TLV_JOINER_UDP_PORT = 18, ///< meshcop Joiner UDP Port TLV OT_MESHCOP_TLV_JOINER_IID = 19, ///< meshcop Joiner IID TLV + OT_MESHCOP_TLV_JOINER_RLOC = 20, ///< meshcop Joiner Router Locator TLV OT_MESHCOP_TLV_JOINER_ROUTER_KEK = 21, ///< meshcop Joiner Router KEK TLV OT_MESHCOP_TLV_PENDINGTIMESTAMP = 51, ///< meshcop Pending Timestamp TLV OT_MESHCOP_TLV_DELAYTIMER = 52, ///< meshcop Delay Timer TLV diff --git a/src/core/meshcop/commissioner.cpp b/src/core/meshcop/commissioner.cpp index 1d2fccef0..a2b47098b 100644 --- a/src/core/meshcop/commissioner.cpp +++ b/src/core/meshcop/commissioner.cpp @@ -225,6 +225,7 @@ void Commissioner::HandleRelayReceive(Coap::Header &aHeader, Message &aMessage, ThreadError error; JoinerUdpPortTlv joinerPort; JoinerIidTlv joinerIid; + JoinerRouterLocatorTlv joinerRloc; uint16_t offset; uint16_t length; @@ -239,16 +240,20 @@ void Commissioner::HandleRelayReceive(Coap::Header &aHeader, Message &aMessage, SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kJoinerIid, sizeof(joinerIid), joinerIid)); VerifyOrExit(joinerIid.IsValid(), error = kThreadError_Parse); + SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kJoinerRouterLocator, sizeof(joinerRloc), joinerRloc)); + VerifyOrExit(joinerRloc.IsValid(), error = kThreadError_Parse); + SuccessOrExit(error = Tlv::GetValueOffset(aMessage, Tlv::kJoinerDtlsEncapsulation, offset, length)); memcpy(mJoinerIid, joinerIid.GetIid(), sizeof(mJoinerIid)); mNetif.GetDtls().SetClientId(mJoinerIid, sizeof(mJoinerIid)); mJoinerPort = joinerPort.GetUdpPort(); - mJoinerRouterAddress = aMessageInfo.GetPeerAddr(); + mJoinerRloc = joinerRloc.GetJoinerRouterLocator(); mNetif.GetDtls().Receive(aMessage, offset, length); exit: + (void)aMessageInfo; return; } @@ -320,6 +325,7 @@ ThreadError Commissioner::HandleDtlsSend(const unsigned char *aBuf, uint16_t aLe Coap::Header header; JoinerUdpPortTlv udpPort; JoinerIidTlv iid; + JoinerRouterLocatorTlv rloc; ExtendedTlv tlv; VerifyOrExit((mTransmitMessage = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs); @@ -341,6 +347,10 @@ ThreadError Commissioner::HandleDtlsSend(const unsigned char *aBuf, uint16_t aLe iid.SetIid(mJoinerIid); SuccessOrExit(error = mTransmitMessage->Append(&iid, sizeof(iid))); + rloc.Init(); + rloc.SetJoinerRouterLocator(mJoinerRloc); + SuccessOrExit(error = mTransmitMessage->Append(&rloc, sizeof(rloc))); + if (mSendKek) { JoinerRouterKekTlv kek; @@ -400,9 +410,10 @@ void Commissioner::HandleUdpTransmit(void) mTransmitMessage->Write(mTransmitMessage->GetOffset(), sizeof(tlv), &tlv); memset(&messageInfo, 0, sizeof(messageInfo)); - messageInfo.GetPeerAddr() = mJoinerRouterAddress; + messageInfo.GetPeerAddr() = *mNetif.GetMle().GetMeshLocal16(); + messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(mJoinerRloc); messageInfo.mPeerPort = kCoapUdpPort; - messageInfo.mInterfaceId = 1; + messageInfo.mInterfaceId = mNetif.GetInterfaceId(); SuccessOrExit(error = mSocket.SendTo(*mTransmitMessage, messageInfo)); diff --git a/src/core/meshcop/commissioner.hpp b/src/core/meshcop/commissioner.hpp index 60f6e75f3..8b79e25e8 100644 --- a/src/core/meshcop/commissioner.hpp +++ b/src/core/meshcop/commissioner.hpp @@ -122,9 +122,9 @@ private: uint8_t mState; - Ip6::Address mJoinerRouterAddress; uint8_t mJoinerIid[8]; uint16_t mJoinerPort; + uint16_t mJoinerRloc; uint16_t mSessionId; Message *mTransmitMessage; diff --git a/src/core/meshcop/joiner_router.cpp b/src/core/meshcop/joiner_router.cpp index 8501f08ef..dd515811e 100644 --- a/src/core/meshcop/joiner_router.cpp +++ b/src/core/meshcop/joiner_router.cpp @@ -166,6 +166,7 @@ void JoinerRouter::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &a Ip6::MessageInfo messageInfo; JoinerUdpPortTlv udpPort; JoinerIidTlv iid; + JoinerRouterLocatorTlv rloc; ExtendedTlv tlv; uint16_t borderAgentRloc; @@ -192,6 +193,10 @@ void JoinerRouter::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &a iid.SetIid(aMessageInfo.GetPeerAddr().mFields.m8 + 8); SuccessOrExit(error = message->Append(&iid, sizeof(iid))); + rloc.Init(); + rloc.SetJoinerRouterLocator(mNetif.GetMle().GetRloc16()); + SuccessOrExit(error = message->Append(&rloc, sizeof(rloc))); + tlv.SetType(Tlv::kJoinerDtlsEncapsulation); tlv.SetLength(aMessage.GetLength() - aMessage.GetOffset()); SuccessOrExit(error = message->Append(&tlv, sizeof(tlv))); diff --git a/src/core/thread/meshcop_tlvs.hpp b/src/core/thread/meshcop_tlvs.hpp index 4e1eb65fb..ce0fb20a3 100644 --- a/src/core/thread/meshcop_tlvs.hpp +++ b/src/core/thread/meshcop_tlvs.hpp @@ -79,6 +79,7 @@ public: kJoinerDtlsEncapsulation = OT_MESHCOP_TLV_JOINER_DTLS, ///< Joiner DTLS Encapsulation TLV kJoinerUdpPort = OT_MESHCOP_TLV_JOINER_UDP_PORT, ///< Joiner UDP Port TLV kJoinerIid = OT_MESHCOP_TLV_JOINER_IID, ///< Joiner IID TLV + kJoinerRouterLocator = OT_MESHCOP_TLV_JOINER_RLOC, ///< Joiner Router Locator TLV kJoinerRouterKek = OT_MESHCOP_TLV_JOINER_ROUTER_KEK, ///< Joiner Router KEK TLV kPendingTimestamp = OT_MESHCOP_TLV_PENDINGTIMESTAMP, ///< Pending Timestamp TLV kDelayTimer = OT_MESHCOP_TLV_DELAYTIMER, ///< Delay Timer TLV @@ -1082,6 +1083,49 @@ private: uint8_t mIid[8]; } OT_TOOL_PACKED_END; +/** + * This class implements Joiner Router Locator TLV generation and parsing. + * + */ +OT_TOOL_PACKED_BEGIN +class JoinerRouterLocatorTlv: public Tlv +{ +public: + /** + * This method initializes the TLV. + * + */ + void Init(void) { SetType(kJoinerRouterLocator); 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 Joiner Router Locator value. + * + * @returns The Joiner Router Locator value. + * + */ + uint16_t GetJoinerRouterLocator(void) const { return HostSwap16(mLocator); } + + /** + * This method sets the Joiner Router Locator value. + * + * @param[in] aJoinerRouterLocator The Joiner Router Locator value. + * + */ + void SetJoinerRouterLocator(uint16_t aLocator) { mLocator = HostSwap16(aLocator); } + +private: + uint16_t mLocator; +} OT_TOOL_PACKED_END; + /** * This class implements Joiner Router KEK TLV generation and parsing. *