1 /*
2 * Copyright (c) 2020-2022 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 "devhost_service_clnt.h"
10 #include "hcs_tree_if.h"
11 #include "hdf_attribute_manager.h"
12 #include "hdf_device_desc.h"
13 #include "hdf_host_info.h"
14 #include "hdf_log.h"
15 #ifdef LOSCFG_DRIVERS_HDF_USB_PNP_NOTIFY
16 #include "usb_pnp_manager.h"
17 #endif
18
19 #define ATTR_HOST_NAME "hostName"
20 #define ATTR_DEV_POLICY "policy"
21 #define ATTR_DEV_PRIORITY "priority"
22 #define ATTR_DEV_PRELOAD "preload"
23 #define ATTR_DEV_PERMISSION "permission"
24 #define ATTR_DEV_MODULENAME "moduleName"
25 #define ATTR_DEV_SVCNAME "serviceName"
26 #define ATTR_DEV_MATCHATTR "deviceMatchAttr"
27 #define MANAGER_NODE_MATCH_ATTR "hdf_manager"
28
29 #define DEFATLT_DEV_PRIORITY 100
30
HdfHostListCompare(struct HdfSListNode * listEntryFirst,struct HdfSListNode * listEntrySecond)31 static bool HdfHostListCompare(struct HdfSListNode *listEntryFirst, struct HdfSListNode *listEntrySecond)
32 {
33 struct HdfHostInfo *attrFirst = NULL;
34 struct HdfHostInfo *attrSecond = NULL;
35 if (listEntryFirst == NULL || listEntrySecond == NULL) {
36 return false;
37 }
38 attrFirst = (struct HdfHostInfo *)listEntryFirst;
39 attrSecond = (struct HdfHostInfo *)listEntrySecond;
40 return attrFirst->priority <= attrSecond->priority;
41 }
42
GetHdfManagerNode(const struct DeviceResourceNode * node)43 static const struct DeviceResourceNode *GetHdfManagerNode(const struct DeviceResourceNode *node)
44 {
45 return HcsGetNodeByMatchAttr(node, MANAGER_NODE_MATCH_ATTR);
46 }
47
GetHostInfo(const struct DeviceResourceNode * hostNode,struct HdfHostInfo * hostInfo)48 static bool GetHostInfo(const struct DeviceResourceNode *hostNode, struct HdfHostInfo *hostInfo)
49 {
50 uint16_t readNum = 0;
51 if ((HcsGetString(hostNode, ATTR_HOST_NAME, &hostInfo->hostName, NULL) != HDF_SUCCESS) ||
52 (strcmp(hostInfo->hostName, "") == 0)) {
53 HDF_LOGW("%{public}s: get host name failed", __func__);
54 return false;
55 }
56 if ((HcsGetUint16(hostNode, ATTR_DEV_PRIORITY, &readNum, 0) != HDF_SUCCESS) || (readNum > MAX_PRIORITY_NUM)) {
57 HDF_LOGW("%{public}s: get host priority failed, priority is: %{public}u", __func__, readNum);
58 return false;
59 }
60 hostInfo->priority = readNum;
61 return true;
62 }
63
HdfAttributeManagerGetHostList(struct HdfSList * hostList)64 bool HdfAttributeManagerGetHostList(struct HdfSList *hostList)
65 {
66 const struct DeviceResourceNode *hdfManagerNode = NULL;
67 const struct DeviceResourceNode *hostNode = NULL;
68 uint16_t hostId = 0;
69 if (hostList == NULL) {
70 return false;
71 }
72
73 hdfManagerNode = GetHdfManagerNode(HdfGetHcsRootNode());
74 if (hdfManagerNode == NULL) {
75 HDF_LOGE("%{public}s: get hdf manager node is null", __func__);
76 return false;
77 }
78
79 hostNode = hdfManagerNode->child;
80 for (; hostNode != NULL; hostNode = hostNode->sibling) {
81 struct HdfHostInfo *hostInfo = HdfHostInfoNewInstance();
82 if (hostInfo == NULL) {
83 HdfSListFlush(hostList, HdfHostInfoDelete);
84 HDF_LOGE("%{public}s: new hostInfo is null", __func__);
85 return false;
86 }
87 if (!GetHostInfo(hostNode, hostInfo)) {
88 HdfHostInfoFreeInstance(hostInfo);
89 continue;
90 }
91 hostInfo->hostId = hostId;
92 if (!HdfSListAddOrder(hostList, &hostInfo->node, HdfHostListCompare)) {
93 HdfHostInfoFreeInstance(hostInfo);
94 continue;
95 }
96 hostId++;
97 }
98 return true;
99 }
100
HdfDeviceListCompare(struct HdfSListNode * listEntryFirst,struct HdfSListNode * listEntrySecond)101 static bool HdfDeviceListCompare(struct HdfSListNode *listEntryFirst, struct HdfSListNode *listEntrySecond)
102 {
103 struct HdfDeviceInfo *attrFirst = NULL;
104 struct HdfDeviceInfo *attrSecond = NULL;
105 if (listEntryFirst == NULL || listEntrySecond == NULL) {
106 return false;
107 }
108 attrFirst = (struct HdfDeviceInfo *)listEntryFirst;
109 attrSecond = (struct HdfDeviceInfo *)listEntrySecond;
110 return attrFirst->priority <= attrSecond->priority;
111 }
112
GetHostNode(const char * inHostName)113 static const struct DeviceResourceNode *GetHostNode(const char *inHostName)
114 {
115 const struct DeviceResourceNode *hdfManagerNode = NULL;
116 const struct DeviceResourceNode *hostNode = NULL;
117 const char *hostName = NULL;
118 if (inHostName == NULL) {
119 return NULL;
120 }
121 hdfManagerNode = GetHdfManagerNode(HdfGetHcsRootNode());
122 if (hdfManagerNode == NULL) {
123 return NULL;
124 }
125 hostNode = hdfManagerNode->child;
126 while (hostNode != NULL) {
127 if (HcsGetString(hostNode, ATTR_HOST_NAME, &hostName, NULL) != HDF_SUCCESS) {
128 hostNode = hostNode->sibling;
129 continue;
130 }
131 if (strcmp(hostName, inHostName) == 0) {
132 return hostNode;
133 }
134 hostNode = hostNode->sibling;
135 }
136 return NULL;
137 }
138
CheckDeviceInfo(const struct HdfDeviceInfo * deviceNodeInfo)139 static bool CheckDeviceInfo(const struct HdfDeviceInfo *deviceNodeInfo)
140 {
141 if (deviceNodeInfo->policy >= SERVICE_POLICY_INVALID) {
142 HDF_LOGE("%{public}s: policy %{public}u is invalid", __func__, deviceNodeInfo->policy);
143 return false;
144 }
145
146 if (deviceNodeInfo->priority > MAX_PRIORITY_NUM) {
147 HDF_LOGE("%{public}s: priority %{public}u is invalid", __func__, deviceNodeInfo->priority);
148 return false;
149 }
150
151 if (deviceNodeInfo->preload >= DEVICE_PRELOAD_INVALID) {
152 HDF_LOGE("%{public}s: preload %{public}u is invalid", __func__, deviceNodeInfo->preload);
153 return false;
154 }
155
156 return (strcmp(deviceNodeInfo->moduleName, "") != 0);
157 }
158
GetDeviceNodeInfo(const struct DeviceResourceNode * deviceNode,struct HdfDeviceInfo * deviceNodeInfo)159 static bool GetDeviceNodeInfo(const struct DeviceResourceNode *deviceNode, struct HdfDeviceInfo *deviceNodeInfo)
160 {
161 HcsGetUint16(deviceNode, ATTR_DEV_POLICY, &deviceNodeInfo->policy, 0);
162 HcsGetUint16(deviceNode, ATTR_DEV_PRIORITY, &deviceNodeInfo->priority, DEFATLT_DEV_PRIORITY);
163 HcsGetUint16(deviceNode, ATTR_DEV_PRELOAD, &deviceNodeInfo->preload, 0);
164 HcsGetUint16(deviceNode, ATTR_DEV_PERMISSION, &deviceNodeInfo->permission, 0);
165 HcsGetString(deviceNode, ATTR_DEV_MATCHATTR, &deviceNodeInfo->deviceMatchAttr, NULL);
166
167 if (HcsGetString(deviceNode, ATTR_DEV_MODULENAME, &deviceNodeInfo->moduleName, NULL) != HDF_SUCCESS) {
168 HDF_LOGE("%{public}s: failed to get module name", __func__);
169 return false;
170 }
171
172 if (HcsGetString(deviceNode, ATTR_DEV_SVCNAME, &deviceNodeInfo->svcName, NULL) != HDF_SUCCESS) {
173 HDF_LOGE("%{public}s: failed to get service name", __func__);
174 return false;
175 }
176 deviceNodeInfo->deviceName = deviceNode->name;
177 return CheckDeviceInfo(deviceNodeInfo);
178 }
179
GetDevcieNodeList(const struct DeviceResourceNode * device,struct DevHostServiceClnt * hostClnt,uint16_t deviceIdx)180 static bool GetDevcieNodeList(
181 const struct DeviceResourceNode *device, struct DevHostServiceClnt *hostClnt, uint16_t deviceIdx)
182 {
183 uint8_t deviceNodeIdx = 1;
184 uint16_t hostId = hostClnt->hostId;
185 struct HdfDeviceInfo *deviceNodeInfo = NULL;
186 const struct DeviceResourceNode *devNodeResource = device->child;
187
188 for (; devNodeResource != NULL; devNodeResource = devNodeResource->sibling) {
189 deviceNodeInfo = HdfDeviceInfoNewInstance();
190 if (deviceNodeInfo == NULL) {
191 return false;
192 }
193 if (!GetDeviceNodeInfo(devNodeResource, deviceNodeInfo)) {
194 HdfDeviceInfoFreeInstance(deviceNodeInfo);
195 HDF_LOGE("%{public}s: failed to parse device node info, ignore", __func__);
196 continue;
197 }
198
199 deviceNodeInfo->deviceId = MK_DEVID(hostId, deviceIdx, deviceNodeIdx);
200 if (deviceNodeInfo->preload != DEVICE_PRELOAD_DISABLE) {
201 if (!HdfSListAddOrder(&hostClnt->unloadDevInfos, &deviceNodeInfo->node, HdfDeviceListCompare)) {
202 HDF_LOGE("%{public}s: failed to add device info to list %{public}s",
203 __func__, deviceNodeInfo->svcName);
204 HdfDeviceInfoFreeInstance(deviceNodeInfo);
205 continue;
206 }
207 } else {
208 HdfSListAdd(&hostClnt->dynamicDevInfos, &deviceNodeInfo->node);
209 }
210
211 deviceNodeIdx++;
212 }
213 return deviceNodeIdx > 1;
214 }
215
HdfAttributeManagerGetDeviceList(struct DevHostServiceClnt * hostClnt)216 int HdfAttributeManagerGetDeviceList(struct DevHostServiceClnt *hostClnt)
217 {
218 uint16_t deviceIdx = 1;
219 const struct DeviceResourceNode *hostNode = NULL;
220 const struct DeviceResourceNode *device = NULL;
221 int ret = HDF_DEV_ERR_NO_DEVICE;
222
223 if (hostClnt == NULL) {
224 return HDF_ERR_INVALID_PARAM;
225 }
226
227 hostNode = GetHostNode(hostClnt->hostName);
228 if (hostNode == NULL) {
229 return ret;
230 }
231
232 for (device = hostNode->child; device != NULL; device = device->sibling, deviceIdx++) {
233 if (!GetDevcieNodeList(device, hostClnt, deviceIdx)) {
234 return ret;
235 }
236 }
237
238 return HDF_SUCCESS;
239 }