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/include/btif_hh.h"
31 
32 #include <bluetooth/log.h>
33 #include <com_android_bluetooth_flags.h>
34 
35 #include <cstdint>
36 
37 #include "bta_hh_co.h"
38 #include "bta_sec_api.h"
39 #include "btif/include/btif_common.h"
40 #include "btif/include/btif_metrics_logging.h"
41 #include "btif/include/btif_profile_storage.h"
42 #include "btif/include/btif_storage.h"
43 #include "btif/include/btif_util.h"
44 #include "include/hardware/bt_hh.h"
45 #include "main/shim/dumpsys.h"
46 #include "os/log.h"
47 #include "osi/include/allocator.h"
48 #include "stack/include/acl_api.h"
49 #include "stack/include/bt_hdr.h"
50 #include "stack/include/bt_uuid16.h"
51 #include "stack/include/btm_ble_api.h"
52 #include "stack/include/hidh_api.h"
53 #include "types/raw_address.h"
54 
55 #define COD_HID_KEYBOARD 0x0540
56 #define COD_HID_POINTING 0x0580
57 #define COD_HID_COMBO 0x05C0
58 
59 #define HID_REPORT_CAPSLOCK 0x39
60 #define HID_REPORT_NUMLOCK 0x53
61 #define HID_REPORT_SCROLLLOCK 0x47
62 
63 // For Apple Magic Mouse
64 #define MAGICMOUSE_VENDOR_ID 0x05ac
65 #define MAGICMOUSE_PRODUCT_ID 0x030d
66 
67 #define LOGITECH_KB_MX5500_VENDOR_ID 0x046D
68 #define LOGITECH_KB_MX5500_PRODUCT_ID 0xB30B
69 
70 using namespace bluetooth;
71 
72 static int btif_hh_keylockstates = 0;  // The current key state of each key
73 
74 #define BTIF_TIMEOUT_VUP_MS (3 * 1000)
75 
76 /* HH request events */
77 typedef enum {
78   BTIF_HH_CONNECT_REQ_EVT = 0,
79   BTIF_HH_DISCONNECT_REQ_EVT,
80   BTIF_HH_VUP_REQ_EVT
81 } btif_hh_req_evt_t;
82 
83 /*******************************************************************************
84  *  Constants & Macros
85  ******************************************************************************/
86 
87 /*******************************************************************************
88  *  Local type definitions
89  ******************************************************************************/
90 
91 typedef struct hid_kb_list {
92   uint16_t product_id;
93   uint16_t version_id;
94   const char* kb_name;
95 } tHID_KB_LIST;
96 
97 /*******************************************************************************
98  *  Static variables
99  ******************************************************************************/
100 btif_hh_cb_t btif_hh_cb;
101 
102 static bthh_callbacks_t* bt_hh_callbacks = NULL;
103 static bthh_profile_enable_t bt_hh_enable_type = {.hidp_enabled = true,
104                                                   .hogp_enabled = true};
105 
106 /* List of HID keyboards for which the NUMLOCK state needs to be
107  * turned ON by default. Add devices to this list to apply the
108  * NUMLOCK state toggle on fpr first connect.*/
109 static tHID_KB_LIST hid_kb_numlock_on_list[] = {{LOGITECH_KB_MX5500_PRODUCT_ID,
110                                                  LOGITECH_KB_MX5500_VENDOR_ID,
111                                                  "Logitech MX5500 Keyboard"}};
112 
113 #define CHECK_BTHH_INIT()                 \
114   do {                                    \
115     if (bt_hh_callbacks == NULL) {        \
116       log::error("BTHH not initialized"); \
117       return BT_STATUS_NOT_READY;         \
118     }                                     \
119   } while (0)
120 
121 #define BTHH_CHECK_NOT_DISABLED()                                           \
122   do {                                                                      \
123     if (btif_hh_cb.status == BTIF_HH_DISABLED) {                            \
124       log::error("HH status = {}", btif_hh_status_text(btif_hh_cb.status)); \
125       return BT_STATUS_UNEXPECTED_STATE;                                    \
126     }                                                                       \
127   } while (0)
128 
129 #define BTHH_LOG_UNKNOWN_LINK(_link_spec) \
130   log::error("Unknown link: {}", (_link_spec).ToRedactedStringForLogging())
131 #define BTHH_LOG_LINK(_link_spec) \
132   log::verbose("link spec: {}", (_link_spec).ToRedactedStringForLogging())
133 
134 #define BTHH_STATE_UPDATE(_link_spec, _state)                                \
135   do {                                                                       \
136     log::verbose("link spec: {} state: {}",                                  \
137                  (_link_spec).ToRedactedStringForLogging(),                  \
138                  bthh_connection_state_text(_state));                        \
139     HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(_link_spec).addrt.bda, \
140               (_link_spec).addrt.type, (_link_spec).transport, (_state));    \
141   } while (0)
142 
143 /*******************************************************************************
144  *  Static functions
145  ******************************************************************************/
146 
147 static void btif_hh_transport_select(tAclLinkSpec& link_spec);
148 /*******************************************************************************
149  *  Externs
150  ******************************************************************************/
151 bool check_cod(const RawAddress* remote_bdaddr, uint32_t cod);
152 bool check_cod_hid(const RawAddress* remote_bdaddr);
153 bool check_cod_hid_major(const RawAddress& bd_addr, uint32_t cod);
154 void bta_hh_co_close(btif_hh_device_t* p_dev);
155 void bta_hh_co_send_hid_info(btif_hh_device_t* p_dev, const char* dev_name,
156                              uint16_t vendor_id, uint16_t product_id,
157                              uint16_t version, uint8_t ctry_code, int dscp_len,
158                              uint8_t* p_dscp);
159 void bta_hh_co_write(int fd, uint8_t* rpt, uint16_t len);
160 static void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data);
161 void btif_dm_hh_open_failed(RawAddress* bdaddr);
162 void btif_hd_service_registration();
163 void btif_hh_timer_timeout(void* data);
164 
165 /*******************************************************************************
166  *  Functions
167  ******************************************************************************/
168 
get_keylockstates()169 static int get_keylockstates() { return btif_hh_keylockstates; }
170 
set_keylockstate(int keymask,bool isSet)171 static void set_keylockstate(int keymask, bool isSet) {
172   if (isSet) btif_hh_keylockstates |= keymask;
173 }
174 
175 /*******************************************************************************
176  *
177  * Function         toggle_os_keylockstates
178  *
179  * Description      Function to toggle the keyboard lock states managed by the
180  linux.
181  *                  This function is used in by two call paths
182  *                  (1) if the lock state change occurred from an onscreen
183  keyboard,
184  *                  this function is called to update the lock state maintained
185                     for the HID keyboard(s)
186  *                  (2) if a HID keyboard is disconnected and reconnected,
187  *                  this function is called to update the lock state maintained
188                     for the HID keyboard(s)
189  * Returns          void
190  ******************************************************************************/
191 
toggle_os_keylockstates(int fd,int changedlockstates)192 static void toggle_os_keylockstates(int fd, int changedlockstates) {
193   log::verbose("fd = {}, changedlockstates = 0x{:x}", fd, changedlockstates);
194   uint8_t hidreport[9];
195   int reportIndex;
196   memset(hidreport, 0, 9);
197   hidreport[0] = 1;
198   reportIndex = 4;
199 
200   if (changedlockstates & BTIF_HH_KEYSTATE_MASK_CAPSLOCK) {
201     log::verbose("Setting CAPSLOCK");
202     hidreport[reportIndex++] = (uint8_t)HID_REPORT_CAPSLOCK;
203   }
204 
205   if (changedlockstates & BTIF_HH_KEYSTATE_MASK_NUMLOCK) {
206     log::verbose("Setting NUMLOCK");
207     hidreport[reportIndex++] = (uint8_t)HID_REPORT_NUMLOCK;
208   }
209 
210   if (changedlockstates & BTIF_HH_KEYSTATE_MASK_SCROLLLOCK) {
211     log::verbose("Setting SCROLLLOCK");
212     hidreport[reportIndex++] = (uint8_t)HID_REPORT_SCROLLLOCK;
213   }
214 
215   log::verbose("Writing hidreport #1 to os:");
216   log::verbose("| {:x} {:x} {:x}", hidreport[0], hidreport[1], hidreport[2]);
217   log::verbose("| {:x} {:x} {:x}", hidreport[3], hidreport[4], hidreport[5]);
218   log::verbose("| {:x} {:x} {:x}", hidreport[6], hidreport[7], hidreport[8]);
219   bta_hh_co_write(fd, hidreport, sizeof(hidreport));
220   usleep(200000);
221   memset(hidreport, 0, 9);
222   hidreport[0] = 1;
223   log::verbose("Writing hidreport #2 to os:");
224   log::verbose("| {:x} {:x} {:x}", hidreport[0], hidreport[1], hidreport[2]);
225   log::verbose("| {:x} {:x} {:x}", hidreport[3], hidreport[4], hidreport[5]);
226   log::verbose("| {:x} {:x} {:x}", hidreport[6], hidreport[7], hidreport[8]);
227   bta_hh_co_write(fd, hidreport, sizeof(hidreport));
228 }
229 
230 /*******************************************************************************
231  *
232  * Function         create_pbuf
233  *
234  * Description      Helper function to create p_buf for send_data or set_report
235  *
236  ******************************************************************************/
create_pbuf(uint16_t len,uint8_t * data)237 static BT_HDR* create_pbuf(uint16_t len, uint8_t* data) {
238   BT_HDR* p_buf = (BT_HDR*)osi_malloc(len + BTA_HH_MIN_OFFSET + sizeof(BT_HDR));
239   uint8_t* pbuf_data;
240 
241   p_buf->len = len;
242   p_buf->offset = BTA_HH_MIN_OFFSET;
243 
244   pbuf_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
245   memcpy(pbuf_data, data, len);
246 
247   return p_buf;
248 }
249 
250 /*******************************************************************************
251  *
252  * Function         update_keyboard_lockstates
253  *
254  * Description      Sends a report to the keyboard to set the lock states of
255  *                  keys.
256  *
257  ******************************************************************************/
update_keyboard_lockstates(btif_hh_device_t * p_dev)258 static void update_keyboard_lockstates(btif_hh_device_t* p_dev) {
259   uint8_t len = 2; /* reportid + 1 byte report*/
260   BT_HDR* p_buf;
261   uint8_t data[] = {0x01, /* report id */
262                     static_cast<uint8_t>(btif_hh_keylockstates)}; /* keystate */
263 
264   /* Set report for other keyboards */
265   log::verbose("setting report on dev_handle {} to 0x{:x}", p_dev->dev_handle,
266                btif_hh_keylockstates);
267 
268   /* Get SetReport buffer */
269   p_buf = create_pbuf(len, data);
270   if (p_buf != NULL) {
271     p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
272     BTA_HhSendData(p_dev->dev_handle, p_dev->link_spec, p_buf);
273   }
274 }
275 
276 /*******************************************************************************
277  *
278  * Function         sync_lockstate_on_connect
279  *
280  * Description      Function to update the keyboard lock states managed by the
281  *                  OS when a HID keyboard is connected or disconnected and
282  *                  reconnected
283  *
284  * Returns          void
285  ******************************************************************************/
sync_lockstate_on_connect(btif_hh_device_t * p_dev)286 static void sync_lockstate_on_connect(btif_hh_device_t* p_dev) {
287   int keylockstates;
288 
289   log::verbose("Syncing keyboard lock states after reconnect...");
290   /*If the device is connected, update keyboard state */
291   update_keyboard_lockstates(p_dev);
292 
293   /*Check if the lockstate of caps,scroll,num is set.
294    If so, send a report to the kernel
295   so the lockstate is in sync */
296   keylockstates = get_keylockstates();
297   if (keylockstates) {
298     log::verbose(
299         "Sending hid report to kernel indicating lock key state 0x{:x}",
300         keylockstates);
301     usleep(200000);
302     toggle_os_keylockstates(p_dev->uhid.fd, keylockstates);
303   } else {
304     log::verbose(
305         "NOT sending hid report to kernel indicating lock key state 0x{:x}",
306         keylockstates);
307   }
308 }
309 
310 /*******************************************************************************
311  *
312  * Function         btif_hh_find_added_dev
313  *
314  * Description      Return the added device pointer of the specified link spec
315  *
316  * Returns          Added device entry
317  ******************************************************************************/
btif_hh_find_added_dev(const tAclLinkSpec & link_spec)318 btif_hh_added_device_t* btif_hh_find_added_dev(const tAclLinkSpec& link_spec) {
319   for (int i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
320     btif_hh_added_device_t* added_dev = &btif_hh_cb.added_devices[i];
321     if (added_dev->link_spec == link_spec) {
322       return added_dev;
323     }
324   }
325   return NULL;
326 }
327 
328 /*******************************************************************************
329  *
330  * Function         btif_hh_find_connected_dev_by_handle
331  *
332  * Description      Return the connected device pointer of the specified device
333  *                  handle
334  *
335  * Returns          Device entry pointer in the device table
336  ******************************************************************************/
btif_hh_find_connected_dev_by_handle(uint8_t handle)337 btif_hh_device_t* btif_hh_find_connected_dev_by_handle(uint8_t handle) {
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].dev_handle == handle) {
342       return &btif_hh_cb.devices[i];
343     }
344   }
345   return NULL;
346 }
347 
348 /*******************************************************************************
349  *
350  * Function         btif_hh_find_dev_by_handle
351  *
352  * Description      Return the device pointer of the specified device handle
353  *
354  * Returns          Device entry pointer in the device table
355  ******************************************************************************/
btif_hh_find_dev_by_handle(uint8_t handle)356 btif_hh_device_t* btif_hh_find_dev_by_handle(uint8_t handle) {
357   for (int i = 0; i < BTIF_HH_MAX_HID; i++) {
358     btif_hh_device_t* p_dev = &btif_hh_cb.devices[i];
359     if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN &&
360         p_dev->dev_handle == handle) {
361       return p_dev;
362     }
363   }
364   return nullptr;
365 }
366 
367 /*******************************************************************************
368  *
369  * Function         btif_hh_find_empty_dev
370  *
371  * Description      Return an empty device
372  *
373  * Returns          Device entry pointer in the device table
374  ******************************************************************************/
btif_hh_find_empty_dev(void)375 btif_hh_device_t* btif_hh_find_empty_dev(void) {
376   for (int i = 0; i < BTIF_HH_MAX_HID; i++) {
377     btif_hh_device_t* p_dev = &btif_hh_cb.devices[i];
378     if (p_dev->dev_status == BTHH_CONN_STATE_UNKNOWN) {
379       return p_dev;
380     }
381   }
382   return nullptr;
383 }
384 
385 /*******************************************************************************
386  *
387  * Function         btif_hh_find_dev_by_link_spec
388  *
389  * Description      Return the device pointer of the specified ACL link
390  *                  specification.
391  *
392  * Returns          Device entry pointer in the device table
393  ******************************************************************************/
btif_hh_find_dev_by_link_spec(const tAclLinkSpec & link_spec)394 static btif_hh_device_t* btif_hh_find_dev_by_link_spec(
395     const tAclLinkSpec& link_spec) {
396   uint32_t i;
397   for (i = 0; i < BTIF_HH_MAX_HID; i++) {
398     if (btif_hh_cb.devices[i].dev_status != BTHH_CONN_STATE_UNKNOWN &&
399         btif_hh_cb.devices[i].link_spec == link_spec) {
400       return &btif_hh_cb.devices[i];
401     }
402   }
403   return NULL;
404 }
405 
406 /*******************************************************************************
407  *
408  * Function         btif_hh_find_connected_dev_by_link_spec
409  *
410  * Description      Return the connected device pointer of the specified ACL
411  *                  link specification.
412  *
413  * Returns          Device entry pointer in the device table
414  ******************************************************************************/
btif_hh_find_connected_dev_by_link_spec(const tAclLinkSpec & link_spec)415 static btif_hh_device_t* btif_hh_find_connected_dev_by_link_spec(
416     const tAclLinkSpec& link_spec) {
417   uint32_t i;
418   for (i = 0; i < BTIF_HH_MAX_HID; i++) {
419     if (btif_hh_cb.devices[i].dev_status == BTHH_CONN_STATE_CONNECTED &&
420         btif_hh_cb.devices[i].link_spec == link_spec) {
421       return &btif_hh_cb.devices[i];
422     }
423   }
424   return NULL;
425 }
426 
427 /*******************************************************************************
428  *
429  * Function      btif_hh_stop_vup_timer
430  *
431  * Description  stop vitual unplug timer
432  *
433  * Returns      void
434  ******************************************************************************/
btif_hh_stop_vup_timer(const tAclLinkSpec & link_spec)435 static void btif_hh_stop_vup_timer(const tAclLinkSpec& link_spec) {
436   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_link_spec(link_spec);
437 
438   if (p_dev != NULL) {
439     log::verbose("stop VUP timer");
440     alarm_free(p_dev->vup_timer);
441     p_dev->vup_timer = NULL;
442   }
443 }
444 /*******************************************************************************
445  *
446  * Function      btif_hh_start_vup_timer
447  *
448  * Description  start virtual unplug timer
449  *
450  * Returns      void
451  ******************************************************************************/
btif_hh_start_vup_timer(const tAclLinkSpec & link_spec)452 static void btif_hh_start_vup_timer(const tAclLinkSpec& link_spec) {
453   log::verbose("");
454 
455   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_link_spec(link_spec);
456   log::assert_that(p_dev != NULL, "assert failed: p_dev != NULL");
457 
458   alarm_free(p_dev->vup_timer);
459   p_dev->vup_timer = alarm_new("btif_hh.vup_timer");
460   alarm_set_on_mloop(p_dev->vup_timer, BTIF_TIMEOUT_VUP_MS,
461                      btif_hh_timer_timeout, p_dev);
462 }
463 
hh_get_state_on_disconnect(tAclLinkSpec & link_spec)464 static bthh_connection_state_t hh_get_state_on_disconnect(
465     tAclLinkSpec& link_spec) {
466   if (!com::android::bluetooth::flags::allow_switching_hid_and_hogp()) {
467     return BTHH_CONN_STATE_ACCEPTING;
468   }
469 
470   btif_hh_added_device_t* added_dev = btif_hh_find_added_dev(link_spec);
471   if (added_dev != nullptr) {
472     return added_dev->reconnect_allowed ? BTHH_CONN_STATE_ACCEPTING
473                                         : BTHH_CONN_STATE_DISCONNECTED;
474   } else {
475     return BTHH_CONN_STATE_DISCONNECTED;
476   }
477 }
478 
hh_connect_complete(uint8_t handle,tAclLinkSpec & link_spec,BTIF_HH_STATUS status)479 static void hh_connect_complete(uint8_t handle, tAclLinkSpec& link_spec,
480                                 BTIF_HH_STATUS status) {
481   bthh_connection_state_t state = BTHH_CONN_STATE_CONNECTED;
482   btif_hh_cb.status = status;
483 
484   if (status != BTIF_HH_DEV_CONNECTED) {
485     state = BTHH_CONN_STATE_DISCONNECTED;
486     BTA_HhClose(handle);
487   }
488   BTHH_STATE_UPDATE(link_spec, state);
489 }
490 
hh_open_handler(tBTA_HH_CONN & conn)491 static void hh_open_handler(tBTA_HH_CONN& conn) {
492   log::debug("link spec = {}, status = {}, handle = {}",
493              conn.link_spec.ToRedactedStringForLogging(), conn.status,
494              conn.handle);
495 
496   if (com::android::bluetooth::flags::allow_switching_hid_and_hogp()) {
497     // Initialize with disconnected/accepting state based on reconnection policy
498     bthh_connection_state_t dev_status =
499         hh_get_state_on_disconnect(conn.link_spec);
500 
501     // Use current state if the device instance already exists
502     btif_hh_device_t* p_dev = btif_hh_find_dev_by_link_spec(conn.link_spec);
503     if (p_dev != nullptr) {
504       log::debug("Device instance found: {}, state: {}",
505                  p_dev->link_spec.ToRedactedStringForLogging(),
506                  bthh_connection_state_text(p_dev->dev_status));
507       dev_status = p_dev->dev_status;
508     }
509 
510     if (btif_hh_cb.pending_link_spec == conn.link_spec) {
511       log::verbose("Device connection was pending for: {}, status: {}",
512                    conn.link_spec.ToRedactedStringForLogging(),
513                    btif_hh_status_text(btif_hh_cb.status));
514       dev_status = BTHH_CONN_STATE_CONNECTING;
515     }
516 
517     if (dev_status != BTHH_CONN_STATE_ACCEPTING &&
518         dev_status != BTHH_CONN_STATE_CONNECTING) {
519       log::warn("Reject Incoming HID Connection, device: {}, state: {}",
520                 conn.link_spec.ToRedactedStringForLogging(),
521                 bthh_connection_state_text(dev_status));
522       log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum::
523                                    HIDH_COUNT_INCOMING_CONNECTION_REJECTED,
524                                1);
525 
526       if (p_dev != nullptr) {
527         p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
528       }
529 
530       if (!com::android::bluetooth::flags::suppress_hid_rejection_broadcast()) {
531         hh_connect_complete(conn.handle, conn.link_spec,
532                             BTIF_HH_DEV_DISCONNECTED);
533         return;
534       }
535       BTA_HhClose(conn.handle);
536       return;
537     }
538   }
539 
540   if (!com::android::bluetooth::flags::allow_switching_hid_and_hogp()) {
541     BTHH_STATE_UPDATE(conn.link_spec, BTHH_CONN_STATE_CONNECTING);
542   }
543 
544   btif_hh_cb.pending_link_spec = {};
545 
546   if (conn.status != BTA_HH_OK) {
547     btif_dm_hh_open_failed(&conn.link_spec.addrt.bda);
548     btif_hh_device_t* p_dev = btif_hh_find_dev_by_link_spec(conn.link_spec);
549     if (p_dev != NULL) {
550       btif_hh_stop_vup_timer(p_dev->link_spec);
551 
552       p_dev->dev_status = hh_get_state_on_disconnect(p_dev->link_spec);
553     }
554     hh_connect_complete(conn.handle, conn.link_spec, BTIF_HH_DEV_DISCONNECTED);
555     return;
556   }
557 
558   /* Initialize device driver */
559   if (!bta_hh_co_open(conn.handle, conn.sub_class, conn.attr_mask, conn.app_id,
560                       conn.link_spec)) {
561     log::warn("Failed to find the uhid driver");
562     hh_connect_complete(conn.handle, conn.link_spec, BTIF_HH_DEV_DISCONNECTED);
563     return;
564   }
565 
566   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_handle(conn.handle);
567   if (p_dev == NULL) {
568     /* The connect request must have come from device side and exceeded the
569      * connected HID device number. */
570     log::warn("Cannot find device with handle {}", conn.handle);
571     hh_connect_complete(conn.handle, conn.link_spec, BTIF_HH_DEV_DISCONNECTED);
572     return;
573   }
574 
575   log::info("Found device, getting dscp info for handle {}", conn.handle);
576 
577   p_dev->link_spec = conn.link_spec;
578   p_dev->dev_status = BTHH_CONN_STATE_CONNECTED;
579   hh_connect_complete(conn.handle, conn.link_spec, BTIF_HH_DEV_CONNECTED);
580   // Send set_idle if the peer_device is a keyboard
581   if (check_cod_hid_major(conn.link_spec.addrt.bda, COD_HID_KEYBOARD) ||
582       check_cod_hid_major(conn.link_spec.addrt.bda, COD_HID_COMBO)) {
583     BTA_HhSetIdle(conn.handle, 0);
584   }
585   BTA_HhGetDscpInfo(conn.handle);
586 }
587 
588 /*******************************************************************************
589  *
590  * Function         hh_add_device
591  *
592  * Description      Add a new device to the added device list.
593  *
594  * Returns          true if add successfully, otherwise false.
595  ******************************************************************************/
hh_add_device(const tAclLinkSpec & link_spec,tBTA_HH_ATTR_MASK attr_mask,bool reconnect_allowed)596 static bool hh_add_device(const tAclLinkSpec& link_spec,
597                           tBTA_HH_ATTR_MASK attr_mask, bool reconnect_allowed) {
598   int i;
599 
600   // Check if already added
601   if (btif_hh_find_added_dev(link_spec) != nullptr) {
602     log::warn("Device {} already added",
603               link_spec.ToRedactedStringForLogging());
604     return false;
605   }
606 
607   // Use an empty slot for the new device
608   for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
609     btif_hh_added_device_t& dev = btif_hh_cb.added_devices[i];
610     if (dev.link_spec.addrt.bda.IsEmpty()) {
611       log::info("Added device {}", link_spec.ToRedactedStringForLogging());
612       dev.link_spec = link_spec;
613       dev.dev_handle = BTA_HH_INVALID_HANDLE;
614       dev.attr_mask = attr_mask;
615       dev.reconnect_allowed = reconnect_allowed;
616       return true;
617     }
618   }
619 
620   log::error("Out of space to add device");
621   log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum::
622                                HIDH_COUNT_MAX_ADDED_DEVICE_LIMIT_REACHED,
623                            1);
624   return false;
625 }
626 
btif_hh_load_bonded_dev(const tAclLinkSpec & link_spec_ref,tBTA_HH_ATTR_MASK attr_mask,uint8_t sub_class,uint8_t app_id,tBTA_HH_DEV_DSCP_INFO dscp_info,bool reconnect_allowed)627 void btif_hh_load_bonded_dev(const tAclLinkSpec& link_spec_ref,
628                              tBTA_HH_ATTR_MASK attr_mask, uint8_t sub_class,
629                              uint8_t app_id, tBTA_HH_DEV_DSCP_INFO dscp_info,
630                              bool reconnect_allowed) {
631   btif_hh_device_t* p_dev;
632   uint8_t i;
633   tAclLinkSpec link_spec = link_spec_ref;
634 
635   if (com::android::bluetooth::flags::allow_switching_hid_and_hogp() &&
636       link_spec.transport == BT_TRANSPORT_AUTO) {
637     log::warn("Resolving link spec {} transport to BREDR/LE",
638               link_spec.ToRedactedStringForLogging());
639     btif_hh_transport_select(link_spec);
640     reconnect_allowed = true;
641     btif_storage_set_hid_connection_policy(link_spec, reconnect_allowed);
642 
643     // remove and re-write the hid info
644     btif_storage_remove_hid_info(link_spec);
645     btif_storage_add_hid_device_info(
646         link_spec, attr_mask, sub_class, app_id, dscp_info.vendor_id,
647         dscp_info.product_id, dscp_info.version, dscp_info.ctry_code,
648         dscp_info.ssr_max_latency, dscp_info.ssr_min_tout,
649         dscp_info.descriptor.dl_len, dscp_info.descriptor.dsc_list);
650   }
651 
652   if (hh_add_device(link_spec, attr_mask, reconnect_allowed)) {
653     if (com::android::bluetooth::flags::allow_switching_hid_and_hogp() &&
654         reconnect_allowed) {
655       BTHH_STATE_UPDATE(link_spec, BTHH_CONN_STATE_ACCEPTING);
656     }
657     BTA_HhAddDev(link_spec, attr_mask, sub_class, app_id, dscp_info);
658   }
659 }
660 
661 /*******************************************************************************
662  **
663  ** Function         btif_hh_remove_device
664  **
665  ** Description      Remove an added device from the stack.
666  **
667  ** Returns          void
668  ******************************************************************************/
btif_hh_remove_device(const tAclLinkSpec & link_spec)669 void btif_hh_remove_device(const tAclLinkSpec& link_spec) {
670   int i;
671   btif_hh_device_t* p_dev;
672   btif_hh_added_device_t* p_added_dev;
673 
674   BTHH_LOG_LINK(link_spec);
675 
676   for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
677     p_added_dev = &btif_hh_cb.added_devices[i];
678     if (p_added_dev->link_spec == link_spec) {
679       BTA_HhRemoveDev(p_added_dev->dev_handle);
680       btif_storage_remove_hid_info(p_added_dev->link_spec);
681       p_added_dev->link_spec = {};
682       p_added_dev->dev_handle = BTA_HH_INVALID_HANDLE;
683 
684       /* Look for other instances only if AUTO transport was used */
685       if (link_spec.transport != BT_TRANSPORT_AUTO) {
686         break;
687       }
688     }
689   }
690 
691   /* Remove all connections instances related to link_spec. If AUTO transport is
692    * used, btif_hh_find_dev_by_link_spec() finds both HID and HOGP instances */
693   while ((p_dev = btif_hh_find_dev_by_link_spec(link_spec)) != NULL) {
694     /* need to notify up-layer device is disconnected to avoid state out of sync
695      * with up-layer */
696 
697     do_in_jni_thread(base::Bind(
698         [](tAclLinkSpec link_spec) {
699           BTHH_STATE_UPDATE(link_spec, BTHH_CONN_STATE_DISCONNECTED);
700         },
701         link_spec));
702 
703     if (btif_hh_cb.device_num > 0) {
704       btif_hh_cb.device_num--;
705     } else {
706       log::warn("device_num = 0");
707     }
708     bta_hh_co_close(p_dev);
709     p_dev->dev_status = BTHH_CONN_STATE_UNKNOWN;
710     p_dev->dev_handle = BTA_HH_INVALID_HANDLE;
711     p_dev->uhid.ready_for_data = false;
712   }
713 }
714 
btif_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO * dest,tBTA_HH_DEV_DSCP_INFO * src)715 bool btif_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO* dest,
716                            tBTA_HH_DEV_DSCP_INFO* src) {
717   memset(dest, 0, sizeof(tBTA_HH_DEV_DSCP_INFO));
718   dest->descriptor.dl_len = 0;
719   if (src->descriptor.dl_len > 0) {
720     dest->descriptor.dsc_list = (uint8_t*)osi_malloc(src->descriptor.dl_len);
721   }
722   memcpy(dest->descriptor.dsc_list, src->descriptor.dsc_list,
723          src->descriptor.dl_len);
724   dest->descriptor.dl_len = src->descriptor.dl_len;
725   dest->vendor_id = src->vendor_id;
726   dest->product_id = src->product_id;
727   dest->version = src->version;
728   dest->ctry_code = src->ctry_code;
729   dest->ssr_max_latency = src->ssr_max_latency;
730   dest->ssr_min_tout = src->ssr_min_tout;
731   return true;
732 }
733 
734 /*******************************************************************************
735  *
736  * Function         btif_hh_virtual_unplug
737  *
738  * Description      Virtual unplug initiated from the BTIF thread context
739  *                  Special handling for HID mouse-
740  *
741  * Returns          void
742  *
743  ******************************************************************************/
744 
btif_hh_virtual_unplug(const tAclLinkSpec & link_spec)745 bt_status_t btif_hh_virtual_unplug(const tAclLinkSpec& link_spec) {
746   BTHH_LOG_LINK(link_spec);
747   btif_hh_device_t* p_dev;
748   p_dev = btif_hh_find_dev_by_link_spec(link_spec);
749   if ((p_dev != NULL) && (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED) &&
750       (p_dev->attr_mask & HID_VIRTUAL_CABLE)) {
751     log::verbose("Sending BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG for: {}",
752                  link_spec.ToRedactedStringForLogging());
753     /* start the timer */
754     btif_hh_start_vup_timer(link_spec);
755     p_dev->local_vup = true;
756     BTA_HhSendCtrl(p_dev->dev_handle, BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG);
757     return BT_STATUS_SUCCESS;
758   } else if ((p_dev != NULL) &&
759              (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED)) {
760     log::error("Virtual unplug not supported, disconnecting device: {}",
761                link_spec.ToRedactedStringForLogging());
762     /* start the timer */
763     btif_hh_start_vup_timer(link_spec);
764     p_dev->local_vup = true;
765     BTA_HhClose(p_dev->dev_handle);
766     return BT_STATUS_SUCCESS;
767   } else {
768     log::error("Error, device {} not opened, status = {}",
769                link_spec.ToRedactedStringForLogging(),
770                btif_hh_status_text(btif_hh_cb.status));
771     if ((btif_hh_cb.pending_link_spec.addrt.bda == link_spec.addrt.bda) &&
772         (btif_hh_cb.status == BTIF_HH_DEV_CONNECTING)) {
773       btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
774       btif_hh_cb.pending_link_spec = {};
775 
776       /* need to notify up-layer device is disconnected to avoid
777        * state out of sync with up-layer */
778       do_in_jni_thread(base::Bind(
779           [](tAclLinkSpec link_spec) {
780             BTHH_STATE_UPDATE(link_spec, BTHH_CONN_STATE_DISCONNECTED);
781           },
782           link_spec));
783     }
784     return BT_STATUS_DEVICE_NOT_FOUND;
785   }
786 }
787 
788 /*******************************************************************************
789  *
790  * Function         btif_hh_connect
791  *
792  * Description      connection initiated from the BTIF thread context
793  *
794  * Returns          int status
795  *
796  ******************************************************************************/
797 
btif_hh_connect(const tAclLinkSpec & link_spec)798 bt_status_t btif_hh_connect(const tAclLinkSpec& link_spec) {
799   CHECK_BTHH_INIT();
800   log::verbose("BTHH");
801   btif_hh_device_t* p_dev = btif_hh_find_dev_by_link_spec(link_spec);
802   if (!p_dev && btif_hh_cb.device_num >= BTIF_HH_MAX_HID) {
803     // No space for more HID device now.
804     log::warn("Error, exceeded the maximum supported HID device number {}",
805               BTIF_HH_MAX_HID);
806     log_counter_metrics_btif(
807         android::bluetooth::CodePathCounterKeyEnum::
808             HIDH_COUNT_CONNECT_REQ_WHEN_MAX_DEVICE_LIMIT_REACHED,
809         1);
810     return BT_STATUS_NOMEM;
811   }
812 
813   btif_hh_added_device_t* added_dev = btif_hh_find_added_dev(link_spec);
814   if (added_dev != nullptr) {
815     log::info("Device {} already added, attr_mask = 0x{:x}",
816               link_spec.ToRedactedStringForLogging(), added_dev->attr_mask);
817 
818     if (added_dev->dev_handle == BTA_HH_INVALID_HANDLE) {
819       // No space for more HID device now.
820       log::error("Device {} added but addition failed",
821                  link_spec.ToRedactedStringForLogging());
822       added_dev->link_spec = {};
823       added_dev->dev_handle = BTA_HH_INVALID_HANDLE;
824       return BT_STATUS_NOMEM;
825     }
826 
827     // Reset the connection policy to allow incoming reconnections
828     if (com::android::bluetooth::flags::allow_switching_hid_and_hogp()) {
829       added_dev->reconnect_allowed = true;
830       btif_storage_set_hid_connection_policy(link_spec, true);
831     }
832   }
833 
834   if (p_dev && p_dev->dev_status == BTHH_CONN_STATE_CONNECTED) {
835     log::debug("HidHost profile already connected for {}",
836                link_spec.ToRedactedStringForLogging());
837     return BT_STATUS_SUCCESS;
838   }
839 
840   if (p_dev) {
841     p_dev->dev_status = BTHH_CONN_STATE_CONNECTING;
842   }
843 
844   /* Not checking the NORMALLY_Connectible flags from sdp record, and anyways
845    sending this request from host, for subsequent user initiated connection.
846    If the remote is not in pagescan mode, we will do 2 retries to connect before
847    giving up */
848   btif_hh_cb.status = BTIF_HH_DEV_CONNECTING;
849   btif_hh_cb.pending_link_spec = link_spec;
850   BTA_HhOpen(btif_hh_cb.pending_link_spec);
851 
852   do_in_jni_thread(base::Bind(
853       [](tAclLinkSpec link_spec) {
854         BTHH_STATE_UPDATE(link_spec, BTHH_CONN_STATE_CONNECTING);
855       },
856       link_spec));
857   return BT_STATUS_SUCCESS;
858 }
859 
860 /*******************************************************************************
861  *
862  * Function         btif_hh_disconnect
863  *
864  * Description      disconnection initiated from the BTIF thread context
865  *
866  * Returns          void
867  *
868  ******************************************************************************/
btif_hh_disconnect(const tAclLinkSpec & link_spec)869 void btif_hh_disconnect(const tAclLinkSpec& link_spec) {
870   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_link_spec(link_spec);
871   if (p_dev == nullptr) {
872     log::warn("Unable to disconnect unknown HID device:{}",
873               link_spec.ToRedactedStringForLogging());
874     return;
875   }
876   log::debug("Disconnect and close request for HID device:{}",
877              link_spec.ToRedactedStringForLogging());
878   BTA_HhClose(p_dev->dev_handle);
879 }
880 
881 /*******************************************************************************
882  *
883  * Function         btif_btif_hh_setreport
884  *
885  * Description      setreport initiated from the UHID thread context
886  *
887  * Returns          void
888  *
889  ******************************************************************************/
btif_hh_setreport(btif_hh_uhid_t * p_uhid,bthh_report_type_t r_type,uint16_t size,uint8_t * report)890 void btif_hh_setreport(btif_hh_uhid_t* p_uhid, bthh_report_type_t r_type,
891                        uint16_t size, uint8_t* report) {
892   BT_HDR* p_buf = create_pbuf(size, report);
893   if (p_buf == NULL) {
894     log::error("Error, failed to allocate RPT buffer, size = {}", size);
895     return;
896   }
897   BTA_HhSetReport(p_uhid->dev_handle, r_type, p_buf);
898 }
899 
900 /*******************************************************************************
901  *
902  * Function         btif_btif_hh_senddata
903  *
904  * Description      senddata initiated from the UHID thread context
905  *
906  * Returns          void
907  *
908  ******************************************************************************/
btif_hh_senddata(btif_hh_uhid_t * p_uhid,uint16_t size,uint8_t * report)909 void btif_hh_senddata(btif_hh_uhid_t* p_uhid, uint16_t size, uint8_t* report) {
910   BT_HDR* p_buf = create_pbuf(size, report);
911   if (p_buf == NULL) {
912     log::error("Error, failed to allocate RPT buffer, size = {}", size);
913     return;
914   }
915   p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
916   BTA_HhSendData(p_uhid->dev_handle, p_uhid->link_spec, p_buf);
917 }
918 
919 /*******************************************************************************
920  *
921  * Function         btif_hh_service_registration
922  *
923  * Description      Registers or derigisters the hid host service
924  *
925  * Returns          none
926  *
927  ******************************************************************************/
btif_hh_service_registration(bool enable)928 void btif_hh_service_registration(bool enable) {
929   log::verbose("");
930 
931   log::verbose("enable = {}", enable);
932   if (bt_hh_callbacks == NULL) {
933     // The HID Host service was never initialized (it is either disabled or not
934     // available in this build). We should proceed directly to changing the HID
935     // Device service state (if needed).
936     if (!enable) {
937       btif_hd_service_registration();
938     }
939   } else if (enable) {
940     BTA_HhEnable(bte_hh_evt, bt_hh_enable_type.hidp_enabled,
941                  bt_hh_enable_type.hogp_enabled);
942   } else {
943     btif_hh_cb.service_dereg_active = TRUE;
944     BTA_HhDisable();
945   }
946 }
947 
948 /*******************************************************************************
949  *
950  *
951  * Function         btif_hh_getreport
952  *
953  * Description      getreport initiated from the UHID thread context
954  *
955  * Returns          void
956  *
957  ******************************************************************************/
btif_hh_getreport(btif_hh_uhid_t * p_uhid,bthh_report_type_t r_type,uint8_t reportId,uint16_t bufferSize)958 void btif_hh_getreport(btif_hh_uhid_t* p_uhid, bthh_report_type_t r_type,
959                        uint8_t reportId, uint16_t bufferSize) {
960   BTA_HhGetReport(p_uhid->dev_handle, r_type, reportId, bufferSize);
961 }
962 
963 /*****************************************************************************
964  *   Section name (Group of functions)
965  ****************************************************************************/
966 
967 /*****************************************************************************
968  *
969  *   btif hh api functions (no context switch)
970  *
971  ****************************************************************************/
972 
973 /*******************************************************************************
974  *
975  * Function         btif_hh_upstreams_evt
976  *
977  * Description      Executes HH UPSTREAMS events in btif context
978  *
979  * Returns          void
980  *
981  ******************************************************************************/
btif_hh_upstreams_evt(uint16_t event,char * p_param)982 static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
983   tBTA_HH* p_data = (tBTA_HH*)p_param;
984   btif_hh_device_t* p_dev = NULL;
985 
986   log::verbose("event={} dereg = {}", bta_hh_event_text(event),
987                btif_hh_cb.service_dereg_active);
988 
989   switch (event) {
990     case BTA_HH_ENABLE_EVT:
991       log::verbose("BTA_HH_ENABLE_EVT: status ={}", p_data->status);
992       if (p_data->status == BTA_HH_OK) {
993         btif_hh_cb.status = BTIF_HH_ENABLED;
994         log::verbose("Loading added devices");
995         /* Add hid descriptors for already bonded hid devices*/
996         btif_storage_load_bonded_hid_info();
997       } else {
998         btif_hh_cb.status = BTIF_HH_DISABLED;
999         log::warn("BTA_HH_ENABLE_EVT: HH enabling failed, status = {}",
1000                   p_data->status);
1001       }
1002       break;
1003 
1004     case BTA_HH_DISABLE_EVT:
1005       if (btif_hh_cb.status == BTIF_HH_DISABLING) {
1006         bt_hh_callbacks = NULL;
1007       }
1008 
1009       btif_hh_cb.status = BTIF_HH_DISABLED;
1010       if (btif_hh_cb.service_dereg_active) {
1011         log::verbose("BTA_HH_DISABLE_EVT: enabling HID Device service");
1012         btif_hd_service_registration();
1013         btif_hh_cb.service_dereg_active = FALSE;
1014       }
1015       if (p_data->status == BTA_HH_OK) {
1016         int i;
1017         // Clear the control block
1018         for (i = 0; i < BTIF_HH_MAX_HID; i++) {
1019           alarm_free(btif_hh_cb.devices[i].vup_timer);
1020         }
1021         memset(&btif_hh_cb, 0, sizeof(btif_hh_cb));
1022         for (i = 0; i < BTIF_HH_MAX_HID; i++) {
1023           btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN;
1024         }
1025       } else {
1026         log::warn("BTA_HH_DISABLE_EVT: HH disabling failed, status = {}",
1027                   p_data->status);
1028       }
1029       break;
1030 
1031     case BTA_HH_OPEN_EVT:
1032       hh_open_handler(p_data->conn);
1033       break;
1034 
1035     case BTA_HH_CLOSE_EVT:
1036       log::verbose("BTA_HH_CLOSE_EVT: status = {}, handle = {}",
1037                    p_data->dev_status.status, p_data->dev_status.handle);
1038       p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
1039       if (p_dev != NULL) {
1040         BTHH_STATE_UPDATE(p_dev->link_spec, BTHH_CONN_STATE_DISCONNECTING);
1041         log::verbose("uhid fd={} local_vup={}", p_dev->uhid.fd,
1042                      p_dev->local_vup);
1043         btif_hh_stop_vup_timer(p_dev->link_spec);
1044         /* If this is a locally initiated VUP, remove the bond as ACL got
1045          *  disconnected while VUP being processed.
1046          */
1047         if (p_dev->local_vup) {
1048           p_dev->local_vup = false;
1049           BTA_DmRemoveDevice(p_dev->link_spec.addrt.bda);
1050         } else if (p_data->dev_status.status == BTA_HH_HS_SERVICE_CHANGED) {
1051           /* Local disconnection due to service change in the HOGP device.
1052              HID descriptor would be read again, so remove it from cache. */
1053           log::warn(
1054               "Removing cached descriptor due to service change, handle = {}",
1055               p_data->dev_status.handle);
1056           btif_storage_remove_hid_info(p_dev->link_spec);
1057         }
1058 
1059         btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
1060         p_dev->dev_status = hh_get_state_on_disconnect(p_dev->link_spec);
1061 
1062         bta_hh_co_close(p_dev);
1063         BTHH_STATE_UPDATE(p_dev->link_spec, p_dev->dev_status);
1064       } else {
1065         log::warn("Error: cannot find device with handle {}",
1066                   p_data->dev_status.handle);
1067       }
1068       break;
1069 
1070     case BTA_HH_GET_RPT_EVT: {
1071       log::verbose("BTA_HH_GET_RPT_EVT: status = {}, handle = {}",
1072                    p_data->hs_data.status, p_data->hs_data.handle);
1073       p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
1074       if (p_dev) {
1075         BT_HDR* hdr = p_data->hs_data.rsp_data.p_rpt_data;
1076 
1077         if (hdr) { /* Get report response */
1078           uint8_t* data = (uint8_t*)(hdr + 1) + hdr->offset;
1079           uint16_t len = hdr->len;
1080           HAL_CBACK(bt_hh_callbacks, get_report_cb,
1081                     (RawAddress*)&(p_dev->link_spec.addrt.bda),
1082                     p_dev->link_spec.addrt.type, p_dev->link_spec.transport,
1083                     (bthh_status_t)p_data->hs_data.status, data, len);
1084 
1085           bta_hh_co_get_rpt_rsp(p_dev->dev_handle,
1086                                 (tBTA_HH_STATUS)p_data->hs_data.status, data,
1087                                 len);
1088         } else { /* Handshake */
1089           HAL_CBACK(bt_hh_callbacks, handshake_cb,
1090                     (RawAddress*)&(p_dev->link_spec.addrt.bda),
1091                     p_dev->link_spec.addrt.type, p_dev->link_spec.transport,
1092                     (bthh_status_t)p_data->hs_data.status);
1093         }
1094       } else {
1095         log::warn("Error: cannot find device with handle {}",
1096                   p_data->hs_data.handle);
1097       }
1098       break;
1099     }
1100 
1101     case BTA_HH_SET_RPT_EVT:
1102       log::verbose("BTA_HH_SET_RPT_EVT: status = {}, handle = {}",
1103                    p_data->dev_status.status, p_data->dev_status.handle);
1104       p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
1105       if (p_dev != NULL) {
1106         HAL_CBACK(bt_hh_callbacks, handshake_cb,
1107                   (RawAddress*)&(p_dev->link_spec.addrt.bda),
1108                   p_dev->link_spec.addrt.type, p_dev->link_spec.transport,
1109                   (bthh_status_t)p_data->hs_data.status);
1110 
1111         bta_hh_co_set_rpt_rsp(p_dev->dev_handle, p_data->dev_status.status);
1112       }
1113       break;
1114 
1115     case BTA_HH_GET_PROTO_EVT:
1116       p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
1117       if (p_dev == NULL) {
1118         log::warn("BTA_HH_GET_PROTO_EVT: cannot find device with handle {}",
1119                   p_data->hs_data.handle);
1120         return;
1121       }
1122       log::warn(
1123           "BTA_HH_GET_PROTO_EVT: status = {}, handle = {}, proto = [{}], {}",
1124           p_data->hs_data.status, p_data->hs_data.handle,
1125           p_data->hs_data.rsp_data.proto_mode,
1126           (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE)
1127               ? "Report Mode"
1128           : (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_BOOT_MODE)
1129               ? "Boot Mode"
1130               : "Unsupported");
1131       if (p_data->hs_data.rsp_data.proto_mode != BTA_HH_PROTO_UNKNOWN) {
1132         HAL_CBACK(bt_hh_callbacks, protocol_mode_cb,
1133                   (RawAddress*)&(p_dev->link_spec.addrt.bda),
1134                   p_dev->link_spec.addrt.type, p_dev->link_spec.transport,
1135                   (bthh_status_t)p_data->hs_data.status,
1136                   (bthh_protocol_mode_t)p_data->hs_data.rsp_data.proto_mode);
1137       } else {
1138         HAL_CBACK(bt_hh_callbacks, handshake_cb,
1139                   (RawAddress*)&(p_dev->link_spec.addrt.bda),
1140                   p_dev->link_spec.addrt.type, p_dev->link_spec.transport,
1141                   (bthh_status_t)p_data->hs_data.status);
1142       }
1143       break;
1144 
1145     case BTA_HH_SET_PROTO_EVT:
1146       log::verbose("BTA_HH_SET_PROTO_EVT: status = {}, handle = {}",
1147                    p_data->dev_status.status, p_data->dev_status.handle);
1148       p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
1149       if (p_dev) {
1150         HAL_CBACK(bt_hh_callbacks, handshake_cb,
1151                   (RawAddress*)&(p_dev->link_spec.addrt.bda),
1152                   p_dev->link_spec.addrt.type, p_dev->link_spec.transport,
1153                   (bthh_status_t)p_data->hs_data.status);
1154       }
1155       break;
1156 
1157     case BTA_HH_GET_IDLE_EVT:
1158       log::verbose("BTA_HH_GET_IDLE_EVT: handle = {}, status = {}, rate = {}",
1159                    p_data->hs_data.handle, p_data->hs_data.status,
1160                    p_data->hs_data.rsp_data.idle_rate);
1161       p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
1162       if (p_dev) {
1163         HAL_CBACK(bt_hh_callbacks, idle_time_cb,
1164                   (RawAddress*)&(p_dev->link_spec.addrt.bda),
1165                   p_dev->link_spec.addrt.type, p_dev->link_spec.transport,
1166                   (bthh_status_t)p_data->hs_data.status,
1167                   p_data->hs_data.rsp_data.idle_rate);
1168       }
1169       break;
1170 
1171     case BTA_HH_SET_IDLE_EVT:
1172       log::verbose("BTA_HH_SET_IDLE_EVT: status = {}, handle = {}",
1173                    p_data->dev_status.status, p_data->dev_status.handle);
1174       break;
1175 
1176     case BTA_HH_GET_DSCP_EVT: {
1177       uint8_t hid_handle = p_data->dscp_info.hid_handle;
1178       int len = p_data->dscp_info.descriptor.dl_len;
1179       log::verbose("BTA_HH_GET_DSCP_EVT: len = {}, handle = {}", len,
1180                    hid_handle);
1181 
1182       p_dev = btif_hh_find_connected_dev_by_handle(hid_handle);
1183       if (p_dev == NULL) {
1184         log::error("BTA_HH_GET_DSCP_EVT: No HID device is currently connected");
1185         p_data->dscp_info.hid_handle = BTA_HH_INVALID_HANDLE;
1186         return;
1187       }
1188 
1189       if (p_dev->uhid.fd < 0) {
1190         log::error("BTA_HH_GET_DSCP_EVT: failed to find the uhid driver...");
1191         return;
1192       }
1193 
1194       const char* cached_name = NULL;
1195       bt_bdname_t bdname;
1196       bt_property_t prop_name;
1197       BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_BDNAME,
1198                                  sizeof(bt_bdname_t), &bdname);
1199       if (btif_storage_get_remote_device_property(
1200               &p_dev->link_spec.addrt.bda, &prop_name) == BT_STATUS_SUCCESS) {
1201         cached_name = (char*)bdname.name;
1202       } else {
1203         cached_name = "Bluetooth HID";
1204       }
1205 
1206       log::warn("name = {}", cached_name);
1207       bta_hh_co_send_hid_info(p_dev, cached_name, p_data->dscp_info.vendor_id,
1208                               p_data->dscp_info.product_id,
1209                               p_data->dscp_info.version,
1210                               p_data->dscp_info.ctry_code, len,
1211                               p_data->dscp_info.descriptor.dsc_list);
1212       if (hh_add_device(p_dev->link_spec, p_dev->attr_mask, true)) {
1213         tBTA_HH_DEV_DSCP_INFO dscp_info;
1214         bt_status_t ret;
1215         btif_hh_copy_hid_info(&dscp_info, &p_data->dscp_info);
1216         log::verbose("BTA_HH_GET_DSCP_EVT: link spec = {}",
1217                      p_dev->link_spec.ToRedactedStringForLogging());
1218         BTA_HhAddDev(p_dev->link_spec, p_dev->attr_mask, p_dev->sub_class,
1219                      p_dev->app_id, dscp_info);
1220         // write hid info to nvram
1221         ret = btif_storage_add_hid_device_info(
1222             p_dev->link_spec, p_dev->attr_mask, p_dev->sub_class, p_dev->app_id,
1223             p_data->dscp_info.vendor_id, p_data->dscp_info.product_id,
1224             p_data->dscp_info.version, p_data->dscp_info.ctry_code,
1225             p_data->dscp_info.ssr_max_latency, p_data->dscp_info.ssr_min_tout,
1226             len, p_data->dscp_info.descriptor.dsc_list);
1227 
1228         // Allow incoming connections
1229         if (com::android::bluetooth::flags::allow_switching_hid_and_hogp() &&
1230             com::android::bluetooth::flags::
1231                 save_initial_hid_connection_policy()) {
1232           btif_storage_set_hid_connection_policy(p_dev->link_spec, true);
1233         }
1234 
1235         ASSERTC(ret == BT_STATUS_SUCCESS, "storing hid info failed", ret);
1236         log::warn("BTA_HH_GET_DSCP_EVT: Called add device");
1237 
1238         // Free buffer created for dscp_info;
1239         if (dscp_info.descriptor.dl_len > 0 &&
1240             dscp_info.descriptor.dsc_list != NULL) {
1241           osi_free_and_reset((void**)&dscp_info.descriptor.dsc_list);
1242           dscp_info.descriptor.dl_len = 0;
1243         }
1244       } else {
1245         // Device already added.
1246         log::warn("BTA_HH_GET_DSCP_EVT: Device {} already added",
1247                   p_dev->link_spec.ToRedactedStringForLogging());
1248       }
1249       /*Sync HID Keyboard lockstates */
1250       int tmplen = sizeof(hid_kb_numlock_on_list) / sizeof(tHID_KB_LIST);
1251       for (int i = 0; i < tmplen; i++) {
1252         if (p_data->dscp_info.vendor_id ==
1253                 hid_kb_numlock_on_list[i].version_id &&
1254             p_data->dscp_info.product_id ==
1255                 hid_kb_numlock_on_list[i].product_id) {
1256           log::verbose("idx[{}] Enabling NUMLOCK for device :: {}", i,
1257                        hid_kb_numlock_on_list[i].kb_name);
1258           /* Enable NUMLOCK by default so that numeric
1259               keys work from first keyboard connect */
1260           set_keylockstate(BTIF_HH_KEYSTATE_MASK_NUMLOCK, true);
1261           sync_lockstate_on_connect(p_dev);
1262           /* End Sync HID Keyboard lockstates */
1263           break;
1264         }
1265       }
1266     } break;
1267 
1268     case BTA_HH_ADD_DEV_EVT: {
1269       log::info("BTA_HH_ADD_DEV_EVT: status = {}, handle = {}",
1270                 p_data->dev_info.status, p_data->dev_info.handle);
1271       btif_hh_added_device_t* added_dev =
1272           btif_hh_find_added_dev(p_data->dev_info.link_spec);
1273       if (added_dev != nullptr) {
1274         if (p_data->dev_info.status == BTA_HH_OK) {
1275           added_dev->dev_handle = p_data->dev_info.handle;
1276         } else {
1277           added_dev->link_spec = {};
1278           added_dev->dev_handle = BTA_HH_INVALID_HANDLE;
1279         }
1280       }
1281     } break;
1282     case BTA_HH_RMV_DEV_EVT:
1283       log::verbose(
1284           "BTA_HH_RMV_DEV_EVT: status = {}, handle = {}, link spec = {}",
1285           p_data->dev_info.status, p_data->dev_info.handle,
1286           p_data->dev_info.link_spec.ToRedactedStringForLogging());
1287       break;
1288 
1289     case BTA_HH_VC_UNPLUG_EVT:
1290       log::verbose("BTA_HH_VC_UNPLUG_EVT: status = {}, handle = {}",
1291                    p_data->dev_status.status, p_data->dev_status.handle);
1292       p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
1293 
1294       if (p_dev == NULL) {
1295         log::error("BTA_HH_VC_UNPLUG_EVT: device not found handle {}",
1296                    p_data->dev_status.handle);
1297         return;
1298       }
1299 
1300       if (p_dev->link_spec.transport == BT_TRANSPORT_LE) {
1301         log::error("BTA_HH_VC_UNPLUG_EVT: not expected for {}",
1302                    p_dev->link_spec.ToRedactedStringForLogging());
1303         return;
1304       }
1305       btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
1306       log::verbose("BTA_HH_VC_UNPLUG_EVT: link_spec = {}",
1307                    p_dev->link_spec.ToRedactedStringForLogging());
1308 
1309       /* Stop the VUP timer */
1310       btif_hh_stop_vup_timer(p_dev->link_spec);
1311       p_dev->dev_status = hh_get_state_on_disconnect(p_dev->link_spec);
1312       log::verbose("--Sending connection state change");
1313       BTHH_STATE_UPDATE(p_dev->link_spec, p_dev->dev_status);
1314       log::verbose("--Removing HID bond");
1315       /* If it is locally initiated VUP or remote device has its major COD as
1316       Peripheral removed the bond.*/
1317       if (p_dev->local_vup || check_cod_hid(&(p_dev->link_spec.addrt.bda))) {
1318         p_dev->local_vup = false;
1319         BTA_DmRemoveDevice(p_dev->link_spec.addrt.bda);
1320       } else {
1321         log_counter_metrics_btif(
1322             android::bluetooth::CodePathCounterKeyEnum::
1323                 HIDH_COUNT_VIRTUAL_UNPLUG_REQUESTED_BY_REMOTE_DEVICE,
1324             1);
1325         btif_hh_remove_device(p_dev->link_spec);
1326       }
1327       HAL_CBACK(bt_hh_callbacks, virtual_unplug_cb,
1328                 &(p_dev->link_spec.addrt.bda), p_dev->link_spec.addrt.type,
1329                 p_dev->link_spec.transport,
1330                 (bthh_status_t)p_data->dev_status.status);
1331       break;
1332 
1333     case BTA_HH_API_ERR_EVT:
1334       log::error("BTA_HH API_ERR");
1335       break;
1336 
1337     default:
1338       log::warn("Unhandled event: {}", event);
1339       break;
1340   }
1341 }
1342 
1343 /*******************************************************************************
1344  *
1345  * Function         btif_hh_hsdata_rpt_copy_cb
1346  *
1347  * Description      Deep copies the tBTA_HH_HSDATA structure
1348  *
1349  * Returns          void
1350  *
1351  ******************************************************************************/
1352 
btif_hh_hsdata_rpt_copy_cb(uint16_t event,char * p_dest,const char * p_src)1353 static void btif_hh_hsdata_rpt_copy_cb(uint16_t event, char* p_dest,
1354                                        const char* p_src) {
1355   tBTA_HH_HSDATA* p_dst_data = (tBTA_HH_HSDATA*)p_dest;
1356   tBTA_HH_HSDATA* p_src_data = (tBTA_HH_HSDATA*)p_src;
1357   BT_HDR* hdr;
1358 
1359   if (!p_src) {
1360     log::error("Nothing to copy");
1361     return;
1362   }
1363 
1364   memcpy(p_dst_data, p_src_data, sizeof(tBTA_HH_HSDATA));
1365 
1366   hdr = p_src_data->rsp_data.p_rpt_data;
1367   if (hdr != NULL) {
1368     uint8_t* p_data = ((uint8_t*)p_dst_data) + sizeof(tBTA_HH_HSDATA);
1369     memcpy(p_data, hdr, BT_HDR_SIZE + hdr->offset + hdr->len);
1370 
1371     p_dst_data->rsp_data.p_rpt_data = (BT_HDR*)p_data;
1372   }
1373 }
1374 
1375 /*******************************************************************************
1376  *
1377  * Function         bte_hh_evt
1378  *
1379  * Description      Switches context from BTE to BTIF for all HH events
1380  *
1381  * Returns          void
1382  *
1383  ******************************************************************************/
1384 
bte_hh_evt(tBTA_HH_EVT event,tBTA_HH * p_data)1385 static void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
1386   bt_status_t status;
1387   int param_len = 0;
1388   tBTIF_COPY_CBACK* p_copy_cback = NULL;
1389 
1390   if (BTA_HH_ENABLE_EVT == event)
1391     param_len = sizeof(tBTA_HH_STATUS);
1392   else if (BTA_HH_OPEN_EVT == event)
1393     param_len = sizeof(tBTA_HH_CONN);
1394   else if (BTA_HH_DISABLE_EVT == event)
1395     param_len = sizeof(tBTA_HH_STATUS);
1396   else if (BTA_HH_CLOSE_EVT == event)
1397     param_len = sizeof(tBTA_HH_CBDATA);
1398   else if (BTA_HH_GET_DSCP_EVT == event)
1399     param_len = sizeof(tBTA_HH_DEV_DSCP_INFO);
1400   else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_IDLE_EVT == event))
1401     param_len = sizeof(tBTA_HH_HSDATA);
1402   else if (BTA_HH_GET_RPT_EVT == event) {
1403     BT_HDR* hdr = p_data->hs_data.rsp_data.p_rpt_data;
1404     param_len = sizeof(tBTA_HH_HSDATA);
1405 
1406     if (hdr != NULL) {
1407       p_copy_cback = btif_hh_hsdata_rpt_copy_cb;
1408       param_len += BT_HDR_SIZE + hdr->offset + hdr->len;
1409     }
1410   } else if ((BTA_HH_SET_PROTO_EVT == event) || (BTA_HH_SET_RPT_EVT == event) ||
1411              (BTA_HH_VC_UNPLUG_EVT == event) || (BTA_HH_SET_IDLE_EVT == event))
1412     param_len = sizeof(tBTA_HH_CBDATA);
1413   else if ((BTA_HH_ADD_DEV_EVT == event) || (BTA_HH_RMV_DEV_EVT == event))
1414     param_len = sizeof(tBTA_HH_DEV_INFO);
1415   else if (BTA_HH_API_ERR_EVT == event)
1416     param_len = 0;
1417   /* switch context to btif task context (copy full union size for convenience)
1418    */
1419   status = btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event,
1420                                  (char*)p_data, param_len, p_copy_cback);
1421 
1422   /* catch any failed context transfers */
1423   ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
1424 }
1425 
1426 /*******************************************************************************
1427  *
1428  * Function         btif_hh_handle_evt
1429  *
1430  * Description      Switches context for immediate callback
1431  *
1432  * Returns          void
1433  *
1434  ******************************************************************************/
1435 
btif_hh_handle_evt(uint16_t event,char * p_param)1436 static void btif_hh_handle_evt(uint16_t event, char* p_param) {
1437   log::assert_that(p_param != nullptr, "assert failed: p_param != nullptr");
1438   tAclLinkSpec link_spec = *(tAclLinkSpec*)p_param;
1439 
1440   switch (event) {
1441     case BTIF_HH_CONNECT_REQ_EVT: {
1442       log::debug("BTIF_HH_CONNECT_REQ_EVT: link spec:{}",
1443                  link_spec.ToRedactedStringForLogging());
1444       if (btif_hh_connect(link_spec) == BT_STATUS_SUCCESS) {
1445         BTHH_STATE_UPDATE(link_spec, BTHH_CONN_STATE_CONNECTING);
1446       } else {
1447         BTHH_STATE_UPDATE(link_spec, BTHH_CONN_STATE_DISCONNECTED);
1448       }
1449     } break;
1450 
1451     case BTIF_HH_DISCONNECT_REQ_EVT: {
1452       log::debug("BTIF_HH_DISCONNECT_REQ_EVT: link spec:{}",
1453                  link_spec.ToRedactedStringForLogging());
1454       btif_hh_disconnect(link_spec);
1455       BTHH_STATE_UPDATE(link_spec, BTHH_CONN_STATE_DISCONNECTING);
1456     } break;
1457 
1458     case BTIF_HH_VUP_REQ_EVT: {
1459       log::debug("BTIF_HH_VUP_REQ_EVT: link spec:{}",
1460                  link_spec.ToRedactedStringForLogging());
1461       if (btif_hh_virtual_unplug(link_spec) != BT_STATUS_SUCCESS) {
1462         log::warn("Unable to virtual unplug device remote:{}",
1463                   link_spec.ToRedactedStringForLogging());
1464       }
1465     } break;
1466 
1467     default: {
1468       log::warn("Unknown event received:{} remote:{}", event,
1469                 link_spec.ToRedactedStringForLogging());
1470     } break;
1471   }
1472 }
1473 
1474 /*******************************************************************************
1475  *
1476  * Function      btif_hh_timer_timeout
1477  *
1478  * Description   Process timer timeout
1479  *
1480  * Returns      void
1481  ******************************************************************************/
btif_hh_timer_timeout(void * data)1482 void btif_hh_timer_timeout(void* data) {
1483   btif_hh_device_t* p_dev = (btif_hh_device_t*)data;
1484   tBTA_HH_EVT event = BTA_HH_VC_UNPLUG_EVT;
1485   tBTA_HH p_data;
1486   int param_len = sizeof(tBTA_HH_CBDATA);
1487 
1488   log::verbose("");
1489   if (p_dev->dev_status != BTHH_CONN_STATE_CONNECTED) return;
1490 
1491   memset(&p_data, 0, sizeof(tBTA_HH));
1492   p_data.dev_status.status = BTA_HH_ERR;  // tBTA_HH_STATUS
1493   p_data.dev_status.handle = p_dev->dev_handle;
1494 
1495   /* switch context to btif task context */
1496   btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event, (char*)&p_data,
1497                         param_len, NULL);
1498 }
1499 
1500 /*******************************************************************************
1501  *
1502  * Function         btif_hh_init
1503  *
1504  * Description     initializes the hh interface
1505  *
1506  * Returns         bt_status_t
1507  *
1508  ******************************************************************************/
init(bthh_callbacks_t * callbacks)1509 static bt_status_t init(bthh_callbacks_t* callbacks) {
1510   uint32_t i;
1511   log::verbose("");
1512 
1513   bt_hh_callbacks = callbacks;
1514   memset(&btif_hh_cb, 0, sizeof(btif_hh_cb));
1515   for (i = 0; i < BTIF_HH_MAX_HID; i++) {
1516     btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN;
1517   }
1518   /* Invoke the enable service API to the core to set the appropriate service_id
1519    */
1520   btif_enable_service(BTA_HID_SERVICE_ID);
1521   return BT_STATUS_SUCCESS;
1522 }
1523 /*******************************************************************************
1524  *
1525  * Function         btif_hh_transport_select
1526  *
1527  * Description      Select HID transport based on services available.
1528  *
1529  * Returns          void
1530  *
1531  ******************************************************************************/
btif_hh_transport_select(tAclLinkSpec & link_spec)1532 static void btif_hh_transport_select(tAclLinkSpec& link_spec) {
1533   bool hid_available = false;
1534   bool hogp_available = false;
1535   bool headtracker_available = false;
1536   bool le_preferred = false;
1537   bluetooth::Uuid remote_uuids[BT_MAX_NUM_UUIDS] = {};
1538   bt_property_t remote_properties = {BT_PROPERTY_UUIDS, sizeof(remote_uuids),
1539                                      &remote_uuids};
1540   const RawAddress& bd_addr = link_spec.addrt.bda;
1541 
1542   // Find the device type
1543   tBT_DEVICE_TYPE dev_type;
1544   tBLE_ADDR_TYPE addr_type;
1545   BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type);
1546 
1547   // Find which transports are already connected
1548   bool bredr_acl = BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR);
1549   bool le_acl = BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE);
1550 
1551   // Find which services known to be available
1552   if (btif_storage_get_remote_device_property(&bd_addr, &remote_properties) ==
1553       BT_STATUS_SUCCESS) {
1554     int count = remote_properties.len / sizeof(remote_uuids[0]);
1555     for (int i = 0; i < count; i++) {
1556       if (remote_uuids[i].Is16Bit()) {
1557         if (remote_uuids[i].As16Bit() == UUID_SERVCLASS_HUMAN_INTERFACE) {
1558           hid_available = true;
1559         } else if (remote_uuids[i].As16Bit() == UUID_SERVCLASS_LE_HID) {
1560           hogp_available = true;
1561         }
1562       } else if (com::android::bluetooth::flags::
1563                      android_headtracker_service() &&
1564                  remote_uuids[i] == ANDROID_HEADTRACKER_SERVICE_UUID) {
1565         headtracker_available = true;
1566       }
1567 
1568       if (hid_available && (hogp_available || headtracker_available)) {
1569         break;
1570       }
1571     }
1572   }
1573 
1574   /* Decide whether to connect HID or HOGP */
1575   if (bredr_acl && hid_available) {
1576     le_preferred = false;
1577   } else if (le_acl && (hogp_available || headtracker_available)) {
1578     le_preferred = true;
1579   } else if (hid_available) {
1580     le_preferred = false;
1581   } else if (hogp_available || headtracker_available) {
1582     le_preferred = true;
1583   } else if (bredr_acl) {
1584     le_preferred = false;
1585   } else if (le_acl || dev_type == BT_DEVICE_TYPE_BLE) {
1586     le_preferred = true;
1587   } else {
1588     le_preferred = false;
1589   }
1590 
1591   link_spec.transport = le_preferred ? BT_TRANSPORT_LE : BT_TRANSPORT_BR_EDR;
1592   log::info(
1593       "link_spec:{}, bredr_acl:{}, hid_available:{}, le_acl:{}, "
1594       "hogp_available:{}, headtracker_available:{}, "
1595       "dev_type:{}, le_preferred:{}",
1596       link_spec.ToRedactedStringForLogging(), bredr_acl, hid_available, le_acl,
1597       hogp_available, headtracker_available, dev_type, le_preferred);
1598 }
1599 /*******************************************************************************
1600  *
1601  * Function        connect
1602  *
1603  * Description     connect to hid device
1604  *
1605  * Returns         bt_status_t
1606  *
1607  ******************************************************************************/
connect(RawAddress * bd_addr,tBLE_ADDR_TYPE addr_type,tBT_TRANSPORT transport)1608 static bt_status_t connect(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
1609                            tBT_TRANSPORT transport) {
1610   tAclLinkSpec link_spec = {};
1611   link_spec.addrt.bda = *bd_addr;
1612   link_spec.addrt.type = addr_type;
1613   link_spec.transport = transport;
1614 
1615   BTHH_LOG_LINK(link_spec);
1616 
1617   if (btif_hh_cb.status == BTIF_HH_DEV_CONNECTING) {
1618     log::warn("HH status = {}", btif_hh_status_text(btif_hh_cb.status));
1619     return BT_STATUS_BUSY;
1620   } else if (btif_hh_cb.status == BTIF_HH_DISABLED ||
1621              btif_hh_cb.status == BTIF_HH_DISABLING) {
1622     log::warn("HH status = {}", btif_hh_status_text(btif_hh_cb.status));
1623     return BT_STATUS_NOT_READY;
1624   }
1625 
1626   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_link_spec(link_spec);
1627   if (p_dev != nullptr) {
1628     log::warn("device {} already connected",
1629               p_dev->link_spec.ToRedactedStringForLogging());
1630     return BT_STATUS_DONE;
1631   }
1632 
1633   if (link_spec.transport == BT_TRANSPORT_AUTO) {
1634     btif_hh_transport_select(link_spec);
1635   }
1636 
1637   return btif_transfer_context(btif_hh_handle_evt, BTIF_HH_CONNECT_REQ_EVT,
1638                                (char*)&link_spec, sizeof(tAclLinkSpec), NULL);
1639 }
1640 
1641 /*******************************************************************************
1642  *
1643  * Function         disconnect
1644  *
1645  * Description      disconnect from hid device
1646  *
1647  * Returns         bt_status_t
1648  *
1649  ******************************************************************************/
disconnect(RawAddress * bd_addr,tBLE_ADDR_TYPE addr_type,tBT_TRANSPORT transport,bool reconnect_allowed)1650 static bt_status_t disconnect(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
1651                               tBT_TRANSPORT transport, bool reconnect_allowed) {
1652   CHECK_BTHH_INIT();
1653   tAclLinkSpec link_spec = {};
1654   link_spec.addrt.bda = *bd_addr;
1655   link_spec.addrt.type = addr_type;
1656   link_spec.transport = transport;
1657 
1658   BTHH_LOG_LINK(link_spec);
1659 
1660   if (btif_hh_cb.status == BTIF_HH_DISABLED ||
1661       btif_hh_cb.status == BTIF_HH_DISABLING) {
1662     log::error("HH status = {}", btif_hh_status_text(btif_hh_cb.status));
1663     return BT_STATUS_UNHANDLED;
1664   }
1665 
1666   if (com::android::bluetooth::flags::allow_switching_hid_and_hogp() &&
1667       !reconnect_allowed) {
1668     log::info("Incoming reconnections disabled for device {}",
1669               link_spec.ToRedactedStringForLogging());
1670     btif_hh_added_device_t* added_dev = btif_hh_find_added_dev(link_spec);
1671     if (added_dev != nullptr) {
1672       added_dev->reconnect_allowed = reconnect_allowed;
1673       btif_storage_set_hid_connection_policy(added_dev->link_spec,
1674                                              reconnect_allowed);
1675     }
1676   }
1677 
1678   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_link_spec(link_spec);
1679   if (p_dev == nullptr) {
1680     if (com::android::bluetooth::flags::allow_switching_hid_and_hogp()) {
1681       // Conclude the request if the device is already disconnected
1682       p_dev = btif_hh_find_dev_by_link_spec(link_spec);
1683       if (p_dev != nullptr &&
1684           (p_dev->dev_status == BTHH_CONN_STATE_ACCEPTING ||
1685            p_dev->dev_status == BTHH_CONN_STATE_CONNECTING)) {
1686         log::warn("Device {} already not connected, state: {}",
1687                   p_dev->link_spec.ToRedactedStringForLogging(),
1688                   bthh_connection_state_text(p_dev->dev_status));
1689         p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
1690         return BT_STATUS_DONE;
1691       }
1692     }
1693 
1694     BTHH_LOG_UNKNOWN_LINK(link_spec);
1695     return BT_STATUS_UNHANDLED;
1696   }
1697 
1698   return btif_transfer_context(btif_hh_handle_evt, BTIF_HH_DISCONNECT_REQ_EVT,
1699                                (char*)&p_dev->link_spec, sizeof(tAclLinkSpec),
1700                                NULL);
1701 }
1702 
1703 /*******************************************************************************
1704  *
1705  * Function         virtual_unplug
1706  *
1707  * Description      Virtual UnPlug (VUP) the specified HID device.
1708  *
1709  * Returns         bt_status_t
1710  *
1711  ******************************************************************************/
virtual_unplug(RawAddress * bd_addr,tBLE_ADDR_TYPE addr_type,tBT_TRANSPORT transport)1712 static bt_status_t virtual_unplug(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
1713                                   tBT_TRANSPORT transport) {
1714   CHECK_BTHH_INIT();
1715   tAclLinkSpec link_spec = {};
1716   link_spec.addrt.bda = *bd_addr;
1717   link_spec.addrt.type = addr_type;
1718   link_spec.transport = transport;
1719 
1720   BTHH_LOG_LINK(link_spec);
1721 
1722   BTHH_CHECK_NOT_DISABLED();
1723 
1724   btif_hh_device_t* p_dev = btif_hh_find_dev_by_link_spec(link_spec);
1725   if (!p_dev) {
1726     BTHH_LOG_UNKNOWN_LINK(link_spec);
1727     return BT_STATUS_DEVICE_NOT_FOUND;
1728   }
1729   btif_transfer_context(btif_hh_handle_evt, BTIF_HH_VUP_REQ_EVT,
1730                         (char*)&link_spec, sizeof(tAclLinkSpec), NULL);
1731   return BT_STATUS_SUCCESS;
1732 }
1733 
1734 /*******************************************************************************
1735 **
1736 ** Function         get_idle_time
1737 **
1738 ** Description      Get the HID idle time
1739 **
1740 ** Returns         bt_status_t
1741 **
1742 *******************************************************************************/
get_idle_time(RawAddress * bd_addr,tBLE_ADDR_TYPE addr_type,tBT_TRANSPORT transport)1743 static bt_status_t get_idle_time(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
1744                                  tBT_TRANSPORT transport) {
1745   CHECK_BTHH_INIT();
1746   tAclLinkSpec link_spec = {};
1747   link_spec.addrt.bda = *bd_addr;
1748   link_spec.addrt.type = addr_type;
1749   link_spec.transport = transport;
1750 
1751   BTHH_LOG_LINK(link_spec);
1752 
1753   BTHH_CHECK_NOT_DISABLED();
1754 
1755   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_link_spec(link_spec);
1756   if (p_dev == NULL) {
1757     BTHH_LOG_UNKNOWN_LINK(link_spec);
1758     return BT_STATUS_DEVICE_NOT_FOUND;
1759   }
1760 
1761   BTA_HhGetIdle(p_dev->dev_handle);
1762   return BT_STATUS_SUCCESS;
1763 }
1764 
1765 /*******************************************************************************
1766 **
1767 ** Function         set_idle_time
1768 **
1769 ** Description      Set the HID idle time
1770 **
1771 ** Returns         bt_status_t
1772 **
1773 *******************************************************************************/
set_idle_time(RawAddress * bd_addr,tBLE_ADDR_TYPE addr_type,tBT_TRANSPORT transport,uint8_t idle_time)1774 static bt_status_t set_idle_time(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
1775                                  tBT_TRANSPORT transport, uint8_t idle_time) {
1776   CHECK_BTHH_INIT();
1777   tAclLinkSpec link_spec = {};
1778   link_spec.addrt.bda = *bd_addr;
1779   link_spec.addrt.type = addr_type;
1780   link_spec.transport = transport;
1781 
1782   BTHH_LOG_LINK(link_spec);
1783   log::verbose("idle time: {}", idle_time);
1784 
1785   BTHH_CHECK_NOT_DISABLED();
1786 
1787   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_link_spec(link_spec);
1788   if (p_dev == NULL) {
1789     BTHH_LOG_UNKNOWN_LINK(link_spec);
1790     return BT_STATUS_DEVICE_NOT_FOUND;
1791   }
1792 
1793   BTA_HhSetIdle(p_dev->dev_handle, idle_time);
1794   return BT_STATUS_SUCCESS;
1795 }
1796 
1797 /*******************************************************************************
1798  *
1799  * Function         set_info
1800  *
1801  * Description      Set the HID device descriptor for the specified HID device.
1802  *
1803  * Returns         bt_status_t
1804  *
1805  ******************************************************************************/
set_info(RawAddress * bd_addr,tBLE_ADDR_TYPE addr_type,tBT_TRANSPORT transport,bthh_hid_info_t hid_info)1806 static bt_status_t set_info(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
1807                             tBT_TRANSPORT transport, bthh_hid_info_t hid_info) {
1808   CHECK_BTHH_INIT();
1809   tBTA_HH_DEV_DSCP_INFO dscp_info = {};
1810   tAclLinkSpec link_spec = {};
1811   link_spec.addrt.bda = *bd_addr;
1812   link_spec.addrt.type = addr_type;
1813   link_spec.transport = transport;
1814 
1815   BTHH_LOG_LINK(link_spec);
1816   log::verbose(
1817       "sub_class = 0x{:02x}, app_id = {}, vendor_id = 0x{:04x}, "
1818       "product_id = 0x{:04x}, version= 0x{:04x}",
1819       hid_info.sub_class, hid_info.app_id, hid_info.vendor_id,
1820       hid_info.product_id, hid_info.version);
1821 
1822   BTHH_CHECK_NOT_DISABLED();
1823 
1824   dscp_info.vendor_id = hid_info.vendor_id;
1825   dscp_info.product_id = hid_info.product_id;
1826   dscp_info.version = hid_info.version;
1827   dscp_info.ctry_code = hid_info.ctry_code;
1828 
1829   dscp_info.descriptor.dl_len = hid_info.dl_len;
1830   dscp_info.descriptor.dsc_list =
1831       (uint8_t*)osi_malloc(dscp_info.descriptor.dl_len);
1832   memcpy(dscp_info.descriptor.dsc_list, &(hid_info.dsc_list), hid_info.dl_len);
1833 
1834   if (transport == BT_TRANSPORT_AUTO) {
1835     btif_hh_transport_select(link_spec);
1836   }
1837 
1838   if (hh_add_device(link_spec, hid_info.attr_mask, true)) {
1839     BTA_HhAddDev(link_spec, hid_info.attr_mask, hid_info.sub_class,
1840                  hid_info.app_id, dscp_info);
1841   }
1842 
1843   osi_free_and_reset((void**)&dscp_info.descriptor.dsc_list);
1844 
1845   return BT_STATUS_SUCCESS;
1846 }
1847 
1848 /*******************************************************************************
1849  *
1850  * Function         get_protocol
1851  *
1852  * Description      Get the HID proto mode.
1853  *
1854  * Returns         bt_status_t
1855  *
1856  ******************************************************************************/
get_protocol(RawAddress * bd_addr,tBLE_ADDR_TYPE addr_type,tBT_TRANSPORT transport,bthh_protocol_mode_t)1857 static bt_status_t get_protocol(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
1858                                 tBT_TRANSPORT transport,
1859                                 bthh_protocol_mode_t /* protocolMode */) {
1860   CHECK_BTHH_INIT();
1861   tAclLinkSpec link_spec = {};
1862   link_spec.addrt.bda = *bd_addr;
1863   link_spec.addrt.type = addr_type;
1864   link_spec.transport = transport;
1865 
1866   BTHH_LOG_LINK(link_spec);
1867 
1868   BTHH_CHECK_NOT_DISABLED();
1869 
1870   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_link_spec(link_spec);
1871   if (!p_dev) {
1872     BTHH_LOG_UNKNOWN_LINK(link_spec);
1873     return BT_STATUS_DEVICE_NOT_FOUND;
1874   }
1875 
1876   BTA_HhGetProtoMode(p_dev->dev_handle);
1877   return BT_STATUS_SUCCESS;
1878 }
1879 
1880 /*******************************************************************************
1881  *
1882  * Function         set_protocol
1883  *
1884  * Description      Set the HID proto mode.
1885  *
1886  * Returns         bt_status_t
1887  *
1888  ******************************************************************************/
set_protocol(RawAddress * bd_addr,tBLE_ADDR_TYPE addr_type,tBT_TRANSPORT transport,bthh_protocol_mode_t protocolMode)1889 static bt_status_t set_protocol(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
1890                                 tBT_TRANSPORT transport,
1891                                 bthh_protocol_mode_t protocolMode) {
1892   CHECK_BTHH_INIT();
1893   btif_hh_device_t* p_dev;
1894   uint8_t proto_mode = protocolMode;
1895   tAclLinkSpec link_spec = {};
1896   link_spec.addrt.bda = *bd_addr;
1897   link_spec.addrt.type = addr_type;
1898   link_spec.transport = transport;
1899 
1900   BTHH_LOG_LINK(link_spec);
1901   log::verbose("mode: {}", protocolMode);
1902 
1903   BTHH_CHECK_NOT_DISABLED();
1904 
1905   p_dev = btif_hh_find_connected_dev_by_link_spec(link_spec);
1906   if (p_dev == NULL) {
1907     BTHH_LOG_UNKNOWN_LINK(link_spec);
1908     return BT_STATUS_DEVICE_NOT_FOUND;
1909   } else if (protocolMode != BTA_HH_PROTO_RPT_MODE &&
1910              protocolMode != BTA_HH_PROTO_BOOT_MODE) {
1911     log::warn("device proto_mode = {}", proto_mode);
1912     return BT_STATUS_PARM_INVALID;
1913   } else {
1914     BTA_HhSetProtoMode(p_dev->dev_handle, protocolMode);
1915   }
1916 
1917   return BT_STATUS_SUCCESS;
1918 }
1919 
1920 /*******************************************************************************
1921  *
1922  * Function         get_report
1923  *
1924  * Description      Send a GET_REPORT to HID device.
1925  *
1926  * Returns         bt_status_t
1927  *
1928  ******************************************************************************/
get_report(RawAddress * bd_addr,tBLE_ADDR_TYPE addr_type,tBT_TRANSPORT transport,bthh_report_type_t reportType,uint8_t reportId,int bufferSize)1929 static bt_status_t get_report(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
1930                               tBT_TRANSPORT transport,
1931                               bthh_report_type_t reportType, uint8_t reportId,
1932                               int bufferSize) {
1933   CHECK_BTHH_INIT();
1934   btif_hh_device_t* p_dev;
1935   tAclLinkSpec link_spec = {};
1936   link_spec.addrt.bda = *bd_addr;
1937   link_spec.addrt.type = addr_type;
1938   link_spec.transport = transport;
1939 
1940   BTHH_LOG_LINK(link_spec);
1941   log::verbose("r_type: {}; rpt_id: {}; buf_size: {}", reportType, reportId,
1942                bufferSize);
1943 
1944   BTHH_CHECK_NOT_DISABLED();
1945 
1946   p_dev = btif_hh_find_connected_dev_by_link_spec(link_spec);
1947   if (p_dev == NULL) {
1948     BTHH_LOG_UNKNOWN_LINK(link_spec);
1949     return BT_STATUS_DEVICE_NOT_FOUND;
1950   } else if (((int)reportType) <= BTA_HH_RPTT_RESRV ||
1951              ((int)reportType) > BTA_HH_RPTT_FEATURE) {
1952     log::error("report type={} not supported", reportType);
1953     log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum::
1954                                  HIDH_COUNT_WRONG_REPORT_TYPE,
1955                              1);
1956     return BT_STATUS_UNSUPPORTED;
1957   } else {
1958     BTA_HhGetReport(p_dev->dev_handle, reportType, reportId, bufferSize);
1959   }
1960 
1961   return BT_STATUS_SUCCESS;
1962 }
1963 
1964 /*******************************************************************************
1965  *
1966  * Function         get_report_reply
1967  *
1968  * Description      Send a REPORT_REPLY/FEATURE_ANSWER to HID driver.
1969  *
1970  * Returns         bt_status_t
1971  *
1972  ******************************************************************************/
get_report_reply(RawAddress * bd_addr,tBLE_ADDR_TYPE addr_type,tBT_TRANSPORT transport,bthh_status_t status,char * report,uint16_t size)1973 static bt_status_t get_report_reply(RawAddress* bd_addr,
1974                                     tBLE_ADDR_TYPE addr_type,
1975                                     tBT_TRANSPORT transport,
1976                                     bthh_status_t status, char* report,
1977                                     uint16_t size) {
1978   CHECK_BTHH_INIT();
1979   tAclLinkSpec link_spec = {};
1980   link_spec.addrt.bda = *bd_addr;
1981   link_spec.addrt.type = addr_type;
1982   link_spec.transport = transport;
1983 
1984   BTHH_LOG_LINK(link_spec);
1985 
1986   BTHH_CHECK_NOT_DISABLED();
1987 
1988   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_link_spec(link_spec);
1989   if (p_dev == NULL) {
1990     BTHH_LOG_UNKNOWN_LINK(link_spec);
1991     return BT_STATUS_DEVICE_NOT_FOUND;
1992   }
1993 
1994   bta_hh_co_get_rpt_rsp(p_dev->dev_handle, (tBTA_HH_STATUS)status,
1995                         (uint8_t*)report, size);
1996   return BT_STATUS_SUCCESS;
1997 }
1998 
1999 /*******************************************************************************
2000  *
2001  * Function         set_report
2002  *
2003  * Description      Send a SET_REPORT to HID device.
2004  *
2005  * Returns         bt_status_t
2006  *
2007  ******************************************************************************/
set_report(RawAddress * bd_addr,tBLE_ADDR_TYPE addr_type,tBT_TRANSPORT transport,bthh_report_type_t reportType,char * report)2008 static bt_status_t set_report(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
2009                               tBT_TRANSPORT transport,
2010                               bthh_report_type_t reportType, char* report) {
2011   CHECK_BTHH_INIT();
2012   btif_hh_device_t* p_dev;
2013   tAclLinkSpec link_spec = {};
2014   link_spec.addrt.bda = *bd_addr;
2015   link_spec.addrt.type = addr_type;
2016   link_spec.transport = transport;
2017 
2018   BTHH_LOG_LINK(link_spec);
2019   log::verbose("reportType: {}", reportType);
2020 
2021   BTHH_CHECK_NOT_DISABLED();
2022 
2023   p_dev = btif_hh_find_connected_dev_by_link_spec(link_spec);
2024   if (p_dev == NULL) {
2025     BTHH_LOG_UNKNOWN_LINK(link_spec);
2026     return BT_STATUS_DEVICE_NOT_FOUND;
2027   } else if (((int)reportType) <= BTA_HH_RPTT_RESRV ||
2028              ((int)reportType) > BTA_HH_RPTT_FEATURE) {
2029     log::error("report type={} not supported", reportType);
2030     log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum::
2031                                  HIDH_COUNT_WRONG_REPORT_TYPE,
2032                              1);
2033     return BT_STATUS_UNSUPPORTED;
2034   } else {
2035     int hex_bytes_filled;
2036     size_t len = (strlen(report) + 1) / 2;
2037     uint8_t* hexbuf = (uint8_t*)osi_calloc(len);
2038 
2039     /* Build a SetReport data buffer */
2040     // TODO
2041     hex_bytes_filled = ascii_2_hex(report, len, hexbuf);
2042     log::info("Hex bytes filled, hex value: {}", hex_bytes_filled);
2043     if (hex_bytes_filled) {
2044       BT_HDR* p_buf = create_pbuf(hex_bytes_filled, hexbuf);
2045       if (p_buf == NULL) {
2046         log::error("failed to allocate RPT buffer, len = {}", hex_bytes_filled);
2047         osi_free(hexbuf);
2048         return BT_STATUS_NOMEM;
2049       }
2050       BTA_HhSetReport(p_dev->dev_handle, reportType, p_buf);
2051       osi_free(hexbuf);
2052       return BT_STATUS_SUCCESS;
2053     }
2054     osi_free(hexbuf);
2055     return BT_STATUS_FAIL;
2056   }
2057 }
2058 
2059 /*******************************************************************************
2060  *
2061  * Function         send_data
2062  *
2063  * Description      Send a SEND_DATA to HID device.
2064  *
2065  * Returns         bt_status_t
2066  *
2067  ******************************************************************************/
send_data(RawAddress * bd_addr,tBLE_ADDR_TYPE addr_type,tBT_TRANSPORT transport,char * data)2068 static bt_status_t send_data(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
2069                              tBT_TRANSPORT transport, char* data) {
2070   CHECK_BTHH_INIT();
2071   tAclLinkSpec link_spec = {};
2072   link_spec.addrt.bda = *bd_addr;
2073   link_spec.addrt.type = addr_type;
2074   link_spec.transport = transport;
2075 
2076   BTHH_LOG_LINK(link_spec);
2077 
2078   BTHH_CHECK_NOT_DISABLED();
2079 
2080   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_link_spec(link_spec);
2081   if (p_dev == NULL) {
2082     BTHH_LOG_UNKNOWN_LINK(link_spec);
2083     return BT_STATUS_DEVICE_NOT_FOUND;
2084   } else {
2085     int hex_bytes_filled;
2086     size_t len = (strlen(data) + 1) / 2;
2087     uint8_t* hexbuf = (uint8_t*)osi_calloc(len);
2088 
2089     /* Build a SendData data buffer */
2090     hex_bytes_filled = ascii_2_hex(data, len, hexbuf);
2091     log::info("Hex bytes filled, hex value: {}, {}", hex_bytes_filled, len);
2092 
2093     if (hex_bytes_filled) {
2094       BT_HDR* p_buf = create_pbuf(hex_bytes_filled, hexbuf);
2095       if (p_buf == NULL) {
2096         log::error("failed to allocate RPT buffer, len = {}", hex_bytes_filled);
2097         osi_free(hexbuf);
2098         return BT_STATUS_NOMEM;
2099       }
2100       p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
2101       BTA_HhSendData(p_dev->dev_handle, link_spec, p_buf);
2102       osi_free(hexbuf);
2103       return BT_STATUS_SUCCESS;
2104     }
2105     osi_free(hexbuf);
2106     return BT_STATUS_FAIL;
2107   }
2108 }
2109 
2110 /*******************************************************************************
2111  *
2112  * Function         cleanup
2113  *
2114  * Description      Closes the HH interface
2115  *
2116  * Returns          bt_status_t
2117  *
2118  ******************************************************************************/
cleanup(void)2119 static void cleanup(void) {
2120   log::verbose("");
2121   btif_hh_device_t* p_dev;
2122   int i;
2123   if (btif_hh_cb.status == BTIF_HH_DISABLED ||
2124       btif_hh_cb.status == BTIF_HH_DISABLING) {
2125     log::warn("HH disabling or disabled already, status = {}",
2126               btif_hh_status_text(btif_hh_cb.status));
2127     return;
2128   }
2129   if (bt_hh_callbacks) {
2130     btif_hh_cb.status = BTIF_HH_DISABLING;
2131     /* update flag, not to enable hid device service now as BT is switching off
2132      */
2133     btif_hh_cb.service_dereg_active = FALSE;
2134     btif_disable_service(BTA_HID_SERVICE_ID);
2135   }
2136   for (i = 0; i < BTIF_HH_MAX_HID; i++) {
2137     p_dev = &btif_hh_cb.devices[i];
2138     if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->uhid.fd >= 0) {
2139       log::verbose("Closing uhid fd = {}", p_dev->uhid.fd);
2140       bta_hh_co_close(p_dev);
2141     }
2142   }
2143 }
2144 
2145 /*******************************************************************************
2146  *
2147  * Function         configure_enabled_profiles
2148  *
2149  * Description      Configure HIDP or HOGP enablement. Require to cleanup and
2150  *re-init to take effect.
2151  *
2152  * Returns          void
2153  *
2154  ******************************************************************************/
configure_enabled_profiles(bool enable_hidp,bool enable_hogp)2155 static void configure_enabled_profiles(bool enable_hidp, bool enable_hogp) {
2156   bt_hh_enable_type.hidp_enabled = enable_hidp;
2157   bt_hh_enable_type.hogp_enabled = enable_hogp;
2158 }
2159 
2160 static const bthh_interface_t bthhInterface = {
2161     sizeof(bthhInterface),
2162     init,
2163     connect,
2164     disconnect,
2165     virtual_unplug,
2166     set_info,
2167     get_protocol,
2168     set_protocol,
2169     get_idle_time,
2170     set_idle_time,
2171     get_report,
2172     get_report_reply,
2173     set_report,
2174     send_data,
2175     cleanup,
2176     configure_enabled_profiles,
2177 };
2178 
2179 /*******************************************************************************
2180  *
2181  * Function         btif_hh_execute_service
2182  *
2183  * Description      Initializes/Shuts down the service
2184  *
2185  * Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
2186  *
2187  ******************************************************************************/
btif_hh_execute_service(bool b_enable)2188 bt_status_t btif_hh_execute_service(bool b_enable) {
2189   if (b_enable) {
2190     /* Enable and register with BTA-HH */
2191     BTA_HhEnable(bte_hh_evt, bt_hh_enable_type.hidp_enabled,
2192                  bt_hh_enable_type.hogp_enabled);
2193   } else {
2194     /* Disable HH */
2195     BTA_HhDisable();
2196   }
2197   return BT_STATUS_SUCCESS;
2198 }
2199 
2200 /*******************************************************************************
2201  *
2202  * Function         btif_hh_get_interface
2203  *
2204  * Description      Get the hh callback interface
2205  *
2206  * Returns          bthh_interface_t
2207  *
2208  ******************************************************************************/
btif_hh_get_interface()2209 const bthh_interface_t* btif_hh_get_interface() {
2210   log::verbose("");
2211   return &bthhInterface;
2212 }
2213 
2214 #define DUMPSYS_TAG "shim::legacy::hid"
DumpsysHid(int fd)2215 void DumpsysHid(int fd) {
2216   LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG);
2217   LOG_DUMPSYS(fd, "status:%s num_devices:%u",
2218               btif_hh_status_text(btif_hh_cb.status).c_str(),
2219               btif_hh_cb.device_num);
2220   LOG_DUMPSYS(fd, "status:%s", btif_hh_status_text(btif_hh_cb.status).c_str());
2221   for (unsigned i = 0; i < BTIF_HH_MAX_HID; i++) {
2222     const btif_hh_device_t* p_dev = &btif_hh_cb.devices[i];
2223     if (p_dev->link_spec.addrt.bda != RawAddress::kEmpty) {
2224       LOG_DUMPSYS(
2225           fd, "  %u: addr:%s fd:%d state:%s ready:%s thread_id:%d handle:%d", i,
2226           p_dev->link_spec.ToRedactedStringForLogging().c_str(), p_dev->uhid.fd,
2227           bthh_connection_state_text(p_dev->dev_status).c_str(),
2228           (p_dev->uhid.ready_for_data) ? ("T") : ("F"),
2229           static_cast<int>(p_dev->hh_poll_thread_id), p_dev->dev_handle);
2230     }
2231   }
2232   for (unsigned i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
2233     const btif_hh_added_device_t* p_dev = &btif_hh_cb.added_devices[i];
2234     if (p_dev->link_spec.addrt.bda != RawAddress::kEmpty) {
2235       LOG_DUMPSYS(fd, "  %u: addr:%s reconnect:%s", i,
2236                   p_dev->link_spec.ToRedactedStringForLogging().c_str(),
2237                   p_dev->reconnect_allowed ? "T" : "F");
2238     }
2239   }
2240 }
2241 
2242 namespace bluetooth {
2243 namespace legacy {
2244 namespace testing {
2245 
bte_hh_evt(tBTA_HH_EVT event,tBTA_HH * p_data)2246 void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
2247   ::bte_hh_evt(event, p_data);
2248 }
2249 
2250 }  // namespace testing
2251 }  // namespace legacy
2252 }  // namespace bluetooth
2253 
2254 #undef DUMPSYS_TAG
2255