Skip to content

Commit 416789c

Browse files
committed
Bluetooth: Controller: Add Extended Advertising Type Validations
Add Extended Advertising Type validation when associated Periodic Advertising is enable, and Extended Advertising set is re-configured to other advertising types. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent a63c515 commit 416789c

File tree

2 files changed

+117
-17
lines changed

2 files changed

+117
-17
lines changed

subsys/bluetooth/controller/ll_sw/ull_adv.c

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ static void conn_release(struct ll_adv_set *adv);
9191
#endif /* CONFIG_BT_PERIPHERAL */
9292

9393
#if defined(CONFIG_BT_CTLR_ADV_EXT)
94+
static uint8_t leg_adv_type_get(uint8_t evt_prop);
9495
static void adv_max_events_duration_set(struct ll_adv_set *adv,
9596
uint16_t duration,
9697
uint8_t max_ext_adv_evts);
@@ -255,24 +256,25 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type,
255256
if (adv_type == PDU_ADV_TYPE_EXT_IND) {
256257
/* legacy */
257258
if (evt_prop & BT_HCI_LE_ADV_PROP_LEGACY) {
258-
/* lookup evt_prop to PDU type in pdu_adv_type[] */
259-
uint8_t const leg_adv_type[] = {
260-
0x03, /* PDU_ADV_TYPE_NONCONN_IND */
261-
0x04, /* PDU_ADV_TYPE_DIRECT_IND */
262-
0x02, /* PDU_ADV_TYPE_SCAN_IND */
263-
0x00 /* PDU_ADV_TYPE_ADV_IND */
264-
};
265-
266259
if (evt_prop & BT_HCI_LE_ADV_PROP_ANON) {
267260
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
268261
}
269262

270-
adv_type = leg_adv_type[evt_prop & 0x03];
263+
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
264+
/* disallow changing to legacy advertising while
265+
* periodic advertising enabled.
266+
*/
267+
if (adv->lll.sync) {
268+
const struct ll_adv_sync_set *sync;
271269

272-
/* high duty cycle directed */
273-
if (evt_prop & BT_HCI_LE_ADV_PROP_HI_DC_CONN) {
274-
adv_type = 0x01; /* PDU_ADV_TYPE_DIRECT_IND */
270+
sync = HDR_LLL2ULL(adv->lll.sync);
271+
if (sync->is_enabled) {
272+
return BT_HCI_ERR_INVALID_PARAM;
273+
}
275274
}
275+
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
276+
277+
adv_type = leg_adv_type_get(evt_prop);
276278

277279
adv->lll.phy_p = PHY_1M;
278280
} else {
@@ -287,6 +289,20 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type,
287289
return BT_HCI_ERR_INVALID_PARAM;
288290
}
289291

292+
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
293+
if (adv->lll.sync &&
294+
(evt_prop & (BT_HCI_LE_ADV_PROP_ANON |
295+
BT_HCI_LE_ADV_PROP_CONN |
296+
BT_HCI_LE_ADV_PROP_SCAN))) {
297+
const struct ll_adv_sync_set *sync;
298+
299+
sync = HDR_LLL2ULL(adv->lll.sync);
300+
if (sync->is_enabled) {
301+
return BT_HCI_ERR_INVALID_PARAM;
302+
}
303+
}
304+
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
305+
290306
#if (CONFIG_BT_CTLR_ADV_AUX_SET == 0)
291307
/* Connectable or scannable requires aux */
292308
if (evt_prop & (BT_HCI_LE_ADV_PROP_CONN |
@@ -295,8 +311,8 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type,
295311
}
296312
#endif
297313

298-
adv_type = 0x05; /* PDU_ADV_TYPE_EXT_IND in */
299-
/* pdu_adv_type array. */
314+
adv_type = 0x05; /* index of PDU_ADV_TYPE_EXT_IND in */
315+
/* pdu_adv_type[] */
300316

301317
adv->lll.phy_p = phy_p;
302318
adv->lll.phy_flags = PHY_FLAGS_S8;
@@ -463,9 +479,8 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type,
463479
pri_dptr_prev += BDADDR_SIZE;
464480
}
465481
if (!pri_com_hdr->adv_mode &&
466-
(!pri_hdr_prev.aux_ptr ||
467-
(!(evt_prop & BT_HCI_LE_ADV_PROP_ANON) &&
468-
(phy_p != PHY_CODED)))) {
482+
!(evt_prop & BT_HCI_LE_ADV_PROP_ANON) &&
483+
(!pri_hdr_prev.aux_ptr || (phy_p != PHY_CODED))) {
469484
/* TODO: optional on 1M with Aux Ptr */
470485
pri_hdr->adv_addr = 1;
471486

@@ -2421,6 +2436,28 @@ static void conn_release(struct ll_adv_set *adv)
24212436
#endif /* CONFIG_BT_PERIPHERAL */
24222437

24232438
#if defined(CONFIG_BT_CTLR_ADV_EXT)
2439+
static uint8_t leg_adv_type_get(uint8_t evt_prop)
2440+
{
2441+
/* We take advantage of the fact that 2 LS bits
2442+
* of evt_prop can be used in a lookup to return
2443+
* PDU type value in the pdu_adv_type[] lookup.
2444+
*/
2445+
uint8_t const leg_adv_type[] = {
2446+
0x03, /* index of PDU_ADV_TYPE_NONCONN_IND in pdu_adv_type[] */
2447+
0x04, /* index of PDU_ADV_TYPE_DIRECT_IND in pdu_adv_type[] */
2448+
0x02, /* index of PDU_ADV_TYPE_SCAN_IND in pdu_adv_type[] */
2449+
0x00 /* index of PDU_ADV_TYPE_ADV_IND in pdu_adv_type[] */
2450+
};
2451+
2452+
/* if high duty cycle directed */
2453+
if (evt_prop & BT_HCI_LE_ADV_PROP_HI_DC_CONN) {
2454+
/* index of PDU_ADV_TYPE_DIRECT_IND in pdu_adv_type[] */
2455+
return 0x01;
2456+
}
2457+
2458+
return leg_adv_type[evt_prop & 0x03];
2459+
}
2460+
24242461
static void adv_max_events_duration_set(struct ll_adv_set *adv,
24252462
uint16_t duration,
24262463
uint8_t max_ext_adv_evts)

subsys/bluetooth/controller/ll_sw/ull_adv_sync.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "hal/debug.h"
4949

5050
static int init_reset(void);
51+
static uint8_t adv_type_check(struct ll_adv_set *adv);
5152
static inline struct ll_adv_sync_set *sync_acquire(void);
5253
static inline void sync_release(struct ll_adv_sync_set *sync);
5354
static inline uint16_t sync_handle_get(struct ll_adv_sync_set *sync);
@@ -350,6 +351,15 @@ uint8_t ll_adv_sync_param_set(uint8_t handle, uint16_t interval, uint16_t flags)
350351
return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
351352
}
352353

354+
if (IS_ENABLED(CONFIG_BT_CTLR_PARAM_CHECK)) {
355+
uint8_t err;
356+
357+
err = adv_type_check(adv);
358+
if (err) {
359+
return err;
360+
}
361+
}
362+
353363
lll_sync = adv->lll.sync;
354364
if (!lll_sync) {
355365
struct pdu_adv *ter_pdu;
@@ -455,6 +465,15 @@ uint8_t ll_adv_sync_ad_data_set(uint8_t handle, uint8_t op, uint8_t len,
455465
return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
456466
}
457467

468+
if (IS_ENABLED(CONFIG_BT_CTLR_PARAM_CHECK)) {
469+
uint8_t err;
470+
471+
err = adv_type_check(adv);
472+
if (err) {
473+
return err;
474+
}
475+
}
476+
458477
lll_sync = adv->lll.sync;
459478
if (!lll_sync) {
460479
return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
@@ -549,6 +568,15 @@ uint8_t ll_adv_sync_enable(uint8_t handle, uint8_t enable)
549568
return err;
550569
}
551570

571+
if (IS_ENABLED(CONFIG_BT_CTLR_PARAM_CHECK)) {
572+
uint8_t err;
573+
574+
err = adv_type_check(adv);
575+
if (err) {
576+
return BT_HCI_ERR_CMD_DISALLOWED;
577+
}
578+
}
579+
552580
/* TODO: Check for periodic data being complete */
553581

554582
/* TODO: Check packet too long */
@@ -1454,6 +1482,41 @@ static int init_reset(void)
14541482
return 0;
14551483
}
14561484

1485+
static uint8_t adv_type_check(struct ll_adv_set *adv)
1486+
{
1487+
struct pdu_adv_com_ext_adv *pri_com_hdr;
1488+
struct pdu_adv_ext_hdr *pri_hdr;
1489+
struct pdu_adv *pri_pdu;
1490+
1491+
pri_pdu = lll_adv_data_latest_peek(&adv->lll);
1492+
if (pri_pdu->type != PDU_ADV_TYPE_EXT_IND) {
1493+
return BT_HCI_ERR_INVALID_PARAM;
1494+
}
1495+
1496+
pri_com_hdr = (void *)&pri_pdu->adv_ext_ind;
1497+
if (pri_com_hdr->adv_mode != 0U) {
1498+
return BT_HCI_ERR_INVALID_PARAM;
1499+
}
1500+
1501+
pri_hdr = (void *)pri_com_hdr->ext_hdr_adv_data;
1502+
if (pri_hdr->aux_ptr) {
1503+
struct pdu_adv_com_ext_adv *sec_com_hdr;
1504+
struct pdu_adv_ext_hdr *sec_hdr;
1505+
struct pdu_adv *sec_pdu;
1506+
1507+
sec_pdu = lll_adv_aux_data_latest_peek(adv->lll.aux);
1508+
sec_com_hdr = (void *)&sec_pdu->adv_ext_ind;
1509+
sec_hdr = (void *)sec_com_hdr->ext_hdr_adv_data;
1510+
if (!pri_hdr->adv_addr && !sec_hdr->adv_addr) {
1511+
return BT_HCI_ERR_INVALID_PARAM;
1512+
}
1513+
} else if (!pri_hdr->adv_addr) {
1514+
return BT_HCI_ERR_INVALID_PARAM;
1515+
}
1516+
1517+
return 0;
1518+
}
1519+
14571520
static inline struct ll_adv_sync_set *sync_acquire(void)
14581521
{
14591522
return mem_acquire(&adv_sync_free);

0 commit comments

Comments
 (0)