Skip to content

Commit 1eb74c4

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

File tree

1 file changed

+169
-58
lines changed

1 file changed

+169
-58
lines changed

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

Lines changed: 169 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,20 @@
4949

5050
static int init_reset(void);
5151
static int prepare_cb(struct lll_prepare_param *p);
52+
#if !defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) || \
53+
defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
54+
static int aux_ptr_get(struct pdu_adv *pdu, struct pdu_adv_aux_ptr **aux_ptr);
55+
#endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO ||
56+
* CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK
57+
*/
5258
#if !defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
5359
static void isr_early_abort(void *param);
5460
#endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
5561
static void isr_done(void *param);
5662
#if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
5763
static void isr_tx_chain(void *param);
64+
static void chain_pdu_aux_ptr_chan_idx_set(struct lll_adv_aux *lll);
65+
static void aux_ptr_chan_idx_set(struct lll_adv_aux *lll, struct pdu_adv *pdu);
5866
#endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK */
5967
static void isr_tx_rx(void *param);
6068
static void isr_rx(void *param);
@@ -150,47 +158,22 @@ static int prepare_cb(struct lll_prepare_param *p)
150158

151159
#else /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
152160
struct pdu_adv_aux_ptr *aux_ptr;
153-
struct pdu_adv_ext_hdr *pri_hdr;
154161
struct pdu_adv *pri_pdu;
155-
uint8_t *pri_dptr;
162+
int err;
156163

157164
/* Get reference to primary PDU */
158165
pri_pdu = lll_adv_data_curr_get(lll_adv);
159166
LL_ASSERT(pri_pdu->type == PDU_ADV_TYPE_EXT_IND);
160167

161-
/* Get reference to extended header */
168+
/* Get reference to common extended header */
162169
com_hdr = (void *)&pri_pdu->adv_ext_ind;
163-
pri_hdr = (void *)com_hdr->ext_hdr_adv_data;
164-
pri_dptr = pri_hdr->data;
165-
166-
/* NOTE: We shall be here in auxiliary PDU prepare due to
167-
* aux_ptr flag being set in the extended common header
168-
* flags. Hence, ext_hdr_len is non-zero, an explicit check
169-
* is not needed.
170-
*/
171-
LL_ASSERT(com_hdr->ext_hdr_len);
172-
173-
/* traverse through adv_addr, if present */
174-
if (pri_hdr->adv_addr) {
175-
pri_dptr += BDADDR_SIZE;
176-
}
177-
178-
/* traverse through tgt_addr, if present */
179-
if (pri_hdr->tgt_addr) {
180-
pri_dptr += BDADDR_SIZE;
181-
}
182-
183-
/* No CTEInfo flag in primary and secondary channel PDU */
184170

185-
/* traverse through adi, if present */
186-
if (pri_hdr->adi) {
187-
pri_dptr += sizeof(struct pdu_adv_adi);
188-
}
189-
190-
aux_ptr = (void *)pri_dptr;
171+
/* Get reference to aux pointer structure */
172+
err = aux_ptr_get(pri_pdu, &aux_ptr);
173+
LL_ASSERT(!err);
191174

192175
/* Abort if no aux_ptr filled */
193-
if (unlikely(!pri_hdr->aux_ptr || !PDU_ADV_AUX_PTR_OFFSET_GET(aux_ptr))) {
176+
if (unlikely(!aux_ptr || !PDU_ADV_AUX_PTR_OFFSET_GET(aux_ptr))) {
194177
radio_isr_set(isr_early_abort, lll);
195178
radio_disable();
196179

@@ -200,7 +183,7 @@ static int prepare_cb(struct lll_prepare_param *p)
200183
chan_idx = aux_ptr->chan_idx;
201184
#endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
202185

203-
/* Increment counter used in ULL for channel index calculation */
186+
/* Increment counter, for next channel index calculation */
204187
lll->data_chan_counter++;
205188

206189
/* Set up Radio H/W */
@@ -228,9 +211,6 @@ static int prepare_cb(struct lll_prepare_param *p)
228211
/* Use channel idx calculated or that was in aux_ptr */
229212
lll_chan_set(chan_idx);
230213

231-
/* Set the Radio Tx Packet */
232-
radio_pkt_tx_set(sec_pdu);
233-
234214
/* Switch to Rx if connectable or scannable */
235215
if (com_hdr->adv_mode & (BT_HCI_LE_ADV_PROP_CONN |
236216
BT_HCI_LE_ADV_PROP_SCAN)) {
@@ -282,19 +262,38 @@ static int prepare_cb(struct lll_prepare_param *p)
282262
#if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
283263
} else if (sec_pdu->adv_ext_ind.ext_hdr_len &&
284264
sec_pdu->adv_ext_ind.ext_hdr.aux_ptr) {
265+
/* Set the last used auxiliary PDU for transmission */
285266
lll->last_pdu = sec_pdu;
286267

268+
/* Populate chan idx for AUX_ADV_IND PDU */
269+
aux_ptr_chan_idx_set(lll, sec_pdu);
270+
287271
radio_isr_set(isr_tx_chain, lll);
288272
radio_tmr_tifs_set(EVENT_B2B_MAFS_US);
289273
radio_switch_complete_and_b2b_tx(phy_s, lll_adv->phy_flags,
290274
phy_s, lll_adv->phy_flags);
291-
#endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK */
275+
} else {
276+
/* No chain PDU */
277+
lll->last_pdu = NULL;
292278

279+
#else /* !CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK */
293280
} else {
281+
#endif /* !CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK */
282+
294283
radio_isr_set(isr_done, lll);
295284
radio_switch_complete_and_disable();
296285
}
297286

287+
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC) &&
288+
IS_ENABLED(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) &&
289+
sec_pdu->adv_ext_ind.ext_hdr_len &&
290+
sec_pdu->adv_ext_ind.ext_hdr.sync_info) {
291+
ull_adv_sync_lll_syncinfo_fill(sec_pdu, lll);
292+
}
293+
294+
/* Set the Radio Tx Packet */
295+
radio_pkt_tx_set(sec_pdu);
296+
298297
ticks_at_event = p->ticks_at_expire;
299298
ull = HDR_LLL2ULL(lll);
300299
ticks_at_event += lll_event_offset_get(ull);
@@ -335,12 +334,10 @@ static int prepare_cb(struct lll_prepare_param *p)
335334
}
336335
#endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */
337336

