1 /******************************************************************************
2 *
3 * Copyright 2009-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /*******************************************************************************
20 *
21 * Filename: btif_hh.c
22 *
23 * Description: HID Host Profile Bluetooth Interface
24 *
25 *
26 ******************************************************************************/
27
28 #define LOG_TAG "bt_btif_hh"
29
30 #include "btif_hh.h"
31
32 #include <base/logging.h>
33 #include <errno.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
38
39 #include "bt_common.h"
40 #include "bta_api.h"
41 #include "btif_common.h"
42 #include "btif_storage.h"
43 #include "btif_util.h"
44 #include "l2c_api.h"
45 #include "osi/include/log.h"
46 #include "osi/include/osi.h"
47
48 #define BTIF_HH_APP_ID_MI 0x01
49 #define BTIF_HH_APP_ID_KB 0x02
50
51 #define COD_HID_KEYBOARD 0x0540
52 #define COD_HID_POINTING 0x0580
53 #define COD_HID_COMBO 0x05C0
54
55 #define KEYSTATE_FILEPATH \
56 "/data/misc/bluedroid/bt_hh_ks" // keep this in sync with HID host jni
57
58 #define HID_REPORT_CAPSLOCK 0x39
59 #define HID_REPORT_NUMLOCK 0x53
60 #define HID_REPORT_SCROLLLOCK 0x47
61
62 // For Apple Magic Mouse
63 #define MAGICMOUSE_VENDOR_ID 0x05ac
64 #define MAGICMOUSE_PRODUCT_ID 0x030d
65
66 #define LOGITECH_KB_MX5500_VENDOR_ID 0x046D
67 #define LOGITECH_KB_MX5500_PRODUCT_ID 0xB30B
68
69 extern const int BT_UID;
70 extern const int BT_GID;
71 static int btif_hh_keylockstates = 0; // The current key state of each key
72
73 #define BTIF_HH_ID_1 0
74 #define BTIF_HH_DEV_DISCONNECTED 3
75
76 #define BTIF_TIMEOUT_VUP_MS (3 * 1000)
77
78 #ifndef BTUI_HH_SECURITY
79 #define BTUI_HH_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
80 #endif
81
82 #ifndef BTUI_HH_MOUSE_SECURITY
83 #define BTUI_HH_MOUSE_SECURITY (BTA_SEC_NONE)
84 #endif
85
86 /* HH request events */
87 typedef enum {
88 BTIF_HH_CONNECT_REQ_EVT = 0,
89 BTIF_HH_DISCONNECT_REQ_EVT,
90 BTIF_HH_VUP_REQ_EVT
91 } btif_hh_req_evt_t;
92
93 /*******************************************************************************
94 * Constants & Macros
95 ******************************************************************************/
96 #define BTIF_HH_SERVICES (BTA_HID_SERVICE_MASK)
97
98 /*******************************************************************************
99 * Local type definitions
100 ******************************************************************************/
101
102 typedef struct hid_kb_list {
103 uint16_t product_id;
104 uint16_t version_id;
105 const char* kb_name;
106 } tHID_KB_LIST;
107
108 /*******************************************************************************
109 * Static variables
110 ******************************************************************************/
111 btif_hh_cb_t btif_hh_cb;
112
113 static bthh_callbacks_t* bt_hh_callbacks = NULL;
114
115 /* List of HID keyboards for which the NUMLOCK state needs to be
116 * turned ON by default. Add devices to this list to apply the
117 * NUMLOCK state toggle on fpr first connect.*/
118 static tHID_KB_LIST hid_kb_numlock_on_list[] = {{LOGITECH_KB_MX5500_PRODUCT_ID,
119 LOGITECH_KB_MX5500_VENDOR_ID,
120 "Logitech MX5500 Keyboard"}};
121
122 #define CHECK_BTHH_INIT() \
123 do { \
124 if (bt_hh_callbacks == NULL) { \
125 BTIF_TRACE_WARNING("BTHH: %s: BTHH not initialized", __func__); \
126 return BT_STATUS_NOT_READY; \
127 } \
128 } while (0)
129
130 /*******************************************************************************
131 * Static functions
132 ******************************************************************************/
133
134 /*******************************************************************************
135 * Externs
136 ******************************************************************************/
137 extern void bta_hh_co_destroy(int fd);
138 extern void bta_hh_co_write(int fd, uint8_t* rpt, uint16_t len);
139 extern bt_status_t btif_dm_remove_bond(const RawAddress* bd_addr);
140 extern void bta_hh_co_send_hid_info(btif_hh_device_t* p_dev,
141 const char* dev_name, uint16_t vendor_id,
142 uint16_t product_id, uint16_t version,
143 uint8_t ctry_code, int dscp_len,
144 uint8_t* p_dscp);
145 extern bool check_cod(const RawAddress* remote_bdaddr, uint32_t cod);
146 extern void btif_dm_cb_remove_bond(const RawAddress* bd_addr);
147 extern bool check_cod_hid(const RawAddress* remote_bdaddr);
148 extern int scru_ascii_2_hex(char* p_ascii, int len, uint8_t* p_hex);
149 extern void btif_dm_hh_open_failed(RawAddress* bdaddr);
150 extern void btif_hd_service_registration();
151
152 /*****************************************************************************
153 * Local Function prototypes
154 ****************************************************************************/
155 static void set_keylockstate(int keymask, bool isSet);
156 static void toggle_os_keylockstates(int fd, int changedkeystates);
157 static void sync_lockstate_on_connect(btif_hh_device_t* p_dev);
158 // static void hh_update_keyboard_lockstates(btif_hh_device_t *p_dev);
159 void btif_hh_timer_timeout(void* data);
160 void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data);
161
162 /*******************************************************************************
163 * Functions
164 ******************************************************************************/
165
get_keylockstates()166 static int get_keylockstates() { return btif_hh_keylockstates; }
167
set_keylockstate(int keymask,bool isSet)168 static void set_keylockstate(int keymask, bool isSet) {
169 if (isSet) btif_hh_keylockstates |= keymask;
170 }
171
172 /*******************************************************************************
173 *
174 * Function toggle_os_keylockstates
175 *
176 * Description Function to toggle the keyboard lock states managed by the
177 linux.
178 * This function is used in by two call paths
179 * (1) if the lock state change occurred from an onscreen
180 keyboard,
181 * this function is called to update the lock state maintained
182 for the HID keyboard(s)
183 * (2) if a HID keyboard is disconnected and reconnected,
184 * this function is called to update the lock state maintained
185 for the HID keyboard(s)
186 * Returns void
187 ******************************************************************************/
188
toggle_os_keylockstates(int fd,int changedlockstates)189 static void toggle_os_keylockstates(int fd, int changedlockstates) {
190 BTIF_TRACE_EVENT("%s: fd = %d, changedlockstates = 0x%x", __func__, fd,
191 changedlockstates);
192 uint8_t hidreport[9];
193 int reportIndex;
194 memset(hidreport, 0, 9);
195 hidreport[0] = 1;
196 reportIndex = 4;
197
198 if (changedlockstates & BTIF_HH_KEYSTATE_MASK_CAPSLOCK) {
199 BTIF_TRACE_DEBUG("%s Setting CAPSLOCK", __func__);
200 hidreport[reportIndex++] = (uint8_t)HID_REPORT_CAPSLOCK;
201 }
202
203 if (changedlockstates & BTIF_HH_KEYSTATE_MASK_NUMLOCK) {
204 BTIF_TRACE_DEBUG("%s Setting NUMLOCK", __func__);
205 hidreport[reportIndex++] = (uint8_t)HID_REPORT_NUMLOCK;
206 }
207
208 if (changedlockstates & BTIF_HH_KEYSTATE_MASK_SCROLLLOCK) {
209 BTIF_TRACE_DEBUG("%s Setting SCROLLLOCK", __func__);
210 hidreport[reportIndex++] = (uint8_t)HID_REPORT_SCROLLLOCK;
211 }
212
213 BTIF_TRACE_DEBUG(
214 "Writing hidreport #1 to os: "
215 "%s: %x %x %x",
216 __func__, hidreport[0], hidreport[1], hidreport[2]);
217 BTIF_TRACE_DEBUG("%s: %x %x %x", __func__, hidreport[3], hidreport[4],
218 hidreport[5]);
219 BTIF_TRACE_DEBUG("%s: %x %x %x", __func__, hidreport[6], hidreport[7],
220 hidreport[8]);
221 bta_hh_co_write(fd, hidreport, sizeof(hidreport));
222 usleep(200000);
223 memset(hidreport, 0, 9);
224 hidreport[0] = 1;
225 BTIF_TRACE_DEBUG(
226 "Writing hidreport #2 to os: "
227 "%s: %x %x %x",
228 __func__, hidreport[0], hidreport[1], hidreport[2]);
229 BTIF_TRACE_DEBUG("%s: %x %x %x", __func__, hidreport[3], hidreport[4],
230 hidreport[5]);
231 BTIF_TRACE_DEBUG("%s: %x %x %x ", __func__, hidreport[6], hidreport[7],
232 hidreport[8]);
233 bta_hh_co_write(fd, hidreport, sizeof(hidreport));
234 }
235
236 /*******************************************************************************
237 *
238 * Function create_pbuf
239 *
240 * Description Helper function to create p_buf for send_data or set_report
241 *
242 ******************************************************************************/
create_pbuf(uint16_t len,uint8_t * data)243 static BT_HDR* create_pbuf(uint16_t len, uint8_t* data) {
244 BT_HDR* p_buf = (BT_HDR*)osi_malloc(len + BTA_HH_MIN_OFFSET + sizeof(BT_HDR));
245 uint8_t* pbuf_data;
246
247 p_buf->len = len;
248 p_buf->offset = BTA_HH_MIN_OFFSET;
249
250 pbuf_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
251 memcpy(pbuf_data, data, len);
252
253 return p_buf;
254 }
255
256 /*******************************************************************************
257 *
258 * Function update_keyboard_lockstates
259 *
260 * Description Sends a report to the keyboard to set the lock states of
261 * keys.
262 *
263 ******************************************************************************/
update_keyboard_lockstates(btif_hh_device_t * p_dev)264 static void update_keyboard_lockstates(btif_hh_device_t* p_dev) {
265 uint8_t len = 2; /* reportid + 1 byte report*/
266 BT_HDR* p_buf;
267 uint8_t data[] = {0x01, /* report id */
268 static_cast<uint8_t>(btif_hh_keylockstates)}; /* keystate */
269
270 /* Set report for other keyboards */
271 BTIF_TRACE_EVENT("%s: setting report on dev_handle %d to 0x%x", __func__,
272 p_dev->dev_handle, btif_hh_keylockstates);
273
274 /* Get SetReport buffer */
275 p_buf = create_pbuf(len, data);
276 if (p_buf != NULL) {
277 p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
278 BTA_HhSendData(p_dev->dev_handle, p_dev->bd_addr, p_buf);
279 }
280 }
281
282 /*******************************************************************************
283 *
284 * Function sync_lockstate_on_connect
285 *
286 * Description Function to update the keyboard lock states managed by the
287 * OS when a HID keyboard is connected or disconnected and
288 * reconnected
289 *
290 * Returns void
291 ******************************************************************************/
sync_lockstate_on_connect(btif_hh_device_t * p_dev)292 static void sync_lockstate_on_connect(btif_hh_device_t* p_dev) {
293 int keylockstates;
294
295 BTIF_TRACE_EVENT(
296 "%s: Syncing keyboard lock states after "
297 "reconnect...",
298 __func__);
299 /*If the device is connected, update keyboard state */
300 update_keyboard_lockstates(p_dev);
301
302 /*Check if the lockstate of caps,scroll,num is set.
303 If so, send a report to the kernel
304 so the lockstate is in sync */
305 keylockstates = get_keylockstates();
306 if (keylockstates) {
307 BTIF_TRACE_DEBUG(
308 "%s: Sending hid report to kernel "
309 "indicating lock key state 0x%x",
310 __func__, keylockstates);
311 usleep(200000);
312 toggle_os_keylockstates(p_dev->fd, keylockstates);
313 } else {
314 BTIF_TRACE_DEBUG(
315 "%s: NOT sending hid report to kernel "
316 "indicating lock key state 0x%x",
317 __func__, keylockstates);
318 }
319 }
320
321 /*******************************************************************************
322 *
323 * Function btif_hh_find_connected_dev_by_handle
324 *
325 * Description Return the connected device pointer of the specified device
326 * handle
327 *
328 * Returns Device entry pointer in the device table
329 ******************************************************************************/
btif_hh_find_connected_dev_by_handle(uint8_t handle)330 btif_hh_device_t* btif_hh_find_connected_dev_by_handle(uint8_t handle) {
331 uint32_t i;
332 for (i = 0; i < BTIF_HH_MAX_HID; i++) {
333 if (btif_hh_cb.devices[i].dev_status == BTHH_CONN_STATE_CONNECTED &&
334 btif_hh_cb.devices[i].dev_handle == handle) {
335 return &btif_hh_cb.devices[i];
336 }
337 }
338 return NULL;
339 }
340
341 /*******************************************************************************
342 *
343 * Function btif_hh_find_dev_by_bda
344 *
345 * Description Return the device pointer of the specified RawAddress.
346 *
347 * Returns Device entry pointer in the device table
348 ******************************************************************************/
btif_hh_find_dev_by_bda(const RawAddress & bd_addr)349 static btif_hh_device_t* btif_hh_find_dev_by_bda(const RawAddress& bd_addr) {
350 uint32_t i;
351 for (i = 0; i < BTIF_HH_MAX_HID; i++) {
352 if (btif_hh_cb.devices[i].dev_status != BTHH_CONN_STATE_UNKNOWN &&
353 btif_hh_cb.devices[i].bd_addr == bd_addr) {
354 return &btif_hh_cb.devices[i];
355 }
356 }
357 return NULL;
358 }
359
360 /*******************************************************************************
361 *
362 * Function btif_hh_find_connected_dev_by_bda
363 *
364 * Description Return the connected device pointer of the specified
365 * RawAddress.
366 *
367 * Returns Device entry pointer in the device table
368 ******************************************************************************/
btif_hh_find_connected_dev_by_bda(const RawAddress & bd_addr)369 static btif_hh_device_t* btif_hh_find_connected_dev_by_bda(
370 const RawAddress& bd_addr) {
371 uint32_t i;
372 for (i = 0; i < BTIF_HH_MAX_HID; i++) {
373 if (btif_hh_cb.devices[i].dev_status == BTHH_CONN_STATE_CONNECTED &&
374 btif_hh_cb.devices[i].bd_addr == bd_addr) {
375 return &btif_hh_cb.devices[i];
376 }
377 }
378 return NULL;
379 }
380
381 /*******************************************************************************
382 *
383 * Function btif_hh_stop_vup_timer
384 *
385 * Description stop vitual unplug timer
386 *
387 * Returns void
388 ******************************************************************************/
btif_hh_stop_vup_timer(RawAddress * bd_addr)389 void btif_hh_stop_vup_timer(RawAddress* bd_addr) {
390 btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
391
392 if (p_dev != NULL) {
393 BTIF_TRACE_DEBUG("stop VUP timer");
394 alarm_free(p_dev->vup_timer);
395 p_dev->vup_timer = NULL;
396 }
397 }
398 /*******************************************************************************
399 *
400 * Function btif_hh_start_vup_timer
401 *
402 * Description start virtual unplug timer
403 *
404 * Returns void
405 ******************************************************************************/
btif_hh_start_vup_timer(const RawAddress * bd_addr)406 void btif_hh_start_vup_timer(const RawAddress* bd_addr) {
407 BTIF_TRACE_DEBUG("%s", __func__);
408
409 btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
410 CHECK(p_dev != NULL);
411
412 alarm_free(p_dev->vup_timer);
413 p_dev->vup_timer = alarm_new("btif_hh.vup_timer");
414 alarm_set_on_mloop(p_dev->vup_timer, BTIF_TIMEOUT_VUP_MS,
415 btif_hh_timer_timeout, p_dev);
416 }
417
418 /*******************************************************************************
419 *
420 * Function btif_hh_add_added_dev
421 *
422 * Description Add a new device to the added device list.
423 *
424 * Returns true if add successfully, otherwise false.
425 ******************************************************************************/
btif_hh_add_added_dev(const RawAddress & bda,tBTA_HH_ATTR_MASK attr_mask)426 bool btif_hh_add_added_dev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask) {
427 int i;
428 for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
429 if (btif_hh_cb.added_devices[i].bd_addr == bda) {
430 LOG(WARNING) << " Device " << bda << " already added";
431 return false;
432 }
433 }
434 for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
435 if (btif_hh_cb.added_devices[i].bd_addr.IsEmpty()) {
436 LOG(WARNING) << " Added device " << bda;
437 btif_hh_cb.added_devices[i].bd_addr = bda;
438 btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE;
439 btif_hh_cb.added_devices[i].attr_mask = attr_mask;
440 return true;
441 }
442 }
443
444 BTIF_TRACE_WARNING("%s: Error, out of space to add device", __func__);
445 return false;
446 }
447
448 /*******************************************************************************
449 **
450 ** Function btif_hh_remove_device
451 **
452 ** Description Remove an added device from the stack.
453 **
454 ** Returns void
455 ******************************************************************************/
btif_hh_remove_device(RawAddress bd_addr)456 void btif_hh_remove_device(RawAddress bd_addr) {
457 int i;
458 btif_hh_device_t* p_dev;
459 btif_hh_added_device_t* p_added_dev;
460
461 LOG(INFO) << __func__ << ": bda = " << bd_addr;
462
463 for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
464 p_added_dev = &btif_hh_cb.added_devices[i];
465 if (p_added_dev->bd_addr == bd_addr) {
466 BTA_HhRemoveDev(p_added_dev->dev_handle);
467 btif_storage_remove_hid_info(&(p_added_dev->bd_addr));
468 memset(&(p_added_dev->bd_addr), 0, 6);
469 p_added_dev->dev_handle = BTA_HH_INVALID_HANDLE;
470 break;
471 }
472 }
473
474 p_dev = btif_hh_find_dev_by_bda(bd_addr);
475 if (p_dev == NULL) {
476 LOG(WARNING) << " Oops, can't find device " << bd_addr;
477 return;
478 }
479
480 /* need to notify up-layer device is disconnected to avoid state out of sync
481 * with up-layer */
482 HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr),
483 BTHH_CONN_STATE_DISCONNECTED);
484
485 p_dev->dev_status = BTHH_CONN_STATE_UNKNOWN;
486 p_dev->dev_handle = BTA_HH_INVALID_HANDLE;
487 p_dev->ready_for_data = false;
488
489 if (btif_hh_cb.device_num > 0) {
490 btif_hh_cb.device_num--;
491 } else {
492 BTIF_TRACE_WARNING("%s: device_num = 0", __func__);
493 }
494
495 p_dev->hh_keep_polling = 0;
496 p_dev->hh_poll_thread_id = -1;
497 BTIF_TRACE_DEBUG("%s: uhid fd = %d", __func__, p_dev->fd);
498 if (p_dev->fd >= 0) {
499 bta_hh_co_destroy(p_dev->fd);
500 p_dev->fd = -1;
501 }
502 }
503
btif_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO * dest,tBTA_HH_DEV_DSCP_INFO * src)504 bool btif_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO* dest,
505 tBTA_HH_DEV_DSCP_INFO* src) {
506 memset(dest, 0, sizeof(tBTA_HH_DEV_DSCP_INFO));
507 dest->descriptor.dl_len = 0;
508 if (src->descriptor.dl_len > 0) {
509 dest->descriptor.dsc_list = (uint8_t*)osi_malloc(src->descriptor.dl_len);
510 }
511 memcpy(dest->descriptor.dsc_list, src->descriptor.dsc_list,
512 src->descriptor.dl_len);
513 dest->descriptor.dl_len = src->descriptor.dl_len;
514 dest->vendor_id = src->vendor_id;
515 dest->product_id = src->product_id;
516 dest->version = src->version;
517 dest->ctry_code = src->ctry_code;
518 dest->ssr_max_latency = src->ssr_max_latency;
519 dest->ssr_min_tout = src->ssr_min_tout;
520 return true;
521 }
522
523 /*******************************************************************************
524 *
525 * Function btif_hh_virtual_unplug
526 *
527 * Description Virtual unplug initiated from the BTIF thread context
528 * Special handling for HID mouse-
529 *
530 * Returns void
531 *
532 ******************************************************************************/
533
btif_hh_virtual_unplug(const RawAddress * bd_addr)534 bt_status_t btif_hh_virtual_unplug(const RawAddress* bd_addr) {
535 BTIF_TRACE_DEBUG("%s", __func__);
536 btif_hh_device_t* p_dev;
537 p_dev = btif_hh_find_dev_by_bda(*bd_addr);
538 if ((p_dev != NULL) && (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED) &&
539 (p_dev->attr_mask & HID_VIRTUAL_CABLE)) {
540 BTIF_TRACE_DEBUG("%s Sending BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG", __func__);
541 /* start the timer */
542 btif_hh_start_vup_timer(bd_addr);
543 p_dev->local_vup = true;
544 BTA_HhSendCtrl(p_dev->dev_handle, BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG);
545 return BT_STATUS_SUCCESS;
546 } else {
547 BTIF_TRACE_ERROR("%s: Error, device %s not opened, status = %d", __func__,
548 bd_addr->ToString().c_str(), btif_hh_cb.status);
549 if ((btif_hh_cb.pending_conn_address == *bd_addr) &&
550 (btif_hh_cb.status == BTIF_HH_DEV_CONNECTING)) {
551 btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
552 btif_hh_cb.pending_conn_address = RawAddress::kEmpty;
553 }
554 return BT_STATUS_FAIL;
555 }
556 }
557
558 /*******************************************************************************
559 *
560 * Function btif_hh_connect
561 *
562 * Description connection initiated from the BTIF thread context
563 *
564 * Returns int status
565 *
566 ******************************************************************************/
567
btif_hh_connect(const RawAddress * bd_addr)568 bt_status_t btif_hh_connect(const RawAddress* bd_addr) {
569 btif_hh_added_device_t* added_dev = NULL;
570 CHECK_BTHH_INIT();
571 BTIF_TRACE_EVENT("BTHH: %s", __func__);
572 btif_hh_device_t* dev = btif_hh_find_dev_by_bda(*bd_addr);
573 if (!dev && btif_hh_cb.device_num >= BTIF_HH_MAX_HID) {
574 // No space for more HID device now.
575 BTIF_TRACE_WARNING(
576 "%s: Error, exceeded the maximum supported HID device number %d",
577 __func__, BTIF_HH_MAX_HID);
578 return BT_STATUS_FAIL;
579 }
580
581 for (int i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
582 if (btif_hh_cb.added_devices[i].bd_addr == *bd_addr) {
583 added_dev = &btif_hh_cb.added_devices[i];
584 LOG(WARNING) << __func__ << ": Device " << *bd_addr
585 << " already added, attr_mask = 0x" << std::hex
586 << added_dev->attr_mask;
587 }
588 }
589
590 if (added_dev != NULL) {
591 if (added_dev->dev_handle == BTA_HH_INVALID_HANDLE) {
592 // No space for more HID device now.
593 LOG(ERROR) << __func__ << ": Error, device " << *bd_addr
594 << " added but addition failed";
595 added_dev->bd_addr = RawAddress::kEmpty;
596 added_dev->dev_handle = BTA_HH_INVALID_HANDLE;
597 return BT_STATUS_FAIL;
598 }
599 }
600
601 /* Not checking the NORMALLY_Connectible flags from sdp record, and anyways
602 sending this
603 request from host, for subsequent user initiated connection. If the remote is
604 not in
605 pagescan mode, we will do 2 retries to connect before giving up */
606 tBTA_SEC sec_mask = BTUI_HH_SECURITY;
607 btif_hh_cb.status = BTIF_HH_DEV_CONNECTING;
608 btif_hh_cb.pending_conn_address = *bd_addr;
609 BTA_HhOpen(*bd_addr, BTA_HH_PROTO_RPT_MODE, sec_mask);
610
611 // TODO(jpawlowski); make cback accept const and remove tmp!
612 auto tmp = *bd_addr;
613 HAL_CBACK(bt_hh_callbacks, connection_state_cb, &tmp,
614 BTHH_CONN_STATE_CONNECTING);
615 return BT_STATUS_SUCCESS;
616 }
617
618 /*******************************************************************************
619 *
620 * Function btif_hh_disconnect
621 *
622 * Description disconnection initiated from the BTIF thread context
623 *
624 * Returns void
625 *
626 ******************************************************************************/
627
btif_hh_disconnect(RawAddress * bd_addr)628 void btif_hh_disconnect(RawAddress* bd_addr) {
629 btif_hh_device_t* p_dev;
630 p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
631 if (p_dev != NULL) {
632 BTA_HhClose(p_dev->dev_handle);
633 } else
634 BTIF_TRACE_DEBUG("%s-- Error: device not connected:", __func__);
635 }
636
637 /*******************************************************************************
638 *
639 * Function btif_btif_hh_setreport
640 *
641 * Description setreport initiated from the BTIF thread context
642 *
643 * Returns void
644 *
645 ******************************************************************************/
btif_hh_setreport(btif_hh_device_t * p_dev,bthh_report_type_t r_type,uint16_t size,uint8_t * report)646 void btif_hh_setreport(btif_hh_device_t* p_dev, bthh_report_type_t r_type,
647 uint16_t size, uint8_t* report) {
648 BT_HDR* p_buf = create_pbuf(size, report);
649 if (p_buf == NULL) {
650 APPL_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, size = %d",
651 __func__, size);
652 return;
653 }
654 BTA_HhSetReport(p_dev->dev_handle, r_type, p_buf);
655 }
656
657 /*******************************************************************************
658 *
659 * Function btif_hh_service_registration
660 *
661 * Description Registers or derigisters the hid host service
662 *
663 * Returns none
664 *
665 ******************************************************************************/
btif_hh_service_registration(bool enable)666 void btif_hh_service_registration(bool enable) {
667 BTIF_TRACE_API("%s", __func__);
668
669 BTIF_TRACE_API("enable = %d", enable);
670 if (bt_hh_callbacks == NULL) {
671 // The HID Host service was never initialized (it is either disabled or not
672 // available in this build). We should proceed directly to changing the HID
673 // Device service state (if needed).
674 if (!enable) {
675 btif_hd_service_registration();
676 }
677 } else if (enable) {
678 BTA_HhEnable(BTA_SEC_ENCRYPT, bte_hh_evt);
679 } else {
680 btif_hh_cb.service_dereg_active = TRUE;
681 BTA_HhDisable();
682 }
683 }
684
685 /*****************************************************************************
686 * Section name (Group of functions)
687 ****************************************************************************/
688
689 /*****************************************************************************
690 *
691 * btif hh api functions (no context switch)
692 *
693 ****************************************************************************/
694
695 /*******************************************************************************
696 *
697 * Function btif_hh_upstreams_evt
698 *
699 * Description Executes HH UPSTREAMS events in btif context
700 *
701 * Returns void
702 *
703 ******************************************************************************/
btif_hh_upstreams_evt(uint16_t event,char * p_param)704 static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
705 tBTA_HH* p_data = (tBTA_HH*)p_param;
706 btif_hh_device_t* p_dev = NULL;
707 int i;
708 int len, tmplen;
709
710 BTIF_TRACE_DEBUG("%s: event=%s dereg = %d", __func__, dump_hh_event(event),
711 btif_hh_cb.service_dereg_active);
712
713 switch (event) {
714 case BTA_HH_ENABLE_EVT:
715 BTIF_TRACE_DEBUG("%s: BTA_HH_ENABLE_EVT: status =%d", __func__,
716 p_data->status);
717 if (p_data->status == BTA_HH_OK) {
718 btif_hh_cb.status = BTIF_HH_ENABLED;
719 BTIF_TRACE_DEBUG("%s--Loading added devices", __func__);
720 /* Add hid descriptors for already bonded hid devices*/
721 btif_storage_load_bonded_hid_info();
722 } else {
723 btif_hh_cb.status = BTIF_HH_DISABLED;
724 BTIF_TRACE_WARNING(
725 "BTA_HH_ENABLE_EVT: Error, HH enabling failed, status = %d",
726 p_data->status);
727 }
728 break;
729
730 case BTA_HH_DISABLE_EVT:
731 btif_hh_cb.status = BTIF_HH_DISABLED;
732 if (btif_hh_cb.service_dereg_active) {
733 BTIF_TRACE_DEBUG("BTA_HH_DISABLE_EVT: enabling HID Device service");
734 btif_hd_service_registration();
735 btif_hh_cb.service_dereg_active = FALSE;
736 }
737 if (p_data->status == BTA_HH_OK) {
738 int i;
739 // Clear the control block
740 for (i = 0; i < BTIF_HH_MAX_HID; i++) {
741 alarm_free(btif_hh_cb.devices[i].vup_timer);
742 }
743 memset(&btif_hh_cb, 0, sizeof(btif_hh_cb));
744 for (i = 0; i < BTIF_HH_MAX_HID; i++) {
745 btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN;
746 }
747 } else
748 BTIF_TRACE_WARNING(
749 "BTA_HH_DISABLE_EVT: Error, HH disabling failed, status = %d",
750 p_data->status);
751 break;
752
753 case BTA_HH_OPEN_EVT:
754 BTIF_TRACE_WARNING("%s: BTA_HH_OPN_EVT: handle=%d, status =%d", __func__,
755 p_data->conn.handle, p_data->conn.status);
756 btif_hh_cb.pending_conn_address = RawAddress::kEmpty;
757 if (p_data->conn.status == BTA_HH_OK) {
758 p_dev = btif_hh_find_connected_dev_by_handle(p_data->conn.handle);
759 if (p_dev == NULL) {
760 BTIF_TRACE_WARNING(
761 "BTA_HH_OPEN_EVT: Error, cannot find device with handle %d",
762 p_data->conn.handle);
763 btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
764 // The connect request must come from device side and exceeded the
765 // connected
766 // HID device number.
767 BTA_HhClose(p_data->conn.handle);
768 HAL_CBACK(bt_hh_callbacks, connection_state_cb,
769 (RawAddress*)&p_data->conn.bda,
770 BTHH_CONN_STATE_DISCONNECTED);
771 } else if (p_dev->fd < 0) {
772 BTIF_TRACE_WARNING(
773 "BTA_HH_OPEN_EVT: Error, failed to find the uhid driver...");
774 p_dev->bd_addr = p_data->conn.bda;
775 // remove the connection and then try again to reconnect from the
776 // mouse side to recover
777 btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
778 BTA_HhClose(p_data->conn.handle);
779 } else {
780 BTIF_TRACE_WARNING(
781 "BTA_HH_OPEN_EVT: Found device...Getting dscp info for handle "
782 "... %d",
783 p_data->conn.handle);
784 p_dev->bd_addr = p_data->conn.bda;
785 btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_CONNECTED;
786 // Send set_idle if the peer_device is a keyboard
787 if (check_cod(&p_data->conn.bda, COD_HID_KEYBOARD) ||
788 check_cod(&p_data->conn.bda, COD_HID_COMBO))
789 BTA_HhSetIdle(p_data->conn.handle, 0);
790 btif_hh_cb.p_curr_dev =
791 btif_hh_find_connected_dev_by_handle(p_data->conn.handle);
792 BTA_HhGetDscpInfo(p_data->conn.handle);
793 p_dev->dev_status = BTHH_CONN_STATE_CONNECTED;
794 HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr),
795 p_dev->dev_status);
796 }
797 } else {
798 RawAddress* bdaddr = &p_data->conn.bda;
799 btif_dm_hh_open_failed(bdaddr);
800 p_dev = btif_hh_find_dev_by_bda(*bdaddr);
801 if (p_dev != NULL) {
802 btif_hh_stop_vup_timer(&(p_dev->bd_addr));
803 if (p_dev->fd >= 0) {
804 bta_hh_co_destroy(p_dev->fd);
805 p_dev->fd = -1;
806 }
807 p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
808 }
809 HAL_CBACK(bt_hh_callbacks, connection_state_cb,
810 (RawAddress*)&p_data->conn.bda, BTHH_CONN_STATE_DISCONNECTED);
811 btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
812 }
813 break;
814
815 case BTA_HH_CLOSE_EVT:
816 BTIF_TRACE_DEBUG("BTA_HH_CLOSE_EVT: status = %d, handle = %d",
817 p_data->dev_status.status, p_data->dev_status.handle);
818 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
819 if (p_dev != NULL) {
820 BTIF_TRACE_DEBUG("%s: uhid fd=%d local_vup=%d", __func__, p_dev->fd,
821 p_dev->local_vup);
822 btif_hh_stop_vup_timer(&(p_dev->bd_addr));
823 /* If this is a locally initiated VUP, remove the bond as ACL got
824 * disconnected while VUP being processed.
825 */
826 if (p_dev->local_vup) {
827 p_dev->local_vup = false;
828 BTA_DmRemoveDevice(p_dev->bd_addr);
829 }
830
831 btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
832 p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
833
834 if (p_dev->fd >= 0) {
835 bta_hh_co_destroy(p_dev->fd);
836 p_dev->fd = -1;
837 }
838 HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr),
839 p_dev->dev_status);
840 } else {
841 BTIF_TRACE_WARNING("Error: cannot find device with handle %d",
842 p_data->dev_status.handle);
843 }
844 break;
845
846 case BTA_HH_GET_RPT_EVT: {
847 BT_HDR* hdr = p_data->hs_data.rsp_data.p_rpt_data;
848 uint8_t* data = NULL;
849 uint16_t len = 0;
850
851 BTIF_TRACE_DEBUG("BTA_HH_GET_RPT_EVT: status = %d, handle = %d",
852 p_data->hs_data.status, p_data->hs_data.handle);
853 p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
854 if (p_dev) {
855 /* p_rpt_data is NULL in HANDSHAKE response case */
856 if (hdr) {
857 data = (uint8_t*)(hdr + 1) + hdr->offset;
858 len = hdr->len;
859 HAL_CBACK(bt_hh_callbacks, get_report_cb,
860 (RawAddress*)&(p_dev->bd_addr),
861 (bthh_status_t)p_data->hs_data.status, data, len);
862 } else {
863 HAL_CBACK(bt_hh_callbacks, handshake_cb,
864 (RawAddress*)&(p_dev->bd_addr),
865 (bthh_status_t)p_data->hs_data.status);
866 }
867 } else {
868 BTIF_TRACE_WARNING("Error: cannot find device with handle %d",
869 p_data->hs_data.handle);
870 }
871 break;
872 }
873
874 case BTA_HH_SET_RPT_EVT:
875 BTIF_TRACE_DEBUG("BTA_HH_SET_RPT_EVT: status = %d, handle = %d",
876 p_data->dev_status.status, p_data->dev_status.handle);
877 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
878 if (p_dev != NULL) {
879 HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr),
880 (bthh_status_t)p_data->hs_data.status);
881 }
882 break;
883
884 case BTA_HH_GET_PROTO_EVT:
885 p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
886 BTIF_TRACE_WARNING(
887 "BTA_HH_GET_PROTO_EVT: status = %d, handle = %d, proto = [%d], %s",
888 p_data->hs_data.status, p_data->hs_data.handle,
889 p_data->hs_data.rsp_data.proto_mode,
890 (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE)
891 ? "Report Mode"
892 : (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_BOOT_MODE)
893 ? "Boot Mode"
894 : "Unsupported");
895 if (p_data->hs_data.rsp_data.proto_mode != BTA_HH_PROTO_UNKNOWN) {
896 HAL_CBACK(bt_hh_callbacks, protocol_mode_cb,
897 (RawAddress*)&(p_dev->bd_addr),
898 (bthh_status_t)p_data->hs_data.status,
899 (bthh_protocol_mode_t)p_data->hs_data.rsp_data.proto_mode);
900 } else {
901 HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr),
902 (bthh_status_t)p_data->hs_data.status);
903 }
904 break;
905
906 case BTA_HH_SET_PROTO_EVT:
907 BTIF_TRACE_DEBUG("BTA_HH_SET_PROTO_EVT: status = %d, handle = %d",
908 p_data->dev_status.status, p_data->dev_status.handle);
909 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
910 if (p_dev) {
911 HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr),
912 (bthh_status_t)p_data->hs_data.status);
913 }
914 break;
915
916 case BTA_HH_GET_IDLE_EVT:
917 BTIF_TRACE_DEBUG(
918 "BTA_HH_GET_IDLE_EVT: handle = %d, status = %d, rate = %d",
919 p_data->hs_data.handle, p_data->hs_data.status,
920 p_data->hs_data.rsp_data.idle_rate);
921 p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
922 HAL_CBACK(bt_hh_callbacks, idle_time_cb, (RawAddress*)&(p_dev->bd_addr),
923 (bthh_status_t)p_data->hs_data.status,
924 p_data->hs_data.rsp_data.idle_rate);
925 break;
926
927 case BTA_HH_SET_IDLE_EVT:
928 BTIF_TRACE_DEBUG("BTA_HH_SET_IDLE_EVT: status = %d, handle = %d",
929 p_data->dev_status.status, p_data->dev_status.handle);
930 break;
931
932 case BTA_HH_GET_DSCP_EVT:
933 len = p_data->dscp_info.descriptor.dl_len;
934 BTIF_TRACE_DEBUG("BTA_HH_GET_DSCP_EVT: len = %d", len);
935 p_dev = btif_hh_cb.p_curr_dev;
936 if (p_dev == NULL) {
937 BTIF_TRACE_ERROR(
938 "BTA_HH_GET_DSCP_EVT: No HID device is currently connected");
939 return;
940 }
941 if (p_dev->fd < 0) {
942 LOG_ERROR(
943 LOG_TAG,
944 "BTA_HH_GET_DSCP_EVT: Error, failed to find the uhid driver...");
945 return;
946 }
947 {
948 const char* cached_name = NULL;
949 bt_bdname_t bdname;
950 bt_property_t prop_name;
951 BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_BDNAME,
952 sizeof(bt_bdname_t), &bdname);
953 if (btif_storage_get_remote_device_property(
954 &p_dev->bd_addr, &prop_name) == BT_STATUS_SUCCESS) {
955 cached_name = (char*)bdname.name;
956 } else {
957 cached_name = "Bluetooth HID";
958 }
959
960 BTIF_TRACE_WARNING("%s: name = %s", __func__, cached_name);
961 bta_hh_co_send_hid_info(p_dev, cached_name, p_data->dscp_info.vendor_id,
962 p_data->dscp_info.product_id,
963 p_data->dscp_info.version,
964 p_data->dscp_info.ctry_code, len,
965 p_data->dscp_info.descriptor.dsc_list);
966 if (btif_hh_add_added_dev(p_dev->bd_addr, p_dev->attr_mask)) {
967 tBTA_HH_DEV_DSCP_INFO dscp_info;
968 bt_status_t ret;
969 btif_hh_copy_hid_info(&dscp_info, &p_data->dscp_info);
970 VLOG(1) << "BTA_HH_GET_DSCP_EVT:bda = " << p_dev->bd_addr;
971 BTA_HhAddDev(p_dev->bd_addr, p_dev->attr_mask, p_dev->sub_class,
972 p_dev->app_id, dscp_info);
973 // write hid info to nvram
974 ret = btif_storage_add_hid_device_info(
975 &(p_dev->bd_addr), p_dev->attr_mask, p_dev->sub_class,
976 p_dev->app_id, p_data->dscp_info.vendor_id,
977 p_data->dscp_info.product_id, p_data->dscp_info.version,
978 p_data->dscp_info.ctry_code, p_data->dscp_info.ssr_max_latency,
979 p_data->dscp_info.ssr_min_tout, len,
980 p_data->dscp_info.descriptor.dsc_list);
981
982 ASSERTC(ret == BT_STATUS_SUCCESS, "storing hid info failed", ret);
983 BTIF_TRACE_WARNING("BTA_HH_GET_DSCP_EVT: Called add device");
984
985 // Free buffer created for dscp_info;
986 if (dscp_info.descriptor.dl_len > 0 &&
987 dscp_info.descriptor.dsc_list != NULL) {
988 osi_free_and_reset((void**)&dscp_info.descriptor.dsc_list);
989 dscp_info.descriptor.dl_len = 0;
990 }
991 } else {
992 // Device already added.
993 BTIF_TRACE_WARNING("%s: Device already added ", __func__);
994 }
995 /*Sync HID Keyboard lockstates */
996 tmplen = sizeof(hid_kb_numlock_on_list) / sizeof(tHID_KB_LIST);
997 for (i = 0; i < tmplen; i++) {
998 if (p_data->dscp_info.vendor_id ==
999 hid_kb_numlock_on_list[i].version_id &&
1000 p_data->dscp_info.product_id ==
1001 hid_kb_numlock_on_list[i].product_id) {
1002 BTIF_TRACE_DEBUG(
1003 "%s() idx[%d] Enabling "
1004 "NUMLOCK for device :: %s",
1005 __func__, i, hid_kb_numlock_on_list[i].kb_name);
1006 /* Enable NUMLOCK by default so that numeric
1007 keys work from first keyboard connect */
1008 set_keylockstate(BTIF_HH_KEYSTATE_MASK_NUMLOCK, true);
1009 sync_lockstate_on_connect(p_dev);
1010 /* End Sync HID Keyboard lockstates */
1011 break;
1012 }
1013 }
1014 }
1015 break;
1016
1017 case BTA_HH_ADD_DEV_EVT:
1018 BTIF_TRACE_WARNING("BTA_HH_ADD_DEV_EVT: status = %d, handle = %d",
1019 p_data->dev_info.status, p_data->dev_info.handle);
1020 int i;
1021 for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
1022 if (btif_hh_cb.added_devices[i].bd_addr == p_data->dev_info.bda) {
1023 if (p_data->dev_info.status == BTA_HH_OK) {
1024 btif_hh_cb.added_devices[i].dev_handle = p_data->dev_info.handle;
1025 } else {
1026 btif_hh_cb.added_devices[i].bd_addr = RawAddress::kEmpty;
1027 btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE;
1028 }
1029 break;
1030 }
1031 }
1032 break;
1033 case BTA_HH_RMV_DEV_EVT:
1034 BTIF_TRACE_DEBUG("BTA_HH_RMV_DEV_EVT: status = %d, handle = %d",
1035 p_data->dev_info.status, p_data->dev_info.handle);
1036 VLOG(1) << "BTA_HH_RMV_DEV_EVT:bda = " << p_data->dev_info.bda;
1037 break;
1038
1039 case BTA_HH_VC_UNPLUG_EVT:
1040 BTIF_TRACE_DEBUG("BTA_HH_VC_UNPLUG_EVT: status = %d, handle = %d",
1041 p_data->dev_status.status, p_data->dev_status.handle);
1042 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
1043 btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
1044 if (p_dev != NULL) {
1045 VLOG(1) << "BTA_HH_VC_UNPLUG_EVT:bda = " << p_dev->bd_addr;
1046
1047 /* Stop the VUP timer */
1048 btif_hh_stop_vup_timer(&(p_dev->bd_addr));
1049 p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
1050 BTIF_TRACE_DEBUG("%s---Sending connection state change", __func__);
1051 HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr),
1052 p_dev->dev_status);
1053 BTIF_TRACE_DEBUG("%s---Removing HID bond", __func__);
1054 /* If it is locally initiated VUP or remote device has its major COD as
1055 Peripheral removed the bond.*/
1056 if (p_dev->local_vup || check_cod_hid(&(p_dev->bd_addr))) {
1057 p_dev->local_vup = false;
1058 BTA_DmRemoveDevice(p_dev->bd_addr);
1059 } else
1060 btif_hh_remove_device(p_dev->bd_addr);
1061 HAL_CBACK(bt_hh_callbacks, virtual_unplug_cb, &(p_dev->bd_addr),
1062 (bthh_status_t)p_data->dev_status.status);
1063 }
1064 break;
1065
1066 case BTA_HH_API_ERR_EVT:
1067 LOG_INFO(LOG_TAG, "BTA_HH API_ERR");
1068 break;
1069
1070 default:
1071 BTIF_TRACE_WARNING("%s: Unhandled event: %d", __func__, event);
1072 break;
1073 }
1074 }
1075
1076 /*******************************************************************************
1077 *
1078 * Function bte_hh_evt
1079 *
1080 * Description Switches context from BTE to BTIF for all HH events
1081 *
1082 * Returns void
1083 *
1084 ******************************************************************************/
1085
bte_hh_evt(tBTA_HH_EVT event,tBTA_HH * p_data)1086 void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
1087 bt_status_t status;
1088 int param_len = 0;
1089
1090 if (BTA_HH_ENABLE_EVT == event)
1091 param_len = sizeof(tBTA_HH_STATUS);
1092 else if (BTA_HH_OPEN_EVT == event)
1093 param_len = sizeof(tBTA_HH_CONN);
1094 else if (BTA_HH_DISABLE_EVT == event)
1095 param_len = sizeof(tBTA_HH_STATUS);
1096 else if (BTA_HH_CLOSE_EVT == event)
1097 param_len = sizeof(tBTA_HH_CBDATA);
1098 else if (BTA_HH_GET_DSCP_EVT == event)
1099 param_len = sizeof(tBTA_HH_DEV_DSCP_INFO);
1100 else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_RPT_EVT == event) ||
1101 (BTA_HH_GET_IDLE_EVT == event))
1102 param_len = sizeof(tBTA_HH_HSDATA);
1103 else if ((BTA_HH_SET_PROTO_EVT == event) || (BTA_HH_SET_RPT_EVT == event) ||
1104 (BTA_HH_VC_UNPLUG_EVT == event) || (BTA_HH_SET_IDLE_EVT == event))
1105 param_len = sizeof(tBTA_HH_CBDATA);
1106 else if ((BTA_HH_ADD_DEV_EVT == event) || (BTA_HH_RMV_DEV_EVT == event))
1107 param_len = sizeof(tBTA_HH_DEV_INFO);
1108 else if (BTA_HH_API_ERR_EVT == event)
1109 param_len = 0;
1110 /* switch context to btif task context (copy full union size for convenience)
1111 */
1112 status = btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event,
1113 (char*)p_data, param_len, NULL);
1114
1115 /* catch any failed context transfers */
1116 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
1117 }
1118
1119 /*******************************************************************************
1120 *
1121 * Function btif_hh_handle_evt
1122 *
1123 * Description Switches context for immediate callback
1124 *
1125 * Returns void
1126 *
1127 ******************************************************************************/
1128
btif_hh_handle_evt(uint16_t event,char * p_param)1129 static void btif_hh_handle_evt(uint16_t event, char* p_param) {
1130 RawAddress* bd_addr = (RawAddress*)p_param;
1131 BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
1132 int ret;
1133 switch (event) {
1134 case BTIF_HH_CONNECT_REQ_EVT: {
1135 ret = btif_hh_connect(bd_addr);
1136 if (ret == BT_STATUS_SUCCESS) {
1137 HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr,
1138 BTHH_CONN_STATE_CONNECTING);
1139 } else
1140 HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr,
1141 BTHH_CONN_STATE_DISCONNECTED);
1142 } break;
1143
1144 case BTIF_HH_DISCONNECT_REQ_EVT: {
1145 BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
1146 btif_hh_disconnect(bd_addr);
1147 HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr,
1148 BTHH_CONN_STATE_DISCONNECTING);
1149 } break;
1150
1151 case BTIF_HH_VUP_REQ_EVT: {
1152 BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
1153 ret = btif_hh_virtual_unplug(bd_addr);
1154 } break;
1155
1156 default: {
1157 BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __func__, event);
1158 } break;
1159 }
1160 }
1161
1162 /*******************************************************************************
1163 *
1164 * Function btif_hh_timer_timeout
1165 *
1166 * Description Process timer timeout
1167 *
1168 * Returns void
1169 ******************************************************************************/
btif_hh_timer_timeout(void * data)1170 void btif_hh_timer_timeout(void* data) {
1171 btif_hh_device_t* p_dev = (btif_hh_device_t*)data;
1172 tBTA_HH_EVT event = BTA_HH_VC_UNPLUG_EVT;
1173 tBTA_HH p_data;
1174 int param_len = sizeof(tBTA_HH_CBDATA);
1175
1176 BTIF_TRACE_DEBUG("%s", __func__);
1177 if (p_dev->dev_status != BTHH_CONN_STATE_CONNECTED) return;
1178
1179 memset(&p_data, 0, sizeof(tBTA_HH));
1180 p_data.dev_status.status = BTHH_ERR;
1181 p_data.dev_status.handle = p_dev->dev_handle;
1182
1183 /* switch context to btif task context */
1184 btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event, (char*)&p_data,
1185 param_len, NULL);
1186 }
1187
1188 /*******************************************************************************
1189 *
1190 * Function btif_hh_init
1191 *
1192 * Description initializes the hh interface
1193 *
1194 * Returns bt_status_t
1195 *
1196 ******************************************************************************/
init(bthh_callbacks_t * callbacks)1197 static bt_status_t init(bthh_callbacks_t* callbacks) {
1198 uint32_t i;
1199 BTIF_TRACE_EVENT("%s", __func__);
1200
1201 bt_hh_callbacks = callbacks;
1202 memset(&btif_hh_cb, 0, sizeof(btif_hh_cb));
1203 for (i = 0; i < BTIF_HH_MAX_HID; i++) {
1204 btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN;
1205 }
1206 /* Invoke the enable service API to the core to set the appropriate service_id
1207 */
1208 btif_enable_service(BTA_HID_SERVICE_ID);
1209 return BT_STATUS_SUCCESS;
1210 }
1211
1212 /*******************************************************************************
1213 *
1214 * Function connect
1215 *
1216 * Description connect to hid device
1217 *
1218 * Returns bt_status_t
1219 *
1220 ******************************************************************************/
connect(RawAddress * bd_addr)1221 static bt_status_t connect(RawAddress* bd_addr) {
1222 if (btif_hh_cb.status != BTIF_HH_DEV_CONNECTING) {
1223 btif_transfer_context(btif_hh_handle_evt, BTIF_HH_CONNECT_REQ_EVT,
1224 (char*)bd_addr, sizeof(RawAddress), NULL);
1225 return BT_STATUS_SUCCESS;
1226 } else
1227 return BT_STATUS_BUSY;
1228 }
1229
1230 /*******************************************************************************
1231 *
1232 * Function disconnect
1233 *
1234 * Description disconnect from hid device
1235 *
1236 * Returns bt_status_t
1237 *
1238 ******************************************************************************/
disconnect(RawAddress * bd_addr)1239 static bt_status_t disconnect(RawAddress* bd_addr) {
1240 CHECK_BTHH_INIT();
1241 BTIF_TRACE_EVENT("BTHH: %s", __func__);
1242 btif_hh_device_t* p_dev;
1243
1244 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1245 BTIF_TRACE_WARNING("%s: Error, HH status = %d", __func__,
1246 btif_hh_cb.status);
1247 return BT_STATUS_FAIL;
1248 }
1249 p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1250 if (p_dev != NULL) {
1251 return btif_transfer_context(btif_hh_handle_evt, BTIF_HH_DISCONNECT_REQ_EVT,
1252 (char*)bd_addr, sizeof(RawAddress), NULL);
1253 } else {
1254 BTIF_TRACE_WARNING("%s: Error, device not opened.", __func__);
1255 return BT_STATUS_FAIL;
1256 }
1257 }
1258
1259 /*******************************************************************************
1260 *
1261 * Function virtual_unplug
1262 *
1263 * Description Virtual UnPlug (VUP) the specified HID device.
1264 *
1265 * Returns bt_status_t
1266 *
1267 ******************************************************************************/
virtual_unplug(RawAddress * bd_addr)1268 static bt_status_t virtual_unplug(RawAddress* bd_addr) {
1269 CHECK_BTHH_INIT();
1270 BTIF_TRACE_EVENT("BTHH: %s", __func__);
1271 btif_hh_device_t* p_dev;
1272 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1273 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1274 return BT_STATUS_FAIL;
1275 }
1276 p_dev = btif_hh_find_dev_by_bda(*bd_addr);
1277 if (!p_dev) {
1278 BTIF_TRACE_ERROR("%s: Error, device %s not opened.", __func__,
1279 bd_addr->ToString().c_str());
1280 return BT_STATUS_FAIL;
1281 }
1282 btif_transfer_context(btif_hh_handle_evt, BTIF_HH_VUP_REQ_EVT, (char*)bd_addr,
1283 sizeof(RawAddress), NULL);
1284 return BT_STATUS_SUCCESS;
1285 }
1286
1287 /*******************************************************************************
1288 **
1289 ** Function get_idle_time
1290 **
1291 ** Description Get the HID idle time
1292 **
1293 ** Returns bt_status_t
1294 **
1295 *******************************************************************************/
get_idle_time(RawAddress * bd_addr)1296 static bt_status_t get_idle_time(RawAddress* bd_addr) {
1297 CHECK_BTHH_INIT();
1298
1299 BTIF_TRACE_DEBUG("%s: addr = %s", __func__, bd_addr->ToString().c_str());
1300
1301 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1302 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1303 return BT_STATUS_FAIL;
1304 }
1305
1306 btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1307 if (p_dev == NULL) return BT_STATUS_FAIL;
1308
1309 BTA_HhGetIdle(p_dev->dev_handle);
1310 return BT_STATUS_SUCCESS;
1311 }
1312
1313 /*******************************************************************************
1314 **
1315 ** Function set_idle_time
1316 **
1317 ** Description Set the HID idle time
1318 **
1319 ** Returns bt_status_t
1320 **
1321 *******************************************************************************/
set_idle_time(RawAddress * bd_addr,uint8_t idle_time)1322 static bt_status_t set_idle_time(RawAddress* bd_addr, uint8_t idle_time) {
1323 CHECK_BTHH_INIT();
1324
1325 BTIF_TRACE_DEBUG("%s: addr = %s, idle time = %d", __func__,
1326 bd_addr->ToString().c_str(), idle_time);
1327
1328 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1329 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1330 return BT_STATUS_FAIL;
1331 }
1332
1333 btif_hh_device_t* p_dev = p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1334 if (p_dev == NULL) {
1335 BTIF_TRACE_WARNING("%s: addr = %s not opened", __func__,
1336 bd_addr->ToString().c_str());
1337 return BT_STATUS_FAIL;
1338 }
1339
1340 BTA_HhSetIdle(p_dev->dev_handle, idle_time);
1341 return BT_STATUS_SUCCESS;
1342 }
1343
1344 /*******************************************************************************
1345 *
1346 * Function set_info
1347 *
1348 * Description Set the HID device descriptor for the specified HID device.
1349 *
1350 * Returns bt_status_t
1351 *
1352 ******************************************************************************/
set_info(RawAddress * bd_addr,bthh_hid_info_t hid_info)1353 static bt_status_t set_info(RawAddress* bd_addr, bthh_hid_info_t hid_info) {
1354 CHECK_BTHH_INIT();
1355 tBTA_HH_DEV_DSCP_INFO dscp_info;
1356
1357 VLOG(1) << __func__ << " BTHH: addr = " << *bd_addr;
1358 BTIF_TRACE_DEBUG(
1359 "BTHH: %s: sub_class = 0x%02x, app_id = %d, vendor_id = 0x%04x, "
1360 "product_id = 0x%04x, version= 0x%04x",
1361 __func__, hid_info.sub_class, hid_info.app_id, hid_info.vendor_id,
1362 hid_info.product_id, hid_info.version);
1363
1364 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1365 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1366 return BT_STATUS_FAIL;
1367 }
1368
1369 memset(&dscp_info, 0, sizeof(dscp_info));
1370 dscp_info.vendor_id = hid_info.vendor_id;
1371 dscp_info.product_id = hid_info.product_id;
1372 dscp_info.version = hid_info.version;
1373 dscp_info.ctry_code = hid_info.ctry_code;
1374
1375 dscp_info.descriptor.dl_len = hid_info.dl_len;
1376 dscp_info.descriptor.dsc_list =
1377 (uint8_t*)osi_malloc(dscp_info.descriptor.dl_len);
1378 memcpy(dscp_info.descriptor.dsc_list, &(hid_info.dsc_list), hid_info.dl_len);
1379
1380 if (btif_hh_add_added_dev(*bd_addr, hid_info.attr_mask)) {
1381 BTA_HhAddDev(*bd_addr, hid_info.attr_mask, hid_info.sub_class,
1382 hid_info.app_id, dscp_info);
1383 }
1384
1385 osi_free_and_reset((void**)&dscp_info.descriptor.dsc_list);
1386
1387 return BT_STATUS_SUCCESS;
1388 }
1389
1390 /*******************************************************************************
1391 *
1392 * Function get_protocol
1393 *
1394 * Description Get the HID proto mode.
1395 *
1396 * Returns bt_status_t
1397 *
1398 ******************************************************************************/
get_protocol(RawAddress * bd_addr,UNUSED_ATTR bthh_protocol_mode_t protocolMode)1399 static bt_status_t get_protocol(RawAddress* bd_addr,
1400 UNUSED_ATTR bthh_protocol_mode_t protocolMode) {
1401 CHECK_BTHH_INIT();
1402
1403 VLOG(1) << __func__ << " BTHH: addr = " << *bd_addr;
1404
1405 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1406 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1407 return BT_STATUS_FAIL;
1408 }
1409
1410 btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1411 if (!p_dev) return BT_STATUS_FAIL;
1412
1413 BTA_HhGetProtoMode(p_dev->dev_handle);
1414 return BT_STATUS_SUCCESS;
1415 }
1416
1417 /*******************************************************************************
1418 *
1419 * Function set_protocol
1420 *
1421 * Description Set the HID proto mode.
1422 *
1423 * Returns bt_status_t
1424 *
1425 ******************************************************************************/
set_protocol(RawAddress * bd_addr,bthh_protocol_mode_t protocolMode)1426 static bt_status_t set_protocol(RawAddress* bd_addr,
1427 bthh_protocol_mode_t protocolMode) {
1428 CHECK_BTHH_INIT();
1429 btif_hh_device_t* p_dev;
1430 uint8_t proto_mode = protocolMode;
1431
1432 VLOG(1) << __func__ << " BTHH: proto_mod=" << protocolMode
1433 << " addr = " << *bd_addr;
1434
1435 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1436 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1437 return BT_STATUS_FAIL;
1438 }
1439
1440 p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1441 if (p_dev == NULL) {
1442 LOG(WARNING) << " Error, device" << *bd_addr << " not opened";
1443 return BT_STATUS_FAIL;
1444 } else if (protocolMode != BTA_HH_PROTO_RPT_MODE &&
1445 protocolMode != BTA_HH_PROTO_BOOT_MODE) {
1446 BTIF_TRACE_WARNING("%s: Error, device proto_mode = %d.", __func__,
1447 proto_mode);
1448 return BT_STATUS_FAIL;
1449 } else {
1450 BTA_HhSetProtoMode(p_dev->dev_handle, protocolMode);
1451 }
1452
1453 return BT_STATUS_SUCCESS;
1454 }
1455
1456 /*******************************************************************************
1457 *
1458 * Function get_report
1459 *
1460 * Description Send a GET_REPORT to HID device.
1461 *
1462 * Returns bt_status_t
1463 *
1464 ******************************************************************************/
get_report(RawAddress * bd_addr,bthh_report_type_t reportType,uint8_t reportId,int bufferSize)1465 static bt_status_t get_report(RawAddress* bd_addr,
1466 bthh_report_type_t reportType, uint8_t reportId,
1467 int bufferSize) {
1468 CHECK_BTHH_INIT();
1469 btif_hh_device_t* p_dev;
1470
1471 VLOG(1) << __func__ << " BTHH: r_type = " << reportType
1472 << ", rpt_id = " << reportId << ", buf_size = " << bufferSize
1473 << " addr = " << *bd_addr;
1474
1475 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1476 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1477 return BT_STATUS_FAIL;
1478 }
1479
1480 p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1481 if (p_dev == NULL) {
1482 LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
1483 return BT_STATUS_FAIL;
1484 } else if (((int)reportType) <= BTA_HH_RPTT_RESRV ||
1485 ((int)reportType) > BTA_HH_RPTT_FEATURE) {
1486 LOG(ERROR) << " Error, report type=" << +reportType << " not supported";
1487 return BT_STATUS_FAIL;
1488 } else {
1489 BTA_HhGetReport(p_dev->dev_handle, reportType, reportId, bufferSize);
1490 }
1491
1492 return BT_STATUS_SUCCESS;
1493 }
1494
1495 /*******************************************************************************
1496 *
1497 * Function set_report
1498 *
1499 * Description Send a SET_REPORT to HID device.
1500 *
1501 * Returns bt_status_t
1502 *
1503 ******************************************************************************/
set_report(RawAddress * bd_addr,bthh_report_type_t reportType,char * report)1504 static bt_status_t set_report(RawAddress* bd_addr,
1505 bthh_report_type_t reportType, char* report) {
1506 CHECK_BTHH_INIT();
1507 btif_hh_device_t* p_dev;
1508
1509 VLOG(1) << __func__ << " BTHH: reportType=" << reportType
1510 << " addr=" << *bd_addr;
1511
1512 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1513 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1514 return BT_STATUS_FAIL;
1515 }
1516
1517 p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1518 if (p_dev == NULL) {
1519 LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
1520 return BT_STATUS_FAIL;
1521 } else if (((int)reportType) <= BTA_HH_RPTT_RESRV ||
1522 ((int)reportType) > BTA_HH_RPTT_FEATURE) {
1523 LOG(ERROR) << " Error, report type=" << +reportType << " not supported";
1524 return BT_STATUS_FAIL;
1525 } else {
1526 int hex_bytes_filled;
1527 size_t len = (strlen(report) + 1) / 2;
1528 uint8_t* hexbuf = (uint8_t*)osi_calloc(len);
1529
1530 /* Build a SetReport data buffer */
1531 // TODO
1532 hex_bytes_filled = ascii_2_hex(report, len, hexbuf);
1533 LOG_INFO(LOG_TAG, "Hex bytes filled, hex value: %d", hex_bytes_filled);
1534 if (hex_bytes_filled) {
1535 BT_HDR* p_buf = create_pbuf(hex_bytes_filled, hexbuf);
1536 if (p_buf == NULL) {
1537 BTIF_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, len = %d",
1538 __func__, hex_bytes_filled);
1539 osi_free(hexbuf);
1540 return BT_STATUS_FAIL;
1541 }
1542 BTA_HhSetReport(p_dev->dev_handle, reportType, p_buf);
1543 osi_free(hexbuf);
1544 return BT_STATUS_SUCCESS;
1545 }
1546 osi_free(hexbuf);
1547 return BT_STATUS_FAIL;
1548 }
1549 }
1550
1551 /*******************************************************************************
1552 *
1553 * Function send_data
1554 *
1555 * Description Send a SEND_DATA to HID device.
1556 *
1557 * Returns bt_status_t
1558 *
1559 ******************************************************************************/
send_data(RawAddress * bd_addr,char * data)1560 static bt_status_t send_data(RawAddress* bd_addr, char* data) {
1561 CHECK_BTHH_INIT();
1562 btif_hh_device_t* p_dev;
1563
1564 VLOG(1) << __func__ << " addr=" << *bd_addr;
1565
1566 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1567 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1568 return BT_STATUS_FAIL;
1569 }
1570
1571 p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1572 if (p_dev == NULL) {
1573 LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
1574 return BT_STATUS_FAIL;
1575 }
1576
1577 else {
1578 int hex_bytes_filled;
1579 size_t len = (strlen(data) + 1) / 2;
1580 uint8_t* hexbuf = (uint8_t*)osi_calloc(len);
1581
1582 /* Build a SendData data buffer */
1583 hex_bytes_filled = ascii_2_hex(data, len, hexbuf);
1584 BTIF_TRACE_ERROR("Hex bytes filled, hex value: %d, %d", hex_bytes_filled,
1585 len);
1586
1587 if (hex_bytes_filled) {
1588 BT_HDR* p_buf = create_pbuf(hex_bytes_filled, hexbuf);
1589 if (p_buf == NULL) {
1590 BTIF_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, len = %d",
1591 __func__, hex_bytes_filled);
1592 osi_free(hexbuf);
1593 return BT_STATUS_FAIL;
1594 }
1595 p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
1596 BTA_HhSendData(p_dev->dev_handle, *bd_addr, p_buf);
1597 osi_free(hexbuf);
1598 return BT_STATUS_SUCCESS;
1599 }
1600 osi_free(hexbuf);
1601 return BT_STATUS_FAIL;
1602 }
1603 }
1604
1605 /*******************************************************************************
1606 *
1607 * Function cleanup
1608 *
1609 * Description Closes the HH interface
1610 *
1611 * Returns bt_status_t
1612 *
1613 ******************************************************************************/
cleanup(void)1614 static void cleanup(void) {
1615 BTIF_TRACE_EVENT("%s", __func__);
1616 btif_hh_device_t* p_dev;
1617 int i;
1618 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1619 BTIF_TRACE_WARNING("%s: HH disabling or disabled already, status = %d",
1620 __func__, btif_hh_cb.status);
1621 return;
1622 }
1623 if (bt_hh_callbacks) {
1624 btif_hh_cb.status = BTIF_HH_DISABLING;
1625 /* update flag, not to enable hid device service now as BT is switching off
1626 */
1627 btif_hh_cb.service_dereg_active = FALSE;
1628 btif_disable_service(BTA_HID_SERVICE_ID);
1629 bt_hh_callbacks = NULL;
1630 }
1631 for (i = 0; i < BTIF_HH_MAX_HID; i++) {
1632 p_dev = &btif_hh_cb.devices[i];
1633 if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->fd >= 0) {
1634 BTIF_TRACE_DEBUG("%s: Closing uhid fd = %d", __func__, p_dev->fd);
1635 if (p_dev->fd >= 0) {
1636 bta_hh_co_destroy(p_dev->fd);
1637 p_dev->fd = -1;
1638 }
1639 p_dev->hh_keep_polling = 0;
1640 p_dev->hh_poll_thread_id = -1;
1641 }
1642 }
1643
1644 }
1645
1646 static const bthh_interface_t bthhInterface = {
1647 sizeof(bthhInterface),
1648 init,
1649 connect,
1650 disconnect,
1651 virtual_unplug,
1652 set_info,
1653 get_protocol,
1654 set_protocol,
1655 get_idle_time,
1656 set_idle_time,
1657 get_report,
1658 set_report,
1659 send_data,
1660 cleanup,
1661 };
1662
1663 /*******************************************************************************
1664 *
1665 * Function btif_hh_execute_service
1666 *
1667 * Description Initializes/Shuts down the service
1668 *
1669 * Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1670 *
1671 ******************************************************************************/
btif_hh_execute_service(bool b_enable)1672 bt_status_t btif_hh_execute_service(bool b_enable) {
1673 if (b_enable) {
1674 /* Enable and register with BTA-HH */
1675 BTA_HhEnable(BTUI_HH_SECURITY, bte_hh_evt);
1676 } else {
1677 /* Disable HH */
1678 BTA_HhDisable();
1679 }
1680 return BT_STATUS_SUCCESS;
1681 }
1682
1683 /*******************************************************************************
1684 *
1685 * Function btif_hh_get_interface
1686 *
1687 * Description Get the hh callback interface
1688 *
1689 * Returns bthh_interface_t
1690 *
1691 ******************************************************************************/
btif_hh_get_interface()1692 const bthh_interface_t* btif_hh_get_interface() {
1693 BTIF_TRACE_EVENT("%s", __func__);
1694 return &bthhInterface;
1695 }
1696