Skip to content

Commit e0c5c27

Browse files
Thalleyhenrikbrixandersen
authored andcommitted
Bluetooth: PACS: Improve handling of notify on reconnect
When we reconnect to a bonded device we always attempted to send the changed PACS notifications, regardless of whether the remote device has subscribed to them or not. This resulted in a lot of failed attempts to send notifications when CONFIG_BT_GATT_ENFORCE_SUBSCRIPTION is enabled (which it is by default). Ideally we would not set the flags for devices that have not subscribed, but since we cannot call bt_gatt_is_subscribed for non-connected devices, we need to do this when the notify_cb is called. It would be possible to use BT_GATT_CCC_MANAGED instead of BT_AUDIO_CCC to keep track of the writes for each client, but that would be a minor optimization which would require significant rework and additions to PACS. The current solution is inspired by the implementation used in has.c Signed-off-by: Emil Gydesen <[email protected]>
1 parent b6e0913 commit e0c5c27

File tree

1 file changed

+62
-7
lines changed

1 file changed

+62
-7
lines changed

subsys/bluetooth/audio/pacs.c

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,23 @@ static struct pacs {
110110
ATOMIC_DEFINE(flags, PACS_FLAG_NUM);
111111

112112
struct pacs_client clients[CONFIG_BT_MAX_PAIRED];
113+
114+
struct bt_gatt_attr *available_ctx_attr;
115+
#if defined(CONFIG_BT_PACS_SUPPORTED_CONTEXT_NOTIFIABLE)
116+
struct bt_gatt_attr *supported_ctx_attr;
117+
#endif /* CONFIG_BT_PACS_SUPPORTED_CONTEXT_NOTIFIABLE */
118+
#if defined(CONFIG_BT_PAC_SNK_NOTIFIABLE)
119+
struct bt_gatt_attr *snk_pac_attr;
120+
#endif /* CONFIG_BT_PAC_SNK_NOTIFIABLE */
121+
#if defined(CONFIG_BT_PAC_SNK_LOC_NOTIFIABLE)
122+
struct bt_gatt_attr *snk_pac_loc_attr;
123+
#endif /* CONFIG_BT_PAC_SNK_LOC_NOTIFIABLE */
124+
#if defined(CONFIG_BT_PAC_SRC_NOTIFIABLE)
125+
struct bt_gatt_attr *src_pac_attr;
126+
#endif /* CONFIG_BT_PAC_SRC_NOTIFIABLE */
127+
#if defined(CONFIG_BT_PAC_SRC_LOC_NOTIFIABLE)
128+
struct bt_gatt_attr *src_pac_loc_attr;
129+
#endif /* CONFIG_BT_PAC_SRC_LOC_NOTIFIABLE */
113130
} pacs;
114131

115132

@@ -860,6 +877,35 @@ int bt_pacs_register(const struct bt_pacs_register_param *param)
860877
return -ENOEXEC;
861878
}
862879

