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 337024728eSMarcel Holtmann #include "a2mp.h" 347ef9fbf0SMarcel Holtmann #include "amp.h" 352ceba539SJohan Hedberg #include "smp.h" 361da177e4SLinus Torvalds 371da177e4SLinus Torvalds /* Handle HCI Event packets */ 381da177e4SLinus Torvalds 39a9de9248SMarcel Holtmann static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) 401da177e4SLinus Torvalds { 41a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 421da177e4SLinus Torvalds 439f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 441da177e4SLinus Torvalds 4582f4785cSAndre Guedes if (status) 46a9de9248SMarcel Holtmann return; 471da177e4SLinus Torvalds 4889352e7dSAndre Guedes clear_bit(HCI_INQUIRY, &hdev->flags); 494e857c58SPeter Zijlstra smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */ 503e13fa1eSAndre Guedes wake_up_bit(&hdev->flags, HCI_INQUIRY); 5189352e7dSAndre Guedes 5250143a43SJohan Hedberg hci_dev_lock(hdev); 5350143a43SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 5450143a43SJohan Hedberg hci_dev_unlock(hdev); 5550143a43SJohan Hedberg 56a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 571da177e4SLinus Torvalds } 586bd57416SMarcel Holtmann 594d93483bSAndre Guedes static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) 604d93483bSAndre Guedes { 614d93483bSAndre Guedes __u8 status = *((__u8 *) skb->data); 624d93483bSAndre Guedes 639f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 64ae854a70SAndre Guedes 65ae854a70SAndre Guedes if (status) 66ae854a70SAndre Guedes return; 67ae854a70SAndre Guedes 68ae854a70SAndre Guedes set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags); 694d93483bSAndre Guedes } 704d93483bSAndre Guedes 71a9de9248SMarcel Holtmann static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) 721da177e4SLinus Torvalds { 73a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 74a9de9248SMarcel Holtmann 759f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 76a9de9248SMarcel Holtmann 77a9de9248SMarcel Holtmann if (status) 78a9de9248SMarcel Holtmann return; 79a9de9248SMarcel Holtmann 80ae854a70SAndre Guedes clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags); 81ae854a70SAndre Guedes 82a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 83a9de9248SMarcel Holtmann } 84a9de9248SMarcel Holtmann 85807deac2SGustavo Padovan static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, 86807deac2SGustavo Padovan struct sk_buff *skb) 87a9de9248SMarcel Holtmann { 88a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 89a9de9248SMarcel Holtmann } 90a9de9248SMarcel Holtmann 91a9de9248SMarcel Holtmann static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb) 92a9de9248SMarcel Holtmann { 93a9de9248SMarcel Holtmann struct hci_rp_role_discovery *rp = (void *) skb->data; 941da177e4SLinus Torvalds struct hci_conn *conn; 951da177e4SLinus Torvalds 969f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 971da177e4SLinus Torvalds 98a9de9248SMarcel Holtmann if (rp->status) 99a9de9248SMarcel Holtmann return; 1001da177e4SLinus Torvalds 1011da177e4SLinus Torvalds hci_dev_lock(hdev); 1021da177e4SLinus Torvalds 103a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 1041da177e4SLinus Torvalds if (conn) { 105a9de9248SMarcel Holtmann if (rp->role) 1064dae2798SJohan Hedberg clear_bit(HCI_CONN_MASTER, &conn->flags); 1071da177e4SLinus Torvalds else 1084dae2798SJohan Hedberg set_bit(HCI_CONN_MASTER, &conn->flags); 1091da177e4SLinus Torvalds } 1101da177e4SLinus Torvalds 1111da177e4SLinus Torvalds hci_dev_unlock(hdev); 112a9de9248SMarcel Holtmann } 1131da177e4SLinus Torvalds 114e4e8e37cSMarcel Holtmann static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 115e4e8e37cSMarcel Holtmann { 116e4e8e37cSMarcel Holtmann struct hci_rp_read_link_policy *rp = (void *) skb->data; 117e4e8e37cSMarcel Holtmann struct hci_conn *conn; 118e4e8e37cSMarcel Holtmann 1199f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 120e4e8e37cSMarcel Holtmann 121e4e8e37cSMarcel Holtmann if (rp->status) 122e4e8e37cSMarcel Holtmann return; 123e4e8e37cSMarcel Holtmann 124e4e8e37cSMarcel Holtmann hci_dev_lock(hdev); 125e4e8e37cSMarcel Holtmann 126e4e8e37cSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 127e4e8e37cSMarcel Holtmann if (conn) 128e4e8e37cSMarcel Holtmann conn->link_policy = __le16_to_cpu(rp->policy); 129e4e8e37cSMarcel Holtmann 130e4e8e37cSMarcel Holtmann hci_dev_unlock(hdev); 131e4e8e37cSMarcel Holtmann } 132e4e8e37cSMarcel Holtmann 133a9de9248SMarcel Holtmann static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 134a9de9248SMarcel Holtmann { 135a9de9248SMarcel Holtmann struct hci_rp_write_link_policy *rp = (void *) skb->data; 136a9de9248SMarcel Holtmann struct hci_conn *conn; 137a9de9248SMarcel Holtmann void *sent; 138a9de9248SMarcel Holtmann 1399f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 140a9de9248SMarcel Holtmann 141a9de9248SMarcel Holtmann if (rp->status) 142a9de9248SMarcel Holtmann return; 143a9de9248SMarcel Holtmann 144a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY); 14504837f64SMarcel Holtmann if (!sent) 146a9de9248SMarcel Holtmann return; 14704837f64SMarcel Holtmann 14804837f64SMarcel Holtmann hci_dev_lock(hdev); 14904837f64SMarcel Holtmann 150a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 151e4e8e37cSMarcel Holtmann if (conn) 15283985319SHarvey Harrison conn->link_policy = get_unaligned_le16(sent + 2); 15304837f64SMarcel Holtmann 15404837f64SMarcel Holtmann hci_dev_unlock(hdev); 1551da177e4SLinus Torvalds } 1561da177e4SLinus Torvalds 157807deac2SGustavo Padovan static void hci_cc_read_def_link_policy(struct hci_dev *hdev, 158807deac2SGustavo Padovan struct sk_buff *skb) 159e4e8e37cSMarcel Holtmann { 160e4e8e37cSMarcel Holtmann struct hci_rp_read_def_link_policy *rp = (void *) skb->data; 161e4e8e37cSMarcel Holtmann 1629f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 163e4e8e37cSMarcel Holtmann 164e4e8e37cSMarcel Holtmann if (rp->status) 165e4e8e37cSMarcel Holtmann return; 166e4e8e37cSMarcel Holtmann 167e4e8e37cSMarcel Holtmann hdev->link_policy = __le16_to_cpu(rp->policy); 168e4e8e37cSMarcel Holtmann } 169e4e8e37cSMarcel Holtmann 170807deac2SGustavo Padovan static void hci_cc_write_def_link_policy(struct hci_dev *hdev, 171807deac2SGustavo Padovan struct sk_buff *skb) 172e4e8e37cSMarcel Holtmann { 173e4e8e37cSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 174e4e8e37cSMarcel Holtmann void *sent; 175e4e8e37cSMarcel Holtmann 1769f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 177e4e8e37cSMarcel Holtmann 17845296acdSMarcel Holtmann if (status) 17945296acdSMarcel Holtmann return; 18045296acdSMarcel Holtmann 181e4e8e37cSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY); 182e4e8e37cSMarcel Holtmann if (!sent) 183e4e8e37cSMarcel Holtmann return; 184e4e8e37cSMarcel Holtmann 185e4e8e37cSMarcel Holtmann hdev->link_policy = get_unaligned_le16(sent); 186e4e8e37cSMarcel Holtmann } 187e4e8e37cSMarcel Holtmann 188a9de9248SMarcel Holtmann static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) 1891da177e4SLinus Torvalds { 190a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 191a9de9248SMarcel Holtmann 1929f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 193a9de9248SMarcel Holtmann 19410572132SGustavo F. Padovan clear_bit(HCI_RESET, &hdev->flags); 19510572132SGustavo F. Padovan 196a297e97cSJohan Hedberg /* Reset all non-persistent flags */ 1972cc6fb00SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 19869775ff6SAndre Guedes 19969775ff6SAndre Guedes hdev->discovery.state = DISCOVERY_STOPPED; 200bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 201bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 2023f0f524bSJohan Hedberg 2033f0f524bSJohan Hedberg memset(hdev->adv_data, 0, sizeof(hdev->adv_data)); 2043f0f524bSJohan Hedberg hdev->adv_data_len = 0; 205f8e808bdSMarcel Holtmann 206f8e808bdSMarcel Holtmann memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data)); 207f8e808bdSMarcel Holtmann hdev->scan_rsp_data_len = 0; 20806f5b778SMarcel Holtmann 209533553f8SMarcel Holtmann hdev->le_scan_type = LE_SCAN_PASSIVE; 210533553f8SMarcel Holtmann 21106f5b778SMarcel Holtmann hdev->ssp_debug_mode = 0; 212a9de9248SMarcel Holtmann } 213a9de9248SMarcel Holtmann 214a9de9248SMarcel Holtmann static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) 215a9de9248SMarcel Holtmann { 216a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 2171da177e4SLinus Torvalds void *sent; 2181da177e4SLinus Torvalds 2199f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 2201da177e4SLinus Torvalds 221a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME); 2221da177e4SLinus Torvalds if (!sent) 223a9de9248SMarcel Holtmann return; 2241da177e4SLinus Torvalds 22556e5cb86SJohan Hedberg hci_dev_lock(hdev); 22656e5cb86SJohan Hedberg 227f51d5b24SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 228f51d5b24SJohan Hedberg mgmt_set_local_name_complete(hdev, sent, status); 22928cc7bdeSJohan Hedberg else if (!status) 23028cc7bdeSJohan Hedberg memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); 231f51d5b24SJohan Hedberg 23256e5cb86SJohan Hedberg hci_dev_unlock(hdev); 233a9de9248SMarcel Holtmann } 234a9de9248SMarcel Holtmann 235a9de9248SMarcel Holtmann static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) 236a9de9248SMarcel Holtmann { 237a9de9248SMarcel Holtmann struct hci_rp_read_local_name *rp = (void *) skb->data; 238a9de9248SMarcel Holtmann 2399f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 240a9de9248SMarcel Holtmann 241a9de9248SMarcel Holtmann if (rp->status) 242a9de9248SMarcel Holtmann return; 243a9de9248SMarcel Holtmann 244db99b5fcSJohan Hedberg if (test_bit(HCI_SETUP, &hdev->dev_flags)) 2451f6c6378SJohan Hedberg memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); 246a9de9248SMarcel Holtmann } 247a9de9248SMarcel Holtmann 248a9de9248SMarcel Holtmann static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) 249a9de9248SMarcel Holtmann { 250a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 251a9de9248SMarcel Holtmann void *sent; 252a9de9248SMarcel Holtmann 2539f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 254a9de9248SMarcel Holtmann 255a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE); 256a9de9248SMarcel Holtmann if (!sent) 257a9de9248SMarcel Holtmann return; 2581da177e4SLinus Torvalds 2591da177e4SLinus Torvalds if (!status) { 260a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 261a9de9248SMarcel Holtmann 2621da177e4SLinus Torvalds if (param == AUTH_ENABLED) 2631da177e4SLinus Torvalds set_bit(HCI_AUTH, &hdev->flags); 2641da177e4SLinus Torvalds else 2651da177e4SLinus Torvalds clear_bit(HCI_AUTH, &hdev->flags); 2661da177e4SLinus Torvalds } 267a9de9248SMarcel Holtmann 26833ef95edSJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 26933ef95edSJohan Hedberg mgmt_auth_enable_complete(hdev, status); 270a9de9248SMarcel Holtmann } 2711da177e4SLinus Torvalds 272a9de9248SMarcel Holtmann static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) 273a9de9248SMarcel Holtmann { 274a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 27545296acdSMarcel Holtmann __u8 param; 276a9de9248SMarcel Holtmann void *sent; 277a9de9248SMarcel Holtmann 2789f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 279a9de9248SMarcel Holtmann 28045296acdSMarcel Holtmann if (status) 28145296acdSMarcel Holtmann return; 28245296acdSMarcel Holtmann 283a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE); 2841da177e4SLinus Torvalds if (!sent) 285a9de9248SMarcel Holtmann return; 2861da177e4SLinus Torvalds 28745296acdSMarcel Holtmann param = *((__u8 *) sent); 288a9de9248SMarcel Holtmann 2891da177e4SLinus Torvalds if (param) 2901da177e4SLinus Torvalds set_bit(HCI_ENCRYPT, &hdev->flags); 2911da177e4SLinus Torvalds else 2921da177e4SLinus Torvalds clear_bit(HCI_ENCRYPT, &hdev->flags); 2931da177e4SLinus Torvalds } 2941da177e4SLinus Torvalds 295a9de9248SMarcel Holtmann static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) 296a9de9248SMarcel Holtmann { 29745296acdSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 29845296acdSMarcel Holtmann __u8 param; 29936f7fc7eSJohan Hedberg int old_pscan, old_iscan; 300a9de9248SMarcel Holtmann void *sent; 3011da177e4SLinus Torvalds 3029f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 303a9de9248SMarcel Holtmann 304a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE); 3051da177e4SLinus Torvalds if (!sent) 306a9de9248SMarcel Holtmann return; 3071da177e4SLinus Torvalds 30836f7fc7eSJohan Hedberg param = *((__u8 *) sent); 309a9de9248SMarcel Holtmann 31056e5cb86SJohan Hedberg hci_dev_lock(hdev); 31156e5cb86SJohan Hedberg 312fa1bd918SMikel Astiz if (status) { 313744cf19eSJohan Hedberg mgmt_write_scan_failed(hdev, param, status); 3142d7cee58SJohan Hedberg hdev->discov_timeout = 0; 3152d7cee58SJohan Hedberg goto done; 3162d7cee58SJohan Hedberg } 3172d7cee58SJohan Hedberg 3180663ca2aSJohan Hedberg /* We need to ensure that we set this back on if someone changed 3190663ca2aSJohan Hedberg * the scan mode through a raw HCI socket. 3200663ca2aSJohan Hedberg */ 3210663ca2aSJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 3220663ca2aSJohan Hedberg 3239fbcbb45SJohan Hedberg old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags); 3249fbcbb45SJohan Hedberg old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags); 325a9de9248SMarcel Holtmann 32673f22f62SJohan Hedberg if (param & SCAN_INQUIRY) { 3271da177e4SLinus Torvalds set_bit(HCI_ISCAN, &hdev->flags); 3289fbcbb45SJohan Hedberg if (!old_iscan) 329744cf19eSJohan Hedberg mgmt_discoverable(hdev, 1); 3309fbcbb45SJohan Hedberg } else if (old_iscan) 331744cf19eSJohan Hedberg mgmt_discoverable(hdev, 0); 3321da177e4SLinus Torvalds 3339fbcbb45SJohan Hedberg if (param & SCAN_PAGE) { 3341da177e4SLinus Torvalds set_bit(HCI_PSCAN, &hdev->flags); 3359fbcbb45SJohan Hedberg if (!old_pscan) 336744cf19eSJohan Hedberg mgmt_connectable(hdev, 1); 3379fbcbb45SJohan Hedberg } else if (old_pscan) 338744cf19eSJohan Hedberg mgmt_connectable(hdev, 0); 339a9de9248SMarcel Holtmann 34036f7fc7eSJohan Hedberg done: 34156e5cb86SJohan Hedberg hci_dev_unlock(hdev); 3421da177e4SLinus Torvalds } 3431da177e4SLinus Torvalds 344a9de9248SMarcel Holtmann static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 345a9de9248SMarcel Holtmann { 346a9de9248SMarcel Holtmann struct hci_rp_read_class_of_dev *rp = (void *) skb->data; 347a9de9248SMarcel Holtmann 3489f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 349a9de9248SMarcel Holtmann 350a9de9248SMarcel Holtmann if (rp->status) 351a9de9248SMarcel Holtmann return; 352a9de9248SMarcel Holtmann 353a9de9248SMarcel Holtmann memcpy(hdev->dev_class, rp->dev_class, 3); 354a9de9248SMarcel Holtmann 355a9de9248SMarcel Holtmann BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name, 356a9de9248SMarcel Holtmann hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); 357a9de9248SMarcel Holtmann } 358a9de9248SMarcel Holtmann 359a9de9248SMarcel Holtmann static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 360a9de9248SMarcel Holtmann { 361a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 362a9de9248SMarcel Holtmann void *sent; 363a9de9248SMarcel Holtmann 3649f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 365a9de9248SMarcel Holtmann 366a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV); 367a9de9248SMarcel Holtmann if (!sent) 368a9de9248SMarcel Holtmann return; 369a9de9248SMarcel Holtmann 3707f9a903cSMarcel Holtmann hci_dev_lock(hdev); 3717f9a903cSMarcel Holtmann 3727f9a903cSMarcel Holtmann if (status == 0) 373a9de9248SMarcel Holtmann memcpy(hdev->dev_class, sent, 3); 3747f9a903cSMarcel Holtmann 3757f9a903cSMarcel Holtmann if (test_bit(HCI_MGMT, &hdev->dev_flags)) 3767f9a903cSMarcel Holtmann mgmt_set_class_of_dev_complete(hdev, sent, status); 3777f9a903cSMarcel Holtmann 3787f9a903cSMarcel Holtmann hci_dev_unlock(hdev); 379a9de9248SMarcel Holtmann } 380a9de9248SMarcel Holtmann 381a9de9248SMarcel Holtmann static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) 382a9de9248SMarcel Holtmann { 383a9de9248SMarcel Holtmann struct hci_rp_read_voice_setting *rp = (void *) skb->data; 384a9de9248SMarcel Holtmann __u16 setting; 385a9de9248SMarcel Holtmann 3869f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 387a9de9248SMarcel Holtmann 388a9de9248SMarcel Holtmann if (rp->status) 389a9de9248SMarcel Holtmann return; 390a9de9248SMarcel Holtmann 391a9de9248SMarcel Holtmann setting = __le16_to_cpu(rp->voice_setting); 392a9de9248SMarcel Holtmann 393a9de9248SMarcel Holtmann if (hdev->voice_setting == setting) 394a9de9248SMarcel Holtmann return; 395a9de9248SMarcel Holtmann 396a9de9248SMarcel Holtmann hdev->voice_setting = setting; 397a9de9248SMarcel Holtmann 3989f1db00cSAndrei Emeltchenko BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting); 399a9de9248SMarcel Holtmann 4003c54711cSGustavo F. Padovan if (hdev->notify) 401a9de9248SMarcel Holtmann hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 402a9de9248SMarcel Holtmann } 403a9de9248SMarcel Holtmann 4048fc9ced3SGustavo Padovan static void hci_cc_write_voice_setting(struct hci_dev *hdev, 4058fc9ced3SGustavo Padovan struct sk_buff *skb) 406a9de9248SMarcel Holtmann { 407a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 408f383f275SMarcel Holtmann __u16 setting; 409a9de9248SMarcel Holtmann void *sent; 410a9de9248SMarcel Holtmann 4119f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 412a9de9248SMarcel Holtmann 413f383f275SMarcel Holtmann if (status) 414f383f275SMarcel Holtmann return; 415f383f275SMarcel Holtmann 416a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING); 417a9de9248SMarcel Holtmann if (!sent) 418a9de9248SMarcel Holtmann return; 419a9de9248SMarcel Holtmann 420f383f275SMarcel Holtmann setting = get_unaligned_le16(sent); 4211da177e4SLinus Torvalds 422f383f275SMarcel Holtmann if (hdev->voice_setting == setting) 423f383f275SMarcel Holtmann return; 424f383f275SMarcel Holtmann 4251da177e4SLinus Torvalds hdev->voice_setting = setting; 4261da177e4SLinus Torvalds 4279f1db00cSAndrei Emeltchenko BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting); 4281da177e4SLinus Torvalds 4293c54711cSGustavo F. Padovan if (hdev->notify) 4301da177e4SLinus Torvalds hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 4311da177e4SLinus Torvalds } 4321da177e4SLinus Torvalds 433b4cb9fb2SMarcel Holtmann static void hci_cc_read_num_supported_iac(struct hci_dev *hdev, 434b4cb9fb2SMarcel Holtmann struct sk_buff *skb) 435b4cb9fb2SMarcel Holtmann { 436b4cb9fb2SMarcel Holtmann struct hci_rp_read_num_supported_iac *rp = (void *) skb->data; 437b4cb9fb2SMarcel Holtmann 438b4cb9fb2SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 439b4cb9fb2SMarcel Holtmann 440b4cb9fb2SMarcel Holtmann if (rp->status) 441b4cb9fb2SMarcel Holtmann return; 442b4cb9fb2SMarcel Holtmann 443b4cb9fb2SMarcel Holtmann hdev->num_iac = rp->num_iac; 444b4cb9fb2SMarcel Holtmann 445b4cb9fb2SMarcel Holtmann BT_DBG("%s num iac %d", hdev->name, hdev->num_iac); 446b4cb9fb2SMarcel Holtmann } 447b4cb9fb2SMarcel Holtmann 448333140b5SMarcel Holtmann static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) 449333140b5SMarcel Holtmann { 450333140b5SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 4515ed8eb2fSJohan Hedberg struct hci_cp_write_ssp_mode *sent; 452333140b5SMarcel Holtmann 4539f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 454333140b5SMarcel Holtmann 455333140b5SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); 456333140b5SMarcel Holtmann if (!sent) 457333140b5SMarcel Holtmann return; 458333140b5SMarcel Holtmann 4595ed8eb2fSJohan Hedberg if (!status) { 4605ed8eb2fSJohan Hedberg if (sent->mode) 461cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_SSP; 4625ed8eb2fSJohan Hedberg else 463cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_SSP; 4645ed8eb2fSJohan Hedberg } 4655ed8eb2fSJohan Hedberg 466c0ecddc2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 4675ed8eb2fSJohan Hedberg mgmt_ssp_enable_complete(hdev, sent->mode, status); 468c0ecddc2SJohan Hedberg else if (!status) { 4695ed8eb2fSJohan Hedberg if (sent->mode) 47084bde9d6SJohan Hedberg set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); 47184bde9d6SJohan Hedberg else 47284bde9d6SJohan Hedberg clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); 473c0ecddc2SJohan Hedberg } 474333140b5SMarcel Holtmann } 475333140b5SMarcel Holtmann 476eac83dc6SMarcel Holtmann static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb) 477eac83dc6SMarcel Holtmann { 478eac83dc6SMarcel Holtmann u8 status = *((u8 *) skb->data); 479eac83dc6SMarcel Holtmann struct hci_cp_write_sc_support *sent; 480eac83dc6SMarcel Holtmann 481eac83dc6SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 482eac83dc6SMarcel Holtmann 483eac83dc6SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT); 484eac83dc6SMarcel Holtmann if (!sent) 485eac83dc6SMarcel Holtmann return; 486eac83dc6SMarcel Holtmann 487eac83dc6SMarcel Holtmann if (!status) { 488eac83dc6SMarcel Holtmann if (sent->support) 489eac83dc6SMarcel Holtmann hdev->features[1][0] |= LMP_HOST_SC; 490eac83dc6SMarcel Holtmann else 491eac83dc6SMarcel Holtmann hdev->features[1][0] &= ~LMP_HOST_SC; 492eac83dc6SMarcel Holtmann } 493eac83dc6SMarcel Holtmann 494eac83dc6SMarcel Holtmann if (test_bit(HCI_MGMT, &hdev->dev_flags)) 495eac83dc6SMarcel Holtmann mgmt_sc_enable_complete(hdev, sent->support, status); 496eac83dc6SMarcel Holtmann else if (!status) { 497eac83dc6SMarcel Holtmann if (sent->support) 498eac83dc6SMarcel Holtmann set_bit(HCI_SC_ENABLED, &hdev->dev_flags); 499eac83dc6SMarcel Holtmann else 500eac83dc6SMarcel Holtmann clear_bit(HCI_SC_ENABLED, &hdev->dev_flags); 501eac83dc6SMarcel Holtmann } 502eac83dc6SMarcel Holtmann } 503eac83dc6SMarcel Holtmann 504a9de9248SMarcel Holtmann static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) 505a9de9248SMarcel Holtmann { 506a9de9248SMarcel Holtmann struct hci_rp_read_local_version *rp = (void *) skb->data; 5071143e5a6SMarcel Holtmann 5089f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 5091143e5a6SMarcel Holtmann 510a9de9248SMarcel Holtmann if (rp->status) 51142c6b129SJohan Hedberg return; 5121143e5a6SMarcel Holtmann 5130d5551f5SMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 514a9de9248SMarcel Holtmann hdev->hci_ver = rp->hci_ver; 515e4e8e37cSMarcel Holtmann hdev->hci_rev = __le16_to_cpu(rp->hci_rev); 516d5859e22SJohan Hedberg hdev->lmp_ver = rp->lmp_ver; 517e4e8e37cSMarcel Holtmann hdev->manufacturer = __le16_to_cpu(rp->manufacturer); 518d5859e22SJohan Hedberg hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); 5190d5551f5SMarcel Holtmann } 520d5859e22SJohan Hedberg } 521d5859e22SJohan Hedberg 5228fc9ced3SGustavo Padovan static void hci_cc_read_local_commands(struct hci_dev *hdev, 5238fc9ced3SGustavo Padovan struct sk_buff *skb) 524a9de9248SMarcel Holtmann { 525a9de9248SMarcel Holtmann struct hci_rp_read_local_commands *rp = (void *) skb->data; 526a9de9248SMarcel Holtmann 5279f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 528a9de9248SMarcel Holtmann 5296a070e6eSMarcel Holtmann if (rp->status) 5306a070e6eSMarcel Holtmann return; 5316a070e6eSMarcel Holtmann 5326a070e6eSMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) 533a9de9248SMarcel Holtmann memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); 534a9de9248SMarcel Holtmann } 535a9de9248SMarcel Holtmann 5368fc9ced3SGustavo Padovan static void hci_cc_read_local_features(struct hci_dev *hdev, 5378fc9ced3SGustavo Padovan struct sk_buff *skb) 538a9de9248SMarcel Holtmann { 539a9de9248SMarcel Holtmann struct hci_rp_read_local_features *rp = (void *) skb->data; 540a9de9248SMarcel Holtmann 5419f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 542a9de9248SMarcel Holtmann 543a9de9248SMarcel Holtmann if (rp->status) 544a9de9248SMarcel Holtmann return; 545a9de9248SMarcel Holtmann 546a9de9248SMarcel Holtmann memcpy(hdev->features, rp->features, 8); 5471da177e4SLinus Torvalds 5481da177e4SLinus Torvalds /* Adjust default settings according to features 5491da177e4SLinus Torvalds * supported by device. */ 550a9de9248SMarcel Holtmann 551cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_3SLOT) 5521da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM3 | HCI_DH3); 5531da177e4SLinus Torvalds 554cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_5SLOT) 5551da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM5 | HCI_DH5); 5561da177e4SLinus Torvalds 557cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV2) { 5581da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV2); 5595b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV2); 5605b7f9909SMarcel Holtmann } 5611da177e4SLinus Torvalds 562cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV3) { 5631da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV3); 5645b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV3); 5655b7f9909SMarcel Holtmann } 5665b7f9909SMarcel Holtmann 56745db810fSAndre Guedes if (lmp_esco_capable(hdev)) 5685b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV3); 5695b7f9909SMarcel Holtmann 570cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV4) 5715b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV4); 5725b7f9909SMarcel Holtmann 573cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV5) 5745b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV5); 5751da177e4SLinus Torvalds 576cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_2M) 577efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV3); 578efc7688bSMarcel Holtmann 579cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_3M) 580efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_3EV3); 581efc7688bSMarcel Holtmann 582cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_3S_ESCO) 583efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); 5841da177e4SLinus Torvalds } 5851da177e4SLinus Torvalds 586971e3a4bSAndre Guedes static void hci_cc_read_local_ext_features(struct hci_dev *hdev, 587971e3a4bSAndre Guedes struct sk_buff *skb) 588971e3a4bSAndre Guedes { 589971e3a4bSAndre Guedes struct hci_rp_read_local_ext_features *rp = (void *) skb->data; 590971e3a4bSAndre Guedes 5919f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 592971e3a4bSAndre Guedes 593971e3a4bSAndre Guedes if (rp->status) 59442c6b129SJohan Hedberg return; 595971e3a4bSAndre Guedes 59657af75a8SMarcel Holtmann if (hdev->max_page < rp->max_page) 597d2c5d77fSJohan Hedberg hdev->max_page = rp->max_page; 598d2c5d77fSJohan Hedberg 599cad718edSJohan Hedberg if (rp->page < HCI_MAX_PAGES) 600cad718edSJohan Hedberg memcpy(hdev->features[rp->page], rp->features, 8); 601971e3a4bSAndre Guedes } 602971e3a4bSAndre Guedes 6031e89cffbSAndrei Emeltchenko static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, 6041e89cffbSAndrei Emeltchenko struct sk_buff *skb) 6051e89cffbSAndrei Emeltchenko { 6061e89cffbSAndrei Emeltchenko struct hci_rp_read_flow_control_mode *rp = (void *) skb->data; 6071e89cffbSAndrei Emeltchenko 6089f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 6091e89cffbSAndrei Emeltchenko 61045296acdSMarcel Holtmann if (rp->status) 61145296acdSMarcel Holtmann return; 61245296acdSMarcel Holtmann 6131e89cffbSAndrei Emeltchenko hdev->flow_ctl_mode = rp->mode; 6141e89cffbSAndrei Emeltchenko } 6151e89cffbSAndrei Emeltchenko 616a9de9248SMarcel Holtmann static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) 617a9de9248SMarcel Holtmann { 618a9de9248SMarcel Holtmann struct hci_rp_read_buffer_size *rp = (void *) skb->data; 619a9de9248SMarcel Holtmann 6209f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 621a9de9248SMarcel Holtmann 622a9de9248SMarcel Holtmann if (rp->status) 623a9de9248SMarcel Holtmann return; 624a9de9248SMarcel Holtmann 625a9de9248SMarcel Holtmann hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu); 626a9de9248SMarcel Holtmann hdev->sco_mtu = rp->sco_mtu; 627a9de9248SMarcel Holtmann hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt); 628a9de9248SMarcel Holtmann hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt); 629da1f5198SMarcel Holtmann 630da1f5198SMarcel Holtmann if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) { 631da1f5198SMarcel Holtmann hdev->sco_mtu = 64; 632da1f5198SMarcel Holtmann hdev->sco_pkts = 8; 633da1f5198SMarcel Holtmann } 634da1f5198SMarcel Holtmann 635da1f5198SMarcel Holtmann hdev->acl_cnt = hdev->acl_pkts; 636da1f5198SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 6371da177e4SLinus Torvalds 638807deac2SGustavo Padovan BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu, 639807deac2SGustavo Padovan hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts); 6401da177e4SLinus Torvalds } 6411da177e4SLinus Torvalds 642a9de9248SMarcel Holtmann static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) 643a9de9248SMarcel Holtmann { 644a9de9248SMarcel Holtmann struct hci_rp_read_bd_addr *rp = (void *) skb->data; 6451da177e4SLinus Torvalds 6469f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 647a9de9248SMarcel Holtmann 648e30d3f5fSMarcel Holtmann if (rp->status) 649e30d3f5fSMarcel Holtmann return; 650e30d3f5fSMarcel Holtmann 651e30d3f5fSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) 652a9de9248SMarcel Holtmann bacpy(&hdev->bdaddr, &rp->bdaddr); 653e30d3f5fSMarcel Holtmann 654e30d3f5fSMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) 655e30d3f5fSMarcel Holtmann bacpy(&hdev->setup_addr, &rp->bdaddr); 65623bb5763SJohan Hedberg } 65723bb5763SJohan Hedberg 658f332ec66SJohan Hedberg static void hci_cc_read_page_scan_activity(struct hci_dev *hdev, 659f332ec66SJohan Hedberg struct sk_buff *skb) 660f332ec66SJohan Hedberg { 661f332ec66SJohan Hedberg struct hci_rp_read_page_scan_activity *rp = (void *) skb->data; 662f332ec66SJohan Hedberg 663f332ec66SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 664f332ec66SJohan Hedberg 66545296acdSMarcel Holtmann if (rp->status) 66645296acdSMarcel Holtmann return; 66745296acdSMarcel Holtmann 66845296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) { 669f332ec66SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(rp->interval); 670f332ec66SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(rp->window); 671f332ec66SJohan Hedberg } 672f332ec66SJohan Hedberg } 673f332ec66SJohan Hedberg 6744a3ee763SJohan Hedberg static void hci_cc_write_page_scan_activity(struct hci_dev *hdev, 6754a3ee763SJohan Hedberg struct sk_buff *skb) 6764a3ee763SJohan Hedberg { 6774a3ee763SJohan Hedberg u8 status = *((u8 *) skb->data); 6784a3ee763SJohan Hedberg struct hci_cp_write_page_scan_activity *sent; 6794a3ee763SJohan Hedberg 6804a3ee763SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 6814a3ee763SJohan Hedberg 6824a3ee763SJohan Hedberg if (status) 6834a3ee763SJohan Hedberg return; 6844a3ee763SJohan Hedberg 6854a3ee763SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY); 6864a3ee763SJohan Hedberg if (!sent) 6874a3ee763SJohan Hedberg return; 6884a3ee763SJohan Hedberg 6894a3ee763SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(sent->interval); 6904a3ee763SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(sent->window); 6914a3ee763SJohan Hedberg } 6924a3ee763SJohan Hedberg 693f332ec66SJohan Hedberg static void hci_cc_read_page_scan_type(struct hci_dev *hdev, 694f332ec66SJohan Hedberg struct sk_buff *skb) 695f332ec66SJohan Hedberg { 696f332ec66SJohan Hedberg struct hci_rp_read_page_scan_type *rp = (void *) skb->data; 697f332ec66SJohan Hedberg 698f332ec66SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 699f332ec66SJohan Hedberg 70045296acdSMarcel Holtmann if (rp->status) 70145296acdSMarcel Holtmann return; 70245296acdSMarcel Holtmann 70345296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) 704f332ec66SJohan Hedberg hdev->page_scan_type = rp->type; 705f332ec66SJohan Hedberg } 706f332ec66SJohan Hedberg 7074a3ee763SJohan Hedberg static void hci_cc_write_page_scan_type(struct hci_dev *hdev, 7084a3ee763SJohan Hedberg struct sk_buff *skb) 7094a3ee763SJohan Hedberg { 7104a3ee763SJohan Hedberg u8 status = *((u8 *) skb->data); 7114a3ee763SJohan Hedberg u8 *type; 7124a3ee763SJohan Hedberg 7134a3ee763SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 7144a3ee763SJohan Hedberg 7154a3ee763SJohan Hedberg if (status) 7164a3ee763SJohan Hedberg return; 7174a3ee763SJohan Hedberg 7184a3ee763SJohan Hedberg type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE); 7194a3ee763SJohan Hedberg if (type) 7204a3ee763SJohan Hedberg hdev->page_scan_type = *type; 7214a3ee763SJohan Hedberg } 7224a3ee763SJohan Hedberg 723350ee4cfSAndrei Emeltchenko static void hci_cc_read_data_block_size(struct hci_dev *hdev, 724350ee4cfSAndrei Emeltchenko struct sk_buff *skb) 725350ee4cfSAndrei Emeltchenko { 726350ee4cfSAndrei Emeltchenko struct hci_rp_read_data_block_size *rp = (void *) skb->data; 727350ee4cfSAndrei Emeltchenko 7289f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 729350ee4cfSAndrei Emeltchenko 730350ee4cfSAndrei Emeltchenko if (rp->status) 731350ee4cfSAndrei Emeltchenko return; 732350ee4cfSAndrei Emeltchenko 733350ee4cfSAndrei Emeltchenko hdev->block_mtu = __le16_to_cpu(rp->max_acl_len); 734350ee4cfSAndrei Emeltchenko hdev->block_len = __le16_to_cpu(rp->block_len); 735350ee4cfSAndrei Emeltchenko hdev->num_blocks = __le16_to_cpu(rp->num_blocks); 736350ee4cfSAndrei Emeltchenko 737350ee4cfSAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 738350ee4cfSAndrei Emeltchenko 739350ee4cfSAndrei Emeltchenko BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu, 740350ee4cfSAndrei Emeltchenko hdev->block_cnt, hdev->block_len); 741350ee4cfSAndrei Emeltchenko } 742350ee4cfSAndrei Emeltchenko 74333f35721SJohan Hedberg static void hci_cc_read_clock(struct hci_dev *hdev, struct sk_buff *skb) 74433f35721SJohan Hedberg { 74533f35721SJohan Hedberg struct hci_rp_read_clock *rp = (void *) skb->data; 74633f35721SJohan Hedberg struct hci_cp_read_clock *cp; 74733f35721SJohan Hedberg struct hci_conn *conn; 74833f35721SJohan Hedberg 74933f35721SJohan Hedberg BT_DBG("%s", hdev->name); 75033f35721SJohan Hedberg 75133f35721SJohan Hedberg if (skb->len < sizeof(*rp)) 75233f35721SJohan Hedberg return; 75333f35721SJohan Hedberg 75433f35721SJohan Hedberg if (rp->status) 75533f35721SJohan Hedberg return; 75633f35721SJohan Hedberg 75733f35721SJohan Hedberg hci_dev_lock(hdev); 75833f35721SJohan Hedberg 75933f35721SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK); 76033f35721SJohan Hedberg if (!cp) 76133f35721SJohan Hedberg goto unlock; 76233f35721SJohan Hedberg 76333f35721SJohan Hedberg if (cp->which == 0x00) { 76433f35721SJohan Hedberg hdev->clock = le32_to_cpu(rp->clock); 76533f35721SJohan Hedberg goto unlock; 76633f35721SJohan Hedberg } 76733f35721SJohan Hedberg 76833f35721SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 76933f35721SJohan Hedberg if (conn) { 77033f35721SJohan Hedberg conn->clock = le32_to_cpu(rp->clock); 77133f35721SJohan Hedberg conn->clock_accuracy = le16_to_cpu(rp->accuracy); 77233f35721SJohan Hedberg } 77333f35721SJohan Hedberg 77433f35721SJohan Hedberg unlock: 77533f35721SJohan Hedberg hci_dev_unlock(hdev); 77633f35721SJohan Hedberg } 77733f35721SJohan Hedberg 778928abaa7SAndrei Emeltchenko static void hci_cc_read_local_amp_info(struct hci_dev *hdev, 779928abaa7SAndrei Emeltchenko struct sk_buff *skb) 780928abaa7SAndrei Emeltchenko { 781928abaa7SAndrei Emeltchenko struct hci_rp_read_local_amp_info *rp = (void *) skb->data; 782928abaa7SAndrei Emeltchenko 7839f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 784928abaa7SAndrei Emeltchenko 785928abaa7SAndrei Emeltchenko if (rp->status) 7868e2a0d92SAndrei Emeltchenko goto a2mp_rsp; 787928abaa7SAndrei Emeltchenko 788928abaa7SAndrei Emeltchenko hdev->amp_status = rp->amp_status; 789928abaa7SAndrei Emeltchenko hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); 790928abaa7SAndrei Emeltchenko hdev->amp_max_bw = __le32_to_cpu(rp->max_bw); 791928abaa7SAndrei Emeltchenko hdev->amp_min_latency = __le32_to_cpu(rp->min_latency); 792928abaa7SAndrei Emeltchenko hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu); 793928abaa7SAndrei Emeltchenko hdev->amp_type = rp->amp_type; 794928abaa7SAndrei Emeltchenko hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap); 795928abaa7SAndrei Emeltchenko hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size); 796928abaa7SAndrei Emeltchenko hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to); 797928abaa7SAndrei Emeltchenko hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); 798928abaa7SAndrei Emeltchenko 7998e2a0d92SAndrei Emeltchenko a2mp_rsp: 8008e2a0d92SAndrei Emeltchenko a2mp_send_getinfo_rsp(hdev); 801928abaa7SAndrei Emeltchenko } 802928abaa7SAndrei Emeltchenko 803903e4541SAndrei Emeltchenko static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev, 804903e4541SAndrei Emeltchenko struct sk_buff *skb) 805903e4541SAndrei Emeltchenko { 806903e4541SAndrei Emeltchenko struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data; 807903e4541SAndrei Emeltchenko struct amp_assoc *assoc = &hdev->loc_assoc; 808903e4541SAndrei Emeltchenko size_t rem_len, frag_len; 809903e4541SAndrei Emeltchenko 810903e4541SAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 811903e4541SAndrei Emeltchenko 812903e4541SAndrei Emeltchenko if (rp->status) 813903e4541SAndrei Emeltchenko goto a2mp_rsp; 814903e4541SAndrei Emeltchenko 815903e4541SAndrei Emeltchenko frag_len = skb->len - sizeof(*rp); 816903e4541SAndrei Emeltchenko rem_len = __le16_to_cpu(rp->rem_len); 817903e4541SAndrei Emeltchenko 818903e4541SAndrei Emeltchenko if (rem_len > frag_len) { 8192e430be3SAndrei Emeltchenko BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len); 820903e4541SAndrei Emeltchenko 821903e4541SAndrei Emeltchenko memcpy(assoc->data + assoc->offset, rp->frag, frag_len); 822903e4541SAndrei Emeltchenko assoc->offset += frag_len; 823903e4541SAndrei Emeltchenko 824903e4541SAndrei Emeltchenko /* Read other fragments */ 825903e4541SAndrei Emeltchenko amp_read_loc_assoc_frag(hdev, rp->phy_handle); 826903e4541SAndrei Emeltchenko 827903e4541SAndrei Emeltchenko return; 828903e4541SAndrei Emeltchenko } 829903e4541SAndrei Emeltchenko 830903e4541SAndrei Emeltchenko memcpy(assoc->data + assoc->offset, rp->frag, rem_len); 831903e4541SAndrei Emeltchenko assoc->len = assoc->offset + rem_len; 832903e4541SAndrei Emeltchenko assoc->offset = 0; 833903e4541SAndrei Emeltchenko 834903e4541SAndrei Emeltchenko a2mp_rsp: 835903e4541SAndrei Emeltchenko /* Send A2MP Rsp when all fragments are received */ 836903e4541SAndrei Emeltchenko a2mp_send_getampassoc_rsp(hdev, rp->status); 8379495b2eeSAndrei Emeltchenko a2mp_send_create_phy_link_req(hdev, rp->status); 838903e4541SAndrei Emeltchenko } 839903e4541SAndrei Emeltchenko 840d5859e22SJohan Hedberg static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, 841d5859e22SJohan Hedberg struct sk_buff *skb) 842d5859e22SJohan Hedberg { 84391c4e9b1SMarcel Holtmann struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data; 844d5859e22SJohan Hedberg 8459f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 846d5859e22SJohan Hedberg 84745296acdSMarcel Holtmann if (rp->status) 84845296acdSMarcel Holtmann return; 84945296acdSMarcel Holtmann 85091c4e9b1SMarcel Holtmann hdev->inq_tx_power = rp->tx_power; 851d5859e22SJohan Hedberg } 852d5859e22SJohan Hedberg 853980e1a53SJohan Hedberg static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) 854980e1a53SJohan Hedberg { 855980e1a53SJohan Hedberg struct hci_rp_pin_code_reply *rp = (void *) skb->data; 856980e1a53SJohan Hedberg struct hci_cp_pin_code_reply *cp; 857980e1a53SJohan Hedberg struct hci_conn *conn; 858980e1a53SJohan Hedberg 8599f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 860980e1a53SJohan Hedberg 86156e5cb86SJohan Hedberg hci_dev_lock(hdev); 86256e5cb86SJohan Hedberg 863a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 864744cf19eSJohan Hedberg mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); 865980e1a53SJohan Hedberg 866fa1bd918SMikel Astiz if (rp->status) 86756e5cb86SJohan Hedberg goto unlock; 868980e1a53SJohan Hedberg 869980e1a53SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); 870980e1a53SJohan Hedberg if (!cp) 87156e5cb86SJohan Hedberg goto unlock; 872980e1a53SJohan Hedberg 873980e1a53SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 874980e1a53SJohan Hedberg if (conn) 875980e1a53SJohan Hedberg conn->pin_length = cp->pin_len; 87656e5cb86SJohan Hedberg 87756e5cb86SJohan Hedberg unlock: 87856e5cb86SJohan Hedberg hci_dev_unlock(hdev); 879980e1a53SJohan Hedberg } 880980e1a53SJohan Hedberg 881980e1a53SJohan Hedberg static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) 882980e1a53SJohan Hedberg { 883980e1a53SJohan Hedberg struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data; 884980e1a53SJohan Hedberg 8859f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 886980e1a53SJohan Hedberg 88756e5cb86SJohan Hedberg hci_dev_lock(hdev); 88856e5cb86SJohan Hedberg 889a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 890744cf19eSJohan Hedberg mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, 891980e1a53SJohan Hedberg rp->status); 89256e5cb86SJohan Hedberg 89356e5cb86SJohan Hedberg hci_dev_unlock(hdev); 894980e1a53SJohan Hedberg } 89556e5cb86SJohan Hedberg 8966ed58ec5SVille Tervo static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, 8976ed58ec5SVille Tervo struct sk_buff *skb) 8986ed58ec5SVille Tervo { 8996ed58ec5SVille Tervo struct hci_rp_le_read_buffer_size *rp = (void *) skb->data; 9006ed58ec5SVille Tervo 9019f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9026ed58ec5SVille Tervo 9036ed58ec5SVille Tervo if (rp->status) 9046ed58ec5SVille Tervo return; 9056ed58ec5SVille Tervo 9066ed58ec5SVille Tervo hdev->le_mtu = __le16_to_cpu(rp->le_mtu); 9076ed58ec5SVille Tervo hdev->le_pkts = rp->le_max_pkt; 9086ed58ec5SVille Tervo 9096ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 9106ed58ec5SVille Tervo 9116ed58ec5SVille Tervo BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts); 9126ed58ec5SVille Tervo } 913980e1a53SJohan Hedberg 91460e77321SJohan Hedberg static void hci_cc_le_read_local_features(struct hci_dev *hdev, 91560e77321SJohan Hedberg struct sk_buff *skb) 91660e77321SJohan Hedberg { 91760e77321SJohan Hedberg struct hci_rp_le_read_local_features *rp = (void *) skb->data; 91860e77321SJohan Hedberg 91960e77321SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 92060e77321SJohan Hedberg 92145296acdSMarcel Holtmann if (rp->status) 92245296acdSMarcel Holtmann return; 92345296acdSMarcel Holtmann 92460e77321SJohan Hedberg memcpy(hdev->le_features, rp->features, 8); 92560e77321SJohan Hedberg } 92660e77321SJohan Hedberg 9278fa19098SJohan Hedberg static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, 9288fa19098SJohan Hedberg struct sk_buff *skb) 9298fa19098SJohan Hedberg { 9308fa19098SJohan Hedberg struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data; 9318fa19098SJohan Hedberg 9328fa19098SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9338fa19098SJohan Hedberg 93445296acdSMarcel Holtmann if (rp->status) 93545296acdSMarcel Holtmann return; 93645296acdSMarcel Holtmann 9378fa19098SJohan Hedberg hdev->adv_tx_power = rp->tx_power; 9388fa19098SJohan Hedberg } 9398fa19098SJohan Hedberg 940a5c29683SJohan Hedberg static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) 941a5c29683SJohan Hedberg { 942a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 943a5c29683SJohan Hedberg 9449f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 945a5c29683SJohan Hedberg 94656e5cb86SJohan Hedberg hci_dev_lock(hdev); 94756e5cb86SJohan Hedberg 948a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 94904124681SGustavo F. Padovan mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0, 95004124681SGustavo F. Padovan rp->status); 95156e5cb86SJohan Hedberg 95256e5cb86SJohan Hedberg hci_dev_unlock(hdev); 953a5c29683SJohan Hedberg } 954a5c29683SJohan Hedberg 955a5c29683SJohan Hedberg static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, 956a5c29683SJohan Hedberg struct sk_buff *skb) 957a5c29683SJohan Hedberg { 958a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 959a5c29683SJohan Hedberg 9609f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 961a5c29683SJohan Hedberg 96256e5cb86SJohan Hedberg hci_dev_lock(hdev); 96356e5cb86SJohan Hedberg 964a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 965744cf19eSJohan Hedberg mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, 96604124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 96756e5cb86SJohan Hedberg 96856e5cb86SJohan Hedberg hci_dev_unlock(hdev); 969a5c29683SJohan Hedberg } 970a5c29683SJohan Hedberg 9711143d458SBrian Gix static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb) 9721143d458SBrian Gix { 9731143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 9741143d458SBrian Gix 9759f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9761143d458SBrian Gix 9771143d458SBrian Gix hci_dev_lock(hdev); 9781143d458SBrian Gix 979a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 980272d90dfSJohan Hedberg mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 981272d90dfSJohan Hedberg 0, rp->status); 9821143d458SBrian Gix 9831143d458SBrian Gix hci_dev_unlock(hdev); 9841143d458SBrian Gix } 9851143d458SBrian Gix 9861143d458SBrian Gix static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, 9871143d458SBrian Gix struct sk_buff *skb) 9881143d458SBrian Gix { 9891143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 9901143d458SBrian Gix 9919f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9921143d458SBrian Gix 9931143d458SBrian Gix hci_dev_lock(hdev); 9941143d458SBrian Gix 995a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 9961143d458SBrian Gix mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr, 99704124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 9981143d458SBrian Gix 9991143d458SBrian Gix hci_dev_unlock(hdev); 10001143d458SBrian Gix } 10011143d458SBrian Gix 10024d2d2796SMarcel Holtmann static void hci_cc_read_local_oob_data(struct hci_dev *hdev, 1003c35938b2SSzymon Janc struct sk_buff *skb) 1004c35938b2SSzymon Janc { 1005c35938b2SSzymon Janc struct hci_rp_read_local_oob_data *rp = (void *) skb->data; 1006c35938b2SSzymon Janc 10079f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 1008c35938b2SSzymon Janc 100956e5cb86SJohan Hedberg hci_dev_lock(hdev); 10104d2d2796SMarcel Holtmann mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->randomizer, 10114d2d2796SMarcel Holtmann NULL, NULL, rp->status); 10124d2d2796SMarcel Holtmann hci_dev_unlock(hdev); 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); 10214d2d2796SMarcel Holtmann 10224d2d2796SMarcel Holtmann hci_dev_lock(hdev); 10234d2d2796SMarcel Holtmann mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->randomizer192, 10244d2d2796SMarcel Holtmann rp->hash256, rp->randomizer256, 10254d2d2796SMarcel Holtmann rp->status); 102656e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1027c35938b2SSzymon Janc } 1028c35938b2SSzymon Janc 10297a4cd51dSMarcel Holtmann 10307a4cd51dSMarcel Holtmann static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb) 10317a4cd51dSMarcel Holtmann { 10327a4cd51dSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 10337a4cd51dSMarcel Holtmann bdaddr_t *sent; 10347a4cd51dSMarcel Holtmann 10357a4cd51dSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 10367a4cd51dSMarcel Holtmann 103745296acdSMarcel Holtmann if (status) 103845296acdSMarcel Holtmann return; 103945296acdSMarcel Holtmann 10407a4cd51dSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR); 10417a4cd51dSMarcel Holtmann if (!sent) 10427a4cd51dSMarcel Holtmann return; 10437a4cd51dSMarcel Holtmann 10447a4cd51dSMarcel Holtmann hci_dev_lock(hdev); 10457a4cd51dSMarcel Holtmann 10467a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, sent); 10477a4cd51dSMarcel Holtmann 10487a4cd51dSMarcel Holtmann hci_dev_unlock(hdev); 10497a4cd51dSMarcel Holtmann } 10507a4cd51dSMarcel Holtmann 1051c1d5dc4aSJohan Hedberg static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) 1052c1d5dc4aSJohan Hedberg { 1053c1d5dc4aSJohan Hedberg __u8 *sent, status = *((__u8 *) skb->data); 1054c1d5dc4aSJohan Hedberg 1055c1d5dc4aSJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 1056c1d5dc4aSJohan Hedberg 105745296acdSMarcel Holtmann if (status) 1058c1d5dc4aSJohan Hedberg return; 1059c1d5dc4aSJohan Hedberg 106045296acdSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE); 106145296acdSMarcel Holtmann if (!sent) 10623c857757SJohan Hedberg return; 10633c857757SJohan Hedberg 1064c1d5dc4aSJohan Hedberg hci_dev_lock(hdev); 1065c1d5dc4aSJohan Hedberg 10663c857757SJohan Hedberg /* If we're doing connection initation as peripheral. Set a 10673c857757SJohan Hedberg * timeout in case something goes wrong. 10683c857757SJohan Hedberg */ 10693c857757SJohan Hedberg if (*sent) { 10703c857757SJohan Hedberg struct hci_conn *conn; 10713c857757SJohan Hedberg 10723c857757SJohan Hedberg conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); 10733c857757SJohan Hedberg if (conn) 10743c857757SJohan Hedberg queue_delayed_work(hdev->workqueue, 10753c857757SJohan Hedberg &conn->le_conn_timeout, 107609ae260bSJohan Hedberg conn->conn_timeout); 10773c857757SJohan Hedberg } 10783c857757SJohan Hedberg 1079778b235aSJohan Hedberg mgmt_advertising(hdev, *sent); 1080c1d5dc4aSJohan Hedberg 108104b4edcbSJohan Hedberg hci_dev_unlock(hdev); 1082c1d5dc4aSJohan Hedberg } 1083c1d5dc4aSJohan Hedberg 1084533553f8SMarcel Holtmann static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) 1085533553f8SMarcel Holtmann { 1086533553f8SMarcel Holtmann struct hci_cp_le_set_scan_param *cp; 1087533553f8SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 1088533553f8SMarcel Holtmann 1089533553f8SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 1090533553f8SMarcel Holtmann 109145296acdSMarcel Holtmann if (status) 109245296acdSMarcel Holtmann return; 109345296acdSMarcel Holtmann 1094533553f8SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM); 1095533553f8SMarcel Holtmann if (!cp) 1096533553f8SMarcel Holtmann return; 1097533553f8SMarcel Holtmann 1098533553f8SMarcel Holtmann hci_dev_lock(hdev); 1099533553f8SMarcel Holtmann 1100533553f8SMarcel Holtmann hdev->le_scan_type = cp->type; 1101533553f8SMarcel Holtmann 1102533553f8SMarcel Holtmann hci_dev_unlock(hdev); 1103533553f8SMarcel Holtmann } 1104533553f8SMarcel Holtmann 1105b9a6328fSJohan Hedberg static bool has_pending_adv_report(struct hci_dev *hdev) 1106b9a6328fSJohan Hedberg { 1107b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1108b9a6328fSJohan Hedberg 1109b9a6328fSJohan Hedberg return bacmp(&d->last_adv_addr, BDADDR_ANY); 1110b9a6328fSJohan Hedberg } 1111b9a6328fSJohan Hedberg 1112b9a6328fSJohan Hedberg static void clear_pending_adv_report(struct hci_dev *hdev) 1113b9a6328fSJohan Hedberg { 1114b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1115b9a6328fSJohan Hedberg 1116b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, BDADDR_ANY); 1117b9a6328fSJohan Hedberg d->last_adv_data_len = 0; 1118b9a6328fSJohan Hedberg } 1119b9a6328fSJohan Hedberg 1120b9a6328fSJohan Hedberg static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr, 1121c70a7e4cSMarcel Holtmann u8 bdaddr_type, s8 rssi, u32 flags, 1122c70a7e4cSMarcel Holtmann u8 *data, u8 len) 1123b9a6328fSJohan Hedberg { 1124b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1125b9a6328fSJohan Hedberg 1126b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, bdaddr); 1127b9a6328fSJohan Hedberg d->last_adv_addr_type = bdaddr_type; 1128ff5cd29fSJohan Hedberg d->last_adv_rssi = rssi; 1129c70a7e4cSMarcel Holtmann d->last_adv_flags = flags; 1130b9a6328fSJohan Hedberg memcpy(d->last_adv_data, data, len); 1131b9a6328fSJohan Hedberg d->last_adv_data_len = len; 1132b9a6328fSJohan Hedberg } 1133b9a6328fSJohan Hedberg 1134eb9d91f5SAndre Guedes static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, 1135eb9d91f5SAndre Guedes struct sk_buff *skb) 1136eb9d91f5SAndre Guedes { 1137eb9d91f5SAndre Guedes struct hci_cp_le_set_scan_enable *cp; 1138eb9d91f5SAndre Guedes __u8 status = *((__u8 *) skb->data); 1139eb9d91f5SAndre Guedes 11409f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1141eb9d91f5SAndre Guedes 114245296acdSMarcel Holtmann if (status) 1143eb9d91f5SAndre Guedes return; 1144eb9d91f5SAndre Guedes 114545296acdSMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE); 114645296acdSMarcel Holtmann if (!cp) 11477ba8b4beSAndre Guedes return; 11487ba8b4beSAndre Guedes 11493fd319b8SAndre Guedes switch (cp->enable) { 11503fd319b8SAndre Guedes case LE_SCAN_ENABLE: 1151d23264a8SAndre Guedes set_bit(HCI_LE_SCAN, &hdev->dev_flags); 1152b9a6328fSJohan Hedberg if (hdev->le_scan_type == LE_SCAN_ACTIVE) 1153b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 115468a8aea4SAndrei Emeltchenko break; 115568a8aea4SAndrei Emeltchenko 115676a388beSAndre Guedes case LE_SCAN_DISABLE: 1157b9a6328fSJohan Hedberg /* We do this here instead of when setting DISCOVERY_STOPPED 1158b9a6328fSJohan Hedberg * since the latter would potentially require waiting for 1159b9a6328fSJohan Hedberg * inquiry to stop too. 1160b9a6328fSJohan Hedberg */ 1161b9a6328fSJohan Hedberg if (has_pending_adv_report(hdev)) { 1162b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1163b9a6328fSJohan Hedberg 1164b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 1165ab0aa433SJohan Hedberg d->last_adv_addr_type, NULL, 1166c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags, 1167ab0aa433SJohan Hedberg d->last_adv_data, 1168b9a6328fSJohan Hedberg d->last_adv_data_len, NULL, 0); 1169b9a6328fSJohan Hedberg } 1170b9a6328fSJohan Hedberg 1171317ac8cbSJohan Hedberg /* Cancel this timer so that we don't try to disable scanning 1172317ac8cbSJohan Hedberg * when it's already disabled. 1173317ac8cbSJohan Hedberg */ 1174317ac8cbSJohan Hedberg cancel_delayed_work(&hdev->le_scan_disable); 1175317ac8cbSJohan Hedberg 1176d23264a8SAndre Guedes clear_bit(HCI_LE_SCAN, &hdev->dev_flags); 117781ad6fd9SJohan Hedberg /* The HCI_LE_SCAN_INTERRUPTED flag indicates that we 117881ad6fd9SJohan Hedberg * interrupted scanning due to a connect request. Mark 117981ad6fd9SJohan Hedberg * therefore discovery as stopped. 118081ad6fd9SJohan Hedberg */ 118181ad6fd9SJohan Hedberg if (test_and_clear_bit(HCI_LE_SCAN_INTERRUPTED, 118281ad6fd9SJohan Hedberg &hdev->dev_flags)) 118381ad6fd9SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 118468a8aea4SAndrei Emeltchenko break; 118568a8aea4SAndrei Emeltchenko 118668a8aea4SAndrei Emeltchenko default: 118768a8aea4SAndrei Emeltchenko BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable); 118868a8aea4SAndrei Emeltchenko break; 118935815085SAndre Guedes } 1190eb9d91f5SAndre Guedes } 1191eb9d91f5SAndre Guedes 1192cf1d081fSJohan Hedberg static void hci_cc_le_read_white_list_size(struct hci_dev *hdev, 1193cf1d081fSJohan Hedberg struct sk_buff *skb) 1194cf1d081fSJohan Hedberg { 1195cf1d081fSJohan Hedberg struct hci_rp_le_read_white_list_size *rp = (void *) skb->data; 1196cf1d081fSJohan Hedberg 1197cf1d081fSJohan Hedberg BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size); 1198cf1d081fSJohan Hedberg 119945296acdSMarcel Holtmann if (rp->status) 120045296acdSMarcel Holtmann return; 120145296acdSMarcel Holtmann 1202cf1d081fSJohan Hedberg hdev->le_white_list_size = rp->size; 1203cf1d081fSJohan Hedberg } 1204cf1d081fSJohan Hedberg 12050f36b589SMarcel Holtmann static void hci_cc_le_clear_white_list(struct hci_dev *hdev, 12060f36b589SMarcel Holtmann struct sk_buff *skb) 12070f36b589SMarcel Holtmann { 12080f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 12090f36b589SMarcel Holtmann 12100f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 12110f36b589SMarcel Holtmann 121245296acdSMarcel Holtmann if (status) 121345296acdSMarcel Holtmann return; 121445296acdSMarcel Holtmann 12150f36b589SMarcel Holtmann hci_white_list_clear(hdev); 12160f36b589SMarcel Holtmann } 12170f36b589SMarcel Holtmann 12180f36b589SMarcel Holtmann static void hci_cc_le_add_to_white_list(struct hci_dev *hdev, 12190f36b589SMarcel Holtmann struct sk_buff *skb) 12200f36b589SMarcel Holtmann { 12210f36b589SMarcel Holtmann struct hci_cp_le_add_to_white_list *sent; 12220f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 12230f36b589SMarcel Holtmann 12240f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 12250f36b589SMarcel Holtmann 122645296acdSMarcel Holtmann if (status) 122745296acdSMarcel Holtmann return; 122845296acdSMarcel Holtmann 12290f36b589SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST); 12300f36b589SMarcel Holtmann if (!sent) 12310f36b589SMarcel Holtmann return; 12320f36b589SMarcel Holtmann 12330f36b589SMarcel Holtmann hci_white_list_add(hdev, &sent->bdaddr, sent->bdaddr_type); 12340f36b589SMarcel Holtmann } 12350f36b589SMarcel Holtmann 12360f36b589SMarcel Holtmann static void hci_cc_le_del_from_white_list(struct hci_dev *hdev, 12370f36b589SMarcel Holtmann struct sk_buff *skb) 12380f36b589SMarcel Holtmann { 12390f36b589SMarcel Holtmann struct hci_cp_le_del_from_white_list *sent; 12400f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 12410f36b589SMarcel Holtmann 12420f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 12430f36b589SMarcel Holtmann 124445296acdSMarcel Holtmann if (status) 124545296acdSMarcel Holtmann return; 124645296acdSMarcel Holtmann 12470f36b589SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST); 12480f36b589SMarcel Holtmann if (!sent) 12490f36b589SMarcel Holtmann return; 12500f36b589SMarcel Holtmann 12510f36b589SMarcel Holtmann hci_white_list_del(hdev, &sent->bdaddr, sent->bdaddr_type); 12520f36b589SMarcel Holtmann } 12530f36b589SMarcel Holtmann 12549b008c04SJohan Hedberg static void hci_cc_le_read_supported_states(struct hci_dev *hdev, 12559b008c04SJohan Hedberg struct sk_buff *skb) 12569b008c04SJohan Hedberg { 12579b008c04SJohan Hedberg struct hci_rp_le_read_supported_states *rp = (void *) skb->data; 12589b008c04SJohan Hedberg 12599b008c04SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 12609b008c04SJohan Hedberg 126145296acdSMarcel Holtmann if (rp->status) 126245296acdSMarcel Holtmann return; 126345296acdSMarcel Holtmann 12649b008c04SJohan Hedberg memcpy(hdev->le_states, rp->le_states, 8); 12659b008c04SJohan Hedberg } 12669b008c04SJohan Hedberg 12676039aa73SGustavo Padovan static void hci_cc_write_le_host_supported(struct hci_dev *hdev, 1268f9b49306SAndre Guedes struct sk_buff *skb) 1269f9b49306SAndre Guedes { 127006199cf8SJohan Hedberg struct hci_cp_write_le_host_supported *sent; 1271f9b49306SAndre Guedes __u8 status = *((__u8 *) skb->data); 1272f9b49306SAndre Guedes 12739f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1274f9b49306SAndre Guedes 127545296acdSMarcel Holtmann if (status) 127645296acdSMarcel Holtmann return; 127745296acdSMarcel Holtmann 127806199cf8SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED); 12798f984dfaSJohan Hedberg if (!sent) 1280f9b49306SAndre Guedes return; 1281f9b49306SAndre Guedes 1282416a4ae5SJohan Hedberg if (sent->le) { 1283cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE; 1284416a4ae5SJohan Hedberg set_bit(HCI_LE_ENABLED, &hdev->dev_flags); 1285416a4ae5SJohan Hedberg } else { 1286cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE; 1287416a4ae5SJohan Hedberg clear_bit(HCI_LE_ENABLED, &hdev->dev_flags); 1288f3d3444aSJohan Hedberg clear_bit(HCI_ADVERTISING, &hdev->dev_flags); 1289416a4ae5SJohan Hedberg } 129053b2caabSJohan Hedberg 129153b2caabSJohan Hedberg if (sent->simul) 1292cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE_BREDR; 129353b2caabSJohan Hedberg else 1294cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE_BREDR; 12958f984dfaSJohan Hedberg } 1296f9b49306SAndre Guedes 129756ed2cb8SJohan Hedberg static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb) 129856ed2cb8SJohan Hedberg { 129956ed2cb8SJohan Hedberg struct hci_cp_le_set_adv_param *cp; 130056ed2cb8SJohan Hedberg u8 status = *((u8 *) skb->data); 130156ed2cb8SJohan Hedberg 130256ed2cb8SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 130356ed2cb8SJohan Hedberg 130456ed2cb8SJohan Hedberg if (status) 130556ed2cb8SJohan Hedberg return; 130656ed2cb8SJohan Hedberg 130756ed2cb8SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM); 130856ed2cb8SJohan Hedberg if (!cp) 130956ed2cb8SJohan Hedberg return; 131056ed2cb8SJohan Hedberg 131156ed2cb8SJohan Hedberg hci_dev_lock(hdev); 131256ed2cb8SJohan Hedberg hdev->adv_addr_type = cp->own_address_type; 131356ed2cb8SJohan Hedberg hci_dev_unlock(hdev); 131456ed2cb8SJohan Hedberg } 131556ed2cb8SJohan Hedberg 131693c284eeSAndrei Emeltchenko static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev, 131793c284eeSAndrei Emeltchenko struct sk_buff *skb) 131893c284eeSAndrei Emeltchenko { 131993c284eeSAndrei Emeltchenko struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data; 132093c284eeSAndrei Emeltchenko 132193c284eeSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x", 132293c284eeSAndrei Emeltchenko hdev->name, rp->status, rp->phy_handle); 132393c284eeSAndrei Emeltchenko 132493c284eeSAndrei Emeltchenko if (rp->status) 132593c284eeSAndrei Emeltchenko return; 132693c284eeSAndrei Emeltchenko 132793c284eeSAndrei Emeltchenko amp_write_rem_assoc_continue(hdev, rp->phy_handle); 132893c284eeSAndrei Emeltchenko } 132993c284eeSAndrei Emeltchenko 13305ae76a94SAndrzej Kaczmarek static void hci_cc_read_rssi(struct hci_dev *hdev, struct sk_buff *skb) 13315ae76a94SAndrzej Kaczmarek { 13325ae76a94SAndrzej Kaczmarek struct hci_rp_read_rssi *rp = (void *) skb->data; 13335ae76a94SAndrzej Kaczmarek struct hci_conn *conn; 13345ae76a94SAndrzej Kaczmarek 13355ae76a94SAndrzej Kaczmarek BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 13365ae76a94SAndrzej Kaczmarek 13375ae76a94SAndrzej Kaczmarek if (rp->status) 13385ae76a94SAndrzej Kaczmarek return; 13395ae76a94SAndrzej Kaczmarek 13405ae76a94SAndrzej Kaczmarek hci_dev_lock(hdev); 13415ae76a94SAndrzej Kaczmarek 13425ae76a94SAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 13435ae76a94SAndrzej Kaczmarek if (conn) 13445ae76a94SAndrzej Kaczmarek conn->rssi = rp->rssi; 13455ae76a94SAndrzej Kaczmarek 13465ae76a94SAndrzej Kaczmarek hci_dev_unlock(hdev); 13475ae76a94SAndrzej Kaczmarek } 13485ae76a94SAndrzej Kaczmarek 13495a134faeSAndrzej Kaczmarek static void hci_cc_read_tx_power(struct hci_dev *hdev, struct sk_buff *skb) 13505a134faeSAndrzej Kaczmarek { 13515a134faeSAndrzej Kaczmarek struct hci_cp_read_tx_power *sent; 13525a134faeSAndrzej Kaczmarek struct hci_rp_read_tx_power *rp = (void *) skb->data; 13535a134faeSAndrzej Kaczmarek struct hci_conn *conn; 13545a134faeSAndrzej Kaczmarek 13555a134faeSAndrzej Kaczmarek BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 13565a134faeSAndrzej Kaczmarek 13575a134faeSAndrzej Kaczmarek if (rp->status) 13585a134faeSAndrzej Kaczmarek return; 13595a134faeSAndrzej Kaczmarek 13605a134faeSAndrzej Kaczmarek sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER); 13615a134faeSAndrzej Kaczmarek if (!sent) 13625a134faeSAndrzej Kaczmarek return; 13635a134faeSAndrzej Kaczmarek 13645a134faeSAndrzej Kaczmarek hci_dev_lock(hdev); 13655a134faeSAndrzej Kaczmarek 13665a134faeSAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 1367d0455ed9SAndrzej Kaczmarek if (!conn) 1368d0455ed9SAndrzej Kaczmarek goto unlock; 13695a134faeSAndrzej Kaczmarek 1370d0455ed9SAndrzej Kaczmarek switch (sent->type) { 1371d0455ed9SAndrzej Kaczmarek case 0x00: 1372d0455ed9SAndrzej Kaczmarek conn->tx_power = rp->tx_power; 1373d0455ed9SAndrzej Kaczmarek break; 1374d0455ed9SAndrzej Kaczmarek case 0x01: 1375d0455ed9SAndrzej Kaczmarek conn->max_tx_power = rp->tx_power; 1376d0455ed9SAndrzej Kaczmarek break; 1377d0455ed9SAndrzej Kaczmarek } 1378d0455ed9SAndrzej Kaczmarek 1379d0455ed9SAndrzej Kaczmarek unlock: 13805a134faeSAndrzej Kaczmarek hci_dev_unlock(hdev); 13815a134faeSAndrzej Kaczmarek } 13825a134faeSAndrzej Kaczmarek 13836039aa73SGustavo Padovan static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) 1384a9de9248SMarcel Holtmann { 13859f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1386a9de9248SMarcel Holtmann 1387a9de9248SMarcel Holtmann if (status) { 1388a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 1389314b2381SJohan Hedberg return; 1390314b2381SJohan Hedberg } 1391314b2381SJohan Hedberg 139289352e7dSAndre Guedes set_bit(HCI_INQUIRY, &hdev->flags); 1393a9de9248SMarcel Holtmann } 1394a9de9248SMarcel Holtmann 13956039aa73SGustavo Padovan static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) 13961da177e4SLinus Torvalds { 1397a9de9248SMarcel Holtmann struct hci_cp_create_conn *cp; 13981da177e4SLinus Torvalds struct hci_conn *conn; 13991da177e4SLinus Torvalds 14009f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1401a9de9248SMarcel Holtmann 1402a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN); 14031da177e4SLinus Torvalds if (!cp) 14041da177e4SLinus Torvalds return; 14051da177e4SLinus Torvalds 14061da177e4SLinus Torvalds hci_dev_lock(hdev); 14071da177e4SLinus Torvalds 14081da177e4SLinus Torvalds conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 14091da177e4SLinus Torvalds 14106ed93dc6SAndrei Emeltchenko BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn); 14111da177e4SLinus Torvalds 14121da177e4SLinus Torvalds if (status) { 14131da177e4SLinus Torvalds if (conn && conn->state == BT_CONNECT) { 14144c67bc74SMarcel Holtmann if (status != 0x0c || conn->attempt > 2) { 14151da177e4SLinus Torvalds conn->state = BT_CLOSED; 14161da177e4SLinus Torvalds hci_proto_connect_cfm(conn, status); 14171da177e4SLinus Torvalds hci_conn_del(conn); 14184c67bc74SMarcel Holtmann } else 14194c67bc74SMarcel Holtmann conn->state = BT_CONNECT2; 14201da177e4SLinus Torvalds } 14211da177e4SLinus Torvalds } else { 14221da177e4SLinus Torvalds if (!conn) { 14231da177e4SLinus Torvalds conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr); 14241da177e4SLinus Torvalds if (conn) { 1425a0c808b3SJohan Hedberg conn->out = true; 14264dae2798SJohan Hedberg set_bit(HCI_CONN_MASTER, &conn->flags); 14271da177e4SLinus Torvalds } else 1428893ef971SGustavo F. Padovan BT_ERR("No memory for new connection"); 14291da177e4SLinus Torvalds } 14301da177e4SLinus Torvalds } 14311da177e4SLinus Torvalds 14321da177e4SLinus Torvalds hci_dev_unlock(hdev); 14331da177e4SLinus Torvalds } 14341da177e4SLinus Torvalds 1435a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status) 14361da177e4SLinus Torvalds { 1437a9de9248SMarcel Holtmann struct hci_cp_add_sco *cp; 14381da177e4SLinus Torvalds struct hci_conn *acl, *sco; 14391da177e4SLinus Torvalds __u16 handle; 14401da177e4SLinus Torvalds 14419f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1442b6a0dc82SMarcel Holtmann 1443a9de9248SMarcel Holtmann if (!status) 1444a9de9248SMarcel Holtmann return; 1445a9de9248SMarcel Holtmann 1446a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO); 14471da177e4SLinus Torvalds if (!cp) 1448a9de9248SMarcel Holtmann return; 14491da177e4SLinus Torvalds 14501da177e4SLinus Torvalds handle = __le16_to_cpu(cp->handle); 14511da177e4SLinus Torvalds 14529f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, handle); 14531da177e4SLinus Torvalds 14541da177e4SLinus Torvalds hci_dev_lock(hdev); 14551da177e4SLinus Torvalds 14561da177e4SLinus Torvalds acl = hci_conn_hash_lookup_handle(hdev, handle); 14575a08ecceSAndrei Emeltchenko if (acl) { 14585a08ecceSAndrei Emeltchenko sco = acl->link; 14595a08ecceSAndrei Emeltchenko if (sco) { 14601da177e4SLinus Torvalds sco->state = BT_CLOSED; 14611da177e4SLinus Torvalds 14621da177e4SLinus Torvalds hci_proto_connect_cfm(sco, status); 14631da177e4SLinus Torvalds hci_conn_del(sco); 14641da177e4SLinus Torvalds } 14655a08ecceSAndrei Emeltchenko } 14661da177e4SLinus Torvalds 14671da177e4SLinus Torvalds hci_dev_unlock(hdev); 14681da177e4SLinus Torvalds } 14691da177e4SLinus Torvalds 1470f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status) 1471f8558555SMarcel Holtmann { 1472f8558555SMarcel Holtmann struct hci_cp_auth_requested *cp; 1473f8558555SMarcel Holtmann struct hci_conn *conn; 1474f8558555SMarcel Holtmann 14759f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1476f8558555SMarcel Holtmann 1477f8558555SMarcel Holtmann if (!status) 1478f8558555SMarcel Holtmann return; 1479f8558555SMarcel Holtmann 1480f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED); 1481f8558555SMarcel Holtmann if (!cp) 1482f8558555SMarcel Holtmann return; 1483f8558555SMarcel Holtmann 1484f8558555SMarcel Holtmann hci_dev_lock(hdev); 1485f8558555SMarcel Holtmann 1486f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1487f8558555SMarcel Holtmann if (conn) { 1488f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1489f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, status); 149076a68ba0SDavid Herrmann hci_conn_drop(conn); 1491f8558555SMarcel Holtmann } 1492f8558555SMarcel Holtmann } 1493f8558555SMarcel Holtmann 1494f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1495f8558555SMarcel Holtmann } 1496f8558555SMarcel Holtmann 1497f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) 1498f8558555SMarcel Holtmann { 1499f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt *cp; 1500f8558555SMarcel Holtmann struct hci_conn *conn; 1501f8558555SMarcel Holtmann 15029f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1503f8558555SMarcel Holtmann 1504f8558555SMarcel Holtmann if (!status) 1505f8558555SMarcel Holtmann return; 1506f8558555SMarcel Holtmann 1507f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT); 1508f8558555SMarcel Holtmann if (!cp) 1509f8558555SMarcel Holtmann return; 1510f8558555SMarcel Holtmann 1511f8558555SMarcel Holtmann hci_dev_lock(hdev); 1512f8558555SMarcel Holtmann 1513f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1514f8558555SMarcel Holtmann if (conn) { 1515f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1516f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, status); 151776a68ba0SDavid Herrmann hci_conn_drop(conn); 1518f8558555SMarcel Holtmann } 1519f8558555SMarcel Holtmann } 1520f8558555SMarcel Holtmann 1521f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1522f8558555SMarcel Holtmann } 1523f8558555SMarcel Holtmann 1524127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev, 1525392599b9SJohan Hedberg struct hci_conn *conn) 1526392599b9SJohan Hedberg { 1527392599b9SJohan Hedberg if (conn->state != BT_CONFIG || !conn->out) 1528392599b9SJohan Hedberg return 0; 1529392599b9SJohan Hedberg 1530765c2a96SJohan Hedberg if (conn->pending_sec_level == BT_SECURITY_SDP) 1531392599b9SJohan Hedberg return 0; 1532392599b9SJohan Hedberg 1533392599b9SJohan Hedberg /* Only request authentication for SSP connections or non-SSP 1534264b8b4eSJohan Hedberg * devices with sec_level MEDIUM or HIGH or if MITM protection 1535264b8b4eSJohan Hedberg * is requested. 1536264b8b4eSJohan Hedberg */ 1537807deac2SGustavo Padovan if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) && 15387e3691e1SJohan Hedberg conn->pending_sec_level != BT_SECURITY_FIPS && 1539264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_HIGH && 1540264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_MEDIUM) 1541392599b9SJohan Hedberg return 0; 1542392599b9SJohan Hedberg 1543392599b9SJohan Hedberg return 1; 1544392599b9SJohan Hedberg } 1545392599b9SJohan Hedberg 15466039aa73SGustavo Padovan static int hci_resolve_name(struct hci_dev *hdev, 154700abfe44SGustavo F. Padovan struct inquiry_entry *e) 154830dc78e1SJohan Hedberg { 154930dc78e1SJohan Hedberg struct hci_cp_remote_name_req cp; 155030dc78e1SJohan Hedberg 155130dc78e1SJohan Hedberg memset(&cp, 0, sizeof(cp)); 155230dc78e1SJohan Hedberg 155330dc78e1SJohan Hedberg bacpy(&cp.bdaddr, &e->data.bdaddr); 155430dc78e1SJohan Hedberg cp.pscan_rep_mode = e->data.pscan_rep_mode; 155530dc78e1SJohan Hedberg cp.pscan_mode = e->data.pscan_mode; 155630dc78e1SJohan Hedberg cp.clock_offset = e->data.clock_offset; 155730dc78e1SJohan Hedberg 155830dc78e1SJohan Hedberg return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 155930dc78e1SJohan Hedberg } 156030dc78e1SJohan Hedberg 1561b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev) 156230dc78e1SJohan Hedberg { 156330dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 156430dc78e1SJohan Hedberg struct inquiry_entry *e; 156530dc78e1SJohan Hedberg 1566b644ba33SJohan Hedberg if (list_empty(&discov->resolve)) 1567b644ba33SJohan Hedberg return false; 1568b644ba33SJohan Hedberg 1569b644ba33SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 1570c810089cSRam Malovany if (!e) 1571c810089cSRam Malovany return false; 1572c810089cSRam Malovany 1573b644ba33SJohan Hedberg if (hci_resolve_name(hdev, e) == 0) { 1574b644ba33SJohan Hedberg e->name_state = NAME_PENDING; 1575b644ba33SJohan Hedberg return true; 1576b644ba33SJohan Hedberg } 1577b644ba33SJohan Hedberg 1578b644ba33SJohan Hedberg return false; 1579b644ba33SJohan Hedberg } 1580b644ba33SJohan Hedberg 1581b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, 1582b644ba33SJohan Hedberg bdaddr_t *bdaddr, u8 *name, u8 name_len) 1583b644ba33SJohan Hedberg { 1584b644ba33SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 1585b644ba33SJohan Hedberg struct inquiry_entry *e; 1586b644ba33SJohan Hedberg 1587b644ba33SJohan Hedberg if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 158804124681SGustavo F. Padovan mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name, 158904124681SGustavo F. Padovan name_len, conn->dev_class); 1590b644ba33SJohan Hedberg 1591b644ba33SJohan Hedberg if (discov->state == DISCOVERY_STOPPED) 1592b644ba33SJohan Hedberg return; 1593b644ba33SJohan Hedberg 159430dc78e1SJohan Hedberg if (discov->state == DISCOVERY_STOPPING) 159530dc78e1SJohan Hedberg goto discov_complete; 159630dc78e1SJohan Hedberg 159730dc78e1SJohan Hedberg if (discov->state != DISCOVERY_RESOLVING) 159830dc78e1SJohan Hedberg return; 159930dc78e1SJohan Hedberg 160030dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING); 16017cc8380eSRam Malovany /* If the device was not found in a list of found devices names of which 16027cc8380eSRam Malovany * are pending. there is no need to continue resolving a next name as it 16037cc8380eSRam Malovany * will be done upon receiving another Remote Name Request Complete 16047cc8380eSRam Malovany * Event */ 16057cc8380eSRam Malovany if (!e) 16067cc8380eSRam Malovany return; 16077cc8380eSRam Malovany 160830dc78e1SJohan Hedberg list_del(&e->list); 16097cc8380eSRam Malovany if (name) { 16107cc8380eSRam Malovany e->name_state = NAME_KNOWN; 1611b644ba33SJohan Hedberg mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, 1612b644ba33SJohan Hedberg e->data.rssi, name, name_len); 1613c3e7c0d9SRam Malovany } else { 1614c3e7c0d9SRam Malovany e->name_state = NAME_NOT_KNOWN; 161530dc78e1SJohan Hedberg } 161630dc78e1SJohan Hedberg 1617b644ba33SJohan Hedberg if (hci_resolve_next_name(hdev)) 161830dc78e1SJohan Hedberg return; 161930dc78e1SJohan Hedberg 162030dc78e1SJohan Hedberg discov_complete: 162130dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 162230dc78e1SJohan Hedberg } 162330dc78e1SJohan Hedberg 1624a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) 16251da177e4SLinus Torvalds { 1626127178d2SJohan Hedberg struct hci_cp_remote_name_req *cp; 1627127178d2SJohan Hedberg struct hci_conn *conn; 1628127178d2SJohan Hedberg 16299f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1630127178d2SJohan Hedberg 1631127178d2SJohan Hedberg /* If successful wait for the name req complete event before 1632127178d2SJohan Hedberg * checking for the need to do authentication */ 1633127178d2SJohan Hedberg if (!status) 1634127178d2SJohan Hedberg return; 1635127178d2SJohan Hedberg 1636127178d2SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ); 1637127178d2SJohan Hedberg if (!cp) 1638127178d2SJohan Hedberg return; 1639127178d2SJohan Hedberg 1640127178d2SJohan Hedberg hci_dev_lock(hdev); 1641127178d2SJohan Hedberg 1642127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 1643b644ba33SJohan Hedberg 1644b644ba33SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 1645b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0); 1646b644ba33SJohan Hedberg 164779c6c70cSJohan Hedberg if (!conn) 164879c6c70cSJohan Hedberg goto unlock; 164979c6c70cSJohan Hedberg 165079c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 165179c6c70cSJohan Hedberg goto unlock; 165279c6c70cSJohan Hedberg 165351a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 1654c1f23a2bSJohannes Berg struct hci_cp_auth_requested auth_cp; 1655c1f23a2bSJohannes Berg 1656c1f23a2bSJohannes Berg auth_cp.handle = __cpu_to_le16(conn->handle); 1657c1f23a2bSJohannes Berg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, 1658c1f23a2bSJohannes Berg sizeof(auth_cp), &auth_cp); 1659127178d2SJohan Hedberg } 1660127178d2SJohan Hedberg 166179c6c70cSJohan Hedberg unlock: 1662127178d2SJohan Hedberg hci_dev_unlock(hdev); 1663a9de9248SMarcel Holtmann } 16641da177e4SLinus Torvalds 1665769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) 1666769be974SMarcel Holtmann { 1667769be974SMarcel Holtmann struct hci_cp_read_remote_features *cp; 1668769be974SMarcel Holtmann struct hci_conn *conn; 1669769be974SMarcel Holtmann 16709f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1671769be974SMarcel Holtmann 1672769be974SMarcel Holtmann if (!status) 1673769be974SMarcel Holtmann return; 1674769be974SMarcel Holtmann 1675769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES); 1676769be974SMarcel Holtmann if (!cp) 1677769be974SMarcel Holtmann return; 1678769be974SMarcel Holtmann 1679769be974SMarcel Holtmann hci_dev_lock(hdev); 1680769be974SMarcel Holtmann 1681769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1682769be974SMarcel Holtmann if (conn) { 1683769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1684769be974SMarcel Holtmann hci_proto_connect_cfm(conn, status); 168576a68ba0SDavid Herrmann hci_conn_drop(conn); 1686769be974SMarcel Holtmann } 1687769be974SMarcel Holtmann } 1688769be974SMarcel Holtmann 1689769be974SMarcel Holtmann hci_dev_unlock(hdev); 1690769be974SMarcel Holtmann } 1691769be974SMarcel Holtmann 1692769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status) 1693769be974SMarcel Holtmann { 1694769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features *cp; 1695769be974SMarcel Holtmann struct hci_conn *conn; 1696769be974SMarcel Holtmann 16979f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1698769be974SMarcel Holtmann 1699769be974SMarcel Holtmann if (!status) 1700769be974SMarcel Holtmann return; 1701769be974SMarcel Holtmann 1702769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES); 1703769be974SMarcel Holtmann if (!cp) 1704769be974SMarcel Holtmann return; 1705769be974SMarcel Holtmann 1706769be974SMarcel Holtmann hci_dev_lock(hdev); 1707769be974SMarcel Holtmann 1708769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1709769be974SMarcel Holtmann if (conn) { 1710769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1711769be974SMarcel Holtmann hci_proto_connect_cfm(conn, status); 171276a68ba0SDavid Herrmann hci_conn_drop(conn); 1713769be974SMarcel Holtmann } 1714769be974SMarcel Holtmann } 1715769be974SMarcel Holtmann 1716769be974SMarcel Holtmann hci_dev_unlock(hdev); 1717769be974SMarcel Holtmann } 1718769be974SMarcel Holtmann 1719a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) 1720a9de9248SMarcel Holtmann { 1721b6a0dc82SMarcel Holtmann struct hci_cp_setup_sync_conn *cp; 1722b6a0dc82SMarcel Holtmann struct hci_conn *acl, *sco; 1723b6a0dc82SMarcel Holtmann __u16 handle; 1724b6a0dc82SMarcel Holtmann 17259f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1726b6a0dc82SMarcel Holtmann 1727b6a0dc82SMarcel Holtmann if (!status) 1728b6a0dc82SMarcel Holtmann return; 1729b6a0dc82SMarcel Holtmann 1730b6a0dc82SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN); 1731b6a0dc82SMarcel Holtmann if (!cp) 1732b6a0dc82SMarcel Holtmann return; 1733b6a0dc82SMarcel Holtmann 1734b6a0dc82SMarcel Holtmann handle = __le16_to_cpu(cp->handle); 1735b6a0dc82SMarcel Holtmann 17369f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, handle); 1737b6a0dc82SMarcel Holtmann 1738b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 1739b6a0dc82SMarcel Holtmann 1740b6a0dc82SMarcel Holtmann acl = hci_conn_hash_lookup_handle(hdev, handle); 17415a08ecceSAndrei Emeltchenko if (acl) { 17425a08ecceSAndrei Emeltchenko sco = acl->link; 17435a08ecceSAndrei Emeltchenko if (sco) { 1744b6a0dc82SMarcel Holtmann sco->state = BT_CLOSED; 1745b6a0dc82SMarcel Holtmann 1746b6a0dc82SMarcel Holtmann hci_proto_connect_cfm(sco, status); 1747b6a0dc82SMarcel Holtmann hci_conn_del(sco); 1748b6a0dc82SMarcel Holtmann } 17495a08ecceSAndrei Emeltchenko } 1750b6a0dc82SMarcel Holtmann 1751b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 1752a9de9248SMarcel Holtmann } 1753a9de9248SMarcel Holtmann 1754a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) 1755a9de9248SMarcel Holtmann { 1756a9de9248SMarcel Holtmann struct hci_cp_sniff_mode *cp; 175704837f64SMarcel Holtmann struct hci_conn *conn; 175804837f64SMarcel Holtmann 17599f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1760a9de9248SMarcel Holtmann 1761a9de9248SMarcel Holtmann if (!status) 1762a9de9248SMarcel Holtmann return; 1763a9de9248SMarcel Holtmann 1764a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE); 176504837f64SMarcel Holtmann if (!cp) 1766a9de9248SMarcel Holtmann return; 176704837f64SMarcel Holtmann 176804837f64SMarcel Holtmann hci_dev_lock(hdev); 176904837f64SMarcel Holtmann 177004837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1771e73439d8SMarcel Holtmann if (conn) { 177251a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 177304837f64SMarcel Holtmann 177451a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 1775e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 1776e73439d8SMarcel Holtmann } 1777e73439d8SMarcel Holtmann 177804837f64SMarcel Holtmann hci_dev_unlock(hdev); 177904837f64SMarcel Holtmann } 178004837f64SMarcel Holtmann 1781a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) 1782a9de9248SMarcel Holtmann { 1783a9de9248SMarcel Holtmann struct hci_cp_exit_sniff_mode *cp; 178404837f64SMarcel Holtmann struct hci_conn *conn; 178504837f64SMarcel Holtmann 17869f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1787a9de9248SMarcel Holtmann 1788a9de9248SMarcel Holtmann if (!status) 1789a9de9248SMarcel Holtmann return; 1790a9de9248SMarcel Holtmann 1791a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE); 179204837f64SMarcel Holtmann if (!cp) 1793a9de9248SMarcel Holtmann return; 179404837f64SMarcel Holtmann 179504837f64SMarcel Holtmann hci_dev_lock(hdev); 179604837f64SMarcel Holtmann 179704837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1798e73439d8SMarcel Holtmann if (conn) { 179951a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 180004837f64SMarcel Holtmann 180151a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 1802e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 1803e73439d8SMarcel Holtmann } 1804e73439d8SMarcel Holtmann 180504837f64SMarcel Holtmann hci_dev_unlock(hdev); 180604837f64SMarcel Holtmann } 180704837f64SMarcel Holtmann 180888c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) 180988c3df13SJohan Hedberg { 181088c3df13SJohan Hedberg struct hci_cp_disconnect *cp; 181188c3df13SJohan Hedberg struct hci_conn *conn; 181288c3df13SJohan Hedberg 181388c3df13SJohan Hedberg if (!status) 181488c3df13SJohan Hedberg return; 181588c3df13SJohan Hedberg 181688c3df13SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT); 181788c3df13SJohan Hedberg if (!cp) 181888c3df13SJohan Hedberg return; 181988c3df13SJohan Hedberg 182088c3df13SJohan Hedberg hci_dev_lock(hdev); 182188c3df13SJohan Hedberg 182288c3df13SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 182388c3df13SJohan Hedberg if (conn) 182488c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 182588c3df13SJohan Hedberg conn->dst_type, status); 182688c3df13SJohan Hedberg 182788c3df13SJohan Hedberg hci_dev_unlock(hdev); 182888c3df13SJohan Hedberg } 182988c3df13SJohan Hedberg 1830a02226d6SAndrei Emeltchenko static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status) 1831a02226d6SAndrei Emeltchenko { 183293c284eeSAndrei Emeltchenko struct hci_cp_create_phy_link *cp; 183393c284eeSAndrei Emeltchenko 1834a02226d6SAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 183593c284eeSAndrei Emeltchenko 183693c284eeSAndrei Emeltchenko cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK); 183793c284eeSAndrei Emeltchenko if (!cp) 183893c284eeSAndrei Emeltchenko return; 183993c284eeSAndrei Emeltchenko 1840e58917b9SAndrei Emeltchenko hci_dev_lock(hdev); 1841e58917b9SAndrei Emeltchenko 1842e58917b9SAndrei Emeltchenko if (status) { 1843e58917b9SAndrei Emeltchenko struct hci_conn *hcon; 1844e58917b9SAndrei Emeltchenko 1845e58917b9SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle); 1846e58917b9SAndrei Emeltchenko if (hcon) 1847e58917b9SAndrei Emeltchenko hci_conn_del(hcon); 1848e58917b9SAndrei Emeltchenko } else { 184993c284eeSAndrei Emeltchenko amp_write_remote_assoc(hdev, cp->phy_handle); 1850a02226d6SAndrei Emeltchenko } 1851a02226d6SAndrei Emeltchenko 1852e58917b9SAndrei Emeltchenko hci_dev_unlock(hdev); 1853e58917b9SAndrei Emeltchenko } 1854e58917b9SAndrei Emeltchenko 18550b26ab9dSAndrei Emeltchenko static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status) 18560b26ab9dSAndrei Emeltchenko { 18570b26ab9dSAndrei Emeltchenko struct hci_cp_accept_phy_link *cp; 18580b26ab9dSAndrei Emeltchenko 18590b26ab9dSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 18600b26ab9dSAndrei Emeltchenko 18610b26ab9dSAndrei Emeltchenko if (status) 18620b26ab9dSAndrei Emeltchenko return; 18630b26ab9dSAndrei Emeltchenko 18640b26ab9dSAndrei Emeltchenko cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK); 18650b26ab9dSAndrei Emeltchenko if (!cp) 18660b26ab9dSAndrei Emeltchenko return; 18670b26ab9dSAndrei Emeltchenko 18680b26ab9dSAndrei Emeltchenko amp_write_remote_assoc(hdev, cp->phy_handle); 18690b26ab9dSAndrei Emeltchenko } 18700b26ab9dSAndrei Emeltchenko 1871cb1d68f7SJohan Hedberg static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status) 1872cb1d68f7SJohan Hedberg { 1873cb1d68f7SJohan Hedberg struct hci_cp_le_create_conn *cp; 1874cb1d68f7SJohan Hedberg struct hci_conn *conn; 1875cb1d68f7SJohan Hedberg 1876cb1d68f7SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 1877cb1d68f7SJohan Hedberg 1878cb1d68f7SJohan Hedberg /* All connection failure handling is taken care of by the 1879cb1d68f7SJohan Hedberg * hci_le_conn_failed function which is triggered by the HCI 1880cb1d68f7SJohan Hedberg * request completion callbacks used for connecting. 1881cb1d68f7SJohan Hedberg */ 1882cb1d68f7SJohan Hedberg if (status) 1883cb1d68f7SJohan Hedberg return; 1884cb1d68f7SJohan Hedberg 1885cb1d68f7SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN); 1886cb1d68f7SJohan Hedberg if (!cp) 1887cb1d68f7SJohan Hedberg return; 1888cb1d68f7SJohan Hedberg 1889cb1d68f7SJohan Hedberg hci_dev_lock(hdev); 1890cb1d68f7SJohan Hedberg 1891cb1d68f7SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr); 1892cb1d68f7SJohan Hedberg if (!conn) 1893cb1d68f7SJohan Hedberg goto unlock; 1894cb1d68f7SJohan Hedberg 1895cb1d68f7SJohan Hedberg /* Store the initiator and responder address information which 1896cb1d68f7SJohan Hedberg * is needed for SMP. These values will not change during the 1897cb1d68f7SJohan Hedberg * lifetime of the connection. 1898cb1d68f7SJohan Hedberg */ 1899cb1d68f7SJohan Hedberg conn->init_addr_type = cp->own_address_type; 1900cb1d68f7SJohan Hedberg if (cp->own_address_type == ADDR_LE_DEV_RANDOM) 1901cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->random_addr); 1902cb1d68f7SJohan Hedberg else 1903cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->bdaddr); 1904cb1d68f7SJohan Hedberg 1905cb1d68f7SJohan Hedberg conn->resp_addr_type = cp->peer_addr_type; 1906cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &cp->peer_addr); 1907cb1d68f7SJohan Hedberg 19089489eca4SJohan Hedberg /* We don't want the connection attempt to stick around 19099489eca4SJohan Hedberg * indefinitely since LE doesn't have a page timeout concept 19109489eca4SJohan Hedberg * like BR/EDR. Set a timer for any connection that doesn't use 19119489eca4SJohan Hedberg * the white list for connecting. 19129489eca4SJohan Hedberg */ 19139489eca4SJohan Hedberg if (cp->filter_policy == HCI_LE_USE_PEER_ADDR) 19149489eca4SJohan Hedberg queue_delayed_work(conn->hdev->workqueue, 19159489eca4SJohan Hedberg &conn->le_conn_timeout, 191609ae260bSJohan Hedberg conn->conn_timeout); 19179489eca4SJohan Hedberg 1918cb1d68f7SJohan Hedberg unlock: 1919cb1d68f7SJohan Hedberg hci_dev_unlock(hdev); 1920cb1d68f7SJohan Hedberg } 1921cb1d68f7SJohan Hedberg 192281d0c8adSJohan Hedberg static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) 192381d0c8adSJohan Hedberg { 192481d0c8adSJohan Hedberg struct hci_cp_le_start_enc *cp; 192581d0c8adSJohan Hedberg struct hci_conn *conn; 192681d0c8adSJohan Hedberg 192781d0c8adSJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 192881d0c8adSJohan Hedberg 192981d0c8adSJohan Hedberg if (!status) 193081d0c8adSJohan Hedberg return; 193181d0c8adSJohan Hedberg 193281d0c8adSJohan Hedberg hci_dev_lock(hdev); 193381d0c8adSJohan Hedberg 193481d0c8adSJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC); 193581d0c8adSJohan Hedberg if (!cp) 193681d0c8adSJohan Hedberg goto unlock; 193781d0c8adSJohan Hedberg 193881d0c8adSJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 193981d0c8adSJohan Hedberg if (!conn) 194081d0c8adSJohan Hedberg goto unlock; 194181d0c8adSJohan Hedberg 194281d0c8adSJohan Hedberg if (conn->state != BT_CONNECTED) 194381d0c8adSJohan Hedberg goto unlock; 194481d0c8adSJohan Hedberg 194581d0c8adSJohan Hedberg hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 194681d0c8adSJohan Hedberg hci_conn_drop(conn); 194781d0c8adSJohan Hedberg 194881d0c8adSJohan Hedberg unlock: 194981d0c8adSJohan Hedberg hci_dev_unlock(hdev); 195081d0c8adSJohan Hedberg } 195181d0c8adSJohan Hedberg 19526039aa73SGustavo Padovan static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 19531da177e4SLinus Torvalds { 19541da177e4SLinus Torvalds __u8 status = *((__u8 *) skb->data); 195530dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 195630dc78e1SJohan Hedberg struct inquiry_entry *e; 19571da177e4SLinus Torvalds 19589f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 19591da177e4SLinus Torvalds 1960a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 196189352e7dSAndre Guedes 196289352e7dSAndre Guedes if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) 196389352e7dSAndre Guedes return; 196489352e7dSAndre Guedes 19654e857c58SPeter Zijlstra smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */ 19663e13fa1eSAndre Guedes wake_up_bit(&hdev->flags, HCI_INQUIRY); 19673e13fa1eSAndre Guedes 1968a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 196930dc78e1SJohan Hedberg return; 197030dc78e1SJohan Hedberg 197156e5cb86SJohan Hedberg hci_dev_lock(hdev); 197230dc78e1SJohan Hedberg 1973343f935bSAndre Guedes if (discov->state != DISCOVERY_FINDING) 197430dc78e1SJohan Hedberg goto unlock; 197530dc78e1SJohan Hedberg 197630dc78e1SJohan Hedberg if (list_empty(&discov->resolve)) { 1977ff9ef578SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 197830dc78e1SJohan Hedberg goto unlock; 197930dc78e1SJohan Hedberg } 198030dc78e1SJohan Hedberg 198130dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 198230dc78e1SJohan Hedberg if (e && hci_resolve_name(hdev, e) == 0) { 198330dc78e1SJohan Hedberg e->name_state = NAME_PENDING; 198430dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_RESOLVING); 198530dc78e1SJohan Hedberg } else { 198630dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 198730dc78e1SJohan Hedberg } 198830dc78e1SJohan Hedberg 198930dc78e1SJohan Hedberg unlock: 199056e5cb86SJohan Hedberg hci_dev_unlock(hdev); 19911da177e4SLinus Torvalds } 19921da177e4SLinus Torvalds 19936039aa73SGustavo Padovan static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) 19941da177e4SLinus Torvalds { 199545bb4bf0SMarcel Holtmann struct inquiry_data data; 1996a9de9248SMarcel Holtmann struct inquiry_info *info = (void *) (skb->data + 1); 19971da177e4SLinus Torvalds int num_rsp = *((__u8 *) skb->data); 19981da177e4SLinus Torvalds 19991da177e4SLinus Torvalds BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 20001da177e4SLinus Torvalds 200145bb4bf0SMarcel Holtmann if (!num_rsp) 200245bb4bf0SMarcel Holtmann return; 200345bb4bf0SMarcel Holtmann 20041519cc17SAndre Guedes if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) 20051519cc17SAndre Guedes return; 20061519cc17SAndre Guedes 20071da177e4SLinus Torvalds hci_dev_lock(hdev); 200845bb4bf0SMarcel Holtmann 2009e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 2010af58925cSMarcel Holtmann u32 flags; 20113175405bSJohan Hedberg 20121da177e4SLinus Torvalds bacpy(&data.bdaddr, &info->bdaddr); 20131da177e4SLinus Torvalds data.pscan_rep_mode = info->pscan_rep_mode; 20141da177e4SLinus Torvalds data.pscan_period_mode = info->pscan_period_mode; 20151da177e4SLinus Torvalds data.pscan_mode = info->pscan_mode; 20161da177e4SLinus Torvalds memcpy(data.dev_class, info->dev_class, 3); 20171da177e4SLinus Torvalds data.clock_offset = info->clock_offset; 20181da177e4SLinus Torvalds data.rssi = 0x00; 201941a96212SMarcel Holtmann data.ssp_mode = 0x00; 20203175405bSJohan Hedberg 2021af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 2022af58925cSMarcel Holtmann 202348264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 2024af58925cSMarcel Holtmann info->dev_class, 0, flags, NULL, 0, NULL, 0); 20251da177e4SLinus Torvalds } 202645bb4bf0SMarcel Holtmann 20271da177e4SLinus Torvalds hci_dev_unlock(hdev); 20281da177e4SLinus Torvalds } 20291da177e4SLinus Torvalds 20306039aa73SGustavo Padovan static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 20311da177e4SLinus Torvalds { 2032a9de9248SMarcel Holtmann struct hci_ev_conn_complete *ev = (void *) skb->data; 2033a9de9248SMarcel Holtmann struct hci_conn *conn; 20341da177e4SLinus Torvalds 2035a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 203645bb4bf0SMarcel Holtmann 20371da177e4SLinus Torvalds hci_dev_lock(hdev); 203845bb4bf0SMarcel Holtmann 2039a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 20409499237aSMarcel Holtmann if (!conn) { 20419499237aSMarcel Holtmann if (ev->link_type != SCO_LINK) 20429499237aSMarcel Holtmann goto unlock; 20439499237aSMarcel Holtmann 20449499237aSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 2045a9de9248SMarcel Holtmann if (!conn) 2046a9de9248SMarcel Holtmann goto unlock; 204745bb4bf0SMarcel Holtmann 20489499237aSMarcel Holtmann conn->type = SCO_LINK; 20499499237aSMarcel Holtmann } 20509499237aSMarcel Holtmann 2051a9de9248SMarcel Holtmann if (!ev->status) { 2052a9de9248SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 2053769be974SMarcel Holtmann 2054769be974SMarcel Holtmann if (conn->type == ACL_LINK) { 2055769be974SMarcel Holtmann conn->state = BT_CONFIG; 2056769be974SMarcel Holtmann hci_conn_hold(conn); 2057a9ea3ed9SSzymon Janc 2058a9ea3ed9SSzymon Janc if (!conn->out && !hci_conn_ssp_enabled(conn) && 2059a9ea3ed9SSzymon Janc !hci_find_link_key(hdev, &ev->bdaddr)) 2060a9ea3ed9SSzymon Janc conn->disc_timeout = HCI_PAIRING_TIMEOUT; 2061a9ea3ed9SSzymon Janc else 2062052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 2063769be974SMarcel Holtmann } else 2064a9de9248SMarcel Holtmann conn->state = BT_CONNECTED; 2065a9de9248SMarcel Holtmann 20667d0db0a3SMarcel Holtmann hci_conn_add_sysfs(conn); 20677d0db0a3SMarcel Holtmann 2068a9de9248SMarcel Holtmann if (test_bit(HCI_AUTH, &hdev->flags)) 20694dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 2070a9de9248SMarcel Holtmann 2071a9de9248SMarcel Holtmann if (test_bit(HCI_ENCRYPT, &hdev->flags)) 20724dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags); 2073a9de9248SMarcel Holtmann 2074a9de9248SMarcel Holtmann /* Get remote features */ 2075a9de9248SMarcel Holtmann if (conn->type == ACL_LINK) { 2076a9de9248SMarcel Holtmann struct hci_cp_read_remote_features cp; 2077a9de9248SMarcel Holtmann cp.handle = ev->handle; 2078769be974SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, 2079769be974SMarcel Holtmann sizeof(cp), &cp); 208045bb4bf0SMarcel Holtmann } 2081a9de9248SMarcel Holtmann 2082a9de9248SMarcel Holtmann /* Set packet type for incoming connection */ 2083d095c1ebSAndrei Emeltchenko if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) { 2084a9de9248SMarcel Holtmann struct hci_cp_change_conn_ptype cp; 2085a9de9248SMarcel Holtmann cp.handle = ev->handle; 2086a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 208704124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), 208804124681SGustavo F. Padovan &cp); 2089a9de9248SMarcel Holtmann } 209017d5c04cSJohan Hedberg } else { 2091a9de9248SMarcel Holtmann conn->state = BT_CLOSED; 209217d5c04cSJohan Hedberg if (conn->type == ACL_LINK) 209364c7b77cSMarcel Holtmann mgmt_connect_failed(hdev, &conn->dst, conn->type, 209448264f06SJohan Hedberg conn->dst_type, ev->status); 209517d5c04cSJohan Hedberg } 209645bb4bf0SMarcel Holtmann 2097e73439d8SMarcel Holtmann if (conn->type == ACL_LINK) 2098e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 209945bb4bf0SMarcel Holtmann 2100769be974SMarcel Holtmann if (ev->status) { 2101a9de9248SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 2102a9de9248SMarcel Holtmann hci_conn_del(conn); 2103c89b6e6bSMarcel Holtmann } else if (ev->link_type != ACL_LINK) 2104c89b6e6bSMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 2105a9de9248SMarcel Holtmann 2106a9de9248SMarcel Holtmann unlock: 21071da177e4SLinus Torvalds hci_dev_unlock(hdev); 2108a9de9248SMarcel Holtmann 2109a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 21101da177e4SLinus Torvalds } 21111da177e4SLinus Torvalds 21126039aa73SGustavo Padovan static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 21131da177e4SLinus Torvalds { 2114a9de9248SMarcel Holtmann struct hci_ev_conn_request *ev = (void *) skb->data; 21151da177e4SLinus Torvalds int mask = hdev->link_mode; 211620714bfeSFrédéric Dalleau __u8 flags = 0; 21171da177e4SLinus Torvalds 21186ed93dc6SAndrei Emeltchenko BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr, 2119807deac2SGustavo Padovan ev->link_type); 21201da177e4SLinus Torvalds 212120714bfeSFrédéric Dalleau mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type, 212220714bfeSFrédéric Dalleau &flags); 21231da177e4SLinus Torvalds 2124138d22efSSzymon Janc if ((mask & HCI_LM_ACCEPT) && 2125b9ee0a78SMarcel Holtmann !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) { 21261da177e4SLinus Torvalds /* Connection accepted */ 2127c7bdd502SMarcel Holtmann struct inquiry_entry *ie; 21281da177e4SLinus Torvalds struct hci_conn *conn; 21291da177e4SLinus Torvalds 21301da177e4SLinus Torvalds hci_dev_lock(hdev); 2131b6a0dc82SMarcel Holtmann 2132cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 2133cc11b9c1SAndrei Emeltchenko if (ie) 2134c7bdd502SMarcel Holtmann memcpy(ie->data.dev_class, ev->dev_class, 3); 2135c7bdd502SMarcel Holtmann 21368fc9ced3SGustavo Padovan conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, 21378fc9ced3SGustavo Padovan &ev->bdaddr); 21381da177e4SLinus Torvalds if (!conn) { 2139cc11b9c1SAndrei Emeltchenko conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr); 2140cc11b9c1SAndrei Emeltchenko if (!conn) { 2141893ef971SGustavo F. Padovan BT_ERR("No memory for new connection"); 21421da177e4SLinus Torvalds hci_dev_unlock(hdev); 21431da177e4SLinus Torvalds return; 21441da177e4SLinus Torvalds } 21451da177e4SLinus Torvalds } 2146b6a0dc82SMarcel Holtmann 21471da177e4SLinus Torvalds memcpy(conn->dev_class, ev->dev_class, 3); 2148b6a0dc82SMarcel Holtmann 21491da177e4SLinus Torvalds hci_dev_unlock(hdev); 21501da177e4SLinus Torvalds 215120714bfeSFrédéric Dalleau if (ev->link_type == ACL_LINK || 215220714bfeSFrédéric Dalleau (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) { 2153b6a0dc82SMarcel Holtmann struct hci_cp_accept_conn_req cp; 215420714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 2155b6a0dc82SMarcel Holtmann 21561da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 21571da177e4SLinus Torvalds 21581da177e4SLinus Torvalds if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) 21591da177e4SLinus Torvalds cp.role = 0x00; /* Become master */ 21601da177e4SLinus Torvalds else 21611da177e4SLinus Torvalds cp.role = 0x01; /* Remain slave */ 21621da177e4SLinus Torvalds 216304124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), 216404124681SGustavo F. Padovan &cp); 216520714bfeSFrédéric Dalleau } else if (!(flags & HCI_PROTO_DEFER)) { 2166b6a0dc82SMarcel Holtmann struct hci_cp_accept_sync_conn_req cp; 216720714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 2168b6a0dc82SMarcel Holtmann 2169b6a0dc82SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 2170a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 2171b6a0dc82SMarcel Holtmann 2172dcf4adbfSJoe Perches cp.tx_bandwidth = cpu_to_le32(0x00001f40); 2173dcf4adbfSJoe Perches cp.rx_bandwidth = cpu_to_le32(0x00001f40); 2174dcf4adbfSJoe Perches cp.max_latency = cpu_to_le16(0xffff); 2175b6a0dc82SMarcel Holtmann cp.content_format = cpu_to_le16(hdev->voice_setting); 2176b6a0dc82SMarcel Holtmann cp.retrans_effort = 0xff; 2177b6a0dc82SMarcel Holtmann 2178b6a0dc82SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, 2179b6a0dc82SMarcel Holtmann sizeof(cp), &cp); 218020714bfeSFrédéric Dalleau } else { 218120714bfeSFrédéric Dalleau conn->state = BT_CONNECT2; 218220714bfeSFrédéric Dalleau hci_proto_connect_cfm(conn, 0); 2183b6a0dc82SMarcel Holtmann } 21841da177e4SLinus Torvalds } else { 21851da177e4SLinus Torvalds /* Connection rejected */ 21861da177e4SLinus Torvalds struct hci_cp_reject_conn_req cp; 21871da177e4SLinus Torvalds 21881da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 21899f5a0d7bSAndrei Emeltchenko cp.reason = HCI_ERROR_REJ_BAD_ADDR; 2190a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); 21911da177e4SLinus Torvalds } 21921da177e4SLinus Torvalds } 21931da177e4SLinus Torvalds 2194f0d6a0eaSMikel Astiz static u8 hci_to_mgmt_reason(u8 err) 2195f0d6a0eaSMikel Astiz { 2196f0d6a0eaSMikel Astiz switch (err) { 2197f0d6a0eaSMikel Astiz case HCI_ERROR_CONNECTION_TIMEOUT: 2198f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_TIMEOUT; 2199f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_USER_TERM: 2200f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_LOW_RESOURCES: 2201f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_POWER_OFF: 2202f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_REMOTE; 2203f0d6a0eaSMikel Astiz case HCI_ERROR_LOCAL_HOST_TERM: 2204f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_LOCAL_HOST; 2205f0d6a0eaSMikel Astiz default: 2206f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_UNKNOWN; 2207f0d6a0eaSMikel Astiz } 2208f0d6a0eaSMikel Astiz } 2209f0d6a0eaSMikel Astiz 22106039aa73SGustavo Padovan static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 22111da177e4SLinus Torvalds { 2212a9de9248SMarcel Holtmann struct hci_ev_disconn_complete *ev = (void *) skb->data; 2213abf54a50SAndre Guedes u8 reason = hci_to_mgmt_reason(ev->reason); 22149fcb18efSAndre Guedes struct hci_conn_params *params; 221504837f64SMarcel Holtmann struct hci_conn *conn; 221612d4a3b2SJohan Hedberg bool mgmt_connected; 22173846220bSAndre Guedes u8 type; 22181da177e4SLinus Torvalds 22199f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 22201da177e4SLinus Torvalds 22211da177e4SLinus Torvalds hci_dev_lock(hdev); 22221da177e4SLinus Torvalds 222304837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2224f7520543SJohan Hedberg if (!conn) 2225f7520543SJohan Hedberg goto unlock; 2226f7520543SJohan Hedberg 2227f0d6a0eaSMikel Astiz if (ev->status) { 222888c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 222988c3df13SJohan Hedberg conn->dst_type, ev->status); 2230abf54a50SAndre Guedes goto unlock; 2231abf54a50SAndre Guedes } 2232f0d6a0eaSMikel Astiz 22333846220bSAndre Guedes conn->state = BT_CLOSED; 22343846220bSAndre Guedes 223512d4a3b2SJohan Hedberg mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags); 223612d4a3b2SJohan Hedberg mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type, 223712d4a3b2SJohan Hedberg reason, mgmt_connected); 2238f7520543SJohan Hedberg 2239af6a9c32SJohan Hedberg if (conn->type == ACL_LINK && 2240af6a9c32SJohan Hedberg test_bit(HCI_CONN_FLUSH_KEY, &conn->flags)) 22416ec5bcadSVishal Agarwal hci_remove_link_key(hdev, &conn->dst); 22423846220bSAndre Guedes 22439fcb18efSAndre Guedes params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); 22449fcb18efSAndre Guedes if (params) { 22459fcb18efSAndre Guedes switch (params->auto_connect) { 22469fcb18efSAndre Guedes case HCI_AUTO_CONN_LINK_LOSS: 22479fcb18efSAndre Guedes if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT) 22489fcb18efSAndre Guedes break; 22499fcb18efSAndre Guedes /* Fall through */ 22509fcb18efSAndre Guedes 22519fcb18efSAndre Guedes case HCI_AUTO_CONN_ALWAYS: 2252418025d1SJohan Hedberg list_del_init(¶ms->action); 2253418025d1SJohan Hedberg list_add(¶ms->action, &hdev->pend_le_conns); 2254418025d1SJohan Hedberg hci_update_background_scan(hdev); 22559fcb18efSAndre Guedes break; 22569fcb18efSAndre Guedes 22579fcb18efSAndre Guedes default: 22589fcb18efSAndre Guedes break; 22599fcb18efSAndre Guedes } 22609fcb18efSAndre Guedes } 22619fcb18efSAndre Guedes 22623846220bSAndre Guedes type = conn->type; 22633846220bSAndre Guedes 22642950f21aSMarcel Holtmann hci_proto_disconn_cfm(conn, ev->reason); 22651da177e4SLinus Torvalds hci_conn_del(conn); 22662210246cSJohan Hedberg 22672210246cSJohan Hedberg /* Re-enable advertising if necessary, since it might 22682210246cSJohan Hedberg * have been disabled by the connection. From the 22692210246cSJohan Hedberg * HCI_LE_Set_Advertise_Enable command description in 22702210246cSJohan Hedberg * the core specification (v4.0): 22712210246cSJohan Hedberg * "The Controller shall continue advertising until the Host 22722210246cSJohan Hedberg * issues an LE_Set_Advertise_Enable command with 22732210246cSJohan Hedberg * Advertising_Enable set to 0x00 (Advertising is disabled) 22742210246cSJohan Hedberg * or until a connection is created or until the Advertising 22752210246cSJohan Hedberg * is timed out due to Directed Advertising." 22762210246cSJohan Hedberg */ 22772210246cSJohan Hedberg if (type == LE_LINK) 22785976e608SMarcel Holtmann mgmt_reenable_advertising(hdev); 22791da177e4SLinus Torvalds 2280f7520543SJohan Hedberg unlock: 22811da177e4SLinus Torvalds hci_dev_unlock(hdev); 22821da177e4SLinus Torvalds } 22831da177e4SLinus Torvalds 22846039aa73SGustavo Padovan static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2285a9de9248SMarcel Holtmann { 2286a9de9248SMarcel Holtmann struct hci_ev_auth_complete *ev = (void *) skb->data; 2287a9de9248SMarcel Holtmann struct hci_conn *conn; 2288a9de9248SMarcel Holtmann 22899f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2290a9de9248SMarcel Holtmann 2291a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2292a9de9248SMarcel Holtmann 2293a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2294d7556e20SWaldemar Rymarkiewicz if (!conn) 2295d7556e20SWaldemar Rymarkiewicz goto unlock; 2296d7556e20SWaldemar Rymarkiewicz 2297765c2a96SJohan Hedberg if (!ev->status) { 2298aa64a8b5SJohan Hedberg if (!hci_conn_ssp_enabled(conn) && 229951a8efd7SJohan Hedberg test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { 2300d7556e20SWaldemar Rymarkiewicz BT_INFO("re-auth of legacy device is not possible."); 230119f8def0SWaldemar Rymarkiewicz } else { 23024dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 2303765c2a96SJohan Hedberg conn->sec_level = conn->pending_sec_level; 230419f8def0SWaldemar Rymarkiewicz } 23052a611692SJohan Hedberg } else { 2306bab73cb6SJohan Hedberg mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, 2307bab73cb6SJohan Hedberg ev->status); 23082a611692SJohan Hedberg } 2309a9de9248SMarcel Holtmann 231051a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 231151a8efd7SJohan Hedberg clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags); 2312a9de9248SMarcel Holtmann 2313f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 2314aa64a8b5SJohan Hedberg if (!ev->status && hci_conn_ssp_enabled(conn)) { 2315f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 2316f8558555SMarcel Holtmann cp.handle = ev->handle; 2317f8558555SMarcel Holtmann cp.encrypt = 0x01; 2318d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 2319d7556e20SWaldemar Rymarkiewicz &cp); 2320f8558555SMarcel Holtmann } else { 2321f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 2322f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 232376a68ba0SDavid Herrmann hci_conn_drop(conn); 2324f8558555SMarcel Holtmann } 2325052b30b0SMarcel Holtmann } else { 2326a9de9248SMarcel Holtmann hci_auth_cfm(conn, ev->status); 2327a9de9248SMarcel Holtmann 2328052b30b0SMarcel Holtmann hci_conn_hold(conn); 2329052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 233076a68ba0SDavid Herrmann hci_conn_drop(conn); 2331052b30b0SMarcel Holtmann } 2332052b30b0SMarcel Holtmann 233351a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { 2334a9de9248SMarcel Holtmann if (!ev->status) { 2335a9de9248SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 2336f8558555SMarcel Holtmann cp.handle = ev->handle; 2337f8558555SMarcel Holtmann cp.encrypt = 0x01; 2338d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 2339d7556e20SWaldemar Rymarkiewicz &cp); 2340a9de9248SMarcel Holtmann } else { 234151a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 2342a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, 0x00); 2343a9de9248SMarcel Holtmann } 2344a9de9248SMarcel Holtmann } 2345a9de9248SMarcel Holtmann 2346d7556e20SWaldemar Rymarkiewicz unlock: 2347a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2348a9de9248SMarcel Holtmann } 2349a9de9248SMarcel Holtmann 23506039aa73SGustavo Padovan static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) 2351a9de9248SMarcel Holtmann { 2352127178d2SJohan Hedberg struct hci_ev_remote_name *ev = (void *) skb->data; 2353127178d2SJohan Hedberg struct hci_conn *conn; 2354127178d2SJohan Hedberg 2355a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2356a9de9248SMarcel Holtmann 2357a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 2358127178d2SJohan Hedberg 2359127178d2SJohan Hedberg hci_dev_lock(hdev); 2360127178d2SJohan Hedberg 2361127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2362b644ba33SJohan Hedberg 2363b644ba33SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2364b644ba33SJohan Hedberg goto check_auth; 2365b644ba33SJohan Hedberg 2366b644ba33SJohan Hedberg if (ev->status == 0) 2367b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name, 2368b644ba33SJohan Hedberg strnlen(ev->name, HCI_MAX_NAME_LENGTH)); 2369b644ba33SJohan Hedberg else 2370b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0); 2371b644ba33SJohan Hedberg 2372b644ba33SJohan Hedberg check_auth: 237379c6c70cSJohan Hedberg if (!conn) 237479c6c70cSJohan Hedberg goto unlock; 237579c6c70cSJohan Hedberg 237679c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 237779c6c70cSJohan Hedberg goto unlock; 237879c6c70cSJohan Hedberg 237951a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 2380127178d2SJohan Hedberg struct hci_cp_auth_requested cp; 2381127178d2SJohan Hedberg cp.handle = __cpu_to_le16(conn->handle); 2382127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); 2383127178d2SJohan Hedberg } 2384127178d2SJohan Hedberg 238579c6c70cSJohan Hedberg unlock: 2386127178d2SJohan Hedberg hci_dev_unlock(hdev); 2387a9de9248SMarcel Holtmann } 2388a9de9248SMarcel Holtmann 23896039aa73SGustavo Padovan static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2390a9de9248SMarcel Holtmann { 2391a9de9248SMarcel Holtmann struct hci_ev_encrypt_change *ev = (void *) skb->data; 2392a9de9248SMarcel Holtmann struct hci_conn *conn; 2393a9de9248SMarcel Holtmann 23949f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2395a9de9248SMarcel Holtmann 2396a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2397a9de9248SMarcel Holtmann 2398a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2399dc8357ccSMarcel Holtmann if (!conn) 2400dc8357ccSMarcel Holtmann goto unlock; 2401dc8357ccSMarcel Holtmann 2402a9de9248SMarcel Holtmann if (!ev->status) { 2403ae293196SMarcel Holtmann if (ev->encrypt) { 2404ae293196SMarcel Holtmann /* Encryption implies authentication */ 24054dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 24064dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags); 2407da85e5e5SVinicius Costa Gomes conn->sec_level = conn->pending_sec_level; 2408abf76badSMarcel Holtmann 2409914a6ffeSMarcel Holtmann /* P-256 authentication key implies FIPS */ 2410914a6ffeSMarcel Holtmann if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256) 24114dae2798SJohan Hedberg set_bit(HCI_CONN_FIPS, &conn->flags); 2412914a6ffeSMarcel Holtmann 2413abf76badSMarcel Holtmann if ((conn->type == ACL_LINK && ev->encrypt == 0x02) || 2414abf76badSMarcel Holtmann conn->type == LE_LINK) 2415abf76badSMarcel Holtmann set_bit(HCI_CONN_AES_CCM, &conn->flags); 2416abf76badSMarcel Holtmann } else { 24174dae2798SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT, &conn->flags); 2418abf76badSMarcel Holtmann clear_bit(HCI_CONN_AES_CCM, &conn->flags); 2419abf76badSMarcel Holtmann } 2420a9de9248SMarcel Holtmann } 2421a9de9248SMarcel Holtmann 242251a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 2423a9de9248SMarcel Holtmann 2424a7d7723aSGustavo Padovan if (ev->status && conn->state == BT_CONNECTED) { 2425bed71748SAndre Guedes hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 242676a68ba0SDavid Herrmann hci_conn_drop(conn); 2427a7d7723aSGustavo Padovan goto unlock; 2428a7d7723aSGustavo Padovan } 2429a7d7723aSGustavo Padovan 2430f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 2431f8558555SMarcel Holtmann if (!ev->status) 2432f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 2433f8558555SMarcel Holtmann 243440b552aaSMarcel Holtmann /* In Secure Connections Only mode, do not allow any 243540b552aaSMarcel Holtmann * connections that are not encrypted with AES-CCM 243640b552aaSMarcel Holtmann * using a P-256 authenticated combination key. 243740b552aaSMarcel Holtmann */ 243840b552aaSMarcel Holtmann if (test_bit(HCI_SC_ONLY, &hdev->dev_flags) && 243940b552aaSMarcel Holtmann (!test_bit(HCI_CONN_AES_CCM, &conn->flags) || 244040b552aaSMarcel Holtmann conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) { 244140b552aaSMarcel Holtmann hci_proto_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE); 244240b552aaSMarcel Holtmann hci_conn_drop(conn); 244340b552aaSMarcel Holtmann goto unlock; 244440b552aaSMarcel Holtmann } 244540b552aaSMarcel Holtmann 2446f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 244776a68ba0SDavid Herrmann hci_conn_drop(conn); 2448f8558555SMarcel Holtmann } else 2449a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, ev->encrypt); 2450a9de9248SMarcel Holtmann 2451a7d7723aSGustavo Padovan unlock: 2452a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2453a9de9248SMarcel Holtmann } 2454a9de9248SMarcel Holtmann 24556039aa73SGustavo Padovan static void hci_change_link_key_complete_evt(struct hci_dev *hdev, 2456807deac2SGustavo Padovan struct sk_buff *skb) 2457a9de9248SMarcel Holtmann { 2458a9de9248SMarcel Holtmann struct hci_ev_change_link_key_complete *ev = (void *) skb->data; 2459a9de9248SMarcel Holtmann struct hci_conn *conn; 2460a9de9248SMarcel Holtmann 24619f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2462a9de9248SMarcel Holtmann 2463a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2464a9de9248SMarcel Holtmann 2465a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2466a9de9248SMarcel Holtmann if (conn) { 2467a9de9248SMarcel Holtmann if (!ev->status) 24684dae2798SJohan Hedberg set_bit(HCI_CONN_SECURE, &conn->flags); 2469a9de9248SMarcel Holtmann 247051a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 2471a9de9248SMarcel Holtmann 2472a9de9248SMarcel Holtmann hci_key_change_cfm(conn, ev->status); 2473a9de9248SMarcel Holtmann } 2474a9de9248SMarcel Holtmann 2475a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2476a9de9248SMarcel Holtmann } 2477a9de9248SMarcel Holtmann 24786039aa73SGustavo Padovan static void hci_remote_features_evt(struct hci_dev *hdev, 2479807deac2SGustavo Padovan struct sk_buff *skb) 2480a9de9248SMarcel Holtmann { 2481a9de9248SMarcel Holtmann struct hci_ev_remote_features *ev = (void *) skb->data; 2482a9de9248SMarcel Holtmann struct hci_conn *conn; 2483a9de9248SMarcel Holtmann 24849f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2485a9de9248SMarcel Holtmann 2486a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2487a9de9248SMarcel Holtmann 2488a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2489ccd556feSJohan Hedberg if (!conn) 2490ccd556feSJohan Hedberg goto unlock; 2491ccd556feSJohan Hedberg 2492769be974SMarcel Holtmann if (!ev->status) 2493cad718edSJohan Hedberg memcpy(conn->features[0], ev->features, 8); 2494a9de9248SMarcel Holtmann 2495ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 2496ccd556feSJohan Hedberg goto unlock; 2497ccd556feSJohan Hedberg 2498ccd556feSJohan Hedberg if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) { 2499769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features cp; 2500769be974SMarcel Holtmann cp.handle = ev->handle; 2501769be974SMarcel Holtmann cp.page = 0x01; 2502ccd556feSJohan Hedberg hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, 2503769be974SMarcel Holtmann sizeof(cp), &cp); 2504392599b9SJohan Hedberg goto unlock; 2505392599b9SJohan Hedberg } 2506392599b9SJohan Hedberg 2507671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 2508127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 2509127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 2510127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 2511127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 2512127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 2513b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 2514b644ba33SJohan Hedberg mgmt_device_connected(hdev, &conn->dst, conn->type, 251508c79b61SJohan Hedberg conn->dst_type, 0, NULL, 0, 2516b644ba33SJohan Hedberg conn->dev_class); 2517392599b9SJohan Hedberg 2518127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 2519769be974SMarcel Holtmann conn->state = BT_CONNECTED; 2520769be974SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 252176a68ba0SDavid Herrmann hci_conn_drop(conn); 2522769be974SMarcel Holtmann } 2523769be974SMarcel Holtmann 2524ccd556feSJohan Hedberg unlock: 2525a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2526a9de9248SMarcel Holtmann } 2527a9de9248SMarcel Holtmann 25286039aa73SGustavo Padovan static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2529a9de9248SMarcel Holtmann { 2530a9de9248SMarcel Holtmann struct hci_ev_cmd_complete *ev = (void *) skb->data; 25319238f36aSJohan Hedberg u8 status = skb->data[sizeof(*ev)]; 2532a9de9248SMarcel Holtmann __u16 opcode; 2533a9de9248SMarcel Holtmann 2534a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 2535a9de9248SMarcel Holtmann 2536a9de9248SMarcel Holtmann opcode = __le16_to_cpu(ev->opcode); 2537a9de9248SMarcel Holtmann 2538a9de9248SMarcel Holtmann switch (opcode) { 2539a9de9248SMarcel Holtmann case HCI_OP_INQUIRY_CANCEL: 2540a9de9248SMarcel Holtmann hci_cc_inquiry_cancel(hdev, skb); 2541a9de9248SMarcel Holtmann break; 2542a9de9248SMarcel Holtmann 25434d93483bSAndre Guedes case HCI_OP_PERIODIC_INQ: 25444d93483bSAndre Guedes hci_cc_periodic_inq(hdev, skb); 25454d93483bSAndre Guedes break; 25464d93483bSAndre Guedes 2547a9de9248SMarcel Holtmann case HCI_OP_EXIT_PERIODIC_INQ: 2548a9de9248SMarcel Holtmann hci_cc_exit_periodic_inq(hdev, skb); 2549a9de9248SMarcel Holtmann break; 2550a9de9248SMarcel Holtmann 2551a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ_CANCEL: 2552a9de9248SMarcel Holtmann hci_cc_remote_name_req_cancel(hdev, skb); 2553a9de9248SMarcel Holtmann break; 2554a9de9248SMarcel Holtmann 2555a9de9248SMarcel Holtmann case HCI_OP_ROLE_DISCOVERY: 2556a9de9248SMarcel Holtmann hci_cc_role_discovery(hdev, skb); 2557a9de9248SMarcel Holtmann break; 2558a9de9248SMarcel Holtmann 2559e4e8e37cSMarcel Holtmann case HCI_OP_READ_LINK_POLICY: 2560e4e8e37cSMarcel Holtmann hci_cc_read_link_policy(hdev, skb); 2561e4e8e37cSMarcel Holtmann break; 2562e4e8e37cSMarcel Holtmann 2563a9de9248SMarcel Holtmann case HCI_OP_WRITE_LINK_POLICY: 2564a9de9248SMarcel Holtmann hci_cc_write_link_policy(hdev, skb); 2565a9de9248SMarcel Holtmann break; 2566a9de9248SMarcel Holtmann 2567e4e8e37cSMarcel Holtmann case HCI_OP_READ_DEF_LINK_POLICY: 2568e4e8e37cSMarcel Holtmann hci_cc_read_def_link_policy(hdev, skb); 2569e4e8e37cSMarcel Holtmann break; 2570e4e8e37cSMarcel Holtmann 2571e4e8e37cSMarcel Holtmann case HCI_OP_WRITE_DEF_LINK_POLICY: 2572e4e8e37cSMarcel Holtmann hci_cc_write_def_link_policy(hdev, skb); 2573e4e8e37cSMarcel Holtmann break; 2574e4e8e37cSMarcel Holtmann 2575a9de9248SMarcel Holtmann case HCI_OP_RESET: 2576a9de9248SMarcel Holtmann hci_cc_reset(hdev, skb); 2577a9de9248SMarcel Holtmann break; 2578a9de9248SMarcel Holtmann 2579a9de9248SMarcel Holtmann case HCI_OP_WRITE_LOCAL_NAME: 2580a9de9248SMarcel Holtmann hci_cc_write_local_name(hdev, skb); 2581a9de9248SMarcel Holtmann break; 2582a9de9248SMarcel Holtmann 2583a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_NAME: 2584a9de9248SMarcel Holtmann hci_cc_read_local_name(hdev, skb); 2585a9de9248SMarcel Holtmann break; 2586a9de9248SMarcel Holtmann 2587a9de9248SMarcel Holtmann case HCI_OP_WRITE_AUTH_ENABLE: 2588a9de9248SMarcel Holtmann hci_cc_write_auth_enable(hdev, skb); 2589a9de9248SMarcel Holtmann break; 2590a9de9248SMarcel Holtmann 2591a9de9248SMarcel Holtmann case HCI_OP_WRITE_ENCRYPT_MODE: 2592a9de9248SMarcel Holtmann hci_cc_write_encrypt_mode(hdev, skb); 2593a9de9248SMarcel Holtmann break; 2594a9de9248SMarcel Holtmann 2595a9de9248SMarcel Holtmann case HCI_OP_WRITE_SCAN_ENABLE: 2596a9de9248SMarcel Holtmann hci_cc_write_scan_enable(hdev, skb); 2597a9de9248SMarcel Holtmann break; 2598a9de9248SMarcel Holtmann 2599a9de9248SMarcel Holtmann case HCI_OP_READ_CLASS_OF_DEV: 2600a9de9248SMarcel Holtmann hci_cc_read_class_of_dev(hdev, skb); 2601a9de9248SMarcel Holtmann break; 2602a9de9248SMarcel Holtmann 2603a9de9248SMarcel Holtmann case HCI_OP_WRITE_CLASS_OF_DEV: 2604a9de9248SMarcel Holtmann hci_cc_write_class_of_dev(hdev, skb); 2605a9de9248SMarcel Holtmann break; 2606a9de9248SMarcel Holtmann 2607a9de9248SMarcel Holtmann case HCI_OP_READ_VOICE_SETTING: 2608a9de9248SMarcel Holtmann hci_cc_read_voice_setting(hdev, skb); 2609a9de9248SMarcel Holtmann break; 2610a9de9248SMarcel Holtmann 2611a9de9248SMarcel Holtmann case HCI_OP_WRITE_VOICE_SETTING: 2612a9de9248SMarcel Holtmann hci_cc_write_voice_setting(hdev, skb); 2613a9de9248SMarcel Holtmann break; 2614a9de9248SMarcel Holtmann 2615b4cb9fb2SMarcel Holtmann case HCI_OP_READ_NUM_SUPPORTED_IAC: 2616b4cb9fb2SMarcel Holtmann hci_cc_read_num_supported_iac(hdev, skb); 2617b4cb9fb2SMarcel Holtmann break; 2618b4cb9fb2SMarcel Holtmann 2619333140b5SMarcel Holtmann case HCI_OP_WRITE_SSP_MODE: 2620333140b5SMarcel Holtmann hci_cc_write_ssp_mode(hdev, skb); 2621333140b5SMarcel Holtmann break; 2622333140b5SMarcel Holtmann 2623eac83dc6SMarcel Holtmann case HCI_OP_WRITE_SC_SUPPORT: 2624eac83dc6SMarcel Holtmann hci_cc_write_sc_support(hdev, skb); 2625eac83dc6SMarcel Holtmann break; 2626eac83dc6SMarcel Holtmann 2627a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_VERSION: 2628a9de9248SMarcel Holtmann hci_cc_read_local_version(hdev, skb); 2629a9de9248SMarcel Holtmann break; 2630a9de9248SMarcel Holtmann 2631a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_COMMANDS: 2632a9de9248SMarcel Holtmann hci_cc_read_local_commands(hdev, skb); 2633a9de9248SMarcel Holtmann break; 2634a9de9248SMarcel Holtmann 2635a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_FEATURES: 2636a9de9248SMarcel Holtmann hci_cc_read_local_features(hdev, skb); 2637a9de9248SMarcel Holtmann break; 2638a9de9248SMarcel Holtmann 2639971e3a4bSAndre Guedes case HCI_OP_READ_LOCAL_EXT_FEATURES: 2640971e3a4bSAndre Guedes hci_cc_read_local_ext_features(hdev, skb); 2641971e3a4bSAndre Guedes break; 2642971e3a4bSAndre Guedes 2643a9de9248SMarcel Holtmann case HCI_OP_READ_BUFFER_SIZE: 2644a9de9248SMarcel Holtmann hci_cc_read_buffer_size(hdev, skb); 2645a9de9248SMarcel Holtmann break; 2646a9de9248SMarcel Holtmann 2647a9de9248SMarcel Holtmann case HCI_OP_READ_BD_ADDR: 2648a9de9248SMarcel Holtmann hci_cc_read_bd_addr(hdev, skb); 2649a9de9248SMarcel Holtmann break; 2650a9de9248SMarcel Holtmann 2651f332ec66SJohan Hedberg case HCI_OP_READ_PAGE_SCAN_ACTIVITY: 2652f332ec66SJohan Hedberg hci_cc_read_page_scan_activity(hdev, skb); 2653f332ec66SJohan Hedberg break; 2654f332ec66SJohan Hedberg 26554a3ee763SJohan Hedberg case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY: 26564a3ee763SJohan Hedberg hci_cc_write_page_scan_activity(hdev, skb); 26574a3ee763SJohan Hedberg break; 26584a3ee763SJohan Hedberg 2659f332ec66SJohan Hedberg case HCI_OP_READ_PAGE_SCAN_TYPE: 2660f332ec66SJohan Hedberg hci_cc_read_page_scan_type(hdev, skb); 2661f332ec66SJohan Hedberg break; 2662f332ec66SJohan Hedberg 26634a3ee763SJohan Hedberg case HCI_OP_WRITE_PAGE_SCAN_TYPE: 26644a3ee763SJohan Hedberg hci_cc_write_page_scan_type(hdev, skb); 26654a3ee763SJohan Hedberg break; 26664a3ee763SJohan Hedberg 2667350ee4cfSAndrei Emeltchenko case HCI_OP_READ_DATA_BLOCK_SIZE: 2668350ee4cfSAndrei Emeltchenko hci_cc_read_data_block_size(hdev, skb); 2669350ee4cfSAndrei Emeltchenko break; 2670350ee4cfSAndrei Emeltchenko 26711e89cffbSAndrei Emeltchenko case HCI_OP_READ_FLOW_CONTROL_MODE: 26721e89cffbSAndrei Emeltchenko hci_cc_read_flow_control_mode(hdev, skb); 26731e89cffbSAndrei Emeltchenko break; 26741e89cffbSAndrei Emeltchenko 2675928abaa7SAndrei Emeltchenko case HCI_OP_READ_LOCAL_AMP_INFO: 2676928abaa7SAndrei Emeltchenko hci_cc_read_local_amp_info(hdev, skb); 2677928abaa7SAndrei Emeltchenko break; 2678928abaa7SAndrei Emeltchenko 267933f35721SJohan Hedberg case HCI_OP_READ_CLOCK: 268033f35721SJohan Hedberg hci_cc_read_clock(hdev, skb); 268133f35721SJohan Hedberg break; 268233f35721SJohan Hedberg 2683903e4541SAndrei Emeltchenko case HCI_OP_READ_LOCAL_AMP_ASSOC: 2684903e4541SAndrei Emeltchenko hci_cc_read_local_amp_assoc(hdev, skb); 2685903e4541SAndrei Emeltchenko break; 2686903e4541SAndrei Emeltchenko 2687d5859e22SJohan Hedberg case HCI_OP_READ_INQ_RSP_TX_POWER: 2688d5859e22SJohan Hedberg hci_cc_read_inq_rsp_tx_power(hdev, skb); 2689d5859e22SJohan Hedberg break; 2690d5859e22SJohan Hedberg 2691980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_REPLY: 2692980e1a53SJohan Hedberg hci_cc_pin_code_reply(hdev, skb); 2693980e1a53SJohan Hedberg break; 2694980e1a53SJohan Hedberg 2695980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_NEG_REPLY: 2696980e1a53SJohan Hedberg hci_cc_pin_code_neg_reply(hdev, skb); 2697980e1a53SJohan Hedberg break; 2698980e1a53SJohan Hedberg 2699c35938b2SSzymon Janc case HCI_OP_READ_LOCAL_OOB_DATA: 27004d2d2796SMarcel Holtmann hci_cc_read_local_oob_data(hdev, skb); 27014d2d2796SMarcel Holtmann break; 27024d2d2796SMarcel Holtmann 27034d2d2796SMarcel Holtmann case HCI_OP_READ_LOCAL_OOB_EXT_DATA: 27044d2d2796SMarcel Holtmann hci_cc_read_local_oob_ext_data(hdev, skb); 2705c35938b2SSzymon Janc break; 2706c35938b2SSzymon Janc 27076ed58ec5SVille Tervo case HCI_OP_LE_READ_BUFFER_SIZE: 27086ed58ec5SVille Tervo hci_cc_le_read_buffer_size(hdev, skb); 27096ed58ec5SVille Tervo break; 27106ed58ec5SVille Tervo 271160e77321SJohan Hedberg case HCI_OP_LE_READ_LOCAL_FEATURES: 271260e77321SJohan Hedberg hci_cc_le_read_local_features(hdev, skb); 271360e77321SJohan Hedberg break; 271460e77321SJohan Hedberg 27158fa19098SJohan Hedberg case HCI_OP_LE_READ_ADV_TX_POWER: 27168fa19098SJohan Hedberg hci_cc_le_read_adv_tx_power(hdev, skb); 27178fa19098SJohan Hedberg break; 27188fa19098SJohan Hedberg 2719a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_REPLY: 2720a5c29683SJohan Hedberg hci_cc_user_confirm_reply(hdev, skb); 2721a5c29683SJohan Hedberg break; 2722a5c29683SJohan Hedberg 2723a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_NEG_REPLY: 2724a5c29683SJohan Hedberg hci_cc_user_confirm_neg_reply(hdev, skb); 2725a5c29683SJohan Hedberg break; 2726a5c29683SJohan Hedberg 27271143d458SBrian Gix case HCI_OP_USER_PASSKEY_REPLY: 27281143d458SBrian Gix hci_cc_user_passkey_reply(hdev, skb); 27291143d458SBrian Gix break; 27301143d458SBrian Gix 27311143d458SBrian Gix case HCI_OP_USER_PASSKEY_NEG_REPLY: 27321143d458SBrian Gix hci_cc_user_passkey_neg_reply(hdev, skb); 273316cde993SSzymon Janc break; 273407f7fa5dSAndre Guedes 27357a4cd51dSMarcel Holtmann case HCI_OP_LE_SET_RANDOM_ADDR: 27367a4cd51dSMarcel Holtmann hci_cc_le_set_random_addr(hdev, skb); 27377a4cd51dSMarcel Holtmann break; 27387a4cd51dSMarcel Holtmann 2739c1d5dc4aSJohan Hedberg case HCI_OP_LE_SET_ADV_ENABLE: 2740c1d5dc4aSJohan Hedberg hci_cc_le_set_adv_enable(hdev, skb); 2741c1d5dc4aSJohan Hedberg break; 2742c1d5dc4aSJohan Hedberg 2743533553f8SMarcel Holtmann case HCI_OP_LE_SET_SCAN_PARAM: 2744533553f8SMarcel Holtmann hci_cc_le_set_scan_param(hdev, skb); 2745533553f8SMarcel Holtmann break; 2746533553f8SMarcel Holtmann 2747eb9d91f5SAndre Guedes case HCI_OP_LE_SET_SCAN_ENABLE: 2748eb9d91f5SAndre Guedes hci_cc_le_set_scan_enable(hdev, skb); 2749eb9d91f5SAndre Guedes break; 2750eb9d91f5SAndre Guedes 2751cf1d081fSJohan Hedberg case HCI_OP_LE_READ_WHITE_LIST_SIZE: 2752cf1d081fSJohan Hedberg hci_cc_le_read_white_list_size(hdev, skb); 2753cf1d081fSJohan Hedberg break; 2754cf1d081fSJohan Hedberg 27550f36b589SMarcel Holtmann case HCI_OP_LE_CLEAR_WHITE_LIST: 27560f36b589SMarcel Holtmann hci_cc_le_clear_white_list(hdev, skb); 27570f36b589SMarcel Holtmann break; 27580f36b589SMarcel Holtmann 27590f36b589SMarcel Holtmann case HCI_OP_LE_ADD_TO_WHITE_LIST: 27600f36b589SMarcel Holtmann hci_cc_le_add_to_white_list(hdev, skb); 27610f36b589SMarcel Holtmann break; 27620f36b589SMarcel Holtmann 27630f36b589SMarcel Holtmann case HCI_OP_LE_DEL_FROM_WHITE_LIST: 27640f36b589SMarcel Holtmann hci_cc_le_del_from_white_list(hdev, skb); 27650f36b589SMarcel Holtmann break; 27660f36b589SMarcel Holtmann 27679b008c04SJohan Hedberg case HCI_OP_LE_READ_SUPPORTED_STATES: 27689b008c04SJohan Hedberg hci_cc_le_read_supported_states(hdev, skb); 27699b008c04SJohan Hedberg break; 27709b008c04SJohan Hedberg 2771f9b49306SAndre Guedes case HCI_OP_WRITE_LE_HOST_SUPPORTED: 2772f9b49306SAndre Guedes hci_cc_write_le_host_supported(hdev, skb); 2773f9b49306SAndre Guedes break; 2774f9b49306SAndre Guedes 277556ed2cb8SJohan Hedberg case HCI_OP_LE_SET_ADV_PARAM: 277656ed2cb8SJohan Hedberg hci_cc_set_adv_param(hdev, skb); 277756ed2cb8SJohan Hedberg break; 277856ed2cb8SJohan Hedberg 277993c284eeSAndrei Emeltchenko case HCI_OP_WRITE_REMOTE_AMP_ASSOC: 278093c284eeSAndrei Emeltchenko hci_cc_write_remote_amp_assoc(hdev, skb); 278193c284eeSAndrei Emeltchenko break; 278293c284eeSAndrei Emeltchenko 27835ae76a94SAndrzej Kaczmarek case HCI_OP_READ_RSSI: 27845ae76a94SAndrzej Kaczmarek hci_cc_read_rssi(hdev, skb); 27855ae76a94SAndrzej Kaczmarek break; 27865ae76a94SAndrzej Kaczmarek 27875a134faeSAndrzej Kaczmarek case HCI_OP_READ_TX_POWER: 27885a134faeSAndrzej Kaczmarek hci_cc_read_tx_power(hdev, skb); 27895a134faeSAndrzej Kaczmarek break; 27905a134faeSAndrzej Kaczmarek 2791a9de9248SMarcel Holtmann default: 27929f1db00cSAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 2793a9de9248SMarcel Holtmann break; 2794a9de9248SMarcel Holtmann } 2795a9de9248SMarcel Holtmann 2796ad82cdd1SJohan Hedberg if (opcode != HCI_OP_NOP) 279765cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 27986bd32326SVille Tervo 2799ad82cdd1SJohan Hedberg hci_req_cmd_complete(hdev, opcode, status); 28009238f36aSJohan Hedberg 2801dbccd791SSzymon Janc if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { 2802a9de9248SMarcel Holtmann atomic_set(&hdev->cmd_cnt, 1); 2803a9de9248SMarcel Holtmann if (!skb_queue_empty(&hdev->cmd_q)) 2804c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 2805a9de9248SMarcel Holtmann } 2806a9de9248SMarcel Holtmann } 2807a9de9248SMarcel Holtmann 28086039aa73SGustavo Padovan static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) 2809a9de9248SMarcel Holtmann { 2810a9de9248SMarcel Holtmann struct hci_ev_cmd_status *ev = (void *) skb->data; 2811a9de9248SMarcel Holtmann __u16 opcode; 2812a9de9248SMarcel Holtmann 2813a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 2814a9de9248SMarcel Holtmann 2815a9de9248SMarcel Holtmann opcode = __le16_to_cpu(ev->opcode); 2816a9de9248SMarcel Holtmann 2817a9de9248SMarcel Holtmann switch (opcode) { 2818a9de9248SMarcel Holtmann case HCI_OP_INQUIRY: 2819a9de9248SMarcel Holtmann hci_cs_inquiry(hdev, ev->status); 2820a9de9248SMarcel Holtmann break; 2821a9de9248SMarcel Holtmann 2822a9de9248SMarcel Holtmann case HCI_OP_CREATE_CONN: 2823a9de9248SMarcel Holtmann hci_cs_create_conn(hdev, ev->status); 2824a9de9248SMarcel Holtmann break; 2825a9de9248SMarcel Holtmann 2826a9de9248SMarcel Holtmann case HCI_OP_ADD_SCO: 2827a9de9248SMarcel Holtmann hci_cs_add_sco(hdev, ev->status); 2828a9de9248SMarcel Holtmann break; 2829a9de9248SMarcel Holtmann 2830f8558555SMarcel Holtmann case HCI_OP_AUTH_REQUESTED: 2831f8558555SMarcel Holtmann hci_cs_auth_requested(hdev, ev->status); 2832f8558555SMarcel Holtmann break; 2833f8558555SMarcel Holtmann 2834f8558555SMarcel Holtmann case HCI_OP_SET_CONN_ENCRYPT: 2835f8558555SMarcel Holtmann hci_cs_set_conn_encrypt(hdev, ev->status); 2836f8558555SMarcel Holtmann break; 2837f8558555SMarcel Holtmann 2838a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ: 2839a9de9248SMarcel Holtmann hci_cs_remote_name_req(hdev, ev->status); 2840a9de9248SMarcel Holtmann break; 2841a9de9248SMarcel Holtmann 2842769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_FEATURES: 2843769be974SMarcel Holtmann hci_cs_read_remote_features(hdev, ev->status); 2844769be974SMarcel Holtmann break; 2845769be974SMarcel Holtmann 2846769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_EXT_FEATURES: 2847769be974SMarcel Holtmann hci_cs_read_remote_ext_features(hdev, ev->status); 2848769be974SMarcel Holtmann break; 2849769be974SMarcel Holtmann 2850a9de9248SMarcel Holtmann case HCI_OP_SETUP_SYNC_CONN: 2851a9de9248SMarcel Holtmann hci_cs_setup_sync_conn(hdev, ev->status); 2852a9de9248SMarcel Holtmann break; 2853a9de9248SMarcel Holtmann 2854a9de9248SMarcel Holtmann case HCI_OP_SNIFF_MODE: 2855a9de9248SMarcel Holtmann hci_cs_sniff_mode(hdev, ev->status); 2856a9de9248SMarcel Holtmann break; 2857a9de9248SMarcel Holtmann 2858a9de9248SMarcel Holtmann case HCI_OP_EXIT_SNIFF_MODE: 2859a9de9248SMarcel Holtmann hci_cs_exit_sniff_mode(hdev, ev->status); 2860a9de9248SMarcel Holtmann break; 2861a9de9248SMarcel Holtmann 28628962ee74SJohan Hedberg case HCI_OP_DISCONNECT: 286388c3df13SJohan Hedberg hci_cs_disconnect(hdev, ev->status); 28648962ee74SJohan Hedberg break; 28658962ee74SJohan Hedberg 2866a02226d6SAndrei Emeltchenko case HCI_OP_CREATE_PHY_LINK: 2867a02226d6SAndrei Emeltchenko hci_cs_create_phylink(hdev, ev->status); 2868a02226d6SAndrei Emeltchenko break; 2869a02226d6SAndrei Emeltchenko 28700b26ab9dSAndrei Emeltchenko case HCI_OP_ACCEPT_PHY_LINK: 28710b26ab9dSAndrei Emeltchenko hci_cs_accept_phylink(hdev, ev->status); 28720b26ab9dSAndrei Emeltchenko break; 28730b26ab9dSAndrei Emeltchenko 2874cb1d68f7SJohan Hedberg case HCI_OP_LE_CREATE_CONN: 2875cb1d68f7SJohan Hedberg hci_cs_le_create_conn(hdev, ev->status); 2876cb1d68f7SJohan Hedberg break; 2877cb1d68f7SJohan Hedberg 287881d0c8adSJohan Hedberg case HCI_OP_LE_START_ENC: 287981d0c8adSJohan Hedberg hci_cs_le_start_enc(hdev, ev->status); 288081d0c8adSJohan Hedberg break; 288181d0c8adSJohan Hedberg 2882a9de9248SMarcel Holtmann default: 28839f1db00cSAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 2884a9de9248SMarcel Holtmann break; 2885a9de9248SMarcel Holtmann } 2886a9de9248SMarcel Holtmann 2887ad82cdd1SJohan Hedberg if (opcode != HCI_OP_NOP) 288865cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 28896bd32326SVille Tervo 289002350a72SJohan Hedberg if (ev->status || 289102350a72SJohan Hedberg (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event)) 289233720450SAndre Guedes hci_req_cmd_complete(hdev, opcode, ev->status); 28939238f36aSJohan Hedberg 289410572132SGustavo F. Padovan if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { 2895a9de9248SMarcel Holtmann atomic_set(&hdev->cmd_cnt, 1); 2896a9de9248SMarcel Holtmann if (!skb_queue_empty(&hdev->cmd_q)) 2897c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 2898a9de9248SMarcel Holtmann } 2899a9de9248SMarcel Holtmann } 2900a9de9248SMarcel Holtmann 29016039aa73SGustavo Padovan static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2902a9de9248SMarcel Holtmann { 2903a9de9248SMarcel Holtmann struct hci_ev_role_change *ev = (void *) skb->data; 2904a9de9248SMarcel Holtmann struct hci_conn *conn; 2905a9de9248SMarcel Holtmann 29069f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2907a9de9248SMarcel Holtmann 2908a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2909a9de9248SMarcel Holtmann 2910a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2911a9de9248SMarcel Holtmann if (conn) { 2912a9de9248SMarcel Holtmann if (!ev->status) { 2913a9de9248SMarcel Holtmann if (ev->role) 29144dae2798SJohan Hedberg clear_bit(HCI_CONN_MASTER, &conn->flags); 2915a9de9248SMarcel Holtmann else 29164dae2798SJohan Hedberg set_bit(HCI_CONN_MASTER, &conn->flags); 2917a9de9248SMarcel Holtmann } 2918a9de9248SMarcel Holtmann 291951a8efd7SJohan Hedberg clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 2920a9de9248SMarcel Holtmann 2921a9de9248SMarcel Holtmann hci_role_switch_cfm(conn, ev->status, ev->role); 2922a9de9248SMarcel Holtmann } 2923a9de9248SMarcel Holtmann 2924a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2925a9de9248SMarcel Holtmann } 2926a9de9248SMarcel Holtmann 29276039aa73SGustavo Padovan static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) 29281da177e4SLinus Torvalds { 2929a9de9248SMarcel Holtmann struct hci_ev_num_comp_pkts *ev = (void *) skb->data; 29301da177e4SLinus Torvalds int i; 29311da177e4SLinus Torvalds 293232ac5b9bSAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) { 293332ac5b9bSAndrei Emeltchenko BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); 293432ac5b9bSAndrei Emeltchenko return; 293532ac5b9bSAndrei Emeltchenko } 293632ac5b9bSAndrei Emeltchenko 2937c5993de8SAndrei Emeltchenko if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + 2938c5993de8SAndrei Emeltchenko ev->num_hndl * sizeof(struct hci_comp_pkts_info)) { 29391da177e4SLinus Torvalds BT_DBG("%s bad parameters", hdev->name); 29401da177e4SLinus Torvalds return; 29411da177e4SLinus Torvalds } 29421da177e4SLinus Torvalds 2943c5993de8SAndrei Emeltchenko BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl); 2944c5993de8SAndrei Emeltchenko 2945613a1c0cSAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 2946613a1c0cSAndrei Emeltchenko struct hci_comp_pkts_info *info = &ev->handles[i]; 29471da177e4SLinus Torvalds struct hci_conn *conn; 29481da177e4SLinus Torvalds __u16 handle, count; 29491da177e4SLinus Torvalds 2950613a1c0cSAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 2951613a1c0cSAndrei Emeltchenko count = __le16_to_cpu(info->count); 29521da177e4SLinus Torvalds 29531da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 2954f4280918SAndrei Emeltchenko if (!conn) 2955f4280918SAndrei Emeltchenko continue; 2956f4280918SAndrei Emeltchenko 29571da177e4SLinus Torvalds conn->sent -= count; 29581da177e4SLinus Torvalds 2959f4280918SAndrei Emeltchenko switch (conn->type) { 2960f4280918SAndrei Emeltchenko case ACL_LINK: 296170f23020SAndrei Emeltchenko hdev->acl_cnt += count; 296270f23020SAndrei Emeltchenko if (hdev->acl_cnt > hdev->acl_pkts) 29631da177e4SLinus Torvalds hdev->acl_cnt = hdev->acl_pkts; 2964f4280918SAndrei Emeltchenko break; 2965f4280918SAndrei Emeltchenko 2966f4280918SAndrei Emeltchenko case LE_LINK: 29676ed58ec5SVille Tervo if (hdev->le_pkts) { 29686ed58ec5SVille Tervo hdev->le_cnt += count; 29696ed58ec5SVille Tervo if (hdev->le_cnt > hdev->le_pkts) 29706ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 29716ed58ec5SVille Tervo } else { 29726ed58ec5SVille Tervo hdev->acl_cnt += count; 29736ed58ec5SVille Tervo if (hdev->acl_cnt > hdev->acl_pkts) 29746ed58ec5SVille Tervo hdev->acl_cnt = hdev->acl_pkts; 29756ed58ec5SVille Tervo } 2976f4280918SAndrei Emeltchenko break; 2977f4280918SAndrei Emeltchenko 2978f4280918SAndrei Emeltchenko case SCO_LINK: 297970f23020SAndrei Emeltchenko hdev->sco_cnt += count; 298070f23020SAndrei Emeltchenko if (hdev->sco_cnt > hdev->sco_pkts) 29815b7f9909SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 2982f4280918SAndrei Emeltchenko break; 2983f4280918SAndrei Emeltchenko 2984f4280918SAndrei Emeltchenko default: 2985f4280918SAndrei Emeltchenko BT_ERR("Unknown type %d conn %p", conn->type, conn); 2986f4280918SAndrei Emeltchenko break; 29871da177e4SLinus Torvalds } 29881da177e4SLinus Torvalds } 2989a9de9248SMarcel Holtmann 29903eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 29911da177e4SLinus Torvalds } 29921da177e4SLinus Torvalds 299376ef7cf7SAndrei Emeltchenko static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev, 299476ef7cf7SAndrei Emeltchenko __u16 handle) 299576ef7cf7SAndrei Emeltchenko { 299676ef7cf7SAndrei Emeltchenko struct hci_chan *chan; 299776ef7cf7SAndrei Emeltchenko 299876ef7cf7SAndrei Emeltchenko switch (hdev->dev_type) { 299976ef7cf7SAndrei Emeltchenko case HCI_BREDR: 300076ef7cf7SAndrei Emeltchenko return hci_conn_hash_lookup_handle(hdev, handle); 300176ef7cf7SAndrei Emeltchenko case HCI_AMP: 300276ef7cf7SAndrei Emeltchenko chan = hci_chan_lookup_handle(hdev, handle); 300376ef7cf7SAndrei Emeltchenko if (chan) 300476ef7cf7SAndrei Emeltchenko return chan->conn; 300576ef7cf7SAndrei Emeltchenko break; 300676ef7cf7SAndrei Emeltchenko default: 300776ef7cf7SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 300876ef7cf7SAndrei Emeltchenko break; 300976ef7cf7SAndrei Emeltchenko } 301076ef7cf7SAndrei Emeltchenko 301176ef7cf7SAndrei Emeltchenko return NULL; 301276ef7cf7SAndrei Emeltchenko } 301376ef7cf7SAndrei Emeltchenko 30146039aa73SGustavo Padovan static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) 301525e89e99SAndrei Emeltchenko { 301625e89e99SAndrei Emeltchenko struct hci_ev_num_comp_blocks *ev = (void *) skb->data; 301725e89e99SAndrei Emeltchenko int i; 301825e89e99SAndrei Emeltchenko 301925e89e99SAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) { 302025e89e99SAndrei Emeltchenko BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); 302125e89e99SAndrei Emeltchenko return; 302225e89e99SAndrei Emeltchenko } 302325e89e99SAndrei Emeltchenko 302425e89e99SAndrei Emeltchenko if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + 302525e89e99SAndrei Emeltchenko ev->num_hndl * sizeof(struct hci_comp_blocks_info)) { 302625e89e99SAndrei Emeltchenko BT_DBG("%s bad parameters", hdev->name); 302725e89e99SAndrei Emeltchenko return; 302825e89e99SAndrei Emeltchenko } 302925e89e99SAndrei Emeltchenko 303025e89e99SAndrei Emeltchenko BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks, 303125e89e99SAndrei Emeltchenko ev->num_hndl); 303225e89e99SAndrei Emeltchenko 303325e89e99SAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 303425e89e99SAndrei Emeltchenko struct hci_comp_blocks_info *info = &ev->handles[i]; 303576ef7cf7SAndrei Emeltchenko struct hci_conn *conn = NULL; 303625e89e99SAndrei Emeltchenko __u16 handle, block_count; 303725e89e99SAndrei Emeltchenko 303825e89e99SAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 303925e89e99SAndrei Emeltchenko block_count = __le16_to_cpu(info->blocks); 304025e89e99SAndrei Emeltchenko 304176ef7cf7SAndrei Emeltchenko conn = __hci_conn_lookup_handle(hdev, handle); 304225e89e99SAndrei Emeltchenko if (!conn) 304325e89e99SAndrei Emeltchenko continue; 304425e89e99SAndrei Emeltchenko 304525e89e99SAndrei Emeltchenko conn->sent -= block_count; 304625e89e99SAndrei Emeltchenko 304725e89e99SAndrei Emeltchenko switch (conn->type) { 304825e89e99SAndrei Emeltchenko case ACL_LINK: 3049bd1eb66bSAndrei Emeltchenko case AMP_LINK: 305025e89e99SAndrei Emeltchenko hdev->block_cnt += block_count; 305125e89e99SAndrei Emeltchenko if (hdev->block_cnt > hdev->num_blocks) 305225e89e99SAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 305325e89e99SAndrei Emeltchenko break; 305425e89e99SAndrei Emeltchenko 305525e89e99SAndrei Emeltchenko default: 305625e89e99SAndrei Emeltchenko BT_ERR("Unknown type %d conn %p", conn->type, conn); 305725e89e99SAndrei Emeltchenko break; 305825e89e99SAndrei Emeltchenko } 305925e89e99SAndrei Emeltchenko } 306025e89e99SAndrei Emeltchenko 306125e89e99SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->tx_work); 306225e89e99SAndrei Emeltchenko } 306325e89e99SAndrei Emeltchenko 30646039aa73SGustavo Padovan static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 30651da177e4SLinus Torvalds { 3066a9de9248SMarcel Holtmann struct hci_ev_mode_change *ev = (void *) skb->data; 306704837f64SMarcel Holtmann struct hci_conn *conn; 30681da177e4SLinus Torvalds 30699f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 30701da177e4SLinus Torvalds 30711da177e4SLinus Torvalds hci_dev_lock(hdev); 30721da177e4SLinus Torvalds 307304837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 307404837f64SMarcel Holtmann if (conn) { 307504837f64SMarcel Holtmann conn->mode = ev->mode; 307604837f64SMarcel Holtmann 30778fc9ced3SGustavo Padovan if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, 30788fc9ced3SGustavo Padovan &conn->flags)) { 307904837f64SMarcel Holtmann if (conn->mode == HCI_CM_ACTIVE) 308058a681efSJohan Hedberg set_bit(HCI_CONN_POWER_SAVE, &conn->flags); 308104837f64SMarcel Holtmann else 308258a681efSJohan Hedberg clear_bit(HCI_CONN_POWER_SAVE, &conn->flags); 308304837f64SMarcel Holtmann } 3084e73439d8SMarcel Holtmann 308551a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 3086e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 308704837f64SMarcel Holtmann } 308804837f64SMarcel Holtmann 308904837f64SMarcel Holtmann hci_dev_unlock(hdev); 309004837f64SMarcel Holtmann } 309104837f64SMarcel Holtmann 30926039aa73SGustavo Padovan static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 30931da177e4SLinus Torvalds { 3094052b30b0SMarcel Holtmann struct hci_ev_pin_code_req *ev = (void *) skb->data; 3095052b30b0SMarcel Holtmann struct hci_conn *conn; 3096052b30b0SMarcel Holtmann 3097a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 3098052b30b0SMarcel Holtmann 3099052b30b0SMarcel Holtmann hci_dev_lock(hdev); 3100052b30b0SMarcel Holtmann 3101052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 3102b6f98044SWaldemar Rymarkiewicz if (!conn) 3103b6f98044SWaldemar Rymarkiewicz goto unlock; 3104b6f98044SWaldemar Rymarkiewicz 3105b6f98044SWaldemar Rymarkiewicz if (conn->state == BT_CONNECTED) { 3106052b30b0SMarcel Holtmann hci_conn_hold(conn); 3107052b30b0SMarcel Holtmann conn->disc_timeout = HCI_PAIRING_TIMEOUT; 310876a68ba0SDavid Herrmann hci_conn_drop(conn); 3109052b30b0SMarcel Holtmann } 3110052b30b0SMarcel Holtmann 3111a8b2d5c2SJohan Hedberg if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags)) 311203b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, 311303b555e1SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 3114a8b2d5c2SJohan Hedberg else if (test_bit(HCI_MGMT, &hdev->dev_flags)) { 3115a770bb5aSWaldemar Rymarkiewicz u8 secure; 3116a770bb5aSWaldemar Rymarkiewicz 3117a770bb5aSWaldemar Rymarkiewicz if (conn->pending_sec_level == BT_SECURITY_HIGH) 3118a770bb5aSWaldemar Rymarkiewicz secure = 1; 3119a770bb5aSWaldemar Rymarkiewicz else 3120a770bb5aSWaldemar Rymarkiewicz secure = 0; 3121a770bb5aSWaldemar Rymarkiewicz 3122744cf19eSJohan Hedberg mgmt_pin_code_request(hdev, &ev->bdaddr, secure); 3123a770bb5aSWaldemar Rymarkiewicz } 3124980e1a53SJohan Hedberg 3125b6f98044SWaldemar Rymarkiewicz unlock: 3126052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 31271da177e4SLinus Torvalds } 31281da177e4SLinus Torvalds 31296039aa73SGustavo Padovan static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 31301da177e4SLinus Torvalds { 313155ed8ca1SJohan Hedberg struct hci_ev_link_key_req *ev = (void *) skb->data; 313255ed8ca1SJohan Hedberg struct hci_cp_link_key_reply cp; 313355ed8ca1SJohan Hedberg struct hci_conn *conn; 313455ed8ca1SJohan Hedberg struct link_key *key; 313555ed8ca1SJohan Hedberg 3136a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 313755ed8ca1SJohan Hedberg 3138034cbea0SAndrei Emeltchenko if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 313955ed8ca1SJohan Hedberg return; 314055ed8ca1SJohan Hedberg 314155ed8ca1SJohan Hedberg hci_dev_lock(hdev); 314255ed8ca1SJohan Hedberg 314355ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, &ev->bdaddr); 314455ed8ca1SJohan Hedberg if (!key) { 31456ed93dc6SAndrei Emeltchenko BT_DBG("%s link key not found for %pMR", hdev->name, 31466ed93dc6SAndrei Emeltchenko &ev->bdaddr); 314755ed8ca1SJohan Hedberg goto not_found; 314855ed8ca1SJohan Hedberg } 314955ed8ca1SJohan Hedberg 31506ed93dc6SAndrei Emeltchenko BT_DBG("%s found key type %u for %pMR", hdev->name, key->type, 31516ed93dc6SAndrei Emeltchenko &ev->bdaddr); 315255ed8ca1SJohan Hedberg 315355ed8ca1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 315460b83f57SWaldemar Rymarkiewicz if (conn) { 315566138ce8SMarcel Holtmann if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 || 315666138ce8SMarcel Holtmann key->type == HCI_LK_UNAUTH_COMBINATION_P256) && 3157807deac2SGustavo Padovan conn->auth_type != 0xff && (conn->auth_type & 0x01)) { 315855ed8ca1SJohan Hedberg BT_DBG("%s ignoring unauthenticated key", hdev->name); 315955ed8ca1SJohan Hedberg goto not_found; 316055ed8ca1SJohan Hedberg } 316155ed8ca1SJohan Hedberg 316260b83f57SWaldemar Rymarkiewicz if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && 3163f3fb0b58SJohan Hedberg (conn->pending_sec_level == BT_SECURITY_HIGH || 3164f3fb0b58SJohan Hedberg conn->pending_sec_level == BT_SECURITY_FIPS)) { 31658fc9ced3SGustavo Padovan BT_DBG("%s ignoring key unauthenticated for high security", 31668fc9ced3SGustavo Padovan hdev->name); 316760b83f57SWaldemar Rymarkiewicz goto not_found; 316860b83f57SWaldemar Rymarkiewicz } 316960b83f57SWaldemar Rymarkiewicz 317060b83f57SWaldemar Rymarkiewicz conn->key_type = key->type; 317160b83f57SWaldemar Rymarkiewicz conn->pin_length = key->pin_len; 317260b83f57SWaldemar Rymarkiewicz } 317360b83f57SWaldemar Rymarkiewicz 317455ed8ca1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 31759b3b4460SAndrei Emeltchenko memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE); 317655ed8ca1SJohan Hedberg 317755ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp); 317855ed8ca1SJohan Hedberg 317955ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 318055ed8ca1SJohan Hedberg 318155ed8ca1SJohan Hedberg return; 318255ed8ca1SJohan Hedberg 318355ed8ca1SJohan Hedberg not_found: 318455ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr); 318555ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 31861da177e4SLinus Torvalds } 31871da177e4SLinus Torvalds 31886039aa73SGustavo Padovan static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 31891da177e4SLinus Torvalds { 3190052b30b0SMarcel Holtmann struct hci_ev_link_key_notify *ev = (void *) skb->data; 3191052b30b0SMarcel Holtmann struct hci_conn *conn; 31927652ff6aSJohan Hedberg struct link_key *key; 31937652ff6aSJohan Hedberg bool persistent; 319455ed8ca1SJohan Hedberg u8 pin_len = 0; 3195052b30b0SMarcel Holtmann 3196a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 3197052b30b0SMarcel Holtmann 3198052b30b0SMarcel Holtmann hci_dev_lock(hdev); 3199052b30b0SMarcel Holtmann 3200052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 3201052b30b0SMarcel Holtmann if (conn) { 3202052b30b0SMarcel Holtmann hci_conn_hold(conn); 3203052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 3204980e1a53SJohan Hedberg pin_len = conn->pin_length; 320513d39315SWaldemar Rymarkiewicz 320613d39315SWaldemar Rymarkiewicz if (ev->key_type != HCI_LK_CHANGED_COMBINATION) 320713d39315SWaldemar Rymarkiewicz conn->key_type = ev->key_type; 320813d39315SWaldemar Rymarkiewicz 320976a68ba0SDavid Herrmann hci_conn_drop(conn); 3210052b30b0SMarcel Holtmann } 3211052b30b0SMarcel Holtmann 32127652ff6aSJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 32137652ff6aSJohan Hedberg goto unlock; 321455ed8ca1SJohan Hedberg 32157652ff6aSJohan Hedberg key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key, 32167652ff6aSJohan Hedberg ev->key_type, pin_len, &persistent); 32177652ff6aSJohan Hedberg if (!key) 32187652ff6aSJohan Hedberg goto unlock; 32197652ff6aSJohan Hedberg 32207652ff6aSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 32217652ff6aSJohan Hedberg 32226d5650c4SJohan Hedberg /* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag 32236d5650c4SJohan Hedberg * is set. If it's not set simply remove the key from the kernel 32246d5650c4SJohan Hedberg * list (we've still notified user space about it but with 32256d5650c4SJohan Hedberg * store_hint being 0). 32266d5650c4SJohan Hedberg */ 32276d5650c4SJohan Hedberg if (key->type == HCI_LK_DEBUG_COMBINATION && 32286d5650c4SJohan Hedberg !test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags)) { 32296d5650c4SJohan Hedberg list_del(&key->list); 32306d5650c4SJohan Hedberg kfree(key); 32316d5650c4SJohan Hedberg } else if (conn) { 3232af6a9c32SJohan Hedberg if (persistent) 3233af6a9c32SJohan Hedberg clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags); 3234af6a9c32SJohan Hedberg else 3235af6a9c32SJohan Hedberg set_bit(HCI_CONN_FLUSH_KEY, &conn->flags); 32366d5650c4SJohan Hedberg } 32377652ff6aSJohan Hedberg 32387652ff6aSJohan Hedberg unlock: 3239052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 32401da177e4SLinus Torvalds } 32411da177e4SLinus Torvalds 32426039aa73SGustavo Padovan static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) 324304837f64SMarcel Holtmann { 3244a9de9248SMarcel Holtmann struct hci_ev_clock_offset *ev = (void *) skb->data; 324504837f64SMarcel Holtmann struct hci_conn *conn; 324604837f64SMarcel Holtmann 32479f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 324804837f64SMarcel Holtmann 324904837f64SMarcel Holtmann hci_dev_lock(hdev); 325004837f64SMarcel Holtmann 325104837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 32521da177e4SLinus Torvalds if (conn && !ev->status) { 32531da177e4SLinus Torvalds struct inquiry_entry *ie; 32541da177e4SLinus Torvalds 3255cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 3256cc11b9c1SAndrei Emeltchenko if (ie) { 32571da177e4SLinus Torvalds ie->data.clock_offset = ev->clock_offset; 32581da177e4SLinus Torvalds ie->timestamp = jiffies; 32591da177e4SLinus Torvalds } 32601da177e4SLinus Torvalds } 32611da177e4SLinus Torvalds 32621da177e4SLinus Torvalds hci_dev_unlock(hdev); 32631da177e4SLinus Torvalds } 32641da177e4SLinus Torvalds 32656039aa73SGustavo Padovan static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 3266a8746417SMarcel Holtmann { 3267a8746417SMarcel Holtmann struct hci_ev_pkt_type_change *ev = (void *) skb->data; 3268a8746417SMarcel Holtmann struct hci_conn *conn; 3269a8746417SMarcel Holtmann 32709f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3271a8746417SMarcel Holtmann 3272a8746417SMarcel Holtmann hci_dev_lock(hdev); 3273a8746417SMarcel Holtmann 3274a8746417SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3275a8746417SMarcel Holtmann if (conn && !ev->status) 3276a8746417SMarcel Holtmann conn->pkt_type = __le16_to_cpu(ev->pkt_type); 3277a8746417SMarcel Holtmann 3278a8746417SMarcel Holtmann hci_dev_unlock(hdev); 3279a8746417SMarcel Holtmann } 3280a8746417SMarcel Holtmann 32816039aa73SGustavo Padovan static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) 328285a1e930SMarcel Holtmann { 3283a9de9248SMarcel Holtmann struct hci_ev_pscan_rep_mode *ev = (void *) skb->data; 328485a1e930SMarcel Holtmann struct inquiry_entry *ie; 328585a1e930SMarcel Holtmann 328685a1e930SMarcel Holtmann BT_DBG("%s", hdev->name); 328785a1e930SMarcel Holtmann 328885a1e930SMarcel Holtmann hci_dev_lock(hdev); 328985a1e930SMarcel Holtmann 3290cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 3291cc11b9c1SAndrei Emeltchenko if (ie) { 329285a1e930SMarcel Holtmann ie->data.pscan_rep_mode = ev->pscan_rep_mode; 329385a1e930SMarcel Holtmann ie->timestamp = jiffies; 329485a1e930SMarcel Holtmann } 329585a1e930SMarcel Holtmann 329685a1e930SMarcel Holtmann hci_dev_unlock(hdev); 329785a1e930SMarcel Holtmann } 329885a1e930SMarcel Holtmann 32996039aa73SGustavo Padovan static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, 3300807deac2SGustavo Padovan struct sk_buff *skb) 3301a9de9248SMarcel Holtmann { 3302a9de9248SMarcel Holtmann struct inquiry_data data; 3303a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 3304a9de9248SMarcel Holtmann 3305a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 3306a9de9248SMarcel Holtmann 3307a9de9248SMarcel Holtmann if (!num_rsp) 3308a9de9248SMarcel Holtmann return; 3309a9de9248SMarcel Holtmann 33101519cc17SAndre Guedes if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) 33111519cc17SAndre Guedes return; 33121519cc17SAndre Guedes 3313a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3314a9de9248SMarcel Holtmann 3315a9de9248SMarcel Holtmann if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { 3316138d22efSSzymon Janc struct inquiry_info_with_rssi_and_pscan_mode *info; 3317138d22efSSzymon Janc info = (void *) (skb->data + 1); 3318a9de9248SMarcel Holtmann 3319e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3320af58925cSMarcel Holtmann u32 flags; 3321af58925cSMarcel Holtmann 3322a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3323a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3324a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3325a9de9248SMarcel Holtmann data.pscan_mode = info->pscan_mode; 3326a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3327a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3328a9de9248SMarcel Holtmann data.rssi = info->rssi; 332941a96212SMarcel Holtmann data.ssp_mode = 0x00; 33303175405bSJohan Hedberg 3331af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 3332af58925cSMarcel Holtmann 333348264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3334e17acd40SJohan Hedberg info->dev_class, info->rssi, 3335af58925cSMarcel Holtmann flags, NULL, 0, NULL, 0); 3336a9de9248SMarcel Holtmann } 3337a9de9248SMarcel Holtmann } else { 3338a9de9248SMarcel Holtmann struct inquiry_info_with_rssi *info = (void *) (skb->data + 1); 3339a9de9248SMarcel Holtmann 3340e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3341af58925cSMarcel Holtmann u32 flags; 3342af58925cSMarcel Holtmann 3343a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3344a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3345a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3346a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 3347a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3348a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3349a9de9248SMarcel Holtmann data.rssi = info->rssi; 335041a96212SMarcel Holtmann data.ssp_mode = 0x00; 3351af58925cSMarcel Holtmann 3352af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 3353af58925cSMarcel Holtmann 335448264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3355e17acd40SJohan Hedberg info->dev_class, info->rssi, 3356af58925cSMarcel Holtmann flags, NULL, 0, NULL, 0); 3357a9de9248SMarcel Holtmann } 3358a9de9248SMarcel Holtmann } 3359a9de9248SMarcel Holtmann 3360a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3361a9de9248SMarcel Holtmann } 3362a9de9248SMarcel Holtmann 33636039aa73SGustavo Padovan static void hci_remote_ext_features_evt(struct hci_dev *hdev, 3364807deac2SGustavo Padovan struct sk_buff *skb) 3365a9de9248SMarcel Holtmann { 336641a96212SMarcel Holtmann struct hci_ev_remote_ext_features *ev = (void *) skb->data; 336741a96212SMarcel Holtmann struct hci_conn *conn; 336841a96212SMarcel Holtmann 3369a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 337041a96212SMarcel Holtmann 337141a96212SMarcel Holtmann hci_dev_lock(hdev); 337241a96212SMarcel Holtmann 337341a96212SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3374ccd556feSJohan Hedberg if (!conn) 3375ccd556feSJohan Hedberg goto unlock; 3376ccd556feSJohan Hedberg 3377cad718edSJohan Hedberg if (ev->page < HCI_MAX_PAGES) 3378cad718edSJohan Hedberg memcpy(conn->features[ev->page], ev->features, 8); 3379cad718edSJohan Hedberg 3380769be974SMarcel Holtmann if (!ev->status && ev->page == 0x01) { 338141a96212SMarcel Holtmann struct inquiry_entry *ie; 338241a96212SMarcel Holtmann 3383cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 3384cc11b9c1SAndrei Emeltchenko if (ie) 338502b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 338641a96212SMarcel Holtmann 3387bbb0eadaSJaganath Kanakkassery if (ev->features[0] & LMP_HOST_SSP) { 338858a681efSJohan Hedberg set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 3389bbb0eadaSJaganath Kanakkassery } else { 3390bbb0eadaSJaganath Kanakkassery /* It is mandatory by the Bluetooth specification that 3391bbb0eadaSJaganath Kanakkassery * Extended Inquiry Results are only used when Secure 3392bbb0eadaSJaganath Kanakkassery * Simple Pairing is enabled, but some devices violate 3393bbb0eadaSJaganath Kanakkassery * this. 3394bbb0eadaSJaganath Kanakkassery * 3395bbb0eadaSJaganath Kanakkassery * To make these devices work, the internal SSP 3396bbb0eadaSJaganath Kanakkassery * enabled flag needs to be cleared if the remote host 3397bbb0eadaSJaganath Kanakkassery * features do not indicate SSP support */ 3398bbb0eadaSJaganath Kanakkassery clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 3399bbb0eadaSJaganath Kanakkassery } 3400eb9a8f3fSMarcel Holtmann 3401eb9a8f3fSMarcel Holtmann if (ev->features[0] & LMP_HOST_SC) 3402eb9a8f3fSMarcel Holtmann set_bit(HCI_CONN_SC_ENABLED, &conn->flags); 340341a96212SMarcel Holtmann } 340441a96212SMarcel Holtmann 3405ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 3406ccd556feSJohan Hedberg goto unlock; 3407ccd556feSJohan Hedberg 3408671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 3409127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 3410127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 3411127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 3412127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 3413127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 3414b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 3415b644ba33SJohan Hedberg mgmt_device_connected(hdev, &conn->dst, conn->type, 341608c79b61SJohan Hedberg conn->dst_type, 0, NULL, 0, 3417b644ba33SJohan Hedberg conn->dev_class); 3418392599b9SJohan Hedberg 3419127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 3420769be974SMarcel Holtmann conn->state = BT_CONNECTED; 3421769be974SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 342276a68ba0SDavid Herrmann hci_conn_drop(conn); 3423769be974SMarcel Holtmann } 3424769be974SMarcel Holtmann 3425ccd556feSJohan Hedberg unlock: 342641a96212SMarcel Holtmann hci_dev_unlock(hdev); 3427a9de9248SMarcel Holtmann } 3428a9de9248SMarcel Holtmann 34296039aa73SGustavo Padovan static void hci_sync_conn_complete_evt(struct hci_dev *hdev, 3430807deac2SGustavo Padovan struct sk_buff *skb) 3431a9de9248SMarcel Holtmann { 3432b6a0dc82SMarcel Holtmann struct hci_ev_sync_conn_complete *ev = (void *) skb->data; 3433b6a0dc82SMarcel Holtmann struct hci_conn *conn; 3434b6a0dc82SMarcel Holtmann 34359f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3436b6a0dc82SMarcel Holtmann 3437b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 3438b6a0dc82SMarcel Holtmann 3439b6a0dc82SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 34409dc0a3afSMarcel Holtmann if (!conn) { 34419dc0a3afSMarcel Holtmann if (ev->link_type == ESCO_LINK) 34429dc0a3afSMarcel Holtmann goto unlock; 34439dc0a3afSMarcel Holtmann 34449dc0a3afSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 3445b6a0dc82SMarcel Holtmann if (!conn) 3446b6a0dc82SMarcel Holtmann goto unlock; 3447b6a0dc82SMarcel Holtmann 34489dc0a3afSMarcel Holtmann conn->type = SCO_LINK; 34499dc0a3afSMarcel Holtmann } 34509dc0a3afSMarcel Holtmann 3451732547f9SMarcel Holtmann switch (ev->status) { 3452732547f9SMarcel Holtmann case 0x00: 3453732547f9SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 3454732547f9SMarcel Holtmann conn->state = BT_CONNECTED; 3455732547f9SMarcel Holtmann 3456732547f9SMarcel Holtmann hci_conn_add_sysfs(conn); 3457732547f9SMarcel Holtmann break; 3458732547f9SMarcel Holtmann 345981218d20SNick Pelly case 0x10: /* Connection Accept Timeout */ 34601a4c958cSFrédéric Dalleau case 0x0d: /* Connection Rejected due to Limited Resources */ 3461705e5711SStephen Coe case 0x11: /* Unsupported Feature or Parameter Value */ 3462732547f9SMarcel Holtmann case 0x1c: /* SCO interval rejected */ 34631038a00bSNick Pelly case 0x1a: /* Unsupported Remote Feature */ 3464732547f9SMarcel Holtmann case 0x1f: /* Unspecified error */ 346527539bc4SAndrew Earl case 0x20: /* Unsupported LMP Parameter value */ 34662dea632fSFrédéric Dalleau if (conn->out) { 3467efc7688bSMarcel Holtmann conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | 3468efc7688bSMarcel Holtmann (hdev->esco_type & EDR_ESCO_MASK); 34692dea632fSFrédéric Dalleau if (hci_setup_sync(conn, conn->link->handle)) 3470efc7688bSMarcel Holtmann goto unlock; 3471efc7688bSMarcel Holtmann } 3472732547f9SMarcel Holtmann /* fall through */ 3473efc7688bSMarcel Holtmann 3474732547f9SMarcel Holtmann default: 3475b6a0dc82SMarcel Holtmann conn->state = BT_CLOSED; 3476732547f9SMarcel Holtmann break; 3477732547f9SMarcel Holtmann } 3478b6a0dc82SMarcel Holtmann 3479b6a0dc82SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 3480b6a0dc82SMarcel Holtmann if (ev->status) 3481b6a0dc82SMarcel Holtmann hci_conn_del(conn); 3482b6a0dc82SMarcel Holtmann 3483b6a0dc82SMarcel Holtmann unlock: 3484b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 3485a9de9248SMarcel Holtmann } 3486a9de9248SMarcel Holtmann 3487efdcf8e3SMarcel Holtmann static inline size_t eir_get_length(u8 *eir, size_t eir_len) 3488efdcf8e3SMarcel Holtmann { 3489efdcf8e3SMarcel Holtmann size_t parsed = 0; 3490efdcf8e3SMarcel Holtmann 3491efdcf8e3SMarcel Holtmann while (parsed < eir_len) { 3492efdcf8e3SMarcel Holtmann u8 field_len = eir[0]; 3493efdcf8e3SMarcel Holtmann 3494efdcf8e3SMarcel Holtmann if (field_len == 0) 3495efdcf8e3SMarcel Holtmann return parsed; 3496efdcf8e3SMarcel Holtmann 3497efdcf8e3SMarcel Holtmann parsed += field_len + 1; 3498efdcf8e3SMarcel Holtmann eir += field_len + 1; 3499efdcf8e3SMarcel Holtmann } 3500efdcf8e3SMarcel Holtmann 3501efdcf8e3SMarcel Holtmann return eir_len; 3502efdcf8e3SMarcel Holtmann } 3503efdcf8e3SMarcel Holtmann 35046039aa73SGustavo Padovan static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, 3505807deac2SGustavo Padovan struct sk_buff *skb) 3506a9de9248SMarcel Holtmann { 3507a9de9248SMarcel Holtmann struct inquiry_data data; 3508a9de9248SMarcel Holtmann struct extended_inquiry_info *info = (void *) (skb->data + 1); 3509a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 35109d939d94SVishal Agarwal size_t eir_len; 3511a9de9248SMarcel Holtmann 3512a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 3513a9de9248SMarcel Holtmann 3514a9de9248SMarcel Holtmann if (!num_rsp) 3515a9de9248SMarcel Holtmann return; 3516a9de9248SMarcel Holtmann 35171519cc17SAndre Guedes if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) 35181519cc17SAndre Guedes return; 35191519cc17SAndre Guedes 3520a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3521a9de9248SMarcel Holtmann 3522e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3523af58925cSMarcel Holtmann u32 flags; 3524af58925cSMarcel Holtmann bool name_known; 3525561aafbcSJohan Hedberg 3526a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3527a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3528a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3529a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 3530a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3531a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3532a9de9248SMarcel Holtmann data.rssi = info->rssi; 353341a96212SMarcel Holtmann data.ssp_mode = 0x01; 3534561aafbcSJohan Hedberg 3535a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 35364ddb1930SJohan Hedberg name_known = eir_has_data_type(info->data, 35374ddb1930SJohan Hedberg sizeof(info->data), 35384ddb1930SJohan Hedberg EIR_NAME_COMPLETE); 3539561aafbcSJohan Hedberg else 3540561aafbcSJohan Hedberg name_known = true; 3541561aafbcSJohan Hedberg 3542af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, name_known); 3543af58925cSMarcel Holtmann 35449d939d94SVishal Agarwal eir_len = eir_get_length(info->data, sizeof(info->data)); 3545af58925cSMarcel Holtmann 354648264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3547af58925cSMarcel Holtmann info->dev_class, info->rssi, 3548af58925cSMarcel Holtmann flags, info->data, eir_len, NULL, 0); 3549a9de9248SMarcel Holtmann } 3550a9de9248SMarcel Holtmann 3551a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3552a9de9248SMarcel Holtmann } 3553a9de9248SMarcel Holtmann 35541c2e0041SJohan Hedberg static void hci_key_refresh_complete_evt(struct hci_dev *hdev, 35551c2e0041SJohan Hedberg struct sk_buff *skb) 35561c2e0041SJohan Hedberg { 35571c2e0041SJohan Hedberg struct hci_ev_key_refresh_complete *ev = (void *) skb->data; 35581c2e0041SJohan Hedberg struct hci_conn *conn; 35591c2e0041SJohan Hedberg 35609f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status, 35611c2e0041SJohan Hedberg __le16_to_cpu(ev->handle)); 35621c2e0041SJohan Hedberg 35631c2e0041SJohan Hedberg hci_dev_lock(hdev); 35641c2e0041SJohan Hedberg 35651c2e0041SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 35661c2e0041SJohan Hedberg if (!conn) 35671c2e0041SJohan Hedberg goto unlock; 35681c2e0041SJohan Hedberg 35699eb1fbfaSJohan Hedberg /* For BR/EDR the necessary steps are taken through the 35709eb1fbfaSJohan Hedberg * auth_complete event. 35719eb1fbfaSJohan Hedberg */ 35729eb1fbfaSJohan Hedberg if (conn->type != LE_LINK) 35739eb1fbfaSJohan Hedberg goto unlock; 35749eb1fbfaSJohan Hedberg 35751c2e0041SJohan Hedberg if (!ev->status) 35761c2e0041SJohan Hedberg conn->sec_level = conn->pending_sec_level; 35771c2e0041SJohan Hedberg 35781c2e0041SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 35791c2e0041SJohan Hedberg 35801c2e0041SJohan Hedberg if (ev->status && conn->state == BT_CONNECTED) { 3581bed71748SAndre Guedes hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 358276a68ba0SDavid Herrmann hci_conn_drop(conn); 35831c2e0041SJohan Hedberg goto unlock; 35841c2e0041SJohan Hedberg } 35851c2e0041SJohan Hedberg 35861c2e0041SJohan Hedberg if (conn->state == BT_CONFIG) { 35871c2e0041SJohan Hedberg if (!ev->status) 35881c2e0041SJohan Hedberg conn->state = BT_CONNECTED; 35891c2e0041SJohan Hedberg 35901c2e0041SJohan Hedberg hci_proto_connect_cfm(conn, ev->status); 359176a68ba0SDavid Herrmann hci_conn_drop(conn); 35921c2e0041SJohan Hedberg } else { 35931c2e0041SJohan Hedberg hci_auth_cfm(conn, ev->status); 35941c2e0041SJohan Hedberg 35951c2e0041SJohan Hedberg hci_conn_hold(conn); 35961c2e0041SJohan Hedberg conn->disc_timeout = HCI_DISCONN_TIMEOUT; 359776a68ba0SDavid Herrmann hci_conn_drop(conn); 35981c2e0041SJohan Hedberg } 35991c2e0041SJohan Hedberg 36001c2e0041SJohan Hedberg unlock: 36011c2e0041SJohan Hedberg hci_dev_unlock(hdev); 36021c2e0041SJohan Hedberg } 36031c2e0041SJohan Hedberg 36046039aa73SGustavo Padovan static u8 hci_get_auth_req(struct hci_conn *conn) 360517fa4b9dSJohan Hedberg { 360617fa4b9dSJohan Hedberg /* If remote requests no-bonding follow that lead */ 3607acabae96SMikel Astiz if (conn->remote_auth == HCI_AT_NO_BONDING || 3608acabae96SMikel Astiz conn->remote_auth == HCI_AT_NO_BONDING_MITM) 360958797bf7SWaldemar Rymarkiewicz return conn->remote_auth | (conn->auth_type & 0x01); 361017fa4b9dSJohan Hedberg 3611b7f94c88SMikel Astiz /* If both remote and local have enough IO capabilities, require 3612b7f94c88SMikel Astiz * MITM protection 3613b7f94c88SMikel Astiz */ 3614b7f94c88SMikel Astiz if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT && 3615b7f94c88SMikel Astiz conn->io_capability != HCI_IO_NO_INPUT_OUTPUT) 3616b7f94c88SMikel Astiz return conn->remote_auth | 0x01; 3617b7f94c88SMikel Astiz 36187e74170aSTimo Mueller /* No MITM protection possible so ignore remote requirement */ 36197e74170aSTimo Mueller return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01); 362017fa4b9dSJohan Hedberg } 362117fa4b9dSJohan Hedberg 36226039aa73SGustavo Padovan static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 36230493684eSMarcel Holtmann { 36240493684eSMarcel Holtmann struct hci_ev_io_capa_request *ev = (void *) skb->data; 36250493684eSMarcel Holtmann struct hci_conn *conn; 36260493684eSMarcel Holtmann 36270493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 36280493684eSMarcel Holtmann 36290493684eSMarcel Holtmann hci_dev_lock(hdev); 36300493684eSMarcel Holtmann 36310493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 363203b555e1SJohan Hedberg if (!conn) 363303b555e1SJohan Hedberg goto unlock; 363403b555e1SJohan Hedberg 36350493684eSMarcel Holtmann hci_conn_hold(conn); 36360493684eSMarcel Holtmann 3637a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 363803b555e1SJohan Hedberg goto unlock; 363903b555e1SJohan Hedberg 3640a8b2d5c2SJohan Hedberg if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) || 364103b555e1SJohan Hedberg (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { 364217fa4b9dSJohan Hedberg struct hci_cp_io_capability_reply cp; 364317fa4b9dSJohan Hedberg 364417fa4b9dSJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 36457a7f1e7cSHemant Gupta /* Change the IO capability from KeyboardDisplay 36467a7f1e7cSHemant Gupta * to DisplayYesNo as it is not supported by BT spec. */ 36477a7f1e7cSHemant Gupta cp.capability = (conn->io_capability == 0x04) ? 3648a767631aSMikel Astiz HCI_IO_DISPLAY_YESNO : conn->io_capability; 3649b7f94c88SMikel Astiz 3650b7f94c88SMikel Astiz /* If we are initiators, there is no remote information yet */ 3651b7f94c88SMikel Astiz if (conn->remote_auth == 0xff) { 3652b7f94c88SMikel Astiz cp.authentication = conn->auth_type; 36536fd6b915SMikel Astiz 3654b16c6604SMikel Astiz /* Request MITM protection if our IO caps allow it 36554ad51a75SJohan Hedberg * except for the no-bonding case. 36564ad51a75SJohan Hedberg * conn->auth_type is not updated here since 36574ad51a75SJohan Hedberg * that might cause the user confirmation to be 36584ad51a75SJohan Hedberg * rejected in case the remote doesn't have the 36594ad51a75SJohan Hedberg * IO capabilities for MITM. 3660b16c6604SMikel Astiz */ 36616fd6b915SMikel Astiz if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT && 3662b16c6604SMikel Astiz cp.authentication != HCI_AT_NO_BONDING) 36636fd6b915SMikel Astiz cp.authentication |= 0x01; 3664b7f94c88SMikel Astiz } else { 36657cbc9bd9SJohan Hedberg conn->auth_type = hci_get_auth_req(conn); 36667cbc9bd9SJohan Hedberg cp.authentication = conn->auth_type; 3667b7f94c88SMikel Astiz } 366817fa4b9dSJohan Hedberg 36698fc9ced3SGustavo Padovan if (hci_find_remote_oob_data(hdev, &conn->dst) && 36708fc9ced3SGustavo Padovan (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags))) 3671ce85ee13SSzymon Janc cp.oob_data = 0x01; 3672ce85ee13SSzymon Janc else 3673ce85ee13SSzymon Janc cp.oob_data = 0x00; 3674ce85ee13SSzymon Janc 367517fa4b9dSJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY, 367617fa4b9dSJohan Hedberg sizeof(cp), &cp); 367703b555e1SJohan Hedberg } else { 367803b555e1SJohan Hedberg struct hci_cp_io_capability_neg_reply cp; 367903b555e1SJohan Hedberg 368003b555e1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 36819f5a0d7bSAndrei Emeltchenko cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED; 368203b555e1SJohan Hedberg 368303b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, 368403b555e1SJohan Hedberg sizeof(cp), &cp); 368503b555e1SJohan Hedberg } 368603b555e1SJohan Hedberg 368703b555e1SJohan Hedberg unlock: 368803b555e1SJohan Hedberg hci_dev_unlock(hdev); 368903b555e1SJohan Hedberg } 369003b555e1SJohan Hedberg 36916039aa73SGustavo Padovan static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) 369203b555e1SJohan Hedberg { 369303b555e1SJohan Hedberg struct hci_ev_io_capa_reply *ev = (void *) skb->data; 369403b555e1SJohan Hedberg struct hci_conn *conn; 369503b555e1SJohan Hedberg 369603b555e1SJohan Hedberg BT_DBG("%s", hdev->name); 369703b555e1SJohan Hedberg 369803b555e1SJohan Hedberg hci_dev_lock(hdev); 369903b555e1SJohan Hedberg 370003b555e1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 370103b555e1SJohan Hedberg if (!conn) 370203b555e1SJohan Hedberg goto unlock; 370303b555e1SJohan Hedberg 370403b555e1SJohan Hedberg conn->remote_cap = ev->capability; 370503b555e1SJohan Hedberg conn->remote_auth = ev->authentication; 370658a681efSJohan Hedberg if (ev->oob_data) 370758a681efSJohan Hedberg set_bit(HCI_CONN_REMOTE_OOB, &conn->flags); 370803b555e1SJohan Hedberg 370903b555e1SJohan Hedberg unlock: 37100493684eSMarcel Holtmann hci_dev_unlock(hdev); 37110493684eSMarcel Holtmann } 37120493684eSMarcel Holtmann 37136039aa73SGustavo Padovan static void hci_user_confirm_request_evt(struct hci_dev *hdev, 3714a5c29683SJohan Hedberg struct sk_buff *skb) 3715a5c29683SJohan Hedberg { 3716a5c29683SJohan Hedberg struct hci_ev_user_confirm_req *ev = (void *) skb->data; 371755bc1a37SJohan Hedberg int loc_mitm, rem_mitm, confirm_hint = 0; 37187a828908SJohan Hedberg struct hci_conn *conn; 3719a5c29683SJohan Hedberg 3720a5c29683SJohan Hedberg BT_DBG("%s", hdev->name); 3721a5c29683SJohan Hedberg 3722a5c29683SJohan Hedberg hci_dev_lock(hdev); 3723a5c29683SJohan Hedberg 3724a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 37257a828908SJohan Hedberg goto unlock; 37267a828908SJohan Hedberg 37277a828908SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 37287a828908SJohan Hedberg if (!conn) 37297a828908SJohan Hedberg goto unlock; 37307a828908SJohan Hedberg 37317a828908SJohan Hedberg loc_mitm = (conn->auth_type & 0x01); 37327a828908SJohan Hedberg rem_mitm = (conn->remote_auth & 0x01); 37337a828908SJohan Hedberg 37347a828908SJohan Hedberg /* If we require MITM but the remote device can't provide that 37356fd6b915SMikel Astiz * (it has NoInputNoOutput) then reject the confirmation request 37366fd6b915SMikel Astiz */ 37376fd6b915SMikel Astiz if (loc_mitm && conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) { 37387a828908SJohan Hedberg BT_DBG("Rejecting request: remote device can't provide MITM"); 37397a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY, 37407a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 37417a828908SJohan Hedberg goto unlock; 37427a828908SJohan Hedberg } 37437a828908SJohan Hedberg 37447a828908SJohan Hedberg /* If no side requires MITM protection; auto-accept */ 3745a767631aSMikel Astiz if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) && 3746a767631aSMikel Astiz (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) { 374755bc1a37SJohan Hedberg 374855bc1a37SJohan Hedberg /* If we're not the initiators request authorization to 374955bc1a37SJohan Hedberg * proceed from user space (mgmt_user_confirm with 3750ba15a58bSJohan Hedberg * confirm_hint set to 1). The exception is if neither 3751ba15a58bSJohan Hedberg * side had MITM in which case we do auto-accept. 3752ba15a58bSJohan Hedberg */ 3753ba15a58bSJohan Hedberg if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && 3754ba15a58bSJohan Hedberg (loc_mitm || rem_mitm)) { 375555bc1a37SJohan Hedberg BT_DBG("Confirming auto-accept as acceptor"); 375655bc1a37SJohan Hedberg confirm_hint = 1; 375755bc1a37SJohan Hedberg goto confirm; 375855bc1a37SJohan Hedberg } 375955bc1a37SJohan Hedberg 37609f61656aSJohan Hedberg BT_DBG("Auto-accept of user confirmation with %ums delay", 37619f61656aSJohan Hedberg hdev->auto_accept_delay); 37629f61656aSJohan Hedberg 37639f61656aSJohan Hedberg if (hdev->auto_accept_delay > 0) { 37649f61656aSJohan Hedberg int delay = msecs_to_jiffies(hdev->auto_accept_delay); 37657bc18d9dSJohan Hedberg queue_delayed_work(conn->hdev->workqueue, 37667bc18d9dSJohan Hedberg &conn->auto_accept_work, delay); 37679f61656aSJohan Hedberg goto unlock; 37689f61656aSJohan Hedberg } 37699f61656aSJohan Hedberg 37707a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, 37717a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 37727a828908SJohan Hedberg goto unlock; 37737a828908SJohan Hedberg } 37747a828908SJohan Hedberg 377555bc1a37SJohan Hedberg confirm: 377639adbffeSJohan Hedberg mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, 377739adbffeSJohan Hedberg le32_to_cpu(ev->passkey), confirm_hint); 3778a5c29683SJohan Hedberg 37797a828908SJohan Hedberg unlock: 3780a5c29683SJohan Hedberg hci_dev_unlock(hdev); 3781a5c29683SJohan Hedberg } 3782a5c29683SJohan Hedberg 37836039aa73SGustavo Padovan static void hci_user_passkey_request_evt(struct hci_dev *hdev, 37841143d458SBrian Gix struct sk_buff *skb) 37851143d458SBrian Gix { 37861143d458SBrian Gix struct hci_ev_user_passkey_req *ev = (void *) skb->data; 37871143d458SBrian Gix 37881143d458SBrian Gix BT_DBG("%s", hdev->name); 37891143d458SBrian Gix 3790a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 3791272d90dfSJohan Hedberg mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); 37921143d458SBrian Gix } 37931143d458SBrian Gix 379492a25256SJohan Hedberg static void hci_user_passkey_notify_evt(struct hci_dev *hdev, 379592a25256SJohan Hedberg struct sk_buff *skb) 379692a25256SJohan Hedberg { 379792a25256SJohan Hedberg struct hci_ev_user_passkey_notify *ev = (void *) skb->data; 379892a25256SJohan Hedberg struct hci_conn *conn; 379992a25256SJohan Hedberg 380092a25256SJohan Hedberg BT_DBG("%s", hdev->name); 380192a25256SJohan Hedberg 380292a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 380392a25256SJohan Hedberg if (!conn) 380492a25256SJohan Hedberg return; 380592a25256SJohan Hedberg 380692a25256SJohan Hedberg conn->passkey_notify = __le32_to_cpu(ev->passkey); 380792a25256SJohan Hedberg conn->passkey_entered = 0; 380892a25256SJohan Hedberg 380992a25256SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 381092a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 381192a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 381292a25256SJohan Hedberg conn->passkey_entered); 381392a25256SJohan Hedberg } 381492a25256SJohan Hedberg 381592a25256SJohan Hedberg static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 381692a25256SJohan Hedberg { 381792a25256SJohan Hedberg struct hci_ev_keypress_notify *ev = (void *) skb->data; 381892a25256SJohan Hedberg struct hci_conn *conn; 381992a25256SJohan Hedberg 382092a25256SJohan Hedberg BT_DBG("%s", hdev->name); 382192a25256SJohan Hedberg 382292a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 382392a25256SJohan Hedberg if (!conn) 382492a25256SJohan Hedberg return; 382592a25256SJohan Hedberg 382692a25256SJohan Hedberg switch (ev->type) { 382792a25256SJohan Hedberg case HCI_KEYPRESS_STARTED: 382892a25256SJohan Hedberg conn->passkey_entered = 0; 382992a25256SJohan Hedberg return; 383092a25256SJohan Hedberg 383192a25256SJohan Hedberg case HCI_KEYPRESS_ENTERED: 383292a25256SJohan Hedberg conn->passkey_entered++; 383392a25256SJohan Hedberg break; 383492a25256SJohan Hedberg 383592a25256SJohan Hedberg case HCI_KEYPRESS_ERASED: 383692a25256SJohan Hedberg conn->passkey_entered--; 383792a25256SJohan Hedberg break; 383892a25256SJohan Hedberg 383992a25256SJohan Hedberg case HCI_KEYPRESS_CLEARED: 384092a25256SJohan Hedberg conn->passkey_entered = 0; 384192a25256SJohan Hedberg break; 384292a25256SJohan Hedberg 384392a25256SJohan Hedberg case HCI_KEYPRESS_COMPLETED: 384492a25256SJohan Hedberg return; 384592a25256SJohan Hedberg } 384692a25256SJohan Hedberg 384792a25256SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 384892a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 384992a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 385092a25256SJohan Hedberg conn->passkey_entered); 385192a25256SJohan Hedberg } 385292a25256SJohan Hedberg 38536039aa73SGustavo Padovan static void hci_simple_pair_complete_evt(struct hci_dev *hdev, 3854807deac2SGustavo Padovan struct sk_buff *skb) 38550493684eSMarcel Holtmann { 38560493684eSMarcel Holtmann struct hci_ev_simple_pair_complete *ev = (void *) skb->data; 38570493684eSMarcel Holtmann struct hci_conn *conn; 38580493684eSMarcel Holtmann 38590493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 38600493684eSMarcel Holtmann 38610493684eSMarcel Holtmann hci_dev_lock(hdev); 38620493684eSMarcel Holtmann 38630493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 38642a611692SJohan Hedberg if (!conn) 38652a611692SJohan Hedberg goto unlock; 38662a611692SJohan Hedberg 38672a611692SJohan Hedberg /* To avoid duplicate auth_failed events to user space we check 38682a611692SJohan Hedberg * the HCI_CONN_AUTH_PEND flag which will be set if we 38692a611692SJohan Hedberg * initiated the authentication. A traditional auth_complete 38702a611692SJohan Hedberg * event gets always produced as initiator and is also mapped to 38712a611692SJohan Hedberg * the mgmt_auth_failed event */ 3872fa1bd918SMikel Astiz if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status) 3873bab73cb6SJohan Hedberg mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, 3874bab73cb6SJohan Hedberg ev->status); 38752a611692SJohan Hedberg 387676a68ba0SDavid Herrmann hci_conn_drop(conn); 38770493684eSMarcel Holtmann 38782a611692SJohan Hedberg unlock: 38790493684eSMarcel Holtmann hci_dev_unlock(hdev); 38800493684eSMarcel Holtmann } 38810493684eSMarcel Holtmann 38826039aa73SGustavo Padovan static void hci_remote_host_features_evt(struct hci_dev *hdev, 3883807deac2SGustavo Padovan struct sk_buff *skb) 388441a96212SMarcel Holtmann { 388541a96212SMarcel Holtmann struct hci_ev_remote_host_features *ev = (void *) skb->data; 388641a96212SMarcel Holtmann struct inquiry_entry *ie; 3887cad718edSJohan Hedberg struct hci_conn *conn; 388841a96212SMarcel Holtmann 388941a96212SMarcel Holtmann BT_DBG("%s", hdev->name); 389041a96212SMarcel Holtmann 389141a96212SMarcel Holtmann hci_dev_lock(hdev); 389241a96212SMarcel Holtmann 3893cad718edSJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 3894cad718edSJohan Hedberg if (conn) 3895cad718edSJohan Hedberg memcpy(conn->features[1], ev->features, 8); 3896cad718edSJohan Hedberg 3897cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 3898cc11b9c1SAndrei Emeltchenko if (ie) 389902b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 390041a96212SMarcel Holtmann 390141a96212SMarcel Holtmann hci_dev_unlock(hdev); 390241a96212SMarcel Holtmann } 390341a96212SMarcel Holtmann 39046039aa73SGustavo Padovan static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, 39052763eda6SSzymon Janc struct sk_buff *skb) 39062763eda6SSzymon Janc { 39072763eda6SSzymon Janc struct hci_ev_remote_oob_data_request *ev = (void *) skb->data; 39082763eda6SSzymon Janc struct oob_data *data; 39092763eda6SSzymon Janc 39102763eda6SSzymon Janc BT_DBG("%s", hdev->name); 39112763eda6SSzymon Janc 39122763eda6SSzymon Janc hci_dev_lock(hdev); 39132763eda6SSzymon Janc 3914a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 3915e1ba1f15SSzymon Janc goto unlock; 3916e1ba1f15SSzymon Janc 39172763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, &ev->bdaddr); 39182763eda6SSzymon Janc if (data) { 3919519ca9d0SMarcel Holtmann if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) { 3920519ca9d0SMarcel Holtmann struct hci_cp_remote_oob_ext_data_reply cp; 3921519ca9d0SMarcel Holtmann 3922519ca9d0SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 3923519ca9d0SMarcel Holtmann memcpy(cp.hash192, data->hash192, sizeof(cp.hash192)); 3924519ca9d0SMarcel Holtmann memcpy(cp.randomizer192, data->randomizer192, 3925519ca9d0SMarcel Holtmann sizeof(cp.randomizer192)); 3926519ca9d0SMarcel Holtmann memcpy(cp.hash256, data->hash256, sizeof(cp.hash256)); 3927519ca9d0SMarcel Holtmann memcpy(cp.randomizer256, data->randomizer256, 3928519ca9d0SMarcel Holtmann sizeof(cp.randomizer256)); 3929519ca9d0SMarcel Holtmann 3930519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY, 3931519ca9d0SMarcel Holtmann sizeof(cp), &cp); 3932519ca9d0SMarcel Holtmann } else { 39332763eda6SSzymon Janc struct hci_cp_remote_oob_data_reply cp; 39342763eda6SSzymon Janc 39352763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr); 3936519ca9d0SMarcel Holtmann memcpy(cp.hash, data->hash192, sizeof(cp.hash)); 3937519ca9d0SMarcel Holtmann memcpy(cp.randomizer, data->randomizer192, 3938519ca9d0SMarcel Holtmann sizeof(cp.randomizer)); 39392763eda6SSzymon Janc 3940519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, 3941519ca9d0SMarcel Holtmann sizeof(cp), &cp); 3942519ca9d0SMarcel Holtmann } 39432763eda6SSzymon Janc } else { 39442763eda6SSzymon Janc struct hci_cp_remote_oob_data_neg_reply cp; 39452763eda6SSzymon Janc 39462763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr); 3947519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, 3948519ca9d0SMarcel Holtmann sizeof(cp), &cp); 39492763eda6SSzymon Janc } 39502763eda6SSzymon Janc 3951e1ba1f15SSzymon Janc unlock: 39522763eda6SSzymon Janc hci_dev_unlock(hdev); 39532763eda6SSzymon Janc } 39542763eda6SSzymon Janc 3955d5e91192SAndrei Emeltchenko static void hci_phy_link_complete_evt(struct hci_dev *hdev, 3956d5e91192SAndrei Emeltchenko struct sk_buff *skb) 3957d5e91192SAndrei Emeltchenko { 3958d5e91192SAndrei Emeltchenko struct hci_ev_phy_link_complete *ev = (void *) skb->data; 3959d5e91192SAndrei Emeltchenko struct hci_conn *hcon, *bredr_hcon; 3960d5e91192SAndrei Emeltchenko 3961d5e91192SAndrei Emeltchenko BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle, 3962d5e91192SAndrei Emeltchenko ev->status); 3963d5e91192SAndrei Emeltchenko 3964d5e91192SAndrei Emeltchenko hci_dev_lock(hdev); 3965d5e91192SAndrei Emeltchenko 3966d5e91192SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 3967d5e91192SAndrei Emeltchenko if (!hcon) { 3968d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 3969d5e91192SAndrei Emeltchenko return; 3970d5e91192SAndrei Emeltchenko } 3971d5e91192SAndrei Emeltchenko 3972d5e91192SAndrei Emeltchenko if (ev->status) { 3973d5e91192SAndrei Emeltchenko hci_conn_del(hcon); 3974d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 3975d5e91192SAndrei Emeltchenko return; 3976d5e91192SAndrei Emeltchenko } 3977d5e91192SAndrei Emeltchenko 3978d5e91192SAndrei Emeltchenko bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon; 3979d5e91192SAndrei Emeltchenko 3980d5e91192SAndrei Emeltchenko hcon->state = BT_CONNECTED; 3981d5e91192SAndrei Emeltchenko bacpy(&hcon->dst, &bredr_hcon->dst); 3982d5e91192SAndrei Emeltchenko 3983d5e91192SAndrei Emeltchenko hci_conn_hold(hcon); 3984d5e91192SAndrei Emeltchenko hcon->disc_timeout = HCI_DISCONN_TIMEOUT; 398576a68ba0SDavid Herrmann hci_conn_drop(hcon); 3986d5e91192SAndrei Emeltchenko 3987d5e91192SAndrei Emeltchenko hci_conn_add_sysfs(hcon); 3988d5e91192SAndrei Emeltchenko 3989cf70ff22SAndrei Emeltchenko amp_physical_cfm(bredr_hcon, hcon); 3990cf70ff22SAndrei Emeltchenko 3991d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 3992d5e91192SAndrei Emeltchenko } 3993d5e91192SAndrei Emeltchenko 399427695fb4SAndrei Emeltchenko static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 399527695fb4SAndrei Emeltchenko { 399627695fb4SAndrei Emeltchenko struct hci_ev_logical_link_complete *ev = (void *) skb->data; 399727695fb4SAndrei Emeltchenko struct hci_conn *hcon; 399827695fb4SAndrei Emeltchenko struct hci_chan *hchan; 399927695fb4SAndrei Emeltchenko struct amp_mgr *mgr; 400027695fb4SAndrei Emeltchenko 400127695fb4SAndrei Emeltchenko BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x", 400227695fb4SAndrei Emeltchenko hdev->name, le16_to_cpu(ev->handle), ev->phy_handle, 400327695fb4SAndrei Emeltchenko ev->status); 400427695fb4SAndrei Emeltchenko 400527695fb4SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 400627695fb4SAndrei Emeltchenko if (!hcon) 400727695fb4SAndrei Emeltchenko return; 400827695fb4SAndrei Emeltchenko 400927695fb4SAndrei Emeltchenko /* Create AMP hchan */ 401027695fb4SAndrei Emeltchenko hchan = hci_chan_create(hcon); 401127695fb4SAndrei Emeltchenko if (!hchan) 401227695fb4SAndrei Emeltchenko return; 401327695fb4SAndrei Emeltchenko 401427695fb4SAndrei Emeltchenko hchan->handle = le16_to_cpu(ev->handle); 401527695fb4SAndrei Emeltchenko 401627695fb4SAndrei Emeltchenko BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan); 401727695fb4SAndrei Emeltchenko 401827695fb4SAndrei Emeltchenko mgr = hcon->amp_mgr; 401927695fb4SAndrei Emeltchenko if (mgr && mgr->bredr_chan) { 402027695fb4SAndrei Emeltchenko struct l2cap_chan *bredr_chan = mgr->bredr_chan; 402127695fb4SAndrei Emeltchenko 402227695fb4SAndrei Emeltchenko l2cap_chan_lock(bredr_chan); 402327695fb4SAndrei Emeltchenko 402427695fb4SAndrei Emeltchenko bredr_chan->conn->mtu = hdev->block_mtu; 402527695fb4SAndrei Emeltchenko l2cap_logical_cfm(bredr_chan, hchan, 0); 402627695fb4SAndrei Emeltchenko hci_conn_hold(hcon); 402727695fb4SAndrei Emeltchenko 402827695fb4SAndrei Emeltchenko l2cap_chan_unlock(bredr_chan); 402927695fb4SAndrei Emeltchenko } 403027695fb4SAndrei Emeltchenko } 403127695fb4SAndrei Emeltchenko 4032606e2a10SAndrei Emeltchenko static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev, 4033606e2a10SAndrei Emeltchenko struct sk_buff *skb) 4034606e2a10SAndrei Emeltchenko { 4035606e2a10SAndrei Emeltchenko struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data; 4036606e2a10SAndrei Emeltchenko struct hci_chan *hchan; 4037606e2a10SAndrei Emeltchenko 4038606e2a10SAndrei Emeltchenko BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name, 4039606e2a10SAndrei Emeltchenko le16_to_cpu(ev->handle), ev->status); 4040606e2a10SAndrei Emeltchenko 4041606e2a10SAndrei Emeltchenko if (ev->status) 4042606e2a10SAndrei Emeltchenko return; 4043606e2a10SAndrei Emeltchenko 4044606e2a10SAndrei Emeltchenko hci_dev_lock(hdev); 4045606e2a10SAndrei Emeltchenko 4046606e2a10SAndrei Emeltchenko hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle)); 4047606e2a10SAndrei Emeltchenko if (!hchan) 4048606e2a10SAndrei Emeltchenko goto unlock; 4049606e2a10SAndrei Emeltchenko 4050606e2a10SAndrei Emeltchenko amp_destroy_logical_link(hchan, ev->reason); 4051606e2a10SAndrei Emeltchenko 4052606e2a10SAndrei Emeltchenko unlock: 4053606e2a10SAndrei Emeltchenko hci_dev_unlock(hdev); 4054606e2a10SAndrei Emeltchenko } 4055606e2a10SAndrei Emeltchenko 40569eef6b3aSAndrei Emeltchenko static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, 40579eef6b3aSAndrei Emeltchenko struct sk_buff *skb) 40589eef6b3aSAndrei Emeltchenko { 40599eef6b3aSAndrei Emeltchenko struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data; 40609eef6b3aSAndrei Emeltchenko struct hci_conn *hcon; 40619eef6b3aSAndrei Emeltchenko 40629eef6b3aSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 40639eef6b3aSAndrei Emeltchenko 40649eef6b3aSAndrei Emeltchenko if (ev->status) 40659eef6b3aSAndrei Emeltchenko return; 40669eef6b3aSAndrei Emeltchenko 40679eef6b3aSAndrei Emeltchenko hci_dev_lock(hdev); 40689eef6b3aSAndrei Emeltchenko 40699eef6b3aSAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 40709eef6b3aSAndrei Emeltchenko if (hcon) { 40719eef6b3aSAndrei Emeltchenko hcon->state = BT_CLOSED; 40729eef6b3aSAndrei Emeltchenko hci_conn_del(hcon); 40739eef6b3aSAndrei Emeltchenko } 40749eef6b3aSAndrei Emeltchenko 40759eef6b3aSAndrei Emeltchenko hci_dev_unlock(hdev); 40769eef6b3aSAndrei Emeltchenko } 40779eef6b3aSAndrei Emeltchenko 40786039aa73SGustavo Padovan static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 4079fcd89c09SVille Tervo { 4080fcd89c09SVille Tervo struct hci_ev_le_conn_complete *ev = (void *) skb->data; 4081912b42efSJohan Hedberg struct hci_conn_params *params; 4082fcd89c09SVille Tervo struct hci_conn *conn; 408368d6f6deSJohan Hedberg struct smp_irk *irk; 4084837d502eSJohan Hedberg u8 addr_type; 4085fcd89c09SVille Tervo 40869f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 4087fcd89c09SVille Tervo 4088fcd89c09SVille Tervo hci_dev_lock(hdev); 4089fcd89c09SVille Tervo 40904f72b329SAndrzej Kaczmarek conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); 4091b62f328bSVille Tervo if (!conn) { 4092b62f328bSVille Tervo conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr); 4093b62f328bSVille Tervo if (!conn) { 4094b62f328bSVille Tervo BT_ERR("No memory for new connection"); 4095230fd16aSAndre Guedes goto unlock; 4096b62f328bSVille Tervo } 409729b7988aSAndre Guedes 409829b7988aSAndre Guedes conn->dst_type = ev->bdaddr_type; 4099b9b343d2SAndre Guedes 4100b9b343d2SAndre Guedes if (ev->role == LE_CONN_ROLE_MASTER) { 4101b9b343d2SAndre Guedes conn->out = true; 41024dae2798SJohan Hedberg set_bit(HCI_CONN_MASTER, &conn->flags); 4103b9b343d2SAndre Guedes } 4104cb1d68f7SJohan Hedberg 4105cb1d68f7SJohan Hedberg /* If we didn't have a hci_conn object previously 4106cb1d68f7SJohan Hedberg * but we're in master role this must be something 4107cb1d68f7SJohan Hedberg * initiated using a white list. Since white list based 4108cb1d68f7SJohan Hedberg * connections are not "first class citizens" we don't 4109cb1d68f7SJohan Hedberg * have full tracking of them. Therefore, we go ahead 4110cb1d68f7SJohan Hedberg * with a "best effort" approach of determining the 4111cb1d68f7SJohan Hedberg * initiator address based on the HCI_PRIVACY flag. 4112cb1d68f7SJohan Hedberg */ 4113cb1d68f7SJohan Hedberg if (conn->out) { 4114cb1d68f7SJohan Hedberg conn->resp_addr_type = ev->bdaddr_type; 4115cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &ev->bdaddr); 4116cb1d68f7SJohan Hedberg if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) { 4117cb1d68f7SJohan Hedberg conn->init_addr_type = ADDR_LE_DEV_RANDOM; 4118cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->rpa); 4119cb1d68f7SJohan Hedberg } else { 4120cb1d68f7SJohan Hedberg hci_copy_identity_address(hdev, 4121cb1d68f7SJohan Hedberg &conn->init_addr, 4122cb1d68f7SJohan Hedberg &conn->init_addr_type); 4123cb1d68f7SJohan Hedberg } 412480c24ab8SJohan Hedberg } 4125cb1d68f7SJohan Hedberg } else { 412680c24ab8SJohan Hedberg cancel_delayed_work(&conn->le_conn_timeout); 412780c24ab8SJohan Hedberg } 412880c24ab8SJohan Hedberg 412980c24ab8SJohan Hedberg if (!conn->out) { 4130cb1d68f7SJohan Hedberg /* Set the responder (our side) address type based on 4131cb1d68f7SJohan Hedberg * the advertising address type. 4132cb1d68f7SJohan Hedberg */ 4133cb1d68f7SJohan Hedberg conn->resp_addr_type = hdev->adv_addr_type; 4134cb1d68f7SJohan Hedberg if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) 4135cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &hdev->random_addr); 4136cb1d68f7SJohan Hedberg else 4137cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &hdev->bdaddr); 4138cb1d68f7SJohan Hedberg 4139cb1d68f7SJohan Hedberg conn->init_addr_type = ev->bdaddr_type; 4140cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &ev->bdaddr); 4141a720d735SMarcel Holtmann 4142a720d735SMarcel Holtmann /* For incoming connections, set the default minimum 4143a720d735SMarcel Holtmann * and maximum connection interval. They will be used 4144a720d735SMarcel Holtmann * to check if the parameters are in range and if not 4145a720d735SMarcel Holtmann * trigger the connection update procedure. 4146a720d735SMarcel Holtmann */ 4147a720d735SMarcel Holtmann conn->le_conn_min_interval = hdev->le_conn_min_interval; 4148a720d735SMarcel Holtmann conn->le_conn_max_interval = hdev->le_conn_max_interval; 4149cb1d68f7SJohan Hedberg } 41507be2edbbSJohan Hedberg 4151edb4b466SMarcel Holtmann /* Lookup the identity address from the stored connection 4152edb4b466SMarcel Holtmann * address and address type. 4153edb4b466SMarcel Holtmann * 4154edb4b466SMarcel Holtmann * When establishing connections to an identity address, the 4155edb4b466SMarcel Holtmann * connection procedure will store the resolvable random 4156edb4b466SMarcel Holtmann * address first. Now if it can be converted back into the 4157edb4b466SMarcel Holtmann * identity address, start using the identity address from 4158edb4b466SMarcel Holtmann * now on. 4159edb4b466SMarcel Holtmann */ 4160edb4b466SMarcel Holtmann irk = hci_get_irk(hdev, &conn->dst, conn->dst_type); 416168d6f6deSJohan Hedberg if (irk) { 416268d6f6deSJohan Hedberg bacpy(&conn->dst, &irk->bdaddr); 416368d6f6deSJohan Hedberg conn->dst_type = irk->addr_type; 416468d6f6deSJohan Hedberg } 416568d6f6deSJohan Hedberg 4166837d502eSJohan Hedberg if (conn->dst_type == ADDR_LE_DEV_PUBLIC) 4167837d502eSJohan Hedberg addr_type = BDADDR_LE_PUBLIC; 4168837d502eSJohan Hedberg else 4169837d502eSJohan Hedberg addr_type = BDADDR_LE_RANDOM; 4170837d502eSJohan Hedberg 4171837d502eSJohan Hedberg /* Drop the connection if he device is blocked */ 4172837d502eSJohan Hedberg if (hci_blacklist_lookup(hdev, &conn->dst, addr_type)) { 4173837d502eSJohan Hedberg hci_conn_drop(conn); 4174837d502eSJohan Hedberg goto unlock; 4175837d502eSJohan Hedberg } 4176837d502eSJohan Hedberg 4177cd17decbSAndre Guedes if (ev->status) { 417806c053fbSAndre Guedes hci_le_conn_failed(conn, ev->status); 4179cd17decbSAndre Guedes goto unlock; 4180cd17decbSAndre Guedes } 4181cd17decbSAndre Guedes 4182b644ba33SJohan Hedberg if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 418301fdb0fcSMarcel Holtmann mgmt_device_connected(hdev, &conn->dst, conn->type, 418495b23582SSzymon Janc conn->dst_type, 0, NULL, 0, NULL); 418583bc71b4SVinicius Costa Gomes 41867b5c0d52SVinicius Costa Gomes conn->sec_level = BT_SECURITY_LOW; 4187fcd89c09SVille Tervo conn->handle = __le16_to_cpu(ev->handle); 4188fcd89c09SVille Tervo conn->state = BT_CONNECTED; 4189fcd89c09SVille Tervo 4190e04fde60SMarcel Holtmann conn->le_conn_interval = le16_to_cpu(ev->interval); 4191e04fde60SMarcel Holtmann conn->le_conn_latency = le16_to_cpu(ev->latency); 4192e04fde60SMarcel Holtmann conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout); 4193e04fde60SMarcel Holtmann 4194fcd89c09SVille Tervo hci_conn_add_sysfs(conn); 4195fcd89c09SVille Tervo 4196fcd89c09SVille Tervo hci_proto_connect_cfm(conn, ev->status); 4197fcd89c09SVille Tervo 4198912b42efSJohan Hedberg params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); 4199223683a5SJohan Hedberg if (params) 420095305baaSJohan Hedberg list_del_init(¶ms->action); 4201a4790dbdSAndre Guedes 4202fcd89c09SVille Tervo unlock: 4203223683a5SJohan Hedberg hci_update_background_scan(hdev); 4204fcd89c09SVille Tervo hci_dev_unlock(hdev); 4205fcd89c09SVille Tervo } 4206fcd89c09SVille Tervo 42071855d92dSMarcel Holtmann static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, 42081855d92dSMarcel Holtmann struct sk_buff *skb) 42091855d92dSMarcel Holtmann { 42101855d92dSMarcel Holtmann struct hci_ev_le_conn_update_complete *ev = (void *) skb->data; 42111855d92dSMarcel Holtmann struct hci_conn *conn; 42121855d92dSMarcel Holtmann 42131855d92dSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 42141855d92dSMarcel Holtmann 42151855d92dSMarcel Holtmann if (ev->status) 42161855d92dSMarcel Holtmann return; 42171855d92dSMarcel Holtmann 42181855d92dSMarcel Holtmann hci_dev_lock(hdev); 42191855d92dSMarcel Holtmann 42201855d92dSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 42211855d92dSMarcel Holtmann if (conn) { 42221855d92dSMarcel Holtmann conn->le_conn_interval = le16_to_cpu(ev->interval); 42231855d92dSMarcel Holtmann conn->le_conn_latency = le16_to_cpu(ev->latency); 42241855d92dSMarcel Holtmann conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout); 42251855d92dSMarcel Holtmann } 42261855d92dSMarcel Holtmann 42271855d92dSMarcel Holtmann hci_dev_unlock(hdev); 42281855d92dSMarcel Holtmann } 42291855d92dSMarcel Holtmann 4230a4790dbdSAndre Guedes /* This function requires the caller holds hdev->lock */ 4231bb5ce4d0SJohan Hedberg static bool check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, 4232a4790dbdSAndre Guedes u8 addr_type) 4233a4790dbdSAndre Guedes { 4234a4790dbdSAndre Guedes struct hci_conn *conn; 4235a4790dbdSAndre Guedes 4236501f8827SJohan Hedberg if (!hci_pend_le_action_lookup(&hdev->pend_le_conns, addr, addr_type)) 4237bb5ce4d0SJohan Hedberg return false; 4238a4790dbdSAndre Guedes 4239a4790dbdSAndre Guedes conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, 424009ae260bSJohan Hedberg HCI_AT_NO_BONDING, HCI_LE_AUTOCONN_TIMEOUT); 4241a4790dbdSAndre Guedes if (!IS_ERR(conn)) 4242bb5ce4d0SJohan Hedberg return true; 4243a4790dbdSAndre Guedes 4244a4790dbdSAndre Guedes switch (PTR_ERR(conn)) { 4245a4790dbdSAndre Guedes case -EBUSY: 4246a4790dbdSAndre Guedes /* If hci_connect() returns -EBUSY it means there is already 4247a4790dbdSAndre Guedes * an LE connection attempt going on. Since controllers don't 4248a4790dbdSAndre Guedes * support more than one connection attempt at the time, we 4249a4790dbdSAndre Guedes * don't consider this an error case. 4250a4790dbdSAndre Guedes */ 4251a4790dbdSAndre Guedes break; 4252a4790dbdSAndre Guedes default: 4253a4790dbdSAndre Guedes BT_DBG("Failed to connect: err %ld", PTR_ERR(conn)); 4254a4790dbdSAndre Guedes } 4255bb5ce4d0SJohan Hedberg 4256bb5ce4d0SJohan Hedberg return true; 4257a4790dbdSAndre Guedes } 4258a4790dbdSAndre Guedes 42594af605d8SJohan Hedberg static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, 42604af605d8SJohan Hedberg u8 bdaddr_type, s8 rssi, u8 *data, u8 len) 42614af605d8SJohan Hedberg { 4262b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 4263474ee066SJohan Hedberg bool match; 4264c70a7e4cSMarcel Holtmann u32 flags; 4265b9a6328fSJohan Hedberg 42660d2bf134SJohan Hedberg /* Passive scanning shouldn't trigger any device found events, 42670d2bf134SJohan Hedberg * except for devices marked as CONN_REPORT for which we do send 42680d2bf134SJohan Hedberg * device found events. 42690d2bf134SJohan Hedberg */ 4270ca5c4be7SJohan Hedberg if (hdev->le_scan_type == LE_SCAN_PASSIVE) { 42710d2bf134SJohan Hedberg struct hci_conn_params *param; 4272079446c8SJohan Hedberg struct smp_irk *irk; 42730d2bf134SJohan Hedberg 4274435a13d8SJohan Hedberg /* Check if we need to convert to identity address */ 4275435a13d8SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, bdaddr_type); 4276435a13d8SJohan Hedberg if (irk) { 4277435a13d8SJohan Hedberg bdaddr = &irk->bdaddr; 4278435a13d8SJohan Hedberg bdaddr_type = irk->addr_type; 4279435a13d8SJohan Hedberg } 4280435a13d8SJohan Hedberg 428199a6768eSJohan Hedberg /* Ignore if the device is blocked */ 428299a6768eSJohan Hedberg if (hci_blacklist_lookup(hdev, bdaddr, bdaddr_type)) 428399a6768eSJohan Hedberg return; 428499a6768eSJohan Hedberg 4285bb5ce4d0SJohan Hedberg if (type == LE_ADV_IND || type == LE_ADV_DIRECT_IND) { 4286bb5ce4d0SJohan Hedberg if (check_pending_le_conn(hdev, bdaddr, bdaddr_type)) 4287bb5ce4d0SJohan Hedberg return; 4288bb5ce4d0SJohan Hedberg } 42890d2bf134SJohan Hedberg 42900d2bf134SJohan Hedberg if (type == LE_ADV_DIRECT_IND) 42910d2bf134SJohan Hedberg return; 42920d2bf134SJohan Hedberg 4293a7545f2aSJohan Hedberg param = hci_pend_le_action_lookup(&hdev->pend_le_reports, 4294a7545f2aSJohan Hedberg bdaddr, bdaddr_type); 4295a7545f2aSJohan Hedberg if (!param) 42960d2bf134SJohan Hedberg return; 42970d2bf134SJohan Hedberg 42980d2bf134SJohan Hedberg if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND) 42990d2bf134SJohan Hedberg flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 43000d2bf134SJohan Hedberg else 43010d2bf134SJohan Hedberg flags = 0; 43020d2bf134SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 43030d2bf134SJohan Hedberg rssi, flags, data, len, NULL, 0); 430497bf2e99SJohan Hedberg return; 4305ca5c4be7SJohan Hedberg } 43064af605d8SJohan Hedberg 4307c70a7e4cSMarcel Holtmann /* When receiving non-connectable or scannable undirected 4308c70a7e4cSMarcel Holtmann * advertising reports, this means that the remote device is 4309c70a7e4cSMarcel Holtmann * not connectable and then clearly indicate this in the 4310c70a7e4cSMarcel Holtmann * device found event. 4311c70a7e4cSMarcel Holtmann * 4312c70a7e4cSMarcel Holtmann * When receiving a scan response, then there is no way to 4313c70a7e4cSMarcel Holtmann * know if the remote device is connectable or not. However 4314c70a7e4cSMarcel Holtmann * since scan responses are merged with a previously seen 4315c70a7e4cSMarcel Holtmann * advertising report, the flags field from that report 4316c70a7e4cSMarcel Holtmann * will be used. 4317c70a7e4cSMarcel Holtmann * 4318c70a7e4cSMarcel Holtmann * In the really unlikely case that a controller get confused 4319c70a7e4cSMarcel Holtmann * and just sends a scan response event, then it is marked as 4320c70a7e4cSMarcel Holtmann * not connectable as well. 4321c70a7e4cSMarcel Holtmann */ 4322c70a7e4cSMarcel Holtmann if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND || 4323c70a7e4cSMarcel Holtmann type == LE_ADV_SCAN_RSP) 4324c70a7e4cSMarcel Holtmann flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 4325c70a7e4cSMarcel Holtmann else 4326c70a7e4cSMarcel Holtmann flags = 0; 4327c70a7e4cSMarcel Holtmann 4328b9a6328fSJohan Hedberg /* If there's nothing pending either store the data from this 4329b9a6328fSJohan Hedberg * event or send an immediate device found event if the data 4330b9a6328fSJohan Hedberg * should not be stored for later. 4331b9a6328fSJohan Hedberg */ 4332b9a6328fSJohan Hedberg if (!has_pending_adv_report(hdev)) { 4333b9a6328fSJohan Hedberg /* If the report will trigger a SCAN_REQ store it for 4334b9a6328fSJohan Hedberg * later merging. 4335b9a6328fSJohan Hedberg */ 4336b9a6328fSJohan Hedberg if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { 4337b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type, 4338c70a7e4cSMarcel Holtmann rssi, flags, data, len); 4339b9a6328fSJohan Hedberg return; 4340b9a6328fSJohan Hedberg } 4341b9a6328fSJohan Hedberg 4342b9a6328fSJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 4343c70a7e4cSMarcel Holtmann rssi, flags, data, len, NULL, 0); 4344b9a6328fSJohan Hedberg return; 4345b9a6328fSJohan Hedberg } 4346b9a6328fSJohan Hedberg 4347474ee066SJohan Hedberg /* Check if the pending report is for the same device as the new one */ 4348474ee066SJohan Hedberg match = (!bacmp(bdaddr, &d->last_adv_addr) && 4349474ee066SJohan Hedberg bdaddr_type == d->last_adv_addr_type); 4350474ee066SJohan Hedberg 4351b9a6328fSJohan Hedberg /* If the pending data doesn't match this report or this isn't a 4352b9a6328fSJohan Hedberg * scan response (e.g. we got a duplicate ADV_IND) then force 4353b9a6328fSJohan Hedberg * sending of the pending data. 4354b9a6328fSJohan Hedberg */ 4355474ee066SJohan Hedberg if (type != LE_ADV_SCAN_RSP || !match) { 4356474ee066SJohan Hedberg /* Send out whatever is in the cache, but skip duplicates */ 4357474ee066SJohan Hedberg if (!match) 4358b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 4359ff5cd29fSJohan Hedberg d->last_adv_addr_type, NULL, 4360c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags, 4361ff5cd29fSJohan Hedberg d->last_adv_data, 4362474ee066SJohan Hedberg d->last_adv_data_len, NULL, 0); 4363b9a6328fSJohan Hedberg 4364b9a6328fSJohan Hedberg /* If the new report will trigger a SCAN_REQ store it for 4365b9a6328fSJohan Hedberg * later merging. 4366b9a6328fSJohan Hedberg */ 4367b9a6328fSJohan Hedberg if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { 4368b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type, 4369c70a7e4cSMarcel Holtmann rssi, flags, data, len); 4370b9a6328fSJohan Hedberg return; 4371b9a6328fSJohan Hedberg } 4372b9a6328fSJohan Hedberg 4373b9a6328fSJohan Hedberg /* The advertising reports cannot be merged, so clear 4374b9a6328fSJohan Hedberg * the pending report and send out a device found event. 4375b9a6328fSJohan Hedberg */ 4376b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 43775c5b93e4SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 4378c70a7e4cSMarcel Holtmann rssi, flags, data, len, NULL, 0); 4379b9a6328fSJohan Hedberg return; 4380b9a6328fSJohan Hedberg } 4381b9a6328fSJohan Hedberg 4382b9a6328fSJohan Hedberg /* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and 4383b9a6328fSJohan Hedberg * the new event is a SCAN_RSP. We can therefore proceed with 4384b9a6328fSJohan Hedberg * sending a merged device found event. 4385b9a6328fSJohan Hedberg */ 4386b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 4387c70a7e4cSMarcel Holtmann d->last_adv_addr_type, NULL, rssi, d->last_adv_flags, 438842bd6a56SMarcel Holtmann d->last_adv_data, d->last_adv_data_len, data, len); 4389b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 43904af605d8SJohan Hedberg } 43914af605d8SJohan Hedberg 43926039aa73SGustavo Padovan static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) 43939aa04c91SAndre Guedes { 4394e95beb41SAndre Guedes u8 num_reports = skb->data[0]; 4395e95beb41SAndre Guedes void *ptr = &skb->data[1]; 43969aa04c91SAndre Guedes 4397a4790dbdSAndre Guedes hci_dev_lock(hdev); 4398a4790dbdSAndre Guedes 4399e95beb41SAndre Guedes while (num_reports--) { 4400e95beb41SAndre Guedes struct hci_ev_le_advertising_info *ev = ptr; 44014af605d8SJohan Hedberg s8 rssi; 4402a4790dbdSAndre Guedes 44033c9e9195SAndre Guedes rssi = ev->data[ev->length]; 44044af605d8SJohan Hedberg process_adv_report(hdev, ev->evt_type, &ev->bdaddr, 44054af605d8SJohan Hedberg ev->bdaddr_type, rssi, ev->data, ev->length); 44063c9e9195SAndre Guedes 4407e95beb41SAndre Guedes ptr += sizeof(*ev) + ev->length + 1; 44089aa04c91SAndre Guedes } 4409a4790dbdSAndre Guedes 4410a4790dbdSAndre Guedes hci_dev_unlock(hdev); 44119aa04c91SAndre Guedes } 44129aa04c91SAndre Guedes 44136039aa73SGustavo Padovan static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 4414a7a595f6SVinicius Costa Gomes { 4415a7a595f6SVinicius Costa Gomes struct hci_ev_le_ltk_req *ev = (void *) skb->data; 4416a7a595f6SVinicius Costa Gomes struct hci_cp_le_ltk_reply cp; 4417bea710feSVinicius Costa Gomes struct hci_cp_le_ltk_neg_reply neg; 4418a7a595f6SVinicius Costa Gomes struct hci_conn *conn; 4419c9839a11SVinicius Costa Gomes struct smp_ltk *ltk; 4420a7a595f6SVinicius Costa Gomes 44219f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle)); 4422a7a595f6SVinicius Costa Gomes 4423a7a595f6SVinicius Costa Gomes hci_dev_lock(hdev); 4424a7a595f6SVinicius Costa Gomes 4425a7a595f6SVinicius Costa Gomes conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 4426bea710feSVinicius Costa Gomes if (conn == NULL) 4427bea710feSVinicius Costa Gomes goto not_found; 4428a7a595f6SVinicius Costa Gomes 4429fe39c7b2SMarcel Holtmann ltk = hci_find_ltk(hdev, ev->ediv, ev->rand, conn->out); 4430bea710feSVinicius Costa Gomes if (ltk == NULL) 4431bea710feSVinicius Costa Gomes goto not_found; 4432bea710feSVinicius Costa Gomes 4433bea710feSVinicius Costa Gomes memcpy(cp.ltk, ltk->val, sizeof(ltk->val)); 4434a7a595f6SVinicius Costa Gomes cp.handle = cpu_to_le16(conn->handle); 4435c9839a11SVinicius Costa Gomes 4436c9839a11SVinicius Costa Gomes if (ltk->authenticated) 4437f8776218SAndre Guedes conn->pending_sec_level = BT_SECURITY_HIGH; 4438f8776218SAndre Guedes else 4439f8776218SAndre Guedes conn->pending_sec_level = BT_SECURITY_MEDIUM; 4440a7a595f6SVinicius Costa Gomes 444189cbb4daSAndre Guedes conn->enc_key_size = ltk->enc_size; 4442a7a595f6SVinicius Costa Gomes 4443a7a595f6SVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); 4444a7a595f6SVinicius Costa Gomes 44455981a882SClaudio Takahasi /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a 44465981a882SClaudio Takahasi * temporary key used to encrypt a connection following 44475981a882SClaudio Takahasi * pairing. It is used during the Encrypted Session Setup to 44485981a882SClaudio Takahasi * distribute the keys. Later, security can be re-established 44495981a882SClaudio Takahasi * using a distributed LTK. 44505981a882SClaudio Takahasi */ 44512ceba539SJohan Hedberg if (ltk->type == SMP_STK) { 4452fe59a05fSJohan Hedberg set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); 4453c9839a11SVinicius Costa Gomes list_del(<k->list); 4454c9839a11SVinicius Costa Gomes kfree(ltk); 4455fe59a05fSJohan Hedberg } else { 4456fe59a05fSJohan Hedberg clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); 4457c9839a11SVinicius Costa Gomes } 4458c9839a11SVinicius Costa Gomes 4459a7a595f6SVinicius Costa Gomes hci_dev_unlock(hdev); 4460bea710feSVinicius Costa Gomes 4461bea710feSVinicius Costa Gomes return; 4462bea710feSVinicius Costa Gomes 4463bea710feSVinicius Costa Gomes not_found: 4464bea710feSVinicius Costa Gomes neg.handle = ev->handle; 4465bea710feSVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg); 4466bea710feSVinicius Costa Gomes hci_dev_unlock(hdev); 4467a7a595f6SVinicius Costa Gomes } 4468a7a595f6SVinicius Costa Gomes 44698e75b46aSAndre Guedes static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle, 44708e75b46aSAndre Guedes u8 reason) 44718e75b46aSAndre Guedes { 44728e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_neg_reply cp; 44738e75b46aSAndre Guedes 44748e75b46aSAndre Guedes cp.handle = cpu_to_le16(handle); 44758e75b46aSAndre Guedes cp.reason = reason; 44768e75b46aSAndre Guedes 44778e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp), 44788e75b46aSAndre Guedes &cp); 44798e75b46aSAndre Guedes } 44808e75b46aSAndre Guedes 44818e75b46aSAndre Guedes static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, 44828e75b46aSAndre Guedes struct sk_buff *skb) 44838e75b46aSAndre Guedes { 44848e75b46aSAndre Guedes struct hci_ev_le_remote_conn_param_req *ev = (void *) skb->data; 44858e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_reply cp; 44868e75b46aSAndre Guedes struct hci_conn *hcon; 44878e75b46aSAndre Guedes u16 handle, min, max, latency, timeout; 44888e75b46aSAndre Guedes 44898e75b46aSAndre Guedes handle = le16_to_cpu(ev->handle); 44908e75b46aSAndre Guedes min = le16_to_cpu(ev->interval_min); 44918e75b46aSAndre Guedes max = le16_to_cpu(ev->interval_max); 44928e75b46aSAndre Guedes latency = le16_to_cpu(ev->latency); 44938e75b46aSAndre Guedes timeout = le16_to_cpu(ev->timeout); 44948e75b46aSAndre Guedes 44958e75b46aSAndre Guedes hcon = hci_conn_hash_lookup_handle(hdev, handle); 44968e75b46aSAndre Guedes if (!hcon || hcon->state != BT_CONNECTED) 44978e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle, 44988e75b46aSAndre Guedes HCI_ERROR_UNKNOWN_CONN_ID); 44998e75b46aSAndre Guedes 45008e75b46aSAndre Guedes if (hci_check_conn_params(min, max, latency, timeout)) 45018e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle, 45028e75b46aSAndre Guedes HCI_ERROR_INVALID_LL_PARAMS); 45038e75b46aSAndre Guedes 4504348d50b8SJohan Hedberg if (test_bit(HCI_CONN_MASTER, &hcon->flags)) { 4505348d50b8SJohan Hedberg struct hci_conn_params *params; 4506f4869e2aSJohan Hedberg u8 store_hint; 4507348d50b8SJohan Hedberg 4508348d50b8SJohan Hedberg hci_dev_lock(hdev); 4509348d50b8SJohan Hedberg 4510348d50b8SJohan Hedberg params = hci_conn_params_lookup(hdev, &hcon->dst, 4511348d50b8SJohan Hedberg hcon->dst_type); 4512348d50b8SJohan Hedberg if (params) { 4513348d50b8SJohan Hedberg params->conn_min_interval = min; 4514348d50b8SJohan Hedberg params->conn_max_interval = max; 4515348d50b8SJohan Hedberg params->conn_latency = latency; 4516348d50b8SJohan Hedberg params->supervision_timeout = timeout; 4517f4869e2aSJohan Hedberg store_hint = 0x01; 4518f4869e2aSJohan Hedberg } else{ 4519f4869e2aSJohan Hedberg store_hint = 0x00; 4520348d50b8SJohan Hedberg } 4521348d50b8SJohan Hedberg 4522348d50b8SJohan Hedberg hci_dev_unlock(hdev); 4523348d50b8SJohan Hedberg 4524f4869e2aSJohan Hedberg mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type, 4525f4869e2aSJohan Hedberg store_hint, min, max, latency, timeout); 4526348d50b8SJohan Hedberg } 4527ffb5a827SAndre Guedes 45288e75b46aSAndre Guedes cp.handle = ev->handle; 45298e75b46aSAndre Guedes cp.interval_min = ev->interval_min; 45308e75b46aSAndre Guedes cp.interval_max = ev->interval_max; 45318e75b46aSAndre Guedes cp.latency = ev->latency; 45328e75b46aSAndre Guedes cp.timeout = ev->timeout; 45338e75b46aSAndre Guedes cp.min_ce_len = 0; 45348e75b46aSAndre Guedes cp.max_ce_len = 0; 45358e75b46aSAndre Guedes 45368e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp); 45378e75b46aSAndre Guedes } 45388e75b46aSAndre Guedes 45396039aa73SGustavo Padovan static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) 4540fcd89c09SVille Tervo { 4541fcd89c09SVille Tervo struct hci_ev_le_meta *le_ev = (void *) skb->data; 4542fcd89c09SVille Tervo 4543fcd89c09SVille Tervo skb_pull(skb, sizeof(*le_ev)); 4544fcd89c09SVille Tervo 4545fcd89c09SVille Tervo switch (le_ev->subevent) { 4546fcd89c09SVille Tervo case HCI_EV_LE_CONN_COMPLETE: 4547fcd89c09SVille Tervo hci_le_conn_complete_evt(hdev, skb); 4548fcd89c09SVille Tervo break; 4549fcd89c09SVille Tervo 45501855d92dSMarcel Holtmann case HCI_EV_LE_CONN_UPDATE_COMPLETE: 45511855d92dSMarcel Holtmann hci_le_conn_update_complete_evt(hdev, skb); 45521855d92dSMarcel Holtmann break; 45531855d92dSMarcel Holtmann 45549aa04c91SAndre Guedes case HCI_EV_LE_ADVERTISING_REPORT: 45559aa04c91SAndre Guedes hci_le_adv_report_evt(hdev, skb); 45569aa04c91SAndre Guedes break; 45579aa04c91SAndre Guedes 4558a7a595f6SVinicius Costa Gomes case HCI_EV_LE_LTK_REQ: 4559a7a595f6SVinicius Costa Gomes hci_le_ltk_request_evt(hdev, skb); 4560a7a595f6SVinicius Costa Gomes break; 4561a7a595f6SVinicius Costa Gomes 45628e75b46aSAndre Guedes case HCI_EV_LE_REMOTE_CONN_PARAM_REQ: 45638e75b46aSAndre Guedes hci_le_remote_conn_param_req_evt(hdev, skb); 45648e75b46aSAndre Guedes break; 45658e75b46aSAndre Guedes 4566fcd89c09SVille Tervo default: 4567fcd89c09SVille Tervo break; 4568fcd89c09SVille Tervo } 4569fcd89c09SVille Tervo } 4570fcd89c09SVille Tervo 45719495b2eeSAndrei Emeltchenko static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb) 45729495b2eeSAndrei Emeltchenko { 45739495b2eeSAndrei Emeltchenko struct hci_ev_channel_selected *ev = (void *) skb->data; 45749495b2eeSAndrei Emeltchenko struct hci_conn *hcon; 45759495b2eeSAndrei Emeltchenko 45769495b2eeSAndrei Emeltchenko BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle); 45779495b2eeSAndrei Emeltchenko 45789495b2eeSAndrei Emeltchenko skb_pull(skb, sizeof(*ev)); 45799495b2eeSAndrei Emeltchenko 45809495b2eeSAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 45819495b2eeSAndrei Emeltchenko if (!hcon) 45829495b2eeSAndrei Emeltchenko return; 45839495b2eeSAndrei Emeltchenko 45849495b2eeSAndrei Emeltchenko amp_read_loc_assoc_final_data(hdev, hcon); 45859495b2eeSAndrei Emeltchenko } 45869495b2eeSAndrei Emeltchenko 45871da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) 45881da177e4SLinus Torvalds { 4589a9de9248SMarcel Holtmann struct hci_event_hdr *hdr = (void *) skb->data; 4590a9de9248SMarcel Holtmann __u8 event = hdr->evt; 45911da177e4SLinus Torvalds 4592b6ddb638SJohan Hedberg hci_dev_lock(hdev); 4593b6ddb638SJohan Hedberg 4594b6ddb638SJohan Hedberg /* Received events are (currently) only needed when a request is 4595b6ddb638SJohan Hedberg * ongoing so avoid unnecessary memory allocation. 4596b6ddb638SJohan Hedberg */ 4597b6ddb638SJohan Hedberg if (hdev->req_status == HCI_REQ_PEND) { 4598b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 4599b6ddb638SJohan Hedberg hdev->recv_evt = skb_clone(skb, GFP_KERNEL); 4600b6ddb638SJohan Hedberg } 4601b6ddb638SJohan Hedberg 4602b6ddb638SJohan Hedberg hci_dev_unlock(hdev); 4603b6ddb638SJohan Hedberg 46041da177e4SLinus Torvalds skb_pull(skb, HCI_EVENT_HDR_SIZE); 46051da177e4SLinus Torvalds 460602350a72SJohan Hedberg if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) { 4607c1f23a2bSJohannes Berg struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data; 4608c1f23a2bSJohannes Berg u16 opcode = __le16_to_cpu(cmd_hdr->opcode); 460902350a72SJohan Hedberg 461002350a72SJohan Hedberg hci_req_cmd_complete(hdev, opcode, 0); 461102350a72SJohan Hedberg } 461202350a72SJohan Hedberg 4613a9de9248SMarcel Holtmann switch (event) { 46141da177e4SLinus Torvalds case HCI_EV_INQUIRY_COMPLETE: 46151da177e4SLinus Torvalds hci_inquiry_complete_evt(hdev, skb); 46161da177e4SLinus Torvalds break; 46171da177e4SLinus Torvalds 46181da177e4SLinus Torvalds case HCI_EV_INQUIRY_RESULT: 46191da177e4SLinus Torvalds hci_inquiry_result_evt(hdev, skb); 46201da177e4SLinus Torvalds break; 46211da177e4SLinus Torvalds 4622a9de9248SMarcel Holtmann case HCI_EV_CONN_COMPLETE: 4623a9de9248SMarcel Holtmann hci_conn_complete_evt(hdev, skb); 462421d9e30eSMarcel Holtmann break; 462521d9e30eSMarcel Holtmann 46261da177e4SLinus Torvalds case HCI_EV_CONN_REQUEST: 46271da177e4SLinus Torvalds hci_conn_request_evt(hdev, skb); 46281da177e4SLinus Torvalds break; 46291da177e4SLinus Torvalds 46301da177e4SLinus Torvalds case HCI_EV_DISCONN_COMPLETE: 46311da177e4SLinus Torvalds hci_disconn_complete_evt(hdev, skb); 46321da177e4SLinus Torvalds break; 46331da177e4SLinus Torvalds 46341da177e4SLinus Torvalds case HCI_EV_AUTH_COMPLETE: 46351da177e4SLinus Torvalds hci_auth_complete_evt(hdev, skb); 46361da177e4SLinus Torvalds break; 46371da177e4SLinus Torvalds 4638a9de9248SMarcel Holtmann case HCI_EV_REMOTE_NAME: 4639a9de9248SMarcel Holtmann hci_remote_name_evt(hdev, skb); 4640a9de9248SMarcel Holtmann break; 4641a9de9248SMarcel Holtmann 46421da177e4SLinus Torvalds case HCI_EV_ENCRYPT_CHANGE: 46431da177e4SLinus Torvalds hci_encrypt_change_evt(hdev, skb); 46441da177e4SLinus Torvalds break; 46451da177e4SLinus Torvalds 4646a9de9248SMarcel Holtmann case HCI_EV_CHANGE_LINK_KEY_COMPLETE: 4647a9de9248SMarcel Holtmann hci_change_link_key_complete_evt(hdev, skb); 4648a9de9248SMarcel Holtmann break; 4649a9de9248SMarcel Holtmann 4650a9de9248SMarcel Holtmann case HCI_EV_REMOTE_FEATURES: 4651a9de9248SMarcel Holtmann hci_remote_features_evt(hdev, skb); 4652a9de9248SMarcel Holtmann break; 4653a9de9248SMarcel Holtmann 4654a9de9248SMarcel Holtmann case HCI_EV_CMD_COMPLETE: 4655a9de9248SMarcel Holtmann hci_cmd_complete_evt(hdev, skb); 4656a9de9248SMarcel Holtmann break; 4657a9de9248SMarcel Holtmann 4658a9de9248SMarcel Holtmann case HCI_EV_CMD_STATUS: 4659a9de9248SMarcel Holtmann hci_cmd_status_evt(hdev, skb); 4660a9de9248SMarcel Holtmann break; 4661a9de9248SMarcel Holtmann 4662a9de9248SMarcel Holtmann case HCI_EV_ROLE_CHANGE: 4663a9de9248SMarcel Holtmann hci_role_change_evt(hdev, skb); 4664a9de9248SMarcel Holtmann break; 4665a9de9248SMarcel Holtmann 4666a9de9248SMarcel Holtmann case HCI_EV_NUM_COMP_PKTS: 4667a9de9248SMarcel Holtmann hci_num_comp_pkts_evt(hdev, skb); 4668a9de9248SMarcel Holtmann break; 4669a9de9248SMarcel Holtmann 4670a9de9248SMarcel Holtmann case HCI_EV_MODE_CHANGE: 4671a9de9248SMarcel Holtmann hci_mode_change_evt(hdev, skb); 46721da177e4SLinus Torvalds break; 46731da177e4SLinus Torvalds 46741da177e4SLinus Torvalds case HCI_EV_PIN_CODE_REQ: 46751da177e4SLinus Torvalds hci_pin_code_request_evt(hdev, skb); 46761da177e4SLinus Torvalds break; 46771da177e4SLinus Torvalds 46781da177e4SLinus Torvalds case HCI_EV_LINK_KEY_REQ: 46791da177e4SLinus Torvalds hci_link_key_request_evt(hdev, skb); 46801da177e4SLinus Torvalds break; 46811da177e4SLinus Torvalds 46821da177e4SLinus Torvalds case HCI_EV_LINK_KEY_NOTIFY: 46831da177e4SLinus Torvalds hci_link_key_notify_evt(hdev, skb); 46841da177e4SLinus Torvalds break; 46851da177e4SLinus Torvalds 46861da177e4SLinus Torvalds case HCI_EV_CLOCK_OFFSET: 46871da177e4SLinus Torvalds hci_clock_offset_evt(hdev, skb); 46881da177e4SLinus Torvalds break; 46891da177e4SLinus Torvalds 4690a8746417SMarcel Holtmann case HCI_EV_PKT_TYPE_CHANGE: 4691a8746417SMarcel Holtmann hci_pkt_type_change_evt(hdev, skb); 4692a8746417SMarcel Holtmann break; 4693a8746417SMarcel Holtmann 469485a1e930SMarcel Holtmann case HCI_EV_PSCAN_REP_MODE: 469585a1e930SMarcel Holtmann hci_pscan_rep_mode_evt(hdev, skb); 469685a1e930SMarcel Holtmann break; 469785a1e930SMarcel Holtmann 4698a9de9248SMarcel Holtmann case HCI_EV_INQUIRY_RESULT_WITH_RSSI: 4699a9de9248SMarcel Holtmann hci_inquiry_result_with_rssi_evt(hdev, skb); 4700a9de9248SMarcel Holtmann break; 4701a9de9248SMarcel Holtmann 4702a9de9248SMarcel Holtmann case HCI_EV_REMOTE_EXT_FEATURES: 4703a9de9248SMarcel Holtmann hci_remote_ext_features_evt(hdev, skb); 4704a9de9248SMarcel Holtmann break; 4705a9de9248SMarcel Holtmann 4706a9de9248SMarcel Holtmann case HCI_EV_SYNC_CONN_COMPLETE: 4707a9de9248SMarcel Holtmann hci_sync_conn_complete_evt(hdev, skb); 4708a9de9248SMarcel Holtmann break; 4709a9de9248SMarcel Holtmann 4710a9de9248SMarcel Holtmann case HCI_EV_EXTENDED_INQUIRY_RESULT: 4711a9de9248SMarcel Holtmann hci_extended_inquiry_result_evt(hdev, skb); 47121da177e4SLinus Torvalds break; 47131da177e4SLinus Torvalds 47141c2e0041SJohan Hedberg case HCI_EV_KEY_REFRESH_COMPLETE: 47151c2e0041SJohan Hedberg hci_key_refresh_complete_evt(hdev, skb); 47161c2e0041SJohan Hedberg break; 47171c2e0041SJohan Hedberg 47180493684eSMarcel Holtmann case HCI_EV_IO_CAPA_REQUEST: 47190493684eSMarcel Holtmann hci_io_capa_request_evt(hdev, skb); 47200493684eSMarcel Holtmann break; 47210493684eSMarcel Holtmann 472203b555e1SJohan Hedberg case HCI_EV_IO_CAPA_REPLY: 472303b555e1SJohan Hedberg hci_io_capa_reply_evt(hdev, skb); 472403b555e1SJohan Hedberg break; 472503b555e1SJohan Hedberg 4726a5c29683SJohan Hedberg case HCI_EV_USER_CONFIRM_REQUEST: 4727a5c29683SJohan Hedberg hci_user_confirm_request_evt(hdev, skb); 4728a5c29683SJohan Hedberg break; 4729a5c29683SJohan Hedberg 47301143d458SBrian Gix case HCI_EV_USER_PASSKEY_REQUEST: 47311143d458SBrian Gix hci_user_passkey_request_evt(hdev, skb); 47321143d458SBrian Gix break; 47331143d458SBrian Gix 473492a25256SJohan Hedberg case HCI_EV_USER_PASSKEY_NOTIFY: 473592a25256SJohan Hedberg hci_user_passkey_notify_evt(hdev, skb); 473692a25256SJohan Hedberg break; 473792a25256SJohan Hedberg 473892a25256SJohan Hedberg case HCI_EV_KEYPRESS_NOTIFY: 473992a25256SJohan Hedberg hci_keypress_notify_evt(hdev, skb); 474092a25256SJohan Hedberg break; 474192a25256SJohan Hedberg 47420493684eSMarcel Holtmann case HCI_EV_SIMPLE_PAIR_COMPLETE: 47430493684eSMarcel Holtmann hci_simple_pair_complete_evt(hdev, skb); 47440493684eSMarcel Holtmann break; 47450493684eSMarcel Holtmann 474641a96212SMarcel Holtmann case HCI_EV_REMOTE_HOST_FEATURES: 474741a96212SMarcel Holtmann hci_remote_host_features_evt(hdev, skb); 474841a96212SMarcel Holtmann break; 474941a96212SMarcel Holtmann 4750fcd89c09SVille Tervo case HCI_EV_LE_META: 4751fcd89c09SVille Tervo hci_le_meta_evt(hdev, skb); 4752fcd89c09SVille Tervo break; 4753fcd89c09SVille Tervo 47549495b2eeSAndrei Emeltchenko case HCI_EV_CHANNEL_SELECTED: 47559495b2eeSAndrei Emeltchenko hci_chan_selected_evt(hdev, skb); 47569495b2eeSAndrei Emeltchenko break; 47579495b2eeSAndrei Emeltchenko 47582763eda6SSzymon Janc case HCI_EV_REMOTE_OOB_DATA_REQUEST: 47592763eda6SSzymon Janc hci_remote_oob_data_request_evt(hdev, skb); 47602763eda6SSzymon Janc break; 47612763eda6SSzymon Janc 4762d5e91192SAndrei Emeltchenko case HCI_EV_PHY_LINK_COMPLETE: 4763d5e91192SAndrei Emeltchenko hci_phy_link_complete_evt(hdev, skb); 4764d5e91192SAndrei Emeltchenko break; 4765d5e91192SAndrei Emeltchenko 476627695fb4SAndrei Emeltchenko case HCI_EV_LOGICAL_LINK_COMPLETE: 476727695fb4SAndrei Emeltchenko hci_loglink_complete_evt(hdev, skb); 476827695fb4SAndrei Emeltchenko break; 476927695fb4SAndrei Emeltchenko 4770606e2a10SAndrei Emeltchenko case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE: 4771606e2a10SAndrei Emeltchenko hci_disconn_loglink_complete_evt(hdev, skb); 4772606e2a10SAndrei Emeltchenko break; 4773606e2a10SAndrei Emeltchenko 47749eef6b3aSAndrei Emeltchenko case HCI_EV_DISCONN_PHY_LINK_COMPLETE: 47759eef6b3aSAndrei Emeltchenko hci_disconn_phylink_complete_evt(hdev, skb); 47769eef6b3aSAndrei Emeltchenko break; 47779eef6b3aSAndrei Emeltchenko 477825e89e99SAndrei Emeltchenko case HCI_EV_NUM_COMP_BLOCKS: 477925e89e99SAndrei Emeltchenko hci_num_comp_blocks_evt(hdev, skb); 478025e89e99SAndrei Emeltchenko break; 478125e89e99SAndrei Emeltchenko 47821da177e4SLinus Torvalds default: 47839f1db00cSAndrei Emeltchenko BT_DBG("%s event 0x%2.2x", hdev->name, event); 47841da177e4SLinus Torvalds break; 47851da177e4SLinus Torvalds } 47861da177e4SLinus Torvalds 47871da177e4SLinus Torvalds kfree_skb(skb); 47881da177e4SLinus Torvalds hdev->stat.evt_rx++; 47891da177e4SLinus Torvalds } 4790