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