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