diff options
author | Wim Taymans <wtaymans@redhat.com> | 2014-08-02 20:39:40 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2014-08-02 20:39:40 +0200 |
commit | 2841a3e0963eb8a544e389f02cb5e3f24f2db843 (patch) | |
tree | 1fb9ff96066959d3c0fc89c00c64bfbd129a3d3b | |
parent | 854f4f6f507b224687b8800d284ce042a4625aba (diff) |
implement Transport and call MediaEndpoint
-rwxr-xr-x | compile | 2 | ||||
-rw-r--r-- | make-hsp-ag.c | 177 |
2 files changed, 164 insertions, 15 deletions
@@ -1 +1 @@ -gcc `pkg-config --cflags --libs gio-2.0` -o make-hsp-ag make-hsp-ag.c +gcc `pkg-config --cflags --libs gio-unix-2.0` -o make-hsp-ag make-hsp-ag.c diff --git a/make-hsp-ag.c b/make-hsp-ag.c index f5f4c16..59ac50b 100644 --- a/make-hsp-ag.c +++ b/make-hsp-ag.c @@ -18,6 +18,7 @@ */ #include <gio/gio.h> +#include <gio/gunixfdlist.h> #include <errno.h> #include <sys/types.h> @@ -48,10 +49,25 @@ static const gchar introspection_xml[] = " <arg type='a{sv}' name='opts' direction='in'/>" " </method>" " </interface>" + " <interface name='org.bluez.MediaTransport1'>" + " <method name='Release'>" + " </method>" + " <method name='Acquire'>" + " <arg name='fd' direction='out' type='h'/>" + " <arg name='mtu_r' direction='out' type='q'/>" + " <arg name='mtu_w' direction='out' type='q'/>" + " </method>" + " <method name='TryAcquire'>" + " <arg name='fd' direction='out' type='h'/>" + " <arg name='mtu_r' direction='out' type='q'/>" + " <arg name='mtu_w' direction='out' type='q'/>" + " </method>" + " </interface>" "</node>"; static struct sco_options so; +#if 0 static gboolean sco_io_cb (GIOChannel *source, GIOCondition condition, gpointer data) { @@ -82,10 +98,10 @@ sco_io_cb (GIOChannel *source, GIOCondition condition, gpointer data) } return TRUE; } +#endif static int -start_codec_connection (gchar *src_addr, - gchar *dst_addr) +transport_acquire (gchar *src_addr, gchar *dst_addr) { struct sockaddr_sco addr; int err, i; @@ -148,14 +164,15 @@ start_codec_connection (gchar *src_addr, g_print ("connected: MTU %d\n", so.mtu); + /* io = g_io_channel_unix_new (sock); g_io_channel_set_close_on_unref(io, TRUE); g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL); cond = G_IO_IN | G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL; g_io_add_watch(io, cond, sco_io_cb, NULL); - - return 0; + */ + return sock; } static gboolean @@ -195,7 +212,6 @@ rfcomm_io_cb (GIOChannel *source, GIOCondition condition, gpointer data) } else if (g_str_has_prefix (buf, "AT+CMEE=")) { write (fd, "\r\nOK\r\n", 5); - start_codec_connection ("FC:F8:AE:4A:3F:D4", "13:11:14:AA:00:B8"); } else { write (fd, "\r\nOK\r\n", 5); @@ -205,14 +221,56 @@ rfcomm_io_cb (GIOChannel *source, GIOCondition condition, gpointer data) } static void +transport_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + if (g_strcmp0 (method_name, "Acquire") == 0) { + gint fd; + GUnixFDList *fdlist; + + fd = transport_acquire ("FC:F8:AE:4A:3F:D4", "13:11:14:AA:00:B8"); + + g_print ("got fd %d\n", fd); + + fdlist = g_unix_fd_list_new (); + g_unix_fd_list_append (fdlist, fd, NULL); + fdlist= NULL; + + g_dbus_method_invocation_return_value_with_unix_fd_list ( + invocation, g_variant_new ("(hqq)", (gint32) 0, (guint16) 48, (guint16) 48), fdlist); + + //g_print ("%s\n", g_dbus_message_print ( + + } else if (g_strcmp0 (method_name, "TryAcquire") == 0) { + g_dbus_method_invocation_return_value (invocation, NULL); + + } else if (g_strcmp0 (method_name, "Release") == 0) { + g_dbus_method_invocation_return_value (invocation, NULL); + } +} + +static const GDBusInterfaceVTable transport_interface_vtable = +{ + transport_method_call, + NULL, + NULL +}; + +static void profile_method_call (GDBusConnection *connection, - const gchar *sender, - const gchar *object_path, - const gchar *interface_name, - const gchar *method_name, - GVariant *parameters, - GDBusMethodInvocation *invocation, - gpointer user_data) + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) { if (g_strcmp0 (method_name, "Release") == 0) { @@ -222,15 +280,19 @@ profile_method_call (GDBusConnection *connection, } else if (g_strcmp0 (method_name, "RequestDisconnection") == 0) { g_print ("RequestDisconnection\n"); } else if (g_strcmp0 (method_name, "NewConnection") == 0) { - gint fd; + gint32 fd; gchar *obj; GDBusMessage *message; GUnixFDList * fdlist; GIOChannel *channel; + GVariantIter *props_i; + GVariant *value; gsize written; + gchar *key, *transport_name; + guint registration_id; g_variant_get (parameters, "(oha{sv})", - &obj, &fd, NULL); + &obj, &fd, &props_i); message = g_dbus_method_invocation_get_message (invocation); fdlist = g_dbus_message_get_unix_fd_list (message); @@ -238,6 +300,93 @@ profile_method_call (GDBusConnection *connection, g_print ("NewConnection %s %d\n", obj, fd); + /* make a new transport object to handle the setup of the SCO connection */ + transport_name = g_strdup_printf ("%s/fd%d", obj, fd); + + registration_id = g_dbus_connection_register_object (connection, + transport_name, + introspection_data->interfaces[1], + &transport_interface_vtable, + NULL, + NULL, /* user_data_free_func */ + NULL); /* GError** */ + g_assert (registration_id > 0); + + /* now go over all registered endpoints and inform them about the + * new transport object */ + while (g_variant_iter_next (props_i, "{&sv}", &key, &value)) { + g_print (" prop: %s\n", key); + + if (g_str_equal (key, "MediaEndpoints")) { + GVariantIter *endpoints_i; + gchar *owner; + GVariant *oprops; + + g_variant_get (value, "a{sv}", &endpoints_i); + + while (g_variant_iter_next (endpoints_i, "{&sv}", &owner, &oprops)) { + GVariantIter *oprops_i; + gchar *pname; + const gchar *spath; + GVariant *pval; + + g_print (" owner: %s\n", owner); + + g_variant_get (oprops, "a{sv}", &oprops_i); + + while (g_variant_iter_next (oprops_i, "{&sv}", &pname, &pval)) { + if (g_variant_is_of_type (pval, G_VARIANT_TYPE_OBJECT_PATH)) { + spath = g_variant_get_string (pval, NULL); + g_print (" key: %s object-path=%s\n", pname, spath); + } else if (g_variant_is_of_type (pval, G_VARIANT_TYPE_BYTE)) { + g_print (" key: %s byte=%c\n", pname, g_variant_get_byte (pval)); + } else if (g_variant_is_of_type (pval, G_VARIANT_TYPE_ARRAY)) { + g_print (" key: %s array\n", pname); + } else if (g_variant_is_of_type (pval, G_VARIANT_TYPE_STRING)) { + g_print (" key: %s string=%s\n", pname, g_variant_get_string (pval, NULL)); + } else { + g_print (" key: %s (%s)\n", pname, g_variant_get_type_string (pval)); + } + + g_variant_unref (pval); + } + + /* send transport to endpoint */ + { + GVariantBuilder *b; + GError *error = NULL; + + b = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (b, "{sv}", "UUID", g_variant_new_string ("0000111f-0000-1000-8000-00805f9b34fb")); + g_variant_builder_add (b, "{sv}", "Device", g_variant_new_object_path (obj)); + + g_dbus_connection_call_sync (connection, + owner, + spath, + "org.bluez.MediaEndpoint1", + "SetConfiguration", + g_variant_new ("(oa{sv})", + transport_name, + b), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (error) { + g_printerr ("error SetConfiguration %s\n", error->message); + } + } + + g_variant_iter_free (oprops_i); + g_variant_unref (oprops); + } + g_variant_iter_free (endpoints_i); + } + g_variant_unref (value); + } + g_variant_iter_free (props_i); + channel = g_io_channel_unix_new (fd); g_io_add_watch (channel, G_IO_IN, rfcomm_io_cb, NULL); |