From d71939d3318067dba9aa5e94f477e854d6f2745f Mon Sep 17 00:00:00 2001 From: Shu Chen Date: Mon, 26 Sep 2016 11:50:28 +0800 Subject: [PATCH] Add Joiner UDP Port feature (#676) * Add Joiner UDP Port feature - Add 'joinerport' cli for configuration - Include Joiner UDP Port TLV in discovery response message - Joiner use it as destination port during commissioning process --- include/openthread-types.h | 1 + include/openthread.h | 23 +++++++++++++++++++++++ src/cli/cli.cpp | 20 ++++++++++++++++++++ src/cli/cli.hpp | 1 + src/core/meshcop/joiner.cpp | 5 +++-- src/core/meshcop/joiner.hpp | 1 + src/core/meshcop/joiner_router.cpp | 26 ++++++++++++++++---------- src/core/meshcop/joiner_router.hpp | 22 +++++++++++++++++++++- src/core/openthread.cpp | 10 ++++++++++ src/core/thread/mle.cpp | 14 ++++++++++++++ src/core/thread/mle.hpp | 16 +++++++++------- 11 files changed, 119 insertions(+), 20 deletions(-) diff --git a/include/openthread-types.h b/include/openthread-types.h index e6eecd3b3..eac5f0a3e 100644 --- a/include/openthread-types.h +++ b/include/openthread-types.h @@ -302,6 +302,7 @@ typedef struct otActiveScanResult otNetworkName mNetworkName; ///< Thread Network Name otExtendedPanId mExtendedPanId; ///< Thread Extended PAN ID uint16_t mPanId; ///< IEEE 802.15.4 PAN ID + uint16_t mJoinerUdpPort; ///< Joiner UDP Port uint8_t mChannel; ///< IEEE 802.15.4 Channel int8_t mRssi; ///< RSSI (dBm) uint8_t mLqi; ///< LQI diff --git a/include/openthread.h b/include/openthread.h index 93324db0d..e1ce56029 100644 --- a/include/openthread.h +++ b/include/openthread.h @@ -985,6 +985,29 @@ uint32_t otGetLocalLeaderPartitionId(otInstance *aInstance); */ void otSetLocalLeaderPartitionId(otInstance *aInstance, uint32_t aPartitionId); +/** + * Get the Joiner UDP Port. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @returns The Joiner UDP Port number. + * + * @sa otSetJoinerUdpPort + */ +uint16_t otGetJoinerUdpPort(otInstance *aInstance); + +/** + * Set the Joiner UDP Port + * + * @param[in] aInstance A pointer to an OpenThread instance. + * @param[in] aJoinerUdpPort The Joiner UDP Port number. + * + * @retval kThreadErrorNone Successfully set the Joiner UDP Port. + * + * @sa otGetJoinerUdpPort + */ +ThreadError otSetJoinerUdpPort(otInstance *aInstance, uint16_t aJoinerUdpPort); + /** * @} */ diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 6d3e343df..14da8c01d 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -95,6 +95,7 @@ const struct Command Interpreter::sCommands[] = #if OPENTHREAD_ENABLE_JOINER { "joiner", &Interpreter::ProcessJoiner }, #endif + { "joinerport", &Interpreter::ProcessJoinerPort }, { "keysequence", &Interpreter::ProcessKeySequence }, { "leaderdata", &Interpreter::ProcessLeaderData }, { "leaderpartitionid", &Interpreter::ProcessLeaderPartitionId }, @@ -2206,6 +2207,25 @@ exit: #endif // OPENTHREAD_ENABLE_JOINER +void Interpreter::ProcessJoinerPort(int argc, char *argv[]) +{ + ThreadError error = kThreadError_None; + long value; + + if (argc == 0) + { + sServer->OutputFormat("%d\r\n", otGetJoinerUdpPort(mInstance)); + } + else + { + SuccessOrExit(error = ParseLong(argv[0], value)); + error = otSetJoinerUdpPort(mInstance, static_cast(value)); + } + +exit: + AppendResult(error); +} + void Interpreter::ProcessWhitelist(int argc, char *argv[]) { ThreadError error = kThreadError_None; diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp index ee8235224..59eb69b4e 100644 --- a/src/cli/cli.hpp +++ b/src/cli/cli.hpp @@ -167,6 +167,7 @@ private: #if OPENTHREAD_ENABLE_JOINER void ProcessJoiner(int argc, char *argv[]); #endif // OPENTHREAD_ENABLE_JOINER + void ProcessJoinerPort(int argc, char *argv[]); void ProcessKeySequence(int argc, char *argv[]); void ProcessLeaderData(int argc, char *argv[]); void ProcessLeaderPartitionId(int argc, char *argv[]); diff --git a/src/core/meshcop/joiner.cpp b/src/core/meshcop/joiner.cpp index 0aef3ebe6..87f35a687 100644 --- a/src/core/meshcop/joiner.cpp +++ b/src/core/meshcop/joiner.cpp @@ -100,6 +100,7 @@ void Joiner::HandleDiscoverResult(otActiveScanResult *aResult) { if (aResult != NULL) { + mJoinerUdpPort = aResult->mJoinerUdpPort; mJoinerRouterPanId = aResult->mPanId; mJoinerRouterChannel = aResult->mChannel; memcpy(&mJoinerRouter, &aResult->mExtAddress, sizeof(mJoinerRouter)); @@ -108,7 +109,7 @@ void Joiner::HandleDiscoverResult(otActiveScanResult *aResult) { // open UDP port Ip6::SockAddr sockaddr; - sockaddr.mPort = 1000; + sockaddr.mPort = mJoinerUdpPort; mSocket.Open(&Joiner::HandleUdpReceive, this); mSocket.Bind(sockaddr); @@ -198,7 +199,7 @@ void Joiner::HandleUdpTransmit(void) memset(&messageInfo, 0, sizeof(messageInfo)); messageInfo.GetPeerAddr().mFields.m16[0] = HostSwap16(0xfe80); messageInfo.GetPeerAddr().SetIid(mJoinerRouter); - messageInfo.mPeerPort = 1000; + messageInfo.mPeerPort = mJoinerUdpPort; messageInfo.mInterfaceId = 1; SuccessOrExit(error = mSocket.SendTo(*mTransmitMessage, messageInfo)); diff --git a/src/core/meshcop/joiner.hpp b/src/core/meshcop/joiner.hpp index 73a89f845..b59a1cd90 100644 --- a/src/core/meshcop/joiner.hpp +++ b/src/core/meshcop/joiner.hpp @@ -105,6 +105,7 @@ private: uint8_t mJoinerRouterChannel; uint16_t mJoinerRouterPanId; + uint16_t mJoinerUdpPort; Mac::ExtAddress mJoinerRouter; Message *mTransmitMessage; Ip6::UdpSocket mSocket; diff --git a/src/core/meshcop/joiner_router.cpp b/src/core/meshcop/joiner_router.cpp index dd515811e..8b5e15da4 100644 --- a/src/core/meshcop/joiner_router.cpp +++ b/src/core/meshcop/joiner_router.cpp @@ -51,7 +51,8 @@ namespace MeshCoP { JoinerRouter::JoinerRouter(ThreadNetif &aNetif): mSocket(aNetif.GetIp6().mUdp), mRelayTransmit(OPENTHREAD_URI_RELAY_TX, &JoinerRouter::HandleRelayTransmit, this), - mNetif(aNetif) + mNetif(aNetif), + mIsJoinerPortConfigured(false) { mSocket.GetSockName().mPort = OPENTHREAD_CONFIG_JOINER_UDP_PORT; mNetif.GetCoapServer().AddResource(mRelayTransmit); @@ -77,10 +78,7 @@ void JoinerRouter::HandleNetifStateChanged(uint32_t aFlags) { Ip6::SockAddr sockaddr; - if (GetJoinerPort(sockaddr.mPort) != kThreadError_None) - { - sockaddr.mPort = OPENTHREAD_CONFIG_JOINER_UDP_PORT; - } + sockaddr.mPort = GetJoinerUdpPort(); mSocket.Open(&JoinerRouter::HandleUdpReceive, this); mSocket.Bind(sockaddr); @@ -124,13 +122,14 @@ exit: return error; } -ThreadError JoinerRouter::GetJoinerPort(uint16_t &aJoinerPort) +uint16_t JoinerRouter::GetJoinerUdpPort(void) { - ThreadError error = kThreadError_NotFound; + uint16_t joinerUdpPort = OPENTHREAD_CONFIG_JOINER_UDP_PORT; uint8_t *cur; uint8_t *end; uint8_t length; + VerifyOrExit(!mIsJoinerPortConfigured, joinerUdpPort = mJoinerUdpPort); VerifyOrExit((cur = mNetif.GetNetworkDataLeader().GetCommissioningData(length)) != NULL, ;); end = cur + length; @@ -141,15 +140,22 @@ ThreadError JoinerRouter::GetJoinerPort(uint16_t &aJoinerPort) if (tlv->GetType() == Tlv::kJoinerUdpPort) { - aJoinerPort = reinterpret_cast(tlv)->GetUdpPort(); - ExitNow(error = kThreadError_None); + ExitNow(joinerUdpPort = reinterpret_cast(tlv)->GetUdpPort()); } cur += sizeof(Tlv) + tlv->GetLength(); } exit: - return error; + return joinerUdpPort; +} + +ThreadError JoinerRouter::SetJoinerUdpPort(uint16_t aJoinerUdpPort) +{ + mJoinerUdpPort = aJoinerUdpPort; + mIsJoinerPortConfigured = true; + HandleNetifStateChanged(OT_THREAD_NETDATA_UPDATED); + return kThreadError_None; } void JoinerRouter::HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo) diff --git a/src/core/meshcop/joiner_router.hpp b/src/core/meshcop/joiner_router.hpp index 5021570c4..b852ac1f0 100644 --- a/src/core/meshcop/joiner_router.hpp +++ b/src/core/meshcop/joiner_router.hpp @@ -59,6 +59,24 @@ public: */ JoinerRouter(ThreadNetif &aNetif); + /** + * This method returns the Joiner UDP Port. + * + * @returns The Joiner UDP Port number . + * + */ + uint16_t GetJoinerUdpPort(void); + + /** + * This method sets the Joiner UDP Port. + * + * @param[in] The Joiner UDP Port number. + * + * @retval kThreadError_None Successfully set the Joiner UDP Port. + * + */ + ThreadError SetJoinerUdpPort(uint16_t aJoinerUdpPort); + private: static void HandleNetifStateChanged(uint32_t aFlags, void *aContext); void HandleNetifStateChanged(uint32_t aFlags); @@ -73,13 +91,15 @@ private: ThreadError SendJoinerEntrust(const Ip6::MessageInfo &aMessageInfo); ThreadError GetBorderAgentRloc(uint16_t &aRloc); - ThreadError GetJoinerPort(uint16_t &aRloc); Ip6::NetifCallback mNetifCallback; Ip6::UdpSocket mSocket; Coap::Resource mRelayTransmit; ThreadNetif &mNetif; + + uint16_t mJoinerUdpPort; + bool mIsJoinerPortConfigured; }; } // namespace MeshCoP diff --git a/src/core/openthread.cpp b/src/core/openthread.cpp index dea474e8f..666dfc870 100644 --- a/src/core/openthread.cpp +++ b/src/core/openthread.cpp @@ -379,6 +379,16 @@ void otSetLocalLeaderPartitionId(otInstance *, uint32_t aPartitionId) return sThreadNetif->GetMle().SetLeaderPartitionId(aPartitionId); } +uint16_t otGetJoinerUdpPort(otInstance *) +{ + return sThreadNetif->GetJoinerRouter().GetJoinerUdpPort(); +} + +ThreadError otSetJoinerUdpPort(otInstance *, uint16_t aJoinerUdpPort) +{ + return sThreadNetif->GetJoinerRouter().SetJoinerUdpPort(aJoinerUdpPort); +} + ThreadError otAddBorderRouter(otInstance *, const otBorderRouterConfig *aConfig) { uint8_t flags = 0; diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index c7db567ea..0d6ff122f 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -61,6 +61,7 @@ Mle::Mle(ThreadNetif &aThreadNetif) : mMesh(aThreadNetif.GetMeshForwarder()), mMleRouter(aThreadNetif.GetMle()), mNetworkData(aThreadNetif.GetNetworkDataLeader()), + mJoinerRouter(aThreadNetif.GetJoinerRouter()), mParentRequestTimer(aThreadNetif.GetIp6().mTimerScheduler, &Mle::HandleParentRequestTimer, this), mSocket(aThreadNetif.GetIp6().mUdp), mSendChildUpdateRequest(aThreadNetif.GetIp6().mTaskletScheduler, &Mle::HandleSendChildUpdateRequest, this) @@ -2207,6 +2208,7 @@ ThreadError Mle::SendDiscoveryResponse(const Ip6::Address &aDestination, uint16_ MeshCoP::DiscoveryResponseTlv discoveryResponse; MeshCoP::ExtendedPanIdTlv extPanId; MeshCoP::NetworkNameTlv networkName; + MeshCoP::JoinerUdpPortTlv joinerUdpPort; VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;); message->SetLinkSecurityEnabled(false); @@ -2235,6 +2237,11 @@ ThreadError Mle::SendDiscoveryResponse(const Ip6::Address &aDestination, uint16_ networkName.SetNetworkName(mMac.GetNetworkName()); SuccessOrExit(error = message->Append(&networkName, sizeof(tlv) + networkName.GetLength())); + // Joiner UDP Port TLV + joinerUdpPort.Init(); + joinerUdpPort.SetUdpPort(mJoinerRouter.GetJoinerUdpPort()); + SuccessOrExit(error = message->Append(&joinerUdpPort, sizeof(tlv) + joinerUdpPort.GetLength())); + tlv.SetLength(static_cast(message->GetLength() - startOffset)); message->Write(startOffset - sizeof(tlv), sizeof(tlv), &tlv); @@ -2261,6 +2268,7 @@ ThreadError Mle::HandleDiscoveryResponse(const Message &aMessage, const Ip6::Mes MeshCoP::DiscoveryResponseTlv discoveryResponse; MeshCoP::ExtendedPanIdTlv extPanId; MeshCoP::NetworkNameTlv networkName; + MeshCoP::JoinerUdpPortTlv JoinerUdpPort; otActiveScanResult result; uint16_t offset; uint16_t end; @@ -2323,6 +2331,12 @@ ThreadError Mle::HandleDiscoveryResponse(const Message &aMessage, const Ip6::Mes memcpy(&result.mNetworkName, networkName.GetNetworkName(), networkName.GetLength()); break; + case MeshCoP::Tlv::kJoinerUdpPort: + aMessage.Read(offset, sizeof(JoinerUdpPort), &JoinerUdpPort); + VerifyOrExit(JoinerUdpPort.IsValid(), error = kThreadError_Parse); + result.mJoinerUdpPort = JoinerUdpPort.GetUdpPort(); + break; + default: break; } diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 891c65e63..36f601739 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -42,6 +42,7 @@ #include #include #include +#include namespace Thread { @@ -1039,13 +1040,14 @@ protected: */ void SetLeaderData(uint32_t aPartitionId, uint8_t aWeighting, uint8_t aLeaderRouterId); - ThreadNetif &mNetif; ///< The Thread Network Interface object. - AddressResolver &mAddressResolver; ///< The Address Resolver object. - KeyManager &mKeyManager; ///< The Key Manager object. - Mac::Mac &mMac; ///< The MAC object. - MeshForwarder &mMesh; ///< The Mesh Forwarding object. - MleRouter &mMleRouter; ///< The MLE Router object. - NetworkData::Leader &mNetworkData; ///< The Network Data object. + ThreadNetif &mNetif; ///< The Thread Network Interface object. + AddressResolver &mAddressResolver; ///< The Address Resolver object. + KeyManager &mKeyManager; ///< The Key Manager object. + Mac::Mac &mMac; ///< The MAC object. + MeshForwarder &mMesh; ///< The Mesh Forwarding object. + MleRouter &mMleRouter; ///< The MLE Router object. + NetworkData::Leader &mNetworkData; ///< The Network Data object. + MeshCoP::JoinerRouter &mJoinerRouter; ///< The Joiner Router object. LeaderDataTlv mLeaderData; ///< Last received Leader Data TLV. bool mRetrieveNewNetworkData; ///< Indicating new Network Data is needed if set.