Bluetooth: controller: Sync ISO Establishment fixes

- Introduce variable in lll_sync_iso for sync establishment timeout
- Introduce estab_failed flag in event_done_extra struct to convey
  establishment failure from LLL.
- Fix ull_sync_iso_estab_done always sending success
- Return correct HCI error depending on prepare state

Signed-off-by: Morten Priess <mtpr@oticon.com>
This commit is contained in:
Morten Priess 2024-02-23 15:33:42 +01:00 committed by Alberto Escolar
commit 425dcc4678
4 changed files with 32 additions and 14 deletions

View file

@ -503,6 +503,9 @@ struct event_done_extra {
struct {
uint16_t trx_cnt;
uint8_t crc_valid:1;
#if defined(CONFIG_BT_CTLR_SYNC_ISO)
uint8_t estab_failed:1;
#endif /* CONFIG_BT_CTLR_SYNC_ISO */
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING) && \
defined(CONFIG_BT_CTLR_CTEINLINE_SUPPORT)
/* Used to inform ULL that periodic

View file

@ -55,6 +55,8 @@ struct lll_sync_iso {
uint8_t stream_curr:5;
uint8_t establish_events:3;
uint8_t next_chan_use;
/* Encryption */

View file

@ -456,6 +456,7 @@ static void isr_rx_estab(void *param)
LL_ASSERT(e);
e->type = EVENT_DONE_EXTRA_TYPE_SYNC_ISO_ESTAB;
e->estab_failed = 0U;
e->trx_cnt = trx_cnt;
e->crc_valid = crc_ok;

View file

@ -464,6 +464,9 @@ void ull_sync_iso_setup(struct ll_sync_iso_set *sync_iso,
lll->payload_count |= (uint64_t)bi->payload_count_framing[3] << 24;
lll->payload_count |= (uint64_t)(bi->payload_count_framing[4] & 0x7f) << 32;
/* Set establishment event countdown */
lll->establish_events = CONN_ESTAB_COUNTDOWN;
if (lll->enc && (bi_size == PDU_BIG_INFO_ENCRYPTED_SIZE)) {
const uint8_t BIG3[4] = {0x33, 0x47, 0x49, 0x42};
struct ccm *ccm_rx;
@ -651,22 +654,25 @@ void ull_sync_iso_estab_done(struct node_rx_event_done *done)
struct node_rx_sync_iso *se;
struct node_rx_pdu *rx;
/* switch to normal prepare */
mfy_lll_prepare.fp = lll_sync_iso_prepare;
if (done->extra.trx_cnt || done->extra.estab_failed) {
/* Switch to normal prepare */
mfy_lll_prepare.fp = lll_sync_iso_prepare;
/* Get reference to ULL context */
sync_iso = CONTAINER_OF(done->param, struct ll_sync_iso_set, ull);
/* Get reference to ULL context */
sync_iso = CONTAINER_OF(done->param, struct ll_sync_iso_set, ull);
/* Prepare BIG Sync Established */
rx = (void *)sync_iso->sync->iso.node_rx_estab;
rx->hdr.type = NODE_RX_TYPE_SYNC_ISO;
rx->hdr.handle = sync_iso_handle_get(sync_iso);
rx->rx_ftr.param = sync_iso;
/* Prepare BIG Sync Established */
rx = (void *)sync_iso->sync->iso.node_rx_estab;
rx->hdr.type = NODE_RX_TYPE_SYNC_ISO;
rx->hdr.handle = sync_iso_handle_get(sync_iso);
rx->rx_ftr.param = sync_iso;
se = (void *)rx->pdu;
se->status = BT_HCI_ERR_SUCCESS;
se = (void *)rx->pdu;
se->status = done->extra.estab_failed ?
BT_HCI_ERR_CONN_FAIL_TO_ESTAB : BT_HCI_ERR_SUCCESS;
ll_rx_put_sched(rx->hdr.link, rx);
ll_rx_put_sched(rx->hdr.link, rx);
}
ull_sync_iso_done(done);
}
@ -871,9 +877,15 @@ static void timeout_cleanup(struct ll_sync_iso_set *sync_iso)
/* Populate the Sync Lost which will be enqueued in disabled_cb */
rx = (void *)&sync_iso->node_rx_lost;
rx->hdr.handle = sync_iso_handle_get(sync_iso);
rx->hdr.type = NODE_RX_TYPE_SYNC_ISO_LOST;
rx->rx_ftr.param = sync_iso;
*((uint8_t *)rx->pdu) = BT_HCI_ERR_CONN_TIMEOUT;
if (mfy_lll_prepare.fp == lll_sync_iso_prepare) {
rx->hdr.type = NODE_RX_TYPE_SYNC_ISO_LOST;
*((uint8_t *)rx->pdu) = BT_HCI_ERR_CONN_TIMEOUT;
} else {
rx->hdr.type = NODE_RX_TYPE_SYNC_ISO;
*((uint8_t *)rx->pdu) = BT_HCI_ERR_CONN_FAIL_TO_ESTAB;
}
/* Stop Sync ISO Ticker */
handle = sync_iso_handle_get(sync_iso);