diff --git a/examples/all-clusters-app/all-clusters-common/include/resource-monitoring-instances.h b/examples/all-clusters-app/all-clusters-common/include/resource-monitoring-instances.h index c12a686735abba..276e423626c1d7 100644 --- a/examples/all-clusters-app/all-clusters-common/include/resource-monitoring-instances.h +++ b/examples/all-clusters-app/all-clusters-common/include/resource-monitoring-instances.h @@ -55,23 +55,9 @@ class HepaFilterMonitoringInstance : public chip::app::Clusters::ResourceMonitor aResetConditionCommandSupported){}; }; -class StaticReplacementProductListManager : public chip::app::Clusters::ResourceMonitoring::ReplacementProductListManager +class ImmutableReplacementProductListManager : public chip::app::Clusters::ResourceMonitoring::ReplacementProductListManager { public: - uint8_t Size() override { return mReplacementProductListSize; }; - - CHIP_ERROR Next(chip::app::Clusters::ResourceMonitoring::Attributes::ReplacementProductStruct::Type & item) override; - - ~StaticReplacementProductListManager() {} - StaticReplacementProductListManager( - chip::app::Clusters::ResourceMonitoring::Attributes::ReplacementProductStruct::Type * aReplacementProductsList, - uint8_t aReplacementProductListSize) - { - mReplacementProductsList = aReplacementProductsList; - mReplacementProductListSize = aReplacementProductListSize; - } - -private: - chip::app::Clusters::ResourceMonitoring::Attributes::ReplacementProductStruct::Type * mReplacementProductsList; - uint8_t mReplacementProductListSize; + CHIP_ERROR + Next(chip::app::Clusters::ResourceMonitoring::ReplacementProductStruct & item) override; }; diff --git a/examples/all-clusters-app/all-clusters-common/src/resource-monitoring-instances.cpp b/examples/all-clusters-app/all-clusters-common/src/resource-monitoring-instances.cpp index de7b46d26d1c1a..dc4283539b437b 100644 --- a/examples/all-clusters-app/all-clusters-common/src/resource-monitoring-instances.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/resource-monitoring-instances.cpp @@ -36,20 +36,7 @@ constexpr std::bitset<4> gActivatedCarbonFeatureMap{ static_cast(Featu static HepaFilterMonitoringInstance * gHepaFilterInstance = nullptr; static ActivatedCarbonFilterMonitoringInstance * gActivatedCarbonFilterInstance = nullptr; - -static ResourceMonitoring::Attributes::ReplacementProductStruct::Type sReplacementProductsList[] = { - { .productIdentifierType = ProductIdentifierTypeEnum::kUpc, - .productIdentifierValue = CharSpan::fromCharString("111112222233") }, - { .productIdentifierType = ProductIdentifierTypeEnum::kGtin8, .productIdentifierValue = CharSpan::fromCharString("gtin8xxx") }, - { .productIdentifierType = ProductIdentifierTypeEnum::kEan, - .productIdentifierValue = CharSpan::fromCharString("4444455555666") }, - { .productIdentifierType = ProductIdentifierTypeEnum::kGtin14, - .productIdentifierValue = CharSpan::fromCharString("gtin14xxxxxxxx") }, - { .productIdentifierType = ProductIdentifierTypeEnum::kOem, - .productIdentifierValue = CharSpan::fromCharString("oem20xxxxxxxxxxxxxxx") }, -}; -StaticReplacementProductListManager sReplacementProductListManager(&sReplacementProductsList[0], - ArraySize(sReplacementProductsList)); +static ImmutableReplacementProductListManager sReplacementProductListManager; //-- Activated Carbon Filter Monitoring Instance methods CHIP_ERROR ActivatedCarbonFilterMonitoringInstance::AppInit() @@ -106,14 +93,40 @@ void emberAfHepaFilterMonitoringClusterInitCallback(chip::EndpointId endpoint) gHepaFilterInstance->Init(); } -CHIP_ERROR StaticReplacementProductListManager::Next(Attributes::ReplacementProductStruct::Type & item) +CHIP_ERROR ImmutableReplacementProductListManager::Next(ReplacementProductStruct & item) { - if (mIndex < mReplacementProductListSize) + if (mIndex >= kReplacementProductListMaxSize) { - item = mReplacementProductsList[mIndex]; - mIndex++; - return CHIP_NO_ERROR; + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; } - return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + switch (mIndex) + { + case 0: { + item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kUpc); + item.SetProductIdentifierValue(CharSpan::fromCharString("111112222233")); + break; + case 1: + item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kGtin8); + item.SetProductIdentifierValue(CharSpan::fromCharString("gtin8xxx")); + break; + case 2: + item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kEan); + item.SetProductIdentifierValue(CharSpan::fromCharString("4444455555666")); + break; + case 3: + item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kGtin14); + item.SetProductIdentifierValue(CharSpan::fromCharString("gtin14xxxxxxxx")); + break; + case 4: + item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kOem); + item.SetProductIdentifierValue(CharSpan::fromCharString("oem20xxxxxxxxxxxxxxx")); + break; + default: + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + break; + } + } + mIndex++; + return CHIP_NO_ERROR; } diff --git a/examples/placeholder/linux/apps/app1/BUILD.gn b/examples/placeholder/linux/apps/app1/BUILD.gn index 595a0b7563132c..99b3547b81e7c8 100644 --- a/examples/placeholder/linux/apps/app1/BUILD.gn +++ b/examples/placeholder/linux/apps/app1/BUILD.gn @@ -30,6 +30,7 @@ source_set("app1") { ] sources = [ + "../../resource-monitoring-instances.cpp", "../../src/bridged-actions-stub.cpp", "../../static-supported-modes-manager.cpp", ] diff --git a/examples/placeholder/linux/apps/app2/BUILD.gn b/examples/placeholder/linux/apps/app2/BUILD.gn index 7d8f30a8ea83ec..91777971875d15 100644 --- a/examples/placeholder/linux/apps/app2/BUILD.gn +++ b/examples/placeholder/linux/apps/app2/BUILD.gn @@ -30,6 +30,7 @@ source_set("app2") { ] sources = [ + "../../resource-monitoring-instances.cpp", "../../src/bridged-actions-stub.cpp", "../../static-supported-modes-manager.cpp", ] diff --git a/examples/placeholder/linux/include/resource-monitoring-instances.h b/examples/placeholder/linux/include/resource-monitoring-instances.h new file mode 100644 index 00000000000000..276e423626c1d7 --- /dev/null +++ b/examples/placeholder/linux/include/resource-monitoring-instances.h @@ -0,0 +1,63 @@ +/* + * + * 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. + */ + +#include +#include +#include +#include + +/// This is an application level Instance to handle ActivatedCarbonfilterMonitoringInstance commands according to the specific +/// business logic. +class ActivatedCarbonFilterMonitoringInstance : public chip::app::Clusters::ResourceMonitoring::Instance +{ +private: + CHIP_ERROR AppInit() override; + chip::Protocols::InteractionModel::Status PreResetCondition() override; + chip::Protocols::InteractionModel::Status PostResetCondition() override; + +public: + ActivatedCarbonFilterMonitoringInstance( + chip::EndpointId aEndpointId, uint32_t aFeature, + chip::app::Clusters::ResourceMonitoring::Attributes::DegradationDirection::TypeInfo::Type aDegradationDirection, + bool aResetConditionCommandSupported) : + Instance(aEndpointId, chip::app::Clusters::ActivatedCarbonFilterMonitoring::Id, aFeature, aDegradationDirection, + aResetConditionCommandSupported){}; +}; + +/// This is an application level instance to handle HepaFilterMonitoringInstance commands according to the specific business logic. +class HepaFilterMonitoringInstance : public chip::app::Clusters::ResourceMonitoring::Instance +{ +private: + CHIP_ERROR AppInit() override; + chip::Protocols::InteractionModel::Status PreResetCondition() override; + chip::Protocols::InteractionModel::Status PostResetCondition() override; + +public: + HepaFilterMonitoringInstance( + chip::EndpointId aEndpointId, uint32_t aFeature, + chip::app::Clusters::ResourceMonitoring::Attributes::DegradationDirection::TypeInfo::Type aDegradationDirection, + bool aResetConditionCommandSupported) : + Instance(aEndpointId, chip::app::Clusters::HepaFilterMonitoring::Id, aFeature, aDegradationDirection, + aResetConditionCommandSupported){}; +}; + +class ImmutableReplacementProductListManager : public chip::app::Clusters::ResourceMonitoring::ReplacementProductListManager +{ +public: + CHIP_ERROR + Next(chip::app::Clusters::ResourceMonitoring::ReplacementProductStruct & item) override; +}; diff --git a/examples/placeholder/linux/resource-monitoring-instances.cpp b/examples/placeholder/linux/resource-monitoring-instances.cpp new file mode 100644 index 00000000000000..a030beed78c7e6 --- /dev/null +++ b/examples/placeholder/linux/resource-monitoring-instances.cpp @@ -0,0 +1,133 @@ +/* + * + * 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. + */ + +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::ResourceMonitoring; +using chip::Protocols::InteractionModel::Status; + +constexpr std::bitset<4> gHepaFilterFeatureMap{ static_cast(Feature::kCondition) | + static_cast(Feature::kWarning) | + static_cast(Feature::kReplacementProductList) }; +constexpr std::bitset<4> gActivatedCarbonFeatureMap{ static_cast(Feature::kCondition) | + static_cast(Feature::kWarning) | + static_cast(Feature::kReplacementProductList) }; + +static HepaFilterMonitoringInstance * gHepaFilterInstance = nullptr; +static ActivatedCarbonFilterMonitoringInstance * gActivatedCarbonFilterInstance = nullptr; + +static ImmutableReplacementProductListManager sReplacementProductListManager; + +//-- Activated Carbon Filter Monitoring Instance methods +CHIP_ERROR ActivatedCarbonFilterMonitoringInstance::AppInit() +{ + ChipLogDetail(Zcl, "ActivatedCarbonFilterMonitoringDelegate::Init()"); + SetReplacementProductListManagerInstance(&sReplacementProductListManager); + return CHIP_NO_ERROR; +} + +Status ActivatedCarbonFilterMonitoringInstance::PreResetCondition() +{ + ChipLogDetail(Zcl, "ActivatedCarbonFilterMonitoringInstance::PreResetCondition()"); + return Status::Success; +} + +Status ActivatedCarbonFilterMonitoringInstance::PostResetCondition() +{ + ChipLogDetail(Zcl, "ActivatedCarbonFilterMonitoringInstance::PostResetCondition()"); + return Status::Success; +} + +//-- Hepa Filter Monitoring instance methods +CHIP_ERROR HepaFilterMonitoringInstance::AppInit() +{ + ChipLogDetail(Zcl, "HepaFilterMonitoringInstance::Init()"); + SetReplacementProductListManagerInstance(&sReplacementProductListManager); + return CHIP_NO_ERROR; +} + +Status HepaFilterMonitoringInstance::PreResetCondition() +{ + ChipLogDetail(Zcl, "HepaFilterMonitoringInstance::PreResetCondition()"); + return Status::Success; +} + +Status HepaFilterMonitoringInstance::PostResetCondition() +{ + ChipLogDetail(Zcl, "HepaFilterMonitoringInstance::PostResetCondition()"); + return Status::Success; +} + +void emberAfActivatedCarbonFilterMonitoringClusterInitCallback(chip::EndpointId endpoint) +{ + VerifyOrDie(gActivatedCarbonFilterInstance == nullptr); + gActivatedCarbonFilterInstance = new ActivatedCarbonFilterMonitoringInstance( + endpoint, static_cast(gActivatedCarbonFeatureMap.to_ulong()), DegradationDirectionEnum::kDown, true); + gActivatedCarbonFilterInstance->Init(); +} +void emberAfHepaFilterMonitoringClusterInitCallback(chip::EndpointId endpoint) +{ + VerifyOrDie(gHepaFilterInstance == nullptr); + gHepaFilterInstance = new HepaFilterMonitoringInstance(endpoint, static_cast(gHepaFilterFeatureMap.to_ulong()), + DegradationDirectionEnum::kDown, true); + gHepaFilterInstance->Init(); +} + +CHIP_ERROR ImmutableReplacementProductListManager::Next(ReplacementProductStruct & item) +{ + if (mIndex >= kReplacementProductListMaxSize) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } + + switch (mIndex) + { + case 0: { + item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kUpc); + item.SetProductIdentifierValue(CharSpan::fromCharString("111112222233")); + break; + case 1: + item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kGtin8); + item.SetProductIdentifierValue(CharSpan::fromCharString("gtin8xxx")); + break; + case 2: + item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kEan); + item.SetProductIdentifierValue(CharSpan::fromCharString("4444455555666")); + break; + case 3: + item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kGtin14); + item.SetProductIdentifierValue(CharSpan::fromCharString("gtin14xxxxxxxx")); + break; + case 4: + item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kOem); + item.SetProductIdentifierValue(CharSpan::fromCharString("oem20xxxxxxxxxxxxxxx")); + break; + default: + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + break; + } + } + mIndex++; + return CHIP_NO_ERROR; +} diff --git a/examples/resource-monitoring-app/linux/BUILD.gn b/examples/resource-monitoring-app/linux/BUILD.gn index c5e769a39ce4f7..e9d5e391def96c 100644 --- a/examples/resource-monitoring-app/linux/BUILD.gn +++ b/examples/resource-monitoring-app/linux/BUILD.gn @@ -30,7 +30,7 @@ config("includes") { executable("chip-resource-monitoring-app") { sources = [ - "${chip_root}/examples/resource-monitoring-app/resource-monitoring-common/src/StaticReplacementProductListManager.cpp", + "${chip_root}/examples/resource-monitoring-app/resource-monitoring-common/src/ReplacementProductListManager.cpp", "${chip_root}/examples/resource-monitoring-app/resource-monitoring-common/src/instances/ActivatedCarbonFilterMonitoring.cpp", "${chip_root}/examples/resource-monitoring-app/resource-monitoring-common/src/instances/HepaFilterMonitoring.cpp", "include/CHIPProjectAppConfig.h", diff --git a/examples/resource-monitoring-app/resource-monitoring-common/include/ImmutableReplacementProductListManager.h b/examples/resource-monitoring-app/resource-monitoring-common/include/ImmutableReplacementProductListManager.h new file mode 100644 index 00000000000000..2dcbff41372866 --- /dev/null +++ b/examples/resource-monitoring-app/resource-monitoring-common/include/ImmutableReplacementProductListManager.h @@ -0,0 +1,44 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ResourceMonitoring { + +/** + * This implementation returns an immutable list of replacement products. + * It holds ReplacementProductListManager::kReplacementProductListMaxSize products in the list. + */ + +class ImmutableReplacementProductListManager : public ReplacementProductListManager +{ +public: + CHIP_ERROR Next(ReplacementProductStruct & item) override; +}; + +} // namespace ResourceMonitoring +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/resource-monitoring-app/resource-monitoring-common/include/StaticReplacementProductListManager.h b/examples/resource-monitoring-app/resource-monitoring-common/include/StaticReplacementProductListManager.h index cb83148302f8b6..26601a235fcb1d 100644 --- a/examples/resource-monitoring-app/resource-monitoring-common/include/StaticReplacementProductListManager.h +++ b/examples/resource-monitoring-app/resource-monitoring-common/include/StaticReplacementProductListManager.h @@ -34,20 +34,17 @@ namespace ResourceMonitoring { class StaticReplacementProductListManager : public ReplacementProductListManager { public: - uint8_t Size() override { return mReplacementProductListSize; }; - - CHIP_ERROR Next(Attributes::ReplacementProductStruct::Type & item) override; + CHIP_ERROR Next(ReplacementProductStruct & item) override; ~StaticReplacementProductListManager() {} - StaticReplacementProductListManager(Attributes::ReplacementProductStruct::Type * aReplacementProductsList, - uint8_t aReplacementProductListSize) + StaticReplacementProductListManager(ReplacementProductStruct * aReplacementProductsList, uint8_t aReplacementProductListSize) { mReplacementProductsList = aReplacementProductsList; mReplacementProductListSize = aReplacementProductListSize; } private: - Attributes::ReplacementProductStruct::Type * mReplacementProductsList; + ReplacementProductStruct * mReplacementProductsList; uint8_t mReplacementProductListSize; }; diff --git a/examples/resource-monitoring-app/resource-monitoring-common/src/ReplacementProductListManager.cpp b/examples/resource-monitoring-app/resource-monitoring-common/src/ReplacementProductListManager.cpp new file mode 100644 index 00000000000000..f450df6f380ef3 --- /dev/null +++ b/examples/resource-monitoring-app/resource-monitoring-common/src/ReplacementProductListManager.cpp @@ -0,0 +1,77 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::ResourceMonitoring; + +CHIP_ERROR StaticReplacementProductListManager::Next(ReplacementProductStruct & item) +{ + if (mIndex < mReplacementProductListSize) + { + item = mReplacementProductsList[mIndex]; + mIndex++; + return CHIP_NO_ERROR; + } + + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; +} + +CHIP_ERROR ImmutableReplacementProductListManager::Next(ReplacementProductStruct & item) +{ + if (mIndex >= kReplacementProductListMaxSize) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } + + switch (mIndex) + { + case 0: { + item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kUpc); + item.SetProductIdentifierValue(CharSpan::fromCharString("111112222233")); + break; + case 1: + item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kGtin8); + item.SetProductIdentifierValue(CharSpan::fromCharString("gtin8xxx")); + break; + case 2: + item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kEan); + item.SetProductIdentifierValue(CharSpan::fromCharString("4444455555666")); + break; + case 3: + item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kGtin14); + item.SetProductIdentifierValue(CharSpan::fromCharString("gtin14xxxxxxxx")); + break; + case 4: + item.SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum::kOem); + item.SetProductIdentifierValue(CharSpan::fromCharString("oem20xxxxxxxxxxxxxxx")); + break; + default: + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + break; + } + } + mIndex++; + return CHIP_NO_ERROR; +} diff --git a/examples/resource-monitoring-app/resource-monitoring-common/src/StaticReplacementProductListManager.cpp b/examples/resource-monitoring-app/resource-monitoring-common/src/StaticReplacementProductListManager.cpp deleted file mode 100644 index 4c657ff05cc488..00000000000000 --- a/examples/resource-monitoring-app/resource-monitoring-common/src/StaticReplacementProductListManager.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -using namespace chip::app::Clusters; -using namespace chip::app::Clusters::ResourceMonitoring; - -CHIP_ERROR StaticReplacementProductListManager::Next(Attributes::ReplacementProductStruct::Type & item) -{ - if (mIndex < mReplacementProductListSize) - { - item = mReplacementProductsList[mIndex]; - mIndex++; - return CHIP_NO_ERROR; - } - - return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; -} diff --git a/examples/resource-monitoring-app/resource-monitoring-common/src/instances/ActivatedCarbonFilterMonitoring.cpp b/examples/resource-monitoring-app/resource-monitoring-common/src/instances/ActivatedCarbonFilterMonitoring.cpp index 778bb9d6e22dd0..3ab33e675e02a9 100644 --- a/examples/resource-monitoring-app/resource-monitoring-common/src/instances/ActivatedCarbonFilterMonitoring.cpp +++ b/examples/resource-monitoring-app/resource-monitoring-common/src/instances/ActivatedCarbonFilterMonitoring.cpp @@ -32,19 +32,15 @@ using namespace chip; using namespace chip::app::Clusters; using namespace chip::app::Clusters::ActivatedCarbonFilterMonitoring; using namespace chip::app::Clusters::ResourceMonitoring; +using namespace chip::app::Clusters::ResourceMonitoring::Attributes; using chip::Protocols::InteractionModel::Status; -static ResourceMonitoring::Attributes::ReplacementProductStruct::Type sActivatedCarbonFilterReplacementProductsList[] = { - { .productIdentifierType = ResourceMonitoring::ProductIdentifierTypeEnum::kUpc, - .productIdentifierValue = CharSpan::fromCharString("111112222233") }, - { .productIdentifierType = ResourceMonitoring::ProductIdentifierTypeEnum::kGtin8, - .productIdentifierValue = CharSpan::fromCharString("gtin8xca") }, - { .productIdentifierType = ResourceMonitoring::ProductIdentifierTypeEnum::kEan, - .productIdentifierValue = CharSpan::fromCharString("4444455555666") }, - { .productIdentifierType = ResourceMonitoring::ProductIdentifierTypeEnum::kGtin14, - .productIdentifierValue = CharSpan::fromCharString("gtin14xcarbonx") }, - { .productIdentifierType = ResourceMonitoring::ProductIdentifierTypeEnum::kOem, - .productIdentifierValue = CharSpan::fromCharString("oem20xcarbonxxxxxxxx") }, +static ReplacementProductStruct sActivatedCarbonFilterReplacementProductsList[] = { + { ResourceMonitoring::ProductIdentifierTypeEnum::kUpc, CharSpan::fromCharString("111112222233") }, + { ResourceMonitoring::ProductIdentifierTypeEnum::kGtin8, CharSpan::fromCharString("gtin8xca") }, + { ResourceMonitoring::ProductIdentifierTypeEnum::kEan, CharSpan::fromCharString("4444455555666") }, + { ResourceMonitoring::ProductIdentifierTypeEnum::kGtin14, CharSpan::fromCharString("gtin14xcarbonx") }, + { ResourceMonitoring::ProductIdentifierTypeEnum::kOem, CharSpan::fromCharString("oem20xcarbonxxxxxxxx") }, }; StaticReplacementProductListManager sActivatedCarbonFilterReplacementProductListManager(&sActivatedCarbonFilterReplacementProductsList[0], diff --git a/examples/resource-monitoring-app/resource-monitoring-common/src/instances/HepafilterMonitoring.cpp b/examples/resource-monitoring-app/resource-monitoring-common/src/instances/HepafilterMonitoring.cpp index c0ee95ed7c02ff..6404f973a95097 100644 --- a/examples/resource-monitoring-app/resource-monitoring-common/src/instances/HepafilterMonitoring.cpp +++ b/examples/resource-monitoring-app/resource-monitoring-common/src/instances/HepafilterMonitoring.cpp @@ -16,7 +16,7 @@ * limitations under the License. */ -#include +#include #include #include #include @@ -31,22 +31,10 @@ using namespace chip; using namespace chip::app::Clusters; using namespace chip::app::Clusters::ResourceMonitoring; +using namespace chip::app::Clusters::ResourceMonitoring::Attributes; using chip::Protocols::InteractionModel::Status; -static ResourceMonitoring::Attributes::ReplacementProductStruct::Type sHepaFilterReplacementProductsList[] = { - { .productIdentifierType = ResourceMonitoring::ProductIdentifierTypeEnum::kUpc, - .productIdentifierValue = CharSpan::fromCharString("111112222233") }, - { .productIdentifierType = ResourceMonitoring::ProductIdentifierTypeEnum::kGtin8, - .productIdentifierValue = CharSpan::fromCharString("gtin8xhe") }, - { .productIdentifierType = ResourceMonitoring::ProductIdentifierTypeEnum::kEan, - .productIdentifierValue = CharSpan::fromCharString("4444455555666") }, - { .productIdentifierType = ResourceMonitoring::ProductIdentifierTypeEnum::kGtin14, - .productIdentifierValue = CharSpan::fromCharString("gtin14xhepaxxx") }, - { .productIdentifierType = ResourceMonitoring::ProductIdentifierTypeEnum::kOem, - .productIdentifierValue = CharSpan::fromCharString("oem20xhepaxxxxxxxxxx") }, -}; -StaticReplacementProductListManager sHepaFilterReplacementProductListManager(&sHepaFilterReplacementProductsList[0], - ArraySize(sHepaFilterReplacementProductsList)); +static ImmutableReplacementProductListManager sHepaFilterReplacementProductListManager; //-- Hepa filter Monitoring instance methods CHIP_ERROR HepaFilterMonitoringInstance::AppInit() diff --git a/src/app/clusters/resource-monitoring-server/replacement-product-list-manager.h b/src/app/clusters/resource-monitoring-server/replacement-product-list-manager.h index b252597306c21a..bd63dabca180c9 100644 --- a/src/app/clusters/resource-monitoring-server/replacement-product-list-manager.h +++ b/src/app/clusters/resource-monitoring-server/replacement-product-list-manager.h @@ -34,15 +34,24 @@ namespace ResourceMonitoring { class ReplacementProductListManager { public: + // The max replacement product list size as defined in the specification + static constexpr size_t kReplacementProductListMaxSize = 5u; + ReplacementProductListManager() {} virtual ~ReplacementProductListManager() = default; void Reset() { mIndex = 0; } - // Returns total size of Replacement Products List. - virtual uint8_t Size() = 0; - - virtual CHIP_ERROR Next(Attributes::ReplacementProductStruct::Type & item) = 0; + /** + * Iterates through the entries in the ReplacementProductListManager. Each call to this function copies the next item into + * the out param. Calls to this function will return CHIP_NO_ERROR if there are still valid elements in the list. The function + * will return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the end of the list has been reached. + * + * @param[out] item An out parameter that has a copy of the item retrieved in the list. + * @return CHIP_NO_ERROR if the pointer to the list element has moved to the next element and there are still valid remaining + * entries in the list. Otherwise returns CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the list has hit the last element. + */ + virtual CHIP_ERROR Next(ReplacementProductStruct & item) = 0; protected: uint8_t mIndex; diff --git a/src/app/clusters/resource-monitoring-server/resource-monitoring-cluster-objects.cpp b/src/app/clusters/resource-monitoring-server/resource-monitoring-cluster-objects.cpp index 932c95ce3a77ee..34388cba90c4d9 100644 --- a/src/app/clusters/resource-monitoring-server/resource-monitoring-cluster-objects.cpp +++ b/src/app/clusters/resource-monitoring-server/resource-monitoring-cluster-objects.cpp @@ -44,22 +44,6 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } // namespace ResetCondition. } // namespace Commands -namespace Attributes { -namespace ReplacementProductStruct { - -CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const -{ - TLV::TLVType outer; - ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer)); - ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(Fields::kProductIdentifierType), productIdentifierType)); - ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(Fields::kProductIdentifierValue), productIdentifierValue)); - ReturnErrorOnFailure(writer.EndContainer(outer)); - return CHIP_NO_ERROR; -} - -} // namespace ReplacementProductStruct -} // namespace Attributes - } // namespace ResourceMonitoring } // namespace Clusters } // namespace app diff --git a/src/app/clusters/resource-monitoring-server/resource-monitoring-cluster-objects.h b/src/app/clusters/resource-monitoring-server/resource-monitoring-cluster-objects.h index 995f42b6dc4d7c..970a85c957bdf3 100644 --- a/src/app/clusters/resource-monitoring-server/resource-monitoring-cluster-objects.h +++ b/src/app/clusters/resource-monitoring-server/resource-monitoring-cluster-objects.h @@ -29,7 +29,9 @@ namespace app { namespace Clusters { namespace ResourceMonitoring { -static constexpr std::array AliasedClusters = { HepaFilterMonitoring::Id, ActivatedCarbonFilterMonitoring::Id }; +// max of 20 characters as defined by the constraint on the ProductIdentifierValue in the specification +static constexpr size_t kProductIdentifierValueMaxNameLength = 20u; +static constexpr std::array AliasedClusters = { HepaFilterMonitoring::Id, ActivatedCarbonFilterMonitoring::Id }; // Enum for ChangeIndicationEnum enum class ChangeIndicationEnum : uint8_t @@ -74,6 +76,74 @@ enum class ProductIdentifierTypeEnum : uint8_t kOem = 0x04 }; +// A struct used during reads of the ReplacementProductList to store a single list instance we request +// from the application. +// +// Inherit from an auto-generated struct to pick up the implementation bits, but make +// it private inheritance so people can't accidentally use this struct where the other +// is expected. +struct ReplacementProductStruct : private HepaFilterMonitoring::Structs::ReplacementProductStruct::Type +{ +private: + char productIdentifierValueBuffer[kProductIdentifierValueMaxNameLength]; + +public: + static constexpr bool kIsFabricScoped = false; + virtual ~ReplacementProductStruct() = default; + ReplacementProductStruct() {} + ReplacementProductStruct(ResourceMonitoring::ProductIdentifierTypeEnum aProductIdentifierType, + chip::CharSpan aProductIdentifierValue) + { + SetProductIdentifierType(aProductIdentifierType); + SetProductIdentifierValue(aProductIdentifierValue); + } + + ReplacementProductStruct & operator=(const ReplacementProductStruct & aReplacementProductStruct) + { + SetProductIdentifierType(aReplacementProductStruct.GetProductIdentifierType()); + SetProductIdentifierValue(aReplacementProductStruct.GetProductIdentifierValue()); + return *this; + } + + using HepaFilterMonitoring::Structs::ReplacementProductStruct::Type::Encode; + + /** + * Sets the product identifier type. + * + * @param aProductIdentifierType The product identifier type. + */ + void SetProductIdentifierType(ResourceMonitoring::ProductIdentifierTypeEnum aProductIdentifierType) + { + productIdentifierType = static_cast(aProductIdentifierType); + } + + /** + * Sets the product identifier value. + * This implementation will copy the argument into this struct's buffer. + * + * @param aProductIdentifierValue The value of the product identifier to set. + * @return CHIP_ERROR_INVALID_ARGUMENT when aProductIdentifierValue is invalid + * or the size exceeds kProductIdentifierValueMaxNameLength, returns CHIP_NO_ERROR + * otherwise. + */ + CHIP_ERROR SetProductIdentifierValue(chip::CharSpan aProductIdentifierValue) + { + VerifyOrReturnError(IsSpanUsable(aProductIdentifierValue), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(aProductIdentifierValue.size() <= sizeof(productIdentifierValueBuffer), CHIP_ERROR_INVALID_ARGUMENT); + + memcpy(productIdentifierValueBuffer, aProductIdentifierValue.data(), aProductIdentifierValue.size()); + productIdentifierValue = CharSpan(productIdentifierValueBuffer, aProductIdentifierValue.size()); + + return CHIP_NO_ERROR; + } + + ProductIdentifierTypeEnum GetProductIdentifierType() const + { + return static_cast(productIdentifierType); + }; + chip::CharSpan GetProductIdentifierValue() const { return productIdentifierValue; }; +}; + namespace Attributes { namespace Condition { @@ -141,42 +211,9 @@ struct TypeInfo }; } // namespace LastChangedTime -namespace ReplacementProductStruct { -enum class Fields : uint8_t -{ - kProductIdentifierType = 0, - kProductIdentifierValue = 1, -}; - -struct Type -{ -public: - ProductIdentifierTypeEnum productIdentifierType = static_cast(0); - chip::CharSpan productIdentifierValue; - - CHIP_ERROR Decode(TLV::TLVReader & reader); - - static constexpr bool kIsFabricScoped = false; - - CHIP_ERROR Encode(TLV::TLVWriter & writer, TLV::Tag tag) const; -}; - -using DecodableType = Type; - -} // namespace ReplacementProductStruct - namespace ReplacementProductList { static constexpr AttributeId Id = 0x00000005; -struct TypeInfo -{ - using Type = chip::app::DataModel::List; - using DecodableType = chip::app::DataModel::DecodableList; - using DecodableArgType = const chip::app::DataModel::DecodableList &; - - static constexpr AttributeId GetAttributeId() { return Attributes::ReplacementProductList::Id; } - static constexpr bool MustUseTimedWrite() { return false; } -}; -} // namespace ReplacementProductList +} namespace GeneratedCommandList { static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; diff --git a/src/app/clusters/resource-monitoring-server/resource-monitoring-server.cpp b/src/app/clusters/resource-monitoring-server/resource-monitoring-server.cpp index 2cbcb433a23f42..c5687467d00ca0 100644 --- a/src/app/clusters/resource-monitoring-server/resource-monitoring-server.cpp +++ b/src/app/clusters/resource-monitoring-server/resource-monitoring-server.cpp @@ -244,10 +244,10 @@ CHIP_ERROR Instance::EnumerateAcceptedCommands(const ConcreteClusterPath & clust CHIP_ERROR Instance::ReadReplacableProductList(AttributeValueEncoder & aEncoder) { - CHIP_ERROR err; - if (Instance::HasFeature(ResourceMonitoring::Feature::kReplacementProductList)) + CHIP_ERROR err = CHIP_NO_ERROR; + if (HasFeature(ResourceMonitoring::Feature::kReplacementProductList)) { - ReplacementProductListManager * productListManagerInstance = Instance::GetReplacementProductListManagerInstance(); + ReplacementProductListManager * productListManagerInstance = GetReplacementProductListManagerInstance(); if (nullptr == productListManagerInstance) { aEncoder.EncodeEmptyList(); @@ -256,16 +256,19 @@ CHIP_ERROR Instance::ReadReplacableProductList(AttributeValueEncoder & aEncoder) productListManagerInstance->Reset(); - err = aEncoder.EncodeList([&](const auto & encoder) -> CHIP_ERROR { - Attributes::ReplacementProductStruct::Type replacementProductStruct; - while (productListManagerInstance->Next(replacementProductStruct) == CHIP_NO_ERROR) + err = aEncoder.EncodeList([productListManagerInstance](const auto & encoder) -> CHIP_ERROR { + ReplacementProductStruct replacementProductStruct; + CHIP_ERROR iteratorError = productListManagerInstance->Next(replacementProductStruct); + + while (CHIP_NO_ERROR == iteratorError) { ReturnErrorOnFailure(encoder.Encode(replacementProductStruct)); + iteratorError = productListManagerInstance->Next(replacementProductStruct); } - return CHIP_NO_ERROR; + return (CHIP_ERROR_PROVIDER_LIST_EXHAUSTED == iteratorError) ? CHIP_NO_ERROR : iteratorError; }); } - return CHIP_NO_ERROR; + return err; } // Implements the read functionality for non-standard attributes. diff --git a/src/app/tests/suites/TestActivatedCarbonFilterMonitoring.yaml b/src/app/tests/suites/TestActivatedCarbonFilterMonitoring.yaml new file mode 100644 index 00000000000000..c47e01fc473bf4 --- /dev/null +++ b/src/app/tests/suites/TestActivatedCarbonFilterMonitoring.yaml @@ -0,0 +1,57 @@ +# 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. + +name: Activated Carbon Filter Monitoring Cluster Tests + +config: + nodeId: 0x12344321 + cluster: "Activated Carbon Filter Monitoring" + endpoint: 1 + +tests: + - label: "Wait for the commissioned device to be retrieved" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "Read Replacement Product List" + command: "readAttribute" + attribute: "ReplacementProductList" + response: + value: + [ + { + ProductIdentifierType: 0, + ProductIdentifierValue: "111112222233", + }, + { + ProductIdentifierType: 1, + ProductIdentifierValue: "gtin8xxx", + }, + { + ProductIdentifierType: 2, + ProductIdentifierValue: "4444455555666", + }, + { + ProductIdentifierType: 3, + ProductIdentifierValue: "gtin14xxxxxxxx", + }, + { + ProductIdentifierType: 4, + ProductIdentifierValue: "oem20xxxxxxxxxxxxxxx", + }, + ] diff --git a/src/app/tests/suites/TestHepaFilterMonitoring.yaml b/src/app/tests/suites/TestHepaFilterMonitoring.yaml new file mode 100644 index 00000000000000..44b79eec8afc5c --- /dev/null +++ b/src/app/tests/suites/TestHepaFilterMonitoring.yaml @@ -0,0 +1,57 @@ +# 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. + +name: HEPA Filter Monitoring Cluster Tests + +config: + nodeId: 0x12344321 + cluster: "HEPA Filter Monitoring" + endpoint: 1 + +tests: + - label: "Wait for the commissioned device to be retrieved" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "Read Replacement Product List" + command: "readAttribute" + attribute: "ReplacementProductList" + response: + value: + [ + { + ProductIdentifierType: 0, + ProductIdentifierValue: "111112222233", + }, + { + ProductIdentifierType: 1, + ProductIdentifierValue: "gtin8xxx", + }, + { + ProductIdentifierType: 2, + ProductIdentifierValue: "4444455555666", + }, + { + ProductIdentifierType: 3, + ProductIdentifierValue: "gtin14xxxxxxxx", + }, + { + ProductIdentifierType: 4, + ProductIdentifierValue: "oem20xxxxxxxxxxxxxxx", + }, + ] diff --git a/src/app/tests/suites/ciTests.json b/src/app/tests/suites/ciTests.json index 377dd568b2aea0..a22aea164ddc76 100644 --- a/src/app/tests/suites/ciTests.json +++ b/src/app/tests/suites/ciTests.json @@ -303,6 +303,8 @@ ], "Scenes": ["Test_TC_S_1_1"], "ResourceMonitoring": [ + "TestActivatedCarbonFilterMonitoring", + "TestHepaFilterMonitoring", "Test_TC_ACFREMON_1_1", "Test_TC_ACFREMON_2_1", "Test_TC_HEPAFREMON_1_1", diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index e800416ec18db5..a07a8e2609fed0 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -322,6 +322,8 @@ class TestList : public Command printf("TestGroupKeyManagementCluster\n"); printf("Test_TC_G_1_1\n"); printf("Test_TC_G_2_1\n"); + printf("TestActivatedCarbonFilterMonitoring\n"); + printf("TestHepaFilterMonitoring\n"); printf("Test_TC_ACFREMON_1_1\n"); printf("Test_TC_ACFREMON_2_1\n"); printf("Test_TC_HEPAFREMON_1_1\n"); @@ -113646,6 +113648,236 @@ class Test_TC_G_2_1Suite : public TestCommand } }; +class TestActivatedCarbonFilterMonitoringSuite : public TestCommand +{ +public: + TestActivatedCarbonFilterMonitoringSuite(CredentialIssuerCommands * credsIssuerConfig) : + TestCommand("TestActivatedCarbonFilterMonitoring", 2, credsIssuerConfig) + { + AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); + AddArgument("cluster", &mCluster); + AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); + AddArgument("timeout", 0, UINT16_MAX, &mTimeout); + } + + ~TestActivatedCarbonFilterMonitoringSuite() {} + + chip::System::Clock::Timeout GetWaitDuration() const override + { + return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds)); + } + +private: + chip::Optional mNodeId; + chip::Optional mCluster; + chip::Optional mEndpoint; + chip::Optional mTimeout; + + chip::EndpointId GetEndpoint(chip::EndpointId endpoint) { return mEndpoint.HasValue() ? mEndpoint.Value() : endpoint; } + + // + // Tests methods + // + + void OnResponse(const chip::app::StatusIB & status, chip::TLV::TLVReader * data) override + { + bool shouldContinue = false; + + switch (mTestIndex - 1) + { + case 0: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + shouldContinue = true; + break; + case 1: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList< + chip::app::Clusters::ActivatedCarbonFilterMonitoring::Structs::ReplacementProductStruct::DecodableType> + value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + { + auto iter_0 = value.begin(); + VerifyOrReturn(CheckNextListItemDecodes("replacementProductList", iter_0, 0)); + VerifyOrReturn( + CheckValue("replacementProductList[0].productIdentifierType", iter_0.GetValue().productIdentifierType, 0U)); + VerifyOrReturn(CheckValueAsString("replacementProductList[0].productIdentifierValue", + iter_0.GetValue().productIdentifierValue, + chip::CharSpan("111112222233", 12))); + VerifyOrReturn(CheckNextListItemDecodes("replacementProductList", iter_0, 1)); + VerifyOrReturn( + CheckValue("replacementProductList[1].productIdentifierType", iter_0.GetValue().productIdentifierType, 1U)); + VerifyOrReturn(CheckValueAsString("replacementProductList[1].productIdentifierValue", + iter_0.GetValue().productIdentifierValue, chip::CharSpan("gtin8xxx", 8))); + VerifyOrReturn(CheckNextListItemDecodes("replacementProductList", iter_0, 2)); + VerifyOrReturn( + CheckValue("replacementProductList[2].productIdentifierType", iter_0.GetValue().productIdentifierType, 2U)); + VerifyOrReturn(CheckValueAsString("replacementProductList[2].productIdentifierValue", + iter_0.GetValue().productIdentifierValue, + chip::CharSpan("4444455555666", 13))); + VerifyOrReturn(CheckNextListItemDecodes("replacementProductList", iter_0, 3)); + VerifyOrReturn( + CheckValue("replacementProductList[3].productIdentifierType", iter_0.GetValue().productIdentifierType, 3U)); + VerifyOrReturn(CheckValueAsString("replacementProductList[3].productIdentifierValue", + iter_0.GetValue().productIdentifierValue, + chip::CharSpan("gtin14xxxxxxxx", 14))); + VerifyOrReturn(CheckNextListItemDecodes("replacementProductList", iter_0, 4)); + VerifyOrReturn( + CheckValue("replacementProductList[4].productIdentifierType", iter_0.GetValue().productIdentifierType, 4U)); + VerifyOrReturn(CheckValueAsString("replacementProductList[4].productIdentifierValue", + iter_0.GetValue().productIdentifierValue, + chip::CharSpan("oem20xxxxxxxxxxxxxxx", 20))); + VerifyOrReturn(CheckNoMoreListItems("replacementProductList", iter_0, 5)); + } + } + break; + default: + LogErrorOnFailure(ContinueOnChipMainThread(CHIP_ERROR_INVALID_ARGUMENT)); + } + + if (shouldContinue) + { + ContinueOnChipMainThread(CHIP_NO_ERROR); + } + } + + CHIP_ERROR DoTestStep(uint16_t testIndex) override + { + using namespace chip::app::Clusters; + switch (testIndex) + { + case 0: { + LogStep(0, "Wait for the commissioned device to be retrieved"); + ListFreer listFreer; + chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value; + value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; + return WaitForCommissionee(kIdentityAlpha, value); + } + case 1: { + LogStep(1, "Read Replacement Product List"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), ActivatedCarbonFilterMonitoring::Id, + ActivatedCarbonFilterMonitoring::Attributes::ReplacementProductList::Id, true, chip::NullOptional); + } + } + return CHIP_NO_ERROR; + } +}; + +class TestHepaFilterMonitoringSuite : public TestCommand +{ +public: + TestHepaFilterMonitoringSuite(CredentialIssuerCommands * credsIssuerConfig) : + TestCommand("TestHepaFilterMonitoring", 2, credsIssuerConfig) + { + AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); + AddArgument("cluster", &mCluster); + AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); + AddArgument("timeout", 0, UINT16_MAX, &mTimeout); + } + + ~TestHepaFilterMonitoringSuite() {} + + chip::System::Clock::Timeout GetWaitDuration() const override + { + return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds)); + } + +private: + chip::Optional mNodeId; + chip::Optional mCluster; + chip::Optional mEndpoint; + chip::Optional mTimeout; + + chip::EndpointId GetEndpoint(chip::EndpointId endpoint) { return mEndpoint.HasValue() ? mEndpoint.Value() : endpoint; } + + // + // Tests methods + // + + void OnResponse(const chip::app::StatusIB & status, chip::TLV::TLVReader * data) override + { + bool shouldContinue = false; + + switch (mTestIndex - 1) + { + case 0: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + shouldContinue = true; + break; + case 1: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + { + chip::app::DataModel::DecodableList< + chip::app::Clusters::HepaFilterMonitoring::Structs::ReplacementProductStruct::DecodableType> + value; + VerifyOrReturn(CheckDecodeValue(chip::app::DataModel::Decode(*data, value))); + { + auto iter_0 = value.begin(); + VerifyOrReturn(CheckNextListItemDecodes("replacementProductList", iter_0, 0)); + VerifyOrReturn( + CheckValue("replacementProductList[0].productIdentifierType", iter_0.GetValue().productIdentifierType, 0U)); + VerifyOrReturn(CheckValueAsString("replacementProductList[0].productIdentifierValue", + iter_0.GetValue().productIdentifierValue, + chip::CharSpan("111112222233", 12))); + VerifyOrReturn(CheckNextListItemDecodes("replacementProductList", iter_0, 1)); + VerifyOrReturn( + CheckValue("replacementProductList[1].productIdentifierType", iter_0.GetValue().productIdentifierType, 1U)); + VerifyOrReturn(CheckValueAsString("replacementProductList[1].productIdentifierValue", + iter_0.GetValue().productIdentifierValue, chip::CharSpan("gtin8xxx", 8))); + VerifyOrReturn(CheckNextListItemDecodes("replacementProductList", iter_0, 2)); + VerifyOrReturn( + CheckValue("replacementProductList[2].productIdentifierType", iter_0.GetValue().productIdentifierType, 2U)); + VerifyOrReturn(CheckValueAsString("replacementProductList[2].productIdentifierValue", + iter_0.GetValue().productIdentifierValue, + chip::CharSpan("4444455555666", 13))); + VerifyOrReturn(CheckNextListItemDecodes("replacementProductList", iter_0, 3)); + VerifyOrReturn( + CheckValue("replacementProductList[3].productIdentifierType", iter_0.GetValue().productIdentifierType, 3U)); + VerifyOrReturn(CheckValueAsString("replacementProductList[3].productIdentifierValue", + iter_0.GetValue().productIdentifierValue, + chip::CharSpan("gtin14xxxxxxxx", 14))); + VerifyOrReturn(CheckNextListItemDecodes("replacementProductList", iter_0, 4)); + VerifyOrReturn( + CheckValue("replacementProductList[4].productIdentifierType", iter_0.GetValue().productIdentifierType, 4U)); + VerifyOrReturn(CheckValueAsString("replacementProductList[4].productIdentifierValue", + iter_0.GetValue().productIdentifierValue, + chip::CharSpan("oem20xxxxxxxxxxxxxxx", 20))); + VerifyOrReturn(CheckNoMoreListItems("replacementProductList", iter_0, 5)); + } + } + break; + default: + LogErrorOnFailure(ContinueOnChipMainThread(CHIP_ERROR_INVALID_ARGUMENT)); + } + + if (shouldContinue) + { + ContinueOnChipMainThread(CHIP_NO_ERROR); + } + } + + CHIP_ERROR DoTestStep(uint16_t testIndex) override + { + using namespace chip::app::Clusters; + switch (testIndex) + { + case 0: { + LogStep(0, "Wait for the commissioned device to be retrieved"); + ListFreer listFreer; + chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value; + value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; + return WaitForCommissionee(kIdentityAlpha, value); + } + case 1: { + LogStep(1, "Read Replacement Product List"); + return ReadAttribute(kIdentityAlpha, GetEndpoint(1), HepaFilterMonitoring::Id, + HepaFilterMonitoring::Attributes::ReplacementProductList::Id, true, chip::NullOptional); + } + } + return CHIP_NO_ERROR; + } +}; + class Test_TC_ACFREMON_1_1Suite : public TestCommand { public: @@ -144954,6 +145186,8 @@ void registerCommandsTests(Commands & commands, CredentialIssuerCommands * creds make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), + make_unique(credsIssuerConfig), + make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), diff --git a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h index 3d69b11871f7b8..125b3516ffbc3d 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h @@ -286,6 +286,8 @@ class TestList : public Command { printf("TestGroupsCluster\n"); printf("TestGroupKeyManagementCluster\n"); printf("Test_TC_G_1_1\n"); + printf("TestActivatedCarbonFilterMonitoring\n"); + printf("TestHepaFilterMonitoring\n"); printf("Test_TC_ACFREMON_1_1\n"); printf("Test_TC_ACFREMON_2_1\n"); printf("Test_TC_HEPAFREMON_1_1\n"); @@ -172696,6 +172698,295 @@ class Test_TC_G_1_1 : public TestCommandBridge { } }; +class TestActivatedCarbonFilterMonitoring : public TestCommandBridge { +public: + // NOLINTBEGIN(clang-analyzer-nullability.NullPassedToNonnull): Test constructor nullability not enforced + TestActivatedCarbonFilterMonitoring() + : TestCommandBridge("TestActivatedCarbonFilterMonitoring") + , mTestIndex(0) + { + AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); + AddArgument("cluster", &mCluster); + AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); + AddArgument("timeout", 0, UINT16_MAX, &mTimeout); + } + // NOLINTEND(clang-analyzer-nullability.NullPassedToNonnull) + + ~TestActivatedCarbonFilterMonitoring() {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (0 == mTestIndex) { + ChipLogProgress(chipTool, " **** Test Start: TestActivatedCarbonFilterMonitoring\n"); + } + + if (mTestCount == mTestIndex) { + ChipLogProgress(chipTool, " **** Test Complete: TestActivatedCarbonFilterMonitoring\n"); + SetCommandExitStatus(CHIP_NO_ERROR); + return; + } + + Wait(); + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) { + case 0: + ChipLogProgress(chipTool, " ***** Test Step 0 : Wait for the commissioned device to be retrieved\n"); + err = TestWaitForTheCommissionedDeviceToBeRetrieved_0(); + break; + case 1: + ChipLogProgress(chipTool, " ***** Test Step 1 : Read Replacement Product List\n"); + err = TestReadReplacementProductList_1(); + break; + } + + if (CHIP_NO_ERROR != err) { + ChipLogError(chipTool, " ***** Test Failure: %s\n", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + + void OnStatusUpdate(const chip::app::StatusIB & status) override + { + switch (mTestIndex - 1) { + case 0: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 1: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + } + + // Go on to the next test. + ContinueOnChipMainThread(CHIP_NO_ERROR); + } + + chip::System::Clock::Timeout GetWaitDuration() const override + { + return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds)); + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 2; + + chip::Optional mNodeId; + chip::Optional mCluster; + chip::Optional mEndpoint; + chip::Optional mTimeout; + + CHIP_ERROR TestWaitForTheCommissionedDeviceToBeRetrieved_0() + { + + chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value; + value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; + return WaitForCommissionee("alpha", value); + } + + CHIP_ERROR TestReadReplacementProductList_1() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device + endpointID:@(1) + queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeReplacementProductListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable err) { + NSLog(@"Read Replacement Product List Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + { + id actualValue = value; + VerifyOrReturn(CheckValue("ReplacementProductList", [actualValue count], static_cast(5))); + VerifyOrReturn(CheckValue("ProductIdentifierType", + ((MTRActivatedCarbonFilterMonitoringClusterReplacementProductStruct *) actualValue[0]).productIdentifierType, + 0U)); + VerifyOrReturn(CheckValueAsString("ProductIdentifierValue", + ((MTRActivatedCarbonFilterMonitoringClusterReplacementProductStruct *) actualValue[0]).productIdentifierValue, + @"111112222233")); + VerifyOrReturn(CheckValue("ProductIdentifierType", + ((MTRActivatedCarbonFilterMonitoringClusterReplacementProductStruct *) actualValue[1]).productIdentifierType, + 1U)); + VerifyOrReturn(CheckValueAsString("ProductIdentifierValue", + ((MTRActivatedCarbonFilterMonitoringClusterReplacementProductStruct *) actualValue[1]).productIdentifierValue, + @"gtin8xxx")); + VerifyOrReturn(CheckValue("ProductIdentifierType", + ((MTRActivatedCarbonFilterMonitoringClusterReplacementProductStruct *) actualValue[2]).productIdentifierType, + 2U)); + VerifyOrReturn(CheckValueAsString("ProductIdentifierValue", + ((MTRActivatedCarbonFilterMonitoringClusterReplacementProductStruct *) actualValue[2]).productIdentifierValue, + @"4444455555666")); + VerifyOrReturn(CheckValue("ProductIdentifierType", + ((MTRActivatedCarbonFilterMonitoringClusterReplacementProductStruct *) actualValue[3]).productIdentifierType, + 3U)); + VerifyOrReturn(CheckValueAsString("ProductIdentifierValue", + ((MTRActivatedCarbonFilterMonitoringClusterReplacementProductStruct *) actualValue[3]).productIdentifierValue, + @"gtin14xxxxxxxx")); + VerifyOrReturn(CheckValue("ProductIdentifierType", + ((MTRActivatedCarbonFilterMonitoringClusterReplacementProductStruct *) actualValue[4]).productIdentifierType, + 4U)); + VerifyOrReturn(CheckValueAsString("ProductIdentifierValue", + ((MTRActivatedCarbonFilterMonitoringClusterReplacementProductStruct *) actualValue[4]).productIdentifierValue, + @"oem20xxxxxxxxxxxxxxx")); + } + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } +}; + +class TestHepaFilterMonitoring : public TestCommandBridge { +public: + // NOLINTBEGIN(clang-analyzer-nullability.NullPassedToNonnull): Test constructor nullability not enforced + TestHepaFilterMonitoring() + : TestCommandBridge("TestHepaFilterMonitoring") + , mTestIndex(0) + { + AddArgument("nodeId", 0, UINT64_MAX, &mNodeId); + AddArgument("cluster", &mCluster); + AddArgument("endpoint", 0, UINT16_MAX, &mEndpoint); + AddArgument("timeout", 0, UINT16_MAX, &mTimeout); + } + // NOLINTEND(clang-analyzer-nullability.NullPassedToNonnull) + + ~TestHepaFilterMonitoring() {} + + /////////// TestCommand Interface ///////// + void NextTest() override + { + CHIP_ERROR err = CHIP_NO_ERROR; + + if (0 == mTestIndex) { + ChipLogProgress(chipTool, " **** Test Start: TestHepaFilterMonitoring\n"); + } + + if (mTestCount == mTestIndex) { + ChipLogProgress(chipTool, " **** Test Complete: TestHepaFilterMonitoring\n"); + SetCommandExitStatus(CHIP_NO_ERROR); + return; + } + + Wait(); + + // Ensure we increment mTestIndex before we start running the relevant + // command. That way if we lose the timeslice after we send the message + // but before our function call returns, we won't end up with an + // incorrect mTestIndex value observed when we get the response. + switch (mTestIndex++) { + case 0: + ChipLogProgress(chipTool, " ***** Test Step 0 : Wait for the commissioned device to be retrieved\n"); + err = TestWaitForTheCommissionedDeviceToBeRetrieved_0(); + break; + case 1: + ChipLogProgress(chipTool, " ***** Test Step 1 : Read Replacement Product List\n"); + err = TestReadReplacementProductList_1(); + break; + } + + if (CHIP_NO_ERROR != err) { + ChipLogError(chipTool, " ***** Test Failure: %s\n", chip::ErrorStr(err)); + SetCommandExitStatus(err); + } + } + + void OnStatusUpdate(const chip::app::StatusIB & status) override + { + switch (mTestIndex - 1) { + case 0: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + case 1: + VerifyOrReturn(CheckValue("status", chip::to_underlying(status.mStatus), 0)); + break; + } + + // Go on to the next test. + ContinueOnChipMainThread(CHIP_NO_ERROR); + } + + chip::System::Clock::Timeout GetWaitDuration() const override + { + return chip::System::Clock::Seconds16(mTimeout.ValueOr(kTimeoutInSeconds)); + } + +private: + std::atomic_uint16_t mTestIndex; + const uint16_t mTestCount = 2; + + chip::Optional mNodeId; + chip::Optional mCluster; + chip::Optional mEndpoint; + chip::Optional mTimeout; + + CHIP_ERROR TestWaitForTheCommissionedDeviceToBeRetrieved_0() + { + + chip::app::Clusters::DelayCommands::Commands::WaitForCommissionee::Type value; + value.nodeId = mNodeId.HasValue() ? mNodeId.Value() : 305414945ULL; + return WaitForCommissionee("alpha", value); + } + + CHIP_ERROR TestReadReplacementProductList_1() + { + + MTRBaseDevice * device = GetDevice("alpha"); + __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device + endpointID:@(1) + queue:mCallbackQueue]; + VerifyOrReturnError(cluster != nil, CHIP_ERROR_INCORRECT_STATE); + + [cluster readAttributeReplacementProductListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable err) { + NSLog(@"Read Replacement Product List Error: %@", err); + + VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); + + { + id actualValue = value; + VerifyOrReturn(CheckValue("ReplacementProductList", [actualValue count], static_cast(5))); + VerifyOrReturn(CheckValue("ProductIdentifierType", + ((MTRHEPAFilterMonitoringClusterReplacementProductStruct *) actualValue[0]).productIdentifierType, 0U)); + VerifyOrReturn(CheckValueAsString("ProductIdentifierValue", + ((MTRHEPAFilterMonitoringClusterReplacementProductStruct *) actualValue[0]).productIdentifierValue, + @"111112222233")); + VerifyOrReturn(CheckValue("ProductIdentifierType", + ((MTRHEPAFilterMonitoringClusterReplacementProductStruct *) actualValue[1]).productIdentifierType, 1U)); + VerifyOrReturn(CheckValueAsString("ProductIdentifierValue", + ((MTRHEPAFilterMonitoringClusterReplacementProductStruct *) actualValue[1]).productIdentifierValue, + @"gtin8xxx")); + VerifyOrReturn(CheckValue("ProductIdentifierType", + ((MTRHEPAFilterMonitoringClusterReplacementProductStruct *) actualValue[2]).productIdentifierType, 2U)); + VerifyOrReturn(CheckValueAsString("ProductIdentifierValue", + ((MTRHEPAFilterMonitoringClusterReplacementProductStruct *) actualValue[2]).productIdentifierValue, + @"4444455555666")); + VerifyOrReturn(CheckValue("ProductIdentifierType", + ((MTRHEPAFilterMonitoringClusterReplacementProductStruct *) actualValue[3]).productIdentifierType, 3U)); + VerifyOrReturn(CheckValueAsString("ProductIdentifierValue", + ((MTRHEPAFilterMonitoringClusterReplacementProductStruct *) actualValue[3]).productIdentifierValue, + @"gtin14xxxxxxxx")); + VerifyOrReturn(CheckValue("ProductIdentifierType", + ((MTRHEPAFilterMonitoringClusterReplacementProductStruct *) actualValue[4]).productIdentifierType, 4U)); + VerifyOrReturn(CheckValueAsString("ProductIdentifierValue", + ((MTRHEPAFilterMonitoringClusterReplacementProductStruct *) actualValue[4]).productIdentifierValue, + @"oem20xxxxxxxxxxxxxxx")); + } + + NextTest(); + }]; + + return CHIP_NO_ERROR; + } +}; + class Test_TC_ACFREMON_1_1 : public TestCommandBridge { public: // NOLINTBEGIN(clang-analyzer-nullability.NullPassedToNonnull): Test constructor nullability not enforced @@ -174471,6 +174762,8 @@ void registerCommandsTests(Commands & commands) make_unique(), make_unique(), make_unique(), + make_unique(), + make_unique(), make_unique(), make_unique(), make_unique(),