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