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