diff options
-rw-r--r-- | include/net/bluetooth/hci_core.h | 3 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 17 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 10 | ||||
-rw-r--r-- | net/bluetooth/hci_sysfs.c | 31 |
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 | ||
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 | struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | 285 | struct 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 | ||
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 | int hci_register_sysfs(struct hci_dev *hdev) | 543 | int 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 | ||