summaryrefslogtreecommitdiff
path: root/src/hsd-headset.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/hsd-headset.c')
-rw-r--r--src/hsd-headset.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/src/hsd-headset.c b/src/hsd-headset.c
index dcea642..1ed514d 100644
--- a/src/hsd-headset.c
+++ b/src/hsd-headset.c
@@ -110,6 +110,36 @@ headset_set_state (HsdHeadset *h,
}
}
+static void
+headset_do_disconnect (HsdHeadset *h)
+{
+ if (h->fd != -1) {
+ shutdown (h->fd, SHUT_RDWR);
+ close (h->fd);
+ h->fd = -1;
+ }
+
+ if (h->owner) {
+ g_free (h->owner);
+ h->owner = NULL;
+ g_bus_unwatch_name (h->owner_watch);
+ h->owner_watch = 0;
+ }
+ headset_set_state (h, HSD_HEADSET_STATE_IDLE);
+}
+
+
+static void
+headset_owner_vanished (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ HsdHeadset *h = user_data;
+
+ g_warning ("SCO connection owner vanished");
+ headset_do_disconnect (h);
+}
+
static gboolean
headset_connect_cb (GIOChannel *io, GIOCondition cond, gpointer user_data)
{
@@ -142,11 +172,7 @@ headset_connect_cb (GIOChannel *io, GIOCondition cond, gpointer user_data)
connect_failed:
{
- close (h->fd);
- h->fd = -1;
- g_free (h->owner);
- h->owner = NULL;
- headset_set_state (h, HSD_HEADSET_STATE_IDLE);
+ headset_do_disconnect (h);
g_dbus_method_invocation_return_dbus_error (invocation,
HSD_HEADSET_INTERFACE ".Error.Failed", "failed to connect");
return FALSE;
@@ -180,6 +206,7 @@ headset_connect (HsdHeadset *h,
if (h->state != HSD_HEADSET_STATE_IDLE)
goto not_idle;
+
src_addr = h->adapter_addr;
dst_addr = h->device_addr;
@@ -224,6 +251,13 @@ headset_connect (HsdHeadset *h,
headset_set_state (h, HSD_HEADSET_STATE_PENDING);
h->owner = g_strdup (sender);
h->invocation = invocation;
+ /* we need to make sure the owner stays alive */
+ h->owner_watch = g_bus_watch_name_on_connection (connection,
+ sender,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ NULL,
+ headset_owner_vanished,
+ h, NULL);
io = g_io_channel_unix_new(h->fd);
g_io_add_watch(io, G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
@@ -282,14 +316,7 @@ headset_disconnect (HsdHeadset *h,
if (h->owner != NULL && strcmp (h->owner, sender))
goto not_owner;
- if (h->fd != -1) {
- shutdown (h->fd, SHUT_RDWR);
- close (h->fd);
- }
- h->fd = -1;
-
- h->owner = NULL;
- headset_set_state (h, HSD_HEADSET_STATE_IDLE);
+ headset_do_disconnect (h);
g_dbus_method_invocation_return_value (invocation, NULL);
@@ -499,13 +526,13 @@ hsd_headset_free (HsdHeadset *headset)
{
GDBusConnection *conn = hsd_dbus_connection_get ();
+ headset_do_disconnect (headset);
if (headset->id)
g_dbus_connection_unregister_object (conn, headset->id);
g_free (headset->device);
g_free (headset->device_addr);
g_free (headset->adapter);
g_free (headset->adapter_addr);
- g_free (headset->owner);
g_io_channel_unref (headset->rfcomm);
g_free (headset);
}