@@ -351,6 +351,44 @@ static int a2dp_start_ind(struct bt_avdtp *session, struct bt_avdtp_sep *sep, ui
351351 return a2dp_ctrl_ind (session , sep , errcode , req_cb , done_cb , false);
352352}
353353
354+ static int a2dp_suspend_ind (struct bt_avdtp * session , struct bt_avdtp_sep * sep , uint8_t * errcode )
355+ {
356+ struct bt_a2dp_ep * ep = CONTAINER_OF (sep , struct bt_a2dp_ep , sep );
357+ bt_a2dp_ctrl_req_cb req_cb ;
358+ bt_a2dp_ctrl_done_cb done_cb ;
359+
360+ __ASSERT (sep , "Invalid sep" );
361+ req_cb = a2dp_cb != NULL ? a2dp_cb -> suspend_req : NULL ;
362+ done_cb =
363+ (ep -> stream != NULL && ep -> stream -> ops != NULL ) ? ep -> stream -> ops -> suspended : NULL ;
364+ return a2dp_ctrl_ind (session , sep , errcode , req_cb , done_cb , false);
365+ }
366+
367+ static int a2dp_close_ind (struct bt_avdtp * session , struct bt_avdtp_sep * sep , uint8_t * errcode )
368+ {
369+ struct bt_a2dp_ep * ep = CONTAINER_OF (sep , struct bt_a2dp_ep , sep );
370+ bt_a2dp_ctrl_req_cb req_cb ;
371+ bt_a2dp_ctrl_done_cb done_cb ;
372+
373+ __ASSERT (sep , "Invalid sep" );
374+ req_cb = a2dp_cb != NULL ? a2dp_cb -> release_req : NULL ;
375+ done_cb =
376+ (ep -> stream != NULL && ep -> stream -> ops != NULL ) ? ep -> stream -> ops -> released : NULL ;
377+ return a2dp_ctrl_ind (session , sep , errcode , req_cb , done_cb , true);
378+ }
379+
380+ static int a2dp_abort_ind (struct bt_avdtp * session , struct bt_avdtp_sep * sep , uint8_t * errcode )
381+ {
382+ struct bt_a2dp_ep * ep = CONTAINER_OF (sep , struct bt_a2dp_ep , sep );
383+ bt_a2dp_ctrl_req_cb req_cb ;
384+ bt_a2dp_ctrl_done_cb done_cb ;
385+
386+ __ASSERT (sep , "Invalid sep" );
387+ req_cb = a2dp_cb != NULL ? a2dp_cb -> abort_req : NULL ;
388+ done_cb = (ep -> stream != NULL && ep -> stream -> ops != NULL ) ? ep -> stream -> ops -> aborted : NULL ;
389+ return a2dp_ctrl_ind (session , sep , errcode , req_cb , done_cb , true);
390+ }
391+
354392static int bt_a2dp_set_config_cb (struct bt_avdtp_req * req )
355393{
356394 struct bt_a2dp * a2dp = SET_CONF_PARAM (SET_CONF_REQ (req ));
@@ -656,6 +694,36 @@ static int bt_a2dp_start_cb(struct bt_avdtp_req *req)
656694 return bt_a2dp_ctrl_cb (req , rsp_cb , done_cb , false);
657695}
658696
697+ static int bt_a2dp_suspend_cb (struct bt_avdtp_req * req )
698+ {
699+ struct bt_a2dp_ep * ep = CONTAINER_OF (CTRL_REQ (req )-> sep , struct bt_a2dp_ep , sep );
700+ bt_a2dp_rsp_cb rsp_cb = a2dp_cb != NULL ? a2dp_cb -> suspend_rsp : NULL ;
701+ bt_a2dp_done_cb done_cb =
702+ (ep -> stream != NULL && ep -> stream -> ops != NULL ) ? ep -> stream -> ops -> suspended : NULL ;
703+
704+ return bt_a2dp_ctrl_cb (req , rsp_cb , done_cb , false);
705+ }
706+
707+ static int bt_a2dp_close_cb (struct bt_avdtp_req * req )
708+ {
709+ struct bt_a2dp_ep * ep = CONTAINER_OF (CTRL_REQ (req )-> sep , struct bt_a2dp_ep , sep );
710+ bt_a2dp_rsp_cb rsp_cb = a2dp_cb != NULL ? a2dp_cb -> release_rsp : NULL ;
711+ bt_a2dp_done_cb done_cb =
712+ (ep -> stream != NULL && ep -> stream -> ops != NULL ) ? ep -> stream -> ops -> released : NULL ;
713+
714+ return bt_a2dp_ctrl_cb (req , rsp_cb , done_cb , true);
715+ }
716+
717+ static int bt_a2dp_abort_cb (struct bt_avdtp_req * req )
718+ {
719+ struct bt_a2dp_ep * ep = CONTAINER_OF (CTRL_REQ (req )-> sep , struct bt_a2dp_ep , sep );
720+ bt_a2dp_rsp_cb rsp_cb = a2dp_cb != NULL ? a2dp_cb -> abort_rsp : NULL ;
721+ bt_a2dp_done_cb done_cb =
722+ (ep -> stream != NULL && ep -> stream -> ops != NULL ) ? ep -> stream -> ops -> aborted : NULL ;
723+
724+ return bt_a2dp_ctrl_cb (req , rsp_cb , done_cb , true);
725+ }
726+
659727static int bt_a2dp_stream_ctrl_pre (struct bt_a2dp_stream * stream , bt_avdtp_func_t cb )
660728{
661729 struct bt_a2dp * a2dp ;
@@ -685,6 +753,18 @@ int bt_a2dp_stream_establish(struct bt_a2dp_stream *stream)
685753 return bt_avdtp_open (& a2dp -> session , & a2dp -> ctrl_param );
686754}
687755
756+ int bt_a2dp_stream_release (struct bt_a2dp_stream * stream )
757+ {
758+ int err ;
759+ struct bt_a2dp * a2dp = stream -> a2dp ;
760+
761+ err = bt_a2dp_stream_ctrl_pre (stream , bt_a2dp_close_cb );
762+ if (err ) {
763+ return err ;
764+ }
765+ return bt_avdtp_close (& a2dp -> session , & a2dp -> ctrl_param );
766+ }
767+
688768int bt_a2dp_stream_start (struct bt_a2dp_stream * stream )
689769{
690770 int err ;
@@ -697,6 +777,30 @@ int bt_a2dp_stream_start(struct bt_a2dp_stream *stream)
697777 return bt_avdtp_start (& a2dp -> session , & a2dp -> ctrl_param );
698778}
699779
780+ int bt_a2dp_stream_suspend (struct bt_a2dp_stream * stream )
781+ {
782+ int err ;
783+ struct bt_a2dp * a2dp = stream -> a2dp ;
784+
785+ err = bt_a2dp_stream_ctrl_pre (stream , bt_a2dp_suspend_cb );
786+ if (err ) {
787+ return err ;
788+ }
789+ return bt_avdtp_suspend (& a2dp -> session , & a2dp -> ctrl_param );
790+ }
791+
792+ int bt_a2dp_stream_abort (struct bt_a2dp_stream * stream )
793+ {
794+ int err ;
795+ struct bt_a2dp * a2dp = stream -> a2dp ;
796+
797+ err = bt_a2dp_stream_ctrl_pre (stream , bt_a2dp_abort_cb );
798+ if (err ) {
799+ return err ;
800+ }
801+ return bt_avdtp_abort (& a2dp -> session , & a2dp -> ctrl_param );
802+ }
803+
700804int bt_a2dp_stream_reconfig (struct bt_a2dp_stream * stream , struct bt_a2dp_codec_cfg * config )
701805{
702806 uint8_t remote_id ;
@@ -749,6 +853,30 @@ int bt_a2dp_stream_send(struct bt_a2dp_stream *stream, struct net_buf *buf, uint
749853}
750854#endif
751855
856+ int a2dp_stream_l2cap_disconnected (struct bt_avdtp * session , struct bt_avdtp_sep * sep )
857+ {
858+ struct bt_a2dp_ep * ep ;
859+
860+ __ASSERT (sep , "Invalid sep" );
861+ ep = CONTAINER_OF (sep , struct bt_a2dp_ep , sep );
862+ if (ep -> stream != NULL ) {
863+ struct bt_a2dp_stream_ops * ops ;
864+ struct bt_a2dp_stream * stream = ep -> stream ;
865+
866+ ops = stream -> ops ;
867+ /* Many places set ep->stream as NULL like abort and close.
868+ * it should be OK without lock protection because
869+ * all the related callbacks are in the same zephyr task context.
870+ */
871+ ep -> stream = NULL ;
872+ if ((ops != NULL ) && (ops -> released != NULL )) {
873+ ops -> released (stream );
874+ }
875+ }
876+
877+ return 0 ;
878+ }
879+
752880static const struct bt_avdtp_ops_cb signaling_avdtp_ops = {
753881 .connected = a2dp_connected ,
754882 .disconnected = a2dp_disconnected ,
@@ -759,6 +887,10 @@ static const struct bt_avdtp_ops_cb signaling_avdtp_ops = {
759887 .re_configuration_ind = a2dp_re_config_ind ,
760888 .open_ind = a2dp_open_ind ,
761889 .start_ind = a2dp_start_ind ,
890+ .close_ind = a2dp_close_ind ,
891+ .suspend_ind = a2dp_suspend_ind ,
892+ .abort_ind = a2dp_abort_ind ,
893+ .stream_l2cap_disconnected = a2dp_stream_l2cap_disconnected ,
762894};
763895
764896int a2dp_accept (struct bt_conn * conn , struct bt_avdtp * * session )
0 commit comments