[gnome-bluetooth] agent: Port agent code to BlueZ 5
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-bluetooth] agent: Port agent code to BlueZ 5
- Date: Thu, 30 May 2013 12:25:57 +0000 (UTC)
commit 1755d1bd2c35443792e157de3fc8d2972849e1ce
Author: Gustavo Padovan <gustavo padovan collabora co uk>
Date: Wed May 15 17:55:13 2013 -0300
agent: Port agent code to BlueZ 5
The biggest difference of the new Agent API is that BlueZ 5 doesn't
register one agent per adapter anymore. There is now only one agent, to
handle all adapters at the same time and most of changes in this commit
are related to that.
The new API also introduces a new Agent method, RequestAuthorization(), to
give power to the user allow/deny JustWorks pairing(when both sides
doesn't require user interaction), so now bluetooth_agent_set_authorize_func
is related to that method and there is new
bluetooth_agent_set_authorize_service_func which is sets the callback to
the function to authorize services to trying to connect.
https://bugzilla.gnome.org/show_bug.cgi?id=685717
lib/bluetooth-agent.c | 299 +++++++++++++++++++++----------------------
lib/bluetooth-agent.h | 4 +
lib/gnome-bluetooth.symbols | 1 +
lib/test-agent.c | 31 +----
4 files changed, 162 insertions(+), 173 deletions(-)
---
diff --git a/lib/bluetooth-agent.c b/lib/bluetooth-agent.c
index f8b5cd0..92ccb45 100644
--- a/lib/bluetooth-agent.c
+++ b/lib/bluetooth-agent.c
@@ -29,17 +29,16 @@
#include <gio/gio.h>
#include "bluetooth-client-glue.h"
+#include "bluetooth-fdo-glue.h"
#include "bluetooth-agent.h"
-#define BLUEZ_SERVICE "org.bluez"
-
-#define BLUEZ_MANAGER_PATH "/"
-#define BLUEZ_MANAGER_INTERFACE "org.bluez.Manager"
-#define BLUEZ_DEVICE_INTERFACE "org.bluez.Device"
+#define BLUEZ_SERVICE "org.bluez"
+#define BLUEZ_AGENT_PATH "/org/bluez/agent/gnome"
+#define BLUEZ_MANAGER_PATH "/"
static const gchar introspection_xml[] =
"<node name='/'>"
-" <interface name='org.bluez.Agent'>"
+" <interface name='org.bluez.Agent1'>"
" <method name='Release'/>"
" <method name='RequestPinCode'>"
" <arg type='o' name='device' direction='in'/>"
@@ -58,12 +57,12 @@ static const gchar introspection_xml[] =
" <arg type='o' name='device' direction='in'/>"
" <arg type='u' name='passkey' direction='in'/>"
" </method>"
-" <method name='Authorize'>"
+" <method name='RequestAuthorization'>"
" <arg type='o' name='device' direction='in'/>"
-" <arg type='s' name='uuid' direction='in'/>"
" </method>"
-" <method name='ConfirmMode'>"
-" <arg type='s' name='mode'/>"
+" <method name='AuthorizeService'>"
+" <arg type='o' name='device' direction='in'/>"
+" <arg type='s' name='uuid' direction='in'/>"
" </method>"
" <method name='Cancel'/>"
" </interface>"
@@ -78,7 +77,7 @@ struct _BluetoothAgentPrivate {
GDBusConnection *conn;
gchar *busname;
gchar *path;
- GDBusProxy *adapter;
+ AgentManager1 *agent_manager;
GDBusNodeInfo *introspection_data;
guint reg_id;
guint watch_id;
@@ -98,49 +97,46 @@ struct _BluetoothAgentPrivate {
BluetoothAgentAuthorizeFunc authorize_func;
gpointer authorize_data;
+ BluetoothAgentAuthorizeServiceFunc authorize_service_func;
+ gpointer authorize_service_data;
+
BluetoothAgentCancelFunc cancel_func;
gpointer cancel_data;
};
-G_DEFINE_TYPE(BluetoothAgent, bluetooth_agent, G_TYPE_OBJECT)
-
-static GDBusProxy *
-get_device_from_adapter (BluetoothAgent *agent,
- const char *path)
+static GDBusProxy *get_device_from_path (const char *path)
{
- BluetoothAgentPrivate *priv = BLUETOOTH_AGENT_GET_PRIVATE(agent);
-
- if (priv->adapter == NULL)
- return NULL;
-
- return g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
- NULL,
- g_dbus_proxy_get_name (priv->adapter),
- path,
- BLUEZ_DEVICE_INTERFACE,
- NULL,
- NULL);
+ Device1 *device;
+ device = device1_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ BLUEZ_SERVICE,
+ path,
+ NULL,
+ NULL);
+
+ return G_DBUS_PROXY(device);
}
-static gboolean bluetooth_agent_request_pin_code(BluetoothAgent *agent,
+G_DEFINE_TYPE(BluetoothAgent, bluetooth_agent, G_TYPE_OBJECT)
+
+static gboolean bluetooth_agent_request_pincode(BluetoothAgent *agent,
const char *path, GDBusMethodInvocation *invocation)
{
BluetoothAgentPrivate *priv = BLUETOOTH_AGENT_GET_PRIVATE(agent);
GDBusProxy *device;
- gboolean result = FALSE;
- if (priv->pincode_func) {
- device = get_device_from_adapter (agent, path);
+ if (priv->pincode_func == NULL)
+ return FALSE;
+
+ device = get_device_from_path(path);
+ if (device == NULL)
+ return FALSE;
- result = priv->pincode_func(invocation, device,
- priv->pincode_data);
+ priv->pincode_func(invocation, device, priv->pincode_data);
- if (device != NULL)
- g_object_unref(device);
- }
+ g_object_unref(device);
- return result;
+ return TRUE;
}
static gboolean bluetooth_agent_request_passkey(BluetoothAgent *agent,
@@ -148,19 +144,19 @@ static gboolean bluetooth_agent_request_passkey(BluetoothAgent *agent,
{
BluetoothAgentPrivate *priv = BLUETOOTH_AGENT_GET_PRIVATE(agent);
GDBusProxy *device;
- gboolean result = FALSE;
- if (priv->passkey_func) {
- device = get_device_from_adapter (agent, path);
+ if (priv->passkey_func == NULL)
+ return FALSE;
- result = priv->passkey_func(invocation, device,
- priv->passkey_data);
+ device = get_device_from_path(path);
+ if (device == NULL)
+ return FALSE;
- if (device != NULL)
- g_object_unref(device);
- }
+ priv->passkey_func(invocation, device, priv->passkey_data);
- return result;
+ g_object_unref(device);
+
+ return TRUE;
}
static gboolean bluetooth_agent_display_passkey(BluetoothAgent *agent,
@@ -169,19 +165,20 @@ static gboolean bluetooth_agent_display_passkey(BluetoothAgent *agent,
{
BluetoothAgentPrivate *priv = BLUETOOTH_AGENT_GET_PRIVATE(agent);
GDBusProxy *device;
- gboolean result = FALSE;
- if (priv->display_func) {
- device = get_device_from_adapter (agent, path);
+ if (priv->display_func == NULL)
+ return FALSE;
- result = priv->display_func(invocation, device, passkey, entered,
- priv->display_data);
+ device = get_device_from_path(path);
+ if (device == NULL)
+ return FALSE;
- if (device != NULL)
- g_object_unref(device);
- }
+ priv->display_func(invocation, device, passkey, entered,
+ priv->display_data);
- return result;
+ g_object_unref(device);
+
+ return TRUE;
}
static gboolean bluetooth_agent_request_confirmation(BluetoothAgent *agent,
@@ -190,52 +187,72 @@ static gboolean bluetooth_agent_request_confirmation(BluetoothAgent *agent,
{
BluetoothAgentPrivate *priv = BLUETOOTH_AGENT_GET_PRIVATE(agent);
GDBusProxy *device;
- gboolean result = FALSE;
- if (priv->confirm_func) {
- device = get_device_from_adapter (agent, path);
+ if (priv->confirm_func == NULL)
+ return FALSE;
- result = priv->confirm_func(invocation, device, passkey,
- priv->confirm_data);
+ device = get_device_from_path(path);
+ if (device == NULL)
+ return FALSE;
- if (device != NULL)
- g_object_unref(device);
- }
+ priv->confirm_func(invocation, device, passkey, priv->confirm_data);
+
+ g_object_unref(device);
- return result;
+ return TRUE;
}
-static gboolean bluetooth_agent_authorize(BluetoothAgent *agent,
+static gboolean bluetooth_agent_request_authorization(BluetoothAgent *agent,
+ const char *path, GDBusMethodInvocation *invocation)
+{
+ BluetoothAgentPrivate *priv = BLUETOOTH_AGENT_GET_PRIVATE(agent);
+ GDBusProxy *device;
+
+ if (priv->authorize_func == NULL)
+ return FALSE;
+
+ device = get_device_from_path(path);
+ if (device == NULL)
+ return FALSE;
+
+ priv->authorize_func(invocation, device, priv->authorize_data);
+
+ g_object_unref(device);
+
+ return TRUE;
+}
+
+static gboolean bluetooth_agent_authorize_service(BluetoothAgent *agent,
const char *path, const char *uuid,
GDBusMethodInvocation *invocation)
{
BluetoothAgentPrivate *priv = BLUETOOTH_AGENT_GET_PRIVATE(agent);
GDBusProxy *device;
- gboolean result = FALSE;
- if (priv->authorize_func) {
- device = get_device_from_adapter (agent, path);
+ if (priv->authorize_service_func == NULL)
+ return FALSE;
+
+ device = get_device_from_path(path);
+ if (device == NULL)
+ return FALSE;
- result = priv->authorize_func(invocation, device, uuid,
- priv->authorize_data);
+ priv->authorize_service_func(invocation, device, uuid,
+ priv->authorize_service_data);
- if (device != NULL)
- g_object_unref(device);
- }
+ g_object_unref(device);
- return result;
+ return TRUE;
}
static gboolean bluetooth_agent_cancel(BluetoothAgent *agent,
GDBusMethodInvocation *invocation)
{
BluetoothAgentPrivate *priv = BLUETOOTH_AGENT_GET_PRIVATE(agent);
- gboolean result = FALSE;
- if (priv->cancel_func)
- result = priv->cancel_func(invocation, priv->cancel_data);
+ if (priv->cancel_func == NULL)
+ return FALSE;
- return result;
+ return priv->cancel_func(invocation, priv->cancel_data);
}
static void
@@ -320,8 +337,11 @@ handle_method_call (GDBusConnection *connection,
BluetoothAgentPrivate *priv = BLUETOOTH_AGENT_GET_PRIVATE(agent);
if (g_str_equal (sender, priv->busname) == FALSE) {
- g_assert_not_reached ();
- /* FIXME, should this just be a D-Bus Error instead? */
+ GError *error = NULL;
+ error = g_error_new (AGENT_ERROR, AGENT_ERROR_REJECT,
+ "Permission Denied");
+ g_dbus_method_invocation_take_error(invocation, error);
+ return;
}
if (g_strcmp0 (method_name, "Release") == 0) {
@@ -329,7 +349,7 @@ handle_method_call (GDBusConnection *connection,
} else if (g_strcmp0 (method_name, "RequestPinCode") == 0) {
char *path;
g_variant_get (parameters, "(o)", &path);
- bluetooth_agent_request_pin_code (agent, path, invocation);
+ bluetooth_agent_request_pincode (agent, path, invocation);
g_free (path);
} else if (g_strcmp0 (method_name, "RequestPasskey") == 0) {
char *path;
@@ -351,16 +371,20 @@ handle_method_call (GDBusConnection *connection,
g_variant_get (parameters, "(ou)", &path, &passkey);
bluetooth_agent_request_confirmation (agent, path, passkey, invocation);
g_free (path);
- } else if (g_strcmp0 (method_name, "Authorize") == 0) {
+ } else if (g_strcmp0 (method_name, "RequestAuthorization") == 0) {
+ char *path;
+
+ g_variant_get (parameters, "(o)", &path);
+ bluetooth_agent_request_authorization (agent, path, invocation);
+ g_free (path);
+ } else if (g_strcmp0 (method_name, "AuthorizeService") == 0) {
char *path, *uuid;
g_variant_get (parameters, "(os)", &path, &uuid);
- bluetooth_agent_authorize (agent, path, uuid, invocation);
+ bluetooth_agent_authorize_service (agent, path, uuid, invocation);
g_free (path);
g_free (uuid);
} else if (g_strcmp0 (method_name, "Cancel") == 0) {
bluetooth_agent_cancel (agent, invocation);
- } else if (g_strcmp0 (method_name, "ConfirmMode") == 0) {
- g_dbus_method_invocation_return_value (invocation, NULL);
}
}
@@ -398,67 +422,22 @@ gboolean bluetooth_agent_setup(BluetoothAgent *agent, const char *path)
return TRUE;
}
-#define BLUEZ_SERVICE "org.bluez"
-#define BLUEZ_MANAGER_INTERFACE "org.bluez.Manager"
-
-static GDBusProxy *
-get_default_adapter (void)
-{
- Manager *manager;
- char *adapter_path;
- Adapter *adapter;
-
- manager = manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
- BLUEZ_SERVICE,
- BLUEZ_MANAGER_PATH,
- NULL,
- NULL);
- if (manager == NULL)
- return NULL;
- if (manager_call_default_adapter_sync (manager, &adapter_path, NULL, NULL) == FALSE) {
- g_object_unref (manager);
- return NULL;
- }
- adapter = adapter_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
- BLUEZ_SERVICE,
- adapter_path,
- NULL,
- NULL);
- g_object_unref (manager);
- g_free (adapter_path);
-
- return G_DBUS_PROXY (adapter);
-}
-
gboolean bluetooth_agent_register(BluetoothAgent *agent)
{
BluetoothAgentPrivate *priv;
GError *error = NULL;
- char *path;
- GVariant *r;
+ gboolean ret;
g_return_val_if_fail (BLUETOOTH_IS_AGENT (agent), FALSE);
priv = BLUETOOTH_AGENT_GET_PRIVATE (agent);
- priv->adapter = get_default_adapter ();
-
- if (priv->adapter == NULL)
- return FALSE;
-
- if (priv->path != NULL) {
- g_warning ("Agent already setup on '%s'", priv->path);
- return FALSE;
- }
-
- path = g_path_get_basename(g_dbus_proxy_get_object_path(priv->adapter));
- priv->path = g_strdup_printf("/org/bluez/agent/%s", path);
- g_free(path);
+ priv->agent_manager = agent_manager1_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ BLUEZ_SERVICE, "/org/bluez", NULL, NULL);
priv->reg_id = g_dbus_connection_register_object (priv->conn,
- priv->path,
+ BLUEZ_AGENT_PATH,
priv->introspection_data->interfaces[0],
&interface_vtable,
agent,
@@ -471,16 +450,24 @@ gboolean bluetooth_agent_register(BluetoothAgent *agent)
return FALSE;
}
- r = g_dbus_proxy_call_sync (priv->adapter, "RegisterAgent",
- g_variant_new ("(os)", priv->path, "DisplayYesNo"),
- G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, &error);
- if (r == NULL) {
+ ret = agent_manager1_call_register_agent_sync (priv->agent_manager,
+ BLUEZ_AGENT_PATH,
+ "DisplayYesNo",
+ NULL, &error);
+ if (ret == FALSE) {
+ g_printerr ("Agent registration failed: %s\n", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ ret = agent_manager1_call_request_default_agent_sync (priv->agent_manager,
+ BLUEZ_AGENT_PATH,
+ NULL, &error);
+ if (ret == FALSE) {
g_printerr ("Agent registration failed: %s\n", error->message);
g_error_free (error);
return FALSE;
}
- g_variant_unref (r);
return TRUE;
}
@@ -494,13 +481,12 @@ gboolean bluetooth_agent_unregister(BluetoothAgent *agent)
priv = BLUETOOTH_AGENT_GET_PRIVATE(agent);
- if (priv->adapter == NULL)
+ if (priv->agent_manager == NULL)
return FALSE;
- if (g_dbus_proxy_call_sync (priv->adapter, "UnregisterAgent",
- g_variant_new ("(o)", priv->path),
- G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, &error) == FALSE) {
+ if (agent_manager1_call_unregister_agent_sync (priv->agent_manager,
+ BLUEZ_AGENT_PATH,
+ NULL, &error) == FALSE) {
/* Ignore errors if the adapter is gone */
if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD) == FALSE) {
g_printerr ("Agent unregistration failed: %s '%s'\n",
@@ -510,8 +496,8 @@ gboolean bluetooth_agent_unregister(BluetoothAgent *agent)
g_error_free(error);
}
- g_object_unref(priv->adapter);
- priv->adapter = NULL;
+ g_object_unref(priv->agent_manager);
+ priv->agent_manager = NULL;
g_free(priv->path);
priv->path = NULL;
@@ -592,6 +578,19 @@ void bluetooth_agent_set_authorize_func(BluetoothAgent *agent,
priv->authorize_data = data;
}
+void bluetooth_agent_set_authorize_service_func(BluetoothAgent *agent,
+ BluetoothAgentAuthorizeServiceFunc func, gpointer data)
+{
+ BluetoothAgentPrivate *priv;
+
+ g_return_if_fail (BLUETOOTH_IS_AGENT (agent));
+
+ priv = BLUETOOTH_AGENT_GET_PRIVATE(agent);
+
+ priv->authorize_service_func = func;
+ priv->authorize_service_data = data;
+}
+
void bluetooth_agent_set_cancel_func(BluetoothAgent *agent,
BluetoothAgentCancelFunc func, gpointer data)
{
diff --git a/lib/bluetooth-agent.h b/lib/bluetooth-agent.h
index db97387..1c0fbf4 100644
--- a/lib/bluetooth-agent.h
+++ b/lib/bluetooth-agent.h
@@ -70,6 +70,8 @@ typedef gboolean (*BluetoothAgentConfirmFunc) (GDBusMethodInvocation *invocation
GDBusProxy *device, guint passkey,
gpointer data);
typedef gboolean (*BluetoothAgentAuthorizeFunc) (GDBusMethodInvocation *invocation,
+ GDBusProxy *device, gpointer data);
+typedef gboolean (*BluetoothAgentAuthorizeServiceFunc) (GDBusMethodInvocation *invocation,
GDBusProxy *device, const char *uuid,
gpointer data);
typedef gboolean (*BluetoothAgentCancelFunc) (GDBusMethodInvocation *invocation,
@@ -85,6 +87,8 @@ void bluetooth_agent_set_confirm_func(BluetoothAgent *agent,
BluetoothAgentConfirmFunc func, gpointer data);
void bluetooth_agent_set_authorize_func(BluetoothAgent *agent,
BluetoothAgentAuthorizeFunc func, gpointer data);
+void bluetooth_agent_set_authorize_service_func(BluetoothAgent *agent,
+ BluetoothAgentAuthorizeServiceFunc func, gpointer data);
void bluetooth_agent_set_cancel_func(BluetoothAgent *agent,
BluetoothAgentCancelFunc func, gpointer data);
diff --git a/lib/gnome-bluetooth.symbols b/lib/gnome-bluetooth.symbols
index bf292a0..f06e9fe 100644
--- a/lib/gnome-bluetooth.symbols
+++ b/lib/gnome-bluetooth.symbols
@@ -65,4 +65,5 @@ bluetooth_agent_set_cancel_func
bluetooth_agent_error_quark
bluetooth_agent_set_authorize_func
bluetooth_agent_set_display_func
+bluetooth_agent_set_authorize_service_func
bluetooth_agent_setup
diff --git a/lib/test-agent.c b/lib/test-agent.c
index 0a9c1c4..a57baac 100644
--- a/lib/test-agent.c
+++ b/lib/test-agent.c
@@ -31,35 +31,20 @@
#include <signal.h>
#include "bluetooth-agent.h"
-#include "bluetooth-client-glue.h"
static gboolean
-agent_pincode (GDBusMethodInvocation *invocation,
+agent_confirm (GDBusMethodInvocation *invocation,
GDBusProxy *device,
- gpointer user_data)
+ guint passkey,
+ gpointer data)
{
- GVariant *value;
- GVariant *result;
- const char *alias, *address;
+ const char *path;
- result = g_dbus_proxy_call_sync (device, "GetProperties", NULL,
- G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);
- if (result != NULL) {
- value = g_variant_lookup_value (result, "Address", G_VARIANT_TYPE_STRING);
- address = value ? g_variant_get_string (value, NULL) : "No address";
+ path = g_dbus_proxy_get_object_path(device);
- value = g_variant_lookup_value (result, "Name", G_VARIANT_TYPE_STRING);
- alias = value ? g_variant_get_string (value, NULL) : address;
+ g_print ("Confirming passkey %6.6d from %s\n", passkey, path);
- printf("address %s name %s\n", address, alias);
-
- g_variant_unref (result);
- } else {
- g_message ("Could not get address or name for '%s'",
- g_dbus_proxy_get_object_path (device));
- }
-
- g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "1234"));
+ g_dbus_method_invocation_return_value (invocation, NULL);
return TRUE;
}
@@ -87,7 +72,7 @@ int main (int argc, char **argv)
agent = bluetooth_agent_new();
- bluetooth_agent_set_pincode_func(agent, agent_pincode, NULL);
+ bluetooth_agent_set_confirm_func(agent, agent_confirm, NULL);
bluetooth_agent_register(agent);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]