aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_event.c72
1 files changed, 54 insertions, 18 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 9c6d9bc1d8af..4165895049b3 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -677,11 +677,9 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
677 hci_dev_unlock(hdev); 677 hci_dev_unlock(hdev);
678} 678}
679 679
680static int hci_request_outgoing_auth(struct hci_dev *hdev, 680static int hci_outgoing_auth_needed(struct hci_dev *hdev,
681 struct hci_conn *conn) 681 struct hci_conn *conn)
682{ 682{
683 struct hci_cp_auth_requested cp;
684
685 if (conn->state != BT_CONFIG || !conn->out) 683 if (conn->state != BT_CONFIG || !conn->out)
686 return 0; 684 return 0;
687 685
@@ -694,15 +692,35 @@ static int hci_request_outgoing_auth(struct hci_dev *hdev,
694 conn->sec_level != BT_SECURITY_HIGH) 692 conn->sec_level != BT_SECURITY_HIGH)
695 return 0; 693 return 0;
696 694
697 cp.handle = __cpu_to_le16(conn->handle);
698 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
699
700 return 1; 695 return 1;
701} 696}
702 697
703static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) 698static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
704{ 699{
700 struct hci_cp_remote_name_req *cp;
701 struct hci_conn *conn;
702
705 BT_DBG("%s status 0x%x", hdev->name, status); 703 BT_DBG("%s status 0x%x", hdev->name, status);
704
705 /* If successful wait for the name req complete event before
706 * checking for the need to do authentication */
707 if (!status)
708 return;
709
710 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
711 if (!cp)
712 return;
713
714 hci_dev_lock(hdev);
715
716 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
717 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
718 struct hci_cp_auth_requested cp;
719 cp.handle = __cpu_to_le16(conn->handle);
720 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
721 }
722
723 hci_dev_unlock(hdev);
706} 724}
707 725
708static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) 726static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
@@ -1113,9 +1131,23 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
1113 1131
1114static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) 1132static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1115{ 1133{
1134 struct hci_ev_remote_name *ev = (void *) skb->data;
1135 struct hci_conn *conn;
1136
1116 BT_DBG("%s", hdev->name); 1137 BT_DBG("%s", hdev->name);
1117 1138
1118 hci_conn_check_pending(hdev); 1139 hci_conn_check_pending(hdev);
1140
1141 hci_dev_lock(hdev);
1142
1143 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1144 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
1145 struct hci_cp_auth_requested cp;
1146 cp.handle = __cpu_to_le16(conn->handle);
1147 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1148 }
1149
1150 hci_dev_unlock(hdev);
1119} 1151}
1120 1152
1121static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 1153static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
@@ -1179,7 +1211,6 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
1179{ 1211{
1180 struct hci_ev_remote_features *ev = (void *) skb->data; 1212 struct hci_ev_remote_features *ev = (void *) skb->data;
1181 struct hci_conn *conn; 1213 struct hci_conn *conn;
1182 int auth_requested;
1183 1214
1184 BT_DBG("%s status %d", hdev->name, ev->status); 1215 BT_DBG("%s status %d", hdev->name, ev->status);
1185 1216
@@ -1204,12 +1235,15 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
1204 goto unlock; 1235 goto unlock;
1205 } 1236 }
1206 1237
1207 if (!ev->status) 1238 if (!ev->status) {
1208 auth_requested = hci_request_outgoing_auth(hdev, conn); 1239 struct hci_cp_remote_name_req cp;
1209 else 1240 memset(&cp, 0, sizeof(cp));
1210 auth_requested = 0; 1241 bacpy(&cp.bdaddr, &conn->dst);
1242 cp.pscan_rep_mode = 0x02;
1243 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1244 }
1211 1245
1212 if (!auth_requested) { 1246 if (!hci_outgoing_auth_needed(hdev, conn)) {
1213 conn->state = BT_CONNECTED; 1247 conn->state = BT_CONNECTED;
1214 hci_proto_connect_cfm(conn, ev->status); 1248 hci_proto_connect_cfm(conn, ev->status);
1215 hci_conn_put(conn); 1249 hci_conn_put(conn);
@@ -1667,7 +1701,6 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
1667{ 1701{
1668 struct hci_ev_remote_ext_features *ev = (void *) skb->data; 1702 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
1669 struct hci_conn *conn; 1703 struct hci_conn *conn;
1670 int auth_requested;
1671 1704
1672 BT_DBG("%s", hdev->name); 1705 BT_DBG("%s", hdev->name);
1673 1706
@@ -1689,12 +1722,15 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
1689 if (conn->state != BT_CONFIG) 1722 if (conn->state != BT_CONFIG)
1690 goto unlock; 1723 goto unlock;
1691 1724
1692 if (!ev->status) 1725 if (!ev->status) {
1693 auth_requested = hci_request_outgoing_auth(hdev, conn); 1726 struct hci_cp_remote_name_req cp;
1694 else 1727 memset(&cp, 0, sizeof(cp));
1695 auth_requested = 0; 1728 bacpy(&cp.bdaddr, &conn->dst);
1729 cp.pscan_rep_mode = 0x02;
1730 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1731 }
1696 1732
1697 if (!auth_requested) { 1733 if (!hci_outgoing_auth_needed(hdev, conn)) {
1698 conn->state = BT_CONNECTED; 1734 conn->state = BT_CONNECTED;
1699 hci_proto_connect_cfm(conn, ev->status); 1735 hci_proto_connect_cfm(conn, ev->status);
1700 hci_conn_put(conn); 1736 hci_conn_put(conn);