From 5cd5320fc5f93d9ead6c7d98a44b666e1c809c63 Mon Sep 17 00:00:00 2001 From: mideayanghui <106149377+mideayanghui@users.noreply.github.com> Date: Fri, 21 Jul 2023 00:51:14 +0800 Subject: [PATCH 1/2] [OPSTATE] Add OperationalError Event and OperationCompletion Event api (#27990) * Add OperationalError event api for operational state cluster * fix build error * Add OperationCompletion event api for operational state cluster * fix build error * save the zap for all-clusters-app.zap * Restyled by clang-format --------- Co-authored-by: Restyled.io --- .../operational-state-server.cpp | 45 +++++++++++++++++++ .../operational-state-server.h | 15 ++++++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/app/clusters/operational-state-server/operational-state-server.cpp b/src/app/clusters/operational-state-server/operational-state-server.cpp index ec54a41f2b7b60..b3fd2d89523f00 100644 --- a/src/app/clusters/operational-state-server/operational-state-server.cpp +++ b/src/app/clusters/operational-state-server/operational-state-server.cpp @@ -29,7 +29,10 @@ #include #include #include +#include +#include #include +#include #include #include #include @@ -294,3 +297,45 @@ CHIP_ERROR OperationalStateServer::Read(const ConcreteReadAttributePath & aPath, } return CHIP_NO_ERROR; } + +void OperationalStateServer::OnOperationalErrorDetect(const Structs::ErrorStateStruct::Type & aError) +{ + ChipLogDetail(Zcl, "OperationalStateServer: OnOperationalErrorDetect"); + MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, OperationalState::Attributes::OperationalState::Id); + + EventNumber eventNumber; + Events::OperationalError::Type event{ aError }; + EventLogger eventData(event); + ConcreteEventPath path(mEndpointId, mClusterId, event.GetEventId()); + EventManagement & logMgmt = chip::app::EventManagement::GetInstance(); + EventOptions eventOptions; + eventOptions.mPath = path; + eventOptions.mPriority = event.GetPriorityLevel(); + + CHIP_ERROR err = logMgmt.LogEvent(&eventData, eventOptions, eventNumber); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "OperationalStateServer: Failed to record OperationalError event: %" CHIP_ERROR_FORMAT, err.Format()); + } +} + +void OperationalStateServer::OnOperationCompletionDetect(const Events::OperationCompletion::Type & aEvent) +{ + ChipLogDetail(Zcl, "OperationalStateServer: OnOperationCompletionDetect"); + MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, OperationalState::Attributes::OperationalState::Id); + + EventNumber eventNumber; + EventLogger eventData(aEvent); + ConcreteEventPath path(mEndpointId, mClusterId, aEvent.GetEventId()); + EventManagement & logMgmt = chip::app::EventManagement::GetInstance(); + EventOptions eventOptions; + eventOptions.mPath = path; + eventOptions.mPriority = aEvent.GetPriorityLevel(); + + CHIP_ERROR err = logMgmt.LogEvent(&eventData, eventOptions, eventNumber); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "OperationalStateServer: Failed to record OnOperationCompletionDetect event: %" CHIP_ERROR_FORMAT, + err.Format()); + } +} diff --git a/src/app/clusters/operational-state-server/operational-state-server.h b/src/app/clusters/operational-state-server/operational-state-server.h index 247ef3779ffd7a..796fa4cc3640e4 100644 --- a/src/app/clusters/operational-state-server/operational-state-server.h +++ b/src/app/clusters/operational-state-server/operational-state-server.h @@ -60,11 +60,23 @@ class OperationalStateServer : public CommandHandlerInterface, public AttributeA */ void Shutdown(); + /** + * @brief Called when the Node detects a OperationalError has been raised. + * @param aError OperationalError which detects + */ + void OnOperationalErrorDetect(const Structs::ErrorStateStruct::Type & aError); + + /** + * @brief Called when the Node detects a OperationCompletion has been raised. + * @param aEvent OperationCompletion event + */ + void OnOperationCompletionDetect(const Events::OperationCompletion::Type & aEvent); + /** * Creates an operational state cluster instance. The Init() function needs to be called for this instance to be registered and * called by the interaction model at the appropriate times. * @param aEndpointId The endpoint on which this cluster exists. This must match the zap configuration. - * @param aClusterId The ID of the ModeSelect aliased cluster to be instantiated. + * @param aClusterId The ID of the operational state aliased cluster to be instantiated. */ OperationalStateServer(EndpointId aEndpointId, ClusterId aClusterId) : CommandHandlerInterface(MakeOptional(aEndpointId), aClusterId), @@ -113,7 +125,6 @@ class OperationalStateServer : public CommandHandlerInterface, public AttributeA EndpointId mEndpointId; ClusterId mClusterId; }; - } // namespace OperationalState } // namespace Clusters } // namespace app From ddd5861567642398b96e1a2c02a8c200eb6e1a5a Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 20 Jul 2023 13:10:25 -0400 Subject: [PATCH 2/2] Make tlvmeta recognize feature map bitmaps. (#28084) * Make tlvmeta recognize feature map bitmaps. zap does not support per cluster featuremap types because types are global, however we can use naming conventions to select the correct featuremap values. This makes decoded data more user friendly. * Make flake8 happy * Support "Feature" as a name for features * Fix unit tests --------- Co-authored-by: Andrei Litvin --- .../generators/cpp/tlvmeta/__init__.py | 24 ++++++++++++++----- .../cpp-tlvmeta/clusters_meta.cpp | 2 +- src/lib/format/tests/TestDecoding.cpp | 2 +- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/scripts/py_matter_idl/matter_idl/generators/cpp/tlvmeta/__init__.py b/scripts/py_matter_idl/matter_idl/generators/cpp/tlvmeta/__init__.py index 6a567ee122d551..46c7de39498fac 100644 --- a/scripts/py_matter_idl/matter_idl/generators/cpp/tlvmeta/__init__.py +++ b/scripts/py_matter_idl/matter_idl/generators/cpp/tlvmeta/__init__.py @@ -62,14 +62,16 @@ def __init__(self, cluster: Cluster): for b in self.cluster.bitmaps: self.item_type_map[b.name] = "kBitmap" - def FieldEntry(self, field: Field, tag_type: str = 'ContextTag') -> TableEntry: - type_reference = "%s_%s" % (self.cluster.name, field.data_type.name) + def FieldEntry(self, field: Field, tag_type: str = 'ContextTag', type_override: Optional[str] = None) -> TableEntry: + data_type_name = type_override or field.data_type.name + type_reference = "%s_%s" % (self.cluster.name, data_type_name) + if type_reference not in self.known_types: type_reference = None - item_type = self.item_type_map.get(field.data_type.name, 'kDefault') + item_type = self.item_type_map.get(data_type_name, 'kDefault') - real_type = "%s::%s" % (self.cluster.name, field.data_type.name) + real_type = "%s::%s" % (self.cluster.name, data_type_name) if field.is_list: real_type = real_type + "[]" item_type = "kList" @@ -142,11 +144,21 @@ def CommandEntries(self) -> Generator[TableEntry, None, None]: def GenerateTables(self) -> Generator[Table, None, None]: self.ComputeKnownTypes() + cluster_feature_map = None + for b in self.cluster.bitmaps: + # Older matter files use `ClusterNameFeature` as naming, newer code was + # updated to just `Feature`. For now support both. + if b.name in {'Feature', f'{self.cluster.name}Feature'} and b.base_type.lower() == 'bitmap32': + cluster_feature_map = b.name + # Clusters have attributes. They are direct descendants for # attributes cluster_entries = [] - cluster_entries.extend([self.FieldEntry( - a.definition, tag_type='AttributeTag') for a in self.cluster.attributes]) + cluster_entries.extend([ + self.FieldEntry(a.definition, tag_type='AttributeTag', + type_override=(cluster_feature_map if a.definition.code == 0xFFFC else None)) + for a in self.cluster.attributes + ]) cluster_entries.extend([ # events always reference an existing struct diff --git a/scripts/py_matter_idl/matter_idl/tests/outputs/cluster_with_commands/cpp-tlvmeta/clusters_meta.cpp b/scripts/py_matter_idl/matter_idl/tests/outputs/cluster_with_commands/cpp-tlvmeta/clusters_meta.cpp index d96c8564e626dd..66462f8a497554 100644 --- a/scripts/py_matter_idl/matter_idl/tests/outputs/cluster_with_commands/cpp-tlvmeta/clusters_meta.cpp +++ b/scripts/py_matter_idl/matter_idl/tests/outputs/cluster_with_commands/cpp-tlvmeta/clusters_meta.cpp @@ -9,7 +9,7 @@ using namespace chip::TLV; const Entry _OnOff[] = { { { AttributeTag(0), "onOff", ItemType::kDefault }, kInvalidNodeIndex }, // OnOff::boolean - { { AttributeTag(65532), "featureMap", ItemType::kDefault }, kInvalidNodeIndex }, // OnOff::bitmap32 + { { AttributeTag(65532), "featureMap", ItemType::kBitmap }, 8 }, // OnOff::OnOffFeature { { AttributeTag(65533), "clusterRevision", ItemType::kDefault }, kInvalidNodeIndex }, // OnOff::int16u { { CommandTag(0), "Off", ItemType::kDefault }, kInvalidNodeIndex }, // OnOff::Off::() { { CommandTag(1), "On", ItemType::kDefault }, kInvalidNodeIndex }, // OnOff::On::() diff --git a/src/lib/format/tests/TestDecoding.cpp b/src/lib/format/tests/TestDecoding.cpp index e822c6869a82f9..7dfc005e8e5988 100644 --- a/src/lib/format/tests/TestDecoding.cpp +++ b/src/lib/format/tests/TestDecoding.cpp @@ -274,7 +274,7 @@ void TestFullDataDecoding(nlTestSuite * inSuite, void * inContext) " endpoint_id: 0\n" " cluster_id: 49 == 'NetworkCommissioning'\n" " attribute_id: 65532 == 'featureMap'\n" - " NetworkCommissioning::featureMap: 4\n" + " NetworkCommissioning::featureMap: 4 == kEthernetNetworkInterface\n" " suppress_response: true\n" " interaction_model_revison: 1\n");