From 21e4efe862204976de862a6119a2d821f23d25ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boris=20Labb=C3=A9?= Date: Tue, 12 Mar 2024 11:48:12 +0100 Subject: [PATCH] GH-36: Send 0xFF by default for endpoint_find controllable with a flag A new flag have been introduced to send the endpoint Generic/Specific class in multi_channel_endpoint_find. The default behavior is to send 0xFF to discover all endpoints. Forwarded: https://github.com/SiliconLabs/UnifySDK/pull/36 Bug-SiliconLabs: UIC-3160 Bug-Github: https://github.com/SiliconLabs/UnifySDK/pull/36 --- .../attribute_store_defined_attribute_types.h | 4 + .../zpc_attribute_store_type_registration.cpp | 2 + .../src/zwave_command_class_multi_channel.c | 54 +++++++----- .../zwave_command_class_multi_channel_test.c | 87 ++++++++++++++++++- 4 files changed, 126 insertions(+), 21 deletions(-) diff --git a/applications/zpc/components/zpc_attribute_store/include/attribute_store_defined_attribute_types.h b/applications/zpc/components/zpc_attribute_store/include/attribute_store_defined_attribute_types.h index 78ca2909e5..bc0b4c0297 100644 --- a/applications/zpc/components/zpc_attribute_store/include/attribute_store_defined_attribute_types.h +++ b/applications/zpc/components/zpc_attribute_store/include/attribute_store_defined_attribute_types.h @@ -613,6 +613,10 @@ DEFINE_ATTRIBUTE( DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_AGGREGATED_MEMBERS, ((COMMAND_CLASS_MULTI_CHANNEL_V3 << 8) | 0x06)) +/** If set will send the endpoint Generic/Specific device class in ZW_MULTI_CHANNEL_END_POINT_FIND */ +DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_FLAG_SEND_TARGETED_DEVICE_CLASS, + ((COMMAND_CLASS_MULTI_CHANNEL_V3 << 8) | 0x07)) + ///////////////////////////////////////////////// // Notification Command Class DEFINE_ATTRIBUTE(ATTRIBUTE_COMMAND_CLASS_NOTIFICATION_VERSION, diff --git a/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_type_registration.cpp b/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_type_registration.cpp index 774ba2882d..0ba9b26319 100644 --- a/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_type_registration.cpp +++ b/applications/zpc/components/zpc_attribute_store/src/zpc_attribute_store_type_registration.cpp @@ -249,6 +249,8 @@ static const std::vector attribute_schema = { {ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_AGGREGATED_ENDPOINTS, "Aggregated Endpoints", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_ALL_INDIVIDUAL_ENDPOINTS_FOUND, "All Endpoints discovered", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, {ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_AGGREGATED_MEMBERS, "Aggregated endpoint members bitmask", ATTRIBUTE_ENDPOINT_ID, BYTE_ARRAY_STORAGE_TYPE}, + {ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_FLAG_SEND_TARGETED_DEVICE_CLASS, "If set will send the endpoint Generic/Specific device class in ZW_MULTI_CHANNEL_END_POINT_FIND", ATTRIBUTE_ENDPOINT_ID, U8_STORAGE_TYPE}, + ///////////////////////////////////////////////////////////////////// // Notification Command Class attributes ///////////////////////////////////////////////////////////////////// diff --git a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_multi_channel.c b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_multi_channel.c index 03bbe48145..87c35cf950 100644 --- a/applications/zpc/components/zwave_command_classes/src/zwave_command_class_multi_channel.c +++ b/applications/zpc/components/zwave_command_classes/src/zwave_command_class_multi_channel.c @@ -558,32 +558,46 @@ sl_status_t zwave_command_class_multi_channel_capability_get( static sl_status_t zwave_command_class_multi_channel_endpoint_find( attribute_store_node_t node, uint8_t *frame, uint16_t *frame_len) { - uint8_t generic_device_class = 0; - uint8_t specific_device_class = 0; + uint8_t generic_device_class = 0xFF; + uint8_t specific_device_class = 0xFF; attribute_store_node_t endpoint_node = attribute_store_get_first_parent_with_type(node, ATTRIBUTE_ENDPOINT_ID); - sl_status_t result = attribute_store_get_child_reported( + uint8_t endpoint_find_legacy = 0; + sl_status_t status = attribute_store_get_child_reported( endpoint_node, - ATTRIBUTE_ZWAVE_GENERIC_DEVICE_CLASS, - &generic_device_class, - sizeof(generic_device_class)); - - if (result != SL_STATUS_OK) { - sl_log_warning(LOG_TAG, "Can't find generic device class. Setting to default 0xff"); - generic_device_class = 0xFF; - } - - result = attribute_store_get_child_reported( - endpoint_node, - ATTRIBUTE_ZWAVE_SPECIFIC_DEVICE_CLASS, - &specific_device_class, - sizeof(specific_device_class)); + ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_FLAG_SEND_TARGETED_DEVICE_CLASS, + &endpoint_find_legacy, + sizeof(endpoint_find_legacy)); + + // By default we use 0xFF to discover all endpoint supported by the device. + // Some legacy device doesn't support 0xFF and needs to send the device Generic/Specific class instead + // So we use a flag to control that behavior + if (status == SL_STATUS_OK && endpoint_find_legacy) { + sl_status_t result + = attribute_store_get_child_reported(endpoint_node, + ATTRIBUTE_ZWAVE_GENERIC_DEVICE_CLASS, + &generic_device_class, + sizeof(generic_device_class)); + + if (result != SL_STATUS_OK) { + sl_log_warning( + LOG_TAG, + "Can't find generic device class. Setting to default 0xff"); + } - if (result != SL_STATUS_OK) { - sl_log_warning(LOG_TAG, "Can't find specific device class. Setting to default 0xff"); - specific_device_class = 0xFF; + result = attribute_store_get_child_reported( + endpoint_node, + ATTRIBUTE_ZWAVE_SPECIFIC_DEVICE_CLASS, + &specific_device_class, + sizeof(specific_device_class)); + + if (result != SL_STATUS_OK) { + sl_log_warning( + LOG_TAG, + "Can't find specific device class. Setting to default 0xff"); + } } // Create a frame for the attribute resolver diff --git a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_multi_channel_test.c b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_multi_channel_test.c index d9b033a824..a93f9f2c42 100644 --- a/applications/zpc/components/zwave_command_classes/test/zwave_command_class_multi_channel_test.c +++ b/applications/zpc/components/zwave_command_classes/test/zwave_command_class_multi_channel_test.c @@ -179,7 +179,7 @@ void test_zwave_command_class_multi_channel_capability_get_happy_case() last_received_frame_length); } -void test_zwave_command_class_multi_channel_endpoint_find() +void test_zwave_command_class_multi_channel_endpoint_find_with_flag() { attribute_store_node_t test_node = 0x9485; attribute_store_node_t test_endpoint_node = 0xf7; @@ -189,6 +189,19 @@ void test_zwave_command_class_multi_channel_endpoint_find() ATTRIBUTE_ENDPOINT_ID, test_endpoint_node); + // Set legacy flag + uint8_t legacy_flag = 1; + attribute_store_get_child_reported_ExpectAndReturn(test_endpoint_node, + ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_FLAG_SEND_TARGETED_DEVICE_CLASS, + NULL, + sizeof(uint8_t), + SL_STATUS_OK); + attribute_store_get_child_reported_IgnoreArg_value(); + attribute_store_get_child_reported_ReturnMemThruPtr_value( + &legacy_flag, + sizeof(legacy_flag)); + + // Simulate not existing parameter uint8_t generic_device_class = 0xFF; attribute_store_get_child_reported_ExpectAndReturn(test_endpoint_node, @@ -212,6 +225,8 @@ void test_zwave_command_class_multi_channel_endpoint_find() sizeof(specific_device_class)); + + TEST_ASSERT_EQUAL(SL_STATUS_OK, zwave_command_class_multi_channel_endpoint_find( test_node, @@ -227,7 +242,77 @@ void test_zwave_command_class_multi_channel_endpoint_find() last_received_frame, last_received_frame_length); } +void test_zwave_command_class_multi_channel_endpoint_find_no_flag() +{ + attribute_store_node_t test_node = 0x9485; + attribute_store_node_t test_endpoint_node = 0xf7; + + attribute_store_get_first_parent_with_type_ExpectAndReturn( + test_node, + ATTRIBUTE_ENDPOINT_ID, + test_endpoint_node); + + + attribute_store_get_child_reported_ExpectAndReturn(test_endpoint_node, + ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_FLAG_SEND_TARGETED_DEVICE_CLASS, + NULL, + sizeof(uint8_t), + SL_STATUS_FAIL); + attribute_store_get_child_reported_IgnoreArg_value(); + + TEST_ASSERT_EQUAL(SL_STATUS_OK, + zwave_command_class_multi_channel_endpoint_find( + test_node, + last_received_frame, + &last_received_frame_length)); + + const uint8_t expected_frame_data[] = {COMMAND_CLASS_MULTI_CHANNEL_V4, + MULTI_CHANNEL_END_POINT_FIND_V4, + 0xFF, + 0xFF}; + TEST_ASSERT_EQUAL(sizeof(expected_frame_data), last_received_frame_length); + TEST_ASSERT_EQUAL_INT8_ARRAY(expected_frame_data, + last_received_frame, + last_received_frame_length); +} + +void test_zwave_command_class_multi_channel_endpoint_find_flag_but_off() +{ + attribute_store_node_t test_node = 0x9485; + attribute_store_node_t test_endpoint_node = 0xf7; + + attribute_store_get_first_parent_with_type_ExpectAndReturn( + test_node, + ATTRIBUTE_ENDPOINT_ID, + test_endpoint_node); + + // Set legacy flag + uint8_t legacy_flag = 0; + attribute_store_get_child_reported_ExpectAndReturn(test_endpoint_node, + ATTRIBUTE_COMMAND_CLASS_MULTI_CHANNEL_FLAG_SEND_TARGETED_DEVICE_CLASS, + NULL, + sizeof(uint8_t), + SL_STATUS_OK); + attribute_store_get_child_reported_IgnoreArg_value(); + attribute_store_get_child_reported_ReturnMemThruPtr_value( + &legacy_flag, + sizeof(legacy_flag)); + TEST_ASSERT_EQUAL(SL_STATUS_OK, + zwave_command_class_multi_channel_endpoint_find( + test_node, + last_received_frame, + &last_received_frame_length)); + + const uint8_t expected_frame_data[] = {COMMAND_CLASS_MULTI_CHANNEL_V4, + MULTI_CHANNEL_END_POINT_FIND_V4, + 0xFF, + 0xFF}; + TEST_ASSERT_EQUAL(sizeof(expected_frame_data), last_received_frame_length); + TEST_ASSERT_EQUAL_INT8_ARRAY(expected_frame_data, + last_received_frame, + last_received_frame_length); +} void test_zwave_command_class_multi_channel_aggregated_members_get_endpoint_0() { attribute_store_node_t test_node = 12345;