Skip to content

Commit

Permalink
SiliconLabsGH-36: Send 0xFF by default for endpoint_find controllable…
Browse files Browse the repository at this point in the history
… 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: SiliconLabs#36
Bug-SiliconLabs: UIC-3160
Bug-Github: SiliconLabs#36
  • Loading branch information
silabs-borisl committed Mar 12, 2024
1 parent 3b43b68 commit 21e4efe
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 21 deletions.
Expand Up @@ -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,
Expand Down
Expand Up @@ -249,6 +249,8 @@ static const std::vector<attribute_schema_t> 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
/////////////////////////////////////////////////////////////////////
Expand Down
Expand Up @@ -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
Expand Down
Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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;
Expand Down

0 comments on commit 21e4efe

Please sign in to comment.