From 0cde52b76d36ebb146e9f161248b144ed79a5f3d Mon Sep 17 00:00:00 2001 From: Louis-Philip Beliveau Date: Wed, 3 Jul 2024 14:47:44 +0000 Subject: [PATCH 1/4] Updated Silabs ThreadStackManagerImpl for the Simplicity_sdk changes, added a helper in GenericThreadStackManagerImpl_OpenThread.hpp to avoid code repetition Fixes for memory allocation initialization added since, unlike in SLC, here we use MBEDTLS_CONFIG_FILE="efr32-chip-mbedtls-config.h" --- examples/platform/silabs/BaseApplication.cpp | 79 +++++++++- examples/platform/silabs/BaseApplication.h | 25 +++- examples/platform/silabs/MatterConfig.cpp | 15 +- examples/platform/silabs/efr32/uart.cpp | 6 + examples/platform/silabs/matter-platform.slcp | 7 + ...GenericThreadStackManagerImpl_OpenThread.h | 1 + ...nericThreadStackManagerImpl_OpenThread.hpp | 61 +++++--- src/platform/silabs/ThreadStackManagerImpl.h | 26 +++- .../silabs/ThreadStackManagerImpl_CMSIS.h | 97 ++++++++++++ .../silabs/efr32/ThreadStackManagerImpl.cpp | 140 +++++++++++++----- .../efr32/ThreadStackManagerImpl_CMSIS.hpp | 138 +++++++++++++++++ .../silabs/platformAbstraction/GsdkSpam.cpp | 4 - .../openthread/platforms/efr32/BUILD.gn | 4 +- third_party/silabs/efr32_sdk.gni | 40 ++++- third_party/silabs/lwip.gni | 3 + 15 files changed, 556 insertions(+), 90 deletions(-) create mode 100644 src/platform/silabs/ThreadStackManagerImpl_CMSIS.h create mode 100644 src/platform/silabs/efr32/ThreadStackManagerImpl_CMSIS.hpp diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index fd22a7ea3a48fc..1454bd09ca1d26 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -115,9 +115,10 @@ app::Clusters::NetworkCommissioning::Instance sWiFiNetworkCommissioningInstance(0 /* Endpoint Id */, &(NetworkCommissioning::SlWiFiDriver::GetInstance())); #endif /* SL_WIFI */ -#if !(defined(CHIP_CONFIG_ENABLE_ICD_SERVER) && CHIP_CONFIG_ENABLE_ICD_SERVER) bool sIsEnabled = false; bool sIsAttached = false; + +#if !(defined(CHIP_CONFIG_ENABLE_ICD_SERVER) && CHIP_CONFIG_ENABLE_ICD_SERVER) bool sHaveBLEConnections = false; #endif // CHIP_CONFIG_ENABLE_ICD_SERVER @@ -156,14 +157,13 @@ Identify gIdentify = { }; #endif // MATTER_DM_PLUGIN_IDENTIFY_SERVER + } // namespace bool BaseApplication::sIsProvisioned = false; bool BaseApplication::sIsFactoryResetTriggered = false; LEDWidget * BaseApplication::sAppActionLed = nullptr; -#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 BaseApplicationDelegate BaseApplication::sAppDelegate = BaseApplicationDelegate(); -#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 #ifdef DIC_ENABLE namespace { @@ -181,17 +181,19 @@ void AppSpecificConnectivityEventCallback(const ChipDeviceEvent * event, intptr_ } // namespace #endif // DIC_ENABLE -#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 void BaseApplicationDelegate::OnCommissioningSessionStarted() { isComissioningStarted = true; } + void BaseApplicationDelegate::OnCommissioningSessionStopped() { isComissioningStarted = false; } + void BaseApplicationDelegate::OnCommissioningWindowClosed() { +#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 if (!BaseApplication::GetProvisionStatus() && !isComissioningStarted) { int32_t status = wfx_power_save(RSI_SLEEP_MODE_8, STANDBY_POWER_SAVE_WITH_RAM_RETENTION); @@ -200,8 +202,27 @@ void BaseApplicationDelegate::OnCommissioningWindowClosed() ChipLogError(DeviceLayer, "Failed to enable the TA Deep Sleep"); } } +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917qq +} + +void BaseApplicationDelegate::OnFabricCommitted(const FabricTable & fabricTable, FabricIndex fabricIndex) +{ + // If we commissioned our first fabric, Update the commissioned status of the App + if (fabricTable.FabricCount() == 1) + { + BaseApplication::UpdateCommissioningStatus(true); + } +} + +void BaseApplicationDelegate::OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) +{ + if (fabricTable.FabricCount() == 0) + { + BaseApplication::UpdateCommissioningStatus(false); + + BaseApplication::DoProvisioningReset(); + } } -#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 /********************************************************** * AppTask Definitions @@ -298,6 +319,8 @@ CHIP_ERROR BaseApplication::Init() #if CHIP_ENABLE_OPENTHREAD BaseApplication::sIsProvisioned = ConnectivityMgr().IsThreadProvisioned(); #endif + + err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(&sAppDelegate); return err; } @@ -411,6 +434,23 @@ bool BaseApplication::ActivateStatusLedPatterns() return isPatternSet; } +void BaseApplication::UpdateCommissioningStatus(bool newState) +{ +#ifdef SL_WIFI + BaseApplication::sIsProvisioned = ConnectivityMgr().IsWiFiStationProvisioned(); + sIsEnabled = ConnectivityMgr().IsWiFiStationEnabled(); + sIsAttached = ConnectivityMgr().IsWiFiStationConnected(); +#endif /* SL_WIFI */ +#if CHIP_ENABLE_OPENTHREAD + // TODO: This is a temporary solution until we can read Thread provisioning status from RAM instead of NVM. + BaseApplication::sIsProvisioned = newState; + sIsEnabled = ConnectivityMgr().IsThreadEnabled(); + sIsAttached = ConnectivityMgr().IsThreadAttached(); +#endif /* CHIP_ENABLE_OPENTHREAD */ + + ActivateStatusLedPatterns(); +} + // TODO Move State Monitoring elsewhere void BaseApplication::LightEventHandler() { @@ -750,15 +790,42 @@ void BaseApplication::ScheduleFactoryReset() { Provision::Manager::GetInstance().SetProvisionRequired(true); } - PlatformMgr().HandleServerShuttingDown(); + PlatformMgr().HandleServerShuttingDown(); // HandleServerShuttingDown calls OnShutdown() which is only implemented for the basic information cluster it seems. And triggers and Event flush, which is not relevant when there are no fabrics left ConfigurationMgr().InitiateFactoryReset(); }); } +void BaseApplication::DoProvisioningReset() +{ + PlatformMgr().ScheduleWork([](intptr_t) { +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + ThreadStackMgr().ClearAllSrpHostAndServices(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + ChipLogProgress(DeviceLayer, "Clearing Thread provision"); + chip::DeviceLayer::ConnectivityMgr().ErasePersistentInfo(); + ThreadStackMgrImpl().FactoryResetThreadStack(); + ThreadStackMgr().InitThreadStack(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + ChipLogProgress(DeviceLayer, "Clearing WiFi provision"); + chip::DeviceLayer::ConnectivityMgr().ClearWiFiStationProvision(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + + CHIP_ERROR err = Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow(); + if (err != CHIP_NO_ERROR) + { + SILABS_LOG("Failed to open the Basic Commissioning Window"); + } + }); +} + void BaseApplication::OnPlatformEvent(const ChipDeviceEvent * event, intptr_t) { if (event->Type == DeviceEventType::kServiceProvisioningChange) { + // Note: This is only called on Attach, we need to add a method to detect Thread Network Detach BaseApplication::sIsProvisioned = event->ServiceProvisioningChange.IsServiceProvisioned; } } diff --git a/examples/platform/silabs/BaseApplication.h b/examples/platform/silabs/BaseApplication.h index 8a231aa6c51513..cfef5f945a382f 100644 --- a/examples/platform/silabs/BaseApplication.h +++ b/examples/platform/silabs/BaseApplication.h @@ -35,6 +35,7 @@ #include #include #include +#include #include "LEDWidget.h" @@ -62,16 +63,20 @@ #define APP_ERROR_START_TIMER_FAILED CHIP_APPLICATION_ERROR(0x05) #define APP_ERROR_STOP_TIMER_FAILED CHIP_APPLICATION_ERROR(0x06) -#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 -class BaseApplicationDelegate : public AppDelegate +class BaseApplicationDelegate : public AppDelegate, + public chip::FabricTable::Delegate { private: + // AppDelegate bool isComissioningStarted; void OnCommissioningSessionStarted() override; void OnCommissioningSessionStopped() override; void OnCommissioningWindowClosed() override; + + // FabricTable::Delegate + void OnFabricCommitted(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex) override; + void OnFabricRemoved(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex) override; }; -#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 /********************************************************** * BaseApplication Declaration @@ -86,9 +91,7 @@ class BaseApplication static bool sIsProvisioned; static bool sIsFactoryResetTriggered; static LEDWidget * sAppActionLed; -#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 static BaseApplicationDelegate sAppDelegate; -#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 /** * @brief Create AppTask task and Event Queue @@ -156,6 +159,18 @@ class BaseApplication static void OnTriggerIdentifyEffect(Identify * identify); #endif + /** + * @brief Updates the static boolean isCommissioned to the desired state + * + */ + static void UpdateCommissioningStatus(bool newState); + + /** + * @brief Called when the last Fabric is removed, clears all Fabric related data and Thread Wifi provision. + * @note This function preserves some NVM3 data that is not Fabric scoped like Attribute Value or Boot Count. + */ + static void DoProvisioningReset(); + protected: CHIP_ERROR Init(); diff --git a/examples/platform/silabs/MatterConfig.cpp b/examples/platform/silabs/MatterConfig.cpp index 0f25e2e25a40ed..1aabd29bb75ab6 100644 --- a/examples/platform/silabs/MatterConfig.cpp +++ b/examples/platform/silabs/MatterConfig.cpp @@ -222,9 +222,12 @@ void SilabsMatterConfig::ConnectivityEventCallback(const ChipDeviceEvent * event CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) { CHIP_ERROR err; - +#ifdef SL_WIFI + // Because OpenThread needs to use memory allocation during its Key operations, we initialize the memory management for thread + // and set the allocation functions inside sl_ot_create_instance, which is called by sl_system_init in the OpenThread stack + // initialization. mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree); - +#endif SILABS_LOG("=================================================="); SILABS_LOG("%s starting", appName); SILABS_LOG("=================================================="); @@ -241,11 +244,11 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) // Init Matter Stack //============================================== SILABS_LOG("Init CHIP Stack"); - // Init Chip memory management before the stack - ReturnErrorOnFailure(chip::Platform::MemoryInit()); -// WiFi needs to be initialized after Memory Init for some reason #ifdef SL_WIFI + // Init Chip memory management before the stack + // See comment above about OpenThread memory allocation as to why this is WIFI only here. + ReturnErrorOnFailure(chip::Platform::MemoryInit()); ReturnErrorOnFailure(InitWiFi()); #endif @@ -304,9 +307,7 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) initParams.endpointNativeParams = static_cast(&nativeParams); #endif -#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 initParams.appDelegate = &BaseApplication::sAppDelegate; -#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 // Init Matter Server and Start Event Loop err = chip::Server::GetInstance().Init(initParams); diff --git a/examples/platform/silabs/efr32/uart.cpp b/examples/platform/silabs/efr32/uart.cpp index 5feaaa66d86923..80d2dbba63b3a8 100644 --- a/examples/platform/silabs/efr32/uart.cpp +++ b/examples/platform/silabs/efr32/uart.cpp @@ -361,6 +361,12 @@ int16_t uartConsoleWrite(const char * Buf, uint16_t BufLength) return UART_CONSOLE_ERR; } + if (NULL == sUartTxQueue) + { + // This is to prevent the first prompt from OTCLI to be rejected and to break the OTCli output + uartConsoleInit(); + } + #ifdef PW_RPC_ENABLED // Pigweed Logger is already thread safe. UARTDRV_ForceTransmit(vcom_handle, (uint8_t *) Buf, BufLength); diff --git a/examples/platform/silabs/matter-platform.slcp b/examples/platform/silabs/matter-platform.slcp index c8075656e9f74d..bfde28d9f721f9 100644 --- a/examples/platform/silabs/matter-platform.slcp +++ b/examples/platform/silabs/matter-platform.slcp @@ -72,6 +72,9 @@ component: - {id: mbedtls_platform_dynamic_memory_allocation_config_init_runtime } - {id: mbedtls_base64} - {id: ot_psa_crypto} +- {id: ot_platform_abstraction} +- {id: ot_rtos_wrappers_real} +- {id: sl_ot_custom_cli} # Necessary componenets for ot coap cert lib # - {id: mbedtls_dtls} # Requried by COAP lib # - {id: mbedtls_tls_server} # Requried by COAP lib @@ -86,6 +89,10 @@ config_file: directory: btconf configuration: +- name: SL_OPENTHREAD_ENABLE_APP_TASK + value: 0 +- name: SL_OPENTHREAD_ENABLE_CLI_TASK + value: 0 - {name: SL_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED, value: '0'} - {name: SL_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED, value: '1'} - condition: [uartdrv_usart] diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h index 317bff7c05403e..c45ff84bb0f26e 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h @@ -142,6 +142,7 @@ class GenericThreadStackManagerImpl_OpenThread // ===== Members available to the implementation subclass. + CHIP_ERROR ConfigureThreadStack(otInstance * otInst); CHIP_ERROR DoInit(otInstance * otInst); bool IsThreadAttachedNoLock(void); bool IsThreadInterfaceUpNoLock(void); diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp index 876cb54385efe6..77f7293d7a43bd 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp @@ -1088,29 +1088,21 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_GetPollPeriod(u return CHIP_NO_ERROR; } +/** + * @brief Helper that sets callbacks for OpenThread state changes and configures the Thread stack. + * Assigns mOTInst to and instance and configures the OT stack on a device by setting state change callbacks enabling features + * for IPv6 address configuration, enabling the Thread network if necessary, and handling SRP if enabled. + * Allows for the configuration of the Thread stack on a device where the instance and the otCLI are already initialised. + * + * @param otInst Pointer to the OT instance + * @return CHIP_ERROR OpenThread error mapped to CHIP_ERROR + */ template -CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::DoInit(otInstance * otInst) +CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::ConfigureThreadStack(otInstance * otInst) { CHIP_ERROR err = CHIP_NO_ERROR; otError otErr = OT_ERROR_NONE; - // Arrange for OpenThread errors to be translated to text. - RegisterOpenThreadErrorFormatter(); - - mOTInst = NULL; - - // If an OpenThread instance hasn't been supplied, call otInstanceInitSingle() to - // create or acquire a singleton instance of OpenThread. - if (otInst == NULL) - { - otInst = otInstanceInitSingle(); - VerifyOrExit(otInst != NULL, err = MapOpenThreadError(OT_ERROR_FAILED)); - } - -#if !defined(PW_RPC_ENABLED) && CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI - otAppCliInit(otInst); -#endif - mOTInst = otInst; // Arrange for OpenThread to call the OnOpenThreadStateChange method whenever a @@ -1146,14 +1138,43 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::DoInit(otInstanc } #endif - initNetworkCommissioningThreadDriver(); - exit: ChipLogProgress(DeviceLayer, "OpenThread started: %s", otThreadErrorToString(otErr)); return err; } + +template +CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::DoInit(otInstance * otInst) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Arrange for OpenThread errors to be translated to text. + RegisterOpenThreadErrorFormatter(); + + mOTInst = NULL; + + // If an OpenThread instance hasn't been supplied, call otInstanceInitSingle() to + // create or acquire a singleton instance of OpenThread. + if (otInst == NULL) + { + otInst = otInstanceInitSingle(); + VerifyOrExit(otInst != NULL, err = MapOpenThreadError(OT_ERROR_FAILED)); + } + +#if !defined(PW_RPC_ENABLED) && CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI + otAppCliInit(otInst); +#endif + + err = ConfigureThreadStack(otInst); + + initNetworkCommissioningThreadDriver(); + +exit: + return err; +} + template bool GenericThreadStackManagerImpl_OpenThread::IsThreadAttachedNoLock(void) { diff --git a/src/platform/silabs/ThreadStackManagerImpl.h b/src/platform/silabs/ThreadStackManagerImpl.h index c56990fb0d3712..411c8eeb0676e1 100644 --- a/src/platform/silabs/ThreadStackManagerImpl.h +++ b/src/platform/silabs/ThreadStackManagerImpl.h @@ -25,12 +25,17 @@ #pragma once -#include #include #include #include +#include "cmsis_os2.h" + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT +static constexpr uint32_t threadSrpClearAllFlags = 0x0001U; +#endif + extern "C" void otSysEventSignalPending(void); namespace chip { @@ -47,8 +52,7 @@ extern int GetEntropy_EFR32(uint8_t * buf, size_t bufSize); * using the Silicon Labs SDK and the OpenThread stack. */ class ThreadStackManagerImpl final : public ThreadStackManager, - public Internal::GenericThreadStackManagerImpl_OpenThread, - public Internal::GenericThreadStackManagerImpl_FreeRTOS + public Internal::GenericThreadStackManagerImpl_OpenThread { // Allow the ThreadStackManager interface class to delegate method calls to // the implementation methods provided by this class. @@ -58,8 +62,6 @@ class ThreadStackManagerImpl final : public ThreadStackManager, // this class. #ifndef DOXYGEN_SHOULD_SKIP_THIS friend Internal::GenericThreadStackManagerImpl_OpenThread; - friend Internal::GenericThreadStackManagerImpl_OpenThread; - friend Internal::GenericThreadStackManagerImpl_FreeRTOS; #endif // Allow glue functions called by OpenThread to call helper methods on this @@ -72,11 +74,21 @@ class ThreadStackManagerImpl final : public ThreadStackManager, using ThreadStackManager::InitThreadStack; CHIP_ERROR InitThreadStack(otInstance * otInst); + void FactoryResetThreadStack(void); private: // ===== Methods that implement the ThreadStackManager abstract interface. CHIP_ERROR _InitThreadStack(void); + CHIP_ERROR _StartThreadTask(void); + void _LockThreadStack(void); + bool _TryLockThreadStack(void); + void _UnlockThreadStack(void); + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + void _WaitOnSrpClearAllComplete(); + void _NotifySrpClearAllComplete(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT // ===== Members for internal use by the following friends. friend ThreadStackManager & ::chip::DeviceLayer::ThreadStackMgr(void); @@ -90,6 +102,10 @@ class ThreadStackManagerImpl final : public ThreadStackManager, // ===== Private members for use by this class only. ThreadStackManagerImpl() = default; + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + osThreadId_t mSrpClearAllRequester = NULL; +#endif }; /** diff --git a/src/platform/silabs/ThreadStackManagerImpl_CMSIS.h b/src/platform/silabs/ThreadStackManagerImpl_CMSIS.h new file mode 100644 index 00000000000000..e6a74a1a230dae --- /dev/null +++ b/src/platform/silabs/ThreadStackManagerImpl_CMSIS.h @@ -0,0 +1,97 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2018 Nest Labs, Inc. + * 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. + */ + +/** + * @file + * Provides an generic implementation of ThreadStackManager features + * for use on FreeRTOS platforms. + */ + +#pragma once + +#if defined(ESP_PLATFORM) +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/task.h" +#include "timers.h" +#else +#include "FreeRTOS.h" +#include "semphr.h" +#include "task.h" +#include "timers.h" +#endif + +namespace chip { +namespace DeviceLayer { + +class ThreadStackManagerImpl; + +namespace Internal { + +/** + * Provides a generic implementation of ThreadStackManager features that works on FreeRTOS platforms. + * + * This template contains implementations of select features from the ThreadStackManager abstract + * interface that are suitable for use on FreeRTOS-based platforms. It is intended to be + * inherited, directly or indirectly, by the ThreadStackManagerImpl class, which also appears as + * the template's ImplClass parameter. + */ +template +class ThreadStackManagerImpl_CMSIS +{ + +protected: + // ===== Methods that implement the ThreadStackManager abstract interface. + + CHIP_ERROR _StartThreadTask(void); + void _LockThreadStack(void); + bool _TryLockThreadStack(void); + void _UnlockThreadStack(void); + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + void _WaitOnSrpClearAllComplete(); + void _NotifySrpClearAllComplete(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + // ===== Members available to the implementation subclass. + + SemaphoreHandle_t mThreadStackLock; + TaskHandle_t mThreadTask; + + CHIP_ERROR DoInit(); + void SignalThreadActivityPending(); + BaseType_t SignalThreadActivityPendingFromISR(); + +private: + // ===== Private members for use by this class only. + + inline ImplClass * Impl() { return static_cast(this); } + + static void ThreadTaskMain(void * arg); + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + TaskHandle_t mSrpClearAllRequester = nullptr; +#endif +}; + +// Instruct the compiler to instantiate the template only when explicitly told to do so. +extern template class ThreadStackManagerImpl_CMSIS; + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/efr32/ThreadStackManagerImpl.cpp b/src/platform/silabs/efr32/ThreadStackManagerImpl.cpp index 2cab401837e8d8..ae44ed09fc7a18 100644 --- a/src/platform/silabs/efr32/ThreadStackManagerImpl.cpp +++ b/src/platform/silabs/efr32/ThreadStackManagerImpl.cpp @@ -26,7 +26,8 @@ /* this file behaves like a config.h, comes first */ #include -#include +#include +#include #include #include #include @@ -35,11 +36,45 @@ #include +#include +#include + +extern "C" { +#include "platform-efr32.h" +} + // Forward declaration extern "C" otInstance * otGetInstance(void); +#if CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI +extern "C" void otAppCliInit(otInstance * aInstance); +#endif + namespace chip { namespace DeviceLayer { +namespace { +otInstance * sOTInstance = NULL; + +// Network commissioning +#ifndef _NO_NETWORK_COMMISSIONING_DRIVER_ +NetworkCommissioning::GenericThreadDriver sGenericThreadDriver; +app::Clusters::NetworkCommissioning::Instance sThreadNetworkCommissioningInstance(0 /* Endpoint Id */, &sGenericThreadDriver); +#endif + +void initStaticNetworkCommissioningThreadDriver(void) +{ +#ifndef _NO_NETWORK_COMMISSIONING_DRIVER_ + sThreadNetworkCommissioningInstance.Init(); +#endif +} + +void shutdownStaticNetworkCommissioningThreadDriver(void) +{ +#ifndef _NO_NETWORK_COMMISSIONING_DRIVER_ + sThreadNetworkCommissioningInstance.Shutdown(); +#endif +} +}; // namespace using namespace ::chip::DeviceLayer::Internal; @@ -47,61 +82,81 @@ ThreadStackManagerImpl ThreadStackManagerImpl::sInstance; CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack(void) { - return InitThreadStack(NULL); + return InitThreadStack(sOTInstance); } -CHIP_ERROR ThreadStackManagerImpl::InitThreadStack(otInstance * otInst) +CHIP_ERROR ThreadStackManagerImpl::_StartThreadTask(void) { - CHIP_ERROR err = CHIP_NO_ERROR; - - // Initialize the generic implementation base classes. - err = GenericThreadStackManagerImpl_FreeRTOS::DoInit(); - SuccessOrExit(err); - err = GenericThreadStackManagerImpl_OpenThread::DoInit(otInst); - SuccessOrExit(err); + // Stubbed since our thread task is created in the InitThreadStack function and it will start once the scheduler starts. + return CHIP_NO_ERROR; +} -exit: - return err; +void ThreadStackManagerImpl::_LockThreadStack(void) +{ + sl_ot_rtos_acquire_stack_mutex(); } -bool ThreadStackManagerImpl::IsInitialized() +bool ThreadStackManagerImpl::_TryLockThreadStack(void) { - return sInstance.mThreadStackLock != NULL; + // TODO: Implement a non-blocking version of the mutex lock + sl_ot_rtos_acquire_stack_mutex(); + return true; } -} // namespace DeviceLayer -} // namespace chip +void ThreadStackManagerImpl::_UnlockThreadStack(void) +{ + sl_ot_rtos_release_stack_mutex(); +} -using namespace ::chip::DeviceLayer; +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT +void ThreadStackManagerImpl::_WaitOnSrpClearAllComplete() +{ + // Only 1 task can be blocked on a srpClearAll request + if (mSrpClearAllRequester == NULL) + { + mSrpClearAllRequester = osThreadGetId(); + // Wait on OnSrpClientNotification which confirms the clearing is done. + // It will notify this current task with NotifySrpClearAllComplete. + // However, we won't wait more than 2s. + osThreadFlagsWait(threadSrpClearAllFlags, osFlagsWaitAny, pdMS_TO_TICKS(2000)); + mSrpClearAllRequester = NULL; + } +} -/** - * Glue function called directly by the OpenThread stack when tasklet processing work - * is pending. - */ -extern "C" void otTaskletsSignalPending(otInstance * p_instance) +void ThreadStackManagerImpl::_NotifySrpClearAllComplete() { - ThreadStackMgrImpl().SignalThreadActivityPending(); + if (mSrpClearAllRequester) + { + osThreadFlagsSet(mSrpClearAllRequester, threadSrpClearAllFlags); + } } +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT -/** - * Glue function called directly by the OpenThread stack when system event processing work - * is pending. - */ -extern "C" void otSysEventSignalPending(void) +CHIP_ERROR ThreadStackManagerImpl::InitThreadStack(otInstance * otInst) { - BaseType_t yieldRequired = ThreadStackMgrImpl().SignalThreadActivityPendingFromISR(); - portYIELD_FROM_ISR(yieldRequired); + CHIP_ERROR err = CHIP_NO_ERROR; + err = GenericThreadStackManagerImpl_OpenThread::ConfigureThreadStack(otInst); + initStaticNetworkCommissioningThreadDriver(); + return err; } -extern "C" void * otPlatCAlloc(size_t aNum, size_t aSize) +void ThreadStackManagerImpl::FactoryResetThreadStack(void) { - return CHIPPlatformMemoryCalloc(aNum, aSize); + VerifyOrReturn(sOTInstance != NULL); + otInstanceFactoryReset(sOTInstance); + shutdownStaticNetworkCommissioningThreadDriver(); } -extern "C" void otPlatFree(void * aPtr) +bool ThreadStackManagerImpl::IsInitialized() { - CHIPPlatformMemoryFree(aPtr); + return otGetInstance() != NULL; } + +} // namespace DeviceLayer +} // namespace chip + +using namespace ::chip::DeviceLayer; + #ifndef SL_COMPONENT_CATALOG_PRESENT extern "C" __WEAK void sl_openthread_init(void) { @@ -137,7 +192,22 @@ extern "C" otError otPlatUartEnable(void) extern "C" otInstance * otGetInstance(void) { - return ThreadStackMgrImpl().OTInstance(); + return sOTInstance; +} + +extern "C" void sl_ot_create_instance(void) +{ + VerifyOrDie(chip::Platform::MemoryInit() == CHIP_NO_ERROR); + mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree); + sOTInstance = otInstanceInitSingle(); +} + +extern "C" void sl_ot_cli_init(void) +{ +#if !defined(PW_RPC_ENABLED) && CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI + VerifyOrDie(sOTInstance != NULL); + otAppCliInit(sOTInstance); +#endif } #if CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI diff --git a/src/platform/silabs/efr32/ThreadStackManagerImpl_CMSIS.hpp b/src/platform/silabs/efr32/ThreadStackManagerImpl_CMSIS.hpp new file mode 100644 index 00000000000000..01821ab2d492ff --- /dev/null +++ b/src/platform/silabs/efr32/ThreadStackManagerImpl_CMSIS.hpp @@ -0,0 +1,138 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * 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. + */ + +/** + * @file + * Contains non-inline method definitions for the + * GenericThreadStackManagerImpl_FreeRTOS<> template. + */ + +#include +#include +#include "../ThreadStackManagerImpl_CMSIS.h" +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +template +CHIP_ERROR ThreadStackManagerImpl_CMSIS::DoInit(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + return err; +} + +template +CHIP_ERROR ThreadStackManagerImpl_CMSIS::_StartThreadTask(void) +{ + return CHIP_NO_ERROR; +} + +template +void ThreadStackManagerImpl_CMSIS::_LockThreadStack(void) +{ +} + +template +bool ThreadStackManagerImpl_CMSIS::_TryLockThreadStack(void) +{ + return true; +} + +template +void ThreadStackManagerImpl_CMSIS::_UnlockThreadStack(void) +{ +} + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT +template +void ThreadStackManagerImpl_CMSIS::_WaitOnSrpClearAllComplete() +{ + // Only 1 task can be blocked on a srpClearAll request + // if (mSrpClearAllRequester == nullptr) + // { + // //mSrpClearAllRequester = xTaskGetCurrentTaskHandle(); + // // Wait on OnSrpClientNotification which confirms the slearing is done. + // // It will notify this current task with NotifySrpClearAllComplete. + // // However, we won't wait more than 2s. + // ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(2000)); + // mSrpClearAllRequester = nullptr; + // } +} + +template +void ThreadStackManagerImpl_CMSIS::_NotifySrpClearAllComplete() +{ + // if (mSrpClearAllRequester) + // { + // xTaskNotifyGive(mSrpClearAllRequester); + // } +} +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + +template +void ThreadStackManagerImpl_CMSIS::SignalThreadActivityPending() +{ + // if (mThreadTask != NULL) + // { + // xTaskNotifyGive(mThreadTask); + // } +} + +template +BaseType_t ThreadStackManagerImpl_CMSIS::SignalThreadActivityPendingFromISR() +{ + BaseType_t yieldRequired = pdFALSE; + + // if (mThreadTask != NULL) + // { + // vTaskNotifyGiveFromISR(mThreadTask, &yieldRequired); + // } + + return yieldRequired; +} + +template +void ThreadStackManagerImpl_CMSIS::ThreadTaskMain(void * arg) +{ + ThreadStackManagerImpl_CMSIS * self = + static_cast *>(arg); + + ChipLogDetail(DeviceLayer, "Thread task running"); + + while (true) + { + self->Impl()->LockThreadStack(); + self->Impl()->ProcessThreadActivity(); + self->Impl()->UnlockThreadStack(); + + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + } +} + +// Fully instantiate the generic implementation class in whatever compilation unit includes this file. +// NB: This must come after all templated class members are defined. +template class ThreadStackManagerImpl_CMSIS; + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/platformAbstraction/GsdkSpam.cpp b/src/platform/silabs/platformAbstraction/GsdkSpam.cpp index 0881bea848112b..514003305868cf 100644 --- a/src/platform/silabs/platformAbstraction/GsdkSpam.cpp +++ b/src/platform/silabs/platformAbstraction/GsdkSpam.cpp @@ -79,10 +79,6 @@ CHIP_ERROR SilabsPlatform::Init(void) sl_iostream_set_default(sl_iostream_stdio_handle); #endif -#if CHIP_ENABLE_OPENTHREAD - sl_ot_sys_init(); -#endif - #ifdef SL_CATALOG_SYSTEMVIEW_TRACE_PRESENT SEGGER_SYSVIEW_Conf(); #endif diff --git a/third_party/openthread/platforms/efr32/BUILD.gn b/third_party/openthread/platforms/efr32/BUILD.gn index 381c6407f2c7cd..69e55a5d76151d 100644 --- a/third_party/openthread/platforms/efr32/BUILD.gn +++ b/third_party/openthread/platforms/efr32/BUILD.gn @@ -32,11 +32,9 @@ config("openthread_efr32_config") { "${sl_ot_efr32_root}", "${chip_root}/examples/platform/efr32", "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}", + "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/config", "${sl_ot_platform_abstraction}/include", "${sl_ot_platform_abstraction}/rtos", - - #TODO this is for sl_openthread_features_config.h. should use generated one per board when sl_ot_abstraction is integrated - "${sl_ot_libs_path}/config", ] # temporarily disable check until gsdk pulls in a more recent version of openthread diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index 87d0b0bc078d06..8793ec81f8fb7c 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -222,12 +222,15 @@ template("efr32_sdk") { "${efr32_sdk_root}/util/third_party/freertos/kernel/include", "${silabs_gen_folder}/config", "${silabs_gen_folder}/autogen", + "${sl_ot_platform_abstraction}/rtos", + "${efr32_sdk_root}/protocol/openthread/include", + "${efr32_sdk_root}/util/third_party/openthread/include", + "${efr32_sdk_root}/util/third_party/openthread/src/core", + "${efr32_sdk_root}/util/third_party/openthread/examples/platforms/", + "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/config", # Headers needed for Init no function will be called if OT is not used "${sl_ot_efr32_root}", - - # TODO this is for sl_openthread_features_config.h. should use generated one per board when sl_ot_abstraction is integrated - "${sl_ot_libs_path}/config", ] if (is_series_2) { @@ -437,7 +440,6 @@ template("efr32_sdk") { "SL_OPENTHREAD_STACK_FEATURES_CONFIG_FILE=\"sl_openthread_features_config.h\"", "SL_CSL_TIMEOUT=${sl_ot_csl_timeout_sec}", "CIRCULAR_QUEUE_USE_LOCAL_CONFIG_HEADER=1", - "MATTER_INTEGRATION=1", ] if (silabs_log_enabled && chip_logging) { @@ -475,6 +477,25 @@ template("efr32_sdk") { ] } + if (defined(invoker.chip_enable_openthread) && + invoker.chip_enable_openthread) { + defines += [ + "SL_OT_ENABLE=1", + + #TODO: Remove these defines onse sl_openthread_rtos_config is included in sl_ot_rtos_adaptation.c + "SL_OPENTHREAD_RTOS_STACK_TASK_PRIORITY=24", + "SL_OPENTHREAD_RTOS_APP_TASK_PRIORITY=23", + "SL_OPENTHREAD_RTOS_CLI_TASK_PRIORITY=16", + "SL_OPENTHREAD_STACK_TASK_MEM_SIZE=4608", + "SL_OPENTHREAD_APP_TASK_MEM_SIZE=4608", + "SL_OPENTHREAD_CLI_TASK_MEM_SIZE=2048", + "SL_OPENTHREAD_RTOS_CLI_TASK_PRIORITY=16", + "SL_OPENTHREAD_OS_CLI_TASK_SIZE=2048", + "SL_OPENTHREAD_ENABLE_APP_TASK=0", + "SL_OPENTHREAD_ENABLE_CLI_TASK=0", + ] + } + if (defined(invoker.chip_enable_wifi) && invoker.chip_enable_wifi) { if (enable_dic) { assert(chip_enable_wifi_ipv4, "enable chip_enable_wifi_ipv4") @@ -809,6 +830,15 @@ template("efr32_sdk") { ] } + if (defined(invoker.chip_enable_openthread) && + invoker.chip_enable_openthread) { + sources += [ + "${silabs_gen_folder}/autogen/sl_ot_custom_cli.c", + "${silabs_gen_folder}/autogen/sl_ot_init.c", + "${sl_ot_platform_abstraction}/rtos/sl_ot_rtos_adaptation.c", + ] + } + if (use_wstk_buttons) { sources += [ "${efr32_sdk_root}/platform/driver/button/src/sl_button.c", @@ -947,7 +977,6 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/Device/SiliconLabs/MGM24/Source/startup_mgm24.c", "${efr32_sdk_root}/platform/Device/SiliconLabs/MGM24/Source/system_mgm24.c", "${efr32_sdk_root}/platform/radio/rail_lib/plugin/fem_util/sl_fem_util.c", - "${efr32_sdk_root}/platform/radio/rail_lib/plugin/rail_util_rssi/sl_rail_util_rssi.c", "${efr32_sdk_root}/platform/service/device_manager/clocks/sl_device_clock_efr32xg24.c", "${efr32_sdk_root}/platform/service/device_manager/devices/sl_device_peripheral_hal_efr32xg24.c", ] @@ -963,6 +992,7 @@ template("efr32_sdk") { if (is_series_2) { sources += [ "${efr32_sdk_root}/platform/radio/rail_lib/plugin/pa-conversions/pa_curves_efr32.c", + "${efr32_sdk_root}/platform/radio/rail_lib/plugin/rail_util_rssi/sl_rail_util_rssi.c", "${efr32_sdk_root}/platform/radio/rail_lib/plugin/rail_util_sequencer/sl_rail_util_sequencer.c", "${efr32_sdk_root}/platform/security/sl_component/se_manager/src/sl_se_manager.c", "${efr32_sdk_root}/platform/security/sl_component/se_manager/src/sl_se_manager_attestation.c", diff --git a/third_party/silabs/lwip.gni b/third_party/silabs/lwip.gni index 9a35e7c45f7a61..e434d1c80d1722 100644 --- a/third_party/silabs/lwip.gni +++ b/third_party/silabs/lwip.gni @@ -171,6 +171,9 @@ template("lwip_target") { "${_lwip_root}/src/core/ipv6/ip6_frag.c", "${_lwip_root}/src/core/ipv6/mld6.c", "${_lwip_root}/src/core/ipv6/nd6.c", + + # TODO: When updating to next Si SDK version, revert change. + "${sdk_support_root}/src/core/ipv6/mld6.c", ] } From 64f2facdd844f1b3b952f0f56c1231c5ca17062c Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs Date: Thu, 18 Jul 2024 09:09:12 -0400 Subject: [PATCH 2/4] Updated matter support --- examples/platform/silabs/BaseApplication.cpp | 24 +-- examples/platform/silabs/BaseApplication.h | 5 +- ...nericThreadStackManagerImpl_OpenThread.hpp | 5 +- .../silabs/ThreadStackManagerImpl_CMSIS.h | 97 ------------ .../efr32/ThreadStackManagerImpl_CMSIS.hpp | 138 ------------------ third_party/silabs/efr32_sdk.gni | 2 +- third_party/silabs/matter_support | 2 +- 7 files changed, 19 insertions(+), 254 deletions(-) delete mode 100644 src/platform/silabs/ThreadStackManagerImpl_CMSIS.h delete mode 100644 src/platform/silabs/efr32/ThreadStackManagerImpl_CMSIS.hpp diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index 1454bd09ca1d26..b954f739e3c6a0 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -115,8 +115,8 @@ app::Clusters::NetworkCommissioning::Instance sWiFiNetworkCommissioningInstance(0 /* Endpoint Id */, &(NetworkCommissioning::SlWiFiDriver::GetInstance())); #endif /* SL_WIFI */ -bool sIsEnabled = false; -bool sIsAttached = false; +bool sIsEnabled = false; +bool sIsAttached = false; #if !(defined(CHIP_CONFIG_ENABLE_ICD_SERVER) && CHIP_CONFIG_ENABLE_ICD_SERVER) bool sHaveBLEConnections = false; @@ -160,9 +160,9 @@ Identify gIdentify = { } // namespace -bool BaseApplication::sIsProvisioned = false; -bool BaseApplication::sIsFactoryResetTriggered = false; -LEDWidget * BaseApplication::sAppActionLed = nullptr; +bool BaseApplication::sIsProvisioned = false; +bool BaseApplication::sIsFactoryResetTriggered = false; +LEDWidget * BaseApplication::sAppActionLed = nullptr; BaseApplicationDelegate BaseApplication::sAppDelegate = BaseApplicationDelegate(); #ifdef DIC_ENABLE @@ -437,15 +437,15 @@ bool BaseApplication::ActivateStatusLedPatterns() void BaseApplication::UpdateCommissioningStatus(bool newState) { #ifdef SL_WIFI - BaseApplication::sIsProvisioned = ConnectivityMgr().IsWiFiStationProvisioned(); - sIsEnabled = ConnectivityMgr().IsWiFiStationEnabled(); - sIsAttached = ConnectivityMgr().IsWiFiStationConnected(); + BaseApplication::sIsProvisioned = ConnectivityMgr().IsWiFiStationProvisioned(); + sIsEnabled = ConnectivityMgr().IsWiFiStationEnabled(); + sIsAttached = ConnectivityMgr().IsWiFiStationConnected(); #endif /* SL_WIFI */ #if CHIP_ENABLE_OPENTHREAD // TODO: This is a temporary solution until we can read Thread provisioning status from RAM instead of NVM. BaseApplication::sIsProvisioned = newState; - sIsEnabled = ConnectivityMgr().IsThreadEnabled(); - sIsAttached = ConnectivityMgr().IsThreadAttached(); + sIsEnabled = ConnectivityMgr().IsThreadEnabled(); + sIsAttached = ConnectivityMgr().IsThreadAttached(); #endif /* CHIP_ENABLE_OPENTHREAD */ ActivateStatusLedPatterns(); @@ -790,7 +790,9 @@ void BaseApplication::ScheduleFactoryReset() { Provision::Manager::GetInstance().SetProvisionRequired(true); } - PlatformMgr().HandleServerShuttingDown(); // HandleServerShuttingDown calls OnShutdown() which is only implemented for the basic information cluster it seems. And triggers and Event flush, which is not relevant when there are no fabrics left + PlatformMgr().HandleServerShuttingDown(); // HandleServerShuttingDown calls OnShutdown() which is only implemented for the + // basic information cluster it seems. And triggers and Event flush, which is not + // relevant when there are no fabrics left ConfigurationMgr().InitiateFactoryReset(); }); } diff --git a/examples/platform/silabs/BaseApplication.h b/examples/platform/silabs/BaseApplication.h index cfef5f945a382f..ed233246ec8ee5 100644 --- a/examples/platform/silabs/BaseApplication.h +++ b/examples/platform/silabs/BaseApplication.h @@ -32,10 +32,10 @@ #include #include #include +#include #include #include #include -#include #include "LEDWidget.h" @@ -63,8 +63,7 @@ #define APP_ERROR_START_TIMER_FAILED CHIP_APPLICATION_ERROR(0x05) #define APP_ERROR_STOP_TIMER_FAILED CHIP_APPLICATION_ERROR(0x06) -class BaseApplicationDelegate : public AppDelegate, - public chip::FabricTable::Delegate +class BaseApplicationDelegate : public AppDelegate, public chip::FabricTable::Delegate { private: // AppDelegate diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp index 77f7293d7a43bd..3fe20c2cf6a804 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp @@ -1090,10 +1090,10 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_GetPollPeriod(u /** * @brief Helper that sets callbacks for OpenThread state changes and configures the Thread stack. - * Assigns mOTInst to and instance and configures the OT stack on a device by setting state change callbacks enabling features + * Assigns mOTInst to and instance and configures the OT stack on a device by setting state change callbacks enabling features * for IPv6 address configuration, enabling the Thread network if necessary, and handling SRP if enabled. * Allows for the configuration of the Thread stack on a device where the instance and the otCLI are already initialised. - * + * * @param otInst Pointer to the OT instance * @return CHIP_ERROR OpenThread error mapped to CHIP_ERROR */ @@ -1144,7 +1144,6 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::ConfigureThreadS return err; } - template CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::DoInit(otInstance * otInst) { diff --git a/src/platform/silabs/ThreadStackManagerImpl_CMSIS.h b/src/platform/silabs/ThreadStackManagerImpl_CMSIS.h deleted file mode 100644 index e6a74a1a230dae..00000000000000 --- a/src/platform/silabs/ThreadStackManagerImpl_CMSIS.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2018 Nest Labs, Inc. - * 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. - */ - -/** - * @file - * Provides an generic implementation of ThreadStackManager features - * for use on FreeRTOS platforms. - */ - -#pragma once - -#if defined(ESP_PLATFORM) -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" -#include "freertos/task.h" -#include "timers.h" -#else -#include "FreeRTOS.h" -#include "semphr.h" -#include "task.h" -#include "timers.h" -#endif - -namespace chip { -namespace DeviceLayer { - -class ThreadStackManagerImpl; - -namespace Internal { - -/** - * Provides a generic implementation of ThreadStackManager features that works on FreeRTOS platforms. - * - * This template contains implementations of select features from the ThreadStackManager abstract - * interface that are suitable for use on FreeRTOS-based platforms. It is intended to be - * inherited, directly or indirectly, by the ThreadStackManagerImpl class, which also appears as - * the template's ImplClass parameter. - */ -template -class ThreadStackManagerImpl_CMSIS -{ - -protected: - // ===== Methods that implement the ThreadStackManager abstract interface. - - CHIP_ERROR _StartThreadTask(void); - void _LockThreadStack(void); - bool _TryLockThreadStack(void); - void _UnlockThreadStack(void); - -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT - void _WaitOnSrpClearAllComplete(); - void _NotifySrpClearAllComplete(); -#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT - // ===== Members available to the implementation subclass. - - SemaphoreHandle_t mThreadStackLock; - TaskHandle_t mThreadTask; - - CHIP_ERROR DoInit(); - void SignalThreadActivityPending(); - BaseType_t SignalThreadActivityPendingFromISR(); - -private: - // ===== Private members for use by this class only. - - inline ImplClass * Impl() { return static_cast(this); } - - static void ThreadTaskMain(void * arg); - -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT - TaskHandle_t mSrpClearAllRequester = nullptr; -#endif -}; - -// Instruct the compiler to instantiate the template only when explicitly told to do so. -extern template class ThreadStackManagerImpl_CMSIS; - -} // namespace Internal -} // namespace DeviceLayer -} // namespace chip diff --git a/src/platform/silabs/efr32/ThreadStackManagerImpl_CMSIS.hpp b/src/platform/silabs/efr32/ThreadStackManagerImpl_CMSIS.hpp deleted file mode 100644 index 01821ab2d492ff..00000000000000 --- a/src/platform/silabs/efr32/ThreadStackManagerImpl_CMSIS.hpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2019 Nest Labs, Inc. - * 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. - */ - -/** - * @file - * Contains non-inline method definitions for the - * GenericThreadStackManagerImpl_FreeRTOS<> template. - */ - -#include -#include -#include "../ThreadStackManagerImpl_CMSIS.h" -#include -#include -#include - -namespace chip { -namespace DeviceLayer { -namespace Internal { - -template -CHIP_ERROR ThreadStackManagerImpl_CMSIS::DoInit(void) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - return err; -} - -template -CHIP_ERROR ThreadStackManagerImpl_CMSIS::_StartThreadTask(void) -{ - return CHIP_NO_ERROR; -} - -template -void ThreadStackManagerImpl_CMSIS::_LockThreadStack(void) -{ -} - -template -bool ThreadStackManagerImpl_CMSIS::_TryLockThreadStack(void) -{ - return true; -} - -template -void ThreadStackManagerImpl_CMSIS::_UnlockThreadStack(void) -{ -} - -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT -template -void ThreadStackManagerImpl_CMSIS::_WaitOnSrpClearAllComplete() -{ - // Only 1 task can be blocked on a srpClearAll request - // if (mSrpClearAllRequester == nullptr) - // { - // //mSrpClearAllRequester = xTaskGetCurrentTaskHandle(); - // // Wait on OnSrpClientNotification which confirms the slearing is done. - // // It will notify this current task with NotifySrpClearAllComplete. - // // However, we won't wait more than 2s. - // ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(2000)); - // mSrpClearAllRequester = nullptr; - // } -} - -template -void ThreadStackManagerImpl_CMSIS::_NotifySrpClearAllComplete() -{ - // if (mSrpClearAllRequester) - // { - // xTaskNotifyGive(mSrpClearAllRequester); - // } -} -#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT - -template -void ThreadStackManagerImpl_CMSIS::SignalThreadActivityPending() -{ - // if (mThreadTask != NULL) - // { - // xTaskNotifyGive(mThreadTask); - // } -} - -template -BaseType_t ThreadStackManagerImpl_CMSIS::SignalThreadActivityPendingFromISR() -{ - BaseType_t yieldRequired = pdFALSE; - - // if (mThreadTask != NULL) - // { - // vTaskNotifyGiveFromISR(mThreadTask, &yieldRequired); - // } - - return yieldRequired; -} - -template -void ThreadStackManagerImpl_CMSIS::ThreadTaskMain(void * arg) -{ - ThreadStackManagerImpl_CMSIS * self = - static_cast *>(arg); - - ChipLogDetail(DeviceLayer, "Thread task running"); - - while (true) - { - self->Impl()->LockThreadStack(); - self->Impl()->ProcessThreadActivity(); - self->Impl()->UnlockThreadStack(); - - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - } -} - -// Fully instantiate the generic implementation class in whatever compilation unit includes this file. -// NB: This must come after all templated class members are defined. -template class ThreadStackManagerImpl_CMSIS; - -} // namespace Internal -} // namespace DeviceLayer -} // namespace chip diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index 8793ec81f8fb7c..f22f82d464a240 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -482,7 +482,7 @@ template("efr32_sdk") { defines += [ "SL_OT_ENABLE=1", - #TODO: Remove these defines onse sl_openthread_rtos_config is included in sl_ot_rtos_adaptation.c + #TODO: Remove these defines once sl_openthread_rtos_config is included in sl_ot_rtos_adaptation.c "SL_OPENTHREAD_RTOS_STACK_TASK_PRIORITY=24", "SL_OPENTHREAD_RTOS_APP_TASK_PRIORITY=23", "SL_OPENTHREAD_RTOS_CLI_TASK_PRIORITY=16", diff --git a/third_party/silabs/matter_support b/third_party/silabs/matter_support index 9e983904a64d2f..9084b6fa2f9407 160000 --- a/third_party/silabs/matter_support +++ b/third_party/silabs/matter_support @@ -1 +1 @@ -Subproject commit 9e983904a64d2f74280cd48b65ffd4457abd64f7 +Subproject commit 9084b6fa2f9407396a7f2db12975e6e89fe07a8c From 097006258e6d22c95bf7f80f6bd8266aeca03a4c Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs Date: Thu, 18 Jul 2024 10:48:16 -0400 Subject: [PATCH 3/4] Added ClearThreadStack Helper --- examples/platform/silabs/BaseApplication.cpp | 7 ++----- src/platform/silabs/ConfigurationManagerImpl.cpp | 16 +++++++++++----- src/platform/silabs/ConfigurationManagerImpl.h | 2 ++ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index b954f739e3c6a0..44e6a4ff3b1827 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -51,6 +51,7 @@ #if CHIP_ENABLE_OPENTHREAD #include #include +#include #include #endif // CHIP_ENABLE_OPENTHREAD @@ -801,11 +802,7 @@ void BaseApplication::DoProvisioningReset() { PlatformMgr().ScheduleWork([](intptr_t) { #if CHIP_DEVICE_CONFIG_ENABLE_THREAD -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT - ThreadStackMgr().ClearAllSrpHostAndServices(); -#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT - ChipLogProgress(DeviceLayer, "Clearing Thread provision"); - chip::DeviceLayer::ConnectivityMgr().ErasePersistentInfo(); + ConfigurationManagerImpl::GetDefaultInstance().ClearThreadStack(); ThreadStackMgrImpl().FactoryResetThreadStack(); ThreadStackMgr().InitThreadStack(); #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD diff --git a/src/platform/silabs/ConfigurationManagerImpl.cpp b/src/platform/silabs/ConfigurationManagerImpl.cpp index 9454367d3bf030..48ca5109e616d2 100644 --- a/src/platform/silabs/ConfigurationManagerImpl.cpp +++ b/src/platform/silabs/ConfigurationManagerImpl.cpp @@ -260,6 +260,16 @@ void ConfigurationManagerImpl::RunConfigUnitTest(void) #endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST } +/// @brief Helper to erase Thread info from device +void ConfigurationManagerImpl::ClearThreadStack() +{ +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + ThreadStackMgr().ClearAllSrpHostAndServices(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + ChipLogProgress(DeviceLayer, "Clearing Thread provision"); + ThreadStackMgr().ErasePersistentInfo(); +} + void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) { CHIP_ERROR err; @@ -273,11 +283,7 @@ void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) } #if CHIP_DEVICE_CONFIG_ENABLE_THREAD -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT - ThreadStackMgr().ClearAllSrpHostAndServices(); -#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT - ChipLogProgress(DeviceLayer, "Clearing Thread provision"); - ThreadStackMgr().ErasePersistentInfo(); + GetDefaultInstance().ClearThreadStack(); #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD PersistedStorage::KeyValueStoreMgrImpl().ErasePartition(); diff --git a/src/platform/silabs/ConfigurationManagerImpl.h b/src/platform/silabs/ConfigurationManagerImpl.h index f34e37ed91bb52..262b68053a3214 100644 --- a/src/platform/silabs/ConfigurationManagerImpl.h +++ b/src/platform/silabs/ConfigurationManagerImpl.h @@ -46,6 +46,8 @@ class ConfigurationManagerImpl : public Internal::GenericConfigurationManagerImp CHIP_ERROR GetTotalOperationalHours(uint32_t & totalOperationalHours); CHIP_ERROR StoreTotalOperationalHours(uint32_t totalOperationalHours); + void ClearThreadStack(); + private: // ===== Members that implement the ConfigurationManager public interface. From 5271440abd8f0d0b540a59a06f7a51b8d13498c3 Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs Date: Thu, 18 Jul 2024 11:10:48 -0400 Subject: [PATCH 4/4] Grouped extern C statements --- examples/platform/silabs/BaseApplication.h | 4 ++-- ...GenericThreadStackManagerImpl_OpenThread.hpp | 2 +- .../silabs/ConfigurationManagerImpl.cpp | 4 ++-- .../silabs/efr32/ThreadStackManagerImpl.cpp | 17 +++++++---------- third_party/silabs/BUILD.gn | 1 + third_party/silabs/efr32_sdk.gni | 2 ++ third_party/silabs/lwip.gni | 1 - 7 files changed, 15 insertions(+), 16 deletions(-) diff --git a/examples/platform/silabs/BaseApplication.h b/examples/platform/silabs/BaseApplication.h index ed233246ec8ee5..161f1cdc9eb2fd 100644 --- a/examples/platform/silabs/BaseApplication.h +++ b/examples/platform/silabs/BaseApplication.h @@ -165,8 +165,8 @@ class BaseApplication static void UpdateCommissioningStatus(bool newState); /** - * @brief Called when the last Fabric is removed, clears all Fabric related data and Thread Wifi provision. - * @note This function preserves some NVM3 data that is not Fabric scoped like Attribute Value or Boot Count. + * @brief Called when the last Fabric is removed, clears all Fabric related data, including Thread and Wifi provision. + * @note This function preserves some NVM3 data that is not Fabric scoped, like Attribute Value or Boot Count. */ static void DoProvisioningReset(); diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp index 3fe20c2cf6a804..61452f5ff0ec90 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp @@ -1090,7 +1090,7 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_GetPollPeriod(u /** * @brief Helper that sets callbacks for OpenThread state changes and configures the Thread stack. - * Assigns mOTInst to and instance and configures the OT stack on a device by setting state change callbacks enabling features + * Assigns mOTInst to an instance, and configures the OT stack on a device by setting state change callbacks enabling features * for IPv6 address configuration, enabling the Thread network if necessary, and handling SRP if enabled. * Allows for the configuration of the Thread stack on a device where the instance and the otCLI are already initialised. * diff --git a/src/platform/silabs/ConfigurationManagerImpl.cpp b/src/platform/silabs/ConfigurationManagerImpl.cpp index 48ca5109e616d2..5a511038c799ed 100644 --- a/src/platform/silabs/ConfigurationManagerImpl.cpp +++ b/src/platform/silabs/ConfigurationManagerImpl.cpp @@ -263,11 +263,13 @@ void ConfigurationManagerImpl::RunConfigUnitTest(void) /// @brief Helper to erase Thread info from device void ConfigurationManagerImpl::ClearThreadStack() { +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT ThreadStackMgr().ClearAllSrpHostAndServices(); #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT ChipLogProgress(DeviceLayer, "Clearing Thread provision"); ThreadStackMgr().ErasePersistentInfo(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD } void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) @@ -282,9 +284,7 @@ void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) ChipLogError(DeviceLayer, "FactoryResetConfig() failed: %s", chip::ErrorStr(err)); } -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD GetDefaultInstance().ClearThreadStack(); -#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD PersistedStorage::KeyValueStoreMgrImpl().ErasePartition(); diff --git a/src/platform/silabs/efr32/ThreadStackManagerImpl.cpp b/src/platform/silabs/efr32/ThreadStackManagerImpl.cpp index ae44ed09fc7a18..d2ae058a8a03f1 100644 --- a/src/platform/silabs/efr32/ThreadStackManagerImpl.cpp +++ b/src/platform/silabs/efr32/ThreadStackManagerImpl.cpp @@ -41,14 +41,11 @@ extern "C" { #include "platform-efr32.h" -} - -// Forward declaration -extern "C" otInstance * otGetInstance(void); - +otInstance * otGetInstance(void); #if CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI -extern "C" void otAppCliInit(otInstance * aInstance); -#endif +void otAppCliInit(otInstance * aInstance); +#endif // CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI +} namespace chip { namespace DeviceLayer { @@ -56,21 +53,21 @@ namespace { otInstance * sOTInstance = NULL; // Network commissioning -#ifndef _NO_NETWORK_COMMISSIONING_DRIVER_ +#ifndef _NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_ NetworkCommissioning::GenericThreadDriver sGenericThreadDriver; app::Clusters::NetworkCommissioning::Instance sThreadNetworkCommissioningInstance(0 /* Endpoint Id */, &sGenericThreadDriver); #endif void initStaticNetworkCommissioningThreadDriver(void) { -#ifndef _NO_NETWORK_COMMISSIONING_DRIVER_ +#ifndef _NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_ sThreadNetworkCommissioningInstance.Init(); #endif } void shutdownStaticNetworkCommissioningThreadDriver(void) { -#ifndef _NO_NETWORK_COMMISSIONING_DRIVER_ +#ifndef _NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_ sThreadNetworkCommissioningInstance.Shutdown(); #endif } diff --git a/third_party/silabs/BUILD.gn b/third_party/silabs/BUILD.gn index 915cf8ba2bf164..e08c7cd0bd11bd 100644 --- a/third_party/silabs/BUILD.gn +++ b/third_party/silabs/BUILD.gn @@ -211,6 +211,7 @@ if (wifi_soc != true) { # CCP board include_dirs = [ "${sl_ot_platform_abstraction}/include" ] } + sources += [ "${sl_ot_platform_abstraction}/efr32/sleep.c" ] # Use silabs openthread library stack with or without coap api enabled COAP_API = "" diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index f22f82d464a240..08695af1fc3800 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -916,6 +916,8 @@ template("efr32_sdk") { sources += [ "${efr32_sdk_root}/hardware/driver/configuration_over_swo/src/sl_cos.c", "${efr32_sdk_root}/platform/driver/debug/src/sl_debug_swo.c", + "${efr32_sdk_root}/util/third_party/mbedtls/library/hmac_drbg.c", + "${efr32_sdk_root}/util/third_party/mbedtls/library/psa_crypto_ecp.c", ] } diff --git a/third_party/silabs/lwip.gni b/third_party/silabs/lwip.gni index e434d1c80d1722..b0b6a0db0d2c9f 100644 --- a/third_party/silabs/lwip.gni +++ b/third_party/silabs/lwip.gni @@ -169,7 +169,6 @@ template("lwip_target") { "${_lwip_root}/src/core/ipv6/ip6.c", "${_lwip_root}/src/core/ipv6/ip6_addr.c", "${_lwip_root}/src/core/ipv6/ip6_frag.c", - "${_lwip_root}/src/core/ipv6/mld6.c", "${_lwip_root}/src/core/ipv6/nd6.c", # TODO: When updating to next Si SDK version, revert change.