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); 224a9de9248SMarcel Holtmann } 225a9de9248SMarcel Holtmann 226c2f0f979SMarcel Holtmann static void hci_cc_read_stored_link_key(struct hci_dev *hdev, 227c2f0f979SMarcel Holtmann struct sk_buff *skb) 228c2f0f979SMarcel Holtmann { 229c2f0f979SMarcel Holtmann struct hci_rp_read_stored_link_key *rp = (void *)skb->data; 230c2f0f979SMarcel Holtmann struct hci_cp_read_stored_link_key *sent; 231c2f0f979SMarcel Holtmann 232c2f0f979SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 233c2f0f979SMarcel Holtmann 234c2f0f979SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_READ_STORED_LINK_KEY); 235c2f0f979SMarcel Holtmann if (!sent) 236c2f0f979SMarcel Holtmann return; 237c2f0f979SMarcel Holtmann 238c2f0f979SMarcel Holtmann if (!rp->status && sent->read_all == 0x01) { 239c2f0f979SMarcel Holtmann hdev->stored_max_keys = rp->max_keys; 240c2f0f979SMarcel Holtmann hdev->stored_num_keys = rp->num_keys; 241c2f0f979SMarcel Holtmann } 242c2f0f979SMarcel Holtmann } 243c2f0f979SMarcel Holtmann 244a9366120SMarcel Holtmann static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, 245a9366120SMarcel Holtmann struct sk_buff *skb) 246a9366120SMarcel Holtmann { 247a9366120SMarcel Holtmann struct hci_rp_delete_stored_link_key *rp = (void *)skb->data; 248a9366120SMarcel Holtmann 249a9366120SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 250a9366120SMarcel Holtmann 251a9366120SMarcel Holtmann if (rp->status) 252a9366120SMarcel Holtmann return; 253a9366120SMarcel Holtmann 254a9366120SMarcel Holtmann if (rp->num_keys <= hdev->stored_num_keys) 255a9366120SMarcel Holtmann hdev->stored_num_keys -= rp->num_keys; 256a9366120SMarcel Holtmann else 257a9366120SMarcel Holtmann hdev->stored_num_keys = 0; 258a9366120SMarcel Holtmann } 259a9366120SMarcel Holtmann 260a9de9248SMarcel Holtmann static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) 261a9de9248SMarcel Holtmann { 262a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 2631da177e4SLinus Torvalds void *sent; 2641da177e4SLinus Torvalds 2659f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 2661da177e4SLinus Torvalds 267a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME); 2681da177e4SLinus Torvalds if (!sent) 269a9de9248SMarcel Holtmann return; 2701da177e4SLinus Torvalds 27156e5cb86SJohan Hedberg hci_dev_lock(hdev); 27256e5cb86SJohan Hedberg 273d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 274f51d5b24SJohan Hedberg mgmt_set_local_name_complete(hdev, sent, status); 27528cc7bdeSJohan Hedberg else if (!status) 27628cc7bdeSJohan Hedberg memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); 277f51d5b24SJohan Hedberg 27856e5cb86SJohan Hedberg hci_dev_unlock(hdev); 279a9de9248SMarcel Holtmann } 280a9de9248SMarcel Holtmann 281a9de9248SMarcel Holtmann static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) 282a9de9248SMarcel Holtmann { 283a9de9248SMarcel Holtmann struct hci_rp_read_local_name *rp = (void *) skb->data; 284a9de9248SMarcel Holtmann 2859f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 286a9de9248SMarcel Holtmann 287a9de9248SMarcel Holtmann if (rp->status) 288a9de9248SMarcel Holtmann return; 289a9de9248SMarcel Holtmann 290d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 291d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) 2921f6c6378SJohan Hedberg memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); 293a9de9248SMarcel Holtmann } 294a9de9248SMarcel Holtmann 295a9de9248SMarcel Holtmann static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) 296a9de9248SMarcel Holtmann { 297a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 298a9de9248SMarcel Holtmann void *sent; 299a9de9248SMarcel Holtmann 3009f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 301a9de9248SMarcel Holtmann 302a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE); 303a9de9248SMarcel Holtmann if (!sent) 304a9de9248SMarcel Holtmann return; 3051da177e4SLinus Torvalds 3065c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 3075c1a4c8fSJaganath Kanakkassery 3081da177e4SLinus Torvalds if (!status) { 309a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 310a9de9248SMarcel Holtmann 3111da177e4SLinus Torvalds if (param == AUTH_ENABLED) 3121da177e4SLinus Torvalds set_bit(HCI_AUTH, &hdev->flags); 3131da177e4SLinus Torvalds else 3141da177e4SLinus Torvalds clear_bit(HCI_AUTH, &hdev->flags); 3151da177e4SLinus Torvalds } 316a9de9248SMarcel Holtmann 317d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 31833ef95edSJohan Hedberg mgmt_auth_enable_complete(hdev, status); 3195c1a4c8fSJaganath Kanakkassery 3205c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 321a9de9248SMarcel Holtmann } 3221da177e4SLinus Torvalds 323a9de9248SMarcel Holtmann static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) 324a9de9248SMarcel Holtmann { 325a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 32645296acdSMarcel Holtmann __u8 param; 327a9de9248SMarcel Holtmann void *sent; 328a9de9248SMarcel Holtmann 3299f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 330a9de9248SMarcel Holtmann 33145296acdSMarcel Holtmann if (status) 33245296acdSMarcel Holtmann return; 33345296acdSMarcel Holtmann 334a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE); 3351da177e4SLinus Torvalds if (!sent) 336a9de9248SMarcel Holtmann return; 3371da177e4SLinus Torvalds 33845296acdSMarcel Holtmann param = *((__u8 *) sent); 339a9de9248SMarcel Holtmann 3401da177e4SLinus Torvalds if (param) 3411da177e4SLinus Torvalds set_bit(HCI_ENCRYPT, &hdev->flags); 3421da177e4SLinus Torvalds else 3431da177e4SLinus Torvalds clear_bit(HCI_ENCRYPT, &hdev->flags); 3441da177e4SLinus Torvalds } 3451da177e4SLinus Torvalds 346a9de9248SMarcel Holtmann static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) 347a9de9248SMarcel Holtmann { 34845296acdSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 34945296acdSMarcel Holtmann __u8 param; 350a9de9248SMarcel Holtmann void *sent; 3511da177e4SLinus Torvalds 3529f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 353a9de9248SMarcel Holtmann 354a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE); 3551da177e4SLinus Torvalds if (!sent) 356a9de9248SMarcel Holtmann return; 3571da177e4SLinus Torvalds 35836f7fc7eSJohan Hedberg param = *((__u8 *) sent); 359a9de9248SMarcel Holtmann 36056e5cb86SJohan Hedberg hci_dev_lock(hdev); 36156e5cb86SJohan Hedberg 362fa1bd918SMikel Astiz if (status) { 3632d7cee58SJohan Hedberg hdev->discov_timeout = 0; 3642d7cee58SJohan Hedberg goto done; 3652d7cee58SJohan Hedberg } 3662d7cee58SJohan Hedberg 367bc6d2d04SJohan Hedberg if (param & SCAN_INQUIRY) 3681da177e4SLinus Torvalds set_bit(HCI_ISCAN, &hdev->flags); 369bc6d2d04SJohan Hedberg else 370bc6d2d04SJohan Hedberg clear_bit(HCI_ISCAN, &hdev->flags); 3711da177e4SLinus Torvalds 372031547d8SJohan Hedberg if (param & SCAN_PAGE) 3731da177e4SLinus Torvalds set_bit(HCI_PSCAN, &hdev->flags); 374bc6d2d04SJohan Hedberg else 375204e3990SJohan Hedberg clear_bit(HCI_PSCAN, &hdev->flags); 376a9de9248SMarcel Holtmann 37736f7fc7eSJohan Hedberg done: 37856e5cb86SJohan Hedberg hci_dev_unlock(hdev); 3791da177e4SLinus Torvalds } 3801da177e4SLinus Torvalds 381a9de9248SMarcel Holtmann static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 382a9de9248SMarcel Holtmann { 383a9de9248SMarcel Holtmann struct hci_rp_read_class_of_dev *rp = (void *) skb->data; 384a9de9248SMarcel Holtmann 3859f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 386a9de9248SMarcel Holtmann 387a9de9248SMarcel Holtmann if (rp->status) 388a9de9248SMarcel Holtmann return; 389a9de9248SMarcel Holtmann 390a9de9248SMarcel Holtmann memcpy(hdev->dev_class, rp->dev_class, 3); 391a9de9248SMarcel Holtmann 392a9de9248SMarcel Holtmann BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name, 393a9de9248SMarcel Holtmann hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); 394a9de9248SMarcel Holtmann } 395a9de9248SMarcel Holtmann 396a9de9248SMarcel Holtmann static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 397a9de9248SMarcel Holtmann { 398a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 399a9de9248SMarcel Holtmann void *sent; 400a9de9248SMarcel Holtmann 4019f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 402a9de9248SMarcel Holtmann 403a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV); 404a9de9248SMarcel Holtmann if (!sent) 405a9de9248SMarcel Holtmann return; 406a9de9248SMarcel Holtmann 4077f9a903cSMarcel Holtmann hci_dev_lock(hdev); 4087f9a903cSMarcel Holtmann 4097f9a903cSMarcel Holtmann if (status == 0) 410a9de9248SMarcel Holtmann memcpy(hdev->dev_class, sent, 3); 4117f9a903cSMarcel Holtmann 412d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 4137f9a903cSMarcel Holtmann mgmt_set_class_of_dev_complete(hdev, sent, status); 4147f9a903cSMarcel Holtmann 4157f9a903cSMarcel Holtmann hci_dev_unlock(hdev); 416a9de9248SMarcel Holtmann } 417a9de9248SMarcel Holtmann 418a9de9248SMarcel Holtmann static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) 419a9de9248SMarcel Holtmann { 420a9de9248SMarcel Holtmann struct hci_rp_read_voice_setting *rp = (void *) skb->data; 421a9de9248SMarcel Holtmann __u16 setting; 422a9de9248SMarcel Holtmann 4239f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 424a9de9248SMarcel Holtmann 425a9de9248SMarcel Holtmann if (rp->status) 426a9de9248SMarcel Holtmann return; 427a9de9248SMarcel Holtmann 428a9de9248SMarcel Holtmann setting = __le16_to_cpu(rp->voice_setting); 429a9de9248SMarcel Holtmann 430a9de9248SMarcel Holtmann if (hdev->voice_setting == setting) 431a9de9248SMarcel Holtmann return; 432a9de9248SMarcel Holtmann 433a9de9248SMarcel Holtmann hdev->voice_setting = setting; 434a9de9248SMarcel Holtmann 4359f1db00cSAndrei Emeltchenko BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting); 436a9de9248SMarcel Holtmann 4373c54711cSGustavo F. Padovan if (hdev->notify) 438a9de9248SMarcel Holtmann hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 439a9de9248SMarcel Holtmann } 440a9de9248SMarcel Holtmann 4418fc9ced3SGustavo Padovan static void hci_cc_write_voice_setting(struct hci_dev *hdev, 4428fc9ced3SGustavo Padovan struct sk_buff *skb) 443a9de9248SMarcel Holtmann { 444a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 445f383f275SMarcel Holtmann __u16 setting; 446a9de9248SMarcel Holtmann void *sent; 447a9de9248SMarcel Holtmann 4489f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 449a9de9248SMarcel Holtmann 450f383f275SMarcel Holtmann if (status) 451f383f275SMarcel Holtmann return; 452f383f275SMarcel Holtmann 453a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING); 454a9de9248SMarcel Holtmann if (!sent) 455a9de9248SMarcel Holtmann return; 456a9de9248SMarcel Holtmann 457f383f275SMarcel Holtmann setting = get_unaligned_le16(sent); 4581da177e4SLinus Torvalds 459f383f275SMarcel Holtmann if (hdev->voice_setting == setting) 460f383f275SMarcel Holtmann return; 461f383f275SMarcel Holtmann 4621da177e4SLinus Torvalds hdev->voice_setting = setting; 4631da177e4SLinus Torvalds 4649f1db00cSAndrei Emeltchenko BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting); 4651da177e4SLinus Torvalds 4663c54711cSGustavo F. Padovan if (hdev->notify) 4671da177e4SLinus Torvalds hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 4681da177e4SLinus Torvalds } 4691da177e4SLinus Torvalds 470b4cb9fb2SMarcel Holtmann static void hci_cc_read_num_supported_iac(struct hci_dev *hdev, 471b4cb9fb2SMarcel Holtmann struct sk_buff *skb) 472b4cb9fb2SMarcel Holtmann { 473b4cb9fb2SMarcel Holtmann struct hci_rp_read_num_supported_iac *rp = (void *) skb->data; 474b4cb9fb2SMarcel Holtmann 475b4cb9fb2SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 476b4cb9fb2SMarcel Holtmann 477b4cb9fb2SMarcel Holtmann if (rp->status) 478b4cb9fb2SMarcel Holtmann return; 479b4cb9fb2SMarcel Holtmann 480b4cb9fb2SMarcel Holtmann hdev->num_iac = rp->num_iac; 481b4cb9fb2SMarcel Holtmann 482b4cb9fb2SMarcel Holtmann BT_DBG("%s num iac %d", hdev->name, hdev->num_iac); 483b4cb9fb2SMarcel Holtmann } 484b4cb9fb2SMarcel Holtmann 485333140b5SMarcel Holtmann static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) 486333140b5SMarcel Holtmann { 487333140b5SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 4885ed8eb2fSJohan Hedberg struct hci_cp_write_ssp_mode *sent; 489333140b5SMarcel Holtmann 4909f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 491333140b5SMarcel Holtmann 492333140b5SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); 493333140b5SMarcel Holtmann if (!sent) 494333140b5SMarcel Holtmann return; 495333140b5SMarcel Holtmann 4965c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 4975c1a4c8fSJaganath Kanakkassery 4985ed8eb2fSJohan Hedberg if (!status) { 4995ed8eb2fSJohan Hedberg if (sent->mode) 500cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_SSP; 5015ed8eb2fSJohan Hedberg else 502cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_SSP; 5035ed8eb2fSJohan Hedberg } 5045ed8eb2fSJohan Hedberg 505d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 5065ed8eb2fSJohan Hedberg mgmt_ssp_enable_complete(hdev, sent->mode, status); 507c0ecddc2SJohan Hedberg else if (!status) { 5085ed8eb2fSJohan Hedberg if (sent->mode) 509a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SSP_ENABLED); 51084bde9d6SJohan Hedberg else 511a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_SSP_ENABLED); 512c0ecddc2SJohan Hedberg } 5135c1a4c8fSJaganath Kanakkassery 5145c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 515333140b5SMarcel Holtmann } 516333140b5SMarcel Holtmann 517eac83dc6SMarcel Holtmann static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb) 518eac83dc6SMarcel Holtmann { 519eac83dc6SMarcel Holtmann u8 status = *((u8 *) skb->data); 520eac83dc6SMarcel Holtmann struct hci_cp_write_sc_support *sent; 521eac83dc6SMarcel Holtmann 522eac83dc6SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 523eac83dc6SMarcel Holtmann 524eac83dc6SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT); 525eac83dc6SMarcel Holtmann if (!sent) 526eac83dc6SMarcel Holtmann return; 527eac83dc6SMarcel Holtmann 5285c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 5295c1a4c8fSJaganath Kanakkassery 530eac83dc6SMarcel Holtmann if (!status) { 531eac83dc6SMarcel Holtmann if (sent->support) 532eac83dc6SMarcel Holtmann hdev->features[1][0] |= LMP_HOST_SC; 533eac83dc6SMarcel Holtmann else 534eac83dc6SMarcel Holtmann hdev->features[1][0] &= ~LMP_HOST_SC; 535eac83dc6SMarcel Holtmann } 536eac83dc6SMarcel Holtmann 537d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT) && !status) { 538eac83dc6SMarcel Holtmann if (sent->support) 539a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SC_ENABLED); 540eac83dc6SMarcel Holtmann else 541a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_SC_ENABLED); 542eac83dc6SMarcel Holtmann } 5435c1a4c8fSJaganath Kanakkassery 5445c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 545eac83dc6SMarcel Holtmann } 546eac83dc6SMarcel Holtmann 547a9de9248SMarcel Holtmann static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) 548a9de9248SMarcel Holtmann { 549a9de9248SMarcel Holtmann struct hci_rp_read_local_version *rp = (void *) skb->data; 5501143e5a6SMarcel Holtmann 5519f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 5521143e5a6SMarcel Holtmann 553a9de9248SMarcel Holtmann if (rp->status) 55442c6b129SJohan Hedberg return; 5551143e5a6SMarcel Holtmann 556d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 557d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) { 558a9de9248SMarcel Holtmann hdev->hci_ver = rp->hci_ver; 559e4e8e37cSMarcel Holtmann hdev->hci_rev = __le16_to_cpu(rp->hci_rev); 560d5859e22SJohan Hedberg hdev->lmp_ver = rp->lmp_ver; 561e4e8e37cSMarcel Holtmann hdev->manufacturer = __le16_to_cpu(rp->manufacturer); 562d5859e22SJohan Hedberg hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); 5630d5551f5SMarcel Holtmann } 564d5859e22SJohan Hedberg } 565d5859e22SJohan Hedberg 5668fc9ced3SGustavo Padovan static void hci_cc_read_local_commands(struct hci_dev *hdev, 5678fc9ced3SGustavo Padovan struct sk_buff *skb) 568a9de9248SMarcel Holtmann { 569a9de9248SMarcel Holtmann struct hci_rp_read_local_commands *rp = (void *) skb->data; 570a9de9248SMarcel Holtmann 5719f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 572a9de9248SMarcel Holtmann 5736a070e6eSMarcel Holtmann if (rp->status) 5746a070e6eSMarcel Holtmann return; 5756a070e6eSMarcel Holtmann 576d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 577d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) 578a9de9248SMarcel Holtmann memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); 579a9de9248SMarcel Holtmann } 580a9de9248SMarcel Holtmann 5818fc9ced3SGustavo Padovan static void hci_cc_read_local_features(struct hci_dev *hdev, 5828fc9ced3SGustavo Padovan struct sk_buff *skb) 583a9de9248SMarcel Holtmann { 584a9de9248SMarcel Holtmann struct hci_rp_read_local_features *rp = (void *) skb->data; 585a9de9248SMarcel Holtmann 5869f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 587a9de9248SMarcel Holtmann 588a9de9248SMarcel Holtmann if (rp->status) 589a9de9248SMarcel Holtmann return; 590a9de9248SMarcel Holtmann 591a9de9248SMarcel Holtmann memcpy(hdev->features, rp->features, 8); 5921da177e4SLinus Torvalds 5931da177e4SLinus Torvalds /* Adjust default settings according to features 5941da177e4SLinus Torvalds * supported by device. */ 595a9de9248SMarcel Holtmann 596cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_3SLOT) 5971da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM3 | HCI_DH3); 5981da177e4SLinus Torvalds 599cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_5SLOT) 6001da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM5 | HCI_DH5); 6011da177e4SLinus Torvalds 602cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV2) { 6031da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV2); 6045b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV2); 6055b7f9909SMarcel Holtmann } 6061da177e4SLinus Torvalds 607cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV3) { 6081da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV3); 6095b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV3); 6105b7f9909SMarcel Holtmann } 6115b7f9909SMarcel Holtmann 61245db810fSAndre Guedes if (lmp_esco_capable(hdev)) 6135b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV3); 6145b7f9909SMarcel Holtmann 615cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV4) 6165b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV4); 6175b7f9909SMarcel Holtmann 618cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV5) 6195b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV5); 6201da177e4SLinus Torvalds 621cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_2M) 622efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV3); 623efc7688bSMarcel Holtmann 624cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_3M) 625efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_3EV3); 626efc7688bSMarcel Holtmann 627cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_3S_ESCO) 628efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); 6291da177e4SLinus Torvalds } 6301da177e4SLinus Torvalds 631971e3a4bSAndre Guedes static void hci_cc_read_local_ext_features(struct hci_dev *hdev, 632971e3a4bSAndre Guedes struct sk_buff *skb) 633971e3a4bSAndre Guedes { 634971e3a4bSAndre Guedes struct hci_rp_read_local_ext_features *rp = (void *) skb->data; 635971e3a4bSAndre Guedes 6369f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 637971e3a4bSAndre Guedes 638971e3a4bSAndre Guedes if (rp->status) 63942c6b129SJohan Hedberg return; 640971e3a4bSAndre Guedes 64157af75a8SMarcel Holtmann if (hdev->max_page < rp->max_page) 642d2c5d77fSJohan Hedberg hdev->max_page = rp->max_page; 643d2c5d77fSJohan Hedberg 644cad718edSJohan Hedberg if (rp->page < HCI_MAX_PAGES) 645cad718edSJohan Hedberg memcpy(hdev->features[rp->page], rp->features, 8); 646971e3a4bSAndre Guedes } 647971e3a4bSAndre Guedes 6481e89cffbSAndrei Emeltchenko static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, 6491e89cffbSAndrei Emeltchenko struct sk_buff *skb) 6501e89cffbSAndrei Emeltchenko { 6511e89cffbSAndrei Emeltchenko struct hci_rp_read_flow_control_mode *rp = (void *) skb->data; 6521e89cffbSAndrei Emeltchenko 6539f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 6541e89cffbSAndrei Emeltchenko 65545296acdSMarcel Holtmann if (rp->status) 65645296acdSMarcel Holtmann return; 65745296acdSMarcel Holtmann 6581e89cffbSAndrei Emeltchenko hdev->flow_ctl_mode = rp->mode; 6591e89cffbSAndrei Emeltchenko } 6601e89cffbSAndrei Emeltchenko 661a9de9248SMarcel Holtmann static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) 662a9de9248SMarcel Holtmann { 663a9de9248SMarcel Holtmann struct hci_rp_read_buffer_size *rp = (void *) skb->data; 664a9de9248SMarcel Holtmann 6659f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 666a9de9248SMarcel Holtmann 667a9de9248SMarcel Holtmann if (rp->status) 668a9de9248SMarcel Holtmann return; 669a9de9248SMarcel Holtmann 670a9de9248SMarcel Holtmann hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu); 671a9de9248SMarcel Holtmann hdev->sco_mtu = rp->sco_mtu; 672a9de9248SMarcel Holtmann hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt); 673a9de9248SMarcel Holtmann hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt); 674da1f5198SMarcel Holtmann 675da1f5198SMarcel Holtmann if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) { 676da1f5198SMarcel Holtmann hdev->sco_mtu = 64; 677da1f5198SMarcel Holtmann hdev->sco_pkts = 8; 678da1f5198SMarcel Holtmann } 679da1f5198SMarcel Holtmann 680da1f5198SMarcel Holtmann hdev->acl_cnt = hdev->acl_pkts; 681da1f5198SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 6821da177e4SLinus Torvalds 683807deac2SGustavo Padovan BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu, 684807deac2SGustavo Padovan hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts); 6851da177e4SLinus Torvalds } 6861da177e4SLinus Torvalds 687a9de9248SMarcel Holtmann static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) 688a9de9248SMarcel Holtmann { 689a9de9248SMarcel Holtmann struct hci_rp_read_bd_addr *rp = (void *) skb->data; 6901da177e4SLinus Torvalds 6919f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 692a9de9248SMarcel Holtmann 693e30d3f5fSMarcel Holtmann if (rp->status) 694e30d3f5fSMarcel Holtmann return; 695e30d3f5fSMarcel Holtmann 696e30d3f5fSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) 697a9de9248SMarcel Holtmann bacpy(&hdev->bdaddr, &rp->bdaddr); 698e30d3f5fSMarcel Holtmann 699d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) 700e30d3f5fSMarcel Holtmann bacpy(&hdev->setup_addr, &rp->bdaddr); 70123bb5763SJohan Hedberg } 70223bb5763SJohan Hedberg 703f332ec66SJohan Hedberg static void hci_cc_read_page_scan_activity(struct hci_dev *hdev, 704f332ec66SJohan Hedberg struct sk_buff *skb) 705f332ec66SJohan Hedberg { 706f332ec66SJohan Hedberg struct hci_rp_read_page_scan_activity *rp = (void *) skb->data; 707f332ec66SJohan Hedberg 708f332ec66SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 709f332ec66SJohan Hedberg 71045296acdSMarcel Holtmann if (rp->status) 71145296acdSMarcel Holtmann return; 71245296acdSMarcel Holtmann 71345296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) { 714f332ec66SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(rp->interval); 715f332ec66SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(rp->window); 716f332ec66SJohan Hedberg } 717f332ec66SJohan Hedberg } 718f332ec66SJohan Hedberg 7194a3ee763SJohan Hedberg static void hci_cc_write_page_scan_activity(struct hci_dev *hdev, 7204a3ee763SJohan Hedberg struct sk_buff *skb) 7214a3ee763SJohan Hedberg { 7224a3ee763SJohan Hedberg u8 status = *((u8 *) skb->data); 7234a3ee763SJohan Hedberg struct hci_cp_write_page_scan_activity *sent; 7244a3ee763SJohan Hedberg 7254a3ee763SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 7264a3ee763SJohan Hedberg 7274a3ee763SJohan Hedberg if (status) 7284a3ee763SJohan Hedberg return; 7294a3ee763SJohan Hedberg 7304a3ee763SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY); 7314a3ee763SJohan Hedberg if (!sent) 7324a3ee763SJohan Hedberg return; 7334a3ee763SJohan Hedberg 7344a3ee763SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(sent->interval); 7354a3ee763SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(sent->window); 7364a3ee763SJohan Hedberg } 7374a3ee763SJohan Hedberg 738f332ec66SJohan Hedberg static void hci_cc_read_page_scan_type(struct hci_dev *hdev, 739f332ec66SJohan Hedberg struct sk_buff *skb) 740f332ec66SJohan Hedberg { 741f332ec66SJohan Hedberg struct hci_rp_read_page_scan_type *rp = (void *) skb->data; 742f332ec66SJohan Hedberg 743f332ec66SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 744f332ec66SJohan Hedberg 74545296acdSMarcel Holtmann if (rp->status) 74645296acdSMarcel Holtmann return; 74745296acdSMarcel Holtmann 74845296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) 749f332ec66SJohan Hedberg hdev->page_scan_type = rp->type; 750f332ec66SJohan Hedberg } 751f332ec66SJohan Hedberg 7524a3ee763SJohan Hedberg static void hci_cc_write_page_scan_type(struct hci_dev *hdev, 7534a3ee763SJohan Hedberg struct sk_buff *skb) 7544a3ee763SJohan Hedberg { 7554a3ee763SJohan Hedberg u8 status = *((u8 *) skb->data); 7564a3ee763SJohan Hedberg u8 *type; 7574a3ee763SJohan Hedberg 7584a3ee763SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 7594a3ee763SJohan Hedberg 7604a3ee763SJohan Hedberg if (status) 7614a3ee763SJohan Hedberg return; 7624a3ee763SJohan Hedberg 7634a3ee763SJohan Hedberg type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE); 7644a3ee763SJohan Hedberg if (type) 7654a3ee763SJohan Hedberg hdev->page_scan_type = *type; 7664a3ee763SJohan Hedberg } 7674a3ee763SJohan Hedberg 768350ee4cfSAndrei Emeltchenko static void hci_cc_read_data_block_size(struct hci_dev *hdev, 769350ee4cfSAndrei Emeltchenko struct sk_buff *skb) 770350ee4cfSAndrei Emeltchenko { 771350ee4cfSAndrei Emeltchenko struct hci_rp_read_data_block_size *rp = (void *) skb->data; 772350ee4cfSAndrei Emeltchenko 7739f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 774350ee4cfSAndrei Emeltchenko 775350ee4cfSAndrei Emeltchenko if (rp->status) 776350ee4cfSAndrei Emeltchenko return; 777350ee4cfSAndrei Emeltchenko 778350ee4cfSAndrei Emeltchenko hdev->block_mtu = __le16_to_cpu(rp->max_acl_len); 779350ee4cfSAndrei Emeltchenko hdev->block_len = __le16_to_cpu(rp->block_len); 780350ee4cfSAndrei Emeltchenko hdev->num_blocks = __le16_to_cpu(rp->num_blocks); 781350ee4cfSAndrei Emeltchenko 782350ee4cfSAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 783350ee4cfSAndrei Emeltchenko 784350ee4cfSAndrei Emeltchenko BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu, 785350ee4cfSAndrei Emeltchenko hdev->block_cnt, hdev->block_len); 786350ee4cfSAndrei Emeltchenko } 787350ee4cfSAndrei Emeltchenko 78833f35721SJohan Hedberg static void hci_cc_read_clock(struct hci_dev *hdev, struct sk_buff *skb) 78933f35721SJohan Hedberg { 79033f35721SJohan Hedberg struct hci_rp_read_clock *rp = (void *) skb->data; 79133f35721SJohan Hedberg struct hci_cp_read_clock *cp; 79233f35721SJohan Hedberg struct hci_conn *conn; 79333f35721SJohan Hedberg 79433f35721SJohan Hedberg BT_DBG("%s", hdev->name); 79533f35721SJohan Hedberg 79633f35721SJohan Hedberg if (skb->len < sizeof(*rp)) 79733f35721SJohan Hedberg return; 79833f35721SJohan Hedberg 79933f35721SJohan Hedberg if (rp->status) 80033f35721SJohan Hedberg return; 80133f35721SJohan Hedberg 80233f35721SJohan Hedberg hci_dev_lock(hdev); 80333f35721SJohan Hedberg 80433f35721SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK); 80533f35721SJohan Hedberg if (!cp) 80633f35721SJohan Hedberg goto unlock; 80733f35721SJohan Hedberg 80833f35721SJohan Hedberg if (cp->which == 0x00) { 80933f35721SJohan Hedberg hdev->clock = le32_to_cpu(rp->clock); 81033f35721SJohan Hedberg goto unlock; 81133f35721SJohan Hedberg } 81233f35721SJohan Hedberg 81333f35721SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 81433f35721SJohan Hedberg if (conn) { 81533f35721SJohan Hedberg conn->clock = le32_to_cpu(rp->clock); 81633f35721SJohan Hedberg conn->clock_accuracy = le16_to_cpu(rp->accuracy); 81733f35721SJohan Hedberg } 81833f35721SJohan Hedberg 81933f35721SJohan Hedberg unlock: 82033f35721SJohan Hedberg hci_dev_unlock(hdev); 82133f35721SJohan Hedberg } 82233f35721SJohan Hedberg 823928abaa7SAndrei Emeltchenko static void hci_cc_read_local_amp_info(struct hci_dev *hdev, 824928abaa7SAndrei Emeltchenko struct sk_buff *skb) 825928abaa7SAndrei Emeltchenko { 826928abaa7SAndrei Emeltchenko struct hci_rp_read_local_amp_info *rp = (void *) skb->data; 827928abaa7SAndrei Emeltchenko 8289f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 829928abaa7SAndrei Emeltchenko 830928abaa7SAndrei Emeltchenko if (rp->status) 83183927882SArron Wang return; 832928abaa7SAndrei Emeltchenko 833928abaa7SAndrei Emeltchenko hdev->amp_status = rp->amp_status; 834928abaa7SAndrei Emeltchenko hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); 835928abaa7SAndrei Emeltchenko hdev->amp_max_bw = __le32_to_cpu(rp->max_bw); 836928abaa7SAndrei Emeltchenko hdev->amp_min_latency = __le32_to_cpu(rp->min_latency); 837928abaa7SAndrei Emeltchenko hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu); 838928abaa7SAndrei Emeltchenko hdev->amp_type = rp->amp_type; 839928abaa7SAndrei Emeltchenko hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap); 840928abaa7SAndrei Emeltchenko hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size); 841928abaa7SAndrei Emeltchenko hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to); 842928abaa7SAndrei Emeltchenko hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); 843928abaa7SAndrei Emeltchenko } 844928abaa7SAndrei Emeltchenko 845d5859e22SJohan Hedberg static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, 846d5859e22SJohan Hedberg struct sk_buff *skb) 847d5859e22SJohan Hedberg { 84891c4e9b1SMarcel Holtmann struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data; 849d5859e22SJohan Hedberg 8509f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 851d5859e22SJohan Hedberg 85245296acdSMarcel Holtmann if (rp->status) 85345296acdSMarcel Holtmann return; 85445296acdSMarcel Holtmann 85591c4e9b1SMarcel Holtmann hdev->inq_tx_power = rp->tx_power; 856d5859e22SJohan Hedberg } 857d5859e22SJohan Hedberg 858980e1a53SJohan Hedberg static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) 859980e1a53SJohan Hedberg { 860980e1a53SJohan Hedberg struct hci_rp_pin_code_reply *rp = (void *) skb->data; 861980e1a53SJohan Hedberg struct hci_cp_pin_code_reply *cp; 862980e1a53SJohan Hedberg struct hci_conn *conn; 863980e1a53SJohan Hedberg 8649f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 865980e1a53SJohan Hedberg 86656e5cb86SJohan Hedberg hci_dev_lock(hdev); 86756e5cb86SJohan Hedberg 868d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 869744cf19eSJohan Hedberg mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); 870980e1a53SJohan Hedberg 871fa1bd918SMikel Astiz if (rp->status) 87256e5cb86SJohan Hedberg goto unlock; 873980e1a53SJohan Hedberg 874980e1a53SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); 875980e1a53SJohan Hedberg if (!cp) 87656e5cb86SJohan Hedberg goto unlock; 877980e1a53SJohan Hedberg 878980e1a53SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 879980e1a53SJohan Hedberg if (conn) 880980e1a53SJohan Hedberg conn->pin_length = cp->pin_len; 88156e5cb86SJohan Hedberg 88256e5cb86SJohan Hedberg unlock: 88356e5cb86SJohan Hedberg hci_dev_unlock(hdev); 884980e1a53SJohan Hedberg } 885980e1a53SJohan Hedberg 886980e1a53SJohan Hedberg static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) 887980e1a53SJohan Hedberg { 888980e1a53SJohan Hedberg struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data; 889980e1a53SJohan Hedberg 8909f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 891980e1a53SJohan Hedberg 89256e5cb86SJohan Hedberg hci_dev_lock(hdev); 89356e5cb86SJohan Hedberg 894d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 895744cf19eSJohan Hedberg mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, 896980e1a53SJohan Hedberg rp->status); 89756e5cb86SJohan Hedberg 89856e5cb86SJohan Hedberg hci_dev_unlock(hdev); 899980e1a53SJohan Hedberg } 90056e5cb86SJohan Hedberg 9016ed58ec5SVille Tervo static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, 9026ed58ec5SVille Tervo struct sk_buff *skb) 9036ed58ec5SVille Tervo { 9046ed58ec5SVille Tervo struct hci_rp_le_read_buffer_size *rp = (void *) skb->data; 9056ed58ec5SVille Tervo 9069f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9076ed58ec5SVille Tervo 9086ed58ec5SVille Tervo if (rp->status) 9096ed58ec5SVille Tervo return; 9106ed58ec5SVille Tervo 9116ed58ec5SVille Tervo hdev->le_mtu = __le16_to_cpu(rp->le_mtu); 9126ed58ec5SVille Tervo hdev->le_pkts = rp->le_max_pkt; 9136ed58ec5SVille Tervo 9146ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 9156ed58ec5SVille Tervo 9166ed58ec5SVille Tervo BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts); 9176ed58ec5SVille Tervo } 918980e1a53SJohan Hedberg 91960e77321SJohan Hedberg static void hci_cc_le_read_local_features(struct hci_dev *hdev, 92060e77321SJohan Hedberg struct sk_buff *skb) 92160e77321SJohan Hedberg { 92260e77321SJohan Hedberg struct hci_rp_le_read_local_features *rp = (void *) skb->data; 92360e77321SJohan Hedberg 92460e77321SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 92560e77321SJohan Hedberg 92645296acdSMarcel Holtmann if (rp->status) 92745296acdSMarcel Holtmann return; 92845296acdSMarcel Holtmann 92960e77321SJohan Hedberg memcpy(hdev->le_features, rp->features, 8); 93060e77321SJohan Hedberg } 93160e77321SJohan Hedberg 9328fa19098SJohan Hedberg static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, 9338fa19098SJohan Hedberg struct sk_buff *skb) 9348fa19098SJohan Hedberg { 9358fa19098SJohan Hedberg struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data; 9368fa19098SJohan Hedberg 9378fa19098SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9388fa19098SJohan Hedberg 93945296acdSMarcel Holtmann if (rp->status) 94045296acdSMarcel Holtmann return; 94145296acdSMarcel Holtmann 9428fa19098SJohan Hedberg hdev->adv_tx_power = rp->tx_power; 9438fa19098SJohan Hedberg } 9448fa19098SJohan Hedberg 945a5c29683SJohan Hedberg static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) 946a5c29683SJohan Hedberg { 947a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 948a5c29683SJohan Hedberg 9499f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 950a5c29683SJohan Hedberg 95156e5cb86SJohan Hedberg hci_dev_lock(hdev); 95256e5cb86SJohan Hedberg 953d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 95404124681SGustavo F. Padovan mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0, 95504124681SGustavo F. Padovan rp->status); 95656e5cb86SJohan Hedberg 95756e5cb86SJohan Hedberg hci_dev_unlock(hdev); 958a5c29683SJohan Hedberg } 959a5c29683SJohan Hedberg 960a5c29683SJohan Hedberg static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, 961a5c29683SJohan Hedberg struct sk_buff *skb) 962a5c29683SJohan Hedberg { 963a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 964a5c29683SJohan Hedberg 9659f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 966a5c29683SJohan Hedberg 96756e5cb86SJohan Hedberg hci_dev_lock(hdev); 96856e5cb86SJohan Hedberg 969d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 970744cf19eSJohan Hedberg mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, 97104124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 97256e5cb86SJohan Hedberg 97356e5cb86SJohan Hedberg hci_dev_unlock(hdev); 974a5c29683SJohan Hedberg } 975a5c29683SJohan Hedberg 9761143d458SBrian Gix static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb) 9771143d458SBrian Gix { 9781143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 9791143d458SBrian Gix 9809f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9811143d458SBrian Gix 9821143d458SBrian Gix hci_dev_lock(hdev); 9831143d458SBrian Gix 984d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 985272d90dfSJohan Hedberg mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 986272d90dfSJohan Hedberg 0, rp->status); 9871143d458SBrian Gix 9881143d458SBrian Gix hci_dev_unlock(hdev); 9891143d458SBrian Gix } 9901143d458SBrian Gix 9911143d458SBrian Gix static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, 9921143d458SBrian Gix struct sk_buff *skb) 9931143d458SBrian Gix { 9941143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 9951143d458SBrian Gix 9969f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9971143d458SBrian Gix 9981143d458SBrian Gix hci_dev_lock(hdev); 9991143d458SBrian Gix 1000d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 10011143d458SBrian Gix mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr, 100204124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 10031143d458SBrian Gix 10041143d458SBrian Gix hci_dev_unlock(hdev); 10051143d458SBrian Gix } 10061143d458SBrian Gix 10074d2d2796SMarcel Holtmann static void hci_cc_read_local_oob_data(struct hci_dev *hdev, 1008c35938b2SSzymon Janc struct sk_buff *skb) 1009c35938b2SSzymon Janc { 1010c35938b2SSzymon Janc struct hci_rp_read_local_oob_data *rp = (void *) skb->data; 1011c35938b2SSzymon Janc 10129f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 10134d2d2796SMarcel Holtmann } 10144d2d2796SMarcel Holtmann 10154d2d2796SMarcel Holtmann static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, 10164d2d2796SMarcel Holtmann struct sk_buff *skb) 10174d2d2796SMarcel Holtmann { 10184d2d2796SMarcel Holtmann struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data; 10194d2d2796SMarcel Holtmann 10204d2d2796SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 1021c35938b2SSzymon Janc } 1022c35938b2SSzymon Janc 10237a4cd51dSMarcel Holtmann static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb) 10247a4cd51dSMarcel Holtmann { 10257a4cd51dSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 10267a4cd51dSMarcel Holtmann bdaddr_t *sent; 10277a4cd51dSMarcel Holtmann 10287a4cd51dSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 10297a4cd51dSMarcel Holtmann 103045296acdSMarcel Holtmann if (status) 103145296acdSMarcel Holtmann return; 103245296acdSMarcel Holtmann 10337a4cd51dSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR); 10347a4cd51dSMarcel Holtmann if (!sent) 10357a4cd51dSMarcel Holtmann return; 10367a4cd51dSMarcel Holtmann 10377a4cd51dSMarcel Holtmann hci_dev_lock(hdev); 10387a4cd51dSMarcel Holtmann 10397a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, sent); 10407a4cd51dSMarcel Holtmann 10417a4cd51dSMarcel Holtmann hci_dev_unlock(hdev); 10427a4cd51dSMarcel Holtmann } 10437a4cd51dSMarcel Holtmann 1044c1d5dc4aSJohan Hedberg static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) 1045c1d5dc4aSJohan Hedberg { 1046c1d5dc4aSJohan Hedberg __u8 *sent, status = *((__u8 *) skb->data); 1047c1d5dc4aSJohan Hedberg 1048c1d5dc4aSJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 1049c1d5dc4aSJohan Hedberg 105045296acdSMarcel Holtmann if (status) 1051c1d5dc4aSJohan Hedberg return; 1052c1d5dc4aSJohan Hedberg 105345296acdSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE); 105445296acdSMarcel Holtmann if (!sent) 10553c857757SJohan Hedberg return; 10563c857757SJohan Hedberg 1057c1d5dc4aSJohan Hedberg hci_dev_lock(hdev); 1058c1d5dc4aSJohan Hedberg 105949c922bbSStephen Hemminger /* If we're doing connection initiation as peripheral. Set a 10603c857757SJohan Hedberg * timeout in case something goes wrong. 10613c857757SJohan Hedberg */ 10623c857757SJohan Hedberg if (*sent) { 10633c857757SJohan Hedberg struct hci_conn *conn; 10643c857757SJohan Hedberg 1065a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ADV); 106666c417c1SJohan Hedberg 1067e7d9ab73SJakub Pawlowski conn = hci_lookup_le_connect(hdev); 10683c857757SJohan Hedberg if (conn) 10693c857757SJohan Hedberg queue_delayed_work(hdev->workqueue, 10703c857757SJohan Hedberg &conn->le_conn_timeout, 107109ae260bSJohan Hedberg conn->conn_timeout); 107266c417c1SJohan Hedberg } else { 1073a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ADV); 10743c857757SJohan Hedberg } 10753c857757SJohan Hedberg 107604b4edcbSJohan Hedberg hci_dev_unlock(hdev); 1077c1d5dc4aSJohan Hedberg } 1078c1d5dc4aSJohan Hedberg 1079533553f8SMarcel Holtmann static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) 1080533553f8SMarcel Holtmann { 1081533553f8SMarcel Holtmann struct hci_cp_le_set_scan_param *cp; 1082533553f8SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 1083533553f8SMarcel Holtmann 1084533553f8SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 1085533553f8SMarcel Holtmann 108645296acdSMarcel Holtmann if (status) 108745296acdSMarcel Holtmann return; 108845296acdSMarcel Holtmann 1089533553f8SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM); 1090533553f8SMarcel Holtmann if (!cp) 1091533553f8SMarcel Holtmann return; 1092533553f8SMarcel Holtmann 1093533553f8SMarcel Holtmann hci_dev_lock(hdev); 1094533553f8SMarcel Holtmann 1095533553f8SMarcel Holtmann hdev->le_scan_type = cp->type; 1096533553f8SMarcel Holtmann 1097533553f8SMarcel Holtmann hci_dev_unlock(hdev); 1098533553f8SMarcel Holtmann } 1099533553f8SMarcel Holtmann 1100b9a6328fSJohan Hedberg static bool has_pending_adv_report(struct hci_dev *hdev) 1101b9a6328fSJohan Hedberg { 1102b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1103b9a6328fSJohan Hedberg 1104b9a6328fSJohan Hedberg return bacmp(&d->last_adv_addr, BDADDR_ANY); 1105b9a6328fSJohan Hedberg } 1106b9a6328fSJohan Hedberg 1107b9a6328fSJohan Hedberg static void clear_pending_adv_report(struct hci_dev *hdev) 1108b9a6328fSJohan Hedberg { 1109b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1110b9a6328fSJohan Hedberg 1111b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, BDADDR_ANY); 1112b9a6328fSJohan Hedberg d->last_adv_data_len = 0; 1113b9a6328fSJohan Hedberg } 1114b9a6328fSJohan Hedberg 1115b9a6328fSJohan Hedberg static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr, 1116c70a7e4cSMarcel Holtmann u8 bdaddr_type, s8 rssi, u32 flags, 1117c70a7e4cSMarcel Holtmann u8 *data, u8 len) 1118b9a6328fSJohan Hedberg { 1119b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1120b9a6328fSJohan Hedberg 1121b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, bdaddr); 1122b9a6328fSJohan Hedberg d->last_adv_addr_type = bdaddr_type; 1123ff5cd29fSJohan Hedberg d->last_adv_rssi = rssi; 1124c70a7e4cSMarcel Holtmann d->last_adv_flags = flags; 1125b9a6328fSJohan Hedberg memcpy(d->last_adv_data, data, len); 1126b9a6328fSJohan Hedberg d->last_adv_data_len = len; 1127b9a6328fSJohan Hedberg } 1128b9a6328fSJohan Hedberg 1129eb9d91f5SAndre Guedes static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, 1130eb9d91f5SAndre Guedes struct sk_buff *skb) 1131eb9d91f5SAndre Guedes { 1132eb9d91f5SAndre Guedes struct hci_cp_le_set_scan_enable *cp; 1133eb9d91f5SAndre Guedes __u8 status = *((__u8 *) skb->data); 1134eb9d91f5SAndre Guedes 11359f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1136eb9d91f5SAndre Guedes 113745296acdSMarcel Holtmann if (status) 1138eb9d91f5SAndre Guedes return; 1139eb9d91f5SAndre Guedes 114045296acdSMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE); 114145296acdSMarcel Holtmann if (!cp) 11427ba8b4beSAndre Guedes return; 11437ba8b4beSAndre Guedes 11445c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 11455c1a4c8fSJaganath Kanakkassery 11463fd319b8SAndre Guedes switch (cp->enable) { 11473fd319b8SAndre Guedes case LE_SCAN_ENABLE: 1148a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_SCAN); 1149b9a6328fSJohan Hedberg if (hdev->le_scan_type == LE_SCAN_ACTIVE) 1150b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 115168a8aea4SAndrei Emeltchenko break; 115268a8aea4SAndrei Emeltchenko 115376a388beSAndre Guedes case LE_SCAN_DISABLE: 1154b9a6328fSJohan Hedberg /* We do this here instead of when setting DISCOVERY_STOPPED 1155b9a6328fSJohan Hedberg * since the latter would potentially require waiting for 1156b9a6328fSJohan Hedberg * inquiry to stop too. 1157b9a6328fSJohan Hedberg */ 1158b9a6328fSJohan Hedberg if (has_pending_adv_report(hdev)) { 1159b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1160b9a6328fSJohan Hedberg 1161b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 1162ab0aa433SJohan Hedberg d->last_adv_addr_type, NULL, 1163c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags, 1164ab0aa433SJohan Hedberg d->last_adv_data, 1165b9a6328fSJohan Hedberg d->last_adv_data_len, NULL, 0); 1166b9a6328fSJohan Hedberg } 1167b9a6328fSJohan Hedberg 1168317ac8cbSJohan Hedberg /* Cancel this timer so that we don't try to disable scanning 1169317ac8cbSJohan Hedberg * when it's already disabled. 1170317ac8cbSJohan Hedberg */ 1171317ac8cbSJohan Hedberg cancel_delayed_work(&hdev->le_scan_disable); 1172317ac8cbSJohan Hedberg 1173a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_SCAN); 1174e8bb6b97SJohan Hedberg 117581ad6fd9SJohan Hedberg /* The HCI_LE_SCAN_INTERRUPTED flag indicates that we 117681ad6fd9SJohan Hedberg * interrupted scanning due to a connect request. Mark 1177e8bb6b97SJohan Hedberg * therefore discovery as stopped. If this was not 1178e8bb6b97SJohan Hedberg * because of a connect request advertising might have 1179e8bb6b97SJohan Hedberg * been disabled because of active scanning, so 1180e8bb6b97SJohan Hedberg * re-enable it again if necessary. 118181ad6fd9SJohan Hedberg */ 1182a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_LE_SCAN_INTERRUPTED)) 118381ad6fd9SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 1184d7a5a11dSMarcel Holtmann else if (!hci_dev_test_flag(hdev, HCI_LE_ADV) && 118534722277SJohan Hedberg hdev->discovery.state == DISCOVERY_FINDING) 1186e8bb6b97SJohan Hedberg mgmt_reenable_advertising(hdev); 1187e8bb6b97SJohan Hedberg 118868a8aea4SAndrei Emeltchenko break; 118968a8aea4SAndrei Emeltchenko 119068a8aea4SAndrei Emeltchenko default: 119168a8aea4SAndrei Emeltchenko BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable); 119268a8aea4SAndrei Emeltchenko break; 119335815085SAndre Guedes } 11945c1a4c8fSJaganath Kanakkassery 11955c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 1196eb9d91f5SAndre Guedes } 1197eb9d91f5SAndre Guedes 1198cf1d081fSJohan Hedberg static void hci_cc_le_read_white_list_size(struct hci_dev *hdev, 1199cf1d081fSJohan Hedberg struct sk_buff *skb) 1200cf1d081fSJohan Hedberg { 1201cf1d081fSJohan Hedberg struct hci_rp_le_read_white_list_size *rp = (void *) skb->data; 1202cf1d081fSJohan Hedberg 1203cf1d081fSJohan Hedberg BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size); 1204cf1d081fSJohan Hedberg 120545296acdSMarcel Holtmann if (rp->status) 120645296acdSMarcel Holtmann return; 120745296acdSMarcel Holtmann 1208cf1d081fSJohan Hedberg hdev->le_white_list_size = rp->size; 1209cf1d081fSJohan Hedberg } 1210cf1d081fSJohan Hedberg 12110f36b589SMarcel Holtmann static void hci_cc_le_clear_white_list(struct hci_dev *hdev, 12120f36b589SMarcel Holtmann struct sk_buff *skb) 12130f36b589SMarcel Holtmann { 12140f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 12150f36b589SMarcel Holtmann 12160f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 12170f36b589SMarcel Holtmann 121845296acdSMarcel Holtmann if (status) 121945296acdSMarcel Holtmann return; 122045296acdSMarcel Holtmann 1221dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->le_white_list); 12220f36b589SMarcel Holtmann } 12230f36b589SMarcel Holtmann 12240f36b589SMarcel Holtmann static void hci_cc_le_add_to_white_list(struct hci_dev *hdev, 12250f36b589SMarcel Holtmann struct sk_buff *skb) 12260f36b589SMarcel Holtmann { 12270f36b589SMarcel Holtmann struct hci_cp_le_add_to_white_list *sent; 12280f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 12290f36b589SMarcel Holtmann 12300f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 12310f36b589SMarcel Holtmann 123245296acdSMarcel Holtmann if (status) 123345296acdSMarcel Holtmann return; 123445296acdSMarcel Holtmann 12350f36b589SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST); 12360f36b589SMarcel Holtmann if (!sent) 12370f36b589SMarcel Holtmann return; 12380f36b589SMarcel Holtmann 1239dcc36c16SJohan Hedberg hci_bdaddr_list_add(&hdev->le_white_list, &sent->bdaddr, 1240dcc36c16SJohan Hedberg sent->bdaddr_type); 12410f36b589SMarcel Holtmann } 12420f36b589SMarcel Holtmann 12430f36b589SMarcel Holtmann static void hci_cc_le_del_from_white_list(struct hci_dev *hdev, 12440f36b589SMarcel Holtmann struct sk_buff *skb) 12450f36b589SMarcel Holtmann { 12460f36b589SMarcel Holtmann struct hci_cp_le_del_from_white_list *sent; 12470f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 12480f36b589SMarcel Holtmann 12490f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 12500f36b589SMarcel Holtmann 125145296acdSMarcel Holtmann if (status) 125245296acdSMarcel Holtmann return; 125345296acdSMarcel Holtmann 12540f36b589SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST); 12550f36b589SMarcel Holtmann if (!sent) 12560f36b589SMarcel Holtmann return; 12570f36b589SMarcel Holtmann 1258dcc36c16SJohan Hedberg hci_bdaddr_list_del(&hdev->le_white_list, &sent->bdaddr, 1259dcc36c16SJohan Hedberg sent->bdaddr_type); 12600f36b589SMarcel Holtmann } 12610f36b589SMarcel Holtmann 12629b008c04SJohan Hedberg static void hci_cc_le_read_supported_states(struct hci_dev *hdev, 12639b008c04SJohan Hedberg struct sk_buff *skb) 12649b008c04SJohan Hedberg { 12659b008c04SJohan Hedberg struct hci_rp_le_read_supported_states *rp = (void *) skb->data; 12669b008c04SJohan Hedberg 12679b008c04SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 12689b008c04SJohan Hedberg 126945296acdSMarcel Holtmann if (rp->status) 127045296acdSMarcel Holtmann return; 127145296acdSMarcel Holtmann 12729b008c04SJohan Hedberg memcpy(hdev->le_states, rp->le_states, 8); 12739b008c04SJohan Hedberg } 12749b008c04SJohan Hedberg 1275a8e1bfaaSMarcel Holtmann static void hci_cc_le_read_def_data_len(struct hci_dev *hdev, 1276a8e1bfaaSMarcel Holtmann struct sk_buff *skb) 1277a8e1bfaaSMarcel Holtmann { 1278a8e1bfaaSMarcel Holtmann struct hci_rp_le_read_def_data_len *rp = (void *) skb->data; 1279a8e1bfaaSMarcel Holtmann 1280a8e1bfaaSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 1281a8e1bfaaSMarcel Holtmann 1282a8e1bfaaSMarcel Holtmann if (rp->status) 1283a8e1bfaaSMarcel Holtmann return; 1284a8e1bfaaSMarcel Holtmann 1285a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = le16_to_cpu(rp->tx_len); 1286a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = le16_to_cpu(rp->tx_time); 1287a8e1bfaaSMarcel Holtmann } 1288a8e1bfaaSMarcel Holtmann 1289a8e1bfaaSMarcel Holtmann static void hci_cc_le_write_def_data_len(struct hci_dev *hdev, 1290a8e1bfaaSMarcel Holtmann struct sk_buff *skb) 1291a8e1bfaaSMarcel Holtmann { 1292a8e1bfaaSMarcel Holtmann struct hci_cp_le_write_def_data_len *sent; 1293a8e1bfaaSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 1294a8e1bfaaSMarcel Holtmann 1295a8e1bfaaSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 1296a8e1bfaaSMarcel Holtmann 1297a8e1bfaaSMarcel Holtmann if (status) 1298a8e1bfaaSMarcel Holtmann return; 1299a8e1bfaaSMarcel Holtmann 1300a8e1bfaaSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN); 1301a8e1bfaaSMarcel Holtmann if (!sent) 1302a8e1bfaaSMarcel Holtmann return; 1303a8e1bfaaSMarcel Holtmann 1304a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = le16_to_cpu(sent->tx_len); 1305a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = le16_to_cpu(sent->tx_time); 1306a8e1bfaaSMarcel Holtmann } 1307a8e1bfaaSMarcel Holtmann 1308a8e1bfaaSMarcel Holtmann static void hci_cc_le_read_max_data_len(struct hci_dev *hdev, 1309a8e1bfaaSMarcel Holtmann struct sk_buff *skb) 1310a8e1bfaaSMarcel Holtmann { 1311a8e1bfaaSMarcel Holtmann struct hci_rp_le_read_max_data_len *rp = (void *) skb->data; 1312a8e1bfaaSMarcel Holtmann 1313a8e1bfaaSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 1314a8e1bfaaSMarcel Holtmann 1315a8e1bfaaSMarcel Holtmann if (rp->status) 1316a8e1bfaaSMarcel Holtmann return; 1317a8e1bfaaSMarcel Holtmann 1318a8e1bfaaSMarcel Holtmann hdev->le_max_tx_len = le16_to_cpu(rp->tx_len); 1319a8e1bfaaSMarcel Holtmann hdev->le_max_tx_time = le16_to_cpu(rp->tx_time); 1320a8e1bfaaSMarcel Holtmann hdev->le_max_rx_len = le16_to_cpu(rp->rx_len); 1321a8e1bfaaSMarcel Holtmann hdev->le_max_rx_time = le16_to_cpu(rp->rx_time); 1322a8e1bfaaSMarcel Holtmann } 1323a8e1bfaaSMarcel Holtmann 13246039aa73SGustavo Padovan static void hci_cc_write_le_host_supported(struct hci_dev *hdev, 1325f9b49306SAndre Guedes struct sk_buff *skb) 1326f9b49306SAndre Guedes { 132706199cf8SJohan Hedberg struct hci_cp_write_le_host_supported *sent; 1328f9b49306SAndre Guedes __u8 status = *((__u8 *) skb->data); 1329f9b49306SAndre Guedes 13309f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1331f9b49306SAndre Guedes 133245296acdSMarcel Holtmann if (status) 133345296acdSMarcel Holtmann return; 133445296acdSMarcel Holtmann 133506199cf8SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED); 13368f984dfaSJohan Hedberg if (!sent) 1337f9b49306SAndre Guedes return; 1338f9b49306SAndre Guedes 13395c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 13405c1a4c8fSJaganath Kanakkassery 1341416a4ae5SJohan Hedberg if (sent->le) { 1342cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE; 1343a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ENABLED); 1344416a4ae5SJohan Hedberg } else { 1345cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE; 1346a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ENABLED); 1347a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_ADVERTISING); 1348416a4ae5SJohan Hedberg } 134953b2caabSJohan Hedberg 135053b2caabSJohan Hedberg if (sent->simul) 1351cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE_BREDR; 135253b2caabSJohan Hedberg else 1353cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE_BREDR; 13545c1a4c8fSJaganath Kanakkassery 13555c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 13568f984dfaSJohan Hedberg } 1357f9b49306SAndre Guedes 135856ed2cb8SJohan Hedberg static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb) 135956ed2cb8SJohan Hedberg { 136056ed2cb8SJohan Hedberg struct hci_cp_le_set_adv_param *cp; 136156ed2cb8SJohan Hedberg u8 status = *((u8 *) skb->data); 136256ed2cb8SJohan Hedberg 136356ed2cb8SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 136456ed2cb8SJohan Hedberg 136556ed2cb8SJohan Hedberg if (status) 136656ed2cb8SJohan Hedberg return; 136756ed2cb8SJohan Hedberg 136856ed2cb8SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM); 136956ed2cb8SJohan Hedberg if (!cp) 137056ed2cb8SJohan Hedberg return; 137156ed2cb8SJohan Hedberg 137256ed2cb8SJohan Hedberg hci_dev_lock(hdev); 137356ed2cb8SJohan Hedberg hdev->adv_addr_type = cp->own_address_type; 137456ed2cb8SJohan Hedberg hci_dev_unlock(hdev); 137556ed2cb8SJohan Hedberg } 137656ed2cb8SJohan Hedberg 13775ae76a94SAndrzej Kaczmarek static void hci_cc_read_rssi(struct hci_dev *hdev, struct sk_buff *skb) 13785ae76a94SAndrzej Kaczmarek { 13795ae76a94SAndrzej Kaczmarek struct hci_rp_read_rssi *rp = (void *) skb->data; 13805ae76a94SAndrzej Kaczmarek struct hci_conn *conn; 13815ae76a94SAndrzej Kaczmarek 13825ae76a94SAndrzej Kaczmarek BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 13835ae76a94SAndrzej Kaczmarek 13845ae76a94SAndrzej Kaczmarek if (rp->status) 13855ae76a94SAndrzej Kaczmarek return; 13865ae76a94SAndrzej Kaczmarek 13875ae76a94SAndrzej Kaczmarek hci_dev_lock(hdev); 13885ae76a94SAndrzej Kaczmarek 13895ae76a94SAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 13905ae76a94SAndrzej Kaczmarek if (conn) 13915ae76a94SAndrzej Kaczmarek conn->rssi = rp->rssi; 13925ae76a94SAndrzej Kaczmarek 13935ae76a94SAndrzej Kaczmarek hci_dev_unlock(hdev); 13945ae76a94SAndrzej Kaczmarek } 13955ae76a94SAndrzej Kaczmarek 13965a134faeSAndrzej Kaczmarek static void hci_cc_read_tx_power(struct hci_dev *hdev, struct sk_buff *skb) 13975a134faeSAndrzej Kaczmarek { 13985a134faeSAndrzej Kaczmarek struct hci_cp_read_tx_power *sent; 13995a134faeSAndrzej Kaczmarek struct hci_rp_read_tx_power *rp = (void *) skb->data; 14005a134faeSAndrzej Kaczmarek struct hci_conn *conn; 14015a134faeSAndrzej Kaczmarek 14025a134faeSAndrzej Kaczmarek BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 14035a134faeSAndrzej Kaczmarek 14045a134faeSAndrzej Kaczmarek if (rp->status) 14055a134faeSAndrzej Kaczmarek return; 14065a134faeSAndrzej Kaczmarek 14075a134faeSAndrzej Kaczmarek sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER); 14085a134faeSAndrzej Kaczmarek if (!sent) 14095a134faeSAndrzej Kaczmarek return; 14105a134faeSAndrzej Kaczmarek 14115a134faeSAndrzej Kaczmarek hci_dev_lock(hdev); 14125a134faeSAndrzej Kaczmarek 14135a134faeSAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 1414d0455ed9SAndrzej Kaczmarek if (!conn) 1415d0455ed9SAndrzej Kaczmarek goto unlock; 14165a134faeSAndrzej Kaczmarek 1417d0455ed9SAndrzej Kaczmarek switch (sent->type) { 1418d0455ed9SAndrzej Kaczmarek case 0x00: 1419d0455ed9SAndrzej Kaczmarek conn->tx_power = rp->tx_power; 1420d0455ed9SAndrzej Kaczmarek break; 1421d0455ed9SAndrzej Kaczmarek case 0x01: 1422d0455ed9SAndrzej Kaczmarek conn->max_tx_power = rp->tx_power; 1423d0455ed9SAndrzej Kaczmarek break; 1424d0455ed9SAndrzej Kaczmarek } 1425d0455ed9SAndrzej Kaczmarek 1426d0455ed9SAndrzej Kaczmarek unlock: 14275a134faeSAndrzej Kaczmarek hci_dev_unlock(hdev); 14285a134faeSAndrzej Kaczmarek } 14295a134faeSAndrzej Kaczmarek 1430c50b33c8SMarcel Holtmann static void hci_cc_write_ssp_debug_mode(struct hci_dev *hdev, struct sk_buff *skb) 1431c50b33c8SMarcel Holtmann { 1432c50b33c8SMarcel Holtmann u8 status = *((u8 *) skb->data); 1433c50b33c8SMarcel Holtmann u8 *mode; 1434c50b33c8SMarcel Holtmann 1435c50b33c8SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 1436c50b33c8SMarcel Holtmann 1437c50b33c8SMarcel Holtmann if (status) 1438c50b33c8SMarcel Holtmann return; 1439c50b33c8SMarcel Holtmann 1440c50b33c8SMarcel Holtmann mode = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE); 1441c50b33c8SMarcel Holtmann if (mode) 1442c50b33c8SMarcel Holtmann hdev->ssp_debug_mode = *mode; 1443c50b33c8SMarcel Holtmann } 1444c50b33c8SMarcel Holtmann 14456039aa73SGustavo Padovan static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) 1446a9de9248SMarcel Holtmann { 14479f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1448a9de9248SMarcel Holtmann 1449a9de9248SMarcel Holtmann if (status) { 1450a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 1451314b2381SJohan Hedberg return; 1452314b2381SJohan Hedberg } 1453314b2381SJohan Hedberg 145489352e7dSAndre Guedes set_bit(HCI_INQUIRY, &hdev->flags); 1455a9de9248SMarcel Holtmann } 1456a9de9248SMarcel Holtmann 14576039aa73SGustavo Padovan static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) 14581da177e4SLinus Torvalds { 1459a9de9248SMarcel Holtmann struct hci_cp_create_conn *cp; 14601da177e4SLinus Torvalds struct hci_conn *conn; 14611da177e4SLinus Torvalds 14629f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1463a9de9248SMarcel Holtmann 1464a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN); 14651da177e4SLinus Torvalds if (!cp) 14661da177e4SLinus Torvalds return; 14671da177e4SLinus Torvalds 14681da177e4SLinus Torvalds hci_dev_lock(hdev); 14691da177e4SLinus Torvalds 14701da177e4SLinus Torvalds conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 14711da177e4SLinus Torvalds 14726ed93dc6SAndrei Emeltchenko BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn); 14731da177e4SLinus Torvalds 14741da177e4SLinus Torvalds if (status) { 14751da177e4SLinus Torvalds if (conn && conn->state == BT_CONNECT) { 14764c67bc74SMarcel Holtmann if (status != 0x0c || conn->attempt > 2) { 14771da177e4SLinus Torvalds conn->state = BT_CLOSED; 1478539c496dSJohan Hedberg hci_connect_cfm(conn, status); 14791da177e4SLinus Torvalds hci_conn_del(conn); 14804c67bc74SMarcel Holtmann } else 14814c67bc74SMarcel Holtmann conn->state = BT_CONNECT2; 14821da177e4SLinus Torvalds } 14831da177e4SLinus Torvalds } else { 14841da177e4SLinus Torvalds if (!conn) { 1485a5c4e309SJohan Hedberg conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr, 1486a5c4e309SJohan Hedberg HCI_ROLE_MASTER); 1487a5c4e309SJohan Hedberg if (!conn) 1488893ef971SGustavo F. Padovan BT_ERR("No memory for new connection"); 14891da177e4SLinus Torvalds } 14901da177e4SLinus Torvalds } 14911da177e4SLinus Torvalds 14921da177e4SLinus Torvalds hci_dev_unlock(hdev); 14931da177e4SLinus Torvalds } 14941da177e4SLinus Torvalds 1495a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status) 14961da177e4SLinus Torvalds { 1497a9de9248SMarcel Holtmann struct hci_cp_add_sco *cp; 14981da177e4SLinus Torvalds struct hci_conn *acl, *sco; 14991da177e4SLinus Torvalds __u16 handle; 15001da177e4SLinus Torvalds 15019f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1502b6a0dc82SMarcel Holtmann 1503a9de9248SMarcel Holtmann if (!status) 1504a9de9248SMarcel Holtmann return; 1505a9de9248SMarcel Holtmann 1506a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO); 15071da177e4SLinus Torvalds if (!cp) 1508a9de9248SMarcel Holtmann return; 15091da177e4SLinus Torvalds 15101da177e4SLinus Torvalds handle = __le16_to_cpu(cp->handle); 15111da177e4SLinus Torvalds 15129f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, handle); 15131da177e4SLinus Torvalds 15141da177e4SLinus Torvalds hci_dev_lock(hdev); 15151da177e4SLinus Torvalds 15161da177e4SLinus Torvalds acl = hci_conn_hash_lookup_handle(hdev, handle); 15175a08ecceSAndrei Emeltchenko if (acl) { 15185a08ecceSAndrei Emeltchenko sco = acl->link; 15195a08ecceSAndrei Emeltchenko if (sco) { 15201da177e4SLinus Torvalds sco->state = BT_CLOSED; 15211da177e4SLinus Torvalds 1522539c496dSJohan Hedberg hci_connect_cfm(sco, status); 15231da177e4SLinus Torvalds hci_conn_del(sco); 15241da177e4SLinus Torvalds } 15255a08ecceSAndrei Emeltchenko } 15261da177e4SLinus Torvalds 15271da177e4SLinus Torvalds hci_dev_unlock(hdev); 15281da177e4SLinus Torvalds } 15291da177e4SLinus Torvalds 1530f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status) 1531f8558555SMarcel Holtmann { 1532f8558555SMarcel Holtmann struct hci_cp_auth_requested *cp; 1533f8558555SMarcel Holtmann struct hci_conn *conn; 1534f8558555SMarcel Holtmann 15359f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1536f8558555SMarcel Holtmann 1537f8558555SMarcel Holtmann if (!status) 1538f8558555SMarcel Holtmann return; 1539f8558555SMarcel Holtmann 1540f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED); 1541f8558555SMarcel Holtmann if (!cp) 1542f8558555SMarcel Holtmann return; 1543f8558555SMarcel Holtmann 1544f8558555SMarcel Holtmann hci_dev_lock(hdev); 1545f8558555SMarcel Holtmann 1546f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1547f8558555SMarcel Holtmann if (conn) { 1548f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1549539c496dSJohan Hedberg hci_connect_cfm(conn, status); 155076a68ba0SDavid Herrmann hci_conn_drop(conn); 1551f8558555SMarcel Holtmann } 1552f8558555SMarcel Holtmann } 1553f8558555SMarcel Holtmann 1554f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1555f8558555SMarcel Holtmann } 1556f8558555SMarcel Holtmann 1557f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) 1558f8558555SMarcel Holtmann { 1559f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt *cp; 1560f8558555SMarcel Holtmann struct hci_conn *conn; 1561f8558555SMarcel Holtmann 15629f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1563f8558555SMarcel Holtmann 1564f8558555SMarcel Holtmann if (!status) 1565f8558555SMarcel Holtmann return; 1566f8558555SMarcel Holtmann 1567f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT); 1568f8558555SMarcel Holtmann if (!cp) 1569f8558555SMarcel Holtmann return; 1570f8558555SMarcel Holtmann 1571f8558555SMarcel Holtmann hci_dev_lock(hdev); 1572f8558555SMarcel Holtmann 1573f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1574f8558555SMarcel Holtmann if (conn) { 1575f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1576539c496dSJohan Hedberg hci_connect_cfm(conn, status); 157776a68ba0SDavid Herrmann hci_conn_drop(conn); 1578f8558555SMarcel Holtmann } 1579f8558555SMarcel Holtmann } 1580f8558555SMarcel Holtmann 1581f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1582f8558555SMarcel Holtmann } 1583f8558555SMarcel Holtmann 1584127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev, 1585392599b9SJohan Hedberg struct hci_conn *conn) 1586392599b9SJohan Hedberg { 1587392599b9SJohan Hedberg if (conn->state != BT_CONFIG || !conn->out) 1588392599b9SJohan Hedberg return 0; 1589392599b9SJohan Hedberg 1590765c2a96SJohan Hedberg if (conn->pending_sec_level == BT_SECURITY_SDP) 1591392599b9SJohan Hedberg return 0; 1592392599b9SJohan Hedberg 1593392599b9SJohan Hedberg /* Only request authentication for SSP connections or non-SSP 1594264b8b4eSJohan Hedberg * devices with sec_level MEDIUM or HIGH or if MITM protection 1595264b8b4eSJohan Hedberg * is requested. 1596264b8b4eSJohan Hedberg */ 1597807deac2SGustavo Padovan if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) && 15987e3691e1SJohan Hedberg conn->pending_sec_level != BT_SECURITY_FIPS && 1599264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_HIGH && 1600264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_MEDIUM) 1601392599b9SJohan Hedberg return 0; 1602392599b9SJohan Hedberg 1603392599b9SJohan Hedberg return 1; 1604392599b9SJohan Hedberg } 1605392599b9SJohan Hedberg 16066039aa73SGustavo Padovan static int hci_resolve_name(struct hci_dev *hdev, 160700abfe44SGustavo F. Padovan struct inquiry_entry *e) 160830dc78e1SJohan Hedberg { 160930dc78e1SJohan Hedberg struct hci_cp_remote_name_req cp; 161030dc78e1SJohan Hedberg 161130dc78e1SJohan Hedberg memset(&cp, 0, sizeof(cp)); 161230dc78e1SJohan Hedberg 161330dc78e1SJohan Hedberg bacpy(&cp.bdaddr, &e->data.bdaddr); 161430dc78e1SJohan Hedberg cp.pscan_rep_mode = e->data.pscan_rep_mode; 161530dc78e1SJohan Hedberg cp.pscan_mode = e->data.pscan_mode; 161630dc78e1SJohan Hedberg cp.clock_offset = e->data.clock_offset; 161730dc78e1SJohan Hedberg 161830dc78e1SJohan Hedberg return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 161930dc78e1SJohan Hedberg } 162030dc78e1SJohan Hedberg 1621b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev) 162230dc78e1SJohan Hedberg { 162330dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 162430dc78e1SJohan Hedberg struct inquiry_entry *e; 162530dc78e1SJohan Hedberg 1626b644ba33SJohan Hedberg if (list_empty(&discov->resolve)) 1627b644ba33SJohan Hedberg return false; 1628b644ba33SJohan Hedberg 1629b644ba33SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 1630c810089cSRam Malovany if (!e) 1631c810089cSRam Malovany return false; 1632c810089cSRam Malovany 1633b644ba33SJohan Hedberg if (hci_resolve_name(hdev, e) == 0) { 1634b644ba33SJohan Hedberg e->name_state = NAME_PENDING; 1635b644ba33SJohan Hedberg return true; 1636b644ba33SJohan Hedberg } 1637b644ba33SJohan Hedberg 1638b644ba33SJohan Hedberg return false; 1639b644ba33SJohan Hedberg } 1640b644ba33SJohan Hedberg 1641b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, 1642b644ba33SJohan Hedberg bdaddr_t *bdaddr, u8 *name, u8 name_len) 1643b644ba33SJohan Hedberg { 1644b644ba33SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 1645b644ba33SJohan Hedberg struct inquiry_entry *e; 1646b644ba33SJohan Hedberg 164760cb49d2SJohan Hedberg /* Update the mgmt connected state if necessary. Be careful with 164860cb49d2SJohan Hedberg * conn objects that exist but are not (yet) connected however. 164960cb49d2SJohan Hedberg * Only those in BT_CONFIG or BT_CONNECTED states can be 165060cb49d2SJohan Hedberg * considered connected. 165160cb49d2SJohan Hedberg */ 165260cb49d2SJohan Hedberg if (conn && 165360cb49d2SJohan Hedberg (conn->state == BT_CONFIG || conn->state == BT_CONNECTED) && 1654cb77c3ecSJaganath Kanakkassery !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 165548ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, name, name_len); 1656b644ba33SJohan Hedberg 1657b644ba33SJohan Hedberg if (discov->state == DISCOVERY_STOPPED) 1658b644ba33SJohan Hedberg return; 1659b644ba33SJohan Hedberg 166030dc78e1SJohan Hedberg if (discov->state == DISCOVERY_STOPPING) 166130dc78e1SJohan Hedberg goto discov_complete; 166230dc78e1SJohan Hedberg 166330dc78e1SJohan Hedberg if (discov->state != DISCOVERY_RESOLVING) 166430dc78e1SJohan Hedberg return; 166530dc78e1SJohan Hedberg 166630dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING); 16677cc8380eSRam Malovany /* If the device was not found in a list of found devices names of which 16687cc8380eSRam Malovany * are pending. there is no need to continue resolving a next name as it 16697cc8380eSRam Malovany * will be done upon receiving another Remote Name Request Complete 16707cc8380eSRam Malovany * Event */ 16717cc8380eSRam Malovany if (!e) 16727cc8380eSRam Malovany return; 16737cc8380eSRam Malovany 167430dc78e1SJohan Hedberg list_del(&e->list); 16757cc8380eSRam Malovany if (name) { 16767cc8380eSRam Malovany e->name_state = NAME_KNOWN; 1677b644ba33SJohan Hedberg mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, 1678b644ba33SJohan Hedberg e->data.rssi, name, name_len); 1679c3e7c0d9SRam Malovany } else { 1680c3e7c0d9SRam Malovany e->name_state = NAME_NOT_KNOWN; 168130dc78e1SJohan Hedberg } 168230dc78e1SJohan Hedberg 1683b644ba33SJohan Hedberg if (hci_resolve_next_name(hdev)) 168430dc78e1SJohan Hedberg return; 168530dc78e1SJohan Hedberg 168630dc78e1SJohan Hedberg discov_complete: 168730dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 168830dc78e1SJohan Hedberg } 168930dc78e1SJohan Hedberg 1690a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) 16911da177e4SLinus Torvalds { 1692127178d2SJohan Hedberg struct hci_cp_remote_name_req *cp; 1693127178d2SJohan Hedberg struct hci_conn *conn; 1694127178d2SJohan Hedberg 16959f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1696127178d2SJohan Hedberg 1697127178d2SJohan Hedberg /* If successful wait for the name req complete event before 1698127178d2SJohan Hedberg * checking for the need to do authentication */ 1699127178d2SJohan Hedberg if (!status) 1700127178d2SJohan Hedberg return; 1701127178d2SJohan Hedberg 1702127178d2SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ); 1703127178d2SJohan Hedberg if (!cp) 1704127178d2SJohan Hedberg return; 1705127178d2SJohan Hedberg 1706127178d2SJohan Hedberg hci_dev_lock(hdev); 1707127178d2SJohan Hedberg 1708127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 1709b644ba33SJohan Hedberg 1710d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 1711b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0); 1712b644ba33SJohan Hedberg 171379c6c70cSJohan Hedberg if (!conn) 171479c6c70cSJohan Hedberg goto unlock; 171579c6c70cSJohan Hedberg 171679c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 171779c6c70cSJohan Hedberg goto unlock; 171879c6c70cSJohan Hedberg 171951a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 1720c1f23a2bSJohannes Berg struct hci_cp_auth_requested auth_cp; 1721c1f23a2bSJohannes Berg 1722977f8fceSJohan Hedberg set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags); 1723977f8fceSJohan Hedberg 1724c1f23a2bSJohannes Berg auth_cp.handle = __cpu_to_le16(conn->handle); 1725c1f23a2bSJohannes Berg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, 1726c1f23a2bSJohannes Berg sizeof(auth_cp), &auth_cp); 1727127178d2SJohan Hedberg } 1728127178d2SJohan Hedberg 172979c6c70cSJohan Hedberg unlock: 1730127178d2SJohan Hedberg hci_dev_unlock(hdev); 1731a9de9248SMarcel Holtmann } 17321da177e4SLinus Torvalds 1733769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) 1734769be974SMarcel Holtmann { 1735769be974SMarcel Holtmann struct hci_cp_read_remote_features *cp; 1736769be974SMarcel Holtmann struct hci_conn *conn; 1737769be974SMarcel Holtmann 17389f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1739769be974SMarcel Holtmann 1740769be974SMarcel Holtmann if (!status) 1741769be974SMarcel Holtmann return; 1742769be974SMarcel Holtmann 1743769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES); 1744769be974SMarcel Holtmann if (!cp) 1745769be974SMarcel Holtmann return; 1746769be974SMarcel Holtmann 1747769be974SMarcel Holtmann hci_dev_lock(hdev); 1748769be974SMarcel Holtmann 1749769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1750769be974SMarcel Holtmann if (conn) { 1751769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1752539c496dSJohan Hedberg hci_connect_cfm(conn, status); 175376a68ba0SDavid Herrmann hci_conn_drop(conn); 1754769be974SMarcel Holtmann } 1755769be974SMarcel Holtmann } 1756769be974SMarcel Holtmann 1757769be974SMarcel Holtmann hci_dev_unlock(hdev); 1758769be974SMarcel Holtmann } 1759769be974SMarcel Holtmann 1760769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status) 1761769be974SMarcel Holtmann { 1762769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features *cp; 1763769be974SMarcel Holtmann struct hci_conn *conn; 1764769be974SMarcel Holtmann 17659f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1766769be974SMarcel Holtmann 1767769be974SMarcel Holtmann if (!status) 1768769be974SMarcel Holtmann return; 1769769be974SMarcel Holtmann 1770769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES); 1771769be974SMarcel Holtmann if (!cp) 1772769be974SMarcel Holtmann return; 1773769be974SMarcel Holtmann 1774769be974SMarcel Holtmann hci_dev_lock(hdev); 1775769be974SMarcel Holtmann 1776769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1777769be974SMarcel Holtmann if (conn) { 1778769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1779539c496dSJohan Hedberg hci_connect_cfm(conn, status); 178076a68ba0SDavid Herrmann hci_conn_drop(conn); 1781769be974SMarcel Holtmann } 1782769be974SMarcel Holtmann } 1783769be974SMarcel Holtmann 1784769be974SMarcel Holtmann hci_dev_unlock(hdev); 1785769be974SMarcel Holtmann } 1786769be974SMarcel Holtmann 1787a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) 1788a9de9248SMarcel Holtmann { 1789b6a0dc82SMarcel Holtmann struct hci_cp_setup_sync_conn *cp; 1790b6a0dc82SMarcel Holtmann struct hci_conn *acl, *sco; 1791b6a0dc82SMarcel Holtmann __u16 handle; 1792b6a0dc82SMarcel Holtmann 17939f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1794b6a0dc82SMarcel Holtmann 1795b6a0dc82SMarcel Holtmann if (!status) 1796b6a0dc82SMarcel Holtmann return; 1797b6a0dc82SMarcel Holtmann 1798b6a0dc82SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN); 1799b6a0dc82SMarcel Holtmann if (!cp) 1800b6a0dc82SMarcel Holtmann return; 1801b6a0dc82SMarcel Holtmann 1802b6a0dc82SMarcel Holtmann handle = __le16_to_cpu(cp->handle); 1803b6a0dc82SMarcel Holtmann 18049f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, handle); 1805b6a0dc82SMarcel Holtmann 1806b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 1807b6a0dc82SMarcel Holtmann 1808b6a0dc82SMarcel Holtmann acl = hci_conn_hash_lookup_handle(hdev, handle); 18095a08ecceSAndrei Emeltchenko if (acl) { 18105a08ecceSAndrei Emeltchenko sco = acl->link; 18115a08ecceSAndrei Emeltchenko if (sco) { 1812b6a0dc82SMarcel Holtmann sco->state = BT_CLOSED; 1813b6a0dc82SMarcel Holtmann 1814539c496dSJohan Hedberg hci_connect_cfm(sco, status); 1815b6a0dc82SMarcel Holtmann hci_conn_del(sco); 1816b6a0dc82SMarcel Holtmann } 18175a08ecceSAndrei Emeltchenko } 1818b6a0dc82SMarcel Holtmann 1819b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 1820a9de9248SMarcel Holtmann } 1821a9de9248SMarcel Holtmann 1822a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) 1823a9de9248SMarcel Holtmann { 1824a9de9248SMarcel Holtmann struct hci_cp_sniff_mode *cp; 182504837f64SMarcel Holtmann struct hci_conn *conn; 182604837f64SMarcel Holtmann 18279f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1828a9de9248SMarcel Holtmann 1829a9de9248SMarcel Holtmann if (!status) 1830a9de9248SMarcel Holtmann return; 1831a9de9248SMarcel Holtmann 1832a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE); 183304837f64SMarcel Holtmann if (!cp) 1834a9de9248SMarcel Holtmann return; 183504837f64SMarcel Holtmann 183604837f64SMarcel Holtmann hci_dev_lock(hdev); 183704837f64SMarcel Holtmann 183804837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1839e73439d8SMarcel Holtmann if (conn) { 184051a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 184104837f64SMarcel Holtmann 184251a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 1843e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 1844e73439d8SMarcel Holtmann } 1845e73439d8SMarcel Holtmann 184604837f64SMarcel Holtmann hci_dev_unlock(hdev); 184704837f64SMarcel Holtmann } 184804837f64SMarcel Holtmann 1849a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) 1850a9de9248SMarcel Holtmann { 1851a9de9248SMarcel Holtmann struct hci_cp_exit_sniff_mode *cp; 185204837f64SMarcel Holtmann struct hci_conn *conn; 185304837f64SMarcel Holtmann 18549f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1855a9de9248SMarcel Holtmann 1856a9de9248SMarcel Holtmann if (!status) 1857a9de9248SMarcel Holtmann return; 1858a9de9248SMarcel Holtmann 1859a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE); 186004837f64SMarcel Holtmann if (!cp) 1861a9de9248SMarcel Holtmann return; 186204837f64SMarcel Holtmann 186304837f64SMarcel Holtmann hci_dev_lock(hdev); 186404837f64SMarcel Holtmann 186504837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1866e73439d8SMarcel Holtmann if (conn) { 186751a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 186804837f64SMarcel Holtmann 186951a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 1870e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 1871e73439d8SMarcel Holtmann } 1872e73439d8SMarcel Holtmann 187304837f64SMarcel Holtmann hci_dev_unlock(hdev); 187404837f64SMarcel Holtmann } 187504837f64SMarcel Holtmann 187688c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) 187788c3df13SJohan Hedberg { 187888c3df13SJohan Hedberg struct hci_cp_disconnect *cp; 187988c3df13SJohan Hedberg struct hci_conn *conn; 188088c3df13SJohan Hedberg 188188c3df13SJohan Hedberg if (!status) 188288c3df13SJohan Hedberg return; 188388c3df13SJohan Hedberg 188488c3df13SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT); 188588c3df13SJohan Hedberg if (!cp) 188688c3df13SJohan Hedberg return; 188788c3df13SJohan Hedberg 188888c3df13SJohan Hedberg hci_dev_lock(hdev); 188988c3df13SJohan Hedberg 189088c3df13SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 189188c3df13SJohan Hedberg if (conn) 189288c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 189388c3df13SJohan Hedberg conn->dst_type, status); 189488c3df13SJohan Hedberg 189588c3df13SJohan Hedberg hci_dev_unlock(hdev); 189688c3df13SJohan Hedberg } 189788c3df13SJohan Hedberg 1898cb1d68f7SJohan Hedberg static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status) 1899cb1d68f7SJohan Hedberg { 1900cb1d68f7SJohan Hedberg struct hci_cp_le_create_conn *cp; 1901cb1d68f7SJohan Hedberg struct hci_conn *conn; 1902cb1d68f7SJohan Hedberg 1903cb1d68f7SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 1904cb1d68f7SJohan Hedberg 1905cb1d68f7SJohan Hedberg /* All connection failure handling is taken care of by the 1906cb1d68f7SJohan Hedberg * hci_le_conn_failed function which is triggered by the HCI 1907cb1d68f7SJohan Hedberg * request completion callbacks used for connecting. 1908cb1d68f7SJohan Hedberg */ 1909cb1d68f7SJohan Hedberg if (status) 1910cb1d68f7SJohan Hedberg return; 1911cb1d68f7SJohan Hedberg 1912cb1d68f7SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN); 1913cb1d68f7SJohan Hedberg if (!cp) 1914cb1d68f7SJohan Hedberg return; 1915cb1d68f7SJohan Hedberg 1916cb1d68f7SJohan Hedberg hci_dev_lock(hdev); 1917cb1d68f7SJohan Hedberg 19189d4c1cc1SJohan Hedberg conn = hci_conn_hash_lookup_le(hdev, &cp->peer_addr, 19199d4c1cc1SJohan Hedberg cp->peer_addr_type); 1920cb1d68f7SJohan Hedberg if (!conn) 1921cb1d68f7SJohan Hedberg goto unlock; 1922cb1d68f7SJohan Hedberg 1923cb1d68f7SJohan Hedberg /* Store the initiator and responder address information which 1924cb1d68f7SJohan Hedberg * is needed for SMP. These values will not change during the 1925cb1d68f7SJohan Hedberg * lifetime of the connection. 1926cb1d68f7SJohan Hedberg */ 1927cb1d68f7SJohan Hedberg conn->init_addr_type = cp->own_address_type; 1928cb1d68f7SJohan Hedberg if (cp->own_address_type == ADDR_LE_DEV_RANDOM) 1929cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->random_addr); 1930cb1d68f7SJohan Hedberg else 1931cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->bdaddr); 1932cb1d68f7SJohan Hedberg 1933cb1d68f7SJohan Hedberg conn->resp_addr_type = cp->peer_addr_type; 1934cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &cp->peer_addr); 1935cb1d68f7SJohan Hedberg 19369489eca4SJohan Hedberg /* We don't want the connection attempt to stick around 19379489eca4SJohan Hedberg * indefinitely since LE doesn't have a page timeout concept 19389489eca4SJohan Hedberg * like BR/EDR. Set a timer for any connection that doesn't use 19399489eca4SJohan Hedberg * the white list for connecting. 19409489eca4SJohan Hedberg */ 19419489eca4SJohan Hedberg if (cp->filter_policy == HCI_LE_USE_PEER_ADDR) 19429489eca4SJohan Hedberg queue_delayed_work(conn->hdev->workqueue, 19439489eca4SJohan Hedberg &conn->le_conn_timeout, 194409ae260bSJohan Hedberg conn->conn_timeout); 19459489eca4SJohan Hedberg 1946cb1d68f7SJohan Hedberg unlock: 1947cb1d68f7SJohan Hedberg hci_dev_unlock(hdev); 1948cb1d68f7SJohan Hedberg } 1949cb1d68f7SJohan Hedberg 19500fe29fd1SMarcel Holtmann static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status) 19510fe29fd1SMarcel Holtmann { 19520fe29fd1SMarcel Holtmann struct hci_cp_le_read_remote_features *cp; 19530fe29fd1SMarcel Holtmann struct hci_conn *conn; 19540fe29fd1SMarcel Holtmann 19550fe29fd1SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 19560fe29fd1SMarcel Holtmann 19570fe29fd1SMarcel Holtmann if (!status) 19580fe29fd1SMarcel Holtmann return; 19590fe29fd1SMarcel Holtmann 19600fe29fd1SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_READ_REMOTE_FEATURES); 19610fe29fd1SMarcel Holtmann if (!cp) 19620fe29fd1SMarcel Holtmann return; 19630fe29fd1SMarcel Holtmann 19640fe29fd1SMarcel Holtmann hci_dev_lock(hdev); 19650fe29fd1SMarcel Holtmann 19660fe29fd1SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 19670fe29fd1SMarcel Holtmann if (conn) { 19680fe29fd1SMarcel Holtmann if (conn->state == BT_CONFIG) { 19690fe29fd1SMarcel Holtmann hci_connect_cfm(conn, status); 19700fe29fd1SMarcel Holtmann hci_conn_drop(conn); 19710fe29fd1SMarcel Holtmann } 19720fe29fd1SMarcel Holtmann } 19730fe29fd1SMarcel Holtmann 19740fe29fd1SMarcel Holtmann hci_dev_unlock(hdev); 19750fe29fd1SMarcel Holtmann } 19760fe29fd1SMarcel Holtmann 197781d0c8adSJohan Hedberg static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) 197881d0c8adSJohan Hedberg { 197981d0c8adSJohan Hedberg struct hci_cp_le_start_enc *cp; 198081d0c8adSJohan Hedberg struct hci_conn *conn; 198181d0c8adSJohan Hedberg 198281d0c8adSJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 198381d0c8adSJohan Hedberg 198481d0c8adSJohan Hedberg if (!status) 198581d0c8adSJohan Hedberg return; 198681d0c8adSJohan Hedberg 198781d0c8adSJohan Hedberg hci_dev_lock(hdev); 198881d0c8adSJohan Hedberg 198981d0c8adSJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC); 199081d0c8adSJohan Hedberg if (!cp) 199181d0c8adSJohan Hedberg goto unlock; 199281d0c8adSJohan Hedberg 199381d0c8adSJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 199481d0c8adSJohan Hedberg if (!conn) 199581d0c8adSJohan Hedberg goto unlock; 199681d0c8adSJohan Hedberg 199781d0c8adSJohan Hedberg if (conn->state != BT_CONNECTED) 199881d0c8adSJohan Hedberg goto unlock; 199981d0c8adSJohan Hedberg 200081d0c8adSJohan Hedberg hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 200181d0c8adSJohan Hedberg hci_conn_drop(conn); 200281d0c8adSJohan Hedberg 200381d0c8adSJohan Hedberg unlock: 200481d0c8adSJohan Hedberg hci_dev_unlock(hdev); 200581d0c8adSJohan Hedberg } 200681d0c8adSJohan Hedberg 200750fc85f1SKuba Pawlak static void hci_cs_switch_role(struct hci_dev *hdev, u8 status) 200850fc85f1SKuba Pawlak { 200950fc85f1SKuba Pawlak struct hci_cp_switch_role *cp; 201050fc85f1SKuba Pawlak struct hci_conn *conn; 201150fc85f1SKuba Pawlak 201250fc85f1SKuba Pawlak BT_DBG("%s status 0x%2.2x", hdev->name, status); 201350fc85f1SKuba Pawlak 201450fc85f1SKuba Pawlak if (!status) 201550fc85f1SKuba Pawlak return; 201650fc85f1SKuba Pawlak 201750fc85f1SKuba Pawlak cp = hci_sent_cmd_data(hdev, HCI_OP_SWITCH_ROLE); 201850fc85f1SKuba Pawlak if (!cp) 201950fc85f1SKuba Pawlak return; 202050fc85f1SKuba Pawlak 202150fc85f1SKuba Pawlak hci_dev_lock(hdev); 202250fc85f1SKuba Pawlak 202350fc85f1SKuba Pawlak conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 202450fc85f1SKuba Pawlak if (conn) 202550fc85f1SKuba Pawlak clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 202650fc85f1SKuba Pawlak 202750fc85f1SKuba Pawlak hci_dev_unlock(hdev); 202850fc85f1SKuba Pawlak } 202950fc85f1SKuba Pawlak 20306039aa73SGustavo Padovan static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 20311da177e4SLinus Torvalds { 20321da177e4SLinus Torvalds __u8 status = *((__u8 *) skb->data); 203330dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 203430dc78e1SJohan Hedberg struct inquiry_entry *e; 20351da177e4SLinus Torvalds 20369f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 20371da177e4SLinus Torvalds 2038a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 203989352e7dSAndre Guedes 204089352e7dSAndre Guedes if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) 204189352e7dSAndre Guedes return; 204289352e7dSAndre Guedes 20434e857c58SPeter Zijlstra smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */ 20443e13fa1eSAndre Guedes wake_up_bit(&hdev->flags, HCI_INQUIRY); 20453e13fa1eSAndre Guedes 2046d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 204730dc78e1SJohan Hedberg return; 204830dc78e1SJohan Hedberg 204956e5cb86SJohan Hedberg hci_dev_lock(hdev); 205030dc78e1SJohan Hedberg 2051343f935bSAndre Guedes if (discov->state != DISCOVERY_FINDING) 205230dc78e1SJohan Hedberg goto unlock; 205330dc78e1SJohan Hedberg 205430dc78e1SJohan Hedberg if (list_empty(&discov->resolve)) { 205507d2334aSJakub Pawlowski /* When BR/EDR inquiry is active and no LE scanning is in 205607d2334aSJakub Pawlowski * progress, then change discovery state to indicate completion. 205707d2334aSJakub Pawlowski * 205807d2334aSJakub Pawlowski * When running LE scanning and BR/EDR inquiry simultaneously 205907d2334aSJakub Pawlowski * and the LE scan already finished, then change the discovery 206007d2334aSJakub Pawlowski * state to indicate completion. 206107d2334aSJakub Pawlowski */ 206207d2334aSJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) || 206307d2334aSJakub Pawlowski !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks)) 2064ff9ef578SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 206530dc78e1SJohan Hedberg goto unlock; 206630dc78e1SJohan Hedberg } 206730dc78e1SJohan Hedberg 206830dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 206930dc78e1SJohan Hedberg if (e && hci_resolve_name(hdev, e) == 0) { 207030dc78e1SJohan Hedberg e->name_state = NAME_PENDING; 207130dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_RESOLVING); 207230dc78e1SJohan Hedberg } else { 207307d2334aSJakub Pawlowski /* When BR/EDR inquiry is active and no LE scanning is in 207407d2334aSJakub Pawlowski * progress, then change discovery state to indicate completion. 207507d2334aSJakub Pawlowski * 207607d2334aSJakub Pawlowski * When running LE scanning and BR/EDR inquiry simultaneously 207707d2334aSJakub Pawlowski * and the LE scan already finished, then change the discovery 207807d2334aSJakub Pawlowski * state to indicate completion. 207907d2334aSJakub Pawlowski */ 208007d2334aSJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) || 208107d2334aSJakub Pawlowski !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks)) 208230dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 208330dc78e1SJohan Hedberg } 208430dc78e1SJohan Hedberg 208530dc78e1SJohan Hedberg unlock: 208656e5cb86SJohan Hedberg hci_dev_unlock(hdev); 20871da177e4SLinus Torvalds } 20881da177e4SLinus Torvalds 20896039aa73SGustavo Padovan static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) 20901da177e4SLinus Torvalds { 209145bb4bf0SMarcel Holtmann struct inquiry_data data; 2092a9de9248SMarcel Holtmann struct inquiry_info *info = (void *) (skb->data + 1); 20931da177e4SLinus Torvalds int num_rsp = *((__u8 *) skb->data); 20941da177e4SLinus Torvalds 20951da177e4SLinus Torvalds BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 20961da177e4SLinus Torvalds 209745bb4bf0SMarcel Holtmann if (!num_rsp) 209845bb4bf0SMarcel Holtmann return; 209945bb4bf0SMarcel Holtmann 2100d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) 21011519cc17SAndre Guedes return; 21021519cc17SAndre Guedes 21031da177e4SLinus Torvalds hci_dev_lock(hdev); 210445bb4bf0SMarcel Holtmann 2105e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 2106af58925cSMarcel Holtmann u32 flags; 21073175405bSJohan Hedberg 21081da177e4SLinus Torvalds bacpy(&data.bdaddr, &info->bdaddr); 21091da177e4SLinus Torvalds data.pscan_rep_mode = info->pscan_rep_mode; 21101da177e4SLinus Torvalds data.pscan_period_mode = info->pscan_period_mode; 21111da177e4SLinus Torvalds data.pscan_mode = info->pscan_mode; 21121da177e4SLinus Torvalds memcpy(data.dev_class, info->dev_class, 3); 21131da177e4SLinus Torvalds data.clock_offset = info->clock_offset; 2114efb2513fSMarcel Holtmann data.rssi = HCI_RSSI_INVALID; 211541a96212SMarcel Holtmann data.ssp_mode = 0x00; 21163175405bSJohan Hedberg 2117af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 2118af58925cSMarcel Holtmann 211948264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 2120efb2513fSMarcel Holtmann info->dev_class, HCI_RSSI_INVALID, 2121efb2513fSMarcel Holtmann flags, NULL, 0, NULL, 0); 21221da177e4SLinus Torvalds } 212345bb4bf0SMarcel Holtmann 21241da177e4SLinus Torvalds hci_dev_unlock(hdev); 21251da177e4SLinus Torvalds } 21261da177e4SLinus Torvalds 21276039aa73SGustavo Padovan static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 21281da177e4SLinus Torvalds { 2129a9de9248SMarcel Holtmann struct hci_ev_conn_complete *ev = (void *) skb->data; 2130a9de9248SMarcel Holtmann struct hci_conn *conn; 21311da177e4SLinus Torvalds 2132a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 213345bb4bf0SMarcel Holtmann 21341da177e4SLinus Torvalds hci_dev_lock(hdev); 213545bb4bf0SMarcel Holtmann 2136a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 21379499237aSMarcel Holtmann if (!conn) { 21389499237aSMarcel Holtmann if (ev->link_type != SCO_LINK) 21399499237aSMarcel Holtmann goto unlock; 21409499237aSMarcel Holtmann 21419499237aSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 2142a9de9248SMarcel Holtmann if (!conn) 2143a9de9248SMarcel Holtmann goto unlock; 214445bb4bf0SMarcel Holtmann 21459499237aSMarcel Holtmann conn->type = SCO_LINK; 21469499237aSMarcel Holtmann } 21479499237aSMarcel Holtmann 2148a9de9248SMarcel Holtmann if (!ev->status) { 2149a9de9248SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 2150769be974SMarcel Holtmann 2151769be974SMarcel Holtmann if (conn->type == ACL_LINK) { 2152769be974SMarcel Holtmann conn->state = BT_CONFIG; 2153769be974SMarcel Holtmann hci_conn_hold(conn); 2154a9ea3ed9SSzymon Janc 2155a9ea3ed9SSzymon Janc if (!conn->out && !hci_conn_ssp_enabled(conn) && 2156a9ea3ed9SSzymon Janc !hci_find_link_key(hdev, &ev->bdaddr)) 2157a9ea3ed9SSzymon Janc conn->disc_timeout = HCI_PAIRING_TIMEOUT; 2158a9ea3ed9SSzymon Janc else 2159052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 2160769be974SMarcel Holtmann } else 2161a9de9248SMarcel Holtmann conn->state = BT_CONNECTED; 2162a9de9248SMarcel Holtmann 216323b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn); 21647d0db0a3SMarcel Holtmann hci_conn_add_sysfs(conn); 21657d0db0a3SMarcel Holtmann 2166a9de9248SMarcel Holtmann if (test_bit(HCI_AUTH, &hdev->flags)) 21674dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 2168a9de9248SMarcel Holtmann 2169a9de9248SMarcel Holtmann if (test_bit(HCI_ENCRYPT, &hdev->flags)) 21704dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags); 2171a9de9248SMarcel Holtmann 2172a9de9248SMarcel Holtmann /* Get remote features */ 2173a9de9248SMarcel Holtmann if (conn->type == ACL_LINK) { 2174a9de9248SMarcel Holtmann struct hci_cp_read_remote_features cp; 2175a9de9248SMarcel Holtmann cp.handle = ev->handle; 2176769be974SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, 2177769be974SMarcel Holtmann sizeof(cp), &cp); 217822f433dcSJohan Hedberg 21791d2dc5b7SJohan Hedberg hci_update_page_scan(hdev); 218045bb4bf0SMarcel Holtmann } 2181a9de9248SMarcel Holtmann 2182a9de9248SMarcel Holtmann /* Set packet type for incoming connection */ 2183d095c1ebSAndrei Emeltchenko if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) { 2184a9de9248SMarcel Holtmann struct hci_cp_change_conn_ptype cp; 2185a9de9248SMarcel Holtmann cp.handle = ev->handle; 2186a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 218704124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), 218804124681SGustavo F. Padovan &cp); 2189a9de9248SMarcel Holtmann } 219017d5c04cSJohan Hedberg } else { 2191a9de9248SMarcel Holtmann conn->state = BT_CLOSED; 219217d5c04cSJohan Hedberg if (conn->type == ACL_LINK) 219364c7b77cSMarcel Holtmann mgmt_connect_failed(hdev, &conn->dst, conn->type, 219448264f06SJohan Hedberg conn->dst_type, ev->status); 219517d5c04cSJohan Hedberg } 219645bb4bf0SMarcel Holtmann 2197e73439d8SMarcel Holtmann if (conn->type == ACL_LINK) 2198e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 219945bb4bf0SMarcel Holtmann 2200769be974SMarcel Holtmann if (ev->status) { 2201539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 2202a9de9248SMarcel Holtmann hci_conn_del(conn); 2203c89b6e6bSMarcel Holtmann } else if (ev->link_type != ACL_LINK) 2204539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 2205a9de9248SMarcel Holtmann 2206a9de9248SMarcel Holtmann unlock: 22071da177e4SLinus Torvalds hci_dev_unlock(hdev); 2208a9de9248SMarcel Holtmann 2209a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 22101da177e4SLinus Torvalds } 22111da177e4SLinus Torvalds 221270c46425SJohan Hedberg static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr) 221370c46425SJohan Hedberg { 221470c46425SJohan Hedberg struct hci_cp_reject_conn_req cp; 221570c46425SJohan Hedberg 221670c46425SJohan Hedberg bacpy(&cp.bdaddr, bdaddr); 221770c46425SJohan Hedberg cp.reason = HCI_ERROR_REJ_BAD_ADDR; 221870c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); 221970c46425SJohan Hedberg } 222070c46425SJohan Hedberg 22216039aa73SGustavo Padovan static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 22221da177e4SLinus Torvalds { 2223a9de9248SMarcel Holtmann struct hci_ev_conn_request *ev = (void *) skb->data; 22241da177e4SLinus Torvalds int mask = hdev->link_mode; 222570c46425SJohan Hedberg struct inquiry_entry *ie; 222670c46425SJohan Hedberg struct hci_conn *conn; 222720714bfeSFrédéric Dalleau __u8 flags = 0; 22281da177e4SLinus Torvalds 22296ed93dc6SAndrei Emeltchenko BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr, 2230807deac2SGustavo Padovan ev->link_type); 22311da177e4SLinus Torvalds 223220714bfeSFrédéric Dalleau mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type, 223320714bfeSFrédéric Dalleau &flags); 22341da177e4SLinus Torvalds 223570c46425SJohan Hedberg if (!(mask & HCI_LM_ACCEPT)) { 223670c46425SJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 223770c46425SJohan Hedberg return; 223870c46425SJohan Hedberg } 223970c46425SJohan Hedberg 2240a55bd29dSJohan Hedberg if (hci_bdaddr_list_lookup(&hdev->blacklist, &ev->bdaddr, 2241dcc36c16SJohan Hedberg BDADDR_BREDR)) { 224270c46425SJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 224370c46425SJohan Hedberg return; 224470c46425SJohan Hedberg } 224546c4c941SJohan Hedberg 22466a8fc95cSJohan Hedberg /* Require HCI_CONNECTABLE or a whitelist entry to accept the 22476a8fc95cSJohan Hedberg * connection. These features are only touched through mgmt so 22486a8fc95cSJohan Hedberg * only do the checks if HCI_MGMT is set. 22496a8fc95cSJohan Hedberg */ 2250d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT) && 2251d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONNECTABLE) && 225246c4c941SJohan Hedberg !hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr, 2253a55bd29dSJohan Hedberg BDADDR_BREDR)) { 2254a55bd29dSJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 2255a55bd29dSJohan Hedberg return; 2256a55bd29dSJohan Hedberg } 225770c46425SJohan Hedberg 22581da177e4SLinus Torvalds /* Connection accepted */ 22591da177e4SLinus Torvalds 22601da177e4SLinus Torvalds hci_dev_lock(hdev); 2261b6a0dc82SMarcel Holtmann 2262cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 2263cc11b9c1SAndrei Emeltchenko if (ie) 2264c7bdd502SMarcel Holtmann memcpy(ie->data.dev_class, ev->dev_class, 3); 2265c7bdd502SMarcel Holtmann 22668fc9ced3SGustavo Padovan conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, 22678fc9ced3SGustavo Padovan &ev->bdaddr); 22681da177e4SLinus Torvalds if (!conn) { 2269a5c4e309SJohan Hedberg conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr, 2270a5c4e309SJohan Hedberg HCI_ROLE_SLAVE); 2271cc11b9c1SAndrei Emeltchenko if (!conn) { 2272893ef971SGustavo F. Padovan BT_ERR("No memory for new connection"); 22731da177e4SLinus Torvalds hci_dev_unlock(hdev); 22741da177e4SLinus Torvalds return; 22751da177e4SLinus Torvalds } 22761da177e4SLinus Torvalds } 2277b6a0dc82SMarcel Holtmann 22781da177e4SLinus Torvalds memcpy(conn->dev_class, ev->dev_class, 3); 2279b6a0dc82SMarcel Holtmann 22801da177e4SLinus Torvalds hci_dev_unlock(hdev); 22811da177e4SLinus Torvalds 228220714bfeSFrédéric Dalleau if (ev->link_type == ACL_LINK || 228320714bfeSFrédéric Dalleau (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) { 2284b6a0dc82SMarcel Holtmann struct hci_cp_accept_conn_req cp; 228520714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 2286b6a0dc82SMarcel Holtmann 22871da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 22881da177e4SLinus Torvalds 22891da177e4SLinus Torvalds if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) 22901da177e4SLinus Torvalds cp.role = 0x00; /* Become master */ 22911da177e4SLinus Torvalds else 22921da177e4SLinus Torvalds cp.role = 0x01; /* Remain slave */ 22931da177e4SLinus Torvalds 229470c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); 229520714bfeSFrédéric Dalleau } else if (!(flags & HCI_PROTO_DEFER)) { 2296b6a0dc82SMarcel Holtmann struct hci_cp_accept_sync_conn_req cp; 229720714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 2298b6a0dc82SMarcel Holtmann 2299b6a0dc82SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 2300a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 2301b6a0dc82SMarcel Holtmann 2302dcf4adbfSJoe Perches cp.tx_bandwidth = cpu_to_le32(0x00001f40); 2303dcf4adbfSJoe Perches cp.rx_bandwidth = cpu_to_le32(0x00001f40); 2304dcf4adbfSJoe Perches cp.max_latency = cpu_to_le16(0xffff); 2305b6a0dc82SMarcel Holtmann cp.content_format = cpu_to_le16(hdev->voice_setting); 2306b6a0dc82SMarcel Holtmann cp.retrans_effort = 0xff; 2307b6a0dc82SMarcel Holtmann 230870c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp), 230970c46425SJohan Hedberg &cp); 231020714bfeSFrédéric Dalleau } else { 231120714bfeSFrédéric Dalleau conn->state = BT_CONNECT2; 2312539c496dSJohan Hedberg hci_connect_cfm(conn, 0); 2313b6a0dc82SMarcel Holtmann } 23141da177e4SLinus Torvalds } 23151da177e4SLinus Torvalds 2316f0d6a0eaSMikel Astiz static u8 hci_to_mgmt_reason(u8 err) 2317f0d6a0eaSMikel Astiz { 2318f0d6a0eaSMikel Astiz switch (err) { 2319f0d6a0eaSMikel Astiz case HCI_ERROR_CONNECTION_TIMEOUT: 2320f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_TIMEOUT; 2321f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_USER_TERM: 2322f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_LOW_RESOURCES: 2323f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_POWER_OFF: 2324f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_REMOTE; 2325f0d6a0eaSMikel Astiz case HCI_ERROR_LOCAL_HOST_TERM: 2326f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_LOCAL_HOST; 2327f0d6a0eaSMikel Astiz default: 2328f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_UNKNOWN; 2329f0d6a0eaSMikel Astiz } 2330f0d6a0eaSMikel Astiz } 2331f0d6a0eaSMikel Astiz 23326039aa73SGustavo Padovan static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 23331da177e4SLinus Torvalds { 2334a9de9248SMarcel Holtmann struct hci_ev_disconn_complete *ev = (void *) skb->data; 2335abf54a50SAndre Guedes u8 reason = hci_to_mgmt_reason(ev->reason); 23369fcb18efSAndre Guedes struct hci_conn_params *params; 233704837f64SMarcel Holtmann struct hci_conn *conn; 233812d4a3b2SJohan Hedberg bool mgmt_connected; 23393846220bSAndre Guedes u8 type; 23401da177e4SLinus Torvalds 23419f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 23421da177e4SLinus Torvalds 23431da177e4SLinus Torvalds hci_dev_lock(hdev); 23441da177e4SLinus Torvalds 234504837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2346f7520543SJohan Hedberg if (!conn) 2347f7520543SJohan Hedberg goto unlock; 2348f7520543SJohan Hedberg 2349f0d6a0eaSMikel Astiz if (ev->status) { 235088c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 235188c3df13SJohan Hedberg conn->dst_type, ev->status); 2352abf54a50SAndre Guedes goto unlock; 2353abf54a50SAndre Guedes } 2354f0d6a0eaSMikel Astiz 23553846220bSAndre Guedes conn->state = BT_CLOSED; 23563846220bSAndre Guedes 235712d4a3b2SJohan Hedberg mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags); 235812d4a3b2SJohan Hedberg mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type, 235912d4a3b2SJohan Hedberg reason, mgmt_connected); 2360f7520543SJohan Hedberg 236122f433dcSJohan Hedberg if (conn->type == ACL_LINK) { 236222f433dcSJohan Hedberg if (test_bit(HCI_CONN_FLUSH_KEY, &conn->flags)) 23636ec5bcadSVishal Agarwal hci_remove_link_key(hdev, &conn->dst); 23643846220bSAndre Guedes 23651d2dc5b7SJohan Hedberg hci_update_page_scan(hdev); 236622f433dcSJohan Hedberg } 236722f433dcSJohan Hedberg 23689fcb18efSAndre Guedes params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); 23699fcb18efSAndre Guedes if (params) { 23709fcb18efSAndre Guedes switch (params->auto_connect) { 23719fcb18efSAndre Guedes case HCI_AUTO_CONN_LINK_LOSS: 23729fcb18efSAndre Guedes if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT) 23739fcb18efSAndre Guedes break; 23749fcb18efSAndre Guedes /* Fall through */ 23759fcb18efSAndre Guedes 23764b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_DIRECT: 23779fcb18efSAndre Guedes case HCI_AUTO_CONN_ALWAYS: 2378418025d1SJohan Hedberg list_del_init(¶ms->action); 2379418025d1SJohan Hedberg list_add(¶ms->action, &hdev->pend_le_conns); 2380418025d1SJohan Hedberg hci_update_background_scan(hdev); 23819fcb18efSAndre Guedes break; 23829fcb18efSAndre Guedes 23839fcb18efSAndre Guedes default: 23849fcb18efSAndre Guedes break; 23859fcb18efSAndre Guedes } 23869fcb18efSAndre Guedes } 23879fcb18efSAndre Guedes 23883846220bSAndre Guedes type = conn->type; 23893846220bSAndre Guedes 23903a6d576bSJohan Hedberg hci_disconn_cfm(conn, ev->reason); 23911da177e4SLinus Torvalds hci_conn_del(conn); 23922210246cSJohan Hedberg 23932210246cSJohan Hedberg /* Re-enable advertising if necessary, since it might 23942210246cSJohan Hedberg * have been disabled by the connection. From the 23952210246cSJohan Hedberg * HCI_LE_Set_Advertise_Enable command description in 23962210246cSJohan Hedberg * the core specification (v4.0): 23972210246cSJohan Hedberg * "The Controller shall continue advertising until the Host 23982210246cSJohan Hedberg * issues an LE_Set_Advertise_Enable command with 23992210246cSJohan Hedberg * Advertising_Enable set to 0x00 (Advertising is disabled) 24002210246cSJohan Hedberg * or until a connection is created or until the Advertising 24012210246cSJohan Hedberg * is timed out due to Directed Advertising." 24022210246cSJohan Hedberg */ 24032210246cSJohan Hedberg if (type == LE_LINK) 24045976e608SMarcel Holtmann mgmt_reenable_advertising(hdev); 24051da177e4SLinus Torvalds 2406f7520543SJohan Hedberg unlock: 24071da177e4SLinus Torvalds hci_dev_unlock(hdev); 24081da177e4SLinus Torvalds } 24091da177e4SLinus Torvalds 24106039aa73SGustavo Padovan static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2411a9de9248SMarcel Holtmann { 2412a9de9248SMarcel Holtmann struct hci_ev_auth_complete *ev = (void *) skb->data; 2413a9de9248SMarcel Holtmann struct hci_conn *conn; 2414a9de9248SMarcel Holtmann 24159f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2416a9de9248SMarcel Holtmann 2417a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2418a9de9248SMarcel Holtmann 2419a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2420d7556e20SWaldemar Rymarkiewicz if (!conn) 2421d7556e20SWaldemar Rymarkiewicz goto unlock; 2422d7556e20SWaldemar Rymarkiewicz 2423765c2a96SJohan Hedberg if (!ev->status) { 2424aa64a8b5SJohan Hedberg if (!hci_conn_ssp_enabled(conn) && 242551a8efd7SJohan Hedberg test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { 2426d7556e20SWaldemar Rymarkiewicz BT_INFO("re-auth of legacy device is not possible."); 242719f8def0SWaldemar Rymarkiewicz } else { 24284dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 2429765c2a96SJohan Hedberg conn->sec_level = conn->pending_sec_level; 243019f8def0SWaldemar Rymarkiewicz } 24312a611692SJohan Hedberg } else { 2432e1e930f5SJohan Hedberg mgmt_auth_failed(conn, ev->status); 24332a611692SJohan Hedberg } 2434a9de9248SMarcel Holtmann 243551a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 243651a8efd7SJohan Hedberg clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags); 2437a9de9248SMarcel Holtmann 2438f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 2439aa64a8b5SJohan Hedberg if (!ev->status && hci_conn_ssp_enabled(conn)) { 2440f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 2441f8558555SMarcel Holtmann cp.handle = ev->handle; 2442f8558555SMarcel Holtmann cp.encrypt = 0x01; 2443d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 2444d7556e20SWaldemar Rymarkiewicz &cp); 2445f8558555SMarcel Holtmann } else { 2446f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 2447539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 244876a68ba0SDavid Herrmann hci_conn_drop(conn); 2449f8558555SMarcel Holtmann } 2450052b30b0SMarcel Holtmann } else { 2451a9de9248SMarcel Holtmann hci_auth_cfm(conn, ev->status); 2452a9de9248SMarcel Holtmann 2453052b30b0SMarcel Holtmann hci_conn_hold(conn); 2454052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 245576a68ba0SDavid Herrmann hci_conn_drop(conn); 2456052b30b0SMarcel Holtmann } 2457052b30b0SMarcel Holtmann 245851a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { 2459a9de9248SMarcel Holtmann if (!ev->status) { 2460a9de9248SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 2461f8558555SMarcel Holtmann cp.handle = ev->handle; 2462f8558555SMarcel Holtmann cp.encrypt = 0x01; 2463d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 2464d7556e20SWaldemar Rymarkiewicz &cp); 2465a9de9248SMarcel Holtmann } else { 246651a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 2467a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, 0x00); 2468a9de9248SMarcel Holtmann } 2469a9de9248SMarcel Holtmann } 2470a9de9248SMarcel Holtmann 2471d7556e20SWaldemar Rymarkiewicz unlock: 2472a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2473a9de9248SMarcel Holtmann } 2474a9de9248SMarcel Holtmann 24756039aa73SGustavo Padovan static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) 2476a9de9248SMarcel Holtmann { 2477127178d2SJohan Hedberg struct hci_ev_remote_name *ev = (void *) skb->data; 2478127178d2SJohan Hedberg struct hci_conn *conn; 2479127178d2SJohan Hedberg 2480a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2481a9de9248SMarcel Holtmann 2482a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 2483127178d2SJohan Hedberg 2484127178d2SJohan Hedberg hci_dev_lock(hdev); 2485127178d2SJohan Hedberg 2486127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2487b644ba33SJohan Hedberg 2488d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 2489b644ba33SJohan Hedberg goto check_auth; 2490b644ba33SJohan Hedberg 2491b644ba33SJohan Hedberg if (ev->status == 0) 2492b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name, 2493b644ba33SJohan Hedberg strnlen(ev->name, HCI_MAX_NAME_LENGTH)); 2494b644ba33SJohan Hedberg else 2495b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0); 2496b644ba33SJohan Hedberg 2497b644ba33SJohan Hedberg check_auth: 249879c6c70cSJohan Hedberg if (!conn) 249979c6c70cSJohan Hedberg goto unlock; 250079c6c70cSJohan Hedberg 250179c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 250279c6c70cSJohan Hedberg goto unlock; 250379c6c70cSJohan Hedberg 250451a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 2505127178d2SJohan Hedberg struct hci_cp_auth_requested cp; 2506977f8fceSJohan Hedberg 2507977f8fceSJohan Hedberg set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags); 2508977f8fceSJohan Hedberg 2509127178d2SJohan Hedberg cp.handle = __cpu_to_le16(conn->handle); 2510127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); 2511127178d2SJohan Hedberg } 2512127178d2SJohan Hedberg 251379c6c70cSJohan Hedberg unlock: 2514127178d2SJohan Hedberg hci_dev_unlock(hdev); 2515a9de9248SMarcel Holtmann } 2516a9de9248SMarcel Holtmann 2517821f3766SJohan Hedberg static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status, 2518821f3766SJohan Hedberg u16 opcode, struct sk_buff *skb) 2519821f3766SJohan Hedberg { 2520821f3766SJohan Hedberg const struct hci_rp_read_enc_key_size *rp; 2521821f3766SJohan Hedberg struct hci_conn *conn; 2522821f3766SJohan Hedberg u16 handle; 2523821f3766SJohan Hedberg 2524821f3766SJohan Hedberg BT_DBG("%s status 0x%02x", hdev->name, status); 2525821f3766SJohan Hedberg 2526821f3766SJohan Hedberg if (!skb || skb->len < sizeof(*rp)) { 2527821f3766SJohan Hedberg BT_ERR("%s invalid HCI Read Encryption Key Size response", 2528821f3766SJohan Hedberg hdev->name); 2529821f3766SJohan Hedberg return; 2530821f3766SJohan Hedberg } 2531821f3766SJohan Hedberg 2532821f3766SJohan Hedberg rp = (void *)skb->data; 2533821f3766SJohan Hedberg handle = le16_to_cpu(rp->handle); 2534821f3766SJohan Hedberg 2535821f3766SJohan Hedberg hci_dev_lock(hdev); 2536821f3766SJohan Hedberg 2537821f3766SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, handle); 2538821f3766SJohan Hedberg if (!conn) 2539821f3766SJohan Hedberg goto unlock; 2540821f3766SJohan Hedberg 2541821f3766SJohan Hedberg /* If we fail to read the encryption key size, assume maximum 2542821f3766SJohan Hedberg * (which is the same we do also when this HCI command isn't 2543821f3766SJohan Hedberg * supported. 2544821f3766SJohan Hedberg */ 2545821f3766SJohan Hedberg if (rp->status) { 2546821f3766SJohan Hedberg BT_ERR("%s failed to read key size for handle %u", hdev->name, 2547821f3766SJohan Hedberg handle); 2548821f3766SJohan Hedberg conn->enc_key_size = HCI_LINK_KEY_SIZE; 2549821f3766SJohan Hedberg } else { 2550821f3766SJohan Hedberg conn->enc_key_size = rp->key_size; 2551821f3766SJohan Hedberg } 2552821f3766SJohan Hedberg 2553821f3766SJohan Hedberg if (conn->state == BT_CONFIG) { 2554821f3766SJohan Hedberg conn->state = BT_CONNECTED; 2555821f3766SJohan Hedberg hci_connect_cfm(conn, 0); 2556821f3766SJohan Hedberg hci_conn_drop(conn); 2557821f3766SJohan Hedberg } else { 2558821f3766SJohan Hedberg u8 encrypt; 2559821f3766SJohan Hedberg 2560821f3766SJohan Hedberg if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags)) 2561821f3766SJohan Hedberg encrypt = 0x00; 25625d667ef6SJohan Hedberg else if (test_bit(HCI_CONN_AES_CCM, &conn->flags)) 2563821f3766SJohan Hedberg encrypt = 0x02; 2564821f3766SJohan Hedberg else 2565821f3766SJohan Hedberg encrypt = 0x01; 2566821f3766SJohan Hedberg 2567821f3766SJohan Hedberg hci_encrypt_cfm(conn, 0, encrypt); 2568821f3766SJohan Hedberg } 2569821f3766SJohan Hedberg 2570821f3766SJohan Hedberg unlock: 2571821f3766SJohan Hedberg hci_dev_unlock(hdev); 2572821f3766SJohan Hedberg } 2573821f3766SJohan Hedberg 25746039aa73SGustavo Padovan static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2575a9de9248SMarcel Holtmann { 2576a9de9248SMarcel Holtmann struct hci_ev_encrypt_change *ev = (void *) skb->data; 2577a9de9248SMarcel Holtmann struct hci_conn *conn; 2578a9de9248SMarcel Holtmann 25799f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2580a9de9248SMarcel Holtmann 2581a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2582a9de9248SMarcel Holtmann 2583a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2584dc8357ccSMarcel Holtmann if (!conn) 2585dc8357ccSMarcel Holtmann goto unlock; 2586dc8357ccSMarcel Holtmann 2587a9de9248SMarcel Holtmann if (!ev->status) { 2588ae293196SMarcel Holtmann if (ev->encrypt) { 2589ae293196SMarcel Holtmann /* Encryption implies authentication */ 25904dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 25914dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags); 2592da85e5e5SVinicius Costa Gomes conn->sec_level = conn->pending_sec_level; 2593abf76badSMarcel Holtmann 2594914a6ffeSMarcel Holtmann /* P-256 authentication key implies FIPS */ 2595914a6ffeSMarcel Holtmann if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256) 25964dae2798SJohan Hedberg set_bit(HCI_CONN_FIPS, &conn->flags); 2597914a6ffeSMarcel Holtmann 2598abf76badSMarcel Holtmann if ((conn->type == ACL_LINK && ev->encrypt == 0x02) || 2599abf76badSMarcel Holtmann conn->type == LE_LINK) 2600abf76badSMarcel Holtmann set_bit(HCI_CONN_AES_CCM, &conn->flags); 2601abf76badSMarcel Holtmann } else { 26024dae2798SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT, &conn->flags); 2603abf76badSMarcel Holtmann clear_bit(HCI_CONN_AES_CCM, &conn->flags); 2604abf76badSMarcel Holtmann } 2605a9de9248SMarcel Holtmann } 2606a9de9248SMarcel Holtmann 26077ed3fa20SJohan Hedberg /* We should disregard the current RPA and generate a new one 26087ed3fa20SJohan Hedberg * whenever the encryption procedure fails. 26097ed3fa20SJohan Hedberg */ 26107ed3fa20SJohan Hedberg if (ev->status && conn->type == LE_LINK) 2611a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); 26127ed3fa20SJohan Hedberg 261351a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 2614a9de9248SMarcel Holtmann 2615a7d7723aSGustavo Padovan if (ev->status && conn->state == BT_CONNECTED) { 2616bed71748SAndre Guedes hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 261776a68ba0SDavid Herrmann hci_conn_drop(conn); 2618a7d7723aSGustavo Padovan goto unlock; 2619a7d7723aSGustavo Padovan } 2620a7d7723aSGustavo Padovan 2621035ad621SJohan Hedberg /* In Secure Connections Only mode, do not allow any connections 2622035ad621SJohan Hedberg * that are not encrypted with AES-CCM using a P-256 authenticated 2623035ad621SJohan Hedberg * combination key. 262440b552aaSMarcel Holtmann */ 2625d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY) && 262640b552aaSMarcel Holtmann (!test_bit(HCI_CONN_AES_CCM, &conn->flags) || 262740b552aaSMarcel Holtmann conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) { 2628539c496dSJohan Hedberg hci_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE); 262940b552aaSMarcel Holtmann hci_conn_drop(conn); 263040b552aaSMarcel Holtmann goto unlock; 263140b552aaSMarcel Holtmann } 263240b552aaSMarcel Holtmann 2633821f3766SJohan Hedberg /* Try reading the encryption key size for encrypted ACL links */ 2634821f3766SJohan Hedberg if (!ev->status && ev->encrypt && conn->type == ACL_LINK) { 2635821f3766SJohan Hedberg struct hci_cp_read_enc_key_size cp; 2636821f3766SJohan Hedberg struct hci_request req; 2637821f3766SJohan Hedberg 2638821f3766SJohan Hedberg /* Only send HCI_Read_Encryption_Key_Size if the 2639821f3766SJohan Hedberg * controller really supports it. If it doesn't, assume 2640821f3766SJohan Hedberg * the default size (16). 2641821f3766SJohan Hedberg */ 2642821f3766SJohan Hedberg if (!(hdev->commands[20] & 0x10)) { 2643821f3766SJohan Hedberg conn->enc_key_size = HCI_LINK_KEY_SIZE; 2644821f3766SJohan Hedberg goto notify; 2645821f3766SJohan Hedberg } 2646821f3766SJohan Hedberg 2647821f3766SJohan Hedberg hci_req_init(&req, hdev); 2648821f3766SJohan Hedberg 2649821f3766SJohan Hedberg cp.handle = cpu_to_le16(conn->handle); 2650821f3766SJohan Hedberg hci_req_add(&req, HCI_OP_READ_ENC_KEY_SIZE, sizeof(cp), &cp); 2651821f3766SJohan Hedberg 2652821f3766SJohan Hedberg if (hci_req_run_skb(&req, read_enc_key_size_complete)) { 2653821f3766SJohan Hedberg BT_ERR("Sending HCI Read Encryption Key Size failed"); 2654821f3766SJohan Hedberg conn->enc_key_size = HCI_LINK_KEY_SIZE; 2655821f3766SJohan Hedberg goto notify; 2656821f3766SJohan Hedberg } 2657821f3766SJohan Hedberg 2658821f3766SJohan Hedberg goto unlock; 2659821f3766SJohan Hedberg } 2660821f3766SJohan Hedberg 2661821f3766SJohan Hedberg notify: 2662035ad621SJohan Hedberg if (conn->state == BT_CONFIG) { 2663035ad621SJohan Hedberg if (!ev->status) 2664035ad621SJohan Hedberg conn->state = BT_CONNECTED; 2665035ad621SJohan Hedberg 2666539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 266776a68ba0SDavid Herrmann hci_conn_drop(conn); 2668f8558555SMarcel Holtmann } else 2669a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, ev->encrypt); 2670a9de9248SMarcel Holtmann 2671a7d7723aSGustavo Padovan unlock: 2672a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2673a9de9248SMarcel Holtmann } 2674a9de9248SMarcel Holtmann 26756039aa73SGustavo Padovan static void hci_change_link_key_complete_evt(struct hci_dev *hdev, 2676807deac2SGustavo Padovan struct sk_buff *skb) 2677a9de9248SMarcel Holtmann { 2678a9de9248SMarcel Holtmann struct hci_ev_change_link_key_complete *ev = (void *) skb->data; 2679a9de9248SMarcel Holtmann struct hci_conn *conn; 2680a9de9248SMarcel Holtmann 26819f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2682a9de9248SMarcel Holtmann 2683a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2684a9de9248SMarcel Holtmann 2685a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2686a9de9248SMarcel Holtmann if (conn) { 2687a9de9248SMarcel Holtmann if (!ev->status) 26884dae2798SJohan Hedberg set_bit(HCI_CONN_SECURE, &conn->flags); 2689a9de9248SMarcel Holtmann 269051a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 2691a9de9248SMarcel Holtmann 2692a9de9248SMarcel Holtmann hci_key_change_cfm(conn, ev->status); 2693a9de9248SMarcel Holtmann } 2694a9de9248SMarcel Holtmann 2695a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2696a9de9248SMarcel Holtmann } 2697a9de9248SMarcel Holtmann 26986039aa73SGustavo Padovan static void hci_remote_features_evt(struct hci_dev *hdev, 2699807deac2SGustavo Padovan struct sk_buff *skb) 2700a9de9248SMarcel Holtmann { 2701a9de9248SMarcel Holtmann struct hci_ev_remote_features *ev = (void *) skb->data; 2702a9de9248SMarcel Holtmann struct hci_conn *conn; 2703a9de9248SMarcel Holtmann 27049f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2705a9de9248SMarcel Holtmann 2706a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2707a9de9248SMarcel Holtmann 2708a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2709ccd556feSJohan Hedberg if (!conn) 2710ccd556feSJohan Hedberg goto unlock; 2711ccd556feSJohan Hedberg 2712769be974SMarcel Holtmann if (!ev->status) 2713cad718edSJohan Hedberg memcpy(conn->features[0], ev->features, 8); 2714a9de9248SMarcel Holtmann 2715ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 2716ccd556feSJohan Hedberg goto unlock; 2717ccd556feSJohan Hedberg 2718ac363cf9SSzymon Janc if (!ev->status && lmp_ext_feat_capable(hdev) && 2719ac363cf9SSzymon Janc lmp_ext_feat_capable(conn)) { 2720769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features cp; 2721769be974SMarcel Holtmann cp.handle = ev->handle; 2722769be974SMarcel Holtmann cp.page = 0x01; 2723ccd556feSJohan Hedberg hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, 2724769be974SMarcel Holtmann sizeof(cp), &cp); 2725392599b9SJohan Hedberg goto unlock; 2726392599b9SJohan Hedberg } 2727392599b9SJohan Hedberg 2728671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 2729127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 2730127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 2731127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 2732127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 2733127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 2734b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 273548ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, NULL, 0); 2736392599b9SJohan Hedberg 2737127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 2738769be974SMarcel Holtmann conn->state = BT_CONNECTED; 2739539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 274076a68ba0SDavid Herrmann hci_conn_drop(conn); 2741769be974SMarcel Holtmann } 2742769be974SMarcel Holtmann 2743ccd556feSJohan Hedberg unlock: 2744a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2745a9de9248SMarcel Holtmann } 2746a9de9248SMarcel Holtmann 2747e6214487SJohan Hedberg static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb, 2748e6214487SJohan Hedberg u16 *opcode, u8 *status, 2749e6214487SJohan Hedberg hci_req_complete_t *req_complete, 2750e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 2751a9de9248SMarcel Holtmann { 2752a9de9248SMarcel Holtmann struct hci_ev_cmd_complete *ev = (void *) skb->data; 2753e6214487SJohan Hedberg 2754e6214487SJohan Hedberg *opcode = __le16_to_cpu(ev->opcode); 2755e6214487SJohan Hedberg *status = skb->data[sizeof(*ev)]; 2756a9de9248SMarcel Holtmann 2757a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 2758a9de9248SMarcel Holtmann 2759e6214487SJohan Hedberg switch (*opcode) { 2760a9de9248SMarcel Holtmann case HCI_OP_INQUIRY_CANCEL: 2761a9de9248SMarcel Holtmann hci_cc_inquiry_cancel(hdev, skb); 2762a9de9248SMarcel Holtmann break; 2763a9de9248SMarcel Holtmann 27644d93483bSAndre Guedes case HCI_OP_PERIODIC_INQ: 27654d93483bSAndre Guedes hci_cc_periodic_inq(hdev, skb); 27664d93483bSAndre Guedes break; 27674d93483bSAndre Guedes 2768a9de9248SMarcel Holtmann case HCI_OP_EXIT_PERIODIC_INQ: 2769a9de9248SMarcel Holtmann hci_cc_exit_periodic_inq(hdev, skb); 2770a9de9248SMarcel Holtmann break; 2771a9de9248SMarcel Holtmann 2772a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ_CANCEL: 2773a9de9248SMarcel Holtmann hci_cc_remote_name_req_cancel(hdev, skb); 2774a9de9248SMarcel Holtmann break; 2775a9de9248SMarcel Holtmann 2776a9de9248SMarcel Holtmann case HCI_OP_ROLE_DISCOVERY: 2777a9de9248SMarcel Holtmann hci_cc_role_discovery(hdev, skb); 2778a9de9248SMarcel Holtmann break; 2779a9de9248SMarcel Holtmann 2780e4e8e37cSMarcel Holtmann case HCI_OP_READ_LINK_POLICY: 2781e4e8e37cSMarcel Holtmann hci_cc_read_link_policy(hdev, skb); 2782e4e8e37cSMarcel Holtmann break; 2783e4e8e37cSMarcel Holtmann 2784a9de9248SMarcel Holtmann case HCI_OP_WRITE_LINK_POLICY: 2785a9de9248SMarcel Holtmann hci_cc_write_link_policy(hdev, skb); 2786a9de9248SMarcel Holtmann break; 2787a9de9248SMarcel Holtmann 2788e4e8e37cSMarcel Holtmann case HCI_OP_READ_DEF_LINK_POLICY: 2789e4e8e37cSMarcel Holtmann hci_cc_read_def_link_policy(hdev, skb); 2790e4e8e37cSMarcel Holtmann break; 2791e4e8e37cSMarcel Holtmann 2792e4e8e37cSMarcel Holtmann case HCI_OP_WRITE_DEF_LINK_POLICY: 2793e4e8e37cSMarcel Holtmann hci_cc_write_def_link_policy(hdev, skb); 2794e4e8e37cSMarcel Holtmann break; 2795e4e8e37cSMarcel Holtmann 2796a9de9248SMarcel Holtmann case HCI_OP_RESET: 2797a9de9248SMarcel Holtmann hci_cc_reset(hdev, skb); 2798a9de9248SMarcel Holtmann break; 2799a9de9248SMarcel Holtmann 2800c2f0f979SMarcel Holtmann case HCI_OP_READ_STORED_LINK_KEY: 2801c2f0f979SMarcel Holtmann hci_cc_read_stored_link_key(hdev, skb); 2802c2f0f979SMarcel Holtmann break; 2803c2f0f979SMarcel Holtmann 2804a9366120SMarcel Holtmann case HCI_OP_DELETE_STORED_LINK_KEY: 2805a9366120SMarcel Holtmann hci_cc_delete_stored_link_key(hdev, skb); 2806a9366120SMarcel Holtmann break; 2807a9366120SMarcel Holtmann 2808a9de9248SMarcel Holtmann case HCI_OP_WRITE_LOCAL_NAME: 2809a9de9248SMarcel Holtmann hci_cc_write_local_name(hdev, skb); 2810a9de9248SMarcel Holtmann break; 2811a9de9248SMarcel Holtmann 2812a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_NAME: 2813a9de9248SMarcel Holtmann hci_cc_read_local_name(hdev, skb); 2814a9de9248SMarcel Holtmann break; 2815a9de9248SMarcel Holtmann 2816a9de9248SMarcel Holtmann case HCI_OP_WRITE_AUTH_ENABLE: 2817a9de9248SMarcel Holtmann hci_cc_write_auth_enable(hdev, skb); 2818a9de9248SMarcel Holtmann break; 2819a9de9248SMarcel Holtmann 2820a9de9248SMarcel Holtmann case HCI_OP_WRITE_ENCRYPT_MODE: 2821a9de9248SMarcel Holtmann hci_cc_write_encrypt_mode(hdev, skb); 2822a9de9248SMarcel Holtmann break; 2823a9de9248SMarcel Holtmann 2824a9de9248SMarcel Holtmann case HCI_OP_WRITE_SCAN_ENABLE: 2825a9de9248SMarcel Holtmann hci_cc_write_scan_enable(hdev, skb); 2826a9de9248SMarcel Holtmann break; 2827a9de9248SMarcel Holtmann 2828a9de9248SMarcel Holtmann case HCI_OP_READ_CLASS_OF_DEV: 2829a9de9248SMarcel Holtmann hci_cc_read_class_of_dev(hdev, skb); 2830a9de9248SMarcel Holtmann break; 2831a9de9248SMarcel Holtmann 2832a9de9248SMarcel Holtmann case HCI_OP_WRITE_CLASS_OF_DEV: 2833a9de9248SMarcel Holtmann hci_cc_write_class_of_dev(hdev, skb); 2834a9de9248SMarcel Holtmann break; 2835a9de9248SMarcel Holtmann 2836a9de9248SMarcel Holtmann case HCI_OP_READ_VOICE_SETTING: 2837a9de9248SMarcel Holtmann hci_cc_read_voice_setting(hdev, skb); 2838a9de9248SMarcel Holtmann break; 2839a9de9248SMarcel Holtmann 2840a9de9248SMarcel Holtmann case HCI_OP_WRITE_VOICE_SETTING: 2841a9de9248SMarcel Holtmann hci_cc_write_voice_setting(hdev, skb); 2842a9de9248SMarcel Holtmann break; 2843a9de9248SMarcel Holtmann 2844b4cb9fb2SMarcel Holtmann case HCI_OP_READ_NUM_SUPPORTED_IAC: 2845b4cb9fb2SMarcel Holtmann hci_cc_read_num_supported_iac(hdev, skb); 2846b4cb9fb2SMarcel Holtmann break; 2847b4cb9fb2SMarcel Holtmann 2848333140b5SMarcel Holtmann case HCI_OP_WRITE_SSP_MODE: 2849333140b5SMarcel Holtmann hci_cc_write_ssp_mode(hdev, skb); 2850333140b5SMarcel Holtmann break; 2851333140b5SMarcel Holtmann 2852eac83dc6SMarcel Holtmann case HCI_OP_WRITE_SC_SUPPORT: 2853eac83dc6SMarcel Holtmann hci_cc_write_sc_support(hdev, skb); 2854eac83dc6SMarcel Holtmann break; 2855eac83dc6SMarcel Holtmann 2856a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_VERSION: 2857a9de9248SMarcel Holtmann hci_cc_read_local_version(hdev, skb); 2858a9de9248SMarcel Holtmann break; 2859a9de9248SMarcel Holtmann 2860a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_COMMANDS: 2861a9de9248SMarcel Holtmann hci_cc_read_local_commands(hdev, skb); 2862a9de9248SMarcel Holtmann break; 2863a9de9248SMarcel Holtmann 2864a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_FEATURES: 2865a9de9248SMarcel Holtmann hci_cc_read_local_features(hdev, skb); 2866a9de9248SMarcel Holtmann break; 2867a9de9248SMarcel Holtmann 2868971e3a4bSAndre Guedes case HCI_OP_READ_LOCAL_EXT_FEATURES: 2869971e3a4bSAndre Guedes hci_cc_read_local_ext_features(hdev, skb); 2870971e3a4bSAndre Guedes break; 2871971e3a4bSAndre Guedes 2872a9de9248SMarcel Holtmann case HCI_OP_READ_BUFFER_SIZE: 2873a9de9248SMarcel Holtmann hci_cc_read_buffer_size(hdev, skb); 2874a9de9248SMarcel Holtmann break; 2875a9de9248SMarcel Holtmann 2876a9de9248SMarcel Holtmann case HCI_OP_READ_BD_ADDR: 2877a9de9248SMarcel Holtmann hci_cc_read_bd_addr(hdev, skb); 2878a9de9248SMarcel Holtmann break; 2879a9de9248SMarcel Holtmann 2880f332ec66SJohan Hedberg case HCI_OP_READ_PAGE_SCAN_ACTIVITY: 2881f332ec66SJohan Hedberg hci_cc_read_page_scan_activity(hdev, skb); 2882f332ec66SJohan Hedberg break; 2883f332ec66SJohan Hedberg 28844a3ee763SJohan Hedberg case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY: 28854a3ee763SJohan Hedberg hci_cc_write_page_scan_activity(hdev, skb); 28864a3ee763SJohan Hedberg break; 28874a3ee763SJohan Hedberg 2888f332ec66SJohan Hedberg case HCI_OP_READ_PAGE_SCAN_TYPE: 2889f332ec66SJohan Hedberg hci_cc_read_page_scan_type(hdev, skb); 2890f332ec66SJohan Hedberg break; 2891f332ec66SJohan Hedberg 28924a3ee763SJohan Hedberg case HCI_OP_WRITE_PAGE_SCAN_TYPE: 28934a3ee763SJohan Hedberg hci_cc_write_page_scan_type(hdev, skb); 28944a3ee763SJohan Hedberg break; 28954a3ee763SJohan Hedberg 2896350ee4cfSAndrei Emeltchenko case HCI_OP_READ_DATA_BLOCK_SIZE: 2897350ee4cfSAndrei Emeltchenko hci_cc_read_data_block_size(hdev, skb); 2898350ee4cfSAndrei Emeltchenko break; 2899350ee4cfSAndrei Emeltchenko 29001e89cffbSAndrei Emeltchenko case HCI_OP_READ_FLOW_CONTROL_MODE: 29011e89cffbSAndrei Emeltchenko hci_cc_read_flow_control_mode(hdev, skb); 29021e89cffbSAndrei Emeltchenko break; 29031e89cffbSAndrei Emeltchenko 2904928abaa7SAndrei Emeltchenko case HCI_OP_READ_LOCAL_AMP_INFO: 2905928abaa7SAndrei Emeltchenko hci_cc_read_local_amp_info(hdev, skb); 2906928abaa7SAndrei Emeltchenko break; 2907928abaa7SAndrei Emeltchenko 290833f35721SJohan Hedberg case HCI_OP_READ_CLOCK: 290933f35721SJohan Hedberg hci_cc_read_clock(hdev, skb); 291033f35721SJohan Hedberg break; 291133f35721SJohan Hedberg 2912d5859e22SJohan Hedberg case HCI_OP_READ_INQ_RSP_TX_POWER: 2913d5859e22SJohan Hedberg hci_cc_read_inq_rsp_tx_power(hdev, skb); 2914d5859e22SJohan Hedberg break; 2915d5859e22SJohan Hedberg 2916980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_REPLY: 2917980e1a53SJohan Hedberg hci_cc_pin_code_reply(hdev, skb); 2918980e1a53SJohan Hedberg break; 2919980e1a53SJohan Hedberg 2920980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_NEG_REPLY: 2921980e1a53SJohan Hedberg hci_cc_pin_code_neg_reply(hdev, skb); 2922980e1a53SJohan Hedberg break; 2923980e1a53SJohan Hedberg 2924c35938b2SSzymon Janc case HCI_OP_READ_LOCAL_OOB_DATA: 29254d2d2796SMarcel Holtmann hci_cc_read_local_oob_data(hdev, skb); 29264d2d2796SMarcel Holtmann break; 29274d2d2796SMarcel Holtmann 29284d2d2796SMarcel Holtmann case HCI_OP_READ_LOCAL_OOB_EXT_DATA: 29294d2d2796SMarcel Holtmann hci_cc_read_local_oob_ext_data(hdev, skb); 2930c35938b2SSzymon Janc break; 2931c35938b2SSzymon Janc 29326ed58ec5SVille Tervo case HCI_OP_LE_READ_BUFFER_SIZE: 29336ed58ec5SVille Tervo hci_cc_le_read_buffer_size(hdev, skb); 29346ed58ec5SVille Tervo break; 29356ed58ec5SVille Tervo 293660e77321SJohan Hedberg case HCI_OP_LE_READ_LOCAL_FEATURES: 293760e77321SJohan Hedberg hci_cc_le_read_local_features(hdev, skb); 293860e77321SJohan Hedberg break; 293960e77321SJohan Hedberg 29408fa19098SJohan Hedberg case HCI_OP_LE_READ_ADV_TX_POWER: 29418fa19098SJohan Hedberg hci_cc_le_read_adv_tx_power(hdev, skb); 29428fa19098SJohan Hedberg break; 29438fa19098SJohan Hedberg 2944a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_REPLY: 2945a5c29683SJohan Hedberg hci_cc_user_confirm_reply(hdev, skb); 2946a5c29683SJohan Hedberg break; 2947a5c29683SJohan Hedberg 2948a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_NEG_REPLY: 2949a5c29683SJohan Hedberg hci_cc_user_confirm_neg_reply(hdev, skb); 2950a5c29683SJohan Hedberg break; 2951a5c29683SJohan Hedberg 29521143d458SBrian Gix case HCI_OP_USER_PASSKEY_REPLY: 29531143d458SBrian Gix hci_cc_user_passkey_reply(hdev, skb); 29541143d458SBrian Gix break; 29551143d458SBrian Gix 29561143d458SBrian Gix case HCI_OP_USER_PASSKEY_NEG_REPLY: 29571143d458SBrian Gix hci_cc_user_passkey_neg_reply(hdev, skb); 295816cde993SSzymon Janc break; 295907f7fa5dSAndre Guedes 29607a4cd51dSMarcel Holtmann case HCI_OP_LE_SET_RANDOM_ADDR: 29617a4cd51dSMarcel Holtmann hci_cc_le_set_random_addr(hdev, skb); 29627a4cd51dSMarcel Holtmann break; 29637a4cd51dSMarcel Holtmann 2964c1d5dc4aSJohan Hedberg case HCI_OP_LE_SET_ADV_ENABLE: 2965c1d5dc4aSJohan Hedberg hci_cc_le_set_adv_enable(hdev, skb); 2966c1d5dc4aSJohan Hedberg break; 2967c1d5dc4aSJohan Hedberg 2968533553f8SMarcel Holtmann case HCI_OP_LE_SET_SCAN_PARAM: 2969533553f8SMarcel Holtmann hci_cc_le_set_scan_param(hdev, skb); 2970533553f8SMarcel Holtmann break; 2971533553f8SMarcel Holtmann 2972eb9d91f5SAndre Guedes case HCI_OP_LE_SET_SCAN_ENABLE: 2973eb9d91f5SAndre Guedes hci_cc_le_set_scan_enable(hdev, skb); 2974eb9d91f5SAndre Guedes break; 2975eb9d91f5SAndre Guedes 2976cf1d081fSJohan Hedberg case HCI_OP_LE_READ_WHITE_LIST_SIZE: 2977cf1d081fSJohan Hedberg hci_cc_le_read_white_list_size(hdev, skb); 2978cf1d081fSJohan Hedberg break; 2979cf1d081fSJohan Hedberg 29800f36b589SMarcel Holtmann case HCI_OP_LE_CLEAR_WHITE_LIST: 29810f36b589SMarcel Holtmann hci_cc_le_clear_white_list(hdev, skb); 29820f36b589SMarcel Holtmann break; 29830f36b589SMarcel Holtmann 29840f36b589SMarcel Holtmann case HCI_OP_LE_ADD_TO_WHITE_LIST: 29850f36b589SMarcel Holtmann hci_cc_le_add_to_white_list(hdev, skb); 29860f36b589SMarcel Holtmann break; 29870f36b589SMarcel Holtmann 29880f36b589SMarcel Holtmann case HCI_OP_LE_DEL_FROM_WHITE_LIST: 29890f36b589SMarcel Holtmann hci_cc_le_del_from_white_list(hdev, skb); 29900f36b589SMarcel Holtmann break; 29910f36b589SMarcel Holtmann 29929b008c04SJohan Hedberg case HCI_OP_LE_READ_SUPPORTED_STATES: 29939b008c04SJohan Hedberg hci_cc_le_read_supported_states(hdev, skb); 29949b008c04SJohan Hedberg break; 29959b008c04SJohan Hedberg 2996a8e1bfaaSMarcel Holtmann case HCI_OP_LE_READ_DEF_DATA_LEN: 2997a8e1bfaaSMarcel Holtmann hci_cc_le_read_def_data_len(hdev, skb); 2998a8e1bfaaSMarcel Holtmann break; 2999a8e1bfaaSMarcel Holtmann 3000a8e1bfaaSMarcel Holtmann case HCI_OP_LE_WRITE_DEF_DATA_LEN: 3001a8e1bfaaSMarcel Holtmann hci_cc_le_write_def_data_len(hdev, skb); 3002a8e1bfaaSMarcel Holtmann break; 3003a8e1bfaaSMarcel Holtmann 3004a8e1bfaaSMarcel Holtmann case HCI_OP_LE_READ_MAX_DATA_LEN: 3005a8e1bfaaSMarcel Holtmann hci_cc_le_read_max_data_len(hdev, skb); 3006a8e1bfaaSMarcel Holtmann break; 3007a8e1bfaaSMarcel Holtmann 3008f9b49306SAndre Guedes case HCI_OP_WRITE_LE_HOST_SUPPORTED: 3009f9b49306SAndre Guedes hci_cc_write_le_host_supported(hdev, skb); 3010f9b49306SAndre Guedes break; 3011f9b49306SAndre Guedes 301256ed2cb8SJohan Hedberg case HCI_OP_LE_SET_ADV_PARAM: 301356ed2cb8SJohan Hedberg hci_cc_set_adv_param(hdev, skb); 301456ed2cb8SJohan Hedberg break; 301556ed2cb8SJohan Hedberg 30165ae76a94SAndrzej Kaczmarek case HCI_OP_READ_RSSI: 30175ae76a94SAndrzej Kaczmarek hci_cc_read_rssi(hdev, skb); 30185ae76a94SAndrzej Kaczmarek break; 30195ae76a94SAndrzej Kaczmarek 30205a134faeSAndrzej Kaczmarek case HCI_OP_READ_TX_POWER: 30215a134faeSAndrzej Kaczmarek hci_cc_read_tx_power(hdev, skb); 30225a134faeSAndrzej Kaczmarek break; 30235a134faeSAndrzej Kaczmarek 3024c50b33c8SMarcel Holtmann case HCI_OP_WRITE_SSP_DEBUG_MODE: 3025c50b33c8SMarcel Holtmann hci_cc_write_ssp_debug_mode(hdev, skb); 3026c50b33c8SMarcel Holtmann break; 3027c50b33c8SMarcel Holtmann 3028a9de9248SMarcel Holtmann default: 3029e6214487SJohan Hedberg BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode); 3030a9de9248SMarcel Holtmann break; 3031a9de9248SMarcel Holtmann } 3032a9de9248SMarcel Holtmann 3033e6214487SJohan Hedberg if (*opcode != HCI_OP_NOP) 303465cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 30356bd32326SVille Tervo 3036600b2150SJohan Hedberg if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) 3037600b2150SJohan Hedberg atomic_set(&hdev->cmd_cnt, 1); 3038600b2150SJohan Hedberg 3039e6214487SJohan Hedberg hci_req_cmd_complete(hdev, *opcode, *status, req_complete, 3040e6214487SJohan Hedberg req_complete_skb); 30419238f36aSJohan Hedberg 3042600b2150SJohan Hedberg if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q)) 3043c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 3044a9de9248SMarcel Holtmann } 3045a9de9248SMarcel Holtmann 3046e6214487SJohan Hedberg static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb, 3047e6214487SJohan Hedberg u16 *opcode, u8 *status, 3048e6214487SJohan Hedberg hci_req_complete_t *req_complete, 3049e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 3050a9de9248SMarcel Holtmann { 3051a9de9248SMarcel Holtmann struct hci_ev_cmd_status *ev = (void *) skb->data; 3052a9de9248SMarcel Holtmann 3053a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 3054a9de9248SMarcel Holtmann 3055e6214487SJohan Hedberg *opcode = __le16_to_cpu(ev->opcode); 3056e6214487SJohan Hedberg *status = ev->status; 3057a9de9248SMarcel Holtmann 3058e6214487SJohan Hedberg switch (*opcode) { 3059a9de9248SMarcel Holtmann case HCI_OP_INQUIRY: 3060a9de9248SMarcel Holtmann hci_cs_inquiry(hdev, ev->status); 3061a9de9248SMarcel Holtmann break; 3062a9de9248SMarcel Holtmann 3063a9de9248SMarcel Holtmann case HCI_OP_CREATE_CONN: 3064a9de9248SMarcel Holtmann hci_cs_create_conn(hdev, ev->status); 3065a9de9248SMarcel Holtmann break; 3066a9de9248SMarcel Holtmann 30679645c76cSKuba Pawlak case HCI_OP_DISCONNECT: 30689645c76cSKuba Pawlak hci_cs_disconnect(hdev, ev->status); 30699645c76cSKuba Pawlak break; 30709645c76cSKuba Pawlak 3071a9de9248SMarcel Holtmann case HCI_OP_ADD_SCO: 3072a9de9248SMarcel Holtmann hci_cs_add_sco(hdev, ev->status); 3073a9de9248SMarcel Holtmann break; 3074a9de9248SMarcel Holtmann 3075f8558555SMarcel Holtmann case HCI_OP_AUTH_REQUESTED: 3076f8558555SMarcel Holtmann hci_cs_auth_requested(hdev, ev->status); 3077f8558555SMarcel Holtmann break; 3078f8558555SMarcel Holtmann 3079f8558555SMarcel Holtmann case HCI_OP_SET_CONN_ENCRYPT: 3080f8558555SMarcel Holtmann hci_cs_set_conn_encrypt(hdev, ev->status); 3081f8558555SMarcel Holtmann break; 3082f8558555SMarcel Holtmann 3083a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ: 3084a9de9248SMarcel Holtmann hci_cs_remote_name_req(hdev, ev->status); 3085a9de9248SMarcel Holtmann break; 3086a9de9248SMarcel Holtmann 3087769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_FEATURES: 3088769be974SMarcel Holtmann hci_cs_read_remote_features(hdev, ev->status); 3089769be974SMarcel Holtmann break; 3090769be974SMarcel Holtmann 3091769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_EXT_FEATURES: 3092769be974SMarcel Holtmann hci_cs_read_remote_ext_features(hdev, ev->status); 3093769be974SMarcel Holtmann break; 3094769be974SMarcel Holtmann 3095a9de9248SMarcel Holtmann case HCI_OP_SETUP_SYNC_CONN: 3096a9de9248SMarcel Holtmann hci_cs_setup_sync_conn(hdev, ev->status); 3097a9de9248SMarcel Holtmann break; 3098a9de9248SMarcel Holtmann 3099a9de9248SMarcel Holtmann case HCI_OP_SNIFF_MODE: 3100a9de9248SMarcel Holtmann hci_cs_sniff_mode(hdev, ev->status); 3101a9de9248SMarcel Holtmann break; 3102a9de9248SMarcel Holtmann 3103a9de9248SMarcel Holtmann case HCI_OP_EXIT_SNIFF_MODE: 3104a9de9248SMarcel Holtmann hci_cs_exit_sniff_mode(hdev, ev->status); 3105a9de9248SMarcel Holtmann break; 3106a9de9248SMarcel Holtmann 310750fc85f1SKuba Pawlak case HCI_OP_SWITCH_ROLE: 310850fc85f1SKuba Pawlak hci_cs_switch_role(hdev, ev->status); 310950fc85f1SKuba Pawlak break; 311050fc85f1SKuba Pawlak 3111cb1d68f7SJohan Hedberg case HCI_OP_LE_CREATE_CONN: 3112cb1d68f7SJohan Hedberg hci_cs_le_create_conn(hdev, ev->status); 3113cb1d68f7SJohan Hedberg break; 3114cb1d68f7SJohan Hedberg 31150fe29fd1SMarcel Holtmann case HCI_OP_LE_READ_REMOTE_FEATURES: 31160fe29fd1SMarcel Holtmann hci_cs_le_read_remote_features(hdev, ev->status); 31170fe29fd1SMarcel Holtmann break; 31180fe29fd1SMarcel Holtmann 311981d0c8adSJohan Hedberg case HCI_OP_LE_START_ENC: 312081d0c8adSJohan Hedberg hci_cs_le_start_enc(hdev, ev->status); 312181d0c8adSJohan Hedberg break; 312281d0c8adSJohan Hedberg 3123a9de9248SMarcel Holtmann default: 3124e6214487SJohan Hedberg BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode); 3125a9de9248SMarcel Holtmann break; 3126a9de9248SMarcel Holtmann } 3127a9de9248SMarcel Holtmann 3128e6214487SJohan Hedberg if (*opcode != HCI_OP_NOP) 312965cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 31306bd32326SVille Tervo 3131600b2150SJohan Hedberg if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) 3132600b2150SJohan Hedberg atomic_set(&hdev->cmd_cnt, 1); 3133600b2150SJohan Hedberg 3134444c6dd5SJohan Hedberg /* Indicate request completion if the command failed. Also, if 3135444c6dd5SJohan Hedberg * we're not waiting for a special event and we get a success 3136444c6dd5SJohan Hedberg * command status we should try to flag the request as completed 3137444c6dd5SJohan Hedberg * (since for this kind of commands there will not be a command 3138444c6dd5SJohan Hedberg * complete event). 3139444c6dd5SJohan Hedberg */ 314002350a72SJohan Hedberg if (ev->status || 3141db6e3e8dSJohan Hedberg (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event)) 3142e6214487SJohan Hedberg hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete, 3143e6214487SJohan Hedberg req_complete_skb); 31449238f36aSJohan Hedberg 3145600b2150SJohan Hedberg if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q)) 3146c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 3147a9de9248SMarcel Holtmann } 3148a9de9248SMarcel Holtmann 314924dfa343SMarcel Holtmann static void hci_hardware_error_evt(struct hci_dev *hdev, struct sk_buff *skb) 315024dfa343SMarcel Holtmann { 315124dfa343SMarcel Holtmann struct hci_ev_hardware_error *ev = (void *) skb->data; 315224dfa343SMarcel Holtmann 3153c7741d16SMarcel Holtmann hdev->hw_error_code = ev->code; 3154c7741d16SMarcel Holtmann 3155c7741d16SMarcel Holtmann queue_work(hdev->req_workqueue, &hdev->error_reset); 315624dfa343SMarcel Holtmann } 315724dfa343SMarcel Holtmann 31586039aa73SGustavo Padovan static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 3159a9de9248SMarcel Holtmann { 3160a9de9248SMarcel Holtmann struct hci_ev_role_change *ev = (void *) skb->data; 3161a9de9248SMarcel Holtmann struct hci_conn *conn; 3162a9de9248SMarcel Holtmann 31639f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3164a9de9248SMarcel Holtmann 3165a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3166a9de9248SMarcel Holtmann 3167a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 3168a9de9248SMarcel Holtmann if (conn) { 316940bef302SJohan Hedberg if (!ev->status) 317040bef302SJohan Hedberg conn->role = ev->role; 3171a9de9248SMarcel Holtmann 317251a8efd7SJohan Hedberg clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 3173a9de9248SMarcel Holtmann 3174a9de9248SMarcel Holtmann hci_role_switch_cfm(conn, ev->status, ev->role); 3175a9de9248SMarcel Holtmann } 3176a9de9248SMarcel Holtmann 3177a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3178a9de9248SMarcel Holtmann } 3179a9de9248SMarcel Holtmann 31806039aa73SGustavo Padovan static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) 31811da177e4SLinus Torvalds { 3182a9de9248SMarcel Holtmann struct hci_ev_num_comp_pkts *ev = (void *) skb->data; 31831da177e4SLinus Torvalds int i; 31841da177e4SLinus Torvalds 318532ac5b9bSAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) { 318632ac5b9bSAndrei Emeltchenko BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); 318732ac5b9bSAndrei Emeltchenko return; 318832ac5b9bSAndrei Emeltchenko } 318932ac5b9bSAndrei Emeltchenko 3190c5993de8SAndrei Emeltchenko if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + 3191c5993de8SAndrei Emeltchenko ev->num_hndl * sizeof(struct hci_comp_pkts_info)) { 31921da177e4SLinus Torvalds BT_DBG("%s bad parameters", hdev->name); 31931da177e4SLinus Torvalds return; 31941da177e4SLinus Torvalds } 31951da177e4SLinus Torvalds 3196c5993de8SAndrei Emeltchenko BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl); 3197c5993de8SAndrei Emeltchenko 3198613a1c0cSAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 3199613a1c0cSAndrei Emeltchenko struct hci_comp_pkts_info *info = &ev->handles[i]; 32001da177e4SLinus Torvalds struct hci_conn *conn; 32011da177e4SLinus Torvalds __u16 handle, count; 32021da177e4SLinus Torvalds 3203613a1c0cSAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 3204613a1c0cSAndrei Emeltchenko count = __le16_to_cpu(info->count); 32051da177e4SLinus Torvalds 32061da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 3207f4280918SAndrei Emeltchenko if (!conn) 3208f4280918SAndrei Emeltchenko continue; 3209f4280918SAndrei Emeltchenko 32101da177e4SLinus Torvalds conn->sent -= count; 32111da177e4SLinus Torvalds 3212f4280918SAndrei Emeltchenko switch (conn->type) { 3213f4280918SAndrei Emeltchenko case ACL_LINK: 321470f23020SAndrei Emeltchenko hdev->acl_cnt += count; 321570f23020SAndrei Emeltchenko if (hdev->acl_cnt > hdev->acl_pkts) 32161da177e4SLinus Torvalds hdev->acl_cnt = hdev->acl_pkts; 3217f4280918SAndrei Emeltchenko break; 3218f4280918SAndrei Emeltchenko 3219f4280918SAndrei Emeltchenko case LE_LINK: 32206ed58ec5SVille Tervo if (hdev->le_pkts) { 32216ed58ec5SVille Tervo hdev->le_cnt += count; 32226ed58ec5SVille Tervo if (hdev->le_cnt > hdev->le_pkts) 32236ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 32246ed58ec5SVille Tervo } else { 32256ed58ec5SVille Tervo hdev->acl_cnt += count; 32266ed58ec5SVille Tervo if (hdev->acl_cnt > hdev->acl_pkts) 32276ed58ec5SVille Tervo hdev->acl_cnt = hdev->acl_pkts; 32286ed58ec5SVille Tervo } 3229f4280918SAndrei Emeltchenko break; 3230f4280918SAndrei Emeltchenko 3231f4280918SAndrei Emeltchenko case SCO_LINK: 323270f23020SAndrei Emeltchenko hdev->sco_cnt += count; 323370f23020SAndrei Emeltchenko if (hdev->sco_cnt > hdev->sco_pkts) 32345b7f9909SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 3235f4280918SAndrei Emeltchenko break; 3236f4280918SAndrei Emeltchenko 3237f4280918SAndrei Emeltchenko default: 3238f4280918SAndrei Emeltchenko BT_ERR("Unknown type %d conn %p", conn->type, conn); 3239f4280918SAndrei Emeltchenko break; 32401da177e4SLinus Torvalds } 32411da177e4SLinus Torvalds } 3242a9de9248SMarcel Holtmann 32433eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 32441da177e4SLinus Torvalds } 32451da177e4SLinus Torvalds 324676ef7cf7SAndrei Emeltchenko static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev, 324776ef7cf7SAndrei Emeltchenko __u16 handle) 324876ef7cf7SAndrei Emeltchenko { 324976ef7cf7SAndrei Emeltchenko struct hci_chan *chan; 325076ef7cf7SAndrei Emeltchenko 325176ef7cf7SAndrei Emeltchenko switch (hdev->dev_type) { 325276ef7cf7SAndrei Emeltchenko case HCI_BREDR: 325376ef7cf7SAndrei Emeltchenko return hci_conn_hash_lookup_handle(hdev, handle); 325476ef7cf7SAndrei Emeltchenko case HCI_AMP: 325576ef7cf7SAndrei Emeltchenko chan = hci_chan_lookup_handle(hdev, handle); 325676ef7cf7SAndrei Emeltchenko if (chan) 325776ef7cf7SAndrei Emeltchenko return chan->conn; 325876ef7cf7SAndrei Emeltchenko break; 325976ef7cf7SAndrei Emeltchenko default: 326076ef7cf7SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 326176ef7cf7SAndrei Emeltchenko break; 326276ef7cf7SAndrei Emeltchenko } 326376ef7cf7SAndrei Emeltchenko 326476ef7cf7SAndrei Emeltchenko return NULL; 326576ef7cf7SAndrei Emeltchenko } 326676ef7cf7SAndrei Emeltchenko 32676039aa73SGustavo Padovan static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) 326825e89e99SAndrei Emeltchenko { 326925e89e99SAndrei Emeltchenko struct hci_ev_num_comp_blocks *ev = (void *) skb->data; 327025e89e99SAndrei Emeltchenko int i; 327125e89e99SAndrei Emeltchenko 327225e89e99SAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) { 327325e89e99SAndrei Emeltchenko BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); 327425e89e99SAndrei Emeltchenko return; 327525e89e99SAndrei Emeltchenko } 327625e89e99SAndrei Emeltchenko 327725e89e99SAndrei Emeltchenko if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + 327825e89e99SAndrei Emeltchenko ev->num_hndl * sizeof(struct hci_comp_blocks_info)) { 327925e89e99SAndrei Emeltchenko BT_DBG("%s bad parameters", hdev->name); 328025e89e99SAndrei Emeltchenko return; 328125e89e99SAndrei Emeltchenko } 328225e89e99SAndrei Emeltchenko 328325e89e99SAndrei Emeltchenko BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks, 328425e89e99SAndrei Emeltchenko ev->num_hndl); 328525e89e99SAndrei Emeltchenko 328625e89e99SAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 328725e89e99SAndrei Emeltchenko struct hci_comp_blocks_info *info = &ev->handles[i]; 328876ef7cf7SAndrei Emeltchenko struct hci_conn *conn = NULL; 328925e89e99SAndrei Emeltchenko __u16 handle, block_count; 329025e89e99SAndrei Emeltchenko 329125e89e99SAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 329225e89e99SAndrei Emeltchenko block_count = __le16_to_cpu(info->blocks); 329325e89e99SAndrei Emeltchenko 329476ef7cf7SAndrei Emeltchenko conn = __hci_conn_lookup_handle(hdev, handle); 329525e89e99SAndrei Emeltchenko if (!conn) 329625e89e99SAndrei Emeltchenko continue; 329725e89e99SAndrei Emeltchenko 329825e89e99SAndrei Emeltchenko conn->sent -= block_count; 329925e89e99SAndrei Emeltchenko 330025e89e99SAndrei Emeltchenko switch (conn->type) { 330125e89e99SAndrei Emeltchenko case ACL_LINK: 3302bd1eb66bSAndrei Emeltchenko case AMP_LINK: 330325e89e99SAndrei Emeltchenko hdev->block_cnt += block_count; 330425e89e99SAndrei Emeltchenko if (hdev->block_cnt > hdev->num_blocks) 330525e89e99SAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 330625e89e99SAndrei Emeltchenko break; 330725e89e99SAndrei Emeltchenko 330825e89e99SAndrei Emeltchenko default: 330925e89e99SAndrei Emeltchenko BT_ERR("Unknown type %d conn %p", conn->type, conn); 331025e89e99SAndrei Emeltchenko break; 331125e89e99SAndrei Emeltchenko } 331225e89e99SAndrei Emeltchenko } 331325e89e99SAndrei Emeltchenko 331425e89e99SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->tx_work); 331525e89e99SAndrei Emeltchenko } 331625e89e99SAndrei Emeltchenko 33176039aa73SGustavo Padovan static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 33181da177e4SLinus Torvalds { 3319a9de9248SMarcel Holtmann struct hci_ev_mode_change *ev = (void *) skb->data; 332004837f64SMarcel Holtmann struct hci_conn *conn; 33211da177e4SLinus Torvalds 33229f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 33231da177e4SLinus Torvalds 33241da177e4SLinus Torvalds hci_dev_lock(hdev); 33251da177e4SLinus Torvalds 332604837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 332704837f64SMarcel Holtmann if (conn) { 332804837f64SMarcel Holtmann conn->mode = ev->mode; 332904837f64SMarcel Holtmann 33308fc9ced3SGustavo Padovan if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, 33318fc9ced3SGustavo Padovan &conn->flags)) { 333204837f64SMarcel Holtmann if (conn->mode == HCI_CM_ACTIVE) 333358a681efSJohan Hedberg set_bit(HCI_CONN_POWER_SAVE, &conn->flags); 333404837f64SMarcel Holtmann else 333558a681efSJohan Hedberg clear_bit(HCI_CONN_POWER_SAVE, &conn->flags); 333604837f64SMarcel Holtmann } 3337e73439d8SMarcel Holtmann 333851a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 3339e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 334004837f64SMarcel Holtmann } 334104837f64SMarcel Holtmann 334204837f64SMarcel Holtmann hci_dev_unlock(hdev); 334304837f64SMarcel Holtmann } 334404837f64SMarcel Holtmann 33456039aa73SGustavo Padovan static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 33461da177e4SLinus Torvalds { 3347052b30b0SMarcel Holtmann struct hci_ev_pin_code_req *ev = (void *) skb->data; 3348052b30b0SMarcel Holtmann struct hci_conn *conn; 3349052b30b0SMarcel Holtmann 3350a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 3351052b30b0SMarcel Holtmann 3352052b30b0SMarcel Holtmann hci_dev_lock(hdev); 3353052b30b0SMarcel Holtmann 3354052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 3355b6f98044SWaldemar Rymarkiewicz if (!conn) 3356b6f98044SWaldemar Rymarkiewicz goto unlock; 3357b6f98044SWaldemar Rymarkiewicz 3358b6f98044SWaldemar Rymarkiewicz if (conn->state == BT_CONNECTED) { 3359052b30b0SMarcel Holtmann hci_conn_hold(conn); 3360052b30b0SMarcel Holtmann conn->disc_timeout = HCI_PAIRING_TIMEOUT; 336176a68ba0SDavid Herrmann hci_conn_drop(conn); 3362052b30b0SMarcel Holtmann } 3363052b30b0SMarcel Holtmann 3364d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE) && 33652f407f0aSJohan Hedberg !test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags)) { 336603b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, 336703b555e1SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 3368d7a5a11dSMarcel Holtmann } else if (hci_dev_test_flag(hdev, HCI_MGMT)) { 3369a770bb5aSWaldemar Rymarkiewicz u8 secure; 3370a770bb5aSWaldemar Rymarkiewicz 3371a770bb5aSWaldemar Rymarkiewicz if (conn->pending_sec_level == BT_SECURITY_HIGH) 3372a770bb5aSWaldemar Rymarkiewicz secure = 1; 3373a770bb5aSWaldemar Rymarkiewicz else 3374a770bb5aSWaldemar Rymarkiewicz secure = 0; 3375a770bb5aSWaldemar Rymarkiewicz 3376744cf19eSJohan Hedberg mgmt_pin_code_request(hdev, &ev->bdaddr, secure); 3377a770bb5aSWaldemar Rymarkiewicz } 3378980e1a53SJohan Hedberg 3379b6f98044SWaldemar Rymarkiewicz unlock: 3380052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 33811da177e4SLinus Torvalds } 33821da177e4SLinus Torvalds 3383cb6f3f7aSJohan Hedberg static void conn_set_key(struct hci_conn *conn, u8 key_type, u8 pin_len) 3384cb6f3f7aSJohan Hedberg { 3385cb6f3f7aSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION) 3386cb6f3f7aSJohan Hedberg return; 3387cb6f3f7aSJohan Hedberg 3388cb6f3f7aSJohan Hedberg conn->pin_length = pin_len; 3389cb6f3f7aSJohan Hedberg conn->key_type = key_type; 3390cb6f3f7aSJohan Hedberg 3391cb6f3f7aSJohan Hedberg switch (key_type) { 3392cb6f3f7aSJohan Hedberg case HCI_LK_LOCAL_UNIT: 3393cb6f3f7aSJohan Hedberg case HCI_LK_REMOTE_UNIT: 3394cb6f3f7aSJohan Hedberg case HCI_LK_DEBUG_COMBINATION: 3395cb6f3f7aSJohan Hedberg return; 3396cb6f3f7aSJohan Hedberg case HCI_LK_COMBINATION: 3397cb6f3f7aSJohan Hedberg if (pin_len == 16) 3398cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_HIGH; 3399cb6f3f7aSJohan Hedberg else 3400cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_MEDIUM; 3401cb6f3f7aSJohan Hedberg break; 3402cb6f3f7aSJohan Hedberg case HCI_LK_UNAUTH_COMBINATION_P192: 3403cb6f3f7aSJohan Hedberg case HCI_LK_UNAUTH_COMBINATION_P256: 3404cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_MEDIUM; 3405cb6f3f7aSJohan Hedberg break; 3406cb6f3f7aSJohan Hedberg case HCI_LK_AUTH_COMBINATION_P192: 3407cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_HIGH; 3408cb6f3f7aSJohan Hedberg break; 3409cb6f3f7aSJohan Hedberg case HCI_LK_AUTH_COMBINATION_P256: 3410cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_FIPS; 3411cb6f3f7aSJohan Hedberg break; 3412cb6f3f7aSJohan Hedberg } 3413cb6f3f7aSJohan Hedberg } 3414cb6f3f7aSJohan Hedberg 34156039aa73SGustavo Padovan static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 34161da177e4SLinus Torvalds { 341755ed8ca1SJohan Hedberg struct hci_ev_link_key_req *ev = (void *) skb->data; 341855ed8ca1SJohan Hedberg struct hci_cp_link_key_reply cp; 341955ed8ca1SJohan Hedberg struct hci_conn *conn; 342055ed8ca1SJohan Hedberg struct link_key *key; 342155ed8ca1SJohan Hedberg 3422a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 342355ed8ca1SJohan Hedberg 3424d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 342555ed8ca1SJohan Hedberg return; 342655ed8ca1SJohan Hedberg 342755ed8ca1SJohan Hedberg hci_dev_lock(hdev); 342855ed8ca1SJohan Hedberg 342955ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, &ev->bdaddr); 343055ed8ca1SJohan Hedberg if (!key) { 34316ed93dc6SAndrei Emeltchenko BT_DBG("%s link key not found for %pMR", hdev->name, 34326ed93dc6SAndrei Emeltchenko &ev->bdaddr); 343355ed8ca1SJohan Hedberg goto not_found; 343455ed8ca1SJohan Hedberg } 343555ed8ca1SJohan Hedberg 34366ed93dc6SAndrei Emeltchenko BT_DBG("%s found key type %u for %pMR", hdev->name, key->type, 34376ed93dc6SAndrei Emeltchenko &ev->bdaddr); 343855ed8ca1SJohan Hedberg 343955ed8ca1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 344060b83f57SWaldemar Rymarkiewicz if (conn) { 3441fe8bc5acSJohan Hedberg clear_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags); 3442fe8bc5acSJohan Hedberg 344366138ce8SMarcel Holtmann if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 || 344466138ce8SMarcel Holtmann key->type == HCI_LK_UNAUTH_COMBINATION_P256) && 3445807deac2SGustavo Padovan conn->auth_type != 0xff && (conn->auth_type & 0x01)) { 344655ed8ca1SJohan Hedberg BT_DBG("%s ignoring unauthenticated key", hdev->name); 344755ed8ca1SJohan Hedberg goto not_found; 344855ed8ca1SJohan Hedberg } 344955ed8ca1SJohan Hedberg 345060b83f57SWaldemar Rymarkiewicz if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && 3451f3fb0b58SJohan Hedberg (conn->pending_sec_level == BT_SECURITY_HIGH || 3452f3fb0b58SJohan Hedberg conn->pending_sec_level == BT_SECURITY_FIPS)) { 34538fc9ced3SGustavo Padovan BT_DBG("%s ignoring key unauthenticated for high security", 34548fc9ced3SGustavo Padovan hdev->name); 345560b83f57SWaldemar Rymarkiewicz goto not_found; 345660b83f57SWaldemar Rymarkiewicz } 345760b83f57SWaldemar Rymarkiewicz 3458cb6f3f7aSJohan Hedberg conn_set_key(conn, key->type, key->pin_len); 345960b83f57SWaldemar Rymarkiewicz } 346060b83f57SWaldemar Rymarkiewicz 346155ed8ca1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 34629b3b4460SAndrei Emeltchenko memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE); 346355ed8ca1SJohan Hedberg 346455ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp); 346555ed8ca1SJohan Hedberg 346655ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 346755ed8ca1SJohan Hedberg 346855ed8ca1SJohan Hedberg return; 346955ed8ca1SJohan Hedberg 347055ed8ca1SJohan Hedberg not_found: 347155ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr); 347255ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 34731da177e4SLinus Torvalds } 34741da177e4SLinus Torvalds 34756039aa73SGustavo Padovan static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 34761da177e4SLinus Torvalds { 3477052b30b0SMarcel Holtmann struct hci_ev_link_key_notify *ev = (void *) skb->data; 3478052b30b0SMarcel Holtmann struct hci_conn *conn; 34797652ff6aSJohan Hedberg struct link_key *key; 34807652ff6aSJohan Hedberg bool persistent; 348155ed8ca1SJohan Hedberg u8 pin_len = 0; 3482052b30b0SMarcel Holtmann 3483a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 3484052b30b0SMarcel Holtmann 3485052b30b0SMarcel Holtmann hci_dev_lock(hdev); 3486052b30b0SMarcel Holtmann 3487052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 348882c13d42SJohan Hedberg if (!conn) 348982c13d42SJohan Hedberg goto unlock; 349082c13d42SJohan Hedberg 3491052b30b0SMarcel Holtmann hci_conn_hold(conn); 3492052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 349376a68ba0SDavid Herrmann hci_conn_drop(conn); 349482c13d42SJohan Hedberg 3495fe8bc5acSJohan Hedberg set_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags); 3496cb6f3f7aSJohan Hedberg conn_set_key(conn, ev->key_type, conn->pin_length); 3497052b30b0SMarcel Holtmann 3498d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 34997652ff6aSJohan Hedberg goto unlock; 350055ed8ca1SJohan Hedberg 35017652ff6aSJohan Hedberg key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key, 35027652ff6aSJohan Hedberg ev->key_type, pin_len, &persistent); 35037652ff6aSJohan Hedberg if (!key) 35047652ff6aSJohan Hedberg goto unlock; 35057652ff6aSJohan Hedberg 3506cb6f3f7aSJohan Hedberg /* Update connection information since adding the key will have 3507cb6f3f7aSJohan Hedberg * fixed up the type in the case of changed combination keys. 3508cb6f3f7aSJohan Hedberg */ 3509cb6f3f7aSJohan Hedberg if (ev->key_type == HCI_LK_CHANGED_COMBINATION) 3510cb6f3f7aSJohan Hedberg conn_set_key(conn, key->type, key->pin_len); 3511cb6f3f7aSJohan Hedberg 35127652ff6aSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 35137652ff6aSJohan Hedberg 35146d5650c4SJohan Hedberg /* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag 35156d5650c4SJohan Hedberg * is set. If it's not set simply remove the key from the kernel 35166d5650c4SJohan Hedberg * list (we've still notified user space about it but with 35176d5650c4SJohan Hedberg * store_hint being 0). 35186d5650c4SJohan Hedberg */ 35196d5650c4SJohan Hedberg if (key->type == HCI_LK_DEBUG_COMBINATION && 3520d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS)) { 35210378b597SJohan Hedberg list_del_rcu(&key->list); 35220378b597SJohan Hedberg kfree_rcu(key, rcu); 352382c13d42SJohan Hedberg goto unlock; 352482c13d42SJohan Hedberg } 352582c13d42SJohan Hedberg 3526af6a9c32SJohan Hedberg if (persistent) 3527af6a9c32SJohan Hedberg clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags); 3528af6a9c32SJohan Hedberg else 3529af6a9c32SJohan Hedberg set_bit(HCI_CONN_FLUSH_KEY, &conn->flags); 35307652ff6aSJohan Hedberg 35317652ff6aSJohan Hedberg unlock: 3532052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 35331da177e4SLinus Torvalds } 35341da177e4SLinus Torvalds 35356039aa73SGustavo Padovan static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) 353604837f64SMarcel Holtmann { 3537a9de9248SMarcel Holtmann struct hci_ev_clock_offset *ev = (void *) skb->data; 353804837f64SMarcel Holtmann struct hci_conn *conn; 353904837f64SMarcel Holtmann 35409f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 354104837f64SMarcel Holtmann 354204837f64SMarcel Holtmann hci_dev_lock(hdev); 354304837f64SMarcel Holtmann 354404837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 35451da177e4SLinus Torvalds if (conn && !ev->status) { 35461da177e4SLinus Torvalds struct inquiry_entry *ie; 35471da177e4SLinus Torvalds 3548cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 3549cc11b9c1SAndrei Emeltchenko if (ie) { 35501da177e4SLinus Torvalds ie->data.clock_offset = ev->clock_offset; 35511da177e4SLinus Torvalds ie->timestamp = jiffies; 35521da177e4SLinus Torvalds } 35531da177e4SLinus Torvalds } 35541da177e4SLinus Torvalds 35551da177e4SLinus Torvalds hci_dev_unlock(hdev); 35561da177e4SLinus Torvalds } 35571da177e4SLinus Torvalds 35586039aa73SGustavo Padovan static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 3559a8746417SMarcel Holtmann { 3560a8746417SMarcel Holtmann struct hci_ev_pkt_type_change *ev = (void *) skb->data; 3561a8746417SMarcel Holtmann struct hci_conn *conn; 3562a8746417SMarcel Holtmann 35639f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3564a8746417SMarcel Holtmann 3565a8746417SMarcel Holtmann hci_dev_lock(hdev); 3566a8746417SMarcel Holtmann 3567a8746417SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3568a8746417SMarcel Holtmann if (conn && !ev->status) 3569a8746417SMarcel Holtmann conn->pkt_type = __le16_to_cpu(ev->pkt_type); 3570a8746417SMarcel Holtmann 3571a8746417SMarcel Holtmann hci_dev_unlock(hdev); 3572a8746417SMarcel Holtmann } 3573a8746417SMarcel Holtmann 35746039aa73SGustavo Padovan static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) 357585a1e930SMarcel Holtmann { 3576a9de9248SMarcel Holtmann struct hci_ev_pscan_rep_mode *ev = (void *) skb->data; 357785a1e930SMarcel Holtmann struct inquiry_entry *ie; 357885a1e930SMarcel Holtmann 357985a1e930SMarcel Holtmann BT_DBG("%s", hdev->name); 358085a1e930SMarcel Holtmann 358185a1e930SMarcel Holtmann hci_dev_lock(hdev); 358285a1e930SMarcel Holtmann 3583cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 3584cc11b9c1SAndrei Emeltchenko if (ie) { 358585a1e930SMarcel Holtmann ie->data.pscan_rep_mode = ev->pscan_rep_mode; 358685a1e930SMarcel Holtmann ie->timestamp = jiffies; 358785a1e930SMarcel Holtmann } 358885a1e930SMarcel Holtmann 358985a1e930SMarcel Holtmann hci_dev_unlock(hdev); 359085a1e930SMarcel Holtmann } 359185a1e930SMarcel Holtmann 35926039aa73SGustavo Padovan static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, 3593807deac2SGustavo Padovan struct sk_buff *skb) 3594a9de9248SMarcel Holtmann { 3595a9de9248SMarcel Holtmann struct inquiry_data data; 3596a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 3597a9de9248SMarcel Holtmann 3598a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 3599a9de9248SMarcel Holtmann 3600a9de9248SMarcel Holtmann if (!num_rsp) 3601a9de9248SMarcel Holtmann return; 3602a9de9248SMarcel Holtmann 3603d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) 36041519cc17SAndre Guedes return; 36051519cc17SAndre Guedes 3606a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3607a9de9248SMarcel Holtmann 3608a9de9248SMarcel Holtmann if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { 3609138d22efSSzymon Janc struct inquiry_info_with_rssi_and_pscan_mode *info; 3610138d22efSSzymon Janc info = (void *) (skb->data + 1); 3611a9de9248SMarcel Holtmann 3612e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3613af58925cSMarcel Holtmann u32 flags; 3614af58925cSMarcel Holtmann 3615a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3616a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3617a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3618a9de9248SMarcel Holtmann data.pscan_mode = info->pscan_mode; 3619a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3620a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3621a9de9248SMarcel Holtmann data.rssi = info->rssi; 362241a96212SMarcel Holtmann data.ssp_mode = 0x00; 36233175405bSJohan Hedberg 3624af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 3625af58925cSMarcel Holtmann 362648264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3627e17acd40SJohan Hedberg info->dev_class, info->rssi, 3628af58925cSMarcel Holtmann flags, NULL, 0, NULL, 0); 3629a9de9248SMarcel Holtmann } 3630a9de9248SMarcel Holtmann } else { 3631a9de9248SMarcel Holtmann struct inquiry_info_with_rssi *info = (void *) (skb->data + 1); 3632a9de9248SMarcel Holtmann 3633e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3634af58925cSMarcel Holtmann u32 flags; 3635af58925cSMarcel Holtmann 3636a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3637a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3638a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3639a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 3640a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3641a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3642a9de9248SMarcel Holtmann data.rssi = info->rssi; 364341a96212SMarcel Holtmann data.ssp_mode = 0x00; 3644af58925cSMarcel Holtmann 3645af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 3646af58925cSMarcel Holtmann 364748264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3648e17acd40SJohan Hedberg info->dev_class, info->rssi, 3649af58925cSMarcel Holtmann flags, NULL, 0, NULL, 0); 3650a9de9248SMarcel Holtmann } 3651a9de9248SMarcel Holtmann } 3652a9de9248SMarcel Holtmann 3653a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3654a9de9248SMarcel Holtmann } 3655a9de9248SMarcel Holtmann 36566039aa73SGustavo Padovan static void hci_remote_ext_features_evt(struct hci_dev *hdev, 3657807deac2SGustavo Padovan struct sk_buff *skb) 3658a9de9248SMarcel Holtmann { 365941a96212SMarcel Holtmann struct hci_ev_remote_ext_features *ev = (void *) skb->data; 366041a96212SMarcel Holtmann struct hci_conn *conn; 366141a96212SMarcel Holtmann 3662a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 366341a96212SMarcel Holtmann 366441a96212SMarcel Holtmann hci_dev_lock(hdev); 366541a96212SMarcel Holtmann 366641a96212SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3667ccd556feSJohan Hedberg if (!conn) 3668ccd556feSJohan Hedberg goto unlock; 3669ccd556feSJohan Hedberg 3670cad718edSJohan Hedberg if (ev->page < HCI_MAX_PAGES) 3671cad718edSJohan Hedberg memcpy(conn->features[ev->page], ev->features, 8); 3672cad718edSJohan Hedberg 3673769be974SMarcel Holtmann if (!ev->status && ev->page == 0x01) { 367441a96212SMarcel Holtmann struct inquiry_entry *ie; 367541a96212SMarcel Holtmann 3676cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 3677cc11b9c1SAndrei Emeltchenko if (ie) 367802b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 367941a96212SMarcel Holtmann 3680bbb0eadaSJaganath Kanakkassery if (ev->features[0] & LMP_HOST_SSP) { 368158a681efSJohan Hedberg set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 3682bbb0eadaSJaganath Kanakkassery } else { 3683bbb0eadaSJaganath Kanakkassery /* It is mandatory by the Bluetooth specification that 3684bbb0eadaSJaganath Kanakkassery * Extended Inquiry Results are only used when Secure 3685bbb0eadaSJaganath Kanakkassery * Simple Pairing is enabled, but some devices violate 3686bbb0eadaSJaganath Kanakkassery * this. 3687bbb0eadaSJaganath Kanakkassery * 3688bbb0eadaSJaganath Kanakkassery * To make these devices work, the internal SSP 3689bbb0eadaSJaganath Kanakkassery * enabled flag needs to be cleared if the remote host 3690bbb0eadaSJaganath Kanakkassery * features do not indicate SSP support */ 3691bbb0eadaSJaganath Kanakkassery clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 3692bbb0eadaSJaganath Kanakkassery } 3693eb9a8f3fSMarcel Holtmann 3694eb9a8f3fSMarcel Holtmann if (ev->features[0] & LMP_HOST_SC) 3695eb9a8f3fSMarcel Holtmann set_bit(HCI_CONN_SC_ENABLED, &conn->flags); 369641a96212SMarcel Holtmann } 369741a96212SMarcel Holtmann 3698ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 3699ccd556feSJohan Hedberg goto unlock; 3700ccd556feSJohan Hedberg 3701671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 3702127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 3703127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 3704127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 3705127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 3706127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 3707b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 370848ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, NULL, 0); 3709392599b9SJohan Hedberg 3710127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 3711769be974SMarcel Holtmann conn->state = BT_CONNECTED; 3712539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 371376a68ba0SDavid Herrmann hci_conn_drop(conn); 3714769be974SMarcel Holtmann } 3715769be974SMarcel Holtmann 3716ccd556feSJohan Hedberg unlock: 371741a96212SMarcel Holtmann hci_dev_unlock(hdev); 3718a9de9248SMarcel Holtmann } 3719a9de9248SMarcel Holtmann 37206039aa73SGustavo Padovan static void hci_sync_conn_complete_evt(struct hci_dev *hdev, 3721807deac2SGustavo Padovan struct sk_buff *skb) 3722a9de9248SMarcel Holtmann { 3723b6a0dc82SMarcel Holtmann struct hci_ev_sync_conn_complete *ev = (void *) skb->data; 3724b6a0dc82SMarcel Holtmann struct hci_conn *conn; 3725b6a0dc82SMarcel Holtmann 37269f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3727b6a0dc82SMarcel Holtmann 3728b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 3729b6a0dc82SMarcel Holtmann 3730b6a0dc82SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 37319dc0a3afSMarcel Holtmann if (!conn) { 37329dc0a3afSMarcel Holtmann if (ev->link_type == ESCO_LINK) 37339dc0a3afSMarcel Holtmann goto unlock; 37349dc0a3afSMarcel Holtmann 3735618353b1SKuba Pawlak /* When the link type in the event indicates SCO connection 3736618353b1SKuba Pawlak * and lookup of the connection object fails, then check 3737618353b1SKuba Pawlak * if an eSCO connection object exists. 3738618353b1SKuba Pawlak * 3739618353b1SKuba Pawlak * The core limits the synchronous connections to either 3740618353b1SKuba Pawlak * SCO or eSCO. The eSCO connection is preferred and tried 3741618353b1SKuba Pawlak * to be setup first and until successfully established, 3742618353b1SKuba Pawlak * the link type will be hinted as eSCO. 3743618353b1SKuba Pawlak */ 37449dc0a3afSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 3745b6a0dc82SMarcel Holtmann if (!conn) 3746b6a0dc82SMarcel Holtmann goto unlock; 37479dc0a3afSMarcel Holtmann } 37489dc0a3afSMarcel Holtmann 3749732547f9SMarcel Holtmann switch (ev->status) { 3750732547f9SMarcel Holtmann case 0x00: 3751732547f9SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 3752732547f9SMarcel Holtmann conn->state = BT_CONNECTED; 3753618353b1SKuba Pawlak conn->type = ev->link_type; 3754732547f9SMarcel Holtmann 375523b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn); 3756732547f9SMarcel Holtmann hci_conn_add_sysfs(conn); 3757732547f9SMarcel Holtmann break; 3758732547f9SMarcel Holtmann 375981218d20SNick Pelly case 0x10: /* Connection Accept Timeout */ 37601a4c958cSFrédéric Dalleau case 0x0d: /* Connection Rejected due to Limited Resources */ 3761705e5711SStephen Coe case 0x11: /* Unsupported Feature or Parameter Value */ 3762732547f9SMarcel Holtmann case 0x1c: /* SCO interval rejected */ 37631038a00bSNick Pelly case 0x1a: /* Unsupported Remote Feature */ 3764732547f9SMarcel Holtmann case 0x1f: /* Unspecified error */ 376527539bc4SAndrew Earl case 0x20: /* Unsupported LMP Parameter value */ 37662dea632fSFrédéric Dalleau if (conn->out) { 3767efc7688bSMarcel Holtmann conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | 3768efc7688bSMarcel Holtmann (hdev->esco_type & EDR_ESCO_MASK); 37692dea632fSFrédéric Dalleau if (hci_setup_sync(conn, conn->link->handle)) 3770efc7688bSMarcel Holtmann goto unlock; 3771efc7688bSMarcel Holtmann } 3772732547f9SMarcel Holtmann /* fall through */ 3773efc7688bSMarcel Holtmann 3774732547f9SMarcel Holtmann default: 3775b6a0dc82SMarcel Holtmann conn->state = BT_CLOSED; 3776732547f9SMarcel Holtmann break; 3777732547f9SMarcel Holtmann } 3778b6a0dc82SMarcel Holtmann 3779539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 3780b6a0dc82SMarcel Holtmann if (ev->status) 3781b6a0dc82SMarcel Holtmann hci_conn_del(conn); 3782b6a0dc82SMarcel Holtmann 3783b6a0dc82SMarcel Holtmann unlock: 3784b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 3785a9de9248SMarcel Holtmann } 3786a9de9248SMarcel Holtmann 3787efdcf8e3SMarcel Holtmann static inline size_t eir_get_length(u8 *eir, size_t eir_len) 3788efdcf8e3SMarcel Holtmann { 3789efdcf8e3SMarcel Holtmann size_t parsed = 0; 3790efdcf8e3SMarcel Holtmann 3791efdcf8e3SMarcel Holtmann while (parsed < eir_len) { 3792efdcf8e3SMarcel Holtmann u8 field_len = eir[0]; 3793efdcf8e3SMarcel Holtmann 3794efdcf8e3SMarcel Holtmann if (field_len == 0) 3795efdcf8e3SMarcel Holtmann return parsed; 3796efdcf8e3SMarcel Holtmann 3797efdcf8e3SMarcel Holtmann parsed += field_len + 1; 3798efdcf8e3SMarcel Holtmann eir += field_len + 1; 3799efdcf8e3SMarcel Holtmann } 3800efdcf8e3SMarcel Holtmann 3801efdcf8e3SMarcel Holtmann return eir_len; 3802efdcf8e3SMarcel Holtmann } 3803efdcf8e3SMarcel Holtmann 38046039aa73SGustavo Padovan static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, 3805807deac2SGustavo Padovan struct sk_buff *skb) 3806a9de9248SMarcel Holtmann { 3807a9de9248SMarcel Holtmann struct inquiry_data data; 3808a9de9248SMarcel Holtmann struct extended_inquiry_info *info = (void *) (skb->data + 1); 3809a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 38109d939d94SVishal Agarwal size_t eir_len; 3811a9de9248SMarcel Holtmann 3812a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 3813a9de9248SMarcel Holtmann 3814a9de9248SMarcel Holtmann if (!num_rsp) 3815a9de9248SMarcel Holtmann return; 3816a9de9248SMarcel Holtmann 3817d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) 38181519cc17SAndre Guedes return; 38191519cc17SAndre Guedes 3820a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3821a9de9248SMarcel Holtmann 3822e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3823af58925cSMarcel Holtmann u32 flags; 3824af58925cSMarcel Holtmann bool name_known; 3825561aafbcSJohan Hedberg 3826a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3827a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3828a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3829a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 3830a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3831a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3832a9de9248SMarcel Holtmann data.rssi = info->rssi; 383341a96212SMarcel Holtmann data.ssp_mode = 0x01; 3834561aafbcSJohan Hedberg 3835d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 38364ddb1930SJohan Hedberg name_known = eir_has_data_type(info->data, 38374ddb1930SJohan Hedberg sizeof(info->data), 38384ddb1930SJohan Hedberg EIR_NAME_COMPLETE); 3839561aafbcSJohan Hedberg else 3840561aafbcSJohan Hedberg name_known = true; 3841561aafbcSJohan Hedberg 3842af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, name_known); 3843af58925cSMarcel Holtmann 38449d939d94SVishal Agarwal eir_len = eir_get_length(info->data, sizeof(info->data)); 3845af58925cSMarcel Holtmann 384648264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3847af58925cSMarcel Holtmann info->dev_class, info->rssi, 3848af58925cSMarcel Holtmann flags, info->data, eir_len, NULL, 0); 3849a9de9248SMarcel Holtmann } 3850a9de9248SMarcel Holtmann 3851a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3852a9de9248SMarcel Holtmann } 3853a9de9248SMarcel Holtmann 38541c2e0041SJohan Hedberg static void hci_key_refresh_complete_evt(struct hci_dev *hdev, 38551c2e0041SJohan Hedberg struct sk_buff *skb) 38561c2e0041SJohan Hedberg { 38571c2e0041SJohan Hedberg struct hci_ev_key_refresh_complete *ev = (void *) skb->data; 38581c2e0041SJohan Hedberg struct hci_conn *conn; 38591c2e0041SJohan Hedberg 38609f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status, 38611c2e0041SJohan Hedberg __le16_to_cpu(ev->handle)); 38621c2e0041SJohan Hedberg 38631c2e0041SJohan Hedberg hci_dev_lock(hdev); 38641c2e0041SJohan Hedberg 38651c2e0041SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 38661c2e0041SJohan Hedberg if (!conn) 38671c2e0041SJohan Hedberg goto unlock; 38681c2e0041SJohan Hedberg 38699eb1fbfaSJohan Hedberg /* For BR/EDR the necessary steps are taken through the 38709eb1fbfaSJohan Hedberg * auth_complete event. 38719eb1fbfaSJohan Hedberg */ 38729eb1fbfaSJohan Hedberg if (conn->type != LE_LINK) 38739eb1fbfaSJohan Hedberg goto unlock; 38749eb1fbfaSJohan Hedberg 38751c2e0041SJohan Hedberg if (!ev->status) 38761c2e0041SJohan Hedberg conn->sec_level = conn->pending_sec_level; 38771c2e0041SJohan Hedberg 38781c2e0041SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 38791c2e0041SJohan Hedberg 38801c2e0041SJohan Hedberg if (ev->status && conn->state == BT_CONNECTED) { 3881bed71748SAndre Guedes hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 388276a68ba0SDavid Herrmann hci_conn_drop(conn); 38831c2e0041SJohan Hedberg goto unlock; 38841c2e0041SJohan Hedberg } 38851c2e0041SJohan Hedberg 38861c2e0041SJohan Hedberg if (conn->state == BT_CONFIG) { 38871c2e0041SJohan Hedberg if (!ev->status) 38881c2e0041SJohan Hedberg conn->state = BT_CONNECTED; 38891c2e0041SJohan Hedberg 3890539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 389176a68ba0SDavid Herrmann hci_conn_drop(conn); 38921c2e0041SJohan Hedberg } else { 38931c2e0041SJohan Hedberg hci_auth_cfm(conn, ev->status); 38941c2e0041SJohan Hedberg 38951c2e0041SJohan Hedberg hci_conn_hold(conn); 38961c2e0041SJohan Hedberg conn->disc_timeout = HCI_DISCONN_TIMEOUT; 389776a68ba0SDavid Herrmann hci_conn_drop(conn); 38981c2e0041SJohan Hedberg } 38991c2e0041SJohan Hedberg 39001c2e0041SJohan Hedberg unlock: 39011c2e0041SJohan Hedberg hci_dev_unlock(hdev); 39021c2e0041SJohan Hedberg } 39031c2e0041SJohan Hedberg 39046039aa73SGustavo Padovan static u8 hci_get_auth_req(struct hci_conn *conn) 390517fa4b9dSJohan Hedberg { 390617fa4b9dSJohan Hedberg /* If remote requests no-bonding follow that lead */ 3907acabae96SMikel Astiz if (conn->remote_auth == HCI_AT_NO_BONDING || 3908acabae96SMikel Astiz conn->remote_auth == HCI_AT_NO_BONDING_MITM) 390958797bf7SWaldemar Rymarkiewicz return conn->remote_auth | (conn->auth_type & 0x01); 391017fa4b9dSJohan Hedberg 3911b7f94c88SMikel Astiz /* If both remote and local have enough IO capabilities, require 3912b7f94c88SMikel Astiz * MITM protection 3913b7f94c88SMikel Astiz */ 3914b7f94c88SMikel Astiz if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT && 3915b7f94c88SMikel Astiz conn->io_capability != HCI_IO_NO_INPUT_OUTPUT) 3916b7f94c88SMikel Astiz return conn->remote_auth | 0x01; 3917b7f94c88SMikel Astiz 39187e74170aSTimo Mueller /* No MITM protection possible so ignore remote requirement */ 39197e74170aSTimo Mueller return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01); 392017fa4b9dSJohan Hedberg } 392117fa4b9dSJohan Hedberg 3922a83ed81eSMarcel Holtmann static u8 bredr_oob_data_present(struct hci_conn *conn) 3923a83ed81eSMarcel Holtmann { 3924a83ed81eSMarcel Holtmann struct hci_dev *hdev = conn->hdev; 3925a83ed81eSMarcel Holtmann struct oob_data *data; 3926a83ed81eSMarcel Holtmann 3927a83ed81eSMarcel Holtmann data = hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR); 3928a83ed81eSMarcel Holtmann if (!data) 3929a83ed81eSMarcel Holtmann return 0x00; 3930a83ed81eSMarcel Holtmann 3931bf21d793SMarcel Holtmann if (bredr_sc_enabled(hdev)) { 3932bf21d793SMarcel Holtmann /* When Secure Connections is enabled, then just 3933bf21d793SMarcel Holtmann * return the present value stored with the OOB 3934bf21d793SMarcel Holtmann * data. The stored value contains the right present 3935bf21d793SMarcel Holtmann * information. However it can only be trusted when 3936bf21d793SMarcel Holtmann * not in Secure Connection Only mode. 3937aa5b0345SMarcel Holtmann */ 3938d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SC_ONLY)) 3939bf21d793SMarcel Holtmann return data->present; 3940bf21d793SMarcel Holtmann 3941bf21d793SMarcel Holtmann /* When Secure Connections Only mode is enabled, then 3942bf21d793SMarcel Holtmann * the P-256 values are required. If they are not 3943bf21d793SMarcel Holtmann * available, then do not declare that OOB data is 3944bf21d793SMarcel Holtmann * present. 3945bf21d793SMarcel Holtmann */ 3946bf21d793SMarcel Holtmann if (!memcmp(data->rand256, ZERO_KEY, 16) || 3947bf21d793SMarcel Holtmann !memcmp(data->hash256, ZERO_KEY, 16)) 3948aa5b0345SMarcel Holtmann return 0x00; 3949aa5b0345SMarcel Holtmann 3950bf21d793SMarcel Holtmann return 0x02; 3951bf21d793SMarcel Holtmann } 3952659c7fb0SMarcel Holtmann 3953659c7fb0SMarcel Holtmann /* When Secure Connections is not enabled or actually 3954659c7fb0SMarcel Holtmann * not supported by the hardware, then check that if 3955659c7fb0SMarcel Holtmann * P-192 data values are present. 3956659c7fb0SMarcel Holtmann */ 3957659c7fb0SMarcel Holtmann if (!memcmp(data->rand192, ZERO_KEY, 16) || 3958659c7fb0SMarcel Holtmann !memcmp(data->hash192, ZERO_KEY, 16)) 3959659c7fb0SMarcel Holtmann return 0x00; 3960659c7fb0SMarcel Holtmann 3961a83ed81eSMarcel Holtmann return 0x01; 3962659c7fb0SMarcel Holtmann } 3963a83ed81eSMarcel Holtmann 39646039aa73SGustavo Padovan static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 39650493684eSMarcel Holtmann { 39660493684eSMarcel Holtmann struct hci_ev_io_capa_request *ev = (void *) skb->data; 39670493684eSMarcel Holtmann struct hci_conn *conn; 39680493684eSMarcel Holtmann 39690493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 39700493684eSMarcel Holtmann 39710493684eSMarcel Holtmann hci_dev_lock(hdev); 39720493684eSMarcel Holtmann 39730493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 397403b555e1SJohan Hedberg if (!conn) 397503b555e1SJohan Hedberg goto unlock; 397603b555e1SJohan Hedberg 39770493684eSMarcel Holtmann hci_conn_hold(conn); 39780493684eSMarcel Holtmann 3979d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 398003b555e1SJohan Hedberg goto unlock; 398103b555e1SJohan Hedberg 39822f407f0aSJohan Hedberg /* Allow pairing if we're pairable, the initiators of the 39832f407f0aSJohan Hedberg * pairing or if the remote is not requesting bonding. 39842f407f0aSJohan Hedberg */ 3985d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_BONDABLE) || 39862f407f0aSJohan Hedberg test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags) || 398703b555e1SJohan Hedberg (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { 398817fa4b9dSJohan Hedberg struct hci_cp_io_capability_reply cp; 398917fa4b9dSJohan Hedberg 399017fa4b9dSJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 39917a7f1e7cSHemant Gupta /* Change the IO capability from KeyboardDisplay 39927a7f1e7cSHemant Gupta * to DisplayYesNo as it is not supported by BT spec. */ 39937a7f1e7cSHemant Gupta cp.capability = (conn->io_capability == 0x04) ? 3994a767631aSMikel Astiz HCI_IO_DISPLAY_YESNO : conn->io_capability; 3995b7f94c88SMikel Astiz 3996b7f94c88SMikel Astiz /* If we are initiators, there is no remote information yet */ 3997b7f94c88SMikel Astiz if (conn->remote_auth == 0xff) { 3998b16c6604SMikel Astiz /* Request MITM protection if our IO caps allow it 39994ad51a75SJohan Hedberg * except for the no-bonding case. 4000b16c6604SMikel Astiz */ 40016fd6b915SMikel Astiz if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT && 40029f743d74SJohan Hedberg conn->auth_type != HCI_AT_NO_BONDING) 40036c53823aSJohan Hedberg conn->auth_type |= 0x01; 4004b7f94c88SMikel Astiz } else { 40057cbc9bd9SJohan Hedberg conn->auth_type = hci_get_auth_req(conn); 4006b7f94c88SMikel Astiz } 400717fa4b9dSJohan Hedberg 400882c295b1SJohan Hedberg /* If we're not bondable, force one of the non-bondable 400982c295b1SJohan Hedberg * authentication requirement values. 401082c295b1SJohan Hedberg */ 4011d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE)) 401282c295b1SJohan Hedberg conn->auth_type &= HCI_AT_NO_BONDING_MITM; 401382c295b1SJohan Hedberg 401482c295b1SJohan Hedberg cp.authentication = conn->auth_type; 4015a83ed81eSMarcel Holtmann cp.oob_data = bredr_oob_data_present(conn); 4016ce85ee13SSzymon Janc 401717fa4b9dSJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY, 401817fa4b9dSJohan Hedberg sizeof(cp), &cp); 401903b555e1SJohan Hedberg } else { 402003b555e1SJohan Hedberg struct hci_cp_io_capability_neg_reply cp; 402103b555e1SJohan Hedberg 402203b555e1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 40239f5a0d7bSAndrei Emeltchenko cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED; 402403b555e1SJohan Hedberg 402503b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, 402603b555e1SJohan Hedberg sizeof(cp), &cp); 402703b555e1SJohan Hedberg } 402803b555e1SJohan Hedberg 402903b555e1SJohan Hedberg unlock: 403003b555e1SJohan Hedberg hci_dev_unlock(hdev); 403103b555e1SJohan Hedberg } 403203b555e1SJohan Hedberg 40336039aa73SGustavo Padovan static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) 403403b555e1SJohan Hedberg { 403503b555e1SJohan Hedberg struct hci_ev_io_capa_reply *ev = (void *) skb->data; 403603b555e1SJohan Hedberg struct hci_conn *conn; 403703b555e1SJohan Hedberg 403803b555e1SJohan Hedberg BT_DBG("%s", hdev->name); 403903b555e1SJohan Hedberg 404003b555e1SJohan Hedberg hci_dev_lock(hdev); 404103b555e1SJohan Hedberg 404203b555e1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 404303b555e1SJohan Hedberg if (!conn) 404403b555e1SJohan Hedberg goto unlock; 404503b555e1SJohan Hedberg 404603b555e1SJohan Hedberg conn->remote_cap = ev->capability; 404703b555e1SJohan Hedberg conn->remote_auth = ev->authentication; 404803b555e1SJohan Hedberg 404903b555e1SJohan Hedberg unlock: 40500493684eSMarcel Holtmann hci_dev_unlock(hdev); 40510493684eSMarcel Holtmann } 40520493684eSMarcel Holtmann 40536039aa73SGustavo Padovan static void hci_user_confirm_request_evt(struct hci_dev *hdev, 4054a5c29683SJohan Hedberg struct sk_buff *skb) 4055a5c29683SJohan Hedberg { 4056a5c29683SJohan Hedberg struct hci_ev_user_confirm_req *ev = (void *) skb->data; 405755bc1a37SJohan Hedberg int loc_mitm, rem_mitm, confirm_hint = 0; 40587a828908SJohan Hedberg struct hci_conn *conn; 4059a5c29683SJohan Hedberg 4060a5c29683SJohan Hedberg BT_DBG("%s", hdev->name); 4061a5c29683SJohan Hedberg 4062a5c29683SJohan Hedberg hci_dev_lock(hdev); 4063a5c29683SJohan Hedberg 4064d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 40657a828908SJohan Hedberg goto unlock; 40667a828908SJohan Hedberg 40677a828908SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 40687a828908SJohan Hedberg if (!conn) 40697a828908SJohan Hedberg goto unlock; 40707a828908SJohan Hedberg 40717a828908SJohan Hedberg loc_mitm = (conn->auth_type & 0x01); 40727a828908SJohan Hedberg rem_mitm = (conn->remote_auth & 0x01); 40737a828908SJohan Hedberg 40747a828908SJohan Hedberg /* If we require MITM but the remote device can't provide that 40756c53823aSJohan Hedberg * (it has NoInputNoOutput) then reject the confirmation 40766c53823aSJohan Hedberg * request. We check the security level here since it doesn't 40776c53823aSJohan Hedberg * necessarily match conn->auth_type. 40786fd6b915SMikel Astiz */ 40796c53823aSJohan Hedberg if (conn->pending_sec_level > BT_SECURITY_MEDIUM && 40806c53823aSJohan Hedberg conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) { 40817a828908SJohan Hedberg BT_DBG("Rejecting request: remote device can't provide MITM"); 40827a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY, 40837a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 40847a828908SJohan Hedberg goto unlock; 40857a828908SJohan Hedberg } 40867a828908SJohan Hedberg 40877a828908SJohan Hedberg /* If no side requires MITM protection; auto-accept */ 4088a767631aSMikel Astiz if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) && 4089a767631aSMikel Astiz (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) { 409055bc1a37SJohan Hedberg 409155bc1a37SJohan Hedberg /* If we're not the initiators request authorization to 409255bc1a37SJohan Hedberg * proceed from user space (mgmt_user_confirm with 4093ba15a58bSJohan Hedberg * confirm_hint set to 1). The exception is if neither 409402f3e254SJohan Hedberg * side had MITM or if the local IO capability is 409502f3e254SJohan Hedberg * NoInputNoOutput, in which case we do auto-accept 4096ba15a58bSJohan Hedberg */ 4097ba15a58bSJohan Hedberg if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && 409802f3e254SJohan Hedberg conn->io_capability != HCI_IO_NO_INPUT_OUTPUT && 4099ba15a58bSJohan Hedberg (loc_mitm || rem_mitm)) { 410055bc1a37SJohan Hedberg BT_DBG("Confirming auto-accept as acceptor"); 410155bc1a37SJohan Hedberg confirm_hint = 1; 410255bc1a37SJohan Hedberg goto confirm; 410355bc1a37SJohan Hedberg } 410455bc1a37SJohan Hedberg 41059f61656aSJohan Hedberg BT_DBG("Auto-accept of user confirmation with %ums delay", 41069f61656aSJohan Hedberg hdev->auto_accept_delay); 41079f61656aSJohan Hedberg 41089f61656aSJohan Hedberg if (hdev->auto_accept_delay > 0) { 41099f61656aSJohan Hedberg int delay = msecs_to_jiffies(hdev->auto_accept_delay); 41107bc18d9dSJohan Hedberg queue_delayed_work(conn->hdev->workqueue, 41117bc18d9dSJohan Hedberg &conn->auto_accept_work, delay); 41129f61656aSJohan Hedberg goto unlock; 41139f61656aSJohan Hedberg } 41149f61656aSJohan Hedberg 41157a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, 41167a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 41177a828908SJohan Hedberg goto unlock; 41187a828908SJohan Hedberg } 41197a828908SJohan Hedberg 412055bc1a37SJohan Hedberg confirm: 412139adbffeSJohan Hedberg mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, 412239adbffeSJohan Hedberg le32_to_cpu(ev->passkey), confirm_hint); 4123a5c29683SJohan Hedberg 41247a828908SJohan Hedberg unlock: 4125a5c29683SJohan Hedberg hci_dev_unlock(hdev); 4126a5c29683SJohan Hedberg } 4127a5c29683SJohan Hedberg 41286039aa73SGustavo Padovan static void hci_user_passkey_request_evt(struct hci_dev *hdev, 41291143d458SBrian Gix struct sk_buff *skb) 41301143d458SBrian Gix { 41311143d458SBrian Gix struct hci_ev_user_passkey_req *ev = (void *) skb->data; 41321143d458SBrian Gix 41331143d458SBrian Gix BT_DBG("%s", hdev->name); 41341143d458SBrian Gix 4135d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 4136272d90dfSJohan Hedberg mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); 41371143d458SBrian Gix } 41381143d458SBrian Gix 413992a25256SJohan Hedberg static void hci_user_passkey_notify_evt(struct hci_dev *hdev, 414092a25256SJohan Hedberg struct sk_buff *skb) 414192a25256SJohan Hedberg { 414292a25256SJohan Hedberg struct hci_ev_user_passkey_notify *ev = (void *) skb->data; 414392a25256SJohan Hedberg struct hci_conn *conn; 414492a25256SJohan Hedberg 414592a25256SJohan Hedberg BT_DBG("%s", hdev->name); 414692a25256SJohan Hedberg 414792a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 414892a25256SJohan Hedberg if (!conn) 414992a25256SJohan Hedberg return; 415092a25256SJohan Hedberg 415192a25256SJohan Hedberg conn->passkey_notify = __le32_to_cpu(ev->passkey); 415292a25256SJohan Hedberg conn->passkey_entered = 0; 415392a25256SJohan Hedberg 4154d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 415592a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 415692a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 415792a25256SJohan Hedberg conn->passkey_entered); 415892a25256SJohan Hedberg } 415992a25256SJohan Hedberg 416092a25256SJohan Hedberg static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 416192a25256SJohan Hedberg { 416292a25256SJohan Hedberg struct hci_ev_keypress_notify *ev = (void *) skb->data; 416392a25256SJohan Hedberg struct hci_conn *conn; 416492a25256SJohan Hedberg 416592a25256SJohan Hedberg BT_DBG("%s", hdev->name); 416692a25256SJohan Hedberg 416792a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 416892a25256SJohan Hedberg if (!conn) 416992a25256SJohan Hedberg return; 417092a25256SJohan Hedberg 417192a25256SJohan Hedberg switch (ev->type) { 417292a25256SJohan Hedberg case HCI_KEYPRESS_STARTED: 417392a25256SJohan Hedberg conn->passkey_entered = 0; 417492a25256SJohan Hedberg return; 417592a25256SJohan Hedberg 417692a25256SJohan Hedberg case HCI_KEYPRESS_ENTERED: 417792a25256SJohan Hedberg conn->passkey_entered++; 417892a25256SJohan Hedberg break; 417992a25256SJohan Hedberg 418092a25256SJohan Hedberg case HCI_KEYPRESS_ERASED: 418192a25256SJohan Hedberg conn->passkey_entered--; 418292a25256SJohan Hedberg break; 418392a25256SJohan Hedberg 418492a25256SJohan Hedberg case HCI_KEYPRESS_CLEARED: 418592a25256SJohan Hedberg conn->passkey_entered = 0; 418692a25256SJohan Hedberg break; 418792a25256SJohan Hedberg 418892a25256SJohan Hedberg case HCI_KEYPRESS_COMPLETED: 418992a25256SJohan Hedberg return; 419092a25256SJohan Hedberg } 419192a25256SJohan Hedberg 4192d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 419392a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 419492a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 419592a25256SJohan Hedberg conn->passkey_entered); 419692a25256SJohan Hedberg } 419792a25256SJohan Hedberg 41986039aa73SGustavo Padovan static void hci_simple_pair_complete_evt(struct hci_dev *hdev, 4199807deac2SGustavo Padovan struct sk_buff *skb) 42000493684eSMarcel Holtmann { 42010493684eSMarcel Holtmann struct hci_ev_simple_pair_complete *ev = (void *) skb->data; 42020493684eSMarcel Holtmann struct hci_conn *conn; 42030493684eSMarcel Holtmann 42040493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 42050493684eSMarcel Holtmann 42060493684eSMarcel Holtmann hci_dev_lock(hdev); 42070493684eSMarcel Holtmann 42080493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 42092a611692SJohan Hedberg if (!conn) 42102a611692SJohan Hedberg goto unlock; 42112a611692SJohan Hedberg 4212c1d4fa7aSJohan Hedberg /* Reset the authentication requirement to unknown */ 4213c1d4fa7aSJohan Hedberg conn->remote_auth = 0xff; 4214c1d4fa7aSJohan Hedberg 42152a611692SJohan Hedberg /* To avoid duplicate auth_failed events to user space we check 42162a611692SJohan Hedberg * the HCI_CONN_AUTH_PEND flag which will be set if we 42172a611692SJohan Hedberg * initiated the authentication. A traditional auth_complete 42182a611692SJohan Hedberg * event gets always produced as initiator and is also mapped to 42192a611692SJohan Hedberg * the mgmt_auth_failed event */ 4220fa1bd918SMikel Astiz if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status) 4221e1e930f5SJohan Hedberg mgmt_auth_failed(conn, ev->status); 42222a611692SJohan Hedberg 422376a68ba0SDavid Herrmann hci_conn_drop(conn); 42240493684eSMarcel Holtmann 42252a611692SJohan Hedberg unlock: 42260493684eSMarcel Holtmann hci_dev_unlock(hdev); 42270493684eSMarcel Holtmann } 42280493684eSMarcel Holtmann 42296039aa73SGustavo Padovan static void hci_remote_host_features_evt(struct hci_dev *hdev, 4230807deac2SGustavo Padovan struct sk_buff *skb) 423141a96212SMarcel Holtmann { 423241a96212SMarcel Holtmann struct hci_ev_remote_host_features *ev = (void *) skb->data; 423341a96212SMarcel Holtmann struct inquiry_entry *ie; 4234cad718edSJohan Hedberg struct hci_conn *conn; 423541a96212SMarcel Holtmann 423641a96212SMarcel Holtmann BT_DBG("%s", hdev->name); 423741a96212SMarcel Holtmann 423841a96212SMarcel Holtmann hci_dev_lock(hdev); 423941a96212SMarcel Holtmann 4240cad718edSJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 4241cad718edSJohan Hedberg if (conn) 4242cad718edSJohan Hedberg memcpy(conn->features[1], ev->features, 8); 4243cad718edSJohan Hedberg 4244cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 4245cc11b9c1SAndrei Emeltchenko if (ie) 424602b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 424741a96212SMarcel Holtmann 424841a96212SMarcel Holtmann hci_dev_unlock(hdev); 424941a96212SMarcel Holtmann } 425041a96212SMarcel Holtmann 42516039aa73SGustavo Padovan static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, 42522763eda6SSzymon Janc struct sk_buff *skb) 42532763eda6SSzymon Janc { 42542763eda6SSzymon Janc struct hci_ev_remote_oob_data_request *ev = (void *) skb->data; 42552763eda6SSzymon Janc struct oob_data *data; 42562763eda6SSzymon Janc 42572763eda6SSzymon Janc BT_DBG("%s", hdev->name); 42582763eda6SSzymon Janc 42592763eda6SSzymon Janc hci_dev_lock(hdev); 42602763eda6SSzymon Janc 4261d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 4262e1ba1f15SSzymon Janc goto unlock; 4263e1ba1f15SSzymon Janc 42646928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, &ev->bdaddr, BDADDR_BREDR); 42656665d057SMarcel Holtmann if (!data) { 42666665d057SMarcel Holtmann struct hci_cp_remote_oob_data_neg_reply cp; 42676665d057SMarcel Holtmann 42686665d057SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 42696665d057SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, 42706665d057SMarcel Holtmann sizeof(cp), &cp); 42716665d057SMarcel Holtmann goto unlock; 42726665d057SMarcel Holtmann } 42736665d057SMarcel Holtmann 4274710f11c0SJohan Hedberg if (bredr_sc_enabled(hdev)) { 4275519ca9d0SMarcel Holtmann struct hci_cp_remote_oob_ext_data_reply cp; 4276519ca9d0SMarcel Holtmann 4277519ca9d0SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 4278d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) { 42796665d057SMarcel Holtmann memset(cp.hash192, 0, sizeof(cp.hash192)); 42806665d057SMarcel Holtmann memset(cp.rand192, 0, sizeof(cp.rand192)); 42816665d057SMarcel Holtmann } else { 4282519ca9d0SMarcel Holtmann memcpy(cp.hash192, data->hash192, sizeof(cp.hash192)); 428338da1703SJohan Hedberg memcpy(cp.rand192, data->rand192, sizeof(cp.rand192)); 42846665d057SMarcel Holtmann } 4285519ca9d0SMarcel Holtmann memcpy(cp.hash256, data->hash256, sizeof(cp.hash256)); 428638da1703SJohan Hedberg memcpy(cp.rand256, data->rand256, sizeof(cp.rand256)); 4287519ca9d0SMarcel Holtmann 4288519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY, 4289519ca9d0SMarcel Holtmann sizeof(cp), &cp); 4290519ca9d0SMarcel Holtmann } else { 42912763eda6SSzymon Janc struct hci_cp_remote_oob_data_reply cp; 42922763eda6SSzymon Janc 42932763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr); 4294519ca9d0SMarcel Holtmann memcpy(cp.hash, data->hash192, sizeof(cp.hash)); 429538da1703SJohan Hedberg memcpy(cp.rand, data->rand192, sizeof(cp.rand)); 42962763eda6SSzymon Janc 4297519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, 4298519ca9d0SMarcel Holtmann sizeof(cp), &cp); 4299519ca9d0SMarcel Holtmann } 43002763eda6SSzymon Janc 4301e1ba1f15SSzymon Janc unlock: 43022763eda6SSzymon Janc hci_dev_unlock(hdev); 43032763eda6SSzymon Janc } 43042763eda6SSzymon Janc 4305a77a6a14SArron Wang #if IS_ENABLED(CONFIG_BT_HS) 4306a77a6a14SArron Wang static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb) 4307a77a6a14SArron Wang { 4308a77a6a14SArron Wang struct hci_ev_channel_selected *ev = (void *)skb->data; 4309a77a6a14SArron Wang struct hci_conn *hcon; 4310a77a6a14SArron Wang 4311a77a6a14SArron Wang BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle); 4312a77a6a14SArron Wang 4313a77a6a14SArron Wang skb_pull(skb, sizeof(*ev)); 4314a77a6a14SArron Wang 4315a77a6a14SArron Wang hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 4316a77a6a14SArron Wang if (!hcon) 4317a77a6a14SArron Wang return; 4318a77a6a14SArron Wang 4319a77a6a14SArron Wang amp_read_loc_assoc_final_data(hdev, hcon); 4320a77a6a14SArron Wang } 4321a77a6a14SArron Wang 4322d5e91192SAndrei Emeltchenko static void hci_phy_link_complete_evt(struct hci_dev *hdev, 4323d5e91192SAndrei Emeltchenko struct sk_buff *skb) 4324d5e91192SAndrei Emeltchenko { 4325d5e91192SAndrei Emeltchenko struct hci_ev_phy_link_complete *ev = (void *) skb->data; 4326d5e91192SAndrei Emeltchenko struct hci_conn *hcon, *bredr_hcon; 4327d5e91192SAndrei Emeltchenko 4328d5e91192SAndrei Emeltchenko BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle, 4329d5e91192SAndrei Emeltchenko ev->status); 4330d5e91192SAndrei Emeltchenko 4331d5e91192SAndrei Emeltchenko hci_dev_lock(hdev); 4332d5e91192SAndrei Emeltchenko 4333d5e91192SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 4334d5e91192SAndrei Emeltchenko if (!hcon) { 4335d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 4336d5e91192SAndrei Emeltchenko return; 4337d5e91192SAndrei Emeltchenko } 4338d5e91192SAndrei Emeltchenko 4339d5e91192SAndrei Emeltchenko if (ev->status) { 4340d5e91192SAndrei Emeltchenko hci_conn_del(hcon); 4341d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 4342d5e91192SAndrei Emeltchenko return; 4343d5e91192SAndrei Emeltchenko } 4344d5e91192SAndrei Emeltchenko 4345d5e91192SAndrei Emeltchenko bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon; 4346d5e91192SAndrei Emeltchenko 4347d5e91192SAndrei Emeltchenko hcon->state = BT_CONNECTED; 4348d5e91192SAndrei Emeltchenko bacpy(&hcon->dst, &bredr_hcon->dst); 4349d5e91192SAndrei Emeltchenko 4350d5e91192SAndrei Emeltchenko hci_conn_hold(hcon); 4351d5e91192SAndrei Emeltchenko hcon->disc_timeout = HCI_DISCONN_TIMEOUT; 435276a68ba0SDavid Herrmann hci_conn_drop(hcon); 4353d5e91192SAndrei Emeltchenko 435423b9ceb7SMarcel Holtmann hci_debugfs_create_conn(hcon); 4355d5e91192SAndrei Emeltchenko hci_conn_add_sysfs(hcon); 4356d5e91192SAndrei Emeltchenko 4357cf70ff22SAndrei Emeltchenko amp_physical_cfm(bredr_hcon, hcon); 4358cf70ff22SAndrei Emeltchenko 4359d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 4360d5e91192SAndrei Emeltchenko } 4361d5e91192SAndrei Emeltchenko 436227695fb4SAndrei Emeltchenko static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 436327695fb4SAndrei Emeltchenko { 436427695fb4SAndrei Emeltchenko struct hci_ev_logical_link_complete *ev = (void *) skb->data; 436527695fb4SAndrei Emeltchenko struct hci_conn *hcon; 436627695fb4SAndrei Emeltchenko struct hci_chan *hchan; 436727695fb4SAndrei Emeltchenko struct amp_mgr *mgr; 436827695fb4SAndrei Emeltchenko 436927695fb4SAndrei Emeltchenko BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x", 437027695fb4SAndrei Emeltchenko hdev->name, le16_to_cpu(ev->handle), ev->phy_handle, 437127695fb4SAndrei Emeltchenko ev->status); 437227695fb4SAndrei Emeltchenko 437327695fb4SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 437427695fb4SAndrei Emeltchenko if (!hcon) 437527695fb4SAndrei Emeltchenko return; 437627695fb4SAndrei Emeltchenko 437727695fb4SAndrei Emeltchenko /* Create AMP hchan */ 437827695fb4SAndrei Emeltchenko hchan = hci_chan_create(hcon); 437927695fb4SAndrei Emeltchenko if (!hchan) 438027695fb4SAndrei Emeltchenko return; 438127695fb4SAndrei Emeltchenko 438227695fb4SAndrei Emeltchenko hchan->handle = le16_to_cpu(ev->handle); 438327695fb4SAndrei Emeltchenko 438427695fb4SAndrei Emeltchenko BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan); 438527695fb4SAndrei Emeltchenko 438627695fb4SAndrei Emeltchenko mgr = hcon->amp_mgr; 438727695fb4SAndrei Emeltchenko if (mgr && mgr->bredr_chan) { 438827695fb4SAndrei Emeltchenko struct l2cap_chan *bredr_chan = mgr->bredr_chan; 438927695fb4SAndrei Emeltchenko 439027695fb4SAndrei Emeltchenko l2cap_chan_lock(bredr_chan); 439127695fb4SAndrei Emeltchenko 439227695fb4SAndrei Emeltchenko bredr_chan->conn->mtu = hdev->block_mtu; 439327695fb4SAndrei Emeltchenko l2cap_logical_cfm(bredr_chan, hchan, 0); 439427695fb4SAndrei Emeltchenko hci_conn_hold(hcon); 439527695fb4SAndrei Emeltchenko 439627695fb4SAndrei Emeltchenko l2cap_chan_unlock(bredr_chan); 439727695fb4SAndrei Emeltchenko } 439827695fb4SAndrei Emeltchenko } 439927695fb4SAndrei Emeltchenko 4400606e2a10SAndrei Emeltchenko static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev, 4401606e2a10SAndrei Emeltchenko struct sk_buff *skb) 4402606e2a10SAndrei Emeltchenko { 4403606e2a10SAndrei Emeltchenko struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data; 4404606e2a10SAndrei Emeltchenko struct hci_chan *hchan; 4405606e2a10SAndrei Emeltchenko 4406606e2a10SAndrei Emeltchenko BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name, 4407606e2a10SAndrei Emeltchenko le16_to_cpu(ev->handle), ev->status); 4408606e2a10SAndrei Emeltchenko 4409606e2a10SAndrei Emeltchenko if (ev->status) 4410606e2a10SAndrei Emeltchenko return; 4411606e2a10SAndrei Emeltchenko 4412606e2a10SAndrei Emeltchenko hci_dev_lock(hdev); 4413606e2a10SAndrei Emeltchenko 4414606e2a10SAndrei Emeltchenko hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle)); 4415606e2a10SAndrei Emeltchenko if (!hchan) 4416606e2a10SAndrei Emeltchenko goto unlock; 4417606e2a10SAndrei Emeltchenko 4418606e2a10SAndrei Emeltchenko amp_destroy_logical_link(hchan, ev->reason); 4419606e2a10SAndrei Emeltchenko 4420606e2a10SAndrei Emeltchenko unlock: 4421606e2a10SAndrei Emeltchenko hci_dev_unlock(hdev); 4422606e2a10SAndrei Emeltchenko } 4423606e2a10SAndrei Emeltchenko 44249eef6b3aSAndrei Emeltchenko static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, 44259eef6b3aSAndrei Emeltchenko struct sk_buff *skb) 44269eef6b3aSAndrei Emeltchenko { 44279eef6b3aSAndrei Emeltchenko struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data; 44289eef6b3aSAndrei Emeltchenko struct hci_conn *hcon; 44299eef6b3aSAndrei Emeltchenko 44309eef6b3aSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 44319eef6b3aSAndrei Emeltchenko 44329eef6b3aSAndrei Emeltchenko if (ev->status) 44339eef6b3aSAndrei Emeltchenko return; 44349eef6b3aSAndrei Emeltchenko 44359eef6b3aSAndrei Emeltchenko hci_dev_lock(hdev); 44369eef6b3aSAndrei Emeltchenko 44379eef6b3aSAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 44389eef6b3aSAndrei Emeltchenko if (hcon) { 44399eef6b3aSAndrei Emeltchenko hcon->state = BT_CLOSED; 44409eef6b3aSAndrei Emeltchenko hci_conn_del(hcon); 44419eef6b3aSAndrei Emeltchenko } 44429eef6b3aSAndrei Emeltchenko 44439eef6b3aSAndrei Emeltchenko hci_dev_unlock(hdev); 44449eef6b3aSAndrei Emeltchenko } 4445a77a6a14SArron Wang #endif 44469eef6b3aSAndrei Emeltchenko 44476039aa73SGustavo Padovan static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 4448fcd89c09SVille Tervo { 4449fcd89c09SVille Tervo struct hci_ev_le_conn_complete *ev = (void *) skb->data; 4450912b42efSJohan Hedberg struct hci_conn_params *params; 4451fcd89c09SVille Tervo struct hci_conn *conn; 445268d6f6deSJohan Hedberg struct smp_irk *irk; 4453837d502eSJohan Hedberg u8 addr_type; 4454fcd89c09SVille Tervo 44559f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 4456fcd89c09SVille Tervo 4457fcd89c09SVille Tervo hci_dev_lock(hdev); 4458fcd89c09SVille Tervo 4459fbd96c15SJohan Hedberg /* All controllers implicitly stop advertising in the event of a 4460fbd96c15SJohan Hedberg * connection, so ensure that the state bit is cleared. 4461fbd96c15SJohan Hedberg */ 4462a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ADV); 4463fbd96c15SJohan Hedberg 4464e7d9ab73SJakub Pawlowski conn = hci_lookup_le_connect(hdev); 4465b62f328bSVille Tervo if (!conn) { 4466a5c4e309SJohan Hedberg conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr, ev->role); 4467b62f328bSVille Tervo if (!conn) { 4468b62f328bSVille Tervo BT_ERR("No memory for new connection"); 4469230fd16aSAndre Guedes goto unlock; 4470b62f328bSVille Tervo } 447129b7988aSAndre Guedes 447229b7988aSAndre Guedes conn->dst_type = ev->bdaddr_type; 4473b9b343d2SAndre Guedes 4474cb1d68f7SJohan Hedberg /* If we didn't have a hci_conn object previously 4475cb1d68f7SJohan Hedberg * but we're in master role this must be something 4476cb1d68f7SJohan Hedberg * initiated using a white list. Since white list based 4477cb1d68f7SJohan Hedberg * connections are not "first class citizens" we don't 4478cb1d68f7SJohan Hedberg * have full tracking of them. Therefore, we go ahead 4479cb1d68f7SJohan Hedberg * with a "best effort" approach of determining the 4480cb1d68f7SJohan Hedberg * initiator address based on the HCI_PRIVACY flag. 4481cb1d68f7SJohan Hedberg */ 4482cb1d68f7SJohan Hedberg if (conn->out) { 4483cb1d68f7SJohan Hedberg conn->resp_addr_type = ev->bdaddr_type; 4484cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &ev->bdaddr); 4485d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PRIVACY)) { 4486cb1d68f7SJohan Hedberg conn->init_addr_type = ADDR_LE_DEV_RANDOM; 4487cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->rpa); 4488cb1d68f7SJohan Hedberg } else { 4489cb1d68f7SJohan Hedberg hci_copy_identity_address(hdev, 4490cb1d68f7SJohan Hedberg &conn->init_addr, 4491cb1d68f7SJohan Hedberg &conn->init_addr_type); 4492cb1d68f7SJohan Hedberg } 449380c24ab8SJohan Hedberg } 4494cb1d68f7SJohan Hedberg } else { 449580c24ab8SJohan Hedberg cancel_delayed_work(&conn->le_conn_timeout); 449680c24ab8SJohan Hedberg } 449780c24ab8SJohan Hedberg 449880c24ab8SJohan Hedberg if (!conn->out) { 4499cb1d68f7SJohan Hedberg /* Set the responder (our side) address type based on 4500cb1d68f7SJohan Hedberg * the advertising address type. 4501cb1d68f7SJohan Hedberg */ 4502cb1d68f7SJohan Hedberg conn->resp_addr_type = hdev->adv_addr_type; 4503cb1d68f7SJohan Hedberg if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) 4504cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &hdev->random_addr); 4505cb1d68f7SJohan Hedberg else 4506cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &hdev->bdaddr); 4507cb1d68f7SJohan Hedberg 4508cb1d68f7SJohan Hedberg conn->init_addr_type = ev->bdaddr_type; 4509cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &ev->bdaddr); 4510a720d735SMarcel Holtmann 4511a720d735SMarcel Holtmann /* For incoming connections, set the default minimum 4512a720d735SMarcel Holtmann * and maximum connection interval. They will be used 4513a720d735SMarcel Holtmann * to check if the parameters are in range and if not 4514a720d735SMarcel Holtmann * trigger the connection update procedure. 4515a720d735SMarcel Holtmann */ 4516a720d735SMarcel Holtmann conn->le_conn_min_interval = hdev->le_conn_min_interval; 4517a720d735SMarcel Holtmann conn->le_conn_max_interval = hdev->le_conn_max_interval; 4518cb1d68f7SJohan Hedberg } 45197be2edbbSJohan Hedberg 4520edb4b466SMarcel Holtmann /* Lookup the identity address from the stored connection 4521edb4b466SMarcel Holtmann * address and address type. 4522edb4b466SMarcel Holtmann * 4523edb4b466SMarcel Holtmann * When establishing connections to an identity address, the 4524edb4b466SMarcel Holtmann * connection procedure will store the resolvable random 4525edb4b466SMarcel Holtmann * address first. Now if it can be converted back into the 4526edb4b466SMarcel Holtmann * identity address, start using the identity address from 4527edb4b466SMarcel Holtmann * now on. 4528edb4b466SMarcel Holtmann */ 4529edb4b466SMarcel Holtmann irk = hci_get_irk(hdev, &conn->dst, conn->dst_type); 453068d6f6deSJohan Hedberg if (irk) { 453168d6f6deSJohan Hedberg bacpy(&conn->dst, &irk->bdaddr); 453268d6f6deSJohan Hedberg conn->dst_type = irk->addr_type; 453368d6f6deSJohan Hedberg } 453468d6f6deSJohan Hedberg 45352d3c2260SJohan Hedberg if (ev->status) { 45362d3c2260SJohan Hedberg hci_le_conn_failed(conn, ev->status); 4537837d502eSJohan Hedberg goto unlock; 4538837d502eSJohan Hedberg } 4539837d502eSJohan Hedberg 454008853f18SJohan Hedberg if (conn->dst_type == ADDR_LE_DEV_PUBLIC) 454108853f18SJohan Hedberg addr_type = BDADDR_LE_PUBLIC; 454208853f18SJohan Hedberg else 454308853f18SJohan Hedberg addr_type = BDADDR_LE_RANDOM; 454408853f18SJohan Hedberg 45452d3c2260SJohan Hedberg /* Drop the connection if the device is blocked */ 45462d3c2260SJohan Hedberg if (hci_bdaddr_list_lookup(&hdev->blacklist, &conn->dst, addr_type)) { 45472d3c2260SJohan Hedberg hci_conn_drop(conn); 4548cd17decbSAndre Guedes goto unlock; 4549cd17decbSAndre Guedes } 4550cd17decbSAndre Guedes 4551b644ba33SJohan Hedberg if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 455248ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, NULL, 0); 455383bc71b4SVinicius Costa Gomes 45547b5c0d52SVinicius Costa Gomes conn->sec_level = BT_SECURITY_LOW; 4555fcd89c09SVille Tervo conn->handle = __le16_to_cpu(ev->handle); 45560fe29fd1SMarcel Holtmann conn->state = BT_CONFIG; 4557fcd89c09SVille Tervo 4558e04fde60SMarcel Holtmann conn->le_conn_interval = le16_to_cpu(ev->interval); 4559e04fde60SMarcel Holtmann conn->le_conn_latency = le16_to_cpu(ev->latency); 4560e04fde60SMarcel Holtmann conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout); 4561e04fde60SMarcel Holtmann 456223b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn); 4563fcd89c09SVille Tervo hci_conn_add_sysfs(conn); 4564fcd89c09SVille Tervo 45650fe29fd1SMarcel Holtmann if (!ev->status) { 45660fe29fd1SMarcel Holtmann /* The remote features procedure is defined for master 45670fe29fd1SMarcel Holtmann * role only. So only in case of an initiated connection 45680fe29fd1SMarcel Holtmann * request the remote features. 45690fe29fd1SMarcel Holtmann * 45700fe29fd1SMarcel Holtmann * If the local controller supports slave-initiated features 45710fe29fd1SMarcel Holtmann * exchange, then requesting the remote features in slave 45720fe29fd1SMarcel Holtmann * role is possible. Otherwise just transition into the 45730fe29fd1SMarcel Holtmann * connected state without requesting the remote features. 45740fe29fd1SMarcel Holtmann */ 45750fe29fd1SMarcel Holtmann if (conn->out || 45760fe29fd1SMarcel Holtmann (hdev->le_features[0] & HCI_LE_SLAVE_FEATURES)) { 45770fe29fd1SMarcel Holtmann struct hci_cp_le_read_remote_features cp; 45780fe29fd1SMarcel Holtmann 45790fe29fd1SMarcel Holtmann cp.handle = __cpu_to_le16(conn->handle); 45800fe29fd1SMarcel Holtmann 45810fe29fd1SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_LE_READ_REMOTE_FEATURES, 45820fe29fd1SMarcel Holtmann sizeof(cp), &cp); 45830fe29fd1SMarcel Holtmann 45840fe29fd1SMarcel Holtmann hci_conn_hold(conn); 45850fe29fd1SMarcel Holtmann } else { 45860fe29fd1SMarcel Holtmann conn->state = BT_CONNECTED; 4587539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 45880fe29fd1SMarcel Holtmann } 45890fe29fd1SMarcel Holtmann } else { 45900fe29fd1SMarcel Holtmann hci_connect_cfm(conn, ev->status); 45910fe29fd1SMarcel Holtmann } 4592fcd89c09SVille Tervo 45935477610fSJohan Hedberg params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst, 45945477610fSJohan Hedberg conn->dst_type); 4595f161dd41SJohan Hedberg if (params) { 459695305baaSJohan Hedberg list_del_init(¶ms->action); 4597f161dd41SJohan Hedberg if (params->conn) { 4598f161dd41SJohan Hedberg hci_conn_drop(params->conn); 4599f8aaf9b6SJohan Hedberg hci_conn_put(params->conn); 4600f161dd41SJohan Hedberg params->conn = NULL; 4601f161dd41SJohan Hedberg } 4602f161dd41SJohan Hedberg } 4603a4790dbdSAndre Guedes 4604fcd89c09SVille Tervo unlock: 4605223683a5SJohan Hedberg hci_update_background_scan(hdev); 4606fcd89c09SVille Tervo hci_dev_unlock(hdev); 4607fcd89c09SVille Tervo } 4608fcd89c09SVille Tervo 46091855d92dSMarcel Holtmann static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, 46101855d92dSMarcel Holtmann struct sk_buff *skb) 46111855d92dSMarcel Holtmann { 46121855d92dSMarcel Holtmann struct hci_ev_le_conn_update_complete *ev = (void *) skb->data; 46131855d92dSMarcel Holtmann struct hci_conn *conn; 46141855d92dSMarcel Holtmann 46151855d92dSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 46161855d92dSMarcel Holtmann 46171855d92dSMarcel Holtmann if (ev->status) 46181855d92dSMarcel Holtmann return; 46191855d92dSMarcel Holtmann 46201855d92dSMarcel Holtmann hci_dev_lock(hdev); 46211855d92dSMarcel Holtmann 46221855d92dSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 46231855d92dSMarcel Holtmann if (conn) { 46241855d92dSMarcel Holtmann conn->le_conn_interval = le16_to_cpu(ev->interval); 46251855d92dSMarcel Holtmann conn->le_conn_latency = le16_to_cpu(ev->latency); 46261855d92dSMarcel Holtmann conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout); 46271855d92dSMarcel Holtmann } 46281855d92dSMarcel Holtmann 46291855d92dSMarcel Holtmann hci_dev_unlock(hdev); 46301855d92dSMarcel Holtmann } 46311855d92dSMarcel Holtmann 4632a4790dbdSAndre Guedes /* This function requires the caller holds hdev->lock */ 4633fd45ada9SAlfonso Acosta static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev, 4634fd45ada9SAlfonso Acosta bdaddr_t *addr, 46351c1abcabSJohan Hedberg u8 addr_type, u8 adv_type) 4636a4790dbdSAndre Guedes { 4637a4790dbdSAndre Guedes struct hci_conn *conn; 46384b9e7e75SMarcel Holtmann struct hci_conn_params *params; 4639a4790dbdSAndre Guedes 46401c1abcabSJohan Hedberg /* If the event is not connectable don't proceed further */ 46411c1abcabSJohan Hedberg if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND) 4642fd45ada9SAlfonso Acosta return NULL; 46431c1abcabSJohan Hedberg 46441c1abcabSJohan Hedberg /* Ignore if the device is blocked */ 4645dcc36c16SJohan Hedberg if (hci_bdaddr_list_lookup(&hdev->blacklist, addr, addr_type)) 4646fd45ada9SAlfonso Acosta return NULL; 46471c1abcabSJohan Hedberg 4648f99353cfSJohan Hedberg /* Most controller will fail if we try to create new connections 4649f99353cfSJohan Hedberg * while we have an existing one in slave role. 4650f99353cfSJohan Hedberg */ 4651f99353cfSJohan Hedberg if (hdev->conn_hash.le_num_slave > 0) 4652fd45ada9SAlfonso Acosta return NULL; 4653f99353cfSJohan Hedberg 46541c1abcabSJohan Hedberg /* If we're not connectable only connect devices that we have in 46551c1abcabSJohan Hedberg * our pend_le_conns list. 46561c1abcabSJohan Hedberg */ 465749c50922SJohan Hedberg params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr, 465849c50922SJohan Hedberg addr_type); 46594b9e7e75SMarcel Holtmann if (!params) 4660fd45ada9SAlfonso Acosta return NULL; 4661a4790dbdSAndre Guedes 466228a667c9SJakub Pawlowski if (!params->explicit_connect) { 46634b9e7e75SMarcel Holtmann switch (params->auto_connect) { 46644b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_DIRECT: 46654b9e7e75SMarcel Holtmann /* Only devices advertising with ADV_DIRECT_IND are 46664b9e7e75SMarcel Holtmann * triggering a connection attempt. This is allowing 46674b9e7e75SMarcel Holtmann * incoming connections from slave devices. 46684b9e7e75SMarcel Holtmann */ 46694b9e7e75SMarcel Holtmann if (adv_type != LE_ADV_DIRECT_IND) 4670fd45ada9SAlfonso Acosta return NULL; 46714b9e7e75SMarcel Holtmann break; 46724b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_ALWAYS: 46734b9e7e75SMarcel Holtmann /* Devices advertising with ADV_IND or ADV_DIRECT_IND 46744b9e7e75SMarcel Holtmann * are triggering a connection attempt. This means 46754b9e7e75SMarcel Holtmann * that incoming connectioms from slave device are 46764b9e7e75SMarcel Holtmann * accepted and also outgoing connections to slave 46774b9e7e75SMarcel Holtmann * devices are established when found. 46784b9e7e75SMarcel Holtmann */ 46794b9e7e75SMarcel Holtmann break; 46804b9e7e75SMarcel Holtmann default: 4681fd45ada9SAlfonso Acosta return NULL; 46824b9e7e75SMarcel Holtmann } 468328a667c9SJakub Pawlowski } 46844b9e7e75SMarcel Holtmann 4685a4790dbdSAndre Guedes conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, 4686e804d25dSJohan Hedberg HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER); 4687f161dd41SJohan Hedberg if (!IS_ERR(conn)) { 468828a667c9SJakub Pawlowski /* If HCI_AUTO_CONN_EXPLICIT is set, conn is already owned 468928a667c9SJakub Pawlowski * by higher layer that tried to connect, if no then 469028a667c9SJakub Pawlowski * store the pointer since we don't really have any 4691f161dd41SJohan Hedberg * other owner of the object besides the params that 4692f161dd41SJohan Hedberg * triggered it. This way we can abort the connection if 4693f161dd41SJohan Hedberg * the parameters get removed and keep the reference 4694f161dd41SJohan Hedberg * count consistent once the connection is established. 4695f161dd41SJohan Hedberg */ 469628a667c9SJakub Pawlowski 469728a667c9SJakub Pawlowski if (!params->explicit_connect) 4698f8aaf9b6SJohan Hedberg params->conn = hci_conn_get(conn); 469928a667c9SJakub Pawlowski 4700fd45ada9SAlfonso Acosta return conn; 4701f161dd41SJohan Hedberg } 4702a4790dbdSAndre Guedes 4703a4790dbdSAndre Guedes switch (PTR_ERR(conn)) { 4704a4790dbdSAndre Guedes case -EBUSY: 4705a4790dbdSAndre Guedes /* If hci_connect() returns -EBUSY it means there is already 4706a4790dbdSAndre Guedes * an LE connection attempt going on. Since controllers don't 4707a4790dbdSAndre Guedes * support more than one connection attempt at the time, we 4708a4790dbdSAndre Guedes * don't consider this an error case. 4709a4790dbdSAndre Guedes */ 4710a4790dbdSAndre Guedes break; 4711a4790dbdSAndre Guedes default: 4712a4790dbdSAndre Guedes BT_DBG("Failed to connect: err %ld", PTR_ERR(conn)); 4713fd45ada9SAlfonso Acosta return NULL; 4714a4790dbdSAndre Guedes } 4715fd45ada9SAlfonso Acosta 4716fd45ada9SAlfonso Acosta return NULL; 4717a4790dbdSAndre Guedes } 4718a4790dbdSAndre Guedes 47194af605d8SJohan Hedberg static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, 47202f010b55SMarcel Holtmann u8 bdaddr_type, bdaddr_t *direct_addr, 47212f010b55SMarcel Holtmann u8 direct_addr_type, s8 rssi, u8 *data, u8 len) 47224af605d8SJohan Hedberg { 4723b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 47241c1abcabSJohan Hedberg struct smp_irk *irk; 4725fd45ada9SAlfonso Acosta struct hci_conn *conn; 4726474ee066SJohan Hedberg bool match; 4727c70a7e4cSMarcel Holtmann u32 flags; 47286818375eSSzymon Janc u8 *ptr, real_len; 47296818375eSSzymon Janc 47306818375eSSzymon Janc /* Find the end of the data in case the report contains padded zero 47316818375eSSzymon Janc * bytes at the end causing an invalid length value. 47326818375eSSzymon Janc * 47336818375eSSzymon Janc * When data is NULL, len is 0 so there is no need for extra ptr 47346818375eSSzymon Janc * check as 'ptr < data + 0' is already false in such case. 47356818375eSSzymon Janc */ 47366818375eSSzymon Janc for (ptr = data; ptr < data + len && *ptr; ptr += *ptr + 1) { 47376818375eSSzymon Janc if (ptr + 1 + *ptr > data + len) 47386818375eSSzymon Janc break; 47396818375eSSzymon Janc } 47406818375eSSzymon Janc 47416818375eSSzymon Janc real_len = ptr - data; 47426818375eSSzymon Janc 47436818375eSSzymon Janc /* Adjust for actual length */ 47446818375eSSzymon Janc if (len != real_len) { 47456818375eSSzymon Janc BT_ERR_RATELIMITED("%s advertising data length corrected", 47466818375eSSzymon Janc hdev->name); 47476818375eSSzymon Janc len = real_len; 47486818375eSSzymon Janc } 4749b9a6328fSJohan Hedberg 47502f010b55SMarcel Holtmann /* If the direct address is present, then this report is from 47512f010b55SMarcel Holtmann * a LE Direct Advertising Report event. In that case it is 47522f010b55SMarcel Holtmann * important to see if the address is matching the local 47532f010b55SMarcel Holtmann * controller address. 47542f010b55SMarcel Holtmann */ 47552f010b55SMarcel Holtmann if (direct_addr) { 47562f010b55SMarcel Holtmann /* Only resolvable random addresses are valid for these 47572f010b55SMarcel Holtmann * kind of reports and others can be ignored. 47582f010b55SMarcel Holtmann */ 47592f010b55SMarcel Holtmann if (!hci_bdaddr_is_rpa(direct_addr, direct_addr_type)) 47602f010b55SMarcel Holtmann return; 47612f010b55SMarcel Holtmann 47622f010b55SMarcel Holtmann /* If the controller is not using resolvable random 47632f010b55SMarcel Holtmann * addresses, then this report can be ignored. 47642f010b55SMarcel Holtmann */ 4765d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_PRIVACY)) 47662f010b55SMarcel Holtmann return; 47672f010b55SMarcel Holtmann 47682f010b55SMarcel Holtmann /* If the local IRK of the controller does not match 47692f010b55SMarcel Holtmann * with the resolvable random address provided, then 47702f010b55SMarcel Holtmann * this report can be ignored. 47712f010b55SMarcel Holtmann */ 47722f010b55SMarcel Holtmann if (!smp_irk_matches(hdev, hdev->irk, direct_addr)) 47732f010b55SMarcel Holtmann return; 47742f010b55SMarcel Holtmann } 47752f010b55SMarcel Holtmann 4776435a13d8SJohan Hedberg /* Check if we need to convert to identity address */ 4777435a13d8SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, bdaddr_type); 4778435a13d8SJohan Hedberg if (irk) { 4779435a13d8SJohan Hedberg bdaddr = &irk->bdaddr; 4780435a13d8SJohan Hedberg bdaddr_type = irk->addr_type; 4781435a13d8SJohan Hedberg } 4782435a13d8SJohan Hedberg 47831c1abcabSJohan Hedberg /* Check if we have been requested to connect to this device */ 4784fd45ada9SAlfonso Acosta conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, type); 4785fd45ada9SAlfonso Acosta if (conn && type == LE_ADV_IND) { 4786fd45ada9SAlfonso Acosta /* Store report for later inclusion by 4787fd45ada9SAlfonso Acosta * mgmt_device_connected 4788fd45ada9SAlfonso Acosta */ 4789fd45ada9SAlfonso Acosta memcpy(conn->le_adv_data, data, len); 4790fd45ada9SAlfonso Acosta conn->le_adv_data_len = len; 4791fd45ada9SAlfonso Acosta } 479299a6768eSJohan Hedberg 47931c1abcabSJohan Hedberg /* Passive scanning shouldn't trigger any device found events, 47941c1abcabSJohan Hedberg * except for devices marked as CONN_REPORT for which we do send 47951c1abcabSJohan Hedberg * device found events. 47961c1abcabSJohan Hedberg */ 47971c1abcabSJohan Hedberg if (hdev->le_scan_type == LE_SCAN_PASSIVE) { 47980d2bf134SJohan Hedberg if (type == LE_ADV_DIRECT_IND) 47990d2bf134SJohan Hedberg return; 48000d2bf134SJohan Hedberg 48013a19b6feSJohan Hedberg if (!hci_pend_le_action_lookup(&hdev->pend_le_reports, 48023a19b6feSJohan Hedberg bdaddr, bdaddr_type)) 48030d2bf134SJohan Hedberg return; 48040d2bf134SJohan Hedberg 48050d2bf134SJohan Hedberg if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND) 48060d2bf134SJohan Hedberg flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 48070d2bf134SJohan Hedberg else 48080d2bf134SJohan Hedberg flags = 0; 48090d2bf134SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 48100d2bf134SJohan Hedberg rssi, flags, data, len, NULL, 0); 481197bf2e99SJohan Hedberg return; 4812ca5c4be7SJohan Hedberg } 48134af605d8SJohan Hedberg 4814c70a7e4cSMarcel Holtmann /* When receiving non-connectable or scannable undirected 4815c70a7e4cSMarcel Holtmann * advertising reports, this means that the remote device is 4816c70a7e4cSMarcel Holtmann * not connectable and then clearly indicate this in the 4817c70a7e4cSMarcel Holtmann * device found event. 4818c70a7e4cSMarcel Holtmann * 4819c70a7e4cSMarcel Holtmann * When receiving a scan response, then there is no way to 4820c70a7e4cSMarcel Holtmann * know if the remote device is connectable or not. However 4821c70a7e4cSMarcel Holtmann * since scan responses are merged with a previously seen 4822c70a7e4cSMarcel Holtmann * advertising report, the flags field from that report 4823c70a7e4cSMarcel Holtmann * will be used. 4824c70a7e4cSMarcel Holtmann * 4825c70a7e4cSMarcel Holtmann * In the really unlikely case that a controller get confused 4826c70a7e4cSMarcel Holtmann * and just sends a scan response event, then it is marked as 4827c70a7e4cSMarcel Holtmann * not connectable as well. 4828c70a7e4cSMarcel Holtmann */ 4829c70a7e4cSMarcel Holtmann if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND || 4830c70a7e4cSMarcel Holtmann type == LE_ADV_SCAN_RSP) 4831c70a7e4cSMarcel Holtmann flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 4832c70a7e4cSMarcel Holtmann else 4833c70a7e4cSMarcel Holtmann flags = 0; 4834c70a7e4cSMarcel Holtmann 4835b9a6328fSJohan Hedberg /* If there's nothing pending either store the data from this 4836b9a6328fSJohan Hedberg * event or send an immediate device found event if the data 4837b9a6328fSJohan Hedberg * should not be stored for later. 4838b9a6328fSJohan Hedberg */ 4839b9a6328fSJohan Hedberg if (!has_pending_adv_report(hdev)) { 4840b9a6328fSJohan Hedberg /* If the report will trigger a SCAN_REQ store it for 4841b9a6328fSJohan Hedberg * later merging. 4842b9a6328fSJohan Hedberg */ 4843b9a6328fSJohan Hedberg if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { 4844b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type, 4845c70a7e4cSMarcel Holtmann rssi, flags, data, len); 4846b9a6328fSJohan Hedberg return; 4847b9a6328fSJohan Hedberg } 4848b9a6328fSJohan Hedberg 4849b9a6328fSJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 4850c70a7e4cSMarcel Holtmann rssi, flags, data, len, NULL, 0); 4851b9a6328fSJohan Hedberg return; 4852b9a6328fSJohan Hedberg } 4853b9a6328fSJohan Hedberg 4854474ee066SJohan Hedberg /* Check if the pending report is for the same device as the new one */ 4855474ee066SJohan Hedberg match = (!bacmp(bdaddr, &d->last_adv_addr) && 4856474ee066SJohan Hedberg bdaddr_type == d->last_adv_addr_type); 4857474ee066SJohan Hedberg 4858b9a6328fSJohan Hedberg /* If the pending data doesn't match this report or this isn't a 4859b9a6328fSJohan Hedberg * scan response (e.g. we got a duplicate ADV_IND) then force 4860b9a6328fSJohan Hedberg * sending of the pending data. 4861b9a6328fSJohan Hedberg */ 4862474ee066SJohan Hedberg if (type != LE_ADV_SCAN_RSP || !match) { 4863474ee066SJohan Hedberg /* Send out whatever is in the cache, but skip duplicates */ 4864474ee066SJohan Hedberg if (!match) 4865b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 4866ff5cd29fSJohan Hedberg d->last_adv_addr_type, NULL, 4867c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags, 4868ff5cd29fSJohan Hedberg d->last_adv_data, 4869474ee066SJohan Hedberg d->last_adv_data_len, NULL, 0); 4870b9a6328fSJohan Hedberg 4871b9a6328fSJohan Hedberg /* If the new report will trigger a SCAN_REQ store it for 4872b9a6328fSJohan Hedberg * later merging. 4873b9a6328fSJohan Hedberg */ 4874b9a6328fSJohan Hedberg if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { 4875b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type, 4876c70a7e4cSMarcel Holtmann rssi, flags, data, len); 4877b9a6328fSJohan Hedberg return; 4878b9a6328fSJohan Hedberg } 4879b9a6328fSJohan Hedberg 4880b9a6328fSJohan Hedberg /* The advertising reports cannot be merged, so clear 4881b9a6328fSJohan Hedberg * the pending report and send out a device found event. 4882b9a6328fSJohan Hedberg */ 4883b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 48845c5b93e4SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 4885c70a7e4cSMarcel Holtmann rssi, flags, data, len, NULL, 0); 4886b9a6328fSJohan Hedberg return; 4887b9a6328fSJohan Hedberg } 4888b9a6328fSJohan Hedberg 4889b9a6328fSJohan Hedberg /* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and 4890b9a6328fSJohan Hedberg * the new event is a SCAN_RSP. We can therefore proceed with 4891b9a6328fSJohan Hedberg * sending a merged device found event. 4892b9a6328fSJohan Hedberg */ 4893b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 4894c70a7e4cSMarcel Holtmann d->last_adv_addr_type, NULL, rssi, d->last_adv_flags, 489542bd6a56SMarcel Holtmann d->last_adv_data, d->last_adv_data_len, data, len); 4896b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 48974af605d8SJohan Hedberg } 48984af605d8SJohan Hedberg 48996039aa73SGustavo Padovan static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) 49009aa04c91SAndre Guedes { 4901e95beb41SAndre Guedes u8 num_reports = skb->data[0]; 4902e95beb41SAndre Guedes void *ptr = &skb->data[1]; 49039aa04c91SAndre Guedes 4904a4790dbdSAndre Guedes hci_dev_lock(hdev); 4905a4790dbdSAndre Guedes 4906e95beb41SAndre Guedes while (num_reports--) { 4907e95beb41SAndre Guedes struct hci_ev_le_advertising_info *ev = ptr; 49084af605d8SJohan Hedberg s8 rssi; 4909a4790dbdSAndre Guedes 49103c9e9195SAndre Guedes rssi = ev->data[ev->length]; 49114af605d8SJohan Hedberg process_adv_report(hdev, ev->evt_type, &ev->bdaddr, 49122f010b55SMarcel Holtmann ev->bdaddr_type, NULL, 0, rssi, 49132f010b55SMarcel Holtmann ev->data, ev->length); 49143c9e9195SAndre Guedes 4915e95beb41SAndre Guedes ptr += sizeof(*ev) + ev->length + 1; 49169aa04c91SAndre Guedes } 4917a4790dbdSAndre Guedes 4918a4790dbdSAndre Guedes hci_dev_unlock(hdev); 49199aa04c91SAndre Guedes } 49209aa04c91SAndre Guedes 49210fe29fd1SMarcel Holtmann static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev, 49220fe29fd1SMarcel Holtmann struct sk_buff *skb) 49230fe29fd1SMarcel Holtmann { 49240fe29fd1SMarcel Holtmann struct hci_ev_le_remote_feat_complete *ev = (void *)skb->data; 49250fe29fd1SMarcel Holtmann struct hci_conn *conn; 49260fe29fd1SMarcel Holtmann 49270fe29fd1SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 49280fe29fd1SMarcel Holtmann 49290fe29fd1SMarcel Holtmann hci_dev_lock(hdev); 49300fe29fd1SMarcel Holtmann 49310fe29fd1SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 49320fe29fd1SMarcel Holtmann if (conn) { 49330fe29fd1SMarcel Holtmann if (!ev->status) 49340fe29fd1SMarcel Holtmann memcpy(conn->features[0], ev->features, 8); 49350fe29fd1SMarcel Holtmann 49360fe29fd1SMarcel Holtmann if (conn->state == BT_CONFIG) { 49370fe29fd1SMarcel Holtmann __u8 status; 49380fe29fd1SMarcel Holtmann 49390fe29fd1SMarcel Holtmann /* If the local controller supports slave-initiated 49400fe29fd1SMarcel Holtmann * features exchange, but the remote controller does 49410fe29fd1SMarcel Holtmann * not, then it is possible that the error code 0x1a 49420fe29fd1SMarcel Holtmann * for unsupported remote feature gets returned. 49430fe29fd1SMarcel Holtmann * 49440fe29fd1SMarcel Holtmann * In this specific case, allow the connection to 49450fe29fd1SMarcel Holtmann * transition into connected state and mark it as 49460fe29fd1SMarcel Holtmann * successful. 49470fe29fd1SMarcel Holtmann */ 49480fe29fd1SMarcel Holtmann if ((hdev->le_features[0] & HCI_LE_SLAVE_FEATURES) && 49490fe29fd1SMarcel Holtmann !conn->out && ev->status == 0x1a) 49500fe29fd1SMarcel Holtmann status = 0x00; 49510fe29fd1SMarcel Holtmann else 49520fe29fd1SMarcel Holtmann status = ev->status; 49530fe29fd1SMarcel Holtmann 49540fe29fd1SMarcel Holtmann conn->state = BT_CONNECTED; 49550fe29fd1SMarcel Holtmann hci_connect_cfm(conn, status); 49560fe29fd1SMarcel Holtmann hci_conn_drop(conn); 49570fe29fd1SMarcel Holtmann } 49580fe29fd1SMarcel Holtmann } 49590fe29fd1SMarcel Holtmann 49600fe29fd1SMarcel Holtmann hci_dev_unlock(hdev); 49610fe29fd1SMarcel Holtmann } 49620fe29fd1SMarcel Holtmann 49636039aa73SGustavo Padovan static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 4964a7a595f6SVinicius Costa Gomes { 4965a7a595f6SVinicius Costa Gomes struct hci_ev_le_ltk_req *ev = (void *) skb->data; 4966a7a595f6SVinicius Costa Gomes struct hci_cp_le_ltk_reply cp; 4967bea710feSVinicius Costa Gomes struct hci_cp_le_ltk_neg_reply neg; 4968a7a595f6SVinicius Costa Gomes struct hci_conn *conn; 4969c9839a11SVinicius Costa Gomes struct smp_ltk *ltk; 4970a7a595f6SVinicius Costa Gomes 49719f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle)); 4972a7a595f6SVinicius Costa Gomes 4973a7a595f6SVinicius Costa Gomes hci_dev_lock(hdev); 4974a7a595f6SVinicius Costa Gomes 4975a7a595f6SVinicius Costa Gomes conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 4976bea710feSVinicius Costa Gomes if (conn == NULL) 4977bea710feSVinicius Costa Gomes goto not_found; 4978a7a595f6SVinicius Costa Gomes 4979f3a73d97SJohan Hedberg ltk = hci_find_ltk(hdev, &conn->dst, conn->dst_type, conn->role); 49805378bc56SJohan Hedberg if (!ltk) 4981bea710feSVinicius Costa Gomes goto not_found; 4982bea710feSVinicius Costa Gomes 49835378bc56SJohan Hedberg if (smp_ltk_is_sc(ltk)) { 49845378bc56SJohan Hedberg /* With SC both EDiv and Rand are set to zero */ 49855378bc56SJohan Hedberg if (ev->ediv || ev->rand) 49865378bc56SJohan Hedberg goto not_found; 49875378bc56SJohan Hedberg } else { 49885378bc56SJohan Hedberg /* For non-SC keys check that EDiv and Rand match */ 49895378bc56SJohan Hedberg if (ev->ediv != ltk->ediv || ev->rand != ltk->rand) 49905378bc56SJohan Hedberg goto not_found; 49915378bc56SJohan Hedberg } 49925378bc56SJohan Hedberg 49938b76ce34SJohan Hedberg memcpy(cp.ltk, ltk->val, ltk->enc_size); 49948b76ce34SJohan Hedberg memset(cp.ltk + ltk->enc_size, 0, sizeof(cp.ltk) - ltk->enc_size); 4995a7a595f6SVinicius Costa Gomes cp.handle = cpu_to_le16(conn->handle); 4996c9839a11SVinicius Costa Gomes 4997a6f7833cSJohan Hedberg conn->pending_sec_level = smp_ltk_sec_level(ltk); 4998a7a595f6SVinicius Costa Gomes 499989cbb4daSAndre Guedes conn->enc_key_size = ltk->enc_size; 5000a7a595f6SVinicius Costa Gomes 5001a7a595f6SVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); 5002a7a595f6SVinicius Costa Gomes 50035981a882SClaudio Takahasi /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a 50045981a882SClaudio Takahasi * temporary key used to encrypt a connection following 50055981a882SClaudio Takahasi * pairing. It is used during the Encrypted Session Setup to 50065981a882SClaudio Takahasi * distribute the keys. Later, security can be re-established 50075981a882SClaudio Takahasi * using a distributed LTK. 50085981a882SClaudio Takahasi */ 50092ceba539SJohan Hedberg if (ltk->type == SMP_STK) { 5010fe59a05fSJohan Hedberg set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); 5011970d0f1bSJohan Hedberg list_del_rcu(<k->list); 5012970d0f1bSJohan Hedberg kfree_rcu(ltk, rcu); 5013fe59a05fSJohan Hedberg } else { 5014fe59a05fSJohan Hedberg clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); 5015c9839a11SVinicius Costa Gomes } 5016c9839a11SVinicius Costa Gomes 5017a7a595f6SVinicius Costa Gomes hci_dev_unlock(hdev); 5018bea710feSVinicius Costa Gomes 5019bea710feSVinicius Costa Gomes return; 5020bea710feSVinicius Costa Gomes 5021bea710feSVinicius Costa Gomes not_found: 5022bea710feSVinicius Costa Gomes neg.handle = ev->handle; 5023bea710feSVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg); 5024bea710feSVinicius Costa Gomes hci_dev_unlock(hdev); 5025a7a595f6SVinicius Costa Gomes } 5026a7a595f6SVinicius Costa Gomes 50278e75b46aSAndre Guedes static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle, 50288e75b46aSAndre Guedes u8 reason) 50298e75b46aSAndre Guedes { 50308e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_neg_reply cp; 50318e75b46aSAndre Guedes 50328e75b46aSAndre Guedes cp.handle = cpu_to_le16(handle); 50338e75b46aSAndre Guedes cp.reason = reason; 50348e75b46aSAndre Guedes 50358e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp), 50368e75b46aSAndre Guedes &cp); 50378e75b46aSAndre Guedes } 50388e75b46aSAndre Guedes 50398e75b46aSAndre Guedes static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, 50408e75b46aSAndre Guedes struct sk_buff *skb) 50418e75b46aSAndre Guedes { 50428e75b46aSAndre Guedes struct hci_ev_le_remote_conn_param_req *ev = (void *) skb->data; 50438e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_reply cp; 50448e75b46aSAndre Guedes struct hci_conn *hcon; 50458e75b46aSAndre Guedes u16 handle, min, max, latency, timeout; 50468e75b46aSAndre Guedes 50478e75b46aSAndre Guedes handle = le16_to_cpu(ev->handle); 50488e75b46aSAndre Guedes min = le16_to_cpu(ev->interval_min); 50498e75b46aSAndre Guedes max = le16_to_cpu(ev->interval_max); 50508e75b46aSAndre Guedes latency = le16_to_cpu(ev->latency); 50518e75b46aSAndre Guedes timeout = le16_to_cpu(ev->timeout); 50528e75b46aSAndre Guedes 50538e75b46aSAndre Guedes hcon = hci_conn_hash_lookup_handle(hdev, handle); 50548e75b46aSAndre Guedes if (!hcon || hcon->state != BT_CONNECTED) 50558e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle, 50568e75b46aSAndre Guedes HCI_ERROR_UNKNOWN_CONN_ID); 50578e75b46aSAndre Guedes 50588e75b46aSAndre Guedes if (hci_check_conn_params(min, max, latency, timeout)) 50598e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle, 50608e75b46aSAndre Guedes HCI_ERROR_INVALID_LL_PARAMS); 50618e75b46aSAndre Guedes 506240bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) { 5063348d50b8SJohan Hedberg struct hci_conn_params *params; 5064f4869e2aSJohan Hedberg u8 store_hint; 5065348d50b8SJohan Hedberg 5066348d50b8SJohan Hedberg hci_dev_lock(hdev); 5067348d50b8SJohan Hedberg 5068348d50b8SJohan Hedberg params = hci_conn_params_lookup(hdev, &hcon->dst, 5069348d50b8SJohan Hedberg hcon->dst_type); 5070348d50b8SJohan Hedberg if (params) { 5071348d50b8SJohan Hedberg params->conn_min_interval = min; 5072348d50b8SJohan Hedberg params->conn_max_interval = max; 5073348d50b8SJohan Hedberg params->conn_latency = latency; 5074348d50b8SJohan Hedberg params->supervision_timeout = timeout; 5075f4869e2aSJohan Hedberg store_hint = 0x01; 5076f4869e2aSJohan Hedberg } else{ 5077f4869e2aSJohan Hedberg store_hint = 0x00; 5078348d50b8SJohan Hedberg } 5079348d50b8SJohan Hedberg 5080348d50b8SJohan Hedberg hci_dev_unlock(hdev); 5081348d50b8SJohan Hedberg 5082f4869e2aSJohan Hedberg mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type, 5083f4869e2aSJohan Hedberg store_hint, min, max, latency, timeout); 5084348d50b8SJohan Hedberg } 5085ffb5a827SAndre Guedes 50868e75b46aSAndre Guedes cp.handle = ev->handle; 50878e75b46aSAndre Guedes cp.interval_min = ev->interval_min; 50888e75b46aSAndre Guedes cp.interval_max = ev->interval_max; 50898e75b46aSAndre Guedes cp.latency = ev->latency; 50908e75b46aSAndre Guedes cp.timeout = ev->timeout; 50918e75b46aSAndre Guedes cp.min_ce_len = 0; 50928e75b46aSAndre Guedes cp.max_ce_len = 0; 50938e75b46aSAndre Guedes 50948e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp); 50958e75b46aSAndre Guedes } 50968e75b46aSAndre Guedes 50972f010b55SMarcel Holtmann static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, 50982f010b55SMarcel Holtmann struct sk_buff *skb) 50992f010b55SMarcel Holtmann { 51002f010b55SMarcel Holtmann u8 num_reports = skb->data[0]; 51012f010b55SMarcel Holtmann void *ptr = &skb->data[1]; 51022f010b55SMarcel Holtmann 51032f010b55SMarcel Holtmann hci_dev_lock(hdev); 51042f010b55SMarcel Holtmann 51052f010b55SMarcel Holtmann while (num_reports--) { 51062f010b55SMarcel Holtmann struct hci_ev_le_direct_adv_info *ev = ptr; 51072f010b55SMarcel Holtmann 51082f010b55SMarcel Holtmann process_adv_report(hdev, ev->evt_type, &ev->bdaddr, 51092f010b55SMarcel Holtmann ev->bdaddr_type, &ev->direct_addr, 51102f010b55SMarcel Holtmann ev->direct_addr_type, ev->rssi, NULL, 0); 51112f010b55SMarcel Holtmann 51122f010b55SMarcel Holtmann ptr += sizeof(*ev); 51132f010b55SMarcel Holtmann } 51142f010b55SMarcel Holtmann 51152f010b55SMarcel Holtmann hci_dev_unlock(hdev); 51162f010b55SMarcel Holtmann } 51172f010b55SMarcel Holtmann 51186039aa73SGustavo Padovan static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) 5119fcd89c09SVille Tervo { 5120fcd89c09SVille Tervo struct hci_ev_le_meta *le_ev = (void *) skb->data; 5121fcd89c09SVille Tervo 5122fcd89c09SVille Tervo skb_pull(skb, sizeof(*le_ev)); 5123fcd89c09SVille Tervo 5124fcd89c09SVille Tervo switch (le_ev->subevent) { 5125fcd89c09SVille Tervo case HCI_EV_LE_CONN_COMPLETE: 5126fcd89c09SVille Tervo hci_le_conn_complete_evt(hdev, skb); 5127fcd89c09SVille Tervo break; 5128fcd89c09SVille Tervo 51291855d92dSMarcel Holtmann case HCI_EV_LE_CONN_UPDATE_COMPLETE: 51301855d92dSMarcel Holtmann hci_le_conn_update_complete_evt(hdev, skb); 51311855d92dSMarcel Holtmann break; 51321855d92dSMarcel Holtmann 51339aa04c91SAndre Guedes case HCI_EV_LE_ADVERTISING_REPORT: 51349aa04c91SAndre Guedes hci_le_adv_report_evt(hdev, skb); 51359aa04c91SAndre Guedes break; 51369aa04c91SAndre Guedes 51370fe29fd1SMarcel Holtmann case HCI_EV_LE_REMOTE_FEAT_COMPLETE: 51380fe29fd1SMarcel Holtmann hci_le_remote_feat_complete_evt(hdev, skb); 51390fe29fd1SMarcel Holtmann break; 51400fe29fd1SMarcel Holtmann 5141a7a595f6SVinicius Costa Gomes case HCI_EV_LE_LTK_REQ: 5142a7a595f6SVinicius Costa Gomes hci_le_ltk_request_evt(hdev, skb); 5143a7a595f6SVinicius Costa Gomes break; 5144a7a595f6SVinicius Costa Gomes 51458e75b46aSAndre Guedes case HCI_EV_LE_REMOTE_CONN_PARAM_REQ: 51468e75b46aSAndre Guedes hci_le_remote_conn_param_req_evt(hdev, skb); 51478e75b46aSAndre Guedes break; 51488e75b46aSAndre Guedes 51492f010b55SMarcel Holtmann case HCI_EV_LE_DIRECT_ADV_REPORT: 51502f010b55SMarcel Holtmann hci_le_direct_adv_report_evt(hdev, skb); 51512f010b55SMarcel Holtmann break; 51522f010b55SMarcel Holtmann 5153fcd89c09SVille Tervo default: 5154fcd89c09SVille Tervo break; 5155fcd89c09SVille Tervo } 5156fcd89c09SVille Tervo } 5157fcd89c09SVille Tervo 5158757aa0b5SJohan Hedberg static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 5159757aa0b5SJohan Hedberg u8 event, struct sk_buff *skb) 5160757aa0b5SJohan Hedberg { 5161757aa0b5SJohan Hedberg struct hci_ev_cmd_complete *ev; 5162757aa0b5SJohan Hedberg struct hci_event_hdr *hdr; 5163757aa0b5SJohan Hedberg 5164757aa0b5SJohan Hedberg if (!skb) 5165757aa0b5SJohan Hedberg return false; 5166757aa0b5SJohan Hedberg 5167757aa0b5SJohan Hedberg if (skb->len < sizeof(*hdr)) { 5168757aa0b5SJohan Hedberg BT_ERR("Too short HCI event"); 5169757aa0b5SJohan Hedberg return false; 5170757aa0b5SJohan Hedberg } 5171757aa0b5SJohan Hedberg 5172757aa0b5SJohan Hedberg hdr = (void *) skb->data; 5173757aa0b5SJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 5174757aa0b5SJohan Hedberg 5175757aa0b5SJohan Hedberg if (event) { 5176757aa0b5SJohan Hedberg if (hdr->evt != event) 5177757aa0b5SJohan Hedberg return false; 5178757aa0b5SJohan Hedberg return true; 5179757aa0b5SJohan Hedberg } 5180757aa0b5SJohan Hedberg 5181757aa0b5SJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 5182757aa0b5SJohan Hedberg BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); 5183757aa0b5SJohan Hedberg return false; 5184757aa0b5SJohan Hedberg } 5185757aa0b5SJohan Hedberg 5186757aa0b5SJohan Hedberg if (skb->len < sizeof(*ev)) { 5187757aa0b5SJohan Hedberg BT_ERR("Too short cmd_complete event"); 5188757aa0b5SJohan Hedberg return false; 5189757aa0b5SJohan Hedberg } 5190757aa0b5SJohan Hedberg 5191757aa0b5SJohan Hedberg ev = (void *) skb->data; 5192757aa0b5SJohan Hedberg skb_pull(skb, sizeof(*ev)); 5193757aa0b5SJohan Hedberg 5194757aa0b5SJohan Hedberg if (opcode != __le16_to_cpu(ev->opcode)) { 5195757aa0b5SJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 5196757aa0b5SJohan Hedberg __le16_to_cpu(ev->opcode)); 5197757aa0b5SJohan Hedberg return false; 5198757aa0b5SJohan Hedberg } 5199757aa0b5SJohan Hedberg 5200757aa0b5SJohan Hedberg return true; 5201757aa0b5SJohan Hedberg } 5202757aa0b5SJohan Hedberg 52031da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) 52041da177e4SLinus Torvalds { 5205a9de9248SMarcel Holtmann struct hci_event_hdr *hdr = (void *) skb->data; 5206e6214487SJohan Hedberg hci_req_complete_t req_complete = NULL; 5207e6214487SJohan Hedberg hci_req_complete_skb_t req_complete_skb = NULL; 5208e6214487SJohan Hedberg struct sk_buff *orig_skb = NULL; 5209757aa0b5SJohan Hedberg u8 status = 0, event = hdr->evt, req_evt = 0; 5210e6214487SJohan Hedberg u16 opcode = HCI_OP_NOP; 52111da177e4SLinus Torvalds 5212db6e3e8dSJohan Hedberg if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) { 5213c1f23a2bSJohannes Berg struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data; 5214e6214487SJohan Hedberg opcode = __le16_to_cpu(cmd_hdr->opcode); 5215e6214487SJohan Hedberg hci_req_cmd_complete(hdev, opcode, status, &req_complete, 5216e6214487SJohan Hedberg &req_complete_skb); 5217757aa0b5SJohan Hedberg req_evt = event; 521802350a72SJohan Hedberg } 521902350a72SJohan Hedberg 5220e6214487SJohan Hedberg /* If it looks like we might end up having to call 5221e6214487SJohan Hedberg * req_complete_skb, store a pristine copy of the skb since the 5222e6214487SJohan Hedberg * various handlers may modify the original one through 5223e6214487SJohan Hedberg * skb_pull() calls, etc. 5224e6214487SJohan Hedberg */ 5225e6214487SJohan Hedberg if (req_complete_skb || event == HCI_EV_CMD_STATUS || 5226e6214487SJohan Hedberg event == HCI_EV_CMD_COMPLETE) 5227e6214487SJohan Hedberg orig_skb = skb_clone(skb, GFP_KERNEL); 5228e6214487SJohan Hedberg 5229e6214487SJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 5230e6214487SJohan Hedberg 5231a9de9248SMarcel Holtmann switch (event) { 52321da177e4SLinus Torvalds case HCI_EV_INQUIRY_COMPLETE: 52331da177e4SLinus Torvalds hci_inquiry_complete_evt(hdev, skb); 52341da177e4SLinus Torvalds break; 52351da177e4SLinus Torvalds 52361da177e4SLinus Torvalds case HCI_EV_INQUIRY_RESULT: 52371da177e4SLinus Torvalds hci_inquiry_result_evt(hdev, skb); 52381da177e4SLinus Torvalds break; 52391da177e4SLinus Torvalds 5240a9de9248SMarcel Holtmann case HCI_EV_CONN_COMPLETE: 5241a9de9248SMarcel Holtmann hci_conn_complete_evt(hdev, skb); 524221d9e30eSMarcel Holtmann break; 524321d9e30eSMarcel Holtmann 52441da177e4SLinus Torvalds case HCI_EV_CONN_REQUEST: 52451da177e4SLinus Torvalds hci_conn_request_evt(hdev, skb); 52461da177e4SLinus Torvalds break; 52471da177e4SLinus Torvalds 52481da177e4SLinus Torvalds case HCI_EV_DISCONN_COMPLETE: 52491da177e4SLinus Torvalds hci_disconn_complete_evt(hdev, skb); 52501da177e4SLinus Torvalds break; 52511da177e4SLinus Torvalds 52521da177e4SLinus Torvalds case HCI_EV_AUTH_COMPLETE: 52531da177e4SLinus Torvalds hci_auth_complete_evt(hdev, skb); 52541da177e4SLinus Torvalds break; 52551da177e4SLinus Torvalds 5256a9de9248SMarcel Holtmann case HCI_EV_REMOTE_NAME: 5257a9de9248SMarcel Holtmann hci_remote_name_evt(hdev, skb); 5258a9de9248SMarcel Holtmann break; 5259a9de9248SMarcel Holtmann 52601da177e4SLinus Torvalds case HCI_EV_ENCRYPT_CHANGE: 52611da177e4SLinus Torvalds hci_encrypt_change_evt(hdev, skb); 52621da177e4SLinus Torvalds break; 52631da177e4SLinus Torvalds 5264a9de9248SMarcel Holtmann case HCI_EV_CHANGE_LINK_KEY_COMPLETE: 5265a9de9248SMarcel Holtmann hci_change_link_key_complete_evt(hdev, skb); 5266a9de9248SMarcel Holtmann break; 5267a9de9248SMarcel Holtmann 5268a9de9248SMarcel Holtmann case HCI_EV_REMOTE_FEATURES: 5269a9de9248SMarcel Holtmann hci_remote_features_evt(hdev, skb); 5270a9de9248SMarcel Holtmann break; 5271a9de9248SMarcel Holtmann 5272a9de9248SMarcel Holtmann case HCI_EV_CMD_COMPLETE: 5273e6214487SJohan Hedberg hci_cmd_complete_evt(hdev, skb, &opcode, &status, 5274e6214487SJohan Hedberg &req_complete, &req_complete_skb); 5275a9de9248SMarcel Holtmann break; 5276a9de9248SMarcel Holtmann 5277a9de9248SMarcel Holtmann case HCI_EV_CMD_STATUS: 5278e6214487SJohan Hedberg hci_cmd_status_evt(hdev, skb, &opcode, &status, &req_complete, 5279e6214487SJohan Hedberg &req_complete_skb); 5280a9de9248SMarcel Holtmann break; 5281a9de9248SMarcel Holtmann 528224dfa343SMarcel Holtmann case HCI_EV_HARDWARE_ERROR: 528324dfa343SMarcel Holtmann hci_hardware_error_evt(hdev, skb); 528424dfa343SMarcel Holtmann break; 528524dfa343SMarcel Holtmann 5286a9de9248SMarcel Holtmann case HCI_EV_ROLE_CHANGE: 5287a9de9248SMarcel Holtmann hci_role_change_evt(hdev, skb); 5288a9de9248SMarcel Holtmann break; 5289a9de9248SMarcel Holtmann 5290a9de9248SMarcel Holtmann case HCI_EV_NUM_COMP_PKTS: 5291a9de9248SMarcel Holtmann hci_num_comp_pkts_evt(hdev, skb); 5292a9de9248SMarcel Holtmann break; 5293a9de9248SMarcel Holtmann 5294a9de9248SMarcel Holtmann case HCI_EV_MODE_CHANGE: 5295a9de9248SMarcel Holtmann hci_mode_change_evt(hdev, skb); 52961da177e4SLinus Torvalds break; 52971da177e4SLinus Torvalds 52981da177e4SLinus Torvalds case HCI_EV_PIN_CODE_REQ: 52991da177e4SLinus Torvalds hci_pin_code_request_evt(hdev, skb); 53001da177e4SLinus Torvalds break; 53011da177e4SLinus Torvalds 53021da177e4SLinus Torvalds case HCI_EV_LINK_KEY_REQ: 53031da177e4SLinus Torvalds hci_link_key_request_evt(hdev, skb); 53041da177e4SLinus Torvalds break; 53051da177e4SLinus Torvalds 53061da177e4SLinus Torvalds case HCI_EV_LINK_KEY_NOTIFY: 53071da177e4SLinus Torvalds hci_link_key_notify_evt(hdev, skb); 53081da177e4SLinus Torvalds break; 53091da177e4SLinus Torvalds 53101da177e4SLinus Torvalds case HCI_EV_CLOCK_OFFSET: 53111da177e4SLinus Torvalds hci_clock_offset_evt(hdev, skb); 53121da177e4SLinus Torvalds break; 53131da177e4SLinus Torvalds 5314a8746417SMarcel Holtmann case HCI_EV_PKT_TYPE_CHANGE: 5315a8746417SMarcel Holtmann hci_pkt_type_change_evt(hdev, skb); 5316a8746417SMarcel Holtmann break; 5317a8746417SMarcel Holtmann 531885a1e930SMarcel Holtmann case HCI_EV_PSCAN_REP_MODE: 531985a1e930SMarcel Holtmann hci_pscan_rep_mode_evt(hdev, skb); 532085a1e930SMarcel Holtmann break; 532185a1e930SMarcel Holtmann 5322a9de9248SMarcel Holtmann case HCI_EV_INQUIRY_RESULT_WITH_RSSI: 5323a9de9248SMarcel Holtmann hci_inquiry_result_with_rssi_evt(hdev, skb); 5324a9de9248SMarcel Holtmann break; 5325a9de9248SMarcel Holtmann 5326a9de9248SMarcel Holtmann case HCI_EV_REMOTE_EXT_FEATURES: 5327a9de9248SMarcel Holtmann hci_remote_ext_features_evt(hdev, skb); 5328a9de9248SMarcel Holtmann break; 5329a9de9248SMarcel Holtmann 5330a9de9248SMarcel Holtmann case HCI_EV_SYNC_CONN_COMPLETE: 5331a9de9248SMarcel Holtmann hci_sync_conn_complete_evt(hdev, skb); 5332a9de9248SMarcel Holtmann break; 5333a9de9248SMarcel Holtmann 5334a9de9248SMarcel Holtmann case HCI_EV_EXTENDED_INQUIRY_RESULT: 5335a9de9248SMarcel Holtmann hci_extended_inquiry_result_evt(hdev, skb); 53361da177e4SLinus Torvalds break; 53371da177e4SLinus Torvalds 53381c2e0041SJohan Hedberg case HCI_EV_KEY_REFRESH_COMPLETE: 53391c2e0041SJohan Hedberg hci_key_refresh_complete_evt(hdev, skb); 53401c2e0041SJohan Hedberg break; 53411c2e0041SJohan Hedberg 53420493684eSMarcel Holtmann case HCI_EV_IO_CAPA_REQUEST: 53430493684eSMarcel Holtmann hci_io_capa_request_evt(hdev, skb); 53440493684eSMarcel Holtmann break; 53450493684eSMarcel Holtmann 534603b555e1SJohan Hedberg case HCI_EV_IO_CAPA_REPLY: 534703b555e1SJohan Hedberg hci_io_capa_reply_evt(hdev, skb); 534803b555e1SJohan Hedberg break; 534903b555e1SJohan Hedberg 5350a5c29683SJohan Hedberg case HCI_EV_USER_CONFIRM_REQUEST: 5351a5c29683SJohan Hedberg hci_user_confirm_request_evt(hdev, skb); 5352a5c29683SJohan Hedberg break; 5353a5c29683SJohan Hedberg 53541143d458SBrian Gix case HCI_EV_USER_PASSKEY_REQUEST: 53551143d458SBrian Gix hci_user_passkey_request_evt(hdev, skb); 53561143d458SBrian Gix break; 53571143d458SBrian Gix 535892a25256SJohan Hedberg case HCI_EV_USER_PASSKEY_NOTIFY: 535992a25256SJohan Hedberg hci_user_passkey_notify_evt(hdev, skb); 536092a25256SJohan Hedberg break; 536192a25256SJohan Hedberg 536292a25256SJohan Hedberg case HCI_EV_KEYPRESS_NOTIFY: 536392a25256SJohan Hedberg hci_keypress_notify_evt(hdev, skb); 536492a25256SJohan Hedberg break; 536592a25256SJohan Hedberg 53660493684eSMarcel Holtmann case HCI_EV_SIMPLE_PAIR_COMPLETE: 53670493684eSMarcel Holtmann hci_simple_pair_complete_evt(hdev, skb); 53680493684eSMarcel Holtmann break; 53690493684eSMarcel Holtmann 537041a96212SMarcel Holtmann case HCI_EV_REMOTE_HOST_FEATURES: 537141a96212SMarcel Holtmann hci_remote_host_features_evt(hdev, skb); 537241a96212SMarcel Holtmann break; 537341a96212SMarcel Holtmann 5374fcd89c09SVille Tervo case HCI_EV_LE_META: 5375fcd89c09SVille Tervo hci_le_meta_evt(hdev, skb); 5376fcd89c09SVille Tervo break; 5377fcd89c09SVille Tervo 53782763eda6SSzymon Janc case HCI_EV_REMOTE_OOB_DATA_REQUEST: 53792763eda6SSzymon Janc hci_remote_oob_data_request_evt(hdev, skb); 53802763eda6SSzymon Janc break; 53812763eda6SSzymon Janc 5382a77a6a14SArron Wang #if IS_ENABLED(CONFIG_BT_HS) 5383a77a6a14SArron Wang case HCI_EV_CHANNEL_SELECTED: 5384a77a6a14SArron Wang hci_chan_selected_evt(hdev, skb); 5385a77a6a14SArron Wang break; 5386a77a6a14SArron Wang 5387d5e91192SAndrei Emeltchenko case HCI_EV_PHY_LINK_COMPLETE: 5388d5e91192SAndrei Emeltchenko hci_phy_link_complete_evt(hdev, skb); 5389d5e91192SAndrei Emeltchenko break; 5390d5e91192SAndrei Emeltchenko 539127695fb4SAndrei Emeltchenko case HCI_EV_LOGICAL_LINK_COMPLETE: 539227695fb4SAndrei Emeltchenko hci_loglink_complete_evt(hdev, skb); 539327695fb4SAndrei Emeltchenko break; 539427695fb4SAndrei Emeltchenko 5395606e2a10SAndrei Emeltchenko case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE: 5396606e2a10SAndrei Emeltchenko hci_disconn_loglink_complete_evt(hdev, skb); 5397606e2a10SAndrei Emeltchenko break; 5398606e2a10SAndrei Emeltchenko 53999eef6b3aSAndrei Emeltchenko case HCI_EV_DISCONN_PHY_LINK_COMPLETE: 54009eef6b3aSAndrei Emeltchenko hci_disconn_phylink_complete_evt(hdev, skb); 54019eef6b3aSAndrei Emeltchenko break; 5402a77a6a14SArron Wang #endif 54039eef6b3aSAndrei Emeltchenko 540425e89e99SAndrei Emeltchenko case HCI_EV_NUM_COMP_BLOCKS: 540525e89e99SAndrei Emeltchenko hci_num_comp_blocks_evt(hdev, skb); 540625e89e99SAndrei Emeltchenko break; 540725e89e99SAndrei Emeltchenko 54081da177e4SLinus Torvalds default: 54099f1db00cSAndrei Emeltchenko BT_DBG("%s event 0x%2.2x", hdev->name, event); 54101da177e4SLinus Torvalds break; 54111da177e4SLinus Torvalds } 54121da177e4SLinus Torvalds 5413757aa0b5SJohan Hedberg if (req_complete) { 5414e6214487SJohan Hedberg req_complete(hdev, status, opcode); 5415757aa0b5SJohan Hedberg } else if (req_complete_skb) { 5416757aa0b5SJohan Hedberg if (!hci_get_cmd_complete(hdev, opcode, req_evt, orig_skb)) { 5417757aa0b5SJohan Hedberg kfree_skb(orig_skb); 5418757aa0b5SJohan Hedberg orig_skb = NULL; 5419757aa0b5SJohan Hedberg } 5420e6214487SJohan Hedberg req_complete_skb(hdev, status, opcode, orig_skb); 5421757aa0b5SJohan Hedberg } 5422e6214487SJohan Hedberg 5423e6214487SJohan Hedberg kfree_skb(orig_skb); 54241da177e4SLinus Torvalds kfree_skb(skb); 54251da177e4SLinus Torvalds hdev->stat.evt_rx++; 54261da177e4SLinus Torvalds } 5427