diff options
author | Jiaming Wang <wangjm92@gmail.com> | 2021-10-12 16:03:58 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-12 16:03:58 -0700 |
commit | 816aff033865abbede1528956ef0ea6ad9302348 (patch) | |
tree | b485252a99dbd7508bf19ce940c484be81fbae9f /src/agent | |
parent | abcabb03811033d5f41d5fea741bdcf41832f6c6 (diff) | |
download | ot-br-posix-816aff033865abbede1528956ef0ea6ad9302348.tar.gz |
[build] refactor ot-br-agent (#1025)
Added library otbr-border-agent and otbr-sdp-proxy. Functionality of
ot-br-posix remains unchanged.
Diffstat (limited to 'src/agent')
-rw-r--r-- | src/agent/CMakeLists.txt | 18 | ||||
-rw-r--r-- | src/agent/advertising_proxy.cpp | 415 | ||||
-rw-r--r-- | src/agent/advertising_proxy.hpp | 164 | ||||
-rw-r--r-- | src/agent/agent_instance.hpp | 4 | ||||
-rw-r--r-- | src/agent/border_agent.cpp | 400 | ||||
-rw-r--r-- | src/agent/border_agent.hpp | 191 | ||||
-rw-r--r-- | src/agent/discovery_proxy.cpp | 339 | ||||
-rw-r--r-- | src/agent/discovery_proxy.hpp | 110 | ||||
-rw-r--r-- | src/agent/main.cpp | 2 | ||||
-rw-r--r-- | src/agent/ncp_openthread.cpp | 288 | ||||
-rw-r--r-- | src/agent/ncp_openthread.hpp | 187 | ||||
-rw-r--r-- | src/agent/thread_helper.cpp | 450 | ||||
-rw-r--r-- | src/agent/thread_helper.hpp | 240 |
13 files changed, 8 insertions, 2800 deletions
diff --git a/src/agent/CMakeLists.txt b/src/agent/CMakeLists.txt index 68099a3f..ebe02011 100644 --- a/src/agent/CMakeLists.txt +++ b/src/agent/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, The OpenThread Authors. +# Copyright (c) 2020-2021, The OpenThread Authors. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -27,20 +27,10 @@ # add_executable(otbr-agent - advertising_proxy.cpp - advertising_proxy.hpp agent_instance.cpp agent_instance.hpp - border_agent.cpp - border_agent.hpp - discovery_proxy.cpp - discovery_proxy.hpp main.cpp uris.hpp - ncp_openthread.cpp - ncp_openthread.hpp - thread_helper.cpp - thread_helper.hpp instance_params.cpp instance_params.hpp ) @@ -54,14 +44,16 @@ target_link_libraries(otbr-agent PRIVATE openthread-posix openthread-cli-ftd openthread-ftd - openthread-posix openthread-spinel-rcp openthread-hdlc + otbr-border-agent + otbr-sdp-proxy + otbr-ncp otbr-common otbr-utils ) -add_dependencies(otbr-agent ot-ctl print-ot-config) +add_dependencies(otbr-agent ot-ctl print-ot-config otbr-border-agent otbr-sdp-proxy otbr-utils otbr-ncp) install(TARGETS otbr-agent DESTINATION sbin) if(CMAKE_VERSION VERSION_LESS 3.13) diff --git a/src/agent/advertising_proxy.cpp b/src/agent/advertising_proxy.cpp deleted file mode 100644 index ab3881cb..00000000 --- a/src/agent/advertising_proxy.cpp +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Copyright (c) 2020, 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 - * The file implements the Advertising Proxy. - */ - -#define OTBR_LOG_TAG "ADPROXY" - -#include "agent/advertising_proxy.hpp" - -#if OTBR_ENABLE_SRP_ADVERTISING_PROXY - -#if !OTBR_ENABLE_MDNS_AVAHI && !OTBR_ENABLE_MDNS_MDNSSD && !OTBR_ENABLE_MDNS_MOJO -#error "The Advertising Proxy requires OTBR_ENABLE_MDNS_AVAHI, OTBR_ENABLE_MDNS_MDNSSD or OTBR_ENABLE_MDNS_MOJO" -#endif - -#include <string> - -#include <assert.h> - -#include "common/code_utils.hpp" -#include "common/dns_utils.hpp" -#include "common/logging.hpp" - -namespace otbr { - -static otError OtbrErrorToOtError(otbrError aError) -{ - otError error; - - switch (aError) - { - case OTBR_ERROR_NONE: - error = OT_ERROR_NONE; - break; - - case OTBR_ERROR_NOT_FOUND: - error = OT_ERROR_NOT_FOUND; - break; - - case OTBR_ERROR_PARSE: - error = OT_ERROR_PARSE; - break; - - case OTBR_ERROR_NOT_IMPLEMENTED: - error = OT_ERROR_NOT_IMPLEMENTED; - break; - - case OTBR_ERROR_INVALID_ARGS: - error = OT_ERROR_INVALID_ARGS; - break; - - case OTBR_ERROR_DUPLICATED: - error = OT_ERROR_DUPLICATED; - break; - - default: - error = OT_ERROR_FAILED; - break; - } - - return error; -} - -AdvertisingProxy::AdvertisingProxy(Ncp::ControllerOpenThread &aNcp, Mdns::Publisher &aPublisher) - : mNcp(aNcp) - , mPublisher(aPublisher) -{ -} - -otbrError AdvertisingProxy::Start(void) -{ - otSrpServerSetServiceUpdateHandler(GetInstance(), AdvertisingHandler, this); - - mPublisher.SetPublishServiceHandler(PublishServiceHandler, this); - mPublisher.SetPublishHostHandler(PublishHostHandler, this); - - otbrLogInfo("Started"); - - return OTBR_ERROR_NONE; -} - -void AdvertisingProxy::Stop() -{ - mPublisher.SetPublishServiceHandler(nullptr, nullptr); - mPublisher.SetPublishHostHandler(nullptr, nullptr); - - // Outstanding updates will fail on the SRP server because of timeout. - // TODO: handle this case gracefully. - - // Stop receiving SRP server events. - if (GetInstance() != nullptr) - { - otSrpServerSetServiceUpdateHandler(GetInstance(), nullptr, nullptr); - } - - otbrLogInfo("Stopped"); -} - -void AdvertisingProxy::AdvertisingHandler(otSrpServerServiceUpdateId aId, - const otSrpServerHost * aHost, - uint32_t aTimeout, - void * aContext) -{ - static_cast<AdvertisingProxy *>(aContext)->AdvertisingHandler(aId, aHost, aTimeout); -} - -void AdvertisingProxy::AdvertisingHandler(otSrpServerServiceUpdateId aId, - const otSrpServerHost * aHost, - uint32_t aTimeout) -{ - OTBR_UNUSED_VARIABLE(aTimeout); - - OutstandingUpdate *update = nullptr; - otbrError error = OTBR_ERROR_NONE; - - mOutstandingUpdates.emplace_back(); - update = &mOutstandingUpdates.back(); - update->mId = aId; - - error = PublishHostAndItsServices(aHost, update); - - if (error != OTBR_ERROR_NONE || update->mCallbackCount == 0) - { - mOutstandingUpdates.pop_back(); - otSrpServerHandleServiceUpdateResult(GetInstance(), aId, OtbrErrorToOtError(error)); - } -} - -void AdvertisingProxy::PublishServiceHandler(const char *aName, const char *aType, otbrError aError, void *aContext) -{ - std::string name(aName); - std::string type(aType); - AdvertisingProxy *thisPtr = static_cast<AdvertisingProxy *>(aContext); - - thisPtr->mTaskRunner.Post( - [name, type, aError, thisPtr]() { thisPtr->PublishServiceHandler(name.c_str(), type.c_str(), aError); }); -} - -void AdvertisingProxy::PublishServiceHandler(const char *aName, const char *aType, otbrError aError) -{ - otbrError error = OTBR_ERROR_NONE; - - otbrLogInfo("Handle publish service '%s.%s' result: %d", aName, aType, aError); - - // TODO: there may be same names between two SRP updates. - for (auto update = mOutstandingUpdates.begin(); update != mOutstandingUpdates.end(); ++update) - { - for (auto nameAndType = update->mServiceNames.begin(); nameAndType != update->mServiceNames.end(); - ++nameAndType) - { - if (aName != nameAndType->first || !Mdns::Publisher::IsServiceTypeEqual(aType, nameAndType->second.c_str())) - { - continue; - } - - if (aError != OTBR_ERROR_NONE || update->mCallbackCount == 1) - { - otSrpServerServiceUpdateId updateId = update->mId; - - // Erase before notifying OpenThread, because there are chances that new - // elements may be added to `otSrpServerHandleServiceUpdateResult` and - // the iterator will be invalidated. - mOutstandingUpdates.erase(update); - otSrpServerHandleServiceUpdateResult(GetInstance(), updateId, OtbrErrorToOtError(aError)); - } - else - { - update->mServiceNames.erase(nameAndType); - --update->mCallbackCount; - } - ExitNow(); - } - } - -exit: - if (error != OTBR_ERROR_NONE) - { - otbrLogWarning("Failed to handle result of service %s", aName); - } -} - -void AdvertisingProxy::PublishHostHandler(const char *aName, otbrError aError, void *aContext) -{ - std::string name(aName); - AdvertisingProxy *thisPtr = static_cast<AdvertisingProxy *>(aContext); - - thisPtr->mTaskRunner.Post([name, aError, thisPtr]() { thisPtr->PublishHostHandler(name.c_str(), aError); }); -} - -void AdvertisingProxy::PublishHostHandler(const char *aName, otbrError aError) -{ - otbrError error = OTBR_ERROR_NONE; - - otbrLogInfo("Handle publish host '%s' result: %d", aName, aError); - - for (auto update = mOutstandingUpdates.begin(); update != mOutstandingUpdates.end(); ++update) - { - if (update->mHostNamePublished || aName != update->mHostName) - { - continue; - } - - if (aError != OTBR_ERROR_NONE || update->mCallbackCount == 1) - { - otSrpServerServiceUpdateId updateId = update->mId; - - // Erase before notifying OpenThread, because there are chances that new - // elements may be added to `otSrpServerHandleServiceUpdateResult` and - // the iterator will be invalidated. - mOutstandingUpdates.erase(update); - otSrpServerHandleServiceUpdateResult(GetInstance(), updateId, OtbrErrorToOtError(aError)); - } - else - { - update->mHostNamePublished = true; - --update->mCallbackCount; - } - ExitNow(); - } - -exit: - if (error != OTBR_ERROR_NONE) - { - otbrLogWarning("Failed to handle result of host %s", aName); - } -} - -void AdvertisingProxy::PublishAllHostsAndServices(void) -{ - const otSrpServerHost *host = nullptr; - - VerifyOrExit(mPublisher.IsStarted(), mPublisher.Start()); - - otbrLogInfo("Publish all hosts and services"); - while ((host = otSrpServerGetNextHost(GetInstance(), host))) - { - PublishHostAndItsServices(host, nullptr); - } - -exit: - return; -} - -void AdvertisingProxy::Update(MainloopContext &aMainloop) -{ - mTaskRunner.Update(aMainloop); -} - -void AdvertisingProxy::Process(const MainloopContext &aMainloop) -{ - mTaskRunner.Process(aMainloop); -} - -otbrError AdvertisingProxy::PublishHostAndItsServices(const otSrpServerHost *aHost, OutstandingUpdate *aUpdate) -{ - otbrError error = OTBR_ERROR_NONE; - const char * fullHostName; - std::string hostName; - std::string hostDomain; - const otIp6Address * hostAddress; - uint8_t hostAddressNum; - bool hostDeleted; - const otSrpServerService *service; - - fullHostName = otSrpServerHostGetFullName(aHost); - - otbrLogInfo("Advertise SRP service updates: host=%s", fullHostName); - - SuccessOrExit(error = SplitFullHostName(fullHostName, hostName, hostDomain)); - hostAddress = otSrpServerHostGetAddresses(aHost, &hostAddressNum); - hostDeleted = otSrpServerHostIsDeleted(aHost); - - if (aUpdate) - { - aUpdate->mCallbackCount += !hostDeleted; - aUpdate->mHostName = hostName; - service = nullptr; - while ((service = otSrpServerHostFindNextService(aHost, service, OT_SRP_SERVER_FLAGS_BASE_TYPE_SERVICE_ONLY, - /* aServiceName */ nullptr, /* aInstanceName */ nullptr))) - { - aUpdate->mCallbackCount += !hostDeleted && !otSrpServerServiceIsDeleted(service); - } - } - - if (!hostDeleted) - { - // TODO: select a preferred address or advertise all addresses from SRP client. - otbrLogInfo("Publish SRP host: %s", fullHostName); - SuccessOrExit(error = - mPublisher.PublishHost(hostName.c_str(), hostAddress[0].mFields.m8, sizeof(hostAddress[0]))); - } - else - { - otbrLogInfo("Unpublish SRP host: %s", fullHostName); - SuccessOrExit(error = mPublisher.UnpublishHost(hostName.c_str())); - } - - service = nullptr; - while ((service = otSrpServerHostFindNextService(aHost, service, OT_SRP_SERVER_FLAGS_BASE_TYPE_SERVICE_ONLY, - /* aServiceName */ nullptr, /* aInstanceName */ nullptr))) - { - const char *fullServiceName = otSrpServerServiceGetFullName(service); - std::string serviceName; - std::string serviceType; - std::string serviceDomain; - - SuccessOrExit(error = SplitFullServiceInstanceName(fullServiceName, serviceName, serviceType, serviceDomain)); - - if (aUpdate) - { - aUpdate->mServiceNames.emplace_back(serviceName, serviceType); - } - - if (!hostDeleted && !otSrpServerServiceIsDeleted(service)) - { - Mdns::Publisher::TxtList txtList = MakeTxtList(service); - Mdns::Publisher::SubTypeList subTypeList = MakeSubTypeList(service); - - otbrLogInfo("Publish SRP service: %s", fullServiceName); - SuccessOrExit(error = mPublisher.PublishService(hostName.c_str(), otSrpServerServiceGetPort(service), - serviceName.c_str(), serviceType.c_str(), subTypeList, - txtList)); - } - else - { - otbrLogInfo("Unpublish SRP service: %s", fullServiceName); - SuccessOrExit(error = mPublisher.UnpublishService(serviceName.c_str(), serviceType.c_str())); - } - } - -exit: - if (error != OTBR_ERROR_NONE) - { - otbrLogInfo("Failed to advertise SRP service updates %p", aHost); - } - return error; -} - -Mdns::Publisher::TxtList AdvertisingProxy::MakeTxtList(const otSrpServerService *aSrpService) -{ - const uint8_t * txtData; - uint16_t txtDataLength = 0; - otDnsTxtEntryIterator iterator; - otDnsTxtEntry txtEntry; - Mdns::Publisher::TxtList txtList; - - txtData = otSrpServerServiceGetTxtData(aSrpService, &txtDataLength); - - otDnsInitTxtEntryIterator(&iterator, txtData, txtDataLength); - - while (otDnsGetNextTxtEntry(&iterator, &txtEntry) == OT_ERROR_NONE) - { - txtList.emplace_back(txtEntry.mKey, txtEntry.mValue, txtEntry.mValueLength); - } - - return txtList; -} - -Mdns::Publisher::SubTypeList AdvertisingProxy::MakeSubTypeList(const otSrpServerService *aSrpService) -{ - const otSrpServerHost * host = otSrpServerServiceGetHost(aSrpService); - const char * instanceName = otSrpServerServiceGetInstanceName(aSrpService); - const otSrpServerService * subService = nullptr; - Mdns::Publisher::SubTypeList subTypeList; - - while ((subService = otSrpServerHostFindNextService( - host, subService, (OT_SRP_SERVER_SERVICE_FLAG_SUB_TYPE | OT_SRP_SERVER_SERVICE_FLAG_ACTIVE), - /* aServiceName */ nullptr, instanceName)) != nullptr) - { - char subLabel[OT_DNS_MAX_LABEL_SIZE]; - - if (otSrpServerServiceGetServiceSubTypeLabel(subService, subLabel, sizeof(subLabel)) == OT_ERROR_NONE) - { - subTypeList.emplace_back(subLabel); - } - else - { - otbrLogWarning("Failed to retrieve subtype of SRP service: %s", otSrpServerServiceGetFullName(aSrpService)); - } - } - - return subTypeList; -} - -} // namespace otbr - -#endif // OTBR_ENABLE_SRP_ADVERTISING_PROXY diff --git a/src/agent/advertising_proxy.hpp b/src/agent/advertising_proxy.hpp deleted file mode 100644 index 4d05782f..00000000 --- a/src/agent/advertising_proxy.hpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2020, 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 for Advertising Proxy. - */ - -#ifndef OTBR_SRP_ADVERTISING_PROXY_HPP_ -#define OTBR_SRP_ADVERTISING_PROXY_HPP_ - -#if OTBR_ENABLE_SRP_ADVERTISING_PROXY - -#include <stdint.h> - -#include <openthread/instance.h> -#include <openthread/srp_server.h> - -#include "agent/ncp_openthread.hpp" -#include "common/mainloop.hpp" -#include "common/task_runner.hpp" -#include "mdns/mdns.hpp" - -namespace otbr { - -/** - * This class implements the Advertising Proxy. - * - */ -class AdvertisingProxy : public MainloopProcessor -{ -public: - /** - * This constructor initializes the Advertising Proxy object. - * - * @param[in] aNcp A reference to the NCP controller. - * @param[in] aPublisher A reference to the mDNS publisher. - * - */ - explicit AdvertisingProxy(Ncp::ControllerOpenThread &aNcp, Mdns::Publisher &aPublisher); - - /** - * This method starts the Advertising Proxy. - * - * @retval OTBR_ERROR_NONE Successfully started the Advertising Proxy. - * @retval ... Failed to start the Advertising Proxy. - * - */ - otbrError Start(void); - - /** - * This method stops the Advertising Proxy. - * - */ - void Stop(); - - /** - * This method publishes all registered hosts and services. - * - */ - void PublishAllHostsAndServices(void); - - /** - * This method updates the mainloop context. - * - * @param[inout] aMainloop A reference to the mainloop to be updated. - * - */ - void Update(MainloopContext &aMainloop) override; - - /** - * This method processes mainloop events. - * - * @param[in] aMainloop A reference to the mainloop context. - * - */ - void Process(const MainloopContext &aMainloop) override; - -private: - struct OutstandingUpdate - { - typedef std::vector<std::pair<std::string, std::string>> ServiceNameList; - - otSrpServerServiceUpdateId mId; // The ID of the SRP service update transaction. - std::string mHostName; // The host name. - ServiceNameList mServiceNames; // The list of service instance and name pairs to be updated. - uint32_t mCallbackCount = 0; // The number of callbacks which we are waiting for. - bool mHostNamePublished = false; // Is the host name already published? - }; - - static void AdvertisingHandler(otSrpServerServiceUpdateId aId, - const otSrpServerHost * aHost, - uint32_t aTimeout, - void * aContext); - void AdvertisingHandler(otSrpServerServiceUpdateId aId, const otSrpServerHost *aHost, uint32_t aTimeout); - - static Mdns::Publisher::TxtList MakeTxtList(const otSrpServerService *aSrpService); - static Mdns::Publisher::SubTypeList MakeSubTypeList(const otSrpServerService *aSrpService); - - static void PublishServiceHandler(const char *aName, const char *aType, otbrError aError, void *aContext); - void PublishServiceHandler(const char *aName, const char *aType, otbrError aError); - static void PublishHostHandler(const char *aName, otbrError aError, void *aContext); - void PublishHostHandler(const char *aName, otbrError aError); - - /** - * This method publishes a specified host and its services. - * - * It also makes a OutstandingUpdate object when needed. - * - * @param[in] aHost A pointer to the host. - * @param[in] aUpdate A pointer to the output OutstandingUpdate object. When it's not null, the method will - * fill its fields, otherwise it's ignored. - * - * @retval OTBR_ERROR_NONE Successfully published the host and its services. - * @retval ... Failed to publish the host and/or its services. - * - */ - otbrError PublishHostAndItsServices(const otSrpServerHost *aHost, OutstandingUpdate *aUpdate); - - otInstance *GetInstance(void) { return mNcp.GetInstance(); } - - // A reference to the NCP controller, has no ownership. - Ncp::ControllerOpenThread &mNcp; - - // A reference to the mDNS publisher, has no ownership. - Mdns::Publisher &mPublisher; - - // A vector that tracks outstanding updates. - std::vector<OutstandingUpdate> mOutstandingUpdates; - - // Task runner for running tasks in the context of the main thread. - TaskRunner mTaskRunner; -}; - -} // namespace otbr - -#endif // OTBR_ENABLE_SRP_ADVERTISING_PROXY - -#endif // OTBR_SRP_ADVERTISING_PROXY_HPP_ diff --git a/src/agent/agent_instance.hpp b/src/agent/agent_instance.hpp index 92d13dd7..b5c92cb6 100644 --- a/src/agent/agent_instance.hpp +++ b/src/agent/agent_instance.hpp @@ -41,10 +41,10 @@ #include <sys/select.h> #include <sys/types.h> -#include "agent/border_agent.hpp" #include "agent/instance_params.hpp" -#include "agent/ncp_openthread.hpp" +#include "border_agent/border_agent.hpp" #include "common/mainloop.hpp" +#include "ncp/ncp_openthread.hpp" namespace otbr { diff --git a/src/agent/border_agent.cpp b/src/agent/border_agent.cpp deleted file mode 100644 index 638b2a8a..00000000 --- a/src/agent/border_agent.cpp +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (c) 2017, 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 - * The file implements the Thread border agent. - */ - -#define OTBR_LOG_TAG "AGENT" - -#include "agent/border_agent.hpp" - -#include <arpa/inet.h> -#include <assert.h> -#include <errno.h> -#include <netinet/in.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <openthread/border_agent.h> -#include <openthread/thread_ftd.h> -#include <openthread/platform/toolchain.h> - -#include "agent/ncp_openthread.hpp" -#include "agent/uris.hpp" -#if OTBR_ENABLE_BACKBONE_ROUTER -#include "backbone_router/backbone_agent.hpp" -#endif -#include "common/byteswap.hpp" -#include "common/code_utils.hpp" -#include "common/logging.hpp" -#include "common/tlv.hpp" -#include "common/types.hpp" -#include "utils/hex.hpp" -#include "utils/strcpy_utils.hpp" - -namespace otbr { - -static const char kBorderAgentServiceType[] = "_meshcop._udp"; ///< Border agent service type of mDNS -static const char kBorderAgentServiceInstanceName[] = - OTBR_MESHCOP_SERVICE_INSTANCE_NAME; ///< Border agent service name of mDNS - -/** - * Locators - * - */ -enum -{ - kAloc16Leader = 0xfc00, ///< leader anycast locator. - kInvalidLocator = 0xffff, ///< invalid locator. -}; - -uint32_t BorderAgent::StateBitmap::ToUint32(void) const -{ - uint32_t bitmap = 0; - - bitmap |= mConnectionMode << 0; - bitmap |= mThreadIfStatus << 3; - bitmap |= mAvailability << 5; - bitmap |= mBbrIsActive << 7; - bitmap |= mBbrIsPrimary << 8; - - return bitmap; -} - -BorderAgent::BorderAgent(otbr::Ncp::ControllerOpenThread &aNcp) - : mNcp(aNcp) -#if OTBR_ENABLE_MDNS_AVAHI || OTBR_ENABLE_MDNS_MDNSSD || OTBR_ENABLE_MDNS_MOJO - , mPublisher(Mdns::Publisher::Create(AF_UNSPEC, /* aDomain */ nullptr, HandleMdnsState, this)) -#if OTBR_ENABLE_SRP_ADVERTISING_PROXY - , mAdvertisingProxy(aNcp, *mPublisher) -#endif -#else - , mPublisher(nullptr) -#endif -#if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY - , mDiscoveryProxy(aNcp, *mPublisher) -#endif -#if OTBR_ENABLE_BACKBONE_ROUTER - , mBackboneAgent(aNcp) -#endif -{ -} - -void BorderAgent::Init(void) -{ - mNcp.AddThreadStateChangedCallback([this](otChangedFlags aFlags) { HandleThreadStateChanged(aFlags); }); - -#if OTBR_ENABLE_BACKBONE_ROUTER - mBackboneAgent.Init(); -#endif - - if (IsThreadStarted()) - { - Start(); - } - else - { - Stop(); - } -} - -otbrError BorderAgent::Start(void) -{ - otbrError error = OTBR_ERROR_NONE; - - VerifyOrExit(IsThreadStarted(), errno = EAGAIN, error = OTBR_ERROR_ERRNO); - - // In case we didn't receive Thread down event. - Stop(); - -#if OTBR_ENABLE_MDNS_AVAHI || OTBR_ENABLE_MDNS_MDNSSD || OTBR_ENABLE_MDNS_MOJO -#if OTBR_ENABLE_SRP_ADVERTISING_PROXY - mAdvertisingProxy.Start(); -#endif - UpdateMeshCopService(); - -#if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY - mDiscoveryProxy.Start(); -#endif - -#endif // OTBR_ENABLE_MDNS_AVAHI || OTBR_ENABLE_MDNS_MDNSSD || OTBR_ENABLE_MDNS_MOJO - -exit: - otbrLogResult(error, "Start Thread Border Agent"); - return error; -} - -void BorderAgent::Stop(void) -{ - otbrLogInfo("Stop Thread Border Agent"); - -#if OTBR_ENABLE_MDNS_AVAHI || OTBR_ENABLE_MDNS_MDNSSD || OTBR_ENABLE_MDNS_MOJO - mPublisher->Stop(); -#if OTBR_ENABLE_SRP_ADVERTISING_PROXY - mAdvertisingProxy.Stop(); -#endif - -#if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY - mDiscoveryProxy.Stop(); -#endif - -#endif -} - -void BorderAgent::HandleMdnsState(void *aContext, Mdns::Publisher::State aState) -{ - static_cast<BorderAgent *>(aContext)->HandleMdnsState(aState); -} - -BorderAgent::~BorderAgent(void) -{ - Stop(); - - if (mPublisher != nullptr) - { - delete mPublisher; - mPublisher = nullptr; - } -} - -void BorderAgent::HandleMdnsState(Mdns::Publisher::State aState) -{ - switch (aState) - { - case Mdns::Publisher::State::kReady: - UpdateMeshCopService(); -#if OTBR_ENABLE_SRP_ADVERTISING_PROXY - mAdvertisingProxy.PublishAllHostsAndServices(); -#endif - break; - default: - otbrLogWarning("mDNS service not available!"); - break; - } -} - -void BorderAgent::Update(MainloopContext &aMainloop) -{ -#if OTBR_ENABLE_BACKBONE_ROUTER - mBackboneAgent.Update(aMainloop); -#endif -#if OTBR_ENABLE_SRP_ADVERTISING_PROXY - mAdvertisingProxy.Update(aMainloop); -#endif - - if (mPublisher != nullptr) - { - mPublisher->Update(aMainloop); - } -} - -void BorderAgent::Process(const MainloopContext &aMainloop) -{ -#if OTBR_ENABLE_BACKBONE_ROUTER - mBackboneAgent.Process(aMainloop); -#endif -#if OTBR_ENABLE_SRP_ADVERTISING_PROXY - mAdvertisingProxy.Process(aMainloop); -#endif - - if (mPublisher != nullptr) - { - mPublisher->Process(aMainloop); - } -} - -void BorderAgent::PublishMeshCopService(void) -{ - StateBitmap state; - uint32_t stateUint32; - otInstance * instance = mNcp.GetInstance(); - const otExtendedPanId * extPanId = otThreadGetExtendedPanId(instance); - const otExtAddress * extAddr = otLinkGetExtendedAddress(instance); - const char * networkName = otThreadGetNetworkName(instance); - Mdns::Publisher::TxtList txtList{{"rv", "1"}}; - - otbrLogInfo("Publish meshcop service %s.%s.local.", kBorderAgentServiceInstanceName, kBorderAgentServiceType); - - txtList.emplace_back("nn", networkName); - txtList.emplace_back("xp", extPanId->m8, sizeof(extPanId->m8)); - txtList.emplace_back("tv", mNcp.GetThreadVersion()); - - // "dd" represents for device discriminator which - // should always be the IEEE 802.15.4 extended address. - txtList.emplace_back("dd", extAddr->m8, sizeof(extAddr->m8)); - - state.mConnectionMode = kConnectionModePskc; - state.mAvailability = kAvailabilityHigh; -#if OTBR_ENABLE_BACKBONE_ROUTER - state.mBbrIsActive = otBackboneRouterGetState(instance) != OT_BACKBONE_ROUTER_STATE_DISABLED; - state.mBbrIsPrimary = otBackboneRouterGetState(instance) == OT_BACKBONE_ROUTER_STATE_PRIMARY; -#endif - switch (otThreadGetDeviceRole(instance)) - { - case OT_DEVICE_ROLE_DISABLED: - state.mThreadIfStatus = kThreadIfStatusNotInitialized; - break; - case OT_DEVICE_ROLE_DETACHED: - state.mThreadIfStatus = kThreadIfStatusInitialized; - break; - default: - state.mThreadIfStatus = kThreadIfStatusActive; - } - - stateUint32 = htobe32(state.ToUint32()); - txtList.emplace_back("sb", reinterpret_cast<uint8_t *>(&stateUint32), sizeof(stateUint32)); - - if (state.mThreadIfStatus == kThreadIfStatusActive) - { - otError error; - otOperationalDataset activeDataset; - uint64_t activeTimestamp; - uint32_t partitionId; - - if ((error = otDatasetGetActive(instance, &activeDataset)) != OT_ERROR_NONE) - { - otbrLogWarning("Failed to get active dataset: %s", otThreadErrorToString(error)); - } - else - { - activeTimestamp = htobe64(activeDataset.mActiveTimestamp); - txtList.emplace_back("at", reinterpret_cast<uint8_t *>(&activeTimestamp), sizeof(activeTimestamp)); - } - - partitionId = otThreadGetPartitionId(instance); - txtList.emplace_back("pt", reinterpret_cast<uint8_t *>(&partitionId), sizeof(partitionId)); - } - -#if OTBR_ENABLE_BACKBONE_ROUTER - if (state.mBbrIsActive) - { - otBackboneRouterConfig bbrConfig; - uint16_t bbrPort = htobe16(BackboneRouter::BackboneAgent::kBackboneUdpPort); - - otBackboneRouterGetConfig(instance, &bbrConfig); - txtList.emplace_back("sq", &bbrConfig.mSequenceNumber, sizeof(bbrConfig.mSequenceNumber)); - txtList.emplace_back("bb", reinterpret_cast<const uint8_t *>(&bbrPort), sizeof(bbrPort)); - } - - txtList.emplace_back("dn", otThreadGetDomainName(instance)); -#endif - - mPublisher->PublishService(/* aHostName */ nullptr, otBorderAgentGetUdpPort(instance), - kBorderAgentServiceInstanceName, kBorderAgentServiceType, Mdns::Publisher::SubTypeList{}, - txtList); -} - -void BorderAgent::UnpublishMeshCopService(void) -{ - assert(IsThreadStarted()); - VerifyOrExit(!mNetworkName.empty()); - - otbrLogInfo("Unpublish meshcop service %s.%s.local.", kBorderAgentServiceInstanceName, kBorderAgentServiceType); - - mPublisher->UnpublishService(kBorderAgentServiceInstanceName, kBorderAgentServiceType); - -exit: - return; -} - -void BorderAgent::UpdateMeshCopService(void) -{ - assert(IsThreadStarted()); - - const char *networkName = otThreadGetNetworkName(mNcp.GetInstance()); - - VerifyOrExit(mPublisher->IsStarted(), mPublisher->Start()); - VerifyOrExit(IsPskcInitialized(), UnpublishMeshCopService()); - - PublishMeshCopService(); - mNetworkName = networkName; - -exit: - return; -} - -void BorderAgent::HandleThreadStateChanged(otChangedFlags aFlags) -{ - VerifyOrExit(mPublisher != nullptr); - VerifyOrExit(aFlags & (OT_CHANGED_THREAD_ROLE | OT_CHANGED_THREAD_EXT_PANID | OT_CHANGED_THREAD_NETWORK_NAME | - OT_CHANGED_ACTIVE_DATASET | OT_CHANGED_THREAD_PARTITION_ID | - OT_CHANGED_THREAD_BACKBONE_ROUTER_STATE | OT_CHANGED_PSKC)); - - if (aFlags & OT_CHANGED_THREAD_ROLE) - { - otbrLogInfo("Thread is %s", (IsThreadStarted() ? "up" : "down")); - - if (IsThreadStarted()) - { - Start(); - } - else - { - Stop(); - } - } - else if (IsThreadStarted()) - { - UpdateMeshCopService(); - } - -exit: - return; -} - -bool BorderAgent::IsThreadStarted(void) const -{ - otDeviceRole role = otThreadGetDeviceRole(mNcp.GetInstance()); - - return role == OT_DEVICE_ROLE_CHILD || role == OT_DEVICE_ROLE_ROUTER || role == OT_DEVICE_ROLE_LEADER; -} - -bool BorderAgent::IsPskcInitialized(void) const -{ - bool initialized = false; - otPskc pskc; - - otThreadGetPskc(mNcp.GetInstance(), &pskc); - - for (uint8_t byte : pskc.m8) - { - if (byte != 0x00) - { - initialized = true; - break; - } - } - - return initialized; -} - -} // namespace otbr diff --git a/src/agent/border_agent.hpp b/src/agent/border_agent.hpp deleted file mode 100644 index 7fca894b..00000000 --- a/src/agent/border_agent.hpp +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2017, 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 definition for Thread border agent. - */ - -#ifndef OTBR_AGENT_BORDER_AGENT_HPP_ -#define OTBR_AGENT_BORDER_AGENT_HPP_ - -#include <vector> - -#include <stdint.h> - -#include "agent/advertising_proxy.hpp" -#include "agent/discovery_proxy.hpp" -#include "agent/instance_params.hpp" -#include "agent/ncp_openthread.hpp" -#include "common/mainloop.hpp" -#include "mdns/mdns.hpp" - -#if OTBR_ENABLE_BACKBONE_ROUTER -#include "backbone_router/backbone_agent.hpp" -#endif - -#ifndef OTBR_VENDOR_NAME -#define OTBR_VENDOR_NAME "OpenThread" -#endif - -#ifndef OTBR_PRODUCT_NAME -#define OTBR_PRODUCT_NAME "BorderRouter" -#endif - -#ifndef OTBR_MESHCOP_SERVICE_INSTANCE_NAME -#define OTBR_MESHCOP_SERVICE_INSTANCE_NAME OTBR_VENDOR_NAME "_" OTBR_PRODUCT_NAME -#endif - -namespace otbr { - -/** - * @addtogroup border-router-border-agent - * - * @brief - * This module includes definition for Thread border agent - * - * @{ - */ - -/** - * This class implements Thread border agent functionality. - * - */ -class BorderAgent : public MainloopProcessor -{ -public: - /** - * The constructor to initialize the Thread border agent. - * - * @param[in] aNcp A reference to the NCP controller. - * - */ - BorderAgent(otbr::Ncp::ControllerOpenThread &aNcp); - - ~BorderAgent(void) override; - - /** - * This method initialize border agent service. - * - */ - void Init(void); - - /** - * This method updates the mainloop context. - * - * @param[inout] aMainloop A reference to the mainloop to be updated. - * - */ - void Update(MainloopContext &aMainloop) override; - - /** - * This method processes mainloop events. - * - * @param[in] aMainloop A reference to the mainloop context. - * - */ - void Process(const MainloopContext &aMainloop) override; - -private: - enum : uint8_t - { - kConnectionModeDisabled = 0, - kConnectionModePskc = 1, - kConnectionModePskd = 2, - kConnectionModeVendor = 3, - kConnectionModeX509 = 4, - }; - - enum : uint8_t - { - kThreadIfStatusNotInitialized = 0, - kThreadIfStatusInitialized = 1, - kThreadIfStatusActive = 2, - }; - - enum : uint8_t - { - kAvailabilityInfrequent = 0, - kAvailabilityHigh = 1, - }; - - struct StateBitmap - { - uint32_t mConnectionMode : 3; - uint32_t mThreadIfStatus : 2; - uint32_t mAvailability : 2; - uint32_t mBbrIsActive : 1; - uint32_t mBbrIsPrimary : 1; - - StateBitmap(void) - : mConnectionMode(0) - , mThreadIfStatus(0) - , mAvailability(0) - , mBbrIsActive(0) - , mBbrIsPrimary(0) - { - } - - uint32_t ToUint32(void) const; - }; - - otbrError Start(void); - void Stop(void); - static void HandleMdnsState(void *aContext, Mdns::Publisher::State aState); - void HandleMdnsState(Mdns::Publisher::State aState); - void PublishMeshCopService(void); - void UnpublishMeshCopService(void); - void UpdateMeshCopService(void); - - void HandleThreadStateChanged(otChangedFlags aFlags); - - bool IsThreadStarted(void) const; - bool IsPskcInitialized(void) const; - - otbr::Ncp::ControllerOpenThread &mNcp; - Mdns::Publisher * mPublisher; - std::string mNetworkName; - -#if OTBR_ENABLE_SRP_ADVERTISING_PROXY - AdvertisingProxy mAdvertisingProxy; -#endif -#if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY - Dnssd::DiscoveryProxy mDiscoveryProxy; -#endif -#if OTBR_ENABLE_BACKBONE_ROUTER - BackboneRouter::BackboneAgent mBackboneAgent; -#endif -}; - -/** - * @} - */ - -} // namespace otbr - -#endif // OTBR_AGENT_BORDER_AGENT_HPP_ diff --git a/src/agent/discovery_proxy.cpp b/src/agent/discovery_proxy.cpp deleted file mode 100644 index 02f798a0..00000000 --- a/src/agent/discovery_proxy.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/* - * 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 - * The file implements the DNS-SD Discovery Proxy. - */ - -#if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY - -#define OTBR_LOG_TAG "DPROXY" - -#include "agent/discovery_proxy.hpp" - -#include <algorithm> -#include <string> - -#include <assert.h> - -#include <openthread/dnssd_server.h> - -#include "common/code_utils.hpp" -#include "common/dns_utils.hpp" -#include "common/logging.hpp" - -namespace otbr { -namespace Dnssd { - -DiscoveryProxy::DiscoveryProxy(Ncp::ControllerOpenThread &aNcp, Mdns::Publisher &aPublisher) - : mNcp(aNcp) - , mMdnsPublisher(aPublisher) -{ -} - -void DiscoveryProxy::Start(void) -{ - otDnssdQuerySetCallbacks(mNcp.GetInstance(), &DiscoveryProxy::OnDiscoveryProxySubscribe, - &DiscoveryProxy::OnDiscoveryProxyUnsubscribe, this); - - mMdnsPublisher.SetSubscriptionCallbacks( - [this](const std::string &aType, const Mdns::Publisher::DiscoveredInstanceInfo &aInstanceInfo) { - OnServiceDiscovered(aType, aInstanceInfo); - }, - - [this](const std::string &aHostName, const Mdns::Publisher::DiscoveredHostInfo &aHostInfo) { - OnHostDiscovered(aHostName, aHostInfo); - }); - - otbrLogInfo("started"); -} - -void DiscoveryProxy::Stop(void) -{ - otDnssdQuerySetCallbacks(mNcp.GetInstance(), nullptr, nullptr, nullptr); - mMdnsPublisher.SetSubscriptionCallbacks(nullptr, nullptr); - - otbrLogInfo("stopped"); -} - -void DiscoveryProxy::OnDiscoveryProxySubscribe(void *aContext, const char *aFullName) -{ - reinterpret_cast<DiscoveryProxy *>(aContext)->OnDiscoveryProxySubscribe(aFullName); -} - -void DiscoveryProxy::OnDiscoveryProxySubscribe(const char *aFullName) -{ - std::string fullName(aFullName); - otbrError error = OTBR_ERROR_NONE; - DnsNameInfo nameInfo = SplitFullDnsName(fullName); - - otbrLogInfo("subscribe: %s", fullName.c_str()); - - if (GetServiceSubscriptionCount(nameInfo) == 1) - { - if (nameInfo.mHostName.empty()) - { - mMdnsPublisher.SubscribeService(nameInfo.mServiceName, nameInfo.mInstanceName); - } - else - { - mMdnsPublisher.SubscribeHost(nameInfo.mHostName); - } - } - - if (error != OTBR_ERROR_NONE) - { - otbrLogWarning("failed to subscribe %s: %s", fullName.c_str(), otbrErrorString(error)); - } -} - -void DiscoveryProxy::OnDiscoveryProxyUnsubscribe(void *aContext, const char *aFullName) -{ - reinterpret_cast<DiscoveryProxy *>(aContext)->OnDiscoveryProxyUnsubscribe(aFullName); -} - -void DiscoveryProxy::OnDiscoveryProxyUnsubscribe(const char *aFullName) -{ - std::string fullName(aFullName); - otbrError error = OTBR_ERROR_NONE; - DnsNameInfo nameInfo = SplitFullDnsName(fullName); - - otbrLogInfo("unsubscribe: %s", fullName.c_str()); - - if (GetServiceSubscriptionCount(nameInfo) == 1) - { - if (nameInfo.mHostName.empty()) - { - mMdnsPublisher.UnsubscribeService(nameInfo.mServiceName, nameInfo.mInstanceName); - } - else - { - mMdnsPublisher.UnsubscribeHost(nameInfo.mHostName); - } - } - if (error != OTBR_ERROR_NONE) - { - otbrLogWarning("failed to unsubscribe %s: %s", fullName.c_str(), otbrErrorString(error)); - } -} - -void DiscoveryProxy::OnServiceDiscovered(const std::string & aType, - const Mdns::Publisher::DiscoveredInstanceInfo &aInstanceInfo) -{ - otDnssdServiceInstanceInfo instanceInfo; - const otDnssdQuery * query = nullptr; - - otbrLogInfo("service discovered: %s, instance %s hostname %s addresses %zu port %d priority %d " - "weight %d", - aType.c_str(), aInstanceInfo.mName.c_str(), aInstanceInfo.mHostName.c_str(), - aInstanceInfo.mAddresses.size(), aInstanceInfo.mPort, aInstanceInfo.mPriority, aInstanceInfo.mWeight); - - CheckServiceNameSanity(aType); - CheckHostnameSanity(aInstanceInfo.mHostName); - - instanceInfo.mAddressNum = aInstanceInfo.mAddresses.size(); - - if (!aInstanceInfo.mAddresses.empty()) - { - instanceInfo.mAddresses = reinterpret_cast<const otIp6Address *>(&aInstanceInfo.mAddresses[0]); - } - else - { - instanceInfo.mAddresses = nullptr; - } - - instanceInfo.mPort = aInstanceInfo.mPort; - instanceInfo.mPriority = aInstanceInfo.mPriority; - instanceInfo.mWeight = aInstanceInfo.mWeight; - instanceInfo.mTxtLength = static_cast<uint16_t>(aInstanceInfo.mTxtData.size()); - instanceInfo.mTxtData = aInstanceInfo.mTxtData.data(); - instanceInfo.mTtl = CapTtl(aInstanceInfo.mTtl); - - while ((query = otDnssdGetNextQuery(mNcp.GetInstance(), query)) != nullptr) - { - std::string instanceName; - std::string serviceName; - std::string hostName; - std::string domain; - char queryName[OT_DNS_MAX_NAME_SIZE]; - otDnssdQueryType type = otDnssdGetQueryTypeAndName(query, &queryName); - otbrError splitError; - - switch (type) - { - case OT_DNSSD_QUERY_TYPE_BROWSE: - splitError = SplitFullServiceName(queryName, serviceName, domain); - assert(splitError == OTBR_ERROR_NONE); - break; - case OT_DNSSD_QUERY_TYPE_RESOLVE: - splitError = SplitFullServiceInstanceName(queryName, instanceName, serviceName, domain); - assert(splitError == OTBR_ERROR_NONE); - break; - default: - splitError = OTBR_ERROR_NOT_FOUND; - break; - } - if (splitError != OTBR_ERROR_NONE) - { - continue; - } - - if (serviceName == aType && (instanceName.empty() || instanceName == aInstanceInfo.mName)) - { - std::string serviceFullName = aType + "." + domain; - std::string hostName = TranslateDomain(aInstanceInfo.mHostName, domain); - std::string instanceFullName = aInstanceInfo.mName + "." + serviceFullName; - - instanceInfo.mFullName = instanceFullName.c_str(); - instanceInfo.mHostName = hostName.c_str(); - - otDnssdQueryHandleDiscoveredServiceInstance(mNcp.GetInstance(), serviceFullName.c_str(), &instanceInfo); - } - } -} - -void DiscoveryProxy::OnHostDiscovered(const std::string & aHostName, - const Mdns::Publisher::DiscoveredHostInfo &aHostInfo) -{ - otDnssdHostInfo hostInfo; - const otDnssdQuery *query = nullptr; - std::string resolvedHostName = aHostInfo.mHostName; - - otbrLogInfo("host discovered: %s hostname %s addresses %zu", aHostName.c_str(), aHostInfo.mHostName.c_str(), - aHostInfo.mAddresses.size()); - - if (resolvedHostName.empty()) - { - resolvedHostName = aHostName + ".local."; - } - - CheckHostnameSanity(resolvedHostName); - - hostInfo.mAddressNum = aHostInfo.mAddresses.size(); - if (!aHostInfo.mAddresses.empty()) - { - hostInfo.mAddresses = reinterpret_cast<const otIp6Address *>(&aHostInfo.mAddresses[0]); - } - else - { - hostInfo.mAddresses = nullptr; - } - - hostInfo.mTtl = CapTtl(aHostInfo.mTtl); - - while ((query = otDnssdGetNextQuery(mNcp.GetInstance(), query)) != nullptr) - { - std::string hostName, domain; - char queryName[OT_DNS_MAX_NAME_SIZE]; - otDnssdQueryType type = otDnssdGetQueryTypeAndName(query, &queryName); - otbrError splitError; - - if (type != OT_DNSSD_QUERY_TYPE_RESOLVE_HOST) - { - continue; - } - splitError = SplitFullHostName(queryName, hostName, domain); - assert(splitError == OTBR_ERROR_NONE); - - if (hostName == aHostName) - { - std::string hostFullName = TranslateDomain(resolvedHostName, domain); - - otDnssdQueryHandleDiscoveredHost(mNcp.GetInstance(), hostFullName.c_str(), &hostInfo); - } - } -} - -std::string DiscoveryProxy::TranslateDomain(const std::string &aName, const std::string &aTargetDomain) -{ - std::string targetName; - std::string hostName; - std::string domain; - - VerifyOrExit(OTBR_ERROR_NONE == SplitFullHostName(aName, hostName, domain), targetName = aName); - VerifyOrExit(domain == "local.", targetName = aName); - - targetName = hostName + "." + aTargetDomain; - -exit: - otbrLogDebug("translate domain: %s => %s", aName.c_str(), targetName.c_str()); - return targetName; -} - -int DiscoveryProxy::GetServiceSubscriptionCount(const DnsNameInfo &aNameInfo) const -{ - const otDnssdQuery *query = nullptr; - int count = 0; - - while ((query = otDnssdGetNextQuery(mNcp.GetInstance(), query)) != nullptr) - { - char queryName[OT_DNS_MAX_NAME_SIZE]; - DnsNameInfo queryInfo; - - otDnssdGetQueryTypeAndName(query, &queryName); - queryInfo = SplitFullDnsName(queryName); - - count += (aNameInfo.mInstanceName == queryInfo.mInstanceName && - aNameInfo.mServiceName == queryInfo.mServiceName && aNameInfo.mHostName == queryInfo.mHostName); - } - - return count; -} - -void DiscoveryProxy::CheckServiceNameSanity(const std::string &aType) -{ - size_t dotpos; - - OTBR_UNUSED_VARIABLE(aType); - OTBR_UNUSED_VARIABLE(dotpos); - - assert(aType.length() > 0); - assert(aType[aType.length() - 1] != '.'); - dotpos = aType.find_first_of('.'); - assert(dotpos != std::string::npos); - assert(dotpos == aType.find_last_of('.')); -} - -void DiscoveryProxy::CheckHostnameSanity(const std::string &aHostName) -{ - OTBR_UNUSED_VARIABLE(aHostName); - - assert(aHostName.length() > 0); - assert(aHostName[aHostName.length() - 1] == '.'); -} - -uint32_t DiscoveryProxy::CapTtl(uint32_t aTtl) -{ - return std::min(aTtl, static_cast<uint32_t>(kServiceTtlCapLimit)); -} - -} // namespace Dnssd -} // namespace otbr - -#endif // OTBR_ENABLE_DNSSD_DISCOVERY_PROXY diff --git a/src/agent/discovery_proxy.hpp b/src/agent/discovery_proxy.hpp deleted file mode 100644 index ac8748bd..00000000 --- a/src/agent/discovery_proxy.hpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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 definition for DNS-SD Discovery Proxy. - */ - -#ifndef OTBR_AGENT_DISCOVERY_PROXY_HPP_ -#define OTBR_AGENT_DISCOVERY_PROXY_HPP_ - -#if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY - -#include <set> -#include <utility> - -#include <stdint.h> - -#include <openthread/dnssd_server.h> -#include <openthread/instance.h> - -#include "agent/ncp_openthread.hpp" -#include "common/dns_utils.hpp" -#include "mdns/mdns.hpp" - -namespace otbr { -namespace Dnssd { - -/** - * This class implements the DNS-SD Discovery Proxy. - * - */ -class DiscoveryProxy -{ -public: - /** - * This constructor initializes the Discovery Proxy instance. - * - * @param[in] aNcp A reference to the OpenThread Controller instance. - * @param[in] aPublisher A reference to the mDNS Publisher. - * - */ - explicit DiscoveryProxy(Ncp::ControllerOpenThread &aNcp, Mdns::Publisher &aPublisher); - - /** - * This method starts the Discovery Proxy. - * - */ - void Start(void); - - /** - * This method stops the Discovery Proxy. - * - */ - void Stop(void); - -private: - enum : uint32_t - { - kServiceTtlCapLimit = 10, // TTL cap limit for Discovery Proxy (in seconds). - }; - - static void OnDiscoveryProxySubscribe(void *aContext, const char *aFullName); - void OnDiscoveryProxySubscribe(const char *aSubscription); - static void OnDiscoveryProxyUnsubscribe(void *aContext, const char *aFullName); - void OnDiscoveryProxyUnsubscribe(const char *aSubscription); - int GetServiceSubscriptionCount(const DnsNameInfo &aNameInfo) const; - static std::string TranslateDomain(const std::string &aName, const std::string &aTargetDomain); - static void CheckServiceNameSanity(const std::string &aType); - static void CheckHostnameSanity(const std::string &aHostName); - void OnServiceDiscovered(const std::string & aSubscription, - const Mdns::Publisher::DiscoveredInstanceInfo &aInstanceInfo); - void OnHostDiscovered(const std::string &aHostName, const Mdns::Publisher::DiscoveredHostInfo &aHostInfo); - static uint32_t CapTtl(uint32_t aTtl); - - Ncp::ControllerOpenThread &mNcp; - Mdns::Publisher & mMdnsPublisher; -}; - -} // namespace Dnssd -} // namespace otbr - -#endif // OTBR_ENABLE_DNSSD_DISCOVERY_PROXY - -#endif // OTBR_AGENT_DISCOVERY_PROXY_HPP_ diff --git a/src/agent/main.cpp b/src/agent/main.cpp index 32c27e51..41a1f8e9 100644 --- a/src/agent/main.cpp +++ b/src/agent/main.cpp @@ -46,11 +46,11 @@ #include <openthread/platform/radio.h> #include "agent/agent_instance.hpp" -#include "agent/ncp_openthread.hpp" #include "common/code_utils.hpp" #include "common/logging.hpp" #include "common/mainloop.hpp" #include "common/types.hpp" +#include "ncp/ncp_openthread.hpp" #if OTBR_ENABLE_REST_SERVER #include "rest/rest_web_server.hpp" using otbr::rest::RestWebServer; diff --git a/src/agent/ncp_openthread.cpp b/src/agent/ncp_openthread.cpp deleted file mode 100644 index a6659cd4..00000000 --- a/src/agent/ncp_openthread.cpp +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (c) 2019, 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. - */ - -#define OTBR_LOG_TAG "AGENT" - -#include "agent/ncp_openthread.hpp" - -#include <assert.h> -#include <stdio.h> -#include <string.h> - -#include <openthread/backbone_router_ftd.h> -#include <openthread/dataset.h> -#include <openthread/logging.h> -#include <openthread/srp_server.h> -#include <openthread/tasklet.h> -#include <openthread/thread.h> -#include <openthread/thread_ftd.h> -#include <openthread/platform/logging.h> -#include <openthread/platform/misc.h> -#include <openthread/platform/radio.h> -#include <openthread/platform/settings.h> - -#include "common/code_utils.hpp" -#include "common/logging.hpp" -#include "common/types.hpp" - -#if OTBR_ENABLE_LEGACY -#include <ot-legacy-pairing-ext.h> -#endif - -namespace otbr { -namespace Ncp { - -static const uint16_t kThreadVersion11 = 2; ///< Thread Version 1.1 -static const uint16_t kThreadVersion12 = 3; ///< Thread Version 1.2 - -ControllerOpenThread::ControllerOpenThread(const char * aInterfaceName, - const std::vector<const char *> &aRadioUrls, - const char * aBackboneInterfaceName) - : mInstance(nullptr) -{ - VerifyOrDie(aRadioUrls.size() <= OT_PLATFORM_CONFIG_MAX_RADIO_URLS, "Too many Radio URLs!"); - - memset(&mConfig, 0, sizeof(mConfig)); - - mConfig.mInterfaceName = aInterfaceName; - mConfig.mBackboneInterfaceName = aBackboneInterfaceName; - for (const char *url : aRadioUrls) - { - mConfig.mRadioUrls[mConfig.mRadioUrlNum++] = url; - } - mConfig.mSpeedUpFactor = 1; -} - -ControllerOpenThread::~ControllerOpenThread(void) -{ - otSysDeinit(); -} - -otbrError ControllerOpenThread::Init(void) -{ - otbrError error = OTBR_ERROR_NONE; - otLogLevel level = OT_LOG_LEVEL_NONE; - - switch (otbrLogGetLevel()) - { - case OTBR_LOG_EMERG: - case OTBR_LOG_ALERT: - case OTBR_LOG_CRIT: - level = OT_LOG_LEVEL_CRIT; - break; - case OTBR_LOG_ERR: - case OTBR_LOG_WARNING: - level = OT_LOG_LEVEL_WARN; - break; - case OTBR_LOG_NOTICE: - level = OT_LOG_LEVEL_NOTE; - break; - case OTBR_LOG_INFO: - level = OT_LOG_LEVEL_INFO; - break; - case OTBR_LOG_DEBUG: - level = OT_LOG_LEVEL_DEBG; - break; - default: - ExitNow(error = OTBR_ERROR_OPENTHREAD); - break; - } - VerifyOrExit(otLoggingSetLevel(level) == OT_ERROR_NONE, error = OTBR_ERROR_OPENTHREAD); - - mInstance = otSysInit(&mConfig); - assert(mInstance != nullptr); - -#if OTBR_ENABLE_LEGACY - otLegacyInit(); -#endif - - { - otError result = otSetStateChangedCallback(mInstance, &ControllerOpenThread::HandleStateChanged, this); - - agent::ThreadHelper::LogOpenThreadResult("Set state callback", result); - VerifyOrExit(result == OT_ERROR_NONE, error = OTBR_ERROR_OPENTHREAD); - } - -#if OTBR_ENABLE_SRP_ADVERTISING_PROXY - otSrpServerSetEnabled(mInstance, /* aEnabled */ true); -#endif - - mThreadHelper = std::unique_ptr<otbr::agent::ThreadHelper>(new otbr::agent::ThreadHelper(mInstance, this)); - -exit: - return error; -} - -void ControllerOpenThread::HandleStateChanged(otChangedFlags aFlags) -{ - if (aFlags & OT_CHANGED_THREAD_ROLE) - { - switch (otThreadGetDeviceRole(mInstance)) - { - case OT_DEVICE_ROLE_DISABLED: -#if OTBR_ENABLE_LEGACY - otLegacyStop(); -#endif - break; - case OT_DEVICE_ROLE_CHILD: - case OT_DEVICE_ROLE_ROUTER: - case OT_DEVICE_ROLE_LEADER: -#if OTBR_ENABLE_LEGACY - otLegacyStart(); -#endif - break; - default: - break; - } - } - - for (auto &stateCallback : mThreadStateChangedCallbacks) - { - stateCallback(aFlags); - } - - mThreadHelper->StateChangedCallback(aFlags); -} - -void ControllerOpenThread::Update(MainloopContext &aMainloop) -{ - mTaskRunner.Update(aMainloop); - - if (otTaskletsArePending(mInstance)) - { - aMainloop.mTimeout = ToTimeval(Microseconds::zero()); - } - - otSysMainloopUpdate(mInstance, &aMainloop); -} - -void ControllerOpenThread::Process(const MainloopContext &aMainloop) -{ - otTaskletsProcess(mInstance); - - otSysMainloopProcess(mInstance, &aMainloop); - - mTaskRunner.Process(aMainloop); - - if (getenv("OTBR_NO_AUTO_ATTACH") == nullptr && mThreadHelper->TryResumeNetwork() == OT_ERROR_NONE) - { - setenv("OTBR_NO_AUTO_ATTACH", "1", 0); - } -} - -void ControllerOpenThread::PostTimerTask(Milliseconds aDelay, TaskRunner::Task<void> aTask) -{ - mTaskRunner.Post(std::move(aDelay), std::move(aTask)); -} - -void ControllerOpenThread::RegisterResetHandler(std::function<void(void)> aHandler) -{ - mResetHandlers.emplace_back(std::move(aHandler)); -} - -void ControllerOpenThread::AddThreadStateChangedCallback(ThreadStateChangedCallback aCallback) -{ - mThreadStateChangedCallbacks.emplace_back(std::move(aCallback)); -} - -void ControllerOpenThread::Reset(void) -{ - gPlatResetReason = OT_PLAT_RESET_REASON_SOFTWARE; - - otSysDeinit(); - mInstance = nullptr; - - Init(); - for (auto &handler : mResetHandlers) - { - handler(); - } - unsetenv("OTBR_NO_AUTO_ATTACH"); -} - -const char *ControllerOpenThread::GetThreadVersion(void) -{ - const char *version; - - switch (otThreadGetVersion()) - { - case kThreadVersion11: - version = "1.1.1"; - break; - case kThreadVersion12: - version = "1.2.0"; - break; - default: - otbrLogEmerg("Unexpected thread version %hu", otThreadGetVersion()); - exit(-1); - } - return version; -} - -/* - * Provide, if required an "otPlatLog()" function - */ -extern "C" void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) -{ - OT_UNUSED_VARIABLE(aLogRegion); - - otbrLogLevel otbrLogLevel; - - switch (aLogLevel) - { - case OT_LOG_LEVEL_NONE: - otbrLogLevel = OTBR_LOG_EMERG; - break; - case OT_LOG_LEVEL_CRIT: - otbrLogLevel = OTBR_LOG_CRIT; - break; - case OT_LOG_LEVEL_WARN: - otbrLogLevel = OTBR_LOG_WARNING; - break; - case OT_LOG_LEVEL_NOTE: - otbrLogLevel = OTBR_LOG_NOTICE; - break; - case OT_LOG_LEVEL_INFO: - otbrLogLevel = OTBR_LOG_INFO; - break; - case OT_LOG_LEVEL_DEBG: - otbrLogLevel = OTBR_LOG_DEBUG; - break; - default: - otbrLogLevel = OTBR_LOG_DEBUG; - break; - } - - va_list ap; - va_start(ap, aFormat); - otbrLogvNoFilter(otbrLogLevel, aFormat, ap); - va_end(ap); -} - -} // namespace Ncp -} // namespace otbr diff --git a/src/agent/ncp_openthread.hpp b/src/agent/ncp_openthread.hpp deleted file mode 100644 index 11aa8358..00000000 --- a/src/agent/ncp_openthread.hpp +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2017, 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 for NCP service. - */ - -#ifndef OTBR_AGENT_NCP_OPENTHREAD_HPP_ -#define OTBR_AGENT_NCP_OPENTHREAD_HPP_ - -#include <chrono> -#include <memory> - -#include <openthread/backbone_router_ftd.h> -#include <openthread/cli.h> -#include <openthread/instance.h> -#include <openthread/openthread-system.h> - -#include "agent/thread_helper.hpp" -#include "common/mainloop.hpp" -#include "common/task_runner.hpp" -#include "common/types.hpp" - -namespace otbr { -namespace Ncp { - -/** - * This interface defines NCP Controller functionality. - * - */ -class ControllerOpenThread : public MainloopProcessor -{ -public: - using ThreadStateChangedCallback = std::function<void(otChangedFlags aFlags)>; - - /** - * This constructor initializes this object. - * - * @param[in] aInterfaceName A string of the NCP interface name. - * @param[in] aRadioUrls The radio URLs (can be IEEE802.15.4 or TREL radio). - * @param[in] aBackboneInterfaceName The Backbone network interface name. - * - */ - ControllerOpenThread(const char * aInterfaceName, - const std::vector<const char *> &aRadioUrls, - const char * aBackboneInterfaceName); - - /** - * This method initalize the NCP controller. - * - * @retval OTBR_ERROR_NONE Successfully initialized NCP controller. - * - */ - otbrError Init(void); - - /** - * This method get mInstance pointer. - * - * @retval the pointer of mInstance. - * - */ - otInstance *GetInstance(void) { return mInstance; } - - /** - * This method gets the thread functionality helper. - * - * @retval the pointer to the helper object. - * - */ - otbr::agent::ThreadHelper *GetThreadHelper(void) { return mThreadHelper.get(); } - - /** - * This method updates the mainloop context. - * - * @param[inout] aMainloop A reference to the mainloop to be updated. - * - */ - void Update(MainloopContext &aMainloop) override; - - /** - * This method processes mainloop events. - * - * @param[in] aMainloop A reference to the mainloop context. - * - */ - void Process(const MainloopContext &aMainloop) override; - - /** - * This method posts a task to the timer - * - * @param[in] aDelay The delay in milliseconds before executing the task. - * @param[in] aTask The task function. - * - */ - void PostTimerTask(Milliseconds aDelay, TaskRunner::Task<void> aTask); - - /** - * This method registers a reset handler. - * - * @param[in] aHandler The handler function. - * - */ - void RegisterResetHandler(std::function<void(void)> aHandler); - - /** - * This method adds a event listener for Thread state changes. - * - * @param[in] aCallback The callback to receive Thread state changed events. - * - */ - void AddThreadStateChangedCallback(ThreadStateChangedCallback aCallback); - - /** - * This method resets the OpenThread instance. - * - */ - void Reset(void); - - /** - * This method returns the Thread protocol version as a string. - * - * @returns A pointer to the Thread version string. - * - */ - static const char *GetThreadVersion(void); - - ~ControllerOpenThread(void) override; - -private: - static void HandleStateChanged(otChangedFlags aFlags, void *aContext) - { - static_cast<ControllerOpenThread *>(aContext)->HandleStateChanged(aFlags); - } - void HandleStateChanged(otChangedFlags aFlags); - - static void HandleBackboneRouterDomainPrefixEvent(void * aContext, - otBackboneRouterDomainPrefixEvent aEvent, - const otIp6Prefix * aDomainPrefix); - void HandleBackboneRouterDomainPrefixEvent(otBackboneRouterDomainPrefixEvent aEvent, - const otIp6Prefix * aDomainPrefix); - -#if OTBR_ENABLE_DUA_ROUTING - static void HandleBackboneRouterNdProxyEvent(void * aContext, - otBackboneRouterNdProxyEvent aEvent, - const otIp6Address * aAddress); - void HandleBackboneRouterNdProxyEvent(otBackboneRouterNdProxyEvent aEvent, const otIp6Address *aAddress); -#endif - - otInstance *mInstance; - - otPlatformConfig mConfig; - std::unique_ptr<otbr::agent::ThreadHelper> mThreadHelper; - std::vector<std::function<void(void)>> mResetHandlers; - TaskRunner mTaskRunner; - std::vector<ThreadStateChangedCallback> mThreadStateChangedCallbacks; -}; - -} // namespace Ncp -} // namespace otbr - -#endif // OTBR_AGENT_NCP_OPENTHREAD_HPP_ diff --git a/src/agent/thread_helper.cpp b/src/agent/thread_helper.cpp deleted file mode 100644 index f6e7eb26..00000000 --- a/src/agent/thread_helper.cpp +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright (c) 2020, 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. - */ - -#define OTBR_LOG_TAG "AGENT" - -#include "agent/thread_helper.hpp" - -#include <assert.h> -#include <limits.h> -#include <string.h> - -#include <string> - -#include <openthread/border_router.h> -#include <openthread/channel_manager.h> -#include <openthread/jam_detection.h> -#include <openthread/joiner.h> -#include <openthread/thread_ftd.h> -#include <openthread/platform/radio.h> - -#include "agent/ncp_openthread.hpp" -#include "common/byteswap.hpp" -#include "common/code_utils.hpp" -#include "common/logging.hpp" - -namespace otbr { -namespace agent { - -ThreadHelper::ThreadHelper(otInstance *aInstance, otbr::Ncp::ControllerOpenThread *aNcp) - : mInstance(aInstance) - , mNcp(aNcp) -{ -} - -void ThreadHelper::StateChangedCallback(otChangedFlags aFlags) -{ - if (aFlags & OT_CHANGED_THREAD_ROLE) - { - otDeviceRole role = otThreadGetDeviceRole(mInstance); - - for (const auto &handler : mDeviceRoleHandlers) - { - handler(role); - } - - if (role != OT_DEVICE_ROLE_DISABLED && role != OT_DEVICE_ROLE_DETACHED) - { - if (mAttachHandler != nullptr) - { - mAttachHandler(OT_ERROR_NONE); - mAttachHandler = nullptr; - } - else if (mJoinerHandler != nullptr) - { - mJoinerHandler(OT_ERROR_NONE); - mJoinerHandler = nullptr; - } - } - } -} - -void ThreadHelper::AddDeviceRoleHandler(DeviceRoleHandler aHandler) -{ - mDeviceRoleHandlers.emplace_back(aHandler); -} - -void ThreadHelper::Scan(ScanHandler aHandler) -{ - otError error = OT_ERROR_NONE; - - VerifyOrExit(aHandler != nullptr); - mScanHandler = aHandler; - mScanResults.clear(); - - error = - otLinkActiveScan(mInstance, /*scanChannels =*/0, /*scanDuration=*/0, &ThreadHelper::sActiveScanHandler, this); - -exit: - if (error != OT_ERROR_NONE) - { - if (aHandler) - { - mScanHandler(error, {}); - } - mScanHandler = nullptr; - } -} - -void ThreadHelper::RandomFill(void *aBuf, size_t size) -{ - std::uniform_int_distribution<> dist(0, UINT8_MAX); - uint8_t * buf = static_cast<uint8_t *>(aBuf); - - for (size_t i = 0; i < size; i++) - { - buf[i] = static_cast<uint8_t>(dist(mRandomDevice)); - } -} - -void ThreadHelper::sActiveScanHandler(otActiveScanResult *aResult, void *aThreadHelper) -{ - ThreadHelper *helper = static_cast<ThreadHelper *>(aThreadHelper); - - helper->ActiveScanHandler(aResult); -} - -void ThreadHelper::ActiveScanHandler(otActiveScanResult *aResult) -{ - if (aResult == nullptr) - { - if (mScanHandler != nullptr) - { - mScanHandler(OT_ERROR_NONE, mScanResults); - } - } - else - { - mScanResults.push_back(*aResult); - } -} - -uint8_t ThreadHelper::RandomChannelFromChannelMask(uint32_t aChannelMask) -{ - // 8 bit per byte - constexpr uint8_t kNumChannels = sizeof(aChannelMask) * 8; - uint8_t channels[kNumChannels]; - uint8_t numValidChannels = 0; - - for (uint8_t i = 0; i < kNumChannels; i++) - { - if (aChannelMask & (1 << i)) - { - channels[numValidChannels++] = i; - } - } - - return channels[std::uniform_int_distribution<unsigned int>(0, numValidChannels - 1)(mRandomDevice)]; -} - -static otExtendedPanId ToOtExtendedPanId(uint64_t aExtPanId) -{ - otExtendedPanId extPanId; - uint64_t mask = UINT8_MAX; - - for (size_t i = 0; i < sizeof(uint64_t); i++) - { - extPanId.m8[i] = static_cast<uint8_t>((aExtPanId >> ((sizeof(uint64_t) - i - 1) * 8)) & mask); - } - - return extPanId; -} - -void ThreadHelper::Attach(const std::string & aNetworkName, - uint16_t aPanId, - uint64_t aExtPanId, - const std::vector<uint8_t> &aNetworkKey, - const std::vector<uint8_t> &aPSKc, - uint32_t aChannelMask, - ResultHandler aHandler) - -{ - otError error = OT_ERROR_NONE; - otExtendedPanId extPanId; - otNetworkKey networkKey; - otPskc pskc; - uint32_t channelMask; - uint8_t channel; - - VerifyOrExit(aHandler != nullptr, error = OT_ERROR_INVALID_ARGS); - VerifyOrExit(mAttachHandler == nullptr && mJoinerHandler == nullptr, error = OT_ERROR_INVALID_STATE); - mAttachHandler = aHandler; - VerifyOrExit(aNetworkKey.empty() || aNetworkKey.size() == sizeof(networkKey.m8), error = OT_ERROR_INVALID_ARGS); - VerifyOrExit(aPSKc.empty() || aPSKc.size() == sizeof(pskc.m8), error = OT_ERROR_INVALID_ARGS); - VerifyOrExit(aChannelMask != 0, error = OT_ERROR_INVALID_ARGS); - - while (aPanId == UINT16_MAX) - { - RandomFill(&aPanId, sizeof(aPanId)); - } - - if (aExtPanId != UINT64_MAX) - { - extPanId = ToOtExtendedPanId(aExtPanId); - } - else - { - *reinterpret_cast<uint64_t *>(&extPanId) = UINT64_MAX; - - while (*reinterpret_cast<uint64_t *>(&extPanId) == UINT64_MAX) - { - RandomFill(extPanId.m8, sizeof(extPanId.m8)); - } - } - - if (!aNetworkKey.empty()) - { - memcpy(networkKey.m8, &aNetworkKey[0], sizeof(networkKey.m8)); - } - else - { - RandomFill(networkKey.m8, sizeof(networkKey.m8)); - } - - if (!aPSKc.empty()) - { - memcpy(pskc.m8, &aPSKc[0], sizeof(pskc.m8)); - } - else - { - RandomFill(pskc.m8, sizeof(pskc.m8)); - } - - if (!otIp6IsEnabled(mInstance)) - { - SuccessOrExit(error = otIp6SetEnabled(mInstance, true)); - } - - SuccessOrExit(error = otThreadSetNetworkName(mInstance, aNetworkName.c_str())); - SuccessOrExit(error = otLinkSetPanId(mInstance, aPanId)); - SuccessOrExit(error = otThreadSetExtendedPanId(mInstance, &extPanId)); - SuccessOrExit(error = otThreadSetNetworkKey(mInstance, &networkKey)); - - channelMask = otPlatRadioGetPreferredChannelMask(mInstance) & aChannelMask; - - if (channelMask == 0) - { - channelMask = otLinkGetSupportedChannelMask(mInstance) & aChannelMask; - } - VerifyOrExit(channelMask != 0, otbrLogWarning("Invalid channel mask"), error = OT_ERROR_INVALID_ARGS); - - channel = RandomChannelFromChannelMask(channelMask); - SuccessOrExit(otLinkSetChannel(mInstance, channel)); - - SuccessOrExit(error = otThreadSetPskc(mInstance, &pskc)); - - SuccessOrExit(error = otThreadSetEnabled(mInstance, true)); -exit: - if (error != OT_ERROR_NONE) - { - if (aHandler) - { - aHandler(error); - } - mAttachHandler = nullptr; - } -} - -void ThreadHelper::Attach(ResultHandler aHandler) -{ - otError error = OT_ERROR_NONE; - - VerifyOrExit(mAttachHandler == nullptr && mJoinerHandler == nullptr, error = OT_ERROR_INVALID_STATE); - mAttachHandler = aHandler; - - if (!otIp6IsEnabled(mInstance)) - { - SuccessOrExit(error = otIp6SetEnabled(mInstance, true)); - } - SuccessOrExit(error = otThreadSetEnabled(mInstance, true)); - -exit: - if (error != OT_ERROR_NONE) - { - if (aHandler) - { - aHandler(error); - } - mAttachHandler = nullptr; - } -} - -otError ThreadHelper::Detach(void) -{ - otError error = OT_ERROR_NONE; - - SuccessOrExit(error = otThreadSetEnabled(mInstance, false)); - SuccessOrExit(error = otIp6SetEnabled(mInstance, false)); - -exit: - return error; -} - -otError ThreadHelper::Reset(void) -{ - mDeviceRoleHandlers.clear(); - otInstanceReset(mInstance); - - return OT_ERROR_NONE; -} - -void ThreadHelper::JoinerStart(const std::string &aPskd, - const std::string &aProvisioningUrl, - const std::string &aVendorName, - const std::string &aVendorModel, - const std::string &aVendorSwVersion, - const std::string &aVendorData, - ResultHandler aHandler) -{ - otError error = OT_ERROR_NONE; - - VerifyOrExit(aHandler != nullptr, error = OT_ERROR_INVALID_ARGS); - VerifyOrExit(mAttachHandler == nullptr && mJoinerHandler == nullptr, error = OT_ERROR_INVALID_STATE); - mJoinerHandler = aHandler; - - if (!otIp6IsEnabled(mInstance)) - { - SuccessOrExit(error = otIp6SetEnabled(mInstance, true)); - } - error = otJoinerStart(mInstance, aPskd.c_str(), aProvisioningUrl.c_str(), aVendorName.c_str(), aVendorModel.c_str(), - aVendorSwVersion.c_str(), aVendorData.c_str(), sJoinerCallback, this); -exit: - if (error != OT_ERROR_NONE) - { - if (aHandler) - { - aHandler(error); - } - mJoinerHandler = nullptr; - } -} - -void ThreadHelper::sJoinerCallback(otError aError, void *aThreadHelper) -{ - ThreadHelper *helper = static_cast<ThreadHelper *>(aThreadHelper); - - helper->JoinerCallback(aError); -} - -void ThreadHelper::JoinerCallback(otError aError) -{ - if (aError != OT_ERROR_NONE) - { - otbrLogWarning("Failed to join Thread network: %s", otThreadErrorToString(aError)); - mJoinerHandler(aError); - mJoinerHandler = nullptr; - } - else - { - LogOpenThreadResult("Start Thread network", otThreadSetEnabled(mInstance, true)); - } -} - -otError ThreadHelper::TryResumeNetwork(void) -{ - otError error = OT_ERROR_NONE; - - if (otLinkGetPanId(mInstance) != UINT16_MAX && otThreadGetDeviceRole(mInstance) == OT_DEVICE_ROLE_DISABLED) - { - if (!otIp6IsEnabled(mInstance)) - { - SuccessOrExit(error = otIp6SetEnabled(mInstance, true)); - SuccessOrExit(error = otThreadSetEnabled(mInstance, true)); - } - } - -exit: - if (error != OT_ERROR_NONE) - { - (void)otIp6SetEnabled(mInstance, false); - } - - return error; -} - -void ThreadHelper::LogOpenThreadResult(const char *aAction, otError aError) -{ - if (aError == OT_ERROR_NONE) - { - otbrLogInfo("%s: %s", aAction, otThreadErrorToString(aError)); - } - else - { - otbrLogWarning("%s: %s", aAction, otThreadErrorToString(aError)); - } -} - -#if OTBR_ENABLE_UNSECURE_JOIN -otError ThreadHelper::PermitUnsecureJoin(uint16_t aPort, uint32_t aSeconds) -{ - otError error = OT_ERROR_NONE; - otExtAddress steeringData; - - // 0xff to allow all devices to join - memset(&steeringData.m8, 0xff, sizeof(steeringData.m8)); - SuccessOrExit(error = otIp6AddUnsecurePort(mInstance, aPort)); - otThreadSetSteeringData(mInstance, &steeringData); - - if (aSeconds > 0) - { - auto delay = Milliseconds(aSeconds * 1000); - - ++mUnsecurePortRefCounter[aPort]; - - mNcp->PostTimerTask(delay, [this, aPort]() { - assert(mUnsecurePortRefCounter.find(aPort) != mUnsecurePortRefCounter.end()); - assert(mUnsecurePortRefCounter[aPort] > 0); - - if (--mUnsecurePortRefCounter[aPort] == 0) - { - otExtAddress noneAddress; - - // 0 to clean steering data - memset(&noneAddress.m8, 0, sizeof(noneAddress.m8)); - (void)otIp6RemoveUnsecurePort(mInstance, aPort); - otThreadSetSteeringData(mInstance, &noneAddress); - mUnsecurePortRefCounter.erase(aPort); - } - }); - } - else - { - otExtAddress noneAddress; - - memset(&noneAddress.m8, 0, sizeof(noneAddress.m8)); - (void)otIp6RemoveUnsecurePort(mInstance, aPort); - otThreadSetSteeringData(mInstance, &noneAddress); - } - -exit: - return error; -} -#endif - -} // namespace agent -} // namespace otbr diff --git a/src/agent/thread_helper.hpp b/src/agent/thread_helper.hpp deleted file mode 100644 index 8edab39a..00000000 --- a/src/agent/thread_helper.hpp +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (c) 2020, 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 for Thread helper. - */ - -#ifndef OTBR_THREAD_HELPER_HPP_ -#define OTBR_THREAD_HELPER_HPP_ - -#include <chrono> -#include <functional> -#include <map> -#include <random> -#include <string> -#include <vector> - -#include <openthread/instance.h> -#include <openthread/ip6.h> -#include <openthread/jam_detection.h> -#include <openthread/joiner.h> -#include <openthread/netdata.h> -#include <openthread/thread.h> - -namespace otbr { -namespace Ncp { -class ControllerOpenThread; -} -} // namespace otbr - -namespace otbr { -namespace agent { - -/** - * This class implements Thread helper. - */ -class ThreadHelper -{ -public: - using DeviceRoleHandler = std::function<void(otDeviceRole)>; - using ScanHandler = std::function<void(otError, const std::vector<otActiveScanResult> &)>; - using ResultHandler = std::function<void(otError)>; - - /** - * The constructor of a Thread helper. - * - * @param[in] aInstance The Thread instance. - * @param[in] aNcp The ncp controller. - * - */ - ThreadHelper(otInstance *aInstance, otbr::Ncp::ControllerOpenThread *aNcp); - - /** - * This method adds a callback for device role change. - * - * @param[in] aHandler The device role handler. - * - */ - void AddDeviceRoleHandler(DeviceRoleHandler aHandler); - - /** - * This method permits unsecure join on port. - * - * @param[in] aPort The port number. - * @param[in] aSeconds The timeout to close the port, 0 for never close. - * - * @returns The error value of underlying OpenThread api calls. - * - */ - otError PermitUnsecureJoin(uint16_t aPort, uint32_t aSeconds); - - /** - * This method performs a Thread network scan. - * - * @param[in] aHandler The scan result handler. - * - */ - void Scan(ScanHandler aHandler); - - /** - * This method attaches the device to the Thread network. - * - * @note The joiner start and the attach proccesses are exclusive - * - * @param[in] aNetworkName The network name. - * @param[in] aPanId The pan id, UINT16_MAX for random. - * @param[in] aExtPanId The extended pan id, UINT64_MAX for random. - * @param[in] aNetworkKey The network key, empty for random. - * @param[in] aPSKc The pre-shared commissioner key, empty for random. - * @param[in] aChannelMask A bitmask for valid channels, will random select one. - * @param[in] aHandler The attach result handler. - * - */ - void Attach(const std::string & aNetworkName, - uint16_t aPanId, - uint64_t aExtPanId, - const std::vector<uint8_t> &aNetworkKey, - const std::vector<uint8_t> &aPSKc, - uint32_t aChannelMask, - ResultHandler aHandler); - - /** - * This method detaches the device from the Thread network. - * - * @returns The error value of underlying OpenThread API calls. - * - */ - otError Detach(void); - - /** - * This method attaches the device to the Thread network. - * - * @note The joiner start and the attach proccesses are exclusive, and the - * network parameter will be set through the active dataset. - * - * @param[in] aHandler The attach result handler. - * - */ - void Attach(ResultHandler aHandler); - - /** - * This method resets the OpenThread stack. - * - * @returns The error value of underlying OpenThread api calls. - * - */ - otError Reset(void); - - /** - * This method triggers a thread join process. - * - * @note The joiner start and the attach proccesses are exclusive - * - * @param[in] aPskd The pre-shared key for device. - * @param[in] aProvisioningUrl The provision url. - * @param[in] aVendorName The vendor name. - * @param[in] aVendorModel The vendor model. - * @param[in] aVendorSwVersion The vendor software version. - * @param[in] aVendorData The vendor custom data. - * @param[in] aHandler The join result handler. - * - */ - void JoinerStart(const std::string &aPskd, - const std::string &aProvisioningUrl, - const std::string &aVendorName, - const std::string &aVendorModel, - const std::string &aVendorSwVersion, - const std::string &aVendorData, - ResultHandler aHandler); - - /** - * This method tries to restore the network after reboot - * - * @returns The error value of underlying OpenThread api calls. - * - */ - otError TryResumeNetwork(void); - - /** - * This method returns the underlying OpenThread instance. - * - * @returns The underlying instance. - * - */ - otInstance *GetInstance(void) { return mInstance; } - - /** - * This method handles OpenThread state changed notification. - * - * @param[in] aFlags A bit-field indicating specific state that has changed. See `OT_CHANGED_*` definitions. - * - */ - void StateChangedCallback(otChangedFlags aFlags); - - /** - * This method logs OpenThread action result. - * - * @param[in] aAction The action OpenThread performs. - * @param[in] aError The action result. - * - */ - static void LogOpenThreadResult(const char *aAction, otError aError); - -private: - static void sActiveScanHandler(otActiveScanResult *aResult, void *aThreadHelper); - void ActiveScanHandler(otActiveScanResult *aResult); - - static void sJoinerCallback(otError aError, void *aThreadHelper); - void JoinerCallback(otError aResult); - - void RandomFill(void *aBuf, size_t size); - uint8_t RandomChannelFromChannelMask(uint32_t aChannelMask); - - otInstance *mInstance; - - otbr::Ncp::ControllerOpenThread *mNcp; - - ScanHandler mScanHandler; - std::vector<otActiveScanResult> mScanResults; - - std::vector<DeviceRoleHandler> mDeviceRoleHandlers; - - std::map<uint16_t, size_t> mUnsecurePortRefCounter; - - ResultHandler mAttachHandler; - ResultHandler mJoinerHandler; - - std::random_device mRandomDevice; -}; - -} // namespace agent -} // namespace otbr - -#endif // OTBR_THREAD_HELPER_HPP_ |