From d22e9cb737de7f49593e9f2506cfb3264728a2ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arkadiusz=20Ba=C5=82ys?= Date: Thu, 5 Oct 2023 10:35:35 +0200 Subject: [PATCH] [nrfconnect] Added erasing network credentials after last fabric removal (#29448) Users can decide now what should happen after removing the last fabric: - Do nothing. - Erase the saved network credentials (Thread/WI-FI). - Erase the saved network credentials and start Bluetooth LE advertising. - Erase the saved network credentials and reboot the device. --- .../nrfconnect/chip-module/Kconfig.defaults | 2 +- .../nrfconnect/chip-module/Kconfig.features | 37 +++++++++ .../nrfconnect/main/AppTask.cpp | 2 + .../nrfconnect/main/include/AppTask.h | 3 + .../nrfconnect/main/AppTask.cpp | 2 + .../nrfconnect/main/include/AppTask.h | 3 + .../nrfconnect/main/AppTask.cpp | 2 + .../nrfconnect/main/include/AppTask.h | 3 + .../lighting-app/nrfconnect/main/AppTask.cpp | 2 + .../nrfconnect/main/include/AppTask.h | 3 + examples/lock-app/nrfconnect/main/AppTask.cpp | 2 + .../nrfconnect/main/include/AppTask.h | 5 +- .../util/include/FabricTableDelegate.h | 77 +++++++++++++++++++ examples/pump-app/nrfconnect/main/AppTask.cpp | 2 + .../nrfconnect/main/include/AppTask.h | 3 + .../nrfconnect/main/AppTask.cpp | 2 + .../nrfconnect/main/include/AppTask.h | 3 + .../window-app/nrfconnect/main/AppTask.cpp | 2 + .../nrfconnect/main/include/AppTask.h | 3 + 19 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 examples/platform/nrfconnect/util/include/FabricTableDelegate.h diff --git a/config/nrfconnect/chip-module/Kconfig.defaults b/config/nrfconnect/chip-module/Kconfig.defaults index d275d938021c63..30611686b1e41a 100644 --- a/config/nrfconnect/chip-module/Kconfig.defaults +++ b/config/nrfconnect/chip-module/Kconfig.defaults @@ -194,7 +194,7 @@ endif # BOARD_NRF7002DK_NRF5340_CPUAPP # Enable extended discovery config CHIP_EXTENDED_DISCOVERY - default y + default n config NVS_LOOKUP_CACHE default y diff --git a/config/nrfconnect/chip-module/Kconfig.features b/config/nrfconnect/chip-module/Kconfig.features index 6486d19506bab9..522b52f8b7fe3d 100644 --- a/config/nrfconnect/chip-module/Kconfig.features +++ b/config/nrfconnect/chip-module/Kconfig.features @@ -230,4 +230,41 @@ config CHIP_WIFI_CONNECTION_RECOVERY_JITTER a random jitter interval is added to it to avoid periodicity. The random jitter is selected within range [-JITTER; +JITTER]. +choice CHIP_LAST_FABRIC_REMOVED_ACTION + prompt "An action to perform after removing the last fabric" + default CHIP_LAST_FABRIC_REMOVED_ERASE_AND_REBOOT + + config CHIP_LAST_FABRIC_REMOVED_NONE + bool "After removing the last fabric do not perform any action" + help + After removing the last fabric the device will not perform factory reset + or reboot. The current state will be left as it is and the BLE advertising + will not start automatically. + + config CHIP_LAST_FABRIC_REMOVED_ERASE_AND_REBOOT + bool "After removing the last fabric erase NVS and reboot" + help + After removing the last fabric the device will perform the factory reset and + then reboot. The current RAM state will be removed and the new commissioning to + the new fabric will use the initial fabric index. This option is the most safe. + + config CHIP_LAST_FABRIC_REMOVED_ERASE_AND_PAIRING_START + bool "After removing the last fabric erase NVS and start Bluetooth LE advertising" + help + After removing the last fabric the device will perform the factory reset without + rebooting and start the Bluetooth LE advertisement automatically. + The current RAM state will be saved and the new commissioning to the next + fabric will use the next possible fabric index. This option should not be used for + devices that normally do not advertise Bluetooth LE on boot to keep their original + behavior. + + config CHIP_LAST_FABRIC_REMOVED_ERASE_ONLY + bool "After removing the last fabric erase NVS only" + help + After removing the last fabric the device will perform the factory reset only without + rebooting. The current RAM state will be saved and the new commissioning to the next + fabric will use the next possible fabric index. + +endchoice + endif # CHIP diff --git a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp index 217748c218519f..9f471943406c80 100644 --- a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp +++ b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp @@ -18,6 +18,7 @@ #include "AppTask.h" #include "AppConfig.h" #include "AppEvent.h" +#include "FabricTableDelegate.h" #include "LEDUtil.h" #include "binding-handler.h" @@ -207,6 +208,7 @@ CHIP_ERROR AppTask::Init() (void) initParams.InitializeStaticResourcesBeforeServerInit(); initParams.testEventTriggerDelegate = &testEventTriggerDelegate; ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); + AppFabricTableDelegate::Init(); gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); diff --git a/examples/all-clusters-app/nrfconnect/main/include/AppTask.h b/examples/all-clusters-app/nrfconnect/main/include/AppTask.h index 4db18dba683c0e..2bd1956dbcf64e 100644 --- a/examples/all-clusters-app/nrfconnect/main/include/AppTask.h +++ b/examples/all-clusters-app/nrfconnect/main/include/AppTask.h @@ -34,10 +34,13 @@ 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/AppTask.cpp b/examples/all-clusters-minimal-app/nrfconnect/main/AppTask.cpp index 6ec81dfd5c363b..02f0704f080a58 100644 --- a/examples/all-clusters-minimal-app/nrfconnect/main/AppTask.cpp +++ b/examples/all-clusters-minimal-app/nrfconnect/main/AppTask.cpp @@ -18,6 +18,7 @@ #include "AppTask.h" #include "AppConfig.h" #include "AppEvent.h" +#include "FabricTableDelegate.h" #include "LEDUtil.h" #include "binding-handler.h" @@ -156,6 +157,7 @@ CHIP_ERROR AppTask::Init() static chip::CommonCaseDeviceServerInitParams initParams; (void) initParams.InitializeStaticResourcesBeforeServerInit(); ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); + AppFabricTableDelegate::Init(); // We only have network commissioning on endpoint 0. emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false); 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 0d5a9f1f1dc84f..7db9b0b4c7b3ad 100644 --- a/examples/all-clusters-minimal-app/nrfconnect/main/include/AppTask.h +++ b/examples/all-clusters-minimal-app/nrfconnect/main/include/AppTask.h @@ -34,10 +34,13 @@ 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/AppTask.cpp b/examples/light-switch-app/nrfconnect/main/AppTask.cpp index 2716458175b20c..a4b5ac5b47b318 100644 --- a/examples/light-switch-app/nrfconnect/main/AppTask.cpp +++ b/examples/light-switch-app/nrfconnect/main/AppTask.cpp @@ -19,6 +19,7 @@ #include "AppTask.h" #include "AppConfig.h" #include "BoardUtil.h" +#include "FabricTableDelegate.h" #include "LEDUtil.h" #include "LightSwitch.h" @@ -218,6 +219,7 @@ CHIP_ERROR AppTask::Init() (void) initParams.InitializeStaticResourcesBeforeServerInit(); initParams.testEventTriggerDelegate = &testEventTriggerDelegate; ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); + AppFabricTableDelegate::Init(); gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); diff --git a/examples/light-switch-app/nrfconnect/main/include/AppTask.h b/examples/light-switch-app/nrfconnect/main/include/AppTask.h index c4018152e23da5..ebff88838b1d82 100644 --- a/examples/light-switch-app/nrfconnect/main/include/AppTask.h +++ b/examples/light-switch-app/nrfconnect/main/include/AppTask.h @@ -37,10 +37,13 @@ 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/AppTask.cpp b/examples/lighting-app/nrfconnect/main/AppTask.cpp index 9a2b6a71e7fa80..03632106fc8667 100644 --- a/examples/lighting-app/nrfconnect/main/AppTask.cpp +++ b/examples/lighting-app/nrfconnect/main/AppTask.cpp @@ -20,6 +20,7 @@ #include "AppConfig.h" #include "AppEvent.h" +#include "FabricTableDelegate.h" #include "LEDUtil.h" #include "PWMDevice.h" @@ -246,6 +247,7 @@ CHIP_ERROR AppTask::Init() (void) initParams.InitializeStaticResourcesBeforeServerInit(); initParams.testEventTriggerDelegate = &testEventTriggerDelegate; ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); + AppFabricTableDelegate::Init(); gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); diff --git a/examples/lighting-app/nrfconnect/main/include/AppTask.h b/examples/lighting-app/nrfconnect/main/include/AppTask.h index 37be9a0334847c..1a26e65eed50da 100644 --- a/examples/lighting-app/nrfconnect/main/include/AppTask.h +++ b/examples/lighting-app/nrfconnect/main/include/AppTask.h @@ -42,10 +42,13 @@ 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/AppTask.cpp b/examples/lock-app/nrfconnect/main/AppTask.cpp index 4eecd0b6702c76..d64a4950ace777 100644 --- a/examples/lock-app/nrfconnect/main/AppTask.cpp +++ b/examples/lock-app/nrfconnect/main/AppTask.cpp @@ -19,6 +19,7 @@ #include "AppTask.h" #include "AppConfig.h" #include "BoltLockManager.h" +#include "FabricTableDelegate.h" #include "LEDUtil.h" #include "LEDWidget.h" @@ -212,6 +213,7 @@ CHIP_ERROR AppTask::Init() (void) initParams.InitializeStaticResourcesBeforeServerInit(); initParams.testEventTriggerDelegate = &testEventTriggerDelegate; ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); + AppFabricTableDelegate::Init(); gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); diff --git a/examples/lock-app/nrfconnect/main/include/AppTask.h b/examples/lock-app/nrfconnect/main/include/AppTask.h index a0a50da9ed23db..c65d3f1694c70f 100644 --- a/examples/lock-app/nrfconnect/main/include/AppTask.h +++ b/examples/lock-app/nrfconnect/main/include/AppTask.h @@ -37,10 +37,13 @@ struct k_timer; struct Identify; +class AppFabricTableDelegate; class AppTask { public: + friend class AppFabricTableDelegate; + static AppTask & Instance() { static AppTask sAppTask; @@ -67,8 +70,8 @@ class AppTask static void FunctionHandler(const AppEvent & event); static void StartBLEAdvertisementAndLockActionEventHandler(const AppEvent & event); static void LockActionEventHandler(const AppEvent & event); - static void StartBLEAdvertisementHandler(const AppEvent & event); static void UpdateLedStateEventHandler(const AppEvent & event); + static void StartBLEAdvertisementHandler(const AppEvent & event); static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); static void ButtonEventHandler(uint32_t buttonState, uint32_t hasChanged); diff --git a/examples/platform/nrfconnect/util/include/FabricTableDelegate.h b/examples/platform/nrfconnect/util/include/FabricTableDelegate.h new file mode 100644 index 00000000000000..01b5e40be86d16 --- /dev/null +++ b/examples/platform/nrfconnect/util/include/FabricTableDelegate.h @@ -0,0 +1,77 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "AppTask.h" + +#include +#include +#ifdef CONFIG_CHIP_WIFI +#include +#endif + +class AppFabricTableDelegate : public chip::FabricTable::Delegate +{ +public: + ~AppFabricTableDelegate() { chip::Server::GetInstance().GetFabricTable().RemoveFabricDelegate(this); } + + /** + * @brief Initialize module and add a delegation to the Fabric Table. + * + * To use the OnFabricRemoved method defined within this class and allow to react on the last fabric removal + * this method should be called in the application code. + */ + static void Init() + { +#ifndef CONFIG_CHIP_LAST_FABRIC_REMOVED_NONE + static AppFabricTableDelegate sAppFabricDelegate; + chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(&sAppFabricDelegate); +#endif // CONFIG_CHIP_LAST_FABRIC_REMOVED_NONE + } + +private: + void OnFabricRemoved(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex) + { +#ifndef CONFIG_CHIP_LAST_FABRIC_REMOVED_NONE + if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) + { +#ifdef CONFIG_CHIP_LAST_FABRIC_REMOVED_ERASE_AND_REBOOT + 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 */ + chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().DoFactoryReset(); + /* 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); +#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 + } +}; diff --git a/examples/pump-app/nrfconnect/main/AppTask.cpp b/examples/pump-app/nrfconnect/main/AppTask.cpp index f1d9dd6b7f358b..fa38eba254853a 100644 --- a/examples/pump-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-app/nrfconnect/main/AppTask.cpp @@ -18,6 +18,7 @@ #include "AppTask.h" #include "AppConfig.h" +#include "FabricTableDelegate.h" #include "LEDUtil.h" #include "LEDWidget.h" #include "PumpManager.h" @@ -189,6 +190,7 @@ CHIP_ERROR AppTask::Init() (void) initParams.InitializeStaticResourcesBeforeServerInit(); initParams.testEventTriggerDelegate = &testEventTriggerDelegate; ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); + AppFabricTableDelegate::Init(); gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); diff --git a/examples/pump-app/nrfconnect/main/include/AppTask.h b/examples/pump-app/nrfconnect/main/include/AppTask.h index fb2fe2c855cb1a..e36bedd01b0efb 100644 --- a/examples/pump-app/nrfconnect/main/include/AppTask.h +++ b/examples/pump-app/nrfconnect/main/include/AppTask.h @@ -36,10 +36,13 @@ #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/AppTask.cpp b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp index 07d85d9f2b330b..db96480e5acb9d 100644 --- a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp @@ -18,6 +18,7 @@ #include "AppTask.h" #include "AppConfig.h" +#include "FabricTableDelegate.h" #include "LEDUtil.h" #include "LEDWidget.h" #include "PumpManager.h" @@ -187,6 +188,7 @@ CHIP_ERROR AppTask::Init() (void) initParams.InitializeStaticResourcesBeforeServerInit(); initParams.testEventTriggerDelegate = &testEventTriggerDelegate; ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); + AppFabricTableDelegate::Init(); gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); diff --git a/examples/pump-controller-app/nrfconnect/main/include/AppTask.h b/examples/pump-controller-app/nrfconnect/main/include/AppTask.h index 8ca4a69e91c0f0..d0c670785c2a9a 100644 --- a/examples/pump-controller-app/nrfconnect/main/include/AppTask.h +++ b/examples/pump-controller-app/nrfconnect/main/include/AppTask.h @@ -36,10 +36,13 @@ #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/AppTask.cpp b/examples/window-app/nrfconnect/main/AppTask.cpp index cda4c0c9e318b8..f607114da6d031 100644 --- a/examples/window-app/nrfconnect/main/AppTask.cpp +++ b/examples/window-app/nrfconnect/main/AppTask.cpp @@ -18,6 +18,7 @@ #include "AppTask.h" #include "AppConfig.h" #include "AppEvent.h" +#include "FabricTableDelegate.h" #include "LEDUtil.h" #include "WindowCovering.h" @@ -191,6 +192,7 @@ CHIP_ERROR AppTask::Init() (void) initParams.InitializeStaticResourcesBeforeServerInit(); initParams.testEventTriggerDelegate = &testEventTriggerDelegate; ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); + AppFabricTableDelegate::Init(); gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); diff --git a/examples/window-app/nrfconnect/main/include/AppTask.h b/examples/window-app/nrfconnect/main/include/AppTask.h index fdd94d0c61e416..b9f78d244d1cd5 100644 --- a/examples/window-app/nrfconnect/main/include/AppTask.h +++ b/examples/window-app/nrfconnect/main/include/AppTask.h @@ -34,10 +34,13 @@ struct k_timer; struct Identify; +class AppFabricTableDelegate; class AppTask { public: + friend class AppFabricTableDelegate; + static AppTask & Instance(void) { static AppTask sAppTask;