From ddca34c4e3a7d7a7fae45760054327007116c03c Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 13 Apr 2023 14:45:56 -0400 Subject: [PATCH 01/23] Improve the Darwin logging when we cancel dns-sd browse/resolve operations. (#26072) Right now we are treating those as "timeout" and logging that, which really confuses people reading the logs. We should log them as cancellations instead. There's no obvious kDNSServiceErr_* value for "cancelled", so allow doing GenericContext::Finalize with a CHIP_ERROR. --- src/platform/Darwin/DnssdContexts.cpp | 36 +++++++++++++++++---------- src/platform/Darwin/DnssdImpl.cpp | 14 +++++------ src/platform/Darwin/DnssdImpl.h | 15 +++++++---- 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/platform/Darwin/DnssdContexts.cpp b/src/platform/Darwin/DnssdContexts.cpp index ebc1079b3fb32b..832b33637d88fa 100644 --- a/src/platform/Darwin/DnssdContexts.cpp +++ b/src/platform/Darwin/DnssdContexts.cpp @@ -112,17 +112,17 @@ DNSServiceProtocol GetProtocol(const chip::Inet::IPAddressType & addressType) namespace chip { namespace Dnssd { -CHIP_ERROR GenericContext::Finalize(DNSServiceErrorType err) +CHIP_ERROR GenericContext::FinalizeInternal(const char * errorStr, CHIP_ERROR err) { if (MdnsContexts::GetInstance().Has(this) == CHIP_NO_ERROR) { - if (kDNSServiceErr_NoError == err) + if (CHIP_NO_ERROR == err) { DispatchSuccess(); } else { - DispatchFailure(err); + DispatchFailure(errorStr, err); } } else @@ -130,7 +130,17 @@ CHIP_ERROR GenericContext::Finalize(DNSServiceErrorType err) chip::Platform::Delete(this); } - return Error::ToChipError(err); + return err; +} + +CHIP_ERROR GenericContext::Finalize(CHIP_ERROR err) +{ + return FinalizeInternal(err.AsString(), err); +} + +CHIP_ERROR GenericContext::Finalize(DNSServiceErrorType err) +{ + return FinalizeInternal(Error::ToString(err), Error::ToChipError(err)); } MdnsContexts::~MdnsContexts() @@ -289,10 +299,10 @@ RegisterContext::RegisterContext(const char * sType, const char * instanceName, mInstanceName = instanceName; } -void RegisterContext::DispatchFailure(DNSServiceErrorType err) +void RegisterContext::DispatchFailure(const char * errorStr, CHIP_ERROR err) { - ChipLogError(Discovery, "Mdns: Register failure (%s)", Error::ToString(err)); - callback(context, nullptr, nullptr, Error::ToChipError(err)); + ChipLogError(Discovery, "Mdns: Register failure (%s)", errorStr); + callback(context, nullptr, nullptr, err); MdnsContexts::GetInstance().Remove(this); } @@ -316,10 +326,10 @@ BrowseContext::BrowseContext(void * cbContext, DnssdBrowseCallback cb, DnssdServ protocol = cbContextProtocol; } -void BrowseContext::DispatchFailure(DNSServiceErrorType err) +void BrowseContext::DispatchFailure(const char * errorStr, CHIP_ERROR err) { - ChipLogError(Discovery, "Mdns: Browse failure (%s)", Error::ToString(err)); - callback(context, nullptr, 0, true, Error::ToChipError(err)); + ChipLogError(Discovery, "Mdns: Browse failure (%s)", errorStr); + callback(context, nullptr, 0, true, err); MdnsContexts::GetInstance().Remove(this); } @@ -353,14 +363,14 @@ ResolveContext::ResolveContext(void * cbContext, DnssdResolveCallback cb, chip:: ResolveContext::~ResolveContext() {} -void ResolveContext::DispatchFailure(DNSServiceErrorType err) +void ResolveContext::DispatchFailure(const char * errorStr, CHIP_ERROR err) { - ChipLogError(Discovery, "Mdns: Resolve failure (%s)", Error::ToString(err)); + ChipLogError(Discovery, "Mdns: Resolve failure (%s)", errorStr); // Remove before dispatching, so calls back into // ChipDnssdResolveNoLongerNeeded don't find us and try to also remove us. bool needDelete = MdnsContexts::GetInstance().RemoveWithoutDeleting(this); - callback(context, nullptr, Span(), Error::ToChipError(err)); + callback(context, nullptr, Span(), err); if (needDelete) { diff --git a/src/platform/Darwin/DnssdImpl.cpp b/src/platform/Darwin/DnssdImpl.cpp index d859f2b8d1391d..acf65e09511534 100644 --- a/src/platform/Darwin/DnssdImpl.cpp +++ b/src/platform/Darwin/DnssdImpl.cpp @@ -465,11 +465,11 @@ CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) return CHIP_ERROR_NOT_FOUND; } - // Just treat this as a timeout error. Don't bother delivering the partial + // We have been canceled. Don't bother delivering the partial // results we have queued up in the BrowseContext, if any. In practice // there shouldn't be anything there long-term anyway. // - // Make sure to time out all the resolves first, before we time out the + // Make sure to cancel all the resolves first, before we cancel the // browse (just to avoid dangling pointers in the resolves, even though we // only use them for equality compares). std::vector resolves; @@ -481,10 +481,10 @@ CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) for (auto & resolve : resolves) { - resolve->Finalize(kDNSServiceErr_Timeout); + resolve->Finalize(CHIP_ERROR_CANCELLED); } - ctx->Finalize(kDNSServiceErr_Timeout); + ctx->Finalize(CHIP_ERROR_CANCELLED); return CHIP_NO_ERROR; } @@ -511,11 +511,11 @@ void ChipDnssdResolveNoLongerNeeded(const char * instanceName) if (*existingCtx->consumerCounter == 0) { // No more consumers; clear out all of these resolves so they don't - // stick around. Dispatch timeout failure on all of them to make sure - // whatever kicked them off cleans up resources as needed. + // stick around. Dispatch a "cancelled" failure on all of them to make + // sure whatever kicked them off cleans up resources as needed. do { - existingCtx->Finalize(kDNSServiceErr_Timeout); + existingCtx->Finalize(CHIP_ERROR_CANCELLED); existingCtx = MdnsContexts::GetInstance().GetExistingResolveForInstanceName(instanceName); } while (existingCtx != nullptr); } diff --git a/src/platform/Darwin/DnssdImpl.h b/src/platform/Darwin/DnssdImpl.h index 42f5d246ecb6fc..d599b052cdb1f6 100644 --- a/src/platform/Darwin/DnssdImpl.h +++ b/src/platform/Darwin/DnssdImpl.h @@ -44,9 +44,14 @@ struct GenericContext virtual ~GenericContext() {} + CHIP_ERROR Finalize(CHIP_ERROR err); CHIP_ERROR Finalize(DNSServiceErrorType err = kDNSServiceErr_NoError); - virtual void DispatchFailure(DNSServiceErrorType err) = 0; - virtual void DispatchSuccess() = 0; + + virtual void DispatchFailure(const char * errorStr, CHIP_ERROR err) = 0; + virtual void DispatchSuccess() = 0; + +private: + CHIP_ERROR FinalizeInternal(const char * errorStr, CHIP_ERROR err); }; struct RegisterContext; @@ -130,7 +135,7 @@ struct RegisterContext : public GenericContext RegisterContext(const char * sType, const char * instanceName, DnssdPublishCallback cb, void * cbContext); virtual ~RegisterContext() { mHostNameRegistrar.Unregister(); } - void DispatchFailure(DNSServiceErrorType err) override; + void DispatchFailure(const char * errorStr, CHIP_ERROR err) override; void DispatchSuccess() override; bool matches(const char * sType) { return mType.compare(sType) == 0; } @@ -145,7 +150,7 @@ struct BrowseContext : public GenericContext BrowseContext(void * cbContext, DnssdBrowseCallback cb, DnssdServiceProtocol cbContextProtocol); virtual ~BrowseContext() {} - void DispatchFailure(DNSServiceErrorType err) override; + void DispatchFailure(const char * errorStr, CHIP_ERROR err) override; void DispatchSuccess() override; // Dispatch what we have found so far, but don't stop browsing. @@ -195,7 +200,7 @@ struct ResolveContext : public GenericContext std::shared_ptr && consumerCounterToUse); virtual ~ResolveContext(); - void DispatchFailure(DNSServiceErrorType err) override; + void DispatchFailure(const char * errorStr, CHIP_ERROR err) override; void DispatchSuccess() override; CHIP_ERROR OnNewAddress(uint32_t interfaceId, const struct sockaddr * address); From e1f306f84d815d3b49b10292c48880fa81662cb7 Mon Sep 17 00:00:00 2001 From: Jean-Francois Penven <67962328+jepenven-silabs@users.noreply.github.com> Date: Thu, 13 Apr 2023 15:41:21 -0400 Subject: [PATCH 02/23] Rename credentials define (#26089) --- examples/chef/efr32/src/main.cpp | 4 ++-- examples/light-switch-app/silabs/SiWx917/src/main.cpp | 4 ++-- examples/light-switch-app/silabs/efr32/src/main.cpp | 4 ++-- examples/lighting-app/silabs/SiWx917/src/main.cpp | 4 ++-- examples/lighting-app/silabs/efr32/src/main.cpp | 4 ++-- examples/lock-app/silabs/SiWx917/src/main.cpp | 4 ++-- examples/lock-app/silabs/efr32/src/main.cpp | 4 ++-- examples/platform/silabs/SiWx917/BUILD.gn | 2 +- examples/platform/silabs/efr32/BUILD.gn | 2 +- examples/thermostat/silabs/efr32/src/main.cpp | 4 ++-- examples/window-app/silabs/SiWx917/src/main.cpp | 4 ++-- examples/window-app/silabs/efr32/src/main.cpp | 4 ++-- 12 files changed, 22 insertions(+), 22 deletions(-) diff --git a/examples/chef/efr32/src/main.cpp b/examples/chef/efr32/src/main.cpp index c54683e092bd90..291337b24c8330 100644 --- a/examples/chef/efr32/src/main.cpp +++ b/examples/chef/efr32/src/main.cpp @@ -27,7 +27,7 @@ #include #include #include -#ifdef EFR32_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS #include #else #include @@ -58,7 +58,7 @@ int main(void) chip::DeviceLayer::PlatformMgr().LockChipStack(); // Initialize device attestation config -#ifdef EFR32_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS SetDeviceAttestationCredentialsProvider(EFR32::GetEFR32DacProvider()); #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/light-switch-app/silabs/SiWx917/src/main.cpp b/examples/light-switch-app/silabs/SiWx917/src/main.cpp index 7bae26206310d4..66f158cd48809e 100644 --- a/examples/light-switch-app/silabs/SiWx917/src/main.cpp +++ b/examples/light-switch-app/silabs/SiWx917/src/main.cpp @@ -25,7 +25,7 @@ #include #include #include -#ifdef SI917_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS #include #else #include @@ -61,7 +61,7 @@ int main(void) chip::DeviceLayer::PlatformMgr().LockChipStack(); // Initialize device attestation config -#ifdef SI917_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS SetDeviceAttestationCredentialsProvider(SIWx917::GetSIWx917DacProvider()); #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/light-switch-app/silabs/efr32/src/main.cpp b/examples/light-switch-app/silabs/efr32/src/main.cpp index 0b0211fdbfe61c..97aff97aea535b 100644 --- a/examples/light-switch-app/silabs/efr32/src/main.cpp +++ b/examples/light-switch-app/silabs/efr32/src/main.cpp @@ -27,7 +27,7 @@ #include #include #include -#ifdef EFR32_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS #include #else #include @@ -58,7 +58,7 @@ int main(void) chip::DeviceLayer::PlatformMgr().LockChipStack(); // Initialize device attestation config -#ifdef EFR32_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS SetDeviceAttestationCredentialsProvider(Silabs::GetSilabsDacProvider()); #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/lighting-app/silabs/SiWx917/src/main.cpp b/examples/lighting-app/silabs/SiWx917/src/main.cpp index d95f6b7ab51295..f1103e3340310c 100644 --- a/examples/lighting-app/silabs/SiWx917/src/main.cpp +++ b/examples/lighting-app/silabs/SiWx917/src/main.cpp @@ -26,7 +26,7 @@ #include #include #include -#ifdef SI917_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS #include #else #include @@ -62,7 +62,7 @@ int main(void) chip::DeviceLayer::PlatformMgr().LockChipStack(); // Initialize device attestation config -#ifdef SI917_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS SetDeviceAttestationCredentialsProvider(Silabs::GetSilabsDacProvider()); #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/lighting-app/silabs/efr32/src/main.cpp b/examples/lighting-app/silabs/efr32/src/main.cpp index 9f447b972678b6..54fccb26ba8f35 100644 --- a/examples/lighting-app/silabs/efr32/src/main.cpp +++ b/examples/lighting-app/silabs/efr32/src/main.cpp @@ -29,7 +29,7 @@ #include #include #include -#ifdef EFR32_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS #include #else #include @@ -60,7 +60,7 @@ int main(void) chip::DeviceLayer::PlatformMgr().LockChipStack(); // Initialize device attestation config -#ifdef EFR32_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS SetDeviceAttestationCredentialsProvider(Silabs::GetSilabsDacProvider()); #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/lock-app/silabs/SiWx917/src/main.cpp b/examples/lock-app/silabs/SiWx917/src/main.cpp index a3617564575ec3..44ef40f931b19a 100644 --- a/examples/lock-app/silabs/SiWx917/src/main.cpp +++ b/examples/lock-app/silabs/SiWx917/src/main.cpp @@ -25,7 +25,7 @@ #include #include #include -#ifdef EFR32_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS #include #else #include @@ -59,7 +59,7 @@ int main(void) chip::DeviceLayer::PlatformMgr().LockChipStack(); // Initialize device attestation config -#ifdef SI917_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS SetDeviceAttestationCredentialsProvider(SI917::GetSI917DacProvider()); #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/lock-app/silabs/efr32/src/main.cpp b/examples/lock-app/silabs/efr32/src/main.cpp index 67ec50bc6c1319..e9fc2130f29009 100644 --- a/examples/lock-app/silabs/efr32/src/main.cpp +++ b/examples/lock-app/silabs/efr32/src/main.cpp @@ -27,7 +27,7 @@ #include #include #include -#ifdef EFR32_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS #include #else #include @@ -58,7 +58,7 @@ int main(void) chip::DeviceLayer::PlatformMgr().LockChipStack(); // Initialize device attestation config -#ifdef EFR32_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS SetDeviceAttestationCredentialsProvider(Silabs::GetSilabsDacProvider()); #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/platform/silabs/SiWx917/BUILD.gn b/examples/platform/silabs/SiWx917/BUILD.gn index 79a71b0fe49462..f10af3deca4d79 100644 --- a/examples/platform/silabs/SiWx917/BUILD.gn +++ b/examples/platform/silabs/SiWx917/BUILD.gn @@ -129,7 +129,7 @@ config("attestation-credentials-config") { defines = [ # Set to 1 to enable SI917 attestation credentials - "SI917_ATTESTATION_CREDENTIALS", + "SILABS_ATTESTATION_CREDENTIALS", ] } diff --git a/examples/platform/silabs/efr32/BUILD.gn b/examples/platform/silabs/efr32/BUILD.gn index d9e7d9e961a87f..05f9c6797c0b69 100644 --- a/examples/platform/silabs/efr32/BUILD.gn +++ b/examples/platform/silabs/efr32/BUILD.gn @@ -161,7 +161,7 @@ config("attestation-credentials-config") { defines = [ # Set to 1 to enable EFR32 attestation credentials - "EFR32_ATTESTATION_CREDENTIALS", + "SILABS_ATTESTATION_CREDENTIALS", ] } diff --git a/examples/thermostat/silabs/efr32/src/main.cpp b/examples/thermostat/silabs/efr32/src/main.cpp index e822b71646261e..5cfef676d77c8a 100644 --- a/examples/thermostat/silabs/efr32/src/main.cpp +++ b/examples/thermostat/silabs/efr32/src/main.cpp @@ -27,7 +27,7 @@ #include #include #include -#ifdef EFR32_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS #include #else #include @@ -58,7 +58,7 @@ int main(void) chip::DeviceLayer::PlatformMgr().LockChipStack(); // Initialize device attestation config -#ifdef EFR32_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS SetDeviceAttestationCredentialsProvider(Silabs::GetSilabsDacProvider()); #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/window-app/silabs/SiWx917/src/main.cpp b/examples/window-app/silabs/SiWx917/src/main.cpp index 49a33ad9181f0a..9545aae1e4acd5 100644 --- a/examples/window-app/silabs/SiWx917/src/main.cpp +++ b/examples/window-app/silabs/SiWx917/src/main.cpp @@ -25,7 +25,7 @@ #include #include #include -#ifdef SI917_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS #include #else #include @@ -60,7 +60,7 @@ int main(void) chip::DeviceLayer::PlatformMgr().LockChipStack(); err = app.Init(); // Initialize device attestation config -#ifdef SI917_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS SetDeviceAttestationCredentialsProvider(SILABS::GetSILABSDacProvider()); #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); diff --git a/examples/window-app/silabs/efr32/src/main.cpp b/examples/window-app/silabs/efr32/src/main.cpp index f0536c625cbe49..12c1af9c9ad710 100644 --- a/examples/window-app/silabs/efr32/src/main.cpp +++ b/examples/window-app/silabs/efr32/src/main.cpp @@ -27,7 +27,7 @@ #include #include #include -#ifdef EFR32_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS #include #else #include @@ -62,7 +62,7 @@ int main(void) chip::DeviceLayer::PlatformMgr().LockChipStack(); err = app.Init(); // Initialize device attestation config -#ifdef EFR32_ATTESTATION_CREDENTIALS +#ifdef SILABS_ATTESTATION_CREDENTIALS SetDeviceAttestationCredentialsProvider(Silabs::GetSilabsDacProvider()); #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); From c20ee5e3d17fecda0d8a8a88c65b066ef52ae92c Mon Sep 17 00:00:00 2001 From: chirag-silabs <100861685+chirag-silabs@users.noreply.github.com> Date: Fri, 14 Apr 2023 04:47:25 +0530 Subject: [PATCH 03/23] [Silabs] Wifi bug fixes which were causing hardfault (#26092) * Wifi small bug fixes * Restyled by clang-format --------- Co-authored-by: Restyled.io --- examples/platform/silabs/SiWx917/SiWx917/rsi_if.c | 4 ++-- examples/platform/silabs/efr32/rs911x/rsi_if.c | 4 ++-- examples/platform/silabs/efr32/wf200/efr_spi.c | 8 -------- examples/platform/silabs/efr32/wf200/host_if.cpp | 1 + 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/examples/platform/silabs/SiWx917/SiWx917/rsi_if.c b/examples/platform/silabs/SiWx917/SiWx917/rsi_if.c index 5461e4ad524387..403dff68ce6a2f 100644 --- a/examples/platform/silabs/SiWx917/SiWx917/rsi_if.c +++ b/examples/platform/silabs/SiWx917/SiWx917/rsi_if.c @@ -357,7 +357,7 @@ static void wfx_rsi_save_ap_info() #else /* !WIFI_ENABLE_SECURITY_WPA3 */ wfx_rsi.sec.security = WFX_SEC_WPA2; #endif /* WIFI_ENABLE_SECURITY_WPA3 */ - SILABS_LOG("%s: warn: failed with status: %02x", status); + SILABS_LOG("%s: warn: failed with status: %02x", __func__, status); return; } else @@ -429,7 +429,7 @@ static void wfx_rsi_do_join(void) connect_security_mode = RSI_OPEN; break; default: - SILABS_LOG("%s: error: unknown security type."); + SILABS_LOG("%s: error: unknown security type.", __func__); return; } diff --git a/examples/platform/silabs/efr32/rs911x/rsi_if.c b/examples/platform/silabs/efr32/rs911x/rsi_if.c index 2f7c6651f20df2..324f635f3015f0 100644 --- a/examples/platform/silabs/efr32/rs911x/rsi_if.c +++ b/examples/platform/silabs/efr32/rs911x/rsi_if.c @@ -408,7 +408,7 @@ static void wfx_rsi_save_ap_info() // translation #else /* !WIFI_ENABLE_SECURITY_WPA3 */ wfx_rsi.sec.security = WFX_SEC_WPA2; #endif /* WIFI_ENABLE_SECURITY_WPA3 */ - SILABS_LOG("%s: warn: failed with status: %02x", status); + SILABS_LOG("%s: warn: failed with status: %02x", __func__, status); return; } else @@ -482,7 +482,7 @@ static void wfx_rsi_do_join(void) connect_security_mode = RSI_OPEN; break; default: - SILABS_LOG("%s: error: unknown security type."); + SILABS_LOG("%s: error: unknown security type.", __func__); return; } diff --git a/examples/platform/silabs/efr32/wf200/efr_spi.c b/examples/platform/silabs/efr32/wf200/efr_spi.c index 5d75638b54f49a..7422ec686f0b9d 100644 --- a/examples/platform/silabs/efr32/wf200/efr_spi.c +++ b/examples/platform/silabs/efr32/wf200/efr_spi.c @@ -381,10 +381,6 @@ sl_status_t sl_wfx_host_enable_spi(void) { if (spi_enabled == false) { -#ifdef SLEEP_ENABLED - // Prevent the host to use lower EM than EM1 - sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM1); -#endif spi_enabled = true; } return SL_STATUS_OK; @@ -403,10 +399,6 @@ sl_status_t sl_wfx_host_disable_spi(void) if (spi_enabled == true) { spi_enabled = false; -#ifdef SLEEP_ENABLED - // Allow the host to use the lowest allowed EM - sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1); -#endif } return SL_STATUS_OK; } diff --git a/examples/platform/silabs/efr32/wf200/host_if.cpp b/examples/platform/silabs/efr32/wf200/host_if.cpp index 6b55cbf6dd7832..1d0f061e77d1bc 100644 --- a/examples/platform/silabs/efr32/wf200/host_if.cpp +++ b/examples/platform/silabs/efr32/wf200/host_if.cpp @@ -606,6 +606,7 @@ static void wfx_events_task(void * p_arg) if (!(wfx_get_wifi_state() & SL_WFX_AP_INTERFACE_UP)) { // Enable the power save + SILABS_LOG("WF200 going to DTIM based sleep"); sl_wfx_set_power_mode(WFM_PM_MODE_DTIM, WFM_PM_POLL_FAST_PS, BEACON_1); sl_wfx_enable_device_power_save(); } From 7703ed2c5ffa48fd0857bce76d584ef711ff80f4 Mon Sep 17 00:00:00 2001 From: Timothy Maes Date: Fri, 14 Apr 2023 01:17:50 +0200 Subject: [PATCH 04/23] Removal reportable:0 from zap files (#26086) --- examples/lighting-app/qpg/zap/light.matter | 12 ++++++------ examples/lighting-app/qpg/zap/light.zap | 12 ++++++------ examples/lock-app/qpg/zap/lock.zap | 14 +++++++------- .../tv-casting-common/tv-casting-app.zap | 6 +++--- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/examples/lighting-app/qpg/zap/light.matter b/examples/lighting-app/qpg/zap/light.matter index 3b70d0b639086f..b6b9cb244c744b 100644 --- a/examples/lighting-app/qpg/zap/light.matter +++ b/examples/lighting-app/qpg/zap/light.matter @@ -153,7 +153,7 @@ server cluster OnOff = 6 { kLighting = 0x1; } - readonly nosubscribe attribute boolean onOff = 0; + readonly attribute boolean onOff = 0; readonly attribute boolean globalSceneControl = 16384; attribute int16u onTime = 16385; attribute int16u offWaitTime = 16386; @@ -1452,12 +1452,12 @@ server cluster ColorControl = 768 { kUpdateStartHue = 0x8; } - readonly nosubscribe attribute int8u currentHue = 0; - readonly nosubscribe attribute int8u currentSaturation = 1; + readonly attribute int8u currentHue = 0; + readonly attribute int8u currentSaturation = 1; readonly attribute int16u remainingTime = 2; - readonly nosubscribe attribute int16u currentX = 3; - readonly nosubscribe attribute int16u currentY = 4; - readonly nosubscribe attribute int16u colorTemperatureMireds = 7; + readonly attribute int16u currentX = 3; + readonly attribute int16u currentY = 4; + readonly attribute int16u colorTemperatureMireds = 7; readonly attribute enum8 colorMode = 8; attribute bitmap8 options = 15; readonly attribute nullable int8u numberOfPrimaries = 16; diff --git a/examples/lighting-app/qpg/zap/light.zap b/examples/lighting-app/qpg/zap/light.zap index 7907760199fd9e..ccd32d3549f65d 100644 --- a/examples/lighting-app/qpg/zap/light.zap +++ b/examples/lighting-app/qpg/zap/light.zap @@ -7328,7 +7328,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0x00", - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -9224,7 +9224,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0x00", - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -9240,7 +9240,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0x00", - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -9272,7 +9272,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0x616B", - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -9288,7 +9288,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0x607D", - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -9336,7 +9336,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0x00FA", - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 diff --git a/examples/lock-app/qpg/zap/lock.zap b/examples/lock-app/qpg/zap/lock.zap index d97211c9d05a77..9e480a2bbb4e1a 100644 --- a/examples/lock-app/qpg/zap/lock.zap +++ b/examples/lock-app/qpg/zap/lock.zap @@ -8897,7 +8897,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0", - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -8977,7 +8977,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0", - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -8993,7 +8993,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "1", - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -9025,7 +9025,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0", - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -9057,7 +9057,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0", - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -9105,7 +9105,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0", - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -9137,7 +9137,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "", - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 diff --git a/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap b/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap index 7fa8a0aed5e58c..199ce4901cad79 100644 --- a/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap +++ b/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap @@ -8484,7 +8484,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "", - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -8500,7 +8500,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "", - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -8516,7 +8516,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "", - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 From 21d2129f26c81702763a4f25e53acac4825e4158 Mon Sep 17 00:00:00 2001 From: stoneM2017 Date: Fri, 14 Apr 2023 07:18:34 +0800 Subject: [PATCH 05/23] [Bouffalolab]improvements related to ota requestor (#26013) * [Bouffalolab]improvements related to ota requestor: 1. init ota requestor after got IPV6 address or thread attached. 2. sync-up ota related API changes in bl_iot_sdk. 3. make the ota auto reboot delay configureable. 4. update bl_iot_sdk, commit id 7ca85fd7. * Restyled by clang-format * Restyled by gn * fix compile error after auto-rebase * add time unit to the timeout/delay variables --------- Co-authored-by: Restyled.io Co-authored-by: wyhong --- .../lighting-app/bouffalolab/bl602/BUILD.gn | 8 ++++++-- .../lighting-app/bouffalolab/bl702/BUILD.gn | 8 ++++++-- .../bouffalolab/bl702/ldscripts/psram_flash.ld | 4 ---- .../bouffalolab/common/plat/OTAConfig.cpp | 9 +++++++++ .../bouffalolab/common/plat/OTAConfig.h | 2 ++ .../bouffalolab/common/plat/platform.cpp | 17 +++++++++-------- .../bouffalolab/BL602/OTAImageProcessorImpl.cpp | 7 ++++--- .../bouffalolab/BL702/OTAImageProcessorImpl.cpp | 15 ++++++++++++--- third_party/bouffalolab/bl602/bl_iot_sdk.gni | 1 + 9 files changed, 49 insertions(+), 22 deletions(-) diff --git a/examples/lighting-app/bouffalolab/bl602/BUILD.gn b/examples/lighting-app/bouffalolab/bl602/BUILD.gn index d5233ec407fa46..125e9ea45a3e0f 100644 --- a/examples/lighting-app/bouffalolab/bl602/BUILD.gn +++ b/examples/lighting-app/bouffalolab/bl602/BUILD.gn @@ -41,7 +41,10 @@ declare_args() { chip_print_memory_usage = true # OTA periodic query timeout in seconds - ota_periodic_query_timeout = 86400 + ota_periodic_query_timeout_seconds = 86400 + + # reboot delay in seconds to apply new OTA image + ota_auto_reboot_delay_seconds = 5 enable_heap_monitoring = false @@ -66,7 +69,8 @@ bl_iot_sdk("sdk") { "INCLUDE_xSemaphoreGetMutexHolder=1", "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE=${setupPinCode}", "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setupDiscriminator}", - "OTA_PERIODIC_TIMEOUT=${ota_periodic_query_timeout}", + "OTA_PERIODIC_TIMEOUT=${ota_periodic_query_timeout_seconds}", + "OTA_AUTO_REBOOT_DELAY=${ota_auto_reboot_delay_seconds}", "CHIP_UART_BAUDRATE=${baudrate}", "SYS_AOS_LOOP_ENABLE", ] diff --git a/examples/lighting-app/bouffalolab/bl702/BUILD.gn b/examples/lighting-app/bouffalolab/bl702/BUILD.gn index 4e6319dac88dc7..028a36f25cc0e7 100644 --- a/examples/lighting-app/bouffalolab/bl702/BUILD.gn +++ b/examples/lighting-app/bouffalolab/bl702/BUILD.gn @@ -41,7 +41,10 @@ declare_args() { chip_print_memory_usage = true # OTA periodic query timeout in seconds - ota_periodic_query_timeout = 86400 + ota_periodic_query_timeout_seconds = 86400 + + # reboot delay in seconds to apply new OTA image + ota_auto_reboot_delay_seconds = 5 config_cache_size = 8192 @@ -69,7 +72,8 @@ bl_iot_sdk("sdk") { "INCLUDE_xSemaphoreGetMutexHolder=1", "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE=${setupPinCode}", "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setupDiscriminator}", - "OTA_PERIODIC_TIMEOUT=${ota_periodic_query_timeout}", + "OTA_PERIODIC_TIMEOUT=${ota_periodic_query_timeout_seconds}", + "OTA_AUTO_REBOOT_DELAY=${ota_auto_reboot_delay_seconds}", "OPENTHREAD_CONFIG_PLATFORM_XTAL_ACCURACY=40", "PRINT_DEBUG=0", ] diff --git a/examples/platform/bouffalolab/bl702/ldscripts/psram_flash.ld b/examples/platform/bouffalolab/bl702/ldscripts/psram_flash.ld index cf9dce4d23430c..e432a4d7bd2ed8 100644 --- a/examples/platform/bouffalolab/bl702/ldscripts/psram_flash.ld +++ b/examples/platform/bouffalolab/bl702/ldscripts/psram_flash.ld @@ -143,10 +143,6 @@ SECTIONS { *(.rsvd_data) *(.ble_rsvd_mem) - - KEEP(*AppTask.cpp.o(.bss.*appStack*)) - KEEP(*main.cpp.o(.bss.*TimerTaskStack*)) - } >hbnram .tcmcode : ALIGN(4) diff --git a/examples/platform/bouffalolab/common/plat/OTAConfig.cpp b/examples/platform/bouffalolab/common/plat/OTAConfig.cpp index fc9b18c3d2c450..ed5c6286178ef7 100644 --- a/examples/platform/bouffalolab/common/plat/OTAConfig.cpp +++ b/examples/platform/bouffalolab/common/plat/OTAConfig.cpp @@ -44,3 +44,12 @@ void OTAConfig::Init() gDownloader.SetImageProcessorDelegate(&gImageProcessor); // Initialize and interconnect the Requestor and Image Processor objects -- END } + +void OTAConfig::InitOTARequestorHandler(chip::System::Layer * systemLayer, void * appState) +{ + if (!chip::GetRequestorInstance()) + { + ChipLogProgress(NotSpecified, "Init OTA Requestor"); + OTAConfig::Init(); + } +} diff --git a/examples/platform/bouffalolab/common/plat/OTAConfig.h b/examples/platform/bouffalolab/common/plat/OTAConfig.h index 0aed631b16fff0..906b7f533709cc 100644 --- a/examples/platform/bouffalolab/common/plat/OTAConfig.h +++ b/examples/platform/bouffalolab/common/plat/OTAConfig.h @@ -30,4 +30,6 @@ class OTAConfig OTAConfig(){}; static void Init(); + static constexpr uint32_t kInitOTARequestorDelaySec = 3; + static void InitOTARequestorHandler(chip::System::Layer * systemLayer, void * appState); }; diff --git a/examples/platform/bouffalolab/common/plat/platform.cpp b/examples/platform/bouffalolab/common/plat/platform.cpp index 50ed0de9c19a4d..0c6f1912d3bb80 100644 --- a/examples/platform/bouffalolab/common/plat/platform.cpp +++ b/examples/platform/bouffalolab/common/plat/platform.cpp @@ -121,6 +121,10 @@ void ChipEventHandler(const ChipDeviceEvent * event, intptr_t arg) { GetAppTask().PostEvent(AppTask::APP_EVENT_SYS_PROVISIONED); GetAppTask().mIsConnected = true; +#ifdef OTA_ENABLED + chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(OTAConfig::kInitOTARequestorDelaySec), + OTAConfig::InitOTARequestorHandler, nullptr); +#endif } break; #endif @@ -155,11 +159,14 @@ void ChipEventHandler(const ChipDeviceEvent * event, intptr_t arg) { ChipLogProgress(NotSpecified, "Initializing route hook..."); bl_route_hook_init(); + +#ifdef OTA_ENABLED + chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(OTAConfig::kInitOTARequestorDelaySec), + OTAConfig::InitOTARequestorHandler, nullptr); +#endif } break; #endif - - break; default: break; } @@ -249,12 +256,6 @@ CHIP_ERROR PlatformManagerImpl::PlatformInit(void) PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE)); PlatformMgr().AddEventHandler(ChipEventHandler, 0); -#ifdef OTA_ENABLED - chip::DeviceLayer::PlatformMgr().LockChipStack(); - OTAConfig::Init(); - chip::DeviceLayer::PlatformMgr().UnlockChipStack(); -#endif // OTA_ENABLED - #if PW_RPC_ENABLED chip::rpc::Init(); #endif diff --git a/src/platform/bouffalolab/BL602/OTAImageProcessorImpl.cpp b/src/platform/bouffalolab/BL602/OTAImageProcessorImpl.cpp index a24d9316f6d5f7..97af465ef1fef3 100644 --- a/src/platform/bouffalolab/BL602/OTAImageProcessorImpl.cpp +++ b/src/platform/bouffalolab/BL602/OTAImageProcessorImpl.cpp @@ -135,7 +135,7 @@ void OTAImageProcessorImpl::HandleFinalize(intptr_t context) return; } - if (hosal_ota_finish(1, 0) < 0) + if (hosal_ota_check() < 0) { imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); ChipLogProgress(SoftwareUpdate, "OTA image verification error"); @@ -157,8 +157,9 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context) return; } + hosal_ota_apply(0); DeviceLayer::SystemLayer().StartTimer( - System::Clock::Seconds32(4), + System::Clock::Seconds32(OTA_AUTO_REBOOT_DELAY), [](Layer *, void *) { ChipLogProgress(SoftwareUpdate, "Rebooting..."); hal_reboot(); @@ -174,7 +175,7 @@ void OTAImageProcessorImpl::HandleAbort(intptr_t context) return; } - hosal_ota_finish(1, 0); + hosal_ota_abort(); imageProcessor->ReleaseBlock(); } diff --git a/src/platform/bouffalolab/BL702/OTAImageProcessorImpl.cpp b/src/platform/bouffalolab/BL702/OTAImageProcessorImpl.cpp index c59e34d366cfc2..1e49c74e4f9eb0 100644 --- a/src/platform/bouffalolab/BL702/OTAImageProcessorImpl.cpp +++ b/src/platform/bouffalolab/BL702/OTAImageProcessorImpl.cpp @@ -23,6 +23,8 @@ extern "C" { #include } +using namespace chip::System; + namespace chip { CHIP_ERROR OTAImageProcessorImpl::PrepareDownload() @@ -98,7 +100,7 @@ void OTAImageProcessorImpl::HandleFinalize(intptr_t context) return; } - if (hosal_ota_finish(1, 0) < 0) + if (hosal_ota_check() < 0) { imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); ChipLogProgress(SoftwareUpdate, "OTA image verification error"); @@ -120,7 +122,14 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context) return; } - hal_reboot(); + hosal_ota_apply(0); + DeviceLayer::SystemLayer().StartTimer( + System::Clock::Seconds32(OTA_AUTO_REBOOT_DELAY), + [](Layer *, void *) { + ChipLogProgress(SoftwareUpdate, "Rebooting..."); + hal_reboot(); + }, + nullptr); } void OTAImageProcessorImpl::HandleAbort(intptr_t context) @@ -131,7 +140,7 @@ void OTAImageProcessorImpl::HandleAbort(intptr_t context) return; } - hosal_ota_finish(1, 0); + hosal_ota_abort(); imageProcessor->ReleaseBlock(); } diff --git a/third_party/bouffalolab/bl602/bl_iot_sdk.gni b/third_party/bouffalolab/bl602/bl_iot_sdk.gni index ea44002bccf38d..b65371d55f88ac 100644 --- a/third_party/bouffalolab/bl602/bl_iot_sdk.gni +++ b/third_party/bouffalolab/bl602/bl_iot_sdk.gni @@ -608,6 +608,7 @@ template("bl_iot_sdk") { ":${sdk_target_name}_config_BSP_Driver", ":${sdk_target_name}_config_freertos", ":${sdk_target_name}_config_utils", + ":${sdk_target_name}_config_hosal", ] public_configs = [ ":${sdk_target_name}_config", From 94ccbdda686ee84230e839476aacbba31dff5214 Mon Sep 17 00:00:00 2001 From: Hamid Abubakr Date: Fri, 14 Apr 2023 03:20:35 +0400 Subject: [PATCH 06/23] implement unpairdevice API for python CHIP controller (#25961) * implement unpairdevice API for python chip controller * Restyled by clang-format * Restyled by autopep8 * pep8 formatting * autopep8 * fix leak on error return from RemoveCurrentFabric * delete fabric remover on error * autopep8 * clean up callbacks as well on RemoveCurrentFabric error --------- Co-authored-by: Restyled.io Co-authored-by: Andrei Litvin --- .../ChipDeviceController-ScriptBinding.cpp | 44 +++++++++++++++++++ src/controller/python/chip/ChipDeviceCtrl.py | 25 ++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp index eaced943177314..5b2b3a01759ec4 100644 --- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp +++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -89,6 +90,7 @@ typedef void (*ConstructBytesArrayFunct)(const uint8_t * dataBuf, uint32_t dataL typedef void (*LogMessageFunct)(uint64_t time, uint64_t timeUS, const char * moduleName, uint8_t category, const char * msg); typedef void (*DeviceAvailableFunc)(DeviceProxy * device, PyChipError err); typedef void (*ChipThreadTaskRunnerFunct)(intptr_t context); +typedef void (*DeviceUnpairingCompleteFunct)(uint64_t nodeId, PyChipError error); } namespace { @@ -131,6 +133,8 @@ PyChipError pychip_DeviceController_ConnectIP(chip::Controller::DeviceCommission uint32_t setupPINCode, chip::NodeId nodeid); PyChipError pychip_DeviceController_ConnectWithCode(chip::Controller::DeviceCommissioner * devCtrl, const char * onboardingPayload, chip::NodeId nodeid); +PyChipError pychip_DeviceController_UnpairDevice(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId remoteDeviceId, + DeviceUnpairingCompleteFunct callback); PyChipError pychip_DeviceController_SetThreadOperationalDataset(const char * threadOperationalDataset, uint32_t size); PyChipError pychip_DeviceController_SetWiFiCredentials(const char * ssid, const char * credentials); PyChipError pychip_DeviceController_CloseSession(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid); @@ -386,6 +390,46 @@ PyChipError pychip_DeviceController_ConnectWithCode(chip::Controller::DeviceComm return ToPyChipError(devCtrl->PairDevice(nodeid, onboardingPayload, sCommissioningParameters)); } +namespace { +struct UnpairDeviceCallback +{ + UnpairDeviceCallback(DeviceUnpairingCompleteFunct callback, chip::Controller::CurrentFabricRemover * remover) : + mOnCurrentFabricRemove(OnCurrentFabricRemoveFn, this), mCallback(callback), mRemover(remover) + {} + + static void OnCurrentFabricRemoveFn(void * context, chip::NodeId nodeId, CHIP_ERROR error) + { + auto * self = static_cast(context); + self->mCallback(nodeId, ToPyChipError(error)); + delete self->mRemover; + delete self; + } + + Callback::Callback mOnCurrentFabricRemove; + DeviceUnpairingCompleteFunct mCallback; + chip::Controller::CurrentFabricRemover * mRemover; +}; +} // anonymous namespace + +PyChipError pychip_DeviceController_UnpairDevice(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeid, + DeviceUnpairingCompleteFunct callback) +{ + // Create a new CurrentFabricRemover instance + auto * fabricRemover = new chip::Controller::CurrentFabricRemover(devCtrl); + + auto * callbacks = new UnpairDeviceCallback(callback, fabricRemover); + + // Pass the callback and nodeid to the RemoveCurrentFabric function + CHIP_ERROR err = fabricRemover->RemoveCurrentFabric(nodeid, &callbacks->mOnCurrentFabricRemove); + if (err != CHIP_NO_ERROR) + { + delete fabricRemover; + delete callbacks; + } + // Else will clean up when the callback is called. + return ToPyChipError(err); +} + PyChipError pychip_DeviceController_OnNetworkCommission(chip::Controller::DeviceCommissioner * devCtrl, uint64_t nodeId, uint32_t setupPasscode, const uint8_t filterType, const char * filterParam) { diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index 3626dac0027e76..e41bb4257434bc 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -60,6 +60,7 @@ __all__ = ["ChipDeviceController"] _DevicePairingDelegate_OnPairingCompleteFunct = CFUNCTYPE(None, PyChipError) +_DeviceUnpairingCompleteFunct = CFUNCTYPE(None, c_uint64, PyChipError) _DevicePairingDelegate_OnCommissioningCompleteFunct = CFUNCTYPE( None, c_uint64, PyChipError) _DevicePairingDelegate_OnOpenWindowCompleteFunct = CFUNCTYPE( @@ -248,6 +249,15 @@ def HandleOpenWindowComplete(nodeid: int, setupPinCode: int, setupCode: str, err self._ChipStack.callbackRes = err self._ChipStack.completeEvent.set() + def HandleUnpairDeviceComplete(nodeid: int, err: PyChipError): + if err.is_success: + print("Succesfully unpaired device with nodeid {}".format(nodeid)) + else: + print("Failed to unpair device: {}".format(err)) + + self._ChipStack.callbackRes = err + self._ChipStack.completeEvent.set() + def HandlePASEEstablishmentComplete(err: PyChipError): if not err.is_success: print("Failed to establish secure session to device: {}".format(err)) @@ -284,9 +294,10 @@ def HandlePASEEstablishmentComplete(err: PyChipError): self._dmLib.pychip_ScriptDevicePairingDelegate_SetOpenWindowCompleteCallback( self.devCtrl, self.cbHandleOpenWindowCompleteFunct) + self.cbHandleDeviceUnpairCompleteFunct = _DeviceUnpairingCompleteFunct(HandleUnpairDeviceComplete) + self.state = DCState.IDLE self._isActive = True - # Validate FabricID/NodeID followed from NOC Chain self._fabricId = self.GetFabricIdInternal() self._nodeId = self.GetNodeIdInternal() @@ -386,6 +397,14 @@ def ConnectBLE(self, discriminator, setupPinCode, nodeid): return False return self._ChipStack.commissioningEventRes.is_success + def UnpairDevice(self, nodeid: int): + self.CheckIsActive() + + return self._ChipStack.CallAsync( + lambda: self._dmLib.pychip_DeviceController_UnpairDevice( + self.devCtrl, nodeid, self.cbHandleDeviceUnpairCompleteFunct) + ).raise_on_error() + def CloseBLEConnection(self): self.CheckIsActive() @@ -1274,6 +1293,10 @@ def _InitLib(self): c_void_p, c_char_p, c_uint64] self._dmLib.pychip_DeviceController_ConnectWithCode.restype = PyChipError + self._dmLib.pychip_DeviceController_UnpairDevice.argtypes = [ + c_void_p, c_uint64, _DeviceUnpairingCompleteFunct] + self._dmLib.pychip_DeviceController_UnpairDevice.restype = PyChipError + self._dmLib.pychip_DeviceController_CloseSession.argtypes = [ c_void_p, c_uint64] self._dmLib.pychip_DeviceController_CloseSession.restype = PyChipError From e56fe6d5b323d3c3339330ba69ab37410ca5360e Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Fri, 14 Apr 2023 01:21:13 +0200 Subject: [PATCH 07/23] [Linux] Run functions on GLib event loop in a sync way (#25916) * Run functions on GLib event loop in a sync way * Include invoke sync template when GLib is enabled * Restore workaround for TSAN false positives * Fix variable shadowing * Do not use g_main_context_invoke_full for waiting for loop to start The g_main_context_invoke_full() function checks whether the context, on which it's supposed to run callback function, is acquired. Otherwise, it runs given callback on the current thread. In our case this may lead to incorrect GLib signals bindings, so we have to use g_source_attach() when waiting for main loop. * Release context object after joining glib thread TSAN can report false-positive on context unref. By firstly joining thread and later unreferencing context we will prevent such warning. --- src/platform/Linux/PlatformManagerImpl.cpp | 98 ++++++++++--------- src/platform/Linux/PlatformManagerImpl.h | 48 ++++----- .../Linux/bluez/ChipDeviceScanner.cpp | 12 +-- src/platform/Linux/bluez/ChipDeviceScanner.h | 4 +- src/platform/Linux/bluez/Helper.cpp | 72 +++++++------- 5 files changed, 118 insertions(+), 116 deletions(-) diff --git a/src/platform/Linux/PlatformManagerImpl.cpp b/src/platform/Linux/PlatformManagerImpl.cpp index ff753e40fab6ba..8001ae6677d7de 100644 --- a/src/platform/Linux/PlatformManagerImpl.cpp +++ b/src/platform/Linux/PlatformManagerImpl.cpp @@ -194,10 +194,28 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack() mGLibMainLoopThread = g_thread_new("gmain-matter", GLibMainLoopThread, mGLibMainLoop); { + // Wait for the GLib main loop to start. It is required that the context used + // by the main loop is acquired before any other GLib functions are called. Otherwise, + // the GLibMatterContextInvokeSync() might run functions on the wrong thread. + std::unique_lock lock(mGLibMainLoopCallbackIndirectionMutex); - CallbackIndirection startedInd([](void *) { return G_SOURCE_REMOVE; }, nullptr); - g_idle_add(G_SOURCE_FUNC(&CallbackIndirection::Callback), &startedInd); - startedInd.Wait(lock); + GLibMatterContextInvokeData invokeData{}; + + auto * idleSource = g_idle_source_new(); + g_source_set_callback( + idleSource, + [](void * userData_) { + auto * data = reinterpret_cast(userData_); + std::unique_lock lock_(PlatformMgrImpl().mGLibMainLoopCallbackIndirectionMutex); + data->mDone = true; + data->mDoneCond.notify_one(); + return G_SOURCE_REMOVE; + }, + &invokeData, nullptr); + g_source_attach(idleSource, g_main_loop_get_context(mGLibMainLoop)); + g_source_unref(idleSource); + + invokeData.mDoneCond.wait(lock, [&invokeData]() { return invokeData.mDone; }); } #endif @@ -248,68 +266,52 @@ void PlatformManagerImpl::_Shutdown() #if CHIP_DEVICE_CONFIG_WITH_GLIB_MAIN_LOOP g_main_loop_quit(mGLibMainLoop); - g_main_loop_unref(mGLibMainLoop); g_thread_join(mGLibMainLoopThread); + g_main_loop_unref(mGLibMainLoop); #endif } #if CHIP_DEVICE_CONFIG_WITH_GLIB_MAIN_LOOP - -void PlatformManagerImpl::CallbackIndirection::Wait(std::unique_lock & lock) -{ - mDoneCond.wait(lock, [this]() { return mDone; }); -} - -gboolean PlatformManagerImpl::CallbackIndirection::Callback(CallbackIndirection * self) +CHIP_ERROR PlatformManagerImpl::_GLibMatterContextInvokeSync(CHIP_ERROR (*func)(void *), void * userData) { - // We can not access "self" before acquiring the lock, because TSAN will complain that - // there is a race condition between the thread that created the object and the thread - // that is executing the callback. - std::unique_lock lock(PlatformMgrImpl().mGLibMainLoopCallbackIndirectionMutex); + // Because of TSAN false positives, we need to use a mutex to synchronize access to all members of + // the GLibMatterContextInvokeData object (including constructor and destructor). This is a temporary + // workaround until TSAN-enabled GLib will be used in our CI. + std::unique_lock lock(mGLibMainLoopCallbackIndirectionMutex); - auto callback = self->mCallback; - auto userData = self->mUserData; + GLibMatterContextInvokeData invokeData{ func, userData }; lock.unlock(); - auto result = callback(userData); - lock.lock(); - self->mDone = true; - self->mDoneCond.notify_all(); + g_main_context_invoke_full( + g_main_loop_get_context(mGLibMainLoop), G_PRIORITY_HIGH_IDLE, + [](void * userData_) { + auto * data = reinterpret_cast(userData_); - return result; -} + // XXX: Temporary workaround for TSAN false positives. + std::unique_lock lock_(PlatformMgrImpl().mGLibMainLoopCallbackIndirectionMutex); -#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE -CHIP_ERROR PlatformManagerImpl::RunOnGLibMainLoopThread(GSourceFunc callback, void * userData, bool wait) -{ + auto mFunc = data->mFunc; + auto mUserData = data->mFuncUserData; - GMainContext * context = g_main_loop_get_context(mGLibMainLoop); - VerifyOrReturnError(context != nullptr, CHIP_ERROR_INTERNAL, - ChipLogDetail(DeviceLayer, "Failed to get GLib main loop context")); + lock_.unlock(); + auto result = mFunc(mUserData); + lock_.lock(); - // If we've been called from the GLib main loop thread itself, there is no reason to wait - // for the callback, as it will be executed immediately by the g_main_context_invoke() call - // below. Using a callback indirection in this case would cause a deadlock. - if (g_main_context_is_owner(context)) - { - wait = false; - } + data->mDone = true; + data->mFuncResult = result; + data->mDoneCond.notify_one(); - if (wait) - { - std::unique_lock lock(mGLibMainLoopCallbackIndirectionMutex); - CallbackIndirection indirection(callback, userData); - g_main_context_invoke(context, G_SOURCE_FUNC(&CallbackIndirection::Callback), &indirection); - indirection.Wait(lock); - return CHIP_NO_ERROR; - } + return G_SOURCE_REMOVE; + }, + &invokeData, nullptr); - g_main_context_invoke(context, callback, userData); - return CHIP_NO_ERROR; -} -#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + lock.lock(); + invokeData.mDoneCond.wait(lock, [&invokeData]() { return invokeData.mDone; }); + + return invokeData.mFuncResult; +} #endif // CHIP_DEVICE_CONFIG_WITH_GLIB_MAIN_LOOP } // namespace DeviceLayer diff --git a/src/platform/Linux/PlatformManagerImpl.h b/src/platform/Linux/PlatformManagerImpl.h index 2b1bad0ea7fd2c..aa50cce59e2998 100644 --- a/src/platform/Linux/PlatformManagerImpl.h +++ b/src/platform/Linux/PlatformManagerImpl.h @@ -54,25 +54,22 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener public: // ===== Platform-specific members that may be accessed directly by the application. -#if CHIP_DEVICE_CONFIG_WITH_GLIB_MAIN_LOOP && CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#if CHIP_DEVICE_CONFIG_WITH_GLIB_MAIN_LOOP /** - * @brief Executes a callback in the GLib main loop thread. + * @brief Invoke a function on the Matter GLib context. * - * @param[in] callback The callback to execute. - * @param[in] userData User data to pass to the callback. - * @param[in] wait If true, the function will block until the callback has been executed. - * @returns CHIP_NO_ERROR if the callback was successfully executed. - */ - CHIP_ERROR RunOnGLibMainLoopThread(GSourceFunc callback, void * userData, bool wait = false); - - /** - * @brief Convenience method to require less casts to void pointers. + * If execution of the function will have to be scheduled on other thread, + * this call will block the current thread until the function is executed. + * + * @param[in] function The function to call. + * @param[in] userData User data to pass to the function. + * @returns The result of the function. */ - template - CHIP_ERROR ScheduleOnGLibMainLoopThread(gboolean (*callback)(T *), T * userData, bool wait = false) + template + CHIP_ERROR GLibMatterContextInvokeSync(CHIP_ERROR (*func)(T *), T * userData) { - return RunOnGLibMainLoopThread(G_SOURCE_FUNC(callback), userData, wait); + return _GLibMatterContextInvokeSync((CHIP_ERROR(*)(void *)) func, (void *) userData); } #endif @@ -97,21 +94,24 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener #if CHIP_DEVICE_CONFIG_WITH_GLIB_MAIN_LOOP - class CallbackIndirection + struct GLibMatterContextInvokeData { - public: - CallbackIndirection(GSourceFunc callback, void * userData) : mCallback(callback), mUserData(userData) {} - void Wait(std::unique_lock & lock); - static gboolean Callback(CallbackIndirection * self); - - private: - GSourceFunc mCallback; - void * mUserData; - // Sync primitives to wait for the callback to be executed. + CHIP_ERROR (*mFunc)(void *); + void * mFuncUserData; + CHIP_ERROR mFuncResult; + // Sync primitives to wait for the function to be executed std::condition_variable mDoneCond; bool mDone = false; }; + /** + * @brief Invoke a function on the Matter GLib context. + * + * @note This function does not provide type safety for the user data. Please, + * use the GLibMatterContextInvokeSync() template function instead. + */ + CHIP_ERROR _GLibMatterContextInvokeSync(CHIP_ERROR (*func)(void *), void * userData); + // XXX: Mutex for guarding access to glib main event loop callback indirection // synchronization primitives. This is a workaround to suppress TSAN warnings. // TSAN does not know that from the thread synchronization perspective the diff --git a/src/platform/Linux/bluez/ChipDeviceScanner.cpp b/src/platform/Linux/bluez/ChipDeviceScanner.cpp index 04c522ba34aa66..0172c820c5a0cc 100644 --- a/src/platform/Linux/bluez/ChipDeviceScanner.cpp +++ b/src/platform/Linux/bluez/ChipDeviceScanner.cpp @@ -123,7 +123,7 @@ CHIP_ERROR ChipDeviceScanner::StartScan(System::Clock::Timeout timeout) ReturnErrorCodeIf(mIsScanning, CHIP_ERROR_INCORRECT_STATE); mIsScanning = true; // optimistic, to allow all callbacks to check this - if (PlatformMgrImpl().ScheduleOnGLibMainLoopThread(MainLoopStartScan, this, true) != CHIP_NO_ERROR) + if (PlatformMgrImpl().GLibMatterContextInvokeSync(MainLoopStartScan, this) != CHIP_NO_ERROR) { ChipLogError(Ble, "Failed to schedule BLE scan start."); mIsScanning = false; @@ -174,7 +174,7 @@ CHIP_ERROR ChipDeviceScanner::StopScan() mInterfaceChangedSignal = 0; } - if (PlatformMgrImpl().ScheduleOnGLibMainLoopThread(MainLoopStopScan, this, true) != CHIP_NO_ERROR) + if (PlatformMgrImpl().GLibMatterContextInvokeSync(MainLoopStopScan, this) != CHIP_NO_ERROR) { ChipLogError(Ble, "Failed to schedule BLE scan stop."); return CHIP_ERROR_INTERNAL; @@ -183,7 +183,7 @@ CHIP_ERROR ChipDeviceScanner::StopScan() return CHIP_NO_ERROR; } -int ChipDeviceScanner::MainLoopStopScan(ChipDeviceScanner * self) +CHIP_ERROR ChipDeviceScanner::MainLoopStopScan(ChipDeviceScanner * self) { GError * error = nullptr; @@ -199,7 +199,7 @@ int ChipDeviceScanner::MainLoopStopScan(ChipDeviceScanner * self) // references to 'self' here) delegate->OnScanComplete(); - return 0; + return CHIP_NO_ERROR; } void ChipDeviceScanner::SignalObjectAdded(GDBusObjectManager * manager, GDBusObject * object, ChipDeviceScanner * self) @@ -266,7 +266,7 @@ void ChipDeviceScanner::RemoveDevice(BluezDevice1 * device) } } -int ChipDeviceScanner::MainLoopStartScan(ChipDeviceScanner * self) +CHIP_ERROR ChipDeviceScanner::MainLoopStartScan(ChipDeviceScanner * self) { GError * error = nullptr; @@ -308,7 +308,7 @@ int ChipDeviceScanner::MainLoopStartScan(ChipDeviceScanner * self) self->mDelegate->OnScanComplete(); } - return 0; + return CHIP_NO_ERROR; } } // namespace Internal diff --git a/src/platform/Linux/bluez/ChipDeviceScanner.h b/src/platform/Linux/bluez/ChipDeviceScanner.h index f81f923dfb3b47..ad12ba9b31c8d8 100644 --- a/src/platform/Linux/bluez/ChipDeviceScanner.h +++ b/src/platform/Linux/bluez/ChipDeviceScanner.h @@ -79,8 +79,8 @@ class ChipDeviceScanner private: static void TimerExpiredCallback(chip::System::Layer * layer, void * appState); - static int MainLoopStartScan(ChipDeviceScanner * self); - static int MainLoopStopScan(ChipDeviceScanner * self); + static CHIP_ERROR MainLoopStartScan(ChipDeviceScanner * self); + static CHIP_ERROR MainLoopStopScan(ChipDeviceScanner * self); static void SignalObjectAdded(GDBusObjectManager * manager, GDBusObject * object, ChipDeviceScanner * self); static void SignalInterfaceChanged(GDBusObjectManagerClient * manager, GDBusObjectProxy * object, GDBusProxy * aInterface, GVariant * aChangedProperties, const gchar * const * aInvalidatedProps, diff --git a/src/platform/Linux/bluez/Helper.cpp b/src/platform/Linux/bluez/Helper.cpp index ff0c73d1214c8c..f73d4ccb392ba9 100644 --- a/src/platform/Linux/bluez/Helper.cpp +++ b/src/platform/Linux/bluez/Helper.cpp @@ -251,7 +251,7 @@ static void BluezAdvStopDone(GObject * aObject, GAsyncResult * aResult, gpointer g_error_free(error); } -static gboolean BluezAdvSetup(BluezEndpoint * endpoint) +static CHIP_ERROR BluezAdvSetup(BluezEndpoint * endpoint) { BluezLEAdvertisement1 * adv; @@ -263,10 +263,10 @@ static gboolean BluezAdvSetup(BluezEndpoint * endpoint) VerifyOrExit(adv != nullptr, ChipLogError(DeviceLayer, "FAIL: NULL adv in %s", __func__)); exit: - return G_SOURCE_REMOVE; + return CHIP_NO_ERROR; } -static gboolean BluezAdvStart(BluezEndpoint * endpoint) +static CHIP_ERROR BluezAdvStart(BluezEndpoint * endpoint) { GDBusObject * adapter; BluezLEAdvertisingManager1 * advMgr = nullptr; @@ -291,10 +291,10 @@ static gboolean BluezAdvStart(BluezEndpoint * endpoint) endpoint); exit: - return G_SOURCE_REMOVE; + return CHIP_NO_ERROR; } -static gboolean BluezAdvStop(BluezEndpoint * endpoint) +static CHIP_ERROR BluezAdvStop(BluezEndpoint * endpoint) { GDBusObject * adapter; BluezLEAdvertisingManager1 * advMgr = nullptr; @@ -313,7 +313,7 @@ static gboolean BluezAdvStop(BluezEndpoint * endpoint) bluez_leadvertising_manager1_call_unregister_advertisement(advMgr, endpoint->mpAdvPath, nullptr, BluezAdvStopDone, endpoint); exit: - return G_SOURCE_REMOVE; + return CHIP_NO_ERROR; } static gboolean BluezCharacteristicReadValue(BluezGattCharacteristic1 * aChar, GDBusMethodInvocation * aInvocation, @@ -843,7 +843,7 @@ static void BluezPeripheralRegisterAppDone(GObject * aObject, GAsyncResult * aRe } } -gboolean BluezPeripheralRegisterApp(BluezEndpoint * endpoint) +static CHIP_ERROR BluezPeripheralRegisterApp(BluezEndpoint * endpoint) { GDBusObject * adapter; BluezGattManager1 * gattMgr; @@ -865,7 +865,7 @@ gboolean BluezPeripheralRegisterApp(BluezEndpoint * endpoint) nullptr); exit: - return G_SOURCE_REMOVE; + return CHIP_NO_ERROR; } /// Update the table of open BLE connections whevener a new device is spotted or its attributes have changed. @@ -1343,7 +1343,7 @@ static void BluezOnNameLost(GDBusConnection * aConn, const gchar * aName, gpoint } #endif -static int StartupEndpointBindings(BluezEndpoint * endpoint) +static CHIP_ERROR StartupEndpointBindings(BluezEndpoint * endpoint) { GDBusObjectManager * manager; GError * error = nullptr; @@ -1378,10 +1378,10 @@ static int StartupEndpointBindings(BluezEndpoint * endpoint) if (error != nullptr) g_error_free(error); - return 0; + return CHIP_NO_ERROR; } -static gboolean BluezC2Indicate(ConnectionDataBundle * closure) +static CHIP_ERROR BluezC2Indicate(ConnectionDataBundle * closure) { BluezConnection * conn = nullptr; GError * error = nullptr; @@ -1424,7 +1424,8 @@ static gboolean BluezC2Indicate(ConnectionDataBundle * closure) if (error != nullptr) g_error_free(error); - return G_SOURCE_REMOVE; + + return CHIP_NO_ERROR; } static ConnectionDataBundle * MakeConnectionDataBundle(BLE_CONNECTION_OBJECT apConn, const chip::System::PacketBufferHandle & apBuf) @@ -1439,10 +1440,10 @@ static ConnectionDataBundle * MakeConnectionDataBundle(BLE_CONNECTION_OBJECT apC CHIP_ERROR SendBluezIndication(BLE_CONNECTION_OBJECT apConn, chip::System::PacketBufferHandle apBuf) { VerifyOrReturnError(!apBuf.IsNull(), CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(DeviceLayer, "apBuf is NULL in %s", __func__)); - return PlatformMgrImpl().ScheduleOnGLibMainLoopThread(BluezC2Indicate, MakeConnectionDataBundle(apConn, apBuf)); + return PlatformMgrImpl().GLibMatterContextInvokeSync(BluezC2Indicate, MakeConnectionDataBundle(apConn, apBuf)); } -static gboolean BluezDisconnect(void * apClosure) +static CHIP_ERROR BluezDisconnect(void * apClosure) { BluezConnection * conn = static_cast(apClosure); GError * error = nullptr; @@ -1459,23 +1460,22 @@ static gboolean BluezDisconnect(void * apClosure) exit: if (error != nullptr) g_error_free(error); - return G_SOURCE_REMOVE; + return CHIP_NO_ERROR; } -static int CloseBleconnectionCB(void * apAppState) +static CHIP_ERROR CloseBleconnectionCB(void * apAppState) { - BluezDisconnect(apAppState); - return G_SOURCE_REMOVE; + return BluezDisconnect(apAppState); } CHIP_ERROR CloseBluezConnection(BLE_CONNECTION_OBJECT apConn) { - return PlatformMgrImpl().ScheduleOnGLibMainLoopThread(CloseBleconnectionCB, apConn); + return PlatformMgrImpl().GLibMatterContextInvokeSync(CloseBleconnectionCB, apConn); } CHIP_ERROR StartBluezAdv(BluezEndpoint * apEndpoint) { - CHIP_ERROR err = PlatformMgrImpl().ScheduleOnGLibMainLoopThread(BluezAdvStart, apEndpoint); + CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync(BluezAdvStart, apEndpoint); VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Ble, "Failed to schedule BluezAdvStart() on CHIPoBluez thread")); return err; @@ -1483,7 +1483,7 @@ CHIP_ERROR StartBluezAdv(BluezEndpoint * apEndpoint) CHIP_ERROR StopBluezAdv(BluezEndpoint * apEndpoint) { - CHIP_ERROR err = PlatformMgrImpl().ScheduleOnGLibMainLoopThread(BluezAdvStop, apEndpoint); + CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync(BluezAdvStop, apEndpoint); VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Ble, "Failed to schedule BluezAdvStop() on CHIPoBluez thread")); return err; @@ -1491,7 +1491,7 @@ CHIP_ERROR StopBluezAdv(BluezEndpoint * apEndpoint) CHIP_ERROR BluezAdvertisementSetup(BluezEndpoint * apEndpoint) { - CHIP_ERROR err = PlatformMgrImpl().ScheduleOnGLibMainLoopThread(BluezAdvSetup, apEndpoint); + CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync(BluezAdvSetup, apEndpoint); VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Ble, "Failed to schedule BluezAdvSetup() on CHIPoBluez thread")); return err; @@ -1499,7 +1499,7 @@ CHIP_ERROR BluezAdvertisementSetup(BluezEndpoint * apEndpoint) CHIP_ERROR BluezGattsAppRegister(BluezEndpoint * apEndpoint) { - CHIP_ERROR err = PlatformMgrImpl().ScheduleOnGLibMainLoopThread(BluezPeripheralRegisterApp, apEndpoint); + CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync(BluezPeripheralRegisterApp, apEndpoint); VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Ble, "Failed to schedule BluezPeripheralRegisterApp() on CHIPoBluez thread")); return err; @@ -1564,7 +1564,7 @@ CHIP_ERROR InitBluezBleLayer(bool aIsCentral, char * apBleAddr, BLEAdvConfig & a endpoint->mpConnectCancellable = g_cancellable_new(); } - err = PlatformMgrImpl().ScheduleOnGLibMainLoopThread(StartupEndpointBindings, endpoint, true); + err = PlatformMgrImpl().GLibMatterContextInvokeSync(StartupEndpointBindings, endpoint); VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(DeviceLayer, "Failed to schedule endpoint initialization")); retval = TRUE; @@ -1607,7 +1607,7 @@ static void SendWriteRequestDone(GObject * aObject, GAsyncResult * aResult, gpoi g_error_free(error); } -static gboolean SendWriteRequestImpl(ConnectionDataBundle * data) +static CHIP_ERROR SendWriteRequestImpl(ConnectionDataBundle * data) { GVariant * options = nullptr; GVariantBuilder optionsBuilder; @@ -1625,13 +1625,13 @@ static gboolean SendWriteRequestImpl(ConnectionDataBundle * data) exit: g_free(data); - return G_SOURCE_REMOVE; + return CHIP_NO_ERROR; } CHIP_ERROR BluezSendWriteRequest(BLE_CONNECTION_OBJECT apConn, chip::System::PacketBufferHandle apBuf) { VerifyOrReturnError(!apBuf.IsNull(), CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(DeviceLayer, "apBuf is NULL in %s", __func__)); - return PlatformMgrImpl().ScheduleOnGLibMainLoopThread(SendWriteRequestImpl, MakeConnectionDataBundle(apConn, apBuf)); + return PlatformMgrImpl().GLibMatterContextInvokeSync(SendWriteRequestImpl, MakeConnectionDataBundle(apConn, apBuf)); } // BluezSubscribeCharacteristic callbacks @@ -1665,7 +1665,7 @@ static void SubscribeCharacteristicDone(GObject * aObject, GAsyncResult * aResul g_error_free(error); } -static gboolean SubscribeCharacteristicImpl(BluezConnection * connection) +static CHIP_ERROR SubscribeCharacteristicImpl(BluezConnection * connection) { BluezGattCharacteristic1 * c2 = nullptr; VerifyOrExit(connection != nullptr, ChipLogError(DeviceLayer, "BluezConnection is NULL in %s", __func__)); @@ -1677,12 +1677,12 @@ static gboolean SubscribeCharacteristicImpl(BluezConnection * connection) bluez_gatt_characteristic1_call_start_notify(connection->mpC2, nullptr, SubscribeCharacteristicDone, connection); exit: - return G_SOURCE_REMOVE; + return CHIP_NO_ERROR; } CHIP_ERROR BluezSubscribeCharacteristic(BLE_CONNECTION_OBJECT apConn) { - return PlatformMgrImpl().ScheduleOnGLibMainLoopThread(SubscribeCharacteristicImpl, static_cast(apConn)); + return PlatformMgrImpl().GLibMatterContextInvokeSync(SubscribeCharacteristicImpl, static_cast(apConn)); } // BluezUnsubscribeCharacteristic callbacks @@ -1704,7 +1704,7 @@ static void UnsubscribeCharacteristicDone(GObject * aObject, GAsyncResult * aRes g_error_free(error); } -static gboolean UnsubscribeCharacteristicImpl(BluezConnection * connection) +static CHIP_ERROR UnsubscribeCharacteristicImpl(BluezConnection * connection) { VerifyOrExit(connection != nullptr, ChipLogError(DeviceLayer, "BluezConnection is NULL in %s", __func__)); VerifyOrExit(connection->mpC2 != nullptr, ChipLogError(DeviceLayer, "C2 is NULL in %s", __func__)); @@ -1712,12 +1712,12 @@ static gboolean UnsubscribeCharacteristicImpl(BluezConnection * connection) bluez_gatt_characteristic1_call_stop_notify(connection->mpC2, nullptr, UnsubscribeCharacteristicDone, connection); exit: - return G_SOURCE_REMOVE; + return CHIP_NO_ERROR; } CHIP_ERROR BluezUnsubscribeCharacteristic(BLE_CONNECTION_OBJECT apConn) { - return PlatformMgrImpl().ScheduleOnGLibMainLoopThread(UnsubscribeCharacteristicImpl, static_cast(apConn)); + return PlatformMgrImpl().GLibMatterContextInvokeSync(UnsubscribeCharacteristicImpl, static_cast(apConn)); } // ConnectDevice callbacks @@ -1772,7 +1772,7 @@ static void ConnectDeviceDone(GObject * aObject, GAsyncResult * aResult, gpointe g_error_free(error); } -static gboolean ConnectDeviceImpl(ConnectParams * apParams) +static CHIP_ERROR ConnectDeviceImpl(ConnectParams * apParams) { BluezDevice1 * device = apParams->mDevice; BluezEndpoint * endpoint = apParams->mEndpoint; @@ -1784,7 +1784,7 @@ static gboolean ConnectDeviceImpl(ConnectParams * apParams) bluez_device1_call_connect(device, endpoint->mpConnectCancellable, ConnectDeviceDone, apParams); g_object_unref(device); - return G_SOURCE_REMOVE; + return CHIP_NO_ERROR; } CHIP_ERROR ConnectDevice(BluezDevice1 * apDevice, BluezEndpoint * apEndpoint) @@ -1792,7 +1792,7 @@ CHIP_ERROR ConnectDevice(BluezDevice1 * apDevice, BluezEndpoint * apEndpoint) auto params = chip::Platform::New(apDevice, apEndpoint); g_object_ref(apDevice); - if (PlatformMgrImpl().ScheduleOnGLibMainLoopThread(ConnectDeviceImpl, params) != CHIP_NO_ERROR) + if (PlatformMgrImpl().GLibMatterContextInvokeSync(ConnectDeviceImpl, params) != CHIP_NO_ERROR) { ChipLogError(Ble, "Failed to schedule ConnectDeviceImpl() on CHIPoBluez thread"); g_object_unref(apDevice); From 5568b709a86e6c90344534dfaf805409259c6cdf Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Thu, 13 Apr 2023 19:25:40 -0400 Subject: [PATCH 08/23] [Silabs] Fix compilation issues with gcc 12.2 (#26090) * disable -Werror=array-parameter= for gsdk sources build * Fix compilation issues with gcc arm 12.2 * Restyled by whitespace * Comment the cflag -Wno-error=array-parameter until gcc 12.2 is used --------- Co-authored-by: Restyled.io --- examples/platform/silabs/efr32/BUILD.gn | 5 + examples/platform/silabs/syscalls_stubs.cpp | 215 ++++++++++++++++++ .../silabs/KeyValueStoreManagerImpl.cpp | 2 +- third_party/silabs/efr32_sdk.gni | 4 + 4 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 examples/platform/silabs/syscalls_stubs.cpp diff --git a/examples/platform/silabs/efr32/BUILD.gn b/examples/platform/silabs/efr32/BUILD.gn index 05f9c6797c0b69..aaa3213138e8eb 100644 --- a/examples/platform/silabs/efr32/BUILD.gn +++ b/examples/platform/silabs/efr32/BUILD.gn @@ -227,6 +227,10 @@ config("efr32-common-config") { if (enable_heap_monitoring) { defines += [ "HEAP_MONITORING" ] } + + # Do not warn for LOAD segment with RWX permissions + # Uncomment this cflag when pigweed update is done and GCC 12.2 is used. + #ldflags = [ "-Wl,--no-warn-rwx-segment" ] } config("silabs-wifi-config") { @@ -279,6 +283,7 @@ source_set("efr32-common") { sources = [ "${silabs_common_plat_dir}/heap_4_silabs.c", + "${silabs_common_plat_dir}/syscalls_stubs.cpp", "efr32_utils.cpp", "init_efrPlatform.cpp", "matter_config.cpp", diff --git a/examples/platform/silabs/syscalls_stubs.cpp b/examples/platform/silabs/syscalls_stubs.cpp new file mode 100644 index 00000000000000..f6a845639c6e7c --- /dev/null +++ b/examples/platform/silabs/syscalls_stubs.cpp @@ -0,0 +1,215 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ + +/* + This file is only used to implement weak syscall stubs + that gcc-arm-none-eabi 12.2.1 expect to link when using Libc + (newlib/libc_nano) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if SILABS_LOG_OUT_UART +#include "uart.h" +#endif + +int _close(int file); +int _fstat(int file, struct stat * st); +int _isatty(int file); +int _lseek(int file, int ptr, int dir); +int _read(int file, char * ptr, int len); +int _write(int file, const char * ptr, int len); + +/************************************************************************** + * @brief + * Close a file. + * + * @param[in] file + * File you want to close. + * + * @return + * Returns 0 when the file is closed. + **************************************************************************/ +int __attribute__((weak)) _close(int file) +{ + (void) file; + return 0; +} + +/************************************************************************** + * @brief Exit the program. + * @param[in] status The value to return to the parent process as the + * exit status (not used). + **************************************************************************/ +void __attribute__((weak)) _exit(int status) +{ + (void) status; + while (1) + { + } /* Hang here forever... */ +} + +/************************************************************************* + * @brief + * Status of an open file. + * + * @param[in] file + * Check status for this file. + * + * @param[in] st + * Status information. + * + * @return + * Returns 0 when st_mode is set to character special. + ************************************************************************/ +int __attribute__((weak)) _fstat(int file, struct stat * st) +{ + (void) file; + (void) st; + return 0; +} + +/************************************************************************** + * @brief Get process ID. + *************************************************************************/ +int __attribute__((weak)) _getpid(void) +{ + return 1; +} + +/************************************************************************** + * @brief + * Query whether output stream is a terminal. + * + * @param[in] file + * Descriptor for the file. + * + * @return + * Returns 1 when query is done. + **************************************************************************/ +int __attribute__((weak)) _isatty(int file) +{ + (void) file; + return 1; +} + +/************************************************************************** + * @brief Send signal to process. + * @param[in] pid Process id (not used). + * @param[in] sig Signal to send (not used). + *************************************************************************/ +int __attribute__((weak)) _kill(int pid, int sig) +{ + (void) pid; + (void) sig; + return -1; +} + +/************************************************************************** + * @brief + * Set position in a file. + * + * @param[in] file + * Descriptor for the file. + * + * @param[in] ptr + * Poiter to the argument offset. + * + * @param[in] dir + * Directory whence. + * + * @return + * Returns 0 when position is set. + *************************************************************************/ +int __attribute__((weak)) _lseek(int file, int ptr, int dir) +{ + (void) file; + (void) ptr; + (void) dir; + return 0; +} + +/************************************************************************** + * @brief + * Read from a file. + * + * @param[in] file + * Descriptor for the file you want to read from. + * + * @param[in] ptr + * Pointer to the chacaters that are beeing read. + * + * @param[in] len + * Number of characters to be read. + * + * @return + * Number of characters that have been read. + *************************************************************************/ +int __attribute__((weak)) _read(int file, char * ptr, int len) +{ + (void) file; +#if SILABS_LOG_OUT_UART + return = uartConsoleRead(ptr, len); +#else + (void) ptr; + (void) len; +#endif + return 0; +} + +/************************************************************************** + * @brief + * Write to a file. + * + * @param[in] file + * Descriptor for the file you want to write to. + * + * @param[in] ptr + * Pointer to the text you want to write + * + * @param[in] len + * Number of characters to be written. + * + * @return + * Number of characters that have been written. + **************************************************************************/ +int __attribute__((weak)) _write(int file, const char * ptr, int len) +{ + (void) file; +#if SILABS_LOG_OUT_UART + uartConsoleWrite(ptr, len); +#else + (void) ptr; +#endif + + return len; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/platform/silabs/KeyValueStoreManagerImpl.cpp b/src/platform/silabs/KeyValueStoreManagerImpl.cpp index ffff7b945186bb..88b494d9771448 100644 --- a/src/platform/silabs/KeyValueStoreManagerImpl.cpp +++ b/src/platform/silabs/KeyValueStoreManagerImpl.cpp @@ -75,7 +75,7 @@ uint16_t KeyValueStoreManagerImpl::hashKvsKeyString(const char * key) const uint8_t hash256[Crypto::kSHA256_Hash_Length] = { 0 }; Crypto::Hash_SHA256(reinterpret_cast(key), strlen(key), hash256); - uint16_t hash16, i = 0; + uint16_t hash16 = 0, i = 0; while (!hash16 && (i < (Crypto::kSHA256_Hash_Length - 1))) { diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index 55ff1066d214ff..baf89660ce836b 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -502,6 +502,10 @@ template("efr32_sdk") { cflags += [ "-Wno-maybe-uninitialized", "-Wno-shadow", + + # see https://github.com/project-chip/connectedhomeip/issues/26058 + # Uncomment this cflag when pigweed update is done and GCC 12.2 is used. + # "-Wno-error=array-parameter", ] if (silabs_family == "efr32mg24" || silabs_family == "mgm24") { From faf548c06e411f6b0a22276604c78465935ed9ee Mon Sep 17 00:00:00 2001 From: kliffQorvo <130646729+kliffQorvo@users.noreply.github.com> Date: Fri, 14 Apr 2023 02:01:31 +0100 Subject: [PATCH 09/23] Fix LED status after reset (#26081) --- examples/lighting-app/qpg/src/AppTask.cpp | 4 ++++ examples/lock-app/qpg/src/AppTask.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/examples/lighting-app/qpg/src/AppTask.cpp b/examples/lighting-app/qpg/src/AppTask.cpp index f88ea503a91fdb..ba75fa7fbf4b0e 100644 --- a/examples/lighting-app/qpg/src/AppTask.cpp +++ b/examples/lighting-app/qpg/src/AppTask.cpp @@ -299,6 +299,10 @@ CHIP_ERROR AppTask::Init() ConfigurationMgr().LogDeviceConfig(); PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); + sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); + sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0); + sIsBLEAdvertisingEnabled = ConnectivityMgr().IsBLEAdvertisingEnabled(); UpdateLEDs(); return err; diff --git a/examples/lock-app/qpg/src/AppTask.cpp b/examples/lock-app/qpg/src/AppTask.cpp index b5c5d73fb723c1..a9cfa9df861607 100644 --- a/examples/lock-app/qpg/src/AppTask.cpp +++ b/examples/lock-app/qpg/src/AppTask.cpp @@ -177,6 +177,10 @@ CHIP_ERROR AppTask::Init() ConfigurationMgr().LogDeviceConfig(); PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); + sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); + sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0); + sIsBLEAdvertisingEnabled = ConnectivityMgr().IsBLEAdvertisingEnabled(); UpdateLEDs(); return err; From f31e396560dff9886f0450feaad6d0859fae263b Mon Sep 17 00:00:00 2001 From: Timothy Maes Date: Fri, 14 Apr 2023 03:14:41 +0200 Subject: [PATCH 10/23] Update qpg_sdk for GCC 12.2 compiler warnings (#26094) --- third_party/qpg_sdk/repo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/qpg_sdk/repo b/third_party/qpg_sdk/repo index 3e8aacf8e5eec9..1f0c845a7de8ad 160000 --- a/third_party/qpg_sdk/repo +++ b/third_party/qpg_sdk/repo @@ -1 +1 @@ -Subproject commit 3e8aacf8e5eec98a7a937ce399d43b4bbe4a4864 +Subproject commit 1f0c845a7de8ad2b81f07bfa4c83e6a8f22dbe99 From 62974a091b0366a18a8e88222121bbeea936dc9c Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Thu, 13 Apr 2023 21:17:12 -0400 Subject: [PATCH 11/23] Fix pigweedlogger assert. Wait until the previous send has completed/empty the buffer before verifing if we have enough space in the send buffer (#26093) --- examples/platform/silabs/PigweedLogger.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/platform/silabs/PigweedLogger.cpp b/examples/platform/silabs/PigweedLogger.cpp index de816da1cc6b81..280b232374ffcb 100644 --- a/examples/platform/silabs/PigweedLogger.cpp +++ b/examples/platform/silabs/PigweedLogger.cpp @@ -68,9 +68,8 @@ void init(void) int putString(const char * buffer, size_t size) { - assert(sWriteBufferPos < kWriteBufferSize); - xSemaphoreTake(sLoggerLock, portMAX_DELAY); + assert(sWriteBufferPos < kWriteBufferSize); for (size_t i = 0; i < size; ++i) { From 6d2841bbfd4d277289428ffbadd618ad5fb8dc71 Mon Sep 17 00:00:00 2001 From: Rohit Jadhav <69809379+jadhavrohit924@users.noreply.github.com> Date: Fri, 14 Apr 2023 16:21:57 +0530 Subject: [PATCH 12/23] [ESP32] Added support of mode select for esp32 to read/write SupportedModes attribute from factory partition (#25766) * [ESP32] Added support of mode select for esp32 to read/write SupportedModes attribute from factory partition * Restyled by whitespace * Restyled by clang-format * Restyled by autopep8 * Restyled by isort * Addressed review comments * Free allocated memory * Restyled by whitespace * Restyled by clang-format * Restyled by prettier-markdown * Tested memory leaks * Restyled by clang-format * Restyled by prettier-markdown * Addressed review comments --------- Co-authored-by: Restyled.io --- docs/guides/esp32/factory_data.md | 3 + .../esp32/main/CMakeLists.txt | 6 +- .../static-supported-modes-manager.cpp | 209 ++++++++++++++++++ .../static-supported-modes-manager.h | 69 ++++++ .../tools/generate_esp32_chip_factory_bin.py | 82 +++++++ .../supported-modes-manager.h | 5 +- src/platform/ESP32/ESP32Config.h | 33 +++ 7 files changed, 403 insertions(+), 4 deletions(-) create mode 100644 examples/platform/esp32/mode-support/static-supported-modes-manager.cpp create mode 100644 examples/platform/esp32/mode-support/static-supported-modes-manager.h diff --git a/docs/guides/esp32/factory_data.md b/docs/guides/esp32/factory_data.md index 9818eec9880964..179fb2e315a9c0 100644 --- a/docs/guides/esp32/factory_data.md +++ b/docs/guides/esp32/factory_data.md @@ -34,6 +34,9 @@ Following data can be added to the manufacturing partition using - Fixed Labels - Supported locales - Supported calendar types + - Supported modes + - Note: As per spec at max size of label should be 64 and `\0` will be + added at the end. ### Configuration Options diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index 4b2f6a464e2933..70f17774c00d77 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -32,6 +32,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/common" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/shell_extension" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/lock" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/mode-support" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" @@ -91,6 +92,9 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/src" ) + +set(EXCLUDE_SRCS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp") + if (CONFIG_ENABLE_PW_RPC) # Append additional directories for RPC build set(PRIV_INCLUDE_DIRS_LIST "${PRIV_INCLUDE_DIRS_LIST}" @@ -119,7 +123,7 @@ endif() idf_component_register(PRIV_INCLUDE_DIRS ${PRIV_INCLUDE_DIRS_LIST} SRC_DIRS ${SRC_DIRS_LIST} - EXCLUDE_SRCS ${EXCLUDE_SRCS_LIST} + EXCLUDE_SRCS ${EXCLUDE_SRCS} PRIV_REQUIRES ${PRIV_REQUIRES_LIST}) get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) diff --git a/examples/platform/esp32/mode-support/static-supported-modes-manager.cpp b/examples/platform/esp32/mode-support/static-supported-modes-manager.cpp new file mode 100644 index 00000000000000..ec752cd8be67ba --- /dev/null +++ b/examples/platform/esp32/mode-support/static-supported-modes-manager.cpp @@ -0,0 +1,209 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * 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. + */ + +#include "static-supported-modes-manager.h" +#include +#include +#include + +using namespace chip; +using namespace chip::app::Clusters; +using namespace chip::DeviceLayer::Internal; +using namespace chip::app::Clusters::ModeSelect; +using chip::Protocols::InteractionModel::Status; + +using ModeOptionStructType = Structs::ModeOptionStruct::Type; +using SemanticTag = Structs::SemanticTagStruct::Type; +template +using List = app::DataModel::List; + +const StaticSupportedModesManager StaticSupportedModesManager::instance = StaticSupportedModesManager(); + +SupportedModesManager::ModeOptionsProvider StaticSupportedModesManager::epModeOptionsProviderList[FIXED_ENDPOINT_COUNT]; + +void StaticSupportedModesManager::InitEndpointArray() +{ + for (int i = 0; i < FIXED_ENDPOINT_COUNT; i++) + { + epModeOptionsProviderList[i] = ModeOptionsProvider(); + } +} + +SupportedModesManager::ModeOptionsProvider StaticSupportedModesManager::getModeOptionsProvider(EndpointId endpointId) const +{ + if (epModeOptionsProviderList[endpointId].begin() != nullptr && epModeOptionsProviderList[endpointId].end() != nullptr) + { + return ModeOptionsProvider(epModeOptionsProviderList[endpointId].begin(), epModeOptionsProviderList[endpointId].end()); + } + + ModeOptionStructType * modeOptionStructList = nullptr; + SemanticTag * semanticTags = nullptr; + + char keyBuf[ESP32Config::kMaxConfigKeyNameLength]; + uint32_t supportedModeCount = 0; + + VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesCount(keyBuf, sizeof(keyBuf), endpointId) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr)); + ESP32Config::Key countKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(countKey, supportedModeCount) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr)); + + modeOptionStructList = new ModeOptionStructType[supportedModeCount]; + if (modeOptionStructList == nullptr) + { + return ModeOptionsProvider(nullptr, nullptr); + } + + epModeOptionsProviderList[endpointId] = ModeOptionsProvider(modeOptionStructList, modeOptionStructList + supportedModeCount); + + for (int index = 0; index < supportedModeCount; index++) + { + Structs::ModeOptionStruct::Type option; + uint32_t supportedModeMode = 0; + uint32_t semanticTagCount = 0; + size_t outLen = 0; + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesLabel(keyBuf, sizeof(keyBuf), endpointId, index) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key labelKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(labelKey, nullptr, 0, outLen) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + char * modeLabel = new char[outLen + 1]; + if (modeLabel == nullptr) + { + CleanUp(endpointId); + return ModeOptionsProvider(nullptr, nullptr); + } + + VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(labelKey, modeLabel, outLen + 1, outLen) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesValue(keyBuf, sizeof(keyBuf), endpointId, index) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key modeKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(labelKey, supportedModeMode) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagsCount(keyBuf, sizeof(keyBuf), endpointId, index) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key stCountKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(stCountKey, semanticTagCount) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + semanticTags = new SemanticTag[semanticTagCount]; + if (semanticTags == nullptr) + { + CleanUp(endpointId); + return ModeOptionsProvider(nullptr, nullptr); + } + for (auto stIndex = 0; stIndex < semanticTagCount; stIndex++) + { + + uint32_t semanticTagValue = 0; + uint32_t semanticTagMfgCode = 0; + SemanticTag tag; + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagValue(keyBuf, sizeof(keyBuf), endpointId, index, stIndex) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key stValueKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(stValueKey, semanticTagValue) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagMfgCode(keyBuf, sizeof(keyBuf), endpointId, index, stIndex) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key stMfgCodeKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(stMfgCodeKey, semanticTagMfgCode) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + tag.value = static_cast(semanticTagValue); + tag.mfgCode = static_cast(semanticTagMfgCode); + semanticTags[stIndex] = tag; + } + + option.label = chip::CharSpan::fromCharString(modeLabel); + option.mode = static_cast(supportedModeMode); + option.semanticTags = DataModel::List(semanticTags, semanticTagCount); + + modeOptionStructList[index] = option; + } + + return ModeOptionsProvider(modeOptionStructList, modeOptionStructList + supportedModeCount); +} + +Status StaticSupportedModesManager::getModeOptionByMode(unsigned short endpointId, unsigned char mode, + const ModeOptionStructType ** dataPtr) const +{ + auto modeOptionsProvider = this->getModeOptionsProvider(endpointId); + if (modeOptionsProvider.begin() == nullptr) + { + return Status::UnsupportedCluster; + } + auto * begin = modeOptionsProvider.begin(); + auto * end = modeOptionsProvider.end(); + + for (auto * it = begin; it != end; ++it) + { + auto & modeOption = *it; + if (modeOption.mode == mode) + { + *dataPtr = &modeOption; + return Status::Success; + } + } + emberAfPrintln(EMBER_AF_PRINT_DEBUG, "Cannot find the mode %u", mode); + return Status::InvalidCommand; +} + +const ModeSelect::SupportedModesManager * ModeSelect::getSupportedModesManager() +{ + return &StaticSupportedModesManager::instance; +} + +void StaticSupportedModesManager::FreeSupportedModes(EndpointId endpointId) const +{ + if (epModeOptionsProviderList[endpointId].begin() != nullptr) + { + auto * begin = epModeOptionsProviderList[endpointId].begin(); + auto * end = epModeOptionsProviderList[endpointId].end(); + for (auto * it = begin; it != end; ++it) + { + auto & modeOption = *it; + delete[] modeOption.label.data(); + delete[] modeOption.semanticTags.data(); + } + delete[] begin; + } + epModeOptionsProviderList[endpointId] = ModeOptionsProvider(); +} + +void StaticSupportedModesManager::CleanUp(EndpointId endpointId) const +{ + ChipLogError(Zcl, "Supported mode data is in incorrect format"); + FreeSupportedModes(endpointId); +} diff --git a/examples/platform/esp32/mode-support/static-supported-modes-manager.h b/examples/platform/esp32/mode-support/static-supported-modes-manager.h new file mode 100644 index 00000000000000..689c9d059f4ab7 --- /dev/null +++ b/examples/platform/esp32/mode-support/static-supported-modes-manager.h @@ -0,0 +1,69 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * 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. + */ + +#pragma once + +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ModeSelect { + +class StaticSupportedModesManager : public chip::app::Clusters::ModeSelect::SupportedModesManager +{ +private: + using ModeOptionStructType = Structs::ModeOptionStruct::Type; + using SemanticTag = Structs::SemanticTagStruct::Type; + + static ModeOptionsProvider epModeOptionsProviderList[FIXED_ENDPOINT_COUNT]; + + void InitEndpointArray(); + + void FreeSupportedModes(EndpointId endpointId) const; + +public: + static const StaticSupportedModesManager instance; + + SupportedModesManager::ModeOptionsProvider getModeOptionsProvider(EndpointId endpointId) const override; + + Protocols::InteractionModel::Status getModeOptionByMode(EndpointId endpointId, uint8_t mode, + const ModeOptionStructType ** dataPtr) const override; + + void CleanUp(EndpointId endpointId) const; + + StaticSupportedModesManager() { InitEndpointArray(); } + + ~StaticSupportedModesManager() + { + for (int i = 0; i < FIXED_ENDPOINT_COUNT; i++) + { + FreeSupportedModes(i); + } + } + + static inline const StaticSupportedModesManager & getStaticSupportedModesManagerInstance() { return instance; } +}; + +const SupportedModesManager * getSupportedModesManager(); + +} // namespace ModeSelect +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/scripts/tools/generate_esp32_chip_factory_bin.py b/scripts/tools/generate_esp32_chip_factory_bin.py index fac1c274e70a67..f5744720c6fc6c 100755 --- a/scripts/tools/generate_esp32_chip_factory_bin.py +++ b/scripts/tools/generate_esp32_chip_factory_bin.py @@ -226,6 +226,32 @@ def get_fixed_label_dict(fixed_labels): return fl_dict +# get_supported_modes_dict() converts the list of strings to per endpoint dictionaries. +# example input : ['0/label1/1/"1\0x8000, 2\0x8000", 1/label2/1/"1\0x8000, 2\0x8000"'] +# example outout : {'1': [{'Label': 'label1', 'Mode': 0, 'Semantic_Tag': [{'value': 1, 'mfgCode': 32768}, {'value': 2, 'mfgCode': 32768}]}, {'Label': 'label2', 'Mode': 1, 'Semantic_Tag': [{'value': 1, 'mfgCode': 32768}, {'value': 2, 'mfgCode': 32768}]}]} + + +def get_supported_modes_dict(supported_modes): + output_dict = {} + + for mode_str in supported_modes: + mode_label_strs = mode_str.split('/') + mode = mode_label_strs[0] + label = mode_label_strs[1] + ep = mode_label_strs[2] + + semantic_tag_strs = mode_label_strs[3].split(', ') + semantic_tags = [{"value": int(v.split('\\')[0]), "mfgCode": int(v.split('\\')[1], 16)} for v in semantic_tag_strs] + + mode_dict = {"Label": label, "Mode": int(mode), "Semantic_Tag": semantic_tags} + + if ep in output_dict: + output_dict[ep].append(mode_dict) + else: + output_dict[ep] = [mode_dict] + + return output_dict + def check_str_range(s, min_len, max_len, name): if s and ((len(s) < min_len) or (len(s) > max_len)): @@ -358,6 +384,60 @@ def populate_factory_data(args, spake2p_params): FACTORY_DATA.update({'fl-k/{:x}/{:x}'.format(int(key), i): _label_key}) FACTORY_DATA.update({'fl-v/{:x}/{:x}'.format(int(key), i): _label_value}) + # SupportedModes are stored as multiple entries + # - sm-sz/ : number of supported modes for the endpoint + # - sm-label// : supported modes label key for the endpoint and index + # - sm-mode// : supported modes mode key for the endpoint and index + # - sm-st-sz// : supported modes SemanticTag key for the endpoint and index + # - st-v/// : semantic tag value key for the endpoint and index and ind + # - st-mfg/// : semantic tag mfg code key for the endpoint and index and ind + if (args.supported_modes is not None): + dictionary = get_supported_modes_dict(args.supported_modes) + for ep in dictionary.keys(): + _sz = { + 'type': 'data', + 'encoding': 'u32', + 'value': len(dictionary[ep]) + } + FACTORY_DATA.update({'sm-sz/{:x}'.format(int(ep)): _sz}) + for i in range(len(dictionary[ep])): + item = dictionary[ep][i] + _label = { + 'type': 'data', + 'encoding': 'string', + 'value': item["Label"] + } + _mode = { + 'type': 'data', + 'encoding': 'u32', + 'value': item["Mode"] + } + _st_sz = { + 'type': 'data', + 'encoding': 'u32', + 'value': len(item["Semantic_Tag"]) + } + FACTORY_DATA.update({'sm-label/{:x}/{:x}'.format(int(ep), i): _label}) + FACTORY_DATA.update({'sm-mode/{:x}/{:x}'.format(int(ep), i): _mode}) + FACTORY_DATA.update({'sm-st-sz/{:x}/{:x}'.format(int(ep), i): _st_sz}) + + for j in range(len(item["Semantic_Tag"])): + entry = item["Semantic_Tag"][j] + + _value = { + 'type': 'data', + 'encoding': 'u32', + 'value': entry["value"] + } + _mfg_code = { + 'type': 'data', + 'encoding': 'u32', + 'value': entry["mfgCode"] + } + + FACTORY_DATA.update({'st-v/{:x}/{:x}/{:x}'.format(int(ep), i, j): _value}) + FACTORY_DATA.update({'st-mfg/{:x}/{:x}/{:x}'.format(int(ep), i, j): _mfg_code}) + def gen_raw_ec_keypair_from_der(key_file, pubkey_raw_file, privkey_raw_file): with open(key_file, 'rb') as f: @@ -467,6 +547,8 @@ def any_base_int(s): return int(s, 0) parser.add_argument('--locales', nargs='+', help='List of supported locales, Language Tag as defined by BCP47, eg. en-US en-GB') parser.add_argument('--fixed-labels', nargs='+', help='List of fixed labels, eg: "0/orientation/up" "1/orientation/down" "2/orientation/down"') + parser.add_argument('--supported-modes', type=str, nargs='+', required=False, + help='List of supported modes, eg: mode1/label1/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode" mode2/label2/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode" mode3/label3/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode"') parser.add_argument('-s', '--size', type=any_base_int, default=0x6000, help='The size of the partition.bin, default: 0x6000') diff --git a/src/app/clusters/mode-select-server/supported-modes-manager.h b/src/app/clusters/mode-select-server/supported-modes-manager.h index 497a604497200a..4a6ccd20c5f60a 100644 --- a/src/app/clusters/mode-select-server/supported-modes-manager.h +++ b/src/app/clusters/mode-select-server/supported-modes-manager.h @@ -20,9 +20,6 @@ #include #include -#include -#include -#include #include namespace chip { @@ -56,6 +53,8 @@ class SupportedModesManager */ inline pointer end() const { return mEnd; } + ModeOptionsProvider() : mBegin(nullptr), mEnd(nullptr) {} + ModeOptionsProvider(const pointer aBegin, const pointer aEnd) : mBegin(aBegin), mEnd(aEnd) {} pointer mBegin; diff --git a/src/platform/ESP32/ESP32Config.h b/src/platform/ESP32/ESP32Config.h index c85303c2197555..e07d98eba27594 100644 --- a/src/platform/ESP32/ESP32Config.h +++ b/src/platform/ESP32/ESP32Config.h @@ -180,6 +180,39 @@ class ESP32Config::KeyAllocator VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT); return snprintf(key, size, "fl-v/%x/%x", endpoint, index) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; } + + // Supported modes + + static CHIP_ERROR SupportedModesCount(char * key, size_t size, uint16_t endpoint) + { + VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT); + return snprintf(key, size, "sm-sz/%x", endpoint) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + } + static CHIP_ERROR SupportedModesLabel(char * key, size_t size, uint16_t endpoint, uint16_t index) + { + VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT); + return snprintf(key, size, "sm-label/%x/%x", endpoint, index) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + } + static CHIP_ERROR SupportedModesValue(char * key, size_t size, uint16_t endpoint, uint16_t index) + { + VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT); + return snprintf(key, size, "sm-mode/%x/%x", endpoint, index) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + } + static CHIP_ERROR SemanticTagsCount(char * key, size_t size, uint16_t endpoint, uint16_t index) + { + VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT); + return snprintf(key, size, "sm-st-sz/%x/%x", endpoint, index) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + } + static CHIP_ERROR SemanticTagValue(char * key, size_t size, uint16_t endpoint, uint16_t index, uint16_t ind) + { + VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT); + return snprintf(key, size, "st-v/%x/%x/%x", endpoint, index, ind) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + } + static CHIP_ERROR SemanticTagMfgCode(char * key, size_t size, uint16_t endpoint, uint16_t index, uint16_t ind) + { + VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT); + return snprintf(key, size, "st-mfg/%x/%x/%x", endpoint, index, ind) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + } }; } // namespace Internal From 993fc262026fbf46b22b3156f8cdb1ed5970244d Mon Sep 17 00:00:00 2001 From: Rohan Sahay Date: Fri, 14 Apr 2023 16:47:43 +0530 Subject: [PATCH 13/23] [Silabs] Adds fix for SPI corruption when SPI was multiplexed (#26080) * Adds re factored code with the use of DMA * Changes ordering of spi_cs_assert * Add logs * Reverts SPI drvier re-init from post APIs * Revert changes * Adds delay and disable autoCsEnable * Revert "Adds delay and disable autoCsEnable" This reverts commit d038bb6dd9291313faa1d4e39a0ade8bb3626866. * Adds code to make SL_SPIDRV_HANDLE available in multiplex logic * Adds working logic * Cleanup logs and comments * Adds temporary fix * Use the config provided BITRATE * Revert "Use the config provided BITRATE" This reverts commit 05574a3c137c6666559f433f824205541cf9e538. * Use MY_USART instead of USART0 * Adds guard to check for current and incoming baudrate * Revert MY_USART to USART0 * Requires multiplexing if SL_WIFI is present * Update examples/platform/silabs/efr32/spi_multiplex.c Co-authored-by: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> --------- Co-authored-by: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> --- .../platform/silabs/efr32/display/lcd.cpp | 6 -- .../platform/silabs/efr32/spi_multiplex.c | 41 ++--------- .../platform/silabs/efr32/spi_multiplex.h | 27 ++++---- .../platform/silabs/efr32/wf200/efr_spi.c | 68 ++++++++----------- 4 files changed, 50 insertions(+), 92 deletions(-) diff --git a/examples/platform/silabs/efr32/display/lcd.cpp b/examples/platform/silabs/efr32/display/lcd.cpp index 37ccb0dedbb1d5..561c02451686ee 100644 --- a/examples/platform/silabs/efr32/display/lcd.cpp +++ b/examples/platform/silabs/efr32/display/lcd.cpp @@ -71,12 +71,6 @@ CHIP_ERROR SilabsLCD::Init(uint8_t * name, bool initialState) err = CHIP_ERROR_INTERNAL; } -#if (defined(EFR32MG24) && defined(WF200_WIFI)) - if (pr_type != LCD) - { - pr_type = LCD; - } -#endif /* Initialize the DMD module for the DISPLAY device driver. */ status = DMD_init(0); if (DMD_OK != status) diff --git a/examples/platform/silabs/efr32/spi_multiplex.c b/examples/platform/silabs/efr32/spi_multiplex.c index 137c3973aa846e..6b8d6539d760c5 100644 --- a/examples/platform/silabs/efr32/spi_multiplex.c +++ b/examples/platform/silabs/efr32/spi_multiplex.c @@ -38,6 +38,11 @@ *****************************************************************************/ void spi_drv_reinit(uint32_t baudrate) { + if (USART_BaudrateGet(USART0) == baudrate) + { + // USART synced to baudrate already + return; + } // USART is used in MG24 + WF200 combination USART_InitSync_TypeDef usartInit = USART_INITSYNC_DEFAULT; usartInit.msbf = true; @@ -50,29 +55,6 @@ void spi_drv_reinit(uint32_t baudrate) USART_InitSync(USART0, &usartInit); } -/**************************************************************************** - * @fn void set_spi_baudrate() - * @brief - * Setting the appropriate SPI baudrate - * @param[in] None - * @return returns void - *****************************************************************************/ -void set_spi_baudrate(peripheraltype_t pr_type) -{ - if (pr_type == LCD) - { - spi_drv_reinit(LCD_BIT_RATE); - } - else if (pr_type == EXP_HDR) - { - spi_drv_reinit(EXP_HDR_BIT_RATE); - } - else if (pr_type == EXT_SPIFLASH) - { - spi_drv_reinit(SPI_FLASH_BIT_RATE); - } -} - /**************************************************************************** * @fn void spiflash_cs_assert() * @brief @@ -110,14 +92,10 @@ void pre_bootloader_spi_transfer(void) { return; } - /* - * CS for Expansion header controlled within GSDK, - * however we need to ensure CS for Expansion header is High/disabled before use of EXT SPI Flash - */ - sl_wfx_host_spi_cs_deassert(); /* * Assert CS pin for EXT SPI Flash */ + spi_drv_reinit(SL_BIT_RATE_SPI_FLASH); spiflash_cs_assert(); } @@ -150,11 +128,7 @@ void pre_lcd_spi_transfer(void) { return; } - if (pr_type != LCD) - { - pr_type = LCD; - set_spi_baudrate(pr_type); - } + spi_drv_reinit(SL_BIT_RATE_LCD); /*LCD CS is handled as part of LCD gsdk*/ } @@ -208,7 +182,6 @@ void post_uart_transfer(void) return; } GPIO_PinModeSet(gpioPortA, 8, gpioModeInputPull, 1); - set_spi_baudrate(EXP_HDR); xSemaphoreGive(spi_sem_sync_hdl); sl_wfx_host_enable_platform_interrupt(); sl_wfx_enable_irq(); diff --git a/examples/platform/silabs/efr32/spi_multiplex.h b/examples/platform/silabs/efr32/spi_multiplex.h index 865e93ff4d8b36..29835962a4dd85 100644 --- a/examples/platform/silabs/efr32/spi_multiplex.h +++ b/examples/platform/silabs/efr32/spi_multiplex.h @@ -25,23 +25,26 @@ extern "C" { #include "sl_mx25_flash_shutdown_usart_config.h" #include "sl_spidrv_exp_config.h" #include "sl_wfx_host_api.h" +#include "spidrv.h" -#define LCD_BIT_RATE 1100000 -#define EXP_HDR_BIT_RATE 16000000 -#define SPI_FLASH_BIT_RATE 16000000 - -typedef enum PERIPHERAL_TYPE -{ - EXP_HDR = 0, - LCD, - EXT_SPIFLASH, -} peripheraltype_t; +#define SL_BIT_RATE_LCD 1100000 +#define SL_BIT_RATE_EXP_HDR 16000000 +#define SL_BIT_RATE_SPI_FLASH 16000000 +#define SL_BIT_RATE_UART_CONSOLE 16000000 extern SemaphoreHandle_t spi_sem_sync_hdl; -extern peripheraltype_t pr_type; + +#ifdef RS911X_WIFI +extern SPIDRV_Handle_t sl_spidrv_eusart_exp_handle; +#define SL_SPIDRV_HANDLE sl_spidrv_eusart_exp_handle +#endif + +#ifdef WF200_WIFI +extern SPIDRV_Handle_t sl_spidrv_exp_handle; +#define SL_SPIDRV_HANDLE sl_spidrv_exp_handle +#endif void spi_drv_reinit(uint32_t); -void set_spi_baudrate(peripheraltype_t); void spiflash_cs_assert(void); void spiflash_cs_deassert(void); diff --git a/examples/platform/silabs/efr32/wf200/efr_spi.c b/examples/platform/silabs/efr32/wf200/efr_spi.c index 7422ec686f0b9d..927b9a5fb892fa 100644 --- a/examples/platform/silabs/efr32/wf200/efr_spi.c +++ b/examples/platform/silabs/efr32/wf200/efr_spi.c @@ -49,13 +49,11 @@ #include "sl_power_manager.h" #endif -#if defined(EFR32MG24) +#if SL_WIFI #include "spi_multiplex.h" StaticSemaphore_t spi_sem_peripharal; SemaphoreHandle_t spi_sem_sync_hdl; -peripheraltype_t pr_type = EXP_HDR; #endif -extern SPIDRV_Handle_t sl_spidrv_exp_handle; #define USART SL_WFX_HOST_PINOUT_SPI_PERIPHERAL @@ -90,8 +88,8 @@ sl_status_t sl_wfx_host_init_bus(void) spi_enabled = true; /* Assign allocated DMA channel */ - tx_dma_channel = sl_spidrv_exp_handle->txDMACh; - rx_dma_channel = sl_spidrv_exp_handle->rxDMACh; + tx_dma_channel = SL_SPIDRV_HANDLE->txDMACh; + rx_dma_channel = SL_SPIDRV_HANDLE->rxDMACh; /* * Route EUSART1 MOSI, MISO, and SCLK to the specified pins. CS is @@ -116,7 +114,7 @@ sl_status_t sl_wfx_host_init_bus(void) #if defined(EFR32MG24) spi_sem_sync_hdl = xSemaphoreCreateBinaryStatic(&spi_sem_peripharal); xSemaphoreGive(spi_sem_sync_hdl); -#endif +#endif /* EFR32MG24 */ return SL_STATUS_OK; } @@ -130,6 +128,7 @@ sl_status_t sl_wfx_host_init_bus(void) sl_status_t sl_wfx_host_deinit_bus(void) { vSemaphoreDelete(spi_sem); + vSemaphoreDelete(spi_sem_sync_hdl); // Stop DMAs. DMADRV_StopTransfer(rx_dma_channel); DMADRV_StopTransfer(tx_dma_channel); @@ -149,6 +148,12 @@ sl_status_t sl_wfx_host_deinit_bus(void) *****************************************************************************/ sl_status_t sl_wfx_host_spi_cs_assert() { + configASSERT(spi_sem_sync_hdl); + if (xSemaphoreTake(spi_sem_sync_hdl, portMAX_DELAY) != pdTRUE) + { + return SL_STATUS_TIMEOUT; + } + spi_drv_reinit(SL_BIT_RATE_EXP_HDR); GPIO_PinOutClear(SL_SPIDRV_EXP_CS_PORT, SL_SPIDRV_EXP_CS_PIN); return SL_STATUS_OK; } @@ -163,6 +168,7 @@ sl_status_t sl_wfx_host_spi_cs_assert() sl_status_t sl_wfx_host_spi_cs_deassert() { GPIO_PinOutSet(SL_SPIDRV_EXP_CS_PORT, SL_SPIDRV_EXP_CS_PIN); + xSemaphoreGive(spi_sem_sync_hdl); return SL_STATUS_OK; } @@ -258,19 +264,6 @@ void transmitDMA(uint8_t * buffer, uint16_t buffer_length) sl_status_t sl_wfx_host_spi_transfer_no_cs_assert(sl_wfx_host_bus_transfer_type_t type, uint8_t * header, uint16_t header_length, uint8_t * buffer, uint16_t buffer_length) { - sl_status_t result = SL_STATUS_FAIL; -#if defined(EFR32MG24) - if (pr_type != EXP_HDR) - { - pr_type = EXP_HDR; - set_spi_baudrate(pr_type); - } - if (xSemaphoreTake(spi_sem_sync_hdl, portMAX_DELAY) != pdTRUE) - { - return SL_STATUS_TIMEOUT; - } - sl_wfx_host_spi_cs_assert(); -#endif const bool is_read = (type == SL_WFX_BUS_READ); while (!(MY_USART->STATUS & USART_STATUS_TXBL)) @@ -298,34 +291,29 @@ sl_status_t sl_wfx_host_spi_transfer_no_cs_assert(sl_wfx_host_bus_transfer_type_ if (buffer_length > 0) { MY_USART->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX; - if (xSemaphoreTake(spi_sem, portMAX_DELAY) == pdTRUE) + // Reset the semaphore + configASSERT(spi_sem); + if (xSemaphoreTake(spi_sem, portMAX_DELAY) != pdTRUE) { - if (is_read) - { - receiveDMA(buffer, buffer_length); - result = SL_STATUS_OK; - } - else - { - transmitDMA(buffer, buffer_length); - result = SL_STATUS_OK; - } + return SL_STATUS_TIMEOUT; + } - if (xSemaphoreTake(spi_sem, portMAX_DELAY) == pdTRUE) - { - xSemaphoreGive(spi_sem); - } + if (is_read) + { + receiveDMA(buffer, buffer_length); } else { - result = SL_STATUS_TIMEOUT; + transmitDMA(buffer, buffer_length); + } + // wait for dma_complete by using the same spi_semaphore + if (xSemaphoreTake(spi_sem, portMAX_DELAY) != pdTRUE) + { + return SL_STATUS_TIMEOUT; } + xSemaphoreGive(spi_sem); } -#if defined(EFR32MG24) - sl_wfx_host_spi_cs_deassert(); - xSemaphoreGive(spi_sem_sync_hdl); -#endif - return result; + return SL_STATUS_OK; } /**************************************************************************** From b42e176ad6770f4b8bb86cb8c8d5ece55e5a3bff Mon Sep 17 00:00:00 2001 From: srningap <107042150+srningap@users.noreply.github.com> Date: Fri, 14 Apr 2023 18:59:06 +0530 Subject: [PATCH 14/23] [Silabs] WiFi factory reset support for window-app 917SoC (#26066) * adds factory reset support for 917SoC window-app * applied restyle --- .../silabs/SiWx917/src/AppTask.cpp | 2 +- .../silabs/SiWx917/src/AppTask.cpp | 2 +- .../lock-app/silabs/SiWx917/src/AppTask.cpp | 2 +- .../SiWx917/SiWx917/hal/rsi_hal_mcu_m4.c | 3 ++- .../silabs/SiWx917/include/WindowAppImpl.h | 1 + .../silabs/SiWx917/src/WindowAppImpl.cpp | 26 ++++++++++++++++--- 6 files changed, 28 insertions(+), 8 deletions(-) diff --git a/examples/light-switch-app/silabs/SiWx917/src/AppTask.cpp b/examples/light-switch-app/silabs/SiWx917/src/AppTask.cpp index 3ea96abf726399..2fbad4ed4d3286 100644 --- a/examples/light-switch-app/silabs/SiWx917/src/AppTask.cpp +++ b/examples/light-switch-app/silabs/SiWx917/src/AppTask.cpp @@ -265,7 +265,7 @@ void AppTask::ButtonEventHandler(uint8_t button, uint8_t btnAction) button_event.Handler = SwitchActionEventHandler; sAppTask.PostEvent(&button_event); } - else if (button == SIWx917_BTN0) + else if (button == SIWx917_BTN0 && btnAction == SL_SIMPLE_BUTTON_PRESSED) { button_event.Handler = BaseApplication::ButtonHandler; sAppTask.PostEvent(&button_event); diff --git a/examples/lighting-app/silabs/SiWx917/src/AppTask.cpp b/examples/lighting-app/silabs/SiWx917/src/AppTask.cpp index 6133df35c33610..8da8003549c216 100644 --- a/examples/lighting-app/silabs/SiWx917/src/AppTask.cpp +++ b/examples/lighting-app/silabs/SiWx917/src/AppTask.cpp @@ -246,7 +246,7 @@ void AppTask::ButtonEventHandler(uint8_t button, uint8_t btnAction) button_event.Handler = LightActionEventHandler; sAppTask.PostEvent(&button_event); } - else if (button == SIWx917_BTN0) + else if (button == SIWx917_BTN0 && btnAction == SL_SIMPLE_BUTTON_PRESSED) { button_event.Handler = BaseApplication::ButtonHandler; sAppTask.PostEvent(&button_event); diff --git a/examples/lock-app/silabs/SiWx917/src/AppTask.cpp b/examples/lock-app/silabs/SiWx917/src/AppTask.cpp index bb9d15b6328039..abc276588bdab6 100644 --- a/examples/lock-app/silabs/SiWx917/src/AppTask.cpp +++ b/examples/lock-app/silabs/SiWx917/src/AppTask.cpp @@ -358,7 +358,7 @@ void AppTask::ButtonEventHandler(uint8_t button, uint8_t btnAction) button_event.Handler = LockActionEventHandler; sAppTask.PostEvent(&button_event); } - else if (button == SIWx917_BTN0) + else if (button == SIWx917_BTN0 && btnAction == SL_SIMPLE_BUTTON_PRESSED) { button_event.Handler = BaseApplication::ButtonHandler; sAppTask.PostEvent(&button_event); diff --git a/examples/platform/silabs/SiWx917/SiWx917/hal/rsi_hal_mcu_m4.c b/examples/platform/silabs/SiWx917/SiWx917/hal/rsi_hal_mcu_m4.c index 87d998e0e0ddbb..bcedf1c8a52c16 100644 --- a/examples/platform/silabs/SiWx917/SiWx917/hal/rsi_hal_mcu_m4.c +++ b/examples/platform/silabs/SiWx917/SiWx917/hal/rsi_hal_mcu_m4.c @@ -92,9 +92,10 @@ void IRQ021_Handler(void) btn1 = 0; sl_button_on_change(1, 1); } - if (RSI_NPSSGPIO_GetPin(NPSS_GPIO_0)) + if (RSI_NPSSGPIO_GetPin(NPSS_GPIO_0) && (!btn0)) { btn0 = 1; + sl_button_on_change(0, 0); } if (!RSI_NPSSGPIO_GetPin(NPSS_GPIO_0) && btn0) { diff --git a/examples/window-app/silabs/SiWx917/include/WindowAppImpl.h b/examples/window-app/silabs/SiWx917/include/WindowAppImpl.h index efaf194618b3a9..0acb38a4b1de22 100644 --- a/examples/window-app/silabs/SiWx917/include/WindowAppImpl.h +++ b/examples/window-app/silabs/SiWx917/include/WindowAppImpl.h @@ -44,6 +44,7 @@ class WindowAppImpl : public WindowApp { public: static WindowAppImpl sInstance; + bool mWindowAppInit = false; WindowAppImpl(); CHIP_ERROR Init() override; diff --git a/examples/window-app/silabs/SiWx917/src/WindowAppImpl.cpp b/examples/window-app/silabs/SiWx917/src/WindowAppImpl.cpp index 4cb033e349a366..694bc918f5bcd0 100644 --- a/examples/window-app/silabs/SiWx917/src/WindowAppImpl.cpp +++ b/examples/window-app/silabs/SiWx917/src/WindowAppImpl.cpp @@ -227,6 +227,8 @@ CHIP_ERROR WindowAppImpl::Init() } #endif // QR_CODE_ENABLED + mWindowAppInit = true; + return CHIP_NO_ERROR; } @@ -531,14 +533,30 @@ WindowAppImpl::Button::Button(WindowApp::Button::Id id, const char * name) : Win void WindowAppImpl::OnButtonChange(uint8_t Btn, uint8_t btnAction) { WindowApp::Button * btn = static_cast