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