Skip to content

Commit b4182ca

Browse files
cvinayakdleach02
authored andcommitted
Bluetooth: Controller: Fix Periodic Adv Chain PDU channel indices
Fix missing population of channel indices for Periodic Advertising Chain PDUs. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
1 parent 1eb74c4 commit b4182ca

File tree

3 files changed

+134
-11
lines changed

3 files changed

+134
-11
lines changed

subsys/bluetooth/controller/ll_sw/lll_adv.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ struct lll_adv_sync {
117117
struct lll_adv_pdu data;
118118

119119
#if defined(CONFIG_BT_CTLR_ADV_PDU_LINK)
120+
/* Implementation defined radio event counter to calculate chain
121+
* PDU channel index.
122+
*/
123+
uint16_t data_chan_counter;
124+
120125
struct pdu_adv *last_pdu;
121126
#endif /* CONFIG_BT_CTLR_ADV_PDU_LINK */
122127

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

Lines changed: 125 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ static void isr_done(void *param);
5151

5252
#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK)
5353
static void isr_tx(void *param);
54+
static int aux_ptr_get(struct pdu_adv *pdu, struct pdu_adv_aux_ptr **aux_ptr);
55+
static void chain_pdu_aux_ptr_chan_idx_set(struct lll_adv_sync *lll);
56+
static void aux_ptr_chan_idx_set(struct lll_adv_sync *lll, struct pdu_adv *pdu);
5457
static void switch_radio_complete_and_b2b_tx(const struct lll_adv_sync *lll, uint8_t phy_s);
5558
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
5659

@@ -181,22 +184,38 @@ static int prepare_cb(struct lll_prepare_param *p)
181184
cte_len_us = 0U;
182185
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX) */
183186

184-
radio_pkt_tx_set(pdu);
185-
186187
#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK)
187188
if (pdu->adv_ext_ind.ext_hdr_len && pdu->adv_ext_ind.ext_hdr.aux_ptr) {
189+
/* Set the last used auxiliary PDU for transmission */
188190
lll->last_pdu = pdu;
189191

192+
/* Populate chan idx for AUX_ADV_IND PDU */
193+
aux_ptr_chan_idx_set(lll, pdu);
194+
190195
radio_isr_set(isr_tx, lll);
191196
radio_tmr_tifs_set(EVENT_SYNC_B2B_MAFS_US);
192197
switch_radio_complete_and_b2b_tx(lll, phy_s);
193-
} else
194-
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
198+
} else {
199+
/* No chain PDU */
200+
lll->last_pdu = NULL;
201+
202+
#else /* !CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
195203
{
204+
#endif /* !CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
205+
196206
radio_isr_set(isr_done, lll);
197207
radio_switch_complete_and_disable();
198208
}
199209

210+
#if defined(CONFIG_BT_CTLR_ADV_ISO) && defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
211+
if (lll->iso) {
212+
ull_adv_iso_lll_biginfo_fill(pdu, lll);
213+
}
214+
#endif /* CONFIG_BT_CTLR_ADV_ISO && CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
215+
216+
/* Set the Radio Tx Packet */
217+
radio_pkt_tx_set(pdu);
218+
200219
ticks_at_event = p->ticks_at_expire;
201220
ull = HDR_LLL2ULL(lll);
202221
ticks_at_event += lll_event_offset_get(ull);
@@ -253,11 +272,10 @@ static int prepare_cb(struct lll_prepare_param *p)
253272
}
254273
#endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */
255274

256-
#if defined(CONFIG_BT_CTLR_ADV_ISO) && defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
257-
if (lll->iso) {
258-
ull_adv_iso_lll_biginfo_fill(pdu, lll);
259-
}
260-
#endif /* CONFIG_BT_CTLR_ADV_ISO && CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
275+
#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK)
276+
/* Populate chan idx for AUX_CHAIN_IND PDU */
277+
chain_pdu_aux_ptr_chan_idx_set(lll);
278+
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
261279

262280
ret = lll_prepare_done(lll);
263281
LL_ASSERT(!ret);
@@ -332,10 +350,12 @@ static void isr_done(void *param)
332350
#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK)
333351
static void isr_tx(void *param)
334352
{
353+
struct pdu_adv_aux_ptr *aux_ptr;
335354
struct lll_adv_sync *lll_sync;
336355
struct pdu_adv *pdu;
337356
struct lll_adv *lll;
338357
uint32_t cte_len_us;
358+
int err;
339359

340360
if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
341361
lll_prof_latency_capture();
@@ -344,14 +364,22 @@ static void isr_tx(void *param)
344364
/* Clear radio tx status and events */
345365
lll_isr_tx_status_reset();
346366

367+
/* Get reference to sync and primary advertising LLL contexts */
347368
lll_sync = param;
348369
lll = lll_sync->adv;
349370

350-
/* FIXME: Use implementation defined channel index */
351-
lll_chan_set(0);
371+
/* Get reference to aux pointer structure */
372+
err = aux_ptr_get(lll_sync->last_pdu, &aux_ptr);
373+
LL_ASSERT(!err && aux_ptr);
352374

375+
/* Use channel idx that was in aux_ptr */
376+
lll_chan_set(aux_ptr->chan_idx);
377+
378+
/* Get reference to the auxiliary chain PDU */
353379
pdu = lll_adv_pdu_linked_next_get(lll_sync->last_pdu);
354380
LL_ASSERT(pdu);
381+
382+
/* Set the last used auxiliary PDU for transmission */
355383
lll_sync->last_pdu = pdu;
356384

357385
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
@@ -403,11 +431,97 @@ static void isr_tx(void *param)
403431
HAL_RADIO_GPIO_PA_OFFSET);
404432
#endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
405433

