-
Notifications
You must be signed in to change notification settings - Fork 8k
Bluetooth: Host: Add role-specific auto PHY update options #97198
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
base: main
Are you sure you want to change the base?
Conversation
c33aaac
to
b93d436
Compare
Posting here the latest from Discord: There shouldn't be a need for any of this automation in the host, neither for the PHY nor for the data length, due to the existence of Actually, we already have The only place where the |
Conclusion from the Bluetooth WG meeting: The set_default HCI commands don't actually cause any procedures to be triggered in themselves, so the explicit triggering by the host still has a purpose. I'll therefore roll back to my earlier plan to just do the role split for the phy update. For data length, we can either remove or deprecate the "auto" Kconfig option, since it serves no purpose now that the controller "no_auto_dle" quirk comes from DTS, i.e. is build-time resolvable in itself. Another improvement that can be done (follow-up PR) is to cache the controller max data length, since we read it already during HCI init, i.e. no need to redo this for every connection. |
Just re-iterating my statements from the WG meeting.
Agree. And keep the feature available (default disabled is ok) for users needing auto PHY update being handled by Host on connection establishment (i.e. while
Agree.
Agree. |
HCI spec does not prohibit asking for a larger value than the Controller supports. We can always do |
From 7.8.33 LE Set Data Length command (similar text exists for 7.8.35 LE Write Suggested Default Data Length command):
I think that make might sense to do. We probably want to use the largest data length, and since the host isn't using the results of |
b93d436
to
d6b78bb
Compare
subsys/bluetooth/host/conn.c
Outdated
switch (conn->role) { | ||
#if defined(AUTO_PHY_CENTRAL) | ||
case BT_HCI_ROLE_CENTRAL: | ||
if (AUTO_PHY_CENTRAL_SUPPORTED(bt_dev.le.features) && | ||
phy_change_needed(conn, AUTO_PHY_CENTRAL)) { | ||
err = bt_le_set_phy(conn, 0U, AUTO_PHY_CENTRAL_PREF, | ||
AUTO_PHY_CENTRAL_PREF, BT_HCI_LE_PHY_CODED_ANY); | ||
} | ||
if (conn->state != BT_CONN_CONNECTED) { | ||
return; | ||
break; | ||
#endif | ||
#if defined(AUTO_PHY_PERIPHERAL) | ||
case BT_HCI_ROLE_PERIPHERAL: | ||
if (AUTO_PHY_PERIPHERAL_SUPPORTED(bt_dev.le.features) && | ||
phy_change_needed(conn, AUTO_PHY_PERIPHERAL)) { | ||
err = bt_le_set_phy(conn, 0U, AUTO_PHY_PERIPHERAL_PREF, | ||
AUTO_PHY_PERIPHERAL_PREF, BT_HCI_LE_PHY_CODED_ANY); | ||
} | ||
break; | ||
#endif | ||
default: | ||
/* No PHY preferences set for the given role */ | ||
break; | ||
} |
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.
Given that phy_change_needed
takes conn
, the conn->role
check could be moved to that function which would make the code here significantly simpler
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'm all for finding ways to simplify this. However, I'm not sure how that exact proposal helps, since we also need the role to know what to pass to the bt_le_set_phy()
call.
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.
since we also need the role to know what to pass to the bt_le_set_phy() call.
Since the value is exclusively based on the conn->role
, then we don't need to pass it along at all. The function can just take the conn
pointer and nothing more :)
subsys/bluetooth/host/conn.c
Outdated
*/ | ||
static bool uses_symmetric_2mbit_phy(struct bt_conn *conn) | ||
#if defined(AUTO_PHY_CENTRAL) || defined(AUTO_PHY_PERIPHERAL) | ||
static bool phy_change_needed(struct bt_conn *conn, uint8_t phy) |
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.
Minor: "Needed" is a bit strongly worded here; we never really need to update the PHY, do we?
(Not a blocker, and the name is OK, but otherwise consider can_update_phy
or something 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.
I'm not sure "can" is any more intuitive here. This is whether we already have the PHY we prefer. If we do, then we don't "need" to do the procedure. What other word would be better?
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.
If we end up moving everything related to the PHY update into the function (see #97198 (comment)), it would probably just be do_auto_phy_update
:D
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.
Yes, I can certainly refactor this so that everything is in a single PHY-related function. It might have a slight impact on code size, but likely not much (if any)
subsys/bluetooth/host/Kconfig
Outdated
config BT_AUTO_PHY_PERIPHERAL_NONE | ||
bool "No PHY preference" |
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 would consider putting "None" as the first choice
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.
Done
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.
Btw, the _NONE options shouldn't really be needed since Kconfig has the optional
keyword for choice
statements which make it possible to not have any of the possible options selected. The problem with optional
(as I discovered) is that it then doesn't allow us to have a default where one of the options would anyway be selected. The only effect of a default for optional
is that when you select the choice on the top-level in menuconfig, then the default is what'll be initially enabled, however the top-level doesn't implicitly get enabled by specifying a default.
d6b78bb
to
cc810c8
Compare
b6b0b5f
to
8b36c01
Compare
#define BT_BUF_CMD_TX_AUTO_PHY_UPDATE (!IS_ENABLED(CONFIG_BT_AUTO_PHY_PERIPHERAL_NONE) && \ | ||
!IS_ENABLED(CONFIG_BT_AUTO_PHY_CENTRAL_NONE)) |
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.
#define BT_BUF_CMD_TX_AUTO_PHY_UPDATE (!IS_ENABLED(CONFIG_BT_AUTO_PHY_PERIPHERAL_NONE) && \ | |
!IS_ENABLED(CONFIG_BT_AUTO_PHY_CENTRAL_NONE)) | |
#define BT_BUF_CMD_TX_AUTO_PHY_UPDATE (1) |
Will the bsim test pass locally if hardcoding the buffer count? if it still fails, then there must be a bug in Host or in the Controller that is being exposed by the changes in this PR.
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 above had a bug: it should have been ||
instead of &&
. Let's see one more time. As for "locally", I have no idea since I don't have a development environment supported by babblesim.
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.
Still failing, but looks like a different error. So probably this particular issue is solved.
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.
d_00: @00:00:00.004938 Advertising failed to start (err -114)
This looks suspicious... let me checkout your branch and test it.
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.
@jhedberg please fixup
commit e6eb3c52637751ec2c0e613d0610127ab0ffd826
Author: Johan Hedberg <[email protected]>
Date: Fri Oct 10 15:38:56 2025 +0300
fixup! Bluetooth: samples/tests: Update auto PHY usage to recent changes
Remove deprecated Kconfig option usage, and replace it with corresponding
options which yield the same behavior as before.
Signed-off-by: Johan Hedberg <[email protected]>
diff --git a/tests/bsim/bluetooth/ll/conn/prj_split_tx_defer.conf b/tests/bsim/bluetooth/ll/conn/prj_split_tx_defer.conf
index 22dc32be4c4..6b6ecfc2b23 100644
--- a/tests/bsim/bluetooth/ll/conn/prj_split_tx_defer.conf
+++ b/tests/bsim/bluetooth/ll/conn/prj_split_tx_defer.conf
@@ -13,6 +13,8 @@ CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
CONFIG_BT_DEVICE_NAME="bsim_test_split"
CONFIG_BT_L2CAP_TX_BUF_COUNT=6
+CONFIG_BT_AUTO_PHY_PERIPHERAL_2M=y
+
CONFIG_BT_CTLR_PRIVACY=n
CONFIG_BT_CTLR_ADVANCED_FEATURES=y
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.
ae17c44
to
6b578db
Compare
Keep in mind that |
This is the call stack when that error is returned:
|
Discussed a while ago with @alwa-nordic to use one of the Zephyr LIBC implementations for BSIM tests to help make it easier to lookup the error from the value. We can probably also find a way to convert the values to strings using |
There's a regression from commit 8cfad44 which introduced trying to enable advertising twice. Remove the other attempt. Signed-off-by: Johan Hedberg <[email protected]>
The BT_AUTO_PHY_UPDATE option was problematic in the sense that it didn't really allow any kind of fine-tuning of what automation is desired. In particular, it didn't allow specifying which PHY was the preferred one (it was hardcoded to 2M) and also didn't allow specifying role-specific (central vs peripheral) preferences. To solve this, deprecate the old option, and instead introduce role-specific options that allow specifying 1M/2M/Coded/None as the preference. The new options have slightly different defaults than the new: for central role 2M stays as the preference, however since it's uncommon to require automated changes on the peripheral side the default is set to None there. Signed-off-by: Johan Hedberg <[email protected]>
Document the changes related to Bluetooth auto PHY update Kconfig options. Signed-off-by: Johan Hedberg <[email protected]>
Remove deprecated Kconfig option usage, and replace it with corresponding options which yield the same behavior as before. Signed-off-by: Johan Hedberg <[email protected]>
Make sure to consider both the new peripheral and central Kconfig options when calculating needed TX buffers. Signed-off-by: Johan Hedberg <[email protected]>
6b578db
to
dff2e4c
Compare
I'd say that would be nicer. Otherwise the next thing would be someone looking at one libc errno.h or another and getting confused. Just faster to see the error name printed. |
Turns out this was a red herring :( It was a bug, but not the cause of the test case failure. Only other idea I have is to 100% restore the PHY config for this test case, in case it depends on both sides to have "auto-phy 2M" enabled. |
Restore the auto-phy config for split_tx_defer test case, since it seems to fail otherwise. Signed-off-by: Johan Hedberg <[email protected]>
Now we have
|
I also get that for #91587. Sometimes it helps nudging the |
|
@Thalley that should not be happening unless there is unitialized memory in play (or the test is killed in CI due to taking too long). |
I've seen that happen on many occasions over the years, and I've never been able to find any memory issues with valgrind, ASAN or UBSAN :) |
Uh oh!
There was an error while loading. Please reload this page.