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