summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Orlenko <zxteam@gmail.com>2010-06-29 23:21:37 +1100
committerAlexander Orlenko <zxteam@gmail.com>2010-06-29 23:21:37 +1100
commitebbcda0b861f23e35d7eeab8e39d0ef3dc3c978f (patch)
tree8b3328628ec9732b6ed4c17f5cbea73cca9a2977
parent19bb1d403cf17a0da285ee451f88330c60f28c78 (diff)
downloadbluez-tools-ebbcda0b861f23e35d7eeab8e39d0ef3dc3c978f.tar.gz
added agent gobject && started dev. of bt-adapter
-rwxr-xr-xcontrib/gen-dbus-gobject.pl19
-rw-r--r--src/Makefile.am4
-rw-r--r--src/bt-adapter.c170
-rw-r--r--src/bt-agent.c0
-rw-r--r--src/bt-audio.c0
-rw-r--r--src/bt-device.c0
-rw-r--r--src/bt-input.c0
-rw-r--r--src/bt-monitor.c8
-rw-r--r--src/bt-network.c0
-rw-r--r--src/bt-serial.c0
-rw-r--r--src/lib/adapter.c17
-rw-r--r--src/lib/adapter.h2
-rw-r--r--src/lib/agent.c118
-rw-r--r--src/lib/agent.h94
-rw-r--r--src/lib/dbus-common.c4
-rw-r--r--src/lib/device.c17
-rw-r--r--src/lib/device.h2
-rw-r--r--src/lib/helpers.c148
-rw-r--r--src/lib/helpers.h42
-rw-r--r--src/lib/marshallers.list6
20 files changed, 628 insertions, 23 deletions
diff --git a/contrib/gen-dbus-gobject.pl b/contrib/gen-dbus-gobject.pl
index d4db223..379f9c9 100755
--- a/contrib/gen-dbus-gobject.pl
+++ b/contrib/gen-dbus-gobject.pl
@@ -173,7 +173,8 @@ sub get_g_type {
$g_type = 'gboolean ' if $bluez_type eq 'boolean';
$g_type = 'gint32 ' if $bluez_type eq 'int32';
$g_type = 'guint32 ' if $bluez_type eq 'uint32';
- $g_type = 'GPtrArray *' if $bluez_type eq 'array{object}' || $bluez_type eq 'array{string}';
+ $g_type = 'GPtrArray *' if $bluez_type eq 'array{object}';
+ $g_type = 'gchar **' if $bluez_type eq 'array{string}';
die "unknown bluez type (1): $bluez_type\n" unless defined $g_type;
@@ -645,7 +646,7 @@ EOT
$properties_changed_handler .=
"\t\tg_free(self->priv->$property_var);\n".
"\t\tself->priv->$property_var = (gchar *)g_value_dup_boxed(value);\n";
- } elsif ($p{'type'} eq 'array{object}' || $p{'type'} eq 'array{string}') {
+ } elsif ($p{'type'} eq 'array{object}') {
$properties_registration .= "\tpspec = g_param_spec_boxed(\"$property\", NULL, NULL, G_TYPE_PTR_ARRAY, ".($p{'mode'} eq 'readonly' ? 'G_PARAM_READABLE' : 'G_PARAM_READWRITE').");\n";
$properties_init .=
"\tif (g_hash_table_lookup(properties, \"$property\")) {\n".
@@ -658,6 +659,20 @@ EOT
$properties_changed_handler .=
"\t\tg_ptr_array_unref(self->priv->$property_var);\n".
"\t\tself->priv->$property_var = g_value_dup_boxed(value);\n";
+ } elsif ($p{'type'} eq 'array{string}') {
+ $properties_registration .= "\tpspec = g_param_spec_boxed(\"$property\", NULL, NULL, G_TYPE_STRV, ".($p{'mode'} eq 'readonly' ? 'G_PARAM_READABLE' : 'G_PARAM_READWRITE').");\n";
+ $properties_init .=
+ "\tif (g_hash_table_lookup(properties, \"$property\")) {\n".
+ "\t\tself->priv->$property_var = (gchar **)g_value_dup_boxed(g_hash_table_lookup(properties, \"$property\"));\n".
+ "\t} else {\n".
+ "\t\tself->priv->$property_var = g_new0(char *, 1);\n".
+ "\t\tself->priv->${property_var}[0] = NULL;\n".
+ "\t}\n";
+ $get_properties .= "\t\tg_value_set_boxed(value, $property_get_method(self));\n";
+ $properties_free .= "\tg_strfreev(self->priv->$property_var);\n";
+ $properties_changed_handler .=
+ "\t\tg_strfreev(self->priv->$property_var);\n".
+ "\t\tself->priv->$property_var = (gchar **)g_value_dup_boxed(value);\n";
} elsif ($p{'type'} eq 'uint32') {
$properties_registration .= "\tpspec = g_param_spec_uint(\"$property\", NULL, NULL, 0, 65535, 0, ".($p{'mode'} eq 'readonly' ? 'G_PARAM_READABLE' : 'G_PARAM_READWRITE').");\n";
$properties_init .=
diff --git a/src/Makefile.am b/src/Makefile.am
index a5391bb..9b70b80 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,6 +15,7 @@ lib_sources = lib/marshallers.c lib/marshallers.h \
lib/dbus-common.c lib/dbus-common.h \
lib/helpers.c lib/helpers.h \
lib/adapter.c lib/adapter.h \
+ lib/agent.c lib/agent.h \
lib/audio.c lib/audio.h \
lib/device.c lib/device.h \
lib/input.c lib/input.h \
@@ -22,8 +23,9 @@ lib_sources = lib/marshallers.c lib/marshallers.h \
lib/network.c lib/network.h \
lib/serial.c lib/serial.h
-bin_PROGRAMS = bt-monitor
+bin_PROGRAMS = bt-monitor bt-adapter
bt_monitor_SOURCES = $(lib_sources) bt-monitor.c
+bt_adapter_SOURCES = ${lib_sources} bt-adapter.c
CLEANFILES = Makefile.in lib/marshallers.c lib/marshallers.h
diff --git a/src/bt-adapter.c b/src/bt-adapter.c
new file mode 100644
index 0000000..187fe3f
--- /dev/null
+++ b/src/bt-adapter.c
@@ -0,0 +1,170 @@
+/*
+ *
+ * bluez-tools - a set of tools to manage bluetooth devices for linux
+ *
+ * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <glib.h>
+
+#include "lib/dbus-common.h"
+#include "lib/helpers.h"
+#include "lib/adapter.h"
+#include "lib/device.h"
+#include "lib/manager.h"
+#include "lib/agent.h"
+
+static gboolean stop_discovery(gpointer data) {
+ g_main_loop_quit(data);
+ return FALSE;
+}
+
+static void adapter_device_found(Adapter *adapter, const gchar *address, const GHashTable *values, gpointer data)
+{
+ g_print("device found: %s\n", address);
+}
+
+static void adapter_device_disappeared(Adapter *adapter, const gchar *address, gpointer data)
+{
+ g_print("device disappeared: %s\n", address);
+}
+
+static gboolean list_arg = FALSE;
+static gchar *adapter_arg = NULL;
+static gboolean info_arg = FALSE;
+static gboolean discover_arg = FALSE;
+static gboolean set_arg = FALSE;
+
+static GOptionEntry entries[] = {
+ { "list", 'l', 0, G_OPTION_ARG_NONE, &list_arg, "List all available adapters", NULL},
+ { "adapter", 'a', 0, G_OPTION_ARG_STRING, &adapter_arg, "Adapter name or MAC", "adapter#id"},
+ { "info", 'i', 0, G_OPTION_ARG_NONE, &info_arg, "Show adapter info", NULL},
+ { "discover", 'd', 0, G_OPTION_ARG_NONE, &discover_arg, "Discover remote devices", NULL},
+ { "set", 0, 0, G_OPTION_ARG_NONE, &set_arg, "Set property", NULL},
+ { NULL}
+};
+
+int main(int argc, char *argv[])
+{
+ GError *error = NULL;
+ GOptionContext *context;
+
+ g_type_init();
+
+ context = g_option_context_new("[--set Name Value] - a bluetooth adapter manager");
+ g_option_context_add_main_entries(context, entries, NULL);
+ g_option_context_set_summary(context, "summary");
+ g_option_context_set_description(context, "desc");
+ if (!g_option_context_parse(context, &argc, &argv, &error)) {
+ g_print("%s: %s\n", g_get_prgname(), error->message);
+ g_print("Try `%s --help` for more information.\n", g_get_prgname());
+ exit(EXIT_FAILURE);
+ }
+
+ if (!list_arg && !info_arg && !discover_arg && !set_arg) {
+ g_print("%s", g_option_context_get_help(context, FALSE, NULL));
+ exit(EXIT_FAILURE);
+ }
+
+ g_option_context_free(context);
+
+ if (!dbus_connect(&error)) {
+ g_printerr("Couldn't connect to dbus: %s", error->message);
+ exit(EXIT_FAILURE);
+ }
+
+ Manager *manager = g_object_new(MANAGER_TYPE, NULL);
+
+ if (list_arg) {
+ const GPtrArray *adapters_list = manager_get_adapters(manager);
+ g_return_val_if_fail(adapters_list != NULL, EXIT_FAILURE);
+
+ g_print("Available adapters:\n");
+
+ if (adapters_list->len == 0) {
+ g_print("no adapters found\n");
+ }
+
+ for (int i = 0; i < adapters_list->len; i++) {
+ Adapter *adapter = g_object_new(ADAPTER_TYPE, "DBusObjectPath", g_ptr_array_index(adapters_list, i), NULL);
+ g_print("%s (%s)\n", adapter_get_name(adapter), adapter_get_address(adapter));
+ g_object_unref(adapter);
+ }
+ } else if (info_arg) {
+ Adapter *adapter = find_adapter(adapter_arg, &error);
+ exit_if_error(error);
+
+ g_print("[%s]\n", g_basename(adapter_get_dbus_object_path(adapter)));
+ g_print(" Name: %s [rw]\n", adapter_get_name(adapter));
+ g_print(" Address: %s\n", adapter_get_address(adapter));
+ g_print(" Class: 0x%x\n", adapter_get_class(adapter));
+ g_print(" Discoverable: %d [rw]\n", adapter_get_discoverable(adapter));
+ g_print(" DiscoverableTimeout: %d [rw]\n", adapter_get_discoverable_timeout(adapter));
+ g_print(" Discovering: %d\n", adapter_get_discovering(adapter));
+ g_print(" Pairable: %d [rw]\n", adapter_get_pairable(adapter));
+ g_print(" PairableTimeout: %d [rw]\n", adapter_get_pairable_timeout(adapter));
+ g_print(" Powered: %d [rw]\n", adapter_get_powered(adapter));
+ g_print(" Service(s): [");
+ const gchar **uuids = adapter_get_uuids(adapter);
+ for (int j = 0; uuids[j] != NULL; j++) {
+ if (j > 0) g_print(", ");
+ g_print("%s", uuid2service(uuids[j]));
+ }
+ g_print("]\n");
+ g_object_unref(adapter);
+ } else if (discover_arg) {
+ Adapter *adapter = find_adapter(adapter_arg, &error);
+ exit_if_error(error);
+
+ g_signal_connect(adapter, "DeviceFound", G_CALLBACK(adapter_device_found), NULL);
+ g_signal_connect(adapter, "DeviceDisappeared", G_CALLBACK(adapter_device_disappeared), NULL);
+
+ adapter_start_discovery(adapter, error);
+ exit_if_error(error);
+
+ g_print("Searching...\n");
+
+ GSource *timeout_src = g_timeout_source_new_seconds(60);
+ g_source_attach(timeout_src, NULL);
+ GMainLoop *mainloop = g_main_loop_new(NULL, FALSE);
+ g_source_set_callback(timeout_src, stop_discovery, mainloop, NULL);
+ g_main_loop_run(mainloop);
+ g_main_loop_unref(mainloop);
+ g_source_unref(timeout_src);
+
+ adapter_stop_discovery(adapter, &error);
+ exit_if_error(error);
+
+ g_print("Done\n");
+ } else if (set_arg) {
+ Adapter *adapter = find_adapter(adapter_arg, &error);
+ exit_if_error(error);
+
+ }
+
+ g_object_unref(manager);
+
+ exit(EXIT_SUCCESS);
+}
+
diff --git a/src/bt-agent.c b/src/bt-agent.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/bt-agent.c
diff --git a/src/bt-audio.c b/src/bt-audio.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/bt-audio.c
diff --git a/src/bt-device.c b/src/bt-device.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/bt-device.c
diff --git a/src/bt-input.c b/src/bt-input.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/bt-input.c
diff --git a/src/bt-monitor.c b/src/bt-monitor.c
index 253d7e1..b1ebae2 100644
--- a/src/bt-monitor.c
+++ b/src/bt-monitor.c
@@ -33,6 +33,7 @@
#include "lib/adapter.h"
#include "lib/device.h"
#include "lib/manager.h"
+#include "lib/agent.h"
static gchar *capture_adapter_name = NULL;
static GPtrArray *captured_adapters = NULL;
@@ -92,7 +93,7 @@ static void adapter_device_disappeared(Adapter *adapter, const gchar *address, g
g_print("[ADAPTER] device disappeared: %s\n", address);
}
-static void adapter_device_found(Adapter *adapter, const gchar *address, gpointer data)
+static void adapter_device_found(Adapter *adapter, const gchar *address, const GHashTable *values, gpointer data)
{
g_print("[ADAPTER] device found: %s\n", address);
}
@@ -242,7 +243,7 @@ int main(int argc, char *argv[])
Manager *manager = g_object_new(MANAGER_TYPE, NULL);
if (capture_adapter_name != NULL) {
- Adapter *adapter = find_adapter_by_name(capture_adapter_name, &error);
+ Adapter *adapter = find_adapter(capture_adapter_name, &error);
exit_if_error(error);
capture_adapter(adapter);
} else {
@@ -264,6 +265,9 @@ int main(int argc, char *argv[])
g_signal_connect(manager, "DefaultAdapterChanged", G_CALLBACK(manager_default_adapter_changed), NULL);
g_signal_connect(manager, "PropertyChanged", G_CALLBACK(manager_property_changed), NULL);
+ Agent *agent = g_object_new(AGENT_TYPE, NULL);
+ g_print("agent registered...\n");
+
GMainLoop *mainloop;
mainloop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(mainloop);
diff --git a/src/bt-network.c b/src/bt-network.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/bt-network.c
diff --git a/src/bt-serial.c b/src/bt-serial.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/bt-serial.c
diff --git a/src/lib/adapter.c b/src/lib/adapter.c
index e26f28f..b456d6c 100644
--- a/src/lib/adapter.c
+++ b/src/lib/adapter.c
@@ -47,7 +47,7 @@ struct _AdapterPrivate {
gboolean pairable;
guint32 pairable_timeout;
gboolean powered;
- GPtrArray *uuids;
+ gchar **uuids;
};
G_DEFINE_TYPE(Adapter, adapter, G_TYPE_OBJECT);
@@ -105,7 +105,7 @@ static void adapter_dispose(GObject *gobject)
g_free(self->priv->address);
g_ptr_array_unref(self->priv->devices);
g_free(self->priv->name);
- g_ptr_array_unref(self->priv->uuids);
+ g_strfreev(self->priv->uuids);
/* Chain up to the parent class */
G_OBJECT_CLASS(adapter_parent_class)->dispose(gobject);
@@ -170,7 +170,7 @@ static void adapter_class_init(AdapterClass *klass)
g_object_class_install_property(gobject_class, PROP_POWERED, pspec);
/* array{string} UUIDs [readonly] */
- pspec = g_param_spec_boxed("UUIDs", NULL, NULL, G_TYPE_PTR_ARRAY, G_PARAM_READABLE);
+ pspec = g_param_spec_boxed("UUIDs", NULL, NULL, G_TYPE_STRV, G_PARAM_READABLE);
g_object_class_install_property(gobject_class, PROP_UUIDS, pspec);
/* Signals registation */
@@ -321,9 +321,10 @@ static void adapter_post_init(Adapter *self)
/* array{string} UUIDs [readonly] */
if (g_hash_table_lookup(properties, "UUIDs")) {
- self->priv->uuids = g_value_dup_boxed(g_hash_table_lookup(properties, "UUIDs"));
+ self->priv->uuids = (gchar **)g_value_dup_boxed(g_hash_table_lookup(properties, "UUIDs"));
} else {
- self->priv->uuids = g_ptr_array_new();
+ self->priv->uuids = g_new0(char *, 1);
+ self->priv->uuids[0] = NULL;
}
g_hash_table_unref(properties);
@@ -751,7 +752,7 @@ void adapter_set_powered(Adapter *self, const gboolean value)
g_assert(error == NULL);
}
-const GPtrArray *adapter_get_uuids(Adapter *self)
+const gchar **adapter_get_uuids(Adapter *self)
{
g_assert(ADAPTER_IS(self));
@@ -815,8 +816,8 @@ static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name
} else if (g_strcmp0(name, "Powered") == 0) {
self->priv->powered = g_value_get_boolean(value);
} else if (g_strcmp0(name, "UUIDs") == 0) {
- g_ptr_array_unref(self->priv->uuids);
- self->priv->uuids = g_value_dup_boxed(value);
+ g_strfreev(self->priv->uuids);
+ self->priv->uuids = (gchar **)g_value_dup_boxed(value);
}
g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value);
diff --git a/src/lib/adapter.h b/src/lib/adapter.h
index 84b4f1c..9758218 100644
--- a/src/lib/adapter.h
+++ b/src/lib/adapter.h
@@ -88,7 +88,7 @@ const guint32 adapter_get_pairable_timeout(Adapter *self);
void adapter_set_pairable_timeout(Adapter *self, const guint32 value);
const gboolean adapter_get_powered(Adapter *self);
void adapter_set_powered(Adapter *self, const gboolean value);
-const GPtrArray *adapter_get_uuids(Adapter *self);
+const gchar **adapter_get_uuids(Adapter *self);
#endif /* __ADAPTER_H */
diff --git a/src/lib/agent.c b/src/lib/agent.c
new file mode 100644
index 0000000..e14703e
--- /dev/null
+++ b/src/lib/agent.c
@@ -0,0 +1,118 @@
+/*
+ *
+ * bluez-tools - a set of tools to manage bluetooth devices for linux
+ *
+ * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "dbus-common.h"
+#include "agent.h"
+
+#define BLUEZ_DBUS_AGENT_INTERFACE "org.bluez.Agent"
+
+#define AGENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), AGENT_TYPE, AgentPrivate))
+
+struct _AgentPrivate {
+ DBusGProxy *proxy;
+};
+
+G_DEFINE_TYPE(Agent, agent, G_TYPE_OBJECT);
+
+static void agent_dispose(GObject *gobject)
+{
+ Agent *self = AGENT(gobject);
+
+ dbus_g_connection_unregister_g_object(conn, gobject);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS(agent_parent_class)->dispose(gobject);
+}
+
+static void agent_class_init(AgentClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->dispose = agent_dispose;
+
+ g_type_class_add_private(klass, sizeof(AgentPrivate));
+}
+
+static void agent_init(Agent *self)
+{
+ self->priv = AGENT_GET_PRIVATE(self);
+
+ g_assert(conn != NULL);
+
+ dbus_g_connection_register_g_object(conn, "/Agent", G_OBJECT(self));
+}
+
+/* Methods */
+
+gboolean agent_release(Agent *self, GError **error)
+{
+ g_print("agent_release\n");
+ return TRUE;
+}
+
+gboolean agent_request_pin_code(Agent *self, const gchar *device, gchar **ret, GError **error)
+{
+ g_print("agent_request_pin_code\n");
+ return TRUE;
+}
+
+gboolean agent_request_passkey(Agent *self, const gchar *device, guint *ret, GError **error)
+{
+ g_print("agent_request_passkey\n");
+ return TRUE;
+}
+
+gboolean agent_display_passkey(Agent *self, const gchar *device, guint passkey, guint8 entered, GError **error)
+{
+ g_print("agent_display_passkey\n");
+ return TRUE;
+}
+
+gboolean agent_request_confirmation(Agent *self, const gchar *device, guint passkey, GError **error)
+{
+ g_print("agent_request_confirmation\n");
+ return TRUE;
+}
+
+gboolean agent_authorize(Agent *self, const gchar *device, const gchar *uuid, GError **error)
+{
+ g_print("agent_authorize\n");
+ return TRUE;
+}
+
+gboolean agent_confirm_mode_change(Agent *self, const gchar *mode, GError **error)
+{
+ g_print("agent_confirm_mode_change\n");
+ return TRUE;
+}
+
+gboolean agent_cancel(Agent *self, GError **error)
+{
+ g_print("agent_cancel\n");
+ return TRUE;
+}
+
diff --git a/src/lib/agent.h b/src/lib/agent.h
new file mode 100644
index 0000000..49b90dc
--- /dev/null
+++ b/src/lib/agent.h
@@ -0,0 +1,94 @@
+/*
+ *
+ * bluez-tools - a set of tools to manage bluetooth devices for linux
+ *
+ * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __AGENT_H
+#define __AGENT_H
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+
+#include "marshallers.h"
+
+/*
+ * Type macros
+ */
+#define AGENT_TYPE (agent_get_type())
+#define AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), AGENT_TYPE, Agent))
+#define AGENT_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), AGENT_TYPE))
+#define AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), AGENT_TYPE, AgentClass))
+#define AGENT_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), AGENT_TYPE))
+#define AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), AGENT_TYPE, AgentClass))
+
+typedef struct _Agent Agent;
+typedef struct _AgentClass AgentClass;
+typedef struct _AgentPrivate AgentPrivate;
+
+struct _Agent {
+ GObject parent_instance;
+
+ /*< private >*/
+ AgentPrivate *priv;
+};
+
+struct _AgentClass {
+ GObjectClass parent_class;
+};
+
+/* used by AGENT_TYPE */
+GType agent_get_type(void) G_GNUC_CONST;
+
+/*
+ * Method definitions
+ */
+gboolean agent_release(Agent *self, GError **error);
+gboolean agent_request_pin_code(Agent *self, const gchar *device, gchar **ret, GError **error);
+gboolean agent_request_passkey(Agent *self, const gchar *device, guint *ret, GError **error);
+gboolean agent_display_passkey(Agent *self, const gchar *device, guint passkey, guint8 entered, GError **error);
+gboolean agent_request_confirmation(Agent *self, const gchar *device, guint passkey, GError **error);
+gboolean agent_authorize(Agent *self, const gchar *device, const gchar *uuid, GError **error);
+gboolean agent_confirm_mode_change(Agent *self, const gchar *mode, GError **error);
+gboolean agent_cancel(Agent *self, GError **error);
+
+/* Glue code */
+static const DBusGMethodInfo dbus_glib_agent_methods[] = {
+ { (GCallback) agent_release, g_cclosure_bluez_marshal_BOOLEAN__POINTER, 0},
+ { (GCallback) agent_request_pin_code, g_cclosure_bluez_marshal_BOOLEAN__BOXED_POINTER_POINTER, 27},
+ { (GCallback) agent_request_passkey, g_cclosure_bluez_marshal_BOOLEAN__BOXED_POINTER_POINTER, 85},
+ { (GCallback) agent_display_passkey, g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_UCHAR_POINTER, 143},
+ { (GCallback) agent_request_confirmation, g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_POINTER, 212},
+ { (GCallback) agent_authorize, g_cclosure_bluez_marshal_BOOLEAN__BOXED_STRING_POINTER, 274},
+ { (GCallback) agent_confirm_mode_change, g_cclosure_bluez_marshal_BOOLEAN__STRING_POINTER, 323},
+ { (GCallback) agent_cancel, g_cclosure_bluez_marshal_BOOLEAN__POINTER, 369},
+};
+
+static const DBusGObjectInfo dbus_glib_agent_object_info = {
+ 0,
+ dbus_glib_agent_methods,
+ 8,
+ "org.bluez.Agent\0Release\0S\0\0org.bluez.Agent\0RequestPinCode\0S\0device\0I\0o\0arg1\0O\0F\0N\0s\0\0org.bluez.Agent\0RequestPasskey\0S\0device\0I\0o\0arg1\0O\0F\0N\0u\0\0org.bluez.Agent\0DisplayPasskey\0S\0device\0I\0o\0passkey\0I\0u\0entered\0I\0y\0\0org.bluez.Agent\0RequestConfirmation\0S\0device\0I\0o\0passkey\0I\0u\0\0org.bluez.Agent\0Authorize\0S\0device\0I\0o\0uuid\0I\0s\0\0org.bluez.Agent\0ConfirmModeChange\0S\0mode\0I\0s\0\0org.bluez.Agent\0Cancel\0S\0\0\0",
+ "\0",
+ "\0"
+};
+
+#endif /* __AGENT_H */
+
diff --git a/src/lib/dbus-common.c b/src/lib/dbus-common.c
index d7ee6bb..054dc56 100644
--- a/src/lib/dbus-common.c
+++ b/src/lib/dbus-common.c
@@ -25,6 +25,7 @@
#include <config.h>
#endif
+#include "agent.h"
#include "marshallers.h"
#include "dbus-common.h"
@@ -40,6 +41,9 @@ gboolean dbus_connect(GError **error)
/* Marshallers registration */
dbus_g_object_register_marshaller(g_cclosure_bluez_marshal_VOID__STRING_BOXED, G_TYPE_NONE, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
+ /* Agent installation */
+ dbus_g_object_type_install_info(AGENT_TYPE, &dbus_glib_agent_object_info);
+
return TRUE;
}
diff --git a/src/lib/device.c b/src/lib/device.c
index d97027b..ca6aca2 100644
--- a/src/lib/device.c
+++ b/src/lib/device.c
@@ -49,7 +49,7 @@ struct _DevicePrivate {
GPtrArray *nodes;
gboolean paired;
gboolean trusted;
- GPtrArray *uuids;
+ gchar **uuids;
};
G_DEFINE_TYPE(Device, device, G_TYPE_OBJECT);
@@ -109,7 +109,7 @@ static void device_dispose(GObject *gobject)
g_free(self->priv->icon);
g_free(self->priv->name);
g_ptr_array_unref(self->priv->nodes);
- g_ptr_array_unref(self->priv->uuids);
+ g_strfreev(self->priv->uuids);
/* Chain up to the parent class */
G_OBJECT_CLASS(device_parent_class)->dispose(gobject);
@@ -182,7 +182,7 @@ static void device_class_init(DeviceClass *klass)
g_object_class_install_property(gobject_class, PROP_TRUSTED, pspec);
/* array{string} UUIDs [readonly] */
- pspec = g_param_spec_boxed("UUIDs", NULL, NULL, G_TYPE_PTR_ARRAY, G_PARAM_READABLE);
+ pspec = g_param_spec_boxed("UUIDs", NULL, NULL, G_TYPE_STRV, G_PARAM_READABLE);
g_object_class_install_property(gobject_class, PROP_UUIDS, pspec);
/* Signals registation */
@@ -336,9 +336,10 @@ static void device_post_init(Device *self)
/* array{string} UUIDs [readonly] */
if (g_hash_table_lookup(properties, "UUIDs")) {
- self->priv->uuids = g_value_dup_boxed(g_hash_table_lookup(properties, "UUIDs"));
+ self->priv->uuids = (gchar **)g_value_dup_boxed(g_hash_table_lookup(properties, "UUIDs"));
} else {
- self->priv->uuids = g_ptr_array_new();
+ self->priv->uuids = g_new0(char *, 1);
+ self->priv->uuids[0] = NULL;
}
g_hash_table_unref(properties);
@@ -679,7 +680,7 @@ void device_set_trusted(Device *self, const gboolean value)
g_assert(error == NULL);
}
-const GPtrArray *device_get_uuids(Device *self)
+const gchar **device_get_uuids(Device *self)
{
g_assert(DEVICE_IS(self));
@@ -743,8 +744,8 @@ static void property_changed_handler(DBusGProxy *dbus_g_proxy, const gchar *name
} else if (g_strcmp0(name, "Trusted") == 0) {
self->priv->trusted = g_value_get_boolean(value);
} else if (g_strcmp0(name, "UUIDs") == 0) {
- g_ptr_array_unref(self->priv->uuids);
- self->priv->uuids = g_value_dup_boxed(value);
+ g_strfreev(self->priv->uuids);
+ self->priv->uuids = (gchar **)g_value_dup_boxed(value);
}
g_signal_emit(self, signals[PROPERTY_CHANGED], 0, name, value);
diff --git a/src/lib/device.h b/src/lib/device.h
index 594f691..6e7370a 100644
--- a/src/lib/device.h
+++ b/src/lib/device.h
@@ -82,7 +82,7 @@ const GPtrArray *device_get_nodes(Device *self);
const gboolean device_get_paired(Device *self);
const gboolean device_get_trusted(Device *self);
void device_set_trusted(Device *self, const gboolean value);
-const GPtrArray *device_get_uuids(Device *self);
+const gchar **device_get_uuids(Device *self);
#endif /* __DEVICE_H */
diff --git a/src/lib/helpers.c b/src/lib/helpers.c
new file mode 100644
index 0000000..04c1450
--- /dev/null
+++ b/src/lib/helpers.c
@@ -0,0 +1,148 @@
+/*
+ *
+ * bluez-tools - a set of tools to manage bluetooth devices for linux
+ *
+ * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "helpers.h"
+#include "adapter.h"
+#include "manager.h"
+
+Adapter *find_adapter(const gchar *name, GError **error)
+{
+ gchar *adapter_path = NULL;
+ Adapter *adapter = NULL;
+
+ Manager *manager = g_object_new(MANAGER_TYPE, NULL);
+
+ // If name is null - return default adapter
+ if (name == NULL || strlen(name) == 0) {
+ adapter_path = manager_default_adapter(manager, error);
+ if (adapter_path) {
+ adapter = g_object_new(ADAPTER_TYPE, "DBusObjectPath", adapter_path, NULL);
+ }
+ } else {
+ // Try to find by id
+ adapter_path = manager_find_adapter(manager, name, error);
+
+ // Found
+ if (adapter_path) {
+ adapter = g_object_new(ADAPTER_TYPE, "DBusObjectPath", adapter_path, NULL);
+ } else {
+ // Try to find by name
+ const GPtrArray *adapters_list = manager_get_adapters(manager);
+ g_assert(adapters_list != NULL);
+ for (int i = 0; i < adapters_list->len; i++) {
+ adapter = g_object_new(ADAPTER_TYPE, "DBusObjectPath", g_ptr_array_index(adapters_list, i), NULL);
+
+ if (g_strcmp0(name, adapter_get_name(adapter)) == 0) {
+ if (error) {
+ g_error_free(*error);
+ *error = NULL;
+ }
+ break;
+ }
+
+ g_object_unref(adapter);
+ adapter = NULL;
+ }
+ }
+ }
+
+ g_object_unref(manager);
+ if (adapter_path) g_free(adapter_path);
+
+ return adapter;
+}
+
+const gchar *uuid2service(const gchar *uuid)
+{
+ static GHashTable *t = NULL;
+ if (t == NULL)
+ {
+ t = g_hash_table_new(g_str_hash, g_str_equal);
+ g_hash_table_insert(t, "00001000-0000-1000-8000-00805f9b34fb", "ServiceDiscoveryServer");
+ g_hash_table_insert(t, "00001001-0000-1000-8000-00805f9b34fb", "BrowseGroupDescriptor");
+ g_hash_table_insert(t, "00001002-0000-1000-8000-00805f9b34fb", "PublicBrowseGroup");
+ g_hash_table_insert(t, "00001101-0000-1000-8000-00805f9b34fb", "SerialPort");
+ g_hash_table_insert(t, "00001102-0000-1000-8000-00805f9b34fb", "LANAccessUsingPPP");
+ g_hash_table_insert(t, "00001103-0000-1000-8000-00805f9b34fb", "DialupNetworking");
+ g_hash_table_insert(t, "00001104-0000-1000-8000-00805f9b34fb", "IrMCSync");
+ g_hash_table_insert(t, "00001105-0000-1000-8000-00805f9b34fb", "OBEXObjectPush");
+ g_hash_table_insert(t, "00001106-0000-1000-8000-00805f9b34fb", "OBEXFileTransfer");
+ g_hash_table_insert(t, "00001107-0000-1000-8000-00805f9b34fb", "IrMCSyncCommand");
+ g_hash_table_insert(t, "00001108-0000-1000-8000-00805f9b34fb", "Headset");
+ g_hash_table_insert(t, "00001109-0000-1000-8000-00805f9b34fb", "CordlessTelephony");
+ g_hash_table_insert(t, "0000110a-0000-1000-8000-00805f9b34fb", "AudioSource");
+ g_hash_table_insert(t, "0000110b-0000-1000-8000-00805f9b34fb", "AudioSink");
+ g_hash_table_insert(t, "0000110c-0000-1000-8000-00805f9b34fb", "AVRemoteControlTarget");
+ g_hash_table_insert(t, "0000110d-0000-1000-8000-00805f9b34fb", "AdvancedAudioDistribution");
+ g_hash_table_insert(t, "0000110e-0000-1000-8000-00805f9b34fb", "AVRemoteControl");
+ g_hash_table_insert(t, "0000110f-0000-1000-8000-00805f9b34fb", "VideoConferencing");
+ g_hash_table_insert(t, "00001110-0000-1000-8000-00805f9b34fb", "Intercom");
+ g_hash_table_insert(t, "00001111-0000-1000-8000-00805f9b34fb", "Fax");
+ g_hash_table_insert(t, "00001112-0000-1000-8000-00805f9b34fb", "HeadsetAudioGateway");
+ g_hash_table_insert(t, "00001113-0000-1000-8000-00805f9b34fb", "WAP");
+ g_hash_table_insert(t, "00001114-0000-1000-8000-00805f9b34fb", "WAPClient");
+ g_hash_table_insert(t, "00001115-0000-1000-8000-00805f9b34fb", "PANU");
+ g_hash_table_insert(t, "00001116-0000-1000-8000-00805f9b34fb", "NAP");
+ g_hash_table_insert(t, "00001117-0000-1000-8000-00805f9b34fb", "GN");
+ g_hash_table_insert(t, "00001118-0000-1000-8000-00805f9b34fb", "DirectPrinting");
+ g_hash_table_insert(t, "00001119-0000-1000-8000-00805f9b34fb", "ReferencePrinting");
+ g_hash_table_insert(t, "0000111a-0000-1000-8000-00805f9b34fb", "Imaging");
+ g_hash_table_insert(t, "0000111b-0000-1000-8000-00805f9b34fb", "ImagingResponder");
+ g_hash_table_insert(t, "0000111c-0000-1000-8000-00805f9b34fb", "ImagingAutomaticArchive");
+ g_hash_table_insert(t, "0000111d-0000-1000-8000-00805f9b34fb", "ImagingReferenceObjects");
+ g_hash_table_insert(t, "0000111e-0000-1000-8000-00805f9b34fb", "Handsfree");
+ g_hash_table_insert(t, "0000111f-0000-1000-8000-00805f9b34fb", "HandsfreeAudioGateway");
+ g_hash_table_insert(t, "00001120-0000-1000-8000-00805f9b34fb", "DirectPrintingReferenceObjects");
+ g_hash_table_insert(t, "00001121-0000-1000-8000-00805f9b34fb", "ReflectedUI");
+ g_hash_table_insert(t, "00001122-0000-1000-8000-00805f9b34fb", "BasicPringing");
+ g_hash_table_insert(t, "00001123-0000-1000-8000-00805f9b34fb", "PrintingStatus");
+ g_hash_table_insert(t, "00001124-0000-1000-8000-00805f9b34fb", "HumanInterfaceDevice");
+ g_hash_table_insert(t, "00001125-0000-1000-8000-00805f9b34fb", "HardcopyCableReplacement");
+ g_hash_table_insert(t, "00001126-0000-1000-8000-00805f9b34fb", "HCRPrint");
+ g_hash_table_insert(t, "00001127-0000-1000-8000-00805f9b34fb", "HCRScan");
+ g_hash_table_insert(t, "00001128-0000-1000-8000-00805f9b34fb", "CommonISDNAccess");
+ g_hash_table_insert(t, "00001129-0000-1000-8000-00805f9b34fb", "VideoConferencingGW");
+ g_hash_table_insert(t, "0000112a-0000-1000-8000-00805f9b34fb", "UDIMT");
+ g_hash_table_insert(t, "0000112b-0000-1000-8000-00805f9b34fb", "UDITA");
+ g_hash_table_insert(t, "0000112c-0000-1000-8000-00805f9b34fb", "AudioVideo");
+ g_hash_table_insert(t, "0000112d-0000-1000-8000-00805f9b34fb", "SIMAccess");
+ g_hash_table_insert(t, "00001200-0000-1000-8000-00805f9b34fb", "PnPInformation");
+ g_hash_table_insert(t, "00001201-0000-1000-8000-00805f9b34fb", "GenericNetworking");
+ g_hash_table_insert(t, "00001202-0000-1000-8000-00805f9b34fb", "GenericFileTransfer");
+ g_hash_table_insert(t, "00001203-0000-1000-8000-00805f9b34fb", "GenericAudio");
+ g_hash_table_insert(t, "00001204-0000-1000-8000-00805f9b34fb", "GenericTelephony");
+ }
+
+ if (g_hash_table_lookup(t, uuid) != NULL) {
+ return g_hash_table_lookup(t, uuid);
+ } else {
+ return uuid;
+ }
+}
+
diff --git a/src/lib/helpers.h b/src/lib/helpers.h
new file mode 100644
index 0000000..c09911d
--- /dev/null
+++ b/src/lib/helpers.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * bluez-tools - a set of tools to manage bluetooth devices for linux
+ *
+ * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __HELPERS_H
+#define __HELPERS_H
+
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+
+#include "adapter.h"
+
+Adapter *find_adapter(const gchar *name, GError **error);
+const gchar *uuid2service(const gchar *uuid);
+
+#define exit_if_error(error) G_STMT_START{ \
+if (error) { \
+ g_printerr("%s\n", error->message); \
+ exit(EXIT_FAILURE); \
+}; }G_STMT_END
+
+#endif /* __HELPERS_H */
+
diff --git a/src/lib/marshallers.list b/src/lib/marshallers.list
index e72aa4b..4096a34 100644
--- a/src/lib/marshallers.list
+++ b/src/lib/marshallers.list
@@ -1 +1,7 @@
VOID:STRING,BOXED
+BOOLEAN:BOXED,UINT,UCHAR,POINTER
+BOOLEAN:BOXED,STRING,POINTER
+BOOLEAN:POINTER
+BOOLEAN:BOXED,POINTER,POINTER
+BOOLEAN:BOXED,UINT,POINTER
+BOOLEAN:STRING,POINTER