diff --git a/Android.bp b/Android.bp index bcb812a03..e0a535fe1 100644 --- a/Android.bp +++ b/Android.bp @@ -246,7 +246,7 @@ cc_library_static { "src/core/common/notifier.cpp", "src/core/common/random_manager.cpp", "src/core/common/settings.cpp", - "src/core/common/string.cpp", + "src/core/common/string.cpp", "src/core/common/tasklet.cpp", "src/core/common/time_ticker.cpp", "src/core/common/timer.cpp", @@ -282,7 +282,7 @@ cc_library_static { "src/core/meshcop/energy_scan_client.cpp", "src/core/meshcop/joiner.cpp", "src/core/meshcop/joiner_router.cpp", - "src/core/meshcop/meshcop.cpp", + "src/core/meshcop/meshcop.cpp", "src/core/meshcop/meshcop_leader.cpp", "src/core/meshcop/meshcop_tlvs.cpp", "src/core/meshcop/panid_query_client.cpp", @@ -332,6 +332,7 @@ cc_library_static { "src/core/thread/network_data_leader_ftd.cpp", "src/core/thread/network_data_local.cpp", "src/core/thread/network_data_notifier.cpp", + "src/core/thread/network_data_service.cpp", "src/core/thread/network_diagnostic.cpp", "src/core/thread/panid_query_server.cpp", "src/core/thread/radio_selector.cpp", diff --git a/Android.mk b/Android.mk index 9fc9a1ed5..7a9195700 100644 --- a/Android.mk +++ b/Android.mk @@ -299,6 +299,7 @@ LOCAL_SRC_FILES := \ src/core/thread/network_data_leader_ftd.cpp \ src/core/thread/network_data_local.cpp \ src/core/thread/network_data_notifier.cpp \ + src/core/thread/network_data_service.cpp \ src/core/thread/network_diagnostic.cpp \ src/core/thread/panid_query_server.cpp \ src/core/thread/radio_selector.cpp \ diff --git a/src/core/BUILD.gn b/src/core/BUILD.gn index c9df6d2ab..a4b08efff 100644 --- a/src/core/BUILD.gn +++ b/src/core/BUILD.gn @@ -559,6 +559,8 @@ openthread_core_files = [ "thread/network_data_local.hpp", "thread/network_data_notifier.cpp", "thread/network_data_notifier.hpp", + "thread/network_data_service.cpp", + "thread/network_data_service.hpp", "thread/network_data_tlvs.hpp", "thread/network_diagnostic.cpp", "thread/network_diagnostic.hpp", diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 04bb78038..02ebb1bb0 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -181,6 +181,7 @@ set(COMMON_SOURCES thread/network_data_leader_ftd.cpp thread/network_data_local.cpp thread/network_data_notifier.cpp + thread/network_data_service.cpp thread/network_diagnostic.cpp thread/panid_query_server.cpp thread/radio_selector.cpp diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 45e1ca0e6..bf8d0f871 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -258,6 +258,7 @@ SOURCES_COMMON = \ thread/network_data_leader_ftd.cpp \ thread/network_data_local.cpp \ thread/network_data_notifier.cpp \ + thread/network_data_service.cpp \ thread/network_diagnostic.cpp \ thread/panid_query_server.cpp \ thread/radio_selector.cpp \ @@ -506,6 +507,7 @@ HEADERS_COMMON = \ thread/network_data_leader_ftd.hpp \ thread/network_data_local.hpp \ thread/network_data_notifier.hpp \ + thread/network_data_service.hpp \ thread/network_data_tlvs.hpp \ thread/network_diagnostic.hpp \ thread/network_diagnostic_tlvs.hpp \ diff --git a/src/core/backbone_router/bbr_leader.cpp b/src/core/backbone_router/bbr_leader.cpp index 806f20034..e17cf3e76 100644 --- a/src/core/backbone_router/bbr_leader.cpp +++ b/src/core/backbone_router/bbr_leader.cpp @@ -71,13 +71,11 @@ exit: otError Leader::GetServiceId(uint8_t &aServiceId) const { - otError error = OT_ERROR_NONE; - uint8_t serviceData = NetworkData::ServiceTlv::kServiceDataBackboneRouter; + otError error = OT_ERROR_NONE; VerifyOrExit(HasPrimary(), error = OT_ERROR_NOT_FOUND); - - error = Get().GetServiceId(NetworkData::ServiceTlv::kThreadEnterpriseNumber, &serviceData, - sizeof(serviceData), true, aServiceId); + error = Get().GetServiceId( + /* aServerStable */ true, aServiceId); exit: return error; @@ -182,7 +180,7 @@ void Leader::UpdateBackboneRouterPrimary(void) State state; uint32_t origMlrTimeout; - IgnoreError(Get().GetBackboneRouterPrimary(config)); + IgnoreError(Get().GetBackboneRouterPrimary(config)); if (config.mServer16 != mConfig.mServer16) { diff --git a/src/core/backbone_router/bbr_local.cpp b/src/core/backbone_router/bbr_local.cpp index ca306aff4..c680a9966 100644 --- a/src/core/backbone_router/bbr_local.cpp +++ b/src/core/backbone_router/bbr_local.cpp @@ -171,9 +171,8 @@ exit: otError Local::AddService(bool aForce) { - otError error = OT_ERROR_INVALID_STATE; - uint8_t serviceData = NetworkData::ServiceTlv::kServiceDataBackboneRouter; - NetworkData::BackboneRouterServerData serverData; + otError error = OT_ERROR_INVALID_STATE; + NetworkData::Service::BackboneRouter::ServerData serverData; VerifyOrExit(mState != OT_BACKBONE_ROUTER_STATE_DISABLED && Get().IsAttached()); @@ -187,12 +186,8 @@ otError Local::AddService(bool aForce) serverData.SetReregistrationDelay(mReregistrationDelay); serverData.SetMlrTimeout(mMlrTimeout); - SuccessOrExit(error = Get().AddService( - NetworkData::ServiceTlv::kThreadEnterpriseNumber, &serviceData, sizeof(serviceData), true, - reinterpret_cast(&serverData), sizeof(serverData))); - + SuccessOrExit(error = Get().Add(serverData)); mIsServiceAdded = true; - Get().HandleServerDataUpdated(); exit: LogBackboneRouterService("Add", error); @@ -202,13 +197,9 @@ exit: void Local::RemoveService(void) { otError error; - uint8_t serviceData = NetworkData::ServiceTlv::kServiceDataBackboneRouter; - - SuccessOrExit(error = Get().RemoveService(NetworkData::ServiceTlv::kThreadEnterpriseNumber, - &serviceData, sizeof(serviceData))); + SuccessOrExit(error = Get().Remove()); mIsServiceAdded = false; - Get().HandleServerDataUpdated(); exit: LogBackboneRouterService("Remove", error); diff --git a/src/core/common/instance.hpp b/src/core/common/instance.hpp index 111e8e874..9d117ef21 100644 --- a/src/core/common/instance.hpp +++ b/src/core/common/instance.hpp @@ -631,6 +631,11 @@ template <> inline NetworkData::Notifier &Instance::Get(void) } #endif +template <> inline NetworkData::Service::Manager &Instance::Get(void) +{ + return mThreadNetif.mNetworkDataServiceManager; +} + template <> inline Ip6::Udp &Instance::Get(void) { return mIp6.mUdp; diff --git a/src/core/config/srp_server.h b/src/core/config/srp_server.h index 3b9147479..883cb78fc 100644 --- a/src/core/config/srp_server.h +++ b/src/core/config/srp_server.h @@ -46,13 +46,13 @@ #endif /** - * @def OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_TYPE + * @def OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_NUMBER * - * Specifies the Service Type for SRP Server. + * Specifies the Thread Network Data Service number for SRP Server. * */ -#ifndef OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_TYPE -#define OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_TYPE 0x5du +#ifndef OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_NUMBER +#define OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_NUMBER 0x5du #endif /** diff --git a/src/core/net/socket.hpp b/src/core/net/socket.hpp index 84d44d0e4..6e83936f8 100644 --- a/src/core/net/socket.hpp +++ b/src/core/net/socket.hpp @@ -304,6 +304,14 @@ public: */ uint16_t GetPort(void) const { return mPort; } + /** + * This method sets the socket address port number. + * + * @param[in] aPort The port number. + * + */ + void SetPort(uint16_t aPort) { mPort = aPort; } + /** * This method overloads operator `==` to evaluate whether or not two `SockAddr` instances are equal (same address * and port number). diff --git a/src/core/net/srp_server.cpp b/src/core/net/srp_server.cpp index 5bfe944de..79288b7f2 100644 --- a/src/core/net/srp_server.cpp +++ b/src/core/net/srp_server.cpp @@ -40,8 +40,7 @@ #include "common/logging.hpp" #include "common/new.hpp" #include "net/dns_headers.hpp" -#include "thread/network_data_local.hpp" -#include "thread/network_data_notifier.hpp" +#include "thread/network_data_service.hpp" #include "thread/thread_netif.hpp" #include "utils/heap.hpp" @@ -468,33 +467,19 @@ exit: otError Server::PublishServerData(void) { - otError error; - const uint8_t serviceData[] = {kThreadServiceTypeSrpServer}; - uint8_t serverData[sizeof(uint16_t)]; + NetworkData::Service::SrpServer::ServerData serverData; OT_ASSERT(mSocket.IsBound()); - Encoding::BigEndian::WriteUint16(mSocket.GetSockName().mPort, serverData); + serverData.SetPort(mSocket.GetSockName().GetPort()); - SuccessOrExit(error = Get().AddService( - NetworkData::ServiceTlv::kThreadEnterpriseNumber, serviceData, sizeof(serviceData), - /* aServerStable */ true, serverData, sizeof(serverData))); - Get().HandleServerDataUpdated(); - -exit: - return error; + return Get().Add(serverData); } void Server::UnpublishServerData(void) { - otError error; - const uint8_t serviceData[] = {kThreadServiceTypeSrpServer}; + otError error = Get().Remove(); - SuccessOrExit(error = Get().RemoveService(NetworkData::ServiceTlv::kThreadEnterpriseNumber, - serviceData, sizeof(serviceData))); - Get().HandleServerDataUpdated(); - -exit: if (error != OT_ERROR_NONE) { otLogWarnSrp("[server] failed to unpublish SRP service: %s", otThreadErrorToString(error)); diff --git a/src/core/net/srp_server.hpp b/src/core/net/srp_server.hpp index be5aa105a..ff9cf1a5f 100644 --- a/src/core/net/srp_server.hpp +++ b/src/core/net/srp_server.hpp @@ -480,11 +480,6 @@ public: void HandleAdvertisingResult(const Host *aHost, otError aError); private: - enum : uint8_t - { - kThreadServiceTypeSrpServer = OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_TYPE, - }; - enum : uint16_t { kUdpPayloadSize = Ip6::Ip6::kMaxDatagramLength - sizeof(Ip6::Udp::Header), // Max UDP payload size diff --git a/src/core/thread/network_data.hpp b/src/core/thread/network_data.hpp index bb6965079..5f9e94e67 100644 --- a/src/core/thread/network_data.hpp +++ b/src/core/thread/network_data.hpp @@ -76,6 +76,10 @@ namespace ot { */ namespace NetworkData { +namespace Service { +class Manager; +} + /** * @addtogroup core-netdata-core * @@ -264,6 +268,8 @@ private: */ class NetworkData : public InstanceLocator { + friend class Service::Manager; + public: enum { diff --git a/src/core/thread/network_data_leader.cpp b/src/core/thread/network_data_leader.cpp index 33eed1581..007681b4c 100644 --- a/src/core/thread/network_data_leader.cpp +++ b/src/core/thread/network_data_leader.cpp @@ -93,57 +93,6 @@ exit: return error; } -#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) -otError LeaderBase::GetBackboneRouterPrimary(BackboneRouter::BackboneRouterConfig &aConfig) const -{ - otError error = OT_ERROR_NOT_FOUND; - uint8_t serviceData = ServiceTlv::kServiceDataBackboneRouter; - const ServerTlv * rvalServerTlv = nullptr; - const BackboneRouterServerData *rvalServerData = nullptr; - const ServiceTlv * serviceTlv; - const ServerTlv * serverTlv; - - serviceTlv = Get().FindService(ServiceTlv::kThreadEnterpriseNumber, &serviceData, sizeof(serviceData)); - - VerifyOrExit(serviceTlv != nullptr, aConfig.mServer16 = Mac::kShortAddrInvalid); - - for (const NetworkDataTlv *start = serviceTlv->GetSubTlvs(); - (serverTlv = FindTlv(start, serviceTlv->GetNext())) != nullptr; start = serverTlv->GetNext()) - { - const BackboneRouterServerData *serverData; - - if (serverTlv->GetServerDataLength() < sizeof(BackboneRouterServerData)) - { - continue; - } - - serverData = reinterpret_cast(serverTlv->GetServerData()); - - if (rvalServerTlv == nullptr || - (serverTlv->GetServer16() == Mle::Mle::Rloc16FromRouterId(Get().GetLeaderId())) || - serverData->GetSequenceNumber() > rvalServerData->GetSequenceNumber() || - (serverData->GetSequenceNumber() == rvalServerData->GetSequenceNumber() && - serverTlv->GetServer16() > rvalServerTlv->GetServer16())) - { - rvalServerTlv = serverTlv; - rvalServerData = serverData; - } - } - - VerifyOrExit(rvalServerTlv != nullptr); - - aConfig.mServer16 = rvalServerTlv->GetServer16(); - aConfig.mSequenceNumber = rvalServerData->GetSequenceNumber(); - aConfig.mReregistrationDelay = rvalServerData->GetReregistrationDelay(); - aConfig.mMlrTimeout = rvalServerData->GetMlrTimeout(); - - error = OT_ERROR_NONE; - -exit: - return error; -} -#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) - const PrefixTlv *LeaderBase::FindNextMatchingPrefix(const Ip6::Address &aAddress, const PrefixTlv *aPrevTlv) const { const PrefixTlv *prefixTlv; diff --git a/src/core/thread/network_data_leader.hpp b/src/core/thread/network_data_leader.hpp index f8691251b..4e5e35898 100644 --- a/src/core/thread/network_data_leader.hpp +++ b/src/core/thread/network_data_leader.hpp @@ -38,10 +38,6 @@ #include -#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) -#include "backbone_router/bbr_leader.hpp" -#endif - #include "coap/coap.hpp" #include "common/timer.hpp" #include "net/ip6_address.hpp" @@ -289,19 +285,6 @@ public: bool aServerStable, uint8_t & aServiceId) const; -#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) - /** - * This method gets the Primary Backbone Router (PBBR) in the Thread Network. - * - * @param[out] aConfig The Primary Backbone Router configuration. - * - * @retval OT_ERROR_NONE Successfully got the Primary Backbone Router configuration. - * @retval OT_ERROR_NOT_FOUND No Backbone Router Service in the Thread Network. - * - */ - otError GetBackboneRouterPrimary(BackboneRouter::BackboneRouterConfig &aConfig) const; -#endif - protected: uint8_t mStableVersion; uint8_t mVersion; diff --git a/src/core/thread/network_data_local.hpp b/src/core/thread/network_data_local.hpp index 8eae4c9a3..ba077c171 100644 --- a/src/core/thread/network_data_local.hpp +++ b/src/core/thread/network_data_local.hpp @@ -146,12 +146,12 @@ public: * @param[in] aServiceData A pointer to the service data. * @param[in] aServiceDataLength The length of @p aServiceData in bytes. * - * @retval OT_ERROR_NONE Successfully removed the Border Router entry. - * @retval OT_ERROR_NOT_FOUND Could not find the Border Router entry. + * @retval OT_ERROR_NONE Successfully removed the Service entry. + * @retval OT_ERROR_NOT_FOUND Could not find the Service entry. * */ otError RemoveService(uint32_t aEnterpriseNumber, const uint8_t *aServiceData, uint8_t aServiceDataLength); -#endif +#endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE /** * This method sends a Server Data Notification message to the Leader. diff --git a/src/core/thread/network_data_service.cpp b/src/core/thread/network_data_service.cpp new file mode 100644 index 000000000..3fb52fa64 --- /dev/null +++ b/src/core/thread/network_data_service.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2021, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file implements function for managing Thread Network Data service/server entries. + * + */ + +#include "network_data_service.hpp" + +#include "common/code_utils.hpp" +#include "common/instance.hpp" +#include "common/locator-getters.hpp" +#include "thread/network_data_local.hpp" + +namespace ot { +namespace NetworkData { +namespace Service { + +#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE + +otError Manager::AddService(uint8_t aServiceNumber, + bool aServerStable, + const void *aServerData, + uint8_t aServerDataLength) +{ + otError error; + + SuccessOrExit(error = Get().AddService(kThreadEnterpriseNumber, &aServiceNumber, sizeof(aServiceNumber), + aServerStable, reinterpret_cast(aServerData), + aServerDataLength)); + + Get().HandleServerDataUpdated(); + +exit: + return error; +} + +otError Manager::RemoveService(uint8_t aServiceNumber) +{ + otError error; + + SuccessOrExit(error = Get().RemoveService(kThreadEnterpriseNumber, &aServiceNumber, sizeof(aServiceNumber))); + Get().HandleServerDataUpdated(); + +exit: + return error; +} + +#endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE + +otError Manager::GetServiceId(uint8_t aServiceNumber, bool aServerStable, uint8_t &aServiceId) const +{ + return Get().GetServiceId(kThreadEnterpriseNumber, &aServiceNumber, sizeof(aServiceNumber), aServerStable, + aServiceId); +} + +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + +otError Manager::GetBackboneRouterPrimary(ot::BackboneRouter::BackboneRouterConfig &aConfig) const +{ + otError error = OT_ERROR_NOT_FOUND; + const uint8_t serviceData = BackboneRouter::kServiceNumber; + const ServerTlv * rvalServerTlv = nullptr; + const BackboneRouter::ServerData *rvalServerData = nullptr; + Iterator iterator; + + iterator.mServiceTlv = Get().FindService(kThreadEnterpriseNumber, &serviceData, sizeof(serviceData)); + + VerifyOrExit(iterator.mServiceTlv != nullptr, aConfig.mServer16 = Mac::kShortAddrInvalid); + + while (IterateToNextServer(iterator) == OT_ERROR_NONE) + { + const BackboneRouter::ServerData *serverData; + + if (iterator.mServerSubTlv->GetServerDataLength() < sizeof(BackboneRouter::ServerData)) + { + continue; + } + + serverData = reinterpret_cast(iterator.mServerSubTlv->GetServerData()); + + if (rvalServerTlv == nullptr || + (iterator.mServerSubTlv->GetServer16() == + Mle::Mle::Rloc16FromRouterId(Get().GetLeaderId())) || + serverData->GetSequenceNumber() > rvalServerData->GetSequenceNumber() || + (serverData->GetSequenceNumber() == rvalServerData->GetSequenceNumber() && + iterator.mServerSubTlv->GetServer16() > rvalServerTlv->GetServer16())) + { + rvalServerTlv = iterator.mServerSubTlv; + rvalServerData = serverData; + } + } + + VerifyOrExit(rvalServerTlv != nullptr); + + aConfig.mServer16 = rvalServerTlv->GetServer16(); + aConfig.mSequenceNumber = rvalServerData->GetSequenceNumber(); + aConfig.mReregistrationDelay = rvalServerData->GetReregistrationDelay(); + aConfig.mMlrTimeout = rvalServerData->GetMlrTimeout(); + + error = OT_ERROR_NONE; + +exit: + return error; +} + +#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + +otError Manager::GetNextSrpServerInfo(Iterator &aIterator, SrpServer::Info &aInfo) const +{ + otError error = OT_ERROR_NOT_FOUND; + + if (aIterator.mServiceTlv == nullptr) + { + const uint8_t serviceData = SrpServer::kServiceNumber; + + aIterator.mServiceTlv = Get().FindService(kThreadEnterpriseNumber, &serviceData, sizeof(serviceData)); + VerifyOrExit(aIterator.mServiceTlv != nullptr); + } + else + { + VerifyOrExit(aIterator.mServerSubTlv != nullptr); + } + + while ((error = IterateToNextServer(aIterator)) == OT_ERROR_NONE) + { + const SrpServer::ServerData *serverData; + + if (aIterator.mServerSubTlv->GetServerDataLength() < sizeof(SrpServer::ServerData)) + { + continue; + } + + serverData = reinterpret_cast(aIterator.mServerSubTlv->GetServerData()); + + aInfo.mRloc16 = aIterator.mServerSubTlv->GetServer16(); + aInfo.mSockAddr.GetAddress().SetToRoutingLocator(Get().GetMeshLocalPrefix(), aInfo.mRloc16); + aInfo.mSockAddr.SetPort(serverData->GetPort()); + + break; + } + +exit: + return error; +} + +otError Manager::IterateToNextServer(Iterator &aIterator) const +{ + const NetworkDataTlv *start; + + start = + (aIterator.mServerSubTlv != nullptr) ? aIterator.mServerSubTlv->GetNext() : aIterator.mServiceTlv->GetSubTlvs(); + aIterator.mServerSubTlv = NetworkData::FindTlv(start, aIterator.mServiceTlv->GetNext()); + + return (aIterator.mServerSubTlv != nullptr) ? OT_ERROR_NONE : OT_ERROR_NOT_FOUND; +} + +} // namespace Service +} // namespace NetworkData +} // namespace ot diff --git a/src/core/thread/network_data_service.hpp b/src/core/thread/network_data_service.hpp new file mode 100644 index 000000000..eb99dbb98 --- /dev/null +++ b/src/core/thread/network_data_service.hpp @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2021, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file includes definitions related to Thread Network Data service/server entries. + */ + +#ifndef NETWORK_DATA_SERVICE_HPP_ +#define NETWORK_DATA_SERVICE_HPP_ + +#include "openthread-core-config.h" + +#include + +#include "backbone_router/bbr_leader.hpp" +#include "common/encoding.hpp" +#include "common/locator.hpp" +#include "common/non_copyable.hpp" +#include "net/socket.hpp" +#include "thread/network_data_tlvs.hpp" + +namespace ot { +namespace NetworkData { +namespace Service { + +using ot::Encoding::BigEndian::HostSwap16; +using ot::Encoding::BigEndian::HostSwap32; + +enum : uint32_t +{ + kThreadEnterpriseNumber = ServiceTlv::kThreadEnterpriseNumber, ///< Thread enterprise number. +}; + +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + +/** + * This type implements Thread Network Data "Backbone Router Service" server data generation and parsing. + * + */ +class BackboneRouter +{ +public: + enum : uint8_t + { + kServiceNumber = 0x01, ///< Backbone Router service data number (THREAD_SERVICE_DATA_BBR). + }; + + /** + * This class implements the generation and parsing of "Backbone Router Service" server data. + * + */ + OT_TOOL_PACKED_BEGIN + class ServerData + { + public: + /** + * This method returns the length (in bytes) of server data. + * + * @returns The server data length in bytes. + * + */ + uint8_t GetLength(void) const { return sizeof(ServerData); } + + /** + * This method returns the sequence number of Backbone Router. + * + * @returns The sequence number of the Backbone Router. + * + */ + uint8_t GetSequenceNumber(void) const { return mSequenceNumber; } + + /** + * This method sets the sequence number of Backbone Router. + * + * @param[in] aSequenceNumber The sequence number of Backbone Router. + * + */ + void SetSequenceNumber(uint8_t aSequenceNumber) { mSequenceNumber = aSequenceNumber; } + + /** + * This method returns the Registration Delay (in seconds) of Backbone Router. + * + * @returns The BBR Registration Delay (in seconds) of Backbone Router. + * + */ + uint16_t GetReregistrationDelay(void) const { return HostSwap16(mReregistrationDelay); } + + /** + * This method sets the Registration Delay (in seconds) of Backbone Router. + * + * @param[in] aReregistrationDelay The Registration Delay (in seconds) of Backbone Router. + * + */ + void SetReregistrationDelay(uint16_t aReregistrationDelay) + { + mReregistrationDelay = HostSwap16(aReregistrationDelay); + } + + /** + * This method returns the multicast listener report timeout (in seconds) of Backbone Router. + * + * @returns The multicast listener report timeout (in seconds) of Backbone Router. + * + */ + uint32_t GetMlrTimeout(void) const { return HostSwap32(mMlrTimeout); } + + /** + * This method sets multicast listener report timeout (in seconds) of Backbone Router. + * + * @param[in] aMlrTimeout The multicast listener report timeout (in seconds) of Backbone Router. + * + */ + void SetMlrTimeout(uint32_t aMlrTimeout) { mMlrTimeout = HostSwap32(aMlrTimeout); } + + private: + uint8_t mSequenceNumber; + uint16_t mReregistrationDelay; + uint32_t mMlrTimeout; + } OT_TOOL_PACKED_END; + + BackboneRouter(void) = delete; +}; + +#endif // #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + +/** + * This type implements Thread Network Data "SRP Server Service" server data generation and parsing. + * + */ +class SrpServer +{ +public: + enum : uint8_t + { + kServiceNumber = OPENTHREAD_CONFIG_SRP_SERVER_SERVICE_NUMBER, ///< SRP Sever Service number + }; + + /** + * This structure represents information about an SRP server (from "SRP Server Service" Server entries). + * + */ + struct Info + { + Ip6::SockAddr mSockAddr; ///< The SRP server address (IPv6 address and port number). + uint16_t mRloc16; ///< The RLOC16 of SRP server. + }; + + /** + * This class implements generation and parsing of "SRP Server Service" server data. + * + */ + OT_TOOL_PACKED_BEGIN + class ServerData + { + public: + /** This method returns the length (in bytes) of server data. + * + * @returns The server data length in bytes. + * + */ + uint8_t GetLength(void) const { return sizeof(ServerData); } + + /** + * This method returns the port number being used by the SRP server. + * + * @return The port number of SPR server. + * + */ + uint16_t GetPort(void) const { return HostSwap16(mPort); } + + /** + * This method sets the SRP port number in `ServerData`. + * + * @param[in] aPort The port number of SRP server. + * + */ + void SetPort(uint16_t aPort) { mPort = HostSwap16(aPort); } + + private: + uint16_t mPort; + } OT_TOOL_PACKED_END; + + SrpServer(void) = delete; +}; + +/** + * This class manages the Thread Service entries in Thread Network Data. + * + */ +class Manager : public InstanceLocator, private NonCopyable +{ +public: + /** + * This class represents an iterator used to iterate through Network Data Service entries. + * + */ + class Iterator : public Clearable + { + friend class Manager; + + public: + /** + * This constructor initializes the iterator (as empty/clear). + * + */ + Iterator(void) + : mServiceTlv(nullptr) + , mServerSubTlv(nullptr) + { + } + + private: + const ServiceTlv *mServiceTlv; + const ServerTlv * mServerSubTlv; + }; + + /** + * This constructor initializes the `Manager` object. + * + * @param[in] aInstance A reference to the OpenThread instance. + * + */ + explicit Manager(Instance &aInstance) + : InstanceLocator(aInstance) + { + } + +#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE + /** + * This method adds a Thread Service entry to the local Thread Network Data. + * + * When successfully added, this method also invokes `Notifier::HandleServerDataUpdated()` to register the changes + * in local Network Data with leader. + * + * The template type `ServiceType` has the following requirements: + * - It MUST have a constant `ServiceType::kServiceNumber` specifying the service number. + * - It MUST define nested type `ServiceType::ServerData` representing the server data (and its format). + * - The `ServiceType::ServerData` MUST provide `GetLength()` method returning the length of server data. + * + * @tparam ServiceType The service type to be added. + * + * @param[in] aServerData The server data. + * @param[in] aServerStable The Stable flag value for Server TLV. + * + * @retval OT_ERROR_NONE Successfully added the Service entry. + * @retval OT_ERROR_NO_BUFS Insufficient space to add the Service entry. + * + */ + template + otError Add(const typename ServiceType::ServerData &aServerData, bool aServerStable = true) + { + return AddService(ServiceType::kServiceNumber, aServerStable, &aServerData, aServerData.GetLength()); + } + + /** + * This method removed a Thread Service entry to the local Thread Network Data. + * + * When successfully removed, this method also invokes `Notifier::HandleServerDataUpdated()` to register the + * changes in local Network Data with leader. + * + * The template type `ServiceType` has the following requirements: + * - It MUST have a constant `ServiceType::kServiceNumber` specifying the service number. + * + * @tparam ServiceType The service type to be removed. + * + * @retval OT_ERROR_NONE Successfully removed the Service entry. + * @retval OT_ERROR_NOT_FOUND Could not find the Service entry. + * + */ + template otError Remove(void) { return RemoveService(ServiceType::kServiceNumber); } + +#endif + + /** + * This method gets the Service ID for the specified service from Thread Network Data. + * + * The template type `ServiceType` has the following requirements: + * - It MUST have a constant `ServiceType::kServiceNumber` specifying the service number. + * + * @tparam ServiceType The service type to be added. + * + * @param[in] aServerStable The Stable flag value for Server TLV + * @param[out] aServiceId A reference where to put the Service ID. + * + * @retval OT_ERROR_NONE Successfully got the Service ID. + * @retval OT_ERROR_NOT_FOUND The specified service was not found. + * + */ + template otError GetServiceId(bool aServerStable, uint8_t &aServiceId) const + { + return GetServiceId(ServiceType::kServiceNumber, aServerStable, aServiceId); + } + +#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) + /** + * This method gets the Primary Backbone Router (PBBR) in the Thread Network Data. + * + * @param[out] aConfig The Primary Backbone Router configuration. + * + * @retval OT_ERROR_NONE Successfully got the Primary Backbone Router configuration. + * @retval OT_ERROR_NOT_FOUND No Backbone Router Service in the Thread Network. + * + */ + otError GetBackboneRouterPrimary(ot::BackboneRouter::BackboneRouterConfig &aConfig) const; +#endif + + /** + * This method gets the next SRP server info from the Thread Network Data "SRP Server Service" entries. + * + * This method allows caller to iterate through all server entries for Network Data "SRP Server Service". To get + * the first entry @p aIterator should be cleared (e.g., a new instance of `Iterator` or calling `Clear()` method). + * + * @param[inout] aIterator A reference to an iterator. + * @param[out] aInfo A reference to `SrpServer::Info` to return the next SRP server info. + * + * @retval OT_ERROR_NONE Successfully got the next SRP server info. @p aInfo and @p aIterator are updated. + * @retval OT_ERROR_NOT_FOUND No more SRP server entries in Network Data. + * + */ + otError GetNextSrpServerInfo(Iterator &aIterator, SrpServer::Info &aInfo) const; + +private: +#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE + otError AddService(uint8_t aServiceNumber, bool aServerStable, const void *aServerData, uint8_t aServerDataLength); + otError RemoveService(uint8_t aServiceNumber); +#endif + + otError GetServiceId(uint8_t aServiceNumber, bool aServerStable, uint8_t &aServiceId) const; + otError IterateToNextServer(Iterator &aIterator) const; +}; + +} // namespace Service +} // namespace NetworkData +} // namespace ot + +#endif // NETWORK_DATA_SERVICE_HPP_ diff --git a/src/core/thread/network_data_tlvs.hpp b/src/core/thread/network_data_tlvs.hpp index ed01d0036..ceac70893 100644 --- a/src/core/thread/network_data_tlvs.hpp +++ b/src/core/thread/network_data_tlvs.hpp @@ -990,9 +990,12 @@ class ServiceTlv : public NetworkDataTlv public: enum { - kType = kTypeService, ///< The TLV Type. - kThreadEnterpriseNumber = 44970, ///< Thread enterprise number. - kServiceDataBackboneRouter = 0x01, ///< const THREAD_SERVICE_DATA_BBR + kType = kTypeService, ///< The TLV Type. + }; + + enum : uint32_t + { + kThreadEnterpriseNumber = 44970, ///< Thread enterprise number. }; /** @@ -1287,67 +1290,6 @@ private: uint16_t mServer16; } OT_TOOL_PACKED_END; -OT_TOOL_PACKED_BEGIN -class BackboneRouterServerData -{ -public: - /** - * This method returns the sequence number of Backbone Router. - * - * @returns The sequence number of the Backbone Router. - * - */ - uint8_t GetSequenceNumber(void) const { return mSequenceNumber; } - - /** - * This method sets the sequence number of Backbone Router. - * - * @param[in] aSequenceNumber The sequence number of Backbone Router. - * - */ - void SetSequenceNumber(uint8_t aSequenceNumber) { mSequenceNumber = aSequenceNumber; } - - /** - * This method returns the Registration Delay (in seconds) of Backbone Router. - * - * @returns The BBR Registration Delay (in seconds) of Backbone Router. - * - */ - uint16_t GetReregistrationDelay(void) const { return HostSwap16(mReregistrationDelay); } - - /** - * This method sets the Registration Delay (in seconds) of Backbone Router. - * - * @param[in] aReregistrationDelay The Registration Delay (in seconds) of Backbone Router. - * - */ - void SetReregistrationDelay(uint16_t aReregistrationDelay) - { - mReregistrationDelay = HostSwap16(aReregistrationDelay); - } - - /** - * This method returns the multicast listener report timeout (in seconds) of Backbone Router. - * - * @returns The multicast listener report timeout (in seconds) of Backbone Router. - * - */ - uint32_t GetMlrTimeout(void) const { return HostSwap32(mMlrTimeout); } - - /** - * This method sets multicast listener report timeout (in seconds) of Backbone Router. - * - * @param[in] aMlrTimeout The multicast listener report timeout (in seconds) of Backbone Router. - * - */ - void SetMlrTimeout(uint32_t aMlrTimeout) { mMlrTimeout = HostSwap32(aMlrTimeout); } - -private: - uint8_t mSequenceNumber; - uint16_t mReregistrationDelay; - uint32_t mMlrTimeout; -} OT_TOOL_PACKED_END; - /** * @} * diff --git a/src/core/thread/thread_netif.cpp b/src/core/thread/thread_netif.cpp index e8248c2b9..c64ecc1f9 100644 --- a/src/core/thread/thread_netif.cpp +++ b/src/core/thread/thread_netif.cpp @@ -86,6 +86,7 @@ ThreadNetif::ThreadNetif(Instance &aInstance) #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE , mNetworkDataNotifier(aInstance) #endif + , mNetworkDataServiceManager(aInstance) #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE , mNetworkDiagnostic(aInstance) #endif diff --git a/src/core/thread/thread_netif.hpp b/src/core/thread/thread_netif.hpp index a80a71c56..ffa49e821 100644 --- a/src/core/thread/thread_netif.hpp +++ b/src/core/thread/thread_netif.hpp @@ -95,6 +95,7 @@ #include "thread/mle_router.hpp" #include "thread/network_data_local.hpp" #include "thread/network_data_notifier.hpp" +#include "thread/network_data_service.hpp" #include "thread/network_diagnostic.hpp" #include "thread/panid_query_server.hpp" #include "thread/radio_selector.hpp" @@ -227,6 +228,7 @@ private: #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE NetworkData::Notifier mNetworkDataNotifier; #endif + NetworkData::Service::Manager mNetworkDataServiceManager; #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE NetworkDiagnostic::NetworkDiagnostic mNetworkDiagnostic; #endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE