From 391583869762b44522b6b3557252869f88619af9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arkadiusz=20Ba=C5=82ys?= Date: Thu, 19 Oct 2023 07:59:26 +0200 Subject: [PATCH] [nrfconnect] Add a delay to last fabric remove action (#29844) In some cases, a last fabric removal action should be delayed to avoid race conditions and allow the device to finish all currently running tasks. To control the delay use the CHIP_LAST_FABRIC_REMOVED_ACTION_DELAY kconfig. By default it has been set to 500 ms. --- .../nrfconnect/chip-module/Kconfig.features | 9 +++++ .../nrfconnect/main/include/AppTask.h | 3 -- .../nrfconnect/main/include/AppTask.h | 3 -- .../nrfconnect/main/include/AppTask.h | 3 -- .../nrfconnect/main/include/AppTask.h | 3 -- .../nrfconnect/main/include/AppTask.h | 3 -- .../util/include/FabricTableDelegate.h | 33 ++++++++++++------- .../nrfconnect/main/include/AppTask.h | 3 -- .../nrfconnect/main/include/AppTask.h | 3 -- .../nrfconnect/main/include/AppTask.h | 3 -- 10 files changed, 31 insertions(+), 35 deletions(-) diff --git a/config/nrfconnect/chip-module/Kconfig.features b/config/nrfconnect/chip-module/Kconfig.features index 522b52f8b7fe3d..9b5a1e7aee9029 100644 --- a/config/nrfconnect/chip-module/Kconfig.features +++ b/config/nrfconnect/chip-module/Kconfig.features @@ -267,4 +267,13 @@ choice CHIP_LAST_FABRIC_REMOVED_ACTION endchoice +config CHIP_LAST_FABRIC_REMOVED_ACTION_DELAY + int "After removing the last fabric wait defined time [in milliseconds] to perform an action" + depends on !CHIP_LAST_FABRIC_REMOVED_NONE + default 500 + help + After removing the last fabric the device will wait for the defined time and then perform + an action chosen by the CHIP_LAST_FABRIC_REMOVED_ACTION option. This schedule will allow for + avoiding race conditions before the device removes non-volatile data. + endif # CHIP diff --git a/examples/all-clusters-app/nrfconnect/main/include/AppTask.h b/examples/all-clusters-app/nrfconnect/main/include/AppTask.h index 2bd1956dbcf64e..4db18dba683c0e 100644 --- a/examples/all-clusters-app/nrfconnect/main/include/AppTask.h +++ b/examples/all-clusters-app/nrfconnect/main/include/AppTask.h @@ -34,13 +34,10 @@ struct k_timer; struct Identify; -class AppFabricTableDelegate; class AppTask { public: - friend class AppFabricTableDelegate; - static AppTask & Instance(void) { static AppTask sAppTask; diff --git a/examples/all-clusters-minimal-app/nrfconnect/main/include/AppTask.h b/examples/all-clusters-minimal-app/nrfconnect/main/include/AppTask.h index 7db9b0b4c7b3ad..0d5a9f1f1dc84f 100644 --- a/examples/all-clusters-minimal-app/nrfconnect/main/include/AppTask.h +++ b/examples/all-clusters-minimal-app/nrfconnect/main/include/AppTask.h @@ -34,13 +34,10 @@ struct k_timer; struct Identify; -class AppFabricTableDelegate; class AppTask { public: - friend class AppFabricTableDelegate; - static AppTask & Instance(void) { static AppTask sAppTask; diff --git a/examples/light-switch-app/nrfconnect/main/include/AppTask.h b/examples/light-switch-app/nrfconnect/main/include/AppTask.h index ebff88838b1d82..c4018152e23da5 100644 --- a/examples/light-switch-app/nrfconnect/main/include/AppTask.h +++ b/examples/light-switch-app/nrfconnect/main/include/AppTask.h @@ -37,13 +37,10 @@ struct k_timer; struct Identify; -class AppFabricTableDelegate; class AppTask { public: - friend class AppFabricTableDelegate; - static AppTask & Instance() { static AppTask sAppTask; diff --git a/examples/lighting-app/nrfconnect/main/include/AppTask.h b/examples/lighting-app/nrfconnect/main/include/AppTask.h index 1a26e65eed50da..37be9a0334847c 100644 --- a/examples/lighting-app/nrfconnect/main/include/AppTask.h +++ b/examples/lighting-app/nrfconnect/main/include/AppTask.h @@ -42,13 +42,10 @@ struct k_timer; struct Identify; -class AppFabricTableDelegate; class AppTask { public: - friend class AppFabricTableDelegate; - static AppTask & Instance() { static AppTask sAppTask; diff --git a/examples/lock-app/nrfconnect/main/include/AppTask.h b/examples/lock-app/nrfconnect/main/include/AppTask.h index c65d3f1694c70f..50b4dd4b5b767d 100644 --- a/examples/lock-app/nrfconnect/main/include/AppTask.h +++ b/examples/lock-app/nrfconnect/main/include/AppTask.h @@ -37,13 +37,10 @@ struct k_timer; struct Identify; -class AppFabricTableDelegate; class AppTask { public: - friend class AppFabricTableDelegate; - static AppTask & Instance() { static AppTask sAppTask; diff --git a/examples/platform/nrfconnect/util/include/FabricTableDelegate.h b/examples/platform/nrfconnect/util/include/FabricTableDelegate.h index 01b5e40be86d16..fa9e6f0c828ad6 100644 --- a/examples/platform/nrfconnect/util/include/FabricTableDelegate.h +++ b/examples/platform/nrfconnect/util/include/FabricTableDelegate.h @@ -18,8 +18,6 @@ #pragma once -#include "AppTask.h" - #include #include #ifdef CONFIG_CHIP_WIFI @@ -42,36 +40,49 @@ class AppFabricTableDelegate : public chip::FabricTable::Delegate #ifndef CONFIG_CHIP_LAST_FABRIC_REMOVED_NONE static AppFabricTableDelegate sAppFabricDelegate; chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(&sAppFabricDelegate); + k_timer_init(&sFabricRemovedTimer, &OnFabricRemovedTimerCallback, nullptr); #endif // CONFIG_CHIP_LAST_FABRIC_REMOVED_NONE } private: void OnFabricRemoved(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex) + { + k_timer_start(&sFabricRemovedTimer, K_MSEC(CONFIG_CHIP_LAST_FABRIC_REMOVED_ACTION_DELAY), K_NO_WAIT); + } + + static void OnFabricRemovedTimerCallback(k_timer * timer) { #ifndef CONFIG_CHIP_LAST_FABRIC_REMOVED_NONE if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) { + chip::DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t) { #ifdef CONFIG_CHIP_LAST_FABRIC_REMOVED_ERASE_AND_REBOOT - chip::Server::GetInstance().ScheduleFactoryReset(); + chip::Server::GetInstance().ScheduleFactoryReset(); #elif defined(CONFIG_CHIP_LAST_FABRIC_REMOVED_ERASE_ONLY) || defined(CONFIG_CHIP_LAST_FABRIC_REMOVED_ERASE_AND_PAIRING_START) - chip::DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t) { - /* Erase Matter data */ + // Erase Matter data chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().DoFactoryReset(); - /* Erase Network credentials and disconnect */ + // Erase Network credentials and disconnect chip::DeviceLayer::ConnectivityMgr().ErasePersistentInfo(); #ifdef CONFIG_CHIP_WIFI chip::DeviceLayer::WiFiManager::Instance().Disconnect(); chip::DeviceLayer::ConnectivityMgr().ClearWiFiStationProvision(); #endif #ifdef CONFIG_CHIP_LAST_FABRIC_REMOVED_ERASE_AND_PAIRING_START - /* Start the New BLE advertising */ - AppEvent event; - event.Handler = AppTask::StartBLEAdvertisementHandler; - AppTask::Instance().PostEvent(event); + // Start the New BLE advertising + if (!chip::DeviceLayer::ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + if (CHIP_NO_ERROR == chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow()) + { + return; + } + } + ChipLogError(FabricProvisioning, "Could not start Bluetooth LE advertising"); #endif // CONFIG_CHIP_LAST_FABRIC_REMOVED_ERASE_AND_PAIRING_START - }); #endif // CONFIG_CHIP_LAST_FABRIC_REMOVED_ERASE_AND_REBOOT + }); } #endif // CONFIG_CHIP_LAST_FABRIC_REMOVED_NONE } + + inline static k_timer sFabricRemovedTimer; }; diff --git a/examples/pump-app/nrfconnect/main/include/AppTask.h b/examples/pump-app/nrfconnect/main/include/AppTask.h index e36bedd01b0efb..fb2fe2c855cb1a 100644 --- a/examples/pump-app/nrfconnect/main/include/AppTask.h +++ b/examples/pump-app/nrfconnect/main/include/AppTask.h @@ -36,13 +36,10 @@ #endif struct k_timer; -class AppFabricTableDelegate; class AppTask { public: - friend class AppFabricTableDelegate; - static AppTask & Instance(void) { static AppTask sAppTask; diff --git a/examples/pump-controller-app/nrfconnect/main/include/AppTask.h b/examples/pump-controller-app/nrfconnect/main/include/AppTask.h index d0c670785c2a9a..8ca4a69e91c0f0 100644 --- a/examples/pump-controller-app/nrfconnect/main/include/AppTask.h +++ b/examples/pump-controller-app/nrfconnect/main/include/AppTask.h @@ -36,13 +36,10 @@ #endif struct k_timer; -class AppFabricTableDelegate; class AppTask { public: - friend class AppFabricTableDelegate; - static AppTask & Instance(void) { static AppTask sAppTask; diff --git a/examples/window-app/nrfconnect/main/include/AppTask.h b/examples/window-app/nrfconnect/main/include/AppTask.h index b9f78d244d1cd5..fdd94d0c61e416 100644 --- a/examples/window-app/nrfconnect/main/include/AppTask.h +++ b/examples/window-app/nrfconnect/main/include/AppTask.h @@ -34,13 +34,10 @@ struct k_timer; struct Identify; -class AppFabricTableDelegate; class AppTask { public: - friend class AppFabricTableDelegate; - static AppTask & Instance(void) { static AppTask sAppTask;