static void bluetooth_exit(struct bluetooth_data *data) { struct bluetooth_a2dp *a2dp = &data->a2dp; if (data->server.fd >= 0) bt_audio_service_close(data->server.fd); if (data->stream.fd >= 0) close(data->stream.fd); if (data->hw_thread) { pthread_cancel(data->hw_thread); pthread_join(data->hw_thread, 0); } if (a2dp->sbc_initialized) sbc_finish(&a2dp->sbc); if (data->pipefd[0] > 0) close(data->pipefd[0]); if (data->pipefd[1] > 0) close(data->pipefd[1]); free(data); }
static void bluetooth_close(struct bluetooth_data *data) { DBG("bluetooth_close"); if (data->server.fd >= 0) { bt_audio_service_close(data->server.fd); data->server.fd = -1; } if (data->stream.fd >= 0) { close(data->stream.fd); data->stream.fd = -1; } data->state = A2DP_STATE_NONE; }
static gboolean gst_avdtp_sink_start(GstBaseSink *basesink) { GstAvdtpSink *self = GST_AVDTP_SINK(basesink); gint sk; gint err; GST_INFO_OBJECT(self, "start"); self->watch_id = 0; sk = bt_audio_service_open(); if (sk <= 0) { err = errno; GST_ERROR_OBJECT(self, "Cannot open connection to bt " "audio service: %s %d", strerror(err), err); goto failed; } self->server = g_io_channel_unix_new(sk); self->watch_id = g_io_add_watch(self->server, G_IO_HUP | G_IO_ERR | G_IO_NVAL, server_callback, self); self->data = g_new0(struct bluetooth_data, 1); self->stream = NULL; self->stream_caps = NULL; self->mp3_using_crc = -1; self->channel_mode = -1; if (!gst_avdtp_sink_get_capabilities(self)) { GST_ERROR_OBJECT(self, "failed to get capabilities " "from device"); goto failed; } return TRUE; failed: bt_audio_service_close(sk); return FALSE; }
static gboolean gst_avdtp_sink_stop(GstBaseSink *basesink) { GstAvdtpSink *self = GST_AVDTP_SINK(basesink); GST_INFO_OBJECT(self, "stop"); if (self->watch_id != 0) { g_source_remove(self->watch_id); self->watch_id = 0; } if (self->server) { bt_audio_service_close(g_io_channel_unix_get_fd(self->server)); g_io_channel_unref(self->server); self->server = NULL; } if (self->stream) { g_io_channel_shutdown(self->stream, TRUE, NULL); g_io_channel_unref(self->stream); self->stream = NULL; } if (self->data) { g_free(self->data); self->data = NULL; } if (self->stream_caps) { gst_caps_unref(self->stream_caps); self->stream_caps = NULL; } if (self->dev_caps) { gst_caps_unref(self->dev_caps); self->dev_caps = NULL; } return TRUE; }
static void bluetooth_close(struct bluetooth_data *data) { DBG("bluetooth_close"); if (data->server.fd >= 0) { // sending BT_CLOSE to cleanup unix socket. char buf[BT_SUGGESTED_BUFFER_SIZE]; struct bt_close_req *close_req = (void*) buf; struct bt_close_rsp *close_rsp = (void*) buf; int err; memset(close_req, 0, BT_SUGGESTED_BUFFER_SIZE); close_req->h.type = BT_REQUEST; close_req->h.name = BT_CLOSE; close_req->h.length = sizeof(*close_req); err = audioservice_send(data, &close_req->h); if (err < 0) { ERR("audioservice_send failed for BT_CLOSE_REQ\n"); } else { close_rsp->h.length = 0; err = audioservice_expect(data, &close_rsp->h, BT_CLOSE); if (err < 0) { ERR("audioservice_expect failed for BT_CLOSE_RSP\n"); } } bt_audio_service_close(data->server.fd); data->server.fd = -1; } if (data->stream.fd >= 0) { close(data->stream.fd); data->stream.fd = -1; } data->state = A2DP_STATE_NONE; }