From ef7803a1d7634003c8d0e427967daa2e1643fc66 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 3 Jul 2017 12:17:09 +0200 Subject: [PATCH] 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 --- nimble/controller/src/ble_ll_ctrl.c | 35 +++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index d701ceebf..909f33d74 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -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);