Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SL-UP] Add application callback to allow the application to inject logic #116

Merged
merged 10 commits into from
Nov 20, 2024
10 changes: 2 additions & 8 deletions examples/platform/silabs/BaseApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,8 @@ void BaseApplicationDelegate::OnCommissioningWindowClosed()
#endif // QR_CODE_ENABLED
#endif // DISPLAY_ENABLED
}

#if SL_WIFI && CHIP_CONFIG_ENABLE_ICD_SERVER
WifiSleepManager::GetInstance().HandleCommissioningWindowClose();
#endif // SL_WIFI && CHIP_CONFIG_ENABLE_ICD_SERVER
}

void BaseApplicationDelegate::OnCommissioningWindowOpened() {}

void BaseApplicationDelegate::OnFabricCommitted(const FabricTable & fabricTable, FabricIndex fabricIndex)
{
// If we commissioned our first fabric, Update the commissioned status of the App
Expand Down Expand Up @@ -905,7 +899,7 @@ void BaseApplication::OnPlatformEvent(const ChipDeviceEvent * event, intptr_t)
#if SL_WIFI
chip::app::DnssdServer::Instance().StartServer();
#if CHIP_CONFIG_ENABLE_ICD_SERVER
WifiSleepManager::GetInstance().HandleInternetConnectivityChange();
WifiSleepManager::GetInstance().VerifyAndTransitionToLowPowerMode();
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
#endif // SL_WIFI

Expand All @@ -920,7 +914,7 @@ void BaseApplication::OnPlatformEvent(const ChipDeviceEvent * event, intptr_t)

case DeviceEventType::kCommissioningComplete: {
#if SL_WIFI && CHIP_CONFIG_ENABLE_ICD_SERVER
WifiSleepManager::GetInstance().HandleCommissioningComplete();
WifiSleepManager::GetInstance().VerifyAndTransitionToLowPowerMode();
#endif // SL_WIFI && CHIP_CONFIG_ENABLE_ICD_SERVER

// SL-Only
Expand Down
3 changes: 1 addition & 2 deletions examples/platform/silabs/BaseApplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ class BaseApplicationDelegate : public AppDelegate, public chip::FabricTable::De
private:
// AppDelegate
bool isComissioningStarted = false;
void OnCommissioningWindowOpened() override;
void OnCommissioningSessionStarted() override;
void OnCommissioningSessionStopped() override;
void OnCommissioningWindowClosed() override;
Expand All @@ -90,7 +89,7 @@ class BaseApplication

public:
BaseApplication() = default;
virtual ~BaseApplication(){};
virtual ~BaseApplication() {};
static bool sIsProvisioned;
static bool sIsFactoryResetTriggered;
static LEDWidget * sAppActionLed;
Expand Down
33 changes: 27 additions & 6 deletions src/platform/silabs/wifi/SiWx/WifiInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,16 @@ extern "C" {
#include <platform/silabs/wifi/rs911x/platform/sl_board_configuration.h>
#endif

#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI91X_MCU_INTERFACE
#if CHIP_CONFIG_ENABLE_ICD_SERVER
#include <platform/silabs/wifi/icd/WifiSleepManager.h>

#if SLI_SI91X_MCU_INTERFACE
#include "rsi_rom_power_save.h"
#include "sl_gpio_board.h"
#include "sl_si91x_driver_gpio.h"
#include "sl_si91x_power_manager.h"
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI91X_MCU_INTERFACE
#endif // SLI_SI91X_MCU_INTERFACE
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER

WfxRsi_t wfx_rsi;
extern osSemaphoreId_t sl_rs_ble_init_sem;
Expand Down Expand Up @@ -418,7 +422,11 @@ sl_status_t JoinWifiNetwork(void)

if (status == SL_STATUS_OK || status == SL_STATUS_IN_PROGRESS)
{
// TODO: Set listen interval to 0 with DTIM sync
#if CHIP_CONFIG_ENABLE_ICD_SERVER
// TODO: We need a way to identify if this was a retry or a first attempt connect to avoid removing a req that was not ours
// Remove High performance request that might have been added during the retry process
chip::DeviceLayer::Silabs::WifiSleepManager::GetInstance().RemoveHighPerformanceRequest();
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER

WifiEvent event = WifiEvent::kStationConnect;
sl_matter_wifi_post_event(event);
Expand Down Expand Up @@ -865,9 +873,8 @@ void wfx_dhcp_got_ipv4(uint32_t ip)
#endif /* CHIP_DEVICE_CONFIG_ENABLE_IPV4 */

#if CHIP_CONFIG_ENABLE_ICD_SERVER

sl_status_t wfx_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state,
uint32_t listenInterval)
sl_status_t ConfigurePowerSave(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state,
uint32_t listenInterval)
{
int32_t error = rsi_bt_power_save_profile(sl_si91x_ble_state, 0);
VerifyOrReturnError(error == RSI_SUCCESS, SL_STATUS_FAIL,
Expand All @@ -885,4 +892,18 @@ sl_status_t wfx_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_

return status;
}

sl_status_t ConfigureBroadcastFilter(bool enableBroadcastFilter)
{
sl_status_t status = SL_STATUS_OK;

uint16_t beaconDropThreshold = (enableBroadcastFilter) ? kTimeToFullBeaconReception : 0;
uint8_t filterBcastInTim = (enableBroadcastFilter) ? 1 : 0;

status = sl_wifi_filter_broadcast(beaconDropThreshold, filterBcastInTim, 1 /* valid till next update*/);
VerifyOrReturnError(status == SL_STATUS_OK, status,
ChipLogError(DeviceLayer, "sl_wifi_filter_broadcast failed: 0x%lx", static_cast<uint32_t>(status)));

return status;
}
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
8 changes: 8 additions & 0 deletions src/platform/silabs/wifi/WifiInterfaceAbstraction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ void wfx_retry_connection(uint16_t retryAttempt)
{
retryInterval = kWlanMaxRetryIntervalsInSec;
}

if (osTimerStart(sRetryTimer, pdMS_TO_TICKS(CONVERT_SEC_TO_MS(retryInterval))) != osOK)
{
ChipLogProgress(DeviceLayer, "Failed to start retry timer");
Expand All @@ -194,11 +195,18 @@ void wfx_retry_connection(uint16_t retryAttempt)
{
ChipLogError(DeviceLayer, "wfx_connect_to_ap() failed.");
}

#if CHIP_CONFIG_ENABLE_ICD_SERVER
// Remove High performance request before giving up due to a timer start error to save battery life
Silabs::WifiSleepManager::GetInstance().RemoveHighPerformanceRequest();
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
return;
}

#if CHIP_CONFIG_ENABLE_ICD_SERVER
Silabs::WifiSleepManager::GetInstance().RemoveHighPerformanceRequest();
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER

ChipLogProgress(DeviceLayer, "wfx_retry_connection : Next attempt after %d Seconds", retryInterval);
retryInterval += retryInterval;
}
14 changes: 11 additions & 3 deletions src/platform/silabs/wifi/WifiInterfaceAbstraction.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,20 @@ bool wfx_hw_ready(void);
#ifdef RS911X_WIFI // for RS9116, 917 NCP and 917 SoC
/* RSI Power Save */
#if (SLI_SI91X_MCU_INTERFACE | EXP_BOARD)
sl_status_t wfx_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state,
uint32_t listenInterval);
sl_status_t ConfigurePowerSave(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state,
uint32_t listenInterval);
#else
sl_status_t wfx_power_save();
sl_status_t ConfigurePowerSave();
#endif /* (SLI_SI91X_MCU_INTERFACE | EXP_BOARD) */
#endif /* RS911X_WIFI */

/**
* @brief Configures the broadcast filter.
*
* @param[in] enableBroadcastFilter Boolean to enable or disable the broadcast filter.
* @return sl_status_t Returns the status of the operation.
*/
sl_status_t ConfigureBroadcastFilter(bool enableBroadcastFilter);
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER

void sl_matter_wifi_task(void * arg);
Expand Down
100 changes: 54 additions & 46 deletions src/platform/silabs/wifi/icd/WifiSleepManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
#include <platform/silabs/wifi/WifiInterfaceAbstraction.h>
#include <platform/silabs/wifi/icd/WifiSleepManager.h>

using namespace chip::app;

namespace chip {
namespace DeviceLayer {
namespace Silabs {
Expand All @@ -34,46 +32,16 @@ CHIP_ERROR WifiSleepManager::Init()
return CHIP_NO_ERROR;
}

void WifiSleepManager::HandleCommissioningComplete()
{
VerifyAndTransitionToLowPowerMode();
}

void WifiSleepManager::HandleInternetConnectivityChange()
{
// TODO: Centralize the buisness logic in the VerifyAndTransitionToLowPowerMode
if (!isCommissioningInProgress)
{
VerifyAndTransitionToLowPowerMode();
}
}

void WifiSleepManager::HandleCommissioningWindowClose() {}

void WifiSleepManager::HandleCommissioningSessionStarted()
{
isCommissioningInProgress = true;
}

void WifiSleepManager::HandleCommissioningSessionStopped()
{
isCommissioningInProgress = false;
}

CHIP_ERROR WifiSleepManager::RequestHighPerformance()
{
VerifyOrReturnError(mHighPerformanceRequestCounter < std::numeric_limits<uint8_t>::max(), CHIP_ERROR_INTERNAL,
ChipLogError(DeviceLayer, "High performance request counter overflow"));

if (mHighPerformanceRequestCounter == 0)
{
#if SLI_SI917 // 917 SoC & NCP
VerifyOrReturnError(wfx_power_save(RSI_ACTIVE, HIGH_PERFORMANCE, 0) == SL_STATUS_OK, CHIP_ERROR_INTERNAL,
ChipLogError(DeviceLayer, "Failed to set Wi-FI configuration to HighPerformance"));
#endif // SLI_SI917
}

mHighPerformanceRequestCounter++;

// We don't do the mHighPerformanceRequestCounter check here; the check is in TransitionToLowPowerMode function
ReturnErrorOnFailure(VerifyAndTransitionToLowPowerMode());
lpbeliveau-silabs marked this conversation as resolved.
Show resolved Hide resolved

return CHIP_NO_ERROR;
}

Expand All @@ -92,31 +60,71 @@ CHIP_ERROR WifiSleepManager::RemoveHighPerformanceRequest()

CHIP_ERROR WifiSleepManager::VerifyAndTransitionToLowPowerMode()
{
VerifyOrReturnValue(mHighPerformanceRequestCounter == 0, CHIP_NO_ERROR,
ChipLogDetail(DeviceLayer, "High Performance Requested - Device cannot go to a lower power mode."));

#if SLI_SI917 // 917 SoC & NCP
if (mHighPerformanceRequestCounter > 0)
{
return ConfigureHighPerformance();
}

if (mIsCommissioningInProgress)
{
return ConfigureDTIMBasedSleep();
}

// TODO: Clean this up when the Wi-Fi interface re-work is finished
wfx_wifi_provision_t wifiConfig;
wfx_get_wifi_provision(&wifiConfig);

if (!(wifiConfig.ssid[0] != 0) && !isCommissioningInProgress)
if (!(wifiConfig.ssid[0] != 0))
lpbeliveau-silabs marked this conversation as resolved.
Show resolved Hide resolved
{
VerifyOrReturnError(wfx_power_save(RSI_SLEEP_MODE_8, DEEP_SLEEP_WITH_RAM_RETENTION, 0) != SL_STATUS_OK, CHIP_ERROR_INTERNAL,
ChipLogError(DeviceLayer, "Failed to enable Deep Sleep."));
return ConfigurePowerSave(RSI_SLEEP_MODE_8, DEEP_SLEEP_WITH_RAM_RETENTION, 0);
}
else

if (mCallback && mCallback->CanGoToLIBasedSleep())
{
VerifyOrReturnError(wfx_power_save(RSI_SLEEP_MODE_2, ASSOCIATED_POWER_SAVE, 0) != SL_STATUS_OK, CHIP_ERROR_INTERNAL,
ChipLogError(DeviceLayer, "Failed to enable to go to sleep."));
return ConfigureLIBasedSleep();
}

return ConfigureDTIMBasedSleep();

#elif RS911X_WIFI // rs9116
VerifyOrReturnError(wfx_power_save() != SL_STATUS_OK, CHIP_ERROR_INTERNAL,
ChipLogError(DeviceLayer, "Failed to enable to go to sleep."));
VerifyOrReturnError(ConfigurePowerSave() == SL_STATUS_OK, CHIP_ERROR_INTERNAL);
return CHIP_NO_ERROR;
#endif
}

#if SLI_SI917 // 917 SoC & NCP
CHIP_ERROR WifiSleepManager::ConfigureLIBasedSleep()
{
VerifyOrReturnError(ConfigurePowerSave(RSI_SLEEP_MODE_2, ASSOCIATED_POWER_SAVE,
ICDConfigurationData::GetInstance().GetSlowPollingInterval().count()) == SL_STATUS_OK,
CHIP_ERROR_INTERNAL, ChipLogError(DeviceLayer, "Failed to enable LI based sleep."));

VerifyOrReturnError(ConfigureBroadcastFilter(true) == SL_STATUS_OK, CHIP_ERROR_INTERNAL,
ChipLogError(DeviceLayer, "Failed to configure broadcasts filter."));

return CHIP_NO_ERROR;
}

CHIP_ERROR WifiSleepManager::ConfigureDTIMBasedSleep()
{
VerifyOrReturnError(ConfigurePowerSave(RSI_SLEEP_MODE_2, ASSOCIATED_POWER_SAVE, 0) == SL_STATUS_OK, CHIP_ERROR_INTERNAL,
ChipLogError(DeviceLayer, "Failed to enable to enable DTIM basedsleep."));

VerifyOrReturnError(ConfigureBroadcastFilter(false) == SL_STATUS_OK, CHIP_ERROR_INTERNAL,
ChipLogError(DeviceLayer, "Failed to configure broadcast filter."));

return CHIP_NO_ERROR;
}

CHIP_ERROR WifiSleepManager::ConfigureHighPerformance()
{
VerifyOrReturnError(ConfigurePowerSave(RSI_ACTIVE, HIGH_PERFORMANCE, 0) == SL_STATUS_OK, CHIP_ERROR_INTERNAL,
ChipLogError(DeviceLayer, "Failed to set Wi-FI configuration to HighPerformance."));
return CHIP_NO_ERROR;
}
#endif // SLI_SI917

} // namespace Silabs
} // namespace DeviceLayer
Expand Down
Loading
Loading