summaryrefslogtreecommitdiffstats
path: root/stack/gap/gap_ble.c
diff options
context:
space:
mode:
authorAndre Eisenbach <andre@broadcom.com>2013-08-05 16:55:38 -0700
committerMatthew Xie <mattx@google.com>2013-08-13 18:40:33 -0700
commit6975b4d711142b885af479721cada448952c6b41 (patch)
treea381f9307fdc9b0fd64adc2c9a8abde1b92ac014 /stack/gap/gap_ble.c
parenta16d6b07c1c3b08e8765f9d2b16ff1f22b0bdfc6 (diff)
downloadandroid_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.c48
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],