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 {