aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/bluetooth/hci_event.c114
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
622static 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
649static 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
622static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) 676static 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