• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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