Skip to content

Commit bd65231

Browse files
ppryga-nordiccfriedt
authored andcommitted
Bluetooth: controller: Fix ASSERT caused by ULL releasing chain PDUs
When CTE is enabled for periodic advertising and number of CTE is greater than number of PDUs in a chain, that are needed to transport advertising data, there are additional empty PDUs used for transport CTE. CTE transmission may be disabled when periodic advertising event is pending in LLL. rem_cte_info_from_per_adv_chain removed CTEInfo field from extended advertising header in chained PDUs. When there were found empty PDUs (created to transport CTE only), they were released from the chain that was currently used by LLL. That caused an assert in isr_tx handler due to broken advertising chain. The rem_cte_info_from_per_adv_chain may not relese PDUs that are in use by LLL. The PDUs may be released by LLL in prepare step when advertising pdu double buffer is swapped by lll_adv_sync_data_latest- _get. This PR fixes that issue. Signed-off-by: Piotr Pryga <[email protected]>
1 parent 701c560 commit bd65231

File tree

3 files changed

+17
-8
lines changed

3 files changed

+17
-8
lines changed

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_pdu.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ static inline void *lll_adv_sync_extra_data_peek(struct lll_adv_sync *lll)
178178
{
179179
return lll->data.extra_data[lll->data.last];
180180
}
181+
182+
static inline void *lll_adv_sync_extra_data_curr_get(struct lll_adv_sync *lll)
183+
{
184+
return lll->data.extra_data[lll->data.first];
185+
}
181186
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */
182187
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
183188
#endif /* CONFIG_BT_CTLR_ADV_EXT */

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_df.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ void lll_df_cte_tx_enable(struct lll_adv_sync *lll_sync, const struct pdu_adv *p
9292
if (ext_hdr->cte_info) {
9393
const struct lll_df_adv_cfg *df_cfg;
9494

95-
df_cfg = lll_adv_sync_extra_data_peek(lll_sync);
95+
df_cfg = lll_adv_sync_extra_data_curr_get(lll_sync);
9696
LL_ASSERT(df_cfg);
9797

9898
df_cte_tx_configure(df_cfg);

subsys/bluetooth/controller/ll_sw/ull_df.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -835,14 +835,18 @@ static uint8_t rem_cte_info_from_per_adv_chain(struct lll_adv_sync *lll_sync,
835835
while (pdu_chained) {
836836
if (pdu_ext_adv_is_empty_without_cte(pdu_chained)) {
837837
/* If there is an empty PDU then all remaining PDUs shoudl be released. */
838-
lll_adv_pdu_linked_release_all(pdu_chained);
838+
if (!new_chain) {
839+
lll_adv_pdu_linked_release_all(pdu_chained);
840+
841+
/* Set new end of chain in PDUs linked list. If pdu differs from
842+
* prev_pdu then it is already end of a chain. If it doesn't differ,
843+
* then chain end is changed in right place by use of pdu_prev.
844+
* That makes sure there is no PDU released twice (here and when LLL
845+
* swaps PDU buffers).
846+
*/
847+
lll_adv_pdu_linked_append(NULL, *pdu_prev);
848+
}
839849
pdu_chained = NULL;
840-
/* Set new end of chain in PDUs linked list. If pdu differs from prev_pdu
841-
* then it is alread end of a chain. If it doesn't differ, then chain end
842-
* is changed in rigth place by use of pdu_prev. That makes sure there
843-
* is no PDU released twice (here and when LLL swaps PDU buffers).
844-
*/
845-
lll_adv_pdu_linked_append(NULL, *pdu_prev);
846850
} else {
847851
/* Update one before pdu_chained */
848852
err = ull_adv_sync_pdu_set_clear(lll_sync, *pdu_prev, *pdu, 0,

0 commit comments

Comments
 (0)