@@ -671,10 +671,185 @@ int bt_cap_commander_broadcast_reception_stop(
671671 return 0 ;
672672}
673673
674+ static void cap_commander_broadcast_assistant_set_broadcast_code_cb (struct bt_conn * conn , int err )
675+ {
676+ struct bt_cap_common_proc * active_proc = bt_cap_common_get_active_proc ();
677+
678+ LOG_DBG ("conn %p" , (void * )conn );
679+
680+ if (!bt_cap_common_conn_in_active_proc (conn )) {
681+ /* State change happened outside of a procedure; ignore */
682+ return ;
683+ }
684+
685+ if (err != 0 ) {
686+ LOG_DBG ("Failed to distribute broadcast code: %d" , err );
687+
688+ bt_cap_common_abort_proc (conn , err );
689+ } else {
690+ active_proc -> proc_done_cnt ++ ;
691+
692+ LOG_DBG ("Conn %p broadcast code set (%zu/%zu done)" , (void * )conn ,
693+ active_proc -> proc_done_cnt , active_proc -> proc_cnt );
694+ }
695+
696+ if (bt_cap_common_proc_is_aborted ()) {
697+ if (bt_cap_common_proc_all_handled ()) {
698+ cap_commander_proc_complete ();
699+ }
700+
701+ return ;
702+ }
703+
704+ if (!bt_cap_common_proc_is_done ()) {
705+ struct bt_cap_commander_proc_param * proc_param ;
706+
707+ proc_param = & active_proc -> proc_param .commander [active_proc -> proc_done_cnt ];
708+ conn = proc_param -> conn ;
709+
710+ active_proc -> proc_initiated_cnt ++ ;
711+ err = bt_bap_broadcast_assistant_set_broadcast_code (
712+ conn , proc_param -> distribute_broadcast_code .src_id ,
713+ proc_param -> distribute_broadcast_code .broadcast_code );
714+ if (err != 0 ) {
715+ LOG_DBG ("Failed to perform set broadcast code for conn %p: %d" ,
716+ (void * )conn , err );
717+ bt_cap_common_abort_proc (conn , err );
718+ cap_commander_proc_complete ();
719+ }
720+ } else {
721+ cap_commander_proc_complete ();
722+ }
723+ }
724+
725+ static bool valid_distribute_broadcast_code_param (
726+ const struct bt_cap_commander_distribute_broadcast_code_param * param )
727+ {
728+ CHECKIF (param == NULL ) {
729+ LOG_DBG ("param is NULL" );
730+ return false;
731+ }
732+
733+ CHECKIF (param -> count == 0 ) {
734+ LOG_DBG ("Invalid param->count: %zu" , param -> count );
735+ return false;
736+ }
737+
738+ CHECKIF (param -> count > CONFIG_BT_MAX_CONN ) {
739+ LOG_DBG ("param->count (%zu) is larger than CONFIG_BT_MAX_CONN (%d)" , param -> count ,
740+ CONFIG_BT_MAX_CONN );
741+ return false;
742+ }
743+
744+ CHECKIF (param -> param == NULL ) {
745+ LOG_DBG ("param->param is NULL" );
746+ return false;
747+ }
748+
749+ for (size_t i = 0 ; i < param -> count ; i ++ ) {
750+ const union bt_cap_set_member * member = & param -> param [i ].member ;
751+ const struct bt_conn * member_conn =
752+ bt_cap_common_get_member_conn (param -> type , member );
753+
754+ if (member == NULL ) {
755+ LOG_DBG ("param->param[%zu].member is NULL" , i );
756+ return false;
757+ }
758+
759+ if (member_conn == NULL ) {
760+ LOG_DBG ("Invalid param->param[%zu].member" , i );
761+ return false;
762+ }
763+
764+ for (size_t j = 0U ; j < i ; j ++ ) {
765+ const union bt_cap_set_member * other = & param -> param [j ].member ;
766+ const struct bt_conn * other_conn =
767+ bt_cap_common_get_member_conn (param -> type , other );
768+
769+ if (other_conn == member_conn ) {
770+ LOG_DBG ("param->param[%zu].member.member (%p) is duplicated by "
771+ "param->member[%zu].member.member (%p)" ,
772+ j , (void * )other_conn , i , (void * )member_conn );
773+ return false;
774+ }
775+ }
776+ }
777+
778+ return true;
779+ }
780+
674781int bt_cap_commander_distribute_broadcast_code (
675782 const struct bt_cap_commander_distribute_broadcast_code_param * param )
676783{
677- return - ENOSYS ;
784+ struct bt_cap_commander_proc_param * proc_param ;
785+ struct bt_cap_common_proc * active_proc ;
786+ struct bt_conn * conn ;
787+ int err ;
788+
789+ if (bt_cap_common_proc_is_active ()) {
790+ LOG_DBG ("A CAP procedure is already in progress" );
791+
792+ return - EBUSY ;
793+ }
794+
795+ if (!valid_distribute_broadcast_code_param (param )) {
796+ return - EINVAL ;
797+ }
798+
799+ bt_cap_common_start_proc (BT_CAP_COMMON_PROC_TYPE_DISTRIBUTE_BROADCAST_CODE , param -> count );
800+
801+ broadcast_assistant_cb .broadcast_code =
802+ cap_commander_broadcast_assistant_set_broadcast_code_cb ;
803+ if (!broadcast_assistant_cb_registered &&
804+ cap_commander_register_broadcast_assistant_cb () != 0 ) {
805+ LOG_DBG ("Failed to register broadcast assistant callbacks" );
806+
807+ return - ENOEXEC ;
808+ }
809+
810+ active_proc = bt_cap_common_get_active_proc ();
811+
812+ for (size_t i = 0U ; i < param -> count ; i ++ ) {
813+ const struct bt_cap_commander_distribute_broadcast_code_member_param * member_param =
814+ & param -> param [i ];
815+ struct bt_cap_commander_proc_param * stored_param ;
816+ struct bt_conn * member_conn =
817+ bt_cap_common_get_member_conn (param -> type , & member_param -> member );
818+
819+ if (member_conn == NULL ) {
820+ LOG_DBG ("Invalid param->member[%zu]" , i );
821+
822+ return - EINVAL ;
823+ }
824+
825+ /* Store the necessary parameters as we cannot assume that the
826+ * supplied parameters are kept valid
827+ */
828+ stored_param = & active_proc -> proc_param .commander [i ];
829+ stored_param -> conn = member_conn ;
830+ stored_param -> distribute_broadcast_code .src_id = member_param -> src_id ;
831+ memcpy (stored_param -> distribute_broadcast_code .broadcast_code ,
832+ param -> broadcast_code , BT_ISO_BROADCAST_CODE_SIZE );
833+ }
834+
835+ active_proc -> proc_initiated_cnt ++ ;
836+
837+ proc_param = & active_proc -> proc_param .commander [0 ];
838+
839+ conn = proc_param -> conn ;
840+
841+ err = bt_bap_broadcast_assistant_set_broadcast_code (
842+ conn , proc_param -> distribute_broadcast_code .src_id ,
843+ proc_param -> distribute_broadcast_code .broadcast_code );
844+
845+ if (err != 0 ) {
846+ LOG_DBG ("Failed to start distribute broadcast code for conn %p: %d" , (void * )conn ,
847+ err );
848+
849+ return - ENOEXEC ;
850+ }
851+
852+ return 0 ;
678853}
679854
680855#endif /* CONFIG_BT_BAP_BROADCAST_ASSISTANT */
@@ -740,6 +915,11 @@ static void cap_commander_proc_complete(void)
740915 cap_cb -> broadcast_reception_stop (failed_conn , err );
741916 }
742917 break ;
918+ case BT_CAP_COMMON_PROC_TYPE_DISTRIBUTE_BROADCAST_CODE :
919+ if (cap_cb -> distribute_broadcast_code != NULL ) {
920+ cap_cb -> distribute_broadcast_code (failed_conn , err );
921+ }
922+ break ;
743923#endif /* CONFIG_BT_BAP_BROADCAST_ASSISTANT */
744924 case BT_CAP_COMMON_PROC_TYPE_NONE :
745925 default :
0 commit comments