diff options
author | Wim Taymans <wtaymans@redhat.com> | 2014-08-04 23:20:37 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2014-08-04 23:20:37 +0200 |
commit | 021f1283950cae691d2c0506da162b09e6815b29 (patch) | |
tree | f117ea0162a755c9f71fd9417fcdecb1bbbff970 | |
parent | d2f1fd297f35473207ceff3b09c3951568291d1a (diff) |
handle release and addresses
-rw-r--r-- | make-hsp-ag.c | 149 |
1 files changed, 134 insertions, 15 deletions
diff --git a/make-hsp-ag.c b/make-hsp-ag.c index 0d963b8..7f01b72 100644 --- a/make-hsp-ag.c +++ b/make-hsp-ag.c @@ -87,6 +87,12 @@ typedef struct { guint id; gchar *state; + gchar *owner; + gchar *spath; + + gchar *src_addr; + gchar *dst_addr; + GVariantIter *props; gchar *name; @@ -101,24 +107,23 @@ static void send_set_configuration_reply (GObject *source_object, GAsyncResult * g_dbus_connection_call_finish (connection, res, &error); if (error) { - g_printerr ("error doing SetConfiguration %s", error->message); + g_printerr ("error doing SetConfiguration %s\n", error->message); g_clear_error (&error); } } -static void send_set_configuration (MediaTransport *t, const gchar *owner, const gchar *spath) +static void send_set_configuration (MediaTransport *t) { /* 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 (t->obj)); g_dbus_connection_call (t->profile->conn, - owner, - spath, + t->owner, + t->spath, "org.bluez.MediaEndpoint1", "SetConfiguration", g_variant_new ("(oa{sv})", @@ -132,6 +137,37 @@ static void send_set_configuration (MediaTransport *t, const gchar *owner, const t); } +static void send_clear_configuration_reply (GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + GError *error = NULL; + GDBusConnection *connection = G_DBUS_CONNECTION (source_object); + + g_dbus_connection_call_finish (connection, res, &error); + + if (error) { + g_printerr ("error doing ClearConfiguration %s\n", error->message); + g_clear_error (&error); + } +} + +static void send_clear_configuration (MediaTransport *t) +{ + /* send transport to endpoint */ + g_dbus_connection_call (t->profile->conn, + t->owner, + t->spath, + "org.bluez.MediaEndpoint1", + "ClearConfiguration", + g_variant_new ("(o)", + t->name), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + send_clear_configuration_reply, + t); +} + static void media_transport_configure_endpoint (MediaTransport *t) { @@ -151,7 +187,7 @@ media_transport_configure_endpoint (MediaTransport *t) g_variant_get (value, "a{sv}", &endpoints_i); - while (g_variant_iter_next (endpoints_i, "{&sv}", &owner, &oprops)) { + while (g_variant_iter_next (endpoints_i, "{sv}", &owner, &oprops)) { GVariantIter *oprops_i; gchar *pname; const gchar *spath; @@ -163,7 +199,7 @@ media_transport_configure_endpoint (MediaTransport *t) 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); + t->spath = g_variant_dup_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)); @@ -178,7 +214,9 @@ media_transport_configure_endpoint (MediaTransport *t) g_variant_unref (pval); } - send_set_configuration (t, owner, spath); + t->owner = owner; + + send_set_configuration (t); g_variant_iter_free (oprops_i); g_variant_unref (oprops); @@ -199,6 +237,9 @@ rfcomm_io_cb (GIOChannel *source, GIOCondition condition, gpointer data) g_print ("condition %d\n", condition); + if (condition & (G_IO_ERR | G_IO_HUP)) + return FALSE; + if (condition & G_IO_IN) { gint fd = g_io_channel_unix_get_fd (source); gsize length; @@ -287,8 +328,8 @@ transport_acquire (MediaTransport *t, gchar *src_addr; gchar *dst_addr; - src_addr = "FC:F8:AE:4A:3F:D4"; - dst_addr = "13:11:14:AA:00:B8"; + src_addr = t->src_addr; + dst_addr = t->dst_addr; for (i = 5; i >= 0; i--, src_addr += 3) src.b[i] = strtol(src_addr, NULL, 16); @@ -343,7 +384,6 @@ transport_acquire (MediaTransport *t, } g_printerr ("connected\n"); - t->state = "active"; transport_set_state (t, "active"); } @@ -418,10 +458,18 @@ static const GDBusInterfaceVTable transport_interface_vtable = static MediaTransport * media_transport_free (MediaTransport *t) { + g_print ("media transport free %p\n", t); + + send_clear_configuration (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->owner); + g_free (t->spath); + g_free (t->src_addr); + g_free (t->dst_addr); g_free (t->obj); g_free (t); } @@ -431,6 +479,8 @@ media_transport_new (Profile *p, const gchar *obj, gint fd, GVariantIter *props) { MediaTransport *t; GError *error = NULL; + GVariant *res, *var; + const gchar *adapter; t = g_new0 (MediaTransport, 1); t->profile = p; @@ -439,6 +489,8 @@ media_transport_new (Profile *p, const gchar *obj, gint fd, GVariantIter *props) t->props = props; t->state = "idle"; + g_print ("new media transport %p\n", t); + /* 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, @@ -446,7 +498,7 @@ media_transport_new (Profile *p, const gchar *obj, gint fd, GVariantIter *props) introspection_data->interfaces[1], &transport_interface_vtable, t, - (GDestroyNotify) media_transport_free, /* user_data_free_func */ + NULL, /* user_data_free_func */ &error); /* GError** */ if (t->id == 0) { g_printerr ("error registering object %s\n", error->message); @@ -454,9 +506,76 @@ media_transport_new (Profile *p, const gchar *obj, gint fd, GVariantIter *props) return NULL; } + res = g_dbus_connection_call_sync (p->conn, + "org.bluez", + obj, + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new ("(ss)", + "org.bluez.Device1", + "Address"), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (res == NULL) { + g_printerr ("Can't get Device Address", error->message); + return NULL; + } + g_variant_get (res, "(v)", &var); + t->dst_addr = g_variant_dup_string (var, NULL); + g_variant_unref (var); + g_print ("device addres %s\n", t->dst_addr); + + res = g_dbus_connection_call_sync (p->conn, + "org.bluez", + obj, + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new ("(ss)", + "org.bluez.Device1", + "Adapter"), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (res == NULL) { + g_printerr ("Can't get Adapter", error->message); + return NULL; + } + g_variant_get (res, "(v)", &var); + adapter = g_variant_get_string (var, NULL); + g_print ("device adapter %s\n", adapter); + + res = g_dbus_connection_call_sync (p->conn, + "org.bluez", + adapter, + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new ("(ss)", + "org.bluez.Adapter1", + "Address"), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_variant_unref (var); + + if (res == NULL) { + g_printerr ("Can't get Adapter Address", error->message); + return NULL; + } + g_variant_get (res, "(v)", &var); + t->src_addr = g_variant_dup_string (var, NULL); + g_variant_unref (var); + g_print ("adapter addres %s\n", t->src_addr); + 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_io_add_watch (t->channel, G_IO_IN | G_IO_ERR | G_IO_HUP, rfcomm_io_cb, t); g_hash_table_insert (p->objs, (gpointer) obj, t); @@ -500,6 +619,7 @@ profile_request_disconnection (Profile *p, MediaTransport *t; g_variant_get (parameters, "(o)", &obj); + g_print ("RequestDisconnection %s\n", obj); t = g_hash_table_lookup (p->objs, obj); if (t == NULL) { @@ -508,7 +628,6 @@ profile_request_disconnection (Profile *p, } g_hash_table_remove (p->objs, obj); - media_transport_free (t); done: @@ -594,7 +713,7 @@ register_profile (GDBusConnection *connection, GDBusProxy * manager, const gchar introspection_data->interfaces[0], &profile_interface_vtable, profile, - (GDestroyNotify) profile_free, /* user_data_free_func */ + NULL, /* user_data_free_func */ &error); /* GError** */ if (profile->id == 0) { g_printerr ("error registering object %s\n", error->message); |