Skip to content

Commit 651137e

Browse files
cvinayakcfriedt
authored andcommitted
Bluetooth: Controller: Fix Extended Advertising channel use
Add implementation defined channel index in the auxiliary pointer of the common extended payload format in the primary channel PDUs and the same be used in the transmission of auxiliary PDUs. Fixes #35668. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent 3075ba9 commit 651137e

File tree

10 files changed

+132
-27
lines changed

10 files changed

+132
-27
lines changed

subsys/bluetooth/controller/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ if(CONFIG_BT_LL_SW_SPLIT)
112112
)
113113
endif()
114114
if(CONFIG_BT_CONN OR
115+
(CONFIG_BT_BROADCASTER AND
116+
CONFIG_BT_CTLR_ADV_EXT) OR
115117
CONFIG_BT_CTLR_ADV_PERIODIC OR
116118
CONFIG_BT_CTLR_SYNC_PERIODIC)
117119
zephyr_library_sources(

subsys/bluetooth/controller/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ config BT_CTLR_PHY_CODED
430430

431431
config BT_CTLR_CHAN_SEL_2
432432
bool "Channel Selection Algorithm #2"
433-
depends on (BT_CONN || BT_CTLR_ADV_PERIODIC || BT_CTLR_SYNC_PERIODIC) && BT_CTLR_CHAN_SEL_2_SUPPORT
433+
depends on (BT_CONN || (BT_BROADCASTER && BT_CTLR_ADV_EXT) || BT_CTLR_ADV_PERIODIC || BT_CTLR_SYNC_PERIODIC) && BT_CTLR_CHAN_SEL_2_SUPPORT
434434
default y
435435
help
436436
Enable support for Bluetooth 5.0 LE Channel Selection Algorithm #2 in

subsys/bluetooth/controller/ll_sw/lll_adv.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ struct lll_adv_aux {
5656
struct lll_hdr hdr;
5757
struct lll_adv *adv;
5858

59+
/* Implementation defined radio event counter to calculate auxiliary
60+
* PDU channel index.
61+
*/
62+
uint16_t data_chan_counter;
63+
64+
/* Temporary stored use by primary channel PDU event to fill the
65+
* auxiliary offset to this auxiliary PDU event.
66+
*/
5967
uint32_t ticks_offset;
6068

6169
struct lll_adv_pdu data;
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018-2020 Nordic Semiconductor ASA
2+
* Copyright (c) 2018-2021 Nordic Semiconductor ASA
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -10,5 +10,6 @@ void lll_adv_aux_prepare(void *param);
1010

1111
extern uint8_t ull_adv_aux_lll_handle_get(struct lll_adv_aux *lll);
1212
extern struct pdu_adv_aux_ptr *
13-
ull_adv_aux_lll_offset_fill(uint32_t ticks_offset, uint32_t start_us,
14-
struct pdu_adv *pdu);
13+
ull_adv_aux_lll_offset_fill(struct pdu_adv *pdu,
14+
uint32_t ticks_offset,
15+
uint32_t start_us);

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,9 +1217,13 @@ static void isr_done(void *param)
12171217
start_us = radio_tmr_start_now(1);
12181218

12191219
#if defined(CONFIG_BT_CTLR_ADV_EXT)
1220-
if (lll->aux) {
1221-
ull_adv_aux_lll_offset_fill(lll->aux->ticks_offset,
1222-
start_us, pdu);
1220+
struct lll_adv_aux *lll_aux;
1221+
1222+
lll_aux = lll->aux;
1223+
if (lll_aux) {
1224+
(void)ull_adv_aux_lll_offset_fill(pdu,
1225+
lll_aux->ticks_offset,
1226+
start_us);
12231227
}
12241228
#else /* !CONFIG_BT_CTLR_ADV_EXT */
12251229
ARG_UNUSED(pdu);

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ static int prepare_cb(struct lll_prepare_param *p)
164164
return 0;
165165
}
166166

167+
/* Increment counter used in ULL for channel index calculation */
168+
lll->data_chan_counter++;
169+
167170
/* Set up Radio H/W */
168171
radio_reset();
169172

subsys/bluetooth/controller/ll_sw/ull_adv_aux.c

Lines changed: 92 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "lll.h"
2525
#include "lll_clock.h"
2626
#include "lll/lll_vendor.h"
27+
#include "lll_chan.h"
2728
#include "lll/lll_adv_types.h"
2829
#include "lll_adv.h"
2930
#include "lll/lll_adv_pdu.h"
@@ -33,6 +34,7 @@
3334
#include "ull_adv_types.h"
3435

3536
#include "ull_internal.h"
37+
#include "ull_chan_internal.h"
3638
#include "ull_adv_internal.h"
3739

3840
#include "ll.h"
@@ -449,6 +451,43 @@ uint8_t const *ull_adv_aux_random_addr_get(struct ll_adv_set const *const adv,
449451
return adv->rnd_addr;
450452
}
451453

454+
uint8_t ull_adv_aux_chm_update(void)
455+
{
456+
/* For each created extended advertising set */
457+
for (uint8_t handle = 0; handle < BT_CTLR_ADV_SET; ++handle) {
458+
struct ll_adv_aux_set *aux;
459+
struct ll_adv_set *adv;
460+
uint8_t chm_last;
461+
462+
adv = ull_adv_is_created_get(handle);
463+
if (!adv || !adv->lll.aux) {
464+
continue;
465+
}
466+
467+
aux = HDR_LLL2ULL(adv->lll.aux);
468+
if (aux->chm_last != aux->chm_first) {
469+
/* TODO: Handle previous Channel Map Update being in
470+
* progress
471+
*/
472+
continue;
473+
}
474+
475+
/* Append the channelMapNew that will be picked up by ULL */
476+
chm_last = aux->chm_last + 1;
477+
if (chm_last == DOUBLE_BUFFER_SIZE) {
478+
chm_last = 0U;
479+
}
480+
aux->chm[chm_last].data_chan_count =
481+
ull_chan_map_get(aux->chm[chm_last].data_chan_map);
482+
aux->chm_last = chm_last;
483+
}
484+
485+
/* TODO: Should failure due to Channel Map Update being already in
486+
* progress be returned to caller?
487+
*/
488+
return 0;
489+
}
490+
452491
uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv,
453492
uint16_t sec_hdr_add_fields,
454493
uint16_t sec_hdr_rem_fields,
@@ -903,17 +942,18 @@ void ull_adv_aux_ptr_fill(uint8_t **dptr, uint8_t phy_s)
903942
{
904943
struct pdu_adv_aux_ptr *aux_ptr;
905944

945+
/* NOTE: Channel Index and Aux Offset will be set on every advertiser's
946+
* event prepare when finding the auxiliary event's ticker offset.
947+
*/
948+
906949
*dptr -= sizeof(struct pdu_adv_aux_ptr);
907950
aux_ptr = (void *)*dptr;
908951

909-
/* FIXME: implementation defined */
910952
aux_ptr->chan_idx = 0U;
911953

912954
aux_ptr->ca = (lll_clock_ppm_local_get() <= SCA_50_PPM) ?
913955
SCA_VALUE_50_PPM : SCA_VALUE_500_PPM;
914956

915-
/* NOTE: Aux Offset will be set in advertiser LLL event
916-
*/
917957
aux_ptr->offs_units = 0U;
918958
aux_ptr->offs = 0U;
919959

@@ -1015,6 +1055,7 @@ struct ll_adv_aux_set *ull_adv_aux_acquire(struct lll_adv *lll)
10151055
{
10161056
struct lll_adv_aux *lll_aux;
10171057
struct ll_adv_aux_set *aux;
1058+
uint8_t chm_last;
10181059
int err;
10191060

10201061
aux = aux_acquire();
@@ -1032,6 +1073,18 @@ struct ll_adv_aux_set *ull_adv_aux_acquire(struct lll_adv *lll)
10321073
return NULL;
10331074
}
10341075

1076+
/* Initialize data channel calculation counter, data channel identifier,
1077+
* and channel map to use.
1078+
*/
1079+
lll_csrand_get(&lll_aux->data_chan_counter,
1080+
sizeof(lll_aux->data_chan_counter));
1081+
lll_csrand_get(&aux->data_chan_id, sizeof(aux->data_chan_id));
1082+
chm_last = aux->chm_first;
1083+
aux->chm_last = chm_last;
1084+
aux->chm[chm_last].data_chan_count =
1085+
ull_chan_map_get(aux->chm[chm_last].data_chan_map);
1086+
1087+
10351088
/* NOTE: ull_hdr_init(&aux->ull); is done on start */
10361089
lll_hdr_init(lll_aux, aux);
10371090

@@ -1063,12 +1116,12 @@ void ull_adv_aux_offset_get(struct ll_adv_set *adv)
10631116
LL_ASSERT(!ret);
10641117
}
10651118

1066-
struct pdu_adv_aux_ptr *ull_adv_aux_lll_offset_fill(uint32_t ticks_offset,
1067-
uint32_t start_us,
1068-
struct pdu_adv *pdu)
1119+
struct pdu_adv_aux_ptr *ull_adv_aux_lll_offset_fill(struct pdu_adv *pdu,
1120+
uint32_t ticks_offset,
1121+
uint32_t start_us)
10691122
{
10701123
struct pdu_adv_com_ext_adv *pri_com_hdr;
1071-
struct pdu_adv_aux_ptr *aux;
1124+
struct pdu_adv_aux_ptr *aux_ptr;
10721125
struct pdu_adv_ext_hdr *h;
10731126
uint32_t offs;
10741127
uint8_t *ptr;
@@ -1085,18 +1138,18 @@ struct pdu_adv_aux_ptr *ull_adv_aux_lll_offset_fill(uint32_t ticks_offset,
10851138
ptr += sizeof(struct pdu_adv_adi);
10861139
}
10871140

1088-
aux = (void *)ptr;
1141+
aux_ptr = (void *)ptr;
10891142
offs = HAL_TICKER_TICKS_TO_US(ticks_offset) - start_us;
10901143
offs = offs / OFFS_UNIT_30_US;
10911144
if (!!(offs >> 13)) {
1092-
aux->offs = offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US);
1093-
aux->offs_units = 1U;
1145+
aux_ptr->offs = offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US);
1146+
aux_ptr->offs_units = 1U;
10941147
} else {
1095-
aux->offs = offs;
1096-
aux->offs_units = 0U;
1148+
aux_ptr->offs = offs;
1149+
aux_ptr->offs_units = 0U;
10971150
}
10981151

1099-
return aux;
1152+
return aux_ptr;
11001153
}
11011154

