@@ -916,6 +916,35 @@ static void setup_free(void *data)
free(setup);
}
+static void update_stream(void *data, void *user_data)
+{
+ struct bap_setup *setup = data;
+ struct bap_setup *data_setup = user_data;
+
+ if ((setup->stream != data_setup->stream) &&
+ (setup->qos.bcast.big == data_setup->qos.bcast.big)) {
+
+ if (setup->base)
+ util_iov_free(setup->base, 1);
+
+ setup->base = util_iov_dup(data_setup->base, 1);
+ }
+}
+
+static void update_setup(void *data, void *user_data)
+{
+ struct bap_ep *ep = data;
+ struct bap_setup *setup = user_data;
+
+ queue_foreach(ep->setups, update_stream, setup);
+}
+
+static void update_base(struct bap_setup *setup,
+ struct bap_data *data)
+{
+ queue_foreach(data->bcast, update_setup, setup);
+}
+
static struct bap_ep *ep_register_bcast(struct bap_data *data,
struct bt_bap_pac *lpac,
struct bt_bap_pac *rpac);
@@ -975,6 +1004,10 @@ static DBusMessage *set_configuration(DBusConnection *conn, DBusMessage *msg,
setup->msg = dbus_message_ref(msg);
else {
setup->base = bt_bap_stream_get_base(setup->stream);
+ /* Set the generated BASE on all setups
+ * from the same BIG.
+ */
+ update_base(setup, ep->data);
setup->id = 0;
/* Create a new endpoint for a new BIS */
if (!ep_register_bcast(ep->data, ep->lpac, ep->rpac))
@@ -1847,7 +1880,7 @@ static void setup_connect_io(struct bap_data *data, struct bap_setup *setup,
static void setup_connect_io_broadcast(struct bap_data *data,
struct bap_setup *setup,
struct bt_bap_stream *stream,
- struct bt_iso_qos *qos)
+ struct bt_iso_qos *qos, int defer)
{
struct btd_adapter *adapter = data->user_data;
GIOChannel *io = NULL;
@@ -1884,7 +1917,7 @@ static void setup_connect_io_broadcast(struct bap_data *data,
BT_IO_OPT_MODE, BT_IO_MODE_ISO,
BT_IO_OPT_QOS, qos,
BT_IO_OPT_BASE, &base,
- BT_IO_OPT_DEFER_TIMEOUT, false,
+ BT_IO_OPT_DEFER_TIMEOUT, defer,
BT_IO_OPT_INVALID);
if (!io) {
@@ -2013,9 +2046,6 @@ static void setup_create_bcast_io(struct bap_data *data,
memset(&iso_qos, 0, sizeof(iso_qos));
- if (!defer)
- goto done;
-
iso_qos.bcast.big = setup->qos.bcast.big;
iso_qos.bcast.bis = setup->qos.bcast.bis;
iso_qos.bcast.sync_factor = setup->qos.bcast.sync_factor;
@@ -2032,9 +2062,10 @@ static void setup_create_bcast_io(struct bap_data *data,
iso_qos.bcast.timeout = setup->qos.bcast.timeout;
memcpy(&iso_qos.bcast.out, &setup->qos.bcast.io_qos,
sizeof(struct bt_iso_io_qos));
-done:
+
if (bt_bap_pac_get_type(setup->ep->lpac) == BT_BAP_BCAST_SOURCE)
- setup_connect_io_broadcast(data, setup, stream, &iso_qos);
+ setup_connect_io_broadcast(data, setup, stream, &iso_qos,
+ defer);
else
setup_listen_io_broadcast(data, setup, stream, &iso_qos);
}
@@ -2127,6 +2158,7 @@ static void bap_state_bcast(struct bt_bap_stream *stream, uint8_t old_state,
{
struct bap_data *data = user_data;
struct bap_setup *setup;
+ bool defer = false;
DBG("stream %p: %s(%u) -> %s(%u)", stream,
bt_bap_stream_statestr(old_state), old_state,
@@ -2148,13 +2180,26 @@ static void bap_state_bcast(struct bt_bap_stream *stream, uint8_t old_state,
break;
case BT_BAP_STREAM_STATE_CONFIG:
if (setup && !setup->id) {
- setup_create_io(data, setup, stream, true);
+ /* If the BIG ID was explicitly set, keep creating each
+ * stream io with defer setup until all streams
+ * belonging to the BIG have been configured
+ * (i.e. transport acquire received on appropriate
+ * transport). If the BIG id was left unset, just
+ * create the io without defer, and a BIG with an
+ * arbitrary handle will be created in kernel space.
+ */
+ if (setup->qos.bcast.big != 0xFF)
+ defer = !bt_bap_test_bcast_streams_state(
+ setup->stream,
+ BT_BAP_STREAM_STATE_CONFIG);
+
+ setup_create_io(data, setup, stream, defer);
if (!setup->io) {
error("Unable to create io");
- if (old_state != BT_BAP_STREAM_STATE_RELEASING)
- bt_bap_stream_release(stream, NULL,
- NULL);
- return;
+ if (old_state !=
+ BT_BAP_STREAM_STATE_RELEASING)
+ bt_bap_stream_release(stream,
+ NULL, NULL);
}
}
break;