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