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 ab7706a73bb..834aa7bc953 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