Skip to content

Commit f758daa

Browse files
ppryga-nordiccarlescufi
authored andcommitted
Bluetooth: controller: add missing ADI support in per adv chains
Recently there was added ADI support to periodic advertising. There was missing implementation of ADI for periodic advertising chained PDUs and direction finding. Also unit tests for periodic advertising chains required update to handle ADI field. The commit provides missing implementation. Signed-off-by: Piotr Pryga <[email protected]> Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent e3144ca commit f758daa

File tree

5 files changed

+93
-19
lines changed

5 files changed

+93
-19
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,11 @@ static void pdu_b2b_aux_ptr_update(struct pdu_adv *pdu, uint8_t phy, uint8_t fla
424424
dptr++;
425425
}
426426

427-
LL_ASSERT(!hdr->adi);
427+
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT) && hdr->adi != 0) {
428+
dptr += sizeof(struct pdu_adv_adi);
429+
} else {
430+
LL_ASSERT(!hdr->adi);
431+
}
428432

429433
/* Update AuxPtr */
430434
aux_ptr = (void *)dptr;

subsys/bluetooth/controller/ll_sw/ull_adv_internal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ void ull_adv_aux_release(struct ll_adv_aux_set *aux);
9595
void ull_adv_aux_offset_get(struct ll_adv_set *adv);
9696

9797
/* Below are BT Spec v5.2, Vol 6, Part B Section 2.3.4 Table 2.12 defined */
98+
#define ULL_ADV_PDU_HDR_FIELD_NONE 0
9899
#define ULL_ADV_PDU_HDR_FIELD_ADVA BIT(0)
99100
#define ULL_ADV_PDU_HDR_FIELD_TARGETA BIT(1)
100101
#define ULL_ADV_PDU_HDR_FIELD_CTE_INFO BIT(2)
@@ -129,6 +130,11 @@ void ull_adv_sync_pdu_init(struct pdu_adv *pdu, uint8_t ext_hdr_flags);
129130
/* helper to add cte_info field to extended advertising header */
130131
uint8_t ull_adv_sync_pdu_cte_info_set(struct pdu_adv *pdu, const struct pdu_cte_info *cte_info);
131132

133+
/* helper to get information whether ADI field is avaialbe in extended advertising PDU */
134+
static inline bool ull_adv_sync_pdu_had_adi(const struct pdu_adv *pdu)
135+
{
136+
return pdu->adv_ext_ind.ext_hdr.adi;
137+
}
132138
/* helper function to calculate common ext adv payload header length and
133139
* adjust the data pointer.
134140
* NOTE: This function reverts the header data pointer if there is no

subsys/bluetooth/controller/ll_sw/ull_adv_sync.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,10 @@ void ull_adv_sync_pdu_init(struct pdu_adv *pdu, uint8_t ext_hdr_flags)
8989
*(uint8_t *)ext_hdr = ext_hdr_flags;
9090
dptr = ext_hdr->data;
9191

92-
LL_ASSERT(!(ext_hdr_flags & (ULL_ADV_PDU_HDR_FIELD_ADVA |
93-
ULL_ADV_PDU_HDR_FIELD_TARGETA |
92+
LL_ASSERT(!(ext_hdr_flags & (ULL_ADV_PDU_HDR_FIELD_ADVA | ULL_ADV_PDU_HDR_FIELD_TARGETA |
93+
#if !defined(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT)
9494
ULL_ADV_PDU_HDR_FIELD_ADI |
95+
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT */
9596
ULL_ADV_PDU_HDR_FIELD_SYNC_INFO)));
9697

9798
if (ext_hdr_flags & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) {
@@ -103,6 +104,10 @@ void ull_adv_sync_pdu_init(struct pdu_adv *pdu, uint8_t ext_hdr_flags)
103104
if (ext_hdr_flags & ULL_ADV_PDU_HDR_FIELD_TX_POWER) {
104105
dptr += sizeof(uint8_t);
105106
}
107+
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT) &&
108+
(ext_hdr_flags & ULL_ADV_PDU_HDR_FIELD_ADI)) {
109+
dptr += sizeof(struct pdu_adv_adi);
110+
}
106111

