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/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 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");