diff options
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r-- | net/bluetooth/hci_event.c | 69 |
1 files changed, 66 insertions, 3 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 98b5764e4315..3fbfa50c2bff 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -796,6 +796,29 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, | |||
796 | hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status); | 796 | hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status); |
797 | } | 797 | } |
798 | 798 | ||
799 | static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) | ||
800 | { | ||
801 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; | ||
802 | |||
803 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
804 | |||
805 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
806 | mgmt_user_confirm_reply_complete(hdev->id, &rp->bdaddr, | ||
807 | rp->status); | ||
808 | } | ||
809 | |||
810 | static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, | ||
811 | struct sk_buff *skb) | ||
812 | { | ||
813 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; | ||
814 | |||
815 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
816 | |||
817 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
818 | mgmt_user_confirm_neg_reply_complete(hdev->id, &rp->bdaddr, | ||
819 | rp->status); | ||
820 | } | ||
821 | |||
799 | static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | 822 | static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) |
800 | { | 823 | { |
801 | BT_DBG("%s status 0x%x", hdev->name, status); | 824 | BT_DBG("%s status 0x%x", hdev->name, status); |
@@ -1401,8 +1424,10 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1401 | if (!ev->status) { | 1424 | if (!ev->status) { |
1402 | conn->link_mode |= HCI_LM_AUTH; | 1425 | conn->link_mode |= HCI_LM_AUTH; |
1403 | conn->sec_level = conn->pending_sec_level; | 1426 | conn->sec_level = conn->pending_sec_level; |
1404 | } else | 1427 | } else { |
1428 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); | ||
1405 | conn->sec_level = BT_SECURITY_LOW; | 1429 | conn->sec_level = BT_SECURITY_LOW; |
1430 | } | ||
1406 | 1431 | ||
1407 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); | 1432 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); |
1408 | 1433 | ||
@@ -1728,6 +1753,14 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1728 | hci_cc_le_read_buffer_size(hdev, skb); | 1753 | hci_cc_le_read_buffer_size(hdev, skb); |
1729 | break; | 1754 | break; |
1730 | 1755 | ||
1756 | case HCI_OP_USER_CONFIRM_REPLY: | ||
1757 | hci_cc_user_confirm_reply(hdev, skb); | ||
1758 | break; | ||
1759 | |||
1760 | case HCI_OP_USER_CONFIRM_NEG_REPLY: | ||
1761 | hci_cc_user_confirm_neg_reply(hdev, skb); | ||
1762 | break; | ||
1763 | |||
1731 | default: | 1764 | default: |
1732 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); | 1765 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); |
1733 | break; | 1766 | break; |
@@ -2362,6 +2395,21 @@ unlock: | |||
2362 | hci_dev_unlock(hdev); | 2395 | hci_dev_unlock(hdev); |
2363 | } | 2396 | } |
2364 | 2397 | ||
2398 | static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, | ||
2399 | struct sk_buff *skb) | ||
2400 | { | ||
2401 | struct hci_ev_user_confirm_req *ev = (void *) skb->data; | ||
2402 | |||
2403 | BT_DBG("%s", hdev->name); | ||
2404 | |||
2405 | hci_dev_lock(hdev); | ||
2406 | |||
2407 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
2408 | mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey); | ||
2409 | |||
2410 | hci_dev_unlock(hdev); | ||
2411 | } | ||
2412 | |||
2365 | static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2413 | static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
2366 | { | 2414 | { |
2367 | struct hci_ev_simple_pair_complete *ev = (void *) skb->data; | 2415 | struct hci_ev_simple_pair_complete *ev = (void *) skb->data; |
@@ -2372,9 +2420,20 @@ static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_ | |||
2372 | hci_dev_lock(hdev); | 2420 | hci_dev_lock(hdev); |
2373 | 2421 | ||
2374 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | 2422 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); |
2375 | if (conn) | 2423 | if (!conn) |
2376 | hci_conn_put(conn); | 2424 | goto unlock; |
2377 | 2425 | ||
2426 | /* To avoid duplicate auth_failed events to user space we check | ||
2427 | * the HCI_CONN_AUTH_PEND flag which will be set if we | ||
2428 | * initiated the authentication. A traditional auth_complete | ||
2429 | * event gets always produced as initiator and is also mapped to | ||
2430 | * the mgmt_auth_failed event */ | ||
2431 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0) | ||
2432 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); | ||
2433 | |||
2434 | hci_conn_put(conn); | ||
2435 | |||
2436 | unlock: | ||
2378 | hci_dev_unlock(hdev); | 2437 | hci_dev_unlock(hdev); |
2379 | } | 2438 | } |
2380 | 2439 | ||
@@ -2580,6 +2639,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
2580 | hci_io_capa_reply_evt(hdev, skb); | 2639 | hci_io_capa_reply_evt(hdev, skb); |
2581 | break; | 2640 | break; |
2582 | 2641 | ||
2642 | case HCI_EV_USER_CONFIRM_REQUEST: | ||
2643 | hci_user_confirm_request_evt(hdev, skb); | ||
2644 | break; | ||
2645 | |||
2583 | case HCI_EV_SIMPLE_PAIR_COMPLETE: | 2646 | case HCI_EV_SIMPLE_PAIR_COMPLETE: |
2584 | hci_simple_pair_complete_evt(hdev, skb); | 2647 | hci_simple_pair_complete_evt(hdev, skb); |
2585 | break; | 2648 | break; |