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