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