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 #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 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 void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject)
61 {
62 (void)deviceObject;
63 return;
64 }
65
SampleDriverRegisterDevice(struct HdfDeviceObject * dev,struct HdfSBuf * data)66 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("faild 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("faild 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("faild 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 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 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 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(%d) done, ret = %d", __func__, powerState, ret);
164 return ret;
165 }
166
SampleDriverUpdateService(struct HdfDeviceIoClient * client,struct HdfSBuf * data)167 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 int32_t SampleDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
186 {
187 uint32_t powerState = 0;
188 int32_t ret = HDF_SUCCESS;
189 if (reply == NULL || client == NULL) {
190 return HDF_FAILURE;
191 }
192 switch (cmdId) {
193 case SAMPLE_DRIVER_REGISTER_DEVICE: {
194 ret = SampleDriverRegisterDevice(client->device, data);
195 HdfSbufWriteInt32(reply, ret);
196 break;
197 }
198 case SAMPLE_DRIVER_UNREGISTER_DEVICE:
199 ret = SampleDriverUnregisterDevice(data);
200 HdfSbufWriteInt32(reply, ret);
201 break;
202 case SAMPLE_DRIVER_UPDATE_SERVICE_INFO:
203 ret = SampleDriverUpdateService(client, data);
204 break;
205 case SAMPLE_DRIVER_SENDEVENT_SINGLE_DEVICE:
206 ret = SampleDriverSendEvent(client, cmdId, data, false);
207 HdfSbufWriteInt32(reply, INT32_MAX);
208 break;
209 case SAMPLE_DRIVER_SENDEVENT_BROADCAST_DEVICE:
210 ret = SampleDriverSendEvent(client, cmdId, data, true);
211 HdfSbufWriteInt32(reply, INT32_MAX);
212 break;
213 case SAMPLE_DRIVER_PM_STATE_INJECT:
214 HdfSbufReadUint32(data, &powerState);
215 return SampleDriverPowerStateInject(powerState);
216 default:
217 break;
218 }
219
220 return ret;
221 }
222
HdfSampleDriverBind(struct HdfDeviceObject * deviceObject)223 int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject)
224 {
225 static struct IDeviceIoService testService = {
226 .Dispatch = SampleDriverDispatch,
227 .Open = NULL,
228 .Release = NULL,
229 };
230 HDF_LOGD("%s::enter", __func__);
231 if (deviceObject == NULL) {
232 return HDF_FAILURE;
233 }
234
235 deviceObject->service = &testService;
236 return HDF_SUCCESS;
237 }
238
HdfSampleDozeResume(struct HdfDeviceObject * deviceObject)239 int HdfSampleDozeResume(struct HdfDeviceObject *deviceObject)
240 {
241 HDF_LOGI("%s:called", __func__);
242 return HDF_SUCCESS;
243 }
244
HdfSampleDozeSuspend(struct HdfDeviceObject * deviceObject)245 int HdfSampleDozeSuspend(struct HdfDeviceObject *deviceObject)
246 {
247 HDF_LOGI("%s:called", __func__);
248 return HDF_SUCCESS;
249 }
250
HdfSampleResume(struct HdfDeviceObject * deviceObject)251 int HdfSampleResume(struct HdfDeviceObject *deviceObject)
252 {
253 HDF_LOGI("%s:called", __func__);
254 return HDF_SUCCESS;
255 }
256
HdfSampleSuspend(struct HdfDeviceObject * deviceObject)257 int HdfSampleSuspend(struct HdfDeviceObject *deviceObject)
258 {
259 HDF_LOGI("%s:called", __func__);
260 return HDF_SUCCESS;
261 }
262
263 struct SampleDriverPmListener {
264 struct IPowerEventListener powerListener;
265 void *p;
266 };
267
HdfSampleDriverInit(struct HdfDeviceObject * deviceObject)268 int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject)
269 {
270 static struct SampleDriverPmListener pmListener = { 0 };
271 int ret;
272 HDF_LOGI("%s::enter!", __func__);
273 if (deviceObject == NULL) {
274 HDF_LOGE("%s::ptr is null!", __func__);
275 return HDF_FAILURE;
276 }
277 HDF_LOGD("%s:Init success", __func__);
278 HdfDeviceObjectSetServInfo(deviceObject, SAMPLE_SERVICE);
279 pmListener.powerListener.DozeResume = HdfSampleDozeResume;
280 pmListener.powerListener.DozeSuspend = HdfSampleDozeSuspend;
281 pmListener.powerListener.Resume = HdfSampleResume;
282 pmListener.powerListener.Suspend = HdfSampleSuspend;
283
284 ret = HdfPmRegisterPowerListener(deviceObject, &pmListener.powerListener);
285 HDF_LOGI("%s:register power listener, ret = %d", __func__, ret);
286
287 return HDF_SUCCESS;
288 }
289
290 struct HdfDriverEntry g_sampleDriverEntry = {
291 .moduleVersion = 1,
292 .moduleName = "sample_driver",
293 .Bind = HdfSampleDriverBind,
294 .Init = HdfSampleDriverInit,
295 .Release = HdfSampleDriverRelease,
296 };
297
298 HDF_INIT(g_sampleDriverEntry);
299
300