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 #include "sample_driver_test.h"
9 #include "devmgr_service.h"
10 #include "devsvc_manager_clnt.h"
11 #include "hdf_device_object.h"
12 #include "hdf_log.h"
13 #include "hdf_pm.h"
14 #include "osal_file.h"
15 #include "osal_mem.h"
16 
17 #define HDF_LOG_TAG sample_driver_test
18 
19 #ifndef INT32_MAX
20 #define INT32_MAX 0x7fffffff
21 #endif
22 
23 struct SampleTestDevice {
24     struct DListHead listNode;
25     struct HdfDeviceObject *devobj;
26 };
27 
28 struct DListHead g_sampleDeviceList = { NULL };
29 
30 #define REGISTER_DEV_MAX 16
31 struct HdfDeviceObject *g_resistedDevice[REGISTER_DEV_MAX] = { 0 };
32 
SaveRegistedDevice(struct SampleTestDevice * sampleDev)33 static void SaveRegistedDevice(struct SampleTestDevice *sampleDev)
34 {
35     if (g_sampleDeviceList.next == NULL) {
36         DListHeadInit(&g_sampleDeviceList);
37     }
38     DListInsertTail(&sampleDev->listNode, &g_sampleDeviceList);
39 }
40 
GetRegistedDevice(const char * serviceName)41 static struct SampleTestDevice *GetRegistedDevice(const char *serviceName)
42 {
43     struct SampleTestDevice *sampleDev = NULL;
44     struct SampleTestDevice *sampleDevTmp = NULL;
45     DLIST_FOR_EACH_ENTRY_SAFE(sampleDev, sampleDevTmp, &g_sampleDeviceList, struct SampleTestDevice, listNode) {
46         if (sampleDev->devobj == NULL || HdfDeviceGetServiceName(sampleDev->devobj) == NULL) {
47             DListRemove(&sampleDev->listNode);
48             OsalMemFree(sampleDev);
49             continue;
50         }
51 
52         if (strcmp(HdfDeviceGetServiceName(sampleDev->devobj), serviceName) == 0) {
53             return sampleDev;
54         }
55     }
56 
57     return NULL;
58 }
59 
HdfSampleDriverRelease(struct HdfDeviceObject * deviceObject)60 static void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject)
61 {
62     (void)deviceObject;
63     return;
64 }
65 
SampleDriverRegisterDevice(struct HdfDeviceObject * dev,struct HdfSBuf * data)66 static int32_t SampleDriverRegisterDevice(struct HdfDeviceObject *dev, struct HdfSBuf *data)
67 {
68     const char *moduleName = NULL;
69     const char *serviceName = NULL;
70     struct HdfDeviceObject *devObj = NULL;
71     struct SampleTestDevice *sampleDev = NULL;
72     int ret;
73 
74     HDF_LOGI("%s:called", __func__);
75     if (data == NULL) {
76         return HDF_FAILURE;
77     }
78 
79     moduleName = HdfSbufReadString(data);
80     if (moduleName == NULL) {
81         return HDF_FAILURE;
82     }
83     serviceName = HdfSbufReadString(data);
84     if (serviceName == NULL) {
85         return HDF_FAILURE;
86     }
87 
88     devObj = HdfDeviceObjectAlloc(dev, moduleName);
89     if (devObj == NULL) {
90         HDF_LOGE("failed to alloc new device for %s", moduleName);
91         return HDF_FAILURE;
92     }
93 
94     ret = HdfDeviceObjectRegister(devObj);
95     if (ret != HDF_SUCCESS) {
96         HDF_LOGE("failed to register device for %s", moduleName);
97         HdfDeviceObjectRelease(devObj);
98         return HDF_FAILURE;
99     }
100 
101     ret = HdfDeviceObjectPublishService(devObj, serviceName, SERVICE_POLICY_CAPACITY,
102         OSAL_S_IREAD | OSAL_S_IWRITE | OSAL_S_IRGRP | OSAL_S_IWGRP | OSAL_S_IROTH);
103     if (ret != HDF_SUCCESS) {
104         HDF_LOGE("failed to publish service for %s", serviceName);
105         HdfDeviceObjectRelease(devObj);
106         return ret;
107     }
108 
109     sampleDev = OsalMemAlloc(sizeof(struct SampleTestDevice));
110     if (sampleDev == NULL) {
111         HdfDeviceObjectRelease(devObj);
112         return HDF_ERR_MALLOC_FAIL;
113     }
114     sampleDev->devobj = devObj;
115     SaveRegistedDevice(sampleDev);
116     HDF_LOGI("register device %s:%s success", moduleName, serviceName);
117     return ret;
118 }
119 
SampleDriverUnregisterDevice(struct HdfSBuf * data)120 static int32_t SampleDriverUnregisterDevice(struct HdfSBuf *data)
121 {
122     const char *moduleName = NULL;
123     const char *serviceName = NULL;
124     struct SampleTestDevice *dev = NULL;
125     if (data == NULL) {
126         return HDF_FAILURE;
127     }
128 
129     moduleName = HdfSbufReadString(data);
130     if (moduleName == NULL) {
131         return HDF_FAILURE;
132     }
133     serviceName = HdfSbufReadString(data);
134     if (serviceName == NULL) {
135         return HDF_FAILURE;
136     }
137     dev = GetRegistedDevice(serviceName);
138     if (dev == NULL) {
139         HDF_LOGE("failed to found device %s", serviceName);
140         return HDF_DEV_ERR_NO_DEVICE;
141     }
142     HdfDeviceObjectRelease(dev->devobj);
143     DListRemove(&dev->listNode);
144     OsalMemFree(dev);
145     HDF_LOGI("unregister device %s:%s success", moduleName, serviceName);
146     return HDF_SUCCESS;
147 }
148 
SampleDriverSendEvent(struct HdfDeviceIoClient * client,int id,struct HdfSBuf * data,bool broadcast)149 static int32_t SampleDriverSendEvent(struct HdfDeviceIoClient *client, int id, struct HdfSBuf *data, bool broadcast)
150 {
151     return broadcast ? HdfDeviceSendEvent(client->device, id, data) : HdfDeviceSendEventToClient(client, id, data);
152 }
153 
SampleDriverPowerStateInject(uint32_t powerState)154 static int32_t SampleDriverPowerStateInject(uint32_t powerState)
155 {
156     int ret;
157     struct IDevmgrService *devmgrService = DevmgrServiceGetInstance();
158     if (devmgrService == NULL || devmgrService->PowerStateChange == NULL) {
159         return HDF_ERR_INVALID_OBJECT;
160     }
161     ret = devmgrService->PowerStateChange(devmgrService, powerState);
162 
163     HDF_LOGI("%s: inject power state(%u) done, ret = %d", __func__, powerState, ret);
164     return ret;
165 }
166 
SampleDriverUpdateService(struct HdfDeviceIoClient * client,struct HdfSBuf * data)167 static int32_t SampleDriverUpdateService(struct HdfDeviceIoClient *client, struct HdfSBuf *data)
168 {
169     const char *servInfo = HdfSbufReadString(data);
170     int32_t ret;
171     if (servInfo == NULL) {
172         HDF_LOGE("%s: miss servce info", __func__);
173         return HDF_ERR_INVALID_PARAM;
174     }
175 
176     if (HdfDeviceObjectSetServInfo(client->device, servInfo) != HDF_SUCCESS) {
177         HDF_LOGE("%s: failed to set servce info", __func__);
178         return HDF_ERR_INVALID_PARAM;
179     }
180     ret = HdfDeviceObjectUpdate(client->device);
181     HDF_LOGE("%s:set servce info done, ret = %d", __func__, ret);
182     return ret;
183 }
184 
SampleDriverDispatch(struct HdfDeviceIoClient * client,int cmdId,struct HdfSBuf * data,struct HdfSBuf * reply)185 static int32_t SampleDriverDispatch(
186     struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
187 {
188     uint32_t powerState = 0;
189     int32_t ret = HDF_SUCCESS;
190     if (reply == NULL || client == NULL) {
191         return HDF_FAILURE;
192     }
193     switch (cmdId) {
194         case SAMPLE_DRIVER_REGISTER_DEVICE: {
195             ret = SampleDriverRegisterDevice(client->device, data);
196             HdfSbufWriteInt32(reply, ret);
197             break;
198         }
199         case SAMPLE_DRIVER_UNREGISTER_DEVICE:
200             ret = SampleDriverUnregisterDevice(data);
201             HdfSbufWriteInt32(reply, ret);
202             break;
203         case SAMPLE_DRIVER_UPDATE_SERVICE_INFO:
204             ret = SampleDriverUpdateService(client, data);
205             break;
206         case SAMPLE_DRIVER_SENDEVENT_SINGLE_DEVICE:
207             ret = SampleDriverSendEvent(client, cmdId, data, false);
208             HdfSbufWriteInt32(reply, INT32_MAX);
209             break;
210         case SAMPLE_DRIVER_SENDEVENT_BROADCAST_DEVICE:
211             ret = SampleDriverSendEvent(client, cmdId, data, true);
212             HdfSbufWriteInt32(reply, INT32_MAX);
213             break;
214         case SAMPLE_DRIVER_PM_STATE_INJECT:
215             HdfSbufReadUint32(data, &powerState);
216             return SampleDriverPowerStateInject(powerState);
217         default:
218             break;
219     }
220 
221     return ret;
222 }
223 
HdfSampleDriverBind(struct HdfDeviceObject * deviceObject)224 static int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject)
225 {
226     static struct IDeviceIoService testService = {
227         .Dispatch = SampleDriverDispatch,
228         .Open = NULL,
229         .Release = NULL,
230     };
231     HDF_LOGD("%s::enter", __func__);
232     if (deviceObject == NULL) {
233         return HDF_FAILURE;
234     }
235 
236     deviceObject->service = &testService;
237     return HDF_SUCCESS;
238 }
239 
HdfSampleDozeResume(struct HdfDeviceObject * deviceObject)240 static int HdfSampleDozeResume(struct HdfDeviceObject *deviceObject)
241 {
242     (void)deviceObject;
243     HDF_LOGI("%s:called", __func__);
244     return HDF_SUCCESS;
245 }
246 
HdfSampleDozeSuspend(struct HdfDeviceObject * deviceObject)247 static int HdfSampleDozeSuspend(struct HdfDeviceObject *deviceObject)
248 {
249     (void)deviceObject;
250     HDF_LOGI("%s:called", __func__);
251     return HDF_SUCCESS;
252 }
253 
HdfSampleResume(struct HdfDeviceObject * deviceObject)254 static int HdfSampleResume(struct HdfDeviceObject *deviceObject)
255 {
256     (void)deviceObject;
257     HDF_LOGI("%s:called", __func__);
258     return HDF_SUCCESS;
259 }
260 
HdfSampleSuspend(struct HdfDeviceObject * deviceObject)261 static int HdfSampleSuspend(struct HdfDeviceObject *deviceObject)
262 {
263     (void)deviceObject;
264     HDF_LOGI("%s:called", __func__);
265     return HDF_SUCCESS;
266 }
267 
268 struct SampleDriverPmListener {
269     struct IPowerEventListener powerListener;
270     void *p;
271 };
272 
HdfSampleDriverInit(struct HdfDeviceObject * deviceObject)273 static int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject)
274 {
275     static struct SampleDriverPmListener pmListener = { 0 };
276     int ret;
277     HDF_LOGI("%s::enter!", __func__);
278     if (deviceObject == NULL) {
279         HDF_LOGE("%s::ptr is null!", __func__);
280         return HDF_FAILURE;
281     }
282     HDF_LOGD("%s:Init success", __func__);
283     HdfDeviceObjectSetServInfo(deviceObject, SAMPLE_SERVICE);
284     pmListener.powerListener.DozeResume = HdfSampleDozeResume;
285     pmListener.powerListener.DozeSuspend = HdfSampleDozeSuspend;
286     pmListener.powerListener.Resume = HdfSampleResume;
287     pmListener.powerListener.Suspend = HdfSampleSuspend;
288 
289     ret = HdfPmRegisterPowerListener(deviceObject, &pmListener.powerListener);
290     HDF_LOGI("%s:register power listener, ret = %d", __func__, ret);
291 
292     return HDF_SUCCESS;
293 }
294 
295 struct HdfDriverEntry g_sampleDriverEntry = {
296     .moduleVersion = 1,
297     .moduleName = "sample_driver",
298     .Bind = HdfSampleDriverBind,
299     .Init = HdfSampleDriverInit,
300     .Release = HdfSampleDriverRelease,
301 };
302 
303 HDF_INIT(g_sampleDriverEntry);
304 
305