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