Component/bt: abnormal behavior for update conn param command

This commit is contained in:
zhiweijian 2017-09-12 16:39:51 +08:00
parent fbdec19c23
commit 25b0a4f514
19 changed files with 288 additions and 109 deletions

View file

@ -50,6 +50,7 @@ typedef enum {
ESP_BT_STATUS_TIMEOUT, /* relate to BT_STATUS_TIMEOUT in bt_def.h */
ESP_BT_STATUS_PEER_LE_DATA_LEN_UNSUPPORTED, /* relate to BTM_PEER_LE_DATA_LEN_UNSUPPORTED in btm_api.h */
ESP_BT_STATUS_CONTROL_LE_DATA_LEN_UNSUPPORTED,/* relate to BTM_CONTROL_LE_DATA_LEN_UNSUPPORTED in btm_api.h */
ESP_BT_STATUS_ERR_ILLEGAL_PARAMETER_FMT, /* relate to HCI_ERR_ILLEGAL_PARAMETER_FMT in hcidefs.h */
} esp_bt_status_t;

View file

@ -4517,13 +4517,6 @@ void bta_dm_ble_set_conn_scan_params (tBTA_DM_MSG *p_data)
*******************************************************************************/
void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data)
{
tACL_CONN *p_acl_cb = btm_bda_to_acl(p_data->ble_update_conn_params.bd_addr, BT_TRANSPORT_LE);
if (p_acl_cb == NULL) {
APPL_TRACE_ERROR("%s error: Invalid connection bd_addr.", __func__);
return;
} else {
p_acl_cb->update_conn_param_cb = p_data->ble_update_conn_params.update_conn_param_cb;
}
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,

View file

@ -1991,7 +1991,7 @@ void BTA_DmEnableScanFilter(UINT8 action, tBTA_DM_BLE_PF_STATUS_CBACK *p_cmpl_cb
**
*******************************************************************************/
void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, UINT16 max_int,
UINT16 latency, UINT16 timeout, tBTA_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb)
UINT16 latency, UINT16 timeout)
{
tBTA_DM_API_UPDATE_CONN_PARAM *p_msg;
@ -2004,7 +2004,6 @@ void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, UINT16 max
p_msg->max_int = max_int;
p_msg->latency = latency;
p_msg->timeout = timeout;
p_msg->update_conn_param_cb = update_conn_param_cb;
bta_sys_sendmsg(p_msg);
}
}

View file

@ -645,7 +645,6 @@ typedef struct {
UINT16 max_int;
UINT16 latency;
UINT16 timeout;
tBTA_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb;
} tBTA_DM_API_UPDATE_CONN_PARAM;
#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE

View file

@ -861,9 +861,6 @@ void bta_gattc_set_discover_st(tBTA_GATTC_SERV *p_srcb)
tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
UINT8 i;
#if BLE_INCLUDED == TRUE
L2CA_EnableUpdateBleConnParams(p_srcb->server_bda, FALSE);
#endif
for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) {
if (p_cb->clcb[i].p_srcb == p_srcb) {
p_cb->clcb[i].status = BTA_GATT_OK;
@ -993,11 +990,6 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
APPL_TRACE_DEBUG("bta_gattc_disc_cmpl conn_id=%d", p_clcb->bta_conn_id);
#if BLE_INCLUDED == 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;
p_clcb->disc_active = FALSE;

View file

@ -36,6 +36,7 @@
#include "bta_gattc_int.h"
#include "btm_api.h"
#include "btm_ble_api.h"
#include "l2c_api.h"
#define LOG_TAG "bt_bta_gattc"
// #include "osi/include/log.h"
@ -588,6 +589,13 @@ static void bta_gattc_explore_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
#if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
bta_gattc_display_cache_server(p_srvc_cb->p_srvc_cache);
#endif
//server discover end, update connection parameters
#if BLE_INCLUDED == TRUE
if (p_clcb->transport == BTA_TRANSPORT_LE) {
L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE);
}
#endif
/* save cache to NV */
p_clcb->p_srcb->state = BTA_GATTC_SERV_SAVE;
bta_gattc_co_cache_open(p_srvc_cb->server_bda, BTA_GATTC_CI_CACHE_OPEN_EVT,

View file

@ -2210,7 +2210,7 @@ extern void BTA_BleDisableAdvInstance(UINT8 inst_id);
**
*******************************************************************************/
extern void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int,
UINT16 max_int, UINT16 latency, UINT16 timeout, tBTA_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb);
UINT16 max_int, UINT16 latency, UINT16 timeout);
/*******************************************************************************
**

View file

@ -141,7 +141,7 @@ int btc_init(void)
{
xBtcQueue = xQueueCreate(BTC_TASK_QUEUE_NUM, sizeof(btc_msg_t));
xTaskCreatePinnedToCore(btc_task, "Btc_task", BTC_TASK_STACK_SIZE, NULL, BTC_TASK_PRIO, &xBtcTaskHandle, 0);
btc_gap_callback_init();
/* TODO: initial the profile_tab */
return BT_STATUS_SUCCESS;

