Skip to content

Commit b58a3da

Browse files
silabs-borislrzr
authored andcommitted
UIC-3222: Admin code support
1 parent d2fadef commit b58a3da

16 files changed

+1280
-352
lines changed

applications/zpc/components/zcl_cluster_servers/src/user_credential_cluster_server.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,51 @@ sl_status_t
615615
credential_type);
616616
}
617617

618+
sl_status_t admin_pin_code_set(dotdot_unid_t unid,
619+
dotdot_endpoint_id_t endpoint,
620+
uic_mqtt_dotdot_callback_call_type_t call_type,
621+
const char *credential_data)
622+
{
623+
attribute_store_node_t endpoint_node
624+
= attribute_store_network_helper_get_endpoint_node(unid, endpoint);
625+
626+
// Now that we know that the command is supported, return here if it is
627+
// a support check type of call.
628+
if (UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK == call_type) {
629+
return zwave_command_class_user_credential_supports(endpoint_node,
630+
ADMIN_PIN_CODE_SET)
631+
? SL_STATUS_OK
632+
: SL_STATUS_FAIL;
633+
}
634+
635+
return zwave_command_class_user_credential_set_admin_pin_code(
636+
endpoint_node,
637+
credential_data);
638+
}
639+
640+
sl_status_t
641+
admin_pin_code_deactivate(dotdot_unid_t unid,
642+
dotdot_endpoint_id_t endpoint,
643+
uic_mqtt_dotdot_callback_call_type_t call_type)
644+
{
645+
attribute_store_node_t endpoint_node
646+
= attribute_store_network_helper_get_endpoint_node(unid, endpoint);
647+
648+
// Now that we know that the command is supported, return here if it is
649+
// a support check type of call.
650+
if (UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK == call_type) {
651+
return (zwave_command_class_user_credential_supports(endpoint_node,
652+
ADMIN_PIN_CODE_SET)
653+
&& zwave_command_class_user_credential_supports_admin_pin_code_deactivation(
654+
endpoint_node))
655+
? SL_STATUS_OK
656+
: SL_STATUS_FAIL;
657+
}
658+
659+
return zwave_command_class_user_credential_set_admin_pin_code(endpoint_node,
660+
"");
661+
};
662+
618663
///////////////////////////////////////////////////////////////////////////////
619664
// Helpers functions
620665
//////////////////////////////////////////////////////////////////////////////
@@ -634,6 +679,35 @@ void register_attributes_to_mqtt_map(
634679
}
635680
}
636681

682+
///////////////////////////////////////////////////////////////////////////////
683+
// Callbacks
684+
//////////////////////////////////////////////////////////////////////////////
685+
void on_admin_pin_code_update(attribute_store_node_t updated_node,
686+
attribute_store_change_t change)
687+
{
688+
if (change != ATTRIBUTE_UPDATED) {
689+
return;
690+
}
691+
692+
attribute_store::attribute admin_pin_code_node(updated_node);
693+
if (!admin_pin_code_node.reported_exists()) {
694+
return;
695+
}
696+
697+
auto raw_pin_code = admin_pin_code_node.reported<std::vector<uint8_t>>();
698+
std::string pin_code_str(raw_pin_code.begin(), raw_pin_code.end());
699+
700+
try {
701+
admin_pin_code_node.first_parent(ATTRIBUTE_ENDPOINT_ID)
702+
.emplace_node(DOTDOT_ATTRIBUTE_ID_USER_CREDENTIAL_ADMIN_PIN_CODE)
703+
.set_reported(pin_code_str);
704+
} catch (const std::exception &e) {
705+
sl_log_error(LOG_TAG,
706+
"Error while updating ZLC Admin Pin Code attribute : %s",
707+
e.what());
708+
}
709+
}
710+
637711
///////////////////////////////////////////////////////////////////////////////
638712
// MQTT Helpers functions
639713
//////////////////////////////////////////////////////////////////////////////
@@ -1135,5 +1209,17 @@ sl_status_t user_credential_cluster_server_init()
11351209
// All Users Checksum
11361210
uic_mqtt_dotdot_user_credential_get_all_users_checksum_callback_set(
11371211
&get_all_users_checksum);
1212+
// Admin PIN code
1213+
uic_mqtt_dotdot_user_credential_set_admin_pin_code_callback_set(
1214+
&admin_pin_code_set);
1215+
uic_mqtt_dotdot_user_credential_deactivate_admin_pin_code_callback_set(
1216+
&admin_pin_code_deactivate);
1217+
1218+
// Types that can't be mapped with UAM
1219+
attribute_store_register_callback_by_type_and_state(
1220+
&on_admin_pin_code_update,
1221+
ATTRIBUTE(ADMIN_PIN_CODE),
1222+
REPORTED_ATTRIBUTE);
1223+
11381224
return SL_STATUS_OK;
11391225
}

