Skip to content

Commit b2cf78a

Browse files
Thalleyjhedberg
authored andcommitted
Bluetooth: Audio: Improved cleanup on disconnect
The LE Audio clients will now do more and proper cleanup during disconnects. Furthermore, the will also take a proper bt_conn_ref when the conn pointer is assigned locally. Signed-off-by: Emil Gydesen <[email protected]>
1 parent 39570bd commit b2cf78a

File tree

7 files changed

+182
-30
lines changed

7 files changed

+182
-30
lines changed

subsys/bluetooth/audio/aics_client.c

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ static uint8_t aics_discover_func(struct bt_conn *conn, const struct bt_gatt_att
621621
return BT_GATT_ITER_CONTINUE;
622622
}
623623

624-
static void aics_client_reset(struct bt_aics *inst, struct bt_conn *conn)
624+
static void aics_client_reset(struct bt_aics *inst)
625625
{
626626
inst->cli.desc_writable = 0;
627627
inst->cli.change_counter = 0;
@@ -635,12 +635,36 @@ static void aics_client_reset(struct bt_aics *inst, struct bt_conn *conn)
635635
inst->cli.control_handle = 0;
636636
inst->cli.desc_handle = 0;
637637

638-
/* It's okay if these fail */
639-
(void)bt_gatt_unsubscribe(conn, &inst->cli.state_sub_params);
640-
(void)bt_gatt_unsubscribe(conn, &inst->cli.status_sub_params);
641-
(void)bt_gatt_unsubscribe(conn, &inst->cli.desc_sub_params);
638+
if (inst->cli.conn != NULL) {
639+
struct bt_conn *conn = inst->cli.conn;
640+
641+
/* It's okay if these fail. In case of disconnect, we can't
642+
* unsubscribe and they will just fail.
643+
* In case that we reset due to another call of the discover
644+
* function, we will unsubscribe (regardless of bonding state)
645+
* to accommodate the new discovery values.
646+
*/
647+
(void)bt_gatt_unsubscribe(conn, &inst->cli.state_sub_params);
648+
(void)bt_gatt_unsubscribe(conn, &inst->cli.status_sub_params);
649+
(void)bt_gatt_unsubscribe(conn, &inst->cli.desc_sub_params);
650+
651+
bt_conn_unref(conn);
652+
inst->cli.conn = NULL;
653+
}
654+
}
655+
656+
static void disconnected(struct bt_conn *conn, uint8_t reason)
657+
{
658+
for (size_t i = 0; i < ARRAY_SIZE(aics_insts); i++) {
659+
if (aics_insts[i].cli.conn == conn) {
660+
aics_client_reset(&aics_insts[i]);
661+
}
662+
}
642663
}
643664

665+
BT_CONN_CB_DEFINE(conn_callbacks) = {
666+
.disconnected = disconnected,
667+
};
644668

645669
int bt_aics_discover(struct bt_conn *conn, struct bt_aics *inst,
646670
const struct bt_aics_discover_param *param)
@@ -669,11 +693,11 @@ int bt_aics_discover(struct bt_conn *conn, struct bt_aics *inst,
669693
return -EBUSY;
670694
}
671695

672-
aics_client_reset(inst, conn);
696+
aics_client_reset(inst);
673697

674698
(void)memset(&inst->cli.discover_params, 0, sizeof(inst->cli.discover_params));
675699

676-
inst->cli.conn = conn;
700+
inst->cli.conn = bt_conn_ref(conn);
677701
inst->cli.discover_params.start_handle = param->start_handle;
678702
inst->cli.discover_params.end_handle = param->end_handle;
679703
inst->cli.discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;

subsys/bluetooth/audio/csis_client.c

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ static uint8_t primary_discover_func(struct bt_conn *conn,
623623
cur_inst->cli.idx = client->inst_count;
624624
cur_inst->cli.start_handle = attr->handle + 1;
625625
cur_inst->cli.end_handle = prim_service->end_handle;
626-
cur_inst->cli.conn = conn;
626+
cur_inst->cli.conn = bt_conn_ref(conn);
627627
client->inst_count++;
628628
}
629629

@@ -1224,6 +1224,55 @@ static int csis_client_read_set_lock(struct bt_csis *inst)
12241224
return bt_gatt_read(inst->cli.conn, &read_params);
12251225
}
12261226

