summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorNick Stoughton <nstoughton@aether.com>2014-12-30 07:21:44 -0800
committerArun Raghavan <git@arunraghavan.net>2015-07-03 15:41:52 +0530
commit2aa0eba67391887f8d08b2aec9ee4a3c439b6e0f (patch)
treef65cd055b76babde259e3b8f19f567879140852e /sys
parentf17899a55cff8bf7ab61b4fe565d0f8e81a74751 (diff)
downloadgstreamer-plugins-bad-2aa0eba67391887f8d08b2aec9ee4a3c439b6e0f.tar.gz
bluez: refactor to use glib and add connection state tracking
Diffstat (limited to 'sys')
-rw-r--r--sys/bluez/Makefile.am24
-rw-r--r--sys/bluez/gstavdtpsink.c4
-rw-r--r--sys/bluez/gstavdtpsrc.c4
-rw-r--r--sys/bluez/gstavdtputil.c274
-rw-r--r--sys/bluez/gstavdtputil.h12
-rw-r--r--sys/bluez/org.bluez.xml29
6 files changed, 151 insertions, 196 deletions
diff --git a/sys/bluez/Makefile.am b/sys/bluez/Makefile.am
index cc9017654..b67c8ba63 100644
--- a/sys/bluez/Makefile.am
+++ b/sys/bluez/Makefile.am
@@ -5,20 +5,23 @@ libgstbluez_la_SOURCES = \
gsta2dpsink.c \
gstavdtpsink.c \
gstavdtpsrc.c \
- gstavdtputil.c
+ gstavdtputil.c \
+ $(BUILT_SOURCES)
libgstbluez_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) \
$(GST_PLUGINS_BASE_CFLAGS) \
$(GST_BASE_CFLAGS) \
$(GST_CFLAGS) \
- $(DBUS_CFLAGS)
+ $(GIO_CFLAGS) \
+ $(GIO_UNIX_CFLAGS)
libgstbluez_la_LIBADD = \
$(GST_PLUGINS_BASE_LIBS) \
-lgstaudio-$(GST_API_VERSION) \
-lgstrtp-$(GST_API_VERSION) \
$(GST_BASE_LIBS) \
$(GST_LIBS) \
- $(DBUS_LIBS)
+ $(GIO_LIBS) \
+ $(GIO_UNIX_LIBS)
libgstbluez_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstbluez_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
@@ -27,4 +30,17 @@ noinst_HEADERS = \
gsta2dpsink.h \
gstavdtpsink.h \
gstavdtpsrc.h \
- gstavdtputil.h
+ gstavdtputil.h \
+ bluez.h
+
+BUILT_SOURCES = \
+ bluez.h \
+ bluez.c
+
+bluez.h: bluez.c
+bluez.c: org.bluez.xml
+ $(AM_V_GEN) $(GDBUS_CODEGEN) \
+ --c-namespace=Bluez \
+ --generate-c-code=bluez \
+ --interface-prefix=org.bluez \
+ $<
diff --git a/sys/bluez/gstavdtpsink.c b/sys/bluez/gstavdtpsink.c
index b549caaa1..70dc742a5 100644
--- a/sys/bluez/gstavdtpsink.c
+++ b/sys/bluez/gstavdtpsink.c
@@ -34,8 +34,6 @@
#include <fcntl.h>
#include <netinet/in.h>
-#include <dbus/dbus.h>
-
#include "a2dp-codecs.h"
#include "gstavdtpsink.h"
@@ -263,7 +261,7 @@ gst_avdtp_sink_start (GstBaseSink * basesink)
if (self->conn.transport == NULL)
return FALSE;
- if (!gst_avdtp_connection_acquire (&self->conn)) {
+ if (!gst_avdtp_connection_acquire (&self->conn, FALSE)) {
GST_ERROR_OBJECT (self, "Failed to acquire connection");
return FALSE;
}
diff --git a/sys/bluez/gstavdtpsrc.c b/sys/bluez/gstavdtpsrc.c
index 311c407b7..176c2d4d0 100644
--- a/sys/bluez/gstavdtpsrc.c
+++ b/sys/bluez/gstavdtpsrc.c
@@ -39,7 +39,7 @@ GST_DEBUG_CATEGORY_STATIC (avdtpsrc_debug);
enum
{
PROP_0,
- PROP_TRANSPORT
+ PROP_TRANSPORT,
};
#define parent_class gst_avdtp_src_parent_class
@@ -262,7 +262,7 @@ gst_avdtp_src_start (GstBaseSrc * bsrc)
* connection to figure out what format the device is going to send us.
*/
- if (!gst_avdtp_connection_acquire (&avdtpsrc->conn)) {
+ if (!gst_avdtp_connection_acquire (&avdtpsrc->conn, FALSE)) {
GST_ERROR_OBJECT (avdtpsrc, "Failed to acquire connection");
return FALSE;
}
diff --git a/sys/bluez/gstavdtputil.c b/sys/bluez/gstavdtputil.c
index 787a06309..52a90a5b6 100644
--- a/sys/bluez/gstavdtputil.c
+++ b/sys/bluez/gstavdtputil.c
@@ -36,98 +36,131 @@
#include <bluetooth/bluetooth.h>
#include "a2dp-codecs.h"
+#include <gio/gunixfdlist.h>
#include <gst/gst.h>
#include "gstavdtputil.h"
+#include "bluez.h"
#define TEMPLATE_MAX_BITPOOL 64
GST_DEBUG_CATEGORY_EXTERN (avdtp_debug);
#define GST_CAT_DEFAULT avdtp_debug
+static void gst_avdtp_connection_transport_release (GstAvdtpConnection * conn);
+
+static gboolean
+on_state_change (BluezMediaTransport1 * proxy, GParamSpec * pspec,
+ GstAvdtpConnection * conn)
+{
+ const gchar *newstate;
+ gboolean is_idle;
+
+ newstate = bluez_media_transport1_get_state (proxy);
+ is_idle = g_str_equal (newstate, "idle");
+
+ if (!conn->data.is_acquired && !is_idle) {
+ GST_DEBUG ("Re-acquiring connection");
+ gst_avdtp_connection_acquire (conn, TRUE);
+
+ } else if (is_idle) {
+ /* We don't know if we need to release the transport -- that may have been
+ * done for us by bluez already! Or not ... so release it just in case, but
+ * mark its stale beforehand to suppress any errors. */
+ GST_DEBUG ("Marking connection stale");
+ conn->data.is_acquired = FALSE;
+ gst_avdtp_connection_transport_release (conn);
+
+ } else
+ GST_DEBUG ("State is %s, acquired is %s", newstate,
+ conn->data.is_acquired ? "true" : "false");
+
+ return TRUE;
+}
+
gboolean
-gst_avdtp_connection_acquire (GstAvdtpConnection * conn)
+gst_avdtp_connection_acquire (GstAvdtpConnection * conn, gboolean use_try)
{
- DBusMessage *msg, *reply;
- DBusError err;
-#ifdef HAVE_BLUEZ4
- const char *access_type = "rw";
-#endif
+ GVariant *handle = NULL;
+ GUnixFDList *fd_list = NULL;
+ GError *err = NULL;
int fd;
uint16_t imtu, omtu;
- dbus_error_init (&err);
-
if (conn->transport == NULL) {
GST_ERROR ("No transport specified");
return FALSE;
}
- if (conn->data.conn == NULL)
- conn->data.conn = dbus_bus_get (DBUS_BUS_SYSTEM, &err);
-
-#ifdef HAVE_BLUEZ4
- msg = dbus_message_new_method_call ("org.bluez", conn->transport,
- "org.bluez.MediaTransport", "Acquire");
+ if (conn->data.conn == NULL) {
+ conn->data.conn =
+ bluez_media_transport1_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE, "org.bluez", conn->transport, NULL, &err);
- dbus_message_append_args (msg, DBUS_TYPE_STRING, &access_type,
- DBUS_TYPE_INVALID);
-#else
- msg = dbus_message_new_method_call ("org.bluez", conn->transport,
- "org.bluez.MediaTransport1", "Acquire");
-#endif
+ if (conn->data.conn == NULL) {
+ GST_ERROR ("Failed to create proxy for media transport: %s",
+ err && err->message ? err->message : "Unknown error");
+ return FALSE;
+ }
- reply = dbus_connection_send_with_reply_and_block (conn->data.conn,
- msg, -1, &err);
+ g_signal_connect (conn->data.conn, "notify::state",
+ G_CALLBACK (on_state_change), conn);
+ }
- dbus_message_unref (msg);
+ if (conn->data.is_acquired) {
+ GST_INFO ("Transport is already acquired");
+ return TRUE;
+ }
- if (dbus_error_is_set (&err))
- goto fail;
+ if (use_try) {
+ if (!bluez_media_transport1_call_try_acquire_sync (conn->data.conn,
+ NULL, &handle, &imtu, &omtu, &fd_list, NULL, &err))
+ goto fail;
+ } else {
+ if (!bluez_media_transport1_call_acquire_sync (conn->data.conn,
+ NULL, &handle, &imtu, &omtu, &fd_list, NULL, &err))
+ goto fail;
+ }
- if (dbus_message_get_args (reply, &err, DBUS_TYPE_UNIX_FD, &fd,
- DBUS_TYPE_UINT16, &imtu,
- DBUS_TYPE_UINT16, &omtu, DBUS_TYPE_INVALID) == FALSE)
+ fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (handle), &err);
+ if (fd < 0)
goto fail;
- dbus_message_unref (reply);
-
+ g_variant_unref (handle);
+ g_object_unref (fd_list);
conn->stream = g_io_channel_unix_new (fd);
g_io_channel_set_encoding (conn->stream, NULL, NULL);
g_io_channel_set_close_on_unref (conn->stream, TRUE);
conn->data.link_mtu = omtu;
+ conn->data.is_acquired = TRUE;
return TRUE;
fail:
- GST_ERROR ("Failed to acquire transport stream: %s", err.message);
-
- dbus_error_free (&err);
+ GST_ERROR ("Failed to %s transport stream: %s", use_try ? "try_acquire" :
+ "acquire", err && err->message ? err->message : "unknown error");
- if (reply)
- dbus_message_unref (reply);
+ g_clear_error (&err);
+ if (handle)
+ g_variant_unref (handle);
+ conn->data.is_acquired = FALSE;
return FALSE;
}
static void
gst_avdtp_connection_transport_release (GstAvdtpConnection * conn)
{
- DBusMessage *msg;
-#ifdef HAVE_BLUEZ4
- const char *access_type = "rw";
-
- msg = dbus_message_new_method_call ("org.bluez", conn->transport,
- "org.bluez.MediaTransport", "Release");
+ GError *err = NULL;
- dbus_message_append_args (msg, DBUS_TYPE_STRING, &access_type,
- DBUS_TYPE_INVALID);
-#else
- msg = dbus_message_new_method_call ("org.bluez", conn->transport,
- "org.bluez.MediaTransport1", "Release");
-#endif
- dbus_connection_send (conn->data.conn, msg, NULL);
+ if (!bluez_media_transport1_call_release_sync (conn->data.conn, NULL, &err)) {
+ /* We don't care about errors if the transport was already marked stale */
+ if (!conn->data.is_acquired)
+ return;
- dbus_message_unref (msg);
+ GST_ERROR ("Failed to release transport stream: %s", err->message ?
+ err->message : "unknown error");
+ }
+ conn->data.is_acquired = FALSE;
}
void
@@ -153,9 +186,7 @@ gst_avdtp_connection_release (GstAvdtpConnection * conn)
if (conn->transport)
gst_avdtp_connection_transport_release (conn);
- dbus_connection_unref (conn->data.conn);
-
- conn->data.conn = NULL;
+ g_clear_object (&conn->data.conn);
}
}
@@ -194,145 +225,22 @@ gst_avdtp_connection_set_transport (GstAvdtpConnection * conn,
conn->transport = g_strdup (transport);
}
-static gboolean
-gst_avdtp_connection_parse_property (GstAvdtpConnection * conn,
- DBusMessageIter * i)
-{
- const char *key;
- DBusMessageIter variant_i;
-
- if (dbus_message_iter_get_arg_type (i) != DBUS_TYPE_STRING) {
- GST_ERROR ("Property name not a string.");
- return FALSE;
- }
-
- dbus_message_iter_get_basic (i, &key);
-
- if (!dbus_message_iter_next (i)) {
- GST_ERROR ("Property value missing");
- return FALSE;
- }
-
- if (dbus_message_iter_get_arg_type (i) != DBUS_TYPE_VARIANT) {
- GST_ERROR ("Property value not a variant.");
- return FALSE;
- }
-
- dbus_message_iter_recurse (i, &variant_i);
-
- switch (dbus_message_iter_get_arg_type (&variant_i)) {
- case DBUS_TYPE_BYTE:{
- uint8_t value;
- dbus_message_iter_get_basic (&variant_i, &value);
-
- if (g_str_equal (key, "Codec") == TRUE)
- conn->data.codec = value;
-
- break;
- }
- case DBUS_TYPE_STRING:{
- const char *value;
- dbus_message_iter_get_basic (&variant_i, &value);
-
- if (g_str_equal (key, "UUID") == TRUE) {
- g_free (conn->data.uuid);
- conn->data.uuid = g_strdup (value);
- }
-
- break;
- }
- case DBUS_TYPE_ARRAY:{
- DBusMessageIter array_i;
- char *value;
- int size;
-
- dbus_message_iter_recurse (&variant_i, &array_i);
- dbus_message_iter_get_fixed_array (&array_i, &value, &size);
-
- if (g_str_equal (key, "Configuration")) {
- g_free (conn->data.config);
- conn->data.config = g_new0 (guint8, size);
- conn->data.config_size = size;
- memcpy (conn->data.config, value, size);
- }
-
- break;
- }
- }
-
- return TRUE;
-}
-
gboolean
gst_avdtp_connection_get_properties (GstAvdtpConnection * conn)
{
- DBusMessage *msg, *reply;
- DBusMessageIter arg_i, ele_i;
- DBusError err;
-#ifndef HAVE_BLUEZ4
- const char *interface;
-#endif
-
- dbus_error_init (&err);
-
-#ifdef HAVE_BLUEZ4
- msg = dbus_message_new_method_call ("org.bluez", conn->transport,
- "org.bluez.MediaTransport", "GetProperties");
-#else
- msg = dbus_message_new_method_call ("org.bluez", conn->transport,
- "org.freedesktop.DBus.Properties", "GetAll");
-#endif
- if (!msg) {
- GST_ERROR ("D-Bus Memory allocation failed");
- return FALSE;
- }
-#ifndef HAVE_BLUEZ4
- interface = "org.bluez.MediaTransport1";
- dbus_message_append_args (msg, DBUS_TYPE_STRING, &interface,
- DBUS_TYPE_INVALID);
-#endif
- reply = dbus_connection_send_with_reply_and_block (conn->data.conn,
- msg, -1, &err);
-
- dbus_message_unref (msg);
-
- if (dbus_error_is_set (&err)) {
- GST_ERROR ("GetProperties failed: %s", err.message);
- dbus_error_free (&err);
- return FALSE;
- }
-
- if (!dbus_message_iter_init (reply, &arg_i)) {
- GST_ERROR ("GetProperties reply has no arguments.");
- goto fail;
- }
-
- if (dbus_message_iter_get_arg_type (&arg_i) != DBUS_TYPE_ARRAY) {
- GST_ERROR ("GetProperties argument is not an array.");
- goto fail;
- }
-
- dbus_message_iter_recurse (&arg_i, &ele_i);
- while (dbus_message_iter_get_arg_type (&ele_i) != DBUS_TYPE_INVALID) {
+ GVariant *var;
- if (dbus_message_iter_get_arg_type (&ele_i) == DBUS_TYPE_DICT_ENTRY) {
- DBusMessageIter dict_i;
+ conn->data.codec = bluez_media_transport1_get_codec (conn->data.conn);
- dbus_message_iter_recurse (&ele_i, &dict_i);
+ conn->data.uuid = bluez_media_transport1_dup_uuid (conn->data.conn);
- gst_avdtp_connection_parse_property (conn, &dict_i);
- }
-
- if (!dbus_message_iter_next (&ele_i))
- break;
- }
+ var = bluez_media_transport1_dup_configuration (conn->data.conn);
+ conn->data.config_size = g_variant_get_size (var);
+ conn->data.config = g_new0 (guint8, conn->data.config_size);
+ g_variant_store (var, conn->data.config);
+ g_variant_unref (var);
return TRUE;
-
-fail:
- dbus_message_unref (reply);
- return FALSE;
-
}
static GstStructure *
diff --git a/sys/bluez/gstavdtputil.h b/sys/bluez/gstavdtputil.h
index b551781af..131944186 100644
--- a/sys/bluez/gstavdtputil.h
+++ b/sys/bluez/gstavdtputil.h
@@ -27,20 +27,23 @@
#include <glib.h>
-#include <dbus/dbus.h>
+#include "bluez.h"
G_BEGIN_DECLS
+
#define DEFAULT_CODEC_BUFFER_SIZE 2048
#define TEMPLATE_MAX_BITPOOL_STR "64"
- struct bluetooth_data
+
+struct bluetooth_data
{
guint link_mtu;
- DBusConnection *conn;
+ BluezMediaTransport1 *conn;
guint8 codec; /* Bluetooth transport configuration */
gchar *uuid;
guint8 *config;
gint config_size;
+ gboolean is_acquired;
gchar buffer[DEFAULT_CODEC_BUFFER_SIZE]; /* Codec transfer buffer */
};
@@ -56,7 +59,8 @@ struct _GstAvdtpConnection
struct bluetooth_data data;
};
-gboolean gst_avdtp_connection_acquire (GstAvdtpConnection * conn);
+gboolean gst_avdtp_connection_acquire (GstAvdtpConnection * conn,
+ gboolean use_try);
void gst_avdtp_connection_release (GstAvdtpConnection * conn);
void gst_avdtp_connection_reset (GstAvdtpConnection * conn);
gboolean gst_avdtp_connection_get_properties (GstAvdtpConnection * conn);
diff --git a/sys/bluez/org.bluez.xml b/sys/bluez/org.bluez.xml
new file mode 100644
index 000000000..ff52ee303
--- /dev/null
+++ b/sys/bluez/org.bluez.xml
@@ -0,0 +1,29 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+
+<node>
+<interface name="org.bluez.MediaTransport1">
+ <method name="Acquire">
+ <annotation name="org.gtk.GDBus.C.UnixFD" value="true" />
+ <arg name="fd" type="h" direction="out"/>
+ <arg name="mtu_r" type="q" direction="out"/>
+ <arg name="mtu_w" type="q" direction="out"/>
+ </method>
+ <method name="TryAcquire">
+ <annotation name="org.gtk.GDBus.C.UnixFD" value="true" />
+ <arg name="fd" type="h" direction="out"/>
+ <arg name="mtu_r" type="q" direction="out"/>
+ <arg name="mtu_w" type="q" direction="out"/>
+ </method>
+ <method name="Release"></method>
+ <property name="Device" type="o" access="read"></property>
+ <property name="UUID" type="s" access="read"></property>
+ <property name="Codec" type="y" access="read"></property>
+ <property name="Configuration" type="ay" access="read">
+ <annotation name="org.gtk.GDBus.C.ForceGVariant" value="true" />
+ </property>
+ <property name="State" type="s" access="read"></property>
+ <property name="Delay" type="q" access="read"></property>
+ <property name="Volume" type="q" access="readwrite"></property>
+</interface>
+</node>