From 8cf2509bd915ec22e451fa219ed1b066e19efe99 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 13 Dec 2019 12:24:36 +0100 Subject: [PATCH] nimble/ll: Recalculate effective TX/RX time after PHY update If LE Coded is supported, effective TX/RX time may change after PHY update due to following restriction: * connEffectiveMaxTxTimeCoded - the greater of 2704 and connEffectiveMaxTxTimeAvailable. * connEffectiveMaxTxTime - equal to connEffectiveMaxTxTimeUncoded while the connection is on an LE Uncoded PHY and equal to connEffectiveMaxTxTimeCoded while the connection is on the LE Coded PHY. This means after PHY change we should recalculate effective TX/RX time and update host if necessary. Reference: Core 5.1, Vol B, Part B, 4.5.10. --- nimble/controller/src/ble_ll_conn.c | 30 +++++++++++------------- nimble/controller/src/ble_ll_conn_priv.h | 3 +-- nimble/controller/src/ble_ll_ctrl.c | 10 ++++++-- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 1ff60b837..2a98c139c 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1772,38 +1772,33 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) SLIST_INSERT_HEAD(&g_ble_ll_conn_active_list, connsm, act_sle); } -/** - * Called when a remotes data length parameters change. - * - * Context: Link Layer task - * - * @param connsm - * @param req - */ void -ble_ll_conn_datalen_update(struct ble_ll_conn_sm *connsm, - struct ble_ll_len_req *req) +ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm) { int send_event; uint16_t eff_time; uint16_t eff_bytes; - /* Update parameters */ - connsm->rem_max_rx_time = req->max_rx_time; - connsm->rem_max_tx_time = req->max_tx_time; - connsm->rem_max_rx_octets = req->max_rx_bytes; - connsm->rem_max_tx_octets = req->max_tx_bytes; - /* Assume no event sent */ send_event = 0; /* See if effective times have changed */ eff_time = min(connsm->rem_max_tx_time, connsm->max_rx_time); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) + if (connsm->phy_data.cur_rx_phy == BLE_PHY_CODED) { + eff_time = max(eff_time, BLE_LL_CONN_SUPP_TIME_MIN_CODED); + } +#endif if (eff_time != connsm->eff_max_rx_time) { connsm->eff_max_rx_time = eff_time; send_event = 1; } eff_time = min(connsm->rem_max_rx_time, connsm->max_tx_time); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) + if (connsm->phy_data.cur_tx_phy == BLE_PHY_CODED) { + eff_time = max(eff_time, BLE_LL_CONN_SUPP_TIME_MIN_CODED); + } +#endif if (eff_time != connsm->eff_max_tx_time) { connsm->eff_max_tx_time = eff_time; send_event = 1; @@ -2149,6 +2144,9 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) ble_ll_ctrl_phy_update_proc_complete(connsm); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) + /* Recalculate effective connection parameters */ + ble_ll_conn_update_eff_data_len(connsm); + /* * If PHY in either direction was changed to coded, we assume that peer * does support LE Coded PHY even if features were not exchanged yet. diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index 86c7b643a..f2f72d17c 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -134,8 +134,7 @@ void ble_ll_conn_ext_set_params(struct ble_ll_conn_sm *connsm, #endif struct ble_ll_conn_sm *ble_ll_conn_find_active_conn(uint16_t handle); -void ble_ll_conn_datalen_update(struct ble_ll_conn_sm *connsm, - struct ble_ll_len_req *req); +void ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm); /* Advertising interface */ int ble_ll_conn_slave_start(uint8_t *rxbuf, uint8_t pat, diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 33e607f69..fcd0e7a06 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -210,8 +210,14 @@ ble_ll_ctrl_len_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr) (ctrl_req.max_tx_time < BLE_LL_CONN_SUPP_TIME_MIN)) { rc = 1; } else { - /* Update the connection with the new parameters */ - ble_ll_conn_datalen_update(connsm, &ctrl_req); + /* Update parameters */ + connsm->rem_max_rx_time = ctrl_req.max_rx_time; + connsm->rem_max_tx_time = ctrl_req.max_tx_time; + connsm->rem_max_rx_octets = ctrl_req.max_rx_bytes; + connsm->rem_max_tx_octets = ctrl_req.max_tx_bytes; + + /* Recalculate effective connection parameters */ + ble_ll_conn_update_eff_data_len(connsm); rc = 0; }