1227+
static void csis_client_reset(struct bt_csis_client_inst *inst)
1228+
{
1229+
for (size_t i = 0; i < ARRAY_SIZE(inst->csis_insts); i++) {
1230+
struct bt_csis_client_svc_inst *cli = &inst->csis_insts[i].cli;
1231+
1232+
cli->idx = 0;
1233+
cli->rank = 0;
1234+
cli->set_lock = 0;
1235+
cli->start_handle = 0;
1236+
cli->end_handle = 0;
1237+
cli->set_sirk_handle = 0;
1238+
cli->set_size_handle = 0;
1239+
cli->set_lock_handle = 0;
1240+
cli->rank_handle = 0;
1241+
1242+
if (cli->conn != NULL) {
1243+
struct bt_conn *conn = cli->conn;
1244+
1245+
/* It's okay if these fail. In case of disconnect,
1246+
* we can't unsubscribe and they will just fail.
1247+
* In case that we reset due to another call of the
1248+
* discover function, we will unsubscribe (regardless of
1249+
* bonding state) to accommodate the new discovery
1250+
* values.
1251+
*/
1252+
(void)bt_gatt_unsubscribe(conn, &cli->sirk_sub_params);
1253+
(void)bt_gatt_unsubscribe(conn, &cli->size_sub_params);
1254+
(void)bt_gatt_unsubscribe(conn, &cli->lock_sub_params);
1255+
1256+
bt_conn_unref(conn);
1257+
cli->conn = NULL;
1258+
}
1259+
}
1260+
}
1261+
1262+
static void disconnected(struct bt_conn *conn, uint8_t reason)
1263+
{
1264+
struct bt_csis_client_inst *inst = &client_insts[bt_conn_index(conn)];
1265+
1266+
/* All csis_insts share the same conn pointer */
1267+
if (inst->csis_insts[0].cli.conn == conn) {
1268+
csis_client_reset(inst);
1269+
}
1270+
}
1271+
1272+
BT_CONN_CB_DEFINE(conn_callbacks) = {
1273+
.disconnected = disconnected,
1274+
};
1275+
12271276
/*************************** PUBLIC FUNCTIONS ***************************/
12281277
void bt_csis_client_register_cb(struct bt_csis_client_cb *cb)
12291278
{

subsys/bluetooth/audio/media_proxy.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,18 @@ int media_proxy_ctrl_register(struct media_proxy_ctrl_cbs *ctrl_cbs)
631631
};
632632

633633
#ifdef CONFIG_BT_MCC
634+
static void disconnected(struct bt_conn *conn, uint8_t reason)
635+
{
636+
if (mprx.remote_player.conn == conn) {
637+
bt_conn_unref(mprx.remote_player.conn);
638+
mprx.remote_player.conn = NULL;
639+
}
640+
}
641+
642+
BT_CONN_CB_DEFINE(conn_callbacks) = {
643+
.disconnected = disconnected,
644+
};
645+
634646
int media_proxy_ctrl_discover_player(struct bt_conn *conn)
635647
{
636648
int err;
@@ -689,7 +701,10 @@ int media_proxy_ctrl_discover_player(struct bt_conn *conn)
689701
return err;
690702
}
691703

692-
mprx.remote_player.conn = conn;
704+
if (mprx.remote_player.conn != NULL) {
705+
bt_conn_unref(mprx.remote_player.conn);
706+
}
707+
mprx.remote_player.conn = bt_conn_ref(conn);
693708
mprx.remote_player.registered = true; /* TODO: Do MCC init and "registration" at startup */
694709

695710
return 0;

subsys/bluetooth/audio/mics_client.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,13 +361,35 @@ static void mics_client_reset(struct bt_mics *mics)
361361
mics->cli.mute_handle = 0;
362362
mics->cli.aics_inst_cnt = 0;
363363