880+
pacs.available_ctx_attr = bt_gatt_find_by_uuid(pacs_svc.attrs, pacs_svc.attr_count,
881+
BT_UUID_PACS_AVAILABLE_CONTEXT);
882+
__ASSERT_NO_MSG(pacs.available_ctx_attr != NULL);
883+
#if defined(CONFIG_BT_PACS_SUPPORTED_CONTEXT_NOTIFIABLE)
884+
pacs.supported_ctx_attr = bt_gatt_find_by_uuid(pacs_svc.attrs, pacs_svc.attr_count,
885+
BT_UUID_PACS_SUPPORTED_CONTEXT);
886+
__ASSERT_NO_MSG(pacs.supported_ctx_attr != NULL);
887+
#endif /* CONFIG_BT_PACS_SUPPORTED_CONTEXT_NOTIFIABLE */
888+
#if defined(CONFIG_BT_PAC_SNK_NOTIFIABLE)
889+
pacs.snk_pac_attr =
890+
bt_gatt_find_by_uuid(pacs_svc.attrs, pacs_svc.attr_count, BT_UUID_PACS_SNK);
891+
__ASSERT_NO_MSG(pacs.snk_pac_attr != NULL);
892+
#endif /* CONFIG_BT_PAC_SNK_NOTIFIABLE */
893+
#if defined(CONFIG_BT_PAC_SNK_LOC_NOTIFIABLE)
894+
pacs.snk_pac_loc_attr =
895+
bt_gatt_find_by_uuid(pacs_svc.attrs, pacs_svc.attr_count, BT_UUID_PACS_SNK_LOC);
896+
__ASSERT_NO_MSG(pacs.snk_pac_loc_attr != NULL);
897+
#endif /* CONFIG_BT_PAC_SNK_LOC_NOTIFIABLE */
898+
#if defined(CONFIG_BT_PAC_SRC_NOTIFIABLE)
899+
pacs.src_pac_attr =
900+
bt_gatt_find_by_uuid(pacs_svc.attrs, pacs_svc.attr_count, BT_UUID_PACS_SRC);
901+
__ASSERT_NO_MSG(pacs.src_pac_attr != NULL);
902+
#endif /* CONFIG_BT_PAC_SRC_NOTIFIABLE */
903+
#if defined(CONFIG_BT_PAC_SRC_LOC_NOTIFIABLE)
904+
pacs.src_pac_loc_attr =
905+
bt_gatt_find_by_uuid(pacs_svc.attrs, pacs_svc.attr_count, BT_UUID_PACS_SRC_LOC);
906+
__ASSERT_NO_MSG(pacs.src_pac_loc_attr != NULL);
907+
#endif /* CONFIG_BT_PAC_SRC_LOC_NOTIFIABLE */
908+
863909
return 0;
864910
}
865911

@@ -1005,6 +1051,7 @@ static int available_contexts_notify(struct bt_conn *conn)
10051051
return 0;
10061052
}
10071053

1054+
#if defined(CONFIG_BT_PACS_SUPPORTED_CONTEXT_NOTIFIABLE)
10081055
static int supported_contexts_notify(struct bt_conn *conn)
10091056
{
10101057
struct bt_pacs_context context = {
@@ -1022,6 +1069,7 @@ static int supported_contexts_notify(struct bt_conn *conn)
10221069
}
10231070
return 0;
10241071
}
1072+
#endif /* CONFIG_BT_PACS_SUPPORTED_CONTEXT_NOTIFIABLE */
10251073

10261074
void pacs_gatt_notify_complete_cb(struct bt_conn *conn, void *user_data)
10271075
{
@@ -1096,7 +1144,8 @@ static void notify_cb(struct bt_conn *conn, void *data)
10961144
}
10971145

