From 57c55bd711bc2e1137204f77dc75fe9d01ef8157 Mon Sep 17 00:00:00 2001 From: PSONALl Date: Tue, 8 Aug 2023 15:05:46 +0530 Subject: [PATCH] Matter v1.2 TE2 platform fixes - Update Cluster Revision of all clusters Add scene clusters missing commands Add Product Appearance attribute to basic information cluster Add missing attributes in color control cluster Add breadcrumb attribute Add missing attributes and commands in bridged device information cluster Fix typo in basic information cluster Add Scene Table Size attribute Fix CI for zigbee bridge Add attribute bounds and string length checks --- .../esp_matter/esp_matter_attribute.cpp | 434 +++++++++++++++--- components/esp_matter/esp_matter_attribute.h | 86 +++- components/esp_matter/esp_matter_cluster.cpp | 51 +- components/esp_matter/esp_matter_cluster.h | 47 +- components/esp_matter/esp_matter_command.cpp | 30 ++ components/esp_matter/esp_matter_command.h | 6 + components/esp_matter/esp_matter_endpoint.cpp | 74 +-- components/esp_matter/esp_matter_endpoint.h | 38 +- components/esp_matter/esp_matter_feature.cpp | 18 +- .../main/esp_matter_console_helpers.cpp | 3 +- examples/blemesh_bridge/main/app_main.cpp | 4 +- .../esp-now_bridge_light/main/app_main.cpp | 3 +- examples/zigbee_bridge/main/app_main.cpp | 4 +- 13 files changed, 650 insertions(+), 148 deletions(-) diff --git a/components/esp_matter/esp_matter_attribute.cpp b/components/esp_matter/esp_matter_attribute.cpp index 3a43b1e81..4374e5326 100644 --- a/components/esp_matter/esp_matter_attribute.cpp +++ b/components/esp_matter/esp_matter_attribute.cpp @@ -141,6 +141,10 @@ attribute_t *create_data_model_revision(cluster_t *cluster, uint16_t value) attribute_t *create_vendor_name(cluster_t *cluster, char *value, uint16_t length) { + if (length > k_max_vendor_name_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } return esp_matter::attribute::create(cluster, BasicInformation::Attributes::VendorName::Id, ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); } @@ -153,6 +157,10 @@ attribute_t *create_vendor_id(cluster_t *cluster, uint16_t value) attribute_t *create_product_name(cluster_t *cluster, char *value, uint16_t length) { + if (length > k_max_product_name_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } return esp_matter::attribute::create(cluster, BasicInformation::Attributes::ProductName::Id, ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); } @@ -165,6 +173,10 @@ attribute_t *create_product_id(cluster_t *cluster, uint16_t value) attribute_t *create_node_label(cluster_t *cluster, char *value, uint16_t length) { + if (length > k_max_node_label_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } return esp_matter::attribute::create(cluster, BasicInformation::Attributes::NodeLabel::Id, ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_char_str(value, length)); @@ -172,6 +184,10 @@ attribute_t *create_node_label(cluster_t *cluster, char *value, uint16_t length) attribute_t *create_location(cluster_t *cluster, char *value, uint16_t length) { + if (length > k_max_location_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } return esp_matter::attribute::create(cluster, BasicInformation::Attributes::Location::Id, ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_char_str(value, length)); @@ -185,6 +201,10 @@ attribute_t *create_hardware_version(cluster_t *cluster, uint16_t value) attribute_t *create_hardware_version_string(cluster_t *cluster, char *value, uint16_t length) { + if (length < k_min_version_string_length || length > k_max_version_string_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } return esp_matter::attribute::create(cluster, BasicInformation::Attributes::HardwareVersionString::Id, ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); } @@ -197,6 +217,10 @@ attribute_t *create_software_version(cluster_t *cluster, uint32_t value) attribute_t *create_software_version_string(cluster_t *cluster, char *value, uint16_t length) { + if (length < k_min_version_string_length || length > k_max_version_string_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } return esp_matter::attribute::create(cluster, BasicInformation::Attributes::SoftwareVersionString::Id, ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); } @@ -209,35 +233,55 @@ attribute_t *create_capability_minima(cluster_t *cluster, uint8_t *value, uint16 attribute_t *create_manufacturing_date(cluster_t *cluster, char *value, uint16_t length) { + if (length < k_min_manufacturing_date_length || length > k_max_manufacturing_date_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } return esp_matter::attribute::create(cluster, BasicInformation::Attributes::ManufacturingDate::Id, ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); } attribute_t *create_part_number(cluster_t *cluster, char *value, uint16_t length) { + if (length > k_max_part_number_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } return esp_matter::attribute::create(cluster, BasicInformation::Attributes::PartNumber::Id, ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); } attribute_t *create_product_url(cluster_t *cluster, char *value, uint16_t length) { + if (length > k_max_product_url_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } return esp_matter::attribute::create(cluster, BasicInformation::Attributes::ProductURL::Id, ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); } attribute_t *create_product_label(cluster_t *cluster, char *value, uint16_t length) { + if (length > k_max_product_label_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } return esp_matter::attribute::create(cluster, BasicInformation::Attributes::ProductLabel::Id, ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); } attribute_t *create_serial_number(cluster_t *cluster, char *value, uint16_t length) { + if (length > k_max_serial_number_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } return esp_matter::attribute::create(cluster, BasicInformation::Attributes::SerialNumber::Id, ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); } -attribute_t *create_local_config_diabled(cluster_t *cluster, bool value) +attribute_t *create_local_config_disabled(cluster_t *cluster, bool value) { return esp_matter::attribute::create(cluster, BasicInformation::Attributes::LocalConfigDisabled::Id, ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_bool(value)); @@ -251,10 +295,20 @@ attribute_t *create_reachable(cluster_t *cluster, bool value) attribute_t *create_unique_id(cluster_t *cluster, char *value, uint16_t length) { + if (length > k_max_unique_id_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } return esp_matter::attribute::create(cluster, BasicInformation::Attributes::UniqueID::Id, ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); } +attribute_t *create_product_appearance(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count) +{ + return esp_matter::attribute::create(cluster, BasicInformation::Attributes::ProductAppearance::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_array(value, length, count)); +} + } /* attribute */ } /* basic_information */ @@ -722,10 +776,122 @@ attribute_t *create_active_network_faults(cluster_t *cluster, uint8_t *value, ui namespace bridged_device_basic_information { namespace attribute { +attribute_t *create_vendor_name(cluster_t *cluster, char *value, uint16_t length) +{ + if (length > k_max_vendor_name_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } + return esp_matter::attribute::create(cluster, BridgedDeviceBasicInformation::Attributes::VendorName::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_char_str(value, length)); +} + +attribute_t *create_vendor_id(cluster_t *cluster, uint16_t value) +{ + return esp_matter::attribute::create(cluster, BridgedDeviceBasicInformation::Attributes::VendorID::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_uint16(value)); +} + +attribute_t *create_product_name(cluster_t *cluster, char *value, uint16_t length) +{ + if (length > k_max_product_name_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } + return esp_matter::attribute::create(cluster, BridgedDeviceBasicInformation::Attributes::ProductName::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_char_str(value, length)); +} + attribute_t *create_node_label(cluster_t *cluster, char *value, uint16_t length) { + if (length > k_max_node_label_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } return esp_matter::attribute::create(cluster, BridgedDeviceBasicInformation::Attributes::NodeLabel::Id, - ATTRIBUTE_FLAG_NONVOLATILE | ATTRIBUTE_FLAG_WRITABLE, + ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE, + esp_matter_char_str(value, length)); +} + +attribute_t *create_hardware_version(cluster_t *cluster, uint16_t value) +{ + return esp_matter::attribute::create(cluster, BridgedDeviceBasicInformation::Attributes::HardwareVersion::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); +} + +attribute_t *create_hardware_version_string(cluster_t *cluster, char *value, uint16_t length) +{ + if (length < k_min_version_string_length || length > k_max_version_string_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } + return esp_matter::attribute::create(cluster, BridgedDeviceBasicInformation::Attributes::HardwareVersionString::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); +} + +attribute_t *create_software_version(cluster_t *cluster, uint32_t value) +{ + return esp_matter::attribute::create(cluster, BridgedDeviceBasicInformation::Attributes::SoftwareVersion::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_uint32(value)); +} + +attribute_t *create_software_version_string(cluster_t *cluster, char *value, uint16_t length) +{ + if (length < k_min_version_string_length || length > k_max_version_string_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } + return esp_matter::attribute::create(cluster, BridgedDeviceBasicInformation::Attributes::SoftwareVersionString::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); +} + +attribute_t *create_manufacturing_date(cluster_t *cluster, char *value, uint16_t length) +{ + if (length < k_min_manufacturing_date_length || length > k_max_manufacturing_date_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } + return esp_matter::attribute::create(cluster, BridgedDeviceBasicInformation::Attributes::ManufacturingDate::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); +} + +attribute_t *create_part_number(cluster_t *cluster, char *value, uint16_t length) +{ + if (length > k_max_part_number_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } + return esp_matter::attribute::create(cluster, BridgedDeviceBasicInformation::Attributes::PartNumber::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_char_str(value, length)); +} + +attribute_t *create_product_url(cluster_t *cluster, char *value, uint16_t length) +{ + if (length > k_max_product_url_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } + return esp_matter::attribute::create(cluster, BridgedDeviceBasicInformation::Attributes::ProductURL::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_char_str(value, length)); +} + +attribute_t *create_product_label(cluster_t *cluster, char *value, uint16_t length) +{ + if (length > k_max_product_label_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } + return esp_matter::attribute::create(cluster, BridgedDeviceBasicInformation::Attributes::ProductLabel::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_char_str(value, length)); +} + +attribute_t *create_serial_number(cluster_t *cluster, char *value, uint16_t length) +{ + if (length > k_max_serial_number_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } + return esp_matter::attribute::create(cluster, BridgedDeviceBasicInformation::Attributes::SerialNumber::Id, ATTRIBUTE_FLAG_NONE, esp_matter_char_str(value, length)); } @@ -735,6 +901,22 @@ attribute_t *create_reachable(cluster_t *cluster, bool value) esp_matter_bool(value)); } +attribute_t *create_unique_id(cluster_t *cluster, char *value, uint16_t length) +{ + if (length > k_max_unique_id_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } + return esp_matter::attribute::create(cluster, BridgedDeviceBasicInformation::Attributes::UniqueID::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_char_str(value, length)); +} + +attribute_t *create_product_appearance(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count) +{ + return esp_matter::attribute::create(cluster, BridgedDeviceBasicInformation::Attributes::ProductAppearance::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_array(value, length, count)); +} + } /* attribute */ } /* bridged_device_basic */ @@ -832,6 +1014,12 @@ attribute_t *create_scene_name_support(cluster_t *cluster, uint8_t value) esp_matter_bitmap8(value)); } +attribute_t *create_scene_table_size(cluster_t *cluster, uint16_t value) +{ + return esp_matter::attribute::create(cluster, Scenes::Attributes::SceneTableSize::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_uint16(value)); +} + } /* attribute */ } /* scenes */ @@ -979,28 +1167,56 @@ attribute_t *create_start_up_current_level(cluster_t *cluster, nullable namespace color_control { namespace attribute { -attribute_t *create_current_hue(cluster_t *cluster, uint8_t value) +attribute_t *create_current_hue(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max) { - return esp_matter::attribute::create(cluster, ColorControl::Attributes::CurrentHue::Id, ATTRIBUTE_FLAG_NONVOLATILE, - esp_matter_uint8(value)); + attribute_t *attribute = + esp_matter::attribute::create(cluster, ColorControl::Attributes::CurrentHue::Id, + ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_uint8(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_uint8(min), esp_matter_uint8(max)); + return attribute; } -attribute_t *create_current_saturation(cluster_t *cluster, uint8_t value) +attribute_t *create_current_saturation(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max) { - return esp_matter::attribute::create(cluster, ColorControl::Attributes::CurrentSaturation::Id, - ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_uint8(value)); + attribute_t *attribute = + esp_matter::attribute::create(cluster, ColorControl::Attributes::CurrentSaturation::Id, + ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_uint8(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_uint8(min), esp_matter_uint8(max)); + return attribute; } -attribute_t *create_remaining_time(cluster_t *cluster, uint16_t value) +attribute_t *create_remaining_time(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max) { - return esp_matter::attribute::create(cluster, ColorControl::Attributes::RemainingTime::Id, ATTRIBUTE_FLAG_NONE, + attribute_t *attribute = + esp_matter::attribute::create(cluster, ColorControl::Attributes::RemainingTime::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_uint16(min), esp_matter_uint16(max)); + return attribute; } -attribute_t *create_color_mode(cluster_t *cluster, uint8_t value) +attribute_t *create_color_mode(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max) { - return esp_matter::attribute::create(cluster, ColorControl::Attributes::ColorMode::Id, ATTRIBUTE_FLAG_NONVOLATILE, + attribute_t *attribute = + esp_matter::attribute::create(cluster, ColorControl::Attributes::ColorMode::Id, ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_enum8(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_enum8(min), esp_matter_enum8(max)); + return attribute; } attribute_t *create_color_control_options(cluster_t *cluster, uint8_t value) @@ -1009,59 +1225,145 @@ attribute_t *create_color_control_options(cluster_t *cluster, uint8_t value) esp_matter_bitmap8(value)); } -attribute_t *create_enhanced_color_mode(cluster_t *cluster, uint8_t value) +attribute_t *create_enhanced_color_mode(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max) { - return esp_matter::attribute::create(cluster, ColorControl::Attributes::EnhancedColorMode::Id, + attribute_t *attribute = + esp_matter::attribute::create(cluster, ColorControl::Attributes::EnhancedColorMode::Id, ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_enum8(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_enum8(min), esp_matter_enum8(max)); + return attribute; } -attribute_t *create_color_capabilities(cluster_t *cluster, uint16_t value) +attribute_t *create_color_capabilities(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max) { - return esp_matter::attribute::create(cluster, ColorControl::Attributes::ColorCapabilities::Id, ATTRIBUTE_FLAG_NONE, + attribute_t *attribute = + esp_matter::attribute::create(cluster, ColorControl::Attributes::ColorCapabilities::Id, ATTRIBUTE_FLAG_NONE, esp_matter_bitmap16(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_bitmap16(min), esp_matter_bitmap16(max)); + return attribute; } -attribute_t *create_color_temperature_mireds(cluster_t *cluster, uint16_t value) +attribute_t *create_color_temperature_mireds(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max) { - return esp_matter::attribute::create(cluster, ColorControl::Attributes::ColorTemperatureMireds::Id, - ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_uint16(value)); + attribute_t *attribute = + esp_matter::attribute::create(cluster, ColorControl::Attributes::ColorTemperatureMireds::Id, + ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_uint16(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_uint16(min), esp_matter_uint16(max)); + return attribute; } -attribute_t *create_color_temp_physical_min_mireds(cluster_t *cluster, uint16_t value) +attribute_t *create_color_temp_physical_min_mireds(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max) { - return esp_matter::attribute::create(cluster, ColorControl::Attributes::ColorTempPhysicalMinMireds::Id, - ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); + attribute_t *attribute = + esp_matter::attribute::create(cluster, ColorControl::Attributes::ColorTempPhysicalMinMireds::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_uint16(min), esp_matter_uint16(max)); + return attribute; } -attribute_t *create_color_temp_physical_max_mireds(cluster_t *cluster, uint16_t value) +attribute_t *create_color_temp_physical_max_mireds(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max) { - return esp_matter::attribute::create(cluster, ColorControl::Attributes::ColorTempPhysicalMaxMireds::Id, - ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); + attribute_t *attribute = + esp_matter::attribute::create(cluster, ColorControl::Attributes::ColorTempPhysicalMaxMireds::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_uint16(min), esp_matter_uint16(max)); + return attribute; } -attribute_t *create_couple_color_temp_to_level_min_mireds(cluster_t *cluster, uint16_t value) +attribute_t *create_couple_color_temp_to_level_min_mireds(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max) { - return esp_matter::attribute::create(cluster, ColorControl::Attributes::CoupleColorTempToLevelMinMireds::Id, - ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); + attribute_t *attribute = + esp_matter::attribute::create(cluster, ColorControl::Attributes::CoupleColorTempToLevelMinMireds::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_uint16(min), esp_matter_uint16(max)); + return attribute; } -attribute_t *create_startup_color_temperature_mireds(cluster_t *cluster, nullable value) +attribute_t *create_startup_color_temperature_mireds(cluster_t *cluster, nullable value, uint16_t min, uint16_t max) { - return esp_matter::attribute::create(cluster, ColorControl::Attributes::StartUpColorTemperatureMireds::Id, - ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE, - esp_matter_nullable_uint16(value)); + attribute_t *attribute = + esp_matter::attribute::create(cluster, ColorControl::Attributes::StartUpColorTemperatureMireds::Id, + ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_WRITABLE | ATTRIBUTE_FLAG_NONVOLATILE, + esp_matter_nullable_uint16(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_uint16(min), esp_matter_uint16(max)); + return attribute; } -attribute_t *create_current_x(cluster_t *cluster, uint16_t value) +attribute_t *create_current_x(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max) { - return esp_matter::attribute::create(cluster, ColorControl::Attributes::CurrentX::Id, ATTRIBUTE_FLAG_NONVOLATILE, + attribute_t *attribute = + esp_matter::attribute::create(cluster, ColorControl::Attributes::CurrentX::Id, ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_uint16(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_uint16(min), esp_matter_uint16(max)); + return attribute; } -attribute_t *create_current_y(cluster_t *cluster, uint16_t value) +attribute_t *create_current_y(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max) { - return esp_matter::attribute::create(cluster, ColorControl::Attributes::CurrentY::Id, ATTRIBUTE_FLAG_NONVOLATILE, + attribute_t *attribute = + esp_matter::attribute::create(cluster, ColorControl::Attributes::CurrentY::Id, ATTRIBUTE_FLAG_NONVOLATILE, esp_matter_uint16(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_uint16(min), esp_matter_uint16(max)); + return attribute; +} + +attribute_t *create_drift_compensation(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max) +{ + attribute_t *attribute = + esp_matter::attribute::create(cluster, ColorControl::Attributes::DriftCompensation::Id, + ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_enum8(min), esp_matter_enum8(max)); + return attribute; +} + +attribute_t *create_compensation_text(cluster_t *cluster, char *value, uint16_t length) +{ + if (length > k_max_compensation_text_length) { + ESP_LOGE(TAG, "Could not create attribute, string length out of bound"); + return NULL; + } + return esp_matter::attribute::create(cluster, ColorControl::Attributes::CompensationText::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_char_str(value, length)); } attribute_t *create_enhanced_current_hue(cluster_t *cluster, uint16_t value) @@ -1100,76 +1402,96 @@ attribute_t *create_color_loop_stored_enhanced_hue(cluster_t *cluster, uint16_t ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); } -attribute_t *create_number_of_primaries(cluster_t *cluster, nullable value) +attribute_t *create_number_of_primaries(cluster_t *cluster, nullable value, uint8_t min, uint8_t max) { - return esp_matter::attribute::create(cluster, ColorControl::Attributes::NumberOfPrimaries::Id, + attribute_t *attribute = + esp_matter::attribute::create(cluster, ColorControl::Attributes::NumberOfPrimaries::Id, ATTRIBUTE_FLAG_NULLABLE, esp_matter_nullable_uint8(value)); + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_uint8(min), esp_matter_uint8(max)); + return attribute; } -attribute_t *create_primary_n_x(cluster_t *cluster, uint16_t value, uint8_t index) +attribute_t *create_primary_n_x(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max, uint8_t index) { + attribute_t *attribute = NULL; switch (index) { case 1: - return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary1X::Id, ATTRIBUTE_FLAG_NONE, - esp_matter_uint16(value)); - break; + attribute = esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary1X::Id, ATTRIBUTE_FLAG_NONE, + esp_matter_uint16(value)); + break; case 2: - return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary2X::Id, ATTRIBUTE_FLAG_NONE, + attribute = esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary2X::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); break; case 3: - return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary3X::Id, ATTRIBUTE_FLAG_NONE, + attribute = esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary3X::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); break; case 4: - return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary4X::Id, ATTRIBUTE_FLAG_NONE, + attribute = esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary4X::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); break; case 5: - return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary5X::Id, ATTRIBUTE_FLAG_NONE, + attribute = esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary5X::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); break; case 6: - return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary6X::Id, ATTRIBUTE_FLAG_NONE, + attribute = esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary6X::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); break; default: break; } - return NULL; + + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_uint16(min), esp_matter_uint16(max)); + return attribute; } -attribute_t *create_primary_n_y(cluster_t *cluster, uint16_t value, uint8_t index) +attribute_t *create_primary_n_y(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max, uint8_t index) { + attribute_t *attribute = NULL; switch (index) { case 1: - return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary1Y::Id, ATTRIBUTE_FLAG_NONE, + attribute = esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary1Y::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); break; case 2: - return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary2Y::Id, ATTRIBUTE_FLAG_NONE, + attribute = esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary2Y::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); break; case 3: - return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary3Y::Id, ATTRIBUTE_FLAG_NONE, + attribute = esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary3Y::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); break; case 4: - return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary4Y::Id, ATTRIBUTE_FLAG_NONE, + attribute = esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary4Y::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); break; case 5: - return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary5Y::Id, ATTRIBUTE_FLAG_NONE, + attribute = esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary5Y::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); break; case 6: - return esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary6Y::Id, ATTRIBUTE_FLAG_NONE, + attribute = esp_matter::attribute::create(cluster, ColorControl::Attributes::Primary6Y::Id, ATTRIBUTE_FLAG_NONE, esp_matter_uint16(value)); break; default: break; } - return NULL; + if (!attribute) { + ESP_LOGE(TAG, "Could not create attribute"); + return NULL; + } + esp_matter::attribute::add_bounds(attribute, esp_matter_uint16(min), esp_matter_uint16(max)); + return attribute; } attribute_t *create_primary_n_intensity(cluster_t *cluster, nullable value, uint8_t index) diff --git a/components/esp_matter/esp_matter_attribute.h b/components/esp_matter/esp_matter_attribute.h index a488fca5a..e19543b25 100644 --- a/components/esp_matter/esp_matter_attribute.h +++ b/components/esp_matter/esp_matter_attribute.h @@ -61,6 +61,20 @@ attribute_t *create_access_control_entries_per_fabric(cluster_t *cluster, uint16 } /* access_control */ namespace basic_information { +constexpr uint8_t k_max_vendor_name_length = 32; +constexpr uint8_t k_max_product_name_length = 32; +constexpr uint8_t k_max_node_label_length = 32; +constexpr uint8_t k_max_location_length = 2; +constexpr uint8_t k_min_version_string_length = 1; +constexpr uint8_t k_max_version_string_length = 64; +constexpr uint8_t k_min_manufacturing_date_length = 8; +constexpr uint8_t k_max_manufacturing_date_length = 16; +constexpr uint8_t k_max_part_number_length = 32; +constexpr uint8_t k_max_product_url_length = 32; +constexpr uint8_t k_max_product_label_length = 32; +constexpr uint8_t k_max_serial_number_length = 32; +constexpr uint8_t k_max_unique_id_length = 32; + namespace attribute { attribute_t *create_data_model_revision(cluster_t *cluster, uint16_t value); attribute_t *create_vendor_name(cluster_t *cluster, char *value, uint16_t length); @@ -83,9 +97,10 @@ attribute_t *create_part_number(cluster_t *cluster, char *value, uint16_t length attribute_t *create_product_url(cluster_t *cluster, char *value, uint16_t length); attribute_t *create_product_label(cluster_t *cluster, char *value, uint16_t length); attribute_t *create_serial_number(cluster_t *cluster, char *value, uint16_t length); -attribute_t *create_local_config_diabled(cluster_t *cluster, bool value); +attribute_t *create_local_config_disabled(cluster_t *cluster, bool value); attribute_t *create_reachable(cluster_t *cluster, bool value); attribute_t *create_unique_id(cluster_t *cluster, char *value, uint16_t length); +attribute_t *create_product_appearance(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); } /* attribute */ } /* basic_information */ @@ -214,9 +229,41 @@ attribute_t *create_active_network_faults(cluster_t *cluster, uint8_t *value, ui } /* diagnostics_network_thread */ namespace bridged_device_basic_information { +constexpr uint8_t k_max_vendor_name_length = 32; +constexpr uint8_t k_max_product_name_length = 32; +constexpr uint8_t k_max_node_label_length = 32; +constexpr uint8_t k_max_location_length = 2; +constexpr uint8_t k_min_version_string_length = 1; +constexpr uint8_t k_max_version_string_length = 64; +constexpr uint8_t k_min_manufacturing_date_length = 8; +constexpr uint8_t k_max_manufacturing_date_length = 16; +constexpr uint8_t k_max_part_number_length = 32; +constexpr uint8_t k_max_product_url_length = 32; +constexpr uint8_t k_max_product_label_length = 32; +constexpr uint8_t k_max_serial_number_length = 32; +constexpr uint8_t k_max_unique_id_length = 32; + namespace attribute { +attribute_t *create_vendor_name(cluster_t *cluster, char *value, uint16_t length); +attribute_t *create_vendor_id(cluster_t *cluster, uint16_t value); +attribute_t *create_product_name(cluster_t *cluster, char *value, uint16_t length); attribute_t *create_node_label(cluster_t *cluster, char *value, uint16_t length); +attribute_t *create_hardware_version(cluster_t *cluster, uint16_t value); +attribute_t *create_hardware_version_string(cluster_t *cluster, char *value, uint16_t length); +attribute_t *create_software_version(cluster_t *cluster, uint32_t value); +attribute_t *create_software_version_string(cluster_t *cluster, char *value, uint16_t length); + +/** These attributes are optional for the cluster, but when added to this cluster, the value is maintained internally. + * If the attributes are added in some other cluster, then the value is not maintained internally. + **/ +attribute_t *create_manufacturing_date(cluster_t *cluster, char *value, uint16_t length); +attribute_t *create_part_number(cluster_t *cluster, char *value, uint16_t length); +attribute_t *create_product_url(cluster_t *cluster, char *value, uint16_t length); +attribute_t *create_product_label(cluster_t *cluster, char *value, uint16_t length); +attribute_t *create_serial_number(cluster_t *cluster, char *value, uint16_t length); attribute_t *create_reachable(cluster_t *cluster, bool value); +attribute_t *create_unique_id(cluster_t *cluster, char *value, uint16_t length); +attribute_t *create_product_appearance(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count); } /* attribute */ } /* bridged_device_basic_information */ @@ -252,6 +299,7 @@ attribute_t *create_current_scene(cluster_t *cluster, uint8_t value); attribute_t *create_current_group(cluster_t *cluster, uint16_t value); attribute_t *create_scene_valid(cluster_t *cluster, bool value); attribute_t *create_scene_name_support(cluster_t *cluster, uint8_t value); +attribute_t *create_scene_table_size(cluster_t *cluster, uint16_t value); } /* attribute */ } /* scenes */ @@ -285,30 +333,34 @@ attribute_t *create_start_up_current_level(cluster_t *cluster, nullable } /* level_control */ namespace color_control { +constexpr uint8_t k_max_compensation_text_length = 254; + namespace attribute { -attribute_t *create_current_hue(cluster_t *cluster, uint8_t value); -attribute_t *create_current_saturation(cluster_t *cluster, uint8_t value); -attribute_t *create_remaining_time(cluster_t *cluster, uint16_t value); -attribute_t *create_color_mode(cluster_t *cluster, uint8_t value); +attribute_t *create_current_hue(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max); +attribute_t *create_current_saturation(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max); +attribute_t *create_remaining_time(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max); +attribute_t *create_color_mode(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max); attribute_t *create_color_control_options(cluster_t *cluster, uint8_t value); -attribute_t *create_enhanced_color_mode(cluster_t *cluster, uint8_t value); -attribute_t *create_color_capabilities(cluster_t *cluster, uint16_t value); -attribute_t *create_color_temperature_mireds(cluster_t *cluster, uint16_t value); -attribute_t *create_color_temp_physical_min_mireds(cluster_t *cluster, uint16_t value); -attribute_t *create_color_temp_physical_max_mireds(cluster_t *cluster, uint16_t value); -attribute_t *create_couple_color_temp_to_level_min_mireds(cluster_t *cluster, uint16_t value); -attribute_t *create_startup_color_temperature_mireds(cluster_t *cluster, nullable value); -attribute_t *create_current_x(cluster_t *cluster, uint16_t value); -attribute_t *create_current_y(cluster_t *cluster, uint16_t value); +attribute_t *create_enhanced_color_mode(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max); +attribute_t *create_color_capabilities(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max); +attribute_t *create_color_temperature_mireds(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max); +attribute_t *create_color_temp_physical_min_mireds(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max); +attribute_t *create_color_temp_physical_max_mireds(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max); +attribute_t *create_couple_color_temp_to_level_min_mireds(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max); +attribute_t *create_startup_color_temperature_mireds(cluster_t *cluster, nullable value, uint16_t min, uint16_t max); +attribute_t *create_current_x(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max); +attribute_t *create_current_y(cluster_t *cluster, uint16_t value, uint16_t min, uint16_t max); +attribute_t *create_drift_compensation(cluster_t *cluster, uint8_t value, uint8_t min, uint8_t max); +attribute_t *create_compensation_text(cluster_t *cluster, char *value, uint16_t length); attribute_t *create_enhanced_current_hue(cluster_t *cluster, uint16_t value); attribute_t *create_color_loop_active(cluster_t *cluster, uint8_t value); attribute_t *create_color_loop_direction(cluster_t *cluster, uint8_t value); attribute_t *create_color_loop_time(cluster_t *cluster, uint16_t value); attribute_t *create_color_loop_start_enhanced_hue(cluster_t *cluster, uint16_t value); attribute_t *create_color_loop_stored_enhanced_hue(cluster_t *cluster, uint16_t value); -attribute_t *create_number_of_primaries(cluster_t *cluster, nullable value); -attribute_t *create_primary_n_x(cluster_t * cluster, uint16_t value, uint8_t index); -attribute_t *create_primary_n_y(cluster_t * cluster, uint16_t value, uint8_t index); +attribute_t *create_number_of_primaries(cluster_t *cluster, nullable value, uint8_t min, uint8_t max); +attribute_t *create_primary_n_x(cluster_t * cluster, uint16_t value, uint16_t min, uint16_t max, uint8_t index); +attribute_t *create_primary_n_y(cluster_t * cluster, uint16_t value, uint16_t min, uint16_t max, uint8_t index); attribute_t *create_primary_n_intensity(cluster_t * cluster, nullable value, uint8_t index); } /* attribute */ } /* color_control */ diff --git a/components/esp_matter/esp_matter_cluster.cpp b/components/esp_matter/esp_matter_cluster.cpp index 7045a7a2f..53ad286ac 100644 --- a/components/esp_matter/esp_matter_cluster.cpp +++ b/components/esp_matter/esp_matter_cluster.cpp @@ -68,7 +68,7 @@ namespace descriptor { const function_generic_t *function_list = NULL; const int function_flags = CLUSTER_FLAG_NONE; -cluster_t *create(endpoint_t *endpoint, uint8_t flags) +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) { cluster_t *cluster = cluster::create(endpoint, Descriptor::Id, flags); if (!cluster) { @@ -91,6 +91,14 @@ cluster_t *create(endpoint_t *endpoint, uint8_t flags) /* Attributes updated later */ global::attribute::create_feature_map(cluster, 0); + + /* 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."); + } + } return cluster; @@ -101,7 +109,7 @@ namespace actions { const function_generic_t *function_list = NULL; const int function_flags = CLUSTER_FLAG_NONE; -cluster_t *create(endpoint_t *endpoint, uint8_t flags) +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) { cluster_t *cluster = cluster::create(endpoint, Actions::Id, flags); if (!cluster) { @@ -120,6 +128,14 @@ cluster_t *create(endpoint_t *endpoint, uint8_t flags) global::attribute::create_feature_map(cluster, 0); attribute::create_action_list(cluster, NULL, 0, 0); attribute::create_endpoint_lists(cluster, NULL, 0, 0); + + /* 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."); + } + } event::create_action_failed(cluster); @@ -133,7 +149,7 @@ namespace access_control { const function_generic_t *function_list = NULL; const int function_flags = CLUSTER_FLAG_NONE; -cluster_t *create(endpoint_t *endpoint, uint8_t flags) +cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) { cluster_t *cluster = cluster::create(endpoint, AccessControl::Id, flags); if (!cluster) { @@ -155,6 +171,14 @@ cluster_t *create(endpoint_t *endpoint, uint8_t flags) /* Attributes updated later */ global::attribute::create_feature_map(cluster, 0); + + /* 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."); + } + } event::create_access_control_entry_changed(cluster); @@ -352,6 +376,7 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) if (flags & CLUSTER_FLAG_SERVER) { /* Attributes managed internally */ global::attribute::create_feature_map(cluster, 0); + attribute::create_breadcrumb(cluster, 0); attribute::create_regulatory_config(cluster, 0); attribute::create_location_capability(cluster, 0); attribute::create_basic_commissioning_info(cluster, NULL, 0, 0); @@ -1004,7 +1029,8 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags) attribute::create_current_group(cluster, config->current_group); attribute::create_scene_valid(cluster, config->scene_valid); attribute::create_scene_name_support(cluster, config->scene_name_support); - } else { + attribute::create_scene_table_size(cluster, config->scene_table_size); + } else { ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); } } @@ -1159,20 +1185,21 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_ /* Attributes not managed internally */ if (config) { global::attribute::create_cluster_revision(cluster, config->cluster_revision); - attribute::create_color_mode(cluster, config->color_mode); + attribute::create_color_mode(cluster, config->color_mode, 0, 2); attribute::create_color_control_options(cluster, config->color_control_options); - attribute::create_enhanced_color_mode(cluster, config->enhanced_color_mode); - attribute::create_color_capabilities(cluster, config->color_capabilities); - attribute::create_number_of_primaries(cluster, config->number_of_primaries); + attribute::create_enhanced_color_mode(cluster, config->enhanced_color_mode, 0, 3); + attribute::create_color_capabilities(cluster, config->color_capabilities, 0, 0x001f); + attribute::create_number_of_primaries(cluster, config->number_of_primaries, 0, 6); } else { ESP_LOGE(TAG, "Config is NULL. Cannot add some attributes."); } /* Attributes managed internally */ - attribute::create_remaining_time(cluster, 0); - for (uint8_t idx = 1; idx <= config->number_of_primaries.value_or(0); ++idx) { - attribute::create_primary_n_x(cluster, 0, idx); - attribute::create_primary_n_y(cluster, 0, idx); + attribute::create_remaining_time(cluster, 0, 0, 65534); + uint16_t max_primary_value = static_cast(0xfeff); + for (uint8_t idx = 1; idx <= config->number_of_primaries.value_or(0); ++idx) { + attribute::create_primary_n_x(cluster, 0, idx, 0, max_primary_value); + attribute::create_primary_n_y(cluster, 0, idx, 0, max_primary_value); attribute::create_primary_n_intensity(cluster, nullable(), idx); } } diff --git a/components/esp_matter/esp_matter_cluster.h b/components/esp_matter/esp_matter_cluster.h index 33d0f1809..5d511a5a1 100644 --- a/components/esp_matter/esp_matter_cluster.h +++ b/components/esp_matter/esp_matter_cluster.h @@ -41,22 +41,37 @@ void plugin_init_callback_common(); */ namespace descriptor { -cluster_t *create(endpoint_t *endpoint, uint8_t flags); +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); } /* descriptor */ namespace actions { -cluster_t *create(endpoint_t *endpoint, uint8_t flags); +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); } /* actions */ namespace access_control { -cluster_t *create(endpoint_t *endpoint, uint8_t flags); +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); } /* access_control */ namespace basic_information { typedef struct config { uint16_t cluster_revision; char node_label[32]; - config() : cluster_revision(1), node_label{0} {} + config() : cluster_revision(2), node_label{0} {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); @@ -157,6 +172,11 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); } /* operational_credentials */ namespace group_key_management { +typedef struct config { + uint16_t cluster_revision; + config() : cluster_revision(2) {} +} config_t; + cluster_t *create(endpoint_t *endpoint, uint8_t flags); } /* group_key_management */ @@ -181,7 +201,7 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); namespace time_synchronization { typedef struct config { uint16_t cluster_revision; - config() : cluster_revision(1) {} + config() : cluster_revision(2) {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); @@ -191,7 +211,7 @@ namespace bridged_device_basic_information { typedef struct config { uint16_t cluster_revision; bool reachable; - config() : cluster_revision(1), reachable(true) {} + config() : cluster_revision(2), reachable(true) {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); @@ -207,7 +227,7 @@ typedef struct config { feature::battery::config_t battery; feature::rechargeable::config_t rechargeable; feature::replaceable::config_t replaceable; - config() : cluster_revision(1), status(0), order(0), description{0} {} + config() : cluster_revision(2), status(0), order(0), description{0} {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features); @@ -260,8 +280,9 @@ typedef struct config { uint16_t current_group; bool scene_valid; uint8_t scene_name_support; + uint16_t scene_table_size; config() : cluster_revision(5), scene_count(0), current_scene(0), current_group(0), scene_valid(false), - scene_name_support(0) {} + scene_name_support(0), scene_table_size(0) {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); @@ -272,7 +293,7 @@ typedef struct config { uint16_t cluster_revision; bool on_off; feature::lighting::config_t lighting; - config() : cluster_revision(4), on_off(false) {} + config() : cluster_revision(5), on_off(false) {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features); @@ -304,7 +325,7 @@ typedef struct config { feature::xy::config_t xy; feature::enhanced_hue::config_t enhanced_hue; feature::color_loop::config_t color_loop; - config() : cluster_revision(5), color_mode(1), color_control_options(0), enhanced_color_mode(1), + config() : cluster_revision(6), color_mode(1), color_control_options(0), enhanced_color_mode(1), color_capabilities(0), number_of_primaries(0) {} } config_t; @@ -330,7 +351,7 @@ typedef struct config { nullable local_temperature; uint8_t control_sequence_of_operation; uint8_t system_mode; - config() : cluster_revision(5), local_temperature(), control_sequence_of_operation(4), system_mode(1) {} + config() : cluster_revision(6), local_temperature(), control_sequence_of_operation(4), system_mode(1) {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); @@ -344,7 +365,7 @@ typedef struct config { bool actuator_enabled; uint8_t operating_mode; uint16_t supported_operating_modes; - config() : cluster_revision(6), lock_state(0), lock_type(0), actuator_enabled(0), operating_mode(0), supported_operating_modes(0xFFF6) {} + config() : cluster_revision(7), lock_state(0), lock_type(0), actuator_enabled(0), operating_mode(0), supported_operating_modes(0xFFF6) {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags); @@ -511,7 +532,7 @@ typedef struct config { const nullable standard_namespace; uint8_t current_mode; feature::on_off::config_t on_off; - config() : cluster_revision(1), mode_select_description{0}, standard_namespace(), current_mode(0) {} + config() : cluster_revision(2), mode_select_description{0}, standard_namespace(), current_mode(0) {} } config_t; cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags, uint32_t features); diff --git a/components/esp_matter/esp_matter_command.cpp b/components/esp_matter/esp_matter_command.cpp index 965db4ad7..5383fadc3 100644 --- a/components/esp_matter/esp_matter_command.cpp +++ b/components/esp_matter/esp_matter_command.cpp @@ -1720,6 +1720,21 @@ command_t *create_get_scene_membership(cluster_t *cluster) return esp_matter::command::create(cluster, Scenes::Commands::GetSceneMembership::Id, COMMAND_FLAG_ACCEPTED, NULL); } +command_t *create_enhanced_add_scene(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, Scenes::Commands::EnhancedAddScene::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_enhanced_view_scene(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, Scenes::Commands::EnhancedViewScene::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + +command_t *create_copy_scene(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, Scenes::Commands::CopyScene::Id, COMMAND_FLAG_ACCEPTED, NULL); +} + command_t *create_add_scene_response(cluster_t *cluster) { return esp_matter::command::create(cluster, Scenes::Commands::AddSceneResponse::Id, COMMAND_FLAG_GENERATED, NULL); @@ -1753,6 +1768,21 @@ command_t *create_get_scene_membership_response(cluster_t *cluster) COMMAND_FLAG_GENERATED, NULL); } +command_t *create_enhanced_add_scene_response(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, Scenes::Commands::EnhancedAddSceneResponse::Id, COMMAND_FLAG_GENERATED, NULL); +} + +command_t *create_enhanced_view_scene_response(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, Scenes::Commands::EnhancedViewSceneResponse::Id, COMMAND_FLAG_GENERATED, NULL); +} + +command_t *create_copy_scene_response(cluster_t *cluster) +{ + return esp_matter::command::create(cluster, Scenes::Commands::CopySceneResponse::Id, COMMAND_FLAG_GENERATED, NULL); +} + } /* command */ } /* scenes */ diff --git a/components/esp_matter/esp_matter_command.h b/components/esp_matter/esp_matter_command.h index 41c337ab2..2f41def00 100644 --- a/components/esp_matter/esp_matter_command.h +++ b/components/esp_matter/esp_matter_command.h @@ -181,12 +181,18 @@ command_t *create_remove_all_scenes(cluster_t *cluster); command_t *create_store_scene(cluster_t *cluster); command_t *create_recall_scene(cluster_t *cluster); command_t *create_get_scene_membership(cluster_t *cluster); +command_t *create_enhanced_add_scene(cluster_t *cluster); +command_t *create_enhanced_view_scene(cluster_t *cluster); +command_t *create_copy_scene(cluster_t *cluster); command_t *create_add_scene_response(cluster_t *cluster); command_t *create_view_scene_response(cluster_t *cluster); command_t *create_remove_scene_response(cluster_t *cluster); command_t *create_remove_all_scenes_response(cluster_t *cluster); command_t *create_store_scene_response(cluster_t *cluster); command_t *create_get_scene_membership_response(cluster_t *cluster); +command_t *create_enhanced_add_scene_response(cluster_t *cluster); +command_t *create_enhanced_view_scene_response(cluster_t *cluster); +command_t *create_copy_scene_response(cluster_t *cluster); } /* command */ } /* scenes */ diff --git a/components/esp_matter/esp_matter_endpoint.cpp b/components/esp_matter/esp_matter_endpoint.cpp index 412102309..4700ff9db 100644 --- a/components/esp_matter/esp_matter_endpoint.cpp +++ b/components/esp_matter/esp_matter_endpoint.cpp @@ -47,8 +47,8 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); - access_control::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); + access_control::create(endpoint, &(config->access_control), CLUSTER_FLAG_SERVER); basic_information::create(endpoint, &(config->basic_information), CLUSTER_FLAG_SERVER); general_commissioning::create(endpoint, &(config->general_commissioning), CLUSTER_FLAG_SERVER); network_commissioning::create(endpoint, &(config->network_commissioning), CLUSTER_FLAG_SERVER); @@ -99,7 +99,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) ESP_LOGE(TAG, "Failed to add device type: err: %d", err); } - cluster_t *cluster = descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + cluster_t *cluster = descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); if (!cluster) { return NULL; } @@ -138,7 +138,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); cluster_t *identify_cluster = identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); identify::command::create_trigger_effect(identify_cluster); groups::create(endpoint, &(config->groups), CLUSTER_FLAG_SERVER); @@ -175,7 +175,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); cluster_t *identify_cluster = identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); identify::command::create_trigger_effect(identify_cluster); groups::create(endpoint, &(config->groups), CLUSTER_FLAG_SERVER); @@ -213,7 +213,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); cluster_t *identify_cluster = identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); identify::command::create_trigger_effect(identify_cluster); groups::create(endpoint, &(config->groups), CLUSTER_FLAG_SERVER); @@ -254,11 +254,15 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); cluster_t *identify_cluster = identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); identify::command::create_trigger_effect(identify_cluster); groups::create(endpoint, &(config->groups), CLUSTER_FLAG_SERVER); - scenes::create(endpoint, &(config->scenes), CLUSTER_FLAG_SERVER); + cluster_t *scenes_cluster = scenes::create(endpoint, &(config->scenes), CLUSTER_FLAG_SERVER); + scenes::command::create_enhanced_add_scene(scenes_cluster); + scenes::command::create_enhanced_view_scene(scenes_cluster); + scenes::command::create_copy_scene(scenes_cluster); + on_off::create(endpoint, &(config->on_off), CLUSTER_FLAG_SERVER, on_off::feature::lighting::get_id()); level_control::create(endpoint, &(config->level_control), CLUSTER_FLAG_SERVER, level_control::feature::on_off::get_id() | level_control::feature::lighting::get_id()); @@ -294,7 +298,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER | CLUSTER_FLAG_CLIENT); binding::create(endpoint, &(config->binding), CLUSTER_FLAG_SERVER); on_off::create(endpoint, NULL, CLUSTER_FLAG_CLIENT, ESP_MATTER_NONE_FEATURE_ID); @@ -328,7 +332,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER | CLUSTER_FLAG_CLIENT); binding::create(endpoint, &(config->binding), CLUSTER_FLAG_SERVER); on_off::create(endpoint, NULL, CLUSTER_FLAG_CLIENT, ESP_MATTER_NONE_FEATURE_ID); @@ -364,7 +368,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER | CLUSTER_FLAG_CLIENT); binding::create(endpoint, &(config->binding), CLUSTER_FLAG_SERVER); on_off::create(endpoint, NULL, CLUSTER_FLAG_CLIENT, ESP_MATTER_NONE_FEATURE_ID); @@ -400,7 +404,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); switch_cluster::create(endpoint, &(config->switch_cluster), CLUSTER_FLAG_SERVER); @@ -433,7 +437,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); cluster_t *identify_cluster = identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); identify::command::create_trigger_effect(identify_cluster); groups::create(endpoint, &(config->groups), CLUSTER_FLAG_SERVER); @@ -469,7 +473,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); cluster_t *identify_cluster = identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); identify::command::create_trigger_effect(identify_cluster); groups::create(endpoint, &(config->groups), CLUSTER_FLAG_SERVER); @@ -507,7 +511,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); groups::create(endpoint, &(config->groups), CLUSTER_FLAG_SERVER); fan_control::create(endpoint, &(config->fan_control), CLUSTER_FLAG_SERVER); @@ -541,7 +545,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); cluster::thermostat::create(endpoint, &(config->thermostat), CLUSTER_FLAG_SERVER); @@ -560,13 +564,13 @@ uint8_t get_device_type_version() return ESP_MATTER_AGGREGATOR_DEVICE_TYPE_VERSION; } -endpoint_t *create(node_t *node, uint8_t flags, void *priv_data) +endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_data) { endpoint_t *endpoint = endpoint::create(node, flags, priv_data); - return add(endpoint); + return add(endpoint, config); } -endpoint_t *add(endpoint_t *endpoint) +endpoint_t *add(endpoint_t *endpoint, config_t *config) { if (!endpoint) { ESP_LOGE(TAG, "Endpoint cannot be NULL"); @@ -574,7 +578,7 @@ endpoint_t *add(endpoint_t *endpoint) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint,CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); return endpoint; } @@ -607,7 +611,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); bridged_device_basic_information::create(endpoint, &(config->bridged_device_basic_information), CLUSTER_FLAG_SERVER); return endpoint; @@ -646,7 +650,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); cluster::door_lock::create(endpoint, &(config->door_lock), CLUSTER_FLAG_SERVER); @@ -680,7 +684,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); groups::create(endpoint, &(config->groups), CLUSTER_FLAG_SERVER); scenes::create(endpoint, &(config->scenes), CLUSTER_FLAG_SERVER); @@ -715,7 +719,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); temperature_measurement::create(endpoint, &(config->temperature_measurement), CLUSTER_FLAG_SERVER); @@ -748,7 +752,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); relative_humidity_measurement::create(endpoint, &(config->relative_humidity_measurement), CLUSTER_FLAG_SERVER); @@ -781,7 +785,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); occupancy_sensing::create(endpoint, &(config->occupancy_sensing), CLUSTER_FLAG_SERVER); @@ -814,7 +818,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); boolean_state::create(endpoint, &(config->boolean_state), CLUSTER_FLAG_SERVER); @@ -847,7 +851,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); illuminance_measurement::create(endpoint, &(config->illuminance_measurement), CLUSTER_FLAG_SERVER); @@ -880,7 +884,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); pressure_measurement::create(endpoint, &(config->pressure_measurement), CLUSTER_FLAG_SERVER); @@ -913,7 +917,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); flow_measurement::create(endpoint, &(config->flow_measurement), CLUSTER_FLAG_SERVER); @@ -948,7 +952,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) add_device_type(endpoint, get_device_type_id(), get_device_type_version()); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); on_off::create(endpoint, &(config->on_off), CLUSTER_FLAG_SERVER, ESP_MATTER_NONE_FEATURE_ID); pump_configuration_and_control::create(endpoint, &(config->pump_configuration_and_control), CLUSTER_FLAG_SERVER); @@ -987,7 +991,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) ESP_LOGE(TAG, "Failed to add device type: err: %d", err); } - cluster_t *cluster = descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + cluster_t *cluster = descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); if (!cluster) { return NULL; } @@ -1031,7 +1035,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); identify::create(endpoint, &(config->identify), CLUSTER_FLAG_SERVER); on_off::create(endpoint, &(config->on_off), CLUSTER_FLAG_SERVER, on_off::feature::dead_front::get_id()); cluster::thermostat::create(endpoint, &(config->thermostat), CLUSTER_FLAG_SERVER); @@ -1067,7 +1071,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); temperature_control::create(endpoint, &(config->temperature_control), CLUSTER_FLAG_SERVER, ESP_MATTER_NONE_FEATURE_ID); return endpoint; @@ -1100,7 +1104,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config) } add_device_type(endpoint, get_device_type_id(), get_device_type_version()); - descriptor::create(endpoint, CLUSTER_FLAG_SERVER); + descriptor::create(endpoint, &(config->descriptor), CLUSTER_FLAG_SERVER); return endpoint; } diff --git a/components/esp_matter/esp_matter_endpoint.h b/components/esp_matter/esp_matter_endpoint.h index 544014d82..c7fc8fce9 100644 --- a/components/esp_matter/esp_matter_endpoint.h +++ b/components/esp_matter/esp_matter_endpoint.h @@ -99,6 +99,8 @@ namespace esp_matter { namespace endpoint { namespace root_node { typedef struct config { + cluster::descriptor::config_t descriptor; + cluster::access_control::config_t access_control; cluster::basic_information::config_t basic_information; cluster::general_commissioning::config_t general_commissioning; cluster::network_commissioning::config_t network_commissioning; @@ -117,6 +119,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace power_source_device{ typedef struct config { + cluster::descriptor::config_t descriptor; cluster::power_source::config_t power_source; } config_t; @@ -128,6 +131,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace on_off_light { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::groups::config_t groups; cluster::scenes::config_t scenes; @@ -142,6 +146,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace dimmable_light { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::groups::config_t groups; cluster::scenes::config_t scenes; @@ -157,6 +162,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace color_temperature_light { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::groups::config_t groups; cluster::scenes::config_t scenes; @@ -173,6 +179,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace extended_color_light { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::groups::config_t groups; cluster::scenes::config_t scenes; @@ -189,6 +196,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace on_off_switch { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::binding::config_t binding; } config_t; @@ -201,6 +209,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace dimmer_switch { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::binding::config_t binding; } config_t; @@ -213,6 +222,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace color_dimmer_switch { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::binding::config_t binding; } config_t; @@ -225,6 +235,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace generic_switch { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::switch_cluster::config_t switch_cluster; } config_t; @@ -237,6 +248,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace on_off_plugin_unit { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::groups::config_t groups; cluster::scenes::config_t scenes; @@ -251,6 +263,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace dimmable_plugin_unit { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::groups::config_t groups; cluster::scenes::config_t scenes; @@ -266,6 +279,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace fan { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::groups::config_t groups; cluster::fan_control::config_t fan_control; @@ -279,6 +293,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace thermostat { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::scenes::config_t scenes; cluster::thermostat::config_t thermostat; @@ -291,14 +306,19 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); } /* thermostat */ namespace aggregator { +typedef struct config { + cluster::descriptor::config_t descriptor; +} config_t; + uint32_t get_device_type_id(); uint8_t get_device_type_version(); -endpoint_t *create(node_t *node, uint8_t flags, void *priv_data); -endpoint_t *add(endpoint_t *endpoint); +endpoint_t *create(node_t *node, config_t *config, uint8_t flags, void *priv_data); +endpoint_t *add(endpoint_t *endpoint, config_t *config); } /* aggregator */ namespace bridged_node { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::bridged_device_basic_information::config_t bridged_device_basic_information; } config_t; @@ -311,6 +331,7 @@ endpoint_t *resume(node_t *node, config_t *config, uint8_t flags, uint16_t endpo namespace door_lock { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::door_lock::config_t door_lock; } config_t; @@ -323,6 +344,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace window_covering_device { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::groups::config_t groups; cluster::scenes::config_t scenes; @@ -338,6 +360,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace temperature_sensor { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::temperature_measurement::config_t temperature_measurement; } config_t; @@ -350,6 +373,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace humidity_sensor { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::relative_humidity_measurement::config_t relative_humidity_measurement; } config_t; @@ -362,6 +386,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace occupancy_sensor { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::occupancy_sensing::config_t occupancy_sensing; } config_t; @@ -374,6 +399,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace contact_sensor { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::boolean_state::config_t boolean_state; } config_t; @@ -386,6 +412,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace light_sensor { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::illuminance_measurement::config_t illuminance_measurement; } config_t; @@ -398,6 +425,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace pressure_sensor { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::pressure_measurement::config_t pressure_measurement; } config_t; @@ -410,6 +438,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace flow_sensor { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::flow_measurement::config_t flow_measurement; } config_t; @@ -422,6 +451,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace pump{ typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify::config_t identify; cluster::on_off::config_t on_off; cluster::pump_configuration_and_control::config_t pump_configuration_and_control; @@ -440,6 +470,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace mode_select_device { typedef struct config { + cluster::descriptor::config_t descriptor; cluster::mode_select::config_t mode_select; } config_t; @@ -451,6 +482,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace room_air_conditioner{ typedef struct config { + cluster::descriptor::config_t descriptor; cluster::identify:: config_t identify; cluster::on_off::config_t on_off; cluster::thermostat::config_t thermostat; @@ -464,6 +496,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace temperature_controlled_cabinet{ typedef struct config { + cluster::descriptor::config_t descriptor; cluster::temperature_control::config_t temperature_control; } config_t; @@ -475,6 +508,7 @@ endpoint_t *add(endpoint_t *endpoint, config_t *config); namespace refrigerator{ typedef struct config { + cluster::descriptor::config_t descriptor; } config_t; uint32_t get_device_type_id(); diff --git a/components/esp_matter/esp_matter_feature.cpp b/components/esp_matter/esp_matter_feature.cpp index 3839003db..c2eebfc8c 100644 --- a/components/esp_matter/esp_matter_feature.cpp +++ b/components/esp_matter/esp_matter_feature.cpp @@ -356,8 +356,8 @@ esp_err_t add(cluster_t *cluster, config_t *config) update_color_capability(cluster, get_id()); /* Attributes not managed internally */ - attribute::create_current_hue(cluster, config->current_hue); - attribute::create_current_saturation(cluster, config->current_saturation); + attribute::create_current_hue(cluster, config->current_hue, 0, 254); + attribute::create_current_saturation(cluster, config->current_saturation, 0, 254); /* Commands */ command::create_move_to_hue(cluster); @@ -391,11 +391,11 @@ esp_err_t add(cluster_t *cluster, config_t *config) update_color_capability(cluster, get_id()); /* Attributes not managed internally */ - attribute::create_color_temperature_mireds(cluster, config->color_temperature_mireds); - attribute::create_color_temp_physical_min_mireds(cluster, config->color_temp_physical_min_mireds); - attribute::create_color_temp_physical_max_mireds(cluster, config->color_temp_physical_max_mireds); - attribute::create_couple_color_temp_to_level_min_mireds(cluster, config->couple_color_temp_to_level_min_mireds); - attribute::create_startup_color_temperature_mireds(cluster, config->startup_color_temperature_mireds); + attribute::create_color_temperature_mireds(cluster, config->color_temperature_mireds, 0, 0xfeff); + attribute::create_color_temp_physical_min_mireds(cluster, config->color_temp_physical_min_mireds, 0, 0xfeff); + attribute::create_color_temp_physical_max_mireds(cluster, config->color_temp_physical_max_mireds, 0, 0xfeff); + attribute::create_couple_color_temp_to_level_min_mireds(cluster, config->couple_color_temp_to_level_min_mireds, config->color_temp_physical_min_mireds, config->color_temperature_mireds); + attribute::create_startup_color_temperature_mireds(cluster, config->startup_color_temperature_mireds, 0, 0xfeff); /* Commands */ command::create_move_to_color_temperature(cluster); @@ -425,8 +425,8 @@ esp_err_t add(cluster_t *cluster, config_t *config) update_color_capability(cluster, get_id()); /* Attributes not managed internally */ - attribute::create_current_x(cluster, config->current_x); - attribute::create_current_y(cluster, config->current_y); + attribute::create_current_x(cluster, config->current_x, 0, 0xfeff); + attribute::create_current_y(cluster, config->current_y, 0, 0xfeff); /* Commands */ command::create_move_to_color(cluster); diff --git a/examples/all_device_types_app/main/esp_matter_console_helpers.cpp b/examples/all_device_types_app/main/esp_matter_console_helpers.cpp index 499a141e5..470475740 100644 --- a/examples/all_device_types_app/main/esp_matter_console_helpers.cpp +++ b/examples/all_device_types_app/main/esp_matter_console_helpers.cpp @@ -206,7 +206,8 @@ int create(uint8_t device_type_index) break; } case ESP_MATTER_AGGREGATOR: { - endpoint = esp_matter::endpoint::aggregator::create(node, ENDPOINT_FLAG_NONE, NULL); + esp_matter::endpoint::aggregator::config_t aggregator_config; + endpoint = esp_matter::endpoint::aggregator::create(node, &aggregator_config, ENDPOINT_FLAG_NONE, NULL); break; } case ESP_MATTER_BRIDGED_NODE: { diff --git a/examples/blemesh_bridge/main/app_main.cpp b/examples/blemesh_bridge/main/app_main.cpp index 56c6c119d..293264d11 100644 --- a/examples/blemesh_bridge/main/app_main.cpp +++ b/examples/blemesh_bridge/main/app_main.cpp @@ -23,6 +23,7 @@ static const char *TAG = "app_main"; using namespace esp_matter; using namespace esp_matter::attribute; +using namespace esp_matter::endpoint; uint16_t aggregator_endpoint_id = chip::kInvalidEndpointId; @@ -88,7 +89,8 @@ extern "C" void app_main() ESP_LOGE(TAG, "Matter node creation failed"); } - endpoint_t *aggregator = endpoint::aggregator::create(node, ENDPOINT_FLAG_NONE, NULL); + aggregator::config_t aggregator_config; + endpoint_t *aggregator = endpoint::aggregator::create(node, &aggregator_config, ENDPOINT_FLAG_NONE, NULL); if (!aggregator) { ESP_LOGE(TAG, "Matter aggregator endpoint creation failed"); } diff --git a/examples/esp-now_bridge_light/main/app_main.cpp b/examples/esp-now_bridge_light/main/app_main.cpp index 8c5df33af..bcd0ca07e 100644 --- a/examples/esp-now_bridge_light/main/app_main.cpp +++ b/examples/esp-now_bridge_light/main/app_main.cpp @@ -118,7 +118,8 @@ extern "C" void app_main() ESP_LOGE(TAG, "Matter color temperature light endpoint creation failed"); } - endpoint_t *aggregator = endpoint::aggregator::create(node, ENDPOINT_FLAG_NONE, NULL); + aggregator::config_t aggregator_config; + endpoint_t *aggregator = endpoint::aggregator::create(node, &aggregator_config, ENDPOINT_FLAG_NONE, NULL); if (!aggregator) { ESP_LOGE(TAG, "Matter aggregator endpoint creation failed"); } diff --git a/examples/zigbee_bridge/main/app_main.cpp b/examples/zigbee_bridge/main/app_main.cpp index 81a32d26f..6a869f148 100644 --- a/examples/zigbee_bridge/main/app_main.cpp +++ b/examples/zigbee_bridge/main/app_main.cpp @@ -22,6 +22,7 @@ static const char *TAG = "app_main"; using namespace esp_matter; using namespace esp_matter::attribute; +using namespace esp_matter::endpoint; uint16_t aggregator_endpoint_id = chip::kInvalidEndpointId; @@ -88,7 +89,8 @@ extern "C" void app_main() ESP_LOGE(TAG, "Matter node creation failed"); } - endpoint_t *aggregator = endpoint::aggregator::create(node, ENDPOINT_FLAG_NONE, NULL); + aggregator::config_t aggregator_config; + endpoint_t *aggregator = endpoint::aggregator::create(node, &aggregator_config, ENDPOINT_FLAG_NONE, NULL); if (!aggregator) { ESP_LOGE(TAG, "Matter aggregator endpoint creation failed"); } else {