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: Controller: Implement PAST Support #78894

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

lutb-ot
Copy link
Contributor

@lutb-ot lutb-ot commented Sep 23, 2024

Implements:

  • LLCP PDU Flow and unittests for Periodic Sync Indication
  • Implements PAST support in ULL
  • PAST bsim tests
  • Fix PAST support bap_scan_delegator

platform_allow:
- nrf52_bsim
- nrf5340bsim/nrf5340/
- nrf5340bsim/nrf5340/cpuapp
Copy link
Member

Choose a reason for hiding this comment

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

If you want to build for the nrf5340bsim/nrf5340/cpuapp you'll need to use sysbuild (you can check other bsim tests building for it)

tests/bluetooth/controller/mock_ctrl/src/ull_sync.c Outdated Show resolved Hide resolved
Copy link
Contributor

@cvinayak cvinayak left a comment

Choose a reason for hiding this comment

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

initial comments, will do re-review after these comments are addressed and CI jobs are passing.

subsys/bluetooth/controller/Kconfig Outdated Show resolved Hide resolved
subsys/bluetooth/controller/hci/hci.c Outdated Show resolved Hide resolved
Copy link
Contributor

@cvinayak cvinayak left a comment

Choose a reason for hiding this comment

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

With a very quick pass, the changes LGTM, I do not see any objections from my side. Just get the CI happy :-)

Copy link
Contributor

@cvinayak cvinayak left a comment

Choose a reason for hiding this comment

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

nitpick.... use Bluetooth and Controller with B and C in commit title and message body etc... (BT Spec documentation uses so).

@cvinayak cvinayak dismissed their stale review September 25, 2024 10:12

I change requests have been addressed.

@lutb-ot lutb-ot marked this pull request as ready for review September 25, 2024 18:25
cvinayak
cvinayak previously approved these changes Sep 25, 2024
Copy link
Collaborator

@Thalley Thalley left a comment

Choose a reason for hiding this comment

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

Very nice work. Great that you've added a bunch of tests for this

Most comments are code style and security related

