Skip to content

Commit f2ee9f3

Browse files
silabs-borislrzr
authored andcommitted
UIC-3222: Move User credential API into their own files
Top level API is now available directly with an header to avoid base file to be too big
1 parent 7831d91 commit f2ee9f3

File tree

9 files changed

+2156
-2060
lines changed

9 files changed

+2156
-2060
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include "user_credential_cluster_server.h"
1414
#include "zcl_cluster_servers_helpers.hpp"
1515
// Interfaces
16-
#include "zwave_command_class_user_credential.h"
16+
#include "zwave_command_class_user_credential_api.h"
1717

1818
// ZPC includes
1919
#include "zpc_attribute_store.h"

applications/zpc/components/zwave_command_classes/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ add_library(
5757
src/zwave_command_class_time.c
5858
src/zwave_command_class_user_code.c
5959
src/zwave_command_class_user_credential.cpp
60+
src/zwave_command_class_user_credential_api.cpp
6061
src/zwave_command_class_version.c
6162
src/zwave_command_class_wake_up.c
6263
src/zwave_command_class_zwave_plus_info.c
@@ -67,6 +68,7 @@ add_library(
6768
src/zwave_command_class_protocol.c
6869
src/private/user_credential/user_credential_user_capabilities.cpp
6970
src/private/user_credential/user_credential_credential_capabilities.cpp
71+
src/private/user_credential/user_credential_checksum_calculator.cpp
7072
)
7173
install(TARGETS zwave_command_classes LIBRARY DESTINATION lib)
7274

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
/******************************************************************************
2+
* # License
3+
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
4+
******************************************************************************
5+
* The licensor of this software is Silicon Laboratories Inc. Your use of this
6+
* software is governed by the terms of Silicon Labs Master Software License
7+
* Agreement (MSLA) available at
8+
* www.silabs.com/about-us/legal/master-software-license-agreement. This
9+
* software is distributed to you in Source Code format and is governed by the
10+
* sections of the MSLA applicable to Source Code.
11+
*
12+
*****************************************************************************/
13+
// Get attribute store names
14+
#include "user_credential_helpers.hpp"
15+
16+
#include "boost/format.hpp"
17+
18+
namespace user_credential_helpers
19+
{
20+
21+
22+
void set_operation_type(attribute_store::attribute base_node,
23+
attribute_store_type_t operation_type_node_type,
24+
user_credential_operation_type_t operation_type)
25+
{
26+
auto operation_type_node = base_node.emplace_node(operation_type_node_type);
27+
28+
// Undefine reported to be sure that we can so the same operation twice in a row
29+
operation_type_node.clear_reported();
30+
operation_type_node.set_desired(operation_type);
31+
}
32+
33+
void set_user_operation_type(attribute_store_node_t user_node,
34+
user_credential_operation_type_t operation_type)
35+
{
36+
set_operation_type(
37+
user_node,
38+
ATTRIBUTE(USER_OPERATION_TYPE),
39+
operation_type);
40+
}
41+
42+
void set_credential_operation_type(
43+
attribute_store_node_t slot_node,
44+
user_credential_operation_type_t operation_type)
45+
{
46+
set_operation_type(slot_node,
47+
ATTRIBUTE(CREDENTIAL_OPERATION_TYPE),
48+
operation_type);
49+
}
50+
51+
void set_credential_learn_operation_type(
52+
attribute_store_node_t slot_node,
53+
user_credential_operation_type_t operation_type)
54+
{
55+
set_operation_type(slot_node,
56+
ATTRIBUTE(CREDENTIAL_LEARN_OPERATION_TYPE),
57+
operation_type);
58+
}
59+
60+
bool user_exists(attribute_store::attribute endpoint_node,
61+
user_credential_user_unique_id_t user_id)
62+
{
63+
return endpoint_node
64+
.child_by_type_and_value(ATTRIBUTE(USER_UNIQUE_ID),
65+
user_id,
66+
REPORTED_ATTRIBUTE)
67+
.is_valid();
68+
}
69+
70+
attribute_store::attribute
71+
get_user_unique_id_node(attribute_store::attribute endpoint_node,
72+
user_credential_user_unique_id_t user_id,
73+
attribute_store_node_value_state_t state)
74+
{
75+
attribute_store::attribute user_id_node
76+
= endpoint_node.child_by_type_and_value(ATTRIBUTE(USER_UNIQUE_ID),
77+
user_id,
78+
state);
79+
80+
if (!user_id_node.is_valid()) {
81+
throw std::runtime_error(
82+
(boost::format("User ID %1% not found (state : %2%).") % user_id % state)
83+
.str());
84+
}
85+
86+
return user_id_node;
87+
}
88+
89+
90+
attribute_store::attribute
91+
get_credential_type_node(attribute_store::attribute user_id_node,
92+
user_credential_type_t cred_type,
93+
attribute_store_node_value_state_t state)
94+
{
95+
if (!user_id_node.is_valid()) {
96+
throw std::runtime_error(
97+
"get_credential_type_node: User ID node is not valid.");
98+
}
99+
100+
attribute_store::attribute cred_type_node
101+
= user_id_node.child_by_type_and_value(ATTRIBUTE(CREDENTIAL_TYPE),
102+
cred_type,
103+
state);
104+
105+
if (!cred_type_node.is_valid()) {
106+
throw std::runtime_error(
107+
(boost::format("Credential type %1% (state : %2%) not found for %3%.")
108+
% cred_type % state % user_id_node.value_to_string())
109+
.str());
110+
}
111+
112+
return cred_type_node;
113+
}
114+
115+
attribute_store::attribute
116+
get_credential_slot_node(attribute_store::attribute cred_type_node,
117+
user_credential_slot_t cred_slot,
118+
attribute_store_node_value_state_t state)
119+
{
120+
if (!cred_type_node.is_valid()) {
121+
throw std::runtime_error(
122+
"get_credential_slot_node: Credential Type node is not valid.");
123+
}
124+
125+
attribute_store::attribute cred_slot_node
126+
= cred_type_node.child_by_type_and_value(ATTRIBUTE(CREDENTIAL_SLOT),
127+
cred_slot,
128+
state);
129+
130+
if (!cred_slot_node.is_valid()) {
131+
throw std::runtime_error(
132+
(boost::format(
133+
"Credential slot %1% (state : %2%) not found for %3% / %4%.")
134+
% cred_slot % state % cred_type_node.value_to_string()
135+
% cred_type_node.parent().value_to_string())
136+
.str());
137+
}
138+
139+
return cred_slot_node;
140+
}
141+
142+
void for_each_credential_type_nodes_for_user(
143+
attribute_store::attribute user_id_node,
144+
const attribute_callback &callback,
145+
user_credential_type_t credential_type)
146+
{
147+
auto credential_type_nodes
148+
= user_id_node.children(ATTRIBUTE(CREDENTIAL_TYPE));
149+
for (auto &credential_type_node: credential_type_nodes) {
150+
// Call
151+
if (credential_type == 0
152+
|| (credential_type_node.reported_exists()
153+
&& credential_type_node.reported<user_credential_type_t>()
154+
== credential_type)) {
155+
callback(credential_type_node);
156+
}
157+
}
158+
}
159+
160+
void for_each_credential_type_nodes(attribute_store::attribute endpoint_node,
161+
const attribute_callback &callback,
162+
user_credential_type_t credential_type)
163+
{
164+
auto user_nodes = endpoint_node.children(ATTRIBUTE(USER_UNIQUE_ID));
165+
for (auto &user_node: user_nodes) {
166+
for_each_credential_type_nodes_for_user(user_node,
167+
callback,
168+
credential_type);
169+
}
170+
}
171+
172+
173+
bool is_credential_available(attribute_store_node_t endpoint_node,
174+
user_credential_type_t credential_type,
175+
user_credential_slot_t credential_slot)
176+
{
177+
bool credential_available = true;
178+
179+
for_each_credential_type_nodes(
180+
endpoint_node,
181+
[&](attribute_store::attribute &credential_type_node) {
182+
for (auto &credential_slot_node:
183+
credential_type_node.children(ATTRIBUTE(CREDENTIAL_SLOT))) {
184+
// If this credential slot node doesn't have a reported value, check the next one
185+
if (!credential_slot_node.reported_exists()) {
186+
continue;
187+
}
188+
189+
if (credential_slot_node.reported<user_credential_slot_t>()
190+
== credential_slot) {
191+
credential_available = false;
192+
return;
193+
}
194+
}
195+
},
196+
credential_type);
197+
198+
return credential_available;
199+
}
200+
201+
202+
credential_id_nodes
203+
get_credential_identifier_nodes(attribute_store_node_t child_node)
204+
{
205+
attribute_store::attribute slot_node(child_node);
206+
slot_node = slot_node.first_parent_or_self(ATTRIBUTE(CREDENTIAL_SLOT));
207+
attribute_store::attribute type_node
208+
= slot_node.first_parent(ATTRIBUTE(CREDENTIAL_TYPE));
209+
attribute_store::attribute user_unique_id_node
210+
= type_node.first_parent(ATTRIBUTE(USER_UNIQUE_ID));
211+
212+
if (!slot_node.is_valid()) {
213+
throw std::runtime_error(
214+
"get_credential_identifier_nodes: Can't get credential slot node.");
215+
}
216+
217+
if (!type_node.is_valid()) {
218+
throw std::runtime_error(
219+
"get_credential_identifier_nodes: Can't get credential type node.");
220+
}
221+
222+
if (!user_unique_id_node.is_valid()) {
223+
throw std::runtime_error(
224+
"get_credential_identifier_nodes: Can't get user unique ID node.");
225+
}
226+
227+
return {.slot_node = slot_node,
228+
.type_node = type_node,
229+
.user_unique_id_node = user_unique_id_node};
230+
}
231+
232+
credential_id_nodes get_credential_identifier_nodes(
233+
const attribute_store::attribute &endpoint_node,
234+
identifier_state<user_credential_user_unique_id_t> user_id,
235+
identifier_state<user_credential_type_t> credential_type,
236+
identifier_state<user_credential_slot_t> credential_slot)
237+
{
238+
credential_id_nodes nodes;
239+
240+
nodes.user_unique_id_node
241+
= get_user_unique_id_node(endpoint_node, user_id.value, user_id.state);
242+
243+
if (!nodes.user_unique_id_node.is_valid()) {
244+
throw std::runtime_error(
245+
"get_credential_identifier_nodes: Can't get user unique ID "
246+
+ std::to_string(user_id.value));
247+
}
248+
249+
nodes.type_node = get_credential_type_node(nodes.user_unique_id_node,
250+
credential_type.value,
251+
credential_type.state);
252+
253+
if (!nodes.type_node.is_valid()) {
254+
throw std::runtime_error(
255+
(boost::format("get_credential_identifier_nodes: Can't get credential "
256+
"type %1% for user %2%")
257+
% credential_type.value % user_id.value)
258+
.str());
259+
}
260+
261+
nodes.slot_node = get_credential_slot_node(nodes.type_node,
262+
credential_slot.value,
263+
credential_slot.state);
264+
265+
if (!nodes.slot_node.is_valid()) {
266+
throw std::runtime_error(
267+
(boost::format("get_credential_identifier_nodes: Can't get credential "
268+
"slot %1% for credential type %2% / user %3%")
269+
% credential_slot.value % credential_type.value % user_id.value)
270+
.str());
271+
}
272+
return nodes;
273+
}
274+
275+
} // namespace user_credential_helpers

0 commit comments

Comments
 (0)