applications/zpc/components/zcl_cluster_servers/test/user_credential_cluster_server_test.cpp

Lines changed: 122 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ uic_mqtt_dotdot_user_credential_credential_association_callback_t credential_ass
9191
uic_mqtt_dotdot_user_credential_get_user_checksum_callback_t get_user_checksum_command = NULL;
9292
uic_mqtt_dotdot_user_credential_get_credential_checksum_callback_t get_credential_checksum_command = NULL;
9393
uic_mqtt_dotdot_user_credential_get_all_users_checksum_callback_t get_all_users_checksum_command = NULL;
94+
uic_mqtt_dotdot_user_credential_set_admin_pin_code_callback_t set_admin_pin_code_command = NULL;
95+
uic_mqtt_dotdot_user_credential_deactivate_admin_pin_code_callback_t deactivate_admin_pin_code_command = NULL;
9496
// clang-format on
9597

9698
// Stub functions for intercepting callback registration.
@@ -223,6 +225,20 @@ void uic_mqtt_dotdot_user_credential_get_all_users_checksum_callback_set_stub(
223225
get_all_users_checksum_command = callback;
224226
}
225227

228+
void uic_mqtt_dotdot_user_credential_set_admin_pin_code_callback_set_stub(
229+
const uic_mqtt_dotdot_user_credential_set_admin_pin_code_callback_t callback,
230+
int cmock_num_calls)
231+
{
232+
set_admin_pin_code_command = callback;
233+
}
234+
235+
void uic_mqtt_dotdot_user_credential_deactivate_admin_pin_code_callback_set_stub(
236+
const uic_mqtt_dotdot_user_credential_deactivate_admin_pin_code_callback_t
237+
callback,
238+
int cmock_num_calls)
239+
{
240+
deactivate_admin_pin_code_command = callback;
241+
}
226242

227243
/// Setup the test suite (called once before all test_xxx functions are called)
228244
void suiteSetUp()
@@ -308,6 +324,9 @@ void setUp()
308324
// Credential checksum
309325
uic_mqtt_dotdot_user_credential_get_credential_checksum_callback_set_Stub(&uic_mqtt_dotdot_user_credential_get_credential_checksum_callback_set_stub);
310326
uic_mqtt_dotdot_user_credential_get_all_users_checksum_callback_set_Stub(&uic_mqtt_dotdot_user_credential_get_all_users_checksum_callback_set_stub);
327+
// Admin code
328+
uic_mqtt_dotdot_user_credential_set_admin_pin_code_callback_set_Stub(&uic_mqtt_dotdot_user_credential_set_admin_pin_code_callback_set_stub);
329+
uic_mqtt_dotdot_user_credential_deactivate_admin_pin_code_callback_set_Stub(&uic_mqtt_dotdot_user_credential_deactivate_admin_pin_code_callback_set_stub);
311330
// clang-format on
312331

313332
// Run the component init
@@ -321,16 +340,21 @@ void setUp()
321340

322341
// Setup helper
323342
cpp_endpoint_node = attribute_store::attribute(endpoint_id_node);
324-
}
325343

326-
void set_version(zwave_cc_version_t version)
327-
{
328-
// Set the version
329-
cpp_endpoint_node
330-
.emplace_node(ATTRIBUTE(VERSION))
331-
.set_reported(version);
344+
// Setup global cred capabilities
345+
cpp_endpoint_node.emplace_node(ATTRIBUTE(SUPPORT_ADMIN_PIN_CODE),
346+
static_cast<uint8_t>(1));
347+
cpp_endpoint_node.emplace_node(ATTRIBUTE(SUPPORT_CREDENTIAL_CHECKSUM),
348+
static_cast<uint8_t>(1));
349+
cpp_endpoint_node.emplace_node(ATTRIBUTE(SUPPORT_ADMIN_PIN_CODE_DEACTIVATION),
350+
static_cast<uint8_t>(1));
351+
352+
// Set command class version
353+
cpp_endpoint_node.emplace_node(ATTRIBUTE(VERSION)).set_reported(1);
332354
}
333355

356+
357+
334358
/////////////////////////////////////////////////////////////////////////
335359
// Mqtt topics helpers
336360
/////////////////////////////////////////////////////////////////////////
@@ -2381,8 +2405,6 @@ void test_user_credential_cluster_test_credential_checksum_happy_case()
23812405

