diff options
author | Priti Aghera <paghera@broadcom.com> | 2012-03-22 11:51:08 -0700 |
---|---|---|
committer | Matthew Xie <mattx@google.com> | 2012-07-14 11:19:14 -0700 |
commit | c01f69a35563261eca49bd2083afd7064790940d (patch) | |
tree | ab42ef0ba2a5f9d86b6b972aa3f9143148e72b30 /btif/co | |
parent | 146738bdcf0accdbd5d865440f86152d2430812d (diff) | |
download | external_bluetooth_bluedroid-c01f69a35563261eca49bd2083afd7064790940d.zip external_bluetooth_bluedroid-c01f69a35563261eca49bd2083afd7064790940d.tar.gz external_bluetooth_bluedroid-c01f69a35563261eca49bd2083afd7064790940d.tar.bz2 |
HID-Host:Fixed white space issue and power management issue
Included more code to support mouse connectiona and reconnection
Signed-off-by: Priti Aghera <paghera@broadcom.com>
Change-Id: I1e20997e85eda5919f20a069131e580bcbb0ca63
Diffstat (limited to 'btif/co')
-rw-r--r-- | btif/co/bta_hh_co.c | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/btif/co/bta_hh_co.c b/btif/co/bta_hh_co.c new file mode 100644 index 0000000..cf7970f --- /dev/null +++ b/btif/co/bta_hh_co.c @@ -0,0 +1,378 @@ +/************************************************************************************ + * + * Copyright (C) 2009-2012 Broadcom Corporation + * + * This program is the proprietary software of Broadcom Corporation and/or its + * licensors, and may only be used, duplicated, modified or distributed + * pursuant to the terms and conditions of a separate, written license + * agreement executed between you and Broadcom (an "Authorized License"). + * Except as set forth in an Authorized License, Broadcom grants no license + * (express or implied), right to use, or waiver of any kind with respect to + * the Software, and Broadcom expressly reserves all rights in and to the + * Software and all intellectual property rights therein. + * IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS + * SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE + * ALL USE OF THE SOFTWARE. + * + * Except as expressly set forth in the Authorized License, + * + * 1. This program, including its structure, sequence and organization, + * constitutes the valuable trade secrets of Broadcom, and you shall + * use all reasonable efforts to protect the confidentiality thereof, + * and to use this information only in connection with your use of + * Broadcom integrated circuit products. + * + * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED + * "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, + * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, + * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY + * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, + * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, + * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR + * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT + * OF USE OR PERFORMANCE OF THE SOFTWARE. + * + * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR + * ITS LICENSORS BE LIABLE FOR + * (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY + * DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO + * YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM + * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR + * (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE + * SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE + * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF + * ESSENTIAL PURPOSE OF ANY LIMITED REMEDY. + * + ************************************************************************************/ + +//#if (defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)) + +#include <ctype.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <errno.h> +#include "btif_hh.h" + +#include "bta_api.h" +#include "bta_hh_api.h" + + + +#define UINT8 uint8_t +#define UINT16 uint16_t +#if (defined(HH_USE_BTHID) && (HH_USE_BTHID == TRUE)) + + +#define BTHID_HID_INFO 1 +#define LOG_TAG "BTA_HH_CO" +#define BTHID_MAX_DEV_NAME_LEN 128 +#define BTHID_MAX_DSCP_BUF_LEN 884 + +typedef struct BTHID_CONTROL +{ + int dscp_len; + char dscp_buf[BTHID_MAX_DSCP_BUF_LEN]; + char dev_name[BTHID_MAX_DEV_NAME_LEN]; + unsigned short vendor_id; + unsigned short product_id; + unsigned short version; + unsigned short ctry_code; +} tBTHID_CONTROL; + +#else + +#endif + +static UINT8 HID_REPORT_START[] = {1,0,0}; +#define HID_REPORT_CAPSLOCK 0x39 +#define HID_REPORT_NUMLOCK 0x53 +#define HID_REPORT_SCROLLLOCK 0x47 +static int saved_keyevents =0; + +static void process_rpt_keys_with_state(UINT8 dev_handle, UINT8 *p_rpt, UINT16 len) +{ +/* + --TODO + */ +} + +/******************************************************************************* +** +** Function bta_hh_co_open +** +** Description When connection is opened, this call-out function is executed +** by HH to do platform specific initialization. +** +** Returns void. +*******************************************************************************/ +void bta_hh_co_open(UINT8 dev_handle, UINT8 sub_class, tBTA_HH_ATTR_MASK attr_mask, + UINT8 app_id) +{ + UINT32 i; + btif_hh_device_t *p_dev = NULL; + + BTIF_TRACE_WARNING5("%s: dev_handle = %d, subclass = 0x%02X, attr_mask = 0x%04X, app_id = %d", + __FUNCTION__, dev_handle, sub_class, attr_mask, app_id); + + if (dev_handle == BTA_HH_INVALID_HANDLE) { + BTIF_TRACE_WARNING2("%s: Oops, dev_handle (%d) is invalid...", __FUNCTION__, dev_handle); + return; + } + + for (i = 0; i < BTIF_HH_MAX_HID; i++) { + p_dev = &btif_hh_cb.devices[i]; + if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->dev_handle == dev_handle) { + // We found a device with the same handle. Must be a device reconnected. + BTIF_TRACE_WARNING2("%s: Found an existing device with the same handle. dev_status = %d", + __FUNCTION__, p_dev->dev_status); + BTIF_TRACE_WARNING6("%s: bd_addr = [%02X:%02X:%02X:%02X:%02X:]", __FUNCTION__, + p_dev->bd_addr.address[0], p_dev->bd_addr.address[1], p_dev->bd_addr.address[2], + p_dev->bd_addr.address[3], p_dev->bd_addr.address[4]); + BTIF_TRACE_WARNING4("%s: attr_mask = 0x%04x, sub_class = 0x%02x, app_id = %d", __FUNCTION__, + p_dev->attr_mask, p_dev->sub_class, p_dev->app_id); + + if(p_dev->fd<0) { + p_dev->fd = open("/dev/bthid", O_RDWR); + BTIF_TRACE_WARNING2("%s: bthid fd = %d", __FUNCTION__, p_dev->fd); + } + + break; + } + p_dev = NULL; + } + + if (p_dev == NULL) { + // Did not find a device reconnection case. Find an empty slot now. + for (i = 0; i < BTIF_HH_MAX_HID; i++) { + if (btif_hh_cb.devices[i].dev_status == BTHH_CONN_STATE_UNKNOWN) { + p_dev = &btif_hh_cb.devices[i]; + p_dev->dev_handle = dev_handle; + p_dev->attr_mask = attr_mask; + p_dev->sub_class = sub_class; + p_dev->app_id = app_id; + + btif_hh_cb.device_num++; + + #if (defined(HH_USE_BTHID) && (HH_USE_BTHID == TRUE)) + // This is a new device,open the bthid driver now. + p_dev->fd = open("/dev/bthid", O_RDWR); + BTIF_TRACE_WARNING3("%s: bthid fd = %d, errno=%d", __FUNCTION__, p_dev->fd,errno); + #endif + break; + } + } + } + + if (p_dev == NULL) { + BTIF_TRACE_WARNING1("%s: Error: too many HID devices are connected", __FUNCTION__); + return; + } + + p_dev->dev_status = BTHH_CONN_STATE_CONNECTED; + BTIF_TRACE_WARNING2("%s: Return device status %d", __FUNCTION__, p_dev->dev_status); +} + + +/******************************************************************************* +** +** Function bta_hh_co_close +** +** Description When connection is closed, this call-out function is executed +** by HH to do platform specific finalization. +** +** Parameters dev_handle - device handle +** app_id - application id +** +** Returns void. +*******************************************************************************/ +void bta_hh_co_close(UINT8 dev_handle, UINT8 app_id) +{ + BTIF_TRACE_WARNING3("%s: dev_handle = %d, app_id = %d", __FUNCTION__, dev_handle, app_id); +} + + +/******************************************************************************* +** +** Function bta_hh_co_data +** +** Description This function is executed by BTA when HID host receive a data +** report. +** +** Parameters dev_handle - device handle +** *p_rpt - pointer to the report data +** len - length of report data +** mode - Hid host Protocol Mode +** sub_clas - Device Subclass +** app_id - application id +** +** Returns void +*******************************************************************************/ +void bta_hh_co_data(UINT8 dev_handle, UINT8 *p_rpt, UINT16 len, tBTA_HH_PROTO_MODE mode, + UINT8 sub_class, UINT8 ctry_code, BD_ADDR peer_addr, UINT8 app_id) +{ + btif_hh_device_t *p_dev; + //tBTA_HH_BOOT_RPT rpt; + + BTIF_TRACE_WARNING6("%s: dev_handle = %d, subclass = 0x%02X, mode = %d, " + "ctry_code = %d, app_id = %d", + __FUNCTION__, dev_handle, sub_class, mode, ctry_code, app_id); + + + // Verbose logging + /* + int i; + for (i =0; i < len;i++) { + LOGV("%s: %x",__FUNCTION__, p_rpt[i]); + } + */ + + p_dev = btif_hh_find_connected_dev_by_handle(dev_handle); + if (p_dev == NULL) { + BTIF_TRACE_WARNING2("%s: Error: unknown HID device handle %d", __FUNCTION__, dev_handle); + return; + } + +#if (defined(HH_USE_BTHID) && (HH_USE_BTHID == TRUE)) + // Send the HID report to the kernel. + if (p_dev->fd >= 0) { + BTIF_TRACE_WARNING3("%s: fd = %d, len = %d", __FUNCTION__, p_dev->fd, len); + /* TODO: keystate + if (app_id == BTAPP_HH_APP_ID_KB) { + process_rpt_keys_with_state(dev_handle,p_rpt,len); + } + */ + write(p_dev->fd, p_rpt, len); + } + else { + BTIF_TRACE_WARNING3("%s: Error: fd = %d, len = %d", __FUNCTION__, p_dev->fd, len); + } +#else + + switch (app_id) { + case BTAPP_HH_APP_ID_KB: + case BTAPP_HH_APP_ID_MI: + if (mode == BTA_HH_PROTO_BOOT_MODE) { + // Call utility function to parse the boot mode report + BTA_HhParseBootRpt(&rpt, p_rpt, len); + + switch (rpt.dev_type) { + + case BTA_HH_KEYBD_RPT_ID: // HID keyboard + /* Process the keypress by looking up the key conversion table + * which could be different from language to language. + * Application can pass in different key conversion table depend on + * the keyboard language. For undefined country code or English + * keyboard, use the default key conversion table + * + * We only use default conversion table here, ignore the language + * and the country code. + */ + process_keyboard_rpt(p_dev, &rpt.data_rpt.keybd_rpt); + break; + + case BTA_HH_MOUSE_RPT_ID: // HID mouse + process_mouse_rpt(&rpt.data_rpt.mice_rpt); + break; + + default: + BTIF_TRACE_WARNING4("%s: Unknown boot-mode HID report(%d) \"%s\", dev_type = %d", + __FUNCTION__, len, p_rpt, rpt.dev_type); + //LOGI("%s: %x %x %x %x %x %x %x", + // __FUNCTION__, p_rpt[0], p_rpt[1], p_rpt[2], p_rpt[3], p_rpt[4], + // p_rpt[5], p_rpt[6]); + break; + } + } + else { + BTIF_TRACE_WARNING4("%s: Unsupported HID mode %d rpt(%d) \"%s\"", + __FUNCTION__, mode, len, p_rpt); + } + break; + + default: + BTIF_TRACE_WARNING4("%s: Unknown HID report app_id %d rpt(%d) \"%s\"", + __FUNCTION__, app_id, len, p_rpt); + break; + } + +#endif // (defined(HH_USE_BTHID) && (HH_USE_BTHID == TRUE)) +} + + +/******************************************************************************* +** +** Function bta_hh_co_send_hid_info +** +** Description This function is called in btapp_hh.c to process DSCP received. +** +** Parameters dev_handle - device handle +** dscp_len - report descriptor length +** *p_dscp - report descriptor +** +** Returns void +*******************************************************************************/ +void bta_hh_co_send_hid_info(btif_hh_device_t *p_dev, char *dev_name, UINT16 vendor_id, + UINT16 product_id, UINT16 version, UINT8 ctry_code, + int dscp_len, UINT8 *p_dscp) +{ +#if (defined(HH_USE_BTHID) && (HH_USE_BTHID == TRUE)) + int result; + tBTHID_CONTROL ctrl; +#endif + + /* + int i; + for (i = 0; i < dscp_len; i += 16) { + LOGI("%02X %02X %02X %02X %02X %02X %02X %02X " + "%02X %02X %02X %02X %02X %02X %02X %02X", + p_dscp[i], p_dscp[i+1], p_dscp[i+2], p_dscp[i+3], + p_dscp[i+4], p_dscp[i+5], p_dscp[i+6], p_dscp[i+7], + p_dscp[i+8], p_dscp[i+9], p_dscp[i+10], p_dscp[i+11], + p_dscp[i+12], p_dscp[i+13], p_dscp[i+14], p_dscp[i+15]); + } + */ + +#if (defined(HH_USE_BTHID) && (HH_USE_BTHID == TRUE)) + if (p_dev->fd < 0) { + BTIF_TRACE_WARNING3("%s: Error: fd = %d, dscp_len = %d", __FUNCTION__, p_dev->fd, dscp_len); + return; + } + + if (dscp_len > BTHID_MAX_DSCP_BUF_LEN) { + BTIF_TRACE_WARNING2("%s: Error: HID report descriptor is too large. dscp_len = %d", __FUNCTION__, dscp_len); + return; + } + + BTIF_TRACE_WARNING4("%s: fd = %d, name = [%s], dscp_len = %d", __FUNCTION__, p_dev->fd, dev_name, dscp_len); + BTIF_TRACE_WARNING5("%s: vendor_id = 0x%04x, product_id = 0x%04x, version= 0x%04x, ctry_code=0x%02x", + __FUNCTION__, vendor_id, product_id, version, ctry_code); + + memset(&ctrl, 0, sizeof(tBTHID_CONTROL)); + + ctrl.dscp_len = dscp_len; + memcpy(ctrl.dscp_buf, p_dscp, dscp_len); + strncpy(ctrl.dev_name, dev_name, BTHID_MAX_DEV_NAME_LEN - 1); + ctrl.vendor_id = vendor_id; + ctrl.product_id = product_id; + ctrl.version = version; + ctrl.ctry_code = ctry_code; + + BTIF_TRACE_WARNING1("%s: send ioctl", __FUNCTION__); + + result = ioctl(p_dev->fd, BTHID_HID_INFO, &ctrl); + + BTIF_TRACE_WARNING4("%s: fd = %d, dscp_len = %d, result = %d", __FUNCTION__, p_dev->fd, dscp_len, result); + + if (result != 0) { + BTIF_TRACE_WARNING2("%s: Error: failed to send DSCP, result = %d", __FUNCTION__, result); + + /* The HID report descriptor is corrupted. Close the driver. */ + close(p_dev->fd); + p_dev->fd = -1; + } +#endif +} + + |