1
1
/* Bluetooth Audio Broadcast Source */
2
2
3
3
/*
4
- * Copyright (c) 2021-2023 Nordic Semiconductor ASA
4
+ * Copyright (c) 2021-2024 Nordic Semiconductor ASA
5
5
*
6
6
* SPDX-License-Identifier: Apache-2.0
7
7
*/
25
25
#include <zephyr/kernel.h>
26
26
#include <zephyr/logging/log.h>
27
27
#include <zephyr/net_buf.h>
28
+ #include <zephyr/sys/__assert.h>
28
29
#include <zephyr/sys/byteorder.h>
29
30
#include <zephyr/sys/check.h>
30
31
#include <zephyr/sys/slist.h>
@@ -55,6 +56,7 @@ static struct bt_bap_broadcast_subgroup
55
56
broadcast_source_subgroups [CONFIG_BT_BAP_BROADCAST_SRC_COUNT ]
56
57
[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT ];
57
58
static struct bt_bap_broadcast_source broadcast_sources [CONFIG_BT_BAP_BROADCAST_SRC_COUNT ];
59
+ static sys_slist_t bap_broadcast_source_cbs = SYS_SLIST_STATIC_INIT (& bap_broadcast_source_cbs );
58
60
59
61
/**
60
62
* 2 octets UUID
@@ -238,9 +240,9 @@ static void broadcast_source_iso_disconnected(struct bt_iso_chan *chan, uint8_t
238
240
}
239
241
240
242
static struct bt_iso_chan_ops broadcast_source_iso_ops = {
241
- .sent = broadcast_source_iso_sent ,
242
- .connected = broadcast_source_iso_connected ,
243
- .disconnected = broadcast_source_iso_disconnected ,
243
+ .sent = broadcast_source_iso_sent ,
244
+ .connected = broadcast_source_iso_connected ,
245
+ .disconnected = broadcast_source_iso_disconnected ,
244
246
};
245
247
246
248
bool bt_bap_ep_is_broadcast_src (const struct bt_bap_ep * ep )
@@ -440,8 +442,7 @@ static bool encode_base(struct bt_bap_broadcast_source *source, struct net_buf_s
440
442
*/
441
443
streams_encoded = 0 ;
442
444
SYS_SLIST_FOR_EACH_CONTAINER (& source -> subgroups , subgroup , _node ) {
443
- if (!encode_base_subgroup (subgroup ,
444
- & source -> stream_data [streams_encoded ],
445
+ if (!encode_base_subgroup (subgroup , & source -> stream_data [streams_encoded ],
445
446
& streams_encoded , buf )) {
446
447
return false;
447
448
}
@@ -454,21 +455,18 @@ static void broadcast_source_cleanup(struct bt_bap_broadcast_source *source)
454
455
{
455
456
struct bt_bap_broadcast_subgroup * subgroup , * next_subgroup ;
456
457
457
- SYS_SLIST_FOR_EACH_CONTAINER_SAFE (& source -> subgroups , subgroup ,
458
- next_subgroup , _node ) {
458
+ SYS_SLIST_FOR_EACH_CONTAINER_SAFE (& source -> subgroups , subgroup , next_subgroup , _node ) {
459
459
struct bt_bap_stream * stream , * next_stream ;
460
460
461
- SYS_SLIST_FOR_EACH_CONTAINER_SAFE (& subgroup -> streams , stream ,
462
- next_stream , _node ) {
461
+ SYS_SLIST_FOR_EACH_CONTAINER_SAFE (& subgroup -> streams , stream , next_stream , _node ) {
463
462
bt_bap_iso_unbind_ep (stream -> ep -> iso , stream -> ep );
464
463
stream -> ep -> stream = NULL ;
465
464
stream -> ep = NULL ;
466
465
stream -> codec_cfg = NULL ;
467
466
stream -> qos = NULL ;
468
467
stream -> group = NULL ;
469
468
470
- sys_slist_remove (& subgroup -> streams , NULL ,
471
- & stream -> _node );
469
+ sys_slist_remove (& subgroup -> streams , NULL , & stream -> _node );
472
470
}
473
471
sys_slist_remove (& source -> subgroups , NULL , & subgroup -> _node );
474
472
}
@@ -777,8 +775,7 @@ int bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_param *param,
777
775
bis_count ++ ;
778
776
}
779
777
780
- err = broadcast_source_setup_stream (index , stream ,
781
- codec_cfg , qos , source );
778
+ err = broadcast_source_setup_stream (index , stream , codec_cfg , qos , source );
782
779
if (err != 0 ) {
783
780
LOG_DBG ("Failed to setup streams[%zu]: %d" , i , err );
784
781
broadcast_source_cleanup (source );
@@ -1039,7 +1036,7 @@ int bt_bap_broadcast_source_update_metadata(struct bt_bap_broadcast_source *sour
1039
1036
int bt_bap_broadcast_source_start (struct bt_bap_broadcast_source * source , struct bt_le_ext_adv * adv )
1040
1037
{
1041
1038
struct bt_iso_chan * bis [BROADCAST_STREAM_CNT ];
1042
- struct bt_iso_big_create_param param = { 0 };
1039
+ struct bt_iso_big_create_param param = {0 };
1043
1040
struct bt_bap_broadcast_subgroup * subgroup ;
1044
1041
enum bt_bap_ep_state broadcast_state ;
1045
1042
struct bt_bap_stream * stream ;
@@ -1078,8 +1075,7 @@ int bt_bap_broadcast_source_start(struct bt_bap_broadcast_source *source, struct
1078
1075
param .latency = source -> qos -> latency ;
1079
1076
param .encryption = source -> encryption ;
1080
1077
if (param .encryption ) {
1081
- (void )memcpy (param .bcode , source -> broadcast_code ,
1082
- sizeof (param .bcode ));
1078
+ (void )memcpy (param .bcode , source -> broadcast_code , sizeof (param .bcode ));
1083
1079
}
1084
1080
#if defined(CONFIG_BT_ISO_TEST_PARAMS )
1085
1081
param .irc = source -> irc ;
@@ -1125,14 +1121,12 @@ int bt_bap_broadcast_source_stop(struct bt_bap_broadcast_source *source)
1125
1121
return - EALREADY ;
1126
1122
}
1127
1123
1128
- err = bt_iso_big_terminate (source -> big );
1124
+ err = bt_iso_big_terminate (source -> big );
1129
1125
if (err ) {
1130
1126
LOG_DBG ("Failed to terminate BIG (err %d)" , err );
1131
1127
return err ;
1132
1128
}
1133
1129
1134
- source -> big = NULL ;
1135
-
1136
1130
return 0 ;
1137
1131
}
1138
1132
@@ -1188,3 +1182,102 @@ int bt_bap_broadcast_source_get_base(struct bt_bap_broadcast_source *source,
1188
1182
1189
1183
return 0 ;
1190
1184
}
1185
+
1186
+ static struct bt_bap_broadcast_source * get_broadcast_source_by_big (const struct bt_iso_big * big )
1187
+ {
1188
+ for (size_t i = 0U ; i < ARRAY_SIZE (broadcast_sources ); i ++ ) {
1189
+ if (broadcast_sources [i ].big == big ) {
1190
+ return & broadcast_sources [i ];
1191
+ }
1192
+ }
1193
+
1194
+ return NULL ;
1195
+ }
1196
+
1197
+ static void big_started_cb (struct bt_iso_big * big )
1198
+ {
1199
+ struct bt_bap_broadcast_source * source = get_broadcast_source_by_big (big );
1200
+ struct bt_bap_broadcast_source_cb * listener ;
1201
+
1202
+ if (source == NULL ) {
1203
+ /* Not one of ours */
1204
+ return ;
1205
+ }
1206
+
1207
+ SYS_SLIST_FOR_EACH_CONTAINER (& bap_broadcast_source_cbs , listener , _node ) {
1208
+ if (listener -> started != NULL ) {
1209
+ listener -> started (source );
1210
+ }
1211
+ }
1212
+ }
1213
+
1214
+ static void big_stopped_cb (struct bt_iso_big * big , uint8_t reason )
1215
+ {
1216
+ struct bt_bap_broadcast_source * source = get_broadcast_source_by_big (big );
1217
+ struct bt_bap_broadcast_source_cb * listener ;
1218
+
1219
+ if (source == NULL ) {
1220
+ /* Not one of ours */
1221
+ return ;
1222
+ }
1223
+
1224
+ source -> big = NULL ;
1225
+
1226
+ SYS_SLIST_FOR_EACH_CONTAINER (& bap_broadcast_source_cbs , listener , _node ) {
1227
+ if (listener -> stopped != NULL ) {
1228
+ listener -> stopped (source , reason );
1229
+ }
1230
+ }
1231
+ }
1232
+
1233
+ int bt_bap_broadcast_source_register_cb (struct bt_bap_broadcast_source_cb * cb )
1234
+ {
1235
+ static bool iso_big_cb_registered ;
1236
+
1237
+ CHECKIF (cb == NULL ) {
1238
+ LOG_DBG ("cb is NULL" );
1239
+
1240
+ return - EINVAL ;
1241
+ }
1242
+
1243
+ if (sys_slist_find (& bap_broadcast_source_cbs , & cb -> _node , NULL )) {
1244
+ LOG_DBG ("cb %p is already registered" , cb );
1245
+
1246
+ return - EEXIST ;
1247
+ }
1248
+
1249
+ if (!iso_big_cb_registered ) {
1250
+ static struct bt_iso_big_cb big_cb = {
1251
+ .started = big_started_cb ,
1252
+ .stopped = big_stopped_cb ,
1253
+ };
1254
+ const int err = bt_iso_big_register_cb (& big_cb );
1255
+
1256
+ if (err != 0 ) {
1257
+ __ASSERT (false, "Failed to register ISO BIG callbacks: %d" , err );
1258
+ }
1259
+
1260
+ iso_big_cb_registered = true;
1261
+ }
1262
+
1263
+ sys_slist_append (& bap_broadcast_source_cbs , & cb -> _node );
1264
+
1265
+ return 0 ;
1266
+ }
1267
+
1268
+ int bt_bap_broadcast_source_unregister_cb (struct bt_bap_broadcast_source_cb * cb )
1269
+ {
1270
+ CHECKIF (cb == NULL ) {
1271
+ LOG_DBG ("cb is NULL" );
1272
+
1273
+ return - EINVAL ;
1274
+ }
1275
+
1276
+ if (!sys_slist_find_and_remove (& bap_broadcast_source_cbs , & cb -> _node )) {
1277
+ LOG_DBG ("cb %p is not registered" , cb );
1278
+
1279
+ return - ENOENT ;
1280
+ }
1281
+
1282
+ return 0 ;
1283
+ }
0 commit comments