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_object.h"
10 #include "devhost_service.h"
11 #include "devsvc_manager_clnt.h"
12 #include "hdf_base.h"
13 #include "hdf_cstring.h"
14 #include "hdf_device_node.h"
15 #include "hdf_driver_loader.h"
16 #include "hdf_log.h"
17 #include "hdf_object_manager.h"
18 #include "hdf_power_manager.h"
19 #include "hdf_service_observer.h"
20 #include "osal_mem.h"
21 #include "power_state_token.h"
22
23 #define HDF_LOG_TAG device_object
24
25 #define SERVICE_INFO_LEN_MAX 128
26
HdfDeviceSubscribeService(struct HdfDeviceObject * deviceObject,const char * serviceName,struct SubscriberCallback callback)27 int32_t HdfDeviceSubscribeService(
28 struct HdfDeviceObject *deviceObject, const char *serviceName, struct SubscriberCallback callback)
29 {
30 struct DevHostService *hostService = NULL;
31 struct HdfDeviceNode *devNode = NULL;
32 if (deviceObject == NULL || serviceName == NULL) {
33 HDF_LOGE("failed to subscribe service, serviceName is null");
34 return HDF_FAILURE;
35 }
36 devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
37 struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
38 hostService = devNode->hostService;
39 if (hostService == NULL) {
40 HDF_LOGE("failed to subscribe service, hostService is null");
41 return HDF_FAILURE;
42 }
43
44 return HdfServiceObserverSubscribeService(&hostService->observer, serviceName, devNode->devId, callback);
45 }
46
HdfDeviceGetServiceName(const struct HdfDeviceObject * deviceObject)47 const char *HdfDeviceGetServiceName(const struct HdfDeviceObject *deviceObject)
48 {
49 struct HdfDeviceNode *devNode = NULL;
50 if (deviceObject == NULL) {
51 HDF_LOGE("failed to get service name, deviceObject is invalid");
52 return NULL;
53 }
54 devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
55 struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
56 return devNode->servName;
57 }
58
HdfPmRegisterPowerListener(struct HdfDeviceObject * deviceObject,const struct IPowerEventListener * listener)59 int HdfPmRegisterPowerListener(struct HdfDeviceObject *deviceObject, const struct IPowerEventListener *listener)
60 {
61 struct HdfDeviceNode *devNode = NULL;
62 if (deviceObject == NULL) {
63 return HDF_ERR_INVALID_PARAM;
64 }
65 devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
66 struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
67 return HdfDeviceNodeAddPowerStateListener(devNode, listener);
68 }
69
HdfPmUnregisterPowerListener(struct HdfDeviceObject * deviceObject,const struct IPowerEventListener * listener)70 void HdfPmUnregisterPowerListener(struct HdfDeviceObject *deviceObject, const struct IPowerEventListener *listener)
71 {
72 struct HdfDeviceNode *devNode = NULL;
73 if (deviceObject == NULL) {
74 return;
75 }
76 devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
77 struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
78 HdfDeviceNodeRemovePowerStateListener(devNode, listener);
79 }
80
HdfPmAcquireDevice(struct HdfDeviceObject * deviceObject)81 void HdfPmAcquireDevice(struct HdfDeviceObject *deviceObject)
82 {
83 struct HdfDeviceNode *devNode = NULL;
84 struct IPowerStateToken *tokenIf = NULL;
85 if (deviceObject == NULL) {
86 HDF_LOGE("HdfPmAcquireDevice input param is invalid");
87 return;
88 }
89 devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
90 struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
91 tokenIf = (struct IPowerStateToken *)devNode->powerToken;
92 if ((tokenIf != NULL) && (tokenIf->AcquireWakeLock != NULL)) {
93 tokenIf->AcquireWakeLock(tokenIf);
94 }
95 }
96
HdfPmReleaseDevice(struct HdfDeviceObject * deviceObject)97 void HdfPmReleaseDevice(struct HdfDeviceObject *deviceObject)
98 {
99 struct HdfDeviceNode *devNode = NULL;
100 struct IPowerStateToken *tokenIf = NULL;
101 if (deviceObject == NULL) {
102 HDF_LOGE("HdfPmReleaseDevice input param is invalid");
103 return;
104 }
105 devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
106 struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
107 tokenIf = (struct IPowerStateToken *)devNode->powerToken;
108 if ((tokenIf != NULL) && (tokenIf->ReleaseWakeLock != NULL)) {
109 tokenIf->ReleaseWakeLock(tokenIf);
110 }
111 }
112
HdfPmAcquireDeviceAsync(struct HdfDeviceObject * deviceObject)113 void HdfPmAcquireDeviceAsync(struct HdfDeviceObject *deviceObject)
114 {
115 struct HdfDeviceNode *devNode = NULL;
116
117 if (deviceObject == NULL) {
118 HDF_LOGE("%s: input param is invalid", __func__);
119 return;
120 }
121
122 devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
123 struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
124 HdfPmTaskPut(devNode->powerToken, HDF_PM_REQUEST_ACQUIRE);
125 }
126
HdfPmReleaseDeviceAsync(struct HdfDeviceObject * deviceObject)127 void HdfPmReleaseDeviceAsync(struct HdfDeviceObject *deviceObject)
128 {
129 struct HdfDeviceNode *devNode = NULL;
130
131 if (deviceObject == NULL) {
132 HDF_LOGE("%s: input param is invalid", __func__);
133 return;
134 }
135
136 devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
137 struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
138 HdfPmTaskPut(devNode->powerToken, HDF_PM_REQUEST_RELEASE);
139 }
140
HdfPmSetMode(struct HdfDeviceObject * deviceObject,uint32_t mode)141 void HdfPmSetMode(struct HdfDeviceObject *deviceObject, uint32_t mode)
142 {
143 struct HdfDeviceNode *devNode = NULL;
144 struct PowerStateToken *token = NULL;
145 if (deviceObject == NULL || mode > HDF_POWER_MODE_MAX) {
146 HDF_LOGE("%s: input param is invalid", __func__);
147 return;
148 }
149 devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF(
150 struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject);
151 token = devNode->powerToken;
152 if (token != NULL) {
153 token->mode = mode;
154 }
155 }
156
HdfDeviceSetClass(struct HdfDeviceObject * deviceObject,DeviceClass deviceClass)157 bool HdfDeviceSetClass(struct HdfDeviceObject *deviceObject, DeviceClass deviceClass)
158 {
159 if ((deviceObject == NULL) || (deviceClass >= DEVICE_CLASS_MAX)) {
160 return false;
161 }
162 deviceObject->deviceClass = deviceClass;
163 return true;
164 }
165
HdfDeviceObjectConstruct(struct HdfDeviceObject * deviceObject)166 void HdfDeviceObjectConstruct(struct HdfDeviceObject *deviceObject)
167 {
168 if (deviceObject != NULL) {
169 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
170 deviceObject->deviceMatchAttr = NULL;
171 #else
172 deviceObject->property = NULL;
173 #endif
174 deviceObject->service = NULL;
175 deviceObject->deviceClass = DEVICE_CLASS_DEFAULT;
176 }
177 }
178
HdfDeviceObjectAlloc(struct HdfDeviceObject * parent,const char * driverName)179 struct HdfDeviceObject *HdfDeviceObjectAlloc(struct HdfDeviceObject *parent, const char *driverName)
180 {
181 struct HdfDeviceNode *newNode = NULL;
182 struct HdfDeviceNode *parentDevNode = CONTAINER_OF(parent, struct HdfDeviceNode, deviceObject);
183
184 if (parent == NULL) {
185 HDF_LOGE("failed to alloc device, parent invalid");
186 return NULL;
187 }
188
189 if (parentDevNode->devStatus != DEVNODE_LAUNCHED) {
190 HDF_LOGE("failed to alloc device, parent status invalid %{public}u", parentDevNode->devStatus);
191 return NULL;
192 }
193
194 newNode = (struct HdfDeviceNode *)HdfObjectManagerGetObject(HDF_OBJECT_ID_DEVICE_SERVICE);
195 if (newNode == NULL) {
196 return NULL;
197 }
198 newNode->driverName = HdfStringCopy(driverName);
199 if (newNode->driverName == NULL) {
200 HdfDeviceNodeFreeInstance(newNode);
201 return NULL;
202 }
203
204 newNode->hostService = parentDevNode->hostService;
205 newNode->device = parentDevNode->device;
206
207 return &newNode->deviceObject;
208 }
209
HdfDeviceObjectRelease(struct HdfDeviceObject * dev)210 void HdfDeviceObjectRelease(struct HdfDeviceObject *dev)
211 {
212 struct HdfDeviceNode *devNode = CONTAINER_OF(dev, struct HdfDeviceNode, deviceObject);
213 if (dev == NULL) {
214 return;
215 }
216
217 if (devNode->device != NULL && devNode->device->super.Detach != NULL) {
218 devNode->device->super.Detach(&devNode->device->super, devNode);
219 }
220 HdfDeviceNodeFreeInstance(devNode);
221 }
222
HdfDeviceObjectRegister(struct HdfDeviceObject * dev)223 int HdfDeviceObjectRegister(struct HdfDeviceObject *dev)
224 {
225 int ret = HDF_FAILURE;
226 struct HdfDeviceNode *devNode = CONTAINER_OF(dev, struct HdfDeviceNode, deviceObject);
227 struct IDriverLoader *driverLoader = HdfDriverLoaderGetInstance();
228
229 if (dev == NULL || devNode->driverName == NULL || devNode->device == NULL || driverLoader == NULL ||
230 driverLoader->GetDriver == NULL) {
231 HDF_LOGE("failed to add device, param invalid");
232 return HDF_ERR_INVALID_PARAM;
233 }
234
235 devNode->driver = driverLoader->GetDriver(devNode->driverName);
236 if (devNode->driver == NULL) {
237 HDF_LOGE("can not found driver %s", devNode->driverName);
238 return HDF_DEV_ERR_NO_DEVICE;
239 }
240
241 ret = devNode->device->super.Attach(&devNode->device->super, devNode);
242 if (ret != HDF_SUCCESS) {
243 HDF_LOGE("failed to attach device %s", devNode->driverName);
244 return HDF_DEV_ERR_ATTACHDEV_FAIL;
245 }
246
247 return ret;
248 }
249
HdfDeviceObjectUnRegister(struct HdfDeviceObject * dev)250 int HdfDeviceObjectUnRegister(struct HdfDeviceObject *dev)
251 {
252 struct HdfDeviceNode *devNode = CONTAINER_OF(dev, struct HdfDeviceNode, deviceObject);
253 if (devNode == NULL || devNode->device == NULL) {
254 return HDF_ERR_INVALID_OBJECT;
255 }
256
257 return devNode->device->super.Detach(&devNode->device->super, devNode);
258 }
259
HdfDeviceObjectPublishService(struct HdfDeviceObject * dev,const char * servName,uint8_t policy,uint32_t perm)260 int HdfDeviceObjectPublishService(struct HdfDeviceObject *dev, const char *servName, uint8_t policy, uint32_t perm)
261 {
262 int ret;
263 struct HdfDeviceNode *devNode = CONTAINER_OF(dev, struct HdfDeviceNode, deviceObject);
264 if (dev == NULL || servName == NULL) {
265 return HDF_ERR_INVALID_PARAM;
266 }
267
268 if (policy <= SERVICE_POLICY_NONE || policy >= SERVICE_POLICY_INVALID) {
269 return HDF_DEV_ERR_NO_DEVICE_SERVICE;
270 }
271
272 if (devNode->servStatus) {
273 HDF_LOGE("failed to publish public service, repeat publish");
274 return HDF_FAILURE;
275 }
276
277 devNode->servName = HdfStringCopy(servName);
278 if (devNode->servName == NULL) {
279 return HDF_DEV_ERR_NO_MEMORY;
280 }
281
282 devNode->policy = policy;
283 devNode->permission = perm;
284
285 ret = DeviceDriverBind(devNode);
286 if (ret != HDF_SUCCESS) {
287 return ret;
288 }
289
290 return devNode->super.PublishService(devNode);
291 }
292
HdfDeviceObjectRemoveService(struct HdfDeviceObject * dev)293 int HdfDeviceObjectRemoveService(struct HdfDeviceObject *dev)
294 {
295 struct HdfDeviceNode *devNode = CONTAINER_OF(dev, struct HdfDeviceNode, deviceObject);
296 if (dev == NULL) {
297 return HDF_ERR_INVALID_PARAM;
298 }
299
300 return devNode->super.RemoveService(devNode);
301 }
HdfDeviceObjectSetServInfo(struct HdfDeviceObject * dev,const char * info)302 int HdfDeviceObjectSetServInfo(struct HdfDeviceObject *dev, const char *info)
303 {
304 if (dev == NULL || info == NULL || strlen(info) > SERVICE_INFO_LEN_MAX) {
305 return HDF_ERR_INVALID_PARAM;
306 }
307
308 struct HdfDeviceNode *devNode = CONTAINER_OF(dev, struct HdfDeviceNode, deviceObject);
309 if (devNode->servInfo != NULL) {
310 OsalMemFree((char *)devNode->servInfo);
311 }
312 devNode->servInfo = HdfStringCopy(info);
313 if (devNode->servInfo == NULL) {
314 return HDF_ERR_MALLOC_FAIL;
315 }
316 return HDF_SUCCESS;
317 }
318
HdfDeviceObjectUpdate(struct HdfDeviceObject * dev)319 int HdfDeviceObjectUpdate(struct HdfDeviceObject *dev)
320 {
321 struct HdfDeviceNode *devNode = CONTAINER_OF(dev, struct HdfDeviceNode, deviceObject);
322 if (dev == NULL) {
323 return HDF_ERR_INVALID_PARAM;
324 }
325 struct HdfServiceInfo servInfo;
326 HdfServiceInfoInit(&servInfo, devNode);
327 return DevSvcManagerClntUpdateService(&devNode->deviceObject, &servInfo);
328 }
329
HdfDeviceObjectSetInterfaceDesc(struct HdfDeviceObject * dev,const char * interfaceDesc)330 int HdfDeviceObjectSetInterfaceDesc(struct HdfDeviceObject *dev, const char *interfaceDesc)
331 {
332 struct HdfDeviceNode *devNode = CONTAINER_OF(dev, struct HdfDeviceNode, deviceObject);
333 if (dev == NULL || interfaceDesc == NULL) {
334 return HDF_ERR_INVALID_PARAM;
335 }
336 devNode->interfaceDesc = HdfStringCopy(interfaceDesc);
337 return devNode->interfaceDesc != NULL ? HDF_SUCCESS : HDF_ERR_MALLOC_FAIL;
338 }
339
HdfDeviceObjectCheckInterfaceDesc(struct HdfDeviceObject * dev,struct HdfSBuf * data)340 bool __attribute__((weak)) HdfDeviceObjectCheckInterfaceDesc(struct HdfDeviceObject *dev, struct HdfSBuf *data)
341 {
342 (void)dev;
343 (void)data;
344 return true;
345 }