diff options
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r-- | net/bluetooth/hci_event.c | 167 |
1 files changed, 156 insertions, 11 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 2022b43c7353..0383635f91fb 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <net/bluetooth/bluetooth.h> | 30 | #include <net/bluetooth/bluetooth.h> |
31 | #include <net/bluetooth/hci_core.h> | 31 | #include <net/bluetooth/hci_core.h> |
32 | #include <net/bluetooth/mgmt.h> | 32 | #include <net/bluetooth/mgmt.h> |
33 | #include <net/bluetooth/a2mp.h> | ||
34 | #include <net/bluetooth/amp.h> | ||
33 | 35 | ||
34 | /* Handle HCI Event packets */ | 36 | /* Handle HCI Event packets */ |
35 | 37 | ||
@@ -846,7 +848,7 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev, | |||
846 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); | 848 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
847 | 849 | ||
848 | if (rp->status) | 850 | if (rp->status) |
849 | return; | 851 | goto a2mp_rsp; |
850 | 852 | ||
851 | hdev->amp_status = rp->amp_status; | 853 | hdev->amp_status = rp->amp_status; |
852 | hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); | 854 | hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); |
@@ -860,6 +862,46 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev, | |||
860 | hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); | 862 | hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); |
861 | 863 | ||
862 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status); | 864 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status); |
865 | |||
866 | a2mp_rsp: | ||
867 | a2mp_send_getinfo_rsp(hdev); | ||
868 | } | ||
869 | |||
870 | static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev, | ||
871 | struct sk_buff *skb) | ||
872 | { | ||
873 | struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data; | ||
874 | struct amp_assoc *assoc = &hdev->loc_assoc; | ||
875 | size_t rem_len, frag_len; | ||
876 | |||
877 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); | ||
878 | |||
879 | if (rp->status) | ||
880 | goto a2mp_rsp; | ||
881 | |||
882 | frag_len = skb->len - sizeof(*rp); | ||
883 | rem_len = __le16_to_cpu(rp->rem_len); | ||
884 | |||
885 | if (rem_len > frag_len) { | ||
886 | BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len); | ||
887 | |||
888 | memcpy(assoc->data + assoc->offset, rp->frag, frag_len); | ||
889 | assoc->offset += frag_len; | ||
890 | |||
891 | /* Read other fragments */ | ||
892 | amp_read_loc_assoc_frag(hdev, rp->phy_handle); | ||
893 | |||
894 | return; | ||
895 | } | ||
896 | |||
897 | memcpy(assoc->data + assoc->offset, rp->frag, rem_len); | ||
898 | assoc->len = assoc->offset + rem_len; | ||
899 | assoc->offset = 0; | ||
900 | |||
901 | a2mp_rsp: | ||
902 | /* Send A2MP Rsp when all fragments are received */ | ||
903 | a2mp_send_getampassoc_rsp(hdev, rp->status); | ||
904 | a2mp_send_create_phy_link_req(hdev, rp->status); | ||
863 | } | 905 | } |
864 | 906 | ||
865 | static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, | 907 | static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, |
@@ -1174,6 +1216,20 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev, | |||
1174 | hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status); | 1216 | hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status); |
1175 | } | 1217 | } |
1176 | 1218 | ||
1219 | static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev, | ||
1220 | struct sk_buff *skb) | ||
1221 | { | ||
1222 | struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data; | ||
1223 | |||
1224 | BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x", | ||
1225 | hdev->name, rp->status, rp->phy_handle); | ||
1226 | |||
1227 | if (rp->status) | ||
1228 | return; | ||
1229 | |||
1230 | amp_write_rem_assoc_continue(hdev, rp->phy_handle); | ||
1231 | } | ||
1232 | |||
1177 | static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | 1233 | static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) |
1178 | { | 1234 | { |
1179 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | 1235 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
@@ -1210,7 +1266,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) | |||
1210 | 1266 | ||
1211 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); | 1267 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); |
1212 | 1268 | ||
1213 | BT_DBG("%s bdaddr %s hcon %p", hdev->name, batostr(&cp->bdaddr), conn); | 1269 | BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn); |
1214 | 1270 | ||
1215 | if (status) { | 1271 | if (status) { |
1216 | if (conn && conn->state == BT_CONNECT) { | 1272 | if (conn && conn->state == BT_CONNECT) { |
@@ -1639,8 +1695,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) | |||
1639 | return; | 1695 | return; |
1640 | } | 1696 | } |
1641 | 1697 | ||
1642 | BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&conn->dst), | 1698 | BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn); |
1643 | conn); | ||
1644 | 1699 | ||
1645 | conn->state = BT_CLOSED; | 1700 | conn->state = BT_CLOSED; |
1646 | mgmt_connect_failed(hdev, &conn->dst, conn->type, | 1701 | mgmt_connect_failed(hdev, &conn->dst, conn->type, |
@@ -1657,6 +1712,38 @@ static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) | |||
1657 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | 1712 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1658 | } | 1713 | } |
1659 | 1714 | ||
1715 | static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status) | ||
1716 | { | ||
1717 | struct hci_cp_create_phy_link *cp; | ||
1718 | |||
1719 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | ||
1720 | |||
1721 | if (status) | ||
1722 | return; | ||
1723 | |||
1724 | cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK); | ||
1725 | if (!cp) | ||
1726 | return; | ||
1727 | |||
1728 | amp_write_remote_assoc(hdev, cp->phy_handle); | ||
1729 | } | ||
1730 | |||
1731 | static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status) | ||
1732 | { | ||
1733 | struct hci_cp_accept_phy_link *cp; | ||
1734 | |||
1735 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | ||
1736 | |||
1737 | if (status) | ||
1738 | return; | ||
1739 | |||
1740 | cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK); | ||
1741 | if (!cp) | ||
1742 | return; | ||
1743 | |||
1744 | amp_write_remote_assoc(hdev, cp->phy_handle); | ||
1745 | } | ||
1746 | |||
1660 | static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1747 | static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
1661 | { | 1748 | { |
1662 | __u8 status = *((__u8 *) skb->data); | 1749 | __u8 status = *((__u8 *) skb->data); |
@@ -1822,7 +1909,7 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1822 | struct hci_ev_conn_request *ev = (void *) skb->data; | 1909 | struct hci_ev_conn_request *ev = (void *) skb->data; |
1823 | int mask = hdev->link_mode; | 1910 | int mask = hdev->link_mode; |
1824 | 1911 | ||
1825 | BT_DBG("%s bdaddr %s type 0x%x", hdev->name, batostr(&ev->bdaddr), | 1912 | BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr, |
1826 | ev->link_type); | 1913 | ev->link_type); |
1827 | 1914 | ||
1828 | mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); | 1915 | mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); |
@@ -2314,6 +2401,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2314 | hci_cc_read_local_amp_info(hdev, skb); | 2401 | hci_cc_read_local_amp_info(hdev, skb); |
2315 | break; | 2402 | break; |
2316 | 2403 | ||
2404 | case HCI_OP_READ_LOCAL_AMP_ASSOC: | ||
2405 | hci_cc_read_local_amp_assoc(hdev, skb); | ||
2406 | break; | ||
2407 | |||
2317 | case HCI_OP_DELETE_STORED_LINK_KEY: | 2408 | case HCI_OP_DELETE_STORED_LINK_KEY: |
2318 | hci_cc_delete_stored_link_key(hdev, skb); | 2409 | hci_cc_delete_stored_link_key(hdev, skb); |
2319 | break; | 2410 | break; |
@@ -2386,6 +2477,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2386 | hci_cc_write_le_host_supported(hdev, skb); | 2477 | hci_cc_write_le_host_supported(hdev, skb); |
2387 | break; | 2478 | break; |
2388 | 2479 | ||
2480 | case HCI_OP_WRITE_REMOTE_AMP_ASSOC: | ||
2481 | hci_cc_write_remote_amp_assoc(hdev, skb); | ||
2482 | break; | ||
2483 | |||
2389 | default: | 2484 | default: |
2390 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); | 2485 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); |
2391 | break; | 2486 | break; |
@@ -2467,6 +2562,14 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2467 | hci_cs_le_start_enc(hdev, ev->status); | 2562 | hci_cs_le_start_enc(hdev, ev->status); |
2468 | break; | 2563 | break; |
2469 | 2564 | ||
2565 | case HCI_OP_CREATE_PHY_LINK: | ||
2566 | hci_cs_create_phylink(hdev, ev->status); | ||
2567 | break; | ||
2568 | |||
2569 | case HCI_OP_ACCEPT_PHY_LINK: | ||
2570 | hci_cs_accept_phylink(hdev, ev->status); | ||
2571 | break; | ||
2572 | |||
2470 | default: | 2573 | default: |
2471 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); | 2574 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); |
2472 | break; | 2575 | break; |
@@ -2574,6 +2677,27 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2574 | queue_work(hdev->workqueue, &hdev->tx_work); | 2677 | queue_work(hdev->workqueue, &hdev->tx_work); |
2575 | } | 2678 | } |
2576 | 2679 | ||
2680 | static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev, | ||
2681 | __u16 handle) | ||
2682 | { | ||
2683 | struct hci_chan *chan; | ||
2684 | |||
2685 | switch (hdev->dev_type) { | ||
2686 | case HCI_BREDR: | ||
2687 | return hci_conn_hash_lookup_handle(hdev, handle); | ||
2688 | case HCI_AMP: | ||
2689 | chan = hci_chan_lookup_handle(hdev, handle); | ||
2690 | if (chan) | ||
2691 | return chan->conn; | ||
2692 | break; | ||
2693 | default: | ||
2694 | BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); | ||
2695 | break; | ||
2696 | } | ||
2697 | |||
2698 | return NULL; | ||
2699 | } | ||
2700 | |||
2577 | static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2701 | static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) |
2578 | { | 2702 | { |
2579 | struct hci_ev_num_comp_blocks *ev = (void *) skb->data; | 2703 | struct hci_ev_num_comp_blocks *ev = (void *) skb->data; |
@@ -2595,13 +2719,13 @@ static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2595 | 2719 | ||
2596 | for (i = 0; i < ev->num_hndl; i++) { | 2720 | for (i = 0; i < ev->num_hndl; i++) { |
2597 | struct hci_comp_blocks_info *info = &ev->handles[i]; | 2721 | struct hci_comp_blocks_info *info = &ev->handles[i]; |
2598 | struct hci_conn *conn; | 2722 | struct hci_conn *conn = NULL; |
2599 | __u16 handle, block_count; | 2723 | __u16 handle, block_count; |
2600 | 2724 | ||
2601 | handle = __le16_to_cpu(info->handle); | 2725 | handle = __le16_to_cpu(info->handle); |
2602 | block_count = __le16_to_cpu(info->blocks); | 2726 | block_count = __le16_to_cpu(info->blocks); |
2603 | 2727 | ||
2604 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 2728 | conn = __hci_conn_lookup_handle(hdev, handle); |
2605 | if (!conn) | 2729 | if (!conn) |
2606 | continue; | 2730 | continue; |
2607 | 2731 | ||
@@ -2609,6 +2733,7 @@ static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2609 | 2733 | ||
2610 | switch (conn->type) { | 2734 | switch (conn->type) { |
2611 | case ACL_LINK: | 2735 | case ACL_LINK: |
2736 | case AMP_LINK: | ||
2612 | hdev->block_cnt += block_count; | 2737 | hdev->block_cnt += block_count; |
2613 | if (hdev->block_cnt > hdev->num_blocks) | 2738 | if (hdev->block_cnt > hdev->num_blocks) |
2614 | hdev->block_cnt = hdev->num_blocks; | 2739 | hdev->block_cnt = hdev->num_blocks; |
@@ -2705,13 +2830,13 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2705 | 2830 | ||
2706 | key = hci_find_link_key(hdev, &ev->bdaddr); | 2831 | key = hci_find_link_key(hdev, &ev->bdaddr); |
2707 | if (!key) { | 2832 | if (!key) { |
2708 | BT_DBG("%s link key not found for %s", hdev->name, | 2833 | BT_DBG("%s link key not found for %pMR", hdev->name, |
2709 | batostr(&ev->bdaddr)); | 2834 | &ev->bdaddr); |
2710 | goto not_found; | 2835 | goto not_found; |
2711 | } | 2836 | } |
2712 | 2837 | ||
2713 | BT_DBG("%s found key type %u for %s", hdev->name, key->type, | 2838 | BT_DBG("%s found key type %u for %pMR", hdev->name, key->type, |
2714 | batostr(&ev->bdaddr)); | 2839 | &ev->bdaddr); |
2715 | 2840 | ||
2716 | if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) && | 2841 | if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) && |
2717 | key->type == HCI_LK_DEBUG_COMBINATION) { | 2842 | key->type == HCI_LK_DEBUG_COMBINATION) { |
@@ -3558,6 +3683,22 @@ static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
3558 | } | 3683 | } |
3559 | } | 3684 | } |
3560 | 3685 | ||
3686 | static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
3687 | { | ||
3688 | struct hci_ev_channel_selected *ev = (void *) skb->data; | ||
3689 | struct hci_conn *hcon; | ||
3690 | |||
3691 | BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle); | ||
3692 | |||
3693 | skb_pull(skb, sizeof(*ev)); | ||
3694 | |||
3695 | hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); | ||
3696 | if (!hcon) | ||
3697 | return; | ||
3698 | |||
3699 | amp_read_loc_assoc_final_data(hdev, hcon); | ||
3700 | } | ||
3701 | |||
3561 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | 3702 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) |
3562 | { | 3703 | { |
3563 | struct hci_event_hdr *hdr = (void *) skb->data; | 3704 | struct hci_event_hdr *hdr = (void *) skb->data; |
@@ -3722,6 +3863,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
3722 | hci_le_meta_evt(hdev, skb); | 3863 | hci_le_meta_evt(hdev, skb); |
3723 | break; | 3864 | break; |
3724 | 3865 | ||
3866 | case HCI_EV_CHANNEL_SELECTED: | ||
3867 | hci_chan_selected_evt(hdev, skb); | ||
3868 | break; | ||
3869 | |||
3725 | case HCI_EV_REMOTE_OOB_DATA_REQUEST: | 3870 | case HCI_EV_REMOTE_OOB_DATA_REQUEST: |
3726 | hci_remote_oob_data_request_evt(hdev, skb); | 3871 | hci_remote_oob_data_request_evt(hdev, skb); |
3727 | break; | 3872 | break; |