diff --git a/src/agent.c b/src/agent.c
index bb4b619..3d234c2 100644
--- a/src/agent.c
+++ b/src/agent.c
typedef enum {
AGENT_REQUEST_PASSKEY,
AGENT_REQUEST_CONFIRMATION,
+ AGENT_REQUEST_AUTHORIZATION,
AGENT_REQUEST_PINCODE,
AGENT_REQUEST_AUTHORIZE_SERVICE,
AGENT_REQUEST_CONFIRM_MODE,
return err;
}
+static int authorization_request_new(struct agent_request *req,
+ const char *device_path)
+{
+ struct agent *agent = req->agent;
+
+ req->msg = dbus_message_new_method_call(agent->name, agent->path,
+ "org.bluez.Agent", "RequestAuthorization");
+ if (req->msg == NULL) {
+ error("Couldn't allocate D-Bus message");
+ return -ENOMEM;
+ }
+
+ dbus_message_append_args(req->msg,
+ DBUS_TYPE_OBJECT_PATH, &device_path,
+ DBUS_TYPE_INVALID);
+
+ if (dbus_connection_send_with_reply(btd_get_dbus_connection(), req->msg,
+ &req->call, REQUEST_TIMEOUT) == FALSE) {
+ error("D-Bus send failed");
+ return -EIO;
+ }
+
+ dbus_pending_call_set_notify(req->call, simple_agent_reply, req, NULL);
+
+ return 0;
+}
+
+int agent_request_authorization(struct agent *agent, struct btd_device *device,
+ agent_cb cb, void *user_data,
+ GDestroyNotify destroy)
+{
+ struct agent_request *req;
+ const gchar *dev_path = device_get_path(device);
+ int err;
+
+ if (agent->request)
+ return -EBUSY;
+
+ DBG("Calling Agent.RequestAuthorization: name=%s, path=%s",
+ agent->name, agent->path);
+
+ req = agent_request_new(agent, AGENT_REQUEST_AUTHORIZATION, cb,
+ user_data, destroy);
+
+ err = authorization_request_new(req, dev_path);
+ if (err < 0)
+ goto failed;
+
+ agent->request = req;
+
+ return 0;
+
+failed:
+ agent_request_free(req, FALSE);
+ return err;
+}
+
int agent_display_passkey(struct agent *agent, struct btd_device *device,
uint32_t passkey, uint16_t entered)
{
diff --git a/src/agent.h b/src/agent.h
index 3b817d4..2b011b7 100644
--- a/src/agent.h
+++ b/src/agent.h
uint32_t passkey, agent_cb cb,
void *user_data, GDestroyNotify destroy);
+int agent_request_authorization(struct agent *agent, struct btd_device *device,
+ agent_cb cb, void *user_data,
+ GDestroyNotify destroy);
+
int agent_display_passkey(struct agent *agent, struct btd_device *device,
uint32_t passkey, uint16_t entered);
diff --git a/src/device.c b/src/device.c
index 254aa77..8c00a59 100644
--- a/src/device.c
+++ b/src/device.c
return err;
}
-int device_confirm_passkey(struct btd_device *device, uint32_t passkey)
+int device_confirm_passkey(struct btd_device *device, uint32_t passkey,
+ uint8_t confirm_hint)
{
struct authentication_req *auth;
auth->passkey = passkey;
- err = agent_request_confirmation(auth->agent, device, passkey,
+ if (confirm_hint)
+ err = agent_request_authorization(auth->agent, device,
confirm_cb, auth, NULL);
+ else
+ err = agent_request_confirmation(auth->agent, device, passkey,
+ confirm_cb, auth, NULL);
+
if (err < 0) {
error("Failed requesting authentication");
device_auth_req_free(device);
diff --git a/src/device.h b/src/device.h
index 7c8765d..1d7f54f 100644
--- a/src/device.h
+++ b/src/device.h
void device_cancel_bonding(struct btd_device *device, uint8_t status);
int device_request_pincode(struct btd_device *device, gboolean secure);
int device_request_passkey(struct btd_device *device);
-int device_confirm_passkey(struct btd_device *device, uint32_t passkey);
+int device_confirm_passkey(struct btd_device *device, uint32_t passkey,
+ uint8_t confirm_hint);
int device_notify_passkey(struct btd_device *device, uint32_t passkey,
uint8_t entered);
int device_notify_pincode(struct btd_device *device, gboolean secure,
diff --git a/src/mgmt.c b/src/mgmt.c
index 4196bdd..95b7433 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
error("device_notify_passkey: %s", strerror(-err));
}
-struct confirm_data {
- int index;
- bdaddr_t bdaddr;
- uint8_t type;
-};
-
-static gboolean confirm_accept(gpointer user_data)
-{
- struct confirm_data *data = user_data;
- struct controller_info *info = &controllers[data->index];
-
- DBG("auto-accepting incoming pairing request");
-
- if (data->index > max_index || !info->valid)
- return FALSE;
-
- mgmt_confirm_reply(data->index, &data->bdaddr, data->type, TRUE);
-
- return FALSE;
-}
-
static void mgmt_user_confirm_request(int sk, uint16_t index, void *buf,
size_t len)
{
return;
}
- if (ev->confirm_hint) {
- struct confirm_data *data;
-
- data = g_new0(struct confirm_data, 1);
- data->index = index;
- bacpy(&data->bdaddr, &ev->addr.bdaddr);
- data->type = ev->addr.type;
-
- g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, 1,
- confirm_accept, data, g_free);
- return;
- }
-
info = &controllers[index];
if (!get_adapter_and_device(&info->bdaddr, &ev->addr.bdaddr,
&adapter, &device, true))
return;
- err = device_confirm_passkey(device, btohl(ev->value));
+ err = device_confirm_passkey(device, btohl(ev->value),
+ ev->confirm_hint);
if (err < 0) {
error("device_confirm_passkey: %s", strerror(-err));
mgmt_confirm_reply(index, &ev->addr.bdaddr, ev->addr.type,