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