23822406
void test_user_credential_cluster_test_all_users_checksum_happy_case()
23832407
{
2384-
set_version(1);
2385-
23862408
// Command not supported yet (default user capabilities SUPPORT_ALL_USERS_CHECKSUM set to 0)
23872409
TEST_ASSERT_EQUAL_MESSAGE(
23882410
SL_STATUS_FAIL,
@@ -2428,6 +2450,96 @@ void test_user_credential_cluster_test_all_users_checksum_happy_case()
24282450
"Checksum node reported value should NOT exists");
24292451
}
24302452

2453+
void test_user_credential_cluster_test_admin_set_command_happy_case()
2454+
{
2455+
auto support_admin_pin_code_node
2456+
= cpp_endpoint_node.emplace_node(ATTRIBUTE(SUPPORT_ADMIN_PIN_CODE))
2457+
.set_reported<uint8_t>(0);
2458+
auto status
2459+
= set_admin_pin_code_command(supporting_node_unid,
2460+
endpoint_id,
2461+
UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK,
2462+
"");
2463+
TEST_ASSERT_EQUAL_MESSAGE(
2464+
SL_STATUS_FAIL,
2465+
status,
2466+
"Admin set should NOT be supported since SUPPORT_ADMIN_PIN_CODE is 0");
2467+
2468+
support_admin_pin_code_node.set_reported<uint8_t>(1);
2469+
2470+
status
2471+
= set_admin_pin_code_command(supporting_node_unid,
2472+
endpoint_id,
2473+
UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK,
2474+
"");
2475+
2476+
TEST_ASSERT_EQUAL_MESSAGE(
2477+
SL_STATUS_OK,
2478+
status,
2479+
"Admin set should be supported since SUPPORT_ADMIN_PIN_CODE is 1");
2480+
2481+
std::string expected_pin_code = "1234";
2482+
status
2483+
= set_admin_pin_code_command(supporting_node_unid,
2484+
endpoint_id,
2485+
UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL,
2486+
expected_pin_code.c_str());
2487+
2488+
auto raw_pin_code
2489+
= cpp_endpoint_node.child_by_type(ATTRIBUTE(ADMIN_PIN_CODE))
2490+
.desired<std::vector<uint8_t>>();
2491+
2492+
std::string reported_pin_code;
2493+
for (char c : raw_pin_code) {
2494+
reported_pin_code += c;
2495+
}
2496+
2497+
TEST_ASSERT_EQUAL_STRING_MESSAGE(expected_pin_code.c_str(),
2498+
reported_pin_code.c_str(),
2499+
"Admin pin code mismatch");
2500+
}
2501+
2502+
void test_user_credential_cluster_test_admin_deactivate_command_happy_case()
2503+
{
2504+
auto support_admin_deactivation_node
2505+
= cpp_endpoint_node
2506+
.emplace_node(ATTRIBUTE(SUPPORT_ADMIN_PIN_CODE_DEACTIVATION))
2507+
.set_reported<uint8_t>(0);
2508+
auto status = deactivate_admin_pin_code_command(
2509+
supporting_node_unid,
2510+
endpoint_id,
2511+
UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK);
2512+
TEST_ASSERT_EQUAL_MESSAGE(SL_STATUS_FAIL,
2513+
status,
2514+
"Admin deactivation should NOT be supported since "
2515+
"SUPPORT_ADMIN_PIN_CODE_DEACTIVATION is 0");
2516+
2517+
support_admin_deactivation_node.set_reported<uint8_t>(1);
2518+
2519+
status = deactivate_admin_pin_code_command(
2520+
supporting_node_unid,
2521+
endpoint_id,
2522+
UIC_MQTT_DOTDOT_CALLBACK_TYPE_SUPPORT_CHECK);
2523+
2524+
TEST_ASSERT_EQUAL_MESSAGE(
2525+
SL_STATUS_OK,
2526+
status,
2527+
"Admin deactivation should be supported since SUPPORT_ADMIN_PIN_CODE is 1");
2528+
2529+
status
2530+
= deactivate_admin_pin_code_command(supporting_node_unid,
2531+
endpoint_id,
2532+
UIC_MQTT_DOTDOT_CALLBACK_TYPE_NORMAL);
2533+
2534+
std::vector<uint8_t> expected_empty_pin_code = {0};
2535+
TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(
2536+
expected_empty_pin_code.data(),
2537+
cpp_endpoint_node.child_by_type(ATTRIBUTE(ADMIN_PIN_CODE))
2538+
.desired<std::vector<uint8_t>>()
2539+
.data(),
2540+
expected_empty_pin_code.size(),
2541+
"Admin pin code should be at empty value");
2542+
}
24312543

24322544
///////////////////////////////////////////////////
24332545
// Support tests
@@ -2538,4 +2650,5 @@ void test_user_credential_cluster_test_user_command_not_supported_happy_case()
25382650
"Delete user should not be supported");
25392651
}
25402652

2653+
25412654
} // extern "C"

0 commit comments

Comments
 (0)