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
diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c
index c1b1086..68bae03 100644
--- a/bta/dm/bta_dm_act.c
+++ b/bta/dm/bta_dm_act.c
@@ -92,9 +92,6 @@
static BOOLEAN bta_dm_dev_blacklisted_for_switch (BD_ADDR remote_bd_addr);
static void bta_dm_delay_role_switch_cback (TIMER_LIST_ENT *p_tle);
-static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr);
-
-
static void bta_dm_disable_search_and_disc(void);
#if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
#if ((defined SMP_INCLUDED) && (SMP_INCLUDED == TRUE))
@@ -110,6 +107,8 @@
static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir);
static void bta_dm_observe_cmpl_cb (void * p_result);
+static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr);
+
#ifndef BTA_DM_BLE_ADV_CHNL_MAP
#define BTA_DM_BLE_ADV_CHNL_MAP (BTM_BLE_ADV_CHNL_37|BTM_BLE_ADV_CHNL_38|BTM_BLE_ADV_CHNL_39)
#endif
@@ -193,6 +192,7 @@
#if BLE_INCLUDED && BTA_GATT_INCLUDED
,BTM_SEC_SERVICE_ATT /* BTA_GATT_SERVICE_ID */
#endif
+
};
/* bta security callback */
@@ -267,7 +267,6 @@
tBTA_SYS_HW_MSG *sys_enable_event;
tBTA_DM_SEC sec_event;
-
/* if already in use, return an error */
if( bta_dm_cb.is_bta_dm_active == TRUE )
{
@@ -279,7 +278,6 @@
return;
}
-
/* first, register our callback to SYS HW manager */
bta_sys_hw_register( BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback );
@@ -382,6 +380,7 @@
{
BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ID, (tBTM_BLE_LOCAL_KEYS *)&id_key);
}
+ bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
#endif
BTM_SecRegister((tBTM_APPL_INFO*)&bta_security);
@@ -2353,11 +2352,6 @@
{
tBTA_DM_MSG * p_msg;
-#if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
- tBT_DEVICE_TYPE dev_type;
- tBLE_ADDR_TYPE addr_type;
-#endif
-
APPL_TRACE_DEBUG6("bta_dm_discover_device, BDA:0x%02X%02X%02X%02X%02X%02X",
remote_bd_addr[0],remote_bd_addr[1],
remote_bd_addr[2],remote_bd_addr[3],
@@ -2434,9 +2428,7 @@
bta_dm_search_cb.services_to_search
);
}
- BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type);
-
- if (dev_type == BT_DEVICE_TYPE_BLE)
+ if (BTM_UseLeLink(bta_dm_search_cb.peer_bdaddr))
/*
if ( bta_dm_search_cb.p_btm_inq_info != NULL &&
bta_dm_search_cb.p_btm_inq_info->results.device_type == BT_DEVICE_TYPE_BLE &&
@@ -2656,10 +2648,6 @@
static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name)
{
tBTA_DM_REM_NAME * p_msg;
-#if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
- tBT_DEVICE_TYPE dev_type;
- tBLE_ADDR_TYPE addr_type;
-#endif
APPL_TRACE_DEBUG2("bta_dm_remname_cback len = %d name=<%s>", p_remote_name->length,
p_remote_name->remote_bd_name);
@@ -2671,8 +2659,7 @@
BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
#if BLE_INCLUDED == TRUE
- BTM_ReadDevInfo(p_remote_name->remote_bd_name, &dev_type, &addr_type);
- if (dev_type == BT_DEVICE_TYPE_BLE)
+ if (BTM_UseLeLink(bta_dm_search_cb.peer_bdaddr))
GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr);
#endif
if ((p_msg = (tBTA_DM_REM_NAME *) GKI_getbuf(sizeof(tBTA_DM_REM_NAME))) != NULL)
@@ -2958,6 +2945,7 @@
}
/* delete this device entry from Sec Dev DB */
bta_dm_remove_sec_dev_entry(bd_addr);
+
}
return BTM_SUCCESS;
@@ -3188,7 +3176,6 @@
*******************************************************************************/
static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data)
{
-
tBTA_DM_ACL_CHANGE * p_msg;
if ((p_msg = (tBTA_DM_ACL_CHANGE *) GKI_getbuf(sizeof(tBTA_DM_ACL_CHANGE))) != NULL)
@@ -3763,6 +3750,7 @@
}
}
+
/*******************************************************************************
**
** Function bta_dm_adjust_roles
@@ -4974,6 +4962,9 @@
}
#if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
+#ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
+#define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000
+#endif
/*******************************************************************************
**
@@ -5133,15 +5124,41 @@
}
if (conn_id != BTA_GATT_INVALID_CONN_ID)
{
- BTA_GATTC_Close(conn_id);
+ if (BTA_DM_GATT_CLOSE_DELAY_TOUT != 0)
+ {
+ bta_sys_start_timer(&bta_dm_search_cb.gatt_close_timer, BTA_DM_DISC_CLOSE_TOUT_EVT,
+ BTA_DM_GATT_CLOSE_DELAY_TOUT);
+ }
+ else
+ {
+ BTA_GATTC_Close(conn_id);
+ bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
+ }
}
- bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
+
bta_dm_search_cb.gatt_disc_active = FALSE;
}
}
/*******************************************************************************
**
+** Function bta_dm_close_gatt_conn
+**
+** Description This function close the GATT connection after delay timeout.
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data)
+{
+ if (bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID)
+ BTA_GATTC_Close(bta_dm_search_cb.conn_id);
+
+ bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
+}
+
+/*******************************************************************************
+**
** Function btm_dm_start_gatt_discovery
**
** Description This is GATT initiate the service search by open a GATT connection
@@ -5153,7 +5170,17 @@
void btm_dm_start_gatt_discovery (BD_ADDR bd_addr)
{
bta_dm_search_cb.gatt_disc_active = TRUE;
- BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE);
+
+ /* connection is already open */
+ if (bdcmp(bta_dm_search_cb.pending_close_bda, bd_addr) == 0 &&
+ bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID)
+ {
+ memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
+ bta_sys_stop_timer(&bta_dm_search_cb.gatt_close_timer);
+ btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id);
+ }
+ else
+ BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE);
}
/*******************************************************************************
diff --git a/bta/dm/bta_dm_int.h b/bta/dm/bta_dm_int.h
index ca34356..9b3069d 100644
--- a/bta/dm/bta_dm_int.h
+++ b/bta/dm/bta_dm_int.h
@@ -128,8 +128,8 @@
BTA_DM_SDP_RESULT_EVT,
BTA_DM_SEARCH_CMPL_EVT,
BTA_DM_DISCOVERY_RESULT_EVT,
- BTA_DM_API_DI_DISCOVER_EVT
-
+ BTA_DM_API_DI_DISCOVER_EVT,
+ BTA_DM_DISC_CLOSE_TOUT_EVT
};
/* data type for BTA_DM_API_ENABLE_EVT */
@@ -818,6 +818,8 @@
UINT8 * p_ble_rawdata;
UINT32 ble_raw_size;
UINT32 ble_raw_used;
+ TIMER_LIST_ENT gatt_close_timer;
+ BD_ADDR pending_close_bda;
#endif
#endif
@@ -991,6 +993,7 @@
extern void bta_dm_ble_set_bg_conn_type (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_conn_params (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_scan_params (tBTA_DM_MSG *p_data);
+extern void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_observe (tBTA_DM_MSG *p_data);
#endif
extern void bta_dm_set_encryption(tBTA_DM_MSG *p_data);
diff --git a/bta/dm/bta_dm_main.c b/bta/dm/bta_dm_main.c
index dc94c6c..c68f315 100644
--- a/bta/dm/bta_dm_main.c
+++ b/bta/dm/bta_dm_main.c
@@ -61,18 +61,18 @@
bta_dm_close_acl, /* 10 BTA_DM_API_ADD_DEVICE_EVT */
/* security API events */
- bta_dm_bond, /* 10 BTA_DM_API_BOND_EVT */
- bta_dm_bond_cancel, /* 11 BTA_DM_API_BOND_CANCEL_EVT */
- bta_dm_pin_reply, /* 12 BTA_DM_API_PIN_REPLY_EVT */
- bta_dm_link_policy, /* 13 BTA_DM_API_LINK_POLICY_EVT */
- bta_dm_auth_reply, /* 14 BTA_DM_API_AUTH_REPLY_EVT */
+ bta_dm_bond, /* 11 BTA_DM_API_BOND_EVT */
+ bta_dm_bond_cancel, /* 12 BTA_DM_API_BOND_CANCEL_EVT */
+ bta_dm_pin_reply, /* 13 BTA_DM_API_PIN_REPLY_EVT */
+ bta_dm_link_policy, /* 14 BTA_DM_API_LINK_POLICY_EVT */
+ bta_dm_auth_reply, /* 15 BTA_DM_API_AUTH_REPLY_EVT */
/* power manger events */
- bta_dm_pm_btm_status, /* 15 BTA_DM_PM_BTM_STATUS_EVT */
- bta_dm_pm_timer, /* 16 BTA_DM_PM_TIMER_EVT*/
+ bta_dm_pm_btm_status, /* 16 BTA_DM_PM_BTM_STATUS_EVT */
+ bta_dm_pm_timer, /* 17 BTA_DM_PM_TIMER_EVT*/
/* simple pairing events */
- bta_dm_confirm, /* 17 BTA_DM_API_CONFIRM_EVT */
+ bta_dm_confirm, /* 18 BTA_DM_API_CONFIRM_EVT */
bta_dm_set_encryption, /* BTA_DM_API_SET_ENCRYPTION_EVT */
@@ -134,7 +134,10 @@
BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL, /* 15 bta_dm_search_cancel_transac_cmpl */
BTA_DM_DISC_RMT_NAME, /* 16 bta_dm_disc_rmt_name */
BTA_DM_API_DI_DISCOVER, /* 17 bta_dm_di_disc */
- BTA_DM_SEARCH_NUM_ACTIONS /* 18 */
+#if BLE_INCLUDED == TRUE
+ BTA_DM_CLOSE_GATT_CONN, /* 18 bta_dm_close_gatt_conn */
+#endif
+ BTA_DM_SEARCH_NUM_ACTIONS /* 19 */
};
@@ -160,6 +163,9 @@
bta_dm_search_cancel_transac_cmpl, /* 15 BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL */
bta_dm_disc_rmt_name, /* 16 BTA_DM_DISC_RMT_NAME */
bta_dm_di_disc /* 17 BTA_DM_API_DI_DISCOVER */
+#if BLE_INCLUDED == TRUE
+ ,bta_dm_close_gatt_conn
+#endif
};
#define BTA_DM_SEARCH_IGNORE BTA_DM_SEARCH_NUM_ACTIONS
@@ -184,6 +190,9 @@
/* SEARCH_CMPL_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
/* DISCV_RES_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
/* API_DI_DISCOVER_EVT */ {BTA_DM_API_DI_DISCOVER, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE}
+#if BLE_INCLUDED == TRUE
+/* DISC_CLOSE_TOUT_EVT */ ,{BTA_DM_CLOSE_GATT_CONN, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE}
+#endif
};
const UINT8 bta_dm_search_search_active_st_table[][BTA_DM_SEARCH_NUM_COLS] =
@@ -200,6 +209,9 @@
/* DISCV_RES_EVT */ {BTA_DM_SEARCH_RESULT, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
/* API_DI_DISCOVER_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE}
+#if BLE_INCLUDED == TRUE
+/* DISC_CLOSE_TOUT_EVT */ ,{BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE}
+#endif
};
@@ -217,6 +229,9 @@
/* DISCV_RES_EVT */ {BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL, BTA_DM_SEARCH_CANCEL_CMPL, BTA_DM_SEARCH_IDLE},
/* API_DI_DISCOVER_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING}
+#if BLE_INCLUDED == TRUE
+/* DISC_CLOSE_TOUT_EVT */ ,{BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING}
+#endif
};
@@ -234,6 +249,10 @@
/* DISCV_RES_EVT */ {BTA_DM_DISC_RESULT, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
/* API_DI_DISCOVER_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE}
+#if BLE_INCLUDED == TRUE
+/* DISC_CLOSE_TOUT_EVT */ ,{BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE}
+#endif
+
};
typedef const UINT8 (*tBTA_DM_ST_TBL)[BTA_DM_SEARCH_NUM_COLS];
diff --git a/bta/gatt/bta_gattc_act.c b/bta/gatt/bta_gattc_act.c
index a3b18c8..211ec34 100644
--- a/bta/gatt/bta_gattc_act.c
+++ b/bta/gatt/bta_gattc_act.c
@@ -471,7 +471,7 @@
p_data->api_conn.remote_bda,
&p_clcb->bta_conn_id))
{
- gattc_data.hdr.layer_specific = p_clcb->bta_conn_id;
+ gattc_data.int_conn.hdr.layer_specific = p_clcb->bta_conn_id;
bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
}
@@ -511,7 +511,7 @@
p_data->remote_bda,
&conn_id))
{
- if ((p_clcb = bta_gattc_clcb_alloc(p_data->client_if, p_data->remote_bda)) != NULL)
+ if ((p_clcb = bta_gattc_find_alloc_clcb(p_data->client_if, p_data->remote_bda)) != NULL)
{
gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
@@ -628,11 +628,11 @@
if (p_data != NULL)
{
APPL_TRACE_DEBUG1("bta_gattc_conn conn_id=%d",p_data->hdr.layer_specific);
+ p_clcb->bta_conn_id = p_data->int_conn.hdr.layer_specific;
+ GATT_GetConnectionInfor(p_data->int_conn.hdr.layer_specific, &gatt_if, p_clcb->bda);
+ }
p_clcb->p_srcb->connected = TRUE;
- p_clcb->bta_conn_id = p_data->hdr.layer_specific;
- GATT_GetConnectionInfor(p_data->hdr.layer_specific, &gatt_if, p_clcb->bda);
-
/* start database cache if needed */
if (p_clcb->p_srcb->p_srvc_cache == NULL ||
p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE)
@@ -640,7 +640,7 @@
if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE)
{
p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD;
- bta_gattc_sm_execute(p_clcb, BTA_GATTC_START_CACHE_EVT, p_data);
+ bta_gattc_sm_execute(p_clcb, BTA_GATTC_START_CACHE_EVT, NULL);
}
else /* cache is building */
p_clcb->state = BTA_GATTC_DISCOVER_ST;
@@ -668,7 +668,6 @@
p_clcb->bta_conn_id);
}
}
-}
/*******************************************************************************
**
** Function bta_gattc_close_fail
@@ -721,19 +720,13 @@
if (!BTM_IsBleLink(p_clcb->bda))
bta_sys_conn_close( BTA_ID_GATTC ,BTA_ALL_APP_ID, p_clcb->bda);
- if (p_clcb->status == BTA_GATT_OK)
- {
- bta_gattc_clcb_dealloc(p_clcb);
- }
+ bta_gattc_clcb_dealloc(p_clcb);
if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT)
cb_data.close.status = GATT_Disconnect(p_data->hdr.layer_specific);
- if ((p_cback != NULL) && (*p_cback != NULL))
- {
- (*p_cback)(BTA_GATTC_CLOSE_EVT,(tBTA_GATTC *)&cb_data);
- }
-
+ if(p_cback)
+ (* p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data);
if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending)
{
@@ -955,7 +948,7 @@
if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
&p_data->api_read.srvc_id,
&p_data->api_read.char_id,
- p_data->api_read.descr_type)) == 0)
+ p_data->api_read.p_descr_type)) == 0)
{
op_cmpl.status = BTA_GATT_ERROR;
}
@@ -992,11 +985,9 @@
tGATT_READ_PARAM read_param;
tBTA_GATTC_OP_CMPL op_cmpl;
tBTA_GATTC_ATTR_ID *p_id;
- tBT_UUID dummy_uuid;
if (bta_gattc_enqueue(p_clcb, p_data))
{
- memset(&dummy_uuid, 0, sizeof(tBT_UUID));
memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
p_id = p_data->api_read_multi.p_id_list;
@@ -1010,14 +1001,14 @@
handle = bta_gattc_id2handle(p_clcb->p_srcb,
&p_id->id_value.char_id.srvc_id,
&p_id->id_value.char_id.char_id,
- dummy_uuid);
+ NULL);
}
else if (p_id->id_type == BTA_GATT_TYPE_CHAR_DESCR)
{
handle = bta_gattc_id2handle(p_clcb->p_srcb,
&p_id->id_value.char_descr_id.char_id.srvc_id,
&p_id->id_value.char_descr_id.char_id.char_id,
- p_id->id_value.char_descr_id.descr_type);
+ &p_id->id_value.char_descr_id.descr_id);
}
else
{
@@ -1072,7 +1063,7 @@
if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
&p_data->api_write.srvc_id,
&p_data->api_write.char_id,
- p_data->api_write.descr_type)) == 0)
+ p_data->api_write.p_descr_type)) == 0)
{
status = BTA_GATT_ERROR;
}
@@ -1143,12 +1134,11 @@
void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
UINT16 handle;
- tBT_UUID null_uuid = {0};
if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
&p_data->api_confirm.srvc_id,
&p_data->api_confirm.char_id,
- null_uuid)) == 0)
+ NULL)) == 0)
{
APPL_TRACE_ERROR0("Can not map service/char ID into valid handle");
}
@@ -1165,7 +1155,6 @@
bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
}
-
}
}
/*******************************************************************************
@@ -1202,7 +1191,7 @@
else
{
cb_data.read.status = bta_gattc_pack_read_cb_data(p_clcb->p_srcb,
- cb_data.read.descr_type,
+ &cb_data.read.descr_type.uuid,
&p_data->p_cmpl->att_value,
&read_value);
cb_data.read.p_value = &read_value;
@@ -1212,10 +1201,11 @@
{
cb_data.read.srvc_id = p_clcb->p_q_cmd->api_read.srvc_id;
cb_data.read.char_id = p_clcb->p_q_cmd->api_read.char_id;
- cb_data.read.descr_type = p_clcb->p_q_cmd->api_read.descr_type;
+ if (p_clcb->p_q_cmd->api_read.p_descr_type)
+ memcpy(&cb_data.read.descr_type, p_clcb->p_q_cmd->api_read.p_descr_type, sizeof(tBTA_GATT_ID));
}
- event = (p_clcb->p_q_cmd->api_read.descr_type.len == 0) ? BTA_GATTC_READ_CHAR_EVT: BTA_GATTC_READ_DESCR_EVT;
+ event = (p_clcb->p_q_cmd->api_read.p_descr_type == NULL) ? BTA_GATTC_READ_CHAR_EVT: BTA_GATTC_READ_DESCR_EVT;
cb_data.read.conn_id = p_clcb->bta_conn_id;
utl_freebuf((void **)&p_clcb->p_q_cmd);
@@ -1237,6 +1227,8 @@
tBTA_GATTC cb_data = {0};
UINT8 event;
+ memset(&cb_data, 0, sizeof(tBTA_GATTC));
+
cb_data.write.status = p_data->status;
if (p_data->p_cmpl != NULL)
@@ -1247,9 +1239,10 @@
}
else
{
- cb_data.write.srvc_id = p_clcb->p_q_cmd->api_write.srvc_id;
- cb_data.write.char_id = p_clcb->p_q_cmd->api_write.char_id;
- cb_data.write.descr_type = p_clcb->p_q_cmd->api_write.descr_type;
+ memcpy(&cb_data.write.srvc_id, &p_clcb->p_q_cmd->api_write.srvc_id, sizeof(tBTA_GATT_SRVC_ID));
+ memcpy(&cb_data.write.char_id, &p_clcb->p_q_cmd->api_write.char_id, sizeof(tBTA_GATT_ID));
+ if (p_clcb->p_q_cmd->api_write.p_descr_type)
+ memcpy(&cb_data.write.descr_type, p_clcb->p_q_cmd->api_write.p_descr_type, sizeof(tBTA_GATT_ID));
}
if (p_clcb->p_q_cmd->api_write.hdr.event == BTA_GATTC_API_WRITE_EVT &&
@@ -1257,7 +1250,7 @@
event = BTA_GATTC_PREP_WRITE_EVT;
- else if (p_clcb->p_q_cmd->api_write.descr_type.len == 0)
+ else if (p_clcb->p_q_cmd->api_write.p_descr_type == NULL)
event = BTA_GATTC_WRITE_CHAR_EVT;
@@ -1392,7 +1385,7 @@
{
status = BTA_GATT_OK;
/* search the local cache of a server device */
- bta_gattc_search_service(p_clcb, p_data->api_search.srvc_uuid);
+ bta_gattc_search_service(p_clcb, p_data->api_search.p_srvc_uuid);
}
cb_data.search_cmpl.status = status;
cb_data.search_cmpl.conn_id = p_clcb->bta_conn_id;
@@ -1609,72 +1602,26 @@
static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
BOOLEAN connected, tGATT_DISCONN_REASON reason)
{
- BT_HDR *p_buf;
- tBTA_GATTC_CLCB *p_clcb = NULL;
- UINT8 role ;
+ tBTA_GATTC_DATA *p_buf;
APPL_TRACE_DEBUG4("bta_gattc_conn_cback: cif = %d connected = %d conn_id = %d reaosn = 0x%04x",
gattc_if, connected, conn_id, reason);
- if (connected)
+ if ((p_buf = (tBTA_GATTC_DATA *) GKI_getbuf(sizeof(tBTA_GATTC_DATA))) != NULL)
{
- role = L2CA_GetBleConnRole(bda);
+ memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
- if (role == HCI_ROLE_SLAVE)
- bta_gattc_conn_find_alloc(bda);
-
- /* outgoing connection : locate a logic channel */
- if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda)) == NULL)
- {
- /* for a background connection or listening connection */
- if (/* L2CA_GetBleConnRole(bda)== HCI_ROLE_MASTER && */
- bta_gattc_check_bg_conn(gattc_if, bda, role))
- {
- /* allocate a new channel */
- p_clcb = bta_gattc_clcb_alloc(gattc_if, bda);
- }
- }
- if (p_clcb != NULL)
- {
- p_clcb->bta_conn_id = conn_id;
-
- if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
- {
- p_buf->event = BTA_GATTC_INT_CONN_EVT;
- p_buf->layer_specific = conn_id;
+ p_buf->int_conn.hdr.event = connected ? BTA_GATTC_INT_CONN_EVT: BTA_GATTC_INT_DISCONN_EVT;
+ p_buf->int_conn.hdr.layer_specific = conn_id;
+ p_buf->int_conn.client_if = gattc_if;
+ p_buf->int_conn.role = L2CA_GetBleConnRole(bda);
+ p_buf->int_conn.reason = reason;
+ bdcpy(p_buf->int_conn.remote_bda, bda);
bta_sys_sendmsg(p_buf);
}
}
- }
- else
- {
-#if BLE_INCLUDED == TRUE
- bta_gattc_conn_dealloc(bda);
-#endif
- /* connection attempt timeout, send connection callback event */
- if (reason == GATT_CONN_CANCEL )
- {
- p_clcb = bta_gattc_find_alloc_clcb(gattc_if, bda);
- p_clcb->bta_conn_id = conn_id;
- }
- if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) != NULL)
- {
- if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
- {
- p_buf->event = BTA_GATTC_INT_DISCONN_EVT;
- p_buf->layer_specific = conn_id;
- p_clcb->reason = reason;
- bta_sys_sendmsg(p_buf);
- }
- }
- else
- {
- APPL_TRACE_DEBUG1(" connection ID: [%d] not used by BTA", conn_id);
- }
- }
-}
/*******************************************************************************
**
** Function bta_gattc_process_api_refresh
@@ -1750,8 +1697,8 @@
srvc_chg_uuid.len = 2;
srvc_chg_uuid.uu.uuid16 = GATT_UUID_GATT_SRV_CHGD;
- if (bta_gattc_uuid_compare(p_notify->char_id.srvc_id.id.uuid, gattp_uuid, TRUE) &&
- bta_gattc_uuid_compare(p_notify->char_id.char_id.uuid, srvc_chg_uuid, TRUE))
+ if (bta_gattc_uuid_compare(&p_notify->char_id.srvc_id.id.uuid, &gattp_uuid, TRUE) &&
+ bta_gattc_uuid_compare(&p_notify->char_id.char_id.uuid, &srvc_chg_uuid, TRUE))
{
processed = TRUE;
/* mark service handle change pending */
@@ -1879,11 +1826,7 @@
{
p_clcb->bta_conn_id = conn_id;
- /* send connection event */
- bta_gattc_send_open_cback(p_clrcb,
- BTA_GATT_OK,
- remote_bda,
- conn_id);
+ bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL);
}
else
{
diff --git a/bta/gatt/bta_gattc_api.c b/bta/gatt/bta_gattc_api.c
index 2341aa6..a57fa90 100644
--- a/bta/gatt/bta_gattc_api.c
+++ b/bta/gatt/bta_gattc_api.c
@@ -252,8 +252,12 @@
if (p_srvc_uuid)
{
- memcpy(&p_buf->srvc_uuid, p_srvc_uuid, sizeof(tBT_UUID));
+ p_buf->p_srvc_uuid = (tBT_UUID *)(p_buf + 1);
+ memcpy(p_buf->p_srvc_uuid, p_srvc_uuid, sizeof(tBT_UUID));
}
+ else
+ p_buf->p_srvc_uuid = NULL;
+
bta_sys_sendmsg(p_buf);
}
return;
@@ -289,7 +293,7 @@
return BTA_GATT_ILLEGAL_PARAMETER;
if ((status = bta_gattc_query_cache(conn_id, BTA_GATTC_ATTR_TYPE_CHAR, p_srvc_id, NULL,
- p_char_uuid_cond, &p_char_result->char_id, p_property))
+ p_char_uuid_cond, &p_char_result->char_id, (void *)p_property))
== BTA_GATT_OK)
{
memcpy(&p_char_result->srvc_id, p_srvc_id, sizeof(tBTA_GATT_SRVC_ID));
@@ -333,7 +337,7 @@
&p_start_char_id->char_id,
p_char_uuid_cond,
&p_char_result->char_id,
- p_property))
+ (void *) p_property))
== BTA_GATT_OK)
{
memcpy(&p_char_result->srvc_id, &p_start_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
@@ -379,7 +383,7 @@
NULL))
== BTA_GATT_OK)
{
- memcpy(&p_descr_result->descr_type, &p_descr_result->char_id.char_id.uuid, sizeof(tBT_UUID));
+ memcpy(&p_descr_result->descr_id, &p_descr_result->char_id.char_id, sizeof(tBTA_GATT_ID));
memcpy(&p_descr_result->char_id, p_char_id, sizeof(tBTA_GATTC_CHAR_ID));
}
@@ -421,10 +425,10 @@
&p_start_descr_id->char_id.char_id,
p_descr_uuid_cond,
&p_descr_result->char_id.char_id,
- (void *)&p_start_descr_id->descr_type))
+ (void *)&p_start_descr_id->descr_id))
== BTA_GATT_OK)
{
- memcpy(&p_descr_result->descr_type, &p_descr_result->char_id.char_id.uuid, sizeof(tBT_UUID));
+ memcpy(&p_descr_result->descr_id, &p_descr_result->char_id.char_id, sizeof(tBTA_GATT_ID));
memcpy(&p_descr_result->char_id, p_start_descr_id, sizeof(tBTA_GATTC_CHAR_ID));
}
@@ -463,7 +467,7 @@
NULL,
p_uuid_cond,
&p_result->incl_svc_id.id,
- (tBTA_GATT_CHAR_PROP *)&p_result->incl_svc_id.is_primary))
+ (void *)&p_result->incl_svc_id.is_primary))
== BTA_GATT_OK)
{
memcpy(&p_result->srvc_id, p_srvc_id, sizeof(tBTA_GATT_SRVC_ID));
@@ -505,7 +509,7 @@
&p_start_id->incl_svc_id.id,
p_uuid_cond,
&p_result->incl_svc_id.id,
- (tBTA_GATT_CHAR_PROP *)&p_result->incl_svc_id.is_primary))
+ (void *)&p_result->incl_svc_id.is_primary))
== BTA_GATT_OK)
{
memcpy(&p_result->srvc_id, &p_start_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
@@ -542,6 +546,7 @@
memcpy(&p_buf->srvc_id, &p_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
memcpy(&p_buf->char_id, &p_char_id->char_id, sizeof(tBTA_GATT_ID));
+ p_buf->p_descr_type = NULL;
bta_sys_sendmsg(p_buf);
}
@@ -565,8 +570,9 @@
tBTA_GATT_AUTH_REQ auth_req)
{
tBTA_GATTC_API_READ *p_buf;
+ UINT16 len = (UINT16)(sizeof(tBTA_GATT_ID) + sizeof(tBTA_GATTC_API_READ));
- if ((p_buf = (tBTA_GATTC_API_READ *) GKI_getbuf(sizeof(tBTA_GATTC_API_READ))) != NULL)
+ if ((p_buf = (tBTA_GATTC_API_READ *) GKI_getbuf(len)) != NULL)
{
memset(p_buf, 0, sizeof(tBTA_GATTC_API_READ));
@@ -576,7 +582,9 @@
memcpy(&p_buf->srvc_id, &p_descr_id->char_id.srvc_id, sizeof(tBTA_GATT_SRVC_ID));
memcpy(&p_buf->char_id, &p_descr_id->char_id.char_id, sizeof(tBTA_GATT_ID));
- memcpy(&p_buf->descr_type, &p_descr_id->descr_type, sizeof(tBT_UUID));
+ p_buf->p_descr_type = (tBTA_GATT_ID *)(p_buf + 1);
+
+ memcpy(p_buf->p_descr_type, &p_descr_id->descr_id, sizeof(tBTA_GATT_ID));
bta_sys_sendmsg(p_buf);
}
@@ -699,7 +707,7 @@
tBTA_GATT_AUTH_REQ auth_req)
{
tBTA_GATTC_API_WRITE *p_buf;
- UINT16 len = sizeof(tBTA_GATTC_API_WRITE);
+ UINT16 len = sizeof(tBTA_GATTC_API_WRITE) + sizeof(tBTA_GATT_ID);
if (p_data != NULL)
len += p_data->len;
@@ -714,12 +722,13 @@
memcpy(&p_buf->srvc_id, &p_char_descr_id->char_id.srvc_id, sizeof(tBTA_GATT_SRVC_ID));
memcpy(&p_buf->char_id, &p_char_descr_id->char_id.char_id, sizeof(tBTA_GATT_ID));
- memcpy(&p_buf->descr_type, &p_char_descr_id->descr_type, sizeof(tBT_UUID));
+ p_buf->p_descr_type = (tBTA_GATT_ID *)(p_buf + 1);
+ memcpy(p_buf->p_descr_type, &p_char_descr_id->descr_id, sizeof(tBTA_GATT_ID));
p_buf->write_type = write_type;
if (p_data && p_data->len != 0)
{
- p_buf->p_value = (UINT8 *)(p_buf + 1);
+ p_buf->p_value = (UINT8 *)(p_buf->p_descr_type + 1);
p_buf->len = p_data->len;
/* pack the descr data */
memcpy(p_buf->p_value, p_data->p_value, p_data->len);
diff --git a/bta/gatt/bta_gattc_cache.c b/bta/gatt/bta_gattc_cache.c
index 45fafe8..bc784d7 100644
--- a/bta/gatt/bta_gattc_cache.c
+++ b/bta/gatt/bta_gattc_cache.c
@@ -219,7 +219,7 @@
{
p_srvc_rec = p_srvc_cb->p_srvc_list + i;
- if (bta_gattc_uuid_compare(p_srvc_rec->uuid, uuid, TRUE))
+ if (bta_gattc_uuid_compare(&p_srvc_rec->uuid, &uuid, TRUE))
inst ++;
}
return inst ;
@@ -233,7 +233,7 @@
** Returns characteristic instance ID.
**
*******************************************************************************/
-static UINT8 bta_gattc_get_char_inst_id(tBTA_GATTC_CACHE *p_service_cache, tBT_UUID uuid)
+static UINT8 bta_gattc_get_char_inst_id(tBTA_GATTC_CACHE *p_service_cache, tBT_UUID *p_uuid)
{
UINT8 inst = 0;
tBTA_GATTC_CACHE_ATTR *p_attr;
@@ -245,11 +245,40 @@
{
bta_gattc_pack_attr_uuid(p_attr, &attr_uuid);
- if (bta_gattc_uuid_compare(attr_uuid, uuid, TRUE))
+ if (bta_gattc_uuid_compare(&attr_uuid, p_uuid, TRUE))
inst ++;
p_attr = p_attr->p_next;
}
+
+ return inst ;
+}
+/*******************************************************************************
+**
+** Function bta_gattc_get_char_descr_inst_id
+**
+** Description get characteristic descriptor instance number
+**
+** Returns characteristic instance ID.
+**
+*******************************************************************************/
+static UINT8 bta_gattc_get_char_descr_inst_id(tBTA_GATTC_CACHE_ATTR *p_char_attr, tBT_UUID *p_uuid)
+{
+ UINT8 inst = 0;
+ tBT_UUID attr_uuid;
+
+ if (p_char_attr != NULL)
+ p_char_attr = p_char_attr->p_next;
+
+ while (p_char_attr)
+ {
+ bta_gattc_pack_attr_uuid(p_char_attr, &attr_uuid);
+
+ if (bta_gattc_uuid_compare(&attr_uuid, p_uuid, TRUE))
+ inst ++;
+
+ p_char_attr = p_char_attr->p_next;
+ }
return inst ;
}
@@ -293,6 +322,7 @@
if (p_srvc_cb->p_cur_srvc != NULL)
p_srvc_cb->p_cur_srvc->p_next = p_new_srvc;
p_srvc_cb->p_cur_srvc = p_new_srvc;
+ p_srvc_cb->p_cur_srvc->p_cur_char = NULL;
/* first service */
if (p_srvc_cb->p_srvc_cache == NULL)
@@ -364,9 +394,13 @@
}
if (type == BTA_GATTC_ATTR_TYPE_CHAR)
- p_attr->inst_id = bta_gattc_get_char_inst_id(p_srvc_cb->p_cur_srvc, *p_uuid);
- /* else: char descriptor, no instance ID needed */
- else /* TODO: --->> temp treat included service same as char descriptor */
+ {
+ p_attr->inst_id = bta_gattc_get_char_inst_id(p_srvc_cb->p_cur_srvc, p_uuid);
+ p_srvc_cb->p_cur_srvc->p_cur_char = p_attr;
+ }
+ else if (type == BTA_GATTC_ATTR_TYPE_CHAR_DESCR)
+ p_attr->inst_id = bta_gattc_get_char_descr_inst_id(p_srvc_cb->p_cur_srvc->p_cur_char, p_uuid);
+ else /* TODO: --->> temp treat included service as single instance */
p_attr->inst_id = 0;
/* update service information */
@@ -427,16 +461,10 @@
*******************************************************************************/
tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type)
{
- tBT_DEVICE_TYPE dev_type;
- tBLE_ADDR_TYPE addr_type;
-
- BTM_ReadDevInfo(p_server_cb->server_bda, &dev_type, &addr_type);
- if (dev_type == BT_DEVICE_TYPE_BLE)
+ if (BTM_IsBleLink(p_server_cb->server_bda))
return bta_gattc_discover_procedure(conn_id, p_server_cb, disc_type);
else
return bta_gattc_sdp_service_disc(conn_id, p_server_cb);
- return BTA_GATT_ERROR;
-
}
/*******************************************************************************
**
@@ -1019,7 +1047,7 @@
**
*******************************************************************************/
UINT16 bta_gattc_id2handle(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_SRVC_ID *p_service_id,
- tBTA_GATT_ID *p_char_id, tBT_UUID descr_uuid)
+ tBTA_GATT_ID *p_char_id, tBTA_GATT_ID *p_descr_uuid)
{
tBTA_GATTC_CACHE *p_cache = p_srcb->p_srvc_cache;
tBTA_GATTC_CACHE_ATTR *p_attr;
@@ -1047,10 +1075,10 @@
#endif
bta_gattc_pack_attr_uuid(p_attr, &attr_uuid);
- if (bta_gattc_uuid_compare(p_char_id->uuid, attr_uuid, TRUE) &&
+ if (bta_gattc_uuid_compare(&p_char_id->uuid, &attr_uuid, TRUE) &&
p_char_id->inst_id == p_attr->inst_id)
{
- if (descr_uuid.len == 0)
+ if (p_descr_uuid == NULL)
{
handle = p_attr->attr_handle;
done = TRUE;
@@ -1069,7 +1097,9 @@
if (p_attr->attr_type == BTA_GATTC_ATTR_TYPE_CHAR_DESCR)
{
- if (bta_gattc_uuid_compare(descr_uuid, attr_uuid, TRUE))
+ if (p_descr_uuid != NULL &&
+ bta_gattc_uuid_compare(&p_descr_uuid->uuid, &attr_uuid, TRUE) &&
+ p_descr_uuid->inst_id == p_attr->inst_id)
{
#if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
APPL_TRACE_DEBUG0("found descriptor!!");
@@ -1114,7 +1144,7 @@
*******************************************************************************/
BOOLEAN bta_gattc_handle2id(tBTA_GATTC_SERV *p_srcb, UINT16 handle, tBTA_GATT_SRVC_ID *p_service_id,
- tBTA_GATT_ID *p_char_id, tBT_UUID *p_descr_type)
+ tBTA_GATT_ID *p_char_id, tBTA_GATT_ID *p_descr_type)
{
tBTA_GATTC_CACHE *p_cache = p_srcb->p_srvc_cache;
tBTA_GATTC_CACHE_ATTR *p_attr, *p_char = NULL;
@@ -1122,7 +1152,7 @@
memset(p_service_id, 0, sizeof(tBTA_GATT_SRVC_ID));
memset(p_char_id, 0, sizeof(tBTA_GATT_ID));
- memset(p_descr_type, 0, sizeof(tBT_UUID));
+ memset(p_descr_type, 0, sizeof(tBTA_GATT_ID));
while (p_cache)
{
@@ -1157,7 +1187,8 @@
if (p_attr->attr_type == BTA_GATTC_ATTR_TYPE_CHAR_DESCR)
{
- bta_gattc_pack_attr_uuid(p_attr, p_descr_type);
+ bta_gattc_pack_attr_uuid(p_attr, &p_descr_type->uuid);
+ p_descr_type->inst_id = p_attr->inst_id;
if (p_char != NULL)
{
@@ -1195,7 +1226,7 @@
** Returns FALSE if map can not be found.
**
*******************************************************************************/
-void bta_gattc_search_service(tBTA_GATTC_CLCB *p_clcb, tBT_UUID uuid)
+void bta_gattc_search_service(tBTA_GATTC_CLCB *p_clcb, tBT_UUID *p_uuid)
{
tBTA_GATTC_SERV *p_srcb = p_clcb->p_srcb;
tBTA_GATTC_CACHE *p_cache = p_srcb->p_srvc_cache;
@@ -1203,7 +1234,7 @@
while (p_cache)
{
- if (bta_gattc_uuid_compare(uuid, p_cache->service_uuid.id.uuid, FALSE))
+ if (bta_gattc_uuid_compare(p_uuid, &p_cache->service_uuid.id.uuid, FALSE))
{
#if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
APPL_TRACE_DEBUG3("found service [0x%04x], inst[%d] handle [%d]",
@@ -1246,13 +1277,10 @@
{
tBTA_GATTC_CACHE *p_cache = p_srcb->p_srvc_cache;
tBTA_GATT_STATUS status = BTA_GATT_ERROR;
- tBT_UUID uuid_cond = {0}, start_descr = {0};
UINT8 i, j;
tBTA_GATTC_CACHE_ATTR *p_attr;
BOOLEAN char_found = FALSE, descr_found = FALSE;
-
- if (p_uuid_cond)
- memcpy(&uuid_cond, p_uuid_cond, sizeof(tBT_UUID));
+ tBTA_GATT_ID *p_descr_id = (tBTA_GATT_ID *)p_param;;
for (i = 0; p_cache && status != BTA_GATT_OK; i ++)
{
@@ -1279,11 +1307,12 @@
if (p_start_rec != NULL && char_found == FALSE)
{
/* find the starting record first */
- if (bta_gattc_uuid_compare(p_start_rec->uuid, p_result->uuid, FALSE) &&
+ if (bta_gattc_uuid_compare(&p_start_rec->uuid, &p_result->uuid, FALSE) &&
p_start_rec->inst_id == p_attr->inst_id &&
(attr_type == p_attr->attr_type ||
/* find descriptor would look for characteristic first */
- (attr_type == BTA_GATTC_ATTR_TYPE_CHAR_DESCR && p_attr->attr_type == BTA_GATTC_ATTR_TYPE_CHAR)))
+ (attr_type == BTA_GATTC_ATTR_TYPE_CHAR_DESCR &&
+ p_attr->attr_type == BTA_GATTC_ATTR_TYPE_CHAR)))
{
char_found = TRUE;
}
@@ -1293,9 +1322,6 @@
/* if looking for descriptor, here is the where the descrptor to be found */
if (attr_type == BTA_GATTC_ATTR_TYPE_CHAR_DESCR)
{
- /* starting descriptor UUID */
- if (p_param != NULL)
- memcpy(&start_descr, p_param, sizeof(tBT_UUID));
/* next characeteristic already, return error */
if (p_attr->attr_type != BTA_GATTC_ATTR_TYPE_CHAR_DESCR)
{
@@ -1303,9 +1329,11 @@
}
else
{
- if (start_descr.len != 0 && !descr_found)
+ /* find starting descriptor */
+ if (p_descr_id != NULL && !descr_found)
{
- if (bta_gattc_uuid_compare(start_descr, p_result->uuid, FALSE))
+ if (bta_gattc_uuid_compare(&p_descr_id->uuid, &p_result->uuid, TRUE)
+ && p_descr_id->inst_id == p_attr->inst_id)
{
descr_found = TRUE;
}
@@ -1313,8 +1341,9 @@
else
{
/* with matching descriptor */
- if (bta_gattc_uuid_compare(uuid_cond, p_result->uuid, FALSE))
+ if (bta_gattc_uuid_compare(p_uuid_cond, &p_result->uuid, FALSE))
{
+ p_result->inst_id = p_attr->inst_id;
status = BTA_GATT_OK;
break;
}
@@ -1323,7 +1352,7 @@
}
else
{
- if (bta_gattc_uuid_compare(uuid_cond, p_result->uuid, FALSE) &&
+ if (bta_gattc_uuid_compare(p_uuid_cond, &p_result->uuid, FALSE) &&
attr_type == p_attr->attr_type)
{
diff --git a/bta/gatt/bta_gattc_int.h b/bta/gatt/bta_gattc_int.h
index 2228d24..7730113 100644
--- a/bta/gatt/bta_gattc_int.h
+++ b/bta/gatt/bta_gattc_int.h
@@ -125,7 +125,7 @@
tBTA_GATT_AUTH_REQ auth_req;
tBTA_GATT_SRVC_ID srvc_id;
tBTA_GATT_ID char_id;
- tBT_UUID descr_type;
+ tBTA_GATT_ID *p_descr_type;
} tBTA_GATTC_API_READ;
typedef struct
@@ -134,7 +134,7 @@
tBTA_GATT_AUTH_REQ auth_req;
tBTA_GATT_SRVC_ID srvc_id;
tBTA_GATT_ID char_id;
- tBT_UUID descr_type;
+ tBTA_GATT_ID *p_descr_type;
tBTA_GATTC_WRITE_TYPE write_type;
UINT16 offset;
UINT16 len;
@@ -167,7 +167,7 @@
typedef struct
{
BT_HDR hdr;
- tBT_UUID srvc_uuid;
+ tBT_UUID *p_srvc_uuid;
}tBTA_GATTC_API_SEARCH;
typedef struct
@@ -178,6 +178,15 @@
tBTA_GATTC_ATTR_ID *p_id_list;
}tBTA_GATTC_API_READ_MULTI;
+typedef struct
+{
+ BT_HDR hdr;
+ BD_ADDR remote_bda;
+ tBTA_GATTC_IF client_if;
+ UINT8 role;
+ tGATT_DISCONN_REASON reason;
+}tBTA_GATTC_INT_CONN;
+
typedef union
{
BT_HDR hdr;
@@ -195,6 +204,7 @@
tBTA_GATTC_CI_EVT ci_open;
tBTA_GATTC_CI_EVT ci_save;
tBTA_GATTC_CI_LOAD ci_load;
+ tBTA_GATTC_INT_CONN int_conn;
tBTA_GATTC_INT_START_IF int_start_if;
tBTA_GATTC_INT_DEREG int_dereg;
@@ -232,6 +242,7 @@
UINT16 s_handle;
UINT16 e_handle;
struct gattc_svc_cache *p_next;
+ tBTA_GATTC_CACHE_ATTR *p_cur_char;
// btla-specific ++
} __attribute__((packed)) tBTA_GATTC_CACHE;
// btla-specific --
@@ -462,14 +473,17 @@
extern tBTA_GATTC_SERV * bta_gattc_find_srcb(BD_ADDR bda);
extern tBTA_GATTC_SERV * bta_gattc_srcb_alloc(BD_ADDR bda);
extern tBTA_GATTC_SERV * bta_gattc_find_scb_by_cid (UINT16 conn_id);
+extern tBTA_GATTC_CLCB * bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA *p_msg);
+extern tBTA_GATTC_CLCB * bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA *p_msg);
+
extern BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
-extern UINT16 bta_gattc_id2handle(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_SRVC_ID *p_service_id, tBTA_GATT_ID *p_char_id, tBT_UUID descr_uuid);
-extern BOOLEAN bta_gattc_handle2id(tBTA_GATTC_SERV *p_srcb, UINT16 handle, tBTA_GATT_SRVC_ID *service_id, tBTA_GATT_ID *char_id, tBT_UUID *p_type);
-extern BOOLEAN bta_gattc_uuid_compare (tBT_UUID src, tBT_UUID tar, BOOLEAN is_precise);
+extern UINT16 bta_gattc_id2handle(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_SRVC_ID *p_service_id, tBTA_GATT_ID *p_char_id, tBTA_GATT_ID *p_descr_uuid);
+extern BOOLEAN bta_gattc_handle2id(tBTA_GATTC_SERV *p_srcb, UINT16 handle, tBTA_GATT_SRVC_ID *service_id, tBTA_GATT_ID *char_id, tBTA_GATT_ID *p_type);
+extern BOOLEAN bta_gattc_uuid_compare (tBT_UUID *p_src, tBT_UUID *p_tar, BOOLEAN is_precise);
extern void bta_gattc_pack_attr_uuid(tBTA_GATTC_CACHE_ATTR *p_attr, tBT_UUID *p_uuid);
extern BOOLEAN bta_gattc_check_notif_registry(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_SERV *p_srcb, tBTA_GATTC_NOTIFY *p_notify);
-extern tBTA_GATT_STATUS bta_gattc_pack_read_cb_data(tBTA_GATTC_SERV *p_srcb, tBT_UUID descr_uuid, tGATT_VALUE *p_attr, tBTA_GATT_READ_VAL *p_value);
+extern tBTA_GATT_STATUS bta_gattc_pack_read_cb_data(tBTA_GATTC_SERV *p_srcb, tBT_UUID *p_descr_uuid, tGATT_VALUE *p_attr, tBTA_GATT_READ_VAL *p_value);
extern BOOLEAN bta_gattc_mark_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR_PTR remote_bda, BOOLEAN add, BOOLEAN is_listen);
extern BOOLEAN bta_gattc_check_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR remote_bda, UINT8 role);
extern UINT8 bta_gattc_num_reg_app(void);
@@ -484,10 +498,10 @@
extern void bta_gattc_disc_cmpl_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_STATUS status);
extern tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type);
extern tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type);
-extern void bta_gattc_search_service(tBTA_GATTC_CLCB *p_clcb, tBT_UUID uuid);
+extern void bta_gattc_search_service(tBTA_GATTC_CLCB *p_clcb, tBT_UUID *p_uuid);
extern tBTA_GATT_STATUS bta_gattc_query_cache(UINT16 conn_id, UINT8 query_type, tBTA_GATT_SRVC_ID *p_srvc_id,
tBTA_GATT_ID *p_start_rec,tBT_UUID *p_uuid_cond,
- tBTA_GATT_ID *p_output, void *p_property);
+ tBTA_GATT_ID *p_output, void *p_param);
extern tBTA_GATT_STATUS bta_gattc_init_cache(tBTA_GATTC_SERV *p_srvc_cb);
extern void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srcv, UINT16 num_attr, tBTA_GATTC_NV_ATTR *p_attr, UINT16 attr_index);
extern BOOLEAN bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id);
diff --git a/bta/gatt/bta_gattc_main.c b/bta/gatt/bta_gattc_main.c
index e6c6819..0479546 100644
--- a/bta/gatt/bta_gattc_main.c
+++ b/bta/gatt/bta_gattc_main.c
@@ -162,7 +162,7 @@
/* BTA_GATTC_API_WRITE_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
/* BTA_GATTC_API_EXEC_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
-/* BTA_GATTC_API_CLOSE_EVT */ {BTA_GATTC_CLOSE_FAIL, BTA_GATTC_W4_CONN_ST},
+/* BTA_GATTC_API_CLOSE_EVT */ {BTA_GATTC_CANCEL_OPEN, BTA_GATTC_W4_CONN_ST},
/* BTA_GATTC_API_SEARCH_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
/* BTA_GATTC_API_CONFIRM_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
@@ -173,7 +173,7 @@
/* BTA_GATTC_INT_DISCOVER_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
/* BTA_GATTC_DISCOVER_CMPL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
/* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
-/* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST},
+/* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_OPEN_FAIL, BTA_GATTC_IDLE_ST},
/* ===> for cache loading, saving */
/* BTA_GATTC_START_CACHE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
@@ -236,7 +236,7 @@
/* BTA_GATTC_API_READ_MULTI_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST},
/* BTA_GATTC_API_REFRESH_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_DISCOVER_ST},
-/* BTA_GATTC_INT_CONN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_DISCOVER_ST},
+/* BTA_GATTC_INT_CONN_EVT */ {BTA_GATTC_CONN, BTA_GATTC_DISCOVER_ST},
/* BTA_GATTC_INT_DISCOVER_EVT */ {BTA_GATTC_RESTART_DISCOVER, BTA_GATTC_DISCOVER_ST},
/* BTA_GATTC_DISCOVER_CMPL_EVT */ {BTA_GATTC_DISC_CMPL, BTA_GATTC_CONN_ST},
/* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_IGNORE_OP_CMPL, BTA_GATTC_DISCOVER_ST},
@@ -382,14 +382,20 @@
break;
default:
- if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->layer_specific))
- != NULL)
+ if (p_msg->event == BTA_GATTC_INT_CONN_EVT)
+ p_clcb = bta_gattc_find_int_conn_clcb((tBTA_GATTC_DATA *) p_msg);
+ else if (p_msg->event == BTA_GATTC_INT_DISCONN_EVT)
+ p_clcb = bta_gattc_find_int_disconn_clcb((tBTA_GATTC_DATA *) p_msg);
+ else
+ p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->layer_specific);
+
+ if (p_clcb != NULL)
{
bta_gattc_sm_execute(p_clcb, p_msg->event, (tBTA_GATTC_DATA *) p_msg);
}
else
{
- APPL_TRACE_ERROR1("Unknown conn ID: %d", p_msg->layer_specific);
+ APPL_TRACE_DEBUG1("Ignore unknown conn ID: %d", p_msg->layer_specific);
}
break;
@@ -468,8 +474,6 @@
return "BTA_GATTC_API_REFRESH_EVT";
case BTA_GATTC_API_DISABLE_EVT:
return "BTA_GATTC_API_DISABLE_EVT";
- case BTA_GATTC_API_ENABLE_EVT:
- return "BTA_GATTC_API_ENABLE_EVT";
default:
return "unknown GATTC event code";
}
diff --git a/bta/gatt/bta_gattc_utils.c b/bta/gatt/bta_gattc_utils.c
index 4749f21..151b7ba 100644
--- a/bta/gatt/bta_gattc_utils.c
+++ b/bta/gatt/bta_gattc_utils.c
@@ -31,6 +31,7 @@
#include "gki.h"
#include "bta_sys.h"
#include "bta_gattc_int.h"
+#include "l2c_api.h"
#include "bd.h"
/*****************************************************************************
@@ -41,6 +42,8 @@
static const UINT8 base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const BD_ADDR dummy_bda = {0,0,0,0,0,0};
+
/*******************************************************************************
**
** Function bta_gatt_convert_uuid16_to_uuid128
@@ -67,13 +70,13 @@
** Returns TRUE if two uuid match; FALSE otherwise.
**
*******************************************************************************/
-BOOLEAN bta_gattc_uuid_compare (tBT_UUID src, tBT_UUID tar, BOOLEAN is_precise)
+BOOLEAN bta_gattc_uuid_compare (tBT_UUID *p_src, tBT_UUID *p_tar, BOOLEAN is_precise)
{
UINT8 su[LEN_UUID_128], tu[LEN_UUID_128];
UINT8 *ps, *pt;
/* any of the UUID is unspecified */
- if (src.len == 0 || tar.len == 0)
+ if (p_src == 0 || p_tar == 0)
{
if (is_precise)
return FALSE;
@@ -82,29 +85,29 @@
}
/* If both are 16-bit, we can do a simple compare */
- if (src.len == 2 && tar.len == 2)
+ if (p_src->len == 2 && p_tar->len == 2)
{
- return src.uu.uuid16 == tar.uu.uuid16;
+ return p_src->uu.uuid16 == p_tar->uu.uuid16;
}
/* One or both of the UUIDs is 128-bit */
- if (src.len == LEN_UUID_16)
+ if (p_src->len == LEN_UUID_16)
{
/* convert a 16 bits UUID to 128 bits value */
- bta_gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16);
+ bta_gatt_convert_uuid16_to_uuid128(su, p_src->uu.uuid16);
ps = su;
}
else
- ps = src.uu.uuid128;
+ ps = p_src->uu.uuid128;
- if (tar.len == LEN_UUID_16)
+ if (p_tar->len == LEN_UUID_16)
{
/* convert a 16 bits UUID to 128 bits value */
- bta_gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16);
+ bta_gatt_convert_uuid16_to_uuid128(tu, p_tar->uu.uuid16);
pt = tu;
}
else
- pt = tar.uu.uuid128;
+ pt = p_tar->uu.uuid128;
return(memcmp(ps, pt, LEN_UUID_128) == 0);
}
@@ -276,15 +279,18 @@
*******************************************************************************/
void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb)
{
- tBTA_GATTC_SERV *p_srcb = p_clcb->p_srcb;
+ tBTA_GATTC_SERV *p_srcb = NULL;
if (p_clcb)
{
+ p_srcb = p_clcb->p_srcb;
if (p_srcb->num_clcb)
p_srcb->num_clcb --;
if (p_clcb->p_rcb->num_clcb)
p_clcb->p_rcb->num_clcb --;
+
+ /* if the srcb is no longer needed, reset the state */
if ( p_srcb->num_clcb == 0)
{
p_srcb->connected = FALSE;
@@ -505,7 +511,7 @@
BOOLEAN bta_gattc_gattid_compare(tBTA_GATT_ID *p_src, tBTA_GATT_ID *p_tar)
{
if (p_src->inst_id == p_tar->inst_id &&
- bta_gattc_uuid_compare (p_src->uuid, p_tar->uuid, TRUE ))
+ bta_gattc_uuid_compare (&p_src->uuid, &p_tar->uuid, TRUE ))
return TRUE;
else
return FALSE;
@@ -616,8 +622,10 @@
** Returns
**
*******************************************************************************/
-tBTA_GATT_STATUS bta_gattc_pack_read_cb_data(tBTA_GATTC_SERV *p_srcb, tBT_UUID descr_uuid,
- tGATT_VALUE *p_attr, tBTA_GATT_READ_VAL *p_value)
+tBTA_GATT_STATUS bta_gattc_pack_read_cb_data(tBTA_GATTC_SERV *p_srcb,
+ tBT_UUID *p_descr_uuid,
+ tGATT_VALUE *p_attr,
+ tBTA_GATT_READ_VAL *p_value)
{
UINT8 i = 0, *pp = p_attr->value;
tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_CHAR_AGG_FORMAT}};
@@ -625,7 +633,7 @@
tBTA_GATT_STATUS status = BTA_GATT_OK;
/* GATT_UUID_CHAR_AGG_FORMAT */
- if (bta_gattc_uuid_compare (uuid, descr_uuid, TRUE))
+ if (bta_gattc_uuid_compare (&uuid, p_descr_uuid, TRUE))
{
while (p_attr->len >= 2 && i < BTA_GATTC_MULTI_MAX)
{
@@ -635,7 +643,7 @@
handle,
&p_value->aggre_value.pre_format[i].char_id.srvc_id,
&p_value->aggre_value.pre_format[i].char_id.char_id,
- &p_value->aggre_value.pre_format[i].descr_type) == FALSE)
+ &p_value->aggre_value.pre_format[i].descr_id) == FALSE)
{
status = BTA_GATT_INTERNAL_ERROR;
APPL_TRACE_ERROR1("can not map to GATT ID. handle = 0x%04x", handle);
@@ -675,7 +683,7 @@
{
if (p_bg_tck->in_use &&
((remote_bda_ptr != NULL && bdcmp(p_bg_tck->remote_bda, remote_bda_ptr) == 0) ||
- (remote_bda_ptr == NULL && bdcmp(p_bg_tck->remote_bda, bd_addr_null) == 0)))
+ (remote_bda_ptr == NULL && bdcmp(p_bg_tck->remote_bda, dummy_bda) == 0)))
{
p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask;
@@ -713,7 +721,7 @@
if (remote_bda_ptr)
bdcpy(p_bg_tck->remote_bda, remote_bda_ptr);
else
- bdcpy(p_bg_tck->remote_bda, bd_addr_null);
+ bdcpy(p_bg_tck->remote_bda, dummy_bda);
p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask;
@@ -744,7 +752,7 @@
{
if (p_bg_tck->in_use &&
(bdcmp(p_bg_tck->remote_bda, remote_bda) == 0 ||
- bdcmp(p_bg_tck->remote_bda, bd_addr_null) == 0))
+ bdcmp(p_bg_tck->remote_bda, dummy_bda) == 0))
{
if (((p_bg_tck->cif_mask &(1 <<(client_if - 1))) != 0) &&
role == HCI_ROLE_MASTER)
@@ -882,4 +890,66 @@
return FALSE;
}
+/*******************************************************************************
+**
+** Function bta_gattc_find_int_conn_clcb
+**
+** Description try to locate a clcb when an internal connecion event arrives.
+**
+** Returns pointer to the clcb
+**
+*******************************************************************************/
+tBTA_GATTC_CLCB * bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA *p_msg)
+{
+ tBTA_GATTC_CLCB *p_clcb = NULL;
+
+ if (p_msg->int_conn.role == HCI_ROLE_SLAVE)
+ bta_gattc_conn_find_alloc(p_msg->int_conn.remote_bda);
+
+ /* try to locate a logic channel */
+ if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
+ p_msg->int_conn.remote_bda)) == NULL)
+ {
+ /* for a background connection or listening connection */
+ if (p_msg->int_conn.role == HCI_ROLE_SLAVE ||
+ bta_gattc_check_bg_conn(p_msg->int_conn.client_if,
+ p_msg->int_conn.remote_bda,
+ p_msg->int_conn.role))
+ {
+ /* allocate a new channel */
+ p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if, p_msg->int_conn.remote_bda);
+ }
+ }
+ return p_clcb;
+}
+
+/*******************************************************************************
+**
+** Function bta_gattc_find_int_disconn_clcb
+**
+** Description try to locate a clcb when an internal disconnect callback arrives.
+**
+** Returns pointer to the clcb
+**
+*******************************************************************************/
+tBTA_GATTC_CLCB * bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA *p_msg)
+{
+ tBTA_GATTC_CLCB *p_clcb = NULL;
+ tGATT_DISCONN_REASON reason = p_msg->int_conn.reason;
+
+ bta_gattc_conn_dealloc(p_msg->int_conn.remote_bda);
+ /* connection attempt timeout, send connection callback event */
+ if (reason == GATT_CONN_CANCEL || reason == GATT_CONN_L2C_FAILURE)
+ {
+ p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
+ p_msg->int_conn.remote_bda);
+ }
+ else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific)) == NULL)
+ {
+ APPL_TRACE_DEBUG1("disconnection ID: [%d] not used by BTA",
+ p_msg->int_conn.hdr.layer_specific);
+ }
+ return p_clcb;
+}
+
#endif /* BTA_GATT_INCLUDED */
diff --git a/bta/gatt/bta_gatts_act.c b/bta/gatt/bta_gatts_act.c
index 244624d..dd7e1fc 100644
--- a/bta/gatt/bta_gatts_act.c
+++ b/bta/gatt/bta_gatts_act.c
@@ -589,9 +589,9 @@
}
/*******************************************************************************
**
-** Function bta_gatts_indicate_handle
+** Function bta_gatts_send_rsp
**
-** Description GATTS send handle value indication or notification.
+** Description GATTS send response.
**
** Returns none.
**
@@ -612,7 +612,11 @@
**
** Function bta_gatts_indicate_handle
**
+<<<<<<< HEAD
** Description GATTS indicate handel value
+=======
+** Description GATTS send handle value indication or notification.
+>>>>>>> 6ea30bf... LE: UPF 45 bug fixes
**
** Returns none.
**
@@ -856,7 +860,12 @@
{
/* there is no RM for GATT */
if (!BTM_IsBleLink(bda))
- bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda);
+ {
+ if (connected)
+ bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda);
+ else
+ bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, bda);
+ }
cb_data.conn.conn_id = conn_id;
cb_data.conn.server_if = gatt_if;
diff --git a/bta/include/bta_gatt_api.h b/bta/include/bta_gatt_api.h
index a63afb3..f052323 100644
--- a/bta/include/bta_gatt_api.h
+++ b/bta/include/bta_gatt_api.h
@@ -162,7 +162,7 @@
typedef UINT8 tBTA_GATTC_WRITE_TYPE;
#define BTA_GATT_CONN_UNKNOWN 0
-#define BTA_GATT_CONN_NO_RESOURCES GATT_CONN_NO_RESOURCES /* connection fail for l2cap resource failure */
+#define BTA_GATT_CONN_L2C_FAILURE GATT_CONN_L2C_FAILURE /* general l2cap resource failure */
#define BTA_GATT_CONN_TIMEOUT GATT_CONN_TIMEOUT /* 0x08 connection timeout */
#define BTA_GATT_CONN_TERMINATE_PEER_USER GATT_CONN_TERMINATE_PEER_USER /* 0x13 connection terminate by peer user */
#define BTA_GATT_CONN_TERMINATE_LOCAL_HOST GATT_CONN_TERMINATE_LOCAL_HOST/* 0x16 connectionterminated by local host */
@@ -187,7 +187,7 @@
typedef struct
{
tBTA_GATTC_CHAR_ID char_id;
- tBT_UUID descr_type;
+ tBTA_GATT_ID descr_id;
}tBTA_GATTC_CHAR_DESCR_ID;
typedef struct
@@ -278,7 +278,7 @@
tBTA_GATT_STATUS status;
tBTA_GATT_SRVC_ID srvc_id;
tBTA_GATT_ID char_id;
- tBT_UUID descr_type;
+ tBTA_GATT_ID descr_type;
tBTA_GATT_READ_VAL *p_value;
}tBTA_GATTC_READ;
@@ -288,7 +288,7 @@
tBTA_GATT_STATUS status;
tBTA_GATT_SRVC_ID srvc_id;
tBTA_GATT_ID char_id;
- tBT_UUID descr_type;
+ tBTA_GATT_ID descr_type;
}tBTA_GATTC_WRITE;
typedef struct
@@ -332,7 +332,7 @@
UINT16 conn_id;
BD_ADDR bda;
tBTA_GATTC_CHAR_ID char_id;
- tBT_UUID descr_type;
+ tBTA_GATT_ID descr_type;
UINT16 len;
UINT8 value[BTA_GATT_MAX_ATTR_LEN];
BOOLEAN is_notify;
diff --git a/btif/src/btif_gatt_client.c b/btif/src/btif_gatt_client.c
index f611c40..937f807 100644
--- a/btif/src/btif_gatt_client.c
+++ b/btif/src/btif_gatt_client.c
@@ -26,7 +26,6 @@
*******************************************************************************/
#include <hardware/bluetooth.h>
-#include <hardware/bt_gatt.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -40,6 +39,7 @@
#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
#include "gki.h"
+#include <hardware/bt_gatt.h>
#include "bta_api.h"
#include "bta_gatt_api.h"
#include "bd.h"
@@ -173,7 +173,7 @@
sizeof(tBTA_GATT_READ_VAL));
// Allocate buffer for att value if necessary
- if (get_uuid16(&p_src_data->read.descr_type) != GATT_UUID_CHAR_AGG_FORMAT
+ if (get_uuid16(&p_src_data->read.descr_type.uuid) != GATT_UUID_CHAR_AGG_FORMAT
&& p_src_data->read.p_value->unformat.len > 0
&& p_src_data->read.p_value->unformat.p_value != NULL)
{
@@ -210,7 +210,7 @@
case BTA_GATTC_READ_DESCR_EVT:
if (p_data != NULL && p_data->read.p_value != NULL)
{
- if (get_uuid16 (&p_data->read.descr_type) != GATT_UUID_CHAR_AGG_FORMAT
+ if (get_uuid16 (&p_data->read.descr_type.uuid) != GATT_UUID_CHAR_AGG_FORMAT
&& p_data->read.p_value->unformat.len > 0
&& p_data->read.p_value->unformat.p_value != NULL)
{
@@ -386,7 +386,7 @@
btgatt_write_params_t data;
bta_to_btif_srvc_id(&data.srvc_id, &p_data->write.srvc_id);
bta_to_btif_char_id(&data.char_id, &p_data->write.char_id);
- bta_to_btif_uuid(&data.descr_id, &p_data->write.descr_type);
+ bta_to_btif_uuid(&data.descr_id, &p_data->write.descr_type.uuid);
HAL_CBACK(bt_gatt_callbacks, client->write_descriptor_cb
, p_data->write.conn_id, p_data->write.status, &data);
@@ -422,11 +422,11 @@
bt_bdaddr_t bda;
bdcpy(bda.address, p_data->open.remote_bda);
- if (p_data->open.status == BTA_GATT_OK)
- btif_gatt_check_encrypted_link(p_data->open.remote_bda);
-
HAL_CBACK(bt_gatt_callbacks, client->open_cb, p_data->open.conn_id
, p_data->open.status, p_data->open.client_if, &bda);
+
+ if (p_data->open.status == BTA_GATT_OK)
+ btif_gatt_check_encrypted_link(p_data->open.remote_bda);
break;
}
@@ -479,14 +479,14 @@
btapp_gattc_free_req_data(event, p_data);
}
-static void bte_gattc_cback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
+static void bta_gattc_cback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
{
bt_status_t status = btif_transfer_context(btif_gattc_upstreams_evt,
(uint16_t) event, (void*)p_data, sizeof(tBTA_GATTC), btapp_gattc_req_data);
ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
}
-static void bte_scan_results_cb (tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
+static void bta_scan_results_cb (tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
{
btif_gattc_cb_t btif_cb;
uint8_t len;
@@ -552,6 +552,7 @@
tBTA_GATTC_INCL_SVC_ID in_incl_svc_id;
tBTA_GATTC_INCL_SVC_ID out_incl_svc_id;
tBTA_GATT_UNFMT descr_val;
+ static UINT8 descr_inst = 0;
btif_gattc_cb_t* p_cb = (btif_gattc_cb_t*)p_param;
if (!p_cb) return;
@@ -562,7 +563,7 @@
{
case BTIF_GATTC_REGISTER_APP:
btif_to_bta_uuid(&uuid, &p_cb->uuid);
- BTA_GATTC_AppRegister(&uuid, bte_gattc_cback);
+ BTA_GATTC_AppRegister(&uuid, bta_gattc_cback);
break;
case BTIF_GATTC_UNREGISTER_APP:
@@ -571,7 +572,7 @@
case BTIF_GATTC_SCAN_START:
btif_gattc_init_dev_cb();
- BTA_DmBleObserve(TRUE, 0, bte_scan_results_cb);
+ BTA_DmBleObserve(TRUE, 0, bta_scan_results_cb);
break;
case BTIF_GATTC_SCAN_STOP:
@@ -586,7 +587,7 @@
break;
case BTIF_GATTC_CLOSE:
- // Disconnect establiched connections
+ // Disconnect established connections
if (p_cb->conn_id != 0)
BTA_GATTC_Close(p_cb->conn_id);
else
@@ -647,12 +648,13 @@
bt_uuid_t descr_id;
btif_to_bta_srvc_id(&in_char_id.srvc_id, &p_cb->srvc_id);
btif_to_bta_char_id(&in_char_id.char_id, &p_cb->char_id);
+ descr_inst = 0;
status = BTA_GATTC_GetFirstCharDescr(p_cb->conn_id, &in_char_id, NULL,
&out_char_descr_id);
if (status == 0)
- bta_to_btif_uuid(&descr_id, &out_char_descr_id.descr_type);
+ bta_to_btif_uuid(&descr_id, &out_char_descr_id.descr_id.uuid);
HAL_CBACK(bt_gatt_callbacks, client->get_descriptor_cb,
p_cb->conn_id, status, &p_cb->srvc_id,
@@ -665,13 +667,15 @@
bt_uuid_t descr_id;
btif_to_bta_srvc_id(&in_char_descr_id.char_id.srvc_id, &p_cb->srvc_id);
btif_to_bta_char_id(&in_char_descr_id.char_id.char_id, &p_cb->char_id);
- btif_to_bta_uuid(&in_char_descr_id.descr_type, &p_cb->uuid);
+ btif_to_bta_uuid(&in_char_descr_id.descr_id.uuid, &p_cb->uuid);
+ in_char_descr_id.descr_id.inst_id = descr_inst; /* TODO: need app layer input */
+ descr_inst ++;
status = BTA_GATTC_GetNextCharDescr(p_cb->conn_id, &in_char_descr_id
, NULL, &out_char_descr_id);
if (status == 0)
- bta_to_btif_uuid(&descr_id, &out_char_descr_id.descr_type);
+ bta_to_btif_uuid(&descr_id, &out_char_descr_id.descr_id.uuid);
HAL_CBACK(bt_gatt_callbacks, client->get_descriptor_cb,
p_cb->conn_id, status, &p_cb->srvc_id,
@@ -722,7 +726,8 @@
case BTIF_GATTC_READ_CHAR_DESCR:
btif_to_bta_srvc_id(&in_char_descr_id.char_id.srvc_id, &p_cb->srvc_id);
btif_to_bta_char_id(&in_char_descr_id.char_id.char_id, &p_cb->char_id);
- btif_to_bta_uuid(&in_char_descr_id.descr_type, &p_cb->uuid);
+ btif_to_bta_uuid(&in_char_descr_id.descr_id.uuid, &p_cb->uuid);
+ in_char_descr_id.descr_id.inst_id = 0; /* TODO: need app layer input */
BTA_GATTC_ReadCharDescr(p_cb->conn_id, &in_char_descr_id, p_cb->auth_req);
break;
@@ -741,7 +746,8 @@
case BTIF_GATTC_WRITE_CHAR_DESCR:
btif_to_bta_srvc_id(&in_char_descr_id.char_id.srvc_id, &p_cb->srvc_id);
btif_to_bta_char_id(&in_char_descr_id.char_id.char_id, &p_cb->char_id);
- btif_to_bta_uuid(&in_char_descr_id.descr_type, &p_cb->uuid);
+ btif_to_bta_uuid(&in_char_descr_id.descr_id.uuid, &p_cb->uuid);
+ in_char_descr_id.descr_id.inst_id = 0; /* TODO: need app layer input */
descr_val.len = p_cb->len;
descr_val.p_value = p_cb->value;
diff --git a/btif/src/btif_gatt_util.c b/btif/src/btif_gatt_util.c
index d07c737..252d221 100644
--- a/btif/src/btif_gatt_util.c
+++ b/btif/src/btif_gatt_util.c
@@ -228,9 +228,9 @@
p_dest->status = p_src->status;
bta_to_btif_srvc_id(&p_dest->srvc_id, &p_src->srvc_id);
bta_to_btif_char_id(&p_dest->char_id, &p_src->char_id);
- bta_to_btif_uuid(&p_dest->descr_id, &p_src->descr_type);
+ bta_to_btif_uuid(&p_dest->descr_id, &p_src->descr_type.uuid);
- descr_type = get_uuid16(&p_src->descr_type);
+ descr_type = get_uuid16(&p_src->descr_type.uuid);
switch (descr_type)
{
diff --git a/stack/btm/btm_ble.c b/stack/btm/btm_ble.c
index 71e7d8c..ad5663f 100644
--- a/stack/btm/btm_ble.c
+++ b/stack/btm/btm_ble.c
@@ -309,6 +309,35 @@
#endif
}
+/*******************************************************************************
+**
+** Function BTM_IsBleConnection
+**
+** Description This function is called to check if the connection handle
+** for an LE link
+**
+** Returns TRUE if connection is LE link, otherwise FALSE.
+**
+*******************************************************************************/
+BOOLEAN BTM_IsBleConnection (UINT16 conn_handle)
+{
+#if (BLE_INCLUDED == TRUE)
+ UINT8 xx;
+ tACL_CONN *p;
+
+ BTM_TRACE_API1 ("BTM_IsBleConnection: conn_handle: %d", conn_handle);
+
+ xx = btm_handle_to_acl_index (conn_handle);
+ if (xx >= MAX_L2CAP_LINKS)
+ return FALSE;
+
+ p = &btm_cb.acl_db[xx];
+
+ return(p->is_le_link);
+#else
+ return FALSE;
+#endif
+}
/*******************************************************************************
**
@@ -327,7 +356,10 @@
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_addr);
memcpy(conn_addr, pseudo_addr, BD_ADDR_LEN);
- *p_addr_type = p_dev_rec->ble.ble_addr_type;
+ if (p_dev_rec != NULL)
+ {
+ *p_addr_type = p_dev_rec->ble.ble_addr_type;
+ }
#endif
return st;
}
@@ -689,7 +721,35 @@
#endif
return FALSE;
}
+/*******************************************************************************
+**
+** Function BTM_UseLeLink
+**
+** Description This function is to select the underneath physical link to use.
+**
+** Returns TRUE to use LE, FALSE use BR/EDR.
+**
+*******************************************************************************/
+BOOLEAN BTM_UseLeLink (BD_ADDR bd_addr)
+{
+ tACL_CONN *p;
+ tBT_DEVICE_TYPE dev_type;
+ tBLE_ADDR_TYPE addr_type;
+ BOOLEAN use_le = FALSE;
+ if ((p = btm_bda_to_acl(bd_addr)) != NULL)
+ {
+#if (BLE_INCLUDED == TRUE)
+ use_le = (p->is_le_link);
+#endif
+ }
+ else
+ {
+ BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type);
+ use_le = (dev_type == BT_DEVICE_TYPE_BLE);
+ }
+ return use_le;
+}
/*******************************************************************************
**
** Function btm_ble_rand_enc_complete
@@ -1006,7 +1066,7 @@
void btm_ble_link_sec_check(BD_ADDR bd_addr, tBTM_LE_AUTH_REQ auth_req, tBTM_BLE_SEC_REQ_ACT *p_sec_req_act)
{
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
- UINT8 req_sec_level, cur_sec_level;
+ UINT8 req_sec_level = BTM_LE_SEC_NONE, cur_sec_level = BTM_LE_SEC_NONE;
BTM_TRACE_DEBUG1 ("btm_ble_link_sec_check auth_req =0x%x", auth_req);
@@ -1167,9 +1227,11 @@
memcpy(p_cb->enc_rand, rand, BT_OCTET8_LEN);
- if (!smp_proc_ltk_request(p_dev_rec->bd_addr))
- btm_ble_ltk_request_reply(p_dev_rec->bd_addr, FALSE, dummy_stk);
-
+ if (p_dev_rec != NULL)
+ {
+ if (!smp_proc_ltk_request(p_dev_rec->bd_addr))
+ btm_ble_ltk_request_reply(p_dev_rec->bd_addr, FALSE, dummy_stk);
+ }
}
@@ -1188,6 +1250,7 @@
tBTM_CB *p_cb = &btm_cb;
tBTM_SEC_DEV_REC *p_rec = btm_find_dev (bda);
BT_OCTET8 dummy_rand = {0};
+ BOOLEAN rt = FALSE;
BTM_TRACE_DEBUG0 ("btm_ble_start_encrypt");
@@ -1195,27 +1258,30 @@
(p_rec && p_rec->sec_state == BTM_SEC_STATE_ENCRYPTING))
return FALSE;
- if (p_rec->sec_state == BTM_SEC_STATE_IDLE)
- p_rec->sec_state = BTM_SEC_STATE_ENCRYPTING;
p_cb->enc_handle = p_rec->hci_handle;
if (use_stk)
{
- if (!btsnd_hcic_ble_start_enc(p_rec->hci_handle, dummy_rand, 0, stk))
- return FALSE;
+ if (btsnd_hcic_ble_start_enc(p_rec->hci_handle, dummy_rand, 0, stk))
+ rt = TRUE;
}
else if (p_rec->ble.key_type & BTM_LE_KEY_PENC)
{
- if (!btsnd_hcic_ble_start_enc(p_rec->hci_handle, p_rec->ble.keys.rand,
+ if (btsnd_hcic_ble_start_enc(p_rec->hci_handle, p_rec->ble.keys.rand,
p_rec->ble.keys.ediv, p_rec->ble.keys.ltk))
- return FALSE;
+ rt = TRUE;
}
else
{
- return FALSE;
+ BTM_TRACE_ERROR0("No key available to encrypt the link");
+ }
+ if (rt)
+ {
+ if (p_rec->sec_state == BTM_SEC_STATE_IDLE)
+ p_rec->sec_state = BTM_SEC_STATE_ENCRYPTING;
}
- return TRUE;
+ return rt;
}
/*******************************************************************************
@@ -1519,6 +1585,9 @@
if (status == HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT)
btm_ble_dir_adv_tout();
}
+
+ btm_ble_set_conn_st(BLE_CONN_IDLE);
+
btm_ble_update_mode_operation(role, bda, TRUE);
}
@@ -1548,6 +1617,9 @@
case SMP_OOB_REQ_EVT:
p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
case SMP_SEC_REQUEST_EVT:
+ memcpy (btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN);
+ p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
+ /* fall through */
case SMP_COMPLT_EVT:
if (btm_cb.api.p_le_callback)
{
@@ -1575,7 +1647,7 @@
#if BTM_BLE_CONFORMANCE_TESTING == TRUE
if (res != BTM_SUCCESS)
{
- if (!btm_cb.devcb.no_disc_if_pair_fail)
+ if (!btm_cb.devcb.no_disc_if_pair_fail && p_data->cmplt.reason != SMP_CONN_TOUT)
{
BTM_TRACE_DEBUG0 ("Pairing failed - Remove ACL");
btm_remove_acl(bd_addr);
@@ -1587,7 +1659,7 @@
}
}
#else
- if (res != BTM_SUCCESS)
+ if (res != BTM_SUCCESS && p_data->cmplt.reason != SMP_CONN_TOUT)
btm_remove_acl(bd_addr);
#endif
@@ -1600,6 +1672,7 @@
btm_cb.pairing_bda[3], btm_cb.pairing_bda[4], btm_cb.pairing_bda[5]);
memset (btm_cb.pairing_bda, 0xff, BD_ADDR_LEN);
+ btm_cb.pairing_state = BTM_PAIR_STATE_IDLE;
btm_cb.pairing_flags = 0;
}
break;
@@ -1665,6 +1738,7 @@
if ((p_buf = (UINT8 *)GKI_getbuf((UINT16)(len + 4))) != NULL)
{
BTM_TRACE_DEBUG0("Start to generate Local CSRK");
+ pp = p_buf;
/* prepare plain text */
if (p_text)
{
diff --git a/stack/btm/btm_ble_bgconn.c b/stack/btm/btm_ble_bgconn.c
index 3b8b1e2..727390c 100644
--- a/stack/btm/btm_ble_bgconn.c
+++ b/stack/btm/btm_ble_bgconn.c
@@ -62,29 +62,17 @@
}
/*******************************************************************************
**
-** Function btm_update_dev_to_white_list
+** Function btm_add_dev_to_controller
**
-** Description This function adds a device into white list.
+** Description This function load the device into controller white list
*******************************************************************************/
-BOOLEAN btm_update_dev_to_white_list(BOOLEAN to_add, BD_ADDR bd_addr, UINT8 attr)
+BOOLEAN btm_add_dev_to_controller (BOOLEAN to_add, BD_ADDR bd_addr, UINT8 attr)
{
- /* look up the sec device record, and find the address */
- tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
- BD_ADDR dummy_bda = {0};
- BOOLEAN started = FALSE;
- UINT8 wl_state = p_cb->wl_state;
- tBT_DEVICE_TYPE dev_type;
tBLE_ADDR_TYPE addr_type = BLE_ADDR_PUBLIC;
-
- if ((to_add && p_cb->num_empty_filter == 0) ||
- (!to_add && p_cb->num_empty_filter == p_cb->max_filter_entries))
- {
- BTM_TRACE_ERROR1("WL full or empty, unable to update to WL. num_entry available: %d", p_cb->num_empty_filter);
- return started;
- }
-
- btm_suspend_wl_activity(wl_state);
+ BOOLEAN started = FALSE;
+ BD_ADDR dummy_bda = {0};
+ tBT_DEVICE_TYPE dev_type;
if (p_dev_rec != NULL &&
p_dev_rec->device_type == BT_DEVICE_TYPE_BLE)
@@ -92,7 +80,7 @@
if (to_add)
{
- if (!BTM_BLE_IS_RESOLVE_BDA(bd_addr))
+ if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_PUBLIC || !BTM_BLE_IS_RESOLVE_BDA(bd_addr))
{
started = btsnd_hcic_ble_add_white_list (p_dev_rec->ble.ble_addr_type, bd_addr);
}
@@ -108,7 +96,8 @@
{
started = btsnd_hcic_ble_remove_from_white_list (p_dev_rec->ble.ble_addr_type, bd_addr);
}
- if (memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) != 0)
+ if (memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) != 0 &&
+ memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) != 0)
{
started = btsnd_hcic_ble_remove_from_white_list (p_dev_rec->ble.static_addr_type, p_dev_rec->ble.static_addr);
}
@@ -117,12 +106,101 @@
else
{
BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type);
+
if (to_add)
started = btsnd_hcic_ble_add_white_list (addr_type, bd_addr);
else
started = btsnd_hcic_ble_remove_from_white_list (addr_type, bd_addr);
}
+ return started;
+
+}
+/*******************************************************************************
+**
+** Function btm_execute_wl_dev_operation
+**
+** Description execute the pending whitelist device operation(loading or removing)
+*******************************************************************************/
+BOOLEAN btm_execute_wl_dev_operation(void)
+{
+ tBTM_BLE_WL_OP *p_dev_op = btm_cb.ble_ctr_cb.wl_op_q;
+ UINT8 i = 0;
+ BOOLEAN rt = TRUE;
+
+ for (i = 0; i < BTM_BLE_MAX_BG_CONN_DEV_NUM && rt; i ++, p_dev_op ++)
+ {
+ if (p_dev_op->in_use)
+ {
+ rt = btm_add_dev_to_controller(p_dev_op->to_add, p_dev_op->bd_addr, p_dev_op->attr);
+ memset(p_dev_op, 0, sizeof(tBTM_BLE_WL_OP));
+ }
+ else
+ break;
+ }
+ return rt;
+}
+/*******************************************************************************
+**
+** Function btm_enq_wl_dev_operation
+**
+** Description enqueue the pending whitelist device operation(loading or removing).
+*******************************************************************************/
+void btm_enq_wl_dev_operation(BOOLEAN to_add, BD_ADDR bd_addr, UINT8 attr)
+{
+ tBTM_BLE_WL_OP *p_dev_op = btm_cb.ble_ctr_cb.wl_op_q;
+ UINT8 i = 0;
+
+ for (i = 0; i < BTM_BLE_MAX_BG_CONN_DEV_NUM; i ++, p_dev_op ++)
+ {
+ if (p_dev_op->in_use && !memcmp(p_dev_op->bd_addr, bd_addr, BD_ADDR_LEN))
+ {
+ p_dev_op->to_add = to_add;
+ p_dev_op->attr = attr;
+ return;
+ }
+ else if (!p_dev_op->in_use)
+ break;
+ }
+ if (i != BTM_BLE_MAX_BG_CONN_DEV_NUM)
+ {
+ p_dev_op->in_use = TRUE;
+ p_dev_op->to_add = to_add;
+ p_dev_op->attr = attr;
+ memcpy(p_dev_op->bd_addr, bd_addr, BD_ADDR_LEN);
+ }
+ else
+ {
+ BTM_TRACE_ERROR0("max pending WL operation reached, discard");
+ }
+ return;
+}
+/*******************************************************************************
+**
+** Function btm_update_dev_to_white_list
+**
+** Description This function adds a device into white list.
+*******************************************************************************/
+BOOLEAN btm_update_dev_to_white_list(BOOLEAN to_add, BD_ADDR bd_addr, UINT8 attr)
+{
+ /* look up the sec device record, and find the address */
+ tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
+ BOOLEAN started = FALSE;
+ UINT8 wl_state = p_cb->wl_state;
+
+ if ((to_add && p_cb->num_empty_filter == 0) ||
+ (!to_add && p_cb->num_empty_filter == p_cb->max_filter_entries))
+ {
+ BTM_TRACE_ERROR1("WL full or empty, unable to update to WL. num_entry available: %d",
+ p_cb->num_empty_filter);
+ return started;
+ }
+
+ btm_suspend_wl_activity(wl_state);
+
+ /* enq pending WL device operation */
+ btm_enq_wl_dev_operation(to_add, bd_addr, attr);
+
btm_resume_wl_activity(wl_state);
return started;
@@ -217,7 +295,6 @@
*******************************************************************************/
BOOLEAN btm_update_bg_conn_list(BOOLEAN to_add, BD_ADDR bd_addr, UINT8 *p_attr_tag)
{
- UINT8 white_list_type = *p_attr_tag;
tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
tBTM_LE_BG_CONN_DEV *p_bg_dev = &p_cb->bg_dev_list[0], *p_next, *p_cur;
UINT8 i, j;
@@ -235,12 +312,7 @@
{
if (p_bg_dev->in_use && memcmp(p_bg_dev->bd_addr, bd_addr, BD_ADDR_LEN) == 0)
{
- if (to_add)
- p_bg_dev->attr |= white_list_type;
- else
- p_bg_dev->attr &= ~white_list_type;
-
- if (p_bg_dev->attr == 0)
+ if (!to_add)
{
memset(p_bg_dev, 0, sizeof(tBTM_LE_BG_CONN_DEV));
p_cb->bg_dev_num --;
@@ -258,7 +330,6 @@
memcpy(p_bg_dev->bd_addr, bd_addr, BD_ADDR_LEN);
p_bg_dev->in_use = TRUE;
- p_bg_dev->attr |= white_list_type;
p_cb->bg_dev_num ++;
ret = TRUE;
@@ -266,8 +337,6 @@
}
}
- if (i != BTM_BLE_MAX_BG_CONN_DEV_NUM)
- *p_attr_tag = p_bg_dev->attr;
return ret;
}
@@ -295,6 +364,7 @@
{
if (p_cb->conn_state == BLE_CONN_IDLE && btm_ble_count_unconn_dev_in_whitelist() > 0)
{
+ btm_execute_wl_dev_operation();
scan_int = (p_cb->scan_int == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_SLOW_INT_1 : p_cb->scan_int;
scan_win = (p_cb->scan_win == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_SLOW_WIN_1 : p_cb->scan_win;
@@ -317,7 +387,7 @@
}
else
{
- p_cb->conn_state = BLE_BG_CONN;
+ btm_ble_set_conn_st (BLE_BG_CONN);
}
}
@@ -331,7 +401,7 @@
if (p_cb->conn_state == BLE_BG_CONN)
{
btsnd_hcic_ble_create_conn_cancel();
- p_cb->conn_state = BLE_CONN_IDLE;
+ btm_ble_set_conn_st (BLE_CONN_CANCEL);
}
else
@@ -417,11 +487,9 @@
btm_update_scanner_filter_policy(SP_ADV_ALL);
/* stop scanning */
- if (p_cb->bg_dev_num > 0)
- {
if (!btsnd_hcic_ble_set_scan_enable(FALSE, TRUE)) /* duplicate filtering enabled */
return FALSE;
- }
+ btm_update_scanner_filter_policy(SP_ADV_ALL);
}
return TRUE;
}
diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c
index 7cef5f2..387f661 100644
--- a/stack/btm/btm_ble_gap.c
+++ b/stack/btm/btm_ble_gap.c
@@ -363,8 +363,7 @@
BOOLEAN BTM_BleUpdateBgConnDev(BOOLEAN add_remove, BD_ADDR remote_bda)
{
BOOLEAN ret = TRUE;
- UINT8 dev_wl_type = BTM_BLE_WL_INIT;
-
+ UINT8 dev_wl_type = 0;
BTM_TRACE_EVENT0 (" BTM_BleUpdateBgConnDev");
/* update white list */
@@ -2033,10 +2032,6 @@
btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode );
}
- /* if connection complete */
- if (conn_cancel || link_role != HCI_ROLE_UNKNOWN)
- btm_ble_set_conn_st(BLE_CONN_IDLE);
-
if (btm_ble_get_conn_st() == BLE_CONN_IDLE)
{
if (!btm_send_pending_direct_conn())
@@ -2074,7 +2069,7 @@
/* for background connection, reset connection params to be undefined */
p_cb->scan_int = p_cb->scan_win = BTM_BLE_CONN_PARAM_UNDEF;
- p_cb->inq_var.evt_type = BTM_BLE_UNKNOWN_EVT;
+ p_cb->inq_var.evt_type = BTM_BLE_NON_CONNECT_EVT;
}
#endif /* BLE_INCLUDED */
diff --git a/stack/btm/btm_ble_int.h b/stack/btm/btm_ble_int.h
index 2b17610..4aeab19 100644
--- a/stack/btm/btm_ble_int.h
+++ b/stack/btm/btm_ble_int.h
@@ -190,12 +190,22 @@
#define BLE_CONN_IDLE 0
#define BLE_DIR_CONN 1
#define BLE_BG_CONN 2
+#define BLE_CONN_CANCEL 3
typedef UINT8 tBTM_BLE_CONN_ST;
typedef struct
{
void *p_param;
}tBTM_BLE_CONN_REQ;
+
+
+typedef struct
+{
+ BOOLEAN in_use;
+ BOOLEAN to_add;
+ BD_ADDR bd_addr;
+ UINT8 attr;
+}tBTM_BLE_WL_OP;
/* Define BLE Device Management control structure
*/
typedef struct
@@ -226,12 +236,12 @@
tBTM_LE_RANDOM_CB addr_mgnt_cb;
BOOLEAN enabled;
+ tBTM_BLE_WL_OP wl_op_q[BTM_BLE_MAX_BG_CONN_DEV_NUM];
#ifdef BTM_BLE_PC_ADV_TEST_MODE
tBTM_BLE_SCAN_REQ_CBACK *p_scan_req_cback;
#endif
- BOOLEAN scatternet_enable;
} tBTM_BLE_CB;
#ifdef __cplusplus
diff --git a/stack/btm/btm_inq.c b/stack/btm/btm_inq.c
index d67f4d4..b1d9eac 100644
--- a/stack/btm/btm_inq.c
+++ b/stack/btm/btm_inq.c
@@ -968,11 +968,6 @@
tBTM_INQ_INFO *p_cur = NULL;
tINQ_DB_ENT *p_i;
-#if BLE_INCLUDED == TRUE
- tBT_DEVICE_TYPE dev_type;
- tBLE_ADDR_TYPE addr_type;
-#endif
-
BTM_TRACE_API6 ("BTM_ReadRemoteDeviceName: bd addr [%02x%02x%02x%02x%02x%02x]",
remote_bda[0], remote_bda[1], remote_bda[2],
remote_bda[3], remote_bda[4], remote_bda[5]);
@@ -989,8 +984,7 @@
BTM_TRACE_API0 ("no device found in inquiry db");
#if (BLE_INCLUDED == TRUE)
- BTM_ReadDevInfo(remote_bda, &dev_type, &addr_type);
- if (dev_type == BT_DEVICE_TYPE_BLE)
+ if (BTM_UseLeLink(remote_bda))
{
return btm_ble_read_remote_name(remote_bda, p_cur, p_cb);
}
@@ -1021,19 +1015,13 @@
{
tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
-#if BLE_INCLUDED == TRUE
- tBT_DEVICE_TYPE dev_type;
- tBLE_ADDR_TYPE addr_type;
-#endif
-
BTM_TRACE_API0 ("BTM_CancelRemoteDeviceName()");
/* Make sure there is not already one in progress */
if (p_inq->remname_active)
{
#if BLE_INCLUDED == TRUE
- BTM_ReadDevInfo(p_inq->remname_bda, &dev_type, &addr_type);
- if (dev_type == BT_DEVICE_TYPE_BLE)
+ if (BTM_UseLeLink(p_inq->remname_bda))
{
if (btm_ble_cancel_remote_name(p_inq->remname_bda))
return (BTM_CMD_STARTED);
@@ -2533,11 +2521,6 @@
UINT8 *p_n;
tBTM_INQ_INFO *p_cur;
#endif
-#if BLE_INCLUDED == TRUE
- tBT_DEVICE_TYPE dev_type;
- tBLE_ADDR_TYPE addr_type;
-#endif
-
if (bda != NULL)
{
@@ -2559,8 +2542,7 @@
{
#if BLE_INCLUDED == TRUE
- BTM_ReadDevInfo(p_inq->remname_bda, &dev_type, &addr_type);
- if (dev_type == BT_DEVICE_TYPE_BLE)
+ if (BTM_UseLeLink(p_inq->remname_bda))
{
if (hci_status == HCI_ERR_UNSPECIFIED)
btm_ble_cancel_remote_name(p_inq->remname_bda);
@@ -2658,8 +2640,7 @@
{
p_cur->remote_name_state = BTM_INQ_RMT_NAME_PENDING;
#if (BLE_INCLUDED == TRUE)
- BTM_ReadDevInfo(remote_bda, &dev_type, &addr_type);
- if (dev_type == BT_DEVICE_TYPE_BLE)
+ if (BTM_UseLeLink(remote_bda))
{
if (btm_ble_read_remote_name(remote_bda, p_cur, p_cb) != BTM_CMD_STARTED)
p_cur->remote_name_state = BTM_INQ_RMT_NAME_FAILED;
diff --git a/stack/btm/btm_sec.c b/stack/btm/btm_sec.c
index 402f81f..8bcf435 100644
--- a/stack/btm/btm_sec.c
+++ b/stack/btm/btm_sec.c
@@ -44,9 +44,10 @@
BOOLEAN (APPL_AUTH_WRITE_EXCEPTION)(BD_ADDR bd_addr);
#endif
-/********************************************************************************/
-/* L O C A L F U N C T I O N P R O T O T Y P E S */
-/********************************************************************************/
+
+/********************************************************************************
+** L O C A L F U N C T I O N P R O T O T Y P E S *
+*********************************************************************************/
static tBTM_SEC_SERV_REC *btm_sec_find_first_serv (BOOLEAN is_originator, UINT16 psm);
static tBTM_SEC_SERV_REC *btm_sec_find_next_serv (tBTM_SEC_SERV_REC *p_cur);
static tBTM_SEC_SERV_REC *btm_sec_find_mx_serv (UINT8 is_originator, UINT16 psm,
@@ -1051,12 +1052,7 @@
tBTM_STATUS status;
UINT8 *p_features;
UINT8 ii;
-#if SMP_INCLUDED == TRUE
- tACL_CONN *p=NULL;
- BOOLEAN is_le_slave_role=FALSE;
- tBT_DEVICE_TYPE dev_type;
- tBLE_ADDR_TYPE addr_type;
-#endif
+
BTM_TRACE_API6 ("BTM_SecBond BDA: %02x:%02x:%02x:%02x:%02x:%02x",
bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
@@ -1067,47 +1063,13 @@
return(BTM_WRONG_MODE);
}
+ if ((p_dev_rec = btm_find_or_alloc_dev (bd_addr)) == NULL)
+ {
+ return(BTM_NO_RESOURCES);
+ }
- p_dev_rec = btm_find_or_alloc_dev (bd_addr);
BTM_TRACE_DEBUG1 ("before update sec_flags=0x%x", p_dev_rec->sec_flags);
-
-#if SMP_INCLUDED == TRUE
- p = btm_bda_to_acl(bd_addr);
- if (p && p->is_le_link )
- {
- if (p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING)
- {
- BTM_TRACE_ERROR1 ("BTM_SecBond: LE already busy in state: %x", p_dev_rec->sec_state );
- return(BTM_WRONG_MODE);
- }
-
- if (p->link_role == BTM_ROLE_SLAVE)
- {
- is_le_slave_role = TRUE;
- BTM_TRACE_DEBUG0 ("LE Link Slave" );
- }
- else
- {
- BTM_TRACE_DEBUG0 ("LE Link Maste" );
- }
- }
- else
- {
- BTM_TRACE_DEBUG0 ("No LE Link" );
- }
-
- if (!is_le_slave_role)
- {
- /* Finished if connection is active and already paired */
- if ( (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE)
- && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED) )
- {
- BTM_TRACE_WARNING0("BTM_SecBond -> Already Paired");
- return(BTM_SUCCESS);
- }
- }
-#else
/* Finished if connection is active and already paired */
if ( (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE)
&& (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED) )
@@ -1115,7 +1077,6 @@
BTM_TRACE_WARNING0("BTM_SecBond -> Already Paired");
return(BTM_SUCCESS);
}
-#endif
/* Tell controller to get rid of the link key if it has one stored */
if ((BTM_DeleteStoredLinkKey (bd_addr, NULL)) != BTM_SUCCESS)
@@ -1137,32 +1098,23 @@
if (trusted_mask)
BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask);
-
-
-#if SMP_INCLUDED == TRUE
-
- if (!is_le_slave_role)
- {
- p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED
+ p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED
| BTM_SEC_ROLE_SWITCHED | BTM_SEC_LINK_KEY_AUTHED);
- }
- BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type);
+#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
/* LE device, do SMP pairing */
- if (dev_type == BT_DEVICE_TYPE_BLE)
+ if (BTM_UseLeLink(bd_addr))
{
if (SMP_Pair(bd_addr) == SMP_STARTED)
{
+ btm_cb.pairing_state = BTM_PAIR_STATE_WAIT_AUTH_COMPLETE;
p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
return BTM_CMD_STARTED;
}
else
return(BTM_NO_RESOURCES);
}
-#else
- p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED
- | BTM_SEC_ROLE_SWITCHED | BTM_SEC_LINK_KEY_AUTHED);
#endif
BTM_TRACE_DEBUG1 ("after update sec_flags=0x%x", p_dev_rec->sec_flags);
@@ -1180,9 +1132,6 @@
}
}
- BTM_TRACE_EVENT1("BTM_SecBond: Local device supports SSP=%d",
- HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]));
-
for (ii = 0; ii <= HCI_EXT_FEATURES_PAGE_MAX; ii++)
{
p_features = p_dev_rec->features[ii];
diff --git a/stack/gap/gap_ble.c b/stack/gap/gap_ble.c
index 19e24a9..6e3afeb 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 @@
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 @@
(* 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_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 @@
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_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],
diff --git a/stack/gatt/gatt_api.c b/stack/gatt/gatt_api.c
index 91eca96..a96c58a 100644
--- a/stack/gatt/gatt_api.c
+++ b/stack/gatt/gatt_api.c
@@ -1537,7 +1537,7 @@
** bd_addr: peer device address. (input)
** p_conn_id: connection id (output)
**
-** Returns TRUE the ligical link is connected
+** Returns TRUE the logical link is connected
**
*******************************************************************************/
BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, UINT16 *p_conn_id)
diff --git a/stack/gatt/gatt_auth.c b/stack/gatt/gatt_auth.c
index ab74001..504b7d8 100644
--- a/stack/gatt/gatt_auth.c
+++ b/stack/gatt/gatt_auth.c
@@ -316,7 +316,7 @@
if (auth_req == GATT_AUTH_REQ_NONE )
return act;
- is_le_link = BTM_IsBleLink(p_tcb->peer_bda);
+ is_le_link = BTM_UseLeLink(p_tcb->peer_bda);
BTM_GetSecurityFlags(p_tcb->peer_bda, &sec_flag);
btm_ble_link_sec_check(p_tcb->peer_bda, auth_req, &sec_act);
diff --git a/stack/gatt/gatt_cl.c b/stack/gatt/gatt_cl.c
index e9402aa..b6dc9d8 100644
--- a/stack/gatt/gatt_cl.c
+++ b/stack/gatt/gatt_cl.c
@@ -73,6 +73,7 @@
{
UINT8 op_code = disc_type_to_att_opcode[p_clcb->op_subtype];
tGATT_CL_MSG cl_req;
+ tGATT_STATUS st;
if (p_clcb->s_handle <= p_clcb->e_handle && p_clcb->s_handle != 0)
{
@@ -97,7 +98,9 @@
memcpy (cl_req.find_type_value.value, &p_clcb->uuid.uu, p_clcb->uuid.len);
}
- if (attp_send_cl_msg(p_clcb->p_tcb, p_clcb->clcb_idx, op_code, &cl_req) != GATT_SUCCESS)
+ st = attp_send_cl_msg(p_clcb->p_tcb, p_clcb->clcb_idx, op_code, &cl_req);
+
+ if (st != GATT_SUCCESS && st != GATT_CMD_STARTED)
{
gatt_end_operation(p_clcb, GATT_ERROR, NULL);
}
@@ -185,8 +188,10 @@
break;
}
- if ( op_code == 0 ||
- (rt = attp_send_cl_msg(p_tcb, p_clcb->clcb_idx, op_code, &msg)) != GATT_SUCCESS)
+ if (op_code != 0)
+ rt = attp_send_cl_msg(p_tcb, p_clcb->clcb_idx, op_code, &msg);
+
+ if ( op_code == 0 || (rt != GATT_SUCCESS && rt != GATT_CMD_STARTED))
{
gatt_end_operation(p_clcb, rt, NULL);
}
@@ -204,7 +209,7 @@
void gatt_act_write (tGATT_CLCB *p_clcb, UINT8 sec_act)
{
tGATT_TCB *p_tcb = p_clcb->p_tcb;
- UINT8 rt = GATT_SUCCESS, op_code;
+ UINT8 rt = GATT_SUCCESS, op_code = 0;
tGATT_VALUE *p_attr = (tGATT_VALUE *)p_clcb->p_attr_buf;
if (p_attr)
@@ -373,7 +378,7 @@
/* remember the write long attribute length */
p_clcb->counter = to_send;
- if (rt != GATT_SUCCESS )
+ if (rt != GATT_SUCCESS && rt != GATT_CMD_STARTED)
{
gatt_end_operation(p_clcb, rt, NULL);
}
@@ -820,7 +825,7 @@
}
return;
}
- else /* discover characterisitic or read characteristic value */
+ else /* discover characterisitic */
{
STREAM_TO_UINT8 (record_value.dclr_value.char_prop, p);
STREAM_TO_UINT16(record_value.dclr_value.val_handle, p);
diff --git a/stack/gatt/gatt_main.c b/stack/gatt/gatt_main.c
index dcd9398..075bda3 100644
--- a/stack/gatt/gatt_main.c
+++ b/stack/gatt/gatt_main.c
@@ -36,6 +36,10 @@
#define GATT_L2C_CFG_IND_DONE (1<<0)
#define GATT_L2C_CFG_CFM_DONE (1<<1)
+/* minimum GATT MTU size over BR/EDR link
+*/
+#define GATT_MIN_BR_MTU_SIZE 48
+
/********************************************************************************/
/* L O C A L F U N C T I O N P R O T O T Y P E S */
/********************************************************************************/
@@ -139,24 +143,21 @@
*******************************************************************************/
BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb)
{
- BOOLEAN gatt_ret = TRUE;
- tBT_DEVICE_TYPE dev_type;
- tBLE_ADDR_TYPE addr_type;
-
- BTM_ReadDevInfo(rem_bda, &dev_type, &addr_type);
+ BOOLEAN gatt_ret = FALSE;
if (gatt_get_ch_state(p_tcb) != GATT_CH_OPEN)
gatt_set_ch_state(p_tcb, GATT_CH_CONN);
- if (dev_type == BT_DEVICE_TYPE_BLE)
+ /* select the physical link for GATT connection */
+ if (BTM_UseLeLink(rem_bda))
{
p_tcb->att_lcid = L2CAP_ATT_CID;
gatt_ret = L2CA_ConnectFixedChnl (L2CAP_ATT_CID, rem_bda);
}
else
{
- if ((p_tcb->att_lcid = L2CA_ConnectReq(BT_PSM_ATT, rem_bda)) == 0)
- gatt_ret = FALSE;
+ if ((p_tcb->att_lcid = L2CA_ConnectReq(BT_PSM_ATT, rem_bda)) != 0)
+ gatt_ret = TRUE;
}
return gatt_ret;
@@ -328,7 +329,9 @@
st = gatt_get_ch_state(p_tcb);
/* before link down, another app try to open a GATT connection */
- if(st == GATT_CH_OPEN && gatt_num_apps_hold_link(p_tcb) == 0 )
+ if(st == GATT_CH_OPEN && gatt_num_apps_hold_link(p_tcb) == 0 &&
+ /* only connection on fix channel when the l2cap channel is already open */
+ p_tcb->att_lcid == L2CAP_ATT_CID )
{
if (!gatt_connect(bd_addr, p_tcb))
ret = FALSE;
@@ -419,11 +422,6 @@
gatt_send_conn_cback(p_tcb);
}
- else /* there was an exisiting link, ignore the callback */
- {
- GATT_TRACE_ERROR0("connection already up, ignore it");
- return;
- }
}
/* this is incoming connection or background connection callback */
else
@@ -585,7 +583,7 @@
/* else initiating connection failure */
else
{
- gatt_cleanup_upon_disc(p_tcb->peer_bda, result);
+ gatt_cleanup_upon_disc(p_tcb->peer_bda, GATT_CONN_L2C_FAILURE);
}
}
else /* wrong state, disconnect it */
@@ -637,11 +635,8 @@
}
else
{
- if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda) &&
- btm_sec_is_le_capable_dev(p_tcb->peer_bda))
- {
+ if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
- }
}
/* send callback */
@@ -676,7 +671,8 @@
if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL)
{
/* GATT uses the smaller of our MTU and peer's MTU */
- if ( (p_cfg->mtu_present) && (p_cfg->mtu < L2CAP_DEFAULT_MTU) )
+ if ( p_cfg->mtu_present &&
+ (p_cfg->mtu >= GATT_MIN_BR_MTU_SIZE && p_cfg->mtu < L2CAP_DEFAULT_MTU))
p_tcb->payload_size = p_cfg->mtu;
else
p_tcb->payload_size = L2CAP_DEFAULT_MTU;
@@ -998,11 +994,6 @@
{
gatt_send_srv_chg_ind(p_srv_chg_clt->bda);
}
- else
- {
- GATT_TRACE_DEBUG0("No need to send srv chg ");
- }
-
}
/*******************************************************************************
diff --git a/stack/gatt/gatt_sr.c b/stack/gatt/gatt_sr.c
index b7ad6f9..da36722 100644
--- a/stack/gatt/gatt_sr.c
+++ b/stack/gatt/gatt_sr.c
@@ -338,7 +338,7 @@
GATT_TRACE_DEBUG2("conf test forced err rsp for %s error status=%d",
__FUNCTION__,gatt_cb.err_status);
- gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, 0, FALSE);
+ gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, gatt_cb.handle, FALSE);
return;
}
@@ -395,7 +395,7 @@
void gatt_process_read_multi_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data)
{
UINT32 trans_id;
- UINT16 handle, ll = len;
+ UINT16 handle = 0, ll = len;
UINT8 *p = p_data, i_rcb;
tGATT_STATUS err = GATT_SUCCESS;
UINT8 sec_flag, key_size;
@@ -1241,6 +1241,7 @@
len -= 2;
#if GATT_CONFORMANCE_TESTING == TRUE
+ gatt_cb.handle = handle;
if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code)
{
GATT_TRACE_DEBUG1("Conformance tst: forced err rsp: error status=%d", gatt_cb.err_status);
diff --git a/stack/gatt/gatt_utils.c b/stack/gatt/gatt_utils.c
index 5b375b5..b7f5224 100644
--- a/stack/gatt/gatt_utils.c
+++ b/stack/gatt/gatt_utils.c
@@ -710,7 +710,7 @@
for (i = start_idx ; i < GATT_MAX_PHY_CHANNEL; i ++)
{
- if (gatt_cb.tcb[i].in_use)
+ if (gatt_cb.tcb[i].in_use && gatt_cb.tcb[i].ch_state == GATT_CH_OPEN)
{
memcpy( bda, gatt_cb.tcb[i].peer_bda, BD_ADDR_LEN);
*p_found_idx = i;
@@ -2543,7 +2543,9 @@
if (p_dev_list->listen_gif[j] == gatt_if)
{
p_dev_list->listen_gif[j] = 0;
- p_reg->listening --;
+
+ if (p_reg != NULL && p_reg->listening > 0)
+ p_reg->listening --;
/* move all element behind one forward */
for (k = j + 1; k < GATT_MAX_APPS; k ++)
diff --git a/stack/include/btm_ble_api.h b/stack/include/btm_ble_api.h
index bb654e5..0dcc8d2 100644
--- a/stack/include/btm_ble_api.h
+++ b/stack/include/btm_ble_api.h
@@ -875,6 +875,17 @@
*******************************************************************************/
BTM_API extern BOOLEAN BTM_IsBleLink (BD_ADDR bd_addr);
+/*******************************************************************************
+**
+** Function BTM_UseLeLink
+**
+** Description This function is to select the underneath physical link to use.
+**
+** Returns TRUE to use LE, FALSE use BR/EDR.
+**
+*******************************************************************************/
+BTM_API extern BOOLEAN BTM_UseLeLink (BD_ADDR bd_addr);
+
#ifdef __cplusplus
}
#endif
diff --git a/stack/include/gatt_api.h b/stack/include/gatt_api.h
index d53a80e..01afb71 100644
--- a/stack/include/gatt_api.h
+++ b/stack/include/gatt_api.h
@@ -100,7 +100,7 @@
#define GATT_HANDLE_IS_VALID(x) ((x) != 0)
#define GATT_CONN_UNKNOWN 0
-#define GATT_CONN_NO_RESOURCES L2CAP_CONN_NO_RESOURCES /* connection fail for l2cap resource failure */
+#define GATT_CONN_L2C_FAILURE 1 /* general L2cap failure */
#define GATT_CONN_TIMEOUT HCI_ERR_CONNECTION_TOUT /* 0x08 connection timeout */
#define GATT_CONN_TERMINATE_PEER_USER HCI_ERR_PEER_USER /* 0x13 connection terminate by peer user */
#define GATT_CONN_TERMINATE_LOCAL_HOST HCI_ERR_CONN_CAUSE_LOCAL_HOST /* 0x16 connectionterminated by local host */
@@ -244,6 +244,15 @@
UINT8 name_spc; /* The name space of the description */
} tGATT_CHAR_PRES;
+/* Characteristic Report reference Descriptor format
+*/
+typedef struct
+{
+ UINT8 rpt_id; /* report ID */
+ UINT8 rpt_type; /* report type */
+} tGATT_CHAR_RPT_REF;
+
+
#define GATT_VALID_RANGE_MAX_SIZE 16
typedef struct
{
@@ -522,12 +531,10 @@
tGATT_INCL_SRVC incl_service; /* include service value */
tGATT_GROUP_VALUE group_value; /* Service UUID type.
This field is used with GATT_DISC_SRVC_ALL
+ or GATT_DISC_SRVC_BY_UUID
type of discovery result callback. */
- UINT16 handle; /* When used with GATT_DISC_SRVC_BY_UUID type
- discovery result, it is the ending handle of a
- known service to be discovered. When used with
- GATT_DISC_INC_SRVC type discovery result,
+ UINT16 handle; /* When used with GATT_DISC_INC_SRVC type discovery result,
it is the included service starting handle.*/
tGATT_CHAR_DCLR_VAL dclr_value; /* Characteristic declaration value.
@@ -1047,7 +1054,8 @@
**
** Function GATT_Connect
**
-** Description This function initiate a connecttion to a ATT server.
+** Description This function initiate a connecttion to a remote device on GATT
+** channel.
**
** Parameters gatt_if: applicaiton interface
** bd_addr: peer device address.
@@ -1063,7 +1071,8 @@
**
** Function GATT_CancelConnect
**
-** Description This function initiate a cancel connecttion to a ATT server.
+** Description This function terminate the connection initaition to a remote
+** device on GATT channel.
**
** Parameters gatt_if: client interface. If 0 used as unconditionally disconnect,
** typically used for direct connection cancellation.
@@ -1079,7 +1088,8 @@
**
** Function GATT_Disconnect
**
-** Description This function disconnect a logic channel.
+** Description This function disconnect the GATT channel for this registered
+** application.
**
** Parameters conn_id: connection identifier.
**
diff --git a/stack/l2cap/l2c_ble.c b/stack/l2cap/l2c_ble.c
index 75053bd..494c6e6 100644
--- a/stack/l2cap/l2c_ble.c
+++ b/stack/l2cap/l2c_ble.c
@@ -48,7 +48,7 @@
tL2C_LCB *p_lcb;
/* There can be only one BLE connection request outstanding at a time */
- if (btm_ble_get_conn_st() == BLE_DIR_CONN)
+ if (btm_ble_get_conn_st() == BLE_CONN_IDLE)
{
L2CAP_TRACE_WARNING0 ("L2CA_CancelBleConnectReq - no connection pending");
return(FALSE);
@@ -72,8 +72,8 @@
p_lcb->disc_reason = L2CAP_CONN_CANCEL;
l2cu_release_lcb (p_lcb);
}
- /* update conn state to IDLE */
- btm_ble_set_conn_st (BLE_CONN_IDLE);
+ /* update state to be cancel, wait for connection cancel complete */
+ btm_ble_set_conn_st (BLE_CONN_CANCEL);
return(TRUE);
}
@@ -551,9 +551,9 @@
if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int */
scan_win, /* UINT16 scan_win */
FALSE, /* UINT8 white_list */
- p_lcb->ble_addr_type, /* UINT8 addr_type_peer */
- p_lcb->remote_bd_addr, /* BD_ADDR bda_peer */
- BLE_ADDR_PUBLIC, /* UINT8 addr_type_own */
+ init_addr_type, /* UINT8 addr_type_peer */
+ init_addr, /* BD_ADDR bda_peer */
+ own_addr_type, /* UINT8 addr_type_own */
(UINT16) ((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN), /* UINT16 conn_int_min */
(UINT16) ((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MIN), /* UINT16 conn_int_max */
(UINT16) ((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.slave_latency : 0), /* UINT16 conn_latency */
@@ -568,6 +568,7 @@
else
{
p_lcb->link_state = LST_CONNECTING;
+ l2cb.is_ble_connecting = TRUE;
memcpy (l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN);
btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_BLE_LINK_CONNECT_TOUT);
btm_ble_set_conn_st (BLE_DIR_CONN);
diff --git a/stack/smp/smp_act.c b/stack/smp/smp_act.c
index e3f676b..032f3ed 100644
--- a/stack/smp/smp_act.c
+++ b/stack/smp/smp_act.c
@@ -889,10 +889,27 @@
{
SMP_TRACE_DEBUG0 ("smp_pair_terminate ");
- if (p_data->reason == L2CAP_CONN_CANCEL)
p_cb->status = SMP_CONN_TOUT;
+
+ smp_proc_pairing_cmpl(p_cb);
+}
+
+/*******************************************************************************
+** Function smp_delay_terminate
+** Description This function is called when connection dropped when smp delay
+** timer is still active.
+*******************************************************************************/
+void smp_delay_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
+{
+ SMP_TRACE_DEBUG0 ("smp_delay_terminate ");
+
+ btu_stop_timer (&p_cb->rsp_timer_ent);
+
+ /* if remote user terminate connection, finish SMP pairing as normal */
+ if (p_data->reason == HCI_ERR_PEER_USER)
+ p_cb->status = SMP_SUCCESS;
else
- p_cb->status = SMP_PAIR_FAIL_UNKNOWN;
+ p_cb->status = SMP_CONN_TOUT;
smp_proc_pairing_cmpl(p_cb);
}
diff --git a/stack/smp/smp_int.h b/stack/smp/smp_int.h
index e8d93de..51cdbb3 100644
--- a/stack/smp/smp_int.h
+++ b/stack/smp/smp_int.h
@@ -287,6 +287,7 @@
extern void smp_key_distribution(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_proc_srk_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
extern void smp_generate_csrk(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
+extern void smp_delay_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
/* smp_l2c */
extern void smp_l2cap_if_init (void);
diff --git a/stack/smp/smp_main.c b/stack/smp/smp_main.c
index 59dddb4..f8e450c 100644
--- a/stack/smp/smp_main.c
+++ b/stack/smp/smp_main.c
@@ -113,6 +113,7 @@
SMP_PROC_DISCARD,
SMP_PROC_REL_DELAY,
SMP_PROC_REL_DELAY_TOUT,
+ SMP_DELAY_TERMINATE,
SMP_SM_NO_ACTION
};
@@ -154,6 +155,7 @@
smp_proc_discard,
smp_proc_release_delay,
smp_proc_release_delay_tout,
+ smp_delay_terminate,
};
/************ SMP Master FSM State/Event Indirection Table **************/
static const UINT8 smp_ma_entry_map[][SMP_ST_MAX] =
@@ -174,7 +176,7 @@
/* KEY_READY */{ 0, 3, 0, 3, 1, 0, 2, 1, 6, 0 },
/* ENC_CMPL */{ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 },
/* L2C_CONN */{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-/* L2C_DISC */{ 0x83, 0x83, 0, 0x83, 0x83,0x83, 0x83,0x83, 0x83, 2 },
+/* L2C_DISC */{ 0x83, 0x83, 0, 0x83, 0x83,0x83, 0x83,0x83, 0x83, 3 },
/* IO_RSP */{ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0 },
/* SEC_GRANT */{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
/* TK_REQ */{ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 },
@@ -250,7 +252,8 @@
static const UINT8 smp_ma_rel_delay_table[][SMP_SM_NUM_COLS] = {
/* Event Action Next State */
/* RELEASE_DELAY*/ {SMP_PROC_REL_DELAY, SMP_SM_NO_ACTION, SMP_ST_RELEASE_DELAY},
-/* RELEASE_DELAY_TOUT*/ {SMP_PROC_REL_DELAY_TOUT, SMP_SM_NO_ACTION, SMP_ST_IDLE}
+/* RELEASE_DELAY_TOUT*/ {SMP_PROC_REL_DELAY_TOUT, SMP_SM_NO_ACTION, SMP_ST_IDLE},
+/* L2C_DISC*/ {SMP_DELAY_TERMINATE, SMP_SM_NO_ACTION, SMP_ST_IDLE}
};
@@ -445,7 +448,7 @@
/* lookup entry /w event & curr_state */
/* If entry is ignore, return.
* Otherwise, get state table (according to curr_state or all_state) */
- if ( (entry = entry_table[event - 1][curr_state]) != SMP_SM_IGNORE )
+ if ((event < SMP_MAX_EVT) && ( (entry = entry_table[event - 1][curr_state]) != SMP_SM_IGNORE ))
{
if (entry & SMP_ALL_TBL_MASK)
{