nimble/controller: Initiate data length update if remote supports it

We initiate data length update procedure as soon as we receive features
from remote and know that this is supported on connection.

This fixes issue with some crippled controllers which do not indicate
DLE support but will reply with LL_LENGTH_RSP but with broken payload
(e.g. the one in Sony Xperia Z5). This would result in LL timeout since
we properly ignore broken PDU.

X-Original-Commit: 456682623f454710824ad97213ab7576ddeca4e9
This commit is contained in:
Andrzej Kaczmarek
2017-07-04 09:54:11 +02:00
parent 0a9a60b06f
commit 64edc2d2be
+31 -4
View File
@@ -1517,6 +1517,27 @@ ble_ll_ctrl_rx_conn_update(struct ble_ll_conn_sm *connsm, uint8_t *dptr)
return rsp_opcode;
}
static void
ble_ll_ctrl_initiate_dle(struct ble_ll_conn_sm *connsm)
{
if (!(connsm->conn_features & BLE_LL_FEAT_DATA_LEN_EXT)) {
return;
}
/*
* Section 4.5.10 Vol 6 PART B. If the max tx/rx time or octets
* exceeds the minimum, data length procedure needs to occur
*/
if ((connsm->max_tx_octets <= BLE_LL_CONN_SUPP_BYTES_MIN) &&
(connsm->max_rx_octets <= BLE_LL_CONN_SUPP_BYTES_MIN) &&
(connsm->max_tx_time <= BLE_LL_CONN_SUPP_TIME_MIN) &&
(connsm->max_rx_time <= BLE_LL_CONN_SUPP_TIME_MIN)) {
return;
}
ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_DATA_LEN_UPD);
}
/**
* Called when we receive a feature request or a slave initiated feature
* request.
@@ -1569,8 +1590,11 @@ ble_ll_ctrl_rx_feature_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
put_le32(rspbuf + 1, our_feat);
rspbuf[1] = connsm->conn_features;
/* We now have remote features */
connsm->csmflags.cfbit.rxd_features = 1;
/* If this is the first time we received remote features, try to start DLE */
if (!connsm->csmflags.cfbit.rxd_features) {
ble_ll_ctrl_initiate_dle(connsm);
connsm->csmflags.cfbit.rxd_features = 1;
}
return rsp_opcode;
}
@@ -2220,8 +2244,11 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
case BLE_LL_CTRL_FEATURE_RSP:
connsm->conn_features = dptr[0];
memcpy(connsm->remote_features, dptr + 1, 7);
/* We now have remote features */
connsm->csmflags.cfbit.rxd_features = 1;
/* If this is the first time we received remote features, try to start DLE */
if (!connsm->csmflags.cfbit.rxd_features) {
ble_ll_ctrl_initiate_dle(connsm);
connsm->csmflags.cfbit.rxd_features = 1;
}
/* Stop the control procedure */
if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG)) {
ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG);