summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2008-03-20 17:32:47 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2008-03-20 17:32:47 +0000
commitd888f2cf3cb2423684a4db1e5f45fe188240408d (patch)
tree9dd7736b6153db03822586771b771f3d4460db06
parent4f02eee62285b7a643b2e87be8df510416a631ec (diff)
Implement support for new Agent.RequestPasskey
-rw-r--r--hcid/dbus-hci.c75
-rw-r--r--hcid/device.h1
2 files changed, 75 insertions, 1 deletions
diff --git a/hcid/dbus-hci.c b/hcid/dbus-hci.c
index d3cb1855..f8a10007 100644
--- a/hcid/dbus-hci.c
+++ b/hcid/dbus-hci.c
@@ -937,9 +937,54 @@ void hcid_dbus_pending_pin_req_add(bdaddr_t *sba, bdaddr_t *dba)
adapter->bonding->auth_active = 1;
}
+static void passkey_cb(struct agent *agent, DBusError *err, const char *passkey,
+ struct device *device)
+{
+ struct adapter *adapter = device->adapter;
+ pin_code_reply_cp pr;
+ bdaddr_t sba, dba;
+ size_t len;
+ int dev;
+
+ dev = hci_open_dev(adapter->dev_id);
+ if (dev < 0) {
+ error("hci_open_dev(%d): %s (%d)", adapter->dev_id,
+ strerror(errno), errno);
+ return;
+ }
+
+ if (err) {
+ if (device->created)
+ device_remove(connection, device);
+ hci_send_cmd(dev, OGF_LINK_CTL,
+ OCF_PIN_CODE_NEG_REPLY, 6, &dba);
+ goto done;
+ }
+
+ device->created = FALSE;
+
+ str2ba(adapter->address, &sba);
+ str2ba(device->address, &dba);
+
+ len = strlen(passkey);
+
+ set_pin_length(&sba, len);
+
+ memset(&pr, 0, sizeof(pr));
+ bacpy(&pr.bdaddr, &dba);
+ memcpy(pr.pin_code, passkey, len);
+ pr.pin_len = len;
+ hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr);
+
+done:
+ hci_close_dev(dev);
+}
+
int hcid_dbus_request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci)
{
char path[MAX_PATH_LENGTH], addr[18];
+ struct adapter *adapter;
+ struct device *device;
int id;
ba2str(sba, addr);
@@ -950,8 +995,36 @@ int hcid_dbus_request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci)
return -1;
}
- snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);
+ if (!hcid_dbus_use_experimental())
+ goto old_fallback;
+
+ snprintf(path, sizeof(path), "/hci%d", id);
+ if (!dbus_connection_get_object_user_data(connection, path,
+ (void *) &adapter)) {
+ error("Getting %s path data failed!", path);
+ goto old_fallback;
+ }
+
+ if (!adapter->agent)
+ goto old_fallback;
+
+ device = adapter_get_device(adapter, &ci->bdaddr);
+ if (!device) {
+ ba2str(&ci->bdaddr, addr);
+ device = device_create(connection, adapter, addr, NULL);
+ device->created = TRUE;
+ }
+
+ if (!device)
+ return -ENODEV;
+
+ return agent_request_passkey(adapter->agent, device,
+ (agent_passkey_cb) passkey_cb,
+ device);
+
+old_fallback:
+ snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);
return handle_passkey_request_old(connection, dev, path, sba, &ci->bdaddr);
}
diff --git a/hcid/device.h b/hcid/device.h
index fe3ca688..e276a49c 100644
--- a/hcid/device.h
+++ b/hcid/device.h
@@ -29,6 +29,7 @@ struct device {
gchar *path;
struct adapter *adapter;
GSList *uuids;
+ gboolean created;
};
struct device *device_create(DBusConnection *conn, struct adapter *adapter,