10981146
#if defined(CONFIG_BT_PAC_SNK_NOTIFIABLE)
1099-
if (atomic_test_bit(client->flags, FLAG_SINK_PAC_CHANGED)) {
1147+
if (atomic_test_bit(client->flags, FLAG_SINK_PAC_CHANGED) &&
1148+
bt_gatt_is_subscribed(conn, pacs.snk_pac_attr, BT_GATT_CCC_NOTIFY)) {
11001149
LOG_DBG("Notifying Sink PAC");
11011150
err = pac_notify(conn, BT_AUDIO_DIR_SINK);
11021151
if (!err) {
@@ -1106,7 +1155,8 @@ static void notify_cb(struct bt_conn *conn, void *data)
11061155
#endif /* CONFIG_BT_PAC_SNK_NOTIFIABLE */
11071156

11081157
#if defined(CONFIG_BT_PAC_SNK_LOC_NOTIFIABLE)
1109-
if (atomic_test_bit(client->flags, FLAG_SINK_AUDIO_LOCATIONS_CHANGED)) {
1158+
if (atomic_test_bit(client->flags, FLAG_SINK_AUDIO_LOCATIONS_CHANGED) &&
1159+
bt_gatt_is_subscribed(conn, pacs.snk_pac_loc_attr, BT_GATT_CCC_NOTIFY)) {
11101160
LOG_DBG("Notifying Sink Audio Location");
11111161
err = pac_notify_loc(conn, BT_AUDIO_DIR_SINK);
11121162
if (!err) {
@@ -1116,7 +1166,8 @@ static void notify_cb(struct bt_conn *conn, void *data)
11161166
#endif /* CONFIG_BT_PAC_SNK_LOC_NOTIFIABLE */
11171167

11181168
#if defined(CONFIG_BT_PAC_SRC_NOTIFIABLE)
1119-
if (atomic_test_bit(client->flags, FLAG_SOURCE_PAC_CHANGED)) {
1169+
if (atomic_test_bit(client->flags, FLAG_SOURCE_PAC_CHANGED) &&
1170+
bt_gatt_is_subscribed(conn, pacs.src_pac_attr, BT_GATT_CCC_NOTIFY)) {
11201171
LOG_DBG("Notifying Source PAC");
11211172
err = pac_notify(conn, BT_AUDIO_DIR_SOURCE);
11221173
if (!err) {
@@ -1126,7 +1177,8 @@ static void notify_cb(struct bt_conn *conn, void *data)
11261177
#endif /* CONFIG_BT_PAC_SRC_NOTIFIABLE */
11271178

11281179
#if defined(CONFIG_BT_PAC_SRC_LOC_NOTIFIABLE)
1129-
if (atomic_test_and_clear_bit(client->flags, FLAG_SOURCE_AUDIO_LOCATIONS_CHANGED)) {
1180+
if (atomic_test_bit(client->flags, FLAG_SOURCE_AUDIO_LOCATIONS_CHANGED) &&
1181+
bt_gatt_is_subscribed(conn, pacs.src_pac_loc_attr, BT_GATT_CCC_NOTIFY)) {
11301182
LOG_DBG("Notifying Source Audio Location");
11311183
err = pac_notify_loc(conn, BT_AUDIO_DIR_SOURCE);
11321184
if (!err) {
@@ -1135,22 +1187,25 @@ static void notify_cb(struct bt_conn *conn, void *data)
11351187
}
11361188
#endif /* CONFIG_BT_PAC_SRC_LOC_NOTIFIABLE */
11371189

1138-
if (atomic_test_bit(client->flags, FLAG_AVAILABLE_AUDIO_CONTEXT_CHANGED)) {
1190+
if (atomic_test_bit(client->flags, FLAG_AVAILABLE_AUDIO_CONTEXT_CHANGED) &&
1191+
bt_gatt_is_subscribed(conn, pacs.available_ctx_attr, BT_GATT_CCC_NOTIFY)) {
11391192
LOG_DBG("Notifying Available Contexts");
11401193
err = available_contexts_notify(conn);
11411194
if (!err) {
11421195
atomic_clear_bit(client->flags, FLAG_AVAILABLE_AUDIO_CONTEXT_CHANGED);
11431196
}
11441197
}
11451198

1146-
if (IS_ENABLED(CONFIG_BT_PACS_SUPPORTED_CONTEXT_NOTIFIABLE) &&
1147-
atomic_test_bit(client->flags, FLAG_SUPPORTED_AUDIO_CONTEXT_CHANGED)) {
1199+
#if defined(CONFIG_BT_PACS_SUPPORTED_CONTEXT_NOTIFIABLE)
1200+
if (atomic_test_bit(client->flags, FLAG_SUPPORTED_AUDIO_CONTEXT_CHANGED) &&
1201+
bt_gatt_is_subscribed(conn, pacs.supported_ctx_attr, BT_GATT_CCC_NOTIFY)) {
11481202
LOG_DBG("Notifying Supported Contexts");
11491203
err = supported_contexts_notify(conn);
11501204
if (!err) {
11511205
atomic_clear_bit(client->flags, FLAG_SUPPORTED_AUDIO_CONTEXT_CHANGED);
11521206
}
11531207
}
1208+
#endif /* CONFIG_BT_PACS_SUPPORTED_CONTEXT_NOTIFIABLE */
11541209
}
11551210

11561211
static void deferred_nfy_work_handler(struct k_work *work)

0 commit comments

Comments
 (0)