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