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_hid_adapter.h"
10 #include <securec.h>
11 #include "event_hub.h"
12 #include "hdf_device_desc.h"
13 #include "hdf_log.h"
14 #include "osal_mem.h"
15 #include "osal_timer.h"
16
17 #ifdef CONFIG_DFX_ZEROHUNG
18 #include <dfx/hung_wp_screen.h>
19 #endif
20
21 #define TIMER_INTERVAL 500
22 #define REPEAT_VALUE 2
23 #define MEMCPY_CHECK_RETURN(ret) do { \
24 if ((ret) != 0) { \
25 HDF_LOGE("%s: memcpy failed, line %d", __func__, __LINE__); \
26 return; \
27 } \
28 } while (0)
29
30 InputDevice *cachedHid[MAX_INPUT_DEV_NUM];
31 HidInfo *g_cachedInfo[MAX_INPUT_DEV_NUM];
32
33 uint32_t g_kbdcode = 0;
34 OsalTimer g_timer;
35
HaveHidCache(void)36 static bool HaveHidCache(void)
37 {
38 if (cachedHid[0] == NULL) {
39 return false;
40 }
41 return true;
42 }
43
LoadCachedHid(void)44 static void LoadCachedHid(void)
45 {
46 int32_t i = 0;
47 int32_t ret;
48 if (!HaveHidCache()) {
49 HDF_LOGI("%s: exit", __func__);
50 return;
51 }
52 while (i < MAX_INPUT_DEV_NUM && cachedHid[i] != NULL) {
53 ret = RegisterInputDevice(cachedHid[i]);
54 if (ret != HDF_SUCCESS) {
55 HDF_LOGE("%s: add %s failed", __func__, cachedHid[i]->devName);
56 }
57 cachedHid[i] = NULL;
58 i++;
59 }
60 }
61
cachedPosId(void)62 static int cachedPosId(void)
63 {
64 int32_t id = 0;
65 while (id < MAX_INPUT_DEV_NUM) {
66 if (g_cachedInfo[id] == NULL) {
67 return id;
68 }
69 id++;
70 }
71 return HDF_FAILURE;
72 }
73
SendInfoToHdf(HidInfo * info)74 void SendInfoToHdf(HidInfo *info)
75 {
76 int ret;
77 int32_t id = cachedPosId();
78 if (id == HDF_FAILURE) {
79 HDF_LOGE("%s: cached hid info failed", __func__);
80 return;
81 }
82 g_cachedInfo[id] = (HidInfo *)OsalMemAlloc(sizeof(HidInfo));
83 if (g_cachedInfo[id] == NULL) {
84 HDF_LOGE("%s: malloc failed", __func__);
85 return;
86 }
87 ret = memcpy_s(g_cachedInfo[id], sizeof(HidInfo), info, sizeof(HidInfo));
88 if (ret != 0) {
89 HDF_LOGE("%s: memcpy failed", __func__);
90 OsalMemFree(g_cachedInfo[id]);
91 g_cachedInfo[id] = NULL;
92 return;
93 }
94 }
95
FreeCachedInfo(void)96 static void FreeCachedInfo(void)
97 {
98 int32_t id = 0;
99 while (id < MAX_INPUT_DEV_NUM) {
100 if (g_cachedInfo[id] != NULL) {
101 OsalMemFree(g_cachedInfo[id]);
102 g_cachedInfo[id] = NULL;
103 }
104 id++;
105 }
106 }
107
SetInputDevAbsAttr(InputDevice * inputDev,const HidInfo * info)108 static int32_t SetInputDevAbsAttr(InputDevice *inputDev, const HidInfo *info)
109 {
110 int32_t ret;
111 int i;
112 for (i = 0; i < BITS_TO_LONG(ABS_CNT); i++) {
113 if (inputDev->abilitySet.absCode[i] != 0) {
114 ret = memcpy_s(inputDev->attrSet.axisInfo, sizeof(AbsAttr) * ABS_CNT,
115 info->axisInfo, sizeof(AbsAttr) * ABS_CNT);
116 return ret;
117 }
118 }
119 return HDF_SUCCESS;
120 }
121
GetInfoFromCache(InputDevice * inputDev,const HidInfo * info)122 static void GetInfoFromCache(InputDevice *inputDev, const HidInfo *info)
123 {
124 uint32_t len;
125 int32_t ret;
126
127 len = sizeof(unsigned long);
128 ret = memcpy_s(inputDev->abilitySet.devProp, len * BITS_TO_LONG(INPUT_PROP_CNT),
129 info->devProp, len * BITS_TO_LONG(INPUT_PROP_CNT));
130 MEMCPY_CHECK_RETURN(ret);
131 ret = memcpy_s(inputDev->abilitySet.eventType, len * BITS_TO_LONG(EV_CNT),
132 info->eventType, len * BITS_TO_LONG(EV_CNT));
133 MEMCPY_CHECK_RETURN(ret);
134 ret = memcpy_s(inputDev->abilitySet.absCode, len * BITS_TO_LONG(ABS_CNT),
135 info->absCode, len * BITS_TO_LONG(ABS_CNT));
136 MEMCPY_CHECK_RETURN(ret);
137 ret = memcpy_s(inputDev->abilitySet.relCode, len * BITS_TO_LONG(REL_CNT),
138 info->relCode, len * BITS_TO_LONG(REL_CNT));
139 MEMCPY_CHECK_RETURN(ret);
140 ret = memcpy_s(inputDev->abilitySet.keyCode, len * BITS_TO_LONG(KEY_CNT),
141 info->keyCode, len * BITS_TO_LONG(KEY_CNT));
142 MEMCPY_CHECK_RETURN(ret);
143 ret = memcpy_s(inputDev->abilitySet.ledCode, len * BITS_TO_LONG(LED_CNT),
144 info->ledCode, len * BITS_TO_LONG(LED_CNT));
145 MEMCPY_CHECK_RETURN(ret);
146 ret = memcpy_s(inputDev->abilitySet.miscCode, len * BITS_TO_LONG(MSC_CNT),
147 info->miscCode, len * BITS_TO_LONG(MSC_CNT));
148 MEMCPY_CHECK_RETURN(ret);
149 ret = memcpy_s(inputDev->abilitySet.soundCode, len * BITS_TO_LONG(SND_CNT),
150 info->soundCode, len * BITS_TO_LONG(SND_CNT));
151 MEMCPY_CHECK_RETURN(ret);
152 ret = memcpy_s(inputDev->abilitySet.forceCode, len * BITS_TO_LONG(FF_CNT),
153 info->forceCode, len * BITS_TO_LONG(FF_CNT));
154 MEMCPY_CHECK_RETURN(ret);
155 ret = memcpy_s(inputDev->abilitySet.switchCode, len * BITS_TO_LONG(SW_CNT),
156 info->switchCode, len * BITS_TO_LONG(SW_CNT));
157 MEMCPY_CHECK_RETURN(ret);
158 ret = SetInputDevAbsAttr(inputDev, info);
159 MEMCPY_CHECK_RETURN(ret);
160 inputDev->attrSet.id.busType = info->bustype;
161 inputDev->attrSet.id.vendor = info->vendor;
162 inputDev->attrSet.id.product = info->product;
163 inputDev->attrSet.id.version = info->version;
164 }
165
SetInputDevAbility(InputDevice * inputDev)166 static void SetInputDevAbility(InputDevice *inputDev)
167 {
168 HidInfo *info = NULL;
169 int32_t id = 0;
170
171 while (id < MAX_INPUT_DEV_NUM) {
172 if (g_cachedInfo[id] != NULL && !strcmp(inputDev->devName, g_cachedInfo[id]->devName)) {
173 info = g_cachedInfo[id];
174 break;
175 }
176 id++;
177 }
178 if (id == MAX_INPUT_DEV_NUM || info == NULL) {
179 HDF_LOGE("%s: match cached info failed", __func__);
180 return;
181 }
182
183 GetInfoFromCache(inputDev, info);
184 FreeCachedInfo();
185 }
186
HidConstructInputDev(HidInfo * info)187 static InputDevice* HidConstructInputDev(HidInfo *info)
188 {
189 InputDevice *inputDev = (InputDevice *)OsalMemAlloc(sizeof(InputDevice));
190 if (inputDev == NULL) {
191 HDF_LOGE("%s: instance input device failed", __func__);
192 return NULL;
193 }
194 (void)memset_s(inputDev, sizeof(InputDevice), 0, sizeof(InputDevice));
195
196 inputDev->devType = info->devType;
197 inputDev->devName = info->devName;
198 SetInputDevAbility(inputDev);
199
200 return inputDev;
201 }
202
DoRegisterInputDev(InputDevice * inputDev)203 static void DoRegisterInputDev(InputDevice* inputDev)
204 {
205 int32_t ret;
206 ret = RegisterInputDevice(inputDev);
207 if (ret != HDF_SUCCESS) {
208 OsalMemFree(inputDev);
209 return;
210 }
211 }
212
CacheHid(InputDevice * inputDev)213 static void CacheHid(InputDevice* inputDev)
214 {
215 int32_t i = 0;
216 while ((i < MAX_INPUT_DEV_NUM) && (cachedHid[i] != NULL)) {
217 i++;
218 }
219 if (i < MAX_INPUT_DEV_NUM) {
220 cachedHid[i] = inputDev;
221 return;
222 } else {
223 HDF_LOGE("%s: cached hid device failed", __func__);
224 }
225 }
226
InputDriverLoaded(void)227 static bool InputDriverLoaded(void)
228 {
229 InputManager* g_inputManager = GetInputManager();
230 if ((g_inputManager != NULL) && (g_inputManager->initialized != false)) {
231 return true;
232 }
233 return false;
234 }
235
HidRegisterHdfInputDev(HidInfo * info)236 void* HidRegisterHdfInputDev(HidInfo *info)
237 {
238 InputDevice* inputDev = HidConstructInputDev(info);
239 if (inputDev == NULL) {
240 HDF_LOGE("%s: hid construct input Dev failed", __func__);
241 return NULL;
242 }
243
244 if (InputDriverLoaded()) {
245 DoRegisterInputDev(inputDev);
246 } else {
247 CacheHid(inputDev);
248 }
249 return inputDev;
250 }
251
HidUnregisterHdfInputDev(const void * inputDev)252 void HidUnregisterHdfInputDev(const void *inputDev)
253 {
254 if (inputDev == NULL) {
255 HDF_LOGE("%s: inputDev is null", __func__);
256 }
257 UnregisterInputDevice((InputDevice *)inputDev);
258 }
259
TimerFunc(uintptr_t arg)260 static void TimerFunc(uintptr_t arg)
261 {
262 InputDevice *device = (InputDevice *)arg;
263 PushOnePackage(device, EV_KEY, g_kbdcode, REPEAT_VALUE);
264 PushOnePackage(device, 0, 0, SYN_CONFIG);
265 }
266
RepateEvent(const InputDevice * device)267 static void RepateEvent(const InputDevice *device)
268 {
269 int32_t ret;
270 static int32_t flag = 0;
271 if (flag == 1) {
272 (void)OsalTimerDelete(&g_timer);
273 }
274
275 ret = OsalTimerCreate(&g_timer, TIMER_INTERVAL, TimerFunc, (uintptr_t)device);
276 if (ret != HDF_SUCCESS) {
277 HDF_LOGE("%s: create timer failed, ret = %d", __func__, ret);
278 return;
279 }
280 ret = OsalTimerStartLoop(&g_timer);
281 if (ret != HDF_SUCCESS) {
282 HDF_LOGE("%s: start timer failed, ret = %d", __func__, ret);
283 return;
284 }
285 flag = 1;
286 }
287
HidReportEvent(const void * inputDev,uint32_t type,uint32_t code,int32_t value)288 void HidReportEvent(const void *inputDev, uint32_t type, uint32_t code, int32_t value)
289 {
290 #ifdef CONFIG_DFX_ZEROHUNG
291 if (type == EV_KEY && code == KEY_POWER)
292 hung_wp_screen_powerkey_ncb(value);
293 #endif
294 InputDevice *device = (InputDevice *)inputDev;
295 PushOnePackage(device, type, code, value);
296 if (type == EV_KEY && KEY_RESERVED < code && code < KEY_MAX && value == 0 && code == g_kbdcode) {
297 OsalTimerDelete(&g_timer);
298 g_kbdcode = 0;
299 }
300 if (type == EV_KEY && KEY_RESERVED < code && code < KEY_MAX && value == 1 &&
301 device->devType == INDEV_TYPE_KEYBOARD) {
302 g_kbdcode = code;
303 RepateEvent(device);
304 }
305 }
306
HdfHIDDriverInit(struct HdfDeviceObject * device)307 static int32_t HdfHIDDriverInit(struct HdfDeviceObject *device)
308 {
309 (void)device;
310 static bool cachedHidRegistered = false;
311 if (!cachedHidRegistered) {
312 cachedHidRegistered = true;
313 LoadCachedHid();
314 }
315 return HDF_SUCCESS;
316 }
317
HidGetDevType(InputDevice * inputDev,struct HdfSBuf * reply)318 static int32_t HidGetDevType(InputDevice *inputDev, struct HdfSBuf *reply)
319 {
320 uint32_t devType = inputDev->devType;
321 HDF_LOGI("%s: enter, devType is %u", __func__, devType);
322 bool ret = HdfSbufWriteUint32(reply, devType);
323 if (!ret) {
324 HDF_LOGE("%s: HdfSbufWriteUint32 failed", __func__);
325 return HDF_FAILURE;
326 }
327 return HDF_SUCCESS;
328 }
329
HidGetDeviceStrInfo(InputDevice * inputDev,int32_t cmd,struct HdfSBuf * reply)330 static int32_t HidGetDeviceStrInfo(InputDevice *inputDev, int32_t cmd, struct HdfSBuf *reply)
331 {
332 const char *info = NULL;
333 if (inputDev == NULL) {
334 HDF_LOGE("%s: parameter invalid", __func__);
335 return HDF_ERR_INVALID_PARAM;
336 }
337
338 switch (cmd) {
339 case GET_CHIP_NAME:
340 info = "null";
341 break;
342 case GET_VENDOR_NAME:
343 info = "null";
344 break;
345 case GET_CHIP_INFO:
346 info = "null";
347 break;
348 default:
349 info = NULL;
350 break;
351 }
352
353 bool ret = HdfSbufWriteString(reply, info);
354 if (!ret) {
355 HDF_LOGE("%s: HdfSbufWriteUint32 failed", __func__);
356 return HDF_FAILURE;
357 }
358 HDF_LOGI("%s: cmd is %d, the info is %s", __func__, cmd, info);
359 return HDF_SUCCESS;
360 }
361
HidGetDeviceAttr(InputDevice * inputDev,struct HdfSBuf * reply)362 static int32_t HidGetDeviceAttr(InputDevice *inputDev, struct HdfSBuf *reply)
363 {
364 int32_t ret;
365 if (inputDev == NULL) {
366 return HDF_FAILURE;
367 }
368
369 ret = strncpy_s(inputDev->attrSet.devName, DEV_NAME_LEN, inputDev->devName, strlen(inputDev->devName));
370 if (ret != 0) {
371 HDF_LOGE("%s: copy name from inputDev failed, ret = %d", __func__, ret);
372 return HDF_FAILURE;
373 }
374
375 if (!HdfSbufWriteBuffer(reply, &inputDev->attrSet, sizeof(DevAttr))) {
376 HDF_LOGE("%s: sbuf write dev attr failed", __func__);
377 return HDF_FAILURE;
378 }
379
380 return HDF_SUCCESS;
381 }
382
HidGetDeviceAbility(InputDevice * inputDev,struct HdfSBuf * reply)383 static int32_t HidGetDeviceAbility(InputDevice *inputDev, struct HdfSBuf *reply)
384 {
385 if (inputDev == NULL) {
386 return HDF_FAILURE;
387 }
388
389 if (!HdfSbufWriteBuffer(reply, &inputDev->abilitySet, sizeof(DevAbility))) {
390 HDF_LOGE("%s: sbuf write dev ability failed", __func__);
391 return HDF_FAILURE;
392 }
393
394 return HDF_SUCCESS;
395 }
396
HdfHIDDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)397 static int32_t HdfHIDDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
398 {
399 (void)cmd;
400 int32_t ret;
401 InputDevice *inputDev = NULL;
402 if (client == NULL || data == NULL || reply == NULL) {
403 HDF_LOGE("%s: param is null", __func__);
404 return HDF_FAILURE;
405 }
406
407 inputDev = (InputDevice *)client->device->priv;
408 if (inputDev == NULL) {
409 HDF_LOGE("%s: inputDev is null", __func__);
410 return HDF_FAILURE;
411 }
412
413 HDF_LOGI("%s: cmd = %d", __func__, cmd);
414 switch (cmd) {
415 case GET_DEV_TYPE:
416 ret = HidGetDevType(inputDev, reply);
417 break;
418 case GET_CHIP_NAME:
419 case GET_VENDOR_NAME:
420 case GET_CHIP_INFO:
421 ret = HidGetDeviceStrInfo(inputDev, cmd, reply);
422 break;
423 case GET_DEV_ATTR:
424 ret = HidGetDeviceAttr(inputDev, reply);
425 break;
426 case GET_DEV_ABILITY:
427 ret = HidGetDeviceAbility(inputDev, reply);
428 break;
429 default:
430 ret = HDF_SUCCESS;
431 HDF_LOGE("%s: cmd unknown, cmd = 0x%x", __func__, cmd);
432 break;
433 }
434 return ret;
435 }
436
HdfHIDDriverBind(struct HdfDeviceObject * device)437 static int32_t HdfHIDDriverBind(struct HdfDeviceObject *device)
438 {
439 if (device == NULL) {
440 return HDF_ERR_INVALID_PARAM;
441 }
442 static struct IDeviceIoService hidService = {
443 .Dispatch = HdfHIDDispatch,
444 };
445 device->service = &hidService;
446 return HDF_SUCCESS;
447 }
448
HdfHIDDriverRelease(struct HdfDeviceObject * device)449 static void HdfHIDDriverRelease(struct HdfDeviceObject *device)
450 {
451 FreeCachedInfo();
452 if (device == NULL) {
453 HDF_LOGE("%s: device is null", __func__);
454 return;
455 }
456 }
457
458 struct HdfDriverEntry g_hdfHIDEntry = {
459 .moduleVersion = 1,
460 .moduleName = "HDF_HID",
461 .Bind = HdfHIDDriverBind,
462 .Init = HdfHIDDriverInit,
463 .Release = HdfHIDDriverRelease,
464 };
465
466 HDF_INIT(g_hdfHIDEntry);
467