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