From 36b6ce6c24d95704408563013889ea0156113eb2 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 10 Dec 2021 10:59:52 -0500 Subject: [PATCH] Use ForAllEndpointsWithServerCluster instead of manual iteration. (#12873) Manual iteration is O(N^2) in number of endpoints. --- .../general-diagnostics-server.cpp | 175 +++++++++--------- 1 file changed, 90 insertions(+), 85 deletions(-) diff --git a/src/app/clusters/general-diagnostics-server/general-diagnostics-server.cpp b/src/app/clusters/general-diagnostics-server/general-diagnostics-server.cpp index a2570a8f5582d3..59f361a1eda6c3 100644 --- a/src/app/clusters/general-diagnostics-server/general-diagnostics-server.cpp +++ b/src/app/clusters/general-diagnostics-server/general-diagnostics-server.cpp @@ -205,113 +205,118 @@ class GeneralDiagnosticsDelegate : public DeviceLayer::ConnectivityManagerDelega ReportAttributeOnAllEndpoints(GeneralDiagnostics::Attributes::BootReasons::Id); } + template + struct TFaults + { + GeneralFaults & previous; + GeneralFaults & current; + }; + // Get called when the Node detects a hardware fault has been raised. - void OnHardwareFaultsDetected(GeneralFaults & previous, - GeneralFaults & current) override + void OnHardwareFaultsDetected(GeneralFaults & previousArg, + GeneralFaults & currentArg) override { ChipLogProgress(Zcl, "GeneralDiagnosticsDelegate: OnHardwareFaultsDetected"); - ReportAttributeOnAllEndpoints(GeneralDiagnostics::Attributes::ActiveHardwareFaults::Id); - - for (uint16_t index = 0; index < emberAfEndpointCount(); index++) - { - if (emberAfEndpointIndexIsEnabled(index)) - { - EndpointId endpointId = emberAfEndpointFromIndex(index); - - if (emberAfContainsServer(endpointId, GeneralDiagnostics::Id)) + using Faults = TFaults; + Faults faults = { previousArg, currentArg }; + ForAllEndpointsWithServerCluster( + GeneralDiagnostics::Id, + [](EndpointId endpointId, intptr_t context) -> Loop { + // If General Diagnostics cluster is implemented on this endpoint + MatterReportingAttributeChangeCallback(endpointId, GeneralDiagnostics::Id, + GeneralDiagnostics::Attributes::ActiveHardwareFaults::Id); + + auto * faultsPtr = reinterpret_cast(context); + auto & current = faultsPtr->current; + auto & previous = faultsPtr->previous; + // Record HardwareFault event + EventNumber eventNumber; + DataModel::List currentList = DataModel::List( + reinterpret_cast(current.data()), current.size()); + DataModel::List previousList = DataModel::List( + reinterpret_cast(previous.data()), previous.size()); + Events::HardwareFaultChange::Type event{ currentList, previousList }; + + if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber, EventOptions::Type::kUrgent)) { - // If General Diagnostics cluster is implemented on this endpoint - MatterReportingAttributeChangeCallback(endpointId, GeneralDiagnostics::Id, - GeneralDiagnostics::Attributes::ActiveHardwareFaults::Id); - - // Record HardwareFault event - EventNumber eventNumber; - DataModel::List currentList = DataModel::List( - reinterpret_cast(current.data()), current.size()); - DataModel::List previousList = DataModel::List( - reinterpret_cast(previous.data()), previous.size()); - Events::HardwareFaultChange::Type event{ currentList, previousList }; - - if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber, EventOptions::Type::kUrgent)) - { - ChipLogError(Zcl, "GeneralDiagnosticsDelegate: Failed to record HardwareFault event"); - } + ChipLogError(Zcl, "GeneralDiagnosticsDelegate: Failed to record HardwareFault event"); } - } - } + + return Loop::Continue; + }, + reinterpret_cast(&faults)); } // Get called when the Node detects a radio fault has been raised. - void OnRadioFaultsDetected(GeneralFaults & previous, GeneralFaults & current) override + void OnRadioFaultsDetected(GeneralFaults & previousArg, GeneralFaults & currentArg) override { ChipLogProgress(Zcl, "GeneralDiagnosticsDelegate: OnHardwareFaultsDetected"); - ReportAttributeOnAllEndpoints(GeneralDiagnostics::Attributes::ActiveRadioFaults::Id); - - for (uint16_t index = 0; index < emberAfEndpointCount(); index++) - { - if (emberAfEndpointIndexIsEnabled(index)) - { - EndpointId endpointId = emberAfEndpointFromIndex(index); - - if (emberAfContainsServer(endpointId, GeneralDiagnostics::Id)) + using Faults = TFaults; + Faults faults = { previousArg, currentArg }; + ForAllEndpointsWithServerCluster( + GeneralDiagnostics::Id, + [](EndpointId endpointId, intptr_t context) -> Loop { + // If General Diagnostics cluster is implemented on this endpoint + MatterReportingAttributeChangeCallback(endpointId, GeneralDiagnostics::Id, + GeneralDiagnostics::Attributes::ActiveRadioFaults::Id); + + auto * faultsPtr = reinterpret_cast(context); + auto & current = faultsPtr->current; + auto & previous = faultsPtr->previous; + // Record RadioFault event + EventNumber eventNumber; + DataModel::List currentList = + DataModel::List(reinterpret_cast(current.data()), current.size()); + DataModel::List previousList = DataModel::List( + reinterpret_cast(previous.data()), previous.size()); + Events::RadioFaultChange::Type event{ currentList, previousList }; + + if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber, EventOptions::Type::kUrgent)) { - // If General Diagnostics cluster is implemented on this endpoint - MatterReportingAttributeChangeCallback(endpointId, GeneralDiagnostics::Id, - GeneralDiagnostics::Attributes::ActiveRadioFaults::Id); - - // Record RadioFault event - EventNumber eventNumber; - DataModel::List currentList = DataModel::List( - reinterpret_cast(current.data()), current.size()); - DataModel::List previousList = DataModel::List( - reinterpret_cast(previous.data()), previous.size()); - Events::RadioFaultChange::Type event{ currentList, previousList }; - - if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber, EventOptions::Type::kUrgent)) - { - ChipLogError(Zcl, "GeneralDiagnosticsDelegate: Failed to record RadioFault event"); - } + ChipLogError(Zcl, "GeneralDiagnosticsDelegate: Failed to record RadioFault event"); } - } - } + + return Loop::Continue; + }, + reinterpret_cast(&faults)); } // Get called when the Node detects a network fault has been raised. - void OnNetworkFaultsDetected(GeneralFaults & previous, GeneralFaults & current) override + void OnNetworkFaultsDetected(GeneralFaults & previousArg, + GeneralFaults & currentArg) override { ChipLogProgress(Zcl, "GeneralDiagnosticsDelegate: OnHardwareFaultsDetected"); - ReportAttributeOnAllEndpoints(GeneralDiagnostics::Attributes::ActiveNetworkFaults::Id); - - for (uint16_t index = 0; index < emberAfEndpointCount(); index++) - { - if (emberAfEndpointIndexIsEnabled(index)) - { - EndpointId endpointId = emberAfEndpointFromIndex(index); - - if (emberAfContainsServer(endpointId, GeneralDiagnostics::Id)) + using Faults = TFaults; + Faults faults = { previousArg, currentArg }; + ForAllEndpointsWithServerCluster( + GeneralDiagnostics::Id, + [](EndpointId endpointId, intptr_t context) -> Loop { + // If General Diagnostics cluster is implemented on this endpoint + MatterReportingAttributeChangeCallback(endpointId, GeneralDiagnostics::Id, + GeneralDiagnostics::Attributes::ActiveNetworkFaults::Id); + + auto * faultsPtr = reinterpret_cast(context); + auto & current = faultsPtr->current; + auto & previous = faultsPtr->previous; + // Record NetworkFault event + EventNumber eventNumber; + DataModel::List currentList = DataModel::List( + reinterpret_cast(current.data()), current.size()); + DataModel::List previousList = DataModel::List( + reinterpret_cast(previous.data()), previous.size()); + Events::NetworkFaultChange::Type event{ currentList, previousList }; + + if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber, EventOptions::Type::kUrgent)) { - // If General Diagnostics cluster is implemented on this endpoint - MatterReportingAttributeChangeCallback(endpointId, GeneralDiagnostics::Id, - GeneralDiagnostics::Attributes::ActiveNetworkFaults::Id); - - // Record NetworkFault event - EventNumber eventNumber; - DataModel::List currentList = DataModel::List( - reinterpret_cast(current.data()), current.size()); - DataModel::List previousList = DataModel::List( - reinterpret_cast(previous.data()), previous.size()); - Events::NetworkFaultChange::Type event{ currentList, previousList }; - - if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber, EventOptions::Type::kUrgent)) - { - ChipLogError(Zcl, "GeneralDiagnosticsDelegate: Failed to record NetworkFault event"); - } + ChipLogError(Zcl, "GeneralDiagnosticsDelegate: Failed to record NetworkFault event"); } - } - } + + return Loop::Continue; + }, + reinterpret_cast(&faults)); } };