aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2011-04-28 14:28:54 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-04-28 15:02:30 -0400
commit9f61656a60c9506e3e4cd41af5efbcf6a30ee3b9 (patch)
treebfeb4576c064f441c0262548165fa5ba9f19b032
parent7a828908a026d801c6192fd32cfb35d6843f1539 (diff)
Bluetooth: Add variable SSP auto-accept delay support
Some test systems require an arbitrary delay to the auto-accept test cases for Secure Simple Pairing in order for the tests to pass. Previously when this was handled in user space it was worked around by code modifications and recompilation, but now that it's on the kernel side it's more convenient if there's a debugfs interface for it. Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r--include/net/bluetooth/hci_core.h3
-rw-r--r--net/bluetooth/hci_conn.c17
-rw-r--r--net/bluetooth/hci_event.c10
-rw-r--r--net/bluetooth/hci_sysfs.c31
4 files changed, 60 insertions, 1 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 2995e2e63512..09b9dd61e370 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -126,6 +126,8 @@ struct hci_dev {
126 __u16 sniff_min_interval; 126 __u16 sniff_min_interval;
127 __u16 sniff_max_interval; 127 __u16 sniff_max_interval;
128 128
129 unsigned int auto_accept_delay;
130
129 unsigned long quirks; 131 unsigned long quirks;
130 132
131 atomic_t cmd_cnt; 133 atomic_t cmd_cnt;
@@ -246,6 +248,7 @@ struct hci_conn {
246 248
247 struct timer_list disc_timer; 249 struct timer_list disc_timer;
248 struct timer_list idle_timer; 250 struct timer_list idle_timer;
251 struct timer_list auto_accept_timer;
249 252
250 struct work_struct work_add; 253 struct work_struct work_add;
251 struct work_struct work_del; 254 struct work_struct work_del;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 74cd755b38a7..7f5ad8a2b22d 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -269,6 +269,19 @@ static void hci_conn_idle(unsigned long arg)
269 hci_conn_enter_sniff_mode(conn); 269 hci_conn_enter_sniff_mode(conn);
270} 270}
271 271
272static void hci_conn_auto_accept(unsigned long arg)
273{
274 struct hci_conn *conn = (void *) arg;
275 struct hci_dev *hdev = conn->hdev;
276
277 hci_dev_lock(hdev);
278
279 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst),
280 &conn->dst);
281
282 hci_dev_unlock(hdev);
283}
284
272struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) 285struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
273{ 286{
274 struct hci_conn *conn; 287 struct hci_conn *conn;
@@ -312,6 +325,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
312 325
313 setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn); 326 setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn);
314 setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); 327 setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn);
328 setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept,
329 (unsigned long) conn);
315 330
316 atomic_set(&conn->refcnt, 0); 331 atomic_set(&conn->refcnt, 0);
317 332
@@ -342,6 +357,8 @@ int hci_conn_del(struct hci_conn *conn)
342 357
343 del_timer(&conn->disc_timer); 358 del_timer(&conn->disc_timer);
344 359
360 del_timer(&conn->auto_accept_timer);
361
345 if (conn->type == ACL_LINK) { 362 if (conn->type == ACL_LINK) {
346 struct hci_conn *sco = conn->link; 363 struct hci_conn *sco = conn->link;
347 if (sco) 364 if (sco)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 514e10e1e0ff..a479389668ef 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2515,7 +2515,15 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
2515 /* If no side requires MITM protection; auto-accept */ 2515 /* If no side requires MITM protection; auto-accept */
2516 if ((!loc_mitm || conn->remote_cap == 0x03) && 2516 if ((!loc_mitm || conn->remote_cap == 0x03) &&
2517 (!rem_mitm || conn->io_capability == 0x03)) { 2517 (!rem_mitm || conn->io_capability == 0x03)) {
2518 BT_DBG("Auto-accept of user confirmation"); 2518 BT_DBG("Auto-accept of user confirmation with %ums delay",
2519 hdev->auto_accept_delay);
2520
2521 if (hdev->auto_accept_delay > 0) {
2522 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
2523 mod_timer(&conn->auto_accept_timer, jiffies + delay);
2524 goto unlock;
2525 }
2526
2519 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, 2527 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
2520 sizeof(ev->bdaddr), &ev->bdaddr); 2528 sizeof(ev->bdaddr), &ev->bdaddr);
2521 goto unlock; 2529 goto unlock;
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 8775933ea837..a6c3aa8be1f7 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -511,6 +511,35 @@ static const struct file_operations uuids_fops = {
511 .release = single_release, 511 .release = single_release,
512}; 512};
513 513
514static int auto_accept_delay_set(void *data, u64 val)
515{
516 struct hci_dev *hdev = data;
517
518 hci_dev_lock_bh(hdev);
519
520 hdev->auto_accept_delay = val;
521
522 hci_dev_unlock_bh(hdev);
523
524 return 0;
525}
526
527static int auto_accept_delay_get(void *data, u64 *val)
528{
529 struct hci_dev *hdev = data;
530
531 hci_dev_lock_bh(hdev);
532
533 *val = hdev->auto_accept_delay;
534
535 hci_dev_unlock_bh(hdev);
536
537 return 0;
538}
539
540DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
541 auto_accept_delay_set, "%llu\n");
542
514int hci_register_sysfs(struct hci_dev *hdev) 543int hci_register_sysfs(struct hci_dev *hdev)
515{ 544{
516 struct device *dev = &hdev->dev; 545 struct device *dev = &hdev->dev;
@@ -545,6 +574,8 @@ int hci_register_sysfs(struct hci_dev *hdev)
545 574
546 debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); 575 debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
547 576
577 debugfs_create_file("auto_accept_delay", 0444, hdev->debugfs, hdev,
578 &auto_accept_delay_fops);
548 return 0; 579 return 0;
549} 580}
550 581