diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index 76456b10e..b0da1e736 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -303,6 +303,7 @@ void ble_ll_ctrl_phy_update_proc_complete(struct ble_ll_conn_sm *connsm); void ble_ll_ctrl_initiate_dle(struct ble_ll_conn_sm *connsm); void ble_ll_hci_ev_send_vendor_err(const char *file, uint32_t line); +uint8_t ble_ll_ctrl_phy_tx_transition_get(uint8_t phy_mask); uint8_t ble_ll_ctrl_phy_from_phy_mask(uint8_t phy_mask); #ifdef __cplusplus diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index a63b90403..1ff60b837 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3793,15 +3793,11 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) /* Adjust payload for max TX time and octets */ #if (BLE_LL_BT5_PHY_SUPPORTED == 1) - if (is_ctrl && (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) - && (opcode == BLE_LL_CTRL_PHY_UPDATE_IND)) { - if (rxbuf[3] & BLE_PHY_MASK_1M) { - connsm->phy_tx_transition = BLE_PHY_1M; - } else if (rxbuf[3] & BLE_PHY_MASK_2M) { - connsm->phy_tx_transition = BLE_PHY_2M; - } else if (rxbuf[3] & BLE_PHY_MASK_CODED) { - connsm->phy_tx_transition = BLE_PHY_CODED; - } + if (is_ctrl && + (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) && + (opcode == BLE_LL_CTRL_PHY_UPDATE_IND)) { + connsm->phy_tx_transition = + ble_ll_ctrl_phy_tx_transition_get(rxbuf[3]); } #endif diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 81608ac25..33e607f69 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -554,6 +554,25 @@ ble_ll_ctrl_start_rsp_timer(struct ble_ll_conn_sm *connsm) } #if (BLE_LL_BT5_PHY_SUPPORTED == 1) +uint8_t +ble_ll_ctrl_phy_tx_transition_get(uint8_t phy_mask) +{ + /* + * Evaluate PHYs in transition starting from the one with longest TX time + * so we select the one that allows shortest payload to be sent. This is + * to make sure we do not violate timing restriction on new PHY. + */ + if (phy_mask & BLE_PHY_MASK_CODED) { + return BLE_PHY_CODED; + } else if (phy_mask & BLE_PHY_MASK_1M) { + return BLE_PHY_1M; + } else if (phy_mask & BLE_PHY_MASK_2M) { + return BLE_PHY_2M; + } + + return 0; +} + void ble_ll_ctrl_phy_update_proc_complete(struct ble_ll_conn_sm *connsm) { @@ -855,13 +874,7 @@ ble_ll_ctrl_rx_phy_req(struct ble_ll_conn_sm *connsm, uint8_t *req, ble_ll_ctrl_phy_req_rsp_make(connsm, rsp); rsp_opcode = BLE_LL_CTRL_PHY_RSP; - if (rsp[0] & BLE_PHY_MASK_1M) { - connsm->phy_tx_transition = BLE_PHY_1M; - } else if (rsp[0] & BLE_PHY_MASK_2M) { - connsm->phy_tx_transition = BLE_PHY_2M; - } else if (rsp[0] & BLE_PHY_MASK_CODED) { - connsm->phy_tx_transition = BLE_PHY_CODED; - } + connsm->phy_tx_transition = ble_ll_ctrl_phy_tx_transition_get(req[1] | rsp[0]); /* Start response timer */ connsm->cur_ctrl_proc = BLE_LL_CTRL_PROC_PHY_UPDATE; @@ -2701,16 +2714,12 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) #endif #if (BLE_LL_BT5_PHY_SUPPORTED == 1) case BLE_LL_CTRL_PHY_REQ: - if (connsm->phy_data.req_pref_tx_phys_mask & BLE_PHY_MASK_1M) { - connsm->phy_tx_transition = BLE_PHY_1M; - } else if (connsm->phy_data.req_pref_tx_phys_mask & BLE_PHY_MASK_2M) { - connsm->phy_tx_transition = BLE_PHY_2M; - } else if (connsm->phy_data.req_pref_tx_phys_mask & BLE_PHY_MASK_CODED) { - connsm->phy_tx_transition = BLE_PHY_CODED; - } + connsm->phy_tx_transition = + ble_ll_ctrl_phy_tx_transition_get(connsm->phy_data.req_pref_tx_phys_mask); break; case BLE_LL_CTRL_PHY_UPDATE_IND: - connsm->phy_tx_transition = ble_ll_ctrl_phy_from_phy_mask(txpdu->om_data[2]); + connsm->phy_tx_transition = + ble_ll_ctrl_phy_tx_transition_get(txpdu->om_data[2]); break; #endif default: