Skip to content

Commit b7bbe4b

Browse files
ppryga-nordiccarlescufi
authored andcommitted
Bluetooth: Controller: Fix per adv chain broken after per adv re-enable
If there is enabled support for ADI in periodic advertising and periodic advertising uses chained PDUs there is an assert when periodic advertising is re-enabled. There is missing a code that will set a chain for PDU with updated ADI field. The commit fixes the issue. Signed-off-by: Piotr Pryga <[email protected]>
1 parent 26e95fa commit b7bbe4b

File tree

1 file changed

+34
-12
lines changed

1 file changed

+34
-12
lines changed

subsys/bluetooth/controller/ll_sw/ull_adv_sync.c

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
6464
uint32_t remainder, uint16_t lazy, uint8_t force,
6565
void *param);
6666
static void ticker_op_cb(uint32_t status, void *param);
67+
static void adv_sync_pdu_chain_check_and_duplicate(struct pdu_adv *new_pdu,
68+
struct pdu_adv *prev_pdu);
6769

6870
static struct ll_adv_sync_set ll_adv_sync_pool[CONFIG_BT_CTLR_ADV_SYNC_SET];
6971
static void *adv_sync_free;
@@ -481,23 +483,12 @@ uint8_t ll_adv_sync_ad_data_set(uint8_t handle, uint8_t op, uint8_t len,
481483
return err;
482484
}
483485

484-
#if defined(CONFIG_BT_CTLR_ADV_PDU_LINK)
485486
/* alloc() will return the same PDU as peek() in case there was PDU
486487
* queued but not switched to current before alloc() - no need to deal
487488
* with chain as it's already there. In other case we need to duplicate
488489
* chain from current PDU and append it to new PDU.
489490
*/
490-
if (pdu != pdu_prev) {
491-
struct pdu_adv *next, *next_dup;
492-
493-
LL_ASSERT(lll_adv_pdu_linked_next_get(pdu) == NULL);
494-
495-
next = lll_adv_pdu_linked_next_get(pdu_prev);
496-
next_dup = adv_sync_pdu_duplicate_chain(next);
497-
498-
lll_adv_pdu_linked_append(next_dup, pdu);
499-
}
500-
#endif /* CONFIG_BT_CTLR_ADV_PDU_LINK */
491+
adv_sync_pdu_chain_check_and_duplicate(pdu, pdu_prev);
501492

502493
sync = HDR_LLL2ULL(lll_sync);
503494
if (sync->is_started) {
@@ -605,6 +596,13 @@ uint8_t ll_adv_sync_enable(uint8_t handle, uint8_t enable)
605596
if (err) {
606597
return err;
607598
}
599+
600+
/* alloc() will return the same PDU as peek() in case there was PDU
601+
* queued but not switched to current before alloc() - no need to deal
602+
* with chain as it's already there. In other case we need to duplicate
603+
* chain from current PDU and append it to new PDU.
604+
*/
605+
adv_sync_pdu_chain_check_and_duplicate(pdu, pdu_prev);
608606
}
609607

610608
if (adv->is_enabled && !sync->is_started) {
@@ -1818,3 +1816,27 @@ static void ticker_op_cb(uint32_t status, void *param)
18181816
{
18191817
*((uint32_t volatile *)param) = status;
18201818
}
1819+
1820+
/**
1821+
* @brief Set a periodic advertising chained PDUs in a new periodic advertising data if there are
1822+
* chained PDUs in former periodic advertising data.
1823+
*
1824+
* @param pdu_new Pointer to new pdu_adv where to add chained pdu_adv.
1825+
* @param pdu_prev Pointer to former pdu_adv where to add chained pdu_adv.
1826+
*/
1827+
static void adv_sync_pdu_chain_check_and_duplicate(struct pdu_adv *pdu_new,
1828+
struct pdu_adv *pdu_prev)
1829+
{
1830+
#if defined(CONFIG_BT_CTLR_ADV_PDU_LINK)
1831+
if (pdu_new != pdu_prev) {
1832+
struct pdu_adv *next, *next_dup;
1833+
1834+
LL_ASSERT(lll_adv_pdu_linked_next_get(pdu_new) == NULL);
1835+
1836+
next = lll_adv_pdu_linked_next_get(pdu_prev);
1837+
next_dup = adv_sync_pdu_duplicate_chain(next);
1838+
1839+
lll_adv_pdu_linked_append(next_dup, pdu_new);
1840+
}
1841+
#endif /* CONFIG_BT_CTLR_ADV_PDU_LINK */
1842+
}

0 commit comments

Comments
 (0)