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

Bluetooth: Host: Fix connection establishment upon RPA timeout #72674

Conversation

rugeGerritsen
Copy link
Collaborator

Before this commit, the following bugs were present:

  • When CONFIG_BT_FILTER_ACCEPT_LIST was set, connection establishment was cancelled upon RPA timeout. This required the application to restart the initiator every RPA timeout.
  • When CONFIG_BT_FILTER_ACCEPT_LIST was not set, the RPA was not updated while the initiator was running.

This commit unifies the RPA timeout handling for both these cases. Upon RPA timeout the initiator is cancelled and restarted when the controller raises the LE Connection Complete event. The workqueue state is checked when restarting the initiator to prevent it being restarted when the timeout is hit.

Corresponding test cases have been added to ensure that this feature works.

/* Create connection canceled by timeout */
}
} else {
int busy_status = k_work_delayable_busy_get(&conn->deferred_work);
Copy link
Collaborator Author

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?

Copy link
Collaborator

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?

Copy link
Collaborator Author

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

Copy link
Collaborator

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?

Copy link
Collaborator Author

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!

Copy link
Collaborator Author

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

@rugeGerritsen
Copy link
Collaborator Author

Note: If we decide to do #71751, we will not need these complex code paths

@jori-nordic
Copy link
Contributor

Unfortunately we will still have complexity regarding the resolving and accept lists. All roles have to be stopped for edits, @alwa-nordic is banging his head on this problem right now. He's implementing a module to take care of this properly.

Copy link
Member

@aescolar aescolar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two trivial nits

subsys/bluetooth/host/hci_core.c Outdated Show resolved Hide resolved
tests/bsim/bluetooth/host/privacy/central/src/main.c Outdated Show resolved Hide resolved
tests/bsim/bluetooth/host/privacy/central/src/tester.c Outdated Show resolved Hide resolved
tests/bsim/bluetooth/host/privacy/central/src/tester.c Outdated Show resolved Hide resolved
tests/bsim/bluetooth/host/privacy/central/src/dut.c Outdated Show resolved Hide resolved
tests/bsim/bluetooth/host/privacy/central/src/dut.c Outdated Show resolved Hide resolved
Comment on lines +160 to +169
err = bt_le_ext_adv_create(&params, &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);
Copy link
Collaborator

Choose a reason for hiding this comment

The 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 bt_testlib_adv_conn?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The 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 BT_LE_ADV_OPT_USE_IDENTITY so that the advertiser would use the same address when restarting

Copy link
Collaborator

Choose a reason for hiding this comment

The 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

@rugeGerritsen rugeGerritsen force-pushed the fix_conn_create_with_rpa_timeout branch 2 times, most recently from 6abdff3 to e11a142 Compare May 14, 2024 20:32
Before this commit, the following bugs were present:
- When `CONFIG_BT_FILTER_ACCEPT_LIST` was set, connection establishment
  was cancelled upon RPA timeout. This required the application
  to restart the initiator every RPA timeout.
- When `CONFIG_BT_FILTER_ACCEPT_LIST` was not set, the RPA was not updated
  while the initiator was running.

This commit unifies the RPA timeout handling for both these cases.
Upon RPA timeout the initiator is cancelled and restarted when
the controller raises the LE Connection Complete event.
The workqueue state is checked when restarting the initiator to prevent
it being restarted when the timeout is hit.

Corresponding test cases have been added to ensure that this
feature works.

Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
@rugeGerritsen rugeGerritsen force-pushed the fix_conn_create_with_rpa_timeout branch from e11a142 to f373444 Compare May 28, 2024 07:42
@carlescufi carlescufi merged commit ff80c0b into zephyrproject-rtos:main May 28, 2024
24 checks passed
rugeGerritsen added a commit to rugeGerritsen/zephyr that referenced this pull request Jun 3, 2024
zephyrproject-rtos#72674 fixed
a bug where this configuration did not work.

The timeout check that was present in the code was useless and
not working because the check was run before a default timeout
of 0 was converted to a real timeout.

Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
rugeGerritsen added a commit to rugeGerritsen/zephyr that referenced this pull request Jun 3, 2024
zephyrproject-rtos#72674 fixed
a bug where this configuration did not work.

Now that this configuration is tested, we should mark it
as supported.

The timeout check that was present in the code before
was useless and was not working because the check was
run before a default timeout of 0 was converted to a timeout.

Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants