summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2014-08-04 23:20:37 +0200
committerWim Taymans <wtaymans@redhat.com>2014-08-04 23:20:37 +0200
commit021f1283950cae691d2c0506da162b09e6815b29 (patch)
treef117ea0162a755c9f71fd9417fcdecb1bbbff970
parentd2f1fd297f35473207ceff3b09c3951568291d1a (diff)
handle release and addresses
-rw-r--r--make-hsp-ag.c149
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);