1
1
/* Bluetooth Coordinated Set Identification Client
2
2
*
3
3
* Copyright (c) 2020 Bose Corporation
4
- * Copyright (c) 2021-2022 Nordic Semiconductor ASA
4
+ * Copyright (c) 2021-2024 Nordic Semiconductor ASA
5
5
*
6
6
* SPDX-License-Identifier: Apache-2.0
7
7
*
@@ -67,9 +67,14 @@ static struct active_members {
67
67
bt_csip_set_coordinator_ordered_access_t oap_cb ;
68
68
} active ;
69
69
70
+ enum set_coordinator_flag {
71
+ SET_COORDINATOR_FLAG_BUSY ,
72
+
73
+ SET_COORDINATOR_FLAG_NUM_FLAGS , /* keep as last */
74
+ };
75
+
70
76
struct bt_csip_set_coordinator_inst {
71
77
uint8_t inst_count ;
72
- bool busy ;
73
78
uint8_t gatt_write_buf [1 ];
74
79
75
80
struct bt_csip_set_coordinator_svc_inst
@@ -80,6 +85,8 @@ struct bt_csip_set_coordinator_inst {
80
85
struct bt_gatt_discover_params discover_params ;
81
86
struct bt_gatt_read_params read_params ;
82
87
struct bt_gatt_write_params write_params ;
88
+
89
+ ATOMIC_DEFINE (flags , SET_COORDINATOR_FLAG_NUM_FLAGS );
83
90
};
84
91
85
92
static struct bt_uuid_16 uuid = BT_UUID_INIT_16 (0 );
@@ -101,6 +108,14 @@ static void discover_insts_resume(struct bt_conn *conn, uint16_t sirk_handle,
101
108
102
109
static void active_members_reset (void )
103
110
{
111
+ for (size_t i = 0U ; i < active .members_count ; i ++ ) {
112
+ const struct bt_csip_set_coordinator_set_member * member = active .members [i ];
113
+ struct bt_csip_set_coordinator_inst * client =
114
+ CONTAINER_OF (member , struct bt_csip_set_coordinator_inst , set_member );
115
+
116
+ atomic_clear_bit (client -> flags , SET_COORDINATOR_FLAG_BUSY );
117
+ }
118
+
104
119
(void )memset (& active , 0 , sizeof (active ));
105
120
}
106
121
@@ -350,7 +365,7 @@ static void discover_complete(struct bt_csip_set_coordinator_inst *client,
350
365
struct bt_csip_set_coordinator_cb * listener ;
351
366
352
367
client -> cur_inst = NULL ;
353
- client -> busy = false ;
368
+ atomic_clear_bit ( client -> flags , SET_COORDINATOR_FLAG_BUSY ) ;
354
369
355
370
SYS_SLIST_FOR_EACH_CONTAINER (& csip_set_coordinator_cbs , listener , _node ) {
356
371
if (listener -> discover ) {
@@ -656,15 +671,9 @@ static int csip_set_coordinator_read_rank(struct bt_conn *conn,
656
671
static int csip_set_coordinator_discover_sets (struct bt_csip_set_coordinator_inst * client )
657
672
{
658
673
struct bt_csip_set_coordinator_set_member * member = & client -> set_member ;
659
- int err ;
660
674
661
675
/* Start reading values and call CB when done */
662
- err = read_sirk ((struct bt_csip_set_coordinator_svc_inst * )member -> insts [0 ].svc_inst );
663
- if (err == 0 ) {
664
- client -> busy = true;
665
- }
666
-
667
- return err ;
676
+ return read_sirk ((struct bt_csip_set_coordinator_svc_inst * )member -> insts [0 ].svc_inst );
668
677
}
669
678
670
679
static uint8_t discover_func (struct bt_conn * conn ,
@@ -702,7 +711,6 @@ static uint8_t discover_func(struct bt_conn *conn,
702
711
int err ;
703
712
704
713
client -> cur_inst = NULL ;
705
- client -> busy = false;
706
714
err = csip_set_coordinator_discover_sets (client );
707
715
if (err != 0 ) {
708
716
LOG_DBG ("Discover sets failed (err %d)" , err );
@@ -868,8 +876,6 @@ static uint8_t csip_set_coordinator_discover_insts_read_rank_cb(struct bt_conn *
868
876
869
877
__ASSERT (client -> cur_inst != NULL , "client->cur_inst must not be NULL" );
870
878
871
- client -> busy = false;
872
-
873
879
if (err != 0 ) {
874
880
LOG_DBG ("err: 0x%02X" , err );
875
881
@@ -902,8 +908,6 @@ static uint8_t csip_set_coordinator_discover_insts_read_set_size_cb(
902
908
903
909
__ASSERT (client -> cur_inst != NULL , "client->cur_inst must not be NULL" );
904
910
905
- client -> busy = false;
906
-
907
911
if (err != 0 ) {
908
912
LOG_DBG ("err: 0x%02X" , err );
909
913
@@ -982,8 +986,6 @@ static uint8_t csip_set_coordinator_discover_insts_read_sirk_cb(struct bt_conn *
982
986
int cb_err = err ;
983
987
__ASSERT (client -> cur_inst != NULL , "client->cur_inst must not be NULL" );
984
988
985
- client -> busy = false;
986
-
987
989
if (err != 0 ) {
988
990
LOG_DBG ("err: 0x%02X" , err );
989
991
@@ -1053,8 +1055,6 @@ static void discover_insts_resume(struct bt_conn *conn, uint16_t sirk_handle,
1053
1055
1054
1056
if (cb_err != 0 ) {
1055
1057
discover_complete (client , cb_err );
1056
- } else {
1057
- client -> busy = true;
1058
1058
}
1059
1059
}
1060
1060
@@ -1064,8 +1064,6 @@ static void csip_set_coordinator_write_restore_cb(struct bt_conn *conn,
1064
1064
{
1065
1065
struct bt_csip_set_coordinator_inst * client = & client_insts [bt_conn_index (conn )];
1066
1066
1067
- client -> busy = false;
1068
-
1069
1067
if (err != 0 ) {
1070
1068
LOG_WRN ("Could not restore (%d)" , err );
1071
1069
release_set_complete (err );
@@ -1091,9 +1089,7 @@ static void csip_set_coordinator_write_restore_cb(struct bt_conn *conn,
1091
1089
1092
1090
csip_err = csip_set_coordinator_write_set_lock (
1093
1091
client -> cur_inst , false, csip_set_coordinator_write_restore_cb );
1094
- if (csip_err == 0 ) {
1095
- client -> busy = true;
1096
- } else {
1092
+ if (csip_err != 0 ) {
1097
1093
LOG_DBG ("Failed to release next member[%u]: %d" , active .members_handled ,
1098
1094
csip_err );
1099
1095
@@ -1110,8 +1106,6 @@ static void csip_set_coordinator_write_lock_cb(struct bt_conn *conn,
1110
1106
{
1111
1107
struct bt_csip_set_coordinator_inst * client = & client_insts [bt_conn_index (conn )];
1112
1108
1113
- client -> busy = false;
1114
-
1115
1109
if (err != 0 ) {
1116
1110
LOG_DBG ("Could not lock (0x%X)" , err );
1117
1111
if (active .members_handled > 0 && CONFIG_BT_MAX_CONN > 1 ) {
@@ -1131,9 +1125,7 @@ static void csip_set_coordinator_write_lock_cb(struct bt_conn *conn,
1131
1125
1132
1126
csip_err = csip_set_coordinator_write_set_lock (
1133
1127
client -> cur_inst , false, csip_set_coordinator_write_restore_cb );
1134
- if (csip_err == 0 ) {
1135
- client -> busy = true;
1136
- } else {
1128
+ if (csip_err != 0 ) {
1137
1129
LOG_WRN ("Could not release lock of previous locked member: %d" ,
1138
1130
csip_err );
1139
1131
active_members_reset ();
@@ -1162,9 +1154,7 @@ static void csip_set_coordinator_write_lock_cb(struct bt_conn *conn,
1162
1154
1163
1155
csip_err = csip_set_coordinator_write_set_lock (client -> cur_inst , true,
1164
1156
csip_set_coordinator_write_lock_cb );
1165
- if (csip_err == 0 ) {
1166
- client -> busy = true;
1167
- } else {
1157
+ if (csip_err != 0 ) {
1168
1158
LOG_DBG ("Failed to lock next member[%u]: %d" , active .members_handled ,
1169
1159
csip_err );
1170
1160
@@ -1173,9 +1163,7 @@ static void csip_set_coordinator_write_lock_cb(struct bt_conn *conn,
1173
1163
csip_err = csip_set_coordinator_write_set_lock (
1174
1164
prev_inst , false,
1175
1165
csip_set_coordinator_write_restore_cb );
1176
- if (csip_err == 0 ) {
1177
- client -> busy = true;
1178
- } else {
1166
+ if (csip_err != 0 ) {
1179
1167
LOG_WRN ("Could not release lock of previous locked member: %d" ,
1180
1168
csip_err );
1181
1169
active_members_reset ();
@@ -1192,8 +1180,6 @@ static void csip_set_coordinator_write_release_cb(struct bt_conn *conn, uint8_t
1192
1180
{
1193
1181
struct bt_csip_set_coordinator_inst * client = & client_insts [bt_conn_index (conn )];
1194
1182
1195
- client -> busy = false;
1196
-
1197
1183
if (err != 0 ) {
1198
1184
LOG_DBG ("Could not release lock (%d)" , err );
1199
1185
release_set_complete (err );
@@ -1216,9 +1202,7 @@ static void csip_set_coordinator_write_release_cb(struct bt_conn *conn, uint8_t
1216
1202
1217
1203
csip_err = csip_set_coordinator_write_set_lock (
1218
1204
client -> cur_inst , false, csip_set_coordinator_write_release_cb );
1219
- if (csip_err == 0 ) {
1220
- client -> busy = true;
1221
- } else {
1205
+ if (csip_err != 0 ) {
1222
1206
LOG_DBG ("Failed to release next member[%u]: %d" , active .members_handled ,
1223
1207
csip_err );
1224
1208
@@ -1253,8 +1237,6 @@ static uint8_t csip_set_coordinator_read_lock_cb(struct bt_conn *conn,
1253
1237
struct bt_csip_set_coordinator_inst * client = & client_insts [bt_conn_index (conn )];
1254
1238
uint8_t value = 0 ;
1255
1239
1256
- client -> busy = false;
1257
-
1258
1240
if (err != 0 ) {
1259
1241
LOG_DBG ("Could not read lock value (0x%X)" , err );
1260
1242
@@ -1305,9 +1287,7 @@ static uint8_t csip_set_coordinator_read_lock_cb(struct bt_conn *conn,
1305
1287
}
1306
1288
1307
1289
csip_err = csip_set_coordinator_read_set_lock (client -> cur_inst );
1308
- if (csip_err == 0 ) {
1309
- client -> busy = true;
1310
- } else {
1290
+ if (csip_err != 0 ) {
1311
1291
LOG_DBG ("Failed to read next member[%u]: %d" , active .members_handled ,
1312
1292
csip_err );
1313
1293
@@ -1469,7 +1449,7 @@ int bt_csip_set_coordinator_discover(struct bt_conn *conn)
1469
1449
}
1470
1450
1471
1451
client = & client_insts [bt_conn_index (conn )];
1472
- if (client -> busy ) {
1452
+ if (atomic_test_and_set_bit ( client -> flags , SET_COORDINATOR_FLAG_BUSY ) ) {
1473
1453
return - EBUSY ;
1474
1454
}
1475
1455
@@ -1489,8 +1469,9 @@ int bt_csip_set_coordinator_discover(struct bt_conn *conn)
1489
1469
for (size_t i = 0 ; i < ARRAY_SIZE (client -> set_member .insts ); i ++ ) {
1490
1470
client -> set_member .insts [i ].svc_inst = (void * )& client -> svc_insts [i ];
1491
1471
}
1492
- client -> busy = true;
1493
1472
client -> conn = bt_conn_ref (conn );
1473
+ } else {
1474
+ atomic_clear_bit (client -> flags , SET_COORDINATOR_FLAG_BUSY );
1494
1475
}
1495
1476
1496
1477
return err ;
@@ -1568,10 +1549,40 @@ static int verify_members(const struct bt_csip_set_coordinator_set_member **memb
1568
1549
return 0 ;
1569
1550
}
1570
1551
1571
- static int bt_csip_set_coordinator_get_lock_state (
1572
- const struct bt_csip_set_coordinator_set_member * * members ,
1573
- uint8_t count ,
1574
- const struct bt_csip_set_coordinator_set_info * set_info )
1552
+ static bool check_and_set_members_busy (const struct bt_csip_set_coordinator_set_member * members [],
1553
+ size_t count )
1554
+ {
1555
+ size_t num_free ;
1556
+
1557
+ for (num_free = 0U ; num_free < count ; num_free ++ ) {
1558
+ const struct bt_csip_set_coordinator_set_member * member = members [num_free ];
1559
+ struct bt_csip_set_coordinator_inst * client =
1560
+ CONTAINER_OF (member , struct bt_csip_set_coordinator_inst , set_member );
1561
+
1562
+ if (atomic_test_and_set_bit (client -> flags , SET_COORDINATOR_FLAG_BUSY )) {
1563
+ LOG_DBG ("Member[%zu] (%p) is busy" , num_free , member );
1564
+ break ;
1565
+ }
1566
+ }
1567
+
1568
+ /* If any is busy, revert any busy states we've set */
1569
+ if (num_free != count ) {
1570
+ for (size_t i = 0U ; i < num_free ; i ++ ) {
1571
+ const struct bt_csip_set_coordinator_set_member * member = members [i ];
1572
+ struct bt_csip_set_coordinator_inst * client = CONTAINER_OF (
1573
+ member , struct bt_csip_set_coordinator_inst , set_member );
1574
+
1575
+ atomic_clear_bit (client -> flags , SET_COORDINATOR_FLAG_BUSY );
1576
+ }
1577
+ }
1578
+
1579
+ return num_free == count ;
1580
+ }
1581
+
1582
+ static int
1583
+ csip_set_coordinator_get_lock_state (const struct bt_csip_set_coordinator_set_member * * members ,
1584
+ uint8_t count ,
1585
+ const struct bt_csip_set_coordinator_set_info * set_info )
1575
1586
{
1576
1587
int err ;
1577
1588
@@ -1586,6 +1597,11 @@ static int bt_csip_set_coordinator_get_lock_state(
1586
1597
return err ;
1587
1598
}
1588
1599
1600
+ if (!check_and_set_members_busy (members , count )) {
1601
+ LOG_DBG ("One or more members are busy" );
1602
+ return - EBUSY ;
1603
+ }
1604
+
1589
1605
active_members_store_ordered (members , count , set_info , true);
1590
1606
1591
1607
for (uint8_t i = 0U ; i < count ; i ++ ) {
@@ -1638,7 +1654,7 @@ int bt_csip_set_coordinator_ordered_access(
1638
1654
/* wait for the get_lock_state to finish and then call the callback */
1639
1655
active .oap_cb = cb ;
1640
1656
1641
- err = bt_csip_set_coordinator_get_lock_state (members , count , set_info );
1657
+ err = csip_set_coordinator_get_lock_state (members , count , set_info );
1642
1658
if (err != 0 ) {
1643
1659
active .oap_cb = NULL ;
1644
1660
@@ -1667,6 +1683,11 @@ int bt_csip_set_coordinator_lock(
1667
1683
return err ;
1668
1684
}
1669
1685
1686
+ if (!check_and_set_members_busy (members , count )) {
1687
+ LOG_DBG ("One or more members are busy" );
1688
+ return - EBUSY ;
1689
+ }
1690
+
1670
1691
active_members_store_ordered (members , count , set_info , true);
1671
1692
1672
1693
svc_inst = lookup_instance_by_set_info (active .members [0 ], active .info );
@@ -1704,6 +1725,11 @@ int bt_csip_set_coordinator_release(const struct bt_csip_set_coordinator_set_mem
1704
1725
return err ;
1705
1726
}
1706
1727
1728
+ if (!check_and_set_members_busy (members , count )) {
1729
+ LOG_DBG ("One or more members are busy" );
1730
+ return - EBUSY ;
1731
+ }
1732
+
1707
1733
active_members_store_ordered (members , count , set_info , false);
1708
1734
1709
1735
svc_inst = lookup_instance_by_set_info (active .members [0 ], active .info );
0 commit comments