diff options
author | Wim Taymans <wtaymans@redhat.com> | 2014-08-04 21:05:29 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2014-08-04 21:05:29 +0200 |
commit | d2f1fd297f35473207ceff3b09c3951568291d1a (patch) | |
tree | cabcefd6fbc46b251f9c391602eca627cb133795 | |
parent | 2841a3e0963eb8a544e389f02cb5e3f24f2db843 (diff) |
implement external profile
-rw-r--r-- | make-hsp-ag.c | 687 |
1 files changed, 436 insertions, 251 deletions
diff --git a/make-hsp-ag.c b/make-hsp-ag.c index 59ac50b..0d963b8 100644 --- a/make-hsp-ag.c +++ b/make-hsp-ag.c @@ -28,6 +28,8 @@ #include <bluetooth/sco.h> +#define HFP_AG_UUID "0000111f-0000-1000-8000-00805f9b34fb" + /* ---------------------------------------------------------------------------------------------------- */ static GDBusNodeInfo *introspection_data = NULL; @@ -62,117 +64,130 @@ static const gchar introspection_xml[] = " <arg name='mtu_r' direction='out' type='q'/>" " <arg name='mtu_w' direction='out' type='q'/>" " </method>" + " <property type='s' name='State' access='read'/>" " </interface>" "</node>"; -static struct sco_options so; +typedef struct { + GDBusConnection *conn; + GDBusProxy *manager; -#if 0 -static gboolean -sco_io_cb (GIOChannel *source, GIOCondition condition, gpointer data) -{ - gchar buf[1024]; - gsize length; - gint fd = g_io_channel_unix_get_fd (source); + gchar *uuid; + gchar *name; + guint id; - if (condition & G_IO_IN) { - length = recv (fd, buf, 1024, 0); - if (length <= 0) - perror ("recv()"); - g_print ("-"); - } else if (condition & G_IO_OUT) { - gint i; - - for (i = 0; i < 48; i++) - buf[i] = g_random_int_range (0, 255); - - length = send (fd, buf, 48, 0); - if (length != 48) - perror ("send()"); - - g_print ("+"); - usleep(2500); - } else if (condition & (G_IO_ERR | G_IO_HUP)) { - g_print ("got error\n"); - return FALSE; - } - return TRUE; -} -#endif + GHashTable *objs; +} Profile; -static int -transport_acquire (gchar *src_addr, gchar *dst_addr) -{ - struct sockaddr_sco addr; - int err, i; - int sock; - GIOCondition cond; - GIOChannel *io; - bdaddr_t src; - bdaddr_t dst; - int voice = 0x60; - socklen_t len; +typedef struct { + Profile *profile; - for (i = 5; i >= 0; i--, src_addr += 3) - src.b[i] = strtol(src_addr, NULL, 16); - for (i = 5; i >= 0; i--, dst_addr += 3) - dst.b[i] = strtol(dst_addr, NULL, 16); + gchar *obj; + gint fd; + guint id; + gchar *state; - sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO); - if (sock < 0) { - g_printerr("socket(SEQPACKET, SCO)"); - return -1; - } + GVariantIter *props; + gchar *name; - memset(&addr, 0, sizeof(addr)); - addr.sco_family = AF_BLUETOOTH; - bacpy(&addr.sco_bdaddr, &src); + GIOChannel *channel; +} MediaTransport; - if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - perror("bind()"); - return -1; - } +static void send_set_configuration_reply (GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + GError *error = NULL; + GDBusConnection *connection = G_DBUS_CONNECTION (source_object); - if (voice) { - struct bt_voice opts; + g_dbus_connection_call_finish (connection, res, &error); - /* SCO voice setting */ - memset(&opts, 0, sizeof(opts)); - opts.setting = voice; - if (setsockopt(sock, SOL_BLUETOOTH, BT_VOICE, &opts, sizeof(opts)) < 0) { - perror("setsockopt()"); - return -1; - } + if (error) { + g_printerr ("error doing SetConfiguration %s", error->message); + g_clear_error (&error); } +} - memset(&addr, 0, sizeof(addr)); - addr.sco_family = AF_BLUETOOTH; - bacpy(&addr.sco_bdaddr, &dst); +static void send_set_configuration (MediaTransport *t, const gchar *owner, const gchar *spath) +{ + /* send transport to endpoint */ + GVariantBuilder *b; + GError *error = NULL; - g_printerr ("doing connect\n"); - err = connect(sock, (struct sockaddr *) &addr, sizeof(addr)); - if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) { - perror("connect()"); - return -1; - } + 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 (t->obj)); + + g_dbus_connection_call (t->profile->conn, + owner, + spath, + "org.bluez.MediaEndpoint1", + "SetConfiguration", + g_variant_new ("(oa{sv})", + t->name, + b), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + send_set_configuration_reply, + t); +} - len = sizeof(so); - if (getsockopt(sock, SOL_SCO, SCO_OPTIONS, &so, &len) < 0) { - perror("getsockopt()"); - return -1; - } +static void +media_transport_configure_endpoint (MediaTransport *t) +{ + GVariantIter *props_i = t->props; + GVariant *value; + gchar *key; + + /* 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_print ("connected: MTU %d\n", so.mtu); + g_variant_unref (pval); + } - /* - 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); + send_set_configuration (t, owner, spath); - 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 sock; + 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); } static gboolean @@ -180,6 +195,7 @@ rfcomm_io_cb (GIOChannel *source, GIOCondition condition, gpointer data) { gchar buf[512]; GIOStatus st; + MediaTransport *t = data; g_print ("condition %d\n", condition); @@ -212,6 +228,7 @@ 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); + media_transport_configure_endpoint (t); } else { write (fd, "\r\nOK\r\n", 5); @@ -221,6 +238,137 @@ rfcomm_io_cb (GIOChannel *source, GIOCondition condition, gpointer data) } static void +transport_set_state (MediaTransport *t, const gchar *state) +{ + GVariantBuilder *builder; + GVariantBuilder *invalidated_builder; + GError *error; + + error = NULL; + builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY); + invalidated_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); + g_variant_builder_add (builder, + "{sv}", + "State", + g_variant_new_string (state)); + g_dbus_connection_emit_signal (t->profile->conn, + NULL, + t->name, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + g_variant_new ("(sa{sv}as)", + "org.bluez.MediaTransport1", + builder, + invalidated_builder), + &error); + g_assert_no_error (error); +} + +static void +transport_acquire (MediaTransport *t, + gboolean optional, + GDBusConnection *connection, + GVariant *parameters, + GDBusMethodInvocation *invocation) +{ + GUnixFDList *fdlist; + GDBusMessage *reply; + GError *error; + guchar *blob; + gsize out_size; + struct sockaddr_sco addr; + int err, i; + GIOCondition cond; + GIOChannel *io; + bdaddr_t src; + bdaddr_t dst; + int voice = 0x60; + socklen_t len; + gchar *src_addr; + gchar *dst_addr; + + src_addr = "FC:F8:AE:4A:3F:D4"; + dst_addr = "13:11:14:AA:00:B8"; + + for (i = 5; i >= 0; i--, src_addr += 3) + src.b[i] = strtol(src_addr, NULL, 16); + for (i = 5; i >= 0; i--, dst_addr += 3) + dst.b[i] = strtol(dst_addr, NULL, 16); + + t->fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO); + if (t->fd < 0) { + g_printerr("socket(SEQPACKET, SCO)"); + return; + } + + g_print ("got fd %d\n", t->fd); + transport_set_state (t, "pending"); + + fdlist = g_unix_fd_list_new (); + g_unix_fd_list_append (fdlist, t->fd, NULL); + g_dbus_method_invocation_return_value_with_unix_fd_list ( + invocation, g_variant_new ("(hqq)", 0, 48, 48), fdlist); + + + memset(&addr, 0, sizeof(addr)); + addr.sco_family = AF_BLUETOOTH; + bacpy(&addr.sco_bdaddr, &src); + + if (bind(t->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("bind()"); + return; + } + + if (voice) { + struct bt_voice opts; + + /* SCO voice setting */ + memset(&opts, 0, sizeof(opts)); + opts.setting = voice; + if (setsockopt(t->fd, SOL_BLUETOOTH, BT_VOICE, &opts, sizeof(opts)) < 0) { + perror("setsockopt()"); + return; + } + } + + memset(&addr, 0, sizeof(addr)); + addr.sco_family = AF_BLUETOOTH; + bacpy(&addr.sco_bdaddr, &dst); + + g_printerr ("doing connect\n"); + err = connect(t->fd, (struct sockaddr *) &addr, sizeof(addr)); + if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) { + perror("connect()"); + return; + } + + g_printerr ("connected\n"); + t->state = "active"; + + transport_set_state (t, "active"); +} + +static void +transport_release (MediaTransport *t, + GDBusConnection *connection, + GVariant *parameters, + GDBusMethodInvocation *invocation) +{ + + g_print ("close fd %d\n", t->fd); + + if (t->fd != -1) { + shutdown (t->fd, SHUT_RDWR); + close (t->fd); + } + t->fd = -1; + + g_dbus_method_invocation_return_value (invocation, NULL); + + transport_set_state (t, "idle"); +} + +static void transport_method_call (GDBusConnection *connection, const gchar *sender, const gchar *object_path, @@ -230,69 +378,105 @@ transport_method_call (GDBusConnection *connection, 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 ( + MediaTransport *t = user_data; + if (g_strcmp0 (method_name, "Acquire") == 0) { + transport_acquire (t, TRUE, connection, parameters, invocation); } else if (g_strcmp0 (method_name, "TryAcquire") == 0) { - g_dbus_method_invocation_return_value (invocation, NULL); - + transport_acquire (t, FALSE, connection, parameters, invocation); } else if (g_strcmp0 (method_name, "Release") == 0) { - g_dbus_method_invocation_return_value (invocation, NULL); + transport_release (t, connection, parameters, invocation); + } +} + +static GVariant * +transport_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, + gpointer user_data) +{ + MediaTransport *t = user_data; + GVariant *ret; + + ret = NULL; + if (g_strcmp0 (property_name, "State") == 0) { + ret = g_variant_new_string (t->state); } + return ret; } static const GDBusInterfaceVTable transport_interface_vtable = { transport_method_call, - NULL, + transport_get_property, 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) +static MediaTransport * +media_transport_free (MediaTransport *t) { + if (t->id) + g_dbus_connection_unregister_object (t->profile->conn, t->id); + if (t->channel) + g_io_channel_unref (t->channel); + g_free (t->obj); + g_free (t); +} - if (g_strcmp0 (method_name, "Release") == 0) { - g_print ("Release\n"); - } else if (g_strcmp0 (method_name, "Cancel") == 0) { - g_print ("Cancel\n"); - } else if (g_strcmp0 (method_name, "RequestDisconnection") == 0) { - g_print ("RequestDisconnection\n"); - } else if (g_strcmp0 (method_name, "NewConnection") == 0) { - gint32 fd; +static MediaTransport * +media_transport_new (Profile *p, const gchar *obj, gint fd, GVariantIter *props) +{ + MediaTransport *t; + GError *error = NULL; + + t = g_new0 (MediaTransport, 1); + t->profile = p; + t->obj = g_strdup (obj); + t->fd = fd; + t->props = props; + t->state = "idle"; + + /* make a new transport object to handle the setup of the SCO connection */ + t->name = g_strdup_printf ("%s/fd%d", obj, fd); + t->id = g_dbus_connection_register_object (p->conn, + t->name, + introspection_data->interfaces[1], + &transport_interface_vtable, + t, + (GDestroyNotify) media_transport_free, /* user_data_free_func */ + &error); /* GError** */ + if (t->id == 0) { + g_printerr ("error registering object %s\n", error->message); + media_transport_free (t); + return NULL; + } + + t->channel = g_io_channel_unix_new (fd); + g_io_channel_set_close_on_unref (t->channel, TRUE); + g_io_add_watch (t->channel, G_IO_IN, rfcomm_io_cb, t); + + g_hash_table_insert (p->objs, (gpointer) obj, t); + + return t; +} + +static void +profile_new_connection (Profile *p, + GDBusConnection *connection, + GVariant *parameters, + GDBusMethodInvocation *invocation) +{ gchar *obj; + gint32 fd; + GVariantIter *props; GDBusMessage *message; GUnixFDList * fdlist; - GIOChannel *channel; - GVariantIter *props_i; - GVariant *value; - gsize written; - gchar *key, *transport_name; - guint registration_id; + MediaTransport *t; - g_variant_get (parameters, "(oha{sv})", - &obj, &fd, &props_i); + g_variant_get (parameters, "(oha{sv})", &obj, &fd, &props); message = g_dbus_method_invocation_get_message (invocation); fdlist = g_dbus_message_get_unix_fd_list (message); @@ -300,100 +484,77 @@ profile_method_call (GDBusConnection *connection, g_print ("NewConnection %s %d\n", obj, fd); + g_dbus_method_invocation_return_value (invocation, NULL); + /* 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); - } + t = media_transport_new (p, obj, fd, props); +} - /* 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); - } - } +static void +profile_request_disconnection (Profile *p, + GDBusConnection *connection, + GVariant *parameters, + GDBusMethodInvocation *invocation) +{ + gchar *obj; + MediaTransport *t; - g_variant_iter_free (oprops_i); - g_variant_unref (oprops); - } - g_variant_iter_free (endpoints_i); - } - g_variant_unref (value); + g_variant_get (parameters, "(o)", &obj); + + t = g_hash_table_lookup (p->objs, obj); + if (t == NULL) { + g_warning ("unknown transport object %s", obj); + goto done; } - 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); + g_hash_table_remove (p->objs, obj); + + media_transport_free (t); + +done: + g_dbus_method_invocation_return_value (invocation, NULL); +} + +static void +profile_release (Profile *p, + GDBusConnection *connection, + GVariant *parameters, + GDBusMethodInvocation *invocation) +{ + g_dbus_method_invocation_return_value (invocation, NULL); +} + +static void +profile_cancel (Profile *p, + GDBusConnection *connection, + GVariant *parameters, + GDBusMethodInvocation *invocation) +{ + g_dbus_method_invocation_return_value (invocation, 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) +{ + Profile *p = user_data; + if (g_strcmp0 (method_name, "Release") == 0) { + profile_release (p, connection, parameters, invocation); + } else if (g_strcmp0 (method_name, "Cancel") == 0) { + profile_cancel (p, connection, parameters, invocation); + } else if (g_strcmp0 (method_name, "RequestDisconnection") == 0) { + profile_request_disconnection (p, connection, parameters, invocation); + } else if (g_strcmp0 (method_name, "NewConnection") == 0) { + profile_new_connection (p, connection, parameters, invocation); } else g_print ("Unhandled %s\n", method_name); - - g_dbus_method_invocation_return_value (invocation, NULL); } static const GDBusInterfaceVTable profile_interface_vtable = @@ -403,50 +564,63 @@ static const GDBusInterfaceVTable profile_interface_vtable = NULL }; +static void profile_free (Profile *p) +{ + if (p->id) + g_dbus_connection_unregister_object (p->conn, p->id); + g_free (p->uuid); + g_free (p->name); + g_hash_table_unref (p->objs); + g_free (p); +} -static int -register_profile (GDBusConnection *connection) +static Profile * +register_profile (GDBusConnection *connection, GDBusProxy * manager, const gchar *uuid) { GError *error = NULL; - GDBusProxy *manager; guint registration_id; - - g_print ("making proxy for ProfileManager1\n"); - manager = g_dbus_proxy_new_sync (connection, - G_DBUS_PROXY_FLAGS_NONE, - NULL, "org.bluez", "/org/bluez", "org.bluez.ProfileManager1", - NULL, &error); - if (error != NULL) { - g_printerr ("error getting ProfileManager1: %s", error->message); - return -1; + Profile *profile; + GVariant *res; + + profile = g_new0 (Profile, 1); + profile->conn = connection; + profile->manager = manager; + profile->name = g_strdup_printf ("/org/test/Profile"); + profile->uuid = g_strdup (uuid); + profile->objs = g_hash_table_new (g_str_hash, g_str_equal); + + profile->id = g_dbus_connection_register_object (connection, + profile->name, + introspection_data->interfaces[0], + &profile_interface_vtable, + profile, + (GDestroyNotify) profile_free, /* user_data_free_func */ + &error); /* GError** */ + if (profile->id == 0) { + g_printerr ("error registering object %s\n", error->message); + profile_free (profile); + return NULL; } - registration_id = g_dbus_connection_register_object (connection, - "/org/test/Profile", - introspection_data->interfaces[0], - &profile_interface_vtable, - NULL, - NULL, /* user_data_free_func */ - NULL); /* GError** */ - g_assert (registration_id > 0); - g_print ("Register profile\n"); - g_dbus_proxy_call_sync (manager, + res = g_dbus_proxy_call_sync (manager, "RegisterProfile", g_variant_new ("(osa{sv})", - "/org/test/Profile", - "0000111f-0000-1000-8000-00805f9b34fb", NULL), + profile->name, + uuid, NULL), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); - if (error) { + if (res == NULL) { g_printerr ("error registering %s\n", error->message); - return -1; + profile_free (profile); + return NULL; } g_print ("Profile registered\n"); + g_variant_unref (res); - return 0; + return profile; } int @@ -456,6 +630,7 @@ main (int argc, char *argv[]) GError *error = NULL; GMainLoop *loop; guint registration_id; + GDBusProxy *manager; g_print ("connecting to system bus\n"); connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); @@ -467,7 +642,17 @@ main (int argc, char *argv[]) introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); g_assert (introspection_data != NULL); - if (register_profile (connection) < 0) + g_print ("making proxy for ProfileManager1\n"); + manager = g_dbus_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + NULL, "org.bluez", "/org/bluez", "org.bluez.ProfileManager1", + NULL, &error); + if (error != NULL) { + g_printerr ("error getting ProfileManager1: %s", error->message); + return -1; + } + + if (register_profile (connection, manager, HFP_AG_UUID) == NULL) return -1; g_print ("going into mainloop\n"); |