From 59f7a9aed641bbcce2f06f38e380c8b76b0bcf00 Mon Sep 17 00:00:00 2001 From: Simon Lin Date: Fri, 13 Aug 2021 06:01:32 +0800 Subject: [PATCH] [posix] refine system initialization and deinitialization (#6886) This commit refines system initialization and de-initialization by separating the process before and after OpenThread instance creation and destruction: otSysInit(): Call platformInit() Create OpenThread Instance as `gInstance` Call platformSetUp() otSysDeinit(): Call platformTearDown() Destroy OpenThread Instance `gInstance` Call platformDeinit() This commit should help fix the issue that platform UDP sockets can not be created when constructing OpenThread instance. This commit contains other related changes: - otSysDeinit now destroys the OpenThread instance - posix/platform code use a global variable gInstance to track the single global OpenThread instance, instead of using multiple pointers in multiple files. --- src/posix/main.c | 8 +- src/posix/platform/backbone.cpp | 22 +-- src/posix/platform/daemon.cpp | 6 +- src/posix/platform/daemon.hpp | 4 +- .../include/openthread/openthread-system.h | 6 +- src/posix/platform/infra_if.cpp | 30 +++- src/posix/platform/infra_if.hpp | 32 +++- src/posix/platform/multicast_routing.cpp | 15 +- src/posix/platform/multicast_routing.hpp | 5 +- src/posix/platform/netif.cpp | 139 ++++++++---------- src/posix/platform/platform-posix.h | 68 +++++++-- src/posix/platform/system.cpp | 108 +++++++++++--- src/posix/platform/udp.cpp | 20 ++- src/posix/platform/udp.hpp | 7 +- 14 files changed, 308 insertions(+), 162 deletions(-) diff --git a/src/posix/main.c b/src/posix/main.c index 147372dc4..b6ea5b96b 100644 --- a/src/posix/main.c +++ b/src/posix/main.c @@ -296,10 +296,9 @@ static otInstance *InitInstance(PosixConfig *aConfig) IgnoreError(otLoggingSetLevel(aConfig->mLogLevel)); instance = otSysInit(&aConfig->mPlatformConfig); + VerifyOrDie(instance != NULL, OT_EXIT_FAILURE); syslog(LOG_INFO, "Thread interface: %s", otSysGetThreadNetifName()); - atexit(otSysDeinit); - if (aConfig->mPrintRadioVersion) { printf("%s\n", otPlatRadioGetVersionString(instance)); @@ -324,9 +323,10 @@ void otTaskletsSignalPending(otInstance *aInstance) void otPlatReset(otInstance *aInstance) { + OT_UNUSED_VARIABLE(aInstance); + gPlatResetReason = OT_PLAT_RESET_REASON_SOFTWARE; - otInstanceFinalize(aInstance); otSysDeinit(); longjmp(gResetJump, 1); @@ -430,7 +430,7 @@ int main(int argc, char *argv[]) #endif exit: - otInstanceFinalize(instance); + otSysDeinit(); return rval; } diff --git a/src/posix/platform/backbone.cpp b/src/posix/platform/backbone.cpp index 1fb8b8d03..4a29d0cab 100644 --- a/src/posix/platform/backbone.cpp +++ b/src/posix/platform/backbone.cpp @@ -46,10 +46,8 @@ unsigned int gBackboneNetifIndex = 0; static ot::Posix::MulticastRoutingManager sMulticastRoutingManager; #endif -void platformBackboneInit(otInstance *aInstance, const char *aInterfaceName) +void platformBackboneInit(const char *aInterfaceName) { - OT_UNUSED_VARIABLE(aInstance); - VerifyOrExit(aInterfaceName != nullptr && aInterfaceName[0] != '\0'); VerifyOrDie(strnlen(aInterfaceName, sizeof(gBackboneNetifName)) < sizeof(gBackboneNetifName), @@ -61,20 +59,26 @@ void platformBackboneInit(otInstance *aInstance, const char *aInterfaceName) otLogInfoPlat("Backbone interface is configured to %s (%d)", gBackboneNetifName, gBackboneNetifIndex); -#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE - sMulticastRoutingManager.Init(aInstance); -#endif - exit: return; } -void platformBackboneDeinit(void) +void platformBackboneSetUp(void) { #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE - sMulticastRoutingManager.Deinit(); + sMulticastRoutingManager.SetUp(); #endif +} +void platformBackboneTearDown(void) +{ +#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE + sMulticastRoutingManager.TearDown(); +#endif +} + +void platformBackboneDeinit(void) +{ gBackboneNetifIndex = 0; memset(gBackboneNetifName, 0, sizeof(gBackboneNetifName)); diff --git a/src/posix/platform/daemon.cpp b/src/posix/platform/daemon.cpp index 08f3fd089..25997768e 100644 --- a/src/posix/platform/daemon.cpp +++ b/src/posix/platform/daemon.cpp @@ -147,7 +147,7 @@ exit: } } -void Daemon::Enable(otInstance *aInstance) +void Daemon::SetUp(void) { struct sockaddr_un sockname; int ret; @@ -205,7 +205,7 @@ void Daemon::Enable(otInstance *aInstance) } otCliInit( - aInstance, + gInstance, [](void *aContext, const char *aFormat, va_list aArguments) -> int { return static_cast(aContext)->OutputFormatV(aFormat, aArguments); }, @@ -217,7 +217,7 @@ exit: return; } -void Daemon::Disable(void) +void Daemon::TearDown(void) { Mainloop::Manager::Get().Remove(*this); diff --git a/src/posix/platform/daemon.hpp b/src/posix/platform/daemon.hpp index 3b1a372b1..213ddf213 100644 --- a/src/posix/platform/daemon.hpp +++ b/src/posix/platform/daemon.hpp @@ -41,8 +41,8 @@ class Daemon : public Mainloop::Source, private NonCopyable public: static Daemon &Get(void); - void Enable(otInstance *aInstance); - void Disable(void); + void SetUp(void); + void TearDown(void); void Update(otSysMainloopContext &aContext) override; void Process(const otSysMainloopContext &aContext) override; diff --git a/src/posix/platform/include/openthread/openthread-system.h b/src/posix/platform/include/openthread/openthread-system.h index 739e6659e..1170bda44 100644 --- a/src/posix/platform/include/openthread/openthread-system.h +++ b/src/posix/platform/include/openthread/openthread-system.h @@ -81,7 +81,8 @@ typedef struct otPlatformConfig } otPlatformConfig; /** - * This function performs all platform-specific initialization of OpenThread's drivers. + * This function performs all platform-specific initialization of OpenThread's drivers and initializes the OpenThread + * instance. * * @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function * when initialization of OpenThread's drivers is most appropriate. @@ -94,7 +95,8 @@ typedef struct otPlatformConfig otInstance *otSysInit(otPlatformConfig *aPlatformConfig); /** - * This function performs all platform-specific deinitialization for OpenThread's drivers. + * This function finalizes the OpenThread instance and performs all platform-specific deinitialization for OpenThread's + * drivers. * * @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function * when deinitialization of OpenThread's drivers is most appropriate. diff --git a/src/posix/platform/infra_if.cpp b/src/posix/platform/infra_if.cpp index a537c274a..7da987a2d 100644 --- a/src/posix/platform/infra_if.cpp +++ b/src/posix/platform/infra_if.cpp @@ -267,7 +267,7 @@ bool InfraNetif::IsRunning(void) const return (ifReq.ifr_flags & IFF_RUNNING); } -void InfraNetif::Init(otInstance *aInstance, const char *aIfName) +void InfraNetif::Init(const char *aIfName) { ssize_t rval; uint32_t ifIndex = 0; @@ -296,11 +296,27 @@ void InfraNetif::Init(otInstance *aInstance, const char *aIfName) mNetLinkSocket = CreateNetLinkSocket(); - SuccessOrDie(otBorderRoutingInit(aInstance, ifIndex, platformInfraIfIsRunning())); - SuccessOrDie(otBorderRoutingSetEnabled(aInstance, /* aEnabled */ true)); +exit: + return; +} - mInstance = aInstance; +void InfraNetif::SetUp(void) +{ + OT_ASSERT(gInstance != nullptr); + VerifyOrExit(mInfraIfIndex != 0); + + SuccessOrDie(otBorderRoutingInit(gInstance, mInfraIfIndex, platformInfraIfIsRunning())); + SuccessOrDie(otBorderRoutingSetEnabled(gInstance, /* aEnabled */ true)); Mainloop::Manager::Get().Add(*this); +exit: + return; +} + +void InfraNetif::TearDown(void) +{ + VerifyOrExit(mInfraIfIndex != 0); + + Mainloop::Manager::Get().Remove(*this); exit: return; @@ -308,8 +324,6 @@ exit: void InfraNetif::Deinit(void) { - Mainloop::Manager::Get().Remove(*this); - if (mInfraIfIcmp6Socket != -1) { close(mInfraIfIcmp6Socket); @@ -369,7 +383,7 @@ void InfraNetif::ReceiveNetLinkMessage(void) case RTM_DELADDR: case RTM_NEWLINK: case RTM_DELLINK: - SuccessOrDie(otPlatInfraIfStateChanged(mInstance, mInfraIfIndex, platformInfraIfIsRunning())); + SuccessOrDie(otPlatInfraIfStateChanged(gInstance, mInfraIfIndex, platformInfraIfIsRunning())); break; case NLMSG_ERROR: { @@ -449,7 +463,7 @@ void InfraNetif::ReceiveIcmp6Message(void) // the hoplimit must be 255 and the source address must be a link-local address. VerifyOrExit(hopLimit == 255 && IN6_IS_ADDR_LINKLOCAL(&srcAddr.sin6_addr), error = OT_ERROR_DROP); - otPlatInfraIfRecvIcmp6Nd(mInstance, ifIndex, reinterpret_cast(&srcAddr.sin6_addr), buffer, + otPlatInfraIfRecvIcmp6Nd(gInstance, ifIndex, reinterpret_cast(&srcAddr.sin6_addr), buffer, bufferLength); exit: diff --git a/src/posix/platform/infra_if.hpp b/src/posix/platform/infra_if.hpp index 6cd2eda53..c44b43038 100644 --- a/src/posix/platform/infra_if.hpp +++ b/src/posix/platform/infra_if.hpp @@ -69,15 +69,34 @@ public: /** * This method initializes the infrastructure network interface. * - * @param[in] aInstance A pointer to an OpenThread instance. + * @note This method is called before OpenThread instance is created. + * * @param[in] aIfName A pointer to infrastructure network interface name. * */ - void Init(otInstance *aInstance, const char *aIfName); + void Init(const char *aIfName); + + /** + * This method sets up the infrastructure network interface. + * + * @note This method is called after OpenThread instance is created. + * + */ + void SetUp(void); + + /** + * This method tears down the infrastructure network interface. + * + * @note This method is called before OpenThread instance is destructed. + * + */ + void TearDown(void); /** * This method deinitializes the infrastructure network interface. * + * @note This method is called after OpenThread instance is destructed. + * */ void Deinit(void); @@ -117,11 +136,10 @@ public: static InfraNetif &Get(void); private: - otInstance *mInstance; - char mInfraIfName[IFNAMSIZ]; - uint32_t mInfraIfIndex = 0; - int mInfraIfIcmp6Socket = -1; - int mNetLinkSocket = -1; + char mInfraIfName[IFNAMSIZ]; + uint32_t mInfraIfIndex = 0; + int mInfraIfIcmp6Socket = -1; + int mNetLinkSocket = -1; void ReceiveNetLinkMessage(void); void ReceiveIcmp6Message(void); diff --git a/src/posix/platform/multicast_routing.cpp b/src/posix/platform/multicast_routing.cpp index f83dfa74d..a5ef307c7 100644 --- a/src/posix/platform/multicast_routing.cpp +++ b/src/posix/platform/multicast_routing.cpp @@ -46,24 +46,27 @@ #include +#include "core/common/debug.hpp" #include "core/common/logging.hpp" namespace ot { namespace Posix { -void MulticastRoutingManager::Init(otInstance *aInstance) +void MulticastRoutingManager::SetUp(void) { - mInstance = aInstance; + OT_ASSERT(gInstance != nullptr); - otBackboneRouterSetMulticastListenerCallback(aInstance, + otBackboneRouterSetMulticastListenerCallback(gInstance, &MulticastRoutingManager::HandleBackboneMulticastListenerEvent, this); Mainloop::Manager::Get().Add(*this); } -void MulticastRoutingManager::Deinit(void) +void MulticastRoutingManager::TearDown(void) { + OT_ASSERT(gInstance != nullptr); + + otBackboneRouterSetMulticastListenerCallback(gInstance, nullptr, nullptr); Mainloop::Manager::Get().Remove(*this); - mInstance = nullptr; } void MulticastRoutingManager::HandleBackboneMulticastListenerEvent(void * aContext, @@ -136,7 +139,7 @@ bool MulticastRoutingManager::HasMulticastListener(const Ip6::Address &aAddress) otBackboneRouterMulticastListenerIterator iter = OT_BACKBONE_ROUTER_MULTICAST_LISTENER_ITERATOR_INIT; otBackboneRouterMulticastListenerInfo listenerInfo; - while (otBackboneRouterMulticastListenerGetNext(mInstance, &iter, &listenerInfo) == OT_ERROR_NONE) + while (otBackboneRouterMulticastListenerGetNext(gInstance, &iter, &listenerInfo) == OT_ERROR_NONE) { VerifyOrExit(static_cast(listenerInfo.mAddress) != aAddress, found = true); } diff --git a/src/posix/platform/multicast_routing.hpp b/src/posix/platform/multicast_routing.hpp index a419d2643..ec48d4c2b 100644 --- a/src/posix/platform/multicast_routing.hpp +++ b/src/posix/platform/multicast_routing.hpp @@ -58,8 +58,8 @@ public: { } - void Init(otInstance *aInstance); - void Deinit(void); + void SetUp(void); + void TearDown(void); void Update(otSysMainloopContext &aContext) override; void Process(const otSysMainloopContext &aContext) override; void HandleStateChange(otInstance *aInstance, otChangedFlags aFlags); @@ -134,7 +134,6 @@ private: MulticastForwardingCache mMulticastForwardingCacheTable[kMulitcastForwardingCacheTableSize]; uint64_t mLastExpireTime; int mMulticastRouterSock; - otInstance * mInstance; }; } // namespace Posix diff --git a/src/posix/platform/netif.cpp b/src/posix/platform/netif.cpp index fa0f2f2b0..9d886d7d6 100644 --- a/src/posix/platform/netif.cpp +++ b/src/posix/platform/netif.cpp @@ -145,9 +145,9 @@ extern int #include #include "common/code_utils.hpp" +#include "common/debug.hpp" #include "common/logging.hpp" #include "net/ip6_address.hpp" -#include "posix/platform/udp.hpp" unsigned int gNetifIndex = 0; char gNetifName[IFNAMSIZ]; @@ -228,10 +228,9 @@ static otIp6Prefix sAddedExternalRoutes[kMaxExternalRoutesNum]; static otError destroyTunnel(void); #endif -static otInstance *sInstance = nullptr; -static int sTunFd = -1; ///< Used to exchange IPv6 packets. -static int sIpFd = -1; ///< Used to manage IPv6 stack on Thread interface. -static int sNetlinkFd = -1; ///< Used to receive netlink events. +static int sTunFd = -1; ///< Used to exchange IPv6 packets. +static int sIpFd = -1; ///< Used to manage IPv6 stack on Thread interface. +static int sNetlinkFd = -1; ///< Used to receive netlink events. #if OPENTHREAD_POSIX_USE_MLD_MONITOR static int sMLDMonitorFd = -1; ///< Used to receive MLD events. #endif @@ -392,7 +391,7 @@ static void UpdateUnicast(otInstance *aInstance, const otIp6AddressInfo &aAddres { OT_UNUSED_VARIABLE(aInstance); - assert(sInstance == aInstance); + assert(gInstance == aInstance); assert(sIpFd >= 0); #if defined(__linux__) @@ -442,7 +441,7 @@ static void UpdateMulticast(otInstance *aInstance, const otIp6Address &aAddress, otError error = OT_ERROR_NONE; int err; - assert(sInstance == aInstance); + assert(gInstance == aInstance); VerifyOrExit(sIpFd >= 0); memcpy(&mreq.ipv6mr_multiaddr, &aAddress, sizeof(mreq.ipv6mr_multiaddr)); @@ -487,7 +486,7 @@ static void UpdateLink(otInstance *aInstance) bool ifState = false; bool otState = false; - assert(sInstance == aInstance); + assert(gInstance == aInstance); VerifyOrExit(sIpFd >= 0); memset(&ifr, 0, sizeof(ifr)); @@ -763,7 +762,7 @@ static void processReceive(otMessage *aMessage, void *aContext) offset += 4; #endif - assert(sInstance == aContext); + assert(gInstance == aContext); assert(length <= kMaxIp6Size); VerifyOrExit(sTunFd > 0); @@ -802,7 +801,7 @@ static void processTransmit(otInstance *aInstance) otError error = OT_ERROR_NONE; size_t offset = 0; - assert(sInstance == aInstance); + assert(gInstance == aInstance); rval = read(sTunFd, packet, sizeof(packet)); VerifyOrExit(rval > 0, error = OT_ERROR_FAILED); @@ -1335,41 +1334,6 @@ exit: return; } -void platformNetifDeinit(void) -{ - if (sTunFd != -1) - { - close(sTunFd); - sTunFd = -1; - -#if defined(__NetBSD__) || defined(__FreeBSD__) - destroyTunnel(); -#endif - } - - if (sIpFd != -1) - { - close(sIpFd); - sIpFd = -1; - } - - if (sNetlinkFd != -1) - { - close(sNetlinkFd); - sNetlinkFd = -1; - } - -#if OPENTHREAD_POSIX_USE_MLD_MONITOR - if (sMLDMonitorFd != -1) - { - close(sMLDMonitorFd); - sMLDMonitorFd = -1; - } -#endif - - gNetifIndex = 0; -} - #if OPENTHREAD_POSIX_USE_MLD_MONITOR static void mldListenerInit(void) { @@ -1491,15 +1455,10 @@ exit: #if defined(__linux__) // set up the tun device -static void platformConfigureTunDevice(otInstance *aInstance, - const char *aInterfaceName, - char * deviceName, - size_t deviceNameLen) +static void platformConfigureTunDevice(const char *aInterfaceName, char *deviceName, size_t deviceNameLen) { struct ifreq ifr; - (void)aInstance; - sTunFd = open(OPENTHREAD_POSIX_TUN_DEVICE, O_RDWR | O_CLOEXEC | O_NONBLOCK); VerifyOrDie(sTunFd >= 0, OT_EXIT_ERROR_ERRNO); @@ -1528,18 +1487,13 @@ static void platformConfigureTunDevice(otInstance *aInstance, #endif #if defined(__APPLE__) && (OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION == OT_POSIX_CONFIG_MACOS_UTUN) -static void platformConfigureTunDevice(otInstance *aInstance, - const char *aInterfaceName, - char * deviceName, - size_t deviceNameLen) +static void platformConfigureTunDevice(const char *aInterfaceName, char *deviceName, size_t deviceNameLen) { (void)aInterfaceName; int err = 0; struct sockaddr_ctl addr; struct ctl_info info; - (void)aInstance; - sTunFd = SocketWithCloseExec(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL, kSocketNonBlock); VerifyOrDie(sTunFd >= 0, OT_EXIT_ERROR_ERRNO); @@ -1585,10 +1539,7 @@ exit: #if defined(__NetBSD__) || \ (defined(__APPLE__) && (OPENTHREAD_POSIX_CONFIG_MACOS_TUN_OPTION == OT_POSIX_CONFIG_MACOS_TUN)) || \ defined(__FreeBSD__) -static void platformConfigureTunDevice(otInstance *aInstance, - const char *aInterfaceName, - char * deviceName, - size_t deviceNameLen) +static void platformConfigureTunDevice(const char *aInterfaceName, char *deviceName, size_t deviceNameLen) { int flags = IFF_BROADCAST | IFF_MULTICAST; int err; @@ -1596,7 +1547,6 @@ static void platformConfigureTunDevice(otInstance *aInstance, const char *path; (void)aInterfaceName; - (void)aInstance; path = OPENTHREAD_POSIX_TUN_DEVICE; @@ -1668,33 +1618,72 @@ static void platformConfigureNetLink(void) #endif // defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__) } -void platformNetifInit(otInstance *aInstance, const char *aInterfaceName) +void platformNetifInit(const char *aInterfaceName) { sIpFd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_IP, kSocketNonBlock); VerifyOrDie(sIpFd >= 0, OT_EXIT_ERROR_ERRNO); platformConfigureNetLink(); - platformConfigureTunDevice(aInstance, aInterfaceName, gNetifName, sizeof(gNetifName)); + platformConfigureTunDevice(aInterfaceName, gNetifName, sizeof(gNetifName)); gNetifIndex = if_nametoindex(gNetifName); VerifyOrDie(gNetifIndex > 0, OT_EXIT_FAILURE); -#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE - ot::Posix::Udp::Get().Init(aInstance, gNetifName); -#endif #if OPENTHREAD_POSIX_USE_MLD_MONITOR mldListenerInit(); #endif +} - otIp6SetReceiveFilterEnabled(aInstance, true); - otIcmp6SetEchoMode(aInstance, OT_ICMP6_ECHO_HANDLER_DISABLED); - otIp6SetReceiveCallback(aInstance, processReceive, aInstance); - otIp6SetAddressCallback(aInstance, processAddressChange, aInstance); +void platformNetifSetUp(void) +{ + OT_ASSERT(gInstance != nullptr); + + otIp6SetReceiveFilterEnabled(gInstance, true); + otIcmp6SetEchoMode(gInstance, OT_ICMP6_ECHO_HANDLER_DISABLED); + otIp6SetReceiveCallback(gInstance, processReceive, gInstance); + otIp6SetAddressCallback(gInstance, processAddressChange, gInstance); #if OPENTHREAD_POSIX_MULTICAST_PROMISCUOUS_REQUIRED otIp6SetMulticastPromiscuousEnabled(aInstance, true); #endif +} - sInstance = aInstance; +void platformNetifTearDown(void) +{ +} + +void platformNetifDeinit(void) +{ + if (sTunFd != -1) + { + close(sTunFd); + sTunFd = -1; + +#if defined(__NetBSD__) || defined(__FreeBSD__) + destroyTunnel(); +#endif + } + + if (sIpFd != -1) + { + close(sIpFd); + sIpFd = -1; + } + + if (sNetlinkFd != -1) + { + close(sNetlinkFd); + sNetlinkFd = -1; + } + +#if OPENTHREAD_POSIX_USE_MLD_MONITOR + if (sMLDMonitorFd != -1) + { + close(sMLDMonitorFd); + sMLDMonitorFd = -1; + } +#endif + + gNetifIndex = 0; } void platformNetifUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd) @@ -1763,18 +1752,18 @@ void platformNetifProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, c if (FD_ISSET(sTunFd, aReadFdSet)) { - processTransmit(sInstance); + processTransmit(gInstance); } if (FD_ISSET(sNetlinkFd, aReadFdSet)) { - processNetlinkEvent(sInstance); + processNetlinkEvent(gInstance); } #if OPENTHREAD_POSIX_USE_MLD_MONITOR if (FD_ISSET(sMLDMonitorFd, aReadFdSet)) { - processMLDEvent(sInstance); + processMLDEvent(gInstance); } #endif diff --git a/src/posix/platform/platform-posix.h b/src/posix/platform/platform-posix.h index 022790ae2..9eadc6871 100644 --- a/src/posix/platform/platform-posix.h +++ b/src/posix/platform/platform-posix.h @@ -171,12 +171,6 @@ void platformRadioInit(const char *aUrl); */ void platformRadioDeinit(void); -/** - * This function shuts down platform network interface. - * - */ -void platformNetifDeinit(void); - /** * This function inputs a received radio frame. * @@ -245,11 +239,38 @@ void platformUartProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, co /** * This function initializes platform netif. * - * @param[in] aInstance A pointer to the OpenThread instance. + * @note This function is called before OpenThread instance is created. + * * @param[in] aInterfaceName A pointer to Thread network interface name. * */ -void platformNetifInit(otInstance *aInstance, const char *aInterfaceName); +void platformNetifInit(const char *aInterfaceName); + +/** + * This function sets up platform netif. + * + * @note This function is called after OpenThread instance is created. + * + * @param[in] aInstance A pointer to the OpenThread instance. + * + */ +void platformNetifSetUp(void); + +/** + * This function tears down platform netif. + * + * @note This function is called before OpenThread instance is destructed. + * + */ +void platformNetifTearDown(void); + +/** + * This function deinitializes platform netif. + * + * @note This function is called after OpenThread instance is destructed. + * + */ +void platformNetifDeinit(void); /** * This function updates the file descriptor sets with file descriptors used by platform netif module. @@ -430,15 +451,36 @@ extern unsigned int gNetifIndex; /** * This function initializes platform Backbone network. * - * @param[in] aInstance A pointer to the OpenThread instance. + * @note This function is called before OpenThread instance is created. + * * @param[in] aInterfaceName A pointer to Thread network interface name. * */ -void platformBackboneInit(otInstance *aInstance, const char *aInterfaceName); +void platformBackboneInit(const char *aInterfaceName); + +/** + * This function sets up platform Backbone network. + * + * @note This function is called after OpenThread instance is created. + * + * @param[in] aInstance A pointer to the OpenThread instance. + * + */ +void platformBackboneSetUp(void); + +/** + * This function tears down platform Backbone network. + * + * @note This function is called before OpenThread instance is destructed. + * + */ +void platformBackboneTearDown(void); /** * This function shuts down the platform Backbone network. * + * @note This function is called after OpenThread instance is destructed. + * */ void platformBackboneDeinit(void); @@ -451,6 +493,12 @@ void platformBackboneDeinit(void); */ void platformBackboneStateChange(otInstance *aInstance, otChangedFlags aFlags); +/** + * A pointer to the OpenThread instance. + * + */ +extern otInstance *gInstance; + /** * The name of Backbone network interface. * diff --git a/src/posix/platform/system.cpp b/src/posix/platform/system.cpp index cd5a8897d..26b340166 100644 --- a/src/posix/platform/system.cpp +++ b/src/posix/platform/system.cpp @@ -47,12 +47,15 @@ #include #include "common/code_utils.hpp" +#include "common/debug.hpp" #include "posix/platform/daemon.hpp" #include "posix/platform/infra_if.hpp" #include "posix/platform/mainloop.hpp" #include "posix/platform/radio_url.hpp" #include "posix/platform/udp.hpp" +otInstance *gInstance = nullptr; + #if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE || OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE static void processStateChange(otChangedFlags aFlags, void *aContext) { @@ -115,10 +118,8 @@ static const char *getTrelRadioUrl(otPlatformConfig *aPlatformConfig) } #endif -otInstance *otSysInit(otPlatformConfig *aPlatformConfig) +void platformInit(otPlatformConfig *aPlatformConfig) { - otInstance *instance = nullptr; - platformAlarmInit(aPlatformConfig->mSpeedUpFactor, aPlatformConfig->mRealTimeSignal); platformRadioInit(get802154RadioUrl(aPlatformConfig)); #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE @@ -126,40 +127,95 @@ otInstance *otSysInit(otPlatformConfig *aPlatformConfig) #endif platformRandomInit(); - instance = otInstanceInitSingle(); - assert(instance != nullptr); - #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE - platformBackboneInit(instance, aPlatformConfig->mBackboneInterfaceName); + platformBackboneInit(aPlatformConfig->mBackboneInterfaceName); #endif #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE - ot::Posix::InfraNetif::Get().Init(instance, aPlatformConfig->mBackboneInterfaceName); + ot::Posix::InfraNetif::Get().Init(aPlatformConfig->mBackboneInterfaceName); +#endif + + gNetifName[0] = '\0'; + +#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE + platformNetifInit(aPlatformConfig->mInterfaceName); +#endif + +#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE +#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE + ot::Posix::Udp::Get().Init(otSysGetThreadNetifName()); +#else + ot::Posix::Udp::Get().Init(aPlatformConfig->mInterfaceName); +#endif +#endif +} + +void platformSetUp(void) +{ +#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE + platformBackboneSetUp(); +#endif + +#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + ot::Posix::InfraNetif::Get().SetUp(); #endif #if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE - platformNetifInit(instance, aPlatformConfig->mInterfaceName); -#elif OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE - ot::Posix::Udp::Get().Init(instance, aPlatformConfig->mInterfaceName); -#else - gNetifName[0] = '\0'; + platformNetifSetUp(); +#endif + +#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE + ot::Posix::Udp::Get().SetUp(); +#endif + +#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE + ot::Posix::Daemon::Get().SetUp(); #endif #if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE || OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE - SuccessOrDie(otSetStateChangedCallback(instance, processStateChange, instance)); + SuccessOrDie(otSetStateChangedCallback(gInstance, processStateChange, gInstance)); #endif - -#if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - ot::Posix::Daemon::Get().Enable(instance); -#endif - return instance; } -void otSysDeinit(void) +otInstance *otSysInit(otPlatformConfig *aPlatformConfig) +{ + OT_ASSERT(gInstance == nullptr); + + platformInit(aPlatformConfig); + + gInstance = otInstanceInitSingle(); + OT_ASSERT(gInstance != nullptr); + + platformSetUp(); + + return gInstance; +} + +void platformTearDown(void) { #if OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE - ot::Posix::Daemon::Get().Disable(); + ot::Posix::Daemon::Get().TearDown(); #endif + +#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE + ot::Posix::Udp::Get().TearDown(); +#endif + +#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE + platformNetifTearDown(); +#endif + +#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + ot::Posix::InfraNetif::Get().TearDown(); +#endif + +#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE + platformBackboneTearDown(); +#endif +} + +void platformDeinit(void) +{ #if OPENTHREAD_POSIX_VIRTUAL_TIME virtualTimeDeinit(); #endif @@ -183,6 +239,16 @@ void otSysDeinit(void) #endif } +void otSysDeinit(void) +{ + OT_ASSERT(gInstance != nullptr); + + platformTearDown(); + otInstanceFinalize(gInstance); + gInstance = nullptr; + platformDeinit(); +} + #if OPENTHREAD_POSIX_VIRTUAL_TIME /** * This function try selecting the given file descriptors in nonblocking mode. diff --git a/src/posix/platform/udp.cpp b/src/posix/platform/udp.cpp index 1ff976b86..b7aacc5fa 100644 --- a/src/posix/platform/udp.cpp +++ b/src/posix/platform/udp.cpp @@ -550,7 +550,7 @@ void Udp::Update(otSysMainloopContext &aContext) { VerifyOrExit(gNetifIndex != 0); - for (otUdpSocket *socket = otUdpGetSockets(mInstance); socket != nullptr; socket = socket->mNext) + for (otUdpSocket *socket = otUdpGetSockets(gInstance); socket != nullptr; socket = socket->mNext) { int fd; @@ -572,7 +572,7 @@ exit: return; } -void Udp::Init(otInstance *aInstance, const char *aIfName) +void Udp::Init(const char *aIfName) { if (aIfName == nullptr) { @@ -589,17 +589,21 @@ void Udp::Init(otInstance *aInstance, const char *aIfName) } assert(gNetifIndex != 0); +} - mInstance = aInstance; +void Udp::SetUp(void) +{ Mainloop::Manager::Get().Add(*this); } +void Udp::TearDown(void) +{ + Mainloop::Manager::Get().Remove(*this); +} + void Udp::Deinit(void) { // TODO All platform sockets should be closed - - mInstance = nullptr; - Mainloop::Manager::Get().Remove(*this); } Udp &Udp::Get(void) @@ -613,7 +617,7 @@ void Udp::Process(const otSysMainloopContext &aContext) { otMessageSettings msgSettings = {false, OT_MESSAGE_PRIORITY_NORMAL}; - for (otUdpSocket *socket = otUdpGetSockets(mInstance); socket != nullptr; socket = socket->mNext) + for (otUdpSocket *socket = otUdpGetSockets(gInstance); socket != nullptr; socket = socket->mNext) { int fd = FdFromHandle(socket->mHandle); @@ -632,7 +636,7 @@ void Udp::Process(const otSysMainloopContext &aContext) continue; } - message = otUdpNewMessage(mInstance, &msgSettings); + message = otUdpNewMessage(gInstance, &msgSettings); if (message == nullptr) { diff --git a/src/posix/platform/udp.hpp b/src/posix/platform/udp.hpp index 208488b46..adc252ac4 100644 --- a/src/posix/platform/udp.hpp +++ b/src/posix/platform/udp.hpp @@ -39,13 +39,12 @@ class Udp : public Mainloop::Source, private NonCopyable public: static Udp &Get(void); - void Init(otInstance *aInstance, const char *aIfName); + void Init(const char *aIfName); + void SetUp(void); + void TearDown(void); void Deinit(void); void Update(otSysMainloopContext &aContext) override; void Process(const otSysMainloopContext &aContext) override; - -private: - otInstance *mInstance = nullptr; }; } // namespace Posix