@@ -318,6 +318,10 @@ static void unicast_client_ep_iso_connected(struct bt_bap_ep *ep)
318318 const struct bt_bap_stream_ops * stream_ops ;
319319 struct bt_bap_stream * stream ;
320320
321+ if (ep -> unicast_group != NULL ) {
322+ ep -> unicast_group -> has_been_connected = true;
323+ }
324+
321325 if (ep -> status .state != BT_BAP_EP_STATE_ENABLING ) {
322326 LOG_DBG ("endpoint not in enabling state: %s" ,
323327 bt_bap_ep_state_str (ep -> status .state ));
@@ -2171,25 +2175,30 @@ static void bt_audio_codec_qos_to_cig_param(struct bt_iso_cig_param *cig_param,
21712175 }
21722176}
21732177
2174- static int bt_audio_cig_create ( struct bt_bap_unicast_group * group )
2178+ static uint8_t unicast_group_get_cis_count ( const struct bt_bap_unicast_group * unicast_group )
21752179{
2176- struct bt_iso_cig_param param = {0 };
2177- uint8_t cis_count ;
2178- int err ;
2180+ uint8_t cis_count = 0U ;
21792181
2180- LOG_DBG ("group %p" , group );
2181-
2182- cis_count = 0U ;
2183- for (size_t i = 0U ; i < ARRAY_SIZE (group -> cis ); i ++ ) {
2184- if (group -> cis [i ] == NULL ) {
2182+ for (size_t i = 0U ; i < ARRAY_SIZE (unicast_group -> cis ); i ++ ) {
2183+ if (unicast_group -> cis [i ] == NULL ) {
21852184 /* A NULL CIS acts as a NULL terminator */
21862185 break ;
21872186 }
21882187
21892188 cis_count ++ ;
21902189 }
21912190
2192- param .num_cis = cis_count ;
2191+ return cis_count ;
2192+ }
2193+
2194+ static int bt_audio_cig_create (struct bt_bap_unicast_group * group )
2195+ {
2196+ struct bt_iso_cig_param param = {0 };
2197+ int err ;
2198+
2199+ LOG_DBG ("group %p" , group );
2200+
2201+ param .num_cis = unicast_group_get_cis_count (group );
21932202 param .cis_channels = group -> cis ;
21942203 bt_audio_codec_qos_to_cig_param (& param , group );
21952204
@@ -2352,6 +2361,27 @@ static void unicast_client_codec_qos_to_iso_qos(struct bt_bap_iso *iso,
23522361 }
23532362}
23542363
2364+ static void unicast_group_set_iso_stream_param (struct bt_bap_unicast_group * group ,
2365+ struct bt_bap_iso * iso ,
2366+ struct bt_audio_codec_qos * qos ,
2367+ enum bt_audio_dir dir )
2368+ {
2369+ /* Store the stream Codec QoS in the bap_iso */
2370+ unicast_client_codec_qos_to_iso_qos (iso , qos , dir );
2371+
2372+ /* Store the group Codec QoS in the group - This assume thats the parameters have been
2373+ * verified first
2374+ */
2375+ group -> cig_param .framing = qos -> framing ;
2376+ if (dir == BT_AUDIO_DIR_SOURCE ) {
2377+ group -> cig_param .p_to_c_interval = qos -> interval ;
2378+ group -> cig_param .p_to_c_latency = qos -> latency ;
2379+ } else {
2380+ group -> cig_param .c_to_p_interval = qos -> interval ;
2381+ group -> cig_param .c_to_p_latency = qos -> latency ;
2382+ }
2383+ }
2384+
23552385static void unicast_group_add_stream (struct bt_bap_unicast_group * group ,
23562386 struct bt_bap_unicast_group_stream_param * param ,
23572387 struct bt_bap_iso * iso , enum bt_audio_dir dir )
@@ -2372,20 +2402,7 @@ static void unicast_group_add_stream(struct bt_bap_unicast_group *group,
23722402 bt_bap_iso_bind_ep (iso , stream -> ep );
23732403 }
23742404
2375- /* Store the stream Codec QoS in the bap_iso */
2376- unicast_client_codec_qos_to_iso_qos (iso , qos , dir );
2377-
2378- /* Store the group Codec QoS in the group - This assume thats the parameters have been
2379- * verified first
2380- */
2381- group -> cig_param .framing = qos -> framing ;
2382- if (dir == BT_AUDIO_DIR_SOURCE ) {
2383- group -> cig_param .p_to_c_interval = qos -> interval ;
2384- group -> cig_param .p_to_c_latency = qos -> latency ;
2385- } else {
2386- group -> cig_param .c_to_p_interval = qos -> interval ;
2387- group -> cig_param .c_to_p_latency = qos -> latency ;
2388- }
2405+ unicast_group_set_iso_stream_param (group , iso , qos , dir );
23892406
23902407 sys_slist_append (& group -> streams , & stream -> _node );
23912408}
@@ -2574,7 +2591,8 @@ static int stream_pair_param_check(const struct bt_bap_unicast_group_stream_pair
25742591}
25752592
25762593/** Validates that the stream parameter does not contain invalid values */
2577- static bool valid_unicast_group_stream_param (const struct bt_bap_unicast_group_stream_param * param ,
2594+ static bool valid_unicast_group_stream_param (const struct bt_bap_unicast_group * unicast_group ,
2595+ const struct bt_bap_unicast_group_stream_param * param ,
25782596 struct bt_bap_unicast_group_cig_param * cig_param ,
25792597 enum bt_audio_dir dir )
25802598{
@@ -2591,7 +2609,13 @@ static bool valid_unicast_group_stream_param(const struct bt_bap_unicast_group_s
25912609 }
25922610
25932611 if (param -> stream != NULL && param -> stream -> group != NULL ) {
2594- LOG_DBG ("stream %p already part of group %p" , param -> stream , param -> stream -> group );
2612+ if (unicast_group != NULL && param -> stream -> group != unicast_group ) {
2613+ LOG_DBG ("stream %p not part of group %p (%p)" , param -> stream , unicast_group ,
2614+ param -> stream -> group );
2615+ } else {
2616+ LOG_DBG ("stream %p already part of group %p" , param -> stream ,
2617+ param -> stream -> group );
2618+ }
25952619 return - EALREADY ;
25962620 }
25972621
@@ -2659,23 +2683,23 @@ valid_group_stream_pair_param(const struct bt_bap_unicast_group *unicast_group,
26592683 }
26602684
26612685 if (pair_param -> rx_param != NULL ) {
2662- if (!valid_unicast_group_stream_param (pair_param -> rx_param , & cig_param ,
2663- BT_AUDIO_DIR_SOURCE )) {
2686+ if (!valid_unicast_group_stream_param (unicast_group , pair_param -> rx_param ,
2687+ & cig_param , BT_AUDIO_DIR_SOURCE )) {
26642688 return false;
26652689 }
26662690 }
26672691
26682692 if (pair_param -> tx_param != NULL ) {
2669- if (!valid_unicast_group_stream_param (pair_param -> tx_param , & cig_param ,
2670- BT_AUDIO_DIR_SINK )) {
2693+ if (!valid_unicast_group_stream_param (unicast_group , pair_param -> tx_param ,
2694+ & cig_param , BT_AUDIO_DIR_SINK )) {
26712695 return false;
26722696 }
26732697 }
26742698
26752699 return true;
26762700}
26772701
2678- static bool valid_unicast_group_param (const struct bt_bap_unicast_group * unicast_group ,
2702+ static bool valid_unicast_group_param (struct bt_bap_unicast_group * unicast_group ,
26792703 const struct bt_bap_unicast_group_param * param )
26802704{
26812705 CHECKIF (param == NULL ) {
@@ -2689,6 +2713,17 @@ static bool valid_unicast_group_param(const struct bt_bap_unicast_group *unicast
26892713 return false;
26902714 }
26912715
2716+ if (unicast_group != NULL ) {
2717+ const size_t group_cis_cnt = unicast_group_get_cis_count (unicast_group );
2718+
2719+ if (param -> params_count != group_cis_cnt ) {
2720+ LOG_DBG ("Mismatch between group CIS count (%zu) and params_count (%zu)" ,
2721+ group_cis_cnt , param -> params_count );
2722+
2723+ return false;
2724+ }
2725+ }
2726+
26922727 for (size_t i = 0U ; i < param -> params_count ; i ++ ) {
26932728 if (!valid_group_stream_pair_param (unicast_group , & param -> params [i ])) {
26942729 return false;
@@ -2718,7 +2753,7 @@ int bt_bap_unicast_group_create(struct bt_bap_unicast_group_param *param,
27182753 return - ENOMEM ;
27192754 }
27202755
2721- if (!valid_unicast_group_param (unicast_group , param )) {
2756+ if (!valid_unicast_group_param (NULL , param )) {
27222757 unicast_group_free (unicast_group );
27232758
27242759 return - EINVAL ;
@@ -2758,6 +2793,91 @@ int bt_bap_unicast_group_create(struct bt_bap_unicast_group_param *param,
27582793 return 0 ;
27592794}
27602795
2796+ int bt_bap_unicast_group_reconfig (struct bt_bap_unicast_group * unicast_group ,
2797+ const struct bt_bap_unicast_group_param * param )
2798+ {
2799+ struct bt_iso_chan_io_qos rx_io_qos_backup [UNICAST_GROUP_STREAM_CNT ];
2800+ struct bt_iso_chan_io_qos tx_io_qos_backup [UNICAST_GROUP_STREAM_CNT ];
2801+ struct bt_bap_unicast_group_cig_param cig_param_backup ;
2802+ struct bt_bap_stream * tmp_stream ;
2803+ size_t idx ;
2804+ int err ;
2805+
2806+ IF_ENABLED (CONFIG_BT_ISO_TEST_PARAMS ,
2807+ (uint8_t num_subevents_backup [UNICAST_GROUP_STREAM_CNT ]));
2808+
2809+ CHECKIF (unicast_group == NULL ) {
2810+ LOG_DBG ("unicast_group is NULL" );
2811+ return - EINVAL ;
2812+ }
2813+
2814+ if (unicast_group -> has_been_connected ) {
2815+ LOG_DBG ("Cannot modify a unicast_group where a CIS has been connected" );
2816+ return - EINVAL ;
2817+ }
2818+
2819+ if (!valid_unicast_group_param (unicast_group , param )) {
2820+ return - EINVAL ;
2821+ }
2822+
2823+ /* Make backups of the values in case that the reconfigure request is rejected by e.g. the
2824+ * controller
2825+ */
2826+ idx = 0U ;
2827+ SYS_SLIST_FOR_EACH_CONTAINER (& unicast_group -> streams , tmp_stream , _node ) {
2828+ memcpy (& rx_io_qos_backup [idx ], tmp_stream -> bap_iso -> chan .qos -> rx ,
2829+ sizeof (rx_io_qos_backup [idx ]));
2830+ memcpy (& tx_io_qos_backup [idx ], tmp_stream -> bap_iso -> chan .qos -> tx ,
2831+ sizeof (tx_io_qos_backup [idx ]));
2832+ IF_ENABLED (
2833+ CONFIG_BT_ISO_TEST_PARAMS ,
2834+ (num_subevents_backup [idx ] = tmp_stream -> bap_iso -> chan .qos -> num_subevents ));
2835+ idx ++ ;
2836+ }
2837+ memcpy (& cig_param_backup , & unicast_group -> cig_param , sizeof (cig_param_backup ));
2838+
2839+ /* Update the stream and group parameters */
2840+ for (size_t i = 0U ; i < param -> params_count ; i ++ ) {
2841+ struct bt_bap_unicast_group_stream_pair_param * stream_param = & param -> params [i ];
2842+ struct bt_bap_unicast_group_stream_param * rx_param = stream_param -> rx_param ;
2843+ struct bt_bap_unicast_group_stream_param * tx_param = stream_param -> tx_param ;
2844+
2845+ if (rx_param != NULL ) {
2846+ unicast_group_set_iso_stream_param (unicast_group , rx_param -> stream -> bap_iso ,
2847+ rx_param -> qos , BT_AUDIO_DIR_SOURCE );
2848+ }
2849+
2850+ if (tx_param != NULL ) {
2851+ unicast_group_set_iso_stream_param (unicast_group , tx_param -> stream -> bap_iso ,
2852+ tx_param -> qos , BT_AUDIO_DIR_SOURCE );
2853+ }
2854+ }
2855+
2856+ /* Reconfigure the CIG based on the above new values */
2857+ err = bt_audio_cig_reconfigure (unicast_group );
2858+ if (err != 0 ) {
2859+ LOG_DBG ("bt_audio_cig_reconfigure failed: %d" , err );
2860+
2861+ /* Revert any changes above */
2862+ memcpy (& unicast_group -> cig_param , & cig_param_backup , sizeof (cig_param_backup ));
2863+ idx = 0U ;
2864+ SYS_SLIST_FOR_EACH_CONTAINER (& unicast_group -> streams , tmp_stream , _node ) {
2865+ memcpy (tmp_stream -> bap_iso -> chan .qos -> rx , & rx_io_qos_backup [idx ],
2866+ sizeof (rx_io_qos_backup [idx ]));
2867+ memcpy (tmp_stream -> bap_iso -> chan .qos -> tx , & tx_io_qos_backup [idx ],
2868+ sizeof (tx_io_qos_backup [idx ]));
2869+ IF_ENABLED (CONFIG_BT_ISO_TEST_PARAMS ,
2870+ (tmp_stream -> bap_iso -> chan .qos -> num_subevents =
2871+ num_subevents_backup [idx ]));
2872+ idx ++ ;
2873+ }
2874+
2875+ return err ;
2876+ }
2877+
2878+ return 0 ;
2879+ }
2880+
27612881int bt_bap_unicast_group_add_streams (struct bt_bap_unicast_group * unicast_group ,
27622882 struct bt_bap_unicast_group_stream_pair_param params [],
27632883 size_t num_param )
@@ -2774,6 +2894,11 @@ int bt_bap_unicast_group_add_streams(struct bt_bap_unicast_group *unicast_group,
27742894 return - EINVAL ;
27752895 }
27762896
2897+ if (unicast_group -> has_been_connected ) {
2898+ LOG_DBG ("Cannot modify a unicast_group where a CIS has been connected" );
2899+ return - EINVAL ;
2900+ }
2901+
27772902 CHECKIF (params == NULL )
27782903 {
27792904 LOG_DBG ("params is NULL" );
0 commit comments