From 916791b0348534a72b25fd59a8e0917d0a65eeb5 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 4 Dec 2012 15:14:13 +0200 Subject: [PATCH] core: Add SSP just-works acceptor mapping to Agent.RequestAuthorization --- src/agent.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/agent.h | 4 ++++ src/device.c | 10 +++++++-- src/device.h | 3 ++- src/mgmt.c | 37 ++------------------------------- 5 files changed, 74 insertions(+), 38 deletions(-) diff --git a/src/agent.c b/src/agent.c index bb4b61925..3d234c246 100644 --- a/src/agent.c +++ b/src/agent.c @@ -52,6 +52,7 @@ typedef enum { AGENT_REQUEST_PASSKEY, AGENT_REQUEST_CONFIRMATION, + AGENT_REQUEST_AUTHORIZATION, AGENT_REQUEST_PINCODE, AGENT_REQUEST_AUTHORIZE_SERVICE, AGENT_REQUEST_CONFIRM_MODE, @@ -669,6 +670,63 @@ failed: 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 3b817d466..2b011b7a9 100644 --- a/src/agent.h +++ b/src/agent.h @@ -61,6 +61,10 @@ int agent_request_confirmation(struct agent *agent, struct btd_device *device, 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 254aa77df..8c00a5975 100644 --- a/src/device.c +++ b/src/device.c @@ -3755,7 +3755,8 @@ int device_request_passkey(struct btd_device *device) 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; @@ -3767,8 +3768,13 @@ int device_confirm_passkey(struct btd_device *device, uint32_t passkey) 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 7c8765dea..1d7f54f71 100644 --- a/src/device.h +++ b/src/device.h @@ -86,7 +86,8 @@ gboolean device_is_bonding(struct btd_device *device, const char *sender); 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 4196bdd06..95b74332e 100644 --- a/src/mgmt.c +++ b/src/mgmt.c @@ -938,27 +938,6 @@ static void mgmt_passkey_notify(int sk, uint16_t index, void *buf, size_t len) 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) { @@ -984,26 +963,14 @@ static void mgmt_user_confirm_request(int sk, uint16_t index, void *buf, 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, -- 2.47.3