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