diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index c80dc1091b..5051edac48 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -96,6 +96,11 @@ #include #endif // MATTER_TRACING_ENABLED +// sl-only +#if SL_MATTER_ENABLE_APP_SLEEP_MANAGER +#include +#endif // SL_MATTER_ENABLE_APP_SLEEP_MANAGER + /********************************************************** * Defines and Constants *********************************************************/ @@ -213,8 +218,19 @@ void BaseApplicationDelegate::OnCommissioningSessionStopped() #endif // SL_WIFI && CHIP_CONFIG_ENABLE_ICD_SERVER } +void BaseApplicationDelegate::OnCommissioningWindowOpened() +{ +#if SL_MATTER_ENABLE_APP_SLEEP_MANAGER + app::Silabs::ApplicationSleepManager::GetInstance().OnCommissioningWindowOpened(); +#endif // SL_MATTER_ENABLE_APP_SLEEP_MANAGER +} + void BaseApplicationDelegate::OnCommissioningWindowClosed() { +#if SL_MATTER_ENABLE_APP_SLEEP_MANAGER + app::Silabs::ApplicationSleepManager::GetInstance().OnCommissioningWindowClosed(); +#endif // SL_MATTER_ENABLE_APP_SLEEP_MANAGER + if (BaseApplication::GetProvisionStatus()) { // After the device is provisioned and the commissioning passed diff --git a/examples/platform/silabs/BaseApplication.h b/examples/platform/silabs/BaseApplication.h index 994d62f14f..d28596220b 100644 --- a/examples/platform/silabs/BaseApplication.h +++ b/examples/platform/silabs/BaseApplication.h @@ -74,6 +74,7 @@ class BaseApplicationDelegate : public AppDelegate, public chip::FabricTable::De void OnCommissioningSessionStarted() override; void OnCommissioningSessionStopped() override; void OnCommissioningWindowClosed() override; + void OnCommissioningWindowOpened() override; // FabricTable::Delegate void OnFabricCommitted(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex) override; diff --git a/examples/platform/silabs/MatterConfig.cpp b/examples/platform/silabs/MatterConfig.cpp index b146a12547..b7f007b07b 100644 --- a/examples/platform/silabs/MatterConfig.cpp +++ b/examples/platform/silabs/MatterConfig.cpp @@ -227,9 +227,6 @@ void SilabsMatterConfig::AppInit() ChipLogProgress(DeviceLayer, "Starting scheduler"); VerifyOrDie(sMainTaskHandle); // We can't proceed if the Main Task creation failed. -#if MATTER_TRACING_ENABLED - SilabsTracer::Instance().TimeTraceEnd(TimeTraceOperation::kBootup); -#endif // MATTER_TRACING_ENABLED GetPlatform().StartScheduler(); // Should never get here. @@ -334,15 +331,11 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) initParams.appDelegate = &BaseApplication::sAppDelegate; - // Init Matter Server and Start Event Loop - err = chip::Server::GetInstance().Init(initParams); - // [sl-only]: Configure Wi-Fi App Sleep Manager #if SL_MATTER_ENABLE_APP_SLEEP_MANAGER err = app::Silabs::ApplicationSleepManager::GetInstance() .SetFabricTable(&Server::GetInstance().GetFabricTable()) .SetSubscriptionInfoProvider(app::InteractionModelEngine::GetInstance()) - .SetCommissioningWindowManager(&Server::GetInstance().GetCommissioningWindowManager()) .SetWifiSleepManager(&WifiSleepManager::GetInstance()) .Init(); VerifyOrReturnError(err == CHIP_NO_ERROR, err, ChipLogError(DeviceLayer, "ApplicationSleepManager init failed")); @@ -352,6 +345,9 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) &app::Silabs::ApplicationSleepManager::GetInstance()); #endif // SL_MATTER_ENABLE_APP_SLEEP_MANAGER + // Init Matter Server and Start Event Loop + err = chip::Server::GetInstance().Init(initParams); + #if MATTER_TRACING_ENABLED static Tracing::Silabs::BackendImpl backend; Tracing::Register(backend); diff --git a/examples/platform/silabs/sensors/AirQuality/AirQualitySensor.cpp b/examples/platform/silabs/sensors/AirQuality/AirQualitySensor.cpp index 43c5a5573b..e693a26021 100644 --- a/examples/platform/silabs/sensors/AirQuality/AirQualitySensor.cpp +++ b/examples/platform/silabs/sensors/AirQuality/AirQualitySensor.cpp @@ -26,7 +26,6 @@ extern "C" { #endif #include -#include } #include "sl_i2cspm_instances.h" #endif // USE_SPARKFUN_AIR_QUALITY_SENSOR diff --git a/examples/platform/silabs/wifi/icd/ApplicationSleepManager.cpp b/examples/platform/silabs/wifi/icd/ApplicationSleepManager.cpp index cdf32f07e2..5d75e609cb 100644 --- a/examples/platform/silabs/wifi/icd/ApplicationSleepManager.cpp +++ b/examples/platform/silabs/wifi/icd/ApplicationSleepManager.cpp @@ -29,8 +29,6 @@ CHIP_ERROR ApplicationSleepManager::Init() VerifyOrReturnError(mFabricTable != nullptr, CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(AppServer, "FabricTable is null")); VerifyOrReturnError(mSubscriptionsInfoProvider != nullptr, CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(AppServer, "SubscriptionsInfoProvider is null")); - VerifyOrReturnError(mCommissioningWindowManager != nullptr, CHIP_ERROR_INVALID_ARGUMENT, - ChipLogError(AppServer, "CommissioningWindowManager is null")); VerifyOrReturnError(mWifiSleepManager != nullptr, CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(AppServer, "WifiSleepManager is null")); @@ -42,6 +40,18 @@ CHIP_ERROR ApplicationSleepManager::Init() return CHIP_NO_ERROR; } +void ApplicationSleepManager::OnCommissioningWindowOpened() +{ + mIsCommissionningWindowOpen = true; + mWifiSleepManager->VerifyAndTransitionToLowPowerMode(); +} + +void ApplicationSleepManager::OnCommissioningWindowClosed() +{ + mIsCommissionningWindowOpen = false; + mWifiSleepManager->VerifyAndTransitionToLowPowerMode(); +} + void ApplicationSleepManager::OnSubscriptionEstablished(chip::app::ReadHandler & aReadHandler) { mWifiSleepManager->VerifyAndTransitionToLowPowerMode(); @@ -71,10 +81,29 @@ void ApplicationSleepManager::OnFabricCommitted(const chip::FabricTable & fabric bool ApplicationSleepManager::CanGoToLIBasedSleep() { - // TODO: Implement your logic here + bool canGoToLIBasedSleep = true; + + if (mIsCommissionningWindowOpen) + { + ChipLogProgress(AppServer, "Commissioning Window is Open - Cannot go to LI based sleep"); + canGoToLIBasedSleep = false; + } + else + { + for (auto it = mFabricTable->begin(); it != mFabricTable->end(); ++it) + { + if (!mSubscriptionsInfoProvider->FabricHasAtLeastOneActiveSubscription(it->GetFabricIndex())) + { + ChipLogProgress(AppServer, "Fabric index %u has no active subscriptions - Cannot go to LI based sleep", + it->GetFabricIndex()); + canGoToLIBasedSleep = false; + break; + } + ChipLogProgress(AppServer, "All Fabrics have at least 1 active subscription!"); + } + } - ChipLogProgress(AppServer, "CanGoToLIBasedSleep was called!"); - return false; + return canGoToLIBasedSleep; } } // namespace Silabs diff --git a/examples/platform/silabs/wifi/icd/ApplicationSleepManager.h b/examples/platform/silabs/wifi/icd/ApplicationSleepManager.h index 8eba8fcdc4..800c1f980c 100644 --- a/examples/platform/silabs/wifi/icd/ApplicationSleepManager.h +++ b/examples/platform/silabs/wifi/icd/ApplicationSleepManager.h @@ -61,18 +61,26 @@ class ApplicationSleepManager : public chip::app::ReadHandler::ApplicationCallba return *this; } - ApplicationSleepManager & SetCommissioningWindowManager(chip::CommissioningWindowManager * commissioningWindowManager) - { - mCommissioningWindowManager = commissioningWindowManager; - return *this; - } - ApplicationSleepManager & SetWifiSleepManager(chip::DeviceLayer::Silabs::WifiSleepManager * wifiSleepManager) { mWifiSleepManager = wifiSleepManager; return *this; } + /** + * @brief Sets the commissioning window state to open and calls the WifiSleepManager VerifyAndTransitionToLowPowerMode. + * The VerifyAndTransitionToLowPowerMode function is responsible of then queriyng the ApplicationSleepManager to + * determine in which low power state the Wi-Fi device can transition to. + */ + void OnCommissioningWindowOpened(); + + /** + * @brief Sets the commissioning window state to open and calls the WifiSleepManager VerifyAndTransitionToLowPowerMode. + * The VerifyAndTransitionToLowPowerMode function is responsible of then queriyng the ApplicationSleepManager to + * determine in which low power state the Wi-Fi device can transition to. + */ + void OnCommissioningWindowClosed(); + // ReadHandler::ApplicationCallback implementation /** @@ -94,10 +102,14 @@ class ApplicationSleepManager : public chip::app::ReadHandler::ApplicationCallba // WifiSleepManager::ApplicationCallback implementation /** - * @brief TODO + * @brief Function encapsulates the application logic to determine if the Wi-Fi device can go into LI based sleep. * - * @return true - * @return false + * - 1. Check if the commissioning window is open. If it is open, the Wi-Fi device cannot go to LI based sleep. + * - 2. Check if all Fabrics have at least 1 subscription. If there is at least one fabric without a subscription, the + * Wi-Fi cannot go to LI based sleep. + * + * @return true if the device can go to LI sleep + * false if the device cannot go to LI sleep */ bool CanGoToLIBasedSleep() override; @@ -131,6 +143,8 @@ class ApplicationSleepManager : public chip::app::ReadHandler::ApplicationCallba chip::app::SubscriptionsInfoProvider * mSubscriptionsInfoProvider = nullptr; chip::CommissioningWindowManager * mCommissioningWindowManager = nullptr; chip::DeviceLayer::Silabs::WifiSleepManager * mWifiSleepManager = nullptr; + + bool mIsCommissionningWindowOpen = false; }; } // namespace Silabs diff --git a/src/app/ReadHandler.cpp b/src/app/ReadHandler.cpp index 4794ead97e..7861dcc1d5 100644 --- a/src/app/ReadHandler.cpp +++ b/src/app/ReadHandler.cpp @@ -55,8 +55,7 @@ uint16_t ReadHandler::GetPublisherSelectedIntervalLimit() ReadHandler::ReadHandler(ManagementCallback & apCallback, Messaging::ExchangeContext * apExchangeContext, InteractionType aInteractionType, Observer * observer, DataModel::Provider * apDataModel) : - mAttributePathExpandIterator(apDataModel, nullptr), - mExchangeCtx(*this), mManagementCallback(apCallback) + mAttributePathExpandIterator(apDataModel, nullptr), mExchangeCtx(*this), mManagementCallback(apCallback) { VerifyOrDie(apExchangeContext != nullptr); @@ -152,6 +151,7 @@ ReadHandler::~ReadHandler() auto * appCallback = mManagementCallback.GetAppCallback(); if (mFlags.Has(ReadHandlerFlags::ActiveSubscription) && appCallback) { + mFlags.Clear(ReadHandlerFlags::ActiveSubscription); appCallback->OnSubscriptionTerminated(*this); } diff --git a/src/platform/silabs/Logging.cpp b/src/platform/silabs/Logging.cpp index b6345da431..5a2e3b770b 100644 --- a/src/platform/silabs/Logging.cpp +++ b/src/platform/silabs/Logging.cpp @@ -52,13 +52,8 @@ #include "uart.h" #endif -// Enable RTT by default -#ifndef SILABS_LOG_OUT_RTT -#define SILABS_LOG_OUT_RTT 1 -#endif - // SEGGER_RTT includes -#if SILABS_LOG_OUT_RTT +#if !SILABS_LOG_OUT_UART #include "SEGGER_RTT.h" #include "SEGGER_RTT_Conf.h" #endif @@ -137,7 +132,7 @@ static void PrintLog(const char * msg) SEGGER_RTT_WriteNoLock(LOG_RTT_BUFFER_INDEX, msg, sz); #endif // SILABS_LOG_OUT_UART -#if SILABS_LOG_OUT_RTT || PW_RPC_ENABLED +#if !SILABS_LOG_OUT_UART || PW_RPC_ENABLED const char * newline = "\r\n"; sz = strlen(newline); #if PW_RPC_ENABLED @@ -155,7 +150,7 @@ static void PrintLog(const char * msg) extern "C" void silabsInitLog(void) { #if SILABS_LOG_ENABLED -#if SILABS_LOG_OUT_RTT +#if !SILABS_LOG_OUT_UART #if LOG_RTT_BUFFER_INDEX != 0 SEGGER_RTT_ConfigUpBuffer(LOG_RTT_BUFFER_INDEX, LOG_RTT_BUFFER_NAME, sLogBuffer, LOG_RTT_BUFFER_SIZE, SEGGER_RTT_MODE_NO_BLOCK_TRIM); @@ -165,7 +160,7 @@ extern "C" void silabsInitLog(void) #else SEGGER_RTT_SetFlagsUpBuffer(LOG_RTT_BUFFER_INDEX, SEGGER_RTT_MODE_NO_BLOCK_TRIM); #endif -#endif // SILABS_LOG_OUT_RTT +#endif // !SILABS_LOG_OUT_UART #ifdef PW_RPC_ENABLED PigweedLogger::init(); diff --git a/src/platform/silabs/tracing/SilabsTracing.cpp b/src/platform/silabs/tracing/SilabsTracing.cpp index 5291936391..91788b1829 100644 --- a/src/platform/silabs/tracing/SilabsTracing.cpp +++ b/src/platform/silabs/tracing/SilabsTracing.cpp @@ -179,13 +179,13 @@ CHIP_ERROR SilabsTracer::StartWatermarksStorage(PersistentStorageDelegate * stor CHIP_ERROR SilabsTracer::TimeTraceBegin(TimeTraceOperation aOperation) { // Log the start time of the operation - auto & tracker = mLatestTimeTrackers[static_cast(aOperation)]; + auto & tracker = mLatestTimeTrackers[to_underlying(aOperation)]; tracker.mStartTime = System::SystemClock().GetMonotonicTimestamp(); tracker.mOperation = aOperation; tracker.mType = OperationType::kBegin; tracker.mError = CHIP_NO_ERROR; - auto & watermark = mWatermarks[static_cast(aOperation)]; + auto & watermark = mWatermarks[to_underlying(aOperation)]; watermark.mTotalCount++; return OutputTrace(tracker); @@ -193,7 +193,7 @@ CHIP_ERROR SilabsTracer::TimeTraceBegin(TimeTraceOperation aOperation) CHIP_ERROR SilabsTracer::TimeTraceEnd(TimeTraceOperation aOperation, CHIP_ERROR error) { - auto & tracker = mLatestTimeTrackers[static_cast(aOperation)]; + auto & tracker = mLatestTimeTrackers[to_underlying(aOperation)]; tracker.mEndTime = System::SystemClock().GetMonotonicTimestamp(); tracker.mType = OperationType::kEnd; tracker.mError = error; @@ -203,7 +203,7 @@ CHIP_ERROR SilabsTracer::TimeTraceEnd(TimeTraceOperation aOperation, CHIP_ERROR // Calculate the duration and update the time tracker auto duration = tracker.mEndTime - tracker.mStartTime; - auto & watermark = mWatermarks[static_cast(aOperation)]; + auto & watermark = mWatermarks[to_underlying(aOperation)]; watermark.mSuccessfullCount++; watermark.mMovingAverage = System::Clock::Milliseconds32( (watermark.mMovingAverage.count() * (watermark.mSuccessfullCount - 1) + duration.count()) / @@ -287,15 +287,16 @@ CHIP_ERROR SilabsTracer::OutputWaterMark(TimeTraceOperation aOperation) { VerifyOrReturnError(to_underlying(aOperation) < kNumTraces, CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(DeviceLayer, "Invalid TimeTraceOperation")); - size_t index = to_underlying(aOperation); - auto & watermark = mWatermarks[index]; VerifyOrReturnError(isLogInitialized(), CHIP_ERROR_UNINITIALIZED); ChipLogProgress(DeviceLayer, "| Operation: %-25s| MaxTime:%-5" PRIu32 "| MinTime:%-5" PRIu32 "| AvgTime:%-5" PRIu32 "| TotalCount:%-8" PRIu32 ", SuccessFullCount:%-8" PRIu32 "| CountAboveAvg:%-8" PRIu32 "|", - TimeTraceOperationToString(aOperation), watermark.mMaxTimeMs.count(), watermark.mMinTimeMs.count(), - watermark.mMovingAverage.count(), watermark.mTotalCount, watermark.mSuccessfullCount, watermark.mCountAboveAvg); + TimeTraceOperationToString(aOperation), mWatermarks[to_underlying(aOperation)].mMaxTimeMs.count(), + mWatermarks[to_underlying(aOperation)].mMinTimeMs.count(), + mWatermarks[to_underlying(aOperation)].mMovingAverage.count(), + mWatermarks[to_underlying(aOperation)].mTotalCount, mWatermarks[to_underlying(aOperation)].mSuccessfullCount, + mWatermarks[to_underlying(aOperation)].mCountAboveAvg); return CHIP_NO_ERROR; } diff --git a/src/platform/silabs/wifi/SiWx/WifiInterface.cpp b/src/platform/silabs/wifi/SiWx/WifiInterface.cpp index 36bdbf2217..0e8181cc06 100644 --- a/src/platform/silabs/wifi/SiWx/WifiInterface.cpp +++ b/src/platform/silabs/wifi/SiWx/WifiInterface.cpp @@ -298,14 +298,17 @@ sl_status_t ScanCallback(sl_wifi_event_t event, sl_wifi_scan_result_t * scan_res sl_status_t status = SL_STATUS_OK; if (SL_WIFI_CHECK_IF_EVENT_FAILED(event)) { - ChipLogError(DeviceLayer, "Scan Netwrok Failed: 0x%lx", *reinterpret_cast(status)); + if (scan_result != nullptr) + { + status = *reinterpret_cast(scan_result); + ChipLogError(DeviceLayer, "ScanCallback: failed: 0x%lx", static_cast(status)); + } + #if WIFI_ENABLE_SECURITY_WPA3_TRANSITION security = SL_WIFI_WPA3; #else security = SL_WIFI_WPA_WPA2_MIXED; #endif /* WIFI_ENABLE_SECURITY_WPA3_TRANSITION */ - - status = SL_STATUS_FAIL; } else { @@ -408,6 +411,45 @@ sl_status_t SetWifiConfigurations() return status; } +/** + * @brief Callback function for the SL_WIFI_JOIN_EVENTS group + * + * This callback handler will be invoked when any event within join event group occurs, providing the event details and any associated data + * The callback doesn't get called when we join a network using the sl net APIs + * + * @note In case of failure, the 'result' parameter will be of type sl_status_t, and the 'resultLenght' parameter should be ignored + * + * @param[in] event sl_wifi_event_t that triggered the callback + * @param[in] result Pointer to the response data received + * @param[in] result_length Length of the data received in bytes + * @param[in] arg Optional user provided argument + * + * @return sl_status_t Returns the status of the operation + */ +sl_status_t JoinCallback(sl_wifi_event_t event, char * result, uint32_t resultLenght, void * arg) +{ + sl_status_t status = SL_STATUS_OK; + wfx_rsi.dev_state.Clear(WifiState::kStationConnecting); + if (SL_WIFI_CHECK_IF_EVENT_FAILED(event)) + { + status = *reinterpret_cast(result); + ChipLogError(DeviceLayer, "JoinCallback: failed: 0x%lx", static_cast(status)); + wfx_rsi.dev_state.Clear(WifiState::kStationConnected); + wfx_retry_connection(++wfx_rsi.join_retries); + return status; + } + + /* + * Join was complete - Do the DHCP + */ + ChipLogDetail(DeviceLayer, "JoinCallback: success"); + memset(&temp_reset, 0, sizeof(temp_reset)); + + WifiEvent wifievent = WifiEvent::kStationConnect; + sl_matter_wifi_post_event(wifievent); + wfx_rsi.join_retries = 0; + return status; +} sl_status_t JoinWifiNetwork(void) { VerifyOrReturnError(!wfx_rsi.dev_state.HasAny(WifiState::kStationConnecting, WifiState::kStationConnected), @@ -420,6 +462,9 @@ sl_status_t JoinWifiNetwork(void) status = SetWifiConfigurations(); VerifyOrReturnError(status == SL_STATUS_OK, status, ChipLogError(DeviceLayer, "Failure to set the Wifi Configurations!")); + status = sl_wifi_set_join_callback(JoinCallback, nullptr); + VerifyOrReturnError(status == SL_STATUS_OK, status); + status = sl_net_up((sl_net_interface_t) SL_NET_WIFI_CLIENT_INTERFACE, SL_NET_DEFAULT_WIFI_CLIENT_PROFILE_ID); if (status == SL_STATUS_OK || status == SL_STATUS_IN_PROGRESS) @@ -437,16 +482,12 @@ sl_status_t JoinWifiNetwork(void) // failure only happens when the firmware returns an error ChipLogError(DeviceLayer, "sl_wifi_connect failed: 0x%lx", static_cast(status)); - VerifyOrReturnError((wfx_rsi.join_retries <= MAX_JOIN_RETRIES_COUNT), status); wfx_rsi.dev_state.Clear(WifiState::kStationConnecting).Clear(WifiState::kStationConnected); ChipLogProgress(DeviceLayer, "Connection retry attempt %d", wfx_rsi.join_retries); wfx_retry_connection(++wfx_rsi.join_retries); - WifiEvent event = WifiEvent::kStationStartJoin; - sl_matter_wifi_post_event(event); - return status; } diff --git a/third_party/silabs/SiWx917_sdk.gni b/third_party/silabs/SiWx917_sdk.gni index 5843c7faa6..3d22486601 100644 --- a/third_party/silabs/SiWx917_sdk.gni +++ b/third_party/silabs/SiWx917_sdk.gni @@ -334,10 +334,9 @@ template("siwx917_sdk") { } if (sl_uart_log_output) { - defines += [ - "SILABS_LOG_OUT_UART=1", - "SILABS_LOG_OUT_RTT=0", - ] + defines += [ "SILABS_LOG_OUT_UART=1" ] + } else { + defines += [ "SILABS_LOG_OUT_UART=0" ] } if (chip_build_libshell) { # matter shell diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index 40296046cc..a477809326 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -490,10 +490,9 @@ template("efr32_sdk") { } if (sl_uart_log_output) { - defines += [ - "SILABS_LOG_OUT_UART=1", - "SILABS_LOG_OUT_RTT=0", - ] + defines += [ "SILABS_LOG_OUT_UART=1" ] + } else { + defines += [ "SILABS_LOG_OUT_UART=0" ] } if (use_silabs_thread_lib) {