107112
/* Calc tertiary PDU len */
108113
len = ull_adv_aux_hdr_len_calc(com_hdr, &dptr);
@@ -151,7 +156,8 @@ static uint8_t adv_sync_pdu_init_from_prev_pdu(struct pdu_adv *pdu,
151156

152157
LL_ASSERT(!ext_hdr->adv_addr);
153158
LL_ASSERT(!ext_hdr->tgt_addr);
154-
LL_ASSERT(!ext_hdr->adi);
159+
LL_ASSERT(IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT) ||
160+
!ext_hdr->adi);
155161
LL_ASSERT(!ext_hdr->sync_info);
156162

157163
dptr = ext_hdr->data;
@@ -164,14 +170,24 @@ static uint8_t adv_sync_pdu_init_from_prev_pdu(struct pdu_adv *pdu,
164170
/* Copy CTEInfo, if applicable */
165171
if (ext_hdr->cte_info) {
166172
if (ext_hdr_prev->cte_info) {
167-
memcpy(dptr, dptr_prev, sizeof(struct pdu_cte_info));
173+
(void)memcpy(dptr, dptr_prev, sizeof(struct pdu_cte_info));
168174
}
169175
dptr += sizeof(struct pdu_cte_info);
170176
}
171177
if (ext_hdr_prev->cte_info) {
172178
dptr_prev += sizeof(struct pdu_cte_info);
173179
}
174180

181+
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT) && ext_hdr->adi != 0) {
182+
if (ext_hdr_prev->adi) {
183+
memcpy(dptr, dptr_prev, sizeof(struct pdu_adv_adi));
184+
}
185+
dptr += sizeof(struct pdu_adv_adi);
186+
}
187+
if (ext_hdr_prev->adi) {
188+
dptr_prev += sizeof(struct pdu_adv_adi);
189+
}
190+
175191
/* Add AuxPtr, if applicable. Do not copy since it will be updated later
176192
* anyway.
177193
*/

subsys/bluetooth/controller/ll_sw/ull_df.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,13 +613,18 @@ static uint8_t per_adv_chain_cte_info_set(struct lll_adv_sync *lll_sync, struct
613613
uint8_t pdu_add_field_flags;
614614
struct pdu_adv *pdu_next;
615615
uint8_t cte_index = 1;
616+
bool adi_in_sync_ind;
616617
bool new_chain;
617618
uint8_t err;
618619

619620
new_chain = (pdu_prev == pdu ? false : true);
620621

621622
pdu_add_field_flags = ULL_ADV_PDU_HDR_FIELD_CTE_INFO;
622623

624+
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT)) {
625+
adi_in_sync_ind = ull_adv_sync_pdu_had_adi(pdu_prev);
626+
}
627+
623628
pdu_prev = lll_adv_pdu_linked_next_get(pdu_prev);
624629

625630
/* Update PDUs in existing chain. Add cte_info to extended advertising header. */
@@ -646,6 +651,10 @@ static uint8_t per_adv_chain_cte_info_set(struct lll_adv_sync *lll_sync, struct
646651
}
647652
}
648653

654+
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT) && adi_in_sync_ind) {
655+
pdu_add_field_flags |= ULL_ADV_PDU_HDR_FIELD_ADI;
656+
}
657+
649658
err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu, pdu_add_field_flags, 0,
650659
cte_info);
651660
if (err != BT_HCI_ERR_SUCCESS) {
@@ -665,6 +674,10 @@ static uint8_t per_adv_chain_cte_info_set(struct lll_adv_sync *lll_sync, struct
665674
pdu_add_field_flags = ULL_ADV_PDU_HDR_FIELD_CTE_INFO;
666675
}
667676

677+
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT) && adi_in_sync_ind) {
678+
pdu_add_field_flags |= ULL_ADV_PDU_HDR_FIELD_ADI;
679+
}
680+
668681
/* Add new PDUs if the number of PDUs in existing chain is lower than requested number
669682
* of CTEs.
670683
*/
@@ -784,6 +797,9 @@ static bool pdu_ext_adv_is_empty_without_cte(const struct pdu_adv *pdu)
784797
if (ext_hdr->aux_ptr) {
785798
size_rem += sizeof(struct pdu_adv_aux_ptr);
786799
}
800+
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT) && ext_hdr->adi) {
801+
size_rem += sizeof(struct pdu_adv_adi);
802+
}
787803

