Commit 9f61656a60c9506e3e4cd41af5efbcf6a30ee3b9
Committed by
Gustavo F. Padovan
1 parent
7a828908a0
Exists in
master
and in
7 other branches
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>
Showing 4 changed files with 60 additions and 1 deletions Side-by-side Diff
include/net/bluetooth/hci_core.h
... | ... | @@ -126,6 +126,8 @@ |
126 | 126 | __u16 sniff_min_interval; |
127 | 127 | __u16 sniff_max_interval; |
128 | 128 | |
129 | + unsigned int auto_accept_delay; | |
130 | + | |
129 | 131 | unsigned long quirks; |
130 | 132 | |
131 | 133 | atomic_t cmd_cnt; |
... | ... | @@ -246,6 +248,7 @@ |
246 | 248 | |
247 | 249 | struct timer_list disc_timer; |
248 | 250 | struct timer_list idle_timer; |
251 | + struct timer_list auto_accept_timer; | |
249 | 252 | |
250 | 253 | struct work_struct work_add; |
251 | 254 | struct work_struct work_del; |
net/bluetooth/hci_conn.c
... | ... | @@ -269,6 +269,19 @@ |
269 | 269 | hci_conn_enter_sniff_mode(conn); |
270 | 270 | } |
271 | 271 | |
272 | +static 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 | + | |
272 | 285 | struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) |
273 | 286 | { |
274 | 287 | struct hci_conn *conn; |
... | ... | @@ -312,6 +325,8 @@ |
312 | 325 | |
313 | 326 | setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn); |
314 | 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 | 331 | atomic_set(&conn->refcnt, 0); |
317 | 332 | |
... | ... | @@ -341,6 +356,8 @@ |
341 | 356 | del_timer(&conn->idle_timer); |
342 | 357 | |
343 | 358 | del_timer(&conn->disc_timer); |
359 | + | |
360 | + del_timer(&conn->auto_accept_timer); | |
344 | 361 | |
345 | 362 | if (conn->type == ACL_LINK) { |
346 | 363 | struct hci_conn *sco = conn->link; |
net/bluetooth/hci_event.c
... | ... | @@ -2515,7 +2515,15 @@ |
2515 | 2515 | /* If no side requires MITM protection; auto-accept */ |
2516 | 2516 | if ((!loc_mitm || conn->remote_cap == 0x03) && |
2517 | 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 | 2527 | hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, |
2520 | 2528 | sizeof(ev->bdaddr), &ev->bdaddr); |
2521 | 2529 | goto unlock; |
net/bluetooth/hci_sysfs.c
... | ... | @@ -511,6 +511,35 @@ |
511 | 511 | .release = single_release, |
512 | 512 | }; |
513 | 513 | |
514 | +static 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 | + | |
527 | +static 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 | + | |
540 | +DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, | |
541 | + auto_accept_delay_set, "%llu\n"); | |
542 | + | |
514 | 543 | int hci_register_sysfs(struct hci_dev *hdev) |
515 | 544 | { |
516 | 545 | struct device *dev = &hdev->dev; |
... | ... | @@ -545,6 +574,8 @@ |
545 | 574 | |
546 | 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 | 579 | return 0; |
549 | 580 | } |
550 | 581 |