Bluetooth: controller: Fix post DLE/PHY update event length
Fix the controller implementation to perform connection event length reservation based on the completed Data Length Update and/or PHY Update Procedure. This fix with avoid states/roles from stepping on each others event length. Connection would have supervision timed out or have stalled data transmissions due to insufficient reserved air time. Relates to #15171. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
70a89876d0
commit
fa4b4932b9
2 changed files with 98 additions and 17 deletions
|
@ -276,11 +276,11 @@ static void ticker_update_adv_assert(u32_t status, void *params);
|
|||
#if defined(CONFIG_BT_CONN)
|
||||
#if defined(CONFIG_BT_PERIPHERAL)
|
||||
static void ticker_stop_adv_assert(u32_t status, void *params);
|
||||
static void ticker_update_slave_assert(u32_t status, void *params);
|
||||
#endif /* CONFIG_BT_PERIPHERAL */
|
||||
#if defined(CONFIG_BT_CENTRAL)
|
||||
static void ticker_stop_scan_assert(u32_t status, void *params);
|
||||
#endif /* CONFIG_BT_CENTRAL */
|
||||
static void ticker_update_conn_assert(u32_t status, void *params);
|
||||
static void ticker_stop_conn_assert(u32_t status, void *params);
|
||||
static void ticker_start_conn_assert(u32_t status, void *params);
|
||||
#endif /* CONFIG_BT_CONN */
|
||||
|
@ -2380,6 +2380,11 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx,
|
|||
eff_tx_time;
|
||||
#endif /* CONFIG_BT_CTLR_PHY */
|
||||
|
||||
/* flag an event length update*/
|
||||
_radio.conn_curr->evt_len_upd = 1U;
|
||||
_radio.conn_curr->evt_len_adv = 1U;
|
||||
|
||||
/* Request Rx buffer resize */
|
||||
_radio.conn_curr->llcp_length.ack =
|
||||
(_radio.conn_curr->llcp_length.req - 1);
|
||||
_radio.conn_curr->llcp_length.state =
|
||||
|
@ -2420,6 +2425,10 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx,
|
|||
_radio.conn_curr->max_tx_time = eff_tx_time;
|
||||
#endif /* CONFIG_BT_CTLR_PHY */
|
||||
|
||||
/* flag an event length update*/
|
||||
_radio.conn_curr->evt_len_upd = 1U;
|
||||
_radio.conn_curr->evt_len_adv = 0U;
|
||||
|
||||
/* prepare event params */
|
||||
lr->max_rx_octets = eff_rx_octets;
|
||||
lr->max_tx_octets = eff_tx_octets;
|
||||
|
@ -4318,8 +4327,10 @@ static inline u32_t isr_close_scan(void)
|
|||
#if defined(CONFIG_BT_CONN)
|
||||
static inline void isr_close_conn(void)
|
||||
{
|
||||
u32_t ticks_drift_plus;
|
||||
u32_t ticks_drift_minus;
|
||||
u32_t ticks_drift_plus;
|
||||
u32_t ticks_slot_minus;
|
||||
u32_t ticks_slot_plus;
|
||||
u16_t latency_event;
|
||||
u16_t elapsed_event;
|
||||
u8_t reason_peer;
|
||||
|
@ -4345,10 +4356,12 @@ static inline void isr_close_conn(void)
|
|||
return;
|
||||
}
|
||||
|
||||
ticks_drift_plus = 0U;
|
||||
ticks_drift_minus = 0U;
|
||||
latency_event = _radio.conn_curr->latency_event;
|
||||
elapsed_event = latency_event + 1;
|
||||
ticks_drift_minus = 0U;
|
||||
ticks_drift_plus = 0U;
|
||||
ticks_slot_minus = 0U;
|
||||
ticks_slot_plus = 0U;
|
||||
|
||||
/* calculate drift if anchor point sync-ed */
|
||||
if (_radio.packet_counter &&
|
||||
|
@ -4579,8 +4592,65 @@ static inline void isr_close_conn(void)
|
|||
lazy = _radio.conn_curr->latency_event + 1;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_PERIPHERAL)
|
||||
#if defined(CONFIG_BT_CTLR_DATA_LENGTH) || defined(CONFIG_BT_CTLR_PHY)
|
||||
/* TODO: Design connection event length use. for only reserve for single
|
||||
* trx.
|
||||
*/
|
||||
if (_radio.conn_curr->evt_len_upd) {
|
||||
u32_t ready_delay, rx_time, tx_time, ticks_slot;
|
||||
struct connection *conn = _radio.conn_curr;
|
||||
|
||||
/* Reset event length update flag */
|
||||
conn->evt_len_upd = 0U;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
ready_delay = (conn->role) ?
|
||||
radio_rx_ready_delay_get(conn->phy_rx, 1) :
|
||||
radio_tx_ready_delay_get(conn->phy_tx,
|
||||
conn->phy_flags);
|
||||
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
|
||||
tx_time = conn->max_tx_time;
|
||||
if (conn->evt_len_adv) {
|
||||
rx_time = conn->llcp_length.rx_time;
|
||||
} else {
|
||||
rx_time = conn->max_rx_time;
|
||||
}
|
||||
#else /* !CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
tx_time = MAX(RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0),
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN,
|
||||
conn->phy_tx));
|
||||
rx_time = MAX(RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0),
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN,
|
||||
conn->phy_rx));
|
||||
#endif /* !CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
#else /* !CONFIG_BT_CTLR_PHY */
|
||||
ready_delay = (conn->role) ?
|
||||
radio_rx_ready_delay_get(0, 0) :
|
||||
radio_tx_ready_delay_get(0, 0);
|
||||
tx_time = RADIO_PKT_TIME(conn->max_tx_octets, 0);
|
||||
if (conn->evt_len_adv) {
|
||||
rx_time = RADIO_PKT_TIME(conn->llcp_length.rx_octets,
|
||||
0);
|
||||
} else {
|
||||
rx_time = RADIO_PKT_TIME(conn->max_rx_octets, 0);
|
||||
}
|
||||
#endif /* !CONFIG_BT_CTLR_PHY */
|
||||
|
||||
ticks_slot = HAL_TICKER_US_TO_TICKS(RADIO_TICKER_START_PART_US +
|
||||
ready_delay + RADIO_TIFS +
|
||||
rx_time + tx_time + 4);
|
||||
|
||||
if (ticks_slot > conn->hdr.ticks_slot) {
|
||||
ticks_slot_plus = ticks_slot - conn->hdr.ticks_slot;
|
||||
} else {
|
||||
ticks_slot_minus = conn->hdr.ticks_slot - ticks_slot;
|
||||
}
|
||||
conn->hdr.ticks_slot = ticks_slot;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((ticks_drift_plus != 0) || (ticks_drift_minus != 0) ||
|
||||
(ticks_slot_plus != 0) || (ticks_slot_minus != 0) ||
|
||||
(lazy != 0) || (force != 0)) {
|
||||
u32_t ticker_status;
|
||||
u8_t ticker_id = RADIO_TICKER_ID_FIRST_CONNECTION +
|
||||
|
@ -4596,14 +4666,14 @@ static inline void isr_close_conn(void)
|
|||
ticker_update(RADIO_TICKER_INSTANCE_ID_RADIO,
|
||||
RADIO_TICKER_USER_ID_WORKER,
|
||||
ticker_id,
|
||||
ticks_drift_plus, ticks_drift_minus, 0, 0,
|
||||
lazy, force, ticker_update_slave_assert,
|
||||
ticks_drift_plus, ticks_drift_minus,
|
||||
ticks_slot_plus, ticks_slot_minus,
|
||||
lazy, force, ticker_update_conn_assert,
|
||||
(void *)(u32_t)ticker_id);
|
||||
LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
|
||||
(ticker_status == TICKER_STATUS_BUSY) ||
|
||||
(_radio.ticker_id_stop == ticker_id));
|
||||
}
|
||||
#endif /* CONFIG_BT_PERIPHERAL */
|
||||
}
|
||||
#endif /* CONFIG_BT_CONN */
|
||||
|
||||
|
@ -4809,15 +4879,6 @@ static void ticker_stop_adv_assert(u32_t status, void *params)
|
|||
LL_ASSERT(_radio.ticker_id_prepare != RADIO_TICKER_ID_ADV);
|
||||
}
|
||||
}
|
||||
|
||||
static void ticker_update_slave_assert(u32_t status, void *params)
|
||||
{
|
||||
u8_t ticker_id = (u32_t)params & 0xFF;
|
||||
|
||||
LL_ASSERT((status == TICKER_STATUS_SUCCESS) ||
|
||||
(_radio.ticker_id_stop == ticker_id) ||
|
||||
(_radio.ticker_id_upd == ticker_id));
|
||||
}
|
||||
#endif /* CONFIG_BT_PERIPHERAL */
|
||||
|
||||
#if defined(CONFIG_BT_CENTRAL)
|
||||
|
@ -4847,6 +4908,15 @@ static void ticker_stop_scan_assert(u32_t status, void *params)
|
|||
}
|
||||
#endif /* CONFIG_BT_CENTRAL */
|
||||
|
||||
static void ticker_update_conn_assert(u32_t status, void *params)
|
||||
{
|
||||
u8_t ticker_id = (u32_t)params & 0xFF;
|
||||
|
||||
LL_ASSERT((status == TICKER_STATUS_SUCCESS) ||
|
||||
(_radio.ticker_id_stop == ticker_id) ||
|
||||
(_radio.ticker_id_upd == ticker_id));
|
||||
}
|
||||
|
||||
static void ticker_stop_conn_assert(u32_t status, void *params)
|
||||
{
|
||||
LL_ASSERT(status == TICKER_STATUS_SUCCESS);
|
||||
|
@ -8105,6 +8175,9 @@ static inline int event_len_prep(struct connection *conn)
|
|||
conn->max_rx_time = conn->llcp_length.rx_time;
|
||||
#endif /* CONFIG_BT_CTLR_PHY */
|
||||
|
||||
/* Reset event length update advanced flag */
|
||||
conn->evt_len_adv = 0U;
|
||||
|
||||
/** TODO This design is exception as memory initialization
|
||||
* and allocation is done in radio context here, breaking the
|
||||
* rule that the rx buffers are allocated in application
|
||||
|
@ -8492,6 +8565,9 @@ static inline void event_phy_upd_ind_prep(struct connection *conn,
|
|||
conn->max_tx_time = eff_tx_time;
|
||||
conn->max_rx_time = eff_rx_time;
|
||||
|
||||
/* flag an event length update*/
|
||||
conn->evt_len_upd = 1U;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
|
||||
/* Prepare the rx packet structure */
|
||||
node_rx = packet_rx_reserve_get(2);
|
||||
|
|
|
@ -295,6 +295,11 @@ struct connection {
|
|||
/* Detect empty L2CAP start frame */
|
||||
u8_t start_empty:1;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_DATA_LENGTH) || defined(CONFIG_BT_CTLR_PHY)
|
||||
u8_t evt_len_upd:1;
|
||||
u8_t evt_len_adv:1;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_CONN_RSSI)
|
||||
u8_t rssi_latest;
|
||||
u8_t rssi_reported;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue