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