338-
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC) &&
339-
IS_ENABLED(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) &&
340-
sec_pdu->adv_ext_ind.ext_hdr_len &&
341-
sec_pdu->adv_ext_ind.ext_hdr.sync_info) {
342-
ull_adv_sync_lll_syncinfo_fill(sec_pdu, lll);
343-
}
337+
#if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
338+
/* Populate chan idx for AUX_CHAIN_IND PDU */
339+
chain_pdu_aux_ptr_chan_idx_set(lll);
340+
#endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK */
344341

345342
ret = lll_prepare_done(lll);
346343
LL_ASSERT(!ret);
@@ -350,6 +347,57 @@ static int prepare_cb(struct lll_prepare_param *p)
350347
return 0;
351348
}
352349

350+
#if !defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO) || \
351+
defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
352+
static int aux_ptr_get(struct pdu_adv *pdu, struct pdu_adv_aux_ptr **aux_ptr)
353+
{
354+
struct pdu_adv_com_ext_adv *com_hdr;
355+
struct pdu_adv_ext_hdr *hdr;
356+
uint8_t *dptr;
357+
358+
/* Get reference to common extended header */
359+
com_hdr = (void *)&pdu->adv_ext_ind;
360+
if (com_hdr->ext_hdr_len == 0U) {
361+
*aux_ptr = NULL;
362+
363+
return -EINVAL;
364+
}
365+
366+
/* Get reference to extended header flags and header fields */
367+
hdr = (void *)com_hdr->ext_hdr_adv_data;
368+
dptr = hdr->data;
369+
370+
/* traverse through adv_addr, if present */
371+
if (hdr->adv_addr) {
372+
dptr += BDADDR_SIZE;
373+
}
374+
375+
/* traverse through tgt_addr, if present */
376+
if (hdr->tgt_addr) {
377+
dptr += BDADDR_SIZE;
378+
}
379+
380+
/* No CTEInfo flag in primary and secondary channel PDU */
381+
382+
/* traverse through adi, if present */
383+
if (hdr->adi) {
384+
dptr += sizeof(struct pdu_adv_adi);
385+
}
386+
387+
/* check for aux_ptr flag */
388+
if (hdr->aux_ptr) {
389+
/* Return reference to aux pointer structure */
390+
*aux_ptr = (void *)dptr;
391+
} else {
392+
*aux_ptr = NULL;
393+
}
394+
395+
return 0;
396+
}
397+
#endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO ||
398+
* CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK
399+
*/
400+
353401
#if !defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
354402
static void isr_race(void *param)
355403
{
@@ -395,9 +443,11 @@ static void isr_done(void *param)
395443
#if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
396444
static void isr_tx_chain(void *param)
397445
{
446+
struct pdu_adv_aux_ptr *aux_ptr;
398447
struct lll_adv_aux *lll_aux;
399448
struct lll_adv *lll;
400449
struct pdu_adv *pdu;
450+
int err;
401451

402452
if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
403453
lll_prof_latency_capture();
@@ -406,14 +456,22 @@ static void isr_tx_chain(void *param)
406456
/* Clear radio tx status and events */
407457
lll_isr_tx_status_reset();
408458

459+
/* Get reference to auxiliary and primary advertising LLL contexts */
409460
lll_aux = param;
410461
lll = lll_aux->adv;
411462

412-
/* FIXME: Use implementation defined channel index */
413-
lll_chan_set(0);
463+
/* Get reference to aux pointer structure */
464+
err = aux_ptr_get(lll_aux->last_pdu, &aux_ptr);
465+
LL_ASSERT(!err && aux_ptr);
414466

467+
/* Use channel idx that was in aux_ptr */
468+
lll_chan_set(aux_ptr->chan_idx);
469+
470+
/* Get reference to the auxiliary chain PDU */
415471
pdu = lll_adv_pdu_linked_next_get(lll_aux->last_pdu);
416472
LL_ASSERT(pdu);
473+
474+
/* Set the last used auxiliary PDU for transmission */
417475
lll_aux->last_pdu = pdu;
418476

419477
/* setup tIFS switching */
@@ -458,10 +516,56 @@ static void isr_tx_chain(void *param)
458516
HAL_RADIO_GPIO_PA_OFFSET);
459517
#endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
460518

519+
/* Populate chan idx for AUX_CHAIN_IND PDU */
520+
chain_pdu_aux_ptr_chan_idx_set(lll_aux);
521+
461522
if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
462523
lll_prof_send();
463524
}
464525
}
526+
527+
static void chain_pdu_aux_ptr_chan_idx_set(struct lll_adv_aux *lll)
528+
{
529+
struct pdu_adv *chain_pdu;
530+
531+
/* No chain PDU */
532+
if (!lll->last_pdu) {
533+
return;
534+
}
535+
536+
/* Get reference to the auxiliary chain PDU */
537+
chain_pdu = lll_adv_pdu_linked_next_get(lll->last_pdu);
538+
539+
/* Check if there is further chain PDU */
540+
if (chain_pdu && chain_pdu->adv_ext_ind.ext_hdr_len &&
541+
chain_pdu->adv_ext_ind.ext_hdr.aux_ptr) {
542+
aux_ptr_chan_idx_set(lll, chain_pdu);
543+
}
544+
}
545+
546+
static void aux_ptr_chan_idx_set(struct lll_adv_aux *lll, struct pdu_adv *pdu)
547+
{
548+
struct pdu_adv_aux_ptr *aux_ptr;
549+
struct ll_adv_aux_set *aux;
550+
uint8_t chan_idx;
551+
int err;
552+
553+
/* Get reference to aux pointer structure */
554+
err = aux_ptr_get(pdu, &aux_ptr);
555+
LL_ASSERT(!err && aux_ptr);
556+
557+
/* Calculate a new channel index */
558+
aux = HDR_LLL2ULL(lll);
559+
chan_idx = lll_chan_sel_2(lll->data_chan_counter, aux->data_chan_id,
560+
aux->chm[aux->chm_first].data_chan_map,
561+
aux->chm[aux->chm_first].data_chan_count);
562+
563+
/* Increment counter, for next channel index calculation */
564+
lll->data_chan_counter++;
565+
566+
/* Set the channel index for the auxiliary chain PDU */
567+
aux_ptr->chan_idx = chan_idx;
568+
}
465569
#endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK */
466570

