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