diff options
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r-- | net/bluetooth/hci_conn.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 6f22533e7656..0d4b8aeb8e09 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -379,13 +379,21 @@ int hci_conn_auth(struct hci_conn *conn) | |||
379 | { | 379 | { |
380 | BT_DBG("conn %p", conn); | 380 | BT_DBG("conn %p", conn); |
381 | 381 | ||
382 | if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) { | ||
383 | if (!(conn->auth_type & 0x01)) { | ||
384 | conn->auth_type = HCI_AT_GENERAL_BONDING_MITM; | ||
385 | conn->link_mode &= ~HCI_LM_AUTH; | ||
386 | } | ||
387 | } | ||
388 | |||
382 | if (conn->link_mode & HCI_LM_AUTH) | 389 | if (conn->link_mode & HCI_LM_AUTH) |
383 | return 1; | 390 | return 1; |
384 | 391 | ||
385 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { | 392 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { |
386 | struct hci_cp_auth_requested cp; | 393 | struct hci_cp_auth_requested cp; |
387 | cp.handle = cpu_to_le16(conn->handle); | 394 | cp.handle = cpu_to_le16(conn->handle); |
388 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); | 395 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, |
396 | sizeof(cp), &cp); | ||
389 | } | 397 | } |
390 | return 0; | 398 | return 0; |
391 | } | 399 | } |
@@ -397,7 +405,7 @@ int hci_conn_encrypt(struct hci_conn *conn) | |||
397 | BT_DBG("conn %p", conn); | 405 | BT_DBG("conn %p", conn); |
398 | 406 | ||
399 | if (conn->link_mode & HCI_LM_ENCRYPT) | 407 | if (conn->link_mode & HCI_LM_ENCRYPT) |
400 | return 1; | 408 | return hci_conn_auth(conn); |
401 | 409 | ||
402 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) | 410 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) |
403 | return 0; | 411 | return 0; |
@@ -406,7 +414,8 @@ int hci_conn_encrypt(struct hci_conn *conn) | |||
406 | struct hci_cp_set_conn_encrypt cp; | 414 | struct hci_cp_set_conn_encrypt cp; |
407 | cp.handle = cpu_to_le16(conn->handle); | 415 | cp.handle = cpu_to_le16(conn->handle); |
408 | cp.encrypt = 1; | 416 | cp.encrypt = 1; |
409 | hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp); | 417 | hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, |
418 | sizeof(cp), &cp); | ||
410 | } | 419 | } |
411 | return 0; | 420 | return 0; |
412 | } | 421 | } |
@@ -420,7 +429,8 @@ int hci_conn_change_link_key(struct hci_conn *conn) | |||
420 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { | 429 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { |
421 | struct hci_cp_change_conn_link_key cp; | 430 | struct hci_cp_change_conn_link_key cp; |
422 | cp.handle = cpu_to_le16(conn->handle); | 431 | cp.handle = cpu_to_le16(conn->handle); |
423 | hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, sizeof(cp), &cp); | 432 | hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, |
433 | sizeof(cp), &cp); | ||
424 | } | 434 | } |
425 | return 0; | 435 | return 0; |
426 | } | 436 | } |
@@ -624,3 +634,23 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg) | |||
624 | 634 | ||
625 | return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0; | 635 | return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0; |
626 | } | 636 | } |
637 | |||
638 | int hci_get_auth_info(struct hci_dev *hdev, void __user *arg) | ||
639 | { | ||
640 | struct hci_auth_info_req req; | ||
641 | struct hci_conn *conn; | ||
642 | |||
643 | if (copy_from_user(&req, arg, sizeof(req))) | ||
644 | return -EFAULT; | ||
645 | |||
646 | hci_dev_lock_bh(hdev); | ||
647 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &req.bdaddr); | ||
648 | if (conn) | ||
649 | req.type = conn->auth_type; | ||
650 | hci_dev_unlock_bh(hdev); | ||
651 | |||
652 | if (!conn) | ||
653 | return -ENOENT; | ||
654 | |||
655 | return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0; | ||
656 | } | ||