From 9b3feb5ee12e4d50b86c522b2e8b0780ca6bc291 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 5 Aug 2022 14:04:26 +0200 Subject: [PATCH] nimble/ll: Use OTA max rx time for connection event calculations Using effective max rx time for connection event calculations is not optimal since it's possible that time to rx packet with max octets payload is shorter that effective max rx time. Instead, we should calculate time it takes to rx packaet with effectiva max octets payload and use it if less than effective max rx time. --- .../include/controller/ble_ll_conn.h | 1 + nimble/controller/src/ble_ll_conn.c | 28 +++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 413ae9ecb..3872406f1 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -227,6 +227,7 @@ struct ble_ll_conn_sm uint16_t rem_max_rx_time; uint16_t eff_max_tx_time; uint16_t eff_max_rx_time; + uint16_t ota_max_rx_time; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) uint16_t host_req_max_tx_time; #endif diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 564c6cf8c..2a8c0c05b 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1259,13 +1259,13 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) tx_phy_mode = BLE_PHY_MODE_1M; #endif - ticks = (BLE_LL_IFS * 3) + connsm->eff_max_rx_time + + ticks = (BLE_LL_IFS * 3) + connsm->ota_max_rx_time + ble_ll_pdu_tx_time_get(next_txlen, tx_phy_mode) + ble_ll_pdu_tx_time_get(cur_txlen, tx_phy_mode); #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { - ticks += (BLE_LL_IFS + connsm->eff_max_rx_time); + ticks += (BLE_LL_IFS + connsm->ota_max_rx_time); } #endif @@ -1674,7 +1674,7 @@ ble_ll_conn_can_send_next_pdu(struct ble_ll_conn_sm *connsm, uint32_t begtime, /* We will send empty pdu (just a LL header) */ usecs = ble_ll_pdu_tx_time_get(0, tx_phy_mode); } - usecs += (BLE_LL_IFS * 2) + connsm->eff_max_rx_time; + usecs += (BLE_LL_IFS * 2) + connsm->ota_max_rx_time; ticks = (uint32_t)(next_sched_time - begtime); allowed_usecs = ble_ll_tmr_t2u(ticks); @@ -1981,6 +1981,7 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) connsm->rem_max_rx_time = BLE_LL_CONN_SUPP_TIME_MIN; connsm->eff_max_tx_time = BLE_LL_CONN_SUPP_TIME_MIN; connsm->eff_max_rx_time = BLE_LL_CONN_SUPP_TIME_MIN; + connsm->ota_max_rx_time = BLE_LL_CONN_SUPP_TIME_MIN; connsm->rem_max_tx_octets = BLE_LL_CONN_SUPP_BYTES_MIN; connsm->rem_max_rx_octets = BLE_LL_CONN_SUPP_BYTES_MIN; connsm->eff_max_tx_octets = BLE_LL_CONN_SUPP_BYTES_MIN; @@ -2013,9 +2014,12 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) void ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm) { + int ota_max_rx_time_calc = 0; int send_event; uint16_t eff_time; uint16_t eff_bytes; + uint16_t ota_time; + uint8_t phy_mode; /* Assume no event sent */ send_event = 0; @@ -2029,6 +2033,7 @@ ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm) #endif if (eff_time != connsm->eff_max_rx_time) { connsm->eff_max_rx_time = eff_time; + ota_max_rx_time_calc = 1; send_event = 1; } eff_time = min(connsm->rem_max_rx_time, connsm->max_tx_time); @@ -2044,6 +2049,7 @@ ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm) eff_bytes = min(connsm->rem_max_tx_octets, connsm->max_rx_octets); if (eff_bytes != connsm->eff_max_rx_octets) { connsm->eff_max_rx_octets = eff_bytes; + ota_max_rx_time_calc = 1; send_event = 1; } eff_bytes = min(connsm->rem_max_rx_octets, connsm->max_tx_octets); @@ -2052,6 +2058,22 @@ ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm) send_event = 1; } + /* If effective rx octets and/or time value changes, we need to calculate + * actual OTA max rx time, i.e. lesser of effective max rx time and rx time + * of PDU containing max rx octets of payload. This is then used to calculate + * connection events timings. + */ + if (ota_max_rx_time_calc) { +#if BLE_LL_BT5_PHY_SUPPORTED + phy_mode = ble_ll_phy_to_phy_mode(connsm->phy_data.cur_rx_phy, + BLE_HCI_LE_PHY_CODED_S8_PREF); +#else + phy_mode = BLE_PHY_MODE_1M; +#endif + ota_time = ble_ll_pdu_tx_time_get(connsm->eff_max_rx_octets, phy_mode); + connsm->ota_max_rx_time = min(ota_time, connsm->eff_max_rx_time); + } + if (send_event) { ble_ll_hci_ev_datalen_chg(connsm); }