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