-
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: has: Ensure that notifications are sent #61980
Bluetooth: has: Ensure that notifications are sent #61980
Conversation
b884dd3
to
085952f
Compare
561273c
to
f771b20
Compare
f771b20
to
6e485c4
Compare
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.
Why are we mostly re-implementing the HAS client again here?
Couldn't we reuse a lot of the code from the actual implementation?
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.
As HAS client unsubscribes from the notifications on disconnection, I cannot use it for offline behavior test cases
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.
As HAS client unsubscribes from the notifications on disconnection, I cannot use it for offline behavior test cases
Wouldn't it be easier to implement support for bonding in the client, than reimplementing a new HAS client that supports that? This just seems like much more effort than fixing the missing feature from the current HAS client :)
But can be done in a separate PR.
subsys/bluetooth/audio/has.c
Outdated
@@ -589,7 +687,7 @@ static int bt_has_cp_generic_update(struct has_client *client, const struct has_ | |||
preset_changed_prepare(&buf, BT_HAS_CHANGE_ID_GENERIC_UPDATE, is_last); | |||
|
|||
generic_update = net_buf_simple_add(&buf, sizeof(*generic_update)); | |||
generic_update->prev_index = get_prev_preset_index(preset); | |||
generic_update->prev_index = preset_get_prev_index(preset); |
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.
This will provide a wrapped index. The first item in the list has to have a prevIndex of 0.
6e485c4
to
a2f2940
Compare
Fixed preset list notifications after reconnection if the tail of the preset list have changed (the las one preset have been removed). In such case:
|
6efa790
to
bc400b9
Compare
This fixes testing and clearing features flag. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This fixes code indentation. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This removes revering the features value back to previous state if work submission failes. Even if it fails it indicates an internal sysworkq issue, so even retry won't help. The client can read the features value anyway, thus it's sane to just log an error in such case. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This fixes missing setting of FLAG_CONTROL_POINT_NOTIFY flag that indicate whether submit control_point_work. In case the there are more indications/notifications to sent (is_last flag is unset), the FLAG_CONTROL_POINT_NOTIFY shall be set to resubmit control_point_work. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This moves common code to set_preset_availability function to be called from bt_has_preset_available and bt_has_preset_unavailable. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
Verify that a HAS Server IUT sends changed characteristic notifications or indications when the Lower Tester reconnects. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
8087ca0
to
d8478f8
Compare
Defer sending the features, active index, preset list and preset read response to sysworkq and retry sending in case failed due to buffers not available at the moment. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This refactors the preset list to use sys_slist API. There have been various issues seen while iterating presets, thus it's more save to use well-defined and tested sys_slist API. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
Some of the data shall be persistent across connections to bonded clients. This includes notidication state flags that are used to determine whether notify bonded client after reconnection. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This fixes sending proper Preset List notifications after reconnection. The issue was observed when the last preset known to the client has been removed. As we do not hold the information about the deleted presets, we need to use Generic Update procedure to: 1. Notify the presets that have been removed in range (PrevIndex = current_preset_last, Index=previous_preset_last) 2. Notify deletion of preset Index=previous_preset_last. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This fixes missing memset of parameters used for indications and/or notifications. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
b2b7135
to
85d80f3
Compare
subsys/bluetooth/audio/Kconfig.has
Outdated
@@ -9,6 +9,7 @@ menuconfig BT_HAS | |||
select EXPERIMENTAL | |||
select UTF8 | |||
select BT_GATT_DYNAMIC_DB | |||
select BT_GATT_AUTO_UPDATE_MTU |
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.
This is an interesting addition.
We've seen issues with Android, where Android (as the central) did not properly update the MTU on connection, which mean that some notifications sent by us (as peripheral) could not be done, due to MTU not matching the requirements from e.g. BAP.
HOWEVER
BT_GATT_AUTO_UPDATE_MTU
depends on BT_GATT_CLIENT
, which may not always be the case here for BT_HAS
. So I don't think we should add select BT_GATT_AUTO_UPDATE_MTU
here, but maybe we need to wait with the notifications until the MTU has been exchanged?
This is, btw, a general issue with all the LE Audio service implementations, where we cannot assume that the MTU has been exchanged when we are the server (and not can we expect it to do it ourself, if we are not the client).
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.
This is an interesting addition.
We've seen issues with Android, where Android (as the central) did not properly update the MTU on connection, which mean that some notifications sent by us (as peripheral) could not be done, due to MTU not matching the requirements from e.g. BAP.
Can you elaborate? Was the MTU requested too small?
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, we've seen issues where we try to send notifications on reconnect of size e.g. 30 (assuming that the MTU is 64 as mandated by e.g. the BAP spec), because the phone did not request an update to the MTU before our first notification. I think it would make sense for all services in profiles that depend on BAP (CAP, TMAP, HAP, etc.) wait with sending notifications on reconnect until after the GATT MTU has been exchanged (at least the ones where it may be larger than the initial MTU of 23).
I think that we should probably add select BT_GATT_AUTO_UPDATE_MTU
to any profile enabled where we act as the GATT client (e.g. BT_HAS_CLIENT
), but we should not enable it for profiles where we are the GATT server (e.g. BT_HAS
), as we cannot be sure that BT_GATT_CLIENT
is enabled.
I am unsure what happens if a Kconfig select
s another Kconfig without satisfying the dependencies.
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, we've seen issues where we try to send notifications on reconnect of size e.g. 30 (assuming that the MTU is 64 as mandated by e.g. the BAP spec), because the phone did not request an update to the MTU before our first notification. I think it would make sense for all services in profiles that depend on BAP (CAP, TMAP, HAP, etc.) wait with sending notifications on reconnect until after the GATT MTU has been exchanged (at least the ones where it may be larger than the initial MTU of 23).
I would say it's not phone's fault that the server wants to send the notification that does not fit MTU.
On the other hand the server does not know when the client is ready to receive the notifications (e.g. the profiles or some application is ready).
As there is no dedicated L2CAP channel PSM the client connects to, but ATT which is available right after connection this causes issues like that IMO.
I think that we should probably add
select BT_GATT_AUTO_UPDATE_MTU
to any profile enabled where we act as the GATT client (e.g.BT_HAS_CLIENT
), but we should not enable it for profiles where we are the GATT server (e.g.BT_HAS
), as we cannot be sure thatBT_GATT_CLIENT
is enabled.
BT_HAS_CLIENT
selects BT_GATT_AUTO_UPDATE_MTU
already. For profiles that are written on top of GATT Server I think that we should truncate the notifications, and apply some timeout waiting tor ATT exchange.
BTW, it would be helpful if we could have a function that will return true/false to know whether MTU was or was not already exchanged.
Like in HAS case in security_changed
callback, I would like to check whether I still need to wait for MTU to be exchanged or it was exchanged already but the MTU stayed at 23 bytes
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, it would be helpful if we could have a function that will return true/false to know whether MTU was or was not already exchanged.
We have bt_gatt_get_mtu
, and I guess you could simply do bool mtu_exchanged = bt_gatt_get_mtu() == BT_ATT_DEFAULT_LE_MTU
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.
This won't work, because if bt_gatt_get_mtu
returns 23, it means either the MTU was not exchanged, or it was exchanged and is 23. So one does not know whether it may still expect MTU Exchange 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.
Good point.
IIRC the bt_gatt_cb.att_mtu_updated
is even called on connection (bt_att_connected
calls att_chan_mtu_updated
), so we can't even use the callback.
I'll raise a GH issue for 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.
85d80f3
to
8087ac2
Compare
This will truncate ATT notifications/indications if exceed ATT MTU size. It is up to the client to exchange MTU. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This makes use of bt_conn_get_info function to access the conn address. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This adds more logs for debugging purposes. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
8087ac2
to
46f74aa
Compare
This ensures active preset index, HAS features and partially control point notifications are sent.
The code retries sending notifications in case of lack of available buffers.
Partially addresses #57454