| /** |
| * |
| * 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. |
| */ |
| |
| #include <app-common/zap-generated/attributes/Accessors.h> |
| #include <app-common/zap-generated/cluster-objects.h> |
| #include <app-common/zap-generated/ids/Attributes.h> |
| #include <app-common/zap-generated/ids/Clusters.h> |
| #include <app/AttributeAccessInterface.h> |
| #include <app/CommandHandler.h> |
| #include <app/ConcreteCommandPath.h> |
| #include <app/util/af.h> |
| #include <app/util/attribute-storage.h> |
| #include <lib/core/Optional.h> |
| #include <platform/DiagnosticDataProvider.h> |
| |
| using namespace chip; |
| using namespace chip::app; |
| using namespace chip::app::Clusters; |
| using namespace chip::app::Clusters::EthernetNetworkDiagnostics; |
| using namespace chip::app::Clusters::EthernetNetworkDiagnostics::Attributes; |
| using chip::DeviceLayer::DiagnosticDataProvider; |
| |
| namespace { |
| |
| class EthernetDiagosticsAttrAccess : public AttributeAccessInterface |
| { |
| public: |
| // Register for the EthernetNetworkDiagnostics cluster on all endpoints. |
| EthernetDiagosticsAttrAccess() : AttributeAccessInterface(Optional<EndpointId>::Missing(), EthernetNetworkDiagnostics::Id) {} |
| |
| CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; |
| |
| private: |
| template <typename T> |
| CHIP_ERROR ReadIfSupported(CHIP_ERROR (DiagnosticDataProvider::*getter)(T &), AttributeValueEncoder & aEncoder); |
| |
| CHIP_ERROR ReadPHYRate(AttributeValueEncoder & aEncoder); |
| CHIP_ERROR ReadFullDuplex(AttributeValueEncoder & aEncoder); |
| CHIP_ERROR ReadCarrierDetect(AttributeValueEncoder & aEncoder); |
| }; |
| |
| template <typename T> |
| CHIP_ERROR EthernetDiagosticsAttrAccess::ReadIfSupported(CHIP_ERROR (DiagnosticDataProvider::*getter)(T &), |
| AttributeValueEncoder & aEncoder) |
| { |
| T data; |
| CHIP_ERROR err = (DeviceLayer::GetDiagnosticDataProvider().*getter)(data); |
| if (err == CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE) |
| { |
| data = 0; |
| } |
| else if (err != CHIP_NO_ERROR) |
| { |
| return err; |
| } |
| |
| return aEncoder.Encode(data); |
| } |
| |
| CHIP_ERROR EthernetDiagosticsAttrAccess::ReadPHYRate(AttributeValueEncoder & aEncoder) |
| { |
| Attributes::PHYRate::TypeInfo::Type pHYRate; |
| auto value = EmberAfPHYRateEnum::EMBER_ZCL_PHY_RATE_ENUM_RATE10_M; |
| |
| if (DeviceLayer::GetDiagnosticDataProvider().GetEthPHYRate(value) == CHIP_NO_ERROR) |
| { |
| pHYRate.SetNonNull(value); |
| ChipLogProgress(Zcl, "The current nominal, usable speed at the top of the physical layer of the Node: %d", value); |
| } |
| else |
| { |
| ChipLogProgress(Zcl, "The Ethernet interface is not currently configured or operational"); |
| } |
| |
| return aEncoder.Encode(pHYRate); |
| } |
| |
| CHIP_ERROR EthernetDiagosticsAttrAccess::ReadFullDuplex(AttributeValueEncoder & aEncoder) |
| { |
| Attributes::FullDuplex::TypeInfo::Type fullDuplex; |
| bool value = false; |
| |
| if (DeviceLayer::GetDiagnosticDataProvider().GetEthFullDuplex(value) == CHIP_NO_ERROR) |
| { |
| fullDuplex.SetNonNull(value); |
| ChipLogProgress(Zcl, "The full-duplex operating status of Node: %d", value); |
| } |
| else |
| { |
| ChipLogProgress(Zcl, "The Ethernet interface is not currently configured or operational"); |
| } |
| |
| return aEncoder.Encode(fullDuplex); |
| } |
| |
| CHIP_ERROR EthernetDiagosticsAttrAccess::ReadCarrierDetect(AttributeValueEncoder & aEncoder) |
| { |
| Attributes::CarrierDetect::TypeInfo::Type carrierDetect; |
| bool value = false; |
| |
| if (DeviceLayer::GetDiagnosticDataProvider().GetEthCarrierDetect(value) == CHIP_NO_ERROR) |
| { |
| carrierDetect.SetNonNull(value); |
| ChipLogProgress(Zcl, "The status of the Carrier Detect control signal present on the ethernet network interface: %d", |
| value); |
| } |
| else |
| { |
| ChipLogProgress(Zcl, "The Ethernet interface is not currently configured or operational"); |
| } |
| |
| return aEncoder.Encode(carrierDetect); |
| } |
| |
| EthernetDiagosticsAttrAccess gAttrAccess; |
| |
| CHIP_ERROR EthernetDiagosticsAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) |
| { |
| if (aPath.mClusterId != EthernetNetworkDiagnostics::Id) |
| { |
| // We shouldn't have been called at all. |
| return CHIP_ERROR_INVALID_ARGUMENT; |
| } |
| |
| switch (aPath.mAttributeId) |
| { |
| case Attributes::PHYRate::Id: { |
| return ReadPHYRate(aEncoder); |
| } |
| case FullDuplex::Id: { |
| return ReadFullDuplex(aEncoder); |
| } |
| case CarrierDetect::Id: { |
| return ReadCarrierDetect(aEncoder); |
| } |
| case TimeSinceReset::Id: { |
| return ReadIfSupported(&DiagnosticDataProvider::GetEthTimeSinceReset, aEncoder); |
| } |
| case PacketRxCount::Id: { |
| return ReadIfSupported(&DiagnosticDataProvider::GetEthPacketRxCount, aEncoder); |
| } |
| case PacketTxCount::Id: { |
| return ReadIfSupported(&DiagnosticDataProvider::GetEthPacketTxCount, aEncoder); |
| } |
| case TxErrCount::Id: { |
| return ReadIfSupported(&DiagnosticDataProvider::GetEthTxErrCount, aEncoder); |
| } |
| case CollisionCount::Id: { |
| return ReadIfSupported(&DiagnosticDataProvider::GetEthCollisionCount, aEncoder); |
| } |
| case OverrunCount::Id: { |
| return ReadIfSupported(&DiagnosticDataProvider::GetEthOverrunCount, aEncoder); |
| } |
| default: { |
| break; |
| } |
| } |
| return CHIP_NO_ERROR; |
| } |
| } // anonymous namespace |
| |
| bool emberAfEthernetNetworkDiagnosticsClusterResetCountsCallback(app::CommandHandler * commandObj, |
| const app::ConcreteCommandPath & commandPath, |
| const Commands::ResetCounts::DecodableType & commandData) |
| { |
| DeviceLayer::GetDiagnosticDataProvider().ResetEthNetworkDiagnosticsCounts(); |
| commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::Success); |
| |
| return true; |
| } |
| |
| void MatterEthernetNetworkDiagnosticsPluginServerInitCallback() |
| { |
| registerAttributeAccessOverride(&gAttrAccess); |
| } |