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