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