From ec498f0c0e80da56d999f4c8263893bff79d8d8a Mon Sep 17 00:00:00 2001 From: Esko Dijk Date: Mon, 4 May 2026 15:47:05 +0200 Subject: [PATCH] [tcat][ble] introduce notifier events to update TCAT advertisement data / use bool for advertising state (#12913) To get an update of TCAT advertisement data when the active dataset changes, notifier events are introduced. This also refactors the existing adv update on MLE role change to use a notifier event. This update now covers all cases where an application/CLI/user changes the active dataset, which should be then reflected in TCAT advertisement flag values. The 'requested advertising state' is refactored from a BleState to a bool, to make the code more readable and avoid subtle errors. --- src/core/common/notifier.cpp | 7 ++++--- src/core/radio/ble_secure.cpp | 28 ++++++++++++++++++---------- src/core/radio/ble_secure.hpp | 7 ++++++- src/core/thread/mle.cpp | 4 ---- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/core/common/notifier.cpp b/src/core/common/notifier.cpp index 4f5f6e863..dc74cd9ea 100644 --- a/src/core/common/notifier.cpp +++ b/src/core/common/notifier.cpp @@ -140,6 +140,10 @@ void Notifier::EmitEvents(void) #if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_ADMITTER_ENABLE Get().HandleNotifierEvents(events); #endif +#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE + Get().HandleNotifierEvents(events); + Get().HandleNotifierEvents(events); +#endif #if OPENTHREAD_CONFIG_MLR_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE) Get().HandleNotifierEvents(events); #endif @@ -190,9 +194,6 @@ void Notifier::EmitEvents(void) #if OPENTHREAD_CONFIG_LINK_METRICS_MANAGER_ENABLE Get().HandleNotifierEvents(events); #endif -#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE - Get().HandleNotifierEvents(events); -#endif for (ExternalCallback &callback : mExternalCallbacks) { diff --git a/src/core/radio/ble_secure.cpp b/src/core/radio/ble_secure.cpp index 3186f9509..63dc272a8 100644 --- a/src/core/radio/ble_secure.cpp +++ b/src/core/radio/ble_secure.cpp @@ -56,7 +56,7 @@ BleSecure::BleSecure(Instance &aInstance) , mSendMessage(nullptr) , mTransmitTask(aInstance) , mBleState(kStopped) - , mBleAdvRequestedState(kStopped) + , mIsBleAdvRequested(false) , mMtuSize(kInitialMtuSize) { } @@ -86,9 +86,9 @@ Error BleSecure::Start(ConnectCallback aConnectHandler, ReceiveCallback aReceive mTls.SetConnectCallback(HandleTlsConnectEvent, this); // attempt to start BLE advertising only if everything else succeeded. - mBleState = kNotAdvertising; - mBleAdvRequestedState = kAdvertising; - error = SetRequestedBleAdvertisementsState(); + mBleState = kNotAdvertising; + mIsBleAdvRequested = true; + error = SetRequestedBleAdvertisementsState(); exit: if (error != kErrorNone && error != kErrorAlready) @@ -118,9 +118,9 @@ void BleSecure::Stop(void) // Even if stop-advertisements or disable BLE would fail, we continue closing TLS and stopping TCAT agent. IgnoreError(otPlatBleGapAdvStop(&GetInstance())); IgnoreError(otPlatBleDisable(&GetInstance())); - mBleState = kStopped; - mBleAdvRequestedState = kStopped; - mMtuSize = kInitialMtuSize; + mBleState = kStopped; + mIsBleAdvRequested = false; + mMtuSize = kInitialMtuSize; mTls.Close(); Get().Stop(); @@ -214,9 +214,17 @@ exit: return error; } +void BleSecure::HandleNotifierEvents(Events aEvents) +{ + if (aEvents.ContainsAny(kEventActiveDatasetChanged | kEventThreadRoleChanged)) + { + IgnoreError(NotifyAdvertisementChanged()); + } +} + void BleSecure::NotifySendAdvertisements(bool aSendAdvertisements) { - mBleAdvRequestedState = aSendAdvertisements ? kAdvertising : kNotAdvertising; + mIsBleAdvRequested = aSendAdvertisements; IgnoreError(SetRequestedBleAdvertisementsState()); } @@ -227,12 +235,12 @@ Error BleSecure::SetRequestedBleAdvertisementsState(void) Error error = kErrorNone; // Must not make GapAdv platform calls when kStopped, or kConnected. - if (mBleAdvRequestedState == kAdvertising && mBleState == kNotAdvertising) + if (mIsBleAdvRequested && mBleState == kNotAdvertising) { SuccessOrExit(error = otPlatBleGapAdvStart(&GetInstance(), OT_BLE_ADV_INTERVAL_DEFAULT)); mBleState = kAdvertising; } - else if (mBleAdvRequestedState != kAdvertising && mBleState == kAdvertising) + else if (!mIsBleAdvRequested && mBleState == kAdvertising) { SuccessOrExit(error = otPlatBleGapAdvStop(&GetInstance())); mBleState = kNotAdvertising; diff --git a/src/core/radio/ble_secure.hpp b/src/core/radio/ble_secure.hpp index 725a92d43..0d39f3643 100644 --- a/src/core/radio/ble_secure.hpp +++ b/src/core/radio/ble_secure.hpp @@ -35,6 +35,7 @@ #include +#include "common/notifier.hpp" #include "meshcop/meshcop.hpp" #include "meshcop/secure_transport.hpp" #include "meshcop/tcat_agent.hpp" @@ -54,6 +55,8 @@ namespace Ble { class BleSecure : public InstanceLocator, public MeshCoP::Tls::Extension, private NonCopyable { + friend class ot::Notifier; + public: /** * Pointer to call when the secure BLE connection state changes. @@ -356,6 +359,8 @@ private: static constexpr uint16_t kTxBleHandle = 0; // Characteristics Handle for TX (not used) static constexpr uint16_t kTlsDataMaxSize = 800; // Maximum size of data chunks sent with mTls.Send(..) + void HandleNotifierEvents(Events aEvents); + static void HandleTlsConnectEvent(MeshCoP::Tls::ConnectEvent aEvent, void *aContext); void HandleTlsConnectEvent(MeshCoP::Tls::ConnectEvent aEvent); @@ -381,7 +386,7 @@ private: TxTask mTransmitTask; uint8_t mPacketBuffer[kPacketBufferSize]; BleState mBleState; - BleState mBleAdvRequestedState; + bool mIsBleAdvRequested; uint16_t mMtuSize; }; diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 19f1b590f..45f74a0c5 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -319,10 +319,6 @@ void Mle::SetRole(DeviceRole aRole) break; } -#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE - IgnoreError(Get().NotifyAdvertisementChanged()); -#endif - // If the previous state is disabled, the parent can be in kStateRestored. if (!IsChild() && oldRole != kRoleDisabled) {