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/ncp | |
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/ncp')
-rw-r--r-- | src/ncp/CMakeLists.txt | 36 | ||||
-rw-r--r-- | src/ncp/ncp_openthread.cpp | 288 | ||||
-rw-r--r-- | src/ncp/ncp_openthread.hpp | 187 |
3 files changed, 511 insertions, 0 deletions
diff --git a/src/ncp/CMakeLists.txt b/src/ncp/CMakeLists.txt new file mode 100644 index 00000000..cd86860c --- /dev/null +++ b/src/ncp/CMakeLists.txt @@ -0,0 +1,36 @@ +# +# 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. +# + +add_library(otbr-ncp + ncp_openthread.cpp + ncp_openthread.hpp +) + +target_link_libraries(otbr-ncp PRIVATE + otbr-common +) diff --git a/src/ncp/ncp_openthread.cpp b/src/ncp/ncp_openthread.cpp new file mode 100644 index 00000000..4f28f210 --- /dev/null +++ b/src/ncp/ncp_openthread.cpp @@ -0,0 +1,288 @@ +/* + * 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 "ncp/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/ncp/ncp_openthread.hpp b/src/ncp/ncp_openthread.hpp new file mode 100644 index 00000000..6a97ed1c --- /dev/null +++ b/src/ncp/ncp_openthread.hpp @@ -0,0 +1,187 @@ +/* + * 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 "common/mainloop.hpp" +#include "common/task_runner.hpp" +#include "common/types.hpp" +#include "utils/thread_helper.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_ |