From 4345e2d972c0eabc05a59f4310400e29dd2efdcb Mon Sep 17 00:00:00 2001 From: Lazar Kovacic Date: Tue, 25 Jun 2024 15:01:28 +0200 Subject: [PATCH 01/21] Update App Install Flow & Attribute Retrieval Status Errors (#33981) * Update App Install Flow Error & Attribute Retrieval Status * Update code break * Restyled by whitespace * Restyled by clang-format --------- Co-authored-by: Restyled.io --- .../matter/tv/server/model/ContentApp.java | 4 +- .../tv/server/service/AppPlatformService.java | 2 + .../tv-app/android/java/AppPlatform-JNI.cpp | 2 +- .../android/java/MyUserPrompter-JNI.cpp | 9 --- .../tv-app/android/java/MyUserPrompter-JNI.h | 1 - examples/tv-app/android/java/TVApp-JNI.cpp | 11 ++++ examples/tv-app/tv-common/include/AppTv.h | 4 ++ examples/tv-app/tv-common/src/AppTv.cpp | 64 +++++++++++++------ .../CommissionerDiscoveryController.cpp | 16 ----- .../CommissionerDiscoveryController.h | 17 ----- 10 files changed, 64 insertions(+), 66 deletions(-) diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/model/ContentApp.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/model/ContentApp.java index 6b5856870eba58..e30a75a00d98b2 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/model/ContentApp.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/model/ContentApp.java @@ -67,7 +67,9 @@ public void setEndpointId(int endpoint) { } public Set getSupportedClusters() { - return Collections.unmodifiableSet(supportedClusters); + return supportedClusters != null + ? Collections.unmodifiableSet(supportedClusters) + : Collections.EMPTY_SET; } public String getVersion() { diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java index 32a5a9c2e2d865..df360375068e70 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java @@ -34,6 +34,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; /** @@ -198,6 +199,7 @@ private Collection mapSupportedClusters( Collection supportedClusters) { return supportedClusters .stream() + .filter(Objects::nonNull) .map(AppPlatformService::mapSupportedCluster) .collect(Collectors.toList()); } diff --git a/examples/tv-app/android/java/AppPlatform-JNI.cpp b/examples/tv-app/android/java/AppPlatform-JNI.cpp index 2daebbdd890b6a..52905cf0ba130b 100644 --- a/examples/tv-app/android/java/AppPlatform-JNI.cpp +++ b/examples/tv-app/android/java/AppPlatform-JNI.cpp @@ -128,7 +128,7 @@ std::vector convert_to_cpp(JNIEnv * env, jobject s // Find Java classes. WARNING: Reflection jclass collectionClass = env->FindClass("java/util/Collection"); jclass iteratorClass = env->FindClass("java/util/Iterator"); - jclass clusterClass = env->FindClass("com/matter/tv/server/tvapp/SupportedCluster"); + jclass clusterClass = env->FindClass("com/matter/tv/server/tvapp/ContentAppSupportedCluster"); if (collectionClass == nullptr || iteratorClass == nullptr || clusterClass == nullptr) { return {}; diff --git a/examples/tv-app/android/java/MyUserPrompter-JNI.cpp b/examples/tv-app/android/java/MyUserPrompter-JNI.cpp index 4eb0abe25645da..6d586d99c1c67f 100644 --- a/examples/tv-app/android/java/MyUserPrompter-JNI.cpp +++ b/examples/tv-app/android/java/MyUserPrompter-JNI.cpp @@ -227,15 +227,6 @@ bool JNIMyUserPrompter::DisplaysPasscodeAndQRCode() return false; } -/** - * Called to prompt the user for consent to allow the app commissioneeName/vendorId/productId to be installed. - * For example "[commissioneeName] is requesting permission to install app to this TV, approve?" - */ -void JNIMyUserPrompter::PromptForAppInstallOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) -{ - ChipLogError(Zcl, "JNIMyUserPrompter::PromptForAppInstallOKPermission Needs Implementation"); -} - /** * Called to display the given setup passcode to the user, * for commissioning the given commissioneeName with the given vendorId and productId, diff --git a/examples/tv-app/android/java/MyUserPrompter-JNI.h b/examples/tv-app/android/java/MyUserPrompter-JNI.h index 3d2e7f14afb75e..408346326a6fd6 100644 --- a/examples/tv-app/android/java/MyUserPrompter-JNI.h +++ b/examples/tv-app/android/java/MyUserPrompter-JNI.h @@ -29,7 +29,6 @@ class JNIMyUserPrompter : public UserPrompter void PromptForCommissionOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) override; void PromptForCommissionPasscode(uint16_t vendorId, uint16_t productId, const char * commissioneeName, uint16_t pairingHint, const char * pairingInstruction) override; - void PromptForAppInstallOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) override; void HidePromptsOnCancel(uint16_t vendorId, uint16_t productId, const char * commissioneeName) override; bool DisplaysPasscodeAndQRCode() override; void PromptWithCommissionerPasscode(uint16_t vendorId, uint16_t productId, const char * commissioneeName, uint32_t passcode, diff --git a/examples/tv-app/android/java/TVApp-JNI.cpp b/examples/tv-app/android/java/TVApp-JNI.cpp index f154b0759c2b1a..04b5f4199edcaa 100644 --- a/examples/tv-app/android/java/TVApp-JNI.cpp +++ b/examples/tv-app/android/java/TVApp-JNI.cpp @@ -240,6 +240,16 @@ class MyPincodeService : public PasscodeService }; MyPincodeService gMyPincodeService; +class SampleTvAppInstallationService : public AppInstallationService +{ + bool LookupTargetContentApp(uint16_t vendorId, uint16_t productId) override + { + return ContentAppPlatform::GetInstance().LoadContentAppByClient(vendorId, productId) != nullptr; + } +}; + +SampleTvAppInstallationService gSampleTvAppInstallationService; + class MyPostCommissioningListener : public PostCommissioningListener { void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr, @@ -372,6 +382,7 @@ void TvAppJNI::InitializeCommissioner(JNIMyUserPrompter * userPrompter) if (cdc != nullptr && userPrompter != nullptr) { cdc->SetPasscodeService(&gMyPincodeService); + cdc->SetAppInstallationService(&gSampleTvAppInstallationService); cdc->SetUserPrompter(userPrompter); cdc->SetPostCommissioningListener(&gMyPostCommissioningListener); } diff --git a/examples/tv-app/tv-common/include/AppTv.h b/examples/tv-app/tv-common/include/AppTv.h index 8ddd793c611f70..026f125339aba6 100644 --- a/examples/tv-app/tv-common/include/AppTv.h +++ b/examples/tv-app/tv-common/include/AppTv.h @@ -149,6 +149,10 @@ class DLL_EXPORT ContentAppFactoryImpl : public ContentAppFactory void InstallContentApp(uint16_t vendorId, uint16_t productId); // Remove the app from the list of mContentApps bool UninstallContentApp(uint16_t vendorId, uint16_t productId); + // Print mContentApps and endpoints + void LogInstalledApps(); + // TODO: method to retrieve list of mContentApps + // https://github.com/project-chip/connectedhomeip/issues/34020 protected: std::vector> mContentApps; diff --git a/examples/tv-app/tv-common/src/AppTv.cpp b/examples/tv-app/tv-common/src/AppTv.cpp index bcdeac1a52b39f..03422c3fa462e7 100644 --- a/examples/tv-app/tv-common/src/AppTv.cpp +++ b/examples/tv-app/tv-common/src/AppTv.cpp @@ -98,12 +98,6 @@ class MyUserPrompter : public UserPrompter // tv should override this with a dialog prompt inline void PromptCommissioningFailed(const char * commissioneeName, CHIP_ERROR error) override { return; } - - // tv should override this with a dialog prompt - inline void PromptForAppInstallOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) override - { - return; - } }; MyUserPrompter gMyUserPrompter; @@ -583,28 +577,33 @@ void ContentAppFactoryImpl::InstallContentApp(uint16_t vendorId, uint16_t produc ChipLogProgress(DeviceLayer, "ContentAppFactoryImpl: InstallContentApp vendorId=%d productId=%d ", vendorId, productId); if (vendorId == 1 && productId == 11) { - mContentApps.emplace_back(std::make_unique("Vendor1", vendorId, "exampleid", productId, "Version1", - "34567890", make_default_supported_clusters())); + auto ptr = std::make_unique("Vendor1", vendorId, "exampleid", productId, "Version1", "34567890", + make_default_supported_clusters()); + mContentApps.emplace_back(std::move(ptr)); } - else if (vendorId == 65521 && productId == 32768) + else if (vendorId == 65521 && productId == 32769) { - mContentApps.emplace_back(std::make_unique("Vendor2", vendorId, "exampleString", productId, "Version2", - "20202021", make_default_supported_clusters())); + auto ptr = std::make_unique("Vendor2", vendorId, "exampleString", productId, "Version2", "20202021", + make_default_supported_clusters()); + mContentApps.emplace_back(std::move(ptr)); } else if (vendorId == 9050 && productId == 22) { - mContentApps.emplace_back(std::make_unique("Vendor3", vendorId, "App3", productId, "Version3", "20202021", - make_default_supported_clusters())); + auto ptr = std::make_unique("Vendor3", vendorId, "App3", productId, "Version3", "20202021", + make_default_supported_clusters()); + mContentApps.emplace_back(std::move(ptr)); } else if (vendorId == 1111 && productId == 22) { - mContentApps.emplace_back(std::make_unique("TestSuiteVendor", vendorId, "applicationId", productId, "v2", - "20202021", make_default_supported_clusters())); + auto ptr = std::make_unique("TestSuiteVendor", vendorId, "applicationId", productId, "v2", "20202021", + make_default_supported_clusters()); + mContentApps.emplace_back(std::move(ptr)); } else { - mContentApps.emplace_back(std::make_unique("NewAppVendor", vendorId, "newAppApplicationId", productId, "v2", - "20202021", make_default_supported_clusters())); + auto ptr = std::make_unique("NewAppVendor", vendorId, "newAppApplicationId", productId, "v2", "20202021", + make_default_supported_clusters()); + mContentApps.emplace_back(std::move(ptr)); } } @@ -627,6 +626,7 @@ bool ContentAppFactoryImpl::UninstallContentApp(uint16_t vendorId, uint16_t prod app->GetApplicationBasicDelegate()->HandleGetVendorId(), app->GetApplicationBasicDelegate()->HandleGetProductId()); mContentApps.erase(mContentApps.begin() + index); + // TODO: call ContentAppPlatform->RemoveContentApp(ids...) return true; } @@ -635,6 +635,18 @@ bool ContentAppFactoryImpl::UninstallContentApp(uint16_t vendorId, uint16_t prod return false; } +void ContentAppFactoryImpl::LogInstalledApps() +{ + for (auto & contentApp : mContentApps) + { + auto app = contentApp.get(); + + ChipLogProgress(DeviceLayer, "Content app vid=%d pid=%d is on ep=%d", + app->GetApplicationBasicDelegate()->HandleGetVendorId(), + app->GetApplicationBasicDelegate()->HandleGetProductId(), app->GetEndpointId()); + } +} + Access::Privilege ContentAppFactoryImpl::GetVendorPrivilege(uint16_t vendorId) { for (size_t i = 0; i < mAdminVendorIds.size(); ++i) @@ -689,12 +701,22 @@ std::list ContentAppFactoryImpl::GetAllowedClusterListForStaticEndpoi CHIP_ERROR AppTvInit() { #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + // test data for apps + constexpr uint16_t kApp1VendorId = 1; + constexpr uint16_t kApp1ProductId = 11; + constexpr uint16_t kApp2VendorId = 65521; + constexpr uint16_t kApp2ProductId = 32769; + constexpr uint16_t kApp3VendorId = 9050; + constexpr uint16_t kApp3ProductId = 22; + constexpr uint16_t kApp4VendorId = 1111; + constexpr uint16_t kApp4ProductId = 22; + ContentAppPlatform::GetInstance().SetupAppPlatform(); ContentAppPlatform::GetInstance().SetContentAppFactory(&gFactory); - gFactory.InstallContentApp((uint16_t) 1, (uint16_t) 11); - gFactory.InstallContentApp((uint16_t) 65521, (uint16_t) 32768); - gFactory.InstallContentApp((uint16_t) 9050, (uint16_t) 22); - gFactory.InstallContentApp((uint16_t) 1111, (uint16_t) 22); + gFactory.InstallContentApp(kApp1VendorId, kApp1ProductId); + gFactory.InstallContentApp(kApp2VendorId, kApp2ProductId); + gFactory.InstallContentApp(kApp3VendorId, kApp3ProductId); + gFactory.InstallContentApp(kApp4VendorId, kApp4ProductId); uint16_t value; if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(value) != CHIP_NO_ERROR) { diff --git a/src/controller/CommissionerDiscoveryController.cpp b/src/controller/CommissionerDiscoveryController.cpp index d1a5747491ad50..7f13a4323d2f5c 100644 --- a/src/controller/CommissionerDiscoveryController.cpp +++ b/src/controller/CommissionerDiscoveryController.cpp @@ -229,22 +229,6 @@ void CommissionerDiscoveryController::InternalOk() if (!mAppInstallationService->LookupTargetContentApp(client->GetVendorId(), client->GetProductId())) { ChipLogDetail(AppServer, "UX InternalOk: app not installed."); - - // notify client that app will be installed - CommissionerDeclaration cd; - cd.SetErrorCode(CommissionerDeclaration::CdError::kAppInstallConsentPending); - mUdcServer->SendCDCMessage(cd, Transport::PeerAddress::UDP(client->GetPeerAddress().GetIPAddress(), client->GetCdPort())); - - // dialog - ChipLogDetail(Controller, "------PROMPT USER: %s is requesting to install app on this TV. vendorId=%d, productId=%d", - client->GetDeviceName(), client->GetVendorId(), client->GetProductId()); - - if (mUserPrompter != nullptr) - { - mUserPrompter->PromptForAppInstallOKPermission(client->GetVendorId(), client->GetProductId(), client->GetDeviceName()); - } - ChipLogDetail(Controller, "------Via Shell Enter: app install "); - return; } if (client->GetUDCClientProcessingState() != UDCClientProcessingState::kPromptingUser) diff --git a/src/controller/CommissionerDiscoveryController.h b/src/controller/CommissionerDiscoveryController.h index b2211641fd0ede..5f7572b29def17 100644 --- a/src/controller/CommissionerDiscoveryController.h +++ b/src/controller/CommissionerDiscoveryController.h @@ -150,21 +150,6 @@ class DLL_EXPORT UserPrompter */ virtual void PromptCommissioningFailed(const char * commissioneeName, CHIP_ERROR error) = 0; - /** - * @brief - * Called to prompt the user for consent to allow the app commissioneeName/vendorId/productId to be installed. - * For example "[commissioneeName] is requesting permission to install app to this TV, approve?" - * - * If user responds with OK then implementor should call CommissionerRespondOk(); - * If user responds with Cancel then implementor should call CommissionerRespondCancel(); - * - * @param[in] vendorId The vendorId in the DNS-SD advertisement of the requesting commissionee. - * @param[in] productId The productId in the DNS-SD advertisement of the requesting commissionee. - * @param[in] commissioneeName The commissioneeName in the DNS-SD advertisement of the requesting commissionee. - * - */ - virtual void PromptForAppInstallOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) = 0; - virtual ~UserPrompter() = default; }; @@ -227,8 +212,6 @@ class DLL_EXPORT AppInstallationService * Called to check if the given target app is available to the commissione with th given * vendorId/productId * - * This will be called by the main chip thread so any blocking work should be moved to a separate thread. - * * @param[in] vendorId The vendorId in the DNS-SD advertisement of the requesting commissionee. * @param[in] productId The productId in the DNS-SD advertisement of the requesting commissionee. * From 1948efd5289c5fcb029c5e925fe9018c64bc46f6 Mon Sep 17 00:00:00 2001 From: Mahesh <92411857+pimpalemahesh@users.noreply.github.com> Date: Tue, 25 Jun 2024 21:43:45 +0530 Subject: [PATCH 02/21] [ESP32] Replaced FreeRTOS timer with CHIP timers in nimble BLEManagerImpl. (#34050) * Replace free RTOS timer with ChipTimer * Replaced FreeRTOS timer with CHIP timer --- src/platform/ESP32/BLEManagerImpl.h | 2 +- src/platform/ESP32/nimble/BLEManagerImpl.cpp | 39 ++++---------------- 2 files changed, 9 insertions(+), 32 deletions(-) diff --git a/src/platform/ESP32/BLEManagerImpl.h b/src/platform/ESP32/BLEManagerImpl.h index 1fe7ba77decce8..2bed34902002c1 100644 --- a/src/platform/ESP32/BLEManagerImpl.h +++ b/src/platform/ESP32/BLEManagerImpl.h @@ -296,7 +296,7 @@ class BLEManagerImpl final : public BLEManager, CHIP_ERROR StartAdvertising(void); void StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs); void CancelBleAdvTimeoutTimer(void); - static void BleAdvTimeoutHandler(TimerHandle_t xTimer); + static void BleAdvTimeoutHandler(System::Layer *, void *); #ifdef CONFIG_BT_BLUEDROID_ENABLED void HandleGATTControlEvent(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t * param); diff --git a/src/platform/ESP32/nimble/BLEManagerImpl.cpp b/src/platform/ESP32/nimble/BLEManagerImpl.cpp index c3953ec53c2bea..b43f866c0577f2 100644 --- a/src/platform/ESP32/nimble/BLEManagerImpl.cpp +++ b/src/platform/ESP32/nimble/BLEManagerImpl.cpp @@ -82,7 +82,6 @@ namespace Internal { namespace { -TimerHandle_t sbleAdvTimeoutTimer; // FreeRTOS sw timer. #ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER static constexpr uint16_t kNewConnectionScanTimeout = 60; static constexpr uint16_t kConnectTimeout = 20; @@ -209,16 +208,6 @@ CHIP_ERROR BLEManagerImpl::_Init() { CHIP_ERROR err; - // Create FreeRTOS sw timer for BLE timeouts and interval change. - sbleAdvTimeoutTimer = xTimerCreate("BleAdvTimer", // Just a text name, not used by the RTOS kernel - 1, // == default timer period - false, // no timer reload (==one-shot) - (void *) this, // init timer id = ble obj context - BleAdvTimeoutHandler // timer callback handler - ); - - VerifyOrReturnError(sbleAdvTimeoutTimer != nullptr, CHIP_ERROR_NO_MEMORY); - // Initialize the Chip BleLayer. #ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER err = BleLayer::Init(this, this, this, &DeviceLayer::SystemLayer()); @@ -253,9 +242,7 @@ CHIP_ERROR BLEManagerImpl::_Init() void BLEManagerImpl::_Shutdown() { - VerifyOrReturn(sbleAdvTimeoutTimer != nullptr); - xTimerDelete(sbleAdvTimeoutTimer, portMAX_DELAY); - sbleAdvTimeoutTimer = nullptr; + CancelBleAdvTimeoutTimer(); BleLayer::Shutdown(); @@ -286,7 +273,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) return err; } -void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer) +void BLEManagerImpl::BleAdvTimeoutHandler(System::Layer *, void *) { if (BLEMgrImpl().mFlags.Has(Flags::kFastAdvertisingEnabled)) { @@ -298,7 +285,6 @@ void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer) BLEMgrImpl().mFlags.Clear(Flags::kExtAdvertisingEnabled); BLEMgrImpl().StartBleAdvTimeoutTimer(CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_CHANGE_TIME_MS); #endif - PlatformMgr().ScheduleWork(DriveBLEState, 0); } #if CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING else @@ -308,9 +294,9 @@ void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer) BLEMgrImpl().mFlags.Set(Flags::kExtAdvertisingEnabled); BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising); BLEMgrImpl().mFlags.Set(Flags::kAdvertisingRefreshNeeded, 1); - PlatformMgr().ScheduleWork(DriveBLEState, 0); } #endif + PlatformMgr().ScheduleWork(DriveBLEState, 0); } CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) @@ -719,26 +705,17 @@ CHIP_ERROR BLEManagerImpl::MapBLEError(int bleErr) } void BLEManagerImpl::CancelBleAdvTimeoutTimer(void) { - VerifyOrReturn(sbleAdvTimeoutTimer != nullptr); - - if (xTimerStop(sbleAdvTimeoutTimer, pdMS_TO_TICKS(0)) == pdFAIL) + if (SystemLayer().IsTimerActive(BleAdvTimeoutHandler, nullptr)) { - ChipLogError(DeviceLayer, "Failed to stop BledAdv timeout timer"); + SystemLayer().CancelTimer(BleAdvTimeoutHandler, nullptr); } } void BLEManagerImpl::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs) { - VerifyOrReturn(sbleAdvTimeoutTimer != nullptr); - - if (xTimerIsTimerActive(sbleAdvTimeoutTimer)) - { - CancelBleAdvTimeoutTimer(); - } + CancelBleAdvTimeoutTimer(); - // timer is not active, change its period to required value (== restart). - // FreeRTOS- Block for a maximum of 100 ticks if the change period command - // cannot immediately be sent to the timer command queue. - if (xTimerChangePeriod(sbleAdvTimeoutTimer, pdMS_TO_TICKS(aTimeoutInMs), pdMS_TO_TICKS(100)) != pdPASS) + CHIP_ERROR err = SystemLayer().StartTimer(System::Clock::Milliseconds32(aTimeoutInMs), BleAdvTimeoutHandler, nullptr); + if ((err != CHIP_NO_ERROR)) { ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer"); } From 57fc697fe06e1921307fdef054785955ae130dea Mon Sep 17 00:00:00 2001 From: Shao Ling Tan <161761051+shaoltan-amazon@users.noreply.github.com> Date: Tue, 25 Jun 2024 12:43:10 -0700 Subject: [PATCH 03/21] Update Matter Casting automation test script to use the simplified Linux tv-casting-app build command in the workflow yaml file. (#34037) * Update Matter Casting automation test script to use the simplified Linux tv-casting-app build command in the workflow yaml file. * Fix Linux tv-casting-app build issue by adding to args.gni file. * Fix Linux tv-casting-app build issue by removing unneeded comparison condition that always return true in simple-app-helper.cpp:392. * Addressed PR comments from @andy31415. * Fix lint and unit tests issues. * Addressed PR comment from @andy31415. * Addressed PR comment from @andy31415. --- .../examples-linux-tv-casting-app.yaml | 2 +- examples/tv-casting-app/linux/args.gni | 2 + .../linux/simple-app-helper.cpp | 2 +- scripts/build/build/targets.py | 1 + scripts/build/builders/host.py | 6 ++- .../build/testdata/all_targets_linux_x64.txt | 2 +- .../tests/linux/tv_casting_test_sequences.py | 45 +++++++++---------- scripts/tests/run_tv_casting_test.py | 41 ++++++++++++----- 8 files changed, 60 insertions(+), 41 deletions(-) diff --git a/.github/workflows/examples-linux-tv-casting-app.yaml b/.github/workflows/examples-linux-tv-casting-app.yaml index d18de64382ee6a..ca6d1b6ea20e5c 100644 --- a/.github/workflows/examples-linux-tv-casting-app.yaml +++ b/.github/workflows/examples-linux-tv-casting-app.yaml @@ -61,7 +61,7 @@ jobs: - name: Build Linux tv-casting-app run: | ./scripts/run_in_build_env.sh \ - "scripts/examples/gn_build_example.sh examples/tv-casting-app/linux/ out/tv-casting-app" + "scripts/examples/gn_build_example.sh examples/tv-casting-app/linux/ out/tv-casting-app chip_casting_simplified=true" - name: Test casting from Linux tv-casting-app to Linux tv-app run: | diff --git a/examples/tv-casting-app/linux/args.gni b/examples/tv-casting-app/linux/args.gni index 03ba28645f8940..549819b797f6c7 100644 --- a/examples/tv-casting-app/linux/args.gni +++ b/examples/tv-casting-app/linux/args.gni @@ -32,4 +32,6 @@ chip_enable_rotating_device_id = true chip_max_discovered_ip_addresses = 20 +enable_rtti = true + matter_enable_tracing_support = true diff --git a/examples/tv-casting-app/linux/simple-app-helper.cpp b/examples/tv-casting-app/linux/simple-app-helper.cpp index c961bd5adaaacb..8fc0e7fafe0a07 100644 --- a/examples/tv-casting-app/linux/simple-app-helper.cpp +++ b/examples/tv-casting-app/linux/simple-app-helper.cpp @@ -389,7 +389,7 @@ CHIP_ERROR CommandHandler(int argc, char ** argv) unsigned long index = static_cast(strtol(argv[1], &eptr, 10)); std::vector> castingPlayers = matter::casting::core::CastingPlayerDiscovery::GetInstance()->GetCastingPlayers(); - VerifyOrReturnValue(0 <= index && index < castingPlayers.size(), CHIP_ERROR_INVALID_ARGUMENT, + VerifyOrReturnValue(index < castingPlayers.size(), CHIP_ERROR_INVALID_ARGUMENT, ChipLogError(AppServer, "Invalid casting player index provided: %lu", index)); targetCastingPlayer = castingPlayers.at(index); diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 0a91b3ea17bcd2..0a72b3733a96d1 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -189,6 +189,7 @@ def BuildHostTarget(): target.AppendModifier('evse-test-event', enable_test_event_triggers=['EVSE']).OnlyIfRe('-energy-management') target.AppendModifier('enable-dnssd-tests', enable_dnssd_tests=True).OnlyIfRe('-tests') target.AppendModifier('disable-dnssd-tests', enable_dnssd_tests=False).OnlyIfRe('-tests') + target.AppendModifier('chip-casting-simplified', chip_casting_simplified=True).OnlyIfRe('-tv-casting-app') return target diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index 258fb33c6a83fe..79d6b849a32aeb 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -313,7 +313,8 @@ def __init__(self, root, runner, app: HostApp, board=HostBoard.NATIVE, use_coverage=False, use_dmalloc=False, minmdns_address_policy=None, minmdns_high_verbosity=False, imgui_ui=False, crypto_library: HostCryptoLibrary = None, enable_test_event_triggers=None, - enable_dnssd_tests: Optional[bool] = None + enable_dnssd_tests: Optional[bool] = None, + chip_casting_simplified: Optional[bool] = None ): super(HostBuilder, self).__init__( root=os.path.join(root, 'examples', app.ExamplePath()), @@ -428,6 +429,9 @@ def __init__(self, root, runner, app: HostApp, board=HostBoard.NATIVE, else: self.extra_gn_options.append('chip_enable_dnssd_tests=false') + if chip_casting_simplified is not None: + self.extra_gn_options.append(f'chip_casting_simplified={str(chip_casting_simplified).lower()}') + if self.board == HostBoard.ARM64: if not use_clang: raise Exception("Cross compile only supported using clang") diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index f8880cc1e0cff5..7714bddaae42e3 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -9,7 +9,7 @@ efr32-{brd2704b,brd4316a,brd4317a,brd4318a,brd4319a,brd4186a,brd4187a,brd2601b,b esp32-{m5stack,c3devkit,devkitc,qemu}-{all-clusters,all-clusters-minimal,energy-management,ota-provider,ota-requestor,shell,light,lock,bridge,temperature-measurement,ota-requestor,tests}[-rpc][-ipv6only][-tracing] genio-lighting-app linux-fake-tests[-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-coverage][-dmalloc][-clang] -linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,thermostat,java-matter-controller,kotlin-matter-controller,minmdns,light,lock,shell,ota-provider,ota-requestor,simulated-app1,simulated-app2,python-bindings,tv-app,tv-casting-app,bridge,fabric-admin,fabric-bridge,tests,chip-cert,address-resolve-tool,contact-sensor,dishwasher,microwave-oven,refrigerator,rvc,air-purifier,lit-icd,air-quality-sensor,network-manager,energy-management}[-nodeps][-nlfaultinject][-platform-mdns][-minmdns-verbose][-libnl][-same-event-loop][-no-interactive][-ipv6only][-no-ble][-no-wifi][-no-thread][-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-coverage][-dmalloc][-clang][-test][-rpc][-with-ui][-evse-test-event][-enable-dnssd-tests][-disable-dnssd-tests] +linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,thermostat,java-matter-controller,kotlin-matter-controller,minmdns,light,lock,shell,ota-provider,ota-requestor,simulated-app1,simulated-app2,python-bindings,tv-app,tv-casting-app,bridge,fabric-admin,fabric-bridge,tests,chip-cert,address-resolve-tool,contact-sensor,dishwasher,microwave-oven,refrigerator,rvc,air-purifier,lit-icd,air-quality-sensor,network-manager,energy-management}[-nodeps][-nlfaultinject][-platform-mdns][-minmdns-verbose][-libnl][-same-event-loop][-no-interactive][-ipv6only][-no-ble][-no-wifi][-no-thread][-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-coverage][-dmalloc][-clang][-test][-rpc][-with-ui][-evse-test-event][-enable-dnssd-tests][-disable-dnssd-tests][-chip-casting-simplified] linux-x64-efr32-test-runner[-clang] imx-{chip-tool,lighting-app,thermostat,all-clusters-app,all-clusters-minimal-app,ota-provider-app}[-release] infineon-psoc6-{lock,light,all-clusters,all-clusters-minimal}[-ota][-updateimage][-trustm] diff --git a/scripts/tests/linux/tv_casting_test_sequences.py b/scripts/tests/linux/tv_casting_test_sequences.py index 9b65e64c9bb575..3ed249ae28532f 100644 --- a/scripts/tests/linux/tv_casting_test_sequences.py +++ b/scripts/tests/linux/tv_casting_test_sequences.py @@ -18,7 +18,7 @@ """ In this file, we define the test sequences with the relevant steps that will be used in the `scripts/tests/run_tv_casting_test.py` -for validating the casting experience between the Linux tv-casting-app and the Linux tv-app. +test script for validating the casting experience between the Linux tv-casting-app and the Linux tv-app. At the beginning of each test sequence we need to indicate the start up of the tv-app using the `START_APP` string as the `input_cmd` followed by the same for the tv-casting-app. On the other hand, at the end of each test sequence we need to ensure that each app will @@ -71,11 +71,8 @@ PRODUCT_ID = 0x8001 # Test product id DEVICE_TYPE_CASTING_VIDEO_PLAYER = 0x23 # Device type library 10.3: Casting Video Player -TEST_TV_CASTING_APP_DEVICE_NAME = 'Test TV casting app' # Test device name for identifying the tv-casting-app - -# Values to verify the subscription state against from the `ReportDataMessage` in the Linux tv-casting-app output. -CLUSTER_MEDIA_PLAYBACK = '0x506' # Application Cluster Spec 6.10.3 Cluster ID: Media Playback -ATTRIBUTE_CURRENT_PLAYBACK_STATE = '0x0000_0000' # Application Cluster Spec 6.10.6 Attribute ID: Current State of Playback +# Value to verify the subscription state against in the Linux tv-casting-app output. +ATTRIBUTE_CURRENT_PLAYBACK_STATE = 0x0000_0000 # Application Cluster Spec 6.10.6 Attribute ID: Current State of Playback test_sequences = [ Sequence( @@ -93,27 +90,24 @@ # Validate that the server is properly initialized in the tv-casting-app output. Step(app=App.TV_CASTING_APP, timeout_sec=APP_MAX_START_WAIT_SEC, output_msg=['Server initialization complete']), - # Validate that there is a valid discovered commissioner with {VENDOR_ID}, {PRODUCT_ID}, and {DEVICE_TYPE_CASTING_VIDEO_PLAYER} in the tv-casting-app output. - Step(app=App.TV_CASTING_APP, output_msg=['Discovered Commissioner #0', f'Vendor ID: {VENDOR_ID}', f'Product ID: {PRODUCT_ID}', + # Validate that there is a valid discovered casting player with {PRODUCT_ID}, {VENDOR_ID}, and {DEVICE_TYPE_CASTING_VIDEO_PLAYER} in the tv-casting-app output. + Step(app=App.TV_CASTING_APP, output_msg=['Discovered CastingPlayer #0', f'Product ID: {PRODUCT_ID}', f'Vendor ID: {VENDOR_ID}', f'Device Type: {DEVICE_TYPE_CASTING_VIDEO_PLAYER}', 'Supports Commissioner Generated Passcode: true']), - # Validate that we are ready to send `cast request` command to the tv-casting-app subprocess. - Step(app=App.TV_CASTING_APP, output_msg=['Example: cast request 0']), - # Send `cast request {valid_discovered_commissioner_number}\n` command to the tv-casting-app subprocess. Step(app=App.TV_CASTING_APP, input_cmd='cast request 0\n'), - # Validate that the `Identification Declaration` message block in the tv-casting-app output has the expected values for `device Name`, `vendor id`, and `product id`. - Step(app=App.TV_CASTING_APP, output_msg=['Identification Declaration Start', f'device Name: {TEST_TV_CASTING_APP_DEVICE_NAME}', - f'vendor id: {VENDOR_ID}', f'product id: {PRODUCT_ID}', 'Identification Declaration End']), + # Validate that the tv-casting-app begins the commissioning process. + Step(app=App.TV_CASTING_APP, output_msg=[ + 'CastingPlayer::VerifyOrEstablishConnection() calling OpenBasicCommissioningWindow()']), - # Validate that the `Identification Declaration` message block in the tv-app output has the expected values for `device Name`, `vendor id`, and `product id`. - Step(app=App.TV_APP, output_msg=['Identification Declaration Start', f'device Name: {TEST_TV_CASTING_APP_DEVICE_NAME}', - f'vendor id: {VENDOR_ID}', f'product id: {PRODUCT_ID}', 'Identification Declaration End']), + # Validate that the `IdentificationDeclaration` message sent from the tv-casting-app to the tv-app will contain the {VENDOR_ID} of the target content app. + Step(app=App.TV_CASTING_APP, output_msg=['IdentificationDeclarationOptions::TargetAppInfos list:']), + Step(app=App.TV_CASTING_APP, output_msg=[f'TargetAppInfo 1, Vendor ID: {VENDOR_ID}']), # Validate that we received the cast request from the tv-casting-app on the tv-app output. Step(app=App.TV_APP, - output_msg=['PROMPT USER: Test TV casting app is requesting permission to cast to this TV, approve?']), + output_msg=['------PROMPT USER: Test TV casting app is requesting permission to cast to this TV, approve?']), # Validate that we received the instructions on the tv-app output for sending the `controller ux ok` command. Step(app=App.TV_APP, output_msg=['Via Shell Enter: controller ux ok|cancel']), @@ -124,23 +118,24 @@ # Validate that pairing succeeded between the tv-casting-app and the tv-app. Step(app=App.TV_APP, output_msg=['Secure Pairing Success']), - # Validate that commissioning succeeded in the tv-casting-app output. - Step(app=App.TV_CASTING_APP, output_msg=['Commissioning completed successfully']), + # Validate that the connection succeeded in the tv-casting-app output. + Step(app=App.TV_CASTING_APP, output_msg=['Successfully connected to CastingPlayer']), # Validate that commissioning succeeded in the tv-app output. Step(app=App.TV_APP, output_msg=['------PROMPT USER: commissioning success']), - # Validate the subscription state by looking at the `Cluster` and `Attribute` values in the `ReportDataMessage` block in the tv-casting-app output. - Step(app=App.TV_CASTING_APP, output_msg=[ - 'ReportDataMessage =', f'Cluster = {CLUSTER_MEDIA_PLAYBACK}', f'Attribute = {ATTRIBUTE_CURRENT_PLAYBACK_STATE}', 'InteractionModelRevision =', '}']), + # Validate that we are able to read the application VendorID value and that it matches {VENDOR_ID}. + Step(app=App.TV_CASTING_APP, output_msg=[f'Read VendorID value: {VENDOR_ID}']), + + # Validate that we are able to subscribe to the media playback cluster by reading the CurrentState value and that it matches {ATTRIBUTE_CURRENT_PLAYBACK_STATE}. + Step(app=App.TV_CASTING_APP, output_msg=[f'Read CurrentState value: {ATTRIBUTE_CURRENT_PLAYBACK_STATE}']), # Validate the LaunchURL in the tv-app output. Step(app=App.TV_APP, output_msg=['ContentLauncherManager::HandleLaunchUrl TEST CASE ContentURL=https://www.test.com/videoid DisplayString=Test video']), # Validate the LaunchURL in the tv-casting-app output. - Step(app=App.TV_CASTING_APP, output_msg=['InvokeResponseMessage =', - 'exampleData', 'InteractionModelRevision =', '},']), + Step(app=App.TV_CASTING_APP, output_msg=['LaunchURL Success with response.data: exampleData']), # Signal to stop the tv-casting-app as we finished validation. Step(app=App.TV_CASTING_APP, input_cmd=STOP_APP), diff --git a/scripts/tests/run_tv_casting_test.py b/scripts/tests/run_tv_casting_test.py index 45cc6171bc3dca..13b003eed67e66 100644 --- a/scripts/tests/run_tv_casting_test.py +++ b/scripts/tests/run_tv_casting_test.py @@ -14,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import glob import logging import os import signal @@ -63,6 +64,19 @@ def __exit__(self, exception_type, exception_value, traceback): self.process.wait() +def remove_cached_files(cached_file_pattern: str): + """Remove any cached files that match the provided pattern.""" + + cached_files = glob.glob(cached_file_pattern) # Returns a list of paths that match the pattern. + + for cached_file in cached_files: + try: + os.remove(cached_file) + except OSError as e: + logging.error(f'Failed to remove cached file `{cached_file}` with error: `{e.strerror}`') + raise # Re-raise the OSError to propagate it up. + + def dump_temporary_logs_to_console(log_file_path: str): """Dump log file to the console; log file will be removed once the function exits.""" """Write the entire content of `log_file_path` to the console.""" @@ -86,7 +100,7 @@ def handle_casting_failure(test_sequence_name: str, log_file_paths: List[str]): sys.exit(1) -def stop_app(test_sequence_name: str, app_name: str, app: subprocess.Popen): +def stop_app(test_sequence_name: str, app_name: str, app: subprocess.Popen) -> bool: """Stop the given `app` subprocess.""" app.terminate() @@ -115,7 +129,7 @@ def parse_output_msg_in_subprocess( log_paths: List[str], test_sequence_name: str, test_sequence_step: Step -): +) -> bool: """Parse the output of a given `app` subprocess and validate its output against the expected `output_msg` in the given `Step`.""" if not test_sequence_step.output_msg: @@ -168,7 +182,7 @@ def send_input_cmd_to_subprocess( tv_app_info: Tuple[subprocess.Popen, TextIO], test_sequence_name: str, test_sequence_step: Step -): +) -> bool: """Send a given input command (`input_cmd`) from the `Step` to its given `app` subprocess.""" if not test_sequence_step.input_cmd: @@ -176,17 +190,14 @@ def send_input_cmd_to_subprocess( return False app_subprocess, app_log_file = (tv_casting_app_info if test_sequence_step.app == App.TV_CASTING_APP else tv_app_info) + app_name = test_sequence_step.app.value - app_subprocess.stdin.write(test_sequence_step.input_cmd) + input_cmd = test_sequence_step.input_cmd + app_subprocess.stdin.write(input_cmd) app_subprocess.stdin.flush() - # Read in the next line which should be the `input_cmd` that was issued. - next_line = app_subprocess.stdout.readline() - app_log_file.write(next_line) - app_log_file.flush() - next_line = next_line.rstrip('\n') - - logging.info(f'{test_sequence_name} - Sent `{next_line}` to the {test_sequence_step.app.value} subprocess.') + input_cmd = input_cmd.rstrip('\n') + logging.info(f'{test_sequence_name} - Sent `{input_cmd}` to the {app_name} subprocess.') return True @@ -338,7 +349,13 @@ def test_casting_fn(tv_app_rel_path, tv_casting_app_rel_path): if __name__ == '__main__': # Start with a clean slate by removing any previously cached entries. - os.system('rm -f /tmp/chip_*') + try: + cached_file_pattern = '/tmp/chip_*' + remove_cached_files(cached_file_pattern) + except OSError: + logging.error( + f'Error while removing cached files with file pattern: {cached_file_pattern}') + sys.exit(1) # Test casting (discovery and commissioning) between the Linux tv-casting-app and the tv-app. test_casting_fn() From 857accf9e947bdeb7d74d5bcf7c8605e0a0b70ba Mon Sep 17 00:00:00 2001 From: austina-csa <168131796+austina-csa@users.noreply.github.com> Date: Tue, 25 Jun 2024 12:59:56 -0700 Subject: [PATCH 04/21] Worked on issue 243; replaced input with self.wait_for_user_input; other changes (#33672) * Worked on issue 243; replaced input with self.wait_for_user_input; removed input_msg message argument and made several adjustments accordingly * Restyled by autopep8 * Clarified text for user input by adding test step. --------- Co-authored-by: Restyled.io Co-authored-by: C Freeman --- src/python_testing/TC_OpstateCommon.py | 4 +- src/python_testing/TC_RVCCLEANM_2_1.py | 6 +- src/python_testing/TC_RVCCLEANM_2_2.py | 5 +- src/python_testing/TC_RVCOPSTATE_2_1.py | 95 ++++++++++++-------- src/python_testing/TC_RVCOPSTATE_2_3.py | 45 +++++----- src/python_testing/TC_RVCOPSTATE_2_4.py | 8 +- src/python_testing/TC_RVCRUNM_2_1.py | 6 +- src/python_testing/TC_RVCRUNM_2_2.py | 14 +-- src/python_testing/matter_testing_support.py | 8 +- 9 files changed, 109 insertions(+), 82 deletions(-) diff --git a/src/python_testing/TC_OpstateCommon.py b/src/python_testing/TC_OpstateCommon.py index 9e32aac00ec846..648eea59f2bb3c 100644 --- a/src/python_testing/TC_OpstateCommon.py +++ b/src/python_testing/TC_OpstateCommon.py @@ -122,7 +122,7 @@ def send_raw_manual_or_pipe_command(self, command): self.write_to_app_pipe(command) time.sleep(0.1) else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg="Press Enter when ready.\n") def send_manual_or_pipe_command(self, device: str, name: str, operation: str, param: Any = None): command = { @@ -1113,7 +1113,7 @@ async def TEST_TC_OPSTATE_BASE_2_5(self, endpoint=1): # In CI environment, the STOP coommand (step 8) already resets the variables. Only ask for # reboot outside CI environment. if not self.is_ci: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg="Restart DUT. Press Enter when ready.\n") # STEP 12: TH waits for {PIXIT.WAITTIME.REBOOT} self.step(12) diff --git a/src/python_testing/TC_RVCCLEANM_2_1.py b/src/python_testing/TC_RVCCLEANM_2_1.py index 6ef91d89a06729..8613c123b5950c 100644 --- a/src/python_testing/TC_RVCCLEANM_2_1.py +++ b/src/python_testing/TC_RVCCLEANM_2_1.py @@ -138,7 +138,8 @@ class CommonCodes(Enum): print("Changing mode to Cleaning") await self.send_run_change_to_mode_cmd(1) else: - input("Press Enter when done.\n") + self.wait_for_user_input( + prompt_msg="Manually put the device in a state from which it will FAIL to transition to mode %d, and press Enter when done" % (self.mode_fail)) self.print_step(6, "Read CurrentMode attribute") old_current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) @@ -169,7 +170,8 @@ class CommonCodes(Enum): print("Changing mode to Idle") await self.send_run_change_to_mode_cmd(0) else: - input("Press Enter when done.\n") + self.wait_for_user_input( + prompt_msg="Manually put the device in a state from which it will SUCCESSFULLY transition to mode %d, and press Enter when done" % (self.mode_ok)) self.print_step(10, "Read CurrentMode attribute") old_current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) diff --git a/src/python_testing/TC_RVCCLEANM_2_2.py b/src/python_testing/TC_RVCCLEANM_2_2.py index 7e1fa6aaf2667e..157d31924afd4a 100644 --- a/src/python_testing/TC_RVCCLEANM_2_2.py +++ b/src/python_testing/TC_RVCCLEANM_2_2.py @@ -63,7 +63,7 @@ async def send_run_change_to_mode_cmd(self, newMode) -> Clusters.Objects.RvcRunM # Prints the instruction and waits for a user input to continue def print_instruction(self, step_number, instruction): self.print_step(step_number, instruction) - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{instruction}, and press Enter when ready.") def pics_TC_RVCCLEANM_2_2(self) -> list[str]: return ["RVCCLEANM.S"] @@ -101,7 +101,8 @@ async def test_TC_RVCCLEANM_2_2(self): if self.is_ci: await self.send_run_change_to_mode_cmd(1) else: - input("Press Enter when done.\n") + self.wait_for_user_input( + prompt_msg="Manually put the device in a state in which the RVC Run Mode cluster’s CurrentMode attribute is set to a mode without the Idle mode tag, and press Enter when done.") self.print_step(3, "Read the RvcRunMode SupportedModes attribute") supported_run_modes = await self.read_run_supported_modes() diff --git a/src/python_testing/TC_RVCOPSTATE_2_1.py b/src/python_testing/TC_RVCOPSTATE_2_1.py index e9dd4659059fa0..922ae1c9348592 100644 --- a/src/python_testing/TC_RVCOPSTATE_2_1.py +++ b/src/python_testing/TC_RVCOPSTATE_2_1.py @@ -158,53 +158,60 @@ async def test_TC_RVCOPSTATE_2_1(self): asserts.assert_true(operational_state in defined_states or in_range, "OperationalState has an invalid ID value!") if self.check_pics("RVCOPSTATE.S.M.ST_STOPPED"): - self.print_step("6a", "Manually put the device in the stopped state") + test_step = "Manually put the device in the stopped state" + self.print_step("6a", test_step) if not self.is_ci: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_opstate(step="6b", expected_state=Clusters.OperationalState.Enums.OperationalStateEnum.kStopped) if self.check_pics("RVCOPSTATE.S.M.ST_RUNNING"): - self.print_step("6c", "Manually put the device in the running state") + test_step = "Manually put the device in the running state" + self.print_step("6c", test_step) if self.is_ci: await self.send_run_change_to_mode_cmd(1) else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_opstate(step="6d", expected_state=Clusters.OperationalState.Enums.OperationalStateEnum.kRunning) if self.check_pics("RVCOPSTATE.S.M.ST_PAUSED"): - self.print_step("6e", "Manually put the device in the paused state") + test_step = "Manually put the device in the paused state" + self.print_step("6e", test_step) if self.is_ci: await self.send_pause_cmd() else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_opstate(step="6f", expected_state=Clusters.OperationalState.Enums.OperationalStateEnum.kPaused) if self.check_pics("RVCOPSTATE.S.M.ST_ERROR"): - self.print_step("6g", "Manually put the device in the error state") + test_step = "Manually put the device in the error state" + self.print_step("6g", test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "ErrorEvent", "Error": "UnableToStartOrResume"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_opstate(step="6h", expected_state=Clusters.OperationalState.Enums.OperationalStateEnum.kError) if self.check_pics("RVCOPSTATE.S.M.ST_SEEKING_CHARGER"): - self.print_step("6i", "Manually put the device in the seeking charger state") + test_step = "Manually put the device in the seeking charger state" + self.print_step("6i", test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "Reset"}') await self.send_run_change_to_mode_cmd(1) await self.send_run_change_to_mode_cmd(0) else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_opstate(step="6j", expected_state=Clusters.RvcOperationalState.Enums.OperationalStateEnum.kSeekingCharger) if self.check_pics("RVCOPSTATE.S.M.ST_CHARGING"): - self.print_step("6k", "Manually put the device in the charging state") + test_step = "Manually put the device in the charging state" + self.print_step("6k", test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "ChargerFound"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_opstate(step="6l", expected_state=Clusters.RvcOperationalState.Enums.OperationalStateEnum.kCharging) if self.check_pics("RVCOPSTATE.S.M.ST_DOCKED"): - self.print_step("6m", "Manually put the device in the docked state") + test_step = "Manually put the device in the docked state" + self.print_step("6m", test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "Charged"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_opstate(step="6n", expected_state=Clusters.RvcOperationalState.Enums.OperationalStateEnum.kDocked) if self.check_pics("RVCOPSTATE.S.A0005"): @@ -226,86 +233,98 @@ async def test_TC_RVCOPSTATE_2_1(self): asserts.assert_true(operational_error.errorStateLabel is not None, "ErrorStateLabel should be populated") if self.check_pics("RVCOPSTATE.S.M.ERR_NO_ERROR"): - self.print_step("7a", "Manually put the device in the no error state") + test_step = "Manually put the device in the no error state" + self.print_step("7a", test_step) if not self.is_ci: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_operror(step="7b", expected_error=Clusters.OperationalState.Enums.ErrorStateEnum.kNoError) if self.check_pics("RVCOPSTATE.S.M.ERR_UNABLE_TO_START_OR_RESUME"): - self.print_step("7c", "Manually put the device in the unable to start or resume error state") + test_step = "Manually put the device in the unable to start or resume error state" + self.print_step("7c", test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "ErrorEvent", "Error": "UnableToStartOrResume"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_operror(step="7d", expected_error=Clusters.OperationalState.Enums.ErrorStateEnum.kUnableToStartOrResume) if self.check_pics("RVCOPSTATE.S.M.ERR_UNABLE_TO_COMPLETE_OPERATION"): - self.print_step("7e", "Manually put the device in the unable to complete operation error state") + test_step = "Manually put the device in the unable to complete operation error state" + self.print_step("7e", test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "ErrorEvent", "Error": "UnableToCompleteOperation"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_operror(step="7f", expected_error=Clusters.OperationalState.Enums.ErrorStateEnum.kUnableToCompleteOperation) if self.check_pics("RVCOPSTATE.S.M.ERR_COMMAND_INVALID_IN_STATE"): - self.print_step("7g", "Manually put the device in the command invalid error state") + test_step = "Manually put the device in the command invalid error state" + self.print_step("7g", test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "ErrorEvent", "Error": "CommandInvalidInState"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_operror(step="7h", expected_error=Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState) if self.check_pics("RVCOPSTATE.S.M.ERR_FAILED_TO_FIND_CHARGING_DOCK"): - self.print_step("7i", "Manually put the device in the failed to find dock error state") + test_step = "Manually put the device in the failed to find dock error state" + self.print_step("7i", test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "ErrorEvent", "Error": "FailedToFindChargingDock"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_operror(step="7j", expected_error=Clusters.RvcOperationalState.Enums.ErrorStateEnum.kFailedToFindChargingDock) if self.check_pics("RVCOPSTATE.S.M.ERR_STUCK"): - self.print_step("7k", "Manually put the device in the stuck error state") + test_step = "Manually put the device in the stuck error state" + self.print_step("7k", test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "ErrorEvent", "Error": "Stuck"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_operror(step="7l", expected_error=Clusters.RvcOperationalState.Enums.ErrorStateEnum.kStuck) if self.check_pics("RVCOPSTATE.S.M.ERR_DUST_BIN_MISSING"): - self.print_step("7m", "Manually put the device in the dust bin missing error state") + test_step = "Manually put the device in the dust bin missing error state" + self.print_step("7m", test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "ErrorEvent", "Error": "DustBinMissing"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_operror(step="7n", expected_error=Clusters.RvcOperationalState.Enums.ErrorStateEnum.kDustBinMissing) if self.check_pics("RVCOPSTATE.S.M.ERR_DUST_BIN_FULL"): - self.print_step("7o", "Manually put the device in the dust bin full error state") + test_step = "Manually put the device in the dust bin full error state" + self.print_step("7o", test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "ErrorEvent", "Error": "DustBinFull"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_operror(step="7p", expected_error=Clusters.RvcOperationalState.Enums.ErrorStateEnum.kDustBinFull) if self.check_pics("RVCOPSTATE.S.M.ERR_WATER_TANK_EMPTY"): - self.print_step("7q", "Manually put the device in the water tank empty error state") + test_step = "Manually put the device in the water tank empty error state" + self.print_step("7q", test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "ErrorEvent", "Error": "WaterTankEmpty"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_operror(step="7r", expected_error=Clusters.RvcOperationalState.Enums.ErrorStateEnum.kWaterTankEmpty) if self.check_pics("RVCOPSTATE.S.M.ERR_WATER_TANK_MISSING"): - self.print_step("7s", "Manually put the device in the water tank missing error state") + test_step = "Manually put the device in the water tank missing error state" + self.print_step("7s", test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "ErrorEvent", "Error": "WaterTankMissing"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_operror(step="7t", expected_error=Clusters.RvcOperationalState.Enums.ErrorStateEnum.kWaterTankMissing) if self.check_pics("RVCOPSTATE.S.M.ERR_WATER_TANK_LID_OPEN"): - self.print_step("7u", "Manually put the device in the water tank lid open error state") + test_step = "Manually put the device in the water tank lid open error state" + self.print_step("7u", test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "ErrorEvent", "Error": "WaterTankLidOpen"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_operror(step="7v", expected_error=Clusters.RvcOperationalState.Enums.ErrorStateEnum.kWaterTankLidOpen) if self.check_pics("RVCOPSTATE.S.M.ERR_MOP_CLEANING_PAD_MISSING"): - self.print_step("7w", "Manually put the device in the mop cleaning pad missing error state") + test_step = "Manually put the device in the mop cleaning pad missing error state" + self.print_step("7w", test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "ErrorEvent", "Error": "MopCleaningPadMissing"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_and_validate_operror(step="7x", expected_error=Clusters.RvcOperationalState.Enums.ErrorStateEnum.kMopCleaningPadMissing) diff --git a/src/python_testing/TC_RVCOPSTATE_2_3.py b/src/python_testing/TC_RVCOPSTATE_2_3.py index f41e6bcb0de8b1..ea576bbf036263 100644 --- a/src/python_testing/TC_RVCOPSTATE_2_3.py +++ b/src/python_testing/TC_RVCOPSTATE_2_3.py @@ -137,7 +137,7 @@ def write_to_app_pipe(self, command): # Prints the instruction and waits for a user input to continue def print_instruction(self, step_number, instruction): self.print_step(step_number, instruction) - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{instruction}, and press Enter when done.") def pics_TC_RVCOPSTATE_2_3(self) -> list[str]: return ["RVCOPSTATE.S"] @@ -172,11 +172,12 @@ async def test_TC_RVCOPSTATE_2_3(self): if self.is_ci: self.write_to_app_pipe('{"Name": "Reset"}') - self.print_step(2, "Manually put the device in a state where it can receive a Pause command") + test_step = "Manually put the device in a state where it can receive a Pause command" + self.print_step(2, test_step) if self.is_ci: await self.send_run_change_to_mode_cmd(1) else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") self.print_step(3, "Read OperationalStateList attribute") op_state_list = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, @@ -253,11 +254,12 @@ async def test_TC_RVCOPSTATE_2_3(self): await self.read_operational_state_with_check(23, op_states.kRunning) if self.check_pics("RVCOPSTATE.S.M.ST_STOPPED"): - self.print_step(24, "Manually put the device in the Stopped(0x00) operational state") + test_step = "Manually put the device in the Stopped(0x00) operational state" + self.print_step(24, test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "Reset"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_operational_state_with_check(25, op_states.kStopped) @@ -266,11 +268,12 @@ async def test_TC_RVCOPSTATE_2_3(self): await self.send_resume_cmd_with_check(27, op_errors.kCommandInvalidInState) if self.check_pics("RVCOPSTATE.S.M.ST_ERROR"): - self.print_step(28, "Manually put the device in the Error(0x03) operational state") + test_step = "Manually put the device in the Error(0x03) operational state" + self.print_step(28, test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "ErrorEvent", "Error": "Stuck"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_operational_state_with_check(29, op_states.kError) @@ -279,53 +282,55 @@ async def test_TC_RVCOPSTATE_2_3(self): await self.send_resume_cmd_with_check(31, op_errors.kCommandInvalidInState) if self.check_pics("RVCOPSTATE.S.M.ST_CHARGING"): - self.print_step(32, "Manually put the device in the Charging(0x41) operational state") + test_step = "Manually put the device in the Charging(0x41) operational state" + self.print_step(32, test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "Reset"}') await self.send_run_change_to_mode_cmd(1) await self.send_run_change_to_mode_cmd(0) self.write_to_app_pipe('{"Name": "ChargerFound"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_operational_state_with_check(33, rvc_op_states.kCharging) await self.send_pause_cmd_with_check(34, op_errors.kCommandInvalidInState) - - self.print_step( - 35, "Manually put the device in the Charging(0x41) operational state and RVC Run Mode cluster's CurrentMode attribute set to a mode with the Idle mode tag") + test_step = "Manually put the device in the Charging(0x41) operational state and RVC Run Mode cluster's CurrentMode attribute set to a mode with the Idle mode tag" + self.print_step(35, test_step) if not self.is_ci: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_operational_state_with_check(36, rvc_op_states.kCharging) await self.send_resume_cmd_with_check(37, op_errors.kCommandInvalidInState) if self.check_pics("RVCOPSTATE.S.M.ST_DOCKED"): - self.print_step(38, "Manually put the device in the Docked(0x42) operational state") + test_step = "Manually put the device in the Docked(0x42) operational state" + self.print_step(38, test_step) if self.is_ci: self.write_to_app_pipe('{"Name": "Charged"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_operational_state_with_check(39, rvc_op_states.kDocked) await self.send_pause_cmd_with_check(40, op_errors.kCommandInvalidInState) - self.print_step( - 41, "Manually put the device in the Docked(0x42) operational state and RVC Run Mode cluster's CurrentMode attribute set to a mode with the Idle mode tag") + test_step = "Manually put the device in the Docked(0x42) operational state and RVC Run Mode cluster's CurrentMode attribute set to a mode with the Idle mode tag" + self.print_step(41, test_step) if not self.is_ci: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.send_resume_cmd_with_check(42, op_errors.kCommandInvalidInState) if self.check_pics("RVCOPSTATE.S.M.ST_SEEKING_CHARGER"): - self.print_step(43, "Manually put the device in the SeekingCharger(0x40) operational state") + test_step = "Manually put the device in the SeekingCharger(0x40) operational state" + self.print_step(43, test_step) if self.is_ci: await self.send_run_change_to_mode_cmd(1) await self.send_run_change_to_mode_cmd(0) else: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") await self.read_operational_state_with_check(44, rvc_op_states.kSeekingCharger) diff --git a/src/python_testing/TC_RVCOPSTATE_2_4.py b/src/python_testing/TC_RVCOPSTATE_2_4.py index 9c07fd15de042f..afddeb65ea6b0c 100644 --- a/src/python_testing/TC_RVCOPSTATE_2_4.py +++ b/src/python_testing/TC_RVCOPSTATE_2_4.py @@ -124,7 +124,7 @@ async def test_TC_RVCOPSTATE_2_4(self): if self.is_ci: self.write_to_app_pipe('{"Name": "ErrorEvent", "Error": "UnableToStartOrResume"}') else: - self.wait_for_user_input(step_name) + self.wait_for_user_input(prompt_msg=f"{step_name}, and press Enter when ready.") await self.read_operational_state_with_check(3, op_states.kError) @@ -138,7 +138,7 @@ async def test_TC_RVCOPSTATE_2_4(self): self.write_to_app_pipe('{"Name": "Docked"}') self.write_to_app_pipe('{"Name": "Charging"}') else: - self.wait_for_user_input(step_name) + self.wait_for_user_input(prompt_msg=f"{step_name}, and press Enter when ready.") await self.read_operational_state_with_check(6, rvc_op_states.kCharging) @@ -150,7 +150,7 @@ async def test_TC_RVCOPSTATE_2_4(self): if self.is_ci: self.write_to_app_pipe('{"Name": "Charged"}') else: - self.wait_for_user_input(step_name) + self.wait_for_user_input(prompt_msg=f"{step_name}, and press Enter when ready.") await self.read_operational_state_with_check(9, rvc_op_states.kDocked) @@ -163,7 +163,7 @@ async def test_TC_RVCOPSTATE_2_4(self): await self.send_run_change_to_mode_cmd(rvc_app_run_mode_cleaning) await self.send_run_change_to_mode_cmd(rvc_app_run_mode_idle) else: - self.wait_for_user_input(step_name) + self.wait_for_user_input(prompt_msg=f"{step_name}, and press Enter when ready.") await self.read_operational_state_with_check(9, rvc_op_states.kSeekingCharger) diff --git a/src/python_testing/TC_RVCRUNM_2_1.py b/src/python_testing/TC_RVCRUNM_2_1.py index 1f3bccb528f137..ce9e5bf6830625 100644 --- a/src/python_testing/TC_RVCRUNM_2_1.py +++ b/src/python_testing/TC_RVCRUNM_2_1.py @@ -133,7 +133,8 @@ class CommonCodes(Enum): print("Change to RVC Run mode Cleaning") await self.send_change_to_mode_cmd(newMode=1) else: - input("Press Enter when done.\n") + self.wait_for_user_input( + prompt_msg="Manually put the device in a state from which it will FAIL to transition to mode %d, and press Enter when ready." % (self.mode_fail)) self.print_step(6, "Read CurrentMode attribute") old_current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) @@ -163,7 +164,8 @@ class CommonCodes(Enum): if self.is_ci: print("Continuing...") else: - input("Press Enter when done.\n") + self.wait_for_user_input( + prompt_msg="Manually put the device in a state from which it will SUCCESSFULLY transition to mode %d, and press Enter when ready." % (self.mode_ok)) self.print_step(10, "Read CurrentMode attribute") old_current_mode = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) diff --git a/src/python_testing/TC_RVCRUNM_2_2.py b/src/python_testing/TC_RVCRUNM_2_2.py index 6680ada707a85e..f4d7bc9f0eb042 100644 --- a/src/python_testing/TC_RVCRUNM_2_2.py +++ b/src/python_testing/TC_RVCRUNM_2_2.py @@ -135,12 +135,12 @@ async def test_TC_RVCRUNM_2_2(self): # Ensure that the device is in the correct state if self.is_ci: self.write_to_app_pipe('{"Name": "Reset"}') - - self.print_step(2, "Manually put the device in a RVC Run Mode cluster mode with " - "the Idle(0x4000) mode tag and in a device state that allows changing to either " - "of these modes: %i, %i" % (self.mode_a, self.mode_b)) + test_step = ("Manually put the device in a RVC Run Mode cluster mode with " + "the Idle(0x4000) mode tag and in a device state that allows changing to either " + "of these modes: %i, %i" % (self.mode_a, self.mode_b)) + self.print_step(2, test_step) if not self.is_ci: - input("Press Enter when done.\n") + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when ready.") self.print_step(3, "Read the RvcRunMode SupportedModes attribute") supported_run_modes = await self.read_run_supported_modes() @@ -207,11 +207,11 @@ async def test_TC_RVCRUNM_2_2(self): if self.is_ci: self.write_to_app_pipe('{"Name": "ChargerFound"}') else: - input("Press Enter when done.\n") + self.wait_for_user_input( + prompt_msg="Manually put the device in one of Stopped(0x00), Paused(0x02), Charging(0x41) or Docked(0x42), and press Enter when ready.\n") self.print_step(10, "Read RVCOPSTATE's OperationalState attribute") op_state = await self.read_op_state_operational_state() - asserts.assert_true(op_state in valid_op_states, "Expected RVCOPSTATE's OperationalState attribute to be one of Stopped(0x00), Paused(0x02), Charging(0x41) or Docked(0x42)") diff --git a/src/python_testing/matter_testing_support.py b/src/python_testing/matter_testing_support.py index 03d69e71566eaa..623ec9e8e44518 100644 --- a/src/python_testing/matter_testing_support.py +++ b/src/python_testing/matter_testing_support.py @@ -1060,15 +1060,13 @@ def get_setup_payload_info(self) -> SetupPayloadInfo: def wait_for_user_input(self, prompt_msg: str, - input_msg: str = "Press Enter when done.\n", prompt_msg_placeholder: str = "Submit anything to continue", default_value: str = "y") -> str: """Ask for user input and wait for it. Args: - prompt_msg (str): Message for TH UI prompt. Indicates what is expected from the user. - input_msg (str, optional): Prompt for input function, used when running tests manually. Defaults to "Press Enter when done.\n". - prompt_msg_placeholder (str, optional): TH UI prompt input placeholder. Defaults to "Submit anything to continue". + prompt_msg (str): Message for TH UI prompt and input function. Indicates what is expected from the user. + prompt_msg_placeholder (str, optional): TH UI prompt input placeholder (where the user types). Defaults to "Submit anything to continue". default_value (str, optional): TH UI prompt default value. Defaults to "y". Returns: @@ -1078,7 +1076,7 @@ def wait_for_user_input(self, self.runner_hook.show_prompt(msg=prompt_msg, placeholder=prompt_msg_placeholder, default_value=default_value) - return input(input_msg) + return input(f'{prompt_msg.removesuffix(chr(10))}\n') def generate_mobly_test_config(matter_test_config: MatterTestConfig): From 58536ba64da75f0a63c569baa29966008ffdf306 Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Tue, 25 Jun 2024 23:45:47 -0400 Subject: [PATCH 05/21] [Silabs]Update Submodules, API, gn files to use latest silabs sdks (#34073) * add simplicity sdk as submodule. remove gecko_sdk. Change wifi sdk branch * Reamove Heap_4_silabs, replace by sl_memory_manager Update matter-platform.slcp for simplicity sdk * Update 917 apis for wifi sdk 3.3.0 * Workflow to use latest silabs docker image * Fix to leverage csl on thread libs * bump matter support submodule * Restyled by clang-format * Restyled by autopep8 * fix linking issue with thread FTD lib * clean up * fix wifi ncp builds * update linker script for mgm24 and si917 --------- Co-authored-by: Restyled.io --- .github/workflows/examples-efr32.yaml | 2 +- .github/workflows/release_artifacts.yaml | 2 +- .gitmodules | 10 +- examples/light-switch-app/silabs/.gn | 2 +- examples/platform/silabs/SiWx917/BUILD.gn | 8 +- .../silabs/SiWx917/SiWx917/sl_wifi_if.cpp | 168 ++--- examples/platform/silabs/display/lcd.cpp | 7 +- examples/platform/silabs/efr32/BUILD.gn | 8 +- .../efr32/project_include/OpenThreadConfig.h | 4 +- .../efr32/rs911x/hal/rsi_hal_mcu_interrupt.c | 2 +- examples/platform/silabs/heap_4_silabs.c | 673 ------------------ examples/platform/silabs/heap_4_silabs.h | 49 -- .../silabs/ldscripts/SiWx917-common.ld | 51 +- .../platform/silabs/ldscripts/efr32mg24.ld | 262 ++++--- examples/platform/silabs/ldscripts/mgm24.ld | 262 ++++--- examples/platform/silabs/matter-platform.slcp | 28 +- src/platform/silabs/CHIPMem-Platform.cpp | 22 +- .../silabs/DiagnosticDataProviderImpl.cpp | 26 +- .../silabs/SiWx917/wifi/ethernetif.cpp | 102 +-- .../silabs/SiWx917/wifi/wfx_host_events.h | 9 +- src/platform/silabs/efr32/args.gni | 2 +- src/platform/silabs/efr32/wifi/ethernetif.cpp | 38 +- .../silabs/efr32/wifi/wfx_host_events.h | 6 - src/test_driver/efr32/BUILD.gn | 1 - .../openthread/platforms/efr32/BUILD.gn | 15 +- third_party/silabs/BUILD.gn | 38 +- third_party/silabs/SiWx917_sdk.gni | 25 + third_party/silabs/efr32_sdk.gni | 137 ++-- third_party/silabs/gecko_sdk | 1 - third_party/silabs/matter_support | 2 +- third_party/silabs/simplicity_sdk | 1 + third_party/silabs/slc_gen/run_slc.py | 23 +- third_party/silabs/wifi_sdk | 2 +- 33 files changed, 564 insertions(+), 1424 deletions(-) delete mode 100644 examples/platform/silabs/heap_4_silabs.c delete mode 100644 examples/platform/silabs/heap_4_silabs.h delete mode 160000 third_party/silabs/gecko_sdk create mode 160000 third_party/silabs/simplicity_sdk diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index 7dab3f0886f09e..eaaedd226e778b 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-efr32:54 + image: ghcr.io/project-chip/chip-build-efr32:56 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/release_artifacts.yaml b/.github/workflows/release_artifacts.yaml index 55041773007925..be862403037423 100644 --- a/.github/workflows/release_artifacts.yaml +++ b/.github/workflows/release_artifacts.yaml @@ -64,7 +64,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-efr32:54 + image: ghcr.io/project-chip/chip-build-efr32:56 steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.gitmodules b/.gitmodules index b2e1bc8d4ebd98..dee55fa9536e7e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -231,10 +231,10 @@ url = https://github.com/SiliconLabs/sdk_support.git branch = main platforms = silabs,silabs_docker -[submodule "third_party/silabs/gecko_sdk"] - path = third_party/silabs/gecko_sdk - url = https://github.com/SiliconLabs/gecko_sdk.git - branch = v4.4.2 +[submodule "third_party/silabs/simplicity_sdk"] + path = third_party/silabs/simplicity_sdk + url = https://github.com/SiliconLabs/simplicity_sdk.git + branch = v2024.6.0 platforms = silabs [submodule "third_party/silabs/wiseconnect-wifi-bt-sdk"] path = third_party/silabs/wiseconnect-wifi-bt-sdk @@ -244,7 +244,7 @@ [submodule "third_party/silabs/wifi_sdk"] path = third_party/silabs/wifi_sdk url = https://github.com/SiliconLabs/wiseconnect.git - branch = v3.1.3-matter-hotfix.4 + branch = v3.3.0 platforms = silabs [submodule "editline"] path = third_party/editline/repo diff --git a/examples/light-switch-app/silabs/.gn b/examples/light-switch-app/silabs/.gn index b05216fc9d7eae..27aa6c766a17e6 100644 --- a/examples/light-switch-app/silabs/.gn +++ b/examples/light-switch-app/silabs/.gn @@ -23,7 +23,7 @@ check_system_includes = true default_args = { target_cpu = "arm" target_os = "freertos" - chip_openthread_ftd = true + chip_openthread_ftd = false import("//openthread.gni") } diff --git a/examples/platform/silabs/SiWx917/BUILD.gn b/examples/platform/silabs/SiWx917/BUILD.gn index e8fce7e11279f6..084339723a0037 100644 --- a/examples/platform/silabs/SiWx917/BUILD.gn +++ b/examples/platform/silabs/SiWx917/BUILD.gn @@ -59,13 +59,8 @@ config("chip_examples_project_config") { include_dirs = [ "project_include" ] # Link options that provide a replacement for dynamic memory operations in standard - # library with the FreeRTOS malloc in platform code. + # library with the sl_memory_manager in platform code. ldflags = [ - # memory allocation -- these must be re-entrant and do locking - "-Wl,--wrap=malloc", - "-Wl,--wrap=free", - "-Wl,--wrap=realloc", - "-Wl,--wrap=calloc", "-Wl,--wrap=MemoryAlloc", # Wrap these in case internal newlib call them (e.g. strdup will) @@ -234,7 +229,6 @@ source_set("siwx917-common") { "${silabs_common_plat_dir}/LEDWidget.cpp", "${silabs_common_plat_dir}/MatterConfig.cpp", "${silabs_common_plat_dir}/SoftwareFaultReports.cpp", - "${silabs_common_plat_dir}/heap_4_silabs.c", "${silabs_common_plat_dir}/silabs_utils.cpp", "${silabs_common_plat_dir}/syscalls_stubs.cpp", "${silabs_plat_si91x_wifi_dir}/dhcp_client.cpp", diff --git a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp index 741dc96496aeb5..c89c6768abe62c 100644 --- a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp +++ b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp @@ -21,6 +21,7 @@ #include "silabs_utils.h" #include "sl_status.h" +#include #include "FreeRTOS.h" #include "event_groups.h" @@ -39,9 +40,12 @@ extern "C" { #include "ble_config.h" -#if SL_ICD_ENABLED && SLI_SI91X_MCU_INTERFACE +#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI91X_MCU_INTERFACE #include "rsi_rom_power_save.h" #include "sl_si91x_button_pin_config.h" +#if DISPLAY_ENABLED +#include "sl_memlcd.h" +#endif // DISPLAY_ENABLED extern "C" { #include "sl_si91x_driver.h" #include "sl_si91x_m4_ps.h" @@ -50,7 +54,7 @@ extern "C" { // TODO: should be removed once we are getting the press interrupt for button 0 with sleep #define BUTTON_PRESSED 1 bool btn0_pressed = false; -#endif // SL_ICD_ENABLED && SLI_SI91X_MCU_INTERFACE +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI91X_MCU_INTERFACE #include "dhcp_client.h" #include "wfx_host_events.h" @@ -70,19 +74,14 @@ extern "C" { #include "sl_wifi.h" #include "sl_wifi_callback_framework.h" #include "wfx_host_events.h" -#if TINYCRYPT_PRIMITIVES +#if SLI_SI91X_MCU_INTERFACE #include "sl_si91x_trng.h" #define TRNGKEY_SIZE 4 -#endif // TINYCRYPT_PRIMITIVES +#endif // SLI_SI91X_MCU_INTERFACE } WfxRsi_t wfx_rsi; -// TODO: remove this. Added only to monitor how many watch dog reset have happened during testing. -#ifdef SLI_SI91X_MCU_INTERFACE -volatile uint32_t watchdog_reset = 0; -#endif // SLI_SI91X_MCU_INTERFACE - /* Declare a variable to hold the data associated with the created event group. */ StaticEventGroup_t rsiDriverEventGroup; @@ -246,10 +245,9 @@ sl_status_t join_callback_handler(sl_wifi_event_t event, char * result, uint32_t wfx_rsi.dev_state &= ~(WFX_RSI_ST_STA_CONNECTING); if (SL_WIFI_CHECK_IF_EVENT_FAILED(event)) { - SILABS_LOG("F: Join Event received with %u bytes payload\n", result_length); callback_status = *(sl_status_t *) result; + SILABS_LOG("join_callback_handler: failed: 0x%X", callback_status); wfx_rsi.dev_state &= ~(WFX_RSI_ST_STA_CONNECTED); - is_wifi_disconnection_event = true; wfx_retry_interval_handler(is_wifi_disconnection_event, wfx_rsi.join_retries++); if (is_wifi_disconnection_event || wfx_rsi.join_retries <= WFX_RSI_CONFIG_MAX_JOIN) { @@ -262,26 +260,22 @@ sl_status_t join_callback_handler(sl_wifi_event_t event, char * result, uint32_t * Join was complete - Do the DHCP */ memset(&temp_reset, 0, sizeof(wfx_wifi_scan_ext_t)); - SILABS_LOG("join_callback_handler: join completed."); - SILABS_LOG("%c: Join Event received with %u bytes payload\n", *result, result_length); + SILABS_LOG("join_callback_handler: success"); WfxEvent.eventType = WFX_EVT_STA_CONN; WfxPostEvent(&WfxEvent); wfx_rsi.join_retries = 0; retryInterval = WLAN_MIN_RETRY_TIMER_MS; - if (is_wifi_disconnection_event) - { - is_wifi_disconnection_event = false; - } - callback_status = SL_STATUS_OK; + // Once the join passes setting the disconnection event to true to differentiate between the first connection and reconnection + is_wifi_disconnection_event = true; + callback_status = SL_STATUS_OK; return SL_STATUS_OK; } -#if SL_ICD_ENABLED - -#if SI917_M4_SLEEP_ENABLED +#if CHIP_CONFIG_ENABLE_ICD_SERVER +#if SLI_SI91X_MCU_INTERFACE // Required to invoke button press event during sleep as falling edge is not detected -void invoke_btn_press_event() +void sl_si91x_invoke_btn_press_event() { // TODO: should be removed once we are getting the press interrupt for button 0 with sleep if (!RSI_NPSSGPIO_GetPin(SL_BUTTON_BTN0_PIN) && !btn0_pressed) @@ -295,36 +289,28 @@ void invoke_btn_press_event() } } -/** - * @brief Checks if the Wi-Fi module is ready for sleep. - * - * This function checks if the Wi-Fi module is ready to enter sleep mode. - * - * @return true if the Wi-Fi module is ready for sleep, false otherwise. - */ -bool wfx_is_sleep_ready() -{ - // BRD4002A board BTN_PRESS is 0 when pressed, release is 1 - // sli_si91x_is_sleep_ready requires OS Scheduler to be active - return ((RSI_NPSSGPIO_GetPin(SL_BUTTON_BTN0_PIN) != 0) && (wfx_rsi.dev_state & WFX_RSI_ST_SLEEP_READY) && - sli_si91x_is_sleep_ready()); -} - -/** - * @brief Sleeps for a specified duration and then wakes up. - * - * This function puts the SI91x host into sleep mode for the specified duration - * in milliseconds and then wakes it up. - * - * @param sleep_time_ms The duration in milliseconds to sleep. - */ -void sl_wfx_host_si91x_sleep(uint16_t * sleep_time_ms) +/****************************************************************** + * @fn sl_app_sleep_ready() + * @brief + * Called from the supress ticks from tickless to check if it + * is ok to go to sleep + * @param[in] None + * @return + * None + *********************************************************************/ +uint32_t sl_app_sleep_ready() { - SL_ASSERT(sleep_time_ms != NULL); - sl_si91x_m4_sleep_wakeup(sleep_time_ms); + if (wfx_rsi.dev_state & WFX_RSI_ST_SLEEP_READY) + { +#if DISPLAY_ENABLED + // Powering down the LCD + sl_memlcd_power_on(NULL, false); +#endif /* DISPLAY_ENABLED */ + return true; + } + return false; } - -#endif // SI917_M4_SLEEP_ENABLED +#endif // SLI_SI91X_MCU_INTERFACE /****************************************************************** * @fn wfx_rsi_power_save() @@ -363,7 +349,7 @@ int32_t wfx_rsi_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_ } return status; } -#endif /* SL_ICD_ENABLED */ +#endif /* CHIP_CONFIG_ENABLE_ICD_SERVER */ /************************************************************************************* * @fn static int32_t wfx_wifi_rsi_init(void) @@ -378,13 +364,6 @@ int32_t wfx_wifi_rsi_init(void) SILABS_LOG("wfx_wifi_rsi_init started"); sl_status_t status; status = sl_wifi_init(&config, NULL, sl_wifi_default_event_handler); -#ifdef SLI_SI91X_MCU_INTERFACE - // TODO: remove this. Added only to monitor how many watch dog reset have happened during testing. - if ((MCU_FSM->MCU_FSM_WAKEUP_STATUS_REG) & BIT(5)) - { - watchdog_reset++; - } -#endif // SLI_SI91X_MCU_INTERFACE if (status != SL_STATUS_OK) { return status; @@ -449,7 +428,7 @@ static sl_status_t wfx_rsi_init(void) return status; } #else // For SoC -#if SL_ICD_ENABLED +#if CHIP_CONFIG_ENABLE_ICD_SERVER uint8_t xtal_enable = 1; status = sl_si91x_m4_ta_secure_handshake(SL_SI91X_ENABLE_XTAL, 1, &xtal_enable, 0, NULL); if (status != SL_STATUS_OK) @@ -457,7 +436,7 @@ static sl_status_t wfx_rsi_init(void) SILABS_LOG("Failed to bring m4_ta_secure_handshake: 0x%lx\r\n", status); return status; } -#endif /* SL_ICD_ENABLED */ +#endif /* CHIP_CONFIG_ENABLE_ICD_SERVER */ #endif /* SLI_SI91X_MCU_INTERFACE */ sl_wifi_firmware_version_t version = { 0 }; @@ -477,7 +456,7 @@ static sl_status_t wfx_rsi_init(void) return status; } -#ifdef TINYCRYPT_PRIMITIVES +#ifdef SLI_SI91X_MCU_INTERFACE const uint32_t trngKey[TRNGKEY_SIZE] = { 0x16157E2B, 0xA6D2AE28, 0x8815F7AB, 0x3C4FCF09 }; // To check the Entropy of TRNG and verify TRNG functioning. @@ -495,7 +474,7 @@ static sl_status_t wfx_rsi_init(void) SILABS_LOG("TRNG Key Programming Failed"); return status; } -#endif // TINYCRYPT_PRIMITIVES +#endif // SLI_SI91X_MCU_INTERFACE wfx_rsi.events = xEventGroupCreateStatic(&rsiDriverEventGroup); wfx_rsi.dev_state |= WFX_RSI_ST_DEV_READY; @@ -520,12 +499,13 @@ sl_status_t scan_callback_handler(sl_wifi_event_t event, sl_wifi_scan_result_t * { if (SL_WIFI_CHECK_IF_EVENT_FAILED(event)) { - callback_status = *(sl_status_t *) scan_result; + callback_status = *(sl_status_t *) scan_result; + SILABS_LOG("scan_callback_handler: failed: 0x%X", callback_status); scan_results_complete = true; #if WIFI_ENABLE_SECURITY_WPA3_TRANSITION wfx_rsi.sec.security = WFX_SEC_WPA3; #else - wfx_rsi.sec.security = WFX_SEC_WPA2; + wfx_rsi.sec.security = WFX_SEC_WPA2; #endif /* WIFI_ENABLE_SECURITY_WPA3_TRANSITION */ osSemaphoreRelease(sScanSemaphore); @@ -541,9 +521,9 @@ sl_status_t scan_callback_handler(sl_wifi_event_t event, sl_wifi_scan_result_t * break; case SL_WIFI_WPA: case SL_WIFI_WPA_ENTERPRISE: - case SL_WIFI_WPA_WPA2_MIXED: wfx_rsi.sec.security = WFX_SEC_WPA; break; + case SL_WIFI_WPA_WPA2_MIXED: case SL_WIFI_WPA2: case SL_WIFI_WPA2_ENTERPRISE: wfx_rsi.sec.security = WFX_SEC_WPA2; @@ -556,7 +536,7 @@ sl_status_t scan_callback_handler(sl_wifi_event_t event, sl_wifi_scan_result_t * case SL_WIFI_WPA3: wfx_rsi.sec.security = WFX_SEC_WPA3; #else - wfx_rsi.sec.security = WFX_SEC_WPA2; + wfx_rsi.sec.security = WFX_SEC_WPA2; #endif /* WIFI_ENABLE_SECURITY_WPA3_TRANSITION */ break; default: @@ -661,14 +641,18 @@ static sl_status_t wfx_rsi_do_join(void) connect_security_mode = SL_WIFI_WEP; break; case WFX_SEC_WPA: - case WFX_SEC_WPA2: connect_security_mode = SL_WIFI_WPA_WPA2_MIXED; break; + case WFX_SEC_WPA2: #if WIFI_ENABLE_SECURITY_WPA3_TRANSITION + connect_security_mode = SL_WIFI_WPA3_TRANSITION; + break; case WFX_SEC_WPA3: connect_security_mode = SL_WIFI_WPA3_TRANSITION; +#else + connect_security_mode = SL_WIFI_WPA_WPA2_MIXED; +#endif // WIFI_ENABLE_SECURITY_WPA3_TRANSITION break; -#endif /*WIFI_ENABLE_SECURITY_WPA3_TRANSITION*/ case WFX_SEC_NONE: connect_security_mode = SL_WIFI_OPEN; break; @@ -695,14 +679,14 @@ static sl_status_t wfx_rsi_do_join(void) sl_wifi_set_join_callback(join_callback_handler, NULL); -#if SL_ICD_ENABLED +#if CHIP_CONFIG_ENABLE_ICD_SERVER // Setting the listen interval to 0 which will set it to DTIM interval sl_wifi_listen_interval_t sleep_interval = { .listen_interval = 0 }; status = sl_wifi_set_listen_interval(SL_WIFI_CLIENT_INTERFACE, sleep_interval); sl_wifi_advanced_client_configuration_t client_config = { .max_retry_attempts = 5 }; sl_wifi_set_advanced_client_configuration(SL_WIFI_CLIENT_INTERFACE, &client_config); -#endif // SL_ICD_ENABLED +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER /* Try to connect Wifi with given Credentials * untill there is a success or maximum number of tries allowed */ @@ -1006,47 +990,3 @@ void wfx_dhcp_got_ipv4(uint32_t ip) wfx_rsi.dev_state |= WFX_RSI_ST_STA_READY; } #endif /* CHIP_DEVICE_CONFIG_ENABLE_IPV4 */ - -/******************************************************************************************** - * @fn void wfx_rsi_pkt_add_data(void *p, uint8_t *buf, uint16_t len, uint16_t off) - * @brief - * add the data into packet - * @param[in] p: - * @param[in] buf: - * @param[in] len: - * @param[in] off: - * @return - * None - **********************************************************************************************/ -void wfx_rsi_pkt_add_data(void * p, uint8_t * buf, uint16_t len, uint16_t off) -{ - sl_si91x_packet_t * pkt; - pkt = (sl_si91x_packet_t *) p; - memcpy(((char *) pkt->data) + off, buf, len); -} - -#if !EXP_BOARD -/******************************************************************************************** - * @fn int32_t wfx_rsi_send_data(void *p, uint16_t len) - * @brief - * Driver send a data - * @param[in] p: - * @param[in] len: - * @return - * None - **********************************************************************************************/ -int32_t wfx_rsi_send_data(void * p, uint16_t len) -{ - int32_t status; - sl_wifi_buffer_t * buffer; - buffer = (sl_wifi_buffer_t *) p; - - if (sl_si91x_driver_send_data_packet(SI91X_WLAN_CMD_QUEUE, buffer, RSI_SEND_RAW_DATA_RESPONSE_WAIT_TIME)) - { - SILABS_LOG("*ERR*EN-RSI:Send fail"); - return ERR_IF; - } - return status; -} - -#endif diff --git a/examples/platform/silabs/display/lcd.cpp b/examples/platform/silabs/display/lcd.cpp index bf40cd0f6d543b..80cd5a1774bbad 100644 --- a/examples/platform/silabs/display/lcd.cpp +++ b/examples/platform/silabs/display/lcd.cpp @@ -26,7 +26,7 @@ #include "glib.h" #if (SLI_SI91X_MCU_INTERFACE) -#include "rsi_chip.h" +#include "sl_memlcd.h" #endif #ifdef QR_CODE_ENABLED @@ -67,10 +67,7 @@ CHIP_ERROR SilabsLCD::Init(uint8_t * name, bool initialState) /* Enable the memory lcd */ #if (SLI_SI91X_MCU_INTERFACE) - RSI_NPSSGPIO_InputBufferEn(SL_BOARD_ENABLE_DISPLAY_PIN, 1U); - RSI_NPSSGPIO_SetPinMux(SL_BOARD_ENABLE_DISPLAY_PIN, 0); - RSI_NPSSGPIO_SetDir(SL_BOARD_ENABLE_DISPLAY_PIN, 0); - RSI_NPSSGPIO_SetPin(SL_BOARD_ENABLE_DISPLAY_PIN, 1U); + sl_memlcd_display_enable(); #else status = sl_board_enable_display(); if (status != SL_STATUS_OK) diff --git a/examples/platform/silabs/efr32/BUILD.gn b/examples/platform/silabs/efr32/BUILD.gn index aa6c72a98c24b2..20180ecb57656a 100644 --- a/examples/platform/silabs/efr32/BUILD.gn +++ b/examples/platform/silabs/efr32/BUILD.gn @@ -76,13 +76,8 @@ config("chip_examples_project_config") { include_dirs = [ "project_include" ] # Link options that provide a replacement for dynamic memory operations in standard - # library with the FreeRTOS malloc in platform code. + # library with the sl_memory_manager in platform code. ldflags = [ - # memory allocation -- these must be re-entrant and do locking - "-Wl,--wrap=malloc", - "-Wl,--wrap=free", - "-Wl,--wrap=realloc", - "-Wl,--wrap=calloc", "-Wl,--wrap=MemoryAlloc", # Wrap these in case internal newlib call them (e.g. strdup will) @@ -280,7 +275,6 @@ source_set("efr32-common") { "${silabs_common_plat_dir}/LEDWidget.cpp", "${silabs_common_plat_dir}/MatterConfig.cpp", "${silabs_common_plat_dir}/SoftwareFaultReports.cpp", - "${silabs_common_plat_dir}/heap_4_silabs.c", "${silabs_common_plat_dir}/silabs_utils.cpp", "${silabs_common_plat_dir}/syscalls_stubs.cpp", ] diff --git a/examples/platform/silabs/efr32/project_include/OpenThreadConfig.h b/examples/platform/silabs/efr32/project_include/OpenThreadConfig.h index d7492f4044f3fa..ed56c7a5785d8a 100644 --- a/examples/platform/silabs/efr32/project_include/OpenThreadConfig.h +++ b/examples/platform/silabs/efr32/project_include/OpenThreadConfig.h @@ -45,7 +45,7 @@ // Timeout after 2 missed checkin or 4 mins if sleep interval is too short. #define OPENTHREAD_CONFIG_MLE_CHILD_TIMEOUT_DEFAULT ((SL_MLE_TIMEOUT_s < 120) ? 240 : ((SL_MLE_TIMEOUT_s * 2) + 1)) -#if defined(SL_CSL_ENABLE) && SL_CSL_ENABLE +#if defined(SL_CSL_ENABLE) && SL_CSL_ENABLE || SL_CONFIG_OPENTHREAD_LIB #define OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1 #define OPENTHREAD_CONFIG_MAC_CSL_AUTO_SYNC_ENABLE 1 @@ -55,7 +55,7 @@ #define OPENTHREAD_CONFIG_CSL_TIMEOUT SL_CSL_TIMEOUT #define SL_OPENTHREAD_CSL_TX_UNCERTAINTY 200 -#endif // SL_CSL_ENABLE +#endif // SL_CSL_ENABLE || SL_CONFIG_OPENTHREAD_LIB #endif // SL_ICD_ENABLED diff --git a/examples/platform/silabs/efr32/rs911x/hal/rsi_hal_mcu_interrupt.c b/examples/platform/silabs/efr32/rs911x/hal/rsi_hal_mcu_interrupt.c index 079a5e0c9c32f4..1cb5ddf9206d65 100644 --- a/examples/platform/silabs/efr32/rs911x/hal/rsi_hal_mcu_interrupt.c +++ b/examples/platform/silabs/efr32/rs911x/hal/rsi_hal_mcu_interrupt.c @@ -62,7 +62,7 @@ void rsi_gpio_irq_cb(uint8_t irqnum) if (irqnum != SL_WFX_HOST_PINOUT_SPI_IRQ) return; #if (SLI_SI91X_MCU_INTERFACE | EXP_BOARD) - sl_si91x_host_set_bus_event(NCP_HOST_BUS_RX_EVENT); + sl_si91x_host_set_bus_event(SL_SI91X_NCP_HOST_BUS_RX_EVENT); #else GPIO_IntClear(1 << SL_WFX_HOST_PINOUT_SPI_IRQ); if (call_back != NULL) diff --git a/examples/platform/silabs/heap_4_silabs.c b/examples/platform/silabs/heap_4_silabs.c deleted file mode 100644 index 8abb295caefd2d..00000000000000 --- a/examples/platform/silabs/heap_4_silabs.c +++ /dev/null @@ -1,673 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -/* - * FreeRTOS Kernel V10.4.3 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -/* - * A sample implementation of pvPortMalloc() and vPortFree() that combines - * (coalescences) adjacent memory blocks as they are freed, and in so doing - * limits memory fragmentation. - * - * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the - * memory management pages of https://www.FreeRTOS.org for more information. - */ -#include - -/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining -all the API functions to use the MPU wrappers. That should only be done when -task.h is included from an application file. */ -#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE - -#include "heap_4_silabs.h" -#include "task.h" -#include -#include - -#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE - -#if (configSUPPORT_DYNAMIC_ALLOCATION == 0) -#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 -#endif - -/* Block sizes must not get too small. */ -#define heapMINIMUM_BLOCK_SIZE ((size_t) (xHeapStructSize << 1)) - -/* Assumes 8bit bytes! */ -#define heapBITS_PER_BYTE ((size_t) 8) - -/* Allocate the memory for the heap. */ -#if (configAPPLICATION_ALLOCATED_HEAP == 1) -/* The application writer has already defined the array used for the RTOS -heap - probably so it can be placed in a special segment or address. */ -extern uint8_t ucHeap[configTOTAL_HEAP_SIZE]; -#else -static uint8_t ucHeap[configTOTAL_HEAP_SIZE]; -#endif /* configAPPLICATION_ALLOCATED_HEAP */ - -/* Define the linked list structure. This is used to link free blocks in order -of their memory address. */ -typedef struct A_BLOCK_LINK -{ - struct A_BLOCK_LINK * pxNextFreeBlock; /*<< The next free block in the list. */ - size_t xBlockSize; /*<< The size of the free block. */ -} BlockLink_t; - -/*-----------------------------------------------------------*/ - -/* - * Inserts a block of memory that is being freed into the correct position in - * the list of free memory blocks. The block being freed will be merged with - * the block in front it and/or the block behind it if the memory blocks are - * adjacent to each other. - */ -static void prvInsertBlockIntoFreeList(BlockLink_t * pxBlockToInsert); - -/* - * Called automatically to setup the required heap structures the first time - * pvPortMalloc() is called. - */ -static void prvHeapInit(void); - -/*-----------------------------------------------------------*/ - -/* The size of the structure placed at the beginning of each allocated memory - * block must by correctly byte aligned. */ -static const size_t xHeapStructSize = - (sizeof(BlockLink_t) + ((size_t) (portBYTE_ALIGNMENT - 1))) & ~((size_t) portBYTE_ALIGNMENT_MASK); - -/* Create a couple of list links to mark the start and end of the list. */ -static BlockLink_t xStart, *pxEnd = NULL; - -/* Keeps track of the number of calls to allocate and free memory as well as the - * number of free bytes remaining, but says nothing about fragmentation. */ -static size_t xFreeBytesRemaining = 0U; -static size_t xMinimumEverFreeBytesRemaining = 0U; -static size_t xNumberOfSuccessfulAllocations = 0; -static size_t xNumberOfSuccessfulFrees = 0; - -/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize - * member of an BlockLink_t structure is set then the block belongs to the - * application. When the bit is free the block is still part of the free heap - * space. */ -static size_t xBlockAllocatedBit = 0; - -/** - * @brief xPortPointerSize is based on the malloc implementation of heap_4 - * Returns the size of allocated block associated to the pointer - * - * @param pv pointer - * @return size_t block size - */ -size_t xPortPointerSize(void * pv) -{ - uint8_t * puc = (uint8_t *) pv; - BlockLink_t * pxLink; - void * voidp; - size_t sz = 0; - - if (pv != NULL) - { - vTaskSuspendAll(); - { - /* The memory being checked will have an BlockLink_t structure immediately - before it. */ - puc -= xHeapStructSize; - - /* This casting is to keep the compiler from issuing warnings. */ - voidp = (void *) puc; - pxLink = (BlockLink_t *) voidp; - - /* Check if the block is actually allocated. */ - configASSERT((pxLink->xBlockSize & xBlockAllocatedBit) != 0); - configASSERT(pxLink->pxNextFreeBlock == NULL); - - sz = (pxLink->xBlockSize & ~xBlockAllocatedBit) - xHeapStructSize; - } - (void) xTaskResumeAll(); - } - - return sz; -} - -/*-----------------------------------------------------------*/ - -void * pvPortMalloc(size_t xWantedSize) -{ - BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; - void * pvReturn = NULL; - - vTaskSuspendAll(); - { - /* If this is the first call to malloc then the heap will require - * initialisation to setup the list of free blocks. */ - if (pxEnd == NULL) - { - prvHeapInit(); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - /* Check the requested block size is not so large that the top bit is - * set. The top bit of the block size member of the BlockLink_t structure - * is used to determine who owns the block - the application or the - * kernel, so it must be free. */ - if ((xWantedSize & xBlockAllocatedBit) == 0) - { - /* The wanted size must be increased so it can contain a BlockLink_t - * structure in addition to the requested amount of bytes. */ - if ((xWantedSize > 0) && ((xWantedSize + xHeapStructSize) > xWantedSize)) /* Overflow check */ - { - xWantedSize += xHeapStructSize; - - /* Ensure that blocks are always aligned. */ - if ((xWantedSize & portBYTE_ALIGNMENT_MASK) != 0x00) - { - /* Byte alignment required. Check for overflow. */ - if ((xWantedSize + (portBYTE_ALIGNMENT - (xWantedSize & portBYTE_ALIGNMENT_MASK))) > xWantedSize) - { - xWantedSize += (portBYTE_ALIGNMENT - (xWantedSize & portBYTE_ALIGNMENT_MASK)); - configASSERT((xWantedSize & portBYTE_ALIGNMENT_MASK) == 0); - } - else - { - xWantedSize = 0; - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - xWantedSize = 0; - } - - if ((xWantedSize > 0) && (xWantedSize <= xFreeBytesRemaining)) - { - /* Traverse the list from the start (lowest address) block until - * one of adequate size is found. */ - pxPreviousBlock = &xStart; - pxBlock = xStart.pxNextFreeBlock; - - while ((pxBlock->xBlockSize < xWantedSize) && (pxBlock->pxNextFreeBlock != NULL)) - { - pxPreviousBlock = pxBlock; - pxBlock = pxBlock->pxNextFreeBlock; - } - - /* If the end marker was reached then a block of adequate size - * was not found. */ - if (pxBlock != pxEnd) - { - /* Return the memory space pointed to - jumping over the - * BlockLink_t structure at its start. */ - pvReturn = (void *) (((uint8_t *) pxPreviousBlock->pxNextFreeBlock) + xHeapStructSize); - - /* This block is being returned for use so must be taken out - * of the list of free blocks. */ - pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; - - /* If the block is larger than required it can be split into - * two. */ - if ((pxBlock->xBlockSize - xWantedSize) > heapMINIMUM_BLOCK_SIZE) - { - /* This block is to be split into two. Create a new - * block following the number of bytes requested. The void - * cast is used to prevent byte alignment warnings from the - * compiler. */ - pxNewBlockLink = (void *) (((uint8_t *) pxBlock) + xWantedSize); - configASSERT((((size_t) pxNewBlockLink) & portBYTE_ALIGNMENT_MASK) == 0); - - /* Calculate the sizes of two blocks split from the - * single block. */ - pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; - pxBlock->xBlockSize = xWantedSize; - - /* Insert the new block into the list of free blocks. */ - prvInsertBlockIntoFreeList(pxNewBlockLink); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - xFreeBytesRemaining -= pxBlock->xBlockSize; - - if (xFreeBytesRemaining < xMinimumEverFreeBytesRemaining) - { - xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - /* The block is being returned - it is allocated and owned - * by the application and has no "next" block. */ - pxBlock->xBlockSize |= xBlockAllocatedBit; - pxBlock->pxNextFreeBlock = NULL; - xNumberOfSuccessfulAllocations++; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - traceMALLOC(pvReturn, xWantedSize); - } - (void) xTaskResumeAll(); - -#if (configUSE_MALLOC_FAILED_HOOK == 1) - { - if (pvReturn == NULL) - { - extern void vApplicationMallocFailedHook(void); - vApplicationMallocFailedHook(); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } -#endif /* if ( configUSE_MALLOC_FAILED_HOOK == 1 ) */ - - configASSERT((((size_t) pvReturn) & (size_t) portBYTE_ALIGNMENT_MASK) == 0); - return pvReturn; -} -/*-----------------------------------------------------------*/ - -void * pvPortCalloc(size_t num, size_t size) -{ - size_t total = num * size; - // check for multiplication overflow - if ((size != 0) && ((total / size) != num)) - { - return NULL; - } - - void * ptr = pvPortMalloc(total); - if (ptr != NULL) - { - memset(ptr, 0, total); - } - - return ptr; -} - -void * pvPortRealloc(void * pv, size_t size) -{ - void * resized_ptr = NULL; - size_t current_size = xPortPointerSize(pv); - - if (current_size > 0) // pv is allocated - { - if (size) // New size is not 0 - { - if (size == current_size) // if existing pointer is the same size - { - resized_ptr = pv; - } - else // New size is a different from current size - { - resized_ptr = pvPortCalloc(1, size); - if (resized_ptr != NULL) - { - size_t smallest_size = size < current_size ? size : current_size; - memcpy(resized_ptr, pv, smallest_size); - - vPortFree(pv); - } - } - } - else // If size if 0, free pointer - { - vPortFree(pv); - } - } - else // pv is not allocated, allocate a new pointer - { - resized_ptr = pvPortCalloc(1, size); - } - - return resized_ptr; -} - -/*-----------------------------------------------------------*/ - -void vPortFree(void * pv) -{ - uint8_t * puc = (uint8_t *) pv; - BlockLink_t * pxLink; - - if (pv != NULL) - { - /* The memory being freed will have an BlockLink_t structure immediately - * before it. */ - puc -= xHeapStructSize; - - /* This casting is to keep the compiler from issuing warnings. */ - pxLink = (void *) puc; - - /* Check the block is actually allocated. */ - configASSERT((pxLink->xBlockSize & xBlockAllocatedBit) != 0); - configASSERT(pxLink->pxNextFreeBlock == NULL); - - if ((pxLink->xBlockSize & xBlockAllocatedBit) != 0) - { - if (pxLink->pxNextFreeBlock == NULL) - { - /* The block is being returned to the heap - it is no longer - * allocated. */ - pxLink->xBlockSize &= ~xBlockAllocatedBit; - - vTaskSuspendAll(); - { - /* Add this block to the list of free blocks. */ - xFreeBytesRemaining += pxLink->xBlockSize; - traceFREE(pv, pxLink->xBlockSize); - prvInsertBlockIntoFreeList(((BlockLink_t *) pxLink)); - xNumberOfSuccessfulFrees++; - } - (void) xTaskResumeAll(); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } -} -/*-----------------------------------------------------------*/ - -size_t xPortGetFreeHeapSize(void) -{ - return xFreeBytesRemaining; -} -/*-----------------------------------------------------------*/ - -size_t xPortGetMinimumEverFreeHeapSize(void) -{ - return xMinimumEverFreeBytesRemaining; -} - -void xPortResetHeapMinimumEverFreeHeapSize(void) -{ - taskENTER_CRITICAL(); - { - xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; - } - taskEXIT_CRITICAL(); -} - -/*-----------------------------------------------------------*/ - -void vPortInitialiseBlocks(void) -{ - /* This just exists to keep the linker quiet. */ -} -/*-----------------------------------------------------------*/ - -static void prvHeapInit(void) -{ - BlockLink_t * pxFirstFreeBlock; - uint8_t * pucAlignedHeap; - size_t uxAddress; - size_t xTotalHeapSize = configTOTAL_HEAP_SIZE; - - /* Ensure the heap starts on a correctly aligned boundary. */ - uxAddress = (size_t) ucHeap; - - if ((uxAddress & portBYTE_ALIGNMENT_MASK) != 0) - { - uxAddress += (portBYTE_ALIGNMENT - 1); - uxAddress &= ~((size_t) portBYTE_ALIGNMENT_MASK); - xTotalHeapSize -= uxAddress - (size_t) ucHeap; - } - - pucAlignedHeap = (uint8_t *) uxAddress; - - /* xStart is used to hold a pointer to the first item in the list of free - * blocks. The void cast is used to prevent compiler warnings. */ - xStart.pxNextFreeBlock = (void *) pucAlignedHeap; - xStart.xBlockSize = (size_t) 0; - - /* pxEnd is used to mark the end of the list of free blocks and is inserted - * at the end of the heap space. */ - uxAddress = ((size_t) pucAlignedHeap) + xTotalHeapSize; - uxAddress -= xHeapStructSize; - uxAddress &= ~((size_t) portBYTE_ALIGNMENT_MASK); - pxEnd = (void *) uxAddress; - pxEnd->xBlockSize = 0; - pxEnd->pxNextFreeBlock = NULL; - - /* To start with there is a single free block that is sized to take up the - * entire heap space, minus the space taken by pxEnd. */ - pxFirstFreeBlock = (void *) pucAlignedHeap; - pxFirstFreeBlock->xBlockSize = uxAddress - (size_t) pxFirstFreeBlock; - pxFirstFreeBlock->pxNextFreeBlock = pxEnd; - - /* Only one block exists - and it covers the entire usable heap space. */ - xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; - xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; - - /* Work out the position of the top bit in a size_t variable. */ - xBlockAllocatedBit = ((size_t) 1) << ((sizeof(size_t) * heapBITS_PER_BYTE) - 1); -} -/*-----------------------------------------------------------*/ - -static void prvInsertBlockIntoFreeList(BlockLink_t * pxBlockToInsert) -{ - BlockLink_t * pxIterator; - uint8_t * puc; - - if (xStart.pxNextFreeBlock == 0) - { - // configASSERT( xStart.pxNextFreeBlock!=0); - HeapStats_t Stats; - vPortGetHeapStats(&Stats); - } - /* Iterate through the list until a block is found that has a higher address - * than the block being inserted. */ - for (pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock) - { - /* Nothing to do here, just iterate to the right position. */ - } - - /* Do the block being inserted, and the block it is being inserted after - * make a contiguous block of memory? */ - puc = (uint8_t *) pxIterator; - - if ((puc + pxIterator->xBlockSize) == (uint8_t *) pxBlockToInsert) - { - pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; - pxBlockToInsert = pxIterator; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - /* Do the block being inserted, and the block it is being inserted before - * make a contiguous block of memory? */ - puc = (uint8_t *) pxBlockToInsert; - - if ((puc + pxBlockToInsert->xBlockSize) == (uint8_t *) pxIterator->pxNextFreeBlock) - { - if (pxIterator->pxNextFreeBlock != pxEnd) - { - /* Form one big block from the two blocks. */ - pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; - pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; - } - else - { - pxBlockToInsert->pxNextFreeBlock = pxEnd; - } - } - else - { - pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; - } - - /* If the block being inserted plugged a gab, so was merged with the block - * before and the block after, then it's pxNextFreeBlock pointer will have - * already been set, and should not be set here as that would make it point - * to itself. */ - if (pxIterator != pxBlockToInsert) - { - pxIterator->pxNextFreeBlock = pxBlockToInsert; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } -} -/*-----------------------------------------------------------*/ - -void vPortGetHeapStats(HeapStats_t * pxHeapStats) -{ - BlockLink_t * pxBlock; - size_t xBlocks = 0, xMaxSize = 0, - xMinSize = portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */ - - vTaskSuspendAll(); - { - pxBlock = xStart.pxNextFreeBlock; - - /* pxBlock will be NULL if the heap has not been initialised. The heap - * is initialised automatically when the first allocation is made. */ - if (pxBlock != NULL) - { - do - { - /* Increment the number of blocks and record the largest block seen - * so far. */ - xBlocks++; - - if (pxBlock->xBlockSize > xMaxSize) - { - xMaxSize = pxBlock->xBlockSize; - } - - if (pxBlock->xBlockSize < xMinSize) - { - xMinSize = pxBlock->xBlockSize; - } - - /* Move to the next block in the chain until the last block is - * reached. */ - pxBlock = pxBlock->pxNextFreeBlock; - } while (pxBlock != pxEnd); - } - } - (void) xTaskResumeAll(); - - pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize; - pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize; - pxHeapStats->xNumberOfFreeBlocks = xBlocks; - - taskENTER_CRITICAL(); - { - pxHeapStats->xAvailableHeapSpaceInBytes = xFreeBytesRemaining; - pxHeapStats->xNumberOfSuccessfulAllocations = xNumberOfSuccessfulAllocations; - pxHeapStats->xNumberOfSuccessfulFrees = xNumberOfSuccessfulFrees; - pxHeapStats->xMinimumEverFreeBytesRemaining = xMinimumEverFreeBytesRemaining; - } - taskEXIT_CRITICAL(); -} - -/* - * Wrapper functions to override default memory allocation functions - */ -void * __wrap_malloc(size_t size) -{ - return pvPortMalloc(size); -} - -void __wrap_free(void * ptr) -{ - vPortFree(ptr); -} - -void * __wrap_realloc(void * ptr, size_t new_size) -{ - return pvPortRealloc(ptr, new_size); -} - -__attribute__((used)) void * __wrap_calloc(size_t num, size_t size) -{ - return pvPortCalloc(num, size); -} - -void * __wrap__calloc_r(void * REENT, size_t num, size_t size) -{ - return __wrap_calloc(num, size); -} - -void * __wrap__malloc_r(void * REENT, size_t size) -{ - return __wrap_malloc(size); -} - -void __wrap__free_r(void * REENT, void * ptr) -{ - __wrap_free(ptr); -} - -void * __wrap__realloc_r(void * REENT, void * ptr, size_t new_size) -{ - return __wrap_realloc(ptr, new_size); -} diff --git a/examples/platform/silabs/heap_4_silabs.h b/examples/platform/silabs/heap_4_silabs.h deleted file mode 100644 index ed773f59f0a33c..00000000000000 --- a/examples/platform/silabs/heap_4_silabs.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Copyright (c) 2020 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. - */ -/******************************************************************************* - * @file - * @brief heap_4_silabs.h - ******************************************************************************* - * # License - * Copyright 2018 Silicon Laboratories Inc. www.silabs.com - ******************************************************************************* - * - * The licensor of this software is Silicon Laboratories Inc. Your use of this - * software is governed by the terms of Silicon Labs Master Software License - * Agreement (MSLA) available at - * www.silabs.com/about-us/legal/master-software-license-agreement. This - * software is distributed to you in Source Code format and is governed by the - * sections of the MSLA applicable to Source Code. - * - ******************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "FreeRTOS.h" -#include - -void * pvPortCalloc(size_t num, size_t size); -void * pvPortRealloc(void * pv, size_t size); - -void xPortResetHeapMinimumEverFreeHeapSize(void); - -#ifdef __cplusplus -} -#endif diff --git a/examples/platform/silabs/ldscripts/SiWx917-common.ld b/examples/platform/silabs/ldscripts/SiWx917-common.ld index f23fecf8950d4c..fcc5c97de0a85b 100644 --- a/examples/platform/silabs/ldscripts/SiWx917-common.ld +++ b/examples/platform/silabs/ldscripts/SiWx917-common.ld @@ -39,8 +39,8 @@ SECTIONS .text : { KEEP(*(.isr_vector)) - KEEP(*(.reset_handler)) - *(EXCLUDE_FILE(*sl_si91x_bus.c.o *sl_si91x_driver.c.o *sli_si91x_multithreaded.c.o *rsi_hal_mcu_m4_ram.c.o *rsi_hal_mcu_m4_rom.c.o *rsi_deepsleep_soc.c.o *croutine.c.o *event_groups.c.o *list.c.o *queue.c.o *stream_buffer.c.o *tasks.c.o *timers.c.o *cmsis_os2.c.o *freertos_umm_malloc_host.c.o *malloc_buffers.c.o *sl_rsi_utility.c.o *port.c.o *heap_*.c.o *os_systick.c.o *sl_wifi_if.c.o *sl_si91x_m4_ps.c.o *sl_platform_wireless.c.o) .text*) + KEEP(*(.reset_handler)) + *(EXCLUDE_FILE(*sl_si91x_bus.o *sl_si91x_driver.o *sli_si91x_multithreaded.o *rsi_hal_mcu_m4_ram.o *rsi_hal_mcu_m4_rom.o *rsi_deepsleep_soc.o *croutine.o *event_groups.o *list.o *queue.o *stream_buffer.o *tasks.o *timers.o *cmsis_os2.o *freertos_umm_malloc_host.o *malloc_buffers.o *sl_rsi_utility.o *port.o *sl_sleeptimer.o *sl_sleeptimer_hal_si91x_sysrtc.o *rsi_sysrtc.o *sl_si91x_low_power_tickless_mode.o *heap_*.o *sl_core_cortexm.o) .text*) /* .ctors */ *crtbegin.o(.ctors) @@ -127,29 +127,30 @@ SECTIONS *(.rodata*) *(vtable) *(.data*) - *sl_si91x_bus.c.o(.text*) - *sl_si91x_driver.c.o(.text*) - *sli_si91x_multithreaded.c.o(.text*) - *rsi_hal_mcu_m4_ram.c.o(.text*) - *rsi_hal_mcu_m4_rom.c.o(.text*) - *rsi_deepsleep_soc.c.o(.text*) - *croutine.c.o(.text*) - *event_groups.c.o(.text*) - *list.c.o(.text*) - *queue.c.o(.text*) - *cmsis_os2.c.o(.text*) - *stream_buffer.c.o(.text*) - *tasks.c.o(.text*) - *timers.c.o(.text*) - *freertos_umm_malloc_host.c.o(.text*) - *malloc_buffers.c.o(.text*) - *sl_rsi_utility.c.o(.text*) - *port.c.o(.text*) - *heap_*.c.o(.text*) - *os_systick.c.o(.text*) - *sl_wifi_if.c.o(.text*) - *sl_si91x_m4_ps.c.o(.text*) - *sl_platform_wireless.c.o(.text*) + *sl_si91x_bus.o(.text*) + *sl_si91x_driver.o(.text*) + *sli_si91x_multithreaded.o(.text*) + *rsi_hal_mcu_m4_ram.o(.text*) + *rsi_hal_mcu_m4_rom.o(.text*) + *rsi_deepsleep_soc.o(.text*) + *croutine.o(.text*) + *event_groups.o(.text*) + *list.o(.text*) + *queue.o(.text*) + *cmsis_os2.o(.text*) + *stream_buffer.o(.text*) + *tasks.o(.text*) + *timers.o(.text*) + *freertos_umm_malloc_host.o(.text*) + *malloc_buffers.o(.text*) + *sl_rsi_utility.o(.text*) + *port.o(.text*) + *heap_*.o(.text*) + *sl_sleeptimer.o(.text*) + *sl_sleeptimer_hal_si91x_sysrtc.o(.text*) + *rsi_sysrtc.o(.text*) + *sl_si91x_low_power_tickless_mode.o(.text*) + *sl_core_cortexm.o(.text*) . = ALIGN(4); /* preinit data */ diff --git a/examples/platform/silabs/ldscripts/efr32mg24.ld b/examples/platform/silabs/ldscripts/efr32mg24.ld index b911b1339741d4..16066c24195cec 100644 --- a/examples/platform/silabs/ldscripts/efr32mg24.ld +++ b/examples/platform/silabs/ldscripts/efr32mg24.ld @@ -1,43 +1,22 @@ -/* - * - * Copyright (c) 2021 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. - */ /***************************************************************************//** - * @file gcc_EFR32MG24.ld - * @brief GNU Linker Script for Cortex-M based device - * @version V2.2.0 - * @date 16. December 2020 - * Linker script for Silicon Labs EFR32MG24 devices + * GCC Linker script for Silicon Labs devices ******************************************************************************* * # License - * Copyright 2022 Silicon Laboratories, Inc. www.silabs.com + * Copyright 2020 Silicon Laboratories Inc. www.silabs.com ******************************************************************************* * * SPDX-License-Identifier: Zlib - * + * * The licensor of this software is Silicon Laboratories Inc. - * + * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. - * + * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: - * + * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be @@ -48,52 +27,81 @@ * ******************************************************************************/ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x08006000, LENGTH = 0x17A000 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 -} - -/* Linker script to place sections and symbol values. Should be used together - * with other linker script that defines memory regions FLASH and RAM. - * It references following symbols, which must be defined in code: - * Reset_Handler : Entry of reset handler - * - * It defines following symbols, which code can use without definition: - * __exidx_start - * __exidx_end - * __copy_table_start__ - * __copy_table_end__ - * __zero_table_start__ - * __zero_table_end__ - * __etext - * __data_start__ - * __preinit_array_start - * __preinit_array_end - * __init_array_start - * __init_array_end - * __fini_array_start - * __fini_array_end - * __data_end__ - * __bss_start__ - * __bss_end__ - * __end__ - * end - * __HeapLimit - * __StackLimit - * __StackTop - * __stack - * __StackSeal (only if ARMv8-M stack sealing is used) - */ + MEMORY + { + FLASH (rx) : ORIGIN = 0x8006000, LENGTH = 0x178000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 + } ENTRY(Reset_Handler) SECTIONS { - .text : + + .vectors : { + linker_vectors_begin = .; KEEP(*(.vectors)) - *(.text*) + linker_vectors_end = .; + + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __lma_ramfuncs_start__ = .; + } > FLASH + + .stack (NOLOAD): + { + . = ALIGN(8); + __StackLimit = .; + KEEP(*(.stack*)) + . = ALIGN(4); + __StackTop = .; + PROVIDE(__stack = __StackTop); + } > RAM + + + .noinit (NOLOAD): + { + *(.noinit*); + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(SORT_BY_ALIGNMENT(.bss*)) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + text_application_ram : + { + . = ALIGN(4); + __vma_ramfuncs_start__ = .; + __text_application_ram_start__ = .; + + *(text_application_ram) + + . = ALIGN(4); + __vma_ramfuncs_end__ = .; + __text_application_ram_end__ = .; + } > RAM AT > FLASH + + .rodata : + { + __lma_ramfuncs_end__ = .; + __rodata_start__ = .; + __rodata_end__ = .; + } > FLASH + + .text : + { + linker_code_begin = .; + *(SORT_BY_ALIGNMENT(.text*)) + *(SORT_BY_ALIGNMENT(text_*)) + . = ALIGN(32); + linker_code_end = .; KEEP(*(.init)) KEEP(*(.fini)) @@ -111,16 +119,11 @@ SECTIONS *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) - - __code_classification_validator_start__ = .; - . = . + 0x20; - *(code_classification_validator) - . = ALIGN(32); - __code_classification_validator_end__ = .; + *(.rodata*) - - KEEP(*(.eh_frame*)) + *(.eh_frame*) } > FLASH + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) @@ -142,6 +145,13 @@ SECTIONS LONG (__data_start__) LONG ((__data_end__ - __data_start__) / 4) + /* Add each additional data section here */ + /* + LONG (__etext2) + LONG (__data2_start__) + LONG ((__data2_end__ - __data2_start__) / 4) + */ + __copy_table_end__ = .; } > FLASH @@ -149,19 +159,23 @@ SECTIONS { . = ALIGN(4); __zero_table_start__ = .; + /* Add each additional bss section here */ + /* + LONG (__bss2_start__) + LONG ((__bss2_end__ - __bss2_start__) / 4) + */ + __zero_table_end__ = .; - __etext = ALIGN(4); + __etext = .; } > FLASH - .data : AT (__etext) + .data : { + . = ALIGN(4); __data_start__ = .; *(vtable) - *(.data*) - . = ALIGN (4); - PROVIDE (__ram_func_section_start = .); - *(.ram) - PROVIDE (__ram_func_section_end = .); + *(SORT_BY_ALIGNMENT(.data*)) + . = ALIGN(4); . = ALIGN(4); /* preinit data */ @@ -183,87 +197,49 @@ SECTIONS KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); - KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; - } > RAM - - .bss : - { - . = ALIGN(4); - __bss_start__ = .; - *(.bss) - *(.bss.*) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - } > RAM AT > RAM - - __ramfuncs_start__ = .; - - __vma_ramfuncs_start__ = .; - __lma_ramfuncs_start__ = __etext + SIZEOF(.data); - - __text_application_ram_offset__ = . - __vma_ramfuncs_start__; - text_application_ram . : AT(__lma_ramfuncs_start__ + __text_application_ram_offset__) - { - . = ALIGN(4); - __text_application_ram_start__ = .; - *(text_application_ram) - . = ALIGN(4); - __text_application_ram_end__ = .; - } > RAM - - . = ALIGN(4); - __vma_ramfuncs_end__ = .; - __lma_ramfuncs_end__ = __lma_ramfuncs_start__ + __text_application_ram_offset__ + SIZEOF(text_application_ram); - - __ramfuncs_end__ = .; - - .heap (COPY): + } > RAM AT > FLASH + .memory_manager_heap (NOLOAD): { + . = ALIGN(8); __HeapBase = .; __end__ = .; end = __end__; _end = __end__; - KEEP(*(.heap*)) - __HeapLimit = .; + KEEP(*(.memory_manager_heap*)) + __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); } > RAM - __main_flash_end__ = ORIGIN(FLASH) + LENGTH(FLASH); + __heap_size = __HeapLimit - __HeapBase; + __ram_end__ = 0x20000000 + 0x40000; + __main_flash_end__ = 0x8006000 + 0x178000; - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy (COPY): - { - KEEP(*(.stack*)) - /* KEEP(*(.stackseal*))*/ - } > RAM + /* This is where we handle flash storage blocks. We use dummy sections for finding the configured + * block sizes and then "place" them at the end of flash when the size is known. */ + .internal_storage (DSECT) : { + KEEP(*(.internal_storage*)) + } > FLASH - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(RAM) + LENGTH(RAM); - __StackLimit = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - .nvm (DSECT) : { + .nvm (DSECT) : { KEEP(*(.simee*)) } > FLASH - /* Last page of flash is reserved for the manufacturing token space */ - linker_nvm_end = __main_flash_end__ - 8192; + __ramfuncs_start__ = __vma_ramfuncs_start__; + __ramfuncs_end__ = __vma_ramfuncs_end__; + + linker_nvm_end = __main_flash_end__; linker_nvm_begin = linker_nvm_end - SIZEOF(.nvm); - linker_nvm_size = SIZEOF(.nvm); + linker_storage_end = linker_nvm_begin; __nvm3Base = linker_nvm_begin; - __attestation_credentials_base = linker_nvm_end; - /* Check if data + heap + stack exceeds RAM limit */ - /*ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")*/ - ASSERT( (linker_nvm_begin + SIZEOF(.nvm)) <= __main_flash_end__, "NVM3 is excessing the flash size !") + linker_storage_begin = linker_storage_end - SIZEOF(.internal_storage); + ASSERT((linker_storage_begin >= (__etext + SIZEOF(.data))), "FLASH memory overflowed !") + - /* Check if FLASH usage exceeds FLASH size */ - ASSERT( LENGTH(FLASH) >= (__etext + SIZEOF(.data)), "FLASH memory overflowed !") + app_flash_end = 0x8006000 + 0x178000; + ASSERT( (linker_nvm_begin + SIZEOF(.nvm)) <= app_flash_end, "NVM3 is excessing the flash size !") } diff --git a/examples/platform/silabs/ldscripts/mgm24.ld b/examples/platform/silabs/ldscripts/mgm24.ld index a38794bbd7973d..16066c24195cec 100644 --- a/examples/platform/silabs/ldscripts/mgm24.ld +++ b/examples/platform/silabs/ldscripts/mgm24.ld @@ -1,43 +1,22 @@ -/* - * - * Copyright (c) 2021 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. - */ /***************************************************************************//** - * @file gcc_EFR32MG24.ld - * @brief GNU Linker Script for Cortex-M based device - * @version V2.2.0 - * @date 16. December 2020 - * Linker script for Silicon Labs EFR32MG24 devices + * GCC Linker script for Silicon Labs devices ******************************************************************************* * # License - * Copyright 2022 Silicon Laboratories, Inc. www.silabs.com + * Copyright 2020 Silicon Laboratories Inc. www.silabs.com ******************************************************************************* * * SPDX-License-Identifier: Zlib - * + * * The licensor of this software is Silicon Laboratories Inc. - * + * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. - * + * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: - * + * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be @@ -48,52 +27,81 @@ * ******************************************************************************/ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x08006000, LENGTH = 0x17A000 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 -} - -/* Linker script to place sections and symbol values. Should be used together - * with other linker script that defines memory regions FLASH and RAM. - * It references following symbols, which must be defined in code: - * Reset_Handler : Entry of reset handler - * - * It defines following symbols, which code can use without definition: - * __exidx_start - * __exidx_end - * __copy_table_start__ - * __copy_table_end__ - * __zero_table_start__ - * __zero_table_end__ - * __etext - * __data_start__ - * __preinit_array_start - * __preinit_array_end - * __init_array_start - * __init_array_end - * __fini_array_start - * __fini_array_end - * __data_end__ - * __bss_start__ - * __bss_end__ - * __end__ - * end - * __HeapLimit - * __StackLimit - * __StackTop - * __stack - * __StackSeal (only if ARMv8-M stack sealing is used) - */ + MEMORY + { + FLASH (rx) : ORIGIN = 0x8006000, LENGTH = 0x178000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 + } ENTRY(Reset_Handler) SECTIONS { - .text : + + .vectors : { + linker_vectors_begin = .; KEEP(*(.vectors)) - *(.text*) + linker_vectors_end = .; + + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __lma_ramfuncs_start__ = .; + } > FLASH + + .stack (NOLOAD): + { + . = ALIGN(8); + __StackLimit = .; + KEEP(*(.stack*)) + . = ALIGN(4); + __StackTop = .; + PROVIDE(__stack = __StackTop); + } > RAM + + + .noinit (NOLOAD): + { + *(.noinit*); + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(SORT_BY_ALIGNMENT(.bss*)) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + text_application_ram : + { + . = ALIGN(4); + __vma_ramfuncs_start__ = .; + __text_application_ram_start__ = .; + + *(text_application_ram) + + . = ALIGN(4); + __vma_ramfuncs_end__ = .; + __text_application_ram_end__ = .; + } > RAM AT > FLASH + + .rodata : + { + __lma_ramfuncs_end__ = .; + __rodata_start__ = .; + __rodata_end__ = .; + } > FLASH + + .text : + { + linker_code_begin = .; + *(SORT_BY_ALIGNMENT(.text*)) + *(SORT_BY_ALIGNMENT(text_*)) + . = ALIGN(32); + linker_code_end = .; KEEP(*(.init)) KEEP(*(.fini)) @@ -111,16 +119,11 @@ SECTIONS *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) - - __code_classification_validator_start__ = .; - . = . + 0x20; - *(code_classification_validator) - . = ALIGN(32); - __code_classification_validator_end__ = .; - *(.rodata*) - KEEP(*(.eh_frame*)) + *(.rodata*) + *(.eh_frame*) } > FLASH + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) @@ -142,6 +145,13 @@ SECTIONS LONG (__data_start__) LONG ((__data_end__ - __data_start__) / 4) + /* Add each additional data section here */ + /* + LONG (__etext2) + LONG (__data2_start__) + LONG ((__data2_end__ - __data2_start__) / 4) + */ + __copy_table_end__ = .; } > FLASH @@ -149,19 +159,23 @@ SECTIONS { . = ALIGN(4); __zero_table_start__ = .; + /* Add each additional bss section here */ + /* + LONG (__bss2_start__) + LONG ((__bss2_end__ - __bss2_start__) / 4) + */ + __zero_table_end__ = .; - __etext = ALIGN(4); + __etext = .; } > FLASH - .data : AT (__etext) + .data : { + . = ALIGN(4); __data_start__ = .; *(vtable) - *(.data*) - . = ALIGN (4); - PROVIDE (__ram_func_section_start = .); - *(.ram) - PROVIDE (__ram_func_section_end = .); + *(SORT_BY_ALIGNMENT(.data*)) + . = ALIGN(4); . = ALIGN(4); /* preinit data */ @@ -183,87 +197,49 @@ SECTIONS KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); - KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; - } > RAM - - .bss : - { - . = ALIGN(4); - __bss_start__ = .; - *(.bss) - *(.bss.*) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - } > RAM AT > RAM - - __ramfuncs_start__ = .; - - __vma_ramfuncs_start__ = .; - __lma_ramfuncs_start__ = __etext + SIZEOF(.data); - - __text_application_ram_offset__ = . - __vma_ramfuncs_start__; - text_application_ram . : AT(__lma_ramfuncs_start__ + __text_application_ram_offset__) - { - . = ALIGN(4); - __text_application_ram_start__ = .; - *(text_application_ram) - . = ALIGN(4); - __text_application_ram_end__ = .; - } > RAM - - . = ALIGN(4); - __vma_ramfuncs_end__ = .; - __lma_ramfuncs_end__ = __lma_ramfuncs_start__ + __text_application_ram_offset__ + SIZEOF(text_application_ram); - - __ramfuncs_end__ = .; - - .heap (COPY): + } > RAM AT > FLASH + .memory_manager_heap (NOLOAD): { + . = ALIGN(8); __HeapBase = .; __end__ = .; end = __end__; _end = __end__; - KEEP(*(.heap*)) - __HeapLimit = .; + KEEP(*(.memory_manager_heap*)) + __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); } > RAM - __main_flash_end__ = ORIGIN(FLASH) + LENGTH(FLASH); + __heap_size = __HeapLimit - __HeapBase; + __ram_end__ = 0x20000000 + 0x40000; + __main_flash_end__ = 0x8006000 + 0x178000; - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy (COPY): - { - KEEP(*(.stack*)) - /* KEEP(*(.stackseal*))*/ - } > RAM + /* This is where we handle flash storage blocks. We use dummy sections for finding the configured + * block sizes and then "place" them at the end of flash when the size is known. */ + .internal_storage (DSECT) : { + KEEP(*(.internal_storage*)) + } > FLASH - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(RAM) + LENGTH(RAM); - __StackLimit = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - .nvm (DSECT) : { + .nvm (DSECT) : { KEEP(*(.simee*)) } > FLASH - /* Last page of flash is reserved for the manufacturing token space */ - linker_nvm_end = __main_flash_end__ - 8192; + __ramfuncs_start__ = __vma_ramfuncs_start__; + __ramfuncs_end__ = __vma_ramfuncs_end__; + + linker_nvm_end = __main_flash_end__; linker_nvm_begin = linker_nvm_end - SIZEOF(.nvm); - linker_nvm_size = SIZEOF(.nvm); + linker_storage_end = linker_nvm_begin; __nvm3Base = linker_nvm_begin; - __attestation_credentials_base = linker_nvm_end; - /* Check if data + heap + stack exceeds RAM limit */ - /*ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")*/ - ASSERT( (linker_nvm_begin + SIZEOF(.nvm)) <= __main_flash_end__, "NVM3 is excessing the flash size !") + linker_storage_begin = linker_storage_end - SIZEOF(.internal_storage); + ASSERT((linker_storage_begin >= (__etext + SIZEOF(.data))), "FLASH memory overflowed !") + - /* Check if FLASH usage exceeds FLASH size */ - ASSERT( LENGTH(FLASH) >= (__etext + SIZEOF(.data)), "FLASH memory overflowed !") + app_flash_end = 0x8006000 + 0x178000; + ASSERT( (linker_nvm_begin + SIZEOF(.nvm)) <= app_flash_end, "NVM3 is excessing the flash size !") } diff --git a/examples/platform/silabs/matter-platform.slcp b/examples/platform/silabs/matter-platform.slcp index 4f5d1ef2c05064..c8075656e9f74d 100644 --- a/examples/platform/silabs/matter-platform.slcp +++ b/examples/platform/silabs/matter-platform.slcp @@ -27,7 +27,7 @@ include: file_list: - {path: app.h} - {path: reset_util.h} -sdk: {id: gecko_sdk, version: 4.4.2} +sdk: {id: simplicity_sdk, version: 2024.6.0} toolchain_settings: [] component: @@ -38,13 +38,26 @@ component: - {id: bluetooth_feature_connection} - {id: bluetooth_feature_system} - {id: bluetooth_stack} -# Other components +# Platform support +- {id: cpp_support} +- {id: sl_system} +- {id: device_init} +- {id: board_control} +- {id: memory_manager} +- {id: silabs_core_memory_manager} +- {id: clock_manager} +- {id: silabs_core_circular_queue} +- {id: sleeptimer} - {id: nvm3_lib} - {id: freertos} +- {id: freertos_heap_3} +- {id: iostream_rtt} +- {id: toolchain_gcc} - {id: brd4002a} - {id: rail_util_pti} - {id: rail_lib_multiprotocol} - {id: rail_util_power_manager_init} +# crypto components - {id: psa_crypto} - {id: psa_crypto_aes} - {id: psa_crypto_ccm} @@ -59,7 +72,6 @@ component: - {id: mbedtls_platform_dynamic_memory_allocation_config_init_runtime } - {id: mbedtls_base64} - {id: ot_psa_crypto} -- {id: iostream_rtt} # Necessary componenets for ot coap cert lib # - {id: mbedtls_dtls} # Requried by COAP lib # - {id: mbedtls_tls_server} # Requried by COAP lib @@ -86,9 +98,15 @@ configuration: name: SL_IOSTREAM_USART_VCOM_RX_BUFFER_SIZE value: '128' - {name: SL_HEAP_SIZE, value: '0'} -- {name: SL_STACK_SIZE, value: '0'} +- {name: SL_STACK_SIZE, value: '4608'} - {name: SL_BOARD_ENABLE_VCOM, value: '0'} - {name: EMDRV_UARTDRV_FLOW_CONTROL_ENABLE, value: '0'} +- {name: NVM3_DEFAULT_MAX_OBJECT_SIZE, value: '4092'} +- {name: CIRCULAR_QUEUE_LEN_MAX, value: '16'} +- {name: SL_CLOCK_MANAGER_HFRCO_DPLL_EN, value: 1} +- {name: SL_BT_RTOS_LINK_LAYER_TASK_STACK_SIZE, value: 1024} +- {name: SL_BT_RTOS_HOST_STACK_TASK_STACK_SIZE, value: 2048} +- {name: SL_BT_RTOS_EVENT_HANDLER_STACK_SIZE, value: 1536} template_contribution: - name: mbedtls_ssl_content_len_in_requirement @@ -97,8 +115,6 @@ template_contribution: value: 900 requires: -- condition: [device_series_1] - name: uartdrv_usart - condition: [device_series_2] name: uartdrv_eusart - condition: [device_series_2] diff --git a/src/platform/silabs/CHIPMem-Platform.cpp b/src/platform/silabs/CHIPMem-Platform.cpp index 20859100f129c4..cf6552dd64b43b 100644 --- a/src/platform/silabs/CHIPMem-Platform.cpp +++ b/src/platform/silabs/CHIPMem-Platform.cpp @@ -44,9 +44,6 @@ // #include #include -#include "heap_4_silabs.h" -#include "task.h" - #include #include #include @@ -104,7 +101,7 @@ void * MemoryAlloc(size_t size) { void * ptr; VERIFY_INITIALIZED(); - ptr = pvPortMalloc(size); + ptr = malloc(size); trackAlloc(ptr, size); return ptr; } @@ -113,7 +110,7 @@ void * MemoryAlloc(size_t size, bool isLongTermAlloc) { void * ptr; VERIFY_INITIALIZED(); - ptr = pvPortMalloc(size); + ptr = malloc(size); trackAlloc(ptr, size); return ptr; } @@ -122,7 +119,7 @@ void * MemoryCalloc(size_t num, size_t size) { VERIFY_INITIALIZED(); - void * ptr = pvPortCalloc(num, size); + void * ptr = calloc(num, size); trackAlloc(ptr, size * num); return ptr; } @@ -131,7 +128,7 @@ void * MemoryRealloc(void * p, size_t size) { VERIFY_INITIALIZED(); - p = pvPortRealloc(p, size); + p = realloc(p, size); return p; } @@ -139,7 +136,7 @@ void MemoryFree(void * p) { VERIFY_INITIALIZED(); trackFree(p, 0); - vPortFree(p); + free(p); } bool MemoryInternalCheckPointer(const void * p, size_t min_size) @@ -150,12 +147,7 @@ bool MemoryInternalCheckPointer(const void * p, size_t min_size) } // namespace Platform } // namespace chip -#ifdef BRD4325A -extern "C" void memMonitoringTrackAlloc(void * ptr, size_t size) {} -extern "C" void memMonitoringTrackFree(void * ptr, size_t size) {} -#else -extern "C" __WEAK void memMonitoringTrackAlloc(void * ptr, size_t size) {} -extern "C" __WEAK void memMonitoringTrackFree(void * ptr, size_t size) {} -#endif // BRD4325A +extern "C" __attribute__((weak)) void memMonitoringTrackAlloc(void * ptr, size_t size) {} +extern "C" __attribute__((weak)) void memMonitoringTrackFree(void * ptr, size_t size) {} #endif // CHIP_CONFIG_MEMORY_MGMT_PLATFORM diff --git a/src/platform/silabs/DiagnosticDataProviderImpl.cpp b/src/platform/silabs/DiagnosticDataProviderImpl.cpp index 1dc408394f7a71..4be7113bb67b5b 100644 --- a/src/platform/silabs/DiagnosticDataProviderImpl.cpp +++ b/src/platform/silabs/DiagnosticDataProviderImpl.cpp @@ -29,7 +29,7 @@ #include #endif #include "FreeRTOS.h" -#include "heap_4_silabs.h" +#include "sl_memory_manager.h" #include #include @@ -46,38 +46,28 @@ DiagnosticDataProviderImpl & DiagnosticDataProviderImpl::GetDefaultInstance() // Software Diagnostics Getters /* - * The following Heap stats are compiled values done by the FreeRTOS Heap4 implementation. - * See /examples/platform/silabs/heap_4_silabs.c + * The following Heap stats are compiled values done by the sl_memory_manager. * It keeps track of the number of calls to allocate and free memory as well as the * number of free bytes remaining, but says nothing about fragmentation. */ CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapFree(uint64_t & currentHeapFree) { - size_t freeHeapSize = xPortGetFreeHeapSize(); + size_t freeHeapSize = sl_memory_get_free_heap_size(); currentHeapFree = static_cast(freeHeapSize); return CHIP_NO_ERROR; } CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapUsed(uint64_t & currentHeapUsed) { - // Calculate the Heap used based on Total heap - Free heap - int64_t heapUsed = (configTOTAL_HEAP_SIZE - xPortGetFreeHeapSize()); - - // Something went wrong, this should not happen - VerifyOrReturnError(heapUsed >= 0, CHIP_ERROR_INVALID_INTEGER_VALUE); + size_t heapUsed = sl_memory_get_used_heap_size(); currentHeapUsed = static_cast(heapUsed); return CHIP_NO_ERROR; } CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) { - // FreeRTOS records the lowest amount of available heap during runtime - // currentHeapHighWatermark wants the highest heap usage point so we calculate it here - int64_t HighestHeapUsageRecorded = (configTOTAL_HEAP_SIZE - xPortGetMinimumEverFreeHeapSize()); - - // Something went wrong, this should not happen - VerifyOrReturnError(HighestHeapUsageRecorded >= 0, CHIP_ERROR_INVALID_INTEGER_VALUE); - currentHeapHighWatermark = static_cast(HighestHeapUsageRecorded); + size_t HighestHeapUsageRecorded = sl_memory_get_heap_high_watermark(); + currentHeapHighWatermark = static_cast(HighestHeapUsageRecorded); return CHIP_NO_ERROR; } @@ -86,9 +76,7 @@ CHIP_ERROR DiagnosticDataProviderImpl::ResetWatermarks() { // If implemented, the server SHALL set the value of the CurrentHeapHighWatermark attribute to the // value of the CurrentHeapUsed. - - xPortResetHeapMinimumEverFreeHeapSize(); - + sl_memory_reset_heap_high_watermark(); return CHIP_NO_ERROR; } diff --git a/src/platform/silabs/SiWx917/wifi/ethernetif.cpp b/src/platform/silabs/SiWx917/wifi/ethernetif.cpp index 8570fc4b9a4fb3..72725102d6da48 100644 --- a/src/platform/silabs/SiWx917/wifi/ethernetif.cpp +++ b/src/platform/silabs/SiWx917/wifi/ethernetif.cpp @@ -32,6 +32,7 @@ extern "C" { #include "sl_si91x_driver.h" #include "sl_si91x_host_interface.h" #include "sl_si91x_types.h" +#include "sl_wifi.h" #include "sl_wifi_callback_framework.h" #include "sl_wifi_constants.h" #include "sl_wifi_types.h" @@ -45,8 +46,6 @@ extern "C" { #include "netif/etharp.h" #include "silabs_utils.h" -#include - StaticSemaphore_t xEthernetIfSemaBuffer; /***************************************************************************** @@ -132,14 +131,13 @@ static void low_level_input(struct netif * netif, uint8_t * b, uint16_t len) (memcmp(netif->hwaddr, dst_mac, netif->hwaddr_len) != 0)) { #ifdef WIFI_DEBUG_ENABLED - ChipLogProgress(DeviceLayer, "%s: DROP, [%02x:%02x:%02x:%02x:%02x:%02x]<-[%02x:%02x:%02x:%02x:%02x:%02x] type=%02x%02x", - __func__, + SILABS_LOG("%s: DROP, [%02x:%02x:%02x:%02x:%02x:%02x]<-[%02x:%02x:%02x:%02x:%02x:%02x] type=%02x%02x", __func__, - dst_mac[0], dst_mac[1], dst_mac[2], dst_mac[3], dst_mac[4], dst_mac[5], + dst_mac[0], dst_mac[1], dst_mac[2], dst_mac[3], dst_mac[4], dst_mac[5], - src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5], + src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5], - b[12], b[13]); + b[12], b[13]); #endif return; } @@ -155,15 +153,14 @@ static void low_level_input(struct netif * netif, uint8_t * b, uint16_t len) bufferoffset += q->len; } #ifdef WIFI_DEBUG_ENABLED - ChipLogProgress(DeviceLayer, - "%s: ACCEPT %d, [%02x:%02x:%02x:%02x:%02x:%02x]<-[%02x:%02x:%02x:%02x:%02x:%02x] type=%02x%02x", __func__, - bufferoffset, + SILABS_LOG("%s: ACCEPT %d, [%02x:%02x:%02x:%02x:%02x:%02x]<-[%02x:%02x:%02x:%02x:%02x:%02x] type=%02x%02x", __func__, + bufferoffset, - dst_mac[0], dst_mac[1], dst_mac[2], dst_mac[3], dst_mac[4], dst_mac[5], + dst_mac[0], dst_mac[1], dst_mac[2], dst_mac[3], dst_mac[4], dst_mac[5], - src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5], + src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5], - b[12], b[13]); + b[12], b[13]); #endif if (netif->input(p, netif) != ERR_OK) @@ -194,84 +191,13 @@ static SemaphoreHandle_t ethout_sem; ******************************************************************************/ static err_t low_level_output(struct netif * netif, struct pbuf * p) { - sl_wifi_buffer_t * buffer; - sl_si91x_packet_t * packet; - sl_status_t status = SL_STATUS_OK; - void * rsipkt; - struct pbuf * q; - uint16_t framelength = 0; - uint16_t datalength = 0; - -#ifdef WIFI_DEBUG_ENABLED - ChipLogProgress(DeviceLayer, "LWIP : low_level_output"); -#endif - if (xSemaphoreTake(ethout_sem, portMAX_DELAY) != pdTRUE) - { - return ERR_IF; - } - /* Calculate total packet size */ - for (q = p, framelength = 0; q != NULL; q = q->next) - { - framelength += q->len; - } - if (framelength < LWIP_FRAME_ALIGNMENT) - { - framelength = LWIP_FRAME_ALIGNMENT; - } - - /* Confirm if packet is allocated */ - status = sl_si91x_allocate_command_buffer(&buffer, (void **) &packet, sizeof(sl_si91x_packet_t) + framelength, - SL_WIFI_ALLOCATE_COMMAND_BUFFER_WAIT_TIME_MS); - VERIFY_STATUS_AND_RETURN(status); - if (packet == NULL) - { - ChipLogProgress(DeviceLayer, "EN-RSI:No buf"); - xSemaphoreGive(ethout_sem); - return SL_STATUS_ALLOCATION_FAILED; - } - memset(packet->desc, 0, sizeof(packet->desc)); -#ifdef WIFI_DEBUG_ENABLED - ChipLogProgress(DeviceLayer, "EN-RSI: Output"); -#endif - if ((netif->flags & (NETIF_FLAG_LINK_UP | NETIF_FLAG_UP)) != (NETIF_FLAG_LINK_UP | NETIF_FLAG_UP)) + UNUSED_PARAMETER(netif); + sl_status_t status; + status = sl_wifi_send_raw_data_frame(SL_WIFI_CLIENT_INTERFACE, (uint8_t *) p->payload, p->len); + if (status != SL_STATUS_OK) { - ChipLogProgress(DeviceLayer, "EN-RSI:NOT UP"); - xSemaphoreGive(ethout_sem); return ERR_IF; } -#ifdef WIFI_DEBUG_ENABLED - uint8_t * b = (uint8_t *) p->payload; - ChipLogProgress(DeviceLayer, "EN-RSI: Out [%02x:%02x:%02x:%02x:%02x:%02x][%02x:%02x:%02x:%02x:%02x:%02x]type=%02x%02x", b[0], - b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13]); -#endif - /* Generate the packet */ - for (q = p, datalength = 0; q != NULL; q = q->next) - { - wfx_rsi_pkt_add_data(packet, (uint8_t *) (q->payload), (uint16_t) q->len, datalength); - datalength += q->len; - } - if (datalength < LWIP_FRAME_ALIGNMENT) - { - /* Add junk data to the end for frame alignment if framelength is less than 60 */ - wfx_rsi_pkt_add_data(packet, (uint8_t *) (p->payload), LWIP_FRAME_ALIGNMENT - datalength, datalength); - } -#ifdef WIFI_DEBUG_ENABLED - ChipLogProgress(DeviceLayer, "EN-RSI: Sending %d", framelength); -#endif - packet->length = framelength & 0xFFF; - packet->command = RSI_SEND_RAW_DATA; - if (sl_si91x_driver_send_data_packet(SI91X_WLAN_CMD_QUEUE, buffer, 1000)) - { - ChipLogProgress(DeviceLayer, "*ERR*EN-RSI:Send fail"); - xSemaphoreGive(ethout_sem); - return ERR_IF; - } - /* - * forward the generated packet to RSI to - * send the data over wifi network - */ - xSemaphoreGive(ethout_sem); - return ERR_OK; } diff --git a/src/platform/silabs/SiWx917/wifi/wfx_host_events.h b/src/platform/silabs/SiWx917/wifi/wfx_host_events.h index 526e22c751a69f..e3f923894c24e6 100644 --- a/src/platform/silabs/SiWx917/wifi/wfx_host_events.h +++ b/src/platform/silabs/SiWx917/wifi/wfx_host_events.h @@ -246,19 +246,12 @@ void wfx_ip_changed_notify(int got_ip); #endif /* CHIP_DEVICE_CONFIG_ENABLE_IPV4 */ #if SL_ICD_ENABLED +uint32_t sl_app_sleep_ready(); sl_status_t wfx_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state); void sl_button_on_change(uint8_t btn, uint8_t btnAction); #endif /* SL_ICD_ENABLED */ void wfx_ipv6_notify(int got_ip); - -/* RSI for LWIP */ -void wfx_rsi_pkt_add_data(void * p, uint8_t * buf, uint16_t len, uint16_t off); -int32_t wfx_rsi_send_data(void * p, uint16_t len); -sl_status_t sl_si91x_driver_send_data_packet(sl_si91x_queue_type_t queue_type, sl_wifi_buffer_t * buffer, uint32_t wait_time); -sl_status_t sl_si91x_allocate_command_buffer(sl_wifi_buffer_t ** host_buffer, void ** buffer, uint32_t requested_buffer_size, - uint32_t wait_duration_ms); - void wfx_retry_interval_handler(bool is_wifi_disconnection_event, uint16_t retryJoin); #ifdef __cplusplus diff --git a/src/platform/silabs/efr32/args.gni b/src/platform/silabs/efr32/args.gni index ad124dec8e63c0..394e4bb1bd806a 100644 --- a/src/platform/silabs/efr32/args.gni +++ b/src/platform/silabs/efr32/args.gni @@ -48,7 +48,7 @@ chip_build_tests = false chip_use_transitional_commissionable_data_provider = false openthread_root = - "${chip_root}/third_party/silabs/gecko_sdk/util/third_party/openthread" + "${chip_root}/third_party/silabs/simplicity_sdk/util/third_party/openthread" openthread_core_config_platform_check_file = "openthread-core-efr32-config-check.h" diff --git a/src/platform/silabs/efr32/wifi/ethernetif.cpp b/src/platform/silabs/efr32/wifi/ethernetif.cpp index d07c14f61e2287..0388337939a3e2 100644 --- a/src/platform/silabs/efr32/wifi/ethernetif.cpp +++ b/src/platform/silabs/efr32/wifi/ethernetif.cpp @@ -40,6 +40,7 @@ extern "C" { #include "sl_si91x_driver.h" #include "sl_si91x_host_interface.h" #include "sl_si91x_types.h" +#include "sl_wifi.h" #include "sl_wifi_callback_framework.h" #include "sl_wifi_constants.h" #include "sl_wifi_types.h" @@ -347,12 +348,16 @@ static SemaphoreHandle_t ethout_sem; static err_t low_level_output(struct netif * netif, struct pbuf * p) { #if (SLI_SI91X_MCU_INTERFACE | EXP_BOARD) - sl_wifi_buffer_t * buffer; - sl_si91x_packet_t * packet; - sl_status_t status = SL_STATUS_OK; + UNUSED_PARAMETER(netif); + sl_status_t status; + status = sl_wifi_send_raw_data_frame(SL_WIFI_CLIENT_INTERFACE, (uint8_t *) p->payload, p->len); + if (status != SL_STATUS_OK) + { + return ERR_IF; + } + return ERR_OK; #else void * packet; -#endif struct pbuf * q; uint16_t framelength = 0; uint16_t datalength = 0; @@ -381,27 +386,14 @@ static err_t low_level_output(struct netif * netif, struct pbuf * p) xSemaphoreGive(ethout_sem); return ERR_IF; } - /* Confirm if packet is allocated */ -#if (SLI_SI91X_MCU_INTERFACE | EXP_BOARD) - status = sl_si91x_allocate_command_buffer(&buffer, (void **) &packet, sizeof(sl_si91x_packet_t) + framelength, - SL_WIFI_ALLOCATE_COMMAND_BUFFER_WAIT_TIME_MS); - VERIFY_STATUS_AND_RETURN(status); - if (packet == NULL) -#else // RS9116 packet = wfx_rsi_alloc_pkt(); if (!packet) -#endif // SLI_SI91X_MCU_INTERFACE { ChipLogProgress(DeviceLayer, "EN-RSI:No buf"); xSemaphoreGive(ethout_sem); -#if (SLI_SI91X_MCU_INTERFACE | EXP_BOARD) - return SL_STATUS_ALLOCATION_FAILED; - } - memset(packet->desc, 0, sizeof(packet->desc)); -#else // RS9116 return ERR_IF; } -#endif // SLI_SI91X_MCU_INTERFACE + #ifdef WIFI_DEBUG_ENABLED uint8_t * b = (uint8_t *) p->payload; ChipLogProgress(DeviceLayer, "EN-RSI: Out [%02x:%02x:%02x:%02x:%02x:%02x][%02x:%02x:%02x:%02x:%02x:%02x]type=%02x%02x", b[0], @@ -422,19 +414,10 @@ static err_t low_level_output(struct netif * netif, struct pbuf * p) ChipLogProgress(DeviceLayer, "EN-RSI: Sending %d", framelength); #endif - /* forward the generated packet to RSI to - * send the data over wifi network - */ -#if (SLI_SI91X_MCU_INTERFACE | EXP_BOARD) - packet->length = framelength & 0xFFF; - packet->command = RSI_SEND_RAW_DATA; - if (sl_si91x_driver_send_data_packet(SI91X_WLAN_CMD_QUEUE, buffer, 1000)) -#else /* forward the generated packet to RSI to * send the data over wifi network */ if (wfx_rsi_send_data(packet, datalength)) -#endif { ChipLogProgress(DeviceLayer, "*ERR*EN-RSI:Send fail"); xSemaphoreGive(ethout_sem); @@ -447,6 +430,7 @@ static err_t low_level_output(struct netif * netif, struct pbuf * p) xSemaphoreGive(ethout_sem); return ERR_OK; +#endif // RS9116 } #if (SLI_SI91X_MCU_INTERFACE | EXP_BOARD) diff --git a/src/platform/silabs/efr32/wifi/wfx_host_events.h b/src/platform/silabs/efr32/wifi/wfx_host_events.h index b7a7c936b8d6de..a7a2dc2ac34fa4 100644 --- a/src/platform/silabs/efr32/wifi/wfx_host_events.h +++ b/src/platform/silabs/efr32/wifi/wfx_host_events.h @@ -386,12 +386,6 @@ void sl_wfx_host_gpio_init(void); sl_status_t sl_wfx_host_process_event(sl_wfx_generic_message_t * event_payload); #endif -#if (SLI_SI91X_MCU_INTERFACE | EXP_BOARD) -void wfx_retry_interval_handler(bool is_wifi_disconnection_event, uint16_t retryJoin); -sl_status_t sl_si91x_driver_send_data_packet(sl_si91x_queue_type_t queue_type, sl_wifi_buffer_t * buffer, uint32_t wait_time); -sl_status_t sl_si91x_allocate_command_buffer(sl_wifi_buffer_t ** host_buffer, void ** buffer, uint32_t requested_buffer_size, - uint32_t wait_duration_ms); -#endif void wfx_retry_interval_handler(bool is_wifi_disconnection_event, uint16_t retryJoin); #ifdef __cplusplus diff --git a/src/test_driver/efr32/BUILD.gn b/src/test_driver/efr32/BUILD.gn index 76b4df8e8bc8ec..ad0c1a22d270d3 100644 --- a/src/test_driver/efr32/BUILD.gn +++ b/src/test_driver/efr32/BUILD.gn @@ -70,7 +70,6 @@ silabs_executable("efr32_device_tests") { "${chip_root}/examples/common/pigweed/RpcService.cpp", "${chip_root}/examples/common/pigweed/efr32/PigweedLoggerMutex.cpp", "${examples_common_plat_dir}/PigweedLogger.cpp", - "${examples_common_plat_dir}/heap_4_silabs.c", "${examples_common_plat_dir}/syscalls_stubs.cpp", "${examples_plat_dir}/uart.cpp", "src/main.cpp", diff --git a/third_party/openthread/platforms/efr32/BUILD.gn b/third_party/openthread/platforms/efr32/BUILD.gn index f8f2dd4ac6f072..381c6407f2c7cd 100644 --- a/third_party/openthread/platforms/efr32/BUILD.gn +++ b/third_party/openthread/platforms/efr32/BUILD.gn @@ -29,10 +29,14 @@ config("openthread_efr32_config") { ] include_dirs = [ + "${sl_ot_efr32_root}", "${chip_root}/examples/platform/efr32", "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}", - "${sl_ot_efr32_root}", "${sl_ot_platform_abstraction}/include", + "${sl_ot_platform_abstraction}/rtos", + + #TODO this is for sl_openthread_features_config.h. should use generated one per board when sl_ot_abstraction is integrated + "${sl_ot_libs_path}/config", ] # temporarily disable check until gsdk pulls in a more recent version of openthread @@ -54,6 +58,9 @@ source_set("openthread_core_config_efr32") { source_set("libopenthread-efr32") { sources = [ "${openthread_root}/examples/apps/cli/cli_uart.cpp", + "${openthread_root}/examples/platforms/utils/link_metrics.cpp", + "${openthread_root}/examples/platforms/utils/mac_frame.cpp", + "${openthread_root}/examples/platforms/utils/settings_ram.c", "${sl_ot_efr32_root}/alarm.c", "${sl_ot_efr32_root}/crypto.c", "${sl_ot_efr32_root}/entropy.c", @@ -61,11 +68,17 @@ source_set("libopenthread-efr32") { "${sl_ot_efr32_root}/ieee802154-packet-utils.cpp", "${sl_ot_efr32_root}/misc.c", "${sl_ot_efr32_root}/radio.c", + "${sl_ot_efr32_root}/radio_coex.c", + "${sl_ot_efr32_root}/radio_extension.c", + "${sl_ot_efr32_root}/radio_power_manager.c", + "${sl_ot_efr32_root}/sl_gp_interface.c", "${sl_ot_efr32_root}/sleep.c", "${sl_ot_efr32_root}/soft_source_match_table.c", "${sl_ot_efr32_root}/system.c", ] + include_dirs = [ "${openthread_root}/examples/platforms/utils" ] + public_deps = [ ":openthread_core_config_efr32", "${openthread_root}/src/core:libopenthread_core_headers", diff --git a/third_party/silabs/BUILD.gn b/third_party/silabs/BUILD.gn index 2326a73ab09121..915cf8ba2bf164 100644 --- a/third_party/silabs/BUILD.gn +++ b/third_party/silabs/BUILD.gn @@ -66,8 +66,6 @@ if (wifi_soc != true) { # CCP board if (use_silabs_thread_lib) { config("libopenthread-platform_config") { include_dirs = [ "${openthread_root}/examples/platforms" ] - - defines = [ "SL_CONFIG_OPENTHREAD_LIB=1" ] } copy("copy_openthread_system") { @@ -126,8 +124,13 @@ if (wifi_soc != true) { # CCP board } source_set("ot-efr32-cert") { + sources = [ + "${openthread_root}/examples/platforms/utils/mac_frame.cpp", + "${openthread_root}/examples/platforms/utils/mac_frame.h", + ] + if (enable_openthread_cli) { - sources = [ + sources += [ "${openthread_root}/examples/apps/cli/cli_uart.cpp", "${openthread_root}/src/cli/cli.cpp", "${openthread_root}/src/cli/cli.hpp", @@ -150,12 +153,16 @@ if (wifi_soc != true) { # CCP board "${openthread_root}/src/cli/cli_history.hpp", "${openthread_root}/src/cli/cli_joiner.cpp", "${openthread_root}/src/cli/cli_joiner.hpp", + "${openthread_root}/src/cli/cli_link_metrics.cpp", + "${openthread_root}/src/cli/cli_link_metrics.hpp", "${openthread_root}/src/cli/cli_mac_filter.cpp", "${openthread_root}/src/cli/cli_mac_filter.hpp", + "${openthread_root}/src/cli/cli_mdns.cpp", + "${openthread_root}/src/cli/cli_mdns.hpp", "${openthread_root}/src/cli/cli_network_data.cpp", "${openthread_root}/src/cli/cli_network_data.hpp", - "${openthread_root}/src/cli/cli_output.cpp", - "${openthread_root}/src/cli/cli_output.hpp", + "${openthread_root}/src/cli/cli_ping.cpp", + "${openthread_root}/src/cli/cli_ping.hpp", "${openthread_root}/src/cli/cli_srp_client.cpp", "${openthread_root}/src/cli/cli_srp_client.hpp", "${openthread_root}/src/cli/cli_srp_server.cpp", @@ -164,6 +171,8 @@ if (wifi_soc != true) { # CCP board "${openthread_root}/src/cli/cli_tcp.hpp", "${openthread_root}/src/cli/cli_udp.cpp", "${openthread_root}/src/cli/cli_udp.hpp", + "${openthread_root}/src/cli/cli_utils.cpp", + "${openthread_root}/src/cli/cli_utils.hpp", "${openthread_root}/src/cli/x509_cert_key.hpp", ] } @@ -187,6 +196,20 @@ if (wifi_soc != true) { # CCP board XTD = "ftd" if (!chip_openthread_ftd) { XTD = "mtd" + } else { + # additional files needed for ftd lib + sources += [ + "${openthread_root}/examples/platforms/utils/link_metrics.cpp", + "${openthread_root}/examples/platforms/utils/link_metrics.h", + "${openthread_root}/src/core/api/link_api.cpp", + "${openthread_root}/src/core/mac/mac.cpp", + "${openthread_root}/src/core/mac/mac_frame.cpp", + "${openthread_root}/src/core/mac/sub_mac.cpp", + "${openthread_root}/src/core/thread/mle.cpp", + "${sl_ot_platform_abstraction}/efr32/radio.c", + ] + + include_dirs = [ "${sl_ot_platform_abstraction}/include" ] } # Use silabs openthread library stack with or without coap api enabled @@ -197,6 +220,11 @@ if (wifi_soc != true) { # CCP board public_configs += [ "${openthread_root}:openthread_${XTD}_config" ] + if (silabs_family == "mgm24") { + # Locally set silabs_family to efr32mg24 as mgm24 doesn't have dedicated sl_ot_platform libs + silabs_family = "efr32mg24" + } + libs = [ "${sl_ot_libs_path}/libs/libsl_ot_stack_${XTD}_${COAP_API}${silabs_family}_gcc.a", "${sl_ot_libs_path}/libs/libsl_platform_${XTD}_dmp_${silabs_family}_gcc.a", diff --git a/third_party/silabs/SiWx917_sdk.gni b/third_party/silabs/SiWx917_sdk.gni index 59ab00534af208..2862f9bc9d09f6 100644 --- a/third_party/silabs/SiWx917_sdk.gni +++ b/third_party/silabs/SiWx917_sdk.gni @@ -141,6 +141,13 @@ template("siwx917_sdk") { "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/led/config", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/core/config", + # sl memory manager + "${efr32_sdk_root}/platform/service/memory_manager/inc", + "${efr32_sdk_root}/platform/service/memory_manager/src", + "${efr32_sdk_root}/platform/service/memory_manager/profiler/inc", + "${efr32_sdk_root}/platform/service/memory_manager/profiler/config", + "${efr32_sdk_root}/util/silicon_labs/silabs_core/memory_manager", + # OTA "${wifi_sdk_root}/components/device/silabs/si91x/wireless/firmware_upgrade", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/hal/inc", @@ -225,6 +232,7 @@ template("siwx917_sdk") { "RADIO_CONFIG_DMP_SUPPORT=1", "configUSE_POSIX_ERRNO=1", "NVM3_LOCK_OVERRIDE=1", + "SL_MEMORY_POOL_LIGHT=1", ] if (silabs_log_enabled && chip_logging) { @@ -373,6 +381,7 @@ template("siwx917_sdk") { # si91x component "${efr32_sdk_root}/platform/CMSIS/RTOS2/Source/os_systick.c", "${efr32_sdk_root}/platform/common/src/sl_assert.c", + "${efr32_sdk_root}/platform/common/src/sl_core_cortexm.c", "${efr32_sdk_root}/platform/common/src/sl_slist.c", "${efr32_sdk_root}/platform/common/src/sli_cmsis_os2_ext_task_register.c", "${efr32_sdk_root}/util/third_party/freertos/cmsis/Source/cmsis_os2.c", @@ -410,7 +419,10 @@ template("siwx917_sdk") { "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/cmsis_driver/UDMA.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/cmsis_driver/USART.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/clock_update.c", + "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_crc.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_egpio.c", + "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_spi.c", + "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_timers.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_udma.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_udma_wrapper.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_usart.c", @@ -446,10 +458,12 @@ template("siwx917_sdk") { "${efr32_sdk_root}/platform/emlib/src/em_core.c", "${efr32_sdk_root}/platform/service/device_init/src/sl_device_init_nvic.c", "${efr32_sdk_root}/platform/service/system/src/sl_system_init.c", + "${efr32_sdk_root}/platform/service/system/src/sl_system_kernel.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/croutine.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/event_groups.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/list.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/portable/GCC/ARM_CM4F/port.c", + "${efr32_sdk_root}/util/third_party/freertos/kernel/portable/MemMang/heap_3.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/queue.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/stream_buffer.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/tasks.c", @@ -457,11 +471,22 @@ template("siwx917_sdk") { "${sdk_support_root}/matter/si91x/siwx917/BRD4338A/autogen/sl_event_handler.c", "${sdk_support_root}/matter/si91x/siwx917/BRD4338A/autogen/sl_si91x_button_instances.c", "${sdk_support_root}/matter/si91x/siwx917/BRD4338A/autogen/sl_si91x_led_instances.c", + "${sdk_support_root}/matter/si91x/siwx917/BRD4338A/autogen/sl_ulp_timer_init.c", "${sdk_support_root}/matter/si91x/siwx917/BRD4338A/support/hal/rsi_hal_mcu_m4.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/button/src/sl_si91x_button.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/led/src/sl_si91x_led.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/service/nvm3/src/sl_si91x_nvm3_hal_flash.c", + # sl memory manager + "${efr32_sdk_root}/platform/service/memory_manager/profiler/src/sli_memory_profiler_stubs.c", + "${efr32_sdk_root}/platform/service/memory_manager/src/sl_memory_manager.c", + "${efr32_sdk_root}/platform/service/memory_manager/src/sl_memory_manager_cpp.cpp", + "${efr32_sdk_root}/platform/service/memory_manager/src/sl_memory_manager_dynamic_reservation.c", + "${efr32_sdk_root}/platform/service/memory_manager/src/sl_memory_manager_pool.c", + "${efr32_sdk_root}/platform/service/memory_manager/src/sl_memory_manager_region.c", + "${efr32_sdk_root}/platform/service/memory_manager/src/sl_memory_manager_retarget.c", + "${efr32_sdk_root}/platform/service/memory_manager/src/sli_memory_manager_common.c", + # mbedtls "${chip_root}/third_party/mbedtls/repo/library/aes.c", "${chip_root}/third_party/mbedtls/repo/library/asn1parse.c", diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index a563f8eb4a9731..8ef09c80f3f214 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -23,7 +23,7 @@ import("silabs_board.gni") declare_args() { # Location of the efr32 SDK. - efr32_sdk_root = "${chip_root}/third_party/silabs/gecko_sdk" + efr32_sdk_root = "${chip_root}/third_party/silabs/simplicity_sdk" sdk_support_root = "${chip_root}/third_party/silabs/matter_support" wiseconnect_sdk_root = "${chip_root}/third_party/silabs/wiseconnect-wifi-bt-sdk" @@ -153,31 +153,45 @@ template("efr32_sdk") { "${efr32_sdk_root}/hardware/driver/configuration_over_swo/inc/", "${efr32_sdk_root}/platform/bootloader", "${efr32_sdk_root}/platform/bootloader/config", - "${efr32_sdk_root}/platform/bootloader/config/s2/btl_interface", + "${efr32_sdk_root}/platform/bootloader/config/btl_interface", "${efr32_sdk_root}/platform/bootloader/api", "${efr32_sdk_root}/platform/CMSIS/Core/Include", "${efr32_sdk_root}/platform/CMSIS/RTOS2/Include", "${efr32_sdk_root}/platform/common/inc", + "${efr32_sdk_root}/platform/driver/debug/inc", "${efr32_sdk_root}/platform/emdrv/common/inc", "${efr32_sdk_root}/platform/emdrv/gpiointerrupt/inc", "${efr32_sdk_root}/platform/emdrv/dmadrv/inc", "${efr32_sdk_root}/platform/emdrv/nvm3/inc", - "${efr32_sdk_root}/platform/emdrv/rtcdrv/inc", "${efr32_sdk_root}/platform/emlib/inc", "${efr32_sdk_root}/platform/halconfig/inc/hal-config", "${efr32_sdk_root}/platform/peripheral/inc", "${efr32_sdk_root}/platform/radio/rail_lib/common", "${efr32_sdk_root}/platform/radio/rail_lib/chip/efr32", - "${efr32_sdk_root}/platform/radio/rail_lib/chip/efr32/rf/common/cortex", "${efr32_sdk_root}/platform/radio/rail_lib/protocol/ieee802154", "${efr32_sdk_root}/platform/radio/rail_lib/protocol/ble", "${efr32_sdk_root}/platform/radio/rail_lib/plugin/pa-conversions", "${efr32_sdk_root}/platform/radio/rail_lib/plugin/rail_util_pti", "${efr32_sdk_root}/platform/radio/rail_lib/plugin/rail_util_power_manager_init", + "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/config/", + "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/config/preset", + "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/inc", + "${efr32_sdk_root}/platform/security/sl_component/sl_protocol_crypto/src", + "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/inc", + "${efr32_sdk_root}/platform/security/sl_component/se_manager/inc", + "${efr32_sdk_root}/platform/security/sl_component/se_manager/src/", + "${efr32_sdk_root}/platform/service/clock_manager/inc", "${efr32_sdk_root}/platform/service/device_init/inc", + "${efr32_sdk_root}/platform/service/device_manager/inc", "${efr32_sdk_root}/platform/service/hfxo_manager/inc", "${efr32_sdk_root}/platform/service/hfxo_manager/src", + "${efr32_sdk_root}/platform/service/interrupt_manager/inc/", + "${efr32_sdk_root}/platform/service/interrupt_manager/inc/arm/", "${efr32_sdk_root}/platform/service/iostream/inc", + "${efr32_sdk_root}/platform/service/memory_manager/inc", + "${efr32_sdk_root}/platform/service/memory_manager/src", + "${efr32_sdk_root}/platform/service/memory_manager/profiler/inc", + "${efr32_sdk_root}/platform/service/memory_manager/profiler/config", "${efr32_sdk_root}/platform/service/mpu/inc", "${efr32_sdk_root}/platform/service/power_manager/inc/", "${efr32_sdk_root}/platform/service/power_manager/src/", @@ -189,34 +203,26 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/middleware/glib/config", "${efr32_sdk_root}/platform/middleware/glib/glib", "${efr32_sdk_root}/platform/middleware/glib/dmd", - "${efr32_sdk_root}/platform/base/hal/plugin/psstore", - "${efr32_sdk_root}/platform/base/hal/plugin/antenna", "${efr32_sdk_root}/protocol/bluetooth/inc/", "${efr32_sdk_root}/protocol/bluetooth/bgstack/ll/inc", "${efr32_sdk_root}/util/plugin/plugin-common/fem-control", "${efr32_sdk_root}/util/silicon_labs/silabs_core/graphics", "${efr32_sdk_root}/util/silicon_labs/silabs_core/memory_manager", + "${efr32_sdk_root}/util/silicon_labs/silabs_core/queue", "${efr32_sdk_root}/util/third_party/mbedtls/include", "${efr32_sdk_root}/util/third_party/mbedtls/include/mbedtls", "${efr32_sdk_root}/util/third_party/mbedtls/include/psa", "${efr32_sdk_root}/util/third_party/mbedtls/library", - "${efr32_sdk_root}/platform/security/sl_component/sl_protocol_crypto/src", - "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/config/", - "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/config/preset", - "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/inc", - "${efr32_sdk_root}/platform/security/sl_component/se_manager/inc", - "${efr32_sdk_root}/platform/security/sl_component/se_manager/src/", "${efr32_sdk_root}/util/third_party/freertos/cmsis/Include", "${efr32_sdk_root}/util/third_party/freertos/kernel/include", - "${efr32_sdk_root}/platform/driver/debug/inc", "${silabs_gen_folder}/config", "${silabs_gen_folder}/autogen", - # Use directory in matter support until gsdk files are updated - "${sdk_support_root}/platform/security/sl_component/sl_mbedtls_support/inc", - # Headers needed for Init no function will be called if OT is not used "${sl_ot_efr32_root}", + + # TODO this is for sl_openthread_features_config.h. should use generated one per board when sl_ot_abstraction is integrated + "${sl_ot_libs_path}/config", ] if (silabs_family == "efr32mg24") { @@ -287,25 +293,33 @@ template("efr32_sdk") { "NVM3_DEFAULT_NVM_SIZE=40960", "NVM3_DEFAULT_MAX_OBJECT_SIZE=4092", "KVS_MAX_ENTRIES=${kvs_max_entries}", - "EFR32_OPENTHREAD_API", - "PHY=EMBER_PHY_RAIL", - "CORTEXM3", + "CORTEXM3=1", "MICRO=EMBER_MICRO_CORTEXM3_EFR32", "PLAT=EMBER_PLATFORM_CORTEXM3", "${silabs_mcu}=1", "${silabs_board}=1", "SL_BOARD_NAME=${silabs_board}", "__HEAP_SIZE=0", + "__STACK_SIZE=0", "SL_THREADING_ALT=1", "SL_COMPONENT_CATALOG_PRESENT=1", + "SL_CODE_COMPONENT_CORE=core", + "SL_CODE_COMPONENT_PERIPHERAL_SYSRTC=hal_sysrtc", + "SL_CODE_COMPONENT_POWER_MANAGER=power_manager", + "SL_CODE_COMPONENT_SLEEPTIMER=sleeptimer", + "CMSIS_NVIC_VIRTUAL=1", + "CMSIS_NVIC_VIRTUAL_HEADER_FILE=\"cmsis_nvic_virtual.h\"", "PLATFORM_HEADER=\"platform-header.h\"", "USE_NVM3=1", "SL_RAIL_LIB_MULTIPROTOCOL_SUPPORT=1", "SL_RAIL_UTIL_PA_CONFIG_HEADER=", "RADIO_CONFIG_DMP_SUPPORT=1", "SL_MATTER_BLE_EXTENDED_ADV=${sl_matter_ble_extended_adv}", - - #"__STACK_SIZE=0", + "SL_MEMORY_POOL_LIGHT=1", + "SL_OPENTHREAD_STACK_FEATURES_CONFIG_FILE=\"sl_openthread_features_config.h\"", + "SL_CSL_TIMEOUT=${sl_ot_csl_timeout_sec}", + "CIRCULAR_QUEUE_USE_LOCAL_CONFIG_HEADER=1", + "MATTER_INTEGRATION=1", ] if (silabs_log_enabled && chip_logging) { @@ -314,11 +328,6 @@ template("efr32_sdk") { defines += [ "SILABS_LOG_ENABLED=0" ] } - # Temporary configuration to enable COAP specific configurations - if (use_thread_coap_lib) { - defines += [ "SL_USE_COAP_CONFIG=1" ] - } - if (sl_uart_log_output) { defines += [ "SILABS_LOG_OUT_UART=1", @@ -326,6 +335,18 @@ template("efr32_sdk") { ] } + if (use_silabs_thread_lib) { + defines += [ "SL_CONFIG_OPENTHREAD_LIB=1" ] + } else { + defines += [ "SL_CONFIG_OPENTHREAD_LIB=0" ] + } + + if (use_thread_coap_lib) { + defines += [ "SL_USE_COAP_CONFIG=1" ] + } else { + defines += [ "SL_USE_COAP_CONFIG=0" ] + } + if (chip_enable_ble_rs911x) { defines += [ "RSI_BLE_ENABLE=1", @@ -449,7 +470,6 @@ template("efr32_sdk") { defines += [ "CHIP_DEVICE_CONFIG_THREAD_SSED=1", "SL_CSL_ENABLE=1", - "SL_CSL_TIMEOUT=${sl_ot_csl_timeout_sec}", ] } } @@ -511,6 +531,8 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/radio/rail_lib/plugin/pa-conversions/efr32xg24/config", "${efr32_sdk_root}/platform/service/device_init/config/s2/", "${efr32_sdk_root}/platform/emdrv/spidrv/inc", + "${efr32_sdk_root}/platform/emdrv/spidrv/config", + "${efr32_sdk_root}/platform/emdrv/dmadrv/inc/s2_signals", ] libs += [ @@ -521,9 +543,10 @@ template("efr32_sdk") { if (!chip_enable_ble_rs911x) { libs += [ - "${sdk_support_root}/protocol/bluetooth/bgcommon/lib/libbgcommon_efr32xg24_gcc_release.a", + "${sdk_support_root}/protocol/bluetooth/bgcommon/lib/build/gcc/cortex-m33/bgcommon/release/libbgcommon.a", "${sdk_support_root}/protocol/bluetooth/bgstack/ll/lib/libbluetooth_controller_efr32xg24_gcc_release.a", - "${sdk_support_root}/protocol/bluetooth/lib/libbluetooth_host_efr32xg24_gcc_release.a", + "${sdk_support_root}/protocol/bluetooth/build/gcc/cortex-m33/bt_host/release/libbt_host.a", + "${sdk_support_root}/protocol/bluetooth/build/gcc/cortex-m33/bt_host/hal/release/libbt_hal_series2.a", ] } @@ -542,12 +565,14 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/radio/rail_lib/plugin/pa-conversions/efr32xg24", "${efr32_sdk_root}/platform/radio/rail_lib/plugin/pa-conversions/efr32xg24/config", "${efr32_sdk_root}/platform/service/device_init/config/s2/", + "${efr32_sdk_root}/platform/emdrv/dmadrv/inc/s2_signals", ] libs += [ - "${sdk_support_root}/protocol/bluetooth/bgcommon/lib/libbgcommon_efr32xg24_gcc_release.a", + "${sdk_support_root}/protocol/bluetooth/bgcommon/lib/build/gcc/cortex-m33/bgcommon/release/libbgcommon.a", "${sdk_support_root}/protocol/bluetooth/bgstack/ll/lib/libbluetooth_controller_efr32xg24_gcc_release.a", - "${sdk_support_root}/protocol/bluetooth/lib/libbluetooth_host_efr32xg24_gcc_release.a", + "${sdk_support_root}/protocol/bluetooth/build/gcc/cortex-m33/bt_host/release/libbt_host.a", + "${sdk_support_root}/protocol/bluetooth/build/gcc/cortex-m33/bt_host/hal/release/libbt_hal_series2.a", "${sdk_support_root}/platform/radio/rail_lib/autogen/librail_release/librail_multiprotocol_module_efr32xg24_gcc_release.a", "${sdk_support_root}/platform/emdrv/nvm3/lib/libnvm3_CM33_gcc.a", "${sdk_support_root}/protocol/openthread/libs/libsl_openthread_efr32mg2x_gcc.a", @@ -618,6 +643,7 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/bootloader/api/btl_interface.c", "${efr32_sdk_root}/platform/bootloader/api/btl_interface_storage.c", "${efr32_sdk_root}/platform/bootloader/security/sha/crypto_sha.c", + "${efr32_sdk_root}/platform/common/src/sl_core_cortexm.c", "${efr32_sdk_root}/platform/common/src/sl_slist.c", "${efr32_sdk_root}/platform/common/src/sli_cmsis_os2_ext_task_register.c", "${efr32_sdk_root}/platform/emdrv/dmadrv/src/dmadrv.c", @@ -625,7 +651,6 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/emdrv/nvm3/src/nvm3_default.c", "${efr32_sdk_root}/platform/emdrv/nvm3/src/nvm3_hal_flash.c", "${efr32_sdk_root}/platform/emdrv/nvm3/src/nvm3_lock.c", - "${efr32_sdk_root}/platform/emlib/src/em_adc.c", "${efr32_sdk_root}/platform/emlib/src/em_cmu.c", "${efr32_sdk_root}/platform/emlib/src/em_core.c", "${efr32_sdk_root}/platform/emlib/src/em_crypto.c", @@ -639,11 +664,10 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/emlib/src/em_se.c", "${efr32_sdk_root}/platform/emlib/src/em_system.c", "${efr32_sdk_root}/platform/emlib/src/em_timer.c", - "${efr32_sdk_root}/platform/peripheral/src/peripheral_sysrtc.c", + "${efr32_sdk_root}/platform/peripheral/src/sl_hal_sysrtc.c", "${efr32_sdk_root}/platform/radio/rail_lib/plugin/pa-conversions/pa_conversions_efr32.c", "${efr32_sdk_root}/platform/radio/rail_lib/plugin/rail_util_power_manager_init/sl_rail_util_power_manager_init.c", "${efr32_sdk_root}/platform/radio/rail_lib/plugin/rail_util_pti/sl_rail_util_pti.c", - "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/src/crypto_ecp.c", "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/src/error.c", "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/src/mbedtls_ccm.c", "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/src/mbedtls_cmac.c", @@ -651,23 +675,34 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/src/mbedtls_sha.c", "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/src/sl_entropy_hardware.c", "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/src/sl_mbedtls.c", + "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/src/sl_psa_crypto.c", "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/src/sli_psa_crypto.c", + "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sl_psa_its_nvm3.c", "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_psa_driver_common.c", "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_psa_driver_init.c", "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_psa_trng.c", "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_se_driver_builtin_keys.c", "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_se_driver_signature.c", "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_se_version_dependencies.c", - "${efr32_sdk_root}/platform/service/device_init/src/sl_device_init_lfrco.c", - "${efr32_sdk_root}/platform/service/device_init/src/sl_device_init_nvic.c", + "${efr32_sdk_root}/platform/service/clock_manager/src/sl_clock_manager.c", + "${efr32_sdk_root}/platform/service/clock_manager/src/sl_clock_manager_init.c", + "${efr32_sdk_root}/platform/service/device_manager/src/sl_device_clock.c", + "${efr32_sdk_root}/platform/service/device_manager/src/sl_device_peripheral.c", "${efr32_sdk_root}/platform/service/hfxo_manager/src/sl_hfxo_manager.c", + "${efr32_sdk_root}/platform/service/interrupt_manager/src/sl_interrupt_manager_cortexm.c", "${efr32_sdk_root}/platform/service/iostream/src/sl_iostream.c", "${efr32_sdk_root}/platform/service/iostream/src/sl_iostream_rtt.c", + "${efr32_sdk_root}/platform/service/memory_manager/profiler/src/sli_memory_profiler_stubs.c", + "${efr32_sdk_root}/platform/service/memory_manager/src/sl_memory_manager.c", + "${efr32_sdk_root}/platform/service/memory_manager/src/sl_memory_manager_cpp.cpp", + "${efr32_sdk_root}/platform/service/memory_manager/src/sl_memory_manager_dynamic_reservation.c", + "${efr32_sdk_root}/platform/service/memory_manager/src/sl_memory_manager_pool.c", + "${efr32_sdk_root}/platform/service/memory_manager/src/sl_memory_manager_region.c", + "${efr32_sdk_root}/platform/service/memory_manager/src/sl_memory_manager_retarget.c", + "${efr32_sdk_root}/platform/service/memory_manager/src/sli_memory_manager_common.c", "${efr32_sdk_root}/platform/service/mpu/src/sl_mpu.c", "${efr32_sdk_root}/platform/service/power_manager/src/sl_power_manager.c", "${efr32_sdk_root}/platform/service/power_manager/src/sl_power_manager_debug.c", - "${efr32_sdk_root}/platform/service/power_manager/src/sl_power_manager_hal_s0_s1.c", - "${efr32_sdk_root}/platform/service/power_manager/src/sl_power_manager_hal_s2.c", "${efr32_sdk_root}/platform/service/sleeptimer/src/sl_sleeptimer.c", "${efr32_sdk_root}/platform/service/sleeptimer/src/sl_sleeptimer_hal_rtcc.c", "${efr32_sdk_root}/platform/service/system/src/sl_system_init.c", @@ -675,11 +710,12 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/service/udelay/src/sl_udelay.c", "${efr32_sdk_root}/platform/service/udelay/src/sl_udelay_armv6m_gcc.S", "${efr32_sdk_root}/util/plugin/security_manager/security_manager.c", - "${efr32_sdk_root}/util/silicon_labs/silabs_core/memory_manager/sl_malloc.c", + "${efr32_sdk_root}/util/silicon_labs/silabs_core/queue/circular_queue.c", "${efr32_sdk_root}/util/third_party/freertos/cmsis/Source/cmsis_os2.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/croutine.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/event_groups.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/list.c", + "${efr32_sdk_root}/util/third_party/freertos/kernel/portable/MemMang/heap_3.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/portable/SiliconLabs/tick_power_manager.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/queue.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/stream_buffer.c", @@ -718,7 +754,6 @@ template("efr32_sdk") { "${efr32_sdk_root}/util/third_party/mbedtls/library/psa_crypto_cipher.c", "${efr32_sdk_root}/util/third_party/mbedtls/library/psa_crypto_client.c", "${efr32_sdk_root}/util/third_party/mbedtls/library/psa_crypto_driver_wrappers_no_static.c", - "${efr32_sdk_root}/util/third_party/mbedtls/library/psa_crypto_ecp.c", "${efr32_sdk_root}/util/third_party/mbedtls/library/psa_crypto_hash.c", "${efr32_sdk_root}/util/third_party/mbedtls/library/psa_crypto_mac.c", "${efr32_sdk_root}/util/third_party/mbedtls/library/psa_crypto_rsa.c", @@ -747,12 +782,8 @@ template("efr32_sdk") { "${silabs_gen_folder}/autogen/gatt_db.c", "${silabs_gen_folder}/autogen/sl_bluetooth.c", "${silabs_gen_folder}/autogen/sl_board_default_init.c", - "${silabs_gen_folder}/autogen/sl_device_init_clocks.c", "${silabs_gen_folder}/autogen/sl_event_handler.c", "${silabs_gen_folder}/autogen/sl_iostream_handles.c", - - # Used file in matter_support until fix is pushed to gsdk - "${sdk_support_root}/platform/security/sl_component/sl_psa_driver/src/sl_psa_its_nvm3.c", ] if (enable_dic) { sources += [ @@ -765,11 +796,6 @@ template("efr32_sdk") { ] } - if (silabs_family != "mgm24") { - sources += - [ "${efr32_sdk_root}/platform/radio/rail_lib/hal/efr32/hal_efr.c" ] - } - if (use_wstk_buttons) { sources += [ "${efr32_sdk_root}/platform/driver/button/src/sl_button.c", @@ -803,6 +829,7 @@ template("efr32_sdk") { "${efr32_sdk_root}/protocol/bluetooth/src/sl_bt_stack_init.c", "${efr32_sdk_root}/protocol/bluetooth/src/sli_bt_advertiser_config.c", "${efr32_sdk_root}/protocol/bluetooth/src/sli_bt_connection_config.c", + "${efr32_sdk_root}/protocol/bluetooth/src/sli_bt_host_adaptation.c", ] } @@ -858,7 +885,6 @@ template("efr32_sdk") { "${efr32_sdk_root}/hardware/driver/memlcd/src/memlcd_usart/sl_memlcd_spi.c", "${efr32_sdk_root}/platform/emdrv/uartdrv/src/uartdrv.c", "${efr32_sdk_root}/platform/emlib/src/em_eusart.c", - "${efr32_sdk_root}/platform/emlib/src/em_leuart.c", "${efr32_sdk_root}/platform/emlib/src/em_usart.c", "${silabs_gen_folder}/autogen/sl_uartdrv_init.c", ] @@ -901,7 +927,6 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/Device/SiliconLabs/EFR32MG24/Source/startup_efr32mg24.c", "${efr32_sdk_root}/platform/Device/SiliconLabs/EFR32MG24/Source/system_efr32mg24.c", "${efr32_sdk_root}/platform/radio/rail_lib/plugin/pa-conversions/pa_curves_efr32.c", - "${efr32_sdk_root}/platform/service/device_init/src/sl_device_init_hfxo_s2.c", ] } else if (silabs_family == "mgm24") { sources += [ @@ -909,7 +934,6 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/Device/SiliconLabs/MGM24/Source/system_mgm24.c", "${efr32_sdk_root}/platform/radio/rail_lib/plugin/fem_util/sl_fem_util.c", "${efr32_sdk_root}/platform/radio/rail_lib/plugin/rail_util_rssi/sl_rail_util_rssi.c", - "${efr32_sdk_root}/platform/service/device_init/src/sl_device_init_hfxo_mgm24.c", ] } @@ -925,6 +949,7 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/security/sl_component/se_manager/src/sl_se_manager_key_handling.c", "${efr32_sdk_root}/platform/security/sl_component/se_manager/src/sl_se_manager_signature.c", "${efr32_sdk_root}/platform/security/sl_component/se_manager/src/sl_se_manager_util.c", + "${efr32_sdk_root}/platform/security/sl_component/se_manager/src/sli_se_manager_mailbox.c", "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/src/se_aes.c", "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/src/se_jpake.c", "${efr32_sdk_root}/platform/security/sl_component/sl_protocol_crypto/src/sli_protocol_crypto_radioaes.c", @@ -943,11 +968,13 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_se_transparent_driver_hash.c", "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_se_transparent_driver_mac.c", "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_se_transparent_key_derivation.c", + "${efr32_sdk_root}/platform/service/clock_manager/src/sl_clock_manager_hal_s2.c", + "${efr32_sdk_root}/platform/service/clock_manager/src/sl_clock_manager_init_hal_s2.c", "${efr32_sdk_root}/platform/service/device_init/src/sl_device_init_dcdc_s2.c", - "${efr32_sdk_root}/platform/service/device_init/src/sl_device_init_dpll_s2.c", - "${efr32_sdk_root}/platform/service/device_init/src/sl_device_init_emu_s2.c", - "${efr32_sdk_root}/platform/service/device_init/src/sl_device_init_lfxo_s2.c", + "${efr32_sdk_root}/platform/service/device_manager/clocks/sl_device_clock_efr32xg24.c", + "${efr32_sdk_root}/platform/service/device_manager/devices/sl_device_peripheral_hal_efr32xg24.c", "${efr32_sdk_root}/platform/service/hfxo_manager/src/sl_hfxo_manager_hal_s2.c", + "${efr32_sdk_root}/platform/service/power_manager/src/sl_power_manager_hal_s2.c", "${efr32_sdk_root}/platform/service/sleeptimer/src/sl_sleeptimer_hal_sysrtc.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/portable/GCC/ARM_CM33_NTZ/non_secure/port.c", "${efr32_sdk_root}/util/third_party/freertos/kernel/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c", diff --git a/third_party/silabs/gecko_sdk b/third_party/silabs/gecko_sdk deleted file mode 160000 index e359ba40a2ba5b..00000000000000 --- a/third_party/silabs/gecko_sdk +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e359ba40a2ba5b127964a6e7afe9e70ff5f9a1cf diff --git a/third_party/silabs/matter_support b/third_party/silabs/matter_support index edbfeba723c9ff..a1fdd62cb16804 160000 --- a/third_party/silabs/matter_support +++ b/third_party/silabs/matter_support @@ -1 +1 @@ -Subproject commit edbfeba723c9ffdc93f57ad1eee85186b1643f25 +Subproject commit a1fdd62cb168049f946f7e1b5399c39353bcd7b4 diff --git a/third_party/silabs/simplicity_sdk b/third_party/silabs/simplicity_sdk new file mode 160000 index 00000000000000..a1a37fa7dda1f7 --- /dev/null +++ b/third_party/silabs/simplicity_sdk @@ -0,0 +1 @@ +Subproject commit a1a37fa7dda1f76ea70229aa4ffe2e47cb066edc diff --git a/third_party/silabs/slc_gen/run_slc.py b/third_party/silabs/slc_gen/run_slc.py index 4ec7f59b9ae600..22ef27b2c750e6 100644 --- a/third_party/silabs/slc_gen/run_slc.py +++ b/third_party/silabs/slc_gen/run_slc.py @@ -14,10 +14,11 @@ def asBoolean(valueToTest): def isMG24(partnumber): - if "EFR32MG24" in partnumber or "MGM240" in partnumber: - return True - else: - return False + return ("EFR32MG24" in partnumber or "MGM240" in partnumber) + + +def isMG26(partnumber): + return ("EFR32MG26" in partnumber) root_path = sys.argv[1] @@ -35,10 +36,8 @@ def isMG24(partnumber): slc_arguments = "" # Add Familly specific component -if isMG24(silabs_mcu): +if isMG24(silabs_mcu) or isMG26(silabs_mcu): slc_arguments += "uartdrv_eusart:vcom," -else: - slc_arguments += "uartdrv_usart:vcom," # Translate GN arguments in SLC arguments if not disable_lcd: @@ -58,15 +57,15 @@ def isMG24(partnumber): print(slc_arguments) -if "GSDK_ROOT" in os.environ: - gsdk_root = os.getenv('GSDK_ROOT') +if "SISDK_ROOT" in os.environ: + sisdk_root = os.getenv('SISDK_ROOT') else: # If no gsdk path is set in the environment, use the standard path to the submodule - gsdk_root = os.path.join(root_path, "third_party/silabs/gecko_sdk/") + sisdk_root = os.path.join(root_path, "third_party/silabs/simplicity_sdk/") # make sure we have a configured and trusted gsdk in slc -subprocess.run(["slc", "configuration", "--sdk", gsdk_root], check=True) -subprocess.run(["slc", "signature", "trust", "--sdk", gsdk_root], check=True) +subprocess.run(["slc", "configuration", "--sdk", sisdk_root], check=True) +subprocess.run(["slc", "signature", "trust", "--sdk", sisdk_root], check=True) subprocess.run(["slc", "generate", slcp_file_path, "-d", output_path, "--with", slc_arguments], check=True) diff --git a/third_party/silabs/wifi_sdk b/third_party/silabs/wifi_sdk index aa514d4fac4b56..e97a0ed00ddda3 160000 --- a/third_party/silabs/wifi_sdk +++ b/third_party/silabs/wifi_sdk @@ -1 +1 @@ -Subproject commit aa514d4fac4b568d03e1f6d3d19c7811034d5077 +Subproject commit e97a0ed00ddda347a8a39e8276f470e1c5fea469 From 2829a87431cc8d8740abbaf7035a0edb6518afbb Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 26 Jun 2024 08:28:24 -0400 Subject: [PATCH 06/21] Fix cluster index key name for Darwin attribute cache. (#34078) The endpoint was not being formatted right. --- src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm index d38712c00a5151..a328b2a903627f 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm @@ -479,7 +479,7 @@ - (BOOL)_deleteEndpointIndexForNodeID:(NSNumber *)nodeID - (NSString *)_clusterIndexKeyForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID { - return [sAttributeCacheClusterIndexKeyPrefix stringByAppendingFormat:@":0x%016llX:%0x04X", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue]; + return [sAttributeCacheClusterIndexKeyPrefix stringByAppendingFormat:@":0x%016llX:0x%04X", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue]; } - (nullable NSArray *)_fetchClusterIndexForNodeID:(NSNumber *)nodeID endpointID:(NSNumber *)endpointID From edf1118ab74cfa3ac618fab77d7880622221c6c5 Mon Sep 17 00:00:00 2001 From: shripad621git <79364691+shripad621git@users.noreply.github.com> Date: Wed, 26 Jun 2024 19:41:29 +0530 Subject: [PATCH 07/21] Fix the hardware mac address isssue for thread network (#34081) --- src/platform/ESP32/DiagnosticDataProviderImpl.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/platform/ESP32/DiagnosticDataProviderImpl.cpp b/src/platform/ESP32/DiagnosticDataProviderImpl.cpp index 154be055d92e9c..33de4d372199ee 100644 --- a/src/platform/ESP32/DiagnosticDataProviderImpl.cpp +++ b/src/platform/ESP32/DiagnosticDataProviderImpl.cpp @@ -38,6 +38,7 @@ #else #include "esp_spi_flash.h" #endif +#include "esp_mac.h" #include "esp_system.h" #include "esp_wifi.h" @@ -222,6 +223,7 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetNetworkInterfaces(NetworkInterface ** ifp->type = GetInterfaceType(esp_netif_get_desc(ifa)); ifp->offPremiseServicesReachableIPv4.SetNull(); ifp->offPremiseServicesReachableIPv6.SetNull(); +#if !CHIP_DEVICE_CONFIG_ENABLE_THREAD if (esp_netif_get_mac(ifa, ifp->MacAddress) != ESP_OK) { ChipLogError(DeviceLayer, "Failed to get network hardware address"); @@ -230,6 +232,17 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetNetworkInterfaces(NetworkInterface ** { ifp->hardwareAddress = ByteSpan(ifp->MacAddress, 6); } +#else + if (esp_read_mac(ifp->MacAddress, ESP_MAC_IEEE802154) != ESP_OK) + { + ChipLogError(DeviceLayer, "Failed to get network hardware address"); + } + else + { + ifp->hardwareAddress = ByteSpan(ifp->MacAddress, 8); + } +#endif + #ifndef CONFIG_DISABLE_IPV4 if (esp_netif_get_ip_info(ifa, &ipv4_info) == ESP_OK) { From 21863572a4afa6d07a53b563f50610ac945eb4f0 Mon Sep 17 00:00:00 2001 From: William Date: Wed, 26 Jun 2024 15:54:08 +0100 Subject: [PATCH 08/21] =?UTF-8?q?Add=20definitions=20for=20common=20HomeLo?= =?UTF-8?q?cationStruct=20and=20types=20-=20see=20connect=E2=80=A6=20(#335?= =?UTF-8?q?69)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add definitions for common HomeLocationStruct and types - see connectedhomeip-spec PR 8933 * Fix Carport typo, remove IsGroundFloor field (spec change) * Update home location definitions per spec PR 8933 commit f04958166412d5b7eff4d3443273f47f12f22baf 2024-05-23 * update generated files * Regenerated zap files after merge. * Moved the AreaTypeTag namespace definition to namespaces.xml. * Moved the HomeLoc global struct into global-sturcts.xml. * Updated the AreaTypeTag namespace to match the latest spec definition. * Updated the AreaTypeTag namespace to match the latest spec definition. * Updated the matterlint rules with the changes in the xml files. * Reverted changes to the rvc zap file. * Addded global xml files to relevant lists of xmls. * Added the Position, Landmark and Floor Surface Namespaces. * Explicitly set the conformance. * Added github issue to a comment. * Renamed namespaces.xml to semantic-tag-namespace-enums.xml. * Missed some rename locations. --------- Co-authored-by: jfierke@irobot.com --- .github/workflows/tests.yaml | 2 + scripts/rules.matterlint | 2 + src/app/zap-templates/zcl/data-model/all.xml | 2 + .../zcl/data-model/chip/global-structs.xml | 34 +++ .../chip/semantic-tag-namespace-enums.xml | 239 ++++++++++++++++++ .../zcl/zcl-with-test-extensions.json | 2 + src/app/zap-templates/zcl/zcl.json | 2 + 7 files changed, 283 insertions(+) create mode 100644 src/app/zap-templates/zcl/data-model/chip/global-structs.xml create mode 100644 src/app/zap-templates/zcl/data-model/chip/semantic-tag-namespace-enums.xml diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index ad54b57a515568..8c95d0d10c5a60 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -91,6 +91,8 @@ jobs: --no-print \ --log-level info \ src/app/zap-templates/zcl/data-model/chip/global-attributes.xml \ + src/app/zap-templates/zcl/data-model/chip/global-structs.xml \ + src/app/zap-templates/zcl/data-model/chip/semantic-tag-namespace-enums.xml \ src/app/zap-templates/zcl/data-model/chip/access-control-definitions.xml \ src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/account-login-cluster.xml \ diff --git a/scripts/rules.matterlint b/scripts/rules.matterlint index 76e9d8df313d63..2ea8c5545471ef 100644 --- a/scripts/rules.matterlint +++ b/scripts/rules.matterlint @@ -42,6 +42,7 @@ load "../src/app/zap-templates/zcl/data-model/chip/flow-measurement-cluster.xml" load "../src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/general-diagnostics-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/global-attributes.xml"; +load "../src/app/zap-templates/zcl/data-model/chip/global-structs.xml"; load "../src/app/zap-templates/zcl/data-model/chip/groups-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/group-key-mgmt-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/identify-cluster.xml"; @@ -58,6 +59,7 @@ load "../src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/messages-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/mode-select-cluster.xml"; +load "../src/app/zap-templates/zcl/data-model/chip/semantic-tag-namespace-enums.xml"; load "../src/app/zap-templates/zcl/data-model/chip/network-commissioning-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/occupancy-sensing-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/onoff-cluster.xml"; diff --git a/src/app/zap-templates/zcl/data-model/all.xml b/src/app/zap-templates/zcl/data-model/all.xml index e523acb886541d..c0067fad34dc90 100644 --- a/src/app/zap-templates/zcl/data-model/all.xml +++ b/src/app/zap-templates/zcl/data-model/all.xml @@ -45,6 +45,7 @@ + @@ -61,6 +62,7 @@ + diff --git a/src/app/zap-templates/zcl/data-model/chip/global-structs.xml b/src/app/zap-templates/zcl/data-model/chip/global-structs.xml new file mode 100644 index 00000000000000..54b4f69bc93bb8 --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/global-structs.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/semantic-tag-namespace-enums.xml b/src/app/zap-templates/zcl/data-model/chip/semantic-tag-namespace-enums.xml new file mode 100644 index 00000000000000..a1572523bcb0b3 --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/semantic-tag-namespace-enums.xml @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json index 0c1e2c2b5a715f..b480f5d700a883 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -61,6 +61,7 @@ "general-commissioning-cluster.xml", "general-diagnostics-cluster.xml", "global-attributes.xml", + "global-structs.xml", "groups-cluster.xml", "group-key-mgmt-cluster.xml", "icd-management-cluster.xml", @@ -80,6 +81,7 @@ "mode-base-cluster.xml", "mode-select-cluster.xml", "mode-select-extensions.xml", + "semantic-tag-namespace-enums.xml", "network-commissioning-cluster.xml", "occupancy-sensing-cluster.xml", "onoff-cluster.xml", diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index 0d99e3f865463c..b647b6728f2d56 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -59,6 +59,7 @@ "general-commissioning-cluster.xml", "general-diagnostics-cluster.xml", "global-attributes.xml", + "global-structs.xml", "groups-cluster.xml", "group-key-mgmt-cluster.xml", "icd-management-cluster.xml", @@ -77,6 +78,7 @@ "messages-cluster.xml", "mode-base-cluster.xml", "mode-select-cluster.xml", + "semantic-tag-namespace-enums.xml", "network-commissioning-cluster.xml", "occupancy-sensing-cluster.xml", "onoff-cluster.xml", From ce71ed55121f69b650c0cb6612f4eecacefb1b63 Mon Sep 17 00:00:00 2001 From: William Date: Wed, 26 Jun 2024 15:59:15 +0100 Subject: [PATCH 09/21] Add xml definition for service area cluster (#33752) * Add definitions for common HomeLocationStruct and types - see connectedhomeip-spec PR 8933 * Add definition for Service Area Cluster - see connectedhomeip-spec PR 8937 * Add semantic tag definitions needed for Service Area Cluster - see connectedhomeip-spec PR 8937 * Update Service Area Cluster definition of LocationInfoStruct - see connectedhomeip-spec PR 8937 * Rename SurfaceTag to FloorSurfaceTag - spec PR 8937 commit 431739b3e3996d0ef74a36b2a6b93ac0d3db9c45 * Fix Carport typo, remove IsGroundFloor field (spec change) * Update home location definitions per spec PR 8933 commit f04958166412d5b7eff4d3443273f47f12f22baf 2024-05-23 * update generated files * Update Service Area Cluster definitions per spec PR 8937 up to commit 6bf3762eb1ee733c642e79074744d1185b82a89c 2024-05-24 * update generated files * Regenerated zap files after merge. * Moved the AreaTypeTag namespace definition to namespaces.xml. * Moved the HomeLoc global struct into global-sturcts.xml. * Updated the AreaTypeTag namespace to match the latest spec definition. * Updated the AreaTypeTag namespace to match the latest spec definition. * Updated the matterlint rules with the changes in the xml files. * Reverted changes to the rvc zap file. * Addded global xml files to relevant lists of xmls. * Added the Position, Landmark and Floor Surface Namespaces. * Removed namespace tag definitions from the service area cluters XML. * Regenerated zap files. * Explicitly set the conformance. * Fixed typos in the service-area clusters XML from review. * Used a more feature rich method for defining the cluster's features. * Reordered data-type definitions to match the order in the spec. * Regenerated zap files. * Added github issue to a comment. * Renamed namespaces.xml to semantic-tag-namespace-enums.xml. * Missed some rename locations. --------- Co-authored-by: jfierke@irobot.com --- docs/zap_clusters.md | 1 + scripts/rules.matterlint | 1 + src/app/zap-templates/zcl/data-model/all.xml | 1 + .../data-model/chip/service-area-cluster.xml | 130 ++ .../zcl/zcl-with-test-extensions.json | 1 + src/app/zap-templates/zcl/zcl.json | 1 + .../data_model/controller-clusters.matter | 290 ++++ .../chip/devicecontroller/ChipClusters.java | 457 ++++++ .../chip/devicecontroller/ChipStructs.java | 395 +++++ .../devicecontroller/ClusterIDMapping.java | 128 ++ .../devicecontroller/ClusterInfoMapping.java | 297 ++++ .../devicecontroller/ClusterReadMapping.java | 137 ++ .../devicecontroller/ClusterWriteMapping.java | 2 + .../chip/devicecontroller/cluster/files.gni | 5 + .../ServiceAreaClusterHomeLocationStruct.kt | 84 + .../ServiceAreaClusterLocationInfoStruct.kt | 117 ++ .../ServiceAreaClusterLocationStruct.kt | 78 + .../structs/ServiceAreaClusterMapStruct.kt | 56 + .../ServiceAreaClusterProgressStruct.kt | 109 ++ .../cluster/clusters/ServiceAreaCluster.kt | 1460 +++++++++++++++++ .../java/matter/controller/cluster/files.gni | 6 + .../ServiceAreaClusterHomeLocationStruct.kt | 84 + .../ServiceAreaClusterLocationInfoStruct.kt | 117 ++ .../ServiceAreaClusterLocationStruct.kt | 78 + .../structs/ServiceAreaClusterMapStruct.kt | 56 + .../ServiceAreaClusterProgressStruct.kt | 109 ++ .../CHIPAttributeTLVValueDecoder.cpp | 601 +++++++ .../CHIPEventTLVValueDecoder.cpp | 10 + .../python/chip/clusters/CHIPClusters.py | 95 ++ .../python/chip/clusters/Objects.py | 624 +++++++ .../MTRAttributeSpecifiedCheck.mm | 48 + .../MTRAttributeTLVValueDecoder.mm | 231 +++ .../CHIP/zap-generated/MTRBaseClusters.h | 334 ++++ .../CHIP/zap-generated/MTRBaseClusters.mm | 489 ++++++ .../CHIP/zap-generated/MTRClusterConstants.h | 21 + .../CHIP/zap-generated/MTRClusterNames.mm | 61 + .../CHIP/zap-generated/MTRClusters.h | 53 + .../CHIP/zap-generated/MTRClusters.mm | 122 ++ .../zap-generated/MTRCommandPayloadsObjc.h | 100 ++ .../zap-generated/MTRCommandPayloadsObjc.mm | 364 ++++ .../MTRCommandPayloads_Internal.h | 24 + .../zap-generated/MTRCommandTimedCheck.mm | 12 + .../zap-generated/MTREventTLVValueDecoder.mm | 15 + .../CHIP/zap-generated/MTRStructsObjc.h | 36 + .../CHIP/zap-generated/MTRStructsObjc.mm | 168 ++ .../zap-generated/attributes/Accessors.cpp | 274 ++++ .../zap-generated/attributes/Accessors.h | 40 + .../app-common/zap-generated/callback.h | 56 + .../zap-generated/cluster-enums-check.h | 267 +++ .../app-common/zap-generated/cluster-enums.h | 276 ++++ .../zap-generated/cluster-objects.cpp | 419 +++++ .../zap-generated/cluster-objects.h | 432 +++++ .../app-common/zap-generated/ids/Attributes.h | 54 + .../app-common/zap-generated/ids/Clusters.h | 3 + .../app-common/zap-generated/ids/Commands.h | 22 + .../zap-generated/cluster/Commands.h | 184 +++ .../cluster/ComplexArgumentParser.cpp | 200 +++ .../cluster/ComplexArgumentParser.h | 25 + .../cluster/logging/DataModelLogger.cpp | 277 ++++ .../cluster/logging/DataModelLogger.h | 19 + .../zap-generated/cluster/Commands.h | 1245 ++++++++++++++ 61 files changed, 11401 insertions(+) create mode 100644 src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml create mode 100644 src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt create mode 100644 src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt create mode 100644 src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationStruct.kt create mode 100644 src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterMapStruct.kt create mode 100644 src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterProgressStruct.kt create mode 100644 src/controller/java/generated/java/matter/controller/cluster/clusters/ServiceAreaCluster.kt create mode 100644 src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt create mode 100644 src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt create mode 100644 src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationStruct.kt create mode 100644 src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterMapStruct.kt create mode 100644 src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterProgressStruct.kt diff --git a/docs/zap_clusters.md b/docs/zap_clusters.md index 9033fff4101de9..7651e35b784ed1 100644 --- a/docs/zap_clusters.md +++ b/docs/zap_clusters.md @@ -90,6 +90,7 @@ Generally regenerate using one of: | 257 | 0x101 | DoorLock | | 258 | 0x102 | WindowCovering | | 259 | 0x103 | BarrierControl | +| 336 | 0x150 | ServiceArea | | 512 | 0x200 | PumpConfigurationAndControl | | 513 | 0x201 | Thermostat | | 514 | 0x202 | FanControl | diff --git a/scripts/rules.matterlint b/scripts/rules.matterlint index 2ea8c5545471ef..335e37436be00c 100644 --- a/scripts/rules.matterlint +++ b/scripts/rules.matterlint @@ -81,6 +81,7 @@ load "../src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature- load "../src/app/zap-templates/zcl/data-model/chip/relative-humidity-measurement-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml"; +load "../src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/scene.xml"; load "../src/app/zap-templates/zcl/data-model/chip/smoke-co-alarm-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/software-diagnostics-cluster.xml"; diff --git a/src/app/zap-templates/zcl/data-model/all.xml b/src/app/zap-templates/zcl/data-model/all.xml index c0067fad34dc90..23709faca1ace5 100644 --- a/src/app/zap-templates/zcl/data-model/all.xml +++ b/src/app/zap-templates/zcl/data-model/all.xml @@ -87,6 +87,7 @@ + diff --git a/src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml new file mode 100644 index 00000000000000..84e9a464336080 --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml @@ -0,0 +1,130 @@ + + + + + + Data types + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + General + Service Area + The Service Area cluster provides an interface for controlling the locations where a device should operate, and for querying the current location. + 0x0150 + SERVICE_AREA_CLUSTER + + + + + + + + + + + + SupportedLocations + SupportedMaps + SelectedLocations + CurrentLocation + EstimatedEndTime + Progress + + + + + Command used to select a set of device locations, where the device is to operate + + + + + + + This command is sent by the device on receipt of the SelectLocations command. + + + + + + + + This command is used to skip the current location where the device operates. + + + + + + This command is sent by the device on receipt of the SelectLocations command. + + + + + + + + diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json index b480f5d700a883..b253dd55e72831 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -108,6 +108,7 @@ "rvc-run-mode-cluster.xml", "resource-monitoring-cluster.xml", "scene.xml", + "service-area-cluster.xml", "smoke-co-alarm-cluster.xml", "software-diagnostics-cluster.xml", "switch-cluster.xml", diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index b647b6728f2d56..6b361e507a3cf3 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -105,6 +105,7 @@ "replacable-monitoring-cluster.xml", "resource-monitoring-cluster.xml", "scene.xml", + "service-area-cluster.xml", "smoke-co-alarm-cluster.xml", "software-diagnostics-cluster.xml", "switch-cluster.xml", diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index 2b21d4b4a4e708..cb858ffdcd8802 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -5994,6 +5994,296 @@ deprecated cluster BarrierControl = 259 { command BarrierControlStop(): DefaultSuccess = 1; } +/** The Service Area cluster provides an interface for controlling the locations where a device should operate, and for querying the current location. */ +cluster ServiceArea = 336 { + revision 1; // NOTE: Default/not specifically set + + enum AreaTypeTag : enum8 { + kAisle = 0; + kAttic = 1; + kBackDoor = 2; + kBackYard = 3; + kBalcony = 4; + kBallroom = 5; + kBathroom = 6; + kBedroom = 7; + kBorder = 8; + kBoxroom = 9; + kBreakfastRoom = 10; + kCarport = 11; + kCellar = 12; + kCloakroom = 13; + kCloset = 14; + kConservatory = 15; + kCorridor = 16; + kCraftRoom = 17; + kCupboard = 18; + kDeck = 19; + kDen = 20; + kDining = 21; + kDrawingRoom = 22; + kDressingRoom = 23; + kDriveway = 24; + kElevator = 25; + kEnsuite = 26; + kEntrance = 27; + kEntryway = 28; + kFamilyRoom = 29; + kFoyer = 30; + kFrontDoor = 31; + kFrontYard = 32; + kGameRoom = 33; + kGarage = 34; + kGarageDoor = 35; + kGarden = 36; + kGardenDoor = 37; + kGuestBathroom = 38; + kGuestBedroom = 39; + kGuestRestroom = 40; + kGuestRoom = 41; + kGym = 42; + kHallway = 43; + kHearthRoom = 44; + kKidsRoom = 45; + kKidsBedroom = 46; + kKitchen = 47; + kLarder = 48; + kLaundryRoom = 49; + kLawn = 50; + kLibrary = 51; + kLivingRoom = 52; + kLounge = 53; + kMediaTVRoom = 54; + kMudRoom = 55; + kMusicRoom = 56; + kNursery = 57; + kOffice = 58; + kOutdoorKitchen = 59; + kOutside = 60; + kPantry = 61; + kParkingLot = 62; + kParlor = 63; + kPatio = 64; + kPlayRoom = 65; + kPoolRoom = 66; + kPorch = 67; + kPrimaryBathroom = 68; + kPrimaryBedroom = 69; + kRamp = 70; + kReceptionRoom = 71; + kRecreationRoom = 72; + kRestroom = 73; + kRoof = 74; + kSauna = 75; + kScullery = 76; + kSewingRoom = 77; + kShed = 78; + kSideDoor = 79; + kSideYard = 80; + kSittingRoom = 81; + kSnug = 82; + kSpa = 83; + kStaircase = 84; + kSteamRoom = 85; + kStorageRoom = 86; + kStudio = 87; + kStudy = 88; + kSunRoom = 89; + kSwimmingPool = 90; + kTerrace = 91; + kUtilityRoom = 92; + kWard = 93; + kWorkshop = 94; + } + + enum FloorSurfaceTag : enum8 { + kCarpet = 0; + kCeramic = 1; + kConcrete = 2; + kCork = 3; + kDeepCarpet = 4; + kDirt = 5; + kEngineeredWood = 6; + kGlass = 7; + kGrass = 8; + kHardwood = 9; + kLaminate = 10; + kLinoleum = 11; + kMat = 12; + kMetal = 13; + kPlastic = 14; + kPolishedConcrete = 15; + kRubber = 16; + kRug = 17; + kSand = 18; + kStone = 19; + kTatami = 20; + kTerrazzo = 21; + kTile = 22; + kVinyl = 23; + } + + enum LandmarkTag : enum8 { + kAirConditioner = 0; + kAirPurifier = 1; + kBackDoor = 2; + kBarStool = 3; + kBathMat = 4; + kBathtub = 5; + kBed = 6; + kBookshelf = 7; + kChair = 8; + kChristmasTree = 9; + kCoatRack = 10; + kCoffeeTable = 11; + kCookingRange = 12; + kCouch = 13; + kCountertop = 14; + kCradle = 15; + kCrib = 16; + kDesk = 17; + kDiningTable = 18; + kDishwasher = 19; + kDoor = 20; + kDresser = 21; + kLaundryDryer = 22; + kFan = 23; + kFireplace = 24; + kFreezer = 25; + kFrontDoor = 26; + kHighChair = 27; + kKitchenIsland = 28; + kLamp = 29; + kLitterBox = 30; + kMirror = 31; + kNightstand = 32; + kOven = 33; + kPetBed = 34; + kPetBowl = 35; + kPetCrate = 36; + kRefrigerator = 37; + kScratchingPost = 38; + kShoeRack = 39; + kShower = 40; + kSideDoor = 41; + kSink = 42; + kSofa = 43; + kStove = 44; + kTable = 45; + kToilet = 46; + kTrashCan = 47; + kLaundryWasher = 48; + kWindow = 49; + kWineCooler = 50; + } + + enum OperationalStatusEnum : enum8 { + kPending = 0; + kOperating = 1; + kSkipped = 2; + kCompleted = 3; + } + + enum PositionTag : enum8 { + kLeft = 0; + kRight = 1; + kTop = 2; + kBottom = 3; + kMiddle = 4; + kRow = 5; + kColumn = 6; + kUnder = 7; + kNextTo = 8; + kAround = 9; + kOn = 10; + kAbove = 11; + kFrontOf = 12; + kBehind = 13; + } + + enum SelectLocationsStatus : enum8 { + kSuccess = 0; + kUnsupportedLocation = 1; + kDuplicatedLocations = 2; + kInvalidInMode = 3; + kInvalidSet = 4; + } + + enum SkipCurrentLocationStatus : enum8 { + kSuccess = 0; + kInvalidLocationList = 1; + kInvalidInMode = 2; + } + + bitmap Feature : bitmap32 { + kListOrder = 0x1; + kSelectWhileRunning = 0x2; + } + + struct HomeLocationStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; + } + + struct LocationInfoStruct { + nullable HomeLocationStruct locationInfo = 0; + nullable LandmarkTag landmarkTag = 1; + nullable PositionTag positionTag = 2; + nullable FloorSurfaceTag surfaceTag = 3; + } + + struct LocationStruct { + int32u locationID = 0; + nullable int8u mapID = 1; + LocationInfoStruct locationInfo = 2; + } + + struct MapStruct { + int8u mapID = 0; + char_string<64> name = 1; + } + + struct ProgressStruct { + int32u locationID = 0; + OperationalStatusEnum status = 1; + optional nullable elapsed_s totalOperationalTime = 2; + optional nullable elapsed_s estimatedTime = 3; + } + + readonly attribute LocationStruct supportedLocations[] = 0; + readonly attribute nullable MapStruct supportedMaps[] = 1; + readonly attribute nullable int32u selectedLocations[] = 2; + readonly attribute optional nullable int32u currentLocation = 3; + readonly attribute optional nullable epoch_s estimatedEndTime = 4; + readonly attribute optional nullable ProgressStruct progress[] = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct SelectLocationsRequest { + nullable int32u newLocations[] = 0; + } + + response struct SelectLocationsResponse = 1 { + SelectLocationsStatus status = 0; + optional char_string<256> statusText = 1; + } + + response struct SkipCurrentLocationResponse = 3 { + SkipCurrentLocationStatus status = 0; + optional char_string<256> statusText = 1; + } + + /** Command used to select a set of device locations, where the device is to operate */ + command SelectLocations(SelectLocationsRequest): SelectLocationsResponse = 0; + /** This command is used to skip the current location where the device operates. */ + command SkipCurrentLocation(): SkipCurrentLocationResponse = 2; +} + /** An interface for configuring and controlling pumps. */ cluster PumpConfigurationAndControl = 512 { revision 3; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 40725b1dfba8fe..80491515bc57d3 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -37953,6 +37953,463 @@ public void onSuccess(byte[] tlv) { } } + public static class ServiceAreaCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 336L; + + private static final long SUPPORTED_LOCATIONS_ATTRIBUTE_ID = 0L; + private static final long SUPPORTED_MAPS_ATTRIBUTE_ID = 1L; + private static final long SELECTED_LOCATIONS_ATTRIBUTE_ID = 2L; + private static final long CURRENT_LOCATION_ATTRIBUTE_ID = 3L; + private static final long ESTIMATED_END_TIME_ATTRIBUTE_ID = 4L; + private static final long PROGRESS_ATTRIBUTE_ID = 5L; + private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; + private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; + private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; + private static final long ATTRIBUTE_LIST_ATTRIBUTE_ID = 65531L; + private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L; + private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L; + + public ServiceAreaCluster(long devicePtr, int endpointId) { + super(devicePtr, endpointId, CLUSTER_ID); + } + + @Override + @Deprecated + public long initWithDevice(long devicePtr, int endpointId) { + return 0L; + } + + public void selectLocations(SelectLocationsResponseCallback callback, @Nullable ArrayList newLocations) { + selectLocations(callback, newLocations, 0); + } + + public void selectLocations(SelectLocationsResponseCallback callback, @Nullable ArrayList newLocations, int timedInvokeTimeoutMs) { + final long commandId = 0L; + + ArrayList elements = new ArrayList<>(); + final long newLocationsFieldID = 0L; + BaseTLVType newLocationstlvValue = newLocations != null ? ArrayType.generateArrayType(newLocations, (elementnewLocations) -> new UIntType(elementnewLocations)) : new NullType(); + elements.add(new StructElement(newLocationsFieldID, newLocationstlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long statusFieldID = 0L; + Integer status = null; + final long statusTextFieldID = 1L; + Optional statusText = Optional.empty(); + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == statusFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + status = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == statusTextFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + statusText = Optional.of(castingValue.value(String.class)); + } + } + } + callback.onSuccess(status, statusText); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public void skipCurrentLocation(SkipCurrentLocationResponseCallback callback) { + skipCurrentLocation(callback, 0); + } + + public void skipCurrentLocation(SkipCurrentLocationResponseCallback callback, int timedInvokeTimeoutMs) { + final long commandId = 2L; + + ArrayList elements = new ArrayList<>(); + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long statusFieldID = 0L; + Integer status = null; + final long statusTextFieldID = 1L; + Optional statusText = Optional.empty(); + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == statusFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + status = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == statusTextFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + statusText = Optional.of(castingValue.value(String.class)); + } + } + } + callback.onSuccess(status, statusText); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public interface SelectLocationsResponseCallback extends BaseClusterCallback { + void onSuccess(Integer status, Optional statusText); + } + + public interface SkipCurrentLocationResponseCallback extends BaseClusterCallback { + void onSuccess(Integer status, Optional statusText); + } + + public interface SupportedLocationsAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface SupportedMapsAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable List value); + } + + public interface SelectedLocationsAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable List value); + } + + public interface CurrentLocationAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable Long value); + } + + public interface EstimatedEndTimeAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable Long value); + } + + public interface ProgressAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable List value); + } + + public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AcceptedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface EventListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AttributeListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public void readSupportedLocationsAttribute( + SupportedLocationsAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_LOCATIONS_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SUPPORTED_LOCATIONS_ATTRIBUTE_ID, true); + } + + public void subscribeSupportedLocationsAttribute( + SupportedLocationsAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_LOCATIONS_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SUPPORTED_LOCATIONS_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readSupportedMapsAttribute( + SupportedMapsAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_MAPS_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SUPPORTED_MAPS_ATTRIBUTE_ID, true); + } + + public void subscribeSupportedMapsAttribute( + SupportedMapsAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_MAPS_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SUPPORTED_MAPS_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readSelectedLocationsAttribute( + SelectedLocationsAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SELECTED_LOCATIONS_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SELECTED_LOCATIONS_ATTRIBUTE_ID, true); + } + + public void subscribeSelectedLocationsAttribute( + SelectedLocationsAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SELECTED_LOCATIONS_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SELECTED_LOCATIONS_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readCurrentLocationAttribute( + CurrentLocationAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_LOCATION_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CURRENT_LOCATION_ATTRIBUTE_ID, true); + } + + public void subscribeCurrentLocationAttribute( + CurrentLocationAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_LOCATION_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CURRENT_LOCATION_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readEstimatedEndTimeAttribute( + EstimatedEndTimeAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ESTIMATED_END_TIME_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ESTIMATED_END_TIME_ATTRIBUTE_ID, true); + } + + public void subscribeEstimatedEndTimeAttribute( + EstimatedEndTimeAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ESTIMATED_END_TIME_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ESTIMATED_END_TIME_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readProgressAttribute( + ProgressAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, PROGRESS_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, PROGRESS_ATTRIBUTE_ID, true); + } + + public void subscribeProgressAttribute( + ProgressAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, PROGRESS_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, PROGRESS_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readEventListAttribute( + EventListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeEventListAttribute( + EventListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAttributeListAttribute( + AttributeListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAttributeListAttribute( + AttributeListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readFeatureMapAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, true); + } + + public void subscribeFeatureMapAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readClusterRevisionAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, true); + } + + public void subscribeClusterRevisionAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, minInterval, maxInterval); + } + } + public static class PumpConfigurationAndControlCluster extends BaseChipCluster { public static final long CLUSTER_ID = 512L; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java index 426e73b9ab524a..c22d3593b9e87e 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java @@ -8686,6 +8686,401 @@ public String toString() { return output.toString(); } } +public static class ServiceAreaClusterHomeLocationStruct { + public String locationName; + public @Nullable Integer floorNumber; + public @Nullable Integer areaType; + private static final long LOCATION_NAME_ID = 0L; + private static final long FLOOR_NUMBER_ID = 1L; + private static final long AREA_TYPE_ID = 2L; + + public ServiceAreaClusterHomeLocationStruct( + String locationName, + @Nullable Integer floorNumber, + @Nullable Integer areaType + ) { + this.locationName = locationName; + this.floorNumber = floorNumber; + this.areaType = areaType; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(LOCATION_NAME_ID, new StringType(locationName))); + values.add(new StructElement(FLOOR_NUMBER_ID, floorNumber != null ? new IntType(floorNumber) : new NullType())); + values.add(new StructElement(AREA_TYPE_ID, areaType != null ? new UIntType(areaType) : new NullType())); + + return new StructType(values); + } + + public static ServiceAreaClusterHomeLocationStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + String locationName = null; + @Nullable Integer floorNumber = null; + @Nullable Integer areaType = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == LOCATION_NAME_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + locationName = castingValue.value(String.class); + } + } else if (element.contextTagNum() == FLOOR_NUMBER_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Int) { + IntType castingValue = element.value(IntType.class); + floorNumber = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == AREA_TYPE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + areaType = castingValue.value(Integer.class); + } + } + } + return new ServiceAreaClusterHomeLocationStruct( + locationName, + floorNumber, + areaType + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("ServiceAreaClusterHomeLocationStruct {\n"); + output.append("\tlocationName: "); + output.append(locationName); + output.append("\n"); + output.append("\tfloorNumber: "); + output.append(floorNumber); + output.append("\n"); + output.append("\tareaType: "); + output.append(areaType); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class ServiceAreaClusterLocationInfoStruct { + public @Nullable ChipStructs.ServiceAreaClusterHomeLocationStruct locationInfo; + public @Nullable Integer landmarkTag; + public @Nullable Integer positionTag; + public @Nullable Integer surfaceTag; + private static final long LOCATION_INFO_ID = 0L; + private static final long LANDMARK_TAG_ID = 1L; + private static final long POSITION_TAG_ID = 2L; + private static final long SURFACE_TAG_ID = 3L; + + public ServiceAreaClusterLocationInfoStruct( + @Nullable ChipStructs.ServiceAreaClusterHomeLocationStruct locationInfo, + @Nullable Integer landmarkTag, + @Nullable Integer positionTag, + @Nullable Integer surfaceTag + ) { + this.locationInfo = locationInfo; + this.landmarkTag = landmarkTag; + this.positionTag = positionTag; + this.surfaceTag = surfaceTag; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(LOCATION_INFO_ID, locationInfo != null ? locationInfo.encodeTlv() : new NullType())); + values.add(new StructElement(LANDMARK_TAG_ID, landmarkTag != null ? new UIntType(landmarkTag) : new NullType())); + values.add(new StructElement(POSITION_TAG_ID, positionTag != null ? new UIntType(positionTag) : new NullType())); + values.add(new StructElement(SURFACE_TAG_ID, surfaceTag != null ? new UIntType(surfaceTag) : new NullType())); + + return new StructType(values); + } + + public static ServiceAreaClusterLocationInfoStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + @Nullable ChipStructs.ServiceAreaClusterHomeLocationStruct locationInfo = null; + @Nullable Integer landmarkTag = null; + @Nullable Integer positionTag = null; + @Nullable Integer surfaceTag = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == LOCATION_INFO_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Struct) { + StructType castingValue = element.value(StructType.class); + locationInfo = ChipStructs.ServiceAreaClusterHomeLocationStruct.decodeTlv(castingValue); + } + } else if (element.contextTagNum() == LANDMARK_TAG_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + landmarkTag = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == POSITION_TAG_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + positionTag = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == SURFACE_TAG_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + surfaceTag = castingValue.value(Integer.class); + } + } + } + return new ServiceAreaClusterLocationInfoStruct( + locationInfo, + landmarkTag, + positionTag, + surfaceTag + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("ServiceAreaClusterLocationInfoStruct {\n"); + output.append("\tlocationInfo: "); + output.append(locationInfo); + output.append("\n"); + output.append("\tlandmarkTag: "); + output.append(landmarkTag); + output.append("\n"); + output.append("\tpositionTag: "); + output.append(positionTag); + output.append("\n"); + output.append("\tsurfaceTag: "); + output.append(surfaceTag); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class ServiceAreaClusterLocationStruct { + public Long locationID; + public @Nullable Integer mapID; + public ChipStructs.ServiceAreaClusterLocationInfoStruct locationInfo; + private static final long LOCATION_I_D_ID = 0L; + private static final long MAP_I_D_ID = 1L; + private static final long LOCATION_INFO_ID = 2L; + + public ServiceAreaClusterLocationStruct( + Long locationID, + @Nullable Integer mapID, + ChipStructs.ServiceAreaClusterLocationInfoStruct locationInfo + ) { + this.locationID = locationID; + this.mapID = mapID; + this.locationInfo = locationInfo; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(LOCATION_I_D_ID, new UIntType(locationID))); + values.add(new StructElement(MAP_I_D_ID, mapID != null ? new UIntType(mapID) : new NullType())); + values.add(new StructElement(LOCATION_INFO_ID, locationInfo.encodeTlv())); + + return new StructType(values); + } + + public static ServiceAreaClusterLocationStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Long locationID = null; + @Nullable Integer mapID = null; + ChipStructs.ServiceAreaClusterLocationInfoStruct locationInfo = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == LOCATION_I_D_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + locationID = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == MAP_I_D_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + mapID = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == LOCATION_INFO_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Struct) { + StructType castingValue = element.value(StructType.class); + locationInfo = ChipStructs.ServiceAreaClusterLocationInfoStruct.decodeTlv(castingValue); + } + } + } + return new ServiceAreaClusterLocationStruct( + locationID, + mapID, + locationInfo + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("ServiceAreaClusterLocationStruct {\n"); + output.append("\tlocationID: "); + output.append(locationID); + output.append("\n"); + output.append("\tmapID: "); + output.append(mapID); + output.append("\n"); + output.append("\tlocationInfo: "); + output.append(locationInfo); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class ServiceAreaClusterMapStruct { + public Integer mapID; + public String name; + private static final long MAP_I_D_ID = 0L; + private static final long NAME_ID = 1L; + + public ServiceAreaClusterMapStruct( + Integer mapID, + String name + ) { + this.mapID = mapID; + this.name = name; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(MAP_I_D_ID, new UIntType(mapID))); + values.add(new StructElement(NAME_ID, new StringType(name))); + + return new StructType(values); + } + + public static ServiceAreaClusterMapStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Integer mapID = null; + String name = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == MAP_I_D_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + mapID = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == NAME_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + name = castingValue.value(String.class); + } + } + } + return new ServiceAreaClusterMapStruct( + mapID, + name + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("ServiceAreaClusterMapStruct {\n"); + output.append("\tmapID: "); + output.append(mapID); + output.append("\n"); + output.append("\tname: "); + output.append(name); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class ServiceAreaClusterProgressStruct { + public Long locationID; + public Integer status; + public @Nullable Optional totalOperationalTime; + public @Nullable Optional estimatedTime; + private static final long LOCATION_I_D_ID = 0L; + private static final long STATUS_ID = 1L; + private static final long TOTAL_OPERATIONAL_TIME_ID = 2L; + private static final long ESTIMATED_TIME_ID = 3L; + + public ServiceAreaClusterProgressStruct( + Long locationID, + Integer status, + @Nullable Optional totalOperationalTime, + @Nullable Optional estimatedTime + ) { + this.locationID = locationID; + this.status = status; + this.totalOperationalTime = totalOperationalTime; + this.estimatedTime = estimatedTime; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(LOCATION_I_D_ID, new UIntType(locationID))); + values.add(new StructElement(STATUS_ID, new UIntType(status))); + values.add(new StructElement(TOTAL_OPERATIONAL_TIME_ID, totalOperationalTime != null ? totalOperationalTime.map((nonOptionaltotalOperationalTime) -> new UIntType(nonOptionaltotalOperationalTime)).orElse(new EmptyType()) : new NullType())); + values.add(new StructElement(ESTIMATED_TIME_ID, estimatedTime != null ? estimatedTime.map((nonOptionalestimatedTime) -> new UIntType(nonOptionalestimatedTime)).orElse(new EmptyType()) : new NullType())); + + return new StructType(values); + } + + public static ServiceAreaClusterProgressStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Long locationID = null; + Integer status = null; + @Nullable Optional totalOperationalTime = null; + @Nullable Optional estimatedTime = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == LOCATION_I_D_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + locationID = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == STATUS_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + status = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == TOTAL_OPERATIONAL_TIME_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + totalOperationalTime = Optional.of(castingValue.value(Long.class)); + } + } else if (element.contextTagNum() == ESTIMATED_TIME_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + estimatedTime = Optional.of(castingValue.value(Long.class)); + } + } + } + return new ServiceAreaClusterProgressStruct( + locationID, + status, + totalOperationalTime, + estimatedTime + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("ServiceAreaClusterProgressStruct {\n"); + output.append("\tlocationID: "); + output.append(locationID); + output.append("\n"); + output.append("\tstatus: "); + output.append(status); + output.append("\n"); + output.append("\ttotalOperationalTime: "); + output.append(totalOperationalTime); + output.append("\n"); + output.append("\testimatedTime: "); + output.append(estimatedTime); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} public static class ThermostatClusterScheduleTransitionStruct { public Integer dayOfWeek; public Integer transitionTime; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index df03516f3e4063..06f9941b772c21 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -262,6 +262,9 @@ public static BaseCluster getCluster(long clusterId) { if (clusterId == BarrierControl.ID) { return new BarrierControl(); } + if (clusterId == ServiceArea.ID) { + return new ServiceArea(); + } if (clusterId == PumpConfigurationAndControl.ID) { return new PumpConfigurationAndControl(); } @@ -11300,6 +11303,131 @@ public long getCommandID(String name) throws IllegalArgumentException { return Command.valueOf(name).getID(); } } + public static class ServiceArea implements BaseCluster { + public static final long ID = 336L; + public long getID() { + return ID; + } + + public enum Attribute { + SupportedLocations(0L), + SupportedMaps(1L), + SelectedLocations(2L), + CurrentLocation(3L), + EstimatedEndTime(4L), + Progress(5L), + GeneratedCommandList(65528L), + AcceptedCommandList(65529L), + EventList(65530L), + AttributeList(65531L), + FeatureMap(65532L), + ClusterRevision(65533L),; + private final long id; + Attribute(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Attribute value(long id) throws NoSuchFieldError { + for (Attribute attribute : Attribute.values()) { + if (attribute.getID() == id) { + return attribute; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Event {; + private final long id; + Event(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Event value(long id) throws NoSuchFieldError { + for (Event event : Event.values()) { + if (event.getID() == id) { + return event; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Command { + SelectLocations(0L), + SkipCurrentLocation(2L),; + private final long id; + Command(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Command value(long id) throws NoSuchFieldError { + for (Command command : Command.values()) { + if (command.getID() == id) { + return command; + } + } + throw new NoSuchFieldError(); + } + }public enum SelectLocationsCommandField {NewLocations(0),; + private final int id; + SelectLocationsCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static SelectLocationsCommandField value(int id) throws NoSuchFieldError { + for (SelectLocationsCommandField field : SelectLocationsCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }@Override + public String getAttributeName(long id) throws NoSuchFieldError { + return Attribute.value(id).toString(); + } + + @Override + public String getEventName(long id) throws NoSuchFieldError { + return Event.value(id).toString(); + } + + @Override + public String getCommandName(long id) throws NoSuchFieldError { + return Command.value(id).toString(); + } + + @Override + public long getAttributeID(String name) throws IllegalArgumentException { + return Attribute.valueOf(name).getID(); + } + + @Override + public long getEventID(String name) throws IllegalArgumentException { + return Event.valueOf(name).getID(); + } + + @Override + public long getCommandID(String name) throws IllegalArgumentException { + return Command.valueOf(name).getID(); + } + } public static class PumpConfigurationAndControl implements BaseCluster { public static final long ID = 512L; public long getID() { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 219baca838f58b..f4830c334b842f 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -12797,6 +12797,264 @@ public void onError(Exception ex) { } } + + public static class DelegatedServiceAreaClusterSelectLocationsResponseCallback implements ChipClusters.ServiceAreaCluster.SelectLocationsResponseCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(Integer status, Optional statusText) { + Map responseValues = new LinkedHashMap<>(); + + CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer"); + responseValues.put(statusResponseValue, status); + CommandResponseInfo statusTextResponseValue = new CommandResponseInfo("statusText", "Optional"); + responseValues.put(statusTextResponseValue, statusText); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } + + public static class DelegatedServiceAreaClusterSkipCurrentLocationResponseCallback implements ChipClusters.ServiceAreaCluster.SkipCurrentLocationResponseCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(Integer status, Optional statusText) { + Map responseValues = new LinkedHashMap<>(); + + CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer"); + responseValues.put(statusResponseValue, status); + CommandResponseInfo statusTextResponseValue = new CommandResponseInfo("statusText", "Optional"); + responseValues.put(statusTextResponseValue, statusText); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } + public static class DelegatedServiceAreaClusterSupportedLocationsAttributeCallback implements ChipClusters.ServiceAreaCluster.SupportedLocationsAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedServiceAreaClusterSupportedMapsAttributeCallback implements ChipClusters.ServiceAreaCluster.SupportedMapsAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedServiceAreaClusterSelectedLocationsAttributeCallback implements ChipClusters.ServiceAreaCluster.SelectedLocationsAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedServiceAreaClusterCurrentLocationAttributeCallback implements ChipClusters.ServiceAreaCluster.CurrentLocationAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable Long value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedServiceAreaClusterEstimatedEndTimeAttributeCallback implements ChipClusters.ServiceAreaCluster.EstimatedEndTimeAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable Long value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedServiceAreaClusterProgressAttributeCallback implements ChipClusters.ServiceAreaCluster.ProgressAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedServiceAreaClusterGeneratedCommandListAttributeCallback implements ChipClusters.ServiceAreaCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedServiceAreaClusterAcceptedCommandListAttributeCallback implements ChipClusters.ServiceAreaCluster.AcceptedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedServiceAreaClusterEventListAttributeCallback implements ChipClusters.ServiceAreaCluster.EventListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedServiceAreaClusterAttributeListAttributeCallback implements ChipClusters.ServiceAreaCluster.AttributeListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + public static class DelegatedPumpConfigurationAndControlClusterMaxPressureAttributeCallback implements ChipClusters.PumpConfigurationAndControlCluster.MaxPressureAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -21491,6 +21749,10 @@ public Map initializeClusterMap() { (ptr, endpointId) -> new ChipClusters.BarrierControlCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("barrierControl", barrierControlClusterInfo); + ClusterInfo serviceAreaClusterInfo = new ClusterInfo( + (ptr, endpointId) -> new ChipClusters.ServiceAreaCluster(ptr, endpointId), new HashMap<>()); + clusterMap.put("serviceArea", serviceAreaClusterInfo); + ClusterInfo pumpConfigurationAndControlClusterInfo = new ClusterInfo( (ptr, endpointId) -> new ChipClusters.PumpConfigurationAndControlCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("pumpConfigurationAndControl", pumpConfigurationAndControlClusterInfo); @@ -21745,6 +22007,7 @@ public void combineCommand(Map destination, Map> getCommandMap() { commandMap.put("barrierControl", barrierControlClusterInteractionInfoMap); + Map serviceAreaClusterInteractionInfoMap = new LinkedHashMap<>(); + + Map serviceAreaselectLocationsCommandParams = new LinkedHashMap(); + + CommandParameterInfo serviceAreaselectLocationsnewLocationsCommandParameterInfo = new CommandParameterInfo("newLocations", ArrayList.class, ArrayList.class); + serviceAreaselectLocationsCommandParams.put("newLocations",serviceAreaselectLocationsnewLocationsCommandParameterInfo); + InteractionInfo serviceAreaselectLocationsInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ServiceAreaCluster) cluster) + .selectLocations((ChipClusters.ServiceAreaCluster.SelectLocationsResponseCallback) callback + , (ArrayList) + commandArguments.get("newLocations") + + ); + }, + () -> new DelegatedServiceAreaClusterSelectLocationsResponseCallback(), + serviceAreaselectLocationsCommandParams + ); + serviceAreaClusterInteractionInfoMap.put("selectLocations", serviceAreaselectLocationsInteractionInfo); + + Map serviceAreaskipCurrentLocationCommandParams = new LinkedHashMap(); + InteractionInfo serviceAreaskipCurrentLocationInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ServiceAreaCluster) cluster) + .skipCurrentLocation((ChipClusters.ServiceAreaCluster.SkipCurrentLocationResponseCallback) callback + ); + }, + () -> new DelegatedServiceAreaClusterSkipCurrentLocationResponseCallback(), + serviceAreaskipCurrentLocationCommandParams + ); + serviceAreaClusterInteractionInfoMap.put("skipCurrentLocation", serviceAreaskipCurrentLocationInteractionInfo); + + commandMap.put("serviceArea", serviceAreaClusterInteractionInfoMap); + Map pumpConfigurationAndControlClusterInteractionInfoMap = new LinkedHashMap<>(); commandMap.put("pumpConfigurationAndControl", pumpConfigurationAndControlClusterInteractionInfoMap); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index 23261b74f09dbf..18cc03aa13a99f 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -11524,6 +11524,142 @@ private static Map readBarrierControlInteractionInfo() return result; } + private static Map readServiceAreaInteractionInfo() { + Map result = new LinkedHashMap<>();Map readServiceAreaSupportedLocationsCommandParams = new LinkedHashMap(); + InteractionInfo readServiceAreaSupportedLocationsAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ServiceAreaCluster) cluster).readSupportedLocationsAttribute( + (ChipClusters.ServiceAreaCluster.SupportedLocationsAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedServiceAreaClusterSupportedLocationsAttributeCallback(), + readServiceAreaSupportedLocationsCommandParams + ); + result.put("readSupportedLocationsAttribute", readServiceAreaSupportedLocationsAttributeInteractionInfo); + Map readServiceAreaSupportedMapsCommandParams = new LinkedHashMap(); + InteractionInfo readServiceAreaSupportedMapsAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ServiceAreaCluster) cluster).readSupportedMapsAttribute( + (ChipClusters.ServiceAreaCluster.SupportedMapsAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedServiceAreaClusterSupportedMapsAttributeCallback(), + readServiceAreaSupportedMapsCommandParams + ); + result.put("readSupportedMapsAttribute", readServiceAreaSupportedMapsAttributeInteractionInfo); + Map readServiceAreaSelectedLocationsCommandParams = new LinkedHashMap(); + InteractionInfo readServiceAreaSelectedLocationsAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ServiceAreaCluster) cluster).readSelectedLocationsAttribute( + (ChipClusters.ServiceAreaCluster.SelectedLocationsAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedServiceAreaClusterSelectedLocationsAttributeCallback(), + readServiceAreaSelectedLocationsCommandParams + ); + result.put("readSelectedLocationsAttribute", readServiceAreaSelectedLocationsAttributeInteractionInfo); + Map readServiceAreaCurrentLocationCommandParams = new LinkedHashMap(); + InteractionInfo readServiceAreaCurrentLocationAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ServiceAreaCluster) cluster).readCurrentLocationAttribute( + (ChipClusters.ServiceAreaCluster.CurrentLocationAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedServiceAreaClusterCurrentLocationAttributeCallback(), + readServiceAreaCurrentLocationCommandParams + ); + result.put("readCurrentLocationAttribute", readServiceAreaCurrentLocationAttributeInteractionInfo); + Map readServiceAreaEstimatedEndTimeCommandParams = new LinkedHashMap(); + InteractionInfo readServiceAreaEstimatedEndTimeAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ServiceAreaCluster) cluster).readEstimatedEndTimeAttribute( + (ChipClusters.ServiceAreaCluster.EstimatedEndTimeAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedServiceAreaClusterEstimatedEndTimeAttributeCallback(), + readServiceAreaEstimatedEndTimeCommandParams + ); + result.put("readEstimatedEndTimeAttribute", readServiceAreaEstimatedEndTimeAttributeInteractionInfo); + Map readServiceAreaProgressCommandParams = new LinkedHashMap(); + InteractionInfo readServiceAreaProgressAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ServiceAreaCluster) cluster).readProgressAttribute( + (ChipClusters.ServiceAreaCluster.ProgressAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedServiceAreaClusterProgressAttributeCallback(), + readServiceAreaProgressCommandParams + ); + result.put("readProgressAttribute", readServiceAreaProgressAttributeInteractionInfo); + Map readServiceAreaGeneratedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readServiceAreaGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ServiceAreaCluster) cluster).readGeneratedCommandListAttribute( + (ChipClusters.ServiceAreaCluster.GeneratedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedServiceAreaClusterGeneratedCommandListAttributeCallback(), + readServiceAreaGeneratedCommandListCommandParams + ); + result.put("readGeneratedCommandListAttribute", readServiceAreaGeneratedCommandListAttributeInteractionInfo); + Map readServiceAreaAcceptedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readServiceAreaAcceptedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ServiceAreaCluster) cluster).readAcceptedCommandListAttribute( + (ChipClusters.ServiceAreaCluster.AcceptedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedServiceAreaClusterAcceptedCommandListAttributeCallback(), + readServiceAreaAcceptedCommandListCommandParams + ); + result.put("readAcceptedCommandListAttribute", readServiceAreaAcceptedCommandListAttributeInteractionInfo); + Map readServiceAreaEventListCommandParams = new LinkedHashMap(); + InteractionInfo readServiceAreaEventListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ServiceAreaCluster) cluster).readEventListAttribute( + (ChipClusters.ServiceAreaCluster.EventListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedServiceAreaClusterEventListAttributeCallback(), + readServiceAreaEventListCommandParams + ); + result.put("readEventListAttribute", readServiceAreaEventListAttributeInteractionInfo); + Map readServiceAreaAttributeListCommandParams = new LinkedHashMap(); + InteractionInfo readServiceAreaAttributeListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ServiceAreaCluster) cluster).readAttributeListAttribute( + (ChipClusters.ServiceAreaCluster.AttributeListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedServiceAreaClusterAttributeListAttributeCallback(), + readServiceAreaAttributeListCommandParams + ); + result.put("readAttributeListAttribute", readServiceAreaAttributeListAttributeInteractionInfo); + Map readServiceAreaFeatureMapCommandParams = new LinkedHashMap(); + InteractionInfo readServiceAreaFeatureMapAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ServiceAreaCluster) cluster).readFeatureMapAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readServiceAreaFeatureMapCommandParams + ); + result.put("readFeatureMapAttribute", readServiceAreaFeatureMapAttributeInteractionInfo); + Map readServiceAreaClusterRevisionCommandParams = new LinkedHashMap(); + InteractionInfo readServiceAreaClusterRevisionAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.ServiceAreaCluster) cluster).readClusterRevisionAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readServiceAreaClusterRevisionCommandParams + ); + result.put("readClusterRevisionAttribute", readServiceAreaClusterRevisionAttributeInteractionInfo); + + return result; + } private static Map readPumpConfigurationAndControlInteractionInfo() { Map result = new LinkedHashMap<>();Map readPumpConfigurationAndControlMaxPressureCommandParams = new LinkedHashMap(); InteractionInfo readPumpConfigurationAndControlMaxPressureAttributeInteractionInfo = new InteractionInfo( @@ -20864,6 +21000,7 @@ public Map> getReadAttributeMap() { put("doorLock", readDoorLockInteractionInfo()); put("windowCovering", readWindowCoveringInteractionInfo()); put("barrierControl", readBarrierControlInteractionInfo()); + put("serviceArea", readServiceAreaInteractionInfo()); put("pumpConfigurationAndControl", readPumpConfigurationAndControlInteractionInfo()); put("thermostat", readThermostatInteractionInfo()); put("fanControl", readFanControlInteractionInfo()); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java index 948e665b63da72..bd73d50f14c538 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java @@ -2008,6 +2008,8 @@ public Map> getWriteAttributeMap() { ); writeBarrierControlInteractionInfo.put("writeBarrierClosePeriodAttribute", writeBarrierControlBarrierClosePeriodAttributeInteractionInfo); writeAttributeMap.put("barrierControl", writeBarrierControlInteractionInfo); + Map writeServiceAreaInteractionInfo = new LinkedHashMap<>(); + writeAttributeMap.put("serviceArea", writeServiceAreaInteractionInfo); Map writePumpConfigurationAndControlInteractionInfo = new LinkedHashMap<>(); Map writePumpConfigurationAndControlLifetimeRunningHoursCommandParams = new LinkedHashMap(); CommandParameterInfo pumpConfigurationAndControllifetimeRunningHoursCommandParameterInfo = diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni index a5f7518b9c8766..c5c5d5e1adbb0d 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni @@ -115,6 +115,11 @@ structs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ScenesManagementClusterAttributeValuePair.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ScenesManagementClusterExtensionFieldSet.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ScenesManagementClusterSceneInfoStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterMapStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterProgressStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/SoftwareDiagnosticsClusterThreadMetricsStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/TargetNavigatorClusterTargetInfoStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThermostatClusterPresetStruct.kt", diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt new file mode 100644 index 00000000000000..7262fc9102917c --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt @@ -0,0 +1,84 @@ +/* + * + * 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. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ServiceAreaClusterHomeLocationStruct( + val locationName: String, + val floorNumber: Int?, + val areaType: UInt? +) { + override fun toString(): String = buildString { + append("ServiceAreaClusterHomeLocationStruct {\n") + append("\tlocationName : $locationName\n") + append("\tfloorNumber : $floorNumber\n") + append("\tareaType : $areaType\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_LOCATION_NAME), locationName) + if (floorNumber != null) { + put(ContextSpecificTag(TAG_FLOOR_NUMBER), floorNumber) + } else { + putNull(ContextSpecificTag(TAG_FLOOR_NUMBER)) + } + if (areaType != null) { + put(ContextSpecificTag(TAG_AREA_TYPE), areaType) + } else { + putNull(ContextSpecificTag(TAG_AREA_TYPE)) + } + endStructure() + } + } + + companion object { + private const val TAG_LOCATION_NAME = 0 + private const val TAG_FLOOR_NUMBER = 1 + private const val TAG_AREA_TYPE = 2 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterHomeLocationStruct { + tlvReader.enterStructure(tlvTag) + val locationName = tlvReader.getString(ContextSpecificTag(TAG_LOCATION_NAME)) + val floorNumber = + if (!tlvReader.isNull()) { + tlvReader.getInt(ContextSpecificTag(TAG_FLOOR_NUMBER)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_FLOOR_NUMBER)) + null + } + val areaType = + if (!tlvReader.isNull()) { + tlvReader.getUInt(ContextSpecificTag(TAG_AREA_TYPE)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_AREA_TYPE)) + null + } + + tlvReader.exitContainer() + + return ServiceAreaClusterHomeLocationStruct(locationName, floorNumber, areaType) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt new file mode 100644 index 00000000000000..4ddb164dd98834 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt @@ -0,0 +1,117 @@ +/* + * + * 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. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ServiceAreaClusterLocationInfoStruct( + val locationInfo: ServiceAreaClusterHomeLocationStruct?, + val landmarkTag: UInt?, + val positionTag: UInt?, + val surfaceTag: UInt? +) { + override fun toString(): String = buildString { + append("ServiceAreaClusterLocationInfoStruct {\n") + append("\tlocationInfo : $locationInfo\n") + append("\tlandmarkTag : $landmarkTag\n") + append("\tpositionTag : $positionTag\n") + append("\tsurfaceTag : $surfaceTag\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + if (locationInfo != null) { + locationInfo.toTlv(ContextSpecificTag(TAG_LOCATION_INFO), this) + } else { + putNull(ContextSpecificTag(TAG_LOCATION_INFO)) + } + if (landmarkTag != null) { + put(ContextSpecificTag(TAG_LANDMARK_TAG), landmarkTag) + } else { + putNull(ContextSpecificTag(TAG_LANDMARK_TAG)) + } + if (positionTag != null) { + put(ContextSpecificTag(TAG_POSITION_TAG), positionTag) + } else { + putNull(ContextSpecificTag(TAG_POSITION_TAG)) + } + if (surfaceTag != null) { + put(ContextSpecificTag(TAG_SURFACE_TAG), surfaceTag) + } else { + putNull(ContextSpecificTag(TAG_SURFACE_TAG)) + } + endStructure() + } + } + + companion object { + private const val TAG_LOCATION_INFO = 0 + private const val TAG_LANDMARK_TAG = 1 + private const val TAG_POSITION_TAG = 2 + private const val TAG_SURFACE_TAG = 3 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterLocationInfoStruct { + tlvReader.enterStructure(tlvTag) + val locationInfo = + if (!tlvReader.isNull()) { + ServiceAreaClusterHomeLocationStruct.fromTlv( + ContextSpecificTag(TAG_LOCATION_INFO), + tlvReader + ) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_LOCATION_INFO)) + null + } + val landmarkTag = + if (!tlvReader.isNull()) { + tlvReader.getUInt(ContextSpecificTag(TAG_LANDMARK_TAG)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_LANDMARK_TAG)) + null + } + val positionTag = + if (!tlvReader.isNull()) { + tlvReader.getUInt(ContextSpecificTag(TAG_POSITION_TAG)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_POSITION_TAG)) + null + } + val surfaceTag = + if (!tlvReader.isNull()) { + tlvReader.getUInt(ContextSpecificTag(TAG_SURFACE_TAG)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_SURFACE_TAG)) + null + } + + tlvReader.exitContainer() + + return ServiceAreaClusterLocationInfoStruct( + locationInfo, + landmarkTag, + positionTag, + surfaceTag + ) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationStruct.kt new file mode 100644 index 00000000000000..1e34a8c330b656 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationStruct.kt @@ -0,0 +1,78 @@ +/* + * + * 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. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ServiceAreaClusterLocationStruct( + val locationID: ULong, + val mapID: UInt?, + val locationInfo: ServiceAreaClusterLocationInfoStruct +) { + override fun toString(): String = buildString { + append("ServiceAreaClusterLocationStruct {\n") + append("\tlocationID : $locationID\n") + append("\tmapID : $mapID\n") + append("\tlocationInfo : $locationInfo\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_LOCATION_I_D), locationID) + if (mapID != null) { + put(ContextSpecificTag(TAG_MAP_I_D), mapID) + } else { + putNull(ContextSpecificTag(TAG_MAP_I_D)) + } + locationInfo.toTlv(ContextSpecificTag(TAG_LOCATION_INFO), this) + endStructure() + } + } + + companion object { + private const val TAG_LOCATION_I_D = 0 + private const val TAG_MAP_I_D = 1 + private const val TAG_LOCATION_INFO = 2 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterLocationStruct { + tlvReader.enterStructure(tlvTag) + val locationID = tlvReader.getULong(ContextSpecificTag(TAG_LOCATION_I_D)) + val mapID = + if (!tlvReader.isNull()) { + tlvReader.getUInt(ContextSpecificTag(TAG_MAP_I_D)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_MAP_I_D)) + null + } + val locationInfo = + ServiceAreaClusterLocationInfoStruct.fromTlv( + ContextSpecificTag(TAG_LOCATION_INFO), + tlvReader + ) + + tlvReader.exitContainer() + + return ServiceAreaClusterLocationStruct(locationID, mapID, locationInfo) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterMapStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterMapStruct.kt new file mode 100644 index 00000000000000..377ab13f0e9130 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterMapStruct.kt @@ -0,0 +1,56 @@ +/* + * + * 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. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ServiceAreaClusterMapStruct(val mapID: UInt, val name: String) { + override fun toString(): String = buildString { + append("ServiceAreaClusterMapStruct {\n") + append("\tmapID : $mapID\n") + append("\tname : $name\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_MAP_I_D), mapID) + put(ContextSpecificTag(TAG_NAME), name) + endStructure() + } + } + + companion object { + private const val TAG_MAP_I_D = 0 + private const val TAG_NAME = 1 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterMapStruct { + tlvReader.enterStructure(tlvTag) + val mapID = tlvReader.getUInt(ContextSpecificTag(TAG_MAP_I_D)) + val name = tlvReader.getString(ContextSpecificTag(TAG_NAME)) + + tlvReader.exitContainer() + + return ServiceAreaClusterMapStruct(mapID, name) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterProgressStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterProgressStruct.kt new file mode 100644 index 00000000000000..d65a0faa19c1a2 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterProgressStruct.kt @@ -0,0 +1,109 @@ +/* + * + * 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. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import java.util.Optional +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ServiceAreaClusterProgressStruct( + val locationID: ULong, + val status: UInt, + val totalOperationalTime: Optional?, + val estimatedTime: Optional? +) { + override fun toString(): String = buildString { + append("ServiceAreaClusterProgressStruct {\n") + append("\tlocationID : $locationID\n") + append("\tstatus : $status\n") + append("\ttotalOperationalTime : $totalOperationalTime\n") + append("\testimatedTime : $estimatedTime\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_LOCATION_I_D), locationID) + put(ContextSpecificTag(TAG_STATUS), status) + if (totalOperationalTime != null) { + if (totalOperationalTime.isPresent) { + val opttotalOperationalTime = totalOperationalTime.get() + put(ContextSpecificTag(TAG_TOTAL_OPERATIONAL_TIME), opttotalOperationalTime) + } + } else { + putNull(ContextSpecificTag(TAG_TOTAL_OPERATIONAL_TIME)) + } + if (estimatedTime != null) { + if (estimatedTime.isPresent) { + val optestimatedTime = estimatedTime.get() + put(ContextSpecificTag(TAG_ESTIMATED_TIME), optestimatedTime) + } + } else { + putNull(ContextSpecificTag(TAG_ESTIMATED_TIME)) + } + endStructure() + } + } + + companion object { + private const val TAG_LOCATION_I_D = 0 + private const val TAG_STATUS = 1 + private const val TAG_TOTAL_OPERATIONAL_TIME = 2 + private const val TAG_ESTIMATED_TIME = 3 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterProgressStruct { + tlvReader.enterStructure(tlvTag) + val locationID = tlvReader.getULong(ContextSpecificTag(TAG_LOCATION_I_D)) + val status = tlvReader.getUInt(ContextSpecificTag(TAG_STATUS)) + val totalOperationalTime = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(ContextSpecificTag(TAG_TOTAL_OPERATIONAL_TIME))) { + Optional.of(tlvReader.getULong(ContextSpecificTag(TAG_TOTAL_OPERATIONAL_TIME))) + } else { + Optional.empty() + } + } else { + tlvReader.getNull(ContextSpecificTag(TAG_TOTAL_OPERATIONAL_TIME)) + null + } + val estimatedTime = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(ContextSpecificTag(TAG_ESTIMATED_TIME))) { + Optional.of(tlvReader.getULong(ContextSpecificTag(TAG_ESTIMATED_TIME))) + } else { + Optional.empty() + } + } else { + tlvReader.getNull(ContextSpecificTag(TAG_ESTIMATED_TIME)) + null + } + + tlvReader.exitContainer() + + return ServiceAreaClusterProgressStruct( + locationID, + status, + totalOperationalTime, + estimatedTime + ) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/ServiceAreaCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/ServiceAreaCluster.kt new file mode 100644 index 00000000000000..11203b5f2a99b7 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/ServiceAreaCluster.kt @@ -0,0 +1,1460 @@ +/* + * + * 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. + */ + +package matter.controller.cluster.clusters + +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.transform +import matter.controller.InvokeRequest +import matter.controller.InvokeResponse +import matter.controller.MatterController +import matter.controller.ReadData +import matter.controller.ReadRequest +import matter.controller.SubscribeRequest +import matter.controller.SubscriptionState +import matter.controller.UIntSubscriptionState +import matter.controller.UShortSubscriptionState +import matter.controller.cluster.structs.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ServiceAreaCluster(private val controller: MatterController, private val endpointId: UShort) { + class SelectLocationsResponse(val status: UByte, val statusText: String?) + + class SkipCurrentLocationResponse(val status: UByte, val statusText: String?) + + class SupportedLocationsAttribute(val value: List) + + sealed class SupportedLocationsAttributeSubscriptionState { + data class Success(val value: List) : + SupportedLocationsAttributeSubscriptionState() + + data class Error(val exception: Exception) : SupportedLocationsAttributeSubscriptionState() + + object SubscriptionEstablished : SupportedLocationsAttributeSubscriptionState() + } + + class SupportedMapsAttribute(val value: List?) + + sealed class SupportedMapsAttributeSubscriptionState { + data class Success(val value: List?) : + SupportedMapsAttributeSubscriptionState() + + data class Error(val exception: Exception) : SupportedMapsAttributeSubscriptionState() + + object SubscriptionEstablished : SupportedMapsAttributeSubscriptionState() + } + + class SelectedLocationsAttribute(val value: List?) + + sealed class SelectedLocationsAttributeSubscriptionState { + data class Success(val value: List?) : SelectedLocationsAttributeSubscriptionState() + + data class Error(val exception: Exception) : SelectedLocationsAttributeSubscriptionState() + + object SubscriptionEstablished : SelectedLocationsAttributeSubscriptionState() + } + + class CurrentLocationAttribute(val value: UInt?) + + sealed class CurrentLocationAttributeSubscriptionState { + data class Success(val value: UInt?) : CurrentLocationAttributeSubscriptionState() + + data class Error(val exception: Exception) : CurrentLocationAttributeSubscriptionState() + + object SubscriptionEstablished : CurrentLocationAttributeSubscriptionState() + } + + class EstimatedEndTimeAttribute(val value: UInt?) + + sealed class EstimatedEndTimeAttributeSubscriptionState { + data class Success(val value: UInt?) : EstimatedEndTimeAttributeSubscriptionState() + + data class Error(val exception: Exception) : EstimatedEndTimeAttributeSubscriptionState() + + object SubscriptionEstablished : EstimatedEndTimeAttributeSubscriptionState() + } + + class ProgressAttribute(val value: List?) + + sealed class ProgressAttributeSubscriptionState { + data class Success(val value: List?) : + ProgressAttributeSubscriptionState() + + data class Error(val exception: Exception) : ProgressAttributeSubscriptionState() + + object SubscriptionEstablished : ProgressAttributeSubscriptionState() + } + + class GeneratedCommandListAttribute(val value: List) + + sealed class GeneratedCommandListAttributeSubscriptionState { + data class Success(val value: List) : GeneratedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : GeneratedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : GeneratedCommandListAttributeSubscriptionState() + } + + class AcceptedCommandListAttribute(val value: List) + + sealed class AcceptedCommandListAttributeSubscriptionState { + data class Success(val value: List) : AcceptedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AcceptedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : AcceptedCommandListAttributeSubscriptionState() + } + + class EventListAttribute(val value: List) + + sealed class EventListAttributeSubscriptionState { + data class Success(val value: List) : EventListAttributeSubscriptionState() + + data class Error(val exception: Exception) : EventListAttributeSubscriptionState() + + object SubscriptionEstablished : EventListAttributeSubscriptionState() + } + + class AttributeListAttribute(val value: List) + + sealed class AttributeListAttributeSubscriptionState { + data class Success(val value: List) : AttributeListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AttributeListAttributeSubscriptionState() + + object SubscriptionEstablished : AttributeListAttributeSubscriptionState() + } + + suspend fun selectLocations( + newLocations: List?, + timedInvokeTimeout: Duration? = null + ): SelectLocationsResponse { + val commandId: UInt = 0u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NEW_LOCATIONS_REQ: Int = 0 + newLocations?.let { + tlvWriter.startArray(ContextSpecificTag(TAG_NEW_LOCATIONS_REQ)) + for (item in newLocations.iterator()) { + tlvWriter.put(AnonymousTag, item) + } + tlvWriter.endArray() + } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_STATUS_TEXT: Int = 1 + var statusText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_STATUS_TEXT)) { + statusText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + tlvReader.skipElement() + } + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } + + tlvReader.exitContainer() + + return SelectLocationsResponse(status_decoded, statusText_decoded) + } + + suspend fun skipCurrentLocation( + timedInvokeTimeout: Duration? = null + ): SkipCurrentLocationResponse { + val commandId: UInt = 2u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_STATUS_TEXT: Int = 1 + var statusText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_STATUS_TEXT)) { + statusText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + tlvReader.skipElement() + } + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } + + tlvReader.exitContainer() + + return SkipCurrentLocationResponse(status_decoded, statusText_decoded) + } + + suspend fun readSupportedLocationsAttribute(): SupportedLocationsAttribute { + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedlocations attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ServiceAreaClusterLocationStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return SupportedLocationsAttribute(decodedValue) + } + + suspend fun subscribeSupportedLocationsAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 0u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + SupportedLocationsAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Supportedlocations attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ServiceAreaClusterLocationStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + emit(SupportedLocationsAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(SupportedLocationsAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readSupportedMapsAttribute(): SupportedMapsAttribute { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedmaps attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (!tlvReader.isNull()) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ServiceAreaClusterMapStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return SupportedMapsAttribute(decodedValue) + } + + suspend fun subscribeSupportedMapsAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 1u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + SupportedMapsAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Supportedmaps attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (!tlvReader.isNull()) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ServiceAreaClusterMapStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(SupportedMapsAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(SupportedMapsAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readSelectedLocationsAttribute(): SelectedLocationsAttribute { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Selectedlocations attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (!tlvReader.isNull()) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return SelectedLocationsAttribute(decodedValue) + } + + suspend fun subscribeSelectedLocationsAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 2u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + SelectedLocationsAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Selectedlocations attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (!tlvReader.isNull()) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(SelectedLocationsAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(SelectedLocationsAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readCurrentLocationAttribute(): CurrentLocationAttribute { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentlocation attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return CurrentLocationAttribute(decodedValue) + } + + suspend fun subscribeCurrentLocationAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 3u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + CurrentLocationAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Currentlocation attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(CurrentLocationAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(CurrentLocationAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readEstimatedEndTimeAttribute(): EstimatedEndTimeAttribute { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Estimatedendtime attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return EstimatedEndTimeAttribute(decodedValue) + } + + suspend fun subscribeEstimatedEndTimeAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 4u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + EstimatedEndTimeAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Estimatedendtime attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(EstimatedEndTimeAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(EstimatedEndTimeAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readProgressAttribute(): ProgressAttribute { + val ATTRIBUTE_ID: UInt = 5u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Progress attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ServiceAreaClusterProgressStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return ProgressAttribute(decodedValue) + } + + suspend fun subscribeProgressAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 5u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + ProgressAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Progress attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(ServiceAreaClusterProgressStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(ProgressAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(ProgressAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) + } + + suspend fun subscribeGeneratedCommandListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65528u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + GeneratedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Generatedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(GeneratedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(GeneratedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) + } + + suspend fun subscribeAcceptedCommandListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65529u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AcceptedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Acceptedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AcceptedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AcceptedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readEventListAttribute(): EventListAttribute { + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) + } + + suspend fun subscribeEventListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65530u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + EventListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Eventlist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(EventListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(EventListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAttributeListAttribute(): AttributeListAttribute { + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) + } + + suspend fun subscribeAttributeListAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65531u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AttributeListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Attributelist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AttributeListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AttributeListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readFeatureMapAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeFeatureMapAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65532u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UIntSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Featuremap attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + emit(UIntSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UIntSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readClusterRevisionAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeClusterRevisionAttribute( + minInterval: Int, + maxInterval: Int + ): Flow { + val ATTRIBUTE_ID: UInt = 65533u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()) + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UShortSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Clusterrevision attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + emit(UShortSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UShortSubscriptionState.SubscriptionEstablished) + } + } + } + } + + companion object { + private val logger = Logger.getLogger(ServiceAreaCluster::class.java.name) + const val CLUSTER_ID: UInt = 336u + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/files.gni b/src/controller/java/generated/java/matter/controller/cluster/files.gni index ff3afa7d53e5fd..4485a760e2b427 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/files.gni +++ b/src/controller/java/generated/java/matter/controller/cluster/files.gni @@ -115,6 +115,11 @@ matter_structs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ScenesManagementClusterAttributeValuePair.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ScenesManagementClusterExtensionFieldSet.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ScenesManagementClusterSceneInfoStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterMapStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterProgressStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/SoftwareDiagnosticsClusterThreadMetricsStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/TargetNavigatorClusterTargetInfoStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThermostatClusterPresetStruct.kt", @@ -325,6 +330,7 @@ matter_clusters_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/RvcRunModeCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/SampleMeiCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ScenesManagementCluster.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ServiceAreaCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/SmokeCoAlarmCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/SoftwareDiagnosticsCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/SwitchCluster.kt", diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt new file mode 100644 index 00000000000000..5af3730a4460a8 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt @@ -0,0 +1,84 @@ +/* + * + * 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. + */ +package matter.controller.cluster.structs + +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ServiceAreaClusterHomeLocationStruct( + val locationName: String, + val floorNumber: Short?, + val areaType: UByte? +) { + override fun toString(): String = buildString { + append("ServiceAreaClusterHomeLocationStruct {\n") + append("\tlocationName : $locationName\n") + append("\tfloorNumber : $floorNumber\n") + append("\tareaType : $areaType\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_LOCATION_NAME), locationName) + if (floorNumber != null) { + put(ContextSpecificTag(TAG_FLOOR_NUMBER), floorNumber) + } else { + putNull(ContextSpecificTag(TAG_FLOOR_NUMBER)) + } + if (areaType != null) { + put(ContextSpecificTag(TAG_AREA_TYPE), areaType) + } else { + putNull(ContextSpecificTag(TAG_AREA_TYPE)) + } + endStructure() + } + } + + companion object { + private const val TAG_LOCATION_NAME = 0 + private const val TAG_FLOOR_NUMBER = 1 + private const val TAG_AREA_TYPE = 2 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterHomeLocationStruct { + tlvReader.enterStructure(tlvTag) + val locationName = tlvReader.getString(ContextSpecificTag(TAG_LOCATION_NAME)) + val floorNumber = + if (!tlvReader.isNull()) { + tlvReader.getShort(ContextSpecificTag(TAG_FLOOR_NUMBER)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_FLOOR_NUMBER)) + null + } + val areaType = + if (!tlvReader.isNull()) { + tlvReader.getUByte(ContextSpecificTag(TAG_AREA_TYPE)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_AREA_TYPE)) + null + } + + tlvReader.exitContainer() + + return ServiceAreaClusterHomeLocationStruct(locationName, floorNumber, areaType) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt new file mode 100644 index 00000000000000..c53b65c2dbb22f --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt @@ -0,0 +1,117 @@ +/* + * + * 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. + */ +package matter.controller.cluster.structs + +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ServiceAreaClusterLocationInfoStruct( + val locationInfo: ServiceAreaClusterHomeLocationStruct?, + val landmarkTag: UByte?, + val positionTag: UByte?, + val surfaceTag: UByte? +) { + override fun toString(): String = buildString { + append("ServiceAreaClusterLocationInfoStruct {\n") + append("\tlocationInfo : $locationInfo\n") + append("\tlandmarkTag : $landmarkTag\n") + append("\tpositionTag : $positionTag\n") + append("\tsurfaceTag : $surfaceTag\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + if (locationInfo != null) { + locationInfo.toTlv(ContextSpecificTag(TAG_LOCATION_INFO), this) + } else { + putNull(ContextSpecificTag(TAG_LOCATION_INFO)) + } + if (landmarkTag != null) { + put(ContextSpecificTag(TAG_LANDMARK_TAG), landmarkTag) + } else { + putNull(ContextSpecificTag(TAG_LANDMARK_TAG)) + } + if (positionTag != null) { + put(ContextSpecificTag(TAG_POSITION_TAG), positionTag) + } else { + putNull(ContextSpecificTag(TAG_POSITION_TAG)) + } + if (surfaceTag != null) { + put(ContextSpecificTag(TAG_SURFACE_TAG), surfaceTag) + } else { + putNull(ContextSpecificTag(TAG_SURFACE_TAG)) + } + endStructure() + } + } + + companion object { + private const val TAG_LOCATION_INFO = 0 + private const val TAG_LANDMARK_TAG = 1 + private const val TAG_POSITION_TAG = 2 + private const val TAG_SURFACE_TAG = 3 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterLocationInfoStruct { + tlvReader.enterStructure(tlvTag) + val locationInfo = + if (!tlvReader.isNull()) { + ServiceAreaClusterHomeLocationStruct.fromTlv( + ContextSpecificTag(TAG_LOCATION_INFO), + tlvReader + ) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_LOCATION_INFO)) + null + } + val landmarkTag = + if (!tlvReader.isNull()) { + tlvReader.getUByte(ContextSpecificTag(TAG_LANDMARK_TAG)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_LANDMARK_TAG)) + null + } + val positionTag = + if (!tlvReader.isNull()) { + tlvReader.getUByte(ContextSpecificTag(TAG_POSITION_TAG)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_POSITION_TAG)) + null + } + val surfaceTag = + if (!tlvReader.isNull()) { + tlvReader.getUByte(ContextSpecificTag(TAG_SURFACE_TAG)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_SURFACE_TAG)) + null + } + + tlvReader.exitContainer() + + return ServiceAreaClusterLocationInfoStruct( + locationInfo, + landmarkTag, + positionTag, + surfaceTag + ) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationStruct.kt new file mode 100644 index 00000000000000..0a5b5aa3a825b4 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationStruct.kt @@ -0,0 +1,78 @@ +/* + * + * 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. + */ +package matter.controller.cluster.structs + +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ServiceAreaClusterLocationStruct( + val locationID: UInt, + val mapID: UByte?, + val locationInfo: ServiceAreaClusterLocationInfoStruct +) { + override fun toString(): String = buildString { + append("ServiceAreaClusterLocationStruct {\n") + append("\tlocationID : $locationID\n") + append("\tmapID : $mapID\n") + append("\tlocationInfo : $locationInfo\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_LOCATION_I_D), locationID) + if (mapID != null) { + put(ContextSpecificTag(TAG_MAP_I_D), mapID) + } else { + putNull(ContextSpecificTag(TAG_MAP_I_D)) + } + locationInfo.toTlv(ContextSpecificTag(TAG_LOCATION_INFO), this) + endStructure() + } + } + + companion object { + private const val TAG_LOCATION_I_D = 0 + private const val TAG_MAP_I_D = 1 + private const val TAG_LOCATION_INFO = 2 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterLocationStruct { + tlvReader.enterStructure(tlvTag) + val locationID = tlvReader.getUInt(ContextSpecificTag(TAG_LOCATION_I_D)) + val mapID = + if (!tlvReader.isNull()) { + tlvReader.getUByte(ContextSpecificTag(TAG_MAP_I_D)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_MAP_I_D)) + null + } + val locationInfo = + ServiceAreaClusterLocationInfoStruct.fromTlv( + ContextSpecificTag(TAG_LOCATION_INFO), + tlvReader + ) + + tlvReader.exitContainer() + + return ServiceAreaClusterLocationStruct(locationID, mapID, locationInfo) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterMapStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterMapStruct.kt new file mode 100644 index 00000000000000..3109c9bcb82b76 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterMapStruct.kt @@ -0,0 +1,56 @@ +/* + * + * 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. + */ +package matter.controller.cluster.structs + +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ServiceAreaClusterMapStruct(val mapID: UByte, val name: String) { + override fun toString(): String = buildString { + append("ServiceAreaClusterMapStruct {\n") + append("\tmapID : $mapID\n") + append("\tname : $name\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_MAP_I_D), mapID) + put(ContextSpecificTag(TAG_NAME), name) + endStructure() + } + } + + companion object { + private const val TAG_MAP_I_D = 0 + private const val TAG_NAME = 1 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterMapStruct { + tlvReader.enterStructure(tlvTag) + val mapID = tlvReader.getUByte(ContextSpecificTag(TAG_MAP_I_D)) + val name = tlvReader.getString(ContextSpecificTag(TAG_NAME)) + + tlvReader.exitContainer() + + return ServiceAreaClusterMapStruct(mapID, name) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterProgressStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterProgressStruct.kt new file mode 100644 index 00000000000000..a5dac6e470d299 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterProgressStruct.kt @@ -0,0 +1,109 @@ +/* + * + * 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. + */ +package matter.controller.cluster.structs + +import java.util.Optional +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class ServiceAreaClusterProgressStruct( + val locationID: UInt, + val status: UByte, + val totalOperationalTime: Optional?, + val estimatedTime: Optional? +) { + override fun toString(): String = buildString { + append("ServiceAreaClusterProgressStruct {\n") + append("\tlocationID : $locationID\n") + append("\tstatus : $status\n") + append("\ttotalOperationalTime : $totalOperationalTime\n") + append("\testimatedTime : $estimatedTime\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_LOCATION_I_D), locationID) + put(ContextSpecificTag(TAG_STATUS), status) + if (totalOperationalTime != null) { + if (totalOperationalTime.isPresent) { + val opttotalOperationalTime = totalOperationalTime.get() + put(ContextSpecificTag(TAG_TOTAL_OPERATIONAL_TIME), opttotalOperationalTime) + } + } else { + putNull(ContextSpecificTag(TAG_TOTAL_OPERATIONAL_TIME)) + } + if (estimatedTime != null) { + if (estimatedTime.isPresent) { + val optestimatedTime = estimatedTime.get() + put(ContextSpecificTag(TAG_ESTIMATED_TIME), optestimatedTime) + } + } else { + putNull(ContextSpecificTag(TAG_ESTIMATED_TIME)) + } + endStructure() + } + } + + companion object { + private const val TAG_LOCATION_I_D = 0 + private const val TAG_STATUS = 1 + private const val TAG_TOTAL_OPERATIONAL_TIME = 2 + private const val TAG_ESTIMATED_TIME = 3 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterProgressStruct { + tlvReader.enterStructure(tlvTag) + val locationID = tlvReader.getUInt(ContextSpecificTag(TAG_LOCATION_I_D)) + val status = tlvReader.getUByte(ContextSpecificTag(TAG_STATUS)) + val totalOperationalTime = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(ContextSpecificTag(TAG_TOTAL_OPERATIONAL_TIME))) { + Optional.of(tlvReader.getUInt(ContextSpecificTag(TAG_TOTAL_OPERATIONAL_TIME))) + } else { + Optional.empty() + } + } else { + tlvReader.getNull(ContextSpecificTag(TAG_TOTAL_OPERATIONAL_TIME)) + null + } + val estimatedTime = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(ContextSpecificTag(TAG_ESTIMATED_TIME))) { + Optional.of(tlvReader.getUInt(ContextSpecificTag(TAG_ESTIMATED_TIME))) + } else { + Optional.empty() + } + } else { + tlvReader.getNull(ContextSpecificTag(TAG_ESTIMATED_TIME)) + null + } + + tlvReader.exitContainer() + + return ServiceAreaClusterProgressStruct( + locationID, + status, + totalOperationalTime, + estimatedTime + ) + } + } +} diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index 6f9ee58cafcadb..7cdabec93f43ca 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -27716,6 +27716,607 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } + case app::Clusters::ServiceArea::Id: { + using namespace app::Clusters::ServiceArea; + switch (aPath.mAttributeId) + { + case Attributes::SupportedLocations::Id: { + using TypeInfo = Attributes::SupportedLocations::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + jobject newElement_0_locationID; + std::string newElement_0_locationIDClassName = "java/lang/Long"; + std::string newElement_0_locationIDCtorSignature = "(J)V"; + jlong jninewElement_0_locationID = static_cast(entry_0.locationID); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_locationIDClassName.c_str(), + newElement_0_locationIDCtorSignature.c_str(), + jninewElement_0_locationID, newElement_0_locationID); + jobject newElement_0_mapID; + if (entry_0.mapID.IsNull()) + { + newElement_0_mapID = nullptr; + } + else + { + std::string newElement_0_mapIDClassName = "java/lang/Integer"; + std::string newElement_0_mapIDCtorSignature = "(I)V"; + jint jninewElement_0_mapID = static_cast(entry_0.mapID.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_mapIDClassName.c_str(), + newElement_0_mapIDCtorSignature.c_str(), + jninewElement_0_mapID, newElement_0_mapID); + } + jobject newElement_0_locationInfo; + jobject newElement_0_locationInfo_locationInfo; + if (entry_0.locationInfo.locationInfo.IsNull()) + { + newElement_0_locationInfo_locationInfo = nullptr; + } + else + { + jobject newElement_0_locationInfo_locationInfo_locationName; + LogErrorOnFailure( + chip::JniReferences::GetInstance().CharToStringUTF(entry_0.locationInfo.locationInfo.Value().locationName, + newElement_0_locationInfo_locationInfo_locationName)); + jobject newElement_0_locationInfo_locationInfo_floorNumber; + if (entry_0.locationInfo.locationInfo.Value().floorNumber.IsNull()) + { + newElement_0_locationInfo_locationInfo_floorNumber = nullptr; + } + else + { + std::string newElement_0_locationInfo_locationInfo_floorNumberClassName = "java/lang/Integer"; + std::string newElement_0_locationInfo_locationInfo_floorNumberCtorSignature = "(I)V"; + jint jninewElement_0_locationInfo_locationInfo_floorNumber = + static_cast(entry_0.locationInfo.locationInfo.Value().floorNumber.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_locationInfo_locationInfo_floorNumberClassName.c_str(), + newElement_0_locationInfo_locationInfo_floorNumberCtorSignature.c_str(), + jninewElement_0_locationInfo_locationInfo_floorNumber, + newElement_0_locationInfo_locationInfo_floorNumber); + } + jobject newElement_0_locationInfo_locationInfo_areaType; + if (entry_0.locationInfo.locationInfo.Value().areaType.IsNull()) + { + newElement_0_locationInfo_locationInfo_areaType = nullptr; + } + else + { + std::string newElement_0_locationInfo_locationInfo_areaTypeClassName = "java/lang/Integer"; + std::string newElement_0_locationInfo_locationInfo_areaTypeCtorSignature = "(I)V"; + jint jninewElement_0_locationInfo_locationInfo_areaType = + static_cast(entry_0.locationInfo.locationInfo.Value().areaType.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_locationInfo_locationInfo_areaTypeClassName.c_str(), + newElement_0_locationInfo_locationInfo_areaTypeCtorSignature.c_str(), + jninewElement_0_locationInfo_locationInfo_areaType, newElement_0_locationInfo_locationInfo_areaType); + } + + jclass homeLocationStructStructClass_4; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$ServiceAreaClusterHomeLocationStruct", + homeLocationStructStructClass_4); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$ServiceAreaClusterHomeLocationStruct"); + return nullptr; + } + + jmethodID homeLocationStructStructCtor_4; + err = chip::JniReferences::GetInstance().FindMethod( + env, homeLocationStructStructClass_4, "", + "(Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;)V", &homeLocationStructStructCtor_4); + if (err != CHIP_NO_ERROR || homeLocationStructStructCtor_4 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$ServiceAreaClusterHomeLocationStruct constructor"); + return nullptr; + } + + newElement_0_locationInfo_locationInfo = env->NewObject( + homeLocationStructStructClass_4, homeLocationStructStructCtor_4, + newElement_0_locationInfo_locationInfo_locationName, newElement_0_locationInfo_locationInfo_floorNumber, + newElement_0_locationInfo_locationInfo_areaType); + } + jobject newElement_0_locationInfo_landmarkTag; + if (entry_0.locationInfo.landmarkTag.IsNull()) + { + newElement_0_locationInfo_landmarkTag = nullptr; + } + else + { + std::string newElement_0_locationInfo_landmarkTagClassName = "java/lang/Integer"; + std::string newElement_0_locationInfo_landmarkTagCtorSignature = "(I)V"; + jint jninewElement_0_locationInfo_landmarkTag = static_cast(entry_0.locationInfo.landmarkTag.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_locationInfo_landmarkTagClassName.c_str(), + newElement_0_locationInfo_landmarkTagCtorSignature.c_str(), jninewElement_0_locationInfo_landmarkTag, + newElement_0_locationInfo_landmarkTag); + } + jobject newElement_0_locationInfo_positionTag; + if (entry_0.locationInfo.positionTag.IsNull()) + { + newElement_0_locationInfo_positionTag = nullptr; + } + else + { + std::string newElement_0_locationInfo_positionTagClassName = "java/lang/Integer"; + std::string newElement_0_locationInfo_positionTagCtorSignature = "(I)V"; + jint jninewElement_0_locationInfo_positionTag = static_cast(entry_0.locationInfo.positionTag.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_locationInfo_positionTagClassName.c_str(), + newElement_0_locationInfo_positionTagCtorSignature.c_str(), jninewElement_0_locationInfo_positionTag, + newElement_0_locationInfo_positionTag); + } + jobject newElement_0_locationInfo_surfaceTag; + if (entry_0.locationInfo.surfaceTag.IsNull()) + { + newElement_0_locationInfo_surfaceTag = nullptr; + } + else + { + std::string newElement_0_locationInfo_surfaceTagClassName = "java/lang/Integer"; + std::string newElement_0_locationInfo_surfaceTagCtorSignature = "(I)V"; + jint jninewElement_0_locationInfo_surfaceTag = static_cast(entry_0.locationInfo.surfaceTag.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_locationInfo_surfaceTagClassName.c_str(), + newElement_0_locationInfo_surfaceTagCtorSignature.c_str(), jninewElement_0_locationInfo_surfaceTag, + newElement_0_locationInfo_surfaceTag); + } + + jclass locationInfoStructStructClass_2; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$ServiceAreaClusterLocationInfoStruct", locationInfoStructStructClass_2); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$ServiceAreaClusterLocationInfoStruct"); + return nullptr; + } + + jmethodID locationInfoStructStructCtor_2; + err = chip::JniReferences::GetInstance().FindMethod( + env, locationInfoStructStructClass_2, "", + "(Lchip/devicecontroller/ChipStructs$ServiceAreaClusterHomeLocationStruct;Ljava/lang/Integer;Ljava/lang/" + "Integer;Ljava/lang/Integer;)V", + &locationInfoStructStructCtor_2); + if (err != CHIP_NO_ERROR || locationInfoStructStructCtor_2 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$ServiceAreaClusterLocationInfoStruct constructor"); + return nullptr; + } + + newElement_0_locationInfo = + env->NewObject(locationInfoStructStructClass_2, locationInfoStructStructCtor_2, + newElement_0_locationInfo_locationInfo, newElement_0_locationInfo_landmarkTag, + newElement_0_locationInfo_positionTag, newElement_0_locationInfo_surfaceTag); + + jclass locationStructStructClass_1; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$ServiceAreaClusterLocationStruct", locationStructStructClass_1); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$ServiceAreaClusterLocationStruct"); + return nullptr; + } + + jmethodID locationStructStructCtor_1; + err = chip::JniReferences::GetInstance().FindMethod(env, locationStructStructClass_1, "", + "(Ljava/lang/Long;Ljava/lang/Integer;Lchip/devicecontroller/" + "ChipStructs$ServiceAreaClusterLocationInfoStruct;)V", + &locationStructStructCtor_1); + if (err != CHIP_NO_ERROR || locationStructStructCtor_1 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$ServiceAreaClusterLocationStruct constructor"); + return nullptr; + } + + newElement_0 = env->NewObject(locationStructStructClass_1, locationStructStructCtor_1, newElement_0_locationID, + newElement_0_mapID, newElement_0_locationInfo); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::SupportedMaps::Id: { + using TypeInfo = Attributes::SupportedMaps::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_1 = cppValue.Value().begin(); + while (iter_value_1.Next()) + { + auto & entry_1 = iter_value_1.GetValue(); + jobject newElement_1; + jobject newElement_1_mapID; + std::string newElement_1_mapIDClassName = "java/lang/Integer"; + std::string newElement_1_mapIDCtorSignature = "(I)V"; + jint jninewElement_1_mapID = static_cast(entry_1.mapID); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_1_mapIDClassName.c_str(), + newElement_1_mapIDCtorSignature.c_str(), + jninewElement_1_mapID, newElement_1_mapID); + jobject newElement_1_name; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_1.name, newElement_1_name)); + + jclass mapStructStructClass_2; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$ServiceAreaClusterMapStruct", mapStructStructClass_2); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$ServiceAreaClusterMapStruct"); + return nullptr; + } + + jmethodID mapStructStructCtor_2; + err = chip::JniReferences::GetInstance().FindMethod( + env, mapStructStructClass_2, "", "(Ljava/lang/Integer;Ljava/lang/String;)V", &mapStructStructCtor_2); + if (err != CHIP_NO_ERROR || mapStructStructCtor_2 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$ServiceAreaClusterMapStruct constructor"); + return nullptr; + } + + newElement_1 = + env->NewObject(mapStructStructClass_2, mapStructStructCtor_2, newElement_1_mapID, newElement_1_name); + chip::JniReferences::GetInstance().AddToList(value, newElement_1); + } + } + return value; + } + case Attributes::SelectedLocations::Id: { + using TypeInfo = Attributes::SelectedLocations::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_1 = cppValue.Value().begin(); + while (iter_value_1.Next()) + { + auto & entry_1 = iter_value_1.GetValue(); + jobject newElement_1; + std::string newElement_1ClassName = "java/lang/Long"; + std::string newElement_1CtorSignature = "(J)V"; + jlong jninewElement_1 = static_cast(entry_1); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_1ClassName.c_str(), newElement_1CtorSignature.c_str(), jninewElement_1, newElement_1); + chip::JniReferences::GetInstance().AddToList(value, newElement_1); + } + } + return value; + } + case Attributes::CurrentLocation::Id: { + using TypeInfo = Attributes::CurrentLocation::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } + case Attributes::EstimatedEndTime::Id: { + using TypeInfo = Attributes::EstimatedEndTime::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } + case Attributes::Progress::Id: { + using TypeInfo = Attributes::Progress::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_1 = cppValue.Value().begin(); + while (iter_value_1.Next()) + { + auto & entry_1 = iter_value_1.GetValue(); + jobject newElement_1; + jobject newElement_1_locationID; + std::string newElement_1_locationIDClassName = "java/lang/Long"; + std::string newElement_1_locationIDCtorSignature = "(J)V"; + jlong jninewElement_1_locationID = static_cast(entry_1.locationID); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_1_locationIDClassName.c_str(), newElement_1_locationIDCtorSignature.c_str(), + jninewElement_1_locationID, newElement_1_locationID); + jobject newElement_1_status; + std::string newElement_1_statusClassName = "java/lang/Integer"; + std::string newElement_1_statusCtorSignature = "(I)V"; + jint jninewElement_1_status = static_cast(entry_1.status); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_1_statusClassName.c_str(), + newElement_1_statusCtorSignature.c_str(), + jninewElement_1_status, newElement_1_status); + jobject newElement_1_totalOperationalTime; + if (!entry_1.totalOperationalTime.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_1_totalOperationalTime); + } + else + { + jobject newElement_1_totalOperationalTimeInsideOptional; + if (entry_1.totalOperationalTime.Value().IsNull()) + { + newElement_1_totalOperationalTimeInsideOptional = nullptr; + } + else + { + std::string newElement_1_totalOperationalTimeInsideOptionalClassName = "java/lang/Long"; + std::string newElement_1_totalOperationalTimeInsideOptionalCtorSignature = "(J)V"; + jlong jninewElement_1_totalOperationalTimeInsideOptional = + static_cast(entry_1.totalOperationalTime.Value().Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_1_totalOperationalTimeInsideOptionalClassName.c_str(), + newElement_1_totalOperationalTimeInsideOptionalCtorSignature.c_str(), + jninewElement_1_totalOperationalTimeInsideOptional, + newElement_1_totalOperationalTimeInsideOptional); + } + chip::JniReferences::GetInstance().CreateOptional(newElement_1_totalOperationalTimeInsideOptional, + newElement_1_totalOperationalTime); + } + jobject newElement_1_estimatedTime; + if (!entry_1.estimatedTime.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_1_estimatedTime); + } + else + { + jobject newElement_1_estimatedTimeInsideOptional; + if (entry_1.estimatedTime.Value().IsNull()) + { + newElement_1_estimatedTimeInsideOptional = nullptr; + } + else + { + std::string newElement_1_estimatedTimeInsideOptionalClassName = "java/lang/Long"; + std::string newElement_1_estimatedTimeInsideOptionalCtorSignature = "(J)V"; + jlong jninewElement_1_estimatedTimeInsideOptional = + static_cast(entry_1.estimatedTime.Value().Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_1_estimatedTimeInsideOptionalClassName.c_str(), + newElement_1_estimatedTimeInsideOptionalCtorSignature.c_str(), + jninewElement_1_estimatedTimeInsideOptional, newElement_1_estimatedTimeInsideOptional); + } + chip::JniReferences::GetInstance().CreateOptional(newElement_1_estimatedTimeInsideOptional, + newElement_1_estimatedTime); + } + + jclass progressStructStructClass_2; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$ServiceAreaClusterProgressStruct", progressStructStructClass_2); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$ServiceAreaClusterProgressStruct"); + return nullptr; + } + + jmethodID progressStructStructCtor_2; + err = chip::JniReferences::GetInstance().FindMethod( + env, progressStructStructClass_2, "", + "(Ljava/lang/Long;Ljava/lang/Integer;Ljava/util/Optional;Ljava/util/Optional;)V", + &progressStructStructCtor_2); + if (err != CHIP_NO_ERROR || progressStructStructCtor_2 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$ServiceAreaClusterProgressStruct constructor"); + return nullptr; + } + + newElement_1 = + env->NewObject(progressStructStructClass_2, progressStructStructCtor_2, newElement_1_locationID, + newElement_1_status, newElement_1_totalOperationalTime, newElement_1_estimatedTime); + chip::JniReferences::GetInstance().AddToList(value, newElement_1); + } + } + return value; + } + case Attributes::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::EventList::Id: { + using TypeInfo = Attributes::EventList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AttributeList::Id: { + using TypeInfo = Attributes::AttributeList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::FeatureMap::Id: { + using TypeInfo = Attributes::FeatureMap::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::ClusterRevision::Id: { + using TypeInfo = Attributes::ClusterRevision::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + break; + } + break; + } case app::Clusters::PumpConfigurationAndControl::Id: { using namespace app::Clusters::PumpConfigurationAndControl; switch (aPath.mAttributeId) diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp index 0df7c762b20da8..4db00a7efd0f57 100644 --- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp @@ -6638,6 +6638,16 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } break; } + case app::Clusters::ServiceArea::Id: { + using namespace app::Clusters::ServiceArea; + switch (aPath.mEventId) + { + default: + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + break; + } + break; + } case app::Clusters::PumpConfigurationAndControl::Id: { using namespace app::Clusters::PumpConfigurationAndControl; switch (aPath.mEventId) diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index c89a767203ce71..773fe342105443 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -8310,6 +8310,99 @@ class ChipClusters: }, }, } + _SERVICE_AREA_CLUSTER_INFO = { + "clusterName": "ServiceArea", + "clusterId": 0x00000150, + "commands": { + 0x00000000: { + "commandId": 0x00000000, + "commandName": "SelectLocations", + "args": { + "newLocations": "int", + }, + }, + 0x00000002: { + "commandId": 0x00000002, + "commandName": "SkipCurrentLocation", + "args": { + }, + }, + }, + "attributes": { + 0x00000000: { + "attributeName": "SupportedLocations", + "attributeId": 0x00000000, + "type": "", + "reportable": True, + }, + 0x00000001: { + "attributeName": "SupportedMaps", + "attributeId": 0x00000001, + "type": "", + "reportable": True, + }, + 0x00000002: { + "attributeName": "SelectedLocations", + "attributeId": 0x00000002, + "type": "int", + "reportable": True, + }, + 0x00000003: { + "attributeName": "CurrentLocation", + "attributeId": 0x00000003, + "type": "int", + "reportable": True, + }, + 0x00000004: { + "attributeName": "EstimatedEndTime", + "attributeId": 0x00000004, + "type": "int", + "reportable": True, + }, + 0x00000005: { + "attributeName": "Progress", + "attributeId": 0x00000005, + "type": "", + "reportable": True, + }, + 0x0000FFF8: { + "attributeName": "GeneratedCommandList", + "attributeId": 0x0000FFF8, + "type": "int", + "reportable": True, + }, + 0x0000FFF9: { + "attributeName": "AcceptedCommandList", + "attributeId": 0x0000FFF9, + "type": "int", + "reportable": True, + }, + 0x0000FFFA: { + "attributeName": "EventList", + "attributeId": 0x0000FFFA, + "type": "int", + "reportable": True, + }, + 0x0000FFFB: { + "attributeName": "AttributeList", + "attributeId": 0x0000FFFB, + "type": "int", + "reportable": True, + }, + 0x0000FFFC: { + "attributeName": "FeatureMap", + "attributeId": 0x0000FFFC, + "type": "int", + "reportable": True, + }, + 0x0000FFFD: { + "attributeName": "ClusterRevision", + "attributeId": 0x0000FFFD, + "type": "int", + "reportable": True, + }, + }, + } _PUMP_CONFIGURATION_AND_CONTROL_CLUSTER_INFO = { "clusterName": "PumpConfigurationAndControl", "clusterId": 0x00000200, @@ -14857,6 +14950,7 @@ class ChipClusters: 0x00000101: _DOOR_LOCK_CLUSTER_INFO, 0x00000102: _WINDOW_COVERING_CLUSTER_INFO, 0x00000103: _BARRIER_CONTROL_CLUSTER_INFO, + 0x00000150: _SERVICE_AREA_CLUSTER_INFO, 0x00000200: _PUMP_CONFIGURATION_AND_CONTROL_CLUSTER_INFO, 0x00000201: _THERMOSTAT_CLUSTER_INFO, 0x00000202: _FAN_CONTROL_CLUSTER_INFO, @@ -14981,6 +15075,7 @@ class ChipClusters: "DoorLock": _DOOR_LOCK_CLUSTER_INFO, "WindowCovering": _WINDOW_COVERING_CLUSTER_INFO, "BarrierControl": _BARRIER_CONTROL_CLUSTER_INFO, + "ServiceArea": _SERVICE_AREA_CLUSTER_INFO, "PumpConfigurationAndControl": _PUMP_CONFIGURATION_AND_CONTROL_CLUSTER_INFO, "Thermostat": _THERMOSTAT_CLUSTER_INFO, "FanControl": _FAN_CONTROL_CLUSTER_INFO, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 8dc1fad59e2591..43917192955506 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -29878,6 +29878,630 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'uint' = 0 +@dataclass +class ServiceArea(Cluster): + id: typing.ClassVar[int] = 0x00000150 + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="supportedLocations", Tag=0x00000000, Type=typing.List[ServiceArea.Structs.LocationStruct]), + ClusterObjectFieldDescriptor(Label="supportedMaps", Tag=0x00000001, Type=typing.Union[Nullable, typing.List[ServiceArea.Structs.MapStruct]]), + ClusterObjectFieldDescriptor(Label="selectedLocations", Tag=0x00000002, Type=typing.Union[Nullable, typing.List[uint]]), + ClusterObjectFieldDescriptor(Label="currentLocation", Tag=0x00000003, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="estimatedEndTime", Tag=0x00000004, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="progress", Tag=0x00000005, Type=typing.Union[None, Nullable, typing.List[ServiceArea.Structs.ProgressStruct]]), + ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), + ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), + ]) + + supportedLocations: 'typing.List[ServiceArea.Structs.LocationStruct]' = None + supportedMaps: 'typing.Union[Nullable, typing.List[ServiceArea.Structs.MapStruct]]' = None + selectedLocations: 'typing.Union[Nullable, typing.List[uint]]' = None + currentLocation: 'typing.Union[None, Nullable, uint]' = None + estimatedEndTime: 'typing.Union[None, Nullable, uint]' = None + progress: 'typing.Union[None, Nullable, typing.List[ServiceArea.Structs.ProgressStruct]]' = None + generatedCommandList: 'typing.List[uint]' = None + acceptedCommandList: 'typing.List[uint]' = None + eventList: 'typing.List[uint]' = None + attributeList: 'typing.List[uint]' = None + featureMap: 'uint' = None + clusterRevision: 'uint' = None + + class Enums: + class AreaTypeTag(MatterIntEnum): + kAisle = 0x00 + kAttic = 0x01 + kBackDoor = 0x02 + kBackYard = 0x03 + kBalcony = 0x04 + kBallroom = 0x05 + kBathroom = 0x06 + kBedroom = 0x07 + kBorder = 0x08 + kBoxroom = 0x09 + kBreakfastRoom = 0x0A + kCarport = 0x0B + kCellar = 0x0C + kCloakroom = 0x0D + kCloset = 0x0E + kConservatory = 0x0F + kCorridor = 0x10 + kCraftRoom = 0x11 + kCupboard = 0x12 + kDeck = 0x13 + kDen = 0x14 + kDining = 0x15 + kDrawingRoom = 0x16 + kDressingRoom = 0x17 + kDriveway = 0x18 + kElevator = 0x19 + kEnsuite = 0x1A + kEntrance = 0x1B + kEntryway = 0x1C + kFamilyRoom = 0x1D + kFoyer = 0x1E + kFrontDoor = 0x1F + kFrontYard = 0x20 + kGameRoom = 0x21 + kGarage = 0x22 + kGarageDoor = 0x23 + kGarden = 0x24 + kGardenDoor = 0x25 + kGuestBathroom = 0x26 + kGuestBedroom = 0x27 + kGuestRestroom = 0x28 + kGuestRoom = 0x29 + kGym = 0x2A + kHallway = 0x2B + kHearthRoom = 0x2C + kKidsRoom = 0x2D + kKidsBedroom = 0x2E + kKitchen = 0x2F + kLarder = 0x30 + kLaundryRoom = 0x31 + kLawn = 0x32 + kLibrary = 0x33 + kLivingRoom = 0x34 + kLounge = 0x35 + kMediaTvRoom = 0x36 + kMudRoom = 0x37 + kMusicRoom = 0x38 + kNursery = 0x39 + kOffice = 0x3A + kOutdoorKitchen = 0x3B + kOutside = 0x3C + kPantry = 0x3D + kParkingLot = 0x3E + kParlor = 0x3F + kPatio = 0x40 + kPlayRoom = 0x41 + kPoolRoom = 0x42 + kPorch = 0x43 + kPrimaryBathroom = 0x44 + kPrimaryBedroom = 0x45 + kRamp = 0x46 + kReceptionRoom = 0x47 + kRecreationRoom = 0x48 + kRestroom = 0x49 + kRoof = 0x4A + kSauna = 0x4B + kScullery = 0x4C + kSewingRoom = 0x4D + kShed = 0x4E + kSideDoor = 0x4F + kSideYard = 0x50 + kSittingRoom = 0x51 + kSnug = 0x52 + kSpa = 0x53 + kStaircase = 0x54 + kSteamRoom = 0x55 + kStorageRoom = 0x56 + kStudio = 0x57 + kStudy = 0x58 + kSunRoom = 0x59 + kSwimmingPool = 0x5A + kTerrace = 0x5B + kUtilityRoom = 0x5C + kWard = 0x5D + kWorkshop = 0x5E + # All received enum values that are not listed above will be mapped + # to kUnknownEnumValue. This is a helper enum value that should only + # be used by code to process how it handles receiving and unknown + # enum value. This specific should never be transmitted. + kUnknownEnumValue = 95, + + class FloorSurfaceTag(MatterIntEnum): + kCarpet = 0x00 + kCeramic = 0x01 + kConcrete = 0x02 + kCork = 0x03 + kDeepCarpet = 0x04 + kDirt = 0x05 + kEngineeredWood = 0x06 + kGlass = 0x07 + kGrass = 0x08 + kHardwood = 0x09 + kLaminate = 0x0A + kLinoleum = 0x0B + kMat = 0x0C + kMetal = 0x0D + kPlastic = 0x0E + kPolishedConcrete = 0x0F + kRubber = 0x10 + kRug = 0x11 + kSand = 0x12 + kStone = 0x13 + kTatami = 0x14 + kTerrazzo = 0x15 + kTile = 0x16 + kVinyl = 0x17 + # All received enum values that are not listed above will be mapped + # to kUnknownEnumValue. This is a helper enum value that should only + # be used by code to process how it handles receiving and unknown + # enum value. This specific should never be transmitted. + kUnknownEnumValue = 24, + + class LandmarkTag(MatterIntEnum): + kAirConditioner = 0x00 + kAirPurifier = 0x01 + kBackDoor = 0x02 + kBarStool = 0x03 + kBathMat = 0x04 + kBathtub = 0x05 + kBed = 0x06 + kBookshelf = 0x07 + kChair = 0x08 + kChristmasTree = 0x09 + kCoatRack = 0x0A + kCoffeeTable = 0x0B + kCookingRange = 0x0C + kCouch = 0x0D + kCountertop = 0x0E + kCradle = 0x0F + kCrib = 0x10 + kDesk = 0x11 + kDiningTable = 0x12 + kDishwasher = 0x13 + kDoor = 0x14 + kDresser = 0x15 + kLaundryDryer = 0x16 + kFan = 0x17 + kFireplace = 0x18 + kFreezer = 0x19 + kFrontDoor = 0x1A + kHighChair = 0x1B + kKitchenIsland = 0x1C + kLamp = 0x1D + kLitterBox = 0x1E + kMirror = 0x1F + kNightstand = 0x20 + kOven = 0x21 + kPetBed = 0x22 + kPetBowl = 0x23 + kPetCrate = 0x24 + kRefrigerator = 0x25 + kScratchingPost = 0x26 + kShoeRack = 0x27 + kShower = 0x28 + kSideDoor = 0x29 + kSink = 0x2A + kSofa = 0x2B + kStove = 0x2C + kTable = 0x2D + kToilet = 0x2E + kTrashCan = 0x2F + kLaundryWasher = 0x30 + kWindow = 0x31 + kWineCooler = 0x32 + # All received enum values that are not listed above will be mapped + # to kUnknownEnumValue. This is a helper enum value that should only + # be used by code to process how it handles receiving and unknown + # enum value. This specific should never be transmitted. + kUnknownEnumValue = 51, + + class OperationalStatusEnum(MatterIntEnum): + kPending = 0x00 + kOperating = 0x01 + kSkipped = 0x02 + kCompleted = 0x03 + # All received enum values that are not listed above will be mapped + # to kUnknownEnumValue. This is a helper enum value that should only + # be used by code to process how it handles receiving and unknown + # enum value. This specific should never be transmitted. + kUnknownEnumValue = 4, + + class PositionTag(MatterIntEnum): + kLeft = 0x00 + kRight = 0x01 + kTop = 0x02 + kBottom = 0x03 + kMiddle = 0x04 + kRow = 0x05 + kColumn = 0x06 + kUnder = 0x07 + kNextTo = 0x08 + kAround = 0x09 + kOn = 0x0A + kAbove = 0x0B + kFrontOf = 0x0C + kBehind = 0x0D + # All received enum values that are not listed above will be mapped + # to kUnknownEnumValue. This is a helper enum value that should only + # be used by code to process how it handles receiving and unknown + # enum value. This specific should never be transmitted. + kUnknownEnumValue = 14, + + class SelectLocationsStatus(MatterIntEnum): + kSuccess = 0x00 + kUnsupportedLocation = 0x01 + kDuplicatedLocations = 0x02 + kInvalidInMode = 0x03 + kInvalidSet = 0x04 + # All received enum values that are not listed above will be mapped + # to kUnknownEnumValue. This is a helper enum value that should only + # be used by code to process how it handles receiving and unknown + # enum value. This specific should never be transmitted. + kUnknownEnumValue = 5, + + class SkipCurrentLocationStatus(MatterIntEnum): + kSuccess = 0x00 + kInvalidLocationList = 0x01 + kInvalidInMode = 0x02 + # All received enum values that are not listed above will be mapped + # to kUnknownEnumValue. This is a helper enum value that should only + # be used by code to process how it handles receiving and unknown + # enum value. This specific should never be transmitted. + kUnknownEnumValue = 3, + + class Bitmaps: + class Feature(IntFlag): + kListOrder = 0x1 + kSelectWhileRunning = 0x2 + + class Structs: + @dataclass + class HomeLocationStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="locationName", Tag=0, Type=str), + ClusterObjectFieldDescriptor(Label="floorNumber", Tag=1, Type=typing.Union[Nullable, int]), + ClusterObjectFieldDescriptor(Label="areaType", Tag=2, Type=typing.Union[Nullable, ServiceArea.Enums.AreaTypeTag]), + ]) + + locationName: 'str' = "" + floorNumber: 'typing.Union[Nullable, int]' = NullValue + areaType: 'typing.Union[Nullable, ServiceArea.Enums.AreaTypeTag]' = NullValue + + @dataclass + class LocationInfoStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="locationInfo", Tag=0, Type=typing.Union[Nullable, ServiceArea.Structs.HomeLocationStruct]), + ClusterObjectFieldDescriptor(Label="landmarkTag", Tag=1, Type=typing.Union[Nullable, ServiceArea.Enums.LandmarkTag]), + ClusterObjectFieldDescriptor(Label="positionTag", Tag=2, Type=typing.Union[Nullable, ServiceArea.Enums.PositionTag]), + ClusterObjectFieldDescriptor(Label="surfaceTag", Tag=3, Type=typing.Union[Nullable, ServiceArea.Enums.FloorSurfaceTag]), + ]) + + locationInfo: 'typing.Union[Nullable, ServiceArea.Structs.HomeLocationStruct]' = NullValue + landmarkTag: 'typing.Union[Nullable, ServiceArea.Enums.LandmarkTag]' = NullValue + positionTag: 'typing.Union[Nullable, ServiceArea.Enums.PositionTag]' = NullValue + surfaceTag: 'typing.Union[Nullable, ServiceArea.Enums.FloorSurfaceTag]' = NullValue + + @dataclass + class LocationStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="locationID", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="mapID", Tag=1, Type=typing.Union[Nullable, uint]), + ClusterObjectFieldDescriptor(Label="locationInfo", Tag=2, Type=ServiceArea.Structs.LocationInfoStruct), + ]) + + locationID: 'uint' = 0 + mapID: 'typing.Union[Nullable, uint]' = NullValue + locationInfo: 'ServiceArea.Structs.LocationInfoStruct' = field(default_factory=lambda: ServiceArea.Structs.LocationInfoStruct()) + + @dataclass + class MapStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="mapID", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="name", Tag=1, Type=str), + ]) + + mapID: 'uint' = 0 + name: 'str' = "" + + @dataclass + class ProgressStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="locationID", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="status", Tag=1, Type=ServiceArea.Enums.OperationalStatusEnum), + ClusterObjectFieldDescriptor(Label="totalOperationalTime", Tag=2, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="estimatedTime", Tag=3, Type=typing.Union[None, Nullable, uint]), + ]) + + locationID: 'uint' = 0 + status: 'ServiceArea.Enums.OperationalStatusEnum' = 0 + totalOperationalTime: 'typing.Union[None, Nullable, uint]' = None + estimatedTime: 'typing.Union[None, Nullable, uint]' = None + + class Commands: + @dataclass + class SelectLocations(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000150 + command_id: typing.ClassVar[int] = 0x00000000 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'SelectLocationsResponse' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="newLocations", Tag=0, Type=typing.Union[Nullable, typing.List[uint]]), + ]) + + newLocations: 'typing.Union[Nullable, typing.List[uint]]' = NullValue + + @dataclass + class SelectLocationsResponse(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000150 + command_id: typing.ClassVar[int] = 0x00000001 + is_client: typing.ClassVar[bool] = False + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="status", Tag=0, Type=ServiceArea.Enums.SelectLocationsStatus), + ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=typing.Optional[str]), + ]) + + status: 'ServiceArea.Enums.SelectLocationsStatus' = 0 + statusText: 'typing.Optional[str]' = None + + @dataclass + class SkipCurrentLocation(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000150 + command_id: typing.ClassVar[int] = 0x00000002 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'SkipCurrentLocationResponse' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ]) + + @dataclass + class SkipCurrentLocationResponse(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000150 + command_id: typing.ClassVar[int] = 0x00000003 + is_client: typing.ClassVar[bool] = False + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="status", Tag=0, Type=ServiceArea.Enums.SkipCurrentLocationStatus), + ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=typing.Optional[str]), + ]) + + status: 'ServiceArea.Enums.SkipCurrentLocationStatus' = 0 + statusText: 'typing.Optional[str]' = None + + class Attributes: + @dataclass + class SupportedLocations(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000150 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[ServiceArea.Structs.LocationStruct]) + + value: 'typing.List[ServiceArea.Structs.LocationStruct]' = field(default_factory=lambda: []) + + @dataclass + class SupportedMaps(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000150 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000001 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, typing.List[ServiceArea.Structs.MapStruct]]) + + value: 'typing.Union[Nullable, typing.List[ServiceArea.Structs.MapStruct]]' = NullValue + + @dataclass + class SelectedLocations(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000150 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000002 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, typing.List[uint]]) + + value: 'typing.Union[Nullable, typing.List[uint]]' = NullValue + + @dataclass + class CurrentLocation(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000150 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000003 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) + + value: 'typing.Union[None, Nullable, uint]' = None + + @dataclass + class EstimatedEndTime(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000150 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000004 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) + + value: 'typing.Union[None, Nullable, uint]' = None + + @dataclass + class Progress(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000150 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000005 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, typing.List[ServiceArea.Structs.ProgressStruct]]) + + value: 'typing.Union[None, Nullable, typing.List[ServiceArea.Structs.ProgressStruct]]' = None + + @dataclass + class GeneratedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000150 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF8 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AcceptedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000150 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF9 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class EventList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000150 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFA + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AttributeList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000150 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFB + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class FeatureMap(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000150 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFC + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class ClusterRevision(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000150 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFD + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass class PumpConfigurationAndControl(Cluster): id: typing.ClassVar[int] = 0x00000200 diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index 603647682805f6..4200cb1dccd108 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -3749,6 +3749,51 @@ static BOOL AttributeIsSpecifiedInBarrierControlCluster(AttributeId aAttributeId } } } +static BOOL AttributeIsSpecifiedInServiceAreaCluster(AttributeId aAttributeId) +{ + using namespace Clusters::ServiceArea; + switch (aAttributeId) { + case Attributes::SupportedLocations::Id: { + return YES; + } + case Attributes::SupportedMaps::Id: { + return YES; + } + case Attributes::SelectedLocations::Id: { + return YES; + } + case Attributes::CurrentLocation::Id: { + return YES; + } + case Attributes::EstimatedEndTime::Id: { + return YES; + } + case Attributes::Progress::Id: { + return YES; + } + case Attributes::GeneratedCommandList::Id: { + return YES; + } + case Attributes::AcceptedCommandList::Id: { + return YES; + } + case Attributes::EventList::Id: { + return YES; + } + case Attributes::AttributeList::Id: { + return YES; + } + case Attributes::FeatureMap::Id: { + return YES; + } + case Attributes::ClusterRevision::Id: { + return YES; + } + default: { + return NO; + } + } +} static BOOL AttributeIsSpecifiedInPumpConfigurationAndControlCluster(AttributeId aAttributeId) { using namespace Clusters::PumpConfigurationAndControl; @@ -6846,6 +6891,9 @@ BOOL MTRAttributeIsSpecified(ClusterId aClusterId, AttributeId aAttributeId) case Clusters::BarrierControl::Id: { return AttributeIsSpecifiedInBarrierControlCluster(aAttributeId); } + case Clusters::ServiceArea::Id: { + return AttributeIsSpecifiedInServiceAreaCluster(aAttributeId); + } case Clusters::PumpConfigurationAndControl::Id: { return AttributeIsSpecifiedInPumpConfigurationAndControlCluster(aAttributeId); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index fdc2820cc0d584..02ce62e1c2f0dc 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -10818,6 +10818,234 @@ static id _Nullable DecodeAttributeValueForBarrierControlCluster(AttributeId aAt *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; return nil; } +static id _Nullable DecodeAttributeValueForServiceAreaCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::ServiceArea; + switch (aAttributeId) { + case Attributes::SupportedLocations::Id: { + using TypeInfo = Attributes::SupportedLocations::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSArray * _Nonnull value; + { // Scope for our temporary variables + auto * array_0 = [NSMutableArray new]; + auto iter_0 = cppValue.begin(); + while (iter_0.Next()) { + auto & entry_0 = iter_0.GetValue(); + MTRServiceAreaClusterLocationStruct * newElement_0; + newElement_0 = [MTRServiceAreaClusterLocationStruct new]; + newElement_0.locationID = [NSNumber numberWithUnsignedInt:entry_0.locationID]; + if (entry_0.mapID.IsNull()) { + newElement_0.mapID = nil; + } else { + newElement_0.mapID = [NSNumber numberWithUnsignedChar:entry_0.mapID.Value()]; + } + newElement_0.locationInfo = [MTRServiceAreaClusterLocationInfoStruct new]; + if (entry_0.locationInfo.locationInfo.IsNull()) { + newElement_0.locationInfo.locationInfo = nil; + } else { + newElement_0.locationInfo.locationInfo = [MTRServiceAreaClusterHomeLocationStruct new]; + newElement_0.locationInfo.locationInfo.locationName = AsString(entry_0.locationInfo.locationInfo.Value().locationName); + if (newElement_0.locationInfo.locationInfo.locationName == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + if (entry_0.locationInfo.locationInfo.Value().floorNumber.IsNull()) { + newElement_0.locationInfo.locationInfo.floorNumber = nil; + } else { + newElement_0.locationInfo.locationInfo.floorNumber = [NSNumber numberWithShort:entry_0.locationInfo.locationInfo.Value().floorNumber.Value()]; + } + if (entry_0.locationInfo.locationInfo.Value().areaType.IsNull()) { + newElement_0.locationInfo.locationInfo.areaType = nil; + } else { + newElement_0.locationInfo.locationInfo.areaType = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.locationInfo.locationInfo.Value().areaType.Value())]; + } + } + if (entry_0.locationInfo.landmarkTag.IsNull()) { + newElement_0.locationInfo.landmarkTag = nil; + } else { + newElement_0.locationInfo.landmarkTag = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.locationInfo.landmarkTag.Value())]; + } + if (entry_0.locationInfo.positionTag.IsNull()) { + newElement_0.locationInfo.positionTag = nil; + } else { + newElement_0.locationInfo.positionTag = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.locationInfo.positionTag.Value())]; + } + if (entry_0.locationInfo.surfaceTag.IsNull()) { + newElement_0.locationInfo.surfaceTag = nil; + } else { + newElement_0.locationInfo.surfaceTag = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.locationInfo.surfaceTag.Value())]; + } + [array_0 addObject:newElement_0]; + } + CHIP_ERROR err = iter_0.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + value = array_0; + } + return value; + } + case Attributes::SupportedMaps::Id: { + using TypeInfo = Attributes::SupportedMaps::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSArray * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + { // Scope for our temporary variables + auto * array_1 = [NSMutableArray new]; + auto iter_1 = cppValue.Value().begin(); + while (iter_1.Next()) { + auto & entry_1 = iter_1.GetValue(); + MTRServiceAreaClusterMapStruct * newElement_1; + newElement_1 = [MTRServiceAreaClusterMapStruct new]; + newElement_1.mapID = [NSNumber numberWithUnsignedChar:entry_1.mapID]; + newElement_1.name = AsString(entry_1.name); + if (newElement_1.name == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + [array_1 addObject:newElement_1]; + } + CHIP_ERROR err = iter_1.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + value = array_1; + } + } + return value; + } + case Attributes::SelectedLocations::Id: { + using TypeInfo = Attributes::SelectedLocations::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSArray * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + { // Scope for our temporary variables + auto * array_1 = [NSMutableArray new]; + auto iter_1 = cppValue.Value().begin(); + while (iter_1.Next()) { + auto & entry_1 = iter_1.GetValue(); + NSNumber * newElement_1; + newElement_1 = [NSNumber numberWithUnsignedInt:entry_1]; + [array_1 addObject:newElement_1]; + } + CHIP_ERROR err = iter_1.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + value = array_1; + } + } + return value; + } + case Attributes::CurrentLocation::Id: { + using TypeInfo = Attributes::CurrentLocation::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + value = [NSNumber numberWithUnsignedInt:cppValue.Value()]; + } + return value; + } + case Attributes::EstimatedEndTime::Id: { + using TypeInfo = Attributes::EstimatedEndTime::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + value = [NSNumber numberWithUnsignedInt:cppValue.Value()]; + } + return value; + } + case Attributes::Progress::Id: { + using TypeInfo = Attributes::Progress::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSArray * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + { // Scope for our temporary variables + auto * array_1 = [NSMutableArray new]; + auto iter_1 = cppValue.Value().begin(); + while (iter_1.Next()) { + auto & entry_1 = iter_1.GetValue(); + MTRServiceAreaClusterProgressStruct * newElement_1; + newElement_1 = [MTRServiceAreaClusterProgressStruct new]; + newElement_1.locationID = [NSNumber numberWithUnsignedInt:entry_1.locationID]; + newElement_1.status = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_1.status)]; + if (entry_1.totalOperationalTime.HasValue()) { + if (entry_1.totalOperationalTime.Value().IsNull()) { + newElement_1.totalOperationalTime = nil; + } else { + newElement_1.totalOperationalTime = [NSNumber numberWithUnsignedInt:entry_1.totalOperationalTime.Value().Value()]; + } + } else { + newElement_1.totalOperationalTime = nil; + } + if (entry_1.estimatedTime.HasValue()) { + if (entry_1.estimatedTime.Value().IsNull()) { + newElement_1.estimatedTime = nil; + } else { + newElement_1.estimatedTime = [NSNumber numberWithUnsignedInt:entry_1.estimatedTime.Value().Value()]; + } + } else { + newElement_1.estimatedTime = nil; + } + [array_1 addObject:newElement_1]; + } + CHIP_ERROR err = iter_1.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + value = array_1; + } + } + return value; + } + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + return nil; +} static id _Nullable DecodeAttributeValueForPumpConfigurationAndControlCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::PumpConfigurationAndControl; @@ -19708,6 +19936,9 @@ id _Nullable MTRDecodeAttributeValue(const ConcreteAttributePath & aPath, TLV::T case Clusters::BarrierControl::Id: { return DecodeAttributeValueForBarrierControlCluster(aPath.mAttributeId, aReader, aError); } + case Clusters::ServiceArea::Id: { + return DecodeAttributeValueForServiceAreaCluster(aPath.mAttributeId, aReader, aError); + } case Clusters::PumpConfigurationAndControl::Id: { return DecodeAttributeValueForPumpConfigurationAndControlCluster(aPath.mAttributeId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 4c81148a2b6c40..a481ad0f37f8a4 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -9410,6 +9410,118 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @end +/** + * Cluster Service Area + * + * The Service Area cluster provides an interface for controlling the locations where a device should operate, and for querying the current location. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRBaseClusterServiceArea : MTRGenericBaseCluster + +/** + * Command SelectLocations + * + * Command used to select a set of device locations, where the device is to operate + */ +- (void)selectLocationsWithParams:(MTRServiceAreaClusterSelectLocationsParams *)params completion:(void (^)(MTRServiceAreaClusterSelectLocationsResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +/** + * Command SkipCurrentLocation + * + * This command is used to skip the current location where the device operates. + */ +- (void)skipCurrentLocationWithParams:(MTRServiceAreaClusterSkipCurrentLocationParams * _Nullable)params completion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)skipCurrentLocationWithCompletion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeSupportedLocationsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeSupportedLocationsWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeSupportedLocationsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeSupportedMapsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeSupportedMapsWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeSupportedMapsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeSelectedLocationsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeSelectedLocationsWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeSelectedLocationsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeCurrentLocationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeCurrentLocationWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeCurrentLocationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeEstimatedEndTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeEstimatedEndTimeWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeEstimatedEndTimeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeProgressWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeProgressWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeProgressWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRBaseClusterServiceArea (Availability) + +/** + * For all instance methods (reads, writes, commands) that take a completion, + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRBaseDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Pump Configuration and Control * @@ -18937,6 +19049,228 @@ typedef NS_OPTIONS(uint16_t, MTRBarrierControlSafetyStatus) { MTRBarrierControlSafetyStatusPositionFailure MTR_PROVISIONALLY_AVAILABLE = 0x8, } MTR_PROVISIONALLY_AVAILABLE; +typedef NS_ENUM(uint8_t, MTRServiceAreaAreaTypeTag) { + MTRServiceAreaAreaTypeTagAisle MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRServiceAreaAreaTypeTagAttic MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRServiceAreaAreaTypeTagBackDoor MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTRServiceAreaAreaTypeTagBackYard MTR_PROVISIONALLY_AVAILABLE = 0x03, + MTRServiceAreaAreaTypeTagBalcony MTR_PROVISIONALLY_AVAILABLE = 0x04, + MTRServiceAreaAreaTypeTagBallroom MTR_PROVISIONALLY_AVAILABLE = 0x05, + MTRServiceAreaAreaTypeTagBathroom MTR_PROVISIONALLY_AVAILABLE = 0x06, + MTRServiceAreaAreaTypeTagBedroom MTR_PROVISIONALLY_AVAILABLE = 0x07, + MTRServiceAreaAreaTypeTagBorder MTR_PROVISIONALLY_AVAILABLE = 0x08, + MTRServiceAreaAreaTypeTagBoxroom MTR_PROVISIONALLY_AVAILABLE = 0x09, + MTRServiceAreaAreaTypeTagBreakfastRoom MTR_PROVISIONALLY_AVAILABLE = 0x0A, + MTRServiceAreaAreaTypeTagCarport MTR_PROVISIONALLY_AVAILABLE = 0x0B, + MTRServiceAreaAreaTypeTagCellar MTR_PROVISIONALLY_AVAILABLE = 0x0C, + MTRServiceAreaAreaTypeTagCloakroom MTR_PROVISIONALLY_AVAILABLE = 0x0D, + MTRServiceAreaAreaTypeTagCloset MTR_PROVISIONALLY_AVAILABLE = 0x0E, + MTRServiceAreaAreaTypeTagConservatory MTR_PROVISIONALLY_AVAILABLE = 0x0F, + MTRServiceAreaAreaTypeTagCorridor MTR_PROVISIONALLY_AVAILABLE = 0x10, + MTRServiceAreaAreaTypeTagCraftRoom MTR_PROVISIONALLY_AVAILABLE = 0x11, + MTRServiceAreaAreaTypeTagCupboard MTR_PROVISIONALLY_AVAILABLE = 0x12, + MTRServiceAreaAreaTypeTagDeck MTR_PROVISIONALLY_AVAILABLE = 0x13, + MTRServiceAreaAreaTypeTagDen MTR_PROVISIONALLY_AVAILABLE = 0x14, + MTRServiceAreaAreaTypeTagDining MTR_PROVISIONALLY_AVAILABLE = 0x15, + MTRServiceAreaAreaTypeTagDrawingRoom MTR_PROVISIONALLY_AVAILABLE = 0x16, + MTRServiceAreaAreaTypeTagDressingRoom MTR_PROVISIONALLY_AVAILABLE = 0x17, + MTRServiceAreaAreaTypeTagDriveway MTR_PROVISIONALLY_AVAILABLE = 0x18, + MTRServiceAreaAreaTypeTagElevator MTR_PROVISIONALLY_AVAILABLE = 0x19, + MTRServiceAreaAreaTypeTagEnsuite MTR_PROVISIONALLY_AVAILABLE = 0x1A, + MTRServiceAreaAreaTypeTagEntrance MTR_PROVISIONALLY_AVAILABLE = 0x1B, + MTRServiceAreaAreaTypeTagEntryway MTR_PROVISIONALLY_AVAILABLE = 0x1C, + MTRServiceAreaAreaTypeTagFamilyRoom MTR_PROVISIONALLY_AVAILABLE = 0x1D, + MTRServiceAreaAreaTypeTagFoyer MTR_PROVISIONALLY_AVAILABLE = 0x1E, + MTRServiceAreaAreaTypeTagFrontDoor MTR_PROVISIONALLY_AVAILABLE = 0x1F, + MTRServiceAreaAreaTypeTagFrontYard MTR_PROVISIONALLY_AVAILABLE = 0x20, + MTRServiceAreaAreaTypeTagGameRoom MTR_PROVISIONALLY_AVAILABLE = 0x21, + MTRServiceAreaAreaTypeTagGarage MTR_PROVISIONALLY_AVAILABLE = 0x22, + MTRServiceAreaAreaTypeTagGarageDoor MTR_PROVISIONALLY_AVAILABLE = 0x23, + MTRServiceAreaAreaTypeTagGarden MTR_PROVISIONALLY_AVAILABLE = 0x24, + MTRServiceAreaAreaTypeTagGardenDoor MTR_PROVISIONALLY_AVAILABLE = 0x25, + MTRServiceAreaAreaTypeTagGuestBathroom MTR_PROVISIONALLY_AVAILABLE = 0x26, + MTRServiceAreaAreaTypeTagGuestBedroom MTR_PROVISIONALLY_AVAILABLE = 0x27, + MTRServiceAreaAreaTypeTagGuestRestroom MTR_PROVISIONALLY_AVAILABLE = 0x28, + MTRServiceAreaAreaTypeTagGuestRoom MTR_PROVISIONALLY_AVAILABLE = 0x29, + MTRServiceAreaAreaTypeTagGym MTR_PROVISIONALLY_AVAILABLE = 0x2A, + MTRServiceAreaAreaTypeTagHallway MTR_PROVISIONALLY_AVAILABLE = 0x2B, + MTRServiceAreaAreaTypeTagHearthRoom MTR_PROVISIONALLY_AVAILABLE = 0x2C, + MTRServiceAreaAreaTypeTagKidsRoom MTR_PROVISIONALLY_AVAILABLE = 0x2D, + MTRServiceAreaAreaTypeTagKidsBedroom MTR_PROVISIONALLY_AVAILABLE = 0x2E, + MTRServiceAreaAreaTypeTagKitchen MTR_PROVISIONALLY_AVAILABLE = 0x2F, + MTRServiceAreaAreaTypeTagLarder MTR_PROVISIONALLY_AVAILABLE = 0x30, + MTRServiceAreaAreaTypeTagLaundryRoom MTR_PROVISIONALLY_AVAILABLE = 0x31, + MTRServiceAreaAreaTypeTagLawn MTR_PROVISIONALLY_AVAILABLE = 0x32, + MTRServiceAreaAreaTypeTagLibrary MTR_PROVISIONALLY_AVAILABLE = 0x33, + MTRServiceAreaAreaTypeTagLivingRoom MTR_PROVISIONALLY_AVAILABLE = 0x34, + MTRServiceAreaAreaTypeTagLounge MTR_PROVISIONALLY_AVAILABLE = 0x35, + MTRServiceAreaAreaTypeTagMediaTVRoom MTR_PROVISIONALLY_AVAILABLE = 0x36, + MTRServiceAreaAreaTypeTagMudRoom MTR_PROVISIONALLY_AVAILABLE = 0x37, + MTRServiceAreaAreaTypeTagMusicRoom MTR_PROVISIONALLY_AVAILABLE = 0x38, + MTRServiceAreaAreaTypeTagNursery MTR_PROVISIONALLY_AVAILABLE = 0x39, + MTRServiceAreaAreaTypeTagOffice MTR_PROVISIONALLY_AVAILABLE = 0x3A, + MTRServiceAreaAreaTypeTagOutdoorKitchen MTR_PROVISIONALLY_AVAILABLE = 0x3B, + MTRServiceAreaAreaTypeTagOutside MTR_PROVISIONALLY_AVAILABLE = 0x3C, + MTRServiceAreaAreaTypeTagPantry MTR_PROVISIONALLY_AVAILABLE = 0x3D, + MTRServiceAreaAreaTypeTagParkingLot MTR_PROVISIONALLY_AVAILABLE = 0x3E, + MTRServiceAreaAreaTypeTagParlor MTR_PROVISIONALLY_AVAILABLE = 0x3F, + MTRServiceAreaAreaTypeTagPatio MTR_PROVISIONALLY_AVAILABLE = 0x40, + MTRServiceAreaAreaTypeTagPlayRoom MTR_PROVISIONALLY_AVAILABLE = 0x41, + MTRServiceAreaAreaTypeTagPoolRoom MTR_PROVISIONALLY_AVAILABLE = 0x42, + MTRServiceAreaAreaTypeTagPorch MTR_PROVISIONALLY_AVAILABLE = 0x43, + MTRServiceAreaAreaTypeTagPrimaryBathroom MTR_PROVISIONALLY_AVAILABLE = 0x44, + MTRServiceAreaAreaTypeTagPrimaryBedroom MTR_PROVISIONALLY_AVAILABLE = 0x45, + MTRServiceAreaAreaTypeTagRamp MTR_PROVISIONALLY_AVAILABLE = 0x46, + MTRServiceAreaAreaTypeTagReceptionRoom MTR_PROVISIONALLY_AVAILABLE = 0x47, + MTRServiceAreaAreaTypeTagRecreationRoom MTR_PROVISIONALLY_AVAILABLE = 0x48, + MTRServiceAreaAreaTypeTagRestroom MTR_PROVISIONALLY_AVAILABLE = 0x49, + MTRServiceAreaAreaTypeTagRoof MTR_PROVISIONALLY_AVAILABLE = 0x4A, + MTRServiceAreaAreaTypeTagSauna MTR_PROVISIONALLY_AVAILABLE = 0x4B, + MTRServiceAreaAreaTypeTagScullery MTR_PROVISIONALLY_AVAILABLE = 0x4C, + MTRServiceAreaAreaTypeTagSewingRoom MTR_PROVISIONALLY_AVAILABLE = 0x4D, + MTRServiceAreaAreaTypeTagShed MTR_PROVISIONALLY_AVAILABLE = 0x4E, + MTRServiceAreaAreaTypeTagSideDoor MTR_PROVISIONALLY_AVAILABLE = 0x4F, + MTRServiceAreaAreaTypeTagSideYard MTR_PROVISIONALLY_AVAILABLE = 0x50, + MTRServiceAreaAreaTypeTagSittingRoom MTR_PROVISIONALLY_AVAILABLE = 0x51, + MTRServiceAreaAreaTypeTagSnug MTR_PROVISIONALLY_AVAILABLE = 0x52, + MTRServiceAreaAreaTypeTagSpa MTR_PROVISIONALLY_AVAILABLE = 0x53, + MTRServiceAreaAreaTypeTagStaircase MTR_PROVISIONALLY_AVAILABLE = 0x54, + MTRServiceAreaAreaTypeTagSteamRoom MTR_PROVISIONALLY_AVAILABLE = 0x55, + MTRServiceAreaAreaTypeTagStorageRoom MTR_PROVISIONALLY_AVAILABLE = 0x56, + MTRServiceAreaAreaTypeTagStudio MTR_PROVISIONALLY_AVAILABLE = 0x57, + MTRServiceAreaAreaTypeTagStudy MTR_PROVISIONALLY_AVAILABLE = 0x58, + MTRServiceAreaAreaTypeTagSunRoom MTR_PROVISIONALLY_AVAILABLE = 0x59, + MTRServiceAreaAreaTypeTagSwimmingPool MTR_PROVISIONALLY_AVAILABLE = 0x5A, + MTRServiceAreaAreaTypeTagTerrace MTR_PROVISIONALLY_AVAILABLE = 0x5B, + MTRServiceAreaAreaTypeTagUtilityRoom MTR_PROVISIONALLY_AVAILABLE = 0x5C, + MTRServiceAreaAreaTypeTagWard MTR_PROVISIONALLY_AVAILABLE = 0x5D, + MTRServiceAreaAreaTypeTagWorkshop MTR_PROVISIONALLY_AVAILABLE = 0x5E, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_ENUM(uint8_t, MTRServiceAreaFloorSurfaceTag) { + MTRServiceAreaFloorSurfaceTagCarpet MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRServiceAreaFloorSurfaceTagCeramic MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRServiceAreaFloorSurfaceTagConcrete MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTRServiceAreaFloorSurfaceTagCork MTR_PROVISIONALLY_AVAILABLE = 0x03, + MTRServiceAreaFloorSurfaceTagDeepCarpet MTR_PROVISIONALLY_AVAILABLE = 0x04, + MTRServiceAreaFloorSurfaceTagDirt MTR_PROVISIONALLY_AVAILABLE = 0x05, + MTRServiceAreaFloorSurfaceTagEngineeredWood MTR_PROVISIONALLY_AVAILABLE = 0x06, + MTRServiceAreaFloorSurfaceTagGlass MTR_PROVISIONALLY_AVAILABLE = 0x07, + MTRServiceAreaFloorSurfaceTagGrass MTR_PROVISIONALLY_AVAILABLE = 0x08, + MTRServiceAreaFloorSurfaceTagHardwood MTR_PROVISIONALLY_AVAILABLE = 0x09, + MTRServiceAreaFloorSurfaceTagLaminate MTR_PROVISIONALLY_AVAILABLE = 0x0A, + MTRServiceAreaFloorSurfaceTagLinoleum MTR_PROVISIONALLY_AVAILABLE = 0x0B, + MTRServiceAreaFloorSurfaceTagMat MTR_PROVISIONALLY_AVAILABLE = 0x0C, + MTRServiceAreaFloorSurfaceTagMetal MTR_PROVISIONALLY_AVAILABLE = 0x0D, + MTRServiceAreaFloorSurfaceTagPlastic MTR_PROVISIONALLY_AVAILABLE = 0x0E, + MTRServiceAreaFloorSurfaceTagPolishedConcrete MTR_PROVISIONALLY_AVAILABLE = 0x0F, + MTRServiceAreaFloorSurfaceTagRubber MTR_PROVISIONALLY_AVAILABLE = 0x10, + MTRServiceAreaFloorSurfaceTagRug MTR_PROVISIONALLY_AVAILABLE = 0x11, + MTRServiceAreaFloorSurfaceTagSand MTR_PROVISIONALLY_AVAILABLE = 0x12, + MTRServiceAreaFloorSurfaceTagStone MTR_PROVISIONALLY_AVAILABLE = 0x13, + MTRServiceAreaFloorSurfaceTagTatami MTR_PROVISIONALLY_AVAILABLE = 0x14, + MTRServiceAreaFloorSurfaceTagTerrazzo MTR_PROVISIONALLY_AVAILABLE = 0x15, + MTRServiceAreaFloorSurfaceTagTile MTR_PROVISIONALLY_AVAILABLE = 0x16, + MTRServiceAreaFloorSurfaceTagVinyl MTR_PROVISIONALLY_AVAILABLE = 0x17, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_ENUM(uint8_t, MTRServiceAreaLandmarkTag) { + MTRServiceAreaLandmarkTagAirConditioner MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRServiceAreaLandmarkTagAirPurifier MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRServiceAreaLandmarkTagBackDoor MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTRServiceAreaLandmarkTagBarStool MTR_PROVISIONALLY_AVAILABLE = 0x03, + MTRServiceAreaLandmarkTagBathMat MTR_PROVISIONALLY_AVAILABLE = 0x04, + MTRServiceAreaLandmarkTagBathtub MTR_PROVISIONALLY_AVAILABLE = 0x05, + MTRServiceAreaLandmarkTagBed MTR_PROVISIONALLY_AVAILABLE = 0x06, + MTRServiceAreaLandmarkTagBookshelf MTR_PROVISIONALLY_AVAILABLE = 0x07, + MTRServiceAreaLandmarkTagChair MTR_PROVISIONALLY_AVAILABLE = 0x08, + MTRServiceAreaLandmarkTagChristmasTree MTR_PROVISIONALLY_AVAILABLE = 0x09, + MTRServiceAreaLandmarkTagCoatRack MTR_PROVISIONALLY_AVAILABLE = 0x0A, + MTRServiceAreaLandmarkTagCoffeeTable MTR_PROVISIONALLY_AVAILABLE = 0x0B, + MTRServiceAreaLandmarkTagCookingRange MTR_PROVISIONALLY_AVAILABLE = 0x0C, + MTRServiceAreaLandmarkTagCouch MTR_PROVISIONALLY_AVAILABLE = 0x0D, + MTRServiceAreaLandmarkTagCountertop MTR_PROVISIONALLY_AVAILABLE = 0x0E, + MTRServiceAreaLandmarkTagCradle MTR_PROVISIONALLY_AVAILABLE = 0x0F, + MTRServiceAreaLandmarkTagCrib MTR_PROVISIONALLY_AVAILABLE = 0x10, + MTRServiceAreaLandmarkTagDesk MTR_PROVISIONALLY_AVAILABLE = 0x11, + MTRServiceAreaLandmarkTagDiningTable MTR_PROVISIONALLY_AVAILABLE = 0x12, + MTRServiceAreaLandmarkTagDishwasher MTR_PROVISIONALLY_AVAILABLE = 0x13, + MTRServiceAreaLandmarkTagDoor MTR_PROVISIONALLY_AVAILABLE = 0x14, + MTRServiceAreaLandmarkTagDresser MTR_PROVISIONALLY_AVAILABLE = 0x15, + MTRServiceAreaLandmarkTagLaundryDryer MTR_PROVISIONALLY_AVAILABLE = 0x16, + MTRServiceAreaLandmarkTagFan MTR_PROVISIONALLY_AVAILABLE = 0x17, + MTRServiceAreaLandmarkTagFireplace MTR_PROVISIONALLY_AVAILABLE = 0x18, + MTRServiceAreaLandmarkTagFreezer MTR_PROVISIONALLY_AVAILABLE = 0x19, + MTRServiceAreaLandmarkTagFrontDoor MTR_PROVISIONALLY_AVAILABLE = 0x1A, + MTRServiceAreaLandmarkTagHighChair MTR_PROVISIONALLY_AVAILABLE = 0x1B, + MTRServiceAreaLandmarkTagKitchenIsland MTR_PROVISIONALLY_AVAILABLE = 0x1C, + MTRServiceAreaLandmarkTagLamp MTR_PROVISIONALLY_AVAILABLE = 0x1D, + MTRServiceAreaLandmarkTagLitterBox MTR_PROVISIONALLY_AVAILABLE = 0x1E, + MTRServiceAreaLandmarkTagMirror MTR_PROVISIONALLY_AVAILABLE = 0x1F, + MTRServiceAreaLandmarkTagNightstand MTR_PROVISIONALLY_AVAILABLE = 0x20, + MTRServiceAreaLandmarkTagOven MTR_PROVISIONALLY_AVAILABLE = 0x21, + MTRServiceAreaLandmarkTagPetBed MTR_PROVISIONALLY_AVAILABLE = 0x22, + MTRServiceAreaLandmarkTagPetBowl MTR_PROVISIONALLY_AVAILABLE = 0x23, + MTRServiceAreaLandmarkTagPetCrate MTR_PROVISIONALLY_AVAILABLE = 0x24, + MTRServiceAreaLandmarkTagRefrigerator MTR_PROVISIONALLY_AVAILABLE = 0x25, + MTRServiceAreaLandmarkTagScratchingPost MTR_PROVISIONALLY_AVAILABLE = 0x26, + MTRServiceAreaLandmarkTagShoeRack MTR_PROVISIONALLY_AVAILABLE = 0x27, + MTRServiceAreaLandmarkTagShower MTR_PROVISIONALLY_AVAILABLE = 0x28, + MTRServiceAreaLandmarkTagSideDoor MTR_PROVISIONALLY_AVAILABLE = 0x29, + MTRServiceAreaLandmarkTagSink MTR_PROVISIONALLY_AVAILABLE = 0x2A, + MTRServiceAreaLandmarkTagSofa MTR_PROVISIONALLY_AVAILABLE = 0x2B, + MTRServiceAreaLandmarkTagStove MTR_PROVISIONALLY_AVAILABLE = 0x2C, + MTRServiceAreaLandmarkTagTable MTR_PROVISIONALLY_AVAILABLE = 0x2D, + MTRServiceAreaLandmarkTagToilet MTR_PROVISIONALLY_AVAILABLE = 0x2E, + MTRServiceAreaLandmarkTagTrashCan MTR_PROVISIONALLY_AVAILABLE = 0x2F, + MTRServiceAreaLandmarkTagLaundryWasher MTR_PROVISIONALLY_AVAILABLE = 0x30, + MTRServiceAreaLandmarkTagWindow MTR_PROVISIONALLY_AVAILABLE = 0x31, + MTRServiceAreaLandmarkTagWineCooler MTR_PROVISIONALLY_AVAILABLE = 0x32, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_ENUM(uint8_t, MTRServiceAreaOperationalStatus) { + MTRServiceAreaOperationalStatusPending MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRServiceAreaOperationalStatusOperating MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRServiceAreaOperationalStatusSkipped MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTRServiceAreaOperationalStatusCompleted MTR_PROVISIONALLY_AVAILABLE = 0x03, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_ENUM(uint8_t, MTRServiceAreaPositionTag) { + MTRServiceAreaPositionTagLeft MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRServiceAreaPositionTagRight MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRServiceAreaPositionTagTop MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTRServiceAreaPositionTagBottom MTR_PROVISIONALLY_AVAILABLE = 0x03, + MTRServiceAreaPositionTagMiddle MTR_PROVISIONALLY_AVAILABLE = 0x04, + MTRServiceAreaPositionTagRow MTR_PROVISIONALLY_AVAILABLE = 0x05, + MTRServiceAreaPositionTagColumn MTR_PROVISIONALLY_AVAILABLE = 0x06, + MTRServiceAreaPositionTagUnder MTR_PROVISIONALLY_AVAILABLE = 0x07, + MTRServiceAreaPositionTagNextTo MTR_PROVISIONALLY_AVAILABLE = 0x08, + MTRServiceAreaPositionTagAround MTR_PROVISIONALLY_AVAILABLE = 0x09, + MTRServiceAreaPositionTagOn MTR_PROVISIONALLY_AVAILABLE = 0x0A, + MTRServiceAreaPositionTagAbove MTR_PROVISIONALLY_AVAILABLE = 0x0B, + MTRServiceAreaPositionTagFrontOf MTR_PROVISIONALLY_AVAILABLE = 0x0C, + MTRServiceAreaPositionTagBehind MTR_PROVISIONALLY_AVAILABLE = 0x0D, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_ENUM(uint8_t, MTRServiceAreaSelectLocationsStatus) { + MTRServiceAreaSelectLocationsStatusSuccess MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRServiceAreaSelectLocationsStatusUnsupportedLocation MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRServiceAreaSelectLocationsStatusDuplicatedLocations MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTRServiceAreaSelectLocationsStatusInvalidInMode MTR_PROVISIONALLY_AVAILABLE = 0x03, + MTRServiceAreaSelectLocationsStatusInvalidSet MTR_PROVISIONALLY_AVAILABLE = 0x04, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_ENUM(uint8_t, MTRServiceAreaSkipCurrentLocationStatus) { + MTRServiceAreaSkipCurrentLocationStatusSuccess MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRServiceAreaSkipCurrentLocationStatusInvalidLocationList MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRServiceAreaSkipCurrentLocationStatusInvalidInMode MTR_PROVISIONALLY_AVAILABLE = 0x02, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_OPTIONS(uint32_t, MTRServiceAreaFeature) { + MTRServiceAreaFeatureListOrder MTR_PROVISIONALLY_AVAILABLE = 0x1, + MTRServiceAreaFeatureSelectWhileRunning MTR_PROVISIONALLY_AVAILABLE = 0x2, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_ENUM(uint8_t, MTRPumpConfigurationAndControlControlMode) { MTRPumpConfigurationAndControlControlModeConstantSpeed MTR_AVAILABLE(ios(16.5), macos(13.4), watchos(9.5), tvos(16.5)) = 0x00, MTRPumpConfigurationAndControlControlModeConstantPressure MTR_AVAILABLE(ios(16.5), macos(13.4), watchos(9.5), tvos(16.5)) = 0x01, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index f5ad47a7917dd0..694f35228a4701 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -64056,6 +64056,495 @@ - (nullable instancetype)initWithDevice:(MTRBaseDevice *)device @end +@implementation MTRBaseClusterServiceArea + +- (void)selectLocationsWithParams:(MTRServiceAreaClusterSelectLocationsParams *)params completion:(void (^)(MTRServiceAreaClusterSelectLocationsResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRServiceAreaClusterSelectLocationsParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = ServiceArea::Commands::SelectLocations::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRServiceAreaClusterSelectLocationsResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} +- (void)skipCurrentLocationWithCompletion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self skipCurrentLocationWithParams:nil completion:completion]; +} +- (void)skipCurrentLocationWithParams:(MTRServiceAreaClusterSkipCurrentLocationParams * _Nullable)params completion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRServiceAreaClusterSkipCurrentLocationParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = ServiceArea::Commands::SkipCurrentLocation::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRServiceAreaClusterSkipCurrentLocationResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)readAttributeSupportedLocationsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::SupportedLocations::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeSupportedLocationsWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ServiceArea::Attributes::SupportedLocations::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeSupportedLocationsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::SupportedLocations::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeSupportedMapsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::SupportedMaps::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeSupportedMapsWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ServiceArea::Attributes::SupportedMaps::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeSupportedMapsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::SupportedMaps::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeSelectedLocationsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::SelectedLocations::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeSelectedLocationsWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ServiceArea::Attributes::SelectedLocations::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeSelectedLocationsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::SelectedLocations::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeCurrentLocationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::CurrentLocation::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeCurrentLocationWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ServiceArea::Attributes::CurrentLocation::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeCurrentLocationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::CurrentLocation::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeEstimatedEndTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::EstimatedEndTime::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeEstimatedEndTimeWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ServiceArea::Attributes::EstimatedEndTime::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeEstimatedEndTimeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::EstimatedEndTime::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeProgressWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::Progress::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeProgressWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ServiceArea::Attributes::Progress::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeProgressWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::Progress::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::GeneratedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ServiceArea::Attributes::GeneratedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::GeneratedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::AcceptedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ServiceArea::Attributes::AcceptedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::AcceptedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::EventList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ServiceArea::Attributes::EventList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::EventList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::AttributeList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ServiceArea::Attributes::AttributeList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::AttributeList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::FeatureMap::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ServiceArea::Attributes::FeatureMap::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::FeatureMap::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::ClusterRevision::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = ServiceArea::Attributes::ClusterRevision::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = ServiceArea::Attributes::ClusterRevision::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +@end + @implementation MTRBaseClusterPumpConfigurationAndControl - (void)readAttributeMaxPressureWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index da9c24e4c35beb..b6c6dc2aba2dc2 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -162,6 +162,7 @@ typedef NS_ENUM(uint32_t, MTRClusterIDType) { MTRClusterIDTypeDoorLockID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000101, MTRClusterIDTypeWindowCoveringID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000102, MTRClusterIDTypeBarrierControlID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000103, + MTRClusterIDTypeServiceAreaID MTR_PROVISIONALLY_AVAILABLE = 0x00000150, MTRClusterIDTypePumpConfigurationAndControlID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000200, MTRClusterIDTypeThermostatID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000201, MTRClusterIDTypeFanControlID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000202, @@ -3099,6 +3100,20 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterBarrierControlAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterBarrierControlAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster ServiceArea attributes + MTRAttributeIDTypeClusterServiceAreaAttributeSupportedLocationsID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRAttributeIDTypeClusterServiceAreaAttributeSupportedMapsID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRAttributeIDTypeClusterServiceAreaAttributeSelectedLocationsID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRAttributeIDTypeClusterServiceAreaAttributeCurrentLocationID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, + MTRAttributeIDTypeClusterServiceAreaAttributeEstimatedEndTimeID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, + MTRAttributeIDTypeClusterServiceAreaAttributeProgressID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, + MTRAttributeIDTypeClusterServiceAreaAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, + MTRAttributeIDTypeClusterServiceAreaAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, + MTRAttributeIDTypeClusterServiceAreaAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, + MTRAttributeIDTypeClusterServiceAreaAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, + MTRAttributeIDTypeClusterServiceAreaAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, + MTRAttributeIDTypeClusterServiceAreaAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster PumpConfigurationAndControl deprecated attribute names MTRClusterPumpConfigurationAndControlAttributeMaxPressureID MTR_DEPRECATED("Please use MTRAttributeIDTypeClusterPumpConfigurationAndControlAttributeMaxPressureID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) @@ -6495,6 +6510,12 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterBarrierControlCommandBarrierControlGoToPercentID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000000, MTRCommandIDTypeClusterBarrierControlCommandBarrierControlStopID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000001, + // Cluster ServiceArea commands + MTRCommandIDTypeClusterServiceAreaCommandSelectLocationsID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRCommandIDTypeClusterServiceAreaCommandSelectLocationsResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRCommandIDTypeClusterServiceAreaCommandSkipCurrentLocationID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRCommandIDTypeClusterServiceAreaCommandSkipCurrentLocationResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, + // Cluster Thermostat deprecated command id names MTRClusterThermostatCommandSetpointRaiseLowerID MTR_DEPRECATED("Please use MTRCommandIDTypeClusterThermostatCommandSetpointRaiseLowerID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 5ca3b9058c217a..c320e8c06e8dea 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -252,6 +252,9 @@ case MTRClusterIDTypeBarrierControlID: result = @"BarrierControl"; break; + case MTRClusterIDTypeServiceAreaID: + result = @"ServiceArea"; + break; case MTRClusterIDTypePumpConfigurationAndControlID: result = @"PumpConfigurationAndControl"; break; @@ -5213,6 +5216,64 @@ break; } + case MTRClusterIDTypeServiceAreaID: + + switch (attributeID) { + + // Cluster ServiceArea attributes + case MTRAttributeIDTypeClusterServiceAreaAttributeSupportedLocationsID: + result = @"SupportedLocations"; + break; + + case MTRAttributeIDTypeClusterServiceAreaAttributeSupportedMapsID: + result = @"SupportedMaps"; + break; + + case MTRAttributeIDTypeClusterServiceAreaAttributeSelectedLocationsID: + result = @"SelectedLocations"; + break; + + case MTRAttributeIDTypeClusterServiceAreaAttributeCurrentLocationID: + result = @"CurrentLocation"; + break; + + case MTRAttributeIDTypeClusterServiceAreaAttributeEstimatedEndTimeID: + result = @"EstimatedEndTime"; + break; + + case MTRAttributeIDTypeClusterServiceAreaAttributeProgressID: + result = @"Progress"; + break; + + case MTRAttributeIDTypeClusterServiceAreaAttributeGeneratedCommandListID: + result = @"GeneratedCommandList"; + break; + + case MTRAttributeIDTypeClusterServiceAreaAttributeAcceptedCommandListID: + result = @"AcceptedCommandList"; + break; + + case MTRAttributeIDTypeClusterServiceAreaAttributeEventListID: + result = @"EventList"; + break; + + case MTRAttributeIDTypeClusterServiceAreaAttributeAttributeListID: + result = @"AttributeList"; + break; + + case MTRAttributeIDTypeClusterServiceAreaAttributeFeatureMapID: + result = @"FeatureMap"; + break; + + case MTRAttributeIDTypeClusterServiceAreaAttributeClusterRevisionID: + result = @"ClusterRevision"; + break; + + default: + result = [NSString stringWithFormat:@"", attributeID]; + break; + } + case MTRClusterIDTypePumpConfigurationAndControlID: switch (attributeID) { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index e2a0873cee6392..c47d2bf28caa4c 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -4379,6 +4379,59 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @end +/** + * Cluster Service Area + * The Service Area cluster provides an interface for controlling the locations where a device should operate, and for querying the current location. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRClusterServiceArea : MTRGenericCluster + +- (void)selectLocationsWithParams:(MTRServiceAreaClusterSelectLocationsParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSelectLocationsResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)skipCurrentLocationWithParams:(MTRServiceAreaClusterSkipCurrentLocationParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)skipCurrentLocationWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeSupportedLocationsWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeSupportedMapsWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeSelectedLocationsWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeCurrentLocationWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeEstimatedEndTimeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeProgressWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRClusterServiceArea (Availability) + +/** + * For all instance methods that take a completion (i.e. command invocations), + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Pump Configuration and Control * An interface for configuring and controlling pumps. diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index 953df0cde7fa90..f04fd07262ea1f 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -12489,6 +12489,128 @@ - (void)barrierControlStopWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSelectLocationsResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRServiceAreaClusterSelectLocationsParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = ServiceArea::Commands::SelectLocations::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRServiceAreaClusterSelectLocationsResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)skipCurrentLocationWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self skipCurrentLocationWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} +- (void)skipCurrentLocationWithParams:(MTRServiceAreaClusterSkipCurrentLocationParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRServiceAreaClusterSkipCurrentLocationParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = ServiceArea::Commands::SkipCurrentLocation::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRServiceAreaClusterSkipCurrentLocationResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (NSDictionary * _Nullable)readAttributeSupportedLocationsWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeSupportedLocationsID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeSupportedMapsWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeSupportedMapsID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeSelectedLocationsWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeSelectedLocationsID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeCurrentLocationWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeCurrentLocationID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeEstimatedEndTimeWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeEstimatedEndTimeID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeProgressWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeProgressID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeGeneratedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeAcceptedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeEventListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeAttributeListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeFeatureMapID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeClusterRevisionID) params:params]; +} + +@end + @implementation MTRClusterPumpConfigurationAndControl - (NSDictionary * _Nullable)readAttributeMaxPressureWithParams:(MTRReadParams * _Nullable)params diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index 6ec4cfb8ee8778..4e74aa8828a718 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -7385,6 +7385,106 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRServiceAreaClusterSelectLocationsParams : NSObject + +@property (nonatomic, copy, getter=getNewLocations) NSArray * _Nullable newLocations MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRServiceAreaClusterSelectLocationsResponseParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull status MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSString * _Nullable statusText MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRServiceAreaClusterSelectLocationsResponseParams with a response-value dictionary + * of the sort that MTRDeviceResponseHandler would receive. + * + * Will return nil and hand out an error if the response-value dictionary is not + * a command data response or is not the right command response. + * + * Will return nil and hand out an error if the data response does not match the known + * schema for this command. + */ +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRServiceAreaClusterSkipCurrentLocationParams : NSObject +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRServiceAreaClusterSkipCurrentLocationResponseParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull status MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSString * _Nullable statusText MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRServiceAreaClusterSkipCurrentLocationResponseParams with a response-value dictionary + * of the sort that MTRDeviceResponseHandler would receive. + * + * Will return nil and hand out an error if the response-value dictionary is not + * a command data response or is not the right command response. + * + * Will return nil and hand out an error if the data response does not match the known + * schema for this command. + */ +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRThermostatClusterSetpointRaiseLowerParams : NSObject diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index ffe9c4121915af..1dd6753fa889ed 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -20888,6 +20888,370 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end +@implementation MTRServiceAreaClusterSelectLocationsParams +- (instancetype)init +{ + if (self = [super init]) { + + _newLocations = nil; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRServiceAreaClusterSelectLocationsParams alloc] init]; + + other.newLocations = self.newLocations; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: newLocations:%@; >", NSStringFromClass([self class]), _newLocations]; + return descriptionString; +} + +@end + +@implementation MTRServiceAreaClusterSelectLocationsParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::ServiceArea::Commands::SelectLocations::Type encodableStruct; + ListFreer listFreer; + { + if (self.newLocations == nil) { + encodableStruct.newLocations.SetNull(); + } else { + auto & nonNullValue_0 = encodableStruct.newLocations.SetNonNull(); + { + using ListType_1 = std::remove_reference_t; + using ListMemberType_1 = ListMemberTypeGetter::Type; + if (self.newLocations.count != 0) { + auto * listHolder_1 = new ListHolder(self.newLocations.count); + if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) { + return CHIP_ERROR_INVALID_ARGUMENT; + } + listFreer.add(listHolder_1); + for (size_t i_1 = 0; i_1 < self.newLocations.count; ++i_1) { + if (![self.newLocations[i_1] isKindOfClass:[NSNumber class]]) { + // Wrong kind of value. + return CHIP_ERROR_INVALID_ARGUMENT; + } + auto element_1 = (NSNumber *) self.newLocations[i_1]; + listHolder_1->mList[i_1] = element_1.unsignedIntValue; + } + nonNullValue_0 = ListType_1(listHolder_1->mList, self.newLocations.count); + } else { + nonNullValue_0 = ListType_1(); + } + } + } + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRServiceAreaClusterSelectLocationsResponseParams +- (instancetype)init +{ + if (self = [super init]) { + + _status = @(0); + + _statusText = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRServiceAreaClusterSelectLocationsResponseParams alloc] init]; + + other.status = self.status; + other.statusText = self.statusText; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: status:%@; statusText:%@; >", NSStringFromClass([self class]), _status, _statusText]; + return descriptionString; +} + +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error +{ + if (!(self = [super init])) { + return nil; + } + + using DecodableType = chip::app::Clusters::ServiceArea::Commands::SelectLocationsResponse::DecodableType; + chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue + clusterID:DecodableType::GetClusterId() + commandID:DecodableType::GetCommandId() + error:error]; + if (buffer.IsNull()) { + return nil; + } + + chip::TLV::TLVReader reader; + reader.Init(buffer->Start(), buffer->DataLength()); + + CHIP_ERROR err = reader.Next(chip::TLV::AnonymousTag()); + if (err == CHIP_NO_ERROR) { + DecodableType decodedStruct; + err = chip::app::DataModel::Decode(reader, decodedStruct); + if (err == CHIP_NO_ERROR) { + err = [self _setFieldsFromDecodableStruct:decodedStruct]; + if (err == CHIP_NO_ERROR) { + return self; + } + } + } + + NSString * errorStr = [NSString stringWithFormat:@"Command payload decoding failed: %s", err.AsString()]; + MTR_LOG_ERROR("%s", errorStr.UTF8String); + if (error != nil) { + NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : NSLocalizedString(errorStr, nil) }; + *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeSchemaMismatch userInfo:userInfo]; + } + return nil; +} + +@end + +@implementation MTRServiceAreaClusterSelectLocationsResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ServiceArea::Commands::SelectLocationsResponse::DecodableType &)decodableStruct +{ + { + self.status = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.status)]; + } + { + if (decodableStruct.statusText.HasValue()) { + self.statusText = AsString(decodableStruct.statusText.Value()); + if (self.statusText == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.statusText = nil; + } + } + return CHIP_NO_ERROR; +} + +@end + +@implementation MTRServiceAreaClusterSkipCurrentLocationParams +- (instancetype)init +{ + if (self = [super init]) { + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRServiceAreaClusterSkipCurrentLocationParams alloc] init]; + + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: >", NSStringFromClass([self class])]; + return descriptionString; +} + +@end + +@implementation MTRServiceAreaClusterSkipCurrentLocationParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocation::Type encodableStruct; + ListFreer listFreer; + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRServiceAreaClusterSkipCurrentLocationResponseParams +- (instancetype)init +{ + if (self = [super init]) { + + _status = @(0); + + _statusText = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRServiceAreaClusterSkipCurrentLocationResponseParams alloc] init]; + + other.status = self.status; + other.statusText = self.statusText; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: status:%@; statusText:%@; >", NSStringFromClass([self class]), _status, _statusText]; + return descriptionString; +} + +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error +{ + if (!(self = [super init])) { + return nil; + } + + using DecodableType = chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocationResponse::DecodableType; + chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue + clusterID:DecodableType::GetClusterId() + commandID:DecodableType::GetCommandId() + error:error]; + if (buffer.IsNull()) { + return nil; + } + + chip::TLV::TLVReader reader; + reader.Init(buffer->Start(), buffer->DataLength()); + + CHIP_ERROR err = reader.Next(chip::TLV::AnonymousTag()); + if (err == CHIP_NO_ERROR) { + DecodableType decodedStruct; + err = chip::app::DataModel::Decode(reader, decodedStruct); + if (err == CHIP_NO_ERROR) { + err = [self _setFieldsFromDecodableStruct:decodedStruct]; + if (err == CHIP_NO_ERROR) { + return self; + } + } + } + + NSString * errorStr = [NSString stringWithFormat:@"Command payload decoding failed: %s", err.AsString()]; + MTR_LOG_ERROR("%s", errorStr.UTF8String); + if (error != nil) { + NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : NSLocalizedString(errorStr, nil) }; + *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeSchemaMismatch userInfo:userInfo]; + } + return nil; +} + +@end + +@implementation MTRServiceAreaClusterSkipCurrentLocationResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocationResponse::DecodableType &)decodableStruct +{ + { + self.status = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.status)]; + } + { + if (decodableStruct.statusText.HasValue()) { + self.statusText = AsString(decodableStruct.statusText.Value()); + if (self.statusText == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.statusText = nil; + } + } + return CHIP_NO_ERROR; +} + +@end + @implementation MTRThermostatClusterSetpointRaiseLowerParams - (instancetype)init { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h index 36938c35dd5637..f281c8e89570d1 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h @@ -1378,6 +1378,30 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRServiceAreaClusterSelectLocationsParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRServiceAreaClusterSelectLocationsResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ServiceArea::Commands::SelectLocationsResponse::DecodableType &)decodableStruct; + +@end + +@interface MTRServiceAreaClusterSkipCurrentLocationParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRServiceAreaClusterSkipCurrentLocationResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocationResponse::DecodableType &)decodableStruct; + +@end + @interface MTRThermostatClusterSetpointRaiseLowerParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm index f49e574232b544..1b96c8c41201d5 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm @@ -758,6 +758,15 @@ static BOOL CommandNeedsTimedInvokeInBarrierControlCluster(AttributeId aAttribut } } } +static BOOL CommandNeedsTimedInvokeInServiceAreaCluster(AttributeId aAttributeId) +{ + using namespace Clusters::ServiceArea; + switch (aAttributeId) { + default: { + return NO; + } + } +} static BOOL CommandNeedsTimedInvokeInPumpConfigurationAndControlCluster(AttributeId aAttributeId) { using namespace Clusters::PumpConfigurationAndControl; @@ -1389,6 +1398,9 @@ BOOL MTRCommandNeedsTimedInvoke(NSNumber * _Nonnull aClusterID, NSNumber * _Nonn case Clusters::BarrierControl::Id: { return CommandNeedsTimedInvokeInBarrierControlCluster(commandID); } + case Clusters::ServiceArea::Id: { + return CommandNeedsTimedInvokeInServiceAreaCluster(commandID); + } case Clusters::PumpConfigurationAndControl::Id: { return CommandNeedsTimedInvokeInPumpConfigurationAndControlCluster(commandID); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm index db48844fca89ee..8de4f7c5966b50 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm @@ -3584,6 +3584,18 @@ static id _Nullable DecodeEventPayloadForBarrierControlCluster(EventId aEventId, *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; return nil; } +static id _Nullable DecodeEventPayloadForServiceAreaCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::ServiceArea; + switch (aEventId) { + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + return nil; +} static id _Nullable DecodeEventPayloadForPumpConfigurationAndControlCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::PumpConfigurationAndControl; @@ -4823,6 +4835,9 @@ id _Nullable MTRDecodeEventPayload(const ConcreteEventPath & aPath, TLV::TLVRead case Clusters::BarrierControl::Id: { return DecodeEventPayloadForBarrierControlCluster(aPath.mEventId, aReader, aError); } + case Clusters::ServiceArea::Id: { + return DecodeEventPayloadForServiceAreaCluster(aPath.mEventId, aReader, aError); + } case Clusters::PumpConfigurationAndControl::Id: { return DecodeEventPayloadForPumpConfigurationAndControlCluster(aPath.mEventId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index 5729c811ab2ac4..2d5da93d9df2f5 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -1511,6 +1511,42 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @property (nonatomic, copy) NSNumber * _Nullable dataIndex MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRServiceAreaClusterHomeLocationStruct : NSObject +@property (nonatomic, copy) NSString * _Nonnull locationName MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable floorNumber MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable areaType MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRServiceAreaClusterLocationInfoStruct : NSObject +@property (nonatomic, copy) MTRServiceAreaClusterHomeLocationStruct * _Nullable locationInfo MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable landmarkTag MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable positionTag MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable surfaceTag MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRServiceAreaClusterLocationStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull locationID MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable mapID MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) MTRServiceAreaClusterLocationInfoStruct * _Nonnull locationInfo MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRServiceAreaClusterMapStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull mapID MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSString * _Nonnull name MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRServiceAreaClusterProgressStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull locationID MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull status MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable totalOperationalTime MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable estimatedTime MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRPumpConfigurationAndControlClusterSupplyVoltageLowEvent : NSObject @end diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index 6f9a82e6231831..559789940c7fb9 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -6262,6 +6262,174 @@ - (NSString *)description @end +@implementation MTRServiceAreaClusterHomeLocationStruct +- (instancetype)init +{ + if (self = [super init]) { + + _locationName = @""; + + _floorNumber = nil; + + _areaType = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRServiceAreaClusterHomeLocationStruct alloc] init]; + + other.locationName = self.locationName; + other.floorNumber = self.floorNumber; + other.areaType = self.areaType; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: locationName:%@; floorNumber:%@; areaType:%@; >", NSStringFromClass([self class]), _locationName, _floorNumber, _areaType]; + return descriptionString; +} + +@end + +@implementation MTRServiceAreaClusterLocationInfoStruct +- (instancetype)init +{ + if (self = [super init]) { + + _locationInfo = nil; + + _landmarkTag = nil; + + _positionTag = nil; + + _surfaceTag = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRServiceAreaClusterLocationInfoStruct alloc] init]; + + other.locationInfo = self.locationInfo; + other.landmarkTag = self.landmarkTag; + other.positionTag = self.positionTag; + other.surfaceTag = self.surfaceTag; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: locationInfo:%@; landmarkTag:%@; positionTag:%@; surfaceTag:%@; >", NSStringFromClass([self class]), _locationInfo, _landmarkTag, _positionTag, _surfaceTag]; + return descriptionString; +} + +@end + +@implementation MTRServiceAreaClusterLocationStruct +- (instancetype)init +{ + if (self = [super init]) { + + _locationID = @(0); + + _mapID = nil; + + _locationInfo = [MTRServiceAreaClusterLocationInfoStruct new]; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRServiceAreaClusterLocationStruct alloc] init]; + + other.locationID = self.locationID; + other.mapID = self.mapID; + other.locationInfo = self.locationInfo; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: locationID:%@; mapID:%@; locationInfo:%@; >", NSStringFromClass([self class]), _locationID, _mapID, _locationInfo]; + return descriptionString; +} + +@end + +@implementation MTRServiceAreaClusterMapStruct +- (instancetype)init +{ + if (self = [super init]) { + + _mapID = @(0); + + _name = @""; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRServiceAreaClusterMapStruct alloc] init]; + + other.mapID = self.mapID; + other.name = self.name; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: mapID:%@; name:%@; >", NSStringFromClass([self class]), _mapID, _name]; + return descriptionString; +} + +@end + +@implementation MTRServiceAreaClusterProgressStruct +- (instancetype)init +{ + if (self = [super init]) { + + _locationID = @(0); + + _status = @(0); + + _totalOperationalTime = nil; + + _estimatedTime = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRServiceAreaClusterProgressStruct alloc] init]; + + other.locationID = self.locationID; + other.status = self.status; + other.totalOperationalTime = self.totalOperationalTime; + other.estimatedTime = self.estimatedTime; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: locationID:%@; status:%@; totalOperationalTime:%@; estimatedTime:%@; >", NSStringFromClass([self class]), _locationID, _status, _totalOperationalTime, _estimatedTime]; + return descriptionString; +} + +@end + @implementation MTRPumpConfigurationAndControlClusterSupplyVoltageLowEvent - (instancetype)init { diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index 9a952b67e21b17..c16c4d688e2744 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -20530,6 +20530,280 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace Attributes } // namespace BarrierControl +namespace ServiceArea { +namespace Attributes { + +namespace CurrentLocation { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::ServiceArea::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (Traits::IsNullValue(temp)) + { + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); + } + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty) +{ + if (value.IsNull()) + { + return SetNull(endpoint, markDirty); + } + + return Set(endpoint, value.Value(), markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } + + return Set(endpoint, value.Value()); +} + +} // namespace CurrentLocation + +namespace EstimatedEndTime { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::ServiceArea::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (Traits::IsNullValue(temp)) + { + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); + } + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_EPOCH_S_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_EPOCH_S_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_EPOCH_S_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_EPOCH_S_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty) +{ + if (value.IsNull()) + { + return SetNull(endpoint, markDirty); + } + + return Set(endpoint, value.Value(), markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } + + return Set(endpoint, value.Value()); +} + +} // namespace EstimatedEndTime + +namespace FeatureMap { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::ServiceArea::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); +} + +} // namespace FeatureMap + +namespace ClusterRevision { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::ServiceArea::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace ServiceArea + namespace PumpConfigurationAndControl { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index feec1e6f04bcb8..4d0c6c1d97ad9a 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -3294,6 +3294,46 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace Attributes } // namespace BarrierControl +namespace ServiceArea { +namespace Attributes { + +namespace CurrentLocation { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int32u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty); +} // namespace CurrentLocation + +namespace EstimatedEndTime { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value); // epoch_s +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty); +} // namespace EstimatedEndTime + +namespace FeatureMap { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); +} // namespace FeatureMap + +namespace ClusterRevision { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace ServiceArea + namespace PumpConfigurationAndControl { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/callback.h b/zzz_generated/app-common/app-common/zap-generated/callback.h index 0f6a34fec9a9cc..1619aeb30881d7 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -423,6 +423,11 @@ void emberAfWindowCoveringClusterInitCallback(chip::EndpointId endpoint); */ void emberAfBarrierControlClusterInitCallback(chip::EndpointId endpoint); +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfServiceAreaClusterInitCallback(chip::EndpointId endpoint); + /** * @param endpoint Endpoint that is being initialized */ @@ -3651,6 +3656,45 @@ MatterBarrierControlClusterServerPreAttributeChangedCallback(const chip::app::Co */ void emberAfBarrierControlClusterServerTickCallback(chip::EndpointId endpoint); +// +// Service Area Cluster +// + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfServiceAreaClusterServerInitCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being shutdown + */ +void MatterServiceAreaClusterServerShutdownCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfServiceAreaClusterClientInitCallback(chip::EndpointId endpoint); + +/** + * @param attributePath Concrete attribute path that changed + */ +void MatterServiceAreaClusterServerAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath); + +/** + * @param attributePath Concrete attribute path to be changed + * @param attributeType Attribute type + * @param size Attribute size + * @param value Attribute value + */ +chip::Protocols::InteractionModel::Status +MatterServiceAreaClusterServerPreAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath, + EmberAfAttributeType attributeType, uint16_t size, uint8_t * value); + +/** + * @param endpoint Endpoint that is being served + */ +void emberAfServiceAreaClusterServerTickCallback(chip::EndpointId endpoint); + // // Pump Configuration and Control Cluster // @@ -6059,6 +6103,18 @@ bool emberAfBarrierControlClusterBarrierControlGoToPercentCallback( bool emberAfBarrierControlClusterBarrierControlStopCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::BarrierControl::Commands::BarrierControlStop::DecodableType & commandData); +/** + * @brief Service Area Cluster SelectLocations Command callback (from client) + */ +bool emberAfServiceAreaClusterSelectLocationsCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ServiceArea::Commands::SelectLocations::DecodableType & commandData); +/** + * @brief Service Area Cluster SkipCurrentLocation Command callback (from client) + */ +bool emberAfServiceAreaClusterSkipCurrentLocationCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocation::DecodableType & commandData); /** * @brief Thermostat Cluster SetpointRaiseLower Command callback (from client) */ diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h index 4ff889fac693cd..e53404d7b32737 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h @@ -2268,6 +2268,273 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(WindowCovering::Type va } } +static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::AreaTypeTag val) +{ + using EnumType = ServiceArea::AreaTypeTag; + switch (val) + { + case EnumType::kAisle: + case EnumType::kAttic: + case EnumType::kBackDoor: + case EnumType::kBackYard: + case EnumType::kBalcony: + case EnumType::kBallroom: + case EnumType::kBathroom: + case EnumType::kBedroom: + case EnumType::kBorder: + case EnumType::kBoxroom: + case EnumType::kBreakfastRoom: + case EnumType::kCarport: + case EnumType::kCellar: + case EnumType::kCloakroom: + case EnumType::kCloset: + case EnumType::kConservatory: + case EnumType::kCorridor: + case EnumType::kCraftRoom: + case EnumType::kCupboard: + case EnumType::kDeck: + case EnumType::kDen: + case EnumType::kDining: + case EnumType::kDrawingRoom: + case EnumType::kDressingRoom: + case EnumType::kDriveway: + case EnumType::kElevator: + case EnumType::kEnsuite: + case EnumType::kEntrance: + case EnumType::kEntryway: + case EnumType::kFamilyRoom: + case EnumType::kFoyer: + case EnumType::kFrontDoor: + case EnumType::kFrontYard: + case EnumType::kGameRoom: + case EnumType::kGarage: + case EnumType::kGarageDoor: + case EnumType::kGarden: + case EnumType::kGardenDoor: + case EnumType::kGuestBathroom: + case EnumType::kGuestBedroom: + case EnumType::kGuestRestroom: + case EnumType::kGuestRoom: + case EnumType::kGym: + case EnumType::kHallway: + case EnumType::kHearthRoom: + case EnumType::kKidsRoom: + case EnumType::kKidsBedroom: + case EnumType::kKitchen: + case EnumType::kLarder: + case EnumType::kLaundryRoom: + case EnumType::kLawn: + case EnumType::kLibrary: + case EnumType::kLivingRoom: + case EnumType::kLounge: + case EnumType::kMediaTvRoom: + case EnumType::kMudRoom: + case EnumType::kMusicRoom: + case EnumType::kNursery: + case EnumType::kOffice: + case EnumType::kOutdoorKitchen: + case EnumType::kOutside: + case EnumType::kPantry: + case EnumType::kParkingLot: + case EnumType::kParlor: + case EnumType::kPatio: + case EnumType::kPlayRoom: + case EnumType::kPoolRoom: + case EnumType::kPorch: + case EnumType::kPrimaryBathroom: + case EnumType::kPrimaryBedroom: + case EnumType::kRamp: + case EnumType::kReceptionRoom: + case EnumType::kRecreationRoom: + case EnumType::kRestroom: + case EnumType::kRoof: + case EnumType::kSauna: + case EnumType::kScullery: + case EnumType::kSewingRoom: + case EnumType::kShed: + case EnumType::kSideDoor: + case EnumType::kSideYard: + case EnumType::kSittingRoom: + case EnumType::kSnug: + case EnumType::kSpa: + case EnumType::kStaircase: + case EnumType::kSteamRoom: + case EnumType::kStorageRoom: + case EnumType::kStudio: + case EnumType::kStudy: + case EnumType::kSunRoom: + case EnumType::kSwimmingPool: + case EnumType::kTerrace: + case EnumType::kUtilityRoom: + case EnumType::kWard: + case EnumType::kWorkshop: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} +static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::FloorSurfaceTag val) +{ + using EnumType = ServiceArea::FloorSurfaceTag; + switch (val) + { + case EnumType::kCarpet: + case EnumType::kCeramic: + case EnumType::kConcrete: + case EnumType::kCork: + case EnumType::kDeepCarpet: + case EnumType::kDirt: + case EnumType::kEngineeredWood: + case EnumType::kGlass: + case EnumType::kGrass: + case EnumType::kHardwood: + case EnumType::kLaminate: + case EnumType::kLinoleum: + case EnumType::kMat: + case EnumType::kMetal: + case EnumType::kPlastic: + case EnumType::kPolishedConcrete: + case EnumType::kRubber: + case EnumType::kRug: + case EnumType::kSand: + case EnumType::kStone: + case EnumType::kTatami: + case EnumType::kTerrazzo: + case EnumType::kTile: + case EnumType::kVinyl: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} +static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::LandmarkTag val) +{ + using EnumType = ServiceArea::LandmarkTag; + switch (val) + { + case EnumType::kAirConditioner: + case EnumType::kAirPurifier: + case EnumType::kBackDoor: + case EnumType::kBarStool: + case EnumType::kBathMat: + case EnumType::kBathtub: + case EnumType::kBed: + case EnumType::kBookshelf: + case EnumType::kChair: + case EnumType::kChristmasTree: + case EnumType::kCoatRack: + case EnumType::kCoffeeTable: + case EnumType::kCookingRange: + case EnumType::kCouch: + case EnumType::kCountertop: + case EnumType::kCradle: + case EnumType::kCrib: + case EnumType::kDesk: + case EnumType::kDiningTable: + case EnumType::kDishwasher: + case EnumType::kDoor: + case EnumType::kDresser: + case EnumType::kLaundryDryer: + case EnumType::kFan: + case EnumType::kFireplace: + case EnumType::kFreezer: + case EnumType::kFrontDoor: + case EnumType::kHighChair: + case EnumType::kKitchenIsland: + case EnumType::kLamp: + case EnumType::kLitterBox: + case EnumType::kMirror: + case EnumType::kNightstand: + case EnumType::kOven: + case EnumType::kPetBed: + case EnumType::kPetBowl: + case EnumType::kPetCrate: + case EnumType::kRefrigerator: + case EnumType::kScratchingPost: + case EnumType::kShoeRack: + case EnumType::kShower: + case EnumType::kSideDoor: + case EnumType::kSink: + case EnumType::kSofa: + case EnumType::kStove: + case EnumType::kTable: + case EnumType::kToilet: + case EnumType::kTrashCan: + case EnumType::kLaundryWasher: + case EnumType::kWindow: + case EnumType::kWineCooler: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} +static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::OperationalStatusEnum val) +{ + using EnumType = ServiceArea::OperationalStatusEnum; + switch (val) + { + case EnumType::kPending: + case EnumType::kOperating: + case EnumType::kSkipped: + case EnumType::kCompleted: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} +static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::PositionTag val) +{ + using EnumType = ServiceArea::PositionTag; + switch (val) + { + case EnumType::kLeft: + case EnumType::kRight: + case EnumType::kTop: + case EnumType::kBottom: + case EnumType::kMiddle: + case EnumType::kRow: + case EnumType::kColumn: + case EnumType::kUnder: + case EnumType::kNextTo: + case EnumType::kAround: + case EnumType::kOn: + case EnumType::kAbove: + case EnumType::kFrontOf: + case EnumType::kBehind: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} +static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::SelectLocationsStatus val) +{ + using EnumType = ServiceArea::SelectLocationsStatus; + switch (val) + { + case EnumType::kSuccess: + case EnumType::kUnsupportedLocation: + case EnumType::kDuplicatedLocations: + case EnumType::kInvalidInMode: + case EnumType::kInvalidSet: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} +static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::SkipCurrentLocationStatus val) +{ + using EnumType = ServiceArea::SkipCurrentLocationStatus; + switch (val) + { + case EnumType::kSuccess: + case EnumType::kInvalidLocationList: + case EnumType::kInvalidInMode: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} + static auto __attribute__((unused)) EnsureKnownEnumValue(PumpConfigurationAndControl::ControlModeEnum val) { using EnumType = PumpConfigurationAndControl::ControlModeEnum; diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h index 40d73a3fade401..27601f4e651c63 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h @@ -3426,6 +3426,282 @@ enum class BarrierControlSafetyStatus : uint16_t }; } // namespace BarrierControl +namespace ServiceArea { + +// Enum for AreaTypeTag +enum class AreaTypeTag : uint8_t +{ + kAisle = 0x00, + kAttic = 0x01, + kBackDoor = 0x02, + kBackYard = 0x03, + kBalcony = 0x04, + kBallroom = 0x05, + kBathroom = 0x06, + kBedroom = 0x07, + kBorder = 0x08, + kBoxroom = 0x09, + kBreakfastRoom = 0x0A, + kCarport = 0x0B, + kCellar = 0x0C, + kCloakroom = 0x0D, + kCloset = 0x0E, + kConservatory = 0x0F, + kCorridor = 0x10, + kCraftRoom = 0x11, + kCupboard = 0x12, + kDeck = 0x13, + kDen = 0x14, + kDining = 0x15, + kDrawingRoom = 0x16, + kDressingRoom = 0x17, + kDriveway = 0x18, + kElevator = 0x19, + kEnsuite = 0x1A, + kEntrance = 0x1B, + kEntryway = 0x1C, + kFamilyRoom = 0x1D, + kFoyer = 0x1E, + kFrontDoor = 0x1F, + kFrontYard = 0x20, + kGameRoom = 0x21, + kGarage = 0x22, + kGarageDoor = 0x23, + kGarden = 0x24, + kGardenDoor = 0x25, + kGuestBathroom = 0x26, + kGuestBedroom = 0x27, + kGuestRestroom = 0x28, + kGuestRoom = 0x29, + kGym = 0x2A, + kHallway = 0x2B, + kHearthRoom = 0x2C, + kKidsRoom = 0x2D, + kKidsBedroom = 0x2E, + kKitchen = 0x2F, + kLarder = 0x30, + kLaundryRoom = 0x31, + kLawn = 0x32, + kLibrary = 0x33, + kLivingRoom = 0x34, + kLounge = 0x35, + kMediaTvRoom = 0x36, + kMudRoom = 0x37, + kMusicRoom = 0x38, + kNursery = 0x39, + kOffice = 0x3A, + kOutdoorKitchen = 0x3B, + kOutside = 0x3C, + kPantry = 0x3D, + kParkingLot = 0x3E, + kParlor = 0x3F, + kPatio = 0x40, + kPlayRoom = 0x41, + kPoolRoom = 0x42, + kPorch = 0x43, + kPrimaryBathroom = 0x44, + kPrimaryBedroom = 0x45, + kRamp = 0x46, + kReceptionRoom = 0x47, + kRecreationRoom = 0x48, + kRestroom = 0x49, + kRoof = 0x4A, + kSauna = 0x4B, + kScullery = 0x4C, + kSewingRoom = 0x4D, + kShed = 0x4E, + kSideDoor = 0x4F, + kSideYard = 0x50, + kSittingRoom = 0x51, + kSnug = 0x52, + kSpa = 0x53, + kStaircase = 0x54, + kSteamRoom = 0x55, + kStorageRoom = 0x56, + kStudio = 0x57, + kStudy = 0x58, + kSunRoom = 0x59, + kSwimmingPool = 0x5A, + kTerrace = 0x5B, + kUtilityRoom = 0x5C, + kWard = 0x5D, + kWorkshop = 0x5E, + // All received enum values that are not listed above will be mapped + // to kUnknownEnumValue. This is a helper enum value that should only + // be used by code to process how it handles receiving and unknown + // enum value. This specific should never be transmitted. + kUnknownEnumValue = 95, +}; + +// Enum for FloorSurfaceTag +enum class FloorSurfaceTag : uint8_t +{ + kCarpet = 0x00, + kCeramic = 0x01, + kConcrete = 0x02, + kCork = 0x03, + kDeepCarpet = 0x04, + kDirt = 0x05, + kEngineeredWood = 0x06, + kGlass = 0x07, + kGrass = 0x08, + kHardwood = 0x09, + kLaminate = 0x0A, + kLinoleum = 0x0B, + kMat = 0x0C, + kMetal = 0x0D, + kPlastic = 0x0E, + kPolishedConcrete = 0x0F, + kRubber = 0x10, + kRug = 0x11, + kSand = 0x12, + kStone = 0x13, + kTatami = 0x14, + kTerrazzo = 0x15, + kTile = 0x16, + kVinyl = 0x17, + // All received enum values that are not listed above will be mapped + // to kUnknownEnumValue. This is a helper enum value that should only + // be used by code to process how it handles receiving and unknown + // enum value. This specific should never be transmitted. + kUnknownEnumValue = 24, +}; + +// Enum for LandmarkTag +enum class LandmarkTag : uint8_t +{ + kAirConditioner = 0x00, + kAirPurifier = 0x01, + kBackDoor = 0x02, + kBarStool = 0x03, + kBathMat = 0x04, + kBathtub = 0x05, + kBed = 0x06, + kBookshelf = 0x07, + kChair = 0x08, + kChristmasTree = 0x09, + kCoatRack = 0x0A, + kCoffeeTable = 0x0B, + kCookingRange = 0x0C, + kCouch = 0x0D, + kCountertop = 0x0E, + kCradle = 0x0F, + kCrib = 0x10, + kDesk = 0x11, + kDiningTable = 0x12, + kDishwasher = 0x13, + kDoor = 0x14, + kDresser = 0x15, + kLaundryDryer = 0x16, + kFan = 0x17, + kFireplace = 0x18, + kFreezer = 0x19, + kFrontDoor = 0x1A, + kHighChair = 0x1B, + kKitchenIsland = 0x1C, + kLamp = 0x1D, + kLitterBox = 0x1E, + kMirror = 0x1F, + kNightstand = 0x20, + kOven = 0x21, + kPetBed = 0x22, + kPetBowl = 0x23, + kPetCrate = 0x24, + kRefrigerator = 0x25, + kScratchingPost = 0x26, + kShoeRack = 0x27, + kShower = 0x28, + kSideDoor = 0x29, + kSink = 0x2A, + kSofa = 0x2B, + kStove = 0x2C, + kTable = 0x2D, + kToilet = 0x2E, + kTrashCan = 0x2F, + kLaundryWasher = 0x30, + kWindow = 0x31, + kWineCooler = 0x32, + // All received enum values that are not listed above will be mapped + // to kUnknownEnumValue. This is a helper enum value that should only + // be used by code to process how it handles receiving and unknown + // enum value. This specific should never be transmitted. + kUnknownEnumValue = 51, +}; + +// Enum for OperationalStatusEnum +enum class OperationalStatusEnum : uint8_t +{ + kPending = 0x00, + kOperating = 0x01, + kSkipped = 0x02, + kCompleted = 0x03, + // All received enum values that are not listed above will be mapped + // to kUnknownEnumValue. This is a helper enum value that should only + // be used by code to process how it handles receiving and unknown + // enum value. This specific should never be transmitted. + kUnknownEnumValue = 4, +}; + +// Enum for PositionTag +enum class PositionTag : uint8_t +{ + kLeft = 0x00, + kRight = 0x01, + kTop = 0x02, + kBottom = 0x03, + kMiddle = 0x04, + kRow = 0x05, + kColumn = 0x06, + kUnder = 0x07, + kNextTo = 0x08, + kAround = 0x09, + kOn = 0x0A, + kAbove = 0x0B, + kFrontOf = 0x0C, + kBehind = 0x0D, + // All received enum values that are not listed above will be mapped + // to kUnknownEnumValue. This is a helper enum value that should only + // be used by code to process how it handles receiving and unknown + // enum value. This specific should never be transmitted. + kUnknownEnumValue = 14, +}; + +// Enum for SelectLocationsStatus +enum class SelectLocationsStatus : uint8_t +{ + kSuccess = 0x00, + kUnsupportedLocation = 0x01, + kDuplicatedLocations = 0x02, + kInvalidInMode = 0x03, + kInvalidSet = 0x04, + // All received enum values that are not listed above will be mapped + // to kUnknownEnumValue. This is a helper enum value that should only + // be used by code to process how it handles receiving and unknown + // enum value. This specific should never be transmitted. + kUnknownEnumValue = 5, +}; + +// Enum for SkipCurrentLocationStatus +enum class SkipCurrentLocationStatus : uint8_t +{ + kSuccess = 0x00, + kInvalidLocationList = 0x01, + kInvalidInMode = 0x02, + // All received enum values that are not listed above will be mapped + // to kUnknownEnumValue. This is a helper enum value that should only + // be used by code to process how it handles receiving and unknown + // enum value. This specific should never be transmitted. + kUnknownEnumValue = 3, +}; + +// Bitmap for Feature +enum class Feature : uint32_t +{ + kListOrder = 0x1, + kSelectWhileRunning = 0x2, +}; +} // namespace ServiceArea + namespace PumpConfigurationAndControl { // Enum for ControlModeEnum diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index 2f12fdc6048972..289909746b0640 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -19444,6 +19444,418 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre namespace Events {} // namespace Events } // namespace BarrierControl +namespace ServiceArea { +namespace Structs { + +namespace HomeLocationStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kLocationName), locationName); + encoder.Encode(to_underlying(Fields::kFloorNumber), floorNumber); + encoder.Encode(to_underlying(Fields::kAreaType), areaType); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kLocationName)) + { + err = DataModel::Decode(reader, locationName); + } + else if (__context_tag == to_underlying(Fields::kFloorNumber)) + { + err = DataModel::Decode(reader, floorNumber); + } + else if (__context_tag == to_underlying(Fields::kAreaType)) + { + err = DataModel::Decode(reader, areaType); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace HomeLocationStruct + +namespace LocationInfoStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kLocationInfo), locationInfo); + encoder.Encode(to_underlying(Fields::kLandmarkTag), landmarkTag); + encoder.Encode(to_underlying(Fields::kPositionTag), positionTag); + encoder.Encode(to_underlying(Fields::kSurfaceTag), surfaceTag); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kLocationInfo)) + { + err = DataModel::Decode(reader, locationInfo); + } + else if (__context_tag == to_underlying(Fields::kLandmarkTag)) + { + err = DataModel::Decode(reader, landmarkTag); + } + else if (__context_tag == to_underlying(Fields::kPositionTag)) + { + err = DataModel::Decode(reader, positionTag); + } + else if (__context_tag == to_underlying(Fields::kSurfaceTag)) + { + err = DataModel::Decode(reader, surfaceTag); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace LocationInfoStruct + +namespace LocationStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kLocationID), locationID); + encoder.Encode(to_underlying(Fields::kMapID), mapID); + encoder.Encode(to_underlying(Fields::kLocationInfo), locationInfo); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kLocationID)) + { + err = DataModel::Decode(reader, locationID); + } + else if (__context_tag == to_underlying(Fields::kMapID)) + { + err = DataModel::Decode(reader, mapID); + } + else if (__context_tag == to_underlying(Fields::kLocationInfo)) + { + err = DataModel::Decode(reader, locationInfo); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace LocationStruct + +namespace MapStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kMapID), mapID); + encoder.Encode(to_underlying(Fields::kName), name); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kMapID)) + { + err = DataModel::Decode(reader, mapID); + } + else if (__context_tag == to_underlying(Fields::kName)) + { + err = DataModel::Decode(reader, name); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace MapStruct + +namespace ProgressStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kLocationID), locationID); + encoder.Encode(to_underlying(Fields::kStatus), status); + encoder.Encode(to_underlying(Fields::kTotalOperationalTime), totalOperationalTime); + encoder.Encode(to_underlying(Fields::kEstimatedTime), estimatedTime); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kLocationID)) + { + err = DataModel::Decode(reader, locationID); + } + else if (__context_tag == to_underlying(Fields::kStatus)) + { + err = DataModel::Decode(reader, status); + } + else if (__context_tag == to_underlying(Fields::kTotalOperationalTime)) + { + err = DataModel::Decode(reader, totalOperationalTime); + } + else if (__context_tag == to_underlying(Fields::kEstimatedTime)) + { + err = DataModel::Decode(reader, estimatedTime); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace ProgressStruct +} // namespace Structs + +namespace Commands { +namespace SelectLocations { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kNewLocations), newLocations); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kNewLocations)) + { + err = DataModel::Decode(reader, newLocations); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace SelectLocations. +namespace SelectLocationsResponse { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kStatus), status); + encoder.Encode(to_underlying(Fields::kStatusText), statusText); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kStatus)) + { + err = DataModel::Decode(reader, status); + } + else if (__context_tag == to_underlying(Fields::kStatusText)) + { + err = DataModel::Decode(reader, statusText); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace SelectLocationsResponse. +namespace SkipCurrentLocation { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + } +} +} // namespace SkipCurrentLocation. +namespace SkipCurrentLocationResponse { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kStatus), status); + encoder.Encode(to_underlying(Fields::kStatusText), statusText); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kStatus)) + { + err = DataModel::Decode(reader, status); + } + else if (__context_tag == to_underlying(Fields::kStatusText)) + { + err = DataModel::Decode(reader, statusText); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace SkipCurrentLocationResponse. +} // namespace Commands + +namespace Attributes { +CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path) +{ + switch (path.mAttributeId) + { + case Attributes::SupportedLocations::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, supportedLocations); + case Attributes::SupportedMaps::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, supportedMaps); + case Attributes::SelectedLocations::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, selectedLocations); + case Attributes::CurrentLocation::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, currentLocation); + case Attributes::EstimatedEndTime::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, estimatedEndTime); + case Attributes::Progress::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, progress); + case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, generatedCommandList); + case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, acceptedCommandList); + case Attributes::EventList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, eventList); + case Attributes::AttributeList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, attributeList); + case Attributes::FeatureMap::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, featureMap); + case Attributes::ClusterRevision::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, clusterRevision); + default: + return CHIP_NO_ERROR; + } +} +} // namespace Attributes + +namespace Events {} // namespace Events + +} // namespace ServiceArea namespace PumpConfigurationAndControl { namespace Commands {} // namespace Commands @@ -30908,6 +31320,13 @@ bool CommandIsFabricScoped(ClusterId aCluster, CommandId aCommand) return false; } } + case Clusters::ServiceArea::Id: { + switch (aCommand) + { + default: + return false; + } + } case Clusters::Thermostat::Id: { switch (aCommand) { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index 75d2d9e01ff1f4..d396989d0a6edf 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -27270,6 +27270,438 @@ struct TypeInfo }; } // namespace Attributes } // namespace BarrierControl +namespace ServiceArea { +namespace Structs { +namespace HomeLocationStruct { +enum class Fields : uint8_t +{ + kLocationName = 0, + kFloorNumber = 1, + kAreaType = 2, +}; + +struct Type +{ +public: + chip::CharSpan locationName; + DataModel::Nullable floorNumber; + DataModel::Nullable areaType; + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = false; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +using DecodableType = Type; + +} // namespace HomeLocationStruct +namespace LocationInfoStruct { +enum class Fields : uint8_t +{ + kLocationInfo = 0, + kLandmarkTag = 1, + kPositionTag = 2, + kSurfaceTag = 3, +}; + +struct Type +{ +public: + DataModel::Nullable locationInfo; + DataModel::Nullable landmarkTag; + DataModel::Nullable positionTag; + DataModel::Nullable surfaceTag; + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = false; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +using DecodableType = Type; + +} // namespace LocationInfoStruct +namespace LocationStruct { +enum class Fields : uint8_t +{ + kLocationID = 0, + kMapID = 1, + kLocationInfo = 2, +}; + +struct Type +{ +public: + uint32_t locationID = static_cast(0); + DataModel::Nullable mapID; + Structs::LocationInfoStruct::Type locationInfo; + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = false; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +using DecodableType = Type; + +} // namespace LocationStruct +namespace MapStruct { +enum class Fields : uint8_t +{ + kMapID = 0, + kName = 1, +}; + +struct Type +{ +public: + uint8_t mapID = static_cast(0); + chip::CharSpan name; + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = false; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +using DecodableType = Type; + +} // namespace MapStruct +namespace ProgressStruct { +enum class Fields : uint8_t +{ + kLocationID = 0, + kStatus = 1, + kTotalOperationalTime = 2, + kEstimatedTime = 3, +}; + +struct Type +{ +public: + uint32_t locationID = static_cast(0); + OperationalStatusEnum status = static_cast(0); + Optional> totalOperationalTime; + Optional> estimatedTime; + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = false; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +using DecodableType = Type; + +} // namespace ProgressStruct +} // namespace Structs + +namespace Commands { +// Forward-declarations so we can reference these later. + +namespace SelectLocations { +struct Type; +struct DecodableType; +} // namespace SelectLocations + +namespace SelectLocationsResponse { +struct Type; +struct DecodableType; +} // namespace SelectLocationsResponse + +namespace SkipCurrentLocation { +struct Type; +struct DecodableType; +} // namespace SkipCurrentLocation + +namespace SkipCurrentLocationResponse { +struct Type; +struct DecodableType; +} // namespace SkipCurrentLocationResponse + +} // namespace Commands + +namespace Commands { +namespace SelectLocations { +enum class Fields : uint8_t +{ + kNewLocations = 0, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::SelectLocations::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } + + DataModel::Nullable> newLocations; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::ServiceArea::Commands::SelectLocationsResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::SelectLocations::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } + + DataModel::Nullable> newLocations; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace SelectLocations +namespace SelectLocationsResponse { +enum class Fields : uint8_t +{ + kStatus = 0, + kStatusText = 1, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::SelectLocationsResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } + + SelectLocationsStatus status = static_cast(0); + Optional statusText; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::SelectLocationsResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } + + SelectLocationsStatus status = static_cast(0); + Optional statusText; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace SelectLocationsResponse +namespace SkipCurrentLocation { +enum class Fields : uint8_t +{ +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::SkipCurrentLocation::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::ServiceArea::Commands::SkipCurrentLocationResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::SkipCurrentLocation::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace SkipCurrentLocation +namespace SkipCurrentLocationResponse { +enum class Fields : uint8_t +{ + kStatus = 0, + kStatusText = 1, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::SkipCurrentLocationResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } + + SkipCurrentLocationStatus status = static_cast(0); + Optional statusText; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::SkipCurrentLocationResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } + + SkipCurrentLocationStatus status = static_cast(0); + Optional statusText; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace SkipCurrentLocationResponse +} // namespace Commands + +namespace Attributes { + +namespace SupportedLocations { +struct TypeInfo +{ + using Type = chip::app::DataModel::List; + using DecodableType = + chip::app::DataModel::DecodableList; + using DecodableArgType = + const chip::app::DataModel::DecodableList &; + + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::SupportedLocations::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace SupportedLocations +namespace SupportedMaps { +struct TypeInfo +{ + using Type = chip::app::DataModel::Nullable< + chip::app::DataModel::List>; + using DecodableType = chip::app::DataModel::Nullable< + chip::app::DataModel::DecodableList>; + using DecodableArgType = const chip::app::DataModel::Nullable< + chip::app::DataModel::DecodableList> &; + + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::SupportedMaps::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace SupportedMaps +namespace SelectedLocations { +struct TypeInfo +{ + using Type = chip::app::DataModel::Nullable>; + using DecodableType = chip::app::DataModel::Nullable>; + using DecodableArgType = const chip::app::DataModel::Nullable> &; + + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::SelectedLocations::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace SelectedLocations +namespace CurrentLocation { +struct TypeInfo +{ + using Type = chip::app::DataModel::Nullable; + using DecodableType = chip::app::DataModel::Nullable; + using DecodableArgType = const chip::app::DataModel::Nullable &; + + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::CurrentLocation::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace CurrentLocation +namespace EstimatedEndTime { +struct TypeInfo +{ + using Type = chip::app::DataModel::Nullable; + using DecodableType = chip::app::DataModel::Nullable; + using DecodableArgType = const chip::app::DataModel::Nullable &; + + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::EstimatedEndTime::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace EstimatedEndTime +namespace Progress { +struct TypeInfo +{ + using Type = chip::app::DataModel::Nullable< + chip::app::DataModel::List>; + using DecodableType = chip::app::DataModel::Nullable< + chip::app::DataModel::DecodableList>; + using DecodableArgType = const chip::app::DataModel::Nullable< + chip::app::DataModel::DecodableList> &; + + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::Progress::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace Progress +namespace GeneratedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } +}; +} // namespace GeneratedCommandList +namespace AcceptedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } +}; +} // namespace AcceptedCommandList +namespace EventList { +struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } +}; +} // namespace EventList +namespace AttributeList { +struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } +}; +} // namespace AttributeList +namespace FeatureMap { +struct TypeInfo : public Clusters::Globals::Attributes::FeatureMap::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } +}; +} // namespace FeatureMap +namespace ClusterRevision { +struct TypeInfo : public Clusters::Globals::Attributes::ClusterRevision::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } +}; +} // namespace ClusterRevision + +struct TypeInfo +{ + struct DecodableType + { + static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); + + Attributes::SupportedLocations::TypeInfo::DecodableType supportedLocations; + Attributes::SupportedMaps::TypeInfo::DecodableType supportedMaps; + Attributes::SelectedLocations::TypeInfo::DecodableType selectedLocations; + Attributes::CurrentLocation::TypeInfo::DecodableType currentLocation; + Attributes::EstimatedEndTime::TypeInfo::DecodableType estimatedEndTime; + Attributes::Progress::TypeInfo::DecodableType progress; + Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; + Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; + Attributes::EventList::TypeInfo::DecodableType eventList; + Attributes::AttributeList::TypeInfo::DecodableType attributeList; + Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); + Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); + }; +}; +} // namespace Attributes +} // namespace ServiceArea namespace PumpConfigurationAndControl { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h index ad8b2c79bbecd7..03ddaed214890c 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h @@ -4663,6 +4663,60 @@ static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; } // namespace Attributes } // namespace BarrierControl +namespace ServiceArea { +namespace Attributes { + +namespace SupportedLocations { +static constexpr AttributeId Id = 0x00000000; +} // namespace SupportedLocations + +namespace SupportedMaps { +static constexpr AttributeId Id = 0x00000001; +} // namespace SupportedMaps + +namespace SelectedLocations { +static constexpr AttributeId Id = 0x00000002; +} // namespace SelectedLocations + +namespace CurrentLocation { +static constexpr AttributeId Id = 0x00000003; +} // namespace CurrentLocation + +namespace EstimatedEndTime { +static constexpr AttributeId Id = 0x00000004; +} // namespace EstimatedEndTime + +namespace Progress { +static constexpr AttributeId Id = 0x00000005; +} // namespace Progress + +namespace GeneratedCommandList { +static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; +} // namespace GeneratedCommandList + +namespace AcceptedCommandList { +static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; +} // namespace AcceptedCommandList + +namespace EventList { +static constexpr AttributeId Id = Globals::Attributes::EventList::Id; +} // namespace EventList + +namespace AttributeList { +static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; +} // namespace AttributeList + +namespace FeatureMap { +static constexpr AttributeId Id = Globals::Attributes::FeatureMap::Id; +} // namespace FeatureMap + +namespace ClusterRevision { +static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace ServiceArea + namespace PumpConfigurationAndControl { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h index 030893e204de34..eab334c8ce3a29 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h @@ -259,6 +259,9 @@ static constexpr ClusterId Id = 0x00000102; namespace BarrierControl { static constexpr ClusterId Id = 0x00000103; } // namespace BarrierControl +namespace ServiceArea { +static constexpr ClusterId Id = 0x00000150; +} // namespace ServiceArea namespace PumpConfigurationAndControl { static constexpr ClusterId Id = 0x00000200; } // namespace PumpConfigurationAndControl diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h index 98bfd4eaceb968..7e0003ebe52fc4 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h @@ -1235,6 +1235,28 @@ static constexpr CommandId Id = 0x00000001; } // namespace Commands } // namespace BarrierControl +namespace ServiceArea { +namespace Commands { + +namespace SelectLocations { +static constexpr CommandId Id = 0x00000000; +} // namespace SelectLocations + +namespace SelectLocationsResponse { +static constexpr CommandId Id = 0x00000001; +} // namespace SelectLocationsResponse + +namespace SkipCurrentLocation { +static constexpr CommandId Id = 0x00000002; +} // namespace SkipCurrentLocation + +namespace SkipCurrentLocationResponse { +static constexpr CommandId Id = 0x00000003; +} // namespace SkipCurrentLocationResponse + +} // namespace Commands +} // namespace ServiceArea + namespace Thermostat { namespace Commands { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index a160e9db747c7a..a9658c4a1ace4f 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -113,6 +113,7 @@ | DoorLock | 0x0101 | | WindowCovering | 0x0102 | | BarrierControl | 0x0103 | +| ServiceArea | 0x0150 | | PumpConfigurationAndControl | 0x0200 | | Thermostat | 0x0201 | | FanControl | 0x0202 | @@ -9059,6 +9060,106 @@ class BarrierControlBarrierControlStop : public ClusterCommand chip::app::Clusters::BarrierControl::Commands::BarrierControlStop::Type mRequest; }; +/*----------------------------------------------------------------------------*\ +| Cluster ServiceArea | 0x0150 | +|------------------------------------------------------------------------------| +| Commands: | | +| * SelectLocations | 0x00 | +| * SkipCurrentLocation | 0x02 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * SupportedLocations | 0x0000 | +| * SupportedMaps | 0x0001 | +| * SelectedLocations | 0x0002 | +| * CurrentLocation | 0x0003 | +| * EstimatedEndTime | 0x0004 | +| * Progress | 0x0005 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +/* + * Command SelectLocations + */ +class ServiceAreaSelectLocations : public ClusterCommand +{ +public: + ServiceAreaSelectLocations(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("select-locations", credsIssuerConfig), mComplex_NewLocations(&mRequest.newLocations) + { + AddArgument("NewLocations", &mComplex_NewLocations); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SelectLocations::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SelectLocations::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::ServiceArea::Commands::SelectLocations::Type mRequest; + TypedComplexArgument>> mComplex_NewLocations; +}; + +/* + * Command SkipCurrentLocation + */ +class ServiceAreaSkipCurrentLocation : public ClusterCommand +{ +public: + ServiceAreaSkipCurrentLocation(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("skip-current-location", credsIssuerConfig) + { + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocation::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocation::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocation::Type mRequest; +}; + /*----------------------------------------------------------------------------*\ | Cluster PumpConfigurationAndControl | 0x0200 | |------------------------------------------------------------------------------| @@ -22113,6 +22214,88 @@ void registerClusterBarrierControl(Commands & commands, CredentialIssuerCommands commands.RegisterCluster(clusterName, clusterCommands); } +void registerClusterServiceArea(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) +{ + using namespace chip::app::Clusters::ServiceArea; + + const char * clusterName = "ServiceArea"; + + commands_list clusterCommands = { + // + // Commands + // + make_unique(Id, credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // + // + // Attributes + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "supported-locations", Attributes::SupportedLocations::Id, credsIssuerConfig), // + make_unique(Id, "supported-maps", Attributes::SupportedMaps::Id, credsIssuerConfig), // + make_unique(Id, "selected-locations", Attributes::SelectedLocations::Id, credsIssuerConfig), // + make_unique(Id, "current-location", Attributes::CurrentLocation::Id, credsIssuerConfig), // + make_unique(Id, "estimated-end-time", Attributes::EstimatedEndTime::Id, credsIssuerConfig), // + make_unique(Id, "progress", Attributes::Progress::Id, credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + make_unique>(Id, credsIssuerConfig), // + make_unique>>( + Id, "supported-locations", Attributes::SupportedLocations::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>>( + Id, "supported-maps", Attributes::SupportedMaps::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>>( + Id, "selected-locations", Attributes::SelectedLocations::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>(Id, "current-location", 0, UINT32_MAX, + Attributes::CurrentLocation::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>(Id, "estimated-end-time", 0, UINT32_MAX, + Attributes::EstimatedEndTime::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>>( + Id, "progress", Attributes::Progress::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, + credsIssuerConfig), // + make_unique>>( + Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "cluster-revision", 0, UINT16_MAX, Attributes::ClusterRevision::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "supported-locations", Attributes::SupportedLocations::Id, credsIssuerConfig), // + make_unique(Id, "supported-maps", Attributes::SupportedMaps::Id, credsIssuerConfig), // + make_unique(Id, "selected-locations", Attributes::SelectedLocations::Id, credsIssuerConfig), // + make_unique(Id, "current-location", Attributes::CurrentLocation::Id, credsIssuerConfig), // + make_unique(Id, "estimated-end-time", Attributes::EstimatedEndTime::Id, credsIssuerConfig), // + make_unique(Id, "progress", Attributes::Progress::Id, credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + // + // Events + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + }; + + commands.RegisterCluster(clusterName, clusterCommands); +} void registerClusterPumpConfigurationAndControl(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) { using namespace chip::app::Clusters::PumpConfigurationAndControl; @@ -27423,6 +27606,7 @@ void registerClusters(Commands & commands, CredentialIssuerCommands * credsIssue registerClusterDoorLock(commands, credsIssuerConfig); registerClusterWindowCovering(commands, credsIssuerConfig); registerClusterBarrierControl(commands, credsIssuerConfig); + registerClusterServiceArea(commands, credsIssuerConfig); registerClusterPumpConfigurationAndControl(commands, credsIssuerConfig); registerClusterThermostat(commands, credsIssuerConfig); registerClusterFanControl(commands, credsIssuerConfig); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp index f0970c2c4cdeea..6c7da78177ff10 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp @@ -3684,6 +3684,206 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::DoorLock::Structs::Cre ComplexArgumentParser::Finalize(request.credentialIndex); } +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::ServiceArea::Structs::HomeLocationStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("HomeLocationStruct.locationName", "locationName", + value.isMember("locationName"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("HomeLocationStruct.floorNumber", "floorNumber", value.isMember("floorNumber"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("HomeLocationStruct.areaType", "areaType", value.isMember("areaType"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "locationName"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.locationName, value["locationName"])); + valueCopy.removeMember("locationName"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "floorNumber"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.floorNumber, value["floorNumber"])); + valueCopy.removeMember("floorNumber"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "areaType"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.areaType, value["areaType"])); + valueCopy.removeMember("areaType"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs::HomeLocationStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.locationName); + ComplexArgumentParser::Finalize(request.floorNumber); + ComplexArgumentParser::Finalize(request.areaType); +} + +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::ServiceArea::Structs::LocationInfoStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LocationInfoStruct.locationInfo", "locationInfo", + value.isMember("locationInfo"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("LocationInfoStruct.landmarkTag", "landmarkTag", value.isMember("landmarkTag"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("LocationInfoStruct.positionTag", "positionTag", value.isMember("positionTag"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("LocationInfoStruct.surfaceTag", "surfaceTag", value.isMember("surfaceTag"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "locationInfo"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.locationInfo, value["locationInfo"])); + valueCopy.removeMember("locationInfo"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "landmarkTag"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.landmarkTag, value["landmarkTag"])); + valueCopy.removeMember("landmarkTag"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "positionTag"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.positionTag, value["positionTag"])); + valueCopy.removeMember("positionTag"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "surfaceTag"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.surfaceTag, value["surfaceTag"])); + valueCopy.removeMember("surfaceTag"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs::LocationInfoStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.locationInfo); + ComplexArgumentParser::Finalize(request.landmarkTag); + ComplexArgumentParser::Finalize(request.positionTag); + ComplexArgumentParser::Finalize(request.surfaceTag); +} + +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::ServiceArea::Structs::LocationStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("LocationStruct.locationID", "locationID", value.isMember("locationID"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LocationStruct.mapID", "mapID", value.isMember("mapID"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("LocationStruct.locationInfo", "locationInfo", value.isMember("locationInfo"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "locationID"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.locationID, value["locationID"])); + valueCopy.removeMember("locationID"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "mapID"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.mapID, value["mapID"])); + valueCopy.removeMember("mapID"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "locationInfo"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.locationInfo, value["locationInfo"])); + valueCopy.removeMember("locationInfo"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs::LocationStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.locationID); + ComplexArgumentParser::Finalize(request.mapID); + ComplexArgumentParser::Finalize(request.locationInfo); +} + +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::ServiceArea::Structs::MapStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MapStruct.mapID", "mapID", value.isMember("mapID"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("MapStruct.name", "name", value.isMember("name"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "mapID"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.mapID, value["mapID"])); + valueCopy.removeMember("mapID"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "name"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.name, value["name"])); + valueCopy.removeMember("name"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs::MapStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.mapID); + ComplexArgumentParser::Finalize(request.name); +} + +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::ServiceArea::Structs::ProgressStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("ProgressStruct.locationID", "locationID", value.isMember("locationID"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ProgressStruct.status", "status", value.isMember("status"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "locationID"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.locationID, value["locationID"])); + valueCopy.removeMember("locationID"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "status"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.status, value["status"])); + valueCopy.removeMember("status"); + + if (value.isMember("totalOperationalTime")) + { + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "totalOperationalTime"); + ReturnErrorOnFailure( + ComplexArgumentParser::Setup(labelWithMember, request.totalOperationalTime, value["totalOperationalTime"])); + } + valueCopy.removeMember("totalOperationalTime"); + + if (value.isMember("estimatedTime")) + { + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "estimatedTime"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.estimatedTime, value["estimatedTime"])); + } + valueCopy.removeMember("estimatedTime"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs::ProgressStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.locationID); + ComplexArgumentParser::Finalize(request.status); + ComplexArgumentParser::Finalize(request.totalOperationalTime); + ComplexArgumentParser::Finalize(request.estimatedTime); +} + CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Thermostat::Structs::ScheduleTransitionStruct::Type & request, Json::Value & value) diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h index 074f8c5d2c7c93..4d7544b92daa32 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h @@ -425,6 +425,31 @@ static CHIP_ERROR Setup(const char * label, chip::app::Clusters::DoorLock::Struc static void Finalize(chip::app::Clusters::DoorLock::Structs::CredentialStruct::Type & request); +static CHIP_ERROR Setup(const char * label, chip::app::Clusters::ServiceArea::Structs::HomeLocationStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::ServiceArea::Structs::HomeLocationStruct::Type & request); + +static CHIP_ERROR Setup(const char * label, chip::app::Clusters::ServiceArea::Structs::LocationInfoStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::ServiceArea::Structs::LocationInfoStruct::Type & request); + +static CHIP_ERROR Setup(const char * label, chip::app::Clusters::ServiceArea::Structs::LocationStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::ServiceArea::Structs::LocationStruct::Type & request); + +static CHIP_ERROR Setup(const char * label, chip::app::Clusters::ServiceArea::Structs::MapStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::ServiceArea::Structs::MapStruct::Type & request); + +static CHIP_ERROR Setup(const char * label, chip::app::Clusters::ServiceArea::Structs::ProgressStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::ServiceArea::Structs::ProgressStruct::Type & request); + static CHIP_ERROR Setup(const char * label, chip::app::Clusters::Thermostat::Structs::ScheduleTransitionStruct::Type & request, Json::Value & value); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index 1845cb7ac5fe7d..1f8be3d7029a79 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -3257,6 +3257,179 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, return CHIP_NO_ERROR; } +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::ServiceArea::Structs::HomeLocationStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("LocationName", indent + 1, value.locationName); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LocationName'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("FloorNumber", indent + 1, value.floorNumber); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'FloorNumber'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("AreaType", indent + 1, value.areaType); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'AreaType'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::ServiceArea::Structs::LocationInfoStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("LocationInfo", indent + 1, value.locationInfo); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LocationInfo'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("LandmarkTag", indent + 1, value.landmarkTag); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LandmarkTag'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("PositionTag", indent + 1, value.positionTag); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'PositionTag'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("SurfaceTag", indent + 1, value.surfaceTag); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'SurfaceTag'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::ServiceArea::Structs::LocationStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("LocationID", indent + 1, value.locationID); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LocationID'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("MapID", indent + 1, value.mapID); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'MapID'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("LocationInfo", indent + 1, value.locationInfo); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LocationInfo'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::ServiceArea::Structs::MapStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("MapID", indent + 1, value.mapID); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'MapID'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Name", indent + 1, value.name); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Name'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::ServiceArea::Structs::ProgressStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("LocationID", indent + 1, value.locationID); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LocationID'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Status", indent + 1, value.status); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Status'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("TotalOperationalTime", indent + 1, value.totalOperationalTime); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'TotalOperationalTime'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("EstimatedTime", indent + 1, value.estimatedTime); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'EstimatedTime'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const chip::app::Clusters::Thermostat::Structs::ScheduleTransitionStruct::DecodableType & value) @@ -7783,6 +7956,24 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; } +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const ServiceArea::Commands::SelectLocationsResponse::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("status", indent + 1, value.status)); + ReturnErrorOnFailure(DataModelLogger::LogValue("statusText", indent + 1, value.statusText)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const ServiceArea::Commands::SkipCurrentLocationResponse::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("status", indent + 1, value.status)); + ReturnErrorOnFailure(DataModelLogger::LogValue("statusText", indent + 1, value.statusText)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const Thermostat::Commands::GetWeeklyScheduleResponse::DecodableType & value) { @@ -13822,6 +14013,76 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP } break; } + case ServiceArea::Id: { + switch (path.mAttributeId) + { + case ServiceArea::Attributes::SupportedLocations::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("SupportedLocations", 1, value); + } + case ServiceArea::Attributes::SupportedMaps::Id: { + chip::app::DataModel::Nullable< + chip::app::DataModel::DecodableList> + value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("SupportedMaps", 1, value); + } + case ServiceArea::Attributes::SelectedLocations::Id: { + chip::app::DataModel::Nullable> value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("SelectedLocations", 1, value); + } + case ServiceArea::Attributes::CurrentLocation::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("CurrentLocation", 1, value); + } + case ServiceArea::Attributes::EstimatedEndTime::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EstimatedEndTime", 1, value); + } + case ServiceArea::Attributes::Progress::Id: { + chip::app::DataModel::Nullable< + chip::app::DataModel::DecodableList> + value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("Progress", 1, value); + } + case ServiceArea::Attributes::GeneratedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("GeneratedCommandList", 1, value); + } + case ServiceArea::Attributes::AcceptedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AcceptedCommandList", 1, value); + } + case ServiceArea::Attributes::EventList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EventList", 1, value); + } + case ServiceArea::Attributes::AttributeList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AttributeList", 1, value); + } + case ServiceArea::Attributes::FeatureMap::Id: { + uint32_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("FeatureMap", 1, value); + } + case ServiceArea::Attributes::ClusterRevision::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ClusterRevision", 1, value); + } + } + break; + } case PumpConfigurationAndControl::Id: { switch (path.mAttributeId) { @@ -18682,6 +18943,22 @@ CHIP_ERROR DataModelLogger::LogCommand(const chip::app::ConcreteCommandPath & pa } break; } + case ServiceArea::Id: { + switch (path.mCommandId) + { + case ServiceArea::Commands::SelectLocationsResponse::Id: { + ServiceArea::Commands::SelectLocationsResponse::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("SelectLocationsResponse", 1, value); + } + case ServiceArea::Commands::SkipCurrentLocationResponse::Id: { + ServiceArea::Commands::SkipCurrentLocationResponse::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("SkipCurrentLocationResponse", 1, value); + } + } + break; + } case Thermostat::Id: { switch (path.mCommandId) { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h index 0e3ede94434295..ab1040c7069e3b 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h @@ -267,6 +267,21 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::DoorLock::Structs::CredentialStruct::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::ServiceArea::Structs::HomeLocationStruct::DecodableType & value); + +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::ServiceArea::Structs::LocationInfoStruct::DecodableType & value); + +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::ServiceArea::Structs::LocationStruct::DecodableType & value); + +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::ServiceArea::Structs::MapStruct::DecodableType & value); + +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::ServiceArea::Structs::ProgressStruct::DecodableType & value); + static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Thermostat::Structs::ScheduleTransitionStruct::DecodableType & value); @@ -742,6 +757,10 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::DoorLock::Commands::SetCredentialResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::DoorLock::Commands::GetCredentialStatusResponse::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::ServiceArea::Commands::SelectLocationsResponse::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocationResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Thermostat::Commands::GetWeeklyScheduleResponse::DecodableType & value); static CHIP_ERROR diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index 58147bd1e54e96..2bea6e6b3fff8a 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -115,6 +115,7 @@ | DoorLock | 0x0101 | | WindowCovering | 0x0102 | | BarrierControl | 0x0103 | +| ServiceArea | 0x0150 | | PumpConfigurationAndControl | 0x0200 | | Thermostat | 0x0201 | | FanControl | 0x0202 | @@ -100678,6 +100679,1178 @@ class SubscribeAttributeBarrierControlClusterRevision : public SubscribeAttribut } }; +#if MTR_ENABLE_PROVISIONAL +/*----------------------------------------------------------------------------*\ +| Cluster ServiceArea | 0x0150 | +|------------------------------------------------------------------------------| +| Commands: | | +| * SelectLocations | 0x00 | +| * SkipCurrentLocation | 0x02 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * SupportedLocations | 0x0000 | +| * SupportedMaps | 0x0001 | +| * SelectedLocations | 0x0002 | +| * CurrentLocation | 0x0003 | +| * EstimatedEndTime | 0x0004 | +| * Progress | 0x0005 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +#if MTR_ENABLE_PROVISIONAL +/* + * Command SelectLocations + */ +class ServiceAreaSelectLocations : public ClusterCommand { +public: + ServiceAreaSelectLocations() + : ClusterCommand("select-locations") + , mComplex_NewLocations(&mRequest.newLocations) + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("NewLocations", &mComplex_NewLocations); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SelectLocations::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRServiceAreaClusterSelectLocationsParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + if (mRequest.newLocations.IsNull()) { + params.newLocations = nil; + } else { + { // Scope for our temporary variables + auto * array_1 = [NSMutableArray new]; + for (auto & entry_1 : mRequest.newLocations.Value()) { + NSNumber * newElement_1; + newElement_1 = [NSNumber numberWithUnsignedInt:entry_1]; + [array_1 addObject:newElement_1]; + } + params.newLocations = array_1; + } + } +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster selectLocationsWithParams:params completion: + ^(MTRServiceAreaClusterSelectLocationsResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::ServiceArea::Commands::SelectLocationsResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::ServiceArea::Commands::SelectLocationsResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::ServiceArea::Commands::SelectLocations::Type mRequest; + TypedComplexArgument>> mComplex_NewLocations; +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command SkipCurrentLocation + */ +class ServiceAreaSkipCurrentLocation : public ClusterCommand { +public: + ServiceAreaSkipCurrentLocation() + : ClusterCommand("skip-current-location") + { + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocation::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRServiceAreaClusterSkipCurrentLocationParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster skipCurrentLocationWithParams:params completion: + ^(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocationResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocationResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: +}; + +#endif // MTR_ENABLE_PROVISIONAL + +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute SupportedLocations + */ +class ReadServiceAreaSupportedLocations : public ReadAttribute { +public: + ReadServiceAreaSupportedLocations() + : ReadAttribute("supported-locations") + { + } + + ~ReadServiceAreaSupportedLocations() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::SupportedLocations::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeSupportedLocationsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.SupportedLocations response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ServiceArea SupportedLocations read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeServiceAreaSupportedLocations : public SubscribeAttribute { +public: + SubscribeAttributeServiceAreaSupportedLocations() + : SubscribeAttribute("supported-locations") + { + } + + ~SubscribeAttributeServiceAreaSupportedLocations() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::SupportedLocations::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeSupportedLocationsWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.SupportedLocations response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute SupportedMaps + */ +class ReadServiceAreaSupportedMaps : public ReadAttribute { +public: + ReadServiceAreaSupportedMaps() + : ReadAttribute("supported-maps") + { + } + + ~ReadServiceAreaSupportedMaps() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::SupportedMaps::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeSupportedMapsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.SupportedMaps response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ServiceArea SupportedMaps read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeServiceAreaSupportedMaps : public SubscribeAttribute { +public: + SubscribeAttributeServiceAreaSupportedMaps() + : SubscribeAttribute("supported-maps") + { + } + + ~SubscribeAttributeServiceAreaSupportedMaps() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::SupportedMaps::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeSupportedMapsWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.SupportedMaps response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute SelectedLocations + */ +class ReadServiceAreaSelectedLocations : public ReadAttribute { +public: + ReadServiceAreaSelectedLocations() + : ReadAttribute("selected-locations") + { + } + + ~ReadServiceAreaSelectedLocations() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::SelectedLocations::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeSelectedLocationsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.SelectedLocations response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ServiceArea SelectedLocations read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeServiceAreaSelectedLocations : public SubscribeAttribute { +public: + SubscribeAttributeServiceAreaSelectedLocations() + : SubscribeAttribute("selected-locations") + { + } + + ~SubscribeAttributeServiceAreaSelectedLocations() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::SelectedLocations::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeSelectedLocationsWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.SelectedLocations response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute CurrentLocation + */ +class ReadServiceAreaCurrentLocation : public ReadAttribute { +public: + ReadServiceAreaCurrentLocation() + : ReadAttribute("current-location") + { + } + + ~ReadServiceAreaCurrentLocation() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::CurrentLocation::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeCurrentLocationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.CurrentLocation response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ServiceArea CurrentLocation read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeServiceAreaCurrentLocation : public SubscribeAttribute { +public: + SubscribeAttributeServiceAreaCurrentLocation() + : SubscribeAttribute("current-location") + { + } + + ~SubscribeAttributeServiceAreaCurrentLocation() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::CurrentLocation::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeCurrentLocationWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.CurrentLocation response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute EstimatedEndTime + */ +class ReadServiceAreaEstimatedEndTime : public ReadAttribute { +public: + ReadServiceAreaEstimatedEndTime() + : ReadAttribute("estimated-end-time") + { + } + + ~ReadServiceAreaEstimatedEndTime() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::EstimatedEndTime::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEstimatedEndTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.EstimatedEndTime response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ServiceArea EstimatedEndTime read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeServiceAreaEstimatedEndTime : public SubscribeAttribute { +public: + SubscribeAttributeServiceAreaEstimatedEndTime() + : SubscribeAttribute("estimated-end-time") + { + } + + ~SubscribeAttributeServiceAreaEstimatedEndTime() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::EstimatedEndTime::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeEstimatedEndTimeWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.EstimatedEndTime response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute Progress + */ +class ReadServiceAreaProgress : public ReadAttribute { +public: + ReadServiceAreaProgress() + : ReadAttribute("progress") + { + } + + ~ReadServiceAreaProgress() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::Progress::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeProgressWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.Progress response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ServiceArea Progress read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeServiceAreaProgress : public SubscribeAttribute { +public: + SubscribeAttributeServiceAreaProgress() + : SubscribeAttribute("progress") + { + } + + ~SubscribeAttributeServiceAreaProgress() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::Progress::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeProgressWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.Progress response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute GeneratedCommandList + */ +class ReadServiceAreaGeneratedCommandList : public ReadAttribute { +public: + ReadServiceAreaGeneratedCommandList() + : ReadAttribute("generated-command-list") + { + } + + ~ReadServiceAreaGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ServiceArea GeneratedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeServiceAreaGeneratedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeServiceAreaGeneratedCommandList() + : SubscribeAttribute("generated-command-list") + { + } + + ~SubscribeAttributeServiceAreaGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeGeneratedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AcceptedCommandList + */ +class ReadServiceAreaAcceptedCommandList : public ReadAttribute { +public: + ReadServiceAreaAcceptedCommandList() + : ReadAttribute("accepted-command-list") + { + } + + ~ReadServiceAreaAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ServiceArea AcceptedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeServiceAreaAcceptedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeServiceAreaAcceptedCommandList() + : SubscribeAttribute("accepted-command-list") + { + } + + ~SubscribeAttributeServiceAreaAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAcceptedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute EventList + */ +class ReadServiceAreaEventList : public ReadAttribute { +public: + ReadServiceAreaEventList() + : ReadAttribute("event-list") + { + } + + ~ReadServiceAreaEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ServiceArea EventList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeServiceAreaEventList : public SubscribeAttribute { +public: + SubscribeAttributeServiceAreaEventList() + : SubscribeAttribute("event-list") + { + } + + ~SubscribeAttributeServiceAreaEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeEventListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AttributeList + */ +class ReadServiceAreaAttributeList : public ReadAttribute { +public: + ReadServiceAreaAttributeList() + : ReadAttribute("attribute-list") + { + } + + ~ReadServiceAreaAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ServiceArea AttributeList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeServiceAreaAttributeList : public SubscribeAttribute { +public: + SubscribeAttributeServiceAreaAttributeList() + : SubscribeAttribute("attribute-list") + { + } + + ~SubscribeAttributeServiceAreaAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAttributeListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute FeatureMap + */ +class ReadServiceAreaFeatureMap : public ReadAttribute { +public: + ReadServiceAreaFeatureMap() + : ReadAttribute("feature-map") + { + } + + ~ReadServiceAreaFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ServiceArea FeatureMap read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeServiceAreaFeatureMap : public SubscribeAttribute { +public: + SubscribeAttributeServiceAreaFeatureMap() + : SubscribeAttribute("feature-map") + { + } + + ~SubscribeAttributeServiceAreaFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeFeatureMapWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ClusterRevision + */ +class ReadServiceAreaClusterRevision : public ReadAttribute { +public: + ReadServiceAreaClusterRevision() + : ReadAttribute("cluster-revision") + { + } + + ~ReadServiceAreaClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ServiceArea ClusterRevision read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeServiceAreaClusterRevision : public SubscribeAttribute { +public: + SubscribeAttributeServiceAreaClusterRevision() + : SubscribeAttribute("cluster-revision") + { + } + + ~SubscribeAttributeServiceAreaClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeClusterRevisionWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#endif // MTR_ENABLE_PROVISIONAL /*----------------------------------------------------------------------------*\ | Cluster PumpConfigurationAndControl | 0x0200 | |------------------------------------------------------------------------------| @@ -189332,6 +190505,77 @@ void registerClusterBarrierControl(Commands & commands) commands.RegisterCluster(clusterName, clusterCommands); } +void registerClusterServiceArea(Commands & commands) +{ +#if MTR_ENABLE_PROVISIONAL + using namespace chip::app::Clusters::ServiceArea; + + const char * clusterName = "ServiceArea"; + + commands_list clusterCommands = { + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + make_unique(Id), // + make_unique(Id), // + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + }; + + commands.RegisterCluster(clusterName, clusterCommands); +#endif // MTR_ENABLE_PROVISIONAL +} void registerClusterPumpConfigurationAndControl(Commands & commands) { using namespace chip::app::Clusters::PumpConfigurationAndControl; @@ -192323,6 +193567,7 @@ void registerClusters(Commands & commands) registerClusterDoorLock(commands); registerClusterWindowCovering(commands); registerClusterBarrierControl(commands); + registerClusterServiceArea(commands); registerClusterPumpConfigurationAndControl(commands); registerClusterThermostat(commands); registerClusterFanControl(commands); From b63c2714318075d35188106afb0362fefc8ea165 Mon Sep 17 00:00:00 2001 From: Anton Usmansky Date: Wed, 26 Jun 2024 19:05:40 +0300 Subject: [PATCH 10/21] feat: possibility to get node id of the unsolicited message sender (#33704) --- src/messaging/ExchangeDelegate.h | 14 ++++++++++++-- src/messaging/ExchangeMgr.cpp | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/messaging/ExchangeDelegate.h b/src/messaging/ExchangeDelegate.h index 97a5a0adaebb42..cf2eea8910954f 100644 --- a/src/messaging/ExchangeDelegate.h +++ b/src/messaging/ExchangeDelegate.h @@ -140,7 +140,7 @@ class DLL_EXPORT ExchangeDelegate /** * @brief * This class handles unsolicited messages. The implementation can select an exchange delegate to use based on the payload header - * of the incoming message. + * of the incoming message or its session. */ class DLL_EXPORT UnsolicitedMessageHandler { @@ -158,9 +158,19 @@ class DLL_EXPORT UnsolicitedMessageHandler * * @param[in] payloadHeader A reference to the PayloadHeader object for the unsolicited message. The protocol and message * type of this header match the UnsolicitedMessageHandler. + * @param[in] session A reference to the session where unsolicited message was received. * @param[out] newDelegate A new exchange delegate to be used by the new exchange created to handle the message. */ - virtual CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, ExchangeDelegate *& newDelegate) = 0; + virtual CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, const SessionHandle & session, + ExchangeDelegate *& newDelegate) + { + return OnUnsolicitedMessageReceived(payloadHeader, newDelegate); + } + + virtual CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, ExchangeDelegate *& newDelegate) + { + return CHIP_ERROR_NOT_IMPLEMENTED; + } /** * @brief diff --git a/src/messaging/ExchangeMgr.cpp b/src/messaging/ExchangeMgr.cpp index c60b948c87f814..bf92fa22f54985 100644 --- a/src/messaging/ExchangeMgr.cpp +++ b/src/messaging/ExchangeMgr.cpp @@ -320,7 +320,7 @@ void ExchangeManager::OnMessageReceived(const PacketHeader & packetHeader, const ExchangeDelegate * delegate = nullptr; // Fetch delegate from the handler - CHIP_ERROR err = matchingUMH->Handler->OnUnsolicitedMessageReceived(payloadHeader, delegate); + CHIP_ERROR err = matchingUMH->Handler->OnUnsolicitedMessageReceived(payloadHeader, session, delegate); if (err != CHIP_NO_ERROR) { // Using same error message for all errors to reduce code size. From dd0c49b29409bf62d35d23d345564f7a8560120c Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 26 Jun 2024 14:19:10 -0400 Subject: [PATCH 11/21] ZAP regen on master (#34088) * ZAP regen * undo submodules updates --------- Co-authored-by: Andrei Litvin --- .../ServiceAreaClusterHomeLocationStruct.kt | 2 +- .../ServiceAreaClusterLocationInfoStruct.kt | 6 +-- .../ServiceAreaClusterLocationStruct.kt | 4 +- .../ServiceAreaClusterProgressStruct.kt | 4 +- .../cluster/clusters/ServiceAreaCluster.kt | 54 +++++++++---------- .../ServiceAreaClusterHomeLocationStruct.kt | 2 +- .../ServiceAreaClusterLocationInfoStruct.kt | 6 +-- .../ServiceAreaClusterLocationStruct.kt | 4 +- .../ServiceAreaClusterProgressStruct.kt | 4 +- 9 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt index 7262fc9102917c..4eb2b2ea14784e 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt @@ -25,7 +25,7 @@ import matter.tlv.TlvWriter class ServiceAreaClusterHomeLocationStruct( val locationName: String, val floorNumber: Int?, - val areaType: UInt? + val areaType: UInt?, ) { override fun toString(): String = buildString { append("ServiceAreaClusterHomeLocationStruct {\n") diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt index 4ddb164dd98834..c6137199382840 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt @@ -26,7 +26,7 @@ class ServiceAreaClusterLocationInfoStruct( val locationInfo: ServiceAreaClusterHomeLocationStruct?, val landmarkTag: UInt?, val positionTag: UInt?, - val surfaceTag: UInt? + val surfaceTag: UInt?, ) { override fun toString(): String = buildString { append("ServiceAreaClusterLocationInfoStruct {\n") @@ -76,7 +76,7 @@ class ServiceAreaClusterLocationInfoStruct( if (!tlvReader.isNull()) { ServiceAreaClusterHomeLocationStruct.fromTlv( ContextSpecificTag(TAG_LOCATION_INFO), - tlvReader + tlvReader, ) } else { tlvReader.getNull(ContextSpecificTag(TAG_LOCATION_INFO)) @@ -110,7 +110,7 @@ class ServiceAreaClusterLocationInfoStruct( locationInfo, landmarkTag, positionTag, - surfaceTag + surfaceTag, ) } } diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationStruct.kt index 1e34a8c330b656..f77ae437cad74c 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationStruct.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationStruct.kt @@ -25,7 +25,7 @@ import matter.tlv.TlvWriter class ServiceAreaClusterLocationStruct( val locationID: ULong, val mapID: UInt?, - val locationInfo: ServiceAreaClusterLocationInfoStruct + val locationInfo: ServiceAreaClusterLocationInfoStruct, ) { override fun toString(): String = buildString { append("ServiceAreaClusterLocationStruct {\n") @@ -67,7 +67,7 @@ class ServiceAreaClusterLocationStruct( val locationInfo = ServiceAreaClusterLocationInfoStruct.fromTlv( ContextSpecificTag(TAG_LOCATION_INFO), - tlvReader + tlvReader, ) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterProgressStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterProgressStruct.kt index d65a0faa19c1a2..b601af531e103d 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterProgressStruct.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterProgressStruct.kt @@ -27,7 +27,7 @@ class ServiceAreaClusterProgressStruct( val locationID: ULong, val status: UInt, val totalOperationalTime: Optional?, - val estimatedTime: Optional? + val estimatedTime: Optional?, ) { override fun toString(): String = buildString { append("ServiceAreaClusterProgressStruct {\n") @@ -102,7 +102,7 @@ class ServiceAreaClusterProgressStruct( locationID, status, totalOperationalTime, - estimatedTime + estimatedTime, ) } } diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/ServiceAreaCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/ServiceAreaCluster.kt index 11203b5f2a99b7..75e608837b40f0 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/ServiceAreaCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/ServiceAreaCluster.kt @@ -149,7 +149,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e suspend fun selectLocations( newLocations: List?, - timedInvokeTimeout: Duration? = null + timedInvokeTimeout: Duration? = null, ): SelectLocationsResponse { val commandId: UInt = 0u @@ -170,7 +170,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e InvokeRequest( CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), tlvPayload = tlvWriter.getEncoded(), - timedRequest = timedInvokeTimeout + timedRequest = timedInvokeTimeout, ) val response: InvokeResponse = controller.invoke(request) @@ -230,7 +230,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e InvokeRequest( CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), tlvPayload = tlvWriter.getEncoded(), - timedRequest = timedInvokeTimeout + timedRequest = timedInvokeTimeout, ) val response: InvokeResponse = controller.invoke(request) @@ -317,7 +317,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e suspend fun subscribeSupportedLocationsAttribute( minInterval: Int, - maxInterval: Int + maxInterval: Int, ): Flow { val ATTRIBUTE_ID: UInt = 0u val attributePaths = @@ -330,7 +330,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e eventPaths = emptyList(), attributePaths = attributePaths, minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()) + maxInterval = Duration.ofSeconds(maxInterval.toLong()), ) return controller.subscribe(subscribeRequest).transform { subscriptionState -> @@ -419,7 +419,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e suspend fun subscribeSupportedMapsAttribute( minInterval: Int, - maxInterval: Int + maxInterval: Int, ): Flow { val ATTRIBUTE_ID: UInt = 1u val attributePaths = @@ -432,7 +432,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e eventPaths = emptyList(), attributePaths = attributePaths, minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()) + maxInterval = Duration.ofSeconds(maxInterval.toLong()), ) return controller.subscribe(subscribeRequest).transform { subscriptionState -> @@ -524,7 +524,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e suspend fun subscribeSelectedLocationsAttribute( minInterval: Int, - maxInterval: Int + maxInterval: Int, ): Flow { val ATTRIBUTE_ID: UInt = 2u val attributePaths = @@ -537,7 +537,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e eventPaths = emptyList(), attributePaths = attributePaths, minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()) + maxInterval = Duration.ofSeconds(maxInterval.toLong()), ) return controller.subscribe(subscribeRequest).transform { subscriptionState -> @@ -629,7 +629,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e suspend fun subscribeCurrentLocationAttribute( minInterval: Int, - maxInterval: Int + maxInterval: Int, ): Flow { val ATTRIBUTE_ID: UInt = 3u val attributePaths = @@ -642,7 +642,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e eventPaths = emptyList(), attributePaths = attributePaths, minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()) + maxInterval = Duration.ofSeconds(maxInterval.toLong()), ) return controller.subscribe(subscribeRequest).transform { subscriptionState -> @@ -732,7 +732,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e suspend fun subscribeEstimatedEndTimeAttribute( minInterval: Int, - maxInterval: Int + maxInterval: Int, ): Flow { val ATTRIBUTE_ID: UInt = 4u val attributePaths = @@ -745,7 +745,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e eventPaths = emptyList(), attributePaths = attributePaths, minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()) + maxInterval = Duration.ofSeconds(maxInterval.toLong()), ) return controller.subscribe(subscribeRequest).transform { subscriptionState -> @@ -841,7 +841,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e suspend fun subscribeProgressAttribute( minInterval: Int, - maxInterval: Int + maxInterval: Int, ): Flow { val ATTRIBUTE_ID: UInt = 5u val attributePaths = @@ -854,7 +854,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e eventPaths = emptyList(), attributePaths = attributePaths, minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()) + maxInterval = Duration.ofSeconds(maxInterval.toLong()), ) return controller.subscribe(subscribeRequest).transform { subscriptionState -> @@ -945,7 +945,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e suspend fun subscribeGeneratedCommandListAttribute( minInterval: Int, - maxInterval: Int + maxInterval: Int, ): Flow { val ATTRIBUTE_ID: UInt = 65528u val attributePaths = @@ -958,7 +958,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e eventPaths = emptyList(), attributePaths = attributePaths, minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()) + maxInterval = Duration.ofSeconds(maxInterval.toLong()), ) return controller.subscribe(subscribeRequest).transform { subscriptionState -> @@ -1042,7 +1042,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e suspend fun subscribeAcceptedCommandListAttribute( minInterval: Int, - maxInterval: Int + maxInterval: Int, ): Flow { val ATTRIBUTE_ID: UInt = 65529u val attributePaths = @@ -1055,7 +1055,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e eventPaths = emptyList(), attributePaths = attributePaths, minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()) + maxInterval = Duration.ofSeconds(maxInterval.toLong()), ) return controller.subscribe(subscribeRequest).transform { subscriptionState -> @@ -1139,7 +1139,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e suspend fun subscribeEventListAttribute( minInterval: Int, - maxInterval: Int + maxInterval: Int, ): Flow { val ATTRIBUTE_ID: UInt = 65530u val attributePaths = @@ -1152,7 +1152,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e eventPaths = emptyList(), attributePaths = attributePaths, minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()) + maxInterval = Duration.ofSeconds(maxInterval.toLong()), ) return controller.subscribe(subscribeRequest).transform { subscriptionState -> @@ -1234,7 +1234,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e suspend fun subscribeAttributeListAttribute( minInterval: Int, - maxInterval: Int + maxInterval: Int, ): Flow { val ATTRIBUTE_ID: UInt = 65531u val attributePaths = @@ -1247,7 +1247,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e eventPaths = emptyList(), attributePaths = attributePaths, minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()) + maxInterval = Duration.ofSeconds(maxInterval.toLong()), ) return controller.subscribe(subscribeRequest).transform { subscriptionState -> @@ -1322,7 +1322,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e suspend fun subscribeFeatureMapAttribute( minInterval: Int, - maxInterval: Int + maxInterval: Int, ): Flow { val ATTRIBUTE_ID: UInt = 65532u val attributePaths = @@ -1335,7 +1335,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e eventPaths = emptyList(), attributePaths = attributePaths, minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()) + maxInterval = Duration.ofSeconds(maxInterval.toLong()), ) return controller.subscribe(subscribeRequest).transform { subscriptionState -> @@ -1403,7 +1403,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e suspend fun subscribeClusterRevisionAttribute( minInterval: Int, - maxInterval: Int + maxInterval: Int, ): Flow { val ATTRIBUTE_ID: UInt = 65533u val attributePaths = @@ -1416,7 +1416,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e eventPaths = emptyList(), attributePaths = attributePaths, minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()) + maxInterval = Duration.ofSeconds(maxInterval.toLong()), ) return controller.subscribe(subscribeRequest).transform { subscriptionState -> diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt index 5af3730a4460a8..76eb3671a26962 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt @@ -25,7 +25,7 @@ import matter.tlv.TlvWriter class ServiceAreaClusterHomeLocationStruct( val locationName: String, val floorNumber: Short?, - val areaType: UByte? + val areaType: UByte?, ) { override fun toString(): String = buildString { append("ServiceAreaClusterHomeLocationStruct {\n") diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt index c53b65c2dbb22f..5c8b08507bb76f 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt @@ -26,7 +26,7 @@ class ServiceAreaClusterLocationInfoStruct( val locationInfo: ServiceAreaClusterHomeLocationStruct?, val landmarkTag: UByte?, val positionTag: UByte?, - val surfaceTag: UByte? + val surfaceTag: UByte?, ) { override fun toString(): String = buildString { append("ServiceAreaClusterLocationInfoStruct {\n") @@ -76,7 +76,7 @@ class ServiceAreaClusterLocationInfoStruct( if (!tlvReader.isNull()) { ServiceAreaClusterHomeLocationStruct.fromTlv( ContextSpecificTag(TAG_LOCATION_INFO), - tlvReader + tlvReader, ) } else { tlvReader.getNull(ContextSpecificTag(TAG_LOCATION_INFO)) @@ -110,7 +110,7 @@ class ServiceAreaClusterLocationInfoStruct( locationInfo, landmarkTag, positionTag, - surfaceTag + surfaceTag, ) } } diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationStruct.kt index 0a5b5aa3a825b4..42dc672d5c51fe 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationStruct.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationStruct.kt @@ -25,7 +25,7 @@ import matter.tlv.TlvWriter class ServiceAreaClusterLocationStruct( val locationID: UInt, val mapID: UByte?, - val locationInfo: ServiceAreaClusterLocationInfoStruct + val locationInfo: ServiceAreaClusterLocationInfoStruct, ) { override fun toString(): String = buildString { append("ServiceAreaClusterLocationStruct {\n") @@ -67,7 +67,7 @@ class ServiceAreaClusterLocationStruct( val locationInfo = ServiceAreaClusterLocationInfoStruct.fromTlv( ContextSpecificTag(TAG_LOCATION_INFO), - tlvReader + tlvReader, ) tlvReader.exitContainer() diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterProgressStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterProgressStruct.kt index a5dac6e470d299..3dd3eb1e412260 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterProgressStruct.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterProgressStruct.kt @@ -27,7 +27,7 @@ class ServiceAreaClusterProgressStruct( val locationID: UInt, val status: UByte, val totalOperationalTime: Optional?, - val estimatedTime: Optional? + val estimatedTime: Optional?, ) { override fun toString(): String = buildString { append("ServiceAreaClusterProgressStruct {\n") @@ -102,7 +102,7 @@ class ServiceAreaClusterProgressStruct( locationID, status, totalOperationalTime, - estimatedTime + estimatedTime, ) } } From 43f70745304ab66869b6751ba15fb1d4dcd3eb4b Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Thu, 27 Jun 2024 02:00:10 +0530 Subject: [PATCH 12/21] ESP32: Fixes in BLEManager (#34082) - Fix the ble re-advertisement if invalid bytes are written on the characteristic. - cancel the ble advertisement timer on ble connection - remove the unnecessary if check --- .../ESP32/bluedroid/BLEManagerImpl.cpp | 1 + src/platform/ESP32/nimble/BLEManagerImpl.cpp | 30 ++++++++++--------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp b/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp index da44e5974b5869..07c02647055ca8 100644 --- a/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp +++ b/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp @@ -890,6 +890,7 @@ bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBle void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) { ChipLogProgress(Ble, "Got notification regarding chip connection closure"); + CloseConnection(conId); } CHIP_ERROR BLEManagerImpl::MapBLEError(int bleErr) diff --git a/src/platform/ESP32/nimble/BLEManagerImpl.cpp b/src/platform/ESP32/nimble/BLEManagerImpl.cpp index b43f866c0577f2..189ebd9dae6775 100644 --- a/src/platform/ESP32/nimble/BLEManagerImpl.cpp +++ b/src/platform/ESP32/nimble/BLEManagerImpl.cpp @@ -672,7 +672,11 @@ bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBle #endif } -void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) {} +void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) +{ + ChipLogDetail(Ble, "Received notification of closed CHIPoBLE connection (con %u)", conId); + CloseConnection(conId); +} CHIP_ERROR BLEManagerImpl::MapBLEError(int bleErr) { @@ -810,23 +814,21 @@ void BLEManagerImpl::DriveBLEState(void) ExitNow(); } } - // mFlags.Clear(Flags::kAdvertisingRefreshNeeded); // Transition to the not Advertising state... - if (mFlags.Has(Flags::kAdvertising)) - { - mFlags.Clear(Flags::kAdvertising); - mFlags.Set(Flags::kFastAdvertisingEnabled, true); + mFlags.Clear(Flags::kAdvertising); + mFlags.Set(Flags::kFastAdvertisingEnabled, true); - ChipLogProgress(DeviceLayer, "CHIPoBLE advertising stopped"); + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising stopped"); - // Post a CHIPoBLEAdvertisingChange(Stopped) event. - { - ChipDeviceEvent advChange; - advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; - advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; - err = PlatformMgr().PostEvent(&advChange); - } + CancelBleAdvTimeoutTimer(); + + // Post a CHIPoBLEAdvertisingChange(Stopped) event. + { + ChipDeviceEvent advChange; + advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; + advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; + err = PlatformMgr().PostEvent(&advChange); } ExitNow(); From 4f0b7e9ed75a19be9625450aaea19dc3d1c8ae3d Mon Sep 17 00:00:00 2001 From: William Date: Wed, 26 Jun 2024 21:32:46 +0100 Subject: [PATCH 13/21] Add service area cluster to rvc device type template (#34075) * Add definitions for common HomeLocationStruct and types - see connectedhomeip-spec PR 8933 * Add definition for Service Area Cluster - see connectedhomeip-spec PR 8937 * Add semantic tag definitions needed for Service Area Cluster - see connectedhomeip-spec PR 8937 * Update Service Area Cluster definition of LocationInfoStruct - see connectedhomeip-spec PR 8937 * Rename SurfaceTag to FloorSurfaceTag - spec PR 8937 commit 431739b3e3996d0ef74a36b2a6b93ac0d3db9c45 * Fix Carport typo, remove IsGroundFloor field (spec change) * Update home location definitions per spec PR 8933 commit f04958166412d5b7eff4d3443273f47f12f22baf 2024-05-23 * update generated files * Update Service Area Cluster definitions per spec PR 8937 up to commit 6bf3762eb1ee733c642e79074744d1185b82a89c 2024-05-24 * update generated files * Regenerated zap files after merge. * Moved the AreaTypeTag namespace definition to namespaces.xml. * Moved the HomeLoc global struct into global-sturcts.xml. * Updated the AreaTypeTag namespace to match the latest spec definition. * Updated the AreaTypeTag namespace to match the latest spec definition. * Updated the matterlint rules with the changes in the xml files. * Reverted changes to the rvc zap file. * Addded global xml files to relevant lists of xmls. * Added the Position, Landmark and Floor Surface Namespaces. * Removed namespace tag definitions from the service area cluters XML. * Regenerated zap files. * Explicitly set the conformance. * Fixed typos in the service-area clusters XML from review. * Used a more feature rich method for defining the cluster's features. * Reordered data-type definitions to match the order in the spec. * Regenerated zap files. * Added github issue to a comment. * Renamed namespaces.xml to semantic-tag-namespace-enums.xml. * Missed some rename locations. * Added the Service Area cluster as an optional cluster to the Robotic Vacuun Cleaner device type. * Regenerated zap files after sync with upstream. * Regenerated zap files after sync with upstream. --------- Co-authored-by: jfierke@irobot.com --- src/app/zap-templates/zcl/data-model/chip/matter-devices.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml index ce28156f3c34e9..ce12fb58abb9f5 100644 --- a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml +++ b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml @@ -2325,6 +2325,7 @@ limitations under the License. + From 2908685029bcbd38c7ef0bb6a39faae6cc14d34a Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Wed, 26 Jun 2024 17:25:32 -0400 Subject: [PATCH 14/21] =?UTF-8?q?[Silabs]=20Add=20support=20for=20factory?= =?UTF-8?q?=20and=20commissionable=20data=20provisioning=20with=20the=20us?= =?UTF-8?q?e=E2=80=A6=20(#34087)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add support factory and commissionable data provisioning with the use of librairies * Restyled by clang-format * remove files that are now used * fix for wifi ncp build * address comments * fixup include path --------- Co-authored-by: Restyled.io --- examples/platform/silabs/BaseApplication.cpp | 13 +- examples/platform/silabs/MatterConfig.cpp | 16 +- examples/platform/silabs/SiWx917/BUILD.gn | 54 +- .../silabs/SilabsDeviceAttestationCreds.cpp | 199 ----- .../silabs/SilabsDeviceDataProvider.cpp | 416 ---------- .../silabs/SilabsDeviceDataProvider.h | 72 -- .../silabs/SilabsTestEventTriggerDelegate.cpp | 4 +- examples/platform/silabs/efr32/BUILD.gn | 54 +- .../provision/ProvisionStorageCustom.cpp | 129 ++++ .../provision/ProvisionStorageDefault.cpp | 731 ++++++++++++++++++ .../provision/ProvisionStorageFlash.cpp | 724 +++++++++++++++++ examples/platform/silabs/silabs_creds.h | 58 +- src/platform/silabs/efr32/BLEManagerImpl.cpp | 15 +- src/platform/silabs/efr32/BUILD.gn | 7 +- .../silabs/platformAbstraction/GsdkSpam.cpp | 14 +- .../platformAbstraction/SilabsPlatform.h | 2 + .../platformAbstraction/SilabsPlatformBase.h | 1 + .../platformAbstraction/WiseMcuSpam.cpp | 6 + .../silabs/provision/AttestationKey.h | 51 ++ src/platform/silabs/provision/BUILD.gn | 38 + .../silabs/provision/ProvisionChannel.h | 34 +- .../silabs/provision/ProvisionEncoder.h | 191 +++++ .../silabs/provision/ProvisionManager.h | 61 ++ .../silabs/provision/ProvisionProtocol.h | 107 +++ .../silabs/provision/ProvisionStorage.h | 298 +++++++ .../provision/ProvisionStorageGeneric.h | 47 ++ src/test_driver/efr32/BUILD.gn | 15 +- src/test_driver/efr32/src/main.cpp | 19 +- third_party/silabs/SiWx917_sdk.gni | 11 +- third_party/silabs/matter_support | 2 +- 30 files changed, 2523 insertions(+), 866 deletions(-) delete mode 100644 examples/platform/silabs/SilabsDeviceAttestationCreds.cpp delete mode 100644 examples/platform/silabs/SilabsDeviceDataProvider.cpp delete mode 100644 examples/platform/silabs/SilabsDeviceDataProvider.h create mode 100644 examples/platform/silabs/provision/ProvisionStorageCustom.cpp create mode 100644 examples/platform/silabs/provision/ProvisionStorageDefault.cpp create mode 100644 examples/platform/silabs/provision/ProvisionStorageFlash.cpp create mode 100644 src/platform/silabs/provision/AttestationKey.h create mode 100644 src/platform/silabs/provision/BUILD.gn rename examples/platform/silabs/SilabsDeviceAttestationCreds.h => src/platform/silabs/provision/ProvisionChannel.h (55%) create mode 100644 src/platform/silabs/provision/ProvisionEncoder.h create mode 100644 src/platform/silabs/provision/ProvisionManager.h create mode 100644 src/platform/silabs/provision/ProvisionProtocol.h create mode 100644 src/platform/silabs/provision/ProvisionStorage.h create mode 100644 src/platform/silabs/provision/ProvisionStorageGeneric.h diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index f02826f1308c32..fd22a7ea3a48fc 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -24,9 +24,10 @@ #include "AppConfig.h" #include "AppEvent.h" #include "AppTask.h" - #include +#define APP_ACTION_BUTTON 1 + #ifdef DISPLAY_ENABLED #include "lcd.h" #ifdef QR_CODE_ENABLED @@ -34,10 +35,10 @@ #endif // QR_CODE_ENABLED #endif // DISPLAY_ENABLED -#include "SilabsDeviceDataProvider.h" #if CHIP_CONFIG_ENABLE_ICD_SERVER == 1 #include // nogncheck #endif +#include #include #include #include @@ -744,6 +745,11 @@ void BaseApplication::DispatchEvent(AppEvent * aEvent) void BaseApplication::ScheduleFactoryReset() { PlatformMgr().ScheduleWork([](intptr_t) { + // Press both buttons to request provisioning + if (GetPlatform().GetButtonState(APP_ACTION_BUTTON)) + { + Provision::Manager::GetInstance().SetProvisionRequired(true); + } PlatformMgr().HandleServerShuttingDown(); ConfigurationMgr().InitiateFactoryReset(); }); @@ -765,7 +771,8 @@ void BaseApplication::OutputQrCode(bool refreshLCD) char setupPayloadBuffer[chip::QRCodeBasicSetupPayloadGenerator::kMaxQRCodeBase38RepresentationLength + 1]; chip::MutableCharSpan setupPayload(setupPayloadBuffer); - if (Silabs::SilabsDeviceDataProvider::GetDeviceDataProvider().GetSetupPayload(setupPayload) == CHIP_NO_ERROR) + CHIP_ERROR err = Provision::Manager::GetInstance().GetStorage().GetSetupPayload(setupPayload); + if (CHIP_NO_ERROR == err) { // Print setup info on LCD if available #ifdef QR_CODE_ENABLED diff --git a/examples/platform/silabs/MatterConfig.cpp b/examples/platform/silabs/MatterConfig.cpp index 0789c12f37aaac..70f759c0e35903 100644 --- a/examples/platform/silabs/MatterConfig.cpp +++ b/examples/platform/silabs/MatterConfig.cpp @@ -56,7 +56,7 @@ static chip::DeviceLayer::Internal::Efr32PsaOperationalKeystore gOperationalKeystore; #endif -#include "SilabsDeviceDataProvider.h" +#include #include #include @@ -80,8 +80,6 @@ static chip::DeviceLayer::Internal::Efr32PsaOperationalKeystore gOperationalKeys #include #include -#include -#include #include @@ -92,7 +90,7 @@ static chip::DeviceLayer::Internal::Efr32PsaOperationalKeystore gOperationalKeys using namespace ::chip; using namespace ::chip::Inet; using namespace ::chip::DeviceLayer; -using namespace ::chip::Credentials::Silabs; +using namespace ::chip::Credentials; using namespace chip::DeviceLayer::Silabs; #if CHIP_ENABLE_OPENTHREAD @@ -174,7 +172,7 @@ void ApplicationStart(void * unused) chip::DeviceLayer::PlatformMgr().LockChipStack(); // Initialize device attestation config - SetDeviceAttestationCredentialsProvider(Credentials::Silabs::GetSilabsDacProvider()); + SetDeviceAttestationCredentialsProvider(&Provision::Manager::GetInstance().GetStorage()); chip::DeviceLayer::PlatformMgr().UnlockChipStack(); SILABS_LOG("Starting App Task"); @@ -190,7 +188,6 @@ void ApplicationStart(void * unused) void SilabsMatterConfig::AppInit() { GetPlatform().Init(); - sMainTaskHandle = osThreadNew(ApplicationStart, nullptr, &kMainTaskAttr); SILABS_LOG("Starting scheduler"); VerifyOrDie(sMainTaskHandle); // We can't proceed if the Main Task creation failed. @@ -257,8 +254,11 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) ReturnErrorOnFailure(PlatformMgr().InitChipStack()); - SetDeviceInstanceInfoProvider(&Silabs::SilabsDeviceDataProvider::GetDeviceDataProvider()); - SetCommissionableDataProvider(&Silabs::SilabsDeviceDataProvider::GetDeviceDataProvider()); + // Provision Manager + Silabs::Provision::Manager & provision = Silabs::Provision::Manager::GetInstance(); + ReturnErrorOnFailure(provision.Init()); + SetDeviceInstanceInfoProvider(&provision.GetStorage()); + SetCommissionableDataProvider(&provision.GetStorage()); chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName(appName); diff --git a/examples/platform/silabs/SiWx917/BUILD.gn b/examples/platform/silabs/SiWx917/BUILD.gn index 084339723a0037..6ada4753457fcb 100644 --- a/examples/platform/silabs/SiWx917/BUILD.gn +++ b/examples/platform/silabs/SiWx917/BUILD.gn @@ -86,10 +86,9 @@ source_set("test-event-trigger") { "${silabs_common_plat_dir}/SilabsTestEventTriggerDelegate.h", ] + deps = [ "${chip_root}/src/platform/silabs/provision:provision-headers" ] public_configs = [ ":test-event-trigger-config" ] - public_deps = [ - ":silabs-factory-data-provider", "${chip_root}/src/app:test-event-trigger", "${chip_root}/src/lib/core", "${chip_root}/src/lib/support", @@ -114,46 +113,9 @@ source_set("siwx917-matter-shell") { } } -config("attestation-credentials-config") { - include_dirs = [ "${chip_root}" ] -} - -source_set("siwx917-attestation-credentials") { - sources = [ - "${silabs_common_plat_dir}/SilabsDeviceAttestationCreds.cpp", - "${silabs_common_plat_dir}/SilabsDeviceAttestationCreds.h", - ] - - public_deps = [ - "${chip_root}/src/credentials", - "${chip_root}/src/platform:platform_base", - ] - - public_configs = [ ":attestation-credentials-config" ] -} - -source_set("silabs-factory-data-provider") { - sources = [ - "${silabs_common_plat_dir}/SilabsDeviceDataProvider.cpp", - "${silabs_common_plat_dir}/SilabsDeviceDataProvider.h", - ] - - public_deps = [ - "${chip_root}/src/credentials", - "${chip_root}/src/lib/support", - "${chip_root}/src/platform:platform_base", - "${chip_root}/src/setup_payload", - ] - - public_configs = [ ":siwx917-common-config" ] - - if (sl_enable_test_event_trigger) { - public_configs += [ ":test-event-trigger-config" ] - } -} - config("siwx917-common-config") { defines = [ "OTA_PERIODIC_TIMEOUT=${ota_periodic_query_timeout_sec}" ] + libs = [ "${sdk_support_root}/matter/provision/lib/libProvision_si917.a" ] if (!disable_lcd) { include_dirs = [ "${silabs_common_plat_dir}/display" ] @@ -210,7 +172,7 @@ config("silabs-wifi-config") { } source_set("siwx917-common") { - deps = [] + deps = [ "${chip_root}/src/platform/silabs/provision:provision-headers" ] defines = [] public_deps = [] public_configs = [ @@ -229,6 +191,8 @@ source_set("siwx917-common") { "${silabs_common_plat_dir}/LEDWidget.cpp", "${silabs_common_plat_dir}/MatterConfig.cpp", "${silabs_common_plat_dir}/SoftwareFaultReports.cpp", + "${silabs_common_plat_dir}/provision/ProvisionStorageCustom.cpp", + "${silabs_common_plat_dir}/provision/ProvisionStorageFlash.cpp", "${silabs_common_plat_dir}/silabs_utils.cpp", "${silabs_common_plat_dir}/syscalls_stubs.cpp", "${silabs_plat_si91x_wifi_dir}/dhcp_client.cpp", @@ -282,14 +246,6 @@ source_set("siwx917-common") { ] } - # Attestation Credentials - deps += [ ":siwx917-attestation-credentials" ] - - # Factory Data Provider - if (use_efr32_factory_data_provider) { - public_deps += [ ":silabs-factory-data-provider" ] - } - public_deps += [ "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/lib", diff --git a/examples/platform/silabs/SilabsDeviceAttestationCreds.cpp b/examples/platform/silabs/SilabsDeviceAttestationCreds.cpp deleted file mode 100644 index 60785413070382..00000000000000 --- a/examples/platform/silabs/SilabsDeviceAttestationCreds.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ -#include "SilabsDeviceAttestationCreds.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "silabs_creds.h" - -using namespace chip::DeviceLayer::Internal; - -using chip::DeviceLayer::Internal::SilabsConfig; - -namespace chip { -namespace Credentials { -namespace Silabs { - -namespace { - -class DeviceAttestationCredsSilabs : public DeviceAttestationCredentialsProvider -{ - // Miss-aligned certificates is a common error, and printing the first few bytes is - // useful to verify proper alignment. Eight bytes is enough for this purpose. - static constexpr size_t kDebugLength = 8; - -public: - CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & out_span) override - { - if (SilabsConfig::ConfigValueExists(SilabsConfig::kConfigKey_Creds_Base_Addr)) - { - // Provisioned CD - return GetFile("GetCertificationDeclaration", SilabsConfig::kConfigKey_Creds_CD_Offset, SILABS_CREDENTIALS_CD_OFFSET, - SilabsConfig::kConfigKey_Creds_CD_Size, SILABS_CREDENTIALS_CD_SIZE, out_span); - } - else - { - // Example CD - return Examples::GetExampleDACProvider()->GetCertificationDeclaration(out_span); - } - } - - CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override - { - // TODO: We need a real example FirmwareInformation to be populated. - out_firmware_info_buffer.reduce_size(0); - return CHIP_NO_ERROR; - } - - CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & out_span) override - { - if (SilabsConfig::ConfigValueExists(SilabsConfig::kConfigKey_Creds_Base_Addr)) - { - // Provisioned DAC - return GetFile("GetDeviceAttestationCert", SilabsConfig::kConfigKey_Creds_DAC_Offset, SILABS_CREDENTIALS_DAC_OFFSET, - SilabsConfig::kConfigKey_Creds_DAC_Size, SILABS_CREDENTIALS_DAC_SIZE, out_span); - } - else - { - // Example DAC - return Examples::GetExampleDACProvider()->GetDeviceAttestationCert(out_span); - } - } - - CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & out_span) override - { - if (SilabsConfig::ConfigValueExists(SilabsConfig::kConfigKey_Creds_Base_Addr)) - { - // Provisioned PAI - return GetFile("GetProductAttestationIntermediateCert", SilabsConfig::kConfigKey_Creds_PAI_Offset, - SILABS_CREDENTIALS_PAI_OFFSET, SilabsConfig::kConfigKey_Creds_PAI_Size, SILABS_CREDENTIALS_PAI_SIZE, - out_span); - } - else - { - // Example PAI - return Examples::GetExampleDACProvider()->GetProductAttestationIntermediateCert(out_span); - } - } - - CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_span) override - { - if (SilabsConfig::ConfigValueExists(SilabsConfig::kConfigKey_Creds_KeyId)) - { - // Provisioned DAC key -#ifdef SLI_SI91X_MCU_INTERFACE - return CHIP_ERROR_NOT_IMPLEMENTED; -#else - uint32_t key_id = SILABS_CREDENTIALS_DAC_KEY_ID; - uint8_t signature[64] = { 0 }; - size_t signature_size = sizeof(signature); - - ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Creds_KeyId, key_id)); - - ChipLogProgress(DeviceLayer, "SignWithDeviceAttestationKey, key:%lu", key_id); - - psa_status_t err = - psa_sign_message(static_cast(key_id), PSA_ALG_ECDSA(PSA_ALG_SHA_256), message_to_sign.data(), - message_to_sign.size(), signature, signature_size, &signature_size); - VerifyOrReturnError(!err, CHIP_ERROR_INTERNAL); - - return CopySpanToMutableSpan(ByteSpan(signature, signature_size), out_span); -#endif - } - else - { - // Example DAC key - return Examples::GetExampleDACProvider()->SignWithDeviceAttestationKey(message_to_sign, out_span); - } - } - -private: - CHIP_ERROR GetFile(const char * description, uint32_t offset_key, uint32_t offset_default, uint32_t size_key, - uint32_t size_default, MutableByteSpan & out_span) - { - uint32_t base_addr = 0; - uint8_t * address = nullptr; - uint32_t offset = offset_default; - uint32_t size = size_default; - - ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Creds_Base_Addr, base_addr)); - - // Offset - if (SilabsConfig::ConfigValueExists(offset_key)) - { - ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(offset_key, offset)); - } - address = (uint8_t *) (base_addr + offset); - - // Size - if (SilabsConfig::ConfigValueExists(size_key)) - { - ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(size_key, size)); - } - - ByteSpan span(address, size); - ChipLogProgress(DeviceLayer, "%s, addr:%p, size:%lu", description, address, size); - ChipLogByteSpan(DeviceLayer, ByteSpan(span.data(), kDebugLength > span.size() ? span.size() : kDebugLength)); - return CopySpanToMutableSpan(span, out_span); - } -}; - -} // namespace - -DeviceAttestationCredentialsProvider * GetSilabsDacProvider() -{ - static DeviceAttestationCredsSilabs dac_provider; - return &dac_provider; -} - -} // namespace Silabs -} // namespace Credentials - -namespace DeviceLayer { -namespace Silabs { - -void MigrateDacProvider(void) -{ - constexpr uint32_t kOldKey_Creds_KeyId = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x21); - constexpr uint32_t kOldKey_Creds_Base_Addr = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x22); - constexpr uint32_t kOldKey_Creds_DAC_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x23); - constexpr uint32_t kOldKey_Creds_DAC_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x24); - constexpr uint32_t kOldKey_Creds_PAI_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x25); - constexpr uint32_t kOldKey_Creds_PAI_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x26); - constexpr uint32_t kOldKey_Creds_CD_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x27); - constexpr uint32_t kOldKey_Creds_CD_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x28); - - MigrationManager::MigrateUint32(kOldKey_Creds_KeyId, SilabsConfig::kConfigKey_Creds_KeyId); - MigrationManager::MigrateUint32(kOldKey_Creds_Base_Addr, SilabsConfig::kConfigKey_Creds_Base_Addr); - MigrationManager::MigrateUint32(kOldKey_Creds_DAC_Offset, SilabsConfig::kConfigKey_Creds_DAC_Offset); - MigrationManager::MigrateUint32(kOldKey_Creds_DAC_Size, SilabsConfig::kConfigKey_Creds_DAC_Size); - MigrationManager::MigrateUint32(kOldKey_Creds_PAI_Offset, SilabsConfig::kConfigKey_Creds_PAI_Offset); - MigrationManager::MigrateUint32(kOldKey_Creds_PAI_Size, SilabsConfig::kConfigKey_Creds_PAI_Size); - MigrationManager::MigrateUint32(kOldKey_Creds_CD_Offset, SilabsConfig::kConfigKey_Creds_CD_Offset); - MigrationManager::MigrateUint32(kOldKey_Creds_CD_Size, SilabsConfig::kConfigKey_Creds_CD_Size); -} - -} // namespace Silabs -} // namespace DeviceLayer -} // namespace chip diff --git a/examples/platform/silabs/SilabsDeviceDataProvider.cpp b/examples/platform/silabs/SilabsDeviceDataProvider.cpp deleted file mode 100644 index 7d80eaaafda2bd..00000000000000 --- a/examples/platform/silabs/SilabsDeviceDataProvider.cpp +++ /dev/null @@ -1,416 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -#include "SilabsDeviceDataProvider.h" -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace chip { -namespace DeviceLayer { -namespace Silabs { - -// using namespace chip::Credentials; -using namespace chip::DeviceLayer::Internal; - -CHIP_ERROR SilabsDeviceDataProvider::GetSetupDiscriminator(uint16_t & setupDiscriminator) -{ - CHIP_ERROR err; - uint32_t setupDiscriminator32; - - err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_SetupDiscriminator, setupDiscriminator32); -#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR) && CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - setupDiscriminator32 = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR; - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR) && CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR - - VerifyOrReturnLogError(setupDiscriminator32 <= kMaxDiscriminatorValue, CHIP_ERROR_INVALID_ARGUMENT); - setupDiscriminator = static_cast(setupDiscriminator32); - return CHIP_NO_ERROR; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) -{ - CHIP_ERROR err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Spake2pIterationCount, iterationCount); - -#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT) && CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - iterationCount = CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT; - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT) && CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) -{ - static constexpr size_t kSpake2pSalt_MaxBase64Len = BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_Max_PBKDF_Salt_Length) + 1; - - CHIP_ERROR err = CHIP_NO_ERROR; - char saltB64[kSpake2pSalt_MaxBase64Len] = { 0 }; - size_t saltB64Len = 0; - - err = SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_Spake2pSalt, saltB64, sizeof(saltB64), saltB64Len); - -#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT) - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - saltB64Len = strlen(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT); - ReturnErrorCodeIf(saltB64Len > sizeof(saltB64), CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(saltB64, CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT, saltB64Len); - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT) - - ReturnErrorOnFailure(err); - - uint8_t saltByteArray[kSpake2pSalt_MaxBase64Len] = { 0 }; - size_t saltLen = chip::Base64Decode32(saltB64, saltB64Len, saltByteArray); - ReturnErrorCodeIf(saltLen > saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); - - memcpy(saltBuf.data(), saltByteArray, saltLen); - saltBuf.reduce_size(saltLen); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) -{ - static constexpr size_t kSpake2pSerializedVerifier_MaxBase64Len = - BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_VerifierSerialized_Length) + 1; - - CHIP_ERROR err = CHIP_NO_ERROR; - char verifierB64[kSpake2pSerializedVerifier_MaxBase64Len] = { 0 }; - size_t verifierB64Len = 0; - - err = SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_Spake2pVerifier, verifierB64, sizeof(verifierB64), - verifierB64Len); - -#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER) - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - verifierB64Len = strlen(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER); - ReturnErrorCodeIf(verifierB64Len > sizeof(verifierB64), CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(verifierB64, CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER, verifierB64Len); - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER) - - ReturnErrorOnFailure(err); - - verifierLen = chip::Base64Decode32(verifierB64, verifierB64Len, reinterpret_cast(verifierB64)); - ReturnErrorCodeIf(verifierLen > verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); - - memcpy(verifierBuf.data(), verifierB64, verifierLen); - verifierBuf.reduce_size(verifierLen); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetSetupPayload(MutableCharSpan & payloadBuf) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - uint8_t payloadBitSet[kTotalPayloadDataSizeInBytes] = { 0 }; - size_t bitSetLen = 0; - - err = SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_SetupPayloadBitSet, payloadBitSet, kTotalPayloadDataSizeInBytes, - bitSetLen); - -#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE) && CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - static constexpr uint8_t kTestSetupPayloadBitset[] = { 0x88, 0xFF, 0x2F, 0x00, 0x44, 0x00, 0xE0, 0x4B, 0x84, 0x68, 0x02 }; - bitSetLen = sizeof(kTestSetupPayloadBitset); - ReturnErrorCodeIf(bitSetLen > kTotalPayloadDataSizeInBytes, CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(payloadBitSet, kTestSetupPayloadBitset, bitSetLen); - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER) - - ReturnErrorOnFailure(err); - - size_t prefixLen = strlen(kQRCodePrefix); - - if (payloadBuf.size() < prefixLen + 1) - { - err = CHIP_ERROR_BUFFER_TOO_SMALL; - } - else - { - MutableCharSpan subSpan = payloadBuf.SubSpan(prefixLen, payloadBuf.size() - prefixLen); - memcpy(payloadBuf.data(), kQRCodePrefix, prefixLen); - err = base38Encode(MutableByteSpan(payloadBitSet), subSpan); - // Reduce output span size to be the size of written data - payloadBuf.reduce_size(subSpan.size() + prefixLen); - } - - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetVendorName(char * buf, size_t bufSize) -{ - size_t vendorNameLen = 0; // without counting null-terminator - CHIP_ERROR err = SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_VendorName, buf, bufSize, vendorNameLen); -#if defined(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME) - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - VerifyOrReturnError(buf != nullptr, CHIP_ERROR_NO_MEMORY); - VerifyOrReturnError(bufSize > strlen(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); - Platform::CopyString(buf, bufSize, CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME); - err = CHIP_NO_ERROR; - } -#endif - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetVendorId(uint16_t & vendorId) -{ - ChipError err = CHIP_NO_ERROR; - uint32_t vendorId32 = 0; - - err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_VendorId, vendorId32); - -#if defined(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID) && CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - vendorId32 = CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID; - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID) && CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID - - ReturnErrorOnFailure(err); - vendorId = static_cast(vendorId32); - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetProductName(char * buf, size_t bufSize) -{ - size_t productNameLen = 0; // without counting null-terminator - CHIP_ERROR err = SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_ProductName, buf, bufSize, productNameLen); -#if defined(CHIP_DEVICE_CONFIG_TEST_PRODUCT_NAME) - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - VerifyOrReturnError(buf != nullptr, CHIP_ERROR_NO_MEMORY); - VerifyOrReturnError(bufSize > strlen(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); - Platform::CopyString(buf, bufSize, CHIP_DEVICE_CONFIG_TEST_PRODUCT_NAME); - err = CHIP_NO_ERROR; - } -#endif - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetProductId(uint16_t & productId) -{ - ChipError err = CHIP_NO_ERROR; - uint32_t productId32 = 0; - - err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_ProductId, productId32); - -#if defined(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID) && CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - productId32 = CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID; - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID) && CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID - ReturnErrorOnFailure(err); - - productId = static_cast(productId32); - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetHardwareVersionString(char * buf, size_t bufSize) -{ - size_t hardwareVersionStringLen = 0; // without counting null-terminator - CHIP_ERROR err = - SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_HardwareVersionString, buf, bufSize, hardwareVersionStringLen); -#if defined(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING) - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - VerifyOrReturnError(buf != nullptr, CHIP_ERROR_NO_MEMORY); - VerifyOrReturnError(bufSize > strlen(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), - CHIP_ERROR_BUFFER_TOO_SMALL); - Platform::CopyString(buf, bufSize, CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING); - err = CHIP_NO_ERROR; - } -#endif // CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetHardwareVersion(uint16_t & hardwareVersion) -{ - CHIP_ERROR err; - uint32_t hardwareVersion32; - - err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_HardwareVersion, hardwareVersion32); -#if defined(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION) - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - hardwareVersion32 = CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION; - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION) - - hardwareVersion = static_cast(hardwareVersion32); - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) -{ - ChipError err = CHIP_ERROR_WRONG_KEY_TYPE; -#if CHIP_ENABLE_ROTATING_DEVICE_ID - static_assert(ConfigurationManager::kRotatingDeviceIDUniqueIDLength >= ConfigurationManager::kMinRotatingDeviceIDUniqueIDLength, - "Length of unique ID for rotating device ID is smaller than minimum."); - - size_t uniqueIdLen = 0; - err = - SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_UniqueId, uniqueIdSpan.data(), uniqueIdSpan.size(), uniqueIdLen); -#ifdef CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - constexpr uint8_t uniqueId[] = CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID; - - ReturnErrorCodeIf(sizeof(uniqueId) > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(uniqueIdSpan.data(), uniqueId, sizeof(uniqueId)); - uniqueIdLen = sizeof(uniqueId); - } -#endif // CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID - - ReturnErrorOnFailure(err); - uniqueIdSpan.reduce_size(uniqueIdLen); - -#endif // CHIP_ENABLE_ROTATING_DEVICE_ID - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetSerialNumber(char * buf, size_t bufSize) -{ - size_t serialNumberLen = 0; // without counting null-terminator - return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_SerialNum, buf, bufSize, serialNumberLen); -} - -CHIP_ERROR SilabsDeviceDataProvider::GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) -{ - CHIP_ERROR err; - constexpr uint8_t kDateStringLength = 10; // YYYY-MM-DD - char dateStr[kDateStringLength + 1]; - size_t dateLen; - char * parseEnd; - - err = SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_ManufacturingDate, reinterpret_cast(dateStr), - sizeof(dateStr), dateLen); - SuccessOrExit(err); - - VerifyOrExit(dateLen == kDateStringLength, err = CHIP_ERROR_INVALID_ARGUMENT); - - // Cast does not lose information, because we then check that we only parsed - // 4 digits, so our number can't be bigger than 9999. - year = static_cast(strtoul(dateStr, &parseEnd, 10)); - VerifyOrExit(parseEnd == dateStr + 4, err = CHIP_ERROR_INVALID_ARGUMENT); - - // Cast does not lose information, because we then check that we only parsed - // 2 digits, so our number can't be bigger than 99. - month = static_cast(strtoul(dateStr + 5, &parseEnd, 10)); - VerifyOrExit(parseEnd == dateStr + 7, err = CHIP_ERROR_INVALID_ARGUMENT); - - // Cast does not lose information, because we then check that we only parsed - // 2 digits, so our number can't be bigger than 99. - day = static_cast(strtoul(dateStr + 8, &parseEnd, 10)); - VerifyOrExit(parseEnd == dateStr + 10, err = CHIP_ERROR_INVALID_ARGUMENT); - -exit: - if (err != CHIP_NO_ERROR && err != CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - ChipLogError(DeviceLayer, "Invalid manufacturing date: %s", dateStr); - } - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetPartNumber(char * buf, size_t bufSize) -{ - size_t partNumberLen = 0; // without counting null-terminator - return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_PartNumber, buf, bufSize, partNumberLen); -} - -CHIP_ERROR SilabsDeviceDataProvider::GetProductURL(char * buf, size_t bufSize) -{ - size_t productUrlLen = 0; // without counting null-terminator - return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_ProductURL, buf, bufSize, productUrlLen); -} - -CHIP_ERROR SilabsDeviceDataProvider::GetProductLabel(char * buf, size_t bufSize) -{ - size_t productLabelLen = 0; // without counting null-terminator - return SilabsConfig::ReadConfigValueStr(SilabsConfig::KConfigKey_ProductLabel, buf, bufSize, productLabelLen); -} - -#ifdef SL_MATTER_TEST_EVENT_TRIGGER_ENABLED -/** - * @brief Reads the test event trigger key from NVM. If the key isn't present, returns default value if defined. - * - * @param[out] keySpan output buffer. Must be at least large enough for 16 bytes (ken length) - * @return CHIP_ERROR - */ -CHIP_ERROR SilabsDeviceDataProvider::GetTestEventTriggerKey(MutableByteSpan & keySpan) -{ - constexpr size_t kEnableKeyLength = 16; // Expected byte size of the EnableKey - CHIP_ERROR err = CHIP_NO_ERROR; - size_t keyLength = 0; - - VerifyOrReturnError(keySpan.size() >= kEnableKeyLength, CHIP_ERROR_BUFFER_TOO_SMALL); - - err = SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_Test_Event_Trigger_Key, keySpan.data(), kEnableKeyLength, - keyLength); -#ifndef NDEBUG - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - - constexpr char enableKey[] = SL_MATTER_TEST_EVENT_TRIGGER_ENABLE_KEY; - if (Encoding::HexToBytes(enableKey, strlen(enableKey), keySpan.data(), kEnableKeyLength) != kEnableKeyLength) - { - // enableKey Hex String doesn't have the correct length - memset(keySpan.data(), 0, keySpan.size()); - return CHIP_ERROR_INTERNAL; - } - err = CHIP_NO_ERROR; - } -#endif // NDEBUG - - keySpan.reduce_size(kEnableKeyLength); - return err; -} -#endif // SL_MATTER_TEST_EVENT_TRIGGER_ENABLED - -SilabsDeviceDataProvider & SilabsDeviceDataProvider::GetDeviceDataProvider() -{ - static SilabsDeviceDataProvider sDataProvider; - return sDataProvider; -} - -} // namespace Silabs -} // namespace DeviceLayer -} // namespace chip diff --git a/examples/platform/silabs/SilabsDeviceDataProvider.h b/examples/platform/silabs/SilabsDeviceDataProvider.h deleted file mode 100644 index 76caac04bd60b8..00000000000000 --- a/examples/platform/silabs/SilabsDeviceDataProvider.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ -#pragma once - -#include -#include - -namespace chip { -namespace DeviceLayer { -namespace Silabs { - -/** - * @brief This class provides Commissionable data, Device Attestation Credentials, - * and Device Instance Info. - */ - -class SilabsDeviceDataProvider : public CommissionableDataProvider, - public Internal::GenericDeviceInstanceInfoProvider -{ -public: - SilabsDeviceDataProvider() : - CommissionableDataProvider(), - Internal::GenericDeviceInstanceInfoProvider(ConfigurationManagerImpl::GetDefaultInstance()) - {} - - static SilabsDeviceDataProvider & GetDeviceDataProvider(); - CHIP_ERROR GetSetupPayload(MutableCharSpan & payloadBuf); - // ===== Members functions that implement the CommissionableDataProvider - CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) override; - CHIP_ERROR SetSetupDiscriminator(uint16_t setupDiscriminator) override { return CHIP_ERROR_NOT_IMPLEMENTED; } - CHIP_ERROR GetSpake2pIterationCount(uint32_t & iterationCount) override; - CHIP_ERROR GetSpake2pSalt(MutableByteSpan & saltBuf) override; - CHIP_ERROR GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) override; - // Per spec 5.1.7. Passcode cannot be stored on the device - CHIP_ERROR GetSetupPasscode(uint32_t & setupPasscode) override { return CHIP_ERROR_NOT_IMPLEMENTED; }; - CHIP_ERROR SetSetupPasscode(uint32_t setupPasscode) override { return CHIP_ERROR_NOT_IMPLEMENTED; } - - // ===== Members functions that implement the GenericDeviceInstanceInfoProvider - CHIP_ERROR GetVendorName(char * buf, size_t bufSize) override; - CHIP_ERROR GetVendorId(uint16_t & vendorId) override; - CHIP_ERROR GetProductName(char * buf, size_t bufSize) override; - CHIP_ERROR GetProductId(uint16_t & productId) override; - CHIP_ERROR GetHardwareVersionString(char * buf, size_t bufSize) override; - CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override; - CHIP_ERROR GetSerialNumber(char * buf, size_t bufSize) override; - CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) override; - CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override; - CHIP_ERROR GetPartNumber(char * buf, size_t bufSize) override; - CHIP_ERROR GetProductURL(char * buf, size_t bufSzie) override; - CHIP_ERROR GetProductLabel(char * buf, size_t bufSize) override; - - // ===== Member functions that are Silabs Specific - CHIP_ERROR GetTestEventTriggerKey(MutableByteSpan & keySpan); -}; - -} // namespace Silabs -} // namespace DeviceLayer -} // namespace chip diff --git a/examples/platform/silabs/SilabsTestEventTriggerDelegate.cpp b/examples/platform/silabs/SilabsTestEventTriggerDelegate.cpp index ef42c0d3a9dfd2..cacb60555b6085 100644 --- a/examples/platform/silabs/SilabsTestEventTriggerDelegate.cpp +++ b/examples/platform/silabs/SilabsTestEventTriggerDelegate.cpp @@ -17,7 +17,7 @@ */ #include "SilabsTestEventTriggerDelegate.h" -#include "SilabsDeviceDataProvider.h" +#include using namespace ::chip::DeviceLayer; @@ -30,7 +30,7 @@ bool SilabsTestEventTriggerDelegate::DoesEnableKeyMatch(const ByteSpan & enableK // Return false if we were not able to get the enableKey VerifyOrReturnValue( - Silabs::SilabsDeviceDataProvider::GetDeviceDataProvider().GetTestEventTriggerKey(enableKeySpan) == CHIP_NO_ERROR, false); + Silabs::Provision::Manager::GetInstance().GetStorage().GetTestEventTriggerKey(enableKeySpan) == CHIP_NO_ERROR, false); return (!enableKeySpan.empty() && enableKeySpan.data_equal(enableKey)); } diff --git a/examples/platform/silabs/efr32/BUILD.gn b/examples/platform/silabs/efr32/BUILD.gn index 20180ecb57656a..6cf43897f43b10 100644 --- a/examples/platform/silabs/efr32/BUILD.gn +++ b/examples/platform/silabs/efr32/BUILD.gn @@ -103,10 +103,9 @@ source_set("test-event-trigger") { "${silabs_common_plat_dir}/SilabsTestEventTriggerDelegate.h", ] + deps = [ "${chip_root}/src/platform/silabs/provision:provision-headers" ] public_configs = [ ":test-event-trigger-config" ] - public_deps = [ - ":silabs-factory-data-provider", "${chip_root}/src/app:test-event-trigger", "${chip_root}/src/lib/core", "${chip_root}/src/lib/support", @@ -147,44 +146,11 @@ source_set("efr-matter-shell") { } } -config("attestation-credentials-config") { - include_dirs = [ "${chip_root}" ] -} - -source_set("efr32-attestation-credentials") { - sources = [ - "${silabs_common_plat_dir}/SilabsDeviceAttestationCreds.cpp", - "${silabs_common_plat_dir}/SilabsDeviceAttestationCreds.h", - ] - - public_deps = [ - "${chip_root}/src/credentials", - "${chip_root}/src/platform:platform_base", - ] - - public_configs = [ ":attestation-credentials-config" ] -} - -source_set("silabs-factory-data-provider") { - sources = [ - "${silabs_common_plat_dir}/SilabsDeviceDataProvider.cpp", - "${silabs_common_plat_dir}/SilabsDeviceDataProvider.h", - ] - - public_deps = [ - "${chip_root}/src/credentials", - "${chip_root}/src/lib/support", - "${chip_root}/src/platform:platform_base", - "${chip_root}/src/setup_payload", - ] - - if (sl_enable_test_event_trigger) { - public_configs = [ ":test-event-trigger-config" ] - } -} - config("efr32-common-config") { defines = [ "OTA_PERIODIC_TIMEOUT=${ota_periodic_query_timeout_sec}" ] + libs = [ + "${sdk_support_root}/matter/provision/lib/libProvision_${silabs_family}.a", + ] if (!disable_lcd) { include_dirs = [ "${silabs_common_plat_dir}/display" ] @@ -246,7 +212,7 @@ config("silabs-wifi-config") { } source_set("efr32-common") { - deps = [] + deps = [ "${chip_root}/src/platform/silabs/provision:provision-headers" ] defines = [] public_deps = [] public_configs = [ @@ -275,6 +241,8 @@ source_set("efr32-common") { "${silabs_common_plat_dir}/LEDWidget.cpp", "${silabs_common_plat_dir}/MatterConfig.cpp", "${silabs_common_plat_dir}/SoftwareFaultReports.cpp", + "${silabs_common_plat_dir}/provision/ProvisionStorageCustom.cpp", + "${silabs_common_plat_dir}/provision/ProvisionStorageDefault.cpp", "${silabs_common_plat_dir}/silabs_utils.cpp", "${silabs_common_plat_dir}/syscalls_stubs.cpp", ] @@ -339,14 +307,6 @@ source_set("efr32-common") { deps += [ ":efr-matter-shell" ] } - # Attestation Credentials - public_deps += [ ":efr32-attestation-credentials" ] - - # Factory Data Provider - if (use_efr32_factory_data_provider) { - public_deps += [ ":silabs-factory-data-provider" ] - } - public_deps += [ "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/app/server", diff --git a/examples/platform/silabs/provision/ProvisionStorageCustom.cpp b/examples/platform/silabs/provision/ProvisionStorageCustom.cpp new file mode 100644 index 00000000000000..7efc99027983ac --- /dev/null +++ b/examples/platform/silabs/provision/ProvisionStorageCustom.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2024 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 "ProvisionStorage.h" +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { + +namespace { +constexpr uint8_t kExample1 = 0x0001; +constexpr uint8_t kExample2 = 0x0002; +uint8_t sExample1 = 0; +uint8_t sExample2[32] = { 0 }; +} // namespace + +CHIP_ERROR CustomStorage::Set(uint16_t id, const uint8_t * value) +{ + switch (id) + { + case kExample1: + sExample1 = (nullptr == value) ? 0 : *value; + break; + + default: + return CHIP_ERROR_UNKNOWN_RESOURCE_ID; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR CustomStorage::Get(uint16_t id, uint8_t & value) +{ + switch (id) + { + case kExample1: + value = sExample1; + break; + + default: + return CHIP_ERROR_UNKNOWN_RESOURCE_ID; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR CustomStorage::Set(uint16_t id, const uint16_t * value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR CustomStorage::Get(uint16_t id, uint16_t & value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR CustomStorage::Set(uint16_t id, const uint32_t * value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR CustomStorage::Get(uint16_t id, uint32_t & value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR CustomStorage::Set(uint16_t id, const uint64_t * value) +{ + return CHIP_ERROR_UNKNOWN_RESOURCE_ID; +} + +CHIP_ERROR CustomStorage::Get(uint16_t id, uint64_t & value) +{ + return CHIP_ERROR_UNKNOWN_RESOURCE_ID; +} + +CHIP_ERROR CustomStorage::Set(uint16_t id, const uint8_t * value, size_t size) +{ + switch (id) + { + case kExample2: + memset(sExample2, 0x00, sizeof(sExample2)); + if (nullptr != value) + { + memcpy(sExample2, value, std::min(size, sizeof(sExample2))); + } + break; + + default: + return CHIP_ERROR_UNKNOWN_RESOURCE_ID; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR CustomStorage::Get(uint16_t id, uint8_t * value, size_t max_size, size_t & size) +{ + VerifyOrReturnError((nullptr != value) && (max_size > 0), CHIP_ERROR_INVALID_ARGUMENT); + switch (id) + { + case kExample2: + size = std::min(max_size, sizeof(sExample2)); + memcpy(value, sExample2, size); + break; + + default: + return CHIP_ERROR_UNKNOWN_RESOURCE_ID; + } + return CHIP_NO_ERROR; +} + +} // namespace Provision +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/examples/platform/silabs/provision/ProvisionStorageDefault.cpp b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp new file mode 100644 index 00000000000000..661189ef9060ac --- /dev/null +++ b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp @@ -0,0 +1,731 @@ +/* + * Copyright (c) 2024 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 "AttestationKey.h" +#include "ProvisionStorage.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef SLI_SI91X_MCU_INTERFACE +#include +#endif + +#ifdef SL_PROVISION_GENERATOR +extern void setNvm3End(uint32_t addr); +#endif + +extern uint8_t linker_nvm_end[]; + +using namespace chip::Credentials; +using namespace chip::DeviceLayer::Internal; + +using SilabsConfig = chip::DeviceLayer::Internal::SilabsConfig; + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { + +namespace { +// Miss-aligned certificates is a common error, and printing the first few bytes is +// useful to verify proper alignment. Eight bytes is enough for this purpose. +constexpr size_t kDebugLength = 8; +size_t sCredentialsOffset = 0; + +CHIP_ERROR ErasePage(uint32_t addr) +{ +#ifdef SLI_SI91X_MCU_INTERFACE + rsi_flash_erase_sector((uint32_t *) addr); +#else + MSC_ErasePage((uint32_t *) addr); +#endif + return CHIP_NO_ERROR; +} + +CHIP_ERROR WritePage(uint32_t addr, const uint8_t * data, size_t size) +{ +#ifdef SLI_SI91X_MCU_INTERFACE + rsi_flash_write((uint32_t *) addr, (unsigned char *) data, size); +#else + MSC_WriteWord((uint32_t *) addr, data, size); +#endif + return CHIP_NO_ERROR; +} + +size_t RoundNearest(size_t n, size_t multiple) +{ + return (n % multiple) > 0 ? n + (multiple - n % multiple) : n; +} + +CHIP_ERROR WriteFile(Storage & store, SilabsConfig::Key offset_key, SilabsConfig::Key size_key, const ByteSpan & value) +{ + uint32_t base_addr = 0; + ReturnErrorOnFailure(store.GetBaseAddress(base_addr)); + if (0 == sCredentialsOffset) + { + ReturnErrorOnFailure(ErasePage(base_addr)); + } + + memcpy(Storage::aux_buffer, value.data(), value.size()); + if (value.size() < Storage::kArgumentSizeMax) + { + memset(Storage::aux_buffer + value.size(), 0xff, Storage::kArgumentSizeMax - value.size()); + } + + ChipLogProgress(DeviceLayer, "WriteFile, addr:0x%06x+%03u, size:%u", (unsigned) base_addr, (unsigned) sCredentialsOffset, + (unsigned) value.size()); + // ChipLogByteSpan(DeviceLayer, ByteSpan(value.data(), value.size() < kDebugLength ? value.size() : kDebugLength)); + + ReturnErrorOnFailure(WritePage(base_addr + sCredentialsOffset, Storage::aux_buffer, Storage::kArgumentSizeMax)); + + // Store file offset + ReturnErrorOnFailure(SilabsConfig::WriteConfigValue(offset_key, (uint32_t) sCredentialsOffset)); + // Store file size + ReturnErrorOnFailure(SilabsConfig::WriteConfigValue(size_key, (uint32_t) value.size())); + // Calculate offset for the next file + sCredentialsOffset = RoundNearest(sCredentialsOffset + value.size(), 64); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ReadFileByOffset(Storage & store, const char * description, uint32_t offset, uint32_t size, MutableByteSpan & value) +{ + uint32_t base_addr = 0; + ReturnErrorOnFailure(store.GetBaseAddress(base_addr)); + + uint8_t * address = (uint8_t *) (base_addr + offset); + ByteSpan span(address, size); + ChipLogProgress(DeviceLayer, "%s, addr:0x%06x+%03u, size:%u", description, (unsigned) base_addr, (unsigned) offset, + (unsigned) size); + // ChipLogByteSpan(DeviceLayer, ByteSpan(span.data(), span.size() < kDebugLength ? span.size() : kDebugLength)); + return CopySpanToMutableSpan(span, value); +} + +CHIP_ERROR ReadFileByKey(Storage & store, const char * description, uint32_t offset_key, uint32_t size_key, MutableByteSpan & value) +{ + uint32_t offset = 0; + uint32_t size = 0; + + // Offset + VerifyOrReturnError(SilabsConfig::ConfigValueExists(offset_key), CHIP_ERROR_NOT_FOUND); + ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(offset_key, offset)); + + // Size + VerifyOrReturnError(SilabsConfig::ConfigValueExists(size_key), CHIP_ERROR_NOT_FOUND); + ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(size_key, size)); + + return ReadFileByOffset(store, description, offset, size, value); +} + +} // namespace + +// +// Initialization +// + +CHIP_ERROR Storage::Initialize(uint32_t flash_addr, uint32_t flash_size) +{ + sCredentialsOffset = 0; + + uint32_t base_addr = (uint32_t) linker_nvm_end; + if (flash_size > 0) + { +#ifndef SLI_SI91X_MCU_INTERFACE + base_addr = (flash_addr + flash_size - FLASH_PAGE_SIZE); + MSC_Init(); +#endif // SLI_SI91X_MCU_INTERFACE +#ifdef SL_PROVISION_GENERATOR + setNvm3End(base_addr); +#endif + } + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_Creds_Base_Addr, base_addr); +} + +CHIP_ERROR Storage::GetBaseAddress(uint32_t & value) +{ + return SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Creds_Base_Addr, value); +} + +CHIP_ERROR Storage::Commit() +{ + return CHIP_NO_ERROR; +} + +// +// DeviceInstanceInfoProvider +// + +CHIP_ERROR Storage::SetSerialNumber(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_SerialNum, value, len); +} + +CHIP_ERROR Storage::GetSerialNumber(char * value, size_t max) +{ + size_t size = 0; + return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_SerialNum, value, max, size); +} + +CHIP_ERROR Storage::SetVendorId(uint16_t value) +{ + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_VendorId, value); +} + +CHIP_ERROR Storage::GetVendorId(uint16_t & value) +{ + CHIP_ERROR err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_VendorId, value); +#if defined(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID) && CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID; + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetVendorName(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_VendorName, value, len); +} + +CHIP_ERROR Storage::GetVendorName(char * value, size_t max) +{ + size_t name_len = 0; // Without counting null-terminator + + CHIP_ERROR err = SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_VendorName, value, max, name_len); +#if defined(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + VerifyOrReturnError(value != nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(max > strlen(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + Platform::CopyString(value, max, CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME); + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetProductId(uint16_t value) +{ + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_ProductId, value); +} + +CHIP_ERROR Storage::GetProductId(uint16_t & value) +{ + CHIP_ERROR err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_ProductId, value); + +#if defined(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID) && CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID; + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetProductName(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_ProductName, value, len); +} + +CHIP_ERROR Storage::GetProductName(char * value, size_t max) +{ + size_t name_len = 0; // Without counting null-terminator + + CHIP_ERROR err = SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_ProductName, value, max, name_len); +#if defined(CHIP_DEVICE_CONFIG_TEST_PRODUCT_NAME) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + VerifyOrReturnError(value != nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(max > strlen(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + Platform::CopyString(value, max, CHIP_DEVICE_CONFIG_TEST_PRODUCT_NAME); + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetProductLabel(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::KConfigKey_ProductLabel, value, len); +} + +CHIP_ERROR Storage::GetProductLabel(char * value, size_t max) +{ + size_t size = 0; + return SilabsConfig::ReadConfigValueStr(SilabsConfig::KConfigKey_ProductLabel, value, max, size); +} + +CHIP_ERROR Storage::SetProductURL(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_ProductURL, value, len); +} +CHIP_ERROR Storage::GetProductURL(char * value, size_t max) +{ + size_t size = 0; + return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_ProductURL, value, max, size); +} + +CHIP_ERROR Storage::SetPartNumber(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_PartNumber, value, len); +} + +CHIP_ERROR Storage::GetPartNumber(char * value, size_t max) +{ + size_t size = 0; + return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_PartNumber, value, max, size); +} + +CHIP_ERROR Storage::SetHardwareVersion(uint16_t value) +{ + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_HardwareVersion, value); +} + +CHIP_ERROR Storage::GetHardwareVersion(uint16_t & value) +{ + CHIP_ERROR err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_HardwareVersion, value); +#if defined(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION; + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetHardwareVersionString(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_HardwareVersionString, value, len); +} + +CHIP_ERROR Storage::GetHardwareVersionString(char * value, size_t max) +{ + size_t hw_version_len = 0; // @ithout counting null-terminator + + CHIP_ERROR err = SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_HardwareVersionString, value, max, hw_version_len); +#if defined(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + VerifyOrReturnError(value != nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(max > strlen(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); + Platform::CopyString(value, max, CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING); + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetManufacturingDate(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_ManufacturingDate, value, len); +} + +CHIP_ERROR Storage::GetManufacturingDate(uint8_t * value, size_t max, size_t & size) +{ + return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_ManufacturingDate, (char *) value, max, size); +} + +CHIP_ERROR Storage::SetUniqueId(const uint8_t * value, size_t size) +{ + return SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_UniqueId, value, size); +} + +CHIP_ERROR Storage::GetUniqueId(uint8_t * value, size_t max, size_t & size) +{ + return SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_UniqueId, value, max, size); +} + +// +// CommissionableDataProvider +// + +CHIP_ERROR Storage::SetSetupDiscriminator(uint16_t value) +{ + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_SetupDiscriminator, value); +} + +CHIP_ERROR Storage::GetSetupDiscriminator(uint16_t & value) +{ + CHIP_ERROR err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_SetupDiscriminator, value); +#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR) && CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR; + err = CHIP_NO_ERROR; + } +#endif + ReturnErrorOnFailure(err); + VerifyOrReturnLogError(value <= kMaxDiscriminatorValue, CHIP_ERROR_INVALID_ARGUMENT); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::SetSpake2pIterationCount(uint32_t value) +{ + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_Spake2pIterationCount, value); +} + +CHIP_ERROR Storage::GetSpake2pIterationCount(uint32_t & value) +{ + CHIP_ERROR err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Spake2pIterationCount, value); +#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT) && CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT; + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetSetupPasscode(uint32_t value) +{ + (void) value; + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR Storage::GetSetupPasscode(uint32_t & value) +{ + (void) value; + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR Storage::SetSpake2pSalt(const char * value, size_t size) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_Spake2pSalt, value, size); +} + +CHIP_ERROR Storage::GetSpake2pSalt(char * value, size_t max, size_t & size) +{ + return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_Spake2pSalt, value, max, size); +} + +CHIP_ERROR Storage::SetSpake2pVerifier(const char * value, size_t size) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_Spake2pVerifier, value, size); +} + +CHIP_ERROR Storage::GetSpake2pVerifier(char * value, size_t max, size_t & size) +{ + return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_Spake2pVerifier, value, max, size); +} + +// +// DeviceAttestationCredentialsProvider +// + +CHIP_ERROR Storage::SetFirmwareInformation(const ByteSpan & value) +{ + (void) value; + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::GetFirmwareInformation(MutableByteSpan & value) +{ + // TODO: We need a real example FirmwareInformation to be populated. + value.reduce_size(0); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::SetCertificationDeclaration(const ByteSpan & value) +{ + ReturnErrorOnFailure(WriteFile(*this, SilabsConfig::kConfigKey_Creds_CD_Offset, SilabsConfig::kConfigKey_Creds_CD_Size, value)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::GetCertificationDeclaration(MutableByteSpan & value) +{ + CHIP_ERROR err = ReadFileByKey(*this, "GetCertificationDeclaration", SilabsConfig::kConfigKey_Creds_CD_Offset, + SilabsConfig::kConfigKey_Creds_CD_Size, value); +#if defined(SL_PROVISION_VERSION_1_0) && SL_PROVISION_VERSION_1_0 + if (CHIP_ERROR_NOT_FOUND == err) + { + // Reading from the old script's location. + err = ReadFileByOffset(*this, "GetDeviceAttestationCert", SL_CREDENTIALS_CD_OFFSET, SL_CREDENTIALS_CD_SIZE, value); + } +#endif +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + if (CHIP_ERROR_NOT_FOUND == err) + { + // Example CD + err = Examples::GetExampleDACProvider()->GetCertificationDeclaration(value); + } +#endif + return err; +} + +CHIP_ERROR Storage::SetProductAttestationIntermediateCert(const ByteSpan & value) +{ + ReturnErrorOnFailure( + WriteFile(*this, SilabsConfig::kConfigKey_Creds_PAI_Offset, SilabsConfig::kConfigKey_Creds_PAI_Size, value)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::GetProductAttestationIntermediateCert(MutableByteSpan & value) +{ + CHIP_ERROR err = ReadFileByKey(*this, "GetProductAttestationIntermediateCert", SilabsConfig::kConfigKey_Creds_PAI_Offset, + SilabsConfig::kConfigKey_Creds_PAI_Size, value); +#if defined(SL_PROVISION_VERSION_1_0) && SL_PROVISION_VERSION_1_0 + if (CHIP_ERROR_NOT_FOUND == err) + { + // Reading from the old script's location. + err = ReadFileByOffset(*this, "GetDeviceAttestationCert", SL_CREDENTIALS_PAI_OFFSET, SL_CREDENTIALS_PAI_SIZE, value); + } +#endif +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + if (CHIP_ERROR_NOT_FOUND == err) + { + // Example PAI + err = Examples::GetExampleDACProvider()->GetProductAttestationIntermediateCert(value); + } +#endif + return err; +} + +CHIP_ERROR Storage::SetDeviceAttestationCert(const ByteSpan & value) +{ + ReturnErrorOnFailure( + WriteFile(*this, SilabsConfig::kConfigKey_Creds_DAC_Offset, SilabsConfig::kConfigKey_Creds_DAC_Size, value)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::GetDeviceAttestationCert(MutableByteSpan & value) +{ + CHIP_ERROR err = ReadFileByKey(*this, "GetDeviceAttestationCert", SilabsConfig::kConfigKey_Creds_DAC_Offset, + SilabsConfig::kConfigKey_Creds_DAC_Size, value); +#if defined(SL_PROVISION_VERSION_1_0) && SL_PROVISION_VERSION_1_0 + if (CHIP_ERROR_NOT_FOUND == err) + { + // Reading from the old script's location. + err = ReadFileByOffset(*this, "GetDeviceAttestationCert", SL_CREDENTIALS_DAC_OFFSET, SL_CREDENTIALS_DAC_SIZE, value); + } +#endif +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + if (CHIP_ERROR_NOT_FOUND == err) + { + // Example DAC + return Examples::GetExampleDACProvider()->GetDeviceAttestationCert(value); + } +#endif + return err; +} + +#ifdef SLI_SI91X_MCU_INTERFACE +CHIP_ERROR Storage::SetDeviceAttestationKey(const ByteSpan & value) +{ + return SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_Creds_KeyId, value.data(), value.size()); +} + +CHIP_ERROR Storage::GetDeviceAttestationCSR(uint16_t vid, uint16_t pid, const CharSpan & cn, MutableCharSpan & csr) +{ + AttestationKey key; + uint8_t temp[kDeviceAttestationKeySizeMax] = { 0 }; + size_t size = 0; + ReturnErrorOnFailure(key.GenerateCSR(vid, pid, cn, csr)); + ReturnErrorOnFailure(key.Export(temp, sizeof(temp), size)); + return SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_Creds_KeyId, temp, size); +} + +CHIP_ERROR Storage::SignWithDeviceAttestationKey(const ByteSpan & message, MutableByteSpan & signature) +{ + if (SilabsConfig::ConfigValueExists(SilabsConfig::kConfigKey_Creds_KeyId)) + { + AttestationKey key; + uint8_t temp[kDeviceAttestationKeySizeMax] = { 0 }; + size_t size = 0; + ReturnErrorOnFailure(SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_Creds_KeyId, temp, sizeof(temp), size)); + key.Import(temp, size); + return key.SignMessage(message, signature); + } + else + { +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + // Example DAC key + return Examples::GetExampleDACProvider()->SignWithDeviceAttestationKey(message, signature); +#else + return CHIP_ERROR_NOT_FOUND; +#endif + } +} + +#else // SLI_SI91X_MCU_INTERFACEX_MCU_INTERFACEX_MCU_INTERFACE + +CHIP_ERROR Storage::SetDeviceAttestationKey(const ByteSpan & value) +{ + AttestationKey key; + ReturnErrorOnFailure(key.Import(value.data(), value.size())); + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_Creds_KeyId, key.GetId()); +} + +CHIP_ERROR Storage::GetDeviceAttestationCSR(uint16_t vid, uint16_t pid, const CharSpan & cn, MutableCharSpan & csr) +{ + AttestationKey key; + ReturnErrorOnFailure(key.GenerateCSR(vid, pid, cn, csr)); + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_Creds_KeyId, key.GetId()); +} + +CHIP_ERROR Storage::SignWithDeviceAttestationKey(const ByteSpan & message, MutableByteSpan & signature) +{ + CHIP_ERROR err = CHIP_ERROR_NOT_FOUND; + uint32_t kid = 0; + + if (SilabsConfig::ConfigValueExists(SilabsConfig::kConfigKey_Creds_KeyId)) + { + ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Creds_KeyId, kid)); + AttestationKey key(kid); + err = key.SignMessage(message, signature); + } +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + else + { + // Example DAC key + err = Examples::GetExampleDACProvider()->SignWithDeviceAttestationKey(message, signature); + } +#endif + ChipLogProgress(DeviceLayer, "SignWithDeviceAttestationKey, kid:%u, msg_size:%u, sig_size:%u, err:0x%02x", (unsigned) kid, + (unsigned) message.size(), (unsigned) signature.size(), (unsigned) err.AsInteger()); + // ChipLogByteSpan(DeviceLayer, ByteSpan(signature.data(), signature.size() < kDebugLength ? signature.size() : kDebugLength)); + return err; +} +#endif // SLI_SI91X_MCU_INTERFACE + +// +// Other +// + +CHIP_ERROR Storage::SetProvisionVersion(const char * value, size_t size) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_Provision_Version, value, size); +} + +CHIP_ERROR Storage::GetProvisionVersion(char * value, size_t max, size_t & size) +{ + return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_Provision_Version, value, max, size); +} + +CHIP_ERROR Storage::SetSetupPayload(const uint8_t * value, size_t size) +{ + return SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_SetupPayloadBitSet, value, size); +} + +CHIP_ERROR Storage::GetSetupPayload(uint8_t * value, size_t max, size_t & size) +{ + return SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_SetupPayloadBitSet, value, max, size); +} + +CHIP_ERROR Storage::SetProvisionRequest(bool value) +{ + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_Provision_Request, value); +} + +CHIP_ERROR Storage::GetProvisionRequest(bool & value) +{ + return SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Provision_Request, value); +} + +#if OTA_ENCRYPTION_ENABLE +CHIP_ERROR Storage::SetOtaTlvEncryptionKey(const ByteSpan & value) +{ + chip::DeviceLayer::Silabs::OtaTlvEncryptionKey::OtaTlvEncryptionKey key; + ReturnErrorOnFailure(key.Import(value.data(), value.size())); + return SilabsConfig::WriteConfigValue(SilabsConfig::kOtaTlvEncryption_KeyId, key.GetId()); +} +#endif + +/** + * @brief Reads the test event trigger key from NVM. If the key isn't present, returns default value if defined. + * + * @param[out] keySpan output buffer. Must be at least large enough for 16 bytes (ken length) + * @return CHIP_ERROR + */ +CHIP_ERROR Storage::GetTestEventTriggerKey(MutableByteSpan & keySpan) +{ + constexpr size_t kEnableKeyLength = 16; // Expected byte size of the EnableKey + CHIP_ERROR err = CHIP_NO_ERROR; + size_t keyLength = 0; + + VerifyOrReturnError(keySpan.size() >= kEnableKeyLength, CHIP_ERROR_BUFFER_TOO_SMALL); + + err = SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_Test_Event_Trigger_Key, keySpan.data(), kEnableKeyLength, + keyLength); +#ifndef NDEBUG +#ifdef SL_MATTER_TEST_EVENT_TRIGGER_ENABLED + if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) + { + + constexpr char enableKey[] = SL_MATTER_TEST_EVENT_TRIGGER_ENABLE_KEY; + if (Encoding::HexToBytes(enableKey, strlen(enableKey), keySpan.data(), kEnableKeyLength) != kEnableKeyLength) + { + // enableKey Hex String doesn't have the correct length + memset(keySpan.data(), 0, keySpan.size()); + return CHIP_ERROR_INTERNAL; + } + err = CHIP_NO_ERROR; + } +#endif // SL_MATTER_TEST_EVENT_TRIGGER_ENABLED +#endif // NDEBUG + + keySpan.reduce_size(kEnableKeyLength); + return err; +} + +} // namespace Provision + +void MigrateUint32(uint32_t old_key, uint32_t new_key) +{ + uint32_t value = 0; + if (SilabsConfig::ConfigValueExists(old_key) && (CHIP_NO_ERROR == SilabsConfig::ReadConfigValue(old_key, value))) + { + SilabsConfig::WriteConfigValue(new_key, value); + } +} + +void MigrateDacProvider(void) +{ + constexpr uint32_t kOldKey_Creds_KeyId = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x21); + constexpr uint32_t kOldKey_Creds_Base_Addr = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x22); + constexpr uint32_t kOldKey_Creds_DAC_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x23); + constexpr uint32_t kOldKey_Creds_DAC_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x24); + constexpr uint32_t kOldKey_Creds_PAI_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x26); + constexpr uint32_t kOldKey_Creds_PAI_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x25); + constexpr uint32_t kOldKey_Creds_CD_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x27); + constexpr uint32_t kOldKey_Creds_CD_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x28); + + MigrateUint32(kOldKey_Creds_KeyId, SilabsConfig::kConfigKey_Creds_KeyId); + MigrateUint32(kOldKey_Creds_Base_Addr, SilabsConfig::kConfigKey_Creds_Base_Addr); + MigrateUint32(kOldKey_Creds_DAC_Offset, SilabsConfig::kConfigKey_Creds_DAC_Offset); + MigrateUint32(kOldKey_Creds_DAC_Size, SilabsConfig::kConfigKey_Creds_DAC_Size); + MigrateUint32(kOldKey_Creds_PAI_Offset, SilabsConfig::kConfigKey_Creds_PAI_Offset); + MigrateUint32(kOldKey_Creds_PAI_Size, SilabsConfig::kConfigKey_Creds_PAI_Size); + MigrateUint32(kOldKey_Creds_CD_Offset, SilabsConfig::kConfigKey_Creds_CD_Offset); + MigrateUint32(kOldKey_Creds_CD_Size, SilabsConfig::kConfigKey_Creds_CD_Size); +} + +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/examples/platform/silabs/provision/ProvisionStorageFlash.cpp b/examples/platform/silabs/provision/ProvisionStorageFlash.cpp new file mode 100644 index 00000000000000..5bd11108bd9cc6 --- /dev/null +++ b/examples/platform/silabs/provision/ProvisionStorageFlash.cpp @@ -0,0 +1,724 @@ +/* + * Copyright (c) 2024 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 "AttestationKey.h" +#include "ProvisionEncoder.h" +#include "ProvisionStorage.h" +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace chip::Credentials; + +#if SLI_SI91X_MCU_INTERFACE +// TODO: Remove this once the flash header integrates these definitions +#define FLASH_ERASE 1 // flash_sector_erase_enable value for erase operation +#define FLASH_WRITE 0 // flash_sector_erase_enable value for write operation + +#define NWP_FLASH_ADDRESS (0x0000000) +#define NWP_FLASH_SIZE (0x0004E20) + +#include +extern "C" { +#include +#include +#include +#include +} + +#else // SLI_SI91X_MCU_INTERFACE +#include +extern uint8_t linker_nvm_end[]; +#endif // SLI_SI91X_MCU_INTERFACE + +namespace { +constexpr size_t kPageSize = FLASH_PAGE_SIZE; +constexpr size_t kMaxBinaryValue = 1024; +constexpr size_t kArgumentBufferSize = 2 * sizeof(uint16_t) + kMaxBinaryValue; // ID(2) + Size(2) + Value(n) +} // namespace + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { +namespace Flash { + +#if SLI_SI91X_MCU_INTERFACE +static uint8_t * sReadOnlyPage = reinterpret_cast(NWP_FLASH_ADDRESS); +#else +static uint8_t * sReadOnlyPage = reinterpret_cast(linker_nvm_end); +#endif // SLI_SI91X_MCU_INTERFACE +uint8_t sTemporaryPage[kPageSize] = { 0 }; +uint8_t * sActivePage = sReadOnlyPage; + +CHIP_ERROR DecodeTotal(Encoding::Buffer & reader, uint16_t & total) +{ + uint16_t sz = 0; + ReturnErrorOnFailure(reader.Get(sz)); + total = (0xffff == sz) ? sizeof(uint16_t) : sz; + reader.in = reader.begin + total; + ReturnErrorCodeIf(reader.in > reader.end, CHIP_ERROR_INTERNAL); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ActivateWrite(uint8_t *& active) +{ +#if !(SLI_SI91X_MCU_INTERFACE) + if (sActivePage == sReadOnlyPage) + { + memcpy(sTemporaryPage, sReadOnlyPage, sizeof(sTemporaryPage)); + } + active = sActivePage = sTemporaryPage; +#endif + return CHIP_NO_ERROR; +} + +CHIP_ERROR Set(uint16_t id, Encoding::Buffer & in) +{ + uint8_t * page = sActivePage; + uint16_t total = 0; + Encoding::Buffer reader(page, kPageSize, true); + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument found(temp, sizeof(temp)); + + // Decode total + ReturnErrorOnFailure(DecodeTotal(reader, total)); + // Search entry + CHIP_ERROR err = Encoding::Version2::Find(reader, id, found); + if ((CHIP_ERROR_NOT_FOUND != err) && (CHIP_NO_ERROR != err)) + { + // Memory corruption, write at the last correct address + return err; + } + ReturnErrorOnFailure(ActivateWrite(page)); + + Encoding::Buffer writer(page, kPageSize); + if (CHIP_ERROR_NOT_FOUND == err) + { + // New entry + size_t temp_total = found.offset; + ReturnErrorCodeIf(temp_total + in.Size() > kPageSize, CHIP_ERROR_INVALID_ARGUMENT); + // Copy entry + ReturnErrorOnFailure(in.Get(page + temp_total, in.Size())); + // Update total + total = temp_total + in.Size(); + ReturnErrorOnFailure(writer.Add(total)); + } + else + { + // Existing entry + if (in.Size() == found.encoded_size) + { + // Same size, keep in place + memset(page + found.offset, 0xff, found.encoded_size); + ReturnErrorOnFailure(in.Get(page + found.offset, in.Size())); + } + else + { + // Size change, move to the end + uint16_t temp_total = total - found.encoded_size; + ReturnErrorCodeIf(temp_total + in.Size() > kPageSize, CHIP_ERROR_INVALID_ARGUMENT); + // Remove the entry + memmove(page + found.offset, page + found.offset + found.encoded_size, temp_total); + // Add the entry + ReturnErrorOnFailure(in.Get(page + temp_total, in.Size())); + // Update total + total = temp_total + in.Size(); + ReturnErrorOnFailure(writer.Add(total)); + } + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR Get(uint16_t id, Encoding::Version2::Argument & arg) +{ + uint16_t total = 0; + + Encoding::Buffer reader(sActivePage, kPageSize, true); + ReturnErrorOnFailure(DecodeTotal(reader, total)); + CHIP_ERROR err = Encoding::Version2::Find(reader, id, arg); + // ProvisionStorage expects CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND + VerifyOrReturnError(CHIP_ERROR_NOT_FOUND != err, CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); + return err; +} + +CHIP_ERROR Set(uint16_t id, uint8_t value) +{ + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Encoding::Version2::Encode(id, &value, arg)); + return Set(id, arg); +} + +CHIP_ERROR Get(uint16_t id, uint8_t & value) +{ + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Get(id, arg)); + VerifyOrReturnError(Encoding::Version2::Type_Int8u == arg.type, CHIP_ERROR_INVALID_ARGUMENT); + value = arg.value.u8; + return CHIP_NO_ERROR; +} + +CHIP_ERROR Set(uint16_t id, uint16_t value) +{ + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Encoding::Version2::Encode(id, &value, arg)); + return Set(id, arg); +} + +CHIP_ERROR Get(uint16_t id, uint16_t & value) +{ + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Get(id, arg)); + VerifyOrReturnError(Encoding::Version2::Type_Int16u == arg.type, CHIP_ERROR_INVALID_ARGUMENT); + value = arg.value.u16; + return CHIP_NO_ERROR; +} + +CHIP_ERROR Set(uint16_t id, uint32_t value) +{ + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Encoding::Version2::Encode(id, &value, arg)); + return Set(id, arg); +} + +CHIP_ERROR Get(uint16_t id, uint32_t & value) +{ + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Get(id, arg)); + VerifyOrReturnError(Encoding::Version2::Type_Int32u == arg.type, CHIP_ERROR_INVALID_ARGUMENT); + value = arg.value.u32; + return CHIP_NO_ERROR; +} + +CHIP_ERROR Set(uint16_t id, const uint8_t * value, size_t size) +{ + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Encoding::Version2::Encode(id, value, size, arg)); + return Set(id, arg); +} + +CHIP_ERROR Get(uint16_t id, uint8_t * value, size_t max_size, size_t & size) +{ + + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Get(id, arg)); + VerifyOrReturnError(Encoding::Version2::Type_Binary == arg.type, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(arg.size <= max_size, CHIP_ERROR_INTERNAL); + memcpy(value, arg.value.b, arg.size); + size = arg.size; + return CHIP_NO_ERROR; +} + +CHIP_ERROR Set(uint16_t id, const char * value, size_t size) +{ + return Set(id, (const uint8_t *) value, size); +} + +CHIP_ERROR Get(uint16_t id, char * value, size_t max_size, size_t & size) +{ + return Get(id, (uint8_t *) value, max_size - 1, size); +} + +} // namespace Flash + +// +// Initialization +// + +CHIP_ERROR Storage::Initialize(uint32_t flash_addr, uint32_t flash_size) +{ +#if SLI_SI91X_MCU_INTERFACE + sl_status_t status = sl_si91x_command_to_read_common_flash((uint32_t) (Flash::sReadOnlyPage), sizeof(Flash::sTemporaryPage), + Flash::sTemporaryPage); + VerifyOrReturnError(status == SL_STATUS_OK, CHIP_ERROR_INVALID_ARGUMENT); + Flash::sActivePage = Flash::sTemporaryPage; + +#else // SLI_SI91X_MCU_INTERFACE + if (flash_size > 0) + { + Flash::sReadOnlyPage = (uint8_t *) (flash_addr + flash_size - kPageSize); + } + Flash::sActivePage = Flash::sReadOnlyPage; + MSC_Init(); +#endif + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::Commit() +{ + if (Flash::sActivePage == Flash::sTemporaryPage) + { +#if SLI_SI91X_MCU_INTERFACE + // Erase page + sl_status_t status = sl_si91x_command_to_write_common_flash((uint32_t) (Flash::sReadOnlyPage), Flash::sTemporaryPage, + kPageSize, FLASH_ERASE); + VerifyOrReturnError(status == SL_STATUS_OK, CHIP_ERROR_WRITE_FAILED); + // Write to flash + status = sl_si91x_command_to_write_common_flash((uint32_t) (Flash::sReadOnlyPage), Flash::sTemporaryPage, kPageSize, + FLASH_WRITE); + VerifyOrReturnError(status == SL_STATUS_OK, CHIP_ERROR_WRITE_FAILED); +#else + // Erase page + MSC_ErasePage((uint32_t *) Flash::sReadOnlyPage); + // Write to flash + MSC_WriteWord((uint32_t *) Flash::sReadOnlyPage, Flash::sTemporaryPage, kPageSize); +#endif // SLI_SI91X_MCU_INTERFACE + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::GetBaseAddress(uint32_t & value) +{ + value = (uint32_t) Flash::sReadOnlyPage; + return CHIP_NO_ERROR; +} + +// +// DeviceInstanceInfoProvider +// + +CHIP_ERROR Storage::SetSerialNumber(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kSerialNumber, value, len); +} + +CHIP_ERROR Storage::GetSerialNumber(char * value, size_t max) +{ + size_t size = 0; + return Flash::Get(Parameters::ID::kSerialNumber, value, max, size); +} + +CHIP_ERROR Storage::SetVendorId(uint16_t value) +{ + return Flash::Set(Parameters::ID::kVendorId, value); +} + +CHIP_ERROR Storage::GetVendorId(uint16_t & value) +{ + CHIP_ERROR err = Flash::Get(Parameters::ID::kVendorId, value); +#if defined(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID) && CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID; + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetVendorName(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kVendorName, value, len); +} + +CHIP_ERROR Storage::GetVendorName(char * value, size_t max) +{ + size_t size = 0; + CHIP_ERROR err = Flash::Get(Parameters::ID::kVendorName, value, max, size); +#if defined(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + VerifyOrReturnError(value != nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(max > strlen(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + Platform::CopyString(value, max, CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME); + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetProductId(uint16_t value) +{ + return Flash::Set(Parameters::ID::kProductId, value); +} + +CHIP_ERROR Storage::GetProductId(uint16_t & value) +{ + CHIP_ERROR err = Flash::Get(Parameters::ID::kProductId, value); +#if defined(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID) && CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID; + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetProductName(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kProductName, value, len); +} + +CHIP_ERROR Storage::GetProductName(char * value, size_t max) +{ + size_t size = 0; + CHIP_ERROR err = Flash::Get(Parameters::ID::kProductName, value, max, size); +#if defined(CHIP_DEVICE_CONFIG_TEST_PRODUCT_NAME) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + VerifyOrReturnError(value != nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(max > strlen(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + Platform::CopyString(value, max, CHIP_DEVICE_CONFIG_TEST_PRODUCT_NAME); + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetProductLabel(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kProductLabel, value, len); +} + +CHIP_ERROR Storage::GetProductLabel(char * value, size_t max) +{ + size_t size = 0; + return Flash::Get(Parameters::ID::kProductLabel, value, max, size); +} + +CHIP_ERROR Storage::SetProductURL(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kProductUrl, value, len); +} +CHIP_ERROR Storage::GetProductURL(char * value, size_t max) +{ + size_t size = 0; + return Flash::Get(Parameters::ID::kProductUrl, value, max, size); +} + +CHIP_ERROR Storage::SetPartNumber(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kPartNumber, value, len); +} + +CHIP_ERROR Storage::GetPartNumber(char * value, size_t max) +{ + size_t size = 0; + return Flash::Get(Parameters::ID::kPartNumber, value, max, size); +} + +CHIP_ERROR Storage::SetHardwareVersion(uint16_t value) +{ + return Flash::Set(Parameters::ID::kHwVersion, value); +} + +CHIP_ERROR Storage::GetHardwareVersion(uint16_t & value) +{ + CHIP_ERROR err = Flash::Get(Parameters::ID::kHwVersion, value); +#if defined(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION; + err = CHIP_NO_ERROR; + } +#endif // CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION + return err; +} + +CHIP_ERROR Storage::SetHardwareVersionString(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kHwVersionStr, value, len); +} + +CHIP_ERROR Storage::GetHardwareVersionString(char * value, size_t max) +{ + size_t size = 0; + CHIP_ERROR err = Flash::Get(Parameters::ID::kHwVersionStr, value, max, size); +#if defined(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + VerifyOrReturnError(value != nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(max > strlen(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); + Platform::CopyString(value, max, CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING); + err = CHIP_NO_ERROR; + } +#endif // CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING + return err; +} + +CHIP_ERROR Storage::SetManufacturingDate(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kManufacturingDate, value, len); +} + +CHIP_ERROR Storage::GetManufacturingDate(uint8_t * value, size_t max, size_t & size) +{ + return Flash::Get(Parameters::ID::kManufacturingDate, value, max, size); +} + +CHIP_ERROR Storage::SetUniqueId(const uint8_t * value, size_t size) +{ + return Flash::Set(Parameters::ID::kUniqueId, value, size); +} + +CHIP_ERROR Storage::GetUniqueId(uint8_t * value, size_t max, size_t & size) +{ + return Flash::Get(Parameters::ID::kUniqueId, value, max, size); +} + +// +// CommissionableDataProvider +// + +CHIP_ERROR Storage::SetSetupDiscriminator(uint16_t value) +{ + return Flash::Set(Parameters::ID::kDiscriminator, value); +} + +CHIP_ERROR Storage::GetSetupDiscriminator(uint16_t & value) +{ + CHIP_ERROR err = Flash::Get(Parameters::ID::kDiscriminator, value); +#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR) && CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR; + err = CHIP_NO_ERROR; + } +#endif // CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR + ReturnErrorOnFailure(err); + VerifyOrReturnLogError(value <= kMaxDiscriminatorValue, CHIP_ERROR_INVALID_ARGUMENT); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::SetSpake2pIterationCount(uint32_t value) +{ + return Flash::Set(Parameters::ID::kSpake2pIterations, value); +} + +CHIP_ERROR Storage::GetSpake2pIterationCount(uint32_t & value) +{ + CHIP_ERROR err = Flash::Get(Parameters::ID::kSpake2pIterations, value); +#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT) && CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT; + err = CHIP_NO_ERROR; + } +#endif // CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT + return err; +} + +CHIP_ERROR Storage::SetSetupPasscode(uint32_t value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR Storage::GetSetupPasscode(uint32_t & value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR Storage::SetSpake2pSalt(const char * value, size_t size) +{ + return Flash::Set(Parameters::ID::kSpake2pSalt, value, size); +} + +CHIP_ERROR Storage::GetSpake2pSalt(char * value, size_t max, size_t & size) +{ + return Flash::Get(Parameters::ID::kSpake2pSalt, value, max, size); +} + +CHIP_ERROR Storage::SetSpake2pVerifier(const char * value, size_t size) +{ + return Flash::Set(Parameters::ID::kSpake2pVerifier, value, size); +} + +CHIP_ERROR Storage::GetSpake2pVerifier(char * value, size_t max, size_t & size) +{ + return Flash::Get(Parameters::ID::kSpake2pVerifier, value, max, size); +} + +// +// DeviceAttestationCredentialsProvider +// + +CHIP_ERROR Storage::SetFirmwareInformation(const ByteSpan & value) +{ + (void) value; + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::GetFirmwareInformation(MutableByteSpan & value) +{ + // TODO: We need a real example FirmwareInformation to be populated. + value.reduce_size(0); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::SetCertificationDeclaration(const ByteSpan & value) +{ + return Flash::Set(Parameters::ID::kCertification, value.data(), value.size()); +} + +CHIP_ERROR Storage::GetCertificationDeclaration(MutableByteSpan & value) +{ + size_t size = 0; + CHIP_ERROR err = (Flash::Get(Parameters::ID::kCertification, value.data(), value.size(), size)); +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + // Example CD + return Examples::GetExampleDACProvider()->GetCertificationDeclaration(value); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + ReturnErrorOnFailure(err); + value.reduce_size(size); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::SetProductAttestationIntermediateCert(const ByteSpan & value) +{ + return Flash::Set(Parameters::ID::kPaiCert, value.data(), value.size()); +} + +CHIP_ERROR Storage::GetProductAttestationIntermediateCert(MutableByteSpan & value) +{ + size_t size = 0; + CHIP_ERROR err = (Flash::Get(Parameters::ID::kPaiCert, value.data(), value.size(), size)); +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + // Example PAI + return Examples::GetExampleDACProvider()->GetProductAttestationIntermediateCert(value); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + ReturnErrorOnFailure(err); + value.reduce_size(size); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::SetDeviceAttestationCert(const ByteSpan & value) +{ + return Flash::Set(Parameters::ID::kDacCert, value.data(), value.size()); +} + +CHIP_ERROR Storage::GetDeviceAttestationCert(MutableByteSpan & value) +{ + size_t size = 0; + CHIP_ERROR err = (Flash::Get(Parameters::ID::kDacCert, value.data(), value.size(), size)); +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + // Example DAC + return Examples::GetExampleDACProvider()->GetDeviceAttestationCert(value); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + ReturnErrorOnFailure(err); + value.reduce_size(size); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::SetDeviceAttestationKey(const ByteSpan & value) +{ + return Flash::Set(Parameters::ID::kDacKey, value.data(), value.size()); +} + +CHIP_ERROR Storage::GetDeviceAttestationCSR(uint16_t vid, uint16_t pid, const CharSpan & cn, MutableCharSpan & csr) +{ + AttestationKey key; + uint8_t temp[kDeviceAttestationKeySizeMax] = { 0 }; + size_t size = 0; + ReturnErrorOnFailure(key.GenerateCSR(vid, pid, cn, csr)); + ReturnErrorOnFailure(key.Export(temp, sizeof(temp), size)); + return Flash::Set(Parameters::ID::kDacKey, temp, size); +} + +CHIP_ERROR Storage::SignWithDeviceAttestationKey(const ByteSpan & message, MutableByteSpan & signature) +{ + AttestationKey key; + uint8_t temp[kDeviceAttestationKeySizeMax] = { 0 }; + size_t size = 0; + CHIP_ERROR err = Flash::Get(Parameters::ID::kDacKey, temp, sizeof(temp), size); +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + // Example DAC key + return Examples::GetExampleDACProvider()->SignWithDeviceAttestationKey(message, signature); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + ReturnErrorOnFailure(err); + ReturnErrorOnFailure(key.Import(temp, size)); + return key.SignMessage(message, signature); +} + +// +// Other +// + +CHIP_ERROR Storage::SetProvisionVersion(const char * value, size_t size) +{ + return Flash::Set(Parameters::ID::kVersion, value, size); +} + +CHIP_ERROR Storage::GetProvisionVersion(char * value, size_t max, size_t & size) +{ + return Flash::Get(Parameters::ID::kVersion, value, max, size); +} + +CHIP_ERROR Storage::SetSetupPayload(const uint8_t * value, size_t size) +{ + return Flash::Set(Parameters::ID::kSetupPayload, value, size); +} + +CHIP_ERROR Storage::GetSetupPayload(uint8_t * value, size_t max, size_t & size) +{ + return Flash::Get(Parameters::ID::kSetupPayload, value, max, size); +} + +CHIP_ERROR Storage::SetProvisionRequest(bool value) +{ + // return Flash::Set(Parameters::ID::kProvisionRequest, value); + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR Storage::GetProvisionRequest(bool & value) +{ + // return Flash::Set(Parameters::ID::kProvisionRequest, value); + return CHIP_ERROR_NOT_IMPLEMENTED; +} +#if OTA_ENCRYPTION_ENABLE +CHIP_ERROR Storage::SetOtaTlvEncryptionKey(const ByteSpan & value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} +#endif + +CHIP_ERROR Storage::GetTestEventTriggerKey(MutableByteSpan & keySpan) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +} // namespace Provision + +void MigrateDacProvider(void) {} + +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/examples/platform/silabs/silabs_creds.h b/examples/platform/silabs/silabs_creds.h index 792c7b2238afaa..bd6c3377006945 100644 --- a/examples/platform/silabs/silabs_creds.h +++ b/examples/platform/silabs/silabs_creds.h @@ -1,41 +1,49 @@ -/** - * This is a boilerplat header to define the SILABS authentication credentials. - * Applications must provide their own version of this header, and include: - * - The content of the CSA-provided Certification Declaration - * - The location and size of the PAI, and DAC - * - The key ID of the key-pair associated with the DAC +/* + * + * Copyright (c) 2024 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 * - * These credentials MUST be provided if the build variable "chip_build_device_attestation_credentials" is set to true. + * 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. + */ +/** + * To enable these credentias, compile the app with option + * "chip_build_device_attestation_credentials=true". */ -#ifndef SILABS_DEVICE_CREDENTIALS -#define SILABS_DEVICE_CREDENTIALS -#ifndef SILABS_CREDENTIALS_DAC_KEY_ID -#define SILABS_CREDENTIALS_DAC_KEY_ID 0x0002 +#ifndef SL_PROVISION_VERSION_1_0 +#define SL_PROVISION_VERSION_1_0 0 #endif -#ifndef SILABS_CREDENTIALS_DAC_OFFSET -#define SILABS_CREDENTIALS_DAC_OFFSET 0x0000 +#ifndef SL_CREDENTIALS_DAC_OFFSET +#define SL_CREDENTIALS_DAC_OFFSET 0x0000 #endif -#ifndef SILABS_CREDENTIALS_DAC_SIZE -#define SILABS_CREDENTIALS_DAC_SIZE 0 +#ifndef SL_CREDENTIALS_DAC_SIZE +#define SL_CREDENTIALS_DAC_SIZE 0 #endif -#ifndef SILABS_CREDENTIALS_PAI_OFFSET -#define SILABS_CREDENTIALS_PAI_OFFSET 0x0200 +#ifndef SL_CREDENTIALS_PAI_OFFSET +#define SL_CREDENTIALS_PAI_OFFSET 0x0200 #endif -#ifndef SILABS_CREDENTIALS_PAI_SIZE -#define SILABS_CREDENTIALS_PAI_SIZE 0 +#ifndef SL_CREDENTIALS_PAI_SIZE +#define SL_CREDENTIALS_PAI_SIZE 0 #endif -#ifndef SILABS_CREDENTIALS_CD_OFFSET -#define SILABS_CREDENTIALS_CD_OFFSET 0x0400 +#ifndef SL_CREDENTIALS_CD_OFFSET +#define SL_CREDENTIALS_CD_OFFSET 0x0400 #endif -#ifndef SILABS_CREDENTIALS_CD_SIZE -#define SILABS_CREDENTIALS_CD_SIZE 0 +#ifndef SL_CREDENTIALS_CD_SIZE +#define SL_CREDENTIALS_CD_SIZE 0 #endif - -#endif // SILABS_DEVICE_CREDENTIALS diff --git a/src/platform/silabs/efr32/BLEManagerImpl.cpp b/src/platform/silabs/efr32/BLEManagerImpl.cpp index 000ddbea63c4ed..78bd13d061ef45 100644 --- a/src/platform/silabs/efr32/BLEManagerImpl.cpp +++ b/src/platform/silabs/efr32/BLEManagerImpl.cpp @@ -52,6 +52,9 @@ extern "C" { #include #endif +#include +#include + using namespace ::chip; using namespace ::chip::Ble; @@ -725,12 +728,20 @@ void BLEManagerImpl::HandleConnectionCloseEvent(volatile sl_bt_msg_t * evt) void BLEManagerImpl::HandleWriteEvent(volatile sl_bt_msg_t * evt) { uint16_t attribute = evt->data.evt_gatt_server_user_write_request.characteristic; - + bool do_provision = chip::DeviceLayer::Silabs::Provision::Manager::GetInstance().IsProvisionRequired(); ChipLogProgress(DeviceLayer, "Char Write Req, char : %d", attribute); if (gattdb_CHIPoBLEChar_Rx == attribute) { - HandleRXCharWrite(evt); + if (do_provision) + { + chip::DeviceLayer::Silabs::Provision::Channel::Update(attribute); + chip::DeviceLayer::Silabs::Provision::Manager::GetInstance().Step(); + } + else + { + HandleRXCharWrite(evt); + } } } diff --git a/src/platform/silabs/efr32/BUILD.gn b/src/platform/silabs/efr32/BUILD.gn index 3d1510d5029d9e..5d661886d54f21 100644 --- a/src/platform/silabs/efr32/BUILD.gn +++ b/src/platform/silabs/efr32/BUILD.gn @@ -98,7 +98,8 @@ static_library("efr32") { "${chip_root}/src/platform:platform_base", "${chip_root}/src/platform/logging:headers", ] - deps = [] + deps = [ "${silabs_platform_dir}/provision:provision-headers" ] + public_configs = [] # Add platform crypto implementation if (chip_crypto == "platform") { @@ -136,8 +137,6 @@ static_library("efr32") { ] deps += [ "${chip_root}/src/lib/dnssd:platform_header" ] } - - public_configs = [] } if (chip_enable_wifi) { @@ -160,7 +159,7 @@ static_library("efr32") { ] } - public_configs = [ ":efr32-platform-wifi-config" ] + public_configs += [ ":efr32-platform-wifi-config" ] } } diff --git a/src/platform/silabs/platformAbstraction/GsdkSpam.cpp b/src/platform/silabs/platformAbstraction/GsdkSpam.cpp index 76673b001a9c6b..0881bea848112b 100644 --- a/src/platform/silabs/platformAbstraction/GsdkSpam.cpp +++ b/src/platform/silabs/platformAbstraction/GsdkSpam.cpp @@ -159,7 +159,19 @@ void sl_button_on_change(const sl_button_t * handle) } } } -#endif + +uint8_t SilabsPlatform::GetButtonState(uint8_t button) +{ + const sl_button_t * handle = SL_SIMPLE_BUTTON_INSTANCE(button); + return nullptr == handle ? 0 : sl_button_get_state(handle); +} + +#else +uint8_t SilabsPlatform::GetButtonState(uint8_t button) +{ + return 0; +} +#endif // SL_CATALOG_SIMPLE_BUTTON_PRESENT } // namespace Silabs } // namespace DeviceLayer diff --git a/src/platform/silabs/platformAbstraction/SilabsPlatform.h b/src/platform/silabs/platformAbstraction/SilabsPlatform.h index 4c42a79996b3f0..49f5264cac0550 100644 --- a/src/platform/silabs/platformAbstraction/SilabsPlatform.h +++ b/src/platform/silabs/platformAbstraction/SilabsPlatform.h @@ -48,10 +48,12 @@ class SilabsPlatform : virtual public SilabsPlatformAbstractionBase CHIP_ERROR ToggleLed(uint8_t led) override; #endif + // Buttons inline void SetButtonsCb(SilabsButtonCb callback) override { mButtonCallback = callback; } inline uint32_t GetRebootCause() { return mRebootCause; } static SilabsButtonCb mButtonCallback; + uint8_t GetButtonState(uint8_t button) override; void StartScheduler(void) override; diff --git a/src/platform/silabs/platformAbstraction/SilabsPlatformBase.h b/src/platform/silabs/platformAbstraction/SilabsPlatformBase.h index fa387228ab2885..12f87c07ea7e0d 100644 --- a/src/platform/silabs/platformAbstraction/SilabsPlatformBase.h +++ b/src/platform/silabs/platformAbstraction/SilabsPlatformBase.h @@ -43,6 +43,7 @@ class SilabsPlatformAbstractionBase // Buttons typedef void (*SilabsButtonCb)(uint8_t, uint8_t); virtual void SetButtonsCb(SilabsButtonCb callback) {} + virtual uint8_t GetButtonState(uint8_t button) { return 0; } // LEDS virtual void InitLed(void) {} diff --git a/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp b/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp index 1d4456a53868d3..0bddafd96506f9 100644 --- a/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp +++ b/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp @@ -16,6 +16,7 @@ */ #include +#include #include #include @@ -153,6 +154,11 @@ void sl_button_on_change(uint8_t btn, uint8_t btnAction) } } +uint8_t SilabsPlatform::GetButtonState(uint8_t button) +{ + return (button < SL_SI91x_BUTTON_COUNT) ? sButtonStates[button] : 0; +} + } // namespace Silabs } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/silabs/provision/AttestationKey.h b/src/platform/silabs/provision/AttestationKey.h new file mode 100644 index 00000000000000..5f7930bb0528e1 --- /dev/null +++ b/src/platform/silabs/provision/AttestationKey.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 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 +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { + +static constexpr uint32_t kCreds_KeyId_Default = 2; //(PSA_KEY_ID_USER_MIN + 1); + +class AttestationKey +{ +public: + AttestationKey(uint32_t id = 0) { mId = (id > 0) ? id : kCreds_KeyId_Default; } + ~AttestationKey() = default; + + uint32_t GetId() { return mId; } + CHIP_ERROR Import(const uint8_t * asn1, size_t size); + CHIP_ERROR Export(uint8_t * asn1, size_t max, size_t & size); + CHIP_ERROR GenerateCSR(uint16_t vid, uint16_t pid, const CharSpan & cn, MutableCharSpan & csr); + CHIP_ERROR SignMessage(const ByteSpan & message, MutableByteSpan & out_span); + +protected: + uint32_t mId = 0; +}; + +} // namespace Provision +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/provision/BUILD.gn b/src/platform/silabs/provision/BUILD.gn new file mode 100644 index 00000000000000..ea5d4b072a03ac --- /dev/null +++ b/src/platform/silabs/provision/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/chip.gni") +import("//build_overrides/efr32_sdk.gni") +import("${efr32_sdk_build_root}/silabs_board.gni") + +config("provision-config") { + include_dirs = [ "." ] + + defines = [ "CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS=1" ] + if (use_provision_channel) { + defines += [ "SL_MATTER_PROVISION_CHANNEL_ENABLED=1" ] + } +} + +source_set("provision-headers") { + sources = [ + "AttestationKey.h", + "ProvisionChannel.h", + "ProvisionEncoder.h", + "ProvisionManager.h", + "ProvisionProtocol.h", + "ProvisionStorage.h", + ] + public_configs = [ ":provision-config" ] +} diff --git a/examples/platform/silabs/SilabsDeviceAttestationCreds.h b/src/platform/silabs/provision/ProvisionChannel.h similarity index 55% rename from examples/platform/silabs/SilabsDeviceAttestationCreds.h rename to src/platform/silabs/provision/ProvisionChannel.h index 79f8f8df042aa8..a15b4364a88092 100644 --- a/examples/platform/silabs/SilabsDeviceAttestationCreds.h +++ b/src/platform/silabs/provision/ProvisionChannel.h @@ -1,6 +1,6 @@ /* - * - * Copyright (c) 2022 Project CHIP Authors + * Copyright (c) 2024 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. @@ -16,23 +16,29 @@ */ #pragma once -#include +#include +#include +#include namespace chip { -namespace Credentials { +namespace DeviceLayer { namespace Silabs { +namespace Provision { -/** - * @brief Get implementation of a sample DAC provider to validate device - * attestation procedure. - * - * @returns a singleton DeviceAttestationCredentialsProvider that relies on no - * storage abstractions. - */ -DeviceAttestationCredentialsProvider * GetSilabsDacProvider(); +class Channel +{ +public: + Channel() = default; + ~Channel() = default; + + CHIP_ERROR Init(); + CHIP_ERROR Read(uint8_t * buffer, size_t buffer_length, size_t & bytes_read); + CHIP_ERROR Write(const uint8_t * buffer, size_t buffer_length); -void SilabsDacProviderMigration(void); + static CHIP_ERROR Update(uint16_t handle); +}; +} // namespace Provision } // namespace Silabs -} // namespace Credentials +} // namespace DeviceLayer } // namespace chip diff --git a/src/platform/silabs/provision/ProvisionEncoder.h b/src/platform/silabs/provision/ProvisionEncoder.h new file mode 100644 index 00000000000000..0c5a5e2bfe22ca --- /dev/null +++ b/src/platform/silabs/provision/ProvisionEncoder.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2024 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 +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { +namespace Encoding { + +struct Buffer +{ + Buffer(uint8_t * ptr, size_t size, bool at_end = false) { Init(ptr, size, at_end); } + + void Init(uint8_t * ptr, size_t size, bool at_end = false) + { + this->begin = ptr; + this->end = ptr + size; + this->in = at_end ? end : begin; + this->out = ptr; + } + + void Clear() { this->in = this->out = this->begin; } + size_t Limit() { return (this->end > this->begin) ? (this->end - this->begin) : 0; } + size_t Size() { return (this->in > this->begin) ? (this->in - this->begin) : 0; } + size_t Offset() { return (this->out > this->begin) ? (this->out - this->begin) : 0; } + size_t Left() { return this->Size() - this->Offset(); } + size_t Spare() { return this->Limit() - this->Size(); } + + CHIP_ERROR Add(uint8_t in); + CHIP_ERROR Add(uint16_t in); + CHIP_ERROR Add(uint32_t in); + CHIP_ERROR Add(int32_t in); + CHIP_ERROR Add(const uint8_t * in, size_t size); + CHIP_ERROR Add(Buffer & from, size_t size); + CHIP_ERROR Get(uint8_t & out); + CHIP_ERROR Get(uint16_t & out); + CHIP_ERROR Get(uint32_t & out); + CHIP_ERROR Get(uint8_t * out, size_t size); + CHIP_ERROR Get(Buffer & into, size_t size); + + uint8_t * begin = nullptr; + uint8_t * end = nullptr; + uint8_t * in = nullptr; + uint8_t * out = nullptr; +}; + +//------------------------------------------------------------------------------ +// Version 1 +//------------------------------------------------------------------------------ +#ifdef SILABS_PROVISION_PROTOCOL_V1 + +namespace Version1 { + +enum Types : uint8_t +{ + Type_None = 0x00, + Type_Int8u = 0x01, + Type_Int16u = 0x02, + Type_Int32u = 0x03, + Type_Array = 0x04, +}; + +CHIP_ERROR Encode(Buffer & arg, uint8_t in); +CHIP_ERROR Encode(Buffer & arg, uint16_t in); +CHIP_ERROR Encode(Buffer & arg, int32_t in); +CHIP_ERROR Encode(Buffer & arg, uint32_t in); +CHIP_ERROR Encode(Buffer & arg, const uint8_t * in, size_t size); +CHIP_ERROR Encode(Buffer & arg, const char * in); + +CHIP_ERROR Decode(Buffer & arg, uint8_t & out); +CHIP_ERROR Decode(Buffer & arg, uint16_t & out); +CHIP_ERROR Decode(Buffer & arg, uint32_t & out); +CHIP_ERROR Decode(Buffer & arg, uint8_t * out, size_t limit, size_t & size); +CHIP_ERROR Decode(Buffer & arg, char * out, size_t limit, size_t & size); + +namespace Legacy { +CHIP_ERROR DecodeInt8u(Encoding::Buffer & in, uint8_t & out); +CHIP_ERROR DecodeInt16u(Encoding::Buffer & in, uint16_t & out); +CHIP_ERROR DecodeInt32u(Encoding::Buffer & in, uint32_t & out); +} // namespace Legacy + +} // namespace Version1 + +#endif // SILABS_PROVISION_PROTOCOL_V1 + +//------------------------------------------------------------------------------ +// Version 2 +//------------------------------------------------------------------------------ + +namespace Version2 { + +enum Types : uint8_t +{ + Type_Binary = 0x00, + Type_Int8u = 0x01, + Type_Int16u = 0x02, + Type_Int32u = 0x03, + Type_Int64u = 0x04, + Type_String = 0x08, + Type_Int8s = 0x09, + Type_Int16s = 0x0a, + Type_Int32s = 0x0b, + Type_Int64s = 0x0c, +}; + +union Value +{ + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint32_t u64; + uint8_t * b; +}; + +struct Argument : public Buffer +{ + enum States : uint8_t + { + State_Flags = 1, + State_Size = 3, + State_Data = 4, + State_Ready = 5, + }; + + Argument(uint8_t * ptr, size_t size) : Buffer(ptr, size) { Reset(); } + + void Reset() + { + this->Clear(); + this->state = State_Flags; + this->id = 0; + this->type = 0; + this->size = 0; + this->size_len = 0; + this->encoded_size = 0; + this->is_null = false; + this->is_binary = false; + this->is_known = false; + this->feedback = false; + this->offset = 0; + memset(&this->value, 0x00, sizeof(Value)); + } + + States state = State_Flags; + uint16_t id = 0; + uint8_t type = 0; + size_t size = 0; + uint8_t size_len = 0; + size_t encoded_size = 0; + bool is_null = false; + bool is_binary = false; + bool is_known = false; + bool feedback = false; + size_t offset = 0; + Value value; +}; + +CHIP_ERROR Encode(uint16_t id, uint8_t * value, Buffer & out); +CHIP_ERROR Encode(uint16_t id, uint16_t * value, Buffer & out); +CHIP_ERROR Encode(uint16_t id, uint32_t * value, Buffer & out); +CHIP_ERROR Encode(uint16_t id, const uint8_t * value, size_t size, Buffer & out); +CHIP_ERROR Decode(Buffer & in, Argument & arg); +CHIP_ERROR Find(Buffer & in, uint16_t id, Argument & arg); + +} // namespace Version2 + +} // namespace Encoding +} // namespace Provision +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/provision/ProvisionManager.h b/src/platform/silabs/provision/ProvisionManager.h new file mode 100644 index 00000000000000..c73e920c345ce1 --- /dev/null +++ b/src/platform/silabs/provision/ProvisionManager.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024 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 "ProvisionChannel.h" +#include "ProvisionProtocol.h" +#include "ProvisionStorage.h" +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { + +class Manager +{ +public: + Manager() : +#ifdef SILABS_PROVISION_PROTOCOL_V1 + mProtocol1(mStore), +#endif + mProtocol2(mStore) + {} + + CHIP_ERROR Init(); + bool Step(); + bool IsProvisionRequired(); + CHIP_ERROR SetProvisionRequired(bool required); + Storage & GetStorage() { return mStore; } + static Manager & GetInstance(); + +private: + bool ProcessCommand(ByteSpan & request, MutableByteSpan & response); + + Storage mStore; + Channel mChannel; +#ifdef SILABS_PROVISION_PROTOCOL_V1 + Protocol1 mProtocol1; +#endif + Protocol2 mProtocol2; + bool mProvisionRequested = true; +}; + +} // namespace Provision +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/provision/ProvisionProtocol.h b/src/platform/silabs/provision/ProvisionProtocol.h new file mode 100644 index 00000000000000..03182b59af0468 --- /dev/null +++ b/src/platform/silabs/provision/ProvisionProtocol.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024 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 "ProvisionEncoder.h" +#include "ProvisionStorage.h" +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { + +//------------------------------------------------------------------------------ +// Common +//------------------------------------------------------------------------------ + +class Protocol +{ +public: + /** + * Must hold the header plus complete argument value + */ + Protocol(Storage & store) : mStore(store) {} + virtual ~Protocol() = default; + virtual bool Execute(ByteSpan & request, MutableByteSpan & response) = 0; + +protected: + Storage & mStore; +}; + +//------------------------------------------------------------------------------ +// Version 1 +//------------------------------------------------------------------------------ +#ifdef SILABS_PROVISION_PROTOCOL_V1 + +class Protocol1 : public Protocol +{ +public: + static constexpr size_t kVersion = 1; + + Protocol1(Storage & store) : Protocol(store) {} + virtual bool Execute(ByteSpan & request, MutableByteSpan & response); + +private: + CHIP_ERROR Init(Encoding::Buffer & in, Encoding::Buffer & out); + CHIP_ERROR GenerateCSR(Encoding::Buffer & in, Encoding::Buffer & out); + CHIP_ERROR Import(Encoding::Buffer & in, Encoding::Buffer & out); + CHIP_ERROR Setup(Encoding::Buffer & in, Encoding::Buffer & out); + CHIP_ERROR Read(Encoding::Buffer & in, Encoding::Buffer & out); +}; + +#endif // SILABS_PROVISION_PROTOCOL_V1 + +//------------------------------------------------------------------------------ +// Version 2 +//------------------------------------------------------------------------------ + +class Protocol2 : public Protocol +{ +public: + static constexpr uint8_t kVersion = 2; + // Command flags + static constexpr uint16_t kResponseFlag = 0x80; + // Payload flags + static constexpr uint16_t kCustomIdMin = 0x0000; + static constexpr uint16_t kCustomIdMax = 0x00ff; + static constexpr uint16_t kKnownIdMin = 0x0100; + static constexpr uint16_t kKnownIdMax = 0x01ff; + static constexpr uint16_t kIdMask = 0x01ff; + static constexpr uint16_t kWellKnownMask = 0x0100; + static constexpr uint16_t kSizeBit = 10; + static constexpr uint16_t kSizeMask = 0x0c00; + static constexpr uint16_t kFeedbackMask = 0x0200; + static constexpr uint16_t kTypeBit = 12; + static constexpr uint16_t kTypeMask = 0xf000; + // Limits + static constexpr size_t kPackageSizeMax = 128; + static constexpr size_t kChecksumSize = 2; + static constexpr size_t kRequestHeaderSize = 4; + static constexpr size_t kResponseHeaderSize = 8; + static_assert(kPackageSizeMax > (kResponseHeaderSize + kChecksumSize)); + + Protocol2(Storage & store) : Protocol(store) {} + virtual bool Execute(ByteSpan & request, MutableByteSpan & response); +}; + +} // namespace Provision +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/provision/ProvisionStorage.h b/src/platform/silabs/provision/ProvisionStorage.h new file mode 100644 index 00000000000000..3dbc78076442a7 --- /dev/null +++ b/src/platform/silabs/provision/ProvisionStorage.h @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2024 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 "ProvisionStorageGeneric.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { + +namespace Parameters { + +enum ID : uint16_t +{ + // Internal, + kFlashAddress = 0x0101, + kFlashSize = 0x0102, + kFlashPageSize = 0x0103, + kBaseAddress = 0x0104, + kCsrFile = 0x0105, + // Options, + kVersion = 0x0111, + kAction = 0x0112, + kExtra = 0x0113, + kStop = 0x0114, + kParamsPath = 0x0121, + kInputsPath = 0x0122, + kOutputPath = 0x0123, + kTemporaryDir = 0x0124, + kTargetDevice = 0x0131, + kChannel = 0x0132, + kGenerateCreds = 0x0133, + kCsrMode = 0x0134, + kGeneratorFW = 0x0135, + kProductionFW = 0x0136, + kCertToolPath = 0x0137, + kPylinkLib = 0x0138, + // Instance Info, + kSerialNumber = 0x0141, + kVendorId = 0x0142, + kVendorName = 0x0143, + kProductId = 0x0144, + kProductName = 0x0145, + kProductLabel = 0x0146, + kProductUrl = 0x0147, + kPartNumber = 0x0148, + kHwVersion = 0x0151, + kHwVersionStr = 0x0152, + kManufacturingDate = 0x0153, + kUniqueId = 0x0154, + // Commissionable Data, + kDiscriminator = 0x0161, + kSpake2pPasscode = 0x0162, + kSpake2pIterations = 0x0163, + kSpake2pSalt = 0x0164, + kSpake2pVerifier = 0x0165, + kSetupPayload = 0x0166, + kCommissioningFlow = 0x0167, + kRendezvousFlags = 0x0168, + // Attestation Credentials, + kFirmwareInfo = 0x0181, + kCertification = 0x0182, + kCdCert = 0x0183, + kCdKey = 0x0184, + kPaaCert = 0x0191, + kPaaKey = 0x0192, + kPaiCert = 0x0193, + kPaiKey = 0x0194, + kDacCert = 0x0195, + kDacKey = 0x0196, + kKeyId = 0x0197, + kKeyPass = 0x0198, + kPKCS12 = 0x0199, + kCommonName = 0x01a1, + kOtaTlvEncryptionKey = 0x01a2, +}; + +} // namespace Parameters + +struct CustomStorage : public GenericStorage +{ + CHIP_ERROR Set(uint16_t id, const uint8_t * value) override; + CHIP_ERROR Get(uint16_t id, uint8_t & value) override; + CHIP_ERROR Set(uint16_t id, const uint16_t * value) override; + CHIP_ERROR Get(uint16_t id, uint16_t & value) override; + CHIP_ERROR Set(uint16_t id, const uint32_t * value) override; + CHIP_ERROR Get(uint16_t id, uint32_t & value) override; + CHIP_ERROR Set(uint16_t id, const uint64_t * value) override; + CHIP_ERROR Get(uint16_t id, uint64_t & value) override; + CHIP_ERROR Get(uint16_t id, uint8_t * value, size_t max_size, size_t & size) override; + CHIP_ERROR Set(uint16_t id, const uint8_t * value, size_t size) override; +}; + +namespace { +constexpr size_t kVersionFieldLengthInBits = 3; +constexpr size_t kVendorIDFieldLengthInBits = 16; +constexpr size_t kProductIDFieldLengthInBits = 16; +constexpr size_t kCommissioningFlowFieldLengthInBits = 2; +constexpr size_t kRendezvousInfoFieldLengthInBits = 8; +constexpr size_t kPayloadDiscriminatorFieldLengthInBits = 12; +constexpr size_t kSetupPINCodeFieldLengthInBits = 27; +constexpr size_t kPaddingFieldLengthInBits = 4; +} // namespace + +struct Storage : public GenericStorage, + public chip::DeviceLayer::DeviceInstanceInfoProvider, + public chip::DeviceLayer::CommissionableDataProvider, + public chip::Credentials::DeviceAttestationCredentialsProvider +{ + static constexpr size_t kArgumentSizeMax = 512; + static constexpr size_t kVersionLengthMax = 16; + static constexpr size_t kSerialNumberLengthMax = 32; + static constexpr size_t kVendorNameLengthMax = 32; + static constexpr size_t kProductNameLengthMax = 32; + static constexpr size_t kProductLabelLengthMax = 32; + static constexpr size_t kProductUrlLengthMax = 32; + static constexpr size_t kPartNumberLengthMax = 32; + static constexpr size_t kHardwareVersionStrLengthMax = 32; + static constexpr size_t kManufacturingDateLengthMax = 11; // yyyy-mm-dd + \0 + static constexpr size_t kUniqueIdLengthMax = 16; + static constexpr size_t kSpake2pVerifierB64LengthMax = BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_VerifierSerialized_Length) + 1; + static constexpr size_t kSpake2pSaltB64LengthMax = BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_Max_PBKDF_Salt_Length) + 1; + static constexpr size_t kFirmwareInfoSizeMax = 32; + static constexpr size_t kCertificationSizeMax = 350; + static constexpr size_t kCertificateSizeMax = kArgumentSizeMax; + static constexpr size_t kDeviceAttestationKeySizeMax = 128; + static constexpr size_t kSetupPayloadSizeMax = 32; + static constexpr size_t kCsrLengthMax = 512; + static constexpr size_t kCommonNameMax = 128; + static constexpr size_t kTotalPayloadDataSizeInBits = + (kVersionFieldLengthInBits + kVendorIDFieldLengthInBits + kProductIDFieldLengthInBits + + kCommissioningFlowFieldLengthInBits + kRendezvousInfoFieldLengthInBits + kPayloadDiscriminatorFieldLengthInBits + + kSetupPINCodeFieldLengthInBits + kPaddingFieldLengthInBits); + static constexpr size_t kTotalPayloadDataSize = kTotalPayloadDataSizeInBits / 8; + +public: + static uint8_t aux_buffer[Storage::kArgumentSizeMax]; + + friend class Manager; + friend class Protocol1; + friend class Command; + friend class CsrCommand; + friend class ReadCommand; + friend class WriteCommand; + + // + // Initialization + // + + CHIP_ERROR Initialize(uint32_t flash_addr = 0, uint32_t flash_size = 0); + CHIP_ERROR Commit(); + CHIP_ERROR GetBaseAddress(uint32_t & value); + + // + // Generic Interface + // + + CHIP_ERROR Get(uint16_t id, uint8_t & value) override; + CHIP_ERROR Get(uint16_t id, uint16_t & value) override; + CHIP_ERROR Get(uint16_t id, uint32_t & value) override; + CHIP_ERROR Get(uint16_t id, uint64_t & value) override; + CHIP_ERROR Get(uint16_t id, uint8_t * value, size_t max_size, size_t & size) override; + + // + // DeviceInstanceInfoProvider + // + + CHIP_ERROR GetSerialNumber(char * value, size_t max); + CHIP_ERROR GetVendorId(uint16_t & value); + CHIP_ERROR GetVendorName(char * value, size_t max); + CHIP_ERROR GetProductId(uint16_t & productId); + CHIP_ERROR GetProductName(char * value, size_t max); + CHIP_ERROR GetProductLabel(char * value, size_t max); + CHIP_ERROR GetProductURL(char * value, size_t max); + CHIP_ERROR GetPartNumber(char * value, size_t max); + CHIP_ERROR GetHardwareVersion(uint16_t & value); + CHIP_ERROR GetHardwareVersionString(char * value, size_t max); + CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day); + CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & value); + + // + // CommissionableDataProvider + // + + CHIP_ERROR GetSetupDiscriminator(uint16_t & value); + CHIP_ERROR GetSpake2pIterationCount(uint32_t & value); + CHIP_ERROR GetSetupPasscode(uint32_t & value); + CHIP_ERROR GetSpake2pSalt(MutableByteSpan & value); + CHIP_ERROR GetSpake2pVerifier(MutableByteSpan & value, size_t & size); + + // + // DeviceAttestationCredentialsProvider + // + + CHIP_ERROR GetFirmwareInformation(MutableByteSpan & value); + CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & value); + CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & value); + CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & value); + CHIP_ERROR GetDeviceAttestationCSR(uint16_t vid, uint16_t pid, const CharSpan & cn, MutableCharSpan & csr); + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & message, MutableByteSpan & signature); + + CHIP_ERROR SetCertificationDeclaration(const ByteSpan & value); + CHIP_ERROR SetProductAttestationIntermediateCert(const ByteSpan & value); + CHIP_ERROR SetDeviceAttestationCert(const ByteSpan & value); + CHIP_ERROR SetDeviceAttestationKey(const ByteSpan & value); + // + // Other + // + + CHIP_ERROR GetSetupPayload(chip::MutableCharSpan & value); + CHIP_ERROR SetProvisionRequest(bool value); + CHIP_ERROR GetProvisionRequest(bool & value); + CHIP_ERROR GetTestEventTriggerKey(MutableByteSpan & keySpan); + +private: + // Generic Interface + CHIP_ERROR Set(uint16_t id, const uint8_t * value) override; + CHIP_ERROR Set(uint16_t id, const uint16_t * value) override; + CHIP_ERROR Set(uint16_t id, const uint32_t * value) override; + CHIP_ERROR Set(uint16_t id, const uint64_t * value) override; + CHIP_ERROR Set(uint16_t id, const uint8_t * value, size_t size) override; + // DeviceInstanceInfoProvider + CHIP_ERROR SetSerialNumber(const char * value, size_t len); + CHIP_ERROR SetVendorId(uint16_t value); + CHIP_ERROR SetVendorName(const char * value, size_t len); + CHIP_ERROR SetProductId(uint16_t productId); + CHIP_ERROR SetProductName(const char * value, size_t len); + CHIP_ERROR SetProductLabel(const char * value, size_t len); + CHIP_ERROR SetProductURL(const char * value, size_t len); + CHIP_ERROR SetPartNumber(const char * value, size_t len); + CHIP_ERROR SetHardwareVersion(uint16_t value); + CHIP_ERROR SetHardwareVersionString(const char * value, size_t len); + CHIP_ERROR SetManufacturingDate(const char * value, size_t len); + CHIP_ERROR GetManufacturingDate(uint8_t * value, size_t max, size_t & size); + CHIP_ERROR SetUniqueId(const uint8_t * value, size_t size); + CHIP_ERROR GetUniqueId(uint8_t * value, size_t max, size_t & size); + // CommissionableDataProvider + CHIP_ERROR SetSetupDiscriminator(uint16_t value); + CHIP_ERROR SetSpake2pIterationCount(uint32_t value); + CHIP_ERROR SetSetupPasscode(uint32_t value); + CHIP_ERROR SetSpake2pSalt(const char * value, size_t size); + CHIP_ERROR GetSpake2pSalt(char * value, size_t max, size_t & size); + CHIP_ERROR SetSpake2pVerifier(const char * value, size_t size); + CHIP_ERROR GetSpake2pVerifier(char * value, size_t max, size_t & size); + // DeviceAttestationCredentialsProvider + CHIP_ERROR SetFirmwareInformation(const ByteSpan & value); + + // Other + CHIP_ERROR SetProvisionVersion(const char * value, size_t len); + CHIP_ERROR GetProvisionVersion(char * value, size_t max, size_t & size); + CHIP_ERROR SetSetupPayload(const uint8_t * value, size_t size); + CHIP_ERROR GetSetupPayload(uint8_t * value, size_t max, size_t & size); +#if OTA_ENCRYPTION_ENABLE + CHIP_ERROR SetOtaTlvEncryptionKey(const ByteSpan & value); +#endif + + uint16_t mVendorId = 0; + uint16_t mProductId = 0; + uint16_t mHwVersion = 0; + uint16_t mDiscriminator = 0; // 12-bit + uint32_t mCommissioningFlow = 0; + uint32_t mRendezvousFlags = 0; + uint32_t mPasscode = 0; + uint32_t mKeyId = 0; + char mCommonName[kCommonNameMax] = { 0 }; + CustomStorage mCustom; +}; + +} // namespace Provision +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/provision/ProvisionStorageGeneric.h b/src/platform/silabs/provision/ProvisionStorageGeneric.h new file mode 100644 index 00000000000000..6c3cdc2c42a39f --- /dev/null +++ b/src/platform/silabs/provision/ProvisionStorageGeneric.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 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 +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { + +struct GenericStorage +{ + virtual ~GenericStorage() = default; + + virtual CHIP_ERROR Set(uint16_t id, const uint8_t * value) = 0; + virtual CHIP_ERROR Get(uint16_t id, uint8_t & value) = 0; + virtual CHIP_ERROR Set(uint16_t id, const uint16_t * value) = 0; + virtual CHIP_ERROR Get(uint16_t id, uint16_t & value) = 0; + virtual CHIP_ERROR Set(uint16_t id, const uint32_t * value) = 0; + virtual CHIP_ERROR Get(uint16_t id, uint32_t & value) = 0; + virtual CHIP_ERROR Set(uint16_t id, const uint64_t * value) = 0; + virtual CHIP_ERROR Get(uint16_t id, uint64_t & value) = 0; + virtual CHIP_ERROR Get(uint16_t id, uint8_t * value, size_t max_size, size_t & size) = 0; + virtual CHIP_ERROR Set(uint16_t id, const uint8_t * value, size_t size) = 0; +}; + +} // namespace Provision +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/test_driver/efr32/BUILD.gn b/src/test_driver/efr32/BUILD.gn index ad0c1a22d270d3..947ed482f4622e 100644 --- a/src/test_driver/efr32/BUILD.gn +++ b/src/test_driver/efr32/BUILD.gn @@ -70,6 +70,8 @@ silabs_executable("efr32_device_tests") { "${chip_root}/examples/common/pigweed/RpcService.cpp", "${chip_root}/examples/common/pigweed/efr32/PigweedLoggerMutex.cpp", "${examples_common_plat_dir}/PigweedLogger.cpp", + "${examples_common_plat_dir}/provision/ProvisionStorageCustom.cpp", + "${examples_common_plat_dir}/provision/ProvisionStorageDefault.cpp", "${examples_common_plat_dir}/syscalls_stubs.cpp", "${examples_plat_dir}/uart.cpp", "src/main.cpp", @@ -84,6 +86,7 @@ silabs_executable("efr32_device_tests") { "${chip_root}/src:tests", "${chip_root}/src/lib", "${chip_root}/src/lib/support:pw_tests_wrapper", + "${chip_root}/src/platform/silabs/provision:provision-headers", "${examples_common_plat_dir}/pw_sys_io:pw_sys_io_silabs", ] @@ -96,16 +99,12 @@ silabs_executable("efr32_device_tests") { ] } - # Attestation Credentials - deps += [ "${examples_plat_dir}:efr32-attestation-credentials" ] - - # Factory Data Provider - if (use_efr32_factory_data_provider) { - deps += [ "${examples_plat_dir}:silabs-factory-data-provider" ] - } - deps += pw_build_LINK_DEPS + libs = [ + "${sdk_support_root}/matter/provision/lib/libProvision_${silabs_family}.a", + ] + include_dirs = [ "${chip_root}/examples/common/pigweed/efr32" ] ldscript = "${examples_common_plat_dir}/ldscripts/${silabs_family}.ld" diff --git a/src/test_driver/efr32/src/main.cpp b/src/test_driver/efr32/src/main.cpp index 010d6b4bc0639b..088dc4e8703664 100644 --- a/src/test_driver/efr32/src/main.cpp +++ b/src/test_driver/efr32/src/main.cpp @@ -22,9 +22,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -38,7 +38,8 @@ #include #include -#include "SilabsDeviceDataProvider.h" +using namespace chip; +using namespace chip::DeviceLayer; extern "C" int printf(const char * format, ...) { @@ -91,16 +92,18 @@ void RunRpcService(void *) int main(void) { sl_system_init(); - chip::DeviceLayer::Silabs::GetPlatform().Init(); + Silabs::GetPlatform().Init(); PigweedLogger::init(); mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree); - chip::Platform::MemoryInit(); + Platform::MemoryInit(); + PlatformMgr().InitChipStack(); - chip::DeviceLayer::PlatformMgr().InitChipStack(); - // required for inits tied to the event loop - chip::DeviceLayer::SetDeviceInstanceInfoProvider(&chip::DeviceLayer::Silabs::SilabsDeviceDataProvider::GetDeviceDataProvider()); - chip::DeviceLayer::SetCommissionableDataProvider(&chip::DeviceLayer::Silabs::SilabsDeviceDataProvider::GetDeviceDataProvider()); + // Init Provision Manager and provider instanaces. Required for inits tied to the event loop + Silabs::Provision::Manager & provision = Silabs::Provision::Manager::GetInstance(); + provision.Init(); + SetDeviceInstanceInfoProvider(&provision.GetStorage()); + SetCommissionableDataProvider(&provision.GetStorage()); SILABS_LOG("***** CHIP EFR32 device tests *****\r\n"); diff --git a/third_party/silabs/SiWx917_sdk.gni b/third_party/silabs/SiWx917_sdk.gni index 2862f9bc9d09f6..ddda1e68b7f4b7 100644 --- a/third_party/silabs/SiWx917_sdk.gni +++ b/third_party/silabs/SiWx917_sdk.gni @@ -491,6 +491,7 @@ template("siwx917_sdk") { "${chip_root}/third_party/mbedtls/repo/library/aes.c", "${chip_root}/third_party/mbedtls/repo/library/asn1parse.c", "${chip_root}/third_party/mbedtls/repo/library/asn1write.c", + "${chip_root}/third_party/mbedtls/repo/library/base64.c", "${chip_root}/third_party/mbedtls/repo/library/bignum.c", "${chip_root}/third_party/mbedtls/repo/library/ccm.c", "${chip_root}/third_party/mbedtls/repo/library/cipher.c", @@ -505,10 +506,12 @@ template("siwx917_sdk") { "${chip_root}/third_party/mbedtls/repo/library/hkdf.c", "${chip_root}/third_party/mbedtls/repo/library/hmac_drbg.c", "${chip_root}/third_party/mbedtls/repo/library/md.c", + "${chip_root}/third_party/mbedtls/repo/library/pem.c", "${chip_root}/third_party/mbedtls/repo/library/pkcs5.c", "${chip_root}/third_party/mbedtls/repo/library/platform.c", "${chip_root}/third_party/mbedtls/repo/library/sha256.c", "${chip_root}/third_party/mbedtls/repo/library/sha512.c", + "${chip_root}/third_party/mbedtls/repo/library/x509.c", "${chip_root}/third_party/mbedtls/repo/library/x509_create.c", "${efr32_sdk_root}/platform/service/iostream/src/sl_iostream.c", "${efr32_sdk_root}/platform/service/iostream/src/sl_iostream_rtt.c", @@ -588,10 +591,8 @@ template("siwx917_sdk") { } if (invoker.enable_dic) { sources += [ - "${chip_root}/third_party/mbedtls/repo/library/base64.c", "${chip_root}/third_party/mbedtls/repo/library/debug.c", "${chip_root}/third_party/mbedtls/repo/library/ecjpake.c", - "${chip_root}/third_party/mbedtls/repo/library/pem.c", "${chip_root}/third_party/mbedtls/repo/library/rsa.c", "${chip_root}/third_party/mbedtls/repo/library/rsa_internal.c", "${chip_root}/third_party/mbedtls/repo/library/sha1.c", @@ -600,14 +601,10 @@ template("siwx917_sdk") { "${chip_root}/third_party/mbedtls/repo/library/ssl_msg.c", "${chip_root}/third_party/mbedtls/repo/library/ssl_srv.c", "${chip_root}/third_party/mbedtls/repo/library/ssl_tls.c", - "${chip_root}/third_party/mbedtls/repo/library/x509.c", "${chip_root}/third_party/silabs/mqtt/stack/mqtt.c", ] } - public_configs = [ - ":${sdk_target_name}_config", - "${examples_plat_dir}:siwx917-common-config", - ] + public_configs = [ ":${sdk_target_name}_config" ] } } diff --git a/third_party/silabs/matter_support b/third_party/silabs/matter_support index a1fdd62cb16804..96fc0a37ecb2e6 160000 --- a/third_party/silabs/matter_support +++ b/third_party/silabs/matter_support @@ -1 +1 @@ -Subproject commit a1fdd62cb168049f946f7e1b5399c39353bcd7b4 +Subproject commit 96fc0a37ecb2e6791f57d62d5619db65d870ae4a From ee49ebdd86669429aa68a8fb5b5c9b756928b9cc Mon Sep 17 00:00:00 2001 From: Maksymilian Knust Date: Thu, 27 Jun 2024 08:54:53 +0200 Subject: [PATCH 15/21] Unify stdio logging (#34070) * Unify stdio logging Darwin now uses the same stdio logging implementation as other platforms. Logs are colorized and contain timestamps. On linux and darwin, pid and tid are also logged. * Darwin formatting * Fix cirque test driver * Log seconds and milliseconds * Update Logging.cpp --- src/platform/logging/BUILD.gn | 6 +- src/platform/logging/impl/stdio/Logging.cpp | 52 +++++++++++++- .../logging/impl/stdio/darwin/Logging.cpp | 72 ------------------- .../linux-cirque/helper/CHIPTestBase.py | 2 +- 4 files changed, 52 insertions(+), 80 deletions(-) delete mode 100644 src/platform/logging/impl/stdio/darwin/Logging.cpp diff --git a/src/platform/logging/BUILD.gn b/src/platform/logging/BUILD.gn index 6b914cab7357d2..632c4ee5353224 100644 --- a/src/platform/logging/BUILD.gn +++ b/src/platform/logging/BUILD.gn @@ -109,11 +109,7 @@ if (current_os == "android") { stdio_archive = "$root_out_dir/liblogging-stdio.a" source_set("stdio") { - if (chip_device_platform == "darwin") { - sources = [ "impl/stdio/darwin/Logging.cpp" ] - } else { - sources = [ "impl/stdio/Logging.cpp" ] - } + sources = [ "impl/stdio/Logging.cpp" ] deps = [ ":headers", diff --git a/src/platform/logging/impl/stdio/Logging.cpp b/src/platform/logging/impl/stdio/Logging.cpp index c403c29b913293..26e050f0286f9f 100644 --- a/src/platform/logging/impl/stdio/Logging.cpp +++ b/src/platform/logging/impl/stdio/Logging.cpp @@ -4,17 +4,65 @@ #include +#include #include +#include + +#if defined(__APPLE__) +#include +#include +#elif defined(__gnu_linux__) +#include +#include +#endif namespace chip { namespace Logging { namespace Platform { +// TODO: investigate whether pw_chrono or pw_log could be used here void LogV(const char * module, uint8_t category, const char * msg, va_list v) { - printf("CHIP:%s: ", module); + // Stdout needs to be locked, because it's printed in pieces +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) + flockfile(stdout); +#endif + + switch (category) + { + case kLogCategory_Error: + printf("\033[1;31m"); + break; + case kLogCategory_Progress: + printf("\033[0;32m"); + break; + case kLogCategory_Detail: + printf("\033[0;34m"); + break; + } + +#if defined(__APPLE__) || defined(__gnu_linux__) + timespec ts; + timespec_get(&ts, TIME_UTC); + printf("[%lld.%03ld] ", static_cast(ts.tv_sec), static_cast(ts.tv_nsec / 1000000)); +#endif + +#if defined(__APPLE__) + uint64_t ktid; + pthread_threadid_np(nullptr, &ktid); + printf("[%lld:%lld] ", static_cast(getpid()), static_cast(ktid)); +#elif defined(__gnu_linux__) && !defined(__NuttX__) + // TODO: change to getpid() and gettid() after glib upgrade + printf("[%lld:%lld] ", static_cast(syscall(SYS_getpid)), static_cast(syscall(SYS_gettid))); +#endif + + printf("[%s] ", module); vprintf(msg, v); - printf("\n"); + printf("\033[0m\n"); + +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) + funlockfile(stdout); +#endif } } // namespace Platform diff --git a/src/platform/logging/impl/stdio/darwin/Logging.cpp b/src/platform/logging/impl/stdio/darwin/Logging.cpp deleted file mode 100644 index 49c58eea1d7bba..00000000000000 --- a/src/platform/logging/impl/stdio/darwin/Logging.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * Copyright (c) 2022 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. - */ - -#include - -#include -#include -#include -#include -#include -#include - -namespace chip { -namespace Logging { -namespace Platform { - -void LogV(const char * module, uint8_t category, const char * msg, va_list v) -{ - timeval time; - gettimeofday(&time, nullptr); - long ms = (time.tv_sec * 1000) + (time.tv_usec / 1000); - - uint64_t ktid; - pthread_threadid_np(nullptr, &ktid); - - char formattedMsg[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE]; - int32_t prefixLen = - snprintf(formattedMsg, sizeof(formattedMsg), "[%ld] [%lld:%lld] [%s] ", ms, (long long) getpid(), (long long) ktid, module); - if (prefixLen < 0) - { - // This should not happen - return; - } - - if (static_cast(prefixLen) >= sizeof(formattedMsg)) - { - prefixLen = sizeof(formattedMsg) - 1; - } - - vsnprintf(formattedMsg + prefixLen, sizeof(formattedMsg) - static_cast(prefixLen), msg, v); - - switch (category) - { - case kLogCategory_Error: - printf("\033[1;31m%s\033[0m\n", formattedMsg); - break; - case kLogCategory_Progress: - printf("\033[0;32m%s\033[0m\n", formattedMsg); - break; - case kLogCategory_Detail: - printf("\033[0;34m%s\033[0m\n", formattedMsg); - break; - } -} - -} // namespace Platform -} // namespace Logging -} // namespace chip diff --git a/src/test_driver/linux-cirque/helper/CHIPTestBase.py b/src/test_driver/linux-cirque/helper/CHIPTestBase.py index 7fd0c81e86f3ca..ea45a62221e7e5 100644 --- a/src/test_driver/linux-cirque/helper/CHIPTestBase.py +++ b/src/test_driver/linux-cirque/helper/CHIPTestBase.py @@ -145,7 +145,7 @@ def reset_thread_devices(self, devices: Union[List[str], str]): self.assertTrue(self.wait_for_device_output( device_id, "Thread Border Router started on AIL", 10)) self.assertTrue(self.wait_for_device_output( - device_id, "CHIP:SVR: Server Listening...", 15)) + device_id, "[SVR] Server Listening...", 15)) # Clear default Thread network commissioning data self.logger.info("Resetting thread network on {}".format( self.get_device_pretty_id(device_id))) From b274320c5d4126b80136881660ae806b58e3b567 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Thu, 27 Jun 2024 13:22:16 +0200 Subject: [PATCH 16/21] Build ESP32 QEMU from correct ESP branch (#34109) --- integrations/docker/images/base/chip-build/version | 2 +- .../docker/images/stage-3/chip-build-esp32-qemu/Dockerfile | 2 +- src/test_driver/esp32/run_qemu_image.py | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index 9e5191f95a822d..d9a04eb8c7a142 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -61 : Update env variable in vscode image +62 : Fix ESP32 qemu build diff --git a/integrations/docker/images/stage-3/chip-build-esp32-qemu/Dockerfile b/integrations/docker/images/stage-3/chip-build-esp32-qemu/Dockerfile index 0eb76b44a3cbc0..12aa3cdb554ce0 100644 --- a/integrations/docker/images/stage-3/chip-build-esp32-qemu/Dockerfile +++ b/integrations/docker/images/stage-3/chip-build-esp32-qemu/Dockerfile @@ -13,7 +13,7 @@ RUN set -x \ WORKDIR /opt/espressif/qemu # Setup QEMU emulator for ESP32 platform RUN set -x \ - && git clone --depth 1 -b v9.0.0 https://github.com/espressif/qemu.git ../qemu-src \ + && git clone --depth 1 -b esp-develop-9.0.0-20240606 https://github.com/espressif/qemu.git ../qemu-src \ && ../qemu-src/configure --target-list=xtensa-softmmu --enable-debug --disable-strip --disable-user --disable-capstone --disable-vnc --disable-sdl --disable-gtk \ && make -j$(nproc) \ && : # last line diff --git a/src/test_driver/esp32/run_qemu_image.py b/src/test_driver/esp32/run_qemu_image.py index 90e06191b121ea..5c7238aae7bd2a 100755 --- a/src/test_driver/esp32/run_qemu_image.py +++ b/src/test_driver/esp32/run_qemu_image.py @@ -150,6 +150,7 @@ def main(log_level, no_log_timestamps, image, file_image_list, qemu, verbose): # make sure output is visible in stdout print("========== TEST OUTPUT BEGIN ============") print(output) + print(status.stderr.decode('ascii')) print("========== TEST OUTPUT END ============") raise From 720c834b82f63301f0aa6081f86e84a181a5ed64 Mon Sep 17 00:00:00 2001 From: cdj <45139296+DejinChen@users.noreply.github.com> Date: Thu, 27 Jun 2024 20:27:56 +0800 Subject: [PATCH 17/21] OpenThread: added Thread interface enabled support (#33860) * OpenThread: added Thread interface enabled support * Added Thread autostart configuration and check for Thread interface * Update comments for RevertConfiguration * Fix CI * Fix CI --- src/include/platform/CHIPDeviceConfig.h | 9 ++++ ...enericNetworkCommissioningThreadDriver.cpp | 54 +++++++++++++++++++ .../GenericNetworkCommissioningThreadDriver.h | 4 ++ ...nericThreadStackManagerImpl_OpenThread.hpp | 2 + 4 files changed, 69 insertions(+) diff --git a/src/include/platform/CHIPDeviceConfig.h b/src/include/platform/CHIPDeviceConfig.h index 785b47656dd5a3..49a94d75c23fcc 100644 --- a/src/include/platform/CHIPDeviceConfig.h +++ b/src/include/platform/CHIPDeviceConfig.h @@ -1101,6 +1101,15 @@ static_assert(CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_MIN <= CHIP_DEVICE #define CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT 0 #endif +/** + * CHIP_DEVICE_CONFIG_ENABLE_THREAD_AUTOSTART + * + * Enable starting provisioned Thread network automatically after device power-up. + */ +#ifndef CHIP_DEVICE_CONFIG_ENABLE_THREAD_AUTOSTART +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_AUTOSTART 1 +#endif + // -------------------- Network Telemetry Configuration -------------------- /** diff --git a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp index 0a961a9f8e4afa..711ad4930f96d4 100644 --- a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp +++ b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp @@ -54,6 +54,8 @@ CHIP_ERROR GenericThreadDriver::Init(Internal::BaseDriver::NetworkStatusChangeCa // must be restored on the boot. If there's no backup, the below function is a no-op. RevertConfiguration(); + CheckInterfaceEnabled(); + return CHIP_NO_ERROR; } @@ -95,6 +97,16 @@ CHIP_ERROR GenericThreadDriver::RevertConfiguration() // since the fail-safe was armed, so return with no error. ReturnErrorCodeIf(error == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR); + if (!GetEnabled()) + { + // When reverting configuration, set InterfaceEnabled to default value (true). + // From the spec: + // If InterfaceEnabled is written to false on the same interface as that which is used to write the value, the Administrator + // could await the recovery of network configuration to prior safe values, before being able to communicate with the + // node again. + ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Delete(kInterfaceEnabled)); + } + ChipLogProgress(NetworkProvisioning, "Reverting Thread operational dataset"); if (error == CHIP_NO_ERROR) @@ -166,6 +178,12 @@ void GenericThreadDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * c { NetworkCommissioning::Status status = MatchesNetworkId(mStagingNetwork, networkId); + if (!GetEnabled()) + { + // Set InterfaceEnabled to default value (true). + ReturnOnFailure(PersistedStorage::KeyValueStoreMgr().Delete(kInterfaceEnabled)); + } + if (status == Status::kSuccess && BackupConfiguration() != CHIP_NO_ERROR) { status = Status::kUnknownError; @@ -183,6 +201,30 @@ void GenericThreadDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * c } } +CHIP_ERROR GenericThreadDriver::SetEnabled(bool enabled) +{ + if (enabled == GetEnabled()) + { + return CHIP_NO_ERROR; + } + + ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kInterfaceEnabled, &enabled, sizeof(enabled))); + + if ((!enabled && ThreadStackMgrImpl().IsThreadEnabled()) || (enabled && ThreadStackMgrImpl().IsThreadProvisioned())) + { + ReturnErrorOnFailure(ThreadStackMgrImpl().SetThreadEnabled(enabled)); + } + return CHIP_NO_ERROR; +} + +bool GenericThreadDriver::GetEnabled() +{ + bool value; + // InterfaceEnabled default value is true. + VerifyOrReturnValue(PersistedStorage::KeyValueStoreMgr().Get(kInterfaceEnabled, &value, sizeof(value)) == CHIP_NO_ERROR, true); + return value; +} + void GenericThreadDriver::ScanNetworks(ThreadDriver::ScanCallback * callback) { if (DeviceLayer::ThreadStackMgrImpl().StartThreadScan(callback) != CHIP_NO_ERROR) @@ -223,6 +265,18 @@ CHIP_ERROR GenericThreadDriver::BackupConfiguration() return KeyValueStoreMgr().Put(DefaultStorageKeyAllocator::FailSafeNetworkConfig().KeyName(), dataset.data(), dataset.size()); } +void GenericThreadDriver::CheckInterfaceEnabled() +{ +#if !CHIP_DEVICE_CONFIG_ENABLE_THREAD_AUTOSTART + // If the Thread interface is enabled and stack has been provisioned, but is not currently enabled, enable it now. + if (GetEnabled() && ThreadStackMgrImpl().IsThreadProvisioned() && !ThreadStackMgrImpl().IsThreadEnabled()) + { + ReturnOnFailure(ThreadStackMgrImpl().SetThreadEnabled(true)); + ChipLogProgress(DeviceLayer, "OpenThread ifconfig up and thread start"); + } +#endif +} + size_t GenericThreadDriver::ThreadNetworkIterator::Count() { return driver->mStagingNetwork.IsCommissioned() ? 1 : 0; diff --git a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.h b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.h index 28dc8f176ddd1f..7fd62159a36522 100644 --- a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.h +++ b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.h @@ -90,6 +90,8 @@ class GenericThreadDriver final : public ThreadDriver // BaseDriver NetworkIterator * GetNetworks() override { return new ThreadNetworkIterator(this); } CHIP_ERROR Init(Internal::BaseDriver::NetworkStatusChangeCallback * statusChangeCallback) override; + CHIP_ERROR SetEnabled(bool enabled) override; + bool GetEnabled() override; void Shutdown() override; // WirelessDriver @@ -114,11 +116,13 @@ class GenericThreadDriver final : public ThreadDriver void ScanNetworks(ThreadDriver::ScanCallback * callback) override; private: + static constexpr const char * kInterfaceEnabled = "g/gtd/en"; uint8_t scanNetworkTimeoutSeconds; uint8_t connectNetworkTimeout; static void OnThreadStateChangeHandler(const ChipDeviceEvent * event, intptr_t arg); Status MatchesNetworkId(const Thread::OperationalDataset & dataset, const ByteSpan & networkId) const; CHIP_ERROR BackupConfiguration(); + void CheckInterfaceEnabled(); ThreadNetworkIterator mThreadIterator = ThreadNetworkIterator(this); Thread::OperationalDataset mStagingNetwork = {}; diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp index 9079e5455db620..876cb54385efe6 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp @@ -1131,6 +1131,7 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::DoInit(otInstanc memset(&mSrpClient, 0, sizeof(mSrpClient)); #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_AUTOSTART // If the Thread stack has been provisioned, but is not currently enabled, enable it now. if (otThreadGetDeviceRole(mOTInst) == OT_DEVICE_ROLE_DISABLED && otDatasetIsCommissioned(otInst)) { @@ -1143,6 +1144,7 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::DoInit(otInstanc ChipLogProgress(DeviceLayer, "OpenThread ifconfig up and thread start"); } +#endif initNetworkCommissioningThreadDriver(); From d71a36364c2c7ba6c6792212b1b3f5ac6f6916d9 Mon Sep 17 00:00:00 2001 From: cdj <45139296+DejinChen@users.noreply.github.com> Date: Thu, 27 Jun 2024 20:54:58 +0800 Subject: [PATCH 18/21] Auto-commissioner: support secondary network interface commissioning (#33801) * Auto-commissioner: support secondary network interface commissioning * Fix code-wifi-thread command and reset trying secondary network flag * Revert server-side changes * Added write request cancel function --- .../chip-tool/commands/pairing/Commands.h | 9 +++ .../commands/pairing/PairingCommand.cpp | 4 ++ .../commands/pairing/PairingCommand.h | 6 ++ src/controller/AutoCommissioner.cpp | 59 +++++++++++-------- src/controller/AutoCommissioner.h | 16 +++++ src/controller/CHIPDeviceController.cpp | 47 +++++++++++++++ src/controller/CHIPDeviceController.h | 7 +++ src/controller/CommissioningDelegate.cpp | 6 ++ src/controller/CommissioningDelegate.h | 3 + src/controller/WriteInteraction.h | 18 +++++- 10 files changed, 151 insertions(+), 24 deletions(-) diff --git a/examples/chip-tool/commands/pairing/Commands.h b/examples/chip-tool/commands/pairing/Commands.h index 388dc4741ffe30..41a35bb6bae6ad 100644 --- a/examples/chip-tool/commands/pairing/Commands.h +++ b/examples/chip-tool/commands/pairing/Commands.h @@ -69,6 +69,14 @@ class PairCodeThread : public PairingCommand {} }; +class PairCodeWiFiThread : public PairingCommand +{ +public: + PairCodeWiFiThread(CredentialIssuerCommands * credsIssuerConfig) : + PairingCommand("code-wifi-thread", PairingMode::Code, PairingNetworkType::WiFiOrThread, credsIssuerConfig) + {} +}; + class PairOnNetwork : public PairingCommand { public: @@ -231,6 +239,7 @@ void registerCommandsPairing(Commands & commands, CredentialIssuerCommands * cre make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), + make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), diff --git a/examples/chip-tool/commands/pairing/PairingCommand.cpp b/examples/chip-tool/commands/pairing/PairingCommand.cpp index 76c8ac8a58cc19..a0437c53f56a7d 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.cpp +++ b/examples/chip-tool/commands/pairing/PairingCommand.cpp @@ -111,6 +111,10 @@ CommissioningParameters PairingCommand::GetCommissioningParameters() case PairingNetworkType::Thread: params.SetThreadOperationalDataset(mOperationalDataset); break; + case PairingNetworkType::WiFiOrThread: + params.SetWiFiCredentials(Controller::WiFiCredentials(mSSID, mPassword)); + params.SetThreadOperationalDataset(mOperationalDataset); + break; case PairingNetworkType::None: break; } diff --git a/examples/chip-tool/commands/pairing/PairingCommand.h b/examples/chip-tool/commands/pairing/PairingCommand.h index aaa8dc714e1017..9ff63e37878576 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.h +++ b/examples/chip-tool/commands/pairing/PairingCommand.h @@ -44,6 +44,7 @@ enum class PairingNetworkType None, WiFi, Thread, + WiFiOrThread, }; class PairingCommand : public CHIPCommand, @@ -85,6 +86,11 @@ class PairingCommand : public CHIPCommand, case PairingNetworkType::Thread: AddArgument("operationalDataset", &mOperationalDataset); break; + case PairingNetworkType::WiFiOrThread: + AddArgument("ssid", &mSSID); + AddArgument("password", &mPassword); + AddArgument("operationalDataset", &mOperationalDataset); + break; } switch (mode) diff --git a/src/controller/AutoCommissioner.cpp b/src/controller/AutoCommissioner.cpp index a72543853fa2d1..d6bc9f5c79fcac 100644 --- a/src/controller/AutoCommissioner.cpp +++ b/src/controller/AutoCommissioner.cpp @@ -298,6 +298,19 @@ CommissioningStage AutoCommissioner::GetNextCommissioningStage(CommissioningStag CommissioningStage AutoCommissioner::GetNextCommissioningStageNetworkSetup(CommissioningStage currentStage, CHIP_ERROR & lastErr) { + if (IsSecondaryNetworkSupported()) + { + if (TryingSecondaryNetwork()) + { + // Try secondary network interface. + return mDeviceCommissioningInfo.network.wifi.endpoint == kRootEndpointId ? CommissioningStage::kThreadNetworkSetup + : CommissioningStage::kWiFiNetworkSetup; + } + // Try primary network interface + return mDeviceCommissioningInfo.network.wifi.endpoint == kRootEndpointId ? CommissioningStage::kWiFiNetworkSetup + : CommissioningStage::kThreadNetworkSetup; + } + if (mParams.GetWiFiCredentials().HasValue() && mDeviceCommissioningInfo.network.wifi.endpoint != kInvalidEndpointId) { return CommissioningStage::kWiFiNetworkSetup; @@ -455,35 +468,15 @@ CommissioningStage AutoCommissioner::GetNextCommissioningStageInternal(Commissio case CommissioningStage::kNeedsNetworkCreds: return GetNextCommissioningStageNetworkSetup(currentStage, lastErr); case CommissioningStage::kWiFiNetworkSetup: - if (mParams.GetThreadOperationalDataset().HasValue() && - mDeviceCommissioningInfo.network.thread.endpoint != kInvalidEndpointId) - { - return CommissioningStage::kThreadNetworkSetup; - } - else - { - return CommissioningStage::kFailsafeBeforeWiFiEnable; - } + return CommissioningStage::kFailsafeBeforeWiFiEnable; case CommissioningStage::kThreadNetworkSetup: - if (mParams.GetWiFiCredentials().HasValue() && mDeviceCommissioningInfo.network.wifi.endpoint != kInvalidEndpointId) - { - return CommissioningStage::kFailsafeBeforeWiFiEnable; - } - else - { - return CommissioningStage::kFailsafeBeforeThreadEnable; - } + return CommissioningStage::kFailsafeBeforeThreadEnable; case CommissioningStage::kFailsafeBeforeWiFiEnable: return CommissioningStage::kWiFiNetworkEnable; case CommissioningStage::kFailsafeBeforeThreadEnable: return CommissioningStage::kThreadNetworkEnable; case CommissioningStage::kWiFiNetworkEnable: - if (mParams.GetThreadOperationalDataset().HasValue() && - mDeviceCommissioningInfo.network.thread.endpoint != kInvalidEndpointId) - { - return CommissioningStage::kThreadNetworkEnable; - } - else if (mParams.GetSkipCommissioningComplete().ValueOr(false)) + if (mParams.GetSkipCommissioningComplete().ValueOr(false)) { SetCASEFailsafeTimerIfNeeded(); return CommissioningStage::kCleanup; @@ -502,6 +495,10 @@ CommissioningStage AutoCommissioner::GetNextCommissioningStageInternal(Commissio return CommissioningStage::kEvictPreviousCaseSessions; case CommissioningStage::kEvictPreviousCaseSessions: return CommissioningStage::kFindOperationalForStayActive; + case CommissioningStage::kPrimaryOperationalNetworkFailed: + return CommissioningStage::kDisablePrimaryNetworkInterface; + case CommissioningStage::kDisablePrimaryNetworkInterface: + return GetNextCommissioningStageNetworkSetup(currentStage, lastErr); case CommissioningStage::kFindOperationalForStayActive: return CommissioningStage::kICDSendStayActive; case CommissioningStage::kICDSendStayActive: @@ -564,6 +561,8 @@ EndpointId AutoCommissioner::GetEndpoint(const CommissioningStage & stage) const case CommissioningStage::kThreadNetworkSetup: case CommissioningStage::kThreadNetworkEnable: return mDeviceCommissioningInfo.network.thread.endpoint; + case CommissioningStage::kDisablePrimaryNetworkInterface: + return kRootEndpointId; default: return kRootEndpointId; } @@ -729,6 +728,16 @@ CHIP_ERROR AutoCommissioner::CommissioningStepFinished(CHIP_ERROR err, Commissio report.stageCompleted = CommissioningStage::kScanNetworks; } } + + if (err != CHIP_NO_ERROR && IsSecondaryNetworkSupported() && !TryingSecondaryNetwork() && + completionStatus.failedStage.HasValue() && completionStatus.failedStage.Value() >= kWiFiNetworkSetup && + completionStatus.failedStage.Value() <= kICDSendStayActive) + { + // Primary network failed, disable primary network interface and try secondary network interface. + TrySecondaryNetwork(); + err = CHIP_NO_ERROR; + report.stageCompleted = CommissioningStage::kPrimaryOperationalNetworkFailed; + } } else { @@ -847,6 +856,10 @@ CHIP_ERROR AutoCommissioner::CommissioningStepFinished(CHIP_ERROR err, Commissio mOperationalDeviceProxy = report.Get().operationalProxy; break; case CommissioningStage::kCleanup: + if (IsSecondaryNetworkSupported() && TryingSecondaryNetwork()) + { + ResetTryingSecondaryNetwork(); + } ReleasePAI(); ReleaseDAC(); mCommissioneeDeviceProxy = nullptr; diff --git a/src/controller/AutoCommissioner.h b/src/controller/AutoCommissioner.h index 3399e2776946de..deacda6e3cca31 100644 --- a/src/controller/AutoCommissioner.h +++ b/src/controller/AutoCommissioner.h @@ -94,6 +94,22 @@ class AutoCommissioner : public CommissioningDelegate mDeviceCommissioningInfo.network.thread.endpoint != kInvalidEndpointId)); }; + // Helper function to Determine whether secondary network interface is supported. + // Only true if information is provided for both networks, and the target has endpoint + // for wifi and thread. + bool IsSecondaryNetworkSupported() const + { + return ((mParams.GetSupportsConcurrentConnection().ValueOr(false) && mParams.GetWiFiCredentials().HasValue() && + mDeviceCommissioningInfo.network.wifi.endpoint != kInvalidEndpointId) && + mParams.GetThreadOperationalDataset().HasValue() && + mDeviceCommissioningInfo.network.thread.endpoint != kInvalidEndpointId); + } + + void TrySecondaryNetwork() { mTryingSecondaryNetwork = true; } + bool TryingSecondaryNetwork() const { return mTryingSecondaryNetwork; } + void ResetTryingSecondaryNetwork() { mTryingSecondaryNetwork = false; } + bool mTryingSecondaryNetwork = false; + bool mStopCommissioning = false; DeviceCommissioner * mCommissioner = nullptr; diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 21cd71e2932b0a..444b48bcf12b49 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -1028,6 +1029,12 @@ void DeviceCommissioner::CancelCommissioningInteractions() mInvokeCancelFn(); mInvokeCancelFn = nullptr; } + if (mWriteCancelFn) + { + ChipLogDetail(Controller, "Cancelling write request for step '%s'", StageToString(mCommissioningStage)); + mWriteCancelFn(); + mWriteCancelFn = nullptr; + } if (mOnDeviceConnectedCallback.IsRegistered()) { ChipLogDetail(Controller, "Cancelling CASE setup for step '%s'", StageToString(mCommissioningStage)); @@ -1800,6 +1807,12 @@ void DeviceCommissioner::OnBasicSuccess(void * context, const chip::app::DataMod commissioner->CommissioningStageComplete(CHIP_NO_ERROR); } +void DeviceCommissioner::OnInterfaceEnableWriteSuccessResponse(void * context) +{ + DeviceCommissioner * commissioner = static_cast(context); + commissioner->CommissioningStageComplete(CHIP_NO_ERROR); +} + void DeviceCommissioner::OnBasicFailure(void * context, CHIP_ERROR error) { ChipLogProgress(Controller, "Received failure response %s\n", chip::ErrorStr(error)); @@ -1971,6 +1984,7 @@ void DeviceCommissioner::CommissioningStageComplete(CHIP_ERROR err, Commissionin DeviceProxy * proxy = mDeviceBeingCommissioned; mDeviceBeingCommissioned = nullptr; mInvokeCancelFn = nullptr; + mWriteCancelFn = nullptr; if (mPairingDelegate != nullptr) { @@ -2739,6 +2753,20 @@ DeviceCommissioner::SendCommissioningCommand(DeviceProxy * device, const Request onFailureCb, NullOptional, timeout, (!fireAndForget) ? &mInvokeCancelFn : nullptr); } +template +CHIP_ERROR DeviceCommissioner::SendCommissioningWriteRequest(DeviceProxy * device, EndpointId endpoint, ClusterId cluster, + AttributeId attribute, const AttrType & requestData, + WriteResponseSuccessCallback successCb, + WriteResponseFailureCallback failureCb) +{ + VerifyOrDie(!mWriteCancelFn); // we don't make parallel (cancellable) calls + auto onSuccessCb = [this, successCb](const app::ConcreteAttributePath & aPath) { successCb(this); }; + auto onFailureCb = [this, failureCb](const app::ConcreteAttributePath * aPath, CHIP_ERROR aError) { failureCb(this, aError); }; + return WriteAttribute(device->GetSecureSession().Value(), endpoint, cluster, attribute, requestData, onSuccessCb, onFailureCb, + /* aTimedWriteTimeoutMs = */ NullOptional, /* onDoneCb = */ nullptr, /* aDataVersion = */ NullOptional, + /* outCancelFn = */ &mWriteCancelFn); +} + void DeviceCommissioner::SendCommissioningReadRequest(DeviceProxy * proxy, Optional timeout, app::AttributePathParams * readPaths, size_t readPathsSize) { @@ -3423,6 +3451,25 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio ); } break; + case CommissioningStage::kPrimaryOperationalNetworkFailed: { + // nothing to do. This stage indicates that the primary operational network failed and the network interface should be + // disabled later. + break; + } + case CommissioningStage::kDisablePrimaryNetworkInterface: { + NetworkCommissioning::Attributes::InterfaceEnabled::TypeInfo::Type request = false; + CHIP_ERROR err = SendCommissioningWriteRequest(proxy, endpoint, NetworkCommissioning::Id, + NetworkCommissioning::Attributes::InterfaceEnabled::Id, request, + OnInterfaceEnableWriteSuccessResponse, OnBasicFailure); + if (err != CHIP_NO_ERROR) + { + // We won't get any async callbacks here, so just complete our stage. + ChipLogError(Controller, "Failed to send InterfaceEnabled write request: %" CHIP_ERROR_FORMAT, err.Format()); + CommissioningStageComplete(err); + return; + } + break; + } case CommissioningStage::kICDSendStayActive: { if (!(params.GetICDStayActiveDurationMsec().HasValue())) { diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index e08c6483710ed2..1ab85ca0dc182b 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -830,6 +830,7 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, CommissioningStage mCommissioningStage = CommissioningStage::kSecurePairing; bool mRunCommissioningAfterConnection = false; Internal::InvokeCancelFn mInvokeCancelFn; + Internal::WriteCancelFn mWriteCancelFn; ObjectPool mCommissioneeDevicePool; @@ -973,6 +974,8 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, OnICDManagementStayActiveResponse(void * context, const app::Clusters::IcdManagement::Commands::StayActiveResponse::DecodableType & data); + static void OnInterfaceEnableWriteSuccessResponse(void * context); + /** * @brief * This function processes the CSR sent by the device. @@ -1025,6 +1028,10 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, Optional timeout = NullOptional, bool fireAndForget = false); void SendCommissioningReadRequest(DeviceProxy * proxy, Optional timeout, app::AttributePathParams * readPaths, size_t readPathsSize); + template + CHIP_ERROR SendCommissioningWriteRequest(DeviceProxy * device, EndpointId endpoint, ClusterId cluster, AttributeId attribute, + const AttrType & requestData, WriteResponseSuccessCallback successCb, + WriteResponseFailureCallback failureCb); void CancelCommissioningInteractions(); void CancelCASECallbacks(); diff --git a/src/controller/CommissioningDelegate.cpp b/src/controller/CommissioningDelegate.cpp index 30f469932a800a..85ea5e86c5e3a6 100644 --- a/src/controller/CommissioningDelegate.cpp +++ b/src/controller/CommissioningDelegate.cpp @@ -136,6 +136,12 @@ const char * StageToString(CommissioningStage stage) case kNeedsNetworkCreds: return "NeedsNetworkCreds"; + case kPrimaryOperationalNetworkFailed: + return "PrimaryOperationalNetworkFailed"; + + case kDisablePrimaryNetworkInterface: + return "DisablePrimaryNetworkInterface"; + default: return "???"; } diff --git a/src/controller/CommissioningDelegate.h b/src/controller/CommissioningDelegate.h index 57d6a0c9a8da53..99f00f109d4ff0 100644 --- a/src/controller/CommissioningDelegate.h +++ b/src/controller/CommissioningDelegate.h @@ -79,6 +79,9 @@ enum CommissioningStage : uint8_t /// Call CHIPDeviceController::NetworkCredentialsReady() when CommissioningParameters is populated with /// network credentials to use in kWiFiNetworkSetup or kThreadNetworkSetup steps. kNeedsNetworkCreds, + kPrimaryOperationalNetworkFailed, ///< Indicate that the primary operational network (on root endpoint) failed, should disable + ///< the primary network interface later. + kDisablePrimaryNetworkInterface, ///< Send InterfaceEnabled write request to the device to disable network interface. }; enum class ICDRegistrationStrategy : uint8_t diff --git a/src/controller/WriteInteraction.h b/src/controller/WriteInteraction.h index 19e383d738efe8..de95e45f6c100c 100644 --- a/src/controller/WriteInteraction.h +++ b/src/controller/WriteInteraction.h @@ -23,11 +23,17 @@ #include #include #include +#include #include namespace chip { namespace Controller { +namespace Internal { +// WriteCancelFn functions on WriteAttribute() are for internal use only. +typedef std::function WriteCancelFn; +} // namespace Internal + /* * An adapter callback that permits applications to provide std::function callbacks for success, error and on done. * This permits a slightly more flexible programming model that allows applications to pass in lambdas and bound member functions @@ -130,7 +136,8 @@ CHIP_ERROR WriteAttribute(const SessionHandle & sessionHandle, chip::EndpointId AttributeId attributeId, const AttrType & requestData, WriteCallback::OnSuccessCallbackType onSuccessCb, WriteCallback::OnErrorCallbackType onErrorCb, const Optional & aTimedWriteTimeoutMs, WriteCallback::OnDoneCallbackType onDoneCb = nullptr, - const Optional & aDataVersion = NullOptional) + const Optional & aDataVersion = NullOptional, + Internal::WriteCancelFn * outCancelFn = nullptr) { auto callback = Platform::MakeUnique(onSuccessCb, onErrorCb, onDoneCb, sessionHandle->IsGroupSession()); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); @@ -151,6 +158,15 @@ CHIP_ERROR WriteAttribute(const SessionHandle & sessionHandle, chip::EndpointId ReturnErrorOnFailure(client->SendWriteRequest(sessionHandle)); + // If requested by the caller, provide a way to cancel the write interaction. + if (outCancelFn != nullptr) + { + *outCancelFn = [rawCallback = callback.get(), rawClient = client.get()]() { + chip::Platform::Delete(rawClient); + chip::Platform::Delete(rawCallback); + }; + } + // At this point the handle will ensure our callback's OnDone is always // called. client.release(); From 6a72fd185b9c01074dfb51d3ab000f1c792fc65f Mon Sep 17 00:00:00 2001 From: Jakub Latusek Date: Thu, 27 Jun 2024 17:28:41 +0200 Subject: [PATCH 19/21] Use in k32w example dependencies from project (#34112) * Use in k32w example dependencies from project not default one from pigweed * Restyle --- examples/lighting-app/nxp/k32w/k32w0/.gn | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/lighting-app/nxp/k32w/k32w0/.gn b/examples/lighting-app/nxp/k32w/k32w0/.gn index 363727423ce903..cfa8fcb8c07dc4 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/.gn +++ b/examples/lighting-app/nxp/k32w/k32w0/.gn @@ -26,6 +26,10 @@ default_args = { import("//args.gni") + pw_build_PIP_CONSTRAINTS = [ "${chip_root}/scripts/setup/constraints.txt" ] + pw_build_PIP_REQUIREMENTS = + [ "${chip_root}/scripts/setup/requirements.build.txt" ] + # Import default platform configs import("${chip_root}/src/platform/nxp/k32w/k32w0/args.gni") } From 3fc8d676525d3b2855b6b3b0278673cfb92a8cdd Mon Sep 17 00:00:00 2001 From: Rohan Sahay Date: Thu, 27 Jun 2024 21:53:56 +0530 Subject: [PATCH 20/21] [Silabs] Adds support for both PSA and TinyCrypt on SiWx917 SoC (#29776) * Refactor SiWx917 for mbedtls usage * Refactor PlatformManagerImpl initialization * Remove experimental ECDSA support * Adds multithreaded safety in crypto operations * Adds changes for use of SL_MBEDTLS_USE_TINYCRYPT * Adds changes for use of SL_MBEDTLS_USE_TINYCRYPT * addressed comments * Updated as per comments --------- Co-authored-by: Rohan S <3526930+brosahay@users.noreply.github.com> --- .../silabs/SiWx917/SiWx917/sl_wifi_if.cpp | 14 +- src/platform/silabs/PlatformManagerImpl.cpp | 17 +- src/platform/silabs/PlatformManagerImpl.h | 4 +- src/platform/silabs/SiWx917/BUILD.gn | 12 +- .../SiWx917/siwx917-chip-mbedtls-config.h | 162 +++----- .../silabs/SiWx917/siwx917-chip-psa-config.h | 32 ++ third_party/silabs/SiWx917_sdk.gni | 356 ++++++++++++++---- 7 files changed, 398 insertions(+), 199 deletions(-) create mode 100644 src/platform/silabs/SiWx917/siwx917-chip-psa-config.h diff --git a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp index c89c6768abe62c..5253b3b2ec5062 100644 --- a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp +++ b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp @@ -74,10 +74,10 @@ extern "C" { #include "sl_wifi.h" #include "sl_wifi_callback_framework.h" #include "wfx_host_events.h" -#if SLI_SI91X_MCU_INTERFACE +#if SL_MBEDTLS_USE_TINYCRYPT +#include "sl_si91x_constants.h" #include "sl_si91x_trng.h" -#define TRNGKEY_SIZE 4 -#endif // SLI_SI91X_MCU_INTERFACE +#endif // SL_MBEDTLS_USE_TINYCRYPT } WfxRsi_t wfx_rsi; @@ -456,8 +456,8 @@ static sl_status_t wfx_rsi_init(void) return status; } -#ifdef SLI_SI91X_MCU_INTERFACE - const uint32_t trngKey[TRNGKEY_SIZE] = { 0x16157E2B, 0xA6D2AE28, 0x8815F7AB, 0x3C4FCF09 }; +#ifdef SL_MBEDTLS_USE_TINYCRYPT + const uint32_t trngKey[TRNG_KEY_SIZE] = { 0x16157E2B, 0xA6D2AE28, 0x8815F7AB, 0x3C4FCF09 }; // To check the Entropy of TRNG and verify TRNG functioning. status = sl_si91x_trng_entropy(); @@ -468,13 +468,13 @@ static sl_status_t wfx_rsi_init(void) } // Initiate and program the key required for TRNG hardware engine - status = sl_si91x_trng_program_key((uint32_t *) trngKey, TRNGKEY_SIZE); + status = sl_si91x_trng_program_key((uint32_t *) trngKey, TRNG_KEY_SIZE); if (status != SL_STATUS_OK) { SILABS_LOG("TRNG Key Programming Failed"); return status; } -#endif // SLI_SI91X_MCU_INTERFACE +#endif // SL_MBEDTLS_USE_TINYCRYPT wfx_rsi.events = xEventGroupCreateStatic(&rsiDriverEventGroup); wfx_rsi.dev_state |= WFX_RSI_ST_DEV_READY; diff --git a/src/platform/silabs/PlatformManagerImpl.cpp b/src/platform/silabs/PlatformManagerImpl.cpp index 4e54a2a53f98a5..741a0b6b8676e1 100644 --- a/src/platform/silabs/PlatformManagerImpl.cpp +++ b/src/platform/silabs/PlatformManagerImpl.cpp @@ -31,9 +31,9 @@ #include #include -#if defined(TINYCRYPT_PRIMITIVES) +#if defined(SL_MBEDTLS_USE_TINYCRYPT) #include "tinycrypt/ecc.h" -#endif // TINYCRYPT_PRIMITIVES +#endif // SL_MBEDTLS_USE_TINYCRYPT #if CHIP_SYSTEM_CONFIG_USE_LWIP #include @@ -46,7 +46,7 @@ namespace DeviceLayer { PlatformManagerImpl PlatformManagerImpl::sInstance; -#if defined(TINYCRYPT_PRIMITIVES) +#if defined(SL_MBEDTLS_USE_TINYCRYPT) sys_mutex_t PlatformManagerImpl::rngMutexHandle = NULL; int PlatformManagerImpl::uECC_RNG_Function(uint8_t * dest, unsigned int size) @@ -76,12 +76,10 @@ static int app_entropy_source(void * data, unsigned char * output, size_t len, s return 0; } #endif // !SLI_SI91X_MCU_INTERFACE -#endif // TINYCRYPT_PRIMITIVES - +#endif // SL_MBEDTLS_USE_TINYCRYPT CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) { CHIP_ERROR err; - // Initialize the configuration system. err = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init(); SuccessOrExit(err); @@ -93,14 +91,15 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) ReturnErrorOnFailure(System::Clock::InitClock_RealTime()); -#if defined(TINYCRYPT_PRIMITIVES) +#if defined(SL_MBEDTLS_USE_TINYCRYPT) #if !(SLI_SI91X_MCU_INTERFACE) - ReturnErrorOnFailure(chip::Crypto::add_entropy_source(app_entropy_source, NULL, 16 /*Threshold value*/)); + // 16 : Threshold value + ReturnErrorOnFailure(chip::Crypto::add_entropy_source(app_entropy_source, NULL, 16)); #endif // !SLI_SI91X_MCU_INTERFACE /* Set RNG function for tinycrypt operations. */ VerifyOrExit(sys_mutex_new(&rngMutexHandle) == ERR_OK, err = CHIP_ERROR_NO_MEMORY); uECC_set_rng(PlatformManagerImpl::uECC_RNG_Function); -#endif // TINYCRYPT_PRIMITIVES +#endif // SL_MBEDTLS_USE_TINYCRYPT // Call _InitChipStack() on the generic implementation base class // to finish the initialization process. diff --git a/src/platform/silabs/PlatformManagerImpl.h b/src/platform/silabs/PlatformManagerImpl.h index 4a0bfdb52c1e81..b44fbadbfa3308 100644 --- a/src/platform/silabs/PlatformManagerImpl.h +++ b/src/platform/silabs/PlatformManagerImpl.h @@ -41,7 +41,7 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener // the implementation methods provided by this class. friend PlatformManager; -#if defined(TINYCRYPT_PRIMITIVES) +#if defined(SL_MBEDTLS_USE_TINYCRYPT) // Since the RNG callback will be called from multiple threads, // use this mutex to lock/unlock the call to Matter RNG API, which // uses some global variables. @@ -51,7 +51,7 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener // It must be set before calling any sign operations, // which are used in both Matter and OT threads. static int uECC_RNG_Function(uint8_t * dest, unsigned int size); -#endif +#endif // SL_MBEDTLS_USE_TINYCRYPT // Allow the generic implementation base class to call helper methods on // this class. diff --git a/src/platform/silabs/SiWx917/BUILD.gn b/src/platform/silabs/SiWx917/BUILD.gn index 27df228be44222..ca3c4042349113 100644 --- a/src/platform/silabs/SiWx917/BUILD.gn +++ b/src/platform/silabs/SiWx917/BUILD.gn @@ -18,11 +18,14 @@ import("${chip_root}/src/platform/device.gni") import("${chip_root}/build/chip/buildconfig_header.gni") import("${chip_root}/src/crypto/crypto.gni") +import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${chip_root}/third_party/silabs/SiWx917_sdk.gni") import("${chip_root}/third_party/silabs/silabs_board.gni") silabs_platform_dir = "${chip_root}/src/platform/silabs" assert(chip_device_platform == "SiWx917") + if (chip_crypto == "platform") { import("//build_overrides/mbedtls.gni") } @@ -80,7 +83,14 @@ static_library("SiWx917") { # Add platform crypto implementation if (chip_crypto == "platform") { - sources += [ "CHIPCryptoPALTinyCrypt.cpp" ] + if (sl_si91x_crypto_flavor == "tinycrypt") { + sources += [ "CHIPCryptoPALTinyCrypt.cpp" ] + } + + if (sl_si91x_crypto_flavor == "psa") { + sources += [ "${silabs_platform_dir}/efr32/CHIPCryptoPALPsaEfr32.cpp" ] + } + public_deps += [ "${chip_root}/src/crypto", "${mbedtls_root}:mbedtls", diff --git a/src/platform/silabs/SiWx917/siwx917-chip-mbedtls-config.h b/src/platform/silabs/SiWx917/siwx917-chip-mbedtls-config.h index 1fb5fde59341af..de0298957c4836 100644 --- a/src/platform/silabs/SiWx917/siwx917-chip-mbedtls-config.h +++ b/src/platform/silabs/SiWx917/siwx917-chip-mbedtls-config.h @@ -1,111 +1,86 @@ /* - * Copyright (c) 2021, The OpenThread Authors. - * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * 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 -#include -/** - * Enable FreeRTOS threading support - */ -#define MBEDTLS_FREERTOS +#define MBEDTLS_PLATFORM_C +#define MBEDTLS_PLATFORM_MEMORY +#define MBEDTLS_VERSION_C +#define MBEDTLS_VERSION_FEATURES -/** - * Enable H Crypto and Entropy modules - */ -#define MBEDTLS_AES_C -#define MBEDTLS_ECP_C -#define MBEDTLS_ECDH_C -#define MBEDTLS_ENTROPY_C -#define MBEDTLS_SHA256_C -#define MBEDTLS_CIPHER_MODE_CTR -#define MBEDTLS_TRNG_C +#define MBEDTLS_HKDF_C +#define MBEDTLS_PKCS5_C -#define MBEDTLS_NO_PLATFORM_ENTROPY -#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES +// DIC Specific Configurations +#ifdef DIC_ENABLE -#if defined(MBEDTLS_ECP_ALT) && !defined(MBEDTLS_ECP_RESTARTABLE) -typedef void mbedtls_ecp_restart_ctx; -#endif +#define MBEDTLS_MPI_MAX_SIZE 512 -#ifdef DIC_ENABLE -#define MBEDTLS_PKCS1_V15 -#define MBEDTLS_RSA_NO_CRT #define MBEDTLS_CIPHER_MODE_CBC +#define MBEDTLS_CIPHER_MODE_WITH_PADDING #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED +#define MBEDTLS_PKCS1_V15 #define MBEDTLS_RSA_C +#define MBEDTLS_RSA_NO_CRT #define MBEDTLS_SHA1_C #define MBEDTLS_SSL_IN_CONTENT_LEN 5120 +#define MBEDTLS_SSL_MAX_CONTENT_LEN 5120 #define MBEDTLS_SSL_OUT_CONTENT_LEN 1560 -#define MBEDTLS_DEBUG_C -#define MBEDTLS_CIPHER_MODE_WITH_PADDING -#endif + +#endif // DIC_ENABLE + +#ifdef SL_MBEDTLS_USE_TINYCRYPT +#define TINYCRYPT_PRIMITIVES +#define OPTIMIZE_TINYCRYPT_ASM + +#define MBEDTLS_FREERTOS + +#if (!(DIC_ENABLE) || !defined(DIC_ENABLE)) +/**< Maximum windows size used. */ +#define MBEDTLS_MPI_WINDOW_SIZE 1 + +/**< Maximum number of bytes for usable MPIs. */ +#define MBEDTLS_MPI_MAX_SIZE 32 +/**< Maxium fragment length in bytes */ +#define MBEDTLS_SSL_MAX_CONTENT_LEN 768 +#endif // !(DIC_ENABLE) + +#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES #define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf #define MBEDTLS_AES_ROM_TABLES -#define MBEDTLS_ASN1_PARSE_C -#define MBEDTLS_ASN1_WRITE_C -#define MBEDTLS_BASE64_C -#define MBEDTLS_BIGNUM_C #define MBEDTLS_CCM_C -#define MBEDTLS_CIPHER_C #define MBEDTLS_CIPHER_MODE_CBC #define MBEDTLS_CIPHER_MODE_CFB -#define MBEDTLS_CMAC_C -#define MBEDTLS_CTR_DRBG_C +#define MBEDTLS_CIPHER_MODE_CTR +#define MBEDTLS_ECDH_C #define MBEDTLS_ECDH_LEGACY_CONTEXT -#define MBEDTLS_ECDSA_C #define MBEDTLS_ECDSA_DETERMINISTIC #define MBEDTLS_ECJPAKE_C -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 #define MBEDTLS_ECP_NIST_OPTIM -#define MBEDTLS_ENTROPY_FORCE_SHA256 -// TODO: 3R -// #define MBEDTLS_ENTROPY_HARDWARE_ALT - +#define MBEDTLS_ECP_WINDOW_SIZE 2 #define MBEDTLS_ERROR_STRERROR_DUMMY #define MBEDTLS_HAVE_ASM -#define MBEDTLS_HKDF_C #define MBEDTLS_HMAC_DRBG_C #define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED #define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED #define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED -#define MBEDTLS_MD_C -#define MBEDTLS_OID_C -#define MBEDTLS_PEM_PARSE_C -#define MBEDTLS_PEM_WRITE_C -#define MBEDTLS_PK_C -#define MBEDTLS_PK_PARSE_C -#define MBEDTLS_PK_WRITE_C -#define MBEDTLS_PKCS5_C -#define MBEDTLS_PLATFORM_C -#define MBEDTLS_PLATFORM_MEMORY #define MBEDTLS_SHA256_SMALLER #define MBEDTLS_SHA512_C #define MBEDTLS_SSL_CLI_C @@ -115,38 +90,17 @@ typedef void mbedtls_ecp_restart_ctx; #define MBEDTLS_SSL_EXPORT_KEYS #define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE #define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH -#define MBEDTLS_SSL_PROTO_TLS1_2 #define MBEDTLS_SSL_PROTO_DTLS +#define MBEDTLS_SSL_PROTO_TLS1_2 #define MBEDTLS_SSL_SRV_C #define MBEDTLS_SSL_TLS_C -#define MBEDTLS_X509_CREATE_C -#define MBEDTLS_X509_CSR_WRITE_C -#define MBEDTLS_X509_CRL_PARSE_C -#define MBEDTLS_X509_CRT_PARSE_C -#define MBEDTLS_X509_CSR_PARSE_C -#define MBEDTLS_X509_USE_C - -#define MBEDTLS_MPI_WINDOW_SIZE 1 /**< Maximum windows size used. */ -#ifdef DIC_ENABLE -#define MBEDTLS_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */ -#else -#define MBEDTLS_MPI_MAX_SIZE 32 /**< Maximum number of bytes for usable MPIs. */ -#endif -#define MBEDTLS_ECP_MAX_BITS 256 /**< Maximum bit size of groups */ -#define MBEDTLS_ECP_WINDOW_SIZE 2 /**< Maximum window size used */ -#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 /**< Enable fixed-point speed-up */ -#define MBEDTLS_ENTROPY_MAX_SOURCES 2 /**< Maximum number of sources supported */ - -#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE -#define MBEDTLS_SSL_MAX_CONTENT_LEN 900 /**< Maxium fragment length in bytes */ -#else -#ifdef DIC_ENABLE -#define MBEDTLS_SSL_MAX_CONTENT_LEN 5120 /**< Maxium fragment length in bytes */ -#else -#define MBEDTLS_SSL_MAX_CONTENT_LEN 768 /**< Maxium fragment length in bytes */ -#endif // DIC +#define MBEDTLS_TRNG_C + +#if defined(MBEDTLS_ECP_ALT) && !defined(MBEDTLS_ECP_RESTARTABLE) +typedef void mbedtls_ecp_restart_ctx; #endif -#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 +#endif // SL_MBEDTLS_USE_TINYCRYPT -#include "mbedtls/check_config.h" +// SLC GENERATED +#include "sl_mbedtls_config.h" diff --git a/src/platform/silabs/SiWx917/siwx917-chip-psa-config.h b/src/platform/silabs/SiWx917/siwx917-chip-psa-config.h new file mode 100644 index 00000000000000..f498cccc2b2582 --- /dev/null +++ b/src/platform/silabs/SiWx917/siwx917-chip-psa-config.h @@ -0,0 +1,32 @@ +/* + * + * Copyright (c) 2024 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 + +// DIC Specific Configurations +#ifdef DIC_ENABLE +#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF + +#define PSA_WANT_ALG_CBC_NO_PADDING +#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN +#define PSA_WANT_ALG_SOME_PAKE +#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY +#endif // DIC_ENABLE + +// SLC GENERATED +#include "psa_crypto_config.h" diff --git a/third_party/silabs/SiWx917_sdk.gni b/third_party/silabs/SiWx917_sdk.gni index ddda1e68b7f4b7..6dd4085381ad4f 100644 --- a/third_party/silabs/SiWx917_sdk.gni +++ b/third_party/silabs/SiWx917_sdk.gni @@ -16,10 +16,12 @@ import("//build_overrides/chip.gni") import("//build_overrides/efr32_sdk.gni") import("//build_overrides/jlink.gni") import("//build_overrides/mbedtls.gni") -import("${efr32_sdk_build_root}/efr32_sdk.gni") import("${chip_root}/src/app/icd/icd.gni") +import("${chip_root}/src/crypto/crypto.gni") import("${chip_root}/src/lib/lib.gni") +import("${chip_root}/src/platform/silabs/wifi_args.gni") +import("${efr32_sdk_build_root}/efr32_sdk.gni") import("silabs_board.gni") examples_plat_dir = "${chip_root}/examples/platform/silabs/SiWx917" @@ -31,6 +33,9 @@ declare_args() { # Periodic time at which the 917 SoC should wakeup si91x_alarm_periodic_time = 30 + # option to select the crypto library + sl_si91x_crypto_flavor = "tinycrypt" + # enable 917 SoC M4 sleep wakeup si917_m4_sleep_enabled = false } @@ -44,13 +49,19 @@ template("siwx917_sdk") { sdk_target_name = target_name config("${sdk_target_name}_config") { + defines = [] include_dirs = [] libs = [] - defines = [] + cflags = [] + if (defined(invoker.include_dirs)) { include_dirs += invoker.include_dirs } + if (defined(invoker.defines)) { + defines += invoker.defines + } + # Treat these includes as system includes, so warnings in them are not fatal. _include_dirs = [ "${chip_root}", @@ -58,11 +69,8 @@ template("siwx917_sdk") { "${efr32_sdk_root}/platform/emdrv/nvm3/inc", "${efr32_sdk_root}/platform/emdrv/common/inc", "${efr32_sdk_root}/platform/service/device_init/inc", - "${sdk_support_root}/matter/mbedtls/tinycrypt/inc", "${sdk_support_root}/matter/si91x/siwx917/BRD4338A/autogen", "${sdk_support_root}/matter/si91x/siwx917/BRD4338A/config", - "${chip_root}/third_party/mbedtls/repo/include", - "${chip_root}/third_party/mbedtls/repo/library", "${chip_root}/src/platform/silabs/rs911x", @@ -173,7 +181,6 @@ template("siwx917_sdk") { # To fix this, these files are also manually depended upon in the source set # declared in siwx917_mbedtls_config further down this file. defines += [ - "MBEDTLS_CONFIG_FILE=\"siwx917-chip-mbedtls-config.h\"", "__STARTUP_CLEAR_BSS", "HARD_FAULT_LOG_ENABLE", "SL_HEAP_SIZE=32768", @@ -197,8 +204,6 @@ template("siwx917_sdk") { "USE_NVM3=1", "SLI_SI91X_ENABLE_BLE=1", "SL_SI91X_ENABLE_LITTLE_ENDIAN=1", - "TINYCRYPT_PRIMITIVES", - "OPTIMIZE_TINYCRYPT_ASM", "__error_t_defined", "RSI_SAMPLE_HAL", "DEBUG_UART=1", @@ -245,7 +250,6 @@ template("siwx917_sdk") { defines += [ "ENABLE_CHIP_SHELL" ] } - import("${chip_root}/src/platform/silabs/wifi_args.gni") defines += [ "LWIP_NETIF_API=1" ] if (lwip_ipv4) { defines += [ @@ -341,11 +345,6 @@ template("siwx917_sdk") { libs += [ "${sdk_support_root}/platform/emdrv/nvm3/lib/libnvm3_CM4_gcc.a" ] - cflags = [] - foreach(include_dir, _include_dirs) { - cflags += [ "-isystem" + rebase_path(include_dir, root_build_dir) ] - } - cflags += [ "-Wno-maybe-uninitialized", "-Wno-shadow", @@ -359,23 +358,256 @@ template("siwx917_sdk") { "-Wno-unused-function", ] - if (defined(invoker.defines)) { - defines += invoker.defines + foreach(include_dir, _include_dirs) { + cflags += [ "-isystem" + rebase_path(include_dir, root_build_dir) ] } } - source_set("siwx917_mbedtls_config") { - # We're setting the mbedTLS config flags here as the siwx917_sdk target - # acts as the mbedTLS target for SiWx917 builds. We need this for the build - # system to recompile mbedTLS (= the SDK) when the mbedTLS config gets - # edited. - sources = [ - "${chip_root}/src/platform/silabs/SiWx917/siwx917-chip-mbedtls-config.h", - ] + assert(chip_crypto == "platform" && (sl_si91x_crypto_flavor == "tinycrypt" || + sl_si91x_crypto_flavor == "psa"), + "sl_si91x_crypto_flavor must be tinycrypt or psa") + + if (chip_crypto == "platform") { + if (sl_si91x_crypto_flavor == "psa") { + _mbedtls_root = "${efr32_sdk_root}/util/third_party/mbedtls" + + sl_si91x_psa_crypto_path = + "${wifi_sdk_root}/components/device/silabs/si91x/wireless/crypto/" + + config("sl_si91x_psa_crypto_config") { + defines = [ + "MBEDTLS_CONFIG_FILE=\"siwx917-chip-mbedtls-config.h\"", + "MBEDTLS_PSA_CRYPTO_CONFIG_FILE=\"siwx917-chip-psa-config.h\"", + + # WISECONNECT 3 SDK + "SLI_AEAD_DEVICE_SI91X=1", + "SLI_CIPHER_DEVICE_SI91X=1", + "SLI_ECDH_DEVICE_SI91X=1", + "SLI_MAC_DEVICE_SI91X=1", + "SLI_SHA_DEVICE_SI91X=1", + "SLI_TRNG_DEVICE_SI91X=1", + "SLI_SECURE_KEY_STORAGE_DEVICE_SI91X=1", + "SLI_MULTITHREAD_DEVICE_SI91X=1", + ] - public_deps = [ "${chip_root}/src/crypto:crypto_buildconfig" ] - } + include_dirs = [ + # WISECONNECT 3 SDK + "${sl_si91x_psa_crypto_path}/inc", + "${sl_si91x_psa_crypto_path}/aes/inc", + "${sl_si91x_psa_crypto_path}/aead/inc", + "${sl_si91x_psa_crypto_path}/ccm/inc", + "${sl_si91x_psa_crypto_path}/ecdh/inc", + "${sl_si91x_psa_crypto_path}/ecdsa/inc", + "${sl_si91x_psa_crypto_path}/hmac/inc", + "${sl_si91x_psa_crypto_path}/mac/inc", + "${sl_si91x_psa_crypto_path}/gcm/inc", + "${sl_si91x_psa_crypto_path}/sha/inc", + "${sl_si91x_psa_crypto_path}/trng/inc", + "${sl_si91x_psa_crypto_path}/wrap/inc", + "${sl_si91x_psa_crypto_path}/multithread/inc", + + # mbedTLS + "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/config", + "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/config/preset", + "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/inc", + "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/inc", + "${efr32_sdk_root}/util/third_party/mbedtls/include", + "${efr32_sdk_root}/util/third_party/mbedtls/library", + ] + } + source_set("sl_si91x_psa_crypto") { + # We're setting the mbedTLS config flags here as the siwx917_sdk target + # acts as the mbedTLS target for SiWx917 builds. We need this for the build + # system to recompile mbedTLS (= the SDK) when the mbedTLS config gets + # edited. + sources = [ + "${_mbedtls_root}/include/mbedtls/platform.h", + "${_mbedtls_root}/include/mbedtls/version.h", + "${chip_root}/src/platform/silabs/SiWx917/siwx917-chip-mbedtls-config.h", + "${chip_root}/src/platform/silabs/SiWx917/siwx917-chip-psa-config.h", + + # mbedtls + "${_mbedtls_root}/library/aes.c", + "${_mbedtls_root}/library/asn1parse.c", + "${_mbedtls_root}/library/asn1write.c", + "${_mbedtls_root}/library/base64.c", + "${_mbedtls_root}/library/bignum.c", + "${_mbedtls_root}/library/bignum_core.c", + "${_mbedtls_root}/library/ccm.c", + "${_mbedtls_root}/library/cipher.c", + "${_mbedtls_root}/library/cipher_wrap.c", + "${_mbedtls_root}/library/cmac.c", + "${_mbedtls_root}/library/constant_time.c", + "${_mbedtls_root}/library/ctr_drbg.c", + "${_mbedtls_root}/library/ecdh.c", + "${_mbedtls_root}/library/ecdsa.c", + "${_mbedtls_root}/library/ecjpake.c", + "${_mbedtls_root}/library/ecp.c", + "${_mbedtls_root}/library/ecp_curves.c", + "${_mbedtls_root}/library/ecp_curves_new.c", + "${_mbedtls_root}/library/entropy.c", + "${_mbedtls_root}/library/entropy_poll.c", + "${_mbedtls_root}/library/hkdf.c", + "${_mbedtls_root}/library/hmac_drbg.c", + "${_mbedtls_root}/library/md.c", + "${_mbedtls_root}/library/oid.c", + "${_mbedtls_root}/library/pem.c", + "${_mbedtls_root}/library/pk.c", + "${_mbedtls_root}/library/pk_wrap.c", + "${_mbedtls_root}/library/pkcs5.c", + "${_mbedtls_root}/library/pkparse.c", + "${_mbedtls_root}/library/pkwrite.c", + "${_mbedtls_root}/library/platform.c", + "${_mbedtls_root}/library/platform_util.c", + "${_mbedtls_root}/library/psa_crypto.c", + "${_mbedtls_root}/library/psa_crypto_aead.c", + "${_mbedtls_root}/library/psa_crypto_cipher.c", + "${_mbedtls_root}/library/psa_crypto_client.c", + "${_mbedtls_root}/library/psa_crypto_driver_wrappers_no_static.c", + "${_mbedtls_root}/library/psa_crypto_ecp.c", + "${_mbedtls_root}/library/psa_crypto_hash.c", + "${_mbedtls_root}/library/psa_crypto_mac.c", + "${_mbedtls_root}/library/psa_crypto_rsa.c", + "${_mbedtls_root}/library/psa_crypto_se.c", + "${_mbedtls_root}/library/psa_crypto_slot_management.c", + "${_mbedtls_root}/library/psa_crypto_storage.c", + "${_mbedtls_root}/library/psa_util.c", + "${_mbedtls_root}/library/sha256.c", + "${_mbedtls_root}/library/ssl_cache.c", + "${_mbedtls_root}/library/ssl_ciphersuites.c", + "${_mbedtls_root}/library/ssl_client.c", + "${_mbedtls_root}/library/ssl_cookie.c", + "${_mbedtls_root}/library/ssl_msg.c", + "${_mbedtls_root}/library/ssl_ticket.c", + "${_mbedtls_root}/library/ssl_tls.c", + "${_mbedtls_root}/library/ssl_tls12_client.c", + "${_mbedtls_root}/library/ssl_tls12_server.c", + "${_mbedtls_root}/library/threading.c", + "${_mbedtls_root}/library/version.c", + "${_mbedtls_root}/library/x509.c", + "${_mbedtls_root}/library/x509_create.c", + "${_mbedtls_root}/library/x509_crl.c", + "${_mbedtls_root}/library/x509_crt.c", + "${_mbedtls_root}/library/x509_csr.c", + "${_mbedtls_root}/library/x509write_crt.c", + "${_mbedtls_root}/library/x509write_csr.c", + + # GECKO SDK + "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/src/sl_psa_crypto.c", + "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/src/sli_psa_crypto.c", + "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sl_psa_its_nvm3.c", + "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_psa_trng.c", + + # WISECONNECT 3 SDK + "${sl_si91x_psa_crypto_path}/aead/src/sl_si91x_psa_aead.c", + "${sl_si91x_psa_crypto_path}/aes/src/sl_si91x_aes.c", + "${sl_si91x_psa_crypto_path}/aes/src/sl_si91x_psa_aes.c", + "${sl_si91x_psa_crypto_path}/ccm/src/sl_si91x_ccm.c", + "${sl_si91x_psa_crypto_path}/ecdh/src/sl_si91x_ecdh.c", + "${sl_si91x_psa_crypto_path}/ecdh/src/sl_si91x_psa_ecdh.c", + "${sl_si91x_psa_crypto_path}/ecdsa/src/sl_si91x_ecdsa.c", + "${sl_si91x_psa_crypto_path}/ecdsa/src/sl_si91x_psa_ecdsa.c", + "${sl_si91x_psa_crypto_path}/gcm/src/sl_si91x_gcm.c", + "${sl_si91x_psa_crypto_path}/hmac/src/sl_si91x_hmac.c", + "${sl_si91x_psa_crypto_path}/mac/src/sl_si91x_psa_mac.c", + "${sl_si91x_psa_crypto_path}/multithread/src/sl_si91x_crypto_thread.c", + "${sl_si91x_psa_crypto_path}/sha/src/sl_si91x_psa_sha.c", + "${sl_si91x_psa_crypto_path}/sha/src/sl_si91x_sha.c", + "${sl_si91x_psa_crypto_path}/src/sli_si91x_crypto_driver_functions.c", + "${sl_si91x_psa_crypto_path}/trng/src/sl_si91x_psa_trng.c", + "${sl_si91x_psa_crypto_path}/wrap/src/sl_si91x_psa_wrap.c", + "${sl_si91x_psa_crypto_path}/wrap/src/sl_si91x_wrap.c", + ] + + public_deps = [ "${chip_root}/src/crypto:crypto_buildconfig" ] + + public_configs = [ + ":${sdk_target_name}_config", + ":sl_si91x_psa_crypto_config", + ] + } + } + + if (sl_si91x_crypto_flavor == "tinycrypt") { + _mbedtls_root = "${mbedtls_root}/repo" + + config("siwx917_tinycrypt_config") { + defines = [ + "SL_MBEDTLS_USE_TINYCRYPT", + "MBEDTLS_CONFIG_FILE=\"siwx917-chip-mbedtls-config.h\"", + ] + + include_dirs = [ + "${sdk_support_root}/matter/mbedtls/tinycrypt/inc", + "${_mbedtls_root}/include", + "${_mbedtls_root}/library", + + # GECKO SDK configuration included to be used in autogenerated files + "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/config", + "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/config/preset", + "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/inc", + ] + } + + source_set("siwx917_tinycrypt") { + sources = [ + # config file + "${_mbedtls_root}/include/mbedtls/platform.h", + "${_mbedtls_root}/include/mbedtls/version.h", + "${chip_root}/src/platform/silabs/SiWx917/siwx917-chip-mbedtls-config.h", + + # mbedtls + "${_mbedtls_root}/library/aes.c", + "${_mbedtls_root}/library/asn1parse.c", + "${_mbedtls_root}/library/asn1write.c", + "${_mbedtls_root}/library/base64.c", + "${_mbedtls_root}/library/bignum.c", + "${_mbedtls_root}/library/ccm.c", + "${_mbedtls_root}/library/cipher.c", + "${_mbedtls_root}/library/cipher_wrap.c", + "${_mbedtls_root}/library/constant_time.c", + "${_mbedtls_root}/library/ctr_drbg.c", + "${_mbedtls_root}/library/ecdh.c", + "${_mbedtls_root}/library/ecdsa.c", + "${_mbedtls_root}/library/ecp.c", + "${_mbedtls_root}/library/ecp_curves.c", + "${_mbedtls_root}/library/entropy.c", + "${_mbedtls_root}/library/hkdf.c", + "${_mbedtls_root}/library/hmac_drbg.c", + "${_mbedtls_root}/library/md.c", + "${_mbedtls_root}/library/pem.c", + "${_mbedtls_root}/library/pkcs5.c", + "${_mbedtls_root}/library/platform.c", + "${_mbedtls_root}/library/sha256.c", + "${_mbedtls_root}/library/sha512.c", + "${_mbedtls_root}/library/version.c", + "${_mbedtls_root}/library/x509_create.c", + + # tinycrypt + "${sdk_support_root}/matter/mbedtls/tinycrypt/src/ecc.c", + "${sdk_support_root}/matter/mbedtls/tinycrypt/src/ecc_dh.c", + "${sdk_support_root}/matter/mbedtls/tinycrypt/src/ecc_dsa.c", + "${sdk_support_root}/matter/mbedtls/tinycrypt/src/error.c", + "${sdk_support_root}/matter/mbedtls/tinycrypt/src/oid.c", + "${sdk_support_root}/matter/mbedtls/tinycrypt/src/pk.c", + "${sdk_support_root}/matter/mbedtls/tinycrypt/src/pk_wrap.c", + "${sdk_support_root}/matter/mbedtls/tinycrypt/src/pkparse.c", + "${sdk_support_root}/matter/mbedtls/tinycrypt/src/pkwrite.c", + "${sdk_support_root}/matter/mbedtls/tinycrypt/src/platform_util.c", + "${sdk_support_root}/matter/mbedtls/tinycrypt/src/x509_crt.c", + "${sdk_support_root}/matter/mbedtls/tinycrypt/src/x509write_csr.c", + ] + + public_deps = [ "${chip_root}/src/crypto:crypto_buildconfig" ] + + public_configs = [ + ":${sdk_target_name}_config", + ":siwx917_tinycrypt_config", + ] + } + } + } source_set(sdk_target_name) { sources = [ # si91x component @@ -487,46 +719,9 @@ template("siwx917_sdk") { "${efr32_sdk_root}/platform/service/memory_manager/src/sl_memory_manager_retarget.c", "${efr32_sdk_root}/platform/service/memory_manager/src/sli_memory_manager_common.c", - # mbedtls - "${chip_root}/third_party/mbedtls/repo/library/aes.c", - "${chip_root}/third_party/mbedtls/repo/library/asn1parse.c", - "${chip_root}/third_party/mbedtls/repo/library/asn1write.c", - "${chip_root}/third_party/mbedtls/repo/library/base64.c", - "${chip_root}/third_party/mbedtls/repo/library/bignum.c", - "${chip_root}/third_party/mbedtls/repo/library/ccm.c", - "${chip_root}/third_party/mbedtls/repo/library/cipher.c", - "${chip_root}/third_party/mbedtls/repo/library/cipher_wrap.c", - "${chip_root}/third_party/mbedtls/repo/library/constant_time.c", - "${chip_root}/third_party/mbedtls/repo/library/ctr_drbg.c", - "${chip_root}/third_party/mbedtls/repo/library/ecdh.c", - "${chip_root}/third_party/mbedtls/repo/library/ecdsa.c", - "${chip_root}/third_party/mbedtls/repo/library/ecp.c", - "${chip_root}/third_party/mbedtls/repo/library/ecp_curves.c", - "${chip_root}/third_party/mbedtls/repo/library/entropy.c", - "${chip_root}/third_party/mbedtls/repo/library/hkdf.c", - "${chip_root}/third_party/mbedtls/repo/library/hmac_drbg.c", - "${chip_root}/third_party/mbedtls/repo/library/md.c", - "${chip_root}/third_party/mbedtls/repo/library/pem.c", - "${chip_root}/third_party/mbedtls/repo/library/pkcs5.c", - "${chip_root}/third_party/mbedtls/repo/library/platform.c", - "${chip_root}/third_party/mbedtls/repo/library/sha256.c", - "${chip_root}/third_party/mbedtls/repo/library/sha512.c", - "${chip_root}/third_party/mbedtls/repo/library/x509.c", - "${chip_root}/third_party/mbedtls/repo/library/x509_create.c", + # STARTUP FILES "${efr32_sdk_root}/platform/service/iostream/src/sl_iostream.c", "${efr32_sdk_root}/platform/service/iostream/src/sl_iostream_rtt.c", - "${sdk_support_root}/matter/mbedtls/tinycrypt/src/ecc.c", - "${sdk_support_root}/matter/mbedtls/tinycrypt/src/ecc_dh.c", - "${sdk_support_root}/matter/mbedtls/tinycrypt/src/ecc_dsa.c", - "${sdk_support_root}/matter/mbedtls/tinycrypt/src/error.c", - "${sdk_support_root}/matter/mbedtls/tinycrypt/src/oid.c", - "${sdk_support_root}/matter/mbedtls/tinycrypt/src/pk.c", - "${sdk_support_root}/matter/mbedtls/tinycrypt/src/pk_wrap.c", - "${sdk_support_root}/matter/mbedtls/tinycrypt/src/pkparse.c", - "${sdk_support_root}/matter/mbedtls/tinycrypt/src/pkwrite.c", - "${sdk_support_root}/matter/mbedtls/tinycrypt/src/platform_util.c", - "${sdk_support_root}/matter/mbedtls/tinycrypt/src/x509_crt.c", - "${sdk_support_root}/matter/mbedtls/tinycrypt/src/x509write_csr.c", "${sdk_support_root}/matter/si91x/siwx917/BRD4338A/support/src/startup_common_RS1xxxx.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/service/nvm3/src/sl_si91x_common_flash_intf.c", @@ -579,29 +774,38 @@ template("siwx917_sdk") { "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_time_period.c", ] } + public_deps = [ - ":siwx917_mbedtls_config", "${segger_rtt_root}:segger_rtt", "${segger_rtt_root}:segger_rtt_printf", "${segger_rtt_root}:segger_rtt_syscalls", ] + if (chip_crypto == "platform") { + if (sl_si91x_crypto_flavor == "tinycrypt") { + public_deps += [ ":siwx917_tinycrypt" ] + } + + if (sl_si91x_crypto_flavor == "psa") { + public_deps += [ ":sl_si91x_psa_crypto" ] + } + } if (defined(invoker.sources)) { sources += invoker.sources } if (invoker.enable_dic) { sources += [ - "${chip_root}/third_party/mbedtls/repo/library/debug.c", - "${chip_root}/third_party/mbedtls/repo/library/ecjpake.c", - "${chip_root}/third_party/mbedtls/repo/library/rsa.c", - "${chip_root}/third_party/mbedtls/repo/library/rsa_internal.c", - "${chip_root}/third_party/mbedtls/repo/library/sha1.c", - "${chip_root}/third_party/mbedtls/repo/library/ssl_ciphersuites.c", - "${chip_root}/third_party/mbedtls/repo/library/ssl_cli.c", - "${chip_root}/third_party/mbedtls/repo/library/ssl_msg.c", - "${chip_root}/third_party/mbedtls/repo/library/ssl_srv.c", - "${chip_root}/third_party/mbedtls/repo/library/ssl_tls.c", - "${chip_root}/third_party/silabs/mqtt/stack/mqtt.c", + "${_mbedtls_root}/library/ecjpake.c", + "${_mbedtls_root}/library/rsa.c", + "${_mbedtls_root}/library/rsa_internal.c", + "${_mbedtls_root}/library/sha1.c", + "${_mbedtls_root}/library/ssl_ciphersuites.c", + "${_mbedtls_root}/library/ssl_cli.c", + "${_mbedtls_root}/library/ssl_msg.c", + "${_mbedtls_root}/library/ssl_srv.c", + "${_mbedtls_root}/library/ssl_tls.c", + "${_mbedtls_root}/library/x509.c", + "${efr32_sdk_build_root}/mqtt/stack/mqtt.c", ] } From 03ae36eff60e7cd2eaf40f35a833896b84190a41 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 27 Jun 2024 14:32:21 -0400 Subject: [PATCH 21/21] Fix discriminator handling in chip-tool pairing commands. (#34115) Not all commands initialize the discriminator value, and the ones that don't should not use it. Fixes https://github.com/project-chip/connectedhomeip/issues/34096 --- .../commands/pairing/PairingCommand.cpp | 17 +++++++++--- .../commands/pairing/PairingCommand.h | 26 ++++++++++++------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/examples/chip-tool/commands/pairing/PairingCommand.cpp b/examples/chip-tool/commands/pairing/PairingCommand.cpp index a0437c53f56a7d..7bddfa3d08039c 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.cpp +++ b/examples/chip-tool/commands/pairing/PairingCommand.cpp @@ -216,7 +216,12 @@ CHIP_ERROR PairingCommand::PairWithCode(NodeId remoteId) CHIP_ERROR PairingCommand::Pair(NodeId remoteId, PeerAddress address) { - auto params = RendezvousParameters().SetSetupPINCode(mSetupPINCode).SetDiscriminator(mDiscriminator).SetPeerAddress(address); + VerifyOrDieWithMsg(mSetupPINCode.has_value(), chipTool, "Using mSetupPINCode in a mode when we have not gotten one"); + auto params = RendezvousParameters().SetSetupPINCode(mSetupPINCode.value()).SetPeerAddress(address); + if (mDiscriminator.has_value()) + { + params.SetDiscriminator(mDiscriminator.value()); + } CHIP_ERROR err = CHIP_NO_ERROR; if (mPaseOnly.ValueOr(false)) @@ -236,9 +241,11 @@ CHIP_ERROR PairingCommand::PairWithMdnsOrBleByIndex(NodeId remoteId, uint16_t in #if CHIP_DEVICE_LAYER_TARGET_DARWIN VerifyOrReturnError(IsInteractive(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrDieWithMsg(mSetupPINCode.has_value(), chipTool, "Using mSetupPINCode in a mode when we have not gotten one"); + RendezvousParameters params; ReturnErrorOnFailure(GetDeviceScanner().Get(index, params)); - params.SetSetupPINCode(mSetupPINCode); + params.SetSetupPINCode(mSetupPINCode.value()); CHIP_ERROR err = CHIP_NO_ERROR; if (mPaseOnly.ValueOr(false)) @@ -258,6 +265,10 @@ CHIP_ERROR PairingCommand::PairWithMdnsOrBleByIndex(NodeId remoteId, uint16_t in CHIP_ERROR PairingCommand::PairWithMdnsOrBleByIndexWithCode(NodeId remoteId, uint16_t index) { + // We might or might not have a setup code. We don't know yet, but if we + // do, we'll emplace it at that point. + mSetupPINCode.reset(); + #if CHIP_DEVICE_LAYER_TARGET_DARWIN VerifyOrReturnError(IsInteractive(), CHIP_ERROR_INCORRECT_STATE); @@ -281,7 +292,7 @@ CHIP_ERROR PairingCommand::PairWithMdnsOrBleByIndexWithCode(NodeId remoteId, uin VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT); } - mSetupPINCode = payload.setUpPINCode; + mSetupPINCode.emplace(payload.setUpPINCode); return PairWithMdnsOrBleByIndex(remoteId, index); } diff --git a/examples/chip-tool/commands/pairing/PairingCommand.h b/examples/chip-tool/commands/pairing/PairingCommand.h index 9ff63e37878576..facb0f2403536b 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.h +++ b/examples/chip-tool/commands/pairing/PairingCommand.h @@ -26,6 +26,8 @@ #include #include +#include + enum class PairingMode { None, @@ -107,32 +109,32 @@ class PairingCommand : public CHIPCommand, break; case PairingMode::Ble: AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete); - AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode); - AddArgument("discriminator", 0, 4096, &mDiscriminator); + AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode.emplace()); + AddArgument("discriminator", 0, 4096, &mDiscriminator.emplace()); break; case PairingMode::OnNetwork: AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete); - AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode); + AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode.emplace()); AddArgument("pase-only", 0, 1, &mPaseOnly); break; case PairingMode::SoftAP: AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete); - AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode); - AddArgument("discriminator", 0, 4096, &mDiscriminator); + AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode.emplace()); + AddArgument("discriminator", 0, 4096, &mDiscriminator.emplace()); AddArgument("device-remote-ip", &mRemoteAddr); AddArgument("device-remote-port", 0, UINT16_MAX, &mRemotePort); AddArgument("pase-only", 0, 1, &mPaseOnly); break; case PairingMode::AlreadyDiscovered: AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete); - AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode); + AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode.emplace()); AddArgument("device-remote-ip", &mRemoteAddr); AddArgument("device-remote-port", 0, UINT16_MAX, &mRemotePort); AddArgument("pase-only", 0, 1, &mPaseOnly); break; case PairingMode::AlreadyDiscoveredByIndex: AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete); - AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode); + AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode.emplace()); AddArgument("index", 0, UINT16_MAX, &mIndex); AddArgument("pase-only", 0, 1, &mPaseOnly); break; @@ -252,8 +254,14 @@ class PairingCommand : public CHIPCommand, mComplex_DSTOffsets; uint16_t mRemotePort; - uint16_t mDiscriminator; - uint32_t mSetupPINCode; + // mDiscriminator is only used for some situations, but in those situations + // it's mandatory. Track whether we're actually using it; the cases that do + // will emplace this optional. + std::optional mDiscriminator; + // mSetupPINCode is only used for some situations, but in those situations + // it's mandatory. Track whether we're actually using it; the cases that do + // will emplace this optional. + std::optional mSetupPINCode; uint16_t mIndex; chip::ByteSpan mOperationalDataset; chip::ByteSpan mSSID;