diff options
author | Andre Eisenbach <eisenbach@google.com> | 2014-12-16 16:18:10 -0800 |
---|---|---|
committer | Andre Eisenbach <eisenbach@google.com> | 2014-12-16 16:32:26 -0800 |
commit | 01a069a228cb63988e502aed01a73a2a1d8a59eb (patch) | |
tree | 24f77ce330f8cd916a248656d470813001523b2c | |
parent | 40053090c5e4faaf0b1906164569666ae722e6fa (diff) | |
download | bluedroid-01a069a228cb63988e502aed01a73a2a1d8a59eb.tar.gz |
Allow connection parameters updates by slave
GATT service discovery in the slave role does not update to fast connection
parameters when connected. Accordin to the 4.0 spec, the connection
parameter disable/enable call is used for only by the masster role.
The 4.1 and later spec allows the slave role to control the connection
parameter update so that a slave role GATT client can perform the service
discovery using fast connection parameters.
Also switched to requestiong 7.5ms connection interval by default during
service discovery.
Bug: 18266904
Change-Id: Ie6300587306be3d694937e3888069e252592be42
-rw-r--r-- | stack/l2cap/l2c_ble.c | 164 |
1 files changed, 94 insertions, 70 deletions
diff --git a/stack/l2cap/l2c_ble.c b/stack/l2cap/l2c_ble.c index 75a2bfb..d3ba6e2 100644 --- a/stack/l2cap/l2c_ble.c +++ b/stack/l2cap/l2c_ble.c @@ -98,62 +98,38 @@ BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda) BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout) { - tL2C_LCB *p_lcb; - tACL_CONN *p_acl_cb = btm_bda_to_acl(rem_bda, BT_TRANSPORT_LE); + 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, 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, BT_TRANSPORT_LE); - /* If we don't have one, create one and accept the connection. */ - if (!p_lcb || !p_acl_cb) - { - L2CAP_TRACE_WARNING ("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_WARNING ("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->transport != BT_TRANSPORT_LE) - { - L2CAP_TRACE_WARNING ("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))) - { - p_lcb->min_interval = min_int; - p_lcb->max_interval = max_int; - p_lcb->latency = latency; - p_lcb->timeout = timeout; - p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; + if (p_lcb->transport != BT_TRANSPORT_LE) + { + L2CAP_TRACE_WARNING ("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); + } - l2cble_start_conn_update(p_lcb); - } - 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) - { - p_lcb->min_interval = min_int; - p_lcb->max_interval = max_int; - p_lcb->latency = latency; - p_lcb->timeout = timeout; - p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; + p_lcb->min_interval = min_int; + p_lcb->max_interval = max_int; + p_lcb->latency = latency; + p_lcb->timeout = timeout; + p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; - l2cble_start_conn_update(p_lcb); - } - else - l2cu_send_peer_ble_par_req (p_lcb, min_int, max_int, latency, timeout); - } - return(TRUE); + l2cble_start_conn_update(p_lcb); + return(TRUE); } @@ -187,9 +163,9 @@ BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable) (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->transport != BT_TRANSPORT_LE || (p_lcb->link_role != HCI_ROLE_MASTER)) + if (p_lcb->transport != BT_TRANSPORT_LE) { - L2CAP_TRACE_WARNING ("%s - BD_ADDR %08x%04x not LE or not master %d", __FUNCTION__, + L2CAP_TRACE_WARNING ("%s - BD_ADDR %08x%04x not LE (link role %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); @@ -330,6 +306,12 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, p_lcb->link_role = HCI_ROLE_MASTER; p_lcb->transport = BT_TRANSPORT_LE; + /* update link parameter, set slave link as non-spec default upon link up */ + p_lcb->min_interval = p_lcb->max_interval = conn_interval; + p_lcb->timeout = conn_timeout; + p_lcb->latency = conn_latency; + p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM; + /* If there are any preferred connection parameters, set them now */ if ( (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN ) && (p_dev_rec->conn_params.min_conn_int <= BTM_BLE_CONN_INT_MAX ) && @@ -348,6 +330,11 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, handle, p_dev_rec->conn_params.min_conn_int, p_dev_rec->conn_params.max_conn_int, p_dev_rec->conn_params.slave_latency, p_dev_rec->conn_params.supervision_tout); + p_lcb->min_interval = p_dev_rec->conn_params.min_conn_int; + p_lcb->max_interval = p_dev_rec->conn_params.max_conn_int; + p_lcb->timeout = p_dev_rec->conn_params.supervision_tout; + p_lcb->latency = p_dev_rec->conn_params.slave_latency; + btsnd_hcic_ble_upd_ll_conn_params (handle, p_dev_rec->conn_params.min_conn_int, p_dev_rec->conn_params.max_conn_int, @@ -416,6 +403,12 @@ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE typ p_lcb->link_role = HCI_ROLE_SLAVE; p_lcb->transport = BT_TRANSPORT_LE; + /* update link parameter, set slave link as non-spec default upon link up */ + p_lcb->min_interval = p_lcb->max_interval = conn_interval; + p_lcb->timeout = conn_timeout; + p_lcb->latency = conn_latency; + p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM; + /* Tell BTM Acl management about the link */ p_dev_rec = btm_find_or_alloc_dev (bda); @@ -472,7 +465,9 @@ void l2cble_conn_comp(UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE typ *******************************************************************************/ static void l2cble_start_conn_update (tL2C_LCB *p_lcb) { + UINT16 min_conn_int, max_conn_int, slave_latency, supervision_tout; tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev(p_lcb->remote_bd_addr); + tACL_CONN *p_acl_cb = btm_bda_to_acl(p_lcb->remote_bd_addr, BT_TRANSPORT_LE); if (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) return; @@ -481,31 +476,59 @@ static void l2cble_start_conn_update (tL2C_LCB *p_lcb) /* 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 & L2C_BLE_NOT_DEFAULT_PARAM) + if (p_lcb->conn_update_mask & L2C_BLE_NOT_DEFAULT_PARAM && + /* current connection interval is greater than default min */ + p_lcb->min_interval > BTM_BLE_CONN_INT_MIN) { - 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); + /* use 7.5 ms as fast connection parameter, 0 slave latency */ + min_conn_int = max_conn_int = BTM_BLE_CONN_INT_MIN; + slave_latency = BTM_BLE_CONN_SLAVE_LATENCY_DEF; + supervision_tout = BTM_BLE_CONN_TIMEOUT_DEF; + + /* if both side 4.1, or we are master device, send HCI command */ + if (p_lcb->link_role == HCI_ROLE_MASTER +#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) + || (HCI_LE_CONN_PARAM_REQ_SUPPORTED(btm_cb.devcb.local_le_features) && + HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features)) +#endif + ) + { + btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, min_conn_int, max_conn_int, + slave_latency, supervision_tout, 0, 0); + p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING; + } + else + { + l2cu_send_peer_ble_par_req (p_lcb, min_conn_int, max_conn_int, slave_latency, supervision_tout); + } p_lcb->conn_update_mask &= ~L2C_BLE_NOT_DEFAULT_PARAM; - p_lcb->conn_update_mask |= (L2C_BLE_UPDATE_PENDING | L2C_BLE_NEW_CONN_PARAM); - } + p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; + } } else { /* application allows to do update, if we were delaying one do it now */ if (p_lcb->conn_update_mask & 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); + /* if both side 4.1, or we are master device, send HCI command */ + if (p_lcb->link_role == HCI_ROLE_MASTER +#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) + || (HCI_LE_CONN_PARAM_REQ_SUPPORTED(btm_cb.devcb.local_le_features) && + HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features)) +#endif + ) + { + 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->conn_update_mask |= L2C_BLE_UPDATE_PENDING; + } + else + { + l2cu_send_peer_ble_par_req (p_lcb, p_lcb->min_interval, p_lcb->max_interval, + p_lcb->latency, p_lcb->timeout); + } p_lcb->conn_update_mask &= ~L2C_BLE_NEW_CONN_PARAM; - p_lcb->conn_update_mask |= (L2C_BLE_UPDATE_PENDING | L2C_BLE_NOT_DEFAULT_PARAM); + p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM; } } } @@ -694,9 +717,9 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) init_addr, /* BD_ADDR bda_peer */ own_addr_type, /* UINT8 addr_type_own */ (UINT16) ((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? - p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF), /* conn_int_min */ + p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF), /* UINT16 conn_int_min */ (UINT16) ((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? - p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF), /* conn_int_max */ + p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF), /* UINT16 conn_int_max */ (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 conn_latency */ (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ? @@ -929,6 +952,7 @@ void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 i else { L2CAP_TRACE_EVENT ("L2CAP - LE - update currently disabled"); + p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; btsnd_hcic_ble_rc_param_req_neg_reply (handle,HCI_ERR_UNACCEPT_CONN_INTERVAL); } |