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); 58168b8a25SJakub Pawlowski /* Set discovery state to stopped if we're not doing LE active 59168b8a25SJakub Pawlowski * scanning. 60168b8a25SJakub Pawlowski */ 61168b8a25SJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) || 62168b8a25SJakub Pawlowski hdev->le_scan_type != LE_SCAN_ACTIVE) 6350143a43SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 6450143a43SJohan Hedberg hci_dev_unlock(hdev); 6550143a43SJohan Hedberg 66a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 671da177e4SLinus Torvalds } 686bd57416SMarcel Holtmann 694d93483bSAndre Guedes static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) 704d93483bSAndre Guedes { 714d93483bSAndre Guedes __u8 status = *((__u8 *) skb->data); 724d93483bSAndre Guedes 739f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 74ae854a70SAndre Guedes 75ae854a70SAndre Guedes if (status) 76ae854a70SAndre Guedes return; 77ae854a70SAndre Guedes 78a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_PERIODIC_INQ); 794d93483bSAndre Guedes } 804d93483bSAndre Guedes 81a9de9248SMarcel Holtmann static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) 821da177e4SLinus Torvalds { 83a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 84a9de9248SMarcel Holtmann 859f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 86a9de9248SMarcel Holtmann 87a9de9248SMarcel Holtmann if (status) 88a9de9248SMarcel Holtmann return; 89a9de9248SMarcel Holtmann 90a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ); 91ae854a70SAndre Guedes 92a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 93a9de9248SMarcel Holtmann } 94a9de9248SMarcel Holtmann 95807deac2SGustavo Padovan static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, 96807deac2SGustavo Padovan struct sk_buff *skb) 97a9de9248SMarcel Holtmann { 98a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 99a9de9248SMarcel Holtmann } 100a9de9248SMarcel Holtmann 101a9de9248SMarcel Holtmann static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb) 102a9de9248SMarcel Holtmann { 103a9de9248SMarcel Holtmann struct hci_rp_role_discovery *rp = (void *) skb->data; 1041da177e4SLinus Torvalds struct hci_conn *conn; 1051da177e4SLinus Torvalds 1069f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 1071da177e4SLinus Torvalds 108a9de9248SMarcel Holtmann if (rp->status) 109a9de9248SMarcel Holtmann return; 1101da177e4SLinus Torvalds 1111da177e4SLinus Torvalds hci_dev_lock(hdev); 1121da177e4SLinus Torvalds 113a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 11440bef302SJohan Hedberg if (conn) 11540bef302SJohan Hedberg conn->role = rp->role; 1161da177e4SLinus Torvalds 1171da177e4SLinus Torvalds hci_dev_unlock(hdev); 118a9de9248SMarcel Holtmann } 1191da177e4SLinus Torvalds 120e4e8e37cSMarcel Holtmann static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 121e4e8e37cSMarcel Holtmann { 122e4e8e37cSMarcel Holtmann struct hci_rp_read_link_policy *rp = (void *) skb->data; 123e4e8e37cSMarcel Holtmann struct hci_conn *conn; 124e4e8e37cSMarcel Holtmann 1259f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 126e4e8e37cSMarcel Holtmann 127e4e8e37cSMarcel Holtmann if (rp->status) 128e4e8e37cSMarcel Holtmann return; 129e4e8e37cSMarcel Holtmann 130e4e8e37cSMarcel Holtmann hci_dev_lock(hdev); 131e4e8e37cSMarcel Holtmann 132e4e8e37cSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 133e4e8e37cSMarcel Holtmann if (conn) 134e4e8e37cSMarcel Holtmann conn->link_policy = __le16_to_cpu(rp->policy); 135e4e8e37cSMarcel Holtmann 136e4e8e37cSMarcel Holtmann hci_dev_unlock(hdev); 137e4e8e37cSMarcel Holtmann } 138e4e8e37cSMarcel Holtmann 139a9de9248SMarcel Holtmann static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 140a9de9248SMarcel Holtmann { 141a9de9248SMarcel Holtmann struct hci_rp_write_link_policy *rp = (void *) skb->data; 142a9de9248SMarcel Holtmann struct hci_conn *conn; 143a9de9248SMarcel Holtmann void *sent; 144a9de9248SMarcel Holtmann 1459f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 146a9de9248SMarcel Holtmann 147a9de9248SMarcel Holtmann if (rp->status) 148a9de9248SMarcel Holtmann return; 149a9de9248SMarcel Holtmann 150a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY); 15104837f64SMarcel Holtmann if (!sent) 152a9de9248SMarcel Holtmann return; 15304837f64SMarcel Holtmann 15404837f64SMarcel Holtmann hci_dev_lock(hdev); 15504837f64SMarcel Holtmann 156a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 157e4e8e37cSMarcel Holtmann if (conn) 15883985319SHarvey Harrison conn->link_policy = get_unaligned_le16(sent + 2); 15904837f64SMarcel Holtmann 16004837f64SMarcel Holtmann hci_dev_unlock(hdev); 1611da177e4SLinus Torvalds } 1621da177e4SLinus Torvalds 163807deac2SGustavo Padovan static void hci_cc_read_def_link_policy(struct hci_dev *hdev, 164807deac2SGustavo Padovan struct sk_buff *skb) 165e4e8e37cSMarcel Holtmann { 166e4e8e37cSMarcel Holtmann struct hci_rp_read_def_link_policy *rp = (void *) skb->data; 167e4e8e37cSMarcel Holtmann 1689f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 169e4e8e37cSMarcel Holtmann 170e4e8e37cSMarcel Holtmann if (rp->status) 171e4e8e37cSMarcel Holtmann return; 172e4e8e37cSMarcel Holtmann 173e4e8e37cSMarcel Holtmann hdev->link_policy = __le16_to_cpu(rp->policy); 174e4e8e37cSMarcel Holtmann } 175e4e8e37cSMarcel Holtmann 176807deac2SGustavo Padovan static void hci_cc_write_def_link_policy(struct hci_dev *hdev, 177807deac2SGustavo Padovan struct sk_buff *skb) 178e4e8e37cSMarcel Holtmann { 179e4e8e37cSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 180e4e8e37cSMarcel Holtmann void *sent; 181e4e8e37cSMarcel Holtmann 1829f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 183e4e8e37cSMarcel Holtmann 18445296acdSMarcel Holtmann if (status) 18545296acdSMarcel Holtmann return; 18645296acdSMarcel Holtmann 187e4e8e37cSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY); 188e4e8e37cSMarcel Holtmann if (!sent) 189e4e8e37cSMarcel Holtmann return; 190e4e8e37cSMarcel Holtmann 191e4e8e37cSMarcel Holtmann hdev->link_policy = get_unaligned_le16(sent); 192e4e8e37cSMarcel Holtmann } 193e4e8e37cSMarcel Holtmann 194a9de9248SMarcel Holtmann static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) 1951da177e4SLinus Torvalds { 196a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 197a9de9248SMarcel Holtmann 1989f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 199a9de9248SMarcel Holtmann 20010572132SGustavo F. Padovan clear_bit(HCI_RESET, &hdev->flags); 20110572132SGustavo F. Padovan 2028761f9d6SMarcel Holtmann if (status) 2038761f9d6SMarcel Holtmann return; 2048761f9d6SMarcel Holtmann 205a297e97cSJohan Hedberg /* Reset all non-persistent flags */ 206eacb44dfSMarcel Holtmann hci_dev_clear_volatile_flags(hdev); 20769775ff6SAndre Guedes 20839c5d970SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 20939c5d970SJohan Hedberg 210bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 211bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 2123f0f524bSJohan Hedberg 2133f0f524bSJohan Hedberg memset(hdev->adv_data, 0, sizeof(hdev->adv_data)); 2143f0f524bSJohan Hedberg hdev->adv_data_len = 0; 215f8e808bdSMarcel Holtmann 216f8e808bdSMarcel Holtmann memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data)); 217f8e808bdSMarcel Holtmann hdev->scan_rsp_data_len = 0; 21806f5b778SMarcel Holtmann 219533553f8SMarcel Holtmann hdev->le_scan_type = LE_SCAN_PASSIVE; 220533553f8SMarcel Holtmann 22106f5b778SMarcel Holtmann hdev->ssp_debug_mode = 0; 222a4d5504dSMarcel Holtmann 223a4d5504dSMarcel Holtmann hci_bdaddr_list_clear(&hdev->le_white_list); 224cfdb0c2dSAnkit Navik hci_bdaddr_list_clear(&hdev->le_resolv_list); 225a9de9248SMarcel Holtmann } 226a9de9248SMarcel Holtmann 227c2f0f979SMarcel Holtmann static void hci_cc_read_stored_link_key(struct hci_dev *hdev, 228c2f0f979SMarcel Holtmann struct sk_buff *skb) 229c2f0f979SMarcel Holtmann { 230c2f0f979SMarcel Holtmann struct hci_rp_read_stored_link_key *rp = (void *)skb->data; 231c2f0f979SMarcel Holtmann struct hci_cp_read_stored_link_key *sent; 232c2f0f979SMarcel Holtmann 233c2f0f979SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 234c2f0f979SMarcel Holtmann 235c2f0f979SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_READ_STORED_LINK_KEY); 236c2f0f979SMarcel Holtmann if (!sent) 237c2f0f979SMarcel Holtmann return; 238c2f0f979SMarcel Holtmann 239c2f0f979SMarcel Holtmann if (!rp->status && sent->read_all == 0x01) { 240c2f0f979SMarcel Holtmann hdev->stored_max_keys = rp->max_keys; 241c2f0f979SMarcel Holtmann hdev->stored_num_keys = rp->num_keys; 242c2f0f979SMarcel Holtmann } 243c2f0f979SMarcel Holtmann } 244c2f0f979SMarcel Holtmann 245a9366120SMarcel Holtmann static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, 246a9366120SMarcel Holtmann struct sk_buff *skb) 247a9366120SMarcel Holtmann { 248a9366120SMarcel Holtmann struct hci_rp_delete_stored_link_key *rp = (void *)skb->data; 249a9366120SMarcel Holtmann 250a9366120SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 251a9366120SMarcel Holtmann 252a9366120SMarcel Holtmann if (rp->status) 253a9366120SMarcel Holtmann return; 254a9366120SMarcel Holtmann 255a9366120SMarcel Holtmann if (rp->num_keys <= hdev->stored_num_keys) 256a9366120SMarcel Holtmann hdev->stored_num_keys -= rp->num_keys; 257a9366120SMarcel Holtmann else 258a9366120SMarcel Holtmann hdev->stored_num_keys = 0; 259a9366120SMarcel Holtmann } 260a9366120SMarcel Holtmann 261a9de9248SMarcel Holtmann static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) 262a9de9248SMarcel Holtmann { 263a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 2641da177e4SLinus Torvalds void *sent; 2651da177e4SLinus Torvalds 2669f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 2671da177e4SLinus Torvalds 268a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME); 2691da177e4SLinus Torvalds if (!sent) 270a9de9248SMarcel Holtmann return; 2711da177e4SLinus Torvalds 27256e5cb86SJohan Hedberg hci_dev_lock(hdev); 27356e5cb86SJohan Hedberg 274d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 275f51d5b24SJohan Hedberg mgmt_set_local_name_complete(hdev, sent, status); 27628cc7bdeSJohan Hedberg else if (!status) 27728cc7bdeSJohan Hedberg memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); 278f51d5b24SJohan Hedberg 27956e5cb86SJohan Hedberg hci_dev_unlock(hdev); 280a9de9248SMarcel Holtmann } 281a9de9248SMarcel Holtmann 282a9de9248SMarcel Holtmann static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) 283a9de9248SMarcel Holtmann { 284a9de9248SMarcel Holtmann struct hci_rp_read_local_name *rp = (void *) skb->data; 285a9de9248SMarcel Holtmann 2869f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 287a9de9248SMarcel Holtmann 288a9de9248SMarcel Holtmann if (rp->status) 289a9de9248SMarcel Holtmann return; 290a9de9248SMarcel Holtmann 291d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 292d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) 2931f6c6378SJohan Hedberg memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); 294a9de9248SMarcel Holtmann } 295a9de9248SMarcel Holtmann 296a9de9248SMarcel Holtmann static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) 297a9de9248SMarcel Holtmann { 298a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 299a9de9248SMarcel Holtmann void *sent; 300a9de9248SMarcel Holtmann 3019f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 302a9de9248SMarcel Holtmann 303a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE); 304a9de9248SMarcel Holtmann if (!sent) 305a9de9248SMarcel Holtmann return; 3061da177e4SLinus Torvalds 3075c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 3085c1a4c8fSJaganath Kanakkassery 3091da177e4SLinus Torvalds if (!status) { 310a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 311a9de9248SMarcel Holtmann 3121da177e4SLinus Torvalds if (param == AUTH_ENABLED) 3131da177e4SLinus Torvalds set_bit(HCI_AUTH, &hdev->flags); 3141da177e4SLinus Torvalds else 3151da177e4SLinus Torvalds clear_bit(HCI_AUTH, &hdev->flags); 3161da177e4SLinus Torvalds } 317a9de9248SMarcel Holtmann 318d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 31933ef95edSJohan Hedberg mgmt_auth_enable_complete(hdev, status); 3205c1a4c8fSJaganath Kanakkassery 3215c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 322a9de9248SMarcel Holtmann } 3231da177e4SLinus Torvalds 324a9de9248SMarcel Holtmann static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) 325a9de9248SMarcel Holtmann { 326a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 32745296acdSMarcel Holtmann __u8 param; 328a9de9248SMarcel Holtmann void *sent; 329a9de9248SMarcel Holtmann 3309f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 331a9de9248SMarcel Holtmann 33245296acdSMarcel Holtmann if (status) 33345296acdSMarcel Holtmann return; 33445296acdSMarcel Holtmann 335a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE); 3361da177e4SLinus Torvalds if (!sent) 337a9de9248SMarcel Holtmann return; 3381da177e4SLinus Torvalds 33945296acdSMarcel Holtmann param = *((__u8 *) sent); 340a9de9248SMarcel Holtmann 3411da177e4SLinus Torvalds if (param) 3421da177e4SLinus Torvalds set_bit(HCI_ENCRYPT, &hdev->flags); 3431da177e4SLinus Torvalds else 3441da177e4SLinus Torvalds clear_bit(HCI_ENCRYPT, &hdev->flags); 3451da177e4SLinus Torvalds } 3461da177e4SLinus Torvalds 347a9de9248SMarcel Holtmann static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) 348a9de9248SMarcel Holtmann { 34945296acdSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 35045296acdSMarcel Holtmann __u8 param; 351a9de9248SMarcel Holtmann void *sent; 3521da177e4SLinus Torvalds 3539f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 354a9de9248SMarcel Holtmann 355a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE); 3561da177e4SLinus Torvalds if (!sent) 357a9de9248SMarcel Holtmann return; 3581da177e4SLinus Torvalds 35936f7fc7eSJohan Hedberg param = *((__u8 *) sent); 360a9de9248SMarcel Holtmann 36156e5cb86SJohan Hedberg hci_dev_lock(hdev); 36256e5cb86SJohan Hedberg 363fa1bd918SMikel Astiz if (status) { 3642d7cee58SJohan Hedberg hdev->discov_timeout = 0; 3652d7cee58SJohan Hedberg goto done; 3662d7cee58SJohan Hedberg } 3672d7cee58SJohan Hedberg 368bc6d2d04SJohan Hedberg if (param & SCAN_INQUIRY) 3691da177e4SLinus Torvalds set_bit(HCI_ISCAN, &hdev->flags); 370bc6d2d04SJohan Hedberg else 371bc6d2d04SJohan Hedberg clear_bit(HCI_ISCAN, &hdev->flags); 3721da177e4SLinus Torvalds 373031547d8SJohan Hedberg if (param & SCAN_PAGE) 3741da177e4SLinus Torvalds set_bit(HCI_PSCAN, &hdev->flags); 375bc6d2d04SJohan Hedberg else 376204e3990SJohan Hedberg clear_bit(HCI_PSCAN, &hdev->flags); 377a9de9248SMarcel Holtmann 37836f7fc7eSJohan Hedberg done: 37956e5cb86SJohan Hedberg hci_dev_unlock(hdev); 3801da177e4SLinus Torvalds } 3811da177e4SLinus Torvalds 382a9de9248SMarcel Holtmann static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 383a9de9248SMarcel Holtmann { 384a9de9248SMarcel Holtmann struct hci_rp_read_class_of_dev *rp = (void *) skb->data; 385a9de9248SMarcel Holtmann 3869f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 387a9de9248SMarcel Holtmann 388a9de9248SMarcel Holtmann if (rp->status) 389a9de9248SMarcel Holtmann return; 390a9de9248SMarcel Holtmann 391a9de9248SMarcel Holtmann memcpy(hdev->dev_class, rp->dev_class, 3); 392a9de9248SMarcel Holtmann 393a9de9248SMarcel Holtmann BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name, 394a9de9248SMarcel Holtmann hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); 395a9de9248SMarcel Holtmann } 396a9de9248SMarcel Holtmann 397a9de9248SMarcel Holtmann static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 398a9de9248SMarcel Holtmann { 399a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 400a9de9248SMarcel Holtmann void *sent; 401a9de9248SMarcel Holtmann 4029f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 403a9de9248SMarcel Holtmann 404a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV); 405a9de9248SMarcel Holtmann if (!sent) 406a9de9248SMarcel Holtmann return; 407a9de9248SMarcel Holtmann 4087f9a903cSMarcel Holtmann hci_dev_lock(hdev); 4097f9a903cSMarcel Holtmann 4107f9a903cSMarcel Holtmann if (status == 0) 411a9de9248SMarcel Holtmann memcpy(hdev->dev_class, sent, 3); 4127f9a903cSMarcel Holtmann 413d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 4147f9a903cSMarcel Holtmann mgmt_set_class_of_dev_complete(hdev, sent, status); 4157f9a903cSMarcel Holtmann 4167f9a903cSMarcel Holtmann hci_dev_unlock(hdev); 417a9de9248SMarcel Holtmann } 418a9de9248SMarcel Holtmann 419a9de9248SMarcel Holtmann static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) 420a9de9248SMarcel Holtmann { 421a9de9248SMarcel Holtmann struct hci_rp_read_voice_setting *rp = (void *) skb->data; 422a9de9248SMarcel Holtmann __u16 setting; 423a9de9248SMarcel Holtmann 4249f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 425a9de9248SMarcel Holtmann 426a9de9248SMarcel Holtmann if (rp->status) 427a9de9248SMarcel Holtmann return; 428a9de9248SMarcel Holtmann 429a9de9248SMarcel Holtmann setting = __le16_to_cpu(rp->voice_setting); 430a9de9248SMarcel Holtmann 431a9de9248SMarcel Holtmann if (hdev->voice_setting == setting) 432a9de9248SMarcel Holtmann return; 433a9de9248SMarcel Holtmann 434a9de9248SMarcel Holtmann hdev->voice_setting = setting; 435a9de9248SMarcel Holtmann 4369f1db00cSAndrei Emeltchenko BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting); 437a9de9248SMarcel Holtmann 4383c54711cSGustavo F. Padovan if (hdev->notify) 439a9de9248SMarcel Holtmann hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 440a9de9248SMarcel Holtmann } 441a9de9248SMarcel Holtmann 4428fc9ced3SGustavo Padovan static void hci_cc_write_voice_setting(struct hci_dev *hdev, 4438fc9ced3SGustavo Padovan struct sk_buff *skb) 444a9de9248SMarcel Holtmann { 445a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 446f383f275SMarcel Holtmann __u16 setting; 447a9de9248SMarcel Holtmann void *sent; 448a9de9248SMarcel Holtmann 4499f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 450a9de9248SMarcel Holtmann 451f383f275SMarcel Holtmann if (status) 452f383f275SMarcel Holtmann return; 453f383f275SMarcel Holtmann 454a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING); 455a9de9248SMarcel Holtmann if (!sent) 456a9de9248SMarcel Holtmann return; 457a9de9248SMarcel Holtmann 458f383f275SMarcel Holtmann setting = get_unaligned_le16(sent); 4591da177e4SLinus Torvalds 460f383f275SMarcel Holtmann if (hdev->voice_setting == setting) 461f383f275SMarcel Holtmann return; 462f383f275SMarcel Holtmann 4631da177e4SLinus Torvalds hdev->voice_setting = setting; 4641da177e4SLinus Torvalds 4659f1db00cSAndrei Emeltchenko BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting); 4661da177e4SLinus Torvalds 4673c54711cSGustavo F. Padovan if (hdev->notify) 4681da177e4SLinus Torvalds hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 4691da177e4SLinus Torvalds } 4701da177e4SLinus Torvalds 471b4cb9fb2SMarcel Holtmann static void hci_cc_read_num_supported_iac(struct hci_dev *hdev, 472b4cb9fb2SMarcel Holtmann struct sk_buff *skb) 473b4cb9fb2SMarcel Holtmann { 474b4cb9fb2SMarcel Holtmann struct hci_rp_read_num_supported_iac *rp = (void *) skb->data; 475b4cb9fb2SMarcel Holtmann 476b4cb9fb2SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 477b4cb9fb2SMarcel Holtmann 478b4cb9fb2SMarcel Holtmann if (rp->status) 479b4cb9fb2SMarcel Holtmann return; 480b4cb9fb2SMarcel Holtmann 481b4cb9fb2SMarcel Holtmann hdev->num_iac = rp->num_iac; 482b4cb9fb2SMarcel Holtmann 483b4cb9fb2SMarcel Holtmann BT_DBG("%s num iac %d", hdev->name, hdev->num_iac); 484b4cb9fb2SMarcel Holtmann } 485b4cb9fb2SMarcel Holtmann 486333140b5SMarcel Holtmann static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) 487333140b5SMarcel Holtmann { 488333140b5SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 4895ed8eb2fSJohan Hedberg struct hci_cp_write_ssp_mode *sent; 490333140b5SMarcel Holtmann 4919f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 492333140b5SMarcel Holtmann 493333140b5SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); 494333140b5SMarcel Holtmann if (!sent) 495333140b5SMarcel Holtmann return; 496333140b5SMarcel Holtmann 4975c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 4985c1a4c8fSJaganath Kanakkassery 4995ed8eb2fSJohan Hedberg if (!status) { 5005ed8eb2fSJohan Hedberg if (sent->mode) 501cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_SSP; 5025ed8eb2fSJohan Hedberg else 503cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_SSP; 5045ed8eb2fSJohan Hedberg } 5055ed8eb2fSJohan Hedberg 506d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 5075ed8eb2fSJohan Hedberg mgmt_ssp_enable_complete(hdev, sent->mode, status); 508c0ecddc2SJohan Hedberg else if (!status) { 5095ed8eb2fSJohan Hedberg if (sent->mode) 510a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SSP_ENABLED); 51184bde9d6SJohan Hedberg else 512a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_SSP_ENABLED); 513c0ecddc2SJohan Hedberg } 5145c1a4c8fSJaganath Kanakkassery 5155c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 516333140b5SMarcel Holtmann } 517333140b5SMarcel Holtmann 518eac83dc6SMarcel Holtmann static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb) 519eac83dc6SMarcel Holtmann { 520eac83dc6SMarcel Holtmann u8 status = *((u8 *) skb->data); 521eac83dc6SMarcel Holtmann struct hci_cp_write_sc_support *sent; 522eac83dc6SMarcel Holtmann 523eac83dc6SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 524eac83dc6SMarcel Holtmann 525eac83dc6SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT); 526eac83dc6SMarcel Holtmann if (!sent) 527eac83dc6SMarcel Holtmann return; 528eac83dc6SMarcel Holtmann 5295c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 5305c1a4c8fSJaganath Kanakkassery 531eac83dc6SMarcel Holtmann if (!status) { 532eac83dc6SMarcel Holtmann if (sent->support) 533eac83dc6SMarcel Holtmann hdev->features[1][0] |= LMP_HOST_SC; 534eac83dc6SMarcel Holtmann else 535eac83dc6SMarcel Holtmann hdev->features[1][0] &= ~LMP_HOST_SC; 536eac83dc6SMarcel Holtmann } 537eac83dc6SMarcel Holtmann 538d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT) && !status) { 539eac83dc6SMarcel Holtmann if (sent->support) 540a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SC_ENABLED); 541eac83dc6SMarcel Holtmann else 542a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_SC_ENABLED); 543eac83dc6SMarcel Holtmann } 5445c1a4c8fSJaganath Kanakkassery 5455c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 546eac83dc6SMarcel Holtmann } 547eac83dc6SMarcel Holtmann 548a9de9248SMarcel Holtmann static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) 549a9de9248SMarcel Holtmann { 550a9de9248SMarcel Holtmann struct hci_rp_read_local_version *rp = (void *) skb->data; 5511143e5a6SMarcel Holtmann 5529f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 5531143e5a6SMarcel Holtmann 554a9de9248SMarcel Holtmann if (rp->status) 55542c6b129SJohan Hedberg return; 5561143e5a6SMarcel Holtmann 557d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 558d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) { 559a9de9248SMarcel Holtmann hdev->hci_ver = rp->hci_ver; 560e4e8e37cSMarcel Holtmann hdev->hci_rev = __le16_to_cpu(rp->hci_rev); 561d5859e22SJohan Hedberg hdev->lmp_ver = rp->lmp_ver; 562e4e8e37cSMarcel Holtmann hdev->manufacturer = __le16_to_cpu(rp->manufacturer); 563d5859e22SJohan Hedberg hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); 5640d5551f5SMarcel Holtmann } 565d5859e22SJohan Hedberg } 566d5859e22SJohan Hedberg 5678fc9ced3SGustavo Padovan static void hci_cc_read_local_commands(struct hci_dev *hdev, 5688fc9ced3SGustavo Padovan struct sk_buff *skb) 569a9de9248SMarcel Holtmann { 570a9de9248SMarcel Holtmann struct hci_rp_read_local_commands *rp = (void *) skb->data; 571a9de9248SMarcel Holtmann 5729f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 573a9de9248SMarcel Holtmann 5746a070e6eSMarcel Holtmann if (rp->status) 5756a070e6eSMarcel Holtmann return; 5766a070e6eSMarcel Holtmann 577d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 578d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) 579a9de9248SMarcel Holtmann memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); 580a9de9248SMarcel Holtmann } 581a9de9248SMarcel Holtmann 5828fc9ced3SGustavo Padovan static void hci_cc_read_local_features(struct hci_dev *hdev, 5838fc9ced3SGustavo Padovan struct sk_buff *skb) 584a9de9248SMarcel Holtmann { 585a9de9248SMarcel Holtmann struct hci_rp_read_local_features *rp = (void *) skb->data; 586a9de9248SMarcel Holtmann 5879f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 588a9de9248SMarcel Holtmann 589a9de9248SMarcel Holtmann if (rp->status) 590a9de9248SMarcel Holtmann return; 591a9de9248SMarcel Holtmann 592a9de9248SMarcel Holtmann memcpy(hdev->features, rp->features, 8); 5931da177e4SLinus Torvalds 5941da177e4SLinus Torvalds /* Adjust default settings according to features 5951da177e4SLinus Torvalds * supported by device. */ 596a9de9248SMarcel Holtmann 597cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_3SLOT) 5981da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM3 | HCI_DH3); 5991da177e4SLinus Torvalds 600cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_5SLOT) 6011da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM5 | HCI_DH5); 6021da177e4SLinus Torvalds 603cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV2) { 6041da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV2); 6055b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV2); 6065b7f9909SMarcel Holtmann } 6071da177e4SLinus Torvalds 608cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV3) { 6091da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV3); 6105b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV3); 6115b7f9909SMarcel Holtmann } 6125b7f9909SMarcel Holtmann 61345db810fSAndre Guedes if (lmp_esco_capable(hdev)) 6145b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV3); 6155b7f9909SMarcel Holtmann 616cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV4) 6175b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV4); 6185b7f9909SMarcel Holtmann 619cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV5) 6205b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV5); 6211da177e4SLinus Torvalds 622cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_2M) 623efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV3); 624efc7688bSMarcel Holtmann 625cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_3M) 626efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_3EV3); 627efc7688bSMarcel Holtmann 628cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_3S_ESCO) 629efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); 6301da177e4SLinus Torvalds } 6311da177e4SLinus Torvalds 632971e3a4bSAndre Guedes static void hci_cc_read_local_ext_features(struct hci_dev *hdev, 633971e3a4bSAndre Guedes struct sk_buff *skb) 634971e3a4bSAndre Guedes { 635971e3a4bSAndre Guedes struct hci_rp_read_local_ext_features *rp = (void *) skb->data; 636971e3a4bSAndre Guedes 6379f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 638971e3a4bSAndre Guedes 639971e3a4bSAndre Guedes if (rp->status) 64042c6b129SJohan Hedberg return; 641971e3a4bSAndre Guedes 64257af75a8SMarcel Holtmann if (hdev->max_page < rp->max_page) 643d2c5d77fSJohan Hedberg hdev->max_page = rp->max_page; 644d2c5d77fSJohan Hedberg 645cad718edSJohan Hedberg if (rp->page < HCI_MAX_PAGES) 646cad718edSJohan Hedberg memcpy(hdev->features[rp->page], rp->features, 8); 647971e3a4bSAndre Guedes } 648971e3a4bSAndre Guedes 6491e89cffbSAndrei Emeltchenko static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, 6501e89cffbSAndrei Emeltchenko struct sk_buff *skb) 6511e89cffbSAndrei Emeltchenko { 6521e89cffbSAndrei Emeltchenko struct hci_rp_read_flow_control_mode *rp = (void *) skb->data; 6531e89cffbSAndrei Emeltchenko 6549f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 6551e89cffbSAndrei Emeltchenko 65645296acdSMarcel Holtmann if (rp->status) 65745296acdSMarcel Holtmann return; 65845296acdSMarcel Holtmann 6591e89cffbSAndrei Emeltchenko hdev->flow_ctl_mode = rp->mode; 6601e89cffbSAndrei Emeltchenko } 6611e89cffbSAndrei Emeltchenko 662a9de9248SMarcel Holtmann static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) 663a9de9248SMarcel Holtmann { 664a9de9248SMarcel Holtmann struct hci_rp_read_buffer_size *rp = (void *) skb->data; 665a9de9248SMarcel Holtmann 6669f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 667a9de9248SMarcel Holtmann 668a9de9248SMarcel Holtmann if (rp->status) 669a9de9248SMarcel Holtmann return; 670a9de9248SMarcel Holtmann 671a9de9248SMarcel Holtmann hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu); 672a9de9248SMarcel Holtmann hdev->sco_mtu = rp->sco_mtu; 673a9de9248SMarcel Holtmann hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt); 674a9de9248SMarcel Holtmann hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt); 675da1f5198SMarcel Holtmann 676da1f5198SMarcel Holtmann if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) { 677da1f5198SMarcel Holtmann hdev->sco_mtu = 64; 678da1f5198SMarcel Holtmann hdev->sco_pkts = 8; 679da1f5198SMarcel Holtmann } 680da1f5198SMarcel Holtmann 681da1f5198SMarcel Holtmann hdev->acl_cnt = hdev->acl_pkts; 682da1f5198SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 6831da177e4SLinus Torvalds 684807deac2SGustavo Padovan BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu, 685807deac2SGustavo Padovan hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts); 6861da177e4SLinus Torvalds } 6871da177e4SLinus Torvalds 688a9de9248SMarcel Holtmann static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) 689a9de9248SMarcel Holtmann { 690a9de9248SMarcel Holtmann struct hci_rp_read_bd_addr *rp = (void *) skb->data; 6911da177e4SLinus Torvalds 6929f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 693a9de9248SMarcel Holtmann 694e30d3f5fSMarcel Holtmann if (rp->status) 695e30d3f5fSMarcel Holtmann return; 696e30d3f5fSMarcel Holtmann 697e30d3f5fSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) 698a9de9248SMarcel Holtmann bacpy(&hdev->bdaddr, &rp->bdaddr); 699e30d3f5fSMarcel Holtmann 700d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) 701e30d3f5fSMarcel Holtmann bacpy(&hdev->setup_addr, &rp->bdaddr); 70223bb5763SJohan Hedberg } 70323bb5763SJohan Hedberg 704f332ec66SJohan Hedberg static void hci_cc_read_page_scan_activity(struct hci_dev *hdev, 705f332ec66SJohan Hedberg struct sk_buff *skb) 706f332ec66SJohan Hedberg { 707f332ec66SJohan Hedberg struct hci_rp_read_page_scan_activity *rp = (void *) skb->data; 708f332ec66SJohan Hedberg 709f332ec66SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 710f332ec66SJohan Hedberg 71145296acdSMarcel Holtmann if (rp->status) 71245296acdSMarcel Holtmann return; 71345296acdSMarcel Holtmann 71445296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) { 715f332ec66SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(rp->interval); 716f332ec66SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(rp->window); 717f332ec66SJohan Hedberg } 718f332ec66SJohan Hedberg } 719f332ec66SJohan Hedberg 7204a3ee763SJohan Hedberg static void hci_cc_write_page_scan_activity(struct hci_dev *hdev, 7214a3ee763SJohan Hedberg struct sk_buff *skb) 7224a3ee763SJohan Hedberg { 7234a3ee763SJohan Hedberg u8 status = *((u8 *) skb->data); 7244a3ee763SJohan Hedberg struct hci_cp_write_page_scan_activity *sent; 7254a3ee763SJohan Hedberg 7264a3ee763SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 7274a3ee763SJohan Hedberg 7284a3ee763SJohan Hedberg if (status) 7294a3ee763SJohan Hedberg return; 7304a3ee763SJohan Hedberg 7314a3ee763SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY); 7324a3ee763SJohan Hedberg if (!sent) 7334a3ee763SJohan Hedberg return; 7344a3ee763SJohan Hedberg 7354a3ee763SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(sent->interval); 7364a3ee763SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(sent->window); 7374a3ee763SJohan Hedberg } 7384a3ee763SJohan Hedberg 739f332ec66SJohan Hedberg static void hci_cc_read_page_scan_type(struct hci_dev *hdev, 740f332ec66SJohan Hedberg struct sk_buff *skb) 741f332ec66SJohan Hedberg { 742f332ec66SJohan Hedberg struct hci_rp_read_page_scan_type *rp = (void *) skb->data; 743f332ec66SJohan Hedberg 744f332ec66SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 745f332ec66SJohan Hedberg 74645296acdSMarcel Holtmann if (rp->status) 74745296acdSMarcel Holtmann return; 74845296acdSMarcel Holtmann 74945296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) 750f332ec66SJohan Hedberg hdev->page_scan_type = rp->type; 751f332ec66SJohan Hedberg } 752f332ec66SJohan Hedberg 7534a3ee763SJohan Hedberg static void hci_cc_write_page_scan_type(struct hci_dev *hdev, 7544a3ee763SJohan Hedberg struct sk_buff *skb) 7554a3ee763SJohan Hedberg { 7564a3ee763SJohan Hedberg u8 status = *((u8 *) skb->data); 7574a3ee763SJohan Hedberg u8 *type; 7584a3ee763SJohan Hedberg 7594a3ee763SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 7604a3ee763SJohan Hedberg 7614a3ee763SJohan Hedberg if (status) 7624a3ee763SJohan Hedberg return; 7634a3ee763SJohan Hedberg 7644a3ee763SJohan Hedberg type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE); 7654a3ee763SJohan Hedberg if (type) 7664a3ee763SJohan Hedberg hdev->page_scan_type = *type; 7674a3ee763SJohan Hedberg } 7684a3ee763SJohan Hedberg 769350ee4cfSAndrei Emeltchenko static void hci_cc_read_data_block_size(struct hci_dev *hdev, 770350ee4cfSAndrei Emeltchenko struct sk_buff *skb) 771350ee4cfSAndrei Emeltchenko { 772350ee4cfSAndrei Emeltchenko struct hci_rp_read_data_block_size *rp = (void *) skb->data; 773350ee4cfSAndrei Emeltchenko 7749f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 775350ee4cfSAndrei Emeltchenko 776350ee4cfSAndrei Emeltchenko if (rp->status) 777350ee4cfSAndrei Emeltchenko return; 778350ee4cfSAndrei Emeltchenko 779350ee4cfSAndrei Emeltchenko hdev->block_mtu = __le16_to_cpu(rp->max_acl_len); 780350ee4cfSAndrei Emeltchenko hdev->block_len = __le16_to_cpu(rp->block_len); 781350ee4cfSAndrei Emeltchenko hdev->num_blocks = __le16_to_cpu(rp->num_blocks); 782350ee4cfSAndrei Emeltchenko 783350ee4cfSAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 784350ee4cfSAndrei Emeltchenko 785350ee4cfSAndrei Emeltchenko BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu, 786350ee4cfSAndrei Emeltchenko hdev->block_cnt, hdev->block_len); 787350ee4cfSAndrei Emeltchenko } 788350ee4cfSAndrei Emeltchenko 78933f35721SJohan Hedberg static void hci_cc_read_clock(struct hci_dev *hdev, struct sk_buff *skb) 79033f35721SJohan Hedberg { 79133f35721SJohan Hedberg struct hci_rp_read_clock *rp = (void *) skb->data; 79233f35721SJohan Hedberg struct hci_cp_read_clock *cp; 79333f35721SJohan Hedberg struct hci_conn *conn; 79433f35721SJohan Hedberg 79533f35721SJohan Hedberg BT_DBG("%s", hdev->name); 79633f35721SJohan Hedberg 79733f35721SJohan Hedberg if (skb->len < sizeof(*rp)) 79833f35721SJohan Hedberg return; 79933f35721SJohan Hedberg 80033f35721SJohan Hedberg if (rp->status) 80133f35721SJohan Hedberg return; 80233f35721SJohan Hedberg 80333f35721SJohan Hedberg hci_dev_lock(hdev); 80433f35721SJohan Hedberg 80533f35721SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK); 80633f35721SJohan Hedberg if (!cp) 80733f35721SJohan Hedberg goto unlock; 80833f35721SJohan Hedberg 80933f35721SJohan Hedberg if (cp->which == 0x00) { 81033f35721SJohan Hedberg hdev->clock = le32_to_cpu(rp->clock); 81133f35721SJohan Hedberg goto unlock; 81233f35721SJohan Hedberg } 81333f35721SJohan Hedberg 81433f35721SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 81533f35721SJohan Hedberg if (conn) { 81633f35721SJohan Hedberg conn->clock = le32_to_cpu(rp->clock); 81733f35721SJohan Hedberg conn->clock_accuracy = le16_to_cpu(rp->accuracy); 81833f35721SJohan Hedberg } 81933f35721SJohan Hedberg 82033f35721SJohan Hedberg unlock: 82133f35721SJohan Hedberg hci_dev_unlock(hdev); 82233f35721SJohan Hedberg } 82333f35721SJohan Hedberg 824928abaa7SAndrei Emeltchenko static void hci_cc_read_local_amp_info(struct hci_dev *hdev, 825928abaa7SAndrei Emeltchenko struct sk_buff *skb) 826928abaa7SAndrei Emeltchenko { 827928abaa7SAndrei Emeltchenko struct hci_rp_read_local_amp_info *rp = (void *) skb->data; 828928abaa7SAndrei Emeltchenko 8299f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 830928abaa7SAndrei Emeltchenko 831928abaa7SAndrei Emeltchenko if (rp->status) 83283927882SArron Wang return; 833928abaa7SAndrei Emeltchenko 834928abaa7SAndrei Emeltchenko hdev->amp_status = rp->amp_status; 835928abaa7SAndrei Emeltchenko hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); 836928abaa7SAndrei Emeltchenko hdev->amp_max_bw = __le32_to_cpu(rp->max_bw); 837928abaa7SAndrei Emeltchenko hdev->amp_min_latency = __le32_to_cpu(rp->min_latency); 838928abaa7SAndrei Emeltchenko hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu); 839928abaa7SAndrei Emeltchenko hdev->amp_type = rp->amp_type; 840928abaa7SAndrei Emeltchenko hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap); 841928abaa7SAndrei Emeltchenko hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size); 842928abaa7SAndrei Emeltchenko hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to); 843928abaa7SAndrei Emeltchenko hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); 844928abaa7SAndrei Emeltchenko } 845928abaa7SAndrei Emeltchenko 846d5859e22SJohan Hedberg static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, 847d5859e22SJohan Hedberg struct sk_buff *skb) 848d5859e22SJohan Hedberg { 84991c4e9b1SMarcel Holtmann struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data; 850d5859e22SJohan Hedberg 8519f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 852d5859e22SJohan Hedberg 85345296acdSMarcel Holtmann if (rp->status) 85445296acdSMarcel Holtmann return; 85545296acdSMarcel Holtmann 85691c4e9b1SMarcel Holtmann hdev->inq_tx_power = rp->tx_power; 857d5859e22SJohan Hedberg } 858d5859e22SJohan Hedberg 859980e1a53SJohan Hedberg static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) 860980e1a53SJohan Hedberg { 861980e1a53SJohan Hedberg struct hci_rp_pin_code_reply *rp = (void *) skb->data; 862980e1a53SJohan Hedberg struct hci_cp_pin_code_reply *cp; 863980e1a53SJohan Hedberg struct hci_conn *conn; 864980e1a53SJohan Hedberg 8659f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 866980e1a53SJohan Hedberg 86756e5cb86SJohan Hedberg hci_dev_lock(hdev); 86856e5cb86SJohan Hedberg 869d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 870744cf19eSJohan Hedberg mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); 871980e1a53SJohan Hedberg 872fa1bd918SMikel Astiz if (rp->status) 87356e5cb86SJohan Hedberg goto unlock; 874980e1a53SJohan Hedberg 875980e1a53SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); 876980e1a53SJohan Hedberg if (!cp) 87756e5cb86SJohan Hedberg goto unlock; 878980e1a53SJohan Hedberg 879980e1a53SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 880980e1a53SJohan Hedberg if (conn) 881980e1a53SJohan Hedberg conn->pin_length = cp->pin_len; 88256e5cb86SJohan Hedberg 88356e5cb86SJohan Hedberg unlock: 88456e5cb86SJohan Hedberg hci_dev_unlock(hdev); 885980e1a53SJohan Hedberg } 886980e1a53SJohan Hedberg 887980e1a53SJohan Hedberg static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) 888980e1a53SJohan Hedberg { 889980e1a53SJohan Hedberg struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data; 890980e1a53SJohan Hedberg 8919f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 892980e1a53SJohan Hedberg 89356e5cb86SJohan Hedberg hci_dev_lock(hdev); 89456e5cb86SJohan Hedberg 895d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 896744cf19eSJohan Hedberg mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, 897980e1a53SJohan Hedberg rp->status); 89856e5cb86SJohan Hedberg 89956e5cb86SJohan Hedberg hci_dev_unlock(hdev); 900980e1a53SJohan Hedberg } 90156e5cb86SJohan Hedberg 9026ed58ec5SVille Tervo static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, 9036ed58ec5SVille Tervo struct sk_buff *skb) 9046ed58ec5SVille Tervo { 9056ed58ec5SVille Tervo struct hci_rp_le_read_buffer_size *rp = (void *) skb->data; 9066ed58ec5SVille Tervo 9079f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9086ed58ec5SVille Tervo 9096ed58ec5SVille Tervo if (rp->status) 9106ed58ec5SVille Tervo return; 9116ed58ec5SVille Tervo 9126ed58ec5SVille Tervo hdev->le_mtu = __le16_to_cpu(rp->le_mtu); 9136ed58ec5SVille Tervo hdev->le_pkts = rp->le_max_pkt; 9146ed58ec5SVille Tervo 9156ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 9166ed58ec5SVille Tervo 9176ed58ec5SVille Tervo BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts); 9186ed58ec5SVille Tervo } 919980e1a53SJohan Hedberg 92060e77321SJohan Hedberg static void hci_cc_le_read_local_features(struct hci_dev *hdev, 92160e77321SJohan Hedberg struct sk_buff *skb) 92260e77321SJohan Hedberg { 92360e77321SJohan Hedberg struct hci_rp_le_read_local_features *rp = (void *) skb->data; 92460e77321SJohan Hedberg 92560e77321SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 92660e77321SJohan Hedberg 92745296acdSMarcel Holtmann if (rp->status) 92845296acdSMarcel Holtmann return; 92945296acdSMarcel Holtmann 93060e77321SJohan Hedberg memcpy(hdev->le_features, rp->features, 8); 93160e77321SJohan Hedberg } 93260e77321SJohan Hedberg 9338fa19098SJohan Hedberg static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, 9348fa19098SJohan Hedberg struct sk_buff *skb) 9358fa19098SJohan Hedberg { 9368fa19098SJohan Hedberg struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data; 9378fa19098SJohan Hedberg 9388fa19098SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9398fa19098SJohan Hedberg 94045296acdSMarcel Holtmann if (rp->status) 94145296acdSMarcel Holtmann return; 94245296acdSMarcel Holtmann 9438fa19098SJohan Hedberg hdev->adv_tx_power = rp->tx_power; 9448fa19098SJohan Hedberg } 9458fa19098SJohan Hedberg 946a5c29683SJohan Hedberg static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) 947a5c29683SJohan Hedberg { 948a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 949a5c29683SJohan Hedberg 9509f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 951a5c29683SJohan Hedberg 95256e5cb86SJohan Hedberg hci_dev_lock(hdev); 95356e5cb86SJohan Hedberg 954d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 95504124681SGustavo F. Padovan mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0, 95604124681SGustavo F. Padovan rp->status); 95756e5cb86SJohan Hedberg 95856e5cb86SJohan Hedberg hci_dev_unlock(hdev); 959a5c29683SJohan Hedberg } 960a5c29683SJohan Hedberg 961a5c29683SJohan Hedberg static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, 962a5c29683SJohan Hedberg struct sk_buff *skb) 963a5c29683SJohan Hedberg { 964a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 965a5c29683SJohan Hedberg 9669f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 967a5c29683SJohan Hedberg 96856e5cb86SJohan Hedberg hci_dev_lock(hdev); 96956e5cb86SJohan Hedberg 970d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 971744cf19eSJohan Hedberg mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, 97204124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 97356e5cb86SJohan Hedberg 97456e5cb86SJohan Hedberg hci_dev_unlock(hdev); 975a5c29683SJohan Hedberg } 976a5c29683SJohan Hedberg 9771143d458SBrian Gix static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb) 9781143d458SBrian Gix { 9791143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 9801143d458SBrian Gix 9819f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9821143d458SBrian Gix 9831143d458SBrian Gix hci_dev_lock(hdev); 9841143d458SBrian Gix 985d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 986272d90dfSJohan Hedberg mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 987272d90dfSJohan Hedberg 0, rp->status); 9881143d458SBrian Gix 9891143d458SBrian Gix hci_dev_unlock(hdev); 9901143d458SBrian Gix } 9911143d458SBrian Gix 9921143d458SBrian Gix static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, 9931143d458SBrian Gix struct sk_buff *skb) 9941143d458SBrian Gix { 9951143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 9961143d458SBrian Gix 9979f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9981143d458SBrian Gix 9991143d458SBrian Gix hci_dev_lock(hdev); 10001143d458SBrian Gix 1001d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 10021143d458SBrian Gix mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr, 100304124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 10041143d458SBrian Gix 10051143d458SBrian Gix hci_dev_unlock(hdev); 10061143d458SBrian Gix } 10071143d458SBrian Gix 10084d2d2796SMarcel Holtmann static void hci_cc_read_local_oob_data(struct hci_dev *hdev, 1009c35938b2SSzymon Janc struct sk_buff *skb) 1010c35938b2SSzymon Janc { 1011c35938b2SSzymon Janc struct hci_rp_read_local_oob_data *rp = (void *) skb->data; 1012c35938b2SSzymon Janc 10139f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 10144d2d2796SMarcel Holtmann } 10154d2d2796SMarcel Holtmann 10164d2d2796SMarcel Holtmann static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, 10174d2d2796SMarcel Holtmann struct sk_buff *skb) 10184d2d2796SMarcel Holtmann { 10194d2d2796SMarcel Holtmann struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data; 10204d2d2796SMarcel Holtmann 10214d2d2796SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 1022c35938b2SSzymon Janc } 1023c35938b2SSzymon Janc 10247a4cd51dSMarcel Holtmann static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb) 10257a4cd51dSMarcel Holtmann { 10267a4cd51dSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 10277a4cd51dSMarcel Holtmann bdaddr_t *sent; 10287a4cd51dSMarcel Holtmann 10297a4cd51dSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 10307a4cd51dSMarcel Holtmann 103145296acdSMarcel Holtmann if (status) 103245296acdSMarcel Holtmann return; 103345296acdSMarcel Holtmann 10347a4cd51dSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR); 10357a4cd51dSMarcel Holtmann if (!sent) 10367a4cd51dSMarcel Holtmann return; 10377a4cd51dSMarcel Holtmann 10387a4cd51dSMarcel Holtmann hci_dev_lock(hdev); 10397a4cd51dSMarcel Holtmann 10407a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, sent); 10417a4cd51dSMarcel Holtmann 10427a4cd51dSMarcel Holtmann hci_dev_unlock(hdev); 10437a4cd51dSMarcel Holtmann } 10447a4cd51dSMarcel Holtmann 10450314f286SJaganath Kanakkassery static void hci_cc_le_set_default_phy(struct hci_dev *hdev, struct sk_buff *skb) 10460314f286SJaganath Kanakkassery { 10470314f286SJaganath Kanakkassery __u8 status = *((__u8 *) skb->data); 10480314f286SJaganath Kanakkassery struct hci_cp_le_set_default_phy *cp; 10490314f286SJaganath Kanakkassery 10500314f286SJaganath Kanakkassery BT_DBG("%s status 0x%2.2x", hdev->name, status); 10510314f286SJaganath Kanakkassery 10520314f286SJaganath Kanakkassery if (status) 10530314f286SJaganath Kanakkassery return; 10540314f286SJaganath Kanakkassery 10550314f286SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_DEFAULT_PHY); 10560314f286SJaganath Kanakkassery if (!cp) 10570314f286SJaganath Kanakkassery return; 10580314f286SJaganath Kanakkassery 10590314f286SJaganath Kanakkassery hci_dev_lock(hdev); 10600314f286SJaganath Kanakkassery 10610314f286SJaganath Kanakkassery hdev->le_tx_def_phys = cp->tx_phys; 10620314f286SJaganath Kanakkassery hdev->le_rx_def_phys = cp->rx_phys; 10630314f286SJaganath Kanakkassery 10640314f286SJaganath Kanakkassery hci_dev_unlock(hdev); 10650314f286SJaganath Kanakkassery } 10660314f286SJaganath Kanakkassery 1067a73c046aSJaganath Kanakkassery static void hci_cc_le_set_adv_set_random_addr(struct hci_dev *hdev, 1068a73c046aSJaganath Kanakkassery struct sk_buff *skb) 1069a73c046aSJaganath Kanakkassery { 1070a73c046aSJaganath Kanakkassery __u8 status = *((__u8 *) skb->data); 1071a73c046aSJaganath Kanakkassery struct hci_cp_le_set_adv_set_rand_addr *cp; 1072a73c046aSJaganath Kanakkassery struct adv_info *adv_instance; 1073a73c046aSJaganath Kanakkassery 1074a73c046aSJaganath Kanakkassery if (status) 1075a73c046aSJaganath Kanakkassery return; 1076a73c046aSJaganath Kanakkassery 1077a73c046aSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR); 1078a73c046aSJaganath Kanakkassery if (!cp) 1079a73c046aSJaganath Kanakkassery return; 1080a73c046aSJaganath Kanakkassery 1081a73c046aSJaganath Kanakkassery hci_dev_lock(hdev); 1082a73c046aSJaganath Kanakkassery 1083a73c046aSJaganath Kanakkassery if (!hdev->cur_adv_instance) { 1084a73c046aSJaganath Kanakkassery /* Store in hdev for instance 0 (Set adv and Directed advs) */ 1085a73c046aSJaganath Kanakkassery bacpy(&hdev->random_addr, &cp->bdaddr); 1086a73c046aSJaganath Kanakkassery } else { 1087a73c046aSJaganath Kanakkassery adv_instance = hci_find_adv_instance(hdev, 1088a73c046aSJaganath Kanakkassery hdev->cur_adv_instance); 1089a73c046aSJaganath Kanakkassery if (adv_instance) 1090a73c046aSJaganath Kanakkassery bacpy(&adv_instance->random_addr, &cp->bdaddr); 1091a73c046aSJaganath Kanakkassery } 1092a73c046aSJaganath Kanakkassery 1093a73c046aSJaganath Kanakkassery hci_dev_unlock(hdev); 1094a73c046aSJaganath Kanakkassery } 1095a73c046aSJaganath Kanakkassery 1096c1d5dc4aSJohan Hedberg static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) 1097c1d5dc4aSJohan Hedberg { 1098c1d5dc4aSJohan Hedberg __u8 *sent, status = *((__u8 *) skb->data); 1099c1d5dc4aSJohan Hedberg 1100c1d5dc4aSJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 1101c1d5dc4aSJohan Hedberg 110245296acdSMarcel Holtmann if (status) 1103c1d5dc4aSJohan Hedberg return; 1104c1d5dc4aSJohan Hedberg 110545296acdSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE); 110645296acdSMarcel Holtmann if (!sent) 11073c857757SJohan Hedberg return; 11083c857757SJohan Hedberg 1109c1d5dc4aSJohan Hedberg hci_dev_lock(hdev); 1110c1d5dc4aSJohan Hedberg 111149c922bbSStephen Hemminger /* If we're doing connection initiation as peripheral. Set a 11123c857757SJohan Hedberg * timeout in case something goes wrong. 11133c857757SJohan Hedberg */ 11143c857757SJohan Hedberg if (*sent) { 11153c857757SJohan Hedberg struct hci_conn *conn; 11163c857757SJohan Hedberg 1117a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ADV); 111866c417c1SJohan Hedberg 1119e7d9ab73SJakub Pawlowski conn = hci_lookup_le_connect(hdev); 11203c857757SJohan Hedberg if (conn) 11213c857757SJohan Hedberg queue_delayed_work(hdev->workqueue, 11223c857757SJohan Hedberg &conn->le_conn_timeout, 112309ae260bSJohan Hedberg conn->conn_timeout); 112466c417c1SJohan Hedberg } else { 1125a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ADV); 11263c857757SJohan Hedberg } 11273c857757SJohan Hedberg 112804b4edcbSJohan Hedberg hci_dev_unlock(hdev); 1129c1d5dc4aSJohan Hedberg } 1130c1d5dc4aSJohan Hedberg 1131de181e88SJaganath Kanakkassery static void hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, 1132de181e88SJaganath Kanakkassery struct sk_buff *skb) 1133de181e88SJaganath Kanakkassery { 1134de181e88SJaganath Kanakkassery struct hci_cp_le_set_ext_adv_enable *cp; 1135de181e88SJaganath Kanakkassery __u8 status = *((__u8 *) skb->data); 1136de181e88SJaganath Kanakkassery 1137de181e88SJaganath Kanakkassery BT_DBG("%s status 0x%2.2x", hdev->name, status); 1138de181e88SJaganath Kanakkassery 1139de181e88SJaganath Kanakkassery if (status) 1140de181e88SJaganath Kanakkassery return; 1141de181e88SJaganath Kanakkassery 1142de181e88SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_ENABLE); 1143de181e88SJaganath Kanakkassery if (!cp) 1144de181e88SJaganath Kanakkassery return; 1145de181e88SJaganath Kanakkassery 1146de181e88SJaganath Kanakkassery hci_dev_lock(hdev); 1147de181e88SJaganath Kanakkassery 1148de181e88SJaganath Kanakkassery if (cp->enable) { 1149de181e88SJaganath Kanakkassery struct hci_conn *conn; 1150de181e88SJaganath Kanakkassery 1151de181e88SJaganath Kanakkassery hci_dev_set_flag(hdev, HCI_LE_ADV); 1152de181e88SJaganath Kanakkassery 1153de181e88SJaganath Kanakkassery conn = hci_lookup_le_connect(hdev); 1154de181e88SJaganath Kanakkassery if (conn) 1155de181e88SJaganath Kanakkassery queue_delayed_work(hdev->workqueue, 1156de181e88SJaganath Kanakkassery &conn->le_conn_timeout, 1157de181e88SJaganath Kanakkassery conn->conn_timeout); 115845b7749fSJaganath Kanakkassery } else { 115945b7749fSJaganath Kanakkassery hci_dev_clear_flag(hdev, HCI_LE_ADV); 1160de181e88SJaganath Kanakkassery } 1161de181e88SJaganath Kanakkassery 1162de181e88SJaganath Kanakkassery hci_dev_unlock(hdev); 1163de181e88SJaganath Kanakkassery } 1164de181e88SJaganath Kanakkassery 1165533553f8SMarcel Holtmann static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) 1166533553f8SMarcel Holtmann { 1167533553f8SMarcel Holtmann struct hci_cp_le_set_scan_param *cp; 1168533553f8SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 1169533553f8SMarcel Holtmann 1170533553f8SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 1171533553f8SMarcel Holtmann 117245296acdSMarcel Holtmann if (status) 117345296acdSMarcel Holtmann return; 117445296acdSMarcel Holtmann 1175533553f8SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM); 1176533553f8SMarcel Holtmann if (!cp) 1177533553f8SMarcel Holtmann return; 1178533553f8SMarcel Holtmann 1179533553f8SMarcel Holtmann hci_dev_lock(hdev); 1180533553f8SMarcel Holtmann 1181533553f8SMarcel Holtmann hdev->le_scan_type = cp->type; 1182533553f8SMarcel Holtmann 1183533553f8SMarcel Holtmann hci_dev_unlock(hdev); 1184533553f8SMarcel Holtmann } 1185533553f8SMarcel Holtmann 1186a2344b9eSJaganath Kanakkassery static void hci_cc_le_set_ext_scan_param(struct hci_dev *hdev, 1187a2344b9eSJaganath Kanakkassery struct sk_buff *skb) 1188a2344b9eSJaganath Kanakkassery { 1189a2344b9eSJaganath Kanakkassery struct hci_cp_le_set_ext_scan_params *cp; 1190a2344b9eSJaganath Kanakkassery __u8 status = *((__u8 *) skb->data); 1191a2344b9eSJaganath Kanakkassery struct hci_cp_le_scan_phy_params *phy_param; 1192a2344b9eSJaganath Kanakkassery 1193a2344b9eSJaganath Kanakkassery BT_DBG("%s status 0x%2.2x", hdev->name, status); 1194a2344b9eSJaganath Kanakkassery 1195a2344b9eSJaganath Kanakkassery if (status) 1196a2344b9eSJaganath Kanakkassery return; 1197a2344b9eSJaganath Kanakkassery 1198a2344b9eSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_PARAMS); 1199a2344b9eSJaganath Kanakkassery if (!cp) 1200a2344b9eSJaganath Kanakkassery return; 1201a2344b9eSJaganath Kanakkassery 1202a2344b9eSJaganath Kanakkassery phy_param = (void *)cp->data; 1203a2344b9eSJaganath Kanakkassery 1204a2344b9eSJaganath Kanakkassery hci_dev_lock(hdev); 1205a2344b9eSJaganath Kanakkassery 1206a2344b9eSJaganath Kanakkassery hdev->le_scan_type = phy_param->type; 1207a2344b9eSJaganath Kanakkassery 1208a2344b9eSJaganath Kanakkassery hci_dev_unlock(hdev); 1209a2344b9eSJaganath Kanakkassery } 1210a2344b9eSJaganath Kanakkassery 1211b9a6328fSJohan Hedberg static bool has_pending_adv_report(struct hci_dev *hdev) 1212b9a6328fSJohan Hedberg { 1213b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1214b9a6328fSJohan Hedberg 1215b9a6328fSJohan Hedberg return bacmp(&d->last_adv_addr, BDADDR_ANY); 1216b9a6328fSJohan Hedberg } 1217b9a6328fSJohan Hedberg 1218b9a6328fSJohan Hedberg static void clear_pending_adv_report(struct hci_dev *hdev) 1219b9a6328fSJohan Hedberg { 1220b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1221b9a6328fSJohan Hedberg 1222b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, BDADDR_ANY); 1223b9a6328fSJohan Hedberg d->last_adv_data_len = 0; 1224b9a6328fSJohan Hedberg } 1225b9a6328fSJohan Hedberg 1226b9a6328fSJohan Hedberg static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr, 1227c70a7e4cSMarcel Holtmann u8 bdaddr_type, s8 rssi, u32 flags, 1228c70a7e4cSMarcel Holtmann u8 *data, u8 len) 1229b9a6328fSJohan Hedberg { 1230b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1231b9a6328fSJohan Hedberg 1232b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, bdaddr); 1233b9a6328fSJohan Hedberg d->last_adv_addr_type = bdaddr_type; 1234ff5cd29fSJohan Hedberg d->last_adv_rssi = rssi; 1235c70a7e4cSMarcel Holtmann d->last_adv_flags = flags; 1236b9a6328fSJohan Hedberg memcpy(d->last_adv_data, data, len); 1237b9a6328fSJohan Hedberg d->last_adv_data_len = len; 1238b9a6328fSJohan Hedberg } 1239b9a6328fSJohan Hedberg 12403baef810SJaganath Kanakkassery static void le_set_scan_enable_complete(struct hci_dev *hdev, u8 enable) 1241eb9d91f5SAndre Guedes { 12425c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 12435c1a4c8fSJaganath Kanakkassery 12443baef810SJaganath Kanakkassery switch (enable) { 12453fd319b8SAndre Guedes case LE_SCAN_ENABLE: 1246a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_SCAN); 1247b9a6328fSJohan Hedberg if (hdev->le_scan_type == LE_SCAN_ACTIVE) 1248b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 124968a8aea4SAndrei Emeltchenko break; 125068a8aea4SAndrei Emeltchenko 125176a388beSAndre Guedes case LE_SCAN_DISABLE: 1252b9a6328fSJohan Hedberg /* We do this here instead of when setting DISCOVERY_STOPPED 1253b9a6328fSJohan Hedberg * since the latter would potentially require waiting for 1254b9a6328fSJohan Hedberg * inquiry to stop too. 1255b9a6328fSJohan Hedberg */ 1256b9a6328fSJohan Hedberg if (has_pending_adv_report(hdev)) { 1257b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1258b9a6328fSJohan Hedberg 1259b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 1260ab0aa433SJohan Hedberg d->last_adv_addr_type, NULL, 1261c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags, 1262ab0aa433SJohan Hedberg d->last_adv_data, 1263b9a6328fSJohan Hedberg d->last_adv_data_len, NULL, 0); 1264b9a6328fSJohan Hedberg } 1265b9a6328fSJohan Hedberg 1266317ac8cbSJohan Hedberg /* Cancel this timer so that we don't try to disable scanning 1267317ac8cbSJohan Hedberg * when it's already disabled. 1268317ac8cbSJohan Hedberg */ 1269317ac8cbSJohan Hedberg cancel_delayed_work(&hdev->le_scan_disable); 1270317ac8cbSJohan Hedberg 1271a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_SCAN); 1272e8bb6b97SJohan Hedberg 127381ad6fd9SJohan Hedberg /* The HCI_LE_SCAN_INTERRUPTED flag indicates that we 127481ad6fd9SJohan Hedberg * interrupted scanning due to a connect request. Mark 1275e8bb6b97SJohan Hedberg * therefore discovery as stopped. If this was not 1276e8bb6b97SJohan Hedberg * because of a connect request advertising might have 1277e8bb6b97SJohan Hedberg * been disabled because of active scanning, so 1278e8bb6b97SJohan Hedberg * re-enable it again if necessary. 127981ad6fd9SJohan Hedberg */ 1280a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_LE_SCAN_INTERRUPTED)) 128181ad6fd9SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 1282d7a5a11dSMarcel Holtmann else if (!hci_dev_test_flag(hdev, HCI_LE_ADV) && 128334722277SJohan Hedberg hdev->discovery.state == DISCOVERY_FINDING) 1284f2252570SJohan Hedberg hci_req_reenable_advertising(hdev); 1285e8bb6b97SJohan Hedberg 128668a8aea4SAndrei Emeltchenko break; 128768a8aea4SAndrei Emeltchenko 128868a8aea4SAndrei Emeltchenko default: 12892064ee33SMarcel Holtmann bt_dev_err(hdev, "use of reserved LE_Scan_Enable param %d", 12903baef810SJaganath Kanakkassery enable); 129168a8aea4SAndrei Emeltchenko break; 129235815085SAndre Guedes } 12935c1a4c8fSJaganath Kanakkassery 12945c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 1295eb9d91f5SAndre Guedes } 1296eb9d91f5SAndre Guedes 12973baef810SJaganath Kanakkassery static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, 12983baef810SJaganath Kanakkassery struct sk_buff *skb) 12993baef810SJaganath Kanakkassery { 13003baef810SJaganath Kanakkassery struct hci_cp_le_set_scan_enable *cp; 13013baef810SJaganath Kanakkassery __u8 status = *((__u8 *) skb->data); 13023baef810SJaganath Kanakkassery 13033baef810SJaganath Kanakkassery BT_DBG("%s status 0x%2.2x", hdev->name, status); 13043baef810SJaganath Kanakkassery 13053baef810SJaganath Kanakkassery if (status) 13063baef810SJaganath Kanakkassery return; 13073baef810SJaganath Kanakkassery 13083baef810SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE); 13093baef810SJaganath Kanakkassery if (!cp) 13103baef810SJaganath Kanakkassery return; 13113baef810SJaganath Kanakkassery 13123baef810SJaganath Kanakkassery le_set_scan_enable_complete(hdev, cp->enable); 13133baef810SJaganath Kanakkassery } 13143baef810SJaganath Kanakkassery 1315a2344b9eSJaganath Kanakkassery static void hci_cc_le_set_ext_scan_enable(struct hci_dev *hdev, 1316a2344b9eSJaganath Kanakkassery struct sk_buff *skb) 1317a2344b9eSJaganath Kanakkassery { 1318a2344b9eSJaganath Kanakkassery struct hci_cp_le_set_ext_scan_enable *cp; 1319a2344b9eSJaganath Kanakkassery __u8 status = *((__u8 *) skb->data); 1320a2344b9eSJaganath Kanakkassery 1321a2344b9eSJaganath Kanakkassery BT_DBG("%s status 0x%2.2x", hdev->name, status); 1322a2344b9eSJaganath Kanakkassery 1323a2344b9eSJaganath Kanakkassery if (status) 1324a2344b9eSJaganath Kanakkassery return; 1325a2344b9eSJaganath Kanakkassery 1326a2344b9eSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_ENABLE); 1327a2344b9eSJaganath Kanakkassery if (!cp) 1328a2344b9eSJaganath Kanakkassery return; 1329a2344b9eSJaganath Kanakkassery 1330a2344b9eSJaganath Kanakkassery le_set_scan_enable_complete(hdev, cp->enable); 1331a2344b9eSJaganath Kanakkassery } 1332a2344b9eSJaganath Kanakkassery 13336b49bcb4SJaganath Kanakkassery static void hci_cc_le_read_num_adv_sets(struct hci_dev *hdev, 13346b49bcb4SJaganath Kanakkassery struct sk_buff *skb) 13356b49bcb4SJaganath Kanakkassery { 13366b49bcb4SJaganath Kanakkassery struct hci_rp_le_read_num_supported_adv_sets *rp = (void *) skb->data; 13376b49bcb4SJaganath Kanakkassery 13386b49bcb4SJaganath Kanakkassery BT_DBG("%s status 0x%2.2x No of Adv sets %u", hdev->name, rp->status, 13396b49bcb4SJaganath Kanakkassery rp->num_of_sets); 13406b49bcb4SJaganath Kanakkassery 13416b49bcb4SJaganath Kanakkassery if (rp->status) 13426b49bcb4SJaganath Kanakkassery return; 13436b49bcb4SJaganath Kanakkassery 13446b49bcb4SJaganath Kanakkassery hdev->le_num_of_adv_sets = rp->num_of_sets; 13456b49bcb4SJaganath Kanakkassery } 13466b49bcb4SJaganath Kanakkassery 1347cf1d081fSJohan Hedberg static void hci_cc_le_read_white_list_size(struct hci_dev *hdev, 1348cf1d081fSJohan Hedberg struct sk_buff *skb) 1349cf1d081fSJohan Hedberg { 1350cf1d081fSJohan Hedberg struct hci_rp_le_read_white_list_size *rp = (void *) skb->data; 1351cf1d081fSJohan Hedberg 1352cf1d081fSJohan Hedberg BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size); 1353cf1d081fSJohan Hedberg 135445296acdSMarcel Holtmann if (rp->status) 135545296acdSMarcel Holtmann return; 135645296acdSMarcel Holtmann 1357cf1d081fSJohan Hedberg hdev->le_white_list_size = rp->size; 1358cf1d081fSJohan Hedberg } 1359cf1d081fSJohan Hedberg 13600f36b589SMarcel Holtmann static void hci_cc_le_clear_white_list(struct hci_dev *hdev, 13610f36b589SMarcel Holtmann struct sk_buff *skb) 13620f36b589SMarcel Holtmann { 13630f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 13640f36b589SMarcel Holtmann 13650f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 13660f36b589SMarcel Holtmann 136745296acdSMarcel Holtmann if (status) 136845296acdSMarcel Holtmann return; 136945296acdSMarcel Holtmann 1370dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->le_white_list); 13710f36b589SMarcel Holtmann } 13720f36b589SMarcel Holtmann 13730f36b589SMarcel Holtmann static void hci_cc_le_add_to_white_list(struct hci_dev *hdev, 13740f36b589SMarcel Holtmann struct sk_buff *skb) 13750f36b589SMarcel Holtmann { 13760f36b589SMarcel Holtmann struct hci_cp_le_add_to_white_list *sent; 13770f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 13780f36b589SMarcel Holtmann 13790f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 13800f36b589SMarcel Holtmann 138145296acdSMarcel Holtmann if (status) 138245296acdSMarcel Holtmann return; 138345296acdSMarcel Holtmann 13840f36b589SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST); 13850f36b589SMarcel Holtmann if (!sent) 13860f36b589SMarcel Holtmann return; 13870f36b589SMarcel Holtmann 1388dcc36c16SJohan Hedberg hci_bdaddr_list_add(&hdev->le_white_list, &sent->bdaddr, 1389dcc36c16SJohan Hedberg sent->bdaddr_type); 13900f36b589SMarcel Holtmann } 13910f36b589SMarcel Holtmann 13920f36b589SMarcel Holtmann static void hci_cc_le_del_from_white_list(struct hci_dev *hdev, 13930f36b589SMarcel Holtmann struct sk_buff *skb) 13940f36b589SMarcel Holtmann { 13950f36b589SMarcel Holtmann struct hci_cp_le_del_from_white_list *sent; 13960f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 13970f36b589SMarcel Holtmann 13980f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 13990f36b589SMarcel Holtmann 140045296acdSMarcel Holtmann if (status) 140145296acdSMarcel Holtmann return; 140245296acdSMarcel Holtmann 14030f36b589SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST); 14040f36b589SMarcel Holtmann if (!sent) 14050f36b589SMarcel Holtmann return; 14060f36b589SMarcel Holtmann 1407dcc36c16SJohan Hedberg hci_bdaddr_list_del(&hdev->le_white_list, &sent->bdaddr, 1408dcc36c16SJohan Hedberg sent->bdaddr_type); 14090f36b589SMarcel Holtmann } 14100f36b589SMarcel Holtmann 14119b008c04SJohan Hedberg static void hci_cc_le_read_supported_states(struct hci_dev *hdev, 14129b008c04SJohan Hedberg struct sk_buff *skb) 14139b008c04SJohan Hedberg { 14149b008c04SJohan Hedberg struct hci_rp_le_read_supported_states *rp = (void *) skb->data; 14159b008c04SJohan Hedberg 14169b008c04SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 14179b008c04SJohan Hedberg 141845296acdSMarcel Holtmann if (rp->status) 141945296acdSMarcel Holtmann return; 142045296acdSMarcel Holtmann 14219b008c04SJohan Hedberg memcpy(hdev->le_states, rp->le_states, 8); 14229b008c04SJohan Hedberg } 14239b008c04SJohan Hedberg 1424a8e1bfaaSMarcel Holtmann static void hci_cc_le_read_def_data_len(struct hci_dev *hdev, 1425a8e1bfaaSMarcel Holtmann struct sk_buff *skb) 1426a8e1bfaaSMarcel Holtmann { 1427a8e1bfaaSMarcel Holtmann struct hci_rp_le_read_def_data_len *rp = (void *) skb->data; 1428a8e1bfaaSMarcel Holtmann 1429a8e1bfaaSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 1430a8e1bfaaSMarcel Holtmann 1431a8e1bfaaSMarcel Holtmann if (rp->status) 1432a8e1bfaaSMarcel Holtmann return; 1433a8e1bfaaSMarcel Holtmann 1434a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = le16_to_cpu(rp->tx_len); 1435a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = le16_to_cpu(rp->tx_time); 1436a8e1bfaaSMarcel Holtmann } 1437a8e1bfaaSMarcel Holtmann 1438a8e1bfaaSMarcel Holtmann static void hci_cc_le_write_def_data_len(struct hci_dev *hdev, 1439a8e1bfaaSMarcel Holtmann struct sk_buff *skb) 1440a8e1bfaaSMarcel Holtmann { 1441a8e1bfaaSMarcel Holtmann struct hci_cp_le_write_def_data_len *sent; 1442a8e1bfaaSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 1443a8e1bfaaSMarcel Holtmann 1444a8e1bfaaSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 1445a8e1bfaaSMarcel Holtmann 1446a8e1bfaaSMarcel Holtmann if (status) 1447a8e1bfaaSMarcel Holtmann return; 1448a8e1bfaaSMarcel Holtmann 1449a8e1bfaaSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN); 1450a8e1bfaaSMarcel Holtmann if (!sent) 1451a8e1bfaaSMarcel Holtmann return; 1452a8e1bfaaSMarcel Holtmann 1453a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = le16_to_cpu(sent->tx_len); 1454a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = le16_to_cpu(sent->tx_time); 1455a8e1bfaaSMarcel Holtmann } 1456a8e1bfaaSMarcel Holtmann 1457b950aa88SAnkit Navik static void hci_cc_le_add_to_resolv_list(struct hci_dev *hdev, 1458b950aa88SAnkit Navik struct sk_buff *skb) 1459b950aa88SAnkit Navik { 1460b950aa88SAnkit Navik struct hci_cp_le_add_to_resolv_list *sent; 1461b950aa88SAnkit Navik __u8 status = *((__u8 *) skb->data); 1462b950aa88SAnkit Navik 1463b950aa88SAnkit Navik BT_DBG("%s status 0x%2.2x", hdev->name, status); 1464b950aa88SAnkit Navik 1465b950aa88SAnkit Navik if (status) 1466b950aa88SAnkit Navik return; 1467b950aa88SAnkit Navik 1468b950aa88SAnkit Navik sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_RESOLV_LIST); 1469b950aa88SAnkit Navik if (!sent) 1470b950aa88SAnkit Navik return; 1471b950aa88SAnkit Navik 1472b950aa88SAnkit Navik hci_bdaddr_list_add_with_irk(&hdev->le_resolv_list, &sent->bdaddr, 1473b950aa88SAnkit Navik sent->bdaddr_type, sent->peer_irk, 1474b950aa88SAnkit Navik sent->local_irk); 1475b950aa88SAnkit Navik } 1476b950aa88SAnkit Navik 1477b950aa88SAnkit Navik static void hci_cc_le_del_from_resolv_list(struct hci_dev *hdev, 1478b950aa88SAnkit Navik struct sk_buff *skb) 1479b950aa88SAnkit Navik { 1480b950aa88SAnkit Navik struct hci_cp_le_del_from_resolv_list *sent; 1481b950aa88SAnkit Navik __u8 status = *((__u8 *) skb->data); 1482b950aa88SAnkit Navik 1483b950aa88SAnkit Navik BT_DBG("%s status 0x%2.2x", hdev->name, status); 1484b950aa88SAnkit Navik 1485b950aa88SAnkit Navik if (status) 1486b950aa88SAnkit Navik return; 1487b950aa88SAnkit Navik 1488b950aa88SAnkit Navik sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_RESOLV_LIST); 1489b950aa88SAnkit Navik if (!sent) 1490b950aa88SAnkit Navik return; 1491b950aa88SAnkit Navik 1492b950aa88SAnkit Navik hci_bdaddr_list_del_with_irk(&hdev->le_resolv_list, &sent->bdaddr, 1493b950aa88SAnkit Navik sent->bdaddr_type); 1494b950aa88SAnkit Navik } 1495b950aa88SAnkit Navik 1496545f2596SAnkit Navik static void hci_cc_le_clear_resolv_list(struct hci_dev *hdev, 1497545f2596SAnkit Navik struct sk_buff *skb) 1498545f2596SAnkit Navik { 1499545f2596SAnkit Navik __u8 status = *((__u8 *) skb->data); 1500545f2596SAnkit Navik 1501545f2596SAnkit Navik BT_DBG("%s status 0x%2.2x", hdev->name, status); 1502545f2596SAnkit Navik 1503545f2596SAnkit Navik if (status) 1504545f2596SAnkit Navik return; 1505545f2596SAnkit Navik 1506545f2596SAnkit Navik hci_bdaddr_list_clear(&hdev->le_resolv_list); 1507545f2596SAnkit Navik } 1508545f2596SAnkit Navik 1509cfdb0c2dSAnkit Navik static void hci_cc_le_read_resolv_list_size(struct hci_dev *hdev, 1510cfdb0c2dSAnkit Navik struct sk_buff *skb) 1511cfdb0c2dSAnkit Navik { 1512cfdb0c2dSAnkit Navik struct hci_rp_le_read_resolv_list_size *rp = (void *) skb->data; 1513cfdb0c2dSAnkit Navik 1514cfdb0c2dSAnkit Navik BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size); 1515cfdb0c2dSAnkit Navik 1516cfdb0c2dSAnkit Navik if (rp->status) 1517cfdb0c2dSAnkit Navik return; 1518cfdb0c2dSAnkit Navik 1519cfdb0c2dSAnkit Navik hdev->le_resolv_list_size = rp->size; 1520cfdb0c2dSAnkit Navik } 1521cfdb0c2dSAnkit Navik 1522aa12af77SAnkit Navik static void hci_cc_le_set_addr_resolution_enable(struct hci_dev *hdev, 1523aa12af77SAnkit Navik struct sk_buff *skb) 1524aa12af77SAnkit Navik { 1525aa12af77SAnkit Navik __u8 *sent, status = *((__u8 *) skb->data); 1526aa12af77SAnkit Navik 1527aa12af77SAnkit Navik BT_DBG("%s status 0x%2.2x", hdev->name, status); 1528aa12af77SAnkit Navik 1529aa12af77SAnkit Navik if (status) 1530aa12af77SAnkit Navik return; 1531aa12af77SAnkit Navik 1532aa12af77SAnkit Navik sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE); 1533aa12af77SAnkit Navik if (!sent) 1534aa12af77SAnkit Navik return; 1535aa12af77SAnkit Navik 1536aa12af77SAnkit Navik hci_dev_lock(hdev); 1537aa12af77SAnkit Navik 1538aa12af77SAnkit Navik if (*sent) 1539aa12af77SAnkit Navik hci_dev_set_flag(hdev, HCI_LL_RPA_RESOLUTION); 1540aa12af77SAnkit Navik else 1541aa12af77SAnkit Navik hci_dev_clear_flag(hdev, HCI_LL_RPA_RESOLUTION); 1542aa12af77SAnkit Navik 1543aa12af77SAnkit Navik hci_dev_unlock(hdev); 1544aa12af77SAnkit Navik } 1545aa12af77SAnkit Navik 1546a8e1bfaaSMarcel Holtmann static void hci_cc_le_read_max_data_len(struct hci_dev *hdev, 1547a8e1bfaaSMarcel Holtmann struct sk_buff *skb) 1548a8e1bfaaSMarcel Holtmann { 1549a8e1bfaaSMarcel Holtmann struct hci_rp_le_read_max_data_len *rp = (void *) skb->data; 1550a8e1bfaaSMarcel Holtmann 1551a8e1bfaaSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 1552a8e1bfaaSMarcel Holtmann 1553a8e1bfaaSMarcel Holtmann if (rp->status) 1554a8e1bfaaSMarcel Holtmann return; 1555a8e1bfaaSMarcel Holtmann 1556a8e1bfaaSMarcel Holtmann hdev->le_max_tx_len = le16_to_cpu(rp->tx_len); 1557a8e1bfaaSMarcel Holtmann hdev->le_max_tx_time = le16_to_cpu(rp->tx_time); 1558a8e1bfaaSMarcel Holtmann hdev->le_max_rx_len = le16_to_cpu(rp->rx_len); 1559a8e1bfaaSMarcel Holtmann hdev->le_max_rx_time = le16_to_cpu(rp->rx_time); 1560a8e1bfaaSMarcel Holtmann } 1561a8e1bfaaSMarcel Holtmann 15626039aa73SGustavo Padovan static void hci_cc_write_le_host_supported(struct hci_dev *hdev, 1563f9b49306SAndre Guedes struct sk_buff *skb) 1564f9b49306SAndre Guedes { 156506199cf8SJohan Hedberg struct hci_cp_write_le_host_supported *sent; 1566f9b49306SAndre Guedes __u8 status = *((__u8 *) skb->data); 1567f9b49306SAndre Guedes 15689f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1569f9b49306SAndre Guedes 157045296acdSMarcel Holtmann if (status) 157145296acdSMarcel Holtmann return; 157245296acdSMarcel Holtmann 157306199cf8SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED); 15748f984dfaSJohan Hedberg if (!sent) 1575f9b49306SAndre Guedes return; 1576f9b49306SAndre Guedes 15775c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 15785c1a4c8fSJaganath Kanakkassery 1579416a4ae5SJohan Hedberg if (sent->le) { 1580cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE; 1581a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ENABLED); 1582416a4ae5SJohan Hedberg } else { 1583cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE; 1584a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ENABLED); 1585a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_ADVERTISING); 1586416a4ae5SJohan Hedberg } 158753b2caabSJohan Hedberg 158853b2caabSJohan Hedberg if (sent->simul) 1589cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE_BREDR; 159053b2caabSJohan Hedberg else 1591cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE_BREDR; 15925c1a4c8fSJaganath Kanakkassery 15935c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 15948f984dfaSJohan Hedberg } 1595f9b49306SAndre Guedes 159656ed2cb8SJohan Hedberg static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb) 159756ed2cb8SJohan Hedberg { 159856ed2cb8SJohan Hedberg struct hci_cp_le_set_adv_param *cp; 159956ed2cb8SJohan Hedberg u8 status = *((u8 *) skb->data); 160056ed2cb8SJohan Hedberg 160156ed2cb8SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 160256ed2cb8SJohan Hedberg 160356ed2cb8SJohan Hedberg if (status) 160456ed2cb8SJohan Hedberg return; 160556ed2cb8SJohan Hedberg 160656ed2cb8SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM); 160756ed2cb8SJohan Hedberg if (!cp) 160856ed2cb8SJohan Hedberg return; 160956ed2cb8SJohan Hedberg 161056ed2cb8SJohan Hedberg hci_dev_lock(hdev); 161156ed2cb8SJohan Hedberg hdev->adv_addr_type = cp->own_address_type; 161256ed2cb8SJohan Hedberg hci_dev_unlock(hdev); 161356ed2cb8SJohan Hedberg } 161456ed2cb8SJohan Hedberg 1615de181e88SJaganath Kanakkassery static void hci_cc_set_ext_adv_param(struct hci_dev *hdev, struct sk_buff *skb) 1616de181e88SJaganath Kanakkassery { 1617de181e88SJaganath Kanakkassery struct hci_rp_le_set_ext_adv_params *rp = (void *) skb->data; 1618de181e88SJaganath Kanakkassery struct hci_cp_le_set_ext_adv_params *cp; 1619de181e88SJaganath Kanakkassery struct adv_info *adv_instance; 1620de181e88SJaganath Kanakkassery 1621de181e88SJaganath Kanakkassery BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 1622de181e88SJaganath Kanakkassery 1623de181e88SJaganath Kanakkassery if (rp->status) 1624de181e88SJaganath Kanakkassery return; 1625de181e88SJaganath Kanakkassery 1626de181e88SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS); 1627de181e88SJaganath Kanakkassery if (!cp) 1628de181e88SJaganath Kanakkassery return; 1629de181e88SJaganath Kanakkassery 1630de181e88SJaganath Kanakkassery hci_dev_lock(hdev); 1631de181e88SJaganath Kanakkassery hdev->adv_addr_type = cp->own_addr_type; 1632de181e88SJaganath Kanakkassery if (!hdev->cur_adv_instance) { 1633de181e88SJaganath Kanakkassery /* Store in hdev for instance 0 */ 1634de181e88SJaganath Kanakkassery hdev->adv_tx_power = rp->tx_power; 1635de181e88SJaganath Kanakkassery } else { 1636de181e88SJaganath Kanakkassery adv_instance = hci_find_adv_instance(hdev, 1637de181e88SJaganath Kanakkassery hdev->cur_adv_instance); 1638de181e88SJaganath Kanakkassery if (adv_instance) 1639de181e88SJaganath Kanakkassery adv_instance->tx_power = rp->tx_power; 1640de181e88SJaganath Kanakkassery } 1641a0fb3726SJaganath Kanakkassery /* Update adv data as tx power is known now */ 1642a0fb3726SJaganath Kanakkassery hci_req_update_adv_data(hdev, hdev->cur_adv_instance); 1643de181e88SJaganath Kanakkassery hci_dev_unlock(hdev); 1644de181e88SJaganath Kanakkassery } 1645de181e88SJaganath Kanakkassery 16465ae76a94SAndrzej Kaczmarek static void hci_cc_read_rssi(struct hci_dev *hdev, struct sk_buff *skb) 16475ae76a94SAndrzej Kaczmarek { 16485ae76a94SAndrzej Kaczmarek struct hci_rp_read_rssi *rp = (void *) skb->data; 16495ae76a94SAndrzej Kaczmarek struct hci_conn *conn; 16505ae76a94SAndrzej Kaczmarek 16515ae76a94SAndrzej Kaczmarek BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 16525ae76a94SAndrzej Kaczmarek 16535ae76a94SAndrzej Kaczmarek if (rp->status) 16545ae76a94SAndrzej Kaczmarek return; 16555ae76a94SAndrzej Kaczmarek 16565ae76a94SAndrzej Kaczmarek hci_dev_lock(hdev); 16575ae76a94SAndrzej Kaczmarek 16585ae76a94SAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 16595ae76a94SAndrzej Kaczmarek if (conn) 16605ae76a94SAndrzej Kaczmarek conn->rssi = rp->rssi; 16615ae76a94SAndrzej Kaczmarek 16625ae76a94SAndrzej Kaczmarek hci_dev_unlock(hdev); 16635ae76a94SAndrzej Kaczmarek } 16645ae76a94SAndrzej Kaczmarek 16655a134faeSAndrzej Kaczmarek static void hci_cc_read_tx_power(struct hci_dev *hdev, struct sk_buff *skb) 16665a134faeSAndrzej Kaczmarek { 16675a134faeSAndrzej Kaczmarek struct hci_cp_read_tx_power *sent; 16685a134faeSAndrzej Kaczmarek struct hci_rp_read_tx_power *rp = (void *) skb->data; 16695a134faeSAndrzej Kaczmarek struct hci_conn *conn; 16705a134faeSAndrzej Kaczmarek 16715a134faeSAndrzej Kaczmarek BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 16725a134faeSAndrzej Kaczmarek 16735a134faeSAndrzej Kaczmarek if (rp->status) 16745a134faeSAndrzej Kaczmarek return; 16755a134faeSAndrzej Kaczmarek 16765a134faeSAndrzej Kaczmarek sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER); 16775a134faeSAndrzej Kaczmarek if (!sent) 16785a134faeSAndrzej Kaczmarek return; 16795a134faeSAndrzej Kaczmarek 16805a134faeSAndrzej Kaczmarek hci_dev_lock(hdev); 16815a134faeSAndrzej Kaczmarek 16825a134faeSAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 1683d0455ed9SAndrzej Kaczmarek if (!conn) 1684d0455ed9SAndrzej Kaczmarek goto unlock; 16855a134faeSAndrzej Kaczmarek 1686d0455ed9SAndrzej Kaczmarek switch (sent->type) { 1687d0455ed9SAndrzej Kaczmarek case 0x00: 1688d0455ed9SAndrzej Kaczmarek conn->tx_power = rp->tx_power; 1689d0455ed9SAndrzej Kaczmarek break; 1690d0455ed9SAndrzej Kaczmarek case 0x01: 1691d0455ed9SAndrzej Kaczmarek conn->max_tx_power = rp->tx_power; 1692d0455ed9SAndrzej Kaczmarek break; 1693d0455ed9SAndrzej Kaczmarek } 1694d0455ed9SAndrzej Kaczmarek 1695d0455ed9SAndrzej Kaczmarek unlock: 16965a134faeSAndrzej Kaczmarek hci_dev_unlock(hdev); 16975a134faeSAndrzej Kaczmarek } 16985a134faeSAndrzej Kaczmarek 1699c50b33c8SMarcel Holtmann static void hci_cc_write_ssp_debug_mode(struct hci_dev *hdev, struct sk_buff *skb) 1700c50b33c8SMarcel Holtmann { 1701c50b33c8SMarcel Holtmann u8 status = *((u8 *) skb->data); 1702c50b33c8SMarcel Holtmann u8 *mode; 1703c50b33c8SMarcel Holtmann 1704c50b33c8SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 1705c50b33c8SMarcel Holtmann 1706c50b33c8SMarcel Holtmann if (status) 1707c50b33c8SMarcel Holtmann return; 1708c50b33c8SMarcel Holtmann 1709c50b33c8SMarcel Holtmann mode = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE); 1710c50b33c8SMarcel Holtmann if (mode) 1711c50b33c8SMarcel Holtmann hdev->ssp_debug_mode = *mode; 1712c50b33c8SMarcel Holtmann } 1713c50b33c8SMarcel Holtmann 17146039aa73SGustavo Padovan static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) 1715a9de9248SMarcel Holtmann { 17169f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1717a9de9248SMarcel Holtmann 1718a9de9248SMarcel Holtmann if (status) { 1719a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 1720314b2381SJohan Hedberg return; 1721314b2381SJohan Hedberg } 1722314b2381SJohan Hedberg 172389352e7dSAndre Guedes set_bit(HCI_INQUIRY, &hdev->flags); 1724a9de9248SMarcel Holtmann } 1725a9de9248SMarcel Holtmann 17266039aa73SGustavo Padovan static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) 17271da177e4SLinus Torvalds { 1728a9de9248SMarcel Holtmann struct hci_cp_create_conn *cp; 17291da177e4SLinus Torvalds struct hci_conn *conn; 17301da177e4SLinus Torvalds 17319f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1732a9de9248SMarcel Holtmann 1733a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN); 17341da177e4SLinus Torvalds if (!cp) 17351da177e4SLinus Torvalds return; 17361da177e4SLinus Torvalds 17371da177e4SLinus Torvalds hci_dev_lock(hdev); 17381da177e4SLinus Torvalds 17391da177e4SLinus Torvalds conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 17401da177e4SLinus Torvalds 17416ed93dc6SAndrei Emeltchenko BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn); 17421da177e4SLinus Torvalds 17431da177e4SLinus Torvalds if (status) { 17441da177e4SLinus Torvalds if (conn && conn->state == BT_CONNECT) { 17454c67bc74SMarcel Holtmann if (status != 0x0c || conn->attempt > 2) { 17461da177e4SLinus Torvalds conn->state = BT_CLOSED; 1747539c496dSJohan Hedberg hci_connect_cfm(conn, status); 17481da177e4SLinus Torvalds hci_conn_del(conn); 17494c67bc74SMarcel Holtmann } else 17504c67bc74SMarcel Holtmann conn->state = BT_CONNECT2; 17511da177e4SLinus Torvalds } 17521da177e4SLinus Torvalds } else { 17531da177e4SLinus Torvalds if (!conn) { 1754a5c4e309SJohan Hedberg conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr, 1755a5c4e309SJohan Hedberg HCI_ROLE_MASTER); 1756a5c4e309SJohan Hedberg if (!conn) 17572064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for new connection"); 17581da177e4SLinus Torvalds } 17591da177e4SLinus Torvalds } 17601da177e4SLinus Torvalds 17611da177e4SLinus Torvalds hci_dev_unlock(hdev); 17621da177e4SLinus Torvalds } 17631da177e4SLinus Torvalds 1764a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status) 17651da177e4SLinus Torvalds { 1766a9de9248SMarcel Holtmann struct hci_cp_add_sco *cp; 17671da177e4SLinus Torvalds struct hci_conn *acl, *sco; 17681da177e4SLinus Torvalds __u16 handle; 17691da177e4SLinus Torvalds 17709f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1771b6a0dc82SMarcel Holtmann 1772a9de9248SMarcel Holtmann if (!status) 1773a9de9248SMarcel Holtmann return; 1774a9de9248SMarcel Holtmann 1775a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO); 17761da177e4SLinus Torvalds if (!cp) 1777a9de9248SMarcel Holtmann return; 17781da177e4SLinus Torvalds 17791da177e4SLinus Torvalds handle = __le16_to_cpu(cp->handle); 17801da177e4SLinus Torvalds 17819f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, handle); 17821da177e4SLinus Torvalds 17831da177e4SLinus Torvalds hci_dev_lock(hdev); 17841da177e4SLinus Torvalds 17851da177e4SLinus Torvalds acl = hci_conn_hash_lookup_handle(hdev, handle); 17865a08ecceSAndrei Emeltchenko if (acl) { 17875a08ecceSAndrei Emeltchenko sco = acl->link; 17885a08ecceSAndrei Emeltchenko if (sco) { 17891da177e4SLinus Torvalds sco->state = BT_CLOSED; 17901da177e4SLinus Torvalds 1791539c496dSJohan Hedberg hci_connect_cfm(sco, status); 17921da177e4SLinus Torvalds hci_conn_del(sco); 17931da177e4SLinus Torvalds } 17945a08ecceSAndrei Emeltchenko } 17951da177e4SLinus Torvalds 17961da177e4SLinus Torvalds hci_dev_unlock(hdev); 17971da177e4SLinus Torvalds } 17981da177e4SLinus Torvalds 1799f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status) 1800f8558555SMarcel Holtmann { 1801f8558555SMarcel Holtmann struct hci_cp_auth_requested *cp; 1802f8558555SMarcel Holtmann struct hci_conn *conn; 1803f8558555SMarcel Holtmann 18049f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1805f8558555SMarcel Holtmann 1806f8558555SMarcel Holtmann if (!status) 1807f8558555SMarcel Holtmann return; 1808f8558555SMarcel Holtmann 1809f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED); 1810f8558555SMarcel Holtmann if (!cp) 1811f8558555SMarcel Holtmann return; 1812f8558555SMarcel Holtmann 1813f8558555SMarcel Holtmann hci_dev_lock(hdev); 1814f8558555SMarcel Holtmann 1815f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1816f8558555SMarcel Holtmann if (conn) { 1817f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1818539c496dSJohan Hedberg hci_connect_cfm(conn, status); 181976a68ba0SDavid Herrmann hci_conn_drop(conn); 1820f8558555SMarcel Holtmann } 1821f8558555SMarcel Holtmann } 1822f8558555SMarcel Holtmann 1823f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1824f8558555SMarcel Holtmann } 1825f8558555SMarcel Holtmann 1826f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) 1827f8558555SMarcel Holtmann { 1828f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt *cp; 1829f8558555SMarcel Holtmann struct hci_conn *conn; 1830f8558555SMarcel Holtmann 18319f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1832f8558555SMarcel Holtmann 1833f8558555SMarcel Holtmann if (!status) 1834f8558555SMarcel Holtmann return; 1835f8558555SMarcel Holtmann 1836f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT); 1837f8558555SMarcel Holtmann if (!cp) 1838f8558555SMarcel Holtmann return; 1839f8558555SMarcel Holtmann 1840f8558555SMarcel Holtmann hci_dev_lock(hdev); 1841f8558555SMarcel Holtmann 1842f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1843f8558555SMarcel Holtmann if (conn) { 1844f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1845539c496dSJohan Hedberg hci_connect_cfm(conn, status); 184676a68ba0SDavid Herrmann hci_conn_drop(conn); 1847f8558555SMarcel Holtmann } 1848f8558555SMarcel Holtmann } 1849f8558555SMarcel Holtmann 1850f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1851f8558555SMarcel Holtmann } 1852f8558555SMarcel Holtmann 1853127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev, 1854392599b9SJohan Hedberg struct hci_conn *conn) 1855392599b9SJohan Hedberg { 1856392599b9SJohan Hedberg if (conn->state != BT_CONFIG || !conn->out) 1857392599b9SJohan Hedberg return 0; 1858392599b9SJohan Hedberg 1859765c2a96SJohan Hedberg if (conn->pending_sec_level == BT_SECURITY_SDP) 1860392599b9SJohan Hedberg return 0; 1861392599b9SJohan Hedberg 1862392599b9SJohan Hedberg /* Only request authentication for SSP connections or non-SSP 1863264b8b4eSJohan Hedberg * devices with sec_level MEDIUM or HIGH or if MITM protection 1864264b8b4eSJohan Hedberg * is requested. 1865264b8b4eSJohan Hedberg */ 1866807deac2SGustavo Padovan if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) && 18677e3691e1SJohan Hedberg conn->pending_sec_level != BT_SECURITY_FIPS && 1868264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_HIGH && 1869264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_MEDIUM) 1870392599b9SJohan Hedberg return 0; 1871392599b9SJohan Hedberg 1872392599b9SJohan Hedberg return 1; 1873392599b9SJohan Hedberg } 1874392599b9SJohan Hedberg 18756039aa73SGustavo Padovan static int hci_resolve_name(struct hci_dev *hdev, 187600abfe44SGustavo F. Padovan struct inquiry_entry *e) 187730dc78e1SJohan Hedberg { 187830dc78e1SJohan Hedberg struct hci_cp_remote_name_req cp; 187930dc78e1SJohan Hedberg 188030dc78e1SJohan Hedberg memset(&cp, 0, sizeof(cp)); 188130dc78e1SJohan Hedberg 188230dc78e1SJohan Hedberg bacpy(&cp.bdaddr, &e->data.bdaddr); 188330dc78e1SJohan Hedberg cp.pscan_rep_mode = e->data.pscan_rep_mode; 188430dc78e1SJohan Hedberg cp.pscan_mode = e->data.pscan_mode; 188530dc78e1SJohan Hedberg cp.clock_offset = e->data.clock_offset; 188630dc78e1SJohan Hedberg 188730dc78e1SJohan Hedberg return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 188830dc78e1SJohan Hedberg } 188930dc78e1SJohan Hedberg 1890b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev) 189130dc78e1SJohan Hedberg { 189230dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 189330dc78e1SJohan Hedberg struct inquiry_entry *e; 189430dc78e1SJohan Hedberg 1895b644ba33SJohan Hedberg if (list_empty(&discov->resolve)) 1896b644ba33SJohan Hedberg return false; 1897b644ba33SJohan Hedberg 1898b644ba33SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 1899c810089cSRam Malovany if (!e) 1900c810089cSRam Malovany return false; 1901c810089cSRam Malovany 1902b644ba33SJohan Hedberg if (hci_resolve_name(hdev, e) == 0) { 1903b644ba33SJohan Hedberg e->name_state = NAME_PENDING; 1904b644ba33SJohan Hedberg return true; 1905b644ba33SJohan Hedberg } 1906b644ba33SJohan Hedberg 1907b644ba33SJohan Hedberg return false; 1908b644ba33SJohan Hedberg } 1909b644ba33SJohan Hedberg 1910b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, 1911b644ba33SJohan Hedberg bdaddr_t *bdaddr, u8 *name, u8 name_len) 1912b644ba33SJohan Hedberg { 1913b644ba33SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 1914b644ba33SJohan Hedberg struct inquiry_entry *e; 1915b644ba33SJohan Hedberg 191660cb49d2SJohan Hedberg /* Update the mgmt connected state if necessary. Be careful with 191760cb49d2SJohan Hedberg * conn objects that exist but are not (yet) connected however. 191860cb49d2SJohan Hedberg * Only those in BT_CONFIG or BT_CONNECTED states can be 191960cb49d2SJohan Hedberg * considered connected. 192060cb49d2SJohan Hedberg */ 192160cb49d2SJohan Hedberg if (conn && 192260cb49d2SJohan Hedberg (conn->state == BT_CONFIG || conn->state == BT_CONNECTED) && 1923cb77c3ecSJaganath Kanakkassery !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 192448ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, name, name_len); 1925b644ba33SJohan Hedberg 1926b644ba33SJohan Hedberg if (discov->state == DISCOVERY_STOPPED) 1927b644ba33SJohan Hedberg return; 1928b644ba33SJohan Hedberg 192930dc78e1SJohan Hedberg if (discov->state == DISCOVERY_STOPPING) 193030dc78e1SJohan Hedberg goto discov_complete; 193130dc78e1SJohan Hedberg 193230dc78e1SJohan Hedberg if (discov->state != DISCOVERY_RESOLVING) 193330dc78e1SJohan Hedberg return; 193430dc78e1SJohan Hedberg 193530dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING); 19367cc8380eSRam Malovany /* If the device was not found in a list of found devices names of which 19377cc8380eSRam Malovany * are pending. there is no need to continue resolving a next name as it 19387cc8380eSRam Malovany * will be done upon receiving another Remote Name Request Complete 19397cc8380eSRam Malovany * Event */ 19407cc8380eSRam Malovany if (!e) 19417cc8380eSRam Malovany return; 19427cc8380eSRam Malovany 194330dc78e1SJohan Hedberg list_del(&e->list); 19447cc8380eSRam Malovany if (name) { 19457cc8380eSRam Malovany e->name_state = NAME_KNOWN; 1946b644ba33SJohan Hedberg mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, 1947b644ba33SJohan Hedberg e->data.rssi, name, name_len); 1948c3e7c0d9SRam Malovany } else { 1949c3e7c0d9SRam Malovany e->name_state = NAME_NOT_KNOWN; 195030dc78e1SJohan Hedberg } 195130dc78e1SJohan Hedberg 1952b644ba33SJohan Hedberg if (hci_resolve_next_name(hdev)) 195330dc78e1SJohan Hedberg return; 195430dc78e1SJohan Hedberg 195530dc78e1SJohan Hedberg discov_complete: 195630dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 195730dc78e1SJohan Hedberg } 195830dc78e1SJohan Hedberg 1959a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) 19601da177e4SLinus Torvalds { 1961127178d2SJohan Hedberg struct hci_cp_remote_name_req *cp; 1962127178d2SJohan Hedberg struct hci_conn *conn; 1963127178d2SJohan Hedberg 19649f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1965127178d2SJohan Hedberg 1966127178d2SJohan Hedberg /* If successful wait for the name req complete event before 1967127178d2SJohan Hedberg * checking for the need to do authentication */ 1968127178d2SJohan Hedberg if (!status) 1969127178d2SJohan Hedberg return; 1970127178d2SJohan Hedberg 1971127178d2SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ); 1972127178d2SJohan Hedberg if (!cp) 1973127178d2SJohan Hedberg return; 1974127178d2SJohan Hedberg 1975127178d2SJohan Hedberg hci_dev_lock(hdev); 1976127178d2SJohan Hedberg 1977127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 1978b644ba33SJohan Hedberg 1979d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 1980b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0); 1981b644ba33SJohan Hedberg 198279c6c70cSJohan Hedberg if (!conn) 198379c6c70cSJohan Hedberg goto unlock; 198479c6c70cSJohan Hedberg 198579c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 198679c6c70cSJohan Hedberg goto unlock; 198779c6c70cSJohan Hedberg 198851a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 1989c1f23a2bSJohannes Berg struct hci_cp_auth_requested auth_cp; 1990c1f23a2bSJohannes Berg 1991977f8fceSJohan Hedberg set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags); 1992977f8fceSJohan Hedberg 1993c1f23a2bSJohannes Berg auth_cp.handle = __cpu_to_le16(conn->handle); 1994c1f23a2bSJohannes Berg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, 1995c1f23a2bSJohannes Berg sizeof(auth_cp), &auth_cp); 1996127178d2SJohan Hedberg } 1997127178d2SJohan Hedberg 199879c6c70cSJohan Hedberg unlock: 1999127178d2SJohan Hedberg hci_dev_unlock(hdev); 2000a9de9248SMarcel Holtmann } 20011da177e4SLinus Torvalds 2002769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) 2003769be974SMarcel Holtmann { 2004769be974SMarcel Holtmann struct hci_cp_read_remote_features *cp; 2005769be974SMarcel Holtmann struct hci_conn *conn; 2006769be974SMarcel Holtmann 20079f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 2008769be974SMarcel Holtmann 2009769be974SMarcel Holtmann if (!status) 2010769be974SMarcel Holtmann return; 2011769be974SMarcel Holtmann 2012769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES); 2013769be974SMarcel Holtmann if (!cp) 2014769be974SMarcel Holtmann return; 2015769be974SMarcel Holtmann 2016769be974SMarcel Holtmann hci_dev_lock(hdev); 2017769be974SMarcel Holtmann 2018769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2019769be974SMarcel Holtmann if (conn) { 2020769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 2021539c496dSJohan Hedberg hci_connect_cfm(conn, status); 202276a68ba0SDavid Herrmann hci_conn_drop(conn); 2023769be974SMarcel Holtmann } 2024769be974SMarcel Holtmann } 2025769be974SMarcel Holtmann 2026769be974SMarcel Holtmann hci_dev_unlock(hdev); 2027769be974SMarcel Holtmann } 2028769be974SMarcel Holtmann 2029769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status) 2030769be974SMarcel Holtmann { 2031769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features *cp; 2032769be974SMarcel Holtmann struct hci_conn *conn; 2033769be974SMarcel Holtmann 20349f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 2035769be974SMarcel Holtmann 2036769be974SMarcel Holtmann if (!status) 2037769be974SMarcel Holtmann return; 2038769be974SMarcel Holtmann 2039769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES); 2040769be974SMarcel Holtmann if (!cp) 2041769be974SMarcel Holtmann return; 2042769be974SMarcel Holtmann 2043769be974SMarcel Holtmann hci_dev_lock(hdev); 2044769be974SMarcel Holtmann 2045769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2046769be974SMarcel Holtmann if (conn) { 2047769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 2048539c496dSJohan Hedberg hci_connect_cfm(conn, status); 204976a68ba0SDavid Herrmann hci_conn_drop(conn); 2050769be974SMarcel Holtmann } 2051769be974SMarcel Holtmann } 2052769be974SMarcel Holtmann 2053769be974SMarcel Holtmann hci_dev_unlock(hdev); 2054769be974SMarcel Holtmann } 2055769be974SMarcel Holtmann 2056a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) 2057a9de9248SMarcel Holtmann { 2058b6a0dc82SMarcel Holtmann struct hci_cp_setup_sync_conn *cp; 2059b6a0dc82SMarcel Holtmann struct hci_conn *acl, *sco; 2060b6a0dc82SMarcel Holtmann __u16 handle; 2061b6a0dc82SMarcel Holtmann 20629f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 2063b6a0dc82SMarcel Holtmann 2064b6a0dc82SMarcel Holtmann if (!status) 2065b6a0dc82SMarcel Holtmann return; 2066b6a0dc82SMarcel Holtmann 2067b6a0dc82SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN); 2068b6a0dc82SMarcel Holtmann if (!cp) 2069b6a0dc82SMarcel Holtmann return; 2070b6a0dc82SMarcel Holtmann 2071b6a0dc82SMarcel Holtmann handle = __le16_to_cpu(cp->handle); 2072b6a0dc82SMarcel Holtmann 20739f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, handle); 2074b6a0dc82SMarcel Holtmann 2075b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 2076b6a0dc82SMarcel Holtmann 2077b6a0dc82SMarcel Holtmann acl = hci_conn_hash_lookup_handle(hdev, handle); 20785a08ecceSAndrei Emeltchenko if (acl) { 20795a08ecceSAndrei Emeltchenko sco = acl->link; 20805a08ecceSAndrei Emeltchenko if (sco) { 2081b6a0dc82SMarcel Holtmann sco->state = BT_CLOSED; 2082b6a0dc82SMarcel Holtmann 2083539c496dSJohan Hedberg hci_connect_cfm(sco, status); 2084b6a0dc82SMarcel Holtmann hci_conn_del(sco); 2085b6a0dc82SMarcel Holtmann } 20865a08ecceSAndrei Emeltchenko } 2087b6a0dc82SMarcel Holtmann 2088b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 2089a9de9248SMarcel Holtmann } 2090a9de9248SMarcel Holtmann 2091a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) 2092a9de9248SMarcel Holtmann { 2093a9de9248SMarcel Holtmann struct hci_cp_sniff_mode *cp; 209404837f64SMarcel Holtmann struct hci_conn *conn; 209504837f64SMarcel Holtmann 20969f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 2097a9de9248SMarcel Holtmann 2098a9de9248SMarcel Holtmann if (!status) 2099a9de9248SMarcel Holtmann return; 2100a9de9248SMarcel Holtmann 2101a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE); 210204837f64SMarcel Holtmann if (!cp) 2103a9de9248SMarcel Holtmann return; 210404837f64SMarcel Holtmann 210504837f64SMarcel Holtmann hci_dev_lock(hdev); 210604837f64SMarcel Holtmann 210704837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2108e73439d8SMarcel Holtmann if (conn) { 210951a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 211004837f64SMarcel Holtmann 211151a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 2112e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 2113e73439d8SMarcel Holtmann } 2114e73439d8SMarcel Holtmann 211504837f64SMarcel Holtmann hci_dev_unlock(hdev); 211604837f64SMarcel Holtmann } 211704837f64SMarcel Holtmann 2118a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) 2119a9de9248SMarcel Holtmann { 2120a9de9248SMarcel Holtmann struct hci_cp_exit_sniff_mode *cp; 212104837f64SMarcel Holtmann struct hci_conn *conn; 212204837f64SMarcel Holtmann 21239f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 2124a9de9248SMarcel Holtmann 2125a9de9248SMarcel Holtmann if (!status) 2126a9de9248SMarcel Holtmann return; 2127a9de9248SMarcel Holtmann 2128a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE); 212904837f64SMarcel Holtmann if (!cp) 2130a9de9248SMarcel Holtmann return; 213104837f64SMarcel Holtmann 213204837f64SMarcel Holtmann hci_dev_lock(hdev); 213304837f64SMarcel Holtmann 213404837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2135e73439d8SMarcel Holtmann if (conn) { 213651a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 213704837f64SMarcel Holtmann 213851a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 2139e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 2140e73439d8SMarcel Holtmann } 2141e73439d8SMarcel Holtmann 214204837f64SMarcel Holtmann hci_dev_unlock(hdev); 214304837f64SMarcel Holtmann } 214404837f64SMarcel Holtmann 214588c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) 214688c3df13SJohan Hedberg { 214788c3df13SJohan Hedberg struct hci_cp_disconnect *cp; 214888c3df13SJohan Hedberg struct hci_conn *conn; 214988c3df13SJohan Hedberg 215088c3df13SJohan Hedberg if (!status) 215188c3df13SJohan Hedberg return; 215288c3df13SJohan Hedberg 215388c3df13SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT); 215488c3df13SJohan Hedberg if (!cp) 215588c3df13SJohan Hedberg return; 215688c3df13SJohan Hedberg 215788c3df13SJohan Hedberg hci_dev_lock(hdev); 215888c3df13SJohan Hedberg 215988c3df13SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 216088c3df13SJohan Hedberg if (conn) 216188c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 216288c3df13SJohan Hedberg conn->dst_type, status); 216388c3df13SJohan Hedberg 216488c3df13SJohan Hedberg hci_dev_unlock(hdev); 216588c3df13SJohan Hedberg } 216688c3df13SJohan Hedberg 2167d12fb056SJaganath Kanakkassery static void cs_le_create_conn(struct hci_dev *hdev, bdaddr_t *peer_addr, 2168d12fb056SJaganath Kanakkassery u8 peer_addr_type, u8 own_address_type, 2169d12fb056SJaganath Kanakkassery u8 filter_policy) 2170d12fb056SJaganath Kanakkassery { 2171d12fb056SJaganath Kanakkassery struct hci_conn *conn; 2172d12fb056SJaganath Kanakkassery 2173d12fb056SJaganath Kanakkassery conn = hci_conn_hash_lookup_le(hdev, peer_addr, 2174d12fb056SJaganath Kanakkassery peer_addr_type); 2175d12fb056SJaganath Kanakkassery if (!conn) 2176d12fb056SJaganath Kanakkassery return; 2177d12fb056SJaganath Kanakkassery 2178d12fb056SJaganath Kanakkassery /* Store the initiator and responder address information which 2179d12fb056SJaganath Kanakkassery * is needed for SMP. These values will not change during the 2180d12fb056SJaganath Kanakkassery * lifetime of the connection. 2181d12fb056SJaganath Kanakkassery */ 2182d12fb056SJaganath Kanakkassery conn->init_addr_type = own_address_type; 2183d12fb056SJaganath Kanakkassery if (own_address_type == ADDR_LE_DEV_RANDOM) 2184d12fb056SJaganath Kanakkassery bacpy(&conn->init_addr, &hdev->random_addr); 2185d12fb056SJaganath Kanakkassery else 2186d12fb056SJaganath Kanakkassery bacpy(&conn->init_addr, &hdev->bdaddr); 2187d12fb056SJaganath Kanakkassery 2188d12fb056SJaganath Kanakkassery conn->resp_addr_type = peer_addr_type; 2189d12fb056SJaganath Kanakkassery bacpy(&conn->resp_addr, peer_addr); 2190d12fb056SJaganath Kanakkassery 2191d12fb056SJaganath Kanakkassery /* We don't want the connection attempt to stick around 2192d12fb056SJaganath Kanakkassery * indefinitely since LE doesn't have a page timeout concept 2193d12fb056SJaganath Kanakkassery * like BR/EDR. Set a timer for any connection that doesn't use 2194d12fb056SJaganath Kanakkassery * the white list for connecting. 2195d12fb056SJaganath Kanakkassery */ 2196d12fb056SJaganath Kanakkassery if (filter_policy == HCI_LE_USE_PEER_ADDR) 2197d12fb056SJaganath Kanakkassery queue_delayed_work(conn->hdev->workqueue, 2198d12fb056SJaganath Kanakkassery &conn->le_conn_timeout, 2199d12fb056SJaganath Kanakkassery conn->conn_timeout); 2200d12fb056SJaganath Kanakkassery } 2201d12fb056SJaganath Kanakkassery 2202cb1d68f7SJohan Hedberg static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status) 2203cb1d68f7SJohan Hedberg { 2204cb1d68f7SJohan Hedberg struct hci_cp_le_create_conn *cp; 2205cb1d68f7SJohan Hedberg 2206cb1d68f7SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 2207cb1d68f7SJohan Hedberg 2208cb1d68f7SJohan Hedberg /* All connection failure handling is taken care of by the 2209cb1d68f7SJohan Hedberg * hci_le_conn_failed function which is triggered by the HCI 2210cb1d68f7SJohan Hedberg * request completion callbacks used for connecting. 2211cb1d68f7SJohan Hedberg */ 2212cb1d68f7SJohan Hedberg if (status) 2213cb1d68f7SJohan Hedberg return; 2214cb1d68f7SJohan Hedberg 2215cb1d68f7SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN); 2216cb1d68f7SJohan Hedberg if (!cp) 2217cb1d68f7SJohan Hedberg return; 2218cb1d68f7SJohan Hedberg 2219cb1d68f7SJohan Hedberg hci_dev_lock(hdev); 2220cb1d68f7SJohan Hedberg 2221d12fb056SJaganath Kanakkassery cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type, 2222d12fb056SJaganath Kanakkassery cp->own_address_type, cp->filter_policy); 2223cb1d68f7SJohan Hedberg 2224cb1d68f7SJohan Hedberg hci_dev_unlock(hdev); 2225cb1d68f7SJohan Hedberg } 2226cb1d68f7SJohan Hedberg 22274d94f95dSJaganath Kanakkassery static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status) 22284d94f95dSJaganath Kanakkassery { 22294d94f95dSJaganath Kanakkassery struct hci_cp_le_ext_create_conn *cp; 22304d94f95dSJaganath Kanakkassery 22314d94f95dSJaganath Kanakkassery BT_DBG("%s status 0x%2.2x", hdev->name, status); 22324d94f95dSJaganath Kanakkassery 22334d94f95dSJaganath Kanakkassery /* All connection failure handling is taken care of by the 22344d94f95dSJaganath Kanakkassery * hci_le_conn_failed function which is triggered by the HCI 22354d94f95dSJaganath Kanakkassery * request completion callbacks used for connecting. 22364d94f95dSJaganath Kanakkassery */ 22374d94f95dSJaganath Kanakkassery if (status) 22384d94f95dSJaganath Kanakkassery return; 22394d94f95dSJaganath Kanakkassery 22404d94f95dSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_EXT_CREATE_CONN); 22414d94f95dSJaganath Kanakkassery if (!cp) 22424d94f95dSJaganath Kanakkassery return; 22434d94f95dSJaganath Kanakkassery 22444d94f95dSJaganath Kanakkassery hci_dev_lock(hdev); 22454d94f95dSJaganath Kanakkassery 22464d94f95dSJaganath Kanakkassery cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type, 22474d94f95dSJaganath Kanakkassery cp->own_addr_type, cp->filter_policy); 22484d94f95dSJaganath Kanakkassery 22494d94f95dSJaganath Kanakkassery hci_dev_unlock(hdev); 22504d94f95dSJaganath Kanakkassery } 22514d94f95dSJaganath Kanakkassery 22520fe29fd1SMarcel Holtmann static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status) 22530fe29fd1SMarcel Holtmann { 22540fe29fd1SMarcel Holtmann struct hci_cp_le_read_remote_features *cp; 22550fe29fd1SMarcel Holtmann struct hci_conn *conn; 22560fe29fd1SMarcel Holtmann 22570fe29fd1SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 22580fe29fd1SMarcel Holtmann 22590fe29fd1SMarcel Holtmann if (!status) 22600fe29fd1SMarcel Holtmann return; 22610fe29fd1SMarcel Holtmann 22620fe29fd1SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_READ_REMOTE_FEATURES); 22630fe29fd1SMarcel Holtmann if (!cp) 22640fe29fd1SMarcel Holtmann return; 22650fe29fd1SMarcel Holtmann 22660fe29fd1SMarcel Holtmann hci_dev_lock(hdev); 22670fe29fd1SMarcel Holtmann 22680fe29fd1SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 22690fe29fd1SMarcel Holtmann if (conn) { 22700fe29fd1SMarcel Holtmann if (conn->state == BT_CONFIG) { 22710fe29fd1SMarcel Holtmann hci_connect_cfm(conn, status); 22720fe29fd1SMarcel Holtmann hci_conn_drop(conn); 22730fe29fd1SMarcel Holtmann } 22740fe29fd1SMarcel Holtmann } 22750fe29fd1SMarcel Holtmann 22760fe29fd1SMarcel Holtmann hci_dev_unlock(hdev); 22770fe29fd1SMarcel Holtmann } 22780fe29fd1SMarcel Holtmann 227981d0c8adSJohan Hedberg static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) 228081d0c8adSJohan Hedberg { 228181d0c8adSJohan Hedberg struct hci_cp_le_start_enc *cp; 228281d0c8adSJohan Hedberg struct hci_conn *conn; 228381d0c8adSJohan Hedberg 228481d0c8adSJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 228581d0c8adSJohan Hedberg 228681d0c8adSJohan Hedberg if (!status) 228781d0c8adSJohan Hedberg return; 228881d0c8adSJohan Hedberg 228981d0c8adSJohan Hedberg hci_dev_lock(hdev); 229081d0c8adSJohan Hedberg 229181d0c8adSJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC); 229281d0c8adSJohan Hedberg if (!cp) 229381d0c8adSJohan Hedberg goto unlock; 229481d0c8adSJohan Hedberg 229581d0c8adSJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 229681d0c8adSJohan Hedberg if (!conn) 229781d0c8adSJohan Hedberg goto unlock; 229881d0c8adSJohan Hedberg 229981d0c8adSJohan Hedberg if (conn->state != BT_CONNECTED) 230081d0c8adSJohan Hedberg goto unlock; 230181d0c8adSJohan Hedberg 230281d0c8adSJohan Hedberg hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 230381d0c8adSJohan Hedberg hci_conn_drop(conn); 230481d0c8adSJohan Hedberg 230581d0c8adSJohan Hedberg unlock: 230681d0c8adSJohan Hedberg hci_dev_unlock(hdev); 230781d0c8adSJohan Hedberg } 230881d0c8adSJohan Hedberg 230950fc85f1SKuba Pawlak static void hci_cs_switch_role(struct hci_dev *hdev, u8 status) 231050fc85f1SKuba Pawlak { 231150fc85f1SKuba Pawlak struct hci_cp_switch_role *cp; 231250fc85f1SKuba Pawlak struct hci_conn *conn; 231350fc85f1SKuba Pawlak 231450fc85f1SKuba Pawlak BT_DBG("%s status 0x%2.2x", hdev->name, status); 231550fc85f1SKuba Pawlak 231650fc85f1SKuba Pawlak if (!status) 231750fc85f1SKuba Pawlak return; 231850fc85f1SKuba Pawlak 231950fc85f1SKuba Pawlak cp = hci_sent_cmd_data(hdev, HCI_OP_SWITCH_ROLE); 232050fc85f1SKuba Pawlak if (!cp) 232150fc85f1SKuba Pawlak return; 232250fc85f1SKuba Pawlak 232350fc85f1SKuba Pawlak hci_dev_lock(hdev); 232450fc85f1SKuba Pawlak 232550fc85f1SKuba Pawlak conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 232650fc85f1SKuba Pawlak if (conn) 232750fc85f1SKuba Pawlak clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 232850fc85f1SKuba Pawlak 232950fc85f1SKuba Pawlak hci_dev_unlock(hdev); 233050fc85f1SKuba Pawlak } 233150fc85f1SKuba Pawlak 23326039aa73SGustavo Padovan static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 23331da177e4SLinus Torvalds { 23341da177e4SLinus Torvalds __u8 status = *((__u8 *) skb->data); 233530dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 233630dc78e1SJohan Hedberg struct inquiry_entry *e; 23371da177e4SLinus Torvalds 23389f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 23391da177e4SLinus Torvalds 2340a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 234189352e7dSAndre Guedes 234289352e7dSAndre Guedes if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) 234389352e7dSAndre Guedes return; 234489352e7dSAndre Guedes 23454e857c58SPeter Zijlstra smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */ 23463e13fa1eSAndre Guedes wake_up_bit(&hdev->flags, HCI_INQUIRY); 23473e13fa1eSAndre Guedes 2348d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 234930dc78e1SJohan Hedberg return; 235030dc78e1SJohan Hedberg 235156e5cb86SJohan Hedberg hci_dev_lock(hdev); 235230dc78e1SJohan Hedberg 2353343f935bSAndre Guedes if (discov->state != DISCOVERY_FINDING) 235430dc78e1SJohan Hedberg goto unlock; 235530dc78e1SJohan Hedberg 235630dc78e1SJohan Hedberg if (list_empty(&discov->resolve)) { 235707d2334aSJakub Pawlowski /* When BR/EDR inquiry is active and no LE scanning is in 235807d2334aSJakub Pawlowski * progress, then change discovery state to indicate completion. 235907d2334aSJakub Pawlowski * 236007d2334aSJakub Pawlowski * When running LE scanning and BR/EDR inquiry simultaneously 236107d2334aSJakub Pawlowski * and the LE scan already finished, then change the discovery 236207d2334aSJakub Pawlowski * state to indicate completion. 236307d2334aSJakub Pawlowski */ 236407d2334aSJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) || 236507d2334aSJakub Pawlowski !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks)) 2366ff9ef578SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 236730dc78e1SJohan Hedberg goto unlock; 236830dc78e1SJohan Hedberg } 236930dc78e1SJohan Hedberg 237030dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 237130dc78e1SJohan Hedberg if (e && hci_resolve_name(hdev, e) == 0) { 237230dc78e1SJohan Hedberg e->name_state = NAME_PENDING; 237330dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_RESOLVING); 237430dc78e1SJohan Hedberg } else { 237507d2334aSJakub Pawlowski /* When BR/EDR inquiry is active and no LE scanning is in 237607d2334aSJakub Pawlowski * progress, then change discovery state to indicate completion. 237707d2334aSJakub Pawlowski * 237807d2334aSJakub Pawlowski * When running LE scanning and BR/EDR inquiry simultaneously 237907d2334aSJakub Pawlowski * and the LE scan already finished, then change the discovery 238007d2334aSJakub Pawlowski * state to indicate completion. 238107d2334aSJakub Pawlowski */ 238207d2334aSJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) || 238307d2334aSJakub Pawlowski !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks)) 238430dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 238530dc78e1SJohan Hedberg } 238630dc78e1SJohan Hedberg 238730dc78e1SJohan Hedberg unlock: 238856e5cb86SJohan Hedberg hci_dev_unlock(hdev); 23891da177e4SLinus Torvalds } 23901da177e4SLinus Torvalds 23916039aa73SGustavo Padovan static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) 23921da177e4SLinus Torvalds { 239345bb4bf0SMarcel Holtmann struct inquiry_data data; 2394a9de9248SMarcel Holtmann struct inquiry_info *info = (void *) (skb->data + 1); 23951da177e4SLinus Torvalds int num_rsp = *((__u8 *) skb->data); 23961da177e4SLinus Torvalds 23971da177e4SLinus Torvalds BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 23981da177e4SLinus Torvalds 239945bb4bf0SMarcel Holtmann if (!num_rsp) 240045bb4bf0SMarcel Holtmann return; 240145bb4bf0SMarcel Holtmann 2402d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) 24031519cc17SAndre Guedes return; 24041519cc17SAndre Guedes 24051da177e4SLinus Torvalds hci_dev_lock(hdev); 240645bb4bf0SMarcel Holtmann 2407e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 2408af58925cSMarcel Holtmann u32 flags; 24093175405bSJohan Hedberg 24101da177e4SLinus Torvalds bacpy(&data.bdaddr, &info->bdaddr); 24111da177e4SLinus Torvalds data.pscan_rep_mode = info->pscan_rep_mode; 24121da177e4SLinus Torvalds data.pscan_period_mode = info->pscan_period_mode; 24131da177e4SLinus Torvalds data.pscan_mode = info->pscan_mode; 24141da177e4SLinus Torvalds memcpy(data.dev_class, info->dev_class, 3); 24151da177e4SLinus Torvalds data.clock_offset = info->clock_offset; 2416efb2513fSMarcel Holtmann data.rssi = HCI_RSSI_INVALID; 241741a96212SMarcel Holtmann data.ssp_mode = 0x00; 24183175405bSJohan Hedberg 2419af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 2420af58925cSMarcel Holtmann 242148264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 2422efb2513fSMarcel Holtmann info->dev_class, HCI_RSSI_INVALID, 2423efb2513fSMarcel Holtmann flags, NULL, 0, NULL, 0); 24241da177e4SLinus Torvalds } 242545bb4bf0SMarcel Holtmann 24261da177e4SLinus Torvalds hci_dev_unlock(hdev); 24271da177e4SLinus Torvalds } 24281da177e4SLinus Torvalds 24296039aa73SGustavo Padovan static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 24301da177e4SLinus Torvalds { 2431a9de9248SMarcel Holtmann struct hci_ev_conn_complete *ev = (void *) skb->data; 2432a9de9248SMarcel Holtmann struct hci_conn *conn; 24331da177e4SLinus Torvalds 2434a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 243545bb4bf0SMarcel Holtmann 24361da177e4SLinus Torvalds hci_dev_lock(hdev); 243745bb4bf0SMarcel Holtmann 2438a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 24399499237aSMarcel Holtmann if (!conn) { 24409499237aSMarcel Holtmann if (ev->link_type != SCO_LINK) 24419499237aSMarcel Holtmann goto unlock; 24429499237aSMarcel Holtmann 24439499237aSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 2444a9de9248SMarcel Holtmann if (!conn) 2445a9de9248SMarcel Holtmann goto unlock; 244645bb4bf0SMarcel Holtmann 24479499237aSMarcel Holtmann conn->type = SCO_LINK; 24489499237aSMarcel Holtmann } 24499499237aSMarcel Holtmann 2450a9de9248SMarcel Holtmann if (!ev->status) { 2451a9de9248SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 2452769be974SMarcel Holtmann 2453769be974SMarcel Holtmann if (conn->type == ACL_LINK) { 2454769be974SMarcel Holtmann conn->state = BT_CONFIG; 2455769be974SMarcel Holtmann hci_conn_hold(conn); 2456a9ea3ed9SSzymon Janc 2457a9ea3ed9SSzymon Janc if (!conn->out && !hci_conn_ssp_enabled(conn) && 2458a9ea3ed9SSzymon Janc !hci_find_link_key(hdev, &ev->bdaddr)) 2459a9ea3ed9SSzymon Janc conn->disc_timeout = HCI_PAIRING_TIMEOUT; 2460a9ea3ed9SSzymon Janc else 2461052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 2462769be974SMarcel Holtmann } else 2463a9de9248SMarcel Holtmann conn->state = BT_CONNECTED; 2464a9de9248SMarcel Holtmann 246523b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn); 24667d0db0a3SMarcel Holtmann hci_conn_add_sysfs(conn); 24677d0db0a3SMarcel Holtmann 2468a9de9248SMarcel Holtmann if (test_bit(HCI_AUTH, &hdev->flags)) 24694dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 2470a9de9248SMarcel Holtmann 2471a9de9248SMarcel Holtmann if (test_bit(HCI_ENCRYPT, &hdev->flags)) 24724dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags); 2473a9de9248SMarcel Holtmann 2474a9de9248SMarcel Holtmann /* Get remote features */ 2475a9de9248SMarcel Holtmann if (conn->type == ACL_LINK) { 2476a9de9248SMarcel Holtmann struct hci_cp_read_remote_features cp; 2477a9de9248SMarcel Holtmann cp.handle = ev->handle; 2478769be974SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, 2479769be974SMarcel Holtmann sizeof(cp), &cp); 248022f433dcSJohan Hedberg 248101b1cb87SJohan Hedberg hci_req_update_scan(hdev); 248245bb4bf0SMarcel Holtmann } 2483a9de9248SMarcel Holtmann 2484a9de9248SMarcel Holtmann /* Set packet type for incoming connection */ 2485d095c1ebSAndrei Emeltchenko if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) { 2486a9de9248SMarcel Holtmann struct hci_cp_change_conn_ptype cp; 2487a9de9248SMarcel Holtmann cp.handle = ev->handle; 2488a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 248904124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), 249004124681SGustavo F. Padovan &cp); 2491a9de9248SMarcel Holtmann } 249217d5c04cSJohan Hedberg } else { 2493a9de9248SMarcel Holtmann conn->state = BT_CLOSED; 249417d5c04cSJohan Hedberg if (conn->type == ACL_LINK) 249564c7b77cSMarcel Holtmann mgmt_connect_failed(hdev, &conn->dst, conn->type, 249648264f06SJohan Hedberg conn->dst_type, ev->status); 249717d5c04cSJohan Hedberg } 249845bb4bf0SMarcel Holtmann 2499e73439d8SMarcel Holtmann if (conn->type == ACL_LINK) 2500e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 250145bb4bf0SMarcel Holtmann 2502769be974SMarcel Holtmann if (ev->status) { 2503539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 2504a9de9248SMarcel Holtmann hci_conn_del(conn); 2505c89b6e6bSMarcel Holtmann } else if (ev->link_type != ACL_LINK) 2506539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 2507a9de9248SMarcel Holtmann 2508a9de9248SMarcel Holtmann unlock: 25091da177e4SLinus Torvalds hci_dev_unlock(hdev); 2510a9de9248SMarcel Holtmann 2511a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 25121da177e4SLinus Torvalds } 25131da177e4SLinus Torvalds 251470c46425SJohan Hedberg static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr) 251570c46425SJohan Hedberg { 251670c46425SJohan Hedberg struct hci_cp_reject_conn_req cp; 251770c46425SJohan Hedberg 251870c46425SJohan Hedberg bacpy(&cp.bdaddr, bdaddr); 251970c46425SJohan Hedberg cp.reason = HCI_ERROR_REJ_BAD_ADDR; 252070c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); 252170c46425SJohan Hedberg } 252270c46425SJohan Hedberg 25236039aa73SGustavo Padovan static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 25241da177e4SLinus Torvalds { 2525a9de9248SMarcel Holtmann struct hci_ev_conn_request *ev = (void *) skb->data; 25261da177e4SLinus Torvalds int mask = hdev->link_mode; 252770c46425SJohan Hedberg struct inquiry_entry *ie; 252870c46425SJohan Hedberg struct hci_conn *conn; 252920714bfeSFrédéric Dalleau __u8 flags = 0; 25301da177e4SLinus Torvalds 25316ed93dc6SAndrei Emeltchenko BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr, 2532807deac2SGustavo Padovan ev->link_type); 25331da177e4SLinus Torvalds 253420714bfeSFrédéric Dalleau mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type, 253520714bfeSFrédéric Dalleau &flags); 25361da177e4SLinus Torvalds 253770c46425SJohan Hedberg if (!(mask & HCI_LM_ACCEPT)) { 253870c46425SJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 253970c46425SJohan Hedberg return; 254070c46425SJohan Hedberg } 254170c46425SJohan Hedberg 2542a55bd29dSJohan Hedberg if (hci_bdaddr_list_lookup(&hdev->blacklist, &ev->bdaddr, 2543dcc36c16SJohan Hedberg BDADDR_BREDR)) { 254470c46425SJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 254570c46425SJohan Hedberg return; 254670c46425SJohan Hedberg } 254746c4c941SJohan Hedberg 25486a8fc95cSJohan Hedberg /* Require HCI_CONNECTABLE or a whitelist entry to accept the 25496a8fc95cSJohan Hedberg * connection. These features are only touched through mgmt so 25506a8fc95cSJohan Hedberg * only do the checks if HCI_MGMT is set. 25516a8fc95cSJohan Hedberg */ 2552d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT) && 2553d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONNECTABLE) && 255446c4c941SJohan Hedberg !hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr, 2555a55bd29dSJohan Hedberg BDADDR_BREDR)) { 2556a55bd29dSJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 2557a55bd29dSJohan Hedberg return; 2558a55bd29dSJohan Hedberg } 255970c46425SJohan Hedberg 25601da177e4SLinus Torvalds /* Connection accepted */ 25611da177e4SLinus Torvalds 25621da177e4SLinus Torvalds hci_dev_lock(hdev); 2563b6a0dc82SMarcel Holtmann 2564cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 2565cc11b9c1SAndrei Emeltchenko if (ie) 2566c7bdd502SMarcel Holtmann memcpy(ie->data.dev_class, ev->dev_class, 3); 2567c7bdd502SMarcel Holtmann 25688fc9ced3SGustavo Padovan conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, 25698fc9ced3SGustavo Padovan &ev->bdaddr); 25701da177e4SLinus Torvalds if (!conn) { 2571a5c4e309SJohan Hedberg conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr, 2572a5c4e309SJohan Hedberg HCI_ROLE_SLAVE); 2573cc11b9c1SAndrei Emeltchenko if (!conn) { 25742064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for new connection"); 25751da177e4SLinus Torvalds hci_dev_unlock(hdev); 25761da177e4SLinus Torvalds return; 25771da177e4SLinus Torvalds } 25781da177e4SLinus Torvalds } 2579b6a0dc82SMarcel Holtmann 25801da177e4SLinus Torvalds memcpy(conn->dev_class, ev->dev_class, 3); 2581b6a0dc82SMarcel Holtmann 25821da177e4SLinus Torvalds hci_dev_unlock(hdev); 25831da177e4SLinus Torvalds 258420714bfeSFrédéric Dalleau if (ev->link_type == ACL_LINK || 258520714bfeSFrédéric Dalleau (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) { 2586b6a0dc82SMarcel Holtmann struct hci_cp_accept_conn_req cp; 258720714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 2588b6a0dc82SMarcel Holtmann 25891da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 25901da177e4SLinus Torvalds 25911da177e4SLinus Torvalds if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) 25921da177e4SLinus Torvalds cp.role = 0x00; /* Become master */ 25931da177e4SLinus Torvalds else 25941da177e4SLinus Torvalds cp.role = 0x01; /* Remain slave */ 25951da177e4SLinus Torvalds 259670c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); 259720714bfeSFrédéric Dalleau } else if (!(flags & HCI_PROTO_DEFER)) { 2598b6a0dc82SMarcel Holtmann struct hci_cp_accept_sync_conn_req cp; 259920714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 2600b6a0dc82SMarcel Holtmann 2601b6a0dc82SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 2602a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 2603b6a0dc82SMarcel Holtmann 2604dcf4adbfSJoe Perches cp.tx_bandwidth = cpu_to_le32(0x00001f40); 2605dcf4adbfSJoe Perches cp.rx_bandwidth = cpu_to_le32(0x00001f40); 2606dcf4adbfSJoe Perches cp.max_latency = cpu_to_le16(0xffff); 2607b6a0dc82SMarcel Holtmann cp.content_format = cpu_to_le16(hdev->voice_setting); 2608b6a0dc82SMarcel Holtmann cp.retrans_effort = 0xff; 2609b6a0dc82SMarcel Holtmann 261070c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp), 261170c46425SJohan Hedberg &cp); 261220714bfeSFrédéric Dalleau } else { 261320714bfeSFrédéric Dalleau conn->state = BT_CONNECT2; 2614539c496dSJohan Hedberg hci_connect_cfm(conn, 0); 2615b6a0dc82SMarcel Holtmann } 26161da177e4SLinus Torvalds } 26171da177e4SLinus Torvalds 2618f0d6a0eaSMikel Astiz static u8 hci_to_mgmt_reason(u8 err) 2619f0d6a0eaSMikel Astiz { 2620f0d6a0eaSMikel Astiz switch (err) { 2621f0d6a0eaSMikel Astiz case HCI_ERROR_CONNECTION_TIMEOUT: 2622f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_TIMEOUT; 2623f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_USER_TERM: 2624f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_LOW_RESOURCES: 2625f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_POWER_OFF: 2626f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_REMOTE; 2627f0d6a0eaSMikel Astiz case HCI_ERROR_LOCAL_HOST_TERM: 2628f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_LOCAL_HOST; 2629f0d6a0eaSMikel Astiz default: 2630f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_UNKNOWN; 2631f0d6a0eaSMikel Astiz } 2632f0d6a0eaSMikel Astiz } 2633f0d6a0eaSMikel Astiz 26346039aa73SGustavo Padovan static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 26351da177e4SLinus Torvalds { 2636a9de9248SMarcel Holtmann struct hci_ev_disconn_complete *ev = (void *) skb->data; 2637160b9251SSzymon Janc u8 reason; 26389fcb18efSAndre Guedes struct hci_conn_params *params; 263904837f64SMarcel Holtmann struct hci_conn *conn; 264012d4a3b2SJohan Hedberg bool mgmt_connected; 26413846220bSAndre Guedes u8 type; 26421da177e4SLinus Torvalds 26439f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 26441da177e4SLinus Torvalds 26451da177e4SLinus Torvalds hci_dev_lock(hdev); 26461da177e4SLinus Torvalds 264704837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2648f7520543SJohan Hedberg if (!conn) 2649f7520543SJohan Hedberg goto unlock; 2650f7520543SJohan Hedberg 2651f0d6a0eaSMikel Astiz if (ev->status) { 265288c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 265388c3df13SJohan Hedberg conn->dst_type, ev->status); 2654abf54a50SAndre Guedes goto unlock; 2655abf54a50SAndre Guedes } 2656f0d6a0eaSMikel Astiz 26573846220bSAndre Guedes conn->state = BT_CLOSED; 26583846220bSAndre Guedes 265912d4a3b2SJohan Hedberg mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags); 2660160b9251SSzymon Janc 2661160b9251SSzymon Janc if (test_bit(HCI_CONN_AUTH_FAILURE, &conn->flags)) 2662160b9251SSzymon Janc reason = MGMT_DEV_DISCONN_AUTH_FAILURE; 2663160b9251SSzymon Janc else 2664160b9251SSzymon Janc reason = hci_to_mgmt_reason(ev->reason); 2665160b9251SSzymon Janc 266612d4a3b2SJohan Hedberg mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type, 266712d4a3b2SJohan Hedberg reason, mgmt_connected); 2668f7520543SJohan Hedberg 266922f433dcSJohan Hedberg if (conn->type == ACL_LINK) { 267022f433dcSJohan Hedberg if (test_bit(HCI_CONN_FLUSH_KEY, &conn->flags)) 26716ec5bcadSVishal Agarwal hci_remove_link_key(hdev, &conn->dst); 26723846220bSAndre Guedes 267301b1cb87SJohan Hedberg hci_req_update_scan(hdev); 267422f433dcSJohan Hedberg } 267522f433dcSJohan Hedberg 26769fcb18efSAndre Guedes params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); 26779fcb18efSAndre Guedes if (params) { 26789fcb18efSAndre Guedes switch (params->auto_connect) { 26799fcb18efSAndre Guedes case HCI_AUTO_CONN_LINK_LOSS: 26809fcb18efSAndre Guedes if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT) 26819fcb18efSAndre Guedes break; 26829fcb18efSAndre Guedes /* Fall through */ 26839fcb18efSAndre Guedes 26844b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_DIRECT: 26859fcb18efSAndre Guedes case HCI_AUTO_CONN_ALWAYS: 2686418025d1SJohan Hedberg list_del_init(¶ms->action); 2687418025d1SJohan Hedberg list_add(¶ms->action, &hdev->pend_le_conns); 2688418025d1SJohan Hedberg hci_update_background_scan(hdev); 26899fcb18efSAndre Guedes break; 26909fcb18efSAndre Guedes 26919fcb18efSAndre Guedes default: 26929fcb18efSAndre Guedes break; 26939fcb18efSAndre Guedes } 26949fcb18efSAndre Guedes } 26959fcb18efSAndre Guedes 26963846220bSAndre Guedes type = conn->type; 26973846220bSAndre Guedes 26983a6d576bSJohan Hedberg hci_disconn_cfm(conn, ev->reason); 26991da177e4SLinus Torvalds hci_conn_del(conn); 27002210246cSJohan Hedberg 27012210246cSJohan Hedberg /* Re-enable advertising if necessary, since it might 27022210246cSJohan Hedberg * have been disabled by the connection. From the 27032210246cSJohan Hedberg * HCI_LE_Set_Advertise_Enable command description in 27042210246cSJohan Hedberg * the core specification (v4.0): 27052210246cSJohan Hedberg * "The Controller shall continue advertising until the Host 27062210246cSJohan Hedberg * issues an LE_Set_Advertise_Enable command with 27072210246cSJohan Hedberg * Advertising_Enable set to 0x00 (Advertising is disabled) 27082210246cSJohan Hedberg * or until a connection is created or until the Advertising 27092210246cSJohan Hedberg * is timed out due to Directed Advertising." 27102210246cSJohan Hedberg */ 27112210246cSJohan Hedberg if (type == LE_LINK) 2712f2252570SJohan Hedberg hci_req_reenable_advertising(hdev); 27131da177e4SLinus Torvalds 2714f7520543SJohan Hedberg unlock: 27151da177e4SLinus Torvalds hci_dev_unlock(hdev); 27161da177e4SLinus Torvalds } 27171da177e4SLinus Torvalds 27186039aa73SGustavo Padovan static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2719a9de9248SMarcel Holtmann { 2720a9de9248SMarcel Holtmann struct hci_ev_auth_complete *ev = (void *) skb->data; 2721a9de9248SMarcel Holtmann struct hci_conn *conn; 2722a9de9248SMarcel Holtmann 27239f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2724a9de9248SMarcel Holtmann 2725a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2726a9de9248SMarcel Holtmann 2727a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2728d7556e20SWaldemar Rymarkiewicz if (!conn) 2729d7556e20SWaldemar Rymarkiewicz goto unlock; 2730d7556e20SWaldemar Rymarkiewicz 2731765c2a96SJohan Hedberg if (!ev->status) { 2732160b9251SSzymon Janc clear_bit(HCI_CONN_AUTH_FAILURE, &conn->flags); 2733160b9251SSzymon Janc 2734aa64a8b5SJohan Hedberg if (!hci_conn_ssp_enabled(conn) && 273551a8efd7SJohan Hedberg test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { 27362064ee33SMarcel Holtmann bt_dev_info(hdev, "re-auth of legacy device is not possible."); 273719f8def0SWaldemar Rymarkiewicz } else { 27384dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 2739765c2a96SJohan Hedberg conn->sec_level = conn->pending_sec_level; 274019f8def0SWaldemar Rymarkiewicz } 27412a611692SJohan Hedberg } else { 2742160b9251SSzymon Janc if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING) 2743160b9251SSzymon Janc set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags); 2744160b9251SSzymon Janc 2745e1e930f5SJohan Hedberg mgmt_auth_failed(conn, ev->status); 27462a611692SJohan Hedberg } 2747a9de9248SMarcel Holtmann 274851a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 274951a8efd7SJohan Hedberg clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags); 2750a9de9248SMarcel Holtmann 2751f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 2752aa64a8b5SJohan Hedberg if (!ev->status && hci_conn_ssp_enabled(conn)) { 2753f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 2754f8558555SMarcel Holtmann cp.handle = ev->handle; 2755f8558555SMarcel Holtmann cp.encrypt = 0x01; 2756d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 2757d7556e20SWaldemar Rymarkiewicz &cp); 2758f8558555SMarcel Holtmann } else { 2759f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 2760539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 276176a68ba0SDavid Herrmann hci_conn_drop(conn); 2762f8558555SMarcel Holtmann } 2763052b30b0SMarcel Holtmann } else { 2764a9de9248SMarcel Holtmann hci_auth_cfm(conn, ev->status); 2765a9de9248SMarcel Holtmann 2766052b30b0SMarcel Holtmann hci_conn_hold(conn); 2767052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 276876a68ba0SDavid Herrmann hci_conn_drop(conn); 2769052b30b0SMarcel Holtmann } 2770052b30b0SMarcel Holtmann 277151a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { 2772a9de9248SMarcel Holtmann if (!ev->status) { 2773a9de9248SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 2774f8558555SMarcel Holtmann cp.handle = ev->handle; 2775f8558555SMarcel Holtmann cp.encrypt = 0x01; 2776d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 2777d7556e20SWaldemar Rymarkiewicz &cp); 2778a9de9248SMarcel Holtmann } else { 277951a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 2780a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, 0x00); 2781a9de9248SMarcel Holtmann } 2782a9de9248SMarcel Holtmann } 2783a9de9248SMarcel Holtmann 2784d7556e20SWaldemar Rymarkiewicz unlock: 2785a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2786a9de9248SMarcel Holtmann } 2787a9de9248SMarcel Holtmann 27886039aa73SGustavo Padovan static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) 2789a9de9248SMarcel Holtmann { 2790127178d2SJohan Hedberg struct hci_ev_remote_name *ev = (void *) skb->data; 2791127178d2SJohan Hedberg struct hci_conn *conn; 2792127178d2SJohan Hedberg 2793a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2794a9de9248SMarcel Holtmann 2795a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 2796127178d2SJohan Hedberg 2797127178d2SJohan Hedberg hci_dev_lock(hdev); 2798127178d2SJohan Hedberg 2799127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2800b644ba33SJohan Hedberg 2801d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 2802b644ba33SJohan Hedberg goto check_auth; 2803b644ba33SJohan Hedberg 2804b644ba33SJohan Hedberg if (ev->status == 0) 2805b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name, 2806b644ba33SJohan Hedberg strnlen(ev->name, HCI_MAX_NAME_LENGTH)); 2807b644ba33SJohan Hedberg else 2808b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0); 2809b644ba33SJohan Hedberg 2810b644ba33SJohan Hedberg check_auth: 281179c6c70cSJohan Hedberg if (!conn) 281279c6c70cSJohan Hedberg goto unlock; 281379c6c70cSJohan Hedberg 281479c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 281579c6c70cSJohan Hedberg goto unlock; 281679c6c70cSJohan Hedberg 281751a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 2818127178d2SJohan Hedberg struct hci_cp_auth_requested cp; 2819977f8fceSJohan Hedberg 2820977f8fceSJohan Hedberg set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags); 2821977f8fceSJohan Hedberg 2822127178d2SJohan Hedberg cp.handle = __cpu_to_le16(conn->handle); 2823127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); 2824127178d2SJohan Hedberg } 2825127178d2SJohan Hedberg 282679c6c70cSJohan Hedberg unlock: 2827127178d2SJohan Hedberg hci_dev_unlock(hdev); 2828a9de9248SMarcel Holtmann } 2829a9de9248SMarcel Holtmann 2830821f3766SJohan Hedberg static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status, 2831821f3766SJohan Hedberg u16 opcode, struct sk_buff *skb) 2832821f3766SJohan Hedberg { 2833821f3766SJohan Hedberg const struct hci_rp_read_enc_key_size *rp; 2834821f3766SJohan Hedberg struct hci_conn *conn; 2835821f3766SJohan Hedberg u16 handle; 2836821f3766SJohan Hedberg 2837821f3766SJohan Hedberg BT_DBG("%s status 0x%02x", hdev->name, status); 2838821f3766SJohan Hedberg 2839821f3766SJohan Hedberg if (!skb || skb->len < sizeof(*rp)) { 28402064ee33SMarcel Holtmann bt_dev_err(hdev, "invalid read key size response"); 2841821f3766SJohan Hedberg return; 2842821f3766SJohan Hedberg } 2843821f3766SJohan Hedberg 2844821f3766SJohan Hedberg rp = (void *)skb->data; 2845821f3766SJohan Hedberg handle = le16_to_cpu(rp->handle); 2846821f3766SJohan Hedberg 2847821f3766SJohan Hedberg hci_dev_lock(hdev); 2848821f3766SJohan Hedberg 2849821f3766SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, handle); 2850821f3766SJohan Hedberg if (!conn) 2851821f3766SJohan Hedberg goto unlock; 2852821f3766SJohan Hedberg 2853821f3766SJohan Hedberg /* If we fail to read the encryption key size, assume maximum 2854821f3766SJohan Hedberg * (which is the same we do also when this HCI command isn't 2855821f3766SJohan Hedberg * supported. 2856821f3766SJohan Hedberg */ 2857821f3766SJohan Hedberg if (rp->status) { 28582064ee33SMarcel Holtmann bt_dev_err(hdev, "failed to read key size for handle %u", 2859821f3766SJohan Hedberg handle); 2860821f3766SJohan Hedberg conn->enc_key_size = HCI_LINK_KEY_SIZE; 2861821f3766SJohan Hedberg } else { 2862821f3766SJohan Hedberg conn->enc_key_size = rp->key_size; 2863821f3766SJohan Hedberg } 2864821f3766SJohan Hedberg 2865821f3766SJohan Hedberg if (conn->state == BT_CONFIG) { 2866821f3766SJohan Hedberg conn->state = BT_CONNECTED; 2867821f3766SJohan Hedberg hci_connect_cfm(conn, 0); 2868821f3766SJohan Hedberg hci_conn_drop(conn); 2869821f3766SJohan Hedberg } else { 2870821f3766SJohan Hedberg u8 encrypt; 2871821f3766SJohan Hedberg 2872821f3766SJohan Hedberg if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags)) 2873821f3766SJohan Hedberg encrypt = 0x00; 28745d667ef6SJohan Hedberg else if (test_bit(HCI_CONN_AES_CCM, &conn->flags)) 2875821f3766SJohan Hedberg encrypt = 0x02; 2876821f3766SJohan Hedberg else 2877821f3766SJohan Hedberg encrypt = 0x01; 2878821f3766SJohan Hedberg 2879821f3766SJohan Hedberg hci_encrypt_cfm(conn, 0, encrypt); 2880821f3766SJohan Hedberg } 2881821f3766SJohan Hedberg 2882821f3766SJohan Hedberg unlock: 2883821f3766SJohan Hedberg hci_dev_unlock(hdev); 2884821f3766SJohan Hedberg } 2885821f3766SJohan Hedberg 28866039aa73SGustavo Padovan static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2887a9de9248SMarcel Holtmann { 2888a9de9248SMarcel Holtmann struct hci_ev_encrypt_change *ev = (void *) skb->data; 2889a9de9248SMarcel Holtmann struct hci_conn *conn; 2890a9de9248SMarcel Holtmann 28919f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2892a9de9248SMarcel Holtmann 2893a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2894a9de9248SMarcel Holtmann 2895a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2896dc8357ccSMarcel Holtmann if (!conn) 2897dc8357ccSMarcel Holtmann goto unlock; 2898dc8357ccSMarcel Holtmann 2899a9de9248SMarcel Holtmann if (!ev->status) { 2900ae293196SMarcel Holtmann if (ev->encrypt) { 2901ae293196SMarcel Holtmann /* Encryption implies authentication */ 29024dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 29034dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags); 2904da85e5e5SVinicius Costa Gomes conn->sec_level = conn->pending_sec_level; 2905abf76badSMarcel Holtmann 2906914a6ffeSMarcel Holtmann /* P-256 authentication key implies FIPS */ 2907914a6ffeSMarcel Holtmann if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256) 29084dae2798SJohan Hedberg set_bit(HCI_CONN_FIPS, &conn->flags); 2909914a6ffeSMarcel Holtmann 2910abf76badSMarcel Holtmann if ((conn->type == ACL_LINK && ev->encrypt == 0x02) || 2911abf76badSMarcel Holtmann conn->type == LE_LINK) 2912abf76badSMarcel Holtmann set_bit(HCI_CONN_AES_CCM, &conn->flags); 2913abf76badSMarcel Holtmann } else { 29144dae2798SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT, &conn->flags); 2915abf76badSMarcel Holtmann clear_bit(HCI_CONN_AES_CCM, &conn->flags); 2916abf76badSMarcel Holtmann } 2917a9de9248SMarcel Holtmann } 2918a9de9248SMarcel Holtmann 29197ed3fa20SJohan Hedberg /* We should disregard the current RPA and generate a new one 29207ed3fa20SJohan Hedberg * whenever the encryption procedure fails. 29217ed3fa20SJohan Hedberg */ 2922a73c046aSJaganath Kanakkassery if (ev->status && conn->type == LE_LINK) { 2923a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); 2924a73c046aSJaganath Kanakkassery hci_adv_instances_set_rpa_expired(hdev, true); 2925a73c046aSJaganath Kanakkassery } 29267ed3fa20SJohan Hedberg 292751a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 2928a9de9248SMarcel Holtmann 2929a7d7723aSGustavo Padovan if (ev->status && conn->state == BT_CONNECTED) { 2930160b9251SSzymon Janc if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING) 2931160b9251SSzymon Janc set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags); 2932160b9251SSzymon Janc 2933bed71748SAndre Guedes hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 293476a68ba0SDavid Herrmann hci_conn_drop(conn); 2935a7d7723aSGustavo Padovan goto unlock; 2936a7d7723aSGustavo Padovan } 2937a7d7723aSGustavo Padovan 2938035ad621SJohan Hedberg /* In Secure Connections Only mode, do not allow any connections 2939035ad621SJohan Hedberg * that are not encrypted with AES-CCM using a P-256 authenticated 2940035ad621SJohan Hedberg * combination key. 294140b552aaSMarcel Holtmann */ 2942d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && 294340b552aaSMarcel Holtmann (!test_bit(HCI_CONN_AES_CCM, &conn->flags) || 294440b552aaSMarcel Holtmann conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) { 2945539c496dSJohan Hedberg hci_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE); 294640b552aaSMarcel Holtmann hci_conn_drop(conn); 294740b552aaSMarcel Holtmann goto unlock; 294840b552aaSMarcel Holtmann } 294940b552aaSMarcel Holtmann 2950821f3766SJohan Hedberg /* Try reading the encryption key size for encrypted ACL links */ 2951821f3766SJohan Hedberg if (!ev->status && ev->encrypt && conn->type == ACL_LINK) { 2952821f3766SJohan Hedberg struct hci_cp_read_enc_key_size cp; 2953821f3766SJohan Hedberg struct hci_request req; 2954821f3766SJohan Hedberg 2955821f3766SJohan Hedberg /* Only send HCI_Read_Encryption_Key_Size if the 2956821f3766SJohan Hedberg * controller really supports it. If it doesn't, assume 2957821f3766SJohan Hedberg * the default size (16). 2958821f3766SJohan Hedberg */ 2959821f3766SJohan Hedberg if (!(hdev->commands[20] & 0x10)) { 2960821f3766SJohan Hedberg conn->enc_key_size = HCI_LINK_KEY_SIZE; 2961821f3766SJohan Hedberg goto notify; 2962821f3766SJohan Hedberg } 2963821f3766SJohan Hedberg 2964821f3766SJohan Hedberg hci_req_init(&req, hdev); 2965821f3766SJohan Hedberg 2966821f3766SJohan Hedberg cp.handle = cpu_to_le16(conn->handle); 2967821f3766SJohan Hedberg hci_req_add(&req, HCI_OP_READ_ENC_KEY_SIZE, sizeof(cp), &cp); 2968821f3766SJohan Hedberg 2969821f3766SJohan Hedberg if (hci_req_run_skb(&req, read_enc_key_size_complete)) { 29702064ee33SMarcel Holtmann bt_dev_err(hdev, "sending read key size failed"); 2971821f3766SJohan Hedberg conn->enc_key_size = HCI_LINK_KEY_SIZE; 2972821f3766SJohan Hedberg goto notify; 2973821f3766SJohan Hedberg } 2974821f3766SJohan Hedberg 2975821f3766SJohan Hedberg goto unlock; 2976821f3766SJohan Hedberg } 2977821f3766SJohan Hedberg 2978821f3766SJohan Hedberg notify: 2979035ad621SJohan Hedberg if (conn->state == BT_CONFIG) { 2980035ad621SJohan Hedberg if (!ev->status) 2981035ad621SJohan Hedberg conn->state = BT_CONNECTED; 2982035ad621SJohan Hedberg 2983539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 298476a68ba0SDavid Herrmann hci_conn_drop(conn); 2985f8558555SMarcel Holtmann } else 2986a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, ev->encrypt); 2987a9de9248SMarcel Holtmann 2988a7d7723aSGustavo Padovan unlock: 2989a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2990a9de9248SMarcel Holtmann } 2991a9de9248SMarcel Holtmann 29926039aa73SGustavo Padovan static void hci_change_link_key_complete_evt(struct hci_dev *hdev, 2993807deac2SGustavo Padovan struct sk_buff *skb) 2994a9de9248SMarcel Holtmann { 2995a9de9248SMarcel Holtmann struct hci_ev_change_link_key_complete *ev = (void *) skb->data; 2996a9de9248SMarcel Holtmann struct hci_conn *conn; 2997a9de9248SMarcel Holtmann 29989f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2999a9de9248SMarcel Holtmann 3000a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3001a9de9248SMarcel Holtmann 3002a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3003a9de9248SMarcel Holtmann if (conn) { 3004a9de9248SMarcel Holtmann if (!ev->status) 30054dae2798SJohan Hedberg set_bit(HCI_CONN_SECURE, &conn->flags); 3006a9de9248SMarcel Holtmann 300751a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 3008a9de9248SMarcel Holtmann 3009a9de9248SMarcel Holtmann hci_key_change_cfm(conn, ev->status); 3010a9de9248SMarcel Holtmann } 3011a9de9248SMarcel Holtmann 3012a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3013a9de9248SMarcel Holtmann } 3014a9de9248SMarcel Holtmann 30156039aa73SGustavo Padovan static void hci_remote_features_evt(struct hci_dev *hdev, 3016807deac2SGustavo Padovan struct sk_buff *skb) 3017a9de9248SMarcel Holtmann { 3018a9de9248SMarcel Holtmann struct hci_ev_remote_features *ev = (void *) skb->data; 3019a9de9248SMarcel Holtmann struct hci_conn *conn; 3020a9de9248SMarcel Holtmann 30219f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3022a9de9248SMarcel Holtmann 3023a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3024a9de9248SMarcel Holtmann 3025a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3026ccd556feSJohan Hedberg if (!conn) 3027ccd556feSJohan Hedberg goto unlock; 3028ccd556feSJohan Hedberg 3029769be974SMarcel Holtmann if (!ev->status) 3030cad718edSJohan Hedberg memcpy(conn->features[0], ev->features, 8); 3031a9de9248SMarcel Holtmann 3032ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 3033ccd556feSJohan Hedberg goto unlock; 3034ccd556feSJohan Hedberg 3035ac363cf9SSzymon Janc if (!ev->status && lmp_ext_feat_capable(hdev) && 3036ac363cf9SSzymon Janc lmp_ext_feat_capable(conn)) { 3037769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features cp; 3038769be974SMarcel Holtmann cp.handle = ev->handle; 3039769be974SMarcel Holtmann cp.page = 0x01; 3040ccd556feSJohan Hedberg hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, 3041769be974SMarcel Holtmann sizeof(cp), &cp); 3042392599b9SJohan Hedberg goto unlock; 3043392599b9SJohan Hedberg } 3044392599b9SJohan Hedberg 3045671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 3046127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 3047127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 3048127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 3049127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 3050127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 3051b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 305248ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, NULL, 0); 3053392599b9SJohan Hedberg 3054127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 3055769be974SMarcel Holtmann conn->state = BT_CONNECTED; 3056539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 305776a68ba0SDavid Herrmann hci_conn_drop(conn); 3058769be974SMarcel Holtmann } 3059769be974SMarcel Holtmann 3060ccd556feSJohan Hedberg unlock: 3061a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3062a9de9248SMarcel Holtmann } 3063a9de9248SMarcel Holtmann 3064e6214487SJohan Hedberg static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb, 3065e6214487SJohan Hedberg u16 *opcode, u8 *status, 3066e6214487SJohan Hedberg hci_req_complete_t *req_complete, 3067e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 3068a9de9248SMarcel Holtmann { 3069a9de9248SMarcel Holtmann struct hci_ev_cmd_complete *ev = (void *) skb->data; 3070e6214487SJohan Hedberg 3071e6214487SJohan Hedberg *opcode = __le16_to_cpu(ev->opcode); 3072e6214487SJohan Hedberg *status = skb->data[sizeof(*ev)]; 3073a9de9248SMarcel Holtmann 3074a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 3075a9de9248SMarcel Holtmann 3076e6214487SJohan Hedberg switch (*opcode) { 3077a9de9248SMarcel Holtmann case HCI_OP_INQUIRY_CANCEL: 3078a9de9248SMarcel Holtmann hci_cc_inquiry_cancel(hdev, skb); 3079a9de9248SMarcel Holtmann break; 3080a9de9248SMarcel Holtmann 30814d93483bSAndre Guedes case HCI_OP_PERIODIC_INQ: 30824d93483bSAndre Guedes hci_cc_periodic_inq(hdev, skb); 30834d93483bSAndre Guedes break; 30844d93483bSAndre Guedes 3085a9de9248SMarcel Holtmann case HCI_OP_EXIT_PERIODIC_INQ: 3086a9de9248SMarcel Holtmann hci_cc_exit_periodic_inq(hdev, skb); 3087a9de9248SMarcel Holtmann break; 3088a9de9248SMarcel Holtmann 3089a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ_CANCEL: 3090a9de9248SMarcel Holtmann hci_cc_remote_name_req_cancel(hdev, skb); 3091a9de9248SMarcel Holtmann break; 3092a9de9248SMarcel Holtmann 3093a9de9248SMarcel Holtmann case HCI_OP_ROLE_DISCOVERY: 3094a9de9248SMarcel Holtmann hci_cc_role_discovery(hdev, skb); 3095a9de9248SMarcel Holtmann break; 3096a9de9248SMarcel Holtmann 3097e4e8e37cSMarcel Holtmann case HCI_OP_READ_LINK_POLICY: 3098e4e8e37cSMarcel Holtmann hci_cc_read_link_policy(hdev, skb); 3099e4e8e37cSMarcel Holtmann break; 3100e4e8e37cSMarcel Holtmann 3101a9de9248SMarcel Holtmann case HCI_OP_WRITE_LINK_POLICY: 3102a9de9248SMarcel Holtmann hci_cc_write_link_policy(hdev, skb); 3103a9de9248SMarcel Holtmann break; 3104a9de9248SMarcel Holtmann 3105e4e8e37cSMarcel Holtmann case HCI_OP_READ_DEF_LINK_POLICY: 3106e4e8e37cSMarcel Holtmann hci_cc_read_def_link_policy(hdev, skb); 3107e4e8e37cSMarcel Holtmann break; 3108e4e8e37cSMarcel Holtmann 3109e4e8e37cSMarcel Holtmann case HCI_OP_WRITE_DEF_LINK_POLICY: 3110e4e8e37cSMarcel Holtmann hci_cc_write_def_link_policy(hdev, skb); 3111e4e8e37cSMarcel Holtmann break; 3112e4e8e37cSMarcel Holtmann 3113a9de9248SMarcel Holtmann case HCI_OP_RESET: 3114a9de9248SMarcel Holtmann hci_cc_reset(hdev, skb); 3115a9de9248SMarcel Holtmann break; 3116a9de9248SMarcel Holtmann 3117c2f0f979SMarcel Holtmann case HCI_OP_READ_STORED_LINK_KEY: 3118c2f0f979SMarcel Holtmann hci_cc_read_stored_link_key(hdev, skb); 3119c2f0f979SMarcel Holtmann break; 3120c2f0f979SMarcel Holtmann 3121a9366120SMarcel Holtmann case HCI_OP_DELETE_STORED_LINK_KEY: 3122a9366120SMarcel Holtmann hci_cc_delete_stored_link_key(hdev, skb); 3123a9366120SMarcel Holtmann break; 3124a9366120SMarcel Holtmann 3125a9de9248SMarcel Holtmann case HCI_OP_WRITE_LOCAL_NAME: 3126a9de9248SMarcel Holtmann hci_cc_write_local_name(hdev, skb); 3127a9de9248SMarcel Holtmann break; 3128a9de9248SMarcel Holtmann 3129a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_NAME: 3130a9de9248SMarcel Holtmann hci_cc_read_local_name(hdev, skb); 3131a9de9248SMarcel Holtmann break; 3132a9de9248SMarcel Holtmann 3133a9de9248SMarcel Holtmann case HCI_OP_WRITE_AUTH_ENABLE: 3134a9de9248SMarcel Holtmann hci_cc_write_auth_enable(hdev, skb); 3135a9de9248SMarcel Holtmann break; 3136a9de9248SMarcel Holtmann 3137a9de9248SMarcel Holtmann case HCI_OP_WRITE_ENCRYPT_MODE: 3138a9de9248SMarcel Holtmann hci_cc_write_encrypt_mode(hdev, skb); 3139a9de9248SMarcel Holtmann break; 3140a9de9248SMarcel Holtmann 3141a9de9248SMarcel Holtmann case HCI_OP_WRITE_SCAN_ENABLE: 3142a9de9248SMarcel Holtmann hci_cc_write_scan_enable(hdev, skb); 3143a9de9248SMarcel Holtmann break; 3144a9de9248SMarcel Holtmann 3145a9de9248SMarcel Holtmann case HCI_OP_READ_CLASS_OF_DEV: 3146a9de9248SMarcel Holtmann hci_cc_read_class_of_dev(hdev, skb); 3147a9de9248SMarcel Holtmann break; 3148a9de9248SMarcel Holtmann 3149a9de9248SMarcel Holtmann case HCI_OP_WRITE_CLASS_OF_DEV: 3150a9de9248SMarcel Holtmann hci_cc_write_class_of_dev(hdev, skb); 3151a9de9248SMarcel Holtmann break; 3152a9de9248SMarcel Holtmann 3153a9de9248SMarcel Holtmann case HCI_OP_READ_VOICE_SETTING: 3154a9de9248SMarcel Holtmann hci_cc_read_voice_setting(hdev, skb); 3155a9de9248SMarcel Holtmann break; 3156a9de9248SMarcel Holtmann 3157a9de9248SMarcel Holtmann case HCI_OP_WRITE_VOICE_SETTING: 3158a9de9248SMarcel Holtmann hci_cc_write_voice_setting(hdev, skb); 3159a9de9248SMarcel Holtmann break; 3160a9de9248SMarcel Holtmann 3161b4cb9fb2SMarcel Holtmann case HCI_OP_READ_NUM_SUPPORTED_IAC: 3162b4cb9fb2SMarcel Holtmann hci_cc_read_num_supported_iac(hdev, skb); 3163b4cb9fb2SMarcel Holtmann break; 3164b4cb9fb2SMarcel Holtmann 3165333140b5SMarcel Holtmann case HCI_OP_WRITE_SSP_MODE: 3166333140b5SMarcel Holtmann hci_cc_write_ssp_mode(hdev, skb); 3167333140b5SMarcel Holtmann break; 3168333140b5SMarcel Holtmann 3169eac83dc6SMarcel Holtmann case HCI_OP_WRITE_SC_SUPPORT: 3170eac83dc6SMarcel Holtmann hci_cc_write_sc_support(hdev, skb); 3171eac83dc6SMarcel Holtmann break; 3172eac83dc6SMarcel Holtmann 3173a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_VERSION: 3174a9de9248SMarcel Holtmann hci_cc_read_local_version(hdev, skb); 3175a9de9248SMarcel Holtmann break; 3176a9de9248SMarcel Holtmann 3177a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_COMMANDS: 3178a9de9248SMarcel Holtmann hci_cc_read_local_commands(hdev, skb); 3179a9de9248SMarcel Holtmann break; 3180a9de9248SMarcel Holtmann 3181a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_FEATURES: 3182a9de9248SMarcel Holtmann hci_cc_read_local_features(hdev, skb); 3183a9de9248SMarcel Holtmann break; 3184a9de9248SMarcel Holtmann 3185971e3a4bSAndre Guedes case HCI_OP_READ_LOCAL_EXT_FEATURES: 3186971e3a4bSAndre Guedes hci_cc_read_local_ext_features(hdev, skb); 3187971e3a4bSAndre Guedes break; 3188971e3a4bSAndre Guedes 3189a9de9248SMarcel Holtmann case HCI_OP_READ_BUFFER_SIZE: 3190a9de9248SMarcel Holtmann hci_cc_read_buffer_size(hdev, skb); 3191a9de9248SMarcel Holtmann break; 3192a9de9248SMarcel Holtmann 3193a9de9248SMarcel Holtmann case HCI_OP_READ_BD_ADDR: 3194a9de9248SMarcel Holtmann hci_cc_read_bd_addr(hdev, skb); 3195a9de9248SMarcel Holtmann break; 3196a9de9248SMarcel Holtmann 3197f332ec66SJohan Hedberg case HCI_OP_READ_PAGE_SCAN_ACTIVITY: 3198f332ec66SJohan Hedberg hci_cc_read_page_scan_activity(hdev, skb); 3199f332ec66SJohan Hedberg break; 3200f332ec66SJohan Hedberg 32014a3ee763SJohan Hedberg case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY: 32024a3ee763SJohan Hedberg hci_cc_write_page_scan_activity(hdev, skb); 32034a3ee763SJohan Hedberg break; 32044a3ee763SJohan Hedberg 3205f332ec66SJohan Hedberg case HCI_OP_READ_PAGE_SCAN_TYPE: 3206f332ec66SJohan Hedberg hci_cc_read_page_scan_type(hdev, skb); 3207f332ec66SJohan Hedberg break; 3208f332ec66SJohan Hedberg 32094a3ee763SJohan Hedberg case HCI_OP_WRITE_PAGE_SCAN_TYPE: 32104a3ee763SJohan Hedberg hci_cc_write_page_scan_type(hdev, skb); 32114a3ee763SJohan Hedberg break; 32124a3ee763SJohan Hedberg 3213350ee4cfSAndrei Emeltchenko case HCI_OP_READ_DATA_BLOCK_SIZE: 3214350ee4cfSAndrei Emeltchenko hci_cc_read_data_block_size(hdev, skb); 3215350ee4cfSAndrei Emeltchenko break; 3216350ee4cfSAndrei Emeltchenko 32171e89cffbSAndrei Emeltchenko case HCI_OP_READ_FLOW_CONTROL_MODE: 32181e89cffbSAndrei Emeltchenko hci_cc_read_flow_control_mode(hdev, skb); 32191e89cffbSAndrei Emeltchenko break; 32201e89cffbSAndrei Emeltchenko 3221928abaa7SAndrei Emeltchenko case HCI_OP_READ_LOCAL_AMP_INFO: 3222928abaa7SAndrei Emeltchenko hci_cc_read_local_amp_info(hdev, skb); 3223928abaa7SAndrei Emeltchenko break; 3224928abaa7SAndrei Emeltchenko 322533f35721SJohan Hedberg case HCI_OP_READ_CLOCK: 322633f35721SJohan Hedberg hci_cc_read_clock(hdev, skb); 322733f35721SJohan Hedberg break; 322833f35721SJohan Hedberg 3229d5859e22SJohan Hedberg case HCI_OP_READ_INQ_RSP_TX_POWER: 3230d5859e22SJohan Hedberg hci_cc_read_inq_rsp_tx_power(hdev, skb); 3231d5859e22SJohan Hedberg break; 3232d5859e22SJohan Hedberg 3233980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_REPLY: 3234980e1a53SJohan Hedberg hci_cc_pin_code_reply(hdev, skb); 3235980e1a53SJohan Hedberg break; 3236980e1a53SJohan Hedberg 3237980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_NEG_REPLY: 3238980e1a53SJohan Hedberg hci_cc_pin_code_neg_reply(hdev, skb); 3239980e1a53SJohan Hedberg break; 3240980e1a53SJohan Hedberg 3241c35938b2SSzymon Janc case HCI_OP_READ_LOCAL_OOB_DATA: 32424d2d2796SMarcel Holtmann hci_cc_read_local_oob_data(hdev, skb); 32434d2d2796SMarcel Holtmann break; 32444d2d2796SMarcel Holtmann 32454d2d2796SMarcel Holtmann case HCI_OP_READ_LOCAL_OOB_EXT_DATA: 32464d2d2796SMarcel Holtmann hci_cc_read_local_oob_ext_data(hdev, skb); 3247c35938b2SSzymon Janc break; 3248c35938b2SSzymon Janc 32496ed58ec5SVille Tervo case HCI_OP_LE_READ_BUFFER_SIZE: 32506ed58ec5SVille Tervo hci_cc_le_read_buffer_size(hdev, skb); 32516ed58ec5SVille Tervo break; 32526ed58ec5SVille Tervo 325360e77321SJohan Hedberg case HCI_OP_LE_READ_LOCAL_FEATURES: 325460e77321SJohan Hedberg hci_cc_le_read_local_features(hdev, skb); 325560e77321SJohan Hedberg break; 325660e77321SJohan Hedberg 32578fa19098SJohan Hedberg case HCI_OP_LE_READ_ADV_TX_POWER: 32588fa19098SJohan Hedberg hci_cc_le_read_adv_tx_power(hdev, skb); 32598fa19098SJohan Hedberg break; 32608fa19098SJohan Hedberg 3261a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_REPLY: 3262a5c29683SJohan Hedberg hci_cc_user_confirm_reply(hdev, skb); 3263a5c29683SJohan Hedberg break; 3264a5c29683SJohan Hedberg 3265a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_NEG_REPLY: 3266a5c29683SJohan Hedberg hci_cc_user_confirm_neg_reply(hdev, skb); 3267a5c29683SJohan Hedberg break; 3268a5c29683SJohan Hedberg 32691143d458SBrian Gix case HCI_OP_USER_PASSKEY_REPLY: 32701143d458SBrian Gix hci_cc_user_passkey_reply(hdev, skb); 32711143d458SBrian Gix break; 32721143d458SBrian Gix 32731143d458SBrian Gix case HCI_OP_USER_PASSKEY_NEG_REPLY: 32741143d458SBrian Gix hci_cc_user_passkey_neg_reply(hdev, skb); 327516cde993SSzymon Janc break; 327607f7fa5dSAndre Guedes 32777a4cd51dSMarcel Holtmann case HCI_OP_LE_SET_RANDOM_ADDR: 32787a4cd51dSMarcel Holtmann hci_cc_le_set_random_addr(hdev, skb); 32797a4cd51dSMarcel Holtmann break; 32807a4cd51dSMarcel Holtmann 3281c1d5dc4aSJohan Hedberg case HCI_OP_LE_SET_ADV_ENABLE: 3282c1d5dc4aSJohan Hedberg hci_cc_le_set_adv_enable(hdev, skb); 3283c1d5dc4aSJohan Hedberg break; 3284c1d5dc4aSJohan Hedberg 3285533553f8SMarcel Holtmann case HCI_OP_LE_SET_SCAN_PARAM: 3286533553f8SMarcel Holtmann hci_cc_le_set_scan_param(hdev, skb); 3287533553f8SMarcel Holtmann break; 3288533553f8SMarcel Holtmann 3289eb9d91f5SAndre Guedes case HCI_OP_LE_SET_SCAN_ENABLE: 3290eb9d91f5SAndre Guedes hci_cc_le_set_scan_enable(hdev, skb); 3291eb9d91f5SAndre Guedes break; 3292eb9d91f5SAndre Guedes 3293cf1d081fSJohan Hedberg case HCI_OP_LE_READ_WHITE_LIST_SIZE: 3294cf1d081fSJohan Hedberg hci_cc_le_read_white_list_size(hdev, skb); 3295cf1d081fSJohan Hedberg break; 3296cf1d081fSJohan Hedberg 32970f36b589SMarcel Holtmann case HCI_OP_LE_CLEAR_WHITE_LIST: 32980f36b589SMarcel Holtmann hci_cc_le_clear_white_list(hdev, skb); 32990f36b589SMarcel Holtmann break; 33000f36b589SMarcel Holtmann 33010f36b589SMarcel Holtmann case HCI_OP_LE_ADD_TO_WHITE_LIST: 33020f36b589SMarcel Holtmann hci_cc_le_add_to_white_list(hdev, skb); 33030f36b589SMarcel Holtmann break; 33040f36b589SMarcel Holtmann 33050f36b589SMarcel Holtmann case HCI_OP_LE_DEL_FROM_WHITE_LIST: 33060f36b589SMarcel Holtmann hci_cc_le_del_from_white_list(hdev, skb); 33070f36b589SMarcel Holtmann break; 33080f36b589SMarcel Holtmann 33099b008c04SJohan Hedberg case HCI_OP_LE_READ_SUPPORTED_STATES: 33109b008c04SJohan Hedberg hci_cc_le_read_supported_states(hdev, skb); 33119b008c04SJohan Hedberg break; 33129b008c04SJohan Hedberg 3313a8e1bfaaSMarcel Holtmann case HCI_OP_LE_READ_DEF_DATA_LEN: 3314a8e1bfaaSMarcel Holtmann hci_cc_le_read_def_data_len(hdev, skb); 3315a8e1bfaaSMarcel Holtmann break; 3316a8e1bfaaSMarcel Holtmann 3317a8e1bfaaSMarcel Holtmann case HCI_OP_LE_WRITE_DEF_DATA_LEN: 3318a8e1bfaaSMarcel Holtmann hci_cc_le_write_def_data_len(hdev, skb); 3319a8e1bfaaSMarcel Holtmann break; 3320a8e1bfaaSMarcel Holtmann 3321b950aa88SAnkit Navik case HCI_OP_LE_ADD_TO_RESOLV_LIST: 3322b950aa88SAnkit Navik hci_cc_le_add_to_resolv_list(hdev, skb); 3323b950aa88SAnkit Navik break; 3324b950aa88SAnkit Navik 3325b950aa88SAnkit Navik case HCI_OP_LE_DEL_FROM_RESOLV_LIST: 3326b950aa88SAnkit Navik hci_cc_le_del_from_resolv_list(hdev, skb); 3327b950aa88SAnkit Navik break; 3328b950aa88SAnkit Navik 3329545f2596SAnkit Navik case HCI_OP_LE_CLEAR_RESOLV_LIST: 3330545f2596SAnkit Navik hci_cc_le_clear_resolv_list(hdev, skb); 3331545f2596SAnkit Navik break; 3332545f2596SAnkit Navik 3333cfdb0c2dSAnkit Navik case HCI_OP_LE_READ_RESOLV_LIST_SIZE: 3334cfdb0c2dSAnkit Navik hci_cc_le_read_resolv_list_size(hdev, skb); 3335cfdb0c2dSAnkit Navik break; 3336cfdb0c2dSAnkit Navik 3337aa12af77SAnkit Navik case HCI_OP_LE_SET_ADDR_RESOLV_ENABLE: 3338aa12af77SAnkit Navik hci_cc_le_set_addr_resolution_enable(hdev, skb); 3339aa12af77SAnkit Navik break; 3340aa12af77SAnkit Navik 3341a8e1bfaaSMarcel Holtmann case HCI_OP_LE_READ_MAX_DATA_LEN: 3342a8e1bfaaSMarcel Holtmann hci_cc_le_read_max_data_len(hdev, skb); 3343a8e1bfaaSMarcel Holtmann break; 3344a8e1bfaaSMarcel Holtmann 3345f9b49306SAndre Guedes case HCI_OP_WRITE_LE_HOST_SUPPORTED: 3346f9b49306SAndre Guedes hci_cc_write_le_host_supported(hdev, skb); 3347f9b49306SAndre Guedes break; 3348f9b49306SAndre Guedes 334956ed2cb8SJohan Hedberg case HCI_OP_LE_SET_ADV_PARAM: 335056ed2cb8SJohan Hedberg hci_cc_set_adv_param(hdev, skb); 335156ed2cb8SJohan Hedberg break; 335256ed2cb8SJohan Hedberg 33535ae76a94SAndrzej Kaczmarek case HCI_OP_READ_RSSI: 33545ae76a94SAndrzej Kaczmarek hci_cc_read_rssi(hdev, skb); 33555ae76a94SAndrzej Kaczmarek break; 33565ae76a94SAndrzej Kaczmarek 33575a134faeSAndrzej Kaczmarek case HCI_OP_READ_TX_POWER: 33585a134faeSAndrzej Kaczmarek hci_cc_read_tx_power(hdev, skb); 33595a134faeSAndrzej Kaczmarek break; 33605a134faeSAndrzej Kaczmarek 3361c50b33c8SMarcel Holtmann case HCI_OP_WRITE_SSP_DEBUG_MODE: 3362c50b33c8SMarcel Holtmann hci_cc_write_ssp_debug_mode(hdev, skb); 3363c50b33c8SMarcel Holtmann break; 3364c50b33c8SMarcel Holtmann 3365a2344b9eSJaganath Kanakkassery case HCI_OP_LE_SET_EXT_SCAN_PARAMS: 3366a2344b9eSJaganath Kanakkassery hci_cc_le_set_ext_scan_param(hdev, skb); 3367a2344b9eSJaganath Kanakkassery break; 3368a2344b9eSJaganath Kanakkassery 3369a2344b9eSJaganath Kanakkassery case HCI_OP_LE_SET_EXT_SCAN_ENABLE: 3370a2344b9eSJaganath Kanakkassery hci_cc_le_set_ext_scan_enable(hdev, skb); 3371a2344b9eSJaganath Kanakkassery break; 3372a2344b9eSJaganath Kanakkassery 33730314f286SJaganath Kanakkassery case HCI_OP_LE_SET_DEFAULT_PHY: 33740314f286SJaganath Kanakkassery hci_cc_le_set_default_phy(hdev, skb); 33750314f286SJaganath Kanakkassery break; 33760314f286SJaganath Kanakkassery 33776b49bcb4SJaganath Kanakkassery case HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS: 33786b49bcb4SJaganath Kanakkassery hci_cc_le_read_num_adv_sets(hdev, skb); 33796b49bcb4SJaganath Kanakkassery break; 33806b49bcb4SJaganath Kanakkassery 3381de181e88SJaganath Kanakkassery case HCI_OP_LE_SET_EXT_ADV_PARAMS: 3382de181e88SJaganath Kanakkassery hci_cc_set_ext_adv_param(hdev, skb); 3383de181e88SJaganath Kanakkassery break; 3384de181e88SJaganath Kanakkassery 3385de181e88SJaganath Kanakkassery case HCI_OP_LE_SET_EXT_ADV_ENABLE: 3386de181e88SJaganath Kanakkassery hci_cc_le_set_ext_adv_enable(hdev, skb); 3387de181e88SJaganath Kanakkassery break; 3388de181e88SJaganath Kanakkassery 3389a73c046aSJaganath Kanakkassery case HCI_OP_LE_SET_ADV_SET_RAND_ADDR: 3390a73c046aSJaganath Kanakkassery hci_cc_le_set_adv_set_random_addr(hdev, skb); 3391a73c046aSJaganath Kanakkassery break; 3392a73c046aSJaganath Kanakkassery 3393a9de9248SMarcel Holtmann default: 3394e6214487SJohan Hedberg BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode); 3395a9de9248SMarcel Holtmann break; 3396a9de9248SMarcel Holtmann } 3397a9de9248SMarcel Holtmann 3398e6214487SJohan Hedberg if (*opcode != HCI_OP_NOP) 339965cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 34006bd32326SVille Tervo 3401600b2150SJohan Hedberg if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) 3402600b2150SJohan Hedberg atomic_set(&hdev->cmd_cnt, 1); 3403600b2150SJohan Hedberg 3404e6214487SJohan Hedberg hci_req_cmd_complete(hdev, *opcode, *status, req_complete, 3405e6214487SJohan Hedberg req_complete_skb); 34069238f36aSJohan Hedberg 3407600b2150SJohan Hedberg if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q)) 3408c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 3409a9de9248SMarcel Holtmann } 3410a9de9248SMarcel Holtmann 3411e6214487SJohan Hedberg static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb, 3412e6214487SJohan Hedberg u16 *opcode, u8 *status, 3413e6214487SJohan Hedberg hci_req_complete_t *req_complete, 3414e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 3415a9de9248SMarcel Holtmann { 3416a9de9248SMarcel Holtmann struct hci_ev_cmd_status *ev = (void *) skb->data; 3417a9de9248SMarcel Holtmann 3418a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 3419a9de9248SMarcel Holtmann 3420e6214487SJohan Hedberg *opcode = __le16_to_cpu(ev->opcode); 3421e6214487SJohan Hedberg *status = ev->status; 3422a9de9248SMarcel Holtmann 3423e6214487SJohan Hedberg switch (*opcode) { 3424a9de9248SMarcel Holtmann case HCI_OP_INQUIRY: 3425a9de9248SMarcel Holtmann hci_cs_inquiry(hdev, ev->status); 3426a9de9248SMarcel Holtmann break; 3427a9de9248SMarcel Holtmann 3428a9de9248SMarcel Holtmann case HCI_OP_CREATE_CONN: 3429a9de9248SMarcel Holtmann hci_cs_create_conn(hdev, ev->status); 3430a9de9248SMarcel Holtmann break; 3431a9de9248SMarcel Holtmann 34329645c76cSKuba Pawlak case HCI_OP_DISCONNECT: 34339645c76cSKuba Pawlak hci_cs_disconnect(hdev, ev->status); 34349645c76cSKuba Pawlak break; 34359645c76cSKuba Pawlak 3436a9de9248SMarcel Holtmann case HCI_OP_ADD_SCO: 3437a9de9248SMarcel Holtmann hci_cs_add_sco(hdev, ev->status); 3438a9de9248SMarcel Holtmann break; 3439a9de9248SMarcel Holtmann 3440f8558555SMarcel Holtmann case HCI_OP_AUTH_REQUESTED: 3441f8558555SMarcel Holtmann hci_cs_auth_requested(hdev, ev->status); 3442f8558555SMarcel Holtmann break; 3443f8558555SMarcel Holtmann 3444f8558555SMarcel Holtmann case HCI_OP_SET_CONN_ENCRYPT: 3445f8558555SMarcel Holtmann hci_cs_set_conn_encrypt(hdev, ev->status); 3446f8558555SMarcel Holtmann break; 3447f8558555SMarcel Holtmann 3448a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ: 3449a9de9248SMarcel Holtmann hci_cs_remote_name_req(hdev, ev->status); 3450a9de9248SMarcel Holtmann break; 3451a9de9248SMarcel Holtmann 3452769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_FEATURES: 3453769be974SMarcel Holtmann hci_cs_read_remote_features(hdev, ev->status); 3454769be974SMarcel Holtmann break; 3455769be974SMarcel Holtmann 3456769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_EXT_FEATURES: 3457769be974SMarcel Holtmann hci_cs_read_remote_ext_features(hdev, ev->status); 3458769be974SMarcel Holtmann break; 3459769be974SMarcel Holtmann 3460a9de9248SMarcel Holtmann case HCI_OP_SETUP_SYNC_CONN: 3461a9de9248SMarcel Holtmann hci_cs_setup_sync_conn(hdev, ev->status); 3462a9de9248SMarcel Holtmann break; 3463a9de9248SMarcel Holtmann 3464a9de9248SMarcel Holtmann case HCI_OP_SNIFF_MODE: 3465a9de9248SMarcel Holtmann hci_cs_sniff_mode(hdev, ev->status); 3466a9de9248SMarcel Holtmann break; 3467a9de9248SMarcel Holtmann 3468a9de9248SMarcel Holtmann case HCI_OP_EXIT_SNIFF_MODE: 3469a9de9248SMarcel Holtmann hci_cs_exit_sniff_mode(hdev, ev->status); 3470a9de9248SMarcel Holtmann break; 3471a9de9248SMarcel Holtmann 347250fc85f1SKuba Pawlak case HCI_OP_SWITCH_ROLE: 347350fc85f1SKuba Pawlak hci_cs_switch_role(hdev, ev->status); 347450fc85f1SKuba Pawlak break; 347550fc85f1SKuba Pawlak 3476cb1d68f7SJohan Hedberg case HCI_OP_LE_CREATE_CONN: 3477cb1d68f7SJohan Hedberg hci_cs_le_create_conn(hdev, ev->status); 3478cb1d68f7SJohan Hedberg break; 3479cb1d68f7SJohan Hedberg 34800fe29fd1SMarcel Holtmann case HCI_OP_LE_READ_REMOTE_FEATURES: 34810fe29fd1SMarcel Holtmann hci_cs_le_read_remote_features(hdev, ev->status); 34820fe29fd1SMarcel Holtmann break; 34830fe29fd1SMarcel Holtmann 348481d0c8adSJohan Hedberg case HCI_OP_LE_START_ENC: 348581d0c8adSJohan Hedberg hci_cs_le_start_enc(hdev, ev->status); 348681d0c8adSJohan Hedberg break; 348781d0c8adSJohan Hedberg 34884d94f95dSJaganath Kanakkassery case HCI_OP_LE_EXT_CREATE_CONN: 34894d94f95dSJaganath Kanakkassery hci_cs_le_ext_create_conn(hdev, ev->status); 34904d94f95dSJaganath Kanakkassery break; 34914d94f95dSJaganath Kanakkassery 3492a9de9248SMarcel Holtmann default: 3493e6214487SJohan Hedberg BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode); 3494a9de9248SMarcel Holtmann break; 3495a9de9248SMarcel Holtmann } 3496a9de9248SMarcel Holtmann 3497e6214487SJohan Hedberg if (*opcode != HCI_OP_NOP) 349865cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 34996bd32326SVille Tervo 3500600b2150SJohan Hedberg if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) 3501600b2150SJohan Hedberg atomic_set(&hdev->cmd_cnt, 1); 3502600b2150SJohan Hedberg 3503444c6dd5SJohan Hedberg /* Indicate request completion if the command failed. Also, if 3504444c6dd5SJohan Hedberg * we're not waiting for a special event and we get a success 3505444c6dd5SJohan Hedberg * command status we should try to flag the request as completed 3506444c6dd5SJohan Hedberg * (since for this kind of commands there will not be a command 3507444c6dd5SJohan Hedberg * complete event). 3508444c6dd5SJohan Hedberg */ 350902350a72SJohan Hedberg if (ev->status || 3510242c0ebdSMarcel Holtmann (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->hci.req_event)) 3511e6214487SJohan Hedberg hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete, 3512e6214487SJohan Hedberg req_complete_skb); 35139238f36aSJohan Hedberg 3514600b2150SJohan Hedberg if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q)) 3515c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 3516a9de9248SMarcel Holtmann } 3517a9de9248SMarcel Holtmann 351824dfa343SMarcel Holtmann static void hci_hardware_error_evt(struct hci_dev *hdev, struct sk_buff *skb) 351924dfa343SMarcel Holtmann { 352024dfa343SMarcel Holtmann struct hci_ev_hardware_error *ev = (void *) skb->data; 352124dfa343SMarcel Holtmann 3522c7741d16SMarcel Holtmann hdev->hw_error_code = ev->code; 3523c7741d16SMarcel Holtmann 3524c7741d16SMarcel Holtmann queue_work(hdev->req_workqueue, &hdev->error_reset); 352524dfa343SMarcel Holtmann } 352624dfa343SMarcel Holtmann 35276039aa73SGustavo Padovan static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 3528a9de9248SMarcel Holtmann { 3529a9de9248SMarcel Holtmann struct hci_ev_role_change *ev = (void *) skb->data; 3530a9de9248SMarcel Holtmann struct hci_conn *conn; 3531a9de9248SMarcel Holtmann 35329f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3533a9de9248SMarcel Holtmann 3534a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3535a9de9248SMarcel Holtmann 3536a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 3537a9de9248SMarcel Holtmann if (conn) { 353840bef302SJohan Hedberg if (!ev->status) 353940bef302SJohan Hedberg conn->role = ev->role; 3540a9de9248SMarcel Holtmann 354151a8efd7SJohan Hedberg clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 3542a9de9248SMarcel Holtmann 3543a9de9248SMarcel Holtmann hci_role_switch_cfm(conn, ev->status, ev->role); 3544a9de9248SMarcel Holtmann } 3545a9de9248SMarcel Holtmann 3546a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3547a9de9248SMarcel Holtmann } 3548a9de9248SMarcel Holtmann 35496039aa73SGustavo Padovan static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) 35501da177e4SLinus Torvalds { 3551a9de9248SMarcel Holtmann struct hci_ev_num_comp_pkts *ev = (void *) skb->data; 35521da177e4SLinus Torvalds int i; 35531da177e4SLinus Torvalds 355432ac5b9bSAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) { 35552064ee33SMarcel Holtmann bt_dev_err(hdev, "wrong event for mode %d", hdev->flow_ctl_mode); 355632ac5b9bSAndrei Emeltchenko return; 355732ac5b9bSAndrei Emeltchenko } 355832ac5b9bSAndrei Emeltchenko 355916e18342SGustavo A. R. Silva if (skb->len < sizeof(*ev) || 356016e18342SGustavo A. R. Silva skb->len < struct_size(ev, handles, ev->num_hndl)) { 35611da177e4SLinus Torvalds BT_DBG("%s bad parameters", hdev->name); 35621da177e4SLinus Torvalds return; 35631da177e4SLinus Torvalds } 35641da177e4SLinus Torvalds 3565c5993de8SAndrei Emeltchenko BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl); 3566c5993de8SAndrei Emeltchenko 3567613a1c0cSAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 3568613a1c0cSAndrei Emeltchenko struct hci_comp_pkts_info *info = &ev->handles[i]; 35691da177e4SLinus Torvalds struct hci_conn *conn; 35701da177e4SLinus Torvalds __u16 handle, count; 35711da177e4SLinus Torvalds 3572613a1c0cSAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 3573613a1c0cSAndrei Emeltchenko count = __le16_to_cpu(info->count); 35741da177e4SLinus Torvalds 35751da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 3576f4280918SAndrei Emeltchenko if (!conn) 3577f4280918SAndrei Emeltchenko continue; 3578f4280918SAndrei Emeltchenko 35791da177e4SLinus Torvalds conn->sent -= count; 35801da177e4SLinus Torvalds 3581f4280918SAndrei Emeltchenko switch (conn->type) { 3582f4280918SAndrei Emeltchenko case ACL_LINK: 358370f23020SAndrei Emeltchenko hdev->acl_cnt += count; 358470f23020SAndrei Emeltchenko if (hdev->acl_cnt > hdev->acl_pkts) 35851da177e4SLinus Torvalds hdev->acl_cnt = hdev->acl_pkts; 3586f4280918SAndrei Emeltchenko break; 3587f4280918SAndrei Emeltchenko 3588f4280918SAndrei Emeltchenko case LE_LINK: 35896ed58ec5SVille Tervo if (hdev->le_pkts) { 35906ed58ec5SVille Tervo hdev->le_cnt += count; 35916ed58ec5SVille Tervo if (hdev->le_cnt > hdev->le_pkts) 35926ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 35936ed58ec5SVille Tervo } else { 35946ed58ec5SVille Tervo hdev->acl_cnt += count; 35956ed58ec5SVille Tervo if (hdev->acl_cnt > hdev->acl_pkts) 35966ed58ec5SVille Tervo hdev->acl_cnt = hdev->acl_pkts; 35976ed58ec5SVille Tervo } 3598f4280918SAndrei Emeltchenko break; 3599f4280918SAndrei Emeltchenko 3600f4280918SAndrei Emeltchenko case SCO_LINK: 360170f23020SAndrei Emeltchenko hdev->sco_cnt += count; 360270f23020SAndrei Emeltchenko if (hdev->sco_cnt > hdev->sco_pkts) 36035b7f9909SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 3604f4280918SAndrei Emeltchenko break; 3605f4280918SAndrei Emeltchenko 3606f4280918SAndrei Emeltchenko default: 36072064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown type %d conn %p", 36082064ee33SMarcel Holtmann conn->type, conn); 3609f4280918SAndrei Emeltchenko break; 36101da177e4SLinus Torvalds } 36111da177e4SLinus Torvalds } 3612a9de9248SMarcel Holtmann 36133eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 36141da177e4SLinus Torvalds } 36151da177e4SLinus Torvalds 361676ef7cf7SAndrei Emeltchenko static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev, 361776ef7cf7SAndrei Emeltchenko __u16 handle) 361876ef7cf7SAndrei Emeltchenko { 361976ef7cf7SAndrei Emeltchenko struct hci_chan *chan; 362076ef7cf7SAndrei Emeltchenko 362176ef7cf7SAndrei Emeltchenko switch (hdev->dev_type) { 3622ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 362376ef7cf7SAndrei Emeltchenko return hci_conn_hash_lookup_handle(hdev, handle); 362476ef7cf7SAndrei Emeltchenko case HCI_AMP: 362576ef7cf7SAndrei Emeltchenko chan = hci_chan_lookup_handle(hdev, handle); 362676ef7cf7SAndrei Emeltchenko if (chan) 362776ef7cf7SAndrei Emeltchenko return chan->conn; 362876ef7cf7SAndrei Emeltchenko break; 362976ef7cf7SAndrei Emeltchenko default: 36302064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type); 363176ef7cf7SAndrei Emeltchenko break; 363276ef7cf7SAndrei Emeltchenko } 363376ef7cf7SAndrei Emeltchenko 363476ef7cf7SAndrei Emeltchenko return NULL; 363576ef7cf7SAndrei Emeltchenko } 363676ef7cf7SAndrei Emeltchenko 36376039aa73SGustavo Padovan static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) 363825e89e99SAndrei Emeltchenko { 363925e89e99SAndrei Emeltchenko struct hci_ev_num_comp_blocks *ev = (void *) skb->data; 364025e89e99SAndrei Emeltchenko int i; 364125e89e99SAndrei Emeltchenko 364225e89e99SAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) { 36432064ee33SMarcel Holtmann bt_dev_err(hdev, "wrong event for mode %d", hdev->flow_ctl_mode); 364425e89e99SAndrei Emeltchenko return; 364525e89e99SAndrei Emeltchenko } 364625e89e99SAndrei Emeltchenko 364716e18342SGustavo A. R. Silva if (skb->len < sizeof(*ev) || 364816e18342SGustavo A. R. Silva skb->len < struct_size(ev, handles, ev->num_hndl)) { 364925e89e99SAndrei Emeltchenko BT_DBG("%s bad parameters", hdev->name); 365025e89e99SAndrei Emeltchenko return; 365125e89e99SAndrei Emeltchenko } 365225e89e99SAndrei Emeltchenko 365325e89e99SAndrei Emeltchenko BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks, 365425e89e99SAndrei Emeltchenko ev->num_hndl); 365525e89e99SAndrei Emeltchenko 365625e89e99SAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 365725e89e99SAndrei Emeltchenko struct hci_comp_blocks_info *info = &ev->handles[i]; 365876ef7cf7SAndrei Emeltchenko struct hci_conn *conn = NULL; 365925e89e99SAndrei Emeltchenko __u16 handle, block_count; 366025e89e99SAndrei Emeltchenko 366125e89e99SAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 366225e89e99SAndrei Emeltchenko block_count = __le16_to_cpu(info->blocks); 366325e89e99SAndrei Emeltchenko 366476ef7cf7SAndrei Emeltchenko conn = __hci_conn_lookup_handle(hdev, handle); 366525e89e99SAndrei Emeltchenko if (!conn) 366625e89e99SAndrei Emeltchenko continue; 366725e89e99SAndrei Emeltchenko 366825e89e99SAndrei Emeltchenko conn->sent -= block_count; 366925e89e99SAndrei Emeltchenko 367025e89e99SAndrei Emeltchenko switch (conn->type) { 367125e89e99SAndrei Emeltchenko case ACL_LINK: 3672bd1eb66bSAndrei Emeltchenko case AMP_LINK: 367325e89e99SAndrei Emeltchenko hdev->block_cnt += block_count; 367425e89e99SAndrei Emeltchenko if (hdev->block_cnt > hdev->num_blocks) 367525e89e99SAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 367625e89e99SAndrei Emeltchenko break; 367725e89e99SAndrei Emeltchenko 367825e89e99SAndrei Emeltchenko default: 36792064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown type %d conn %p", 36802064ee33SMarcel Holtmann conn->type, conn); 368125e89e99SAndrei Emeltchenko break; 368225e89e99SAndrei Emeltchenko } 368325e89e99SAndrei Emeltchenko } 368425e89e99SAndrei Emeltchenko 368525e89e99SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->tx_work); 368625e89e99SAndrei Emeltchenko } 368725e89e99SAndrei Emeltchenko 36886039aa73SGustavo Padovan static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 36891da177e4SLinus Torvalds { 3690a9de9248SMarcel Holtmann struct hci_ev_mode_change *ev = (void *) skb->data; 369104837f64SMarcel Holtmann struct hci_conn *conn; 36921da177e4SLinus Torvalds 36939f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 36941da177e4SLinus Torvalds 36951da177e4SLinus Torvalds hci_dev_lock(hdev); 36961da177e4SLinus Torvalds 369704837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 369804837f64SMarcel Holtmann if (conn) { 369904837f64SMarcel Holtmann conn->mode = ev->mode; 370004837f64SMarcel Holtmann 37018fc9ced3SGustavo Padovan if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, 37028fc9ced3SGustavo Padovan &conn->flags)) { 370304837f64SMarcel Holtmann if (conn->mode == HCI_CM_ACTIVE) 370458a681efSJohan Hedberg set_bit(HCI_CONN_POWER_SAVE, &conn->flags); 370504837f64SMarcel Holtmann else 370658a681efSJohan Hedberg clear_bit(HCI_CONN_POWER_SAVE, &conn->flags); 370704837f64SMarcel Holtmann } 3708e73439d8SMarcel Holtmann 370951a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 3710e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 371104837f64SMarcel Holtmann } 371204837f64SMarcel Holtmann 371304837f64SMarcel Holtmann hci_dev_unlock(hdev); 371404837f64SMarcel Holtmann } 371504837f64SMarcel Holtmann 37166039aa73SGustavo Padovan static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 37171da177e4SLinus Torvalds { 3718052b30b0SMarcel Holtmann struct hci_ev_pin_code_req *ev = (void *) skb->data; 3719052b30b0SMarcel Holtmann struct hci_conn *conn; 3720052b30b0SMarcel Holtmann 3721a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 3722052b30b0SMarcel Holtmann 3723052b30b0SMarcel Holtmann hci_dev_lock(hdev); 3724052b30b0SMarcel Holtmann 3725052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 3726b6f98044SWaldemar Rymarkiewicz if (!conn) 3727b6f98044SWaldemar Rymarkiewicz goto unlock; 3728b6f98044SWaldemar Rymarkiewicz 3729b6f98044SWaldemar Rymarkiewicz if (conn->state == BT_CONNECTED) { 3730052b30b0SMarcel Holtmann hci_conn_hold(conn); 3731052b30b0SMarcel Holtmann conn->disc_timeout = HCI_PAIRING_TIMEOUT; 373276a68ba0SDavid Herrmann hci_conn_drop(conn); 3733052b30b0SMarcel Holtmann } 3734052b30b0SMarcel Holtmann 3735d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE) && 37362f407f0aSJohan Hedberg !test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags)) { 373703b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, 373803b555e1SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 3739d7a5a11dSMarcel Holtmann } else if (hci_dev_test_flag(hdev, HCI_MGMT)) { 3740a770bb5aSWaldemar Rymarkiewicz u8 secure; 3741a770bb5aSWaldemar Rymarkiewicz 3742a770bb5aSWaldemar Rymarkiewicz if (conn->pending_sec_level == BT_SECURITY_HIGH) 3743a770bb5aSWaldemar Rymarkiewicz secure = 1; 3744a770bb5aSWaldemar Rymarkiewicz else 3745a770bb5aSWaldemar Rymarkiewicz secure = 0; 3746a770bb5aSWaldemar Rymarkiewicz 3747744cf19eSJohan Hedberg mgmt_pin_code_request(hdev, &ev->bdaddr, secure); 3748a770bb5aSWaldemar Rymarkiewicz } 3749980e1a53SJohan Hedberg 3750b6f98044SWaldemar Rymarkiewicz unlock: 3751052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 37521da177e4SLinus Torvalds } 37531da177e4SLinus Torvalds 3754cb6f3f7aSJohan Hedberg static void conn_set_key(struct hci_conn *conn, u8 key_type, u8 pin_len) 3755cb6f3f7aSJohan Hedberg { 3756cb6f3f7aSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION) 3757cb6f3f7aSJohan Hedberg return; 3758cb6f3f7aSJohan Hedberg 3759cb6f3f7aSJohan Hedberg conn->pin_length = pin_len; 3760cb6f3f7aSJohan Hedberg conn->key_type = key_type; 3761cb6f3f7aSJohan Hedberg 3762cb6f3f7aSJohan Hedberg switch (key_type) { 3763cb6f3f7aSJohan Hedberg case HCI_LK_LOCAL_UNIT: 3764cb6f3f7aSJohan Hedberg case HCI_LK_REMOTE_UNIT: 3765cb6f3f7aSJohan Hedberg case HCI_LK_DEBUG_COMBINATION: 3766cb6f3f7aSJohan Hedberg return; 3767cb6f3f7aSJohan Hedberg case HCI_LK_COMBINATION: 3768cb6f3f7aSJohan Hedberg if (pin_len == 16) 3769cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_HIGH; 3770cb6f3f7aSJohan Hedberg else 3771cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_MEDIUM; 3772cb6f3f7aSJohan Hedberg break; 3773cb6f3f7aSJohan Hedberg case HCI_LK_UNAUTH_COMBINATION_P192: 3774cb6f3f7aSJohan Hedberg case HCI_LK_UNAUTH_COMBINATION_P256: 3775cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_MEDIUM; 3776cb6f3f7aSJohan Hedberg break; 3777cb6f3f7aSJohan Hedberg case HCI_LK_AUTH_COMBINATION_P192: 3778cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_HIGH; 3779cb6f3f7aSJohan Hedberg break; 3780cb6f3f7aSJohan Hedberg case HCI_LK_AUTH_COMBINATION_P256: 3781cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_FIPS; 3782cb6f3f7aSJohan Hedberg break; 3783cb6f3f7aSJohan Hedberg } 3784cb6f3f7aSJohan Hedberg } 3785cb6f3f7aSJohan Hedberg 37866039aa73SGustavo Padovan static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 37871da177e4SLinus Torvalds { 378855ed8ca1SJohan Hedberg struct hci_ev_link_key_req *ev = (void *) skb->data; 378955ed8ca1SJohan Hedberg struct hci_cp_link_key_reply cp; 379055ed8ca1SJohan Hedberg struct hci_conn *conn; 379155ed8ca1SJohan Hedberg struct link_key *key; 379255ed8ca1SJohan Hedberg 3793a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 379455ed8ca1SJohan Hedberg 3795d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 379655ed8ca1SJohan Hedberg return; 379755ed8ca1SJohan Hedberg 379855ed8ca1SJohan Hedberg hci_dev_lock(hdev); 379955ed8ca1SJohan Hedberg 380055ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, &ev->bdaddr); 380155ed8ca1SJohan Hedberg if (!key) { 38026ed93dc6SAndrei Emeltchenko BT_DBG("%s link key not found for %pMR", hdev->name, 38036ed93dc6SAndrei Emeltchenko &ev->bdaddr); 380455ed8ca1SJohan Hedberg goto not_found; 380555ed8ca1SJohan Hedberg } 380655ed8ca1SJohan Hedberg 38076ed93dc6SAndrei Emeltchenko BT_DBG("%s found key type %u for %pMR", hdev->name, key->type, 38086ed93dc6SAndrei Emeltchenko &ev->bdaddr); 380955ed8ca1SJohan Hedberg 381055ed8ca1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 381160b83f57SWaldemar Rymarkiewicz if (conn) { 3812fe8bc5acSJohan Hedberg clear_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags); 3813fe8bc5acSJohan Hedberg 381466138ce8SMarcel Holtmann if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 || 381566138ce8SMarcel Holtmann key->type == HCI_LK_UNAUTH_COMBINATION_P256) && 3816807deac2SGustavo Padovan conn->auth_type != 0xff && (conn->auth_type & 0x01)) { 381755ed8ca1SJohan Hedberg BT_DBG("%s ignoring unauthenticated key", hdev->name); 381855ed8ca1SJohan Hedberg goto not_found; 381955ed8ca1SJohan Hedberg } 382055ed8ca1SJohan Hedberg 382160b83f57SWaldemar Rymarkiewicz if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && 3822f3fb0b58SJohan Hedberg (conn->pending_sec_level == BT_SECURITY_HIGH || 3823f3fb0b58SJohan Hedberg conn->pending_sec_level == BT_SECURITY_FIPS)) { 38248fc9ced3SGustavo Padovan BT_DBG("%s ignoring key unauthenticated for high security", 38258fc9ced3SGustavo Padovan hdev->name); 382660b83f57SWaldemar Rymarkiewicz goto not_found; 382760b83f57SWaldemar Rymarkiewicz } 382860b83f57SWaldemar Rymarkiewicz 3829cb6f3f7aSJohan Hedberg conn_set_key(conn, key->type, key->pin_len); 383060b83f57SWaldemar Rymarkiewicz } 383160b83f57SWaldemar Rymarkiewicz 383255ed8ca1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 38339b3b4460SAndrei Emeltchenko memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE); 383455ed8ca1SJohan Hedberg 383555ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp); 383655ed8ca1SJohan Hedberg 383755ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 383855ed8ca1SJohan Hedberg 383955ed8ca1SJohan Hedberg return; 384055ed8ca1SJohan Hedberg 384155ed8ca1SJohan Hedberg not_found: 384255ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr); 384355ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 38441da177e4SLinus Torvalds } 38451da177e4SLinus Torvalds 38466039aa73SGustavo Padovan static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 38471da177e4SLinus Torvalds { 3848052b30b0SMarcel Holtmann struct hci_ev_link_key_notify *ev = (void *) skb->data; 3849052b30b0SMarcel Holtmann struct hci_conn *conn; 38507652ff6aSJohan Hedberg struct link_key *key; 38517652ff6aSJohan Hedberg bool persistent; 385255ed8ca1SJohan Hedberg u8 pin_len = 0; 3853052b30b0SMarcel Holtmann 3854a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 3855052b30b0SMarcel Holtmann 3856052b30b0SMarcel Holtmann hci_dev_lock(hdev); 3857052b30b0SMarcel Holtmann 3858052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 385982c13d42SJohan Hedberg if (!conn) 386082c13d42SJohan Hedberg goto unlock; 386182c13d42SJohan Hedberg 3862052b30b0SMarcel Holtmann hci_conn_hold(conn); 3863052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 386476a68ba0SDavid Herrmann hci_conn_drop(conn); 386582c13d42SJohan Hedberg 3866fe8bc5acSJohan Hedberg set_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags); 3867cb6f3f7aSJohan Hedberg conn_set_key(conn, ev->key_type, conn->pin_length); 3868052b30b0SMarcel Holtmann 3869d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 38707652ff6aSJohan Hedberg goto unlock; 387155ed8ca1SJohan Hedberg 38727652ff6aSJohan Hedberg key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key, 38737652ff6aSJohan Hedberg ev->key_type, pin_len, &persistent); 38747652ff6aSJohan Hedberg if (!key) 38757652ff6aSJohan Hedberg goto unlock; 38767652ff6aSJohan Hedberg 3877cb6f3f7aSJohan Hedberg /* Update connection information since adding the key will have 3878cb6f3f7aSJohan Hedberg * fixed up the type in the case of changed combination keys. 3879cb6f3f7aSJohan Hedberg */ 3880cb6f3f7aSJohan Hedberg if (ev->key_type == HCI_LK_CHANGED_COMBINATION) 3881cb6f3f7aSJohan Hedberg conn_set_key(conn, key->type, key->pin_len); 3882cb6f3f7aSJohan Hedberg 38837652ff6aSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 38847652ff6aSJohan Hedberg 38856d5650c4SJohan Hedberg /* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag 38866d5650c4SJohan Hedberg * is set. If it's not set simply remove the key from the kernel 38876d5650c4SJohan Hedberg * list (we've still notified user space about it but with 38886d5650c4SJohan Hedberg * store_hint being 0). 38896d5650c4SJohan Hedberg */ 38906d5650c4SJohan Hedberg if (key->type == HCI_LK_DEBUG_COMBINATION && 3891d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS)) { 38920378b597SJohan Hedberg list_del_rcu(&key->list); 38930378b597SJohan Hedberg kfree_rcu(key, rcu); 389482c13d42SJohan Hedberg goto unlock; 389582c13d42SJohan Hedberg } 389682c13d42SJohan Hedberg 3897af6a9c32SJohan Hedberg if (persistent) 3898af6a9c32SJohan Hedberg clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags); 3899af6a9c32SJohan Hedberg else 3900af6a9c32SJohan Hedberg set_bit(HCI_CONN_FLUSH_KEY, &conn->flags); 39017652ff6aSJohan Hedberg 39027652ff6aSJohan Hedberg unlock: 3903052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 39041da177e4SLinus Torvalds } 39051da177e4SLinus Torvalds 39066039aa73SGustavo Padovan static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) 390704837f64SMarcel Holtmann { 3908a9de9248SMarcel Holtmann struct hci_ev_clock_offset *ev = (void *) skb->data; 390904837f64SMarcel Holtmann struct hci_conn *conn; 391004837f64SMarcel Holtmann 39119f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 391204837f64SMarcel Holtmann 391304837f64SMarcel Holtmann hci_dev_lock(hdev); 391404837f64SMarcel Holtmann 391504837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 39161da177e4SLinus Torvalds if (conn && !ev->status) { 39171da177e4SLinus Torvalds struct inquiry_entry *ie; 39181da177e4SLinus Torvalds 3919cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 3920cc11b9c1SAndrei Emeltchenko if (ie) { 39211da177e4SLinus Torvalds ie->data.clock_offset = ev->clock_offset; 39221da177e4SLinus Torvalds ie->timestamp = jiffies; 39231da177e4SLinus Torvalds } 39241da177e4SLinus Torvalds } 39251da177e4SLinus Torvalds 39261da177e4SLinus Torvalds hci_dev_unlock(hdev); 39271da177e4SLinus Torvalds } 39281da177e4SLinus Torvalds 39296039aa73SGustavo Padovan static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 3930a8746417SMarcel Holtmann { 3931a8746417SMarcel Holtmann struct hci_ev_pkt_type_change *ev = (void *) skb->data; 3932a8746417SMarcel Holtmann struct hci_conn *conn; 3933a8746417SMarcel Holtmann 39349f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3935a8746417SMarcel Holtmann 3936a8746417SMarcel Holtmann hci_dev_lock(hdev); 3937a8746417SMarcel Holtmann 3938a8746417SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3939a8746417SMarcel Holtmann if (conn && !ev->status) 3940a8746417SMarcel Holtmann conn->pkt_type = __le16_to_cpu(ev->pkt_type); 3941a8746417SMarcel Holtmann 3942a8746417SMarcel Holtmann hci_dev_unlock(hdev); 3943a8746417SMarcel Holtmann } 3944a8746417SMarcel Holtmann 39456039aa73SGustavo Padovan static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) 394685a1e930SMarcel Holtmann { 3947a9de9248SMarcel Holtmann struct hci_ev_pscan_rep_mode *ev = (void *) skb->data; 394885a1e930SMarcel Holtmann struct inquiry_entry *ie; 394985a1e930SMarcel Holtmann 395085a1e930SMarcel Holtmann BT_DBG("%s", hdev->name); 395185a1e930SMarcel Holtmann 395285a1e930SMarcel Holtmann hci_dev_lock(hdev); 395385a1e930SMarcel Holtmann 3954cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 3955cc11b9c1SAndrei Emeltchenko if (ie) { 395685a1e930SMarcel Holtmann ie->data.pscan_rep_mode = ev->pscan_rep_mode; 395785a1e930SMarcel Holtmann ie->timestamp = jiffies; 395885a1e930SMarcel Holtmann } 395985a1e930SMarcel Holtmann 396085a1e930SMarcel Holtmann hci_dev_unlock(hdev); 396185a1e930SMarcel Holtmann } 396285a1e930SMarcel Holtmann 39636039aa73SGustavo Padovan static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, 3964807deac2SGustavo Padovan struct sk_buff *skb) 3965a9de9248SMarcel Holtmann { 3966a9de9248SMarcel Holtmann struct inquiry_data data; 3967a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 3968a9de9248SMarcel Holtmann 3969a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 3970a9de9248SMarcel Holtmann 3971a9de9248SMarcel Holtmann if (!num_rsp) 3972a9de9248SMarcel Holtmann return; 3973a9de9248SMarcel Holtmann 3974d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) 39751519cc17SAndre Guedes return; 39761519cc17SAndre Guedes 3977a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3978a9de9248SMarcel Holtmann 3979a9de9248SMarcel Holtmann if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { 3980138d22efSSzymon Janc struct inquiry_info_with_rssi_and_pscan_mode *info; 3981138d22efSSzymon Janc info = (void *) (skb->data + 1); 3982a9de9248SMarcel Holtmann 3983e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3984af58925cSMarcel Holtmann u32 flags; 3985af58925cSMarcel Holtmann 3986a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3987a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3988a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3989a9de9248SMarcel Holtmann data.pscan_mode = info->pscan_mode; 3990a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3991a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3992a9de9248SMarcel Holtmann data.rssi = info->rssi; 399341a96212SMarcel Holtmann data.ssp_mode = 0x00; 39943175405bSJohan Hedberg 3995af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 3996af58925cSMarcel Holtmann 399748264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3998e17acd40SJohan Hedberg info->dev_class, info->rssi, 3999af58925cSMarcel Holtmann flags, NULL, 0, NULL, 0); 4000a9de9248SMarcel Holtmann } 4001a9de9248SMarcel Holtmann } else { 4002a9de9248SMarcel Holtmann struct inquiry_info_with_rssi *info = (void *) (skb->data + 1); 4003a9de9248SMarcel Holtmann 4004e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 4005af58925cSMarcel Holtmann u32 flags; 4006af58925cSMarcel Holtmann 4007a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 4008a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 4009a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 4010a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 4011a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 4012a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 4013a9de9248SMarcel Holtmann data.rssi = info->rssi; 401441a96212SMarcel Holtmann data.ssp_mode = 0x00; 4015af58925cSMarcel Holtmann 4016af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 4017af58925cSMarcel Holtmann 401848264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 4019e17acd40SJohan Hedberg info->dev_class, info->rssi, 4020af58925cSMarcel Holtmann flags, NULL, 0, NULL, 0); 4021a9de9248SMarcel Holtmann } 4022a9de9248SMarcel Holtmann } 4023a9de9248SMarcel Holtmann 4024a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 4025a9de9248SMarcel Holtmann } 4026a9de9248SMarcel Holtmann 40276039aa73SGustavo Padovan static void hci_remote_ext_features_evt(struct hci_dev *hdev, 4028807deac2SGustavo Padovan struct sk_buff *skb) 4029a9de9248SMarcel Holtmann { 403041a96212SMarcel Holtmann struct hci_ev_remote_ext_features *ev = (void *) skb->data; 403141a96212SMarcel Holtmann struct hci_conn *conn; 403241a96212SMarcel Holtmann 4033a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 403441a96212SMarcel Holtmann 403541a96212SMarcel Holtmann hci_dev_lock(hdev); 403641a96212SMarcel Holtmann 403741a96212SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 4038ccd556feSJohan Hedberg if (!conn) 4039ccd556feSJohan Hedberg goto unlock; 4040ccd556feSJohan Hedberg 4041cad718edSJohan Hedberg if (ev->page < HCI_MAX_PAGES) 4042cad718edSJohan Hedberg memcpy(conn->features[ev->page], ev->features, 8); 4043cad718edSJohan Hedberg 4044769be974SMarcel Holtmann if (!ev->status && ev->page == 0x01) { 404541a96212SMarcel Holtmann struct inquiry_entry *ie; 404641a96212SMarcel Holtmann 4047cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 4048cc11b9c1SAndrei Emeltchenko if (ie) 404902b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 405041a96212SMarcel Holtmann 4051bbb0eadaSJaganath Kanakkassery if (ev->features[0] & LMP_HOST_SSP) { 405258a681efSJohan Hedberg set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 4053bbb0eadaSJaganath Kanakkassery } else { 4054bbb0eadaSJaganath Kanakkassery /* It is mandatory by the Bluetooth specification that 4055bbb0eadaSJaganath Kanakkassery * Extended Inquiry Results are only used when Secure 4056bbb0eadaSJaganath Kanakkassery * Simple Pairing is enabled, but some devices violate 4057bbb0eadaSJaganath Kanakkassery * this. 4058bbb0eadaSJaganath Kanakkassery * 4059bbb0eadaSJaganath Kanakkassery * To make these devices work, the internal SSP 4060bbb0eadaSJaganath Kanakkassery * enabled flag needs to be cleared if the remote host 4061bbb0eadaSJaganath Kanakkassery * features do not indicate SSP support */ 4062bbb0eadaSJaganath Kanakkassery clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 4063bbb0eadaSJaganath Kanakkassery } 4064eb9a8f3fSMarcel Holtmann 4065eb9a8f3fSMarcel Holtmann if (ev->features[0] & LMP_HOST_SC) 4066eb9a8f3fSMarcel Holtmann set_bit(HCI_CONN_SC_ENABLED, &conn->flags); 406741a96212SMarcel Holtmann } 406841a96212SMarcel Holtmann 4069ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 4070ccd556feSJohan Hedberg goto unlock; 4071ccd556feSJohan Hedberg 4072671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 4073127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 4074127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 4075127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 4076127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 4077127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 4078b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 407948ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, NULL, 0); 4080392599b9SJohan Hedberg 4081127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 4082769be974SMarcel Holtmann conn->state = BT_CONNECTED; 4083539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 408476a68ba0SDavid Herrmann hci_conn_drop(conn); 4085769be974SMarcel Holtmann } 4086769be974SMarcel Holtmann 4087ccd556feSJohan Hedberg unlock: 408841a96212SMarcel Holtmann hci_dev_unlock(hdev); 4089a9de9248SMarcel Holtmann } 4090a9de9248SMarcel Holtmann 40916039aa73SGustavo Padovan static void hci_sync_conn_complete_evt(struct hci_dev *hdev, 4092807deac2SGustavo Padovan struct sk_buff *skb) 4093a9de9248SMarcel Holtmann { 4094b6a0dc82SMarcel Holtmann struct hci_ev_sync_conn_complete *ev = (void *) skb->data; 4095b6a0dc82SMarcel Holtmann struct hci_conn *conn; 4096b6a0dc82SMarcel Holtmann 40979f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 4098b6a0dc82SMarcel Holtmann 4099b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 4100b6a0dc82SMarcel Holtmann 4101b6a0dc82SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 41029dc0a3afSMarcel Holtmann if (!conn) { 41039dc0a3afSMarcel Holtmann if (ev->link_type == ESCO_LINK) 41049dc0a3afSMarcel Holtmann goto unlock; 41059dc0a3afSMarcel Holtmann 4106618353b1SKuba Pawlak /* When the link type in the event indicates SCO connection 4107618353b1SKuba Pawlak * and lookup of the connection object fails, then check 4108618353b1SKuba Pawlak * if an eSCO connection object exists. 4109618353b1SKuba Pawlak * 4110618353b1SKuba Pawlak * The core limits the synchronous connections to either 4111618353b1SKuba Pawlak * SCO or eSCO. The eSCO connection is preferred and tried 4112618353b1SKuba Pawlak * to be setup first and until successfully established, 4113618353b1SKuba Pawlak * the link type will be hinted as eSCO. 4114618353b1SKuba Pawlak */ 41159dc0a3afSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 4116b6a0dc82SMarcel Holtmann if (!conn) 4117b6a0dc82SMarcel Holtmann goto unlock; 41189dc0a3afSMarcel Holtmann } 41199dc0a3afSMarcel Holtmann 4120732547f9SMarcel Holtmann switch (ev->status) { 4121732547f9SMarcel Holtmann case 0x00: 4122732547f9SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 4123732547f9SMarcel Holtmann conn->state = BT_CONNECTED; 4124618353b1SKuba Pawlak conn->type = ev->link_type; 4125732547f9SMarcel Holtmann 412623b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn); 4127732547f9SMarcel Holtmann hci_conn_add_sysfs(conn); 4128732547f9SMarcel Holtmann break; 4129732547f9SMarcel Holtmann 413081218d20SNick Pelly case 0x10: /* Connection Accept Timeout */ 41311a4c958cSFrédéric Dalleau case 0x0d: /* Connection Rejected due to Limited Resources */ 4132705e5711SStephen Coe case 0x11: /* Unsupported Feature or Parameter Value */ 4133732547f9SMarcel Holtmann case 0x1c: /* SCO interval rejected */ 41341038a00bSNick Pelly case 0x1a: /* Unsupported Remote Feature */ 4135732547f9SMarcel Holtmann case 0x1f: /* Unspecified error */ 413627539bc4SAndrew Earl case 0x20: /* Unsupported LMP Parameter value */ 41372dea632fSFrédéric Dalleau if (conn->out) { 4138efc7688bSMarcel Holtmann conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | 4139efc7688bSMarcel Holtmann (hdev->esco_type & EDR_ESCO_MASK); 41402dea632fSFrédéric Dalleau if (hci_setup_sync(conn, conn->link->handle)) 4141efc7688bSMarcel Holtmann goto unlock; 4142efc7688bSMarcel Holtmann } 4143732547f9SMarcel Holtmann /* fall through */ 4144efc7688bSMarcel Holtmann 4145732547f9SMarcel Holtmann default: 4146b6a0dc82SMarcel Holtmann conn->state = BT_CLOSED; 4147732547f9SMarcel Holtmann break; 4148732547f9SMarcel Holtmann } 4149b6a0dc82SMarcel Holtmann 4150539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 4151b6a0dc82SMarcel Holtmann if (ev->status) 4152b6a0dc82SMarcel Holtmann hci_conn_del(conn); 4153b6a0dc82SMarcel Holtmann 4154b6a0dc82SMarcel Holtmann unlock: 4155b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 4156a9de9248SMarcel Holtmann } 4157a9de9248SMarcel Holtmann 4158efdcf8e3SMarcel Holtmann static inline size_t eir_get_length(u8 *eir, size_t eir_len) 4159efdcf8e3SMarcel Holtmann { 4160efdcf8e3SMarcel Holtmann size_t parsed = 0; 4161efdcf8e3SMarcel Holtmann 4162efdcf8e3SMarcel Holtmann while (parsed < eir_len) { 4163efdcf8e3SMarcel Holtmann u8 field_len = eir[0]; 4164efdcf8e3SMarcel Holtmann 4165efdcf8e3SMarcel Holtmann if (field_len == 0) 4166efdcf8e3SMarcel Holtmann return parsed; 4167efdcf8e3SMarcel Holtmann 4168efdcf8e3SMarcel Holtmann parsed += field_len + 1; 4169efdcf8e3SMarcel Holtmann eir += field_len + 1; 4170efdcf8e3SMarcel Holtmann } 4171efdcf8e3SMarcel Holtmann 4172efdcf8e3SMarcel Holtmann return eir_len; 4173efdcf8e3SMarcel Holtmann } 4174efdcf8e3SMarcel Holtmann 41756039aa73SGustavo Padovan static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, 4176807deac2SGustavo Padovan struct sk_buff *skb) 4177a9de9248SMarcel Holtmann { 4178a9de9248SMarcel Holtmann struct inquiry_data data; 4179a9de9248SMarcel Holtmann struct extended_inquiry_info *info = (void *) (skb->data + 1); 4180a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 41819d939d94SVishal Agarwal size_t eir_len; 4182a9de9248SMarcel Holtmann 4183a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 4184a9de9248SMarcel Holtmann 4185a9de9248SMarcel Holtmann if (!num_rsp) 4186a9de9248SMarcel Holtmann return; 4187a9de9248SMarcel Holtmann 4188d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) 41891519cc17SAndre Guedes return; 41901519cc17SAndre Guedes 4191a9de9248SMarcel Holtmann hci_dev_lock(hdev); 4192a9de9248SMarcel Holtmann 4193e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 4194af58925cSMarcel Holtmann u32 flags; 4195af58925cSMarcel Holtmann bool name_known; 4196561aafbcSJohan Hedberg 4197a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 4198a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 4199a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 4200a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 4201a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 4202a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 4203a9de9248SMarcel Holtmann data.rssi = info->rssi; 420441a96212SMarcel Holtmann data.ssp_mode = 0x01; 4205561aafbcSJohan Hedberg 4206d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 42070d3b7f64SJohan Hedberg name_known = eir_get_data(info->data, 42084ddb1930SJohan Hedberg sizeof(info->data), 42090d3b7f64SJohan Hedberg EIR_NAME_COMPLETE, NULL); 4210561aafbcSJohan Hedberg else 4211561aafbcSJohan Hedberg name_known = true; 4212561aafbcSJohan Hedberg 4213af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, name_known); 4214af58925cSMarcel Holtmann 42159d939d94SVishal Agarwal eir_len = eir_get_length(info->data, sizeof(info->data)); 4216af58925cSMarcel Holtmann 421748264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 4218af58925cSMarcel Holtmann info->dev_class, info->rssi, 4219af58925cSMarcel Holtmann flags, info->data, eir_len, NULL, 0); 4220a9de9248SMarcel Holtmann } 4221a9de9248SMarcel Holtmann 4222a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 4223a9de9248SMarcel Holtmann } 4224a9de9248SMarcel Holtmann 42251c2e0041SJohan Hedberg static void hci_key_refresh_complete_evt(struct hci_dev *hdev, 42261c2e0041SJohan Hedberg struct sk_buff *skb) 42271c2e0041SJohan Hedberg { 42281c2e0041SJohan Hedberg struct hci_ev_key_refresh_complete *ev = (void *) skb->data; 42291c2e0041SJohan Hedberg struct hci_conn *conn; 42301c2e0041SJohan Hedberg 42319f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status, 42321c2e0041SJohan Hedberg __le16_to_cpu(ev->handle)); 42331c2e0041SJohan Hedberg 42341c2e0041SJohan Hedberg hci_dev_lock(hdev); 42351c2e0041SJohan Hedberg 42361c2e0041SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 42371c2e0041SJohan Hedberg if (!conn) 42381c2e0041SJohan Hedberg goto unlock; 42391c2e0041SJohan Hedberg 42409eb1fbfaSJohan Hedberg /* For BR/EDR the necessary steps are taken through the 42419eb1fbfaSJohan Hedberg * auth_complete event. 42429eb1fbfaSJohan Hedberg */ 42439eb1fbfaSJohan Hedberg if (conn->type != LE_LINK) 42449eb1fbfaSJohan Hedberg goto unlock; 42459eb1fbfaSJohan Hedberg 42461c2e0041SJohan Hedberg if (!ev->status) 42471c2e0041SJohan Hedberg conn->sec_level = conn->pending_sec_level; 42481c2e0041SJohan Hedberg 42491c2e0041SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 42501c2e0041SJohan Hedberg 42511c2e0041SJohan Hedberg if (ev->status && conn->state == BT_CONNECTED) { 4252bed71748SAndre Guedes hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 425376a68ba0SDavid Herrmann hci_conn_drop(conn); 42541c2e0041SJohan Hedberg goto unlock; 42551c2e0041SJohan Hedberg } 42561c2e0041SJohan Hedberg 42571c2e0041SJohan Hedberg if (conn->state == BT_CONFIG) { 42581c2e0041SJohan Hedberg if (!ev->status) 42591c2e0041SJohan Hedberg conn->state = BT_CONNECTED; 42601c2e0041SJohan Hedberg 4261539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 426276a68ba0SDavid Herrmann hci_conn_drop(conn); 42631c2e0041SJohan Hedberg } else { 42641c2e0041SJohan Hedberg hci_auth_cfm(conn, ev->status); 42651c2e0041SJohan Hedberg 42661c2e0041SJohan Hedberg hci_conn_hold(conn); 42671c2e0041SJohan Hedberg conn->disc_timeout = HCI_DISCONN_TIMEOUT; 426876a68ba0SDavid Herrmann hci_conn_drop(conn); 42691c2e0041SJohan Hedberg } 42701c2e0041SJohan Hedberg 42711c2e0041SJohan Hedberg unlock: 42721c2e0041SJohan Hedberg hci_dev_unlock(hdev); 42731c2e0041SJohan Hedberg } 42741c2e0041SJohan Hedberg 42756039aa73SGustavo Padovan static u8 hci_get_auth_req(struct hci_conn *conn) 427617fa4b9dSJohan Hedberg { 427717fa4b9dSJohan Hedberg /* If remote requests no-bonding follow that lead */ 4278acabae96SMikel Astiz if (conn->remote_auth == HCI_AT_NO_BONDING || 4279acabae96SMikel Astiz conn->remote_auth == HCI_AT_NO_BONDING_MITM) 428058797bf7SWaldemar Rymarkiewicz return conn->remote_auth | (conn->auth_type & 0x01); 428117fa4b9dSJohan Hedberg 4282b7f94c88SMikel Astiz /* If both remote and local have enough IO capabilities, require 4283b7f94c88SMikel Astiz * MITM protection 4284b7f94c88SMikel Astiz */ 4285b7f94c88SMikel Astiz if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT && 4286b7f94c88SMikel Astiz conn->io_capability != HCI_IO_NO_INPUT_OUTPUT) 4287b7f94c88SMikel Astiz return conn->remote_auth | 0x01; 4288b7f94c88SMikel Astiz 42897e74170aSTimo Mueller /* No MITM protection possible so ignore remote requirement */ 42907e74170aSTimo Mueller return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01); 429117fa4b9dSJohan Hedberg } 429217fa4b9dSJohan Hedberg 4293a83ed81eSMarcel Holtmann static u8 bredr_oob_data_present(struct hci_conn *conn) 4294a83ed81eSMarcel Holtmann { 4295a83ed81eSMarcel Holtmann struct hci_dev *hdev = conn->hdev; 4296a83ed81eSMarcel Holtmann struct oob_data *data; 4297a83ed81eSMarcel Holtmann 4298a83ed81eSMarcel Holtmann data = hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR); 4299a83ed81eSMarcel Holtmann if (!data) 4300a83ed81eSMarcel Holtmann return 0x00; 4301a83ed81eSMarcel Holtmann 4302bf21d793SMarcel Holtmann if (bredr_sc_enabled(hdev)) { 4303bf21d793SMarcel Holtmann /* When Secure Connections is enabled, then just 4304bf21d793SMarcel Holtmann * return the present value stored with the OOB 4305bf21d793SMarcel Holtmann * data. The stored value contains the right present 4306bf21d793SMarcel Holtmann * information. However it can only be trusted when 4307bf21d793SMarcel Holtmann * not in Secure Connection Only mode. 4308aa5b0345SMarcel Holtmann */ 4309d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SC_ONLY)) 4310bf21d793SMarcel Holtmann return data->present; 4311bf21d793SMarcel Holtmann 4312bf21d793SMarcel Holtmann /* When Secure Connections Only mode is enabled, then 4313bf21d793SMarcel Holtmann * the P-256 values are required. If they are not 4314bf21d793SMarcel Holtmann * available, then do not declare that OOB data is 4315bf21d793SMarcel Holtmann * present. 4316bf21d793SMarcel Holtmann */ 4317bf21d793SMarcel Holtmann if (!memcmp(data->rand256, ZERO_KEY, 16) || 4318bf21d793SMarcel Holtmann !memcmp(data->hash256, ZERO_KEY, 16)) 4319aa5b0345SMarcel Holtmann return 0x00; 4320aa5b0345SMarcel Holtmann 4321bf21d793SMarcel Holtmann return 0x02; 4322bf21d793SMarcel Holtmann } 4323659c7fb0SMarcel Holtmann 4324659c7fb0SMarcel Holtmann /* When Secure Connections is not enabled or actually 4325659c7fb0SMarcel Holtmann * not supported by the hardware, then check that if 4326659c7fb0SMarcel Holtmann * P-192 data values are present. 4327659c7fb0SMarcel Holtmann */ 4328659c7fb0SMarcel Holtmann if (!memcmp(data->rand192, ZERO_KEY, 16) || 4329659c7fb0SMarcel Holtmann !memcmp(data->hash192, ZERO_KEY, 16)) 4330659c7fb0SMarcel Holtmann return 0x00; 4331659c7fb0SMarcel Holtmann 4332a83ed81eSMarcel Holtmann return 0x01; 4333659c7fb0SMarcel Holtmann } 4334a83ed81eSMarcel Holtmann 43356039aa73SGustavo Padovan static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 43360493684eSMarcel Holtmann { 43370493684eSMarcel Holtmann struct hci_ev_io_capa_request *ev = (void *) skb->data; 43380493684eSMarcel Holtmann struct hci_conn *conn; 43390493684eSMarcel Holtmann 43400493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 43410493684eSMarcel Holtmann 43420493684eSMarcel Holtmann hci_dev_lock(hdev); 43430493684eSMarcel Holtmann 43440493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 434503b555e1SJohan Hedberg if (!conn) 434603b555e1SJohan Hedberg goto unlock; 434703b555e1SJohan Hedberg 43480493684eSMarcel Holtmann hci_conn_hold(conn); 43490493684eSMarcel Holtmann 4350d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 435103b555e1SJohan Hedberg goto unlock; 435203b555e1SJohan Hedberg 43532f407f0aSJohan Hedberg /* Allow pairing if we're pairable, the initiators of the 43542f407f0aSJohan Hedberg * pairing or if the remote is not requesting bonding. 43552f407f0aSJohan Hedberg */ 4356d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_BONDABLE) || 43572f407f0aSJohan Hedberg test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags) || 435803b555e1SJohan Hedberg (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { 435917fa4b9dSJohan Hedberg struct hci_cp_io_capability_reply cp; 436017fa4b9dSJohan Hedberg 436117fa4b9dSJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 43627a7f1e7cSHemant Gupta /* Change the IO capability from KeyboardDisplay 43637a7f1e7cSHemant Gupta * to DisplayYesNo as it is not supported by BT spec. */ 43647a7f1e7cSHemant Gupta cp.capability = (conn->io_capability == 0x04) ? 4365a767631aSMikel Astiz HCI_IO_DISPLAY_YESNO : conn->io_capability; 4366b7f94c88SMikel Astiz 4367b7f94c88SMikel Astiz /* If we are initiators, there is no remote information yet */ 4368b7f94c88SMikel Astiz if (conn->remote_auth == 0xff) { 4369b16c6604SMikel Astiz /* Request MITM protection if our IO caps allow it 43704ad51a75SJohan Hedberg * except for the no-bonding case. 4371b16c6604SMikel Astiz */ 43726fd6b915SMikel Astiz if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT && 43739f743d74SJohan Hedberg conn->auth_type != HCI_AT_NO_BONDING) 43746c53823aSJohan Hedberg conn->auth_type |= 0x01; 4375b7f94c88SMikel Astiz } else { 43767cbc9bd9SJohan Hedberg conn->auth_type = hci_get_auth_req(conn); 4377b7f94c88SMikel Astiz } 437817fa4b9dSJohan Hedberg 437982c295b1SJohan Hedberg /* If we're not bondable, force one of the non-bondable 438082c295b1SJohan Hedberg * authentication requirement values. 438182c295b1SJohan Hedberg */ 4382d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE)) 438382c295b1SJohan Hedberg conn->auth_type &= HCI_AT_NO_BONDING_MITM; 438482c295b1SJohan Hedberg 438582c295b1SJohan Hedberg cp.authentication = conn->auth_type; 4386a83ed81eSMarcel Holtmann cp.oob_data = bredr_oob_data_present(conn); 4387ce85ee13SSzymon Janc 438817fa4b9dSJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY, 438917fa4b9dSJohan Hedberg sizeof(cp), &cp); 439003b555e1SJohan Hedberg } else { 439103b555e1SJohan Hedberg struct hci_cp_io_capability_neg_reply cp; 439203b555e1SJohan Hedberg 439303b555e1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 43949f5a0d7bSAndrei Emeltchenko cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED; 439503b555e1SJohan Hedberg 439603b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, 439703b555e1SJohan Hedberg sizeof(cp), &cp); 439803b555e1SJohan Hedberg } 439903b555e1SJohan Hedberg 440003b555e1SJohan Hedberg unlock: 440103b555e1SJohan Hedberg hci_dev_unlock(hdev); 440203b555e1SJohan Hedberg } 440303b555e1SJohan Hedberg 44046039aa73SGustavo Padovan static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) 440503b555e1SJohan Hedberg { 440603b555e1SJohan Hedberg struct hci_ev_io_capa_reply *ev = (void *) skb->data; 440703b555e1SJohan Hedberg struct hci_conn *conn; 440803b555e1SJohan Hedberg 440903b555e1SJohan Hedberg BT_DBG("%s", hdev->name); 441003b555e1SJohan Hedberg 441103b555e1SJohan Hedberg hci_dev_lock(hdev); 441203b555e1SJohan Hedberg 441303b555e1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 441403b555e1SJohan Hedberg if (!conn) 441503b555e1SJohan Hedberg goto unlock; 441603b555e1SJohan Hedberg 441703b555e1SJohan Hedberg conn->remote_cap = ev->capability; 441803b555e1SJohan Hedberg conn->remote_auth = ev->authentication; 441903b555e1SJohan Hedberg 442003b555e1SJohan Hedberg unlock: 44210493684eSMarcel Holtmann hci_dev_unlock(hdev); 44220493684eSMarcel Holtmann } 44230493684eSMarcel Holtmann 44246039aa73SGustavo Padovan static void hci_user_confirm_request_evt(struct hci_dev *hdev, 4425a5c29683SJohan Hedberg struct sk_buff *skb) 4426a5c29683SJohan Hedberg { 4427a5c29683SJohan Hedberg struct hci_ev_user_confirm_req *ev = (void *) skb->data; 442855bc1a37SJohan Hedberg int loc_mitm, rem_mitm, confirm_hint = 0; 44297a828908SJohan Hedberg struct hci_conn *conn; 4430a5c29683SJohan Hedberg 4431a5c29683SJohan Hedberg BT_DBG("%s", hdev->name); 4432a5c29683SJohan Hedberg 4433a5c29683SJohan Hedberg hci_dev_lock(hdev); 4434a5c29683SJohan Hedberg 4435d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 44367a828908SJohan Hedberg goto unlock; 44377a828908SJohan Hedberg 44387a828908SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 44397a828908SJohan Hedberg if (!conn) 44407a828908SJohan Hedberg goto unlock; 44417a828908SJohan Hedberg 44427a828908SJohan Hedberg loc_mitm = (conn->auth_type & 0x01); 44437a828908SJohan Hedberg rem_mitm = (conn->remote_auth & 0x01); 44447a828908SJohan Hedberg 44457a828908SJohan Hedberg /* If we require MITM but the remote device can't provide that 44466c53823aSJohan Hedberg * (it has NoInputNoOutput) then reject the confirmation 44476c53823aSJohan Hedberg * request. We check the security level here since it doesn't 44486c53823aSJohan Hedberg * necessarily match conn->auth_type. 44496fd6b915SMikel Astiz */ 44506c53823aSJohan Hedberg if (conn->pending_sec_level > BT_SECURITY_MEDIUM && 44516c53823aSJohan Hedberg conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) { 44527a828908SJohan Hedberg BT_DBG("Rejecting request: remote device can't provide MITM"); 44537a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY, 44547a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 44557a828908SJohan Hedberg goto unlock; 44567a828908SJohan Hedberg } 44577a828908SJohan Hedberg 44587a828908SJohan Hedberg /* If no side requires MITM protection; auto-accept */ 4459a767631aSMikel Astiz if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) && 4460a767631aSMikel Astiz (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) { 446155bc1a37SJohan Hedberg 446255bc1a37SJohan Hedberg /* If we're not the initiators request authorization to 446355bc1a37SJohan Hedberg * proceed from user space (mgmt_user_confirm with 4464ba15a58bSJohan Hedberg * confirm_hint set to 1). The exception is if neither 446502f3e254SJohan Hedberg * side had MITM or if the local IO capability is 446602f3e254SJohan Hedberg * NoInputNoOutput, in which case we do auto-accept 4467ba15a58bSJohan Hedberg */ 4468ba15a58bSJohan Hedberg if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && 446902f3e254SJohan Hedberg conn->io_capability != HCI_IO_NO_INPUT_OUTPUT && 4470ba15a58bSJohan Hedberg (loc_mitm || rem_mitm)) { 447155bc1a37SJohan Hedberg BT_DBG("Confirming auto-accept as acceptor"); 447255bc1a37SJohan Hedberg confirm_hint = 1; 447355bc1a37SJohan Hedberg goto confirm; 447455bc1a37SJohan Hedberg } 447555bc1a37SJohan Hedberg 44769f61656aSJohan Hedberg BT_DBG("Auto-accept of user confirmation with %ums delay", 44779f61656aSJohan Hedberg hdev->auto_accept_delay); 44789f61656aSJohan Hedberg 44799f61656aSJohan Hedberg if (hdev->auto_accept_delay > 0) { 44809f61656aSJohan Hedberg int delay = msecs_to_jiffies(hdev->auto_accept_delay); 44817bc18d9dSJohan Hedberg queue_delayed_work(conn->hdev->workqueue, 44827bc18d9dSJohan Hedberg &conn->auto_accept_work, delay); 44839f61656aSJohan Hedberg goto unlock; 44849f61656aSJohan Hedberg } 44859f61656aSJohan Hedberg 44867a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, 44877a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 44887a828908SJohan Hedberg goto unlock; 44897a828908SJohan Hedberg } 44907a828908SJohan Hedberg 449155bc1a37SJohan Hedberg confirm: 449239adbffeSJohan Hedberg mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, 449339adbffeSJohan Hedberg le32_to_cpu(ev->passkey), confirm_hint); 4494a5c29683SJohan Hedberg 44957a828908SJohan Hedberg unlock: 4496a5c29683SJohan Hedberg hci_dev_unlock(hdev); 4497a5c29683SJohan Hedberg } 4498a5c29683SJohan Hedberg 44996039aa73SGustavo Padovan static void hci_user_passkey_request_evt(struct hci_dev *hdev, 45001143d458SBrian Gix struct sk_buff *skb) 45011143d458SBrian Gix { 45021143d458SBrian Gix struct hci_ev_user_passkey_req *ev = (void *) skb->data; 45031143d458SBrian Gix 45041143d458SBrian Gix BT_DBG("%s", hdev->name); 45051143d458SBrian Gix 4506d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 4507272d90dfSJohan Hedberg mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); 45081143d458SBrian Gix } 45091143d458SBrian Gix 451092a25256SJohan Hedberg static void hci_user_passkey_notify_evt(struct hci_dev *hdev, 451192a25256SJohan Hedberg struct sk_buff *skb) 451292a25256SJohan Hedberg { 451392a25256SJohan Hedberg struct hci_ev_user_passkey_notify *ev = (void *) skb->data; 451492a25256SJohan Hedberg struct hci_conn *conn; 451592a25256SJohan Hedberg 451692a25256SJohan Hedberg BT_DBG("%s", hdev->name); 451792a25256SJohan Hedberg 451892a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 451992a25256SJohan Hedberg if (!conn) 452092a25256SJohan Hedberg return; 452192a25256SJohan Hedberg 452292a25256SJohan Hedberg conn->passkey_notify = __le32_to_cpu(ev->passkey); 452392a25256SJohan Hedberg conn->passkey_entered = 0; 452492a25256SJohan Hedberg 4525d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 452692a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 452792a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 452892a25256SJohan Hedberg conn->passkey_entered); 452992a25256SJohan Hedberg } 453092a25256SJohan Hedberg 453192a25256SJohan Hedberg static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 453292a25256SJohan Hedberg { 453392a25256SJohan Hedberg struct hci_ev_keypress_notify *ev = (void *) skb->data; 453492a25256SJohan Hedberg struct hci_conn *conn; 453592a25256SJohan Hedberg 453692a25256SJohan Hedberg BT_DBG("%s", hdev->name); 453792a25256SJohan Hedberg 453892a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 453992a25256SJohan Hedberg if (!conn) 454092a25256SJohan Hedberg return; 454192a25256SJohan Hedberg 454292a25256SJohan Hedberg switch (ev->type) { 454392a25256SJohan Hedberg case HCI_KEYPRESS_STARTED: 454492a25256SJohan Hedberg conn->passkey_entered = 0; 454592a25256SJohan Hedberg return; 454692a25256SJohan Hedberg 454792a25256SJohan Hedberg case HCI_KEYPRESS_ENTERED: 454892a25256SJohan Hedberg conn->passkey_entered++; 454992a25256SJohan Hedberg break; 455092a25256SJohan Hedberg 455192a25256SJohan Hedberg case HCI_KEYPRESS_ERASED: 455292a25256SJohan Hedberg conn->passkey_entered--; 455392a25256SJohan Hedberg break; 455492a25256SJohan Hedberg 455592a25256SJohan Hedberg case HCI_KEYPRESS_CLEARED: 455692a25256SJohan Hedberg conn->passkey_entered = 0; 455792a25256SJohan Hedberg break; 455892a25256SJohan Hedberg 455992a25256SJohan Hedberg case HCI_KEYPRESS_COMPLETED: 456092a25256SJohan Hedberg return; 456192a25256SJohan Hedberg } 456292a25256SJohan Hedberg 4563d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 456492a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 456592a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 456692a25256SJohan Hedberg conn->passkey_entered); 456792a25256SJohan Hedberg } 456892a25256SJohan Hedberg 45696039aa73SGustavo Padovan static void hci_simple_pair_complete_evt(struct hci_dev *hdev, 4570807deac2SGustavo Padovan struct sk_buff *skb) 45710493684eSMarcel Holtmann { 45720493684eSMarcel Holtmann struct hci_ev_simple_pair_complete *ev = (void *) skb->data; 45730493684eSMarcel Holtmann struct hci_conn *conn; 45740493684eSMarcel Holtmann 45750493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 45760493684eSMarcel Holtmann 45770493684eSMarcel Holtmann hci_dev_lock(hdev); 45780493684eSMarcel Holtmann 45790493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 45802a611692SJohan Hedberg if (!conn) 45812a611692SJohan Hedberg goto unlock; 45822a611692SJohan Hedberg 4583c1d4fa7aSJohan Hedberg /* Reset the authentication requirement to unknown */ 4584c1d4fa7aSJohan Hedberg conn->remote_auth = 0xff; 4585c1d4fa7aSJohan Hedberg 45862a611692SJohan Hedberg /* To avoid duplicate auth_failed events to user space we check 45872a611692SJohan Hedberg * the HCI_CONN_AUTH_PEND flag which will be set if we 45882a611692SJohan Hedberg * initiated the authentication. A traditional auth_complete 45892a611692SJohan Hedberg * event gets always produced as initiator and is also mapped to 45902a611692SJohan Hedberg * the mgmt_auth_failed event */ 4591fa1bd918SMikel Astiz if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status) 4592e1e930f5SJohan Hedberg mgmt_auth_failed(conn, ev->status); 45932a611692SJohan Hedberg 459476a68ba0SDavid Herrmann hci_conn_drop(conn); 45950493684eSMarcel Holtmann 45962a611692SJohan Hedberg unlock: 45970493684eSMarcel Holtmann hci_dev_unlock(hdev); 45980493684eSMarcel Holtmann } 45990493684eSMarcel Holtmann 46006039aa73SGustavo Padovan static void hci_remote_host_features_evt(struct hci_dev *hdev, 4601807deac2SGustavo Padovan struct sk_buff *skb) 460241a96212SMarcel Holtmann { 460341a96212SMarcel Holtmann struct hci_ev_remote_host_features *ev = (void *) skb->data; 460441a96212SMarcel Holtmann struct inquiry_entry *ie; 4605cad718edSJohan Hedberg struct hci_conn *conn; 460641a96212SMarcel Holtmann 460741a96212SMarcel Holtmann BT_DBG("%s", hdev->name); 460841a96212SMarcel Holtmann 460941a96212SMarcel Holtmann hci_dev_lock(hdev); 461041a96212SMarcel Holtmann 4611cad718edSJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 4612cad718edSJohan Hedberg if (conn) 4613cad718edSJohan Hedberg memcpy(conn->features[1], ev->features, 8); 4614cad718edSJohan Hedberg 4615cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 4616cc11b9c1SAndrei Emeltchenko if (ie) 461702b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 461841a96212SMarcel Holtmann 461941a96212SMarcel Holtmann hci_dev_unlock(hdev); 462041a96212SMarcel Holtmann } 462141a96212SMarcel Holtmann 46226039aa73SGustavo Padovan static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, 46232763eda6SSzymon Janc struct sk_buff *skb) 46242763eda6SSzymon Janc { 46252763eda6SSzymon Janc struct hci_ev_remote_oob_data_request *ev = (void *) skb->data; 46262763eda6SSzymon Janc struct oob_data *data; 46272763eda6SSzymon Janc 46282763eda6SSzymon Janc BT_DBG("%s", hdev->name); 46292763eda6SSzymon Janc 46302763eda6SSzymon Janc hci_dev_lock(hdev); 46312763eda6SSzymon Janc 4632d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 4633e1ba1f15SSzymon Janc goto unlock; 4634e1ba1f15SSzymon Janc 46356928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, &ev->bdaddr, BDADDR_BREDR); 46366665d057SMarcel Holtmann if (!data) { 46376665d057SMarcel Holtmann struct hci_cp_remote_oob_data_neg_reply cp; 46386665d057SMarcel Holtmann 46396665d057SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 46406665d057SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, 46416665d057SMarcel Holtmann sizeof(cp), &cp); 46426665d057SMarcel Holtmann goto unlock; 46436665d057SMarcel Holtmann } 46446665d057SMarcel Holtmann 4645710f11c0SJohan Hedberg if (bredr_sc_enabled(hdev)) { 4646519ca9d0SMarcel Holtmann struct hci_cp_remote_oob_ext_data_reply cp; 4647519ca9d0SMarcel Holtmann 4648519ca9d0SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 4649d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) { 46506665d057SMarcel Holtmann memset(cp.hash192, 0, sizeof(cp.hash192)); 46516665d057SMarcel Holtmann memset(cp.rand192, 0, sizeof(cp.rand192)); 46526665d057SMarcel Holtmann } else { 4653519ca9d0SMarcel Holtmann memcpy(cp.hash192, data->hash192, sizeof(cp.hash192)); 465438da1703SJohan Hedberg memcpy(cp.rand192, data->rand192, sizeof(cp.rand192)); 46556665d057SMarcel Holtmann } 4656519ca9d0SMarcel Holtmann memcpy(cp.hash256, data->hash256, sizeof(cp.hash256)); 465738da1703SJohan Hedberg memcpy(cp.rand256, data->rand256, sizeof(cp.rand256)); 4658519ca9d0SMarcel Holtmann 4659519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY, 4660519ca9d0SMarcel Holtmann sizeof(cp), &cp); 4661519ca9d0SMarcel Holtmann } else { 46622763eda6SSzymon Janc struct hci_cp_remote_oob_data_reply cp; 46632763eda6SSzymon Janc 46642763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr); 4665519ca9d0SMarcel Holtmann memcpy(cp.hash, data->hash192, sizeof(cp.hash)); 466638da1703SJohan Hedberg memcpy(cp.rand, data->rand192, sizeof(cp.rand)); 46672763eda6SSzymon Janc 4668519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, 4669519ca9d0SMarcel Holtmann sizeof(cp), &cp); 4670519ca9d0SMarcel Holtmann } 46712763eda6SSzymon Janc 4672e1ba1f15SSzymon Janc unlock: 46732763eda6SSzymon Janc hci_dev_unlock(hdev); 46742763eda6SSzymon Janc } 46752763eda6SSzymon Janc 4676a77a6a14SArron Wang #if IS_ENABLED(CONFIG_BT_HS) 4677a77a6a14SArron Wang static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb) 4678a77a6a14SArron Wang { 4679a77a6a14SArron Wang struct hci_ev_channel_selected *ev = (void *)skb->data; 4680a77a6a14SArron Wang struct hci_conn *hcon; 4681a77a6a14SArron Wang 4682a77a6a14SArron Wang BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle); 4683a77a6a14SArron Wang 4684a77a6a14SArron Wang skb_pull(skb, sizeof(*ev)); 4685a77a6a14SArron Wang 4686a77a6a14SArron Wang hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 4687a77a6a14SArron Wang if (!hcon) 4688a77a6a14SArron Wang return; 4689a77a6a14SArron Wang 4690a77a6a14SArron Wang amp_read_loc_assoc_final_data(hdev, hcon); 4691a77a6a14SArron Wang } 4692a77a6a14SArron Wang 4693d5e91192SAndrei Emeltchenko static void hci_phy_link_complete_evt(struct hci_dev *hdev, 4694d5e91192SAndrei Emeltchenko struct sk_buff *skb) 4695d5e91192SAndrei Emeltchenko { 4696d5e91192SAndrei Emeltchenko struct hci_ev_phy_link_complete *ev = (void *) skb->data; 4697d5e91192SAndrei Emeltchenko struct hci_conn *hcon, *bredr_hcon; 4698d5e91192SAndrei Emeltchenko 4699d5e91192SAndrei Emeltchenko BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle, 4700d5e91192SAndrei Emeltchenko ev->status); 4701d5e91192SAndrei Emeltchenko 4702d5e91192SAndrei Emeltchenko hci_dev_lock(hdev); 4703d5e91192SAndrei Emeltchenko 4704d5e91192SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 4705d5e91192SAndrei Emeltchenko if (!hcon) { 4706d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 4707d5e91192SAndrei Emeltchenko return; 4708d5e91192SAndrei Emeltchenko } 4709d5e91192SAndrei Emeltchenko 4710d5e91192SAndrei Emeltchenko if (ev->status) { 4711d5e91192SAndrei Emeltchenko hci_conn_del(hcon); 4712d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 4713d5e91192SAndrei Emeltchenko return; 4714d5e91192SAndrei Emeltchenko } 4715d5e91192SAndrei Emeltchenko 4716d5e91192SAndrei Emeltchenko bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon; 4717d5e91192SAndrei Emeltchenko 4718d5e91192SAndrei Emeltchenko hcon->state = BT_CONNECTED; 4719d5e91192SAndrei Emeltchenko bacpy(&hcon->dst, &bredr_hcon->dst); 4720d5e91192SAndrei Emeltchenko 4721d5e91192SAndrei Emeltchenko hci_conn_hold(hcon); 4722d5e91192SAndrei Emeltchenko hcon->disc_timeout = HCI_DISCONN_TIMEOUT; 472376a68ba0SDavid Herrmann hci_conn_drop(hcon); 4724d5e91192SAndrei Emeltchenko 472523b9ceb7SMarcel Holtmann hci_debugfs_create_conn(hcon); 4726d5e91192SAndrei Emeltchenko hci_conn_add_sysfs(hcon); 4727d5e91192SAndrei Emeltchenko 4728cf70ff22SAndrei Emeltchenko amp_physical_cfm(bredr_hcon, hcon); 4729cf70ff22SAndrei Emeltchenko 4730d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 4731d5e91192SAndrei Emeltchenko } 4732d5e91192SAndrei Emeltchenko 473327695fb4SAndrei Emeltchenko static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 473427695fb4SAndrei Emeltchenko { 473527695fb4SAndrei Emeltchenko struct hci_ev_logical_link_complete *ev = (void *) skb->data; 473627695fb4SAndrei Emeltchenko struct hci_conn *hcon; 473727695fb4SAndrei Emeltchenko struct hci_chan *hchan; 473827695fb4SAndrei Emeltchenko struct amp_mgr *mgr; 473927695fb4SAndrei Emeltchenko 474027695fb4SAndrei Emeltchenko BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x", 474127695fb4SAndrei Emeltchenko hdev->name, le16_to_cpu(ev->handle), ev->phy_handle, 474227695fb4SAndrei Emeltchenko ev->status); 474327695fb4SAndrei Emeltchenko 474427695fb4SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 474527695fb4SAndrei Emeltchenko if (!hcon) 474627695fb4SAndrei Emeltchenko return; 474727695fb4SAndrei Emeltchenko 474827695fb4SAndrei Emeltchenko /* Create AMP hchan */ 474927695fb4SAndrei Emeltchenko hchan = hci_chan_create(hcon); 475027695fb4SAndrei Emeltchenko if (!hchan) 475127695fb4SAndrei Emeltchenko return; 475227695fb4SAndrei Emeltchenko 475327695fb4SAndrei Emeltchenko hchan->handle = le16_to_cpu(ev->handle); 475427695fb4SAndrei Emeltchenko 475527695fb4SAndrei Emeltchenko BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan); 475627695fb4SAndrei Emeltchenko 475727695fb4SAndrei Emeltchenko mgr = hcon->amp_mgr; 475827695fb4SAndrei Emeltchenko if (mgr && mgr->bredr_chan) { 475927695fb4SAndrei Emeltchenko struct l2cap_chan *bredr_chan = mgr->bredr_chan; 476027695fb4SAndrei Emeltchenko 476127695fb4SAndrei Emeltchenko l2cap_chan_lock(bredr_chan); 476227695fb4SAndrei Emeltchenko 476327695fb4SAndrei Emeltchenko bredr_chan->conn->mtu = hdev->block_mtu; 476427695fb4SAndrei Emeltchenko l2cap_logical_cfm(bredr_chan, hchan, 0); 476527695fb4SAndrei Emeltchenko hci_conn_hold(hcon); 476627695fb4SAndrei Emeltchenko 476727695fb4SAndrei Emeltchenko l2cap_chan_unlock(bredr_chan); 476827695fb4SAndrei Emeltchenko } 476927695fb4SAndrei Emeltchenko } 477027695fb4SAndrei Emeltchenko 4771606e2a10SAndrei Emeltchenko static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev, 4772606e2a10SAndrei Emeltchenko struct sk_buff *skb) 4773606e2a10SAndrei Emeltchenko { 4774606e2a10SAndrei Emeltchenko struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data; 4775606e2a10SAndrei Emeltchenko struct hci_chan *hchan; 4776606e2a10SAndrei Emeltchenko 4777606e2a10SAndrei Emeltchenko BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name, 4778606e2a10SAndrei Emeltchenko le16_to_cpu(ev->handle), ev->status); 4779606e2a10SAndrei Emeltchenko 4780606e2a10SAndrei Emeltchenko if (ev->status) 4781606e2a10SAndrei Emeltchenko return; 4782606e2a10SAndrei Emeltchenko 4783606e2a10SAndrei Emeltchenko hci_dev_lock(hdev); 4784606e2a10SAndrei Emeltchenko 4785606e2a10SAndrei Emeltchenko hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle)); 4786606e2a10SAndrei Emeltchenko if (!hchan) 4787606e2a10SAndrei Emeltchenko goto unlock; 4788606e2a10SAndrei Emeltchenko 4789606e2a10SAndrei Emeltchenko amp_destroy_logical_link(hchan, ev->reason); 4790606e2a10SAndrei Emeltchenko 4791606e2a10SAndrei Emeltchenko unlock: 4792606e2a10SAndrei Emeltchenko hci_dev_unlock(hdev); 4793606e2a10SAndrei Emeltchenko } 4794606e2a10SAndrei Emeltchenko 47959eef6b3aSAndrei Emeltchenko static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, 47969eef6b3aSAndrei Emeltchenko struct sk_buff *skb) 47979eef6b3aSAndrei Emeltchenko { 47989eef6b3aSAndrei Emeltchenko struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data; 47999eef6b3aSAndrei Emeltchenko struct hci_conn *hcon; 48009eef6b3aSAndrei Emeltchenko 48019eef6b3aSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 48029eef6b3aSAndrei Emeltchenko 48039eef6b3aSAndrei Emeltchenko if (ev->status) 48049eef6b3aSAndrei Emeltchenko return; 48059eef6b3aSAndrei Emeltchenko 48069eef6b3aSAndrei Emeltchenko hci_dev_lock(hdev); 48079eef6b3aSAndrei Emeltchenko 48089eef6b3aSAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 48099eef6b3aSAndrei Emeltchenko if (hcon) { 48109eef6b3aSAndrei Emeltchenko hcon->state = BT_CLOSED; 48119eef6b3aSAndrei Emeltchenko hci_conn_del(hcon); 48129eef6b3aSAndrei Emeltchenko } 48139eef6b3aSAndrei Emeltchenko 48149eef6b3aSAndrei Emeltchenko hci_dev_unlock(hdev); 48159eef6b3aSAndrei Emeltchenko } 4816a77a6a14SArron Wang #endif 48179eef6b3aSAndrei Emeltchenko 4818d12fb056SJaganath Kanakkassery static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, 4819d12fb056SJaganath Kanakkassery bdaddr_t *bdaddr, u8 bdaddr_type, u8 role, u16 handle, 4820d12fb056SJaganath Kanakkassery u16 interval, u16 latency, u16 supervision_timeout) 4821fcd89c09SVille Tervo { 4822912b42efSJohan Hedberg struct hci_conn_params *params; 4823fcd89c09SVille Tervo struct hci_conn *conn; 482468d6f6deSJohan Hedberg struct smp_irk *irk; 4825837d502eSJohan Hedberg u8 addr_type; 4826fcd89c09SVille Tervo 4827fcd89c09SVille Tervo hci_dev_lock(hdev); 4828fcd89c09SVille Tervo 4829fbd96c15SJohan Hedberg /* All controllers implicitly stop advertising in the event of a 4830fbd96c15SJohan Hedberg * connection, so ensure that the state bit is cleared. 4831fbd96c15SJohan Hedberg */ 4832a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ADV); 4833fbd96c15SJohan Hedberg 4834e7d9ab73SJakub Pawlowski conn = hci_lookup_le_connect(hdev); 4835b62f328bSVille Tervo if (!conn) { 4836d12fb056SJaganath Kanakkassery conn = hci_conn_add(hdev, LE_LINK, bdaddr, role); 4837b62f328bSVille Tervo if (!conn) { 48382064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for new connection"); 4839230fd16aSAndre Guedes goto unlock; 4840b62f328bSVille Tervo } 484129b7988aSAndre Guedes 4842d12fb056SJaganath Kanakkassery conn->dst_type = bdaddr_type; 4843b9b343d2SAndre Guedes 4844cb1d68f7SJohan Hedberg /* If we didn't have a hci_conn object previously 4845cb1d68f7SJohan Hedberg * but we're in master role this must be something 4846cb1d68f7SJohan Hedberg * initiated using a white list. Since white list based 4847cb1d68f7SJohan Hedberg * connections are not "first class citizens" we don't 4848cb1d68f7SJohan Hedberg * have full tracking of them. Therefore, we go ahead 4849cb1d68f7SJohan Hedberg * with a "best effort" approach of determining the 4850cb1d68f7SJohan Hedberg * initiator address based on the HCI_PRIVACY flag. 4851cb1d68f7SJohan Hedberg */ 4852cb1d68f7SJohan Hedberg if (conn->out) { 4853d12fb056SJaganath Kanakkassery conn->resp_addr_type = bdaddr_type; 4854d12fb056SJaganath Kanakkassery bacpy(&conn->resp_addr, bdaddr); 4855d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PRIVACY)) { 4856cb1d68f7SJohan Hedberg conn->init_addr_type = ADDR_LE_DEV_RANDOM; 4857cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->rpa); 4858cb1d68f7SJohan Hedberg } else { 4859cb1d68f7SJohan Hedberg hci_copy_identity_address(hdev, 4860cb1d68f7SJohan Hedberg &conn->init_addr, 4861cb1d68f7SJohan Hedberg &conn->init_addr_type); 4862cb1d68f7SJohan Hedberg } 486380c24ab8SJohan Hedberg } 4864cb1d68f7SJohan Hedberg } else { 486580c24ab8SJohan Hedberg cancel_delayed_work(&conn->le_conn_timeout); 486680c24ab8SJohan Hedberg } 486780c24ab8SJohan Hedberg 486880c24ab8SJohan Hedberg if (!conn->out) { 4869cb1d68f7SJohan Hedberg /* Set the responder (our side) address type based on 4870cb1d68f7SJohan Hedberg * the advertising address type. 4871cb1d68f7SJohan Hedberg */ 4872cb1d68f7SJohan Hedberg conn->resp_addr_type = hdev->adv_addr_type; 4873acf0aeaeSJaganath Kanakkassery if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) { 4874acf0aeaeSJaganath Kanakkassery /* In case of ext adv, resp_addr will be updated in 4875acf0aeaeSJaganath Kanakkassery * Adv Terminated event. 4876acf0aeaeSJaganath Kanakkassery */ 4877acf0aeaeSJaganath Kanakkassery if (!ext_adv_capable(hdev)) 4878cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &hdev->random_addr); 4879acf0aeaeSJaganath Kanakkassery } else { 4880cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &hdev->bdaddr); 4881acf0aeaeSJaganath Kanakkassery } 4882cb1d68f7SJohan Hedberg 4883d12fb056SJaganath Kanakkassery conn->init_addr_type = bdaddr_type; 4884d12fb056SJaganath Kanakkassery bacpy(&conn->init_addr, bdaddr); 4885a720d735SMarcel Holtmann 4886a720d735SMarcel Holtmann /* For incoming connections, set the default minimum 4887a720d735SMarcel Holtmann * and maximum connection interval. They will be used 4888a720d735SMarcel Holtmann * to check if the parameters are in range and if not 4889a720d735SMarcel Holtmann * trigger the connection update procedure. 4890a720d735SMarcel Holtmann */ 4891a720d735SMarcel Holtmann conn->le_conn_min_interval = hdev->le_conn_min_interval; 4892a720d735SMarcel Holtmann conn->le_conn_max_interval = hdev->le_conn_max_interval; 4893cb1d68f7SJohan Hedberg } 48947be2edbbSJohan Hedberg 4895edb4b466SMarcel Holtmann /* Lookup the identity address from the stored connection 4896edb4b466SMarcel Holtmann * address and address type. 4897edb4b466SMarcel Holtmann * 4898edb4b466SMarcel Holtmann * When establishing connections to an identity address, the 4899edb4b466SMarcel Holtmann * connection procedure will store the resolvable random 4900edb4b466SMarcel Holtmann * address first. Now if it can be converted back into the 4901edb4b466SMarcel Holtmann * identity address, start using the identity address from 4902edb4b466SMarcel Holtmann * now on. 4903edb4b466SMarcel Holtmann */ 4904edb4b466SMarcel Holtmann irk = hci_get_irk(hdev, &conn->dst, conn->dst_type); 490568d6f6deSJohan Hedberg if (irk) { 490668d6f6deSJohan Hedberg bacpy(&conn->dst, &irk->bdaddr); 490768d6f6deSJohan Hedberg conn->dst_type = irk->addr_type; 490868d6f6deSJohan Hedberg } 490968d6f6deSJohan Hedberg 4910d12fb056SJaganath Kanakkassery if (status) { 4911d12fb056SJaganath Kanakkassery hci_le_conn_failed(conn, status); 4912837d502eSJohan Hedberg goto unlock; 4913837d502eSJohan Hedberg } 4914837d502eSJohan Hedberg 491508853f18SJohan Hedberg if (conn->dst_type == ADDR_LE_DEV_PUBLIC) 491608853f18SJohan Hedberg addr_type = BDADDR_LE_PUBLIC; 491708853f18SJohan Hedberg else 491808853f18SJohan Hedberg addr_type = BDADDR_LE_RANDOM; 491908853f18SJohan Hedberg 49202d3c2260SJohan Hedberg /* Drop the connection if the device is blocked */ 49212d3c2260SJohan Hedberg if (hci_bdaddr_list_lookup(&hdev->blacklist, &conn->dst, addr_type)) { 49222d3c2260SJohan Hedberg hci_conn_drop(conn); 4923cd17decbSAndre Guedes goto unlock; 4924cd17decbSAndre Guedes } 4925cd17decbSAndre Guedes 4926b644ba33SJohan Hedberg if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 492748ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, NULL, 0); 492883bc71b4SVinicius Costa Gomes 49297b5c0d52SVinicius Costa Gomes conn->sec_level = BT_SECURITY_LOW; 4930d12fb056SJaganath Kanakkassery conn->handle = handle; 49310fe29fd1SMarcel Holtmann conn->state = BT_CONFIG; 4932fcd89c09SVille Tervo 4933d12fb056SJaganath Kanakkassery conn->le_conn_interval = interval; 4934d12fb056SJaganath Kanakkassery conn->le_conn_latency = latency; 4935d12fb056SJaganath Kanakkassery conn->le_supv_timeout = supervision_timeout; 4936e04fde60SMarcel Holtmann 493723b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn); 4938fcd89c09SVille Tervo hci_conn_add_sysfs(conn); 4939fcd89c09SVille Tervo 49400fe29fd1SMarcel Holtmann /* The remote features procedure is defined for master 49410fe29fd1SMarcel Holtmann * role only. So only in case of an initiated connection 49420fe29fd1SMarcel Holtmann * request the remote features. 49430fe29fd1SMarcel Holtmann * 49440fe29fd1SMarcel Holtmann * If the local controller supports slave-initiated features 49450fe29fd1SMarcel Holtmann * exchange, then requesting the remote features in slave 49460fe29fd1SMarcel Holtmann * role is possible. Otherwise just transition into the 49470fe29fd1SMarcel Holtmann * connected state without requesting the remote features. 49480fe29fd1SMarcel Holtmann */ 49490fe29fd1SMarcel Holtmann if (conn->out || 49500fe29fd1SMarcel Holtmann (hdev->le_features[0] & HCI_LE_SLAVE_FEATURES)) { 49510fe29fd1SMarcel Holtmann struct hci_cp_le_read_remote_features cp; 49520fe29fd1SMarcel Holtmann 49530fe29fd1SMarcel Holtmann cp.handle = __cpu_to_le16(conn->handle); 49540fe29fd1SMarcel Holtmann 49550fe29fd1SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_LE_READ_REMOTE_FEATURES, 49560fe29fd1SMarcel Holtmann sizeof(cp), &cp); 49570fe29fd1SMarcel Holtmann 49580fe29fd1SMarcel Holtmann hci_conn_hold(conn); 49590fe29fd1SMarcel Holtmann } else { 49600fe29fd1SMarcel Holtmann conn->state = BT_CONNECTED; 4961d12fb056SJaganath Kanakkassery hci_connect_cfm(conn, status); 49620fe29fd1SMarcel Holtmann } 4963fcd89c09SVille Tervo 49645477610fSJohan Hedberg params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst, 49655477610fSJohan Hedberg conn->dst_type); 4966f161dd41SJohan Hedberg if (params) { 496795305baaSJohan Hedberg list_del_init(¶ms->action); 4968f161dd41SJohan Hedberg if (params->conn) { 4969f161dd41SJohan Hedberg hci_conn_drop(params->conn); 4970f8aaf9b6SJohan Hedberg hci_conn_put(params->conn); 4971f161dd41SJohan Hedberg params->conn = NULL; 4972f161dd41SJohan Hedberg } 4973f161dd41SJohan Hedberg } 4974a4790dbdSAndre Guedes 4975fcd89c09SVille Tervo unlock: 4976223683a5SJohan Hedberg hci_update_background_scan(hdev); 4977fcd89c09SVille Tervo hci_dev_unlock(hdev); 4978fcd89c09SVille Tervo } 4979fcd89c09SVille Tervo 4980d12fb056SJaganath Kanakkassery static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 4981d12fb056SJaganath Kanakkassery { 4982d12fb056SJaganath Kanakkassery struct hci_ev_le_conn_complete *ev = (void *) skb->data; 4983d12fb056SJaganath Kanakkassery 4984d12fb056SJaganath Kanakkassery BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 4985d12fb056SJaganath Kanakkassery 4986d12fb056SJaganath Kanakkassery le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type, 4987d12fb056SJaganath Kanakkassery ev->role, le16_to_cpu(ev->handle), 4988d12fb056SJaganath Kanakkassery le16_to_cpu(ev->interval), 4989d12fb056SJaganath Kanakkassery le16_to_cpu(ev->latency), 4990d12fb056SJaganath Kanakkassery le16_to_cpu(ev->supervision_timeout)); 4991d12fb056SJaganath Kanakkassery } 4992d12fb056SJaganath Kanakkassery 49934d94f95dSJaganath Kanakkassery static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev, 49944d94f95dSJaganath Kanakkassery struct sk_buff *skb) 49954d94f95dSJaganath Kanakkassery { 49964d94f95dSJaganath Kanakkassery struct hci_ev_le_enh_conn_complete *ev = (void *) skb->data; 49974d94f95dSJaganath Kanakkassery 49984d94f95dSJaganath Kanakkassery BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 49994d94f95dSJaganath Kanakkassery 50004d94f95dSJaganath Kanakkassery le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type, 50014d94f95dSJaganath Kanakkassery ev->role, le16_to_cpu(ev->handle), 50024d94f95dSJaganath Kanakkassery le16_to_cpu(ev->interval), 50034d94f95dSJaganath Kanakkassery le16_to_cpu(ev->latency), 50044d94f95dSJaganath Kanakkassery le16_to_cpu(ev->supervision_timeout)); 50054d94f95dSJaganath Kanakkassery } 50064d94f95dSJaganath Kanakkassery 5007acf0aeaeSJaganath Kanakkassery static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb) 5008acf0aeaeSJaganath Kanakkassery { 5009acf0aeaeSJaganath Kanakkassery struct hci_evt_le_ext_adv_set_term *ev = (void *) skb->data; 5010acf0aeaeSJaganath Kanakkassery struct hci_conn *conn; 5011acf0aeaeSJaganath Kanakkassery 5012acf0aeaeSJaganath Kanakkassery BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 5013acf0aeaeSJaganath Kanakkassery 5014acf0aeaeSJaganath Kanakkassery if (ev->status) 5015acf0aeaeSJaganath Kanakkassery return; 5016acf0aeaeSJaganath Kanakkassery 5017acf0aeaeSJaganath Kanakkassery conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle)); 5018acf0aeaeSJaganath Kanakkassery if (conn) { 5019acf0aeaeSJaganath Kanakkassery struct adv_info *adv_instance; 5020acf0aeaeSJaganath Kanakkassery 5021acf0aeaeSJaganath Kanakkassery if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM) 5022acf0aeaeSJaganath Kanakkassery return; 5023acf0aeaeSJaganath Kanakkassery 5024acf0aeaeSJaganath Kanakkassery if (!hdev->cur_adv_instance) { 5025acf0aeaeSJaganath Kanakkassery bacpy(&conn->resp_addr, &hdev->random_addr); 5026acf0aeaeSJaganath Kanakkassery return; 5027acf0aeaeSJaganath Kanakkassery } 5028acf0aeaeSJaganath Kanakkassery 5029acf0aeaeSJaganath Kanakkassery adv_instance = hci_find_adv_instance(hdev, hdev->cur_adv_instance); 5030acf0aeaeSJaganath Kanakkassery if (adv_instance) 5031acf0aeaeSJaganath Kanakkassery bacpy(&conn->resp_addr, &adv_instance->random_addr); 5032acf0aeaeSJaganath Kanakkassery } 5033acf0aeaeSJaganath Kanakkassery } 5034acf0aeaeSJaganath Kanakkassery 50351855d92dSMarcel Holtmann static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, 50361855d92dSMarcel Holtmann struct sk_buff *skb) 50371855d92dSMarcel Holtmann { 50381855d92dSMarcel Holtmann struct hci_ev_le_conn_update_complete *ev = (void *) skb->data; 50391855d92dSMarcel Holtmann struct hci_conn *conn; 50401855d92dSMarcel Holtmann 50411855d92dSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 50421855d92dSMarcel Holtmann 50431855d92dSMarcel Holtmann if (ev->status) 50441855d92dSMarcel Holtmann return; 50451855d92dSMarcel Holtmann 50461855d92dSMarcel Holtmann hci_dev_lock(hdev); 50471855d92dSMarcel Holtmann 50481855d92dSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 50491855d92dSMarcel Holtmann if (conn) { 50501855d92dSMarcel Holtmann conn->le_conn_interval = le16_to_cpu(ev->interval); 50511855d92dSMarcel Holtmann conn->le_conn_latency = le16_to_cpu(ev->latency); 50521855d92dSMarcel Holtmann conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout); 50531855d92dSMarcel Holtmann } 50541855d92dSMarcel Holtmann 50551855d92dSMarcel Holtmann hci_dev_unlock(hdev); 50561855d92dSMarcel Holtmann } 50571855d92dSMarcel Holtmann 5058a4790dbdSAndre Guedes /* This function requires the caller holds hdev->lock */ 5059fd45ada9SAlfonso Acosta static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev, 5060fd45ada9SAlfonso Acosta bdaddr_t *addr, 5061082f2300SSzymon Janc u8 addr_type, u8 adv_type, 5062082f2300SSzymon Janc bdaddr_t *direct_rpa) 5063a4790dbdSAndre Guedes { 5064a4790dbdSAndre Guedes struct hci_conn *conn; 50654b9e7e75SMarcel Holtmann struct hci_conn_params *params; 5066a4790dbdSAndre Guedes 50671c1abcabSJohan Hedberg /* If the event is not connectable don't proceed further */ 50681c1abcabSJohan Hedberg if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND) 5069fd45ada9SAlfonso Acosta return NULL; 50701c1abcabSJohan Hedberg 50711c1abcabSJohan Hedberg /* Ignore if the device is blocked */ 5072dcc36c16SJohan Hedberg if (hci_bdaddr_list_lookup(&hdev->blacklist, addr, addr_type)) 5073fd45ada9SAlfonso Acosta return NULL; 50741c1abcabSJohan Hedberg 5075f99353cfSJohan Hedberg /* Most controller will fail if we try to create new connections 5076f99353cfSJohan Hedberg * while we have an existing one in slave role. 5077f99353cfSJohan Hedberg */ 5078f99353cfSJohan Hedberg if (hdev->conn_hash.le_num_slave > 0) 5079fd45ada9SAlfonso Acosta return NULL; 5080f99353cfSJohan Hedberg 50811c1abcabSJohan Hedberg /* If we're not connectable only connect devices that we have in 50821c1abcabSJohan Hedberg * our pend_le_conns list. 50831c1abcabSJohan Hedberg */ 508449c50922SJohan Hedberg params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr, 508549c50922SJohan Hedberg addr_type); 50864b9e7e75SMarcel Holtmann if (!params) 5087fd45ada9SAlfonso Acosta return NULL; 5088a4790dbdSAndre Guedes 508928a667c9SJakub Pawlowski if (!params->explicit_connect) { 50904b9e7e75SMarcel Holtmann switch (params->auto_connect) { 50914b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_DIRECT: 50924b9e7e75SMarcel Holtmann /* Only devices advertising with ADV_DIRECT_IND are 50934b9e7e75SMarcel Holtmann * triggering a connection attempt. This is allowing 50944b9e7e75SMarcel Holtmann * incoming connections from slave devices. 50954b9e7e75SMarcel Holtmann */ 50964b9e7e75SMarcel Holtmann if (adv_type != LE_ADV_DIRECT_IND) 5097fd45ada9SAlfonso Acosta return NULL; 50984b9e7e75SMarcel Holtmann break; 50994b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_ALWAYS: 51004b9e7e75SMarcel Holtmann /* Devices advertising with ADV_IND or ADV_DIRECT_IND 51014b9e7e75SMarcel Holtmann * are triggering a connection attempt. This means 51024b9e7e75SMarcel Holtmann * that incoming connectioms from slave device are 51034b9e7e75SMarcel Holtmann * accepted and also outgoing connections to slave 51044b9e7e75SMarcel Holtmann * devices are established when found. 51054b9e7e75SMarcel Holtmann */ 51064b9e7e75SMarcel Holtmann break; 51074b9e7e75SMarcel Holtmann default: 5108fd45ada9SAlfonso Acosta return NULL; 51094b9e7e75SMarcel Holtmann } 511028a667c9SJakub Pawlowski } 51114b9e7e75SMarcel Holtmann 5112a4790dbdSAndre Guedes conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, 5113082f2300SSzymon Janc HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER, 5114082f2300SSzymon Janc direct_rpa); 5115f161dd41SJohan Hedberg if (!IS_ERR(conn)) { 511628a667c9SJakub Pawlowski /* If HCI_AUTO_CONN_EXPLICIT is set, conn is already owned 511728a667c9SJakub Pawlowski * by higher layer that tried to connect, if no then 511828a667c9SJakub Pawlowski * store the pointer since we don't really have any 5119f161dd41SJohan Hedberg * other owner of the object besides the params that 5120f161dd41SJohan Hedberg * triggered it. This way we can abort the connection if 5121f161dd41SJohan Hedberg * the parameters get removed and keep the reference 5122f161dd41SJohan Hedberg * count consistent once the connection is established. 5123f161dd41SJohan Hedberg */ 512428a667c9SJakub Pawlowski 512528a667c9SJakub Pawlowski if (!params->explicit_connect) 5126f8aaf9b6SJohan Hedberg params->conn = hci_conn_get(conn); 512728a667c9SJakub Pawlowski 5128fd45ada9SAlfonso Acosta return conn; 5129f161dd41SJohan Hedberg } 5130a4790dbdSAndre Guedes 5131a4790dbdSAndre Guedes switch (PTR_ERR(conn)) { 5132a4790dbdSAndre Guedes case -EBUSY: 5133a4790dbdSAndre Guedes /* If hci_connect() returns -EBUSY it means there is already 5134a4790dbdSAndre Guedes * an LE connection attempt going on. Since controllers don't 5135a4790dbdSAndre Guedes * support more than one connection attempt at the time, we 5136a4790dbdSAndre Guedes * don't consider this an error case. 5137a4790dbdSAndre Guedes */ 5138a4790dbdSAndre Guedes break; 5139a4790dbdSAndre Guedes default: 5140a4790dbdSAndre Guedes BT_DBG("Failed to connect: err %ld", PTR_ERR(conn)); 5141fd45ada9SAlfonso Acosta return NULL; 5142a4790dbdSAndre Guedes } 5143fd45ada9SAlfonso Acosta 5144fd45ada9SAlfonso Acosta return NULL; 5145a4790dbdSAndre Guedes } 5146a4790dbdSAndre Guedes 51474af605d8SJohan Hedberg static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, 51482f010b55SMarcel Holtmann u8 bdaddr_type, bdaddr_t *direct_addr, 51492f010b55SMarcel Holtmann u8 direct_addr_type, s8 rssi, u8 *data, u8 len) 51504af605d8SJohan Hedberg { 5151b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 51521c1abcabSJohan Hedberg struct smp_irk *irk; 5153fd45ada9SAlfonso Acosta struct hci_conn *conn; 5154474ee066SJohan Hedberg bool match; 5155c70a7e4cSMarcel Holtmann u32 flags; 51566818375eSSzymon Janc u8 *ptr, real_len; 51576818375eSSzymon Janc 515856b40fbfSJohan Hedberg switch (type) { 515956b40fbfSJohan Hedberg case LE_ADV_IND: 516056b40fbfSJohan Hedberg case LE_ADV_DIRECT_IND: 516156b40fbfSJohan Hedberg case LE_ADV_SCAN_IND: 516256b40fbfSJohan Hedberg case LE_ADV_NONCONN_IND: 516356b40fbfSJohan Hedberg case LE_ADV_SCAN_RSP: 516456b40fbfSJohan Hedberg break; 516556b40fbfSJohan Hedberg default: 51662064ee33SMarcel Holtmann bt_dev_err_ratelimited(hdev, "unknown advertising packet " 51672064ee33SMarcel Holtmann "type: 0x%02x", type); 516856b40fbfSJohan Hedberg return; 516956b40fbfSJohan Hedberg } 517056b40fbfSJohan Hedberg 51716818375eSSzymon Janc /* Find the end of the data in case the report contains padded zero 51726818375eSSzymon Janc * bytes at the end causing an invalid length value. 51736818375eSSzymon Janc * 51746818375eSSzymon Janc * When data is NULL, len is 0 so there is no need for extra ptr 51756818375eSSzymon Janc * check as 'ptr < data + 0' is already false in such case. 51766818375eSSzymon Janc */ 51776818375eSSzymon Janc for (ptr = data; ptr < data + len && *ptr; ptr += *ptr + 1) { 51786818375eSSzymon Janc if (ptr + 1 + *ptr > data + len) 51796818375eSSzymon Janc break; 51806818375eSSzymon Janc } 51816818375eSSzymon Janc 51826818375eSSzymon Janc real_len = ptr - data; 51836818375eSSzymon Janc 51846818375eSSzymon Janc /* Adjust for actual length */ 51856818375eSSzymon Janc if (len != real_len) { 51862064ee33SMarcel Holtmann bt_dev_err_ratelimited(hdev, "advertising data len corrected"); 51876818375eSSzymon Janc len = real_len; 51886818375eSSzymon Janc } 5189b9a6328fSJohan Hedberg 51902f010b55SMarcel Holtmann /* If the direct address is present, then this report is from 51912f010b55SMarcel Holtmann * a LE Direct Advertising Report event. In that case it is 51922f010b55SMarcel Holtmann * important to see if the address is matching the local 51932f010b55SMarcel Holtmann * controller address. 51942f010b55SMarcel Holtmann */ 51952f010b55SMarcel Holtmann if (direct_addr) { 51962f010b55SMarcel Holtmann /* Only resolvable random addresses are valid for these 51972f010b55SMarcel Holtmann * kind of reports and others can be ignored. 51982f010b55SMarcel Holtmann */ 51992f010b55SMarcel Holtmann if (!hci_bdaddr_is_rpa(direct_addr, direct_addr_type)) 52002f010b55SMarcel Holtmann return; 52012f010b55SMarcel Holtmann 52022f010b55SMarcel Holtmann /* If the controller is not using resolvable random 52032f010b55SMarcel Holtmann * addresses, then this report can be ignored. 52042f010b55SMarcel Holtmann */ 5205d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_PRIVACY)) 52062f010b55SMarcel Holtmann return; 52072f010b55SMarcel Holtmann 52082f010b55SMarcel Holtmann /* If the local IRK of the controller does not match 52092f010b55SMarcel Holtmann * with the resolvable random address provided, then 52102f010b55SMarcel Holtmann * this report can be ignored. 52112f010b55SMarcel Holtmann */ 52122f010b55SMarcel Holtmann if (!smp_irk_matches(hdev, hdev->irk, direct_addr)) 52132f010b55SMarcel Holtmann return; 52142f010b55SMarcel Holtmann } 52152f010b55SMarcel Holtmann 5216435a13d8SJohan Hedberg /* Check if we need to convert to identity address */ 5217435a13d8SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, bdaddr_type); 5218435a13d8SJohan Hedberg if (irk) { 5219435a13d8SJohan Hedberg bdaddr = &irk->bdaddr; 5220435a13d8SJohan Hedberg bdaddr_type = irk->addr_type; 5221435a13d8SJohan Hedberg } 5222435a13d8SJohan Hedberg 5223082f2300SSzymon Janc /* Check if we have been requested to connect to this device. 5224082f2300SSzymon Janc * 5225082f2300SSzymon Janc * direct_addr is set only for directed advertising reports (it is NULL 5226082f2300SSzymon Janc * for advertising reports) and is already verified to be RPA above. 5227082f2300SSzymon Janc */ 5228082f2300SSzymon Janc conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, type, 5229082f2300SSzymon Janc direct_addr); 5230fd45ada9SAlfonso Acosta if (conn && type == LE_ADV_IND) { 5231fd45ada9SAlfonso Acosta /* Store report for later inclusion by 5232fd45ada9SAlfonso Acosta * mgmt_device_connected 5233fd45ada9SAlfonso Acosta */ 5234fd45ada9SAlfonso Acosta memcpy(conn->le_adv_data, data, len); 5235fd45ada9SAlfonso Acosta conn->le_adv_data_len = len; 5236fd45ada9SAlfonso Acosta } 523799a6768eSJohan Hedberg 52381c1abcabSJohan Hedberg /* Passive scanning shouldn't trigger any device found events, 52391c1abcabSJohan Hedberg * except for devices marked as CONN_REPORT for which we do send 52401c1abcabSJohan Hedberg * device found events. 52411c1abcabSJohan Hedberg */ 52421c1abcabSJohan Hedberg if (hdev->le_scan_type == LE_SCAN_PASSIVE) { 52430d2bf134SJohan Hedberg if (type == LE_ADV_DIRECT_IND) 52440d2bf134SJohan Hedberg return; 52450d2bf134SJohan Hedberg 52463a19b6feSJohan Hedberg if (!hci_pend_le_action_lookup(&hdev->pend_le_reports, 52473a19b6feSJohan Hedberg bdaddr, bdaddr_type)) 52480d2bf134SJohan Hedberg return; 52490d2bf134SJohan Hedberg 52500d2bf134SJohan Hedberg if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND) 52510d2bf134SJohan Hedberg flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 52520d2bf134SJohan Hedberg else 52530d2bf134SJohan Hedberg flags = 0; 52540d2bf134SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 52550d2bf134SJohan Hedberg rssi, flags, data, len, NULL, 0); 525697bf2e99SJohan Hedberg return; 5257ca5c4be7SJohan Hedberg } 52584af605d8SJohan Hedberg 5259c70a7e4cSMarcel Holtmann /* When receiving non-connectable or scannable undirected 5260c70a7e4cSMarcel Holtmann * advertising reports, this means that the remote device is 5261c70a7e4cSMarcel Holtmann * not connectable and then clearly indicate this in the 5262c70a7e4cSMarcel Holtmann * device found event. 5263c70a7e4cSMarcel Holtmann * 5264c70a7e4cSMarcel Holtmann * When receiving a scan response, then there is no way to 5265c70a7e4cSMarcel Holtmann * know if the remote device is connectable or not. However 5266c70a7e4cSMarcel Holtmann * since scan responses are merged with a previously seen 5267c70a7e4cSMarcel Holtmann * advertising report, the flags field from that report 5268c70a7e4cSMarcel Holtmann * will be used. 5269c70a7e4cSMarcel Holtmann * 5270c70a7e4cSMarcel Holtmann * In the really unlikely case that a controller get confused 5271c70a7e4cSMarcel Holtmann * and just sends a scan response event, then it is marked as 5272c70a7e4cSMarcel Holtmann * not connectable as well. 5273c70a7e4cSMarcel Holtmann */ 5274c70a7e4cSMarcel Holtmann if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND || 5275c70a7e4cSMarcel Holtmann type == LE_ADV_SCAN_RSP) 5276c70a7e4cSMarcel Holtmann flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 5277c70a7e4cSMarcel Holtmann else 5278c70a7e4cSMarcel Holtmann flags = 0; 5279c70a7e4cSMarcel Holtmann 5280b9a6328fSJohan Hedberg /* If there's nothing pending either store the data from this 5281b9a6328fSJohan Hedberg * event or send an immediate device found event if the data 5282b9a6328fSJohan Hedberg * should not be stored for later. 5283b9a6328fSJohan Hedberg */ 5284b9a6328fSJohan Hedberg if (!has_pending_adv_report(hdev)) { 5285b9a6328fSJohan Hedberg /* If the report will trigger a SCAN_REQ store it for 5286b9a6328fSJohan Hedberg * later merging. 5287b9a6328fSJohan Hedberg */ 5288b9a6328fSJohan Hedberg if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { 5289b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type, 5290c70a7e4cSMarcel Holtmann rssi, flags, data, len); 5291b9a6328fSJohan Hedberg return; 5292b9a6328fSJohan Hedberg } 5293b9a6328fSJohan Hedberg 5294b9a6328fSJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 5295c70a7e4cSMarcel Holtmann rssi, flags, data, len, NULL, 0); 5296b9a6328fSJohan Hedberg return; 5297b9a6328fSJohan Hedberg } 5298b9a6328fSJohan Hedberg 5299474ee066SJohan Hedberg /* Check if the pending report is for the same device as the new one */ 5300474ee066SJohan Hedberg match = (!bacmp(bdaddr, &d->last_adv_addr) && 5301474ee066SJohan Hedberg bdaddr_type == d->last_adv_addr_type); 5302474ee066SJohan Hedberg 5303b9a6328fSJohan Hedberg /* If the pending data doesn't match this report or this isn't a 5304b9a6328fSJohan Hedberg * scan response (e.g. we got a duplicate ADV_IND) then force 5305b9a6328fSJohan Hedberg * sending of the pending data. 5306b9a6328fSJohan Hedberg */ 5307474ee066SJohan Hedberg if (type != LE_ADV_SCAN_RSP || !match) { 5308474ee066SJohan Hedberg /* Send out whatever is in the cache, but skip duplicates */ 5309474ee066SJohan Hedberg if (!match) 5310b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 5311ff5cd29fSJohan Hedberg d->last_adv_addr_type, NULL, 5312c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags, 5313ff5cd29fSJohan Hedberg d->last_adv_data, 5314474ee066SJohan Hedberg d->last_adv_data_len, NULL, 0); 5315b9a6328fSJohan Hedberg 5316b9a6328fSJohan Hedberg /* If the new report will trigger a SCAN_REQ store it for 5317b9a6328fSJohan Hedberg * later merging. 5318b9a6328fSJohan Hedberg */ 5319b9a6328fSJohan Hedberg if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { 5320b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type, 5321c70a7e4cSMarcel Holtmann rssi, flags, data, len); 5322b9a6328fSJohan Hedberg return; 5323b9a6328fSJohan Hedberg } 5324b9a6328fSJohan Hedberg 5325b9a6328fSJohan Hedberg /* The advertising reports cannot be merged, so clear 5326b9a6328fSJohan Hedberg * the pending report and send out a device found event. 5327b9a6328fSJohan Hedberg */ 5328b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 53295c5b93e4SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 5330c70a7e4cSMarcel Holtmann rssi, flags, data, len, NULL, 0); 5331b9a6328fSJohan Hedberg return; 5332b9a6328fSJohan Hedberg } 5333b9a6328fSJohan Hedberg 5334b9a6328fSJohan Hedberg /* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and 5335b9a6328fSJohan Hedberg * the new event is a SCAN_RSP. We can therefore proceed with 5336b9a6328fSJohan Hedberg * sending a merged device found event. 5337b9a6328fSJohan Hedberg */ 5338b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 5339c70a7e4cSMarcel Holtmann d->last_adv_addr_type, NULL, rssi, d->last_adv_flags, 534042bd6a56SMarcel Holtmann d->last_adv_data, d->last_adv_data_len, data, len); 5341b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 53424af605d8SJohan Hedberg } 53434af605d8SJohan Hedberg 53446039aa73SGustavo Padovan static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) 53459aa04c91SAndre Guedes { 5346e95beb41SAndre Guedes u8 num_reports = skb->data[0]; 5347e95beb41SAndre Guedes void *ptr = &skb->data[1]; 53489aa04c91SAndre Guedes 5349a4790dbdSAndre Guedes hci_dev_lock(hdev); 5350a4790dbdSAndre Guedes 5351e95beb41SAndre Guedes while (num_reports--) { 5352e95beb41SAndre Guedes struct hci_ev_le_advertising_info *ev = ptr; 53534af605d8SJohan Hedberg s8 rssi; 5354a4790dbdSAndre Guedes 5355ee649346SChriz Chow if (ev->length <= HCI_MAX_AD_LENGTH) { 53563c9e9195SAndre Guedes rssi = ev->data[ev->length]; 53574af605d8SJohan Hedberg process_adv_report(hdev, ev->evt_type, &ev->bdaddr, 53582f010b55SMarcel Holtmann ev->bdaddr_type, NULL, 0, rssi, 53592f010b55SMarcel Holtmann ev->data, ev->length); 5360ee649346SChriz Chow } else { 5361ee649346SChriz Chow bt_dev_err(hdev, "Dropping invalid advertising data"); 5362ee649346SChriz Chow } 53633c9e9195SAndre Guedes 5364e95beb41SAndre Guedes ptr += sizeof(*ev) + ev->length + 1; 53659aa04c91SAndre Guedes } 5366a4790dbdSAndre Guedes 5367a4790dbdSAndre Guedes hci_dev_unlock(hdev); 53689aa04c91SAndre Guedes } 53699aa04c91SAndre Guedes 5370b2cc9761SJaganath Kanakkassery static u8 ext_evt_type_to_legacy(u16 evt_type) 5371c215e939SJaganath Kanakkassery { 5372b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_LEGACY_PDU) { 5373c215e939SJaganath Kanakkassery switch (evt_type) { 5374c215e939SJaganath Kanakkassery case LE_LEGACY_ADV_IND: 5375c215e939SJaganath Kanakkassery return LE_ADV_IND; 5376c215e939SJaganath Kanakkassery case LE_LEGACY_ADV_DIRECT_IND: 5377c215e939SJaganath Kanakkassery return LE_ADV_DIRECT_IND; 5378c215e939SJaganath Kanakkassery case LE_LEGACY_ADV_SCAN_IND: 5379c215e939SJaganath Kanakkassery return LE_ADV_SCAN_IND; 5380c215e939SJaganath Kanakkassery case LE_LEGACY_NONCONN_IND: 5381c215e939SJaganath Kanakkassery return LE_ADV_NONCONN_IND; 5382c215e939SJaganath Kanakkassery case LE_LEGACY_SCAN_RSP_ADV: 5383c215e939SJaganath Kanakkassery case LE_LEGACY_SCAN_RSP_ADV_SCAN: 5384c215e939SJaganath Kanakkassery return LE_ADV_SCAN_RSP; 5385c215e939SJaganath Kanakkassery } 5386c215e939SJaganath Kanakkassery 5387c215e939SJaganath Kanakkassery BT_ERR_RATELIMITED("Unknown advertising packet type: 0x%02x", 5388c215e939SJaganath Kanakkassery evt_type); 5389c215e939SJaganath Kanakkassery 5390c215e939SJaganath Kanakkassery return LE_ADV_INVALID; 5391c215e939SJaganath Kanakkassery } 5392c215e939SJaganath Kanakkassery 5393b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_CONN_IND) { 5394b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_DIRECT_IND) 5395b2cc9761SJaganath Kanakkassery return LE_ADV_DIRECT_IND; 5396b2cc9761SJaganath Kanakkassery 5397b2cc9761SJaganath Kanakkassery return LE_ADV_IND; 5398b2cc9761SJaganath Kanakkassery } 5399b2cc9761SJaganath Kanakkassery 5400b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_SCAN_RSP) 5401b2cc9761SJaganath Kanakkassery return LE_ADV_SCAN_RSP; 5402b2cc9761SJaganath Kanakkassery 5403b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_SCAN_IND) 5404b2cc9761SJaganath Kanakkassery return LE_ADV_SCAN_IND; 5405b2cc9761SJaganath Kanakkassery 5406b2cc9761SJaganath Kanakkassery if (evt_type == LE_EXT_ADV_NON_CONN_IND || 5407b2cc9761SJaganath Kanakkassery evt_type & LE_EXT_ADV_DIRECT_IND) 5408b2cc9761SJaganath Kanakkassery return LE_ADV_NONCONN_IND; 5409b2cc9761SJaganath Kanakkassery 5410b2cc9761SJaganath Kanakkassery BT_ERR_RATELIMITED("Unknown advertising packet type: 0x%02x", 5411b2cc9761SJaganath Kanakkassery evt_type); 5412b2cc9761SJaganath Kanakkassery 5413b2cc9761SJaganath Kanakkassery return LE_ADV_INVALID; 5414b2cc9761SJaganath Kanakkassery } 5415b2cc9761SJaganath Kanakkassery 5416c215e939SJaganath Kanakkassery static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) 5417c215e939SJaganath Kanakkassery { 5418c215e939SJaganath Kanakkassery u8 num_reports = skb->data[0]; 5419c215e939SJaganath Kanakkassery void *ptr = &skb->data[1]; 5420c215e939SJaganath Kanakkassery 5421c215e939SJaganath Kanakkassery hci_dev_lock(hdev); 5422c215e939SJaganath Kanakkassery 5423c215e939SJaganath Kanakkassery while (num_reports--) { 5424c215e939SJaganath Kanakkassery struct hci_ev_le_ext_adv_report *ev = ptr; 5425c215e939SJaganath Kanakkassery u8 legacy_evt_type; 5426c215e939SJaganath Kanakkassery u16 evt_type; 5427c215e939SJaganath Kanakkassery 5428c215e939SJaganath Kanakkassery evt_type = __le16_to_cpu(ev->evt_type); 5429b2cc9761SJaganath Kanakkassery legacy_evt_type = ext_evt_type_to_legacy(evt_type); 5430c215e939SJaganath Kanakkassery if (legacy_evt_type != LE_ADV_INVALID) { 5431c215e939SJaganath Kanakkassery process_adv_report(hdev, legacy_evt_type, &ev->bdaddr, 5432c215e939SJaganath Kanakkassery ev->bdaddr_type, NULL, 0, ev->rssi, 5433c215e939SJaganath Kanakkassery ev->data, ev->length); 5434c215e939SJaganath Kanakkassery } 5435c215e939SJaganath Kanakkassery 5436cd9151b6SJaganath Kanakkassery ptr += sizeof(*ev) + ev->length; 5437c215e939SJaganath Kanakkassery } 5438c215e939SJaganath Kanakkassery 5439c215e939SJaganath Kanakkassery hci_dev_unlock(hdev); 5440c215e939SJaganath Kanakkassery } 5441c215e939SJaganath Kanakkassery 54420fe29fd1SMarcel Holtmann static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev, 54430fe29fd1SMarcel Holtmann struct sk_buff *skb) 54440fe29fd1SMarcel Holtmann { 54450fe29fd1SMarcel Holtmann struct hci_ev_le_remote_feat_complete *ev = (void *)skb->data; 54460fe29fd1SMarcel Holtmann struct hci_conn *conn; 54470fe29fd1SMarcel Holtmann 54480fe29fd1SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 54490fe29fd1SMarcel Holtmann 54500fe29fd1SMarcel Holtmann hci_dev_lock(hdev); 54510fe29fd1SMarcel Holtmann 54520fe29fd1SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 54530fe29fd1SMarcel Holtmann if (conn) { 54540fe29fd1SMarcel Holtmann if (!ev->status) 54550fe29fd1SMarcel Holtmann memcpy(conn->features[0], ev->features, 8); 54560fe29fd1SMarcel Holtmann 54570fe29fd1SMarcel Holtmann if (conn->state == BT_CONFIG) { 54580fe29fd1SMarcel Holtmann __u8 status; 54590fe29fd1SMarcel Holtmann 54600fe29fd1SMarcel Holtmann /* If the local controller supports slave-initiated 54610fe29fd1SMarcel Holtmann * features exchange, but the remote controller does 54620fe29fd1SMarcel Holtmann * not, then it is possible that the error code 0x1a 54630fe29fd1SMarcel Holtmann * for unsupported remote feature gets returned. 54640fe29fd1SMarcel Holtmann * 54650fe29fd1SMarcel Holtmann * In this specific case, allow the connection to 54660fe29fd1SMarcel Holtmann * transition into connected state and mark it as 54670fe29fd1SMarcel Holtmann * successful. 54680fe29fd1SMarcel Holtmann */ 54690fe29fd1SMarcel Holtmann if ((hdev->le_features[0] & HCI_LE_SLAVE_FEATURES) && 54700fe29fd1SMarcel Holtmann !conn->out && ev->status == 0x1a) 54710fe29fd1SMarcel Holtmann status = 0x00; 54720fe29fd1SMarcel Holtmann else 54730fe29fd1SMarcel Holtmann status = ev->status; 54740fe29fd1SMarcel Holtmann 54750fe29fd1SMarcel Holtmann conn->state = BT_CONNECTED; 54760fe29fd1SMarcel Holtmann hci_connect_cfm(conn, status); 54770fe29fd1SMarcel Holtmann hci_conn_drop(conn); 54780fe29fd1SMarcel Holtmann } 54790fe29fd1SMarcel Holtmann } 54800fe29fd1SMarcel Holtmann 54810fe29fd1SMarcel Holtmann hci_dev_unlock(hdev); 54820fe29fd1SMarcel Holtmann } 54830fe29fd1SMarcel Holtmann 54846039aa73SGustavo Padovan static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 5485a7a595f6SVinicius Costa Gomes { 5486a7a595f6SVinicius Costa Gomes struct hci_ev_le_ltk_req *ev = (void *) skb->data; 5487a7a595f6SVinicius Costa Gomes struct hci_cp_le_ltk_reply cp; 5488bea710feSVinicius Costa Gomes struct hci_cp_le_ltk_neg_reply neg; 5489a7a595f6SVinicius Costa Gomes struct hci_conn *conn; 5490c9839a11SVinicius Costa Gomes struct smp_ltk *ltk; 5491a7a595f6SVinicius Costa Gomes 54929f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle)); 5493a7a595f6SVinicius Costa Gomes 5494a7a595f6SVinicius Costa Gomes hci_dev_lock(hdev); 5495a7a595f6SVinicius Costa Gomes 5496a7a595f6SVinicius Costa Gomes conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 5497bea710feSVinicius Costa Gomes if (conn == NULL) 5498bea710feSVinicius Costa Gomes goto not_found; 5499a7a595f6SVinicius Costa Gomes 5500f3a73d97SJohan Hedberg ltk = hci_find_ltk(hdev, &conn->dst, conn->dst_type, conn->role); 55015378bc56SJohan Hedberg if (!ltk) 5502bea710feSVinicius Costa Gomes goto not_found; 5503bea710feSVinicius Costa Gomes 55045378bc56SJohan Hedberg if (smp_ltk_is_sc(ltk)) { 55055378bc56SJohan Hedberg /* With SC both EDiv and Rand are set to zero */ 55065378bc56SJohan Hedberg if (ev->ediv || ev->rand) 55075378bc56SJohan Hedberg goto not_found; 55085378bc56SJohan Hedberg } else { 55095378bc56SJohan Hedberg /* For non-SC keys check that EDiv and Rand match */ 55105378bc56SJohan Hedberg if (ev->ediv != ltk->ediv || ev->rand != ltk->rand) 55115378bc56SJohan Hedberg goto not_found; 55125378bc56SJohan Hedberg } 55135378bc56SJohan Hedberg 55148b76ce34SJohan Hedberg memcpy(cp.ltk, ltk->val, ltk->enc_size); 55158b76ce34SJohan Hedberg memset(cp.ltk + ltk->enc_size, 0, sizeof(cp.ltk) - ltk->enc_size); 5516a7a595f6SVinicius Costa Gomes cp.handle = cpu_to_le16(conn->handle); 5517c9839a11SVinicius Costa Gomes 5518a6f7833cSJohan Hedberg conn->pending_sec_level = smp_ltk_sec_level(ltk); 5519a7a595f6SVinicius Costa Gomes 552089cbb4daSAndre Guedes conn->enc_key_size = ltk->enc_size; 5521a7a595f6SVinicius Costa Gomes 5522a7a595f6SVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); 5523a7a595f6SVinicius Costa Gomes 55245981a882SClaudio Takahasi /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a 55255981a882SClaudio Takahasi * temporary key used to encrypt a connection following 55265981a882SClaudio Takahasi * pairing. It is used during the Encrypted Session Setup to 55275981a882SClaudio Takahasi * distribute the keys. Later, security can be re-established 55285981a882SClaudio Takahasi * using a distributed LTK. 55295981a882SClaudio Takahasi */ 55302ceba539SJohan Hedberg if (ltk->type == SMP_STK) { 5531fe59a05fSJohan Hedberg set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); 5532970d0f1bSJohan Hedberg list_del_rcu(<k->list); 5533970d0f1bSJohan Hedberg kfree_rcu(ltk, rcu); 5534fe59a05fSJohan Hedberg } else { 5535fe59a05fSJohan Hedberg clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); 5536c9839a11SVinicius Costa Gomes } 5537c9839a11SVinicius Costa Gomes 5538a7a595f6SVinicius Costa Gomes hci_dev_unlock(hdev); 5539bea710feSVinicius Costa Gomes 5540bea710feSVinicius Costa Gomes return; 5541bea710feSVinicius Costa Gomes 5542bea710feSVinicius Costa Gomes not_found: 5543bea710feSVinicius Costa Gomes neg.handle = ev->handle; 5544bea710feSVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg); 5545bea710feSVinicius Costa Gomes hci_dev_unlock(hdev); 5546a7a595f6SVinicius Costa Gomes } 5547a7a595f6SVinicius Costa Gomes 55488e75b46aSAndre Guedes static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle, 55498e75b46aSAndre Guedes u8 reason) 55508e75b46aSAndre Guedes { 55518e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_neg_reply cp; 55528e75b46aSAndre Guedes 55538e75b46aSAndre Guedes cp.handle = cpu_to_le16(handle); 55548e75b46aSAndre Guedes cp.reason = reason; 55558e75b46aSAndre Guedes 55568e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp), 55578e75b46aSAndre Guedes &cp); 55588e75b46aSAndre Guedes } 55598e75b46aSAndre Guedes 55608e75b46aSAndre Guedes static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, 55618e75b46aSAndre Guedes struct sk_buff *skb) 55628e75b46aSAndre Guedes { 55638e75b46aSAndre Guedes struct hci_ev_le_remote_conn_param_req *ev = (void *) skb->data; 55648e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_reply cp; 55658e75b46aSAndre Guedes struct hci_conn *hcon; 55668e75b46aSAndre Guedes u16 handle, min, max, latency, timeout; 55678e75b46aSAndre Guedes 55688e75b46aSAndre Guedes handle = le16_to_cpu(ev->handle); 55698e75b46aSAndre Guedes min = le16_to_cpu(ev->interval_min); 55708e75b46aSAndre Guedes max = le16_to_cpu(ev->interval_max); 55718e75b46aSAndre Guedes latency = le16_to_cpu(ev->latency); 55728e75b46aSAndre Guedes timeout = le16_to_cpu(ev->timeout); 55738e75b46aSAndre Guedes 55748e75b46aSAndre Guedes hcon = hci_conn_hash_lookup_handle(hdev, handle); 55758e75b46aSAndre Guedes if (!hcon || hcon->state != BT_CONNECTED) 55768e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle, 55778e75b46aSAndre Guedes HCI_ERROR_UNKNOWN_CONN_ID); 55788e75b46aSAndre Guedes 55798e75b46aSAndre Guedes if (hci_check_conn_params(min, max, latency, timeout)) 55808e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle, 55818e75b46aSAndre Guedes HCI_ERROR_INVALID_LL_PARAMS); 55828e75b46aSAndre Guedes 558340bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) { 5584348d50b8SJohan Hedberg struct hci_conn_params *params; 5585f4869e2aSJohan Hedberg u8 store_hint; 5586348d50b8SJohan Hedberg 5587348d50b8SJohan Hedberg hci_dev_lock(hdev); 5588348d50b8SJohan Hedberg 5589348d50b8SJohan Hedberg params = hci_conn_params_lookup(hdev, &hcon->dst, 5590348d50b8SJohan Hedberg hcon->dst_type); 5591348d50b8SJohan Hedberg if (params) { 5592348d50b8SJohan Hedberg params->conn_min_interval = min; 5593348d50b8SJohan Hedberg params->conn_max_interval = max; 5594348d50b8SJohan Hedberg params->conn_latency = latency; 5595348d50b8SJohan Hedberg params->supervision_timeout = timeout; 5596f4869e2aSJohan Hedberg store_hint = 0x01; 5597f4869e2aSJohan Hedberg } else{ 5598f4869e2aSJohan Hedberg store_hint = 0x00; 5599348d50b8SJohan Hedberg } 5600348d50b8SJohan Hedberg 5601348d50b8SJohan Hedberg hci_dev_unlock(hdev); 5602348d50b8SJohan Hedberg 5603f4869e2aSJohan Hedberg mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type, 5604f4869e2aSJohan Hedberg store_hint, min, max, latency, timeout); 5605348d50b8SJohan Hedberg } 5606ffb5a827SAndre Guedes 56078e75b46aSAndre Guedes cp.handle = ev->handle; 56088e75b46aSAndre Guedes cp.interval_min = ev->interval_min; 56098e75b46aSAndre Guedes cp.interval_max = ev->interval_max; 56108e75b46aSAndre Guedes cp.latency = ev->latency; 56118e75b46aSAndre Guedes cp.timeout = ev->timeout; 56128e75b46aSAndre Guedes cp.min_ce_len = 0; 56138e75b46aSAndre Guedes cp.max_ce_len = 0; 56148e75b46aSAndre Guedes 56158e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp); 56168e75b46aSAndre Guedes } 56178e75b46aSAndre Guedes 56182f010b55SMarcel Holtmann static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, 56192f010b55SMarcel Holtmann struct sk_buff *skb) 56202f010b55SMarcel Holtmann { 56212f010b55SMarcel Holtmann u8 num_reports = skb->data[0]; 56222f010b55SMarcel Holtmann void *ptr = &skb->data[1]; 56232f010b55SMarcel Holtmann 56242f010b55SMarcel Holtmann hci_dev_lock(hdev); 56252f010b55SMarcel Holtmann 56262f010b55SMarcel Holtmann while (num_reports--) { 56272f010b55SMarcel Holtmann struct hci_ev_le_direct_adv_info *ev = ptr; 56282f010b55SMarcel Holtmann 56292f010b55SMarcel Holtmann process_adv_report(hdev, ev->evt_type, &ev->bdaddr, 56302f010b55SMarcel Holtmann ev->bdaddr_type, &ev->direct_addr, 56312f010b55SMarcel Holtmann ev->direct_addr_type, ev->rssi, NULL, 0); 56322f010b55SMarcel Holtmann 56332f010b55SMarcel Holtmann ptr += sizeof(*ev); 56342f010b55SMarcel Holtmann } 56352f010b55SMarcel Holtmann 56362f010b55SMarcel Holtmann hci_dev_unlock(hdev); 56372f010b55SMarcel Holtmann } 56382f010b55SMarcel Holtmann 56396039aa73SGustavo Padovan static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) 5640fcd89c09SVille Tervo { 5641fcd89c09SVille Tervo struct hci_ev_le_meta *le_ev = (void *) skb->data; 5642fcd89c09SVille Tervo 5643fcd89c09SVille Tervo skb_pull(skb, sizeof(*le_ev)); 5644fcd89c09SVille Tervo 5645fcd89c09SVille Tervo switch (le_ev->subevent) { 5646fcd89c09SVille Tervo case HCI_EV_LE_CONN_COMPLETE: 5647fcd89c09SVille Tervo hci_le_conn_complete_evt(hdev, skb); 5648fcd89c09SVille Tervo break; 5649fcd89c09SVille Tervo 56501855d92dSMarcel Holtmann case HCI_EV_LE_CONN_UPDATE_COMPLETE: 56511855d92dSMarcel Holtmann hci_le_conn_update_complete_evt(hdev, skb); 56521855d92dSMarcel Holtmann break; 56531855d92dSMarcel Holtmann 56549aa04c91SAndre Guedes case HCI_EV_LE_ADVERTISING_REPORT: 56559aa04c91SAndre Guedes hci_le_adv_report_evt(hdev, skb); 56569aa04c91SAndre Guedes break; 56579aa04c91SAndre Guedes 56580fe29fd1SMarcel Holtmann case HCI_EV_LE_REMOTE_FEAT_COMPLETE: 56590fe29fd1SMarcel Holtmann hci_le_remote_feat_complete_evt(hdev, skb); 56600fe29fd1SMarcel Holtmann break; 56610fe29fd1SMarcel Holtmann 5662a7a595f6SVinicius Costa Gomes case HCI_EV_LE_LTK_REQ: 5663a7a595f6SVinicius Costa Gomes hci_le_ltk_request_evt(hdev, skb); 5664a7a595f6SVinicius Costa Gomes break; 5665a7a595f6SVinicius Costa Gomes 56668e75b46aSAndre Guedes case HCI_EV_LE_REMOTE_CONN_PARAM_REQ: 56678e75b46aSAndre Guedes hci_le_remote_conn_param_req_evt(hdev, skb); 56688e75b46aSAndre Guedes break; 56698e75b46aSAndre Guedes 56702f010b55SMarcel Holtmann case HCI_EV_LE_DIRECT_ADV_REPORT: 56712f010b55SMarcel Holtmann hci_le_direct_adv_report_evt(hdev, skb); 56722f010b55SMarcel Holtmann break; 56732f010b55SMarcel Holtmann 5674c215e939SJaganath Kanakkassery case HCI_EV_LE_EXT_ADV_REPORT: 5675c215e939SJaganath Kanakkassery hci_le_ext_adv_report_evt(hdev, skb); 5676c215e939SJaganath Kanakkassery break; 5677c215e939SJaganath Kanakkassery 56784d94f95dSJaganath Kanakkassery case HCI_EV_LE_ENHANCED_CONN_COMPLETE: 56794d94f95dSJaganath Kanakkassery hci_le_enh_conn_complete_evt(hdev, skb); 56804d94f95dSJaganath Kanakkassery break; 56814d94f95dSJaganath Kanakkassery 5682acf0aeaeSJaganath Kanakkassery case HCI_EV_LE_EXT_ADV_SET_TERM: 5683acf0aeaeSJaganath Kanakkassery hci_le_ext_adv_term_evt(hdev, skb); 5684acf0aeaeSJaganath Kanakkassery break; 5685acf0aeaeSJaganath Kanakkassery 5686fcd89c09SVille Tervo default: 5687fcd89c09SVille Tervo break; 5688fcd89c09SVille Tervo } 5689fcd89c09SVille Tervo } 5690fcd89c09SVille Tervo 5691757aa0b5SJohan Hedberg static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 5692757aa0b5SJohan Hedberg u8 event, struct sk_buff *skb) 5693757aa0b5SJohan Hedberg { 5694757aa0b5SJohan Hedberg struct hci_ev_cmd_complete *ev; 5695757aa0b5SJohan Hedberg struct hci_event_hdr *hdr; 5696757aa0b5SJohan Hedberg 5697757aa0b5SJohan Hedberg if (!skb) 5698757aa0b5SJohan Hedberg return false; 5699757aa0b5SJohan Hedberg 5700757aa0b5SJohan Hedberg if (skb->len < sizeof(*hdr)) { 57012064ee33SMarcel Holtmann bt_dev_err(hdev, "too short HCI event"); 5702757aa0b5SJohan Hedberg return false; 5703757aa0b5SJohan Hedberg } 5704757aa0b5SJohan Hedberg 5705757aa0b5SJohan Hedberg hdr = (void *) skb->data; 5706757aa0b5SJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 5707757aa0b5SJohan Hedberg 5708757aa0b5SJohan Hedberg if (event) { 5709757aa0b5SJohan Hedberg if (hdr->evt != event) 5710757aa0b5SJohan Hedberg return false; 5711757aa0b5SJohan Hedberg return true; 5712757aa0b5SJohan Hedberg } 5713757aa0b5SJohan Hedberg 57141629db9cSJohan Hedberg /* Check if request ended in Command Status - no way to retreive 57151629db9cSJohan Hedberg * any extra parameters in this case. 57161629db9cSJohan Hedberg */ 57171629db9cSJohan Hedberg if (hdr->evt == HCI_EV_CMD_STATUS) 57181629db9cSJohan Hedberg return false; 57191629db9cSJohan Hedberg 5720757aa0b5SJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 57212064ee33SMarcel Holtmann bt_dev_err(hdev, "last event is not cmd complete (0x%2.2x)", 57222064ee33SMarcel Holtmann hdr->evt); 5723757aa0b5SJohan Hedberg return false; 5724757aa0b5SJohan Hedberg } 5725757aa0b5SJohan Hedberg 5726757aa0b5SJohan Hedberg if (skb->len < sizeof(*ev)) { 57272064ee33SMarcel Holtmann bt_dev_err(hdev, "too short cmd_complete event"); 5728757aa0b5SJohan Hedberg return false; 5729757aa0b5SJohan Hedberg } 5730757aa0b5SJohan Hedberg 5731757aa0b5SJohan Hedberg ev = (void *) skb->data; 5732757aa0b5SJohan Hedberg skb_pull(skb, sizeof(*ev)); 5733757aa0b5SJohan Hedberg 5734757aa0b5SJohan Hedberg if (opcode != __le16_to_cpu(ev->opcode)) { 5735757aa0b5SJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 5736757aa0b5SJohan Hedberg __le16_to_cpu(ev->opcode)); 5737757aa0b5SJohan Hedberg return false; 5738757aa0b5SJohan Hedberg } 5739757aa0b5SJohan Hedberg 5740757aa0b5SJohan Hedberg return true; 5741757aa0b5SJohan Hedberg } 5742757aa0b5SJohan Hedberg 57431da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) 57441da177e4SLinus Torvalds { 5745a9de9248SMarcel Holtmann struct hci_event_hdr *hdr = (void *) skb->data; 5746e6214487SJohan Hedberg hci_req_complete_t req_complete = NULL; 5747e6214487SJohan Hedberg hci_req_complete_skb_t req_complete_skb = NULL; 5748e6214487SJohan Hedberg struct sk_buff *orig_skb = NULL; 5749757aa0b5SJohan Hedberg u8 status = 0, event = hdr->evt, req_evt = 0; 5750e6214487SJohan Hedberg u16 opcode = HCI_OP_NOP; 57511da177e4SLinus Torvalds 5752242c0ebdSMarcel Holtmann if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->hci.req_event == event) { 5753c1f23a2bSJohannes Berg struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data; 5754e6214487SJohan Hedberg opcode = __le16_to_cpu(cmd_hdr->opcode); 5755e6214487SJohan Hedberg hci_req_cmd_complete(hdev, opcode, status, &req_complete, 5756e6214487SJohan Hedberg &req_complete_skb); 5757757aa0b5SJohan Hedberg req_evt = event; 575802350a72SJohan Hedberg } 575902350a72SJohan Hedberg 5760e6214487SJohan Hedberg /* If it looks like we might end up having to call 5761e6214487SJohan Hedberg * req_complete_skb, store a pristine copy of the skb since the 5762e6214487SJohan Hedberg * various handlers may modify the original one through 5763e6214487SJohan Hedberg * skb_pull() calls, etc. 5764e6214487SJohan Hedberg */ 5765e6214487SJohan Hedberg if (req_complete_skb || event == HCI_EV_CMD_STATUS || 5766e6214487SJohan Hedberg event == HCI_EV_CMD_COMPLETE) 5767e6214487SJohan Hedberg orig_skb = skb_clone(skb, GFP_KERNEL); 5768e6214487SJohan Hedberg 5769e6214487SJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 5770e6214487SJohan Hedberg 5771a9de9248SMarcel Holtmann switch (event) { 57721da177e4SLinus Torvalds case HCI_EV_INQUIRY_COMPLETE: 57731da177e4SLinus Torvalds hci_inquiry_complete_evt(hdev, skb); 57741da177e4SLinus Torvalds break; 57751da177e4SLinus Torvalds 57761da177e4SLinus Torvalds case HCI_EV_INQUIRY_RESULT: 57771da177e4SLinus Torvalds hci_inquiry_result_evt(hdev, skb); 57781da177e4SLinus Torvalds break; 57791da177e4SLinus Torvalds 5780a9de9248SMarcel Holtmann case HCI_EV_CONN_COMPLETE: 5781a9de9248SMarcel Holtmann hci_conn_complete_evt(hdev, skb); 578221d9e30eSMarcel Holtmann break; 578321d9e30eSMarcel Holtmann 57841da177e4SLinus Torvalds case HCI_EV_CONN_REQUEST: 57851da177e4SLinus Torvalds hci_conn_request_evt(hdev, skb); 57861da177e4SLinus Torvalds break; 57871da177e4SLinus Torvalds 57881da177e4SLinus Torvalds case HCI_EV_DISCONN_COMPLETE: 57891da177e4SLinus Torvalds hci_disconn_complete_evt(hdev, skb); 57901da177e4SLinus Torvalds break; 57911da177e4SLinus Torvalds 57921da177e4SLinus Torvalds case HCI_EV_AUTH_COMPLETE: 57931da177e4SLinus Torvalds hci_auth_complete_evt(hdev, skb); 57941da177e4SLinus Torvalds break; 57951da177e4SLinus Torvalds 5796a9de9248SMarcel Holtmann case HCI_EV_REMOTE_NAME: 5797a9de9248SMarcel Holtmann hci_remote_name_evt(hdev, skb); 5798a9de9248SMarcel Holtmann break; 5799a9de9248SMarcel Holtmann 58001da177e4SLinus Torvalds case HCI_EV_ENCRYPT_CHANGE: 58011da177e4SLinus Torvalds hci_encrypt_change_evt(hdev, skb); 58021da177e4SLinus Torvalds break; 58031da177e4SLinus Torvalds 5804a9de9248SMarcel Holtmann case HCI_EV_CHANGE_LINK_KEY_COMPLETE: 5805a9de9248SMarcel Holtmann hci_change_link_key_complete_evt(hdev, skb); 5806a9de9248SMarcel Holtmann break; 5807a9de9248SMarcel Holtmann 5808a9de9248SMarcel Holtmann case HCI_EV_REMOTE_FEATURES: 5809a9de9248SMarcel Holtmann hci_remote_features_evt(hdev, skb); 5810a9de9248SMarcel Holtmann break; 5811a9de9248SMarcel Holtmann 5812a9de9248SMarcel Holtmann case HCI_EV_CMD_COMPLETE: 5813e6214487SJohan Hedberg hci_cmd_complete_evt(hdev, skb, &opcode, &status, 5814e6214487SJohan Hedberg &req_complete, &req_complete_skb); 5815a9de9248SMarcel Holtmann break; 5816a9de9248SMarcel Holtmann 5817a9de9248SMarcel Holtmann case HCI_EV_CMD_STATUS: 5818e6214487SJohan Hedberg hci_cmd_status_evt(hdev, skb, &opcode, &status, &req_complete, 5819e6214487SJohan Hedberg &req_complete_skb); 5820a9de9248SMarcel Holtmann break; 5821a9de9248SMarcel Holtmann 582224dfa343SMarcel Holtmann case HCI_EV_HARDWARE_ERROR: 582324dfa343SMarcel Holtmann hci_hardware_error_evt(hdev, skb); 582424dfa343SMarcel Holtmann break; 582524dfa343SMarcel Holtmann 5826a9de9248SMarcel Holtmann case HCI_EV_ROLE_CHANGE: 5827a9de9248SMarcel Holtmann hci_role_change_evt(hdev, skb); 5828a9de9248SMarcel Holtmann break; 5829a9de9248SMarcel Holtmann 5830a9de9248SMarcel Holtmann case HCI_EV_NUM_COMP_PKTS: 5831a9de9248SMarcel Holtmann hci_num_comp_pkts_evt(hdev, skb); 5832a9de9248SMarcel Holtmann break; 5833a9de9248SMarcel Holtmann 5834a9de9248SMarcel Holtmann case HCI_EV_MODE_CHANGE: 5835a9de9248SMarcel Holtmann hci_mode_change_evt(hdev, skb); 58361da177e4SLinus Torvalds break; 58371da177e4SLinus Torvalds 58381da177e4SLinus Torvalds case HCI_EV_PIN_CODE_REQ: 58391da177e4SLinus Torvalds hci_pin_code_request_evt(hdev, skb); 58401da177e4SLinus Torvalds break; 58411da177e4SLinus Torvalds 58421da177e4SLinus Torvalds case HCI_EV_LINK_KEY_REQ: 58431da177e4SLinus Torvalds hci_link_key_request_evt(hdev, skb); 58441da177e4SLinus Torvalds break; 58451da177e4SLinus Torvalds 58461da177e4SLinus Torvalds case HCI_EV_LINK_KEY_NOTIFY: 58471da177e4SLinus Torvalds hci_link_key_notify_evt(hdev, skb); 58481da177e4SLinus Torvalds break; 58491da177e4SLinus Torvalds 58501da177e4SLinus Torvalds case HCI_EV_CLOCK_OFFSET: 58511da177e4SLinus Torvalds hci_clock_offset_evt(hdev, skb); 58521da177e4SLinus Torvalds break; 58531da177e4SLinus Torvalds 5854a8746417SMarcel Holtmann case HCI_EV_PKT_TYPE_CHANGE: 5855a8746417SMarcel Holtmann hci_pkt_type_change_evt(hdev, skb); 5856a8746417SMarcel Holtmann break; 5857a8746417SMarcel Holtmann 585885a1e930SMarcel Holtmann case HCI_EV_PSCAN_REP_MODE: 585985a1e930SMarcel Holtmann hci_pscan_rep_mode_evt(hdev, skb); 586085a1e930SMarcel Holtmann break; 586185a1e930SMarcel Holtmann 5862a9de9248SMarcel Holtmann case HCI_EV_INQUIRY_RESULT_WITH_RSSI: 5863a9de9248SMarcel Holtmann hci_inquiry_result_with_rssi_evt(hdev, skb); 5864a9de9248SMarcel Holtmann break; 5865a9de9248SMarcel Holtmann 5866a9de9248SMarcel Holtmann case HCI_EV_REMOTE_EXT_FEATURES: 5867a9de9248SMarcel Holtmann hci_remote_ext_features_evt(hdev, skb); 5868a9de9248SMarcel Holtmann break; 5869a9de9248SMarcel Holtmann 5870a9de9248SMarcel Holtmann case HCI_EV_SYNC_CONN_COMPLETE: 5871a9de9248SMarcel Holtmann hci_sync_conn_complete_evt(hdev, skb); 5872a9de9248SMarcel Holtmann break; 5873a9de9248SMarcel Holtmann 5874a9de9248SMarcel Holtmann case HCI_EV_EXTENDED_INQUIRY_RESULT: 5875a9de9248SMarcel Holtmann hci_extended_inquiry_result_evt(hdev, skb); 58761da177e4SLinus Torvalds break; 58771da177e4SLinus Torvalds 58781c2e0041SJohan Hedberg case HCI_EV_KEY_REFRESH_COMPLETE: 58791c2e0041SJohan Hedberg hci_key_refresh_complete_evt(hdev, skb); 58801c2e0041SJohan Hedberg break; 58811c2e0041SJohan Hedberg 58820493684eSMarcel Holtmann case HCI_EV_IO_CAPA_REQUEST: 58830493684eSMarcel Holtmann hci_io_capa_request_evt(hdev, skb); 58840493684eSMarcel Holtmann break; 58850493684eSMarcel Holtmann 588603b555e1SJohan Hedberg case HCI_EV_IO_CAPA_REPLY: 588703b555e1SJohan Hedberg hci_io_capa_reply_evt(hdev, skb); 588803b555e1SJohan Hedberg break; 588903b555e1SJohan Hedberg 5890a5c29683SJohan Hedberg case HCI_EV_USER_CONFIRM_REQUEST: 5891a5c29683SJohan Hedberg hci_user_confirm_request_evt(hdev, skb); 5892a5c29683SJohan Hedberg break; 5893a5c29683SJohan Hedberg 58941143d458SBrian Gix case HCI_EV_USER_PASSKEY_REQUEST: 58951143d458SBrian Gix hci_user_passkey_request_evt(hdev, skb); 58961143d458SBrian Gix break; 58971143d458SBrian Gix 589892a25256SJohan Hedberg case HCI_EV_USER_PASSKEY_NOTIFY: 589992a25256SJohan Hedberg hci_user_passkey_notify_evt(hdev, skb); 590092a25256SJohan Hedberg break; 590192a25256SJohan Hedberg 590292a25256SJohan Hedberg case HCI_EV_KEYPRESS_NOTIFY: 590392a25256SJohan Hedberg hci_keypress_notify_evt(hdev, skb); 590492a25256SJohan Hedberg break; 590592a25256SJohan Hedberg 59060493684eSMarcel Holtmann case HCI_EV_SIMPLE_PAIR_COMPLETE: 59070493684eSMarcel Holtmann hci_simple_pair_complete_evt(hdev, skb); 59080493684eSMarcel Holtmann break; 59090493684eSMarcel Holtmann 591041a96212SMarcel Holtmann case HCI_EV_REMOTE_HOST_FEATURES: 591141a96212SMarcel Holtmann hci_remote_host_features_evt(hdev, skb); 591241a96212SMarcel Holtmann break; 591341a96212SMarcel Holtmann 5914fcd89c09SVille Tervo case HCI_EV_LE_META: 5915fcd89c09SVille Tervo hci_le_meta_evt(hdev, skb); 5916fcd89c09SVille Tervo break; 5917fcd89c09SVille Tervo 59182763eda6SSzymon Janc case HCI_EV_REMOTE_OOB_DATA_REQUEST: 59192763eda6SSzymon Janc hci_remote_oob_data_request_evt(hdev, skb); 59202763eda6SSzymon Janc break; 59212763eda6SSzymon Janc 5922a77a6a14SArron Wang #if IS_ENABLED(CONFIG_BT_HS) 5923a77a6a14SArron Wang case HCI_EV_CHANNEL_SELECTED: 5924a77a6a14SArron Wang hci_chan_selected_evt(hdev, skb); 5925a77a6a14SArron Wang break; 5926a77a6a14SArron Wang 5927d5e91192SAndrei Emeltchenko case HCI_EV_PHY_LINK_COMPLETE: 5928d5e91192SAndrei Emeltchenko hci_phy_link_complete_evt(hdev, skb); 5929d5e91192SAndrei Emeltchenko break; 5930d5e91192SAndrei Emeltchenko 593127695fb4SAndrei Emeltchenko case HCI_EV_LOGICAL_LINK_COMPLETE: 593227695fb4SAndrei Emeltchenko hci_loglink_complete_evt(hdev, skb); 593327695fb4SAndrei Emeltchenko break; 593427695fb4SAndrei Emeltchenko 5935606e2a10SAndrei Emeltchenko case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE: 5936606e2a10SAndrei Emeltchenko hci_disconn_loglink_complete_evt(hdev, skb); 5937606e2a10SAndrei Emeltchenko break; 5938606e2a10SAndrei Emeltchenko 59399eef6b3aSAndrei Emeltchenko case HCI_EV_DISCONN_PHY_LINK_COMPLETE: 59409eef6b3aSAndrei Emeltchenko hci_disconn_phylink_complete_evt(hdev, skb); 59419eef6b3aSAndrei Emeltchenko break; 5942a77a6a14SArron Wang #endif 59439eef6b3aSAndrei Emeltchenko 594425e89e99SAndrei Emeltchenko case HCI_EV_NUM_COMP_BLOCKS: 594525e89e99SAndrei Emeltchenko hci_num_comp_blocks_evt(hdev, skb); 594625e89e99SAndrei Emeltchenko break; 594725e89e99SAndrei Emeltchenko 59481da177e4SLinus Torvalds default: 59499f1db00cSAndrei Emeltchenko BT_DBG("%s event 0x%2.2x", hdev->name, event); 59501da177e4SLinus Torvalds break; 59511da177e4SLinus Torvalds } 59521da177e4SLinus Torvalds 5953757aa0b5SJohan Hedberg if (req_complete) { 5954e6214487SJohan Hedberg req_complete(hdev, status, opcode); 5955757aa0b5SJohan Hedberg } else if (req_complete_skb) { 5956757aa0b5SJohan Hedberg if (!hci_get_cmd_complete(hdev, opcode, req_evt, orig_skb)) { 5957757aa0b5SJohan Hedberg kfree_skb(orig_skb); 5958757aa0b5SJohan Hedberg orig_skb = NULL; 5959757aa0b5SJohan Hedberg } 5960e6214487SJohan Hedberg req_complete_skb(hdev, status, opcode, orig_skb); 5961757aa0b5SJohan Hedberg } 5962e6214487SJohan Hedberg 5963e6214487SJohan Hedberg kfree_skb(orig_skb); 59641da177e4SLinus Torvalds kfree_skb(skb); 59651da177e4SLinus Torvalds hdev->stat.evt_rx++; 59661da177e4SLinus Torvalds } 5967