11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds BlueZ - Bluetooth protocol stack for Linux 32d0a0346SRon Shaffer Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved. 41da177e4SLinus Torvalds 51da177e4SLinus Torvalds Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 61da177e4SLinus Torvalds 71da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify 81da177e4SLinus Torvalds it under the terms of the GNU General Public License version 2 as 91da177e4SLinus Torvalds published by the Free Software Foundation; 101da177e4SLinus Torvalds 111da177e4SLinus Torvalds THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 121da177e4SLinus Torvalds OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 131da177e4SLinus Torvalds FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 141da177e4SLinus Torvalds IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 151da177e4SLinus Torvalds CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 161da177e4SLinus Torvalds WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 171da177e4SLinus Torvalds ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 181da177e4SLinus Torvalds OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 211da177e4SLinus Torvalds COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 221da177e4SLinus Torvalds SOFTWARE IS DISCLAIMED. 231da177e4SLinus Torvalds */ 241da177e4SLinus Torvalds 251da177e4SLinus Torvalds /* Bluetooth HCI event handling. */ 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds #include <asm/unaligned.h> 281da177e4SLinus Torvalds 291da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 301da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 31f0d6a0eaSMikel Astiz #include <net/bluetooth/mgmt.h> 327ef9fbf0SMarcel Holtmann 330857dd3bSJohan Hedberg #include "hci_request.h" 3423b9ceb7SMarcel Holtmann #include "hci_debugfs.h" 357024728eSMarcel Holtmann #include "a2mp.h" 367ef9fbf0SMarcel Holtmann #include "amp.h" 372ceba539SJohan Hedberg #include "smp.h" 381da177e4SLinus Torvalds 39aa5b0345SMarcel Holtmann #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \ 40aa5b0345SMarcel Holtmann "\x00\x00\x00\x00\x00\x00\x00\x00" 41aa5b0345SMarcel Holtmann 421da177e4SLinus Torvalds /* Handle HCI Event packets */ 431da177e4SLinus Torvalds 44a9de9248SMarcel Holtmann static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) 451da177e4SLinus Torvalds { 46a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 471da177e4SLinus Torvalds 489f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 491da177e4SLinus Torvalds 5082f4785cSAndre Guedes if (status) 51a9de9248SMarcel Holtmann return; 521da177e4SLinus Torvalds 5389352e7dSAndre Guedes clear_bit(HCI_INQUIRY, &hdev->flags); 544e857c58SPeter Zijlstra smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */ 553e13fa1eSAndre Guedes wake_up_bit(&hdev->flags, HCI_INQUIRY); 5689352e7dSAndre Guedes 5750143a43SJohan Hedberg hci_dev_lock(hdev); 5850143a43SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 5950143a43SJohan Hedberg hci_dev_unlock(hdev); 6050143a43SJohan Hedberg 61a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 621da177e4SLinus Torvalds } 636bd57416SMarcel Holtmann 644d93483bSAndre Guedes static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) 654d93483bSAndre Guedes { 664d93483bSAndre Guedes __u8 status = *((__u8 *) skb->data); 674d93483bSAndre Guedes 689f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 69ae854a70SAndre Guedes 70ae854a70SAndre Guedes if (status) 71ae854a70SAndre Guedes return; 72ae854a70SAndre Guedes 73a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_PERIODIC_INQ); 744d93483bSAndre Guedes } 754d93483bSAndre Guedes 76a9de9248SMarcel Holtmann static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) 771da177e4SLinus Torvalds { 78a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 79a9de9248SMarcel Holtmann 809f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 81a9de9248SMarcel Holtmann 82a9de9248SMarcel Holtmann if (status) 83a9de9248SMarcel Holtmann return; 84a9de9248SMarcel Holtmann 85a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ); 86ae854a70SAndre Guedes 87a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 88a9de9248SMarcel Holtmann } 89a9de9248SMarcel Holtmann 90807deac2SGustavo Padovan static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, 91807deac2SGustavo Padovan struct sk_buff *skb) 92a9de9248SMarcel Holtmann { 93a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 94a9de9248SMarcel Holtmann } 95a9de9248SMarcel Holtmann 96a9de9248SMarcel Holtmann static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb) 97a9de9248SMarcel Holtmann { 98a9de9248SMarcel Holtmann struct hci_rp_role_discovery *rp = (void *) skb->data; 991da177e4SLinus Torvalds struct hci_conn *conn; 1001da177e4SLinus Torvalds 1019f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 1021da177e4SLinus Torvalds 103a9de9248SMarcel Holtmann if (rp->status) 104a9de9248SMarcel Holtmann return; 1051da177e4SLinus Torvalds 1061da177e4SLinus Torvalds hci_dev_lock(hdev); 1071da177e4SLinus Torvalds 108a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 10940bef302SJohan Hedberg if (conn) 11040bef302SJohan Hedberg conn->role = rp->role; 1111da177e4SLinus Torvalds 1121da177e4SLinus Torvalds hci_dev_unlock(hdev); 113a9de9248SMarcel Holtmann } 1141da177e4SLinus Torvalds 115e4e8e37cSMarcel Holtmann static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 116e4e8e37cSMarcel Holtmann { 117e4e8e37cSMarcel Holtmann struct hci_rp_read_link_policy *rp = (void *) skb->data; 118e4e8e37cSMarcel Holtmann struct hci_conn *conn; 119e4e8e37cSMarcel Holtmann 1209f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 121e4e8e37cSMarcel Holtmann 122e4e8e37cSMarcel Holtmann if (rp->status) 123e4e8e37cSMarcel Holtmann return; 124e4e8e37cSMarcel Holtmann 125e4e8e37cSMarcel Holtmann hci_dev_lock(hdev); 126e4e8e37cSMarcel Holtmann 127e4e8e37cSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 128e4e8e37cSMarcel Holtmann if (conn) 129e4e8e37cSMarcel Holtmann conn->link_policy = __le16_to_cpu(rp->policy); 130e4e8e37cSMarcel Holtmann 131e4e8e37cSMarcel Holtmann hci_dev_unlock(hdev); 132e4e8e37cSMarcel Holtmann } 133e4e8e37cSMarcel Holtmann 134a9de9248SMarcel Holtmann static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 135a9de9248SMarcel Holtmann { 136a9de9248SMarcel Holtmann struct hci_rp_write_link_policy *rp = (void *) skb->data; 137a9de9248SMarcel Holtmann struct hci_conn *conn; 138a9de9248SMarcel Holtmann void *sent; 139a9de9248SMarcel Holtmann 1409f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 141a9de9248SMarcel Holtmann 142a9de9248SMarcel Holtmann if (rp->status) 143a9de9248SMarcel Holtmann return; 144a9de9248SMarcel Holtmann 145a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY); 14604837f64SMarcel Holtmann if (!sent) 147a9de9248SMarcel Holtmann return; 14804837f64SMarcel Holtmann 14904837f64SMarcel Holtmann hci_dev_lock(hdev); 15004837f64SMarcel Holtmann 151a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 152e4e8e37cSMarcel Holtmann if (conn) 15383985319SHarvey Harrison conn->link_policy = get_unaligned_le16(sent + 2); 15404837f64SMarcel Holtmann 15504837f64SMarcel Holtmann hci_dev_unlock(hdev); 1561da177e4SLinus Torvalds } 1571da177e4SLinus Torvalds 158807deac2SGustavo Padovan static void hci_cc_read_def_link_policy(struct hci_dev *hdev, 159807deac2SGustavo Padovan struct sk_buff *skb) 160e4e8e37cSMarcel Holtmann { 161e4e8e37cSMarcel Holtmann struct hci_rp_read_def_link_policy *rp = (void *) skb->data; 162e4e8e37cSMarcel Holtmann 1639f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 164e4e8e37cSMarcel Holtmann 165e4e8e37cSMarcel Holtmann if (rp->status) 166e4e8e37cSMarcel Holtmann return; 167e4e8e37cSMarcel Holtmann 168e4e8e37cSMarcel Holtmann hdev->link_policy = __le16_to_cpu(rp->policy); 169e4e8e37cSMarcel Holtmann } 170e4e8e37cSMarcel Holtmann 171807deac2SGustavo Padovan static void hci_cc_write_def_link_policy(struct hci_dev *hdev, 172807deac2SGustavo Padovan struct sk_buff *skb) 173e4e8e37cSMarcel Holtmann { 174e4e8e37cSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 175e4e8e37cSMarcel Holtmann void *sent; 176e4e8e37cSMarcel Holtmann 1779f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 178e4e8e37cSMarcel Holtmann 17945296acdSMarcel Holtmann if (status) 18045296acdSMarcel Holtmann return; 18145296acdSMarcel Holtmann 182e4e8e37cSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY); 183e4e8e37cSMarcel Holtmann if (!sent) 184e4e8e37cSMarcel Holtmann return; 185e4e8e37cSMarcel Holtmann 186e4e8e37cSMarcel Holtmann hdev->link_policy = get_unaligned_le16(sent); 187e4e8e37cSMarcel Holtmann } 188e4e8e37cSMarcel Holtmann 189a9de9248SMarcel Holtmann static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) 1901da177e4SLinus Torvalds { 191a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 192a9de9248SMarcel Holtmann 1939f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 194a9de9248SMarcel Holtmann 19510572132SGustavo F. Padovan clear_bit(HCI_RESET, &hdev->flags); 19610572132SGustavo F. Padovan 1978761f9d6SMarcel Holtmann if (status) 1988761f9d6SMarcel Holtmann return; 1998761f9d6SMarcel Holtmann 200a297e97cSJohan Hedberg /* Reset all non-persistent flags */ 201eacb44dfSMarcel Holtmann hci_dev_clear_volatile_flags(hdev); 20269775ff6SAndre Guedes 20339c5d970SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 20439c5d970SJohan Hedberg 205bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 206bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 2073f0f524bSJohan Hedberg 2083f0f524bSJohan Hedberg memset(hdev->adv_data, 0, sizeof(hdev->adv_data)); 2093f0f524bSJohan Hedberg hdev->adv_data_len = 0; 210f8e808bdSMarcel Holtmann 211f8e808bdSMarcel Holtmann memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data)); 212f8e808bdSMarcel Holtmann hdev->scan_rsp_data_len = 0; 21306f5b778SMarcel Holtmann 214533553f8SMarcel Holtmann hdev->le_scan_type = LE_SCAN_PASSIVE; 215533553f8SMarcel Holtmann 21606f5b778SMarcel Holtmann hdev->ssp_debug_mode = 0; 217a4d5504dSMarcel Holtmann 218a4d5504dSMarcel Holtmann hci_bdaddr_list_clear(&hdev->le_white_list); 219a9de9248SMarcel Holtmann } 220a9de9248SMarcel Holtmann 221c2f0f979SMarcel Holtmann static void hci_cc_read_stored_link_key(struct hci_dev *hdev, 222c2f0f979SMarcel Holtmann struct sk_buff *skb) 223c2f0f979SMarcel Holtmann { 224c2f0f979SMarcel Holtmann struct hci_rp_read_stored_link_key *rp = (void *)skb->data; 225c2f0f979SMarcel Holtmann struct hci_cp_read_stored_link_key *sent; 226c2f0f979SMarcel Holtmann 227c2f0f979SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 228c2f0f979SMarcel Holtmann 229c2f0f979SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_READ_STORED_LINK_KEY); 230c2f0f979SMarcel Holtmann if (!sent) 231c2f0f979SMarcel Holtmann return; 232c2f0f979SMarcel Holtmann 233c2f0f979SMarcel Holtmann if (!rp->status && sent->read_all == 0x01) { 234c2f0f979SMarcel Holtmann hdev->stored_max_keys = rp->max_keys; 235c2f0f979SMarcel Holtmann hdev->stored_num_keys = rp->num_keys; 236c2f0f979SMarcel Holtmann } 237c2f0f979SMarcel Holtmann } 238c2f0f979SMarcel Holtmann 239a9366120SMarcel Holtmann static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, 240a9366120SMarcel Holtmann struct sk_buff *skb) 241a9366120SMarcel Holtmann { 242a9366120SMarcel Holtmann struct hci_rp_delete_stored_link_key *rp = (void *)skb->data; 243a9366120SMarcel Holtmann 244a9366120SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 245a9366120SMarcel Holtmann 246a9366120SMarcel Holtmann if (rp->status) 247a9366120SMarcel Holtmann return; 248a9366120SMarcel Holtmann 249a9366120SMarcel Holtmann if (rp->num_keys <= hdev->stored_num_keys) 250a9366120SMarcel Holtmann hdev->stored_num_keys -= rp->num_keys; 251a9366120SMarcel Holtmann else 252a9366120SMarcel Holtmann hdev->stored_num_keys = 0; 253a9366120SMarcel Holtmann } 254a9366120SMarcel Holtmann 255a9de9248SMarcel Holtmann static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) 256a9de9248SMarcel Holtmann { 257a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 2581da177e4SLinus Torvalds void *sent; 2591da177e4SLinus Torvalds 2609f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 2611da177e4SLinus Torvalds 262a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME); 2631da177e4SLinus Torvalds if (!sent) 264a9de9248SMarcel Holtmann return; 2651da177e4SLinus Torvalds 26656e5cb86SJohan Hedberg hci_dev_lock(hdev); 26756e5cb86SJohan Hedberg 268d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 269f51d5b24SJohan Hedberg mgmt_set_local_name_complete(hdev, sent, status); 27028cc7bdeSJohan Hedberg else if (!status) 27128cc7bdeSJohan Hedberg memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); 272f51d5b24SJohan Hedberg 27356e5cb86SJohan Hedberg hci_dev_unlock(hdev); 274a9de9248SMarcel Holtmann } 275a9de9248SMarcel Holtmann 276a9de9248SMarcel Holtmann static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) 277a9de9248SMarcel Holtmann { 278a9de9248SMarcel Holtmann struct hci_rp_read_local_name *rp = (void *) skb->data; 279a9de9248SMarcel Holtmann 2809f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 281a9de9248SMarcel Holtmann 282a9de9248SMarcel Holtmann if (rp->status) 283a9de9248SMarcel Holtmann return; 284a9de9248SMarcel Holtmann 285d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 286d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) 2871f6c6378SJohan Hedberg memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); 288a9de9248SMarcel Holtmann } 289a9de9248SMarcel Holtmann 290a9de9248SMarcel Holtmann static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) 291a9de9248SMarcel Holtmann { 292a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 293a9de9248SMarcel Holtmann void *sent; 294a9de9248SMarcel Holtmann 2959f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 296a9de9248SMarcel Holtmann 297a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE); 298a9de9248SMarcel Holtmann if (!sent) 299a9de9248SMarcel Holtmann return; 3001da177e4SLinus Torvalds 3015c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 3025c1a4c8fSJaganath Kanakkassery 3031da177e4SLinus Torvalds if (!status) { 304a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 305a9de9248SMarcel Holtmann 3061da177e4SLinus Torvalds if (param == AUTH_ENABLED) 3071da177e4SLinus Torvalds set_bit(HCI_AUTH, &hdev->flags); 3081da177e4SLinus Torvalds else 3091da177e4SLinus Torvalds clear_bit(HCI_AUTH, &hdev->flags); 3101da177e4SLinus Torvalds } 311a9de9248SMarcel Holtmann 312d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 31333ef95edSJohan Hedberg mgmt_auth_enable_complete(hdev, status); 3145c1a4c8fSJaganath Kanakkassery 3155c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 316a9de9248SMarcel Holtmann } 3171da177e4SLinus Torvalds 318a9de9248SMarcel Holtmann static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) 319a9de9248SMarcel Holtmann { 320a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 32145296acdSMarcel Holtmann __u8 param; 322a9de9248SMarcel Holtmann void *sent; 323a9de9248SMarcel Holtmann 3249f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 325a9de9248SMarcel Holtmann 32645296acdSMarcel Holtmann if (status) 32745296acdSMarcel Holtmann return; 32845296acdSMarcel Holtmann 329a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE); 3301da177e4SLinus Torvalds if (!sent) 331a9de9248SMarcel Holtmann return; 3321da177e4SLinus Torvalds 33345296acdSMarcel Holtmann param = *((__u8 *) sent); 334a9de9248SMarcel Holtmann 3351da177e4SLinus Torvalds if (param) 3361da177e4SLinus Torvalds set_bit(HCI_ENCRYPT, &hdev->flags); 3371da177e4SLinus Torvalds else 3381da177e4SLinus Torvalds clear_bit(HCI_ENCRYPT, &hdev->flags); 3391da177e4SLinus Torvalds } 3401da177e4SLinus Torvalds 341a9de9248SMarcel Holtmann static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) 342a9de9248SMarcel Holtmann { 34345296acdSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 34445296acdSMarcel Holtmann __u8 param; 345a9de9248SMarcel Holtmann void *sent; 3461da177e4SLinus Torvalds 3479f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 348a9de9248SMarcel Holtmann 349a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE); 3501da177e4SLinus Torvalds if (!sent) 351a9de9248SMarcel Holtmann return; 3521da177e4SLinus Torvalds 35336f7fc7eSJohan Hedberg param = *((__u8 *) sent); 354a9de9248SMarcel Holtmann 35556e5cb86SJohan Hedberg hci_dev_lock(hdev); 35656e5cb86SJohan Hedberg 357fa1bd918SMikel Astiz if (status) { 3582d7cee58SJohan Hedberg hdev->discov_timeout = 0; 3592d7cee58SJohan Hedberg goto done; 3602d7cee58SJohan Hedberg } 3612d7cee58SJohan Hedberg 362bc6d2d04SJohan Hedberg if (param & SCAN_INQUIRY) 3631da177e4SLinus Torvalds set_bit(HCI_ISCAN, &hdev->flags); 364bc6d2d04SJohan Hedberg else 365bc6d2d04SJohan Hedberg clear_bit(HCI_ISCAN, &hdev->flags); 3661da177e4SLinus Torvalds 367031547d8SJohan Hedberg if (param & SCAN_PAGE) 3681da177e4SLinus Torvalds set_bit(HCI_PSCAN, &hdev->flags); 369bc6d2d04SJohan Hedberg else 370204e3990SJohan Hedberg clear_bit(HCI_PSCAN, &hdev->flags); 371a9de9248SMarcel Holtmann 37236f7fc7eSJohan Hedberg done: 37356e5cb86SJohan Hedberg hci_dev_unlock(hdev); 3741da177e4SLinus Torvalds } 3751da177e4SLinus Torvalds 376a9de9248SMarcel Holtmann static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 377a9de9248SMarcel Holtmann { 378a9de9248SMarcel Holtmann struct hci_rp_read_class_of_dev *rp = (void *) skb->data; 379a9de9248SMarcel Holtmann 3809f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 381a9de9248SMarcel Holtmann 382a9de9248SMarcel Holtmann if (rp->status) 383a9de9248SMarcel Holtmann return; 384a9de9248SMarcel Holtmann 385a9de9248SMarcel Holtmann memcpy(hdev->dev_class, rp->dev_class, 3); 386a9de9248SMarcel Holtmann 387a9de9248SMarcel Holtmann BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name, 388a9de9248SMarcel Holtmann hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); 389a9de9248SMarcel Holtmann } 390a9de9248SMarcel Holtmann 391a9de9248SMarcel Holtmann static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 392a9de9248SMarcel Holtmann { 393a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 394a9de9248SMarcel Holtmann void *sent; 395a9de9248SMarcel Holtmann 3969f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 397a9de9248SMarcel Holtmann 398a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV); 399a9de9248SMarcel Holtmann if (!sent) 400a9de9248SMarcel Holtmann return; 401a9de9248SMarcel Holtmann 4027f9a903cSMarcel Holtmann hci_dev_lock(hdev); 4037f9a903cSMarcel Holtmann 4047f9a903cSMarcel Holtmann if (status == 0) 405a9de9248SMarcel Holtmann memcpy(hdev->dev_class, sent, 3); 4067f9a903cSMarcel Holtmann 407d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 4087f9a903cSMarcel Holtmann mgmt_set_class_of_dev_complete(hdev, sent, status); 4097f9a903cSMarcel Holtmann 4107f9a903cSMarcel Holtmann hci_dev_unlock(hdev); 411a9de9248SMarcel Holtmann } 412a9de9248SMarcel Holtmann 413a9de9248SMarcel Holtmann static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) 414a9de9248SMarcel Holtmann { 415a9de9248SMarcel Holtmann struct hci_rp_read_voice_setting *rp = (void *) skb->data; 416a9de9248SMarcel Holtmann __u16 setting; 417a9de9248SMarcel Holtmann 4189f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 419a9de9248SMarcel Holtmann 420a9de9248SMarcel Holtmann if (rp->status) 421a9de9248SMarcel Holtmann return; 422a9de9248SMarcel Holtmann 423a9de9248SMarcel Holtmann setting = __le16_to_cpu(rp->voice_setting); 424a9de9248SMarcel Holtmann 425a9de9248SMarcel Holtmann if (hdev->voice_setting == setting) 426a9de9248SMarcel Holtmann return; 427a9de9248SMarcel Holtmann 428a9de9248SMarcel Holtmann hdev->voice_setting = setting; 429a9de9248SMarcel Holtmann 4309f1db00cSAndrei Emeltchenko BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting); 431a9de9248SMarcel Holtmann 4323c54711cSGustavo F. Padovan if (hdev->notify) 433a9de9248SMarcel Holtmann hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 434a9de9248SMarcel Holtmann } 435a9de9248SMarcel Holtmann 4368fc9ced3SGustavo Padovan static void hci_cc_write_voice_setting(struct hci_dev *hdev, 4378fc9ced3SGustavo Padovan struct sk_buff *skb) 438a9de9248SMarcel Holtmann { 439a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 440f383f275SMarcel Holtmann __u16 setting; 441a9de9248SMarcel Holtmann void *sent; 442a9de9248SMarcel Holtmann 4439f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 444a9de9248SMarcel Holtmann 445f383f275SMarcel Holtmann if (status) 446f383f275SMarcel Holtmann return; 447f383f275SMarcel Holtmann 448a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING); 449a9de9248SMarcel Holtmann if (!sent) 450a9de9248SMarcel Holtmann return; 451a9de9248SMarcel Holtmann 452f383f275SMarcel Holtmann setting = get_unaligned_le16(sent); 4531da177e4SLinus Torvalds 454f383f275SMarcel Holtmann if (hdev->voice_setting == setting) 455f383f275SMarcel Holtmann return; 456f383f275SMarcel Holtmann 4571da177e4SLinus Torvalds hdev->voice_setting = setting; 4581da177e4SLinus Torvalds 4599f1db00cSAndrei Emeltchenko BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting); 4601da177e4SLinus Torvalds 4613c54711cSGustavo F. Padovan if (hdev->notify) 4621da177e4SLinus Torvalds hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 4631da177e4SLinus Torvalds } 4641da177e4SLinus Torvalds 465b4cb9fb2SMarcel Holtmann static void hci_cc_read_num_supported_iac(struct hci_dev *hdev, 466b4cb9fb2SMarcel Holtmann struct sk_buff *skb) 467b4cb9fb2SMarcel Holtmann { 468b4cb9fb2SMarcel Holtmann struct hci_rp_read_num_supported_iac *rp = (void *) skb->data; 469b4cb9fb2SMarcel Holtmann 470b4cb9fb2SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 471b4cb9fb2SMarcel Holtmann 472b4cb9fb2SMarcel Holtmann if (rp->status) 473b4cb9fb2SMarcel Holtmann return; 474b4cb9fb2SMarcel Holtmann 475b4cb9fb2SMarcel Holtmann hdev->num_iac = rp->num_iac; 476b4cb9fb2SMarcel Holtmann 477b4cb9fb2SMarcel Holtmann BT_DBG("%s num iac %d", hdev->name, hdev->num_iac); 478b4cb9fb2SMarcel Holtmann } 479b4cb9fb2SMarcel Holtmann 480333140b5SMarcel Holtmann static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) 481333140b5SMarcel Holtmann { 482333140b5SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 4835ed8eb2fSJohan Hedberg struct hci_cp_write_ssp_mode *sent; 484333140b5SMarcel Holtmann 4859f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 486333140b5SMarcel Holtmann 487333140b5SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); 488333140b5SMarcel Holtmann if (!sent) 489333140b5SMarcel Holtmann return; 490333140b5SMarcel Holtmann 4915c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 4925c1a4c8fSJaganath Kanakkassery 4935ed8eb2fSJohan Hedberg if (!status) { 4945ed8eb2fSJohan Hedberg if (sent->mode) 495cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_SSP; 4965ed8eb2fSJohan Hedberg else 497cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_SSP; 4985ed8eb2fSJohan Hedberg } 4995ed8eb2fSJohan Hedberg 500d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 5015ed8eb2fSJohan Hedberg mgmt_ssp_enable_complete(hdev, sent->mode, status); 502c0ecddc2SJohan Hedberg else if (!status) { 5035ed8eb2fSJohan Hedberg if (sent->mode) 504a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SSP_ENABLED); 50584bde9d6SJohan Hedberg else 506a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_SSP_ENABLED); 507c0ecddc2SJohan Hedberg } 5085c1a4c8fSJaganath Kanakkassery 5095c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 510333140b5SMarcel Holtmann } 511333140b5SMarcel Holtmann 512eac83dc6SMarcel Holtmann static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb) 513eac83dc6SMarcel Holtmann { 514eac83dc6SMarcel Holtmann u8 status = *((u8 *) skb->data); 515eac83dc6SMarcel Holtmann struct hci_cp_write_sc_support *sent; 516eac83dc6SMarcel Holtmann 517eac83dc6SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 518eac83dc6SMarcel Holtmann 519eac83dc6SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT); 520eac83dc6SMarcel Holtmann if (!sent) 521eac83dc6SMarcel Holtmann return; 522eac83dc6SMarcel Holtmann 5235c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 5245c1a4c8fSJaganath Kanakkassery 525eac83dc6SMarcel Holtmann if (!status) { 526eac83dc6SMarcel Holtmann if (sent->support) 527eac83dc6SMarcel Holtmann hdev->features[1][0] |= LMP_HOST_SC; 528eac83dc6SMarcel Holtmann else 529eac83dc6SMarcel Holtmann hdev->features[1][0] &= ~LMP_HOST_SC; 530eac83dc6SMarcel Holtmann } 531eac83dc6SMarcel Holtmann 532d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT) && !status) { 533eac83dc6SMarcel Holtmann if (sent->support) 534a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SC_ENABLED); 535eac83dc6SMarcel Holtmann else 536a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_SC_ENABLED); 537eac83dc6SMarcel Holtmann } 5385c1a4c8fSJaganath Kanakkassery 5395c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 540eac83dc6SMarcel Holtmann } 541eac83dc6SMarcel Holtmann 542a9de9248SMarcel Holtmann static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) 543a9de9248SMarcel Holtmann { 544a9de9248SMarcel Holtmann struct hci_rp_read_local_version *rp = (void *) skb->data; 5451143e5a6SMarcel Holtmann 5469f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 5471143e5a6SMarcel Holtmann 548a9de9248SMarcel Holtmann if (rp->status) 54942c6b129SJohan Hedberg return; 5501143e5a6SMarcel Holtmann 551d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 552d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) { 553a9de9248SMarcel Holtmann hdev->hci_ver = rp->hci_ver; 554e4e8e37cSMarcel Holtmann hdev->hci_rev = __le16_to_cpu(rp->hci_rev); 555d5859e22SJohan Hedberg hdev->lmp_ver = rp->lmp_ver; 556e4e8e37cSMarcel Holtmann hdev->manufacturer = __le16_to_cpu(rp->manufacturer); 557d5859e22SJohan Hedberg hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); 5580d5551f5SMarcel Holtmann } 559d5859e22SJohan Hedberg } 560d5859e22SJohan Hedberg 5618fc9ced3SGustavo Padovan static void hci_cc_read_local_commands(struct hci_dev *hdev, 5628fc9ced3SGustavo Padovan struct sk_buff *skb) 563a9de9248SMarcel Holtmann { 564a9de9248SMarcel Holtmann struct hci_rp_read_local_commands *rp = (void *) skb->data; 565a9de9248SMarcel Holtmann 5669f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 567a9de9248SMarcel Holtmann 5686a070e6eSMarcel Holtmann if (rp->status) 5696a070e6eSMarcel Holtmann return; 5706a070e6eSMarcel Holtmann 571d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 572d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) 573a9de9248SMarcel Holtmann memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); 574a9de9248SMarcel Holtmann } 575a9de9248SMarcel Holtmann 5768fc9ced3SGustavo Padovan static void hci_cc_read_local_features(struct hci_dev *hdev, 5778fc9ced3SGustavo Padovan struct sk_buff *skb) 578a9de9248SMarcel Holtmann { 579a9de9248SMarcel Holtmann struct hci_rp_read_local_features *rp = (void *) skb->data; 580a9de9248SMarcel Holtmann 5819f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 582a9de9248SMarcel Holtmann 583a9de9248SMarcel Holtmann if (rp->status) 584a9de9248SMarcel Holtmann return; 585a9de9248SMarcel Holtmann 586a9de9248SMarcel Holtmann memcpy(hdev->features, rp->features, 8); 5871da177e4SLinus Torvalds 5881da177e4SLinus Torvalds /* Adjust default settings according to features 5891da177e4SLinus Torvalds * supported by device. */ 590a9de9248SMarcel Holtmann 591cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_3SLOT) 5921da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM3 | HCI_DH3); 5931da177e4SLinus Torvalds 594cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_5SLOT) 5951da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM5 | HCI_DH5); 5961da177e4SLinus Torvalds 597cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV2) { 5981da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV2); 5995b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV2); 6005b7f9909SMarcel Holtmann } 6011da177e4SLinus Torvalds 602cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV3) { 6031da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV3); 6045b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV3); 6055b7f9909SMarcel Holtmann } 6065b7f9909SMarcel Holtmann 60745db810fSAndre Guedes if (lmp_esco_capable(hdev)) 6085b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV3); 6095b7f9909SMarcel Holtmann 610cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV4) 6115b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV4); 6125b7f9909SMarcel Holtmann 613cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV5) 6145b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV5); 6151da177e4SLinus Torvalds 616cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_2M) 617efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV3); 618efc7688bSMarcel Holtmann 619cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_3M) 620efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_3EV3); 621efc7688bSMarcel Holtmann 622cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_3S_ESCO) 623efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); 6241da177e4SLinus Torvalds } 6251da177e4SLinus Torvalds 626971e3a4bSAndre Guedes static void hci_cc_read_local_ext_features(struct hci_dev *hdev, 627971e3a4bSAndre Guedes struct sk_buff *skb) 628971e3a4bSAndre Guedes { 629971e3a4bSAndre Guedes struct hci_rp_read_local_ext_features *rp = (void *) skb->data; 630971e3a4bSAndre Guedes 6319f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 632971e3a4bSAndre Guedes 633971e3a4bSAndre Guedes if (rp->status) 63442c6b129SJohan Hedberg return; 635971e3a4bSAndre Guedes 63657af75a8SMarcel Holtmann if (hdev->max_page < rp->max_page) 637d2c5d77fSJohan Hedberg hdev->max_page = rp->max_page; 638d2c5d77fSJohan Hedberg 639cad718edSJohan Hedberg if (rp->page < HCI_MAX_PAGES) 640cad718edSJohan Hedberg memcpy(hdev->features[rp->page], rp->features, 8); 641971e3a4bSAndre Guedes } 642971e3a4bSAndre Guedes 6431e89cffbSAndrei Emeltchenko static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, 6441e89cffbSAndrei Emeltchenko struct sk_buff *skb) 6451e89cffbSAndrei Emeltchenko { 6461e89cffbSAndrei Emeltchenko struct hci_rp_read_flow_control_mode *rp = (void *) skb->data; 6471e89cffbSAndrei Emeltchenko 6489f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 6491e89cffbSAndrei Emeltchenko 65045296acdSMarcel Holtmann if (rp->status) 65145296acdSMarcel Holtmann return; 65245296acdSMarcel Holtmann 6531e89cffbSAndrei Emeltchenko hdev->flow_ctl_mode = rp->mode; 6541e89cffbSAndrei Emeltchenko } 6551e89cffbSAndrei Emeltchenko 656a9de9248SMarcel Holtmann static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) 657a9de9248SMarcel Holtmann { 658a9de9248SMarcel Holtmann struct hci_rp_read_buffer_size *rp = (void *) skb->data; 659a9de9248SMarcel Holtmann 6609f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 661a9de9248SMarcel Holtmann 662a9de9248SMarcel Holtmann if (rp->status) 663a9de9248SMarcel Holtmann return; 664a9de9248SMarcel Holtmann 665a9de9248SMarcel Holtmann hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu); 666a9de9248SMarcel Holtmann hdev->sco_mtu = rp->sco_mtu; 667a9de9248SMarcel Holtmann hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt); 668a9de9248SMarcel Holtmann hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt); 669da1f5198SMarcel Holtmann 670da1f5198SMarcel Holtmann if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) { 671da1f5198SMarcel Holtmann hdev->sco_mtu = 64; 672da1f5198SMarcel Holtmann hdev->sco_pkts = 8; 673da1f5198SMarcel Holtmann } 674da1f5198SMarcel Holtmann 675da1f5198SMarcel Holtmann hdev->acl_cnt = hdev->acl_pkts; 676da1f5198SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 6771da177e4SLinus Torvalds 678807deac2SGustavo Padovan BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu, 679807deac2SGustavo Padovan hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts); 6801da177e4SLinus Torvalds } 6811da177e4SLinus Torvalds 682a9de9248SMarcel Holtmann static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) 683a9de9248SMarcel Holtmann { 684a9de9248SMarcel Holtmann struct hci_rp_read_bd_addr *rp = (void *) skb->data; 6851da177e4SLinus Torvalds 6869f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 687a9de9248SMarcel Holtmann 688e30d3f5fSMarcel Holtmann if (rp->status) 689e30d3f5fSMarcel Holtmann return; 690e30d3f5fSMarcel Holtmann 691e30d3f5fSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) 692a9de9248SMarcel Holtmann bacpy(&hdev->bdaddr, &rp->bdaddr); 693e30d3f5fSMarcel Holtmann 694d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) 695e30d3f5fSMarcel Holtmann bacpy(&hdev->setup_addr, &rp->bdaddr); 69623bb5763SJohan Hedberg } 69723bb5763SJohan Hedberg 698f332ec66SJohan Hedberg static void hci_cc_read_page_scan_activity(struct hci_dev *hdev, 699f332ec66SJohan Hedberg struct sk_buff *skb) 700f332ec66SJohan Hedberg { 701f332ec66SJohan Hedberg struct hci_rp_read_page_scan_activity *rp = (void *) skb->data; 702f332ec66SJohan Hedberg 703f332ec66SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 704f332ec66SJohan Hedberg 70545296acdSMarcel Holtmann if (rp->status) 70645296acdSMarcel Holtmann return; 70745296acdSMarcel Holtmann 70845296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) { 709f332ec66SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(rp->interval); 710f332ec66SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(rp->window); 711f332ec66SJohan Hedberg } 712f332ec66SJohan Hedberg } 713f332ec66SJohan Hedberg 7144a3ee763SJohan Hedberg static void hci_cc_write_page_scan_activity(struct hci_dev *hdev, 7154a3ee763SJohan Hedberg struct sk_buff *skb) 7164a3ee763SJohan Hedberg { 7174a3ee763SJohan Hedberg u8 status = *((u8 *) skb->data); 7184a3ee763SJohan Hedberg struct hci_cp_write_page_scan_activity *sent; 7194a3ee763SJohan Hedberg 7204a3ee763SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 7214a3ee763SJohan Hedberg 7224a3ee763SJohan Hedberg if (status) 7234a3ee763SJohan Hedberg return; 7244a3ee763SJohan Hedberg 7254a3ee763SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY); 7264a3ee763SJohan Hedberg if (!sent) 7274a3ee763SJohan Hedberg return; 7284a3ee763SJohan Hedberg 7294a3ee763SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(sent->interval); 7304a3ee763SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(sent->window); 7314a3ee763SJohan Hedberg } 7324a3ee763SJohan Hedberg 733f332ec66SJohan Hedberg static void hci_cc_read_page_scan_type(struct hci_dev *hdev, 734f332ec66SJohan Hedberg struct sk_buff *skb) 735f332ec66SJohan Hedberg { 736f332ec66SJohan Hedberg struct hci_rp_read_page_scan_type *rp = (void *) skb->data; 737f332ec66SJohan Hedberg 738f332ec66SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 739f332ec66SJohan Hedberg 74045296acdSMarcel Holtmann if (rp->status) 74145296acdSMarcel Holtmann return; 74245296acdSMarcel Holtmann 74345296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) 744f332ec66SJohan Hedberg hdev->page_scan_type = rp->type; 745f332ec66SJohan Hedberg } 746f332ec66SJohan Hedberg 7474a3ee763SJohan Hedberg static void hci_cc_write_page_scan_type(struct hci_dev *hdev, 7484a3ee763SJohan Hedberg struct sk_buff *skb) 7494a3ee763SJohan Hedberg { 7504a3ee763SJohan Hedberg u8 status = *((u8 *) skb->data); 7514a3ee763SJohan Hedberg u8 *type; 7524a3ee763SJohan Hedberg 7534a3ee763SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 7544a3ee763SJohan Hedberg 7554a3ee763SJohan Hedberg if (status) 7564a3ee763SJohan Hedberg return; 7574a3ee763SJohan Hedberg 7584a3ee763SJohan Hedberg type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE); 7594a3ee763SJohan Hedberg if (type) 7604a3ee763SJohan Hedberg hdev->page_scan_type = *type; 7614a3ee763SJohan Hedberg } 7624a3ee763SJohan Hedberg 763350ee4cfSAndrei Emeltchenko static void hci_cc_read_data_block_size(struct hci_dev *hdev, 764350ee4cfSAndrei Emeltchenko struct sk_buff *skb) 765350ee4cfSAndrei Emeltchenko { 766350ee4cfSAndrei Emeltchenko struct hci_rp_read_data_block_size *rp = (void *) skb->data; 767350ee4cfSAndrei Emeltchenko 7689f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 769350ee4cfSAndrei Emeltchenko 770350ee4cfSAndrei Emeltchenko if (rp->status) 771350ee4cfSAndrei Emeltchenko return; 772350ee4cfSAndrei Emeltchenko 773350ee4cfSAndrei Emeltchenko hdev->block_mtu = __le16_to_cpu(rp->max_acl_len); 774350ee4cfSAndrei Emeltchenko hdev->block_len = __le16_to_cpu(rp->block_len); 775350ee4cfSAndrei Emeltchenko hdev->num_blocks = __le16_to_cpu(rp->num_blocks); 776350ee4cfSAndrei Emeltchenko 777350ee4cfSAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 778350ee4cfSAndrei Emeltchenko 779350ee4cfSAndrei Emeltchenko BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu, 780350ee4cfSAndrei Emeltchenko hdev->block_cnt, hdev->block_len); 781350ee4cfSAndrei Emeltchenko } 782350ee4cfSAndrei Emeltchenko 78333f35721SJohan Hedberg static void hci_cc_read_clock(struct hci_dev *hdev, struct sk_buff *skb) 78433f35721SJohan Hedberg { 78533f35721SJohan Hedberg struct hci_rp_read_clock *rp = (void *) skb->data; 78633f35721SJohan Hedberg struct hci_cp_read_clock *cp; 78733f35721SJohan Hedberg struct hci_conn *conn; 78833f35721SJohan Hedberg 78933f35721SJohan Hedberg BT_DBG("%s", hdev->name); 79033f35721SJohan Hedberg 79133f35721SJohan Hedberg if (skb->len < sizeof(*rp)) 79233f35721SJohan Hedberg return; 79333f35721SJohan Hedberg 79433f35721SJohan Hedberg if (rp->status) 79533f35721SJohan Hedberg return; 79633f35721SJohan Hedberg 79733f35721SJohan Hedberg hci_dev_lock(hdev); 79833f35721SJohan Hedberg 79933f35721SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK); 80033f35721SJohan Hedberg if (!cp) 80133f35721SJohan Hedberg goto unlock; 80233f35721SJohan Hedberg 80333f35721SJohan Hedberg if (cp->which == 0x00) { 80433f35721SJohan Hedberg hdev->clock = le32_to_cpu(rp->clock); 80533f35721SJohan Hedberg goto unlock; 80633f35721SJohan Hedberg } 80733f35721SJohan Hedberg 80833f35721SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 80933f35721SJohan Hedberg if (conn) { 81033f35721SJohan Hedberg conn->clock = le32_to_cpu(rp->clock); 81133f35721SJohan Hedberg conn->clock_accuracy = le16_to_cpu(rp->accuracy); 81233f35721SJohan Hedberg } 81333f35721SJohan Hedberg 81433f35721SJohan Hedberg unlock: 81533f35721SJohan Hedberg hci_dev_unlock(hdev); 81633f35721SJohan Hedberg } 81733f35721SJohan Hedberg 818928abaa7SAndrei Emeltchenko static void hci_cc_read_local_amp_info(struct hci_dev *hdev, 819928abaa7SAndrei Emeltchenko struct sk_buff *skb) 820928abaa7SAndrei Emeltchenko { 821928abaa7SAndrei Emeltchenko struct hci_rp_read_local_amp_info *rp = (void *) skb->data; 822928abaa7SAndrei Emeltchenko 8239f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 824928abaa7SAndrei Emeltchenko 825928abaa7SAndrei Emeltchenko if (rp->status) 8268e2a0d92SAndrei Emeltchenko goto a2mp_rsp; 827928abaa7SAndrei Emeltchenko 828928abaa7SAndrei Emeltchenko hdev->amp_status = rp->amp_status; 829928abaa7SAndrei Emeltchenko hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); 830928abaa7SAndrei Emeltchenko hdev->amp_max_bw = __le32_to_cpu(rp->max_bw); 831928abaa7SAndrei Emeltchenko hdev->amp_min_latency = __le32_to_cpu(rp->min_latency); 832928abaa7SAndrei Emeltchenko hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu); 833928abaa7SAndrei Emeltchenko hdev->amp_type = rp->amp_type; 834928abaa7SAndrei Emeltchenko hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap); 835928abaa7SAndrei Emeltchenko hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size); 836928abaa7SAndrei Emeltchenko hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to); 837928abaa7SAndrei Emeltchenko hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); 838928abaa7SAndrei Emeltchenko 8398e2a0d92SAndrei Emeltchenko a2mp_rsp: 8408e2a0d92SAndrei Emeltchenko a2mp_send_getinfo_rsp(hdev); 841928abaa7SAndrei Emeltchenko } 842928abaa7SAndrei Emeltchenko 843903e4541SAndrei Emeltchenko static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev, 844903e4541SAndrei Emeltchenko struct sk_buff *skb) 845903e4541SAndrei Emeltchenko { 846903e4541SAndrei Emeltchenko struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data; 847903e4541SAndrei Emeltchenko struct amp_assoc *assoc = &hdev->loc_assoc; 848903e4541SAndrei Emeltchenko size_t rem_len, frag_len; 849903e4541SAndrei Emeltchenko 850903e4541SAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 851903e4541SAndrei Emeltchenko 852903e4541SAndrei Emeltchenko if (rp->status) 853903e4541SAndrei Emeltchenko goto a2mp_rsp; 854903e4541SAndrei Emeltchenko 855903e4541SAndrei Emeltchenko frag_len = skb->len - sizeof(*rp); 856903e4541SAndrei Emeltchenko rem_len = __le16_to_cpu(rp->rem_len); 857903e4541SAndrei Emeltchenko 858903e4541SAndrei Emeltchenko if (rem_len > frag_len) { 8592e430be3SAndrei Emeltchenko BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len); 860903e4541SAndrei Emeltchenko 861903e4541SAndrei Emeltchenko memcpy(assoc->data + assoc->offset, rp->frag, frag_len); 862903e4541SAndrei Emeltchenko assoc->offset += frag_len; 863903e4541SAndrei Emeltchenko 864903e4541SAndrei Emeltchenko /* Read other fragments */ 865903e4541SAndrei Emeltchenko amp_read_loc_assoc_frag(hdev, rp->phy_handle); 866903e4541SAndrei Emeltchenko 867903e4541SAndrei Emeltchenko return; 868903e4541SAndrei Emeltchenko } 869903e4541SAndrei Emeltchenko 870903e4541SAndrei Emeltchenko memcpy(assoc->data + assoc->offset, rp->frag, rem_len); 871903e4541SAndrei Emeltchenko assoc->len = assoc->offset + rem_len; 872903e4541SAndrei Emeltchenko assoc->offset = 0; 873903e4541SAndrei Emeltchenko 874903e4541SAndrei Emeltchenko a2mp_rsp: 875903e4541SAndrei Emeltchenko /* Send A2MP Rsp when all fragments are received */ 876903e4541SAndrei Emeltchenko a2mp_send_getampassoc_rsp(hdev, rp->status); 8779495b2eeSAndrei Emeltchenko a2mp_send_create_phy_link_req(hdev, rp->status); 878903e4541SAndrei Emeltchenko } 879903e4541SAndrei Emeltchenko 880d5859e22SJohan Hedberg static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, 881d5859e22SJohan Hedberg struct sk_buff *skb) 882d5859e22SJohan Hedberg { 88391c4e9b1SMarcel Holtmann struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data; 884d5859e22SJohan Hedberg 8859f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 886d5859e22SJohan Hedberg 88745296acdSMarcel Holtmann if (rp->status) 88845296acdSMarcel Holtmann return; 88945296acdSMarcel Holtmann 89091c4e9b1SMarcel Holtmann hdev->inq_tx_power = rp->tx_power; 891d5859e22SJohan Hedberg } 892d5859e22SJohan Hedberg 893980e1a53SJohan Hedberg static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) 894980e1a53SJohan Hedberg { 895980e1a53SJohan Hedberg struct hci_rp_pin_code_reply *rp = (void *) skb->data; 896980e1a53SJohan Hedberg struct hci_cp_pin_code_reply *cp; 897980e1a53SJohan Hedberg struct hci_conn *conn; 898980e1a53SJohan Hedberg 8999f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 900980e1a53SJohan Hedberg 90156e5cb86SJohan Hedberg hci_dev_lock(hdev); 90256e5cb86SJohan Hedberg 903d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 904744cf19eSJohan Hedberg mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); 905980e1a53SJohan Hedberg 906fa1bd918SMikel Astiz if (rp->status) 90756e5cb86SJohan Hedberg goto unlock; 908980e1a53SJohan Hedberg 909980e1a53SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); 910980e1a53SJohan Hedberg if (!cp) 91156e5cb86SJohan Hedberg goto unlock; 912980e1a53SJohan Hedberg 913980e1a53SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 914980e1a53SJohan Hedberg if (conn) 915980e1a53SJohan Hedberg conn->pin_length = cp->pin_len; 91656e5cb86SJohan Hedberg 91756e5cb86SJohan Hedberg unlock: 91856e5cb86SJohan Hedberg hci_dev_unlock(hdev); 919980e1a53SJohan Hedberg } 920980e1a53SJohan Hedberg 921980e1a53SJohan Hedberg static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) 922980e1a53SJohan Hedberg { 923980e1a53SJohan Hedberg struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data; 924980e1a53SJohan Hedberg 9259f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 926980e1a53SJohan Hedberg 92756e5cb86SJohan Hedberg hci_dev_lock(hdev); 92856e5cb86SJohan Hedberg 929d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 930744cf19eSJohan Hedberg mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, 931980e1a53SJohan Hedberg rp->status); 93256e5cb86SJohan Hedberg 93356e5cb86SJohan Hedberg hci_dev_unlock(hdev); 934980e1a53SJohan Hedberg } 93556e5cb86SJohan Hedberg 9366ed58ec5SVille Tervo static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, 9376ed58ec5SVille Tervo struct sk_buff *skb) 9386ed58ec5SVille Tervo { 9396ed58ec5SVille Tervo struct hci_rp_le_read_buffer_size *rp = (void *) skb->data; 9406ed58ec5SVille Tervo 9419f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9426ed58ec5SVille Tervo 9436ed58ec5SVille Tervo if (rp->status) 9446ed58ec5SVille Tervo return; 9456ed58ec5SVille Tervo 9466ed58ec5SVille Tervo hdev->le_mtu = __le16_to_cpu(rp->le_mtu); 9476ed58ec5SVille Tervo hdev->le_pkts = rp->le_max_pkt; 9486ed58ec5SVille Tervo 9496ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 9506ed58ec5SVille Tervo 9516ed58ec5SVille Tervo BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts); 9526ed58ec5SVille Tervo } 953980e1a53SJohan Hedberg 95460e77321SJohan Hedberg static void hci_cc_le_read_local_features(struct hci_dev *hdev, 95560e77321SJohan Hedberg struct sk_buff *skb) 95660e77321SJohan Hedberg { 95760e77321SJohan Hedberg struct hci_rp_le_read_local_features *rp = (void *) skb->data; 95860e77321SJohan Hedberg 95960e77321SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 96060e77321SJohan Hedberg 96145296acdSMarcel Holtmann if (rp->status) 96245296acdSMarcel Holtmann return; 96345296acdSMarcel Holtmann 96460e77321SJohan Hedberg memcpy(hdev->le_features, rp->features, 8); 96560e77321SJohan Hedberg } 96660e77321SJohan Hedberg 9678fa19098SJohan Hedberg static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, 9688fa19098SJohan Hedberg struct sk_buff *skb) 9698fa19098SJohan Hedberg { 9708fa19098SJohan Hedberg struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data; 9718fa19098SJohan Hedberg 9728fa19098SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9738fa19098SJohan Hedberg 97445296acdSMarcel Holtmann if (rp->status) 97545296acdSMarcel Holtmann return; 97645296acdSMarcel Holtmann 9778fa19098SJohan Hedberg hdev->adv_tx_power = rp->tx_power; 9788fa19098SJohan Hedberg } 9798fa19098SJohan Hedberg 980a5c29683SJohan Hedberg static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) 981a5c29683SJohan Hedberg { 982a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 983a5c29683SJohan Hedberg 9849f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 985a5c29683SJohan Hedberg 98656e5cb86SJohan Hedberg hci_dev_lock(hdev); 98756e5cb86SJohan Hedberg 988d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 98904124681SGustavo F. Padovan mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0, 99004124681SGustavo F. Padovan rp->status); 99156e5cb86SJohan Hedberg 99256e5cb86SJohan Hedberg hci_dev_unlock(hdev); 993a5c29683SJohan Hedberg } 994a5c29683SJohan Hedberg 995a5c29683SJohan Hedberg static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, 996a5c29683SJohan Hedberg struct sk_buff *skb) 997a5c29683SJohan Hedberg { 998a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 999a5c29683SJohan Hedberg 10009f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 1001a5c29683SJohan Hedberg 100256e5cb86SJohan Hedberg hci_dev_lock(hdev); 100356e5cb86SJohan Hedberg 1004d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 1005744cf19eSJohan Hedberg mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, 100604124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 100756e5cb86SJohan Hedberg 100856e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1009a5c29683SJohan Hedberg } 1010a5c29683SJohan Hedberg 10111143d458SBrian Gix static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb) 10121143d458SBrian Gix { 10131143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 10141143d458SBrian Gix 10159f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 10161143d458SBrian Gix 10171143d458SBrian Gix hci_dev_lock(hdev); 10181143d458SBrian Gix 1019d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 1020272d90dfSJohan Hedberg mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 1021272d90dfSJohan Hedberg 0, rp->status); 10221143d458SBrian Gix 10231143d458SBrian Gix hci_dev_unlock(hdev); 10241143d458SBrian Gix } 10251143d458SBrian Gix 10261143d458SBrian Gix static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, 10271143d458SBrian Gix struct sk_buff *skb) 10281143d458SBrian Gix { 10291143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 10301143d458SBrian Gix 10319f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 10321143d458SBrian Gix 10331143d458SBrian Gix hci_dev_lock(hdev); 10341143d458SBrian Gix 1035d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 10361143d458SBrian Gix mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr, 103704124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 10381143d458SBrian Gix 10391143d458SBrian Gix hci_dev_unlock(hdev); 10401143d458SBrian Gix } 10411143d458SBrian Gix 10424d2d2796SMarcel Holtmann static void hci_cc_read_local_oob_data(struct hci_dev *hdev, 1043c35938b2SSzymon Janc struct sk_buff *skb) 1044c35938b2SSzymon Janc { 1045c35938b2SSzymon Janc struct hci_rp_read_local_oob_data *rp = (void *) skb->data; 1046c35938b2SSzymon Janc 10479f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 10484d2d2796SMarcel Holtmann } 10494d2d2796SMarcel Holtmann 10504d2d2796SMarcel Holtmann static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, 10514d2d2796SMarcel Holtmann struct sk_buff *skb) 10524d2d2796SMarcel Holtmann { 10534d2d2796SMarcel Holtmann struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data; 10544d2d2796SMarcel Holtmann 10554d2d2796SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 1056c35938b2SSzymon Janc } 1057c35938b2SSzymon Janc 10587a4cd51dSMarcel Holtmann static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb) 10597a4cd51dSMarcel Holtmann { 10607a4cd51dSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 10617a4cd51dSMarcel Holtmann bdaddr_t *sent; 10627a4cd51dSMarcel Holtmann 10637a4cd51dSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 10647a4cd51dSMarcel Holtmann 106545296acdSMarcel Holtmann if (status) 106645296acdSMarcel Holtmann return; 106745296acdSMarcel Holtmann 10687a4cd51dSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR); 10697a4cd51dSMarcel Holtmann if (!sent) 10707a4cd51dSMarcel Holtmann return; 10717a4cd51dSMarcel Holtmann 10727a4cd51dSMarcel Holtmann hci_dev_lock(hdev); 10737a4cd51dSMarcel Holtmann 10747a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, sent); 10757a4cd51dSMarcel Holtmann 10767a4cd51dSMarcel Holtmann hci_dev_unlock(hdev); 10777a4cd51dSMarcel Holtmann } 10787a4cd51dSMarcel Holtmann 1079c1d5dc4aSJohan Hedberg static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) 1080c1d5dc4aSJohan Hedberg { 1081c1d5dc4aSJohan Hedberg __u8 *sent, status = *((__u8 *) skb->data); 1082c1d5dc4aSJohan Hedberg 1083c1d5dc4aSJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 1084c1d5dc4aSJohan Hedberg 108545296acdSMarcel Holtmann if (status) 1086c1d5dc4aSJohan Hedberg return; 1087c1d5dc4aSJohan Hedberg 108845296acdSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE); 108945296acdSMarcel Holtmann if (!sent) 10903c857757SJohan Hedberg return; 10913c857757SJohan Hedberg 1092c1d5dc4aSJohan Hedberg hci_dev_lock(hdev); 1093c1d5dc4aSJohan Hedberg 109449c922bbSStephen Hemminger /* If we're doing connection initiation as peripheral. Set a 10953c857757SJohan Hedberg * timeout in case something goes wrong. 10963c857757SJohan Hedberg */ 10973c857757SJohan Hedberg if (*sent) { 10983c857757SJohan Hedberg struct hci_conn *conn; 10993c857757SJohan Hedberg 1100a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ADV); 110166c417c1SJohan Hedberg 11023c857757SJohan Hedberg conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); 11033c857757SJohan Hedberg if (conn) 11043c857757SJohan Hedberg queue_delayed_work(hdev->workqueue, 11053c857757SJohan Hedberg &conn->le_conn_timeout, 110609ae260bSJohan Hedberg conn->conn_timeout); 110766c417c1SJohan Hedberg } else { 1108a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ADV); 11093c857757SJohan Hedberg } 11103c857757SJohan Hedberg 111104b4edcbSJohan Hedberg hci_dev_unlock(hdev); 1112c1d5dc4aSJohan Hedberg } 1113c1d5dc4aSJohan Hedberg 1114533553f8SMarcel Holtmann static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) 1115533553f8SMarcel Holtmann { 1116533553f8SMarcel Holtmann struct hci_cp_le_set_scan_param *cp; 1117533553f8SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 1118533553f8SMarcel Holtmann 1119533553f8SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 1120533553f8SMarcel Holtmann 112145296acdSMarcel Holtmann if (status) 112245296acdSMarcel Holtmann return; 112345296acdSMarcel Holtmann 1124533553f8SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM); 1125533553f8SMarcel Holtmann if (!cp) 1126533553f8SMarcel Holtmann return; 1127533553f8SMarcel Holtmann 1128533553f8SMarcel Holtmann hci_dev_lock(hdev); 1129533553f8SMarcel Holtmann 1130533553f8SMarcel Holtmann hdev->le_scan_type = cp->type; 1131533553f8SMarcel Holtmann 1132533553f8SMarcel Holtmann hci_dev_unlock(hdev); 1133533553f8SMarcel Holtmann } 1134533553f8SMarcel Holtmann 1135b9a6328fSJohan Hedberg static bool has_pending_adv_report(struct hci_dev *hdev) 1136b9a6328fSJohan Hedberg { 1137b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1138b9a6328fSJohan Hedberg 1139b9a6328fSJohan Hedberg return bacmp(&d->last_adv_addr, BDADDR_ANY); 1140b9a6328fSJohan Hedberg } 1141b9a6328fSJohan Hedberg 1142b9a6328fSJohan Hedberg static void clear_pending_adv_report(struct hci_dev *hdev) 1143b9a6328fSJohan Hedberg { 1144b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1145b9a6328fSJohan Hedberg 1146b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, BDADDR_ANY); 1147b9a6328fSJohan Hedberg d->last_adv_data_len = 0; 1148b9a6328fSJohan Hedberg } 1149b9a6328fSJohan Hedberg 1150b9a6328fSJohan Hedberg static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr, 1151c70a7e4cSMarcel Holtmann u8 bdaddr_type, s8 rssi, u32 flags, 1152c70a7e4cSMarcel Holtmann u8 *data, u8 len) 1153b9a6328fSJohan Hedberg { 1154b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1155b9a6328fSJohan Hedberg 1156b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, bdaddr); 1157b9a6328fSJohan Hedberg d->last_adv_addr_type = bdaddr_type; 1158ff5cd29fSJohan Hedberg d->last_adv_rssi = rssi; 1159c70a7e4cSMarcel Holtmann d->last_adv_flags = flags; 1160b9a6328fSJohan Hedberg memcpy(d->last_adv_data, data, len); 1161b9a6328fSJohan Hedberg d->last_adv_data_len = len; 1162b9a6328fSJohan Hedberg } 1163b9a6328fSJohan Hedberg 1164eb9d91f5SAndre Guedes static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, 1165eb9d91f5SAndre Guedes struct sk_buff *skb) 1166eb9d91f5SAndre Guedes { 1167eb9d91f5SAndre Guedes struct hci_cp_le_set_scan_enable *cp; 1168eb9d91f5SAndre Guedes __u8 status = *((__u8 *) skb->data); 1169eb9d91f5SAndre Guedes 11709f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1171eb9d91f5SAndre Guedes 117245296acdSMarcel Holtmann if (status) 1173eb9d91f5SAndre Guedes return; 1174eb9d91f5SAndre Guedes 117545296acdSMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE); 117645296acdSMarcel Holtmann if (!cp) 11777ba8b4beSAndre Guedes return; 11787ba8b4beSAndre Guedes 11795c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 11805c1a4c8fSJaganath Kanakkassery 11813fd319b8SAndre Guedes switch (cp->enable) { 11823fd319b8SAndre Guedes case LE_SCAN_ENABLE: 1183a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_SCAN); 1184b9a6328fSJohan Hedberg if (hdev->le_scan_type == LE_SCAN_ACTIVE) 1185b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 118668a8aea4SAndrei Emeltchenko break; 118768a8aea4SAndrei Emeltchenko 118876a388beSAndre Guedes case LE_SCAN_DISABLE: 1189b9a6328fSJohan Hedberg /* We do this here instead of when setting DISCOVERY_STOPPED 1190b9a6328fSJohan Hedberg * since the latter would potentially require waiting for 1191b9a6328fSJohan Hedberg * inquiry to stop too. 1192b9a6328fSJohan Hedberg */ 1193b9a6328fSJohan Hedberg if (has_pending_adv_report(hdev)) { 1194b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1195b9a6328fSJohan Hedberg 1196b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 1197ab0aa433SJohan Hedberg d->last_adv_addr_type, NULL, 1198c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags, 1199ab0aa433SJohan Hedberg d->last_adv_data, 1200b9a6328fSJohan Hedberg d->last_adv_data_len, NULL, 0); 1201b9a6328fSJohan Hedberg } 1202b9a6328fSJohan Hedberg 1203317ac8cbSJohan Hedberg /* Cancel this timer so that we don't try to disable scanning 1204317ac8cbSJohan Hedberg * when it's already disabled. 1205317ac8cbSJohan Hedberg */ 1206317ac8cbSJohan Hedberg cancel_delayed_work(&hdev->le_scan_disable); 1207317ac8cbSJohan Hedberg 1208a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_SCAN); 1209e8bb6b97SJohan Hedberg 121081ad6fd9SJohan Hedberg /* The HCI_LE_SCAN_INTERRUPTED flag indicates that we 121181ad6fd9SJohan Hedberg * interrupted scanning due to a connect request. Mark 1212e8bb6b97SJohan Hedberg * therefore discovery as stopped. If this was not 1213e8bb6b97SJohan Hedberg * because of a connect request advertising might have 1214e8bb6b97SJohan Hedberg * been disabled because of active scanning, so 1215e8bb6b97SJohan Hedberg * re-enable it again if necessary. 121681ad6fd9SJohan Hedberg */ 1217a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_LE_SCAN_INTERRUPTED)) 121881ad6fd9SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 1219d7a5a11dSMarcel Holtmann else if (!hci_dev_test_flag(hdev, HCI_LE_ADV) && 122034722277SJohan Hedberg hdev->discovery.state == DISCOVERY_FINDING) 1221e8bb6b97SJohan Hedberg mgmt_reenable_advertising(hdev); 1222e8bb6b97SJohan Hedberg 122368a8aea4SAndrei Emeltchenko break; 122468a8aea4SAndrei Emeltchenko 122568a8aea4SAndrei Emeltchenko default: 122668a8aea4SAndrei Emeltchenko BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable); 122768a8aea4SAndrei Emeltchenko break; 122835815085SAndre Guedes } 12295c1a4c8fSJaganath Kanakkassery 12305c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 1231eb9d91f5SAndre Guedes } 1232eb9d91f5SAndre Guedes 1233cf1d081fSJohan Hedberg static void hci_cc_le_read_white_list_size(struct hci_dev *hdev, 1234cf1d081fSJohan Hedberg struct sk_buff *skb) 1235cf1d081fSJohan Hedberg { 1236cf1d081fSJohan Hedberg struct hci_rp_le_read_white_list_size *rp = (void *) skb->data; 1237cf1d081fSJohan Hedberg 1238cf1d081fSJohan Hedberg BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size); 1239cf1d081fSJohan Hedberg 124045296acdSMarcel Holtmann if (rp->status) 124145296acdSMarcel Holtmann return; 124245296acdSMarcel Holtmann 1243cf1d081fSJohan Hedberg hdev->le_white_list_size = rp->size; 1244cf1d081fSJohan Hedberg } 1245cf1d081fSJohan Hedberg 12460f36b589SMarcel Holtmann static void hci_cc_le_clear_white_list(struct hci_dev *hdev, 12470f36b589SMarcel Holtmann struct sk_buff *skb) 12480f36b589SMarcel Holtmann { 12490f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 12500f36b589SMarcel Holtmann 12510f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 12520f36b589SMarcel Holtmann 125345296acdSMarcel Holtmann if (status) 125445296acdSMarcel Holtmann return; 125545296acdSMarcel Holtmann 1256dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->le_white_list); 12570f36b589SMarcel Holtmann } 12580f36b589SMarcel Holtmann 12590f36b589SMarcel Holtmann static void hci_cc_le_add_to_white_list(struct hci_dev *hdev, 12600f36b589SMarcel Holtmann struct sk_buff *skb) 12610f36b589SMarcel Holtmann { 12620f36b589SMarcel Holtmann struct hci_cp_le_add_to_white_list *sent; 12630f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 12640f36b589SMarcel Holtmann 12650f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 12660f36b589SMarcel Holtmann 126745296acdSMarcel Holtmann if (status) 126845296acdSMarcel Holtmann return; 126945296acdSMarcel Holtmann 12700f36b589SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST); 12710f36b589SMarcel Holtmann if (!sent) 12720f36b589SMarcel Holtmann return; 12730f36b589SMarcel Holtmann 1274dcc36c16SJohan Hedberg hci_bdaddr_list_add(&hdev->le_white_list, &sent->bdaddr, 1275dcc36c16SJohan Hedberg sent->bdaddr_type); 12760f36b589SMarcel Holtmann } 12770f36b589SMarcel Holtmann 12780f36b589SMarcel Holtmann static void hci_cc_le_del_from_white_list(struct hci_dev *hdev, 12790f36b589SMarcel Holtmann struct sk_buff *skb) 12800f36b589SMarcel Holtmann { 12810f36b589SMarcel Holtmann struct hci_cp_le_del_from_white_list *sent; 12820f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 12830f36b589SMarcel Holtmann 12840f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 12850f36b589SMarcel Holtmann 128645296acdSMarcel Holtmann if (status) 128745296acdSMarcel Holtmann return; 128845296acdSMarcel Holtmann 12890f36b589SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST); 12900f36b589SMarcel Holtmann if (!sent) 12910f36b589SMarcel Holtmann return; 12920f36b589SMarcel Holtmann 1293dcc36c16SJohan Hedberg hci_bdaddr_list_del(&hdev->le_white_list, &sent->bdaddr, 1294dcc36c16SJohan Hedberg sent->bdaddr_type); 12950f36b589SMarcel Holtmann } 12960f36b589SMarcel Holtmann 12979b008c04SJohan Hedberg static void hci_cc_le_read_supported_states(struct hci_dev *hdev, 12989b008c04SJohan Hedberg struct sk_buff *skb) 12999b008c04SJohan Hedberg { 13009b008c04SJohan Hedberg struct hci_rp_le_read_supported_states *rp = (void *) skb->data; 13019b008c04SJohan Hedberg 13029b008c04SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 13039b008c04SJohan Hedberg 130445296acdSMarcel Holtmann if (rp->status) 130545296acdSMarcel Holtmann return; 130645296acdSMarcel Holtmann 13079b008c04SJohan Hedberg memcpy(hdev->le_states, rp->le_states, 8); 13089b008c04SJohan Hedberg } 13099b008c04SJohan Hedberg 1310a8e1bfaaSMarcel Holtmann static void hci_cc_le_read_def_data_len(struct hci_dev *hdev, 1311a8e1bfaaSMarcel Holtmann struct sk_buff *skb) 1312a8e1bfaaSMarcel Holtmann { 1313a8e1bfaaSMarcel Holtmann struct hci_rp_le_read_def_data_len *rp = (void *) skb->data; 1314a8e1bfaaSMarcel Holtmann 1315a8e1bfaaSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 1316a8e1bfaaSMarcel Holtmann 1317a8e1bfaaSMarcel Holtmann if (rp->status) 1318a8e1bfaaSMarcel Holtmann return; 1319a8e1bfaaSMarcel Holtmann 1320a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = le16_to_cpu(rp->tx_len); 1321a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = le16_to_cpu(rp->tx_time); 1322a8e1bfaaSMarcel Holtmann } 1323a8e1bfaaSMarcel Holtmann 1324a8e1bfaaSMarcel Holtmann static void hci_cc_le_write_def_data_len(struct hci_dev *hdev, 1325a8e1bfaaSMarcel Holtmann struct sk_buff *skb) 1326a8e1bfaaSMarcel Holtmann { 1327a8e1bfaaSMarcel Holtmann struct hci_cp_le_write_def_data_len *sent; 1328a8e1bfaaSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 1329a8e1bfaaSMarcel Holtmann 1330a8e1bfaaSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 1331a8e1bfaaSMarcel Holtmann 1332a8e1bfaaSMarcel Holtmann if (status) 1333a8e1bfaaSMarcel Holtmann return; 1334a8e1bfaaSMarcel Holtmann 1335a8e1bfaaSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN); 1336a8e1bfaaSMarcel Holtmann if (!sent) 1337a8e1bfaaSMarcel Holtmann return; 1338a8e1bfaaSMarcel Holtmann 1339a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = le16_to_cpu(sent->tx_len); 1340a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = le16_to_cpu(sent->tx_time); 1341a8e1bfaaSMarcel Holtmann } 1342a8e1bfaaSMarcel Holtmann 1343a8e1bfaaSMarcel Holtmann static void hci_cc_le_read_max_data_len(struct hci_dev *hdev, 1344a8e1bfaaSMarcel Holtmann struct sk_buff *skb) 1345a8e1bfaaSMarcel Holtmann { 1346a8e1bfaaSMarcel Holtmann struct hci_rp_le_read_max_data_len *rp = (void *) skb->data; 1347a8e1bfaaSMarcel Holtmann 1348a8e1bfaaSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 1349a8e1bfaaSMarcel Holtmann 1350a8e1bfaaSMarcel Holtmann if (rp->status) 1351a8e1bfaaSMarcel Holtmann return; 1352a8e1bfaaSMarcel Holtmann 1353a8e1bfaaSMarcel Holtmann hdev->le_max_tx_len = le16_to_cpu(rp->tx_len); 1354a8e1bfaaSMarcel Holtmann hdev->le_max_tx_time = le16_to_cpu(rp->tx_time); 1355a8e1bfaaSMarcel Holtmann hdev->le_max_rx_len = le16_to_cpu(rp->rx_len); 1356a8e1bfaaSMarcel Holtmann hdev->le_max_rx_time = le16_to_cpu(rp->rx_time); 1357a8e1bfaaSMarcel Holtmann } 1358a8e1bfaaSMarcel Holtmann 13596039aa73SGustavo Padovan static void hci_cc_write_le_host_supported(struct hci_dev *hdev, 1360f9b49306SAndre Guedes struct sk_buff *skb) 1361f9b49306SAndre Guedes { 136206199cf8SJohan Hedberg struct hci_cp_write_le_host_supported *sent; 1363f9b49306SAndre Guedes __u8 status = *((__u8 *) skb->data); 1364f9b49306SAndre Guedes 13659f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1366f9b49306SAndre Guedes 136745296acdSMarcel Holtmann if (status) 136845296acdSMarcel Holtmann return; 136945296acdSMarcel Holtmann 137006199cf8SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED); 13718f984dfaSJohan Hedberg if (!sent) 1372f9b49306SAndre Guedes return; 1373f9b49306SAndre Guedes 13745c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 13755c1a4c8fSJaganath Kanakkassery 1376416a4ae5SJohan Hedberg if (sent->le) { 1377cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE; 1378a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ENABLED); 1379416a4ae5SJohan Hedberg } else { 1380cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE; 1381a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ENABLED); 1382a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_ADVERTISING); 1383416a4ae5SJohan Hedberg } 138453b2caabSJohan Hedberg 138553b2caabSJohan Hedberg if (sent->simul) 1386cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE_BREDR; 138753b2caabSJohan Hedberg else 1388cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE_BREDR; 13895c1a4c8fSJaganath Kanakkassery 13905c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 13918f984dfaSJohan Hedberg } 1392f9b49306SAndre Guedes 139356ed2cb8SJohan Hedberg static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb) 139456ed2cb8SJohan Hedberg { 139556ed2cb8SJohan Hedberg struct hci_cp_le_set_adv_param *cp; 139656ed2cb8SJohan Hedberg u8 status = *((u8 *) skb->data); 139756ed2cb8SJohan Hedberg 139856ed2cb8SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 139956ed2cb8SJohan Hedberg 140056ed2cb8SJohan Hedberg if (status) 140156ed2cb8SJohan Hedberg return; 140256ed2cb8SJohan Hedberg 140356ed2cb8SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM); 140456ed2cb8SJohan Hedberg if (!cp) 140556ed2cb8SJohan Hedberg return; 140656ed2cb8SJohan Hedberg 140756ed2cb8SJohan Hedberg hci_dev_lock(hdev); 140856ed2cb8SJohan Hedberg hdev->adv_addr_type = cp->own_address_type; 140956ed2cb8SJohan Hedberg hci_dev_unlock(hdev); 141056ed2cb8SJohan Hedberg } 141156ed2cb8SJohan Hedberg 141293c284eeSAndrei Emeltchenko static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev, 141393c284eeSAndrei Emeltchenko struct sk_buff *skb) 141493c284eeSAndrei Emeltchenko { 141593c284eeSAndrei Emeltchenko struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data; 141693c284eeSAndrei Emeltchenko 141793c284eeSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x", 141893c284eeSAndrei Emeltchenko hdev->name, rp->status, rp->phy_handle); 141993c284eeSAndrei Emeltchenko 142093c284eeSAndrei Emeltchenko if (rp->status) 142193c284eeSAndrei Emeltchenko return; 142293c284eeSAndrei Emeltchenko 142393c284eeSAndrei Emeltchenko amp_write_rem_assoc_continue(hdev, rp->phy_handle); 142493c284eeSAndrei Emeltchenko } 142593c284eeSAndrei Emeltchenko 14265ae76a94SAndrzej Kaczmarek static void hci_cc_read_rssi(struct hci_dev *hdev, struct sk_buff *skb) 14275ae76a94SAndrzej Kaczmarek { 14285ae76a94SAndrzej Kaczmarek struct hci_rp_read_rssi *rp = (void *) skb->data; 14295ae76a94SAndrzej Kaczmarek struct hci_conn *conn; 14305ae76a94SAndrzej Kaczmarek 14315ae76a94SAndrzej Kaczmarek BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 14325ae76a94SAndrzej Kaczmarek 14335ae76a94SAndrzej Kaczmarek if (rp->status) 14345ae76a94SAndrzej Kaczmarek return; 14355ae76a94SAndrzej Kaczmarek 14365ae76a94SAndrzej Kaczmarek hci_dev_lock(hdev); 14375ae76a94SAndrzej Kaczmarek 14385ae76a94SAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 14395ae76a94SAndrzej Kaczmarek if (conn) 14405ae76a94SAndrzej Kaczmarek conn->rssi = rp->rssi; 14415ae76a94SAndrzej Kaczmarek 14425ae76a94SAndrzej Kaczmarek hci_dev_unlock(hdev); 14435ae76a94SAndrzej Kaczmarek } 14445ae76a94SAndrzej Kaczmarek 14455a134faeSAndrzej Kaczmarek static void hci_cc_read_tx_power(struct hci_dev *hdev, struct sk_buff *skb) 14465a134faeSAndrzej Kaczmarek { 14475a134faeSAndrzej Kaczmarek struct hci_cp_read_tx_power *sent; 14485a134faeSAndrzej Kaczmarek struct hci_rp_read_tx_power *rp = (void *) skb->data; 14495a134faeSAndrzej Kaczmarek struct hci_conn *conn; 14505a134faeSAndrzej Kaczmarek 14515a134faeSAndrzej Kaczmarek BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 14525a134faeSAndrzej Kaczmarek 14535a134faeSAndrzej Kaczmarek if (rp->status) 14545a134faeSAndrzej Kaczmarek return; 14555a134faeSAndrzej Kaczmarek 14565a134faeSAndrzej Kaczmarek sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER); 14575a134faeSAndrzej Kaczmarek if (!sent) 14585a134faeSAndrzej Kaczmarek return; 14595a134faeSAndrzej Kaczmarek 14605a134faeSAndrzej Kaczmarek hci_dev_lock(hdev); 14615a134faeSAndrzej Kaczmarek 14625a134faeSAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 1463d0455ed9SAndrzej Kaczmarek if (!conn) 1464d0455ed9SAndrzej Kaczmarek goto unlock; 14655a134faeSAndrzej Kaczmarek 1466d0455ed9SAndrzej Kaczmarek switch (sent->type) { 1467d0455ed9SAndrzej Kaczmarek case 0x00: 1468d0455ed9SAndrzej Kaczmarek conn->tx_power = rp->tx_power; 1469d0455ed9SAndrzej Kaczmarek break; 1470d0455ed9SAndrzej Kaczmarek case 0x01: 1471d0455ed9SAndrzej Kaczmarek conn->max_tx_power = rp->tx_power; 1472d0455ed9SAndrzej Kaczmarek break; 1473d0455ed9SAndrzej Kaczmarek } 1474d0455ed9SAndrzej Kaczmarek 1475d0455ed9SAndrzej Kaczmarek unlock: 14765a134faeSAndrzej Kaczmarek hci_dev_unlock(hdev); 14775a134faeSAndrzej Kaczmarek } 14785a134faeSAndrzej Kaczmarek 1479c50b33c8SMarcel Holtmann static void hci_cc_write_ssp_debug_mode(struct hci_dev *hdev, struct sk_buff *skb) 1480c50b33c8SMarcel Holtmann { 1481c50b33c8SMarcel Holtmann u8 status = *((u8 *) skb->data); 1482c50b33c8SMarcel Holtmann u8 *mode; 1483c50b33c8SMarcel Holtmann 1484c50b33c8SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 1485c50b33c8SMarcel Holtmann 1486c50b33c8SMarcel Holtmann if (status) 1487c50b33c8SMarcel Holtmann return; 1488c50b33c8SMarcel Holtmann 1489c50b33c8SMarcel Holtmann mode = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE); 1490c50b33c8SMarcel Holtmann if (mode) 1491c50b33c8SMarcel Holtmann hdev->ssp_debug_mode = *mode; 1492c50b33c8SMarcel Holtmann } 1493c50b33c8SMarcel Holtmann 14946039aa73SGustavo Padovan static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) 1495a9de9248SMarcel Holtmann { 14969f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1497a9de9248SMarcel Holtmann 1498a9de9248SMarcel Holtmann if (status) { 1499a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 1500314b2381SJohan Hedberg return; 1501314b2381SJohan Hedberg } 1502314b2381SJohan Hedberg 150389352e7dSAndre Guedes set_bit(HCI_INQUIRY, &hdev->flags); 1504a9de9248SMarcel Holtmann } 1505a9de9248SMarcel Holtmann 15066039aa73SGustavo Padovan static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) 15071da177e4SLinus Torvalds { 1508a9de9248SMarcel Holtmann struct hci_cp_create_conn *cp; 15091da177e4SLinus Torvalds struct hci_conn *conn; 15101da177e4SLinus Torvalds 15119f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1512a9de9248SMarcel Holtmann 1513a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN); 15141da177e4SLinus Torvalds if (!cp) 15151da177e4SLinus Torvalds return; 15161da177e4SLinus Torvalds 15171da177e4SLinus Torvalds hci_dev_lock(hdev); 15181da177e4SLinus Torvalds 15191da177e4SLinus Torvalds conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 15201da177e4SLinus Torvalds 15216ed93dc6SAndrei Emeltchenko BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn); 15221da177e4SLinus Torvalds 15231da177e4SLinus Torvalds if (status) { 15241da177e4SLinus Torvalds if (conn && conn->state == BT_CONNECT) { 15254c67bc74SMarcel Holtmann if (status != 0x0c || conn->attempt > 2) { 15261da177e4SLinus Torvalds conn->state = BT_CLOSED; 1527539c496dSJohan Hedberg hci_connect_cfm(conn, status); 15281da177e4SLinus Torvalds hci_conn_del(conn); 15294c67bc74SMarcel Holtmann } else 15304c67bc74SMarcel Holtmann conn->state = BT_CONNECT2; 15311da177e4SLinus Torvalds } 15321da177e4SLinus Torvalds } else { 15331da177e4SLinus Torvalds if (!conn) { 1534a5c4e309SJohan Hedberg conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr, 1535a5c4e309SJohan Hedberg HCI_ROLE_MASTER); 1536a5c4e309SJohan Hedberg if (!conn) 1537893ef971SGustavo F. Padovan BT_ERR("No memory for new connection"); 15381da177e4SLinus Torvalds } 15391da177e4SLinus Torvalds } 15401da177e4SLinus Torvalds 15411da177e4SLinus Torvalds hci_dev_unlock(hdev); 15421da177e4SLinus Torvalds } 15431da177e4SLinus Torvalds 1544a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status) 15451da177e4SLinus Torvalds { 1546a9de9248SMarcel Holtmann struct hci_cp_add_sco *cp; 15471da177e4SLinus Torvalds struct hci_conn *acl, *sco; 15481da177e4SLinus Torvalds __u16 handle; 15491da177e4SLinus Torvalds 15509f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1551b6a0dc82SMarcel Holtmann 1552a9de9248SMarcel Holtmann if (!status) 1553a9de9248SMarcel Holtmann return; 1554a9de9248SMarcel Holtmann 1555a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO); 15561da177e4SLinus Torvalds if (!cp) 1557a9de9248SMarcel Holtmann return; 15581da177e4SLinus Torvalds 15591da177e4SLinus Torvalds handle = __le16_to_cpu(cp->handle); 15601da177e4SLinus Torvalds 15619f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, handle); 15621da177e4SLinus Torvalds 15631da177e4SLinus Torvalds hci_dev_lock(hdev); 15641da177e4SLinus Torvalds 15651da177e4SLinus Torvalds acl = hci_conn_hash_lookup_handle(hdev, handle); 15665a08ecceSAndrei Emeltchenko if (acl) { 15675a08ecceSAndrei Emeltchenko sco = acl->link; 15685a08ecceSAndrei Emeltchenko if (sco) { 15691da177e4SLinus Torvalds sco->state = BT_CLOSED; 15701da177e4SLinus Torvalds 1571539c496dSJohan Hedberg hci_connect_cfm(sco, status); 15721da177e4SLinus Torvalds hci_conn_del(sco); 15731da177e4SLinus Torvalds } 15745a08ecceSAndrei Emeltchenko } 15751da177e4SLinus Torvalds 15761da177e4SLinus Torvalds hci_dev_unlock(hdev); 15771da177e4SLinus Torvalds } 15781da177e4SLinus Torvalds 1579f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status) 1580f8558555SMarcel Holtmann { 1581f8558555SMarcel Holtmann struct hci_cp_auth_requested *cp; 1582f8558555SMarcel Holtmann struct hci_conn *conn; 1583f8558555SMarcel Holtmann 15849f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1585f8558555SMarcel Holtmann 1586f8558555SMarcel Holtmann if (!status) 1587f8558555SMarcel Holtmann return; 1588f8558555SMarcel Holtmann 1589f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED); 1590f8558555SMarcel Holtmann if (!cp) 1591f8558555SMarcel Holtmann return; 1592f8558555SMarcel Holtmann 1593f8558555SMarcel Holtmann hci_dev_lock(hdev); 1594f8558555SMarcel Holtmann 1595f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1596f8558555SMarcel Holtmann if (conn) { 1597f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1598539c496dSJohan Hedberg hci_connect_cfm(conn, status); 159976a68ba0SDavid Herrmann hci_conn_drop(conn); 1600f8558555SMarcel Holtmann } 1601f8558555SMarcel Holtmann } 1602f8558555SMarcel Holtmann 1603f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1604f8558555SMarcel Holtmann } 1605f8558555SMarcel Holtmann 1606f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) 1607f8558555SMarcel Holtmann { 1608f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt *cp; 1609f8558555SMarcel Holtmann struct hci_conn *conn; 1610f8558555SMarcel Holtmann 16119f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1612f8558555SMarcel Holtmann 1613f8558555SMarcel Holtmann if (!status) 1614f8558555SMarcel Holtmann return; 1615f8558555SMarcel Holtmann 1616f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT); 1617f8558555SMarcel Holtmann if (!cp) 1618f8558555SMarcel Holtmann return; 1619f8558555SMarcel Holtmann 1620f8558555SMarcel Holtmann hci_dev_lock(hdev); 1621f8558555SMarcel Holtmann 1622f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1623f8558555SMarcel Holtmann if (conn) { 1624f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1625539c496dSJohan Hedberg hci_connect_cfm(conn, status); 162676a68ba0SDavid Herrmann hci_conn_drop(conn); 1627f8558555SMarcel Holtmann } 1628f8558555SMarcel Holtmann } 1629f8558555SMarcel Holtmann 1630f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1631f8558555SMarcel Holtmann } 1632f8558555SMarcel Holtmann 1633127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev, 1634392599b9SJohan Hedberg struct hci_conn *conn) 1635392599b9SJohan Hedberg { 1636392599b9SJohan Hedberg if (conn->state != BT_CONFIG || !conn->out) 1637392599b9SJohan Hedberg return 0; 1638392599b9SJohan Hedberg 1639765c2a96SJohan Hedberg if (conn->pending_sec_level == BT_SECURITY_SDP) 1640392599b9SJohan Hedberg return 0; 1641392599b9SJohan Hedberg 1642392599b9SJohan Hedberg /* Only request authentication for SSP connections or non-SSP 1643264b8b4eSJohan Hedberg * devices with sec_level MEDIUM or HIGH or if MITM protection 1644264b8b4eSJohan Hedberg * is requested. 1645264b8b4eSJohan Hedberg */ 1646807deac2SGustavo Padovan if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) && 16477e3691e1SJohan Hedberg conn->pending_sec_level != BT_SECURITY_FIPS && 1648264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_HIGH && 1649264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_MEDIUM) 1650392599b9SJohan Hedberg return 0; 1651392599b9SJohan Hedberg 1652392599b9SJohan Hedberg return 1; 1653392599b9SJohan Hedberg } 1654392599b9SJohan Hedberg 16556039aa73SGustavo Padovan static int hci_resolve_name(struct hci_dev *hdev, 165600abfe44SGustavo F. Padovan struct inquiry_entry *e) 165730dc78e1SJohan Hedberg { 165830dc78e1SJohan Hedberg struct hci_cp_remote_name_req cp; 165930dc78e1SJohan Hedberg 166030dc78e1SJohan Hedberg memset(&cp, 0, sizeof(cp)); 166130dc78e1SJohan Hedberg 166230dc78e1SJohan Hedberg bacpy(&cp.bdaddr, &e->data.bdaddr); 166330dc78e1SJohan Hedberg cp.pscan_rep_mode = e->data.pscan_rep_mode; 166430dc78e1SJohan Hedberg cp.pscan_mode = e->data.pscan_mode; 166530dc78e1SJohan Hedberg cp.clock_offset = e->data.clock_offset; 166630dc78e1SJohan Hedberg 166730dc78e1SJohan Hedberg return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 166830dc78e1SJohan Hedberg } 166930dc78e1SJohan Hedberg 1670b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev) 167130dc78e1SJohan Hedberg { 167230dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 167330dc78e1SJohan Hedberg struct inquiry_entry *e; 167430dc78e1SJohan Hedberg 1675b644ba33SJohan Hedberg if (list_empty(&discov->resolve)) 1676b644ba33SJohan Hedberg return false; 1677b644ba33SJohan Hedberg 1678b644ba33SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 1679c810089cSRam Malovany if (!e) 1680c810089cSRam Malovany return false; 1681c810089cSRam Malovany 1682b644ba33SJohan Hedberg if (hci_resolve_name(hdev, e) == 0) { 1683b644ba33SJohan Hedberg e->name_state = NAME_PENDING; 1684b644ba33SJohan Hedberg return true; 1685b644ba33SJohan Hedberg } 1686b644ba33SJohan Hedberg 1687b644ba33SJohan Hedberg return false; 1688b644ba33SJohan Hedberg } 1689b644ba33SJohan Hedberg 1690b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, 1691b644ba33SJohan Hedberg bdaddr_t *bdaddr, u8 *name, u8 name_len) 1692b644ba33SJohan Hedberg { 1693b644ba33SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 1694b644ba33SJohan Hedberg struct inquiry_entry *e; 1695b644ba33SJohan Hedberg 169660cb49d2SJohan Hedberg /* Update the mgmt connected state if necessary. Be careful with 169760cb49d2SJohan Hedberg * conn objects that exist but are not (yet) connected however. 169860cb49d2SJohan Hedberg * Only those in BT_CONFIG or BT_CONNECTED states can be 169960cb49d2SJohan Hedberg * considered connected. 170060cb49d2SJohan Hedberg */ 170160cb49d2SJohan Hedberg if (conn && 170260cb49d2SJohan Hedberg (conn->state == BT_CONFIG || conn->state == BT_CONNECTED) && 1703cb77c3ecSJaganath Kanakkassery !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 170448ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, name, name_len); 1705b644ba33SJohan Hedberg 1706b644ba33SJohan Hedberg if (discov->state == DISCOVERY_STOPPED) 1707b644ba33SJohan Hedberg return; 1708b644ba33SJohan Hedberg 170930dc78e1SJohan Hedberg if (discov->state == DISCOVERY_STOPPING) 171030dc78e1SJohan Hedberg goto discov_complete; 171130dc78e1SJohan Hedberg 171230dc78e1SJohan Hedberg if (discov->state != DISCOVERY_RESOLVING) 171330dc78e1SJohan Hedberg return; 171430dc78e1SJohan Hedberg 171530dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING); 17167cc8380eSRam Malovany /* If the device was not found in a list of found devices names of which 17177cc8380eSRam Malovany * are pending. there is no need to continue resolving a next name as it 17187cc8380eSRam Malovany * will be done upon receiving another Remote Name Request Complete 17197cc8380eSRam Malovany * Event */ 17207cc8380eSRam Malovany if (!e) 17217cc8380eSRam Malovany return; 17227cc8380eSRam Malovany 172330dc78e1SJohan Hedberg list_del(&e->list); 17247cc8380eSRam Malovany if (name) { 17257cc8380eSRam Malovany e->name_state = NAME_KNOWN; 1726b644ba33SJohan Hedberg mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, 1727b644ba33SJohan Hedberg e->data.rssi, name, name_len); 1728c3e7c0d9SRam Malovany } else { 1729c3e7c0d9SRam Malovany e->name_state = NAME_NOT_KNOWN; 173030dc78e1SJohan Hedberg } 173130dc78e1SJohan Hedberg 1732b644ba33SJohan Hedberg if (hci_resolve_next_name(hdev)) 173330dc78e1SJohan Hedberg return; 173430dc78e1SJohan Hedberg 173530dc78e1SJohan Hedberg discov_complete: 173630dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 173730dc78e1SJohan Hedberg } 173830dc78e1SJohan Hedberg 1739a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) 17401da177e4SLinus Torvalds { 1741127178d2SJohan Hedberg struct hci_cp_remote_name_req *cp; 1742127178d2SJohan Hedberg struct hci_conn *conn; 1743127178d2SJohan Hedberg 17449f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1745127178d2SJohan Hedberg 1746127178d2SJohan Hedberg /* If successful wait for the name req complete event before 1747127178d2SJohan Hedberg * checking for the need to do authentication */ 1748127178d2SJohan Hedberg if (!status) 1749127178d2SJohan Hedberg return; 1750127178d2SJohan Hedberg 1751127178d2SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ); 1752127178d2SJohan Hedberg if (!cp) 1753127178d2SJohan Hedberg return; 1754127178d2SJohan Hedberg 1755127178d2SJohan Hedberg hci_dev_lock(hdev); 1756127178d2SJohan Hedberg 1757127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 1758b644ba33SJohan Hedberg 1759d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 1760b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0); 1761b644ba33SJohan Hedberg 176279c6c70cSJohan Hedberg if (!conn) 176379c6c70cSJohan Hedberg goto unlock; 176479c6c70cSJohan Hedberg 176579c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 176679c6c70cSJohan Hedberg goto unlock; 176779c6c70cSJohan Hedberg 176851a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 1769c1f23a2bSJohannes Berg struct hci_cp_auth_requested auth_cp; 1770c1f23a2bSJohannes Berg 1771977f8fceSJohan Hedberg set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags); 1772977f8fceSJohan Hedberg 1773c1f23a2bSJohannes Berg auth_cp.handle = __cpu_to_le16(conn->handle); 1774c1f23a2bSJohannes Berg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, 1775c1f23a2bSJohannes Berg sizeof(auth_cp), &auth_cp); 1776127178d2SJohan Hedberg } 1777127178d2SJohan Hedberg 177879c6c70cSJohan Hedberg unlock: 1779127178d2SJohan Hedberg hci_dev_unlock(hdev); 1780a9de9248SMarcel Holtmann } 17811da177e4SLinus Torvalds 1782769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) 1783769be974SMarcel Holtmann { 1784769be974SMarcel Holtmann struct hci_cp_read_remote_features *cp; 1785769be974SMarcel Holtmann struct hci_conn *conn; 1786769be974SMarcel Holtmann 17879f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1788769be974SMarcel Holtmann 1789769be974SMarcel Holtmann if (!status) 1790769be974SMarcel Holtmann return; 1791769be974SMarcel Holtmann 1792769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES); 1793769be974SMarcel Holtmann if (!cp) 1794769be974SMarcel Holtmann return; 1795769be974SMarcel Holtmann 1796769be974SMarcel Holtmann hci_dev_lock(hdev); 1797769be974SMarcel Holtmann 1798769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1799769be974SMarcel Holtmann if (conn) { 1800769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1801539c496dSJohan Hedberg hci_connect_cfm(conn, status); 180276a68ba0SDavid Herrmann hci_conn_drop(conn); 1803769be974SMarcel Holtmann } 1804769be974SMarcel Holtmann } 1805769be974SMarcel Holtmann 1806769be974SMarcel Holtmann hci_dev_unlock(hdev); 1807769be974SMarcel Holtmann } 1808769be974SMarcel Holtmann 1809769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status) 1810769be974SMarcel Holtmann { 1811769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features *cp; 1812769be974SMarcel Holtmann struct hci_conn *conn; 1813769be974SMarcel Holtmann 18149f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1815769be974SMarcel Holtmann 1816769be974SMarcel Holtmann if (!status) 1817769be974SMarcel Holtmann return; 1818769be974SMarcel Holtmann 1819769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES); 1820769be974SMarcel Holtmann if (!cp) 1821769be974SMarcel Holtmann return; 1822769be974SMarcel Holtmann 1823769be974SMarcel Holtmann hci_dev_lock(hdev); 1824769be974SMarcel Holtmann 1825769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1826769be974SMarcel Holtmann if (conn) { 1827769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1828539c496dSJohan Hedberg hci_connect_cfm(conn, status); 182976a68ba0SDavid Herrmann hci_conn_drop(conn); 1830769be974SMarcel Holtmann } 1831769be974SMarcel Holtmann } 1832769be974SMarcel Holtmann 1833769be974SMarcel Holtmann hci_dev_unlock(hdev); 1834769be974SMarcel Holtmann } 1835769be974SMarcel Holtmann 1836a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) 1837a9de9248SMarcel Holtmann { 1838b6a0dc82SMarcel Holtmann struct hci_cp_setup_sync_conn *cp; 1839b6a0dc82SMarcel Holtmann struct hci_conn *acl, *sco; 1840b6a0dc82SMarcel Holtmann __u16 handle; 1841b6a0dc82SMarcel Holtmann 18429f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1843b6a0dc82SMarcel Holtmann 1844b6a0dc82SMarcel Holtmann if (!status) 1845b6a0dc82SMarcel Holtmann return; 1846b6a0dc82SMarcel Holtmann 1847b6a0dc82SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN); 1848b6a0dc82SMarcel Holtmann if (!cp) 1849b6a0dc82SMarcel Holtmann return; 1850b6a0dc82SMarcel Holtmann 1851b6a0dc82SMarcel Holtmann handle = __le16_to_cpu(cp->handle); 1852b6a0dc82SMarcel Holtmann 18539f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, handle); 1854b6a0dc82SMarcel Holtmann 1855b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 1856b6a0dc82SMarcel Holtmann 1857b6a0dc82SMarcel Holtmann acl = hci_conn_hash_lookup_handle(hdev, handle); 18585a08ecceSAndrei Emeltchenko if (acl) { 18595a08ecceSAndrei Emeltchenko sco = acl->link; 18605a08ecceSAndrei Emeltchenko if (sco) { 1861b6a0dc82SMarcel Holtmann sco->state = BT_CLOSED; 1862b6a0dc82SMarcel Holtmann 1863539c496dSJohan Hedberg hci_connect_cfm(sco, status); 1864b6a0dc82SMarcel Holtmann hci_conn_del(sco); 1865b6a0dc82SMarcel Holtmann } 18665a08ecceSAndrei Emeltchenko } 1867b6a0dc82SMarcel Holtmann 1868b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 1869a9de9248SMarcel Holtmann } 1870a9de9248SMarcel Holtmann 1871a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) 1872a9de9248SMarcel Holtmann { 1873a9de9248SMarcel Holtmann struct hci_cp_sniff_mode *cp; 187404837f64SMarcel Holtmann struct hci_conn *conn; 187504837f64SMarcel Holtmann 18769f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1877a9de9248SMarcel Holtmann 1878a9de9248SMarcel Holtmann if (!status) 1879a9de9248SMarcel Holtmann return; 1880a9de9248SMarcel Holtmann 1881a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE); 188204837f64SMarcel Holtmann if (!cp) 1883a9de9248SMarcel Holtmann return; 188404837f64SMarcel Holtmann 188504837f64SMarcel Holtmann hci_dev_lock(hdev); 188604837f64SMarcel Holtmann 188704837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1888e73439d8SMarcel Holtmann if (conn) { 188951a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 189004837f64SMarcel Holtmann 189151a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 1892e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 1893e73439d8SMarcel Holtmann } 1894e73439d8SMarcel Holtmann 189504837f64SMarcel Holtmann hci_dev_unlock(hdev); 189604837f64SMarcel Holtmann } 189704837f64SMarcel Holtmann 1898a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) 1899a9de9248SMarcel Holtmann { 1900a9de9248SMarcel Holtmann struct hci_cp_exit_sniff_mode *cp; 190104837f64SMarcel Holtmann struct hci_conn *conn; 190204837f64SMarcel Holtmann 19039f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1904a9de9248SMarcel Holtmann 1905a9de9248SMarcel Holtmann if (!status) 1906a9de9248SMarcel Holtmann return; 1907a9de9248SMarcel Holtmann 1908a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE); 190904837f64SMarcel Holtmann if (!cp) 1910a9de9248SMarcel Holtmann return; 191104837f64SMarcel Holtmann 191204837f64SMarcel Holtmann hci_dev_lock(hdev); 191304837f64SMarcel Holtmann 191404837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1915e73439d8SMarcel Holtmann if (conn) { 191651a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 191704837f64SMarcel Holtmann 191851a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 1919e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 1920e73439d8SMarcel Holtmann } 1921e73439d8SMarcel Holtmann 192204837f64SMarcel Holtmann hci_dev_unlock(hdev); 192304837f64SMarcel Holtmann } 192404837f64SMarcel Holtmann 192588c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) 192688c3df13SJohan Hedberg { 192788c3df13SJohan Hedberg struct hci_cp_disconnect *cp; 192888c3df13SJohan Hedberg struct hci_conn *conn; 192988c3df13SJohan Hedberg 193088c3df13SJohan Hedberg if (!status) 193188c3df13SJohan Hedberg return; 193288c3df13SJohan Hedberg 193388c3df13SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT); 193488c3df13SJohan Hedberg if (!cp) 193588c3df13SJohan Hedberg return; 193688c3df13SJohan Hedberg 193788c3df13SJohan Hedberg hci_dev_lock(hdev); 193888c3df13SJohan Hedberg 193988c3df13SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 194088c3df13SJohan Hedberg if (conn) 194188c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 194288c3df13SJohan Hedberg conn->dst_type, status); 194388c3df13SJohan Hedberg 194488c3df13SJohan Hedberg hci_dev_unlock(hdev); 194588c3df13SJohan Hedberg } 194688c3df13SJohan Hedberg 1947a02226d6SAndrei Emeltchenko static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status) 1948a02226d6SAndrei Emeltchenko { 194993c284eeSAndrei Emeltchenko struct hci_cp_create_phy_link *cp; 195093c284eeSAndrei Emeltchenko 1951a02226d6SAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 195293c284eeSAndrei Emeltchenko 195393c284eeSAndrei Emeltchenko cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK); 195493c284eeSAndrei Emeltchenko if (!cp) 195593c284eeSAndrei Emeltchenko return; 195693c284eeSAndrei Emeltchenko 1957e58917b9SAndrei Emeltchenko hci_dev_lock(hdev); 1958e58917b9SAndrei Emeltchenko 1959e58917b9SAndrei Emeltchenko if (status) { 1960e58917b9SAndrei Emeltchenko struct hci_conn *hcon; 1961e58917b9SAndrei Emeltchenko 1962e58917b9SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle); 1963e58917b9SAndrei Emeltchenko if (hcon) 1964e58917b9SAndrei Emeltchenko hci_conn_del(hcon); 1965e58917b9SAndrei Emeltchenko } else { 196693c284eeSAndrei Emeltchenko amp_write_remote_assoc(hdev, cp->phy_handle); 1967a02226d6SAndrei Emeltchenko } 1968a02226d6SAndrei Emeltchenko 1969e58917b9SAndrei Emeltchenko hci_dev_unlock(hdev); 1970e58917b9SAndrei Emeltchenko } 1971e58917b9SAndrei Emeltchenko 19720b26ab9dSAndrei Emeltchenko static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status) 19730b26ab9dSAndrei Emeltchenko { 19740b26ab9dSAndrei Emeltchenko struct hci_cp_accept_phy_link *cp; 19750b26ab9dSAndrei Emeltchenko 19760b26ab9dSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 19770b26ab9dSAndrei Emeltchenko 19780b26ab9dSAndrei Emeltchenko if (status) 19790b26ab9dSAndrei Emeltchenko return; 19800b26ab9dSAndrei Emeltchenko 19810b26ab9dSAndrei Emeltchenko cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK); 19820b26ab9dSAndrei Emeltchenko if (!cp) 19830b26ab9dSAndrei Emeltchenko return; 19840b26ab9dSAndrei Emeltchenko 19850b26ab9dSAndrei Emeltchenko amp_write_remote_assoc(hdev, cp->phy_handle); 19860b26ab9dSAndrei Emeltchenko } 19870b26ab9dSAndrei Emeltchenko 1988cb1d68f7SJohan Hedberg static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status) 1989cb1d68f7SJohan Hedberg { 1990cb1d68f7SJohan Hedberg struct hci_cp_le_create_conn *cp; 1991cb1d68f7SJohan Hedberg struct hci_conn *conn; 1992cb1d68f7SJohan Hedberg 1993cb1d68f7SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 1994cb1d68f7SJohan Hedberg 1995cb1d68f7SJohan Hedberg /* All connection failure handling is taken care of by the 1996cb1d68f7SJohan Hedberg * hci_le_conn_failed function which is triggered by the HCI 1997cb1d68f7SJohan Hedberg * request completion callbacks used for connecting. 1998cb1d68f7SJohan Hedberg */ 1999cb1d68f7SJohan Hedberg if (status) 2000cb1d68f7SJohan Hedberg return; 2001cb1d68f7SJohan Hedberg 2002cb1d68f7SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN); 2003cb1d68f7SJohan Hedberg if (!cp) 2004cb1d68f7SJohan Hedberg return; 2005cb1d68f7SJohan Hedberg 2006cb1d68f7SJohan Hedberg hci_dev_lock(hdev); 2007cb1d68f7SJohan Hedberg 2008cb1d68f7SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr); 2009cb1d68f7SJohan Hedberg if (!conn) 2010cb1d68f7SJohan Hedberg goto unlock; 2011cb1d68f7SJohan Hedberg 2012cb1d68f7SJohan Hedberg /* Store the initiator and responder address information which 2013cb1d68f7SJohan Hedberg * is needed for SMP. These values will not change during the 2014cb1d68f7SJohan Hedberg * lifetime of the connection. 2015cb1d68f7SJohan Hedberg */ 2016cb1d68f7SJohan Hedberg conn->init_addr_type = cp->own_address_type; 2017cb1d68f7SJohan Hedberg if (cp->own_address_type == ADDR_LE_DEV_RANDOM) 2018cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->random_addr); 2019cb1d68f7SJohan Hedberg else 2020cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->bdaddr); 2021cb1d68f7SJohan Hedberg 2022cb1d68f7SJohan Hedberg conn->resp_addr_type = cp->peer_addr_type; 2023cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &cp->peer_addr); 2024cb1d68f7SJohan Hedberg 20259489eca4SJohan Hedberg /* We don't want the connection attempt to stick around 20269489eca4SJohan Hedberg * indefinitely since LE doesn't have a page timeout concept 20279489eca4SJohan Hedberg * like BR/EDR. Set a timer for any connection that doesn't use 20289489eca4SJohan Hedberg * the white list for connecting. 20299489eca4SJohan Hedberg */ 20309489eca4SJohan Hedberg if (cp->filter_policy == HCI_LE_USE_PEER_ADDR) 20319489eca4SJohan Hedberg queue_delayed_work(conn->hdev->workqueue, 20329489eca4SJohan Hedberg &conn->le_conn_timeout, 203309ae260bSJohan Hedberg conn->conn_timeout); 20349489eca4SJohan Hedberg 2035cb1d68f7SJohan Hedberg unlock: 2036cb1d68f7SJohan Hedberg hci_dev_unlock(hdev); 2037cb1d68f7SJohan Hedberg } 2038cb1d68f7SJohan Hedberg 20390fe29fd1SMarcel Holtmann static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status) 20400fe29fd1SMarcel Holtmann { 20410fe29fd1SMarcel Holtmann struct hci_cp_le_read_remote_features *cp; 20420fe29fd1SMarcel Holtmann struct hci_conn *conn; 20430fe29fd1SMarcel Holtmann 20440fe29fd1SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 20450fe29fd1SMarcel Holtmann 20460fe29fd1SMarcel Holtmann if (!status) 20470fe29fd1SMarcel Holtmann return; 20480fe29fd1SMarcel Holtmann 20490fe29fd1SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_READ_REMOTE_FEATURES); 20500fe29fd1SMarcel Holtmann if (!cp) 20510fe29fd1SMarcel Holtmann return; 20520fe29fd1SMarcel Holtmann 20530fe29fd1SMarcel Holtmann hci_dev_lock(hdev); 20540fe29fd1SMarcel Holtmann 20550fe29fd1SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 20560fe29fd1SMarcel Holtmann if (conn) { 20570fe29fd1SMarcel Holtmann if (conn->state == BT_CONFIG) { 20580fe29fd1SMarcel Holtmann hci_connect_cfm(conn, status); 20590fe29fd1SMarcel Holtmann hci_conn_drop(conn); 20600fe29fd1SMarcel Holtmann } 20610fe29fd1SMarcel Holtmann } 20620fe29fd1SMarcel Holtmann 20630fe29fd1SMarcel Holtmann hci_dev_unlock(hdev); 20640fe29fd1SMarcel Holtmann } 20650fe29fd1SMarcel Holtmann 206681d0c8adSJohan Hedberg static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) 206781d0c8adSJohan Hedberg { 206881d0c8adSJohan Hedberg struct hci_cp_le_start_enc *cp; 206981d0c8adSJohan Hedberg struct hci_conn *conn; 207081d0c8adSJohan Hedberg 207181d0c8adSJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 207281d0c8adSJohan Hedberg 207381d0c8adSJohan Hedberg if (!status) 207481d0c8adSJohan Hedberg return; 207581d0c8adSJohan Hedberg 207681d0c8adSJohan Hedberg hci_dev_lock(hdev); 207781d0c8adSJohan Hedberg 207881d0c8adSJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC); 207981d0c8adSJohan Hedberg if (!cp) 208081d0c8adSJohan Hedberg goto unlock; 208181d0c8adSJohan Hedberg 208281d0c8adSJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 208381d0c8adSJohan Hedberg if (!conn) 208481d0c8adSJohan Hedberg goto unlock; 208581d0c8adSJohan Hedberg 208681d0c8adSJohan Hedberg if (conn->state != BT_CONNECTED) 208781d0c8adSJohan Hedberg goto unlock; 208881d0c8adSJohan Hedberg 208981d0c8adSJohan Hedberg hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 209081d0c8adSJohan Hedberg hci_conn_drop(conn); 209181d0c8adSJohan Hedberg 209281d0c8adSJohan Hedberg unlock: 209381d0c8adSJohan Hedberg hci_dev_unlock(hdev); 209481d0c8adSJohan Hedberg } 209581d0c8adSJohan Hedberg 209650fc85f1SKuba Pawlak static void hci_cs_switch_role(struct hci_dev *hdev, u8 status) 209750fc85f1SKuba Pawlak { 209850fc85f1SKuba Pawlak struct hci_cp_switch_role *cp; 209950fc85f1SKuba Pawlak struct hci_conn *conn; 210050fc85f1SKuba Pawlak 210150fc85f1SKuba Pawlak BT_DBG("%s status 0x%2.2x", hdev->name, status); 210250fc85f1SKuba Pawlak 210350fc85f1SKuba Pawlak if (!status) 210450fc85f1SKuba Pawlak return; 210550fc85f1SKuba Pawlak 210650fc85f1SKuba Pawlak cp = hci_sent_cmd_data(hdev, HCI_OP_SWITCH_ROLE); 210750fc85f1SKuba Pawlak if (!cp) 210850fc85f1SKuba Pawlak return; 210950fc85f1SKuba Pawlak 211050fc85f1SKuba Pawlak hci_dev_lock(hdev); 211150fc85f1SKuba Pawlak 211250fc85f1SKuba Pawlak conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 211350fc85f1SKuba Pawlak if (conn) 211450fc85f1SKuba Pawlak clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 211550fc85f1SKuba Pawlak 211650fc85f1SKuba Pawlak hci_dev_unlock(hdev); 211750fc85f1SKuba Pawlak } 211850fc85f1SKuba Pawlak 21196039aa73SGustavo Padovan static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 21201da177e4SLinus Torvalds { 21211da177e4SLinus Torvalds __u8 status = *((__u8 *) skb->data); 212230dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 212330dc78e1SJohan Hedberg struct inquiry_entry *e; 21241da177e4SLinus Torvalds 21259f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 21261da177e4SLinus Torvalds 2127a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 212889352e7dSAndre Guedes 212989352e7dSAndre Guedes if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) 213089352e7dSAndre Guedes return; 213189352e7dSAndre Guedes 21324e857c58SPeter Zijlstra smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */ 21333e13fa1eSAndre Guedes wake_up_bit(&hdev->flags, HCI_INQUIRY); 21343e13fa1eSAndre Guedes 2135d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 213630dc78e1SJohan Hedberg return; 213730dc78e1SJohan Hedberg 213856e5cb86SJohan Hedberg hci_dev_lock(hdev); 213930dc78e1SJohan Hedberg 2140343f935bSAndre Guedes if (discov->state != DISCOVERY_FINDING) 214130dc78e1SJohan Hedberg goto unlock; 214230dc78e1SJohan Hedberg 214330dc78e1SJohan Hedberg if (list_empty(&discov->resolve)) { 214407d2334aSJakub Pawlowski /* When BR/EDR inquiry is active and no LE scanning is in 214507d2334aSJakub Pawlowski * progress, then change discovery state to indicate completion. 214607d2334aSJakub Pawlowski * 214707d2334aSJakub Pawlowski * When running LE scanning and BR/EDR inquiry simultaneously 214807d2334aSJakub Pawlowski * and the LE scan already finished, then change the discovery 214907d2334aSJakub Pawlowski * state to indicate completion. 215007d2334aSJakub Pawlowski */ 215107d2334aSJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) || 215207d2334aSJakub Pawlowski !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks)) 2153ff9ef578SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 215430dc78e1SJohan Hedberg goto unlock; 215530dc78e1SJohan Hedberg } 215630dc78e1SJohan Hedberg 215730dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 215830dc78e1SJohan Hedberg if (e && hci_resolve_name(hdev, e) == 0) { 215930dc78e1SJohan Hedberg e->name_state = NAME_PENDING; 216030dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_RESOLVING); 216130dc78e1SJohan Hedberg } else { 216207d2334aSJakub Pawlowski /* When BR/EDR inquiry is active and no LE scanning is in 216307d2334aSJakub Pawlowski * progress, then change discovery state to indicate completion. 216407d2334aSJakub Pawlowski * 216507d2334aSJakub Pawlowski * When running LE scanning and BR/EDR inquiry simultaneously 216607d2334aSJakub Pawlowski * and the LE scan already finished, then change the discovery 216707d2334aSJakub Pawlowski * state to indicate completion. 216807d2334aSJakub Pawlowski */ 216907d2334aSJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) || 217007d2334aSJakub Pawlowski !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks)) 217130dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 217230dc78e1SJohan Hedberg } 217330dc78e1SJohan Hedberg 217430dc78e1SJohan Hedberg unlock: 217556e5cb86SJohan Hedberg hci_dev_unlock(hdev); 21761da177e4SLinus Torvalds } 21771da177e4SLinus Torvalds 21786039aa73SGustavo Padovan static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) 21791da177e4SLinus Torvalds { 218045bb4bf0SMarcel Holtmann struct inquiry_data data; 2181a9de9248SMarcel Holtmann struct inquiry_info *info = (void *) (skb->data + 1); 21821da177e4SLinus Torvalds int num_rsp = *((__u8 *) skb->data); 21831da177e4SLinus Torvalds 21841da177e4SLinus Torvalds BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 21851da177e4SLinus Torvalds 218645bb4bf0SMarcel Holtmann if (!num_rsp) 218745bb4bf0SMarcel Holtmann return; 218845bb4bf0SMarcel Holtmann 2189d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) 21901519cc17SAndre Guedes return; 21911519cc17SAndre Guedes 21921da177e4SLinus Torvalds hci_dev_lock(hdev); 219345bb4bf0SMarcel Holtmann 2194e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 2195af58925cSMarcel Holtmann u32 flags; 21963175405bSJohan Hedberg 21971da177e4SLinus Torvalds bacpy(&data.bdaddr, &info->bdaddr); 21981da177e4SLinus Torvalds data.pscan_rep_mode = info->pscan_rep_mode; 21991da177e4SLinus Torvalds data.pscan_period_mode = info->pscan_period_mode; 22001da177e4SLinus Torvalds data.pscan_mode = info->pscan_mode; 22011da177e4SLinus Torvalds memcpy(data.dev_class, info->dev_class, 3); 22021da177e4SLinus Torvalds data.clock_offset = info->clock_offset; 2203efb2513fSMarcel Holtmann data.rssi = HCI_RSSI_INVALID; 220441a96212SMarcel Holtmann data.ssp_mode = 0x00; 22053175405bSJohan Hedberg 2206af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 2207af58925cSMarcel Holtmann 220848264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 2209efb2513fSMarcel Holtmann info->dev_class, HCI_RSSI_INVALID, 2210efb2513fSMarcel Holtmann flags, NULL, 0, NULL, 0); 22111da177e4SLinus Torvalds } 221245bb4bf0SMarcel Holtmann 22131da177e4SLinus Torvalds hci_dev_unlock(hdev); 22141da177e4SLinus Torvalds } 22151da177e4SLinus Torvalds 22166039aa73SGustavo Padovan static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 22171da177e4SLinus Torvalds { 2218a9de9248SMarcel Holtmann struct hci_ev_conn_complete *ev = (void *) skb->data; 2219a9de9248SMarcel Holtmann struct hci_conn *conn; 22201da177e4SLinus Torvalds 2221a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 222245bb4bf0SMarcel Holtmann 22231da177e4SLinus Torvalds hci_dev_lock(hdev); 222445bb4bf0SMarcel Holtmann 2225a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 22269499237aSMarcel Holtmann if (!conn) { 22279499237aSMarcel Holtmann if (ev->link_type != SCO_LINK) 22289499237aSMarcel Holtmann goto unlock; 22299499237aSMarcel Holtmann 22309499237aSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 2231a9de9248SMarcel Holtmann if (!conn) 2232a9de9248SMarcel Holtmann goto unlock; 223345bb4bf0SMarcel Holtmann 22349499237aSMarcel Holtmann conn->type = SCO_LINK; 22359499237aSMarcel Holtmann } 22369499237aSMarcel Holtmann 2237a9de9248SMarcel Holtmann if (!ev->status) { 2238a9de9248SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 2239769be974SMarcel Holtmann 2240769be974SMarcel Holtmann if (conn->type == ACL_LINK) { 2241769be974SMarcel Holtmann conn->state = BT_CONFIG; 2242769be974SMarcel Holtmann hci_conn_hold(conn); 2243a9ea3ed9SSzymon Janc 2244a9ea3ed9SSzymon Janc if (!conn->out && !hci_conn_ssp_enabled(conn) && 2245a9ea3ed9SSzymon Janc !hci_find_link_key(hdev, &ev->bdaddr)) 2246a9ea3ed9SSzymon Janc conn->disc_timeout = HCI_PAIRING_TIMEOUT; 2247a9ea3ed9SSzymon Janc else 2248052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 2249769be974SMarcel Holtmann } else 2250a9de9248SMarcel Holtmann conn->state = BT_CONNECTED; 2251a9de9248SMarcel Holtmann 225223b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn); 22537d0db0a3SMarcel Holtmann hci_conn_add_sysfs(conn); 22547d0db0a3SMarcel Holtmann 2255a9de9248SMarcel Holtmann if (test_bit(HCI_AUTH, &hdev->flags)) 22564dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 2257a9de9248SMarcel Holtmann 2258a9de9248SMarcel Holtmann if (test_bit(HCI_ENCRYPT, &hdev->flags)) 22594dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags); 2260a9de9248SMarcel Holtmann 2261a9de9248SMarcel Holtmann /* Get remote features */ 2262a9de9248SMarcel Holtmann if (conn->type == ACL_LINK) { 2263a9de9248SMarcel Holtmann struct hci_cp_read_remote_features cp; 2264a9de9248SMarcel Holtmann cp.handle = ev->handle; 2265769be974SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, 2266769be974SMarcel Holtmann sizeof(cp), &cp); 226722f433dcSJohan Hedberg 22681d2dc5b7SJohan Hedberg hci_update_page_scan(hdev); 226945bb4bf0SMarcel Holtmann } 2270a9de9248SMarcel Holtmann 2271a9de9248SMarcel Holtmann /* Set packet type for incoming connection */ 2272d095c1ebSAndrei Emeltchenko if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) { 2273a9de9248SMarcel Holtmann struct hci_cp_change_conn_ptype cp; 2274a9de9248SMarcel Holtmann cp.handle = ev->handle; 2275a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 227604124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), 227704124681SGustavo F. Padovan &cp); 2278a9de9248SMarcel Holtmann } 227917d5c04cSJohan Hedberg } else { 2280a9de9248SMarcel Holtmann conn->state = BT_CLOSED; 228117d5c04cSJohan Hedberg if (conn->type == ACL_LINK) 228264c7b77cSMarcel Holtmann mgmt_connect_failed(hdev, &conn->dst, conn->type, 228348264f06SJohan Hedberg conn->dst_type, ev->status); 228417d5c04cSJohan Hedberg } 228545bb4bf0SMarcel Holtmann 2286e73439d8SMarcel Holtmann if (conn->type == ACL_LINK) 2287e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 228845bb4bf0SMarcel Holtmann 2289769be974SMarcel Holtmann if (ev->status) { 2290539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 2291a9de9248SMarcel Holtmann hci_conn_del(conn); 2292c89b6e6bSMarcel Holtmann } else if (ev->link_type != ACL_LINK) 2293539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 2294a9de9248SMarcel Holtmann 2295a9de9248SMarcel Holtmann unlock: 22961da177e4SLinus Torvalds hci_dev_unlock(hdev); 2297a9de9248SMarcel Holtmann 2298a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 22991da177e4SLinus Torvalds } 23001da177e4SLinus Torvalds 230170c46425SJohan Hedberg static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr) 230270c46425SJohan Hedberg { 230370c46425SJohan Hedberg struct hci_cp_reject_conn_req cp; 230470c46425SJohan Hedberg 230570c46425SJohan Hedberg bacpy(&cp.bdaddr, bdaddr); 230670c46425SJohan Hedberg cp.reason = HCI_ERROR_REJ_BAD_ADDR; 230770c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); 230870c46425SJohan Hedberg } 230970c46425SJohan Hedberg 23106039aa73SGustavo Padovan static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 23111da177e4SLinus Torvalds { 2312a9de9248SMarcel Holtmann struct hci_ev_conn_request *ev = (void *) skb->data; 23131da177e4SLinus Torvalds int mask = hdev->link_mode; 231470c46425SJohan Hedberg struct inquiry_entry *ie; 231570c46425SJohan Hedberg struct hci_conn *conn; 231620714bfeSFrédéric Dalleau __u8 flags = 0; 23171da177e4SLinus Torvalds 23186ed93dc6SAndrei Emeltchenko BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr, 2319807deac2SGustavo Padovan ev->link_type); 23201da177e4SLinus Torvalds 232120714bfeSFrédéric Dalleau mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type, 232220714bfeSFrédéric Dalleau &flags); 23231da177e4SLinus Torvalds 232470c46425SJohan Hedberg if (!(mask & HCI_LM_ACCEPT)) { 232570c46425SJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 232670c46425SJohan Hedberg return; 232770c46425SJohan Hedberg } 232870c46425SJohan Hedberg 2329a55bd29dSJohan Hedberg if (hci_bdaddr_list_lookup(&hdev->blacklist, &ev->bdaddr, 2330dcc36c16SJohan Hedberg BDADDR_BREDR)) { 233170c46425SJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 233270c46425SJohan Hedberg return; 233370c46425SJohan Hedberg } 233446c4c941SJohan Hedberg 23356a8fc95cSJohan Hedberg /* Require HCI_CONNECTABLE or a whitelist entry to accept the 23366a8fc95cSJohan Hedberg * connection. These features are only touched through mgmt so 23376a8fc95cSJohan Hedberg * only do the checks if HCI_MGMT is set. 23386a8fc95cSJohan Hedberg */ 2339d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT) && 2340d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONNECTABLE) && 234146c4c941SJohan Hedberg !hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr, 2342a55bd29dSJohan Hedberg BDADDR_BREDR)) { 2343a55bd29dSJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 2344a55bd29dSJohan Hedberg return; 2345a55bd29dSJohan Hedberg } 234670c46425SJohan Hedberg 23471da177e4SLinus Torvalds /* Connection accepted */ 23481da177e4SLinus Torvalds 23491da177e4SLinus Torvalds hci_dev_lock(hdev); 2350b6a0dc82SMarcel Holtmann 2351cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 2352cc11b9c1SAndrei Emeltchenko if (ie) 2353c7bdd502SMarcel Holtmann memcpy(ie->data.dev_class, ev->dev_class, 3); 2354c7bdd502SMarcel Holtmann 23558fc9ced3SGustavo Padovan conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, 23568fc9ced3SGustavo Padovan &ev->bdaddr); 23571da177e4SLinus Torvalds if (!conn) { 2358a5c4e309SJohan Hedberg conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr, 2359a5c4e309SJohan Hedberg HCI_ROLE_SLAVE); 2360cc11b9c1SAndrei Emeltchenko if (!conn) { 2361893ef971SGustavo F. Padovan BT_ERR("No memory for new connection"); 23621da177e4SLinus Torvalds hci_dev_unlock(hdev); 23631da177e4SLinus Torvalds return; 23641da177e4SLinus Torvalds } 23651da177e4SLinus Torvalds } 2366b6a0dc82SMarcel Holtmann 23671da177e4SLinus Torvalds memcpy(conn->dev_class, ev->dev_class, 3); 2368b6a0dc82SMarcel Holtmann 23691da177e4SLinus Torvalds hci_dev_unlock(hdev); 23701da177e4SLinus Torvalds 237120714bfeSFrédéric Dalleau if (ev->link_type == ACL_LINK || 237220714bfeSFrédéric Dalleau (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) { 2373b6a0dc82SMarcel Holtmann struct hci_cp_accept_conn_req cp; 237420714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 2375b6a0dc82SMarcel Holtmann 23761da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 23771da177e4SLinus Torvalds 23781da177e4SLinus Torvalds if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) 23791da177e4SLinus Torvalds cp.role = 0x00; /* Become master */ 23801da177e4SLinus Torvalds else 23811da177e4SLinus Torvalds cp.role = 0x01; /* Remain slave */ 23821da177e4SLinus Torvalds 238370c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); 238420714bfeSFrédéric Dalleau } else if (!(flags & HCI_PROTO_DEFER)) { 2385b6a0dc82SMarcel Holtmann struct hci_cp_accept_sync_conn_req cp; 238620714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 2387b6a0dc82SMarcel Holtmann 2388b6a0dc82SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 2389a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 2390b6a0dc82SMarcel Holtmann 2391dcf4adbfSJoe Perches cp.tx_bandwidth = cpu_to_le32(0x00001f40); 2392dcf4adbfSJoe Perches cp.rx_bandwidth = cpu_to_le32(0x00001f40); 2393dcf4adbfSJoe Perches cp.max_latency = cpu_to_le16(0xffff); 2394b6a0dc82SMarcel Holtmann cp.content_format = cpu_to_le16(hdev->voice_setting); 2395b6a0dc82SMarcel Holtmann cp.retrans_effort = 0xff; 2396b6a0dc82SMarcel Holtmann 239770c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp), 239870c46425SJohan Hedberg &cp); 239920714bfeSFrédéric Dalleau } else { 240020714bfeSFrédéric Dalleau conn->state = BT_CONNECT2; 2401539c496dSJohan Hedberg hci_connect_cfm(conn, 0); 2402b6a0dc82SMarcel Holtmann } 24031da177e4SLinus Torvalds } 24041da177e4SLinus Torvalds 2405f0d6a0eaSMikel Astiz static u8 hci_to_mgmt_reason(u8 err) 2406f0d6a0eaSMikel Astiz { 2407f0d6a0eaSMikel Astiz switch (err) { 2408f0d6a0eaSMikel Astiz case HCI_ERROR_CONNECTION_TIMEOUT: 2409f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_TIMEOUT; 2410f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_USER_TERM: 2411f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_LOW_RESOURCES: 2412f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_POWER_OFF: 2413f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_REMOTE; 2414f0d6a0eaSMikel Astiz case HCI_ERROR_LOCAL_HOST_TERM: 2415f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_LOCAL_HOST; 2416f0d6a0eaSMikel Astiz default: 2417f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_UNKNOWN; 2418f0d6a0eaSMikel Astiz } 2419f0d6a0eaSMikel Astiz } 2420f0d6a0eaSMikel Astiz 24216039aa73SGustavo Padovan static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 24221da177e4SLinus Torvalds { 2423a9de9248SMarcel Holtmann struct hci_ev_disconn_complete *ev = (void *) skb->data; 2424abf54a50SAndre Guedes u8 reason = hci_to_mgmt_reason(ev->reason); 24259fcb18efSAndre Guedes struct hci_conn_params *params; 242604837f64SMarcel Holtmann struct hci_conn *conn; 242712d4a3b2SJohan Hedberg bool mgmt_connected; 24283846220bSAndre Guedes u8 type; 24291da177e4SLinus Torvalds 24309f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 24311da177e4SLinus Torvalds 24321da177e4SLinus Torvalds hci_dev_lock(hdev); 24331da177e4SLinus Torvalds 243404837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2435f7520543SJohan Hedberg if (!conn) 2436f7520543SJohan Hedberg goto unlock; 2437f7520543SJohan Hedberg 2438f0d6a0eaSMikel Astiz if (ev->status) { 243988c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 244088c3df13SJohan Hedberg conn->dst_type, ev->status); 2441abf54a50SAndre Guedes goto unlock; 2442abf54a50SAndre Guedes } 2443f0d6a0eaSMikel Astiz 24443846220bSAndre Guedes conn->state = BT_CLOSED; 24453846220bSAndre Guedes 244612d4a3b2SJohan Hedberg mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags); 244712d4a3b2SJohan Hedberg mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type, 244812d4a3b2SJohan Hedberg reason, mgmt_connected); 2449f7520543SJohan Hedberg 245022f433dcSJohan Hedberg if (conn->type == ACL_LINK) { 245122f433dcSJohan Hedberg if (test_bit(HCI_CONN_FLUSH_KEY, &conn->flags)) 24526ec5bcadSVishal Agarwal hci_remove_link_key(hdev, &conn->dst); 24533846220bSAndre Guedes 24541d2dc5b7SJohan Hedberg hci_update_page_scan(hdev); 245522f433dcSJohan Hedberg } 245622f433dcSJohan Hedberg 24579fcb18efSAndre Guedes params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); 24589fcb18efSAndre Guedes if (params) { 24599fcb18efSAndre Guedes switch (params->auto_connect) { 24609fcb18efSAndre Guedes case HCI_AUTO_CONN_LINK_LOSS: 24619fcb18efSAndre Guedes if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT) 24629fcb18efSAndre Guedes break; 24639fcb18efSAndre Guedes /* Fall through */ 24649fcb18efSAndre Guedes 24654b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_DIRECT: 24669fcb18efSAndre Guedes case HCI_AUTO_CONN_ALWAYS: 2467418025d1SJohan Hedberg list_del_init(¶ms->action); 2468418025d1SJohan Hedberg list_add(¶ms->action, &hdev->pend_le_conns); 2469418025d1SJohan Hedberg hci_update_background_scan(hdev); 24709fcb18efSAndre Guedes break; 24719fcb18efSAndre Guedes 24729fcb18efSAndre Guedes default: 24739fcb18efSAndre Guedes break; 24749fcb18efSAndre Guedes } 24759fcb18efSAndre Guedes } 24769fcb18efSAndre Guedes 24773846220bSAndre Guedes type = conn->type; 24783846220bSAndre Guedes 24793a6d576bSJohan Hedberg hci_disconn_cfm(conn, ev->reason); 24801da177e4SLinus Torvalds hci_conn_del(conn); 24812210246cSJohan Hedberg 24822210246cSJohan Hedberg /* Re-enable advertising if necessary, since it might 24832210246cSJohan Hedberg * have been disabled by the connection. From the 24842210246cSJohan Hedberg * HCI_LE_Set_Advertise_Enable command description in 24852210246cSJohan Hedberg * the core specification (v4.0): 24862210246cSJohan Hedberg * "The Controller shall continue advertising until the Host 24872210246cSJohan Hedberg * issues an LE_Set_Advertise_Enable command with 24882210246cSJohan Hedberg * Advertising_Enable set to 0x00 (Advertising is disabled) 24892210246cSJohan Hedberg * or until a connection is created or until the Advertising 24902210246cSJohan Hedberg * is timed out due to Directed Advertising." 24912210246cSJohan Hedberg */ 24922210246cSJohan Hedberg if (type == LE_LINK) 24935976e608SMarcel Holtmann mgmt_reenable_advertising(hdev); 24941da177e4SLinus Torvalds 2495f7520543SJohan Hedberg unlock: 24961da177e4SLinus Torvalds hci_dev_unlock(hdev); 24971da177e4SLinus Torvalds } 24981da177e4SLinus Torvalds 24996039aa73SGustavo Padovan static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2500a9de9248SMarcel Holtmann { 2501a9de9248SMarcel Holtmann struct hci_ev_auth_complete *ev = (void *) skb->data; 2502a9de9248SMarcel Holtmann struct hci_conn *conn; 2503a9de9248SMarcel Holtmann 25049f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2505a9de9248SMarcel Holtmann 2506a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2507a9de9248SMarcel Holtmann 2508a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2509d7556e20SWaldemar Rymarkiewicz if (!conn) 2510d7556e20SWaldemar Rymarkiewicz goto unlock; 2511d7556e20SWaldemar Rymarkiewicz 2512765c2a96SJohan Hedberg if (!ev->status) { 2513aa64a8b5SJohan Hedberg if (!hci_conn_ssp_enabled(conn) && 251451a8efd7SJohan Hedberg test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { 2515d7556e20SWaldemar Rymarkiewicz BT_INFO("re-auth of legacy device is not possible."); 251619f8def0SWaldemar Rymarkiewicz } else { 25174dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 2518765c2a96SJohan Hedberg conn->sec_level = conn->pending_sec_level; 251919f8def0SWaldemar Rymarkiewicz } 25202a611692SJohan Hedberg } else { 2521e1e930f5SJohan Hedberg mgmt_auth_failed(conn, ev->status); 25222a611692SJohan Hedberg } 2523a9de9248SMarcel Holtmann 252451a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 252551a8efd7SJohan Hedberg clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags); 2526a9de9248SMarcel Holtmann 2527f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 2528aa64a8b5SJohan Hedberg if (!ev->status && hci_conn_ssp_enabled(conn)) { 2529f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 2530f8558555SMarcel Holtmann cp.handle = ev->handle; 2531f8558555SMarcel Holtmann cp.encrypt = 0x01; 2532d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 2533d7556e20SWaldemar Rymarkiewicz &cp); 2534f8558555SMarcel Holtmann } else { 2535f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 2536539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 253776a68ba0SDavid Herrmann hci_conn_drop(conn); 2538f8558555SMarcel Holtmann } 2539052b30b0SMarcel Holtmann } else { 2540a9de9248SMarcel Holtmann hci_auth_cfm(conn, ev->status); 2541a9de9248SMarcel Holtmann 2542052b30b0SMarcel Holtmann hci_conn_hold(conn); 2543052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 254476a68ba0SDavid Herrmann hci_conn_drop(conn); 2545052b30b0SMarcel Holtmann } 2546052b30b0SMarcel Holtmann 254751a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { 2548a9de9248SMarcel Holtmann if (!ev->status) { 2549a9de9248SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 2550f8558555SMarcel Holtmann cp.handle = ev->handle; 2551f8558555SMarcel Holtmann cp.encrypt = 0x01; 2552d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 2553d7556e20SWaldemar Rymarkiewicz &cp); 2554a9de9248SMarcel Holtmann } else { 255551a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 2556a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, 0x00); 2557a9de9248SMarcel Holtmann } 2558a9de9248SMarcel Holtmann } 2559a9de9248SMarcel Holtmann 2560d7556e20SWaldemar Rymarkiewicz unlock: 2561a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2562a9de9248SMarcel Holtmann } 2563a9de9248SMarcel Holtmann 25646039aa73SGustavo Padovan static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) 2565a9de9248SMarcel Holtmann { 2566127178d2SJohan Hedberg struct hci_ev_remote_name *ev = (void *) skb->data; 2567127178d2SJohan Hedberg struct hci_conn *conn; 2568127178d2SJohan Hedberg 2569a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2570a9de9248SMarcel Holtmann 2571a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 2572127178d2SJohan Hedberg 2573127178d2SJohan Hedberg hci_dev_lock(hdev); 2574127178d2SJohan Hedberg 2575127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2576b644ba33SJohan Hedberg 2577d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 2578b644ba33SJohan Hedberg goto check_auth; 2579b644ba33SJohan Hedberg 2580b644ba33SJohan Hedberg if (ev->status == 0) 2581b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name, 2582b644ba33SJohan Hedberg strnlen(ev->name, HCI_MAX_NAME_LENGTH)); 2583b644ba33SJohan Hedberg else 2584b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0); 2585b644ba33SJohan Hedberg 2586b644ba33SJohan Hedberg check_auth: 258779c6c70cSJohan Hedberg if (!conn) 258879c6c70cSJohan Hedberg goto unlock; 258979c6c70cSJohan Hedberg 259079c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 259179c6c70cSJohan Hedberg goto unlock; 259279c6c70cSJohan Hedberg 259351a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 2594127178d2SJohan Hedberg struct hci_cp_auth_requested cp; 2595977f8fceSJohan Hedberg 2596977f8fceSJohan Hedberg set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags); 2597977f8fceSJohan Hedberg 2598127178d2SJohan Hedberg cp.handle = __cpu_to_le16(conn->handle); 2599127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); 2600127178d2SJohan Hedberg } 2601127178d2SJohan Hedberg 260279c6c70cSJohan Hedberg unlock: 2603127178d2SJohan Hedberg hci_dev_unlock(hdev); 2604a9de9248SMarcel Holtmann } 2605a9de9248SMarcel Holtmann 2606821f3766SJohan Hedberg static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status, 2607821f3766SJohan Hedberg u16 opcode, struct sk_buff *skb) 2608821f3766SJohan Hedberg { 2609821f3766SJohan Hedberg const struct hci_rp_read_enc_key_size *rp; 2610821f3766SJohan Hedberg struct hci_conn *conn; 2611821f3766SJohan Hedberg u16 handle; 2612821f3766SJohan Hedberg 2613821f3766SJohan Hedberg BT_DBG("%s status 0x%02x", hdev->name, status); 2614821f3766SJohan Hedberg 2615821f3766SJohan Hedberg if (!skb || skb->len < sizeof(*rp)) { 2616821f3766SJohan Hedberg BT_ERR("%s invalid HCI Read Encryption Key Size response", 2617821f3766SJohan Hedberg hdev->name); 2618821f3766SJohan Hedberg return; 2619821f3766SJohan Hedberg } 2620821f3766SJohan Hedberg 2621821f3766SJohan Hedberg rp = (void *)skb->data; 2622821f3766SJohan Hedberg handle = le16_to_cpu(rp->handle); 2623821f3766SJohan Hedberg 2624821f3766SJohan Hedberg hci_dev_lock(hdev); 2625821f3766SJohan Hedberg 2626821f3766SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, handle); 2627821f3766SJohan Hedberg if (!conn) 2628821f3766SJohan Hedberg goto unlock; 2629821f3766SJohan Hedberg 2630821f3766SJohan Hedberg /* If we fail to read the encryption key size, assume maximum 2631821f3766SJohan Hedberg * (which is the same we do also when this HCI command isn't 2632821f3766SJohan Hedberg * supported. 2633821f3766SJohan Hedberg */ 2634821f3766SJohan Hedberg if (rp->status) { 2635821f3766SJohan Hedberg BT_ERR("%s failed to read key size for handle %u", hdev->name, 2636821f3766SJohan Hedberg handle); 2637821f3766SJohan Hedberg conn->enc_key_size = HCI_LINK_KEY_SIZE; 2638821f3766SJohan Hedberg } else { 2639821f3766SJohan Hedberg conn->enc_key_size = rp->key_size; 2640821f3766SJohan Hedberg } 2641821f3766SJohan Hedberg 2642821f3766SJohan Hedberg if (conn->state == BT_CONFIG) { 2643821f3766SJohan Hedberg conn->state = BT_CONNECTED; 2644821f3766SJohan Hedberg hci_connect_cfm(conn, 0); 2645821f3766SJohan Hedberg hci_conn_drop(conn); 2646821f3766SJohan Hedberg } else { 2647821f3766SJohan Hedberg u8 encrypt; 2648821f3766SJohan Hedberg 2649821f3766SJohan Hedberg if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags)) 2650821f3766SJohan Hedberg encrypt = 0x00; 26515d667ef6SJohan Hedberg else if (test_bit(HCI_CONN_AES_CCM, &conn->flags)) 2652821f3766SJohan Hedberg encrypt = 0x02; 2653821f3766SJohan Hedberg else 2654821f3766SJohan Hedberg encrypt = 0x01; 2655821f3766SJohan Hedberg 2656821f3766SJohan Hedberg hci_encrypt_cfm(conn, 0, encrypt); 2657821f3766SJohan Hedberg } 2658821f3766SJohan Hedberg 2659821f3766SJohan Hedberg unlock: 2660821f3766SJohan Hedberg hci_dev_unlock(hdev); 2661821f3766SJohan Hedberg } 2662821f3766SJohan Hedberg 26636039aa73SGustavo Padovan static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2664a9de9248SMarcel Holtmann { 2665a9de9248SMarcel Holtmann struct hci_ev_encrypt_change *ev = (void *) skb->data; 2666a9de9248SMarcel Holtmann struct hci_conn *conn; 2667a9de9248SMarcel Holtmann 26689f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2669a9de9248SMarcel Holtmann 2670a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2671a9de9248SMarcel Holtmann 2672a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2673dc8357ccSMarcel Holtmann if (!conn) 2674dc8357ccSMarcel Holtmann goto unlock; 2675dc8357ccSMarcel Holtmann 2676a9de9248SMarcel Holtmann if (!ev->status) { 2677ae293196SMarcel Holtmann if (ev->encrypt) { 2678ae293196SMarcel Holtmann /* Encryption implies authentication */ 26794dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 26804dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags); 2681da85e5e5SVinicius Costa Gomes conn->sec_level = conn->pending_sec_level; 2682abf76badSMarcel Holtmann 2683914a6ffeSMarcel Holtmann /* P-256 authentication key implies FIPS */ 2684914a6ffeSMarcel Holtmann if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256) 26854dae2798SJohan Hedberg set_bit(HCI_CONN_FIPS, &conn->flags); 2686914a6ffeSMarcel Holtmann 2687abf76badSMarcel Holtmann if ((conn->type == ACL_LINK && ev->encrypt == 0x02) || 2688abf76badSMarcel Holtmann conn->type == LE_LINK) 2689abf76badSMarcel Holtmann set_bit(HCI_CONN_AES_CCM, &conn->flags); 2690abf76badSMarcel Holtmann } else { 26914dae2798SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT, &conn->flags); 2692abf76badSMarcel Holtmann clear_bit(HCI_CONN_AES_CCM, &conn->flags); 2693abf76badSMarcel Holtmann } 2694a9de9248SMarcel Holtmann } 2695a9de9248SMarcel Holtmann 26967ed3fa20SJohan Hedberg /* We should disregard the current RPA and generate a new one 26977ed3fa20SJohan Hedberg * whenever the encryption procedure fails. 26987ed3fa20SJohan Hedberg */ 26997ed3fa20SJohan Hedberg if (ev->status && conn->type == LE_LINK) 2700a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); 27017ed3fa20SJohan Hedberg 270251a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 2703a9de9248SMarcel Holtmann 2704a7d7723aSGustavo Padovan if (ev->status && conn->state == BT_CONNECTED) { 2705bed71748SAndre Guedes hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 270676a68ba0SDavid Herrmann hci_conn_drop(conn); 2707a7d7723aSGustavo Padovan goto unlock; 2708a7d7723aSGustavo Padovan } 2709a7d7723aSGustavo Padovan 2710035ad621SJohan Hedberg /* In Secure Connections Only mode, do not allow any connections 2711035ad621SJohan Hedberg * that are not encrypted with AES-CCM using a P-256 authenticated 2712035ad621SJohan Hedberg * combination key. 271340b552aaSMarcel Holtmann */ 2714d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && 271540b552aaSMarcel Holtmann (!test_bit(HCI_CONN_AES_CCM, &conn->flags) || 271640b552aaSMarcel Holtmann conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) { 2717539c496dSJohan Hedberg hci_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE); 271840b552aaSMarcel Holtmann hci_conn_drop(conn); 271940b552aaSMarcel Holtmann goto unlock; 272040b552aaSMarcel Holtmann } 272140b552aaSMarcel Holtmann 2722821f3766SJohan Hedberg /* Try reading the encryption key size for encrypted ACL links */ 2723821f3766SJohan Hedberg if (!ev->status && ev->encrypt && conn->type == ACL_LINK) { 2724821f3766SJohan Hedberg struct hci_cp_read_enc_key_size cp; 2725821f3766SJohan Hedberg struct hci_request req; 2726821f3766SJohan Hedberg 2727821f3766SJohan Hedberg /* Only send HCI_Read_Encryption_Key_Size if the 2728821f3766SJohan Hedberg * controller really supports it. If it doesn't, assume 2729821f3766SJohan Hedberg * the default size (16). 2730821f3766SJohan Hedberg */ 2731821f3766SJohan Hedberg if (!(hdev->commands[20] & 0x10)) { 2732821f3766SJohan Hedberg conn->enc_key_size = HCI_LINK_KEY_SIZE; 2733821f3766SJohan Hedberg goto notify; 2734821f3766SJohan Hedberg } 2735821f3766SJohan Hedberg 2736821f3766SJohan Hedberg hci_req_init(&req, hdev); 2737821f3766SJohan Hedberg 2738821f3766SJohan Hedberg cp.handle = cpu_to_le16(conn->handle); 2739821f3766SJohan Hedberg hci_req_add(&req, HCI_OP_READ_ENC_KEY_SIZE, sizeof(cp), &cp); 2740821f3766SJohan Hedberg 2741821f3766SJohan Hedberg if (hci_req_run_skb(&req, read_enc_key_size_complete)) { 2742821f3766SJohan Hedberg BT_ERR("Sending HCI Read Encryption Key Size failed"); 2743821f3766SJohan Hedberg conn->enc_key_size = HCI_LINK_KEY_SIZE; 2744821f3766SJohan Hedberg goto notify; 2745821f3766SJohan Hedberg } 2746821f3766SJohan Hedberg 2747821f3766SJohan Hedberg goto unlock; 2748821f3766SJohan Hedberg } 2749821f3766SJohan Hedberg 2750821f3766SJohan Hedberg notify: 2751035ad621SJohan Hedberg if (conn->state == BT_CONFIG) { 2752035ad621SJohan Hedberg if (!ev->status) 2753035ad621SJohan Hedberg conn->state = BT_CONNECTED; 2754035ad621SJohan Hedberg 2755539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 275676a68ba0SDavid Herrmann hci_conn_drop(conn); 2757f8558555SMarcel Holtmann } else 2758a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, ev->encrypt); 2759a9de9248SMarcel Holtmann 2760a7d7723aSGustavo Padovan unlock: 2761a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2762a9de9248SMarcel Holtmann } 2763a9de9248SMarcel Holtmann 27646039aa73SGustavo Padovan static void hci_change_link_key_complete_evt(struct hci_dev *hdev, 2765807deac2SGustavo Padovan struct sk_buff *skb) 2766a9de9248SMarcel Holtmann { 2767a9de9248SMarcel Holtmann struct hci_ev_change_link_key_complete *ev = (void *) skb->data; 2768a9de9248SMarcel Holtmann struct hci_conn *conn; 2769a9de9248SMarcel Holtmann 27709f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2771a9de9248SMarcel Holtmann 2772a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2773a9de9248SMarcel Holtmann 2774a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2775a9de9248SMarcel Holtmann if (conn) { 2776a9de9248SMarcel Holtmann if (!ev->status) 27774dae2798SJohan Hedberg set_bit(HCI_CONN_SECURE, &conn->flags); 2778a9de9248SMarcel Holtmann 277951a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 2780a9de9248SMarcel Holtmann 2781a9de9248SMarcel Holtmann hci_key_change_cfm(conn, ev->status); 2782a9de9248SMarcel Holtmann } 2783a9de9248SMarcel Holtmann 2784a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2785a9de9248SMarcel Holtmann } 2786a9de9248SMarcel Holtmann 27876039aa73SGustavo Padovan static void hci_remote_features_evt(struct hci_dev *hdev, 2788807deac2SGustavo Padovan struct sk_buff *skb) 2789a9de9248SMarcel Holtmann { 2790a9de9248SMarcel Holtmann struct hci_ev_remote_features *ev = (void *) skb->data; 2791a9de9248SMarcel Holtmann struct hci_conn *conn; 2792a9de9248SMarcel Holtmann 27939f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2794a9de9248SMarcel Holtmann 2795a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2796a9de9248SMarcel Holtmann 2797a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2798ccd556feSJohan Hedberg if (!conn) 2799ccd556feSJohan Hedberg goto unlock; 2800ccd556feSJohan Hedberg 2801769be974SMarcel Holtmann if (!ev->status) 2802cad718edSJohan Hedberg memcpy(conn->features[0], ev->features, 8); 2803a9de9248SMarcel Holtmann 2804ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 2805ccd556feSJohan Hedberg goto unlock; 2806ccd556feSJohan Hedberg 2807ac363cf9SSzymon Janc if (!ev->status && lmp_ext_feat_capable(hdev) && 2808ac363cf9SSzymon Janc lmp_ext_feat_capable(conn)) { 2809769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features cp; 2810769be974SMarcel Holtmann cp.handle = ev->handle; 2811769be974SMarcel Holtmann cp.page = 0x01; 2812ccd556feSJohan Hedberg hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, 2813769be974SMarcel Holtmann sizeof(cp), &cp); 2814392599b9SJohan Hedberg goto unlock; 2815392599b9SJohan Hedberg } 2816392599b9SJohan Hedberg 2817671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 2818127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 2819127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 2820127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 2821127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 2822127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 2823b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 282448ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, NULL, 0); 2825392599b9SJohan Hedberg 2826127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 2827769be974SMarcel Holtmann conn->state = BT_CONNECTED; 2828539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 282976a68ba0SDavid Herrmann hci_conn_drop(conn); 2830769be974SMarcel Holtmann } 2831769be974SMarcel Holtmann 2832ccd556feSJohan Hedberg unlock: 2833a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2834a9de9248SMarcel Holtmann } 2835a9de9248SMarcel Holtmann 2836e6214487SJohan Hedberg static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb, 2837e6214487SJohan Hedberg u16 *opcode, u8 *status, 2838e6214487SJohan Hedberg hci_req_complete_t *req_complete, 2839e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 2840a9de9248SMarcel Holtmann { 2841a9de9248SMarcel Holtmann struct hci_ev_cmd_complete *ev = (void *) skb->data; 2842e6214487SJohan Hedberg 2843e6214487SJohan Hedberg *opcode = __le16_to_cpu(ev->opcode); 2844e6214487SJohan Hedberg *status = skb->data[sizeof(*ev)]; 2845a9de9248SMarcel Holtmann 2846a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 2847a9de9248SMarcel Holtmann 2848e6214487SJohan Hedberg switch (*opcode) { 2849a9de9248SMarcel Holtmann case HCI_OP_INQUIRY_CANCEL: 2850a9de9248SMarcel Holtmann hci_cc_inquiry_cancel(hdev, skb); 2851a9de9248SMarcel Holtmann break; 2852a9de9248SMarcel Holtmann 28534d93483bSAndre Guedes case HCI_OP_PERIODIC_INQ: 28544d93483bSAndre Guedes hci_cc_periodic_inq(hdev, skb); 28554d93483bSAndre Guedes break; 28564d93483bSAndre Guedes 2857a9de9248SMarcel Holtmann case HCI_OP_EXIT_PERIODIC_INQ: 2858a9de9248SMarcel Holtmann hci_cc_exit_periodic_inq(hdev, skb); 2859a9de9248SMarcel Holtmann break; 2860a9de9248SMarcel Holtmann 2861a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ_CANCEL: 2862a9de9248SMarcel Holtmann hci_cc_remote_name_req_cancel(hdev, skb); 2863a9de9248SMarcel Holtmann break; 2864a9de9248SMarcel Holtmann 2865a9de9248SMarcel Holtmann case HCI_OP_ROLE_DISCOVERY: 2866a9de9248SMarcel Holtmann hci_cc_role_discovery(hdev, skb); 2867a9de9248SMarcel Holtmann break; 2868a9de9248SMarcel Holtmann 2869e4e8e37cSMarcel Holtmann case HCI_OP_READ_LINK_POLICY: 2870e4e8e37cSMarcel Holtmann hci_cc_read_link_policy(hdev, skb); 2871e4e8e37cSMarcel Holtmann break; 2872e4e8e37cSMarcel Holtmann 2873a9de9248SMarcel Holtmann case HCI_OP_WRITE_LINK_POLICY: 2874a9de9248SMarcel Holtmann hci_cc_write_link_policy(hdev, skb); 2875a9de9248SMarcel Holtmann break; 2876a9de9248SMarcel Holtmann 2877e4e8e37cSMarcel Holtmann case HCI_OP_READ_DEF_LINK_POLICY: 2878e4e8e37cSMarcel Holtmann hci_cc_read_def_link_policy(hdev, skb); 2879e4e8e37cSMarcel Holtmann break; 2880e4e8e37cSMarcel Holtmann 2881e4e8e37cSMarcel Holtmann case HCI_OP_WRITE_DEF_LINK_POLICY: 2882e4e8e37cSMarcel Holtmann hci_cc_write_def_link_policy(hdev, skb); 2883e4e8e37cSMarcel Holtmann break; 2884e4e8e37cSMarcel Holtmann 2885a9de9248SMarcel Holtmann case HCI_OP_RESET: 2886a9de9248SMarcel Holtmann hci_cc_reset(hdev, skb); 2887a9de9248SMarcel Holtmann break; 2888a9de9248SMarcel Holtmann 2889c2f0f979SMarcel Holtmann case HCI_OP_READ_STORED_LINK_KEY: 2890c2f0f979SMarcel Holtmann hci_cc_read_stored_link_key(hdev, skb); 2891c2f0f979SMarcel Holtmann break; 2892c2f0f979SMarcel Holtmann 2893a9366120SMarcel Holtmann case HCI_OP_DELETE_STORED_LINK_KEY: 2894a9366120SMarcel Holtmann hci_cc_delete_stored_link_key(hdev, skb); 2895a9366120SMarcel Holtmann break; 2896a9366120SMarcel Holtmann 2897a9de9248SMarcel Holtmann case HCI_OP_WRITE_LOCAL_NAME: 2898a9de9248SMarcel Holtmann hci_cc_write_local_name(hdev, skb); 2899a9de9248SMarcel Holtmann break; 2900a9de9248SMarcel Holtmann 2901a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_NAME: 2902a9de9248SMarcel Holtmann hci_cc_read_local_name(hdev, skb); 2903a9de9248SMarcel Holtmann break; 2904a9de9248SMarcel Holtmann 2905a9de9248SMarcel Holtmann case HCI_OP_WRITE_AUTH_ENABLE: 2906a9de9248SMarcel Holtmann hci_cc_write_auth_enable(hdev, skb); 2907a9de9248SMarcel Holtmann break; 2908a9de9248SMarcel Holtmann 2909a9de9248SMarcel Holtmann case HCI_OP_WRITE_ENCRYPT_MODE: 2910a9de9248SMarcel Holtmann hci_cc_write_encrypt_mode(hdev, skb); 2911a9de9248SMarcel Holtmann break; 2912a9de9248SMarcel Holtmann 2913a9de9248SMarcel Holtmann case HCI_OP_WRITE_SCAN_ENABLE: 2914a9de9248SMarcel Holtmann hci_cc_write_scan_enable(hdev, skb); 2915a9de9248SMarcel Holtmann break; 2916a9de9248SMarcel Holtmann 2917a9de9248SMarcel Holtmann case HCI_OP_READ_CLASS_OF_DEV: 2918a9de9248SMarcel Holtmann hci_cc_read_class_of_dev(hdev, skb); 2919a9de9248SMarcel Holtmann break; 2920a9de9248SMarcel Holtmann 2921a9de9248SMarcel Holtmann case HCI_OP_WRITE_CLASS_OF_DEV: 2922a9de9248SMarcel Holtmann hci_cc_write_class_of_dev(hdev, skb); 2923a9de9248SMarcel Holtmann break; 2924a9de9248SMarcel Holtmann 2925a9de9248SMarcel Holtmann case HCI_OP_READ_VOICE_SETTING: 2926a9de9248SMarcel Holtmann hci_cc_read_voice_setting(hdev, skb); 2927a9de9248SMarcel Holtmann break; 2928a9de9248SMarcel Holtmann 2929a9de9248SMarcel Holtmann case HCI_OP_WRITE_VOICE_SETTING: 2930a9de9248SMarcel Holtmann hci_cc_write_voice_setting(hdev, skb); 2931a9de9248SMarcel Holtmann break; 2932a9de9248SMarcel Holtmann 2933b4cb9fb2SMarcel Holtmann case HCI_OP_READ_NUM_SUPPORTED_IAC: 2934b4cb9fb2SMarcel Holtmann hci_cc_read_num_supported_iac(hdev, skb); 2935b4cb9fb2SMarcel Holtmann break; 2936b4cb9fb2SMarcel Holtmann 2937333140b5SMarcel Holtmann case HCI_OP_WRITE_SSP_MODE: 2938333140b5SMarcel Holtmann hci_cc_write_ssp_mode(hdev, skb); 2939333140b5SMarcel Holtmann break; 2940333140b5SMarcel Holtmann 2941eac83dc6SMarcel Holtmann case HCI_OP_WRITE_SC_SUPPORT: 2942eac83dc6SMarcel Holtmann hci_cc_write_sc_support(hdev, skb); 2943eac83dc6SMarcel Holtmann break; 2944eac83dc6SMarcel Holtmann 2945a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_VERSION: 2946a9de9248SMarcel Holtmann hci_cc_read_local_version(hdev, skb); 2947a9de9248SMarcel Holtmann break; 2948a9de9248SMarcel Holtmann 2949a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_COMMANDS: 2950a9de9248SMarcel Holtmann hci_cc_read_local_commands(hdev, skb); 2951a9de9248SMarcel Holtmann break; 2952a9de9248SMarcel Holtmann 2953a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_FEATURES: 2954a9de9248SMarcel Holtmann hci_cc_read_local_features(hdev, skb); 2955a9de9248SMarcel Holtmann break; 2956a9de9248SMarcel Holtmann 2957971e3a4bSAndre Guedes case HCI_OP_READ_LOCAL_EXT_FEATURES: 2958971e3a4bSAndre Guedes hci_cc_read_local_ext_features(hdev, skb); 2959971e3a4bSAndre Guedes break; 2960971e3a4bSAndre Guedes 2961a9de9248SMarcel Holtmann case HCI_OP_READ_BUFFER_SIZE: 2962a9de9248SMarcel Holtmann hci_cc_read_buffer_size(hdev, skb); 2963a9de9248SMarcel Holtmann break; 2964a9de9248SMarcel Holtmann 2965a9de9248SMarcel Holtmann case HCI_OP_READ_BD_ADDR: 2966a9de9248SMarcel Holtmann hci_cc_read_bd_addr(hdev, skb); 2967a9de9248SMarcel Holtmann break; 2968a9de9248SMarcel Holtmann 2969f332ec66SJohan Hedberg case HCI_OP_READ_PAGE_SCAN_ACTIVITY: 2970f332ec66SJohan Hedberg hci_cc_read_page_scan_activity(hdev, skb); 2971f332ec66SJohan Hedberg break; 2972f332ec66SJohan Hedberg 29734a3ee763SJohan Hedberg case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY: 29744a3ee763SJohan Hedberg hci_cc_write_page_scan_activity(hdev, skb); 29754a3ee763SJohan Hedberg break; 29764a3ee763SJohan Hedberg 2977f332ec66SJohan Hedberg case HCI_OP_READ_PAGE_SCAN_TYPE: 2978f332ec66SJohan Hedberg hci_cc_read_page_scan_type(hdev, skb); 2979f332ec66SJohan Hedberg break; 2980f332ec66SJohan Hedberg 29814a3ee763SJohan Hedberg case HCI_OP_WRITE_PAGE_SCAN_TYPE: 29824a3ee763SJohan Hedberg hci_cc_write_page_scan_type(hdev, skb); 29834a3ee763SJohan Hedberg break; 29844a3ee763SJohan Hedberg 2985350ee4cfSAndrei Emeltchenko case HCI_OP_READ_DATA_BLOCK_SIZE: 2986350ee4cfSAndrei Emeltchenko hci_cc_read_data_block_size(hdev, skb); 2987350ee4cfSAndrei Emeltchenko break; 2988350ee4cfSAndrei Emeltchenko 29891e89cffbSAndrei Emeltchenko case HCI_OP_READ_FLOW_CONTROL_MODE: 29901e89cffbSAndrei Emeltchenko hci_cc_read_flow_control_mode(hdev, skb); 29911e89cffbSAndrei Emeltchenko break; 29921e89cffbSAndrei Emeltchenko 2993928abaa7SAndrei Emeltchenko case HCI_OP_READ_LOCAL_AMP_INFO: 2994928abaa7SAndrei Emeltchenko hci_cc_read_local_amp_info(hdev, skb); 2995928abaa7SAndrei Emeltchenko break; 2996928abaa7SAndrei Emeltchenko 299733f35721SJohan Hedberg case HCI_OP_READ_CLOCK: 299833f35721SJohan Hedberg hci_cc_read_clock(hdev, skb); 299933f35721SJohan Hedberg break; 300033f35721SJohan Hedberg 3001903e4541SAndrei Emeltchenko case HCI_OP_READ_LOCAL_AMP_ASSOC: 3002903e4541SAndrei Emeltchenko hci_cc_read_local_amp_assoc(hdev, skb); 3003903e4541SAndrei Emeltchenko break; 3004903e4541SAndrei Emeltchenko 3005d5859e22SJohan Hedberg case HCI_OP_READ_INQ_RSP_TX_POWER: 3006d5859e22SJohan Hedberg hci_cc_read_inq_rsp_tx_power(hdev, skb); 3007d5859e22SJohan Hedberg break; 3008d5859e22SJohan Hedberg 3009980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_REPLY: 3010980e1a53SJohan Hedberg hci_cc_pin_code_reply(hdev, skb); 3011980e1a53SJohan Hedberg break; 3012980e1a53SJohan Hedberg 3013980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_NEG_REPLY: 3014980e1a53SJohan Hedberg hci_cc_pin_code_neg_reply(hdev, skb); 3015980e1a53SJohan Hedberg break; 3016980e1a53SJohan Hedberg 3017c35938b2SSzymon Janc case HCI_OP_READ_LOCAL_OOB_DATA: 30184d2d2796SMarcel Holtmann hci_cc_read_local_oob_data(hdev, skb); 30194d2d2796SMarcel Holtmann break; 30204d2d2796SMarcel Holtmann 30214d2d2796SMarcel Holtmann case HCI_OP_READ_LOCAL_OOB_EXT_DATA: 30224d2d2796SMarcel Holtmann hci_cc_read_local_oob_ext_data(hdev, skb); 3023c35938b2SSzymon Janc break; 3024c35938b2SSzymon Janc 30256ed58ec5SVille Tervo case HCI_OP_LE_READ_BUFFER_SIZE: 30266ed58ec5SVille Tervo hci_cc_le_read_buffer_size(hdev, skb); 30276ed58ec5SVille Tervo break; 30286ed58ec5SVille Tervo 302960e77321SJohan Hedberg case HCI_OP_LE_READ_LOCAL_FEATURES: 303060e77321SJohan Hedberg hci_cc_le_read_local_features(hdev, skb); 303160e77321SJohan Hedberg break; 303260e77321SJohan Hedberg 30338fa19098SJohan Hedberg case HCI_OP_LE_READ_ADV_TX_POWER: 30348fa19098SJohan Hedberg hci_cc_le_read_adv_tx_power(hdev, skb); 30358fa19098SJohan Hedberg break; 30368fa19098SJohan Hedberg 3037a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_REPLY: 3038a5c29683SJohan Hedberg hci_cc_user_confirm_reply(hdev, skb); 3039a5c29683SJohan Hedberg break; 3040a5c29683SJohan Hedberg 3041a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_NEG_REPLY: 3042a5c29683SJohan Hedberg hci_cc_user_confirm_neg_reply(hdev, skb); 3043a5c29683SJohan Hedberg break; 3044a5c29683SJohan Hedberg 30451143d458SBrian Gix case HCI_OP_USER_PASSKEY_REPLY: 30461143d458SBrian Gix hci_cc_user_passkey_reply(hdev, skb); 30471143d458SBrian Gix break; 30481143d458SBrian Gix 30491143d458SBrian Gix case HCI_OP_USER_PASSKEY_NEG_REPLY: 30501143d458SBrian Gix hci_cc_user_passkey_neg_reply(hdev, skb); 305116cde993SSzymon Janc break; 305207f7fa5dSAndre Guedes 30537a4cd51dSMarcel Holtmann case HCI_OP_LE_SET_RANDOM_ADDR: 30547a4cd51dSMarcel Holtmann hci_cc_le_set_random_addr(hdev, skb); 30557a4cd51dSMarcel Holtmann break; 30567a4cd51dSMarcel Holtmann 3057c1d5dc4aSJohan Hedberg case HCI_OP_LE_SET_ADV_ENABLE: 3058c1d5dc4aSJohan Hedberg hci_cc_le_set_adv_enable(hdev, skb); 3059c1d5dc4aSJohan Hedberg break; 3060c1d5dc4aSJohan Hedberg 3061533553f8SMarcel Holtmann case HCI_OP_LE_SET_SCAN_PARAM: 3062533553f8SMarcel Holtmann hci_cc_le_set_scan_param(hdev, skb); 3063533553f8SMarcel Holtmann break; 3064533553f8SMarcel Holtmann 3065eb9d91f5SAndre Guedes case HCI_OP_LE_SET_SCAN_ENABLE: 3066eb9d91f5SAndre Guedes hci_cc_le_set_scan_enable(hdev, skb); 3067eb9d91f5SAndre Guedes break; 3068eb9d91f5SAndre Guedes 3069cf1d081fSJohan Hedberg case HCI_OP_LE_READ_WHITE_LIST_SIZE: 3070cf1d081fSJohan Hedberg hci_cc_le_read_white_list_size(hdev, skb); 3071cf1d081fSJohan Hedberg break; 3072cf1d081fSJohan Hedberg 30730f36b589SMarcel Holtmann case HCI_OP_LE_CLEAR_WHITE_LIST: 30740f36b589SMarcel Holtmann hci_cc_le_clear_white_list(hdev, skb); 30750f36b589SMarcel Holtmann break; 30760f36b589SMarcel Holtmann 30770f36b589SMarcel Holtmann case HCI_OP_LE_ADD_TO_WHITE_LIST: 30780f36b589SMarcel Holtmann hci_cc_le_add_to_white_list(hdev, skb); 30790f36b589SMarcel Holtmann break; 30800f36b589SMarcel Holtmann 30810f36b589SMarcel Holtmann case HCI_OP_LE_DEL_FROM_WHITE_LIST: 30820f36b589SMarcel Holtmann hci_cc_le_del_from_white_list(hdev, skb); 30830f36b589SMarcel Holtmann break; 30840f36b589SMarcel Holtmann 30859b008c04SJohan Hedberg case HCI_OP_LE_READ_SUPPORTED_STATES: 30869b008c04SJohan Hedberg hci_cc_le_read_supported_states(hdev, skb); 30879b008c04SJohan Hedberg break; 30889b008c04SJohan Hedberg 3089a8e1bfaaSMarcel Holtmann case HCI_OP_LE_READ_DEF_DATA_LEN: 3090a8e1bfaaSMarcel Holtmann hci_cc_le_read_def_data_len(hdev, skb); 3091a8e1bfaaSMarcel Holtmann break; 3092a8e1bfaaSMarcel Holtmann 3093a8e1bfaaSMarcel Holtmann case HCI_OP_LE_WRITE_DEF_DATA_LEN: 3094a8e1bfaaSMarcel Holtmann hci_cc_le_write_def_data_len(hdev, skb); 3095a8e1bfaaSMarcel Holtmann break; 3096a8e1bfaaSMarcel Holtmann 3097a8e1bfaaSMarcel Holtmann case HCI_OP_LE_READ_MAX_DATA_LEN: 3098a8e1bfaaSMarcel Holtmann hci_cc_le_read_max_data_len(hdev, skb); 3099a8e1bfaaSMarcel Holtmann break; 3100a8e1bfaaSMarcel Holtmann 3101f9b49306SAndre Guedes case HCI_OP_WRITE_LE_HOST_SUPPORTED: 3102f9b49306SAndre Guedes hci_cc_write_le_host_supported(hdev, skb); 3103f9b49306SAndre Guedes break; 3104f9b49306SAndre Guedes 310556ed2cb8SJohan Hedberg case HCI_OP_LE_SET_ADV_PARAM: 310656ed2cb8SJohan Hedberg hci_cc_set_adv_param(hdev, skb); 310756ed2cb8SJohan Hedberg break; 310856ed2cb8SJohan Hedberg 310993c284eeSAndrei Emeltchenko case HCI_OP_WRITE_REMOTE_AMP_ASSOC: 311093c284eeSAndrei Emeltchenko hci_cc_write_remote_amp_assoc(hdev, skb); 311193c284eeSAndrei Emeltchenko break; 311293c284eeSAndrei Emeltchenko 31135ae76a94SAndrzej Kaczmarek case HCI_OP_READ_RSSI: 31145ae76a94SAndrzej Kaczmarek hci_cc_read_rssi(hdev, skb); 31155ae76a94SAndrzej Kaczmarek break; 31165ae76a94SAndrzej Kaczmarek 31175a134faeSAndrzej Kaczmarek case HCI_OP_READ_TX_POWER: 31185a134faeSAndrzej Kaczmarek hci_cc_read_tx_power(hdev, skb); 31195a134faeSAndrzej Kaczmarek break; 31205a134faeSAndrzej Kaczmarek 3121c50b33c8SMarcel Holtmann case HCI_OP_WRITE_SSP_DEBUG_MODE: 3122c50b33c8SMarcel Holtmann hci_cc_write_ssp_debug_mode(hdev, skb); 3123c50b33c8SMarcel Holtmann break; 3124c50b33c8SMarcel Holtmann 3125a9de9248SMarcel Holtmann default: 3126e6214487SJohan Hedberg BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode); 3127a9de9248SMarcel Holtmann break; 3128a9de9248SMarcel Holtmann } 3129a9de9248SMarcel Holtmann 3130e6214487SJohan Hedberg if (*opcode != HCI_OP_NOP) 313165cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 31326bd32326SVille Tervo 3133600b2150SJohan Hedberg if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) 3134600b2150SJohan Hedberg atomic_set(&hdev->cmd_cnt, 1); 3135600b2150SJohan Hedberg 3136e6214487SJohan Hedberg hci_req_cmd_complete(hdev, *opcode, *status, req_complete, 3137e6214487SJohan Hedberg req_complete_skb); 31389238f36aSJohan Hedberg 3139600b2150SJohan Hedberg if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q)) 3140c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 3141a9de9248SMarcel Holtmann } 3142a9de9248SMarcel Holtmann 3143e6214487SJohan Hedberg static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb, 3144e6214487SJohan Hedberg u16 *opcode, u8 *status, 3145e6214487SJohan Hedberg hci_req_complete_t *req_complete, 3146e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 3147a9de9248SMarcel Holtmann { 3148a9de9248SMarcel Holtmann struct hci_ev_cmd_status *ev = (void *) skb->data; 3149a9de9248SMarcel Holtmann 3150a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 3151a9de9248SMarcel Holtmann 3152e6214487SJohan Hedberg *opcode = __le16_to_cpu(ev->opcode); 3153e6214487SJohan Hedberg *status = ev->status; 3154a9de9248SMarcel Holtmann 3155e6214487SJohan Hedberg switch (*opcode) { 3156a9de9248SMarcel Holtmann case HCI_OP_INQUIRY: 3157a9de9248SMarcel Holtmann hci_cs_inquiry(hdev, ev->status); 3158a9de9248SMarcel Holtmann break; 3159a9de9248SMarcel Holtmann 3160a9de9248SMarcel Holtmann case HCI_OP_CREATE_CONN: 3161a9de9248SMarcel Holtmann hci_cs_create_conn(hdev, ev->status); 3162a9de9248SMarcel Holtmann break; 3163a9de9248SMarcel Holtmann 31649645c76cSKuba Pawlak case HCI_OP_DISCONNECT: 31659645c76cSKuba Pawlak hci_cs_disconnect(hdev, ev->status); 31669645c76cSKuba Pawlak break; 31679645c76cSKuba Pawlak 3168a9de9248SMarcel Holtmann case HCI_OP_ADD_SCO: 3169a9de9248SMarcel Holtmann hci_cs_add_sco(hdev, ev->status); 3170a9de9248SMarcel Holtmann break; 3171a9de9248SMarcel Holtmann 3172f8558555SMarcel Holtmann case HCI_OP_AUTH_REQUESTED: 3173f8558555SMarcel Holtmann hci_cs_auth_requested(hdev, ev->status); 3174f8558555SMarcel Holtmann break; 3175f8558555SMarcel Holtmann 3176f8558555SMarcel Holtmann case HCI_OP_SET_CONN_ENCRYPT: 3177f8558555SMarcel Holtmann hci_cs_set_conn_encrypt(hdev, ev->status); 3178f8558555SMarcel Holtmann break; 3179f8558555SMarcel Holtmann 3180a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ: 3181a9de9248SMarcel Holtmann hci_cs_remote_name_req(hdev, ev->status); 3182a9de9248SMarcel Holtmann break; 3183a9de9248SMarcel Holtmann 3184769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_FEATURES: 3185769be974SMarcel Holtmann hci_cs_read_remote_features(hdev, ev->status); 3186769be974SMarcel Holtmann break; 3187769be974SMarcel Holtmann 3188769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_EXT_FEATURES: 3189769be974SMarcel Holtmann hci_cs_read_remote_ext_features(hdev, ev->status); 3190769be974SMarcel Holtmann break; 3191769be974SMarcel Holtmann 3192a9de9248SMarcel Holtmann case HCI_OP_SETUP_SYNC_CONN: 3193a9de9248SMarcel Holtmann hci_cs_setup_sync_conn(hdev, ev->status); 3194a9de9248SMarcel Holtmann break; 3195a9de9248SMarcel Holtmann 31969645c76cSKuba Pawlak case HCI_OP_CREATE_PHY_LINK: 31979645c76cSKuba Pawlak hci_cs_create_phylink(hdev, ev->status); 31989645c76cSKuba Pawlak break; 31999645c76cSKuba Pawlak 32009645c76cSKuba Pawlak case HCI_OP_ACCEPT_PHY_LINK: 32019645c76cSKuba Pawlak hci_cs_accept_phylink(hdev, ev->status); 32029645c76cSKuba Pawlak break; 32039645c76cSKuba Pawlak 3204a9de9248SMarcel Holtmann case HCI_OP_SNIFF_MODE: 3205a9de9248SMarcel Holtmann hci_cs_sniff_mode(hdev, ev->status); 3206a9de9248SMarcel Holtmann break; 3207a9de9248SMarcel Holtmann 3208a9de9248SMarcel Holtmann case HCI_OP_EXIT_SNIFF_MODE: 3209a9de9248SMarcel Holtmann hci_cs_exit_sniff_mode(hdev, ev->status); 3210a9de9248SMarcel Holtmann break; 3211a9de9248SMarcel Holtmann 321250fc85f1SKuba Pawlak case HCI_OP_SWITCH_ROLE: 321350fc85f1SKuba Pawlak hci_cs_switch_role(hdev, ev->status); 321450fc85f1SKuba Pawlak break; 321550fc85f1SKuba Pawlak 3216cb1d68f7SJohan Hedberg case HCI_OP_LE_CREATE_CONN: 3217cb1d68f7SJohan Hedberg hci_cs_le_create_conn(hdev, ev->status); 3218cb1d68f7SJohan Hedberg break; 3219cb1d68f7SJohan Hedberg 32200fe29fd1SMarcel Holtmann case HCI_OP_LE_READ_REMOTE_FEATURES: 32210fe29fd1SMarcel Holtmann hci_cs_le_read_remote_features(hdev, ev->status); 32220fe29fd1SMarcel Holtmann break; 32230fe29fd1SMarcel Holtmann 322481d0c8adSJohan Hedberg case HCI_OP_LE_START_ENC: 322581d0c8adSJohan Hedberg hci_cs_le_start_enc(hdev, ev->status); 322681d0c8adSJohan Hedberg break; 322781d0c8adSJohan Hedberg 3228a9de9248SMarcel Holtmann default: 3229e6214487SJohan Hedberg BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode); 3230a9de9248SMarcel Holtmann break; 3231a9de9248SMarcel Holtmann } 3232a9de9248SMarcel Holtmann 3233e6214487SJohan Hedberg if (*opcode != HCI_OP_NOP) 323465cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 32356bd32326SVille Tervo 3236600b2150SJohan Hedberg if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) 3237600b2150SJohan Hedberg atomic_set(&hdev->cmd_cnt, 1); 3238600b2150SJohan Hedberg 3239444c6dd5SJohan Hedberg /* Indicate request completion if the command failed. Also, if 3240444c6dd5SJohan Hedberg * we're not waiting for a special event and we get a success 3241444c6dd5SJohan Hedberg * command status we should try to flag the request as completed 3242444c6dd5SJohan Hedberg * (since for this kind of commands there will not be a command 3243444c6dd5SJohan Hedberg * complete event). 3244444c6dd5SJohan Hedberg */ 324502350a72SJohan Hedberg if (ev->status || 3246db6e3e8dSJohan Hedberg (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event)) 3247e6214487SJohan Hedberg hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete, 3248e6214487SJohan Hedberg req_complete_skb); 32499238f36aSJohan Hedberg 3250600b2150SJohan Hedberg if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q)) 3251c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 3252a9de9248SMarcel Holtmann } 3253a9de9248SMarcel Holtmann 325424dfa343SMarcel Holtmann static void hci_hardware_error_evt(struct hci_dev *hdev, struct sk_buff *skb) 325524dfa343SMarcel Holtmann { 325624dfa343SMarcel Holtmann struct hci_ev_hardware_error *ev = (void *) skb->data; 325724dfa343SMarcel Holtmann 3258c7741d16SMarcel Holtmann hdev->hw_error_code = ev->code; 3259c7741d16SMarcel Holtmann 3260c7741d16SMarcel Holtmann queue_work(hdev->req_workqueue, &hdev->error_reset); 326124dfa343SMarcel Holtmann } 326224dfa343SMarcel Holtmann 32636039aa73SGustavo Padovan static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 3264a9de9248SMarcel Holtmann { 3265a9de9248SMarcel Holtmann struct hci_ev_role_change *ev = (void *) skb->data; 3266a9de9248SMarcel Holtmann struct hci_conn *conn; 3267a9de9248SMarcel Holtmann 32689f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3269a9de9248SMarcel Holtmann 3270a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3271a9de9248SMarcel Holtmann 3272a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 3273a9de9248SMarcel Holtmann if (conn) { 327440bef302SJohan Hedberg if (!ev->status) 327540bef302SJohan Hedberg conn->role = ev->role; 3276a9de9248SMarcel Holtmann 327751a8efd7SJohan Hedberg clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 3278a9de9248SMarcel Holtmann 3279a9de9248SMarcel Holtmann hci_role_switch_cfm(conn, ev->status, ev->role); 3280a9de9248SMarcel Holtmann } 3281a9de9248SMarcel Holtmann 3282a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3283a9de9248SMarcel Holtmann } 3284a9de9248SMarcel Holtmann 32856039aa73SGustavo Padovan static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) 32861da177e4SLinus Torvalds { 3287a9de9248SMarcel Holtmann struct hci_ev_num_comp_pkts *ev = (void *) skb->data; 32881da177e4SLinus Torvalds int i; 32891da177e4SLinus Torvalds 329032ac5b9bSAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) { 329132ac5b9bSAndrei Emeltchenko BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); 329232ac5b9bSAndrei Emeltchenko return; 329332ac5b9bSAndrei Emeltchenko } 329432ac5b9bSAndrei Emeltchenko 3295c5993de8SAndrei Emeltchenko if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + 3296c5993de8SAndrei Emeltchenko ev->num_hndl * sizeof(struct hci_comp_pkts_info)) { 32971da177e4SLinus Torvalds BT_DBG("%s bad parameters", hdev->name); 32981da177e4SLinus Torvalds return; 32991da177e4SLinus Torvalds } 33001da177e4SLinus Torvalds 3301c5993de8SAndrei Emeltchenko BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl); 3302c5993de8SAndrei Emeltchenko 3303613a1c0cSAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 3304613a1c0cSAndrei Emeltchenko struct hci_comp_pkts_info *info = &ev->handles[i]; 33051da177e4SLinus Torvalds struct hci_conn *conn; 33061da177e4SLinus Torvalds __u16 handle, count; 33071da177e4SLinus Torvalds 3308613a1c0cSAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 3309613a1c0cSAndrei Emeltchenko count = __le16_to_cpu(info->count); 33101da177e4SLinus Torvalds 33111da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 3312f4280918SAndrei Emeltchenko if (!conn) 3313f4280918SAndrei Emeltchenko continue; 3314f4280918SAndrei Emeltchenko 33151da177e4SLinus Torvalds conn->sent -= count; 33161da177e4SLinus Torvalds 3317f4280918SAndrei Emeltchenko switch (conn->type) { 3318f4280918SAndrei Emeltchenko case ACL_LINK: 331970f23020SAndrei Emeltchenko hdev->acl_cnt += count; 332070f23020SAndrei Emeltchenko if (hdev->acl_cnt > hdev->acl_pkts) 33211da177e4SLinus Torvalds hdev->acl_cnt = hdev->acl_pkts; 3322f4280918SAndrei Emeltchenko break; 3323f4280918SAndrei Emeltchenko 3324f4280918SAndrei Emeltchenko case LE_LINK: 33256ed58ec5SVille Tervo if (hdev->le_pkts) { 33266ed58ec5SVille Tervo hdev->le_cnt += count; 33276ed58ec5SVille Tervo if (hdev->le_cnt > hdev->le_pkts) 33286ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 33296ed58ec5SVille Tervo } else { 33306ed58ec5SVille Tervo hdev->acl_cnt += count; 33316ed58ec5SVille Tervo if (hdev->acl_cnt > hdev->acl_pkts) 33326ed58ec5SVille Tervo hdev->acl_cnt = hdev->acl_pkts; 33336ed58ec5SVille Tervo } 3334f4280918SAndrei Emeltchenko break; 3335f4280918SAndrei Emeltchenko 3336f4280918SAndrei Emeltchenko case SCO_LINK: 333770f23020SAndrei Emeltchenko hdev->sco_cnt += count; 333870f23020SAndrei Emeltchenko if (hdev->sco_cnt > hdev->sco_pkts) 33395b7f9909SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 3340f4280918SAndrei Emeltchenko break; 3341f4280918SAndrei Emeltchenko 3342f4280918SAndrei Emeltchenko default: 3343f4280918SAndrei Emeltchenko BT_ERR("Unknown type %d conn %p", conn->type, conn); 3344f4280918SAndrei Emeltchenko break; 33451da177e4SLinus Torvalds } 33461da177e4SLinus Torvalds } 3347a9de9248SMarcel Holtmann 33483eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 33491da177e4SLinus Torvalds } 33501da177e4SLinus Torvalds 335176ef7cf7SAndrei Emeltchenko static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev, 335276ef7cf7SAndrei Emeltchenko __u16 handle) 335376ef7cf7SAndrei Emeltchenko { 335476ef7cf7SAndrei Emeltchenko struct hci_chan *chan; 335576ef7cf7SAndrei Emeltchenko 335676ef7cf7SAndrei Emeltchenko switch (hdev->dev_type) { 335776ef7cf7SAndrei Emeltchenko case HCI_BREDR: 335876ef7cf7SAndrei Emeltchenko return hci_conn_hash_lookup_handle(hdev, handle); 335976ef7cf7SAndrei Emeltchenko case HCI_AMP: 336076ef7cf7SAndrei Emeltchenko chan = hci_chan_lookup_handle(hdev, handle); 336176ef7cf7SAndrei Emeltchenko if (chan) 336276ef7cf7SAndrei Emeltchenko return chan->conn; 336376ef7cf7SAndrei Emeltchenko break; 336476ef7cf7SAndrei Emeltchenko default: 336576ef7cf7SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 336676ef7cf7SAndrei Emeltchenko break; 336776ef7cf7SAndrei Emeltchenko } 336876ef7cf7SAndrei Emeltchenko 336976ef7cf7SAndrei Emeltchenko return NULL; 337076ef7cf7SAndrei Emeltchenko } 337176ef7cf7SAndrei Emeltchenko 33726039aa73SGustavo Padovan static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) 337325e89e99SAndrei Emeltchenko { 337425e89e99SAndrei Emeltchenko struct hci_ev_num_comp_blocks *ev = (void *) skb->data; 337525e89e99SAndrei Emeltchenko int i; 337625e89e99SAndrei Emeltchenko 337725e89e99SAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) { 337825e89e99SAndrei Emeltchenko BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); 337925e89e99SAndrei Emeltchenko return; 338025e89e99SAndrei Emeltchenko } 338125e89e99SAndrei Emeltchenko 338225e89e99SAndrei Emeltchenko if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + 338325e89e99SAndrei Emeltchenko ev->num_hndl * sizeof(struct hci_comp_blocks_info)) { 338425e89e99SAndrei Emeltchenko BT_DBG("%s bad parameters", hdev->name); 338525e89e99SAndrei Emeltchenko return; 338625e89e99SAndrei Emeltchenko } 338725e89e99SAndrei Emeltchenko 338825e89e99SAndrei Emeltchenko BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks, 338925e89e99SAndrei Emeltchenko ev->num_hndl); 339025e89e99SAndrei Emeltchenko 339125e89e99SAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 339225e89e99SAndrei Emeltchenko struct hci_comp_blocks_info *info = &ev->handles[i]; 339376ef7cf7SAndrei Emeltchenko struct hci_conn *conn = NULL; 339425e89e99SAndrei Emeltchenko __u16 handle, block_count; 339525e89e99SAndrei Emeltchenko 339625e89e99SAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 339725e89e99SAndrei Emeltchenko block_count = __le16_to_cpu(info->blocks); 339825e89e99SAndrei Emeltchenko 339976ef7cf7SAndrei Emeltchenko conn = __hci_conn_lookup_handle(hdev, handle); 340025e89e99SAndrei Emeltchenko if (!conn) 340125e89e99SAndrei Emeltchenko continue; 340225e89e99SAndrei Emeltchenko 340325e89e99SAndrei Emeltchenko conn->sent -= block_count; 340425e89e99SAndrei Emeltchenko 340525e89e99SAndrei Emeltchenko switch (conn->type) { 340625e89e99SAndrei Emeltchenko case ACL_LINK: 3407bd1eb66bSAndrei Emeltchenko case AMP_LINK: 340825e89e99SAndrei Emeltchenko hdev->block_cnt += block_count; 340925e89e99SAndrei Emeltchenko if (hdev->block_cnt > hdev->num_blocks) 341025e89e99SAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 341125e89e99SAndrei Emeltchenko break; 341225e89e99SAndrei Emeltchenko 341325e89e99SAndrei Emeltchenko default: 341425e89e99SAndrei Emeltchenko BT_ERR("Unknown type %d conn %p", conn->type, conn); 341525e89e99SAndrei Emeltchenko break; 341625e89e99SAndrei Emeltchenko } 341725e89e99SAndrei Emeltchenko } 341825e89e99SAndrei Emeltchenko 341925e89e99SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->tx_work); 342025e89e99SAndrei Emeltchenko } 342125e89e99SAndrei Emeltchenko 34226039aa73SGustavo Padovan static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 34231da177e4SLinus Torvalds { 3424a9de9248SMarcel Holtmann struct hci_ev_mode_change *ev = (void *) skb->data; 342504837f64SMarcel Holtmann struct hci_conn *conn; 34261da177e4SLinus Torvalds 34279f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 34281da177e4SLinus Torvalds 34291da177e4SLinus Torvalds hci_dev_lock(hdev); 34301da177e4SLinus Torvalds 343104837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 343204837f64SMarcel Holtmann if (conn) { 343304837f64SMarcel Holtmann conn->mode = ev->mode; 343404837f64SMarcel Holtmann 34358fc9ced3SGustavo Padovan if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, 34368fc9ced3SGustavo Padovan &conn->flags)) { 343704837f64SMarcel Holtmann if (conn->mode == HCI_CM_ACTIVE) 343858a681efSJohan Hedberg set_bit(HCI_CONN_POWER_SAVE, &conn->flags); 343904837f64SMarcel Holtmann else 344058a681efSJohan Hedberg clear_bit(HCI_CONN_POWER_SAVE, &conn->flags); 344104837f64SMarcel Holtmann } 3442e73439d8SMarcel Holtmann 344351a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 3444e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 344504837f64SMarcel Holtmann } 344604837f64SMarcel Holtmann 344704837f64SMarcel Holtmann hci_dev_unlock(hdev); 344804837f64SMarcel Holtmann } 344904837f64SMarcel Holtmann 34506039aa73SGustavo Padovan static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 34511da177e4SLinus Torvalds { 3452052b30b0SMarcel Holtmann struct hci_ev_pin_code_req *ev = (void *) skb->data; 3453052b30b0SMarcel Holtmann struct hci_conn *conn; 3454052b30b0SMarcel Holtmann 3455a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 3456052b30b0SMarcel Holtmann 3457052b30b0SMarcel Holtmann hci_dev_lock(hdev); 3458052b30b0SMarcel Holtmann 3459052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 3460b6f98044SWaldemar Rymarkiewicz if (!conn) 3461b6f98044SWaldemar Rymarkiewicz goto unlock; 3462b6f98044SWaldemar Rymarkiewicz 3463b6f98044SWaldemar Rymarkiewicz if (conn->state == BT_CONNECTED) { 3464052b30b0SMarcel Holtmann hci_conn_hold(conn); 3465052b30b0SMarcel Holtmann conn->disc_timeout = HCI_PAIRING_TIMEOUT; 346676a68ba0SDavid Herrmann hci_conn_drop(conn); 3467052b30b0SMarcel Holtmann } 3468052b30b0SMarcel Holtmann 3469d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE) && 34702f407f0aSJohan Hedberg !test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags)) { 347103b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, 347203b555e1SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 3473d7a5a11dSMarcel Holtmann } else if (hci_dev_test_flag(hdev, HCI_MGMT)) { 3474a770bb5aSWaldemar Rymarkiewicz u8 secure; 3475a770bb5aSWaldemar Rymarkiewicz 3476a770bb5aSWaldemar Rymarkiewicz if (conn->pending_sec_level == BT_SECURITY_HIGH) 3477a770bb5aSWaldemar Rymarkiewicz secure = 1; 3478a770bb5aSWaldemar Rymarkiewicz else 3479a770bb5aSWaldemar Rymarkiewicz secure = 0; 3480a770bb5aSWaldemar Rymarkiewicz 3481744cf19eSJohan Hedberg mgmt_pin_code_request(hdev, &ev->bdaddr, secure); 3482a770bb5aSWaldemar Rymarkiewicz } 3483980e1a53SJohan Hedberg 3484b6f98044SWaldemar Rymarkiewicz unlock: 3485052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 34861da177e4SLinus Torvalds } 34871da177e4SLinus Torvalds 3488cb6f3f7aSJohan Hedberg static void conn_set_key(struct hci_conn *conn, u8 key_type, u8 pin_len) 3489cb6f3f7aSJohan Hedberg { 3490cb6f3f7aSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION) 3491cb6f3f7aSJohan Hedberg return; 3492cb6f3f7aSJohan Hedberg 3493cb6f3f7aSJohan Hedberg conn->pin_length = pin_len; 3494cb6f3f7aSJohan Hedberg conn->key_type = key_type; 3495cb6f3f7aSJohan Hedberg 3496cb6f3f7aSJohan Hedberg switch (key_type) { 3497cb6f3f7aSJohan Hedberg case HCI_LK_LOCAL_UNIT: 3498cb6f3f7aSJohan Hedberg case HCI_LK_REMOTE_UNIT: 3499cb6f3f7aSJohan Hedberg case HCI_LK_DEBUG_COMBINATION: 3500cb6f3f7aSJohan Hedberg return; 3501cb6f3f7aSJohan Hedberg case HCI_LK_COMBINATION: 3502cb6f3f7aSJohan Hedberg if (pin_len == 16) 3503cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_HIGH; 3504cb6f3f7aSJohan Hedberg else 3505cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_MEDIUM; 3506cb6f3f7aSJohan Hedberg break; 3507cb6f3f7aSJohan Hedberg case HCI_LK_UNAUTH_COMBINATION_P192: 3508cb6f3f7aSJohan Hedberg case HCI_LK_UNAUTH_COMBINATION_P256: 3509cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_MEDIUM; 3510cb6f3f7aSJohan Hedberg break; 3511cb6f3f7aSJohan Hedberg case HCI_LK_AUTH_COMBINATION_P192: 3512cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_HIGH; 3513cb6f3f7aSJohan Hedberg break; 3514cb6f3f7aSJohan Hedberg case HCI_LK_AUTH_COMBINATION_P256: 3515cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_FIPS; 3516cb6f3f7aSJohan Hedberg break; 3517cb6f3f7aSJohan Hedberg } 3518cb6f3f7aSJohan Hedberg } 3519cb6f3f7aSJohan Hedberg 35206039aa73SGustavo Padovan static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 35211da177e4SLinus Torvalds { 352255ed8ca1SJohan Hedberg struct hci_ev_link_key_req *ev = (void *) skb->data; 352355ed8ca1SJohan Hedberg struct hci_cp_link_key_reply cp; 352455ed8ca1SJohan Hedberg struct hci_conn *conn; 352555ed8ca1SJohan Hedberg struct link_key *key; 352655ed8ca1SJohan Hedberg 3527a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 352855ed8ca1SJohan Hedberg 3529d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 353055ed8ca1SJohan Hedberg return; 353155ed8ca1SJohan Hedberg 353255ed8ca1SJohan Hedberg hci_dev_lock(hdev); 353355ed8ca1SJohan Hedberg 353455ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, &ev->bdaddr); 353555ed8ca1SJohan Hedberg if (!key) { 35366ed93dc6SAndrei Emeltchenko BT_DBG("%s link key not found for %pMR", hdev->name, 35376ed93dc6SAndrei Emeltchenko &ev->bdaddr); 353855ed8ca1SJohan Hedberg goto not_found; 353955ed8ca1SJohan Hedberg } 354055ed8ca1SJohan Hedberg 35416ed93dc6SAndrei Emeltchenko BT_DBG("%s found key type %u for %pMR", hdev->name, key->type, 35426ed93dc6SAndrei Emeltchenko &ev->bdaddr); 354355ed8ca1SJohan Hedberg 354455ed8ca1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 354560b83f57SWaldemar Rymarkiewicz if (conn) { 3546fe8bc5acSJohan Hedberg clear_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags); 3547fe8bc5acSJohan Hedberg 354866138ce8SMarcel Holtmann if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 || 354966138ce8SMarcel Holtmann key->type == HCI_LK_UNAUTH_COMBINATION_P256) && 3550807deac2SGustavo Padovan conn->auth_type != 0xff && (conn->auth_type & 0x01)) { 355155ed8ca1SJohan Hedberg BT_DBG("%s ignoring unauthenticated key", hdev->name); 355255ed8ca1SJohan Hedberg goto not_found; 355355ed8ca1SJohan Hedberg } 355455ed8ca1SJohan Hedberg 355560b83f57SWaldemar Rymarkiewicz if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && 3556f3fb0b58SJohan Hedberg (conn->pending_sec_level == BT_SECURITY_HIGH || 3557f3fb0b58SJohan Hedberg conn->pending_sec_level == BT_SECURITY_FIPS)) { 35588fc9ced3SGustavo Padovan BT_DBG("%s ignoring key unauthenticated for high security", 35598fc9ced3SGustavo Padovan hdev->name); 356060b83f57SWaldemar Rymarkiewicz goto not_found; 356160b83f57SWaldemar Rymarkiewicz } 356260b83f57SWaldemar Rymarkiewicz 3563cb6f3f7aSJohan Hedberg conn_set_key(conn, key->type, key->pin_len); 356460b83f57SWaldemar Rymarkiewicz } 356560b83f57SWaldemar Rymarkiewicz 356655ed8ca1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 35679b3b4460SAndrei Emeltchenko memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE); 356855ed8ca1SJohan Hedberg 356955ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp); 357055ed8ca1SJohan Hedberg 357155ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 357255ed8ca1SJohan Hedberg 357355ed8ca1SJohan Hedberg return; 357455ed8ca1SJohan Hedberg 357555ed8ca1SJohan Hedberg not_found: 357655ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr); 357755ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 35781da177e4SLinus Torvalds } 35791da177e4SLinus Torvalds 35806039aa73SGustavo Padovan static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 35811da177e4SLinus Torvalds { 3582052b30b0SMarcel Holtmann struct hci_ev_link_key_notify *ev = (void *) skb->data; 3583052b30b0SMarcel Holtmann struct hci_conn *conn; 35847652ff6aSJohan Hedberg struct link_key *key; 35857652ff6aSJohan Hedberg bool persistent; 358655ed8ca1SJohan Hedberg u8 pin_len = 0; 3587052b30b0SMarcel Holtmann 3588a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 3589052b30b0SMarcel Holtmann 3590052b30b0SMarcel Holtmann hci_dev_lock(hdev); 3591052b30b0SMarcel Holtmann 3592052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 359382c13d42SJohan Hedberg if (!conn) 359482c13d42SJohan Hedberg goto unlock; 359582c13d42SJohan Hedberg 3596052b30b0SMarcel Holtmann hci_conn_hold(conn); 3597052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 359876a68ba0SDavid Herrmann hci_conn_drop(conn); 359982c13d42SJohan Hedberg 3600fe8bc5acSJohan Hedberg set_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags); 3601cb6f3f7aSJohan Hedberg conn_set_key(conn, ev->key_type, conn->pin_length); 3602052b30b0SMarcel Holtmann 3603d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 36047652ff6aSJohan Hedberg goto unlock; 360555ed8ca1SJohan Hedberg 36067652ff6aSJohan Hedberg key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key, 36077652ff6aSJohan Hedberg ev->key_type, pin_len, &persistent); 36087652ff6aSJohan Hedberg if (!key) 36097652ff6aSJohan Hedberg goto unlock; 36107652ff6aSJohan Hedberg 3611cb6f3f7aSJohan Hedberg /* Update connection information since adding the key will have 3612cb6f3f7aSJohan Hedberg * fixed up the type in the case of changed combination keys. 3613cb6f3f7aSJohan Hedberg */ 3614cb6f3f7aSJohan Hedberg if (ev->key_type == HCI_LK_CHANGED_COMBINATION) 3615cb6f3f7aSJohan Hedberg conn_set_key(conn, key->type, key->pin_len); 3616cb6f3f7aSJohan Hedberg 36177652ff6aSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 36187652ff6aSJohan Hedberg 36196d5650c4SJohan Hedberg /* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag 36206d5650c4SJohan Hedberg * is set. If it's not set simply remove the key from the kernel 36216d5650c4SJohan Hedberg * list (we've still notified user space about it but with 36226d5650c4SJohan Hedberg * store_hint being 0). 36236d5650c4SJohan Hedberg */ 36246d5650c4SJohan Hedberg if (key->type == HCI_LK_DEBUG_COMBINATION && 3625d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS)) { 36260378b597SJohan Hedberg list_del_rcu(&key->list); 36270378b597SJohan Hedberg kfree_rcu(key, rcu); 362882c13d42SJohan Hedberg goto unlock; 362982c13d42SJohan Hedberg } 363082c13d42SJohan Hedberg 3631af6a9c32SJohan Hedberg if (persistent) 3632af6a9c32SJohan Hedberg clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags); 3633af6a9c32SJohan Hedberg else 3634af6a9c32SJohan Hedberg set_bit(HCI_CONN_FLUSH_KEY, &conn->flags); 36357652ff6aSJohan Hedberg 36367652ff6aSJohan Hedberg unlock: 3637052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 36381da177e4SLinus Torvalds } 36391da177e4SLinus Torvalds 36406039aa73SGustavo Padovan static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) 364104837f64SMarcel Holtmann { 3642a9de9248SMarcel Holtmann struct hci_ev_clock_offset *ev = (void *) skb->data; 364304837f64SMarcel Holtmann struct hci_conn *conn; 364404837f64SMarcel Holtmann 36459f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 364604837f64SMarcel Holtmann 364704837f64SMarcel Holtmann hci_dev_lock(hdev); 364804837f64SMarcel Holtmann 364904837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 36501da177e4SLinus Torvalds if (conn && !ev->status) { 36511da177e4SLinus Torvalds struct inquiry_entry *ie; 36521da177e4SLinus Torvalds 3653cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 3654cc11b9c1SAndrei Emeltchenko if (ie) { 36551da177e4SLinus Torvalds ie->data.clock_offset = ev->clock_offset; 36561da177e4SLinus Torvalds ie->timestamp = jiffies; 36571da177e4SLinus Torvalds } 36581da177e4SLinus Torvalds } 36591da177e4SLinus Torvalds 36601da177e4SLinus Torvalds hci_dev_unlock(hdev); 36611da177e4SLinus Torvalds } 36621da177e4SLinus Torvalds 36636039aa73SGustavo Padovan static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 3664a8746417SMarcel Holtmann { 3665a8746417SMarcel Holtmann struct hci_ev_pkt_type_change *ev = (void *) skb->data; 3666a8746417SMarcel Holtmann struct hci_conn *conn; 3667a8746417SMarcel Holtmann 36689f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3669a8746417SMarcel Holtmann 3670a8746417SMarcel Holtmann hci_dev_lock(hdev); 3671a8746417SMarcel Holtmann 3672a8746417SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3673a8746417SMarcel Holtmann if (conn && !ev->status) 3674a8746417SMarcel Holtmann conn->pkt_type = __le16_to_cpu(ev->pkt_type); 3675a8746417SMarcel Holtmann 3676a8746417SMarcel Holtmann hci_dev_unlock(hdev); 3677a8746417SMarcel Holtmann } 3678a8746417SMarcel Holtmann 36796039aa73SGustavo Padovan static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) 368085a1e930SMarcel Holtmann { 3681a9de9248SMarcel Holtmann struct hci_ev_pscan_rep_mode *ev = (void *) skb->data; 368285a1e930SMarcel Holtmann struct inquiry_entry *ie; 368385a1e930SMarcel Holtmann 368485a1e930SMarcel Holtmann BT_DBG("%s", hdev->name); 368585a1e930SMarcel Holtmann 368685a1e930SMarcel Holtmann hci_dev_lock(hdev); 368785a1e930SMarcel Holtmann 3688cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 3689cc11b9c1SAndrei Emeltchenko if (ie) { 369085a1e930SMarcel Holtmann ie->data.pscan_rep_mode = ev->pscan_rep_mode; 369185a1e930SMarcel Holtmann ie->timestamp = jiffies; 369285a1e930SMarcel Holtmann } 369385a1e930SMarcel Holtmann 369485a1e930SMarcel Holtmann hci_dev_unlock(hdev); 369585a1e930SMarcel Holtmann } 369685a1e930SMarcel Holtmann 36976039aa73SGustavo Padovan static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, 3698807deac2SGustavo Padovan struct sk_buff *skb) 3699a9de9248SMarcel Holtmann { 3700a9de9248SMarcel Holtmann struct inquiry_data data; 3701a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 3702a9de9248SMarcel Holtmann 3703a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 3704a9de9248SMarcel Holtmann 3705a9de9248SMarcel Holtmann if (!num_rsp) 3706a9de9248SMarcel Holtmann return; 3707a9de9248SMarcel Holtmann 3708d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) 37091519cc17SAndre Guedes return; 37101519cc17SAndre Guedes 3711a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3712a9de9248SMarcel Holtmann 3713a9de9248SMarcel Holtmann if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { 3714138d22efSSzymon Janc struct inquiry_info_with_rssi_and_pscan_mode *info; 3715138d22efSSzymon Janc info = (void *) (skb->data + 1); 3716a9de9248SMarcel Holtmann 3717e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3718af58925cSMarcel Holtmann u32 flags; 3719af58925cSMarcel Holtmann 3720a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3721a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3722a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3723a9de9248SMarcel Holtmann data.pscan_mode = info->pscan_mode; 3724a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3725a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3726a9de9248SMarcel Holtmann data.rssi = info->rssi; 372741a96212SMarcel Holtmann data.ssp_mode = 0x00; 37283175405bSJohan Hedberg 3729af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 3730af58925cSMarcel Holtmann 373148264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3732e17acd40SJohan Hedberg info->dev_class, info->rssi, 3733af58925cSMarcel Holtmann flags, NULL, 0, NULL, 0); 3734a9de9248SMarcel Holtmann } 3735a9de9248SMarcel Holtmann } else { 3736a9de9248SMarcel Holtmann struct inquiry_info_with_rssi *info = (void *) (skb->data + 1); 3737a9de9248SMarcel Holtmann 3738e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3739af58925cSMarcel Holtmann u32 flags; 3740af58925cSMarcel Holtmann 3741a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3742a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3743a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3744a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 3745a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3746a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3747a9de9248SMarcel Holtmann data.rssi = info->rssi; 374841a96212SMarcel Holtmann data.ssp_mode = 0x00; 3749af58925cSMarcel Holtmann 3750af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 3751af58925cSMarcel Holtmann 375248264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3753e17acd40SJohan Hedberg info->dev_class, info->rssi, 3754af58925cSMarcel Holtmann flags, NULL, 0, NULL, 0); 3755a9de9248SMarcel Holtmann } 3756a9de9248SMarcel Holtmann } 3757a9de9248SMarcel Holtmann 3758a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3759a9de9248SMarcel Holtmann } 3760a9de9248SMarcel Holtmann 37616039aa73SGustavo Padovan static void hci_remote_ext_features_evt(struct hci_dev *hdev, 3762807deac2SGustavo Padovan struct sk_buff *skb) 3763a9de9248SMarcel Holtmann { 376441a96212SMarcel Holtmann struct hci_ev_remote_ext_features *ev = (void *) skb->data; 376541a96212SMarcel Holtmann struct hci_conn *conn; 376641a96212SMarcel Holtmann 3767a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 376841a96212SMarcel Holtmann 376941a96212SMarcel Holtmann hci_dev_lock(hdev); 377041a96212SMarcel Holtmann 377141a96212SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3772ccd556feSJohan Hedberg if (!conn) 3773ccd556feSJohan Hedberg goto unlock; 3774ccd556feSJohan Hedberg 3775cad718edSJohan Hedberg if (ev->page < HCI_MAX_PAGES) 3776cad718edSJohan Hedberg memcpy(conn->features[ev->page], ev->features, 8); 3777cad718edSJohan Hedberg 3778769be974SMarcel Holtmann if (!ev->status && ev->page == 0x01) { 377941a96212SMarcel Holtmann struct inquiry_entry *ie; 378041a96212SMarcel Holtmann 3781cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 3782cc11b9c1SAndrei Emeltchenko if (ie) 378302b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 378441a96212SMarcel Holtmann 3785bbb0eadaSJaganath Kanakkassery if (ev->features[0] & LMP_HOST_SSP) { 378658a681efSJohan Hedberg set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 3787bbb0eadaSJaganath Kanakkassery } else { 3788bbb0eadaSJaganath Kanakkassery /* It is mandatory by the Bluetooth specification that 3789bbb0eadaSJaganath Kanakkassery * Extended Inquiry Results are only used when Secure 3790bbb0eadaSJaganath Kanakkassery * Simple Pairing is enabled, but some devices violate 3791bbb0eadaSJaganath Kanakkassery * this. 3792bbb0eadaSJaganath Kanakkassery * 3793bbb0eadaSJaganath Kanakkassery * To make these devices work, the internal SSP 3794bbb0eadaSJaganath Kanakkassery * enabled flag needs to be cleared if the remote host 3795bbb0eadaSJaganath Kanakkassery * features do not indicate SSP support */ 3796bbb0eadaSJaganath Kanakkassery clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 3797bbb0eadaSJaganath Kanakkassery } 3798eb9a8f3fSMarcel Holtmann 3799eb9a8f3fSMarcel Holtmann if (ev->features[0] & LMP_HOST_SC) 3800eb9a8f3fSMarcel Holtmann set_bit(HCI_CONN_SC_ENABLED, &conn->flags); 380141a96212SMarcel Holtmann } 380241a96212SMarcel Holtmann 3803ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 3804ccd556feSJohan Hedberg goto unlock; 3805ccd556feSJohan Hedberg 3806671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 3807127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 3808127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 3809127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 3810127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 3811127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 3812b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 381348ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, NULL, 0); 3814392599b9SJohan Hedberg 3815127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 3816769be974SMarcel Holtmann conn->state = BT_CONNECTED; 3817539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 381876a68ba0SDavid Herrmann hci_conn_drop(conn); 3819769be974SMarcel Holtmann } 3820769be974SMarcel Holtmann 3821ccd556feSJohan Hedberg unlock: 382241a96212SMarcel Holtmann hci_dev_unlock(hdev); 3823a9de9248SMarcel Holtmann } 3824a9de9248SMarcel Holtmann 38256039aa73SGustavo Padovan static void hci_sync_conn_complete_evt(struct hci_dev *hdev, 3826807deac2SGustavo Padovan struct sk_buff *skb) 3827a9de9248SMarcel Holtmann { 3828b6a0dc82SMarcel Holtmann struct hci_ev_sync_conn_complete *ev = (void *) skb->data; 3829b6a0dc82SMarcel Holtmann struct hci_conn *conn; 3830b6a0dc82SMarcel Holtmann 38319f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3832b6a0dc82SMarcel Holtmann 3833b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 3834b6a0dc82SMarcel Holtmann 3835b6a0dc82SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 38369dc0a3afSMarcel Holtmann if (!conn) { 38379dc0a3afSMarcel Holtmann if (ev->link_type == ESCO_LINK) 38389dc0a3afSMarcel Holtmann goto unlock; 38399dc0a3afSMarcel Holtmann 38409dc0a3afSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 3841b6a0dc82SMarcel Holtmann if (!conn) 3842b6a0dc82SMarcel Holtmann goto unlock; 3843b6a0dc82SMarcel Holtmann 38449dc0a3afSMarcel Holtmann conn->type = SCO_LINK; 38459dc0a3afSMarcel Holtmann } 38469dc0a3afSMarcel Holtmann 3847732547f9SMarcel Holtmann switch (ev->status) { 3848732547f9SMarcel Holtmann case 0x00: 3849732547f9SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 3850732547f9SMarcel Holtmann conn->state = BT_CONNECTED; 3851732547f9SMarcel Holtmann 385223b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn); 3853732547f9SMarcel Holtmann hci_conn_add_sysfs(conn); 3854732547f9SMarcel Holtmann break; 3855732547f9SMarcel Holtmann 385681218d20SNick Pelly case 0x10: /* Connection Accept Timeout */ 38571a4c958cSFrédéric Dalleau case 0x0d: /* Connection Rejected due to Limited Resources */ 3858705e5711SStephen Coe case 0x11: /* Unsupported Feature or Parameter Value */ 3859732547f9SMarcel Holtmann case 0x1c: /* SCO interval rejected */ 38601038a00bSNick Pelly case 0x1a: /* Unsupported Remote Feature */ 3861732547f9SMarcel Holtmann case 0x1f: /* Unspecified error */ 386227539bc4SAndrew Earl case 0x20: /* Unsupported LMP Parameter value */ 38632dea632fSFrédéric Dalleau if (conn->out) { 3864efc7688bSMarcel Holtmann conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | 3865efc7688bSMarcel Holtmann (hdev->esco_type & EDR_ESCO_MASK); 38662dea632fSFrédéric Dalleau if (hci_setup_sync(conn, conn->link->handle)) 3867efc7688bSMarcel Holtmann goto unlock; 3868efc7688bSMarcel Holtmann } 3869732547f9SMarcel Holtmann /* fall through */ 3870efc7688bSMarcel Holtmann 3871732547f9SMarcel Holtmann default: 3872b6a0dc82SMarcel Holtmann conn->state = BT_CLOSED; 3873732547f9SMarcel Holtmann break; 3874732547f9SMarcel Holtmann } 3875b6a0dc82SMarcel Holtmann 3876539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 3877b6a0dc82SMarcel Holtmann if (ev->status) 3878b6a0dc82SMarcel Holtmann hci_conn_del(conn); 3879b6a0dc82SMarcel Holtmann 3880b6a0dc82SMarcel Holtmann unlock: 3881b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 3882a9de9248SMarcel Holtmann } 3883a9de9248SMarcel Holtmann 3884efdcf8e3SMarcel Holtmann static inline size_t eir_get_length(u8 *eir, size_t eir_len) 3885efdcf8e3SMarcel Holtmann { 3886efdcf8e3SMarcel Holtmann size_t parsed = 0; 3887efdcf8e3SMarcel Holtmann 3888efdcf8e3SMarcel Holtmann while (parsed < eir_len) { 3889efdcf8e3SMarcel Holtmann u8 field_len = eir[0]; 3890efdcf8e3SMarcel Holtmann 3891efdcf8e3SMarcel Holtmann if (field_len == 0) 3892efdcf8e3SMarcel Holtmann return parsed; 3893efdcf8e3SMarcel Holtmann 3894efdcf8e3SMarcel Holtmann parsed += field_len + 1; 3895efdcf8e3SMarcel Holtmann eir += field_len + 1; 3896efdcf8e3SMarcel Holtmann } 3897efdcf8e3SMarcel Holtmann 3898efdcf8e3SMarcel Holtmann return eir_len; 3899efdcf8e3SMarcel Holtmann } 3900efdcf8e3SMarcel Holtmann 39016039aa73SGustavo Padovan static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, 3902807deac2SGustavo Padovan struct sk_buff *skb) 3903a9de9248SMarcel Holtmann { 3904a9de9248SMarcel Holtmann struct inquiry_data data; 3905a9de9248SMarcel Holtmann struct extended_inquiry_info *info = (void *) (skb->data + 1); 3906a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 39079d939d94SVishal Agarwal size_t eir_len; 3908a9de9248SMarcel Holtmann 3909a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 3910a9de9248SMarcel Holtmann 3911a9de9248SMarcel Holtmann if (!num_rsp) 3912a9de9248SMarcel Holtmann return; 3913a9de9248SMarcel Holtmann 3914d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) 39151519cc17SAndre Guedes return; 39161519cc17SAndre Guedes 3917a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3918a9de9248SMarcel Holtmann 3919e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3920af58925cSMarcel Holtmann u32 flags; 3921af58925cSMarcel Holtmann bool name_known; 3922561aafbcSJohan Hedberg 3923a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3924a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3925a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3926a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 3927a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3928a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3929a9de9248SMarcel Holtmann data.rssi = info->rssi; 393041a96212SMarcel Holtmann data.ssp_mode = 0x01; 3931561aafbcSJohan Hedberg 3932d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 39334ddb1930SJohan Hedberg name_known = eir_has_data_type(info->data, 39344ddb1930SJohan Hedberg sizeof(info->data), 39354ddb1930SJohan Hedberg EIR_NAME_COMPLETE); 3936561aafbcSJohan Hedberg else 3937561aafbcSJohan Hedberg name_known = true; 3938561aafbcSJohan Hedberg 3939af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, name_known); 3940af58925cSMarcel Holtmann 39419d939d94SVishal Agarwal eir_len = eir_get_length(info->data, sizeof(info->data)); 3942af58925cSMarcel Holtmann 394348264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3944af58925cSMarcel Holtmann info->dev_class, info->rssi, 3945af58925cSMarcel Holtmann flags, info->data, eir_len, NULL, 0); 3946a9de9248SMarcel Holtmann } 3947a9de9248SMarcel Holtmann 3948a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3949a9de9248SMarcel Holtmann } 3950a9de9248SMarcel Holtmann 39511c2e0041SJohan Hedberg static void hci_key_refresh_complete_evt(struct hci_dev *hdev, 39521c2e0041SJohan Hedberg struct sk_buff *skb) 39531c2e0041SJohan Hedberg { 39541c2e0041SJohan Hedberg struct hci_ev_key_refresh_complete *ev = (void *) skb->data; 39551c2e0041SJohan Hedberg struct hci_conn *conn; 39561c2e0041SJohan Hedberg 39579f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status, 39581c2e0041SJohan Hedberg __le16_to_cpu(ev->handle)); 39591c2e0041SJohan Hedberg 39601c2e0041SJohan Hedberg hci_dev_lock(hdev); 39611c2e0041SJohan Hedberg 39621c2e0041SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 39631c2e0041SJohan Hedberg if (!conn) 39641c2e0041SJohan Hedberg goto unlock; 39651c2e0041SJohan Hedberg 39669eb1fbfaSJohan Hedberg /* For BR/EDR the necessary steps are taken through the 39679eb1fbfaSJohan Hedberg * auth_complete event. 39689eb1fbfaSJohan Hedberg */ 39699eb1fbfaSJohan Hedberg if (conn->type != LE_LINK) 39709eb1fbfaSJohan Hedberg goto unlock; 39719eb1fbfaSJohan Hedberg 39721c2e0041SJohan Hedberg if (!ev->status) 39731c2e0041SJohan Hedberg conn->sec_level = conn->pending_sec_level; 39741c2e0041SJohan Hedberg 39751c2e0041SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 39761c2e0041SJohan Hedberg 39771c2e0041SJohan Hedberg if (ev->status && conn->state == BT_CONNECTED) { 3978bed71748SAndre Guedes hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 397976a68ba0SDavid Herrmann hci_conn_drop(conn); 39801c2e0041SJohan Hedberg goto unlock; 39811c2e0041SJohan Hedberg } 39821c2e0041SJohan Hedberg 39831c2e0041SJohan Hedberg if (conn->state == BT_CONFIG) { 39841c2e0041SJohan Hedberg if (!ev->status) 39851c2e0041SJohan Hedberg conn->state = BT_CONNECTED; 39861c2e0041SJohan Hedberg 3987539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 398876a68ba0SDavid Herrmann hci_conn_drop(conn); 39891c2e0041SJohan Hedberg } else { 39901c2e0041SJohan Hedberg hci_auth_cfm(conn, ev->status); 39911c2e0041SJohan Hedberg 39921c2e0041SJohan Hedberg hci_conn_hold(conn); 39931c2e0041SJohan Hedberg conn->disc_timeout = HCI_DISCONN_TIMEOUT; 399476a68ba0SDavid Herrmann hci_conn_drop(conn); 39951c2e0041SJohan Hedberg } 39961c2e0041SJohan Hedberg 39971c2e0041SJohan Hedberg unlock: 39981c2e0041SJohan Hedberg hci_dev_unlock(hdev); 39991c2e0041SJohan Hedberg } 40001c2e0041SJohan Hedberg 40016039aa73SGustavo Padovan static u8 hci_get_auth_req(struct hci_conn *conn) 400217fa4b9dSJohan Hedberg { 400317fa4b9dSJohan Hedberg /* If remote requests no-bonding follow that lead */ 4004acabae96SMikel Astiz if (conn->remote_auth == HCI_AT_NO_BONDING || 4005acabae96SMikel Astiz conn->remote_auth == HCI_AT_NO_BONDING_MITM) 400658797bf7SWaldemar Rymarkiewicz return conn->remote_auth | (conn->auth_type & 0x01); 400717fa4b9dSJohan Hedberg 4008b7f94c88SMikel Astiz /* If both remote and local have enough IO capabilities, require 4009b7f94c88SMikel Astiz * MITM protection 4010b7f94c88SMikel Astiz */ 4011b7f94c88SMikel Astiz if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT && 4012b7f94c88SMikel Astiz conn->io_capability != HCI_IO_NO_INPUT_OUTPUT) 4013b7f94c88SMikel Astiz return conn->remote_auth | 0x01; 4014b7f94c88SMikel Astiz 40157e74170aSTimo Mueller /* No MITM protection possible so ignore remote requirement */ 40167e74170aSTimo Mueller return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01); 401717fa4b9dSJohan Hedberg } 401817fa4b9dSJohan Hedberg 4019a83ed81eSMarcel Holtmann static u8 bredr_oob_data_present(struct hci_conn *conn) 4020a83ed81eSMarcel Holtmann { 4021a83ed81eSMarcel Holtmann struct hci_dev *hdev = conn->hdev; 4022a83ed81eSMarcel Holtmann struct oob_data *data; 4023a83ed81eSMarcel Holtmann 4024a83ed81eSMarcel Holtmann data = hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR); 4025a83ed81eSMarcel Holtmann if (!data) 4026a83ed81eSMarcel Holtmann return 0x00; 4027a83ed81eSMarcel Holtmann 4028bf21d793SMarcel Holtmann if (bredr_sc_enabled(hdev)) { 4029bf21d793SMarcel Holtmann /* When Secure Connections is enabled, then just 4030bf21d793SMarcel Holtmann * return the present value stored with the OOB 4031bf21d793SMarcel Holtmann * data. The stored value contains the right present 4032bf21d793SMarcel Holtmann * information. However it can only be trusted when 4033bf21d793SMarcel Holtmann * not in Secure Connection Only mode. 4034aa5b0345SMarcel Holtmann */ 4035d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SC_ONLY)) 4036bf21d793SMarcel Holtmann return data->present; 4037bf21d793SMarcel Holtmann 4038bf21d793SMarcel Holtmann /* When Secure Connections Only mode is enabled, then 4039bf21d793SMarcel Holtmann * the P-256 values are required. If they are not 4040bf21d793SMarcel Holtmann * available, then do not declare that OOB data is 4041bf21d793SMarcel Holtmann * present. 4042bf21d793SMarcel Holtmann */ 4043bf21d793SMarcel Holtmann if (!memcmp(data->rand256, ZERO_KEY, 16) || 4044bf21d793SMarcel Holtmann !memcmp(data->hash256, ZERO_KEY, 16)) 4045aa5b0345SMarcel Holtmann return 0x00; 4046aa5b0345SMarcel Holtmann 4047bf21d793SMarcel Holtmann return 0x02; 4048bf21d793SMarcel Holtmann } 4049659c7fb0SMarcel Holtmann 4050659c7fb0SMarcel Holtmann /* When Secure Connections is not enabled or actually 4051659c7fb0SMarcel Holtmann * not supported by the hardware, then check that if 4052659c7fb0SMarcel Holtmann * P-192 data values are present. 4053659c7fb0SMarcel Holtmann */ 4054659c7fb0SMarcel Holtmann if (!memcmp(data->rand192, ZERO_KEY, 16) || 4055659c7fb0SMarcel Holtmann !memcmp(data->hash192, ZERO_KEY, 16)) 4056659c7fb0SMarcel Holtmann return 0x00; 4057659c7fb0SMarcel Holtmann 4058a83ed81eSMarcel Holtmann return 0x01; 4059659c7fb0SMarcel Holtmann } 4060a83ed81eSMarcel Holtmann 40616039aa73SGustavo Padovan static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 40620493684eSMarcel Holtmann { 40630493684eSMarcel Holtmann struct hci_ev_io_capa_request *ev = (void *) skb->data; 40640493684eSMarcel Holtmann struct hci_conn *conn; 40650493684eSMarcel Holtmann 40660493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 40670493684eSMarcel Holtmann 40680493684eSMarcel Holtmann hci_dev_lock(hdev); 40690493684eSMarcel Holtmann 40700493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 407103b555e1SJohan Hedberg if (!conn) 407203b555e1SJohan Hedberg goto unlock; 407303b555e1SJohan Hedberg 40740493684eSMarcel Holtmann hci_conn_hold(conn); 40750493684eSMarcel Holtmann 4076d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 407703b555e1SJohan Hedberg goto unlock; 407803b555e1SJohan Hedberg 40792f407f0aSJohan Hedberg /* Allow pairing if we're pairable, the initiators of the 40802f407f0aSJohan Hedberg * pairing or if the remote is not requesting bonding. 40812f407f0aSJohan Hedberg */ 4082d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_BONDABLE) || 40832f407f0aSJohan Hedberg test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags) || 408403b555e1SJohan Hedberg (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { 408517fa4b9dSJohan Hedberg struct hci_cp_io_capability_reply cp; 408617fa4b9dSJohan Hedberg 408717fa4b9dSJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 40887a7f1e7cSHemant Gupta /* Change the IO capability from KeyboardDisplay 40897a7f1e7cSHemant Gupta * to DisplayYesNo as it is not supported by BT spec. */ 40907a7f1e7cSHemant Gupta cp.capability = (conn->io_capability == 0x04) ? 4091a767631aSMikel Astiz HCI_IO_DISPLAY_YESNO : conn->io_capability; 4092b7f94c88SMikel Astiz 4093b7f94c88SMikel Astiz /* If we are initiators, there is no remote information yet */ 4094b7f94c88SMikel Astiz if (conn->remote_auth == 0xff) { 4095b16c6604SMikel Astiz /* Request MITM protection if our IO caps allow it 40964ad51a75SJohan Hedberg * except for the no-bonding case. 4097b16c6604SMikel Astiz */ 40986fd6b915SMikel Astiz if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT && 40999f743d74SJohan Hedberg conn->auth_type != HCI_AT_NO_BONDING) 41006c53823aSJohan Hedberg conn->auth_type |= 0x01; 4101b7f94c88SMikel Astiz } else { 41027cbc9bd9SJohan Hedberg conn->auth_type = hci_get_auth_req(conn); 4103b7f94c88SMikel Astiz } 410417fa4b9dSJohan Hedberg 410582c295b1SJohan Hedberg /* If we're not bondable, force one of the non-bondable 410682c295b1SJohan Hedberg * authentication requirement values. 410782c295b1SJohan Hedberg */ 4108d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE)) 410982c295b1SJohan Hedberg conn->auth_type &= HCI_AT_NO_BONDING_MITM; 411082c295b1SJohan Hedberg 411182c295b1SJohan Hedberg cp.authentication = conn->auth_type; 4112a83ed81eSMarcel Holtmann cp.oob_data = bredr_oob_data_present(conn); 4113ce85ee13SSzymon Janc 411417fa4b9dSJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY, 411517fa4b9dSJohan Hedberg sizeof(cp), &cp); 411603b555e1SJohan Hedberg } else { 411703b555e1SJohan Hedberg struct hci_cp_io_capability_neg_reply cp; 411803b555e1SJohan Hedberg 411903b555e1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 41209f5a0d7bSAndrei Emeltchenko cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED; 412103b555e1SJohan Hedberg 412203b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, 412303b555e1SJohan Hedberg sizeof(cp), &cp); 412403b555e1SJohan Hedberg } 412503b555e1SJohan Hedberg 412603b555e1SJohan Hedberg unlock: 412703b555e1SJohan Hedberg hci_dev_unlock(hdev); 412803b555e1SJohan Hedberg } 412903b555e1SJohan Hedberg 41306039aa73SGustavo Padovan static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) 413103b555e1SJohan Hedberg { 413203b555e1SJohan Hedberg struct hci_ev_io_capa_reply *ev = (void *) skb->data; 413303b555e1SJohan Hedberg struct hci_conn *conn; 413403b555e1SJohan Hedberg 413503b555e1SJohan Hedberg BT_DBG("%s", hdev->name); 413603b555e1SJohan Hedberg 413703b555e1SJohan Hedberg hci_dev_lock(hdev); 413803b555e1SJohan Hedberg 413903b555e1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 414003b555e1SJohan Hedberg if (!conn) 414103b555e1SJohan Hedberg goto unlock; 414203b555e1SJohan Hedberg 414303b555e1SJohan Hedberg conn->remote_cap = ev->capability; 414403b555e1SJohan Hedberg conn->remote_auth = ev->authentication; 414503b555e1SJohan Hedberg 414603b555e1SJohan Hedberg unlock: 41470493684eSMarcel Holtmann hci_dev_unlock(hdev); 41480493684eSMarcel Holtmann } 41490493684eSMarcel Holtmann 41506039aa73SGustavo Padovan static void hci_user_confirm_request_evt(struct hci_dev *hdev, 4151a5c29683SJohan Hedberg struct sk_buff *skb) 4152a5c29683SJohan Hedberg { 4153a5c29683SJohan Hedberg struct hci_ev_user_confirm_req *ev = (void *) skb->data; 415455bc1a37SJohan Hedberg int loc_mitm, rem_mitm, confirm_hint = 0; 41557a828908SJohan Hedberg struct hci_conn *conn; 4156a5c29683SJohan Hedberg 4157a5c29683SJohan Hedberg BT_DBG("%s", hdev->name); 4158a5c29683SJohan Hedberg 4159a5c29683SJohan Hedberg hci_dev_lock(hdev); 4160a5c29683SJohan Hedberg 4161d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 41627a828908SJohan Hedberg goto unlock; 41637a828908SJohan Hedberg 41647a828908SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 41657a828908SJohan Hedberg if (!conn) 41667a828908SJohan Hedberg goto unlock; 41677a828908SJohan Hedberg 41687a828908SJohan Hedberg loc_mitm = (conn->auth_type & 0x01); 41697a828908SJohan Hedberg rem_mitm = (conn->remote_auth & 0x01); 41707a828908SJohan Hedberg 41717a828908SJohan Hedberg /* If we require MITM but the remote device can't provide that 41726c53823aSJohan Hedberg * (it has NoInputNoOutput) then reject the confirmation 41736c53823aSJohan Hedberg * request. We check the security level here since it doesn't 41746c53823aSJohan Hedberg * necessarily match conn->auth_type. 41756fd6b915SMikel Astiz */ 41766c53823aSJohan Hedberg if (conn->pending_sec_level > BT_SECURITY_MEDIUM && 41776c53823aSJohan Hedberg conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) { 41787a828908SJohan Hedberg BT_DBG("Rejecting request: remote device can't provide MITM"); 41797a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY, 41807a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 41817a828908SJohan Hedberg goto unlock; 41827a828908SJohan Hedberg } 41837a828908SJohan Hedberg 41847a828908SJohan Hedberg /* If no side requires MITM protection; auto-accept */ 4185a767631aSMikel Astiz if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) && 4186a767631aSMikel Astiz (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) { 418755bc1a37SJohan Hedberg 418855bc1a37SJohan Hedberg /* If we're not the initiators request authorization to 418955bc1a37SJohan Hedberg * proceed from user space (mgmt_user_confirm with 4190ba15a58bSJohan Hedberg * confirm_hint set to 1). The exception is if neither 419102f3e254SJohan Hedberg * side had MITM or if the local IO capability is 419202f3e254SJohan Hedberg * NoInputNoOutput, in which case we do auto-accept 4193ba15a58bSJohan Hedberg */ 4194ba15a58bSJohan Hedberg if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && 419502f3e254SJohan Hedberg conn->io_capability != HCI_IO_NO_INPUT_OUTPUT && 4196ba15a58bSJohan Hedberg (loc_mitm || rem_mitm)) { 419755bc1a37SJohan Hedberg BT_DBG("Confirming auto-accept as acceptor"); 419855bc1a37SJohan Hedberg confirm_hint = 1; 419955bc1a37SJohan Hedberg goto confirm; 420055bc1a37SJohan Hedberg } 420155bc1a37SJohan Hedberg 42029f61656aSJohan Hedberg BT_DBG("Auto-accept of user confirmation with %ums delay", 42039f61656aSJohan Hedberg hdev->auto_accept_delay); 42049f61656aSJohan Hedberg 42059f61656aSJohan Hedberg if (hdev->auto_accept_delay > 0) { 42069f61656aSJohan Hedberg int delay = msecs_to_jiffies(hdev->auto_accept_delay); 42077bc18d9dSJohan Hedberg queue_delayed_work(conn->hdev->workqueue, 42087bc18d9dSJohan Hedberg &conn->auto_accept_work, delay); 42099f61656aSJohan Hedberg goto unlock; 42109f61656aSJohan Hedberg } 42119f61656aSJohan Hedberg 42127a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, 42137a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 42147a828908SJohan Hedberg goto unlock; 42157a828908SJohan Hedberg } 42167a828908SJohan Hedberg 421755bc1a37SJohan Hedberg confirm: 421839adbffeSJohan Hedberg mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, 421939adbffeSJohan Hedberg le32_to_cpu(ev->passkey), confirm_hint); 4220a5c29683SJohan Hedberg 42217a828908SJohan Hedberg unlock: 4222a5c29683SJohan Hedberg hci_dev_unlock(hdev); 4223a5c29683SJohan Hedberg } 4224a5c29683SJohan Hedberg 42256039aa73SGustavo Padovan static void hci_user_passkey_request_evt(struct hci_dev *hdev, 42261143d458SBrian Gix struct sk_buff *skb) 42271143d458SBrian Gix { 42281143d458SBrian Gix struct hci_ev_user_passkey_req *ev = (void *) skb->data; 42291143d458SBrian Gix 42301143d458SBrian Gix BT_DBG("%s", hdev->name); 42311143d458SBrian Gix 4232d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 4233272d90dfSJohan Hedberg mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); 42341143d458SBrian Gix } 42351143d458SBrian Gix 423692a25256SJohan Hedberg static void hci_user_passkey_notify_evt(struct hci_dev *hdev, 423792a25256SJohan Hedberg struct sk_buff *skb) 423892a25256SJohan Hedberg { 423992a25256SJohan Hedberg struct hci_ev_user_passkey_notify *ev = (void *) skb->data; 424092a25256SJohan Hedberg struct hci_conn *conn; 424192a25256SJohan Hedberg 424292a25256SJohan Hedberg BT_DBG("%s", hdev->name); 424392a25256SJohan Hedberg 424492a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 424592a25256SJohan Hedberg if (!conn) 424692a25256SJohan Hedberg return; 424792a25256SJohan Hedberg 424892a25256SJohan Hedberg conn->passkey_notify = __le32_to_cpu(ev->passkey); 424992a25256SJohan Hedberg conn->passkey_entered = 0; 425092a25256SJohan Hedberg 4251d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 425292a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 425392a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 425492a25256SJohan Hedberg conn->passkey_entered); 425592a25256SJohan Hedberg } 425692a25256SJohan Hedberg 425792a25256SJohan Hedberg static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 425892a25256SJohan Hedberg { 425992a25256SJohan Hedberg struct hci_ev_keypress_notify *ev = (void *) skb->data; 426092a25256SJohan Hedberg struct hci_conn *conn; 426192a25256SJohan Hedberg 426292a25256SJohan Hedberg BT_DBG("%s", hdev->name); 426392a25256SJohan Hedberg 426492a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 426592a25256SJohan Hedberg if (!conn) 426692a25256SJohan Hedberg return; 426792a25256SJohan Hedberg 426892a25256SJohan Hedberg switch (ev->type) { 426992a25256SJohan Hedberg case HCI_KEYPRESS_STARTED: 427092a25256SJohan Hedberg conn->passkey_entered = 0; 427192a25256SJohan Hedberg return; 427292a25256SJohan Hedberg 427392a25256SJohan Hedberg case HCI_KEYPRESS_ENTERED: 427492a25256SJohan Hedberg conn->passkey_entered++; 427592a25256SJohan Hedberg break; 427692a25256SJohan Hedberg 427792a25256SJohan Hedberg case HCI_KEYPRESS_ERASED: 427892a25256SJohan Hedberg conn->passkey_entered--; 427992a25256SJohan Hedberg break; 428092a25256SJohan Hedberg 428192a25256SJohan Hedberg case HCI_KEYPRESS_CLEARED: 428292a25256SJohan Hedberg conn->passkey_entered = 0; 428392a25256SJohan Hedberg break; 428492a25256SJohan Hedberg 428592a25256SJohan Hedberg case HCI_KEYPRESS_COMPLETED: 428692a25256SJohan Hedberg return; 428792a25256SJohan Hedberg } 428892a25256SJohan Hedberg 4289d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 429092a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 429192a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 429292a25256SJohan Hedberg conn->passkey_entered); 429392a25256SJohan Hedberg } 429492a25256SJohan Hedberg 42956039aa73SGustavo Padovan static void hci_simple_pair_complete_evt(struct hci_dev *hdev, 4296807deac2SGustavo Padovan struct sk_buff *skb) 42970493684eSMarcel Holtmann { 42980493684eSMarcel Holtmann struct hci_ev_simple_pair_complete *ev = (void *) skb->data; 42990493684eSMarcel Holtmann struct hci_conn *conn; 43000493684eSMarcel Holtmann 43010493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 43020493684eSMarcel Holtmann 43030493684eSMarcel Holtmann hci_dev_lock(hdev); 43040493684eSMarcel Holtmann 43050493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 43062a611692SJohan Hedberg if (!conn) 43072a611692SJohan Hedberg goto unlock; 43082a611692SJohan Hedberg 4309c1d4fa7aSJohan Hedberg /* Reset the authentication requirement to unknown */ 4310c1d4fa7aSJohan Hedberg conn->remote_auth = 0xff; 4311c1d4fa7aSJohan Hedberg 43122a611692SJohan Hedberg /* To avoid duplicate auth_failed events to user space we check 43132a611692SJohan Hedberg * the HCI_CONN_AUTH_PEND flag which will be set if we 43142a611692SJohan Hedberg * initiated the authentication. A traditional auth_complete 43152a611692SJohan Hedberg * event gets always produced as initiator and is also mapped to 43162a611692SJohan Hedberg * the mgmt_auth_failed event */ 4317fa1bd918SMikel Astiz if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status) 4318e1e930f5SJohan Hedberg mgmt_auth_failed(conn, ev->status); 43192a611692SJohan Hedberg 432076a68ba0SDavid Herrmann hci_conn_drop(conn); 43210493684eSMarcel Holtmann 43222a611692SJohan Hedberg unlock: 43230493684eSMarcel Holtmann hci_dev_unlock(hdev); 43240493684eSMarcel Holtmann } 43250493684eSMarcel Holtmann 43266039aa73SGustavo Padovan static void hci_remote_host_features_evt(struct hci_dev *hdev, 4327807deac2SGustavo Padovan struct sk_buff *skb) 432841a96212SMarcel Holtmann { 432941a96212SMarcel Holtmann struct hci_ev_remote_host_features *ev = (void *) skb->data; 433041a96212SMarcel Holtmann struct inquiry_entry *ie; 4331cad718edSJohan Hedberg struct hci_conn *conn; 433241a96212SMarcel Holtmann 433341a96212SMarcel Holtmann BT_DBG("%s", hdev->name); 433441a96212SMarcel Holtmann 433541a96212SMarcel Holtmann hci_dev_lock(hdev); 433641a96212SMarcel Holtmann 4337cad718edSJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 4338cad718edSJohan Hedberg if (conn) 4339cad718edSJohan Hedberg memcpy(conn->features[1], ev->features, 8); 4340cad718edSJohan Hedberg 4341cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 4342cc11b9c1SAndrei Emeltchenko if (ie) 434302b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 434441a96212SMarcel Holtmann 434541a96212SMarcel Holtmann hci_dev_unlock(hdev); 434641a96212SMarcel Holtmann } 434741a96212SMarcel Holtmann 43486039aa73SGustavo Padovan static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, 43492763eda6SSzymon Janc struct sk_buff *skb) 43502763eda6SSzymon Janc { 43512763eda6SSzymon Janc struct hci_ev_remote_oob_data_request *ev = (void *) skb->data; 43522763eda6SSzymon Janc struct oob_data *data; 43532763eda6SSzymon Janc 43542763eda6SSzymon Janc BT_DBG("%s", hdev->name); 43552763eda6SSzymon Janc 43562763eda6SSzymon Janc hci_dev_lock(hdev); 43572763eda6SSzymon Janc 4358d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 4359e1ba1f15SSzymon Janc goto unlock; 4360e1ba1f15SSzymon Janc 43616928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, &ev->bdaddr, BDADDR_BREDR); 43626665d057SMarcel Holtmann if (!data) { 43636665d057SMarcel Holtmann struct hci_cp_remote_oob_data_neg_reply cp; 43646665d057SMarcel Holtmann 43656665d057SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 43666665d057SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, 43676665d057SMarcel Holtmann sizeof(cp), &cp); 43686665d057SMarcel Holtmann goto unlock; 43696665d057SMarcel Holtmann } 43706665d057SMarcel Holtmann 4371710f11c0SJohan Hedberg if (bredr_sc_enabled(hdev)) { 4372519ca9d0SMarcel Holtmann struct hci_cp_remote_oob_ext_data_reply cp; 4373519ca9d0SMarcel Holtmann 4374519ca9d0SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 4375d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) { 43766665d057SMarcel Holtmann memset(cp.hash192, 0, sizeof(cp.hash192)); 43776665d057SMarcel Holtmann memset(cp.rand192, 0, sizeof(cp.rand192)); 43786665d057SMarcel Holtmann } else { 4379519ca9d0SMarcel Holtmann memcpy(cp.hash192, data->hash192, sizeof(cp.hash192)); 438038da1703SJohan Hedberg memcpy(cp.rand192, data->rand192, sizeof(cp.rand192)); 43816665d057SMarcel Holtmann } 4382519ca9d0SMarcel Holtmann memcpy(cp.hash256, data->hash256, sizeof(cp.hash256)); 438338da1703SJohan Hedberg memcpy(cp.rand256, data->rand256, sizeof(cp.rand256)); 4384519ca9d0SMarcel Holtmann 4385519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY, 4386519ca9d0SMarcel Holtmann sizeof(cp), &cp); 4387519ca9d0SMarcel Holtmann } else { 43882763eda6SSzymon Janc struct hci_cp_remote_oob_data_reply cp; 43892763eda6SSzymon Janc 43902763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr); 4391519ca9d0SMarcel Holtmann memcpy(cp.hash, data->hash192, sizeof(cp.hash)); 439238da1703SJohan Hedberg memcpy(cp.rand, data->rand192, sizeof(cp.rand)); 43932763eda6SSzymon Janc 4394519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, 4395519ca9d0SMarcel Holtmann sizeof(cp), &cp); 4396519ca9d0SMarcel Holtmann } 43972763eda6SSzymon Janc 4398e1ba1f15SSzymon Janc unlock: 43992763eda6SSzymon Janc hci_dev_unlock(hdev); 44002763eda6SSzymon Janc } 44012763eda6SSzymon Janc 4402d5e91192SAndrei Emeltchenko static void hci_phy_link_complete_evt(struct hci_dev *hdev, 4403d5e91192SAndrei Emeltchenko struct sk_buff *skb) 4404d5e91192SAndrei Emeltchenko { 4405d5e91192SAndrei Emeltchenko struct hci_ev_phy_link_complete *ev = (void *) skb->data; 4406d5e91192SAndrei Emeltchenko struct hci_conn *hcon, *bredr_hcon; 4407d5e91192SAndrei Emeltchenko 4408d5e91192SAndrei Emeltchenko BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle, 4409d5e91192SAndrei Emeltchenko ev->status); 4410d5e91192SAndrei Emeltchenko 4411d5e91192SAndrei Emeltchenko hci_dev_lock(hdev); 4412d5e91192SAndrei Emeltchenko 4413d5e91192SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 4414d5e91192SAndrei Emeltchenko if (!hcon) { 4415d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 4416d5e91192SAndrei Emeltchenko return; 4417d5e91192SAndrei Emeltchenko } 4418d5e91192SAndrei Emeltchenko 4419d5e91192SAndrei Emeltchenko if (ev->status) { 4420d5e91192SAndrei Emeltchenko hci_conn_del(hcon); 4421d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 4422d5e91192SAndrei Emeltchenko return; 4423d5e91192SAndrei Emeltchenko } 4424d5e91192SAndrei Emeltchenko 4425d5e91192SAndrei Emeltchenko bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon; 4426d5e91192SAndrei Emeltchenko 4427d5e91192SAndrei Emeltchenko hcon->state = BT_CONNECTED; 4428d5e91192SAndrei Emeltchenko bacpy(&hcon->dst, &bredr_hcon->dst); 4429d5e91192SAndrei Emeltchenko 4430d5e91192SAndrei Emeltchenko hci_conn_hold(hcon); 4431d5e91192SAndrei Emeltchenko hcon->disc_timeout = HCI_DISCONN_TIMEOUT; 443276a68ba0SDavid Herrmann hci_conn_drop(hcon); 4433d5e91192SAndrei Emeltchenko 443423b9ceb7SMarcel Holtmann hci_debugfs_create_conn(hcon); 4435d5e91192SAndrei Emeltchenko hci_conn_add_sysfs(hcon); 4436d5e91192SAndrei Emeltchenko 4437cf70ff22SAndrei Emeltchenko amp_physical_cfm(bredr_hcon, hcon); 4438cf70ff22SAndrei Emeltchenko 4439d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 4440d5e91192SAndrei Emeltchenko } 4441d5e91192SAndrei Emeltchenko 444227695fb4SAndrei Emeltchenko static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 444327695fb4SAndrei Emeltchenko { 444427695fb4SAndrei Emeltchenko struct hci_ev_logical_link_complete *ev = (void *) skb->data; 444527695fb4SAndrei Emeltchenko struct hci_conn *hcon; 444627695fb4SAndrei Emeltchenko struct hci_chan *hchan; 444727695fb4SAndrei Emeltchenko struct amp_mgr *mgr; 444827695fb4SAndrei Emeltchenko 444927695fb4SAndrei Emeltchenko BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x", 445027695fb4SAndrei Emeltchenko hdev->name, le16_to_cpu(ev->handle), ev->phy_handle, 445127695fb4SAndrei Emeltchenko ev->status); 445227695fb4SAndrei Emeltchenko 445327695fb4SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 445427695fb4SAndrei Emeltchenko if (!hcon) 445527695fb4SAndrei Emeltchenko return; 445627695fb4SAndrei Emeltchenko 445727695fb4SAndrei Emeltchenko /* Create AMP hchan */ 445827695fb4SAndrei Emeltchenko hchan = hci_chan_create(hcon); 445927695fb4SAndrei Emeltchenko if (!hchan) 446027695fb4SAndrei Emeltchenko return; 446127695fb4SAndrei Emeltchenko 446227695fb4SAndrei Emeltchenko hchan->handle = le16_to_cpu(ev->handle); 446327695fb4SAndrei Emeltchenko 446427695fb4SAndrei Emeltchenko BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan); 446527695fb4SAndrei Emeltchenko 446627695fb4SAndrei Emeltchenko mgr = hcon->amp_mgr; 446727695fb4SAndrei Emeltchenko if (mgr && mgr->bredr_chan) { 446827695fb4SAndrei Emeltchenko struct l2cap_chan *bredr_chan = mgr->bredr_chan; 446927695fb4SAndrei Emeltchenko 447027695fb4SAndrei Emeltchenko l2cap_chan_lock(bredr_chan); 447127695fb4SAndrei Emeltchenko 447227695fb4SAndrei Emeltchenko bredr_chan->conn->mtu = hdev->block_mtu; 447327695fb4SAndrei Emeltchenko l2cap_logical_cfm(bredr_chan, hchan, 0); 447427695fb4SAndrei Emeltchenko hci_conn_hold(hcon); 447527695fb4SAndrei Emeltchenko 447627695fb4SAndrei Emeltchenko l2cap_chan_unlock(bredr_chan); 447727695fb4SAndrei Emeltchenko } 447827695fb4SAndrei Emeltchenko } 447927695fb4SAndrei Emeltchenko 4480606e2a10SAndrei Emeltchenko static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev, 4481606e2a10SAndrei Emeltchenko struct sk_buff *skb) 4482606e2a10SAndrei Emeltchenko { 4483606e2a10SAndrei Emeltchenko struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data; 4484606e2a10SAndrei Emeltchenko struct hci_chan *hchan; 4485606e2a10SAndrei Emeltchenko 4486606e2a10SAndrei Emeltchenko BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name, 4487606e2a10SAndrei Emeltchenko le16_to_cpu(ev->handle), ev->status); 4488606e2a10SAndrei Emeltchenko 4489606e2a10SAndrei Emeltchenko if (ev->status) 4490606e2a10SAndrei Emeltchenko return; 4491606e2a10SAndrei Emeltchenko 4492606e2a10SAndrei Emeltchenko hci_dev_lock(hdev); 4493606e2a10SAndrei Emeltchenko 4494606e2a10SAndrei Emeltchenko hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle)); 4495606e2a10SAndrei Emeltchenko if (!hchan) 4496606e2a10SAndrei Emeltchenko goto unlock; 4497606e2a10SAndrei Emeltchenko 4498606e2a10SAndrei Emeltchenko amp_destroy_logical_link(hchan, ev->reason); 4499606e2a10SAndrei Emeltchenko 4500606e2a10SAndrei Emeltchenko unlock: 4501606e2a10SAndrei Emeltchenko hci_dev_unlock(hdev); 4502606e2a10SAndrei Emeltchenko } 4503606e2a10SAndrei Emeltchenko 45049eef6b3aSAndrei Emeltchenko static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, 45059eef6b3aSAndrei Emeltchenko struct sk_buff *skb) 45069eef6b3aSAndrei Emeltchenko { 45079eef6b3aSAndrei Emeltchenko struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data; 45089eef6b3aSAndrei Emeltchenko struct hci_conn *hcon; 45099eef6b3aSAndrei Emeltchenko 45109eef6b3aSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 45119eef6b3aSAndrei Emeltchenko 45129eef6b3aSAndrei Emeltchenko if (ev->status) 45139eef6b3aSAndrei Emeltchenko return; 45149eef6b3aSAndrei Emeltchenko 45159eef6b3aSAndrei Emeltchenko hci_dev_lock(hdev); 45169eef6b3aSAndrei Emeltchenko 45179eef6b3aSAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 45189eef6b3aSAndrei Emeltchenko if (hcon) { 45199eef6b3aSAndrei Emeltchenko hcon->state = BT_CLOSED; 45209eef6b3aSAndrei Emeltchenko hci_conn_del(hcon); 45219eef6b3aSAndrei Emeltchenko } 45229eef6b3aSAndrei Emeltchenko 45239eef6b3aSAndrei Emeltchenko hci_dev_unlock(hdev); 45249eef6b3aSAndrei Emeltchenko } 45259eef6b3aSAndrei Emeltchenko 45266039aa73SGustavo Padovan static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 4527fcd89c09SVille Tervo { 4528fcd89c09SVille Tervo struct hci_ev_le_conn_complete *ev = (void *) skb->data; 4529912b42efSJohan Hedberg struct hci_conn_params *params; 4530fcd89c09SVille Tervo struct hci_conn *conn; 453168d6f6deSJohan Hedberg struct smp_irk *irk; 4532837d502eSJohan Hedberg u8 addr_type; 4533fcd89c09SVille Tervo 45349f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 4535fcd89c09SVille Tervo 4536fcd89c09SVille Tervo hci_dev_lock(hdev); 4537fcd89c09SVille Tervo 4538fbd96c15SJohan Hedberg /* All controllers implicitly stop advertising in the event of a 4539fbd96c15SJohan Hedberg * connection, so ensure that the state bit is cleared. 4540fbd96c15SJohan Hedberg */ 4541a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ADV); 4542fbd96c15SJohan Hedberg 45434f72b329SAndrzej Kaczmarek conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); 4544b62f328bSVille Tervo if (!conn) { 4545a5c4e309SJohan Hedberg conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr, ev->role); 4546b62f328bSVille Tervo if (!conn) { 4547b62f328bSVille Tervo BT_ERR("No memory for new connection"); 4548230fd16aSAndre Guedes goto unlock; 4549b62f328bSVille Tervo } 455029b7988aSAndre Guedes 455129b7988aSAndre Guedes conn->dst_type = ev->bdaddr_type; 4552b9b343d2SAndre Guedes 4553cb1d68f7SJohan Hedberg /* If we didn't have a hci_conn object previously 4554cb1d68f7SJohan Hedberg * but we're in master role this must be something 4555cb1d68f7SJohan Hedberg * initiated using a white list. Since white list based 4556cb1d68f7SJohan Hedberg * connections are not "first class citizens" we don't 4557cb1d68f7SJohan Hedberg * have full tracking of them. Therefore, we go ahead 4558cb1d68f7SJohan Hedberg * with a "best effort" approach of determining the 4559cb1d68f7SJohan Hedberg * initiator address based on the HCI_PRIVACY flag. 4560cb1d68f7SJohan Hedberg */ 4561cb1d68f7SJohan Hedberg if (conn->out) { 4562cb1d68f7SJohan Hedberg conn->resp_addr_type = ev->bdaddr_type; 4563cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &ev->bdaddr); 4564d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PRIVACY)) { 4565cb1d68f7SJohan Hedberg conn->init_addr_type = ADDR_LE_DEV_RANDOM; 4566cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->rpa); 4567cb1d68f7SJohan Hedberg } else { 4568cb1d68f7SJohan Hedberg hci_copy_identity_address(hdev, 4569cb1d68f7SJohan Hedberg &conn->init_addr, 4570cb1d68f7SJohan Hedberg &conn->init_addr_type); 4571cb1d68f7SJohan Hedberg } 457280c24ab8SJohan Hedberg } 4573cb1d68f7SJohan Hedberg } else { 457480c24ab8SJohan Hedberg cancel_delayed_work(&conn->le_conn_timeout); 457580c24ab8SJohan Hedberg } 457680c24ab8SJohan Hedberg 457780c24ab8SJohan Hedberg if (!conn->out) { 4578cb1d68f7SJohan Hedberg /* Set the responder (our side) address type based on 4579cb1d68f7SJohan Hedberg * the advertising address type. 4580cb1d68f7SJohan Hedberg */ 4581cb1d68f7SJohan Hedberg conn->resp_addr_type = hdev->adv_addr_type; 4582cb1d68f7SJohan Hedberg if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) 4583cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &hdev->random_addr); 4584cb1d68f7SJohan Hedberg else 4585cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &hdev->bdaddr); 4586cb1d68f7SJohan Hedberg 4587cb1d68f7SJohan Hedberg conn->init_addr_type = ev->bdaddr_type; 4588cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &ev->bdaddr); 4589a720d735SMarcel Holtmann 4590a720d735SMarcel Holtmann /* For incoming connections, set the default minimum 4591a720d735SMarcel Holtmann * and maximum connection interval. They will be used 4592a720d735SMarcel Holtmann * to check if the parameters are in range and if not 4593a720d735SMarcel Holtmann * trigger the connection update procedure. 4594a720d735SMarcel Holtmann */ 4595a720d735SMarcel Holtmann conn->le_conn_min_interval = hdev->le_conn_min_interval; 4596a720d735SMarcel Holtmann conn->le_conn_max_interval = hdev->le_conn_max_interval; 4597cb1d68f7SJohan Hedberg } 45987be2edbbSJohan Hedberg 4599edb4b466SMarcel Holtmann /* Lookup the identity address from the stored connection 4600edb4b466SMarcel Holtmann * address and address type. 4601edb4b466SMarcel Holtmann * 4602edb4b466SMarcel Holtmann * When establishing connections to an identity address, the 4603edb4b466SMarcel Holtmann * connection procedure will store the resolvable random 4604edb4b466SMarcel Holtmann * address first. Now if it can be converted back into the 4605edb4b466SMarcel Holtmann * identity address, start using the identity address from 4606edb4b466SMarcel Holtmann * now on. 4607edb4b466SMarcel Holtmann */ 4608edb4b466SMarcel Holtmann irk = hci_get_irk(hdev, &conn->dst, conn->dst_type); 460968d6f6deSJohan Hedberg if (irk) { 461068d6f6deSJohan Hedberg bacpy(&conn->dst, &irk->bdaddr); 461168d6f6deSJohan Hedberg conn->dst_type = irk->addr_type; 461268d6f6deSJohan Hedberg } 461368d6f6deSJohan Hedberg 46142d3c2260SJohan Hedberg if (ev->status) { 46152d3c2260SJohan Hedberg hci_le_conn_failed(conn, ev->status); 4616837d502eSJohan Hedberg goto unlock; 4617837d502eSJohan Hedberg } 4618837d502eSJohan Hedberg 461908853f18SJohan Hedberg if (conn->dst_type == ADDR_LE_DEV_PUBLIC) 462008853f18SJohan Hedberg addr_type = BDADDR_LE_PUBLIC; 462108853f18SJohan Hedberg else 462208853f18SJohan Hedberg addr_type = BDADDR_LE_RANDOM; 462308853f18SJohan Hedberg 46242d3c2260SJohan Hedberg /* Drop the connection if the device is blocked */ 46252d3c2260SJohan Hedberg if (hci_bdaddr_list_lookup(&hdev->blacklist, &conn->dst, addr_type)) { 46262d3c2260SJohan Hedberg hci_conn_drop(conn); 4627cd17decbSAndre Guedes goto unlock; 4628cd17decbSAndre Guedes } 4629cd17decbSAndre Guedes 4630b644ba33SJohan Hedberg if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 463148ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, NULL, 0); 463283bc71b4SVinicius Costa Gomes 46337b5c0d52SVinicius Costa Gomes conn->sec_level = BT_SECURITY_LOW; 4634fcd89c09SVille Tervo conn->handle = __le16_to_cpu(ev->handle); 46350fe29fd1SMarcel Holtmann conn->state = BT_CONFIG; 4636fcd89c09SVille Tervo 4637e04fde60SMarcel Holtmann conn->le_conn_interval = le16_to_cpu(ev->interval); 4638e04fde60SMarcel Holtmann conn->le_conn_latency = le16_to_cpu(ev->latency); 4639e04fde60SMarcel Holtmann conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout); 4640e04fde60SMarcel Holtmann 464123b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn); 4642fcd89c09SVille Tervo hci_conn_add_sysfs(conn); 4643fcd89c09SVille Tervo 46440fe29fd1SMarcel Holtmann if (!ev->status) { 46450fe29fd1SMarcel Holtmann /* The remote features procedure is defined for master 46460fe29fd1SMarcel Holtmann * role only. So only in case of an initiated connection 46470fe29fd1SMarcel Holtmann * request the remote features. 46480fe29fd1SMarcel Holtmann * 46490fe29fd1SMarcel Holtmann * If the local controller supports slave-initiated features 46500fe29fd1SMarcel Holtmann * exchange, then requesting the remote features in slave 46510fe29fd1SMarcel Holtmann * role is possible. Otherwise just transition into the 46520fe29fd1SMarcel Holtmann * connected state without requesting the remote features. 46530fe29fd1SMarcel Holtmann */ 46540fe29fd1SMarcel Holtmann if (conn->out || 46550fe29fd1SMarcel Holtmann (hdev->le_features[0] & HCI_LE_SLAVE_FEATURES)) { 46560fe29fd1SMarcel Holtmann struct hci_cp_le_read_remote_features cp; 46570fe29fd1SMarcel Holtmann 46580fe29fd1SMarcel Holtmann cp.handle = __cpu_to_le16(conn->handle); 46590fe29fd1SMarcel Holtmann 46600fe29fd1SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_LE_READ_REMOTE_FEATURES, 46610fe29fd1SMarcel Holtmann sizeof(cp), &cp); 46620fe29fd1SMarcel Holtmann 46630fe29fd1SMarcel Holtmann hci_conn_hold(conn); 46640fe29fd1SMarcel Holtmann } else { 46650fe29fd1SMarcel Holtmann conn->state = BT_CONNECTED; 4666539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 46670fe29fd1SMarcel Holtmann } 46680fe29fd1SMarcel Holtmann } else { 46690fe29fd1SMarcel Holtmann hci_connect_cfm(conn, ev->status); 46700fe29fd1SMarcel Holtmann } 4671fcd89c09SVille Tervo 46725477610fSJohan Hedberg params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst, 46735477610fSJohan Hedberg conn->dst_type); 4674f161dd41SJohan Hedberg if (params) { 467595305baaSJohan Hedberg list_del_init(¶ms->action); 4676f161dd41SJohan Hedberg if (params->conn) { 4677f161dd41SJohan Hedberg hci_conn_drop(params->conn); 4678f8aaf9b6SJohan Hedberg hci_conn_put(params->conn); 4679f161dd41SJohan Hedberg params->conn = NULL; 4680f161dd41SJohan Hedberg } 4681f161dd41SJohan Hedberg } 4682a4790dbdSAndre Guedes 4683fcd89c09SVille Tervo unlock: 4684223683a5SJohan Hedberg hci_update_background_scan(hdev); 4685fcd89c09SVille Tervo hci_dev_unlock(hdev); 4686fcd89c09SVille Tervo } 4687fcd89c09SVille Tervo 46881855d92dSMarcel Holtmann static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, 46891855d92dSMarcel Holtmann struct sk_buff *skb) 46901855d92dSMarcel Holtmann { 46911855d92dSMarcel Holtmann struct hci_ev_le_conn_update_complete *ev = (void *) skb->data; 46921855d92dSMarcel Holtmann struct hci_conn *conn; 46931855d92dSMarcel Holtmann 46941855d92dSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 46951855d92dSMarcel Holtmann 46961855d92dSMarcel Holtmann if (ev->status) 46971855d92dSMarcel Holtmann return; 46981855d92dSMarcel Holtmann 46991855d92dSMarcel Holtmann hci_dev_lock(hdev); 47001855d92dSMarcel Holtmann 47011855d92dSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 47021855d92dSMarcel Holtmann if (conn) { 47031855d92dSMarcel Holtmann conn->le_conn_interval = le16_to_cpu(ev->interval); 47041855d92dSMarcel Holtmann conn->le_conn_latency = le16_to_cpu(ev->latency); 47051855d92dSMarcel Holtmann conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout); 47061855d92dSMarcel Holtmann } 47071855d92dSMarcel Holtmann 47081855d92dSMarcel Holtmann hci_dev_unlock(hdev); 47091855d92dSMarcel Holtmann } 47101855d92dSMarcel Holtmann 4711a4790dbdSAndre Guedes /* This function requires the caller holds hdev->lock */ 4712fd45ada9SAlfonso Acosta static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev, 4713fd45ada9SAlfonso Acosta bdaddr_t *addr, 47141c1abcabSJohan Hedberg u8 addr_type, u8 adv_type) 4715a4790dbdSAndre Guedes { 4716a4790dbdSAndre Guedes struct hci_conn *conn; 47174b9e7e75SMarcel Holtmann struct hci_conn_params *params; 4718a4790dbdSAndre Guedes 47191c1abcabSJohan Hedberg /* If the event is not connectable don't proceed further */ 47201c1abcabSJohan Hedberg if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND) 4721fd45ada9SAlfonso Acosta return NULL; 47221c1abcabSJohan Hedberg 47231c1abcabSJohan Hedberg /* Ignore if the device is blocked */ 4724dcc36c16SJohan Hedberg if (hci_bdaddr_list_lookup(&hdev->blacklist, addr, addr_type)) 4725fd45ada9SAlfonso Acosta return NULL; 47261c1abcabSJohan Hedberg 4727f99353cfSJohan Hedberg /* Most controller will fail if we try to create new connections 4728f99353cfSJohan Hedberg * while we have an existing one in slave role. 4729f99353cfSJohan Hedberg */ 4730f99353cfSJohan Hedberg if (hdev->conn_hash.le_num_slave > 0) 4731fd45ada9SAlfonso Acosta return NULL; 4732f99353cfSJohan Hedberg 47331c1abcabSJohan Hedberg /* If we're not connectable only connect devices that we have in 47341c1abcabSJohan Hedberg * our pend_le_conns list. 47351c1abcabSJohan Hedberg */ 47364b9e7e75SMarcel Holtmann params = hci_pend_le_action_lookup(&hdev->pend_le_conns, 47374b9e7e75SMarcel Holtmann addr, addr_type); 47384b9e7e75SMarcel Holtmann if (!params) 4739fd45ada9SAlfonso Acosta return NULL; 4740a4790dbdSAndre Guedes 47414b9e7e75SMarcel Holtmann switch (params->auto_connect) { 47424b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_DIRECT: 47434b9e7e75SMarcel Holtmann /* Only devices advertising with ADV_DIRECT_IND are 47444b9e7e75SMarcel Holtmann * triggering a connection attempt. This is allowing 47454b9e7e75SMarcel Holtmann * incoming connections from slave devices. 47464b9e7e75SMarcel Holtmann */ 47474b9e7e75SMarcel Holtmann if (adv_type != LE_ADV_DIRECT_IND) 4748fd45ada9SAlfonso Acosta return NULL; 47494b9e7e75SMarcel Holtmann break; 47504b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_ALWAYS: 47514b9e7e75SMarcel Holtmann /* Devices advertising with ADV_IND or ADV_DIRECT_IND 47524b9e7e75SMarcel Holtmann * are triggering a connection attempt. This means 47534b9e7e75SMarcel Holtmann * that incoming connectioms from slave device are 47544b9e7e75SMarcel Holtmann * accepted and also outgoing connections to slave 47554b9e7e75SMarcel Holtmann * devices are established when found. 47564b9e7e75SMarcel Holtmann */ 47574b9e7e75SMarcel Holtmann break; 47584b9e7e75SMarcel Holtmann default: 4759fd45ada9SAlfonso Acosta return NULL; 47604b9e7e75SMarcel Holtmann } 47614b9e7e75SMarcel Holtmann 4762a4790dbdSAndre Guedes conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, 4763e804d25dSJohan Hedberg HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER); 4764f161dd41SJohan Hedberg if (!IS_ERR(conn)) { 4765f161dd41SJohan Hedberg /* Store the pointer since we don't really have any 4766f161dd41SJohan Hedberg * other owner of the object besides the params that 4767f161dd41SJohan Hedberg * triggered it. This way we can abort the connection if 4768f161dd41SJohan Hedberg * the parameters get removed and keep the reference 4769f161dd41SJohan Hedberg * count consistent once the connection is established. 4770f161dd41SJohan Hedberg */ 4771f8aaf9b6SJohan Hedberg params->conn = hci_conn_get(conn); 4772fd45ada9SAlfonso Acosta return conn; 4773f161dd41SJohan Hedberg } 4774a4790dbdSAndre Guedes 4775a4790dbdSAndre Guedes switch (PTR_ERR(conn)) { 4776a4790dbdSAndre Guedes case -EBUSY: 4777a4790dbdSAndre Guedes /* If hci_connect() returns -EBUSY it means there is already 4778a4790dbdSAndre Guedes * an LE connection attempt going on. Since controllers don't 4779a4790dbdSAndre Guedes * support more than one connection attempt at the time, we 4780a4790dbdSAndre Guedes * don't consider this an error case. 4781a4790dbdSAndre Guedes */ 4782a4790dbdSAndre Guedes break; 4783a4790dbdSAndre Guedes default: 4784a4790dbdSAndre Guedes BT_DBG("Failed to connect: err %ld", PTR_ERR(conn)); 4785fd45ada9SAlfonso Acosta return NULL; 4786a4790dbdSAndre Guedes } 4787fd45ada9SAlfonso Acosta 4788fd45ada9SAlfonso Acosta return NULL; 4789a4790dbdSAndre Guedes } 4790a4790dbdSAndre Guedes 47914af605d8SJohan Hedberg static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, 47922f010b55SMarcel Holtmann u8 bdaddr_type, bdaddr_t *direct_addr, 47932f010b55SMarcel Holtmann u8 direct_addr_type, s8 rssi, u8 *data, u8 len) 47944af605d8SJohan Hedberg { 4795b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 47961c1abcabSJohan Hedberg struct smp_irk *irk; 4797fd45ada9SAlfonso Acosta struct hci_conn *conn; 4798474ee066SJohan Hedberg bool match; 4799c70a7e4cSMarcel Holtmann u32 flags; 4800b9a6328fSJohan Hedberg 48012f010b55SMarcel Holtmann /* If the direct address is present, then this report is from 48022f010b55SMarcel Holtmann * a LE Direct Advertising Report event. In that case it is 48032f010b55SMarcel Holtmann * important to see if the address is matching the local 48042f010b55SMarcel Holtmann * controller address. 48052f010b55SMarcel Holtmann */ 48062f010b55SMarcel Holtmann if (direct_addr) { 48072f010b55SMarcel Holtmann /* Only resolvable random addresses are valid for these 48082f010b55SMarcel Holtmann * kind of reports and others can be ignored. 48092f010b55SMarcel Holtmann */ 48102f010b55SMarcel Holtmann if (!hci_bdaddr_is_rpa(direct_addr, direct_addr_type)) 48112f010b55SMarcel Holtmann return; 48122f010b55SMarcel Holtmann 48132f010b55SMarcel Holtmann /* If the controller is not using resolvable random 48142f010b55SMarcel Holtmann * addresses, then this report can be ignored. 48152f010b55SMarcel Holtmann */ 4816d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_PRIVACY)) 48172f010b55SMarcel Holtmann return; 48182f010b55SMarcel Holtmann 48192f010b55SMarcel Holtmann /* If the local IRK of the controller does not match 48202f010b55SMarcel Holtmann * with the resolvable random address provided, then 48212f010b55SMarcel Holtmann * this report can be ignored. 48222f010b55SMarcel Holtmann */ 48232f010b55SMarcel Holtmann if (!smp_irk_matches(hdev, hdev->irk, direct_addr)) 48242f010b55SMarcel Holtmann return; 48252f010b55SMarcel Holtmann } 48262f010b55SMarcel Holtmann 4827435a13d8SJohan Hedberg /* Check if we need to convert to identity address */ 4828435a13d8SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, bdaddr_type); 4829435a13d8SJohan Hedberg if (irk) { 4830435a13d8SJohan Hedberg bdaddr = &irk->bdaddr; 4831435a13d8SJohan Hedberg bdaddr_type = irk->addr_type; 4832435a13d8SJohan Hedberg } 4833435a13d8SJohan Hedberg 48341c1abcabSJohan Hedberg /* Check if we have been requested to connect to this device */ 4835fd45ada9SAlfonso Acosta conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, type); 4836fd45ada9SAlfonso Acosta if (conn && type == LE_ADV_IND) { 4837fd45ada9SAlfonso Acosta /* Store report for later inclusion by 4838fd45ada9SAlfonso Acosta * mgmt_device_connected 4839fd45ada9SAlfonso Acosta */ 4840fd45ada9SAlfonso Acosta memcpy(conn->le_adv_data, data, len); 4841fd45ada9SAlfonso Acosta conn->le_adv_data_len = len; 4842fd45ada9SAlfonso Acosta } 484399a6768eSJohan Hedberg 48441c1abcabSJohan Hedberg /* Passive scanning shouldn't trigger any device found events, 48451c1abcabSJohan Hedberg * except for devices marked as CONN_REPORT for which we do send 48461c1abcabSJohan Hedberg * device found events. 48471c1abcabSJohan Hedberg */ 48481c1abcabSJohan Hedberg if (hdev->le_scan_type == LE_SCAN_PASSIVE) { 48490d2bf134SJohan Hedberg if (type == LE_ADV_DIRECT_IND) 48500d2bf134SJohan Hedberg return; 48510d2bf134SJohan Hedberg 48523a19b6feSJohan Hedberg if (!hci_pend_le_action_lookup(&hdev->pend_le_reports, 48533a19b6feSJohan Hedberg bdaddr, bdaddr_type)) 48540d2bf134SJohan Hedberg return; 48550d2bf134SJohan Hedberg 48560d2bf134SJohan Hedberg if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND) 48570d2bf134SJohan Hedberg flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 48580d2bf134SJohan Hedberg else 48590d2bf134SJohan Hedberg flags = 0; 48600d2bf134SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 48610d2bf134SJohan Hedberg rssi, flags, data, len, NULL, 0); 486297bf2e99SJohan Hedberg return; 4863ca5c4be7SJohan Hedberg } 48644af605d8SJohan Hedberg 4865c70a7e4cSMarcel Holtmann /* When receiving non-connectable or scannable undirected 4866c70a7e4cSMarcel Holtmann * advertising reports, this means that the remote device is 4867c70a7e4cSMarcel Holtmann * not connectable and then clearly indicate this in the 4868c70a7e4cSMarcel Holtmann * device found event. 4869c70a7e4cSMarcel Holtmann * 4870c70a7e4cSMarcel Holtmann * When receiving a scan response, then there is no way to 4871c70a7e4cSMarcel Holtmann * know if the remote device is connectable or not. However 4872c70a7e4cSMarcel Holtmann * since scan responses are merged with a previously seen 4873c70a7e4cSMarcel Holtmann * advertising report, the flags field from that report 4874c70a7e4cSMarcel Holtmann * will be used. 4875c70a7e4cSMarcel Holtmann * 4876c70a7e4cSMarcel Holtmann * In the really unlikely case that a controller get confused 4877c70a7e4cSMarcel Holtmann * and just sends a scan response event, then it is marked as 4878c70a7e4cSMarcel Holtmann * not connectable as well. 4879c70a7e4cSMarcel Holtmann */ 4880c70a7e4cSMarcel Holtmann if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND || 4881c70a7e4cSMarcel Holtmann type == LE_ADV_SCAN_RSP) 4882c70a7e4cSMarcel Holtmann flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 4883c70a7e4cSMarcel Holtmann else 4884c70a7e4cSMarcel Holtmann flags = 0; 4885c70a7e4cSMarcel Holtmann 4886b9a6328fSJohan Hedberg /* If there's nothing pending either store the data from this 4887b9a6328fSJohan Hedberg * event or send an immediate device found event if the data 4888b9a6328fSJohan Hedberg * should not be stored for later. 4889b9a6328fSJohan Hedberg */ 4890b9a6328fSJohan Hedberg if (!has_pending_adv_report(hdev)) { 4891b9a6328fSJohan Hedberg /* If the report will trigger a SCAN_REQ store it for 4892b9a6328fSJohan Hedberg * later merging. 4893b9a6328fSJohan Hedberg */ 4894b9a6328fSJohan Hedberg if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { 4895b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type, 4896c70a7e4cSMarcel Holtmann rssi, flags, data, len); 4897b9a6328fSJohan Hedberg return; 4898b9a6328fSJohan Hedberg } 4899b9a6328fSJohan Hedberg 4900b9a6328fSJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 4901c70a7e4cSMarcel Holtmann rssi, flags, data, len, NULL, 0); 4902b9a6328fSJohan Hedberg return; 4903b9a6328fSJohan Hedberg } 4904b9a6328fSJohan Hedberg 4905474ee066SJohan Hedberg /* Check if the pending report is for the same device as the new one */ 4906474ee066SJohan Hedberg match = (!bacmp(bdaddr, &d->last_adv_addr) && 4907474ee066SJohan Hedberg bdaddr_type == d->last_adv_addr_type); 4908474ee066SJohan Hedberg 4909b9a6328fSJohan Hedberg /* If the pending data doesn't match this report or this isn't a 4910b9a6328fSJohan Hedberg * scan response (e.g. we got a duplicate ADV_IND) then force 4911b9a6328fSJohan Hedberg * sending of the pending data. 4912b9a6328fSJohan Hedberg */ 4913474ee066SJohan Hedberg if (type != LE_ADV_SCAN_RSP || !match) { 4914474ee066SJohan Hedberg /* Send out whatever is in the cache, but skip duplicates */ 4915474ee066SJohan Hedberg if (!match) 4916b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 4917ff5cd29fSJohan Hedberg d->last_adv_addr_type, NULL, 4918c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags, 4919ff5cd29fSJohan Hedberg d->last_adv_data, 4920474ee066SJohan Hedberg d->last_adv_data_len, NULL, 0); 4921b9a6328fSJohan Hedberg 4922b9a6328fSJohan Hedberg /* If the new report will trigger a SCAN_REQ store it for 4923b9a6328fSJohan Hedberg * later merging. 4924b9a6328fSJohan Hedberg */ 4925b9a6328fSJohan Hedberg if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { 4926b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type, 4927c70a7e4cSMarcel Holtmann rssi, flags, data, len); 4928b9a6328fSJohan Hedberg return; 4929b9a6328fSJohan Hedberg } 4930b9a6328fSJohan Hedberg 4931b9a6328fSJohan Hedberg /* The advertising reports cannot be merged, so clear 4932b9a6328fSJohan Hedberg * the pending report and send out a device found event. 4933b9a6328fSJohan Hedberg */ 4934b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 49355c5b93e4SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 4936c70a7e4cSMarcel Holtmann rssi, flags, data, len, NULL, 0); 4937b9a6328fSJohan Hedberg return; 4938b9a6328fSJohan Hedberg } 4939b9a6328fSJohan Hedberg 4940b9a6328fSJohan Hedberg /* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and 4941b9a6328fSJohan Hedberg * the new event is a SCAN_RSP. We can therefore proceed with 4942b9a6328fSJohan Hedberg * sending a merged device found event. 4943b9a6328fSJohan Hedberg */ 4944b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 4945c70a7e4cSMarcel Holtmann d->last_adv_addr_type, NULL, rssi, d->last_adv_flags, 494642bd6a56SMarcel Holtmann d->last_adv_data, d->last_adv_data_len, data, len); 4947b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 49484af605d8SJohan Hedberg } 49494af605d8SJohan Hedberg 49506039aa73SGustavo Padovan static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) 49519aa04c91SAndre Guedes { 4952e95beb41SAndre Guedes u8 num_reports = skb->data[0]; 4953e95beb41SAndre Guedes void *ptr = &skb->data[1]; 49549aa04c91SAndre Guedes 4955a4790dbdSAndre Guedes hci_dev_lock(hdev); 4956a4790dbdSAndre Guedes 4957e95beb41SAndre Guedes while (num_reports--) { 4958e95beb41SAndre Guedes struct hci_ev_le_advertising_info *ev = ptr; 49594af605d8SJohan Hedberg s8 rssi; 4960a4790dbdSAndre Guedes 49613c9e9195SAndre Guedes rssi = ev->data[ev->length]; 49624af605d8SJohan Hedberg process_adv_report(hdev, ev->evt_type, &ev->bdaddr, 49632f010b55SMarcel Holtmann ev->bdaddr_type, NULL, 0, rssi, 49642f010b55SMarcel Holtmann ev->data, ev->length); 49653c9e9195SAndre Guedes 4966e95beb41SAndre Guedes ptr += sizeof(*ev) + ev->length + 1; 49679aa04c91SAndre Guedes } 4968a4790dbdSAndre Guedes 4969a4790dbdSAndre Guedes hci_dev_unlock(hdev); 49709aa04c91SAndre Guedes } 49719aa04c91SAndre Guedes 49720fe29fd1SMarcel Holtmann static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev, 49730fe29fd1SMarcel Holtmann struct sk_buff *skb) 49740fe29fd1SMarcel Holtmann { 49750fe29fd1SMarcel Holtmann struct hci_ev_le_remote_feat_complete *ev = (void *)skb->data; 49760fe29fd1SMarcel Holtmann struct hci_conn *conn; 49770fe29fd1SMarcel Holtmann 49780fe29fd1SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 49790fe29fd1SMarcel Holtmann 49800fe29fd1SMarcel Holtmann hci_dev_lock(hdev); 49810fe29fd1SMarcel Holtmann 49820fe29fd1SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 49830fe29fd1SMarcel Holtmann if (conn) { 49840fe29fd1SMarcel Holtmann if (!ev->status) 49850fe29fd1SMarcel Holtmann memcpy(conn->features[0], ev->features, 8); 49860fe29fd1SMarcel Holtmann 49870fe29fd1SMarcel Holtmann if (conn->state == BT_CONFIG) { 49880fe29fd1SMarcel Holtmann __u8 status; 49890fe29fd1SMarcel Holtmann 49900fe29fd1SMarcel Holtmann /* If the local controller supports slave-initiated 49910fe29fd1SMarcel Holtmann * features exchange, but the remote controller does 49920fe29fd1SMarcel Holtmann * not, then it is possible that the error code 0x1a 49930fe29fd1SMarcel Holtmann * for unsupported remote feature gets returned. 49940fe29fd1SMarcel Holtmann * 49950fe29fd1SMarcel Holtmann * In this specific case, allow the connection to 49960fe29fd1SMarcel Holtmann * transition into connected state and mark it as 49970fe29fd1SMarcel Holtmann * successful. 49980fe29fd1SMarcel Holtmann */ 49990fe29fd1SMarcel Holtmann if ((hdev->le_features[0] & HCI_LE_SLAVE_FEATURES) && 50000fe29fd1SMarcel Holtmann !conn->out && ev->status == 0x1a) 50010fe29fd1SMarcel Holtmann status = 0x00; 50020fe29fd1SMarcel Holtmann else 50030fe29fd1SMarcel Holtmann status = ev->status; 50040fe29fd1SMarcel Holtmann 50050fe29fd1SMarcel Holtmann conn->state = BT_CONNECTED; 50060fe29fd1SMarcel Holtmann hci_connect_cfm(conn, status); 50070fe29fd1SMarcel Holtmann hci_conn_drop(conn); 50080fe29fd1SMarcel Holtmann } 50090fe29fd1SMarcel Holtmann } 50100fe29fd1SMarcel Holtmann 50110fe29fd1SMarcel Holtmann hci_dev_unlock(hdev); 50120fe29fd1SMarcel Holtmann } 50130fe29fd1SMarcel Holtmann 50146039aa73SGustavo Padovan static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 5015a7a595f6SVinicius Costa Gomes { 5016a7a595f6SVinicius Costa Gomes struct hci_ev_le_ltk_req *ev = (void *) skb->data; 5017a7a595f6SVinicius Costa Gomes struct hci_cp_le_ltk_reply cp; 5018bea710feSVinicius Costa Gomes struct hci_cp_le_ltk_neg_reply neg; 5019a7a595f6SVinicius Costa Gomes struct hci_conn *conn; 5020c9839a11SVinicius Costa Gomes struct smp_ltk *ltk; 5021a7a595f6SVinicius Costa Gomes 50229f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle)); 5023a7a595f6SVinicius Costa Gomes 5024a7a595f6SVinicius Costa Gomes hci_dev_lock(hdev); 5025a7a595f6SVinicius Costa Gomes 5026a7a595f6SVinicius Costa Gomes conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 5027bea710feSVinicius Costa Gomes if (conn == NULL) 5028bea710feSVinicius Costa Gomes goto not_found; 5029a7a595f6SVinicius Costa Gomes 5030f3a73d97SJohan Hedberg ltk = hci_find_ltk(hdev, &conn->dst, conn->dst_type, conn->role); 50315378bc56SJohan Hedberg if (!ltk) 5032bea710feSVinicius Costa Gomes goto not_found; 5033bea710feSVinicius Costa Gomes 50345378bc56SJohan Hedberg if (smp_ltk_is_sc(ltk)) { 50355378bc56SJohan Hedberg /* With SC both EDiv and Rand are set to zero */ 50365378bc56SJohan Hedberg if (ev->ediv || ev->rand) 50375378bc56SJohan Hedberg goto not_found; 50385378bc56SJohan Hedberg } else { 50395378bc56SJohan Hedberg /* For non-SC keys check that EDiv and Rand match */ 50405378bc56SJohan Hedberg if (ev->ediv != ltk->ediv || ev->rand != ltk->rand) 50415378bc56SJohan Hedberg goto not_found; 50425378bc56SJohan Hedberg } 50435378bc56SJohan Hedberg 50448b76ce34SJohan Hedberg memcpy(cp.ltk, ltk->val, ltk->enc_size); 50458b76ce34SJohan Hedberg memset(cp.ltk + ltk->enc_size, 0, sizeof(cp.ltk) - ltk->enc_size); 5046a7a595f6SVinicius Costa Gomes cp.handle = cpu_to_le16(conn->handle); 5047c9839a11SVinicius Costa Gomes 5048a6f7833cSJohan Hedberg conn->pending_sec_level = smp_ltk_sec_level(ltk); 5049a7a595f6SVinicius Costa Gomes 505089cbb4daSAndre Guedes conn->enc_key_size = ltk->enc_size; 5051a7a595f6SVinicius Costa Gomes 5052a7a595f6SVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); 5053a7a595f6SVinicius Costa Gomes 50545981a882SClaudio Takahasi /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a 50555981a882SClaudio Takahasi * temporary key used to encrypt a connection following 50565981a882SClaudio Takahasi * pairing. It is used during the Encrypted Session Setup to 50575981a882SClaudio Takahasi * distribute the keys. Later, security can be re-established 50585981a882SClaudio Takahasi * using a distributed LTK. 50595981a882SClaudio Takahasi */ 50602ceba539SJohan Hedberg if (ltk->type == SMP_STK) { 5061fe59a05fSJohan Hedberg set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); 5062970d0f1bSJohan Hedberg list_del_rcu(<k->list); 5063970d0f1bSJohan Hedberg kfree_rcu(ltk, rcu); 5064fe59a05fSJohan Hedberg } else { 5065fe59a05fSJohan Hedberg clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); 5066c9839a11SVinicius Costa Gomes } 5067c9839a11SVinicius Costa Gomes 5068a7a595f6SVinicius Costa Gomes hci_dev_unlock(hdev); 5069bea710feSVinicius Costa Gomes 5070bea710feSVinicius Costa Gomes return; 5071bea710feSVinicius Costa Gomes 5072bea710feSVinicius Costa Gomes not_found: 5073bea710feSVinicius Costa Gomes neg.handle = ev->handle; 5074bea710feSVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg); 5075bea710feSVinicius Costa Gomes hci_dev_unlock(hdev); 5076a7a595f6SVinicius Costa Gomes } 5077a7a595f6SVinicius Costa Gomes 50788e75b46aSAndre Guedes static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle, 50798e75b46aSAndre Guedes u8 reason) 50808e75b46aSAndre Guedes { 50818e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_neg_reply cp; 50828e75b46aSAndre Guedes 50838e75b46aSAndre Guedes cp.handle = cpu_to_le16(handle); 50848e75b46aSAndre Guedes cp.reason = reason; 50858e75b46aSAndre Guedes 50868e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp), 50878e75b46aSAndre Guedes &cp); 50888e75b46aSAndre Guedes } 50898e75b46aSAndre Guedes 50908e75b46aSAndre Guedes static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, 50918e75b46aSAndre Guedes struct sk_buff *skb) 50928e75b46aSAndre Guedes { 50938e75b46aSAndre Guedes struct hci_ev_le_remote_conn_param_req *ev = (void *) skb->data; 50948e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_reply cp; 50958e75b46aSAndre Guedes struct hci_conn *hcon; 50968e75b46aSAndre Guedes u16 handle, min, max, latency, timeout; 50978e75b46aSAndre Guedes 50988e75b46aSAndre Guedes handle = le16_to_cpu(ev->handle); 50998e75b46aSAndre Guedes min = le16_to_cpu(ev->interval_min); 51008e75b46aSAndre Guedes max = le16_to_cpu(ev->interval_max); 51018e75b46aSAndre Guedes latency = le16_to_cpu(ev->latency); 51028e75b46aSAndre Guedes timeout = le16_to_cpu(ev->timeout); 51038e75b46aSAndre Guedes 51048e75b46aSAndre Guedes hcon = hci_conn_hash_lookup_handle(hdev, handle); 51058e75b46aSAndre Guedes if (!hcon || hcon->state != BT_CONNECTED) 51068e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle, 51078e75b46aSAndre Guedes HCI_ERROR_UNKNOWN_CONN_ID); 51088e75b46aSAndre Guedes 51098e75b46aSAndre Guedes if (hci_check_conn_params(min, max, latency, timeout)) 51108e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle, 51118e75b46aSAndre Guedes HCI_ERROR_INVALID_LL_PARAMS); 51128e75b46aSAndre Guedes 511340bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) { 5114348d50b8SJohan Hedberg struct hci_conn_params *params; 5115f4869e2aSJohan Hedberg u8 store_hint; 5116348d50b8SJohan Hedberg 5117348d50b8SJohan Hedberg hci_dev_lock(hdev); 5118348d50b8SJohan Hedberg 5119348d50b8SJohan Hedberg params = hci_conn_params_lookup(hdev, &hcon->dst, 5120348d50b8SJohan Hedberg hcon->dst_type); 5121348d50b8SJohan Hedberg if (params) { 5122348d50b8SJohan Hedberg params->conn_min_interval = min; 5123348d50b8SJohan Hedberg params->conn_max_interval = max; 5124348d50b8SJohan Hedberg params->conn_latency = latency; 5125348d50b8SJohan Hedberg params->supervision_timeout = timeout; 5126f4869e2aSJohan Hedberg store_hint = 0x01; 5127f4869e2aSJohan Hedberg } else{ 5128f4869e2aSJohan Hedberg store_hint = 0x00; 5129348d50b8SJohan Hedberg } 5130348d50b8SJohan Hedberg 5131348d50b8SJohan Hedberg hci_dev_unlock(hdev); 5132348d50b8SJohan Hedberg 5133f4869e2aSJohan Hedberg mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type, 5134f4869e2aSJohan Hedberg store_hint, min, max, latency, timeout); 5135348d50b8SJohan Hedberg } 5136ffb5a827SAndre Guedes 51378e75b46aSAndre Guedes cp.handle = ev->handle; 51388e75b46aSAndre Guedes cp.interval_min = ev->interval_min; 51398e75b46aSAndre Guedes cp.interval_max = ev->interval_max; 51408e75b46aSAndre Guedes cp.latency = ev->latency; 51418e75b46aSAndre Guedes cp.timeout = ev->timeout; 51428e75b46aSAndre Guedes cp.min_ce_len = 0; 51438e75b46aSAndre Guedes cp.max_ce_len = 0; 51448e75b46aSAndre Guedes 51458e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp); 51468e75b46aSAndre Guedes } 51478e75b46aSAndre Guedes 51482f010b55SMarcel Holtmann static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, 51492f010b55SMarcel Holtmann struct sk_buff *skb) 51502f010b55SMarcel Holtmann { 51512f010b55SMarcel Holtmann u8 num_reports = skb->data[0]; 51522f010b55SMarcel Holtmann void *ptr = &skb->data[1]; 51532f010b55SMarcel Holtmann 51542f010b55SMarcel Holtmann hci_dev_lock(hdev); 51552f010b55SMarcel Holtmann 51562f010b55SMarcel Holtmann while (num_reports--) { 51572f010b55SMarcel Holtmann struct hci_ev_le_direct_adv_info *ev = ptr; 51582f010b55SMarcel Holtmann 51592f010b55SMarcel Holtmann process_adv_report(hdev, ev->evt_type, &ev->bdaddr, 51602f010b55SMarcel Holtmann ev->bdaddr_type, &ev->direct_addr, 51612f010b55SMarcel Holtmann ev->direct_addr_type, ev->rssi, NULL, 0); 51622f010b55SMarcel Holtmann 51632f010b55SMarcel Holtmann ptr += sizeof(*ev); 51642f010b55SMarcel Holtmann } 51652f010b55SMarcel Holtmann 51662f010b55SMarcel Holtmann hci_dev_unlock(hdev); 51672f010b55SMarcel Holtmann } 51682f010b55SMarcel Holtmann 51696039aa73SGustavo Padovan static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) 5170fcd89c09SVille Tervo { 5171fcd89c09SVille Tervo struct hci_ev_le_meta *le_ev = (void *) skb->data; 5172fcd89c09SVille Tervo 5173fcd89c09SVille Tervo skb_pull(skb, sizeof(*le_ev)); 5174fcd89c09SVille Tervo 5175fcd89c09SVille Tervo switch (le_ev->subevent) { 5176fcd89c09SVille Tervo case HCI_EV_LE_CONN_COMPLETE: 5177fcd89c09SVille Tervo hci_le_conn_complete_evt(hdev, skb); 5178fcd89c09SVille Tervo break; 5179fcd89c09SVille Tervo 51801855d92dSMarcel Holtmann case HCI_EV_LE_CONN_UPDATE_COMPLETE: 51811855d92dSMarcel Holtmann hci_le_conn_update_complete_evt(hdev, skb); 51821855d92dSMarcel Holtmann break; 51831855d92dSMarcel Holtmann 51849aa04c91SAndre Guedes case HCI_EV_LE_ADVERTISING_REPORT: 51859aa04c91SAndre Guedes hci_le_adv_report_evt(hdev, skb); 51869aa04c91SAndre Guedes break; 51879aa04c91SAndre Guedes 51880fe29fd1SMarcel Holtmann case HCI_EV_LE_REMOTE_FEAT_COMPLETE: 51890fe29fd1SMarcel Holtmann hci_le_remote_feat_complete_evt(hdev, skb); 51900fe29fd1SMarcel Holtmann break; 51910fe29fd1SMarcel Holtmann 5192a7a595f6SVinicius Costa Gomes case HCI_EV_LE_LTK_REQ: 5193a7a595f6SVinicius Costa Gomes hci_le_ltk_request_evt(hdev, skb); 5194a7a595f6SVinicius Costa Gomes break; 5195a7a595f6SVinicius Costa Gomes 51968e75b46aSAndre Guedes case HCI_EV_LE_REMOTE_CONN_PARAM_REQ: 51978e75b46aSAndre Guedes hci_le_remote_conn_param_req_evt(hdev, skb); 51988e75b46aSAndre Guedes break; 51998e75b46aSAndre Guedes 52002f010b55SMarcel Holtmann case HCI_EV_LE_DIRECT_ADV_REPORT: 52012f010b55SMarcel Holtmann hci_le_direct_adv_report_evt(hdev, skb); 52022f010b55SMarcel Holtmann break; 52032f010b55SMarcel Holtmann 5204fcd89c09SVille Tervo default: 5205fcd89c09SVille Tervo break; 5206fcd89c09SVille Tervo } 5207fcd89c09SVille Tervo } 5208fcd89c09SVille Tervo 52099495b2eeSAndrei Emeltchenko static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb) 52109495b2eeSAndrei Emeltchenko { 52119495b2eeSAndrei Emeltchenko struct hci_ev_channel_selected *ev = (void *) skb->data; 52129495b2eeSAndrei Emeltchenko struct hci_conn *hcon; 52139495b2eeSAndrei Emeltchenko 52149495b2eeSAndrei Emeltchenko BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle); 52159495b2eeSAndrei Emeltchenko 52169495b2eeSAndrei Emeltchenko skb_pull(skb, sizeof(*ev)); 52179495b2eeSAndrei Emeltchenko 52189495b2eeSAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 52199495b2eeSAndrei Emeltchenko if (!hcon) 52209495b2eeSAndrei Emeltchenko return; 52219495b2eeSAndrei Emeltchenko 52229495b2eeSAndrei Emeltchenko amp_read_loc_assoc_final_data(hdev, hcon); 52239495b2eeSAndrei Emeltchenko } 52249495b2eeSAndrei Emeltchenko 5225757aa0b5SJohan Hedberg static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 5226757aa0b5SJohan Hedberg u8 event, struct sk_buff *skb) 5227757aa0b5SJohan Hedberg { 5228757aa0b5SJohan Hedberg struct hci_ev_cmd_complete *ev; 5229757aa0b5SJohan Hedberg struct hci_event_hdr *hdr; 5230757aa0b5SJohan Hedberg 5231757aa0b5SJohan Hedberg if (!skb) 5232757aa0b5SJohan Hedberg return false; 5233757aa0b5SJohan Hedberg 5234757aa0b5SJohan Hedberg if (skb->len < sizeof(*hdr)) { 5235757aa0b5SJohan Hedberg BT_ERR("Too short HCI event"); 5236757aa0b5SJohan Hedberg return false; 5237757aa0b5SJohan Hedberg } 5238757aa0b5SJohan Hedberg 5239757aa0b5SJohan Hedberg hdr = (void *) skb->data; 5240757aa0b5SJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 5241757aa0b5SJohan Hedberg 5242757aa0b5SJohan Hedberg if (event) { 5243757aa0b5SJohan Hedberg if (hdr->evt != event) 5244757aa0b5SJohan Hedberg return false; 5245757aa0b5SJohan Hedberg return true; 5246757aa0b5SJohan Hedberg } 5247757aa0b5SJohan Hedberg 5248757aa0b5SJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 5249757aa0b5SJohan Hedberg BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); 5250757aa0b5SJohan Hedberg return false; 5251757aa0b5SJohan Hedberg } 5252757aa0b5SJohan Hedberg 5253757aa0b5SJohan Hedberg if (skb->len < sizeof(*ev)) { 5254757aa0b5SJohan Hedberg BT_ERR("Too short cmd_complete event"); 5255757aa0b5SJohan Hedberg return false; 5256757aa0b5SJohan Hedberg } 5257757aa0b5SJohan Hedberg 5258757aa0b5SJohan Hedberg ev = (void *) skb->data; 5259757aa0b5SJohan Hedberg skb_pull(skb, sizeof(*ev)); 5260757aa0b5SJohan Hedberg 5261757aa0b5SJohan Hedberg if (opcode != __le16_to_cpu(ev->opcode)) { 5262757aa0b5SJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 5263757aa0b5SJohan Hedberg __le16_to_cpu(ev->opcode)); 5264757aa0b5SJohan Hedberg return false; 5265757aa0b5SJohan Hedberg } 5266757aa0b5SJohan Hedberg 5267757aa0b5SJohan Hedberg return true; 5268757aa0b5SJohan Hedberg } 5269757aa0b5SJohan Hedberg 52701da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) 52711da177e4SLinus Torvalds { 5272a9de9248SMarcel Holtmann struct hci_event_hdr *hdr = (void *) skb->data; 5273e6214487SJohan Hedberg hci_req_complete_t req_complete = NULL; 5274e6214487SJohan Hedberg hci_req_complete_skb_t req_complete_skb = NULL; 5275e6214487SJohan Hedberg struct sk_buff *orig_skb = NULL; 5276757aa0b5SJohan Hedberg u8 status = 0, event = hdr->evt, req_evt = 0; 5277e6214487SJohan Hedberg u16 opcode = HCI_OP_NOP; 52781da177e4SLinus Torvalds 5279db6e3e8dSJohan Hedberg if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) { 5280c1f23a2bSJohannes Berg struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data; 5281e6214487SJohan Hedberg opcode = __le16_to_cpu(cmd_hdr->opcode); 5282e6214487SJohan Hedberg hci_req_cmd_complete(hdev, opcode, status, &req_complete, 5283e6214487SJohan Hedberg &req_complete_skb); 5284757aa0b5SJohan Hedberg req_evt = event; 528502350a72SJohan Hedberg } 528602350a72SJohan Hedberg 5287e6214487SJohan Hedberg /* If it looks like we might end up having to call 5288e6214487SJohan Hedberg * req_complete_skb, store a pristine copy of the skb since the 5289e6214487SJohan Hedberg * various handlers may modify the original one through 5290e6214487SJohan Hedberg * skb_pull() calls, etc. 5291e6214487SJohan Hedberg */ 5292e6214487SJohan Hedberg if (req_complete_skb || event == HCI_EV_CMD_STATUS || 5293e6214487SJohan Hedberg event == HCI_EV_CMD_COMPLETE) 5294e6214487SJohan Hedberg orig_skb = skb_clone(skb, GFP_KERNEL); 5295e6214487SJohan Hedberg 5296e6214487SJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 5297e6214487SJohan Hedberg 5298a9de9248SMarcel Holtmann switch (event) { 52991da177e4SLinus Torvalds case HCI_EV_INQUIRY_COMPLETE: 53001da177e4SLinus Torvalds hci_inquiry_complete_evt(hdev, skb); 53011da177e4SLinus Torvalds break; 53021da177e4SLinus Torvalds 53031da177e4SLinus Torvalds case HCI_EV_INQUIRY_RESULT: 53041da177e4SLinus Torvalds hci_inquiry_result_evt(hdev, skb); 53051da177e4SLinus Torvalds break; 53061da177e4SLinus Torvalds 5307a9de9248SMarcel Holtmann case HCI_EV_CONN_COMPLETE: 5308a9de9248SMarcel Holtmann hci_conn_complete_evt(hdev, skb); 530921d9e30eSMarcel Holtmann break; 531021d9e30eSMarcel Holtmann 53111da177e4SLinus Torvalds case HCI_EV_CONN_REQUEST: 53121da177e4SLinus Torvalds hci_conn_request_evt(hdev, skb); 53131da177e4SLinus Torvalds break; 53141da177e4SLinus Torvalds 53151da177e4SLinus Torvalds case HCI_EV_DISCONN_COMPLETE: 53161da177e4SLinus Torvalds hci_disconn_complete_evt(hdev, skb); 53171da177e4SLinus Torvalds break; 53181da177e4SLinus Torvalds 53191da177e4SLinus Torvalds case HCI_EV_AUTH_COMPLETE: 53201da177e4SLinus Torvalds hci_auth_complete_evt(hdev, skb); 53211da177e4SLinus Torvalds break; 53221da177e4SLinus Torvalds 5323a9de9248SMarcel Holtmann case HCI_EV_REMOTE_NAME: 5324a9de9248SMarcel Holtmann hci_remote_name_evt(hdev, skb); 5325a9de9248SMarcel Holtmann break; 5326a9de9248SMarcel Holtmann 53271da177e4SLinus Torvalds case HCI_EV_ENCRYPT_CHANGE: 53281da177e4SLinus Torvalds hci_encrypt_change_evt(hdev, skb); 53291da177e4SLinus Torvalds break; 53301da177e4SLinus Torvalds 5331a9de9248SMarcel Holtmann case HCI_EV_CHANGE_LINK_KEY_COMPLETE: 5332a9de9248SMarcel Holtmann hci_change_link_key_complete_evt(hdev, skb); 5333a9de9248SMarcel Holtmann break; 5334a9de9248SMarcel Holtmann 5335a9de9248SMarcel Holtmann case HCI_EV_REMOTE_FEATURES: 5336a9de9248SMarcel Holtmann hci_remote_features_evt(hdev, skb); 5337a9de9248SMarcel Holtmann break; 5338a9de9248SMarcel Holtmann 5339a9de9248SMarcel Holtmann case HCI_EV_CMD_COMPLETE: 5340e6214487SJohan Hedberg hci_cmd_complete_evt(hdev, skb, &opcode, &status, 5341e6214487SJohan Hedberg &req_complete, &req_complete_skb); 5342a9de9248SMarcel Holtmann break; 5343a9de9248SMarcel Holtmann 5344a9de9248SMarcel Holtmann case HCI_EV_CMD_STATUS: 5345e6214487SJohan Hedberg hci_cmd_status_evt(hdev, skb, &opcode, &status, &req_complete, 5346e6214487SJohan Hedberg &req_complete_skb); 5347a9de9248SMarcel Holtmann break; 5348a9de9248SMarcel Holtmann 534924dfa343SMarcel Holtmann case HCI_EV_HARDWARE_ERROR: 535024dfa343SMarcel Holtmann hci_hardware_error_evt(hdev, skb); 535124dfa343SMarcel Holtmann break; 535224dfa343SMarcel Holtmann 5353a9de9248SMarcel Holtmann case HCI_EV_ROLE_CHANGE: 5354a9de9248SMarcel Holtmann hci_role_change_evt(hdev, skb); 5355a9de9248SMarcel Holtmann break; 5356a9de9248SMarcel Holtmann 5357a9de9248SMarcel Holtmann case HCI_EV_NUM_COMP_PKTS: 5358a9de9248SMarcel Holtmann hci_num_comp_pkts_evt(hdev, skb); 5359a9de9248SMarcel Holtmann break; 5360a9de9248SMarcel Holtmann 5361a9de9248SMarcel Holtmann case HCI_EV_MODE_CHANGE: 5362a9de9248SMarcel Holtmann hci_mode_change_evt(hdev, skb); 53631da177e4SLinus Torvalds break; 53641da177e4SLinus Torvalds 53651da177e4SLinus Torvalds case HCI_EV_PIN_CODE_REQ: 53661da177e4SLinus Torvalds hci_pin_code_request_evt(hdev, skb); 53671da177e4SLinus Torvalds break; 53681da177e4SLinus Torvalds 53691da177e4SLinus Torvalds case HCI_EV_LINK_KEY_REQ: 53701da177e4SLinus Torvalds hci_link_key_request_evt(hdev, skb); 53711da177e4SLinus Torvalds break; 53721da177e4SLinus Torvalds 53731da177e4SLinus Torvalds case HCI_EV_LINK_KEY_NOTIFY: 53741da177e4SLinus Torvalds hci_link_key_notify_evt(hdev, skb); 53751da177e4SLinus Torvalds break; 53761da177e4SLinus Torvalds 53771da177e4SLinus Torvalds case HCI_EV_CLOCK_OFFSET: 53781da177e4SLinus Torvalds hci_clock_offset_evt(hdev, skb); 53791da177e4SLinus Torvalds break; 53801da177e4SLinus Torvalds 5381a8746417SMarcel Holtmann case HCI_EV_PKT_TYPE_CHANGE: 5382a8746417SMarcel Holtmann hci_pkt_type_change_evt(hdev, skb); 5383a8746417SMarcel Holtmann break; 5384a8746417SMarcel Holtmann 538585a1e930SMarcel Holtmann case HCI_EV_PSCAN_REP_MODE: 538685a1e930SMarcel Holtmann hci_pscan_rep_mode_evt(hdev, skb); 538785a1e930SMarcel Holtmann break; 538885a1e930SMarcel Holtmann 5389a9de9248SMarcel Holtmann case HCI_EV_INQUIRY_RESULT_WITH_RSSI: 5390a9de9248SMarcel Holtmann hci_inquiry_result_with_rssi_evt(hdev, skb); 5391a9de9248SMarcel Holtmann break; 5392a9de9248SMarcel Holtmann 5393a9de9248SMarcel Holtmann case HCI_EV_REMOTE_EXT_FEATURES: 5394a9de9248SMarcel Holtmann hci_remote_ext_features_evt(hdev, skb); 5395a9de9248SMarcel Holtmann break; 5396a9de9248SMarcel Holtmann 5397a9de9248SMarcel Holtmann case HCI_EV_SYNC_CONN_COMPLETE: 5398a9de9248SMarcel Holtmann hci_sync_conn_complete_evt(hdev, skb); 5399a9de9248SMarcel Holtmann break; 5400a9de9248SMarcel Holtmann 5401a9de9248SMarcel Holtmann case HCI_EV_EXTENDED_INQUIRY_RESULT: 5402a9de9248SMarcel Holtmann hci_extended_inquiry_result_evt(hdev, skb); 54031da177e4SLinus Torvalds break; 54041da177e4SLinus Torvalds 54051c2e0041SJohan Hedberg case HCI_EV_KEY_REFRESH_COMPLETE: 54061c2e0041SJohan Hedberg hci_key_refresh_complete_evt(hdev, skb); 54071c2e0041SJohan Hedberg break; 54081c2e0041SJohan Hedberg 54090493684eSMarcel Holtmann case HCI_EV_IO_CAPA_REQUEST: 54100493684eSMarcel Holtmann hci_io_capa_request_evt(hdev, skb); 54110493684eSMarcel Holtmann break; 54120493684eSMarcel Holtmann 541303b555e1SJohan Hedberg case HCI_EV_IO_CAPA_REPLY: 541403b555e1SJohan Hedberg hci_io_capa_reply_evt(hdev, skb); 541503b555e1SJohan Hedberg break; 541603b555e1SJohan Hedberg 5417a5c29683SJohan Hedberg case HCI_EV_USER_CONFIRM_REQUEST: 5418a5c29683SJohan Hedberg hci_user_confirm_request_evt(hdev, skb); 5419a5c29683SJohan Hedberg break; 5420a5c29683SJohan Hedberg 54211143d458SBrian Gix case HCI_EV_USER_PASSKEY_REQUEST: 54221143d458SBrian Gix hci_user_passkey_request_evt(hdev, skb); 54231143d458SBrian Gix break; 54241143d458SBrian Gix 542592a25256SJohan Hedberg case HCI_EV_USER_PASSKEY_NOTIFY: 542692a25256SJohan Hedberg hci_user_passkey_notify_evt(hdev, skb); 542792a25256SJohan Hedberg break; 542892a25256SJohan Hedberg 542992a25256SJohan Hedberg case HCI_EV_KEYPRESS_NOTIFY: 543092a25256SJohan Hedberg hci_keypress_notify_evt(hdev, skb); 543192a25256SJohan Hedberg break; 543292a25256SJohan Hedberg 54330493684eSMarcel Holtmann case HCI_EV_SIMPLE_PAIR_COMPLETE: 54340493684eSMarcel Holtmann hci_simple_pair_complete_evt(hdev, skb); 54350493684eSMarcel Holtmann break; 54360493684eSMarcel Holtmann 543741a96212SMarcel Holtmann case HCI_EV_REMOTE_HOST_FEATURES: 543841a96212SMarcel Holtmann hci_remote_host_features_evt(hdev, skb); 543941a96212SMarcel Holtmann break; 544041a96212SMarcel Holtmann 5441fcd89c09SVille Tervo case HCI_EV_LE_META: 5442fcd89c09SVille Tervo hci_le_meta_evt(hdev, skb); 5443fcd89c09SVille Tervo break; 5444fcd89c09SVille Tervo 54459495b2eeSAndrei Emeltchenko case HCI_EV_CHANNEL_SELECTED: 54469495b2eeSAndrei Emeltchenko hci_chan_selected_evt(hdev, skb); 54479495b2eeSAndrei Emeltchenko break; 54489495b2eeSAndrei Emeltchenko 54492763eda6SSzymon Janc case HCI_EV_REMOTE_OOB_DATA_REQUEST: 54502763eda6SSzymon Janc hci_remote_oob_data_request_evt(hdev, skb); 54512763eda6SSzymon Janc break; 54522763eda6SSzymon Janc 5453d5e91192SAndrei Emeltchenko case HCI_EV_PHY_LINK_COMPLETE: 5454d5e91192SAndrei Emeltchenko hci_phy_link_complete_evt(hdev, skb); 5455d5e91192SAndrei Emeltchenko break; 5456d5e91192SAndrei Emeltchenko 545727695fb4SAndrei Emeltchenko case HCI_EV_LOGICAL_LINK_COMPLETE: 545827695fb4SAndrei Emeltchenko hci_loglink_complete_evt(hdev, skb); 545927695fb4SAndrei Emeltchenko break; 546027695fb4SAndrei Emeltchenko 5461606e2a10SAndrei Emeltchenko case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE: 5462606e2a10SAndrei Emeltchenko hci_disconn_loglink_complete_evt(hdev, skb); 5463606e2a10SAndrei Emeltchenko break; 5464606e2a10SAndrei Emeltchenko 54659eef6b3aSAndrei Emeltchenko case HCI_EV_DISCONN_PHY_LINK_COMPLETE: 54669eef6b3aSAndrei Emeltchenko hci_disconn_phylink_complete_evt(hdev, skb); 54679eef6b3aSAndrei Emeltchenko break; 54689eef6b3aSAndrei Emeltchenko 546925e89e99SAndrei Emeltchenko case HCI_EV_NUM_COMP_BLOCKS: 547025e89e99SAndrei Emeltchenko hci_num_comp_blocks_evt(hdev, skb); 547125e89e99SAndrei Emeltchenko break; 547225e89e99SAndrei Emeltchenko 54731da177e4SLinus Torvalds default: 54749f1db00cSAndrei Emeltchenko BT_DBG("%s event 0x%2.2x", hdev->name, event); 54751da177e4SLinus Torvalds break; 54761da177e4SLinus Torvalds } 54771da177e4SLinus Torvalds 5478757aa0b5SJohan Hedberg if (req_complete) { 5479e6214487SJohan Hedberg req_complete(hdev, status, opcode); 5480757aa0b5SJohan Hedberg } else if (req_complete_skb) { 5481757aa0b5SJohan Hedberg if (!hci_get_cmd_complete(hdev, opcode, req_evt, orig_skb)) { 5482757aa0b5SJohan Hedberg kfree_skb(orig_skb); 5483757aa0b5SJohan Hedberg orig_skb = NULL; 5484757aa0b5SJohan Hedberg } 5485e6214487SJohan Hedberg req_complete_skb(hdev, status, opcode, orig_skb); 5486757aa0b5SJohan Hedberg } 5487e6214487SJohan Hedberg 5488e6214487SJohan Hedberg kfree_skb(orig_skb); 54891da177e4SLinus Torvalds kfree_skb(skb); 54901da177e4SLinus Torvalds hdev->stat.evt_rx++; 54911da177e4SLinus Torvalds } 5492