-
Notifications
You must be signed in to change notification settings - Fork 6.6k
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: Ensure only connected peers affect CCC value #80988
base: main
Are you sure you want to change the base?
Conversation
Picks up the thread of two of the commits from #44136 |
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 have liked if I was kept as author or co-author of the commits, but no matter. The important thing is it gets in :)
The two commits should ideally come in two PRs, since they are two separate behavior changes.
The doc on `_bt_gatt_ccc.value` specifies that only connected peers contribute to that value. But before this change, it was computed from all entries in `_bt_gatt_ccc.cfg`, which include bonded but not connected peers when `CONFIG_BT_SETTINGS_CCC_LAZY_LOADING` is set. Co-authored-by: Aleksander Wasaznik <[email protected]> Signed-off-by: Håvard Reierstad <[email protected]>
7306202
to
99e9927
Compare
Added you as co-author, didn't mean to steal your glory :) |
subsys/bluetooth/host/gatt.c
Outdated
struct bt_conn *conn = bt_conn_lookup_addr_le(ccc->cfg[i].id, &ccc->cfg[i].peer); | ||
|
||
if (conn) { | ||
value |= ccc->cfg[i].value; |
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 think this has been attempted before.
Isn't it dangerous to use values that are not defined as a bitfield in the BT core spec as a bitfield?
For example if the BT core spec ever introduces a new value 0x0003 then value
here would be the same as BT_GATT_CCC_NOTIFY | BT_GATT_CCC_INDICATE
.
This change feels less future-proof than the existing, and does not fix any issues. The value here would also be 0x0003 which is not defined in Zephyr, and if applications are testing for == BT_GATT_CCC_NOTIFY
or == BT_GATT_CCC_INDICATE
(which we have several cases of in Zephyr), then those checks will break.
The real issue is that the cfg_changed
callback does not consider that individual clients have different values.
/** @brief CCC attribute changed callback
*
* @param attr The attribute that's changed value
* @param value New value
*/
void (*cfg_changed)(const struct bt_gatt_attr *attr, uint16_t value);
should really be
/** @brief CCC attribute changed callback
*
* @param conn The connection that updated it's CCC value
* @param attr The attribute that's changed value
* @param value New value
*/
void (*cfg_changed)(struct bt_conn *conn, const struct bt_gatt_attr *attr, uint16_t value);
I would suggest to leave the existing callback as is, and introduce the new callback (and possibly deprecate the old one).
It feels like this is trying to fix a fundamental issue by applying a band-aid, while also introducing a breaking change as the callback value of 0x0003 (BT_GATT_CCC_NOTIFY | BT_GATT_CCC_INDICATE) is undefined.
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.
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 think this has been attempted before.
Isn't it dangerous to use values that are not defined as a bitfield in the BT core spec as a bitfield?
For example if the BT core spec ever introduces a new value 0x0003 then
value
here would be the same asBT_GATT_CCC_NOTIFY | BT_GATT_CCC_INDICATE
.
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 stand corrected :)
Thanks.
Should we consider redefining the values in Zephyr from 0x0001
and 0x0002
to BIT(0)
and BIT(2)
then?
In Zephyr we have quite a few cases where we treat it not as a bitfield:
They should be updated to use &
instead of ==
then, as otherwise if the GATT clients subscribe to both indication and notification, then those checks will now fail (granted that all the == BT_GATT_CCC_NOTIFY
would fail anyways due to the current version using the max of the 2.
I would also prefer if we somewhere (either in the values or in the documentation for cfg_changed
or somewhere else) make it clear that these are now bitfields in Zephyr, which they have not been so far.
Not sure if this change counts as a breaking stable API change, as they have been treated as non-bitfield for 9+ years in Zephyr. I'll leave that up to the maintainers of the host to decide.
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.
Thanks. Should we consider redefining the values in Zephyr from
0x0001
and 0x0002to
BIT(0)and
BIT(2)` then?
I agree! And I'll look into switching the checks to bitfields.
As for the breaking/nonbreaking, we should at least have a release note/changelog. Thoughts @alwa-nordic?
(Guess it's BIT(0) and BIT(1), but the point is the same)
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.
Good examples. In that case, this really is a breaking change. To be on the safe side, we should go with a deprecation, would you agree?
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.
We should remove the problematic change from this PR and evaluate how to move forward. I think we should either leave _bt_gatt_ccc.cfg_changed
as it is, or deprecate it without replacement. And we should, as @Thalley points out, address the lack of an event for changes in subscription. The only way to do that without breaking API is to add a new callback.
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.
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.
We should remove the problematic change from this PR and evaluate how to move forward.
Meaning keeping only the commit that checks whether the peer is connected or not?
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 added another issue:
99e9927
to
b4c7381
Compare
Only consider connected peers when summing CCC values instead of
connected or bonded.