• 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 "hdf_attribute_manager.h"
10 #include "devhost_service_clnt.h"
11 #include "devmgr_service.h"
12 #include "hcs_blob_if.h"
13 #include "hcs_parser.h"
14 #include "hcs_tree_if.h"
15 #include "hdf_base.h"
16 #include "hdf_device_info.h"
17 #include "hdf_host_info.h"
18 #include "hdf_log.h"
19 #include "osal_mem.h"
20 #include "securec.h"
21 #ifdef LOSCFG_DRIVERS_HDF_USB_PNP_NOTIFY
22 #include "usb_pnp_manager.h"
23 #endif
24 
25 #define ATTR_HOST_NAME "hostName"
26 #define ATTR_DEV_POLICY "policy"
27 #define ATTR_DEV_PRIORITY "priority"
28 #define ATTR_DEV_PRELOAD "preload"
29 #define ATTR_DEV_PERMISSION "permission"
30 #define ATTR_DEV_MODULENAME "moduleName"
31 #define ATTR_DEV_SVCNAME "serviceName"
32 #define ATTR_DEV_MATCHATTR "deviceMatchAttr"
33 #define MANAGER_NODE_MATCH_ATTR "hdf_manager"
34 
35 static struct DeviceResourceNode *g_hcsTreeRoot = NULL;
36 
37 void HdfGetBuildInConfigData(const unsigned char **data, unsigned int *size);
38 
CreateHcsToTree(void)39 static bool CreateHcsToTree(void)
40 {
41     uint32_t length;
42     const unsigned char *hcsBlob = NULL;
43     HdfGetBuildInConfigData(&hcsBlob, &length);
44     if (!HcsCheckBlobFormat((const char *)hcsBlob, length)) {
45         return false;
46     }
47     if (!HcsDecompile((const char *)hcsBlob, HBC_HEADER_LENGTH, &g_hcsTreeRoot)) {
48         return false;
49     }
50     return true;
51 }
52 
HcsGetRootNode(void)53 const struct DeviceResourceNode *HcsGetRootNode(void)
54 {
55     if ((g_hcsTreeRoot == NULL) && !CreateHcsToTree()) {
56         HDF_LOGE("%s: failed", __func__);
57         return NULL;
58     }
59     return g_hcsTreeRoot;
60 }
61 
HdfGetRootNode(void)62 const struct DeviceResourceNode *HdfGetRootNode(void)
63 {
64     return HcsGetRootNode();
65 }
66 
HdfHostListCompare(struct HdfSListNode * listEntryFirst,struct HdfSListNode * listEntrySecond)67 static bool HdfHostListCompare(struct HdfSListNode *listEntryFirst, struct HdfSListNode *listEntrySecond)
68 {
69     if (listEntryFirst == NULL || listEntrySecond == NULL) {
70         return false;
71     }
72     struct HdfHostInfo *attrFirst = (struct HdfHostInfo *)listEntryFirst;
73     struct HdfHostInfo *attrSecond = (struct HdfHostInfo *)listEntrySecond;
74     return attrFirst->priority <= attrSecond->priority;
75 }
76 
GetHdfManagerNode(const struct DeviceResourceNode * node)77 static const struct DeviceResourceNode *GetHdfManagerNode(const struct DeviceResourceNode *node)
78 {
79     return HcsGetNodeByMatchAttr(node, MANAGER_NODE_MATCH_ATTR);
80 }
81 
GetHostInfo(const struct DeviceResourceNode * hostNode,struct HdfHostInfo * hostInfo)82 static bool GetHostInfo(const struct DeviceResourceNode *hostNode, struct HdfHostInfo *hostInfo)
83 {
84     uint16_t readNum = 0;
85     if ((HcsGetString(hostNode, ATTR_HOST_NAME, &hostInfo->hostName, NULL) != HDF_SUCCESS) ||
86         (strcmp(hostInfo->hostName, "") == 0)) {
87         HDF_LOGW("%s: get host name failed", __func__);
88         return false;
89     }
90     if ((HcsGetUint16(hostNode, ATTR_DEV_PRIORITY, &readNum, 0) != HDF_SUCCESS) ||
91         (readNum > MAX_PRIORITY_NUM)) {
92         HDF_LOGW("%s: get host priority failed, priority is: %u", __func__, readNum);
93         return false;
94     }
95     hostInfo->priority = readNum;
96     return true;
97 }
98 
HdfAttributeManagerGetHostList(struct HdfSList * hostList)99 bool HdfAttributeManagerGetHostList(struct HdfSList *hostList)
100 {
101     const struct DeviceResourceNode *hdfManagerNode = NULL;
102     const struct DeviceResourceNode *hostNode = NULL;
103     uint16_t hostId = 0;
104     if (hostList == NULL) {
105         return false;
106     }
107 
108     hdfManagerNode = GetHdfManagerNode(HcsGetRootNode());
109     if (hdfManagerNode == NULL) {
110         HDF_LOGE("%s: get hdf manager node is null", __func__);
111         return false;
112     }
113 
114     hostNode = hdfManagerNode->child;
115     while (hostNode != NULL) {
116         struct HdfHostInfo *hostInfo = HdfHostInfoNewInstance();
117         if (hostInfo == NULL) {
118             HdfSListFlush(hostList, HdfHostInfoDelete);
119             HDF_LOGE("%s: new hostInfo is null", __func__);
120             return false;
121         }
122         if (!GetHostInfo(hostNode, hostInfo)) {
123             HdfHostInfoFreeInstance(hostInfo);
124             hostNode = hostNode->sibling;
125             continue;
126         }
127         hostInfo->hostId = hostId;
128         if (!HdfSListAddOrder(hostList, &hostInfo->node, HdfHostListCompare)) {
129             HdfHostInfoFreeInstance(hostInfo);
130             hostNode = hostNode->sibling;
131             continue;
132         }
133         hostId++;
134         hostNode = hostNode->sibling;
135     }
136     return true;
137 }
138 
HdfDeviceListCompare(struct HdfSListNode * listEntryFirst,struct HdfSListNode * listEntrySecond)139 static bool HdfDeviceListCompare(struct HdfSListNode *listEntryFirst, struct HdfSListNode *listEntrySecond)
140 {
141     if (listEntryFirst == NULL || listEntrySecond == NULL) {
142         return false;
143     }
144     struct HdfDeviceInfo *attrFirst = (struct HdfDeviceInfo *)listEntryFirst;
145     struct HdfDeviceInfo *attrSecond = (struct HdfDeviceInfo *)listEntrySecond;
146     return attrFirst->priority <= attrSecond->priority;
147 }
148 
GetHostNode(const char * inHostName)149 static const struct DeviceResourceNode *GetHostNode(const char *inHostName)
150 {
151     const struct DeviceResourceNode *hdfManagerNode = NULL;
152     const struct DeviceResourceNode *hostNode = NULL;
153     const char *hostName = NULL;
154     if (inHostName == NULL) {
155         return NULL;
156     }
157     hdfManagerNode = GetHdfManagerNode(HcsGetRootNode());
158     if (hdfManagerNode == NULL) {
159         return NULL;
160     }
161     hostNode = hdfManagerNode->child;
162     while (hostNode != NULL) {
163         if (HcsGetString(hostNode, ATTR_HOST_NAME, &hostName, NULL) != HDF_SUCCESS) {
164             hostNode = hostNode->sibling;
165             continue;
166         }
167         if (strcmp(hostName, inHostName) == 0) {
168             return hostNode;
169         }
170         hostNode = hostNode->sibling;
171     }
172     return NULL;
173 }
174 
CheckDeviceInfo(const struct HdfDeviceInfo * deviceNodeInfo)175 static bool CheckDeviceInfo(const struct HdfDeviceInfo *deviceNodeInfo)
176 {
177     if (deviceNodeInfo->policy > SERVICE_POLICY_PRIVATE) {
178         HDF_LOGE("%s: policy %u is invalid", __func__, deviceNodeInfo->policy);
179         return false;
180     }
181 
182     if (deviceNodeInfo->priority > MAX_PRIORITY_NUM) {
183         HDF_LOGE("%s: priority %u is invalid", __func__, deviceNodeInfo->priority);
184         return false;
185     }
186 
187     if (deviceNodeInfo->preload > DEVICE_PRELOAD_DISABLE) {
188         HDF_LOGE("%s: preload %u is invalid", __func__, deviceNodeInfo->preload);
189         return false;
190     }
191 
192     return (strcmp(deviceNodeInfo->moduleName, "") != 0);
193 }
194 
GetDeviceNodeInfo(const struct DeviceResourceNode * deviceNode,struct HdfDeviceInfo * deviceNodeInfo)195 static bool GetDeviceNodeInfo(const struct DeviceResourceNode *deviceNode, struct HdfDeviceInfo *deviceNodeInfo)
196 {
197     uint16_t readNum = 0;
198     const char *readString = NULL;
199     if (HcsGetUint16(deviceNode, ATTR_DEV_POLICY, &readNum, 0) != HDF_SUCCESS) {
200         HDF_LOGE("%s: failed to get policy", __func__);
201         return false;
202     }
203     deviceNodeInfo->policy = readNum;
204 
205     if (HcsGetUint16(deviceNode, ATTR_DEV_PRIORITY, &readNum, 0) != HDF_SUCCESS) {
206         HDF_LOGE("%s: failed to get priority", __func__);
207         return false;
208     }
209     deviceNodeInfo->priority = readNum;
210 
211     if (HcsGetUint16(deviceNode, ATTR_DEV_PRELOAD, &readNum, 0) != HDF_SUCCESS) {
212         HDF_LOGE("%s: failed to get preload", __func__);
213         return false;
214     }
215     deviceNodeInfo->preload = readNum;
216 
217     if (HcsGetUint16(deviceNode, ATTR_DEV_PERMISSION, &readNum, 0) != HDF_SUCCESS) {
218         HDF_LOGE("%s: failed to get permission", __func__);
219         return false;
220     }
221     deviceNodeInfo->permission = readNum;
222 
223     if (HcsGetString(deviceNode, ATTR_DEV_MODULENAME, &readString, NULL) != HDF_SUCCESS) {
224         HDF_LOGE("%s: failed to get module name", __func__);
225         return false;
226     }
227     deviceNodeInfo->moduleName = readString;
228 
229     if (HcsGetString(deviceNode, ATTR_DEV_SVCNAME, &readString, NULL) != HDF_SUCCESS) {
230         HDF_LOGE("%s: failed to get service name", __func__);
231         return false;
232     }
233     deviceNodeInfo->svcName = readString;
234 
235     if (HcsGetString(deviceNode, ATTR_DEV_MATCHATTR, &readString, NULL) != HDF_SUCCESS) {
236         HDF_LOGE("%s: failed to get matchattr name", __func__);
237         return false;
238     }
239     deviceNodeInfo->deviceMatchAttr = readString;
240     return CheckDeviceInfo(deviceNodeInfo);
241 }
242 
HdfAttributeManagerGetDeviceList(uint16_t hostId,const char * hostName)243 struct HdfSList *HdfAttributeManagerGetDeviceList(uint16_t hostId, const char *hostName)
244 {
245     uint16_t deviceIdx = 0;
246     const struct DeviceResourceNode *hostNode = GetHostNode(hostName);
247     if (hostNode == NULL) {
248         return NULL;
249     }
250     struct HdfSList *deviceList = (struct HdfSList *)OsalMemCalloc(sizeof(struct HdfSList));
251     if (deviceList == NULL) {
252         return NULL;
253     }
254     const struct DeviceResourceNode *device = hostNode->child;
255     while (device != NULL) {
256         const struct DeviceResourceNode *deviceNode = device->child;
257         while (deviceNode != NULL) {
258             struct HdfDeviceInfo *deviceNodeInfo = HdfDeviceInfoNewInstance();
259             if (deviceNodeInfo == NULL) {
260                 HdfSListFlush(deviceList, HdfDeviceInfoDelete);
261                 OsalMemFree(deviceList);
262                 return NULL;
263             }
264             deviceNodeInfo->hostId = hostId;
265             if (!GetDeviceNodeInfo(deviceNode, deviceNodeInfo)) {
266                 HdfDeviceInfoFreeInstance(deviceNodeInfo);
267                 HDF_LOGE("%s: failed to get device", __func__);
268                 deviceNodeInfo = NULL;
269                 deviceNode = deviceNode->sibling;
270                 continue;
271             }
272             if (!HdfSListAddOrder(deviceList, &deviceNodeInfo->node, HdfDeviceListCompare)) {
273                 HDF_LOGE("%s: failed to add device %s", __func__, deviceNodeInfo->svcName);
274                 HdfDeviceInfoFreeInstance(deviceNodeInfo);
275                 deviceNodeInfo = NULL;
276                 deviceNode = deviceNode->sibling;
277                 continue;
278             }
279             deviceNodeInfo->deviceId = deviceIdx;
280             deviceNode = deviceNode->sibling;
281         }
282         device = device->sibling;
283         deviceIdx++;
284     }
285     if (HdfSListCount(deviceList) == 0) {
286         OsalMemFree(deviceList);
287         return NULL;
288     }
289     return deviceList;
290 }
291 
HdfDeviceListAdd(const char * moduleName,const char * serviceName,const void * privateData)292 bool HdfDeviceListAdd(const char *moduleName, const char *serviceName, const void *privateData)
293 {
294     struct HdfSListIterator itDeviceInfo;
295     struct HdfDeviceInfo *deviceInfo = NULL;
296     struct DevHostServiceClnt *hostClnt = NULL;
297     struct DevmgrService *devMgrSvc = (struct DevmgrService *)DevmgrServiceGetInstance();
298     if (devMgrSvc == NULL || moduleName == NULL || serviceName == NULL) {
299         return false;
300     }
301 
302     struct HdfDeviceInfo *deviceNodeInfo = HdfDeviceInfoNewInstance();
303     if (deviceNodeInfo == NULL) {
304         return false;
305     }
306     DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
307         HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos);
308         while (HdfSListIteratorHasNext(&itDeviceInfo)) {
309             deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo);
310             if (deviceInfo->moduleName == NULL) {
311                 continue;
312             }
313             if (strcmp(deviceInfo->moduleName, moduleName) == 0) {
314                 deviceInfo->isDynamic = true;
315                 deviceNodeInfo->hostId = deviceInfo->hostId;
316                 deviceNodeInfo->deviceId = hostClnt->devCount;
317                 deviceNodeInfo->policy = deviceInfo->policy;
318                 deviceNodeInfo->priority = deviceInfo->priority;
319                 deviceNodeInfo->preload = DEVICE_PRELOAD_DISABLE;
320                 deviceNodeInfo->permission = deviceInfo->permission;
321                 deviceNodeInfo->deviceMatchAttr = deviceInfo->deviceMatchAttr;
322                 deviceNodeInfo->moduleName = deviceInfo->moduleName;
323                 char *svcName = OsalMemCalloc(strlen(serviceName) + 1);
324                 if (svcName == NULL) {
325                     break;
326                 }
327                 if (strcpy_s(svcName, strlen(serviceName) + 1, serviceName) != EOK) {
328                     HDF_LOGE("%s: failed to copy string", __func__);
329                     OsalMemFree(svcName);
330                     break;
331                 }
332                 deviceNodeInfo->svcName = svcName;
333 #ifdef LOSCFG_DRIVERS_HDF_USB_PNP_NOTIFY
334                 if (!UsbPnpManagerAddPrivateData(deviceNodeInfo, privateData)) {
335                     break;
336                 }
337 #endif
338                 HdfSListAdd(hostClnt->deviceInfos, &deviceNodeInfo->node);
339                 hostClnt->devCount++;
340                 return true;
341             }
342         }
343     }
344     HdfDeviceInfoFreeInstance(deviceNodeInfo);
345     return false;
346 }
347 
HdfDeviceListDel(const char * moduleName,const char * serviceName)348 void HdfDeviceListDel(const char *moduleName, const char *serviceName)
349 {
350     struct HdfSListIterator itDeviceInfo;
351     struct HdfDeviceInfo *deviceInfo = NULL;
352     struct DevHostServiceClnt *hostClnt = NULL;
353     struct DevmgrService *devMgrSvc = (struct DevmgrService *)DevmgrServiceGetInstance();
354     if (devMgrSvc == NULL || moduleName == NULL || serviceName == NULL) {
355         return;
356     }
357 
358     DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
359         HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos);
360         while (HdfSListIteratorHasNext(&itDeviceInfo)) {
361             deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo);
362             if ((strcmp(deviceInfo->moduleName, moduleName) == 0) &&
363                 (strcmp(deviceInfo->svcName, serviceName) == 0)) {
364                 HdfSListRemove(hostClnt->deviceInfos, &deviceInfo->node);
365                 HdfDeviceInfoFreeInstance(deviceInfo);
366                 hostClnt->devCount--;
367                 return;
368             }
369         }
370     }
371 }
372 
373