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