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 }