@@ -671,10 +671,185 @@ int bt_cap_commander_broadcast_reception_stop(
671
671
return 0 ;
672
672
}
673
673
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
+
674
781
int bt_cap_commander_distribute_broadcast_code (
675
782
const struct bt_cap_commander_distribute_broadcast_code_param * param )
676
783
{
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 ;
678
853
}
679
854
680
855
#endif /* CONFIG_BT_BAP_BROADCAST_ASSISTANT */
@@ -740,6 +915,11 @@ static void cap_commander_proc_complete(void)
740
915
cap_cb -> broadcast_reception_stop (failed_conn , err );
741
916
}
742
917
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 ;
743
923
#endif /* CONFIG_BT_BAP_BROADCAST_ASSISTANT */
744
924
case BT_CAP_COMMON_PROC_TYPE_NONE :
745
925
default :
0 commit comments