summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2014-08-07 10:51:54 +0200
committerWim Taymans <wtaymans@redhat.com>2014-08-07 10:51:54 +0200
commitc0885c29f573a552605387c1d0e760ddd6311ed4 (patch)
tree7939a1873e1d0188a04db45bccfee98a79f4e239 /src
parent4ca6de134ead2aaa2280429df0ced0681c9ca523 (diff)
remove transport
Move transport into headset
Diffstat (limited to 'src')
-rw-r--r--src/hsd-headset-transport.c339
-rw-r--r--src/hsd-headset-transport.h42
-rw-r--r--src/hsd-headset.c291
-rw-r--r--src/hsd-headset.h11
4 files changed, 245 insertions, 438 deletions
diff --git a/src/hsd-headset-transport.c b/src/hsd-headset-transport.c
deleted file mode 100644
index 05acf38..0000000
--- a/src/hsd-headset-transport.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Copyright (C) 2014 Wim Taymans <wim.taymans@gmail.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/sco.h>
-
-#include <gio/gio.h>
-#include <gio/gunixfdlist.h>
-
-#include "hsd.h"
-#include "hsd-headset.h"
-#include "hsd-headset-transport.h"
-
-static GDBusNodeInfo *introspection_data = NULL;
-
-/* Introspection data for the service we are exporting */
-static const gchar introspection_xml[] =
- "<node>"
- " <interface name='org.freedesktop.HeadsetTransport'>"
- " <method name='Acquire'>"
- " <arg type='h' name='fd' direction='out'/>"
- " <arg type='q' name='mtu_r' direction='out'/>"
- " <arg type='q' name='mtu_w' direction='out'/>"
- " </method>"
- " <method name='Release'>"
- " </method>"
- " </interface>"
- "</node>";
-
-static GDBusInterfaceInfo *
-get_headset_transport_interface_info (void)
-{
- static GDBusNodeInfo *introspection_data = NULL;
-
- if (introspection_data == NULL)
- introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
-
- return introspection_data->interfaces[0];
-}
-
-static void
-headset_transport_set_state (HsdHeadsetTransport *t,
- HsdTransportState state)
-{
- if (t->state == state)
- return;
-
- t->state = state;
-}
-
-static gboolean
-transport_connect_cb (GIOChannel *io, GIOCondition cond, gpointer user_data)
-{
- HsdHeadsetTransport *t = user_data;
- GUnixFDList *fdlist;
- gint sock;
- GDBusMethodInvocation *invocation;
-
- invocation = t->invocation;
- t->invocation = NULL;
-
- if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
- goto connect_failed;
-
- headset_transport_set_state (t, HSD_TRANSPORT_STATE_ACTIVE);
-
- g_debug ("connected");
- 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);
-
- return FALSE;
-
-connect_failed:
- {
- close (t->fd);
- t->fd = -1;
- headset_transport_set_state (t, HSD_TRANSPORT_STATE_IDLE);
- g_dbus_method_invocation_return_dbus_error (invocation,
- "org.freedesktop.Headset.Error.Failed", "failed to connect");
- return FALSE;
- }
-}
-
-static void
-headset_transport_acquire (HsdHeadsetTransport *t,
- GDBusConnection *connection,
- GVariant *parameters,
- GDBusMethodInvocation *invocation)
-{
- 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;
-
- g_message ("transport Acquire");
-
- if (t->state != HSD_TRANSPORT_STATE_IDLE)
- goto not_idle;
-
- src_addr = t->headset->adapter_addr;
- dst_addr = t->headset->device_addr;
-
- 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 | SOCK_NONBLOCK | SOCK_CLOEXEC, BTPROTO_SCO);
- if (t->fd < 0)
- goto socket_failed;
-
- g_debug ("got fd %d", t->fd);
-
- 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)
- goto bind_failed;
-
- 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)
- goto sockopt_failed;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sco_family = AF_BLUETOOTH;
- bacpy(&addr.sco_bdaddr, &dst);
-
- g_debug ("doing connect");
-
- err = connect(t->fd, (struct sockaddr *) &addr, sizeof(addr));
- if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS))
- goto connect_failed;
-
- headset_transport_set_state (t, HSD_TRANSPORT_STATE_PENDING);
-
- t->invocation = invocation;
-
- io = g_io_channel_unix_new(t->fd);
- g_io_add_watch(io, G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
- transport_connect_cb, t);
- g_io_channel_unref(io);
-
- return;
-
-not_idle:
- {
- g_dbus_method_invocation_return_dbus_error (invocation,
- "org.freedesktop.Headset.Error.Failed", "transport not idle");
- return;
- }
-socket_failed:
- {
- g_dbus_method_invocation_return_dbus_error (invocation,
- "org.freedesktop.Headset.Error.Failed", "failed to create socket");
- goto close_fd;
- }
-bind_failed:
- {
- g_dbus_method_invocation_return_dbus_error (invocation,
- "org.freedesktop.Headset.Error.Failed", "failed to bind socket");
- goto close_fd;
- }
-sockopt_failed:
- {
- g_dbus_method_invocation_return_dbus_error (invocation,
- "org.freedesktop.Headset.Error.Failed", "failed to setsockopt");
- goto close_fd;
- }
-connect_failed:
- {
- g_dbus_method_invocation_return_dbus_error (invocation,
- "org.freedesktop.Headset.Error.Failed", "failed to connect");
- goto close_fd;
- }
-close_fd:
- {
- close (t->fd);
- t->fd = -1;
- return;
- }
-}
-
-static void
-headset_transport_release (HsdHeadsetTransport *t,
- GDBusConnection *connection,
- GVariant *parameters,
- GDBusMethodInvocation *invocation)
-{
- g_message ("transport release");
-
- if (t->fd != -1) {
- shutdown (t->fd, SHUT_RDWR);
- close (t->fd);
- }
- t->fd = -1;
-
- g_dbus_method_invocation_return_value (invocation, NULL);
-
- headset_transport_set_state (t, HSD_TRANSPORT_STATE_IDLE);
-}
-
-static void
-headset_transport_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)
-{
- HsdHeadsetTransport *t = user_data;
-
- if (t->invocation)
- goto busy;
-
- if (strcmp (t->owner, sender) != 0)
- goto not_owner;
-
- if (g_strcmp0 (method_name, "Acquire") == 0) {
- headset_transport_acquire (t, connection, parameters, invocation);
- } else if (g_strcmp0 (method_name, "Release") == 0) {
- headset_transport_release (t, connection, parameters, invocation);
- } else
- g_dbus_method_invocation_return_dbus_error (invocation,
- "org.freedesktop.Headset.Error.NotImplemented", "no such method");
-
- return;
-
-busy:
- {
- g_dbus_method_invocation_return_dbus_error (invocation,
- "org.freedesktop.Headset.Error.Busy", "We have a pending operation");
- return;
- }
-not_owner:
- {
- g_dbus_method_invocation_return_dbus_error (invocation,
- "org.freedesktop.Headset.Error.NotAuthorized", "not the transport owner");
- return;
- }
-}
-
-static const GDBusInterfaceVTable headset_transport_interface_vtable =
-{
- headset_transport_method_call,
- NULL,
- NULL
-};
-
-HsdHeadsetTransport *
-hsd_headset_transport_new (HsdHeadset *headset, gchar *name, const gchar *owner, GVariantIter *props, GError **error)
-{
- GDBusConnection *conn = hsd_dbus_connection_get ();
- HsdHeadsetTransport *transport;
-
- transport = g_new0 (HsdHeadsetTransport, 1);
- transport->headset = headset;
- transport->name = name;
- transport->owner = g_strdup (owner);
- transport->state = HSD_TRANSPORT_STATE_IDLE;
- transport->fd = -1;
-
- /* FIXME, use props */
- if (props)
- g_variant_iter_free (props);
-
- /* FIXME, watch owner */
-
- g_debug ("Registering headset-transport object");
- transport->id = g_dbus_connection_register_object (conn,
- name,
- get_headset_transport_interface_info(),
- &headset_transport_interface_vtable,
- transport,
- NULL, /* user_data_free_func */
- error); /* GError** */
- if (transport->id == 0) {
- hsd_headset_transport_free (transport);
- return NULL;
- }
-
- return transport;
-}
-
-void
-hsd_headset_transport_free (HsdHeadsetTransport *transport)
-{
- GDBusConnection *conn = hsd_dbus_connection_get ();
-
- if (transport->id)
- g_dbus_connection_unregister_object (conn, transport->id);
- if (transport->fd != -1)
- close (transport->fd);
- g_free (transport->name);
- g_free (transport->owner);
- g_free (transport);
-}
-
diff --git a/src/hsd-headset-transport.h b/src/hsd-headset-transport.h
deleted file mode 100644
index 9eb131e..0000000
--- a/src/hsd-headset-transport.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2014 Wim Taymans <wim.taymans@gmail.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-typedef enum {
- HSD_TRANSPORT_STATE_IDLE,
- HSD_TRANSPORT_STATE_PENDING,
- HSD_TRANSPORT_STATE_ACTIVE,
-} HsdTransportState;
-
-struct _HsdHeadsetTransport {
- HsdHeadset *headset;
-
- gchar *name;
- gchar *owner;
-
- guint id;
-
- gint fd;
- HsdTransportState state;
- GDBusMethodInvocation *invocation;
-};
-
-HsdHeadsetTransport * hsd_headset_transport_new (HsdHeadset *headset, gchar *name,
- const gchar *owner, GVariantIter *props,
- GError **error);
-void hsd_headset_transport_free (HsdHeadsetTransport *transport);
diff --git a/src/hsd-headset.c b/src/hsd-headset.c
index 1af096c..3011272 100644
--- a/src/hsd-headset.c
+++ b/src/hsd-headset.c
@@ -17,11 +17,18 @@
* Boston, MA 02110-1301, USA.
*/
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/sco.h>
+
#include <gio/gio.h>
+#include <gio/gunixfdlist.h>
#include "hsd.h"
#include "hsd-headset.h"
-#include "hsd-headset-transport.h"
static guint count = 0;
@@ -31,14 +38,14 @@ static GDBusNodeInfo *introspection_data = NULL;
static const gchar introspection_xml[] =
"<node>"
" <interface name='org.freedesktop.Headset'>"
- " <method name='GetTransport'>"
+ " <method name='Connect'>"
" <arg type='a{sv}' name='properties' direction='in'/>"
- " <arg type='o' name='transport' direction='out'/>"
+ " <arg type='a{sv}' name='results' direction='out'/>"
" </method>"
- " <method name='ReleaseTransport'>"
- " <arg type='o' name='transport' direction='in'/>"
+ " <method name='Disconnect'>"
" </method>"
" <property type='o' name='Device' access='read'/>"
+ " <property type='s' name='State' access='read'/>"
" </interface>"
"</node>";
@@ -53,81 +60,220 @@ get_headset_interface_info (void)
return introspection_data->interfaces[0];
}
+static const gchar *
+headset_state_to_string (HsdHeadsetState state)
+{
+ switch (state) {
+ case HSD_HEADSET_STATE_IDLE:
+ return "idle";
+ case HSD_HEADSET_STATE_PENDING:
+ return "pending";
+ case HSD_HEADSET_STATE_ACTIVE:
+ return "active";
+ default:
+ return "invalid";
+ }
+}
+
static void
-headset_get_transport (HsdHeadset *h,
- GDBusConnection *connection,
- const gchar *sender,
- GVariant *parameters,
- GDBusMethodInvocation *invocation)
+headset_set_state (HsdHeadset *h,
+ HsdHeadsetState state)
{
- GVariantIter *props;
- HsdHeadsetTransport *t;
- GError *error = NULL;
- gchar *tname;
+ if (h->state == state)
+ return;
+
+ h->state = state;
+}
- g_debug ("headset GetTransport");
+static gboolean
+headset_connect_cb (GIOChannel *io, GIOCondition cond, gpointer user_data)
+{
+ HsdHeadset *h = user_data;
+ GUnixFDList *fdlist;
+ gint sock;
+ GDBusMethodInvocation *invocation;
+ GVariantBuilder *b;
- g_variant_get (parameters, "(a{sv})", &props);
+ invocation = h->invocation;
+ h->invocation = NULL;
- /* FIXME, watch owner */
+ if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
+ goto connect_failed;
- tname = g_strdup_printf ("%s/fd%d", h->device, count++);
- t = hsd_headset_transport_new (h, tname, sender, props, &error);
- if (t == NULL)
- goto transport_failed;
+ headset_set_state (h, HSD_HEADSET_STATE_ACTIVE);
- g_dbus_method_invocation_return_value (invocation,
- g_variant_new ("(o)", tname));
+ g_debug ("connected");
+ fdlist = g_unix_fd_list_new ();
+ g_unix_fd_list_append (fdlist, h->fd, NULL);
- g_hash_table_insert (h->transports, tname, t);
+ b = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add (b, "{sv}", "fd", g_variant_new_handle (0));
+ g_variant_builder_add (b, "{sv}", "mtu_r", g_variant_new_uint16 (48));
+ g_variant_builder_add (b, "{sv}", "mtu_w", g_variant_new_uint16 (48));
+ g_dbus_method_invocation_return_value_with_unix_fd_list (
+ invocation, g_variant_new ("(a{sv})", b), fdlist);
- return;
+ return FALSE;
-transport_failed:
+connect_failed:
{
- g_error ("failed to get transport: %s", error->message);
- g_dbus_method_invocation_take_error (invocation, error);
+ close (h->fd);
+ h->fd = -1;
+ g_free (h->owner);
+ h->owner = NULL;
+ headset_set_state (h, HSD_HEADSET_STATE_IDLE);
+ g_dbus_method_invocation_return_dbus_error (invocation,
+ "org.freedesktop.Headset.Error.Failed", "failed to connect");
+ return FALSE;
}
}
static void
-headset_release_transport (HsdHeadset *h,
- GDBusConnection *connection,
- const gchar *sender,
- GVariant *parameters,
- GDBusMethodInvocation *invocation)
+headset_connect (HsdHeadset *h,
+ GDBusConnection *connection,
+ const gchar *sender,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation)
{
- HsdHeadsetTransport *t;
- gchar *tname;
-
- g_debug ("headset ReleaseTransport");
+ 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;
+
+ g_message ("Connect headset");
+
+ if (h->state != HSD_HEADSET_STATE_IDLE)
+ goto not_idle;
+
+ src_addr = h->adapter_addr;
+ dst_addr = h->device_addr;
+
+ 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);
+
+ h->fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, BTPROTO_SCO);
+ if (h->fd < 0)
+ goto socket_failed;
+
+ g_debug ("got fd %d", h->fd);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sco_family = AF_BLUETOOTH;
+ bacpy(&addr.sco_bdaddr, &src);
+
+ if (bind(h->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
+ goto bind_failed;
+
+ if (voice) {
+ struct bt_voice opts;
+
+ /* SCO voice setting */
+ memset(&opts, 0, sizeof(opts));
+ opts.setting = voice;
+ if (setsockopt(h->fd, SOL_BLUETOOTH, BT_VOICE, &opts, sizeof(opts)) < 0)
+ goto sockopt_failed;
+ }
- g_variant_get (parameters, "(&o)", &tname);
+ memset(&addr, 0, sizeof(addr));
+ addr.sco_family = AF_BLUETOOTH;
+ bacpy(&addr.sco_bdaddr, &dst);
- t = g_hash_table_lookup (h->transports, tname);
- if (t == NULL)
- goto unknown_transport;
+ g_debug ("doing connect");
- if (strcmp (t->owner, sender) != 0)
- goto not_owner;
+ err = connect(h->fd, (struct sockaddr *) &addr, sizeof(addr));
+ if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS))
+ goto connect_failed;
- g_hash_table_remove (h->transports, tname);
- hsd_headset_transport_free (t);
+ headset_set_state (h, HSD_HEADSET_STATE_PENDING);
+ h->owner = g_strdup (sender);
+ h->invocation = invocation;
- g_dbus_method_invocation_return_value (invocation, 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,
+ headset_connect_cb, h);
+ g_io_channel_unref(io);
return;
-unknown_transport:
+not_idle:
{
g_dbus_method_invocation_return_dbus_error (invocation,
- "org.freedesktop.Headset.Error.DoesNotExist", "no such transport");
+ "org.freedesktop.Headset.Error.Failed", "headset not idle");
return;
}
+socket_failed:
+ {
+ g_dbus_method_invocation_return_dbus_error (invocation,
+ "org.freedesktop.Headset.Error.Failed", "failed to create socket");
+ goto close_fd;
+ }
+bind_failed:
+ {
+ g_dbus_method_invocation_return_dbus_error (invocation,
+ "org.freedesktop.Headset.Error.Failed", "failed to bind socket");
+ goto close_fd;
+ }
+sockopt_failed:
+ {
+ g_dbus_method_invocation_return_dbus_error (invocation,
+ "org.freedesktop.Headset.Error.Failed", "failed to setsockopt");
+ goto close_fd;
+ }
+connect_failed:
+ {
+ g_dbus_method_invocation_return_dbus_error (invocation,
+ "org.freedesktop.Headset.Error.Failed", "failed to connect");
+ goto close_fd;
+ }
+close_fd:
+ {
+ close (h->fd);
+ h->fd = -1;
+ return;
+ }
+}
+
+static void
+headset_disconnect (HsdHeadset *h,
+ GDBusConnection *connection,
+ const gchar *sender,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation)
+{
+ g_message ("headset disconnect");
+
+ 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);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+
+ return;
+
not_owner:
{
g_dbus_method_invocation_return_dbus_error (invocation,
- "org.freedesktop.Headset.Error.NotAuthorized", "not the transport owner");
+ "org.freedesktop.Headset.Error.NotAuthorized", "not the connection owner");
return;
}
}
@@ -144,19 +290,53 @@ headset_method_call (GDBusConnection *connection,
{
HsdHeadset *h = user_data;
- if (g_strcmp0 (method_name, "GetTransport") == 0) {
- headset_get_transport (h, connection, sender, parameters, invocation);
- } else if (g_strcmp0 (method_name, "ReleaseTransport") == 0) {
- headset_release_transport (h, connection, sender, parameters, invocation);
+ if (h->invocation)
+ goto busy;
+
+ if (g_strcmp0 (method_name, "Connect") == 0) {
+ headset_connect (h, connection, sender, parameters, invocation);
+ } else if (g_strcmp0 (method_name, "Disconnect") == 0) {
+ headset_disconnect (h, connection, sender, parameters, invocation);
} else
g_dbus_method_invocation_return_dbus_error (invocation,
"org.freedesktop.Headset.Error.NotImplemented", "no such method");
+
+ return;
+
+busy:
+ {
+ g_dbus_method_invocation_return_dbus_error (invocation,
+ "org.freedesktop.Headset.Error.Busy", "We have a pending operation");
+ return;
+ }
}
+static GVariant *
+headset_get_property (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *property_name,
+ GError **error,
+ gpointer user_data)
+{
+ HsdHeadset *h = user_data;
+ GVariant *ret;
+
+ ret = NULL;
+ if (g_strcmp0 (property_name, "Device") == 0) {
+ ret = g_variant_new_object_path (h->device);
+ } else if (g_strcmp0 (property_name, "State") == 0) {
+ ret = g_variant_new_string (headset_state_to_string (h->state));
+ }
+ return ret;
+}
+
+
static const GDBusInterfaceVTable headset_interface_vtable =
{
headset_method_call,
- NULL,
+ headset_get_property,
NULL
};
@@ -244,7 +424,6 @@ hsd_headset_new (const gchar *device, GIOChannel *rfcomm, GError **error)
headset = g_new0 (HsdHeadset, 1);
headset->device = g_strdup (device);
- headset->transports = g_hash_table_new (g_str_hash, g_str_equal);
headset->rfcomm = rfcomm;
headset->device_addr = dbus_get_property (conn, "org.bluez", device, "org.bluez.Device1", "Address", error);
@@ -297,8 +476,8 @@ hsd_headset_free (HsdHeadset *headset)
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_hash_table_unref (headset->transports);
g_free (headset);
}
diff --git a/src/hsd-headset.h b/src/hsd-headset.h
index c739a42..b30c01b 100644
--- a/src/hsd-headset.h
+++ b/src/hsd-headset.h
@@ -17,6 +17,12 @@
* Boston, MA 02110-1301, USA.
*/
+typedef enum {
+ HSD_HEADSET_STATE_IDLE,
+ HSD_HEADSET_STATE_PENDING,
+ HSD_HEADSET_STATE_ACTIVE,
+} HsdHeadsetState;
+
struct _HsdHeadset {
guint id;
@@ -27,7 +33,10 @@ struct _HsdHeadset {
GIOChannel *rfcomm;
- GHashTable *transports;
+ HsdHeadsetState state;
+ gchar *owner;
+ gint fd;
+ GDBusMethodInvocation *invocation;
};
HsdHeadset * hsd_headset_new (const gchar *device, GIOChannel *rfcomm, GError **error);