Permalink
Browse files

Add new Agent API : RequestPairingConsent.

This callback will be called for incoming pairing requests for 2.1
devices only when the remote IO capabilities are NoInputNoOutput
or DisplayOnly and the local IO capability is DisplayYesNo.
Currently, we were silently auto accepting.
  • Loading branch information...
1 parent 518154e commit 7050b0c6c21919186cddda6f2286f43cb99798b2 Jaikumar Ganesh committed Sep 4, 2009
Showing with 126 additions and 1 deletion.
  1. +11 −0 doc/agent-api.txt
  2. +14 −0 plugins/hciops.c
  3. +59 −1 src/agent.c
  4. +4 −0 src/agent.h
  5. +24 −0 src/device.c
  6. +2 −0 src/device.h
  7. +12 −0 src/event.c
View
@@ -74,6 +74,17 @@ Methods void Release()
Possible errors: org.bluez.Error.Rejected
org.bluez.Error.Canceled
+ void RequestPairingConsent(object device)
+
+ This method gets called when the service daemon
+ needs to confirm an incoming pairing request.
+
+ To accept it should return an empty reply
+ or an error to reject.
+
+ Possible errors: org.bluez.Error.Rejected
+ org.bluez.Error.Canceled
+
void Authorize(object device, string uuid)
This method gets called when the service daemon
View
@@ -1083,6 +1083,7 @@ static void user_confirm_request(int index, void *ptr)
evt_user_confirm_request *req = ptr;
gboolean loc_mitm, rem_mitm;
struct bt_conn *conn;
+ struct agent *agent;
DBG("hci%d", index);
@@ -1102,6 +1103,19 @@ static void user_confirm_request(int index, void *ptr)
goto fail;
}
+ /* If local IO capabilities are DisplayYesNo and remote IO
+ * capabiltiies are DisplayOnly or NoInputNoOutput;
+ * call PairingConsent callback for incoming requests. */
+ if (conn->bonding_initiator == FALSE) {
+ if ((conn->loc_cap == 0x01) &&
+ (conn->rem_cap == 0x00 || conn->rem_cap == 0x03)) {
+ if (btd_event_user_consent(&dev->bdaddr, &req->bdaddr)
+ < 0)
+ goto fail;
+ return;
+ }
+ }
+
/* If no side requires MITM protection; auto-accept */
if ((conn->loc_auth == 0xff || !loc_mitm || conn->rem_cap == 0x03) &&
(!rem_mitm || conn->loc_cap == 0x03)) {
View
@@ -53,7 +53,8 @@ typedef enum {
AGENT_REQUEST_CONFIRMATION,
AGENT_REQUEST_PINCODE,
AGENT_REQUEST_AUTHORIZE,
- AGENT_REQUEST_CONFIRM_MODE
+ AGENT_REQUEST_CONFIRM_MODE,
+ AGENT_REQUEST_PAIRING_CONSENT,
} agent_request_type_t;
struct agent {
@@ -694,6 +695,63 @@ int agent_request_confirmation(struct agent *agent, struct btd_device *device,
return err;
}
+static int pairing_consent_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", "RequestPairingConsent");
+ 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(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_pairing_consent(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.RequestPairingConsent: name=%s, path=%s",
+ agent->name, agent->path);
+
+ req = agent_request_new(agent, AGENT_REQUEST_PAIRING_CONSENT, cb,
+ user_data, destroy);
+
+ err = pairing_consent_request_new(req, dev_path);
+ if (err < 0)
+ goto failed;
+
+ agent->request = req;
+
+ return 0;
+
+failed:
+ agent_request_free(req, FALSE);
+ return err;
+}
+
static int request_fallback(struct agent_request *req,
DBusPendingCallNotifyFunction function)
{
View
@@ -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_pairing_consent(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);
View
@@ -2279,6 +2279,20 @@ static void passkey_cb(struct agent *agent, DBusError *err,
device->authr->agent = NULL;
}
+static void pairing_consent_cb(struct agent *agent, DBusError *err, void *data)
+{
+ struct authentication_req *auth = data;
+ struct btd_device *device = auth->device;
+
+ /* No need to reply anything if the authentication already failed */
+ if (!auth->cb)
+ return;
+
+ ((agent_cb) auth->cb)(agent, err, device);
+
+ auth->cb = NULL;
+}
+
int device_request_authentication(struct btd_device *device, auth_type_t type,
uint32_t passkey, void *cb)
{
@@ -2324,6 +2338,13 @@ int device_request_authentication(struct btd_device *device, auth_type_t type,
case AUTH_TYPE_NOTIFY:
err = agent_display_passkey(agent, device, passkey);
break;
+ case AUTH_TYPE_AUTO:
+ err = 0;
+ break;
+ case AUTH_TYPE_PAIRING_CONSENT:
+ err = agent_request_pairing_consent(agent, device,
+ pairing_consent_cb, auth, NULL);
+ break;
default:
err = -EINVAL;
}
@@ -2361,6 +2382,9 @@ static void cancel_authentication(struct authentication_req *auth)
case AUTH_TYPE_PASSKEY:
((agent_passkey_cb) auth->cb)(agent, &err, 0, device);
break;
+ case AUTH_TYPE_PAIRING_CONSENT:
+ ((agent_cb) auth->cb) (agent, &err, device);
+ break;
case AUTH_TYPE_NOTIFY:
/* User Notify doesn't require any reply */
break;
View
@@ -31,6 +31,8 @@ typedef enum {
AUTH_TYPE_PASSKEY,
AUTH_TYPE_CONFIRM,
AUTH_TYPE_NOTIFY,
+ AUTH_TYPE_AUTO,
+ AUTH_TYPE_PAIRING_CONSENT,
} auth_type_t;
typedef enum {
View
@@ -219,6 +219,18 @@ int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey)
passkey, confirm_cb);
}
+int btd_event_user_consent(bdaddr_t *sba, bdaddr_t *dba)
+{
+ struct btd_adapter *adapter;
+ struct btd_device *device;
+
+ if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE))
+ return -ENODEV;
+
+ return device_request_authentication(device, AUTH_TYPE_PAIRING_CONSENT,
+ 0, confirm_cb);
+}
+
int btd_event_user_passkey(bdaddr_t *sba, bdaddr_t *dba)
{
struct btd_adapter *adapter;

0 comments on commit 7050b0c

Please sign in to comment.