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
68extern const int BT_UID;
69extern const int BT_GID;
70static int btif_hh_prev_keyevents=0; //The previous key events
71static 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 */
86typedef 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
105typedef 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************************************************************************************/
115btif_hh_cb_t btif_hh_cb;
116
117static 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.*/
122static 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************************************************************************************/
149extern void bta_hh_co_destroy(int fd);
150extern void bta_hh_co_write(int fd, UINT8* rpt, UINT16 len);
151extern bt_status_t btif_dm_remove_bond(const bt_bdaddr_t *bd_addr);
152extern 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);
155extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
156extern void btif_dm_cb_remove_bond(bt_bdaddr_t *bd_addr);
157extern int  scru_ascii_2_hex(char *p_ascii, int len, UINT8 *p_hex);
158
159/*****************************************************************************
160**  Local Function prototypes
161*****************************************************************************/
162static void set_keylockstate(int keymask, BOOLEAN isSet);
163static void toggle_os_keylockstates(int fd, int changedkeystates);
164static 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
172static int get_keylockstates()
173{
174    return btif_hh_keylockstates;
175}
176
177static 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
198static 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*******************************************************************************/
251static 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*******************************************************************************/
289static 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*******************************************************************************/
326static 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*******************************************************************************/
349btif_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*******************************************************************************/
370static 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*******************************************************************************/
391static 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*******************************************************************************/
412BOOLEAN 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 *******************************************************************************/
451void 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
501BOOLEAN 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
534bt_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
567bt_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
641void 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
665void 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*******************************************************************************/
715static 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
1011static 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
1051static 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*******************************************************************************/
1103static 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*******************************************************************************/
1127static 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*******************************************************************************/
1148static 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*******************************************************************************/
1180static 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*******************************************************************************/
1214static 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*******************************************************************************/
1267static 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*******************************************************************************/
1300static 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*******************************************************************************/
1335static 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*******************************************************************************/
1368static 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*******************************************************************************/
1412static 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*******************************************************************************/
1458static 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*******************************************************************************/
1530static 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*******************************************************************************/
1597static 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
1626static 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*******************************************************************************/
1652bt_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*******************************************************************************/
1675const bthh_interface_t *btif_hh_get_interface()
1676{
1677    BTIF_TRACE_EVENT1("%s", __FUNCTION__);
1678    return &bthhInterface;
1679}
1680