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