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-ONLY] Move SiWx917 Sleep Calls to the SleepManager class #112

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 24 additions & 21 deletions examples/platform/silabs/BaseApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,25 +182,21 @@ BaseApplicationDelegate BaseApplication::sAppDelegate = BaseApplicationDelegate(
void BaseApplicationDelegate::OnCommissioningSessionStarted()
{
isComissioningStarted = true;

ChipDeviceEvent event = { .Type = DeviceEventType::kCommissioningSessionStarted };
(void) PlatformMgr().PostEvent(&event);
}

void BaseApplicationDelegate::OnCommissioningSessionStopped()
{
isComissioningStarted = false;

ChipDeviceEvent event = { .Type = DeviceEventType::kCommissioningSessionStopped };
(void) PlatformMgr().PostEvent(&event);
}

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, DEEP_SLEEP_WITH_RAM_RETENTION);
if (status != SL_STATUS_OK)
{
ChipLogError(AppServer, "Failed to enable the TA Deep Sleep");
}
}
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917
if (BaseApplication::GetProvisionStatus())
{
// After the device is provisioned and the commissioning passed
Expand All @@ -215,6 +211,15 @@ void BaseApplicationDelegate::OnCommissioningWindowClosed()
#endif // QR_CODE_ENABLED
#endif // DISPLAY_ENABLED
}

ChipDeviceEvent event = { .Type = DeviceEventType::kCommissioningWindowClose };
(void) PlatformMgr().PostEvent(&event);
}

void BaseApplicationDelegate::OnCommissioningWindowOpened()
{
ChipDeviceEvent event = { .Type = DeviceEventType::kCommissioningWindowOpen };
(void) PlatformMgr().PostEvent(&event);
}

void BaseApplicationDelegate::OnFabricCommitted(const FabricTable & fabricTable, FabricIndex fabricIndex)
Expand Down Expand Up @@ -904,35 +909,33 @@ void BaseApplication::OnPlatformEvent(const ChipDeviceEvent * event, intptr_t)
InitOTARequestorHandler, nullptr);
#endif // SILABS_OTA_ENABLED
#if (CHIP_CONFIG_ENABLE_ICD_SERVER && RS911X_WIFI)
#if !SLI_SI917
// [sl-only] Only 9116 - 917 is managed by the SleepManager
// on power cycle, let the device go to sleep after connection is established
if (BaseApplication::sAppDelegate.isCommissioningInProgress() == false)
{
#if SLI_SI917
sl_status_t err = wfx_power_save(RSI_SLEEP_MODE_2, ASSOCIATED_POWER_SAVE);
#else
sl_status_t err = wfx_power_save();
#endif /* SLI_SI917 */
if (err != SL_STATUS_OK)
{
ChipLogError(AppServer, "wfx_power_save failed: 0x%lx", err);
}
}
#endif // !SLI_SI917
#endif /* CHIP_CONFIG_ENABLE_ICD_SERVER && RS911X_WIFI */
}
}
break;

case DeviceEventType::kCommissioningComplete: {
#if (CHIP_CONFIG_ENABLE_ICD_SERVER && RS911X_WIFI)
#if SLI_SI917
sl_status_t err = wfx_power_save(RSI_SLEEP_MODE_2, ASSOCIATED_POWER_SAVE);
#else
sl_status_t err = wfx_power_save();
#endif /* SLI_SI917 */
if (err != SL_STATUS_OK)
#if !SLI_SI917
// [sl-only] Only 9116 - 917 is managed by the SleepManager
sl_status_t status = wfx_power_save();
if (status != SL_STATUS_OK)
{
ChipLogError(AppServer, "wfx_power_save failed: 0x%lx", err);
ChipLogError(AppServer, "wfx_power_save failed: 0x%lx", status);
}
#endif /* !SLI_SI917 */
#endif /* CHIP_CONFIG_ENABLE_ICD_SERVER && RS911X_WIFI */
// SL-Only
#ifdef SL_CATALOG_ZIGBEE_STACK_COMMON_PRESENT
Expand Down
1 change: 1 addition & 0 deletions examples/platform/silabs/BaseApplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ 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 Down
14 changes: 14 additions & 0 deletions examples/platform/silabs/MatterConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
#include <platform/silabs/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.h>
#endif // SLI_SI91X_MCU_INTERFACE

// sl-only: Wi-Fi Sleep Manager support
#if SL_MATTER_SLEEP_MANAGER_ENABLED
#include "SleepManager.h"
#endif // SL_MATTER_SLEEP_MANAGER_ENABLED

#include <crypto/CHIPCryptoPAL.h>
// If building with the EFR32-provided crypto backend, we can use the
// opaque keystore
Expand Down Expand Up @@ -299,6 +304,15 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName)
#endif

initParams.appDelegate = &BaseApplication::sAppDelegate;

