Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nrf fromtree] Bluetooth: Host: Add support for advertising coding selection #2511

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions include/zephyr/bluetooth/bluetooth.h
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
10 changes: 9 additions & 1 deletion include/zephyr/bluetooth/gap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
38 changes: 38 additions & 0 deletions include/zephyr/bluetooth/hci_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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, \
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -3173,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;
Expand Down
8 changes: 8 additions & 0 deletions subsys/bluetooth/Kconfig.adv
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 13 additions & 0 deletions subsys/bluetooth/controller/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -742,6 +746,15 @@ 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
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
in the Controller.

if BT_CTLR_ADV_PERIODIC

config BT_CTLR_ADV_PERIODIC_ADI_SUPPORT
Expand Down
38 changes: 33 additions & 5 deletions subsys/bluetooth/host/adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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;
}
Expand Down
8 changes: 8 additions & 0 deletions subsys/bluetooth/host/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
33 changes: 31 additions & 2 deletions subsys/bluetooth/host/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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;
Expand Down
9 changes: 9 additions & 0 deletions tests/bluetooth/init/prj_host_6_x.conf
Original file line number Diff line number Diff line change
@@ -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
7 changes: 7 additions & 0 deletions tests/bluetooth/init/testcase.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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