467571
static void isr_tx_rx(void *param)
@@ -682,6 +786,7 @@ static inline int isr_rx_pdu(struct lll_adv_aux *lll_aux, uint8_t phy_flags_rx,
682786
#if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
683787
} else if (sr_pdu->adv_ext_ind.ext_hdr_len &&
684788
sr_pdu->adv_ext_ind.ext_hdr.aux_ptr) {
789+
/* Set the last used auxiliary PDU for transmission */
685790
lll_aux->last_pdu = sr_pdu;
686791

687792
radio_isr_set(isr_tx_chain, lll_aux);
@@ -710,20 +815,6 @@ static inline int isr_rx_pdu(struct lll_adv_aux *lll_aux, uint8_t phy_flags_rx,
710815
lll_prof_cputime_capture();
711816
}
712817

713-
#if defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY)
714-
if (lll->scan_req_notify) {
715-
uint32_t err;
716-
717-
/* Generate the scan request event */
718-
err = lll_adv_scan_req_report(lll, pdu_rx, rl_idx,
719-
rssi_ready);
720-
if (err) {
721-
/* Scan Response will not be transmitted */
722-
return err;
723-
}
724-
}
725-
#endif /* CONFIG_BT_CTLR_SCAN_REQ_NOTIFY */
726-
727818
#if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
728819
if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
729820
/* PA/LNA enable is overwriting packet end used in ISR
@@ -739,6 +830,26 @@ static inline int isr_rx_pdu(struct lll_adv_aux *lll_aux, uint8_t phy_flags_rx,
739830
phy_flags_rx) -
740831
HAL_RADIO_GPIO_PA_OFFSET);
741832
#endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
833+
834+
#if defined(CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK)
835+
/* Populate chan idx for AUX_CHAIN_IND PDU */
836+
chain_pdu_aux_ptr_chan_idx_set(lll_aux);
837+
#endif /* CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK */
838+
839+
#if defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY)
840+
if (lll->scan_req_notify) {
841+
uint32_t err;
842+
843+
/* Generate the scan request event */
844+
err = lll_adv_scan_req_report(lll, pdu_rx, rl_idx,
845+
rssi_ready);
846+
if (err) {
847+
/* Scan Response will not be transmitted */
848+
return err;
849+
}
850+
}
851+
#endif /* CONFIG_BT_CTLR_SCAN_REQ_NOTIFY */
852+
742853
return 0;
743854

744855
#if defined(CONFIG_BT_PERIPHERAL)

0 commit comments

Comments
 (0)