11021155
void ull_adv_aux_done(struct node_rx_event_done *done)
@@ -1211,16 +1264,22 @@ static uint8_t aux_time_update(struct ll_adv_aux_set *aux, struct pdu_adv *pdu,
12111264

12121265
static void mfy_aux_offset_get(void *param)
12131266
{
1214-
struct ll_adv_set *adv = param;
1267+
struct pdu_adv_aux_ptr *aux_ptr;
1268+
struct lll_adv_aux *lll_aux;
12151269
struct ll_adv_aux_set *aux;
12161270
uint32_t ticks_to_expire;
1271+
uint8_t data_chan_count;
1272+
uint8_t *data_chan_map;
12171273
uint32_t ticks_current;
1274+
struct ll_adv_set *adv;
12181275
struct pdu_adv *pdu;
12191276
uint8_t ticker_id;
12201277
uint8_t retry;
12211278
uint8_t id;
12221279

1223-
aux = HDR_LLL2ULL(adv->lll.aux);
1280+
adv = param;
1281+
lll_aux = adv->lll.aux;
1282+
aux = HDR_LLL2ULL(lll_aux);
12241283
ticker_id = TICKER_ID_ADV_AUX_BASE + ull_adv_aux_handle_get(aux);
12251284

12261285
id = TICKER_NULL;
@@ -1259,19 +1318,32 @@ static void mfy_aux_offset_get(void *param)
12591318
/* Store the ticks offset for population in other advertising primary
12601319
* channel PDUs.
12611320
*/
1262-
aux->lll.ticks_offset = ticks_to_expire;
1321+
lll_aux->ticks_offset = ticks_to_expire;
12631322

12641323
/* NOTE: as remainder used in scheduling primary PDU not available,
12651324
* compensate with a probable jitter of one ticker resolution unit that
12661325
* would be included in the packet timer capture when scheduling next
12671326
* advertising primary channel PDU.
12681327
*/
1269-
aux->lll.ticks_offset +=
1328+
lll_aux->ticks_offset +=
12701329
HAL_TICKER_US_TO_TICKS(EVENT_TICKER_RES_MARGIN_US);
12711330

1272-
/* FIXME: we are in ULL_LOW context, fill offset in LLL context */
1273-
pdu = lll_adv_data_curr_get(&adv->lll);
1274-
ull_adv_aux_lll_offset_fill(ticks_to_expire, 0, pdu);
1331+
/* FIXME: we are in ULL_LOW context, fill offset in LLL context? */
1332+
pdu = lll_adv_data_latest_peek(&adv->lll);
1333+
aux_ptr = ull_adv_aux_lll_offset_fill(pdu, ticks_to_expire, 0);
1334+
1335+
/* Process channel map update, if any */
1336+
if (aux->chm_first != aux->chm_last) {
1337+
/* Use channelMapNew */
1338+
aux->chm_first = aux->chm_last;
1339+
}
1340+
1341+
/* Calculate the radio channel to use */
1342+
data_chan_map = aux->chm[aux->chm_first].data_chan_map;
1343+
data_chan_count = aux->chm[aux->chm_first].data_chan_count;
1344+
aux_ptr->chan_idx = lll_chan_sel_2(lll_aux->data_chan_counter,
1345+
aux->data_chan_id,
1346+
data_chan_map, data_chan_count);
12751347
}
12761348

12771349
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,

subsys/bluetooth/controller/ll_sw/ull_adv_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ uint8_t ull_adv_aux_handle_get(struct ll_adv_aux_set *aux);
7676
uint8_t const *ull_adv_aux_random_addr_get(struct ll_adv_set const *const adv,
7777
uint8_t *const addr);
7878

79+
/* Helper function to apply Channel Map Update for auxiliary PDUs */
80+
uint8_t ull_adv_aux_chm_update(void);
81+
7982
/* helper function to initialize event timings */
8083
uint32_t ull_adv_aux_evt_init(struct ll_adv_aux_set *aux);
8184

subsys/bluetooth/controller/ll_sw/ull_adv_types.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ struct ll_adv_aux_set {
7171

7272
uint16_t interval;
7373

74+
uint16_t data_chan_id;
75+
struct {
76+
uint8_t data_chan_map[PDU_CHANNEL_MAP_SIZE];
77+
uint8_t data_chan_count:6;
78+
} chm[DOUBLE_BUFFER_SIZE];
79+
uint8_t chm_first;
80+
uint8_t chm_last;
81+
7482
uint8_t is_started:1;
7583
};
7684

subsys/bluetooth/controller/ll_sw/ull_chan.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ uint8_t ll_chm_update(uint8_t const *const chm)
5252
(void)ull_adv_sync_chm_update();
5353
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
5454

55+
#if (CONFIG_BT_CTLR_ADV_AUX_SET > 0)
56+
(void)ull_adv_aux_chm_update();
57+
#endif /*(CONFIG_BT_CTLR_ADV_AUX_SET > 0) */
58+
5559
/* TODO: Should failure due to Channel Map Update being already in
5660
* progress be returned to caller?
5761
*/

0 commit comments

Comments
 (0)