Comment on lines +876 to 881
} else {
/* If past is supported - state will change */
if (supports_past(conn, pa_sync)) {
state_changed = true;
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

That is not how state changes in BASS works :) If there are not value changes, we shouldn't send a notification.

The current API is not great for PAST and should probably be improved, but the idea is that the application will call bt_bap_scan_delegator_set_pa_state with BT_BAP_PA_STATE_INFO_REQ to trigger PAST from the broadcast assistant. I think it makes sense for pa_sync_request to return this value in the future

subsys/bluetooth/controller/CMakeLists.txt Outdated Show resolved Hide resolved
subsys/bluetooth/controller/hci/hci.c Outdated Show resolved Hide resolved
subsys/bluetooth/controller/hci/hci.c Outdated Show resolved Hide resolved
Comment on lines +198 to +201
static inline struct pdu_adv *lll_adv_sync_data_curr_get(struct lll_adv_sync *lll)
{
return (void *)lll->data.pdu[lll->data.first];
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Something seems a bit out of place here: The function is called curr_get which I assume is short for current get, but it always uses lll->data.first.
Is that correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cvinayak will you be able to add more information here, as this function follows the same design as struct pdu_adv *lll_adv_aux_data_curr_get(struct lll_adv_aux *lll)

tests/bluetooth/controller/mock_ctrl/src/ull_adv_sync.c Outdated Show resolved Hide resolved
tests/bsim/bluetooth/audio/src/bap_scan_delegator_test.c Outdated Show resolved Hide resolved
Comment on lines +271 to +273
if (err == 0) {
err = bt_bap_scan_delegator_set_pa_state(state->recv_state->src_id,
BT_BAP_PA_STATE_INFO_REQ);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Very nice that you've added this support. Have you verified that it getting triggered correctly?

Comment on lines +8 to +9
CONFIG_BT_ISO_BROADCASTER=y
CONFIG_BT_ISO_SYNC_RECEIVER=y
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is ISO needed for this test?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, same as earlier message.

Comment on lines +40 to +50
#define FAIL(...) \
do { \
bst_result = Failed; \
bs_trace_error_time_line(__VA_ARGS__); \
} while (0)

#define PASS(...) \
do { \
bst_result = Passed; \
bs_trace_info_time(1, __VA_ARGS__); \
} while (0)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Consider having a look at the https://github.com/zephyrproject-rtos/zephyr/tree/main/tests/bsim/babblekit and https://github.com/zephyrproject-rtos/zephyr/tree/main/tests/bluetooth/common/testlib to see if you can reduce the overhead here by using the predefined test helpers

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is how it is done everywhere, so it should probably be a separate PR for fixing and cleaning this up everywhere in both host and controller bsim tests.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I understand your point, although I don't necessarily agree. We do not need to follow the structure of older tests if new tests could use frameworks that were not available when the older tests were written.

It's OK to keep as is, but could have saved you time to use the frameworks we have now :)

Comment on lines 7 to 8
#define INVALID_ADV_HANDLE 0xFF

Copy link
Collaborator

Choose a reason for hiding this comment

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

We already have BT_HCI_ADV_HANDLE_INVALID which we can use

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My bad, I'll fix that.

Comment on lines 11 to 12
#define INVALID_SYNC_HANDLE 0xFFFF

Copy link
Collaborator

Choose a reason for hiding this comment

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

We have BT_HCI_SYNC_HANDLE_INVALID that you can use instead

Comment on lines 162 to 167
struct {
uint8_t mode;
uint8_t cte_type;
uint16_t skip;
uint16_t timeout;
} past;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it make sense to define this struct by itself and use that in ull_conn, instead of the 4 individual values? Would make it easier to reset, and could even return those values as a reference or a single value instead of having 4 functions so that

	conn->past.mode    = ull_conn_default_past_param_mode_get();
	conn->past.skip    = ull_conn_default_past_param_skip_get();
	conn->past.timeout = ull_conn_default_past_param_timeout_get();
	conn->past.cte_type = ull_conn_default_past_param_ctetype_get();

could become something like

	conn->past = ull_conn_default_past_param_get();

or

	memcpy(&conn->past, ull_conn_default_past_param_get(), sizeof(conn->past));

or is there some value in having 4 separate functions and values for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, I think it will make perfect sense to make it into a single get function instead of four.

I'll make a change for that :)

INVALID_SYNC_HANDLE;
ctx->data.periodic_sync.adv_handle = adv_sync ? ull_adv_sync_handle_get(adv_sync) :
INVALID_ADV_HANDLE;
ctx->data.periodic_sync.id = service_data;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it make sense to use service_data instead of id in the periodic_sync struct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The only reason it is called ID is because of the naming in the Spec:

"ID shall be set to an identifier provided by the Host. This is for use by higher-level protocols and its value is not specified or used by this specification."

Copy link
Collaborator

Choose a reason for hiding this comment

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

Aha, interesting. I'm having trouble finding where it's defined that the id here is the same value as the service_data provided by the host. I believe it's correct that it is, but haven't found where that's explicitly stated

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I haven't seen it explicitly stated anywhere in the Spec. However, it is the only host parameter in HCI_LE_­Periodic_­Advertising_­Sync_­Transfer and HCI_LE_­Periodic_­Advertising_­Sync_­Transfer with the correct range and description, but it is not explicitly stated anywhere.

/* This is equivalent to:
* exactly one bit set, and no bit set is rfu's
*/
return (phy == PHY_1M || phy == PHY_2M || phy == PHY_CODED);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should PHY_2M be considered valid if CONFIG_BT_CTLR_PHY_2M=n? Ditto with coded?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It will be checked after: see: ull_llcp_past.c line:83:

`#if defined(CONFIG_BT_CTLR_PHY)
const uint8_t phy = pdu->llctrl.periodic_sync_ind.phy;

if (((phy & PHY_2M) && !IS_ENABLED(CONFIG_BT_CTLR_PHY_2M)) ||
    ((phy & PHY_CODED) && !IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED))) {
	/* Unsupported phy selected */
	return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
}

#endif /* CONFIG_BT_CTLR_PHY */`

conn_interval_us = conn->lll.interval * CONN_INT_UNIT_US;

/* Calculate offset and schedule sync radio events */
ready_delay_us = lll_radio_rx_ready_delay_get(lll->phy, 1);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
ready_delay_us = lll_radio_rx_ready_delay_get(lll->phy, 1);
ready_delay_us = lll_radio_rx_ready_delay_get(lll->phy, PHY_FLAGS_S8);

Right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that should be the most correct way. Will change that.

Adding PDU flow for Periodic Sync Indication

Signed-off-by: Lucas Mathias Balling <[email protected]>
Added LLCP PDU Periodic Sync Indication unittests

Signed-off-by: Lucas Mathias Balling <[email protected]>
Implement PAST support in ULL and fixed test after changed
dependencies in ull_sync_internal.c

Signed-off-by: Lucas Mathias Balling <[email protected]>
Implemented:
  * Central sync to broadcaster, connects to peripheral and
    transfers sync. Peripheral Syncs to PA
  * Broadcaster acting Central connects to peripheral
    and transfers sync. Peripheral sync to PA
  * Moved previous bis tests to test_bis.c and
    new PAST tests was added in test_past.c

Signed-off-by: Lucas Mathias Balling <[email protected]>
Fixed PAST support for bap_scan_delegator

Signed-off-by: Lucas Mathias Balling <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: In Review
Development

Successfully merging this pull request may close these issues.

5 participants