From aff8e2e7745128d29aa72641f668824f9f4ccc78 Mon Sep 17 00:00:00 2001 From: PSONALl Date: Tue, 21 Nov 2023 15:39:29 +0530 Subject: [PATCH] Add ethernet network diagnostics cluster --- .../esp_matter/esp_matter_attribute.cpp | 54 ++++++++++++++++++ components/esp_matter/esp_matter_attribute.h | 14 +++++ .../esp_matter/esp_matter_attribute_utils.cpp | 24 +++++++- .../esp_matter/esp_matter_attribute_utils.h | 2 + components/esp_matter/esp_matter_cluster.cpp | 41 ++++++++++++-- components/esp_matter/esp_matter_cluster.h | 9 +++ components/esp_matter/esp_matter_command.cpp | 24 ++++++++ components/esp_matter/esp_matter_command.h | 6 ++ components/esp_matter/esp_matter_feature.cpp | 55 +++++++++++++++++++ components/esp_matter/esp_matter_feature.h | 33 +++++++++++ 10 files changed, 257 insertions(+), 5 deletions(-) diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index bedd99f39..b894e04f3 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -801,6 +801,60 @@ attribute_t *create_active_network_faults(cluster_t *cluster, uint8_t *value, ui } /* attribute */ } /* diagnostics_network_thread */ +namespace diagnostics_network_ethernet { +namespace attribute { + +attribute_t *create_phy_rate(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EthernetNetworkDiagnostics::Attributes::PHYRate::Id, + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_enum8(value)); +} + +attribute_t *create_full_duplex(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EthernetNetworkDiagnostics::Attributes::FullDuplex::Id, + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_bool(value)); +} + +attribute_t *create_packet_rx_count(cluster_t *cluster, uint64_t value) +{ + return esp_matter::attribute::create(cluster, EthernetNetworkDiagnostics::Attributes::PacketRxCount::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_uint64(value)); +} + +attribute_t *create_packet_tx_count(cluster_t *cluster, uint64_t value) +{ + return esp_matter::attribute::create(cluster, EthernetNetworkDiagnostics::Attributes::PacketTxCount::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_uint64(value)); +} + +attribute_t *create_collision_count(cluster_t *cluster, uint64_t value) +{ + return esp_matter::attribute::create(cluster, EthernetNetworkDiagnostics::Attributes::CollisionCount::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_uint64(value)); +} + +attribute_t *create_overrun_count(cluster_t *cluster, uint64_t value) +{ + return esp_matter::attribute::create(cluster, EthernetNetworkDiagnostics::Attributes::OverrunCount::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_uint64(value)); +} + +attribute_t *create_carrier_detect(cluster_t *cluster, nullable value) +{ + return esp_matter::attribute::create(cluster, EthernetNetworkDiagnostics::Attributes::CarrierDetect::Id, + ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_bool(value)); +} + +attribute_t *create_time_since_reset(cluster_t *cluster, uint64_t value) +{ + return esp_matter::attribute::create(cluster, EthernetNetworkDiagnostics::Attributes::TimeSinceReset::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_uint64(value)); +} + +} /* attribute */ +} /* diagnostics_network_ethernet */ + namespace bridged_device_basic_information { namespace attribute { diff --git a/components/esp_matter/esp_matter_attribute.h b/components/esp_matter/esp_matter_attribute.h index 887072680..06ffd0e3c 100644 --- a/components/esp_matter/esp_matter_attribute.h +++ b/components/esp_matter/esp_matter_attribute.h @@ -228,6 +228,20 @@ attribute_t *create_active_network_faults(cluster_t *cluster, uint8_t *value, ui } /* attribute */ } /* diagnostics_network_thread */ +namespace diagnostics_network_ethernet { +namespace attribute { +attribute_t *create_phy_rate(cluster_t *cluster, nullable value); +attribute_t *create_full_duplex(cluster_t *cluster, nullable value); +attribute_t *create_packet_rx_count(cluster_t *cluster, uint64_t value); +attribute_t *create_packet_tx_count(cluster_t *cluster, uint64_t value); +attribute_t *create_tx_error_count(cluster_t *cluster, uint64_t value); +attribute_t *create_collision_count(cluster_t *cluster, uint64_t value); +attribute_t *create_overrun_count(cluster_t *cluster, uint64_t value); +attribute_t *create_carrier_detect(cluster_t *cluster, nullable value); +attribute_t *create_time_since_reset(cluster_t *cluster, uint64_t value); +} /* attribute */ +} /* diagnostics_network_ethernet */ + namespace bridged_device_basic_information { constexpr uint8_t k_max_node_label_length = 32; diff --git a/components/esp_matter/esp_matter_attribute_utils.cpp b/components/esp_matter/esp_matter_attribute_utils.cpp index 1213de4f2..3964fac55 100644 --- a/components/esp_matter/esp_matter_attribute_utils.cpp +++ b/components/esp_matter/esp_matter_attribute_utils.cpp @@ -66,6 +66,20 @@ esp_matter_attr_val_t esp_matter_int(int val) return attr_val; } +esp_matter_attr_val_t esp_matter_nullable_bool(nullable val) +{ + esp_matter_attr_val_t attr_val = { + .type = ESP_MATTER_VAL_TYPE_NULLABLE_BOOLEAN, + }; + if (val.is_null()) { + chip::app::NumericAttributeTraits::SetNull(*(uint8_t *)(&(attr_val.val.b))); + } + else { + attr_val.val.b = val.value(); + } + return attr_val; +} + esp_matter_attr_val_t esp_matter_nullable_int(nullable val) { esp_matter_attr_val_t attr_val = { @@ -1101,6 +1115,9 @@ static esp_matter_val_type_t get_val_type_from_attribute_type(int attribute_type bool val_is_null(esp_matter_attr_val_t *val) { switch (val->type) { + case ESP_MATTER_VAL_TYPE_NULLABLE_BOOLEAN: + return chip::app::NumericAttributeTraits::IsNullValue(*(uint8_t *)(&(val->val.b))); + break; case ESP_MATTER_VAL_TYPE_NULLABLE_INTEGER: return chip::app::NumericAttributeTraits::IsNullValue(val->val.i); break; @@ -1148,6 +1165,7 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp { switch (val->type) { case ESP_MATTER_VAL_TYPE_BOOLEAN: + case ESP_MATTER_VAL_TYPE_NULLABLE_BOOLEAN: if (attribute_type) { *attribute_type = ZCL_BOOLEAN_ATTRIBUTE_TYPE; } @@ -1156,7 +1174,11 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp } if (value) { using Traits = chip::app::NumericAttributeTraits; - Traits::WorkingToStorage(val->val.b, *value); + if ((val->type & ESP_MATTER_VAL_NULLABLE_BASE) && Traits::IsNullValue(*(uint8_t *)(&(val->val.b)))) { + Traits::SetNull(*(uint8_t *)value); + } else { + Traits::WorkingToStorage(val->val.b, *(uint8_t *)value); + } } break; diff --git a/components/esp_matter/esp_matter_attribute_utils.h b/components/esp_matter/esp_matter_attribute_utils.h index d591df6aa..c04304b6d 100644 --- a/components/esp_matter/esp_matter_attribute_utils.h +++ b/components/esp_matter/esp_matter_attribute_utils.h @@ -86,6 +86,7 @@ typedef enum { ESP_MATTER_VAL_TYPE_LONG_OCTET_STRING = 21, /** nullable types **/ + ESP_MATTER_VAL_TYPE_NULLABLE_BOOLEAN = ESP_MATTER_VAL_TYPE_BOOLEAN + ESP_MATTER_VAL_NULLABLE_BASE, ESP_MATTER_VAL_TYPE_NULLABLE_INTEGER = ESP_MATTER_VAL_TYPE_INTEGER + ESP_MATTER_VAL_NULLABLE_BASE, ESP_MATTER_VAL_TYPE_NULLABLE_FLOAT = ESP_MATTER_VAL_TYPE_FLOAT + ESP_MATTER_VAL_NULLABLE_BASE, ESP_MATTER_VAL_TYPE_NULLABLE_INT8 = ESP_MATTER_VAL_TYPE_INT8 + ESP_MATTER_VAL_NULLABLE_BASE, @@ -240,6 +241,7 @@ private: esp_matter_attr_val_t esp_matter_invalid(void *val); /** Boolean */ esp_matter_attr_val_t esp_matter_bool(bool val); +esp_matter_attr_val_t esp_matter_nullable_bool(nullable val); /** Integer */ esp_matter_attr_val_t esp_matter_int(int val); diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index 937116850..781085413 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -780,6 +780,43 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) } } /* diagnostics_network_thread */ +namespace diagnostics_network_ethernet { +const function_generic_t *function_list = NULL; +const int function_flags = CLUSTER_FLAG_NONE; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) +{ + cluster_t *cluster = cluster::create(endpoint, EthernetNetworkDiagnostics::Id, flags); + if (!cluster) { + ESP_LOGE(TAG, "Could not create cluster"); + return NULL; + } + if (flags & CLUSTER_FLAG_SERVER) { + static const auto plugin_server_init_cb = CALL_ONCE(MatterEthernetNetworkDiagnosticsPluginServerInitCallback); + set_plugin_server_init_callback(cluster, plugin_server_init_cb); + add_function_list(cluster, function_list, function_flags); + + /* Attributes managed internally */ + global::attribute::create_feature_map(cluster, 0); +#if CHIP_CONFIG_ENABLE_EVENTLIST_ATTRIBUTE + global::attribute::create_event_list(cluster, NULL, 0, 0); +#endif + + /* Attributes not managed internally */ + if (config) { + global::attribute::create_cluster_revision(cluster, config->cluster_revision); + } else { + ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); + } + } + + /* Commands */ + command::create_reset_counts(cluster); + + return cluster; +} +} /* diagnostics_network_ethernet */ + namespace time_synchronization { const function_generic_t *function_list = NULL; const int function_flags = CLUSTER_FLAG_NONE; @@ -3149,10 +3186,6 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) // // ToDo // } /* powersource_configuration */ -// namespace ethernet_network_diagnostics { -// // ToDo -// } /* ethernet_network_diagnostics */ - // namespace proxy_configuration { // // ToDo // } /* proxy_configuration */ diff --git a/components/esp_matter/esp_matter_cluster.h b/components/esp_matter/esp_matter_cluster.h index 989dfb009..c6eefed99 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -198,6 +198,15 @@ typedef struct config { cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); } /* diagnostics_network_thread */ +namespace diagnostics_network_ethernet { +typedef struct config { + uint16_t cluster_revision; + config() : cluster_revision(1) {} +} config_t; + +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); +} /* diagnostics_network_ethernet */ + namespace time_synchronization { typedef struct config { uint16_t cluster_revision; diff --git a/components/esp_matter/esp_matter_command.cpp b/components/esp_matter/esp_matter_command.cpp index 94b8ee988..6dac25220 100644 --- a/components/esp_matter/esp_matter_command.cpp +++ b/components/esp_matter/esp_matter_command.cpp @@ -948,6 +948,18 @@ static esp_err_t esp_matter_command_callback_wifi_reset_counts(const ConcreteCom return ESP_OK; } +static esp_err_t esp_matter_command_callback_ethernet_reset_counts(const ConcreteCommandPath &command_path, + TLVReader &tlv_data, void *opaque_ptr) +{ + chip::app::Clusters::EthernetNetworkDiagnostics::Commands::ResetCounts::DecodableType command_data; + CHIP_ERROR error = Decode(tlv_data, command_data); + if (error == CHIP_NO_ERROR) { + emberAfEthernetNetworkDiagnosticsClusterResetCountsCallback((CommandHandler *)opaque_ptr, command_path, + command_data); + } + return ESP_OK; +} + static esp_err_t esp_matter_command_callback_retrieve_logs_request(const ConcreteCommandPath &command_path, TLVReader &tlv_data, void *opaque_ptr) { @@ -1313,6 +1325,18 @@ command_t *create_reset_counts(cluster_t *cluster) } /* command */ } /* diagnostics_network_wifi */ +namespace diagnostics_network_ethernet { +namespace command { + +command_t *create_reset_counts(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, EthernetNetworkDiagnostics::Commands::ResetCounts::Id, COMMAND_FLAG_ACCEPTED, + esp_matter_command_callback_ethernet_reset_counts); +} + +} /* command */ +} /* diagnostics_network_ethernet */ + namespace diagnostic_logs { namespace command { diff --git a/components/esp_matter/esp_matter_command.h b/components/esp_matter/esp_matter_command.h index 526dccc25..b3fa15e0c 100644 --- a/components/esp_matter/esp_matter_command.h +++ b/components/esp_matter/esp_matter_command.h @@ -54,6 +54,12 @@ command_t *create_reset_counts(cluster_t *cluster); } /* command */ } /* diagnostics_network_wifi */ +namespace diagnostics_network_ethernet { +namespace command { +command_t *create_reset_counts(cluster_t *cluster); +} /* command */ +} /* diagnostics_network_ethernet */ + namespace diagnostic_logs { namespace command { command_t *create_retrieve_logs_request(cluster_t *cluster); diff --git a/components/esp_matter/esp_matter_feature.cpp b/components/esp_matter/esp_matter_feature.cpp index 6f34c6d3e..ce4464b42 100644 --- a/components/esp_matter/esp_matter_feature.cpp +++ b/components/esp_matter/esp_matter_feature.cpp @@ -889,6 +889,61 @@ esp_err_t add(cluster_t *cluster) } /* feature */ } /* diagnostics_network_wifi */ +namespace diagnostics_network_ethernet { +namespace feature { + +namespace packets_counts { + +uint32_t get_id() +{ + return (uint32_t)EthernetNetworkDiagnostics::Feature::kPacketCounts; +} + +esp_err_t add(cluster_t *cluster, config_t *config) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + update_feature_map(cluster, get_id()); + + /* Attributes managed internally */ + attribute::create_packet_rx_count(cluster, 0); + attribute::create_packet_tx_count(cluster, 0); + + return ESP_OK; +} + +} /* packets_counts */ + +namespace error_counts { + +uint32_t get_id() +{ + return (uint32_t)EthernetNetworkDiagnostics::Feature::kErrorCounts; +} + +esp_err_t add(cluster_t *cluster, config_t *config) +{ + if (!cluster) { + ESP_LOGE(TAG, "Cluster cannot be NULL"); + return ESP_ERR_INVALID_ARG; + } + update_feature_map(cluster, get_id()); + + /* Attributes managed internally */ + attribute::create_tx_error_count(cluster, config->tx_error_count); + attribute::create_collision_count(cluster, config->collision_count); + attribute::create_overrun_count(cluster, config->overrun_count); + + return ESP_OK; +} + +} /* error_counts */ + +} /* feature */ +} /* diagnostics_network_ethernet */ + namespace air_quality { namespace feature { diff --git a/components/esp_matter/esp_matter_feature.h b/components/esp_matter/esp_matter_feature.h index dd151198a..13bbf48ef 100644 --- a/components/esp_matter/esp_matter_feature.h +++ b/components/esp_matter/esp_matter_feature.h @@ -387,6 +387,39 @@ esp_err_t add(cluster_t *cluster); } /* feature */ } /* diagnostics_network_wifi */ +namespace diagnostics_network_ethernet { +namespace feature { + +namespace packets_counts { + +typedef struct config { + uint64_t packet_rx_count; + uint64_t packet_tx_count; + config() : packet_rx_count(0), packet_tx_count(0) {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); + +} /* packets_counts */ + +namespace error_counts { + +typedef struct config { + uint64_t tx_error_count; + uint64_t collision_count; + uint64_t overrun_count; + config() : tx_error_count(0), collision_count(0), overrun_count(0) {} +} config_t; + +uint32_t get_id(); +esp_err_t add(cluster_t *cluster, config_t *config); + +} /* error_counts */ + +} /* feature */ +} /* diagnostics_network_ethernet */ + namespace thermostat { namespace feature {