From 66d2ede869a0e2b41e84a91a0f7289ac0f6a7019 Mon Sep 17 00:00:00 2001 From: Thomas Deppe Date: Thu, 6 Feb 2025 14:33:25 +0100 Subject: [PATCH 1/2] [nrf fromtree] Bluetooth: Host: Add support for Advertising Coding Selection Adds API for Advertising Coding Selection. Introduces two new advertising options to configure the advertiser's requirement concerning coding scheme when LE Coded PHY is configured. While the Bluetooth v6.0 specification makes a distinction betweeen preferred and required advertising PHY options, a simplification is made to only expose the required PHY options. Inline with how LE Coded PHY is implemented; this API will set both the primary and secondary advertising PHY's to the same coding scheme. The support is enabled by CONFIG_BT_EXT_ADV_CODING_SELECTION, and requires a controller that selects CONFIG_BT_CTLR_ADV_EXT_CODING_SELECTION_SUPPORT. Signed-off-by: Thomas Deppe (cherry picked from commit f3bdd2bc8c6331612ae9d6e9cbddf4434e23a1e4) --- include/zephyr/bluetooth/bluetooth.h | 34 +++++++++++++++++++++++ include/zephyr/bluetooth/hci_types.h | 30 ++++++++++++++++++++ subsys/bluetooth/Kconfig.adv | 8 ++++++ subsys/bluetooth/controller/Kconfig | 12 ++++++++ subsys/bluetooth/host/adv.c | 38 ++++++++++++++++++++++---- tests/bluetooth/init/prj_host_6_x.conf | 9 ++++++ tests/bluetooth/init/testcase.yaml | 7 +++++ 7 files changed, 133 insertions(+), 5 deletions(-) create mode 100644 tests/bluetooth/init/prj_host_6_x.conf diff --git a/include/zephyr/bluetooth/bluetooth.h b/include/zephyr/bluetooth/bluetooth.h index 8d2ceebf6cb..1b5576d9466 100644 --- a/include/zephyr/bluetooth/bluetooth.h +++ b/include/zephyr/bluetooth/bluetooth.h @@ -784,6 +784,40 @@ enum { * @note Mutually exclusive with BT_LE_ADV_OPT_USE_IDENTITY. */ BT_LE_ADV_OPT_USE_NRPA = BIT(19), + + /** + * @brief Configures the advertiser to use the S=2 coding scheme for + * LE Coded PHY. + * + * Sets the advertiser's required coding scheme to S=2, which is one + * of the coding options available for LE Coded PHY. The S=2 coding + * scheme offers higher data rates compared to S=8, with a trade-off + * of reduced range. The coding scheme will only be set if both the + * primary and secondary advertising channels indicate LE Coded Phy. + * Additionally, the Controller must support the LE Feature Advertising + * Coding Selection. If these conditions are not met, it will default to + * no required coding scheme. + * + * @note Requires @kconfig{BT_EXT_ADV_CODING_SELECTION} + */ + BT_LE_ADV_OPT_REQUIRE_S2_CODING = BIT(20), + + /** + * @brief Configures the advertiser to use the S=8 coding scheme for + * LE Coded PHY. + * + * Sets the advertiser's required coding scheme to S=8, which is one + * of the coding options available for LE Coded PHY. The S=8 coding + * scheme offers increased range compared to S=2, with a trade-off + * of lower data rates. The coding scheme will only be set if both the + * primary and secondary advertising channels indicate LE Coded Phy. + * Additionally, the Controller must support the LE Feature Advertising + * Coding Selection. If these conditions are not met, it will default to + * no required coding scheme. + * + * @note Requires @kconfig{BT_EXT_ADV_CODING_SELECTION} + */ + BT_LE_ADV_OPT_REQUIRE_S8_CODING = BIT(21), }; /** LE Advertising Parameters. */ diff --git a/include/zephyr/bluetooth/hci_types.h b/include/zephyr/bluetooth/hci_types.h index 9f312049007..d6fa395ff15 100644 --- a/include/zephyr/bluetooth/hci_types.h +++ b/include/zephyr/bluetooth/hci_types.h @@ -198,6 +198,8 @@ struct bt_hci_cmd_hdr { #define BT_LE_FEAT_BIT_CONN_SUBRATING 37 #define BT_LE_FEAT_BIT_CONN_SUBRATING_HOST_SUPP 38 #define BT_LE_FEAT_BIT_CHANNEL_CLASSIFICATION 39 +#define BT_LE_FEAT_BIT_ADV_CODING_SEL 40 +#define BT_LE_FEAT_BIT_ADV_CODING_SEL_HOST 41 #define BT_LE_FEAT_BIT_PAWR_ADVERTISER 43 #define BT_LE_FEAT_BIT_PAWR_SCANNER 44 @@ -268,6 +270,10 @@ struct bt_hci_cmd_hdr { BT_LE_FEAT_BIT_CONN_SUBRATING_HOST_SUPP) #define BT_FEAT_LE_CHANNEL_CLASSIFICATION(feat) BT_LE_FEAT_TEST(feat, \ BT_LE_FEAT_BIT_CHANNEL_CLASSIFICATION) +#define BT_FEAT_LE_ADV_CODING_SEL(feat) BT_LE_FEAT_TEST(feat, \ + BT_LE_FEAT_BIT_ADV_CODING_SEL) +#define BT_FEAT_LE_ADV_CODING_SEL_HOST(feat) BT_LE_FEAT_TEST(feat, \ + BT_LE_FEAT_BIT_ADV_CODING_SEL_HOST) #define BT_FEAT_LE_PAWR_ADVERTISER(feat) BT_LE_FEAT_TEST(feat, \ BT_LE_FEAT_BIT_PAWR_ADVERTISER) #define BT_FEAT_LE_PAWR_SCANNER(feat) BT_LE_FEAT_TEST(feat, \ @@ -1538,6 +1544,30 @@ struct bt_hci_rp_le_set_ext_adv_param { int8_t tx_power; } __packed; +#define BT_HCI_LE_ADV_PHY_OPTION_NO_REQUIRED 0x00 +#define BT_HCI_LE_ADV_PHY_OPTION_REQUIRE_S2 0x03 +#define BT_HCI_LE_ADV_PHY_OPTION_REQUIRE_S8 0x04 + +#define BT_HCI_OP_LE_SET_EXT_ADV_PARAM_V2 BT_OP(BT_OGF_LE, 0x007F) /* 0x207F */ +struct bt_hci_cp_le_set_ext_adv_param_v2 { + uint8_t handle; + uint16_t props; + uint8_t prim_min_interval[3]; + uint8_t prim_max_interval[3]; + uint8_t prim_channel_map; + uint8_t own_addr_type; + bt_addr_le_t peer_addr; + uint8_t filter_policy; + int8_t tx_power; + uint8_t prim_adv_phy; + uint8_t sec_adv_max_skip; + uint8_t sec_adv_phy; + uint8_t sid; + uint8_t scan_req_notify_enable; + uint8_t prim_adv_phy_opt; + uint8_t sec_adv_phy_opt; +} __packed; + #define BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG 0x00 #define BT_HCI_LE_EXT_ADV_OP_FIRST_FRAG 0x01 #define BT_HCI_LE_EXT_ADV_OP_LAST_FRAG 0x02 diff --git a/subsys/bluetooth/Kconfig.adv b/subsys/bluetooth/Kconfig.adv index 99b40250a94..28e1dea61a2 100644 --- a/subsys/bluetooth/Kconfig.adv +++ b/subsys/bluetooth/Kconfig.adv @@ -68,6 +68,14 @@ config BT_PER_ADV_SYNC_RSP Select this to enable Periodic Advertising with Responses Sync API support. +config BT_EXT_ADV_CODING_SELECTION + bool "Advertising Coding Selection support" + depends on !HAS_BT_CTLR || BT_CTLR_PHY_CODED + help + Select this to enable Advertising Coding Selection API support. + This allows the Host to indicate their strict requirement + concerning coding scheme when using Extended Advertising. + if BT_PER_ADV_SYNC config BT_PER_ADV_SYNC_MAX diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 4953343ba3c..d5469c24bc1 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -45,6 +45,10 @@ config BT_CTLR_PHY_CODED_SUPPORT config BT_CTLR_ADV_EXT_SUPPORT bool +config BT_CTLR_ADV_EXT_CODING_SELECTION_SUPPORT + depends on BT_CTLR_PHY_CODED_SUPPORT + bool + config BT_CTLR_ADV_PERIODIC_SUPPORT depends on BT_CTLR_ADV_EXT_SUPPORT bool @@ -742,6 +746,14 @@ config BT_CTLR_ADV_PERIODIC_RSP Enable support for Bluetooth 5.4 LE Periodic Advertising with Responses in the Controller. +config BT_CTLR_ADV_EXT_CODING_SELECTION + bool "Advertising Coding Selection support" + depends on BT_CTLR_PHY_CODED && BT_CTLR_ADV_EXT_CODING_SELECTION_SUPPORT + default y if BT_EXT_ADV_CODING_SELECTION + help + Enable support for Bluetooth 6.0 Advertising Coding Selection + in the Controller. + if BT_CTLR_ADV_PERIODIC config BT_CTLR_ADV_PERIODIC_ADI_SUPPORT diff --git a/subsys/bluetooth/host/adv.c b/subsys/bluetooth/host/adv.c index db71858f8f2..d99144a420d 100644 --- a/subsys/bluetooth/host/adv.c +++ b/subsys/bluetooth/host/adv.c @@ -1121,20 +1121,32 @@ static int le_ext_adv_param_set(struct bt_le_ext_adv *adv, const struct bt_le_adv_param *param, bool has_scan_data) { - struct bt_hci_cp_le_set_ext_adv_param *cp; + struct bt_hci_cp_le_set_ext_adv_param_v2 *cp; + + uint16_t opcode; + uint16_t size; bool dir_adv = param->peer != NULL, scannable; struct net_buf *buf, *rsp; int err; enum adv_name_type name_type; uint16_t props = 0; - buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_EXT_ADV_PARAM, sizeof(*cp)); + if (IS_ENABLED(CONFIG_BT_EXT_ADV_CODING_SELECTION) && + BT_FEAT_LE_ADV_CODING_SEL(bt_dev.le.features)) { + opcode = BT_HCI_OP_LE_SET_EXT_ADV_PARAM_V2; + size = sizeof(struct bt_hci_cp_le_set_ext_adv_param_v2); + } else { + opcode = BT_HCI_OP_LE_SET_EXT_ADV_PARAM; + size = sizeof(struct bt_hci_cp_le_set_ext_adv_param); + } + + buf = bt_hci_cmd_create(opcode, size); if (!buf) { return -ENOBUFS; } - cp = net_buf_add(buf, sizeof(*cp)); - (void)memset(cp, 0, sizeof(*cp)); + cp = net_buf_add(buf, size); + (void)memset(cp, 0, size); adv->options = param->options; @@ -1171,6 +1183,22 @@ static int le_ext_adv_param_set(struct bt_le_ext_adv *adv, if (param->options & BT_LE_ADV_OPT_CODED) { cp->prim_adv_phy = BT_HCI_LE_PHY_CODED; cp->sec_adv_phy = BT_HCI_LE_PHY_CODED; + + if (IS_ENABLED(CONFIG_BT_EXT_ADV_CODING_SELECTION) && + opcode == BT_HCI_OP_LE_SET_EXT_ADV_PARAM_V2) { + uint8_t adv_phy_opt; + + if (param->options & BT_LE_ADV_OPT_REQUIRE_S8_CODING) { + adv_phy_opt = BT_HCI_LE_ADV_PHY_OPTION_REQUIRE_S8; + } else if (param->options & BT_LE_ADV_OPT_REQUIRE_S2_CODING) { + adv_phy_opt = BT_HCI_LE_ADV_PHY_OPTION_REQUIRE_S2; + } else { + adv_phy_opt = BT_HCI_LE_ADV_PHY_OPTION_NO_REQUIRED; + } + + cp->prim_adv_phy_opt = adv_phy_opt; + cp->sec_adv_phy_opt = adv_phy_opt; + } } if (!(param->options & BT_LE_ADV_OPT_EXT_ADV)) { @@ -1222,7 +1250,7 @@ static int le_ext_adv_param_set(struct bt_le_ext_adv *adv, cp->sec_adv_max_skip = param->secondary_max_skip; cp->props = sys_cpu_to_le16(props); - err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_EXT_ADV_PARAM, buf, &rsp); + err = bt_hci_cmd_send_sync(opcode, buf, &rsp); if (err) { return err; } diff --git a/tests/bluetooth/init/prj_host_6_x.conf b/tests/bluetooth/init/prj_host_6_x.conf new file mode 100644 index 00000000000..033794e2b36 --- /dev/null +++ b/tests/bluetooth/init/prj_host_6_x.conf @@ -0,0 +1,9 @@ +CONFIG_BT=y +CONFIG_BT_BROADCASTER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_OBSERVER=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_EXT_ADV=y +CONFIG_BT_CTLR_PHY_CODED=y +CONFIG_BT_EXT_ADV_CODING_SELECTION=y +CONFIG_ZTEST=y diff --git a/tests/bluetooth/init/testcase.yaml b/tests/bluetooth/init/testcase.yaml index 778049c511a..a5cc40cd39e 100644 --- a/tests/bluetooth/init/testcase.yaml +++ b/tests/bluetooth/init/testcase.yaml @@ -402,3 +402,10 @@ tests: - SNIPPET="bt-ll-sw-split" platform_allow: - nrf52840dk/nrf52840 + bluetooth.init.test_host_6_x: + extra_args: CONF_FILE=prj_host_6_x.conf + platform_allow: + - qemu_cortex_m3 + - nrf52840dk/nrf52840 + integration_platforms: + - nrf52840dk/nrf52840 From dcd42f8cbb2173db95334ca69167354938bc49a8 Mon Sep 17 00:00:00 2001 From: Thomas Deppe Date: Tue, 11 Feb 2025 13:33:33 +0100 Subject: [PATCH 2/2] [nrf fromtree] Bluetooth: Host: Add host support for Advertising Coding Selection Extends the API for Advertising Coding Selection. The API is extended to set the Advertising Coding Selection (Host Support) bit. With this feature, the primary and secondary PHY can now explicitly report S=2 or S=8 coding in the extended advertising report. Previously, the report only indicated LE Coded regardless of whether S=2 or S=8 data coding was used. The API now sets the host support bit and ensures that the advertising PHY coding scheme is conveyed to the application via the scan callback. The support is enabled by CONFIG_BT_EXT_ADV_CODING_SELECTION, and requires a controller that selects CONFIG_BT_CTLR_ADV_EXT_CODING_SELECTION_SUPPORT. Signed-off-by: Thomas Deppe (cherry picked from commit dcbcbe824d079d76aac2dca29e14b50dd5bee7d3) --- include/zephyr/bluetooth/gap.h | 10 ++++++++- include/zephyr/bluetooth/hci_types.h | 8 +++++++ subsys/bluetooth/controller/Kconfig | 1 + subsys/bluetooth/host/hci_core.c | 8 +++++++ subsys/bluetooth/host/scan.c | 33 ++++++++++++++++++++++++++-- 5 files changed, 57 insertions(+), 3 deletions(-) diff --git a/include/zephyr/bluetooth/gap.h b/include/zephyr/bluetooth/gap.h index 1b1569e3003..2582d9fb96c 100644 --- a/include/zephyr/bluetooth/gap.h +++ b/include/zephyr/bluetooth/gap.h @@ -747,8 +747,16 @@ enum { BT_GAP_LE_PHY_1M = BIT(0), /** LE 2M PHY */ BT_GAP_LE_PHY_2M = BIT(1), - /** LE Coded PHY */ + /** LE Coded PHY, coding scheme not specified */ BT_GAP_LE_PHY_CODED = BIT(2), + /** LE Coded S=8 PHY. Only used for advertising reports + * when Kconfig BT_EXT_ADV_CODING_SELECTION is enabled. + */ + BT_GAP_LE_PHY_CODED_S8 = BIT(3), + /** LE Coded S=2 PHY. Only used for advertising reports + * when Kconfig BT_EXT_ADV_CODING_SELECTION is enabled. + */ + BT_GAP_LE_PHY_CODED_S2 = BIT(4), }; /** Advertising PDU types */ diff --git a/include/zephyr/bluetooth/hci_types.h b/include/zephyr/bluetooth/hci_types.h index d6fa395ff15..9717e8ed736 100644 --- a/include/zephyr/bluetooth/hci_types.h +++ b/include/zephyr/bluetooth/hci_types.h @@ -3203,6 +3203,14 @@ struct bt_hci_evt_le_phy_update_complete { #define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_INCOMPLETE 2 #define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_RX_FAILED 0xFF +/* Advertising Coding Selection extended advertising report PHY values. + * Only used when Kconfig BT_EXT_ADV_CODING_SELECTION is enabled. + */ +#define BT_HCI_LE_ADV_EVT_PHY_1M 0x01 +#define BT_HCI_LE_ADV_EVT_PHY_2M 0x02 +#define BT_HCI_LE_ADV_EVT_PHY_CODED_S8 0x03 +#define BT_HCI_LE_ADV_EVT_PHY_CODED_S2 0x04 + struct bt_hci_evt_le_ext_advertising_info { uint16_t evt_type; bt_addr_le_t addr; diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index d5469c24bc1..3360db0abc1 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -749,6 +749,7 @@ config BT_CTLR_ADV_PERIODIC_RSP config BT_CTLR_ADV_EXT_CODING_SELECTION bool "Advertising Coding Selection support" depends on BT_CTLR_PHY_CODED && BT_CTLR_ADV_EXT_CODING_SELECTION_SUPPORT + select BT_CTLR_SET_HOST_FEATURE if BT_OBSERVER default y if BT_EXT_ADV_CODING_SELECTION help Enable support for Bluetooth 6.0 Advertising Coding Selection diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 4701a69b0d5..7c1d1376d06 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -3682,6 +3682,14 @@ static int le_init(void) } } + if (IS_ENABLED(CONFIG_BT_EXT_ADV_CODING_SELECTION) && + BT_FEAT_LE_ADV_CODING_SEL(bt_dev.le.features)) { + err = le_set_host_feature(BT_LE_FEAT_BIT_ADV_CODING_SEL_HOST, 1); + if (err) { + return err; + } + } + return le_set_event_mask(); } diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index 05ad120fb38..c3551c2ef07 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -741,6 +741,28 @@ static uint8_t get_adv_type(uint8_t evt_type) } } +/* Convert Extended adv report PHY to GAP PHY */ +static uint8_t get_ext_adv_coding_sel_phy(uint8_t hci_phy) +{ + /* Converts from Extended adv report PHY to BT_GAP_LE_PHY_* + * When Advertising Coding Selection (Host Support) is enabled + * the controller will return the advertising coding scheme which + * can be S=2 or S=8 data coding. + */ + switch (hci_phy) { + case BT_HCI_LE_ADV_EVT_PHY_1M: + return BT_GAP_LE_PHY_1M; + case BT_HCI_LE_ADV_EVT_PHY_2M: + return BT_GAP_LE_PHY_2M; + case BT_HCI_LE_ADV_EVT_PHY_CODED_S8: + return BT_GAP_LE_PHY_CODED_S8; + case BT_HCI_LE_ADV_EVT_PHY_CODED_S2: + return BT_GAP_LE_PHY_CODED_S2; + default: + return 0; + } +} + /* Convert extended adv report evt_type field to adv props */ static uint16_t get_adv_props_extended(uint16_t evt_type) { @@ -755,8 +777,15 @@ static uint16_t get_adv_props_extended(uint16_t evt_type) static void create_ext_adv_info(struct bt_hci_evt_le_ext_advertising_info const *const evt, struct bt_le_scan_recv_info *const scan_info) { - scan_info->primary_phy = bt_get_phy(evt->prim_phy); - scan_info->secondary_phy = bt_get_phy(evt->sec_phy); + if (IS_ENABLED(CONFIG_BT_EXT_ADV_CODING_SELECTION) && + BT_FEAT_LE_ADV_CODING_SEL(bt_dev.le.features)) { + scan_info->primary_phy = get_ext_adv_coding_sel_phy(evt->prim_phy); + scan_info->secondary_phy = get_ext_adv_coding_sel_phy(evt->sec_phy); + } else { + scan_info->primary_phy = bt_get_phy(evt->prim_phy); + scan_info->secondary_phy = bt_get_phy(evt->sec_phy); + } + scan_info->tx_power = evt->tx_power; scan_info->rssi = evt->rssi; scan_info->sid = evt->sid;