From 5acb79f4e40c906308e71f2ef6b031bed88a2526 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 14 Mar 2024 21:25:03 +0100 Subject: [PATCH] samples: Bluetooth: peripheral_hr extended advertising support Update peripheral_hr sample to support using extended advertising and hence be long range compatible on SoCs that support Bluetooth Low Energy Coded PHY. Signed-off-by: Vinayak Kariappa Chettimada --- .../peripheral_hr/overlay-extended.conf | 6 + .../peripheral_hr/overlay-phy_coded.conf | 12 ++ samples/bluetooth/peripheral_hr/sample.yaml | 32 +++++ samples/bluetooth/peripheral_hr/src/main.c | 119 +++++++++++++----- 4 files changed, 140 insertions(+), 29 deletions(-) create mode 100644 samples/bluetooth/peripheral_hr/overlay-extended.conf create mode 100644 samples/bluetooth/peripheral_hr/overlay-phy_coded.conf diff --git a/samples/bluetooth/peripheral_hr/overlay-extended.conf b/samples/bluetooth/peripheral_hr/overlay-extended.conf new file mode 100644 index 0000000000..69e5e49082 --- /dev/null +++ b/samples/bluetooth/peripheral_hr/overlay-extended.conf @@ -0,0 +1,6 @@ +CONFIG_BT_EXT_ADV=y + +# Increase Advertising Data Length, as Complete Local Name too needs to be +# placed in the AUX_ADV_IND PDU compared to when it is placed in ADV_SCAN_IND +# PDU in the case of legacy advertising. +CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=36 diff --git a/samples/bluetooth/peripheral_hr/overlay-phy_coded.conf b/samples/bluetooth/peripheral_hr/overlay-phy_coded.conf new file mode 100644 index 0000000000..31805e66d4 --- /dev/null +++ b/samples/bluetooth/peripheral_hr/overlay-phy_coded.conf @@ -0,0 +1,12 @@ +CONFIG_BT_EXT_ADV=y + +# Enable Coded PHY support +CONFIG_BT_CTLR_PHY_CODED=y + +# Disable auto PHY update, to switch to 2M PHY +CONFIG_BT_AUTO_PHY_UPDATE=n + +# Increase Advertising Data Length, as Complete Local Name too needs to be +# placed in the AUX_ADV_IND PDU compared to when it is placed in ADV_SCAN_IND +# PDU in the case of legacy advertising. +CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=36 diff --git a/samples/bluetooth/peripheral_hr/sample.yaml b/samples/bluetooth/peripheral_hr/sample.yaml index 71a19327c6..afc3077ac1 100644 --- a/samples/bluetooth/peripheral_hr/sample.yaml +++ b/samples/bluetooth/peripheral_hr/sample.yaml @@ -10,6 +10,38 @@ tests: integration_platforms: - qemu_cortex_m3 tags: bluetooth + sample.bluetooth.peripheral_hr.bt_ll_sw_split.extended: + harness: bluetooth + platform_allow: + - nrf52_bsim + - nrf5340bsim/nrf5340/cpuapp + - nrf52dk/nrf52832 + - nrf52840dk/nrf52840 + - nrf5340dk/nrf5340/cpuapp + integration_platforms: + - nrf52_bsim + - nrf5340bsim/nrf5340/cpuapp + - nrf52dk/nrf52832 + - nrf52840dk/nrf52840 + - nrf5340dk/nrf5340/cpuapp + extra_args: EXTRA_CONF_FILE=overlay-extended.conf + tags: bluetooth + sample.bluetooth.peripheral_hr.bt_ll_sw_split.phy_coded: + harness: bluetooth + platform_allow: + - nrf52_bsim + - nrf5340bsim/nrf5340/cpuapp + - nrf52dk/nrf52832 + - nrf52840dk/nrf52840 + - nrf5340dk/nrf5340/cpuapp + integration_platforms: + - nrf52_bsim + - nrf5340bsim/nrf5340/cpuapp + - nrf52dk/nrf52832 + - nrf52840dk/nrf52840 + - nrf5340dk/nrf5340/cpuapp + extra_args: EXTRA_CONF_FILE=overlay-phy_coded.conf + tags: bluetooth sample.bluetooth.peripheral_hr_rv32m1_vega_openisa_rv32m1_ri5cy: platform_allow: rv32m1_vega/openisa_rv32m1/ri5cy tags: bluetooth diff --git a/samples/bluetooth/peripheral_hr/src/main.c b/samples/bluetooth/peripheral_hr/src/main.c index 11b43586d5..938de5f01e 100644 --- a/samples/bluetooth/peripheral_hr/src/main.c +++ b/samples/bluetooth/peripheral_hr/src/main.c @@ -1,6 +1,7 @@ /* main.c - Application main entry point */ /* + * Copyright (c) 2024 Nordic Semiconductor ASA * Copyright (c) 2015-2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 @@ -29,12 +30,23 @@ static const struct bt_data ad[] = { BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_HRS_VAL), BT_UUID_16_ENCODE(BT_UUID_BAS_VAL), - BT_UUID_16_ENCODE(BT_UUID_DIS_VAL)) + BT_UUID_16_ENCODE(BT_UUID_DIS_VAL)), +#if defined(CONFIG_BT_EXT_ADV) + BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1), +#endif /* CONFIG_BT_EXT_ADV */ }; +#if !defined(CONFIG_BT_EXT_ADV) static const struct bt_data sd[] = { BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1), }; +#endif /* !CONFIG_BT_EXT_ADV */ + +/* Use atomic variable, 2 bits for connection and disconnection state */ +static ATOMIC_DEFINE(state, 2U); + +#define STATE_CONNECTED 1U +#define STATE_DISCONNECTED 2U static void connected(struct bt_conn *conn, uint8_t err) { @@ -42,12 +54,16 @@ static void connected(struct bt_conn *conn, uint8_t err) printk("Connection failed (err 0x%02x)\n", err); } else { printk("Connected\n"); + + (void)atomic_set_bit(state, STATE_CONNECTED); } } static void disconnected(struct bt_conn *conn, uint8_t reason) { printk("Disconnected (reason 0x%02x)\n", reason); + + (void)atomic_set_bit(state, STATE_DISCONNECTED); } BT_CONN_CB_DEFINE(conn_callbacks) = { @@ -59,36 +75,14 @@ static void hrs_ntf_changed(bool enabled) { hrf_ntf_enabled = enabled; - printk("HRS notification status changed: %s\n", enabled ? "enabled" : "disabled"); + printk("HRS notification status changed: %s\n", + enabled ? "enabled" : "disabled"); } static struct bt_hrs_cb hrs_cb = { .ntf_changed = hrs_ntf_changed, }; -/** @brief Heart rate service callback register - * - * This function will register callbacks that will be called in - * certain events related to Heart rate service. - * - * @param cb Pointer to callbacks structure - */ - -static void bt_ready(void) -{ - int err; - - printk("Bluetooth initialized\n"); - - err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd)); - if (err) { - printk("Advertising failed to start (err %d)\n", err); - return; - } - - printk("Advertising successfully started\n"); -} - static void auth_cancel(struct bt_conn *conn) { char addr[BT_ADDR_LE_STR_LEN]; @@ -140,14 +134,66 @@ int main(void) return 0; } - bt_ready(); + printk("Bluetooth initialized\n"); bt_conn_auth_cb_register(&auth_cb_display); bt_hrs_cb_register(&hrs_cb); - /* Implement notification. At the moment there is no suitable way - * of starting delayed work so we do it here - */ + +#if !defined(CONFIG_BT_EXT_ADV) + printk("Starting Legacy Advertising (connectable and scannable)\n"); + err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd)); + if (err) { + printk("Advertising failed to start (err %d)\n", err); + return 0; + } + +#else /* CONFIG_BT_EXT_ADV */ + struct bt_le_adv_param adv_param = { + .id = BT_ID_DEFAULT, + .sid = 0U, + .secondary_max_skip = 0U, + .options = (BT_LE_ADV_OPT_EXT_ADV | + BT_LE_ADV_OPT_CONNECTABLE | + BT_LE_ADV_OPT_CODED), + .interval_min = BT_GAP_ADV_FAST_INT_MIN_2, + .interval_max = BT_GAP_ADV_FAST_INT_MAX_2, + .peer = NULL, + }; + struct bt_le_ext_adv *adv; + + printk("Creating a Coded PHY connectable non-scannable advertising set\n"); + err = bt_le_ext_adv_create(&adv_param, NULL, &adv); + if (err) { + printk("Failed to create Coded PHY extended advertising set (err %d)\n", err); + + printk("Creating a non-Coded PHY connectable non-scannable advertising set\n"); + adv_param.options &= ~BT_LE_ADV_OPT_CODED; + err = bt_le_ext_adv_create(&adv_param, NULL, &adv); + if (err) { + printk("Failed to create extended advertising set (err %d)\n", err); + return 0; + } + } + + printk("Setting extended advertising data\n"); + err = bt_le_ext_adv_set_data(adv, ad, ARRAY_SIZE(ad), NULL, 0); + if (err) { + printk("Failed to set extended advertising data (err %d)\n", err); + return 0; + } + + printk("Starting Extended Advertising (connectable non-scannable)\n"); + err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT); + if (err) { + printk("Failed to start extended advertising set (err %d)\n", err); + return 0; + } +#endif /* CONFIG_BT_EXT_ADV */ + + printk("Advertising successfully started\n"); + + /* Implement notification. */ while (1) { k_sleep(K_SECONDS(1)); @@ -156,6 +202,21 @@ int main(void) /* Battery level simulation */ bas_notify(); + + if (atomic_test_and_clear_bit(state, STATE_CONNECTED)) { + /* Connected callback executed */ + + } else if (atomic_test_and_clear_bit(state, STATE_DISCONNECTED)) { +#if defined(CONFIG_BT_EXT_ADV) + printk("Starting Extended Advertising (connectable and non-scannable)\n"); + err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT); + if (err) { + printk("Failed to start extended advertising set (err %d)\n", err); + return 0; + } +#endif /* CONFIG_BT_EXT_ADV */ + } } + return 0; }