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_device_node.h"
10 #include "devhost_service.h"
11 #include "devmgr_service_clnt.h"
12 #include "devsvc_manager_clnt.h"
13 #include "hcs_tree_if.h"
14 #include "hdf_attribute_manager.h"
15 #include "hdf_base.h"
16 #include "hdf_cstring.h"
17 #include "hdf_device_object.h"
18 #include "hdf_device_token.h"
19 #include "hdf_driver_loader.h"
20 #include "hdf_log.h"
21 #include "hdf_object_manager.h"
22 #include "hdf_observer_record.h"
23 #include "osal_mem.h"
24 #include "power_state_token.h"
25
26 #define HDF_LOG_TAG device_node
27
HdfDeviceNodePublishLocalService(struct HdfDeviceNode * devNode)28 static int HdfDeviceNodePublishLocalService(struct HdfDeviceNode *devNode)
29 {
30 if (devNode == NULL) {
31 HDF_LOGE("failed to publish local service, device is null");
32 return HDF_FAILURE;
33 }
34 if (devNode->hostService == NULL) {
35 HDF_LOGE("failed to publish local service, host service is null");
36 return HDF_FAILURE;
37 }
38 return HdfServiceObserverPublishService(&(devNode->hostService->observer), devNode->servName,
39 devNode->devId, devNode->policy, (struct HdfObject *)devNode->deviceObject.service);
40 }
41
HdfDeviceNodePublishService(struct HdfDeviceNode * devNode)42 static int HdfDeviceNodePublishService(struct HdfDeviceNode *devNode)
43 {
44 int status = HDF_SUCCESS;
45 struct IDeviceNode *nodeIf = NULL;
46 if (devNode->policy == SERVICE_POLICY_NONE ||
47 (devNode->servName != NULL && strlen(devNode->servName) == 0)) {
48 return status;
49 }
50
51 nodeIf = &devNode->super;
52 if (devNode->policy == SERVICE_POLICY_PUBLIC || devNode->policy == SERVICE_POLICY_CAPACITY) {
53 if (nodeIf->PublishService != NULL) {
54 status = nodeIf->PublishService(devNode);
55 }
56 }
57 if (status == HDF_SUCCESS) {
58 status = HdfDeviceNodePublishLocalService(devNode);
59 }
60 return status;
61 }
62
DeviveDriverBind(struct HdfDeviceNode * devNode)63 int DeviveDriverBind(struct HdfDeviceNode *devNode)
64 {
65 int ret;
66 const struct HdfDriverEntry *driverEntry = NULL;
67 if (devNode == NULL) {
68 return HDF_ERR_INVALID_PARAM;
69 }
70
71 driverEntry = devNode->driver->entry;
72 if (devNode->policy == SERVICE_POLICY_PUBLIC || devNode->policy == SERVICE_POLICY_CAPACITY) {
73 if (driverEntry->Bind == NULL) {
74 HDF_LOGE("driver %s bind method not implement", driverEntry->moduleName);
75 devNode->devStatus = DEVNODE_NONE;
76 return HDF_ERR_INVALID_OBJECT;
77 }
78 ret = driverEntry->Bind(&devNode->deviceObject);
79 if (ret != HDF_SUCCESS) {
80 HDF_LOGE("bind driver %s failed", driverEntry->moduleName);
81 return HDF_DEV_ERR_DEV_INIT_FAIL;
82 }
83 }
84
85 return HDF_SUCCESS;
86 }
87
HdfDeviceLaunchNode(struct HdfDeviceNode * devNode)88 int HdfDeviceLaunchNode(struct HdfDeviceNode *devNode)
89 {
90 const struct HdfDriverEntry *driverEntry = NULL;
91 int ret;
92 if (devNode == NULL) {
93 HDF_LOGE("failed to launch service, device or service is null");
94 return HDF_ERR_INVALID_PARAM;
95 }
96
97 HDF_LOGI("launch devnode %s", devNode->servName ? devNode->servName : "");
98 driverEntry = devNode->driver->entry;
99 if (driverEntry == NULL || driverEntry->Init == NULL) {
100 HDF_LOGE("failed to launch service, deviceEntry invalid");
101 return HDF_ERR_INVALID_PARAM;
102 }
103 devNode->devStatus = DEVNODE_LAUNCHED;
104
105 ret = DeviveDriverBind(devNode);
106 if (ret != HDF_SUCCESS) {
107 return ret;
108 }
109
110 ret = driverEntry->Init(&devNode->deviceObject);
111 if (ret != HDF_SUCCESS) {
112 return HDF_DEV_ERR_DEV_INIT_FAIL;
113 }
114
115 ret = HdfDeviceNodePublishService(devNode);
116 if (ret != HDF_SUCCESS) {
117 return HDF_DEV_ERR_PUBLISH_FAIL;
118 }
119
120 ret = DevmgrServiceClntAttachDevice(devNode->token);
121 if (ret != HDF_SUCCESS) {
122 return HDF_DEV_ERR_ATTACHDEV_FAIL;
123 }
124 return ret;
125 }
126
HdfDeviceNodeAddPowerStateListener(struct HdfDeviceNode * devNode,const struct IPowerEventListener * listener)127 int HdfDeviceNodeAddPowerStateListener(
128 struct HdfDeviceNode *devNode, const struct IPowerEventListener *listener)
129 {
130 if (devNode->powerToken != NULL) {
131 return HDF_FAILURE;
132 }
133
134 devNode->powerToken = PowerStateTokenNewInstance(&devNode->deviceObject, listener);
135 return (devNode->powerToken != NULL) ? HDF_SUCCESS : HDF_FAILURE;
136 }
137
HdfDeviceNodeRemovePowerStateListener(struct HdfDeviceNode * devNode,const struct IPowerEventListener * listener)138 void HdfDeviceNodeRemovePowerStateListener(
139 struct HdfDeviceNode *devNode, const struct IPowerEventListener *listener)
140 {
141 (void)listener;
142 if (devNode == NULL || devNode->powerToken == NULL) {
143 return;
144 }
145
146 PowerStateTokenFreeInstance(devNode->powerToken);
147 devNode->powerToken = NULL;
148 }
149
HdfDeviceNodePublishPublicService(struct HdfDeviceNode * devNode)150 int HdfDeviceNodePublishPublicService(struct HdfDeviceNode *devNode)
151 {
152 int ret;
153 if (devNode == NULL || devNode->deviceObject.service == NULL) {
154 HDF_LOGE("failed to publish public service, devNode is NULL");
155 return HDF_FAILURE;
156 }
157
158 ret = DevSvcManagerClntAddService(devNode->servName,
159 devNode->deviceObject.deviceClass, &devNode->deviceObject, devNode->servInfo);
160 if (ret == HDF_SUCCESS) {
161 devNode->servStatus = true;
162 }
163
164 return ret;
165 }
166
HdfDeviceNodeRemoveService(struct HdfDeviceNode * devNode)167 int HdfDeviceNodeRemoveService(struct HdfDeviceNode *devNode)
168 {
169 if (devNode != NULL && devNode->servStatus) {
170 DevSvcManagerClntRemoveService(devNode->servName);
171 devNode->servStatus = false;
172 }
173
174 return HDF_SUCCESS;
175 }
176
HdfDeviceUnlaunchNode(struct HdfDeviceNode * devNode)177 static void HdfDeviceUnlaunchNode(struct HdfDeviceNode *devNode)
178 {
179 const struct HdfDriverEntry *driverEntry = NULL;
180 struct IDriverLoader *driverLoader = NULL;
181 if (devNode == NULL || devNode->devStatus != DEVNODE_LAUNCHED) {
182 return;
183 }
184
185 if (devNode->driver != NULL) {
186 driverEntry = devNode->driver->entry;
187 }
188
189 if (driverEntry != NULL && driverEntry->Release != NULL) {
190 driverEntry->Release(&devNode->deviceObject);
191 }
192
193 if (devNode->servStatus) {
194 devNode->super.RemoveService(devNode);
195 }
196 DevmgrServiceClntDetachDevice(devNode->devId);
197
198 // release driver object or close driver library
199 driverLoader = HdfDriverLoaderGetInstance();
200 if (driverLoader != NULL) {
201 driverLoader->ReclaimDriver(devNode->driver);
202 devNode->driver = NULL;
203 } else {
204 HDF_LOGE("failed to get driver loader");
205 }
206 devNode->devStatus = DEVNODE_INITED;
207 }
208
HdfDeviceNodeConstruct(struct HdfDeviceNode * devNode)209 void HdfDeviceNodeConstruct(struct HdfDeviceNode *devNode)
210 {
211 if (devNode != NULL) {
212 struct IDeviceNode *nodeIf = &devNode->super;
213 HdfDeviceObjectConstruct(&devNode->deviceObject);
214 devNode->token = HdfDeviceTokenNewInstance();
215 nodeIf->LaunchNode = HdfDeviceLaunchNode;
216 nodeIf->PublishService = HdfDeviceNodePublishPublicService;
217 nodeIf->RemoveService = HdfDeviceNodeRemoveService;
218 nodeIf->UnlaunchNode = HdfDeviceUnlaunchNode;
219 }
220 }
221
HdfDeviceNodeDestruct(struct HdfDeviceNode * devNode)222 void HdfDeviceNodeDestruct(struct HdfDeviceNode *devNode)
223 {
224 if (devNode == NULL) {
225 return;
226 }
227 HDF_LOGI("release devnode %s", devNode->servName);
228 switch (devNode->devStatus) {
229 case DEVNODE_LAUNCHED: // fall-through
230 HdfDeviceUnlaunchNode(devNode);
231 case DEVNODE_INITED:
232 HdfDeviceTokenFreeInstance(devNode->token);
233 devNode->token = NULL;
234 PowerStateTokenFreeInstance(devNode->powerToken);
235 devNode->powerToken = NULL;
236 OsalMemFree(devNode->servName);
237 OsalMemFree((char *)devNode->servInfo);
238 OsalMemFree(devNode->driverName);
239 devNode->servName = NULL;
240 devNode->servInfo = NULL;
241 break;
242 case DEVNODE_NONE:
243 break;
244 default:
245 break;
246 }
247 }
248
HdfDeviceNodeNewInstance(const struct HdfDeviceInfo * deviceInfo,struct HdfDriver * driver)249 struct HdfDeviceNode *HdfDeviceNodeNewInstance(const struct HdfDeviceInfo *deviceInfo, struct HdfDriver *driver)
250 {
251 struct HdfDeviceNode *devNode = NULL;
252 if (deviceInfo == NULL) {
253 return NULL;
254 }
255 devNode = (struct HdfDeviceNode *)HdfObjectManagerGetObject(HDF_OBJECT_ID_DEVICE_SERVICE);
256 if (devNode == NULL) {
257 return NULL;
258 }
259
260 devNode->driver = driver;
261 devNode->devId = deviceInfo->deviceId;
262 devNode->permission = deviceInfo->permission;
263 devNode->policy = deviceInfo->policy;
264 devNode->token->devid = deviceInfo->deviceId;
265 devNode->servName = HdfStringCopy(deviceInfo->svcName);
266 if (devNode->servName == NULL) {
267 HdfDeviceNodeFreeInstance(devNode);
268 return NULL;
269 }
270 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
271 devNode->deviceObject.deviceMatchAttr = deviceInfo->deviceMatchAttr;
272 #else
273 devNode->deviceObject.property = HcsGetNodeByMatchAttr(HdfGetHcsRootNode(), deviceInfo->deviceMatchAttr);
274 if (devNode->deviceObject.property == NULL) {
275 HDF_LOGD("node %s property empty, match attr: %s", deviceInfo->moduleName, deviceInfo->deviceMatchAttr);
276 }
277 #endif
278
279 devNode->devStatus = DEVNODE_INITED;
280 return devNode;
281 }
282
HdfDeviceNodeFreeInstance(struct HdfDeviceNode * devNode)283 void HdfDeviceNodeFreeInstance(struct HdfDeviceNode *devNode)
284 {
285 HdfObjectManagerFreeObject((struct HdfObject *)devNode);
286 }
287