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