2424#include <zephyr/logging/log.h>
2525#include <zephyr/net_buf.h>
2626#include <zephyr/sys/__assert.h>
27+ #include <zephyr/sys/atomic.h>
2728#include <zephyr/sys/util.h>
2829#include <zephyr/sys/time_units.h>
2930#include <zephyr/sys/util_macro.h>
@@ -279,6 +280,12 @@ enum mpl_objects {
279280 MPL_OBJ_SEARCH_RESULTS ,
280281};
281282
283+ enum mpl_obj_flag {
284+ MPL_OBJ_FLAG_BUSY ,
285+
286+ MPL_OBJ_FLAG_NUM_FLAGS , /* keep as last */
287+ };
288+
282289/* The active object */
283290/* Only a single object is selected or being added (active) at a time. */
284291/* And, except for the icon object, all objects can be created dynamically. */
@@ -287,8 +294,6 @@ struct obj_t {
287294 /* ID of the currently selected object*/
288295 uint64_t selected_id ;
289296
290- bool busy ;
291-
292297 /* Type of object being added, e.g. MPL_OBJ_ICON */
293298 uint8_t add_type ;
294299
@@ -302,15 +307,16 @@ struct obj_t {
302307 struct mpl_group * add_group ;
303308 };
304309 struct net_buf_simple * content ;
310+
311+ ATOMIC_DEFINE (flags , MPL_OBJ_FLAG_NUM_FLAGS );
305312};
306313
307314static struct obj_t obj = {
308315 .selected_id = 0 ,
309316 .add_type = MPL_OBJ_NONE ,
310- .busy = false,
311317 .add_track = NULL ,
312318 .add_group = NULL ,
313- .content = NET_BUF_SIMPLE (CONFIG_BT_MPL_MAX_OBJ_SIZE )
319+ .content = NET_BUF_SIMPLE (CONFIG_BT_MPL_MAX_OBJ_SIZE ),
314320};
315321
316322/* Set up content buffer for the icon object */
@@ -475,13 +481,6 @@ static int add_icon_object(struct mpl_mediaplayer *pl)
475481 const struct bt_uuid * icon_type = BT_UUID_OTS_TYPE_MPL_ICON ;
476482 static char * icon_name = "Icon" ;
477483
478- if (obj .busy ) {
479- /* TODO: Can there be a collision between select and internal */
480- /* activities, like adding new objects? */
481- LOG_ERR ("Object busy" );
482- return 0 ;
483- }
484- obj .busy = true;
485484 obj .add_type = MPL_OBJ_ICON ;
486485 obj .desc = & created_desc ;
487486
@@ -496,7 +495,6 @@ static int add_icon_object(struct mpl_mediaplayer *pl)
496495 ret = bt_ots_obj_add (bt_mcs_get_ots (), & add_param );
497496 if (ret < 0 ) {
498497 LOG_WRN ("Unable to add icon object, error %d" , ret );
499- obj .busy = false;
500498
501499 return ret ;
502500 }
@@ -512,11 +510,6 @@ static int add_current_track_segments_object(struct mpl_mediaplayer *pl)
512510 struct bt_ots_obj_created_desc created_desc = {};
513511 const struct bt_uuid * segs_type = BT_UUID_OTS_TYPE_TRACK_SEGMENT ;
514512
515- if (obj .busy ) {
516- LOG_ERR ("Object busy" );
517- return 0 ;
518- }
519- obj .busy = true;
520513 obj .add_type = MPL_OBJ_TRACK_SEGMENTS ;
521514 obj .desc = & created_desc ;
522515
@@ -531,7 +524,6 @@ static int add_current_track_segments_object(struct mpl_mediaplayer *pl)
531524 ret = bt_ots_obj_add (bt_mcs_get_ots (), & add_param );
532525 if (ret < 0 ) {
533526 LOG_WRN ("Unable to add track segments object: %d" , ret );
534- obj .busy = false;
535527
536528 return ret ;
537529 }
@@ -547,17 +539,11 @@ static int add_track_object(struct mpl_track *track)
547539 const struct bt_uuid * track_type = BT_UUID_OTS_TYPE_TRACK ;
548540 int ret ;
549541
550- if (obj .busy ) {
551- LOG_ERR ("Object busy" );
552- return 0 ;
553- }
554542 if (!track ) {
555543 LOG_ERR ("No track" );
556544 return - EINVAL ;
557545 }
558546
559- obj .busy = true;
560-
561547 obj .add_type = MPL_OBJ_TRACK ;
562548 obj .add_track = track ;
563549 obj .desc = & created_desc ;
@@ -573,7 +559,6 @@ static int add_track_object(struct mpl_track *track)
573559 ret = bt_ots_obj_add (bt_mcs_get_ots (), & add_param );
574560 if (ret < 0 ) {
575561 LOG_WRN ("Unable to add track object: %d" , ret );
576- obj .busy = false;
577562
578563 return ret ;
579564 }
@@ -589,11 +574,6 @@ static int add_parent_group_object(struct mpl_mediaplayer *pl)
589574 struct bt_ots_obj_created_desc created_desc = {};
590575 const struct bt_uuid * group_type = BT_UUID_OTS_TYPE_GROUP ;
591576
592- if (obj .busy ) {
593- LOG_ERR ("Object busy" );
594- return 0 ;
595- }
596- obj .busy = true;
597577 obj .add_type = MPL_OBJ_PARENT_GROUP ;
598578 obj .desc = & created_desc ;
599579
@@ -608,7 +588,6 @@ static int add_parent_group_object(struct mpl_mediaplayer *pl)
608588 ret = bt_ots_obj_add (bt_mcs_get_ots (), & add_param );
609589 if (ret < 0 ) {
610590 LOG_WRN ("Unable to add parent group object" );
611- obj .busy = false;
612591
613592 return ret ;
614593 }
@@ -624,18 +603,11 @@ static int add_group_object(struct mpl_group *group)
624603 const struct bt_uuid * group_type = BT_UUID_OTS_TYPE_GROUP ;
625604 int ret ;
626605
627- if (obj .busy ) {
628- LOG_ERR ("Object busy" );
629- return 0 ;
630- }
631-
632606 if (!group ) {
633607 LOG_ERR ("No group" );
634608 return - EINVAL ;
635609 }
636610
637- obj .busy = true;
638-
639611 obj .add_type = MPL_OBJ_GROUP ;
640612 obj .add_group = group ;
641613 obj .desc = & created_desc ;
@@ -651,7 +623,6 @@ static int add_group_object(struct mpl_group *group)
651623 ret = bt_ots_obj_add (bt_mcs_get_ots (), & add_param );
652624 if (ret < 0 ) {
653625 LOG_WRN ("Unable to add group object: %d" , ret );
654- obj .busy = false;
655626
656627 return ret ;
657628 }
@@ -729,13 +700,12 @@ static int on_obj_deleted(struct bt_ots *ots, struct bt_conn *conn,
729700static void on_obj_selected (struct bt_ots * ots , struct bt_conn * conn ,
730701 uint64_t id )
731702{
732- if (obj .busy ) {
703+ if (atomic_test_and_set_bit ( obj .flags , MPL_OBJ_FLAG_BUSY ) ) {
733704 /* TODO: Can there be a collision between select and internal */
734705 /* activities, like adding new objects? */
735706 LOG_ERR ("Object busy - select not performed" );
736707 return ;
737708 }
738- obj .busy = true;
739709
740710 LOG_DBG_OBJ_ID ("Object Id selected: " , id );
741711
@@ -764,18 +734,20 @@ static void on_obj_selected(struct bt_ots *ots, struct bt_conn *conn,
764734 (void )setup_group_object (media_player .group );
765735 } else {
766736 LOG_ERR ("Unknown Object ID" );
767- obj .busy = false ;
737+ atomic_clear_bit ( obj .flags , MPL_OBJ_FLAG_BUSY ) ;
768738 return ;
769739 }
770740
771741 obj .selected_id = id ;
772- obj .busy = false ;
742+ atomic_clear_bit ( obj .flags , MPL_OBJ_FLAG_BUSY ) ;
773743}
774744
775745static int on_obj_created (struct bt_ots * ots , struct bt_conn * conn , uint64_t id ,
776746 const struct bt_ots_obj_add_param * add_param ,
777747 struct bt_ots_obj_created_desc * created_desc )
778748{
749+ /* Objects are always created locally so we do not need to check for MPL_OBJ_FLAG_BUSY */
750+
779751 LOG_DBG_OBJ_ID ("Object Id created: " , id );
780752
781753 * created_desc = * obj .desc ;
@@ -830,24 +802,19 @@ static int on_obj_created(struct bt_ots *ots, struct bt_conn *conn, uint64_t id,
830802 LOG_DBG ("Unknown Object ID" );
831803 }
832804
833- if (obj .add_type == MPL_OBJ_NONE ) {
834- obj .busy = false;
835- }
836805 return 0 ;
837806}
838807
839-
840808static ssize_t on_object_send (struct bt_ots * ots , struct bt_conn * conn ,
841809 uint64_t id , void * * data , size_t len ,
842810 off_t offset )
843811{
844- if (obj .busy ) {
812+ if (atomic_test_and_set_bit ( obj .flags , MPL_OBJ_FLAG_BUSY ) ) {
845813 /* TODO: Can there be a collision between select and internal */
846814 /* activities, like adding new objects? */
847815 LOG_ERR ("Object busy" );
848- return 0 ;
816+ return - EBUSY ;
849817 }
850- obj .busy = true;
851818
852819 if (IS_ENABLED (CONFIG_BT_MPL_LOG_LEVEL_DBG )) {
853820 char t [BT_OTS_OBJ_ID_STR_LEN ];
@@ -857,20 +824,20 @@ static ssize_t on_object_send(struct bt_ots *ots, struct bt_conn *conn,
857824
858825 if (id != obj .selected_id ) {
859826 LOG_ERR ("Read from unselected object" );
860- obj .busy = false ;
861- return 0 ;
827+ atomic_clear_bit ( obj .flags , MPL_OBJ_FLAG_BUSY ) ;
828+ return - EINVAL ;
862829 }
863830
864831 if (!data ) {
865832 LOG_DBG ("Read complete" );
866- obj .busy = false ;
833+ atomic_clear_bit ( obj .flags , MPL_OBJ_FLAG_BUSY ) ;
867834 return 0 ;
868835 }
869836
870837 if (offset >= obj .content -> len ) {
871838 LOG_DBG ("Offset too large" );
872- obj .busy = false ;
873- return 0 ;
839+ atomic_clear_bit ( obj .flags , MPL_OBJ_FLAG_BUSY ) ;
840+ return - EINVAL ;
874841 }
875842
876843 if (IS_ENABLED (CONFIG_BT_MPL_LOG_LEVEL_DBG )) {
@@ -880,7 +847,8 @@ static ssize_t on_object_send(struct bt_ots *ots, struct bt_conn *conn,
880847 }
881848
882849 * data = & obj .content -> data [offset ];
883- obj .busy = false;
850+ atomic_clear_bit (obj .flags , MPL_OBJ_FLAG_BUSY );
851+
884852 return MIN (len , obj .content -> len - offset );
885853}
886854
@@ -2357,14 +2325,29 @@ int media_proxy_pl_init(void)
23572325 */
23582326#ifdef CONFIG_BT_MCS
23592327#ifdef CONFIG_BT_MPL_OBJECTS
2328+ /* The test here is arguably needed as the objects cannot be accessed before bt_mcs_init is
2329+ * called, but the set is to avoid the objects being accessed before properly initialized
2330+ */
2331+ if (atomic_test_and_set_bit (obj .flags , MPL_OBJ_FLAG_BUSY )) {
2332+ LOG_ERR ("Object busy" );
2333+ return - EBUSY ;
2334+ }
2335+
23602336 ret = bt_mcs_init (& ots_cbs );
2337+ if (ret < 0 ) {
2338+ LOG_ERR ("Could not init MCS: %d" , ret );
2339+ atomic_clear_bit (obj .flags , MPL_OBJ_FLAG_BUSY );
2340+
2341+ return ret ;
2342+ }
23612343#else
23622344 ret = bt_mcs_init (NULL );
2363- #endif /* CONFIG_BT_MPL_OBJECTS */
23642345 if (ret < 0 ) {
23652346 LOG_ERR ("Could not init MCS: %d" , ret );
23662347 return ret ;
23672348 }
2349+ #endif /* CONFIG_BT_MPL_OBJECTS */
2350+ /* TODO: If anything below fails we should unregister MCS */
23682351#else
23692352 LOG_WRN ("MCS not configured" );
23702353#endif /* CONFIG_BT_MCS */
@@ -2380,13 +2363,15 @@ int media_proxy_pl_init(void)
23802363 ret = add_icon_object (& media_player );
23812364 if (ret < 0 ) {
23822365 LOG_ERR ("Unable to add icon object, error %d" , ret );
2366+ atomic_clear_bit (obj .flags , MPL_OBJ_FLAG_BUSY );
23832367 return ret ;
23842368 }
23852369
23862370 /* Add all tracks and groups to OTS */
23872371 ret = add_group_and_track_objects (& media_player );
23882372 if (ret < 0 ) {
23892373 LOG_ERR ("Error adding tracks and groups to OTS, error %d" , ret );
2374+ atomic_clear_bit (obj .flags , MPL_OBJ_FLAG_BUSY );
23902375 return ret ;
23912376 }
23922377
@@ -2396,8 +2381,11 @@ int media_proxy_pl_init(void)
23962381 ret = add_current_track_segments_object (& media_player );
23972382 if (ret < 0 ) {
23982383 LOG_ERR ("Error adding Track Segments Object to OTS, error %d" , ret );
2384+ atomic_clear_bit (obj .flags , MPL_OBJ_FLAG_BUSY );
23992385 return ret ;
24002386 }
2387+
2388+ atomic_clear_bit (obj .flags , MPL_OBJ_FLAG_BUSY );
24012389#endif /* CONFIG_BT_MPL_OBJECTS */
24022390
24032391 /* Set up the calls structure */
0 commit comments