diff options
author | Andre Eisenbach <andre@broadcom.com> | 2013-08-05 16:55:38 -0700 |
---|---|---|
committer | Matthew Xie <mattx@google.com> | 2013-08-13 18:40:33 -0700 |
commit | 6975b4d711142b885af479721cada448952c6b41 (patch) | |
tree | a381f9307fdc9b0fd64adc2c9a8abde1b92ac014 /stack/gap/gap_ble.c | |
parent | a16d6b07c1c3b08e8765f9d2b16ff1f22b0bdfc6 (diff) | |
download | android_system_bt-6975b4d711142b885af479721cada448952c6b41.tar.gz android_system_bt-6975b4d711142b885af479721cada448952c6b41.tar.bz2 android_system_bt-6975b4d711142b885af479721cada448952c6b41.zip |
LE: UPF 45 bug fixes
This change fixes the following issues:
- Second GATT-over-BR/EDR channel cannot be established when there
already is an existing GATT-over-BR/EDR channel
- If encryption fails for an LE connection due to a missing key,
the security state is not being cleared and blocks all further
security processing
- When DM discovery of an LE Peripheral device fails with a
connection timeout, no further discovery requests can be made
- GATT service discovery can get into endless loop when duplicate descriptor
definitions are found on the remote device
- When GATT over BR/EDR fails, BTA does not give a connection
callback to the application initiating the connection
- BR/EDR connection to remote platform does not generate API callbacks
- Stack crash discovered during UPF after remote disconnects
- The host is sending HCI disconnect to invalid HCI handle when
SMP fails because of a connection timeout
- Possible race condition:
If a disconnect is immediately followed by a connection complete,
the connection complete cannot be processed in the BTA GATT state
machine
- Write Complete event is not triggered for Prepare Write requests
Change-Id: I539cdedd68007818ff4f0d0213cee1c913f72d0f
Conflicts:
bta/gatt/bta_gatts_act.c
Diffstat (limited to 'stack/gap/gap_ble.c')
-rw-r--r-- | stack/gap/gap_ble.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/stack/gap/gap_ble.c b/stack/gap/gap_ble.c index 19e24a9da..6e3afebb1 100644 --- a/stack/gap/gap_ble.c +++ b/stack/gap/gap_ble.c @@ -15,7 +15,6 @@ * limitations under the License. * ******************************************************************************/ - #include "bt_target.h" #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE) @@ -585,9 +584,6 @@ void gap_ble_cl_op_cmpl(tGAP_CLCB *p_clcb, BOOLEAN status, UINT16 len, UINT8 *p_ p_clcb->cl_op_uuid = 0; p_clcb->p_cback=NULL; - if (!gap_ble_process_pending_op(p_clcb) && op != 0) - GATT_Disconnect(p_clcb->conn_id); - if (p_dev_name_cback) { GAP_TRACE_EVENT0("calling gap_ble_cl_op_cmpl"); @@ -596,6 +592,10 @@ void gap_ble_cl_op_cmpl(tGAP_CLCB *p_clcb, BOOLEAN status, UINT16 len, UINT8 *p_ (* p_dev_name_cback)(status, p_clcb->bda, len, (char *)p_name); } + if (!gap_ble_process_pending_op(p_clcb) && + p_clcb->cl_op_uuid == 0) + GATT_Disconnect(p_clcb->conn_id); + } /******************************************************************************* @@ -779,16 +779,17 @@ BOOLEAN gap_ble_cl_read_request(tGAP_CLCB *p_clcb, UINT16 uuid, void * p_cback) *******************************************************************************/ BOOLEAN GAP_BleReadPeerPrefConnParams (BD_ADDR peer_bda) { - tGAP_CLCB *p_clcb; + tGAP_CLCB *p_clcb = gap_find_clcb_by_bd_addr (peer_bda); - /* This function should only be called if there is a connection to */ - /* the peer. Get a client handle for that connection. */ - if ((p_clcb = gap_find_clcb_by_bd_addr (peer_bda)) == NULL || - !p_clcb->connected) + if (p_clcb == NULL) { - GAP_TRACE_ERROR0("No connection, can not update reconnect address"); - return(FALSE); + if ((p_clcb = gap_clcb_alloc(0, peer_bda)) == NULL) + { + GAP_TRACE_ERROR0("GAP_BleReadPeerPrefConnParams max connection reached"); + return FALSE; + } + p_clcb->connected = FALSE; } GAP_TRACE_API3 ("GAP_BleReadPeerPrefConnParams() - BDA: %08x%04x cl_op_uuid: 0x%04x", @@ -799,7 +800,18 @@ BOOLEAN GAP_BleReadPeerPrefConnParams (BD_ADDR peer_bda) if (p_clcb->cl_op_uuid != 0) return(FALSE); + /* hold the link here */ + GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE); + + if (p_clcb->connected) + { return gap_ble_cl_read_request(p_clcb, GATT_UUID_GAP_PREF_CONN_PARAM, NULL); + } + /* Mark currently active operation */ + p_clcb->cl_op_uuid = GATT_UUID_GAP_PREF_CONN_PARAM; + + return(TRUE); + } @@ -814,22 +826,20 @@ BOOLEAN GAP_BleReadPeerPrefConnParams (BD_ADDR peer_bda) *******************************************************************************/ BOOLEAN GAP_BleReadPeerDevName (BD_ADDR peer_bda, tGAP_BLE_DEV_NAME_CBACK *p_cback) { - tGAP_CLCB *p_clcb = gap_find_clcb_by_bd_addr (peer_bda); + tGAP_CLCB *p_clcb = NULL; if (p_cback == NULL) return(FALSE); - if (p_clcb == NULL) + if ((p_clcb = gap_find_clcb_by_bd_addr (peer_bda)) == NULL) { - p_clcb = gap_clcb_alloc(0, peer_bda); - p_clcb->connected = FALSE; - } - - if (p_clcb == NULL) + if ((p_clcb = gap_clcb_alloc(0, peer_bda)) == NULL) { GAP_TRACE_ERROR0("GAP_BleReadPeerDevName max connection reached"); + return FALSE; + } + p_clcb->connected = FALSE; } - GAP_TRACE_EVENT3 ("GAP_BleReadPeerDevName() - BDA: %08x%04x cl_op_uuid: 0x%04x", (peer_bda[0]<<24)+(peer_bda[1]<<16)+(peer_bda[2]<<8)+peer_bda[3], |