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