Skip to content

Commit 300f3bd

Browse files
cvinayakgmarull
authored andcommitted
[nrf fromlist] Bluetooth: Controller: Fix periodic advertising re-enable assertion
When periodic advertising with chaining is re-enabled after changing interval or just re-enabled then the chain PDUs where not duplicated causing the LLL to assert detecting the presence of aux pointer but no linked chain PDUs. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]> (cherry picked from commit 3b9923267500e27ecec521fc8c939c435a60870d) Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent b82f57d commit 300f3bd

File tree

1 file changed

+64
-6
lines changed

1 file changed

+64
-6
lines changed

subsys/bluetooth/controller/ll_sw/ull_adv_sync.c

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,45 @@ uint8_t ll_adv_sync_param_set(uint8_t handle, uint16_t interval, uint16_t flags)
163163
}
164164
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
165165

166-
err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu, 0, 0, NULL);
167-
if (err) {
168-
return err;
169-
}
166+
#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK)
167+
/* Duplicate chain PDUs */
168+
do {
169+
struct pdu_adv *pdu_chain;
170+
171+
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK */
172+
err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu,
173+
0U, 0U, NULL);
174+
if (err) {
175+
return err;
176+
}
177+
178+
#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK)
179+
pdu_prev = lll_adv_pdu_linked_next_get(pdu_prev);
180+
pdu_chain = lll_adv_pdu_linked_next_get(pdu);
181+
182+
/* Allocate new chain PDU if required */
183+
if (pdu_prev) {
184+
/* Prior PDU chain allocation valid */
185+
if (pdu_chain) {
186+
pdu = pdu_chain;
187+
188+
continue;
189+
}
190+
191+
/* Get a new chain PDU */
192+
pdu_chain = lll_adv_pdu_alloc_pdu_adv();
193+
if (!pdu_chain) {
194+
return BT_HCI_ERR_INSUFFICIENT_RESOURCES;
195+
}
196+
197+
/* Link the chain PDU to parent PDU */
198+
lll_adv_pdu_linked_append(pdu_chain, pdu);
199+
200+
/* continue back to update the new PDU */
201+
pdu = pdu_chain;
202+
}
203+
} while (pdu_prev);
204+
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK */
170205

171206
lll_adv_sync_data_enqueue(lll_sync, ter_idx);
172207

@@ -751,7 +786,10 @@ uint8_t ll_adv_sync_enable(uint8_t handle, uint8_t enable)
751786
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
752787

753788
#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK)
789+
/* Update ADI while duplicating chain PDUs */
754790
do {
791+
struct pdu_adv *pdu_chain;
792+
755793
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK */
756794
err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev,
757795
pdu, hdr_add_fields,
@@ -763,9 +801,29 @@ uint8_t ll_adv_sync_enable(uint8_t handle, uint8_t enable)
763801

764802
#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK)
765803
pdu_prev = lll_adv_pdu_linked_next_get(pdu_prev);
766-
pdu = lll_adv_pdu_linked_next_get(pdu);
804+
pdu_chain = lll_adv_pdu_linked_next_get(pdu);
767805

768-
LL_ASSERT((pdu_prev && pdu) || (!pdu_prev && !pdu));
806+
/* Allocate new chain PDU if required */
807+
if (pdu_prev) {
808+
/* Prior PDU chain allocation valid */
809+
if (pdu_chain) {
810+
pdu = pdu_chain;
811+
812+
continue;
813+
}
814+
815+
/* Get a new chain PDU */
816+
pdu_chain = lll_adv_pdu_alloc_pdu_adv();
817+
if (!pdu_chain) {
818+
return BT_HCI_ERR_INSUFFICIENT_RESOURCES;
819+
}
820+
821+
/* Link the chain PDU to parent PDU */
822+
lll_adv_pdu_linked_append(pdu_chain, pdu);
823+
824+
/* continue back to update the new PDU */
825+
pdu = pdu_chain;
826+
}
769827
} while (pdu_prev);
770828
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK */
771829
}

0 commit comments

Comments
 (0)