• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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