View file

@ -126,6 +126,9 @@ static esp_bt_status_t btc_hci_to_esp_status(uint8_t hci_status)
case HCI_ERR_PARAM_OUT_OF_RANGE:
esp_status = ESP_BT_STATUS_PARAM_OUT_OF_RANGE;
break;
case HCI_ERR_ILLEGAL_PARAMETER_FMT:
esp_status = ESP_BT_STATUS_ERR_ILLEGAL_PARAMETER_FMT;
break;
default:
esp_status = ESP_BT_STATUS_FAIL;
break;
@ -626,7 +629,7 @@ static void btc_stop_scan_callback(tBTA_STATUS status)
}
}
void btc_update_conn_param_callback (UINT8 status, BD_ADDR bd_addr,
void btc_update_conn_param_callback (UINT8 status, BD_ADDR bd_addr,
tBTM_LE_UPDATE_CONN_PRAMS *update_conn_params)
{
esp_ble_gap_cb_param_t param;
@ -724,8 +727,7 @@ static void btc_ble_stop_advertising(tBTA_START_STOP_ADV_CMPL_CBACK *stop_adv_cb
}
static void btc_ble_update_conn_params(BD_ADDR bd_addr, uint16_t min_int,
uint16_t max_int, uint16_t latency, uint16_t timeout,
tBTA_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb)
uint16_t max_int, uint16_t latency, uint16_t timeout)
{
if (min_int > max_int) {
min_int = max_int;
@ -736,7 +738,7 @@ static void btc_ble_update_conn_params(BD_ADDR bd_addr, uint16_t min_int,
}
BTA_DmBleUpdateConnectionParams(bd_addr, min_int, max_int,
latency, timeout, update_conn_param_cb);
latency, timeout);
}
static void btc_ble_set_pkt_data_len(BD_ADDR remote_device, uint16_t tx_data_length, tBTA_SET_PKT_DATA_LENGTH_CBACK *p_set_pkt_data_cback)
@ -967,8 +969,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
arg->conn_update_params.conn_params.min_int,
arg->conn_update_params.conn_params.max_int,
arg->conn_update_params.conn_params.latency,
arg->conn_update_params.conn_params.timeout,
btc_update_conn_param_callback);
arg->conn_update_params.conn_params.timeout);
break;
case BTC_GAP_BLE_ACT_SET_PKT_DATA_LEN:
btc_ble_set_pkt_data_len(arg->set_pkt_data_len.remote_device, arg->set_pkt_data_len.tx_data_length, btc_set_pkt_length_callback);
@ -1074,3 +1075,10 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
btc_gap_ble_arg_deep_free(msg);
}
//register connection parameter update callback
void btc_gap_callback_init(void)
{
BTM_BleRegiseterConnParamCallback(btc_update_conn_param_callback);
}

View file

@ -126,7 +126,7 @@ typedef union {
esp_bd_addr_t bd_addr;
} remove_bond_device;
} btc_ble_gap_args_t;
void btc_gap_callback_init(void);
void btc_gap_ble_call_handler(btc_msg_t *msg);
void btc_gap_ble_cb_handler(btc_msg_t *msg);

