Merge BT 4.1 features
The features include:
- LE Peripheral Mode
- Link Layer topology (LE Central & Peripheral Concurrency)
- Dual Mode Topology (Ability to choose LE transport when connecting with
other Dual Mode devices)
- Fast advertising Interval
- Limited Discovery Time Changes
- GAP Authentication and Lost Bond
- Dual Mode Addressing
- Common Profile and Service Error Code
- 32 bit UUIDs
Change-Id: Ic6701da4cf6aaa390ff2c8816b43157f36b7fb42
Conflicts:
stack/btu/btu_hcif.c
diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c
index 92bdded..3c56713 100644
--- a/bta/dm/bta_dm_act.c
+++ b/bta/dm/bta_dm_act.c
@@ -90,7 +90,7 @@
static char *bta_dm_get_remname(void);
static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result);
-static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr);
+static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr,tBT_TRANSPORT transport);
static void bta_dm_discover_device(BD_ADDR remote_bd_addr);
static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status );
@@ -517,6 +517,8 @@
{
UNUSED(p_tle);
UINT8 i;
+ tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
+
APPL_TRACE_EVENT0(" bta_dm_disable_timer_cback ");
@@ -524,8 +526,10 @@
{
for(i=0; i<bta_dm_cb.device_list.count; i++)
{
- btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr);
-
+#if (BLE_INCLUDED == TRUE)
+ transport = bta_dm_cb.device_list.peer_device[i].transport;
+#endif
+ btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, transport);
}
}
@@ -689,22 +693,25 @@
BTA_GATTC_CancelOpen(0, p_dev->bd_addr, FALSE);
#endif
- if (BTM_IsAclConnectionUp(p_dev->bd_addr))
+ if ( BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_LE) ||
+ BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_BR_EDR))
{
+ APPL_TRACE_DEBUG2("%s: ACL Up count %d", __FUNCTION__,bta_dm_cb.device_list.count);
/* Take the link down first, and mark the device for removal when disconnected */
- btm_remove_acl( p_dev->bd_addr) ;
for(i=0; i<bta_dm_cb.device_list.count; i++)
{
if(!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_dev->bd_addr))
- break;
- }
-
- if(i < bta_dm_cb.device_list.count)
- {
- bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
+ {
+ bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
+ btm_remove_acl( p_dev->bd_addr,bta_dm_cb.device_list.peer_device[i].transport);
+ APPL_TRACE_DEBUG2("%s:transport = %d", __FUNCTION__,
+ bta_dm_cb.device_list.peer_device[i].transport);
+ break;
+ }
}
}
+
else /* Ok to remove the device in application layer */
{
BTM_SecDeleteDevice(p_dev->bd_addr);
@@ -790,15 +797,23 @@
{
tBTA_DM_API_REMOVE_ACL *p_remove_acl = &p_data->remove_acl;
UINT8 index;
+ tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
APPL_TRACE_DEBUG0("bta_dm_close_acl");
- if (BTM_IsAclConnectionUp(p_remove_acl->bd_addr))
+ if ( BTM_IsAclConnectionUp(p_remove_acl->bd_addr, BT_TRANSPORT_LE) ||
+ BTM_IsAclConnectionUp(p_remove_acl->bd_addr, BT_TRANSPORT_BR_EDR))
+
{
for (index = 0; index < bta_dm_cb.device_list.count; index ++)
{
if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, p_remove_acl->bd_addr))
+ {
+#if defined (BLE_INCLUDED) && (BLE_INCLUDED == TRUE)
+ transport = bta_dm_cb.device_list.peer_device[index].transport;
+#endif
break;
+ }
}
if (index != bta_dm_cb.device_list.count)
{
@@ -810,7 +825,7 @@
APPL_TRACE_ERROR0("unknown device, remove ACL failed");
}
/* Disconnect the ACL link */
- btm_remove_acl(p_remove_acl->bd_addr);
+ btm_remove_acl(p_remove_acl->bd_addr, transport);
}
/* if to remove the device from security database ? do it now */
else if (p_remove_acl->remove_dev)
@@ -845,7 +860,11 @@
tBTA_DM_SEC sec_event;
char *p_name;
- status = BTM_SecBond ( p_data->bond.bd_addr, 0, NULL, 0 );
+ if (p_data->bond.transport == BTA_TRANSPORT_UNKNOWN)
+ status = BTM_SecBond ( p_data->bond.bd_addr, 0, NULL, 0 );
+ else
+ status = BTM_SecBondByTransport ( p_data->bond.bd_addr, p_data->bond.transport, 0, NULL, 0 );
+
if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED))
{
@@ -1335,6 +1354,7 @@
bta_dm_search_cb.peer_name[0] = 0;
bta_dm_search_cb.sdp_search = p_data->discover.sdp_search;
bta_dm_search_cb.p_btm_inq_info = BTM_InqDbRead (p_data->discover.bd_addr);
+ bta_dm_search_cb.transport = p_data->discover.transport;
bta_dm_search_cb.name_discover_done = FALSE;
memcpy(&bta_dm_search_cb.uuid, &p_data->discover.uuid, sizeof(tSDP_UUID));
@@ -1502,7 +1522,7 @@
** Returns TRUE if started to get remote name
**
*******************************************************************************/
-static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr)
+static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr,tBT_TRANSPORT transport)
{
tBTM_STATUS btm_status;
@@ -1512,7 +1532,8 @@
bta_dm_search_cb.peer_name[0] = 0;
btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
- (tBTM_CMPL_CB *) bta_dm_remname_cback);
+ (tBTM_CMPL_CB *) bta_dm_remname_cback,
+ transport);
if ( btm_status == BTM_CMD_STARTED )
{
@@ -2384,6 +2405,21 @@
static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
{
tBTA_DM_MSG * p_msg;
+ tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
+#if BLE_INCLUDED == TRUE
+ tBT_DEVICE_TYPE dev_type;
+ tBLE_ADDR_TYPE addr_type;
+
+ if (bta_dm_search_cb.transport == BTA_TRANSPORT_UNKNOWN)
+ {
+ BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type);
+ if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM )
+ transport = BT_TRANSPORT_LE;
+ }
+ else
+ transport = bta_dm_search_cb.transport;
+#endif
+
APPL_TRACE_DEBUG6("bta_dm_discover_device, BDA:0x%02X%02X%02X%02X%02X%02X",
remote_bd_addr[0],remote_bd_addr[1],
@@ -2408,7 +2444,7 @@
&& (( bta_dm_search_cb.p_btm_inq_info == NULL )
||(bta_dm_search_cb.p_btm_inq_info && (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name))))
{
- if( bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr) == TRUE )
+ if(bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr, transport) == TRUE)
{
return;
}
@@ -2447,7 +2483,7 @@
/* check whether connection already exists to the device
if connection exists, we don't have to wait for ACL
link to go down to start search on next device */
- if(BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr))
+ if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr, BT_TRANSPORT_BR_EDR))
bta_dm_search_cb.wait_disc = FALSE;
else
bta_dm_search_cb.wait_disc = TRUE;
@@ -2461,8 +2497,7 @@
bta_dm_search_cb.services_to_search
);
}
- if (BTM_UseLeLink(bta_dm_search_cb.peer_bdaddr))
- /*
+ if (transport == BT_TRANSPORT_LE) /*
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 &&
(bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK))*/
@@ -2560,7 +2595,7 @@
result.inq_res.ble_addr_type = p_inq->ble_addr_type;
result.inq_res.inq_result_type = p_inq->inq_result_type;
result.inq_res.device_type = p_inq->device_type;
-
+ result.inq_res.flag = p_inq->flag;
#endif
/* application will parse EIR to find out remote device name */
@@ -2650,7 +2685,8 @@
{
/* get name of device */
btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
- (tBTM_CMPL_CB *) bta_dm_remname_cback);
+ (tBTM_CMPL_CB *) bta_dm_remname_cback,
+ BT_TRANSPORT_BR_EDR);
if ( btm_status == BTM_BUSY )
{
/* wait for next chance(notification of remote name discovery done) */
@@ -2692,9 +2728,12 @@
bta_dm_search_cb.peer_name[BD_NAME_LEN]=0;
BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
+
#if BLE_INCLUDED == TRUE
- if (BTM_UseLeLink(bta_dm_search_cb.peer_bdaddr))
- GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr);
+ if (bta_dm_search_cb.transport == BT_TRANSPORT_LE )
+ {
+ GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr);
+ }
#endif
if ((p_msg = (tBTA_DM_REM_NAME *) GKI_getbuf(sizeof(tBTA_DM_REM_NAME))) != NULL)
{
@@ -2857,7 +2896,7 @@
bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT;
bdcpy(bta_dm_cb.pin_bd_addr, bd_addr);
BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class);
- if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback)) == BTM_CMD_STARTED)
+ if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
return BTM_CMD_STARTED;
APPL_TRACE_WARNING0(" bta_dm_pin_cback() -> Failed to start Remote Name Request ");
@@ -3045,22 +3084,56 @@
/*case BTM_SP_KEY_REQ_EVT: */
case BTM_SP_KEY_NOTIF_EVT:
#endif
- bta_dm_cb.num_val = sec_event.key_notif.passkey = p_data->key_notif.passkey;
- /* If the device name is not known, save bdaddr and devclass and initiate a name request */
- if (p_data->key_notif.bd_name[0] == 0)
+ if(BTM_SP_CFM_REQ_EVT == event)
{
- bta_dm_cb.pin_evt = pin_evt;
- bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr);
- BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class);
- if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback)) == BTM_CMD_STARTED)
- return BTM_CMD_STARTED;
-
- APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
+ /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
+ call remote name request using values from cfm_req */
+ if(p_data->cfm_req.bd_name[0] == 0)
+ {
+ bta_dm_cb.pin_evt = pin_evt;
+ bdcpy(bta_dm_cb.pin_bd_addr, p_data->cfm_req.bd_addr);
+ BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->cfm_req.dev_class);
+ if ((BTM_ReadRemoteDeviceName(p_data->cfm_req.bd_addr, bta_dm_pinname_cback,
+ BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
+ return BTM_CMD_STARTED;
+ APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
+ }
+ else
+ {
+ /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
+ copy these values into key_notif from cfm_req */
+ bdcpy(sec_event.key_notif.bd_addr, p_data->cfm_req.bd_addr);
+ BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->cfm_req.dev_class);
+ BCM_STRNCPY_S((char*)sec_event.key_notif.bd_name, sizeof(BD_NAME),
+ (char*)p_data->cfm_req.bd_name, (BD_NAME_LEN-1));
+ sec_event.key_notif.bd_name[BD_NAME_LEN-1] = 0;
+ }
}
- bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
- BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
- BCM_STRNCPY_S((char*)sec_event.key_notif.bd_name, sizeof(BD_NAME), (char*)p_data->key_notif.bd_name, (BD_NAME_LEN-1));
- sec_event.key_notif.bd_name[BD_NAME_LEN-1] = 0;
+
+ bta_dm_cb.num_val = sec_event.key_notif.passkey = p_data->key_notif.passkey;
+ if (BTM_SP_KEY_NOTIF_EVT == event)
+ {
+ /* If the device name is not known, save bdaddr and devclass
+ and initiate a name request with values from key_notif */
+ if(p_data->key_notif.bd_name[0] == 0)
+ {
+ bta_dm_cb.pin_evt = pin_evt;
+ bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr);
+ BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class);
+ if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback,
+ BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
+ return BTM_CMD_STARTED;
+ APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
+ }
+ else
+ {
+ bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
+ BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
+ BCM_STRNCPY_S((char*)sec_event.key_notif.bd_name, sizeof(BD_NAME),
+ (char*)p_data->key_notif.bd_name, (BD_NAME_LEN-1));
+ sec_event.key_notif.bd_name[BD_NAME_LEN-1] = 0;
+ }
+ }
bta_dm_cb.p_sec_cback(pin_evt, &sec_event);
@@ -3076,17 +3149,18 @@
/* If the device name is not known, save bdaddr and devclass and initiate a name request */
if (p_data->rmt_oob.bd_name[0] == 0)
{
- bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT;
- bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr);
- BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->rmt_oob.dev_class);
- if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, bta_dm_pinname_cback)) == BTM_CMD_STARTED)
- return BTM_CMD_STARTED;
+ bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT;
+ bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr);
+ BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->rmt_oob.dev_class);
+ if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, bta_dm_pinname_cback,
+ BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
+ return BTM_CMD_STARTED;
+ APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
+ }
- APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
- }
- bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
- BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class);
- BCM_STRNCPY_S((char*)sec_event.rmt_oob.bd_name, sizeof(BD_NAME), (char*)p_data->rmt_oob.bd_name, (BD_NAME_LEN-1));
+ bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
+ BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class);
+ BCM_STRNCPY_S((char*)sec_event.rmt_oob.bd_name, sizeof(BD_NAME), (char*)p_data->rmt_oob.bd_name, (BD_NAME_LEN-1));
sec_event.rmt_oob.bd_name[BD_NAME_LEN-1] = 0;
bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event);
@@ -3228,9 +3302,17 @@
case BTM_BL_CONN_EVT:
p_msg->is_new = TRUE;
bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
+#if BLE_INCLUDED == TRUE
+ p_msg->transport = p_data->conn.transport;
+ p_msg->handle = p_data->conn.handle;
+#endif
break;
case BTM_BL_DISCN_EVT:
bdcpy(p_msg->bd_addr, p_data->discn.p_bda);
+#if BLE_INCLUDED == TRUE
+ p_msg->transport = p_data->discn.transport;
+ p_msg->handle = p_data->discn.handle;
+#endif
break;
case BTM_BL_UPDATE_EVT:
p_msg->busy_level = p_data->update.busy_level;
@@ -3241,9 +3323,9 @@
p_msg->hci_status = p_data->role_chg.hci_status;
bdcpy(p_msg->bd_addr, p_data->role_chg.p_bda);
break;
- case BTM_BL_COLLISION_EVT:
- bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
- break;;
+ case BTM_BL_COLLISION_EVT:
+ bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
+ break;
}
p_msg->hdr.event = BTA_DM_ACL_CHANGE_EVT;
@@ -3265,7 +3347,8 @@
**
*******************************************************************************/
static void bta_dm_acl_change_cback (BD_ADDR p_bda, DEV_CLASS p_dc, BD_NAME p_bdn,
- UINT8 *features, BOOLEAN is_new)
+ UINT8 *features, BOOLEAN is_new,UINT16 handle,
+ tBT_TRANSPORT transport)
{
tBTA_DM_ACL_CHANGE * p_msg;
@@ -3274,7 +3357,10 @@
{
bdcpy (p_msg->bd_addr, p_bda);
p_msg->is_new = is_new;
-
+#if BLE_INCLUDED == TRUE
+ p_msg->handle = handle;
+ p_msg->transport = transport;
+#endif
/* This is collision case */
if (features != NULL)
{
@@ -3387,6 +3473,7 @@
#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
tBTA_DM_PEER_DEVICE *p_dev;
+ memset(&conn, 0, sizeof(tBTA_DM_SEC));
switch(p_data->acl_change.event)
{
@@ -3438,7 +3525,7 @@
bdcpy(conn.role_chg.bd_addr, p_bda);
conn.role_chg.new_role = (UINT8) p_data->acl_change.new_role;
if( bta_dm_cb.p_sec_cback )
- bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, &conn);
+ bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, (tBTA_DM_SEC *)&conn);
}
return;
}
@@ -3455,7 +3542,11 @@
{
for(i=0; i<bta_dm_cb.device_list.count; i++)
{
- if(!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda))
+ if (!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
+#if BLE_INCLUDED == TRUE
+ && bta_dm_cb.device_list.peer_device[i].conn_handle == p_data->acl_change.handle
+#endif
+ )
break;
}
@@ -3465,14 +3556,24 @@
bdcpy(bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].peer_bdaddr, p_bda);
bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].link_policy = bta_dm_cb.cur_policy;
bta_dm_cb.device_list.count++;
+#if BLE_INCLUDED == TRUE
+ bta_dm_cb.device_list.peer_device[i].conn_handle = p_data->acl_change.handle;
+ if (p_data->acl_change.transport == BT_TRANSPORT_LE)
+ bta_dm_cb.device_list.le_count++;
+#endif
}
bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_CONNECTED;
bta_dm_cb.device_list.peer_device[i].pref_role = BTA_ANY_ROLE;
bdcpy(conn.link_up.bd_addr, p_bda);
bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_NONE;
- if( ((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
- ((NULL != (p = BTM_ReadRemoteFeatures (p_bda))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) )
+#if BLE_INCLUDED == TRUE
+ conn.link_up.link_type = p_data->acl_change.transport;
+ bta_dm_cb.device_list.peer_device[i].transport = p_data->acl_change.transport;
+#endif
+
+ if (((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
+ ((NULL != (p = BTM_ReadRemoteFeatures (p_bda))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)))
{
/* both local and remote devices support SSR */
bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_USE_SSR;
@@ -3486,17 +3587,23 @@
{
for(i=0; i<bta_dm_cb.device_list.count; i++)
{
- if(bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda))
+ if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
+#if BLE_INCLUDED == TRUE
+ ||bta_dm_cb.device_list.peer_device[i].transport != p_data->acl_change.transport
+#endif
+ )
continue;
if( bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING )
{
- BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr);
+ if (BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr))
+ {
#if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
- /* remove all cached GATT information */
- BTA_GATTC_Refresh(p_bda);
+ /* remove all cached GATT information */
+ BTA_GATTC_Refresh(p_bda);
#endif
- issue_unpair_cb = TRUE;
+ issue_unpair_cb = TRUE;
+ }
}
conn.link_down.is_removed = bta_dm_cb.device_list.peer_device[i].remove_dev_pending;
@@ -3509,6 +3616,12 @@
}
if(bta_dm_cb.device_list.count)
bta_dm_cb.device_list.count--;
+#if BLE_INCLUDED == TRUE
+ if ((p_data->acl_change.transport == BT_TRANSPORT_LE) &&
+ (bta_dm_cb.device_list.le_count))
+ bta_dm_cb.device_list.le_count--;
+ conn.link_down.link_type = p_data->acl_change.transport;
+#endif
if(bta_dm_search_cb.wait_disc && !bdcmp(bta_dm_search_cb.peer_bdaddr, p_bda))
{
@@ -3786,7 +3899,8 @@
static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
{
UINT16 index = 0;
- if (BTM_IsAclConnectionUp(remote_bd_addr))
+ if ( BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) ||
+ BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR))
{
APPL_TRACE_DEBUG1("%s ACL is not down. Schedule for Dev Removal when ACL closes",
__FUNCTION__);
@@ -3832,14 +3946,18 @@
UINT8 i;
BOOLEAN set_master_role = FALSE;
-
- if(bta_dm_cb.device_list.count)
+#if BLE_INCLUDED == TRUE
+ UINT8 br_count = bta_dm_cb.device_list.count - bta_dm_cb.device_list.le_count;
+#else
+ UINT8 br_count = bta_dm_cb.device_list.count;
+#endif
+ if (br_count)
{
/* the configuration is no scatternet
* or AV connection exists and there are more than one ACL link */
- if( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) ||
- (bta_dm_cb.cur_av_count && bta_dm_cb.device_list.count > 1) )
+ if ( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) ||
+ (bta_dm_cb.cur_av_count && br_count > 1) )
{
L2CA_SetDesireRole (HCI_ROLE_MASTER);
@@ -3849,7 +3967,11 @@
for(i=0; i<bta_dm_cb.device_list.count; i++)
{
- if(bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
+ if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED
+#if BLE_INCLUDED == TRUE
+ && bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_BR_EDR
+#endif
+ )
{
if(!set_master_role && (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_ANY_ROLE)
&& (p_bta_dm_rm_cfg[0].cfg == BTA_DM_PARTIAL_SCATTERNET))
@@ -3859,7 +3981,7 @@
}
if((bta_dm_cb.device_list.peer_device[i].pref_role == BTA_MASTER_ROLE_ONLY)
- || (bta_dm_cb.device_list.count > 1))
+ || (br_count > 1))
{
/* Initiating immediate role switch with certain remote devices
@@ -4509,13 +4631,26 @@
** Returns None
**
*******************************************************************************/
-void bta_dm_encrypt_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result)
+void bta_dm_encrypt_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result)
{
tBTA_STATUS bta_status = BTA_SUCCESS;
- tBTA_DM_ENCRYPT_CBACK *p_callback = bta_dm_cb.p_encrypt_cback;
+ tBTA_DM_ENCRYPT_CBACK *p_callback = NULL;
+ UINT8 i ;
UNUSED(p_ref_data);
- bta_dm_cb.p_encrypt_cback = NULL;
+ for (i=0; i<bta_dm_cb.device_list.count; i++)
+ {
+ if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, bd_addr) == 0 &&
+ bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
+ break;
+ }
+
+ if (i < bta_dm_cb.device_list.count)
+ {
+ p_callback = bta_dm_cb.device_list.peer_device[i].p_encrypt_cback;
+ bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = NULL;
+ }
+
switch (result)
{
case BTM_SUCCESS:
@@ -4538,7 +4673,7 @@
if (p_callback)
{
- (*p_callback)(bd_addr, bta_status);
+ (*p_callback)(bd_addr, transport, bta_status);
}
}
/*******************************************************************************
@@ -4552,6 +4687,7 @@
*******************************************************************************/
void bta_dm_set_encryption (tBTA_DM_MSG *p_data)
{
+ UINT8 i ;
APPL_TRACE_DEBUG0("bta_dm_set_encryption"); //todo
if (!p_data->set_encryption.p_callback)
@@ -4560,16 +4696,35 @@
return;
}
- if (bta_dm_cb.p_encrypt_cback)
+ for (i=0; i<bta_dm_cb.device_list.count; i++)
{
- (*p_data->set_encryption.p_callback)(p_data->set_encryption.bd_addr, BTA_BUSY);
- return;
+ if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_data->set_encryption.bd_addr) == 0 &&
+ bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
+ break;
}
+ if (i < bta_dm_cb.device_list.count)
+ {
+ if (bta_dm_cb.device_list.peer_device[i].p_encrypt_cback)
+ {
+ APPL_TRACE_ERROR0("earlier enc was not done for same device");
+ (*p_data->set_encryption.p_callback)(p_data->set_encryption.bd_addr,
+ p_data->set_encryption.transport, BTA_BUSY);
+ return;
+ }
-
- bta_dm_cb.p_encrypt_cback = p_data->set_encryption.p_callback;
- bta_dm_cb.sec_act = p_data->set_encryption.sec_act;
- BTM_SetEncryption(p_data->set_encryption.bd_addr, bta_dm_encrypt_cback, &bta_dm_cb.sec_act);
+ if (BTM_SetEncryption(p_data->set_encryption.bd_addr,
+ p_data->set_encryption.transport,
+ bta_dm_encrypt_cback,
+ &p_data->set_encryption.sec_act)
+ == BTM_CMD_STARTED)
+ {
+ bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = p_data->set_encryption.p_callback;
+ }
+ }
+ else
+ {
+ APPL_TRACE_ERROR1(" %s Device not found/not connected", __FUNCTION__);
+ }
}
/*******************************************************************************
@@ -4992,7 +5147,42 @@
BTM_BleSetConnScanParams(p_data->ble_set_scan_params.scan_int,
p_data->ble_set_scan_params.scan_window);
}
+/*******************************************************************************
+**
+** Function bta_dm_ble_update_conn_params
+**
+** Description This function update LE connection parameters.
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data)
+{
+ if (!L2CA_UpdateBleConnParams(p_data->ble_update_conn_params.bd_addr,
+ p_data->ble_update_conn_params.min_int,
+ p_data-> ble_update_conn_params.max_int,
+ p_data->ble_update_conn_params.latency,
+ p_data->ble_update_conn_params.timeout))
+ {
+ APPL_TRACE_ERROR0("Update connection parameters failed!");
+ }
+}
+#if BLE_PRIVACY_SPT == TRUE
+/*******************************************************************************
+**
+** Function bta_dm_ble_config_local_privacy
+**
+** Description This function set the local device LE privacy settings.
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data)
+{
+ BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable);
+}
+#endif
/*******************************************************************************
**
@@ -5311,7 +5501,7 @@
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);
+ BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE, BTA_GATT_TRANSPORT_LE);
}
/*******************************************************************************
diff --git a/bta/dm/bta_dm_api.c b/bta/dm/bta_dm_api.c
index 7db7f7b..89e2cce 100644
--- a/bta/dm/bta_dm_api.c
+++ b/bta/dm/bta_dm_api.c
@@ -526,12 +526,29 @@
*******************************************************************************/
void BTA_DmBond(BD_ADDR bd_addr)
{
+ BTA_DmBondByTransport (bd_addr, BTA_TRANSPORT_UNKNOWN);
+}
+
+/*******************************************************************************
+**
+** Function BTA_DmBondByTransports
+**
+** Description This function initiates a bonding procedure with a peer
+** device
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_DmBondByTransport(BD_ADDR bd_addr, tBTA_TRANSPORT transport)
+{
tBTA_DM_API_BOND *p_msg;
if ((p_msg = (tBTA_DM_API_BOND *) GKI_getbuf(sizeof(tBTA_DM_API_BOND))) != NULL)
{
p_msg->hdr.event = BTA_DM_API_BOND_EVT;
bdcpy(p_msg->bd_addr, bd_addr);
+ p_msg->transport = transport;
bta_sys_sendmsg(p_msg);
}
@@ -1487,6 +1504,9 @@
}
#endif
}
+/*******************************************************************************
+** BLE ADV data management API
+********************************************************************************/
#if BLE_INCLUDED == TRUE
/*******************************************************************************
@@ -1507,7 +1527,7 @@
if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *) GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL)
{
p_msg->hdr.event = BTA_DM_API_BLE_SET_ADV_CONFIG_EVT;
- p_msg->data_mask = data_mask;
+ p_msg->data_mask = data_mask;
p_msg->p_adv_cfg = p_adv_cfg;
bta_sys_sendmsg(p_msg);
@@ -1532,7 +1552,7 @@
if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *) GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL)
{
p_msg->hdr.event = BTA_DM_API_BLE_SET_SCAN_RSP_EVT;
- p_msg->data_mask = data_mask;
+ p_msg->data_mask = data_mask;
p_msg->p_adv_cfg = p_adv_cfg;
bta_sys_sendmsg(p_msg);
@@ -1599,28 +1619,24 @@
}
#endif
}
+
/*******************************************************************************
**
-** Function BTA_DmDiscoverExt
+** Function bta_dm_discover_send_msg
**
-** Description This function does service discovery for services of a
-** peer device. When services.num_uuid is 0, it indicates all
-** GATT based services are to be searched; other wise a list of
-** UUID of interested services should be provided through
-** p_services->p_uuid.
-**
-**
+** Description This function send discover message to BTA task.
**
** Returns void
**
*******************************************************************************/
-void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
- tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search)
+static void bta_dm_discover_send_msg(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
+ tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search,
+ tBTA_TRANSPORT transport)
{
-#if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
tBTA_DM_API_DISCOVER *p_msg;
- UINT16 len = p_services ? (sizeof(tBTA_DM_API_DISCOVER) + sizeof(tBT_UUID) * p_services->num_uuid) :
- sizeof(tBTA_DM_API_DISCOVER);
+ UINT16 len = p_services ? (sizeof(tBTA_DM_API_DISCOVER) +
+ sizeof(tBT_UUID) * p_services->num_uuid) :
+ sizeof(tBTA_DM_API_DISCOVER);
if ((p_msg = (tBTA_DM_API_DISCOVER *) GKI_getbuf(len)) != NULL)
{
@@ -1630,6 +1646,7 @@
bdcpy(p_msg->bd_addr, bd_addr);
p_msg->p_cback = p_cback;
p_msg->sdp_search = sdp_search;
+ p_msg->transport = transport;
if (p_services != NULL)
{
@@ -1645,12 +1662,60 @@
bta_sys_sendmsg(p_msg);
}
-#else
- UNUSED(bd_addr);
- UNUSED(p_services);
- UNUSED(p_cback);
- UNUSED(sdp_search);
-#endif
+}
+
+/*******************************************************************************
+**
+** Function BTA_DmDiscoverByTransport
+**
+** Description This function does service discovery on particular transport
+** for services of a
+** peer device. When services.num_uuid is 0, it indicates all
+** GATT based services are to be searched; otherwise a list of
+** UUID of interested services should be provided through
+** p_services->p_uuid.
+**
+** Parameters bd_addr: Bluetooth address of remote device
+** p_services :bit mask of the list of services to be discovered
+** p_cback : Callback on which result will be received
+** sdp_search: if TRUE SDP search will be initiated, else services present in
+** EIR structure of remote device will be returned.
+** transport : Physical transport BR/EDR or LE
+** Returns void
+**
+*******************************************************************************/
+
+void BTA_DmDiscoverByTransport(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
+ tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search,
+ tBTA_TRANSPORT transport)
+{
+ bta_dm_discover_send_msg(bd_addr, p_services, p_cback, sdp_search, transport);
+}
+
+
+/*******************************************************************************
+**
+** Function BTA_DmDiscoverExt
+**
+** Description This function does service discovery for services of a
+** peer device. When services.num_uuid is 0, it indicates all
+** GATT based services are to be searched; other wise a list of
+** UUID of interested services should be provided through
+** p_services->p_uuid.
+**
+** Parameters bd_addr: Bluetooth address of remote device
+** p_services :bit mask of the list of services to be discovered
+** p_cback : Callback on which result will be received
+** sdp_search: if TRUE SDP search will be initiated, else services present in
+** EIR structure of remote device will be returned.
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
+ tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search)
+{
+ bta_dm_discover_send_msg(bd_addr, p_services, p_cback, sdp_search, BTA_TRANSPORT_UNKNOWN);
}
@@ -1751,6 +1816,43 @@
/*******************************************************************************
**
+** Function BTA_DmBleUpdateConnectionParams
+**
+** Description Update connection parameters, can only be used when connection is up.
+**
+** Parameters: bd_addr - BD address of the peer
+** min_int - minimum connection interval, [0x0004~ 0x4000]
+** max_int - maximum connection interval, [0x0004~ 0x4000]
+** latency - slave latency [0 ~ 500]
+** timeout - supervision timeout [0x000a ~ 0xc80]
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, UINT16 max_int,
+ UINT16 latency, UINT16 timeout)
+{
+#if BLE_INCLUDED == TRUE
+ tBTA_DM_API_UPDATE_CONN_PARAM *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_UPDATE_CONN_PARAM *) GKI_getbuf(sizeof(tBTA_DM_API_UPDATE_CONN_PARAM))) != NULL)
+ {
+ memset (p_msg, 0, sizeof(tBTA_DM_API_UPDATE_CONN_PARAM));
+
+ p_msg->hdr.event = BTA_DM_API_UPDATE_CONN_PARAM_EVT;
+ bdcpy(p_msg->bd_addr, bd_addr);
+ p_msg->min_int = min_int;
+ p_msg->max_int = max_int;
+ p_msg->latency = latency;
+ p_msg->timeout = timeout;
+
+ bta_sys_sendmsg(p_msg);
+ }
+#endif
+}
+
+/*******************************************************************************
+**
** Function BTA_DmSetEncryption
**
** Description This function is called to ensure that connection is
@@ -1759,6 +1861,7 @@
** bring up unencrypted links, then later encrypt them.
**
** Parameters: bd_addr - Address of the peer device
+** transport - transport of the link to be encruypted
** p_callback - Pointer to callback function to indicat the
** link encryption status
** sec_act - This is the security action to indicate
@@ -1770,7 +1873,7 @@
** Returns void
**
*******************************************************************************/
-void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_DM_ENCRYPT_CBACK *p_callback,
+void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_DM_ENCRYPT_CBACK *p_callback,
tBTA_DM_BLE_SEC_ACT sec_act)
{
tBTA_DM_API_SET_ENCRYPTION *p_msg;
@@ -1783,6 +1886,7 @@
p_msg->hdr.event = BTA_DM_API_SET_ENCRYPTION_EVT;
memcpy(p_msg->bd_addr, bd_addr, BD_ADDR_LEN);
+ p_msg->transport = transport;
p_msg->p_callback = p_callback;
p_msg->sec_act = sec_act;
@@ -1803,7 +1907,7 @@
** Returns void
**
*******************************************************************************/
-void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev)
+void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev, tBTA_TRANSPORT transport)
{
tBTA_DM_API_REMOVE_ACL *p_msg;
@@ -1817,6 +1921,7 @@
memcpy(p_msg->bd_addr, bd_addr, BD_ADDR_LEN);
p_msg->remove_dev = remove_dev;
+ p_msg->transport = transport;
bta_sys_sendmsg(p_msg);
}
diff --git a/bta/dm/bta_dm_int.h b/bta/dm/bta_dm_int.h
index 784d49e..03cb45f 100644
--- a/bta/dm/bta_dm_int.h
+++ b/bta/dm/bta_dm_int.h
@@ -99,6 +99,7 @@
BTA_DM_API_BLE_CONN_PARAM_EVT,
BTA_DM_API_BLE_SCAN_PARAM_EVT,
BTA_DM_API_BLE_OBSERVE_EVT,
+ BTA_DM_API_UPDATE_CONN_PARAM_EVT,
BTA_DM_API_BLE_ADV_PARAM_EVT,
BTA_DM_API_BLE_SET_ADV_CONFIG_EVT,
BTA_DM_API_BLE_SET_SCAN_RSP_EVT,
@@ -214,6 +215,7 @@
tBTA_SERVICE_MASK services;
tBTA_DM_SEARCH_CBACK * p_cback;
BOOLEAN sdp_search;
+ tBTA_TRANSPORT transport;
#if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
UINT8 num_uuid;
tBT_UUID *p_uuid;
@@ -236,6 +238,7 @@
{
BT_HDR hdr;
BD_ADDR bd_addr;
+ tBTA_TRANSPORT transport;
} tBTA_DM_API_BOND;
/* data type for BTA_DM_API_BOND_CANCEL_EVT */
@@ -243,6 +246,7 @@
{
BT_HDR hdr;
BD_ADDR bd_addr;
+ tBTA_TRANSPORT transport;
} tBTA_DM_API_BOND_CANCEL;
/* data type for BTA_DM_API_PIN_REPLY_EVT */
@@ -370,6 +374,10 @@
UINT8 new_role;
BD_ADDR bd_addr;
UINT8 hci_status;
+#if BLE_INCLUDED == TRUE
+ UINT16 handle;
+ tBT_TRANSPORT transport;
+#endif
} tBTA_DM_ACL_CHANGE;
/* data type for BTA_DM_PM_BTM_STATUS_EVT */
@@ -429,6 +437,7 @@
typedef struct
{
BT_HDR hdr;
+ tBTA_TRANSPORT transport;
tBTA_DM_ENCRYPT_CBACK *p_callback;
tBTA_DM_BLE_SEC_ACT sec_act;
BD_ADDR bd_addr;
@@ -568,7 +577,18 @@
BT_HDR hdr;
BD_ADDR bd_addr;
BOOLEAN remove_dev;
+ tBTA_TRANSPORT transport;
+
}tBTA_DM_API_REMOVE_ACL;
+typedef struct
+{
+ BT_HDR hdr;
+ BD_ADDR bd_addr;
+ UINT16 min_int;
+ UINT16 max_int;
+ UINT16 latency;
+ UINT16 timeout;
+}tBTA_DM_API_UPDATE_CONN_PARAM;
#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
typedef struct
@@ -668,6 +688,7 @@
tBTA_DM_API_ENABLE_SCAN_FILTER ble_enable_scan_filter;
tBTA_DM_API_CFG_FILTER_COND ble_cfg_filter_cond;
#endif
+ tBTA_DM_API_UPDATE_CONN_PARAM ble_update_conn_params;
#endif
tBTA_DM_API_SET_AFH_CHANNEL_ASSESSMENT set_afh_channel_assessment;
@@ -707,13 +728,15 @@
tBTA_PREF_ROLES pref_role;
BOOLEAN in_use;
tBTA_DM_DEV_INFO info;
+ tBTA_DM_ENCRYPT_CBACK *p_encrypt_cback;
#if (BTM_SSR_INCLUDED == TRUE)
tBTM_PM_STATUS prev_low; /* previous low power mode used */
#endif
tBTA_DM_PM_ACTTION pm_mode_attempted;
tBTA_DM_PM_ACTTION pm_mode_failed;
BOOLEAN remove_dev_pending;
-
+ UINT16 conn_handle;
+ tBT_TRANSPORT transport;
} tBTA_DM_PEER_DEVICE;
@@ -724,7 +747,9 @@
{
tBTA_DM_PEER_DEVICE peer_device[BTA_DM_NUM_PEER_DEVICE];
UINT8 count;
-
+#if BLE_INCLUDED == TRUE
+ UINT8 le_count;
+#endif
} tBTA_DM_ACTIVE_LINK;
@@ -805,8 +830,6 @@
#endif
- tBTA_DM_ENCRYPT_CBACK *p_encrypt_cback;
- tBTA_DM_BLE_SEC_ACT sec_act;
TIMER_LIST_ENT switch_delay_timer;
} tBTA_DM_CB;
@@ -837,7 +860,7 @@
tSDP_UUID uuid;
UINT8 peer_scn;
BOOLEAN sdp_search;
-
+ tBTA_TRANSPORT transport;
#if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
tBTA_DM_SEARCH_CBACK * p_scan_cback;
#if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
@@ -1024,6 +1047,7 @@
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);
+extern void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data);
@@ -1068,6 +1092,10 @@
extern void bta_dm_disc_rmt_name (tBTA_DM_MSG *p_data);
extern tBTA_DM_PEER_DEVICE * bta_dm_find_peer_device(BD_ADDR peer_addr);
+#if BLE_PRIVACY_SPT == TRUE
+extern void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data);
+#endif
+
extern void bta_dm_pm_active(BD_ADDR peer_addr);
#if ( BTM_EIR_SERVER_INCLUDED == TRUE )
diff --git a/bta/dm/bta_dm_main.c b/bta/dm/bta_dm_main.c
index 74f4d82..8f8c750 100644
--- a/bta/dm/bta_dm_main.c
+++ b/bta/dm/bta_dm_main.c
@@ -96,6 +96,10 @@
bta_dm_ble_set_conn_params, /* BTA_DM_API_BLE_CONN_PARAM_EVT */
bta_dm_ble_set_scan_params, /* BTA_DM_API_BLE_SCAN_PARAM_EVT */
bta_dm_ble_observe,
+ bta_dm_ble_update_conn_params, /* BTA_DM_API_UPDATE_CONN_PARAM_EVT */
+#if BLE_PRIVACY_SPT == TRUE
+ bta_dm_ble_config_local_privacy, /* BTA_DM_API_LOCAL_PRIVACY_EVT */
+#endif
bta_dm_ble_set_adv_params, /* BTA_DM_API_BLE_SCAN_PARAM_EVT */
bta_dm_ble_set_adv_config, /* BTA_DM_API_BLE_SET_ADV_CONFIG_EVT */
bta_dm_ble_set_scan_rsp, /* BTA_DM_API_BLE_SET_SCAN_RSP_EVT */
diff --git a/bta/gatt/bta_gattc_act.c b/bta/gatt/bta_gattc_act.c
index 00e486f..fd0ac5b 100644
--- a/bta/gatt/bta_gattc_act.c
+++ b/bta/gatt/bta_gattc_act.c
@@ -45,7 +45,8 @@
** Constants
*****************************************************************************/
static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
- BOOLEAN connected, tGATT_DISCONN_REASON reason);
+ BOOLEAN connected, tGATT_DISCONN_REASON reason,
+ tBT_TRANSPORT transport);
static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
tGATT_CL_COMPLETE *p_data);
@@ -339,7 +340,8 @@
if (p_msg->api_conn.is_direct)
{
if ((p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if,
- p_msg->api_conn.remote_bda)) != NULL)
+ p_msg->api_conn.remote_bda,
+ p_msg->api_conn.transport)) != NULL)
{
bta_gattc_sm_execute(p_clcb, event, p_msg);
}
@@ -351,7 +353,7 @@
BTA_GATT_NO_RESOURCES,
p_msg->api_conn.remote_bda,
BTA_GATT_INVALID_CONN_ID,
- 0);
+ p_msg->api_conn.transport, 0);
}
}
else
@@ -385,7 +387,8 @@
if (p_msg->api_cancel_conn.is_direct)
{
if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_cancel_conn.client_if,
- p_msg->api_cancel_conn.remote_bda)) != NULL)
+ p_msg->api_cancel_conn.remote_bda,
+ BTA_GATT_TRANSPORT_LE)) != NULL)
{
bta_gattc_sm_execute(p_clcb, event, p_msg);
}
@@ -476,6 +479,7 @@
BTA_GATT_OK,
p_clcb->bda,
p_clcb->bta_conn_id,
+ p_clcb->transport,
0);
}
/*******************************************************************************
@@ -495,8 +499,8 @@
BTA_GATT_ERROR,
p_clcb->bda,
p_clcb->bta_conn_id,
+ p_clcb->transport,
0);
-
/* open failure, remove clcb */
bta_gattc_clcb_dealloc(p_clcb);
}
@@ -515,7 +519,8 @@
tBTA_GATTC_DATA gattc_data;
/* open/hold a connection */
- if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, TRUE))
+ if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda,
+ TRUE, p_data->api_conn.transport))
{
APPL_TRACE_ERROR0("Connection open failure");
@@ -526,7 +531,8 @@
/* a connected remote device */
if (GATT_GetConnIdIfConnected(p_clcb->p_rcb->client_if,
p_data->api_conn.remote_bda,
- &p_clcb->bta_conn_id))
+ &p_clcb->bta_conn_id,
+ p_data->api_conn.transport))
{
gattc_data.int_conn.hdr.layer_specific = p_clcb->bta_conn_id;
@@ -553,8 +559,8 @@
if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE, FALSE))
{
- /* alwaya call open to hold a connection */
- if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE))
+ /* always call open to hold a connection */
+ if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE, p_data->transport))
{
status = BTA_GATT_ERROR;
APPL_TRACE_ERROR0("bta_gattc_init_bk_conn failed");
@@ -566,9 +572,11 @@
/* if is a connected remote device */
if (GATT_GetConnIdIfConnected(p_data->client_if,
p_data->remote_bda,
- &conn_id))
+ &conn_id,
+ p_data->transport))
{
- if ((p_clcb = bta_gattc_find_alloc_clcb(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,
+ BTA_GATT_TRANSPORT_LE)) != NULL)
{
gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
@@ -583,7 +591,8 @@
/* open failure, report OPEN_EVT */
if (status != BTA_GATT_OK)
{
- bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda, BTA_GATT_INVALID_CONN_ID, 0);
+ bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda,
+ BTA_GATT_INVALID_CONN_ID, BTA_GATT_TRANSPORT_LE, 0);
}
}
/*******************************************************************************
@@ -687,7 +696,9 @@
{
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);
+
+ GATT_GetConnectionInfor(p_data->hdr.layer_specific,
+ &gatt_if, p_clcb->bda, &p_clcb->transport);
}
p_clcb->p_srcb->connected = TRUE;
@@ -721,14 +732,16 @@
if (p_clcb->p_rcb)
{
- /* there is no RM for GATT */
- if (!BTM_IsBleLink(p_clcb->bda))
- bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
- bta_gattc_send_open_cback(p_clcb->p_rcb,
- BTA_GATT_OK,
- p_clcb->bda,
- p_clcb->bta_conn_id,
- p_clcb->p_srcb->mtu);
+ /* there is no RM for GATT */
+ if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
+ bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
+
+ bta_gattc_send_open_cback(p_clcb->p_rcb,
+ BTA_GATT_OK,
+ p_clcb->bda,
+ p_clcb->bta_conn_id,
+ p_clcb->transport,
+ p_clcb->p_srcb->mtu);
}
}
/*******************************************************************************
@@ -780,7 +793,7 @@
cb_data.close.status = p_clcb->status;
bdcpy(cb_data.close.remote_bda, p_clcb->bda);
- if (!BTM_IsBleLink(p_clcb->bda))
+ if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
bta_sys_conn_close( BTA_ID_GATTC ,BTA_ALL_APP_ID, p_clcb->bda);
bta_gattc_clcb_dealloc(p_clcb);
@@ -948,12 +961,16 @@
p_clcb->p_srcb->update_count = 0;
p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT;
+ if (p_clcb->transport == BTA_TRANSPORT_LE)
+ L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, FALSE);
+
/* set all srcb related clcb into discovery ST */
bta_gattc_set_discover_st(p_clcb->p_srcb);
if ((p_clcb->status = bta_gattc_init_cache(p_clcb->p_srcb)) == BTA_GATT_OK)
{
- p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id, p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
+ p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id,
+ p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
}
if (p_clcb->status != BTA_GATT_OK)
{
@@ -993,7 +1010,8 @@
APPL_TRACE_DEBUG1("bta_gattc_disc_cmpl conn_id=%d",p_clcb->bta_conn_id);
#if BLE_INCLUDED == TRUE
- L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE);
+ if(p_clcb->transport == BTA_TRANSPORT_LE)
+ L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE);
#endif
p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
@@ -1255,11 +1273,14 @@
{
APPL_TRACE_ERROR1("bta_gattc_confirm to handle [0x%04x] failed", handle);
}
- /* if over BR_EDR, inform PM for mode change */
- else if (!BTM_IsBleLink(p_clcb->bda))
+ else
{
- 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);
+ /* if over BR_EDR, inform PM for mode change */
+ if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
+ {
+ 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);
+ }
}
}
}
@@ -1292,7 +1313,8 @@
&cb_data.read.descr_type) == FALSE)
{
cb_data.read.status = BTA_GATT_INTERNAL_ERROR;
- APPL_TRACE_ERROR1("can not map to GATT ID. handle = 0x%04x", p_data->p_cmpl->att_value.handle);
+ APPL_TRACE_ERROR1("can not map to GATT ID. handle = 0x%04x",
+ p_data->p_cmpl->att_value.handle);
}
else
{
@@ -1308,10 +1330,12 @@
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;
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));
+ 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.p_descr_type == NULL) ? 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);
@@ -1345,10 +1369,13 @@
}
else
{
- 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));
+ 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));
+ 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 &&
@@ -1629,7 +1656,8 @@
p_data->ci_load.status == BTA_GATT_MORE) &&
p_data->ci_load.num_attr > 0)
{
- bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr, p_data->ci_load.attr, p_clcb->p_srcb->attr_index);
+ bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr,
+ p_data->ci_load.attr, p_clcb->p_srcb->attr_index);
if (p_data->ci_load.status == BTA_GATT_OK)
{
@@ -1741,7 +1769,8 @@
**
*******************************************************************************/
static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
- BOOLEAN connected, tGATT_DISCONN_REASON reason)
+ BOOLEAN connected, tGATT_DISCONN_REASON reason,
+ tBT_TRANSPORT transport)
{
tBTA_GATTC_DATA *p_buf;
@@ -1752,11 +1781,13 @@
{
memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
- p_buf->int_conn.hdr.event = connected ? BTA_GATTC_INT_CONN_EVT: BTA_GATTC_INT_DISCONN_EVT;
+ 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;
+ p_buf->int_conn.transport = transport;
bdcpy(p_buf->int_conn.remote_bda, bda);
bta_sys_sendmsg(p_buf);
@@ -1777,7 +1808,7 @@
tBTA_GATTC_DATA *p_buf;
tBTA_GATTC_CLCB *p_clcb = NULL;
- if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda)) == NULL)
+ if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda, BTA_GATT_TRANSPORT_LE)) == NULL)
{
return;
}
@@ -1973,8 +2004,9 @@
tBTA_GATTC_NOTIFY notify;
BD_ADDR remote_bda;
tBTA_GATTC_IF gatt_if;
+ tBTA_TRANSPORT transport;
- if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda))
+ if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport))
{
APPL_TRACE_ERROR0("indication/notif for unknown app");
return;
@@ -2008,9 +2040,10 @@
/* connection not open yet */
if (p_clcb == NULL)
{
- if ((p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda)) != NULL)
+ if ((p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport)) != NULL)
{
p_clcb->bta_conn_id = conn_id;
+ p_clcb->transport = transport;
bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL);
}
@@ -2033,7 +2066,8 @@
}
else
{
- APPL_TRACE_ERROR1("Indi/Notif for Unknown handle[0x%04x], can not find in local cache.", handle);
+ APPL_TRACE_ERROR1("Indi/Notif for Unknown handle[0x%04x], can not find in local cache.",
+ handle);
}
}
/*******************************************************************************
@@ -2068,9 +2102,8 @@
return;
}
-
-/* if over BR_EDR, inform PM for mode change */
- if (!BTM_IsBleLink(p_clcb->bda))
+ /* if over BR_EDR, inform PM for mode change */
+ if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
{
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);
@@ -2112,14 +2145,14 @@
UINT16 conn_id;
/* should always get the connection ID */
- if (GATT_GetConnIdIfConnected(cif, remote_bda,&conn_id) == FALSE)
+ if (GATT_GetConnIdIfConnected(cif, remote_bda, &conn_id, BTA_GATT_TRANSPORT_LE) == FALSE)
{
APPL_TRACE_ERROR0("bta_gattc_init_clcb_conn ERROR: not a connected device");
return;
}
/* initaite a new connection here */
- if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda)) != NULL)
+ if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL)
{
gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
@@ -2153,7 +2186,7 @@
{
if (p_conn->in_use )
{
- if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda) == NULL)
+ if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda, BTA_GATT_TRANSPORT_LE) == NULL)
{
bta_gattc_init_clcb_conn(cif, p_conn->remote_bda);
}
@@ -2212,7 +2245,9 @@
/* if is a connected remote device */
if (L2CA_GetBleConnRole(p_msg->api_listen.remote_bda) == HCI_ROLE_SLAVE &&
- bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if, p_msg->api_listen.remote_bda) == NULL)
+ bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if,
+ p_msg->api_listen.remote_bda,
+ BTA_GATT_TRANSPORT_LE) == NULL)
{
bta_gattc_init_clcb_conn(p_msg->api_listen.client_if,
@@ -2223,7 +2258,8 @@
else
{
APPL_TRACE_ERROR0("Listen For All now");
- /* go through all connected device and send callback for all connected slave connection */
+ /* go through all connected device and send
+ callback for all connected slave connection */
bta_gattc_process_listen_all(p_msg->api_listen.client_if);
}
}
diff --git a/bta/gatt/bta_gattc_api.c b/bta/gatt/bta_gattc_api.c
index 0bc87ec..bfbaf63 100644
--- a/bta/gatt/bta_gattc_api.c
+++ b/bta/gatt/bta_gattc_api.c
@@ -143,11 +143,13 @@
** Parameters client_if: server interface.
** remote_bda: remote device BD address.
** is_direct: direct connection or background auto connection
+** transport: Transport to be used for GATT connection (BREDR/LE)
**
** Returns void
**
*******************************************************************************/
-void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_direct)
+void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
+ BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport)
{
tBTA_GATTC_API_OPEN *p_buf;
@@ -157,6 +159,7 @@
p_buf->client_if = client_if;
p_buf->is_direct = is_direct;
+ p_buf->transport = transport;
memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
diff --git a/bta/gatt/bta_gattc_cache.c b/bta/gatt/bta_gattc_cache.c
index 3d603c3..64147e2 100644
--- a/bta/gatt/bta_gattc_cache.c
+++ b/bta/gatt/bta_gattc_cache.c
@@ -460,12 +460,21 @@
** Returns status of the operation.
**
*******************************************************************************/
-tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type)
+tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb,
+ UINT8 disc_type)
{
- 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);
+ tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
+ tBTA_GATT_STATUS status = BTA_GATT_ERROR;
+
+ if (p_clcb)
+ {
+ if (p_clcb->transport == BTA_TRANSPORT_LE)
+ status = bta_gattc_discover_procedure(conn_id, p_server_cb, disc_type);
+ else
+ status = bta_gattc_sdp_service_disc(conn_id, p_server_cb);
+ }
+
+ return status;
}
/*******************************************************************************
**
@@ -476,7 +485,8 @@
** Returns status of the operation.
**
*******************************************************************************/
-tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type)
+tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb,
+ UINT8 disc_type)
{
tGATT_DISC_PARAM param;
BOOLEAN is_service = TRUE;
@@ -844,7 +854,7 @@
service_uuid.uu.uuid16, start_handle, end_handle);
#endif
- if (GATT_HANDLE_IS_VALID(start_handle) && GATT_HANDLE_IS_VALID(end_handle) &&
+ if (GATT_HANDLE_IS_VALID(start_handle) && GATT_HANDLE_IS_VALID(end_handle)&&
p_srvc_cb != NULL)
{
/* discover services result, add services into a service list */
@@ -856,7 +866,8 @@
}
else
{
- APPL_TRACE_ERROR2("invalid start_handle = %d end_handle = %d", start_handle, end_handle);
+ APPL_TRACE_ERROR2("invalid start_handle = %d end_handle = %d",
+ start_handle, end_handle);
}
}
@@ -904,9 +915,11 @@
attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
- SDP_InitDiscoveryDb (bta_gattc_cb.p_sdp_db, BTA_GATT_SDP_DB_SIZE, 1, &uuid, num_attrs, attr_list);
+ SDP_InitDiscoveryDb (bta_gattc_cb.p_sdp_db, BTA_GATT_SDP_DB_SIZE, 1,
+ &uuid, num_attrs, attr_list);
- if(!SDP_ServiceSearchAttributeRequest (p_server_cb->server_bda, bta_gattc_cb.p_sdp_db, &bta_gattc_sdp_callback))
+ if(!SDP_ServiceSearchAttributeRequest (p_server_cb->server_bda,
+ bta_gattc_cb.p_sdp_db, &bta_gattc_sdp_callback))
{
GKI_freebuf(bta_gattc_cb.p_sdp_db);
bta_gattc_cb.p_sdp_db = NULL;
@@ -990,7 +1003,8 @@
break;
case GATT_DISC_CHAR_DSCPT:
- bta_gattc_add_attr_to_cache(p_srvc_cb, p_data->handle, &p_data->type, 0, BTA_GATTC_ATTR_TYPE_CHAR_DESCR);
+ bta_gattc_add_attr_to_cache(p_srvc_cb, p_data->handle, &p_data->type, 0,
+ BTA_GATTC_ATTR_TYPE_CHAR_DESCR);
break;
}
}
@@ -1073,7 +1087,8 @@
{
#if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
APPL_TRACE_DEBUG5("\t Attr[0x%04x] handle[0x%04x] uuid[0x%04x] inst[%d] type[%d]",
- j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16, p_attr->inst_id, p_attr->attr_type);
+ j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16,
+ p_attr->inst_id, p_attr->attr_type);
#endif
bta_gattc_pack_attr_uuid(p_attr, &attr_uuid);
@@ -1120,7 +1135,7 @@
else /* another char */
{
#if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
- APPL_TRACE_DEBUG0("no matching descriptor found!! start of next characteristic");
+ APPL_TRACE_DEBUG0("no matching descptr found!!start of next characteristic");
#endif
char_map = FALSE;
done = TRUE;
@@ -1178,7 +1193,8 @@
{
#if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
APPL_TRACE_DEBUG5("\t Attr[0x%04x] handle[0x%04x] uuid[0x%04x] inst[%d] type[%d]",
- j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16, p_attr->inst_id, p_attr->attr_type);
+ j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16,
+ p_attr->inst_id, p_attr->attr_type);
#endif
if (p_attr->attr_type == BTA_GATTC_ATTR_TYPE_CHAR)
p_char = p_attr;
@@ -1199,7 +1215,7 @@
}
else
{
- APPL_TRACE_ERROR0("descriptor does not belong to any chracteristic, error");
+ APPL_TRACE_ERROR0("descptr does not belong to any chracteristic");
}
}
else
@@ -1249,7 +1265,8 @@
memset(&cb_data, 0, sizeof(tBTA_GATTC));
cb_data.srvc_res.conn_id = p_clcb->bta_conn_id;
- memcpy(&cb_data.srvc_res.service_uuid, &p_cache->service_uuid ,sizeof(tBTA_GATT_SRVC_ID));
+ memcpy(&cb_data.srvc_res.service_uuid, &p_cache->service_uuid,
+ sizeof(tBTA_GATT_SRVC_ID));
(* p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_RES_EVT, &cb_data);
}
@@ -1533,7 +1550,8 @@
**
*******************************************************************************/
void bta_gattc_fill_nv_attr(tBTA_GATTC_NV_ATTR *p_attr, UINT8 type, UINT16 s_handle,
- UINT16 e_handle, UINT8 id, tBT_UUID uuid, UINT8 prop, BOOLEAN is_primary)
+ UINT16 e_handle, UINT8 id, tBT_UUID uuid, UINT8 prop,
+ BOOLEAN is_primary)
{
p_attr->s_handle = s_handle;
p_attr->e_handle = e_handle;
diff --git a/bta/gatt/bta_gattc_int.h b/bta/gatt/bta_gattc_int.h
index 4f192cb..37a14c9 100644
--- a/bta/gatt/bta_gattc_int.h
+++ b/bta/gatt/bta_gattc_int.h
@@ -118,6 +118,7 @@
BD_ADDR remote_bda;
tBTA_GATTC_IF client_if;
BOOLEAN is_direct;
+ tBTA_TRANSPORT transport;
} tBTA_GATTC_API_OPEN;
typedef tBTA_GATTC_API_OPEN tBTA_GATTC_API_CANCEL_OPEN;
@@ -202,6 +203,7 @@
BD_ADDR remote_bda;
tBTA_GATTC_IF client_if;
UINT8 role;
+ tBT_TRANSPORT transport;
tGATT_DISCONN_REASON reason;
}tBTA_GATTC_INT_CONN;
@@ -366,9 +368,11 @@
{
UINT16 bta_conn_id; /* client channel ID, unique for clcb */
BD_ADDR bda;
+ tBTA_TRANSPORT transport; /* channel transport */
tBTA_GATTC_RCB *p_rcb; /* pointer to the registration CB */
tBTA_GATTC_SERV *p_srcb; /* server cache CB */
tBTA_GATTC_DATA *p_q_cmd; /* command in queue waiting for execution */
+ BOOLEAN buf_held;
#define BTA_GATTC_NO_SCHEDULE 0
#define BTA_GATTC_DISC_WAITING 0x01
@@ -444,7 +448,7 @@
** Function prototypes
*****************************************************************************/
extern BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg);
-extern void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data);
+extern BOOLEAN bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data);
/* function processed outside SM */
extern void bta_gattc_disable(tBTA_GATTC_CB *p_cb);
@@ -491,7 +495,7 @@
extern void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg);
extern void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data);
extern void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status,
- BD_ADDR remote_bda, UINT16 conn_id, UINT16 mtu);
+ BD_ADDR remote_bda, UINT16 conn_id, tBTA_TRANSPORT transport, UINT16 mtu);
extern void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg);
extern void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
#if BLE_INCLUDED == TRUE
@@ -499,11 +503,11 @@
extern void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg);
#endif
/* utility functions */
-extern tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda);
+extern tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
extern tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_conn_id (UINT16 conn_id);
-extern tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda);
+extern tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
extern void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb);
-extern tBTA_GATTC_CLCB * bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda);
+extern tBTA_GATTC_CLCB * bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
extern tBTA_GATTC_RCB * bta_gattc_cl_get_regcb(UINT8 client_if);
extern tBTA_GATTC_SERV * bta_gattc_find_srcb(BD_ADDR bda);
extern tBTA_GATTC_SERV * bta_gattc_srcb_alloc(BD_ADDR bda);
diff --git a/bta/gatt/bta_gattc_main.c b/bta/gatt/bta_gattc_main.c
index 932a1d7..c917d4a 100644
--- a/bta/gatt/bta_gattc_main.c
+++ b/bta/gatt/bta_gattc_main.c
@@ -288,14 +288,16 @@
** Description State machine event handling function for GATTC
**
**
-** Returns void
+** Returns BOOLEAN : TRUE if queued client request buffer can be immediately released
+** else FALSE
**
*******************************************************************************/
-void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data)
+BOOLEAN bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data)
{
tBTA_GATTC_ST_TBL state_table;
UINT8 action;
int i;
+ BOOLEAN rt = TRUE;
#if BTA_GATT_DEBUG == TRUE
tBTA_GATTC_STATE in_state = p_clcb->state;
UINT16 in_event = event;
@@ -320,6 +322,8 @@
if ((action = state_table[event][i]) != BTA_GATTC_IGNORE)
{
(*bta_gattc_action[action])(p_clcb, p_data);
+ p_clcb->buf_held = FALSE;
+ rt = FALSE;
}
else
{
@@ -336,6 +340,7 @@
gattc_evt_code(in_event));
}
#endif
+return rt;
}
/*******************************************************************************
@@ -345,7 +350,7 @@
** Description GATT client main event handling function.
**
**
-** Returns void
+** Returns BOOLEAN
**
*******************************************************************************/
BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
@@ -353,6 +358,7 @@
tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
tBTA_GATTC_CLCB *p_clcb = NULL;
tBTA_GATTC_RCB *p_clreg;
+ BOOLEAN rt = TRUE;
#if BTA_GATT_DEBUG == TRUE
APPL_TRACE_DEBUG1("bta_gattc_hdl_event: Event [%s]", gattc_evt_code(p_msg->event));
#endif
@@ -410,7 +416,7 @@
if (p_clcb != NULL)
{
- bta_gattc_sm_execute(p_clcb, p_msg->event, (tBTA_GATTC_DATA *) p_msg);
+ rt = bta_gattc_sm_execute(p_clcb, p_msg->event, (tBTA_GATTC_DATA *) p_msg);
}
else
{
@@ -421,7 +427,7 @@
}
- return(TRUE);
+ return rt;
}
diff --git a/bta/gatt/bta_gattc_utils.c b/bta/gatt/bta_gattc_utils.c
index b52e52c..99b222a 100644
--- a/bta/gatt/bta_gattc_utils.c
+++ b/bta/gatt/bta_gattc_utils.c
@@ -163,7 +163,8 @@
** Returns pointer to the clcb
**
*******************************************************************************/
-tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda)
+tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda,
+ tBTA_TRANSPORT transport)
{
tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
UINT8 i;
@@ -172,6 +173,7 @@
{
if (p_clcb->in_use &&
p_clcb->p_rcb->client_if == client_if &&
+ p_clcb->transport == transport &&
bdcmp(p_clcb->bda, remote_bda) == 0)
return p_clcb;
}
@@ -209,7 +211,8 @@
** Returns pointer to the clcb
**
*******************************************************************************/
-tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda)
+tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
+ tBTA_TRANSPORT transport)
{
UINT8 i_clcb = 0;
tBTA_GATTC_CLCB *p_clcb = NULL;
@@ -224,6 +227,7 @@
p_clcb = &bta_gattc_cb.clcb[i_clcb];
p_clcb->in_use = TRUE;
p_clcb->status = BTA_GATT_OK;
+ p_clcb->transport = transport;
bdcpy(p_clcb->bda, remote_bda);
p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if);
@@ -256,13 +260,14 @@
** Returns pointer to the clcb
**
*******************************************************************************/
-tBTA_GATTC_CLCB *bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda)
+tBTA_GATTC_CLCB *bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
+ tBTA_TRANSPORT transport)
{
tBTA_GATTC_CLCB *p_clcb ;
- if ((p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda)) == NULL)
+ if ((p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda, transport)) == NULL)
{
- p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda);
+ p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda, transport);
}
return p_clcb;
}
@@ -427,167 +432,19 @@
*******************************************************************************/
BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
- BOOLEAN in_q = FALSE;
- if (p_clcb->p_q_cmd == NULL && p_data)
- {
- UINT16 len;
- switch (p_data->hdr.event)
- {
- case BTA_GATTC_API_SEARCH_EVT:
- {
- if (p_data->api_search.p_srvc_uuid)
- {
- len = sizeof(tBTA_GATTC_API_SEARCH) + sizeof(tBT_UUID);
- }
- else
- {
- len = sizeof(tBTA_GATTC_API_SEARCH);
- }
- p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
- if (p_clcb->p_q_cmd == NULL)
- {
- APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
- return FALSE;
- }
- memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_SEARCH));
- if (p_data->api_search.p_srvc_uuid)
- {
- tBTA_GATTC_API_SEARCH *p_buf;
- p_buf = &(p_clcb->p_q_cmd->api_search);
- p_buf->p_srvc_uuid = (tBT_UUID *)(p_buf + 1);
- memcpy(p_buf->p_srvc_uuid, p_data->api_search.p_srvc_uuid,
- sizeof(tBT_UUID));
- }
- break;
- }
- case BTA_GATTC_API_READ_EVT:
- {
- if (p_data->api_read.p_descr_type)
- {
- len = sizeof(tBTA_GATT_ID) + sizeof(tBTA_GATTC_API_READ);
- }
- else
- {
- len = sizeof(tBTA_GATTC_API_READ);
- }
- p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
- if (p_clcb->p_q_cmd == NULL)
- {
- APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
- return FALSE;
- }
- memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_READ));
- if (p_data->api_read.p_descr_type)
- {
- tBTA_GATTC_API_READ *p_buf;
- p_buf = &(p_clcb->p_q_cmd->api_read);
- p_buf->p_descr_type = (tBTA_GATT_ID *)(p_buf + 1);
- memcpy(p_buf->p_descr_type, p_data->api_read.p_descr_type,
- sizeof(tBTA_GATT_ID));
- }
- break;
- }
- case BTA_GATTC_API_WRITE_EVT:
- {
- tBTA_GATTC_API_WRITE *p_buf;
- len = sizeof(tBTA_GATTC_API_WRITE) + p_data->api_write.len;
- if (p_data->api_write.p_descr_type)
- {
- len += sizeof(tBTA_GATT_ID);
- }
- p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
- if (p_clcb->p_q_cmd == NULL)
- {
- APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
- return FALSE;
- }
- memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_WRITE));
- p_buf = &(p_clcb->p_q_cmd->api_write);
- if (p_data->api_write.p_descr_type)
- {
- p_buf->p_descr_type = (tBTA_GATT_ID *)(p_buf + 1);
- memcpy(p_buf->p_descr_type, p_data->api_write.p_descr_type,
- sizeof(tBTA_GATT_ID));
- if (p_buf->len && p_buf->p_value)
- {
- p_buf->p_value = (UINT8 *)(p_buf->p_descr_type + 1);
- memcpy(p_buf->p_value, p_data->api_write.p_value,
- p_data->api_write.len);
- }
- }
- else if (p_buf->len && p_buf->p_value)
- {
- p_buf->p_value = (UINT8 *)(p_buf + 1);
- memcpy(p_buf->p_value, p_data->api_write.p_value,
- p_data->api_write.len);
- }
- break;
- }
- case BTA_GATTC_API_EXEC_EVT:
- {
- len = sizeof(tBTA_GATTC_API_EXEC);
- p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
- if (p_clcb->p_q_cmd == NULL)
- {
- APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
- return FALSE;
- }
- memcpy(p_clcb->p_q_cmd, p_data, len);
- break;
- }
- case BTA_GATTC_API_READ_MULTI_EVT:
- {
- len = sizeof(tBTA_GATTC_API_READ_MULTI) +
- p_data->api_read_multi.num_attr * sizeof(tBTA_GATTC_ATTR_ID);
- p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
- if (p_clcb->p_q_cmd == NULL)
- {
- APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
- return FALSE;
- }
- memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_READ_MULTI));
- if (p_data->api_read_multi.num_attr &&
- p_data->api_read_multi.p_id_list)
- {
- tBTA_GATTC_API_READ_MULTI *p_buf;
- p_buf = &(p_clcb->p_q_cmd->api_read_multi);
- p_buf->p_id_list = (tBTA_GATTC_ATTR_ID *)(p_buf + 1);
- memcpy(p_buf->p_id_list, p_data->api_read_multi.p_id_list,
- p_data->api_read_multi.num_attr * sizeof(tBTA_GATTC_ATTR_ID));
- }
- break;
- }
- case BTA_GATTC_API_CFG_MTU_EVT:
- {
- len = sizeof(tBTA_GATTC_API_CFG_MTU);
- p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
- if (p_clcb->p_q_cmd == NULL)
- {
- APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
- return FALSE;
- }
- memcpy(p_clcb->p_q_cmd, p_data, len);
- break;
- }
- default:
- APPL_TRACE_ERROR1("queue unsupported command %d", p_data->hdr.event);
- return FALSE;
- }
+ if (p_clcb->p_q_cmd == NULL)
+ {
+ p_clcb->p_q_cmd = p_data;
+ p_clcb->buf_held = TRUE;
+ }
+ else
+ {
+ APPL_TRACE_ERROR0("already has a pending command!!");
+ /* skip the callback now. ----- need to send callback ? */
+ }
+ return p_clcb->buf_held;
- in_q = TRUE;
- }
- else if (p_clcb->p_q_cmd)
- {
- APPL_TRACE_ERROR0("already has a pending command!!");
- /* skip the callback now. ----- need to send callback ? */
- }
- else
- {
- APPL_TRACE_ERROR0("queue a null command");
- }
-
- return in_q;
}
/*******************************************************************************
**
@@ -738,14 +595,16 @@
tBTA_GATTC_IF gatt_if;
tBTA_GATTC_RCB *p_clrcb ;
UINT8 i;
+ tGATT_TRANSPORT transport;
- if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda))
+ if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport))
{
if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL)
{
for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
{
- if (p_clrcb->notif_reg[i].in_use && !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda))
+ if (p_clrcb->notif_reg[i].in_use &&
+ !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda))
memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
}
}
@@ -919,7 +778,8 @@
**
*******************************************************************************/
void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status,
- BD_ADDR remote_bda, UINT16 conn_id, UINT16 mtu)
+ BD_ADDR remote_bda, UINT16 conn_id,
+ tBTA_TRANSPORT transport, UINT16 mtu)
{
tBTA_GATTC cb_data;
@@ -931,6 +791,7 @@
cb_data.open.client_if = p_clreg->client_if;
cb_data.open.conn_id = conn_id;
cb_data.open.mtu = mtu;
+ cb_data.open.transport = transport;
bdcpy(cb_data.open.remote_bda, remote_bda);
(*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data);
@@ -1053,16 +914,19 @@
/* 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)
+ p_msg->int_conn.remote_bda,
+ p_msg->int_conn.transport)) == NULL)
{
/* for a background connection or listening connection */
- if (p_msg->int_conn.role == HCI_ROLE_SLAVE ||
+ 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);
+ p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if,
+ p_msg->int_conn.remote_bda,
+ p_msg->int_conn.transport);
}
}
return p_clcb;
@@ -1087,12 +951,13 @@
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);
+ p_msg->int_conn.remote_bda,
+ p_msg->int_conn.transport);
}
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);
+ APPL_TRACE_DEBUG1(" disconnection ID: [%d] not used by BTA",
+ p_msg->int_conn.hdr.layer_specific);
}
return p_clcb;
}
diff --git a/bta/gatt/bta_gatts_act.c b/bta/gatt/bta_gatts_act.c
index be03655..4a24d66 100644
--- a/bta/gatt/bta_gatts_act.c
+++ b/bta/gatt/bta_gatts_act.c
@@ -37,9 +37,12 @@
#include <string.h>
static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
-static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp);
+static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req,
+ tGATTS_SRV_CHG_RSP *p_rsp);
-static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason);
+static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
+ BOOLEAN connected, tGATT_DISCONN_REASON reason,
+ tGATT_TRANSPORT transport);
static void bta_gatts_send_request_cback (UINT16 conn_id,
UINT32 trans_id,
tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data);
@@ -85,7 +88,8 @@
** Returns none.
**
*******************************************************************************/
-static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp)
+static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,
+ tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp)
{
return bta_gatts_co_srv_chg((tBTA_GATTS_SRV_CHG_CMD) cmd,
(tBTA_GATTS_SRV_CHG_REQ *) p_req,
@@ -223,14 +227,16 @@
p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback;
memcpy(&p_cb->rcb[first_unuse].app_uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
cb_data.reg_oper.server_if =
- p_cb->rcb[first_unuse].gatt_if = GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback);
+ p_cb->rcb[first_unuse].gatt_if =
+ GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback);
if ( !p_cb->rcb[first_unuse].gatt_if)
{
status = BTA_GATT_NO_RESOURCES;
}
else
{
- if ((p_buf = (tBTA_GATTS_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTS_INT_START_IF))) != NULL)
+ if ((p_buf =
+ (tBTA_GATTS_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTS_INT_START_IF))) != NULL)
{
p_buf->hdr.event = BTA_GATTS_INT_START_IF_EVT;
p_buf->server_if = p_cb->rcb[first_unuse].gatt_if;
@@ -275,7 +281,8 @@
}
else
{
- APPL_TRACE_ERROR1("Unable to start app.: Unknown interface =%d",p_msg->int_start_if.server_if );
+ APPL_TRACE_ERROR1("Unable to start app.: Unknown interface =%d",
+ p_msg->int_start_if.server_if );
}
}
/*******************************************************************************
@@ -358,7 +365,8 @@
if (service_id != 0)
{
- memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
+ memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid,
+ &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
p_cb->srvc_cb[srvc_idx].service_id = service_id;
p_cb->srvc_cb[srvc_idx].inst_num = p_msg->api_create_svc.inst;
p_cb->srvc_cb[srvc_idx].idx = srvc_idx;
@@ -617,11 +625,7 @@
**
** 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.
**
@@ -632,13 +636,14 @@
tBTA_GATT_STATUS status = BTA_GATT_ILLEGAL_PARAMETER;
tGATT_IF gatt_if;
BD_ADDR remote_bda;
-
+ tBTA_TRANSPORT transport;
p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id (p_cb, p_msg->api_indicate.attr_id);
if (p_srvc_cb )
{
- if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific, &gatt_if, remote_bda))
+ if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific,
+ &gatt_if, remote_bda, &transport))
{
if (p_msg->api_indicate.need_confirm)
@@ -653,7 +658,7 @@
p_msg->api_indicate.value);
/* if over BR_EDR, inform PM for mode change */
- if (!BTM_IsBleLink(remote_bda))
+ if (transport == BTA_TRANSPORT_BR_EDR)
{
bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
@@ -664,8 +669,7 @@
APPL_TRACE_ERROR1("Unknown connection ID: %d fail sending notification",
p_msg->api_indicate.hdr.layer_specific);
}
-
- if (status != GATT_SUCCESS && p_msg->api_indicate.need_confirm &&
+ if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) &&
p_cb->rcb[p_srvc_cb->rcb_idx].p_cback)
{
(*p_cb->rcb[p_srvc_cb->rcb_idx].p_cback)(BTA_GATTS_CONF_EVT, (tBTA_GATTS *)&status);
@@ -692,13 +696,22 @@
{
tBTA_GATTS_RCB *p_rcb=NULL;
tBTA_GATT_STATUS status= BTA_GATT_ERROR;
+ UINT16 conn_id;
UNUSED(p_cb);
if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if)) != NULL)
{
- if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda, p_msg->api_open.is_direct))
+ /* should always get the connection ID */
+ if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda,
+ p_msg->api_open.is_direct, p_msg->api_open.transport))
{
status = BTA_GATT_OK;
+
+ if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda,
+ &conn_id, p_msg->api_open.transport))
+ {
+ status = BTA_GATT_ALREADY_OPEN;
+ }
}
}
else
@@ -727,7 +740,8 @@
if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if)) != NULL)
{
- if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda, p_msg->api_cancel_open.is_direct))
+ if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda,
+ p_msg->api_cancel_open.is_direct))
{
APPL_TRACE_ERROR0("bta_gatts_cancel_open failed for open request");
}
@@ -759,9 +773,11 @@
tBTA_GATT_STATUS status= BTA_GATT_ERROR;
tGATT_IF gatt_if;
BD_ADDR remote_bda;
+ tBTA_GATT_TRANSPORT transport;
+
UNUSED(p_cb);
- if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda))
+ if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, &transport))
{
if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS)
{
@@ -776,7 +792,7 @@
if (p_rcb && p_rcb->p_cback)
{
- if (!BTM_IsBleLink(remote_bda))
+ if (transport == BTA_TRANSPORT_BR_EDR)
bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, remote_bda);
(*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT, (tBTA_GATTS *)&status);
@@ -840,19 +856,21 @@
tBTA_GATTS cb_data;
tBTA_GATTS_RCB *p_rcb;
tGATT_IF gatt_if;
+ tBTA_GATT_TRANSPORT transport;
memset(&cb_data, 0 , sizeof(tBTA_GATTS));
- if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda))
+ if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
{
p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
- APPL_TRACE_DEBUG3 ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d", conn_id, trans_id, req_type);
+ APPL_TRACE_DEBUG3 ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d",
+ conn_id, trans_id, req_type);
if (p_rcb && p_rcb->p_cback)
{
/* if over BR_EDR, inform PM for mode change */
- if (!BTM_IsBleLink(cb_data.req_data.remote_bda))
+ if (transport == BTA_TRANSPORT_BR_EDR)
{
bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
@@ -885,7 +903,8 @@
**
*******************************************************************************/
static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
- BOOLEAN connected, tGATT_DISCONN_REASON reason)
+ BOOLEAN connected, tGATT_DISCONN_REASON reason,
+ tGATT_TRANSPORT transport)
{
tBTA_GATTS cb_data;
UINT8 evt = connected ? BTA_GATTS_CONNECT_EVT: BTA_GATTS_DISCONNECT_EVT;
@@ -901,7 +920,7 @@
if (p_reg && p_reg->p_cback)
{
/* there is no RM for GATT */
- if (!BTM_IsBleLink(bda))
+ if (transport == BTA_TRANSPORT_BR_EDR)
{
if (connected)
bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda);
@@ -912,6 +931,7 @@
cb_data.conn.conn_id = conn_id;
cb_data.conn.server_if = gatt_if;
cb_data.conn.reason = reason;
+ cb_data.conn.transport = transport;
memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN);
(*p_reg->p_cback)(evt, &cb_data);
}
diff --git a/bta/gatt/bta_gatts_api.c b/bta/gatt/bta_gatts_api.c
index ad30d73..79eb6f9 100644
--- a/bta/gatt/bta_gatts_api.c
+++ b/bta/gatt/bta_gatts_api.c
@@ -464,11 +464,13 @@
** Parameters server_if: server interface.
** remote_bda: remote device BD address.
** is_direct: direct connection or background auto connection
+** transport : Transport on which GATT connection to be opened (BR/EDR or LE)
**
** Returns void
**
*******************************************************************************/
-void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct)
+void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct,
+ tBTA_GATT_TRANSPORT transport)
{
tBTA_GATTS_API_OPEN *p_buf;
@@ -477,6 +479,7 @@
p_buf->hdr.event = BTA_GATTS_API_OPEN_EVT;
p_buf->server_if = server_if;
p_buf->is_direct = is_direct;
+ p_buf->transport = transport;
memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
bta_sys_sendmsg(p_buf);
diff --git a/bta/gatt/bta_gatts_int.h b/bta/gatt/bta_gatts_int.h
index ce9553a..9a12dfd 100644
--- a/bta/gatt/bta_gatts_int.h
+++ b/bta/gatt/bta_gatts_int.h
@@ -139,10 +139,12 @@
typedef struct
{
- BT_HDR hdr;
- BD_ADDR remote_bda;
- tBTA_GATTS_IF server_if;
- BOOLEAN is_direct;
+ BT_HDR hdr;
+ BD_ADDR remote_bda;
+ tBTA_GATTS_IF server_if;
+ BOOLEAN is_direct;
+ tBTA_GATT_TRANSPORT transport;
+
}tBTA_GATTS_API_OPEN;
typedef tBTA_GATTS_API_OPEN tBTA_GATTS_API_CANCEL_OPEN;
diff --git a/bta/hh/bta_hh_le.c b/bta/hh/bta_hh_le.c
index 4f297ee..f2bba4a 100644
--- a/bta/hh/bta_hh_le.c
+++ b/bta/hh/bta_hh_le.c
@@ -347,7 +347,7 @@
bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;
p_cb->in_use = TRUE;
- BTA_GATTC_Open(bta_hh_cb.gatt_if, remote_bda, TRUE);
+ BTA_GATTC_Open(bta_hh_cb.gatt_if, remote_bda, TRUE, BTA_GATT_TRANSPORT_LE);
}
/*******************************************************************************
**
@@ -640,7 +640,8 @@
while (p_rpt != NULL)
{
- if (!p_rpt->in_use) break;
+ if(!p_rpt->in_use)
+ break;
if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT)
{
@@ -674,8 +675,6 @@
break;
}
}
- else
- break;
if (p_rpt->index == BTA_HH_LE_RPT_MAX - 1)
break;
@@ -1210,11 +1209,13 @@
** Returns None
**
*******************************************************************************/
-void bta_hh_le_encrypt_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result)
+void bta_hh_le_encrypt_cback(BD_ADDR bd_addr, tBTA_GATT_TRANSPORT transport,
+ void *p_ref_data, tBTM_STATUS result)
{
UINT8 idx = bta_hh_find_cb(bd_addr);
tBTA_HH_DEV_CB *p_dev_cb;
UNUSED(p_ref_data);
+ UNUSED (transport);
APPL_TRACE_ERROR0("bta_hh_le_encrypt_cback");
@@ -1315,7 +1316,7 @@
}
/* verify bond */
- BTM_GetSecurityFlags(p_cb->addr, &sec_flag);
+ BTM_GetSecurityFlagsByTransport(p_cb->addr, &sec_flag, BT_TRANSPORT_LE);
/* if link has been encrypted */
if (sec_flag & BTM_SEC_FLAG_ENCRYPTED)
@@ -1327,14 +1328,14 @@
{
sec_flag = BTM_BLE_SEC_ENCRYPT;
p_cb->status = BTA_HH_ERR_AUTH_FAILED;
- BTM_SetEncryption(p_cb->addr, bta_hh_le_encrypt_cback, &sec_flag);
+ BTM_SetEncryption(p_cb->addr, BTA_TRANSPORT_LE, bta_hh_le_encrypt_cback, &sec_flag);
}
/* unbonded device, report security error here */
else if (p_cb->sec_mask != BTA_SEC_NONE)
{
sec_flag = BTM_BLE_SEC_ENCRYPT_NO_MITM;
p_cb->status = BTA_HH_ERR_AUTH_FAILED;
- BTM_SetEncryption(p_cb->addr, bta_hh_le_encrypt_cback, &sec_flag);
+ BTM_SetEncryption(p_cb->addr, BTA_TRANSPORT_LE, bta_hh_le_encrypt_cback, &sec_flag);
}
/* otherwise let it go through */
else
@@ -2620,7 +2621,7 @@
!p_cb->in_bg_conn && to_add)
{
/* add device into BG connection to accept remote initiated connection */
- BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->addr, FALSE);
+ BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->addr, FALSE, BTA_GATT_TRANSPORT_LE);
p_cb->in_bg_conn = TRUE;
BTA_DmBleSetBgConnType(BTA_DM_BLE_CONN_AUTO, NULL);
diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h
index 86d9182..b8fcddc 100644
--- a/bta/include/bta_api.h
+++ b/bta/include/bta_api.h
@@ -200,7 +200,11 @@
// btla-specific ++
typedef UINT16 tBTA_DM_CONN;
-// btla-specific --
+
+#define BTA_TRANSPORT_UNKNOWN 0
+#define BTA_TRANSPORT_BR_EDR BT_TRANSPORT_BR_EDR
+#define BTA_TRANSPORT_LE BT_TRANSPORT_LE
+typedef tBT_TRANSPORT tBTA_TRANSPORT;
/* Pairable Modes */
#define BTA_DM_PAIRABLE 1
@@ -311,6 +315,8 @@
#define BTA_BLE_LIMIT_DISC_FLAG BTM_BLE_LIMIT_DISC_FLAG
#define BTA_BLE_GEN_DISC_FLAG BTM_BLE_GEN_DISC_FLAG
#define BTA_BLE_BREDR_NOT_SPT BTM_BLE_BREDR_NOT_SPT
+#define BTA_BLE_DMT_CONTROLLER_SPT BTM_BLE_DMT_CONTROLLER_SPT
+#define BTA_BLE_DMT_HOST_SPT BTM_BLE_DMT_HOST_SPT
#define BTA_BLE_NON_LIMIT_DISC_FLAG BTM_BLE_NON_LIMIT_DISC_FLAG
#define BTA_BLE_ADV_FLAG_MASK BTM_BLE_ADV_FLAG_MASK
#define BTA_BLE_LIMIT_DISC_MASK BTM_BLE_LIMIT_DISC_MASK
@@ -439,7 +445,9 @@
#define BTA_DM_BLE_PF_MANU_DATA BTM_BLE_PF_MANU_DATA
#define BTA_DM_BLE_PF_SRVC_DATA_PATTERN BTM_BLE_PF_SRVC_DATA_PATTERN
#define BTA_DM_BLE_PF_TYPE_MAX BTM_BLE_PF_TYPE_MAX
+#define BTA_DM_BLE_PF_SRVC_DATA BTM_BLE_PF_SRVC_DATA
#define BTA_DM_BLE_PF_TYPE_ALL BTM_BLE_PF_TYPE_ALL
+#define BTA_DM_BLE_PF_TYPE_MAX BTM_BLE_PF_TYPE_MAX
typedef UINT8 tBTA_DM_BLE_PF_COND_TYPE;
typedef union
@@ -541,6 +549,7 @@
/* Structure associated with BTA_DM_PIN_REQ_EVT */
typedef struct
{
+ /* Note: First 3 data members must be, bd_addr, dev_class, and bd_name in order */
BD_ADDR bd_addr; /* BD address peer device. */
DEV_CLASS dev_class; /* Class of Device */
BD_NAME bd_name; /* Name of peer device. */
@@ -674,6 +683,9 @@
typedef struct
{
BD_ADDR bd_addr; /* BD address peer device. */
+#if BLE_INCLUDED == TRUE
+ tBTA_TRANSPORT link_type;
+#endif
} tBTA_DM_LINK_UP;
/* Structure associated with BTA_DM_LINK_DOWN_EVT */
@@ -682,6 +694,9 @@
BD_ADDR bd_addr; /* BD address peer device. */
UINT8 status; /* connection open/closed */
BOOLEAN is_removed; /* TRUE if device is removed when link is down */
+#if BLE_INCLUDED == TRUE
+ tBTA_TRANSPORT link_type;
+#endif
} tBTA_DM_LINK_DOWN;
/* Structure associated with BTA_DM_ROLE_CHG_EVT */
@@ -859,6 +874,7 @@
UINT8 ble_addr_type;
tBTM_BLE_EVT_TYPE ble_evt_type;
tBT_DEVICE_TYPE device_type;
+ UINT8 flag;
#endif
} tBTA_DM_INQ_RES;
@@ -920,7 +936,7 @@
typedef void (tBTA_DM_EXEC_CBACK) (void * p_param);
/* Encryption callback*/
-typedef void (tBTA_DM_ENCRYPT_CBACK) (BD_ADDR bd_addr, tBTA_STATUS result);
+typedef void (tBTA_DM_ENCRYPT_CBACK) (BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_STATUS result);
#if BLE_INCLUDED == TRUE
#define BTA_DM_BLE_SEC_NONE BTM_BLE_SEC_NONE
@@ -980,13 +996,6 @@
#define BTA_DM_PM_PARK_IDX 5 /* the actual index to bta_dm_pm_md[] for PARK mode */
#endif
-#define BTA_DM_SW_BB_TO_MM BTM_SW_BB_TO_MM
-#define BTA_DM_SW_MM_TO_BB BTM_SW_MM_TO_BB
-#define BTA_DM_SW_BB_TO_BTC BTM_SW_BB_TO_BTC
-#define BTA_DM_SW_BTC_TO_BB BTM_SW_BTC_TO_BB
-
-typedef tBTM_SW_DIR tBTA_DM_SW_DIR;
-
/* Switch callback events */
#define BTA_DM_SWITCH_CMPL_EVT 0 /* Completion of the Switch API */
@@ -1023,6 +1032,12 @@
/* Device features mask definitions */
#define BTA_FEATURE_BYTES_PER_PAGE BTM_FEATURE_BYTES_PER_PAGE
#define BTA_EXT_FEATURES_PAGE_MAX BTM_EXT_FEATURES_PAGE_MAX
+/* ACL type
+*/
+#define BTA_DM_LINK_TYPE_BR_EDR 0x01
+#define BTA_DM_LINK_TYPE_LE 0x02
+#define BTA_DM_LINK_TYPE_ALL 0xFF
+typedef UINT8 tBTA_DM_LINK_TYPE;
/*****************************************************************************
** External Function Declarations
@@ -1274,6 +1289,21 @@
/*******************************************************************************
**
+** Function BTA_DmBondByTransport
+**
+** Description This function initiates a bonding procedure with a peer
+** device by designated transport. The bonding procedure enables
+** authentication and optionally encryption on the Bluetooth link.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBondByTransport(BD_ADDR bd_addr, tBTA_TRANSPORT transport);
+
+
+/*******************************************************************************
+**
** Function BTA_DmBondCancel
**
** Description This function cancels a bonding procedure with a peer
@@ -1596,11 +1626,13 @@
**
** Parameters: bd_addr - Address of the peer device
** remove_dev - remove device or not after link down
+** transport - which transport to close
+
**
** Returns void.
**
*******************************************************************************/
-BTA_API extern void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev);
+BTA_API extern void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev, tBTA_TRANSPORT transport);
/*******************************************************************************
**
@@ -1746,7 +1778,8 @@
** Returns void
**
*******************************************************************************/
-BTA_API extern void BTA_DmAddBleKey (BD_ADDR bd_addr, tBTA_LE_KEY_VALUE *p_le_key,
+BTA_API extern void BTA_DmAddBleKey (BD_ADDR bd_addr,
+ tBTA_LE_KEY_VALUE *p_le_key,
tBTA_LE_KEY_TYPE key_type);
/*******************************************************************************
@@ -1844,6 +1877,25 @@
BTA_API extern void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search);
+/*******************************************************************************
+**
+** Function BTA_DmDiscoverByTransport
+**
+** Description This function does service discovery on particular transport
+** for services of a
+** peer device. When services.num_uuid is 0, it indicates all
+** GATT based services are to be searched; other wise a list of
+** UUID of interested services should be provided through
+** p_services->p_uuid.
+**
+**
+**
+** Returns void
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmDiscoverByTransport(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
+ tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search,
+ tBTA_TRANSPORT transport);
/*******************************************************************************
**
@@ -1855,6 +1907,7 @@
** bring up unencrypted links, then later encrypt them.
**
** Parameters: bd_addr - Address of the peer device
+** transport - transport of the link to be encruypted
** p_callback - Pointer to callback function to indicat the
** link encryption status
** sec_act - This is the security action to indicate
@@ -1867,8 +1920,9 @@
**
**
*******************************************************************************/
-BTA_API extern void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_DM_ENCRYPT_CBACK *p_callback,
- tBTA_DM_BLE_SEC_ACT sec_act);
+BTA_API extern void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_TRANSPORT transport,
+ tBTA_DM_ENCRYPT_CBACK *p_callback,
+ tBTA_DM_BLE_SEC_ACT sec_act);
/*******************************************************************************
@@ -1974,6 +2028,23 @@
*******************************************************************************/
BTA_API extern void BTA_DmBleBroadcast (BOOLEAN start);
+/*******************************************************************************
+**
+** Function BTA_DmBleUpdateConnectionParams
+**
+** Description Update connection parameters, can only be used when connection is up.
+**
+** Parameters: bd_addr - BD address of the peer
+** min_int - minimum connection interval, [0x0004~ 0x4000]
+** max_int - maximum connection interval, [0x0004~ 0x4000]
+** latency - slave latency [0 ~ 500]
+** timeout - supervision timeout [0x000a ~ 0xc80]
+**
+** Returns void
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int,
+ UINT16 max_int, UINT16 latency, UINT16 timeout);
#endif
#ifdef __cplusplus
diff --git a/bta/include/bta_gatt_api.h b/bta/include/bta_gatt_api.h
index b53b180..3fec4a0 100644
--- a/bta/include/bta_gatt_api.h
+++ b/bta/include/bta_gatt_api.h
@@ -77,21 +77,32 @@
#define BTA_GATT_INSUF_RESOURCE GATT_INSUF_RESOURCE /* 0x0011 */
-#define BTA_GATT_ILLEGAL_PARAMETER GATT_ILLEGAL_PARAMETER /* 0x0087 */
-#define BTA_GATT_NO_RESOURCES GATT_NO_RESOURCES /* 0x0080 */
-#define BTA_GATT_INTERNAL_ERROR GATT_INTERNAL_ERROR /* 0x0081 */
-#define BTA_GATT_WRONG_STATE GATT_WRONG_STATE /* 0x0082 */
-#define BTA_GATT_DB_FULL GATT_DB_FULL /* 0x0083 */
-#define BTA_GATT_BUSY GATT_BUSY /* 0x0084 */
-#define BTA_GATT_ERROR GATT_ERROR /* 0x0085 */
-#define BTA_GATT_CMD_STARTED GATT_CMD_STARTED /* 0x0086 */
-#define BTA_GATT_PENDING GATT_PENDING /* 0x0088 */
-#define BTA_GATT_AUTH_FAIL GATT_AUTH_FAIL /* 0x0089 */
-#define BTA_GATT_MORE GATT_MORE /* 0x008a */
-#define BTA_GATT_INVALID_CFG GATT_INVALID_CFG /* 0x008b */
-#define BTA_GATT_DUP_REG 0x008c
-#define BTA_GATT_ALREADY_OPEN 0x008d /* 0x008d */
-#define BTA_GATT_CANCEL 0x008e /* 0x008e */
+#define BTA_GATT_NO_RESOURCES GATT_NO_RESOURCES /* 0x80 */
+#define BTA_GATT_INTERNAL_ERROR GATT_INTERNAL_ERROR /* 0x81 */
+#define BTA_GATT_WRONG_STATE GATT_WRONG_STATE /* 0x82 */
+#define BTA_GATT_DB_FULL GATT_DB_FULL /* 0x83 */
+#define BTA_GATT_BUSY GATT_BUSY /* 0x84 */
+#define BTA_GATT_ERROR GATT_ERROR /* 0x85 */
+#define BTA_GATT_CMD_STARTED GATT_CMD_STARTED /* 0x86 */
+#define BTA_GATT_ILLEGAL_PARAMETER GATT_ILLEGAL_PARAMETER /* 0x87 */
+#define BTA_GATT_PENDING GATT_PENDING /* 0x88 */
+#define BTA_GATT_AUTH_FAIL GATT_AUTH_FAIL /* 0x89 */
+#define BTA_GATT_MORE GATT_MORE /* 0x8a */
+#define BTA_GATT_INVALID_CFG GATT_INVALID_CFG /* 0x8b */
+#define BTA_GATT_SERVICE_STARTED GATT_SERVICE_STARTED /* 0x8c */
+#define BTA_GATT_ENCRYPED_MITM GATT_ENCRYPED_MITM /* GATT_SUCCESS */
+#define BTA_GATT_ENCRYPED_NO_MITM GATT_ENCRYPED_NO_MITM /* 0x8d */
+#define BTA_GATT_NOT_ENCRYPTED GATT_NOT_ENCRYPTED /* 0x8e */
+
+#define BTA_GATT_DUP_REG 0x8f /* 0x8f */
+#define BTA_GATT_ALREADY_OPEN 0x90 /* 0x90 */
+#define BTA_GATT_CANCEL 0x91 /* 0x91 */
+
+ /* 0xE0 ~ 0xFC reserved for future use */
+#define BTA_GATT_CCC_CFG_ERR GATT_CCC_CFG_ERR /* 0xFD Client Characteristic Configuration Descriptor Improperly Configured */
+#define BTA_GATT_PRC_IN_PROGRESS GATT_PRC_IN_PROGRESS /* 0xFE Procedure Already in progress */
+#define BTA_GATT_OUT_OF_RANGE GATT_OUT_OF_RANGE /* 0xFFAttribute value out of range */
+
typedef UINT8 tBTA_GATT_STATUS;
#define BTA_GATT_INVALID_CONN_ID GATT_INVALID_CONN_ID
@@ -325,6 +336,7 @@
UINT16 conn_id;
tBTA_GATTC_IF client_if;
BD_ADDR remote_bda;
+ tBTA_TRANSPORT transport;
UINT16 mtu;
}tBTA_GATTC_OPEN;
@@ -469,12 +481,9 @@
typedef tGATTS_SRV_CHG_REQ tBTA_GATTS_SRV_CHG_REQ;
typedef tGATTS_SRV_CHG_RSP tBTA_GATTS_SRV_CHG_RSP;
-enum
-{
- BTA_GATT_TRANSPORT_LE,
- BTA_GATT_TRANSPORT_BR_EDR,
- BTA_GATT_TRANSPORT_LE_BR_EDR
-};
+#define BTA_GATT_TRANSPORT_LE GATT_TRANSPORT_LE
+#define BTA_GATT_TRANSPORT_BR_EDR GATT_TRANSPORT_BR_EDR
+#define BTA_GATT_TRANSPORT_LE_BR_EDR GATT_TRANSPORT_LE_BR_EDR
typedef UINT8 tBTA_GATT_TRANSPORT;
/* attribute value */
@@ -552,6 +561,7 @@
BD_ADDR remote_bda;
UINT16 conn_id;
tBTA_GATT_REASON reason; /* report disconnect reason */
+ tBTA_GATT_TRANSPORT transport;
}tBTA_GATTS_CONN;
/* GATTS callback data */
@@ -560,7 +570,7 @@
tBTA_GATTS_REG_OPER reg_oper;
tBTA_GATTS_CREATE create;
tBTA_GATTS_SRVC_OPER srvc_oper;
- tBTA_GATT_STATUS status; /* BTA_GATTS_CONF_EVT */
+ tBTA_GATT_STATUS status; /* BTA_GATTS_CONF_EVT or BTA_GATTS_LISTEN_EVT */
tBTA_GATTS_ADD_RESULT add_result; /* add included service: BTA_GATTS_ADD_INCL_SRVC_EVT
add char : BTA_GATTS_ADD_CHAR_EVT
add char descriptor: BTA_GATTS_ADD_CHAR_DESCR_EVT */
@@ -644,7 +654,8 @@
** Returns void
**
*******************************************************************************/
-BTA_API extern void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_direct);
+BTA_API extern void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
+ BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport);
/*******************************************************************************
**
@@ -1301,7 +1312,8 @@
** Returns void
**
*******************************************************************************/
- BTA_API extern void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct);
+ BTA_API extern void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda,
+ BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport);
/*******************************************************************************
diff --git a/bta/jv/bta_jv_act.c b/bta/jv/bta_jv_act.c
index ab51071..0c8980b 100644
--- a/bta/jv/bta_jv_act.c
+++ b/bta/jv/bta_jv_act.c
@@ -886,7 +886,7 @@
{
BTM_ReadRemoteDeviceName(p_data->get_rmt_name.bd_addr,
- (tBTM_CMPL_CB *)bta_jv_get_remote_device_name_cback);
+ (tBTM_CMPL_CB *)bta_jv_get_remote_device_name_cback, BT_TRANSPORT_BR_EDR);
}
/*******************************************************************************
@@ -903,11 +903,16 @@
tBTA_UTL_COD cod;
/* set class of device */
- /* BTA_JvSetServiceClass(UINT32 service) assumes that the service class passed to the API function as defined in the assigned number page.
- For example: the object transfer bit is bit 20 of the 24-bit Class of device; the value of this bit is 0x00100000 (value 1)
- Our btm_api.h defines this bit as #define BTM_COD_SERVICE_OBJ_TRANSFER 0x1000 // (value 2)
- This reflects that the service class defined at btm is UINT16, which starts at bit 8 of the 24 bit Class of Device
- The following statement converts from (value 1) into (value 2) */
+ /*
+ BTA_JvSetServiceClass(UINT32 service) assumes that the service class passed to the
+ API function as defined in the assigned number page.
+ For example: the object transfer bit is bit 20 of the 24-bit Class of device;
+ the value of this bit is 0x00100000 (value 1)
+ Our btm_api.h defines this bit as #define BTM_COD_SERVICE_OBJ_TRANSFER 0x1000 (value 2)
+ This reflects that the service class defined at btm is UINT16,
+ which starts at bit 8 of the 24 bit Class of Device
+ The following statement converts from (value 1) into (value 2)
+ */
cod.service = (p_data->set_service.service >> 8);
utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
}
@@ -921,9 +926,11 @@
** Returns void
**
*******************************************************************************/
-static void bta_jv_sec_cback (BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result)
+static void bta_jv_sec_cback (BD_ADDR bd_addr, tBTA_TRANSPORT transport,
+ void *p_ref_data, tBTM_STATUS result)
{
UNUSED(p_ref_data);
+ UNUSED(transport);
tBTA_JV_SET_ENCRYPTION set_enc;
if(bta_jv_cb.p_dm_cback)
@@ -947,7 +954,7 @@
*******************************************************************************/
void bta_jv_set_encryption(tBTA_JV_MSG *p_data)
{
- BTM_SetEncryption(p_data->set_encrypt.bd_addr, bta_jv_sec_cback, NULL);
+ BTM_SetEncryption(p_data->set_encrypt.bd_addr, BTA_TRANSPORT_BR_EDR, bta_jv_sec_cback, NULL);
}
/*******************************************************************************
diff --git a/bta/jv/bta_jv_api.c b/bta/jv/bta_jv_api.c
index 16ab2d5..ad0b694 100644
--- a/bta/jv/bta_jv_api.c
+++ b/bta/jv/bta_jv_api.c
@@ -495,11 +495,13 @@
BOOLEAN BTA_JvIsEncrypted(BD_ADDR bd_addr)
{
BOOLEAN is_encrypted = FALSE;
- UINT8 sec_flags;
+ UINT8 sec_flags, le_flags;
- if(BTM_GetSecurityFlags(bd_addr, &sec_flags))
+ if (BTM_GetSecurityFlags(bd_addr, &sec_flags) &&
+ BTM_GetSecurityFlagsByTransport(bd_addr, &le_flags, BT_TRANSPORT_LE))
{
- if(sec_flags&BTM_SEC_FLAG_ENCRYPTED)
+ if(sec_flags & BTM_SEC_FLAG_ENCRYPTED ||
+ le_flags & BTM_SEC_FLAG_ENCRYPTED)
is_encrypted = TRUE;
}
return is_encrypted;
diff --git a/btif/include/btif_storage.h b/btif/include/btif_storage.h
index 9a69b00..f64c695 100644
--- a/btif/include/btif_storage.h
+++ b/btif/include/btif_storage.h
@@ -353,4 +353,34 @@
bt_status_t btif_storage_get_remote_version(const bt_bdaddr_t *remote_bd_addr,
bt_remote_version_t *p_ver);
+
+/*******************************************************************************
+**
+** Function btif_storage_set_dmt_support_type
+**
+** Description Sets DMT support status for a remote device
+**
+** Returns BT_STATUS_SUCCESS if config update is successful
+** BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+
+bt_status_t btif_storage_set_dmt_support_type(const bt_bdaddr_t *remote_bd_addr,
+ BOOLEAN dmt_supported);
+
+
+
+/*******************************************************************************
+**
+** Function btif_storage_is_dmt_supported_device
+**
+** Description checks if a device supports Dual mode topology
+**
+** Returns TRUE if remote supports DMT else FALSE
+**
+*******************************************************************************/
+
+BOOLEAN btif_storage_is_dmt_supported_device(const bt_bdaddr_t *remote_bd_addr);
+
+
#endif /* BTIF_STORAGE_H */
diff --git a/btif/src/bluetooth.c b/btif/src/bluetooth.c
index 44644de..fe4182f 100644
--- a/btif/src/bluetooth.c
+++ b/btif/src/bluetooth.c
@@ -327,7 +327,7 @@
if (is_profile(profile_id, BT_PROFILE_HEALTH_ID))
return btif_hl_get_interface();
-#if BTA_GATT_INCLUDED == TRUE
+#if ( BTA_GATT_INCLUDED == TRUE &&BLE_INCLUDED == TRUE)
if (is_profile(profile_id, BT_PROFILE_GATT_ID))
return btif_gatt_get_interface();
#endif
diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c
index e72a95e..40d21fd 100644
--- a/btif/src/btif_dm.c
+++ b/btif/src/btif_dm.c
@@ -1073,6 +1073,12 @@
ASSERTC(status == BT_STATUS_SUCCESS, "failed to save remote device (inquiry)", status);
#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
status = btif_storage_set_remote_addr_type(&bdaddr, addr_type);
+ if (( dev_type == BT_DEVICE_TYPE_DUMO)&&
+ (p_search_data->inq_res.flag & BTA_BLE_DMT_CONTROLLER_SPT) &&
+ (p_search_data->inq_res.flag & BTA_BLE_DMT_HOST_SPT))
+ {
+ btif_storage_set_dmt_support_type (&bdaddr, TRUE);
+ }
ASSERTC(status == BT_STATUS_SUCCESS, "failed to save remote addr type (inquiry)", status);
#endif
/* Callback to notify upper layer of device */
diff --git a/btif/src/btif_gatt_client.c b/btif/src/btif_gatt_client.c
index 59840af..3d6d097 100644
--- a/btif/src/btif_gatt_client.c
+++ b/btif/src/btif_gatt_client.c
@@ -141,7 +141,9 @@
uint8_t start;
uint8_t has_mask;
int8_t rssi;
+ uint8_t flag;
tBT_DEVICE_TYPE device_type;
+ btgatt_transport_t transport;
} __attribute__((packed)) btif_gattc_cb_t;
typedef struct
@@ -153,8 +155,8 @@
typedef struct
{
btif_gattc_dev_t remote_dev[BTIF_GATT_MAX_OBSERVED_DEV];
- uint8_t addr_type;
- uint8_t next_storage_idx;
+ uint8_t addr_type;
+ uint8_t next_storage_idx;
}__attribute__((packed)) btif_gattc_dev_cb_t;
/*******************************************************************************
@@ -482,6 +484,8 @@
btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*)p_param;
uint8_t remote_name_len;
uint8_t *p_eir_remote_name=NULL;
+ bt_device_type_t dev_type;
+ bt_property_t properties;
p_eir_remote_name = BTA_CheckEirData(p_btif_cb->value,
BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len);
@@ -506,6 +510,19 @@
}
}
+
+ if (( p_btif_cb->device_type == BT_DEVICE_TYPE_DUMO)&&
+ (p_btif_cb->flag & BTA_BLE_DMT_CONTROLLER_SPT) &&
+ (p_btif_cb->flag & BTA_BLE_DMT_HOST_SPT))
+ {
+ btif_storage_set_dmt_support_type (&(p_btif_cb->bd_addr), TRUE);
+ }
+
+ dev_type = p_btif_cb->device_type;
+ BTIF_STORAGE_FILL_PROPERTY(&properties,
+ BT_PROPERTY_TYPE_OF_DEVICE, sizeof(dev_type), &dev_type);
+ btif_storage_set_remote_device_property(&(p_btif_cb->bd_addr), &properties);
+
HAL_CBACK(bt_gatt_callbacks, client->scan_result_cb,
&p_btif_cb->bd_addr, p_btif_cb->rssi, p_btif_cb->value);
break;
@@ -570,6 +587,7 @@
btif_cb.device_type = p_data->inq_res.device_type;
btif_cb.rssi = p_data->inq_res.rssi;
btif_cb.addr_type = p_data->inq_res.ble_addr_type;
+ btif_cb.flag = p_data->inq_res.flag;
if (p_data->inq_res.p_eir)
{
memcpy(btif_cb.value, p_data->inq_res.p_eir, 62);
@@ -663,6 +681,7 @@
// Ensure device is in inquiry database
int addr_type = 0;
int device_type = 0;
+ tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
if (btif_get_device_type(p_cb->bd_addr.address, &addr_type, &device_type) == TRUE
&& device_type != BT_DEVICE_TYPE_BREDR)
@@ -672,8 +691,29 @@
if (!p_cb->is_direct)
BTA_DmBleSetBgConnType(BTM_BLE_CONN_AUTO, NULL);
+ switch(device_type)
+ {
+ case BT_DEVICE_TYPE_BREDR:
+ transport = BTA_GATT_TRANSPORT_BR_EDR;
+ break;
+
+ case BT_DEVICE_TYPE_BLE:
+ transport = BTA_GATT_TRANSPORT_LE;
+ break;
+
+ case BT_DEVICE_TYPE_DUMO:
+ if ((p_cb->transport == GATT_TRANSPORT_LE) &&
+ (btif_storage_is_dmt_supported_device(&(p_cb->bd_addr)) == TRUE))
+ transport = BTA_GATT_TRANSPORT_LE;
+ else
+ transport = BTA_GATT_TRANSPORT_BR_EDR;
+ break;
+ }
+
// Connect!
- BTA_GATTC_Open(p_cb->client_if, p_cb->bd_addr.address, p_cb->is_direct);
+ BTIF_TRACE_DEBUG2 ("BTA_GATTC_Open Transport = %d, dev type = %d",
+ transport, device_type);
+ BTA_GATTC_Open(p_cb->client_if, p_cb->bd_addr.address, p_cb->is_direct, transport);
break;
}
@@ -1057,12 +1097,14 @@
(char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
}
-static bt_status_t btif_gattc_open(int client_if, const bt_bdaddr_t *bd_addr, bool is_direct )
+static bt_status_t btif_gattc_open(int client_if, const bt_bdaddr_t *bd_addr,
+ bool is_direct,int transport)
{
CHECK_BTGATT_INIT();
btif_gattc_cb_t btif_cb;
btif_cb.client_if = (uint8_t) client_if;
btif_cb.is_direct = is_direct ? 1 : 0;
+ btif_cb.transport = (btgatt_transport_t)transport;
bdcpy(btif_cb.bd_addr.address, bd_addr->address);
return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_OPEN,
(char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
diff --git a/btif/src/btif_gatt_server.c b/btif/src/btif_gatt_server.c
index 9fc4fad..f5ad0f5 100644
--- a/btif/src/btif_gatt_server.c
+++ b/btif/src/btif_gatt_server.c
@@ -100,9 +100,10 @@
uint8_t is_direct;
uint8_t num_handles;
uint8_t properties;
- uint8_t transport;
uint8_t confirm;
uint8_t status;
+ btgatt_transport_t transport;
+
} __attribute__((packed)) btif_gatts_cb_t;
@@ -369,6 +370,7 @@
// Ensure device is in inquiry database
int addr_type = 0;
int device_type = 0;
+ tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
if (btif_get_device_type(p_cb->bd_addr.address, &addr_type, &device_type) == TRUE
&& device_type != BT_DEVICE_TYPE_BREDR)
@@ -378,9 +380,32 @@
if (!p_cb->is_direct)
BTA_DmBleSetBgConnType(BTM_BLE_CONN_AUTO, NULL);
+ switch(device_type)
+ {
+ case BT_DEVICE_TYPE_BREDR:
+ transport = BTA_GATT_TRANSPORT_BR_EDR;
+ break;
+
+ case BT_DEVICE_TYPE_BLE:
+ transport = BTA_GATT_TRANSPORT_LE;
+ break;
+
+ case BT_DEVICE_TYPE_DUMO:
+ if ((p_cb->transport == GATT_TRANSPORT_LE) &&
+ (btif_storage_is_dmt_supported_device(&(p_cb->bd_addr)) == TRUE))
+ transport = BTA_GATT_TRANSPORT_LE;
+ else
+ transport = BTA_GATT_TRANSPORT_BR_EDR;
+ break;
+
+ default:
+ BTIF_TRACE_ERROR1 (" GATT Open :Invalid device type %d",device_type);
+ return;
+ }
+
// Connect!
BTA_GATTS_Open(p_cb->server_if, p_cb->bd_addr.address,
- p_cb->is_direct);
+ p_cb->is_direct, transport);
break;
}
@@ -489,12 +514,14 @@
(char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
}
-static bt_status_t btif_gatts_open( int server_if, const bt_bdaddr_t *bd_addr, bool is_direct )
+static bt_status_t btif_gatts_open( int server_if, const bt_bdaddr_t *bd_addr,
+ bool is_direct, int transport )
{
CHECK_BTGATT_INIT();
btif_gatts_cb_t btif_cb;
btif_cb.server_if = (uint8_t) server_if;
btif_cb.is_direct = is_direct ? 1 : 0;
+ btif_cb.transport = (btgatt_transport_t)transport;
bdcpy(btif_cb.bd_addr.address, bd_addr->address);
return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_OPEN,
(char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
diff --git a/btif/src/btif_gatt_test.c b/btif/src/btif_gatt_test.c
index a2cca6a..def2753 100644
--- a/btif/src/btif_gatt_test.c
+++ b/btif/src/btif_gatt_test.c
@@ -101,11 +101,12 @@
}
static void btif_test_connect_cback(tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
- BOOLEAN connected, tGATT_DISCONN_REASON reason)
+ BOOLEAN connected, tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport)
{
UNUSED(gatt_if);
UNUSED(bda);
UNUSED(reason);
+ UNUSED (transport);
ALOGD("%s: conn_id=%d, connected=%d", __FUNCTION__, conn_id, connected);
test_cb.conn_id = connected ? conn_id : 0;
@@ -242,7 +243,7 @@
if (params->u1 == BT_DEVICE_TYPE_BLE)
BTM_SecAddBleDevice(params->bda1->address, NULL, BT_DEVICE_TYPE_BLE, 0);
- if ( !GATT_Connect(test_cb.gatt_if, params->bda1->address, TRUE) )
+ if ( !GATT_Connect(test_cb.gatt_if, params->bda1->address, TRUE, BT_TRANSPORT_LE) )
{
ALOGE("%s: GATT_Connect failed!", __FUNCTION__);
}
diff --git a/btif/src/btif_gatt_util.c b/btif/src/btif_gatt_util.c
index 91cf004..4facdef 100644
--- a/btif/src/btif_gatt_util.c
+++ b/btif/src/btif_gatt_util.c
@@ -285,7 +285,7 @@
* Encrypted link map handling
*******************************************************************************/
-static void btif_gatt_set_encryption_cb (BD_ADDR bd_addr, tBTA_STATUS result);
+static void btif_gatt_set_encryption_cb (BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_STATUS result);
static BOOLEAN btif_gatt_is_link_encrypted (BD_ADDR bd_addr)
{
@@ -295,8 +295,10 @@
return BTA_JvIsEncrypted(bd_addr);
}
-static void btif_gatt_set_encryption_cb (BD_ADDR bd_addr, tBTA_STATUS result)
+static void btif_gatt_set_encryption_cb (BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_STATUS result)
{
+ UNUSED(transport);
+
if (result != BTA_SUCCESS && result != BTA_BUSY)
{
bt_bdaddr_t bda;
@@ -312,16 +314,39 @@
bt_bdaddr_t bda;
bdcpy(bda.address, bd_addr);
+ int device_type = 0;
+ int addr_type = 0;
+#if (!defined(BLE_DELAY_REQUEST_ENC) || (BLE_DELAY_REQUEST_ENC == FALSE))
if ((btif_storage_get_ble_bonding_key(&bda, BTIF_DM_LE_KEY_PENC,
buf, sizeof(btif_dm_ble_penc_keys_t)) == BT_STATUS_SUCCESS)
&& !btif_gatt_is_link_encrypted(bd_addr))
{
-#if (!defined(BLE_DELAY_REQUEST_ENC) || (BLE_DELAY_REQUEST_ENC == FALSE))
- BTA_DmSetEncryption(bd_addr,
+ tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
+
+ btif_get_device_type(bd_addr, &addr_type, &device_type);
+ switch(device_type)
+ {
+ case BT_DEVICE_TYPE_BREDR:
+ transport = BTA_GATT_TRANSPORT_BR_EDR;
+ break;
+
+ case BT_DEVICE_TYPE_BLE:
+ transport = BTA_GATT_TRANSPORT_LE;
+ break;
+
+ case BT_DEVICE_TYPE_DUMO:
+ transport = BTA_GATT_TRANSPORT_LE_BR_EDR;
+ break;
+
+ default:
+ BTIF_TRACE_ERROR1 (" GATT Encrypt :Invalid device type %d",device_type);
+ return;
+ }
+ BTA_DmSetEncryption(bd_addr,transport,
&btif_gatt_set_encryption_cb, BTM_BLE_SEC_ENCRYPT);
-#endif
}
+#endif
}
/*******************************************************************************
diff --git a/btif/src/btif_storage.c b/btif/src/btif_storage.c
index a849938..f364701 100644
--- a/btif/src/btif_storage.c
+++ b/btif/src/btif_storage.c
@@ -1744,8 +1744,8 @@
bd2str(remote_bd_addr, &bdstr);
- /*consider on LAP part of BDA string*/
- bdstr[8] = '\0';
+ /*consider on LAP part of BDA string*/
+ bdstr[8] = '\0';
int line_size = sizeof(linebuf);
if(btif_config_get_str("Local", BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST,
@@ -1757,3 +1757,68 @@
return FALSE;
}
+
+/*******************************************************************************
+**
+** Function btif_storage_set_dmt_support_type
+**
+** Description Sets DMT support status for a remote device
+**
+** Returns BT_STATUS_SUCCESS if config update is successful
+** BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+
+bt_status_t btif_storage_set_dmt_support_type(const bt_bdaddr_t *remote_bd_addr,
+ BOOLEAN dmt_supported)
+{
+ int ret;
+ bdstr_t bdstr = {0};
+ if(remote_bd_addr)
+ {
+ bd2str(remote_bd_addr, &bdstr);
+ }
+ else
+ {
+ BTIF_TRACE_ERROR1("%s NULL BD Address", __FUNCTION__);
+ return BT_STATUS_FAIL;
+ }
+
+ ret = btif_config_set_int("Remote", bdstr,"DMTSupported", (int)dmt_supported);
+ return ret ? BT_STATUS_SUCCESS:BT_STATUS_FAIL;
+
+}
+
+/*******************************************************************************
+**
+** Function btif_storage_is_dmt_supported_device
+**
+** Description checks if a device supports Dual mode topology
+**
+** Returns TRUE if remote address is valid and supports DMT else FALSE
+**
+*******************************************************************************/
+
+BOOLEAN btif_storage_is_dmt_supported_device(const bt_bdaddr_t *remote_bd_addr)
+{
+ int dmt_supported = 0;
+ bdstr_t bdstr = {0};
+ if(remote_bd_addr)
+ bd2str(remote_bd_addr, &bdstr);
+
+ if(remote_bd_addr)
+ {
+ bd2str(remote_bd_addr, &bdstr);
+ }
+ else
+ {
+ BTIF_TRACE_ERROR1("%s NULL BD Address", __FUNCTION__);
+ return FALSE;
+ }
+
+ btif_config_get_int("Remote", bdstr,"DMTSupported", &dmt_supported);
+
+ return dmt_supported == 1 ? TRUE:FALSE;
+}
+
+
diff --git a/hci/src/utils.c b/hci/src/utils.c
index bfcf724..85304fa 100644
--- a/hci/src/utils.c
+++ b/hci/src/utils.c
@@ -65,6 +65,7 @@
*******************************************************************************/
void utils_cleanup (void)
{
+ pthread_mutex_destroy(&utils_mutex);
}
/*******************************************************************************
diff --git a/include/bt_target.h b/include/bt_target.h
index c81cbe5..e6b3bb5 100644
--- a/include/bt_target.h
+++ b/include/bt_target.h
@@ -102,10 +102,6 @@
#define SMP_HOST_ENCRYPT_INCLUDED FALSE
#endif
-#ifndef SAP_INCLUDED
-#define SAP_INCLUDED FALSE
-#endif
-
#ifndef SBC_NO_PCM_CPY_OPTION
#define SBC_NO_PCM_CPY_OPTION FALSE
#endif
@@ -118,34 +114,6 @@
#define BTA_AG_INCLUDED TRUE
#endif
-#ifndef BTA_CT_INCLUDED
-#define BTA_CT_INCLUDED FALSE
-#endif
-
-#ifndef BTA_CG_INCLUDED
-#define BTA_CG_INCLUDED FALSE
-#endif
-
-#ifndef BTA_DG_INCLUDED
-#define BTA_DG_INCLUDED FALSE
-#endif
-
-#ifndef BTA_FT_INCLUDED
-#define BTA_FT_INCLUDED FALSE
-#endif
-
-#ifndef BTA_OP_INCLUDED
-#define BTA_OP_INCLUDED FALSE
-#endif
-
-#ifndef BTA_PR_INCLUDED
-#define BTA_PR_INCLUDED FALSE
-#endif
-
-#ifndef BTA_SS_INCLUDED
-#define BTA_SS_INCLUDED FALSE
-#endif
-
#ifndef BTA_DM_INCLUDED
#define BTA_DM_INCLUDED TRUE
#endif
@@ -171,14 +139,6 @@
#define BTA_FS_INCLUDED TRUE
#endif
-#ifndef BTA_AC_INCLUDED
-#define BTA_AC_INCLUDED FALSE
-#endif
-
-#ifndef BTA_HD_INCLUDED
-#define BTA_HD_INCLUDED FALSE
-#endif
-
#ifndef BTA_HH_INCLUDED
#define BTA_HH_INCLUDED TRUE
#endif
@@ -199,68 +159,8 @@
#define BTA_AV_INCLUDED TRUE
#endif
-#ifndef BTA_AV_VDP_INCLUDED
-#define BTA_AV_VDP_INCLUDED FALSE
-#endif
-
-#ifndef BTA_AVK_INCLUDED
-#define BTA_AVK_INCLUDED FALSE
-#endif
-
-#ifndef BTA_PBS_INCLUDED
-#define BTA_PBS_INCLUDED FALSE
-#endif
-
-#ifndef BTA_PBC_INCLUDED
-#define BTA_PBC_INCLUDED FALSE
-#endif
-
-#ifndef BTA_FM_INCLUDED
-#define BTA_FM_INCLUDED FALSE
-#endif
-
-#ifndef BTA_FM_DEBUG
-#define BTA_FM_DEBUG FALSE
-#endif
-
-#ifndef BTA_FMTX_INCLUDED
-#define BTA_FMTX_INCLUDED FALSE
-#endif
-
-#ifndef BTA_FMTX_DEBUG
-#define BTA_FMTX_DEBUG FALSE
-#endif
-
-#ifndef BTA_FMTX_FMRX_SWITCH_WORKAROUND
-#define BTA_FMTX_FMRX_SWITCH_WORKAROUND FALSE
-#endif
-
-#ifndef BTA_FMTX_US_FCC_RULES
-#define BTA_FMTX_US_FCC_RULES FALSE
-#endif
-
-#ifndef BTA_HS_INCLUDED
-#define BTA_HS_INCLUDED FALSE
-#endif
-
-#ifndef BTA_MSE_INCLUDED
-#define BTA_MSE_INCLUDED FALSE
-#endif
-
-#ifndef BTA_MCE_INCLUDED
-#define BTA_MCE_INCLUDED FALSE
-#endif
-
-#ifndef BTA_PLAYBACK_INCLUDED
-#define BTA_PLAYBACK_INCLUDED FALSE
-#endif
-
-#ifndef BTA_SSR_INCLUDED
-#define BTA_SSR_INCLUDED FALSE
-#endif
-
-#ifndef BTA_JV_INCLUDED
-#define BTA_JV_INCLUDED FALSE
+#ifndef BTA_GATT_INCLUDED
+#define BTA_GATT_INCLUDED TRUE
#endif
#ifndef BTA_DISABLE_DELAY
@@ -397,10 +297,6 @@
#define BTA_DM_SDP_DB_SIZE 8000
#endif
-#ifndef FTS_REJECT_INVALID_OBEX_SET_PATH_REQ
-#define FTS_REJECT_INVALID_OBEX_SET_PATH_REQ FALSE
-#endif
-
#ifndef HL_INCLUDED
#define HL_INCLUDED TRUE
#endif
@@ -421,8 +317,6 @@
-/* #define BYPASS_AVDATATRACE */
-
/******************************************************************************
**
** Platform-Specific
@@ -1130,16 +1024,6 @@
#define BTM_MAX_VSE_CALLBACKS 3
#endif
-/* Number of streams for dual stack */
-#ifndef BTM_SYNC_INFO_NUM_STR
-#define BTM_SYNC_INFO_NUM_STR 2
-#endif
-
-/* Number of streams for dual stack in BT Controller */
-#ifndef BTM_SYNC_INFO_NUM_STR_BTC
-#define BTM_SYNC_INFO_NUM_STR_BTC 2
-#endif
-
/******************************************
** Lisbon Features
*******************************************/
@@ -1412,8 +1296,8 @@
#define LOCAL_BLE_CONTROLLER_ID (1)
#endif
-#ifndef BTM_BLE_PRIVACY_SPT
-#define BTM_BLE_PRIVACY_SPT TRUE
+#ifndef BLE_PRIVACY_SPT
+#define BLE_PRIVACY_SPT TRUE
#endif
/******************************************************************************
@@ -1433,6 +1317,12 @@
#error "can't have GATT without BLE"
#endif
+#ifndef BLE_LLT_INCLUDED
+#define BLE_LLT_INCLUDED TRUE
+#endif
+#ifndef BTM_DUMO_ADDR_CENTRAL_ENABLED
+#define BTM_DUMO_ADDR_CENTRAL_ENABLED FALSE
+#endif
#ifndef ATT_INCLUDED
#define ATT_INCLUDED TRUE
#endif
@@ -1450,7 +1340,7 @@
#endif
#ifndef BLE_PERIPHERAL_MODE_SUPPORT
-#define BLE_PERIPHERAL_MODE_SUPPORT FALSE
+#define BLE_PERIPHERAL_MODE_SUPPORT TRUE
#endif
#ifndef BLE_PERIPHERAL_DISPLAYONLY
diff --git a/main/bte_main.c b/main/bte_main.c
index b9cbf91..7395481 100644
--- a/main/bte_main.c
+++ b/main/bte_main.c
@@ -641,11 +641,19 @@
APPL_TRACE_DEBUG1("HC alloc size=%d", size);
*/
+ /* Requested buffer size cannot exceed GKI_MAX_BUF_SIZE. */
+ if (size > GKI_MAX_BUF_SIZE)
+ {
+ APPL_TRACE_ERROR2("HCI DATA SIZE %d greater than MAX %d",
+ size, GKI_MAX_BUF_SIZE);
+ return NULL;
+ }
+
p_hdr = (BT_HDR *) GKI_getbuf ((UINT16) size);
if (p_hdr == NULL)
{
- APPL_TRACE_WARNING0("alloc returns NO BUFFER!");
+ APPL_TRACE_WARNING1("alloc returns NO BUFFER! (sz %d)", size);
}
return ((char *) p_hdr);
diff --git a/stack/avdt/avdt_l2c.c b/stack/avdt/avdt_l2c.c
index 2256a90..943a3cf 100644
--- a/stack/avdt/avdt_l2c.c
+++ b/stack/avdt/avdt_l2c.c
@@ -70,7 +70,8 @@
** Returns void
**
*******************************************************************************/
-static void avdt_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+static void avdt_sec_check_complete_term (BD_ADDR bd_addr, tBT_TRANSPORT transport,
+ void *p_ref_data, UINT8 res)
{
tAVDT_CCB *p_ccb = NULL;
tL2CAP_CFG_INFO cfg;
@@ -92,7 +93,7 @@
if (res == BTM_SUCCESS)
{
- /* Send response to the L2CAP layer. */
+ /* Send response to the L2CAP layer. */
L2CA_ConnectRsp (bd_addr, p_tbl->id, p_tbl->lcid, L2CAP_CONN_OK, L2CAP_CONN_OK);
/* store idx in LCID table, store LCID in routing table */
@@ -127,7 +128,8 @@
** Returns void
**
*******************************************************************************/
-static void avdt_sec_check_complete_orig (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+static void avdt_sec_check_complete_orig (BD_ADDR bd_addr, tBT_TRANSPORT trasnport,
+ void *p_ref_data, UINT8 res)
{
tAVDT_CCB *p_ccb = NULL;
tL2CAP_CFG_INFO cfg;
diff --git a/stack/bnep/bnep_int.h b/stack/bnep/bnep_int.h
index 528c809..0c435ef 100644
--- a/stack/bnep/bnep_int.h
+++ b/stack/bnep/bnep_int.h
@@ -234,9 +234,12 @@
extern void bnep_send_conn_responce (tBNEP_CONN *p_bcb, UINT16 resp_code);
extern void bnep_process_setup_conn_req (tBNEP_CONN *p_bcb, UINT8 *p_setup, UINT8 len);
extern void bnep_process_setup_conn_responce (tBNEP_CONN *p_bcb, UINT8 *p_setup);
-extern UINT8 *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *len, BOOLEAN is_ext);
-extern void bnep_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 result);
-extern tBNEP_RESULT bnep_is_packet_allowed (tBNEP_CONN *p_bcb, BD_ADDR p_dest_addr, UINT16 protocol, BOOLEAN fw_ext_present, UINT8 *p_data);
+extern UINT8 *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *len,
+ BOOLEAN is_ext);
+extern void bnep_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT trasnport,
+ void *p_ref_data, UINT8 result);
+extern tBNEP_RESULT bnep_is_packet_allowed (tBNEP_CONN *p_bcb, BD_ADDR p_dest_addr, UINT16 protocol,
+ BOOLEAN fw_ext_present, UINT8 *p_data);
extern UINT32 bnep_get_uuid32 (tBT_UUID *src_uuid);
extern void bnep_dump_status (void);
diff --git a/stack/bnep/bnep_utils.c b/stack/bnep/bnep_utils.c
index 0a8fd6d..faf808b 100644
--- a/stack/bnep/bnep_utils.c
+++ b/stack/bnep/bnep_utils.c
@@ -1209,12 +1209,14 @@
** Returns void
**
*******************************************************************************/
-void bnep_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 result)
+void bnep_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT trasnport,
+ void *p_ref_data, UINT8 result)
{
tBNEP_CONN *p_bcb = (tBNEP_CONN *)p_ref_data;
UINT16 resp_code = BNEP_SETUP_CONN_OK;
BOOLEAN is_role_change;
UNUSED(bd_addr);
+ UNUSED(trasnport);
BNEP_TRACE_EVENT1 ("BNEP security callback returned result %d", result);
if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
diff --git a/stack/btm/btm_acl.c b/stack/btm/btm_acl.c
index 49ace6e..026330c 100644
--- a/stack/btm/btm_acl.c
+++ b/stack/btm/btm_acl.c
@@ -131,11 +131,14 @@
**
** Description This function returns the FIRST acl_db entry for the passed BDA.
**
+** Parameters bda : BD address of the remote device
+** transport : Physical transport used for ACL connection (BR/EDR or LE)
+**
** Returns Returns pointer to the ACL DB for the requested BDA if found.
** NULL if not found.
**
*******************************************************************************/
-tACL_CONN *btm_bda_to_acl (BD_ADDR bda)
+tACL_CONN *btm_bda_to_acl (BD_ADDR bda, tBT_TRANSPORT transport)
{
tACL_CONN *p = &btm_cb.acl_db[0];
UINT16 xx;
@@ -143,7 +146,11 @@
{
for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++)
{
- if ((p->in_use) && (!memcmp (p->remote_addr, bda, BD_ADDR_LEN)))
+ if ((p->in_use) && (!memcmp (p->remote_addr, bda, BD_ADDR_LEN))
+#if BLE_INCLUDED == TRUE
+ && p->transport == transport
+#endif
+ )
{
BTM_TRACE_DEBUG0 ("btm_bda_to_acl found");
return(p);
@@ -181,7 +188,7 @@
return(xx);
}
-#if BTM_BLE_PRIVACY_SPT == TRUE
+#if BLE_PRIVACY_SPT == TRUE
/*******************************************************************************
**
** Function btm_ble_get_acl_remote_addr
@@ -247,24 +254,24 @@
**
*******************************************************************************/
void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn,
- UINT16 hci_handle, UINT8 link_role, UINT8 is_le_link)
+ UINT16 hci_handle, UINT8 link_role, tBT_TRANSPORT transport)
{
tBTM_SEC_DEV_REC *p_dev_rec = NULL;
UINT8 yy;
tACL_CONN *p;
UINT8 xx;
- BTM_TRACE_DEBUG3 ("btm_acl_created hci_handle=%d link_role=%d is_le_link=%d",
- hci_handle,link_role, is_le_link);
+ BTM_TRACE_DEBUG3 ("btm_acl_created hci_handle=%d link_role=%d transport=%d",
+ hci_handle,link_role, transport);
/* Ensure we don't have duplicates */
- p = btm_bda_to_acl(bda);
+ p = btm_bda_to_acl(bda, transport);
if (p != (tACL_CONN *)NULL)
{
p->hci_handle = hci_handle;
p->link_role = link_role;
btm_save_remote_device_role(bda, link_role);
#if BLE_INCLUDED == TRUE
- p->is_le_link = is_le_link;
+ p->transport = transport;
#endif
BTM_TRACE_DEBUG6 ("Duplicate btm_acl_created: RemBdAddr: %02x%02x%02x%02x%02x%02x",
bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
@@ -284,14 +291,23 @@
p->link_up_issued = FALSE;
#if BLE_INCLUDED == TRUE
- p->is_le_link = is_le_link;
-
- if (is_le_link)
+ p->transport = transport;
+ if (transport == BT_TRANSPORT_LE)
{
- p->conn_addr_type = BLE_ADDR_PUBLIC;
- BTM_GetLocalDeviceAddr(p->conn_addr);
+#if ( BLE_PRIVACY_SPT == TRUE )
+ /*allow central device to use random address for now by skipping the role check */
+ if (btm_cb.ble_ctr_cb.privacy /* && p->link_role == HCI_ROLE_SLAVE */)
+ {
+ p->conn_addr_type = btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type;
+ memcpy(p->conn_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, BD_ADDR_LEN);
+ }
+ else
+#endif
+ {
+ p->conn_addr_type = BLE_ADDR_PUBLIC;
+ BTM_GetLocalDeviceAddr(p->conn_addr);
+ }
}
-
#endif
p->restore_pkt_types = 0; /* Only exists while SCO is active */
p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
@@ -311,7 +327,7 @@
memcpy (p->remote_name, bdn, BTM_MAX_REM_BD_NAME_LEN);
/* if BR/EDR do something more */
- if (!is_le_link)
+ if (transport == BT_TRANSPORT_BR_EDR)
{
btsnd_hcic_read_rmt_clk_offset (p->hci_handle);
btsnd_hcic_rmt_ver_req (p->hci_handle);
@@ -325,7 +341,7 @@
}
#endif
- if (p_dev_rec && !is_le_link)
+ if (p_dev_rec && !(transport == BT_TRANSPORT_LE))
{
/* If remote features already known, copy them and continue connection setup */
if ((p_dev_rec->num_read_pages) &&
@@ -353,9 +369,9 @@
#if (BLE_INCLUDED == TRUE)
/* If here, features are not known yet */
- if (p_dev_rec && is_le_link)
+ if (p_dev_rec && transport == BT_TRANSPORT_LE)
{
-#if BTM_BLE_PRIVACY_SPT == TRUE
+#if BLE_PRIVACY_SPT == TRUE
btm_ble_get_acl_remote_addr (p_dev_rec, p->active_remote_addr,
&p->active_remote_addr_type);
#endif
@@ -417,7 +433,7 @@
** Returns void
**
*******************************************************************************/
-void btm_acl_removed (BD_ADDR bda)
+void btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport)
{
tACL_CONN *p;
#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
@@ -428,7 +444,7 @@
#endif
BTM_TRACE_DEBUG0 ("btm_acl_removed");
- p = btm_bda_to_acl(bda);
+ p = btm_bda_to_acl(bda, transport);
if (p != (tACL_CONN *)NULL)
{
p->in_use = FALSE;
@@ -447,22 +463,29 @@
{
evt_data.event = BTM_BL_DISCN_EVT;
evt_data.discn.p_bda = bda;
-
+#if BLE_INCLUDED == TRUE
+ evt_data.discn.handle = p->hci_handle;
+ evt_data.discn.transport = p->transport;
+#endif
(*btm_cb.p_bl_changed_cb)(&evt_data);
}
btm_acl_update_busy_level (BTM_BLI_ACL_DOWN_EVT);
#else
if (btm_cb.p_acl_changed_cb)
+#if BLE_INCLUDED == TRUE
+ (*btm_cb.p_acl_changed_cb) (bda, NULL, NULL, NULL, FALSE, p->hci_handle, p->transport);
+#else
(*btm_cb.p_acl_changed_cb) (bda, NULL, NULL, NULL, FALSE);
#endif
+#endif
}
#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
- BTM_TRACE_DEBUG4 ("acl hci_handle=%d is_le_link=%d connectable_mode=0x%0x link_role=%d",
+ BTM_TRACE_DEBUG4 ("acl hci_handle=%d transport=%d connectable_mode=0x%0x link_role=%d",
p->hci_handle,
- p->is_le_link,
+ p->transport,
btm_cb.ble_ctr_cb.inq_var.connectable_mode,
p->link_role);
@@ -470,14 +493,14 @@
if ( p_dev_rec)
{
BTM_TRACE_DEBUG1("before update p_dev_rec->sec_flags=0x%x", p_dev_rec->sec_flags);
- if (p->is_le_link)
+ if (p->transport == BT_TRANSPORT_LE)
{
BTM_TRACE_DEBUG0("LE link down");
- p_dev_rec->sec_flags &= ~(BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
- if ( (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN) == 0)
+ p_dev_rec->sec_flags &= ~(BTM_SEC_LE_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
+ if ( (p_dev_rec->sec_flags & BTM_SEC_LE_LINK_KEY_KNOWN) == 0)
{
BTM_TRACE_DEBUG0("Not Bonded");
- p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHENTICATED | BTM_SEC_LINK_KEY_AUTHED);
+ p_dev_rec->sec_flags &= ~(BTM_SEC_LE_LINK_KEY_AUTHED | BTM_SEC_LE_AUTHENTICATED);
}
else
{
@@ -545,6 +568,7 @@
tBTM_BL_UPDATE_DATA evt;
UINT8 busy_level;
BTM_TRACE_DEBUG0 ("btm_acl_update_busy_level");
+ BOOLEAN old_inquiry_state = btm_cb.is_inquiry;
switch (event)
{
case BTM_BLI_ACL_UP_EVT:
@@ -594,7 +618,7 @@
else
busy_level = (UINT8)btm_cb.num_acl;
- if (busy_level != btm_cb.busy_level)
+ if ((busy_level != btm_cb.busy_level) ||(old_inquiry_state != btm_cb.is_inquiry))
{
evt.event = BTM_BL_UPDATE_EVT;
evt.busy_level = busy_level;
@@ -623,7 +647,7 @@
{
tACL_CONN *p;
BTM_TRACE_DEBUG0 ("BTM_GetRole");
- if ((p = btm_bda_to_acl(remote_bd_addr)) == NULL)
+ if ((p = btm_bda_to_acl(remote_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
{
*p_role = BTM_ROLE_UNDEFINED;
return(BTM_UNKNOWN_ADDR);
@@ -686,7 +710,7 @@
return(BTM_BUSY);
}
- if ((p = btm_bda_to_acl(remote_bd_addr)) == NULL)
+ if ((p = btm_bda_to_acl(remote_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
return(BTM_UNKNOWN_ADDR);
/* Finished if already in desired role */
@@ -811,7 +835,7 @@
tBTM_PM_PWR_MD settings;
#endif
BTM_TRACE_DEBUG0 ("BTM_ChangeLinkKey");
- if ((p = btm_bda_to_acl(remote_bd_addr)) == NULL)
+ if ((p = btm_bda_to_acl(remote_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
return(BTM_UNKNOWN_ADDR);
/* Ignore change link key request if the previsous request has not completed */
@@ -1123,9 +1147,8 @@
}
}
- if ((p = btm_bda_to_acl(remote_bda)) != NULL)
- return(btsnd_hcic_write_policy_set (p->hci_handle, *settings) ?
- BTM_CMD_STARTED : BTM_NO_RESOURCES);
+ if ((p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR)) != NULL)
+ return(btsnd_hcic_write_policy_set (p->hci_handle, *settings) ? BTM_CMD_STARTED : BTM_NO_RESOURCES);
/* If here, no BD Addr found */
return(BTM_UNKNOWN_ADDR);
@@ -1199,7 +1222,7 @@
if (btm_cb.devcb.p_rlinkp_cmpl_cb)
return(BTM_BUSY);
- p = btm_bda_to_acl(remote_bda);
+ p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
if (p != (tACL_CONN *)NULL)
{
btu_start_timer (&btm_cb.devcb.rlinkp_timer, BTU_TTYPE_BTM_ACL, BTM_DEV_REPLY_TIMEOUT);
@@ -1638,47 +1661,62 @@
static void btm_establish_continue (tACL_CONN *p_acl_cb)
{
#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
- tBTM_BL_EVENT_DATA evt_data;
+ tBTM_BL_EVENT_DATA evt_data;
#endif
- BTM_TRACE_DEBUG0 ("btm_establish_continue");
+ BTM_TRACE_DEBUG0 ("btm_establish_continue");
#if (!defined(BTM_BYPASS_EXTRA_ACL_SETUP) || BTM_BYPASS_EXTRA_ACL_SETUP == FALSE)
#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
- if (!p_acl_cb->is_le_link)
+ if (p_acl_cb->transport == BT_TRANSPORT_BR_EDR)
#endif
- {
- /* For now there are a some devices that do not like sending */
- /* commands events and data at the same time. */
- /* Set the packet types to the default allowed by the device */
- btm_set_packet_types (p_acl_cb, btm_cb.btm_acl_pkt_types_supported);
+ {
+ /* For now there are a some devices that do not like sending */
+ /* commands events and data at the same time. */
+ /* Set the packet types to the default allowed by the device */
+ btm_set_packet_types (p_acl_cb, btm_cb.btm_acl_pkt_types_supported);
- if (btm_cb.btm_def_link_policy)
- BTM_SetLinkPolicy (p_acl_cb->remote_addr, &btm_cb.btm_def_link_policy);
- }
+ if (btm_cb.btm_def_link_policy)
+ BTM_SetLinkPolicy (p_acl_cb->remote_addr, &btm_cb.btm_def_link_policy);
+ }
#endif
- p_acl_cb->link_up_issued = TRUE;
+ p_acl_cb->link_up_issued = TRUE;
- /* If anyone cares, tell him database changed */
+ /* If anyone cares, tell him database changed */
#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
- if (btm_cb.p_bl_changed_cb)
- {
- evt_data.event = BTM_BL_CONN_EVT;
- evt_data.conn.p_bda = p_acl_cb->remote_addr;
- evt_data.conn.p_bdn = p_acl_cb->remote_name;
- evt_data.conn.p_dc = p_acl_cb->remote_dc;
- evt_data.conn.p_features = p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0];
-
-
- (*btm_cb.p_bl_changed_cb)(&evt_data);
- }
- btm_acl_update_busy_level (BTM_BLI_ACL_UP_EVT);
-#else
- if (btm_cb.p_acl_changed_cb)
- (*btm_cb.p_acl_changed_cb) (p_acl_cb->remote_addr,
- p_acl_cb->remote_dc,
- p_acl_cb->remote_name,
- p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0],
- TRUE);
+ if (btm_cb.p_bl_changed_cb)
+ {
+ evt_data.event = BTM_BL_CONN_EVT;
+ evt_data.conn.p_bda = p_acl_cb->remote_addr;
+ evt_data.conn.p_bdn = p_acl_cb->remote_name;
+ evt_data.conn.p_dc = p_acl_cb->remote_dc;
+ evt_data.conn.p_features = p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0];
+#if BLE_INCLUDED == TRUE
+ evt_data.conn.handle = p_acl_cb->hci_handle;
+ evt_data.conn.transport = p_acl_cb->transport;
#endif
+
+ (*btm_cb.p_bl_changed_cb)(&evt_data);
+ }
+ btm_acl_update_busy_level (BTM_BLI_ACL_UP_EVT);
+#else
+ if (btm_cb.p_acl_changed_cb)
+#if BLE_INCLUDED == TRUE
+ (*btm_cb.p_acl_changed_cb) (p_acl_cb->remote_addr,
+ p_acl_cb->remote_dc,
+ p_acl_cb->remote_name,
+ p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0],
+ TRUE,
+ p_acl_cb->hci_handle,
+ p_acl_cb->transport);
+#else
+ (*btm_cb.p_acl_changed_cb) (p_acl_cb->remote_addr,
+ p_acl_cb->remote_dc,
+ p_acl_cb->remote_name,
+ p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0],
+ TRUE);
+#endif
+
+#endif
+
}
@@ -1709,7 +1747,7 @@
*******************************************************************************/
tBTM_STATUS BTM_GetLinkSuperTout (BD_ADDR remote_bda, UINT16 *p_timeout)
{
- tACL_CONN *p = btm_bda_to_acl(remote_bda);
+ tACL_CONN *p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
BTM_TRACE_DEBUG0 ("BTM_GetLinkSuperTout");
if (p != (tACL_CONN *)NULL)
@@ -1733,7 +1771,7 @@
*******************************************************************************/
tBTM_STATUS BTM_SetLinkSuperTout (BD_ADDR remote_bda, UINT16 timeout)
{
- tACL_CONN *p = btm_bda_to_acl(remote_bda);
+ tACL_CONN *p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
BTM_TRACE_DEBUG0 ("BTM_SetLinkSuperTout");
if (p != (tACL_CONN *)NULL)
@@ -1820,7 +1858,7 @@
if (!HCI_HOLD_MODE_SUPPORTED(BTM_ReadLocalFeatures()))
return(BTM_MODE_UNSUPPORTED);
- p = btm_bda_to_acl(remote_bda);
+ p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
if (p != (tACL_CONN *)NULL)
{
/* If the connection is in park or sniff mode, forget about holding it */
@@ -1858,7 +1896,7 @@
if (!HCI_SNIFF_MODE_SUPPORTED(BTM_ReadLocalFeatures()))
return(BTM_MODE_UNSUPPORTED);
- p = btm_bda_to_acl(remote_bda);
+ p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
if (p != (tACL_CONN *)NULL)
{
/* If the connection is in park mode, forget about sniffing it */
@@ -1892,7 +1930,7 @@
*******************************************************************************/
tBTM_STATUS BTM_CancelSniffMode (BD_ADDR remote_bda)
{
- tACL_CONN *p = btm_bda_to_acl(remote_bda);
+ tACL_CONN *p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
BTM_TRACE_DEBUG0 ("BTM_CancelSniffMode ");
if (p == (tACL_CONN *)NULL)
return(BTM_UNKNOWN_ADDR);
@@ -1928,7 +1966,7 @@
if (!HCI_PARK_MODE_SUPPORTED(BTM_ReadLocalFeatures()))
return(BTM_MODE_UNSUPPORTED);
- p = btm_bda_to_acl(remote_bda);
+ p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
if (p != (tACL_CONN *)NULL)
{
/* If the connection is in sniff mode, forget about parking it */
@@ -1966,7 +2004,7 @@
tACL_CONN *p;
BTM_TRACE_DEBUG0 ("BTM_CancelParkMode");
- p = btm_bda_to_acl(remote_bda);
+ p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
if (p != (tACL_CONN *)NULL)
{
/* If the connection is not in park mode, cannot cancel */
@@ -2000,7 +2038,7 @@
tACL_CONN *p;
BTM_TRACE_DEBUG0 ("BTM_SetPacketTypes");
- if ((p = btm_bda_to_acl(remote_bda)) != NULL)
+ if ((p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR)) != NULL)
return(btm_set_packet_types (p, pkt_types));
/* If here, no BD Addr found */
@@ -2023,7 +2061,7 @@
tACL_CONN *p;
BTM_TRACE_DEBUG0 ("BTM_ReadPacketTypes");
- p = btm_bda_to_acl(remote_bda);
+ p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
if (p != (tACL_CONN *)NULL)
{
return(p->pkt_types_mask);
@@ -2063,7 +2101,7 @@
remote_bda[0], remote_bda[1], remote_bda[2],
remote_bda[3], remote_bda[4], remote_bda[5]);
- p = btm_bda_to_acl(remote_bda);
+ p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
if (p != (tACL_CONN *)NULL)
{
*p_mode = p->mode;
@@ -2095,7 +2133,7 @@
remote_bda[0], remote_bda[1], remote_bda[2],
remote_bda[3], remote_bda[4], remote_bda[5]);
- if ( (p = btm_bda_to_acl(remote_bda)) != NULL)
+ if ( (p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR)) != NULL)
return(p->clock_offset);
/* If here, no BD Addr found */
@@ -2112,7 +2150,7 @@
** Returns TRUE if connection is up, else FALSE.
**
*******************************************************************************/
-BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda)
+BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda, tBT_TRANSPORT transport)
{
tACL_CONN *p;
@@ -2120,7 +2158,7 @@
remote_bda[0], remote_bda[1], remote_bda[2],
remote_bda[3], remote_bda[4], remote_bda[5]);
- p = btm_bda_to_acl(remote_bda);
+ p = btm_bda_to_acl(remote_bda, transport);
if (p != (tACL_CONN *)NULL)
{
return(TRUE);
@@ -2160,6 +2198,34 @@
/*******************************************************************************
**
+** Function BTM_GetNumLeLinks
+**
+** Description This function is called to count the number of
+** LE ACL links that are active.
+**
+** Returns UINT16 Number of active LE links
+**
+*******************************************************************************/
+UINT16 BTM_GetNumLeLinks (void)
+{
+ UINT16 yy = 0;
+
+#if BLE_INCLUDED == TRUE
+ tACL_CONN *p = &btm_cb.acl_db[0];
+ UINT16 xx;
+ BTM_TRACE_DEBUG0 ("BTM_GetNumLeLinks");
+ for (xx = yy = 0; xx < MAX_L2CAP_LINKS; xx++, p++)
+ {
+ if ((p->in_use) &&(p->transport == BT_TRANSPORT_LE))
+ yy++;
+ }
+#endif
+
+ return(yy);
+}
+
+/*******************************************************************************
+**
** Function btm_get_acl_disc_reason_code
**
** Description This function is called to get the disconnection reason code
@@ -2186,11 +2252,11 @@
** Returns the handle of the connection, or 0xFFFF if none.
**
*******************************************************************************/
-UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda)
+UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda, tBT_TRANSPORT transport)
{
tACL_CONN *p;
BTM_TRACE_DEBUG0 ("BTM_GetHCIConnHandle");
- p = btm_bda_to_acl(remote_bda);
+ p = btm_bda_to_acl(remote_bda, transport);
if (p != (tACL_CONN *)NULL)
{
return(p->hci_handle);
@@ -2280,7 +2346,7 @@
{
UINT8 *p_bda = (bd_addr) ? bd_addr :
btm_cb.devcb.switch_role_ref_data.remote_bd_addr;
- tACL_CONN *p = btm_bda_to_acl(p_bda);
+ tACL_CONN *p = btm_bda_to_acl(p_bda, BT_TRANSPORT_BR_EDR);
tBTM_ROLE_SWITCH_CMPL *p_data = &btm_cb.devcb.switch_role_ref_data;
tBTM_SEC_DEV_REC *p_dev_rec;
#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
@@ -2567,7 +2633,7 @@
*******************************************************************************/
UINT16 btm_get_max_packet_size (BD_ADDR addr)
{
- tACL_CONN *p = btm_bda_to_acl(addr);
+ tACL_CONN *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
UINT16 pkt_types = 0;
UINT16 pkt_size = 0;
BTM_TRACE_DEBUG0 ("btm_get_max_packet_size");
@@ -2625,7 +2691,7 @@
tBTM_STATUS BTM_ReadRemoteVersion (BD_ADDR addr, UINT8 *lmp_version,
UINT16 *manufacturer, UINT16 *lmp_sub_version)
{
- tACL_CONN *p = btm_bda_to_acl(addr);
+ tACL_CONN *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
BTM_TRACE_DEBUG0 ("BTM_ReadRemoteVersion");
if (p == NULL)
return(BTM_UNKNOWN_ADDR);
@@ -2651,7 +2717,7 @@
*******************************************************************************/
UINT8 *BTM_ReadRemoteFeatures (BD_ADDR addr)
{
- tACL_CONN *p = btm_bda_to_acl(addr);
+ tACL_CONN *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
BTM_TRACE_DEBUG0 ("BTM_ReadRemoteFeatures");
if (p == NULL)
{
@@ -2671,7 +2737,7 @@
*******************************************************************************/
UINT8 *BTM_ReadRemoteExtendedFeatures (BD_ADDR addr, UINT8 page_number)
{
- tACL_CONN *p = btm_bda_to_acl(addr);
+ tACL_CONN *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
BTM_TRACE_DEBUG0 ("BTM_ReadRemoteExtendedFeatures");
if (p == NULL)
{
@@ -2696,7 +2762,7 @@
*******************************************************************************/
UINT8 BTM_ReadNumberRemoteFeaturesPages (BD_ADDR addr)
{
- tACL_CONN *p = btm_bda_to_acl(addr);
+ tACL_CONN *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
BTM_TRACE_DEBUG0 ("BTM_ReadNumberRemoteFeaturesPages");
if (p == NULL)
{
@@ -2715,7 +2781,7 @@
*******************************************************************************/
UINT8 *BTM_ReadAllRemoteFeatures (BD_ADDR addr)
{
- tACL_CONN *p = btm_bda_to_acl(addr);
+ tACL_CONN *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
BTM_TRACE_DEBUG0 ("BTM_ReadAllRemoteFeatures");
if (p == NULL)
{
@@ -2798,7 +2864,7 @@
if (btm_cb.devcb.p_qossu_cmpl_cb)
return(BTM_BUSY);
- if ( (p = btm_bda_to_acl(bd)) != NULL)
+ if ( (p = btm_bda_to_acl(bd, BT_TRANSPORT_BR_EDR)) != NULL)
{
btu_start_timer (&btm_cb.devcb.qossu_timer, BTU_TTYPE_BTM_ACL, BTM_DEV_REPLY_TIMEOUT);
btm_cb.devcb.p_qossu_cmpl_cb = p_cb;
@@ -2882,7 +2948,7 @@
if (btm_cb.devcb.p_rssi_cmpl_cb)
return(BTM_BUSY);
- p = btm_bda_to_acl(remote_bda);
+ p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
if (p != (tACL_CONN *)NULL)
{
btu_start_timer (&btm_cb.devcb.rssi_timer, BTU_TTYPE_BTM_ACL,
@@ -2927,7 +2993,7 @@
if (btm_cb.devcb.p_lnk_qual_cmpl_cb)
return(BTM_BUSY);
- p = btm_bda_to_acl(remote_bda);
+ p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
if (p != (tACL_CONN *)NULL)
{
btu_start_timer (&btm_cb.devcb.lnk_quality_timer, BTU_TTYPE_BTM_ACL,
@@ -2960,7 +3026,7 @@
** Returns BTM_CMD_STARTED if successfully initiated or error code
**
*******************************************************************************/
-tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
+tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb)
{
tACL_CONN *p;
BOOLEAN ret;
@@ -2975,7 +3041,7 @@
if (btm_cb.devcb.p_tx_power_cmpl_cb)
return(BTM_BUSY);
- p = btm_bda_to_acl(remote_bda);
+ p = btm_bda_to_acl(remote_bda, transport);
if (p != (tACL_CONN *)NULL)
{
btu_start_timer (&btm_cb.devcb.tx_power_timer, BTU_TTYPE_BTM_ACL,
@@ -2984,7 +3050,7 @@
btm_cb.devcb.p_tx_power_cmpl_cb = p_cb;
#if BLE_INCLUDED == TRUE
- if (p->is_le_link)
+ if (p->transport == BT_TRANSPORT_LE)
{
memcpy(btm_cb.devcb.read_tx_pwr_addr, remote_bda, BD_ADDR_LEN);
ret = btsnd_hcic_ble_read_adv_chnl_tx_power();
@@ -3187,9 +3253,9 @@
** Returns BTM_SUCCESS if successfully initiated, otherwise BTM_NO_RESOURCES.
**
*******************************************************************************/
-tBTM_STATUS btm_remove_acl (BD_ADDR bd_addr)
+tBTM_STATUS btm_remove_acl (BD_ADDR bd_addr, tBT_TRANSPORT transport)
{
- UINT16 hci_handle = BTM_GetHCIConnHandle(bd_addr);
+ UINT16 hci_handle = BTM_GetHCIConnHandle(bd_addr, transport);
tBTM_STATUS status = BTM_SUCCESS;
BTM_TRACE_DEBUG0 ("btm_remove_acl");
@@ -3463,6 +3529,11 @@
evt_data.event = BTM_BL_COLLISION_EVT;
evt_data.conn.p_bda = bda;
+
+#if BLE_INCLUDED == TRUE
+ evt_data.conn.transport = BT_TRANSPORT_BR_EDR;
+ evt_data.conn.handle = BTM_INVALID_HCI_HANDLE;
+#endif
(*btm_cb.p_bl_changed_cb)(&evt_data);
return TRUE;
}
diff --git a/stack/btm/btm_ble.c b/stack/btm/btm_ble.c
index 5b61b76..9bd771a 100644
--- a/stack/btm/btm_ble.c
+++ b/stack/btm/btm_ble.c
@@ -35,9 +35,6 @@
#include "btm_ble_api.h"
#include "smp_api.h"
#include "l2c_int.h"
-#if (defined BLE_BRCM_INCLUDED && BLE_BRCM_INCLUDED == TRUE)
-#include "brcm_ble.h"
-#endif
#include "gap_api.h"
#include "bt_utils.h"
@@ -94,7 +91,8 @@
memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC));
p_dev_rec->sec_flags = BTM_SEC_IN_USE;
memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
- p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr);
+ p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR);
+ p_dev_rec->ble_hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_LE);
/* update conn params, use default value for background connection params */
p_dev_rec->conn_params.min_conn_int =
@@ -102,7 +100,7 @@
p_dev_rec->conn_params.supervision_tout =
p_dev_rec->conn_params.slave_latency = BTM_BLE_CONN_PARAM_UNDEF;
- BTM_TRACE_DEBUG1 ("hci_handl=0x%x ", p_dev_rec->hci_handle );
+ BTM_TRACE_DEBUG1 ("hci_handl=0x%x ", p_dev_rec->ble_hci_handle );
break;
}
}
@@ -290,7 +288,7 @@
*******************************************************************************/
void BTM_ReadConnectionAddr (BD_ADDR remote_bda, BD_ADDR local_conn_addr, tBLE_ADDR_TYPE *p_addr_type)
{
- tACL_CONN *p_acl = btm_bda_to_acl(remote_bda);
+ tACL_CONN *p_acl = btm_bda_to_acl(remote_bda, BT_TRANSPORT_LE);
if (p_acl == NULL)
{
@@ -316,6 +314,7 @@
*******************************************************************************/
BOOLEAN BTM_IsBleConnection (UINT16 conn_handle)
{
+#if (BLE_INCLUDED == TRUE)
UINT8 xx;
tACL_CONN *p;
@@ -327,7 +326,10 @@
p = &btm_cb.acl_db[xx];
- return(p->is_le_link);
+ return (p->transport == BT_TRANSPORT_LE);
+#else
+ return FALSE;
+#endif
}
/*******************************************************************************
@@ -335,27 +337,33 @@
** Function BTM_ReadRemoteConnectionAddr
**
** Description This function is read the remote device address currently used
-** .
**
-** Returns void
+** Parameters pseudo_addr: pseudo random address available
+** conn_addr:connection address used
+** p_addr_type : BD Address type, Public or Random of the address used
+**
+** Returns BOOLEAN , TRUE if connection to remote device exists, else FALSE
**
*******************************************************************************/
-BOOLEAN BTM_ReadRemoteConnectionAddr(BD_ADDR pseudo_addr, BD_ADDR conn_addr, tBLE_ADDR_TYPE *p_addr_type)
+BOOLEAN BTM_ReadRemoteConnectionAddr(BD_ADDR pseudo_addr, BD_ADDR conn_addr,
+ tBLE_ADDR_TYPE *p_addr_type)
{
- BOOLEAN st = TRUE;
- tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_addr);
-#if BTM_BLE_PRIVACY_SPT == TRUE
- tACL_CONN *p = btm_bda_to_acl (pseudo_addr);
+ BOOLEAN st = TRUE;
+#if (BLE_PRIVACY_SPT == TRUE)
+ tACL_CONN *p = btm_bda_to_acl (pseudo_addr, BT_TRANSPORT_LE);
if (p == NULL)
{
- BTM_TRACE_ERROR0("BTM_ReadRemoteConnectionAddr can not find matching address");
+ BTM_TRACE_ERROR0("BTM_ReadRemoteConnectionAddr can not find connection"
+ " with matching address");
return FALSE;
}
memcpy(conn_addr, p->active_remote_addr, BD_ADDR_LEN);
*p_addr_type = p->active_remote_addr_type;
#else
+ tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_addr);
+
memcpy(conn_addr, pseudo_addr, BD_ADDR_LEN);
if (p_dev_rec != NULL)
{
@@ -363,6 +371,7 @@
}
#endif
return st;
+
}
/*******************************************************************************
**
@@ -412,7 +421,7 @@
return;
}
- p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
+ p_dev_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_AUTHED;
BTM_TRACE_DEBUG0 ("BTM_BlePasskeyReply");
SMP_PasskeyReply(bd_addr, res_smp, passkey);
#endif
@@ -444,7 +453,7 @@
return;
}
- p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
+ p_dev_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_AUTHED;
SMP_OobDataReply(bd_addr, res_smp, len, p_data);
#endif
}
@@ -694,24 +703,6 @@
/*******************************************************************************
**
-** Function BTM_IsBleLink
-**
-** Description This function is to check the link type is BLE or BR/EDR.
-**
-** Returns TRUE if BLE link; FALSE if BR/EDR.
-**
-*******************************************************************************/
-BOOLEAN BTM_IsBleLink (BD_ADDR bd_addr)
-{
- tACL_CONN *p;
- BTM_TRACE_DEBUG0 ("BTM_IsBleLink");
- if ((p = btm_bda_to_acl(bd_addr)) != NULL)
- return p->is_le_link;
- else
- return FALSE;
-}
-/*******************************************************************************
-**
** Function BTM_UseLeLink
**
** Description This function is to select the underneath physical link to use.
@@ -726,9 +717,13 @@
tBLE_ADDR_TYPE addr_type;
BOOLEAN use_le = FALSE;
- if ((p = btm_bda_to_acl(bd_addr)) != NULL)
+ if ((p = btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR)) != NULL)
{
- use_le = (p->is_le_link);
+ return use_le;
+ }
+ else if ((p = btm_bda_to_acl(bd_addr, BT_TRANSPORT_LE)) != NULL)
+ {
+ use_le = TRUE;
}
else
{
@@ -902,11 +897,11 @@
p_rec->ble.keys.ediv = p_keys->penc_key.ediv;
p_rec->ble.keys.key_size = p_keys->penc_key.key_size;
p_rec->ble.key_type |= BTM_LE_KEY_PENC;
- p_rec->sec_flags |= BTM_SEC_LINK_KEY_KNOWN;
+ p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_KNOWN;
if (p_keys->penc_key.sec_level == SMP_SEC_AUTHENTICATED)
- p_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
+ p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_AUTHED;
else
- p_rec->sec_flags &= ~BTM_SEC_LINK_KEY_AUTHED;
+ p_rec->sec_flags &= ~BTM_SEC_LE_LINK_KEY_AUTHED;
BTM_TRACE_DEBUG3("BTM_LE_KEY_PENC key_type=0x%x sec_flags=0x%x sec_leve=0x%x",
p_rec->ble.key_type,
p_rec->sec_flags,
@@ -931,11 +926,11 @@
p_rec->ble.keys.srk_sec_level = p_keys->pcsrk_key.sec_level;
p_rec->ble.keys.counter = p_keys->pcsrk_key.counter;
p_rec->ble.key_type |= BTM_LE_KEY_PCSRK;
- p_rec->sec_flags |= BTM_SEC_LINK_KEY_KNOWN;
+ p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_KNOWN;
if ( p_keys->pcsrk_key.sec_level== SMP_SEC_AUTHENTICATED)
- p_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
+ p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_AUTHED;
else
- p_rec->sec_flags &= ~BTM_SEC_LINK_KEY_AUTHED;
+ p_rec->sec_flags &= ~BTM_SEC_LE_LINK_KEY_AUTHED;
BTM_TRACE_DEBUG4("BTM_LE_KEY_PCSRK key_type=0x%x sec_flags=0x%x sec_level=0x%x peer_counter=%d",
p_rec->ble.key_type,
@@ -1081,9 +1076,9 @@
BTM_TRACE_DEBUG1 ("dev_rec sec_flags=0x%x", p_dev_rec->sec_flags);
/* currently encrpted */
- if (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)
+ if (p_dev_rec->sec_flags & BTM_SEC_LE_ENCRYPTED)
{
- if (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_AUTHED)
+ if (p_dev_rec->sec_flags & BTM_SEC_LE_LINK_KEY_AUTHED)
cur_sec_level = BTM_LE_SEC_AUTHENTICATED;
else
cur_sec_level = BTM_LE_SEC_UNAUTHENTICATE;
@@ -1191,7 +1186,7 @@
break;
default:
- cmd = BTM_SUCCESS;
+ cmd = BTM_WRONG_MODE;
break;
}
return cmd;
@@ -1235,40 +1230,48 @@
** Description This function is called to start LE encryption.
**
**
-** Returns void
+** Returns BTM_SUCCESS if encryption was started successfully
**
*******************************************************************************/
-BOOLEAN btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk)
+tBTM_STATUS btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk)
{
tBTM_CB *p_cb = &btm_cb;
tBTM_SEC_DEV_REC *p_rec = btm_find_dev (bda);
BT_OCTET8 dummy_rand = {0};
- BOOLEAN rt = FALSE;
+ tBTM_STATUS rt = BTM_NO_RESOURCES;
BTM_TRACE_DEBUG0 ("btm_ble_start_encrypt");
- if (!p_rec ||
- (p_rec && p_rec->sec_state == BTM_SEC_STATE_ENCRYPTING))
- return FALSE;
+ if (!p_rec )
+ {
+ BTM_TRACE_ERROR0("Link is not active, can not encrypt!");
+ return BTM_WRONG_MODE;
+ }
- p_cb->enc_handle = p_rec->hci_handle;
+ if (p_rec->sec_state == BTM_SEC_STATE_ENCRYPTING)
+ {
+ BTM_TRACE_WARNING0("Link Encryption is active, Busy!");
+ return BTM_BUSY;
+ }
+
+ p_cb->enc_handle = p_rec->ble_hci_handle;
if (use_stk)
{
- if (btsnd_hcic_ble_start_enc(p_rec->hci_handle, dummy_rand, 0, stk))
- rt = TRUE;
+ if (btsnd_hcic_ble_start_enc(p_rec->ble_hci_handle, dummy_rand, 0, stk))
+ rt = BTM_CMD_STARTED;
}
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->ble_hci_handle, p_rec->ble.keys.rand,
p_rec->ble.keys.ediv, p_rec->ble.keys.ltk))
- rt = TRUE;
+ rt = BTM_CMD_STARTED;
}
else
{
BTM_TRACE_ERROR0("No key available to encrypt the link");
}
- if (rt)
+ if (rt == BTM_CMD_STARTED)
{
if (p_rec->sec_state == BTM_SEC_STATE_IDLE)
p_rec->sec_state = BTM_SEC_STATE_ENCRYPTING;
@@ -1312,9 +1315,9 @@
if (p_dev_rec->p_callback && enc_cback)
{
if (encr_enable)
- btm_sec_dev_rec_cback_event(p_dev_rec, BTM_SUCCESS);
+ btm_sec_dev_rec_cback_event(p_dev_rec, BTM_SUCCESS, TRUE);
else if (p_dev_rec->role_master)
- btm_sec_dev_rec_cback_event(p_dev_rec, BTM_ERR_PROCESSING);
+ btm_sec_dev_rec_cback_event(p_dev_rec, BTM_ERR_PROCESSING, TRUE);
}
/* to notify GATT to send data if any request is pending */
@@ -1399,7 +1402,7 @@
}
BTM_TRACE_DEBUG0 ("btm_ble_ltk_request_reply");
- p_cb->enc_handle = p_rec->hci_handle;
+ p_cb->enc_handle = p_rec->ble_hci_handle;
p_cb->key_size = p_rec->ble.keys.key_size;
BTM_TRACE_ERROR1("key size = %d", p_rec->ble.keys.key_size);
@@ -1477,7 +1480,7 @@
return callback_rc;
}
-#if (BTM_BLE_PRIVACY_SPT == TRUE )
+#if (BLE_PRIVACY_SPT == TRUE )
/*******************************************************************************
**
** Function btm_ble_resolve_random_addr_on_conn_cmpl
@@ -1556,7 +1559,7 @@
#if (BT_USE_TRACES == TRUE)
if (p_dev_rec)
{
- BTM_TRACE_EVENT4 ("Security Manager: btm_sec_connected : handle:%d enc_mode:%d bda:%x RName:%s",
+ BTM_TRACE_EVENT4 ("Security Manager: btm_ble_connected : handle:%d enc_mode:%d bda:%x RName:%s",
handle, enc_mode,
(bda[2]<<24)+(bda[3]<<16)+(bda[4]<<8)+bda[5],
p_dev_rec->sec_bd_name);
@@ -1565,7 +1568,7 @@
}
else
{
- BTM_TRACE_EVENT3 ("Security Manager: btm_sec_connected: handle:%d enc_mode:%d bda:%x ",
+ BTM_TRACE_EVENT3 ("Security Manager: btm_ble_connected: handle:%d enc_mode:%d bda:%x ",
handle, enc_mode,
(bda[2]<<24)+(bda[3]<<16)+(bda[4]<<8)+bda[5]);
}
@@ -1583,14 +1586,14 @@
/* update device information */
p_dev_rec->device_type |= BT_DEVICE_TYPE_BLE;
- p_dev_rec->hci_handle = handle;
+ p_dev_rec->ble_hci_handle = handle;
p_dev_rec->ble.ble_addr_type = addr_type;
p_dev_rec->role_master = FALSE;
if (role == HCI_ROLE_MASTER)
p_dev_rec->role_master = TRUE;
-#if (defined BTM_BLE_PRIVACY_SPT && BTM_BLE_PRIVACY_SPT == TRUE)
+#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
if (!addr_matched)
p_dev_rec->ble.active_addr_type = BTM_BLE_ADDR_PSEUDO;
@@ -1613,7 +1616,7 @@
******************************************************************************/
void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len)
{
-#if (BTM_BLE_PRIVACY_SPT == TRUE )
+#if (BLE_PRIVACY_SPT == TRUE )
UINT8 *p_data = p;
#endif
UINT8 role, status, bda_type;
@@ -1631,10 +1634,10 @@
if (status == 0)
{
-#if (BTM_BLE_PRIVACY_SPT == TRUE )
+#if (BLE_PRIVACY_SPT == TRUE )
/* possiblly receive connection complete with resolvable random on
slave role while the device has been paired */
- if (!match && BTM_BLE_IS_RESOLVE_BDA(bda))
+ if (!match && role == HCI_ROLE_SLAVE && BTM_BLE_IS_RESOLVE_BDA(bda))
{
btm_ble_resolve_random_addr(bda, btm_ble_resolve_random_addr_on_conn_cmpl, p_data);
}
@@ -1679,9 +1682,7 @@
}
}
}
-
btm_ble_set_conn_st(BLE_CONN_IDLE);
-
btm_ble_update_mode_operation(role, bda, TRUE);
}
@@ -1709,10 +1710,12 @@
case SMP_PASSKEY_REQ_EVT:
case SMP_PASSKEY_NOTIF_EVT:
case SMP_OOB_REQ_EVT:
- p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
+ p_dev_rec->sec_flags |= BTM_SEC_LE_AUTHENTICATED;
+
case SMP_SEC_REQUEST_EVT:
memcpy (btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN);
p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
+ btm_cb.pairing_flags |= BTM_PAIR_FLAGS_LE_ACTIVE;
/* fall through */
case SMP_COMPLT_EVT:
if (btm_cb.api.p_le_callback)
@@ -1731,7 +1734,7 @@
BTM_TRACE_DEBUG3 ("after update result=%d sec_level=0x%x sec_flags=0x%x",
res, p_data->cmplt.sec_level , p_dev_rec->sec_flags );
- btm_sec_dev_rec_cback_event(p_dev_rec, res);
+ btm_sec_dev_rec_cback_event(p_dev_rec, res, TRUE);
if (p_data->cmplt.is_pair_cancel && btm_cb.api.p_bond_cancel_cmpl_callback )
{
@@ -1744,7 +1747,7 @@
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);
+ btm_remove_acl(bd_addr, BT_TRANSPORT_LE);
}
else
{
@@ -1754,7 +1757,7 @@
}
#else
if (res != BTM_SUCCESS && p_data->cmplt.reason != SMP_CONN_TOUT)
- btm_remove_acl(bd_addr);
+ btm_remove_acl(bd_addr, BT_TRANSPORT_LE);
#endif
BTM_TRACE_DEBUG3 ("btm_cb pairing_state=%x pairing_flags=%x pin_code_len=%x",
diff --git a/stack/btm/btm_ble_bgconn.c b/stack/btm/btm_ble_bgconn.c
index 96d35c4..7341cd2 100644
--- a/stack/btm/btm_ble_bgconn.c
+++ b/stack/btm/btm_ble_bgconn.c
@@ -57,7 +57,7 @@
btsnd_hcic_ble_set_scan_params (p_inq->scan_type,
(UINT16)(!p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval),
(UINT16)(!p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window),
- BLE_ADDR_PUBLIC,
+ btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type,
scan_policy);
}
/*******************************************************************************
@@ -88,12 +88,13 @@
if (memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) != 0 &&
memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) != 0)
{
- started = btsnd_hcic_ble_add_white_list (p_dev_rec->ble.static_addr_type, p_dev_rec->ble.static_addr);
+ started = btsnd_hcic_ble_add_white_list (p_dev_rec->ble.static_addr_type,
+ p_dev_rec->ble.static_addr);
}
}
else
{
- 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_remove_from_white_list (p_dev_rec->ble.ble_addr_type, bd_addr);
}
@@ -255,9 +256,9 @@
}
/*******************************************************************************
**
-** Function btm_ble_add_2_white_list_complete
+** Function btm_ble_remove_from_white_list_complete
**
-** Description This function read the current white list size.
+** Description This function remove the white list element complete.
*******************************************************************************/
void btm_ble_remove_from_white_list_complete(UINT8 *p, UINT16 evt_len)
{
@@ -284,7 +285,7 @@
for (i = 0; i < BTM_BLE_MAX_BG_CONN_DEV_NUM; i ++)
{
if (p_cb->bg_dev_list[i].in_use &&
- !BTM_IsAclConnectionUp(p_cb->bg_dev_list[i].bd_addr))
+ !BTM_IsAclConnectionUp(p_cb->bg_dev_list[i].bd_addr, BT_TRANSPORT_LE))
{
count ++;
}
@@ -363,12 +364,12 @@
tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
BD_ADDR dummy_bda = {0};
BOOLEAN exec = TRUE;
- UINT8 own_addr_type = BLE_ADDR_PUBLIC;
UINT16 scan_int, scan_win;
if (start)
{
- if (p_cb->conn_state == BLE_CONN_IDLE && btm_ble_count_unconn_dev_in_whitelist() > 0)
+ if ((p_cb->conn_state == BLE_CONN_IDLE && btm_ble_count_unconn_dev_in_whitelist() > 0)
+ && btm_ble_topology_check(BTM_BLE_STATE_INIT))
{
btm_execute_wl_dev_operation();
@@ -380,7 +381,9 @@
0x01, /* UINT8 white_list */
BLE_ADDR_PUBLIC, /* UINT8 addr_type_peer */
dummy_bda, /* BD_ADDR bda_peer */
- own_addr_type, /* UINT8 addr_type_own, not allow random address for central */
+ p_cb->addr_mgnt_cb.own_addr_type,
+ /* UINT8 addr_type_own,
+ not allow random address for central */
BTM_BLE_CONN_INT_MIN_DEF, /* UINT16 conn_int_min */
BTM_BLE_CONN_INT_MAX_DEF, /* UINT16 conn_int_max */
BTM_BLE_CONN_SLAVE_LATENCY_DEF, /* UINT16 conn_latency */
@@ -407,7 +410,7 @@
if (p_cb->conn_state == BLE_BG_CONN)
{
btsnd_hcic_ble_create_conn_cancel();
- btm_ble_set_conn_st (BLE_CONN_CANCEL);
+ btm_ble_set_conn_st (BLE_CONN_CANCEL);
}
else
@@ -446,26 +449,27 @@
if (start)
{
- if (btm_cb.btm_inq_vars.inq_active == BTM_INQUIRY_INACTIVE)
+ if (!BTM_BLE_IS_SCAN_ACTIVE(p_cb->scan_activity))
{
if (p_select_cback != NULL)
btm_cb.ble_ctr_cb.p_select_cback = p_select_cback;
+ btm_execute_wl_dev_operation();
+
btm_update_scanner_filter_policy(SP_ADV_WL);
btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_PASS;
if (!btsnd_hcic_ble_set_scan_params(BTM_BLE_SCAN_MODE_PASS, /* use passive scan by default */
scan_int, /* scan interval */
scan_win, /* scan window */
- BLE_ADDR_PUBLIC, /* own device, DUMO always use public */
+ p_cb->addr_mgnt_cb.own_addr_type,
SP_ADV_WL) /* process advertising packets only from devices in the White List */
)
return FALSE;
- if (p_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE
- )
+ if (!btm_ble_topology_check(BTM_BLE_STATE_PASSIVE_SCAN))
{
- BTM_TRACE_ERROR0("peripheral device cannot initiate a selective connection");
+ BTM_TRACE_ERROR0("peripheral device cannot initiate passive scan for a selective connection");
return FALSE;
}
else if (p_cb->bg_dev_num > 0 && btm_ble_count_unconn_dev_in_whitelist() > 0 )
@@ -475,9 +479,7 @@
return FALSE;
/* mark up inquiry status flag */
- btm_cb.btm_inq_vars.inq_active |= BTM_LE_SELECT_CONN_ACTIVE;
- p_cb->inq_var.proc_mode = BTM_BLE_SELECT_SCAN;
- p_cb->conn_state = BLE_BG_CONN;
+ p_cb->scan_activity |= BTM_LE_SELECT_CONN_ACTIVE;
}
}
else
@@ -488,13 +490,13 @@
}
else /* disable selective connection mode */
{
- btm_cb.btm_inq_vars.inq_active &= ~BTM_LE_SELECT_CONN_ACTIVE;
- btm_cb.ble_ctr_cb.inq_var.proc_mode = BTM_BLE_INQUIRY_NONE;
+ p_cb->scan_activity &= ~BTM_LE_SELECT_CONN_ACTIVE;
+ p_cb->p_select_cback = NULL;
- btm_update_scanner_filter_policy(SP_ADV_ALL);
+
/* stop scanning */
- if (!btsnd_hcic_ble_set_scan_enable(FALSE, TRUE)) /* duplicate filtering enabled */
- return FALSE;
+ if (!BTM_BLE_IS_SCAN_ACTIVE(p_cb->scan_activity))
+ btm_ble_stop_scan(); /* duplicate filtering enabled */
btm_update_scanner_filter_policy(SP_ADV_ALL);
}
return TRUE;
@@ -569,7 +571,7 @@
}
if (wl_state & BTM_BLE_WL_ADV)
{
- btsnd_hcic_ble_set_adv_enable(BTM_BLE_ADV_DISABLE);
+ btm_ble_stop_adv();
}
}
@@ -588,7 +590,7 @@
if (wl_state & BTM_BLE_WL_ADV)
{
- btsnd_hcic_ble_set_adv_enable(BTM_BLE_ADV_ENABLE);
+ btm_ble_start_adv();
}
}
@@ -645,6 +647,10 @@
void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st)
{
btm_cb.ble_ctr_cb.conn_state = new_st;
+ if (new_st == BLE_BG_CONN || new_st == BLE_DIR_CONN)
+ btm_ble_set_topology_mask(BTM_BLE_STATE_INIT_BIT);
+ else
+ btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT);
}
/*******************************************************************************
@@ -689,6 +695,7 @@
return rt;
}
+
#endif
diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c
index 39f344c..f9bd1aa 100644
--- a/stack/btm/btm_ble_gap.c
+++ b/stack/btm/btm_ble_gap.c
@@ -37,6 +37,8 @@
#if (BLE_INCLUDED == TRUE)
#include "gattdefs.h"
+#include "btm_ble_int.h"
+
#define BTM_BLE_NAME_SHORT 0x01
#define BTM_BLE_NAME_CMPL 0x02
@@ -55,26 +57,156 @@
BD_ADDR_PTR p_addr_ptr,
tBLE_ADDR_TYPE *p_init_addr_type,
tBLE_ADDR_TYPE *p_own_addr_type);
-static tBTM_STATUS btm_ble_start_adv(void);
-static tBTM_STATUS btm_ble_stop_adv(void);
+static void btm_ble_stop_observe(void);
+#define BTM_BLE_INQ_RESULT 0x01
+#define BTM_BLE_OBS_RESULT 0x02
+#define BTM_BLE_SEL_CONN_RESULT 0x04
-
-/*******************************************************************************
-**
-** Function BTM_BleReset
-**
-** Description This function is called to reset ULP controller.
-**
-** Parameters None.
-**
-** Returns void
-**
-*******************************************************************************/
-void BTM_BleReset(void)
+/* LE states combo bit to check */
+const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] =
{
- btsnd_hcic_ble_reset();
-}
+ {/* single state support */
+ {HCI_SUPP_LE_STATES_CONN_ADV_MASK, HCI_SUPP_LE_STATES_CONN_ADV_OFF}, /* conn_adv */
+ {HCI_SUPP_LE_STATES_INIT_MASK, HCI_SUPP_LE_STATES_INIT_OFF}, /* init */
+ {HCI_SUPP_LE_STATES_INIT_MASK, HCI_SUPP_LE_STATES_INIT_OFF}, /* master */
+ {HCI_SUPP_LE_STATES_SLAVE_MASK, HCI_SUPP_LE_STATES_SLAVE_OFF}, /* slave */
+ {0, 0}, /* todo: lo du dir adv, not covered ? */
+ {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF}, /* hi duty dir adv */
+ {HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF}, /* non connectable adv */
+ {HCI_SUPP_LE_STATES_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_OFF}, /* passive scan */
+ {HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_OFF}, /* active scan */
+ {HCI_SUPP_LE_STATES_SCAN_ADV_MASK, HCI_SUPP_LE_STATESSCAN_ADV_OFF} /* scanable adv */
+ },
+ { /* conn_adv =0 */
+ {0, 0}, /* conn_adv */
+ {HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK, HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF}, /* init: 32 */
+ {HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF}, /* master: 35 */
+ {HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF}, /* slave: 38,*/
+ {0, 0}, /* lo du dir adv */
+ {0, 0}, /* hi duty dir adv */
+ {0, 0}, /* non connectable adv */
+ {HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF}, /* passive scan */
+ {HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF}, /* active scan */
+ {0, 0} /* scanable adv */
+ },
+ { /* init */
+ {HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK, HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF}, /* conn_adv: 32 */
+ {0, 0}, /* init */
+ {HCI_SUPP_LE_STATES_INIT_MASTER_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_OFF}, /* master 28 */
+ {HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF}, /* slave 41 */
+ {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF} ,/* lo du dir adv 34 */
+ {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF}, /* hi duty dir adv 33 */
+ {HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK, HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF}, /* non connectable adv */
+ {HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF}, /* passive scan */
+ {HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF}, /* active scan */
+ {HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF} /* scanable adv */
+
+ },
+ { /* master */
+ {HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF}, /* conn_adv: 35 */
+ {HCI_SUPP_LE_STATES_INIT_MASTER_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_OFF}, /* init 28 */
+ {HCI_SUPP_LE_STATES_INIT_MASTER_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_OFF}, /* master 28 */
+ {HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK, HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF}, /* slave: 32 */
+ {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF}, /* lo duty cycle adv 37 */
+ {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF}, /* hi duty cycle adv 36 */
+ {HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF}, /* non connectable adv */
+ {HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF}, /* passive scan */
+ {HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF}, /* active scan */
+ {HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF} /* scanable adv */
+
+ },
+ { /* slave */
+ {HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF}, /* conn_adv: 38,*/
+ {HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF}, /* init 41 */
+ {HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF}, /* master 41 */
+ {HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF}, /* slave: 38,*/
+ {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF}, /* lo duty cycle adv 40 */
+ {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF}, /* hi duty cycle adv 39 */
+ {HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF}, /* non connectable adv */
+ {HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF}, /* passive scan */
+ {HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF}, /* active scan */
+ {HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF} /* scanable adv */
+
+ },
+ { /* lo duty cycle adv */
+ {0, 0}, /* conn_adv: 38,*/
+ {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF} ,/* init 34 */
+ {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF}, /* master 37 */
+ {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF}, /* slave: 40 */
+ {0, 0}, /* lo duty cycle adv 40 */
+ {0, 0}, /* hi duty cycle adv 39 */
+ {0, 0}, /* non connectable adv */
+ {0, 0}, /* TODO: passive scan, not covered? */
+ {0, 0}, /* TODO: active scan, not covered? */
+ {0, 0} /* scanable adv */
+ },
+ { /* hi duty cycle adv */
+ {0, 0}, /* conn_adv: 38,*/
+ {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF}, /* init 33 */
+ {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF}, /* master 36 */
+ {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF}, /* slave: 39*/
+ {0, 0}, /* lo duty cycle adv 40 */
+ {0, 0}, /* hi duty cycle adv 39 */
+ {0, 0}, /* non connectable adv */
+ {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF}, /* passive scan */
+ {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF}, /* active scan */
+ {0, 0} /* scanable adv */
+ },
+ { /* non connectable adv */
+ {0, 0}, /* conn_adv: */
+ {HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK, HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF}, /* init */
+ {HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF}, /* master */
+ {HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF}, /* slave: */
+ {0, 0}, /* lo duty cycle adv */
+ {0, 0}, /* hi duty cycle adv */
+ {0, 0}, /* non connectable adv */
+ {HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF}, /* passive scan */
+ {HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF}, /* active scan */
+ {0, 0} /* scanable adv */
+ },
+ { /* passive scan */
+ {HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF}, /* conn_adv: */
+ {HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF}, /* init */
+ {HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF}, /* master */
+ {HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF}, /* slave: */
+ {0, 0}, /* lo duty cycle adv */
+ {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF}, /* hi duty cycle adv */
+ {HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF}, /* non connectable adv */
+ {0, 0}, /* passive scan */
+ {0, 0}, /* active scan */
+ {HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF} /* scanable adv */
+ },
+ { /* active scan */
+ {HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF}, /* conn_adv: */
+ {HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF}, /* init */
+ {HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF}, /* master */
+ {HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF}, /* slave: */
+ {0, 0}, /* lo duty cycle adv */
+ {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF}, /* hi duty cycle adv */
+ {HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF}, /* non connectable adv */
+ {0, 0}, /* TODO: passive scan */
+ {0, 0}, /* TODO: active scan */
+ {HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF} /* scanable adv */
+ },
+ { /* scanable adv */
+ {0, 0}, /* conn_adv: */
+ {HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF}, /* init */
+ {HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF}, /* master */
+ {HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF}, /* slave: */
+ {0, 0}, /* lo duty cycle adv */
+ {0, 0}, /* hi duty cycle adv */
+ {0, 0}, /* non connectable adv */
+ {HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF}, /* passive scan */
+ {HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF}, /* active scan */
+ {0, 0} /* scanable adv */
+ }
+
+};
+/* check LE combo state supported */
+#define BTM_LE_STATES_SUPPORTED(x, y, z) ((x)[(z)] & (y))
+
+
/*******************************************************************************
**
** Function BTM_BleUpdateAdvWhitelist
@@ -122,10 +254,13 @@
btm_ble_stop_adv ();
if (p_cb->connectable_mode & BTM_BLE_CONNECTABLE)
- p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &p_cb->adv_addr_type);
+ p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type,
+ &p_cb->adv_addr_type);
- btsnd_hcic_ble_write_adv_params (p_cb->adv_interval_min,
- p_cb->adv_interval_max,
+ btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min :
+ BTM_BLE_GAP_ADV_SLOW_INT),
+ (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max :
+ BTM_BLE_GAP_ADV_SLOW_INT),
p_cb->evt_type,
p_cb->adv_addr_type,
init_addr_type,
@@ -155,7 +290,7 @@
tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb)
{
tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
- tBTM_STATUS status = BTM_NO_RESOURCES;
+ tBTM_STATUS status = BTM_WRONG_MODE;
BTM_TRACE_EVENT1 ("BTM_BleObserve : scan_type:%d",btm_cb.btm_inq_vars.scan_type);
@@ -165,63 +300,50 @@
if (start)
{
/* shared inquiry database, do not allow observe if any inquiry is active */
- if (btm_cb.btm_inq_vars.inq_active || p_inq->proc_mode != BTM_BLE_INQUIRY_NONE)
+ if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity))
{
- /*check if an interleave scan is already in progress*/
- if(btm_cb.btm_inq_vars.scan_type == INQ_GENERAL
- && btm_cb.btm_inq_vars.p_inq_results_cb != NULL)
- {
- BTM_TRACE_EVENT0 ("BTM_BleObserve general inq in progress, redirecting the results");
- btm_cb.btm_inq_vars.p_inq_ble_results_cb = p_results_cb;
- btm_cb.btm_inq_vars.p_inq_ble_cmpl_cb = p_cmpl_cb;
- return BTM_SUCCESS;
- }
- else
- return BTM_BUSY;
+ BTM_TRACE_ERROR0("Observe Already Active");
+ return status;
}
- btm_cb.btm_inq_vars.scan_type = INQ_LE_OBSERVE;
- btm_cb.btm_inq_vars.p_inq_ble_results_cb = p_results_cb;
- btm_cb.btm_inq_vars.p_inq_ble_cmpl_cb = p_cmpl_cb;
- p_inq->scan_type = (p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) ? BTM_BLE_SCAN_MODE_ACTI: p_inq->scan_type;
- /* allow config scanning type */
- if (btsnd_hcic_ble_set_scan_params (p_inq->scan_type,
+ btm_cb.ble_ctr_cb.p_obs_results_cb = p_results_cb;
+ btm_cb.ble_ctr_cb.p_obs_cmpl_cb = p_cmpl_cb;
+ status = BTM_CMD_STARTED;
+
+ /* scan is not started */
+ if (!BTM_BLE_IS_SCAN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity))
+ {
+ p_inq->scan_type = (p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) ? BTM_BLE_SCAN_MODE_ACTI: p_inq->scan_type;
+ /* allow config scanning type */
+ btsnd_hcic_ble_set_scan_params (p_inq->scan_type,
(UINT16)(!p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval),
(UINT16)(!p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window),
- BLE_ADDR_PUBLIC,
- BTM_BLE_DEFAULT_SFP)) /* assume observe always not using white list */
- {
- /* start scan, disable duplicate filtering */
- if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE))
- {
- status = BTM_SUCCESS;
- p_inq->proc_mode = BTM_BLE_OBSERVE;
- btm_cb.btm_inq_vars.inq_active |= BTM_LE_OBSERVE_ACTIVE;
+ btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type,
+ BTM_BLE_DEFAULT_SFP); /* assume observe always not using white list */
- if (duration != 0)
- {
- /* start inquiry timer */
- btu_start_timer (&p_inq->inq_timer_ent, BTU_TTYPE_BLE_INQUIRY, duration);
- }
- }
+ status = btm_ble_start_scan(BTM_BLE_DUPLICATE_DISABLE);
+ }
+ if (status == BTM_CMD_STARTED)
+ {
+ btm_cb.ble_ctr_cb.scan_activity |= BTM_LE_OBSERVE_ACTIVE;
+
+ if (duration != 0)
+ /* start observer timer */
+ btu_start_timer (&btm_cb.ble_ctr_cb.obs_timer_ent, BTU_TTYPE_BLE_OBSERVE, duration);
}
}
- else/*start = 0*/
+ else if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity))
{
- if(btm_cb.btm_inq_vars.scan_type == INQ_GENERAL)
- {
- //Dont stop the scan. Just nullify the cbs
- btm_cb.btm_inq_vars.p_inq_ble_results_cb = NULL;
- btm_cb.btm_inq_vars.p_inq_ble_cmpl_cb = NULL;
- }
- else if (p_inq->proc_mode == BTM_BLE_OBSERVE)
- {
- btm_cb.btm_inq_vars.inq_active &= ~BTM_LE_OBSERVE_ACTIVE;
- btm_ble_stop_scan();
- }
+ status = BTM_CMD_STARTED;
+ btm_ble_stop_observe();
+ }
+ else
+ {
+ BTM_TRACE_ERROR0("Observe not active");
}
return status;
+
}
/*******************************************************************************
@@ -255,8 +377,10 @@
if (start && p_cb->adv_mode == BTM_BLE_ADV_DISABLE)
{
/* update adv params */
- if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT),
- (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT),
+ if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min :
+ BTM_BLE_GAP_ADV_INT),
+ (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max :
+ BTM_BLE_GAP_ADV_INT),
evt_type,
p_addr_cb->own_addr_type,
p_cb->direct_bda.type,
@@ -270,7 +394,7 @@
status = btm_ble_start_adv ();
}
- else if (!start && p_cb->adv_mode == BTM_BLE_ADV_ENABLE)
+ else if (!start)
{
status = btm_ble_stop_adv();
}
@@ -278,7 +402,7 @@
{
status = BTM_WRONG_MODE;
BTM_TRACE_ERROR2("Can not %s Broadcast, device %s in Broadcast mode",
- (start ? "Start" : "Stop"), (start ? "alerady" :"not"));
+ (start ? "Start" : "Stop"), (start ? "already" :"not"));
}
return status;
}
@@ -309,7 +433,42 @@
#endif
}
-#if BTM_BLE_PRIVACY_SPT == TRUE
+#if BLE_PRIVACY_SPT == TRUE
+/*******************************************************************************
+**
+** Function BTM_BleConfigPrivacy
+**
+** Description This function is called to enable or disable the privacy in
+** LE channel of the local device.
+**
+** Parameters enable: TRUE to enable it; FALSE to disable it.
+**
+** Returns void
+**
+*******************************************************************************/
+void BTM_BleConfigPrivacy(BOOLEAN enable)
+{
+ tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
+
+ BTM_TRACE_EVENT0 (" BTM_BleConfigPrivacy");
+
+ if (p_cb->privacy != enable)
+ {
+ p_cb->privacy = enable;
+
+ if (p_cb->privacy)
+ {
+ /* generate resolvable private address */
+ btm_gen_resolvable_private_addr();
+ }
+ else /* if privacy disabled, always use public address */
+ {
+ p_cb->addr_mgnt_cb.own_addr_type = BLE_ADDR_PUBLIC;
+ }
+ }
+}
+
+
/*******************************************************************************
**
** Function btm_ble_resolve_random_addr_on_adv
@@ -486,11 +645,13 @@
{
UINT8 evt_type;
+ UNUSED(p_own_addr_type);
+
if ( p_cb->directed_conn)
{
/* direct adv mode does not have privacy if privacy
- is not enabled or no reconn addr config */
- *p_own_addr_type = BLE_ADDR_PUBLIC;
+ is not enabled or no reconn addr config */
+
*p_init_addr_type = p_cb->direct_bda.type;
memcpy(p_addr_ptr, p_cb->direct_bda.bda, BD_ADDR_LEN);
evt_type = BTM_BLE_CONNECT_DIR_EVT;
@@ -498,6 +659,16 @@
else /* undirect adv mode */
{
evt_type = BTM_BLE_CONNECT_EVT;
+
+#if BLE_PRIVACY_SPT == TRUE
+ /* may need to reset random address if privacy is enabled */
+ if (btm_cb.ble_ctr_cb.privacy && /* own addr_type is random */
+ !BTM_BLE_IS_RESOLVE_BDA(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr))
+ {
+ /* need to generate RRA and update random addresss in controller */
+ btm_gen_resolvable_private_addr();
+ }
+#endif
}
return evt_type;
@@ -704,7 +875,7 @@
{
tBTM_BLE_LOCAL_ADV_DATA *p_cb_data = &btm_cb.ble_ctr_cb.inq_var.adv_data;
UINT8 *p;
- UINT16 mask = data_mask;
+ tBTM_BLE_AD_MASK mask = data_mask;
BTM_TRACE_EVENT0 ("BTM_BleWriteAdvData ");
@@ -930,7 +1101,99 @@
return p_flag;
}
+/*******************************************************************************
+**
+** Function btm_ble_select_adv_interval
+**
+** Description select adv interval based on device mode
+**
+** Returns void
+**
+*******************************************************************************/
+void btm_ble_select_adv_interval(tBTM_BLE_INQ_CB *p_cb, UINT8 evt_type, UINT16 *p_adv_int_min, UINT16 *p_adv_int_max)
+{
+ if (p_cb->adv_interval_min && p_cb->adv_interval_max)
+ {
+ *p_adv_int_min = p_cb->adv_interval_min;
+ *p_adv_int_max = p_cb->adv_interval_max;
+ }
+ else
+ {
+ switch (evt_type)
+ {
+ case BTM_BLE_CONNECT_EVT:
+ *p_adv_int_min = *p_adv_int_max = BTM_BLE_GAP_ADV_FAST_INT_1;
+ break;
+ case BTM_BLE_NON_CONNECT_EVT:
+ case BTM_BLE_DISCOVER_EVT:
+ *p_adv_int_min = *p_adv_int_max = BTM_BLE_GAP_ADV_FAST_INT_2;
+ break;
+ /* connectable directed event */
+ case BTM_BLE_CONNECT_DIR_EVT:
+ *p_adv_int_min = BTM_BLE_GAP_ADV_DIR_MIN_INT;
+ *p_adv_int_max = BTM_BLE_GAP_ADV_DIR_MAX_INT;
+ break;
+
+ default:
+ *p_adv_int_min = *p_adv_int_max = BTM_BLE_GAP_ADV_SLOW_INT;
+ break;
+ }
+ }
+ return;
+}
+/*******************************************************************************
+**
+** Function btm_ble_set_adv_flag
+**
+** Description Set adv flag in adv data.
+**
+** Returns void
+**
+*******************************************************************************/
+void btm_ble_set_adv_flag(UINT16 connect_mode, UINT16 disc_mode)
+{
+ UINT8 flag = 0, old_flag = 0;
+ tBTM_BLE_LOCAL_ADV_DATA *p_adv_data = &btm_cb.ble_ctr_cb.inq_var.adv_data;
+
+ if (p_adv_data->p_flags != NULL)
+ flag = old_flag = *(p_adv_data->p_flags);
+
+ /* BR/EDR non-discoverable , non-connectable */
+ if ((disc_mode & BTM_DISCOVERABLE_MASK) == 0 &&
+ (connect_mode & BTM_CONNECTABLE_MASK) == 0)
+ flag |= BTM_BLE_BREDR_NOT_SPT;
+ else
+ flag &= ~BTM_BLE_BREDR_NOT_SPT;
+
+ /* if local controller support, mark both controller and host support in flag */
+ if (HCI_SIMUL_LE_BREDR_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
+ flag |= (BTM_BLE_DMT_CONTROLLER_SPT|BTM_BLE_DMT_HOST_SPT);
+ else
+ flag &= ~(BTM_BLE_DMT_CONTROLLER_SPT|BTM_BLE_DMT_HOST_SPT);
+
+ BTM_TRACE_ERROR1("disc_mode %04x", disc_mode);
+ /* update discoverable flag */
+ if (disc_mode & BTM_BLE_LIMITED_DISCOVERABLE)
+ {
+ flag &= ~BTM_BLE_GEN_DISC_FLAG;
+ flag |= BTM_BLE_LIMIT_DISC_FLAG ;
+ }
+ else if (disc_mode & BTM_BLE_GENERAL_DISCOVERABLE)
+ {
+ flag |= BTM_BLE_GEN_DISC_FLAG;
+ flag &= ~BTM_BLE_LIMIT_DISC_FLAG;
+ }
+ else /* remove all discoverable flags */
+ {
+ flag &= ~(BTM_BLE_LIMIT_DISC_FLAG|BTM_BLE_GEN_DISC_FLAG);
+ }
+
+ if (flag != old_flag)
+ {
+ btm_ble_update_adv_flag(flag);
+ }
+}
/*******************************************************************************
**
** Function btm_ble_set_discoverability
@@ -947,7 +1210,6 @@
tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
UINT16 mode = (combined_mode & BTM_BLE_DISCOVERABLE_MASK);
- UINT8 flag = 0;
UINT8 new_mode = BTM_BLE_ADV_ENABLE;
UINT8 evt_type = (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE) ? \
((p_cb->scan_rsp) ? BTM_BLE_DISCOVER_EVT : BTM_BLE_NON_CONNECT_EVT )\
@@ -955,7 +1217,8 @@
tBTM_STATUS status = BTM_SUCCESS;
BD_ADDR p_addr_ptr= {0};
tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC,
- own_addr_type = p_addr_cb->own_addr_type;;
+ own_addr_type = p_addr_cb->own_addr_type;
+ UINT16 adv_int_min, adv_int_max;
BTM_TRACE_EVENT2 ("btm_ble_set_discoverability mode=0x%0x combined_mode=0x%x", mode, combined_mode);
@@ -963,56 +1226,28 @@
if (mode > BTM_BLE_MAX_DISCOVERABLE)
return(BTM_ILLEGAL_VALUE);
- p_cb->br_edr_supported_flag |= (combined_mode & BTM_DISCOVERABLE_MASK);
- p_cb->discoverable_mode = mode;
+ btm_ble_set_adv_flag (btm_cb.btm_inq_vars.connectable_mode, combined_mode);
- if (!p_cb->br_edr_supported_flag)
- {
- flag = BTM_BLE_BREDR_NOT_SPT;
- BTM_TRACE_DEBUG1("btm_ble_set_discoverability (BREDR not sup)flag=0x%x",flag);
- }
+ evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type);
- BTM_TRACE_DEBUG1 ("br_edr_supported=0x%x", p_cb->br_edr_supported_flag);
+ if (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE && mode == BTM_BLE_NON_DISCOVERABLE)
+ new_mode = BTM_BLE_ADV_DISABLE;
- if (mode == BTM_BLE_LIMITED_DISCOVERABLE || mode == BTM_BLE_GENERAL_DISCOVERABLE)
- {
- BTM_TRACE_EVENT0 ("mode == BTM_BLE_LIMITED_DISCOVERABLE ");
- /* write ADV data with limited disc flag */
- if (mode == BTM_BLE_LIMITED_DISCOVERABLE)
- flag |= BTM_BLE_LIMIT_DISC_FLAG ;
- else
- flag |= BTM_BLE_GEN_DISC_FLAG;
- }
- else /* non-discoverable */
- {
- BTM_TRACE_EVENT0 ("mode == BTM_BLE_NON_DISCOVERABLE ");
+ btm_ble_select_adv_interval(p_cb, evt_type, &adv_int_min, &adv_int_max);
- if (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE)
- {
- p_cb->br_edr_supported_flag = 0;
-
- BTM_TRACE_EVENT0 ("always disable adv in non-discoverable non-connectable mode if no scan rsp ");
- if (!p_cb->scan_rsp )
- new_mode = BTM_BLE_ADV_DISABLE;
-
- }
- else
- {
- p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type);
- }
- }
- btm_ble_update_adv_flag(flag);
+ btu_stop_timer(&p_cb->fast_adv_timer);
/* update adv params if start advertising */
BTM_TRACE_EVENT2 ("evt_type=0x%x p-cb->evt_type=0x%x ", evt_type, p_cb->evt_type);
+
if (new_mode == BTM_BLE_ADV_ENABLE &&
- (evt_type != p_cb->evt_type ||p_cb->adv_addr_type != own_addr_type))
+ (evt_type != p_cb->evt_type ||p_cb->adv_addr_type != own_addr_type || !p_cb->fast_adv_on))
{
btm_ble_stop_adv();
/* update adv params */
- if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT),
- (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT),
+ if (!btsnd_hcic_ble_write_adv_params (adv_int_min,
+ adv_int_max,
evt_type,
own_addr_type,
init_addr_type,
@@ -1036,11 +1271,18 @@
else
status = btm_ble_stop_adv();
}
+ if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE)
+ {
+ p_cb->fast_adv_on = TRUE;
+ /* start initial GAP mode adv timer */
+ btu_start_timer (&p_cb->fast_adv_timer, BTU_TTYPE_BLE_GAP_FAST_ADV,
+ BTM_BLE_GAP_FAST_ADV_TOUT);
+ }
/* set up stop advertising timer */
if (status == BTM_SUCCESS && mode == BTM_BLE_LIMITED_DISCOVERABLE)
{
- BTM_TRACE_EVENT1 ("start timer for limited disc mode duration=%d (30 secs)", BTM_BLE_GAP_LIM_TOUT);
+ BTM_TRACE_EVENT1 ("start timer for limited disc mode duration=%d (180 secs)", BTM_BLE_GAP_LIM_TOUT);
/* start Tgap(lim_timeout) */
btu_start_timer (&p_cb->inq_timer_ent, BTU_TTYPE_BLE_GAP_LIM_DISC,
BTM_BLE_GAP_LIM_TOUT);
@@ -1064,57 +1306,39 @@
tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
UINT16 mode = (combined_mode & BTM_BLE_CONNECTABLE_MASK);
- UINT8 cur_flag = 0;
- UINT8 cur_br_edr_not_sup_flag;
- UINT8 new_flag;
UINT8 new_mode = BTM_BLE_ADV_ENABLE;
UINT8 evt_type = (p_cb->scan_rsp) ? BTM_BLE_DISCOVER_EVT: BTM_BLE_NON_CONNECT_EVT;
tBTM_STATUS status = BTM_SUCCESS;
BD_ADDR p_addr_ptr = {0};
tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC,
own_addr_type = p_addr_cb->own_addr_type;
+ UINT16 adv_int_min, adv_int_max;
BTM_TRACE_EVENT2 ("btm_ble_set_connectability mode=0x%0x combined_mode=0x%x", mode, combined_mode);
+
/*** Check mode parameter ***/
if (mode > BTM_BLE_MAX_CONNECTABLE)
return(BTM_ILLEGAL_VALUE);
- if (btm_cb.ble_ctr_cb.inq_var.adv_data.p_flags)
- cur_flag = *btm_cb.ble_ctr_cb.inq_var.adv_data.p_flags ;
- cur_br_edr_not_sup_flag = (cur_flag & ((UINT8) BTM_BLE_BREDR_NOT_SPT));
- p_cb->br_edr_supported_flag |= ((combined_mode & BTM_CONNECTABLE_MASK) << 4);
- if (p_cb->br_edr_supported_flag && cur_br_edr_not_sup_flag)
- {
- new_flag = cur_flag & ((UINT8) (~BTM_BLE_BREDR_NOT_SPT));
- BTM_TRACE_EVENT2 ("new flag=0x%x cur flag=0x%x",new_flag, cur_flag);
- btm_ble_update_adv_flag(new_flag);
- }
p_cb->connectable_mode = mode;
- if (mode == BTM_BLE_NON_CONNECTABLE)
- {
- if (p_cb->discoverable_mode == BTM_BLE_NON_DISCOVERABLE)
- {
- p_cb->br_edr_supported_flag = 0;
- BTM_TRACE_EVENT0 ("always disable adv in non-discoverable non-connectable mode with no scan rsp");
- if(!p_cb->scan_rsp)
- new_mode = BTM_BLE_ADV_DISABLE;
+ btm_ble_set_adv_flag (combined_mode, btm_cb.btm_inq_vars.discoverable_mode);
- }
- }
- else /* connectable */
- {
- evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type);
- }
+ evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type);
+ if (mode == BTM_BLE_NON_CONNECTABLE && p_cb->discoverable_mode == BTM_BLE_NON_DISCOVERABLE)
+ new_mode = BTM_BLE_ADV_DISABLE;
+
+ btm_ble_select_adv_interval(p_cb, evt_type, &adv_int_min, &adv_int_max);
+
+ btu_stop_timer(&p_cb->fast_adv_timer);
/* update adv params if needed */
- if ((p_cb->evt_type != evt_type || p_cb->adv_addr_type != p_addr_cb->own_addr_type)
- && new_mode == BTM_BLE_ADV_ENABLE)
+ if ((p_cb->evt_type != evt_type || p_cb->adv_addr_type != p_addr_cb->own_addr_type || !p_cb->fast_adv_on))
{
btm_ble_stop_adv();
- if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT),
- (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT),
+ if (!btsnd_hcic_ble_write_adv_params (adv_int_min,
+ adv_int_max,
evt_type,
own_addr_type,
init_addr_type,
@@ -1132,24 +1356,22 @@
/* update advertising mode */
if (status == BTM_SUCCESS && new_mode != p_cb->adv_mode)
{
- if (btsnd_hcic_ble_set_adv_enable (new_mode))
- {
- status = BTM_SUCCESS;
-
- p_cb->adv_mode = new_mode;
-
- if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE &&
- p_cb->afp != AP_SCAN_CONN_ALL)
- btm_cb.ble_ctr_cb.wl_state |= BTM_BLE_WL_ADV;
- else
- btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV;
-
- }
+ if (new_mode == BTM_BLE_ADV_ENABLE)
+ status = btm_ble_start_adv();
+ else
+ status = btm_ble_stop_adv();
}
-
+ if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE)
+ {
+ p_cb->fast_adv_on = TRUE;
+ /* start initial GAP mode adv timer */
+ btu_start_timer (&p_cb->fast_adv_timer, BTU_TTYPE_BLE_GAP_FAST_ADV,
+ BTM_BLE_GAP_FAST_ADV_TOUT);
+ }
return status;
}
+
/*******************************************************************************
**
** Function btm_ble_start_inquiry
@@ -1171,24 +1393,32 @@
*******************************************************************************/
tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8 duration)
{
- tBTM_STATUS status = BTM_NO_RESOURCES;
- tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
+ tBTM_STATUS status = BTM_CMD_STARTED;
+ tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
+ tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
- BTM_TRACE_DEBUG2("btm_ble_start_inquiry: mode = %02x inq_active = %d", mode, btm_cb.btm_inq_vars.inq_active);
+ BTM_TRACE_DEBUG2("btm_ble_start_inquiry: mode = %02x inq_active = 0x%02x", mode, btm_cb.btm_inq_vars.inq_active);
- if (p_inq->proc_mode != BTM_BLE_INQUIRY_NONE)
+ /* if selective connection is active, or inquiry is already active, reject it */
+ if (BTM_BLE_IS_INQ_ACTIVE(p_ble_cb->scan_activity) ||
+ BTM_BLE_IS_SEL_CONN_ACTIVE (p_ble_cb->scan_activity))
{
- BTM_TRACE_ERROR0("LE scan is active, can not start inquiry");
+ BTM_TRACE_ERROR0("LE Inquiry is active, can not start inquiry");
return(BTM_BUSY);
}
- btm_update_scanner_filter_policy(SP_ADV_ALL);
-
- /* start scan, already enable duplicate filtering */
- if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE))
+ if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity))
{
- status = BTM_CMD_STARTED;
- p_inq->proc_mode = mode;
+ btm_update_scanner_filter_policy(SP_ADV_ALL);
+ status = btm_ble_start_scan(BTM_BLE_DUPLICATE_DISABLE);
+ }
+
+ if (status == BTM_CMD_STARTED)
+ {
+ p_inq->inq_active |= mode;
+ p_ble_cb->scan_activity |= mode;
+
+ BTM_TRACE_DEBUG1("btm_ble_start_inquiry inq_active = 0x%02x", p_inq->inq_active);
if (duration != 0)
{
@@ -1198,6 +1428,7 @@
}
return status;
+
}
/*******************************************************************************
@@ -1508,68 +1739,54 @@
** Returns void
**
*******************************************************************************/
-BOOLEAN btm_ble_is_discoverable(BD_ADDR bda, UINT8 evt_type, UINT8 *p)
+UINT8 btm_ble_is_discoverable(BD_ADDR bda, UINT8 evt_type, UINT8 *p)
{
- BOOLEAN is_discoverable = FALSE;
- UINT8 *p_flag, flag = 0;
+ UINT8 *p_flag, flag = 0, rt = 0;
UINT8 data_len;
tBTM_INQ_PARMS *p_cond = &btm_cb.btm_inq_vars.inqparms;
+ tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
- STREAM_TO_UINT8 (data_len, p);
+ UNUSED(p);
/* for observer, always "discoverable */
- if (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_OBSERVE ||
- (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_SELECT_SCAN &&
- btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE))
- return TRUE;
+ if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity))
+ rt |= BTM_BLE_OBS_RESULT;
+
+ if (BTM_BLE_IS_SEL_CONN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity) &&
+ (evt_type == BTM_BLE_CONNECT_EVT || evt_type == BTM_BLE_CONNECT_DIR_EVT))
+ rt |= BTM_BLE_SEL_CONN_RESULT;
/* does not match filter condition */
if (p_cond->filter_cond_type == BTM_FILTER_COND_BD_ADDR &&
memcmp(bda, p_cond->filter_cond.bdaddr_cond, BD_ADDR_LEN) != 0)
{
BTM_TRACE_DEBUG0("BD ADDR does not meet filter condition");
- return FALSE;
+ return rt;
}
- /* scan response does not include the flag */
- if (evt_type == BTM_BLE_SCAN_RSP_EVT)
- return FALSE;
-
- if (data_len > BTM_BLE_ADV_DATA_LEN_MAX)
+ if (p_le_inq_cb->adv_len != 0)
{
- BTM_TRACE_WARNING1("ADV data too long %d. discard", data_len);
- return FALSE;
- }
-
- if (data_len != 0)
- {
- if ((p_flag = BTM_CheckAdvData(p, BTM_BLE_AD_TYPE_FLAG, &data_len)) != NULL)
+ if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache,
+ BTM_BLE_AD_TYPE_FLAG, &data_len)) != NULL)
{
flag = * p_flag;
- if ((btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_GENERAL_INQUIRY) &&
+ if ((btm_cb.btm_inq_vars.inq_active & BTM_BLE_GENERAL_INQUIRY) &&
(flag & (BTM_BLE_LIMIT_DISC_FLAG|BTM_BLE_GEN_DISC_FLAG)) != 0)
{
BTM_TRACE_DEBUG0("Find Generable Discoverable device");
- is_discoverable = TRUE;
+ rt |= BTM_BLE_INQ_RESULT;
}
- else if (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_LIMITED_INQUIRY &&
+ else if (btm_cb.btm_inq_vars.inq_active & BTM_BLE_LIMITED_INQUIRY &&
(flag & BTM_BLE_LIMIT_DISC_FLAG) != 0)
{
BTM_TRACE_DEBUG0("Find limited discoverable device");
- is_discoverable = TRUE;
+ rt |= BTM_BLE_INQ_RESULT;
}
-
}
}
-
- if (!is_discoverable)
- {
- BTM_TRACE_ERROR1("discoverable flag not desired: %d", flag);
- }
-
- return is_discoverable;
+ return rt;
}
/*******************************************************************************
@@ -1742,7 +1959,7 @@
BD_ADDR bda;
UINT8 evt_type = 0, *p = p_data;
UINT8 addr_type = 0;
-#if (defined BTM_BLE_PRIVACY_SPT && BTM_BLE_PRIVACY_SPT == TRUE)
+#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
BOOLEAN match = FALSE;
#endif
@@ -1765,15 +1982,12 @@
/* Only process the results if the inquiry is still active */
- if ((btm_cb.btm_inq_vars.inq_active & BTM_LE_SCAN_ACTIVE_MASK) == 0 &&
- (btm_cb.ble_ctr_cb.bg_conn_type != BTM_BLE_CONN_SELECTIVE ||
- /* or selective auto connection is active */
- btm_cb.ble_ctr_cb.p_select_cback == NULL))
+ if (!BTM_BLE_IS_SCAN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity))
return;
BTM_TRACE_DEBUG6("btm_ble_process_adv_pkt:bda= %0x:%0x:%0x:%0x:%0x:%0x",
bda[0],bda[1],bda[2],bda[3],bda[4],bda[5]);
-#if (defined BTM_BLE_PRIVACY_SPT && BTM_BLE_PRIVACY_SPT == TRUE)
+#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
#if SMP_INCLUDED == TRUE
/* always do RRA resolution on host */
if (!match && BTM_BLE_IS_RESOLVE_BDA(bda))
@@ -1803,13 +2017,12 @@
static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt_type, UINT8 *p)
{
tINQ_DB_ENT *p_i;
- BOOLEAN to_report = FALSE;
- BOOLEAN to_report_LE = TRUE; //var for reporting to LE observe
tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
tBTM_INQ_RESULTS_CB *p_inq_results_cb = p_inq->p_inq_results_cb;
- tBTM_INQ_RESULTS_CB *p_inq_ble_results_cb = p_inq->p_inq_ble_results_cb;
+ tBTM_INQ_RESULTS_CB *p_obs_results_cb = btm_cb.ble_ctr_cb.p_obs_results_cb;
tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
- BTM_TRACE_DEBUG2("btm_ble_process_adv_pkt_cont: addr_type: %d, evt_type: %d", addr_type, evt_type);
+ BOOLEAN update = TRUE;
+ UINT8 result = 0;
p_i = btm_inq_db_find (bda);
@@ -1817,26 +2030,23 @@
if (btm_inq_find_bdaddr(bda))
{
/* never been report as an LE device */
- if ((p_i &&
+ if (p_i &&
(!(p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BLE) ||
/* scan repsonse to be updated */
(!p_i->scan_rsp)))
- ||
- btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_OBSERVE)
{
- BTM_TRACE_DEBUG0("update new BLE information ");
- to_report = TRUE;
+ update = TRUE;
+ }
+ else if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity))
+ {
+ update = FALSE;
}
else
{
- to_report = FALSE;
+ /* if yes, skip it */
+ return; /* assumption: one result per event */
}
}
- else /* not been processed in this round */
- {
- to_report = TRUE;
- }
-
/* If existing entry, use that, else get a new one (possibly reusing the oldest) */
if (p_i == NULL)
{
@@ -1846,25 +2056,22 @@
}
else
return;
-
- if (to_report && btm_ble_is_discoverable(bda, evt_type, p))
- {
- to_report = TRUE;
- }
- else
- {
- BTM_TRACE_ERROR0("discard adv pkt");
- to_report = FALSE;
- }
}
else if (p_i->inq_count != p_inq->inq_counter) /* first time seen in this inquiry */
{
p_inq->inq_cmpl_info.num_resp++;
}
/* update the LE device information in inquiry database */
- to_report_LE = btm_ble_update_inq_result(p_i, addr_type, evt_type, p);
- if (to_report)
- to_report = to_report_LE;
+ if (!btm_ble_update_inq_result(p_i, addr_type, evt_type, p))
+ return;
+
+ if ((result = btm_ble_is_discoverable(bda, evt_type, p)) == 0)
+ {
+ BTM_TRACE_ERROR0("discard adv pkt");
+ return;
+ }
+ if (!update)
+ result &= ~BTM_BLE_INQ_RESULT;
#if BTM_USE_INQ_RESULTS_FILTER == TRUE
/* If the number of responses found and limited, issue a cancel inquiry */
if (p_inq->inqparms.max_resps &&
@@ -1882,8 +2089,7 @@
(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) == 0)
btsnd_hcic_inq_cancel();
- /* stop LE scan now */
- btm_ble_stop_scan();
+ btm_ble_stop_inquiry();
#if BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE
btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT);
@@ -1891,32 +2097,58 @@
}
}
#endif
-
- BTM_TRACE_DEBUG2("btm_ble_process_adv_pkt_cont: to_report =%d, to_report_le=%d",
- to_report, to_report_LE);
/* background connection in selective connection mode */
if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE)
{
- if (p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BLE &&
- (evt_type == BTM_BLE_CONNECT_EVT || evt_type == BTM_BLE_CONNECT_DIR_EVT))
+ if (result & BTM_BLE_SEL_CONN_RESULT)
btm_send_sel_conn_callback(bda, evt_type, p, addr_type);
else
{
BTM_TRACE_DEBUG0("None LE device, can not initiate selective connection");
}
}
- else if (to_report || to_report_LE)
+ else
{
- if(p_inq_results_cb && to_report)
+ if (p_inq_results_cb && (result & BTM_BLE_INQ_RESULT))
+ {
(p_inq_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
- if(p_inq_ble_results_cb && to_report_LE)
- (p_inq_ble_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results,
- p_le_inq_cb->adv_data_cache);
+ }
+ if (p_obs_results_cb && (result & BTM_BLE_OBS_RESULT))
+ {
+ (p_obs_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
+ }
}
}
/*******************************************************************************
**
+** Function btm_ble_start_scan
+**
+** Description Start the BLE scan.
+**
+** Returns void
+**
+*******************************************************************************/
+tBTM_STATUS btm_ble_start_scan (UINT8 filter_enable)
+{
+ tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
+ tBTM_STATUS status = BTM_CMD_STARTED;
+
+ /* start scan, disable duplicate filtering */
+ if (!btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, filter_enable))
+ status = BTM_NO_RESOURCES;
+ else
+ {
+ if (p_inq->scan_type == BTM_BLE_SCAN_MODE_ACTI)
+ btm_ble_set_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT);
+ else
+ btm_ble_set_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT);
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
** Function btm_ble_stop_scan
**
** Description Stop the BLE scan.
@@ -1926,44 +2158,135 @@
*******************************************************************************/
void btm_ble_stop_scan(void)
{
- tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
- tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
-
BTM_TRACE_EVENT0 ("btm_ble_stop_scan ");
- btu_stop_timer (&p_cb->inq_timer_ent);
-
/* Clear the inquiry callback if set */
- p_cb->scan_type = BTM_BLE_SCAN_MODE_NONE;
- p_cb->proc_mode = BTM_BLE_INQUIRY_NONE;
+ btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
/* stop discovery now */
btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
+ btm_update_scanner_filter_policy(SP_ADV_ALL);
+}
+/*******************************************************************************
+**
+** Function btm_ble_stop_inquiry
+**
+** Description Stop the BLE Inquiry.
+**
+** Returns void
+**
+*******************************************************************************/
+void btm_ble_stop_inquiry(void)
+{
+ tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
+ tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
+
+ btu_stop_timer (&p_ble_cb->inq_var.inq_timer_ent);
+
+ p_ble_cb->scan_activity &= ~BTM_BLE_INQUIRY_MASK;
+
+ /* If no more scan activity, stop LE scan now */
+ if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity))
+ btm_ble_stop_scan();
+
/* If we have a callback registered for inquiry complete, call it */
BTM_TRACE_DEBUG2 ("BTM Inq Compl Callback: status 0x%02x, num results %d",
p_inq->inq_cmpl_info.status, p_inq->inq_cmpl_info.num_resp);
- btm_update_scanner_filter_policy(SP_ADV_ALL);
-
btm_process_inq_complete(HCI_SUCCESS, (UINT8)(p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK));
-
}
/*******************************************************************************
**
+** Function btm_ble_stop_observe
+**
+** Description Stop the BLE Observe.
+**
+** Returns void
+**
+*******************************************************************************/
+static void btm_ble_stop_observe(void)
+{
+ tBTM_BLE_CB *p_ble_cb = & btm_cb.ble_ctr_cb;
+ tBTM_CMPL_CB *p_obs_cb = p_ble_cb->p_obs_cmpl_cb;
+
+ btu_stop_timer (&p_ble_cb->obs_timer_ent);
+
+ p_ble_cb->scan_activity &= ~BTM_LE_OBSERVE_ACTIVE;
+
+ p_ble_cb->p_obs_results_cb = NULL;
+ p_ble_cb->p_obs_cmpl_cb = NULL;
+
+ if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity))
+ btm_ble_stop_scan();
+
+ if (p_obs_cb)
+ (p_obs_cb)((tBTM_INQUIRY_CMPL *) &btm_cb.btm_inq_vars.inq_cmpl_info);
+}
+/*******************************************************************************
+**
+** Function btm_ble_adv_states_operation
+**
+** Description Set or clear adv states in topology mask
+**
+** Returns operation status. TRUE if sucessful, FALSE otherwise.
+**
+*******************************************************************************/
+typedef BOOLEAN (BTM_TOPOLOGY_FUNC_PTR)(tBTM_BLE_STATE_MASK);
+static BOOLEAN btm_ble_adv_states_operation(BTM_TOPOLOGY_FUNC_PTR *p_handler, UINT8 adv_evt)
+{
+ BOOLEAN rt = FALSE;
+
+ switch (adv_evt)
+ {
+ case BTM_BLE_CONNECT_EVT:
+ rt = (*p_handler)(BTM_BLE_STATE_CONN_ADV_BIT);
+ break;
+
+ case BTM_BLE_NON_CONNECT_EVT:
+ rt = (*p_handler) (BTM_BLE_STATE_NON_CONN_ADV_BIT);
+ break;
+ case BTM_BLE_CONNECT_DIR_EVT:
+ rt = (*p_handler) (BTM_BLE_STATE_HI_DUTY_DIR_ADV_BIT);
+ break;
+
+ case BTM_BLE_DISCOVER_EVT:
+ rt = (*p_handler) (BTM_BLE_STATE_SCAN_ADV_BIT);
+ break;
+
+ default:
+ BTM_TRACE_ERROR1("unknown adv event : %d", adv_evt);
+ break;
+ }
+
+ return rt;
+}
+
+
+/*******************************************************************************
+**
** Function btm_ble_start_adv
**
-** Description Stop the BLE advertising.
+** Description start the BLE advertising.
**
** Returns void
**
*******************************************************************************/
-static tBTM_STATUS btm_ble_start_adv(void)
+tBTM_STATUS btm_ble_start_adv(void)
{
tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
tBTM_STATUS rt = BTM_NO_RESOURCES;
+ if (!btm_ble_adv_states_operation (btm_ble_topology_check, p_cb->evt_type))
+ return BTM_WRONG_MODE;
+
+ if (p_cb->afp != AP_SCAN_CONN_ALL)
+ {
+ btm_execute_wl_dev_operation();
+ btm_cb.ble_ctr_cb.wl_state |= BTM_BLE_WL_ADV;
+ }
+
if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_ENABLE))
{
if (p_cb->afp != AP_SCAN_CONN_ALL)
@@ -1972,13 +2295,13 @@
p_cb->adv_mode = BTM_BLE_ADV_ENABLE;
rt = BTM_SUCCESS;
- }
- else
- {
- p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
- btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV;
- }
- return rt;
+ }
+ else
+ {
+ p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
+ btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV;
+ }
+ return rt;
}
/*******************************************************************************
**
@@ -1989,7 +2312,7 @@
** Returns void
**
*******************************************************************************/
-static tBTM_STATUS btm_ble_stop_adv(void)
+tBTM_STATUS btm_ble_stop_adv(void)
{
tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
tBTM_STATUS rt = BTM_SUCCESS;
@@ -1998,16 +2321,141 @@
{
if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE))
{
+ p_cb->fast_adv_on = FALSE;
p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV;
+
+ /* clear all adv states */
+ btm_ble_clear_topology_mask (BTM_BLE_STATE_ALL_ADV_MASK);
}
else
rt = BTM_NO_RESOURCES;
}
return rt;
-
}
+
+/*******************************************************************************
+**
+** Function btm_ble_set_topology_mask
+**
+** Description set BLE topology mask
+**
+** Returns TRUE is request is allowed, FALSE otherwise.
+**
+*******************************************************************************/
+BOOLEAN btm_ble_set_topology_mask(tBTM_BLE_STATE_MASK request_state_mask)
+{
+ BOOLEAN rt = TRUE;
+
+ request_state_mask &= BTM_BLE_STATE_ALL_MASK;
+
+ btm_cb.ble_ctr_cb.cur_states |= request_state_mask;
+
+ return rt;
+}
+/*******************************************************************************
+**
+** Function btm_ble_clear_topology_mask
+**
+** Description Clear BLE topology bit mask
+**
+** Returns TRUE is request is allowed, FALSE otherwise.
+**
+*******************************************************************************/
+BOOLEAN btm_ble_clear_topology_mask (tBTM_BLE_STATE_MASK request_state_mask)
+{
+ request_state_mask &= BTM_BLE_STATE_ALL_MASK;
+
+ btm_cb.ble_ctr_cb.cur_states &= ~request_state_mask;
+
+ return TRUE;
+}
+/*******************************************************************************
+**
+** Function btm_ble_update_mode_operation
+**
+** Description This function update the GAP role operation when a link status
+** is updated.
+**
+** Returns void
+**
+*******************************************************************************/
+void btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bd_addr, BOOLEAN conn_cancel)
+{
+ tACL_CONN *pa = &btm_cb.acl_db[0];
+ UINT16 xx;
+ UINT16 mask = BTM_BLE_STATE_ALL_CONN_MASK;
+
+ UNUSED(bd_addr);
+ UNUSED (conn_cancel);
+
+ if (link_role == HCI_ROLE_SLAVE)
+ {
+ btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE;
+ /* clear all adv states */
+ mask |= BTM_BLE_STATE_ALL_ADV_MASK;
+ }
+
+ btm_ble_clear_topology_mask (mask);
+
+ /* check the device link role maps */
+ for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, pa++)
+ {
+ if (pa->in_use && pa->transport == BT_TRANSPORT_LE)
+ {
+ if (pa->link_role == HCI_ROLE_MASTER)
+ btm_ble_set_topology_mask (BTM_BLE_STATE_MASTER_BIT);
+ else
+ btm_ble_set_topology_mask (BTM_BLE_STATE_SLAVE_BIT);
+ }
+ }
+
+ if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE)
+ {
+ btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode );
+ }
+
+ if (btm_ble_get_conn_st() == BLE_CONN_IDLE)
+ {
+ if (!btm_send_pending_direct_conn())
+ {
+ btm_ble_resume_bg_conn();
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function btm_ble_start_slow_adv
+**
+** Description Restart adv with slow adv interval
+**
+** Returns void
+**
+*******************************************************************************/
+static void btm_ble_start_slow_adv (void)
+{
+ tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
+ BD_ADDR p_addr_ptr= {0};
+
+ if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE)
+ {
+ btm_ble_stop_adv();
+
+ btsnd_hcic_ble_write_adv_params (BTM_BLE_GAP_ADV_SLOW_INT,
+ BTM_BLE_GAP_ADV_SLOW_INT,
+ p_cb->evt_type,
+ p_cb->adv_addr_type,
+ btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type,/* slow adv
+ mode never goes into directed adv */
+ p_addr_ptr,
+ p_cb->adv_chnl_map,
+ p_cb->afp);
+
+ btm_ble_start_adv();
+ }
+}
/*******************************************************************************
**
** Function btm_ble_timeout
@@ -2019,17 +2467,23 @@
*******************************************************************************/
void btm_ble_timeout(TIMER_LIST_ENT *p_tle)
{
+ BTM_TRACE_EVENT0 ("btm_ble_timeout");
+
switch (p_tle->event)
{
+ case BTU_TTYPE_BLE_OBSERVE:
+ btm_ble_stop_observe();
+ break;
+
case BTU_TTYPE_BLE_INQUIRY:
- btm_ble_stop_scan();
+ btm_ble_stop_inquiry();
break;
case BTU_TTYPE_BLE_GAP_LIM_DISC:
/* lim_timeout expiried, limited discovery should exit now */
- btm_ble_update_adv_flag(BTM_BLE_NON_LIMIT_DISC_FLAG);
+ btm_cb.btm_inq_vars.discoverable_mode &= ~BTM_BLE_LIMITED_DISCOVERABLE;
- btm_ble_stop_adv();
+ btm_ble_set_adv_flag(btm_cb.btm_inq_vars.connectable_mode, btm_cb.btm_inq_vars.discoverable_mode);
break;
case BTU_TTYPE_BLE_RANDOM_ADDR:
@@ -2040,6 +2494,14 @@
}
break;
+ case BTU_TTYPE_BLE_GAP_FAST_ADV:
+ /* fast adv is completed, fall back to slow adv interval */
+ btm_ble_start_slow_adv();
+ break;
+
+ default:
+ break;
+
}
}
@@ -2058,13 +2520,13 @@
void btm_ble_read_remote_features_complete(UINT8 *p)
{
tACL_CONN *p_acl_cb = &btm_cb.acl_db[0];
- UINT8 status;
UINT16 handle;
int xx;
BTM_TRACE_EVENT0 ("btm_ble_read_remote_features_complete ");
- STREAM_TO_UINT8 (status, p);
+ /* Skip status */
+ p++;
STREAM_TO_UINT16 (handle, p);
/* Look up the connection by handle and copy features */
@@ -2076,6 +2538,7 @@
break;
}
}
+
}
/*******************************************************************************
@@ -2120,58 +2583,6 @@
/*******************************************************************************
**
-** Function btm_ble_update_mode_operation
-**
-** Description This function update the GAP role operation when a link status
-** is updated.
-**
-** Returns void
-**
-*******************************************************************************/
-void btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bd_addr, BOOLEAN conn_cancel)
-{
- tACL_CONN *pa = &btm_cb.acl_db[0];
- UINT16 xx;
- UINT8 dev_role = link_role;
- UNUSED(bd_addr);
- UNUSED(conn_cancel);
-
- BTM_TRACE_DEBUG1("btm_ble_update_mode_operation adv_mode = %d", btm_cb.ble_ctr_cb.inq_var.adv_mode );
-
- /* update periphera role operation */
- /* If we are LE connectable, check if we need to start advertising again */
- if (link_role == HCI_ROLE_UNKNOWN)
- /* && btm_cb.ble_ctr_cb.inq_var.connectable_mode != BTM_BLE_NON_CONNECTABLE) */
- {
- for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, pa++)
- {
- /* If any other LE link is up, we are still not connectable */
- if (pa->in_use && pa->is_le_link)
- {
- dev_role = pa->link_role;
- break;
- }
- }
- }
-
- if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE &&
- (dev_role == HCI_ROLE_UNKNOWN )) /* when device has no connection, update adv here */
- /* if already in connection, no connectable adv is allowed unless scatternet is enabled */
- {
- btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode );
- }
-
- if (btm_ble_get_conn_st() == BLE_CONN_IDLE)
- {
- if (!btm_send_pending_direct_conn())
- {
- btm_ble_resume_bg_conn();
- }
- }
-}
-
-/*******************************************************************************
-**
** Function btm_ble_init
**
** Description Initialize the control block variable values.
@@ -2186,6 +2597,7 @@
BTM_TRACE_EVENT0 ("btm_ble_init ");
memset(p_cb, 0, sizeof(tBTM_BLE_CB));
+ p_cb->cur_states = 0;
p_cb->inq_var.adv_mode = BTM_BLE_ADV_DISABLE;
p_cb->inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
@@ -2201,4 +2613,76 @@
p_cb->inq_var.evt_type = BTM_BLE_NON_CONNECT_EVT;
}
+/*******************************************************************************
+**
+** Function btm_ble_topology_check
+**
+** Description check to see requested state is supported. One state check at
+** a time is supported
+**
+** Returns TRUE is request is allowed, FALSE otherwise.
+**
+*******************************************************************************/
+BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request_state_mask)
+{
+ BOOLEAN rt = FALSE;
+ UINT32 llt_mask = 0;
+ UINT8 *p;
+
+ UINT8 state_offset = 0;
+ UINT16 cur_states = btm_cb.ble_ctr_cb.cur_states;
+ UINT8 mask, offset;
+ UINT8 request_state = 0;
+
+ /* check only one bit is set and within valid range */
+ if (request_state_mask == BTM_BLE_STATE_INVALID ||
+ request_state_mask > BTM_BLE_STATE_SCAN_ADV_BIT ||
+ (request_state_mask & (request_state_mask -1 )) != 0)
+ {
+ BTM_TRACE_ERROR1("illegal state requested: %d", request_state_mask);
+ return rt;
+ }
+
+ while (request_state_mask)
+ {
+ request_state_mask >>= 1;
+ request_state ++;
+ }
+
+ /* check if the requested state is supported or not */
+ mask = btm_le_state_combo_tbl[0][request_state - 1][0];
+ offset = btm_le_state_combo_tbl[0][request_state-1][1];
+
+ if (!BTM_LE_STATES_SUPPORTED(btm_cb.devcb.le_supported_states, mask, offset))
+ {
+ BTM_TRACE_ERROR1("state requested not supported: %d", request_state);
+ return rt;
+ }
+
+ rt = TRUE;
+ /* make sure currently active states are all supported in conjunction with the requested
+ state. If the bit in table is not set, the combination is not supported */
+ while (cur_states != 0)
+ {
+ if (cur_states & 0x01)
+ {
+ mask = btm_le_state_combo_tbl[request_state][state_offset][0];
+ offset = btm_le_state_combo_tbl[request_state][state_offset][1];
+
+ if (mask != 0 && offset != 0)
+ {
+ if (!BTM_LE_STATES_SUPPORTED(btm_cb.devcb.le_supported_states, mask, offset))
+ {
+ rt = FALSE;
+ break;
+ }
+ }
+ }
+ cur_states >>= 1;
+ state_offset ++;
+ }
+ return rt;
+}
+
+
#endif /* BLE_INCLUDED */
diff --git a/stack/btm/btm_ble_int.h b/stack/btm/btm_ble_int.h
index 7a05507..f3cb771 100644
--- a/stack/btm/btm_ble_int.h
+++ b/stack/btm/btm_ble_int.h
@@ -61,9 +61,17 @@
#define BTM_BLE_GAP_DISC_SCAN_INT 18 /* Interval(scan_int) = 11.25 ms= 0x0010 * 0.625 ms */
#define BTM_BLE_GAP_DISC_SCAN_WIN 18 /* scan_window = 11.25 ms= 0x0010 * 0.625 ms */
#define BTM_BLE_GAP_ADV_INT 512 /* Tgap(gen_disc) = 1.28 s= 512 * 0.625 ms */
-#define BTM_BLE_GAP_LIM_TOUT 30 /* Tgap(lim_timeout) = 30.72 s max, round down to 30 */
+#define BTM_BLE_GAP_LIM_TOUT 180 /* Tgap(lim_timeout) = 180s max */
+#define BTM_BLE_GAP_ADV_FAST_INT_1 48 /* TGAP(adv_fast_interval1) = 30(used) ~ 60 ms = 48 *0.625 */
+#define BTM_BLE_GAP_ADV_FAST_INT_2 160 /* TGAP(adv_fast_interval2) = 100(used) ~ 150 ms = 160 * 0.625 ms */
+#define BTM_BLE_GAP_ADV_SLOW_INT 2048 /* Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */
+#define BTM_BLE_GAP_ADV_DIR_MAX_INT 800 /* Tgap(dir_conn_adv_int_max) = 500 ms = 800 * 0.625 ms */
+#define BTM_BLE_GAP_ADV_DIR_MIN_INT 400 /* Tgap(dir_conn_adv_int_min) = 250 ms = 400 * 0.625 ms */
+
+#define BTM_BLE_GAP_FAST_ADV_TOUT 30
+
#define BTM_BLE_SEC_REQ_ACT_NONE 0
#define BTM_BLE_SEC_REQ_ACT_ENCRYPT 1 /* encrypt the link using current key or key refresh */
#define BTM_BLE_SEC_REQ_ACT_PAIR 2
@@ -75,6 +83,16 @@
#define BLE_RESOLVE_ADDR_MASK 0xc0 /* bit 6, and bit7 */
#define BTM_BLE_IS_RESOLVE_BDA(x) ((x[0] & BLE_RESOLVE_ADDR_MASK) == BLE_RESOLVE_ADDR_MSB)
+/* LE scan activity bit mask, continue with LE inquiry bits */
+#define BTM_LE_SELECT_CONN_ACTIVE 0x40 /* selection connection is in progress */
+#define BTM_LE_OBSERVE_ACTIVE 0x80 /* observe is in progress */
+
+/* BLE scan activity mask checking */
+#define BTM_BLE_IS_SCAN_ACTIVE(x) ((x) & BTM_BLE_SCAN_ACTIVE_MASK)
+#define BTM_BLE_IS_INQ_ACTIVE(x) ((x) & BTM_BLE_INQUIRY_MASK)
+#define BTM_BLE_IS_OBS_ACTIVE(x) ((x) & BTM_LE_OBSERVE_ACTIVE)
+#define BTM_BLE_IS_SEL_CONN_ACTIVE(x) ((x) & BTM_LE_SELECT_CONN_ACTIVE)
+
typedef struct
{
UINT16 data_mask;
@@ -103,11 +121,6 @@
UINT16 discoverable_mode;
UINT16 connectable_mode;
- UINT16 br_edr_supported_flag; /* combined BR EDR discoverable and connectable mode */
- /* only meaningful when it is zero. This means
- BR EDR is not supported*/
- UINT8 proc_mode; /* current procedure mode : inquiry or discovery */
-
UINT16 scan_window;
UINT16 scan_interval;
UINT8 scan_type; /* current scan type: active or passive */
@@ -121,6 +134,8 @@
UINT8 adv_mode;
tBLE_BD_ADDR direct_bda;
BOOLEAN directed_conn;
+ BOOLEAN fast_adv_on;
+ TIMER_LIST_ENT fast_adv_timer;
UINT8 adv_len;
UINT8 adv_data_cache[BTM_BLE_CACHE_ADV_DATA_MAX];
@@ -148,8 +163,8 @@
/* random address management control block */
typedef struct
{
- tBLE_ADDR_TYPE own_addr_type; /* local device LE address type */
- BD_ADDR private_addr;
+ tBLE_ADDR_TYPE own_addr_type; /* local device LE address type */
+ BD_ADDR private_addr;
BD_ADDR random_bda;
BOOLEAN busy;
UINT16 index;
@@ -198,6 +213,37 @@
void *p_param;
}tBTM_BLE_CONN_REQ;
+/* LE state request */
+#define BTM_BLE_STATE_INVALID 0
+#define BTM_BLE_STATE_CONN_ADV 1
+#define BTM_BLE_STATE_INIT 2
+#define BTM_BLE_STATE_MASTER 3
+#define BTM_BLE_STATE_SLAVE 4
+#define BTM_BLE_STATE_LO_DUTY_DIR_ADV 5
+#define BTM_BLE_STATE_HI_DUTY_DIR_ADV 6
+#define BTM_BLE_STATE_NON_CONN_ADV 7
+#define BTM_BLE_STATE_PASSIVE_SCAN 8
+#define BTM_BLE_STATE_ACTIVE_SCAN 9
+#define BTM_BLE_STATE_SCAN_ADV 10
+#define BTM_BLE_STATE_MAX 11
+typedef UINT8 tBTM_BLE_STATE;
+
+#define BTM_BLE_STATE_CONN_ADV_BIT 0x0001
+#define BTM_BLE_STATE_INIT_BIT 0x0002
+#define BTM_BLE_STATE_MASTER_BIT 0x0004
+#define BTM_BLE_STATE_SLAVE_BIT 0x0008
+#define BTM_BLE_STATE_LO_DUTY_DIR_ADV_BIT 0x0010
+#define BTM_BLE_STATE_HI_DUTY_DIR_ADV_BIT 0x0020
+#define BTM_BLE_STATE_NON_CONN_ADV_BIT 0x0040
+#define BTM_BLE_STATE_PASSIVE_SCAN_BIT 0x0080
+#define BTM_BLE_STATE_ACTIVE_SCAN_BIT 0x0100
+#define BTM_BLE_STATE_SCAN_ADV_BIT 0x0200
+typedef UINT16 tBTM_BLE_STATE_MASK;
+
+#define BTM_BLE_STATE_ALL_MASK 0x03ff
+#define BTM_BLE_STATE_ALL_ADV_MASK (BTM_BLE_STATE_CONN_ADV_BIT|BTM_BLE_STATE_LO_DUTY_DIR_ADV_BIT|BTM_BLE_STATE_HI_DUTY_DIR_ADV_BIT|BTM_BLE_STATE_SCAN_ADV_BIT)
+#define BTM_BLE_STATE_ALL_SCAN_MASK (BTM_BLE_STATE_PASSIVE_SCAN_BIT|BTM_BLE_STATE_ACTIVE_SCAN_BIT)
+#define BTM_BLE_STATE_ALL_CONN_MASK (BTM_BLE_STATE_MASTER_BIT|BTM_BLE_STATE_SLAVE_BIT)
typedef struct
{
@@ -210,11 +256,18 @@
*/
typedef struct
{
+ UINT8 scan_activity; /* LE scan activity mask */
+
/*****************************************************
** BLE Inquiry
*****************************************************/
tBTM_BLE_INQ_CB inq_var;
+ /* observer callback and timer */
+ tBTM_INQ_RESULTS_CB *p_obs_results_cb;
+ tBTM_CMPL_CB *p_obs_cmpl_cb;
+ TIMER_LIST_ENT obs_timer_ent;
+
/* background connection procedure cb value */
tBTM_BLE_CONN_TYPE bg_conn_type;
UINT16 scan_int;
@@ -236,12 +289,18 @@
tBTM_LE_RANDOM_CB addr_mgnt_cb;
BOOLEAN enabled;
+#if BLE_PRIVACY_SPT == TRUE
+ BOOLEAN privacy; /* privacy enabled or disabled */
+#endif
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
+ /* current BLE link state */
+ tBTM_BLE_STATE_MASK cur_states; /* bit mask of tBTM_BLE_STATE */
+
} tBTM_BLE_CB;
#ifdef __cplusplus
@@ -259,15 +318,20 @@
extern tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8 duration);
extern void btm_ble_dir_adv_tout(void);
-extern void btm_ble_stop_scan(void);
-extern void btm_ble_att_db_init(void);
+extern void btm_ble_stop_scan();
+extern void btm_ble_stop_inquiry(void);
extern void btm_ble_init (void);
extern void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role, tBLE_ADDR_TYPE addr_type, BOOLEAN addr_matched);
extern void btm_ble_read_remote_features_complete(UINT8 *p);
extern void btm_ble_write_adv_enable_complete(UINT8 * p);
extern void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len);
+extern void btm_read_ble_local_supported_states_complete(UINT8 *p, UINT16 evt_len);
extern tBTM_BLE_CONN_ST btm_ble_get_conn_st(void);
extern void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st);
+extern tBTM_STATUS btm_ble_start_adv(void);
+extern tBTM_STATUS btm_ble_stop_adv(void);
+extern tBTM_STATUS btm_ble_start_scan (UINT8 filter_enb);
+
/* LE security function from btm_sec.c */
@@ -277,7 +341,7 @@
extern UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data);
extern tBTM_STATUS btm_ble_set_encryption (BD_ADDR bd_addr, void *p_ref_data, UINT8 link_role);
extern void btm_ble_ltk_request(UINT16 handle, UINT8 rand[8], UINT16 ediv);
-extern BOOLEAN btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk);
+extern tBTM_STATUS btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk);
extern void btm_ble_link_encrypted(BD_ADDR bd_addr, UINT8 encr_enable);
#endif
@@ -312,6 +376,7 @@
extern UINT8 btm_ble_count_unconn_dev_in_whitelist(void);
extern void btm_write_dir_conn_wl(BD_ADDR target_addr);
extern void btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bda, BOOLEAN conn_ccancel);
+extern BOOLEAN btm_execute_wl_dev_operation(void);
/* direct connection utility */
extern BOOLEAN btm_send_pending_direct_conn(void);
@@ -322,6 +387,9 @@
extern void btm_gen_non_resolvable_private_addr (tBTM_BLE_ADDR_CBACK *p_cback, void *p);
extern void btm_ble_resolve_random_addr(BD_ADDR random_bda, tBTM_BLE_RESOLVE_CBACK * p_cback, void *p);
extern void btm_ble_update_reconnect_address(BD_ADDR bd_addr);
+extern BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request);
+extern BOOLEAN btm_ble_clear_topology_mask(tBTM_BLE_STATE_MASK request_state);
+extern BOOLEAN btm_ble_set_topology_mask(tBTM_BLE_STATE_MASK request_state);
#if BTM_BLE_CONFORMANCE_TESTING == TRUE
BT_API extern void btm_ble_set_no_disc_if_pair_fail (BOOLEAN disble_disc);
diff --git a/stack/btm/btm_dev.c b/stack/btm/btm_dev.c
index 0dd534c..fbf4df1 100644
--- a/stack/btm/btm_dev.c
+++ b/stack/btm/btm_dev.c
@@ -64,6 +64,7 @@
int i, j;
BOOLEAN found = FALSE;
+ BTM_TRACE_API2("%s, link key type:%x", __FUNCTION__,key_type);
p_dev_rec = btm_find_dev (bd_addr);
if (!p_dev_rec)
{
@@ -79,7 +80,7 @@
memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC));
p_dev_rec->sec_flags = BTM_SEC_IN_USE;
memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
- p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr);
+ p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR);
#if BLE_INCLUDED == TRUE
/* use default value for background connection params */
@@ -172,7 +173,7 @@
{
tBTM_SEC_DEV_REC *p_dev_rec;
- if (BTM_IsAclConnectionUp(bd_addr))
+ if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) || BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR))
{
BTM_TRACE_WARNING0("BTM_SecDeleteDevice FAILED: Cannot Delete when connection is active");
return(FALSE);
@@ -215,9 +216,9 @@
** Function btm_sec_alloc_dev
**
** Description Look for the record in the device database for the record
-** with specified handle
+** with specified address
**
-** Returns Pointer to the record
+** Returns Pointer to the record or NULL
**
*******************************************************************************/
tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr)
@@ -278,7 +279,10 @@
memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
- p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr);
+#if BLE_INCLUDED == TRUE
+ p_dev_rec->ble_hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_LE);
+#endif
+ p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR);
p_dev_rec->timestamp = btm_cb.dev_rec_count++;
return(p_dev_rec);
@@ -376,7 +380,11 @@
for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
{
if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE)
- && (p_dev_rec->hci_handle == handle))
+ && ((p_dev_rec->hci_handle == handle)
+#if BLE_INCLUDED == TRUE
+ ||(p_dev_rec->ble_hci_handle == handle)
+#endif
+ ))
return(p_dev_rec);
}
return(NULL);
@@ -440,7 +448,7 @@
** the oldest non-paired device. If all devices are paired it
** deletes the oldest paired device.
**
-** Returns Pointer to the record
+** Returns Pointer to the record or NULL
**
*******************************************************************************/
tBTM_SEC_DEV_REC *btm_find_oldest_dev (void)
@@ -454,7 +462,7 @@
for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
{
if (((p_dev_rec->sec_flags & BTM_SEC_IN_USE) == 0)
- || ((p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN) != 0))
+ || ((p_dev_rec->sec_flags & (BTM_SEC_LINK_KEY_KNOWN |BTM_SEC_LE_LINK_KEY_KNOWN)) != 0))
continue; /* Device is paired so skip it */
if (p_dev_rec->timestamp < ot)
diff --git a/stack/btm/btm_devctl.c b/stack/btm/btm_devctl.c
index 240bd2f..8117c45 100644
--- a/stack/btm/btm_devctl.c
+++ b/stack/btm/btm_devctl.c
@@ -483,6 +483,25 @@
/* Send a Read Local Supported Features message to the Host Controller. */
btsnd_hcic_ble_read_local_spt_feat ();
}
+
+/*******************************************************************************
+**
+** Function btm_read_ble_local_supported_states
+**
+** Description Local function called to send a read BLE local supported
+** features command
+**
+** Returns void
+**
+*******************************************************************************/
+static void btm_read_ble_local_supported_states(void)
+{
+ BTM_TRACE_DEBUG0("btm_read_ble_local_supported_states ");
+ btu_start_timer (&btm_cb.devcb.reset_timer, BTU_TTYPE_BTM_DEV_CTL, BTM_DEV_REPLY_TIMEOUT);
+
+ /* Send a Read Local Supported states message to the Host Controller. */
+ btsnd_hcic_ble_read_supported_states ();
+}
#endif
/*******************************************************************************
**
@@ -808,6 +827,36 @@
l2c_link_processs_ble_num_bufs (lm_num_le_bufs);
}
+ btm_read_ble_local_supported_states();
+}
+/*******************************************************************************
+**
+** Function btm_read_ble_local_supported_states_complete
+**
+** Description This function is called when command complete for
+** Read LE Local Supported states complete is received.
+**
+** Returns void
+**
+*******************************************************************************/
+void btm_read_ble_local_supported_states_complete (UINT8 *p, UINT16 evt_len)
+{
+ UINT8 status;
+
+ UNUSED(evt_len);
+ BTM_TRACE_DEBUG0("btm_read_ble_local_supported_states_complete ");
+
+ btu_stop_timer (&btm_cb.devcb.reset_timer);
+
+ STREAM_TO_UINT8 (status, p);
+ if (status == HCI_SUCCESS)
+ {
+ STREAM_TO_ARRAY(&btm_cb.devcb.le_supported_states, p, BTM_LE_SUPPORT_STATE_SIZE);
+ }
+ else
+ {
+ BTM_TRACE_WARNING1 ("btm_read_ble_local_supported_features_complete status = %d", status);
+ }
btm_read_ble_local_supported_features();
}
@@ -842,6 +891,8 @@
BTM_TRACE_WARNING1 ("btm_read_ble_local_supported_features_complete status = %d", status);
}
+ btsnd_hcic_ble_set_evt_mask((UINT8 *)HCI_BLE_EVENT_MASK_DEF);
+
#if BTM_INTERNAL_BB == TRUE
{
UINT8 buf[9] = BTM_INTERNAL_LOCAL_FEA;
@@ -874,6 +925,8 @@
STREAM_TO_UINT8(btm_cb.ble_ctr_cb.max_filter_entries, p);
btm_cb.ble_ctr_cb.num_empty_filter = btm_cb.ble_ctr_cb.max_filter_entries;
}
+ /* write LE host support and simultatunous LE supported */
+ btsnd_hcic_ble_write_host_supported(BTM_BLE_HOST_SUPPORT, BTM_BLE_SIMULTANEOUS_HOST);
btm_get_ble_buffer_size();
}
diff --git a/stack/btm/btm_inq.c b/stack/btm/btm_inq.c
index 24f91a8..01cbd56 100644
--- a/stack/btm/btm_inq.c
+++ b/stack/btm/btm_inq.c
@@ -796,10 +796,10 @@
#if BLE_INCLUDED == TRUE
if (((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
- &&(active_mode & BTM_LE_INQ_ACTIVE_MASK)
+ &&(active_mode & BTM_BLE_INQ_ACTIVE_MASK)
#endif
)
- btm_ble_stop_scan();
+ btm_ble_stop_inquiry();
#endif
}
@@ -869,7 +869,6 @@
p_inq->scan_type = INQ_GENERAL;
p_inq->inq_active = BTM_INQUIRY_INACTIVE;
btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
- btm_cb.ble_ctr_cb.inq_var.proc_mode = BTM_BLE_INQUIRY_NONE;
btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
}
else
@@ -1080,7 +1079,8 @@
** BTM_WRONG_MODE if the device is not up.
**
*******************************************************************************/
-tBTM_STATUS BTM_ReadRemoteDeviceName (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
+tBTM_STATUS BTM_ReadRemoteDeviceName (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb
+ ,tBT_TRANSPORT transport)
{
tBTM_INQ_INFO *p_cur = NULL;
tINQ_DB_ENT *p_i;
@@ -1101,7 +1101,7 @@
BTM_TRACE_API0 ("no device found in inquiry db");
#if (BLE_INCLUDED == TRUE)
- if (BTM_UseLeLink(remote_bda))
+ if (transport == BT_TRANSPORT_LE)
{
return btm_ble_read_remote_name(remote_bda, p_cur, p_cb);
}
@@ -2266,7 +2266,7 @@
#if BLE_INCLUDED == TRUE
if ((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
- btm_ble_stop_scan();
+ btm_ble_stop_inquiry();
#endif
@@ -2493,14 +2493,13 @@
(p_inq_cb)((tBTM_INQUIRY_CMPL *) &p_inq->inq_cmpl_info);
}
#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
- if(p_inq->inqparms.mode != 0 && !(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE))
- {
- /* make inquiry inactive for next iteration */
- p_inq->inq_active = BTM_INQUIRY_INACTIVE;
- /* call the inquiry again */
- BTM_StartInquiry(&p_inq->inqparms,p_inq->p_inq_results_cb,p_inq->p_inq_cmpl_cb);
- return;
- }
+ if(p_inq->inqparms.mode != 0 && !(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE))
+ {
+ /* make inquiry inactive for next iteration */
+ p_inq->inq_active = BTM_INQUIRY_INACTIVE;
+ /* call the inquiry again */
+ BTM_StartInquiry(&p_inq->inqparms,p_inq->p_inq_results_cb,p_inq->p_inq_cmpl_cb);
+ }
#endif
}
if(p_inq->inqparms.mode == 0 && p_inq->scan_type == INQ_GENERAL)//this inquiry is complete
@@ -3422,9 +3421,6 @@
BTM_AddEirService( p_results->eir_uuid, uuid16 );
}
}
-
- BTM_TRACE_DEBUG2("btm_set_eir_uuid eir_uuid=0x%08X %08X",
- p_results->eir_uuid[1], p_results->eir_uuid[0] );
}
#endif
diff --git a/stack/btm/btm_int.h b/stack/btm/btm_int.h
index 7865b3e..913e253 100644
--- a/stack/btm/btm_int.h
+++ b/stack/btm/btm_int.h
@@ -46,7 +46,7 @@
typedef char tBTM_LOC_BD_NAME[BTM_MAX_LOC_BD_NAME_LEN + 1];
#endif
-#define BTM_ACL_IS_CONNECTED(bda) (btm_bda_to_acl (bda) != NULL)
+#define BTM_ACL_IS_CONNECTED(bda) (btm_bda_to_acl (bda, BT_TRANSPORT_BR_EDR) != NULL)
/* Definitions for Server Channel Number (SCN) management
*/
@@ -119,8 +119,9 @@
#if BTM_PWR_MGR_INCLUDED == FALSE
UINT8 mode;
#endif /* BTM_PWR_MGR_INCLUDED */
+
#if BLE_INCLUDED == TRUE
- UINT8 is_le_link;
+ tBT_TRANSPORT transport;
BD_ADDR conn_addr; /* local device address used for this connection */
UINT8 conn_addr_type; /* local device address type for this connection */
BD_ADDR active_remote_addr; /* remote address used on this connection */
@@ -189,24 +190,29 @@
BD_FEATURES local_lmp_features[HCI_EXT_FEATURES_PAGE_MAX + 1];
#if BLE_INCLUDED == TRUE
+
+ tBTM_CMPL_CB *p_le_test_cmd_cmpl_cb; /* Callback function to be called when
+ LE test mode command has been sent successfully */
+
BD_ADDR read_tx_pwr_addr; /* read TX power target address */
BD_FEATURES local_le_features; /* Local LE Supported features mask for the device */
tBTM_BLE_LOCAL_ID_KEYS id_keys; /* local BLE ID keys */
BT_OCTET16 er; /* BLE encryption key */
+#define BTM_LE_SUPPORT_STATE_SIZE 8
+UINT8 le_supported_states[BTM_LE_SUPPORT_STATE_SIZE];
+
+
+
#if BTM_BLE_CONFORMANCE_TESTING == TRUE
BOOLEAN no_disc_if_pair_fail;
- BOOLEAN enable_test_mac_val;
+ BOOLEAN enable_test_mac_val;
BT_OCTET8 test_mac;
- BOOLEAN enable_test_local_sign_cntr;
- UINT32 test_local_sign_cntr;
+ BOOLEAN enable_test_local_sign_cntr;
+ UINT32 test_local_sign_cntr;
#endif
-#if BLE_INCLUDED == TRUE
- tBTM_CMPL_CB *p_le_test_cmd_cmpl_cb; /* Callback function to be called when
- LE test mode command has been sent successfully */
-#endif
#endif /* BLE_INCLUDED */
@@ -218,6 +224,7 @@
tBTM_IO_CAP loc_io_caps; /* IO capability of the local device */
BOOLEAN loc_auth_req; /* the auth_req flag */
BD_FEATURES brcm_features; /* Broadcom specific features bit mask */
+#define BTM_RELOAD_LE_HOST_FEATURE 0x10
#define BTM_RE_READ_1ST_PAGE 0x01 /* Set it if you set at least one of "..._HOST_MAY_SUPP_..." bits */
#define BTM_HOST_MAY_SUPP_SSP 0x02
@@ -504,12 +511,13 @@
tBLE_ADDR_TYPE ble_addr_type; /* LE device type: public or random address */
tBLE_ADDR_TYPE static_addr_type; /* static address type */
BD_ADDR static_addr; /* static address */
-#if BTM_BLE_PRIVACY_SPT == TRUE
+#if BLE_PRIVACY_SPT == TRUE
BD_ADDR cur_rand_addr; /* current random address */
#define BTM_BLE_ADDR_PSEUDO 0 /* address index device record */
#define BTM_BLE_ADDR_RRA 1 /* cur_rand_addr */
#define BTM_BLE_ADDR_STATIC 2 /* static_addr */
+
UINT8 active_addr_type;
#endif
@@ -519,6 +527,7 @@
#endif
} tBTM_SEC_BLE;
+
#endif /* BLE_INCLUDED */
/*
@@ -546,8 +555,14 @@
#define BTM_SEC_LINK_KEY_AUTHED 0x20
#define BTM_SEC_ROLE_SWITCHED 0x40
#define BTM_SEC_IN_USE 0x80
+ /* LE link security flag */
+#define BTM_SEC_LE_AUTHENTICATED 0x0200 /* 0x0200 */
+#define BTM_SEC_LE_ENCRYPTED 0x0400 /* 0x04 */
+#define BTM_SEC_LE_NAME_KNOWN 0x0800
+#define BTM_SEC_LE_LINK_KEY_KNOWN 0x1000 /* 0x10 */
+#define BTM_SEC_LE_LINK_KEY_AUTHED 0x2000
- UINT8 sec_flags; /* Current device security state */
+ UINT16 sec_flags; /* Current device security state */
tBTM_BD_NAME sec_bd_name; /* User friendly name of the device. (may be truncated to save space in dev_rec table) */
BD_FEATURES features[HCI_EXT_FEATURES_PAGE_MAX + 1]; /* Features supported by the device */
@@ -589,6 +604,7 @@
BOOLEAN rmt_auth_req; /* the auth_req flag as in the IO caps rsp evt */
#if (BLE_INCLUDED == TRUE)
+ UINT16 ble_hci_handle; /* use in DUMO connection */
UINT8 enc_key_size; /* current link encryption key size */
tBTM_SEC_BLE ble;
tBT_DEVICE_TYPE device_type;
@@ -612,6 +628,7 @@
#define BTM_SEC_IS_SM4_LEGACY(sm) ((BOOLEAN)(BTM_SM4_KNOWN == ((sm)&BTM_SM4_TRUE)))
#define BTM_SEC_IS_SM4_UNKNOWN(sm) ((BOOLEAN)(BTM_SM4_UNKNOWN == ((sm)&BTM_SM4_TRUE)))
+#define BTM_SEC_LE_MASK (BTM_SEC_LE_AUTHENTICATED|BTM_SEC_LE_ENCRYPTED|BTM_SEC_LE_LINK_KEY_KNOWN|BTM_SEC_LE_LINK_KEY_AUTHED)
/*
** Define device configuration structure
@@ -726,11 +743,13 @@
#define BTM_PAIR_FLAGS_WE_STARTED_DD 0x01 /* We want to do dedicated bonding */
#define BTM_PAIR_FLAGS_PEER_STARTED_DD 0x02 /* Peer initiated dedicated bonding */
-#define BTM_PAIR_FLAGS_DISC_WHEN_DONE 0x04
+#define BTM_PAIR_FLAGS_DISC_WHEN_DONE 0x04 /* Disconnect when done */
#define BTM_PAIR_FLAGS_PIN_REQD 0x08 /* set this bit when pin_callback is called */
#define BTM_PAIR_FLAGS_PRE_FETCH_PIN 0x10 /* set this bit when pre-fetch pin */
#define BTM_PAIR_FLAGS_REJECTED_CONNECT 0x20 /* set this bit when rejected incoming connection */
#define BTM_PAIR_FLAGS_WE_CANCEL_DD 0x40 /* set this bit when cancelling a bonding procedure */
+#define BTM_PAIR_FLAGS_LE_ACTIVE 0x80 /* use this bit when SMP pairing is active */
+
typedef struct
{
@@ -975,8 +994,8 @@
extern void btm_acl_init (void);
extern void btm_acl_timeout (TIMER_LIST_ENT *p_tle);
extern void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn,
- UINT16 hci_handle, UINT8 link_role, UINT8 is_le_link);
-extern void btm_acl_removed (BD_ADDR bda);
+ UINT16 hci_handle, UINT8 link_role, tBT_TRANSPORT transport);
+extern void btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport);
extern void btm_acl_device_down (void);
extern void btm_acl_update_busy_level (tBTM_BLI_EVENT event);
extern void btm_acl_link_key_change (UINT16 handle, UINT8 status);
@@ -995,7 +1014,7 @@
extern void btm_acl_role_changed (UINT8 hci_status, BD_ADDR bd_addr, UINT8 new_role);
extern void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable);
BTM_API extern UINT16 btm_get_acl_disc_reason_code (void);
-BTM_API extern tBTM_STATUS btm_remove_acl (BD_ADDR bd_addr);
+BTM_API extern tBTM_STATUS btm_remove_acl (BD_ADDR bd_addr, tBT_TRANSPORT transport);
extern void btm_read_remote_features_complete (UINT8 *p);
extern void btm_read_remote_ext_features_complete (UINT8 *p);
extern void btm_read_remote_ext_features_failed (UINT8 status, UINT16 handle);
@@ -1005,7 +1024,7 @@
// btla-specific --
/* Read maximum data packet that can be sent over current connection */
extern UINT16 btm_get_max_packet_size (BD_ADDR addr);
-extern tACL_CONN *btm_bda_to_acl (BD_ADDR bda);
+extern tACL_CONN *btm_bda_to_acl (BD_ADDR bda, tBT_TRANSPORT transport);
extern BOOLEAN btm_acl_notif_conn_collision (BD_ADDR bda);
#if BTM_PWR_MGR_INCLUDED == FALSE
@@ -1139,7 +1158,7 @@
extern void btm_sec_link_key_request (UINT8 *p_bda);
extern void btm_sec_pin_code_request (UINT8 *p_bda);
extern void btm_sec_update_clock_offset (UINT16 handle, UINT16 clock_offset);
-extern void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res);
+extern void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res, BOOLEAN is_le_trasnport);
#if BLE_INCLUDED == TRUE
extern void btm_sec_clear_ble_keys (tBTM_SEC_DEV_REC *p_dev_rec);
diff --git a/stack/btm/btm_pm.c b/stack/btm/btm_pm.c
index 02e3a6a..711a69b 100644
--- a/stack/btm/btm_pm.c
+++ b/stack/btm/btm_pm.c
@@ -420,7 +420,11 @@
for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++)
{
- if ((p->in_use) && (!memcmp (p->remote_addr, remote_bda, BD_ADDR_LEN)))
+ if ((p->in_use) && (!memcmp (p->remote_addr, remote_bda, BD_ADDR_LEN))
+#if (BLE_INCLUDED == TRUE)
+ && p->transport == BT_TRANSPORT_BR_EDR
+#endif
+ )
{
#if BTM_PM_DEBUG == TRUE
BTM_TRACE_DEBUG2( "btm_pm_find_acl_ind ind:%d, st:%d", xx, btm_cb.pm_mode_db[xx].state);
@@ -848,15 +852,17 @@
BTM_TRACE_DEBUG2( "btm_pm_proc_mode_change new state:0x%x (old:0x%x)", p_cb->state, old_state);
#endif
- if ((p_cb->state == HCI_MODE_ACTIVE) &&
- ((p_lcb = l2cu_find_lcb_by_bd_addr (p->remote_addr)) != NULL))
+ if ((p_lcb = l2cu_find_lcb_by_bd_addr(p->remote_addr, BT_TRANSPORT_BR_EDR)) != NULL)
{
- /* There might be any pending packets due to SNIFF or PENDING state */
- /* Trigger L2C to start transmission of the pending packets. */
- BTM_TRACE_DEBUG0 ("btm mode change to active; check l2c_link for outgoing packets");
- l2c_link_check_send_pkts (p_lcb, NULL, NULL);
+ if ((p_cb->state == BTM_PM_ST_ACTIVE) || (p_cb->state == BTM_PM_ST_SNIFF))
+ {
+ /* There might be any pending packets due to SNIFF or PENDING state */
+ /* Trigger L2C to start transmission of the pending packets. */
+ BTM_TRACE_DEBUG0("btm mode change to active; check l2c_link for outgoing packets");
+ l2c_link_check_send_pkts(p_lcb, NULL, NULL);
//btu_stop_timer (&p_lcb->timer_entry);
+ }
}
/* notify registered parties */
@@ -955,7 +961,9 @@
}
}
}
+
#endif
+
#else /* BTM_PWR_MGR_INCLUDED == TRUE */
/*******************************************************************************
@@ -984,6 +992,7 @@
#endif
+
/*******************************************************************************
**
** Function BTM_IsPowerManagerOn
@@ -998,3 +1007,5 @@
{
return BTM_PWR_MGR_INCLUDED;
}
+
+
diff --git a/stack/btm/btm_sco.c b/stack/btm/btm_sco.c
index 2200b71..1ef3827 100644
--- a/stack/btm/btm_sco.c
+++ b/stack/btm/btm_sco.c
@@ -582,7 +582,7 @@
/* If originating, ensure that there is an ACL connection to the BD Address */
if (is_orig)
{
- if ((!remote_bda) || ((acl_handle = BTM_GetHCIConnHandle (remote_bda)) == 0xFFFF))
+ if ((!remote_bda) || ((acl_handle = BTM_GetHCIConnHandle (remote_bda, BT_TRANSPORT_BR_EDR)) == 0xFFFF))
return (BTM_UNKNOWN_ADDR);
}
@@ -682,7 +682,7 @@
{
/* If role change is in progress, do not proceed with SCO setup
* Wait till role change is complete */
- p_acl = btm_bda_to_acl(remote_bda);
+ p_acl = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
if (p_acl && p_acl->switch_role_state != BTM_ACL_SWKEY_STATE_IDLE)
{
BTM_TRACE_API1("Role Change is in progress for ACL handle 0x%04x",acl_handle);
@@ -740,7 +740,7 @@
for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
{
if ((p->state == SCO_ST_PEND_UNPARK) &&
- ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr)) == hci_handle))
+ ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
{
BTM_TRACE_API3("btm_sco_chk_pend_unpark -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d, hci_status 0x%02x",
@@ -774,7 +774,7 @@
for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
{
if ((p->state == SCO_ST_PEND_ROLECHANGE) &&
- ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr)) == hci_handle))
+ ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
{
BTM_TRACE_API1("btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x%04x", acl_handle);
diff --git a/stack/btm/btm_sec.c b/stack/btm/btm_sec.c
index eb5714a..9139031 100644
--- a/stack/btm/btm_sec.c
+++ b/stack/btm/btm_sec.c
@@ -80,13 +80,19 @@
static UINT8 btm_sec_start_authorization (tBTM_SEC_DEV_REC *p_dev_rec);
BOOLEAN btm_sec_are_all_trusted(UINT32 p_mask[]);
-static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason);
+static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason, UINT16 conn_handle);
+UINT8 btm_sec_start_role_switch (tBTM_SEC_DEV_REC *p_dev_rec);
tBTM_SEC_DEV_REC *btm_sec_find_dev_by_sec_state (UINT8 state);
static BOOLEAN btm_sec_set_security_level ( CONNECTION_TYPE conn_type, char *p_name, UINT8 service_id,
UINT16 sec_level, UINT16 psm, UINT32 mx_proto_id,
UINT32 mx_chan_id);
+static BOOLEAN btm_dev_authenticated(tBTM_SEC_DEV_REC *p_dev_rec);
+static BOOLEAN btm_dev_encrypted(tBTM_SEC_DEV_REC *p_dev_rec);
+static BOOLEAN btm_dev_authorized(tBTM_SEC_DEV_REC *p_dev_rec);
+static BOOLEAN btm_serv_trusted(tBTM_SEC_DEV_REC *p_dev_rec, tBTM_SEC_SERV_REC *p_serv_rec);
+
/* TRUE - authenticated link key is possible */
static const BOOLEAN btm_sec_io_map [BTM_IO_CAP_MAX][BTM_IO_CAP_MAX] =
{
@@ -103,6 +109,78 @@
/*******************************************************************************
**
+** Function btm_dev_authenticated
+**
+** Description check device is authenticated
+**
+** Returns BOOLEAN TRUE or FALSE
+**
+*******************************************************************************/
+static BOOLEAN btm_dev_authenticated (tBTM_SEC_DEV_REC *p_dev_rec)
+{
+ if(p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED)
+ {
+ return(TRUE);
+ }
+ return(FALSE);
+}
+
+/*******************************************************************************
+**
+** Function btm_dev_encrypted
+**
+** Description check device is encrypted
+**
+** Returns BOOLEAN TRUE or FALSE
+**
+*******************************************************************************/
+static BOOLEAN btm_dev_encrypted (tBTM_SEC_DEV_REC *p_dev_rec)
+{
+ if(p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)
+ {
+ return(TRUE);
+ }
+ return(FALSE);
+}
+
+/*******************************************************************************
+**
+** Function btm_dev_authorized
+**
+** Description check device is authorized
+**
+** Returns BOOLEAN TRUE or FALSE
+**
+*******************************************************************************/
+static BOOLEAN btm_dev_authorized (tBTM_SEC_DEV_REC *p_dev_rec)
+{
+ if(p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED)
+ {
+ return(TRUE);
+ }
+ return(FALSE);
+}
+
+/*******************************************************************************
+**
+** Function btm_serv_trusted
+**
+** Description check service is trusted
+**
+** Returns BOOLEAN TRUE or FALSE
+**
+*******************************************************************************/
+static BOOLEAN btm_serv_trusted(tBTM_SEC_DEV_REC *p_dev_rec, tBTM_SEC_SERV_REC *p_serv_rec)
+{
+ if(BTM_SEC_IS_SERVICE_TRUSTED(p_dev_rec->trusted_mask, p_serv_rec->service_id))
+ {
+ return(TRUE);
+ }
+ return(FALSE);
+}
+
+/*******************************************************************************
+**
** Function BTM_SecRegister
**
** Description Application manager calls this function to register for
@@ -121,28 +199,29 @@
BTM_TRACE_EVENT0 ("BTM_Sec: application registered");
#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
- BTM_TRACE_ERROR1 ("BTM_SecRegister:p_cb_info->p_le_callback == 0x%x ", p_cb_info->p_le_callback);
-
if (p_cb_info->p_le_callback)
{
-#if SMP_INCLUDED == TRUE
- BTM_TRACE_EVENT0 ("BTM_Sec: SMP_Register( btm_proc_smp_cback )");
- SMP_Register(btm_proc_smp_cback);
-#endif
- /* if no IR is loaded, need to regenerate all the keys */
- if (memcmp(btm_cb.devcb.id_keys.ir, &temp_value, sizeof(BT_OCTET16)) == 0)
+ BTM_TRACE_ERROR1 ("BTM_SecRegister:p_cb_info->p_le_callback == 0x%x ", p_cb_info->p_le_callback);
+
+ if (p_cb_info->p_le_callback)
{
- btm_ble_reset_id();
+ #if SMP_INCLUDED == TRUE
+ BTM_TRACE_EVENT0 ("BTM_Sec: SMP_Register( btm_proc_smp_cback )");
+ SMP_Register(btm_proc_smp_cback);
+ #endif
+ /* if no IR is loaded, need to regenerate all the keys */
+ if (memcmp(btm_cb.devcb.id_keys.ir, &temp_value, sizeof(BT_OCTET16)) == 0)
+ {
+ btm_ble_reset_id();
+ }
+ }
+ else
+ {
+ BTM_TRACE_ERROR0 ("BTM_SecRegister:p_cb_info->p_le_callback == NULL ");
}
}
- else
- {
- BTM_TRACE_ERROR0 ("BTM_SecRegister:p_cb_info->p_le_callback == NULL ");
- }
#endif
-
-
btm_cb.api = *p_cb_info;
#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
BTM_TRACE_ERROR1 ("BTM_SecRegister: btm_cb.api.p_le_callback = 0x%x ", btm_cb.api.p_le_callback);
@@ -270,7 +349,34 @@
if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
{
- *p_sec_flags = p_dev_rec->sec_flags;
+ *p_sec_flags = (UINT8) p_dev_rec->sec_flags;
+ return(TRUE);
+ }
+ BTM_TRACE_ERROR0 ("BTM_GetSecurityFlags false");
+ return(FALSE);
+}
+
+/*******************************************************************************
+**
+** Function BTM_GetSecurityFlagsByTransport
+**
+** Description Get security flags for the device on a particular transport
+**
+** Returns BOOLEAN TRUE or FALSE is device found
+**
+*******************************************************************************/
+BOOLEAN BTM_GetSecurityFlagsByTransport (BD_ADDR bd_addr, UINT8 * p_sec_flags,
+ tBT_TRANSPORT transport)
+{
+ tBTM_SEC_DEV_REC *p_dev_rec;
+
+ if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
+ {
+ if (transport == BT_TRANSPORT_BR_EDR)
+ *p_sec_flags = (UINT8) p_dev_rec->sec_flags;
+ else
+ *p_sec_flags = (UINT8) (p_dev_rec->sec_flags >> 8);
+
return(TRUE);
}
BTM_TRACE_ERROR0 ("BTM_GetSecurityFlags false");
@@ -958,7 +1064,8 @@
btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_AUTHED;
- (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
+ if (btm_cb.api.p_auth_complete_callback)
+ (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
p_dev_rec->sec_bd_name, HCI_ERR_AUTH_FAILURE);
}
return;
@@ -1028,25 +1135,21 @@
if (res != BTM_SUCCESS)
{
- btm_sec_dev_rec_cback_event (p_dev_rec, res);
+ btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE);
return;
}
if ((res = (UINT8)btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
{
- btm_sec_dev_rec_cback_event (p_dev_rec, res);
+ btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE);
}
}
-
-
/*******************************************************************************
**
-** Function BTM_SecBond
+** Function btm_sec_bond_by_transport
**
-** Description This function is called to perform bonding with peer device.
-** If the connection is already up, but not secure, pairing
-** is attempted. If already paired BTM_SUCCESS is returned.
+** Description this is the bond function that will start either SSP or SMP.
**
** Parameters: bd_addr - Address of the device to bond
** pin_len - length in bytes of the PIN Code
@@ -1055,16 +1158,20 @@
**
** Note: After 2.1 parameters are not used and preserved here not to change API
*******************************************************************************/
-tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[])
+tBTM_STATUS btm_sec_bond_by_transport (BD_ADDR bd_addr, tBT_TRANSPORT transport,
+ UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[])
{
tBTM_SEC_DEV_REC *p_dev_rec;
tBTM_STATUS status;
UINT8 *p_features;
UINT8 ii;
-
- BTM_TRACE_API6 ("BTM_SecBond BDA: %02x:%02x:%02x:%02x:%02x:%02x",
+ tACL_CONN *p= btm_bda_to_acl(bd_addr, transport);
+ BTM_TRACE_API6 ("btm_sec_bond_by_transport 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]);
+ BTM_TRACE_DEBUG1("btm_sec_bond_by_transport: Transport used %d" , transport);
+
+
/* Other security process is in progress */
if (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
{
@@ -1075,13 +1182,19 @@
if ((p_dev_rec = btm_find_or_alloc_dev (bd_addr)) == NULL)
{
return(BTM_NO_RESOURCES);
- }
+ }
BTM_TRACE_DEBUG1 ("before update sec_flags=0x%x", p_dev_rec->sec_flags);
/* 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) )
+ if ( ((p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE) && transport == BT_TRANSPORT_BR_EDR
+ && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))
+#if (BLE_INCLUDED == TRUE)
+ ||((p_dev_rec->ble_hci_handle != BTM_SEC_INVALID_HANDLE) && transport == BT_TRANSPORT_LE
+ && (p_dev_rec->sec_flags & BTM_SEC_LE_AUTHENTICATED))
+#endif
+
+ )
{
BTM_TRACE_WARNING0("BTM_SecBond -> Already Paired");
return(BTM_SUCCESS);
@@ -1107,25 +1220,28 @@
if (trusted_mask)
BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask);
+#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
+ if (transport == BT_TRANSPORT_LE)
+ {
+ p_dev_rec->sec_flags &= ~ BTM_SEC_LE_MASK;
+
+ if (SMP_Pair(bd_addr) == SMP_STARTED)
+ {
+ btm_cb.pairing_flags |= BTM_PAIR_FLAGS_LE_ACTIVE;
+ p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
+ btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
+ return BTM_CMD_STARTED;
+ }
+
+ btm_cb.pairing_flags = 0;
+ return(BTM_NO_RESOURCES);
+ }
+#endif
+
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);
-#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
- /* LE device, do SMP pairing */
- 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);
- }
-#endif
-
BTM_TRACE_DEBUG1 ("after update sec_flags=0x%x", p_dev_rec->sec_flags);
if (!HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
{
@@ -1157,7 +1273,7 @@
#endif
/* If connection already exists... */
- if (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE)
+ if (p && p->hci_handle != BTM_SEC_INVALID_HANDLE)
{
if (!btm_sec_start_authentication (p_dev_rec))
return(BTM_NO_RESOURCES);
@@ -1185,14 +1301,15 @@
* -> RNR (to learn if peer is 2.1)
* RNR when no ACL causes HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT */
btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME);
- BTM_ReadRemoteDeviceName(bd_addr, NULL);
+ BTM_ReadRemoteDeviceName(bd_addr, NULL, BT_TRANSPORT_BR_EDR);
}
else
{
/* We are accepting connection request from peer */
btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_PIN_REQ);
}
- BTM_TRACE_DEBUG3 ("State:%s sm4: 0x%x sec_state:%d", btm_pair_state_descr (btm_cb.pairing_state), p_dev_rec->sm4, p_dev_rec->sec_state);
+ BTM_TRACE_DEBUG3 ("State:%s sm4: 0x%x sec_state:%d",
+ btm_pair_state_descr (btm_cb.pairing_state), p_dev_rec->sm4, p_dev_rec->sec_state);
return BTM_CMD_STARTED;
}
@@ -1207,7 +1324,64 @@
return status;
}
+/*******************************************************************************
+**
+** Function BTM_SecBondByTransport
+**
+** Description This function is called to perform bonding with peer device.
+** If the connection is already up, but not secure, pairing
+** is attempted. If already paired BTM_SUCCESS is returned.
+**
+** Parameters: bd_addr - Address of the device to bond
+** transport - doing SSP over BR/EDR or SMP over LE
+** pin_len - length in bytes of the PIN Code
+** p_pin - pointer to array with the PIN Code
+** trusted_mask - bitwise OR of trusted services (array of UINT32)
+**
+** Note: After 2.1 parameters are not used and preserved here not to change API
+*******************************************************************************/
+tBTM_STATUS BTM_SecBondByTransport (BD_ADDR bd_addr, tBT_TRANSPORT transport,
+ UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[])
+{
+#if SMP_INCLUDED == TRUE
+ tBT_DEVICE_TYPE dev_type;
+ tBLE_ADDR_TYPE addr_type;
+ BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type);
+ /* LE device, do SMP pairing */
+ if ((transport == BT_TRANSPORT_LE && (dev_type & BT_DEVICE_TYPE_BLE) == 0) ||
+ (transport == BT_TRANSPORT_BR_EDR && (dev_type & BT_DEVICE_TYPE_BREDR) == 0))
+ {
+ return BTM_ILLEGAL_ACTION;
+ }
+#endif
+ return btm_sec_bond_by_transport(bd_addr, transport, pin_len, p_pin, trusted_mask);
+}
+
+/*******************************************************************************
+**
+** Function BTM_SecBond
+**
+** Description This function is called to perform bonding with peer device.
+** If the connection is already up, but not secure, pairing
+** is attempted. If already paired BTM_SUCCESS is returned.
+**
+** Parameters: bd_addr - Address of the device to bond
+** pin_len - length in bytes of the PIN Code
+** p_pin - pointer to array with the PIN Code
+** trusted_mask - bitwise OR of trusted services (array of UINT32)
+**
+** Note: After 2.1 parameters are not used and preserved here not to change API
+*******************************************************************************/
+tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[])
+{
+ tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
+#if BLE_INCLUDED == TRUE
+ if (BTM_UseLeLink(bd_addr))
+ transport = BT_TRANSPORT_LE;
+#endif
+ return btm_sec_bond_by_transport(bd_addr, transport, pin_len, p_pin, trusted_mask);
+}
/*******************************************************************************
**
** Function BTM_SecBondCancel
@@ -1216,14 +1390,12 @@
** with peer device.
**
** Parameters: bd_addr - Address of the peer device
+** transport - FALSE for BR/EDR link; TRUE for LE link
**
*******************************************************************************/
tBTM_STATUS BTM_SecBondCancel (BD_ADDR bd_addr)
{
tBTM_SEC_DEV_REC *p_dev_rec;
-#if SMP_INCLUDED == TRUE
- tACL_CONN *p=NULL;
-#endif
BTM_TRACE_API2 ("BTM_SecBondCancel() State: %s flags:0x%x",
btm_pair_state_descr (btm_cb.pairing_state), btm_cb.pairing_flags);
@@ -1233,19 +1405,17 @@
return BTM_UNKNOWN_ADDR;
#if SMP_INCLUDED == TRUE
- p = btm_bda_to_acl(bd_addr);
- if (p && p->is_le_link &&
- (p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING))
+ if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_LE_ACTIVE)
{
- BTM_TRACE_DEBUG0 ("Cancel LE pairing");
- if (SMP_PairCancel(bd_addr))
+ if (p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING)
{
- return BTM_CMD_STARTED;
+ BTM_TRACE_DEBUG0 ("Cancel LE pairing");
+ if (SMP_PairCancel(bd_addr))
+ {
+ return BTM_CMD_STARTED;
+ }
}
- else
- {
- return BTM_WRONG_MODE;
- }
+ return BTM_WRONG_MODE;
}
#endif
@@ -1271,7 +1441,7 @@
/* If the HCI link was set up by Bonding process */
if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE)
- return btm_sec_send_hci_disconnect(p_dev_rec, HCI_ERR_PEER_USER);
+ return btm_sec_send_hci_disconnect(p_dev_rec, HCI_ERR_PEER_USER, p_dev_rec->hci_handle);
else
l2cu_update_lcb_4_bonding(bd_addr, FALSE);
@@ -1375,6 +1545,8 @@
** p_ref_data - pointer to any data the caller wishes to receive
** in the callback function upon completion.
* can be set to NULL if not used.
+** transport - TRUE to encryption the link over LE trasnport
+** or FALSE for BR/EDR trasnport
**
** Returns BTM_SUCCESS - already encrypted
** BTM_PENDING - command will be returned in the callback
@@ -1383,41 +1555,45 @@
** BTM_MODE_UNSUPPORTED - if security manager not linked in.
**
*******************************************************************************/
-tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBTM_SEC_CBACK *p_callback,
+tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBT_TRANSPORT transport, tBTM_SEC_CBACK *p_callback,
void *p_ref_data)
{
tBTM_SEC_DEV_REC *p_dev_rec;
tBTM_STATUS rc;
-
#if BLE_INCLUDED == TRUE
- tACL_CONN *p;
- p = btm_bda_to_acl(bd_addr);
+ tACL_CONN *p = btm_bda_to_acl(bd_addr, transport);
#endif
p_dev_rec = btm_find_dev (bd_addr);
- if (!p_dev_rec || (p_dev_rec->hci_handle == BTM_SEC_INVALID_HANDLE))
+
+ if (!p_dev_rec ||
+ (transport == BT_TRANSPORT_BR_EDR && p_dev_rec->hci_handle == BTM_SEC_INVALID_HANDLE)
+#if BLE_INCLUDED == TRUE
+ || (transport == BT_TRANSPORT_LE && p_dev_rec->ble_hci_handle == BTM_SEC_INVALID_HANDLE)
+#endif
+ )
{
/* Connection should be up and runnning */
BTM_TRACE_WARNING0 ("Security Manager: BTM_SetEncryption not connected");
if (p_callback)
- (*p_callback) (bd_addr, p_ref_data, BTM_WRONG_MODE);
+ (*p_callback) (bd_addr, transport, p_ref_data, BTM_WRONG_MODE);
return(BTM_WRONG_MODE);
}
-
- if (
-#if BLE_INCLUDED == TRUE
- !p->is_le_link &&
+ if ((transport == BT_TRANSPORT_BR_EDR &&
+ (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))
+#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
+ || (transport == BT_TRANSPORT_LE &&
+ (p_dev_rec->sec_flags & BTM_SEC_LE_ENCRYPTED))
#endif
- (p_dev_rec->sec_flags & (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED))
- == (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED))
+ )
{
BTM_TRACE_EVENT0 ("Security Manager: BTM_SetEncryption already encrypted");
if (p_callback)
- (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS);
+ (*p_callback) (bd_addr, transport, p_ref_data, BTM_SUCCESS);
return(BTM_SUCCESS);
}
@@ -1428,7 +1604,7 @@
BTM_TRACE_WARNING0 ("Security Manager: BTM_SetEncryption busy");
if (p_callback)
- (*p_callback) (bd_addr, p_ref_data, BTM_BUSY);
+ (*p_callback) (bd_addr, transport, p_ref_data, BTM_BUSY);
return(BTM_BUSY);
}
@@ -1441,8 +1617,9 @@
BTM_TRACE_API4 ("Security Manager: BTM_SetEncryption Handle:%d State:%d Flags:0x%x Required:0x%x",
p_dev_rec->hci_handle, p_dev_rec->sec_state, p_dev_rec->sec_flags,
p_dev_rec->security_required);
+
#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
- if (p->is_le_link)
+ if (transport == BT_TRANSPORT_LE)
{
rc = btm_ble_set_encryption(bd_addr, p_ref_data, p->link_role);
}
@@ -1451,12 +1628,12 @@
rc = btm_sec_execute_procedure (p_dev_rec);
- if ( rc != BTM_CMD_STARTED)
+ if (rc != BTM_CMD_STARTED && rc != BTM_BUSY)
{
if (p_callback)
{
p_dev_rec->p_callback = NULL;
- (*p_callback) (bd_addr, p_dev_rec->p_ref_data, rc);
+ (*p_callback) (bd_addr, transport, p_dev_rec->p_ref_data, rc);
}
}
return(rc);
@@ -1465,13 +1642,13 @@
/*******************************************************************************
* disconnect the ACL link, if it's not done yet.
*******************************************************************************/
-static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason)
+static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason, UINT16 conn_handle)
{
UINT8 old_state = p_dev_rec->sec_state;
tBTM_STATUS status = BTM_CMD_STARTED;
BTM_TRACE_EVENT2 ("btm_sec_send_hci_disconnect: handle:0x%x, reason=0x%x",
- p_dev_rec->hci_handle, reason);
+ conn_handle, reason);
/* if some other thread disconnecting, we do not send second command */
if (BTM_SEC_STATE_DISCONNECTING != old_state)
@@ -1480,16 +1657,18 @@
#if BTM_DISC_DURING_RS == TRUE
/* If a Role Switch is in progress, delay the HCI Disconnect to avoid controller problem (4329B1) */
- if (p_dev_rec->rs_disc_pending == BTM_SEC_RS_PENDING)
+ if (p_dev_rec->rs_disc_pending == BTM_SEC_RS_PENDING &&
+ p_dev_rec->hci_handle == conn_handle)
+
{
- BTM_TRACE_ERROR0("RS in progress - Set DISC Pending flag in btm_sec_send_hci_disconnect to delay disconnect");
+ BTM_TRACE_DEBUG0("RS in progress - Set DISC Pending flag in btm_sec_send_hci_disconnect to delay disconnect");
p_dev_rec->rs_disc_pending = BTM_SEC_DISC_PENDING;
status = BTM_SUCCESS;
}
else
#endif
/* Tear down the HCI link */
- if (!btsnd_hcic_disconnect (p_dev_rec->hci_handle, reason))
+ if (!btsnd_hcic_disconnect (conn_handle, reason))
{
/* could not send disconnect. restore old state */
p_dev_rec->sec_state = old_state;
@@ -1579,7 +1758,7 @@
btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
if (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE)
- btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE);
+ btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle);
else
BTM_SecBondCancel(bd_addr);
@@ -1951,9 +2130,17 @@
if (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)
{
is_possible = FALSE;
+ if(p_dev_rec->p_cur_service)
+ {
BTM_TRACE_DEBUG5 ("btm_sec_is_upgrade_possible id:%d, link_key_typet:%d, rmt_io_caps:%d, chk flags:x%x, flags:x%x",
p_dev_rec->p_cur_service->service_id, p_dev_rec->link_key_type, p_dev_rec->rmt_io_caps,
mtm_check, p_dev_rec->p_cur_service->security_flags);
+ }
+ else
+ {
+ BTM_TRACE_DEBUG3 ("btm_sec_is_upgrade_possible link_key_typet:%d, rmt_io_caps:%d, chk flags:x%x, ",
+ p_dev_rec->link_key_type, p_dev_rec->rmt_io_caps, mtm_check);
+ }
/* Already have a link key to the connected peer. Is the link key secure enough?
** Is a link key upgrade even possible?
*/
@@ -2050,6 +2237,7 @@
tBTM_STATUS rc = BTM_SUCCESS;
BOOLEAN chk_acp_auth_done = FALSE;
BOOLEAN is_originator;
+ BOOLEAN transport = FALSE; /* should check PSM range in LE connection oriented L2CAP connection */
#if (L2CAP_UCD_INCLUDED == TRUE)
if (conn_type & CONNECTION_TYPE_ORIG_MASK)
@@ -2077,7 +2265,7 @@
{
BTM_TRACE_WARNING1 ("btm_sec_l2cap_access_req() PSM:%d no application registerd", psm);
- (*p_callback) (bd_addr, p_ref_data, BTM_MODE_UNSUPPORTED);
+ (*p_callback) (bd_addr, transport, p_ref_data, BTM_MODE_UNSUPPORTED);
return(BTM_MODE_UNSUPPORTED);
}
@@ -2085,7 +2273,7 @@
/* SDP connection we will always let through */
if (BT_PSM_SDP == psm)
{
- (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS_NO_SECURITY);
+ (*p_callback) (bd_addr,transport, p_ref_data, BTM_SUCCESS_NO_SECURITY);
return(BTM_SUCCESS);
}
@@ -2119,7 +2307,7 @@
if (rc == BTM_SUCCESS)
{
if (p_callback)
- (*p_callback) (bd_addr, (void *)p_ref_data, BTM_SUCCESS);
+ (*p_callback) (bd_addr, transport, (void *)p_ref_data, BTM_SUCCESS);
return(BTM_SUCCESS);
}
@@ -2148,9 +2336,9 @@
if (is_originator)
{
if (((security_required & BTM_SEC_OUT_FLAGS) == 0) ||
- ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) ||
- ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))) ||
- ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_FLAGS) && (p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED))) )
+ ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec))) ||
+ ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && btm_dev_encrypted(p_dev_rec))) ||
+ ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_FLAGS) && btm_dev_authorized(p_dev_rec) && btm_dev_encrypted(p_dev_rec))) )
{
rc = BTM_SUCCESS;
}
@@ -2158,9 +2346,12 @@
else
{
if (((security_required & BTM_SEC_IN_FLAGS) == 0) ||
- ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) ||
- ((((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))) ||
- ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_FLAGS) && (p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED))) )
+ (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec)) ||
+ (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && btm_dev_encrypted(p_dev_rec)) ||
+ (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHORIZE) && (btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec))) ||
+ (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_AUTHORIZE)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec)) && btm_dev_authenticated(p_dev_rec))) ||
+ (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_ENCRYPT | BTM_SEC_IN_AUTHORIZE)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec)) && btm_dev_encrypted(p_dev_rec))) ||
+ (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_FLAGS) && btm_dev_encrypted(p_dev_rec) && (btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec))))
{
rc = BTM_SUCCESS;
}
@@ -2169,7 +2360,7 @@
if (rc == BTM_SUCCESS)
{
if (p_callback)
- (*p_callback) (bd_addr, (void *)p_ref_data, BTM_SUCCESS);
+ (*p_callback) (bd_addr, transport, (void *)p_ref_data, BTM_SUCCESS);
return(BTM_SUCCESS);
}
@@ -2262,7 +2453,7 @@
p_dev_rec->security_required = old_security_required;
p_dev_rec->is_originator = old_is_originator;
- (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS);
+ (*p_callback) (bd_addr, transport, p_ref_data, BTM_SUCCESS);
return(BTM_SUCCESS);
}
@@ -2277,7 +2468,7 @@
p_dev_rec->security_required = old_security_required;
p_dev_rec->is_originator = old_is_originator;
- (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS);
+ (*p_callback) (bd_addr, transport, p_ref_data, BTM_SUCCESS);
return(BTM_SUCCESS);
}
@@ -2299,7 +2490,7 @@
BTM_TRACE_ERROR0 ("peer should have initiated security process by now (SM4 to SM4)");
p_dev_rec->p_callback = p_callback;
p_dev_rec->sec_state = BTM_SEC_STATE_DELAY_FOR_ENC;
- (*p_callback) (bd_addr, p_ref_data, rc);
+ (*p_callback) (bd_addr, transport, p_ref_data, rc);
return(BTM_SUCCESS);
}
@@ -2330,7 +2521,7 @@
if ((rc = btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
{
p_dev_rec->p_callback = NULL;
- (*p_callback) (bd_addr, p_dev_rec->p_ref_data, (UINT8)rc);
+ (*p_callback) (bd_addr, transport, p_dev_rec->p_ref_data, (UINT8)rc);
}
return(rc);
@@ -2368,6 +2559,7 @@
tBTM_SEC_SERV_REC *p_serv_rec;
tBTM_STATUS rc;
UINT16 security_required;
+ BOOLEAN transport = FALSE;/* should check PSM range in LE connection oriented L2CAP connection */
BTM_TRACE_DEBUG1 ("btm_sec_mx_access_request is_originator:%d", is_originator);
/* Find or get oldest record */
@@ -2380,7 +2572,7 @@
if (!p_serv_rec)
{
if (p_callback)
- (*p_callback) (bd_addr, p_ref_data, BTM_MODE_UNSUPPORTED);
+ (*p_callback) (bd_addr, transport, p_ref_data, BTM_MODE_UNSUPPORTED);
BTM_TRACE_ERROR3 ("Security Manager: MX service not found PSM:%d Proto:%d SCN:%d",
psm, mx_proto_id, mx_chan_id);
@@ -2406,8 +2598,8 @@
if (is_originator)
{
if (((security_required & BTM_SEC_OUT_FLAGS) == 0) ||
- ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) ||
- ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)))
+ ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec))) ||
+ ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && btm_dev_encrypted(p_dev_rec)))
)
{
rc = BTM_SUCCESS;
@@ -2416,8 +2608,11 @@
else
{
if (((security_required & BTM_SEC_IN_FLAGS) == 0) ||
- ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) ||
- ((((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)))
+ ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec))) ||
+ (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHORIZE) && (btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec))) ||
+ (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_AUTHENTICATE)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec)) && btm_dev_authenticated(p_dev_rec))) ||
+ (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_ENCRYPT)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec))&& btm_dev_encrypted(p_dev_rec))) ||
+ ((((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && btm_dev_encrypted(p_dev_rec)))
)
{
rc = BTM_SUCCESS;
@@ -2462,7 +2657,7 @@
{
p_dev_rec->p_callback = NULL;
- (*p_callback) (bd_addr, p_ref_data, (UINT8)rc);
+ (*p_callback) (bd_addr,transport, p_ref_data, (UINT8)rc);
}
}
@@ -2666,7 +2861,7 @@
while ((p_e = (tBTM_SEC_QUEUE_ENTRY *)GKI_dequeue (&bq)) != NULL)
{
/* Check that the ACL is still up before starting security procedures */
- if (btm_bda_to_acl(p_e->bd_addr) != NULL)
+ if (btm_bda_to_acl(p_e->bd_addr, BT_TRANSPORT_BR_EDR) != NULL)
{
BTM_TRACE_EVENT4 ("btm_sec_check_pending_reqs() submitting PSM: 0x%04x Is_Orig: %u mx_proto_id: %u mx_chan_id: %u",
p_e->psm, p_e->is_orig, p_e->mx_proto_id, p_e->mx_chan_id);
@@ -2747,9 +2942,13 @@
* right now. */
if (HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
{
+ btsnd_hcic_write_simple_pairing_mode(HCI_SP_MODE_ENABLED);
#if BLE_INCLUDED == TRUE
btsnd_hcic_set_event_mask(LOCAL_BR_EDR_CONTROLLER_ID,
(UINT8 *)HCI_DUMO_EVENT_MASK_EXT);
+
+ btsnd_hcic_ble_set_evt_mask((UINT8 *)HCI_BLE_EVENT_MASK_DEF);
+
#else
btsnd_hcic_set_event_mask(LOCAL_BR_EDR_CONTROLLER_ID,
(UINT8 *)HCI_LISBON_EVENT_MASK_EXT);
@@ -2815,7 +3014,7 @@
tL2C_LCB *p_lcb;
/* Make sure an L2cap link control block is available */
- if ((p_lcb = l2cu_allocate_lcb (p_dev_rec->bd_addr, TRUE)) == NULL)
+ if ((p_lcb = l2cu_allocate_lcb (p_dev_rec->bd_addr, TRUE, BT_TRANSPORT_BR_EDR)) == NULL)
{
BTM_TRACE_WARNING6 ("Security Manager: failed allocate LCB [%02x%02x%02x%02x%02x%02x]",
p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2],
@@ -2827,7 +3026,7 @@
/* set up the control block to indicated dedicated bonding */
btm_cb.pairing_flags |= BTM_PAIR_FLAGS_DISC_WHEN_DONE;
- if (l2cu_create_conn(p_lcb) == FALSE)
+ if (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE)
{
BTM_TRACE_WARNING6 ("Security Manager: failed create [%02x%02x%02x%02x%02x%02x]",
p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2],
@@ -2995,23 +3194,29 @@
{
btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
- (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
- p_dev_rec->sec_bd_name, status);
+ if (btm_cb.api.p_auth_complete_callback)
+ (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
+ p_dev_rec->sec_bd_name, status);
return;
}
/* if peer is very old legacy devices, HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT is not reported */
if (BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4))
{
- /* set the KNOWN flag only if BTM_PAIR_FLAGS_REJECTED_CONNECT is not set.
- * If it is set, there may be a race condition */
- BTM_TRACE_EVENT1 ("btm_sec_rmt_name_request_complete IS_SM4_UNKNOWN Flags:0x%04x", btm_cb.pairing_flags);
+ /* set the KNOWN flag only if BTM_PAIR_FLAGS_REJECTED_CONNECT is not set.*/
+ /* If it is set, there may be a race condition */
+ BTM_TRACE_DEBUG1 ("btm_sec_rmt_name_request_complete IS_SM4_UNKNOWN Flags:0x%04x",
+ btm_cb.pairing_flags);
if ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT) == 0)
{
p_dev_rec->sm4 |= BTM_SM4_KNOWN;
}
}
+ BTM_TRACE_DEBUG5("%s, SM4 Value: %x, Legacy:%d,IS SM4:%d, Unknown:%d",__FUNCTION__,
+ p_dev_rec->sm4, BTM_SEC_IS_SM4_LEGACY(p_dev_rec->sm4),
+ BTM_SEC_IS_SM4(p_dev_rec->sm4),BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4));
+
/* BT 2.1 or carkit, bring up the connection to force the peer to request PIN.
** Else prefetch (btm_sec_check_prefetch_pin will do the prefetching if needed)
*/
@@ -3030,6 +3235,7 @@
btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
+ if (btm_cb.api.p_auth_complete_callback)
(*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
p_dev_rec->sec_bd_name, HCI_ERR_MEMORY_FULL);
}
@@ -3040,7 +3246,7 @@
{
BTM_TRACE_WARNING0 ("btm_sec_rmt_name_request_complete: wrong BDA, retry with pairing BDA");
- BTM_ReadRemoteDeviceName (btm_cb.pairing_bda, NULL);
+ BTM_ReadRemoteDeviceName (btm_cb.pairing_bda, NULL, BT_TRANSPORT_BR_EDR);
return;
}
}
@@ -3084,7 +3290,7 @@
/* If get name failed, notify the waiting layer */
if (status != HCI_SUCCESS)
{
- btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING);
+ btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE);
return;
}
@@ -3102,7 +3308,7 @@
return;
/* There is no next procedure or start of procedure failed, notify the waiting layer */
- btm_sec_dev_rec_cback_event (p_dev_rec, status);
+ btm_sec_dev_rec_cback_event (p_dev_rec, status, FALSE);
}
/*******************************************************************************
@@ -3592,7 +3798,7 @@
if (disc)
{
/* simple pairing failed */
- btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE);
+ btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle);
}
}
@@ -3831,7 +4037,7 @@
p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
if (status != HCI_SUCCESS)
- btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_PEER_USER);
+ btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_PEER_USER, p_dev_rec->hci_handle);
else
l2cu_start_post_bond_timer (p_dev_rec->hci_handle);
@@ -3871,11 +4077,11 @@
}
}
- btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING);
+ btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE);
if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE)
{
- btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE);
+ btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle);
}
return;
}
@@ -3887,7 +4093,7 @@
/* If there is no next procedure, or procedure failed to start, notify the caller */
if (status != BTM_CMD_STARTED)
- btm_sec_dev_rec_cback_event (p_dev_rec, status);
+ btm_sec_dev_rec_cback_event (p_dev_rec, status, FALSE);
}
/*******************************************************************************
@@ -3933,7 +4139,8 @@
{
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle);
#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
- tACL_CONN *p_acl;
+ tACL_CONN *p_acl = NULL;
+ UINT8 acl_idx = btm_handle_to_acl_index(handle);
#endif
BTM_TRACE_EVENT3 ("Security Manager: encrypt_change status:%d State:%d, encr_enable = %d",
status, (p_dev_rec) ? p_dev_rec->sec_state : 0, encr_enable);
@@ -3952,19 +4159,30 @@
return;
if ((status == HCI_SUCCESS) && encr_enable)
- p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED);
+ {
+ if (p_dev_rec->hci_handle == handle)
+ p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED);
+ else
+ p_dev_rec->sec_flags |= (BTM_SEC_LE_AUTHENTICATED | BTM_SEC_LE_ENCRYPTED);
+ }
/* It is possible that we decrypted the link to perform role switch */
/* mark link not to be encrypted, so that when we execute security next time it will kick in again */
if ((status == HCI_SUCCESS) && !encr_enable)
- p_dev_rec->sec_flags &= ~BTM_SEC_ENCRYPTED;
+ {
+ if (p_dev_rec->hci_handle == handle)
+ p_dev_rec->sec_flags &= ~BTM_SEC_ENCRYPTED;
+ else
+ p_dev_rec->sec_flags &= ~BTM_SEC_LE_ENCRYPTED;
+ }
BTM_TRACE_DEBUG1 ("after update p_dev_rec->sec_flags=0x%x", p_dev_rec->sec_flags );
#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
- p_acl = btm_bda_to_acl(p_dev_rec->bd_addr);
+ if (acl_idx != MAX_L2CAP_LINKS )
+ p_acl = &btm_cb.acl_db[acl_idx];
- if (p_acl && p_acl->is_le_link)
+ if (p_acl && p_acl->transport == BT_TRANSPORT_LE)
{
btm_ble_link_encrypted(p_dev_rec->bd_addr, encr_enable);
return;
@@ -3991,7 +4209,7 @@
/* If encryption setup failed, notify the waiting layer */
if (status != HCI_SUCCESS)
{
- btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING);
+ btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE);
return;
}
@@ -4000,7 +4218,7 @@
/* If there is no next procedure, or procedure failed to start, notify the caller */
if (status != BTM_CMD_STARTED)
- btm_sec_dev_rec_cback_event (p_dev_rec, status);
+ btm_sec_dev_rec_cback_event (p_dev_rec, status, FALSE);
}
/*******************************************************************************
@@ -4060,6 +4278,7 @@
btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
+ if (btm_cb.api.p_auth_complete_callback)
(*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
p_dev_rec->sec_bd_name, HCI_ERR_MEMORY_FULL);
}
@@ -4081,6 +4300,7 @@
UINT8 res;
BOOLEAN is_pairing_device = FALSE;
tACL_CONN *p_acl_cb;
+ UINT8 bit_shift = 0;
btm_acl_resubmit_page();
@@ -4108,9 +4328,6 @@
if (status == HCI_SUCCESS)
{
p_dev_rec = btm_sec_alloc_dev (bda);
-#if BLE_INCLUDED == TRUE
- p_dev_rec->device_type |= BT_DEVICE_TYPE_BREDR;
-#endif
}
else
{
@@ -4121,6 +4338,10 @@
}
else /* Update the timestamp for this device */
{
+
+#if BLE_INCLUDED == TRUE
+ bit_shift = (handle == p_dev_rec->ble_hci_handle) ? 8 :0;
+#endif
p_dev_rec->timestamp = btm_cb.dev_rec_count++;
if (p_dev_rec->sm4 & BTM_SM4_CONN_PEND)
{
@@ -4147,7 +4368,7 @@
else
{
btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME);
- BTM_ReadRemoteDeviceName(p_dev_rec->bd_addr, NULL);
+ BTM_ReadRemoteDeviceName(p_dev_rec->bd_addr, NULL, BT_TRANSPORT_BR_EDR);
}
#if BTM_DISC_DURING_RS == TRUE
p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
@@ -4164,6 +4385,10 @@
}
}
+#if BLE_INCLUDED == TRUE
+ p_dev_rec->device_type |= BT_DEVICE_TYPE_BREDR;
+#endif
+
#if BTM_DISC_DURING_RS == TRUE
p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
#endif
@@ -4185,7 +4410,7 @@
{
/* Try again: RNR when no ACL causes HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT */
btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME);
- BTM_ReadRemoteDeviceName(bda, NULL);
+ BTM_ReadRemoteDeviceName(bda, NULL, BT_TRANSPORT_BR_EDR);
return;
}
@@ -4221,7 +4446,7 @@
if (is_pairing_device)
{
p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
- p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED);
+ p_dev_rec->sec_flags &= ~((BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED) << bit_shift);
BTM_TRACE_DEBUG1 ("security_required:%x ", p_dev_rec->security_required );
btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
@@ -4234,17 +4459,33 @@
p_dev_rec->sec_bd_name, status);
}
}
- else if ((status == HCI_ERR_AUTH_FAILURE) ||
+ /*
+ Do not send authentication failure, if following conditions hold good
+ 1. BTM Sec Pairing state is idle
+ 2. Link key for the remote device is present.
+ 3. Remote is SSP capable.
+ */
+ else if ((p_dev_rec->link_key_type <= BTM_LKEY_TYPE_REMOTE_UNIT) &&
+ (((status == HCI_ERR_AUTH_FAILURE) ||
(status == HCI_ERR_KEY_MISSING) ||
(status == HCI_ERR_HOST_REJECT_SECURITY) ||
(status == HCI_ERR_PAIRING_NOT_ALLOWED) ||
(status == HCI_ERR_UNIT_KEY_USED) ||
(status == HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED) ||
(status == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE) ||
- (status == HCI_ERR_REPEATED_ATTEMPTS))
+ (status == HCI_ERR_REPEATED_ATTEMPTS))))
{
p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
- p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_KNOWN;
+ p_dev_rec->sec_flags &= ~ (BTM_SEC_LE_LINK_KEY_KNOWN << bit_shift);
+
+
+#ifdef BRCM_NOT_4_BTE
+ /* If we rejected pairing, pass this special result code */
+ if (btm_cb.acl_disc_reason == HCI_ERR_HOST_REJECT_SECURITY)
+ {
+ status = HCI_ERR_HOST_REJECT_SECURITY;
+ }
+#endif
/* We need to notify host that the key is not known any more */
if (btm_cb.api.p_auth_complete_callback)
@@ -4257,9 +4498,9 @@
if (status == HCI_ERR_CONNECTION_TOUT || status == HCI_ERR_LMP_RESPONSE_TIMEOUT ||
status == HCI_ERR_UNSPECIFIED || status == HCI_ERR_PAGE_TIMEOUT)
- btm_sec_dev_rec_cback_event (p_dev_rec, BTM_DEVICE_TIMEOUT);
+ btm_sec_dev_rec_cback_event (p_dev_rec, BTM_DEVICE_TIMEOUT, FALSE);
else
- btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING);
+ btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE);
return;
}
@@ -4304,7 +4545,7 @@
/* role may not be correct here, it will be updated by l2cap, but we need to */
/* notify btm_acl that link is up, so starting of rmt name request will not */
/* set paging flag up */
- p_acl_cb = btm_bda_to_acl(bda);
+ p_acl_cb = btm_bda_to_acl(bda, BT_TRANSPORT_BR_EDR);
if (p_acl_cb)
{
/* whatever is in btm_establish_continue() without reporting the BTM_BL_CONN_EVT event */
@@ -4318,19 +4559,19 @@
BTM_SetLinkPolicy (p_acl_cb->remote_addr, &btm_cb.btm_def_link_policy);
#endif
}
- btm_acl_created (bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name, handle, HCI_ROLE_SLAVE, FALSE);
+ btm_acl_created (bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name, handle, HCI_ROLE_SLAVE, BT_TRANSPORT_BR_EDR);
/* Initialize security flags. We need to do that because some */
/* authorization complete could have come after the connection is dropped */
/* and that would set wrong flag that link has been authorized already */
- p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED |
- BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
+ p_dev_rec->sec_flags &= ~((BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED |
+ BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED) << bit_shift);
if (enc_mode != HCI_ENCRYPT_MODE_DISABLED)
- p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED);
+ p_dev_rec->sec_flags |= ((BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED) << bit_shift);
if (btm_cb.security_mode == BTM_SEC_MODE_LINK)
- p_dev_rec->sec_flags |= BTM_SEC_AUTHENTICATED;
+ p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED << bit_shift);
p_dev_rec->link_key_changed = FALSE;
@@ -4341,7 +4582,7 @@
if (!(p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN) || p_dev_rec->is_originator)
{
if ((res = btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
- btm_sec_dev_rec_cback_event (p_dev_rec, res);
+ btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE);
}
return;
}
@@ -4371,7 +4612,7 @@
if (((p_dev_rec->security_required & BTM_SEC_FORCE_MASTER) && !p_dev_rec->role_master)
|| ((p_dev_rec->security_required & BTM_SEC_FORCE_SLAVE) && p_dev_rec->role_master))
{
- btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING);
+ btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE);
return;
}
@@ -4384,7 +4625,7 @@
if ((res = (UINT8)btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
{
- btm_sec_dev_rec_cback_event (p_dev_rec, res);
+ btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE);
}
}
@@ -4418,7 +4659,7 @@
return(BTM_BUSY);
}
- return(btm_sec_send_hci_disconnect(p_dev_rec, reason));
+ return(btm_sec_send_hci_disconnect(p_dev_rec, reason, handle));
}
/*******************************************************************************
@@ -4437,6 +4678,7 @@
UINT8 old_pairing_flags = btm_cb.pairing_flags;
int result = HCI_ERR_AUTH_FAILURE;
tBTM_SEC_CALLBACK *p_callback = NULL;
+ tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
/* If page was delayed for disc complete, can do it now */
btm_cb.discing = FALSE;
@@ -4446,6 +4688,8 @@
if (!p_dev_rec)
return;
+ transport = (handle == p_dev_rec->hci_handle) ? BT_TRANSPORT_BR_EDR: BT_TRANSPORT_LE;
+
p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
#if BTM_DISC_DURING_RS == TRUE
@@ -4487,16 +4731,24 @@
}
}
- p_dev_rec->hci_handle = BTM_SEC_INVALID_HANDLE;
- p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
-
#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
p_dev_rec->enc_key_size = 0;
btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, p_dev_rec->bd_addr, FALSE);
/* see sec_flags processing in btm_acl_removed */
-#endif
- p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
+ if (transport == BT_TRANSPORT_LE)
+ {
+ p_dev_rec->ble_hci_handle = BTM_SEC_INVALID_HANDLE;
+ p_dev_rec->sec_flags &= ~(BTM_SEC_LE_AUTHENTICATED|BTM_SEC_LE_ENCRYPTED);
+ }
+ else
+#endif
+ {
+ p_dev_rec->hci_handle = BTM_SEC_INVALID_HANDLE;
+ p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
+ }
+
+ p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
p_dev_rec->security_required = BTM_SEC_NONE;
p_callback = p_dev_rec->p_callback;
@@ -4506,7 +4758,7 @@
{
p_dev_rec->p_callback = NULL; /* when the peer device time out the authentication before
we do, this call back must be reset here */
- (*p_callback) (p_dev_rec->bd_addr, p_dev_rec->p_ref_data, BTM_ERR_PROCESSING);
+ (*p_callback) (p_dev_rec->bd_addr, transport, p_dev_rec->p_ref_data, BTM_ERR_PROCESSING);
}
BTM_TRACE_EVENT1("after Update sec_flags=0x%x", p_dev_rec->sec_flags);
@@ -4741,7 +4993,7 @@
(p_cb->pairing_bda[4] << 8) + p_cb->pairing_bda[5]);
break;
}
- btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE);
+ btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle);
btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
break;
@@ -5384,7 +5636,7 @@
if (status != BTM_CMD_STARTED)
{
/* There is no next procedure or start of procedure failed, notify the waiting layer */
- btm_sec_dev_rec_cback_event (btm_cb.p_collided_dev_rec, status);
+ btm_sec_dev_rec_cback_event (btm_cb.p_collided_dev_rec, status, FALSE);
}
}
@@ -5609,7 +5861,7 @@
** Parameters: void
**
*******************************************************************************/
-void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res)
+void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res, BOOLEAN transport)
{
tBTM_SEC_CALLBACK *p_callback = p_dev_rec->p_callback;
@@ -5617,7 +5869,7 @@
{
p_dev_rec->p_callback = NULL;
- (*p_callback) (p_dev_rec->bd_addr, p_dev_rec->p_ref_data, res);
+ (*p_callback) (p_dev_rec->bd_addr, transport, p_dev_rec->p_ref_data, res);
}
btm_sec_check_pending_reqs();
@@ -5695,7 +5947,7 @@
if (btm_cb.api.p_pin_callback && ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_PIN_REQD) == 0))
{
BTM_TRACE_DEBUG0("btm_sec_check_prefetch_pin: PIN code callback called");
- if (btm_bda_to_acl(p_dev_rec->bd_addr) == NULL)
+ if (btm_bda_to_acl(p_dev_rec->bd_addr, BT_TRANSPORT_BR_EDR) == NULL)
btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
(btm_cb.api.p_pin_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class, p_dev_rec->sec_bd_name);
}
@@ -5746,12 +5998,14 @@
tBTM_SEC_DEV_REC *p_dev_rec= btm_find_dev (bda);
BOOLEAN is_bonded= FALSE;
+ if (p_dev_rec &&
#if (SMP_INCLUDED== TRUE)
- if (p_dev_rec && (p_dev_rec->ble.key_type || (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)))
+ ((p_dev_rec->ble.key_type && (p_dev_rec->sec_flags & BTM_SEC_LE_LINK_KEY_KNOWN))||
+#endif
+ (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)))
{
is_bonded = TRUE;
}
-#endif
BTM_TRACE_DEBUG1 ("btm_sec_is_a_bonded_dev is_bonded=%d", is_bonded);
return(is_bonded);
}
diff --git a/stack/btu/btu_hcif.c b/stack/btu/btu_hcif.c
index cef5096..32c6b58 100644
--- a/stack/btu/btu_hcif.c
+++ b/stack/btu/btu_hcif.c
@@ -139,6 +139,9 @@
static void btu_ble_ll_conn_param_upd_evt (UINT8 *p);
static void btu_ble_proc_ltk_req (UINT8 *p);
static void btu_hcif_encryption_key_refresh_cmpl_evt (UINT8 *p);
+#if (BLE_LLT_INCLUDED == TRUE)
+static void btu_ble_rc_param_req_evt(UINT8 *p);
+#endif
#endif
/*******************************************************************************
**
@@ -424,6 +427,12 @@
case HCI_BLE_LTK_REQ_EVT: /* received only at slave device */
btu_ble_proc_ltk_req(p);
break;
+#if (BLE_LLT_INCLUDED == TRUE)
+ case HCI_BLE_RC_PARAM_REQ_EVT:
+ btu_ble_rc_param_req_evt(p);
+ break;
+#endif
+
}
break;
#endif /* BLE_INCLUDED */
@@ -1141,6 +1150,10 @@
btm_ble_write_adv_enable_complete(p);
break;
+ case HCI_BLE_READ_SUPPORTED_STATES:
+ btm_read_ble_local_supported_states_complete(p, evt_len);
+ break;
+
case HCI_BLE_TRANSMITTER_TEST:
case HCI_BLE_RECEIVER_TEST:
case HCI_BLE_TEST_END:
@@ -2269,16 +2282,7 @@
static void btu_ble_ll_conn_param_upd_evt (UINT8 *p)
{
- /* LE connection update has completed successfully as a master. */
- /* We can enable the update request if the result is a success. */
- /* extract the HCI handle first */
- UINT8 status;
- UINT16 handle;
- BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, "btu_ble_ll_conn_param_upd_evt");
-
- STREAM_TO_UINT8 (status, p);
- STREAM_TO_UINT16 (handle, p);
- L2CA_HandleConnUpdateEvent(handle, status);
+ /* This is empty until an upper layer cares about returning event */
}
static void btu_ble_read_remote_feat_evt (UINT8 *p)
@@ -2302,5 +2306,21 @@
/**********************************************
** End of BLE Events Handler
***********************************************/
+#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
+static void btu_ble_rc_param_req_evt(UINT8 *p)
+{
+ UINT16 handle;
+ UINT16 int_min, int_max, latency, timeout;
+
+ STREAM_TO_UINT16(handle, p);
+ STREAM_TO_UINT16(int_min, p);
+ STREAM_TO_UINT16(int_max, p);
+ STREAM_TO_UINT16(latency, p);
+ STREAM_TO_UINT16(timeout, p);
+
+ l2cble_process_rc_param_request_evt(handle, int_min, int_max, latency, timeout);
+}
+#endif /* BLE_LLT_INCLUDED */
+
#endif /* BLE_INCLUDED */
diff --git a/stack/btu/btu_task.c b/stack/btu/btu_task.c
index 9c09214..5b5108a 100644
--- a/stack/btu/btu_task.c
+++ b/stack/btu/btu_task.c
@@ -400,6 +400,9 @@
case BTU_TTYPE_L2CAP_HOLD:
case BTU_TTYPE_L2CAP_INFO:
case BTU_TTYPE_L2CAP_FCR_ACK:
+#if (BLE_INCLUDED == TRUE)
+ case BTU_TTYPE_L2CAP_END_CONN_UPD:
+#endif
l2c_process_timeout (p_tle);
break;
@@ -473,6 +476,8 @@
case BTU_TTYPE_BLE_INQUIRY:
case BTU_TTYPE_BLE_GAP_LIM_DISC:
case BTU_TTYPE_BLE_RANDOM_ADDR:
+ case BTU_TTYPE_BLE_GAP_FAST_ADV:
+ case BTU_TTYPE_BLE_OBSERVE:
btm_ble_timeout(p_tle);
break;
diff --git a/stack/gap/gap_api.c b/stack/gap/gap_api.c
index fb90d03..e04fc8e 100644
--- a/stack/gap/gap_api.c
+++ b/stack/gap/gap_api.c
@@ -734,7 +734,7 @@
p_cb->gap_cback = callback;
p_cb->event = GAP_EVT_REM_NAME_COMPLETE; /* Return event expected */
- btm_status = BTM_ReadRemoteDeviceName (addr, gap_cb.btm_cback[p_cb->index]);
+ btm_status = BTM_ReadRemoteDeviceName (addr, gap_cb.btm_cback[p_cb->index], BT_TRANSPORT_BR_EDR);
/* If the name was not returned immediately, or if an error occurred, release the control block */
if ((retval = gap_convert_btm_status (btm_status)) != GAP_CMD_INITIATED)
diff --git a/stack/gap/gap_ble.c b/stack/gap/gap_ble.c
index d44577d..d67bf5a 100644
--- a/stack/gap/gap_ble.c
+++ b/stack/gap/gap_ble.c
@@ -57,7 +57,8 @@
static void gap_ble_s_attr_request_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE op_code, tGATTS_DATA *p_data);
/* client connection callback */
-static void gap_ble_c_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason);
+static void gap_ble_c_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected,
+ tGATT_DISCONN_REASON reason, tGATT_TRANSPORT transport);
static void gap_ble_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, tGATT_CL_COMPLETE *p_data);
static tGATT_CBACK gap_cback =
@@ -213,65 +214,6 @@
return(GATT_INVALID_CONN_ID);
}
-/*******************************************************************************
-**
-** Function gap_ble_enqueue_op
-**
-** Description enqueue a GAP operation when GAP client is busy
-**
-** Returns void
-**
-*******************************************************************************/
-void gap_ble_enqueue_op( tGAP_CLCB * p_clcb, UINT8 op, BD_ADDR reconn_addr, UINT8 privacy_flag, void *p_cback)
-{
- tGAP_BLE_PENDING_OP *p_op = (tGAP_BLE_PENDING_OP *)GKI_getbuf(sizeof(tGAP_BLE_PENDING_OP));
-
- if (p_op != NULL)
- {
- p_op->op = op;
- p_op->p_pending_cback = p_cback;
-
- if (op == GATT_SET_GAP_PRIVACY_FLAG)
- p_op->pending_data.privacy_flag = privacy_flag;
- else if (op == GATT_UPDATE_RECONN_ADDR)
- memcpy(p_op->pending_data.reconn_addr, reconn_addr, BD_ADDR_LEN);
-
- GKI_enqueue(&p_clcb->pending_op_q, p_op);
- }
-}
-
-/*******************************************************************************
-**
-** Function gap_ble_process_pending_op
-**
-** Description get next pending operation and process it
-**
-** Returns void
-**
-*******************************************************************************/
-static BOOLEAN gap_ble_process_pending_op(tGAP_CLCB *p_clcb)
-{
- tGAP_BLE_PENDING_OP *p_pending_op = (tGAP_BLE_PENDING_OP *)GKI_dequeue(&p_clcb->pending_op_q);
- BOOLEAN started = FALSE;
-
- if (p_pending_op != NULL)
- {
- if (p_pending_op->op == GATT_UPDATE_RECONN_ADDR)
- {
- GAP_BleUpdateReconnectAddr( p_clcb->bda,
- p_pending_op->pending_data.reconn_addr,
- (tGAP_BLE_RECONN_ADDR_CBACK *)p_pending_op->p_pending_cback);
- started = TRUE;
- }
- GKI_freebuf(p_pending_op);
- }
- else
- {
- GAP_TRACE_EVENT0("No pending operation");
- }
-
- return started;
-}
/*******************************************************************************
** GAP Attributes Database Request callback
@@ -316,16 +258,6 @@
p_value->len = 2;
break;
- case GATT_UUID_GAP_PRIVACY_FLAG:
- UINT8_TO_STREAM(p, p_db_attr->attr_value.privacy);
- p_value->len = 1;
- break;
-
- case GATT_UUID_GAP_RECONN_ADDR:
- p_value->len = BD_ADDR_LEN;
- BDADDR_TO_STREAM(p, p_db_attr->attr_value.reconn_bda);
- break;
-
case GATT_UUID_GAP_PREF_CONN_PARAM:
UINT16_TO_STREAM(p, p_db_attr->attr_value.conn_param.int_min); /* int_min */
UINT16_TO_STREAM(p, p_db_attr->attr_value.conn_param.int_max); /* int_max */
@@ -357,18 +289,6 @@
return status;
}
-BOOLEAN gap_read_local_reconn_addr(BD_ADDR_PTR reconn_bda)
-{
- BD_ADDR dummy_bda = {0};
-
- if (memcmp(gap_cb.reconn_bda, dummy_bda, BD_ADDR_LEN) != 0)
- {
- memcpy(reconn_bda, gap_cb.reconn_bda, BD_ADDR_LEN);
- return TRUE;
- }
- else
- return FALSE;
-}
/******************************************************************************
**
@@ -389,26 +309,7 @@
{
if (p_data-> handle == p_db_attr->handle)
{
- if (p_data->offset != 0) return GATT_NOT_LONG;
- if (p_data->is_prep) return GATT_REQ_NOT_SUPPORTED;
-
-/* DO NOT SUPPORT RECONNECTION ADDRESS FOR NOW
-
- if (p_db_attr->uuid == GATT_UUID_GAP_RECONN_ADDR)
- {
- if (!btm_cb.ble_ctr_cb.privacy)
- return GATT_WRITE_NOT_PERMIT;
- if (p_data->len != BD_ADDR_LEN) return GATT_INVALID_ATTR_LEN;
-
- STREAM_TO_BDADDR(p_db_attr->attr_value.reconn_bda, p);
- // write direct connection address
- memcpy(&gap_cb.reconn_bda, p_db_attr->attr_value.reconn_bda, BD_ADDR_LEN);
-
- return GATT_SUCCESS;
- }
- else
-*/
- return GATT_WRITE_NOT_PERMIT;
+ return GATT_WRITE_NOT_PERMIT;
}
}
return GATT_NOT_FOUND;
@@ -513,6 +414,21 @@
GATT_CHAR_PROP_BIT_READ);
p_db_attr ++;
+#if BTM_PERIPHERAL_ENABLED == TRUE /* Only needed for peripheral testing */
+ /* add preferred connection parameter characteristic
+ */
+ uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_PREF_CONN_PARAM;
+ p_db_attr->attr_value.conn_param.int_max = GAP_PREFER_CONN_INT_MAX; /* 6 */
+ p_db_attr->attr_value.conn_param.int_min = GAP_PREFER_CONN_INT_MIN; /* 0 */
+ p_db_attr->attr_value.conn_param.latency = GAP_PREFER_CONN_LATENCY; /* 0 */
+ p_db_attr->attr_value.conn_param.sp_tout = GAP_PREFER_CONN_SP_TOUT; /* 2000 */
+ p_db_attr->handle = GATTS_AddCharacteristic(service_handle,
+ &uuid,
+ GATT_PERM_READ,
+ GATT_CHAR_PROP_BIT_READ);
+ p_db_attr ++;
+#endif
+
/* start service now */
memset (&app_uuid.uu.uuid128, 0x81, LEN_UUID_128);
@@ -596,8 +512,6 @@
(* 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);
}
@@ -612,11 +526,14 @@
**
*******************************************************************************/
static void gap_ble_c_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
- BOOLEAN connected, tGATT_DISCONN_REASON reason)
+ BOOLEAN connected, tGATT_DISCONN_REASON reason,
+ tGATT_TRANSPORT transport)
{
tGAP_CLCB *p_clcb = gap_find_clcb_by_bd_addr (bda);
UINT16 cl_op_uuid;
+
UNUSED(gatt_if);
+ UNUSED(transport);
GAP_TRACE_EVENT5 ("gap_ble_c_connect_cback: from %08x%04x connected:%d conn_id=%d reason = 0x%04x",
(bda[0]<<24)+(bda[1]<<16)+(bda[2]<<8)+bda[3],
@@ -636,9 +553,6 @@
p_clcb->conn_id = conn_id;
p_clcb->connected = TRUE;
- /* Do not use reconnection address for now -->
- check privacy enabled? set reconnect address
- btm_ble_update_reconnect_address(bda);*/
}
else
{
@@ -659,6 +573,10 @@
{
GAP_BleReadPeerDevName (bda, (tGAP_BLE_DEV_NAME_CBACK *)p_clcb->p_cback);
}
+ else if (cl_op_uuid == GATT_UUID_GAP_PREF_CONN_PARAM)
+ {
+ GAP_BleReadPeerPrefConnParams(bda);
+ }
}
/* current link disconnect */
else
@@ -695,7 +613,7 @@
GAP_TRACE_EVENT3 ("gap_ble_c_cmpl_cback() - op_code: 0x%02x status: 0x%02x read_type: 0x%04x", op, status, op_type);
/* Currently we only issue read commands */
- if (op != GATTC_OPTYPE_READ && op != GATTC_OPTYPE_WRITE)
+ if (op != GATTC_OPTYPE_READ)
return;
if (status != GATT_SUCCESS)
@@ -731,7 +649,6 @@
break;
case GATT_UUID_GAP_ICON:
break;
-
}
}
@@ -806,18 +723,20 @@
return(FALSE);
/* hold the link here */
- GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE);
-
- if (p_clcb->connected)
+ if (GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE, BT_TRANSPORT_LE))
{
- return gap_ble_cl_read_request(p_clcb, GATT_UUID_GAP_PREF_CONN_PARAM, NULL);
+
+ 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);
}
- /* Mark currently active operation */
- p_clcb->cl_op_uuid = GATT_UUID_GAP_PREF_CONN_PARAM;
-
- return(TRUE);
-
-
+ else
+ return FALSE;
}
/*******************************************************************************
@@ -839,10 +758,10 @@
if ((p_clcb = gap_find_clcb_by_bd_addr (peer_bda)) == NULL)
{
if ((p_clcb = gap_clcb_alloc(0, peer_bda)) == NULL)
- {
- GAP_TRACE_ERROR0("GAP_BleReadPeerDevName max connection reached");
+ {
+ GAP_TRACE_ERROR0("GAP_BleReadPeerDevName max connection reached");
return FALSE;
- }
+ }
p_clcb->connected = FALSE;
}
@@ -855,21 +774,26 @@
return(FALSE);
/* hold the link here */
- GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE);
- if (p_clcb->connected)
+ if (GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE, BT_TRANSPORT_LE))
{
- return gap_ble_cl_read_request(p_clcb, GATT_UUID_GAP_DEVICE_NAME, (void *)p_cback);
+ if (p_clcb->connected)
+ {
+ return gap_ble_cl_read_request(p_clcb, GATT_UUID_GAP_DEVICE_NAME, (void *)p_cback);
+ }
+
+ p_clcb->p_cback = (void *)p_cback;
+ /* Mark currently active operation */
+ p_clcb->cl_op_uuid = GATT_UUID_GAP_DEVICE_NAME;
+
+
+ return(TRUE);
}
-
- p_clcb->p_cback = (void *)p_cback;
- /* Mark currently active operation */
- p_clcb->cl_op_uuid = GATT_UUID_GAP_DEVICE_NAME;
-
-
- return(TRUE);
+ else
+ return FALSE;
}
+
/*******************************************************************************
**
** Function GAP_BleCancelReadPeerDevName
@@ -907,73 +831,6 @@
return(TRUE);
}
-/*******************************************************************************
-**
-** Function GAP_BleUpdateReconnectAddr
-**
-** Description Start a process to udpate the reconnect address if remote devive
-** has privacy enabled.
-**
-** Returns TRUE if read started, else FALSE if GAP is busy
-**
-*******************************************************************************/
-BOOLEAN GAP_BleUpdateReconnectAddr (BD_ADDR peer_bda, BD_ADDR reconn_addr,
- tGAP_BLE_RECONN_ADDR_CBACK *p_cback)
-{
- tGAP_CLCB *p_clcb;
- tGATT_DISC_PARAM param;
-
- if (p_cback == NULL)
- return(FALSE);
-
- /* 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)
- {
- GAP_TRACE_ERROR0("No connection, can not update reconnect address");
- return(FALSE);
- }
-
- GAP_TRACE_API3 ("GAP_BleUpdateReconnectAddr() - BDA: %08x%04x cl_op_uuid: 0x%04x",
- (peer_bda[0]<<24)+(peer_bda[1]<<16)+(peer_bda[2]<<8)+peer_bda[3],
- (peer_bda[4]<<8)+peer_bda[5], p_clcb->cl_op_uuid);
-
- /* For now we only handle one at a time */
- if (p_clcb->cl_op_uuid != 0)
- {
- gap_ble_enqueue_op(p_clcb, GATT_UPDATE_RECONN_ADDR, reconn_addr, 0, (void *)p_cback);
- return(FALSE);
- }
-
- /* hold the link here */
- GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE);
-
- memset(¶m, 0, sizeof(tGATT_DISC_PARAM));
-
- param.service.len = LEN_UUID_16;
- param.service.uu.uuid16 = GATT_UUID_GAP_RECONN_ADDR;
- param.s_handle = 1;
- param.e_handle = 0xFFFF;
-
- if (GATTC_Discover(p_clcb->conn_id, GATT_DISC_CHAR, ¶m) != GATT_SUCCESS)
- {
- GAP_TRACE_ERROR0 ("GAP_BleReadPeerPrefConnParams: GATT_Read Failed");
- /* release the link here */
- GATT_Disconnect(p_clcb->conn_id);
- return(FALSE);
- }
- else
- {
- p_clcb->p_cback = (void *)p_cback;
- memcpy(p_clcb->reconn_addr, reconn_addr, BD_ADDR_LEN);
- p_clcb->cl_op_uuid = GATT_UUID_GAP_RECONN_ADDR;
- }
-
- return TRUE;
-
-}
-
#endif /* BLE_INCLUDED */
diff --git a/stack/gap/gap_conn.c b/stack/gap/gap_conn.c
index 44bb5ec..5e26ce2 100644
--- a/stack/gap/gap_conn.c
+++ b/stack/gap/gap_conn.c
@@ -799,10 +799,11 @@
** Returns void
**
*******************************************************************************/
-static void gap_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+static void gap_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
{
tGAP_CCB *p_ccb = (tGAP_CCB *)p_ref_data;
UNUSED(bd_addr);
+ UNUSED (transport);
GAP_TRACE_EVENT3 ("gap_sec_check_complete conn_state:%d, conn_flags:0x%x, status:%d",
p_ccb->con_state, p_ccb->con_flags, res);
diff --git a/stack/gap/gap_utils.c b/stack/gap/gap_utils.c
index 866ad7a..e852d20 100644
--- a/stack/gap/gap_utils.c
+++ b/stack/gap/gap_utils.c
@@ -183,7 +183,7 @@
if ((p_cb->p_cur_inq = BTM_InqDbNext(p_cb->p_cur_inq)) != NULL)
{
if ((BTM_ReadRemoteDeviceName (p_cb->p_cur_inq->results.remote_bd_addr,
- (tBTM_CMPL_CB *) gap_find_addr_name_cb)) == BTM_CMD_STARTED)
+ (tBTM_CMPL_CB *) gap_find_addr_name_cb, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
return; /* This routine will get called again with the next results */
else
p_result->status = gap_convert_btm_status ((tBTM_STATUS) p->status);
@@ -246,7 +246,7 @@
if ((p_cb->p_cur_inq = BTM_InqDbFirst()) != NULL)
{
if ((BTM_ReadRemoteDeviceName (p_cb->p_cur_inq->results.remote_bd_addr,
- (tBTM_CMPL_CB *) gap_find_addr_name_cb)) == BTM_CMD_STARTED)
+ (tBTM_CMPL_CB *) gap_find_addr_name_cb, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
return; /* Wait for the response in gap_find_addr_name_cb() */
else
p_result->status = gap_convert_btm_status (p->status);
diff --git a/stack/gatt/att_protocol.c b/stack/gatt/att_protocol.c
index 3348599..51ea284 100644
--- a/stack/gatt/att_protocol.c
+++ b/stack/gatt/att_protocol.c
@@ -162,7 +162,7 @@
** Returns pointer to the command buffer.
**
*******************************************************************************/
-BT_HDR *attp_build_read_handles_cmd (UINT16 payload_size, tGATT_FIND_TYPE_VALUE *p_value_type)
+BT_HDR *attp_build_read_by_type_value_cmd (UINT16 payload_size, tGATT_FIND_TYPE_VALUE *p_value_type)
{
BT_HDR *p_buf = NULL;
UINT8 *p;
@@ -606,7 +606,7 @@
break;
case GATT_REQ_FIND_TYPE_VALUE:
- p_cmd = attp_build_read_handles_cmd(p_tcb->payload_size, &p_msg->find_type_value);
+ p_cmd = attp_build_read_by_type_value_cmd(p_tcb->payload_size, &p_msg->find_type_value);
break;
case GATT_REQ_READ_MULTI:
diff --git a/stack/gatt/gatt_api.c b/stack/gatt/gatt_api.c
index 54ea0f0..0321fe8 100644
--- a/stack/gatt/gatt_api.c
+++ b/stack/gatt/gatt_api.c
@@ -238,7 +238,7 @@
}
}
- if (!gatts_init_service_db(&p_list->svc_db, *p_svc_uuid, is_pri, s_hdl , num_handles))
+ if (!gatts_init_service_db(&p_list->svc_db, p_svc_uuid, is_pri, s_hdl , num_handles))
{
GATT_TRACE_ERROR0 ("GATTS_ReserveHandles: service DB initialization failed");
if (p_list)
@@ -366,7 +366,8 @@
return 0;
}
if (p_descr_uuid == NULL ||
- (p_descr_uuid->len != LEN_UUID_128 && p_descr_uuid->len != LEN_UUID_16))
+ (p_descr_uuid->len != LEN_UUID_128 && p_descr_uuid->len != LEN_UUID_16
+ && p_descr_uuid->len != LEN_UUID_32))
{
GATT_TRACE_DEBUG0("Illegal parameter");
return 0;
@@ -689,8 +690,13 @@
memcpy (notif.value, p_val, val_len);
notif.auth_req = GATT_AUTH_REQ_NONE;;
- p_buf = attp_build_sr_msg (p_tcb, GATT_HANDLE_VALUE_NOTIF, (tGATT_SR_MSG *)¬if);
- cmd_sent = attp_send_sr_msg (p_tcb, p_buf);
+ if ((p_buf = attp_build_sr_msg (p_tcb, GATT_HANDLE_VALUE_NOTIF, (tGATT_SR_MSG *)¬if))
+ != NULL)
+ {
+ cmd_sent = attp_send_sr_msg (p_tcb, p_buf);
+ }
+ else
+ cmd_sent = GATT_NO_RESOURCES;
}
return cmd_sent;
}
@@ -1147,12 +1153,12 @@
** Returns void
**
*******************************************************************************/
-void GATT_SetIdleTimeout (BD_ADDR bd_addr, UINT16 idle_tout)
+void GATT_SetIdleTimeout (BD_ADDR bd_addr, UINT16 idle_tout, tBT_TRANSPORT transport)
{
tGATT_TCB *p_tcb;
BOOLEAN status = FALSE;
- if ((p_tcb = gatt_find_tcb_by_addr (bd_addr)) != NULL)
+ if ((p_tcb = gatt_find_tcb_by_addr (bd_addr, transport)) != NULL)
{
if (p_tcb->att_lcid == L2CAP_ATT_CID)
{
@@ -1275,7 +1281,7 @@
if (!gatt_num_apps_hold_link(p_tcb))
{
/* this will disconnect the link or cancel the pending connect request at lower layer*/
- gatt_disconnect(p_tcb->peer_bda);
+ gatt_disconnect(p_tcb);
}
}
@@ -1323,19 +1329,20 @@
BD_ADDR bda;
UINT8 start_idx, found_idx;
UINT16 conn_id;
+ tGATT_TRANSPORT transport ;
GATT_TRACE_API1 ("GATT_StartIf gatt_if=%d", gatt_if);
if ((p_reg = gatt_get_regcb(gatt_if)) != NULL)
{
p_reg = &gatt_cb.cl_rcb[gatt_if - 1];
start_idx = 0;
- while (gatt_find_the_connected_bda(start_idx, bda, &found_idx))
+ while (gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport))
{
- p_tcb = gatt_find_tcb_by_addr(bda);
+ p_tcb = gatt_find_tcb_by_addr(bda, transport);
if (p_reg->app_cb.p_conn_cb && p_tcb)
{
conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_if);
- (*p_reg->app_cb.p_conn_cb)(gatt_if, bda, conn_id, TRUE, 0);
+ (*p_reg->app_cb.p_conn_cb)(gatt_if, bda, conn_id, TRUE, 0, transport);
}
start_idx = ++found_idx;
}
@@ -1357,9 +1364,10 @@
** Returns TRUE if connection started; FALSE if connection start failure.
**
*******************************************************************************/
-BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct){
+BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct, tBT_TRANSPORT transport)
+{
tGATT_REG *p_reg;
- BOOLEAN status;
+ BOOLEAN status = FALSE;
GATT_TRACE_API1 ("GATT_Connect gatt_if=%d", gatt_if);
@@ -1371,9 +1379,16 @@
}
if (is_direct)
- status = gatt_act_connect (p_reg, bd_addr);
+ status = gatt_act_connect (p_reg, bd_addr, transport);
else
+ {
+ if (transport == BT_TRANSPORT_LE)
status = gatt_update_auto_connect_dev(gatt_if,TRUE, bd_addr, TRUE);
+ else
+ {
+ GATT_TRACE_ERROR0("Unsupported transport for background connection");
+ }
+ }
return status;
@@ -1414,7 +1429,8 @@
{
GATT_TRACE_DEBUG0("GATT_CancelConnect - unconditional");
start_idx = 0;
- p_tcb = gatt_find_tcb_by_addr(bd_addr);
+ /* only LE connection can be cancelled */
+ p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
if (p_tcb && gatt_num_apps_hold_link(p_tcb))
{
while (status && gatt_find_app_hold_link(p_tcb, start_idx, &found_idx, &temp_gatt_if))
@@ -1486,7 +1502,7 @@
gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE);
if (!gatt_num_apps_hold_link(p_tcb))
{
- gatt_disconnect(p_tcb->peer_bda);
+ gatt_disconnect(p_tcb);
}
ret = GATT_SUCCESS;
}
@@ -1508,7 +1524,8 @@
** Returns TRUE the ligical link information is found for conn_id
**
*******************************************************************************/
-BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, BD_ADDR bd_addr)
+BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, BD_ADDR bd_addr,
+ tBT_TRANSPORT *p_transport)
{
tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
@@ -1523,6 +1540,7 @@
{
memcpy(bd_addr, p_tcb->peer_bda, BD_ADDR_LEN);
*p_gatt_if = gatt_if;
+ *p_transport = p_tcb->transport;
status = TRUE;
}
return status;
@@ -1539,14 +1557,16 @@
** Parameters gatt_if: applicaiton interface (input)
** bd_addr: peer device address. (input)
** p_conn_id: connection id (output)
+** transport: transport option
**
** Returns TRUE the logical link is connected
**
*******************************************************************************/
-BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, UINT16 *p_conn_id)
+BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, UINT16 *p_conn_id,
+ tBT_TRANSPORT transport)
{
tGATT_REG *p_reg = gatt_get_regcb(gatt_if);
- tGATT_TCB *p_tcb= gatt_find_tcb_by_addr(bd_addr);
+ tGATT_TCB *p_tcb= gatt_find_tcb_by_addr(bd_addr, transport);
BOOLEAN status=FALSE;
if (p_reg && p_tcb && (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) )
@@ -1598,10 +1618,7 @@
p_reg->listening = start ? GATT_LISTEN_TO_ALL : GATT_LISTEN_TO_NONE;
}
- gatt_update_listen_mode();
-
- return status;
-
+ return gatt_update_listen_mode();
}
#endif
diff --git a/stack/gatt/gatt_attr.c b/stack/gatt/gatt_attr.c
index 1ee4ae3..60beaa7 100644
--- a/stack/gatt/gatt_attr.c
+++ b/stack/gatt/gatt_attr.c
@@ -41,7 +41,8 @@
#endif
static void gatt_profile_request_cback (UINT16 conn_id, UINT32 trans_id, UINT8 op_code, tGATTS_DATA *p_data);
-static void gatt_profile_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason);
+static void gatt_profile_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
+ BOOLEAN connected, tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport);
static tGATT_CBACK gatt_profile_cback =
{
@@ -87,14 +88,15 @@
** Returns Pointer to the found link conenction control block.
**
*******************************************************************************/
-tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_bd_addr(BD_ADDR bda)
+static tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_bd_addr(BD_ADDR bda, tBT_TRANSPORT transport)
{
UINT8 i_clcb;
tGATT_PROFILE_CLCB *p_clcb = NULL;
for (i_clcb = 0, p_clcb= gatt_cb.profile_clcb; i_clcb < GATT_MAX_APPS; i_clcb++, p_clcb++)
{
- if (p_clcb->in_use && p_clcb->connected && !memcmp(p_clcb->bda, bda, BD_ADDR_LEN))
+ if (p_clcb->in_use && p_clcb->transport == transport &&
+ p_clcb->connected && !memcmp(p_clcb->bda, bda, BD_ADDR_LEN))
{
return p_clcb;
}
@@ -112,7 +114,7 @@
** Returns NULL if not found. Otherwise pointer to the connection link block.
**
*******************************************************************************/
-tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda)
+tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda, tBT_TRANSPORT tranport)
{
UINT8 i_clcb = 0;
tGATT_PROFILE_CLCB *p_clcb = NULL;
@@ -124,6 +126,7 @@
p_clcb->in_use = TRUE;
p_clcb->conn_id = conn_id;
p_clcb->connected = TRUE;
+ p_clcb->transport = tranport;
memcpy (p_clcb->bda, bda, BD_ADDR_LEN);
break;
}
@@ -215,7 +218,8 @@
**
*******************************************************************************/
static void gatt_profile_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
- BOOLEAN connected, tGATT_DISCONN_REASON reason)
+ BOOLEAN connected, tGATT_DISCONN_REASON reason,
+ tBT_TRANSPORT transport)
{
UNUSED(gatt_if);
@@ -225,7 +229,7 @@
if (connected)
{
- if (gatt_profile_clcb_alloc(conn_id, bda) == NULL)
+ if (gatt_profile_clcb_alloc(conn_id, bda, transport) == NULL)
{
GATT_TRACE_ERROR0 ("gatt_profile_connect_cback: no_resource");
return;
diff --git a/stack/gatt/gatt_auth.c b/stack/gatt/gatt_auth.c
index 7dc99e1..b093725 100644
--- a/stack/gatt/gatt_auth.c
+++ b/stack/gatt/gatt_auth.c
@@ -114,9 +114,8 @@
}
else
{
- /* if this is a bad signature, assume from attacker, ignore it */
- GATT_TRACE_ERROR0("Signature Verification Failed");
- gatt_disconnect(p_tcb->peer_bda);
+ /* if this is a bad signature, assume from attacker, ignore it */
+ GATT_TRACE_ERROR0("Signature Verification Failed, data ignored");
}
return;
@@ -157,7 +156,7 @@
** Returns
**
*******************************************************************************/
-void gatt_enc_cmpl_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result)
+void gatt_enc_cmpl_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result)
{
tGATT_TCB *p_tcb;
UINT8 sec_flag;
@@ -167,7 +166,7 @@
UNUSED(p_ref_data);
GATT_TRACE_DEBUG0("gatt_enc_cmpl_cback");
- if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) != NULL)
+ if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, transport)) != NULL)
{
if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING)
return;
@@ -178,8 +177,9 @@
{
if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENCRYPT_MITM )
{
- BTM_GetSecurityFlags(bd_addr, &sec_flag);
- if (sec_flag & sec_flag & BTM_SEC_FLAG_LKEY_AUTHED)
+ BTM_GetSecurityFlagsByTransport(bd_addr, &sec_flag, transport);
+
+ if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED)
{
status = TRUE;
}
@@ -232,7 +232,7 @@
UINT16 count;
UINT8 i = 0;
- if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) != NULL)
+ if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE)) != NULL)
{
for (i = 0; i < GATT_MAX_APPS; i++)
{
@@ -316,9 +316,7 @@
UINT8 sec_flag;
tGATT_TCB *p_tcb = p_clcb->p_tcb;
tGATT_AUTH_REQ auth_req = p_clcb->auth_req;
-
BOOLEAN is_link_encrypted= FALSE;
- BOOLEAN is_le_link=FALSE;
BOOLEAN is_link_key_known=FALSE;
BOOLEAN is_key_mitm=FALSE;
UINT8 key_type;
@@ -327,8 +325,8 @@
if (auth_req == GATT_AUTH_REQ_NONE )
return act;
- is_le_link = BTM_UseLeLink(p_tcb->peer_bda);
- BTM_GetSecurityFlags(p_tcb->peer_bda, &sec_flag);
+ BTM_GetSecurityFlagsByTransport(p_tcb->peer_bda, &sec_flag, p_clcb->p_tcb->transport);
+
btm_ble_link_sec_check(p_tcb->peer_bda, auth_req, &sec_act);
/* if a encryption is pending, need to wait */
@@ -336,24 +334,15 @@
auth_req != GATT_AUTH_REQ_NONE)
return GATT_SEC_ENC_PENDING;
- if (sec_flag & BTM_SEC_FLAG_ENCRYPTED)
+ if (sec_flag & (BTM_SEC_FLAG_ENCRYPTED| BTM_SEC_FLAG_LKEY_KNOWN))
{
- is_link_encrypted = TRUE;
+ if (sec_flag & BTM_SEC_FLAG_ENCRYPTED)
+ is_link_encrypted = TRUE;
+
is_link_key_known = TRUE;
if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED)
- {
is_key_mitm = TRUE;
- }
-
- }
- else if (sec_flag & BTM_SEC_FLAG_LKEY_KNOWN)
- {
- is_link_key_known = TRUE;
- if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED)
- {
- is_key_mitm = TRUE;
- }
}
/* first check link key upgrade required or not */
@@ -377,7 +366,7 @@
/* now check link needs to be encrypted or not if the link key upgrade is not required */
if (act == GATT_SEC_OK)
{
- if (is_le_link &&
+ if (p_tcb->transport == BT_TRANSPORT_LE &&
(p_clcb->operation == GATTC_OPTYPE_WRITE) &&
(p_clcb->op_subtype == GATT_WRITE_NO_RSP))
{
@@ -430,7 +419,7 @@
tGATT_STATUS encrypt_status = GATT_NOT_ENCRYPTED;
UINT8 sec_flag=0;
- BTM_GetSecurityFlags(p_tcb->peer_bda, &sec_flag);
+ BTM_GetSecurityFlagsByTransport(p_tcb->peer_bda, &sec_flag, p_tcb->transport);
if ((sec_flag & BTM_SEC_FLAG_ENCRYPTED) && (sec_flag & BTM_SEC_FLAG_LKEY_KNOWN))
{
@@ -510,7 +499,7 @@
{
GATT_TRACE_DEBUG0("gatt_security_check_start: Encrypt now or key upgreade first");
gatt_convert_sec_action(gatt_sec_act, &btm_ble_sec_act);
- btm_status = BTM_SetEncryption(p_tcb->peer_bda, gatt_enc_cmpl_cback, &btm_ble_sec_act);
+ btm_status = BTM_SetEncryption(p_tcb->peer_bda, p_tcb->transport , gatt_enc_cmpl_cback, &btm_ble_sec_act);
if ( (btm_status != BTM_SUCCESS) && (btm_status != BTM_CMD_STARTED))
{
GATT_TRACE_ERROR1("gatt_security_check_start BTM_SetEncryption failed btm_status=%d", btm_status);
diff --git a/stack/gatt/gatt_cl.c b/stack/gatt/gatt_cl.c
index e8c41fc..930cd35 100644
--- a/stack/gatt/gatt_cl.c
+++ b/stack/gatt/gatt_cl.c
@@ -27,6 +27,7 @@
#if BLE_INCLUDED == TRUE
#include <string.h>
+#include "bt_utils.h"
#include "gki.h"
#include "gatt_int.h"
@@ -102,6 +103,13 @@
cl_req.find_type_value.s_handle = p_clcb->s_handle;
cl_req.find_type_value.e_handle = p_clcb->e_handle;
cl_req.find_type_value.value_len = p_clcb->uuid.len;
+ /* if service type is 32 bits UUID, convert it now */
+ if (p_clcb->uuid.len == LEN_UUID_32)
+ {
+ cl_req.find_type_value.value_len = LEN_UUID_128;
+ gatt_convert_uuid32_to_uuid128(cl_req.find_type_value.value, p_clcb->uuid.uu.uuid32);
+ }
+ else
memcpy (cl_req.find_type_value.value, &p_clcb->uuid.uu, p_clcb->uuid.len);
}
@@ -402,11 +410,13 @@
** Returns void
**
*******************************************************************************/
-static void gatt_process_find_type_value_rsp (tGATT_CLCB *p_clcb, UINT16 len, UINT8 *p_data)
+void gatt_process_find_type_value_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT16 len, UINT8 *p_data)
{
tGATT_DISC_RES result;
UINT8 *p = p_data;
+ UNUSED(p_tcb);
+
GATT_TRACE_DEBUG0("gatt_process_find_type_value_rsp ");
/* unexpected response */
if (p_clcb->operation != GATTC_OPTYPE_DISCOVERY || p_clcb->op_subtype != GATT_DISC_SRVC_BY_UUID)
@@ -445,11 +455,15 @@
** Returns void
**
*******************************************************************************/
-static void gatt_process_read_info_rsp(tGATT_CLCB *p_clcb, UINT16 len, UINT8 *p_data)
+void gatt_process_read_info_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code,
+ UINT16 len, UINT8 *p_data)
{
tGATT_DISC_RES result;
UINT8 *p = p_data, uuid_len = 0, type;
+ UNUSED(p_tcb);
+ UNUSED(op_code);
+
if (len < GATT_INFO_RSP_MIN_LEN)
{
GATT_TRACE_ERROR0("invalid Info Response PDU received, discard.");
@@ -500,10 +514,14 @@
** Returns void.
**
*******************************************************************************/
-static void gatt_proc_disc_error_rsp(tGATT_CLCB *p_clcb, UINT8 opcode, UINT8 reason)
+void gatt_proc_disc_error_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 opcode,
+ UINT16 handle, UINT8 reason)
{
tGATT_STATUS status = (tGATT_STATUS) reason;
+ UNUSED(p_tcb);
+ UNUSED(handle);
+
GATT_TRACE_DEBUG2("gatt_proc_disc_error_rsp reason: %02x cmd_code %04x", reason, opcode);
switch (opcode)
@@ -536,12 +554,16 @@
** Returns void
**
*******************************************************************************/
-static void gatt_process_error_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 *p_data)
+void gatt_process_error_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code,
+ UINT16 len, UINT8 *p_data)
{
UINT8 opcode, reason, * p= p_data;
UINT16 handle;
tGATT_VALUE *p_attr = (tGATT_VALUE *)p_clcb->p_attr_buf;
+ UNUSED(op_code);
+ UNUSED(len);
+
GATT_TRACE_DEBUG0("gatt_process_error_rsp ");
STREAM_TO_UINT8(opcode, p);
STREAM_TO_UINT16(handle, p);
@@ -549,7 +571,7 @@
if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY)
{
- gatt_proc_disc_error_rsp(p_clcb, opcode, reason);
+ gatt_proc_disc_error_rsp(p_tcb, p_clcb, opcode, handle, reason);
}
else
{
@@ -921,12 +943,14 @@
** Returns void
**
*******************************************************************************/
-static void gatt_process_read_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb,
- UINT16 len, UINT8 *p_data)
+void gatt_process_read_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code,
+ UINT16 len, UINT8 *p_data)
{
UINT16 offset = p_clcb->counter;
UINT8 * p= p_data;
+ UNUSED(op_code);
+
if (p_clcb->operation == GATTC_OPTYPE_READ)
{
if (p_clcb->op_subtype != GATT_READ_BY_HANDLE)
@@ -1169,7 +1193,7 @@
switch (op_code)
{
case GATT_RSP_ERROR:
- gatt_process_error_rsp(p_tcb, p_clcb, p_data);
+ gatt_process_error_rsp(p_tcb, p_clcb, op_code, len, p_data);
break;
case GATT_RSP_MTU: /* 2 bytes mtu */
@@ -1177,7 +1201,7 @@
break;
case GATT_RSP_FIND_INFO:
- gatt_process_read_info_rsp(p_clcb, len, p_data);
+ gatt_process_read_info_rsp(p_tcb, p_clcb, op_code, len, p_data);
break;
case GATT_RSP_READ_BY_TYPE:
@@ -1188,11 +1212,11 @@
case GATT_RSP_READ:
case GATT_RSP_READ_BLOB:
case GATT_RSP_READ_MULTI:
- gatt_process_read_rsp(p_tcb, p_clcb, len, p_data);
+ gatt_process_read_rsp(p_tcb, p_clcb, op_code, len, p_data);
break;
case GATT_RSP_FIND_TYPE_VALUE: /* disc service with UUID */
- gatt_process_find_type_value_rsp(p_clcb, len, p_data);
+ gatt_process_find_type_value_rsp(p_tcb, p_clcb, len, p_data);
break;
case GATT_RSP_WRITE:
diff --git a/stack/gatt/gatt_db.c b/stack/gatt/gatt_db.c
index 268bc7d..a1b0a8a 100644
--- a/stack/gatt/gatt_db.c
+++ b/stack/gatt/gatt_db.c
@@ -27,6 +27,7 @@
#if BLE_INCLUDED == TRUE
#include "bt_trace.h"
+#include "bt_utils.h"
#include <stdio.h>
#include <string.h>
@@ -38,11 +39,11 @@
** L O C A L F U N C T I O N P R O T O T Y P E S *
*********************************************************************************/
static BOOLEAN allocate_svc_db_buf(tGATT_SVC_DB *p_db);
-static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *p_uuid128, tGATT_PERM perm);
+static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PERM perm);
static BOOLEAN deallocate_attr_in_db(tGATT_SVC_DB *p_db, void *p_attr);
static BOOLEAN copy_extra_byte_in_db(tGATT_SVC_DB *p_db, void **p_dst, UINT16 len);
-static void gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri);
+static BOOLEAN gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri);
static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code,
UINT16 handle, UINT16 offset, UINT32 trans_id);
@@ -58,7 +59,7 @@
** Returns Status of te operation.
**
*******************************************************************************/
-BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri,
+BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri,
UINT16 s_hdl, UINT16 num_handle)
{
if (!allocate_svc_db_buf(p_db))
@@ -74,9 +75,7 @@
p_db->next_handle = s_hdl;
p_db->end_handle = s_hdl + num_handle;
- gatts_db_add_service_declaration(p_db, service, is_pri);
-
- return TRUE;
+ return gatts_db_add_service_declaration(p_db, p_service, is_pri);
}
/*******************************************************************************
@@ -115,6 +114,7 @@
**
*******************************************************************************/
static tGATT_STATUS gatts_check_attr_readability(tGATT_ATTR16 *p_attr,
+ UINT16 offset,
BOOLEAN read_long,
tGATT_SEC_FLAG sec_flag,
UINT8 key_size)
@@ -122,6 +122,7 @@
UINT16 min_key_size;
tGATT_PERM perm = p_attr->permission;
+ UNUSED(offset);
min_key_size = (((perm & GATT_ENCRYPT_KEY_SIZE_MASK) >> 12));
if (min_key_size != 0 )
{
@@ -223,14 +224,14 @@
offset,
read_long);
- status = gatts_check_attr_readability((tGATT_ATTR16 *)p_attr, read_long, sec_flag, key_size);
-
- if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16)
- uuid16 = p_attr16->uuid;
+ status = gatts_check_attr_readability((tGATT_ATTR16 *)p_attr, offset, read_long, sec_flag, key_size);
if (status != GATT_SUCCESS)
return status;
+ if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16)
+ uuid16 = p_attr16->uuid;
+
status = GATT_NO_RESOURCES;
if (read_long &&
@@ -261,6 +262,12 @@
{
UINT16_TO_STREAM(p, ((tGATT_ATTR16 *)(p_attr16->p_next))->uuid);
}
+ /* convert a 32bits UUID to 128 bits */
+ else if (((tGATT_ATTR32 *)(p_attr16->p_next))->uuid_type == GATT_ATTR_UUID_TYPE_32)
+ {
+ gatt_convert_uuid32_to_uuid128 (p, ((tGATT_ATTR32 *)(p_attr16->p_next))->uuid);
+ p += LEN_UUID_128;
+ }
else
{
ARRAY_TO_STREAM (p, ((tGATT_ATTR128 *)(p_attr16->p_next))->uuid, LEN_UUID_128);
@@ -271,13 +278,17 @@
}
else if (uuid16 == GATT_UUID_INCLUDE_SERVICE)
{
- len = (p_attr16->p_value->incl_handle.service_type.len == 2) ? 6 : 4;
+ if (p_attr16->p_value->incl_handle.service_type.len == LEN_UUID_16)
+ len = 6;
+ else
+ len = 4;
+
if (mtu >= len)
{
UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.s_handle);
UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.e_handle);
- if (p_attr16->p_value->incl_handle.service_type.len == 2)
+ if (p_attr16->p_value->incl_handle.service_type.len == LEN_UUID_16)
{
UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.service_type.uu.uuid16);
}
@@ -345,6 +356,11 @@
attr_uuid.len = LEN_UUID_16;
attr_uuid.uu.uuid16 = p_attr->uuid;
}
+ else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_32)
+ {
+ attr_uuid.len = LEN_UUID_32;
+ attr_uuid.uu.uuid32 = ((tGATT_ATTR32 *)p_attr)->uuid;
+ }
else
{
attr_uuid.len = LEN_UUID_128;
@@ -436,6 +452,7 @@
tBT_UUID service)
{
tGATT_ATTR16 *p_attr;
+ tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_INCLUDE_SERVICE}};
GATT_TRACE_DEBUG3("gatts_add_included_service: s_hdl = 0x%04x e_hdl = 0x%04x uuid = 0x%04x",
s_handle, e_handle, service.uu.uuid16);
@@ -446,7 +463,7 @@
return 0;
}
- if ((p_attr = (tGATT_ATTR16 *) allocate_attr_in_db(p_db, GATT_UUID_INCLUDE_SERVICE, NULL, GATT_PERM_READ)) != NULL)
+ if ((p_attr = (tGATT_ATTR16 *) allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL)
{
if (copy_extra_byte_in_db(p_db, (void **)&p_attr->p_value, sizeof(tGATT_INCL_SRVC)))
{
@@ -485,11 +502,11 @@
tBT_UUID * p_char_uuid)
{
tGATT_ATTR16 *p_char_decl, *p_char_val;
- UINT16 uuid16 = (p_char_uuid->len == LEN_UUID_16) ? p_char_uuid->uu.uuid16 : 0;
+ tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_CHAR_DECLARE}};
GATT_TRACE_DEBUG2("gatts_add_characteristic perm=0x%0x property=0x%0x", perm, property);
- if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, GATT_UUID_CHAR_DECLARE, NULL, GATT_PERM_READ)) != NULL)
+ if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL)
{
if (!copy_extra_byte_in_db(p_db, (void **)&p_char_decl->p_value, sizeof(tGATT_CHAR_DECL)))
{
@@ -497,7 +514,7 @@
return 0;
}
- p_char_val = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, uuid16, p_char_uuid->uu.uuid128, perm);
+ p_char_val = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, p_char_uuid, perm);
if (p_char_val == NULL)
{
@@ -578,14 +595,12 @@
tBT_UUID * p_descr_uuid)
{
tGATT_ATTR16 *p_char_dscptr;
- UINT16 uuid16 = (p_descr_uuid->len == LEN_UUID_16)? p_descr_uuid->uu.uuid16 : 0;
GATT_TRACE_DEBUG1("gatts_add_char_descr uuid=0x%04x", p_descr_uuid->uu.uuid16);
/* Add characteristic descriptors */
if ((p_char_dscptr = (tGATT_ATTR16 *)allocate_attr_in_db(p_db,
- uuid16,
- p_descr_uuid->uu.uuid128,
+ p_descr_uuid,
perm))
== NULL)
{
@@ -695,7 +710,7 @@
{
if (p_attr->handle == handle)
{
- status = gatts_check_attr_readability (p_attr,
+ status = gatts_check_attr_readability (p_attr, 0,
is_long,
sec_flag, key_size);
break;
@@ -812,7 +827,8 @@
GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_INSUF_KEY_SIZE");
}
/* LE security mode 2 attribute */
- else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED))
+ else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)
+ && (perm & GATT_WRITE_ALLOWED) == 0)
{
status = GATT_INSUF_AUTHENTICATION;
GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required");
@@ -842,7 +858,8 @@
break;
}
}
- else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128)
+ else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128 ||
+ p_attr->uuid_type == GATT_ATTR_UUID_TYPE_32)
{
status = GATT_SUCCESS;
}
@@ -897,25 +914,32 @@
**
**
** Parameter p_db : database pointer.
+** p_uuid: pointer to attribute UUID
** service : type of attribute to be added.
**
** Returns pointer to the newly allocated attribute.
**
*******************************************************************************/
-static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *uuid128, tGATT_PERM perm)
+static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PERM perm)
{
tGATT_ATTR16 *p_attr16 = NULL, *p_last;
+ tGATT_ATTR32 *p_attr32 = NULL;
tGATT_ATTR128 *p_attr128 = NULL;
- UINT16 len = (uuid16 == 0) ? sizeof(tGATT_ATTR128): sizeof(tGATT_ATTR16);
+ UINT16 len = sizeof(tGATT_ATTR128);
- GATT_TRACE_DEBUG1("allocate attr %d bytes ",len);
-
- if (uuid16 == GATT_ILLEGAL_UUID && uuid128 == NULL)
+ if (p_uuid == NULL)
{
GATT_TRACE_ERROR0("illegal UUID");
return NULL;
}
+ if (p_uuid->len == LEN_UUID_16)
+ len = sizeof(tGATT_ATTR16);
+ else if (p_uuid->len == LEN_UUID_32)
+ len = sizeof(tGATT_ATTR32);
+
+ GATT_TRACE_DEBUG1("allocate attr %d bytes ",len);
+
if (p_db->end_handle <= p_db->next_handle)
{
GATT_TRACE_DEBUG2("handle space full. handle_max = %d next_handle = %d",
@@ -931,21 +955,25 @@
return NULL;
}
}
-
+ memset(p_db->p_free_mem, 0, len);
p_attr16 = (tGATT_ATTR16 *) p_db->p_free_mem;
- p_attr128 = (tGATT_ATTR128 *) p_db->p_free_mem;
- memset(p_attr16, 0, len);
-
- if (uuid16 != GATT_ILLEGAL_UUID)
+ if (p_uuid->len == LEN_UUID_16 && p_uuid->uu.uuid16 != GATT_ILLEGAL_UUID)
{
p_attr16->uuid_type = GATT_ATTR_UUID_TYPE_16;
- p_attr16->uuid = uuid16;
+ p_attr16->uuid = p_uuid->uu.uuid16;
}
- else
+ else if (p_uuid->len == LEN_UUID_32)
{
+ p_attr32 = (tGATT_ATTR32 *) p_db->p_free_mem;
+ p_attr32->uuid_type = GATT_ATTR_UUID_TYPE_32;
+ p_attr32->uuid = p_uuid->uu.uuid32;
+ }
+ else if (p_uuid->len == LEN_UUID_128)
+ {
+ p_attr128 = (tGATT_ATTR128 *) p_db->p_free_mem;
p_attr128->uuid_type = GATT_ATTR_UUID_TYPE_128;
- memcpy(p_attr128->uuid, uuid128, LEN_UUID_128);
+ memcpy(p_attr128->uuid, p_uuid->uu.uuid128, LEN_UUID_128);
}
p_db->p_free_mem += len;
@@ -970,9 +998,14 @@
if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16)
{
- GATT_TRACE_DEBUG3("=====> handle = [0x%04x] uuid = [0x%04x] perm=0x%02x ",
+ GATT_TRACE_DEBUG3("=====> handle = [0x%04x] uuid16 = [0x%04x] perm=0x%02x ",
p_attr16->handle, p_attr16->uuid, p_attr16->permission);
}
+ else if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_32)
+ {
+ GATT_TRACE_DEBUG3("=====> handle = [0x%04x] uuid32 = [0x%08x] perm=0x%02x ",
+ p_attr32->handle, p_attr32->uuid, p_attr32->permission);
+ }
else
{
GATT_TRACE_DEBUG4("=====> handle = [0x%04x] uuid128 = [0x%02x:0x%02x] perm=0x%02x ",
@@ -1151,21 +1184,44 @@
** Returns void
**
*******************************************************************************/
-static void gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri)
+static BOOLEAN gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri)
{
tGATT_ATTR16 *p_attr;
- UINT16 service_type = is_pri ? GATT_UUID_PRI_SERVICE: GATT_UUID_SEC_SERVICE;
+ tBT_UUID uuid = {LEN_UUID_16, {0}};
+ BOOLEAN rt = FALSE;
GATT_TRACE_DEBUG0( "add_service_declaration");
+ if (is_pri)
+ uuid.uu.uuid16 = GATT_UUID_PRI_SERVICE;
+ else
+ uuid.uu.uuid16 = GATT_UUID_SEC_SERVICE;
+
/* add service declration record */
- if ((p_attr = (tGATT_ATTR16 *)(allocate_attr_in_db(p_db, service_type, NULL, GATT_PERM_READ))) != NULL)
+ if ((p_attr = (tGATT_ATTR16 *)(allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ))) != NULL)
{
if (copy_extra_byte_in_db (p_db, (void **)&p_attr->p_value, sizeof(tBT_UUID)))
{
- memcpy (&p_attr->p_value->uuid, &service, sizeof(tBT_UUID));
+ if (p_service->len == LEN_UUID_16)
+ {
+ p_attr->p_value->uuid.len = LEN_UUID_16;
+ p_attr->p_value->uuid.uu.uuid16 = p_service->uu.uuid16;
+ }
+ else if (p_service->len == LEN_UUID_32)
+ {
+ p_attr->p_value->uuid.len = LEN_UUID_128;
+ gatt_convert_uuid32_to_uuid128(p_attr->p_value->uuid.uu.uuid128, p_service->uu.uuid32);
+ }
+ else
+ {
+ p_attr->p_value->uuid.len = LEN_UUID_128;
+ memcpy(p_attr->p_value->uuid.uu.uuid128, p_service->uu.uuid128, LEN_UUID_128);
+ }
+ rt = TRUE;
}
+
}
+ return rt;
}
#endif /* BLE_INCLUDED */
diff --git a/stack/gatt/gatt_int.h b/stack/gatt/gatt_int.h
index 1f81d63..b6bb95c 100644
--- a/stack/gatt/gatt_int.h
+++ b/stack/gatt/gatt_int.h
@@ -21,8 +21,6 @@
#include "bt_target.h"
-#if BLE_INCLUDED == TRUE
-
#include "bt_trace.h"
#include "gatt_api.h"
@@ -169,6 +167,7 @@
*/
#define GATT_ATTR_UUID_TYPE_16 0
#define GATT_ATTR_UUID_TYPE_128 1
+#define GATT_ATTR_UUID_TYPE_32 2
typedef UINT8 tGATT_ATTR_UUID_TYPE;
/* 16 bits UUID Attribute in server database
@@ -184,6 +183,20 @@
UINT16 uuid;
} tGATT_ATTR16;
+/* 32 bits UUID Attribute in server database
+*/
+typedef struct
+{
+ void *p_next; /* pointer to the next attribute,
+ either tGATT_ATTR16, tGATT_ATTR32 or tGATT_ATTR128 */
+ tGATT_ATTR_VALUE *p_value;
+ tGATT_ATTR_UUID_TYPE uuid_type;
+ tGATT_PERM permission;
+ UINT16 handle;
+ UINT32 uuid;
+} tGATT_ATTR32;
+
+
/* 128 bits UUID Attribute in server database
*/
typedef struct
@@ -340,6 +353,7 @@
BUFFER_Q pending_enc_clcb; /* pending encryption channel q */
tGATT_SEC_ACTION sec_act;
BD_ADDR peer_bda;
+ tBT_TRANSPORT transport;
UINT32 trans_id;
UINT16 att_lcid; /* L2CAP channel ID for ATT */
@@ -400,6 +414,7 @@
BOOLEAN in_use;
TIMER_LIST_ENT rsp_timer_ent; /* peer response timer */
UINT8 retry_count;
+
} tGATT_CLCB;
typedef struct
@@ -454,6 +469,7 @@
BOOLEAN in_use;
BOOLEAN connected;
BD_ADDR bda;
+ tBT_TRANSPORT transport;
}tGATT_PROFILE_CLCB;
typedef struct
@@ -524,9 +540,9 @@
extern void gatt_init (void);
/* from gatt_main.c */
-extern BOOLEAN gatt_disconnect (BD_ADDR rem_bda);
-extern BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr);
-extern BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb);
+extern BOOLEAN gatt_disconnect (tGATT_TCB *p_tcb);
+extern BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, tBT_TRANSPORT transport);
+extern BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb, tBT_TRANSPORT transport);
extern void gatt_data_process (tGATT_TCB *p_tcb, BT_HDR *p_buf);
extern void gatt_update_app_use_link_flag ( tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN is_add, BOOLEAN check_acl_link);
@@ -541,9 +557,8 @@
/* from gatt_attr.c */
extern UINT16 gatt_profile_find_conn_id_by_bd_addr(BD_ADDR bda);
-extern tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_bd_addr(BD_ADDR bda);
extern BOOLEAN gatt_profile_clcb_dealloc (UINT16 conn_id);
-extern tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda);
+extern tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda, tBT_TRANSPORT transport);
/* Functions provided by att_protocol.c */
@@ -558,7 +573,8 @@
extern BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid, UINT16 len, UINT8 **p_data);
extern UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid);
extern BOOLEAN gatt_uuid_compare(tBT_UUID src, tBT_UUID tar);
-extern void gatt_sr_get_sec_info(BD_ADDR rem_bda, BOOLEAN le_conn, UINT8 *p_sec_flag, UINT8 *p_key_size);
+extern void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32);
+extern void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size);
extern void gatt_start_rsp_timer(UINT16 clcb_idx);
extern void gatt_start_conf_timer(tGATT_TCB *p_tcb);
extern void gatt_rsp_timeout(TIMER_LIST_ENT *p_tle);
@@ -573,13 +589,13 @@
extern BOOLEAN gatt_is_srv_chg_ind_pending (tGATT_TCB *p_tcb);
extern tGATTS_SRV_CHG *gatt_is_bda_in_the_srv_chg_clt_list (BD_ADDR bda);
-extern BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx);
+extern BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx, tBT_TRANSPORT *p_transport);
extern void gatt_set_srv_chg(void);
extern void gatt_delete_dev_from_srv_chg_clt_list(BD_ADDR bd_addr);
extern tGATT_VALUE *gatt_add_pending_ind(tGATT_TCB *p_tcb, tGATT_VALUE *p_ind);
extern tGATTS_PENDING_NEW_SRV_START *gatt_add_pending_new_srv_start( tGATTS_HNDL_RANGE *p_new_srv_start);
extern void gatt_free_srvc_db_buffer_app_id(tBT_UUID *p_app_id);
-extern void gatt_update_listen_mode(void);
+extern BOOLEAN gatt_update_listen_mode(void);
/* reserved handle list */
extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_app_id (tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst);
@@ -635,16 +651,16 @@
extern UINT8 gatt_num_apps_hold_link(tGATT_TCB *p_tcb);
extern UINT8 gatt_num_clcb_by_bd_addr(BD_ADDR bda);
extern tGATT_TCB * gatt_find_tcb_by_cid(UINT16 lcid);
-extern tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda);
+extern tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport);
extern tGATT_TCB * gatt_get_tcb_by_idx(UINT8 tcb_idx);
-extern tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda);
-
+extern tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport);
+extern BOOLEAN gatt_send_ble_burst_data (BD_ADDR remote_bda, BT_HDR *p_buf);
/* GATT client functions */
extern void gatt_dequeue_sr_cmd (tGATT_TCB *p_tcb);
extern UINT8 gatt_send_write_msg(tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code, UINT16 handle,
UINT16 len, UINT16 offset, UINT8 *p_data);
-extern void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason);
+extern void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport);
extern void gatt_end_operation(tGATT_CLCB *p_clcb, tGATT_STATUS status, void *p_data);
extern void gatt_act_discovery(tGATT_CLCB *p_clcb);
@@ -667,7 +683,7 @@
extern void gatt_set_sec_act(tGATT_TCB *p_tcb, tGATT_SEC_ACTION sec_act);
/* gatt_db.c */
-extern BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri, UINT16 s_hdl, UINT16 num_handle);
+extern BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri, UINT16 s_hdl, UINT16 num_handle);
extern UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e_handle, tBT_UUID service);
extern UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, tGATT_CHAR_PROP property, tBT_UUID *p_char_uuid);
extern UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, tBT_UUID *p_dscp_uuid);
@@ -684,4 +700,4 @@
extern void gatt_reset_bgdev_list(void);
#endif
-#endif /* BLE_INCLUDED */
+
diff --git a/stack/gatt/gatt_main.c b/stack/gatt/gatt_main.c
index d5e017b..59c6759 100644
--- a/stack/gatt/gatt_main.c
+++ b/stack/gatt/gatt_main.c
@@ -44,7 +44,7 @@
/********************************************************************************/
/* L O C A L F U N C T I O N P R O T O T Y P E S */
/********************************************************************************/
-static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason);
+static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason, tBT_TRANSPORT transport);
static void gatt_le_data_ind (BD_ADDR bd_addr, BT_HDR *p_buf);
static void gatt_l2cif_connect_ind_cback (BD_ADDR bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id);
@@ -143,15 +143,14 @@
** Returns TRUE if connection is started, otherwise return FALSE.
**
*******************************************************************************/
-BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb)
+BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb, tBT_TRANSPORT transport)
{
BOOLEAN gatt_ret = FALSE;
if (gatt_get_ch_state(p_tcb) != GATT_CH_OPEN)
gatt_set_ch_state(p_tcb, GATT_CH_CONN);
- /* select the physical link for GATT connection */
- if (BTM_UseLeLink(rem_bda))
+ if (transport == BT_TRANSPORT_LE)
{
p_tcb->att_lcid = L2CAP_ATT_CID;
gatt_ret = L2CA_ConnectFixedChnl (L2CAP_ATT_CID, rem_bda);
@@ -171,15 +170,14 @@
**
** Description This function is called to disconnect to an ATT device.
**
-** Parameter rem_bda: remote device address to disconnect from.
+** Parameter p_tcb: pointer to the TCB to disconnect.
**
** Returns TRUE: if connection found and to be disconnected; otherwise
** return FALSE.
**
*******************************************************************************/
-BOOLEAN gatt_disconnect (BD_ADDR rem_bda)
+BOOLEAN gatt_disconnect (tGATT_TCB *p_tcb)
{
- tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(rem_bda);
BOOLEAN ret = FALSE;
tGATT_CH_STATE ch_state;
GATT_TRACE_DEBUG0 ("gatt_disconnect ");
@@ -194,12 +192,12 @@
if (ch_state == GATT_CH_OPEN)
{
/* only LCB exist between remote device and local */
- ret = L2CA_RemoveFixedChnl (L2CAP_ATT_CID, rem_bda);
+ ret = L2CA_RemoveFixedChnl (L2CAP_ATT_CID, p_tcb->peer_bda);
}
else
{
gatt_set_ch_state(p_tcb, GATT_CH_CLOSING);
- ret = L2CA_CancelBleConnectReq (rem_bda);
+ ret = L2CA_CancelBleConnectReq (p_tcb->peer_bda);
}
}
else
@@ -286,13 +284,14 @@
if (check_acl_link &&
p_tcb &&
- (BTM_GetHCIConnHandle(p_tcb->peer_bda) != GATT_INVALID_ACL_HANDLE))
+ p_tcb->att_lcid == L2CAP_ATT_CID && /* only update link idle timer for fixed channel */
+ (BTM_GetHCIConnHandle(p_tcb->peer_bda, p_tcb->transport) != GATT_INVALID_ACL_HANDLE))
{
if (is_add)
{
GATT_TRACE_DEBUG0("GATT disables link idle timer");
/* acl link is connected disable the idle timeout */
- GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT);
+ GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport);
}
else
{
@@ -301,7 +300,7 @@
/* acl link is connected but no application needs to use the link
so set the timeout value to GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP seconds */
GATT_TRACE_DEBUG1("GATT starts link idle timer =%d sec", GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP);
- GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP);
+ GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP, p_tcb->transport);
}
}
@@ -317,25 +316,22 @@
** Returns void.
**
*******************************************************************************/
-BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr)
+BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, tBT_TRANSPORT transport)
{
BOOLEAN ret = FALSE;
tGATT_TCB *p_tcb;
UINT8 st;
- GATT_TRACE_DEBUG0("gatt_act_connect");
-
- if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) != NULL)
+ if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, transport)) != NULL)
{
ret = TRUE;
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 &&
- /* only connection on fix channel when the l2cap channel is already open */
- p_tcb->att_lcid == L2CAP_ATT_CID )
+ transport == BT_TRANSPORT_LE )
{
- if (!gatt_connect(bd_addr, p_tcb))
+ if (!gatt_connect(bd_addr, p_tcb, transport))
ret = FALSE;
}
else if(st == GATT_CH_CLOSING)
@@ -346,9 +342,9 @@
}
else
{
- if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr)) != NULL)
+ if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, transport)) != NULL)
{
- if (!gatt_connect(bd_addr, p_tcb))
+ if (!gatt_connect(bd_addr, p_tcb, transport))
{
GATT_TRACE_ERROR0("gatt_connect failed");
memset(p_tcb, 0, sizeof(tGATT_TCB));
@@ -380,19 +376,22 @@
** connected (conn = TRUE)/disconnected (conn = FALSE).
**
*******************************************************************************/
-static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason)
+static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected,
+ UINT16 reason, tBT_TRANSPORT transport)
{
- tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr);
-
+ tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
BOOLEAN check_srv_chg = FALSE;
tGATTS_SRV_CHG *p_srv_chg_clt=NULL;
+ /* ignore all fixed channel connect/disconnect on BR/EDR link for GATT */
+ if (transport == BT_TRANSPORT_BR_EDR)
+ return;
+
GATT_TRACE_DEBUG3 ("GATT ATT protocol channel with BDA: %08x%04x is %s",
(bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
(bd_addr[4]<<8)+bd_addr[5], (connected) ? "connected" : "disconnected");
-
if ((p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr)) != NULL)
{
check_srv_chg = TRUE;
@@ -405,11 +404,6 @@
if (connected)
{
- GATT_TRACE_DEBUG1("connected is TRUE reason=%d",reason );
- /* BR/EDR lik, ignore this callback */
- if (reason == 0)
- return;
-
/* do we have a channel initiating a connection? */
if (p_tcb)
{
@@ -426,9 +420,10 @@
}
}
/* this is incoming connection or background connection callback */
+
else
{
- if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr)) != NULL)
+ if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, BT_TRANSPORT_LE)) != NULL)
{
p_tcb->att_lcid = L2CAP_ATT_CID;
@@ -450,7 +445,7 @@
}
else
{
- gatt_cleanup_upon_disc(bd_addr, reason);
+ gatt_cleanup_upon_disc(bd_addr, reason, transport);
GATT_TRACE_DEBUG0 ("ATT disconnected");
}
}
@@ -475,7 +470,7 @@
tGATT_TCB *p_tcb;
/* Find CCB based on bd addr */
- if ((p_tcb = gatt_find_tcb_by_addr (bd_addr)) != NULL &&
+ if ((p_tcb = gatt_find_tcb_by_addr (bd_addr, BT_TRANSPORT_LE)) != NULL &&
gatt_get_ch_state(p_tcb) >= GATT_CH_OPEN)
{
gatt_data_process(p_tcb, p_buf);
@@ -508,7 +503,7 @@
/* do we already have a control channel for this peer? */
UINT8 result = L2CAP_CONN_OK;
tL2CAP_CFG_INFO cfg;
- tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr);
+ tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_BR_EDR);
UNUSED(psm);
GATT_TRACE_ERROR1("Connection indication cid = %d", lcid);
@@ -516,7 +511,7 @@
if (p_tcb == NULL)
{
/* allocate tcb */
- if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr)) == NULL)
+ if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
{
/* no tcb available, reject L2CAP connection */
result = L2CAP_CONN_NO_RESOURCES;
@@ -586,7 +581,7 @@
/* else initiating connection failure */
else
{
- gatt_cleanup_upon_disc(p_tcb->peer_bda, GATT_CONN_L2C_FAILURE);
+ gatt_cleanup_upon_disc(p_tcb->peer_bda, result, GATT_TRANSPORT_BR_EDR);
}
}
else /* wrong state, disconnect it */
@@ -701,11 +696,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 */
@@ -738,20 +730,17 @@
/* send L2CAP disconnect response */
L2CA_DisconnectRsp(lcid);
}
-
if (gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda) == NULL)
{
- 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);
}
-
/* if ACL link is still up, no reason is logged, l2cap is disconnect from peer */
- if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda)) == 0)
+ if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda, p_tcb->transport)) == 0)
reason = GATT_CONN_TERMINATE_PEER_USER;
/* send disconnect callback */
- gatt_cleanup_upon_disc(p_tcb->peer_bda, reason);
+ gatt_cleanup_upon_disc(p_tcb->peer_bda, reason, GATT_TRANSPORT_BR_EDR);
}
}
@@ -777,17 +766,16 @@
/* If the device is not in the service changed client list, add it... */
if (gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda) == NULL)
{
- 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 disconnect callback */
/* if ACL link is still up, no reason is logged, l2cap is disconnect from peer */
- if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda)) == 0)
+ if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda, p_tcb->transport)) == 0)
reason = GATT_CONN_TERMINATE_LOCAL_HOST;
- gatt_cleanup_upon_disc(p_tcb->peer_bda, reason);
+ gatt_cleanup_upon_disc(p_tcb->peer_bda, reason, GATT_TRANSPORT_BR_EDR);
}
}
@@ -846,16 +834,17 @@
if (p_reg->app_cb.p_conn_cb)
{
conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
- (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id, TRUE, 0);
+ (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id,
+ TRUE, 0, p_tcb->transport);
}
}
}
- if (gatt_num_apps_hold_link(p_tcb))
+ if (gatt_num_apps_hold_link(p_tcb) && p_tcb->att_lcid == L2CAP_ATT_CID )
{
/* disable idle timeout if one or more clients are holding the link disable the idle timer */
- GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT);
+ GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport);
}
}
@@ -894,7 +883,6 @@
if (op_code == GATT_SIGN_CMD_WRITE)
{
gatt_verify_signature(p_tcb, p_buf);
- return;
}
else
{
@@ -1068,6 +1056,7 @@
BD_ADDR bda;
BOOLEAN srv_chg_ind_pending=FALSE;
tGATT_TCB *p_tcb;
+ tBT_TRANSPORT transport;
GATT_TRACE_DEBUG0 ("gatt_proc_srv_chg");
@@ -1075,7 +1064,7 @@
{
gatt_set_srv_chg();
start_idx =0;
- while (gatt_find_the_connected_bda(start_idx, bda, &found_idx))
+ while (gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport))
{
p_tcb = &gatt_cb.tcb[found_idx];;
srv_chg_ind_pending = gatt_is_srv_chg_ind_pending(p_tcb);
diff --git a/stack/gatt/gatt_sr.c b/stack/gatt/gatt_sr.c
index c006dd2..226aad0 100644
--- a/stack/gatt/gatt_sr.c
+++ b/stack/gatt/gatt_sr.c
@@ -328,7 +328,7 @@
** Returns void
**
*******************************************************************************/
-static void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT8 *p_data)
+void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data)
{
UINT8 *p = p_data, flag, i = 0;
UINT32 trans_id = 0;
@@ -336,11 +336,13 @@
tGATT_IF gatt_if;
UINT16 conn_id;
+ UNUSED(len);
+
#if GATT_CONFORMANCE_TESTING == TRUE
if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code)
{
- GATT_TRACE_DEBUG2("conf test forced err rsp for %s error status=%d",
- __FUNCTION__,gatt_cb.err_status);
+ GATT_TRACE_DEBUG1("Conformance tst: forced err rspv for Execute Write: error status=%d",
+ gatt_cb.err_status);
gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, gatt_cb.handle, FALSE);
@@ -409,7 +411,7 @@
p_tcb->sr_cmd.multi_req.num_handles = 0;
gatt_sr_get_sec_info(p_tcb->peer_bda,
- (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID),
+ p_tcb->transport,
&sec_flag,
&key_size);
@@ -527,7 +529,7 @@
*******************************************************************************/
static tGATT_STATUS gatt_build_primary_service_rsp (BT_HDR *p_msg, tGATT_TCB *p_tcb,
UINT8 op_code, UINT16 s_hdl,
- UINT16 e_hdl, tBT_UUID value)
+ UINT16 e_hdl, UINT8 *p_data, tBT_UUID value)
{
tGATT_STATUS status = GATT_NOT_FOUND;
UINT8 handle_len =4, *p ;
@@ -536,6 +538,8 @@
tGATT_SRV_LIST_ELEM *p_srv=NULL;
tBT_UUID *p_uuid;
+ UNUSED(p_data);
+
p = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET;
p_srv = p_list->p_first;
@@ -643,7 +647,7 @@
if (p_attr->handle >= s_hdl)
{
if (p_msg->offset == 0)
- p_msg->offset = (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128) ? GATT_INFO_TYPE_PAIR_128 : GATT_INFO_TYPE_PAIR_16;
+ p_msg->offset = (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) ? GATT_INFO_TYPE_PAIR_16 : GATT_INFO_TYPE_PAIR_128;
if (len >= info_pair_len[p_msg->offset - 1])
{
@@ -652,12 +656,17 @@
UINT16_TO_STREAM(p, p_attr->handle);
UINT16_TO_STREAM(p, p_attr->uuid);
}
- else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 &&
- p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128 )
+ else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 && p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128 )
{
UINT16_TO_STREAM(p, p_attr->handle);
ARRAY_TO_STREAM (p, ((tGATT_ATTR128 *) p_attr)->uuid, LEN_UUID_128);
}
+ else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 && p_attr->uuid_type == GATT_ATTR_UUID_TYPE_32)
+ {
+ UINT16_TO_STREAM(p, p_attr->handle);
+ gatt_convert_uuid32_to_uuid128(p, ((tGATT_ATTR32 *) p_attr)->uuid);
+ p += LEN_UUID_128;
+ }
else
{
GATT_TRACE_ERROR0("format mismatch");
@@ -764,6 +773,7 @@
BT_HDR *p_msg = NULL;
UINT16 msg_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
+ memset (&value, 0, sizeof(tBT_UUID));
reason = gatts_validate_packet_format(op_code, &len, &p_data, &uuid, &s_hdl, &e_hdl);
if (reason == GATT_SUCCESS)
@@ -786,7 +796,7 @@
else
{
memset(p_msg, 0, msg_len);
- reason = gatt_build_primary_service_rsp (p_msg, p_tcb, op_code, s_hdl, e_hdl, value);
+ reason = gatt_build_primary_service_rsp (p_msg, p_tcb, op_code, s_hdl, e_hdl, p_data, value);
}
}
}
@@ -1025,7 +1035,7 @@
p_rcb->e_hdl < s_hdl))
{
gatt_sr_get_sec_info(p_tcb->peer_bda,
- (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID),
+ p_tcb->transport,
&sec_flag,
&key_size);
@@ -1120,7 +1130,7 @@
}
gatt_sr_get_sec_info(p_tcb->peer_bda,
- (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID),
+ p_tcb->transport,
&sec_flag,
&key_size);
@@ -1173,7 +1183,7 @@
**
*******************************************************************************/
static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8 op_code,
- UINT16 handle, UINT8 *p_data)
+ UINT16 handle, UINT16 len, UINT8 *p_data)
{
UINT16 buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
tGATT_STATUS reason;
@@ -1181,6 +1191,7 @@
UINT8 sec_flag, key_size, *p;
UINT16 offset = 0, value_len = 0;
+ UNUSED (len);
if ((p_msg = (BT_HDR *)GKI_getbuf(buf_len)) == NULL)
{
GATT_TRACE_ERROR0("gatts_process_find_info failed. no resources.");
@@ -1199,7 +1210,7 @@
buf_len = p_tcb->payload_size - 1;
gatt_sr_get_sec_info(p_tcb->peer_bda,
- (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID),
+ p_tcb->transport,
&sec_flag,
&key_size);
@@ -1289,7 +1300,7 @@
{
case GATT_REQ_READ: /* read char/char descriptor value */
case GATT_REQ_READ_BLOB:
- gatts_process_read_req(p_tcb, p_rcb, op_code, handle, p);
+ gatts_process_read_req(p_tcb, p_rcb, op_code, handle, len, p);
break;
case GATT_REQ_WRITE: /* write char/char descriptor value */
@@ -1506,7 +1517,7 @@
break;
case GATT_REQ_EXEC_WRITE:
- gatt_process_exec_write_req (p_tcb, op_code, p_data);
+ gatt_process_exec_write_req (p_tcb, op_code, len, p_data);
break;
case GATT_REQ_READ_MULTI:
diff --git a/stack/gatt/gatt_utils.c b/stack/gatt/gatt_utils.c
index 978c88c..d3d4c92 100644
--- a/stack/gatt/gatt_utils.c
+++ b/stack/gatt/gatt_utils.c
@@ -705,7 +705,8 @@
** Returns TRUE if found
**
*******************************************************************************/
-BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx)
+BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx,
+ tBT_TRANSPORT *p_transport)
{
UINT8 i;
BOOLEAN found = FALSE;
@@ -717,6 +718,7 @@
{
memcpy( bda, gatt_cb.tcb[i].peer_bda, BD_ADDR_LEN);
*p_found_idx = i;
+ *p_transport = gatt_cb.tcb[i].transport;
found = TRUE;
GATT_TRACE_DEBUG6("gatt_find_the_connected_bda bda :%02x-%02x-%02x-%02x-%02x-%02x",
bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
@@ -833,19 +835,19 @@
** Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
**
*******************************************************************************/
-UINT8 gatt_find_i_tcb_by_addr(BD_ADDR bda)
+UINT8 gatt_find_i_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport)
{
- UINT8 i = 0, j = GATT_INDEX_INVALID;
+ UINT8 i = 0;
for ( ; i < GATT_MAX_PHY_CHANNEL; i ++)
{
- if (!memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN))
+ if (!memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN) &&
+ gatt_cb.tcb[i].transport == transport)
{
- j = i;
- break;
+ return i;
}
}
- return j;
+ return GATT_INDEX_INVALID;
}
@@ -877,12 +879,12 @@
** Returns NULL if not found. Otherwise index to the tcb.
**
*******************************************************************************/
-tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda)
+tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport)
{
tGATT_TCB *p_tcb = NULL;
UINT8 i = 0;
- if ((i = gatt_find_i_tcb_by_addr(bda)) != GATT_INDEX_INVALID)
+ if ((i = gatt_find_i_tcb_by_addr(bda, transport)) != GATT_INDEX_INVALID)
p_tcb = &gatt_cb.tcb[i];
return p_tcb;
@@ -919,14 +921,14 @@
** Returns GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
**
*******************************************************************************/
-tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda)
+tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport)
{
UINT8 i = 0;
BOOLEAN allocated = FALSE;
tGATT_TCB *p_tcb = NULL;
/* search for existing tcb with matching bda */
- i = gatt_find_i_tcb_by_addr(bda);
+ i = gatt_find_i_tcb_by_addr(bda, transport);
/* find free tcb */
if (i == GATT_INDEX_INVALID)
{
@@ -944,6 +946,7 @@
GKI_init_q (&p_tcb->pending_ind_q);
p_tcb->in_use = TRUE;
p_tcb->tcb_idx = i;
+ p_tcb->transport = transport;
}
memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN);
}
@@ -970,6 +973,23 @@
/*******************************************************************************
**
+** Function gatt_convert_uuid32_to_uuid128
+**
+** Description Convert a 32 bits UUID to be an standard 128 bits one.
+**
+** Returns TRUE if two uuid match; FALSE otherwise.
+**
+*******************************************************************************/
+void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32)
+{
+ UINT8 *p = &uuid_128[LEN_UUID_128 - 4];
+
+ memcpy (uuid_128, base_uuid, LEN_UUID_128);
+
+ UINT32_TO_STREAM(p, uuid_32);
+}
+/*******************************************************************************
+**
** Function gatt_uuid_compare
**
** Description Compare two UUID to see if they are the same.
@@ -989,11 +1009,17 @@
}
/* If both are 16-bit, we can do a simple compare */
- if (src.len == 2 && tar.len == 2)
+ if (src.len == LEN_UUID_16 && tar.len == LEN_UUID_16)
{
return src.uu.uuid16 == tar.uu.uuid16;
}
+ /* If both are 32-bit, we can do a simple compare */
+ if (src.len == LEN_UUID_32 && tar.len == LEN_UUID_32)
+ {
+ return src.uu.uuid32 == tar.uu.uuid32;
+ }
+
/* One or both of the UUIDs is 128-bit */
if (src.len == LEN_UUID_16)
{
@@ -1001,6 +1027,11 @@
gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16);
ps = su;
}
+ else if (src.len == LEN_UUID_32)
+ {
+ gatt_convert_uuid32_to_uuid128(su, src.uu.uuid32);
+ ps = su;
+ }
else
ps = src.uu.uuid128;
@@ -1010,6 +1041,12 @@
gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16);
pt = tu;
}
+ else if (tar.len == LEN_UUID_32)
+ {
+ /* convert a 32 bits UUID to 128 bits value */
+ gatt_convert_uuid32_to_uuid128(tu, tar.uu.uuid32);
+ pt = tu;
+ }
else
pt = tar.uu.uuid128;
@@ -1035,6 +1072,12 @@
UINT16_TO_STREAM (p, uuid.uu.uuid16);
len = LEN_UUID_16;
}
+ else if (uuid.len == LEN_UUID_32) /* always convert 32 bits into 128 bits as alwats */
+ {
+ gatt_convert_uuid32_to_uuid128(p, uuid.uu.uuid32);
+ p += LEN_UUID_128;
+ len = LEN_UUID_128;
+ }
else if (uuid.len == LEN_UUID_128)
{
ARRAY_TO_STREAM (p, uuid.uu.uuid128, LEN_UUID_128);
@@ -1090,7 +1133,11 @@
STREAM_TO_UINT16(p_uuid_rec->uu.uuid16, p_uuid);
}
else
- is_base_uuid = FALSE;
+ {
+ p_uuid += (LEN_UUID_128 - LEN_UUID_32);
+ p_uuid_rec->len = LEN_UUID_32;
+ STREAM_TO_UINT32(p_uuid_rec->uu.uuid32, p_uuid);
+ }
}
if (!is_base_uuid)
{
@@ -1100,6 +1147,9 @@
*p_data += LEN_UUID_128;
break;
+ /* do not allow 32 bits UUID in ATT PDU now */
+ case LEN_UUID_32:
+ GATT_TRACE_ERROR0("DO NOT ALLOW 32 BITS UUID IN ATT PDU");
case 0:
default:
if (uuid_size != 0) ret = FALSE;
@@ -1200,7 +1250,7 @@
}
GATT_TRACE_WARNING0("gatt_rsp_timeout disconnecting...");
- gatt_disconnect (p_clcb->p_tcb->peer_bda);
+ gatt_disconnect (p_clcb->p_tcb);
}
/*******************************************************************************
@@ -1330,12 +1380,11 @@
** Returns void
**
*******************************************************************************/
-void gatt_sr_get_sec_info(BD_ADDR rem_bda, BOOLEAN le_conn, UINT8 *p_sec_flag, UINT8 *p_key_size)
+void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size)
{
UINT8 sec_flag = 0;
- UNUSED(le_conn);
- BTM_GetSecurityFlags(rem_bda, &sec_flag);
+ BTM_GetSecurityFlagsByTransport(rem_bda, &sec_flag, transport);
sec_flag &= (GATT_SEC_FLAG_LKEY_UNAUTHED | GATT_SEC_FLAG_LKEY_AUTHED | GATT_SEC_FLAG_ENCRYPTED);
@@ -1438,6 +1487,14 @@
case LEN_UUID_16:
SDP_AddServiceClassIdList(sdp_handle, 1, &p_uuid->uu.uuid16);
break;
+
+ case LEN_UUID_32:
+ UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES);
+ UINT32_TO_BE_STREAM (p, p_uuid->uu.uuid32);
+ SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE,
+ (UINT32) (p - buff), buff);
+ break;
+
case LEN_UUID_128:
UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
ARRAY_TO_BE_STREAM (p, p_uuid->uu.uuid128, LEN_UUID_128);
@@ -1889,7 +1946,8 @@
tGATT_TCB *p_tcb=NULL;
BOOLEAN status= TRUE;
- p_tcb = gatt_find_tcb_by_addr(bda);
+ p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE);
+
if (p_tcb)
{
if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN)
@@ -1902,7 +1960,7 @@
gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE);
if (!gatt_num_apps_hold_link(p_tcb))
{
- gatt_disconnect(p_tcb->peer_bda);
+ gatt_disconnect(p_tcb);
}
}
}
@@ -2131,7 +2189,7 @@
** Returns 16 bits uuid.
**
*******************************************************************************/
-void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason)
+void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport)
{
tGATT_TCB *p_tcb = NULL;
tGATT_CLCB *p_clcb;
@@ -2142,9 +2200,10 @@
GATT_TRACE_DEBUG0 ("gatt_cleanup_upon_disc ");
- if ((p_tcb = gatt_find_tcb_by_addr(bda)) != NULL)
+ if ((p_tcb = gatt_find_tcb_by_addr(bda, transport)) != NULL)
{
GATT_TRACE_DEBUG0 ("found p_tcb ");
+ gatt_set_ch_state(p_tcb, GATT_CH_CLOSE);
for (i = 0; i < GATT_CL_MAX_LCB; i ++)
{
p_clcb = &gatt_cb.clcb[i];
@@ -2172,7 +2231,7 @@
{
conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
GATT_TRACE_DEBUG3 ("found p_reg tcb_idx=%d gatt_if=%d conn_id=0x%x", p_tcb->tcb_idx, p_reg->gatt_if, conn_id);
- (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, FALSE, reason);
+ (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, FALSE, reason, transport);
}
}
memset(p_tcb, 0, sizeof(tGATT_TCB));
@@ -2228,6 +2287,10 @@
{
sprintf(str_buf, "0x%04x", bt_uuid.uu.uuid16);
}
+ else if (bt_uuid.len == LEN_UUID_32)
+ {
+ sprintf(str_buf, "0x%08x", (unsigned int)bt_uuid.uu.uuid32);
+ }
else if (bt_uuid.len == LEN_UUID_128)
{
x += sprintf(&str_buf[x], "0x%02x%02x%02x%02x%02x%02x%02x%02x",
@@ -2406,7 +2469,7 @@
*******************************************************************************/
BOOLEAN gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr)
{
- tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr);
+ tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
BOOLEAN status;
if (p_tcb)
@@ -2628,7 +2691,7 @@
{
BOOLEAN ret = FALSE;
tGATT_REG *p_reg;
- tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr);
+ tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
GATT_TRACE_API0 ("gatt_update_auto_connect_dev ");
/* Make sure app is registered */
@@ -2659,54 +2722,6 @@
/*******************************************************************************
**
-** Function gatt_get_conn_id
-**
-** Description This function returns a connecttion handle to a ATT server
-** if the server is already connected
-**
-** Parameters gatt_if: client interface.
-** bd_addr: peer device address.
-**
-** Returns Connection handle or invalid handle value
-**
-*******************************************************************************/
-UINT16 gatt_get_conn_id (tGATT_IF gatt_if, BD_ADDR bd_addr)
-{
- tGATT_REG *p_reg;
- tGATT_CLCB *p_clcb;
- tGATT_TCB *p_tcb;
- UINT8 i;
-
- GATT_TRACE_API1 ("GATTC_GetConnIfConnected gatt_if=%d", gatt_if);
- /* Do we have a transport to the peer ? If not, we are not connected */
- if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) == NULL)
- {
- GATT_TRACE_EVENT0 ("GATTC_GetConnIfConnected - no TCB found");
- return(GATT_INVALID_CONN_ID);
- }
-
- /* Make sure app is registered */
- if ((p_reg = gatt_get_regcb(gatt_if)) == NULL)
- {
- GATT_TRACE_ERROR1("GATTC_GetConnIfConnected - gatt_if is not registered", gatt_if);
- return(GATT_INVALID_CONN_ID);
- }
-
- /* Now see if the app already has a client control block to that peer */
- for (i = 0, p_clcb = gatt_cb.clcb; i < GATT_CL_MAX_LCB; i++, p_clcb++)
- {
- if ( p_clcb->in_use && (p_clcb->p_reg == p_reg) && (p_clcb->p_tcb == p_tcb) )
- {
- return(p_clcb->conn_id);
- }
- }
-
- /* If here, failed to allocate a client control block */
- GATT_TRACE_ERROR1 ("gatt_get_conn_id: not connected- gatt_if: %u", gatt_if);
- return(GATT_INVALID_CONN_ID);
-}
-/*******************************************************************************
-**
** Function gatt_add_pending_new_srv_start
**
** Description Add a pending new srv start to the new service start queue
@@ -2736,12 +2751,13 @@
** Returns Pointer to the new service start buffer, NULL no buffer available
**
*******************************************************************************/
-void gatt_update_listen_mode(void)
+BOOLEAN gatt_update_listen_mode(void)
{
UINT8 ii = 0;
tGATT_REG *p_reg = &gatt_cb.cl_rcb[0];
UINT8 listening = 0;
UINT16 connectability, window, interval;
+ BOOLEAN rt = TRUE;
for (; ii < GATT_MAX_APPS; ii ++, p_reg ++)
{
@@ -2757,16 +2773,24 @@
else
BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_WL);
- connectability = BTM_ReadConnectability (&window, &interval);
-
- if (listening != GATT_LISTEN_TO_NONE)
+ if (rt)
{
- connectability |= BTM_BLE_CONNECTABLE;
+ connectability = BTM_ReadConnectability (&window, &interval);
+
+ if (listening != GATT_LISTEN_TO_NONE)
+ {
+ connectability |= BTM_BLE_CONNECTABLE;
+ }
+ else
+ {
+ if ((connectability & BTM_BLE_CONNECTABLE) == 0)
+ connectability &= ~BTM_BLE_CONNECTABLE;
+ }
+ /* turning on the adv now */
+ btm_ble_set_connectability(connectability);
}
- else
- connectability &= ~BTM_BLE_CONNECTABLE;
- /* turning on the adv now */
- BTM_SetConnectability(connectability, window, interval);
+
+ return rt;
}
#endif
diff --git a/stack/hcic/hciblecmds.c b/stack/hcic/hciblecmds.c
index aa2e747..860fb7a 100644
--- a/stack/hcic/hciblecmds.c
+++ b/stack/hcic/hciblecmds.c
@@ -35,27 +35,6 @@
#if (defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE)
-BOOLEAN btsnd_hcic_ble_reset(void)
-{
- BT_HDR *p;
- UINT8 *pp;
-
- if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL)
- return (FALSE);
-
- pp = (UINT8 *)(p + 1);
-
- p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
- p->offset = 0;
-
- UINT16_TO_STREAM (pp, HCI_BLE_RESET);
- UINT8_TO_STREAM (pp, 0);
-
- btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
- return (TRUE);
-
-}
-
BOOLEAN btsnd_hcic_ble_set_evt_mask (BT_EVENT_MASK event_mask)
{
BT_HDR *p;
@@ -856,4 +835,62 @@
return (TRUE);
}
+#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
+
+BOOLEAN btsnd_hcic_ble_rc_param_req_reply( UINT16 handle,
+ UINT16 conn_int_min, UINT16 conn_int_max,
+ UINT16 conn_latency, UINT16 conn_timeout,
+ UINT16 min_ce_len, UINT16 max_ce_len )
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY)) == NULL)
+ return (FALSE);
+
+ pp = (UINT8 *)(p + 1);
+
+ p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY;
+ p->offset = 0;
+
+ UINT16_TO_STREAM (pp, HCI_BLE_RC_PARAM_REQ_REPLY);
+ UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY);
+
+ UINT16_TO_STREAM (pp, handle);
+ UINT16_TO_STREAM (pp, conn_int_min);
+ UINT16_TO_STREAM (pp, conn_int_max);
+ UINT16_TO_STREAM (pp, conn_latency);
+ UINT16_TO_STREAM (pp, conn_timeout);
+ UINT16_TO_STREAM (pp, min_ce_len);
+ UINT16_TO_STREAM (pp, max_ce_len);
+
+ btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
+ return (TRUE);
+}
+
+BOOLEAN btsnd_hcic_ble_rc_param_req_neg_reply(UINT16 handle, UINT8 reason)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY)) == NULL)
+ return (FALSE);
+
+ pp = (UINT8 *)(p + 1);
+
+ p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY;
+ p->offset = 0;
+
+ UINT16_TO_STREAM (pp, HCI_BLE_RC_PARAM_REQ_NEG_REPLY);
+ UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY);
+
+ UINT16_TO_STREAM (pp, handle);
+ UINT8_TO_STREAM (pp, reason);
+
+ btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
+ return (TRUE);
+}
#endif
+
+#endif
+
diff --git a/stack/hid/hidh_conn.c b/stack/hid/hidh_conn.c
index 00c9d05..6fbf849 100644
--- a/stack/hid/hidh_conn.c
+++ b/stack/hid/hidh_conn.c
@@ -163,10 +163,11 @@
** send security block L2C connection response.
**
*******************************************************************************/
-void hidh_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+void hidh_sec_check_complete_term (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
{
tHID_HOST_DEV_CTB *p_dev= (tHID_HOST_DEV_CTB *) p_ref_data;
UNUSED(bd_addr);
+ UNUSED (transport);
if( res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY )
{
@@ -316,7 +317,7 @@
** Returns void
**
*******************************************************************************/
-void hidh_sec_check_complete_orig (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+void hidh_sec_check_complete_orig (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
{
tHID_HOST_DEV_CTB *p_dev = (tHID_HOST_DEV_CTB *) p_ref_data;
UINT8 dhandle;
@@ -325,6 +326,7 @@
#endif
UINT32 reason;
UNUSED(bd_addr);
+ UNUSED (transport);
dhandle = ((UINT32)p_dev - (UINT32)&(hh_cb.devices[0]))/ sizeof(tHID_HOST_DEV_CTB);
if( res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY )
@@ -880,6 +882,13 @@
UINT8 use_data = 0 ;
BOOLEAN blank_datc = FALSE;
+ if (!BTM_IsAclConnectionUp(hh_cb.devices[dhandle].addr, BT_TRANSPORT_BR_EDR))
+ {
+ if (buf)
+ GKI_freebuf ((void *)buf);
+ return( HID_ERR_NO_CONNECTION );
+ }
+
if (p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED)
{
if (buf)
diff --git a/stack/include/bt_types.h b/stack/include/bt_types.h
index 33fb884..e7a7937 100644
--- a/stack/include/bt_types.h
+++ b/stack/include/bt_types.h
@@ -497,6 +497,10 @@
#define BLE_ADDR_TYPE_MASK (BLE_ADDR_RANDOM | BLE_ADDR_PUBLIC)
typedef UINT8 tBLE_ADDR_TYPE;
+#define BT_TRANSPORT_BR_EDR 1
+#define BT_TRANSPORT_LE 2
+typedef UINT8 tBT_TRANSPORT;
+
#define BLE_ADDR_IS_STATIC(x) ((x[0] & 0xC0) == 0xC0)
typedef struct
diff --git a/stack/include/btm_api.h b/stack/include/btm_api.h
index f4b17d4..368e70d 100644
--- a/stack/include/btm_api.h
+++ b/stack/include/btm_api.h
@@ -200,20 +200,20 @@
/* BTM_IsInquiryActive return values (Bit Mask)
* Note: These bit masks are associated with the inquiry modes (BTM_*_INQUIRY) */
#define BTM_INQUIRY_INACTIVE 0x0 /* no inquiry in progress */
-#define BTM_GENERAL_INQUIRY_ACTIVE 0x1 /* a general inquiry is in progress */
-#define BTM_LIMITED_INQUIRY_ACTIVE 0x2 /* a limited inquiry is in progress */
+#define BTM_GENERAL_INQUIRY_ACTIVE BTM_GENERAL_INQUIRY /* a general inquiry is in progress */
+#define BTM_LIMITED_INQUIRY_ACTIVE BTM_LIMITED_INQUIRY /* a limited inquiry is in progress */
#define BTM_PERIODIC_INQUIRY_ACTIVE 0x8 /* a periodic inquiry is active */
#define BTM_SSP_INQUIRY_ACTIVE 0x4 /* SSP is active, so inquiry is disallowed (work around for FW bug) */
-#define BTM_LE_GENERAL_INQUIRY_ACTIVE 0x10 /* a general inquiry is in progress */
-#define BTM_LE_LIMITED_INQUIRY_ACTIVE 0x20 /* a limited inquiry is in progress */
-#define BTM_LE_SELECT_CONN_ACTIVE 0x40 /* selection connection is in progress */
-#define BTM_LE_OBSERVE_ACTIVE 0x80 /* selection connection is in progress */
+#define BTM_LE_GENERAL_INQUIRY_ACTIVE BTM_BLE_GENERAL_INQUIRY /* a general inquiry is in progress */
+#define BTM_LE_LIMITED_INQUIRY_ACTIVE BTM_BLE_LIMITED_INQUIRY /* a limited inquiry is in progress */
+#define BTM_LE_SELECT_CONN_ACTIVE 0x40 /* selection connection is in progress */
+#define BTM_LE_OBSERVE_ACTIVE 0x80 /* selection connection is in progress */
/* inquiry activity mask */
-#define BTM_BR_INQ_ACTIVE_MASK (BTM_GENERAL_INQUIRY_ACTIVE|BTM_LIMITED_INQUIRY_ACTIVE|BTM_PERIODIC_INQUIRY_ACTIVE) /* BR/EDR inquiry activity mask */
-#define BTM_LE_SCAN_ACTIVE_MASK 0xF0 /* LE scan activity mask */
-#define BTM_LE_INQ_ACTIVE_MASK (BTM_LE_GENERAL_INQUIRY_ACTIVE|BTM_LE_LIMITED_INQUIRY_ACTIVE) /* LE inquiry activity mask*/
-#define BTM_INQUIRY_ACTIVE_MASK (BTM_BR_INQ_ACTIVE_MASK | BTM_LE_INQ_ACTIVE_MASK) /* inquiry activity mask */
+#define BTM_BR_INQ_ACTIVE_MASK (BTM_GENERAL_INQUIRY_ACTIVE|BTM_LIMITED_INQUIRY_ACTIVE|BTM_PERIODIC_INQUIRY_ACTIVE) /* BR/EDR inquiry activity mask */
+#define BTM_BLE_SCAN_ACTIVE_MASK 0xF0 /* LE scan activity mask */
+#define BTM_BLE_INQ_ACTIVE_MASK (BTM_LE_GENERAL_INQUIRY_ACTIVE|BTM_LE_LIMITED_INQUIRY_ACTIVE) /* LE inquiry activity mask*/
+#define BTM_INQUIRY_ACTIVE_MASK (BTM_BR_INQ_ACTIVE_MASK | BTM_BLE_INQ_ACTIVE_MASK) /* inquiry activity mask */
/* Define scan types */
#define BTM_SCAN_TYPE_STANDARD 0
@@ -659,6 +659,7 @@
typedef struct
{
UINT16 status;
+ BD_ADDR bd_addr;
UINT16 length;
BD_NAME remote_bd_name;
} tBTM_REMOTE_DEV_NAME;
@@ -837,6 +838,10 @@
DEV_CLASS_PTR p_dc; /* The device class */
BD_NAME_PTR p_bdn; /* The device name */
UINT8 *p_features; /* pointer to the remote device's features page[0] (supported features page) */
+#if BLE_INCLUDED == TRUE
+ UINT16 handle; /* connection handle */
+ tBT_TRANSPORT transport; /* link is LE or not */
+#endif
} tBTM_BL_CONN_DATA;
/* the data type associated with BTM_BL_DISCN_EVT */
@@ -844,6 +849,10 @@
{
tBTM_BL_EVENT event; /* The event reported. */
BD_ADDR_PTR p_bda; /* The address of the disconnected device */
+#if BLE_INCLUDED == TRUE
+ UINT16 handle; /* disconnected connection handle */
+ tBT_TRANSPORT transport; /* link is LE link or not */
+#endif
} tBTM_BL_DISCN_DATA;
/* Busy-Level shall have the inquiry_paging mask set when
@@ -893,10 +902,16 @@
** changes. First param is BD address, second is if added or removed.
** Registered through BTM_AclRegisterForChanges call.
*/
+#if BLE_INCLUDED == TRUE
+typedef void (tBTM_ACL_DB_CHANGE_CB) (BD_ADDR p_bda, DEV_CLASS p_dc,
+ BD_NAME p_bdn, UINT8 *features,
+ BOOLEAN is_new, UINT16 handle,
+ tBT_TRANSPORT transport);
+#else
typedef void (tBTM_ACL_DB_CHANGE_CB) (BD_ADDR p_bda, DEV_CLASS p_dc,
BD_NAME p_bdn, UINT8 *features,
BOOLEAN is_new);
-
+#endif
/*****************************************************************************
** SCO CHANNEL MANAGEMENT
*****************************************************************************/
@@ -1565,7 +1580,8 @@
** optional data passed in by BTM_SetEncryption
** tBTM_STATUS - result of the operation
*/
-typedef void (tBTM_SEC_CBACK) (BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result);
+typedef void (tBTM_SEC_CBACK) (BD_ADDR bd_addr, tBT_TRANSPORT trasnport,
+ void *p_ref_data, tBTM_STATUS result);
/* Bond Cancel complete. Parameters are
** Result of the cancel operation
@@ -1897,73 +1913,6 @@
#define BTM_VSC_NFC_SUPPORTED(x) ((x)[BTM_FEATURE_NFC_OFF] & BTM_FEATURE_NFC_MASK)
-/************************
-** Dual-Stack support
-*************************/
-/* BTM_SYNC_FAIL_EVT reason codes */
-#define BTM_SYNC_SUCCESS 0
-#define BTM_SYNC_FAIL_BTE_SWITCH_REJECTED 1
-#define BTM_SYNC_FAIL_TRANS_PAUSE 2
-#define BTM_SYNC_FAIL_CORE_SYNC 3
-#define BTM_SYNC_FAIL_BTA_SYNC 4
-#define BTM_SYNC_FAIL_TRANS_RESUME 5
-#define BTM_SYNC_FAIL_RESYNC 6
-#define BTM_SYNC_FAIL_ERROR 7
-#define BTM_SYNC_FAIL_UIPC_OPEN 8
-typedef UINT8 tBTM_SYNC_STATUS;
-
-/* Direction of sync (used by BTM_SyncStack) */
-#define BTM_SW_BB_TO_MM 0
-#define BTM_SW_TO_BB 1 /* Switch back to baseband stack (from either MM or BTC host) */
-#define BTM_SW_RESYNC 2
-#define BTM_SW_BB_TO_BTC 3 /* Switch from baseband stack to Bluetooth Controller Host stack */
-#define BTM_SW_MM_TO_BB 4
-#define BTM_SW_BTC_TO_BB 5
-typedef UINT8 tBTM_SW_DIR;
-
-/* Stack synchronization events (returned by tBTM_SYNC_STACK_CBACK callback) */
-#define BTM_SYNC_CPLT_EVT 0
-#define BTM_SYNC_BTA_EVT 1
-#define BTM_RESYNC_CPLT_EVT 2
-#define BTM_UIPC_OPENED_EVT 3
-#define BTM_UIPC_CLOSED_EVT 4
-typedef UINT8 tBTM_SYNC_STACK_EVT;
-
-/* Synchronization info from BTA/application that will be sent when calling BTE sync request functions */
-typedef struct
-{
- tBTM_SW_DIR dir;
- UINT16 lcid[BTM_SYNC_INFO_NUM_STR];
- UINT8 avdt_handle[BTM_SYNC_INFO_NUM_STR];
-} tBTM_SYNC_INFO;
-
-/* Stack synchonization callback function
-** Parameters are
-** event: stack synchronization event
-** status: BTM_SUCCESS if event was successful
-*/
-typedef void (*tBTM_SYNC_STACK_CBACK)(tBTM_SYNC_STACK_EVT event, tBTM_SYNC_STATUS status);
-
-
-/* Sync complete callback function. Called by bte layers after synchronization is complete
-** so that BTM_SYNC can procede with the next step for switching stack to MM
-**
-** Parameters are
-** status: BTM_SUCCESS if synchronization was successful
-*/
-typedef void (*tBTM_SYNC_CPLT_CBACK)(tBTM_STATUS status);
-
-
-
-/* IPC event callback function. Called by BTM when an IPC event is received.
-** These events are currently sent to DM through the callback function.
-**
-** Parameters are
-** status: BTM_SUCCESS if synchronization was successful
-** p_data: Actual message in the IPC
-*/
-typedef void (tBTM_IPC_EVT_CBACK)(tBTM_STATUS status, BT_HDR *p_data);
-
/* MIP evnets, callbacks */
enum
{
@@ -2659,7 +2608,8 @@
**
*******************************************************************************/
BTM_API extern tBTM_STATUS BTM_ReadRemoteDeviceName (BD_ADDR remote_bda,
- tBTM_CMPL_CB *p_cb);
+ tBTM_CMPL_CB *p_cb,
+ tBT_TRANSPORT transport);
/*******************************************************************************
@@ -3187,7 +3137,7 @@
** Returns TRUE if connection is up, else FALSE.
**
*******************************************************************************/
- BTM_API extern BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda);
+ BTM_API extern BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda, tBT_TRANSPORT transport);
/*******************************************************************************
@@ -3273,7 +3223,8 @@
** BTM_BUSY if command is already in progress
**
*******************************************************************************/
- BTM_API extern tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb);
+ BTM_API extern tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda,
+ tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb);
/*******************************************************************************
**
@@ -3640,7 +3591,8 @@
** Returns TRUE if registered OK, else FALSE
**
*******************************************************************************/
- BTM_API extern BOOLEAN BTM_SecRegisterLinkKeyNotificationCallback (tBTM_LINK_KEY_CALLBACK *p_callback);
+ BTM_API extern BOOLEAN BTM_SecRegisterLinkKeyNotificationCallback (
+ tBTM_LINK_KEY_CALLBACK *p_callback);
/*******************************************************************************
@@ -3653,7 +3605,8 @@
** Returns TRUE if registered OK, else FALSE
**
*******************************************************************************/
- BTM_API extern BOOLEAN BTM_SecAddRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback);
+ BTM_API extern BOOLEAN BTM_SecAddRmtNameNotifyCallback (
+ tBTM_RMT_NAME_CALLBACK *p_callback);
/*******************************************************************************
@@ -3666,7 +3619,8 @@
** Returns TRUE if OK, else FALSE
**
*******************************************************************************/
- BTM_API extern BOOLEAN BTM_SecDeleteRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback);
+ BTM_API extern BOOLEAN BTM_SecDeleteRmtNameNotifyCallback (
+ tBTM_RMT_NAME_CALLBACK *p_callback);
/*******************************************************************************
@@ -3709,6 +3663,22 @@
/*******************************************************************************
**
+** Function BTM_GetSecurityFlagsByTransport
+**
+** Description Get security flags for the device on a particular transport
+**
+** Parameters bd_addr: BD address of remote device
+** p_sec_flags : Out parameter to be filled with security flags for the connection
+** transport : Physical transport of the connection (BR/EDR or LE)
+**
+** Returns BOOLEAN TRUE or FALSE is device found
+**
+*******************************************************************************/
+ BTM_API extern BOOLEAN BTM_GetSecurityFlagsByTransport (BD_ADDR bd_addr,
+ UINT8 * p_sec_flags, tBT_TRANSPORT transport);
+
+/*******************************************************************************
+**
** Function BTM_ReadTrustedMask
**
** Description Get trusted mask for the device
@@ -3789,9 +3759,10 @@
** Returns TRUE if registered OK, else FALSE
**
*******************************************************************************/
- BTM_API extern BOOLEAN BTM_SetUCDSecurityLevel (BOOLEAN is_originator, char *p_name, UINT8 service_id,
- UINT16 sec_level, UINT16 psm, UINT32 mx_proto_id,
- UINT32 mx_chan_id);
+ BTM_API extern BOOLEAN BTM_SetUCDSecurityLevel (BOOLEAN is_originator, char *p_name,
+ UINT8 service_id, UINT16 sec_level,
+ UINT16 psm, UINT32 mx_proto_id,
+ UINT32 mx_chan_id);
/*******************************************************************************
**
@@ -3951,10 +3922,37 @@
**
** Description This function is called to perform bonding with peer device.
**
+** Parameters: bd_addr - Address of the device to bond
+** pin_len - length in bytes of the PIN Code
+** p_pin - pointer to array with the PIN Code
+** trusted_mask - bitwise OR of trusted services (array of UINT32)
+
** Returns BTM_CMD_STARTED if successfully initiated, otherwise error
**
*******************************************************************************/
- BTM_API extern tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[]);
+ BTM_API extern tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr,
+ UINT8 pin_len, UINT8 *p_pin,
+ UINT32 trusted_mask[]);
+
+/*******************************************************************************
+**
+** Function BTM_SecBondByTransport
+**
+** Description This function is called to perform bonding by designated transport
+**
+** Parameters: bd_addr - Address of the device to bond
+** pin_len - length in bytes of the PIN Code
+** p_pin - pointer to array with the PIN Code
+** trusted_mask - bitwise OR of trusted services (array of UINT32)
+** transport : Physical transport to use for bonding (BR/EDR or LE)
+**
+** Returns BTM_CMD_STARTED if successfully initiated, otherwise error
+**
+*******************************************************************************/
+ BTM_API extern tBTM_STATUS BTM_SecBondByTransport (BD_ADDR bd_addr,
+ tBT_TRANSPORT transport,
+ UINT8 pin_len, UINT8 *p_pin,
+ UINT32 trusted_mask[]);
/*******************************************************************************
**
@@ -3993,8 +3991,8 @@
** BTM_MODE_UNSUPPORTED - if security manager not linked in.
**
*******************************************************************************/
- BTM_API extern tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBTM_SEC_CBACK *p_callback,
- void *p_ref_data);
+ BTM_API extern tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBT_TRANSPORT transport,
+ tBTM_SEC_CBACK *p_callback, void *p_ref_data);
/*******************************************************************************
**
@@ -4079,7 +4077,8 @@
** r - simple pairing Randomizer C.
**
*******************************************************************************/
- BTM_API extern void BTM_RemoteOobDataReply(tBTM_STATUS res, BD_ADDR bd_addr, BT_OCTET16 c, BT_OCTET16 r);
+ BTM_API extern void BTM_RemoteOobDataReply(tBTM_STATUS res, BD_ADDR bd_addr,
+ BT_OCTET16 c, BT_OCTET16 r);
/*******************************************************************************
**
@@ -4232,7 +4231,7 @@
** Returns the handle of the connection, or 0xFFFF if none.
**
*******************************************************************************/
- BTM_API extern UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda);
+ BTM_API extern UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda, tBT_TRANSPORT transport);
/*******************************************************************************
@@ -4419,171 +4418,6 @@
BTM_API extern UINT8 BTM_GetEirUuidList( UINT8 *p_eir, UINT8 uuid_size, UINT8 *p_num_uuid,
UINT8 *p_uuid_list, UINT8 max_num_uuid);
-/*******************************************************************************
-**
-** Function BTM_SyncStack
-**
-** Description For Dual-Stack support. Called to initiate switching to/from
-** main stack (running on phone baseband) to mm stack (light
-** stack running on multi-media chip)
-**
-** Parameters sync_dir: BTM_SW_BB_TO_MM: switch from BB to MM stack
-** BTM_SW_MM_TO_BB: switch from MM to BB stack
-** BTM_SW_RESYNC: resync MM and BB stacks
-**
-** p_sync_cback: callback function for event notification
-** Returns
-**
-*******************************************************************************/
- BTM_API extern tBTM_STATUS BTM_SyncStack(tBTM_SW_DIR sync_dir, tBTM_SYNC_STACK_CBACK p_sync_cback);
-
-/*******************************************************************************
-**
-** Function BTM_SyncBtaRsp
-**
-** Description For Dual-Stack support. Called to indicate that upper layers
-** (e.g. BTA or application) have completed synchronizing bta/app
-** specific layers for switching.
-**
-** Called in response to 'BTM_SYNC_BTA_EVT'
-**
-** Parameters status: BTM_SUCESS: bta/app successfully synchronized
-** otherwise: sync was unsuccessfule. Abort switch.
-**
-** p_btm_sync_info: information from bta/app that will be needed
-** by BTE (avdt and l2cap) for switching.
-**
-** Returns void
-**
-*******************************************************************************/
- BTM_API extern void BTM_SyncBtaRsp(tBTM_STATUS status, tBTM_SYNC_INFO *p_btm_sync_info);
-
-/*******************************************************************************
-**
-** Function BTM_OpenUIPC
-**
-** Description For Dual-Stack support. Called to open UIPC between
-** main stack (running on phone baseband) to embedded light stack
-** (running on Multimedia or Bluetooth Controller chip)
-**
-** Parameters sync_dir: BTM_SW_BB_TO_MM: switch from BB to MM stack
-** BTM_SW_BB_TO_BTC:switch from BB to BTC stack
-**
-** p_sync_callback: callback function for event notification
-** Returns
-**
-*******************************************************************************/
- BTM_API extern tBTM_STATUS BTM_OpenUIPC(tBTM_SW_DIR sync_dir, tBTM_SYNC_STACK_CBACK p_sync_callback);
-
-/*******************************************************************************
-**
-** Function BTM_CloseUIPC
-**
-** Description For Dual-Stack support. Called to close UIPC between
-** main stack (running on phone baseband) to embedded light stack
-** (running on Multimedia or Bluetooth Controller chip)
-**
-** Parameters
-** p_sync_callback: callback function for event notification
-** Returns
-**
-*******************************************************************************/
- BTM_API extern tBTM_STATUS BTM_CloseUIPC(tBTM_SYNC_STACK_CBACK p_sync_callback);
-
-/*******************************************************************************
-**
-** Function BTM_IpcSend
-**
-** Description For Dual-Stack support. Called to send ipc messages from
-** full stack to lite stack and vice-versa. This API is
-** typically called by bta layers e.g. bta_av.
-**
-**
-** Parameters len: Length of the buffer in the ipc message
-**
-** buffer: Pointer to the buffer to be passed in the IPC message
-**
-** Returns void
-**
-*******************************************************************************/
- BTM_API extern void BTM_IpcSend(UINT16 len, UINT8* buffer);
-
-/*******************************************************************************
-**
-** Function BTM_IpcSendBuf
-**
-** Description For Dual-Stack support. Called to send ipc messages from
-** full stack to lite stack and vice-versa. This API is
-** typically called by bta layers e.g. bta_av_sync.
-**
-**
-** Parameters p_buf: Pointer to the buffer to be passed in the IPC message
-**
-** Returns void
-**
-*******************************************************************************/
- BTM_API extern void BTM_IpcSendBuf(BT_HDR* p_buf);
-
-/*******************************************************************************
-**
-** Function BTM_RegIpcEvtHandler
-**
-** Description registers the DM provided handler for IPC events
-**
-**
-** Returns void
-**
-*******************************************************************************/
- BTM_API extern void BTM_RegIpcEvtHandler(tBTM_IPC_EVT_CBACK *p_cback);
-
-/*******************************************************************************
-**
-** Function BTM_RegRTIpcEvtHandler
-**
-** Description registers the RT(Audio Routing) provided handler for IPC events
-**
-**
-** Returns void
-**
-*******************************************************************************/
- BTM_API extern void BTM_RegRTIpcEvtHandler(tBTM_IPC_EVT_CBACK *p_cback);
-
-/*****************************************************************************
-** N2BT
-*****************************************************************************/
-
-/* Data callback for N2BT */
- typedef void (tBTM_N2BT_DATA_CB) (BD_ADDR bd_addr, UINT16 handle, UINT8 *p_data, UINT16 datalen);
-
-/*******************************************************************************
-**
-** Function BTM_N2BtAcquire
-**
-** Description Put controller into acquisition mode
-**
-** Returns void
-**
-*******************************************************************************/
- BTM_API extern void BTM_N2BtAcquire(BD_ADDR bd_addr, UINT16 timeout,
- UINT8 freq, UINT8 src_addrlen, UINT8 sensor_flags,
- UINT8 sensor_type, UINT8 sensor_clk_accuracy,
- UINT16 add_rx_window, UINT16 init_crc,
- UINT32 ac_low, UINT32 ac_high, UINT16 pkt_hdr,
- UINT16 list_dur, UINT16 list_int,
- UINT8 oor_missed_pkts, tBTM_VSC_CMPL_CB *p_cb,
- tBTM_N2BT_DATA_CB *p_data_cback);
-
-/*******************************************************************************
-**
-** Function BTM_N2BtDisconnect
-**
-** Description Disconnects all N2BT devices
-**
-** Returns void
-**
-*******************************************************************************/
- BTM_API extern void BTM_N2BtDisconnect(void);
-
/*****************************************************************************
** SCO OVER HCI
*****************************************************************************/
diff --git a/stack/include/btm_ble_api.h b/stack/include/btm_ble_api.h
index 584ce9a..0bfaea9 100644
--- a/stack/include/btm_ble_api.h
+++ b/stack/include/btm_ble_api.h
@@ -30,12 +30,17 @@
#define CHNL_MAP_LEN 5
typedef UINT8 tBTM_BLE_CHNL_MAP[CHNL_MAP_LEN];
-#define BTM_BLE_CONNECT_EVT 0x00
-#define BTM_BLE_CONNECT_DIR_EVT 0x01
-#define BTM_BLE_DISCOVER_EVT 0x02
-#define BTM_BLE_NON_CONNECT_EVT 0x03
+/* 0x00-0x04 only used for set advertising parameter command */
+#define BTM_BLE_CONNECT_EVT 0x00 /* 0x00-0x04 only used for set advertising
+ parameter command */
+#define BTM_BLE_CONNECT_DIR_EVT 0x01 /* Connectable directed advertising */
+#define BTM_BLE_DISCOVER_EVT 0x02 /* Scannable undirected advertising */
+#define BTM_BLE_NON_CONNECT_EVT 0x03 /* Non connectable undirected advertising */
+#define BTM_BLE_CONNECT_LO_DUTY_DIR_EVT 0x04 /* Connectable low duty
+ cycle directed advertising */
+ /* 0x00 - 0x05 can be received on adv event type */
#define BTM_BLE_SCAN_RSP_EVT 0x04
-#define BTM_BLE_SCAN_REQ_EVT 0x06
+#define BTM_BLE_SCAN_REQ_EVT 0x05
#define BTM_BLE_UNKNOWN_EVT 0xff
#define BTM_BLE_UNKNOWN_EVT 0xff
@@ -191,27 +196,33 @@
#define BTM_BLE_LIMIT_DISC_FLAG (0x01 << 0)
#define BTM_BLE_GEN_DISC_FLAG (0x01 << 1)
#define BTM_BLE_BREDR_NOT_SPT (0x01 << 2)
+/* 4.1 spec adv flag for simultaneous BR/EDR+LE connection support */
+#define BTM_BLE_DMT_CONTROLLER_SPT (0x01 << 3)
+#define BTM_BLE_DMT_HOST_SPT (0x01 << 4)
+
#define BTM_BLE_NON_LIMIT_DISC_FLAG (0x00 ) /* lowest bit unset */
#define BTM_BLE_ADV_FLAG_MASK (BTM_BLE_LIMIT_DISC_FLAG | BTM_BLE_BREDR_NOT_SPT | BTM_BLE_GEN_DISC_FLAG)
#define BTM_BLE_LIMIT_DISC_MASK (BTM_BLE_LIMIT_DISC_FLAG )
-#define BTM_BLE_AD_BIT_DEV_NAME (0x0001 << 0)
-#define BTM_BLE_AD_BIT_FLAGS (0x0001 << 1)
-#define BTM_BLE_AD_BIT_MANU (0x0001 << 2)
-#define BTM_BLE_AD_BIT_TX_PWR (0x0001 << 3)
-#define BTM_BLE_AD_BIT_INT_RANGE (0x0001 << 5)
-#define BTM_BLE_AD_BIT_SERVICE (0x0001 << 6)
-#define BTM_BLE_AD_BIT_SERVICE_SOL (0x0001 << 7)
-#define BTM_BLE_AD_BIT_SERVICE_DATA (0x0001 << 8)
-#define BTM_BLE_AD_BIT_SIGN_DATA (0x0001 << 9)
-#define BTM_BLE_AD_BIT_SERVICE_128SOL (0x0001 << 10)
-#define BTM_BLE_AD_BIT_APPEARANCE (0x0001 << 11)
-#define BTM_BLE_AD_BIT_PUBLIC_ADDR (0x0001 << 12)
-#define BTM_BLE_AD_BIT_RANDOM_ADDR (0x0001 << 13)
+#define BTM_BLE_AD_BIT_DEV_NAME (0x00000001 << 0)
+#define BTM_BLE_AD_BIT_FLAGS (0x00000001 << 1)
+#define BTM_BLE_AD_BIT_MANU (0x00000001 << 2)
+#define BTM_BLE_AD_BIT_TX_PWR (0x00000001 << 3)
+#define BTM_BLE_AD_BIT_INT_RANGE (0x00000001 << 5)
+#define BTM_BLE_AD_BIT_SERVICE (0x00000001 << 6)
+#define BTM_BLE_AD_BIT_SERVICE_SOL (0x00000001 << 7)
+#define BTM_BLE_AD_BIT_SERVICE_DATA (0x00000001 << 8)
+#define BTM_BLE_AD_BIT_SIGN_DATA (0x00000001 << 9)
+#define BTM_BLE_AD_BIT_SERVICE_128SOL (0x00000001 << 10)
+#define BTM_BLE_AD_BIT_APPEARANCE (0x00000001 << 11)
+#define BTM_BLE_AD_BIT_PUBLIC_ADDR (0x00000001 << 12)
+#define BTM_BLE_AD_BIT_RANDOM_ADDR (0x00000001 << 13)
+#define BTM_BLE_AD_BIT_SERVICE_32 (0x00000001 << 4)
+#define BTM_BLE_AD_BIT_SERVICE_32SOL (0x00000001 << 14)
-#define BTM_BLE_AD_BIT_PROPRIETARY (0x0001 << 15)
+#define BTM_BLE_AD_BIT_PROPRIETARY (0x00000001 << 15)
-typedef UINT16 tBTM_BLE_AD_MASK;
+typedef UINT32 tBTM_BLE_AD_MASK;
#define BTM_BLE_AD_TYPE_FLAG HCI_EIR_FLAGS_TYPE /* 0x01 */
#define BTM_BLE_AD_TYPE_16SRV_PART HCI_EIR_MORE_16BITS_UUID_TYPE /* 0x02 */
@@ -233,6 +244,11 @@
#define BTM_BLE_AD_TYPE_PUBLIC_TARGET 0x17
#define BTM_BLE_AD_TYPE_RANDOM_TARGET 0x18
#define BTM_BLE_AD_TYPE_APPEARANCE 0x19
+#define BTM_BLE_AD_TYPE_ADV_INT 0x1a
+#define BTM_BLE_AD_TYPE_32SOL_SRV_UUID 0x1b
+#define BTM_BLE_AD_TYPE_32SERVICE_DATA 0x1c
+#define BTM_BLE_AD_TYPE_128SERVICE_DATA 0x1d
+
#define BTM_BLE_AD_TYPE_MANU HCI_EIR_MANUFACTURER_SPECIFIC_TYPE /* 0xff */
typedef UINT8 tBTM_BLE_AD_TYPE;
@@ -252,12 +268,30 @@
UINT16 *p_uuid;
}tBTM_BLE_SERVICE;
+/* Service tag supported in the device */
+typedef struct
+{
+ UINT8 num_service;
+ BOOLEAN list_cmpl;
+ UINT32 *p_uuid;
+}tBTM_BLE_32SERVICE;
+
+
typedef struct
{
UINT8 len;
UINT8 *p_val;
}tBTM_BLE_MANU;
+
+typedef struct
+{
+ tBT_UUID service_uuid;
+ UINT8 len;
+ UINT8 *p_val;
+}tBTM_BLE_SERVICE_DATA;
+
+
typedef struct
{
UINT8 adv_type;
@@ -273,9 +307,12 @@
typedef struct
{
- tBTM_BLE_MANU manu; /* manufactuer data */
+ tBTM_BLE_SERVICE_DATA *p_service_data;
+ tBTM_BLE_MANU manu; /* manufactuer data */
tBTM_BLE_INT_RANGE int_range; /* slave prefered conn interval range */
tBTM_BLE_SERVICE services; /* services */
+ tBTM_BLE_32SERVICE service_32b; /* 32 bits Service UUID */
+ tBTM_BLE_32SERVICE sol_service_32b; /* List of 32 bit Service Solicitation UUIDs */
UINT16 appearance;
UINT8 flag;
tBTM_BLE_PROPRIETARY *p_proprietary;
@@ -434,19 +471,6 @@
/*******************************************************************************
**
-** Function BTM_BleReset
-**
-** Description This function is called to reset ULP controller.
-**
-** Parameters None.
-**
-** Returns void
-**
-*******************************************************************************/
-BTM_API extern void BTM_BleReset(void);
-
-/*******************************************************************************
-**
** Function BTM_BleObserve
**
** Description This procedure keep the device listening for advertising
@@ -866,17 +890,6 @@
/*******************************************************************************
**
-** Function BTM_IsBleLink
-**
-** Description This function is to check the link type is BLE or BR/EDR.
-**
-** Returns TRUE if BLE link; FALSE if BR/EDR.
-**
-*******************************************************************************/
-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.
@@ -886,6 +899,20 @@
*******************************************************************************/
BTM_API extern BOOLEAN BTM_UseLeLink (BD_ADDR bd_addr);
+/*******************************************************************************
+**
+** Function BTM_BleStackEnable
+**
+** Description Enable/Disable BLE functionality on stack regarless controller
+** capability.
+**
+** Parameters: enable: TRUE to enable, FALSE to disable.
+**
+** Returns TRUE if added OK, else FALSE
+**
+*******************************************************************************/
+BTM_API extern tBTM_STATUS BTM_BleStackEnable (BOOLEAN enable);
+
#ifdef __cplusplus
}
#endif
diff --git a/stack/include/btu.h b/stack/include/btu.h
index 4f0e162..805fea7 100644
--- a/stack/include/btu.h
+++ b/stack/include/btu.h
@@ -153,10 +153,15 @@
#define BTU_TTYPE_ATT_WAIT_FOR_APP_RSP 104
#define BTU_TTYPE_ATT_WAIT_FOR_IND_ACK 105
-#define BTU_TTYPE_UCD_TO 106
+#define BTU_TTYPE_L2CAP_END_CONN_UPD 106
-/* BTU timer event for TBFC */
-#define BTU_TTYPE_TBFC_RESUME 107
+#define BTU_TTYPE_BLE_GAP_FAST_ADV 107
+#define BTU_TTYPE_BLE_OBSERVE 108
+
+
+#define BTU_TTYPE_UCD_TO 109
+
+
/* Define the BTU_TASK APPL events
*/
diff --git a/stack/include/gap_api.h b/stack/include/gap_api.h
index a17510f..645323d 100644
--- a/stack/include/gap_api.h
+++ b/stack/include/gap_api.h
@@ -225,6 +225,9 @@
typedef void (tGAP_BLE_DEV_NAME_CBACK)(BOOLEAN status, BD_ADDR addr, UINT16 length, char *p_name);
typedef void (tGAP_BLE_RECONN_ADDR_CBACK)(BOOLEAN status, BD_ADDR addr, BD_ADDR reconn_bda);
+#if BLE_PRIVACY_SPT == TRUE
+typedef void (tGAP_BLE_PRIVACY_CBACK)(BOOLEAN status, BD_ADDR addr, BOOLEAN privacy_enabled);
+#endif
/*****************************************************************************
** External Function Declarations
@@ -440,10 +443,16 @@
**
** Description This function is called to initiate bonding with peer device
**
+** Parameters: bd_addr - Address of the device to bond
+** pin_len - length in bytes of the PIN Code
+** p_pin - pointer to array with the PIN Code
+** trusted_mask - bitwise OR of trusted services (array of UINT32)
+**
** Returns tBTM_STATUS - BTM_CMD_STARTED of successfully initiated
**
*******************************************************************************/
-GAP_API extern UINT8 GAP_Bond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[]);
+GAP_API extern UINT8 GAP_Bond (BD_ADDR bd_addr, UINT8 pin_len,
+ UINT8 *p_pin, UINT32 trusted_mask[]);
/*******************************************************************************
**
diff --git a/stack/include/gatt_api.h b/stack/include/gatt_api.h
index f3df8b7..9da7d9c 100644
--- a/stack/include/gatt_api.h
+++ b/stack/include/gatt_api.h
@@ -25,44 +25,47 @@
** Constants
*****************************************************************************/
/* Success code and error codes */
-#define GATT_SUCCESS 0x0000
-#define GATT_INVALID_HANDLE 0x0001
-#define GATT_READ_NOT_PERMIT 0x0002
-#define GATT_WRITE_NOT_PERMIT 0x0003
-#define GATT_INVALID_PDU 0x0004
-#define GATT_INSUF_AUTHENTICATION 0x0005
-#define GATT_REQ_NOT_SUPPORTED 0x0006
-#define GATT_INVALID_OFFSET 0x0007
-#define GATT_INSUF_AUTHORIZATION 0x0008
-#define GATT_PREPARE_Q_FULL 0x0009
-#define GATT_NOT_FOUND 0x000a
-#define GATT_NOT_LONG 0x000b
-#define GATT_INSUF_KEY_SIZE 0x000c
-#define GATT_INVALID_ATTR_LEN 0x000d
-#define GATT_ERR_UNLIKELY 0x000e
-#define GATT_INSUF_ENCRYPTION 0x000f
-#define GATT_UNSUPPORT_GRP_TYPE 0x0010
-#define GATT_INSUF_RESOURCE 0x0011
+#define GATT_SUCCESS 0x00
+#define GATT_INVALID_HANDLE 0x01
+#define GATT_READ_NOT_PERMIT 0x02
+#define GATT_WRITE_NOT_PERMIT 0x03
+#define GATT_INVALID_PDU 0x04
+#define GATT_INSUF_AUTHENTICATION 0x05
+#define GATT_REQ_NOT_SUPPORTED 0x06
+#define GATT_INVALID_OFFSET 0x07
+#define GATT_INSUF_AUTHORIZATION 0x08
+#define GATT_PREPARE_Q_FULL 0x09
+#define GATT_NOT_FOUND 0x0a
+#define GATT_NOT_LONG 0x0b
+#define GATT_INSUF_KEY_SIZE 0x0c
+#define GATT_INVALID_ATTR_LEN 0x0d
+#define GATT_ERR_UNLIKELY 0x0e
+#define GATT_INSUF_ENCRYPTION 0x0f
+#define GATT_UNSUPPORT_GRP_TYPE 0x10
+#define GATT_INSUF_RESOURCE 0x11
-#define GATT_ILLEGAL_PARAMETER 0x0087
-#define GATT_NO_RESOURCES 0x0080
-#define GATT_INTERNAL_ERROR 0x0081
-#define GATT_WRONG_STATE 0x0082
-#define GATT_DB_FULL 0x0083
-#define GATT_BUSY 0x0084
-#define GATT_ERROR 0x0085
-#define GATT_CMD_STARTED 0x0086
-#define GATT_PENDING 0x0088
-#define GATT_AUTH_FAIL 0x0089
-#define GATT_MORE 0x008a
-#define GATT_INVALID_CFG 0x008b
-#define GATT_SERVICE_STARTED 0x008c
+#define GATT_ILLEGAL_PARAMETER 0x87
+#define GATT_NO_RESOURCES 0x80
+#define GATT_INTERNAL_ERROR 0x81
+#define GATT_WRONG_STATE 0x82
+#define GATT_DB_FULL 0x83
+#define GATT_BUSY 0x84
+#define GATT_ERROR 0x85
+#define GATT_CMD_STARTED 0x86
+#define GATT_PENDING 0x88
+#define GATT_AUTH_FAIL 0x89
+#define GATT_MORE 0x8a
+#define GATT_INVALID_CFG 0x8b
+#define GATT_SERVICE_STARTED 0x8c
#define GATT_ENCRYPED_MITM GATT_SUCCESS
-#define GATT_ENCRYPED_NO_MITM 0x008d
-#define GATT_NOT_ENCRYPTED 0x008e
+#define GATT_ENCRYPED_NO_MITM 0x8d
+#define GATT_NOT_ENCRYPTED 0x8e
-
+ /* 0xE0 ~ 0xFC reserved for future use */
+#define GATT_CCC_CFG_ERR 0xFD /* Client Characteristic Configuration Descriptor Improperly Configured */
+#define GATT_PRC_IN_PROGRESS 0xFE /* Procedure Already in progress */
+#define GATT_OUT_OF_RANGE 0xFF /* Attribute value out of range */
typedef UINT8 tGATT_STATUS;
@@ -325,12 +328,9 @@
} tGATTS_RSP;
/* Transports for the primary service */
-enum
-{
- GATT_TRANSPORT_LE,
- GATT_TRANSPORT_BR_EDR,
- GATT_TRANSPORT_LE_BR_EDR
-};
+#define GATT_TRANSPORT_LE BT_TRANSPORT_LE
+#define GATT_TRANSPORT_BR_EDR BT_TRANSPORT_BR_EDR
+#define GATT_TRANSPORT_LE_BR_EDR (BT_TRANSPORT_LE|BT_TRANSPORT_BR_EDR)
typedef UINT8 tGATT_TRANSPORT;
#define GATT_PREP_WRITE_CANCEL 0x00
@@ -548,26 +548,30 @@
typedef UINT8 tGATT_IF;
-#define GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP 0 /* start a idle timer for this duration when no application
- need to use the link */
+#define GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP 0 /* start a idle timer for this duration
+ when no application need to use the link */
#define GATT_LINK_NO_IDLE_TIMEOUT 0xFFFF
#define GATT_INVALID_ACL_HANDLE 0xFFFF
/* discover result callback function */
-typedef void (tGATT_DISC_RES_CB) (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_DISC_RES *p_data);
+typedef void (tGATT_DISC_RES_CB) (UINT16 conn_id, tGATT_DISC_TYPE disc_type,
+ tGATT_DISC_RES *p_data);
/* discover complete callback function */
typedef void (tGATT_DISC_CMPL_CB) (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_STATUS status);
/* Define a callback function for when read/write/disc/config operation is completed. */
-typedef void (tGATT_CMPL_CBACK) (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, tGATT_CL_COMPLETE *p_data);
+typedef void (tGATT_CMPL_CBACK) (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
+ tGATT_CL_COMPLETE *p_data);
/* Define a callback function when an initialized connection is established. */
-typedef void (tGATT_CONN_CBACK) (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason);
+typedef void (tGATT_CONN_CBACK) (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected,
+ tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport);
/* attribute request callback for ATT server */
-typedef void (tGATT_REQ_CBACK )(UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data);
+typedef void (tGATT_REQ_CBACK )(UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type,
+ tGATTS_DATA *p_data);
/* Define a callback function when encryption is established. */
typedef void (tGATT_ENC_CMPL_CB)(tGATT_IF gatt_if, BD_ADDR bda);
@@ -639,7 +643,8 @@
/* Attibute server handle ranges NV storage callback functions
*/
typedef void (tGATTS_NV_SAVE_CBACK)(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
-typedef BOOLEAN (tGATTS_NV_SRV_CHG_CBACK)(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp);
+typedef BOOLEAN (tGATTS_NV_SRV_CHG_CBACK)(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req,
+ tGATTS_SRV_CHG_RSP *p_rsp);
typedef struct
{
@@ -801,7 +806,8 @@
** Returns TRUE if operation succeed, FALSE if handle block was not found.
**
*******************************************************************************/
- GATT_API extern BOOLEAN GATTS_DeleteService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, UINT16 svc_inst);
+ GATT_API extern BOOLEAN GATTS_DeleteService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
+ UINT16 svc_inst);
/*******************************************************************************
**
@@ -998,11 +1004,13 @@
**
** Parameter bd_addr: target device bd address.
** idle_tout: timeout value in seconds.
+** transport: trasnport option.
**
** Returns void
**
*******************************************************************************/
- GATT_API extern void GATT_SetIdleTimeout (BD_ADDR bd_addr, UINT16 idle_tout);
+ GATT_API extern void GATT_SetIdleTimeout (BD_ADDR bd_addr, UINT16 idle_tout,
+ tGATT_TRANSPORT transport);
/*******************************************************************************
@@ -1058,11 +1066,13 @@
** Parameters gatt_if: applicaiton interface
** bd_addr: peer device address.
** is_direct: is a direct conenection or a background auto connection
+** transport : Physical transport for GATT connection (BR/EDR or LE)
**
** Returns TRUE if connection started; FALSE if connection start failure.
**
*******************************************************************************/
- GATT_API extern BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct);
+ GATT_API extern BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr,
+ BOOLEAN is_direct, tBT_TRANSPORT transport);
/*******************************************************************************
@@ -1080,7 +1090,8 @@
** Returns TRUE if connection started; FALSE if connection start failure.
**
*******************************************************************************/
- GATT_API extern BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct);
+ GATT_API extern BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr,
+ BOOLEAN is_direct);
/*******************************************************************************
**
@@ -1108,11 +1119,13 @@
** Parameters conn_id: connection id (input)
** p_gatt_if: applicaiton interface (output)
** bd_addr: peer device address. (output)
+** transport : physical transport of the GATT connection (BR/EDR or LE)
**
** Returns TRUE the ligical link information is found for conn_id
**
*******************************************************************************/
- GATT_API extern BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, BD_ADDR bd_addr);
+ GATT_API extern BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if,
+ BD_ADDR bd_addr, tBT_TRANSPORT *p_transport);
/*******************************************************************************
@@ -1125,11 +1138,13 @@
** Parameters gatt_if: applicaiton interface (input)
** bd_addr: peer device address. (input)
** p_conn_id: connection id (output)
+** transport : physical transport of the GATT connection (BR/EDR or LE)
**
** Returns TRUE the ligical link is connected
**
*******************************************************************************/
- GATT_API extern BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, UINT16 *p_conn_id);
+ GATT_API extern BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr,
+ UINT16 *p_conn_id, tBT_TRANSPORT transport);
/*******************************************************************************
diff --git a/stack/include/hcidefs.h b/stack/include/hcidefs.h
index ad31d52..14ae893 100644
--- a/stack/include/hcidefs.h
+++ b/stack/include/hcidefs.h
@@ -231,11 +231,11 @@
#define HCI_SET_MWS_PATTERN_CONFIGURATION (0x0073 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
/* ConnectionLess Broadcast */
-#define HCI_SET_RESERVED_LT_ADDR (0x0077 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
-#define HCI_DELETE_RESERVED_LT_ADDR (0x0078 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
-#define HCI_WRITE_CLB_DATA (0x0079 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
-#define HCI_WRITE_SYNC_TRAIN_PARAM (0x007A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
-#define HCI_READ_SYNC_TRAIN_PARAM (0x007B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_RESERVED_LT_ADDR (0x0074 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_DELETE_RESERVED_LT_ADDR (0x0075 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_CLB_DATA (0x0076 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_SYNC_TRAIN_PARAM (0x0077 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_SYNC_TRAIN_PARAM (0x0078 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
#define HCI_CONT_BASEBAND_CMDS_FIRST HCI_SET_EVENT_MASK
#define HCI_CONT_BASEBAND_CMDS_LAST HCI_READ_SYNC_TRAIN_PARAM
@@ -323,13 +323,17 @@
#define HCI_BLE_LTK_REQ_REPLY (0x001A | HCI_GRP_BLE_CMDS)
#define HCI_BLE_LTK_REQ_NEG_REPLY (0x001B | HCI_GRP_BLE_CMDS)
#define HCI_BLE_READ_SUPPORTED_STATES (0x001C | HCI_GRP_BLE_CMDS)
+ /*0x001D, 0x001E and 0x001F are reserved*/
+
+#define HCI_BLE_RC_PARAM_REQ_REPLY (0x0020 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_RC_PARAM_REQ_NEG_REPLY (0x0021 | HCI_GRP_BLE_CMDS)
+
+
/* BLE TEST COMMANDS */
#define HCI_BLE_RECEIVER_TEST (0x001D | HCI_GRP_BLE_CMDS)
#define HCI_BLE_TRANSMITTER_TEST (0x001E | HCI_GRP_BLE_CMDS)
#define HCI_BLE_TEST_END (0x001F | HCI_GRP_BLE_CMDS)
-#define HCI_BLE_RESET (0x0020 | HCI_GRP_BLE_CMDS)
-
/* LE supported states definition */
#define HCI_LE_ADV_STATE 0x00000001
#define HCI_LE_SCAN_STATE 0x00000002
@@ -344,6 +348,214 @@
#define HCI_LE_SCAN_SL_STATE 0x00000400
#define HCI_LE_INIT_MA_STATE 0x00000800
+/* LE Supported States */
+/* Non Connectable Adv state is supported. 0x0000000000000001 */
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK 0x01
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF 0
+#define HCI_LE_STATES_NON_CONN_ADV_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK)
+
+/*Scanneable Connectable Adv state is supported. 0x0000000000000002 */
+#define HCI_SUPP_LE_STATES_SCAN_ADV_MASK 0x02
+#define HCI_SUPP_LE_STATESSCAN_ADV_OFF 0
+#define HCI_LE_STATES_SCAN_ADV_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATESSCAN_ADV_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_MASK)
+
+/* Connectable Adv state is supported. 0x0000000000000004 */
+#define HCI_SUPP_LE_STATES_CONN_ADV_MASK 0x04
+#define HCI_SUPP_LE_STATES_CONN_ADV_OFF 0
+#define HCI_LE_STATES_CONN_ADV_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_MASK)
+
+/* Hi duty Cycle Directed Adv state is supported. 0x0000000000000008 */
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK 0x08
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF 0
+#define HCI_LE_STATES_HI_DUTY_DIR_ADV_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK)
+
+/* Passive Scan state is supported. 0x0000000000000010 */
+#define HCI_SUPP_LE_STATES_PASS_SCAN_MASK 0x10
+#define HCI_SUPP_LE_STATES_PASS_SCAN_OFF 0
+#define HCI_LE_STATES_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_MASK)
+
+/* Active Scan state is supported. 0x0000000000000020 */
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASK 0x20
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_OFF 0
+#define HCI_LE_STATES_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASK)
+
+/* Initiating state is supported. 0x0000000000000040 (or connection state in master role is also supported) */
+#define HCI_SUPP_LE_STATES_INIT_MASK 0x40
+#define HCI_SUPP_LE_STATES_INIT_OFF 0
+#define HCI_LE_STATES_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_INIT_OFF] & HCI_SUPP_LE_STATES_INIT_MASK)
+
+/*connection state in slave role is also supported. 0x0000000000000080 */
+#define HCI_SUPP_LE_STATES_SLAVE_MASK 0x80
+#define HCI_SUPP_LE_STATES_SLAVE_OFF 0
+#define HCI_LE_STATES_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SLAVE_OFF] & HCI_SUPP_LE_STATES_SLAVE_MASK)
+
+/* Non Connectable Adv state and Passive Scanning State combination is supported. 0x0000000000000100 */
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK 0x01
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF 1
+#define HCI_LE_STATES_NON_CONN_ADV_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK)
+
+/*Scannable Adv state and Passive Scanning State combination is supported. 0x0000000000000200 */
+#define HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK 0x02
+#define HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF 1
+#define HCI_LE_STATES_SCAN_ADV_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK)
+
+/*Connectable Adv state and Passive Scanning State combination is supported. 0x0000000000000400 */
+#define HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK 0x04
+#define HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF 1
+#define HCI_LE_STATES_CONN_ADV_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK)
+
+/*High Duty Cycl Directed ADv and Passive Scanning State combination is supported. 0x0000000000000800 */
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK 0x08
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF 1
+#define HCI_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF)
+
+/*Non Connectable Adv state and Passive Scanning State combination is supported. 0x0000000000001000 */
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK 0x10
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF 1
+#define HCI_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK)
+
+/*Scannable Adv state and Active Scanning State combination is supported. 0x0000000000002000 */
+#define HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK 0x20
+#define HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF 1
+#define HCI_LE_STATES_SCAN_ADV_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK)
+
+/*Connectable Adv state and Active Scanning State combination is supported. 0x0000000000004000 */
+#define HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK 0x40
+#define HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF 1
+#define HCI_LE_STATES_CONN_ADV_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK)
+
+/*High Duty Cycl Directed ADv and ACtive Scanning State combination is supported. 0x0000000000008000 */
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK 0x80
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF 1
+#define HCI_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF)
+
+/*Non-Connectable Adv state and Initiating State combination is supported. 0x0000000000010000 */
+#define HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK 0x01
+#define HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF 2
+#define HCI_LE_STATES_NON_CONN_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF] & HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK)
+
+/* Scannable Adv state and Initiating State combination is supported. 0x0000000000020000 */
+#define HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK 0x02
+#define HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF 2
+#define HCI_LE_STATES_SCAN_ADV_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK)
+
+/* Non-Connectable Adv state and Master Role combination is supported. 0x0000000000040000 */
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK 0x04
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF 2
+#define HCI_LE_STATES_NON_CONN_ADV_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK)
+
+/*Scannable Adv state and Master Role combination is supported. 0x0000000000040000 */
+#define HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK 0x08
+#define HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF 2
+#define HCI_LE_STATES_SCAN_ADV_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK)
+
+/* Non-Connectable Adv and Slave Role combination is supported. 0x000000000100000 */
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK 0x10
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF 2
+#define HCI_LE_STATES_NON_CONN_ADV_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK)
+
+/*Scannable Adv and Slave Role combination is supported. 0x000000000200000 */
+#define HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK 0x20
+#define HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF 2
+#define HCI_LE_STATES_SCAN_ADV_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK)
+
+/*Passive Scan and Initiating State combination is supported. 0x000000000400000 */
+#define HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK 0x40
+#define HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF 2
+#define HCI_LE_STATES_PASS_SCAN_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK)
+
+/*Active Scan and Initiating State combination is supported. 0x000000000800000 */
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK 0x80
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF 2
+#define HCI_LE_STATES_ACTIVE_SCAN_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK)
+
+/*Passive Scan and Master Role combination is supported. 0x000000001000000 */
+#define HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK 0x01
+#define HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF 3
+#define HCI_LE_STATES_PASS_SCAN_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK)
+
+/*Active Scan and Master Role combination is supported. 0x000000002000000 */
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK 0x02
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF 3
+#define HCI_LE_STATES_ACTIVE_SCAN_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK)
+
+/*Passive Scan and Slave Role combination is supported. 0x000000004000000 */
+#define HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK 0x04
+#define HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF 3
+#define HCI_LE_STATES_PASS_SCAN_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK)
+
+/*Active Scan and Slave Role combination is supported. 0x000000008000000 */
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK 0x08
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF 3
+#define HCI_LE_STATES_ACTIVE_SCAN_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK)
+
+/*Link Layer Topology Added States Combo */
+/*Initiating State and Master Role combination supported.
+ Master Role and Master Role combination is also supported. 0x0000000010000000 */
+#define HCI_SUPP_LE_STATES_INIT_MASTER_MASK 0x10
+#define HCI_SUPP_LE_STATES_INIT_MASTER_OFF 3
+#define HCI_LE_STATES_INIT_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_INIT_MASTER_OFF] & HCI_SUPP_LE_STATES_INIT_MASTER_MASK)
+
+/* Connectable Advertising State and Initiating State combination supported. 0x0000000100000000 */
+#define HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK 0x01
+#define HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF 4
+#define HCI_LE_STATES_CONN_ADV_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK)
+
+/* High Duty Cycle Directed Advertising State and Initiating State combination supported. */
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK 0x02
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF 4
+#define HCI_LE_STATES_HI_DUTY_DIR_ADV_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK)
+
+/* Low Duty Cycle Directed Advertising State and Initiating State combination supported.*/
+#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK 0x04
+#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF 4
+#define HCI_LE_STATES_LO_DUTY_DIR_ADV_INIT_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK)
+
+/* Connectable Advertising State and Master Role combination supported.*/
+#define HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK 0x08
+#define HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF 4
+#define HCI_LE_STATES_CONN_ADV_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK)
+
+/* High Duty Cycle Directed Advertising State and Master Role combination supported.*/
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK 0x10
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF 4
+#define HCI_LE_STATES_HI_DUTY_DIR_ADV_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK)
+
+/* Low Duty Cycle Directed Advertising State and Master Role combination supported.*/
+#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK 0x20
+#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF 4
+#define HCI_LE_STATES_LO_DUTY_DIR_ADV_MASTER_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK)
+
+/* Connectable Advertising State and Slave Role combination supported. */
+#define HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK 0x40
+#define HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF 4
+#define HCI_LE_STATES_CONN_ADV_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK)
+
+/* High Duty Cycle Directed Advertising State and slave Role combination supported.*/
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK 0x80
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF 4
+#define HCI_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK)
+
+/* Low Duty Cycle Directed Advertising State and slave Role combination supported.*/
+#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK 0x01
+#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF 5
+#define HCI_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK)
+
+/* Initiating State and Slave Role combination supported.
+ Master Role and Slave Role combination also supported.
+ */
+#define HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK 0x02
+#define HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF 5
+#define HCI_LE_STATES_INIT_MASTER_SLAVE_SUPPORTED(x) ((x)[HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF] & HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK)
+
+#define HCI_BRCM_ENABLE_WBS_MODIFIED (0x0102 | HCI_GRP_VENDOR_SPECIFIC)
+
+/* ConnectionLess Broadcast Stream VSC */
+#define HCI_BRCM_SET_CLB_STREAM (0x0111 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_RECEIVE_CLB_STREAM (0x0112 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_WRITE_CLB_STREAM_DATA (0x0113 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_CLB_STREAM_FLUSH (0x0114 | HCI_GRP_VENDOR_SPECIFIC)
+
/*
** Definitions for HCI Events
*/
@@ -411,6 +623,7 @@
#define HCI_NUM_COMPL_DATA_BLOCKS_EVT 0x48
#define HCI_SHORT_RANGE_MODE_COMPLETE_EVT 0x4C
#define HCI_AMP_STATUS_CHANGE_EVT 0x4D
+#define HCI_SET_TRIGGERED_CLOCK_CAPTURE_EVT 0x4E
/* ULP HCI Event */
#define HCI_BLE_EVENT 0x03E
@@ -420,16 +633,11 @@
#define HCI_BLE_LL_CONN_PARAM_UPD_EVT 0x03
#define HCI_BLE_READ_REMOTE_FEAT_CMPL_EVT 0x04
#define HCI_BLE_LTK_REQ_EVT 0x05
+#define HCI_BLE_RC_PARAM_REQ_EVT 0x06
-/* ConnectionLess Broadcast events */
-#define HCI_SYNC_TRAIN_COMP_EVT 0x4F
-#define HCI_SYNC_TRAIN_RECEIVED_EVT 0x50
-#define HCI_CLB_RX_DATA_EVT 0x51
-#define HCI_CLB_RX_TIMEOUT_EVT 0x52
-#define HCI_TRUNCATED_PAGE_COMP_EVT 0x53
-#define HCI_SLAVE_PAGE_RESP_TIMEOUT_EVT 0x54
-#define HCI_CLB_CHANNEL_CHANGE_EVT 0x55
-#define HCI_INQUIRY_RESPONSE_NOTIF 0x56
+/* Definitions for LE Channel Map */
+#define HCI_BLE_CHNL_MAP_SIZE 5
+
#define HCI_EVENT_RSP_FIRST HCI_INQUIRY_COMP_EVT
#define HCI_EVENT_RSP_LAST HCI_CLB_CHANNEL_CHANGE_EVT
@@ -439,6 +647,9 @@
because conflict w/ TCI_EVT and per
specification compliant */
+/* the event mask for BLE event mask */
+#define HCI_BLE_EVENT_MASK_DEF "\x00\x00\x00\x00\x00\x00\x00\x3f"
+
/*
@@ -1583,6 +1794,10 @@
#define HCI_EXT_FEATURE_SIMUL_DUMO_HOST_OFF 0
#define HCI_SIMUL_DUMO_HOST_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SIMUL_DUMO_HOST_OFF] & HCI_EXT_FEATURE_SIMUL_DUMO_HOST_MASK)
+#define HCI_EXT_FEATURE_SC_HOST_MASK 0x08
+#define HCI_EXT_FEATURE_SC_HOST_OFF 0
+#define HCI_SC_HOST_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SC_HOST_OFF] & HCI_EXT_FEATURE_SC_HOST_MASK)
+
/*
** LMP features encoding - page 2
*/
@@ -1606,19 +1821,43 @@
#define HCI_EXT_FEATURE_INQ_RESP_NOTIF_OFF 0
#define HCI_INQ_RESP_NOTIF_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_INQ_RESP_NOTIF_OFF] & HCI_EXT_FEATURE_INQ_RESP_NOTIF_MASK)
+#define HCI_EXT_FEATURE_SC_CTRLR_MASK 0x01
+#define HCI_EXT_FEATURE_SC_CTRLR_OFF 1
+#define HCI_SC_CTRLR_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SC_CTRLR_OFF] & HCI_EXT_FEATURE_SC_CTRLR_MASK)
+
+#define HCI_EXT_FEATURE_PING_MASK 0x02
+#define HCI_EXT_FEATURE_PING_OFF 1
+#define HCI_PING_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_PING_OFF] & HCI_EXT_FEATURE_PING_MASK)
+
/*
** LE features encoding - page 0 (the only page for now)
*/
+/* LE Encryption */
#define HCI_LE_FEATURE_LE_ENCRYPTION_MASK 0x01
#define HCI_LE_FEATURE_LE_ENCRYPTION_OFF 0
#define HCI_LE_ENCRYPTION_SUPPORTED(x) ((x)[HCI_LE_FEATURE_LE_ENCRYPTION_OFF] & HCI_LE_FEATURE_LE_ENCRYPTION_MASK)
+/* Connection Parameters Request Procedure */
+#define HCI_LE_FEATURE_CONN_PARAM_REQ_MASK 0x02
+#define HCI_LE_FEATURE_CONN_PARAM_REQ_OFF 0
+#define HCI_LE_CONN_PARAM_REQ_SUPPORTED(x) ((x)[HCI_LE_FEATURE_CONN_PARAM_REQ_OFF] & HCI_LE_FEATURE_CONN_PARAM_REQ_MASK)
+
+/* Extended Reject Indication */
+#define HCI_LE_FEATURE_EXT_REJ_IND_MASK 0x04
+#define HCI_LE_FEATURE_EXT_REJ_IND_OFF 0
+#define HCI_LE_EXT_REJ_IND_SUPPORTED(x) ((x)[HCI_LE_FEATURE_EXT_REJ_IND_OFF] & HCI_LE_FEATURE_EXT_REJ_IND_MASK)
+
+/* Slave-initiated Features Exchange */
+#define HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_MASK 0x08
+#define HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_OFF 0
+#define HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(x) ((x)[HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_OFF] & HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_MASK)
/*
** Local Supported Commands encoding
*/
#define HCI_NUM_SUPP_COMMANDS_BYTES 64
+/* Supported Commands Byte 0 */
#define HCI_SUPP_COMMANDS_INQUIRY_MASK 0x01
#define HCI_SUPP_COMMANDS_INQUIRY_OFF 0
#define HCI_INQUIRY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_INQUIRY_OFF] & HCI_SUPP_COMMANDS_INQUIRY_MASK)
@@ -2398,8 +2637,42 @@
#define HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM_OFF 32
#define HCI_WRITE_SYNC_TRAIN_PARAM_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM_OFF] & HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM)
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_MASK 0x02
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_OFF 32
+#define HCI_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_MASK)
+#define HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_MASK 0x04
+#define HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_OFF 32
+#define HCI_READ_SECURE_CONNS_SUPPORT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_OFF] & HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_MASK)
+#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_MASK 0x08
+#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_OFF 32
+#define HCI_WRITE_SECURE_CONNS_SUPPORT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_OFF] & HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_MASK 0x10
+#define HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_OFF 32
+#define HCI_READ_AUTHENT_PAYLOAD_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_MASK 0x20
+#define HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_OFF 32
+#define HCI_WRITE_AUTHENT_PAYLOAD_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_MASK 0x40
+#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_OFF 32
+#define HCI_READ_LOCAL_OOB_EXTENDED_DATA_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_MASK 0x80
+#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_OFF 32
+#define HCI_WRITE_SECURE_CONNECTIONS_TEST_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_MASK)
+
+/* supported LE remote control connection parameter request reply */
+#define HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_MASK 0x10
+#define HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_OFF 33
+#define HCI_LE_RC_CONN_PARAM_UPD_RPY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_OFF] & HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_MASK)
+
+#define HCI_SUPP_COMMANDS_RLE_RC_CONN_PARAM_UPD_NEG_RPY_MASK 0x20
+#define HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_NEG_RPY_OFF 33
+#define HCI_LE_RC_CONN_PARAM_UPD_NEG_RPY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_NEG_RPY_OFF] & HCI_SUPP_COMMANDS_RLE_RC_CONN_PARAM_UPD_NEG_RPY_MASK)
/*
Commands of HCI_GRP_VENDOR_SPECIFIC group for WIDCOMM SW LM Simulator
diff --git a/stack/include/hcimsgs.h b/stack/include/hcimsgs.h
index 318e748..3201f75 100644
--- a/stack/include/hcimsgs.h
+++ b/stack/include/hcimsgs.h
@@ -1252,8 +1252,6 @@
#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA 31
/* ULP HCI command */
-HCI_API extern BOOLEAN btsnd_hcic_ble_reset(void);
-
HCI_API extern BOOLEAN btsnd_hcic_ble_set_evt_mask (BT_EVENT_MASK event_mask);
HCI_API extern BOOLEAN btsnd_hcic_ble_read_buffer_size (void);
@@ -1331,6 +1329,20 @@
UINT8 payload);
HCI_API extern BOOLEAN btsnd_hcic_ble_test_end(void);
+#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
+
+#define HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY 14
+HCI_API extern BOOLEAN btsnd_hcic_ble_rc_param_req_reply(UINT16 handle,
+ UINT16 conn_int_min, UINT16 conn_int_max,
+ UINT16 conn_latency, UINT16 conn_timeout,
+ UINT16 min_ce_len, UINT16 max_ce_len);
+
+#define HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY 3
+HCI_API extern BOOLEAN btsnd_hcic_ble_rc_param_req_neg_reply(UINT16 handle, UINT8 reason);
+
+#endif /* BLE_LLT_INCLUDED */
+
+
#endif /* BLE_INCLUDED */
#ifdef __cplusplus
diff --git a/stack/include/l2c_api.h b/stack/include/l2c_api.h
index 0da7f79..54c7ddb 100644
--- a/stack/include/l2c_api.h
+++ b/stack/include/l2c_api.h
@@ -919,8 +919,9 @@
** BD Address of remote
** TRUE if channel is connected, FALSE if disconnected
** Reason for connection failure
+** transport : physical transport, BR/EDR or LE
*/
-typedef void (tL2CA_FIXED_CHNL_CB) (BD_ADDR, BOOLEAN, UINT16);
+typedef void (tL2CA_FIXED_CHNL_CB) (BD_ADDR, BOOLEAN, UINT16, tBT_TRANSPORT);
/* Signalling data received. Parameters are
** BD Address of remote
@@ -1128,7 +1129,8 @@
** Return value: TRUE if update started
**
*******************************************************************************/
-L2C_API extern BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bdRa, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout);
+L2C_API extern BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bdRa, UINT16 min_int,
+ UINT16 max_int, UINT16 latency, UINT16 timeout);
/*******************************************************************************
**
@@ -1146,18 +1148,6 @@
/*******************************************************************************
**
-** Function L2CA_HandleConnUpdateEvent
-**
-** Description This function enables the connection update request from remote
-** after a successful connection update response is received.
-**
-** Returns void
-**
-*******************************************************************************/
-L2C_API void L2CA_HandleConnUpdateEvent (UINT16 handle, UINT8 status);
-
-/*******************************************************************************
-**
** Function L2CA_GetBleConnRole
**
** Description This function returns the connection role.
@@ -1173,10 +1163,13 @@
**
** Description This function returns the disconnect reason code.
**
+** Parameters: BD Address of remote
+** Physical transport for the L2CAP connection (BR/EDR or LE)
+**
** Returns disconnect reason
**
*******************************************************************************/
-L2C_API extern UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda);
+L2C_API extern UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport);
#endif /* (BLE_INCLUDED == TRUE) */
diff --git a/stack/include/smp_api.h b/stack/include/smp_api.h
index 68c9ebf..e47cce3 100644
--- a/stack/include/smp_api.h
+++ b/stack/include/smp_api.h
@@ -134,9 +134,9 @@
typedef struct
{
- UINT8 reason;
- UINT8 sec_level;
- BOOLEAN is_pair_cancel;
+ tSMP_STATUS reason;
+ tSMP_SEC_LEVEL sec_level;
+ BOOLEAN is_pair_cancel;
} tSMP_CMPL;
typedef union
diff --git a/stack/include/uipc_msg.h b/stack/include/uipc_msg.h
index 6a9a4ae..53cdccf 100644
--- a/stack/include/uipc_msg.h
+++ b/stack/include/uipc_msg.h
@@ -105,231 +105,6 @@
} tUIPC_LOG_MSG;
#define UIPC_LOG_MSGLEN (IPC_LOG_MSG_LEN + 4)
-/********************************
-
- H5 Sync Message
-
-********************************/
-
-/* op_code */
-#define SLIP_SYNC_TO_LITE_REQ 0
-#define SLIP_SYNC_TO_LITE_RESP 1
-#define SLIP_SYNC_TO_FULL_REQ 2
-#define SLIP_SYNC_TO_FULL_RESP 3
-#define SLIP_SYNC_NOTIFY 4
-
-/* status */
-#define SLIP_SYNC_SUCCESS 0
-#define SLIP_SYNC_FAILURE 1
-
-typedef struct
-{
- UINT8 op_code;
- UINT8 status;
- UINT16 acl_pkt_size;
- UINT8 state;
- UINT8 lp_state; /* Low Power state */
- UINT8 next_seqno; /* next send seq */
- UINT8 ack; /* next ack seq, expected seq from peer */
- UINT8 sent_ack; /* last sent ack */
- UINT8 sliding_window_size;/* window size */
- BOOLEAN oof_flow_control; /* Out of Frame SW Flow Control */
- BOOLEAN data_integrity_type;/* Level of Data Integrity Check */
- UINT8 rx_state; /* rx state for incoming packet processing */
-} tSLIP_SYNC_INFO;
-
-/********************************
-
- L2CAP Sync Message
-
-********************************/
-
-/* op_code */
-#define L2C_SYNC_TO_LITE_REQ 0
-#define L2C_SYNC_TO_LITE_RESP 1
-#define L2C_REMOVE_TO_LITE_REQ 2
-#define L2C_REMOVE_TO_LITE_RESP 3
-#define L2C_FLUSH_TO_FULL_IND 4
-
-/* status */
-#define L2C_SYNC_SUCCESS 0
-#define L2C_SYNC_FAILURE 1
-
-typedef struct t_l2c_stream_info
-{
- UINT16 local_cid; /* Local CID */
- UINT16 remote_cid; /* Remote CID */
- UINT16 out_mtu; /* Max MTU we will send */
- UINT16 handle; /* The handle used with LM */
- UINT16 link_xmit_quota; /* Num outstanding pkts allowed */
- BOOLEAN is_flushable; /* TRUE if flushable channel */
-} tL2C_STREAM_INFO;
-
-typedef struct t_l2c_sync_to_lite_req
-{
- UINT8 op_code; /* L2C_SYNC_TO_LITE_REQ */
- UINT16 light_xmit_quota; /* Total quota for light stack */
- UINT16 acl_data_size; /* Max ACL data size across HCI transport */
- UINT16 non_flushable_pbf; /* L2CAP_PKT_START_NON_FLUSHABLE if controller supports */
- /* Otherwise, L2CAP_PKT_START */
- UINT8 multi_av_data_cong_start; /* Multi-AV queue size to start congestion */
- UINT8 multi_av_data_cong_end; /* Multi-AV queue size to end congestion */
- UINT8 multi_av_data_cong_discard; /* Multi-AV queue size to discard */
- UINT8 num_stream;
- tL2C_STREAM_INFO stream[BTM_SYNC_INFO_NUM_STR];
-} tL2C_SYNC_TO_LITE_REQ;
-
-typedef struct t_l2c_sync_to_lite_resp_stream
-{
- UINT16 lcid;
- UINT8 status;
-} tL2C_SYNC_TO_LITE_RESP_STREAM;
-
-typedef struct t_l2c_sync_to_lite_resp
-{
- UINT8 op_code; /* L2C_SYNC_TO_LITE_RESP */
- UINT16 light_xmit_unacked; /* unacked packet more than quota in light stack */
- UINT8 num_stream;
- tL2C_SYNC_TO_LITE_RESP_STREAM stream[BTM_SYNC_INFO_NUM_STR];
-} tL2C_SYNC_TO_LITE_RESP;
-
-typedef struct t_l2c_remove_to_lite_req
-{
- UINT8 op_code; /* L2C_REMOVE_TO_LITE_REQ */
- UINT16 light_xmit_quota; /* Total quota for light stack */
- UINT8 num_stream;
- UINT16 lcid[BTM_SYNC_INFO_NUM_STR];
-} tL2C_REMOVE_TO_LITE_REQ;
-
-typedef tL2C_SYNC_TO_LITE_RESP tL2C_REMOVE_TO_LITE_RESP;
-typedef tL2C_REMOVE_TO_LITE_REQ tL2C_FLUSH_TO_FULL_IND;
-
-typedef union t_l2c_sync_msg
-{
- UINT8 op_code;
- tL2C_SYNC_TO_LITE_REQ sync_req;
- tL2C_SYNC_TO_LITE_RESP sync_resp;
- tL2C_REMOVE_TO_LITE_REQ remove_req;
- tL2C_REMOVE_TO_LITE_RESP remove_resp;
- tL2C_FLUSH_TO_FULL_IND flush_ind;
-} tL2C_SYNC_MSG;
-
-/********************************
-
- AVDTP Sync Message
-
-********************************/
-
-/* op_code */
-#define AVDT_SYNC_TO_LITE_REQ 0
-#define AVDT_SYNC_TO_LITE_RESP 1
-#define AVDT_RESYNC_TO_LITE_REQ 2
-#define AVDT_RESYNC_TO_LITE_RESP 3
-#define AVDT_SYNC_TO_FULL_REQ 4
-#define AVDT_SYNC_TO_FULL_RESP 5
-#define AVDT_REMOVE_TO_LITE_REQ 6
-#define AVDT_REMOVE_TO_LITE_RESP 7
-#define AVDT_SYNC_TO_BTC_LITE_REQ 8
-#define AVDT_SYNC_TO_BTC_LITE_RESP 9
-
-/* status */
-#define AVDT_SYNC_SUCCESS 0
-#define AVDT_SYNC_FAILURE 1
-
-typedef struct
-{
- UINT16 lcid;
- UINT32 ssrc;
-} tAVDT_SYNC_TO_BTC_LITE_REQ_STREAM;
-
-typedef struct
-{
- UINT8 opcode; /* AVDT_SYNC_TO_BTC_LITE_REQ */
- UINT8 num_stream;
- tAVDT_SYNC_TO_BTC_LITE_REQ_STREAM stream[BTM_SYNC_INFO_NUM_STR];
-} tAVDT_SYNC_TO_BTC_LITE_REQ;
-
-typedef struct
-{
- UINT8 opcode; /* AVDT_SYNC_TO_BTC_LITE_RESP */
- UINT8 status;
-} tAVDT_SYNC_TO_BTC_LITE_RESP;
-
-typedef struct t_avdt_scb_sync_info
-{
- UINT8 handle; /* SCB handle */
- BD_ADDR peer_addr; /* BD address of peer */
- UINT16 local_cid; /* Local CID */
- UINT16 peer_mtu; /* L2CAP mtu of the peer device */
- UINT8 mux_tsid_media; /* TSID for media transport session */
- UINT16 media_seq; /* media packet sequence number */
-} tAVDT_SCB_SYNC_INFO;
-
-typedef struct t_avdt_sync_info
-{
- UINT8 op_code;
- UINT8 status;
-
- tAVDT_SCB_SYNC_INFO scb_info[BTM_SYNC_INFO_NUM_STR];
-
-} tAVDT_SYNC_INFO;
-
-typedef union t_avdt_sync_msg
-{
- UINT8 op_code;
- tAVDT_SYNC_INFO sync_info;
- tAVDT_SYNC_TO_BTC_LITE_REQ btc_sync_req;
- tAVDT_SYNC_TO_BTC_LITE_RESP btc_sync_resp;
-} tAVDT_SYNC_MSG;
-
-/********************************
-
- BTA AV Sync Message
-
-********************************/
-
-/* op_code for MM light stack */
-#define BTA_AV_SYNC_TO_LITE_REQ 0
-#define BTA_AV_SYNC_TO_LITE_RESP 1
-#define BTA_AV_STR_START_TO_LITE_REQ 2
-#define BTA_AV_STR_START_TO_LITE_RESP 3
-#define BTA_AV_STR_STOP_TO_LITE_REQ 4
-#define BTA_AV_STR_STOP_TO_LITE_RESP 5
-#define BTA_AV_STR_CLEANUP_TO_LITE_REQ 6
-#define BTA_AV_STR_CLEANUP_TO_LITE_RESP 7
-#define BTA_AV_STR_SUSPEND_TO_LITE_REQ 8
-#define BTA_AV_STR_SUSPEND_TO_LITE_RESP 9
-#define BTA_AV_SYNC_ERROR_RESP 10
-
-/* op_code for BTC light stack */
-#define A2DP_START_REQ 11
-#define A2DP_START_RESP 12
-#define A2DP_STOP_REQ 13
-#define A2DP_STOP_RESP 14
-#define A2DP_CLEANUP_REQ 15
-#define A2DP_CLEANUP_RESP 16
-#define A2DP_SUSPEND_REQ 17
-#define A2DP_SUSPEND_RESP 18
-
-#define A2DP_JITTER_DONE_IND 41 /* For BTSNK */
-
-#define AUDIO_CODEC_CONFIG_REQ 19
-#define AUDIO_CODEC_CONFIG_RESP 20
-#define AUDIO_CODEC_SET_BITRATE_REQ 21
-#define AUDIO_CODEC_FLUSH_REQ 22
-#define AUDIO_ROUTE_CONFIG_REQ 23
-#define AUDIO_ROUTE_CONFIG_RESP 24
-#define AUDIO_MIX_CONFIG_REQ 25
-#define AUDIO_MIX_CONFIG_RESP 26
-#define AUDIO_BURST_FRAMES_IND 27
-#define AUDIO_BURST_END_IND 28
-#define AUDIO_EQ_MODE_CONFIG_REQ 29
-#define AUDIO_SCALE_CONFIG_REQ 30
-
-/* For TIVO, only applicable for I2S -> DAC */
-#define AUDIO_SUB_ROUTE_REQ 51
-#define AUDIO_SUB_ROUTE_RESP 52
-
typedef struct
{
UINT8 opcode; /* A2DP_START_REQ */
@@ -789,96 +564,5 @@
tMIX_SCALE_CONFIG mix_scale;
} tAUDIO_SCALE_CONFIG_REQ;
-typedef UINT8 tBTA_AV_DUAL_STACK_EVT;
-
-typedef struct
-{
- UINT8 avdt_handle; /* AVDTP handle */
- UINT8 chnl; /* the channel: audio/video */
- UINT8 codec_type; /* codec type */
- BOOLEAN cong; /* TRUE if AVDTP congested */
- UINT8 hdi; /* the index to SCB[] */
- UINT8 hndl; /* the handle: ((hdi + 1)|chnl) */
- UINT8 l2c_bufs; /* the number of buffers queued to L2CAP */
- UINT16 l2c_cid; /* L2CAP channel ID */
- BD_ADDR peer_addr; /* peer BD address */
-}tBTA_AV_SYNC_INFO;
-
-typedef struct
-{
- tBTA_AV_DUAL_STACK_EVT event;
- tBTA_AV_SYNC_INFO sync_info;
- UINT16 curr_mtu; /* common mtu shared by all active streams */
- UINT8 multi_av_supported; /* Whether multi-av is supported */
-}tBTA_AV_SYNC_INFO_REQ; /* SYNC_TO_LITE_REQ */
-
-/* Dual stack stream events */
-typedef struct
-{
- tBTA_AV_DUAL_STACK_EVT event;
- UINT8 scb_idx;
-}tBTA_AV_SCB_EVT;
-
-/* data type for the Audio Codec Information*/
-typedef struct
-{
- UINT16 bit_rate; /* SBC encoder bit rate in kbps */
- UINT16 bit_rate_busy; /* SBC encoder bit rate in kbps */
- UINT16 bit_rate_swampd; /* SBC encoder bit rate in kbps */
- UINT8 busy_level; /* Busy level indicating the bit-rate to be used */
- UINT8 codec_info[AVDT_CODEC_SIZE];
- UINT8 codec_type; /* Codec type */
-} tBTA_AV_AUDIO_CODEC_SYNC_INFO;
-
-/* Dual stack stream events */
-typedef struct
-{
- tBTA_AV_DUAL_STACK_EVT event;
- UINT8 scb_idx;
- UINT8 audio_open_cnt;
- tBTA_AV_AUDIO_CODEC_SYNC_INFO p_codec_cfg;
- UINT8 start_stop_flag;
-}tBTA_AV_SCB_REQ;
-
-typedef struct
-{
- tBTA_AV_DUAL_STACK_EVT event;
- UINT8 scb_idx;
- UINT8 audio_open_cnt;
- UINT16 curr_mtu; /* common mtu shared by all active streams */
-}tBTA_AV_SCB_CLEANUP_REQ;
-
-/* Add request/response structures if needed ...
-typedef struct
-{
- event;
- data;
-}tBTA_AV_SYNC_*_REQ/RESP;
-*/
-
-typedef union
-{
- /* MM light stack */
- tBTA_AV_DUAL_STACK_EVT event;
- tBTA_AV_SYNC_INFO_REQ sync_info_req;
- tBTA_AV_SCB_EVT scb_evt;
- tBTA_AV_SCB_REQ scb_req;
- tBTA_AV_SCB_CLEANUP_REQ scb_cleanup_req;
-
- /* BTC light stack */
- UINT8 opcode;
- tA2DP_START_REQ btc_start_req;
- tA2DP_STOP_REQ btc_stop_req;
- tA2DP_CLEANUP_REQ btc_cleanup_req;
- tA2DP_SUSPEND_REQ btc_suspend_req;
-
- tAUDIO_CODEC_CONFIG_REQ codec_config_req;
- tAUDIO_CODEC_SET_BITRATE_REQ codec_bitrate_req;
- tAUDIO_CODEC_FLUSH_REQ codec_flush_req;
- tAUDIO_ROUTE_CONFIG_REQ route_config_req;
- tAUDIO_MIX_CONFIG_REQ mix_config_req;
- tAUDIO_EQ_MODE_CONFIG_REQ eq_mode_req;
- tAUDIO_SCALE_CONFIG_REQ scale_config_req;
-}tBTA_DUAL_STACK_MSG;
-
#endif /* UIPC_MSG_H */
+
diff --git a/stack/l2cap/l2c_api.c b/stack/l2cap/l2c_api.c
index 30249a4..338a7cd 100644
--- a/stack/l2cap/l2c_api.c
+++ b/stack/l2cap/l2c_api.c
@@ -223,6 +223,10 @@
** connection establishment gets started. The callback function
** will be invoked when connection establishes or fails.
**
+** Parameters: PSM: L2CAP PSM for the connection
+** BD address of the peer
+** Enhaced retransmission mode configurations
+
** Returns the CID of the connection, or 0 if it failed to start
**
*******************************************************************************/
@@ -232,10 +236,12 @@
tL2C_CCB *p_ccb;
tL2C_RCB *p_rcb;
- L2CAP_TRACE_API6 ("L2CA_ErtmConnectReq() PSM: 0x%04x BDA: %08x%04x p_ertm_info: 0x%08x allowed:0x%x preferred:%d", psm,
+ L2CAP_TRACE_API6 ("L2CA_ErtmConnectReq() PSM: 0x%04x BDA: %08x%04x p_ertm_info"
+ ": 0x%08x allowed:0x%x preferred:%d", psm,
(p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3],
(p_bd_addr[4]<<8)+p_bd_addr[5], p_ertm_info,
- (p_ertm_info) ? p_ertm_info->allowed_modes : 0, (p_ertm_info) ? p_ertm_info->preferred_mode : 0);
+ (p_ertm_info) ? p_ertm_info->allowed_modes : 0,
+ (p_ertm_info) ? p_ertm_info->preferred_mode : 0);
/* Fail if we have not established communications with the controller */
if (!BTM_IsDeviceUp())
@@ -251,13 +257,16 @@
}
/* First, see if we already have a link to the remote */
- if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL)
+ /* assume all ERTM l2cap connection is going over BR/EDR for now */
+ if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
{
/* No link. Get an LCB and start link establishment */
- if ( ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE)) == NULL)
- || (l2cu_create_conn(p_lcb) == FALSE) )
+ if ( ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE, BT_TRANSPORT_BR_EDR)) == NULL)
+ /* currently use BR/EDR for ERTM mode l2cap connection */
+ || (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE) )
{
- L2CAP_TRACE_WARNING2 ("L2CAP - conn not started for PSM: 0x%04x p_lcb: 0x%08x", psm, p_lcb);
+ L2CAP_TRACE_WARNING2 ("L2CAP - conn not started for PSM: 0x%04x p_lcb: 0x%08x",
+ psm, p_lcb);
return (0);
}
}
@@ -289,7 +298,8 @@
if (p_ccb->ertm_info.user_tx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID)
p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID;
- p_ccb->max_rx_mtu = GKI_get_pool_bufsize (p_ertm_info->user_rx_pool_id) - (L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN);
+ p_ccb->max_rx_mtu = GKI_get_pool_bufsize (p_ertm_info->user_rx_pool_id) -
+ (L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN);
}
/* If link is up, start the L2CAP connection */
@@ -312,7 +322,8 @@
p_lcb->p_pending_ccb = p_ccb;
}
- L2CAP_TRACE_API2 ("L2CAP - L2CA_conn_req(psm: 0x%04x) returned CID: 0x%04x", psm, p_ccb->local_cid);
+ L2CAP_TRACE_API2 ("L2CAP - L2CA_conn_req(psm: 0x%04x) returned CID: 0x%04x",
+ psm, p_ccb->local_cid);
/* Return the local CID as our handle */
return (p_ccb->local_cid);
@@ -330,7 +341,8 @@
** Returns TRUE for success, FALSE for failure
**
*******************************************************************************/
-BOOLEAN L2CA_ConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 result, UINT16 status)
+BOOLEAN L2CA_ConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid,
+ UINT16 result, UINT16 status)
{
return L2CA_ErtmConnectRsp (p_bd_addr, id, lcid, result, status, NULL);
}
@@ -353,13 +365,14 @@
tL2C_LCB *p_lcb;
tL2C_CCB *p_ccb;
- L2CAP_TRACE_API6 ("L2CA_ErtmConnectRsp() CID: 0x%04x Result: %d Status: %d BDA: %08x%04x p_ertm_info:0x%08x",
+ L2CAP_TRACE_API6 ("L2CA_ErtmConnectRsp() CID: 0x%04x Result: %d Status: %d BDA: %08x%04x"
+ " p_ertm_info:0x%08x",
lcid, result, status,
(p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3],
(p_bd_addr[4]<<8)+p_bd_addr[5], p_ertm_info);
/* First, find the link control block */
- if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL)
+ if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
{
/* No link. Get an LCB and start link establishment */
L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_conn_rsp");
@@ -594,15 +607,15 @@
return (FALSE);
/* First, see if we already have a link to the remote */
- if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL)
+ if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
{
/* No link. Get an LCB and start link establishment */
- if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE)) == NULL)
+ if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE, BT_TRANSPORT_BR_EDR)) == NULL)
{
L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_ping");
return (FALSE);
}
- if (l2cu_create_conn(p_lcb) == FALSE)
+ if (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE)
{
return (FALSE);
}
@@ -670,7 +683,7 @@
}
/* We assume the upper layer will call this function only when the link is established. */
- if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL)
+ if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
{
L2CAP_TRACE_ERROR0 ("L2CA_Echo ERROR : link not established");
return FALSE;
@@ -767,7 +780,7 @@
if (memcmp (BT_BD_ANY, bd_addr, BD_ADDR_LEN))
{
- p_lcb = l2cu_find_lcb_by_bd_addr( bd_addr );
+ p_lcb = l2cu_find_lcb_by_bd_addr( bd_addr, BT_TRANSPORT_BR_EDR);
if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED))
p_lcb->idle_timeout = timeout;
else
@@ -880,7 +893,7 @@
return (0);
}
- if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE)) == NULL)
+ if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE, BT_TRANSPORT_BR_EDR)) == NULL)
{
L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_conn_req");
return (0);
@@ -1129,7 +1142,7 @@
if (memcmp (BT_BD_ANY, bd_addr, BD_ADDR_LEN))
{
- p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr);
+ p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR);
if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED))
{
@@ -1195,7 +1208,7 @@
tL2C_LCB *p_lcb;
/* We must already have a link to the remote */
- if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr)) == NULL)
+ if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
{
L2CAP_TRACE_WARNING2 ("L2CA_GetPeerFeatures() No BDA: %08x%04x",
(bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
@@ -1307,9 +1320,8 @@
BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda)
{
tL2C_LCB *p_lcb;
-#if BLE_INCLUDED == TRUE
+ tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
UINT16 reason;
-#endif
L2CAP_TRACE_API3 ("L2CA_ConnectFixedChnl() CID: 0x%04x BDA: %08x%04x", fixed_cid,
(rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
@@ -1329,39 +1341,58 @@
return (FALSE);
}
+#if BLE_INCLUDED == TRUE
+ if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
+ transport = BT_TRANSPORT_LE;
+#endif
+
/* If we already have a link to the remote, check if it supports that CID */
- if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) != NULL)
+ if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport)) != NULL)
{
if (!(p_lcb->peer_chnl_mask[0] & (1 << fixed_cid)))
{
- L2CAP_TRACE_EVENT3 ("L2CA_ConnectFixedChnl() CID: 0x%04x BDA: %08x%04x not supported", fixed_cid,
- (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
+ L2CAP_TRACE_EVENT3 ("L2CA_ConnectFixedChnl() CID:0x%04x BDA: %08x%04x not supported",
+ fixed_cid,(rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
+ (rem_bda[4]<<8)+rem_bda[5]);
return (FALSE);
}
/* Get a CCB and link the lcb to it */
- if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
+ if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid,
+ &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
{
L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - LCB but no CCB", fixed_cid);
return (FALSE);
}
+
+ /* racing with disconnecting, queue the connection request */
+ if (p_lcb->link_state == LST_DISCONNECTING)
+ {
+ L2CAP_TRACE_DEBUG0 ("L2CAP API - link disconnecting: RETRY LATER");
+ /* Save ccb so it can be started after disconnect is finished */
+ p_lcb->p_pending_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];
+ return (TRUE);
+ }
+
#if BLE_INCLUDED == TRUE
- reason = (p_lcb->is_ble_link) ? 1: 0;
- (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, reason);
+ (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)
+ (p_lcb->remote_bd_addr, TRUE, 0, p_lcb->transport);
#else
- (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, 0);
+ (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)
+ (p_lcb->remote_bd_addr, TRUE, 0, BT_TRANSPORT_BR_EDR);
#endif
return (TRUE);
}
/* No link. Get an LCB and start link establishment */
- if ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE)) == NULL)
+ if ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE, transport)) == NULL)
{
L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - no LCB", fixed_cid);
return (FALSE);
}
/* Get a CCB and link the lcb to it */
- if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
+ if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid,
+ &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
{
p_lcb->disc_reason = L2CAP_CONN_NO_RESOURCES;
L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - no CCB", fixed_cid);
@@ -1369,7 +1400,7 @@
return (FALSE);
}
- return (l2cu_create_conn(p_lcb));
+ return (l2cu_create_conn(p_lcb, transport));
}
/*******************************************************************************
@@ -1389,10 +1420,16 @@
UINT16 L2CA_SendFixedChnlData (UINT16 fixed_cid, BD_ADDR rem_bda, BT_HDR *p_buf)
{
tL2C_LCB *p_lcb;
+ tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
L2CAP_TRACE_API3 ("L2CA_SendFixedChnlData() CID: 0x%04x BDA: %08x%04x", fixed_cid,
(rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
+#if BLE_INCLUDED == TRUE
+ if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
+ transport = BT_TRANSPORT_LE;
+#endif
+
/* Check CID is valid and registered */
if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL)
|| (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL) )
@@ -1409,7 +1446,9 @@
}
/* We need to have a link up */
- if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL)
+ if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport)) == NULL ||
+ /* if link is disconnecting, also report data sending failure */
+ p_lcb->link_state == LST_DISCONNECTING)
{
L2CAP_TRACE_WARNING1 ("L2CA_SendFixedChnlData(0x%04x) - no LCB", fixed_cid);
return (L2CAP_DW_FAILED);
@@ -1463,6 +1502,7 @@
{
tL2C_LCB *p_lcb;
tL2C_CCB *p_ccb;
+ tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
/* Check CID is valid and registered */
if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL)
@@ -1472,8 +1512,14 @@
return (FALSE);
}
+#if BLE_INCLUDED == TRUE
+ if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
+ transport = BT_TRANSPORT_LE;
+#endif
+
/* Is a fixed channel connected to the remote BDA ?*/
- p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda);
+ p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport);
+
if ( ((p_lcb) == NULL) || (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) )
{
L2CAP_TRACE_WARNING3 ("L2CA_RemoveFixedChnl() CID: 0x%04x BDA: %08x%04x not connected", fixed_cid,
@@ -1491,7 +1537,14 @@
p_lcb->disc_reason = HCI_ERR_CONN_CAUSE_LOCAL_HOST;
#if BLE_INCLUDED == TRUE
- if (fixed_cid == L2CAP_ATT_CID && !p_lcb->ccb_queue.p_first_ccb)
+ /* retain the link for a few more seconds after SMP pairing is done, since Android
+ platformalways do service discovery after pairing complete. This way would avoid
+ the link down (pairing is complete) and an immediate reconnection for service
+ discovery. Some devices do not do auto advertising when link is dropped, thus fail
+ the second connection and service discovery.
+ BEFORE :if ((fixed_cid == L2CAP_ATT_CID || fixed_cid == L2CAP_SMP_CID)
+ && !p_lcb->ccb_queue.p_first_ccb)*/
+ if ((fixed_cid == L2CAP_ATT_CID ) && !p_lcb->ccb_queue.p_first_ccb)
p_lcb->idle_timeout = 0;
#endif
@@ -1520,9 +1573,15 @@
BOOLEAN L2CA_SetFixedChannelTout (BD_ADDR rem_bda, UINT16 fixed_cid, UINT16 idle_tout)
{
tL2C_LCB *p_lcb;
+ tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
+
+#if BLE_INCLUDED == TRUE
+ if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
+ transport = BT_TRANSPORT_LE;
+#endif
/* Is a fixed channel connected to the remote BDA ?*/
- p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda);
+ p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport);
if ( ((p_lcb) == NULL) || (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) )
{
L2CAP_TRACE_WARNING3 ("L2CA_SetFixedChannelTout() CID: 0x%04x BDA: %08x%04x not connected", fixed_cid,
@@ -1614,7 +1673,7 @@
tL2C_LCB *p_lcb;
/* Find the link that is associated with this remote bdaddr */
- p_lcb = l2cu_find_lcb_by_bd_addr (p_bda);
+ p_lcb = l2cu_find_lcb_by_bd_addr (p_bda, BT_TRANSPORT_BR_EDR);
/* If no link for this handle, nothing to do. */
if (!p_lcb)
diff --git a/stack/l2cap/l2c_ble.c b/stack/l2cap/l2c_ble.c
index ba0d7ec..0e6c73a 100644
--- a/stack/l2cap/l2c_ble.c
+++ b/stack/l2cap/l2c_ble.c
@@ -32,6 +32,9 @@
#include "hcimsgs.h"
#if (BLE_INCLUDED == TRUE)
+#define L2CA_GET_UPD_ST(x) ((x) & UPD_ST_MASK)
+#define L2CA_SET_UPD_ST(x, y) x = (((x) & ~UPD_ST_MASK) | (y))
+
/*******************************************************************************
**
@@ -68,7 +71,7 @@
if (btsnd_hcic_ble_create_conn_cancel())
{
- if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) != NULL)
+ if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE)) != NULL)
{
p_lcb->disc_reason = L2CAP_CONN_CANCEL;
l2cu_release_lcb (p_lcb);
@@ -84,57 +87,6 @@
/*******************************************************************************
**
-** Function L2CA_InternalBleConnUpdate
-**
-** Description update BLE connection based on status
-**
-** Parameters: lcb
-**
-** Return value: none
-**
-*******************************************************************************/
-static void L2CA_InternalBleConnUpdate (tL2C_LCB *p_lcb)
-{
- if (p_lcb->upd_status & L2C_BLE_UPDATE_PENDING) return;
-
- if (p_lcb->upd_status & L2C_BLE_CONN_UPDATE_DISABLE)
- {
- /* application requests to disable parameters update.
- If parameters are already updated, lets set them
- up to what has been requested during connection establishement */
- if (p_lcb->upd_status & L2C_BLE_NOT_DEFAULT_PARAM)
- {
- tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev(p_lcb->remote_bd_addr);
-
- btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle,
- (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_DEF),
- (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_MAX_DEF),
- (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ?
- p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF),
- (UINT16)((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ?
- p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF),
- 0, 0);
- p_lcb->upd_status &= ~L2C_BLE_NOT_DEFAULT_PARAM;
- p_lcb->upd_status |= (L2C_BLE_UPDATE_PENDING | L2C_BLE_NEW_CONN_PARAM);
- }
- }
- else
- {
- /* application allows to do update, if we were delaying one do it now */
- if (p_lcb->upd_status & L2C_BLE_NEW_CONN_PARAM)
- {
- btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, p_lcb->min_interval,
- p_lcb->max_interval, p_lcb->latency, p_lcb->timeout, 0, 0);
- p_lcb->upd_status &= ~L2C_BLE_NEW_CONN_PARAM;
- p_lcb->upd_status |= (L2C_BLE_UPDATE_PENDING | L2C_BLE_NOT_DEFAULT_PARAM);
- }
- }
-}
-
-/*******************************************************************************
-**
** Function L2CA_UpdateBleConnParams
**
** Description Update BLE connection parameters.
@@ -144,41 +96,54 @@
** Return value: TRUE if update started
**
*******************************************************************************/
-BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout)
+BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_int,
+ UINT16 latency, UINT16 timeout)
{
- tL2C_LCB *p_lcb;
+ tL2C_LCB *p_lcb;
+ tACL_CONN *p_acl_cb = btm_bda_to_acl(rem_bda, BT_TRANSPORT_LE);
- /* See if we have a link control block for the remote device */
- p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda);
+ /* See if we have a link control block for the remote device */
+ p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE);
- /* If we don't have one, create one and accept the connection. */
- if (!p_lcb)
- {
- L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x",
- (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
- return(FALSE);
- }
+ /* If we don't have one, create one and accept the connection. */
+ if (!p_lcb || !p_acl_cb)
+ {
+ L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x",
+ (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
+ (rem_bda[4]<<8)+rem_bda[5]);
+ return(FALSE);
+ }
- if (!p_lcb->is_ble_link)
- {
- L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE",
- (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
- return(FALSE);
- }
+ if (p_lcb->transport != BT_TRANSPORT_LE)
+ {
+ L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE",
+ (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
+ (rem_bda[4]<<8)+rem_bda[5]);
+ return(FALSE);
+ }
+#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
+ /* if both 4.1 compliant */
+ if ((HCI_LE_CONN_PARAM_REQ_SUPPORTED(btm_cb.devcb.local_le_features) &&
+ HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features)))
+ {
+ /* TODO: CE length selection ?? */
+ btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int,
+ latency, timeout, 0, 0);
+ }
+ else
+ /* if either side does not support Connection Parameters Request
+ Link Layer Control Procedure,
+ use Link Layer Connection Update procedure */
+#endif
+ {
+ if (p_lcb->link_role == HCI_ROLE_MASTER)
+ btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int,
+ latency, timeout, 0, 0);
+ else
+ l2cu_send_peer_ble_par_req (p_lcb, min_int, max_int, latency, timeout);
+ }
+ return(TRUE);
- if (p_lcb->link_role == HCI_ROLE_MASTER)
- {
- p_lcb->min_interval = min_int;
- p_lcb->max_interval = max_int;
- p_lcb->latency = latency;
- p_lcb->timeout = timeout;
- p_lcb->upd_status |= L2C_BLE_NEW_CONN_PARAM;
- L2CA_InternalBleConnUpdate(p_lcb);
- }
- else
- l2cu_send_peer_ble_par_req (p_lcb, min_int, max_int, latency, timeout);
-
- return(TRUE);
}
@@ -198,76 +163,68 @@
tL2C_LCB *p_lcb;
/* See if we have a link control block for the remote device */
- p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda);
+ p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE);
- /* If we don't have one, create one and accept the connection. */
if (!p_lcb)
{
L2CAP_TRACE_WARNING2 ("L2CA_EnableUpdateBleConnParams - unknown BD_ADDR %08x%04x",
- (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
+ (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
+ (rem_bda[4]<<8)+rem_bda[5]);
return (FALSE);
}
- L2CAP_TRACE_API4 ("L2CA_EnableUpdateBleConnParams - BD_ADDR %08x%04x enable %d upd state %d",
- (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5],
- enable, p_lcb->upd_status);
+ L2CAP_TRACE_API5 ("%s - BD_ADDR %08x%04x enable %d current upd state 0x%02x",__FUNCTION__,
+ (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
+ (rem_bda[4]<<8)+rem_bda[5], enable, p_lcb->conn_update_mask);
- if (!p_lcb->is_ble_link || (p_lcb->link_role != HCI_ROLE_MASTER))
+ if (p_lcb->transport != BT_TRANSPORT_LE || (p_lcb->link_role != HCI_ROLE_MASTER))
{
- L2CAP_TRACE_WARNING3 ("L2CA_EnableUpdateBleConnParams - BD_ADDR %08x%04x not LE or not master %d",
- (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5], p_lcb->link_role);
+ L2CAP_TRACE_WARNING4 ("%s - BD_ADDR %08x%04x not LE or not master %d", __FUNCTION__,
+ (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
+ (rem_bda[4]<<8)+rem_bda[5], p_lcb->link_role);
return (FALSE);
}
if (enable)
{
- p_lcb->upd_status &= ~L2C_BLE_CONN_UPDATE_DISABLE;
+ if (L2CA_GET_UPD_ST (p_lcb->conn_update_mask) == UPD_DISABLED)
+ {
+ p_lcb->conn_param_enb.param = (TIMER_PARAM_TYPE)p_lcb;
+ btu_start_timer (&p_lcb->conn_param_enb, BTU_TTYPE_L2CAP_END_CONN_UPD,
+ L2CAP_BLE_ENB_CONN_PARAM_TOUT);
+ L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_ENB_TOUT);
+ }
}
- else
+ else if (L2CA_GET_UPD_ST (p_lcb->conn_update_mask) != UPD_DISABLED)
{
- p_lcb->upd_status |= L2C_BLE_CONN_UPDATE_DISABLE;
- }
+ btu_stop_timer(&p_lcb->conn_param_enb);
- L2CA_InternalBleConnUpdate(p_lcb);
+ if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED)
+ {
+
+ /*
+ application requests to disable parameters update.If parameters are already updated,
+ lets set them up to what has been requested during connection establishement
+ */
+ if ((p_lcb->conn_update_mask & UPD_REQUEST) != 0)
+ {
+ /* revert back to default */
+ btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle,
+ BTM_BLE_CONN_INT_MIN_DEF,
+ BTM_BLE_CONN_INT_MAX_DEF,
+ BTM_BLE_CONN_SLAVE_LATENCY_DEF,
+ BTM_BLE_CONN_TIMEOUT_DEF,
+ 0, 0);
+ }
+ }
+ L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_DISABLED);
+
+ }
return (TRUE);
+
}
-/*******************************************************************************
-**
-** Function L2CA_HandleConnUpdateEvent
-**
-** Description This function enables the connection update request from remote
-** after a successful connection update response is received.
-**
-** Returns void
-**
-*******************************************************************************/
-void L2CA_HandleConnUpdateEvent (UINT16 handle, UINT8 status)
-{
- tL2C_LCB *p_lcb;
-
- L2CAP_TRACE_DEBUG0("L2CA_HandleConnUpdateEvent");
-
- /* See if we have a link control block for the remote device */
- p_lcb = l2cu_find_lcb_by_handle(handle);
- if (!p_lcb)
- {
- L2CAP_TRACE_WARNING1("L2CA_EnableUpdateBleConnParams: Invalid handle: %d", handle);
- return;
- }
-
- p_lcb->upd_status &= ~L2C_BLE_UPDATE_PENDING;
-
- if (status != HCI_SUCCESS)
- {
- L2CAP_TRACE_WARNING1("L2CA_EnableUpdateBleConnParams: Error status: %d", status);
- }
-
- L2CA_InternalBleConnUpdate(p_lcb);
-
- L2CAP_TRACE_DEBUG1("L2CA_HandleConnUpdateEvent: upd_status=%d", p_lcb->upd_status);
-}
/*******************************************************************************
**
@@ -284,7 +241,7 @@
tL2C_LCB *p_lcb;
- if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr)) != NULL)
+ if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_LE)) != NULL)
role = p_lcb->link_role;
return role;
@@ -298,12 +255,12 @@
** Returns disconnect reason
**
*******************************************************************************/
-UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda)
+UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport)
{
tL2C_LCB *p_lcb;
UINT16 reason = 0;
- if ((p_lcb = l2cu_find_lcb_by_bd_addr (remote_bda)) != NULL)
+ if ((p_lcb = l2cu_find_lcb_by_bd_addr (remote_bda, transport)) != NULL)
reason = p_lcb->disc_reason;
L2CAP_TRACE_DEBUG1 ("L2CA_GetDisconnectReason=%d ",reason);
@@ -333,12 +290,12 @@
l2cb.is_ble_connecting = FALSE;
/* See if we have a link control block for the remote device */
- p_lcb = l2cu_find_lcb_by_bd_addr (bda);
+ p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
/* If we don't have one, create one. this is auto connection complete. */
if (!p_lcb)
{
- p_lcb = l2cu_allocate_lcb (bda, FALSE);
+ p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE);
if (!p_lcb)
{
btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
@@ -368,7 +325,7 @@
/* Connected OK. Change state to connected, we were scanning so we are master */
p_lcb->link_state = LST_CONNECTED;
p_lcb->link_role = HCI_ROLE_MASTER;
- p_lcb->is_ble_link = TRUE;
+ p_lcb->transport = BT_TRANSPORT_LE;
/* If there are any preferred connection parameters, set them now */
if ( (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN ) &&
@@ -394,21 +351,16 @@
p_dev_rec->conn_params.slave_latency,
p_dev_rec->conn_params.supervision_tout,
0, 0);
- p_lcb->upd_status |= L2C_BLE_UPDATE_PENDING;
}
/* Tell BTM Acl management about the link */
- btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, TRUE);
-
- if (p_lcb->p_echo_rsp_cb)
- {
- L2CAP_TRACE_ERROR0 ("l2cu_send_peer_echo_req");
- l2cu_send_peer_echo_req (p_lcb, NULL, 0);
- }
+ btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE);
p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
l2cu_process_fixed_chnl_resp (p_lcb);
+
+ btm_ble_set_conn_st(BLE_CONN_IDLE);
}
@@ -433,12 +385,12 @@
UNUSED(conn_timeout);
/* See if we have a link control block for the remote device */
- p_lcb = l2cu_find_lcb_by_bd_addr (bda);
+ p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
/* If we don't have one, create one and accept the connection. */
if (!p_lcb)
{
- p_lcb = l2cu_allocate_lcb (bda, FALSE);
+ p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE);
if (!p_lcb)
{
btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
@@ -462,16 +414,22 @@
/* Connected OK. Change state to connected, we were advertising, so we are slave */
p_lcb->link_state = LST_CONNECTED;
p_lcb->link_role = HCI_ROLE_SLAVE;
- p_lcb->is_ble_link = TRUE;
+ p_lcb->transport = BT_TRANSPORT_LE;
/* Tell BTM Acl management about the link */
p_dev_rec = btm_find_or_alloc_dev (bda);
- btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, TRUE);
+ btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE);
p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
l2cu_process_fixed_chnl_resp (p_lcb);
+
+ /* when adv and initiating are both active, cancel the direct connection */
+ if (l2cb.is_ble_connecting && memcmp(bda, l2cb.ble_connecting_bda, BD_ADDR_LEN) == 0)
+ {
+ L2CA_CancelBleConnectReq(bda);
+ }
}
/*******************************************************************************
@@ -561,12 +519,22 @@
l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_OK, id);
- p_lcb->min_interval = min_interval;
- p_lcb->max_interval = max_interval;
- p_lcb->latency = latency;
- p_lcb->timeout = timeout;
- p_lcb->upd_status |= L2C_BLE_NEW_CONN_PARAM;
- L2CA_InternalBleConnUpdate(p_lcb);
+ p_lcb->min_interval = min_interval;
+ p_lcb->max_interval = max_interval;
+ p_lcb->latency = latency;
+ p_lcb->timeout = timeout;
+ p_lcb->conn_update_mask |= UPD_REQUEST;
+
+ if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED)
+ {
+ btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_interval, max_interval,
+ latency, timeout, 0, 0);
+ }
+ else
+ {
+ L2CAP_TRACE_EVENT0 ("L2CAP - LE - update currently disabled");
+ }
+
}
}
else
@@ -583,8 +551,47 @@
return;
}
}
+/*******************************************************************************
+**
+** Function l2c_enable_conn_param_timeout
+**
+** Description This function process the connection parameter enabling timeout
+**
+** Returns None.
+**
+*******************************************************************************/
+void l2c_enable_conn_param_timeout(tL2C_LCB * p_lcb)
+{
+ tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr);
+ /* application allows to do update, if we were delaying one do it now, otherwise
+ just mark lcb that updates are enabled */
+ if (p_lcb->conn_update_mask & UPD_REQUEST)
+ {
+ btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, p_lcb->min_interval, p_lcb->max_interval,
+ p_lcb->latency, p_lcb->timeout, 0, 0);
+ }
+ else
+ {
+ /* if preferred number has been set, set to preferred conn parameter */
+ if (p_dev_rec && p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF)
+ {
+ btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle,
+ (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_DEF),
+ (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_MAX_DEF),
+ (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ?
+ p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF),
+ (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ?
+ p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF),
+ 0, 0);
+ }
+ }
+ L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_ENABLED);
+
+}
/*******************************************************************************
**
** Function l2cble_init_direct_conn
@@ -606,7 +613,7 @@
/* There can be only one BLE connection request outstanding at a time */
if (p_dev_rec == NULL)
{
- BTM_TRACE_WARNING0 ("unknown device, can not initate connection");
+ L2CAP_TRACE_WARNING0 ("unknown device, can not initate connection");
return(FALSE);
}
@@ -616,14 +623,23 @@
init_addr_type = p_lcb->ble_addr_type;
memcpy(init_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
-#if BTM_BLE_PRIVACY_SPT == TRUE
+#if BLE_PRIVACY_SPT == TRUE
if (p_dev_rec->ble.active_addr_type == BTM_BLE_ADDR_RRA)
{
init_addr_type = BLE_ADDR_RANDOM;
memcpy(init_addr, p_dev_rec->ble.cur_rand_addr, BD_ADDR_LEN);
}
+ /* if privacy is on and current do not consider using reconnection address */
+ if (btm_cb.ble_ctr_cb.privacy ) /* && p_dev_rec->ble.use_reconn_addr */
+ own_addr_type = BLE_ADDR_RANDOM;
#endif
+ if (!btm_ble_topology_check(BTM_BLE_STATE_INIT))
+ {
+ l2cu_release_lcb (p_lcb);
+ L2CAP_TRACE_ERROR0("initate direct connection fail, topology limitation");
+ return FALSE;
+ }
if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int */
scan_win, /* UINT16 scan_win */
FALSE, /* UINT8 white_list */
@@ -712,4 +728,47 @@
l2cb.num_lm_ble_bufs = l2cb.controller_le_xmit_window = num_lm_ble_bufs;
}
+#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function l2cble_process_rc_param_request_evt
+**
+** Description process LE Remote Connection Parameter Request Event.
+**
+** Returns void
+**
+*******************************************************************************/
+void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 int_max,
+ UINT16 latency, UINT16 timeout)
+{
+ tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle (handle);
+
+ if (p_lcb != NULL)
+ {
+ p_lcb->min_interval = int_min;
+ p_lcb->max_interval = int_max;
+ p_lcb->latency = latency;
+ p_lcb->timeout = timeout;
+ p_lcb->conn_update_mask |= UPD_REQUEST;
+
+ /* TODO: revisit: if update is enabled, always accept connection parameter update */
+ if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED)
+ {
+ btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, timeout, 0, 0);
+ }
+ else
+ {
+ L2CAP_TRACE_EVENT0 ("L2CAP - LE - update currently disabled");
+ btsnd_hcic_ble_rc_param_req_neg_reply (handle,HCI_ERR_UNACCEPT_CONN_INTERVAL);
+ }
+
+ }
+ else
+ {
+ L2CAP_TRACE_WARNING0("No link to update connection parameter")
+ }
+}
+#endif
+
+
#endif /* (BLE_INCLUDED == TRUE) */
diff --git a/stack/l2cap/l2c_fcr.c b/stack/l2cap/l2c_fcr.c
index 9685f77..f2e72ad 100644
--- a/stack/l2cap/l2c_fcr.c
+++ b/stack/l2cap/l2c_fcr.c
@@ -2246,7 +2246,7 @@
p_ccb->out_cfg_fcr_present = TRUE;
}
- if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE)
+ if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE || p_cfg->fcr.mode == L2CAP_FCR_STREAM_MODE)
{
/* Always respond with FCR ERTM parameters */
p_ccb->out_cfg_fcr_present = TRUE;
diff --git a/stack/l2cap/l2c_int.h b/stack/l2cap/l2c_int.h
index 72d5544..272d318 100644
--- a/stack/l2cap/l2c_int.h
+++ b/stack/l2cap/l2c_int.h
@@ -52,6 +52,8 @@
#define L2CAP_WAIT_UNPARK_TOUT 2 /* 2 seconds */
#define L2CAP_LINK_INFO_RESP_TOUT 2 /* 2 seconds */
#define L2CAP_BLE_LINK_CONNECT_TOUT 30 /* 30 seconds */
+#define L2CAP_BLE_CONN_PARAM_UPD_TOUT 30 /* 30 seconds */
+#define L2CAP_BLE_ENB_CONN_PARAM_TOUT 1 /* 1 seconds */
/* quick timer uses millisecond unit */
#define L2CAP_DEFAULT_RETRANS_TOUT 2000 /* 2000 milliseconds */
@@ -393,6 +395,7 @@
UINT8 link_role; /* Master or slave */
UINT8 id;
+ UINT8 cur_echo_id; /* Current id value for echo request */
tL2CA_ECHO_RSP_CB *p_echo_rsp_cb; /* Echo response callback */
UINT16 idle_timeout; /* Idle timeout */
BOOLEAN is_bonding; /* True - link active only for bonding */
@@ -431,16 +434,17 @@
UINT16 disc_reason;
#endif
+ tBT_TRANSPORT transport;
#if (BLE_INCLUDED == TRUE)
- BOOLEAN is_ble_link;
tBLE_ADDR_TYPE ble_addr_type;
+ TIMER_LIST_ENT conn_param_enb; /* Timer entry for enabling connection parameter update */
-#define L2C_BLE_CONN_UPDATE_DISABLE 0x1 /* disable update connection parameters */
-#define L2C_BLE_NEW_CONN_PARAM 0x2 /* new connection parameter to be set */
-#define L2C_BLE_UPDATE_PENDING 0x4 /* waiting for connection update finished */
-#define L2C_BLE_NOT_DEFAULT_PARAM 0x8 /* not using default connection parameters */
- UINT8 upd_status;
-
+#define UPD_ENABLED 0 /* If peer requests update, we will change params */
+#define UPD_DISABLED 1 /* application requested not to update */
+#define UPD_ENB_TOUT 2 /* while updates are disabled, peer requested new parameters */
+#define UPD_ST_MASK 0x0f
+#define UPD_REQUEST 0x10 /* remote device set preferred conn param */
+ UINT8 conn_update_mask;
UINT16 min_interval; /* parameters as requested by peripheral */
UINT16 max_interval;
UINT16 latency;
@@ -578,14 +582,14 @@
/* Functions provided by l2c_utils.c
************************************
*/
-extern tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding);
+extern tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPORT transport);
extern BOOLEAN l2cu_start_post_bond_timer (UINT16 handle);
extern void l2cu_release_lcb (tL2C_LCB *p_lcb);
-extern tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr);
+extern tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport);
extern tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle);
extern void l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding);
-extern UINT8 l2cu_get_conn_role (BD_ADDR bd_addr);
+extern UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb);
extern BOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_after_rs);
extern void l2cu_enqueue_ccb (tL2C_CCB *p_ccb);
@@ -597,6 +601,7 @@
extern tL2C_CCB *l2cu_find_ccb_by_cid (tL2C_LCB *p_lcb, UINT16 local_cid);
extern tL2C_CCB *l2cu_find_ccb_by_remote_cid (tL2C_LCB *p_lcb, UINT16 remote_cid);
extern void l2cu_adj_id (tL2C_LCB *p_lcb, UINT8 adj_mask);
+extern BOOLEAN l2c_is_cmd_rejected (UINT8 cmd_code, UINT8 id, tL2C_LCB *p_lcb);
extern void l2cu_send_peer_cmd_reject (tL2C_LCB *p_lcb, UINT16 reason,
UINT8 rem_id,UINT16 p1, UINT16 p2);
@@ -676,7 +681,7 @@
extern tL2C_LCB *l2cu_find_lcb_by_state (tL2C_LINK_STATE state);
extern BOOLEAN l2cu_lcb_disconnecting (void);
-extern BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb);
+extern BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport);
extern BOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb);
extern BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb);
extern void l2cu_resubmit_pending_sec_req (BD_ADDR p_bda);
@@ -699,7 +704,7 @@
extern void l2c_link_processs_num_bufs (UINT16 num_lm_acl_bufs);
extern UINT8 l2c_link_pkts_rcvd (UINT16 *num_pkts, UINT16 *handles);
extern void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status);
-extern void l2c_link_sec_comp (BD_ADDR p_bda, void *p_ref_data, UINT8 status);
+extern void l2c_link_sec_comp (BD_ADDR p_bda, tBT_TRANSPORT trasnport, void *p_ref_data, UINT8 status);
extern void l2c_link_segments_xmitted (BT_HDR *p_msg);
extern void l2c_pin_code_request (BD_ADDR bd_addr);
extern void l2c_link_adjust_chnl_allocation (void);
@@ -762,8 +767,13 @@
extern void l2cble_conn_comp (UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type,
UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout);
extern BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb);
-
+extern void l2c_enable_conn_param_timeout(tL2C_LCB * p_lcb);
+#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
+extern void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 int_max,
+ UINT16 latency, UINT16 timeout);
#endif
+#endif
+extern void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb);
#ifdef __cplusplus
}
diff --git a/stack/l2cap/l2c_link.c b/stack/l2cap/l2c_link.c
index fd38ca2..f5e8294 100644
--- a/stack/l2cap/l2c_link.c
+++ b/stack/l2cap/l2c_link.c
@@ -65,12 +65,12 @@
BOOLEAN no_links;
/* See if we have a link control block for the remote device */
- p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr);
+ p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR);
/* If we don't have one, create one and accept the connection. */
if (!p_lcb)
{
- p_lcb = l2cu_allocate_lcb (bd_addr, FALSE);
+ p_lcb = l2cu_allocate_lcb (bd_addr, FALSE, BT_TRANSPORT_BR_EDR);
if (!p_lcb)
{
btsnd_hcic_reject_conn (bd_addr, HCI_ERR_HOST_REJECT_RESOURCES);
@@ -99,7 +99,7 @@
if (!btm_dev_support_switch (bd_addr))
p_lcb->link_role = HCI_ROLE_SLAVE;
else
- p_lcb->link_role = l2cu_get_conn_role(bd_addr);
+ p_lcb->link_role = l2cu_get_conn_role(p_lcb);
}
/* Tell the other side we accept the connection */
@@ -120,7 +120,7 @@
if (!btm_dev_support_switch (bd_addr))
p_lcb->link_role = HCI_ROLE_SLAVE;
else
- p_lcb->link_role = l2cu_get_conn_role(bd_addr);
+ p_lcb->link_role = l2cu_get_conn_role(p_lcb);
btsnd_hcic_accept_conn (bd_addr, p_lcb->link_role);
@@ -168,7 +168,7 @@
memcpy (ci.bd_addr, p_bda, BD_ADDR_LEN);
/* See if we have a link control block for the remote device */
- p_lcb = l2cu_find_lcb_by_bd_addr (ci.bd_addr);
+ p_lcb = l2cu_find_lcb_by_bd_addr (ci.bd_addr, BT_TRANSPORT_BR_EDR);
/* If we don't have one, this is an error */
if (!p_lcb)
@@ -202,9 +202,9 @@
if ((p_dev_info = btm_find_dev (p_bda)) != NULL)
btm_acl_created (ci.bd_addr, p_dev_info->dev_class,
p_dev_info->sec_bd_name, handle,
- p_lcb->link_role, FALSE);
+ p_lcb->link_role, BT_TRANSPORT_BR_EDR);
else
- btm_acl_created (ci.bd_addr, NULL, NULL, handle, p_lcb->link_role, FALSE);
+ btm_acl_created (ci.bd_addr, NULL, NULL, handle, p_lcb->link_role, BT_TRANSPORT_BR_EDR);
BTM_SetLinkSuperTout (ci.bd_addr, btm_cb.btm_def_link_super_tout);
@@ -272,7 +272,7 @@
}
else
{
- l2cu_create_conn(p_lcb);
+ l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR);
}
}
}
@@ -290,7 +290,7 @@
** Returns void
**
*******************************************************************************/
-void l2c_link_sec_comp (BD_ADDR p_bda, void *p_ref_data, UINT8 status)
+void l2c_link_sec_comp (BD_ADDR p_bda, tBT_TRANSPORT transport, void *p_ref_data, UINT8 status)
{
tL2C_CONN_INFO ci;
tL2C_LCB *p_lcb;
@@ -298,6 +298,8 @@
tL2C_CCB *p_next_ccb;
UINT8 event;
+ UNUSED(transport);
+
L2CAP_TRACE_DEBUG2 ("l2c_link_sec_comp: %d, 0x%x", status, p_ref_data);
if (status == BTM_SUCCESS_NO_SECURITY)
@@ -307,7 +309,7 @@
ci.status = status;
memcpy (ci.bd_addr, p_bda, BD_ADDR_LEN);
- p_lcb = l2cu_find_lcb_by_bd_addr (p_bda);
+ p_lcb = l2cu_find_lcb_by_bd_addr (p_bda, BT_TRANSPORT_BR_EDR);
/* If we don't have one, this is an error */
if (!p_lcb)
@@ -361,6 +363,7 @@
tL2C_CCB *p_ccb;
BOOLEAN status = TRUE;
BOOLEAN lcb_is_free = TRUE;
+ tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
/* See if we have a link control block for the connection */
p_lcb = l2cu_find_lcb_by_handle (handle);
@@ -401,35 +404,53 @@
p_ccb = pn;
}
-#if BTM_SCO_INCLUDED == TRUE
- /* Tell SCO management to drop any SCOs on this ACL */
- btm_sco_acl_removed (p_lcb->remote_bd_addr);
+#if (BTM_SCO_INCLUDED == TRUE)
+#if (BLE_INCLUDED == TRUE)
+ if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
+#endif
+ /* Tell SCO management to drop any SCOs on this ACL */
+ btm_sco_acl_removed (p_lcb->remote_bd_addr);
#endif
/* If waiting for disconnect and reconnect is pending start the reconnect now
race condition where layer above issued connect request on link that was
disconnecting
*/
- if (p_lcb->ccb_queue.p_first_ccb != NULL)
+ if (p_lcb->ccb_queue.p_first_ccb != NULL || p_lcb->p_pending_ccb)
{
#if (L2CAP_NUM_FIXED_CHNLS > 0)
/* If we are going to re-use the LCB without dropping it, release all fixed channels here */
int xx;
-
for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
{
- if (p_lcb->p_fixed_ccbs[xx])
+ if (p_lcb->p_fixed_ccbs[xx] && p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb)
{
- (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason);
+#if BLE_INCLUDED == TRUE
+ (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE,
+ p_lcb->disc_reason, p_lcb->transport);
+#else
+ (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE,
+ p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
+#endif
l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
p_lcb->p_fixed_ccbs[xx] = NULL;
}
+#if BLE_INCLUDED == TRUE
+ else if (p_lcb->p_fixed_ccbs[xx] && p_lcb->p_fixed_ccbs[xx] ==
+ p_lcb->p_pending_ccb)
+ {
+ if (p_lcb->p_fixed_ccbs[xx]->local_cid >= L2CAP_ATT_CID &&
+ p_lcb->p_fixed_ccbs[xx]->local_cid <= L2CAP_SMP_CID)
+ transport = BT_TRANSPORT_LE;
+ }
+#endif
+
}
#endif
L2CAP_TRACE_DEBUG0("l2c_link_hci_disc_comp: Restarting pending ACL request");
- if (l2cu_create_conn(p_lcb))
+ if (l2cu_create_conn(p_lcb, transport))
lcb_is_free = FALSE; /* still using this lcb */
}
@@ -444,7 +465,7 @@
if (lcb_is_free && ((p_lcb = l2cu_find_lcb_by_state(LST_CONNECT_HOLDING)) != NULL))
{
/* we found one-- create a connection */
- l2cu_create_conn(p_lcb);
+ l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR);
}
return status;
@@ -576,6 +597,7 @@
}
else if (rc == BTM_SUCCESS)
{
+ l2cu_process_fixed_disc_cback(p_lcb);
/* BTM SEC will make sure that link is release (probably after pairing is done) */
p_lcb->link_state = LST_DISCONNECTING;
timeout = 0xFFFF;
@@ -588,6 +610,7 @@
else if ((p_lcb->is_bonding)
&& (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER)))
{
+ l2cu_process_fixed_disc_cback(p_lcb);
p_lcb->link_state = LST_DISCONNECTING;
timeout = L2CAP_LINK_DISCONNECT_TOUT;
}
@@ -977,7 +1000,7 @@
if (bd_addr)
{
/* If here came form hci role change event */
- p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr);
+ p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR);
if (p_lcb)
{
p_lcb->link_role = new_role;
@@ -1013,7 +1036,7 @@
*******************************************************************************/
void l2c_pin_code_request (BD_ADDR bd_addr)
{
- tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr);
+ tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR);
if ( (p_lcb) && (!p_lcb->ccb_queue.p_first_ccb) )
{
@@ -1129,11 +1152,11 @@
/* If controller window is full, nothing to do */
if ( (l2cb.controller_xmit_window == 0
#if (BLE_INCLUDED == TRUE)
- && !p_lcb->is_ble_link
+ && (p_lcb->transport == BT_TRANSPORT_BR_EDR)
#endif
)
#if (BLE_INCLUDED == TRUE)
- || (p_lcb->is_ble_link && l2cb.controller_le_xmit_window == 0 )
+ || (p_lcb->transport == BT_TRANSPORT_LE && l2cb.controller_le_xmit_window == 0 )
#endif
|| (l2cb.round_robin_unacked >= l2cb.round_robin_quota) )
break;
@@ -1168,8 +1191,8 @@
/* If we finished without using up our quota, no need for a safety check */
#if (BLE_INCLUDED == TRUE)
- if ( ((l2cb.controller_xmit_window > 0 && !p_lcb->is_ble_link) ||
- (l2cb.controller_le_xmit_window > 0 && p_lcb->is_ble_link))
+ if ( ((l2cb.controller_xmit_window > 0 && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
+ (l2cb.controller_le_xmit_window > 0 && (p_lcb->transport == BT_TRANSPORT_LE)))
&& (l2cb.round_robin_unacked < l2cb.round_robin_quota) )
#else
if ( (l2cb.controller_xmit_window > 0)
@@ -1188,8 +1211,8 @@
/* See if we can send anything from the link queue */
#if (BLE_INCLUDED == TRUE)
- while ( ((l2cb.controller_xmit_window != 0 && !p_lcb->is_ble_link) ||
- (l2cb.controller_le_xmit_window != 0 && p_lcb->is_ble_link))
+ while ( ((l2cb.controller_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
+ (l2cb.controller_le_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_LE)))
&& (p_lcb->sent_not_acked < p_lcb->link_xmit_quota))
#else
while ( (l2cb.controller_xmit_window != 0)
@@ -1207,8 +1230,8 @@
{
/* See if we can send anything for any channel */
#if (BLE_INCLUDED == TRUE)
- while ( ((l2cb.controller_xmit_window != 0 && !p_lcb->is_ble_link) ||
- (l2cb.controller_le_xmit_window != 0 && p_lcb->is_ble_link))
+ while ( ((l2cb.controller_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
+ (l2cb.controller_le_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_LE)))
&& (p_lcb->sent_not_acked < p_lcb->link_xmit_quota))
#else
while ((l2cb.controller_xmit_window != 0) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota))
@@ -1245,12 +1268,14 @@
UINT16 num_segs;
UINT16 xmit_window, acl_data_size;
+ if ((p_buf->len <= btu_cb.hcit_acl_pkt_size
#if (BLE_INCLUDED == TRUE)
- if ((!p_lcb->is_ble_link && (p_buf->len <= btu_cb.hcit_acl_pkt_size)) ||
- (p_lcb->is_ble_link && (p_buf->len <= btu_cb.hcit_ble_acl_pkt_size)))
+ && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
+ ((p_lcb->transport == BT_TRANSPORT_LE) && (p_buf->len <= btu_cb.hcit_ble_acl_pkt_size))
#else
- if (p_buf->len <= btu_cb.hcit_acl_pkt_size)
+ )
#endif
+ )
{
if (p_lcb->link_xmit_quota == 0)
l2cb.round_robin_unacked++;
@@ -1259,7 +1284,7 @@
p_buf->layer_specific = 0;
#if (BLE_INCLUDED == TRUE)
- if (p_lcb->is_ble_link)
+ if (p_lcb->transport == BT_TRANSPORT_LE)
{
l2cb.controller_le_xmit_window--;
L2C_LINK_SEND_BLE_ACL_DATA (p_buf);
@@ -1274,7 +1299,7 @@
else
{
#if BLE_INCLUDED == TRUE
- if (p_lcb->is_ble_link)
+ if (p_lcb->transport == BT_TRANSPORT_LE)
{
acl_data_size = btu_cb.hcit_ble_acl_data_size;
xmit_window = l2cb.controller_le_xmit_window;
@@ -1313,7 +1338,7 @@
p_buf->layer_specific = num_segs;
#if BLE_INCLUDED == TRUE
- if (p_lcb->is_ble_link)
+ if (p_lcb->transport == BT_TRANSPORT_LE)
{
l2cb.controller_le_xmit_window -= num_segs;
@@ -1327,7 +1352,7 @@
p_lcb->sent_not_acked += num_segs;
#if BLE_INCLUDED == TRUE
- if (p_lcb->is_ble_link)
+ if (p_lcb->transport == BT_TRANSPORT_LE)
{
L2C_LINK_SEND_BLE_ACL_DATA(p_buf);
}
@@ -1340,7 +1365,7 @@
#if (L2CAP_HCI_FLOW_CONTROL_DEBUG == TRUE)
#if (BLE_INCLUDED == TRUE)
- if (p_lcb->is_ble_link)
+ if (p_lcb->transport == BT_TRANSPORT_LE)
{
L2CAP_TRACE_DEBUG6 ("TotalWin=%d,Hndl=0x%x,Quota=%d,Unack=%d,RRQuota=%d,RRUnack=%d",
l2cb.controller_le_xmit_window,
@@ -1400,11 +1425,9 @@
if (p_lcb)
{
#if (BLE_INCLUDED == TRUE)
- if (p_lcb->is_ble_link)
- {
- l2cb.controller_le_xmit_window += num_sent;
- }
- else
+ if (p_lcb && (p_lcb->transport == BT_TRANSPORT_LE))
+ l2cb.controller_le_xmit_window += num_sent;
+ else
#endif
{
/* Maintain the total window to the controller */
@@ -1441,7 +1464,7 @@
if (p_lcb)
{
#if (BLE_INCLUDED == TRUE)
- if (p_lcb->is_ble_link)
+ if (p_lcb->transport == BT_TRANSPORT_LE)
{
L2CAP_TRACE_DEBUG5 ("TotalWin=%d,LinkUnack(0x%x)=%d,RRCheck=%d,RRUnack=%d",
l2cb.controller_le_xmit_window,
diff --git a/stack/l2cap/l2c_main.c b/stack/l2cap/l2c_main.c
index 49dd811..2795d8c 100644
--- a/stack/l2cap/l2c_main.c
+++ b/stack/l2cap/l2c_main.c
@@ -320,17 +320,29 @@
tL2CAP_CFG_INFO cfg_info;
UINT16 rej_reason, rej_mtu, lcid, rcid, info_type;
tL2C_CCB *p_ccb;
- tL2C_RCB *p_rcb;
- BOOLEAN cfg_rej;
+ tL2C_RCB *p_rcb, *p_rcb2;
+ BOOLEAN cfg_rej, pkt_size_rej = FALSE;
UINT16 cfg_rej_len, cmd_len;
UINT16 result;
tL2C_CONN_INFO ci;
#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
/* if l2cap command received in CID 1 on top of an LE link, ignore this command */
- if (p_lcb->is_ble_link)
+ if (p_lcb->transport == BT_TRANSPORT_LE)
return;
#endif
+
+ /* Reject the packet if it exceeds the default Signalling Channel MTU */
+ if (pkt_len > L2CAP_DEFAULT_MTU)
+ {
+ /* Core Spec requires a single response to the first command found in a multi-command
+ ** L2cap packet. If only responses in the packet, then it will be ignored.
+ ** Here we simply mark the bad packet and decide which cmd ID to reject later
+ */
+ pkt_size_rej = TRUE;
+ L2CAP_TRACE_ERROR1 ("L2CAP SIG MTU Pkt Len Exceeded (672) -> pkt_len: %d", pkt_len);
+ }
+
p_next_cmd = p;
p_pkt_end = p + pkt_len;
@@ -355,6 +367,18 @@
break;
}
+ L2CAP_TRACE_DEBUG3 ("cmd_code: %d, id:%d, cmd_len:%d", cmd_code, id, cmd_len);
+
+ /* Bad L2CAP packet length, look or cmd to reject */
+ if (pkt_size_rej)
+ {
+ /* If command found rejected it and we're done, otherwise keep looking */
+ if (l2c_is_cmd_rejected(cmd_code, id, p_lcb))
+ return;
+ else
+ continue; /* Look for next cmd/response in current packet */
+ }
+
switch (cmd_code)
{
case L2CAP_CMD_REJECT:
@@ -911,6 +935,11 @@
l2c_info_timeout((tL2C_LCB *)p_tle->param);
break;
+#if (BLE_INCLUDED == TRUE)
+ case BTU_TTYPE_L2CAP_END_CONN_UPD:
+ l2c_enable_conn_param_timeout((tL2C_LCB *)p_tle->param);
+ break;
+#endif
}
}
diff --git a/stack/l2cap/l2c_ucd.c b/stack/l2cap/l2c_ucd.c
index 4dfc804..4f907ad 100644
--- a/stack/l2cap/l2c_ucd.c
+++ b/stack/l2cap/l2c_ucd.c
@@ -343,7 +343,7 @@
/* First, see if we already have a link to the remote */
/* then find the channel control block for UCD. */
- if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL)
+ if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL))
{
if ( l2c_ucd_connect (rem_bda) == FALSE )
@@ -411,7 +411,7 @@
/* First, see if we already have a link to the remote */
/* then find the channel control block for UCD */
- if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL)
+ if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL))
{
if ( l2c_ucd_connect (rem_bda) == FALSE )
@@ -421,7 +421,7 @@
}
/* If we still don't have lcb and ccb after connect attempt, then can't proceed */
- if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL)
+ if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
|| ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL))
{
GKI_freebuf (p_buf);
@@ -490,7 +490,7 @@
/* First, see if we already have a link to the remote */
/* then find the channel control block. */
- if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL)
+ if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL))
{
L2CAP_TRACE_WARNING0 ("L2CAP - no UCD channel");
@@ -521,7 +521,7 @@
(rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
(rem_bda[4]<<8)+rem_bda[5]);
- if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL)
+ if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
{
L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_UCDSetTxPriority");
return (FALSE);
@@ -569,11 +569,11 @@
}
/* First, see if we already have a link to the remote */
- if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL)
+ if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
{
/* No link. Get an LCB and start link establishment */
- if ( ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE)) == NULL)
- || (l2cu_create_conn(p_lcb) == FALSE) )
+ if ( ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE, BT_TRANSPORT_BR_EDR)) == NULL)
+ || (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE) )
{
L2CAP_TRACE_WARNING0 ("L2CAP - conn not started l2c_ucd_connect");
return (FALSE);
diff --git a/stack/l2cap/l2c_utils.c b/stack/l2cap/l2c_utils.c
index 05d5e5d..23b7584 100644
--- a/stack/l2cap/l2c_utils.c
+++ b/stack/l2cap/l2c_utils.c
@@ -37,6 +37,7 @@
#include "btm_int.h"
#include "hcidefs.h"
#include "bd.h"
+#include "bt_utils.h"
/*******************************************************************************
**
@@ -47,7 +48,7 @@
** Returns LCB address or NULL if none found
**
*******************************************************************************/
-tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding)
+tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPORT transport)
{
int xx;
tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
@@ -69,7 +70,9 @@
p_lcb->idle_timeout = l2cb.idle_timeout;
p_lcb->id = 1; /* spec does not allow '0' */
p_lcb->is_bonding = is_bonding;
-
+#if BLE_INCLUDED == TRUE
+ p_lcb->transport = transport;
+#endif
l2cb.num_links_active++;
l2c_link_adjust_allocation();
@@ -93,7 +96,7 @@
*******************************************************************************/
void l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding)
{
- tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr);
+ tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR);
if (p_lcb)
{
@@ -133,14 +136,17 @@
}
#if BTM_SCO_INCLUDED == TRUE
- /* Release all SCO links */
- btm_remove_sco_links(p_lcb->remote_bd_addr);
+#if (BLE_INCLUDED == TRUE)
+ if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
+#endif
+ /* Release all SCO links */
+ btm_remove_sco_links(p_lcb->remote_bd_addr);
#endif
if (p_lcb->sent_not_acked > 0)
{
#if (BLE_INCLUDED == TRUE)
- if (p_lcb->is_ble_link)
+ if (p_lcb->transport == BT_TRANSPORT_LE)
{
l2cb.controller_le_xmit_window += p_lcb->sent_not_acked;
if (l2cb.controller_le_xmit_window > l2cb.num_lm_ble_bufs)
@@ -160,7 +166,6 @@
}
#if (BLE_INCLUDED == TRUE)
- p_lcb->is_ble_link = FALSE;
l2cb.is_ble_connecting = FALSE;
#endif
@@ -174,11 +179,11 @@
{
l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
p_lcb->p_fixed_ccbs[xx] = NULL;
- (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason);
+ (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
}
else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
&& (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) )
- (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason);
+ (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
}
}
#endif
@@ -191,8 +196,11 @@
/* Tell BTM Acl management the link was removed */
if ((p_lcb->link_state == LST_CONNECTED) || (p_lcb->link_state == LST_DISCONNECTING))
- btm_acl_removed (p_lcb->remote_bd_addr);
-
+#if (BLE_INCLUDED == TRUE)
+ btm_acl_removed (p_lcb->remote_bd_addr, p_lcb->transport);
+#else
+ btm_acl_removed (p_lcb->remote_bd_addr, BT_TRANSPORT_BR_EDR);
+#endif
/* Release any held buffers */
while (p_lcb->link_xmit_data_q.p_first)
GKI_freebuf (GKI_dequeue (&p_lcb->link_xmit_data_q));
@@ -231,14 +239,18 @@
** Returns pointer to matched LCB, or NULL if no match
**
*******************************************************************************/
-tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr)
+tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport)
{
int xx;
tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
{
- if ((p_lcb->in_use) && (!memcmp (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN)))
+ if ((p_lcb->in_use) &&
+#if BLE_INCLUDED == TRUE
+ p_lcb->transport == transport &&
+#endif
+ (!memcmp (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN)))
{
return (p_lcb);
}
@@ -253,8 +265,6 @@
** Function l2cu_get_conn_role
**
** Description Determine the desired role (master or slave) of a link.
-** If it is the previous connected remote device, use the same
-** role as previous used role.
** If already got a slave link, this one must be a master. If
** already got at least 1 link where we are the master, make this
** also a master.
@@ -262,12 +272,12 @@
** Returns HCI_ROLE_MASTER or HCI_ROLE_SLAVE
**
*******************************************************************************/
-UINT8 l2cu_get_conn_role (BD_ADDR bd_addr)
+UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb)
{
UINT8 i;
for (i = 0; i < BTM_ROLE_DEVICE_NUM; i++) {
if ((btm_cb.previous_connected_role[i] != BTM_ROLE_UNDEFINED) &&
- (!bdcmp(bd_addr, btm_cb.previous_connected_remote_addr[i]))) {
+ (!bdcmp(p_this_lcb->remote_bd_addr, btm_cb.previous_connected_remote_addr[i]))) {
L2CAP_TRACE_WARNING1 ("l2cu_get_conn_role %d",
btm_cb.previous_connected_role[i]);
return btm_cb.previous_connected_role[i];
@@ -278,6 +288,39 @@
/*******************************************************************************
**
+** Function l2c_is_cmd_rejected
+**
+** Description Checks if cmd_code is command or response
+** If a command it will be rejected per spec.
+** This function is used when a illegal packet length is detected
+**
+** Returns BOOLEAN - TRUE if cmd_code is a command and it is rejected,
+** FALSE if response code. (command not rejected)
+**
+*******************************************************************************/
+BOOLEAN l2c_is_cmd_rejected (UINT8 cmd_code, UINT8 id, tL2C_LCB *p_lcb)
+{
+ switch(cmd_code)
+ {
+ case L2CAP_CMD_CONN_REQ:
+ case L2CAP_CMD_CONFIG_REQ:
+ case L2CAP_CMD_DISC_REQ:
+ case L2CAP_CMD_ECHO_REQ:
+ case L2CAP_CMD_INFO_REQ:
+ case L2CAP_CMD_AMP_CONN_REQ:
+ case L2CAP_CMD_AMP_MOVE_REQ:
+ case L2CAP_CMD_BLE_UPDATE_REQ:
+ l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_MTU_EXCEEDED, id, L2CAP_DEFAULT_MTU, 0);
+ L2CAP_TRACE_WARNING1 ("Dumping first Command (%d)", cmd_code);
+ return TRUE;
+
+ default: /* Otherwise a response */
+ return FALSE;
+ }
+}
+
+/*******************************************************************************
+**
** Function l2cu_build_header
**
** Description Builds the L2CAP command packet header
@@ -311,7 +354,7 @@
UINT16_TO_STREAM (p, len + L2CAP_CMD_OVERHEAD);
#if (BLE_INCLUDED == TRUE)
- if (p_lcb->is_ble_link)
+ if (p_lcb->transport == BT_TRANSPORT_LE)
{
UINT16_TO_STREAM (p, L2CAP_BLE_SIGNALLING_CID);
}
@@ -717,11 +760,24 @@
*******************************************************************************/
void l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len, UINT16 rej_len)
{
- BT_HDR *p_buf = (BT_HDR *)GKI_getpoolbuf (L2CAP_CMD_POOL_ID);
- UINT16 len, cfg_len;
+ BT_HDR *p_buf;
+ UINT16 len, cfg_len, buf_space, len1;
UINT8 *p, *p_hci_len, *p_data_end;
UINT8 cfg_code;
+ L2CAP_TRACE_DEBUG2("l2cu_send_peer_config_rej: data_len=%d, rej_len=%d", data_len, rej_len);
+
+
+ len = BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN;
+ len1 = 0xFFFF - len;
+ if (rej_len > len1)
+ {
+ L2CAP_TRACE_ERROR0 ("L2CAP - cfg_rej pkt size exceeds buffer design max limit.");
+ return;
+ }
+
+ p_buf = (BT_HDR *)GKI_getbuf (len + rej_len);
+
if (!p_buf)
{
L2CAP_TRACE_ERROR0 ("L2CAP - no buffer for cfg_rej");
@@ -761,6 +817,8 @@
UINT16_TO_STREAM (p, 0); /* Flags = 0 (no continuation) */
UINT16_TO_STREAM (p, L2CAP_CFG_UNKNOWN_OPTIONS);
+ buf_space = rej_len;
+
/* Now, put the rejected options */
p_data_end = p_data + data_len;
while (p_data < p_data_end)
@@ -784,8 +842,18 @@
{
if ((cfg_code & 0x80) == 0)
{
- memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
- p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
+ if (buf_space >= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD))
+ {
+ memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
+ p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
+ buf_space -= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
+ }
+ else
+ {
+ L2CAP_TRACE_WARNING0("L2CAP - cfg_rej exceeds allocated buffer");
+ p_data = p_data_end; /* force loop exit */
+ break;
+ }
}
p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
}
@@ -803,6 +871,9 @@
p_buf->len = len + 4;
+ L2CAP_TRACE_DEBUG2 ("L2CAP - cfg_rej pkt hci_len=%d, l2cap_len=%d",
+ len, (L2CAP_CMD_OVERHEAD+L2CAP_CONFIG_RSP_LEN+rej_len));
+
l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
}
@@ -941,6 +1012,21 @@
BT_HDR *p_buf;
UINT8 *p;
UINT16 maxlen;
+ /* Filter out duplicate IDs or if available buffers are low (intruder checking) */
+ if (!id || id == p_lcb->cur_echo_id)
+ {
+ /* Dump this request since it is illegal */
+ L2CAP_TRACE_WARNING1 ("L2CAP ignoring duplicate echo request (%d)", id);
+ return;
+ }
+ else
+ p_lcb->cur_echo_id = id;
+ /* Don't respond if we more than 10% of our buffers are used */
+ if (GKI_poolutilization (L2CAP_CMD_POOL_ID) > 10)
+ {
+ L2CAP_TRACE_WARNING0 ("L2CAP gki pool used up to more than 10%%, ignore echo response");
+ return;
+ }
/* Don't return data if it does not fit in ACL and L2CAP MTU */
maxlen = (GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID) > btu_cb.hcit_acl_pkt_size) ?
@@ -1069,7 +1155,7 @@
{
UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
#if (BLE_INCLUDED == TRUE)
- if (p_lcb->is_ble_link)
+ if (p_lcb->transport == BT_TRANSPORT_LE)
{
/* optional data are not added for now */
UINT32_TO_STREAM (p, L2CAP_BLE_EXTFEA_MASK);
@@ -2104,7 +2190,7 @@
** Returns TRUE if successful, FALSE if gki get buffer fails.
**
*******************************************************************************/
-BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb)
+BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport)
{
int xx;
tL2C_LCB *p_lcb_cur = &l2cb.lcb_pool[0];
@@ -2116,15 +2202,16 @@
tBT_DEVICE_TYPE dev_type;
tBLE_ADDR_TYPE addr_type;
+
BTM_ReadDevInfo(p_lcb->remote_bd_addr, &dev_type, &addr_type);
- if (dev_type == BT_DEVICE_TYPE_BLE)
+ if (transport == BT_TRANSPORT_LE)
{
if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
return FALSE;
p_lcb->ble_addr_type = addr_type;
- p_lcb->is_ble_link = TRUE;
+ p_lcb->transport = BT_TRANSPORT_LE;
return (l2cble_create_conn(p_lcb));
}
@@ -2154,7 +2241,7 @@
if (is_sco_active == TRUE)
continue; /* No Master Slave switch not allowed when SCO Active */
#endif
-
+ /*4_1_TODO check if btm_cb.devcb.local_features to be used instead */
if (HCI_SWITCH_SUPPORTED(BTM_ReadLocalFeatures()))
{
/* mark this lcb waiting for switch to be completed and
@@ -2394,7 +2481,7 @@
APPL_TRACE_EVENT1("SET ACL PRIORITY %d", priority);
/* Find the link control block for the acl channel */
- if ((p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr)) == NULL)
+ if ((p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
{
L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_SetAclPriority");
return (FALSE);
@@ -2468,7 +2555,7 @@
/* If we are called with a BDA, only resubmit for that BDA */
if (p_bda)
{
- p_lcb = l2cu_find_lcb_by_bd_addr (p_bda);
+ p_lcb = l2cu_find_lcb_by_bd_addr (p_bda, BT_TRANSPORT_BR_EDR);
/* If we don't have one, this is an error */
if (p_lcb)
@@ -2663,11 +2750,13 @@
rc = btm_sec_disconnect (p_lcb->handle, HCI_ERR_PEER_USER);
if (rc == BTM_CMD_STARTED)
{
+ l2cu_process_fixed_disc_cback(p_lcb);
p_lcb->link_state = LST_DISCONNECTING;
timeout = L2CAP_LINK_DISCONNECT_TOUT;
}
else if (rc == BTM_SUCCESS)
{
+ l2cu_process_fixed_disc_cback(p_lcb);
/* BTM SEC will make sure that link is release (probably after pairing is done) */
p_lcb->link_state = LST_DISCONNECTING;
timeout = 0xFFFF;
@@ -2675,6 +2764,7 @@
else if ( (p_lcb->is_bonding)
&& (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER)) )
{
+ l2cu_process_fixed_disc_cback(p_lcb);
p_lcb->link_state = LST_DISCONNECTING;
timeout = L2CAP_LINK_DISCONNECT_TOUT;
}
@@ -2709,27 +2799,43 @@
void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb)
{
int xx;
-#if BLE_INCLUDED == TRUE
- UINT16 reason = (p_lcb->is_ble_link ) ? 1 : 0;
-#else
- UINT16 reason =0;
+#if (BLE_INCLUDED == TRUE)
+ /* always exclude LE fixed channel on BR/EDR fix channel capability */
+ if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
+ p_lcb->peer_chnl_mask[0] &= ~(L2CAP_FIXED_CHNL_ATT_BIT| \
+ L2CAP_FIXED_CHNL_BLE_SIG_BIT| \
+ L2CAP_FIXED_CHNL_SMP_BIT);
#endif
/* Tell all registered fixed channels about the connection */
for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
{
+#if BLE_INCLUDED == TRUE
+ /* skip sending LE fix channel callbacks on BR/EDR links */
+ if (p_lcb->transport == BT_TRANSPORT_BR_EDR &&
+ xx + L2CAP_FIRST_FIXED_CHNL >= L2CAP_ATT_CID &&
+ xx + L2CAP_FIRST_FIXED_CHNL <= L2CAP_SMP_CID)
+ continue;
+#endif
if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL)
{
if (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
{
if (p_lcb->p_fixed_ccbs[xx])
p_lcb->p_fixed_ccbs[xx]->chnl_state = CST_OPEN;
-
- (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, reason);
+#if BLE_INCLUDED == TRUE
+ (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, 0, p_lcb->transport);
+#else
+ (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, 0, BT_TRANSPORT_BR_EDR);
+#endif
}
else
{
- (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason);
+#if BLE_INCLUDED == TRUE
+ (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
+#else
+ (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
+#endif
if (p_lcb->p_fixed_ccbs[xx])
{
@@ -2742,6 +2848,45 @@
}
#endif
+
+/*******************************************************************************
+**
+** Function l2cu_process_fixed_disc_cback
+**
+** Description send l2cap fixed channel disconnection callback to application
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb)
+{
+#if (L2CAP_NUM_FIXED_CHNLS > 0)
+ int xx;
+
+ for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
+ {
+ if (p_lcb->p_fixed_ccbs[xx])
+ {
+ l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
+ p_lcb->p_fixed_ccbs[xx] = NULL;
+#if BLE_INCLUDED == TRUE
+ (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
+#else
+ (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
+#endif
+ }
+ else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
+ && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) )
+#if BLE_INCLUDED == TRUE
+ (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
+#else
+ (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
+#endif
+ }
+#endif
+}
+
#if (BLE_INCLUDED == TRUE)
/*******************************************************************************
**
@@ -3193,7 +3338,7 @@
UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
#endif
#if (BLE_INCLUDED == TRUE)
- if (p_ccb->p_lcb->is_ble_link)
+ if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)
{
/* The HCI transport will segment the buffers. */
if (p_buf->len > btu_cb.hcit_ble_acl_data_size)
diff --git a/stack/mcap/mca_l2c.c b/stack/mcap/mca_l2c.c
index bc6fe09..d792bfc 100644
--- a/stack/mcap/mca_l2c.c
+++ b/stack/mcap/mca_l2c.c
@@ -70,12 +70,14 @@
** Returns void
**
*******************************************************************************/
-static void mca_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+static void mca_sec_check_complete_term (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
{
tMCA_TC_TBL *p_tbl = (tMCA_TC_TBL *)p_ref_data;
tL2CAP_CFG_INFO cfg;
tL2CAP_ERTM_INFO ertm_info;
+ UNUSED(transport);
+
MCA_TRACE_DEBUG1("mca_sec_check_complete_term res: %d", res);
if ( res == BTM_SUCCESS )
@@ -115,11 +117,12 @@
** Returns void
**
*******************************************************************************/
-static void mca_sec_check_complete_orig (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+static void mca_sec_check_complete_orig (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
{
tMCA_TC_TBL *p_tbl = (tMCA_TC_TBL *)p_ref_data;
tL2CAP_CFG_INFO cfg;
UNUSED(bd_addr);
+ UNUSED(transport);
MCA_TRACE_DEBUG1("mca_sec_check_complete_orig res: %d", res);
diff --git a/stack/rfcomm/rfc_int.h b/stack/rfcomm/rfc_int.h
index 83a63e3..302a8af 100644
--- a/stack/rfcomm/rfc_int.h
+++ b/stack/rfcomm/rfc_int.h
@@ -315,7 +315,7 @@
extern void rfc_save_lcid_mcb (tRFC_MCB *p_rfc_mcb, UINT16 lcid);
extern void rfc_check_mcb_active (tRFC_MCB *p_mcb);
extern void rfc_port_closed (tPORT *p_port);
-extern void rfc_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 res);
+extern void rfc_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT transport,void *p_ref_data, UINT8 res);
extern void rfc_inc_credit (tPORT *p_port, UINT8 credit);
extern void rfc_dec_credit (tPORT *p_port);
extern void rfc_check_send_cmd(tRFC_MCB *p_mcb, BT_HDR *p_buf);
diff --git a/stack/rfcomm/rfc_utils.c b/stack/rfcomm/rfc_utils.c
index d2b02fc..47b093f 100644
--- a/stack/rfcomm/rfc_utils.c
+++ b/stack/rfcomm/rfc_utils.c
@@ -350,10 +350,11 @@
** Returns void
**
*******************************************************************************/
-void rfc_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+void rfc_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
{
tPORT *p_port = (tPORT *)p_ref_data;
UNUSED(bd_addr);
+ UNUSED(transport);
/* Verify that PORT is still waiting for Security to complete */
if (!p_port->in_use
diff --git a/stack/smp/aes.c b/stack/smp/aes.c
index 65cddf5..d3d8ff6 100644
--- a/stack/smp/aes.c
+++ b/stack/smp/aes.c
@@ -510,6 +510,7 @@
keylen = 24;
break;
case 32:
+ /* case 256: length in bits (256 = 8*32) */
keylen = 32;
break;
default:
diff --git a/stack/smp/smp_act.c b/stack/smp/smp_act.c
index 47cd2c9..7543eb7 100644
--- a/stack/smp/smp_act.c
+++ b/stack/smp/smp_act.c
@@ -26,6 +26,7 @@
#include "l2c_api.h"
#include "smp_int.h"
+#define MAX_KEY_DISTRIBUTION_TYPES 3
const UINT8 smp_association_table[2][SMP_IO_CAP_MAX][SMP_IO_CAP_MAX] =
{
@@ -108,6 +109,7 @@
{
p_cb->loc_auth_req = cb_data.io_req.auth_req;
p_cb->loc_io_caps = cb_data.io_req.io_cap;
+
#if (defined(BLE_PERIPHERAL_DISPLAYONLY) && (BLE_PERIPHERAL_DISPLAYONLY == TRUE))
if (p_cb->role == HCI_ROLE_SLAVE)
{
@@ -165,7 +167,11 @@
some peripherals are not able to revert to fast connection parameters
during the start of service discovery. Connection paramter updates
get enabled again once service discovery completes. */
- L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE);
+ if (L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE) == FALSE)
+ {
+ SMP_TRACE_ERROR0 ("smp pair failed...!");
+ return;
+ }
#endif
/* erase all keys when master sends pairing req*/
@@ -616,7 +622,7 @@
*******************************************************************************/
void smp_start_enc(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
{
- BOOLEAN cmd;
+ tBTM_STATUS cmd;
UINT8 reason = SMP_ENC_FAIL;
SMP_TRACE_DEBUG0 ("smp_start_enc ");
@@ -625,7 +631,7 @@
else
cmd = btm_ble_start_encrypt(p_cb->pairing_bda, FALSE, NULL);
- if (!cmd)
+ if (cmd != BTM_CMD_STARTED && cmd != BTM_BUSY)
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
}
@@ -729,7 +735,7 @@
UINT8 i = 0;
SMP_TRACE_DEBUG1 ("smp_key_pick_key key_to_dist=0x%x", key_to_dist);
- while (i < 3)
+ while (i < MAX_KEY_DISTRIBUTION_TYPES)
{
SMP_TRACE_DEBUG2("key to send = %02x, i = %d", key_to_dist, i);
@@ -899,6 +905,7 @@
SMP_TRACE_DEBUG0 ("smp_pairing_cmpl ");
+ (void)L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, TRUE);
if ((p_cb->status == SMP_SUCCESS) ||
(p_cb->status <= SMP_REPEATED_ATTEMPTS && p_cb->status != SMP_SUCCESS))
{
@@ -960,6 +967,18 @@
smp_proc_pairing_cmpl(p_cb);
}
}
+
+/*******************************************************************************
+** Function smp_fast_conn_param
+** Description apply default connection parameter for pairing process
+*******************************************************************************/
+void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
+{
+ /* disable connection parameter update */
+ (void)L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE);
+}
+
+
/*******************************************************************************
**
** Function smp_link_encrypted
diff --git a/stack/smp/smp_int.h b/stack/smp/smp_int.h
index 51cdbb3..70c09a5 100644
--- a/stack/smp/smp_int.h
+++ b/stack/smp/smp_int.h
@@ -202,6 +202,8 @@
BD_ADDR local_bda;
BOOLEAN is_pair_cancel;
BOOLEAN discard_sec_req;
+ UINT8 rcvd_cmd_code;
+ UINT8 rcvd_cmd_len;
#if SMP_CONFORMANCE_TESTING == TRUE
BOOLEAN enable_test_confirm_val;
BT_OCTET16 test_confirm;
@@ -288,6 +290,8 @@
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);
+extern void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
+
/* smp_l2c */
extern void smp_l2cap_if_init (void);
@@ -314,6 +318,7 @@
/* smp main util */
extern void smp_set_state(tSMP_STATE state);
extern tSMP_STATE smp_get_state(void);
+extern void smp_reject_unexp_pair_req(BD_ADDR bd_addr);
#endif /* SMP_INT_H */
diff --git a/stack/smp/smp_l2c.c b/stack/smp/smp_l2c.c
index 54b78b4..02ec38e 100644
--- a/stack/smp/smp_l2c.c
+++ b/stack/smp/smp_l2c.c
@@ -34,7 +34,7 @@
-static void smp_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason);
+static void smp_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason, tBT_TRANSPORT transport);
static void smp_data_ind (BD_ADDR bd_addr, BT_HDR *p_buf);
/*******************************************************************************
@@ -73,13 +73,20 @@
** connected (conn = TRUE)/disconnected (conn = FALSE).
**
*******************************************************************************/
-static void smp_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason)
+static void smp_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason,
+ tBT_TRANSPORT transport)
{
tSMP_CB *p_cb = &smp_cb;
tSMP_INT_DATA int_data;
SMP_TRACE_EVENT0 ("SMDBG l2c smp_connect_cback ");
+ if (transport == BT_TRANSPORT_BR_EDR)
+ {
+ SMP_TRACE_ERROR0 ("smp_connect_cback : Wrong transport");
+ return;
+ }
+
if (memcmp(bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) == 0)
{
SMP_TRACE_EVENT3 ("smp_connect_cback() for pairing BDA: %08x%04x Event: %s",
@@ -132,6 +139,13 @@
STREAM_TO_UINT8(cmd, p);
+ /* sanity check */
+ if ((SMP_OPCODE_MAX <= cmd) || (cmd == 0))
+ {
+ SMP_TRACE_WARNING1( "Ignore received command with RESERVED code 0x%02x", cmd);
+ GKI_freebuf (p_buf);
+ return;
+ }
/* reject the pairing request if there is an on-going SMP pairing */
if (SMP_OPCODE_PAIRING_REQ == cmd || SMP_OPCODE_SEC_REQ == cmd)
@@ -143,14 +157,21 @@
}
else if (memcmp(&bd_addr[0], p_cb->pairing_bda, BD_ADDR_LEN))
{
- p_cb->failure = SMP_PAIR_NOT_SUPPORT;
- smp_send_cmd(SMP_OPCODE_PAIRING_FAILED, p_cb);
+ GKI_freebuf (p_buf);
+ smp_reject_unexp_pair_req(bd_addr);
+ return;
}
+ /* else, out of state pairing request/security request received, passed into SM */
}
if (memcmp(&bd_addr[0], p_cb->pairing_bda, BD_ADDR_LEN) == 0)
{
- btu_stop_timer (&p_cb->rsp_timer_ent);
+ if (p_cb->state != SMP_ST_RELEASE_DELAY)
+ {
+ btu_stop_timer (&p_cb->rsp_timer_ent);
+ }
+ p_cb->rcvd_cmd_code = cmd;
+ p_cb->rcvd_cmd_len = (UINT8) p_buf->len;
smp_sm_event(p_cb, cmd, p);
}
diff --git a/stack/smp/smp_main.c b/stack/smp/smp_main.c
index f8e450c..dd40a71 100644
--- a/stack/smp/smp_main.c
+++ b/stack/smp/smp_main.c
@@ -114,6 +114,8 @@
SMP_PROC_REL_DELAY,
SMP_PROC_REL_DELAY_TOUT,
SMP_DELAY_TERMINATE,
+ SMP_IDLE_TERMINATE,
+ SMP_FAST_CONN_PARAM,
SMP_SM_NO_ACTION
};
@@ -156,6 +158,8 @@
smp_proc_release_delay,
smp_proc_release_delay_tout,
smp_delay_terminate,
+ smp_idle_terminate,
+ smp_fast_conn_param
};
/************ SMP Master FSM State/Event Indirection Table **************/
static const UINT8 smp_ma_entry_map[][SMP_ST_MAX] =
@@ -176,7 +180,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, 3 },
+/* L2C_DISC */{ 3, 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 },
@@ -198,15 +202,16 @@
static const UINT8 smp_ma_idle_table[][SMP_SM_NUM_COLS] = {
/* Event Action Next State */
/* L2C_CONN */ {SMP_SEND_APP_CBACK, SMP_SM_NO_ACTION, SMP_ST_WAIT_APP_RSP},
-/* SEC_REQ */ {SMP_PROC_SEC_REQ, SMP_SEND_APP_CBACK, SMP_ST_WAIT_APP_RSP}
+/* SEC_REQ */ {SMP_PROC_SEC_REQ, SMP_SEND_APP_CBACK, SMP_ST_WAIT_APP_RSP},
+/* L2C_DISC */ {SMP_IDLE_TERMINATE, SMP_SM_NO_ACTION, SMP_ST_IDLE}
};
static const UINT8 smp_ma_wait_app_rsp_table[][SMP_SM_NUM_COLS] = {
/* Event Action Next State */
/* SEC_GRANT */ { SMP_PROC_SEC_GRANT, SMP_SEND_APP_CBACK, SMP_ST_WAIT_APP_RSP},
-/* IO_RSP */ { SMP_SEND_PAIR_REQ, SMP_SM_NO_ACTION, SMP_ST_PAIR_REQ_RSP},
+/* IO_RSP */ { SMP_SEND_PAIR_REQ, SMP_FAST_CONN_PARAM, SMP_ST_PAIR_REQ_RSP},
/* KEY_READY */ { SMP_GENERATE_CONFIRM, SMP_SM_NO_ACTION, SMP_ST_WAIT_CONFIRM},/* TK ready */
-/* ENC_REQ */ { SMP_START_ENC, SMP_SM_NO_ACTION, SMP_ST_ENC_PENDING},/* start enc mode setup */
+/* ENC_REQ */ { SMP_START_ENC, SMP_FAST_CONN_PARAM, SMP_ST_ENC_PENDING},/* start enc mode setup */
/* DISCARD_SEC_REQ */ { SMP_PROC_DISCARD, SMP_SM_NO_ACTION, SMP_ST_IDLE}
};
diff --git a/stack/smp/smp_utils.c b/stack/smp/smp_utils.c
index dac0cc0..38b2be8 100644
--- a/stack/smp/smp_utils.c
+++ b/stack/smp/smp_utils.c
@@ -621,6 +621,35 @@
smp_reset_control_value(p_cb);
}
+/*******************************************************************************
+**
+** Function smp_reject_unexp_pair_req
+**
+** Description send pairing failure to an unexpected pairing request during
+** an active pairing process.
+**
+** Returns void
+**
+*******************************************************************************/
+void smp_reject_unexp_pair_req(BD_ADDR bd_addr)
+{
+ BT_HDR *p_buf;
+ UINT8 *p;
+
+ if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_PAIR_FAIL_SIZE + L2CAP_MIN_OFFSET)) != NULL)
+ {
+ p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
+
+ UINT8_TO_STREAM (p, SMP_OPCODE_PAIRING_FAILED);
+ UINT8_TO_STREAM (p, SMP_PAIR_NOT_SUPPORT);
+
+ p_buf->offset = L2CAP_MIN_OFFSET;
+ p_buf->len = SMP_PAIR_FAIL_SIZE;
+
+ smp_send_msg_to_L2CAP(bd_addr, p_buf);
+ }
+}
+
#if SMP_CONFORMANCE_TESTING == TRUE
/*******************************************************************************
**
diff --git a/stack/srvc/srvc_dis.c b/stack/srvc/srvc_dis.c
index 90b4acd..7c4df0d 100644
--- a/stack/srvc/srvc_dis.c
+++ b/stack/srvc/srvc_dis.c
@@ -443,14 +443,14 @@
(peer_bda[4]<<8)+peer_bda[5], dis_attr_uuid[dis_cb.dis_read_uuid_idx]);
- GATT_GetConnIdIfConnected(srvc_eng_cb.gatt_if, peer_bda, &conn_id);
+ GATT_GetConnIdIfConnected(srvc_eng_cb.gatt_if, peer_bda, &conn_id, BT_TRANSPORT_LE);
/* need to enhance it as multiple service is needed */
srvc_eng_request_channel(peer_bda, SRVC_ID_DIS);
if (conn_id == GATT_INVALID_CONN_ID)
{
- return GATT_Connect(srvc_eng_cb.gatt_if, peer_bda, TRUE);
+ return GATT_Connect(srvc_eng_cb.gatt_if, peer_bda, TRUE, BT_TRANSPORT_LE);
}
return dis_gatt_c_read_dis_req(conn_id);
diff --git a/stack/srvc/srvc_eng.c b/stack/srvc/srvc_eng.c
index 4598738..bf730aa 100644
--- a/stack/srvc/srvc_eng.c
+++ b/stack/srvc/srvc_eng.c
@@ -30,7 +30,8 @@
#include "srvc_battery_int.h"
static void srvc_eng_s_request_cback (UINT16 conn_id, UINT32 trans_id, UINT8 op_code, tGATTS_DATA *p_data);
-static void srvc_eng_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason);
+static void srvc_eng_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected,
+ tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport);
static void srvc_eng_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, tGATT_CL_COMPLETE *p_data);
static tGATT_CBACK srvc_gatt_cback =
@@ -341,9 +342,10 @@
**
*******************************************************************************/
static void srvc_eng_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
- BOOLEAN connected, tGATT_DISCONN_REASON reason)
+ BOOLEAN connected, tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport)
{
UNUSED(gatt_if);
+ UNUSED (transport);
GATT_TRACE_EVENT5 ("srvc_eng_connect_cback: from %08x%04x connected:%d conn_id=%d reason = 0x%04x",
(bda[0]<<24)+(bda[1]<<16)+(bda[2]<<8)+bda[3],