This adds watches to handle closed sockets --- src/shared/bass.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++ src/shared/bass.h | 2 ++ 2 files changed, 61 insertions(+) diff --git a/src/shared/bass.c b/src/shared/bass.c index 0ee3187d1..78103d463 100644 --- a/src/shared/bass.c +++ b/src/shared/bass.c @@ -655,6 +655,11 @@ static void connect_cb(GIOChannel *io, GError *gerr, g_io_channel_unref(bcast_src->listen_io); bcast_src->listen_io = NULL; + if (bcast_src->listen_io_id > 0) { + g_source_remove(bcast_src->listen_io_id); + bcast_src->listen_io_id = 0; + } + /* Close pa sync io */ if (bcast_src->pa_sync_io) { g_io_channel_shutdown(bcast_src->pa_sync_io, @@ -663,6 +668,11 @@ static void connect_cb(GIOChannel *io, GError *gerr, bcast_src->pa_sync_io = NULL; } + if (bcast_src->pa_sync_io_id > 0) { + g_source_remove(bcast_src->pa_sync_io_id); + bcast_src->pa_sync_io_id = 0; + } + for (i = 0; i < bcast_src->num_subgroups; i++) bcast_src->subgroup_data[i].bis_sync = BT_BASS_BIG_SYNC_FAILED_BITMASK; @@ -703,6 +713,18 @@ static bool bass_trigger_big_sync(struct bt_bcast_src *bcast_src) return false; } +static gboolean pa_sync_io_disconnect_cb(GIOChannel *io, GIOCondition cond, + gpointer data) +{ + struct bt_bcast_src *bcast_src = data; + + DBG(bcast_src->bass, "PA sync io has been disconnected"); + + bcast_src->pa_sync_io_id = 0; + bcast_src->pa_sync_io = NULL; + + return FALSE; +} static void confirm_cb(GIOChannel *io, gpointer user_data) { @@ -726,6 +748,15 @@ static void confirm_cb(GIOChannel *io, gpointer user_data) bcast_src->pa_sync_io = io; g_io_channel_ref(bcast_src->pa_sync_io); + if (bcast_src->pa_sync_io_id > 0) { + g_source_remove(bcast_src->pa_sync_io_id); + bcast_src->pa_sync_io_id = 0; + } + + bcast_src->pa_sync_io_id = g_io_add_watch(io, G_IO_ERR | G_IO_HUP | + G_IO_NVAL, (GIOFunc) pa_sync_io_disconnect_cb, + bcast_src); + len = sizeof(qos); memset(&qos, 0, len); @@ -844,6 +875,19 @@ static bool bass_validate_add_src_params(uint8_t *value, size_t len) return true; } +static gboolean listen_io_disconnect_cb(GIOChannel *io, GIOCondition cond, + gpointer data) +{ + struct bt_bcast_src *bcast_src = data; + + DBG(bcast_src->bass, "Listen io has been disconnected"); + + bcast_src->listen_io_id = 0; + bcast_src->listen_io = NULL; + + return FALSE; +} + static void bass_handle_add_src_op(struct bt_bass *bass, struct gatt_db_attribute *attrib, uint8_t opcode, @@ -1023,6 +1067,11 @@ static void bass_handle_add_src_op(struct bt_bass *bass, bcast_src->listen_io = io; g_io_channel_ref(bcast_src->listen_io); + bcast_src->listen_io_id = g_io_add_watch(io, G_IO_ERR | + G_IO_HUP | G_IO_NVAL, + (GIOFunc)listen_io_disconnect_cb, + bcast_src); + if (num_bis > 0 && !bcast_src->bises) bcast_src->bises = queue_new(); } else { @@ -1318,11 +1367,21 @@ static void bass_bcast_src_free(void *data) g_io_channel_unref(bcast_src->listen_io); } + if (bcast_src->listen_io_id > 0) { + g_source_remove(bcast_src->listen_io_id); + bcast_src->listen_io_id = 0; + } + if (bcast_src->pa_sync_io) { g_io_channel_shutdown(bcast_src->pa_sync_io, TRUE, NULL); g_io_channel_unref(bcast_src->pa_sync_io); } + if (bcast_src->pa_sync_io_id > 0) { + g_source_remove(bcast_src->pa_sync_io_id); + bcast_src->pa_sync_io_id = 0; + } + queue_destroy(bcast_src->bises, bass_bis_unref); free(bcast_src); diff --git a/src/shared/bass.h b/src/shared/bass.h index c4b5b76ba..bd3fe900b 100644 --- a/src/shared/bass.h +++ b/src/shared/bass.h @@ -57,7 +57,9 @@ struct bt_bcast_src { uint8_t num_subgroups; struct bt_bass_subgroup_data *subgroup_data; GIOChannel *listen_io; + guint listen_io_id; GIOChannel *pa_sync_io; + guint pa_sync_io_id; struct queue *bises; }; -- 2.39.2