788804
if ((pdu->adv_ext_ind.ext_hdr_len - size_rem) != PDU_AC_EXT_HEADER_SIZE_MIN) {
789805
return false;

tests/bluetooth/df/connectionless_cte_chains/src/common.c

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ struct ll_adv_set *common_create_adv_set(uint8_t hci_handle)
7676
*/
7777
lll_sync = &g_sync_set.lll;
7878
adv_set->lll.sync = &g_sync_set.lll;
79+
lll_hdr_init(&adv_set->lll, adv_set);
7980
g_sync_set.lll.adv = &adv_set->lll;
81+
lll_hdr_init(lll_sync, &g_sync_set);
8082

8183
err = lll_adv_init();
8284
zassert_equal(err, 0, "Unexpected error while initialization advertising set, err: %d",
@@ -137,6 +139,7 @@ void common_create_per_adv_chain(struct ll_adv_set *adv_set, uint8_t pdu_count)
137139
char pdu_buff[PDU_PAULOAD_BUFF_SIZE];
138140
void *extra_data_prev, *extra_data;
139141
struct lll_adv_sync *lll_sync;
142+
bool adi_in_sync_ind;
140143
uint8_t err, pdu_idx;
141144

142145
lll_sync = adv_set->lll.sync;
@@ -153,11 +156,16 @@ void common_create_per_adv_chain(struct ll_adv_set *adv_set, uint8_t pdu_count)
153156

154157
/* Create AUX_SYNC_IND PDU as a head of chain */
155158
err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu,
156-
(pdu_count > 1 ? ULL_ADV_PDU_HDR_FIELD_AUX_PTR : 0), 0,
157-
NULL);
159+
(pdu_count > 1 ? ULL_ADV_PDU_HDR_FIELD_AUX_PTR :
160+
ULL_ADV_PDU_HDR_FIELD_NONE),
161+
ULL_ADV_PDU_HDR_FIELD_NONE, NULL);
158162
zassert_equal(err, 0, "Unexpected error during initialization of extended PDU, err: %d",
159163
err);
160164

