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 } \
217 if ((result) != HDF_SUCCESS) { \
218 HDF_LOGE("%s failed, the result is %d", __func__, (result)); \
219 return result; \
220 } \
221 } while (0)
222
HcsGetUint8Array(const struct DeviceResourceNode * node,const char * attrName,uint8_t * value,uint32_t len,uint8_t def)223 int32_t HcsGetUint8Array(const struct DeviceResourceNode *node, const char *attrName, uint8_t *value, uint32_t len,
224 uint8_t def)
225 {
226 int32_t ret = HDF_SUCCESS;
227 uint32_t i;
228 if ((value == NULL) || (len == 0)) {
229 HDF_LOGE("%s failed, parameter error, len: %u", __func__, len);
230 return HDF_FAILURE;
231 }
232
233 for (i = 0; i < len; i++) {
234 int32_t result = HcsGetUint8ArrayElem(node, attrName, i, value + i, def);
235 // If the error type is HDF_ERR_INVALID_OBJECT, the error is recorded and returned after the loop exits.
236 CONTINUE_RETURN_DIFFERENT_ERRNO(ret, result);
237 }
238 return ret;
239 }
240
HcsGetUint16Array(const struct DeviceResourceNode * node,const char * attrName,uint16_t * value,uint32_t len,uint16_t def)241 int32_t HcsGetUint16Array(const struct DeviceResourceNode *node, const char *attrName, uint16_t *value, uint32_t len,
242 uint16_t def)
243 {
244 int32_t ret = HDF_SUCCESS;
245 uint32_t i;
246 if ((value == NULL) || (len == 0)) {
247 HDF_LOGE("%s failed, parameter error, len: %u", __func__, len);
248 return HDF_FAILURE;
249 }
250
251 for (i = 0; i < len; i++) {
252 int32_t result = HcsGetUint16ArrayElem(node, attrName, i, value + i, def);
253 // If the error type is HDF_ERR_INVALID_OBJECT, the error is recorded and returned after the loop exits.
254 CONTINUE_RETURN_DIFFERENT_ERRNO(ret, result);
255 }
256 return ret;
257 }
258
HcsGetUint32Array(const struct DeviceResourceNode * node,const char * attrName,uint32_t * value,uint32_t len,uint32_t def)259 int32_t HcsGetUint32Array(const struct DeviceResourceNode *node, const char *attrName, uint32_t *value, uint32_t len,
260 uint32_t def)
261 {
262 int32_t ret = HDF_SUCCESS;
263 uint32_t i;
264 if ((value == NULL) || (len == 0)) {
265 HDF_LOGE("%s failed, parameter error, len: %u", __func__, len);
266 return HDF_FAILURE;
267 }
268
269 for (i = 0; i < len; i++) {
270 int32_t result = HcsGetUint32ArrayElem(node, attrName, i, value + i, def);
271 // If the error type is HDF_ERR_INVALID_OBJECT, the error is recorded and returned after the loop exits.
272 CONTINUE_RETURN_DIFFERENT_ERRNO(ret, result);
273 }
274 return ret;
275 }
276
HcsGetUint64Array(const struct DeviceResourceNode * node,const char * attrName,uint64_t * value,uint32_t len,uint64_t def)277 int32_t HcsGetUint64Array(const struct DeviceResourceNode *node, const char *attrName, uint64_t *value, uint32_t len,
278 uint64_t def)
279 {
280 uint32_t i;
281 if ((value == NULL) || (len == 0)) {
282 HDF_LOGE("%s failed, parameter error, len: %u", __func__, len);
283 return HDF_FAILURE;
284 }
285
286 for (i = 0; i < len; i++) {
287 int32_t result = HcsGetUint64ArrayElem(node, attrName, i, value + i, def);
288 if (result != HDF_SUCCESS) {
289 HDF_LOGE("%s failed, the ret is %d", __func__, result);
290 return result;
291 }
292 }
293 return HDF_SUCCESS;
294 }
295
HcsGetStringArrayElem(const struct DeviceResourceNode * node,const char * attrName,uint32_t index,const char ** value,const char * def)296 int32_t HcsGetStringArrayElem(const struct DeviceResourceNode *node, const char *attrName, uint32_t index,
297 const char **value, const char *def)
298 {
299 const char *realValue = NULL;
300 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
301 RETURN_DEFAULT_VALUE(attr, attrName, value, def);
302
303 realValue = GetArrayElem(attr, index);
304 if ((realValue == NULL) || (HcsGetPrefix(realValue) != CONFIG_STRING)) {
305 *value = def;
306 HDF_LOGE("%s failed, %s attr is default value", __func__, attrName);
307 return HDF_FAILURE;
308 }
309 *value = realValue + HCS_PREFIX_LENGTH;
310 return HDF_SUCCESS;
311 }
312
HcsGetString(const struct DeviceResourceNode * node,const char * attrName,const char ** value,const char * def)313 int32_t HcsGetString(const struct DeviceResourceNode *node, const char *attrName, const char **value, const char *def)
314 {
315 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
316 RETURN_DEFAULT_VALUE(attr, attrName, value, def);
317 if (HcsGetPrefix(attr->value) != CONFIG_STRING) {
318 *value = def;
319 HDF_LOGE("%s failed, incorrect prefix", __func__);
320 return HDF_FAILURE;
321 }
322 *value = attr->value + HCS_PREFIX_LENGTH;
323 return HDF_SUCCESS;
324 }
325
HcsGetElemNum(const struct DeviceResourceNode * node,const char * attrName)326 int32_t HcsGetElemNum(const struct DeviceResourceNode *node, const char *attrName)
327 {
328 uint16_t num;
329 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
330 if ((attr == NULL) || (attr->value == NULL) || (HcsGetPrefix(attr->value) != CONFIG_ARRAY)) {
331 HDF_LOGE("%s failed, %s attr error", __func__, (attrName == NULL) ? "error attrName" : attrName);
332 return HDF_FAILURE;
333 }
334
335 (void)HcsSwapToUint16(&num, attr->value + HCS_PREFIX_LENGTH, CONFIG_WORD);
336 return num;
337 }
338
GetAttrValueInNode(const struct DeviceResourceNode * node,const char * attrValue)339 static struct DeviceResourceAttr *GetAttrValueInNode(const struct DeviceResourceNode *node, const char *attrValue)
340 {
341 struct DeviceResourceAttr *attr = NULL;
342 if ((node == NULL) || (attrValue == NULL)) {
343 return NULL;
344 }
345 for (attr = node->attrData; attr != NULL; attr = attr->next) {
346 if ((attr->value != NULL) && (strcmp(attr->value + HCS_PREFIX_LENGTH, attrValue) == 0) &&
347 (attr->name != NULL) && (strcmp(attr->name, HCS_MATCH_ATTR) == 0)) {
348 break;
349 }
350 }
351 return attr;
352 }
353
TraverseTreeNode(const struct DeviceResourceNode * curNode)354 static const struct DeviceResourceNode *TraverseTreeNode(const struct DeviceResourceNode *curNode)
355 {
356 const struct DeviceResourceNode *nextNode = curNode;
357 while (nextNode->parent && !nextNode->sibling) {
358 nextNode = nextNode->parent;
359 }
360 nextNode = nextNode->sibling;
361 return nextNode;
362 }
363
HcsGetNodeByMatchAttr(const struct DeviceResourceNode * node,const char * attrValue)364 const struct DeviceResourceNode *HcsGetNodeByMatchAttr(const struct DeviceResourceNode *node, const char *attrValue)
365 {
366 const struct DeviceResourceNode *curNode = NULL;
367 struct DeviceResourceIface *instance = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
368 if ((attrValue == NULL) || (instance == NULL) || (instance->GetRootNode == NULL)) {
369 HDF_LOGE("%s failed, attrValue or instance error", __func__);
370 return NULL;
371 }
372 curNode = (node != NULL) ? node : instance->GetRootNode();
373 while (curNode != NULL) {
374 if (GetAttrValueInNode(curNode, attrValue) != NULL) {
375 break;
376 }
377 curNode = (curNode->child != NULL) ? curNode->child : TraverseTreeNode(curNode);
378 }
379 return curNode;
380 }
381
HcsGetChildNode(const struct DeviceResourceNode * node,const char * nodeName)382 const struct DeviceResourceNode *HcsGetChildNode(const struct DeviceResourceNode *node, const char *nodeName)
383 {
384 struct DeviceResourceNode *child = NULL;
385 if ((node == NULL) || (nodeName == NULL)) {
386 HDF_LOGE("%s failed, the node or nodeName is NULL", __func__);
387 return NULL;
388 }
389
390 for (child = node->child; child != NULL; child = child->sibling) {
391 if ((child->name != NULL) && (strcmp(nodeName, child->name) == 0)) {
392 break;
393 }
394 }
395 return child;
396 }
397
HcsGetNodeByRefAttr(const struct DeviceResourceNode * node,const char * attrName)398 const struct DeviceResourceNode *HcsGetNodeByRefAttr(const struct DeviceResourceNode *node, const char *attrName)
399 {
400 uint32_t attrValue;
401 struct DeviceResourceIface *instance = NULL;
402 const struct DeviceResourceNode *curNode = NULL;
403 struct DeviceResourceAttr *attr = GetAttrInNode(node, attrName);
404 if ((attr == NULL) || (attr->value == NULL) || (HcsGetPrefix(attr->value) != CONFIG_REFERENCE)) {
405 HDF_LOGE("%s failed, %s attr error", __func__, (attrName == NULL) ? "error attrName" : attrName);
406 return NULL;
407 }
408
409 (void)HcsSwapToUint32(&attrValue, attr->value + HCS_PREFIX_LENGTH, CONFIG_DWORD);
410 instance = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
411 if ((instance == NULL) || (instance->GetRootNode == NULL)) {
412 HDF_LOGE("%s failed, DeviceResourceGetIfaceInstance error", __func__);
413 return NULL;
414 }
415 curNode = instance->GetRootNode();
416 while (curNode != NULL) {
417 if (curNode->hashValue == attrValue) {
418 break;
419 }
420 curNode = (curNode->child != NULL) ? curNode->child : TraverseTreeNode(curNode);
421 }
422 return curNode;
423 }
424