Skip to content

Commit c40856e

Browse files
Thalleyjhedberg
authored andcommitted
Bluetooth: ISO: Support bt_disable
Add support for bt_disable in the ISO implementation. This involves clearing all information related to states in the controller, such as the BIGs and CIGs. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
1 parent 3ccbef2 commit c40856e

File tree

6 files changed

+144
-12
lines changed

6 files changed

+144
-12
lines changed

subsys/bluetooth/host/conn_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ int bt_conn_iso_init(void);
323323
/* Cleanup ISO references */
324324
void bt_iso_cleanup_acl(struct bt_conn *iso_conn);
325325

326+
void bt_iso_reset(void);
327+
326328
/* Add a new BR/EDR connection */
327329
struct bt_conn *bt_conn_add_br(const bt_addr_t *peer);
328330

subsys/bluetooth/host/hci_core.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4264,6 +4264,10 @@ int bt_disable(void)
42644264
k_thread_abort(&bt_workq.thread);
42654265
#endif
42664266

4267+
if (IS_ENABLED(CONFIG_BT_ISO)) {
4268+
bt_iso_reset();
4269+
}
4270+
42674271
bt_monitor_send(BT_MONITOR_CLOSE_INDEX, NULL, 0);
42684272

42694273
/* Clear BT_DEV_ENABLE here to prevent early bt_enable() calls, before disable is

subsys/bluetooth/host/iso.c

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -764,25 +764,26 @@ static int validate_send(const struct bt_iso_chan *chan, const struct net_buf *b
764764
BT_ISO_DATA_DBG("chan %p len %zu", chan, net_buf_frags_len(buf));
765765

766766
if (chan->state != BT_ISO_STATE_CONNECTED) {
767-
LOG_DBG("Not connected");
767+
LOG_DBG("Channel %p not connected", chan);
768768
return -ENOTCONN;
769769
}
770770

771771
iso_conn = chan->iso;
772772
if (!iso_conn->iso.info.can_send) {
773-
LOG_DBG("Channel not able to send");
773+
LOG_DBG("Channel %p not able to send", chan);
774774
return -EINVAL;
775775
}
776776

777777
if (buf->size < hdr_size) {
778-
LOG_DBG("Cannot send ISO packet with buffer size %u", buf->size);
778+
LOG_DBG("Channel %p cannot send ISO packet with buffer size %u", chan, buf->size);
779779

780780
return -EMSGSIZE;
781781
}
782782

783783
max_data_len = iso_chan_max_data_len(chan);
784784
if (buf->len > max_data_len) {
785-
LOG_DBG("Cannot send %u octets, maximum %u", buf->len, max_data_len);
785+
LOG_DBG("Channel %p cannot send %u octets, maximum %u", chan, buf->len,
786+
max_data_len);
786787
return -EMSGSIZE;
787788
}
788789

@@ -2194,6 +2195,11 @@ void bt_iso_security_changed(struct bt_conn *acl, uint8_t hci_status)
21942195
continue;
21952196
}
21962197

2198+
/* Set state to disconnected to indicate that we are no longer waiting for
2199+
* encryption.
2200+
* TODO: Remove the BT_ISO_STATE_ENCRYPT_PENDING state and replace with a flag to
2201+
* avoid these unnecessary state changes
2202+
*/
21972203
bt_iso_chan_set_state(iso_chan, BT_ISO_STATE_DISCONNECTED);
21982204

21992205
if (hci_status == BT_HCI_ERR_SUCCESS) {
@@ -2528,7 +2534,7 @@ static void big_disconnect(struct bt_iso_big *big, uint8_t reason)
25282534
SYS_SLIST_FOR_EACH_CONTAINER(&big->bis_channels, bis, node) {
25292535
bis->iso->err = reason;
25302536

2531-
bt_iso_disconnected(bis->iso);
2537+
bt_iso_chan_disconnected(bis, reason);
25322538
}
25332539
}
25342540

@@ -3278,3 +3284,31 @@ int bt_iso_big_sync(struct bt_le_per_adv_sync *sync, struct bt_iso_big_sync_para
32783284
}
32793285
#endif /* CONFIG_BT_ISO_SYNC_RECEIVER */
32803286
#endif /* CONFIG_BT_ISO_BROADCAST */
3287+
3288+
void bt_iso_reset(void)
3289+
{
3290+
#if defined(CONFIG_BT_ISO_CENTRAL)
3291+
for (size_t i = 0U; i < ARRAY_SIZE(cigs); i++) {
3292+
struct bt_iso_cig *cig = &cigs[i];
3293+
struct bt_iso_chan *cis, *tmp;
3294+
3295+
/* Call the disconnected callback for each CIS that is no idle */
3296+
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&cig->cis_channels, cis, tmp, node) {
3297+
if (cis->state != BT_ISO_STATE_DISCONNECTED) {
3298+
bt_iso_chan_disconnected(cis, BT_HCI_ERR_UNSPECIFIED);
3299+
}
3300+
}
3301+
3302+
cleanup_cig(cig);
3303+
}
3304+
#endif /* CONFIG_BT_ISO_CENTRAL */
3305+
3306+
#if defined(CONFIG_BT_ISO_BROADCAST)
3307+
for (size_t i = 0U; i < ARRAY_SIZE(bigs); i++) {
3308+
struct bt_iso_big *big = &bigs[i];
3309+
3310+
big_disconnect(big, BT_HCI_ERR_UNSPECIFIED);
3311+
cleanup_big(big);
3312+
}
3313+
#endif /* CONFIG_BT_ISO_BROADCAST */
3314+
}