165+
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT)) {
166+
adi_in_sync_ind = ull_adv_sync_pdu_had_adi(pdu);
167+
}
168+
161169
/* Add some AD for testing */
162170
snprintf(pdu_buff, ARRAY_SIZE(pdu_buff), "test%" PRIu8 " test%" PRIu8 " test%" PRIu8 "", 0,
163171
0, 0);
@@ -171,9 +179,20 @@ void common_create_per_adv_chain(struct ll_adv_set *adv_set, uint8_t pdu_count)
171179
zassert_not_null(pdu_new, "Cannot allocate new PDU.");
172180
/* Initialize new empty PDU. Last AUX_CHAIN_IND may not include AuxPtr. */
173181
if (idx < pdu_count - 1) {
174-
ull_adv_sync_pdu_init(pdu_new, ULL_ADV_PDU_HDR_FIELD_AUX_PTR);
182+
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT) &&
183+
adi_in_sync_ind) {
184+
ull_adv_sync_pdu_init(pdu_new, ULL_ADV_PDU_HDR_FIELD_AUX_PTR |
185+
ULL_ADV_PDU_HDR_FIELD_ADI);
186+
} else {
187+
ull_adv_sync_pdu_init(pdu_new, ULL_ADV_PDU_HDR_FIELD_AUX_PTR);
188+
}
175189
} else {
176-
ull_adv_sync_pdu_init(pdu_new, 0);
190+
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT) &&
191+
adi_in_sync_ind) {
192+
ull_adv_sync_pdu_init(pdu_new, ULL_ADV_PDU_HDR_FIELD_ADI);
193+
} else {
194+
ull_adv_sync_pdu_init(pdu_new, ULL_ADV_PDU_HDR_FIELD_NONE);
195+
}
177196
}
178197
/* Add some AD for testing */
179198
common_pdu_adv_data_set(pdu_new, pdu_buff, strlen(pdu_buff));
@@ -246,14 +265,6 @@ void common_validate_per_adv_pdu(struct pdu_adv *pdu, enum test_pdu_ext_adv_type
246265
"Unexpected AdvA field in extended advertising header");
247266
zassert_false(ext_hdr->tgt_addr,
248267
"Unexpected TargetA field in extended advertising header");
249-
if (type == TEST_PDU_EXT_ADV_SYNC_IND) {
250-
zassert_false(
251-
ext_hdr->adi,
252-
"Unexpected ADI field in extended advertising header");
253-
}
254-
zassert_false(ext_hdr->sync_info,
255-
"Unexpected SyncInfo field in extended advertising header");
256-
257268
if (exp_ext_hdr_flags & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) {
258269
zassert_true(
259270
ext_hdr->cte_info,
@@ -264,8 +275,7 @@ void common_validate_per_adv_pdu(struct pdu_adv *pdu, enum test_pdu_ext_adv_type
264275
ext_hdr->cte_info,
265276
"Unexpected CteInfo field in extended advertising header");
266277
}
267-
if (type == TEST_PDU_EXT_ADV_SYNC_IND &&
268-
(exp_ext_hdr_flags & ULL_ADV_PDU_HDR_FIELD_ADI)) {
278+
if (exp_ext_hdr_flags & ULL_ADV_PDU_HDR_FIELD_ADI) {
269279
zassert_true(
270280
ext_hdr->adi,
271281
"Missing expected ADI field in extended advertising header");
@@ -285,6 +295,8 @@ void common_validate_per_adv_pdu(struct pdu_adv *pdu, enum test_pdu_ext_adv_type
285295
ext_hdr->aux_ptr,
286296
"Unexpected AuxPtr field in extended advertising header");
287297
}
298+
zassert_false(ext_hdr->sync_info,
299+
"Unexpected SyncInfo field in extended advertising header");
288300
if (exp_ext_hdr_flags & ULL_ADV_PDU_HDR_FIELD_TX_POWER) {
289301
zassert_true(
290302
ext_hdr->tx_pwr,
@@ -361,6 +373,11 @@ void common_validate_per_adv_chain(struct ll_adv_set *adv, uint8_t pdu_count)
361373
} else {
362374
ext_hdr_flags = ULL_ADV_PDU_HDR_FIELD_AD_DATA;
363375
}
376+
377+
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT)) {
378+
ext_hdr_flags |= ULL_ADV_PDU_HDR_FIELD_ADI;
379+
}
380+
364381
common_validate_per_adv_pdu(pdu, TEST_PDU_EXT_ADV_SYNC_IND, ext_hdr_flags);
365382
pdu = lll_adv_pdu_linked_next_get(pdu);
366383
if (pdu_count > 1) {
@@ -378,6 +395,11 @@ void common_validate_per_adv_chain(struct ll_adv_set *adv, uint8_t pdu_count)
378395
} else {
379396
ext_hdr_flags = ULL_ADV_PDU_HDR_FIELD_AD_DATA;
380397
}
398+
399+
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT)) {
400+
ext_hdr_flags |= ULL_ADV_PDU_HDR_FIELD_ADI;
401+
}
402+
381403
common_validate_per_adv_pdu(pdu, TEST_PDU_EXT_ADV_CHAIN_IND, ext_hdr_flags);
382404
pdu = lll_adv_pdu_linked_next_get(pdu);
383405
if (idx != (pdu_count - 1)) {
@@ -417,6 +439,11 @@ void common_validate_chain_with_cte(struct ll_adv_set *adv, uint8_t cte_count,
417439
if (ad_data_pdu_count > 0) {
418440
ext_hdr_flags |= ULL_ADV_PDU_HDR_FIELD_AD_DATA;
419441
}
442+
443+
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT)) {
444+
ext_hdr_flags |= ULL_ADV_PDU_HDR_FIELD_ADI;
445+
}
446+
420447
common_validate_per_adv_pdu(pdu, TEST_PDU_EXT_ADV_SYNC_IND, ext_hdr_flags);
421448

422449
pdu_count = MAX(cte_count, ad_data_pdu_count);
@@ -440,6 +467,11 @@ void common_validate_chain_with_cte(struct ll_adv_set *adv, uint8_t cte_count,
440467
if (idx < ad_data_pdu_count) {
441468
ext_hdr_flags |= ULL_ADV_PDU_HDR_FIELD_AD_DATA;
442469
}
470+
471+
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT)) {
472+
ext_hdr_flags |= ULL_ADV_PDU_HDR_FIELD_ADI;
473+
}
474+
443475
common_validate_per_adv_pdu(pdu, TEST_PDU_EXT_ADV_CHAIN_IND, ext_hdr_flags);
444476

445477
pdu = lll_adv_pdu_linked_next_get(pdu);

0 commit comments

Comments
 (0)