diff options
-rw-r--r-- | net/bluetooth/hci_event.c | 114 |
1 files changed, 103 insertions, 11 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index e3e360c3c536..64668e2656a5 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -619,6 +619,60 @@ static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status) | |||
619 | hci_dev_unlock(hdev); | 619 | hci_dev_unlock(hdev); |
620 | } | 620 | } |
621 | 621 | ||
622 | static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status) | ||
623 | { | ||
624 | struct hci_cp_auth_requested *cp; | ||
625 | struct hci_conn *conn; | ||
626 | |||
627 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
628 | |||
629 | if (!status) | ||
630 | return; | ||
631 | |||
632 | cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED); | ||
633 | if (!cp) | ||
634 | return; | ||
635 | |||
636 | hci_dev_lock(hdev); | ||
637 | |||
638 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); | ||
639 | if (conn) { | ||
640 | if (conn->state == BT_CONFIG) { | ||
641 | hci_proto_connect_cfm(conn, status); | ||
642 | hci_conn_put(conn); | ||
643 | } | ||
644 | } | ||
645 | |||
646 | hci_dev_unlock(hdev); | ||
647 | } | ||
648 | |||
649 | static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) | ||
650 | { | ||
651 | struct hci_cp_set_conn_encrypt *cp; | ||
652 | struct hci_conn *conn; | ||
653 | |||
654 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
655 | |||
656 | if (!status) | ||
657 | return; | ||
658 | |||
659 | cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT); | ||
660 | if (!cp) | ||
661 | return; | ||
662 | |||
663 | hci_dev_lock(hdev); | ||
664 | |||
665 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); | ||
666 | if (conn) { | ||
667 | if (conn->state == BT_CONFIG) { | ||
668 | hci_proto_connect_cfm(conn, status); | ||
669 | hci_conn_put(conn); | ||
670 | } | ||
671 | } | ||
672 | |||
673 | hci_dev_unlock(hdev); | ||
674 | } | ||
675 | |||
622 | static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) | 676 | static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) |
623 | { | 677 | { |
624 | BT_DBG("%s status 0x%x", hdev->name, status); | 678 | BT_DBG("%s status 0x%x", hdev->name, status); |
@@ -643,7 +697,6 @@ static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) | |||
643 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); | 697 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); |
644 | if (conn) { | 698 | if (conn) { |
645 | if (conn->state == BT_CONFIG) { | 699 | if (conn->state == BT_CONFIG) { |
646 | conn->state = BT_CONNECTED; | ||
647 | hci_proto_connect_cfm(conn, status); | 700 | hci_proto_connect_cfm(conn, status); |
648 | hci_conn_put(conn); | 701 | hci_conn_put(conn); |
649 | } | 702 | } |
@@ -671,7 +724,6 @@ static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status) | |||
671 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); | 724 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); |
672 | if (conn) { | 725 | if (conn) { |
673 | if (conn->state == BT_CONFIG) { | 726 | if (conn->state == BT_CONFIG) { |
674 | conn->state = BT_CONNECTED; | ||
675 | hci_proto_connect_cfm(conn, status); | 727 | hci_proto_connect_cfm(conn, status); |
676 | hci_conn_put(conn); | 728 | hci_conn_put(conn); |
677 | } | 729 | } |
@@ -982,15 +1034,29 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
982 | 1034 | ||
983 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); | 1035 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); |
984 | 1036 | ||
985 | hci_auth_cfm(conn, ev->status); | 1037 | if (conn->state == BT_CONFIG) { |
1038 | if (!ev->status && hdev->ssp_mode > 0 && | ||
1039 | conn->ssp_mode > 0) { | ||
1040 | struct hci_cp_set_conn_encrypt cp; | ||
1041 | cp.handle = ev->handle; | ||
1042 | cp.encrypt = 0x01; | ||
1043 | hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, | ||
1044 | sizeof(cp), &cp); | ||
1045 | } else { | ||
1046 | conn->state = BT_CONNECTED; | ||
1047 | hci_proto_connect_cfm(conn, ev->status); | ||
1048 | hci_conn_put(conn); | ||
1049 | } | ||
1050 | } else | ||
1051 | hci_auth_cfm(conn, ev->status); | ||
986 | 1052 | ||
987 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { | 1053 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { |
988 | if (!ev->status) { | 1054 | if (!ev->status) { |
989 | struct hci_cp_set_conn_encrypt cp; | 1055 | struct hci_cp_set_conn_encrypt cp; |
990 | cp.handle = cpu_to_le16(conn->handle); | 1056 | cp.handle = ev->handle; |
991 | cp.encrypt = 1; | 1057 | cp.encrypt = 0x01; |
992 | hci_send_cmd(conn->hdev, | 1058 | hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, |
993 | HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp); | 1059 | sizeof(cp), &cp); |
994 | } else { | 1060 | } else { |
995 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); | 1061 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); |
996 | hci_encrypt_cfm(conn, ev->status, 0x00); | 1062 | hci_encrypt_cfm(conn, ev->status, 0x00); |
@@ -1030,7 +1096,14 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff * | |||
1030 | 1096 | ||
1031 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); | 1097 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); |
1032 | 1098 | ||
1033 | hci_encrypt_cfm(conn, ev->status, ev->encrypt); | 1099 | if (conn->state == BT_CONFIG) { |
1100 | if (!ev->status) | ||
1101 | conn->state = BT_CONNECTED; | ||
1102 | |||
1103 | hci_proto_connect_cfm(conn, ev->status); | ||
1104 | hci_conn_put(conn); | ||
1105 | } else | ||
1106 | hci_encrypt_cfm(conn, ev->status, ev->encrypt); | ||
1034 | } | 1107 | } |
1035 | 1108 | ||
1036 | hci_dev_unlock(hdev); | 1109 | hci_dev_unlock(hdev); |
@@ -1250,6 +1323,14 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1250 | hci_cs_add_sco(hdev, ev->status); | 1323 | hci_cs_add_sco(hdev, ev->status); |
1251 | break; | 1324 | break; |
1252 | 1325 | ||
1326 | case HCI_OP_AUTH_REQUESTED: | ||
1327 | hci_cs_auth_requested(hdev, ev->status); | ||
1328 | break; | ||
1329 | |||
1330 | case HCI_OP_SET_CONN_ENCRYPT: | ||
1331 | hci_cs_set_conn_encrypt(hdev, ev->status); | ||
1332 | break; | ||
1333 | |||
1253 | case HCI_OP_REMOTE_NAME_REQ: | 1334 | case HCI_OP_REMOTE_NAME_REQ: |
1254 | hci_cs_remote_name_req(hdev, ev->status); | 1335 | hci_cs_remote_name_req(hdev, ev->status); |
1255 | break; | 1336 | break; |
@@ -1518,9 +1599,20 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b | |||
1518 | } | 1599 | } |
1519 | 1600 | ||
1520 | if (conn->state == BT_CONFIG) { | 1601 | if (conn->state == BT_CONFIG) { |
1521 | conn->state = BT_CONNECTED; | 1602 | if (!ev->status && hdev->ssp_mode > 0 && |
1522 | hci_proto_connect_cfm(conn, ev->status); | 1603 | conn->ssp_mode > 0) { |
1523 | hci_conn_put(conn); | 1604 | if (conn->out) { |
1605 | struct hci_cp_auth_requested cp; | ||
1606 | cp.handle = ev->handle; | ||
1607 | hci_send_cmd(hdev, | ||
1608 | HCI_OP_AUTH_REQUESTED, | ||
1609 | sizeof(cp), &cp); | ||
1610 | } | ||
1611 | } else { | ||
1612 | conn->state = BT_CONNECTED; | ||
1613 | hci_proto_connect_cfm(conn, ev->status); | ||
1614 | hci_conn_put(conn); | ||
1615 | } | ||
1524 | } | 1616 | } |
1525 | } | 1617 | } |
1526 | 1618 | ||