tests/bsim/bluetooth/host/iso/cis/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ CONFIG_BT_CTLR_ISO_TX_BUFFER_SIZE=208
2121
CONFIG_BT_CTLR_ISO_TX_BUFFERS=4
2222
CONFIG_BT_CTLR_ISOAL_SOURCES=2
2323
CONFIG_BT_CTLR_ISOAL_SINKS=2
24+
CONFIG_BT_CTLR_CONN_ISO_STREAMS_PER_GROUP=4

tests/bsim/bluetooth/host/iso/cis/src/cis_central.c

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,19 +107,23 @@ static void iso_connected(struct bt_iso_chan *chan)
107107
seq_num = 0U;
108108
enqueue_cnt = ENQUEUE_COUNT;
109109

110-
/* Start send timer */
111-
k_work_schedule(&iso_send_work, K_MSEC(0));
110+
if (chan == default_chan) {
111+
/* Start send timer */
112+
k_work_schedule(&iso_send_work, K_MSEC(0));
112113

113-
SET_FLAG(flag_iso_connected);
114+
SET_FLAG(flag_iso_connected);
115+
}
114116
}
115117

116118
static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason)
117119
{
118120
printk("ISO Channel %p disconnected (reason 0x%02x)\n", chan, reason);
119121

120-
k_work_cancel_delayable(&iso_send_work);
122+
if (chan == default_chan) {
123+
k_work_cancel_delayable(&iso_send_work);
121124

122-
UNSET_FLAG(flag_iso_connected);
125+
UNSET_FLAG(flag_iso_connected);
126+
}
123127
}
124128

125129
static void sdu_sent_cb(struct bt_iso_chan *chan)
@@ -188,12 +192,19 @@ static void set_cig_defaults(struct bt_iso_cig_param *param)
188192

189193
}
190194

191-
static void create_cig(void)
195+
static void create_cig(size_t iso_channels)
192196
{
197+
struct bt_iso_chan *channels[ARRAY_SIZE(iso_chans)];
193198
struct bt_iso_cig_param param;
194199
int err;
195200

201+
for (size_t i = 0U; i < iso_channels; i++) {
202+
channels[i] = &iso_chans[i];
203+
}
204+
196205
set_cig_defaults(&param);
206+
param.num_cis = iso_channels;
207+
param.cis_channels = channels;
197208

198209
err = bt_iso_cig_create(&param, &cig);
199210
if (err != 0) {
@@ -385,10 +396,34 @@ static void terminate_cig(void)
385396
cig = NULL;
386397
}
387398

399+
static void reset_bluetooth(void)
400+
{
401+
int err;
402+
403+
printk("Resetting Bluetooth\n");
404+
405+
err = bt_disable();
406+
if (err != 0) {
407+
FAIL("Failed to disable (%d)\n", err);
408+
409+
return;
410+
}
411+
412+
/* After a disable, all CIGs and BIGs are removed */
413+
cig = NULL;
414+
415+
err = bt_enable(NULL);
416+
if (err != 0) {
417+
FAIL("Failed to re-enable (%d)\n", err);
418+
419+
return;
420+
}
421+
}
422+
388423
static void test_main(void)
389424
{
390425
init();
391-
create_cig();
426+
create_cig(1);
392427
reconfigure_cig();
393428
connect_acl();
394429
connect_cis();
@@ -404,6 +439,34 @@ static void test_main(void)
404439
PASS("Test passed\n");
405440
}
406441

442+
static void test_main_disable(void)
443+
{
444+
init();
445+
446+
/* Setup and connect before disabling */
447+
create_cig(ARRAY_SIZE(iso_chans));
448+
connect_acl();
449+
connect_cis();
450+
451+
/* Reset BT to see if we can set it up again */
452+
reset_bluetooth();
453+
454+
/* Set everything up again to see if everything still works as expected */
455+
create_cig(ARRAY_SIZE(iso_chans));
456+
connect_acl();
457+
connect_cis();
458+
459+
while (seq_num < 100U) {
460+
k_sleep(K_USEC(interval_us));
461+
}
462+
463+
disconnect_cis();
464+
disconnect_acl();
465+
terminate_cig();
466+
467+
PASS("Disable test passed\n");
468+
}
469+
407470
static const struct bst_test_instance test_def[] = {
408471
{
409472
.test_id = "central",
@@ -412,6 +475,13 @@ static const struct bst_test_instance test_def[] = {
412475
.test_tick_f = test_tick,
413476
.test_main_f = test_main,
414477
},
478+
{
479+
.test_id = "central_disable",
480+
.test_descr = "CIS central that tests bt_disable for ISO",
481+
.test_post_init_f = test_init,
482+
.test_tick_f = test_tick,
483+
.test_main_f = test_main_disable,
484+
},
415485
BSTEST_END_MARKER,
416486
};
417487

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/env bash
2+
# Copyright (c) 2023 Nordic Semiconductor
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
source ${ZEPHYR_BASE}/tests/bsim/sh_common.source
6+
7+
simulation_id="iso_cis_disable"
8+
verbosity_level=2
9+
10+
cd ${BSIM_OUT_PATH}/bin
11+
12+
Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_host_iso_cis_prj_conf \
13+
-v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central_disable
14+
15+
Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_host_iso_cis_prj_conf \
16+
-v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral
17+
18+
Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \
19+
-D=2 -sim_length=30e6 $@
20+
21+
wait_for_background_jobs

0 commit comments

Comments
 (0)