diff options
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r-- | net/bluetooth/hci_event.c | 152 |
1 files changed, 126 insertions, 26 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index a89cf1f24e47..35cb56ed3b0b 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -55,8 +55,12 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) | |||
55 | 55 | ||
56 | BT_DBG("%s status 0x%x", hdev->name, status); | 56 | BT_DBG("%s status 0x%x", hdev->name, status); |
57 | 57 | ||
58 | if (status) | 58 | if (status) { |
59 | hci_dev_lock(hdev); | ||
60 | mgmt_stop_discovery_failed(hdev, status); | ||
61 | hci_dev_unlock(hdev); | ||
59 | return; | 62 | return; |
63 | } | ||
60 | 64 | ||
61 | clear_bit(HCI_INQUIRY, &hdev->flags); | 65 | clear_bit(HCI_INQUIRY, &hdev->flags); |
62 | 66 | ||
@@ -190,6 +194,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) | |||
190 | clear_bit(HCI_RESET, &hdev->flags); | 194 | clear_bit(HCI_RESET, &hdev->flags); |
191 | 195 | ||
192 | hci_req_complete(hdev, HCI_OP_RESET, status); | 196 | hci_req_complete(hdev, HCI_OP_RESET, status); |
197 | |||
198 | hdev->dev_flags = 0; | ||
193 | } | 199 | } |
194 | 200 | ||
195 | static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) | 201 | static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -494,7 +500,7 @@ static void hci_setup_event_mask(struct hci_dev *hdev) | |||
494 | 500 | ||
495 | /* CSR 1.1 dongles does not accept any bitfield so don't try to set | 501 | /* CSR 1.1 dongles does not accept any bitfield so don't try to set |
496 | * any event mask for pre 1.2 devices */ | 502 | * any event mask for pre 1.2 devices */ |
497 | if (hdev->lmp_ver <= 1) | 503 | if (hdev->hci_ver < BLUETOOTH_VER_1_2) |
498 | return; | 504 | return; |
499 | 505 | ||
500 | events[4] |= 0x01; /* Flow Specification Complete */ | 506 | events[4] |= 0x01; /* Flow Specification Complete */ |
@@ -558,7 +564,7 @@ static void hci_setup(struct hci_dev *hdev) | |||
558 | { | 564 | { |
559 | hci_setup_event_mask(hdev); | 565 | hci_setup_event_mask(hdev); |
560 | 566 | ||
561 | if (hdev->lmp_ver > 1) | 567 | if (hdev->hci_ver > BLUETOOTH_VER_1_1) |
562 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); | 568 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); |
563 | 569 | ||
564 | if (hdev->features[6] & LMP_SIMPLE_PAIR) { | 570 | if (hdev->features[6] & LMP_SIMPLE_PAIR) { |
@@ -713,6 +719,21 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev, | |||
713 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status); | 719 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status); |
714 | } | 720 | } |
715 | 721 | ||
722 | static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, | ||
723 | struct sk_buff *skb) | ||
724 | { | ||
725 | struct hci_rp_read_flow_control_mode *rp = (void *) skb->data; | ||
726 | |||
727 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
728 | |||
729 | if (rp->status) | ||
730 | return; | ||
731 | |||
732 | hdev->flow_ctl_mode = rp->mode; | ||
733 | |||
734 | hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status); | ||
735 | } | ||
736 | |||
716 | static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) | 737 | static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) |
717 | { | 738 | { |
718 | struct hci_rp_read_buffer_size *rp = (void *) skb->data; | 739 | struct hci_rp_read_buffer_size *rp = (void *) skb->data; |
@@ -927,6 +948,37 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, | |||
927 | hci_dev_unlock(hdev); | 948 | hci_dev_unlock(hdev); |
928 | } | 949 | } |
929 | 950 | ||
951 | static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb) | ||
952 | { | ||
953 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; | ||
954 | |||
955 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
956 | |||
957 | hci_dev_lock(hdev); | ||
958 | |||
959 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
960 | mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, | ||
961 | rp->status); | ||
962 | |||
963 | hci_dev_unlock(hdev); | ||
964 | } | ||
965 | |||
966 | static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, | ||
967 | struct sk_buff *skb) | ||
968 | { | ||
969 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; | ||
970 | |||
971 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
972 | |||
973 | hci_dev_lock(hdev); | ||
974 | |||
975 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
976 | mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr, | ||
977 | rp->status); | ||
978 | |||
979 | hci_dev_unlock(hdev); | ||
980 | } | ||
981 | |||
930 | static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, | 982 | static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, |
931 | struct sk_buff *skb) | 983 | struct sk_buff *skb) |
932 | { | 984 | { |
@@ -940,6 +992,13 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, | |||
940 | hci_dev_unlock(hdev); | 992 | hci_dev_unlock(hdev); |
941 | } | 993 | } |
942 | 994 | ||
995 | static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) | ||
996 | { | ||
997 | __u8 status = *((__u8 *) skb->data); | ||
998 | |||
999 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
1000 | } | ||
1001 | |||
943 | static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | 1002 | static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, |
944 | struct sk_buff *skb) | 1003 | struct sk_buff *skb) |
945 | { | 1004 | { |
@@ -956,12 +1015,16 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | |||
956 | return; | 1015 | return; |
957 | 1016 | ||
958 | if (cp->enable == 0x01) { | 1017 | if (cp->enable == 0x01) { |
1018 | set_bit(HCI_LE_SCAN, &hdev->dev_flags); | ||
1019 | |||
959 | del_timer(&hdev->adv_timer); | 1020 | del_timer(&hdev->adv_timer); |
960 | 1021 | ||
961 | hci_dev_lock(hdev); | 1022 | hci_dev_lock(hdev); |
962 | hci_adv_entries_clear(hdev); | 1023 | hci_adv_entries_clear(hdev); |
963 | hci_dev_unlock(hdev); | 1024 | hci_dev_unlock(hdev); |
964 | } else if (cp->enable == 0x00) { | 1025 | } else if (cp->enable == 0x00) { |
1026 | clear_bit(HCI_LE_SCAN, &hdev->dev_flags); | ||
1027 | |||
965 | mod_timer(&hdev->adv_timer, jiffies + ADV_CLEAR_TIMEOUT); | 1028 | mod_timer(&hdev->adv_timer, jiffies + ADV_CLEAR_TIMEOUT); |
966 | } | 1029 | } |
967 | } | 1030 | } |
@@ -1014,7 +1077,7 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | |||
1014 | hci_conn_check_pending(hdev); | 1077 | hci_conn_check_pending(hdev); |
1015 | hci_dev_lock(hdev); | 1078 | hci_dev_lock(hdev); |
1016 | if (test_bit(HCI_MGMT, &hdev->flags)) | 1079 | if (test_bit(HCI_MGMT, &hdev->flags)) |
1017 | mgmt_inquiry_failed(hdev, status); | 1080 | mgmt_start_discovery_failed(hdev, status); |
1018 | hci_dev_unlock(hdev); | 1081 | hci_dev_unlock(hdev); |
1019 | return; | 1082 | return; |
1020 | } | 1083 | } |
@@ -1437,7 +1500,7 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * | |||
1437 | data.rssi = 0x00; | 1500 | data.rssi = 0x00; |
1438 | data.ssp_mode = 0x00; | 1501 | data.ssp_mode = 0x00; |
1439 | hci_inquiry_cache_update(hdev, &data); | 1502 | hci_inquiry_cache_update(hdev, &data); |
1440 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, | 1503 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, |
1441 | info->dev_class, 0, NULL); | 1504 | info->dev_class, 0, NULL); |
1442 | } | 1505 | } |
1443 | 1506 | ||
@@ -1472,7 +1535,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1472 | conn->state = BT_CONFIG; | 1535 | conn->state = BT_CONFIG; |
1473 | hci_conn_hold(conn); | 1536 | hci_conn_hold(conn); |
1474 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 1537 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
1475 | mgmt_connected(hdev, &ev->bdaddr, conn->type); | 1538 | mgmt_connected(hdev, &ev->bdaddr, conn->type, |
1539 | conn->dst_type); | ||
1476 | } else | 1540 | } else |
1477 | conn->state = BT_CONNECTED; | 1541 | conn->state = BT_CONNECTED; |
1478 | 1542 | ||
@@ -1494,7 +1558,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1494 | } | 1558 | } |
1495 | 1559 | ||
1496 | /* Set packet type for incoming connection */ | 1560 | /* Set packet type for incoming connection */ |
1497 | if (!conn->out && hdev->hci_ver < 3) { | 1561 | if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) { |
1498 | struct hci_cp_change_conn_ptype cp; | 1562 | struct hci_cp_change_conn_ptype cp; |
1499 | cp.handle = ev->handle; | 1563 | cp.handle = ev->handle; |
1500 | cp.pkt_type = cpu_to_le16(conn->pkt_type); | 1564 | cp.pkt_type = cpu_to_le16(conn->pkt_type); |
@@ -1505,7 +1569,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1505 | conn->state = BT_CLOSED; | 1569 | conn->state = BT_CLOSED; |
1506 | if (conn->type == ACL_LINK) | 1570 | if (conn->type == ACL_LINK) |
1507 | mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, | 1571 | mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, |
1508 | ev->status); | 1572 | conn->dst_type, ev->status); |
1509 | } | 1573 | } |
1510 | 1574 | ||
1511 | if (conn->type == ACL_LINK) | 1575 | if (conn->type == ACL_LINK) |
@@ -1604,26 +1668,27 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
1604 | 1668 | ||
1605 | BT_DBG("%s status %d", hdev->name, ev->status); | 1669 | BT_DBG("%s status %d", hdev->name, ev->status); |
1606 | 1670 | ||
1607 | if (ev->status) { | ||
1608 | hci_dev_lock(hdev); | ||
1609 | mgmt_disconnect_failed(hdev); | ||
1610 | hci_dev_unlock(hdev); | ||
1611 | return; | ||
1612 | } | ||
1613 | |||
1614 | hci_dev_lock(hdev); | 1671 | hci_dev_lock(hdev); |
1615 | 1672 | ||
1616 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | 1673 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
1617 | if (!conn) | 1674 | if (!conn) |
1618 | goto unlock; | 1675 | goto unlock; |
1619 | 1676 | ||
1620 | conn->state = BT_CLOSED; | 1677 | if (ev->status == 0) |
1678 | conn->state = BT_CLOSED; | ||
1621 | 1679 | ||
1622 | if (conn->type == ACL_LINK || conn->type == LE_LINK) | 1680 | if (conn->type == ACL_LINK || conn->type == LE_LINK) { |
1623 | mgmt_disconnected(hdev, &conn->dst, conn->type); | 1681 | if (ev->status != 0) |
1682 | mgmt_disconnect_failed(hdev, &conn->dst, ev->status); | ||
1683 | else | ||
1684 | mgmt_disconnected(hdev, &conn->dst, conn->type, | ||
1685 | conn->dst_type); | ||
1686 | } | ||
1624 | 1687 | ||
1625 | hci_proto_disconn_cfm(conn, ev->reason); | 1688 | if (ev->status == 0) { |
1626 | hci_conn_del(conn); | 1689 | hci_proto_disconn_cfm(conn, ev->reason); |
1690 | hci_conn_del(conn); | ||
1691 | } | ||
1627 | 1692 | ||
1628 | unlock: | 1693 | unlock: |
1629 | hci_dev_unlock(hdev); | 1694 | hci_dev_unlock(hdev); |
@@ -1961,6 +2026,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1961 | hci_cc_write_ca_timeout(hdev, skb); | 2026 | hci_cc_write_ca_timeout(hdev, skb); |
1962 | break; | 2027 | break; |
1963 | 2028 | ||
2029 | case HCI_OP_READ_FLOW_CONTROL_MODE: | ||
2030 | hci_cc_read_flow_control_mode(hdev, skb); | ||
2031 | break; | ||
2032 | |||
1964 | case HCI_OP_READ_LOCAL_AMP_INFO: | 2033 | case HCI_OP_READ_LOCAL_AMP_INFO: |
1965 | hci_cc_read_local_amp_info(hdev, skb); | 2034 | hci_cc_read_local_amp_info(hdev, skb); |
1966 | break; | 2035 | break; |
@@ -2009,6 +2078,17 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
2009 | hci_cc_user_confirm_neg_reply(hdev, skb); | 2078 | hci_cc_user_confirm_neg_reply(hdev, skb); |
2010 | break; | 2079 | break; |
2011 | 2080 | ||
2081 | case HCI_OP_USER_PASSKEY_REPLY: | ||
2082 | hci_cc_user_passkey_reply(hdev, skb); | ||
2083 | break; | ||
2084 | |||
2085 | case HCI_OP_USER_PASSKEY_NEG_REPLY: | ||
2086 | hci_cc_user_passkey_neg_reply(hdev, skb); | ||
2087 | |||
2088 | case HCI_OP_LE_SET_SCAN_PARAM: | ||
2089 | hci_cc_le_set_scan_param(hdev, skb); | ||
2090 | break; | ||
2091 | |||
2012 | case HCI_OP_LE_SET_SCAN_ENABLE: | 2092 | case HCI_OP_LE_SET_SCAN_ENABLE: |
2013 | hci_cc_le_set_scan_enable(hdev, skb); | 2093 | hci_cc_le_set_scan_enable(hdev, skb); |
2014 | break; | 2094 | break; |
@@ -2096,7 +2176,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2096 | 2176 | ||
2097 | case HCI_OP_DISCONNECT: | 2177 | case HCI_OP_DISCONNECT: |
2098 | if (ev->status != 0) | 2178 | if (ev->status != 0) |
2099 | mgmt_disconnect_failed(hdev); | 2179 | mgmt_disconnect_failed(hdev, NULL, ev->status); |
2100 | break; | 2180 | break; |
2101 | 2181 | ||
2102 | case HCI_OP_LE_CREATE_CONN: | 2182 | case HCI_OP_LE_CREATE_CONN: |
@@ -2444,7 +2524,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct | |||
2444 | data.rssi = info->rssi; | 2524 | data.rssi = info->rssi; |
2445 | data.ssp_mode = 0x00; | 2525 | data.ssp_mode = 0x00; |
2446 | hci_inquiry_cache_update(hdev, &data); | 2526 | hci_inquiry_cache_update(hdev, &data); |
2447 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, | 2527 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, |
2448 | info->dev_class, info->rssi, | 2528 | info->dev_class, info->rssi, |
2449 | NULL); | 2529 | NULL); |
2450 | } | 2530 | } |
@@ -2461,7 +2541,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct | |||
2461 | data.rssi = info->rssi; | 2541 | data.rssi = info->rssi; |
2462 | data.ssp_mode = 0x00; | 2542 | data.ssp_mode = 0x00; |
2463 | hci_inquiry_cache_update(hdev, &data); | 2543 | hci_inquiry_cache_update(hdev, &data); |
2464 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, | 2544 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, |
2465 | info->dev_class, info->rssi, | 2545 | info->dev_class, info->rssi, |
2466 | NULL); | 2546 | NULL); |
2467 | } | 2547 | } |
@@ -2604,7 +2684,7 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct | |||
2604 | data.rssi = info->rssi; | 2684 | data.rssi = info->rssi; |
2605 | data.ssp_mode = 0x01; | 2685 | data.ssp_mode = 0x01; |
2606 | hci_inquiry_cache_update(hdev, &data); | 2686 | hci_inquiry_cache_update(hdev, &data); |
2607 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, | 2687 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, |
2608 | info->dev_class, info->rssi, info->data); | 2688 | info->dev_class, info->rssi, info->data); |
2609 | } | 2689 | } |
2610 | 2690 | ||
@@ -2768,6 +2848,21 @@ unlock: | |||
2768 | hci_dev_unlock(hdev); | 2848 | hci_dev_unlock(hdev); |
2769 | } | 2849 | } |
2770 | 2850 | ||
2851 | static inline void hci_user_passkey_request_evt(struct hci_dev *hdev, | ||
2852 | struct sk_buff *skb) | ||
2853 | { | ||
2854 | struct hci_ev_user_passkey_req *ev = (void *) skb->data; | ||
2855 | |||
2856 | BT_DBG("%s", hdev->name); | ||
2857 | |||
2858 | hci_dev_lock(hdev); | ||
2859 | |||
2860 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
2861 | mgmt_user_passkey_request(hdev, &ev->bdaddr); | ||
2862 | |||
2863 | hci_dev_unlock(hdev); | ||
2864 | } | ||
2865 | |||
2771 | static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2866 | static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
2772 | { | 2867 | { |
2773 | struct hci_ev_simple_pair_complete *ev = (void *) skb->data; | 2868 | struct hci_ev_simple_pair_complete *ev = (void *) skb->data; |
@@ -2868,14 +2963,15 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
2868 | } | 2963 | } |
2869 | 2964 | ||
2870 | if (ev->status) { | 2965 | if (ev->status) { |
2871 | mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, ev->status); | 2966 | mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, |
2967 | conn->dst_type, ev->status); | ||
2872 | hci_proto_connect_cfm(conn, ev->status); | 2968 | hci_proto_connect_cfm(conn, ev->status); |
2873 | conn->state = BT_CLOSED; | 2969 | conn->state = BT_CLOSED; |
2874 | hci_conn_del(conn); | 2970 | hci_conn_del(conn); |
2875 | goto unlock; | 2971 | goto unlock; |
2876 | } | 2972 | } |
2877 | 2973 | ||
2878 | mgmt_connected(hdev, &ev->bdaddr, conn->type); | 2974 | mgmt_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type); |
2879 | 2975 | ||
2880 | conn->sec_level = BT_SECURITY_LOW; | 2976 | conn->sec_level = BT_SECURITY_LOW; |
2881 | conn->handle = __le16_to_cpu(ev->handle); | 2977 | conn->handle = __le16_to_cpu(ev->handle); |
@@ -3106,6 +3202,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
3106 | hci_user_confirm_request_evt(hdev, skb); | 3202 | hci_user_confirm_request_evt(hdev, skb); |
3107 | break; | 3203 | break; |
3108 | 3204 | ||
3205 | case HCI_EV_USER_PASSKEY_REQUEST: | ||
3206 | hci_user_passkey_request_evt(hdev, skb); | ||
3207 | break; | ||
3208 | |||
3109 | case HCI_EV_SIMPLE_PAIR_COMPLETE: | 3209 | case HCI_EV_SIMPLE_PAIR_COMPLETE: |
3110 | hci_simple_pair_complete_evt(hdev, skb); | 3210 | hci_simple_pair_complete_evt(hdev, skb); |
3111 | break; | 3211 | break; |