diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-07-05 13:13:03 -0400 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-07-05 13:13:03 -0400 |
| commit | 5e66dd6d66ffe758b39b6dcadf2330753ee1159b (patch) | |
| tree | a72cdcff4448e4af9425cc213ddf56ab23e697fe /net/bluetooth/hci_event.c | |
| parent | 026477c1141b67e98e3bd8bdedb7d4b88a3ecd09 (diff) | |
| parent | ca78f6baca863afe2e6a244a0fe94b3a70211d46 (diff) | |
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Diffstat (limited to 'net/bluetooth/hci_event.c')
| -rw-r--r-- | net/bluetooth/hci_event.c | 206 |
1 files changed, 177 insertions, 29 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 618bacee1b1c..3896dabab11d 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
| @@ -83,6 +83,8 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff * | |||
| 83 | { | 83 | { |
| 84 | struct hci_conn *conn; | 84 | struct hci_conn *conn; |
| 85 | struct hci_rp_role_discovery *rd; | 85 | struct hci_rp_role_discovery *rd; |
| 86 | struct hci_rp_write_link_policy *lp; | ||
| 87 | void *sent; | ||
| 86 | 88 | ||
| 87 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); | 89 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); |
| 88 | 90 | ||
| @@ -106,6 +108,27 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff * | |||
| 106 | hci_dev_unlock(hdev); | 108 | hci_dev_unlock(hdev); |
| 107 | break; | 109 | break; |
| 108 | 110 | ||
| 111 | case OCF_WRITE_LINK_POLICY: | ||
| 112 | sent = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY); | ||
| 113 | if (!sent) | ||
| 114 | break; | ||
| 115 | |||
| 116 | lp = (struct hci_rp_write_link_policy *) skb->data; | ||
| 117 | |||
| 118 | if (lp->status) | ||
| 119 | break; | ||
| 120 | |||
| 121 | hci_dev_lock(hdev); | ||
| 122 | |||
| 123 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(lp->handle)); | ||
| 124 | if (conn) { | ||
| 125 | __le16 policy = get_unaligned((__le16 *) (sent + 2)); | ||
| 126 | conn->link_policy = __le16_to_cpu(policy); | ||
| 127 | } | ||
| 128 | |||
| 129 | hci_dev_unlock(hdev); | ||
| 130 | break; | ||
| 131 | |||
| 109 | default: | 132 | default: |
| 110 | BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x", | 133 | BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x", |
| 111 | hdev->name, ocf); | 134 | hdev->name, ocf); |
| @@ -274,7 +297,7 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb | |||
| 274 | /* Command Complete OGF INFO_PARAM */ | 297 | /* Command Complete OGF INFO_PARAM */ |
| 275 | static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) | 298 | static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) |
| 276 | { | 299 | { |
| 277 | struct hci_rp_read_loc_features *lf; | 300 | struct hci_rp_read_local_features *lf; |
| 278 | struct hci_rp_read_buffer_size *bs; | 301 | struct hci_rp_read_buffer_size *bs; |
| 279 | struct hci_rp_read_bd_addr *ba; | 302 | struct hci_rp_read_bd_addr *ba; |
| 280 | 303 | ||
| @@ -282,7 +305,7 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s | |||
| 282 | 305 | ||
| 283 | switch (ocf) { | 306 | switch (ocf) { |
| 284 | case OCF_READ_LOCAL_FEATURES: | 307 | case OCF_READ_LOCAL_FEATURES: |
| 285 | lf = (struct hci_rp_read_loc_features *) skb->data; | 308 | lf = (struct hci_rp_read_local_features *) skb->data; |
| 286 | 309 | ||
| 287 | if (lf->status) { | 310 | if (lf->status) { |
| 288 | BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status); | 311 | BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status); |
| @@ -319,9 +342,17 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s | |||
| 319 | } | 342 | } |
| 320 | 343 | ||
| 321 | hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu); | 344 | hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu); |
| 322 | hdev->sco_mtu = bs->sco_mtu ? bs->sco_mtu : 64; | 345 | hdev->sco_mtu = bs->sco_mtu; |
| 323 | hdev->acl_pkts = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt); | 346 | hdev->acl_pkts = __le16_to_cpu(bs->acl_max_pkt); |
| 324 | hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt); | 347 | hdev->sco_pkts = __le16_to_cpu(bs->sco_max_pkt); |
| 348 | |||
| 349 | if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) { | ||
| 350 | hdev->sco_mtu = 64; | ||
| 351 | hdev->sco_pkts = 8; | ||
| 352 | } | ||
| 353 | |||
| 354 | hdev->acl_cnt = hdev->acl_pkts; | ||
| 355 | hdev->sco_cnt = hdev->sco_pkts; | ||
| 325 | 356 | ||
| 326 | BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name, | 357 | BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name, |
| 327 | hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts); | 358 | hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts); |
| @@ -439,8 +470,46 @@ static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status) | |||
| 439 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); | 470 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); |
| 440 | 471 | ||
| 441 | switch (ocf) { | 472 | switch (ocf) { |
| 473 | case OCF_SNIFF_MODE: | ||
| 474 | if (status) { | ||
| 475 | struct hci_conn *conn; | ||
| 476 | struct hci_cp_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_SNIFF_MODE); | ||
| 477 | |||
| 478 | if (!cp) | ||
| 479 | break; | ||
| 480 | |||
| 481 | hci_dev_lock(hdev); | ||
| 482 | |||
| 483 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); | ||
| 484 | if (conn) { | ||
| 485 | clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); | ||
| 486 | } | ||
| 487 | |||
| 488 | hci_dev_unlock(hdev); | ||
| 489 | } | ||
| 490 | break; | ||
| 491 | |||
| 492 | case OCF_EXIT_SNIFF_MODE: | ||
| 493 | if (status) { | ||
| 494 | struct hci_conn *conn; | ||
| 495 | struct hci_cp_exit_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_EXIT_SNIFF_MODE); | ||
| 496 | |||
| 497 | if (!cp) | ||
| 498 | break; | ||
| 499 | |||
| 500 | hci_dev_lock(hdev); | ||
| 501 | |||
| 502 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); | ||
| 503 | if (conn) { | ||
| 504 | clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); | ||
| 505 | } | ||
| 506 | |||
| 507 | hci_dev_unlock(hdev); | ||
| 508 | } | ||
| 509 | break; | ||
| 510 | |||
| 442 | default: | 511 | default: |
| 443 | BT_DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf); | 512 | BT_DBG("%s Command status: ogf LINK_POLICY ocf %x", hdev->name, ocf); |
| 444 | break; | 513 | break; |
| 445 | } | 514 | } |
| 446 | } | 515 | } |
| @@ -622,14 +691,16 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
| 622 | else | 691 | else |
| 623 | cp.role = 0x01; /* Remain slave */ | 692 | cp.role = 0x01; /* Remain slave */ |
| 624 | 693 | ||
| 625 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp); | 694 | hci_send_cmd(hdev, OGF_LINK_CTL, |
| 695 | OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp); | ||
| 626 | } else { | 696 | } else { |
| 627 | /* Connection rejected */ | 697 | /* Connection rejected */ |
| 628 | struct hci_cp_reject_conn_req cp; | 698 | struct hci_cp_reject_conn_req cp; |
| 629 | 699 | ||
| 630 | bacpy(&cp.bdaddr, &ev->bdaddr); | 700 | bacpy(&cp.bdaddr, &ev->bdaddr); |
| 631 | cp.reason = 0x0f; | 701 | cp.reason = 0x0f; |
| 632 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ, sizeof(cp), &cp); | 702 | hci_send_cmd(hdev, OGF_LINK_CTL, |
| 703 | OCF_REJECT_CONN_REQ, sizeof(cp), &cp); | ||
| 633 | } | 704 | } |
| 634 | } | 705 | } |
| 635 | 706 | ||
| @@ -637,7 +708,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
| 637 | static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 708 | static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 638 | { | 709 | { |
| 639 | struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data; | 710 | struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data; |
| 640 | struct hci_conn *conn = NULL; | 711 | struct hci_conn *conn; |
| 641 | 712 | ||
| 642 | BT_DBG("%s", hdev->name); | 713 | BT_DBG("%s", hdev->name); |
| 643 | 714 | ||
| @@ -659,12 +730,21 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 659 | if (test_bit(HCI_ENCRYPT, &hdev->flags)) | 730 | if (test_bit(HCI_ENCRYPT, &hdev->flags)) |
| 660 | conn->link_mode |= HCI_LM_ENCRYPT; | 731 | conn->link_mode |= HCI_LM_ENCRYPT; |
| 661 | 732 | ||
| 733 | /* Get remote features */ | ||
| 734 | if (conn->type == ACL_LINK) { | ||
| 735 | struct hci_cp_read_remote_features cp; | ||
| 736 | cp.handle = ev->handle; | ||
| 737 | hci_send_cmd(hdev, OGF_LINK_CTL, | ||
| 738 | OCF_READ_REMOTE_FEATURES, sizeof(cp), &cp); | ||
| 739 | } | ||
| 740 | |||
| 662 | /* Set link policy */ | 741 | /* Set link policy */ |
| 663 | if (conn->type == ACL_LINK && hdev->link_policy) { | 742 | if (conn->type == ACL_LINK && hdev->link_policy) { |
| 664 | struct hci_cp_write_link_policy cp; | 743 | struct hci_cp_write_link_policy cp; |
| 665 | cp.handle = ev->handle; | 744 | cp.handle = ev->handle; |
| 666 | cp.policy = __cpu_to_le16(hdev->link_policy); | 745 | cp.policy = __cpu_to_le16(hdev->link_policy); |
| 667 | hci_send_cmd(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY, sizeof(cp), &cp); | 746 | hci_send_cmd(hdev, OGF_LINK_POLICY, |
| 747 | OCF_WRITE_LINK_POLICY, sizeof(cp), &cp); | ||
| 668 | } | 748 | } |
| 669 | 749 | ||
| 670 | /* Set packet type for incoming connection */ | 750 | /* Set packet type for incoming connection */ |
| @@ -675,7 +755,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 675 | __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK): | 755 | __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK): |
| 676 | __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK); | 756 | __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK); |
| 677 | 757 | ||
| 678 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp); | 758 | hci_send_cmd(hdev, OGF_LINK_CTL, |
| 759 | OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp); | ||
| 679 | } | 760 | } |
| 680 | } else | 761 | } else |
| 681 | conn->state = BT_CLOSED; | 762 | conn->state = BT_CLOSED; |
| @@ -703,8 +784,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 703 | static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 784 | static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 704 | { | 785 | { |
| 705 | struct hci_ev_disconn_complete *ev = (struct hci_ev_disconn_complete *) skb->data; | 786 | struct hci_ev_disconn_complete *ev = (struct hci_ev_disconn_complete *) skb->data; |
| 706 | struct hci_conn *conn = NULL; | 787 | struct hci_conn *conn; |
| 707 | __u16 handle = __le16_to_cpu(ev->handle); | ||
| 708 | 788 | ||
| 709 | BT_DBG("%s status %d", hdev->name, ev->status); | 789 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 710 | 790 | ||
| @@ -713,7 +793,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
| 713 | 793 | ||
| 714 | hci_dev_lock(hdev); | 794 | hci_dev_lock(hdev); |
| 715 | 795 | ||
| 716 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 796 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 717 | if (conn) { | 797 | if (conn) { |
| 718 | conn->state = BT_CLOSED; | 798 | conn->state = BT_CLOSED; |
| 719 | hci_proto_disconn_ind(conn, ev->reason); | 799 | hci_proto_disconn_ind(conn, ev->reason); |
| @@ -770,7 +850,7 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 770 | static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | 850 | static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 771 | { | 851 | { |
| 772 | struct hci_ev_role_change *ev = (struct hci_ev_role_change *) skb->data; | 852 | struct hci_ev_role_change *ev = (struct hci_ev_role_change *) skb->data; |
| 773 | struct hci_conn *conn = NULL; | 853 | struct hci_conn *conn; |
| 774 | 854 | ||
| 775 | BT_DBG("%s status %d", hdev->name, ev->status); | 855 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 776 | 856 | ||
| @@ -793,18 +873,43 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb | |||
| 793 | hci_dev_unlock(hdev); | 873 | hci_dev_unlock(hdev); |
| 794 | } | 874 | } |
| 795 | 875 | ||
| 876 | /* Mode Change */ | ||
| 877 | static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
| 878 | { | ||
| 879 | struct hci_ev_mode_change *ev = (struct hci_ev_mode_change *) skb->data; | ||
| 880 | struct hci_conn *conn; | ||
| 881 | |||
| 882 | BT_DBG("%s status %d", hdev->name, ev->status); | ||
| 883 | |||
| 884 | hci_dev_lock(hdev); | ||
| 885 | |||
| 886 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | ||
| 887 | if (conn) { | ||
| 888 | conn->mode = ev->mode; | ||
| 889 | conn->interval = __le16_to_cpu(ev->interval); | ||
| 890 | |||
| 891 | if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { | ||
| 892 | if (conn->mode == HCI_CM_ACTIVE) | ||
| 893 | conn->power_save = 1; | ||
| 894 | else | ||
| 895 | conn->power_save = 0; | ||
| 896 | } | ||
| 897 | } | ||
| 898 | |||
| 899 | hci_dev_unlock(hdev); | ||
| 900 | } | ||
| 901 | |||
| 796 | /* Authentication Complete */ | 902 | /* Authentication Complete */ |
| 797 | static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 903 | static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 798 | { | 904 | { |
| 799 | struct hci_ev_auth_complete *ev = (struct hci_ev_auth_complete *) skb->data; | 905 | struct hci_ev_auth_complete *ev = (struct hci_ev_auth_complete *) skb->data; |
| 800 | struct hci_conn *conn = NULL; | 906 | struct hci_conn *conn; |
| 801 | __u16 handle = __le16_to_cpu(ev->handle); | ||
| 802 | 907 | ||
| 803 | BT_DBG("%s status %d", hdev->name, ev->status); | 908 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 804 | 909 | ||
| 805 | hci_dev_lock(hdev); | 910 | hci_dev_lock(hdev); |
| 806 | 911 | ||
| 807 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 912 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 808 | if (conn) { | 913 | if (conn) { |
| 809 | if (!ev->status) | 914 | if (!ev->status) |
| 810 | conn->link_mode |= HCI_LM_AUTH; | 915 | conn->link_mode |= HCI_LM_AUTH; |
| @@ -819,8 +924,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 819 | cp.handle = __cpu_to_le16(conn->handle); | 924 | cp.handle = __cpu_to_le16(conn->handle); |
| 820 | cp.encrypt = 1; | 925 | cp.encrypt = 1; |
| 821 | hci_send_cmd(conn->hdev, OGF_LINK_CTL, | 926 | hci_send_cmd(conn->hdev, OGF_LINK_CTL, |
| 822 | OCF_SET_CONN_ENCRYPT, | 927 | OCF_SET_CONN_ENCRYPT, sizeof(cp), &cp); |
| 823 | sizeof(cp), &cp); | ||
| 824 | } else { | 928 | } else { |
| 825 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); | 929 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); |
| 826 | hci_encrypt_cfm(conn, ev->status, 0x00); | 930 | hci_encrypt_cfm(conn, ev->status, 0x00); |
| @@ -835,14 +939,13 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 835 | static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | 939 | static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 836 | { | 940 | { |
| 837 | struct hci_ev_encrypt_change *ev = (struct hci_ev_encrypt_change *) skb->data; | 941 | struct hci_ev_encrypt_change *ev = (struct hci_ev_encrypt_change *) skb->data; |
| 838 | struct hci_conn *conn = NULL; | 942 | struct hci_conn *conn; |
| 839 | __u16 handle = __le16_to_cpu(ev->handle); | ||
| 840 | 943 | ||
| 841 | BT_DBG("%s status %d", hdev->name, ev->status); | 944 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 842 | 945 | ||
| 843 | hci_dev_lock(hdev); | 946 | hci_dev_lock(hdev); |
| 844 | 947 | ||
| 845 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 948 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 846 | if (conn) { | 949 | if (conn) { |
| 847 | if (!ev->status) { | 950 | if (!ev->status) { |
| 848 | if (ev->encrypt) | 951 | if (ev->encrypt) |
| @@ -863,14 +966,13 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff * | |||
| 863 | static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 966 | static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 864 | { | 967 | { |
| 865 | struct hci_ev_change_conn_link_key_complete *ev = (struct hci_ev_change_conn_link_key_complete *) skb->data; | 968 | struct hci_ev_change_conn_link_key_complete *ev = (struct hci_ev_change_conn_link_key_complete *) skb->data; |
| 866 | struct hci_conn *conn = NULL; | 969 | struct hci_conn *conn; |
| 867 | __u16 handle = __le16_to_cpu(ev->handle); | ||
| 868 | 970 | ||
| 869 | BT_DBG("%s status %d", hdev->name, ev->status); | 971 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 870 | 972 | ||
| 871 | hci_dev_lock(hdev); | 973 | hci_dev_lock(hdev); |
| 872 | 974 | ||
| 873 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 975 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 874 | if (conn) { | 976 | if (conn) { |
| 875 | if (!ev->status) | 977 | if (!ev->status) |
| 876 | conn->link_mode |= HCI_LM_SECURE; | 978 | conn->link_mode |= HCI_LM_SECURE; |
| @@ -898,18 +1000,35 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff | |||
| 898 | { | 1000 | { |
| 899 | } | 1001 | } |
| 900 | 1002 | ||
| 1003 | /* Remote Features */ | ||
| 1004 | static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
| 1005 | { | ||
| 1006 | struct hci_ev_remote_features *ev = (struct hci_ev_remote_features *) skb->data; | ||
| 1007 | struct hci_conn *conn; | ||
| 1008 | |||
| 1009 | BT_DBG("%s status %d", hdev->name, ev->status); | ||
| 1010 | |||
| 1011 | hci_dev_lock(hdev); | ||
| 1012 | |||
| 1013 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | ||
| 1014 | if (conn && !ev->status) { | ||
| 1015 | memcpy(conn->features, ev->features, sizeof(conn->features)); | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | hci_dev_unlock(hdev); | ||
| 1019 | } | ||
| 1020 | |||
| 901 | /* Clock Offset */ | 1021 | /* Clock Offset */ |
| 902 | static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1022 | static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 903 | { | 1023 | { |
| 904 | struct hci_ev_clock_offset *ev = (struct hci_ev_clock_offset *) skb->data; | 1024 | struct hci_ev_clock_offset *ev = (struct hci_ev_clock_offset *) skb->data; |
| 905 | struct hci_conn *conn = NULL; | 1025 | struct hci_conn *conn; |
| 906 | __u16 handle = __le16_to_cpu(ev->handle); | ||
| 907 | 1026 | ||
| 908 | BT_DBG("%s status %d", hdev->name, ev->status); | 1027 | BT_DBG("%s status %d", hdev->name, ev->status); |
| 909 | 1028 | ||
| 910 | hci_dev_lock(hdev); | 1029 | hci_dev_lock(hdev); |
| 911 | 1030 | ||
| 912 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 1031 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 913 | if (conn && !ev->status) { | 1032 | if (conn && !ev->status) { |
| 914 | struct inquiry_entry *ie; | 1033 | struct inquiry_entry *ie; |
| 915 | 1034 | ||
| @@ -940,6 +1059,23 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff * | |||
| 940 | hci_dev_unlock(hdev); | 1059 | hci_dev_unlock(hdev); |
| 941 | } | 1060 | } |
| 942 | 1061 | ||
| 1062 | /* Sniff Subrate */ | ||
| 1063 | static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
| 1064 | { | ||
| 1065 | struct hci_ev_sniff_subrate *ev = (struct hci_ev_sniff_subrate *) skb->data; | ||
| 1066 | struct hci_conn *conn; | ||
| 1067 | |||
| 1068 | BT_DBG("%s status %d", hdev->name, ev->status); | ||
| 1069 | |||
| 1070 | hci_dev_lock(hdev); | ||
| 1071 | |||
| 1072 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | ||
| 1073 | if (conn) { | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | hci_dev_unlock(hdev); | ||
| 1077 | } | ||
| 1078 | |||
| 943 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | 1079 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) |
| 944 | { | 1080 | { |
| 945 | struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data; | 1081 | struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data; |
| @@ -988,6 +1124,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 988 | hci_role_change_evt(hdev, skb); | 1124 | hci_role_change_evt(hdev, skb); |
| 989 | break; | 1125 | break; |
| 990 | 1126 | ||
| 1127 | case HCI_EV_MODE_CHANGE: | ||
| 1128 | hci_mode_change_evt(hdev, skb); | ||
| 1129 | break; | ||
| 1130 | |||
| 991 | case HCI_EV_AUTH_COMPLETE: | 1131 | case HCI_EV_AUTH_COMPLETE: |
| 992 | hci_auth_complete_evt(hdev, skb); | 1132 | hci_auth_complete_evt(hdev, skb); |
| 993 | break; | 1133 | break; |
| @@ -1012,6 +1152,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 1012 | hci_link_key_notify_evt(hdev, skb); | 1152 | hci_link_key_notify_evt(hdev, skb); |
| 1013 | break; | 1153 | break; |
| 1014 | 1154 | ||
| 1155 | case HCI_EV_REMOTE_FEATURES: | ||
| 1156 | hci_remote_features_evt(hdev, skb); | ||
| 1157 | break; | ||
| 1158 | |||
| 1015 | case HCI_EV_CLOCK_OFFSET: | 1159 | case HCI_EV_CLOCK_OFFSET: |
| 1016 | hci_clock_offset_evt(hdev, skb); | 1160 | hci_clock_offset_evt(hdev, skb); |
| 1017 | break; | 1161 | break; |
| @@ -1020,6 +1164,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 1020 | hci_pscan_rep_mode_evt(hdev, skb); | 1164 | hci_pscan_rep_mode_evt(hdev, skb); |
| 1021 | break; | 1165 | break; |
| 1022 | 1166 | ||
| 1167 | case HCI_EV_SNIFF_SUBRATE: | ||
| 1168 | hci_sniff_subrate_evt(hdev, skb); | ||
| 1169 | break; | ||
| 1170 | |||
| 1023 | case HCI_EV_CMD_STATUS: | 1171 | case HCI_EV_CMD_STATUS: |
| 1024 | cs = (struct hci_ev_cmd_status *) skb->data; | 1172 | cs = (struct hci_ev_cmd_status *) skb->data; |
| 1025 | skb_pull(skb, sizeof(cs)); | 1173 | skb_pull(skb, sizeof(cs)); |
