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