Skip to content

Commit 83941c1

Browse files
committed
GH-43: credentials: Fix User post-interview discovery
This patch will : - Not delete all user database en Unify startup - Allow the user to re-initiate an interview with the device and discover again all users Bug-SiliconLabs: UIC-3222 Bug-GitHub: #43 Signed-off-by: Philippe Coval <[email protected]>
1 parent 61fbaef commit 83941c1

File tree

2 files changed

+58
-31
lines changed

2 files changed

+58
-31
lines changed

applications/zpc/components/zwave_command_classes/src/zwave_command_class_user_credential.cpp

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2317,9 +2317,29 @@ static sl_status_t zwave_command_class_user_credential_user_get(
23172317
sl_status_t status
23182318
= attribute_store_get_desired(node, &user_id, sizeof(user_id));
23192319

2320+
// If we enter this state it means that something went badly wrong or
2321+
// user initiate the interview process again.
2322+
// In both cases we want to invalidate the user database so that the device
2323+
// can send us the correct user database.
23202324
if (status != SL_STATUS_OK) {
2321-
sl_log_error(LOG_TAG,
2322-
"Can't get user unique id value. Not sending USER_GET.");
2325+
sl_log_warning(LOG_TAG,
2326+
"Can't get user unique id value. Reset user database.");
2327+
attribute_store_node_t endpoint_node
2328+
= attribute_store_get_node_parent(node);
2329+
// Get User node count
2330+
auto user_count = attribute_store_get_node_child_count_by_type(
2331+
endpoint_node,
2332+
ATTRIBUTE(USER_UNIQUE_ID));
2333+
2334+
for (size_t j = 0; j < user_count; j++) {
2335+
// Delete the first attribute we find until we have no more left
2336+
attribute_store_node_t user_node
2337+
= attribute_store_get_node_child_by_type(endpoint_node,
2338+
ATTRIBUTE(USER_UNIQUE_ID),
2339+
0);
2340+
attribute_store_delete_node(user_node);
2341+
}
2342+
// NOTE : In the case of user re-interviewing the device, it will be interviewed again when the node goes ONLINE.
23232343
return SL_STATUS_NOT_SUPPORTED;
23242344
}
23252345

@@ -2549,23 +2569,14 @@ void zwave_network_status_changed(attribute_store_node_t updated_node,
25492569
auto user_count = attribute_store_get_node_child_count_by_type(
25502570
endpoint_node,
25512571
ATTRIBUTE(USER_UNIQUE_ID));
2552-
sl_log_debug(LOG_TAG,
2553-
"Endpoint %d supports User Credential. Removing all "
2554-
"existing user nodes (%d)...",
2555-
i,
2556-
user_count);
2557-
for (size_t j = 0; j < user_count; j++) {
2558-
// Delete the first attribute we find until we have no more left
2559-
attribute_store_node_t user_node
2560-
= attribute_store_get_node_child_by_type(endpoint_node,
2561-
ATTRIBUTE(USER_UNIQUE_ID),
2562-
0);
2563-
attribute_store_delete_node(user_node);
2572+
sl_log_debug(LOG_TAG, "Endpoint %d supports User Credential.", endpoint_id);
2573+
if (user_count == 0) {
2574+
sl_log_debug(LOG_TAG, "No user found. Starting User and Credential interview");
2575+
// Start the interview process with user ID = 0
2576+
trigger_get_user(endpoint_node, 0);
2577+
} else {
2578+
sl_log_debug(LOG_TAG, "Users already discovered. No actions needed.");
25642579
}
2565-
2566-
sl_log_debug(LOG_TAG, "Starting User and Credential interview");
2567-
// Start the interview process with user ID = 0
2568-
trigger_get_user(endpoint_node, 0);
25692580
}
25702581
}
25712582
}

applications/zpc/components/zwave_command_classes/test/zwave_command_class_user_credential_test.cpp

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2100,18 +2100,6 @@ void test_post_interview_discovery()
21002100
// Display current store log for debug purpose
21012101
attribute_store_log();
21022102

2103-
// Set two random user id to see if discovery remove it
2104-
user_credential_user_unique_id_t user_id = 12;
2105-
attribute_store_emplace(endpoint_id_node,
2106-
ATTRIBUTE(USER_UNIQUE_ID),
2107-
&user_id,
2108-
sizeof(user_id));
2109-
user_id = 1222;
2110-
attribute_store_emplace(endpoint_id_node,
2111-
ATTRIBUTE(USER_UNIQUE_ID),
2112-
&user_id,
2113-
sizeof(user_id));
2114-
21152103
// Set the network status to online
21162104
network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL;
21172105
attribute_store_set_reported(network_status_node,
@@ -2122,13 +2110,41 @@ void test_post_interview_discovery()
21222110
auto user_id_node
21232111
= attribute_store_get_first_child_by_type(endpoint_id_node,
21242112
ATTRIBUTE(USER_UNIQUE_ID));
2125-
2113+
user_credential_user_unique_id_t user_id = 0;
21262114
attribute_store_get_desired(user_id_node, &user_id, sizeof(user_id));
21272115
TEST_ASSERT_NOT_EQUAL_MESSAGE(ATTRIBUTE_STORE_INVALID_NODE,
21282116
user_id_node,
21292117
"User id node should exists");
21302118
TEST_ASSERT_EQUAL_MESSAGE(0, user_id, "User ID desired value should be 0");
21312119
count_user_node(1);
2120+
2121+
// Simulate user found
2122+
user_id = 12;
2123+
attribute_store_set_reported(user_id_node, &user_id, sizeof(user_id));
2124+
2125+
// Go back to Interview state
2126+
network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_INTERVIEWING;
2127+
attribute_store_set_reported(network_status_node,
2128+
&network_status,
2129+
sizeof(network_status));
2130+
2131+
// Then back in Online Functional
2132+
network_status = ZCL_NODE_STATE_NETWORK_STATUS_ONLINE_FUNCTIONAL;
2133+
attribute_store_set_reported(network_status_node,
2134+
&network_status,
2135+
sizeof(network_status));
2136+
// User should still be there
2137+
count_user_node(1);
2138+
// With right value
2139+
user_credential_user_unique_id_t reported_user_id = 0;
2140+
user_id_node = attribute_store_get_first_child_by_type(endpoint_id_node,
2141+
ATTRIBUTE(USER_UNIQUE_ID));
2142+
attribute_store_get_reported(user_id_node,
2143+
&reported_user_id,
2144+
sizeof(reported_user_id));
2145+
TEST_ASSERT_EQUAL_MESSAGE(user_id,
2146+
reported_user_id,
2147+
"User ID reported value should be 12.");
21322148
}
21332149

21342150
void test_user_credential_notification_empty_parameters()

0 commit comments

Comments
 (0)