From f7e6c7dbd74cf9e146ce4267b666c05d2fcff2ac Mon Sep 17 00:00:00 2001 From: Priti Aghera Date: Tue, 14 Aug 2012 15:07:31 -0700 Subject: Modified HID host to use kernel UHID driver Included more error checking and removed unused code Removed header file as the header file will be included in kernel Change-Id: I3086d6520fc764b73e0e740dadaa64a9cdc11945 --- btif/co/bta_hh_co.c | 177 +++++++++++++++++++++++++++------------------------- btif/src/btif_hh.c | 37 ++++------- 2 files changed, 104 insertions(+), 110 deletions(-) mode change 100644 => 100755 btif/co/bta_hh_co.c mode change 100644 => 100755 btif/src/btif_hh.c (limited to 'btif') diff --git a/btif/co/bta_hh_co.c b/btif/co/bta_hh_co.c old mode 100644 new mode 100755 index 9eb39d2..a2cbd7b --- a/btif/co/bta_hh_co.c +++ b/btif/co/bta_hh_co.c @@ -53,46 +53,60 @@ #include #include #include +#include #include "btif_hh.h" - #include "bta_api.h" #include "bta_hh_api.h" -#define UINT8 uint8_t -#define UINT16 uint16_t +const char *dev_path = "/dev/uhid"; + -#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 +/*Internal function to perform UHID write and error checking*/ +static int uhid_write(int fd, const struct uhid_event *ev) +{ + ssize_t ret; + ret = write(fd, ev, sizeof(*ev)); + if (ret < 0){ + int rtn = -errno; + BTIF_TRACE_ERROR2("%s: Cannot write to uhid:%s",__FUNCTION__,strerror(errno)); + return rtn; + } else if (ret != sizeof(*ev)) { + BTIF_TRACE_ERROR3("%s: Wrong size written to uhid: %ld != %lu", + __FUNCTION__, ret, sizeof(*ev)); + return -EFAULT; + } else { + return 0; + } +} -typedef struct BTHID_CONTROL +void bta_hh_co_destroy(int fd) { - 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; - - -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) + struct uhid_event ev; + memset(&ev, 0, sizeof(ev)); + ev.type = UHID_DESTROY; + uhid_write(fd, &ev); + close(fd); +} + +int bta_hh_co_write(int fd, UINT8* rpt, UINT16 len) { -/* - --TODO - */ + BTIF_TRACE_DEBUG0("bta_hh_co_data: UHID write"); + struct uhid_event ev; + memset(&ev, 0, sizeof(ev)); + ev.type = UHID_INPUT; + ev.u.input.size = len; + if(len > sizeof(ev.u.input.data)){ + BTIF_TRACE_WARNING1("%s:report size greater than allowed size",__FUNCTION__); + return -1; + } + memcpy(ev.u.input.data, rpt, len); + return uhid_write(fd, &ev); + } + /******************************************************************************* ** ** Function bta_hh_co_open @@ -120,17 +134,22 @@ void bta_hh_co_open(UINT8 dev_handle, UINT8 sub_class, tBTA_HH_ATTR_MASK attr_ma 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_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); + 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); + p_dev->fd = open(dev_path, O_RDWR | O_CLOEXEC); + if (p_dev->fd < 0){ + BTIF_TRACE_ERROR2("%s: Error: failed to open uhid, err:%s", + __FUNCTION__,strerror(errno)); + }else + BTIF_TRACE_DEBUG2("%s: uhid fd = %d", __FUNCTION__, p_dev->fd); } break; @@ -149,21 +168,27 @@ void bta_hh_co_open(UINT8 dev_handle, UINT8 sub_class, tBTA_HH_ATTR_MASK attr_ma p_dev->app_id = app_id; btif_hh_cb.device_num++; - // 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); + // This is a new device,open the uhid driver now. + p_dev->fd = open(dev_path, O_RDWR | O_CLOEXEC); + if (p_dev->fd < 0){ + BTIF_TRACE_ERROR2("%s: Error: failed to open uhid, err:%s", + __FUNCTION__,strerror(errno)); + }else + BTIF_TRACE_DEBUG2("%s: uhid fd = %d", __FUNCTION__, p_dev->fd); + + break; } } } if (p_dev == NULL) { - BTIF_TRACE_WARNING1("%s: Error: too many HID devices are connected", __FUNCTION__); + BTIF_TRACE_ERROR1("%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); + BTIF_TRACE_DEBUG2("%s: Return device status %d", __FUNCTION__, p_dev->dev_status); } @@ -205,7 +230,6 @@ void bta_hh_co_data(UINT8 dev_handle, UINT8 *p_rpt, UINT16 len, tBTA_HH_PROTO_MO 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", @@ -218,12 +242,8 @@ void bta_hh_co_data(UINT8 dev_handle, UINT8 *p_rpt, UINT16 len, tBTA_HH_PROTO_MO } // 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 - */ - write(p_dev->fd, p_rpt, len); - } - else { + bta_hh_co_write(p_dev->fd, p_rpt, len); + }else { BTIF_TRACE_WARNING3("%s: Error: fd = %d, len = %d", __FUNCTION__, p_dev->fd, len); } } @@ -246,50 +266,37 @@ void bta_hh_co_send_hid_info(btif_hh_device_t *p_dev, char *dev_name, UINT16 ven int dscp_len, UINT8 *p_dscp) { int result; - tBTHID_CONTROL ctrl; - - /* - 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]); - } - */ + struct uhid_event ev; + 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_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); + +//Create and send hid descriptor to kernel + memset(&ev, 0, sizeof(ev)); + ev.type = UHID_CREATE; + strncpy((char*)ev.u.create.name, dev_name, sizeof(ev.u.create.name) - 1); + ev.u.create.rd_size = dscp_len; + ev.u.create.rd_data = p_dscp; + ev.u.create.bus = BUS_BLUETOOTH; + ev.u.create.vendor = vendor_id; + ev.u.create.product = product_id; + ev.u.create.version = version; + ev.u.create.country = ctry_code; + result = uhid_write(p_dev->fd, &ev); + + BTIF_TRACE_WARNING4("%s: fd = %d, dscp_len = %d, result = %d", __FUNCTION__, + p_dev->fd, dscp_len, result); + + if (result) { BTIF_TRACE_WARNING2("%s: Error: failed to send DSCP, result = %d", __FUNCTION__, result); /* The HID report descriptor is corrupted. Close the driver. */ diff --git a/btif/src/btif_hh.c b/btif/src/btif_hh.c old mode 100644 new mode 100755 index c6fd378..76d8ec3 --- a/btif/src/btif_hh.c +++ b/btif/src/btif_hh.c @@ -67,10 +67,6 @@ #include "bd.h" #include "btif_storage.h" - - - - #include "btif_common.h" #include "btif_util.h" #include "btif_hh.h" @@ -163,7 +159,8 @@ static bthh_callbacks_t *bt_hh_callbacks = NULL; /************************************************************************************ ** Externs ************************************************************************************/ - +extern void bta_hh_co_destroy(int fd); +extern void bta_hh_co_write(int fd, UINT8* rpt, UINT16 len); extern bt_status_t btif_dm_remove_bond(const bt_bdaddr_t *bd_addr); extern 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, @@ -350,9 +347,9 @@ void btif_hh_remove_device(bt_bdaddr_t bd_addr) GKI_freebuf(p_dev->p_buf); p_dev->p_buf = NULL; } - BTIF_TRACE_DEBUG2("%s: bthid fd = %d", __FUNCTION__, p_dev->fd); + BTIF_TRACE_DEBUG2("%s: uhid fd = %d", __FUNCTION__, p_dev->fd); if (p_dev->fd >= 0) { - close(p_dev->fd); + bta_hh_co_destroy(p_dev->fd); p_dev->fd = -1; } } @@ -583,10 +580,9 @@ static void btif_hh_upstreams_evt(UINT16 event, char* p_param) HAL_CBACK(bt_hh_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda,BTHH_CONN_STATE_DISCONNECTED); } else if (p_dev->fd < 0) { - BTIF_TRACE_WARNING0("BTA_HH_OPEN_EVT: Error, failed to find the bthid driver..."); + BTIF_TRACE_WARNING0("BTA_HH_OPEN_EVT: Error, failed to find the uhid driver..."); memcpy(&(p_dev->bd_addr), p_data->conn.bda, BD_ADDR_LEN); //remove the connection and then try again to reconnect from the mouse side to recover - //p_dev->dev_status = BTHH_CONN_STATE_FAILED_NO_BTHID_DRIVER; btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED; BTA_HhClose(p_data->conn.handle); } @@ -612,18 +608,18 @@ static void btif_hh_upstreams_evt(UINT16 event, char* p_param) p_data->dev_status.status, p_data->dev_status.handle); p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle); if (p_dev != NULL) { - BTIF_TRACE_DEBUG2("%s: bthid fd = %d", __FUNCTION__, p_dev->fd); + BTIF_TRACE_DEBUG2("%s: uhid fd = %d", __FUNCTION__, p_dev->fd); if (p_dev->fd >= 0){ UINT8 hidreport[9]; memset(hidreport,0,9); hidreport[0]=1; - write(p_dev->fd, hidreport, 9); + bta_hh_co_write(p_dev->fd , hidreport, sizeof(hidreport)); } btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED; p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED; HAL_CBACK(bt_hh_callbacks, connection_state_cb,&(p_dev->bd_addr), p_dev->dev_status); - BTIF_TRACE_DEBUG2("%s: Closing bthid.ko fd = %d", __FUNCTION__, p_dev->fd); - close(p_dev->fd); + BTIF_TRACE_DEBUG2("%s: Closing uhid fd = %d", __FUNCTION__, p_dev->fd); + bta_hh_co_destroy(p_dev->fd); p_dev->fd = -1; } else { @@ -687,7 +683,7 @@ static void btif_hh_upstreams_evt(UINT16 event, char* p_param) return; } if (p_dev->fd < 0) { - ALOGE("BTA_HH_GET_DSCP_EVT: Error, failed to find the bthid driver..."); + ALOGE("BTA_HH_GET_DSCP_EVT: Error, failed to find the uhid driver..."); return; } { @@ -698,15 +694,6 @@ static void btif_hh_upstreams_evt(UINT16 event, char* p_param) } BTIF_TRACE_WARNING2("%s: name = %s", __FUNCTION__, cached_name); - - //Fix for Apple Magic Mouse - //For Apple Magic Mouse change the product id and version in order to bind to generic-bluetooth driver - if((p_data->dscp_info.vendor_id == MAGICMOUSE_VENDOR_ID) && (p_data->dscp_info.product_id == MAGICMOUSE_PRODUCT_ID)) - { - p_data->dscp_info.product_id = 0x30c; /* Product id for Mighty mouse*/ - p_data->dscp_info.version = 0x0200; /* Version for Mighty mouse*/ - } - bta_hh_co_send_hid_info(p_dev, cached_name, p_data->dscp_info.vendor_id, p_data->dscp_info.product_id, p_data->dscp_info.version, p_data->dscp_info.ctry_code, @@ -1411,8 +1398,8 @@ static void cleanup( void ) 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->fd >= 0) { - BTIF_TRACE_DEBUG2("%s: Closing bthid.ko fd = %d", __FUNCTION__, p_dev->fd); - close(p_dev->fd); + BTIF_TRACE_DEBUG2("%s: Closing uhid fd = %d", __FUNCTION__, p_dev->fd); + bta_hh_co_destroy(p_dev->fd); p_dev->fd = -1; } } -- cgit v1.1