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

[Silabs] Update ThreadStackManagerImpl #34389

Merged
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
86 changes: 76 additions & 10 deletions examples/platform/silabs/BaseApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#if CHIP_ENABLE_OPENTHREAD
#include <platform/OpenThread/OpenThreadUtils.h>
#include <platform/ThreadStackManager.h>
#include <platform/silabs/ConfigurationManagerImpl.h>
#include <platform/silabs/ThreadStackManagerImpl.h>
#endif // CHIP_ENABLE_OPENTHREAD

Expand Down Expand Up @@ -115,9 +116,10 @@ app::Clusters::NetworkCommissioning::Instance
sWiFiNetworkCommissioningInstance(0 /* Endpoint Id */, &(NetworkCommissioning::SlWiFiDriver::GetInstance()));
#endif /* SL_WIFI */

bool sIsEnabled = false;
bool sIsAttached = false;

#if !(defined(CHIP_CONFIG_ENABLE_ICD_SERVER) && CHIP_CONFIG_ENABLE_ICD_SERVER)
bool sIsEnabled = false;
bool sIsAttached = false;
bool sHaveBLEConnections = false;
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER

Expand Down Expand Up @@ -156,14 +158,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
bool BaseApplication::sIsProvisioned = false;
bool BaseApplication::sIsFactoryResetTriggered = false;
LEDWidget * BaseApplication::sAppActionLed = nullptr;
BaseApplicationDelegate BaseApplication::sAppDelegate = BaseApplicationDelegate();
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917

#ifdef DIC_ENABLE
namespace {
Expand All @@ -181,17 +182,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);
Expand All @@ -200,8 +203,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
Expand Down Expand Up @@ -298,6 +320,8 @@ CHIP_ERROR BaseApplication::Init()
#if CHIP_ENABLE_OPENTHREAD
BaseApplication::sIsProvisioned = ConnectivityMgr().IsThreadProvisioned();
#endif

err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(&sAppDelegate);
return err;
}

Expand Down Expand Up @@ -411,6 +435,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()
{
Expand Down Expand Up @@ -750,15 +791,40 @@ 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
ConfigurationManagerImpl::GetDefaultInstance().ClearThreadStack();
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;
}
}
Expand Down
24 changes: 19 additions & 5 deletions examples/platform/silabs/BaseApplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <app/util/config.h>
#include <ble/Ble.h>
#include <cmsis_os2.h>
#include <credentials/FabricTable.h>
#include <lib/core/CHIPError.h>
#include <platform/CHIPDeviceEvent.h>
#include <platform/CHIPDeviceLayer.h>
Expand Down Expand Up @@ -62,16 +63,19 @@
#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
Expand All @@ -86,9 +90,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
Expand Down Expand Up @@ -156,6 +158,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, 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();

protected:
CHIP_ERROR Init();

Expand Down
15 changes: 8 additions & 7 deletions examples/platform/silabs/MatterConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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("==================================================");
Expand All @@ -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

Expand Down Expand Up @@ -304,9 +307,7 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName)
initParams.endpointNativeParams = static_cast<void *>(&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);

Expand Down
6 changes: 6 additions & 0 deletions examples/platform/silabs/efr32/uart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions examples/platform/silabs/matter-platform.slcp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1088,29 +1088,21 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::_GetPollPeriod(u
return CHIP_NO_ERROR;
}

/**
* @brief Helper that sets callbacks for OpenThread state changes and configures the Thread stack.
* 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.
*
* @param otInst Pointer to the OT instance
* @return CHIP_ERROR OpenThread error mapped to CHIP_ERROR
*/
template <class ImplClass>
CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::DoInit(otInstance * otInst)
CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::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
Expand Down Expand Up @@ -1146,14 +1138,42 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::DoInit(otInstanc
}
#endif

initNetworkCommissioningThreadDriver();

exit:

ChipLogProgress(DeviceLayer, "OpenThread started: %s", otThreadErrorToString(otErr));
return err;
}

template <class ImplClass>
CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::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 <class ImplClass>
bool GenericThreadStackManagerImpl_OpenThread<ImplClass>::IsThreadAttachedNoLock(void)
{
Expand Down
Loading
Loading