From c3b73283ef2e47f23ebbf92c2a86926c0756feb7 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Wed, 21 Dec 2022 20:51:39 -0800 Subject: [PATCH] [common] add `Callback` class (#8560) This commit adds a new class `Callback` which represents a callback as a function pointer handler and a `void *` context pair. The context is passed as one of the arguments to the function pointer handler when the callback is invoked. The `Callback` provides two specializations based on the position of the context argument in the function pointer, i.e., whether it is passed as the first argument or as the last argument. The `Callback` class automatically determines this at compile-time based on the given `HandlerType` and passes the context properly from `Invoke()` method. The `Callback` class is used by OT core modules to simplify how callbacks are defined and used. --- src/core/BUILD.gn | 1 + src/core/Makefile.am | 1 + src/core/backbone_router/bbr_local.cpp | 19 +- src/core/backbone_router/bbr_local.hpp | 15 +- .../multicast_listeners_table.cpp | 26 +- .../multicast_listeners_table.hpp | 6 +- src/core/backbone_router/ndproxy_table.cpp | 15 +- src/core/backbone_router/ndproxy_table.hpp | 12 +- src/core/coap/coap.cpp | 24 +- src/core/coap/coap.hpp | 13 +- src/core/coap/coap_secure.cpp | 19 +- src/core/coap/coap_secure.hpp | 16 +- src/core/common/callback.hpp | 228 ++++++++++++++++++ src/core/common/type_traits.hpp | 35 +++ src/core/mac/sub_mac.cpp | 16 +- src/core/mac/sub_mac.hpp | 27 ++- src/core/meshcop/commissioner.cpp | 17 +- src/core/meshcop/commissioner.hpp | 6 +- src/core/meshcop/dataset_manager.cpp | 18 +- src/core/meshcop/dataset_manager.hpp | 4 +- src/core/meshcop/dataset_updater.cpp | 14 +- src/core/meshcop/dataset_updater.hpp | 14 +- src/core/meshcop/dtls.cpp | 47 ++-- src/core/meshcop/dtls.hpp | 9 +- src/core/meshcop/energy_scan_client.cpp | 10 +- src/core/meshcop/energy_scan_client.hpp | 4 +- src/core/meshcop/joiner.cpp | 12 +- src/core/meshcop/joiner.hpp | 4 +- src/core/meshcop/panid_query_client.cpp | 10 +- src/core/meshcop/panid_query_client.hpp | 4 +- src/core/net/ip6.cpp | 28 +-- src/core/net/ip6.hpp | 22 +- src/core/net/netif.cpp | 30 +-- src/core/net/netif.hpp | 9 +- src/core/net/srp_client.cpp | 25 +- src/core/net/srp_client.hpp | 25 +- src/core/net/srp_server.cpp | 20 +- src/core/net/srp_server.hpp | 12 +- src/core/net/udp6.cpp | 9 +- src/core/net/udp6.hpp | 10 +- src/core/thread/anycast_locator.cpp | 17 +- src/core/thread/anycast_locator.hpp | 10 +- src/core/thread/discover_scanner.cpp | 16 +- src/core/thread/discover_scanner.hpp | 26 +- src/core/thread/link_metrics.cpp | 39 +-- src/core/thread/link_metrics.hpp | 22 +- src/core/thread/mle.cpp | 30 +-- src/core/thread/mle.hpp | 14 +- src/core/thread/mle_router.cpp | 6 +- src/core/thread/mle_router.hpp | 7 +- src/core/thread/mlr_manager.cpp | 30 +-- src/core/thread/mlr_manager.hpp | 4 +- src/core/thread/network_data_publisher.cpp | 33 +-- src/core/thread/network_data_publisher.hpp | 15 +- src/core/thread/network_diagnostic.cpp | 14 +- src/core/thread/network_diagnostic.hpp | 4 +- src/core/thread/time_sync_service.cpp | 10 +- src/core/thread/time_sync_service.hpp | 13 +- src/core/utils/jam_detector.cpp | 7 +- src/core/utils/jam_detector.hpp | 24 +- 60 files changed, 580 insertions(+), 597 deletions(-) create mode 100644 src/core/common/callback.hpp diff --git a/src/core/BUILD.gn b/src/core/BUILD.gn index c8ecbc71a..2d2a9cc39 100644 --- a/src/core/BUILD.gn +++ b/src/core/BUILD.gn @@ -386,6 +386,7 @@ openthread_core_files = [ "common/binary_search.cpp", "common/binary_search.hpp", "common/bit_vector.hpp", + "common/callback.hpp", "common/clearable.hpp", "common/code_utils.hpp", "common/const_cast.hpp", diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 77f06e893..c02878c12 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -434,6 +434,7 @@ HEADERS_COMMON = \ common/as_core_type.hpp \ common/binary_search.hpp \ common/bit_vector.hpp \ + common/callback.hpp \ common/clearable.hpp \ common/code_utils.hpp \ common/const_cast.hpp \ diff --git a/src/core/backbone_router/bbr_local.cpp b/src/core/backbone_router/bbr_local.cpp index 421500167..795c8cabe 100644 --- a/src/core/backbone_router/bbr_local.cpp +++ b/src/core/backbone_router/bbr_local.cpp @@ -57,8 +57,6 @@ Local::Local(Instance &aInstance) , mSequenceNumber(Random::NonCrypto::GetUint8() % 127) , mRegistrationJitter(Mle::kBackboneRouterRegistrationJitter) , mIsServiceAdded(false) - , mDomainPrefixCallback(nullptr) - , mDomainPrefixCallbackContext(nullptr) { mDomainPrefixConfig.GetPrefix().SetLength(0); @@ -378,21 +376,18 @@ void Local::HandleDomainPrefixUpdate(Leader::DomainPrefixState aState) Get().SubscribeMulticast(mAllDomainBackboneRouters); } - if (mDomainPrefixCallback != nullptr) + if (mDomainPrefixCallback.IsSet()) { switch (aState) { case Leader::kDomainPrefixAdded: - mDomainPrefixCallback(mDomainPrefixCallbackContext, OT_BACKBONE_ROUTER_DOMAIN_PREFIX_ADDED, - Get().GetDomainPrefix()); + mDomainPrefixCallback.Invoke(OT_BACKBONE_ROUTER_DOMAIN_PREFIX_ADDED, Get().GetDomainPrefix()); break; case Leader::kDomainPrefixRemoved: - mDomainPrefixCallback(mDomainPrefixCallbackContext, OT_BACKBONE_ROUTER_DOMAIN_PREFIX_REMOVED, - Get().GetDomainPrefix()); + mDomainPrefixCallback.Invoke(OT_BACKBONE_ROUTER_DOMAIN_PREFIX_REMOVED, Get().GetDomainPrefix()); break; case Leader::kDomainPrefixRefreshed: - mDomainPrefixCallback(mDomainPrefixCallbackContext, OT_BACKBONE_ROUTER_DOMAIN_PREFIX_CHANGED, - Get().GetDomainPrefix()); + mDomainPrefixCallback.Invoke(OT_BACKBONE_ROUTER_DOMAIN_PREFIX_CHANGED, Get().GetDomainPrefix()); break; default: break; @@ -459,12 +454,6 @@ void Local::LogBackboneRouterService(const char *aAction, Error aError) } #endif -void Local::SetDomainPrefixCallback(otBackboneRouterDomainPrefixCallback aCallback, void *aContext) -{ - mDomainPrefixCallback = aCallback; - mDomainPrefixCallbackContext = aContext; -} - } // namespace BackboneRouter } // namespace ot diff --git a/src/core/backbone_router/bbr_local.hpp b/src/core/backbone_router/bbr_local.hpp index eb132b520..08f0bfb43 100644 --- a/src/core/backbone_router/bbr_local.hpp +++ b/src/core/backbone_router/bbr_local.hpp @@ -54,6 +54,7 @@ #include #include "backbone_router/bbr_leader.hpp" +#include "common/callback.hpp" #include "common/locator.hpp" #include "common/log.hpp" #include "common/non_copyable.hpp" @@ -253,7 +254,10 @@ public: * @param[in] aContext A user context pointer. * */ - void SetDomainPrefixCallback(otBackboneRouterDomainPrefixCallback aCallback, void *aContext); + void SetDomainPrefixCallback(otBackboneRouterDomainPrefixCallback aCallback, void *aContext) + { + mDomainPrefixCallback.Set(aCallback, aContext); + } private: void SetState(BackboneRouterState aState); @@ -282,11 +286,10 @@ private: NetworkData::OnMeshPrefixConfig mDomainPrefixConfig; - Ip6::Netif::UnicastAddress mBackboneRouterPrimaryAloc; - Ip6::Address mAllNetworkBackboneRouters; - Ip6::Address mAllDomainBackboneRouters; - otBackboneRouterDomainPrefixCallback mDomainPrefixCallback; - void *mDomainPrefixCallbackContext; + Ip6::Netif::UnicastAddress mBackboneRouterPrimaryAloc; + Ip6::Address mAllNetworkBackboneRouters; + Ip6::Address mAllDomainBackboneRouters; + Callback mDomainPrefixCallback; }; } // namespace BackboneRouter diff --git a/src/core/backbone_router/multicast_listeners_table.cpp b/src/core/backbone_router/multicast_listeners_table.cpp index fef7485d6..48376e830 100644 --- a/src/core/backbone_router/multicast_listeners_table.cpp +++ b/src/core/backbone_router/multicast_listeners_table.cpp @@ -77,10 +77,7 @@ Error MulticastListenersTable::Add(const Ip6::Address &aAddress, Time aExpireTim FixHeap(mNumValidListeners - 1); - if (mCallback != nullptr) - { - mCallback(mCallbackContext, OT_BACKBONE_ROUTER_MULTICAST_LISTENER_ADDED, &aAddress); - } + mCallback.InvokeIfSet(OT_BACKBONE_ROUTER_MULTICAST_LISTENER_ADDED, &aAddress); exit: LogMulticastListenersTable("Add", aAddress, aExpireTime, error); @@ -106,10 +103,7 @@ void MulticastListenersTable::Remove(const Ip6::Address &aAddress) FixHeap(i); } - if (mCallback != nullptr) - { - mCallback(mCallbackContext, OT_BACKBONE_ROUTER_MULTICAST_LISTENER_REMOVED, &aAddress); - } + mCallback.InvokeIfSet(OT_BACKBONE_ROUTER_MULTICAST_LISTENER_REMOVED, &aAddress); ExitNow(error = kErrorNone); } @@ -138,10 +132,7 @@ void MulticastListenersTable::Expire(void) FixHeap(0); } - if (mCallback != nullptr) - { - mCallback(mCallbackContext, OT_BACKBONE_ROUTER_MULTICAST_LISTENER_REMOVED, &address); - } + mCallback.InvokeIfSet(OT_BACKBONE_ROUTER_MULTICAST_LISTENER_REMOVED, &address); } CheckInvariants(); @@ -263,11 +254,11 @@ MulticastListenersTable::Listener *MulticastListenersTable::IteratorBuilder::end void MulticastListenersTable::Clear(void) { - if (mCallback != nullptr) + if (mCallback.IsSet()) { for (uint16_t i = 0; i < mNumValidListeners; i++) { - mCallback(mCallbackContext, OT_BACKBONE_ROUTER_MULTICAST_LISTENER_REMOVED, &mListeners[i].GetAddress()); + mCallback.Invoke(OT_BACKBONE_ROUTER_MULTICAST_LISTENER_REMOVED, &mListeners[i].GetAddress()); } } @@ -278,14 +269,13 @@ void MulticastListenersTable::Clear(void) void MulticastListenersTable::SetCallback(otBackboneRouterMulticastListenerCallback aCallback, void *aContext) { - mCallback = aCallback; - mCallbackContext = aContext; + mCallback.Set(aCallback, aContext); - if (mCallback != nullptr) + if (mCallback.IsSet()) { for (uint16_t i = 0; i < mNumValidListeners; i++) { - mCallback(mCallbackContext, OT_BACKBONE_ROUTER_MULTICAST_LISTENER_ADDED, &mListeners[i].GetAddress()); + mCallback.Invoke(OT_BACKBONE_ROUTER_MULTICAST_LISTENER_ADDED, &mListeners[i].GetAddress()); } } } diff --git a/src/core/backbone_router/multicast_listeners_table.hpp b/src/core/backbone_router/multicast_listeners_table.hpp index b6a3684f1..0738170e2 100644 --- a/src/core/backbone_router/multicast_listeners_table.hpp +++ b/src/core/backbone_router/multicast_listeners_table.hpp @@ -40,6 +40,7 @@ #include +#include "common/callback.hpp" #include "common/non_copyable.hpp" #include "common/notifier.hpp" #include "common/time.hpp" @@ -108,8 +109,6 @@ public: explicit MulticastListenersTable(Instance &aInstance) : InstanceLocator(aInstance) , mNumValidListeners(0) - , mCallback(nullptr) - , mCallbackContext(nullptr) { } @@ -220,8 +219,7 @@ private: Listener mListeners[kMulticastListenersTableSize]; uint16_t mNumValidListeners; - otBackboneRouterMulticastListenerCallback mCallback; - void *mCallbackContext; + Callback mCallback; }; } // namespace BackboneRouter diff --git a/src/core/backbone_router/ndproxy_table.cpp b/src/core/backbone_router/ndproxy_table.cpp index 8e1f77f3d..d456a3471 100644 --- a/src/core/backbone_router/ndproxy_table.cpp +++ b/src/core/backbone_router/ndproxy_table.cpp @@ -141,10 +141,7 @@ void NdProxyTable::Clear(void) proxy.Clear(); } - if (mCallback != nullptr) - { - mCallback(mCallbackContext, OT_BACKBONE_ROUTER_NDPROXY_CLEARED, nullptr); - } + mCallback.InvokeIfSet(OT_BACKBONE_ROUTER_NDPROXY_CLEARED, nullptr); LogInfo("NdProxyTable::Clear!"); } @@ -268,26 +265,20 @@ exit: return; } -void NdProxyTable::SetCallback(otBackboneRouterNdProxyCallback aCallback, void *aContext) -{ - mCallback = aCallback; - mCallbackContext = aContext; -} - void NdProxyTable::TriggerCallback(otBackboneRouterNdProxyEvent aEvent, const Ip6::InterfaceIdentifier &aAddressIid) const { Ip6::Address dua; const Ip6::Prefix *prefix = Get().GetDomainPrefix(); - VerifyOrExit(mCallback != nullptr); + VerifyOrExit(mCallback.IsSet()); OT_ASSERT(prefix != nullptr); dua.SetPrefix(*prefix); dua.SetIid(aAddressIid); - mCallback(mCallbackContext, aEvent, &dua); + mCallback.Invoke(aEvent, &dua); exit: return; diff --git a/src/core/backbone_router/ndproxy_table.hpp b/src/core/backbone_router/ndproxy_table.hpp index 05a932d2a..c470f7de3 100644 --- a/src/core/backbone_router/ndproxy_table.hpp +++ b/src/core/backbone_router/ndproxy_table.hpp @@ -40,6 +40,7 @@ #include #include "backbone_router/bbr_leader.hpp" +#include "common/callback.hpp" #include "common/iterator_utils.hpp" #include "common/locator.hpp" #include "common/non_copyable.hpp" @@ -134,8 +135,6 @@ public: */ explicit NdProxyTable(Instance &aInstance) : InstanceLocator(aInstance) - , mCallback(nullptr) - , mCallbackContext(nullptr) , mIsAnyDadInProcess(false) { } @@ -217,7 +216,7 @@ public: * @param[in] aContext A user context pointer. * */ - void SetCallback(otBackboneRouterNdProxyCallback aCallback, void *aContext); + void SetCallback(otBackboneRouterNdProxyCallback aCallback, void *aContext) { mCallback.Set(aCallback, aContext); } /** * This method retrieves the ND Proxy info of the Domain Unicast Address. @@ -292,10 +291,9 @@ private: void NotifyDuaRegistrationOnBackboneLink(NdProxy &aNdProxy, bool aIsRenew); void TriggerCallback(otBackboneRouterNdProxyEvent aEvent, const Ip6::InterfaceIdentifier &aAddressIid) const; - NdProxy mProxies[kMaxNdProxyNum]; - otBackboneRouterNdProxyCallback mCallback; - void *mCallbackContext; - bool mIsAnyDadInProcess : 1; + NdProxy mProxies[kMaxNdProxyNum]; + Callback mCallback; + bool mIsAnyDadInProcess : 1; }; } // namespace BackboneRouter diff --git a/src/core/coap/coap.cpp b/src/core/coap/coap.cpp index d02305af1..66c54e565 100644 --- a/src/core/coap/coap.cpp +++ b/src/core/coap/coap.cpp @@ -54,11 +54,7 @@ CoapBase::CoapBase(Instance &aInstance, Sender aSender) : InstanceLocator(aInstance) , mMessageId(Random::NonCrypto::GetUint16()) , mRetransmissionTimer(aInstance, Coap::HandleRetransmissionTimer, this) - , mContext(nullptr) - , mInterceptor(nullptr) , mResponsesQueue(aInstance) - , mDefaultHandler(nullptr) - , mDefaultHandlerContext(nullptr) , mResourceHandler(nullptr) , mSender(aSender) #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE @@ -108,18 +104,6 @@ void CoapBase::RemoveResource(Resource &aResource) aResource.SetNext(nullptr); } -void CoapBase::SetDefaultHandler(RequestHandler aHandler, void *aContext) -{ - mDefaultHandler = aHandler; - mDefaultHandlerContext = aContext; -} - -void CoapBase::SetInterceptor(Interceptor aInterceptor, void *aContext) -{ - mInterceptor = aInterceptor; - mContext = aContext; -} - Message *CoapBase::NewMessage(const Message::Settings &aSettings) { Message *message = nullptr; @@ -1295,9 +1279,9 @@ void CoapBase::ProcessReceivedRequest(Message &aMessage, const Ip6::MessageInfo uint32_t totalTransfereSize = 0; #endif - if (mInterceptor != nullptr) + if (mInterceptor.IsSet()) { - SuccessOrExit(error = mInterceptor(aMessage, aMessageInfo, mContext)); + SuccessOrExit(error = mInterceptor.Invoke(aMessage, aMessageInfo)); } switch (mResponsesQueue.GetMatchedResponseCopy(aMessage, aMessageInfo, &cachedResponse)) @@ -1434,9 +1418,9 @@ void CoapBase::ProcessReceivedRequest(Message &aMessage, const Ip6::MessageInfo } } - if (mDefaultHandler) + if (mDefaultHandler.IsSet()) { - mDefaultHandler(mDefaultHandlerContext, &aMessage, &aMessageInfo); + mDefaultHandler.Invoke(&aMessage, &aMessageInfo); error = kErrorNone; ExitNow(); } diff --git a/src/core/coap/coap.hpp b/src/core/coap/coap.hpp index 66a658cf2..5a35770b1 100644 --- a/src/core/coap/coap.hpp +++ b/src/core/coap/coap.hpp @@ -35,6 +35,7 @@ #include "coap/coap_message.hpp" #include "common/as_core_type.hpp" +#include "common/callback.hpp" #include "common/debug.hpp" #include "common/linked_list.hpp" #include "common/locator.hpp" @@ -438,7 +439,7 @@ public: * @param[in] aContext A pointer to arbitrary context information. May be `nullptr` if not used. * */ - void SetDefaultHandler(RequestHandler aHandler, void *aContext); + void SetDefaultHandler(RequestHandler aHandler, void *aContext) { mDefaultHandler.Set(aHandler, aContext); } /** * This method allocates a new message with a CoAP header. @@ -729,7 +730,7 @@ public: * @param[in] aContext A pointer to arbitrary context information. * */ - void SetInterceptor(Interceptor aInterceptor, void *aContext); + void SetInterceptor(Interceptor aInterceptor, void *aContext) { mInterceptor.Set(aInterceptor, aContext); } /** * This method returns a reference to the request message list. @@ -900,12 +901,10 @@ private: LinkedList mResources; - void *mContext; - Interceptor mInterceptor; - ResponsesQueue mResponsesQueue; + Callback mInterceptor; + ResponsesQueue mResponsesQueue; - RequestHandler mDefaultHandler; - void *mDefaultHandlerContext; + Callback mDefaultHandler; ResourceHandler mResourceHandler; diff --git a/src/core/coap/coap_secure.cpp b/src/core/coap/coap_secure.cpp index 7ea4d41b8..3f5730afb 100644 --- a/src/core/coap/coap_secure.cpp +++ b/src/core/coap/coap_secure.cpp @@ -50,8 +50,6 @@ RegisterLogModule("CoapSecure"); CoapSecure::CoapSecure(Instance &aInstance, bool aLayerTwoSecurity) : CoapBase(aInstance, &CoapSecure::Send) , mDtls(aInstance, aLayerTwoSecurity) - , mConnectedCallback(nullptr) - , mConnectedContext(nullptr) , mTransmitTask(aInstance, CoapSecure::HandleTransmit, this) { } @@ -60,8 +58,7 @@ Error CoapSecure::Start(uint16_t aPort) { Error error = kErrorNone; - mConnectedCallback = nullptr; - mConnectedContext = nullptr; + mConnectedCallback.Clear(); SuccessOrExit(error = mDtls.Open(&CoapSecure::HandleDtlsReceive, &CoapSecure::HandleDtlsConnected, this)); SuccessOrExit(error = mDtls.Bind(aPort)); @@ -74,8 +71,7 @@ Error CoapSecure::Start(MeshCoP::Dtls::TransportCallback aCallback, void *aConte { Error error = kErrorNone; - mConnectedCallback = nullptr; - mConnectedContext = nullptr; + mConnectedCallback.Clear(); SuccessOrExit(error = mDtls.Open(&CoapSecure::HandleDtlsReceive, &CoapSecure::HandleDtlsConnected, this)); SuccessOrExit(error = mDtls.Bind(aCallback, aContext)); @@ -94,8 +90,7 @@ void CoapSecure::Stop(void) Error CoapSecure::Connect(const Ip6::SockAddr &aSockAddr, ConnectedCallback aCallback, void *aContext) { - mConnectedCallback = aCallback; - mConnectedContext = aContext; + mConnectedCallback.Set(aCallback, aContext); return mDtls.Connect(aSockAddr); } @@ -174,13 +169,7 @@ void CoapSecure::HandleDtlsConnected(void *aContext, bool aConnected) return static_cast(aContext)->HandleDtlsConnected(aConnected); } -void CoapSecure::HandleDtlsConnected(bool aConnected) -{ - if (mConnectedCallback != nullptr) - { - mConnectedCallback(aConnected, mConnectedContext); - } -} +void CoapSecure::HandleDtlsConnected(bool aConnected) { mConnectedCallback.InvokeIfSet(aConnected); } void CoapSecure::HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength) { diff --git a/src/core/coap/coap_secure.hpp b/src/core/coap/coap_secure.hpp index 1734d759a..43b2d02ee 100644 --- a/src/core/coap/coap_secure.hpp +++ b/src/core/coap/coap_secure.hpp @@ -34,6 +34,7 @@ #if OPENTHREAD_CONFIG_DTLS_ENABLE #include "coap/coap.hpp" +#include "common/callback.hpp" #include "meshcop/dtls.hpp" #include "meshcop/meshcop.hpp" @@ -101,8 +102,7 @@ public: */ void SetConnectedCallback(ConnectedCallback aCallback, void *aContext) { - mConnectedCallback = aCallback; - mConnectedContext = aContext; + mConnectedCallback.Set(aCallback, aContext); } /** @@ -267,8 +267,7 @@ public: */ void SetClientConnectedCallback(ConnectedCallback aCallback, void *aContext) { - mConnectedCallback = aCallback; - mConnectedContext = aContext; + mConnectedCallback.Set(aCallback, aContext); } /** @@ -410,11 +409,10 @@ private: static void HandleTransmit(Tasklet &aTasklet); void HandleTransmit(void); - MeshCoP::Dtls mDtls; - ConnectedCallback mConnectedCallback; - void *mConnectedContext; - ot::MessageQueue mTransmitQueue; - TaskletContext mTransmitTask; + MeshCoP::Dtls mDtls; + Callback mConnectedCallback; + ot::MessageQueue mTransmitQueue; + TaskletContext mTransmitTask; }; } // namespace Coap diff --git a/src/core/common/callback.hpp b/src/core/common/callback.hpp new file mode 100644 index 000000000..949a190f7 --- /dev/null +++ b/src/core/common/callback.hpp @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2022, 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 defines OpenThread `Callback` class. + */ + +#ifndef CALLBACK_HPP_ +#define CALLBACK_HPP_ + +#include "openthread-core-config.h" + +#include + +#include "common/type_traits.hpp" + +namespace ot { + +/** + * This enumeration specifies the context argument position in a callback function pointer. + * + */ +enum CallbackContextPosition : uint8_t +{ + kContextAsFirstArg, ///< Context is the first argument. + kContextAsLastArg, ///< Context is the last argument. +}; + +/** + * This class is the base class for `Callback` (a function pointer handler and a `void *` context). + * + * @tparam HandlerType The handler function pointer type. + * + */ +template class CallbackBase +{ +public: + /** + * This method clears the `Callback` by setting the handler function pointer to `nullptr`. + * + */ + void Clear(void) { mHandler = nullptr; } + + /** + * This method sets the callback handler function pointer and its associated context. + * + * @param[in] aHandler The handler function pointer. + * @param[in] aContext The context associated with handler. + * + */ + void Set(HandlerType aHandler, void *aContext) + { + mHandler = aHandler; + mContext = aContext; + } + + /** + * This method indicates whether or not the callback is set (not `nullptr`). + * + * @retval TRUE The handler is set. + * @retval FALSE The handler is not set. + * + */ + bool IsSet(void) const { return (mHandler != nullptr); } + + /** + * This method returns the handler function pointer. + * + * @returns The handler function pointer. + * + */ + HandlerType GetHandler(void) const { return mHandler; } + + /** + * This method returns the context associated with callback. + * + * @returns The context. + * + */ + void *GetContext(void) const { return mContext; } + +protected: + CallbackBase(void) + : mHandler(nullptr) + , mContext(nullptr) + { + } + + HandlerType mHandler; + void *mContext; +}; + +/** + * This class represents a `Callback` (a function pointer handler and a `void *` context). + * + * The context is passed as one of the arguments to the function pointer handler when invoked. + * + * The `Callback` provides two specializations based on `CallbackContextPosition` in the function pointer, i.e., whether + * it is passed as the first argument or as the last argument. + * + * The `CallbackContextPosition` template parameter is automatically determined at compile-time based on the given + * `HandlerType`. So user can simply use `Callback`. The `Invoke()` method will properly pass the context + * to the function handler. + * + * @tparam HandlerType The function pointer handler type. + * @tparam CallbackContextPosition Context position (first or last). Automatically determined at compile-time. + * + */ +template ::Type, void *>::kValue + ? kContextAsFirstArg + : kContextAsLastArg)> +class Callback +{ +}; + +// Specialization for `kContextAsLastArg` +template class Callback : public CallbackBase +{ + using CallbackBase::mHandler; + using CallbackBase::mContext; + +public: + using ReturnType = typename TypeTraits::ReturnTypeOf::Type; ///< Return type of `HandlerType`. + + static constexpr CallbackContextPosition kContextPosition = kContextAsLastArg; ///< Context position. + + /** + * This constructor initializes `Callback` as empty (`nullptr` handler function pointer). + * + */ + Callback(void) = default; + + /** + * This method invokes the callback handler. + * + * The caller MUST ensure that callback is set (`IsSet()` returns `true`) before calling this method. + * + * @param[in] aArgs The args to pass to the callback handler. + * + * @returns The return value from handler. + * + */ + template ReturnType Invoke(Args &&...aArgs) const + { + return mHandler(static_cast(aArgs)..., mContext); + } + + /** + * This method invokes the callback handler if it is set. + * + * The method MUST be used when the handler function returns `void`. + * + * @param[in] aArgs The args to pass to the callback handler. + * + */ + template void InvokeIfSet(Args &&...aArgs) const + { + static_assert(TypeTraits::IsSame::kValue, + "InvokeIfSet() MUST be used with `void` returning handler"); + + if (mHandler != nullptr) + { + Invoke(static_cast(aArgs)...); + } + } +}; + +// Specialization for `kContextAsFirstArg` +template class Callback : public CallbackBase +{ + using CallbackBase::mHandler; + using CallbackBase::mContext; + +public: + using ReturnType = typename TypeTraits::ReturnTypeOf::Type; + + static constexpr CallbackContextPosition kContextPosition = kContextAsFirstArg; + + Callback(void) = default; + + template ReturnType Invoke(Args &&...aArgs) const + { + return mHandler(mContext, static_cast(aArgs)...); + } + + template void InvokeIfSet(Args &&...aArgs) const + { + static_assert(TypeTraits::IsSame::kValue, + "InvokeIfSet() MUST be used with `void` returning handler"); + + if (mHandler != nullptr) + { + Invoke(static_cast(aArgs)...); + } + } +}; + +} // namespace ot + +#endif // CALLBACK_HPP_ diff --git a/src/core/common/type_traits.hpp b/src/core/common/type_traits.hpp index 4feb52a2a..a6081464b 100644 --- a/src/core/common/type_traits.hpp +++ b/src/core/common/type_traits.hpp @@ -125,6 +125,41 @@ template struct Conditional::Type` would be `Error`. + * + * @tparam HandlerType The function pointer type. + * + */ +template struct ReturnTypeOf; + +template struct ReturnTypeOf +{ + typedef RetType Type; ///< The return type. +}; + +/** + * This type determines the type of the first argument of a given function pointer type. + * + * It provides member type named `Type` which gives the first argument type of `HandlerType` function pointer. + * + * For example, `ReturnTypeOf::Type` would be `void *`. + * + * @tparam HandlerType The function pointer type. + * + */ +template struct FirstArgTypeOf; + +template +struct FirstArgTypeOf +{ + typedef FirstArgType Type; ///< The first argument type. +}; + } // namespace TypeTraits } // namespace ot diff --git a/src/core/mac/sub_mac.cpp b/src/core/mac/sub_mac.cpp index 8b6d2d3d7..5e1fc7ee1 100644 --- a/src/core/mac/sub_mac.cpp +++ b/src/core/mac/sub_mac.cpp @@ -57,8 +57,6 @@ SubMac::SubMac(Instance &aInstance) , mRadioCaps(Get().GetCaps()) , mTransmitFrame(Get().GetTransmitBuffer()) , mCallbacks(aInstance) - , mPcapCallback(nullptr) - , mPcapCallbackContext(nullptr) , mTimer(aInstance) #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE , mCslTimer(aInstance, SubMac::HandleCslTimer) @@ -178,12 +176,6 @@ void SubMac::SetExtAddress(const ExtAddress &aExtAddress) LogDebg("RadioExtAddress: %s", mExtAddress.ToString().AsCString()); } -void SubMac::SetPcapCallback(otLinkPcapCallback aPcapCallback, void *aCallbackContext) -{ - mPcapCallback = aPcapCallback; - mPcapCallbackContext = aCallbackContext; -} - Error SubMac::Enable(void) { Error error = kErrorNone; @@ -286,9 +278,9 @@ exit: void SubMac::HandleReceiveDone(RxFrame *aFrame, Error aError) { - if (mPcapCallback && (aFrame != nullptr) && (aError == kErrorNone)) + if (mPcapCallback.IsSet() && (aFrame != nullptr) && (aError == kErrorNone)) { - mPcapCallback(aFrame, false, mPcapCallbackContext); + mPcapCallback.Invoke(aFrame, false); } if (!ShouldHandleTransmitSecurity() && aFrame != nullptr && aFrame->mInfo.mRxInfo.mAckedWithSecEnhAck) @@ -507,9 +499,9 @@ void SubMac::BeginTransmit(void) SetState(kStateTransmit); - if (mPcapCallback) + if (mPcapCallback.IsSet()) { - mPcapCallback(&mTransmitFrame, true, mPcapCallbackContext); + mPcapCallback.Invoke(&mTransmitFrame, true); } error = Get().Transmit(mTransmitFrame); diff --git a/src/core/mac/sub_mac.hpp b/src/core/mac/sub_mac.hpp index 62d02ab98..1bcfc7691 100644 --- a/src/core/mac/sub_mac.hpp +++ b/src/core/mac/sub_mac.hpp @@ -40,6 +40,7 @@ #include +#include "common/callback.hpp" #include "common/locator.hpp" #include "common/non_copyable.hpp" #include "common/timer.hpp" @@ -276,7 +277,10 @@ public: * @param[in] aCallbackContext A pointer to application-specific context. * */ - void SetPcapCallback(otLinkPcapCallback aPcapCallback, void *aCallbackContext); + void SetPcapCallback(otLinkPcapCallback aPcapCallback, void *aCallbackContext) + { + mPcapCallback.Set(aPcapCallback, aCallbackContext); + } /** * This method indicates whether radio should stay in Receive or Sleep during CSMA backoff. @@ -624,17 +628,16 @@ private: #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE bool mRadioFilterEnabled : 1; #endif - int8_t mEnergyScanMaxRssi; - TimeMilli mEnergyScanEndTime; - TxFrame &mTransmitFrame; - Callbacks mCallbacks; - otLinkPcapCallback mPcapCallback; - void *mPcapCallbackContext; - KeyMaterial mPrevKey; - KeyMaterial mCurrKey; - KeyMaterial mNextKey; - uint32_t mFrameCounter; - uint8_t mKeyId; + int8_t mEnergyScanMaxRssi; + TimeMilli mEnergyScanEndTime; + TxFrame &mTransmitFrame; + Callbacks mCallbacks; + Callback mPcapCallback; + KeyMaterial mPrevKey; + KeyMaterial mCurrKey; + KeyMaterial mNextKey; + uint32_t mFrameCounter; + uint8_t mKeyId; #if OPENTHREAD_CONFIG_MAC_ADD_DELAY_ON_NO_ACK_ERROR_BEFORE_RETRY uint8_t mRetxDelayBackOffExponent; #endif diff --git a/src/core/meshcop/commissioner.cpp b/src/core/meshcop/commissioner.cpp index ea97c1452..0bec1213d 100644 --- a/src/core/meshcop/commissioner.cpp +++ b/src/core/meshcop/commissioner.cpp @@ -70,9 +70,6 @@ Commissioner::Commissioner(Instance &aInstance) , mEnergyScan(aInstance) , mPanIdQuery(aInstance) , mState(kStateDisabled) - , mStateCallback(nullptr) - , mJoinerCallback(nullptr) - , mCallbackContext(nullptr) { memset(reinterpret_cast(mJoiners), 0, sizeof(mJoiners)); @@ -98,10 +95,7 @@ void Commissioner::SetState(State aState) LogInfo("State: %s -> %s", StateToString(oldState), StateToString(aState)); - if (mStateCallback) - { - mStateCallback(MapEnum(mState), mCallbackContext); - } + mStateCallback.InvokeIfSet(MapEnum(mState)); exit: return; @@ -113,7 +107,7 @@ void Commissioner::SignalJoinerEvent(JoinerEvent aEvent, const Joiner *aJoiner) Mac::ExtAddress joinerId; bool noJoinerId = false; - VerifyOrExit((mJoinerCallback != nullptr) && (aJoiner != nullptr)); + VerifyOrExit(mJoinerCallback.IsSet() && (aJoiner != nullptr)); aJoiner->CopyToJoinerInfo(joinerInfo); @@ -130,7 +124,7 @@ void Commissioner::SignalJoinerEvent(JoinerEvent aEvent, const Joiner *aJoiner) noJoinerId = true; } - mJoinerCallback(MapEnum(aEvent), &joinerInfo, noJoinerId ? nullptr : &joinerId, mCallbackContext); + mJoinerCallback.Invoke(MapEnum(aEvent), &joinerInfo, noJoinerId ? nullptr : &joinerId); exit: return; @@ -295,9 +289,8 @@ Error Commissioner::Start(StateCallback aStateCallback, JoinerCallback aJoinerCa SuccessOrExit(error = Get().Start(SendRelayTransmit, this)); Get().SetConnectedCallback(&Commissioner::HandleSecureAgentConnected, this); - mStateCallback = aStateCallback; - mJoinerCallback = aJoinerCallback; - mCallbackContext = aCallbackContext; + mStateCallback.Set(aStateCallback, aCallbackContext); + mJoinerCallback.Set(aJoinerCallback, aCallbackContext); mTransmitAttempts = 0; SuccessOrExit(error = SendPetition()); diff --git a/src/core/meshcop/commissioner.hpp b/src/core/meshcop/commissioner.hpp index 3614a26e8..c3c4809b2 100644 --- a/src/core/meshcop/commissioner.hpp +++ b/src/core/meshcop/commissioner.hpp @@ -42,6 +42,7 @@ #include "coap/coap_secure.hpp" #include "common/as_core_type.hpp" +#include "common/callback.hpp" #include "common/clearable.hpp" #include "common/locator.hpp" #include "common/log.hpp" @@ -621,9 +622,8 @@ private: State mState; - StateCallback mStateCallback; - JoinerCallback mJoinerCallback; - void *mCallbackContext; + Callback mStateCallback; + Callback mJoinerCallback; }; DeclareTmfHandler(Commissioner, kUriDatasetChanged); diff --git a/src/core/meshcop/dataset_manager.cpp b/src/core/meshcop/dataset_manager.cpp index 4c1f80a97..49d72c5ff 100644 --- a/src/core/meshcop/dataset_manager.cpp +++ b/src/core/meshcop/dataset_manager.cpp @@ -59,8 +59,6 @@ DatasetManager::DatasetManager(Instance &aInstance, Dataset::Type aType, Timer:: , mTimestampValid(false) , mMgmtPending(false) , mTimer(aInstance, aTimerHandler) - , mMgmtSetCallback(nullptr) - , mMgmtSetCallbackContext(nullptr) { mTimestamp.Clear(); } @@ -337,15 +335,12 @@ exit: mMgmtPending = false; - if (mMgmtSetCallback != nullptr) + if (mMgmtSetCallback.IsSet()) { - otDatasetMgmtSetCallback callback = mMgmtSetCallback; - void *context = mMgmtSetCallbackContext; + Callback callbackCopy = mMgmtSetCallback; - mMgmtSetCallback = nullptr; - mMgmtSetCallbackContext = nullptr; - - callback(error, context); + mMgmtSetCallback.Clear(); + callbackCopy.Invoke(error); } mTimer.Start(kSendSetDelay); @@ -510,9 +505,8 @@ Error DatasetManager::SendSetRequest(const Dataset::Info &aDatasetInfo, IgnoreError(messageInfo.SetSockAddrToRlocPeerAddrToLeaderAloc()); SuccessOrExit(error = Get().SendMessage(*message, messageInfo, HandleMgmtSetResponse, this)); - mMgmtSetCallback = aCallback; - mMgmtSetCallbackContext = aContext; - mMgmtPending = true; + mMgmtSetCallback.Set(aCallback, aContext); + mMgmtPending = true; LogInfo("sent dataset set request to leader"); diff --git a/src/core/meshcop/dataset_manager.hpp b/src/core/meshcop/dataset_manager.hpp index d133c8ea0..d6e1bbf7f 100644 --- a/src/core/meshcop/dataset_manager.hpp +++ b/src/core/meshcop/dataset_manager.hpp @@ -37,6 +37,7 @@ #include "openthread-core-config.h" +#include "common/callback.hpp" #include "common/locator.hpp" #include "common/non_copyable.hpp" #include "common/timer.hpp" @@ -359,8 +360,7 @@ private: bool mMgmtPending : 1; TimerMilli mTimer; - otDatasetMgmtSetCallback mMgmtSetCallback; - void *mMgmtSetCallbackContext; + Callback mMgmtSetCallback; }; class ActiveDatasetManager : public DatasetManager, private NonCopyable diff --git a/src/core/meshcop/dataset_updater.cpp b/src/core/meshcop/dataset_updater.cpp index 4b785af3a..114bae550 100644 --- a/src/core/meshcop/dataset_updater.cpp +++ b/src/core/meshcop/dataset_updater.cpp @@ -48,14 +48,12 @@ namespace MeshCoP { DatasetUpdater::DatasetUpdater(Instance &aInstance) : InstanceLocator(aInstance) - , mCallback(nullptr) - , mCallbackContext(nullptr) , mTimer(aInstance) , mDataset(nullptr) { } -Error DatasetUpdater::RequestUpdate(const Dataset::Info &aDataset, Callback aCallback, void *aContext) +Error DatasetUpdater::RequestUpdate(const Dataset::Info &aDataset, UpdaterCallback aCallback, void *aContext) { Error error = kErrorNone; Message *message = nullptr; @@ -71,9 +69,8 @@ Error DatasetUpdater::RequestUpdate(const Dataset::Info &aDataset, Callback aCal SuccessOrExit(error = message->Append(aDataset)); - mCallback = aCallback; - mCallbackContext = aContext; - mDataset = message; + mCallback.Set(aCallback, aContext); + mDataset = message; mTimer.Start(1); @@ -163,10 +160,7 @@ void DatasetUpdater::Finish(Error aError) FreeMessage(mDataset); mDataset = nullptr; - if (mCallback != nullptr) - { - mCallback(aError, mCallbackContext); - } + mCallback.InvokeIfSet(aError); } void DatasetUpdater::HandleNotifierEvents(Events aEvents) diff --git a/src/core/meshcop/dataset_updater.hpp b/src/core/meshcop/dataset_updater.hpp index 4c984c29e..ecc998d70 100644 --- a/src/core/meshcop/dataset_updater.hpp +++ b/src/core/meshcop/dataset_updater.hpp @@ -40,6 +40,7 @@ #include +#include "common/callback.hpp" #include "common/locator.hpp" #include "common/message.hpp" #include "common/non_copyable.hpp" @@ -72,10 +73,10 @@ public: * This type represents the callback function pointer which is called when a Dataset update request finishes, * reporting success or failure status of the request. * - * The function pointer has the syntax `void (*Callback)(Error aError, void *aContext)`. + * The function pointer has the syntax `void (*UpdaterCallback)(Error aError, void *aContext)`. * */ - typedef otDatasetUpdaterCallback Callback; + typedef otDatasetUpdaterCallback UpdaterCallback; /** * This method requests an update to Operational Dataset. @@ -94,7 +95,7 @@ public: * @retval kErrorNoBufs Could not allocated buffer to save Dataset. * */ - Error RequestUpdate(const Dataset::Info &aDataset, Callback aCallback, void *aContext); + Error RequestUpdate(const Dataset::Info &aDataset, UpdaterCallback aCallback, void *aContext); /** * This method cancels an ongoing (if any) Operational Dataset update request. @@ -125,10 +126,9 @@ private: using UpdaterTimer = TimerMilliIn; - Callback mCallback; - void *mCallbackContext; - UpdaterTimer mTimer; - Message *mDataset; + Callback mCallback; + UpdaterTimer mTimer; + Message *mDataset; }; } // namespace MeshCoP diff --git a/src/core/meshcop/dtls.cpp b/src/core/meshcop/dtls.cpp index 4b68305cc..88d63a954 100644 --- a/src/core/meshcop/dtls.cpp +++ b/src/core/meshcop/dtls.cpp @@ -83,12 +83,7 @@ Dtls::Dtls(Instance &aInstance, bool aLayerTwoSecurity) , mTimerSet(false) , mLayerTwoSecurity(aLayerTwoSecurity) , mReceiveMessage(nullptr) - , mConnectedHandler(nullptr) - , mReceiveHandler(nullptr) - , mContext(nullptr) , mSocket(aInstance) - , mTransportCallback(nullptr) - , mTransportContext(nullptr) , mMessageSubType(Message::kSubTypeNone) , mMessageDefaultSubType(Message::kSubTypeNone) { @@ -147,10 +142,9 @@ Error Dtls::Open(ReceiveHandler aReceiveHandler, ConnectedHandler aConnectedHand SuccessOrExit(error = mSocket.Open(&Dtls::HandleUdpReceive, this)); - mReceiveHandler = aReceiveHandler; - mConnectedHandler = aConnectedHandler; - mContext = aContext; - mState = kStateOpen; + mConnectedCallback.Set(aConnectedHandler, aContext); + mReceiveCallback.Set(aReceiveHandler, aContext); + mState = kStateOpen; exit: return error; @@ -221,7 +215,7 @@ Error Dtls::Bind(uint16_t aPort) Error error; VerifyOrExit(mState == kStateOpen, error = kErrorInvalidState); - VerifyOrExit(mTransportCallback == nullptr, error = kErrorAlready); + VerifyOrExit(!mTransportCallback.IsSet(), error = kErrorAlready); SuccessOrExit(error = mSocket.Bind(aPort, Ip6::kNetifUnspecified)); @@ -235,10 +229,9 @@ Error Dtls::Bind(TransportCallback aCallback, void *aContext) VerifyOrExit(mState == kStateOpen, error = kErrorInvalidState); VerifyOrExit(!mSocket.IsBound(), error = kErrorAlready); - VerifyOrExit(mTransportCallback == nullptr, error = kErrorAlready); + VerifyOrExit(!mTransportCallback.IsSet(), error = kErrorAlready); - mTransportCallback = aCallback; - mTransportContext = aContext; + mTransportCallback.Set(aCallback, aContext); exit: return error; @@ -439,10 +432,9 @@ void Dtls::Close(void) { Disconnect(); - mState = kStateClosed; - mTransportCallback = nullptr; - mTransportContext = nullptr; - mTimerSet = false; + mState = kStateClosed; + mTimerSet = false; + mTransportCallback.Clear(); IgnoreError(mSocket.Close()); mTimer.Stop(); @@ -851,11 +843,7 @@ void Dtls::HandleTimer(void) case kStateCloseNotify: mState = kStateOpen; mTimer.Stop(); - - if (mConnectedHandler != nullptr) - { - mConnectedHandler(mContext, false); - } + mConnectedCallback.InvokeIfSet(false); break; default: @@ -879,11 +867,7 @@ void Dtls::Process(void) if (mSsl.MBEDTLS_PRIVATE(state) == MBEDTLS_SSL_HANDSHAKE_OVER) { mState = kStateConnected; - - if (mConnectedHandler != nullptr) - { - mConnectedHandler(mContext, true); - } + mConnectedCallback.InvokeIfSet(true); } } else @@ -893,10 +877,7 @@ void Dtls::Process(void) if (rval > 0) { - if (mReceiveHandler != nullptr) - { - mReceiveHandler(mContext, buf, static_cast(rval)); - } + mReceiveCallback.InvokeIfSet(buf, static_cast(rval)); } else if (rval == 0 || rval == MBEDTLS_ERR_SSL_WANT_READ || rval == MBEDTLS_ERR_SSL_WANT_WRITE) { @@ -1006,9 +987,9 @@ Error Dtls::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, Message::SubTy message->SetSubType(aMessageSubType); } - if (mTransportCallback) + if (mTransportCallback.IsSet()) { - SuccessOrExit(error = mTransportCallback(mTransportContext, *message, mMessageInfo)); + SuccessOrExit(error = mTransportCallback.Invoke(*message, mMessageInfo)); } else { diff --git a/src/core/meshcop/dtls.hpp b/src/core/meshcop/dtls.hpp index e2a0f970a..129ed3c77 100644 --- a/src/core/meshcop/dtls.hpp +++ b/src/core/meshcop/dtls.hpp @@ -51,6 +51,7 @@ #endif #endif +#include "common/callback.hpp" #include "common/locator.hpp" #include "common/message.hpp" #include "common/random.hpp" @@ -494,15 +495,13 @@ private: Message *mReceiveMessage; - ConnectedHandler mConnectedHandler; - ReceiveHandler mReceiveHandler; - void *mContext; + Callback mConnectedCallback; + Callback mReceiveCallback; Ip6::MessageInfo mMessageInfo; Ip6::Udp::Socket mSocket; - TransportCallback mTransportCallback; - void *mTransportContext; + Callback mTransportCallback; Message::SubType mMessageSubType; Message::SubType mMessageDefaultSubType; diff --git a/src/core/meshcop/energy_scan_client.cpp b/src/core/meshcop/energy_scan_client.cpp index 1b98a9f0b..69ca8ed1f 100644 --- a/src/core/meshcop/energy_scan_client.cpp +++ b/src/core/meshcop/energy_scan_client.cpp @@ -55,8 +55,6 @@ RegisterLogModule("EnergyScanClnt"); EnergyScanClient::EnergyScanClient(Instance &aInstance) : InstanceLocator(aInstance) - , mCallback(nullptr) - , mContext(nullptr) { } @@ -95,8 +93,7 @@ Error EnergyScanClient::SendQuery(uint32_t aChannelMas LogInfo("sent query"); - mCallback = aCallback; - mContext = aContext; + mCallback.Set(aCallback, aContext); exit: FreeMessageOnError(message, error); @@ -117,10 +114,7 @@ void EnergyScanClient::HandleTmf(Coap::Message &aMessage, cons SuccessOrExit(MeshCoP::Tlv::FindTlv(aMessage, MeshCoP::Tlv::kEnergyList, sizeof(energyListTlv), energyListTlv)); - if (mCallback != nullptr) - { - mCallback(mask, energyListTlv.GetEnergyList(), energyListTlv.GetEnergyListLength(), mContext); - } + mCallback.InvokeIfSet(mask, energyListTlv.GetEnergyList(), energyListTlv.GetEnergyListLength()); SuccessOrExit(Get().SendEmptyAck(aMessage, aMessageInfo)); diff --git a/src/core/meshcop/energy_scan_client.hpp b/src/core/meshcop/energy_scan_client.hpp index 3649cf5c0..97d9873bb 100644 --- a/src/core/meshcop/energy_scan_client.hpp +++ b/src/core/meshcop/energy_scan_client.hpp @@ -41,6 +41,7 @@ #include #include "coap/coap.hpp" +#include "common/callback.hpp" #include "common/locator.hpp" #include "net/ip6_address.hpp" #include "net/udp6.hpp" @@ -89,8 +90,7 @@ public: private: template void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); - otCommissionerEnergyReportCallback mCallback; - void *mContext; + Callback mCallback; }; DeclareTmfHandler(EnergyScanClient, kUriEnergyReport); diff --git a/src/core/meshcop/joiner.cpp b/src/core/meshcop/joiner.cpp index 478191c11..21adc7dd1 100644 --- a/src/core/meshcop/joiner.cpp +++ b/src/core/meshcop/joiner.cpp @@ -62,8 +62,6 @@ Joiner::Joiner(Instance &aInstance) , mId() , mDiscerner() , mState(kStateIdle) - , mCallback(nullptr) - , mContext(nullptr) , mJoinerRouterIndex(0) , mFinalizeMessage(nullptr) , mTimer(aInstance) @@ -177,9 +175,8 @@ Error Joiner::Start(const char *aPskd, SuccessOrExit(error = Get().Discover(Mac::ChannelMask(0), Get().GetPanId(), /* aJoiner */ true, /* aEnableFiltering */ true, &filterIndexes, HandleDiscoverResult, this)); - mCallback = aCallback; - mContext = aContext; + mCallback.Set(aCallback, aContext); SetState(kStateDiscover); exit: @@ -197,7 +194,7 @@ void Joiner::Stop(void) LogInfo("Joiner stopped"); // Callback is set to `nullptr` to skip calling it from `Finish()` - mCallback = nullptr; + mCallback.Clear(); Finish(kErrorAbort); } @@ -226,10 +223,7 @@ void Joiner::Finish(Error aError) SetState(kStateIdle); FreeJoinerFinalizeMessage(); - if (mCallback) - { - mCallback(aError, mContext); - } + mCallback.InvokeIfSet(aError); exit: return; diff --git a/src/core/meshcop/joiner.hpp b/src/core/meshcop/joiner.hpp index 0f7a99bb9..f47dddb76 100644 --- a/src/core/meshcop/joiner.hpp +++ b/src/core/meshcop/joiner.hpp @@ -43,6 +43,7 @@ #include "coap/coap_message.hpp" #include "coap/coap_secure.hpp" #include "common/as_core_type.hpp" +#include "common/callback.hpp" #include "common/locator.hpp" #include "common/log.hpp" #include "common/message.hpp" @@ -239,8 +240,7 @@ private: State mState; - otJoinerCallback mCallback; - void *mContext; + Callback mCallback; JoinerRouter mJoinerRouters[OPENTHREAD_CONFIG_JOINER_MAX_CANDIDATES]; uint16_t mJoinerRouterIndex; diff --git a/src/core/meshcop/panid_query_client.cpp b/src/core/meshcop/panid_query_client.cpp index 0fb050836..b80ff4ef0 100644 --- a/src/core/meshcop/panid_query_client.cpp +++ b/src/core/meshcop/panid_query_client.cpp @@ -53,8 +53,6 @@ RegisterLogModule("PanIdQueryClnt"); PanIdQueryClient::PanIdQueryClient(Instance &aInstance) : InstanceLocator(aInstance) - , mCallback(nullptr) - , mContext(nullptr) { } @@ -89,8 +87,7 @@ Error PanIdQueryClient::SendQuery(uint16_t aPanId, LogInfo("sent panid query"); - mCallback = aCallback; - mContext = aContext; + mCallback.Set(aCallback, aContext); exit: FreeMessageOnError(message, error); @@ -112,10 +109,7 @@ void PanIdQueryClient::HandleTmf(Coap::Message &aMessage, con VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0); - if (mCallback != nullptr) - { - mCallback(panId, mask, mContext); - } + mCallback.InvokeIfSet(panId, mask); SuccessOrExit(Get().SendEmptyAck(aMessage, responseInfo)); diff --git a/src/core/meshcop/panid_query_client.hpp b/src/core/meshcop/panid_query_client.hpp index 495edfc7e..46b1ff784 100644 --- a/src/core/meshcop/panid_query_client.hpp +++ b/src/core/meshcop/panid_query_client.hpp @@ -40,6 +40,7 @@ #include +#include "common/callback.hpp" #include "common/locator.hpp" #include "net/ip6_address.hpp" #include "net/udp6.hpp" @@ -84,8 +85,7 @@ public: private: template void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); - otCommissionerPanIdConflictCallback mCallback; - void *mContext; + Callback mCallback; }; DeclareTmfHandler(PanIdQueryClient, kUriPanIdConflict); diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index a7c1eeee3..65b2bd340 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -69,12 +69,6 @@ Ip6::Ip6(Instance &aInstance) : InstanceLocator(aInstance) , mForwardingEnabled(false) , mIsReceiveIp6FilterEnabled(false) - , mReceiveIp6DatagramCallback(nullptr) - , mReceiveIp6DatagramCallbackContext(nullptr) -#if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE - , mReceiveIp4DatagramCallback(nullptr) - , mReceiveIp4DatagramCallbackContext(nullptr) -#endif , mSendQueueTask(aInstance) , mIcmp(aInstance) , mUdp(aInstance) @@ -194,20 +188,6 @@ exit: return error; } -void Ip6::SetReceiveDatagramCallback(otIp6ReceiveCallback aCallback, void *aCallbackContext) -{ - mReceiveIp6DatagramCallback = aCallback; - mReceiveIp6DatagramCallbackContext = aCallbackContext; -} - -#if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE -void Ip6::SetNat64ReceiveIp4DatagramCallback(otNat64ReceiveIp4Callback aCallback, void *aCallbackContext) -{ - mReceiveIp4DatagramCallback = aCallback; - mReceiveIp4DatagramCallbackContext = aCallbackContext; -} -#endif - Error Ip6::AddMplOption(Message &aMessage, Header &aHeader) { Error error = kErrorNone; @@ -1027,7 +1007,7 @@ Error Ip6::ProcessReceiveCallback(Message &aMessage, VerifyOrExit(aOrigin != kFromHostDisallowLoopBack, error = kErrorNoRoute); - VerifyOrExit(mReceiveIp6DatagramCallback != nullptr, error = kErrorNoRoute); + VerifyOrExit(mReceiveIp6DatagramCallback.IsSet(), error = kErrorNoRoute); // Do not forward IPv6 packets that exceed kMinimalMtu. VerifyOrExit(aMessage.GetLength() <= kMinimalMtu, error = kErrorDrop); @@ -1100,13 +1080,13 @@ Error Ip6::ProcessReceiveCallback(Message &aMessage, case Nat64::Translator::kDrop: ExitNow(error = kErrorDrop); case Nat64::Translator::kForward: - VerifyOrExit(mReceiveIp4DatagramCallback != nullptr, error = kErrorNoRoute); - mReceiveIp4DatagramCallback(message, mReceiveIp4DatagramCallbackContext); + VerifyOrExit(mReceiveIp4DatagramCallback.IsSet(), error = kErrorNoRoute); + mReceiveIp4DatagramCallback.Invoke(message); ExitNow(); } #endif - mReceiveIp6DatagramCallback(message, mReceiveIp6DatagramCallbackContext); + mReceiveIp6DatagramCallback.Invoke(message); #if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE UpdateBorderRoutingCounters(header, aMessage.GetLength(), /* aIsInbound */ false); diff --git a/src/core/net/ip6.hpp b/src/core/net/ip6.hpp index 3688e4cd2..d6230a2e9 100644 --- a/src/core/net/ip6.hpp +++ b/src/core/net/ip6.hpp @@ -42,6 +42,7 @@ #include #include +#include "common/callback.hpp" #include "common/encoding.hpp" #include "common/frame_data.hpp" #include "common/locator.hpp" @@ -246,7 +247,10 @@ public: * @sa SetReceiveIp6FilterEnabled * */ - void SetReceiveDatagramCallback(otIp6ReceiveCallback aCallback, void *aCallbackContext); + void SetReceiveDatagramCallback(otIp6ReceiveCallback aCallback, void *aCallbackContext) + { + mReceiveIp6DatagramCallback.Set(aCallback, aCallbackContext); + } #if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE /** @@ -259,7 +263,10 @@ public: * @sa SetReceiveDatagramCallback * */ - void SetNat64ReceiveIp4DatagramCallback(otNat64ReceiveIp4Callback aCallback, void *aCallbackContext); + void SetNat64ReceiveIp4DatagramCallback(otNat64ReceiveIp4Callback aCallback, void *aCallbackContext) + { + mReceiveIp4DatagramCallback.Set(aCallback, aCallbackContext); + } #endif /** @@ -414,14 +421,13 @@ private: using SendQueueTask = TaskletIn; - bool mForwardingEnabled; - bool mIsReceiveIp6FilterEnabled; - otIp6ReceiveCallback mReceiveIp6DatagramCallback; - void *mReceiveIp6DatagramCallbackContext; + bool mForwardingEnabled; + bool mIsReceiveIp6FilterEnabled; + + Callback mReceiveIp6DatagramCallback; #if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE - otNat64ReceiveIp4Callback mReceiveIp4DatagramCallback; - void *mReceiveIp4DatagramCallbackContext; + Callback mReceiveIp4DatagramCallback; #endif PriorityQueue mSendQueue; diff --git a/src/core/net/netif.cpp b/src/core/net/netif.cpp index a6b2564c9..009feaa9a 100644 --- a/src/core/net/netif.cpp +++ b/src/core/net/netif.cpp @@ -110,8 +110,6 @@ const otNetifMulticastAddress Netif::kLinkLocalAllRoutersMulticastAddress = { Netif::Netif(Instance &aInstance) : InstanceLocator(aInstance) , mMulticastPromiscuous(false) - , mAddressCallback(nullptr) - , mAddressCallbackContext(nullptr) { } @@ -275,7 +273,7 @@ void Netif::SignalMulticastAddressChange(AddressEvent aAddressEvent, : kEventIp6MulticastUnsubscribed); #if !OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE - VerifyOrExit(mAddressCallback != nullptr); + VerifyOrExit(mAddressCallback.IsSet()); #endif for (const MulticastAddress *entry = aStart; entry != aEnd; entry = entry->GetNext()) @@ -283,12 +281,12 @@ void Netif::SignalMulticastAddressChange(AddressEvent aAddressEvent, #if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE Get().RecordAddressEvent(aAddressEvent, *entry, kOriginThread); - if (mAddressCallback != nullptr) + if (mAddressCallback.IsSet()) #endif { AddressInfo addressInfo(*entry); - mAddressCallback(&addressInfo, aAddressEvent, mAddressCallbackContext); + mAddressCallback.Invoke(&addressInfo, aAddressEvent); } } @@ -313,11 +311,11 @@ void Netif::SubscribeMulticast(MulticastAddress &aAddress) Get().RecordAddressEvent(kAddressAdded, aAddress, kOriginThread); #endif - if (mAddressCallback != nullptr) + if (mAddressCallback.IsSet()) { AddressInfo addressInfo(aAddress); - mAddressCallback(&addressInfo, kAddressAdded, mAddressCallbackContext); + mAddressCallback.Invoke(&addressInfo, kAddressAdded); } exit: @@ -334,11 +332,11 @@ void Netif::UnsubscribeMulticast(const MulticastAddress &aAddress) Get().RecordAddressEvent(kAddressRemoved, aAddress, kOriginThread); #endif - if (mAddressCallback != nullptr) + if (mAddressCallback.IsSet()) { AddressInfo addressInfo(aAddress); - mAddressCallback(&addressInfo, kAddressRemoved, mAddressCallbackContext); + mAddressCallback.Invoke(&addressInfo, kAddressRemoved); } exit: @@ -422,12 +420,6 @@ void Netif::UnsubscribeAllExternalMulticastAddresses(void) } } -void Netif::SetAddressCallback(otIp6AddressCallback aCallback, void *aCallbackContext) -{ - mAddressCallback = aCallback; - mAddressCallbackContext = aCallbackContext; -} - void Netif::AddUnicastAddress(UnicastAddress &aAddress) { SuccessOrExit(mUnicastAddresses.Add(aAddress)); @@ -438,11 +430,11 @@ void Netif::AddUnicastAddress(UnicastAddress &aAddress) Get().RecordAddressEvent(kAddressAdded, aAddress); #endif - if (mAddressCallback != nullptr) + if (mAddressCallback.IsSet()) { AddressInfo addressInfo(aAddress); - mAddressCallback(&addressInfo, kAddressAdded, mAddressCallbackContext); + mAddressCallback.Invoke(&addressInfo, kAddressAdded); } exit: @@ -459,11 +451,11 @@ void Netif::RemoveUnicastAddress(const UnicastAddress &aAddress) Get().RecordAddressEvent(kAddressRemoved, aAddress); #endif - if (mAddressCallback != nullptr) + if (mAddressCallback.IsSet()) { AddressInfo addressInfo(aAddress); - mAddressCallback(&addressInfo, kAddressRemoved, mAddressCallbackContext); + mAddressCallback.Invoke(&addressInfo, kAddressRemoved); } exit: diff --git a/src/core/net/netif.hpp b/src/core/net/netif.hpp index 808d42348..29f3b6124 100644 --- a/src/core/net/netif.hpp +++ b/src/core/net/netif.hpp @@ -37,6 +37,7 @@ #include "openthread-core-config.h" #include "common/as_core_type.hpp" +#include "common/callback.hpp" #include "common/clearable.hpp" #include "common/code_utils.hpp" #include "common/const_cast.hpp" @@ -367,7 +368,10 @@ public: * @param[in] aCallbackContext A pointer to application-specific context. * */ - void SetAddressCallback(otIp6AddressCallback aCallback, void *aCallbackContext); + void SetAddressCallback(otIp6AddressCallback aCallback, void *aCallbackContext) + { + mAddressCallback.Set(aCallback, aCallbackContext); + } /** * This method returns the linked list of unicast addresses. @@ -652,8 +656,7 @@ private: LinkedList mMulticastAddresses; bool mMulticastPromiscuous; - otIp6AddressCallback mAddressCallback; - void *mAddressCallbackContext; + Callback mAddressCallback; Pool mExtUnicastAddressPool; Pool mExtMulticastAddressPool; diff --git a/src/core/net/srp_client.cpp b/src/core/net/srp_client.cpp index 873225ccb..246003858 100644 --- a/src/core/net/srp_client.cpp +++ b/src/core/net/srp_client.cpp @@ -206,18 +206,9 @@ void Client::AutoStart::SetState(State aState) } } -void Client::AutoStart::SetCallback(AutoStartCallback aCallback, void *aContext) -{ - mCallback = aCallback; - mContext = aContext; -} - void Client::AutoStart::InvokeCallback(const Ip6::SockAddr *aServerSockAddr) const { - if (mCallback != nullptr) - { - mCallback(aServerSockAddr, mContext); - } + mCallback.InvokeIfSet(aServerSockAddr); } #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) @@ -266,8 +257,6 @@ Client::Client(Instance &aInstance) , mDefaultLease(kDefaultLease) , mDefaultKeyLease(kDefaultKeyLease) , mSocket(aInstance) - , mCallback(nullptr) - , mCallbackContext(nullptr) , mDomainName(kDefaultDomainName) , mTimer(aInstance) { @@ -382,12 +371,6 @@ exit: #endif } -void Client::SetCallback(Callback aCallback, void *aContext) -{ - mCallback = aCallback; - mCallbackContext = aContext; -} - void Client::Resume(void) { SetState(kStateUpdated); @@ -743,11 +726,7 @@ void Client::InvokeCallback(Error aError) const { InvokeCallback(aError, mHostIn void Client::InvokeCallback(Error aError, const HostInfo &aHostInfo, const Service *aRemovedServices) const { - VerifyOrExit(mCallback != nullptr); - mCallback(aError, &aHostInfo, mServices.GetHead(), aRemovedServices, mCallbackContext); - -exit: - return; + mCallback.InvokeIfSet(aError, &aHostInfo, mServices.GetHead(), aRemovedServices); } void Client::SendUpdate(void) diff --git a/src/core/net/srp_client.hpp b/src/core/net/srp_client.hpp index 9332aae8e..948be4e46 100644 --- a/src/core/net/srp_client.hpp +++ b/src/core/net/srp_client.hpp @@ -36,6 +36,7 @@ #include #include "common/as_core_type.hpp" +#include "common/callback.hpp" #include "common/clearable.hpp" #include "common/linked_list.hpp" #include "common/locator.hpp" @@ -97,7 +98,7 @@ public: * Please see `otSrpClientCallback` for more details. * */ - typedef otSrpClientCallback Callback; + typedef otSrpClientCallback ClientCallback; /** * This type represents an SRP client host info. @@ -461,7 +462,7 @@ public: * @param[in] aContext An arbitrary context used with @p aCallback. * */ - void SetCallback(Callback aCallback, void *aContext); + void SetCallback(ClientCallback aCallback, void *aContext) { mCallback.Set(aCallback, aContext); } /** * This method gets the TTL used in SRP update requests. @@ -925,7 +926,7 @@ private: void SetState(State aState); uint8_t GetAnycastSeqNum(void) const { return mAnycastSeqNum; } void SetAnycastSeqNum(uint8_t aAnycastSeqNum) { mAnycastSeqNum = aAnycastSeqNum; } - void SetCallback(AutoStartCallback aCallback, void *aContext); + void SetCallback(AutoStartCallback aCallback, void *aContext) { mCallback.Set(aCallback, aContext); } void InvokeCallback(const Ip6::SockAddr *aServerSockAddr) const; #if OPENTHREAD_CONFIG_SRP_CLIENT_SWITCH_SERVER_ON_FAILURE @@ -945,10 +946,9 @@ private: static const char *StateToString(State aState); - AutoStartCallback mCallback; - void *mContext; - State mState; - uint8_t mAnycastSeqNum; + Callback mCallback; + State mState; + uint8_t mAnycastSeqNum; #if OPENTHREAD_CONFIG_SRP_CLIENT_SWITCH_SERVER_ON_FAILURE uint8_t mTimoutFailureCount; // Number of no-response timeout failures with the currently selected server. #endif @@ -1049,12 +1049,11 @@ private: Ip6::Udp::Socket mSocket; - Callback mCallback; - void *mCallbackContext; - const char *mDomainName; - HostInfo mHostInfo; - LinkedList mServices; - DelayTimer mTimer; + Callback mCallback; + const char *mDomainName; + HostInfo mHostInfo; + LinkedList mServices; + DelayTimer mTimer; #if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE AutoStart mAutoStart; #endif diff --git a/src/core/net/srp_server.cpp b/src/core/net/srp_server.cpp index 065e734af..eecaf4664 100644 --- a/src/core/net/srp_server.cpp +++ b/src/core/net/srp_server.cpp @@ -86,8 +86,6 @@ static Dns::UpdateHeader::Response ErrorToDnsResponseCode(Error aError) Server::Server(Instance &aInstance) : InstanceLocator(aInstance) , mSocket(aInstance) - , mServiceUpdateHandler(nullptr) - , mServiceUpdateHandlerContext(nullptr) , mLeaseTimer(aInstance) , mOutstandingUpdatesTimer(aInstance) , mServiceUpdateId(Random::NonCrypto::GetUint32()) @@ -103,12 +101,6 @@ Server::Server(Instance &aInstance) IgnoreError(SetDomain(kDefaultDomain)); } -void Server::SetServiceHandler(otSrpServerServiceUpdateHandler aServiceHandler, void *aServiceHandlerContext) -{ - mServiceUpdateHandler = aServiceHandler; - mServiceUpdateHandlerContext = aServiceHandlerContext; -} - Error Server::SetAddressMode(AddressMode aMode) { Error error = kErrorNone; @@ -342,12 +334,12 @@ void Server::RemoveHost(Host *aHost, RetainName aRetainName, NotifyMode aNotifyS LogInfo("Fully remove host %s", aHost->GetFullName()); } - if (aNotifyServiceHandler && mServiceUpdateHandler != nullptr) + if (aNotifyServiceHandler && mServiceUpdateHandler.IsSet()) { uint32_t updateId = AllocateId(); LogInfo("SRP update handler is notified (updatedId = %lu)", ToUlong(updateId)); - mServiceUpdateHandler(updateId, aHost, kDefaultEventsHandlerTimeout, mServiceUpdateHandlerContext); + mServiceUpdateHandler.Invoke(updateId, aHost, static_cast(kDefaultEventsHandlerTimeout)); // We don't wait for the reply from the service update handler, // but always remove the host (and its services) regardless of // host/service update result. Because removing a host should fail @@ -1373,7 +1365,7 @@ void Server::InformUpdateHandlerOrCommit(Error aError, Host &aHost, const Messag } #endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) - if ((aError == kErrorNone) && (mServiceUpdateHandler != nullptr)) + if ((aError == kErrorNone) && mServiceUpdateHandler.IsSet()) { UpdateMetadata *update = UpdateMetadata::Allocate(GetInstance(), aHost, aMetadata); @@ -1383,7 +1375,7 @@ void Server::InformUpdateHandlerOrCommit(Error aError, Host &aHost, const Messag mOutstandingUpdatesTimer.FireAtIfEarlier(update->GetExpireTime()); LogInfo("SRP update handler is notified (updatedId = %lu)", ToUlong(update->GetId())); - mServiceUpdateHandler(update->GetId(), &aHost, kDefaultEventsHandlerTimeout, mServiceUpdateHandlerContext); + mServiceUpdateHandler.Invoke(update->GetId(), &aHost, static_cast(kDefaultEventsHandlerTimeout)); ExitNow(); } @@ -2068,12 +2060,12 @@ void Server::Host::RemoveService(Service *aService, RetainName aRetainName, Noti aService->Log(aRetainName ? Service::kRemoveButRetainName : Service::kFullyRemove); - if (aNotifyServiceHandler && server.mServiceUpdateHandler != nullptr) + if (aNotifyServiceHandler && server.mServiceUpdateHandler.IsSet()) { uint32_t updateId = server.AllocateId(); LogInfo("SRP update handler is notified (updatedId = %lu)", ToUlong(updateId)); - server.mServiceUpdateHandler(updateId, this, kDefaultEventsHandlerTimeout, server.mServiceUpdateHandlerContext); + server.mServiceUpdateHandler.Invoke(updateId, this, static_cast(kDefaultEventsHandlerTimeout)); // We don't wait for the reply from the service update handler, // but always remove the service regardless of service update result. // Because removing a service should fail only when there is system diff --git a/src/core/net/srp_server.hpp b/src/core/net/srp_server.hpp index 92e6a3845..920be2e88 100644 --- a/src/core/net/srp_server.hpp +++ b/src/core/net/srp_server.hpp @@ -55,6 +55,7 @@ #include "common/array.hpp" #include "common/as_core_type.hpp" +#include "common/callback.hpp" #include "common/clearable.hpp" #include "common/heap.hpp" #include "common/heap_allocatable.hpp" @@ -718,7 +719,10 @@ public: * @sa HandleServiceUpdateResult * */ - void SetServiceHandler(otSrpServerServiceUpdateHandler aServiceHandler, void *aServiceHandlerContext); + void SetServiceHandler(otSrpServerServiceUpdateHandler aServiceHandler, void *aServiceHandlerContext) + { + mServiceUpdateHandler.Set(aServiceHandler, aServiceHandlerContext); + } /** * This method returns the domain authorized to the SRP server. @@ -1056,9 +1060,9 @@ private: using LeaseTimer = TimerMilliIn; using UpdateTimer = TimerMilliIn; - Ip6::Udp::Socket mSocket; - otSrpServerServiceUpdateHandler mServiceUpdateHandler; - void *mServiceUpdateHandlerContext; + Ip6::Udp::Socket mSocket; + + Callback mServiceUpdateHandler; Heap::String mDomain; diff --git a/src/core/net/udp6.cpp b/src/core/net/udp6.cpp index 9aed481be..9e2adaaae 100644 --- a/src/core/net/udp6.cpp +++ b/src/core/net/udp6.cpp @@ -149,10 +149,6 @@ Udp::Udp(Instance &aInstance) #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE , mPrevBackboneSockets(nullptr) #endif -#if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE - , mUdpForwarderContext(nullptr) - , mUdpForwarder(nullptr) -#endif { } @@ -430,9 +426,8 @@ Error Udp::SendDatagram(Message &aMessage, MessageInfo &aMessageInfo, uint8_t aI #if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE if (aMessageInfo.IsHostInterface()) { - VerifyOrExit(mUdpForwarder != nullptr, error = kErrorNoRoute); - mUdpForwarder(&aMessage, aMessageInfo.mPeerPort, &aMessageInfo.GetPeerAddr(), aMessageInfo.mSockPort, - mUdpForwarderContext); + VerifyOrExit(mUdpForwarder.IsSet(), error = kErrorNoRoute); + mUdpForwarder.Invoke(&aMessage, aMessageInfo.mPeerPort, &aMessageInfo.GetPeerAddr(), aMessageInfo.mSockPort); // message is consumed by the callback } else diff --git a/src/core/net/udp6.hpp b/src/core/net/udp6.hpp index 396457ad8..41c445f9c 100644 --- a/src/core/net/udp6.hpp +++ b/src/core/net/udp6.hpp @@ -40,6 +40,7 @@ #include #include "common/as_core_type.hpp" +#include "common/callback.hpp" #include "common/clearable.hpp" #include "common/linked_list.hpp" #include "common/locator.hpp" @@ -593,11 +594,7 @@ public: * @param[in] aContext A pointer to arbitrary context information. * */ - void SetUdpForwarder(otUdpForwarder aForwarder, void *aContext) - { - mUdpForwarder = aForwarder; - mUdpForwarderContext = aContext; - } + void SetUdpForwarder(otUdpForwarder aForwarder, void *aContext) { mUdpForwarder.Set(aForwarder, aContext); } #endif /** @@ -652,8 +649,7 @@ private: SocketHandle *mPrevBackboneSockets; #endif #if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE - void *mUdpForwarderContext; - otUdpForwarder mUdpForwarder; + Callback mUdpForwarder; #endif }; diff --git a/src/core/thread/anycast_locator.cpp b/src/core/thread/anycast_locator.cpp index e403542c5..88a02d4e1 100644 --- a/src/core/thread/anycast_locator.cpp +++ b/src/core/thread/anycast_locator.cpp @@ -46,13 +46,11 @@ namespace ot { AnycastLocator::AnycastLocator(Instance &aInstance) : InstanceLocator(aInstance) - , mCallback(nullptr) - , mContext(nullptr) { } -Error AnycastLocator::Locate(const Ip6::Address &aAnycastAddress, Callback aCallback, void *aContext) +Error AnycastLocator::Locate(const Ip6::Address &aAnycastAddress, LocatorCallback aCallback, void *aContext) { Error error = kErrorNone; Coap::Message *message = nullptr; @@ -64,7 +62,7 @@ Error AnycastLocator::Locate(const Ip6::Address &aAnycastAddress, Callback aCall message = Get().NewConfirmablePostMessage(kUriAnycastLocate); VerifyOrExit(message != nullptr, error = kErrorNoBufs); - if (mCallback != nullptr) + if (mCallback.IsSet()) { IgnoreError(Get().AbortTransaction(HandleResponse, this)); } @@ -73,8 +71,7 @@ Error AnycastLocator::Locate(const Ip6::Address &aAnycastAddress, Callback aCall SuccessOrExit(error = Get().SendMessage(*message, messageInfo, HandleResponse, this)); - mCallback = aCallback; - mContext = aContext; + mCallback.Set(aCallback, aContext); exit: FreeMessageOnError(message, error); @@ -112,12 +109,12 @@ void AnycastLocator::HandleResponse(Coap::Message *aMessage, const Ip6::MessageI address = &meshLocalAddress; exit: - if (mCallback != nullptr) + if (mCallback.IsSet()) { - Callback callback = mCallback; + Callback callbackCopy = mCallback; - mCallback = nullptr; - callback(mContext, aError, address, rloc16); + mCallback.Clear(); + callbackCopy.Invoke(aError, address, rloc16); } } diff --git a/src/core/thread/anycast_locator.hpp b/src/core/thread/anycast_locator.hpp index c823676f7..cba969d2e 100644 --- a/src/core/thread/anycast_locator.hpp +++ b/src/core/thread/anycast_locator.hpp @@ -38,6 +38,7 @@ #if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE +#include "common/callback.hpp" #include "common/locator.hpp" #include "common/non_copyable.hpp" #include "net/ip6_address.hpp" @@ -61,7 +62,7 @@ public: * This function pointer type defines the callback to notify the outcome of a request. * */ - typedef otThreadAnycastLocatorCallback Callback; + typedef otThreadAnycastLocatorCallback LocatorCallback; /** * This constructor initializes the `AnycastLocator` object. @@ -86,7 +87,7 @@ public: * @retval kErrorInvalidArgs The @p aAnycastAddress is not a valid anycast address or @p aCallback is `nullptr`. * */ - Error Locate(const Ip6::Address &aAnycastAddress, Callback aCallback, void *aContext); + Error Locate(const Ip6::Address &aAnycastAddress, LocatorCallback aCallback, void *aContext); /** * This method indicates whether an earlier request is in progress. @@ -94,7 +95,7 @@ public: * @returns TRUE if an earlier request is in progress, FALSE otherwise. * */ - bool IsInProgress(void) const { return (mCallback != nullptr); } + bool IsInProgress(void) const { return mCallback.IsSet(); } private: static void HandleResponse(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo, Error aError); @@ -103,8 +104,7 @@ private: template void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); - Callback mCallback; - void *mContext; + Callback mCallback; }; #if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_SEND_RESPONSE diff --git a/src/core/thread/discover_scanner.cpp b/src/core/thread/discover_scanner.cpp index 78688b9cd..c530e635a 100644 --- a/src/core/thread/discover_scanner.cpp +++ b/src/core/thread/discover_scanner.cpp @@ -47,8 +47,6 @@ namespace Mle { DiscoverScanner::DiscoverScanner(Instance &aInstance) : InstanceLocator(aInstance) - , mHandler(nullptr) - , mHandlerContext(nullptr) , mScanDoneTask(aInstance) , mTimer(aInstance) , mFilterIndexes() @@ -97,8 +95,7 @@ Error DiscoverScanner::Discover(const Mac::ChannelMask &aScanChannels, } } - mHandler = aCallback; - mHandlerContext = aContext; + mCallback.Set(aCallback, aContext); mShouldRestorePanId = false; mScanChannels = Get().GetSupportedChannelMask(); @@ -259,11 +256,7 @@ void DiscoverScanner::HandleDiscoverComplete(void) void DiscoverScanner::HandleScanDoneTask(void) { mState = kStateIdle; - - if (mHandler != nullptr) - { - mHandler(nullptr, mHandlerContext); - } + mCallback.InvokeIfSet(nullptr); } void DiscoverScanner::HandleTimer(void) @@ -383,10 +376,7 @@ void DiscoverScanner::HandleDiscoveryResponse(Mle::RxInfo &aRxInfo) const VerifyOrExit(!mEnableFiltering || didCheckSteeringData); - if (mHandler) - { - mHandler(&result, mHandlerContext); - } + mCallback.InvokeIfSet(&result); exit: Mle::LogProcessError(Mle::kTypeDiscoveryResponse, error); diff --git a/src/core/thread/discover_scanner.hpp b/src/core/thread/discover_scanner.hpp index 496b38db2..ac5ac523e 100644 --- a/src/core/thread/discover_scanner.hpp +++ b/src/core/thread/discover_scanner.hpp @@ -36,6 +36,7 @@ #include "openthread-core-config.h" +#include "common/callback.hpp" #include "common/locator.hpp" #include "common/non_copyable.hpp" #include "common/tasklet.hpp" @@ -177,19 +178,18 @@ private: using ScanTimer = TimerMilliIn; using ScanDoneTask = TaskletIn; - Handler mHandler; - void *mHandlerContext; - ScanDoneTask mScanDoneTask; - ScanTimer mTimer; - FilterIndexes mFilterIndexes; - Mac::ChannelMask mScanChannels; - State mState; - uint32_t mOui; - uint8_t mScanChannel; - uint8_t mAdvDataLength; - uint8_t mAdvData[MeshCoP::JoinerAdvertisementTlv::kAdvDataMaxLength]; - bool mEnableFiltering : 1; - bool mShouldRestorePanId : 1; + Callback mCallback; + ScanDoneTask mScanDoneTask; + ScanTimer mTimer; + FilterIndexes mFilterIndexes; + Mac::ChannelMask mScanChannels; + State mState; + uint32_t mOui; + uint8_t mScanChannel; + uint8_t mAdvDataLength; + uint8_t mAdvData[MeshCoP::JoinerAdvertisementTlv::kAdvDataMaxLength]; + bool mEnableFiltering : 1; + bool mShouldRestorePanId : 1; }; } // namespace Mle diff --git a/src/core/thread/link_metrics.cpp b/src/core/thread/link_metrics.cpp index 2768c66af..7fd4e081d 100644 --- a/src/core/thread/link_metrics.cpp +++ b/src/core/thread/link_metrics.cpp @@ -53,12 +53,6 @@ RegisterLogModule("LinkMetrics"); LinkMetrics::LinkMetrics(Instance &aInstance) : InstanceLocator(aInstance) - , mReportCallback(nullptr) - , mReportCallbackContext(nullptr) - , mMgmtResponseCallback(nullptr) - , mMgmtResponseCallbackContext(nullptr) - , mEnhAckProbingIeReportCallback(nullptr) - , mEnhAckProbingIeReportCallbackContext(nullptr) { } @@ -362,7 +356,7 @@ Error LinkMetrics::HandleManagementResponse(const Message &aMessage, const Ip6:: uint8_t status; bool hasStatus = false; - VerifyOrExit(mMgmtResponseCallback != nullptr); + VerifyOrExit(mMgmtResponseCallback.IsSet()); SuccessOrExit(error = Tlv::FindTlvValueOffset(aMessage, Mle::Tlv::Type::kLinkMetricsManagement, offset, length)); endOffset = offset + length; @@ -390,7 +384,7 @@ Error LinkMetrics::HandleManagementResponse(const Message &aMessage, const Ip6:: VerifyOrExit(hasStatus, error = kErrorParse); - mMgmtResponseCallback(&aAddress, status, mMgmtResponseCallbackContext); + mMgmtResponseCallback.Invoke(&aAddress, status); exit: return error; @@ -414,7 +408,7 @@ void LinkMetrics::HandleReport(const Message &aMessage, OT_UNUSED_VARIABLE(error); - VerifyOrExit(mReportCallback != nullptr); + VerifyOrExit(mReportCallback.IsSet()); values.Clear(); @@ -494,8 +488,8 @@ void LinkMetrics::HandleReport(const Message &aMessage, VerifyOrExit(hasStatus || hasReport); - mReportCallback(&aAddress, hasStatus ? nullptr : &values, hasStatus ? static_cast(status) : kStatusSuccess, - mReportCallbackContext); + mReportCallback.Invoke(&aAddress, hasStatus ? nullptr : &values, + hasStatus ? static_cast(status) : kStatusSuccess); exit: LogDebg("HandleReport, error:%s", ErrorToString(error)); @@ -515,30 +509,12 @@ exit: return error; } -void LinkMetrics::SetReportCallback(ReportCallback aCallback, void *aContext) -{ - mReportCallback = aCallback; - mReportCallbackContext = aContext; -} - -void LinkMetrics::SetMgmtResponseCallback(MgmtResponseCallback aCallback, void *aContext) -{ - mMgmtResponseCallback = aCallback; - mMgmtResponseCallbackContext = aContext; -} - -void LinkMetrics::SetEnhAckProbingCallback(EnhAckProbingIeReportCallback aCallback, void *aContext) -{ - mEnhAckProbingIeReportCallback = aCallback; - mEnhAckProbingIeReportCallbackContext = aContext; -} - void LinkMetrics::ProcessEnhAckIeData(const uint8_t *aData, uint8_t aLength, const Neighbor &aNeighbor) { MetricsValues values; uint8_t idx = 0; - VerifyOrExit(mEnhAckProbingIeReportCallback != nullptr); + VerifyOrExit(mEnhAckProbingIeReportCallback.IsSet()); values.SetMetrics(aNeighbor.GetEnhAckProbingMetrics()); @@ -555,8 +531,7 @@ void LinkMetrics::ProcessEnhAckIeData(const uint8_t *aData, uint8_t aLength, con values.mRssiValue = ScaleRawValueToRssi(aData[idx++]); } - mEnhAckProbingIeReportCallback(aNeighbor.GetRloc16(), &aNeighbor.GetExtAddress(), &values, - mEnhAckProbingIeReportCallbackContext); + mEnhAckProbingIeReportCallback.Invoke(aNeighbor.GetRloc16(), &aNeighbor.GetExtAddress(), &values); exit: return; diff --git a/src/core/thread/link_metrics.hpp b/src/core/thread/link_metrics.hpp index f63ca1cfe..0e63ea3f9 100644 --- a/src/core/thread/link_metrics.hpp +++ b/src/core/thread/link_metrics.hpp @@ -46,6 +46,7 @@ #include #include "common/as_core_type.hpp" +#include "common/callback.hpp" #include "common/clearable.hpp" #include "common/locator.hpp" #include "common/message.hpp" @@ -245,7 +246,7 @@ public: * @param[in] aContext A pointer to application-specific context. * */ - void SetReportCallback(ReportCallback aCallback, void *aContext); + void SetReportCallback(ReportCallback aCallback, void *aContext) { mReportCallback.Set(aCallback, aContext); } /** * This method registers a callback to handle Link Metrics Management Response received. @@ -254,7 +255,10 @@ public: * @param[in] aContext A pointer to application-specific context. * */ - void SetMgmtResponseCallback(MgmtResponseCallback aCallback, void *aContext); + void SetMgmtResponseCallback(MgmtResponseCallback aCallback, void *aContext) + { + mMgmtResponseCallback.Set(aCallback, aContext); + } /** * This method registers a callback to handle Link Metrics when Enh-ACK Probing IE is received. @@ -263,7 +267,10 @@ public: * @param[in] aContext A pointer to application-specific context. * */ - void SetEnhAckProbingCallback(EnhAckProbingIeReportCallback aCallback, void *aContext); + void SetEnhAckProbingCallback(EnhAckProbingIeReportCallback aCallback, void *aContext) + { + mEnhAckProbingIeReportCallback.Set(aCallback, aContext); + } /** * This method processes received Enh-ACK Probing IE data. @@ -320,12 +327,9 @@ private: static uint8_t ScaleRssiToRawValue(int8_t aRssi); static int8_t ScaleRawValueToRssi(uint8_t aRawValue); - ReportCallback mReportCallback; - void *mReportCallbackContext; - MgmtResponseCallback mMgmtResponseCallback; - void *mMgmtResponseCallbackContext; - EnhAckProbingIeReportCallback mEnhAckProbingIeReportCallback; - void *mEnhAckProbingIeReportCallbackContext; + Callback mReportCallback; + Callback mMgmtResponseCallback; + Callback mEnhAckProbingIeReportCallback; Pool mSeriesInfoPool; }; diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 3ae7fa9a3..b6a537843 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -107,10 +107,6 @@ Mle::Mle(Instance &aInstance) , mAlternatePanId(Mac::kPanIdBroadcast) , mAlternateTimestamp(0) , mDetachGracefullyTimer(aInstance) - , mDetachGracefullyCallback(nullptr) - , mDetachGracefullyContext(nullptr) - , mParentResponseCb(nullptr) - , mParentResponseCbContext(nullptr) { mParent.Init(aInstance); mParentCandidate.Init(aInstance); @@ -251,15 +247,12 @@ void Mle::Stop(StopMode aMode) exit: mDetachGracefullyTimer.Stop(); - if (mDetachGracefullyCallback != nullptr) + if (mDetachGracefullyCallback.IsSet()) { - otDetachGracefullyCallback callback = mDetachGracefullyCallback; - void *context = mDetachGracefullyContext; + Callback callbackCopy = mDetachGracefullyCallback; - mDetachGracefullyCallback = nullptr; - mDetachGracefullyContext = nullptr; - - callback(context); + mDetachGracefullyCallback.Clear(); + callbackCopy.Invoke(); } } @@ -3150,7 +3143,7 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo) #endif // Share data with application, if requested. - if (mParentResponseCb) + if (mParentResponseCallback.IsSet()) { otThreadParentResponseInfo parentinfo; @@ -3163,7 +3156,7 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo) parentinfo.mLinkQuality1 = connectivityTlv.GetLinkQuality1(); parentinfo.mIsAttached = IsAttached(); - mParentResponseCb(&parentinfo, mParentResponseCbContext); + mParentResponseCallback.Invoke(&parentinfo); } aRxInfo.mClass = RxInfo::kAuthoritativeMessage; @@ -4295,12 +4288,6 @@ exit: } #endif -void Mle::RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCallback, void *aContext) -{ - mParentResponseCb = aCallback; - mParentResponseCbContext = aContext; -} - #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE uint64_t Mle::CalcParentCslMetric(const Mac::CslAccuracy &aCslAccuracy) const { @@ -4325,10 +4312,9 @@ Error Mle::DetachGracefully(otDetachGracefullyCallback aCallback, void *aContext VerifyOrExit(!IsDetachingGracefully(), error = kErrorBusy); - OT_ASSERT(mDetachGracefullyCallback == nullptr); + OT_ASSERT(!mDetachGracefullyCallback.IsSet()); - mDetachGracefullyCallback = aCallback; - mDetachGracefullyContext = aContext; + mDetachGracefullyCallback.Set(aCallback, aContext); #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE Get().RequestStop(); diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index aeef59981..62e471a6c 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -36,6 +36,7 @@ #include "openthread-core-config.h" +#include "common/callback.hpp" #include "common/encoding.hpp" #include "common/locator.hpp" #include "common/log.hpp" @@ -619,7 +620,10 @@ public: * @param[in] aContext A pointer to application-specific context. * */ - void RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCallback, void *aContext); + void RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCallback, void *aContext) + { + mParentResponseCallback.Set(aCallback, aContext); + } /** * This method requests MLE layer to prepare and send a shorter version of Child ID Request message by only @@ -2047,12 +2051,10 @@ private: Ip6::Netif::MulticastAddress mLinkLocalAllThreadNodes; Ip6::Netif::MulticastAddress mRealmLocalAllThreadNodes; - DetachGracefullyTimer mDetachGracefullyTimer; - otDetachGracefullyCallback mDetachGracefullyCallback; - void *mDetachGracefullyContext; + DetachGracefullyTimer mDetachGracefullyTimer; + Callback mDetachGracefullyCallback; - otThreadParentResponseCallback mParentResponseCb; - void *mParentResponseCbContext; + Callback mParentResponseCallback; }; } // namespace Mle diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index e0e9668d0..1b79d2555 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -93,8 +93,6 @@ MleRouter::MleRouter(Instance &aInstance) #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE , mMaxChildIpAddresses(0) #endif - , mDiscoveryRequestCallback(nullptr) - , mDiscoveryRequestCallbackContext(nullptr) { mDeviceMode.Set(mDeviceMode.Get() | DeviceMode::kModeFullThreadDevice | DeviceMode::kModeFullNetworkData); @@ -2909,7 +2907,7 @@ void MleRouter::HandleDiscoveryRequest(RxInfo &aRxInfo) if (discoveryRequestTlv.IsValid()) { - if (mDiscoveryRequestCallback != nullptr) + if (mDiscoveryRequestCallback.IsSet()) { otThreadDiscoveryRequestInfo info; @@ -2917,7 +2915,7 @@ void MleRouter::HandleDiscoveryRequest(RxInfo &aRxInfo) info.mVersion = discoveryRequestTlv.GetVersion(); info.mIsJoiner = discoveryRequestTlv.IsJoiner(); - mDiscoveryRequestCallback(&info, mDiscoveryRequestCallbackContext); + mDiscoveryRequestCallback.Invoke(&info); } if (discoveryRequestTlv.IsJoiner()) diff --git a/src/core/thread/mle_router.hpp b/src/core/thread/mle_router.hpp index da9e34040..2493368e4 100644 --- a/src/core/thread/mle_router.hpp +++ b/src/core/thread/mle_router.hpp @@ -39,6 +39,7 @@ #include #include "coap/coap_message.hpp" +#include "common/callback.hpp" #include "common/time_ticker.hpp" #include "common/timer.hpp" #include "common/trickle_timer.hpp" @@ -483,8 +484,7 @@ public: */ void SetDiscoveryRequestCallback(otThreadDiscoveryRequestCallback aCallback, void *aContext) { - mDiscoveryRequestCallback = aCallback; - mDiscoveryRequestCallbackContext = aContext; + mDiscoveryRequestCallback.Set(aCallback, aContext); } /** @@ -683,8 +683,7 @@ private: MeshCoP::SteeringData mSteeringData; #endif - otThreadDiscoveryRequestCallback mDiscoveryRequestCallback; - void *mDiscoveryRequestCallbackContext; + Callback mDiscoveryRequestCallback; }; DeclareTmfHandler(MleRouter, kUriAddressSolicit); diff --git a/src/core/thread/mlr_manager.cpp b/src/core/thread/mlr_manager.cpp index 13ec8324e..6a1ff9038 100644 --- a/src/core/thread/mlr_manager.cpp +++ b/src/core/thread/mlr_manager.cpp @@ -51,10 +51,6 @@ RegisterLogModule("MlrManager"); MlrManager::MlrManager(Instance &aInstance) : InstanceLocator(aInstance) -#if (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE) && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE - , mRegisterMulticastListenersCallback(nullptr) - , mRegisterMulticastListenersContext(nullptr) -#endif , mReregistrationDelay(0) , mSendDelay(0) , mMlrPending(false) @@ -343,9 +339,8 @@ Error MlrManager::RegisterMulticastListeners(const otIp6Address SuccessOrExit(error = SendMulticastListenerRegistrationMessage( aAddresses, aAddressNum, aTimeout, &MlrManager::HandleRegisterMulticastListenersResponse, this)); - mRegisterMulticastListenersPending = true; - mRegisterMulticastListenersCallback = aCallback; - mRegisterMulticastListenersContext = aContext; + mRegisterMulticastListenersPending = true; + mRegisterMulticastListenersCallback.Set(aCallback, aContext); exit: return error; @@ -366,24 +361,19 @@ void MlrManager::HandleRegisterMulticastListenersResponse(otMessage *a { OT_UNUSED_VARIABLE(aMessageInfo); - uint8_t status; - Error error; - Ip6::Address failedAddresses[Ip6AddressesTlv::kMaxAddresses]; - uint8_t failedAddressNum = 0; - otIp6RegisterMulticastListenersCallback callback = mRegisterMulticastListenersCallback; - void *context = mRegisterMulticastListenersContext; + uint8_t status; + Error error; + Ip6::Address failedAddresses[Ip6AddressesTlv::kMaxAddresses]; + uint8_t failedAddressNum = 0; + Callback callbackCopy = mRegisterMulticastListenersCallback; - mRegisterMulticastListenersPending = false; - mRegisterMulticastListenersCallback = nullptr; - mRegisterMulticastListenersContext = nullptr; + mRegisterMulticastListenersPending = false; + mRegisterMulticastListenersCallback.Clear(); error = ParseMulticastListenerRegistrationResponse(aResult, AsCoapMessagePtr(aMessage), status, failedAddresses, failedAddressNum); - if (callback != nullptr) - { - callback(context, error, status, failedAddresses, failedAddressNum); - } + callbackCopy.InvokeIfSet(error, status, failedAddresses, failedAddressNum); } #endif // (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE) && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE diff --git a/src/core/thread/mlr_manager.hpp b/src/core/thread/mlr_manager.hpp index 31b192b7e..c2a3d363d 100644 --- a/src/core/thread/mlr_manager.hpp +++ b/src/core/thread/mlr_manager.hpp @@ -44,6 +44,7 @@ #include "backbone_router/bbr_leader.hpp" #include "coap/coap_message.hpp" +#include "common/callback.hpp" #include "common/locator.hpp" #include "common/non_copyable.hpp" #include "common/notifier.hpp" @@ -214,8 +215,7 @@ private: uint8_t aFailedAddressNum); #if (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE) && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE - otIp6RegisterMulticastListenersCallback mRegisterMulticastListenersCallback; - void *mRegisterMulticastListenersContext; + Callback mRegisterMulticastListenersCallback; #endif uint32_t mReregistrationDelay; diff --git a/src/core/thread/network_data_publisher.cpp b/src/core/thread/network_data_publisher.cpp index d46b077cb..566bce702 100644 --- a/src/core/thread/network_data_publisher.cpp +++ b/src/core/thread/network_data_publisher.cpp @@ -58,10 +58,6 @@ Publisher::Publisher(Instance &aInstance) : InstanceLocator(aInstance) #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE , mDnsSrpServiceEntry(aInstance) -#endif -#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE - , mPrefixCallback(nullptr) - , mPrefixCallbackContext(nullptr) #endif , mTimer(aInstance) { @@ -81,12 +77,6 @@ Publisher::Publisher(Instance &aInstance) #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE -void Publisher::SetPrefixCallback(PrefixCallback aCallback, void *aContext) -{ - mPrefixCallback = aCallback; - mPrefixCallbackContext = aContext; -} - Error Publisher::PublishOnMeshPrefix(const OnMeshPrefixConfig &aConfig, Requester aRequester) { Error error = kErrorNone; @@ -223,10 +213,7 @@ bool Publisher::IsAPrefixEntry(const Entry &aEntry) const void Publisher::NotifyPrefixEntryChange(Event aEvent, const Ip6::Prefix &aPrefix) const { - if (mPrefixCallback != nullptr) - { - mPrefixCallback(static_cast(aEvent), &aPrefix, mPrefixCallbackContext); - } + mPrefixCallback.InvokeIfSet(static_cast(aEvent), &aPrefix); } #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE @@ -499,18 +486,7 @@ const char *Publisher::Entry::StateToString(State aState) //--------------------------------------------------------------------------------------------------------------------- // Publisher::DnsSrpServiceEntry -Publisher::DnsSrpServiceEntry::DnsSrpServiceEntry(Instance &aInstance) - : mCallback(nullptr) - , mCallbackContext(nullptr) -{ - Init(aInstance); -} - -void Publisher::DnsSrpServiceEntry::SetCallback(DnsSrpServiceCallback aCallback, void *aContext) -{ - mCallback = aCallback; - mCallbackContext = aContext; -} +Publisher::DnsSrpServiceEntry::DnsSrpServiceEntry(Instance &aInstance) { Init(aInstance); } void Publisher::DnsSrpServiceEntry::PublishAnycast(uint8_t aSequenceNumber) { @@ -649,10 +625,7 @@ void Publisher::DnsSrpServiceEntry::Notify(Event aEvent) const Get().HandleNetDataPublisherEvent(aEvent); #endif - if (mCallback != nullptr) - { - mCallback(static_cast(aEvent), mCallbackContext); - } + mCallback.InvokeIfSet(static_cast(aEvent)); } void Publisher::DnsSrpServiceEntry::Process(void) diff --git a/src/core/thread/network_data_publisher.hpp b/src/core/thread/network_data_publisher.hpp index d377d78e6..bd1dfbef0 100644 --- a/src/core/thread/network_data_publisher.hpp +++ b/src/core/thread/network_data_publisher.hpp @@ -46,6 +46,7 @@ #include #include "border_router/routing_manager.hpp" +#include "common/callback.hpp" #include "common/clearable.hpp" #include "common/equatable.hpp" #include "common/error.hpp" @@ -212,7 +213,7 @@ public: * @param[in] aContext A pointer to application-specific context (used when @p aCallback is invoked). * */ - void SetPrefixCallback(PrefixCallback aCallback, void *aContext); + void SetPrefixCallback(PrefixCallback aCallback, void *aContext) { mPrefixCallback.Set(aCallback, aContext); } /** * This method requests an on-mesh prefix to be published in the Thread Network Data. @@ -346,7 +347,7 @@ private: public: explicit DnsSrpServiceEntry(Instance &aInstance); - void SetCallback(DnsSrpServiceCallback aCallback, void *aContext); + void SetCallback(DnsSrpServiceCallback aCallback, void *aContext) { mCallback.Set(aCallback, aContext); } void PublishAnycast(uint8_t aSequenceNumber); void PublishUnicast(const Ip6::Address &aAddress, uint16_t aPort); void PublishUnicast(uint16_t aPort); @@ -401,9 +402,8 @@ private: void CountAnycastEntries(uint8_t &aNumEntries, uint8_t &aNumPreferredEntries) const; void CountUnicastEntries(uint8_t &aNumEntries, uint8_t &aNumPreferredEntries) const; - Info mInfo; - DnsSrpServiceCallback mCallback; - void *mCallbackContext; + Info mInfo; + Callback mCallback; }; #endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE @@ -485,9 +485,8 @@ private: #endif #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE - PrefixEntry mPrefixEntries[kMaxUserPrefixEntries + kMaxRoutingManagerPrefixEntries]; - PrefixCallback mPrefixCallback; - void *mPrefixCallbackContext; + PrefixEntry mPrefixEntries[kMaxUserPrefixEntries + kMaxRoutingManagerPrefixEntries]; + Callback mPrefixCallback; #endif PublisherTimer mTimer; diff --git a/src/core/thread/network_diagnostic.cpp b/src/core/thread/network_diagnostic.cpp index 232dde0d3..7f8837fb8 100644 --- a/src/core/thread/network_diagnostic.cpp +++ b/src/core/thread/network_diagnostic.cpp @@ -59,8 +59,6 @@ namespace NetworkDiagnostic { NetworkDiagnostic::NetworkDiagnostic(Instance &aInstance) : InstanceLocator(aInstance) - , mReceiveDiagnosticGetCallback(nullptr) - , mReceiveDiagnosticGetCallbackContext(nullptr) { } @@ -74,8 +72,7 @@ Error NetworkDiagnostic::SendDiagnosticGet(const Ip6::Address &aDesti SuccessOrExit(error = SendDiagnosticCommand(kDiagnosticGet, aDestination, aTlvTypes, aCount)); - mReceiveDiagnosticGetCallback = aCallback; - mReceiveDiagnosticGetCallbackContext = aCallbackContext; + mReceiveDiagnosticGetCallback.Set(aCallback, aCallbackContext); LogInfo("Sent diagnostic get"); @@ -155,9 +152,9 @@ void NetworkDiagnostic::HandleDiagnosticGetResponse(Coap::Message *aMes VerifyOrExit(aMessage->GetCode() == Coap::kCodeChanged, aResult = kErrorFailed); exit: - if (mReceiveDiagnosticGetCallback) + if (mReceiveDiagnosticGetCallback.IsSet()) { - mReceiveDiagnosticGetCallback(aResult, aMessage, aMessageInfo, mReceiveDiagnosticGetCallbackContext); + mReceiveDiagnosticGetCallback.Invoke(aResult, aMessage, aMessageInfo); } else { @@ -173,10 +170,7 @@ void NetworkDiagnostic::HandleTmf(Coap::Message LogInfo("Diagnostic get answer received"); - if (mReceiveDiagnosticGetCallback) - { - mReceiveDiagnosticGetCallback(kErrorNone, &aMessage, &aMessageInfo, mReceiveDiagnosticGetCallbackContext); - } + mReceiveDiagnosticGetCallback.InvokeIfSet(kErrorNone, &aMessage, &aMessageInfo); SuccessOrExit(Get().SendEmptyAck(aMessage, aMessageInfo)); diff --git a/src/core/thread/network_diagnostic.hpp b/src/core/thread/network_diagnostic.hpp index ea0fec7d8..2b7fa2d98 100644 --- a/src/core/thread/network_diagnostic.hpp +++ b/src/core/thread/network_diagnostic.hpp @@ -40,6 +40,7 @@ #include +#include "common/callback.hpp" #include "common/locator.hpp" #include "common/non_copyable.hpp" #include "net/udp6.hpp" @@ -163,8 +164,7 @@ private: template void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); - otReceiveDiagnosticGetCallback mReceiveDiagnosticGetCallback; - void *mReceiveDiagnosticGetCallbackContext; + Callback mReceiveDiagnosticGetCallback; }; DeclareTmfHandler(NetworkDiagnostic, kUriDiagnosticGetRequest); diff --git a/src/core/thread/time_sync_service.cpp b/src/core/thread/time_sync_service.cpp index 53bc9b059..9aacfda0d 100644 --- a/src/core/thread/time_sync_service.cpp +++ b/src/core/thread/time_sync_service.cpp @@ -62,8 +62,6 @@ TimeSync::TimeSync(Instance &aInstance) #endif , mLastTimeSyncReceived(0) , mNetworkTimeOffset(0) - , mTimeSyncCallback(nullptr) - , mTimeSyncCallbackContext(nullptr) , mTimer(aInstance) , mCurrentStatus(OT_NETWORK_TIME_UNSYNCHRONIZED) { @@ -140,13 +138,7 @@ void TimeSync::IncrementTimeSyncSeq(void) } } -void TimeSync::NotifyTimeSyncCallback(void) -{ - if (mTimeSyncCallback != nullptr) - { - mTimeSyncCallback(mTimeSyncCallbackContext); - } -} +void TimeSync::NotifyTimeSyncCallback(void) { mTimeSyncCallback.InvokeIfSet(); } #if OPENTHREAD_FTD void TimeSync::ProcessTimeSync(void) diff --git a/src/core/thread/time_sync_service.hpp b/src/core/thread/time_sync_service.hpp index 72fc59cb3..3456ef0a5 100644 --- a/src/core/thread/time_sync_service.hpp +++ b/src/core/thread/time_sync_service.hpp @@ -40,6 +40,7 @@ #include +#include "common/callback.hpp" #include "common/locator.hpp" #include "common/message.hpp" #include "common/non_copyable.hpp" @@ -151,8 +152,7 @@ public: */ void SetTimeSyncCallback(otNetworkTimeSyncCallbackFn aCallback, void *aCallbackContext) { - mTimeSyncCallback = aCallback; - mTimeSyncCallbackContext = aCallbackContext; + mTimeSyncCallback.Set(aCallback, aCallbackContext); } /** @@ -202,11 +202,10 @@ private: #endif TimeMilli mLastTimeSyncReceived; ///< The time when the last time synchronization message was received. int64_t mNetworkTimeOffset; ///< The time offset to the Thread Network time - otNetworkTimeSyncCallbackFn - mTimeSyncCallback; ///< The callback to be called when time sync is handled or status updated. - void *mTimeSyncCallbackContext; ///< The context to be passed to callback. - SyncTimer mTimer; ///< Timer for checking if a resync is required. - otNetworkTimeStatus mCurrentStatus; ///< Current network time status. + + Callback mTimeSyncCallback; ///< Callback when time sync is handled or status updated. + SyncTimer mTimer; ///< Timer for checking if a resync is required. + otNetworkTimeStatus mCurrentStatus; ///< Current network time status. }; /** diff --git a/src/core/utils/jam_detector.cpp b/src/core/utils/jam_detector.cpp index 39590eb30..a628fed6c 100644 --- a/src/core/utils/jam_detector.cpp +++ b/src/core/utils/jam_detector.cpp @@ -49,8 +49,6 @@ RegisterLogModule("JamDetector"); JamDetector::JamDetector(Instance &aInstance) : InstanceLocator(aInstance) - , mHandler(nullptr) - , mContext(nullptr) , mTimer(aInstance) , mHistoryBitmap(0) , mCurSecondStartTime(0) @@ -71,8 +69,7 @@ Error JamDetector::Start(Handler aHandler, void *aContext) VerifyOrExit(!mEnabled, error = kErrorAlready); VerifyOrExit(aHandler != nullptr, error = kErrorInvalidArgs); - mHandler = aHandler; - mContext = aContext; + mCallback.Set(aHandler, aContext); mEnabled = true; LogInfo("Started"); @@ -263,7 +260,7 @@ void JamDetector::SetJamState(bool aNewState) if (shouldInvokeHandler) { - mHandler(mJamState, mContext); + mCallback.Invoke(aNewState); } } diff --git a/src/core/utils/jam_detector.hpp b/src/core/utils/jam_detector.hpp index 5aa3ba51b..084ab7773 100644 --- a/src/core/utils/jam_detector.hpp +++ b/src/core/utils/jam_detector.hpp @@ -40,6 +40,7 @@ #include +#include "common/callback.hpp" #include "common/locator.hpp" #include "common/non_copyable.hpp" #include "common/notifier.hpp" @@ -194,18 +195,17 @@ private: using SampleTimer = TimerMilliIn; - Handler mHandler; // Handler/callback to inform about jamming state - void *mContext; // Context for handler/callback - SampleTimer mTimer; // RSSI sample timer - uint64_t mHistoryBitmap; // History bitmap, each bit correspond to 1 sec interval - TimeMilli mCurSecondStartTime; // Start time for current 1 sec interval - uint16_t mSampleInterval; // Current sample interval - uint8_t mWindow : 6; // Window (in sec) to monitor jamming - uint8_t mBusyPeriod : 6; // BusyPeriod (in sec) with mWindow to alert jamming - bool mEnabled : 1; // If jam detection is enabled - bool mAlwaysAboveThreshold : 1; // State for current 1 sec interval - bool mJamState : 1; // Current jam state - int8_t mRssiThreshold; // RSSI threshold for jam detection + Callback mCallback; // Callback to inform about jamming state + SampleTimer mTimer; // RSSI sample timer + uint64_t mHistoryBitmap; // History bitmap, each bit correspond to 1 sec interval + TimeMilli mCurSecondStartTime; // Start time for current 1 sec interval + uint16_t mSampleInterval; // Current sample interval + uint8_t mWindow : 6; // Window (in sec) to monitor jamming + uint8_t mBusyPeriod : 6; // BusyPeriod (in sec) with mWindow to alert jamming + bool mEnabled : 1; // If jam detection is enabled + bool mAlwaysAboveThreshold : 1; // State for current 1 sec interval + bool mJamState : 1; // Current jam state + int8_t mRssiThreshold; // RSSI threshold for jam detection }; /**