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