From 63da4963a0888d9f3ab60dd2b03f5732e4e95150 Mon Sep 17 00:00:00 2001 From: Troels Nilsson Date: Thu, 29 Aug 2024 16:36:07 +0200 Subject: [PATCH] Bluetooth: Controller: Implement Secondary_Advertising_Max_Skip Behaviour is unchanged for max_skip == 0 For max_skip > 0, use a slightly different calculation to ensure we can pass LL/DDI/ADV/BV-28-C Signed-off-by: Troels Nilsson --- subsys/bluetooth/controller/ll_sw/ull_adv.c | 27 +++++++++++++------ .../controller/ll_sw/ull_adv_types.h | 1 + 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv.c b/subsys/bluetooth/controller/ll_sw/ull_adv.c index 269d4dddb5b..32443b6efac 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv.c @@ -339,6 +339,7 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type, is_new_set = !adv->is_created; adv->is_created = 1; adv->is_ad_data_cmplt = 1U; + adv->max_skip = skip; #endif /* CONFIG_BT_CTLR_ADV_EXT */ /* remember parameters so that set adv/scan data and adv enable @@ -1391,6 +1392,7 @@ uint8_t ll_adv_enable(uint8_t enable) struct lll_adv_aux *lll_aux = lll->aux; uint32_t ticks_slot_overhead_aux; uint32_t ticks_anchor_aux; + uint64_t interval_us; aux = HDR_LLL2ULL(lll_aux); @@ -1487,20 +1489,29 @@ uint8_t ll_adv_enable(uint8_t enable) } #endif /* CONFIG_BT_CTLR_ADV_PERIODIC */ - /* Keep aux interval equal or higher than primary PDU - * interval. + /* Keep aux interval equal or lower than primary PDU + * interval * (max_skip + 1). * Use periodic interval units to represent the * periodic behavior of scheduling of AUX_ADV_IND PDUs * so that it is grouped with similar interval units * used for ACL Connections, Periodic Advertising and * BIG radio events. */ - aux->interval = - DIV_ROUND_UP(((uint64_t)adv->interval * - ADV_INT_UNIT_US) + - HAL_TICKER_TICKS_TO_US( - ULL_ADV_RANDOM_DELAY), - PERIODIC_INT_UNIT_US); + interval_us = (uint64_t)adv->interval * ADV_INT_UNIT_US; + + if (adv->max_skip == 0U) { + /* Special case to keep behaviour unchanged from + * before max_skip was implemented; In this case + * add ULL_ADV_RANDOM_DELAY and round up for a + * aux interval equal or higher instead + */ + aux->interval = DIV_ROUND_UP(interval_us + + HAL_TICKER_TICKS_TO_US(ULL_ADV_RANDOM_DELAY), + PERIODIC_INT_UNIT_US); + } else { + aux->interval = (interval_us * (adv->max_skip + 1)) + / PERIODIC_INT_UNIT_US; + } ret = ull_adv_aux_start(aux, ticks_anchor_aux, ticks_slot_overhead_aux); diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_types.h b/subsys/bluetooth/controller/ll_sw/ull_adv_types.h index 9a9c016295e..afe817aefb1 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_types.h @@ -36,6 +36,7 @@ struct ll_adv_set { #if defined(CONFIG_BT_CTLR_HCI_ADV_HANDLE_MAPPING) uint8_t hci_handle; #endif + uint8_t max_skip; uint16_t event_counter; uint16_t max_events; uint32_t remain_duration_us;