1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "hcs_tree_if.h"
10 #include "hcs_blob_if.h"
11 #include "hdf_log.h"
12
13 #define HDF_LOG_TAG hcs_tree_if
14
GetAttrInNode(const struct DeviceResourceNode * node,const char * attrName)15 static struct DeviceResourceAttr *GetAttrInNode(const struct DeviceResourceNode *node, const char *attrName)
16 {
17 struct DeviceResourceAttr *attr = NULL;
18 if ((node == NULL) || (attrName == NULL)) {
19 return NULL;
20 }
21 for (attr = node->attrData; attr != NULL; attr = attr->next) {
22 if ((attr->name != NULL) && (strcmp(attr->name, attrName) == 0)) {
23 break;
24 }
25 }
26 return attr;
27 }
28
HcsGetBool(const struct DeviceResourceNode * node,const char * attrName)29 bool HcsGetBool(const struct DeviceResourceNode *node, const char *attrName)
30 {
31 uint8_t value;
32 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
33 if ((attr == NULL) || (attr->value == NULL)) {
34 HDF_LOGE("%s failed, the node or attrName is NULL", __func__);
35 return false;
36 }
37
38 if (!HcsSwapToUint8(&value, attr->value + HCS_PREFIX_LENGTH, HcsGetPrefix(attr->value))) {
39 HDF_LOGE("%s failed, incorrect prefix", __func__);
40 return false;
41 }
42 return value ? true : false;
43 }
44
45 #define RETURN_DEFAULT_VALUE(attr, attrName, value, def) do { \
46 if (((attr) == NULL) || ((attr)->value == NULL) || ((value) == NULL)) { \
47 HDF_LOGE("%s failed, the attr of %s is NULL, or the value is NULL, the value is default value", \
48 __func__, ((attrName) == NULL) ? "error attrName" : (attrName)); \
49 if ((value) != NULL) { \
50 *(value) = (def); \
51 } \
52 return HDF_FAILURE; \
53 } \
54 } while (0)
55
HcsGetUint8(const struct DeviceResourceNode * node,const char * attrName,uint8_t * value,uint8_t def)56 int32_t HcsGetUint8(const struct DeviceResourceNode *node, const char *attrName, uint8_t *value, uint8_t def)
57 {
58 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
59 RETURN_DEFAULT_VALUE(attr, attrName, value, def);
60
61 if (!HcsSwapToUint8(value, attr->value + HCS_PREFIX_LENGTH, HcsGetPrefix(attr->value))) {
62 *value = def;
63 HDF_LOGE("%s failed, incorrect prefix", __func__);
64 return HDF_FAILURE;
65 }
66 return HDF_SUCCESS;
67 }
68
HcsGetUint16(const struct DeviceResourceNode * node,const char * attrName,uint16_t * value,uint16_t def)69 int32_t HcsGetUint16(const struct DeviceResourceNode *node, const char *attrName, uint16_t *value, uint16_t def)
70 {
71 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
72 RETURN_DEFAULT_VALUE(attr, attrName, value, def);
73
74 if (!HcsSwapToUint16(value, attr->value + HCS_PREFIX_LENGTH, HcsGetPrefix(attr->value))) {
75 *value = def;
76 HDF_LOGE("%s failed, incorrect prefix", __func__);
77 return HDF_FAILURE;
78 }
79 return HDF_SUCCESS;
80 }
81
HcsGetUint32(const struct DeviceResourceNode * node,const char * attrName,uint32_t * value,uint32_t def)82 int32_t HcsGetUint32(const struct DeviceResourceNode *node, const char *attrName, uint32_t *value, uint32_t def)
83 {
84 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
85 RETURN_DEFAULT_VALUE(attr, attrName, value, def);
86
87 if (!HcsSwapToUint32(value, attr->value + HCS_PREFIX_LENGTH, HcsGetPrefix(attr->value))) {
88 *value = def;
89 HDF_LOGE("%s failed, incorrect prefix", __func__);
90 return HDF_FAILURE;
91 }
92 return HDF_SUCCESS;
93 }
94
HcsGetUint64(const struct DeviceResourceNode * node,const char * attrName,uint64_t * value,uint64_t def)95 int32_t HcsGetUint64(const struct DeviceResourceNode *node, const char *attrName, uint64_t *value, uint64_t def)
96 {
97 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
98 RETURN_DEFAULT_VALUE(attr, attrName, value, def);
99
100 if (!HcsSwapToUint64(value, attr->value + HCS_PREFIX_LENGTH, HcsGetPrefix(attr->value))) {
101 *value = def;
102 HDF_LOGE("%s failed, incorrect prefix", __func__);
103 return HDF_FAILURE;
104 }
105 return HDF_SUCCESS;
106 }
107
GetArrayElem(const struct DeviceResourceAttr * attr,uint32_t index)108 static const char *GetArrayElem(const struct DeviceResourceAttr *attr, uint32_t index)
109 {
110 int32_t offset = HCS_WORD_LENGTH + HCS_PREFIX_LENGTH;
111 uint16_t count;
112 uint32_t i;
113 if ((HcsGetPrefix(attr->value) != CONFIG_ARRAY) ||
114 !HcsSwapToUint16(&count, attr->value + HCS_PREFIX_LENGTH, CONFIG_WORD)) {
115 HDF_LOGE("%s failed, the attr of %s is not array", __func__, attr->name);
116 return NULL;
117 }
118 if (index >= count) {
119 HDF_LOGE("%s failed, index: %u >= count: %hu", __func__, index, count);
120 return NULL;
121 }
122 for (i = 0; i < index; i++) {
123 int32_t result = HcsGetDataTypeOffset(attr->value + offset);
124 if (result < 0) {
125 return NULL;
126 }
127 offset += result;
128 }
129 return attr->value + offset;
130 }
131
HcsGetUint8ArrayElem(const struct DeviceResourceNode * node,const char * attrName,uint32_t index,uint8_t * value,uint8_t def)132 int32_t HcsGetUint8ArrayElem(const struct DeviceResourceNode *node, const char *attrName, uint32_t index,
133 uint8_t *value, uint8_t def)
134 {
135 const char *realValue = NULL;
136 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
137 RETURN_DEFAULT_VALUE(attr, attrName, value, def);
138
139 realValue = GetArrayElem(attr, index);
140 if (realValue == NULL) {
141 *value = def;
142 HDF_LOGE("%s failed, the realValue is NULL", __func__);
143 return HDF_FAILURE;
144 }
145 if (!HcsSwapToUint8(value, realValue + HCS_PREFIX_LENGTH, HcsGetPrefix(realValue))) {
146 *value = def;
147 HDF_LOGE("%s failed, incorrect prefix", __func__);
148 return HDF_ERR_INVALID_OBJECT;
149 }
150 return HDF_SUCCESS;
151 }
152
HcsGetUint16ArrayElem(const struct DeviceResourceNode * node,const char * attrName,uint32_t index,uint16_t * value,uint16_t def)153 int32_t HcsGetUint16ArrayElem(const struct DeviceResourceNode *node, const char *attrName, uint32_t index,
154 uint16_t *value, uint16_t def)
155 {
156 const char *realValue = NULL;
157 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
158 RETURN_DEFAULT_VALUE(attr, attrName, value, def);
159
160 realValue = GetArrayElem(attr, index);
161 if (realValue == NULL) {
162 *value = def;
163 HDF_LOGE("%s failed, the realValue is NULL", __func__);
164 return HDF_FAILURE;
165 }
166 if (!HcsSwapToUint16(value, realValue + HCS_PREFIX_LENGTH, HcsGetPrefix(realValue))) {
167 *value = def;
168 HDF_LOGE("%s failed, incorrect prefix", __func__);
169 return HDF_ERR_INVALID_OBJECT;
170 }
171 return HDF_SUCCESS;
172 }
173
HcsGetUint32ArrayElem(const struct DeviceResourceNode * node,const char * attrName,uint32_t index,uint32_t * value,uint32_t def)174 int32_t HcsGetUint32ArrayElem(const struct DeviceResourceNode *node, const char *attrName, uint32_t index,
175 uint32_t *value, uint32_t def)
176 {
177 const char *realValue = NULL;
178 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
179 RETURN_DEFAULT_VALUE(attr, attrName, value, def);
180
181 realValue = GetArrayElem(attr, index);
182 if (realValue == NULL) {
183 *value = def;
184 HDF_LOGE("%s failed, the realValue is NULL", __func__);
185 return HDF_FAILURE;
186 }
187 if (!HcsSwapToUint32(value, realValue + HCS_PREFIX_LENGTH, HcsGetPrefix(realValue))) {
188 *value = def;
189 HDF_LOGE("%s failed, incorrect prefix", __func__);
190 return HDF_ERR_INVALID_OBJECT;
191 }
192 return HDF_SUCCESS;
193 }
194
HcsGetUint64ArrayElem(const struct DeviceResourceNode * node,const char * attrName,uint32_t index,uint64_t * value,uint64_t def)195 int32_t HcsGetUint64ArrayElem(const struct DeviceResourceNode *node, const char *attrName, uint32_t index,
196 uint64_t *value, uint64_t def)
197 {
198 const char *realValue = NULL;
199 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
200 RETURN_DEFAULT_VALUE(attr, attrName, value, def);
201
202 realValue = GetArrayElem(attr, index);
203 if ((realValue == NULL) || !HcsSwapToUint64(value, realValue + HCS_PREFIX_LENGTH, HcsGetPrefix(realValue))) {
204 *value = def;
205 HDF_LOGE("%s failed, invalid realValue (NULL) or incorrect prefix", __func__);
206 return HDF_FAILURE;
207 }
208 return HDF_SUCCESS;
209 }
210
211 #define CONTINUE_RETURN_DIFFERENT_ERRNO(ret, result) do { \
212 if ((result) == HDF_ERR_INVALID_OBJECT) { \
213 (ret) = HDF_ERR_INVALID_OBJECT; \
214 HDF_LOGE("%s failed, the result is %d", __func__, (result)); \
215 continue; \
216 } else if ((result) != HDF_SUCCESS) { \
217 HDF_LOGE("%s failed, the result is %d", __func__, (result)); \
218 return result; \
219 } \
220 } while (0)
221
HcsGetUint8Array(const struct DeviceResourceNode * node,const char * attrName,uint8_t * value,uint32_t len,uint8_t def)222 int32_t HcsGetUint8Array(const struct DeviceResourceNode *node, const char *attrName, uint8_t *value, uint32_t len,
223 uint8_t def)
224 {
225 int32_t ret = HDF_SUCCESS;
226 uint32_t i;
227 if ((value == NULL) || (len == 0)) {
228 HDF_LOGE("%s failed, parameter error, len: %u", __func__, len);
229 return HDF_FAILURE;
230 }
231
232 for (i = 0; i < len; i++) {
233 int32_t result = HcsGetUint8ArrayElem(node, attrName, i, value + i, def);
234 // If the error type is HDF_ERR_INVALID_OBJECT, the error is recorded and returned after the loop exits.
235 CONTINUE_RETURN_DIFFERENT_ERRNO(ret, result);
236 }
237 return ret;
238 }
239
HcsGetUint16Array(const struct DeviceResourceNode * node,const char * attrName,uint16_t * value,uint32_t len,uint16_t def)240 int32_t HcsGetUint16Array(const struct DeviceResourceNode *node, const char *attrName, uint16_t *value, uint32_t len,
241 uint16_t def)
242 {
243 int32_t ret = HDF_SUCCESS;
244 uint32_t i;
245 if ((value == NULL) || (len == 0)) {
246 HDF_LOGE("%s failed, parameter error, len: %u", __func__, len);
247 return HDF_FAILURE;
248 }
249
250 for (i = 0; i < len; i++) {
251 int32_t result = HcsGetUint16ArrayElem(node, attrName, i, value + i, def);
252 // If the error type is HDF_ERR_INVALID_OBJECT, the error is recorded and returned after the loop exits.
253 CONTINUE_RETURN_DIFFERENT_ERRNO(ret, result);
254 }
255 return ret;
256 }
257
HcsGetUint32Array(const struct DeviceResourceNode * node,const char * attrName,uint32_t * value,uint32_t len,uint32_t def)258 int32_t HcsGetUint32Array(const struct DeviceResourceNode *node, const char *attrName, uint32_t *value, uint32_t len,
259 uint32_t def)
260 {
261 int32_t ret = HDF_SUCCESS;
262 uint32_t i;
263 if ((value == NULL) || (len == 0)) {
264 HDF_LOGE("%s failed, parameter error, len: %u", __func__, len);
265 return HDF_FAILURE;
266 }
267
268 for (i = 0; i < len; i++) {
269 int32_t result = HcsGetUint32ArrayElem(node, attrName, i, value + i, def);
270 // If the error type is HDF_ERR_INVALID_OBJECT, the error is recorded and returned after the loop exits.
271 CONTINUE_RETURN_DIFFERENT_ERRNO(ret, result);
272 }
273 return ret;
274 }
275
HcsGetUint64Array(const struct DeviceResourceNode * node,const char * attrName,uint64_t * value,uint32_t len,uint64_t def)276 int32_t HcsGetUint64Array(const struct DeviceResourceNode *node, const char *attrName, uint64_t *value, uint32_t len,
277 uint64_t def)
278 {
279 uint32_t i;
280 if ((value == NULL) || (len == 0)) {
281 HDF_LOGE("%s failed, parameter error, len: %u", __func__, len);
282 return HDF_FAILURE;
283 }
284
285 for (i = 0; i < len; i++) {
286 int32_t result = HcsGetUint64ArrayElem(node, attrName, i, value + i, def);
287 if (result != HDF_SUCCESS) {
288 HDF_LOGE("%s failed, the ret is %d", __func__, result);
289 return result;
290 }
291 }
292 return HDF_SUCCESS;
293 }
294
HcsGetStringArrayElem(const struct DeviceResourceNode * node,const char * attrName,uint32_t index,const char ** value,const char * def)295 int32_t HcsGetStringArrayElem(const struct DeviceResourceNode *node, const char *attrName, uint32_t index,
296 const char **value, const char *def)
297 {
298 const char *realValue = NULL;
299 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
300 RETURN_DEFAULT_VALUE(attr, attrName, value, def);
301
302 realValue = GetArrayElem(attr, index);
303 if ((realValue == NULL) || (HcsGetPrefix(realValue) != CONFIG_STRING)) {
304 *value = def;
305 HDF_LOGE("%s failed, %s attr is default value", __func__, attrName);
306 return HDF_FAILURE;
307 }
308 *value = realValue + HCS_PREFIX_LENGTH;
309 return HDF_SUCCESS;
310 }
311
HcsGetString(const struct DeviceResourceNode * node,const char * attrName,const char ** value,const char * def)312 int32_t HcsGetString(const struct DeviceResourceNode *node, const char *attrName, const char **value, const char *def)
313 {
314 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
315 RETURN_DEFAULT_VALUE(attr, attrName, value, def);
316 if (HcsGetPrefix(attr->value) != CONFIG_STRING) {
317 *value = def;
318 HDF_LOGE("%s failed, incorrect prefix", __func__);
319 return HDF_FAILURE;
320 }
321 *value = attr->value + HCS_PREFIX_LENGTH;
322 return HDF_SUCCESS;
323 }
324
HcsGetElemNum(const struct DeviceResourceNode * node,const char * attrName)325 int32_t HcsGetElemNum(const struct DeviceResourceNode *node, const char *attrName)
326 {
327 uint16_t num;
328 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
329 if ((attr == NULL) || (attr->value == NULL) || (HcsGetPrefix(attr->value) != CONFIG_ARRAY)) {
330 HDF_LOGE("%s failed, %s attr error", __func__, (attrName == NULL) ? "error attrName" : attrName);
331 return HDF_FAILURE;
332 }
333
334 (void)HcsSwapToUint16(&num, attr->value + HCS_PREFIX_LENGTH, CONFIG_WORD);
335 return num;
336 }
337
GetAttrValueInNode(const struct DeviceResourceNode * node,const char * attrValue)338 static struct DeviceResourceAttr *GetAttrValueInNode(const struct DeviceResourceNode *node, const char *attrValue)
339 {
340 struct DeviceResourceAttr *attr = NULL;
341 if ((node == NULL) || (attrValue == NULL)) {
342 return NULL;
343 }
344 for (attr = node->attrData; attr != NULL; attr = attr->next) {
345 if ((attr->value != NULL) && (strcmp(attr->value + HCS_PREFIX_LENGTH, attrValue) == 0) &&
346 (attr->name != NULL) && (strcmp(attr->name, HCS_MATCH_ATTR) == 0)) {
347 break;
348 }
349 }
350 return attr;
351 }
352
TraverseTreeNode(const struct DeviceResourceNode * curNode)353 static const struct DeviceResourceNode *TraverseTreeNode(const struct DeviceResourceNode *curNode)
354 {
355 const struct DeviceResourceNode *nextNode = curNode;
356 while (nextNode->parent && !nextNode->sibling) {
357 nextNode = nextNode->parent;
358 }
359 nextNode = nextNode->sibling;
360 return nextNode;
361 }
362
HcsGetNodeByMatchAttr(const struct DeviceResourceNode * node,const char * attrValue)363 const struct DeviceResourceNode *HcsGetNodeByMatchAttr(const struct DeviceResourceNode *node, const char *attrValue)
364 {
365 const struct DeviceResourceNode *curNode = NULL;
366 struct DeviceResourceIface *instance = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
367 if ((attrValue == NULL) || (instance == NULL) || (instance->GetRootNode == NULL)) {
368 HDF_LOGE("%s failed, attrValue or instance error", __func__);
369 return NULL;
370 }
371 curNode = (node != NULL) ? node : instance->GetRootNode();
372 while (curNode != NULL) {
373 if (GetAttrValueInNode(curNode, attrValue) != NULL) {
374 break;
375 }
376 curNode = (curNode->child != NULL) ? curNode->child : TraverseTreeNode(curNode);
377 }
378 return curNode;
379 }
380
HcsGetChildNode(const struct DeviceResourceNode * node,const char * nodeName)381 const struct DeviceResourceNode *HcsGetChildNode(const struct DeviceResourceNode *node, const char *nodeName)
382 {
383 struct DeviceResourceNode *child = NULL;
384 if ((node == NULL) || (nodeName == NULL)) {
385 HDF_LOGE("%s failed, the node or nodeName is NULL", __func__);
386 return NULL;
387 }
388
389 for (child = node->child; child != NULL; child = child->sibling) {
390 if ((child->name != NULL) && (strcmp(nodeName, child->name) == 0)) {
391 break;
392 }
393 }
394 return child;
395 }
396
HcsGetNodeByRefAttr(const struct DeviceResourceNode * node,const char * attrName)397 const struct DeviceResourceNode *HcsGetNodeByRefAttr(const struct DeviceResourceNode *node, const char *attrName)
398 {
399 uint32_t attrValue;
400 struct DeviceResourceIface *instance = NULL;
401 const struct DeviceResourceNode *curNode = NULL;
402 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
403 if ((attr == NULL) || (attr->value == NULL) || (HcsGetPrefix(attr->value) != CONFIG_REFERENCE)) {
404 HDF_LOGE("%s failed, %s attr error", __func__, (attrName == NULL) ? "error attrName" : attrName);
405 return NULL;
406 }
407
408 (void)HcsSwapToUint32(&attrValue, attr->value + HCS_PREFIX_LENGTH, CONFIG_DWORD);
409 instance = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
410 if ((instance == NULL) || (instance->GetRootNode == NULL)) {
411 HDF_LOGE("%s failed, DeviceResourceGetIfaceInstance error", __func__);
412 return NULL;
413 }
414 curNode = instance->GetRootNode();
415 while (curNode != NULL) {
416 if (curNode->hashValue == attrValue) {
417 break;
418 }
419 curNode = (curNode->child != NULL) ? curNode->child : TraverseTreeNode(curNode);
420 }
421 return curNode;
422 }
423