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 if ((p_dev != NULL) &&
547 (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED)) {
548 BTIF_TRACE_ERROR("%s: Virtual unplug not suported, disconnecting device");
549 /* start the timer */
550 btif_hh_start_vup_timer(bd_addr);
551 p_dev->local_vup = true;
552 BTA_HhClose(p_dev->dev_handle);
553 return BT_STATUS_SUCCESS;
554 } else {
555 BTIF_TRACE_ERROR("%s: Error, device %s not opened, status = %d", __func__,
556 bd_addr->ToString().c_str(), btif_hh_cb.status);
557 if ((btif_hh_cb.pending_conn_address == *bd_addr) &&
558 (btif_hh_cb.status == BTIF_HH_DEV_CONNECTING)) {
559 btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
560 btif_hh_cb.pending_conn_address = RawAddress::kEmpty;
561 }
562 return BT_STATUS_FAIL;
563 }
564 }
565
566 /*******************************************************************************
567 *
568 * Function btif_hh_connect
569 *
570 * Description connection initiated from the BTIF thread context
571 *
572 * Returns int status
573 *
574 ******************************************************************************/
575
btif_hh_connect(const RawAddress * bd_addr)576 bt_status_t btif_hh_connect(const RawAddress* bd_addr) {
577 btif_hh_added_device_t* added_dev = NULL;
578 CHECK_BTHH_INIT();
579 BTIF_TRACE_EVENT("BTHH: %s", __func__);
580 btif_hh_device_t* dev = btif_hh_find_dev_by_bda(*bd_addr);
581 if (!dev && btif_hh_cb.device_num >= BTIF_HH_MAX_HID) {
582 // No space for more HID device now.
583 BTIF_TRACE_WARNING(
584 "%s: Error, exceeded the maximum supported HID device number %d",
585 __func__, BTIF_HH_MAX_HID);
586 return BT_STATUS_FAIL;
587 }
588
589 for (int i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
590 if (btif_hh_cb.added_devices[i].bd_addr == *bd_addr) {
591 added_dev = &btif_hh_cb.added_devices[i];
592 LOG(WARNING) << __func__ << ": Device " << *bd_addr
593 << " already added, attr_mask = 0x" << std::hex
594 << added_dev->attr_mask;
595 }
596 }
597
598 if (added_dev != NULL) {
599 if (added_dev->dev_handle == BTA_HH_INVALID_HANDLE) {
600 // No space for more HID device now.
601 LOG(ERROR) << __func__ << ": Error, device " << *bd_addr
602 << " added but addition failed";
603 added_dev->bd_addr = RawAddress::kEmpty;
604 added_dev->dev_handle = BTA_HH_INVALID_HANDLE;
605 return BT_STATUS_FAIL;
606 }
607 }
608
609 /* Not checking the NORMALLY_Connectible flags from sdp record, and anyways
610 sending this
611 request from host, for subsequent user initiated connection. If the remote is
612 not in
613 pagescan mode, we will do 2 retries to connect before giving up */
614 tBTA_SEC sec_mask = BTUI_HH_SECURITY;
615 btif_hh_cb.status = BTIF_HH_DEV_CONNECTING;
616 btif_hh_cb.pending_conn_address = *bd_addr;
617 BTA_HhOpen(*bd_addr, BTA_HH_PROTO_RPT_MODE, sec_mask);
618
619 // TODO(jpawlowski); make cback accept const and remove tmp!
620 auto tmp = *bd_addr;
621 HAL_CBACK(bt_hh_callbacks, connection_state_cb, &tmp,
622 BTHH_CONN_STATE_CONNECTING);
623 return BT_STATUS_SUCCESS;
624 }
625
626 /*******************************************************************************
627 *
628 * Function btif_hh_disconnect
629 *
630 * Description disconnection initiated from the BTIF thread context
631 *
632 * Returns void
633 *
634 ******************************************************************************/
635
btif_hh_disconnect(RawAddress * bd_addr)636 void btif_hh_disconnect(RawAddress* bd_addr) {
637 btif_hh_device_t* p_dev;
638 p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
639 if (p_dev != NULL) {
640 BTA_HhClose(p_dev->dev_handle);
641 } else
642 BTIF_TRACE_DEBUG("%s-- Error: device not connected:", __func__);
643 }
644
645 /*******************************************************************************
646 *
647 * Function btif_btif_hh_setreport
648 *
649 * Description setreport initiated from the BTIF thread context
650 *
651 * Returns void
652 *
653 ******************************************************************************/
btif_hh_setreport(btif_hh_device_t * p_dev,bthh_report_type_t r_type,uint16_t size,uint8_t * report)654 void btif_hh_setreport(btif_hh_device_t* p_dev, bthh_report_type_t r_type,
655 uint16_t size, uint8_t* report) {
656 BT_HDR* p_buf = create_pbuf(size, report);
657 if (p_buf == NULL) {
658 APPL_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, size = %d",
659 __func__, size);
660 return;
661 }
662 BTA_HhSetReport(p_dev->dev_handle, r_type, p_buf);
663 }
664
665 /*******************************************************************************
666 *
667 * Function btif_hh_service_registration
668 *
669 * Description Registers or derigisters the hid host service
670 *
671 * Returns none
672 *
673 ******************************************************************************/
btif_hh_service_registration(bool enable)674 void btif_hh_service_registration(bool enable) {
675 BTIF_TRACE_API("%s", __func__);
676
677 BTIF_TRACE_API("enable = %d", enable);
678 if (bt_hh_callbacks == NULL) {
679 // The HID Host service was never initialized (it is either disabled or not
680 // available in this build). We should proceed directly to changing the HID
681 // Device service state (if needed).
682 if (!enable) {
683 btif_hd_service_registration();
684 }
685 } else if (enable) {
686 BTA_HhEnable(BTA_SEC_ENCRYPT, bte_hh_evt);
687 } else {
688 btif_hh_cb.service_dereg_active = TRUE;
689 BTA_HhDisable();
690 }
691 }
692
693 /*******************************************************************************
694 *
695 *
696 * Function btif_hh_getreport
697 *
698 * Description getreport initiated from the BTIF thread context
699 *
700 * Returns void
701 *
702 ******************************************************************************/
btif_hh_getreport(btif_hh_device_t * p_dev,bthh_report_type_t r_type,uint8_t reportId,uint16_t bufferSize)703 void btif_hh_getreport(btif_hh_device_t* p_dev, bthh_report_type_t r_type,
704 uint8_t reportId, uint16_t bufferSize) {
705 BTA_HhGetReport(p_dev->dev_handle, r_type, reportId, bufferSize);
706 }
707
708 /*****************************************************************************
709 * Section name (Group of functions)
710 ****************************************************************************/
711
712 /*****************************************************************************
713 *
714 * btif hh api functions (no context switch)
715 *
716 ****************************************************************************/
717
718 /*******************************************************************************
719 *
720 * Function btif_hh_upstreams_evt
721 *
722 * Description Executes HH UPSTREAMS events in btif context
723 *
724 * Returns void
725 *
726 ******************************************************************************/
btif_hh_upstreams_evt(uint16_t event,char * p_param)727 static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
728 tBTA_HH* p_data = (tBTA_HH*)p_param;
729 btif_hh_device_t* p_dev = NULL;
730 int i;
731 int len, tmplen;
732
733 BTIF_TRACE_DEBUG("%s: event=%s dereg = %d", __func__, dump_hh_event(event),
734 btif_hh_cb.service_dereg_active);
735
736 switch (event) {
737 case BTA_HH_ENABLE_EVT:
738 BTIF_TRACE_DEBUG("%s: BTA_HH_ENABLE_EVT: status =%d", __func__,
739 p_data->status);
740 if (p_data->status == BTA_HH_OK) {
741 btif_hh_cb.status = BTIF_HH_ENABLED;
742 BTIF_TRACE_DEBUG("%s--Loading added devices", __func__);
743 /* Add hid descriptors for already bonded hid devices*/
744 btif_storage_load_bonded_hid_info();
745 } else {
746 btif_hh_cb.status = BTIF_HH_DISABLED;
747 BTIF_TRACE_WARNING(
748 "BTA_HH_ENABLE_EVT: Error, HH enabling failed, status = %d",
749 p_data->status);
750 }
751 break;
752
753 case BTA_HH_DISABLE_EVT:
754 btif_hh_cb.status = BTIF_HH_DISABLED;
755 if (btif_hh_cb.service_dereg_active) {
756 BTIF_TRACE_DEBUG("BTA_HH_DISABLE_EVT: enabling HID Device service");
757 btif_hd_service_registration();
758 btif_hh_cb.service_dereg_active = FALSE;
759 }
760 if (p_data->status == BTA_HH_OK) {
761 int i;
762 // Clear the control block
763 for (i = 0; i < BTIF_HH_MAX_HID; i++) {
764 alarm_free(btif_hh_cb.devices[i].vup_timer);
765 }
766 memset(&btif_hh_cb, 0, sizeof(btif_hh_cb));
767 for (i = 0; i < BTIF_HH_MAX_HID; i++) {
768 btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN;
769 }
770 } else
771 BTIF_TRACE_WARNING(
772 "BTA_HH_DISABLE_EVT: Error, HH disabling failed, status = %d",
773 p_data->status);
774 break;
775
776 case BTA_HH_OPEN_EVT:
777 BTIF_TRACE_WARNING("%s: BTA_HH_OPN_EVT: handle=%d, status =%d", __func__,
778 p_data->conn.handle, p_data->conn.status);
779 btif_hh_cb.pending_conn_address = RawAddress::kEmpty;
780 if (p_data->conn.status == BTA_HH_OK) {
781 p_dev = btif_hh_find_connected_dev_by_handle(p_data->conn.handle);
782 if (p_dev == NULL) {
783 BTIF_TRACE_WARNING(
784 "BTA_HH_OPEN_EVT: Error, cannot find device with handle %d",
785 p_data->conn.handle);
786 btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
787 // The connect request must come from device side and exceeded the
788 // connected
789 // HID device number.
790 BTA_HhClose(p_data->conn.handle);
791 HAL_CBACK(bt_hh_callbacks, connection_state_cb,
792 (RawAddress*)&p_data->conn.bda,
793 BTHH_CONN_STATE_DISCONNECTED);
794 } else if (p_dev->fd < 0) {
795 BTIF_TRACE_WARNING(
796 "BTA_HH_OPEN_EVT: Error, failed to find the uhid driver...");
797 p_dev->bd_addr = p_data->conn.bda;
798 // remove the connection and then try again to reconnect from the
799 // mouse side to recover
800 btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
801 BTA_HhClose(p_data->conn.handle);
802 } else {
803 BTIF_TRACE_WARNING(
804 "BTA_HH_OPEN_EVT: Found device...Getting dscp info for handle "
805 "... %d",
806 p_data->conn.handle);
807 p_dev->bd_addr = p_data->conn.bda;
808 btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_CONNECTED;
809 // Send set_idle if the peer_device is a keyboard
810 if (check_cod(&p_data->conn.bda, COD_HID_KEYBOARD) ||
811 check_cod(&p_data->conn.bda, COD_HID_COMBO))
812 BTA_HhSetIdle(p_data->conn.handle, 0);
813 btif_hh_cb.p_curr_dev =
814 btif_hh_find_connected_dev_by_handle(p_data->conn.handle);
815 BTA_HhGetDscpInfo(p_data->conn.handle);
816 p_dev->dev_status = BTHH_CONN_STATE_CONNECTED;
817 HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr),
818 p_dev->dev_status);
819 }
820 } else {
821 RawAddress* bdaddr = &p_data->conn.bda;
822 btif_dm_hh_open_failed(bdaddr);
823 p_dev = btif_hh_find_dev_by_bda(*bdaddr);
824 if (p_dev != NULL) {
825 btif_hh_stop_vup_timer(&(p_dev->bd_addr));
826 if (p_dev->fd >= 0) {
827 bta_hh_co_destroy(p_dev->fd);
828 p_dev->fd = -1;
829 }
830 p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
831 }
832 HAL_CBACK(bt_hh_callbacks, connection_state_cb,
833 (RawAddress*)&p_data->conn.bda, BTHH_CONN_STATE_DISCONNECTED);
834 btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
835 }
836 break;
837
838 case BTA_HH_CLOSE_EVT:
839 BTIF_TRACE_DEBUG("BTA_HH_CLOSE_EVT: status = %d, handle = %d",
840 p_data->dev_status.status, p_data->dev_status.handle);
841 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
842 if (p_dev != NULL) {
843 BTIF_TRACE_DEBUG("%s: uhid fd=%d local_vup=%d", __func__, p_dev->fd,
844 p_dev->local_vup);
845 btif_hh_stop_vup_timer(&(p_dev->bd_addr));
846 /* If this is a locally initiated VUP, remove the bond as ACL got
847 * disconnected while VUP being processed.
848 */
849 if (p_dev->local_vup) {
850 p_dev->local_vup = false;
851 BTA_DmRemoveDevice(p_dev->bd_addr);
852 }
853
854 btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
855 p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
856
857 if (p_dev->fd >= 0) {
858 bta_hh_co_destroy(p_dev->fd);
859 p_dev->fd = -1;
860 }
861 HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr),
862 p_dev->dev_status);
863 } else {
864 BTIF_TRACE_WARNING("Error: cannot find device with handle %d",
865 p_data->dev_status.handle);
866 }
867 break;
868
869 case BTA_HH_GET_RPT_EVT: {
870 BT_HDR* hdr = p_data->hs_data.rsp_data.p_rpt_data;
871 uint8_t* data = NULL;
872 uint16_t len = 0;
873
874 BTIF_TRACE_DEBUG("BTA_HH_GET_RPT_EVT: status = %d, handle = %d",
875 p_data->hs_data.status, p_data->hs_data.handle);
876 p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
877 if (p_dev) {
878 /* p_rpt_data is NULL in HANDSHAKE response case */
879 if (hdr) {
880 data = (uint8_t*)(hdr + 1) + hdr->offset;
881 len = hdr->len;
882 HAL_CBACK(bt_hh_callbacks, get_report_cb,
883 (RawAddress*)&(p_dev->bd_addr),
884 (bthh_status_t)p_data->hs_data.status, data, len);
885 } else {
886 HAL_CBACK(bt_hh_callbacks, handshake_cb,
887 (RawAddress*)&(p_dev->bd_addr),
888 (bthh_status_t)p_data->hs_data.status);
889 }
890 } else {
891 BTIF_TRACE_WARNING("Error: cannot find device with handle %d",
892 p_data->hs_data.handle);
893 }
894 break;
895 }
896
897 case BTA_HH_SET_RPT_EVT:
898 BTIF_TRACE_DEBUG("BTA_HH_SET_RPT_EVT: status = %d, handle = %d",
899 p_data->dev_status.status, p_data->dev_status.handle);
900 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
901 if (p_dev != NULL) {
902 HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr),
903 (bthh_status_t)p_data->hs_data.status);
904 }
905 break;
906
907 case BTA_HH_GET_PROTO_EVT:
908 p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
909 BTIF_TRACE_WARNING(
910 "BTA_HH_GET_PROTO_EVT: status = %d, handle = %d, proto = [%d], %s",
911 p_data->hs_data.status, p_data->hs_data.handle,
912 p_data->hs_data.rsp_data.proto_mode,
913 (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE)
914 ? "Report Mode"
915 : (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_BOOT_MODE)
916 ? "Boot Mode"
917 : "Unsupported");
918 if (p_data->hs_data.rsp_data.proto_mode != BTA_HH_PROTO_UNKNOWN) {
919 HAL_CBACK(bt_hh_callbacks, protocol_mode_cb,
920 (RawAddress*)&(p_dev->bd_addr),
921 (bthh_status_t)p_data->hs_data.status,
922 (bthh_protocol_mode_t)p_data->hs_data.rsp_data.proto_mode);
923 } else {
924 HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr),
925 (bthh_status_t)p_data->hs_data.status);
926 }
927 break;
928
929 case BTA_HH_SET_PROTO_EVT:
930 BTIF_TRACE_DEBUG("BTA_HH_SET_PROTO_EVT: status = %d, handle = %d",
931 p_data->dev_status.status, p_data->dev_status.handle);
932 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
933 if (p_dev) {
934 HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr),
935 (bthh_status_t)p_data->hs_data.status);
936 }
937 break;
938
939 case BTA_HH_GET_IDLE_EVT:
940 BTIF_TRACE_DEBUG(
941 "BTA_HH_GET_IDLE_EVT: handle = %d, status = %d, rate = %d",
942 p_data->hs_data.handle, p_data->hs_data.status,
943 p_data->hs_data.rsp_data.idle_rate);
944 p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
945 HAL_CBACK(bt_hh_callbacks, idle_time_cb, (RawAddress*)&(p_dev->bd_addr),
946 (bthh_status_t)p_data->hs_data.status,
947 p_data->hs_data.rsp_data.idle_rate);
948 break;
949
950 case BTA_HH_SET_IDLE_EVT:
951 BTIF_TRACE_DEBUG("BTA_HH_SET_IDLE_EVT: status = %d, handle = %d",
952 p_data->dev_status.status, p_data->dev_status.handle);
953 break;
954
955 case BTA_HH_GET_DSCP_EVT:
956 len = p_data->dscp_info.descriptor.dl_len;
957 BTIF_TRACE_DEBUG("BTA_HH_GET_DSCP_EVT: len = %d", len);
958 p_dev = btif_hh_cb.p_curr_dev;
959 if (p_dev == NULL) {
960 BTIF_TRACE_ERROR(
961 "BTA_HH_GET_DSCP_EVT: No HID device is currently connected");
962 return;
963 }
964 if (p_dev->fd < 0) {
965 LOG_ERROR(
966 LOG_TAG,
967 "BTA_HH_GET_DSCP_EVT: Error, failed to find the uhid driver...");
968 return;
969 }
970 {
971 const char* cached_name = NULL;
972 bt_bdname_t bdname;
973 bt_property_t prop_name;
974 BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_BDNAME,
975 sizeof(bt_bdname_t), &bdname);
976 if (btif_storage_get_remote_device_property(
977 &p_dev->bd_addr, &prop_name) == BT_STATUS_SUCCESS) {
978 cached_name = (char*)bdname.name;
979 } else {
980 cached_name = "Bluetooth HID";
981 }
982
983 BTIF_TRACE_WARNING("%s: name = %s", __func__, cached_name);
984 bta_hh_co_send_hid_info(p_dev, cached_name, p_data->dscp_info.vendor_id,
985 p_data->dscp_info.product_id,
986 p_data->dscp_info.version,
987 p_data->dscp_info.ctry_code, len,
988 p_data->dscp_info.descriptor.dsc_list);
989 if (btif_hh_add_added_dev(p_dev->bd_addr, p_dev->attr_mask)) {
990 tBTA_HH_DEV_DSCP_INFO dscp_info;
991 bt_status_t ret;
992 btif_hh_copy_hid_info(&dscp_info, &p_data->dscp_info);
993 VLOG(1) << "BTA_HH_GET_DSCP_EVT:bda = " << p_dev->bd_addr;
994 BTA_HhAddDev(p_dev->bd_addr, p_dev->attr_mask, p_dev->sub_class,
995 p_dev->app_id, dscp_info);
996 // write hid info to nvram
997 ret = btif_storage_add_hid_device_info(
998 &(p_dev->bd_addr), p_dev->attr_mask, p_dev->sub_class,
999 p_dev->app_id, p_data->dscp_info.vendor_id,
1000 p_data->dscp_info.product_id, p_data->dscp_info.version,
1001 p_data->dscp_info.ctry_code, p_data->dscp_info.ssr_max_latency,
1002 p_data->dscp_info.ssr_min_tout, len,
1003 p_data->dscp_info.descriptor.dsc_list);
1004
1005 ASSERTC(ret == BT_STATUS_SUCCESS, "storing hid info failed", ret);
1006 BTIF_TRACE_WARNING("BTA_HH_GET_DSCP_EVT: Called add device");
1007
1008 // Free buffer created for dscp_info;
1009 if (dscp_info.descriptor.dl_len > 0 &&
1010 dscp_info.descriptor.dsc_list != NULL) {
1011 osi_free_and_reset((void**)&dscp_info.descriptor.dsc_list);
1012 dscp_info.descriptor.dl_len = 0;
1013 }
1014 } else {
1015 // Device already added.
1016 BTIF_TRACE_WARNING("%s: Device already added ", __func__);
1017 }
1018 /*Sync HID Keyboard lockstates */
1019 tmplen = sizeof(hid_kb_numlock_on_list) / sizeof(tHID_KB_LIST);
1020 for (i = 0; i < tmplen; i++) {
1021 if (p_data->dscp_info.vendor_id ==
1022 hid_kb_numlock_on_list[i].version_id &&
1023 p_data->dscp_info.product_id ==
1024 hid_kb_numlock_on_list[i].product_id) {
1025 BTIF_TRACE_DEBUG(
1026 "%s() idx[%d] Enabling "
1027 "NUMLOCK for device :: %s",
1028 __func__, i, hid_kb_numlock_on_list[i].kb_name);
1029 /* Enable NUMLOCK by default so that numeric
1030 keys work from first keyboard connect */
1031 set_keylockstate(BTIF_HH_KEYSTATE_MASK_NUMLOCK, true);
1032 sync_lockstate_on_connect(p_dev);
1033 /* End Sync HID Keyboard lockstates */
1034 break;
1035 }
1036 }
1037 }
1038 break;
1039
1040 case BTA_HH_ADD_DEV_EVT:
1041 BTIF_TRACE_WARNING("BTA_HH_ADD_DEV_EVT: status = %d, handle = %d",
1042 p_data->dev_info.status, p_data->dev_info.handle);
1043 int i;
1044 for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
1045 if (btif_hh_cb.added_devices[i].bd_addr == p_data->dev_info.bda) {
1046 if (p_data->dev_info.status == BTA_HH_OK) {
1047 btif_hh_cb.added_devices[i].dev_handle = p_data->dev_info.handle;
1048 } else {
1049 btif_hh_cb.added_devices[i].bd_addr = RawAddress::kEmpty;
1050 btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE;
1051 }
1052 break;
1053 }
1054 }
1055 break;
1056 case BTA_HH_RMV_DEV_EVT:
1057 BTIF_TRACE_DEBUG("BTA_HH_RMV_DEV_EVT: status = %d, handle = %d",
1058 p_data->dev_info.status, p_data->dev_info.handle);
1059 VLOG(1) << "BTA_HH_RMV_DEV_EVT:bda = " << p_data->dev_info.bda;
1060 break;
1061
1062 case BTA_HH_VC_UNPLUG_EVT:
1063 BTIF_TRACE_DEBUG("BTA_HH_VC_UNPLUG_EVT: status = %d, handle = %d",
1064 p_data->dev_status.status, p_data->dev_status.handle);
1065 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
1066 btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
1067 if (p_dev != NULL) {
1068 VLOG(1) << "BTA_HH_VC_UNPLUG_EVT:bda = " << p_dev->bd_addr;
1069
1070 /* Stop the VUP timer */
1071 btif_hh_stop_vup_timer(&(p_dev->bd_addr));
1072 p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
1073 BTIF_TRACE_DEBUG("%s---Sending connection state change", __func__);
1074 HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr),
1075 p_dev->dev_status);
1076 BTIF_TRACE_DEBUG("%s---Removing HID bond", __func__);
1077 /* If it is locally initiated VUP or remote device has its major COD as
1078 Peripheral removed the bond.*/
1079 if (p_dev->local_vup || check_cod_hid(&(p_dev->bd_addr))) {
1080 p_dev->local_vup = false;
1081 BTA_DmRemoveDevice(p_dev->bd_addr);
1082 } else
1083 btif_hh_remove_device(p_dev->bd_addr);
1084 HAL_CBACK(bt_hh_callbacks, virtual_unplug_cb, &(p_dev->bd_addr),
1085 (bthh_status_t)p_data->dev_status.status);
1086 }
1087 break;
1088
1089 case BTA_HH_API_ERR_EVT:
1090 LOG_INFO(LOG_TAG, "BTA_HH API_ERR");
1091 break;
1092
1093 default:
1094 BTIF_TRACE_WARNING("%s: Unhandled event: %d", __func__, event);
1095 break;
1096 }
1097 }
1098
1099 /*******************************************************************************
1100 *
1101 * Function bte_hh_evt
1102 *
1103 * Description Switches context from BTE to BTIF for all HH events
1104 *
1105 * Returns void
1106 *
1107 ******************************************************************************/
1108
bte_hh_evt(tBTA_HH_EVT event,tBTA_HH * p_data)1109 void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
1110 bt_status_t status;
1111 int param_len = 0;
1112
1113 if (BTA_HH_ENABLE_EVT == event)
1114 param_len = sizeof(tBTA_HH_STATUS);
1115 else if (BTA_HH_OPEN_EVT == event)
1116 param_len = sizeof(tBTA_HH_CONN);
1117 else if (BTA_HH_DISABLE_EVT == event)
1118 param_len = sizeof(tBTA_HH_STATUS);
1119 else if (BTA_HH_CLOSE_EVT == event)
1120 param_len = sizeof(tBTA_HH_CBDATA);
1121 else if (BTA_HH_GET_DSCP_EVT == event)
1122 param_len = sizeof(tBTA_HH_DEV_DSCP_INFO);
1123 else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_RPT_EVT == event) ||
1124 (BTA_HH_GET_IDLE_EVT == event))
1125 param_len = sizeof(tBTA_HH_HSDATA);
1126 else if ((BTA_HH_SET_PROTO_EVT == event) || (BTA_HH_SET_RPT_EVT == event) ||
1127 (BTA_HH_VC_UNPLUG_EVT == event) || (BTA_HH_SET_IDLE_EVT == event))
1128 param_len = sizeof(tBTA_HH_CBDATA);
1129 else if ((BTA_HH_ADD_DEV_EVT == event) || (BTA_HH_RMV_DEV_EVT == event))
1130 param_len = sizeof(tBTA_HH_DEV_INFO);
1131 else if (BTA_HH_API_ERR_EVT == event)
1132 param_len = 0;
1133 /* switch context to btif task context (copy full union size for convenience)
1134 */
1135 status = btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event,
1136 (char*)p_data, param_len, NULL);
1137
1138 /* catch any failed context transfers */
1139 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
1140 }
1141
1142 /*******************************************************************************
1143 *
1144 * Function btif_hh_handle_evt
1145 *
1146 * Description Switches context for immediate callback
1147 *
1148 * Returns void
1149 *
1150 ******************************************************************************/
1151
btif_hh_handle_evt(uint16_t event,char * p_param)1152 static void btif_hh_handle_evt(uint16_t event, char* p_param) {
1153 RawAddress* bd_addr = (RawAddress*)p_param;
1154 BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
1155 int ret;
1156 switch (event) {
1157 case BTIF_HH_CONNECT_REQ_EVT: {
1158 ret = btif_hh_connect(bd_addr);
1159 if (ret == BT_STATUS_SUCCESS) {
1160 HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr,
1161 BTHH_CONN_STATE_CONNECTING);
1162 } else
1163 HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr,
1164 BTHH_CONN_STATE_DISCONNECTED);
1165 } break;
1166
1167 case BTIF_HH_DISCONNECT_REQ_EVT: {
1168 BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
1169 btif_hh_disconnect(bd_addr);
1170 HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr,
1171 BTHH_CONN_STATE_DISCONNECTING);
1172 } break;
1173
1174 case BTIF_HH_VUP_REQ_EVT: {
1175 BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
1176 ret = btif_hh_virtual_unplug(bd_addr);
1177 } break;
1178
1179 default: {
1180 BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __func__, event);
1181 } break;
1182 }
1183 }
1184
1185 /*******************************************************************************
1186 *
1187 * Function btif_hh_timer_timeout
1188 *
1189 * Description Process timer timeout
1190 *
1191 * Returns void
1192 ******************************************************************************/
btif_hh_timer_timeout(void * data)1193 void btif_hh_timer_timeout(void* data) {
1194 btif_hh_device_t* p_dev = (btif_hh_device_t*)data;
1195 tBTA_HH_EVT event = BTA_HH_VC_UNPLUG_EVT;
1196 tBTA_HH p_data;
1197 int param_len = sizeof(tBTA_HH_CBDATA);
1198
1199 BTIF_TRACE_DEBUG("%s", __func__);
1200 if (p_dev->dev_status != BTHH_CONN_STATE_CONNECTED) return;
1201
1202 memset(&p_data, 0, sizeof(tBTA_HH));
1203 p_data.dev_status.status = BTHH_ERR;
1204 p_data.dev_status.handle = p_dev->dev_handle;
1205
1206 /* switch context to btif task context */
1207 btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event, (char*)&p_data,
1208 param_len, NULL);
1209 }
1210
1211 /*******************************************************************************
1212 *
1213 * Function btif_hh_init
1214 *
1215 * Description initializes the hh interface
1216 *
1217 * Returns bt_status_t
1218 *
1219 ******************************************************************************/
init(bthh_callbacks_t * callbacks)1220 static bt_status_t init(bthh_callbacks_t* callbacks) {
1221 uint32_t i;
1222 BTIF_TRACE_EVENT("%s", __func__);
1223
1224 bt_hh_callbacks = callbacks;
1225 memset(&btif_hh_cb, 0, sizeof(btif_hh_cb));
1226 for (i = 0; i < BTIF_HH_MAX_HID; i++) {
1227 btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN;
1228 }
1229 /* Invoke the enable service API to the core to set the appropriate service_id
1230 */
1231 btif_enable_service(BTA_HID_SERVICE_ID);
1232 return BT_STATUS_SUCCESS;
1233 }
1234
1235 /*******************************************************************************
1236 *
1237 * Function connect
1238 *
1239 * Description connect to hid device
1240 *
1241 * Returns bt_status_t
1242 *
1243 ******************************************************************************/
connect(RawAddress * bd_addr)1244 static bt_status_t connect(RawAddress* bd_addr) {
1245 if (btif_hh_cb.status != BTIF_HH_DEV_CONNECTING) {
1246 btif_transfer_context(btif_hh_handle_evt, BTIF_HH_CONNECT_REQ_EVT,
1247 (char*)bd_addr, sizeof(RawAddress), NULL);
1248 return BT_STATUS_SUCCESS;
1249 } else
1250 return BT_STATUS_BUSY;
1251 }
1252
1253 /*******************************************************************************
1254 *
1255 * Function disconnect
1256 *
1257 * Description disconnect from hid device
1258 *
1259 * Returns bt_status_t
1260 *
1261 ******************************************************************************/
disconnect(RawAddress * bd_addr)1262 static bt_status_t disconnect(RawAddress* bd_addr) {
1263 CHECK_BTHH_INIT();
1264 BTIF_TRACE_EVENT("BTHH: %s", __func__);
1265 btif_hh_device_t* p_dev;
1266
1267 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1268 BTIF_TRACE_WARNING("%s: Error, HH status = %d", __func__,
1269 btif_hh_cb.status);
1270 return BT_STATUS_FAIL;
1271 }
1272 p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1273 if (p_dev != NULL) {
1274 return btif_transfer_context(btif_hh_handle_evt, BTIF_HH_DISCONNECT_REQ_EVT,
1275 (char*)bd_addr, sizeof(RawAddress), NULL);
1276 } else {
1277 BTIF_TRACE_WARNING("%s: Error, device not opened.", __func__);
1278 return BT_STATUS_FAIL;
1279 }
1280 }
1281
1282 /*******************************************************************************
1283 *
1284 * Function virtual_unplug
1285 *
1286 * Description Virtual UnPlug (VUP) the specified HID device.
1287 *
1288 * Returns bt_status_t
1289 *
1290 ******************************************************************************/
virtual_unplug(RawAddress * bd_addr)1291 static bt_status_t virtual_unplug(RawAddress* bd_addr) {
1292 CHECK_BTHH_INIT();
1293 BTIF_TRACE_EVENT("BTHH: %s", __func__);
1294 btif_hh_device_t* p_dev;
1295 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1296 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1297 return BT_STATUS_FAIL;
1298 }
1299 p_dev = btif_hh_find_dev_by_bda(*bd_addr);
1300 if (!p_dev) {
1301 BTIF_TRACE_ERROR("%s: Error, device %s not opened.", __func__,
1302 bd_addr->ToString().c_str());
1303 return BT_STATUS_FAIL;
1304 }
1305 btif_transfer_context(btif_hh_handle_evt, BTIF_HH_VUP_REQ_EVT, (char*)bd_addr,
1306 sizeof(RawAddress), NULL);
1307 return BT_STATUS_SUCCESS;
1308 }
1309
1310 /*******************************************************************************
1311 **
1312 ** Function get_idle_time
1313 **
1314 ** Description Get the HID idle time
1315 **
1316 ** Returns bt_status_t
1317 **
1318 *******************************************************************************/
get_idle_time(RawAddress * bd_addr)1319 static bt_status_t get_idle_time(RawAddress* bd_addr) {
1320 CHECK_BTHH_INIT();
1321
1322 BTIF_TRACE_DEBUG("%s: addr = %s", __func__, bd_addr->ToString().c_str());
1323
1324 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1325 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1326 return BT_STATUS_FAIL;
1327 }
1328
1329 btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1330 if (p_dev == NULL) return BT_STATUS_FAIL;
1331
1332 BTA_HhGetIdle(p_dev->dev_handle);
1333 return BT_STATUS_SUCCESS;
1334 }
1335
1336 /*******************************************************************************
1337 **
1338 ** Function set_idle_time
1339 **
1340 ** Description Set the HID idle time
1341 **
1342 ** Returns bt_status_t
1343 **
1344 *******************************************************************************/
set_idle_time(RawAddress * bd_addr,uint8_t idle_time)1345 static bt_status_t set_idle_time(RawAddress* bd_addr, uint8_t idle_time) {
1346 CHECK_BTHH_INIT();
1347
1348 BTIF_TRACE_DEBUG("%s: addr = %s, idle time = %d", __func__,
1349 bd_addr->ToString().c_str(), idle_time);
1350
1351 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1352 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1353 return BT_STATUS_FAIL;
1354 }
1355
1356 btif_hh_device_t* p_dev = p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1357 if (p_dev == NULL) {
1358 BTIF_TRACE_WARNING("%s: addr = %s not opened", __func__,
1359 bd_addr->ToString().c_str());
1360 return BT_STATUS_FAIL;
1361 }
1362
1363 BTA_HhSetIdle(p_dev->dev_handle, idle_time);
1364 return BT_STATUS_SUCCESS;
1365 }
1366
1367 /*******************************************************************************
1368 *
1369 * Function set_info
1370 *
1371 * Description Set the HID device descriptor for the specified HID device.
1372 *
1373 * Returns bt_status_t
1374 *
1375 ******************************************************************************/
set_info(RawAddress * bd_addr,bthh_hid_info_t hid_info)1376 static bt_status_t set_info(RawAddress* bd_addr, bthh_hid_info_t hid_info) {
1377 CHECK_BTHH_INIT();
1378 tBTA_HH_DEV_DSCP_INFO dscp_info;
1379
1380 VLOG(1) << __func__ << " BTHH: addr = " << *bd_addr;
1381 BTIF_TRACE_DEBUG(
1382 "BTHH: %s: sub_class = 0x%02x, app_id = %d, vendor_id = 0x%04x, "
1383 "product_id = 0x%04x, version= 0x%04x",
1384 __func__, hid_info.sub_class, hid_info.app_id, hid_info.vendor_id,
1385 hid_info.product_id, hid_info.version);
1386
1387 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1388 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1389 return BT_STATUS_FAIL;
1390 }
1391
1392 memset(&dscp_info, 0, sizeof(dscp_info));
1393 dscp_info.vendor_id = hid_info.vendor_id;
1394 dscp_info.product_id = hid_info.product_id;
1395 dscp_info.version = hid_info.version;
1396 dscp_info.ctry_code = hid_info.ctry_code;
1397
1398 dscp_info.descriptor.dl_len = hid_info.dl_len;
1399 dscp_info.descriptor.dsc_list =
1400 (uint8_t*)osi_malloc(dscp_info.descriptor.dl_len);
1401 memcpy(dscp_info.descriptor.dsc_list, &(hid_info.dsc_list), hid_info.dl_len);
1402
1403 if (btif_hh_add_added_dev(*bd_addr, hid_info.attr_mask)) {
1404 BTA_HhAddDev(*bd_addr, hid_info.attr_mask, hid_info.sub_class,
1405 hid_info.app_id, dscp_info);
1406 }
1407
1408 osi_free_and_reset((void**)&dscp_info.descriptor.dsc_list);
1409
1410 return BT_STATUS_SUCCESS;
1411 }
1412
1413 /*******************************************************************************
1414 *
1415 * Function get_protocol
1416 *
1417 * Description Get the HID proto mode.
1418 *
1419 * Returns bt_status_t
1420 *
1421 ******************************************************************************/
get_protocol(RawAddress * bd_addr,UNUSED_ATTR bthh_protocol_mode_t protocolMode)1422 static bt_status_t get_protocol(RawAddress* bd_addr,
1423 UNUSED_ATTR bthh_protocol_mode_t protocolMode) {
1424 CHECK_BTHH_INIT();
1425
1426 VLOG(1) << __func__ << " BTHH: addr = " << *bd_addr;
1427
1428 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1429 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1430 return BT_STATUS_FAIL;
1431 }
1432
1433 btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1434 if (!p_dev) return BT_STATUS_FAIL;
1435
1436 BTA_HhGetProtoMode(p_dev->dev_handle);
1437 return BT_STATUS_SUCCESS;
1438 }
1439
1440 /*******************************************************************************
1441 *
1442 * Function set_protocol
1443 *
1444 * Description Set the HID proto mode.
1445 *
1446 * Returns bt_status_t
1447 *
1448 ******************************************************************************/
set_protocol(RawAddress * bd_addr,bthh_protocol_mode_t protocolMode)1449 static bt_status_t set_protocol(RawAddress* bd_addr,
1450 bthh_protocol_mode_t protocolMode) {
1451 CHECK_BTHH_INIT();
1452 btif_hh_device_t* p_dev;
1453 uint8_t proto_mode = protocolMode;
1454
1455 VLOG(1) << __func__ << " BTHH: proto_mod=" << protocolMode
1456 << " addr = " << *bd_addr;
1457
1458 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1459 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1460 return BT_STATUS_FAIL;
1461 }
1462
1463 p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1464 if (p_dev == NULL) {
1465 LOG(WARNING) << " Error, device" << *bd_addr << " not opened";
1466 return BT_STATUS_FAIL;
1467 } else if (protocolMode != BTA_HH_PROTO_RPT_MODE &&
1468 protocolMode != BTA_HH_PROTO_BOOT_MODE) {
1469 BTIF_TRACE_WARNING("%s: Error, device proto_mode = %d.", __func__,
1470 proto_mode);
1471 return BT_STATUS_FAIL;
1472 } else {
1473 BTA_HhSetProtoMode(p_dev->dev_handle, protocolMode);
1474 }
1475
1476 return BT_STATUS_SUCCESS;
1477 }
1478
1479 /*******************************************************************************
1480 *
1481 * Function get_report
1482 *
1483 * Description Send a GET_REPORT to HID device.
1484 *
1485 * Returns bt_status_t
1486 *
1487 ******************************************************************************/
get_report(RawAddress * bd_addr,bthh_report_type_t reportType,uint8_t reportId,int bufferSize)1488 static bt_status_t get_report(RawAddress* bd_addr,
1489 bthh_report_type_t reportType, uint8_t reportId,
1490 int bufferSize) {
1491 CHECK_BTHH_INIT();
1492 btif_hh_device_t* p_dev;
1493
1494 VLOG(1) << __func__ << " BTHH: r_type = " << reportType
1495 << ", rpt_id = " << reportId << ", buf_size = " << bufferSize
1496 << " addr = " << *bd_addr;
1497
1498 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1499 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1500 return BT_STATUS_FAIL;
1501 }
1502
1503 p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1504 if (p_dev == NULL) {
1505 LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
1506 return BT_STATUS_FAIL;
1507 } else if (((int)reportType) <= BTA_HH_RPTT_RESRV ||
1508 ((int)reportType) > BTA_HH_RPTT_FEATURE) {
1509 LOG(ERROR) << " Error, report type=" << +reportType << " not supported";
1510 return BT_STATUS_FAIL;
1511 } else {
1512 BTA_HhGetReport(p_dev->dev_handle, reportType, reportId, bufferSize);
1513 }
1514
1515 return BT_STATUS_SUCCESS;
1516 }
1517
1518 /*******************************************************************************
1519 *
1520 * Function set_report
1521 *
1522 * Description Send a SET_REPORT to HID device.
1523 *
1524 * Returns bt_status_t
1525 *
1526 ******************************************************************************/
set_report(RawAddress * bd_addr,bthh_report_type_t reportType,char * report)1527 static bt_status_t set_report(RawAddress* bd_addr,
1528 bthh_report_type_t reportType, char* report) {
1529 CHECK_BTHH_INIT();
1530 btif_hh_device_t* p_dev;
1531
1532 VLOG(1) << __func__ << " BTHH: reportType=" << reportType
1533 << " addr=" << *bd_addr;
1534
1535 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1536 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1537 return BT_STATUS_FAIL;
1538 }
1539
1540 p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1541 if (p_dev == NULL) {
1542 LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
1543 return BT_STATUS_FAIL;
1544 } else if (((int)reportType) <= BTA_HH_RPTT_RESRV ||
1545 ((int)reportType) > BTA_HH_RPTT_FEATURE) {
1546 LOG(ERROR) << " Error, report type=" << +reportType << " not supported";
1547 return BT_STATUS_FAIL;
1548 } else {
1549 int hex_bytes_filled;
1550 size_t len = (strlen(report) + 1) / 2;
1551 uint8_t* hexbuf = (uint8_t*)osi_calloc(len);
1552
1553 /* Build a SetReport data buffer */
1554 // TODO
1555 hex_bytes_filled = ascii_2_hex(report, len, hexbuf);
1556 LOG_INFO(LOG_TAG, "Hex bytes filled, hex value: %d", hex_bytes_filled);
1557 if (hex_bytes_filled) {
1558 BT_HDR* p_buf = create_pbuf(hex_bytes_filled, hexbuf);
1559 if (p_buf == NULL) {
1560 BTIF_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, len = %d",
1561 __func__, hex_bytes_filled);
1562 osi_free(hexbuf);
1563 return BT_STATUS_FAIL;
1564 }
1565 BTA_HhSetReport(p_dev->dev_handle, reportType, p_buf);
1566 osi_free(hexbuf);
1567 return BT_STATUS_SUCCESS;
1568 }
1569 osi_free(hexbuf);
1570 return BT_STATUS_FAIL;
1571 }
1572 }
1573
1574 /*******************************************************************************
1575 *
1576 * Function send_data
1577 *
1578 * Description Send a SEND_DATA to HID device.
1579 *
1580 * Returns bt_status_t
1581 *
1582 ******************************************************************************/
send_data(RawAddress * bd_addr,char * data)1583 static bt_status_t send_data(RawAddress* bd_addr, char* data) {
1584 CHECK_BTHH_INIT();
1585 btif_hh_device_t* p_dev;
1586
1587 VLOG(1) << __func__ << " addr=" << *bd_addr;
1588
1589 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1590 BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
1591 return BT_STATUS_FAIL;
1592 }
1593
1594 p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
1595 if (p_dev == NULL) {
1596 LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
1597 return BT_STATUS_FAIL;
1598 }
1599
1600 else {
1601 int hex_bytes_filled;
1602 size_t len = (strlen(data) + 1) / 2;
1603 uint8_t* hexbuf = (uint8_t*)osi_calloc(len);
1604
1605 /* Build a SendData data buffer */
1606 hex_bytes_filled = ascii_2_hex(data, len, hexbuf);
1607 BTIF_TRACE_ERROR("Hex bytes filled, hex value: %d, %d", hex_bytes_filled,
1608 len);
1609
1610 if (hex_bytes_filled) {
1611 BT_HDR* p_buf = create_pbuf(hex_bytes_filled, hexbuf);
1612 if (p_buf == NULL) {
1613 BTIF_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, len = %d",
1614 __func__, hex_bytes_filled);
1615 osi_free(hexbuf);
1616 return BT_STATUS_FAIL;
1617 }
1618 p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
1619 BTA_HhSendData(p_dev->dev_handle, *bd_addr, p_buf);
1620 osi_free(hexbuf);
1621 return BT_STATUS_SUCCESS;
1622 }
1623 osi_free(hexbuf);
1624 return BT_STATUS_FAIL;
1625 }
1626 }
1627
1628 /*******************************************************************************
1629 *
1630 * Function cleanup
1631 *
1632 * Description Closes the HH interface
1633 *
1634 * Returns bt_status_t
1635 *
1636 ******************************************************************************/
cleanup(void)1637 static void cleanup(void) {
1638 BTIF_TRACE_EVENT("%s", __func__);
1639 btif_hh_device_t* p_dev;
1640 int i;
1641 if (btif_hh_cb.status == BTIF_HH_DISABLED) {
1642 BTIF_TRACE_WARNING("%s: HH disabling or disabled already, status = %d",
1643 __func__, btif_hh_cb.status);
1644 return;
1645 }
1646 if (bt_hh_callbacks) {
1647 btif_hh_cb.status = BTIF_HH_DISABLING;
1648 /* update flag, not to enable hid device service now as BT is switching off
1649 */
1650 btif_hh_cb.service_dereg_active = FALSE;
1651 btif_disable_service(BTA_HID_SERVICE_ID);
1652 bt_hh_callbacks = NULL;
1653 }
1654 for (i = 0; i < BTIF_HH_MAX_HID; i++) {
1655 p_dev = &btif_hh_cb.devices[i];
1656 if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->fd >= 0) {
1657 BTIF_TRACE_DEBUG("%s: Closing uhid fd = %d", __func__, p_dev->fd);
1658 if (p_dev->fd >= 0) {
1659 bta_hh_co_destroy(p_dev->fd);
1660 p_dev->fd = -1;
1661 }
1662 p_dev->hh_keep_polling = 0;
1663 p_dev->hh_poll_thread_id = -1;
1664 }
1665 }
1666
1667 }
1668
1669 static const bthh_interface_t bthhInterface = {
1670 sizeof(bthhInterface),
1671 init,
1672 connect,
1673 disconnect,
1674 virtual_unplug,
1675 set_info,
1676 get_protocol,
1677 set_protocol,
1678 get_idle_time,
1679 set_idle_time,
1680 get_report,
1681 set_report,
1682 send_data,
1683 cleanup,
1684 };
1685
1686 /*******************************************************************************
1687 *
1688 * Function btif_hh_execute_service
1689 *
1690 * Description Initializes/Shuts down the service
1691 *
1692 * Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1693 *
1694 ******************************************************************************/
btif_hh_execute_service(bool b_enable)1695 bt_status_t btif_hh_execute_service(bool b_enable) {
1696 if (b_enable) {
1697 /* Enable and register with BTA-HH */
1698 BTA_HhEnable(BTUI_HH_SECURITY, bte_hh_evt);
1699 } else {
1700 /* Disable HH */
1701 BTA_HhDisable();
1702 }
1703 return BT_STATUS_SUCCESS;
1704 }
1705
1706 /*******************************************************************************
1707 *
1708 * Function btif_hh_get_interface
1709 *
1710 * Description Get the hh callback interface
1711 *
1712 * Returns bthh_interface_t
1713 *
1714 ******************************************************************************/
btif_hh_get_interface()1715 const bthh_interface_t* btif_hh_get_interface() {
1716 BTIF_TRACE_EVENT("%s", __func__);
1717 return &bthhInterface;
1718 }
1719