#if SL_MATTER_SLEEP_MANAGER_ENABLED
err = DeviceLayer::Silabs::SleepManager::GetInstance()
.SetInteractionModelEngine(app::InteractionModelEngine::GetInstance())
.SetFabricTable(&Server::GetInstance().GetFabricTable())
.Init();
VerifyOrReturnError(err == CHIP_NO_ERROR, err);
#endif // SL_MATTER_SLEEP_MANAGER_ENABLED

// Init Matter Server and Start Event Loop
err = chip::Server::GetInstance().Init(initParams);

Expand Down
4 changes: 4 additions & 0 deletions examples/platform/silabs/efr32/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ source_set("efr32-common") {
]
}

if (chip_enable_icd_server && use_SiWx917) {
public_deps += [ "${silabs_common_plat_dir}/wifi/icd:sleep-manager" ]
}

if (app_data_model != "") {
public_deps += [ app_data_model ]
}
Expand Down
4 changes: 3 additions & 1 deletion examples/platform/silabs/wifi/icd/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import("//build_overrides/chip.gni")

config("sleep-manager-config") {
include_dirs = [ "." ]
defines = []
defines = [ "SL_MATTER_SLEEP_MANAGER_ENABLED=1" ]
}

source_set("sleep-manager") {
Expand All @@ -29,8 +29,10 @@ source_set("sleep-manager") {
"${chip_root}/src/app:app",
"${chip_root}/src/app/icd/server:manager",
"${chip_root}/src/app/icd/server:observer",
"${chip_root}/src/credentials:credentials",
"${chip_root}/src/lib/core",
"${chip_root}/src/lib/support",
"${chip_root}/src/platform/silabs/wifi:wifi-platform",
]

public_configs = [ ":sleep-manager-config" ]
Expand Down
104 changes: 99 additions & 5 deletions examples/platform/silabs/wifi/icd/SleepManager.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "SleepManager.h"
#include <lib/support/logging/CHIPLogging.h>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if the sleep manager should follow the icd states

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the SIT ICD use-case, there isn't much benefit to follow the ICD states other than the basic Fast / slow poll behavior.
Where we need to be synced is with the LIT ICD behavior to optimize the Wi-Fi connectivity based on the ICD operationnal states.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Part of what i mean is that you are using a eventing based on commissioning events (open/close/completed) but really it is the same as following the kCommissioningWindowOpen KeepActiveFlagsValues. I suspect the wifi device will require to listen to not sleep and not filter mdns packets for any KeepActiveFlags

#include <platform/silabs/wifi/WifiInterfaceAbstraction.h>

using namespace chip::app;

Expand All @@ -11,10 +13,37 @@ SleepManager SleepManager::mInstance;

CHIP_ERROR SleepManager::Init()
{
// Initialization logic
VerifyOrReturnError(mIMEngine != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(mFabricTable != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

mIMEngine->RegisterReadHandlerAppCallback(this);
mFabricTable->AddFabricDelegate(this);

PlatformMgr().AddEventHandler(OnPlatformEvent, reinterpret_cast<intptr_t>(this));

return CHIP_NO_ERROR;
}

void SleepManager::OnSubscriptionEstablished(ReadHandler & aReadHandler)
{
// Implement logic for when a subscription is established
}

void SleepManager::OnSubscriptionTerminated(ReadHandler & aReadHandler)
{
// Implement logic for when a subscription is terminated
}

void SleepManager::OnFabricRemoved(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex)
{
// Implement logic for when a fabric is removed
}

void SleepManager::OnFabricCommitted(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex)
{
// Implement logic for when a fabric is committed
}

void SleepManager::OnEnterActiveMode()
{
// Execution logic for entering active mode
Expand All @@ -25,14 +54,79 @@ void SleepManager::OnEnterIdleMode()
// Execution logic for entering idle mode
}

void SleepManager::OnSubscriptionEstablished(ReadHandler & aReadHandler)
void SleepManager::HandleCommissioningComplete()
{
// Implement logic for when a subscription is established
if (wfx_power_save(RSI_SLEEP_MODE_2, ASSOCIATED_POWER_SAVE) != SL_STATUS_OK)
{
ChipLogError(AppServer, "wfx_power_save failed");
}
}

void SleepManager::OnSubscriptionTerminated(ReadHandler & aReadHandler)
void SleepManager::HandleInternetConnectivityChange(const ChipDeviceEvent * event)
{
// Implement logic for when a subscription is terminated
if (event->InternetConnectivityChange.IPv6 == kConnectivity_Established)
{
if (!IsCommissioningInProgress())
{
if (wfx_power_save(RSI_SLEEP_MODE_2, ASSOCIATED_POWER_SAVE) != SL_STATUS_OK)
{
ChipLogError(AppServer, "wfx_power_save failed");
}
}
}
}

void SleepManager::HandleCommissioningWindowClose()
{
if (!ConnectivityMgr().IsWiFiStationProvisioned() && !IsCommissioningInProgress())
{
if (wfx_power_save(RSI_SLEEP_MODE_8, DEEP_SLEEP_WITH_RAM_RETENTION) != SL_STATUS_OK)
{
ChipLogError(AppServer, "Failed to enable the TA Deep Sleep");
}
}
}

void SleepManager::HandleCommissioningSessionStarted()
{
SetCommissioningInProgress(true);
}

void SleepManager::HandleCommissioningSessionStopped()
{
SetCommissioningInProgress(false);
}

void SleepManager::OnPlatformEvent(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg)
{
SleepManager * manager = reinterpret_cast<SleepManager *>(arg);
VerifyOrDie(manager != nullptr);

switch (event->Type)
{
case DeviceEventType::kCommissioningComplete:
manager->HandleCommissioningComplete();
break;

case DeviceEventType::kInternetConnectivityChange:
manager->HandleInternetConnectivityChange(event);
break;

case DeviceEventType::kCommissioningWindowClose:
manager->HandleCommissioningWindowClose();
break;

case DeviceEventType::kCommissioningSessionStarted:
manager->HandleCommissioningSessionStarted();
break;

case DeviceEventType::kCommissioningSessionStopped:
manager->HandleCommissioningSessionStopped();
break;

default:
break;
}
}

} // namespace Silabs
Expand Down
59 changes: 55 additions & 4 deletions examples/platform/silabs/wifi/icd/SleepManager.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@

#pragma once

#include <app/InteractionModelEngine.h>
#include <app/ReadHandler.h>
#include <app/icd/server/ICDManager.h>
#include <app/icd/server/ICDStateObserver.h>
#include <credentials/FabricTable.h>
#include <lib/core/CHIPError.h>

namespace chip {
Expand All @@ -18,7 +19,9 @@ namespace Silabs {
* For SIT ICDs, the logic is based on the Subscriptions established with the device.
* For LIT ICDs, the logic is based on the ICDManager operating modes. The LIT mode also utilizes the SIT mode logic.
*/
class SleepManager : public chip::app::ICDStateObserver, public chip::app::ReadHandler::ApplicationCallback
class SleepManager : public chip::app::ICDStateObserver,
public chip::app::ReadHandler::ApplicationCallback,
public chip::FabricTable::Delegate
{
public:
SleepManager(const SleepManager &) = delete;
Expand All @@ -37,23 +40,71 @@ class SleepManager : public chip::app::ICDStateObserver, public chip::app::ReadH
*/
CHIP_ERROR Init();

SleepManager & SetInteractionModelEngine(chip::app::InteractionModelEngine * engine)
{
mIMEngine = engine;
return *this;
}

SleepManager & SetFabricTable(chip::FabricTable * fabricTable)
{
mFabricTable = fabricTable;
return *this;
}

// ICDStateObserver implementation overrides

void OnEnterActiveMode();
void OnEnterIdleMode();
void OnTransitionToIdle() { /* No execution logic */ }
void OnICDModeChange() { /* No execution logic */ }
void OnTransitionToIdle()
{ /* No execution logic */
}
void OnICDModeChange()
{ /* No execution logic */
}

// ReadHandler::ApplicationCallback implementation overrides

void OnSubscriptionEstablished(chip::app::ReadHandler & aReadHandler);
void OnSubscriptionTerminated(chip::app::ReadHandler & aReadHandler);

// FabricTable::Delegate implementation overrides
void FabricWillBeRemoved(const chip::FabricTable & fabricTable,
chip::FabricIndex fabricIndex) override{ /* No execution logic */ };
void OnFabricRemoved(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex) override;
void OnFabricCommitted(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex) override;
void OnFabricUpdated(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex) override{ /* No execution logic*/ };

static void OnPlatformEvent(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg);

/**
* @brief Set the commissioning status of the device
*
* @param[in] inProgress bool true if commissioning is in progress, false otherwise
*/
void SetCommissioningInProgress(bool inProgress) { isCommissioningInProgress = inProgress; }

/**
* @brief Returns the current commissioning status of the device
*
* @return bool true if commissioning is in progress, false otherwise
*/
bool IsCommissioningInProgress() { return isCommissioningInProgress; }

private:
SleepManager() = default;
~SleepManager() = default;

void HandleCommissioningComplete();
void HandleInternetConnectivityChange(const chip::DeviceLayer::ChipDeviceEvent * event);
void HandleCommissioningWindowClose();
void HandleCommissioningSessionStarted();
void HandleCommissioningSessionStopped();

static SleepManager mInstance;
chip::app::InteractionModelEngine * mIMEngine = nullptr;
chip::FabricTable * mFabricTable = nullptr;
bool isCommissioningInProgress = false;
};

} // namespace Silabs
Expand Down
5 changes: 4 additions & 1 deletion src/platform/silabs/CHIPDevicePlatformEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ namespace DeviceEventType {
*/
enum PublicPlatformSpecificEventTypes
{
/* None currently defined */
kCommissioningWindowOpen = kRange_PublicPlatformSpecific,
kCommissioningWindowClose,
kCommissioningSessionStarted,
kCommissioningSessionStopped,
};

/**
Expand Down
Loading
Loading