Bluetooth: Controller: Fix BIS payload sliding window overrun check

Fix BIS implementation for checking overrun of the BIS PDU
sliding window buffer overrun.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2023-09-26 22:41:33 +02:00 committed by Carles Cufí
commit 7af967a2f5
3 changed files with 42 additions and 14 deletions

View file

@ -74,7 +74,6 @@ struct lll_sync_iso {
struct node_rx_pdu *payload[BT_CTLR_SYNC_ISO_STREAM_MAX]
[PDU_BIG_PAYLOAD_COUNT_MAX];
uint8_t payload_count_max;
uint8_t payload_head;
uint8_t payload_tail;
uint32_t window_widening_periodic_us;

View file

@ -489,7 +489,6 @@ static void isr_rx(void *param)
uint8_t access_addr[4];
uint16_t data_chan_id;
uint8_t data_chan_use;
uint8_t payload_index;
uint8_t crc_init[3];
uint8_t rssi_ready;
uint32_t start_us;
@ -556,6 +555,8 @@ static void isr_rx(void *param)
if (crc_ok) {
struct lll_sync_iso_stream *sync_stream;
uint16_t stream_handle;
uint8_t payload_offset;
uint8_t payload_index;
struct pdu_bis *pdu;
/* Check if Control Subevent being received */
@ -593,21 +594,28 @@ static void isr_rx(void *param)
/* TODO: check same CSSN is used in every subevent */
}
/* calculate the payload index in the sliding window */
payload_index = lll->payload_tail + (lll->bn_curr - 1U) +
(lll->ptc_curr * lll->pto);
/* Check payload buffer overflow */
payload_offset = (lll->bn_curr - 1U) +
(lll->ptc_curr * lll->pto);
if (payload_offset > lll->payload_count_max) {
goto isr_rx_done;
}
/* Calculate the payload index in the sliding window */
payload_index = lll->payload_tail + payload_offset;
if (payload_index >= lll->payload_count_max) {
payload_index -= lll->payload_count_max;
}
/* Get reference to stream context */
stream_handle = lll->stream_handle[lll->stream_curr];
sync_stream = ull_sync_iso_lll_stream_get(stream_handle);
/* store the received PDU */
/* Store the received PDU if selected stream and not already
* received (say in previous event as pre-transmitted PDU.
*/
if ((lll->bis_curr == sync_stream->bis_index) && pdu->len &&
!lll->payload[bis_idx][payload_index] &&
((payload_index >= lll->payload_tail) ||
(payload_index < lll->payload_head))) {
!lll->payload[bis_idx][payload_index]) {
uint16_t handle;
if (lll->enc) {
@ -644,10 +652,23 @@ isr_rx_find_subevent:
/* Find the next (bn_curr)th subevent to receive PDU */
while (lll->bn_curr < lll->bn) {
uint8_t payload_offset;
uint8_t payload_index;
/* Next burst number to check for reception required */
lll->bn_curr++;
/* Check payload buffer overflow */
payload_offset = (lll->bn_curr - 1U);
if (payload_offset > lll->payload_count_max) {
/* (bn_curr)th Rx PDU skip subevent */
skipped++;
continue;
}
/* Find the index of the (bn_curr)th Rx PDU buffer */
payload_index = lll->payload_tail + (lll->bn_curr - 1U);
payload_index = lll->payload_tail + payload_offset;
if (payload_index >= lll->payload_count_max) {
payload_index -= lll->payload_count_max;
}
@ -667,6 +688,11 @@ isr_rx_find_subevent:
/* Find the next repetition (irc_curr)th subevent to receive PDU */
if (lll->irc_curr < lll->irc) {
if (!new_burst) {
uint8_t payload_index;
/* Increment to next repetition count and be at first
* burst count for it.
*/
lll->bn_curr = 1U;
lll->irc_curr++;
@ -715,6 +741,10 @@ isr_rx_find_subevent:
if (lll->ptc_curr < lll->ptc) {
lll->ptc_curr++;
/* TODO: optimize to skip pre-transmission subevent in case
* of insufficient buffers in sliding window.
*/
/* Receive the (ptc_curr)th Rx PDU of bis_curr */
bis = lll->bis_curr;
@ -733,6 +763,7 @@ isr_rx_find_subevent:
stream_handle = lll->stream_handle[lll->stream_curr];
sync_stream = ull_sync_iso_lll_stream_get(stream_handle);
if (sync_stream->bis_index <= lll->num_bis) {
uint8_t payload_index;
uint8_t bis_idx_new;
lll->bis_curr = sync_stream->bis_index;
@ -1058,8 +1089,7 @@ static void isr_rx_done(void *param)
bn = lll->bn;
while (bn--) {
if (lll->payload[bis_idx][payload_tail]) {
node_rx =
lll->payload[bis_idx][payload_tail];
node_rx = lll->payload[bis_idx][payload_tail];
lll->payload[bis_idx][payload_tail] = NULL;
iso_rx_put(node_rx->hdr.link, node_rx);

View file

@ -454,10 +454,9 @@ void ull_sync_iso_setup(struct ll_sync_iso_set *sync_iso,
/* Initialize payload pointers */
lll->payload_count_max = PDU_BIG_PAYLOAD_COUNT_MAX;
lll->payload_head = 0U;
lll->payload_tail = 0U;
for (int i = 0; i < CONFIG_BT_CTLR_SYNC_ISO_STREAM_MAX; i++) {
for (int j = 0; j < PDU_BIG_PAYLOAD_COUNT_MAX; j++) {
for (int j = 0; j < lll->payload_count_max; j++) {
lll->payload[i][j] = NULL;
}
}