diff options
Diffstat (limited to 'src/hsd-headset.c')
-rw-r--r-- | src/hsd-headset.c | 55 |
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); } |