From 87072892dc006f4c037aae0a346eda6c18e6b8ba Mon Sep 17 00:00:00 2001 From: Hemant Gupta Date: Wed, 19 Nov 2014 19:09:54 +0530 Subject: [PATCH] HID: Handle closing of uhid driver in case failure This patch handles closure of the uhid driver in case of following: - Due to concurrency of disconnection from a conencted device and an incoming connection request from another device, the error code for the ACL disconnection becomes HCI_ERR_HOST_REJECT_SECURITY in the stack. - On reception of disconnection with that error codes, the uhid driver was not closed from the btif layer leading to issues in reconnection with same device that got disconnected. Change-Id: I13c83757051850cc631aa1c24a036a2e1a4d0087 --- btif/co/bta_hh_co.c | 1 + btif/src/btif_hh.c | 26 ++++++++++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/btif/co/bta_hh_co.c b/btif/co/bta_hh_co.c index b0ab2e08e..b5c845a95 100644 --- a/btif/co/bta_hh_co.c +++ b/btif/co/bta_hh_co.c @@ -207,6 +207,7 @@ void bta_hh_co_destroy(int fd) memset(&ev, 0, sizeof(ev)); ev.type = UHID_DESTROY; uhid_write(fd, &ev); + APPL_TRACE_DEBUG("%s: closing fd=%d", __func__, fd); close(fd); } diff --git a/btif/src/btif_hh.c b/btif/src/btif_hh.c index 997f5233a..ee5d9e3ad 100644 --- a/btif/src/btif_hh.c +++ b/btif/src/btif_hh.c @@ -810,10 +810,21 @@ static void btif_hh_upstreams_evt(UINT16 event, char* p_param) else { bt_bdaddr_t *bdaddr = (bt_bdaddr_t*)p_data->conn.bda; btif_dm_hh_open_failed(bdaddr); + p_dev = btif_hh_find_dev_by_bda(bdaddr); + if (p_dev != NULL) { + if(p_dev->vup_timer_active) + btif_hh_stop_vup_timer(&(p_dev->bd_addr)); + if (p_dev->fd >= 0) { + bta_hh_co_destroy(p_dev->fd); + p_dev->fd = -1; + } + p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED; + } HAL_CBACK(bt_hh_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda,BTHH_CONN_STATE_DISCONNECTED); btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED; } break; + case BTA_HH_CLOSE_EVT: BTIF_TRACE_DEBUG("BTA_HH_CLOSE_EVT: status = %d, handle = %d", p_data->dev_status.status, p_data->dev_status.handle); @@ -821,20 +832,20 @@ static void btif_hh_upstreams_evt(UINT16 event, char* p_param) if (p_dev != NULL) { BTIF_TRACE_DEBUG("%s: uhid fd = %d", __FUNCTION__, p_dev->fd); if(p_dev->vup_timer_active) - { btif_hh_stop_vup_timer(&(p_dev->bd_addr)); + if (p_dev->fd >= 0) { + bta_hh_co_destroy(p_dev->fd); + p_dev->fd = -1; } 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_DEBUG("%s: Closing uhid fd = %d", __FUNCTION__, p_dev->fd); - bta_hh_co_destroy(p_dev->fd); - p_dev->fd = -1; } else { BTIF_TRACE_WARNING("Error: cannot find device with handle %d", p_data->dev_status.handle); } break; + case BTA_HH_GET_RPT_EVT: { BT_HDR *hdr = p_data->hs_data.rsp_data.p_rpt_data; UINT8 *data = NULL; @@ -861,6 +872,7 @@ static void btif_hh_upstreams_evt(UINT16 event, char* p_param) } break; } + case BTA_HH_SET_RPT_EVT: BTIF_TRACE_DEBUG("BTA_HH_SET_RPT_EVT: status = %d, handle = %d", p_data->dev_status.status, p_data->dev_status.handle); @@ -1660,8 +1672,10 @@ static void cleanup( void ) p_dev = &btif_hh_cb.devices[i]; if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->fd >= 0) { BTIF_TRACE_DEBUG("%s: Closing uhid fd = %d", __FUNCTION__, p_dev->fd); - bta_hh_co_destroy(p_dev->fd); - p_dev->fd = -1; + if (p_dev->fd >= 0) { + bta_hh_co_destroy(p_dev->fd); + p_dev->fd = -1; + } p_dev->hh_keep_polling = 0; p_dev->hh_poll_thread_id = -1; } -- 2.11.0