364-
/* It's okay if this fails */
365364
if (mics->cli.conn != NULL) {
366-
(void)bt_gatt_unsubscribe(mics->cli.conn,
367-
&mics->cli.mute_sub_params);
365+
struct bt_conn *conn = mics->cli.conn;
366+
367+
/* It's okay if this fails. In case of disconnect, we can't
368+
* unsubscribe and it will just fail.
369+
* In case that we reset due to another call of the discover
370+
* function, we will unsubscribe (regardless of bonding state)
371+
* to accommodate the new discovery values.
372+
*/
373+
(void)bt_gatt_unsubscribe(conn, &mics->cli.mute_sub_params);
374+
375+
bt_conn_unref(conn);
376+
mics->cli.conn = NULL;
377+
}
378+
}
379+
380+
static void disconnected(struct bt_conn *conn, uint8_t reason)
381+
{
382+
struct bt_mics *mics = &mics_insts[bt_conn_index(conn)];
383+
384+
if (mics->cli.conn == conn) {
385+
mics_client_reset(mics);
368386
}
369387
}
370388

389+
BT_CONN_CB_DEFINE(conn_callbacks) = {
390+
.disconnected = disconnected,
391+
};
392+
371393
int bt_mics_discover(struct bt_conn *conn, struct bt_mics **mics)
372394
{
373395
static bool initialized;
@@ -411,7 +433,7 @@ int bt_mics_discover(struct bt_conn *conn, struct bt_mics **mics)
411433
}
412434
}
413435

414-
mics_inst->cli.conn = conn;
436+
mics_inst->cli.conn = bt_conn_ref(conn);
415437
mics_inst->client_instance = true;
416438
mics_inst->cli.discover_params.func = primary_discover_func;
417439
mics_inst->cli.discover_params.uuid = mics_uuid;

subsys/bluetooth/audio/stream.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,11 @@ void bt_audio_stream_attach(struct bt_conn *conn,
4040
{
4141
BT_DBG("conn %p stream %p ep %p codec %p", conn, stream, ep, codec);
4242

43-
stream->conn = conn;
43+
if (conn != NULL) {
44+
__ASSERT(stream->conn == NULL || stream->conn == conn,
45+
"stream->conn already attached");
46+
stream->conn = bt_conn_ref(conn);
47+
}
4448
stream->codec = codec;
4549
stream->ep = ep;
4650
ep->stream = stream;
@@ -217,7 +221,10 @@ void bt_audio_stream_detach(struct bt_audio_stream *stream)
217221

218222
BT_DBG("stream %p", stream);
219223

220-
stream->conn = NULL;
224+
if (stream->conn != NULL) {
225+
bt_conn_unref(stream->conn);
226+
stream->conn = NULL;
227+
}
221228
stream->codec = NULL;
222229
stream->ep->stream = NULL;
223230
stream->ep = NULL;

subsys/bluetooth/audio/vcs_client.c

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -677,10 +677,8 @@ static void vocs_discover_cb(struct bt_vocs *inst, int err)
677677
}
678678
#endif /* CONFIG_BT_VCS_CLIENT_VOCS */
679679

680-
static void vcs_client_reset(struct bt_conn *conn)
680+
static void vcs_client_reset(struct bt_vcs *vcs_inst)
681681
{
682-
struct bt_vcs *vcs_inst = &vcs_insts[bt_conn_index(conn)];
683-
684682
memset(&vcs_inst->cli.state, 0, sizeof(vcs_inst->cli.state));
685683
vcs_inst->cli.flags = 0;
686684
vcs_inst->cli.start_handle = 0;
@@ -693,11 +691,36 @@ static void vcs_client_reset(struct bt_conn *conn)
693691

694692
memset(&vcs_inst->cli.discover_params, 0, sizeof(vcs_inst->cli.discover_params));
695693

696-
/* It's okay if these fail */
697-
(void)bt_gatt_unsubscribe(conn, &vcs_inst->cli.state_sub_params);
698-
(void)bt_gatt_unsubscribe(conn, &vcs_inst->cli.flag_sub_params);
694+
if (vcs_inst->cli.conn != NULL) {
695+
struct bt_conn *conn = vcs_inst->cli.conn;
696+
697+
/* It's okay if these fail. In case of disconnect, we can't
698+
* unsubscribe and they will just fail.
699+
* In case that we reset due to another call of the discover
700+
* function, we will unsubscribe (regardless of bonding state)
701+
* to accommodate the new discovery values.
702+
*/
703+
(void)bt_gatt_unsubscribe(conn, &vcs_inst->cli.state_sub_params);
704+
(void)bt_gatt_unsubscribe(conn, &vcs_inst->cli.flag_sub_params);
705+
706+
bt_conn_unref(conn);
707+
vcs_inst->cli.conn = NULL;
708+
}
709+
}
710+
711+
static void disconnected(struct bt_conn *conn, uint8_t reason)
712+
{
713+
struct bt_vcs *vcs_inst = &vcs_insts[bt_conn_index(conn)];
714+
715+
if (vcs_inst->cli.conn == conn) {
716+
vcs_client_reset(vcs_inst);
717+
}
699718
}
700719

720+
BT_CONN_CB_DEFINE(conn_callbacks) = {
721+
.disconnected = disconnected,
722+
};
723+
701724
static void bt_vcs_client_init(void)
702725
{
703726
int i, j;
@@ -765,12 +788,12 @@ int bt_vcs_discover(struct bt_conn *conn, struct bt_vcs **vcs)
765788
initialized = true;
766789
}
767790

768-
vcs_client_reset(conn);
791+
vcs_client_reset(vcs_inst);
769792

770793
memcpy(&vcs_inst->cli.uuid, BT_UUID_VCS, sizeof(vcs_inst->cli.uuid));
771794

772795
vcs_inst->client_instance = true;
773-
vcs_inst->cli.conn = conn;
796+
vcs_inst->cli.conn = bt_conn_ref(conn);
774797
vcs_inst->cli.discover_params.func = primary_discover_func;
775798
vcs_inst->cli.discover_params.uuid = &vcs_inst->cli.uuid.uuid;
776799
vcs_inst->cli.discover_params.type = BT_GATT_DISCOVER_PRIMARY;

subsys/bluetooth/audio/vocs_client.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,7 @@ int bt_vocs_client_conn_get(const struct bt_vocs *vocs, struct bt_conn **conn)
656656
return 0;
657657
}
658658

