diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index 83e3c97..08ed699 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
struct bt_bap_qos qos;
guint resume_id;
struct iovec *meta;
+ guint chan_id;
};
struct media_transport_ops {
return id;
}
+static void bap_clear_chan(struct bap_transport *bap)
+{
+ if (bap->chan_id) {
+ g_source_remove(bap->chan_id);
+ bap->chan_id = 0;
+ }
+}
+
static void transport_bap_cancel(struct media_transport *transport, guint id)
{
struct bap_transport *bap = transport->data;
+ bap_clear_chan(bap);
+
if (id == bap->resume_id && bap->resume_id) {
g_source_remove(bap->resume_id);
bap->resume_id = 0;
}
}
+static gboolean bap_transport_fd_ready(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ struct media_transport *transport = data;
+ struct bap_transport *bap = transport->data;
+ int fd;
+ uint16_t imtu, omtu;
+ GError *err = NULL;
+
+ if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
+ error("Transport connection failed");
+ goto done;
+ }
+
+ if (!bt_io_get(chan, &err, BT_IO_OPT_OMTU, &omtu,
+ BT_IO_OPT_IMTU, &imtu,
+ BT_IO_OPT_INVALID)) {
+ error("%s", err->message);
+ goto done;
+ }
+
+ fd = g_io_channel_unix_get_fd(chan);
+ media_transport_set_fd(transport, fd, imtu, omtu);
+ transport_update_playing(transport, TRUE);
+
+done:
+ bap->chan_id = 0;
+ bap_resume_complete(transport);
+
+ return FALSE;
+}
+
static void bap_state_changed(struct bt_bap_stream *stream, uint8_t old_state,
uint8_t new_state, void *user_data)
{
struct media_owner *owner = transport->owner;
struct io *io;
GIOChannel *chan;
- GError *err = NULL;
int fd;
- uint16_t imtu, omtu;
if (bap->stream != stream)
return;
bap_update_bcast_qos(transport);
bap_metadata_changed(transport);
- transport_update_playing(transport, TRUE);
break;
case BT_BAP_STREAM_STATE_RELEASING:
if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SINK)
goto done;
}
- chan = g_io_channel_unix_new(fd);
-
- if (!bt_io_get(chan, &err, BT_IO_OPT_OMTU, &omtu,
- BT_IO_OPT_IMTU, &imtu,
- BT_IO_OPT_INVALID)) {
- error("%s", err->message);
- goto done;
- }
+ /* Wait for FD to become ready */
+ bap_clear_chan(bap);
+ chan = g_io_channel_unix_new(fd);
+ bap->chan_id = g_io_add_watch(chan,
+ G_IO_OUT | G_IO_IN |
+ G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ bap_transport_fd_ready, transport);
g_io_channel_unref(chan);
-
- media_transport_set_fd(transport, fd, imtu, omtu);
- transport_update_playing(transport, TRUE);
+ if (bap->chan_id)
+ return;
done:
+ bap_clear_chan(bap);
bap_resume_complete(transport);
}
{
struct bap_transport *bap = data;
+ bap_clear_chan(bap);
+
util_iov_free(bap->meta, 1);
bt_bap_state_unregister(bt_bap_stream_get_session(bap->stream),
bap->state_id);