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