-
Notifications
You must be signed in to change notification settings - Fork 6.9k
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
Bluetooth: Host: Fix connection establishment upon RPA timeout #72674
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,10 @@ | |
#include <zephyr/bluetooth/conn.h> | ||
#include <zephyr/toolchain.h> | ||
|
||
#include <babblekit/testcase.h> | ||
|
||
DEFINE_FLAG(flag_new_address); | ||
DEFINE_FLAG(flag_connected); | ||
|
||
void scanned_cb(struct bt_le_ext_adv *adv, struct bt_le_ext_adv_scanned_info *info) | ||
{ | ||
|
@@ -64,8 +67,14 @@ void scanned_cb(struct bt_le_ext_adv *adv, struct bt_le_ext_adv_scanned_info *in | |
old_addr = new_addr; | ||
} | ||
|
||
static void connected_cb(struct bt_le_ext_adv *adv, struct bt_le_ext_adv_connected_info *info) | ||
{ | ||
SET_FLAG(flag_connected); | ||
} | ||
|
||
static struct bt_le_ext_adv_cb adv_callbacks = { | ||
.scanned = scanned_cb, | ||
.connected = connected_cb | ||
}; | ||
|
||
void start_advertising(void) | ||
|
@@ -125,3 +134,54 @@ void tester_procedure(void) | |
|
||
PASS("PASS\n"); | ||
} | ||
|
||
void tester_procedure_periph_delayed_start_of_conn_adv(void) | ||
{ | ||
backchannel_init(0); | ||
|
||
int err; | ||
struct bt_le_adv_param params = | ||
BT_LE_ADV_PARAM_INIT(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_USE_IDENTITY, | ||
BT_GAP_ADV_FAST_INT_MIN_2, | ||
BT_GAP_ADV_FAST_INT_MAX_2, NULL); | ||
struct bt_data ad; | ||
struct bt_le_ext_adv *adv; | ||
|
||
/* Enable bluetooth */ | ||
err = bt_enable(NULL); | ||
TEST_ASSERT(!err, "Failed to enable bluetooth (err %d)"); | ||
|
||
/* Advertiser to use a long RPA timeout */ | ||
err = bt_le_set_rpa_timeout(100); | ||
TEST_ASSERT(!err, "Failed to set RPA timeout (err %d)", err); | ||
|
||
err = bt_le_ext_adv_create(¶ms, &adv_callbacks, &adv); | ||
TEST_ASSERT(!err, "Failed to create advertising set (err %d)", err); | ||
|
||
ad.type = BT_DATA_NAME_COMPLETE; | ||
ad.data_len = strlen(CONFIG_BT_DEVICE_NAME); | ||
ad.data = (const uint8_t *)CONFIG_BT_DEVICE_NAME; | ||
|
||
err = bt_le_ext_adv_set_data(adv, &ad, 1, NULL, 0); | ||
TEST_ASSERT(!err, "Failed to set advertising data (err %d)", err); | ||
|
||
err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT); | ||
TEST_ASSERT(!err, "Failed to start advertiser (err %d)", err); | ||
Comment on lines
+158
to
+169
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some clever people have worked on a testlib for BSIM, and I think some of this could be replaced by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I looked into that initially. It is nice to have such a library. Here I explicitly wanted to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That makes sense. Maybe the testlib can/should be expanded to support more options |
||
|
||
backchannel_sync_wait(); | ||
|
||
err = bt_le_ext_adv_stop(adv); | ||
TEST_ASSERT(!err, "Failed to stop advertiser (err %d)", err); | ||
|
||
/* Wait a few RPA cycles before restaring the advertiser to force RPA timeout | ||
* on the DUT. | ||
*/ | ||
k_sleep(K_SECONDS(7)); | ||
Thalley marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT); | ||
TEST_ASSERT(!err, "Failed to restart advertiser (err %d)", err); | ||
|
||
WAIT_FOR_FLAG(flag_connected); | ||
|
||
PASS("PASS\n"); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/usr/bin/env bash | ||
# Copyright 2024 Nordic Semiconductor ASA | ||
# SPDX-License-Identifier: Apache-2.0 | ||
set -eu | ||
|
||
source ${ZEPHYR_BASE}/tests/bsim/sh_common.source | ||
|
||
EXECUTE_TIMEOUT=100 | ||
verbosity_level=2 | ||
|
||
# Test that connection establishment times out when RPA | ||
# timeout is shorter than the connection establishment timeout | ||
simulation_id="test_central_connect_fails_with_short_rpa_timeout" | ||
|
||
central_exe="${BSIM_OUT_PATH}/bin/bs_${BOARD_TS}_$(guess_test_long_name)_prj_conf" | ||
Thalley marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
cd ${BSIM_OUT_PATH}/bin | ||
|
||
Execute "$central_exe" \ | ||
-v=${verbosity_level} -s=${simulation_id} -d=0 \ | ||
-testid=central_connect_fails_with_short_rpa_timeout -RealEncryption=1 | ||
|
||
Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ | ||
-D=1 -sim_length=60e6 $@ | ||
|
||
wait_for_background_jobs |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#!/usr/bin/env bash | ||
# Copyright 2024 Nordic Semiconductor ASA | ||
# SPDX-License-Identifier: Apache-2.0 | ||
set -eu | ||
|
||
source ${ZEPHYR_BASE}/tests/bsim/sh_common.source | ||
|
||
EXECUTE_TIMEOUT=100 | ||
verbosity_level=2 | ||
|
||
# Test connection establishment when the RPA times out before | ||
# we expect the connection to be established | ||
simulation_id="test_central_connect_short_rpa_timeout" | ||
|
||
central_exe="${BSIM_OUT_PATH}/bin/bs_${BOARD_TS}_$(guess_test_long_name)_prj_conf" | ||
peripheral_exe="${central_exe}" | ||
|
||
cd ${BSIM_OUT_PATH}/bin | ||
|
||
Execute "$central_exe" \ | ||
-v=${verbosity_level} -s=${simulation_id} -d=0 \ | ||
-testid=central_connect_short_rpa_timeout -RealEncryption=1 | ||
|
||
Execute "$peripheral_exe" \ | ||
-v=${verbosity_level} -s=${simulation_id} -d=1 \ | ||
-testid=periph_delayed_start_of_conn_adv -RealEncryption=1 | ||
|
||
Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ | ||
-D=2 -sim_length=60e6 $@ | ||
|
||
wait_for_background_jobs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation suggests to not use
k_work_delayable_busy_get()
. Should we use another approach here instead?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you refer to the documentation that states that here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about https://docs.zephyrproject.org/latest/kernel/services/threads/workqueue.html#don-t-optimize-prematurely. It feels a bit dangerous to check the state of a work queue item
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could an alternative be to use https://docs.zephyrproject.org/latest/kernel/services/threads/workqueue.html#c.k_work_cancel_delayable_sync and use the return value to determine the next step?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to look further into this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there is another way right now - we cannot simply cancel it as we need to know how much time is remaining. As long as the Bluetooth threads are cooperative this will work fine