diff options
Diffstat (limited to 'net/bluetooth/hci_event.c')
| -rw-r--r-- | net/bluetooth/hci_event.c | 233 |
1 files changed, 202 insertions, 31 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index eb64555d1fb3..d43d0c890975 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
| @@ -24,7 +24,6 @@ | |||
| 24 | 24 | ||
| 25 | /* Bluetooth HCI event handling. */ | 25 | /* Bluetooth HCI event handling. */ |
| 26 | 26 | ||
| 27 | #include <linux/config.h> | ||
| 28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 29 | 28 | ||
| 30 | #include <linux/types.h> | 29 | #include <linux/types.h> |
| @@ -63,6 +62,7 @@ static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb | |||
| 63 | 62 | ||
| 64 | switch (ocf) { | 63 | switch (ocf) { |
| 65 | case OCF_INQUIRY_CANCEL: | 64 | case OCF_INQUIRY_CANCEL: |
| 65 | case OCF_EXIT_PERIODIC_INQ: | ||
| 66 | status = *((__u8 *) skb->data); | 66 | status = *((__u8 *) skb->data); |
| 67 | 67 | ||
| 68 | if (status) { | 68 | if (status) { |
| @@ -84,6 +84,8 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff * | |||
| 84 | { | 84 | { |
| 85 | struct hci_conn *conn; | 85 | struct hci_conn *conn; |
| 86 | struct hci_rp_role_discovery *rd; | 86 | struct hci_rp_role_discovery *rd; |
| 87 | struct hci_rp_write_link_policy *lp; | ||
| 88 | void *sent; | ||
| 87 | 89 | ||
| 88 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); | 90 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); |
| 89 | 91 | ||
| @@ -107,6 +109,27 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff * | |||
| 107 | hci_dev_unlock(hdev); | 109 | hci_dev_unlock(hdev); |
| 108 | break; | 110 | break; |
| 109 | 111 | ||
| 112 | case OCF_WRITE_LINK_POLICY: | ||
| 113 | sent = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY); | ||
| 114 | if (!sent) | ||
| 115 | break; | ||
| 116 | |||
| 117 | lp = (struct hci_rp_write_link_policy *) skb->data; | ||
| 118 | |||
| 119 | if (lp->status) | ||
| 120 | break; | ||
| 121 | |||
| 122 | hci_dev_lock(hdev); | ||
| 123 | |||
| 124 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(lp->handle)); | ||
| 125 | if (conn) { | ||
| 126 | __le16 policy = get_unaligned((__le16 *) (sent + 2)); | ||
| 127 | conn->link_policy = __le16_to_cpu(policy); | ||
| 128 | } | ||
| 129 | |||
| 130 | hci_dev_unlock(hdev); | ||
| 131 | break; | ||
| 132 | |||
| 110 | default: | 133 | default: |
| 111 | BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x", | 134 | BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x", |
| 112 | hdev->name, ocf); | 135 | hdev->name, ocf); |
| @@ -275,15 +298,33 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb | |||
| 275 | /* Command Complete OGF INFO_PARAM */ | 298 | /* Command Complete OGF INFO_PARAM */ |
| 276 | static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) | 299 | static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) |
| 277 | { | 300 | { |
| 278 | struct hci_rp_read_loc_features *lf; | 301 | struct hci_rp_read_loc_version *lv; |
| 302 | struct hci_rp_read_local_features *lf; | ||
| 279 | struct hci_rp_read_buffer_size *bs; | 303 | struct hci_rp_read_buffer_size *bs; |
| 280 | struct hci_rp_read_bd_addr *ba; | 304 | struct hci_rp_read_bd_addr *ba; |
| 281 | 305 | ||
| 282 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); | 306 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); |
| 283 | 307 | ||
| 284 | switch (ocf) { | 308 | switch (ocf) { |
| 309 | case OCF_READ_LOCAL_VERSION: | ||
| 310 | lv = (struct hci_rp_read_loc_version *) skb->data; | ||
| 311 | |||
| 312 | if (lv->status) { | ||
| 313 | BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lf->status); | ||
| 314 | break; | ||
| 315 | } | ||
| 316 | |||
| 317 | hdev->hci_ver = lv->hci_ver; | ||
| 318 | hdev->hci_rev = btohs(lv->hci_rev); | ||
| 319 | hdev->manufacturer = btohs(lv->manufacturer); | ||
| 320 | |||
| 321 | BT_DBG("%s: manufacturer %d hci_ver %d hci_rev %d", hdev->name, | ||
| 322 | hdev->manufacturer, hdev->hci_ver, hdev->hci_rev); | ||
| 323 | |||
| 324 | break; | ||
| 325 | |||
| 285 | case OCF_READ_LOCAL_FEATURES: | 326 | case OCF_READ_LOCAL_FEATURES: |
| 286 | lf = (struct hci_rp_read_loc_features *) skb->data; | 327 | lf = (struct hci_rp_read_local_features *) skb->data; |
| 287 | 328 | ||
| 288 | if (lf->status) { | 329 | if (lf->status) { |
| 289 | BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status); | 330 | BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status); |
| @@ -306,7 +347,8 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s | |||
| 306 | if (hdev->features[1] & LMP_HV3) | 347 | if (hdev->features[1] & LMP_HV3) |
| 307 | hdev->pkt_type |= (HCI_HV3); | 348 | hdev->pkt_type |= (HCI_HV3); |
| 308 | 349 | ||
| 309 | BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]); | 350 | BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, |
| 351 | lf->features[0], lf->features[1], lf->features[2]); | ||
| 310 | 352 | ||
| 311 | break; | 353 | break; |
| 312 | 354 | ||
| @@ -320,9 +362,17 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s | |||
| 320 | } | 362 | } |
| 321 | 363 | ||
| 322 | hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu); | 364 | hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu); |
| 323 | hdev->sco_mtu = bs->sco_mtu ? bs->sco_mtu : 64; | 365 | hdev->sco_mtu = bs->sco_mtu; |
| 324 | hdev->acl_pkts = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt); | 366 | hdev->acl_pkts = __le16_to_cpu(bs->acl_max_pkt); |
| 325 | hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt); | 367 | hdev->sco_pkts = __le16_to_cpu(bs->sco_max_pkt); |
| 368 | |||
| 369 | if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) { | ||
| 370 | hdev->sco_mtu = 64; | ||
| 371 | hdev->sco_pkts = 8; | ||
| 372 | } | ||
| 373 | |||
| 374 | hdev->acl_cnt = hdev->acl_pkts; | ||
| 375 | hdev->sco_cnt = hdev->sco_pkts; | ||
| 326 | 376 | ||
| 327 | BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name, | 377 | BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name, |
| 328 | hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts); | 378 | hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts); |
| @@ -440,8 +490,46 @@ static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status) | |||
| 440 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); | 490 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); |
| 441 | 491 | ||
| 442 | switch (ocf) { | 492 | switch (ocf) { |
| 493 | case OCF_SNIFF_MODE: | ||
| 494 | if (status) { | ||
| 495 | struct hci_conn *conn; | ||
| 496 | struct hci_cp_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_SNIFF_MODE); | ||
| 497 | |||
| 498 | if (!cp) | ||
| 499 | break; | ||
| 500 | |||
| 501 | hci_dev_lock(hdev); | ||
| 502 | |||
| 503 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); | ||
| 504 | if (conn) { | ||
| 505 | clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); | ||
| 506 | } | ||
| 507 | |||
| 508 | hci_dev_unlock(hdev); | ||
| 509 | } | ||
| 510 | break; | ||
| 511 | |||
| 512 | case OCF_EXIT_SNIFF_MODE: | ||
| 513 | if (status) { | ||
| 514 | struct hci_conn *conn; | ||
| 515 | struct hci_cp_exit_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_EXIT_SNIFF_MODE); | ||
| 516 | |||
| 517 | if (!cp) | ||
| 518 | break; | ||
| 519 | |||
| 520 | hci_dev_lock(hdev); | ||
| 521 | |||
| 522 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); | ||
| 523 | if (conn) { | ||
| 524 | clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); | ||
| 525 | } | ||
| 526 | |||
| 527 | hci_dev_unlock(hdev); | ||
| 528 | } | ||
| 529 | break; | ||
| 530 | |||
| 443 | default: | 531 | default: |
| 444 | BT_DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf); | 532 | BT_DBG("%s Command status: ogf LINK_POLICY ocf %x", hdev->name, ocf); |
| 445 | break; | 533 | break; |
| 446 | } | 534 | } |
| 447 | } | 535 | } |
| @@ -623,14 +711,16 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
| 623 | else | 711 | else |
| 624 | cp.role = 0x01; /* Remain slave */ | 712 | cp.role = 0x01; /* Remain slave */ |
| 625 | 713 | ||
| 626 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp); | 714 | hci_send_cmd(hdev, OGF_LINK_CTL, |
| 715 | OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp); | ||
| 627 | } else { | 716 | } else { |
| 628 | /* Connection rejected */ | 717 | /* Connection rejected */ |
| 629 | struct hci_cp_reject_conn_req cp; | 718 | struct hci_cp_reject_conn_req cp; |
| 630 | 719 | ||
| 631 | bacpy(&cp.bdaddr, &ev->bdaddr); | 720 | bacpy(&cp.bdaddr, &ev->bdaddr); |
| 632 | cp.reason = 0x0f; | 721 | cp.reason = 0x0f; |
| 633 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ, sizeof(cp), &cp); | 722 | hci_send_cmd(hdev, OGF_LINK_CTL, |
| 723 | OCF_REJECT_CONN_REQ, sizeof(cp), &cp); | ||
| 634 | } | 724 | } |
| 635 | } | 725 | } |
| 636 | 726 | ||
| @@ -638,7 +728,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
| 638 | static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 728 | static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 639 | { | 729 | { |
| 640 | struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data; | 730 | struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data; |
| 641 | struct hci_conn *conn = NULL; | 731 | struct hci_conn *conn; |
| 642 | 732 | ||
| 643 | BT_DBG("%s", hdev->name); | 733 | BT_DBG("%s", hdev->name); |
| 644 | 734 | ||
| @@ -660,12 +750,21 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 660 | if (test_bit(HCI_ENCRYPT, &hdev->flags)) | 750 | if (test_bit(HCI_ENCRYPT, &hdev->flags)) |
| 661 | conn->link_mode |= HCI_LM_ENCRYPT; | 751 | conn->link_mode |= HCI_LM_ENCRYPT; |
| 662 | 752 | ||
| 753 | /* Get remote features */ | ||
| 754 | if (conn->type == ACL_LINK) { | ||
| 755 | struct hci_cp_read_remote_features cp; | ||
| 756 | cp.handle = ev->handle; | ||
| 757 | hci_send_cmd(hdev, OGF_LINK_CTL, | ||
| 758 | OCF_READ_REMOTE_FEATURES, sizeof(cp), &cp); | ||
| 759 | } | ||
| 760 | |||
| 663 | /* Set link policy */ | 761 | /* Set link policy */ |
| 664 | if (conn->type == ACL_LINK && hdev->link_policy) { | 762 | if (conn->type == ACL_LINK && hdev->link_policy) { |
| 665 | struct hci_cp_write_link_policy cp; | 763 | struct hci_cp_write_link_policy cp; |
| 666 | cp.handle = ev->handle; | 764 | cp.handle = ev->handle; |
| 667 | cp.policy = __cpu_to_le16(hdev->link_policy); | 765 | cp.policy = __cpu_to_le16(hdev->link_policy); |
| 668 | hci_send_cmd(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY, sizeof(cp), &cp); | 766 | hci_send_cmd(hdev, OGF_LINK_POLICY, |
| 767 | OCF_WRITE_LINK_POLICY, sizeof(cp), &cp); | ||
| 669 | } | 768 | } |
| 670 | 769 | ||
| 671 | /* Set packet type for incoming connection */ | 770 | /* Set packet type for incoming connection */ |
| @@ -676,7 +775,12 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 676 | __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK): | 775 | __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK): |
| 677 | __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK); | 776 | __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK); |
| 678 | 777 | ||
| 679 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp); | 778 | hci_send_cmd(hdev, OGF_LINK_CTL, |
| 779 | OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp); | ||
| 780 | } else { | ||
| 781 | /* Update disconnect timer */ | ||
| 782 | hci_conn_hold(conn); | ||
| 783 | hci_conn_put(conn); | ||
| 680 | } | 784 | } |
| 681 | } else | 785 | } else |
| 682 | conn->state = BT_CLOSED; | 786 | conn->state = BT_CLOSED; |
| @@ -704,8 +808,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 704 | static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 808 | static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 705 | { | 809 | { |
| 706 | struct hci_ev_disconn_complete *ev = (struct hci_ev_disconn_complete *) skb->data; | 810 | struct hci_ev_disconn_complete *ev = (struct hci_ev_disconn_complete *) skb->data; |
| 707 | struct hci_conn *conn = NULL; | 811 | struct hci_conn *conn; |
| 708 | __u16 handle = __le16_to_cpu(ev->handle); | ||
| 709 | 812 | ||
| 710 | BT_DBG("%s status %d", hdev->name, ev->status); | 813 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 711 | 814 | ||
| @@ -714,7 +817,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
| 714 | 817 | ||
| 715 | hci_dev_lock(hdev); | 818 | hci_dev_lock(hdev); |
| 716 | 819 | ||
| 717 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 820 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 718 | if (conn) { | 821 | if (conn) { |
| 719 | conn->state = BT_CLOSED; | 822 | conn->state = BT_CLOSED; |
| 720 | hci_proto_disconn_ind(conn, ev->reason); | 823 | hci_proto_disconn_ind(conn, ev->reason); |
| @@ -771,7 +874,7 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 771 | static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | 874 | static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 772 | { | 875 | { |
| 773 | struct hci_ev_role_change *ev = (struct hci_ev_role_change *) skb->data; | 876 | struct hci_ev_role_change *ev = (struct hci_ev_role_change *) skb->data; |
| 774 | struct hci_conn *conn = NULL; | 877 | struct hci_conn *conn; |
| 775 | 878 | ||
| 776 | BT_DBG("%s status %d", hdev->name, ev->status); | 879 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 777 | 880 | ||
| @@ -794,18 +897,43 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb | |||
| 794 | hci_dev_unlock(hdev); | 897 | hci_dev_unlock(hdev); |
| 795 | } | 898 | } |
| 796 | 899 | ||
| 900 | /* Mode Change */ | ||
| 901 | static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
| 902 | { | ||
| 903 | struct hci_ev_mode_change *ev = (struct hci_ev_mode_change *) skb->data; | ||
| 904 | struct hci_conn *conn; | ||
| 905 | |||
| 906 | BT_DBG("%s status %d", hdev->name, ev->status); | ||
| 907 | |||
| 908 | hci_dev_lock(hdev); | ||
| 909 | |||
| 910 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | ||
| 911 | if (conn) { | ||
| 912 | conn->mode = ev->mode; | ||
| 913 | conn->interval = __le16_to_cpu(ev->interval); | ||
| 914 | |||
| 915 | if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { | ||
| 916 | if (conn->mode == HCI_CM_ACTIVE) | ||
| 917 | conn->power_save = 1; | ||
| 918 | else | ||
| 919 | conn->power_save = 0; | ||
| 920 | } | ||
| 921 | } | ||
| 922 | |||
| 923 | hci_dev_unlock(hdev); | ||
| 924 | } | ||
| 925 | |||
| 797 | /* Authentication Complete */ | 926 | /* Authentication Complete */ |
| 798 | static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 927 | static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 799 | { | 928 | { |
| 800 | struct hci_ev_auth_complete *ev = (struct hci_ev_auth_complete *) skb->data; | 929 | struct hci_ev_auth_complete *ev = (struct hci_ev_auth_complete *) skb->data; |
| 801 | struct hci_conn *conn = NULL; | 930 | struct hci_conn *conn; |
| 802 | __u16 handle = __le16_to_cpu(ev->handle); | ||
| 803 | 931 | ||
| 804 | BT_DBG("%s status %d", hdev->name, ev->status); | 932 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 805 | 933 | ||
| 806 | hci_dev_lock(hdev); | 934 | hci_dev_lock(hdev); |
| 807 | 935 | ||
| 808 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 936 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 809 | if (conn) { | 937 | if (conn) { |
| 810 | if (!ev->status) | 938 | if (!ev->status) |
| 811 | conn->link_mode |= HCI_LM_AUTH; | 939 | conn->link_mode |= HCI_LM_AUTH; |
| @@ -820,8 +948,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 820 | cp.handle = __cpu_to_le16(conn->handle); | 948 | cp.handle = __cpu_to_le16(conn->handle); |
| 821 | cp.encrypt = 1; | 949 | cp.encrypt = 1; |
| 822 | hci_send_cmd(conn->hdev, OGF_LINK_CTL, | 950 | hci_send_cmd(conn->hdev, OGF_LINK_CTL, |
| 823 | OCF_SET_CONN_ENCRYPT, | 951 | OCF_SET_CONN_ENCRYPT, sizeof(cp), &cp); |
| 824 | sizeof(cp), &cp); | ||
| 825 | } else { | 952 | } else { |
| 826 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); | 953 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); |
| 827 | hci_encrypt_cfm(conn, ev->status, 0x00); | 954 | hci_encrypt_cfm(conn, ev->status, 0x00); |
| @@ -836,14 +963,13 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 836 | static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | 963 | static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 837 | { | 964 | { |
| 838 | struct hci_ev_encrypt_change *ev = (struct hci_ev_encrypt_change *) skb->data; | 965 | struct hci_ev_encrypt_change *ev = (struct hci_ev_encrypt_change *) skb->data; |
| 839 | struct hci_conn *conn = NULL; | 966 | struct hci_conn *conn; |
| 840 | __u16 handle = __le16_to_cpu(ev->handle); | ||
| 841 | 967 | ||
| 842 | BT_DBG("%s status %d", hdev->name, ev->status); | 968 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 843 | 969 | ||
| 844 | hci_dev_lock(hdev); | 970 | hci_dev_lock(hdev); |
| 845 | 971 | ||
| 846 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 972 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 847 | if (conn) { | 973 | if (conn) { |
| 848 | if (!ev->status) { | 974 | if (!ev->status) { |
| 849 | if (ev->encrypt) | 975 | if (ev->encrypt) |
| @@ -864,14 +990,13 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff * | |||
| 864 | static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 990 | static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 865 | { | 991 | { |
| 866 | struct hci_ev_change_conn_link_key_complete *ev = (struct hci_ev_change_conn_link_key_complete *) skb->data; | 992 | struct hci_ev_change_conn_link_key_complete *ev = (struct hci_ev_change_conn_link_key_complete *) skb->data; |
| 867 | struct hci_conn *conn = NULL; | 993 | struct hci_conn *conn; |
| 868 | __u16 handle = __le16_to_cpu(ev->handle); | ||
| 869 | 994 | ||
| 870 | BT_DBG("%s status %d", hdev->name, ev->status); | 995 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 871 | 996 | ||
| 872 | hci_dev_lock(hdev); | 997 | hci_dev_lock(hdev); |
| 873 | 998 | ||
| 874 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 999 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 875 | if (conn) { | 1000 | if (conn) { |
| 876 | if (!ev->status) | 1001 | if (!ev->status) |
| 877 | conn->link_mode |= HCI_LM_SECURE; | 1002 | conn->link_mode |= HCI_LM_SECURE; |
| @@ -899,18 +1024,35 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff | |||
| 899 | { | 1024 | { |
| 900 | } | 1025 | } |
| 901 | 1026 | ||
| 1027 | /* Remote Features */ | ||
| 1028 | static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
| 1029 | { | ||
| 1030 | struct hci_ev_remote_features *ev = (struct hci_ev_remote_features *) skb->data; | ||
| 1031 | struct hci_conn *conn; | ||
| 1032 | |||
| 1033 | BT_DBG("%s status %d", hdev->name, ev->status); | ||
| 1034 | |||
| 1035 | hci_dev_lock(hdev); | ||
| 1036 | |||
| 1037 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | ||
| 1038 | if (conn && !ev->status) { | ||
| 1039 | memcpy(conn->features, ev->features, sizeof(conn->features)); | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | hci_dev_unlock(hdev); | ||
| 1043 | } | ||
| 1044 | |||
| 902 | /* Clock Offset */ | 1045 | /* Clock Offset */ |
| 903 | static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1046 | static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 904 | { | 1047 | { |
| 905 | struct hci_ev_clock_offset *ev = (struct hci_ev_clock_offset *) skb->data; | 1048 | struct hci_ev_clock_offset *ev = (struct hci_ev_clock_offset *) skb->data; |
| 906 | struct hci_conn *conn = NULL; | 1049 | struct hci_conn *conn; |
| 907 | __u16 handle = __le16_to_cpu(ev->handle); | ||
| 908 | 1050 | ||
| 909 | BT_DBG("%s status %d", hdev->name, ev->status); | 1051 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 910 | 1052 | ||
| 911 | hci_dev_lock(hdev); | 1053 | hci_dev_lock(hdev); |
| 912 | 1054 | ||
| 913 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 1055 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 914 | if (conn && !ev->status) { | 1056 | if (conn && !ev->status) { |
| 915 | struct inquiry_entry *ie; | 1057 | struct inquiry_entry *ie; |
| 916 | 1058 | ||
| @@ -941,6 +1083,23 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff * | |||
| 941 | hci_dev_unlock(hdev); | 1083 | hci_dev_unlock(hdev); |
| 942 | } | 1084 | } |
| 943 | 1085 | ||
| 1086 | /* Sniff Subrate */ | ||
| 1087 | static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
| 1088 | { | ||
| 1089 | struct hci_ev_sniff_subrate *ev = (struct hci_ev_sniff_subrate *) skb->data; | ||
| 1090 | struct hci_conn *conn; | ||
| 1091 | |||
| 1092 | BT_DBG("%s status %d", hdev->name, ev->status); | ||
| 1093 | |||
| 1094 | hci_dev_lock(hdev); | ||
| 1095 | |||
| 1096 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | ||
| 1097 | if (conn) { | ||
| 1098 | } | ||
| 1099 | |||
| 1100 | hci_dev_unlock(hdev); | ||
| 1101 | } | ||
| 1102 | |||
| 944 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | 1103 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) |
| 945 | { | 1104 | { |
| 946 | struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data; | 1105 | struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data; |
| @@ -989,6 +1148,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 989 | hci_role_change_evt(hdev, skb); | 1148 | hci_role_change_evt(hdev, skb); |
| 990 | break; | 1149 | break; |
| 991 | 1150 | ||
| 1151 | case HCI_EV_MODE_CHANGE: | ||
| 1152 | hci_mode_change_evt(hdev, skb); | ||
| 1153 | break; | ||
| 1154 | |||
| 992 | case HCI_EV_AUTH_COMPLETE: | 1155 | case HCI_EV_AUTH_COMPLETE: |
| 993 | hci_auth_complete_evt(hdev, skb); | 1156 | hci_auth_complete_evt(hdev, skb); |
| 994 | break; | 1157 | break; |
| @@ -1013,6 +1176,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 1013 | hci_link_key_notify_evt(hdev, skb); | 1176 | hci_link_key_notify_evt(hdev, skb); |
| 1014 | break; | 1177 | break; |
| 1015 | 1178 | ||
| 1179 | case HCI_EV_REMOTE_FEATURES: | ||
| 1180 | hci_remote_features_evt(hdev, skb); | ||
| 1181 | break; | ||
| 1182 | |||
| 1016 | case HCI_EV_CLOCK_OFFSET: | 1183 | case HCI_EV_CLOCK_OFFSET: |
| 1017 | hci_clock_offset_evt(hdev, skb); | 1184 | hci_clock_offset_evt(hdev, skb); |
| 1018 | break; | 1185 | break; |
| @@ -1021,6 +1188,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 1021 | hci_pscan_rep_mode_evt(hdev, skb); | 1188 | hci_pscan_rep_mode_evt(hdev, skb); |
| 1022 | break; | 1189 | break; |
| 1023 | 1190 | ||
| 1191 | case HCI_EV_SNIFF_SUBRATE: | ||
| 1192 | hci_sniff_subrate_evt(hdev, skb); | ||
| 1193 | break; | ||
| 1194 | |||
| 1024 | case HCI_EV_CMD_STATUS: | 1195 | case HCI_EV_CMD_STATUS: |
| 1025 | cs = (struct hci_ev_cmd_status *) skb->data; | 1196 | cs = (struct hci_ev_cmd_status *) skb->data; |
| 1026 | skb_pull(skb, sizeof(cs)); | 1197 | skb_pull(skb, sizeof(cs)); |
