diff --git a/doc/nrf-bm/release_notes/release_notes_changelog.rst b/doc/nrf-bm/release_notes/release_notes_changelog.rst index 414900f926..589e6c191f 100644 --- a/doc/nrf-bm/release_notes/release_notes_changelog.rst +++ b/doc/nrf-bm/release_notes/release_notes_changelog.rst @@ -139,6 +139,11 @@ Libraries * The ``slave_conn_int`` member in the :c:struct:`ble_adv_data` structure to :c:member:`ble_adv_data.periph_conn_int`. * The ``CONFIG_BLE_ADV_USE_WHITELIST`` Kconfig option to :kconfig:option:`CONFIG_BLE_ADV_USE_ALLOW_LIST`. + * Fixed: + + * An issue with the allow list functionality that made it possible for non-allow-listed devices to connect if advertising was started in either directed or directed high duty mode, but the directed modes had been disabled with Kconfig options. + * Two minor issues with the directed advertising set configuration that caused directed advertising to not work as intended. + * :ref:`lib_ble_conn_params` library: * Added: diff --git a/lib/bluetooth/ble_adv/ble_adv.c b/lib/bluetooth/ble_adv/ble_adv.c index f38c868763..d192c5ca49 100644 --- a/lib/bluetooth/ble_adv/ble_adv.c +++ b/lib/bluetooth/ble_adv/ble_adv.c @@ -45,8 +45,13 @@ static bool adv_mode_is_directed(enum ble_adv_mode mode) { switch (mode) { case BLE_ADV_MODE_DIRECTED_HIGH_DUTY: + if (IS_ENABLED(CONFIG_BLE_ADV_DIRECTED_ADVERTISING_HIGH_DUTY)) { + return true; + } __fallthrough; case BLE_ADV_MODE_DIRECTED: - return true; + if (IS_ENABLED(CONFIG_BLE_ADV_DIRECTED_ADVERTISING)) { + return true; + } __fallthrough; default: return false; } @@ -55,6 +60,14 @@ static bool adv_mode_is_directed(enum ble_adv_mode mode) static bool adv_mode_has_allow_list(enum ble_adv_mode mode) { switch (mode) { + case BLE_ADV_MODE_DIRECTED_HIGH_DUTY: + if (IS_ENABLED(CONFIG_BLE_ADV_DIRECTED_ADVERTISING_HIGH_DUTY)) { + return false; + } __fallthrough; + case BLE_ADV_MODE_DIRECTED: + if (IS_ENABLED(CONFIG_BLE_ADV_DIRECTED_ADVERTISING)) { + return false; + } __fallthrough; case BLE_ADV_MODE_FAST: case BLE_ADV_MODE_SLOW: return true; @@ -324,6 +337,8 @@ uint32_t ble_adv_start(struct ble_adv *ble_adv, enum ble_adv_mode mode) { uint32_t nrf_err; struct ble_adv_evt adv_evt; + ble_gap_adv_data_t *adv_data; + if (!ble_adv) { return NRF_ERROR_NULL; } @@ -341,6 +356,8 @@ uint32_t ble_adv_start(struct ble_adv *ble_adv, enum ble_adv_mode mode) /* Reset peer address */ memset(&ble_adv->peer_address, 0, sizeof(ble_adv->peer_address)); + adv_data = &ble_adv->adv_data; + /* If `mode` is initially directed advertising (and that's supported) * ask the application for a peer address */ @@ -349,6 +366,16 @@ uint32_t ble_adv_start(struct ble_adv *ble_adv, enum ble_adv_mode mode) ble_adv->peer_addr_reply_expected = true; adv_evt.evt_type = BLE_ADV_EVT_PEER_ADDR_REQUEST; ble_adv->evt_handler(ble_adv, &adv_evt); + + if (ble_adv->peer_addr_reply_expected == false) { + /* Peer address was set by the application. Use it. */ + ble_adv->adv_params.p_peer_addr = &ble_adv->peer_address; + adv_data = NULL; + } else { + /* No peer address was supplied. Skip directed advertising. */ + ble_adv->peer_addr_reply_expected = false; + mode = BLE_ADV_MODE_FAST; + } } } @@ -423,7 +450,7 @@ uint32_t ble_adv_start(struct ble_adv *ble_adv, enum ble_adv_mode mode) } if (mode != BLE_ADV_MODE_IDLE) { - nrf_err = sd_ble_gap_adv_set_configure(&ble_adv->adv_handle, &ble_adv->adv_data, + nrf_err = sd_ble_gap_adv_set_configure(&ble_adv->adv_handle, adv_data, &ble_adv->adv_params); if (nrf_err) { LOG_ERR("Failed to set advertising data, nrf_error %#x", nrf_err); diff --git a/tests/lib/bluetooth/ble_adv/src/unity_test.c b/tests/lib/bluetooth/ble_adv/src/unity_test.c index bd36608b95..2f1a70d4e1 100644 --- a/tests/lib/bluetooth/ble_adv/src/unity_test.c +++ b/tests/lib/bluetooth/ble_adv/src/unity_test.c @@ -18,9 +18,23 @@ #define MAX_ADV_MODES 5 uint16_t ble_adv_evt_type; +const ble_gap_addr_t test_addr = { + .addr_id_peer = false, + .addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC, + .addr = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11}, +}; + static void ble_adv_evt_handler(struct ble_adv *adv, const struct ble_adv_evt *adv_evt) { ble_adv_evt_type = adv_evt->evt_type; + + switch (adv_evt->evt_type) { + case BLE_ADV_EVT_PEER_ADDR_REQUEST: + ble_adv_peer_addr_reply(adv, &test_addr); + break; + default: + break; + } } void test_ble_adv_conn_cfg_tag_set(void) @@ -233,11 +247,11 @@ void test_ble_adv_start(void) TEST_ASSERT_TRUE(ble_adv_evt_type == BLE_ADV_EVT_IDLE); } if (mode[i] == BLE_ADV_MODE_DIRECTED_HIGH_DUTY) { - TEST_ASSERT_TRUE(ble_adv.peer_addr_reply_expected == true); + TEST_ASSERT_TRUE(ble_adv.peer_addr_reply_expected == false); TEST_ASSERT_TRUE(ble_adv_evt_type == BLE_ADV_EVT_DIRECTED_HIGH_DUTY); } if (mode[i] == BLE_ADV_MODE_DIRECTED) { - TEST_ASSERT_TRUE(ble_adv.peer_addr_reply_expected == true); + TEST_ASSERT_TRUE(ble_adv.peer_addr_reply_expected == false); TEST_ASSERT_TRUE(ble_adv_evt_type == BLE_ADV_EVT_DIRECTED); } if (mode[i] == BLE_ADV_MODE_FAST) {