659-
static void vocs_client_reset(struct bt_vocs *inst, struct bt_conn *conn)
659+
static void vocs_client_reset(struct bt_vocs *inst)
660660
{
661661
memset(&inst->cli.state, 0, sizeof(inst->cli.state));
662662
inst->cli.location_writable = 0;
@@ -669,10 +669,22 @@ static void vocs_client_reset(struct bt_vocs *inst, struct bt_conn *conn)
669669
inst->cli.control_handle = 0;
670670
inst->cli.desc_handle = 0;
671671

672-
/* It's okay if these fail */
673-
(void)bt_gatt_unsubscribe(conn, &inst->cli.state_sub_params);
674-
(void)bt_gatt_unsubscribe(conn, &inst->cli.location_sub_params);
675-
(void)bt_gatt_unsubscribe(conn, &inst->cli.desc_sub_params);
672+
if (inst->cli.conn != NULL) {
673+
struct bt_conn *conn = inst->cli.conn;
674+
675+
/* It's okay if these fail. In case of disconnect, we can't
676+
* unsubscribe and they will just fail.
677+
* In case that we reset due to another call of the discover
678+
* function, we will unsubscribe (regardless of bonding state)
679+
* to accommodate the new discovery values.
680+
*/
681+
(void)bt_gatt_unsubscribe(conn, &inst->cli.state_sub_params);
682+
(void)bt_gatt_unsubscribe(conn, &inst->cli.location_sub_params);
683+
(void)bt_gatt_unsubscribe(conn, &inst->cli.desc_sub_params);
684+
685+
bt_conn_unref(conn);
686+
inst->cli.conn = NULL;
687+
}
676688
}
677689

678690
int bt_vocs_discover(struct bt_conn *conn, struct bt_vocs *inst,
@@ -702,9 +714,9 @@ int bt_vocs_discover(struct bt_conn *conn, struct bt_vocs *inst,
702714
return -EBUSY;
703715
}
704716

705-
vocs_client_reset(inst, conn);
717+
vocs_client_reset(inst);
706718

707-
inst->cli.conn = conn;
719+
inst->cli.conn = bt_conn_ref(conn);
708720
inst->cli.discover_params.start_handle = param->start_handle;
709721
inst->cli.discover_params.end_handle = param->end_handle;
710722
inst->cli.discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;

0 commit comments

Comments
 (0)