View file

@ -61,6 +61,7 @@ static tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
static tBTM_BLE_CTRL_FEATURES_CBACK *p_ctrl_le_feature_rd_cmpl_cback = NULL;
#endif
tBTM_CallbackFunc conn_param_update_cb;
/*******************************************************************************
** Local functions
*******************************************************************************/
@ -220,6 +221,19 @@ const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] = {
/* check LE combo state supported */
#define BTM_LE_STATES_SUPPORTED(x, y, z) ((x)[(z)] & (y))
/*******************************************************************************
**
** Function BTM_BleRegiseterConnParamCallback
**
** Description register connection parameters update callback func
**
** Returns void
**
*******************************************************************************/
void BTM_BleRegiseterConnParamCallback(tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb)
{
conn_param_update_cb.update_conn_param_cb = update_conn_param_cb;
}
/*******************************************************************************
**

View file

@ -126,6 +126,7 @@ static void btu_ble_ll_conn_complete_evt (UINT8 *p, UINT16 evt_len);
static void btu_ble_process_adv_pkt (UINT8 *p);
static void btu_ble_read_remote_feat_evt (UINT8 *p);
static void btu_ble_ll_conn_param_upd_evt (UINT8 *p, UINT16 evt_len);
static void btu_ble_ll_get_conn_param_format_err_from_contoller (UINT8 status, UINT16 handle);
#if (SMP_INCLUDED == TRUE)
static void btu_ble_proc_ltk_req (UINT8 *p);
static void btu_hcif_encryption_key_refresh_cmpl_evt (UINT8 *p);
@ -1130,6 +1131,14 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c
case HCI_BLE_CREATE_LL_CONN:
btm_ble_create_ll_conn_complete(status);
break;
case HCI_BLE_UPD_LL_CONN_PARAMS:
if (p_cmd != NULL){
p_cmd++;
STREAM_TO_UINT16 (handle, p_cmd);
btu_ble_ll_get_conn_param_format_err_from_contoller(status, handle);
}
break;
#endif
#if BTM_SCO_INCLUDED == TRUE
@ -1758,6 +1767,14 @@ static void btu_ble_ll_conn_param_upd_evt (UINT8 *p, UINT16 evt_len)
conn_latency, conn_timeout);
}
static void btu_ble_ll_get_conn_param_format_err_from_contoller (UINT8 status, UINT16 handle)
{
/* host send illegal connection parameters format, controller would send
back HCI_ERR_ILLEGAL_PARAMETER_FMT */
l2cble_get_conn_param_format_err_from_contoller(status, handle);
}
static void btu_ble_read_remote_feat_evt (UINT8 *p)
{
btm_ble_read_remote_features_complete(p);

View file

@ -164,12 +164,12 @@ typedef UINT8 tBTM_BLE_SFP;
/* default connection interval min */
#ifndef BTM_BLE_CONN_INT_MIN_DEF
#define BTM_BLE_CONN_INT_MIN_DEF 24 /* recommended min: 30ms = 24 * 1.25 */
#define BTM_BLE_CONN_INT_MIN_DEF 10 /* recommended min: 12.5ms = 10 * 1.25 */
#endif
/* default connection interval max */
#ifndef BTM_BLE_CONN_INT_MAX_DEF
#define BTM_BLE_CONN_INT_MAX_DEF 40 /* recommended max: 50 ms = 56 * 1.25 */
#define BTM_BLE_CONN_INT_MAX_DEF 12 /* recommended max: 15 ms = 12 * 1.25 */
#endif
/* default slave latency */
@ -861,6 +861,20 @@ tBTM_BLE_SCAN_SETUP_CBACK bta_ble_scan_setup_cb;
extern "C" {
#endif
*/
/*******************************************************************************
**
** Function BTM_BleRegiseterConnParamCallback
**
** Description register connection parameters update callback func
**
** Parameters: update_conn_param_cb
**
** Returns void
**
*******************************************************************************/
void BTM_BleRegiseterConnParamCallback(tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb);
/*******************************************************************************
**
** Function BTM_SecAddBleDevice

View file

@ -115,7 +115,6 @@ UINT8 conn_addr_type; /* local device address type for this co
BD_ADDR active_remote_addr; /* remote address used on this connection */
UINT8 active_remote_addr_type; /* local device address type for this connection */
BD_FEATURES peer_le_features; /* Peer LE Used features mask for the device */
tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb;
tBTM_SET_PKT_DATA_LENGTH_CBACK *p_set_pkt_data_cback;
tBTM_LE_SET_PKT_DATA_LENGTH_PARAMS data_length_params;
#endif
@ -874,6 +873,12 @@ typedef struct {
#endif
} tBTM_CB;
typedef struct{
//connection parameters update callback
tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb;
}tBTM_CallbackFunc;
extern tBTM_CallbackFunc conn_param_update_cb;
/*
#ifdef __cplusplus
extern "C"

View file

@ -402,14 +402,24 @@ typedef struct t_l2c_linkcb {
#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 */
#define L2C_BLE_UPDATE_PARAM_FULL 0x10 /* update connection parameters full, can not update */
UINT8 conn_update_mask;
UINT16 min_interval; /* parameters as requested by peripheral */
UINT16 max_interval;
UINT16 conn_int;
UINT16 latency;
UINT16 timeout;
/* cache connection parameters that wait to update */
UINT16 waiting_update_conn_min_interval;
UINT16 waiting_update_conn_max_interval;
UINT16 waiting_update_conn_latency;
UINT16 waiting_update_conn_timeout;
/* cache parameters that is being updated */
UINT16 updating_conn_min_interval;
UINT16 updating_conn_max_interval;
bool updating_param_flag;
/* current connection parameters that current connection is using */
UINT16 current_used_conn_interval;
UINT16 current_used_conn_latency;
UINT16 current_used_conn_timeout;
/* connection parameters update order:
waiting_update_conn_xx -> updating_conn_xx -> current_used_conn_xx
*/
#endif
#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
@ -733,6 +743,7 @@ extern void l2cble_notify_le_connection (BD_ADDR bda);
extern void l2c_ble_link_adjust_allocation (void);
extern void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status, UINT16 conn_interval,
UINT16 conn_latency, UINT16 conn_timeout);
extern void l2cble_get_conn_param_format_err_from_contoller(UINT8 status, UINT16 handle);
#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,
@ -745,6 +756,7 @@ extern void l2cble_set_fixed_channel_tx_data_length(BD_ADDR remote_bda, UINT16 f
extern void l2c_send_update_conn_params_cb(tL2C_LCB *p_lcb, UINT8 status);
extern void l2cble_process_data_length_change_event(UINT16 handle, UINT16 tx_data_len,
UINT16 rx_data_len);
extern UINT32 CalConnectParamTimeout(tL2C_LCB *p_lcb);
#endif
extern void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb);

View file

@ -117,14 +117,31 @@ BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_in
return (FALSE);
}
p_lcb->min_interval = min_int;
p_lcb->max_interval = max_int;
p_lcb->latency = latency;
p_lcb->timeout = timeout;
if (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PARAM_FULL){
UINT8 status = HCI_ERR_ILLEGAL_COMMAND;
L2CAP_TRACE_ERROR("There are two connection parameter requests that are being updated, please try later ");
if (conn_param_update_cb.update_conn_param_cb != NULL) {
tBTM_LE_UPDATE_CONN_PRAMS update_param;
update_param.max_conn_int = max_int;
update_param.min_conn_int = min_int;
update_param.conn_int = p_lcb->current_used_conn_interval;
update_param.slave_latency = p_lcb->current_used_conn_latency;
update_param.supervision_tout = p_lcb->current_used_conn_timeout;
(conn_param_update_cb.update_conn_param_cb)(status, p_lcb->remote_bd_addr, &update_param);
}
return (FALSE);
}
p_lcb->waiting_update_conn_min_interval = min_int;
p_lcb->waiting_update_conn_max_interval = max_int;
p_lcb->waiting_update_conn_latency = latency;
p_lcb->waiting_update_conn_timeout = timeout;
p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
if(l2cble_start_conn_update(p_lcb) == TRUE) {
btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, L2CAP_UPDATE_CONN_PARAM_TOUT);
UINT32 time = CalConnectParamTimeout(p_lcb);
btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, time);
}
return (TRUE);
@ -167,6 +184,10 @@ BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable)
return (FALSE);
}
if (p_lcb->current_used_conn_interval <= BTM_BLE_CONN_INT_MAX_DEF && (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) == 0){
return (FALSE);
}
if (enable) {
p_lcb->conn_update_mask &= ~L2C_BLE_CONN_UPDATE_DISABLE;
} else {
@ -174,7 +195,9 @@ BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable)
}
if (l2cble_start_conn_update(p_lcb) == TRUE) {
btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, L2CAP_UPDATE_CONN_PARAM_TOUT);
UINT32 time = CalConnectParamTimeout(p_lcb);
btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, time);
}
return (TRUE);
@ -304,10 +327,11 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
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->waiting_update_conn_min_interval = p_lcb->waiting_update_conn_max_interval = p_lcb->current_used_conn_interval = conn_interval;
p_lcb->waiting_update_conn_timeout = p_lcb->current_used_conn_timeout = conn_timeout;
p_lcb->waiting_update_conn_latency = p_lcb->current_used_conn_latency = conn_latency;
p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM;
p_lcb->updating_param_flag = false;
/* If there are any preferred connection parameters, set them now */
if ( (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN ) &&
@ -326,10 +350,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;
p_lcb->waiting_update_conn_min_interval = p_dev_rec->conn_params.min_conn_int;
p_lcb->waiting_update_conn_max_interval = p_dev_rec->conn_params.max_conn_int;
p_lcb->waiting_update_conn_timeout = p_dev_rec->conn_params.supervision_tout;
p_lcb->waiting_update_conn_latency = p_dev_rec->conn_params.slave_latency;
btsnd_hcic_ble_upd_ll_conn_params (handle,
p_dev_rec->conn_params.min_conn_int,
@ -403,10 +428,11 @@ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE typ
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->waiting_update_conn_min_interval = p_lcb->waiting_update_conn_max_interval = p_lcb->current_used_conn_interval = conn_interval;
p_lcb->waiting_update_conn_timeout = p_lcb->current_used_conn_timeout = conn_timeout;
p_lcb->waiting_update_conn_latency = p_lcb->current_used_conn_latency = conn_latency;
p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM;
p_lcb->updating_param_flag = false;
/* Tell BTM Acl management about the link */
p_dev_rec = btm_find_or_alloc_dev (bda);
@ -469,10 +495,10 @@ static BOOLEAN l2cble_start_conn_update (tL2C_LCB *p_lcb)
#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) && (BLE_SLAVE_UPD_CONN_PARAMS == TRUE)
tACL_CONN *p_acl_cb = btm_bda_to_acl(p_lcb->remote_bd_addr, BT_TRANSPORT_LE);
#endif /* defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) && (BLE_SLAVE_UPD_CONN_PARAMS == TRUE */
UINT8 status;
if (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) {
L2CAP_TRACE_ERROR("%s, the last connection update command still pending.", __func__);
L2CAP_TRACE_WARNING("%s, the last connection update command still pending.", __func__);
p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PARAM_FULL;
return FALSE;
}
@ -482,7 +508,7 @@ static BOOLEAN l2cble_start_conn_update (tL2C_LCB *p_lcb)
up to what has been requested during connection establishement */
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) {
p_lcb->waiting_update_conn_min_interval > BTM_BLE_CONN_INT_MIN) {
/* 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;
@ -500,15 +526,16 @@ static BOOLEAN l2cble_start_conn_update (tL2C_LCB *p_lcb)
} else {
l2cu_send_peer_ble_par_req (p_lcb, min_conn_int, max_conn_int, slave_latency, supervision_tout);
}
//cache save
p_lcb->updating_conn_min_interval = min_conn_int;
p_lcb->updating_conn_max_interval = max_conn_int;
p_lcb->updating_param_flag = true;
p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
p_lcb->conn_update_mask &= ~L2C_BLE_NOT_DEFAULT_PARAM;
p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
return TRUE;
} else {
status = HCI_ERR_ILLEGAL_COMMAND;
L2CAP_TRACE_ERROR("%s, staus = %x, line = %d", __func__, status, __LINE__);
btu_stop_timer(&p_lcb->upda_con_timer);
l2c_send_update_conn_params_cb(p_lcb, status);
return FALSE;
}
} else {
@ -521,18 +548,22 @@ static BOOLEAN l2cble_start_conn_update (tL2C_LCB *p_lcb)
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);
btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, p_lcb->waiting_update_conn_min_interval,
p_lcb->waiting_update_conn_max_interval, p_lcb->waiting_update_conn_latency, p_lcb->waiting_update_conn_timeout, 0, 0);
} else {
l2cu_send_peer_ble_par_req (p_lcb, p_lcb->min_interval, p_lcb->max_interval,
p_lcb->latency, p_lcb->timeout);
l2cu_send_peer_ble_par_req (p_lcb, p_lcb->waiting_update_conn_min_interval, p_lcb->waiting_update_conn_max_interval,
p_lcb->waiting_update_conn_latency, p_lcb->waiting_update_conn_timeout);
}
//cache save
p_lcb->updating_conn_min_interval = p_lcb->waiting_update_conn_min_interval;
p_lcb->updating_conn_max_interval = p_lcb->waiting_update_conn_max_interval;
p_lcb->updating_param_flag = true;
p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
p_lcb->conn_update_mask &= ~L2C_BLE_NEW_CONN_PARAM;
p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM;
return TRUE;
} else {
btu_stop_timer(&p_lcb->upda_con_timer);
return FALSE;
}
}
@ -553,36 +584,77 @@ void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status, UINT16 conn_in
{
tL2C_LCB *p_lcb;
L2CAP_TRACE_DEBUG("l2cble_process_conn_update_evt");
/* 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_WARNING("l2cble_process_conn_update_evt: Invalid handle: %d", handle);
return;
}
p_lcb->conn_int = conn_interval;
p_lcb->latency = conn_latency;
p_lcb->timeout = conn_timeout;
tACL_CONN *p_acl_cb = btm_bda_to_acl(p_lcb->remote_bd_addr, BT_TRANSPORT_LE);
p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING;
if (status != HCI_SUCCESS) {
if (status == HCI_SUCCESS){
p_lcb->current_used_conn_interval = conn_interval;
p_lcb->current_used_conn_latency = conn_latency;
p_lcb->current_used_conn_timeout = conn_timeout;
}else{
L2CAP_TRACE_WARNING("l2cble_process_conn_update_evt: Error status: %d", status);
}
if (l2cble_start_conn_update(p_lcb) == TRUE) {
btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, L2CAP_UPDATE_CONN_PARAM_TOUT);
}
p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING;
p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PARAM_FULL;
btu_stop_timer (&p_lcb->timer_entry);
if (p_acl_cb->update_conn_param_cb != NULL) {
btu_stop_timer(&p_lcb->upda_con_timer);
if (conn_param_update_cb.update_conn_param_cb != NULL) {
l2c_send_update_conn_params_cb(p_lcb, status);
}
if (l2cble_start_conn_update(p_lcb) == TRUE) {
UINT32 time = CalConnectParamTimeout(p_lcb);
btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, time);
}
btu_stop_timer (&p_lcb->timer_entry);
L2CAP_TRACE_DEBUG("l2cble_process_conn_update_evt: conn_update_mask=%d", p_lcb->conn_update_mask);
}
/*******************************************************************************
**
** Function l2cble_get_conn_param_format_err_from_contoller
**
** Description This function is called when host get illegal connection paramrters
** format status from controller
**
** Returns void
**
*******************************************************************************/
void l2cble_get_conn_param_format_err_from_contoller (UINT8 status, UINT16 handle)
{
tL2C_LCB *p_lcb;
/* 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_ERROR("%s: Invalid handle: %d", __FUNCTION__, handle);
return;
}
p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING;
btu_stop_timer (&p_lcb->upda_con_timer);
if (conn_param_update_cb.update_conn_param_cb != NULL) {
l2c_send_update_conn_params_cb(p_lcb, status);
}
if ((p_lcb->conn_update_mask & L2C_BLE_UPDATE_PARAM_FULL) != 0){
p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PARAM_FULL;
if (l2cble_start_conn_update(p_lcb) == TRUE) {
UINT32 time = CalConnectParamTimeout(p_lcb);
btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, time);
}
}
}
/*******************************************************************************
**
** Function l2cble_process_sig_cmd
@ -630,32 +702,33 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
STREAM_TO_UINT16 (timeout, p); /* 0x000A - 0x0C80 */
/* If we are a master, the slave wants to update the parameters */
if (p_lcb->link_role == HCI_ROLE_MASTER) {
if (min_interval < BTM_BLE_CONN_INT_MIN_LIMIT) {
min_interval = BTM_BLE_CONN_INT_MIN_LIMIT;
}
if (min_interval < BTM_BLE_CONN_INT_MIN || min_interval > BTM_BLE_CONN_INT_MAX ||
max_interval < BTM_BLE_CONN_INT_MIN || max_interval > BTM_BLE_CONN_INT_MAX ||
latency > BTM_BLE_CONN_LATENCY_MAX ||
/*(timeout >= max_interval && latency > (timeout * 10/(max_interval * 1.25) - 1)) ||*/
timeout < BTM_BLE_CONN_SUP_TOUT_MIN || timeout > BTM_BLE_CONN_SUP_TOUT_MAX ||
timeout <= ((1 + latency)*max_interval*2) ||
/* The supervision_timeout parameter defines the link supervision timeout for the connection.
The supervision_timeout in milliseconds shall be large than (1 + latency) * max_interval * 2,
where max_interval is given in milliseconds. (See [Vol 6] Part B, Section 4.5.2).
supervision_timeout (mult of 10ms); conn_interval (mult of 1.25ms)
(max_interval * 1.25 * 2) replaced by ((max_interval * 5) >> 1).
*/
((timeout * 10) < ((1 + latency) *((max_interval * 5) >> 1))) ||
max_interval < min_interval) {
l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_UNACCEPTABLE_PARAMS, id);
UINT8 status = HCI_ERR_PARAM_OUT_OF_RANGE;
l2c_send_update_conn_params_cb(p_lcb, status);
L2CAP_TRACE_ERROR("slave connection parameters update failed, the parameters are out of range");
} else {
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->waiting_update_conn_min_interval = min_interval;
p_lcb->waiting_update_conn_max_interval = max_interval;
p_lcb->waiting_update_conn_latency = latency;
p_lcb->waiting_update_conn_timeout = timeout;
p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
if (l2cble_start_conn_update(p_lcb) == TRUE) {
btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, L2CAP_UPDATE_CONN_PARAM_TOUT);
UINT32 time = CalConnectParamTimeout(p_lcb);
btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, time);
}
}
} else {
@ -669,6 +742,8 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
UINT8 status = (result == 0) ? HCI_SUCCESS : HCI_ERR_PARAM_OUT_OF_RANGE;
if (status != HCI_SUCCESS) {
btu_stop_timer(&p_lcb->upda_con_timer);
p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING;
p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PARAM_FULL;
l2c_send_update_conn_params_cb(p_lcb, status);
}
break;
@ -945,10 +1020,7 @@ void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 i
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;
/* if update is enabled, always accept connection parameter update */
if ((p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) == 0) {
p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
@ -1087,16 +1159,48 @@ void l2cble_set_fixed_channel_tx_data_length(BD_ADDR remote_bda, UINT16 fix_cid,
*******************************************************************************/
void l2c_send_update_conn_params_cb(tL2C_LCB *p_lcb, UINT8 status)
{
tACL_CONN *p_acl_cb = btm_bda_to_acl(p_lcb->remote_bd_addr, BT_TRANSPORT_LE);
if (p_acl_cb != NULL && p_acl_cb->update_conn_param_cb != NULL) {
if (conn_param_update_cb.update_conn_param_cb != NULL) {
tBTM_LE_UPDATE_CONN_PRAMS update_param;
update_param.max_conn_int = p_lcb->max_interval;
update_param.min_conn_int = p_lcb->min_interval;
update_param.conn_int = p_lcb->conn_int;
update_param.slave_latency = p_lcb->latency;
update_param.supervision_tout = p_lcb->timeout;
(p_acl_cb->update_conn_param_cb)(status, p_acl_cb->active_remote_addr, &update_param);
//if myself update the connection parameters
if (p_lcb->updating_param_flag){
update_param.max_conn_int = p_lcb->updating_conn_max_interval;
update_param.min_conn_int = p_lcb->updating_conn_min_interval;
p_lcb->updating_param_flag = false;
}else{
// remote device update the connection parameters
update_param.max_conn_int = update_param.min_conn_int = 0;
}
// current connection parameters
update_param.conn_int = p_lcb->current_used_conn_interval;
update_param.slave_latency = p_lcb->current_used_conn_latency;
update_param.supervision_tout = p_lcb->current_used_conn_timeout;
(conn_param_update_cb.update_conn_param_cb)(status, p_lcb->remote_bd_addr, &update_param);
}
}
/*******************************************************************************
**
** Function CalConnectParamTimeout
**
** Description This function is called to calculate the connection parameter timeout.
**
** Returns timeout
**
*******************************************************************************/
UINT32 CalConnectParamTimeout(tL2C_LCB *p_lcb)
{
UINT32 timeout = 6;
if (p_lcb != NULL){
//1.25 * conn_int *(1+ latency) *32
timeout = (40 * ( 1 + p_lcb->current_used_conn_latency) * p_lcb->current_used_conn_interval + 500) / 1000;
if (timeout < 1){
timeout = 1;
}else if (timeout > 120){
timeout = 120;
}
}
return timeout;
}
#endif /* (BLE_INCLUDED == TRUE) */

View file

@ -896,7 +896,12 @@ void l2c_process_timeout (TIMER_LIST_ENT *p_tle)
break;
case BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS: {
UINT8 status = HCI_ERR_HOST_TIMEOUT;
l2c_send_update_conn_params_cb((tL2C_LCB *)p_tle->param, status);
tL2C_LCB *p_lcb = (tL2C_LCB *)p_tle->param;
if (p_lcb){
p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING;
p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PARAM_FULL;
}
l2c_send_update_conn_params_cb(p_lcb, status);
break;
}
}

View file

@ -306,7 +306,15 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par
}
ESP_LOGI(GATTC_TAG, "stop adv successfully");
break;
case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
ESP_LOGI(GATTC_TAG, "update connetion params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d",
param->update_conn_params.status,
param->update_conn_params.min_int,
param->update_conn_params.max_int,
param->update_conn_params.conn_int,
param->update_conn_params.latency,
param->update_conn_params.timeout);
break;
default:
break;
}

View file

@ -471,8 +471,8 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
/* For the IOS system, please reference the apple official documents about the ble connection parameters restrictions. */
conn_params.latency = 0;
conn_params.max_int = 0x50; // max_int = 0x50*1.25ms = 100ms
conn_params.min_int = 0x30; // min_int = 0x30*1.25ms = 60ms
conn_params.max_int = 0x20; // max_int = 0x20*1.25ms = 40ms
conn_params.min_int = 0x10; // min_int = 0x10*1.25ms = 20ms
conn_params.timeout = 400; // timeout = 400*10ms = 4000ms
ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d",
param->connect.conn_id,