@@ -186,7 +186,7 @@ static struct bt_bap_broadcast_sink *broadcast_sink_lookup_iso_chan(
186186{
187187 for (size_t i = 0U ; i < ARRAY_SIZE (broadcast_sinks ); i ++ ) {
188188 for (uint8_t j = 0U ; j < broadcast_sinks [i ].stream_count ; j ++ ) {
189- if (broadcast_sinks [i ].bis [j ] == chan ) {
189+ if (broadcast_sinks [i ].bis [j ]. chan == chan ) {
190190 return & broadcast_sinks [i ];
191191 }
192192 }
@@ -251,6 +251,7 @@ static void broadcast_sink_iso_recv(struct bt_iso_chan *chan,
251251 const struct bt_bap_stream_ops * ops ;
252252 struct bt_bap_stream * stream ;
253253 struct bt_bap_ep * ep = iso -> rx .ep ;
254+ size_t buf_len ;
254255
255256 if (ep == NULL ) {
256257 LOG_ERR ("iso %p not bound with ep" , chan );
@@ -265,8 +266,14 @@ static void broadcast_sink_iso_recv(struct bt_iso_chan *chan,
265266
266267 ops = stream -> ops ;
267268
269+ buf_len = net_buf_frags_len (buf );
268270 if (IS_ENABLED (CONFIG_BT_BAP_DEBUG_STREAM_DATA )) {
269- LOG_DBG ("stream %p ep %p len %zu" , stream , stream -> ep , net_buf_frags_len (buf ));
271+ LOG_DBG ("stream %p ep %p len %zu" , stream , stream -> ep , buf_len );
272+ }
273+
274+ if (buf_len > stream -> qos -> sdu ) {
275+ LOG_WRN ("Received %u octets but stream %p was only configured for %u" , buf_len ,
276+ stream , stream -> qos -> sdu );
270277 }
271278
272279 if (ops != NULL && ops -> recv != NULL ) {
@@ -522,79 +529,171 @@ static bool codec_lookup_id(const struct bt_pacs_cap *cap, void *user_data)
522529 return true;
523530}
524531
532+ struct store_base_info_data {
533+ struct bt_bap_broadcast_sink_bis bis [CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT ];
534+ struct bt_bap_broadcast_sink_subgroup subgroups [CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT ];
535+ struct bt_audio_codec_cfg * subgroup_codec_cfg ;
536+ uint32_t valid_indexes_bitfield ;
537+ uint8_t subgroup_count ;
538+ uint8_t bis_count ;
539+ };
540+
541+ static bool merge_bis_and_subgroup_data_cb (struct bt_data * data , void * user_data )
542+ {
543+ struct bt_audio_codec_cfg * codec_cfg = user_data ;
544+ int err ;
545+
546+ err = bt_audio_codec_cfg_set_val (codec_cfg , data -> type , data -> data , data -> data_len );
547+ if (err < 0 ) {
548+ LOG_DBG ("Failed to set type %u with len %u in codec_cfg: %d" , data -> type ,
549+ data -> data_len , err );
550+
551+ return false;
552+ }
553+
554+ return true;
555+ }
556+
525557static bool base_subgroup_bis_index_cb (const struct bt_bap_base_subgroup_bis * bis , void * user_data )
526558{
527- uint32_t * bis_indexes = user_data ;
559+ struct bt_bap_broadcast_sink_subgroup * sink_subgroup ;
560+ struct store_base_info_data * data = user_data ;
561+ struct bt_bap_broadcast_sink_bis * sink_bis ;
562+
563+ if (data -> bis_count == ARRAY_SIZE (data -> bis )) {
564+ /* We've parsed as many subgroups as we support */
565+ LOG_DBG ("Could only store %u BIS" , data -> bis_count );
566+ return false;
567+ }
568+
569+ sink_bis = & data -> bis [data -> bis_count ];
570+ sink_subgroup = & data -> subgroups [data -> subgroup_count ];
571+
572+ sink_bis -> index = bis -> index ;
573+ sink_subgroup -> bis_indexes |= BIT (bis -> index );
574+
575+ #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
576+ int err ;
577+
578+ memcpy (& sink_bis -> codec_cfg , data -> subgroup_codec_cfg , sizeof (sink_bis -> codec_cfg ));
579+
580+ /* Merge subgroup codec configuration with the BIS configuration
581+ * As per the BAP spec, if a value exist at level 2 (subgroup) and 3 (BIS), then it is
582+ * the value at level 3 that shall be used
583+ */
584+ if (sink_bis -> codec_cfg .id == BT_HCI_CODING_FORMAT_LC3 ) {
585+ memcpy (& sink_bis -> codec_cfg , data -> subgroup_codec_cfg , sizeof (sink_bis -> codec_cfg ));
586+
587+ err = bt_audio_data_parse (bis -> data , bis -> data_len , merge_bis_and_subgroup_data_cb ,
588+ & sink_bis -> codec_cfg );
589+ if (err != 0 ) {
590+ LOG_DBG ("Could not merge BIS and subgroup config in codec_cfg: %d" , err );
591+
592+ return false;
593+ }
594+ } else {
595+ /* If it is not LC3, then we don't know how to merge the subgroup and BIS codecs,
596+ * so we just append them
597+ */
598+ if (sink_bis -> codec_cfg .data_len + bis -> data_len >
599+ sizeof (sink_bis -> codec_cfg .data )) {
600+ LOG_DBG ("Could not store BIS and subgroup config in codec_cfg (%u > %u)" ,
601+ sink_bis -> codec_cfg .data_len + bis -> data_len ,
602+ sizeof (sink_bis -> codec_cfg .data ));
528603
529- * bis_indexes |= BIT (bis -> index );
604+ return false;
605+ }
606+
607+ memcpy (& sink_bis -> codec_cfg .data [sink_bis -> codec_cfg .data_len ], bis -> data ,
608+ bis -> data_len );
609+ }
610+ #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
611+
612+ data -> bis_count ++ ;
530613
531614 return true;
532615}
533616
534617static bool base_subgroup_cb (const struct bt_bap_base_subgroup * subgroup , void * user_data )
535618{
536- struct bt_bap_broadcast_sink * sink = user_data ;
537- struct bt_bap_broadcast_sink_subgroup * sink_subgroup =
538- & sink -> subgroups [sink -> subgroup_count ];
619+ struct bt_bap_broadcast_sink_subgroup * sink_subgroup ;
539620 struct codec_cap_lookup_id_data lookup_data = {0 };
621+ struct store_base_info_data * data = user_data ;
622+ struct bt_audio_codec_cfg codec_cfg ;
540623 int ret ;
541624
542- if (sink -> subgroup_count == ARRAY_SIZE (sink -> subgroups )) {
625+ if (data -> subgroup_count == ARRAY_SIZE (data -> subgroups )) {
543626 /* We've parsed as many subgroups as we support */
544- LOG_DBG ("Could only store %u subgroups" , sink -> subgroup_count );
627+ LOG_DBG ("Could only store %u subgroups" , data -> subgroup_count );
545628 return false;
546629 }
547630
548- ret = bt_bap_base_subgroup_codec_to_codec_cfg (subgroup , & sink_subgroup -> codec_cfg );
549- if (ret < 0 ) {
550- LOG_DBG ("Could not store codec_cfg: %d" , ret );
551- return false;
552- }
631+ sink_subgroup = & data -> subgroups [data -> subgroup_count ];
553632
554- ret = bt_bap_base_subgroup_foreach_bis (subgroup , base_subgroup_bis_index_cb ,
555- & sink_subgroup -> bis_indexes );
633+ ret = bt_bap_base_subgroup_codec_to_codec_cfg (subgroup , & codec_cfg );
556634 if (ret < 0 ) {
557- LOG_DBG ("Could not parse BISes : %d" , ret );
635+ LOG_DBG ("Could not store codec_cfg : %d" , ret );
558636 return false;
559637 }
560638
561639 /* Lookup and assign path_id based on capabilities */
562- lookup_data .id = sink_subgroup -> codec_cfg .id ;
640+ lookup_data .id = codec_cfg .id ;
563641
564642 bt_pacs_cap_foreach (BT_AUDIO_DIR_SINK , codec_lookup_id , & lookup_data );
565643 if (lookup_data .codec_cap == NULL ) {
566644 LOG_DBG ("Codec with id %u is not supported by our capabilities" , lookup_data .id );
567645 } else {
646+ codec_cfg .path_id = lookup_data .codec_cap -> path_id ;
647+ codec_cfg .ctlr_transcode = lookup_data .codec_cap -> ctlr_transcode ;
648+
649+ data -> subgroup_codec_cfg = & codec_cfg ;
650+
651+ ret = bt_bap_base_subgroup_foreach_bis (subgroup , base_subgroup_bis_index_cb , data );
652+ if (ret < 0 ) {
653+ LOG_DBG ("Could not parse BISes: %d" , ret );
654+ return false;
655+ }
656+
568657 /* Add BIS to bitfield of valid BIS indexes we support */
569- sink -> valid_indexes_bitfield |= sink_subgroup -> bis_indexes ;
658+ data -> valid_indexes_bitfield |= sink_subgroup -> bis_indexes ;
659+ data -> subgroup_count ++ ;
570660 }
571661
572- sink -> subgroup_count ++ ;
573-
574662 return true;
575663}
576664
577665static int store_base_info (struct bt_bap_broadcast_sink * sink , const struct bt_bap_base * base )
578666{
667+ /* data is static due to its size, which easily can exceed the stack size */
668+ static struct store_base_info_data data ;
669+ uint32_t pres_delay ;
579670 int ret ;
580671
581- sink -> valid_indexes_bitfield = 0U ;
582- sink -> subgroup_count = 0U ;
583-
584672 ret = bt_bap_base_get_pres_delay (base );
585673 if (ret < 0 ) {
586674 LOG_DBG ("Could not get presentation delay: %d" , ret );
587675 return ret ;
588676 }
589677
590- sink -> codec_qos . pd = (uint32_t )ret ;
678+ pres_delay = (uint32_t )ret ;
591679
592- ret = bt_bap_base_foreach_subgroup (base , base_subgroup_cb , sink );
680+ memset (& data , 0 , sizeof (data ));
681+
682+ ret = bt_bap_base_foreach_subgroup (base , base_subgroup_cb , & data );
593683 if (ret != 0 ) {
594684 LOG_DBG ("Failed to parse all subgroups: %d" , ret );
595685 return ret ;
596686 }
597687
688+ /* Ensure that we have not synced while parsing the BASE */
689+ if (sink -> big == NULL ) {
690+ sink -> codec_qos .pd = pres_delay ;
691+ memcpy (sink -> bis , data .bis , sizeof (sink -> bis ));
692+ memcpy (sink -> subgroups , data .subgroups , sizeof (sink -> subgroups ));
693+ sink -> subgroup_count = data .subgroup_count ;
694+ sink -> valid_indexes_bitfield = data .valid_indexes_bitfield ;
695+ }
696+
598697 return 0 ;
599698}
600699
@@ -940,14 +1039,18 @@ static void broadcast_sink_cleanup(struct bt_bap_broadcast_sink *sink)
9401039
9411040 (void )memset (sink , 0 , sizeof (* sink )); /* also clears flags */
9421041}
1042+
9431043static struct bt_audio_codec_cfg * codec_cfg_from_base_by_index (struct bt_bap_broadcast_sink * sink ,
9441044 uint8_t index )
9451045{
946- for (size_t i = 0U ; i < sink -> subgroup_count ; i ++ ) {
947- struct bt_bap_broadcast_sink_subgroup * subgroup = & sink -> subgroups [i ];
1046+ for (size_t i = 0U ; i < ARRAY_SIZE ( sink -> bis ) ; i ++ ) {
1047+ struct bt_bap_broadcast_sink_bis * bis = & sink -> bis [i ];
9481048
949- if ((subgroup -> bis_indexes & BIT (index )) != 0 ) {
950- return & subgroup -> codec_cfg ;
1049+ if (bis -> index == index ) {
1050+ return & bis -> codec_cfg ;
1051+ } else if (bis -> index == 0 ) {
1052+ /* index 0 is invalid, so we can use that as a terminator in the array */
1053+ break ;
9511054 }
9521055 }
9531056
@@ -1015,7 +1118,8 @@ int bt_bap_broadcast_sink_sync(struct bt_bap_broadcast_sink *sink, uint32_t inde
10151118 struct bt_bap_stream * streams [], const uint8_t broadcast_code [16 ])
10161119{
10171120 struct bt_iso_big_sync_param param ;
1018- struct bt_audio_codec_cfg * codec_cfgs [CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT ] = {NULL };
1121+ struct bt_audio_codec_cfg * codec_cfgs [CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT ] = {NULL };
1122+ struct bt_iso_chan * bis_channels [CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT ];
10191123 uint8_t stream_count ;
10201124 int err ;
10211125
@@ -1110,12 +1214,14 @@ int bt_bap_broadcast_sink_sync(struct bt_bap_broadcast_sink *sink, uint32_t inde
11101214 return err ;
11111215 }
11121216
1113- sink -> bis [i ] = bt_bap_stream_iso_chan_get (stream );
1217+ sink -> bis [i ]. chan = bt_bap_stream_iso_chan_get (stream );
11141218 sys_slist_append (& sink -> streams , & stream -> _node );
11151219 sink -> stream_count ++ ;
1220+
1221+ bis_channels [i ] = sink -> bis [i ].chan ;
11161222 }
11171223
1118- param .bis_channels = sink -> bis ;
1224+ param .bis_channels = bis_channels ;
11191225 param .num_bis = sink -> stream_count ;
11201226 param .bis_bitfield = indexes_bitfield ;
11211227 param .mse = 0 ; /* Let controller decide */
0 commit comments