434+
/* Populate chan idx for AUX_CHAIN_IND PDU */
435+
chain_pdu_aux_ptr_chan_idx_set(lll_sync);
436+
406437
if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
407438
lll_prof_send();
408439
}
409440
}
410441

442+
static int aux_ptr_get(struct pdu_adv *pdu, struct pdu_adv_aux_ptr **aux_ptr)
443+
{
444+
struct pdu_adv_com_ext_adv *com_hdr;
445+
struct pdu_adv_ext_hdr *hdr;
446+
uint8_t *dptr;
447+
448+
/* Get reference to common extended header */
449+
com_hdr = (void *)&pdu->adv_ext_ind;
450+
if (com_hdr->ext_hdr_len == 0U) {
451+
return -EINVAL;
452+
}
453+
454+
/* Get reference to extended header flags and header fields */
455+
hdr = (void *)com_hdr->ext_hdr_adv_data;
456+
dptr = hdr->data;
457+
458+
/* No traverse through of AdvA and TargetA.
459+
* These are RFU for periodic advertising, is not set by local device.
460+
*/
461+
462+
/* traverse through CTEInfo flag, if present */
463+
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
464+
if (hdr->cte_info) {
465+
dptr += sizeof(struct pdu_cte_info);
466+
}
467+
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
468+
469+
/* traverse through adi, if present */
470+
if (hdr->adi) {
471+
dptr += sizeof(struct pdu_adv_adi);
472+
}
473+
474+
/* check for aux_ptr flag */
475+
if (hdr->aux_ptr) {
476+
/* Return reference to aux pointer structure */
477+
*aux_ptr = (void *)dptr;
478+
} else {
479+
*aux_ptr = NULL;
480+
}
481+
482+
return 0;
483+
}
484+
485+
static void chain_pdu_aux_ptr_chan_idx_set(struct lll_adv_sync *lll)
486+
{
487+
struct pdu_adv *chain_pdu;
488+
489+
/* No chain PDU */
490+
if (!lll->last_pdu) {
491+
return;
492+
}
493+
494+
/* Get reference to the auxiliary chain PDU */
495+
chain_pdu = lll_adv_pdu_linked_next_get(lll->last_pdu);
496+
497+
/* Check if there is further chain PDU */
498+
if (chain_pdu && chain_pdu->adv_ext_ind.ext_hdr_len &&
499+
chain_pdu->adv_ext_ind.ext_hdr.aux_ptr) {
500+
aux_ptr_chan_idx_set(lll, chain_pdu);
501+
}
502+
}
503+
504+
static void aux_ptr_chan_idx_set(struct lll_adv_sync *lll, struct pdu_adv *pdu)
505+
{
506+
struct pdu_adv_aux_ptr *aux_ptr;
507+
uint8_t chan_idx;
508+
int err;
509+
510+
/* Get reference to aux pointer structure */
511+
err = aux_ptr_get(pdu, &aux_ptr);
512+
LL_ASSERT(!err && aux_ptr);
513+
514+
/* Calculate a new channel index */
515+
chan_idx = lll_chan_sel_2(lll->data_chan_counter, lll->data_chan_id,
516+
lll->chm[lll->chm_first].data_chan_map,
517+
lll->chm[lll->chm_first].data_chan_count);
518+
519+
/* Increment counter, for next channel index calculation */
520+
lll->data_chan_counter++;
521+
522+
/* Set the channel index for the auxiliary chain PDU */
523+
aux_ptr->chan_idx = chan_idx;
524+
}
411525
static void switch_radio_complete_and_b2b_tx(const struct lll_adv_sync *lll,
412526
uint8_t phy_s)
413527
{

subsys/bluetooth/controller/ll_sw/ull_adv_sync.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ uint8_t ll_adv_sync_param_set(uint8_t handle, uint16_t interval, uint16_t flags)
182182
lll_sync->latency_event = 0;
183183
lll_sync->event_counter = 0;
184184

185+
#if defined(CONFIG_BT_CTLR_ADV_PDU_LINK)
186+
lll_sync->data_chan_counter = 0U;
187+
#endif /* CONFIG_BT_CTLR_ADV_PDU_LINK */
188+
185189
sync->is_enabled = 0U;
186190
sync->is_started = 0U;
187191

0 commit comments

Comments
 (0)