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)); 10440bef302SJohan Hedberg if (conn) 10540bef302SJohan Hedberg conn->role = rp->role; 1061da177e4SLinus Torvalds 1071da177e4SLinus Torvalds hci_dev_unlock(hdev); 108a9de9248SMarcel Holtmann } 1091da177e4SLinus Torvalds 110e4e8e37cSMarcel Holtmann static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 111e4e8e37cSMarcel Holtmann { 112e4e8e37cSMarcel Holtmann struct hci_rp_read_link_policy *rp = (void *) skb->data; 113e4e8e37cSMarcel Holtmann struct hci_conn *conn; 114e4e8e37cSMarcel Holtmann 1159f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 116e4e8e37cSMarcel Holtmann 117e4e8e37cSMarcel Holtmann if (rp->status) 118e4e8e37cSMarcel Holtmann return; 119e4e8e37cSMarcel Holtmann 120e4e8e37cSMarcel Holtmann hci_dev_lock(hdev); 121e4e8e37cSMarcel Holtmann 122e4e8e37cSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 123e4e8e37cSMarcel Holtmann if (conn) 124e4e8e37cSMarcel Holtmann conn->link_policy = __le16_to_cpu(rp->policy); 125e4e8e37cSMarcel Holtmann 126e4e8e37cSMarcel Holtmann hci_dev_unlock(hdev); 127e4e8e37cSMarcel Holtmann } 128e4e8e37cSMarcel Holtmann 129a9de9248SMarcel Holtmann static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 130a9de9248SMarcel Holtmann { 131a9de9248SMarcel Holtmann struct hci_rp_write_link_policy *rp = (void *) skb->data; 132a9de9248SMarcel Holtmann struct hci_conn *conn; 133a9de9248SMarcel Holtmann void *sent; 134a9de9248SMarcel Holtmann 1359f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 136a9de9248SMarcel Holtmann 137a9de9248SMarcel Holtmann if (rp->status) 138a9de9248SMarcel Holtmann return; 139a9de9248SMarcel Holtmann 140a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY); 14104837f64SMarcel Holtmann if (!sent) 142a9de9248SMarcel Holtmann return; 14304837f64SMarcel Holtmann 14404837f64SMarcel Holtmann hci_dev_lock(hdev); 14504837f64SMarcel Holtmann 146a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 147e4e8e37cSMarcel Holtmann if (conn) 14883985319SHarvey Harrison conn->link_policy = get_unaligned_le16(sent + 2); 14904837f64SMarcel Holtmann 15004837f64SMarcel Holtmann hci_dev_unlock(hdev); 1511da177e4SLinus Torvalds } 1521da177e4SLinus Torvalds 153807deac2SGustavo Padovan static void hci_cc_read_def_link_policy(struct hci_dev *hdev, 154807deac2SGustavo Padovan struct sk_buff *skb) 155e4e8e37cSMarcel Holtmann { 156e4e8e37cSMarcel Holtmann struct hci_rp_read_def_link_policy *rp = (void *) skb->data; 157e4e8e37cSMarcel Holtmann 1589f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 159e4e8e37cSMarcel Holtmann 160e4e8e37cSMarcel Holtmann if (rp->status) 161e4e8e37cSMarcel Holtmann return; 162e4e8e37cSMarcel Holtmann 163e4e8e37cSMarcel Holtmann hdev->link_policy = __le16_to_cpu(rp->policy); 164e4e8e37cSMarcel Holtmann } 165e4e8e37cSMarcel Holtmann 166807deac2SGustavo Padovan static void hci_cc_write_def_link_policy(struct hci_dev *hdev, 167807deac2SGustavo Padovan struct sk_buff *skb) 168e4e8e37cSMarcel Holtmann { 169e4e8e37cSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 170e4e8e37cSMarcel Holtmann void *sent; 171e4e8e37cSMarcel Holtmann 1729f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 173e4e8e37cSMarcel Holtmann 17445296acdSMarcel Holtmann if (status) 17545296acdSMarcel Holtmann return; 17645296acdSMarcel Holtmann 177e4e8e37cSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY); 178e4e8e37cSMarcel Holtmann if (!sent) 179e4e8e37cSMarcel Holtmann return; 180e4e8e37cSMarcel Holtmann 181e4e8e37cSMarcel Holtmann hdev->link_policy = get_unaligned_le16(sent); 182e4e8e37cSMarcel Holtmann } 183e4e8e37cSMarcel Holtmann 184a9de9248SMarcel Holtmann static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) 1851da177e4SLinus Torvalds { 186a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 187a9de9248SMarcel Holtmann 1889f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 189a9de9248SMarcel Holtmann 19010572132SGustavo F. Padovan clear_bit(HCI_RESET, &hdev->flags); 19110572132SGustavo F. Padovan 1928761f9d6SMarcel Holtmann if (status) 1938761f9d6SMarcel Holtmann return; 1948761f9d6SMarcel Holtmann 195a297e97cSJohan Hedberg /* Reset all non-persistent flags */ 1962cc6fb00SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 19769775ff6SAndre Guedes 19869775ff6SAndre Guedes hdev->discovery.state = DISCOVERY_STOPPED; 199bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 200bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 2013f0f524bSJohan Hedberg 2023f0f524bSJohan Hedberg memset(hdev->adv_data, 0, sizeof(hdev->adv_data)); 2033f0f524bSJohan Hedberg hdev->adv_data_len = 0; 204f8e808bdSMarcel Holtmann 205f8e808bdSMarcel Holtmann memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data)); 206f8e808bdSMarcel Holtmann hdev->scan_rsp_data_len = 0; 20706f5b778SMarcel Holtmann 208533553f8SMarcel Holtmann hdev->le_scan_type = LE_SCAN_PASSIVE; 209533553f8SMarcel Holtmann 21006f5b778SMarcel Holtmann hdev->ssp_debug_mode = 0; 211a4d5504dSMarcel Holtmann 212a4d5504dSMarcel Holtmann hci_bdaddr_list_clear(&hdev->le_white_list); 213a9de9248SMarcel Holtmann } 214a9de9248SMarcel Holtmann 215a9de9248SMarcel Holtmann static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) 216a9de9248SMarcel Holtmann { 217a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 2181da177e4SLinus Torvalds void *sent; 2191da177e4SLinus Torvalds 2209f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 2211da177e4SLinus Torvalds 222a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME); 2231da177e4SLinus Torvalds if (!sent) 224a9de9248SMarcel Holtmann return; 2251da177e4SLinus Torvalds 22656e5cb86SJohan Hedberg hci_dev_lock(hdev); 22756e5cb86SJohan Hedberg 228f51d5b24SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 229f51d5b24SJohan Hedberg mgmt_set_local_name_complete(hdev, sent, status); 23028cc7bdeSJohan Hedberg else if (!status) 23128cc7bdeSJohan Hedberg memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); 232f51d5b24SJohan Hedberg 23356e5cb86SJohan Hedberg hci_dev_unlock(hdev); 234a9de9248SMarcel Holtmann } 235a9de9248SMarcel Holtmann 236a9de9248SMarcel Holtmann static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) 237a9de9248SMarcel Holtmann { 238a9de9248SMarcel Holtmann struct hci_rp_read_local_name *rp = (void *) skb->data; 239a9de9248SMarcel Holtmann 2409f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 241a9de9248SMarcel Holtmann 242a9de9248SMarcel Holtmann if (rp->status) 243a9de9248SMarcel Holtmann return; 244a9de9248SMarcel Holtmann 245db99b5fcSJohan Hedberg if (test_bit(HCI_SETUP, &hdev->dev_flags)) 2461f6c6378SJohan Hedberg memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); 247a9de9248SMarcel Holtmann } 248a9de9248SMarcel Holtmann 249a9de9248SMarcel Holtmann static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) 250a9de9248SMarcel Holtmann { 251a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 252a9de9248SMarcel Holtmann void *sent; 253a9de9248SMarcel Holtmann 2549f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 255a9de9248SMarcel Holtmann 256a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE); 257a9de9248SMarcel Holtmann if (!sent) 258a9de9248SMarcel Holtmann return; 2591da177e4SLinus Torvalds 2601da177e4SLinus Torvalds if (!status) { 261a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 262a9de9248SMarcel Holtmann 2631da177e4SLinus Torvalds if (param == AUTH_ENABLED) 2641da177e4SLinus Torvalds set_bit(HCI_AUTH, &hdev->flags); 2651da177e4SLinus Torvalds else 2661da177e4SLinus Torvalds clear_bit(HCI_AUTH, &hdev->flags); 2671da177e4SLinus Torvalds } 268a9de9248SMarcel Holtmann 26933ef95edSJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 27033ef95edSJohan Hedberg mgmt_auth_enable_complete(hdev, status); 271a9de9248SMarcel Holtmann } 2721da177e4SLinus Torvalds 273a9de9248SMarcel Holtmann static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) 274a9de9248SMarcel Holtmann { 275a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 27645296acdSMarcel Holtmann __u8 param; 277a9de9248SMarcel Holtmann void *sent; 278a9de9248SMarcel Holtmann 2799f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 280a9de9248SMarcel Holtmann 28145296acdSMarcel Holtmann if (status) 28245296acdSMarcel Holtmann return; 28345296acdSMarcel Holtmann 284a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE); 2851da177e4SLinus Torvalds if (!sent) 286a9de9248SMarcel Holtmann return; 2871da177e4SLinus Torvalds 28845296acdSMarcel Holtmann param = *((__u8 *) sent); 289a9de9248SMarcel Holtmann 2901da177e4SLinus Torvalds if (param) 2911da177e4SLinus Torvalds set_bit(HCI_ENCRYPT, &hdev->flags); 2921da177e4SLinus Torvalds else 2931da177e4SLinus Torvalds clear_bit(HCI_ENCRYPT, &hdev->flags); 2941da177e4SLinus Torvalds } 2951da177e4SLinus Torvalds 296a9de9248SMarcel Holtmann static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) 297a9de9248SMarcel Holtmann { 29845296acdSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 29945296acdSMarcel Holtmann __u8 param; 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) { 3132d7cee58SJohan Hedberg hdev->discov_timeout = 0; 3142d7cee58SJohan Hedberg goto done; 3152d7cee58SJohan Hedberg } 3162d7cee58SJohan Hedberg 317bc6d2d04SJohan Hedberg if (param & SCAN_INQUIRY) 3181da177e4SLinus Torvalds set_bit(HCI_ISCAN, &hdev->flags); 319bc6d2d04SJohan Hedberg else 320bc6d2d04SJohan Hedberg clear_bit(HCI_ISCAN, &hdev->flags); 3211da177e4SLinus Torvalds 322031547d8SJohan Hedberg if (param & SCAN_PAGE) 3231da177e4SLinus Torvalds set_bit(HCI_PSCAN, &hdev->flags); 324bc6d2d04SJohan Hedberg else 325204e3990SJohan Hedberg clear_bit(HCI_PSCAN, &hdev->flags); 326a9de9248SMarcel Holtmann 32736f7fc7eSJohan Hedberg done: 32856e5cb86SJohan Hedberg hci_dev_unlock(hdev); 3291da177e4SLinus Torvalds } 3301da177e4SLinus Torvalds 331a9de9248SMarcel Holtmann static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 332a9de9248SMarcel Holtmann { 333a9de9248SMarcel Holtmann struct hci_rp_read_class_of_dev *rp = (void *) skb->data; 334a9de9248SMarcel Holtmann 3359f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 336a9de9248SMarcel Holtmann 337a9de9248SMarcel Holtmann if (rp->status) 338a9de9248SMarcel Holtmann return; 339a9de9248SMarcel Holtmann 340a9de9248SMarcel Holtmann memcpy(hdev->dev_class, rp->dev_class, 3); 341a9de9248SMarcel Holtmann 342a9de9248SMarcel Holtmann BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name, 343a9de9248SMarcel Holtmann hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); 344a9de9248SMarcel Holtmann } 345a9de9248SMarcel Holtmann 346a9de9248SMarcel Holtmann static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 347a9de9248SMarcel Holtmann { 348a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 349a9de9248SMarcel Holtmann void *sent; 350a9de9248SMarcel Holtmann 3519f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 352a9de9248SMarcel Holtmann 353a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV); 354a9de9248SMarcel Holtmann if (!sent) 355a9de9248SMarcel Holtmann return; 356a9de9248SMarcel Holtmann 3577f9a903cSMarcel Holtmann hci_dev_lock(hdev); 3587f9a903cSMarcel Holtmann 3597f9a903cSMarcel Holtmann if (status == 0) 360a9de9248SMarcel Holtmann memcpy(hdev->dev_class, sent, 3); 3617f9a903cSMarcel Holtmann 3627f9a903cSMarcel Holtmann if (test_bit(HCI_MGMT, &hdev->dev_flags)) 3637f9a903cSMarcel Holtmann mgmt_set_class_of_dev_complete(hdev, sent, status); 3647f9a903cSMarcel Holtmann 3657f9a903cSMarcel Holtmann hci_dev_unlock(hdev); 366a9de9248SMarcel Holtmann } 367a9de9248SMarcel Holtmann 368a9de9248SMarcel Holtmann static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) 369a9de9248SMarcel Holtmann { 370a9de9248SMarcel Holtmann struct hci_rp_read_voice_setting *rp = (void *) skb->data; 371a9de9248SMarcel Holtmann __u16 setting; 372a9de9248SMarcel Holtmann 3739f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 374a9de9248SMarcel Holtmann 375a9de9248SMarcel Holtmann if (rp->status) 376a9de9248SMarcel Holtmann return; 377a9de9248SMarcel Holtmann 378a9de9248SMarcel Holtmann setting = __le16_to_cpu(rp->voice_setting); 379a9de9248SMarcel Holtmann 380a9de9248SMarcel Holtmann if (hdev->voice_setting == setting) 381a9de9248SMarcel Holtmann return; 382a9de9248SMarcel Holtmann 383a9de9248SMarcel Holtmann hdev->voice_setting = setting; 384a9de9248SMarcel Holtmann 3859f1db00cSAndrei Emeltchenko BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting); 386a9de9248SMarcel Holtmann 3873c54711cSGustavo F. Padovan if (hdev->notify) 388a9de9248SMarcel Holtmann hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 389a9de9248SMarcel Holtmann } 390a9de9248SMarcel Holtmann 3918fc9ced3SGustavo Padovan static void hci_cc_write_voice_setting(struct hci_dev *hdev, 3928fc9ced3SGustavo Padovan struct sk_buff *skb) 393a9de9248SMarcel Holtmann { 394a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 395f383f275SMarcel Holtmann __u16 setting; 396a9de9248SMarcel Holtmann void *sent; 397a9de9248SMarcel Holtmann 3989f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 399a9de9248SMarcel Holtmann 400f383f275SMarcel Holtmann if (status) 401f383f275SMarcel Holtmann return; 402f383f275SMarcel Holtmann 403a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING); 404a9de9248SMarcel Holtmann if (!sent) 405a9de9248SMarcel Holtmann return; 406a9de9248SMarcel Holtmann 407f383f275SMarcel Holtmann setting = get_unaligned_le16(sent); 4081da177e4SLinus Torvalds 409f383f275SMarcel Holtmann if (hdev->voice_setting == setting) 410f383f275SMarcel Holtmann return; 411f383f275SMarcel Holtmann 4121da177e4SLinus Torvalds hdev->voice_setting = setting; 4131da177e4SLinus Torvalds 4149f1db00cSAndrei Emeltchenko BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting); 4151da177e4SLinus Torvalds 4163c54711cSGustavo F. Padovan if (hdev->notify) 4171da177e4SLinus Torvalds hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 4181da177e4SLinus Torvalds } 4191da177e4SLinus Torvalds 420b4cb9fb2SMarcel Holtmann static void hci_cc_read_num_supported_iac(struct hci_dev *hdev, 421b4cb9fb2SMarcel Holtmann struct sk_buff *skb) 422b4cb9fb2SMarcel Holtmann { 423b4cb9fb2SMarcel Holtmann struct hci_rp_read_num_supported_iac *rp = (void *) skb->data; 424b4cb9fb2SMarcel Holtmann 425b4cb9fb2SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 426b4cb9fb2SMarcel Holtmann 427b4cb9fb2SMarcel Holtmann if (rp->status) 428b4cb9fb2SMarcel Holtmann return; 429b4cb9fb2SMarcel Holtmann 430b4cb9fb2SMarcel Holtmann hdev->num_iac = rp->num_iac; 431b4cb9fb2SMarcel Holtmann 432b4cb9fb2SMarcel Holtmann BT_DBG("%s num iac %d", hdev->name, hdev->num_iac); 433b4cb9fb2SMarcel Holtmann } 434b4cb9fb2SMarcel Holtmann 435333140b5SMarcel Holtmann static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) 436333140b5SMarcel Holtmann { 437333140b5SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 4385ed8eb2fSJohan Hedberg struct hci_cp_write_ssp_mode *sent; 439333140b5SMarcel Holtmann 4409f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 441333140b5SMarcel Holtmann 442333140b5SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); 443333140b5SMarcel Holtmann if (!sent) 444333140b5SMarcel Holtmann return; 445333140b5SMarcel Holtmann 4465ed8eb2fSJohan Hedberg if (!status) { 4475ed8eb2fSJohan Hedberg if (sent->mode) 448cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_SSP; 4495ed8eb2fSJohan Hedberg else 450cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_SSP; 4515ed8eb2fSJohan Hedberg } 4525ed8eb2fSJohan Hedberg 453c0ecddc2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 4545ed8eb2fSJohan Hedberg mgmt_ssp_enable_complete(hdev, sent->mode, status); 455c0ecddc2SJohan Hedberg else if (!status) { 4565ed8eb2fSJohan Hedberg if (sent->mode) 45784bde9d6SJohan Hedberg set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); 45884bde9d6SJohan Hedberg else 45984bde9d6SJohan Hedberg clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); 460c0ecddc2SJohan Hedberg } 461333140b5SMarcel Holtmann } 462333140b5SMarcel Holtmann 463eac83dc6SMarcel Holtmann static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb) 464eac83dc6SMarcel Holtmann { 465eac83dc6SMarcel Holtmann u8 status = *((u8 *) skb->data); 466eac83dc6SMarcel Holtmann struct hci_cp_write_sc_support *sent; 467eac83dc6SMarcel Holtmann 468eac83dc6SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 469eac83dc6SMarcel Holtmann 470eac83dc6SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT); 471eac83dc6SMarcel Holtmann if (!sent) 472eac83dc6SMarcel Holtmann return; 473eac83dc6SMarcel Holtmann 474eac83dc6SMarcel Holtmann if (!status) { 475eac83dc6SMarcel Holtmann if (sent->support) 476eac83dc6SMarcel Holtmann hdev->features[1][0] |= LMP_HOST_SC; 477eac83dc6SMarcel Holtmann else 478eac83dc6SMarcel Holtmann hdev->features[1][0] &= ~LMP_HOST_SC; 479eac83dc6SMarcel Holtmann } 480eac83dc6SMarcel Holtmann 481eac83dc6SMarcel Holtmann if (test_bit(HCI_MGMT, &hdev->dev_flags)) 482eac83dc6SMarcel Holtmann mgmt_sc_enable_complete(hdev, sent->support, status); 483eac83dc6SMarcel Holtmann else if (!status) { 484eac83dc6SMarcel Holtmann if (sent->support) 485eac83dc6SMarcel Holtmann set_bit(HCI_SC_ENABLED, &hdev->dev_flags); 486eac83dc6SMarcel Holtmann else 487eac83dc6SMarcel Holtmann clear_bit(HCI_SC_ENABLED, &hdev->dev_flags); 488eac83dc6SMarcel Holtmann } 489eac83dc6SMarcel Holtmann } 490eac83dc6SMarcel Holtmann 491a9de9248SMarcel Holtmann static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) 492a9de9248SMarcel Holtmann { 493a9de9248SMarcel Holtmann struct hci_rp_read_local_version *rp = (void *) skb->data; 4941143e5a6SMarcel Holtmann 4959f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 4961143e5a6SMarcel Holtmann 497a9de9248SMarcel Holtmann if (rp->status) 49842c6b129SJohan Hedberg return; 4991143e5a6SMarcel Holtmann 5000d5551f5SMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 501a9de9248SMarcel Holtmann hdev->hci_ver = rp->hci_ver; 502e4e8e37cSMarcel Holtmann hdev->hci_rev = __le16_to_cpu(rp->hci_rev); 503d5859e22SJohan Hedberg hdev->lmp_ver = rp->lmp_ver; 504e4e8e37cSMarcel Holtmann hdev->manufacturer = __le16_to_cpu(rp->manufacturer); 505d5859e22SJohan Hedberg hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); 5060d5551f5SMarcel Holtmann } 507d5859e22SJohan Hedberg } 508d5859e22SJohan Hedberg 5098fc9ced3SGustavo Padovan static void hci_cc_read_local_commands(struct hci_dev *hdev, 5108fc9ced3SGustavo Padovan struct sk_buff *skb) 511a9de9248SMarcel Holtmann { 512a9de9248SMarcel Holtmann struct hci_rp_read_local_commands *rp = (void *) skb->data; 513a9de9248SMarcel Holtmann 5149f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 515a9de9248SMarcel Holtmann 5166a070e6eSMarcel Holtmann if (rp->status) 5176a070e6eSMarcel Holtmann return; 5186a070e6eSMarcel Holtmann 5196a070e6eSMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) 520a9de9248SMarcel Holtmann memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); 521a9de9248SMarcel Holtmann } 522a9de9248SMarcel Holtmann 5238fc9ced3SGustavo Padovan static void hci_cc_read_local_features(struct hci_dev *hdev, 5248fc9ced3SGustavo Padovan struct sk_buff *skb) 525a9de9248SMarcel Holtmann { 526a9de9248SMarcel Holtmann struct hci_rp_read_local_features *rp = (void *) skb->data; 527a9de9248SMarcel Holtmann 5289f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 529a9de9248SMarcel Holtmann 530a9de9248SMarcel Holtmann if (rp->status) 531a9de9248SMarcel Holtmann return; 532a9de9248SMarcel Holtmann 533a9de9248SMarcel Holtmann memcpy(hdev->features, rp->features, 8); 5341da177e4SLinus Torvalds 5351da177e4SLinus Torvalds /* Adjust default settings according to features 5361da177e4SLinus Torvalds * supported by device. */ 537a9de9248SMarcel Holtmann 538cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_3SLOT) 5391da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM3 | HCI_DH3); 5401da177e4SLinus Torvalds 541cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_5SLOT) 5421da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM5 | HCI_DH5); 5431da177e4SLinus Torvalds 544cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV2) { 5451da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV2); 5465b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV2); 5475b7f9909SMarcel Holtmann } 5481da177e4SLinus Torvalds 549cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV3) { 5501da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV3); 5515b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV3); 5525b7f9909SMarcel Holtmann } 5535b7f9909SMarcel Holtmann 55445db810fSAndre Guedes if (lmp_esco_capable(hdev)) 5555b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV3); 5565b7f9909SMarcel Holtmann 557cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV4) 5585b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV4); 5595b7f9909SMarcel Holtmann 560cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV5) 5615b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV5); 5621da177e4SLinus Torvalds 563cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_2M) 564efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV3); 565efc7688bSMarcel Holtmann 566cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_3M) 567efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_3EV3); 568efc7688bSMarcel Holtmann 569cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_3S_ESCO) 570efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); 5711da177e4SLinus Torvalds } 5721da177e4SLinus Torvalds 573971e3a4bSAndre Guedes static void hci_cc_read_local_ext_features(struct hci_dev *hdev, 574971e3a4bSAndre Guedes struct sk_buff *skb) 575971e3a4bSAndre Guedes { 576971e3a4bSAndre Guedes struct hci_rp_read_local_ext_features *rp = (void *) skb->data; 577971e3a4bSAndre Guedes 5789f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 579971e3a4bSAndre Guedes 580971e3a4bSAndre Guedes if (rp->status) 58142c6b129SJohan Hedberg return; 582971e3a4bSAndre Guedes 58357af75a8SMarcel Holtmann if (hdev->max_page < rp->max_page) 584d2c5d77fSJohan Hedberg hdev->max_page = rp->max_page; 585d2c5d77fSJohan Hedberg 586cad718edSJohan Hedberg if (rp->page < HCI_MAX_PAGES) 587cad718edSJohan Hedberg memcpy(hdev->features[rp->page], rp->features, 8); 588971e3a4bSAndre Guedes } 589971e3a4bSAndre Guedes 5901e89cffbSAndrei Emeltchenko static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, 5911e89cffbSAndrei Emeltchenko struct sk_buff *skb) 5921e89cffbSAndrei Emeltchenko { 5931e89cffbSAndrei Emeltchenko struct hci_rp_read_flow_control_mode *rp = (void *) skb->data; 5941e89cffbSAndrei Emeltchenko 5959f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 5961e89cffbSAndrei Emeltchenko 59745296acdSMarcel Holtmann if (rp->status) 59845296acdSMarcel Holtmann return; 59945296acdSMarcel Holtmann 6001e89cffbSAndrei Emeltchenko hdev->flow_ctl_mode = rp->mode; 6011e89cffbSAndrei Emeltchenko } 6021e89cffbSAndrei Emeltchenko 603a9de9248SMarcel Holtmann static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) 604a9de9248SMarcel Holtmann { 605a9de9248SMarcel Holtmann struct hci_rp_read_buffer_size *rp = (void *) skb->data; 606a9de9248SMarcel Holtmann 6079f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 608a9de9248SMarcel Holtmann 609a9de9248SMarcel Holtmann if (rp->status) 610a9de9248SMarcel Holtmann return; 611a9de9248SMarcel Holtmann 612a9de9248SMarcel Holtmann hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu); 613a9de9248SMarcel Holtmann hdev->sco_mtu = rp->sco_mtu; 614a9de9248SMarcel Holtmann hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt); 615a9de9248SMarcel Holtmann hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt); 616da1f5198SMarcel Holtmann 617da1f5198SMarcel Holtmann if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) { 618da1f5198SMarcel Holtmann hdev->sco_mtu = 64; 619da1f5198SMarcel Holtmann hdev->sco_pkts = 8; 620da1f5198SMarcel Holtmann } 621da1f5198SMarcel Holtmann 622da1f5198SMarcel Holtmann hdev->acl_cnt = hdev->acl_pkts; 623da1f5198SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 6241da177e4SLinus Torvalds 625807deac2SGustavo Padovan BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu, 626807deac2SGustavo Padovan hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts); 6271da177e4SLinus Torvalds } 6281da177e4SLinus Torvalds 629a9de9248SMarcel Holtmann static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) 630a9de9248SMarcel Holtmann { 631a9de9248SMarcel Holtmann struct hci_rp_read_bd_addr *rp = (void *) skb->data; 6321da177e4SLinus Torvalds 6339f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 634a9de9248SMarcel Holtmann 635e30d3f5fSMarcel Holtmann if (rp->status) 636e30d3f5fSMarcel Holtmann return; 637e30d3f5fSMarcel Holtmann 638e30d3f5fSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) 639a9de9248SMarcel Holtmann bacpy(&hdev->bdaddr, &rp->bdaddr); 640e30d3f5fSMarcel Holtmann 641e30d3f5fSMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) 642e30d3f5fSMarcel Holtmann bacpy(&hdev->setup_addr, &rp->bdaddr); 64323bb5763SJohan Hedberg } 64423bb5763SJohan Hedberg 645f332ec66SJohan Hedberg static void hci_cc_read_page_scan_activity(struct hci_dev *hdev, 646f332ec66SJohan Hedberg struct sk_buff *skb) 647f332ec66SJohan Hedberg { 648f332ec66SJohan Hedberg struct hci_rp_read_page_scan_activity *rp = (void *) skb->data; 649f332ec66SJohan Hedberg 650f332ec66SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 651f332ec66SJohan Hedberg 65245296acdSMarcel Holtmann if (rp->status) 65345296acdSMarcel Holtmann return; 65445296acdSMarcel Holtmann 65545296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) { 656f332ec66SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(rp->interval); 657f332ec66SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(rp->window); 658f332ec66SJohan Hedberg } 659f332ec66SJohan Hedberg } 660f332ec66SJohan Hedberg 6614a3ee763SJohan Hedberg static void hci_cc_write_page_scan_activity(struct hci_dev *hdev, 6624a3ee763SJohan Hedberg struct sk_buff *skb) 6634a3ee763SJohan Hedberg { 6644a3ee763SJohan Hedberg u8 status = *((u8 *) skb->data); 6654a3ee763SJohan Hedberg struct hci_cp_write_page_scan_activity *sent; 6664a3ee763SJohan Hedberg 6674a3ee763SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 6684a3ee763SJohan Hedberg 6694a3ee763SJohan Hedberg if (status) 6704a3ee763SJohan Hedberg return; 6714a3ee763SJohan Hedberg 6724a3ee763SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY); 6734a3ee763SJohan Hedberg if (!sent) 6744a3ee763SJohan Hedberg return; 6754a3ee763SJohan Hedberg 6764a3ee763SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(sent->interval); 6774a3ee763SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(sent->window); 6784a3ee763SJohan Hedberg } 6794a3ee763SJohan Hedberg 680f332ec66SJohan Hedberg static void hci_cc_read_page_scan_type(struct hci_dev *hdev, 681f332ec66SJohan Hedberg struct sk_buff *skb) 682f332ec66SJohan Hedberg { 683f332ec66SJohan Hedberg struct hci_rp_read_page_scan_type *rp = (void *) skb->data; 684f332ec66SJohan Hedberg 685f332ec66SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 686f332ec66SJohan Hedberg 68745296acdSMarcel Holtmann if (rp->status) 68845296acdSMarcel Holtmann return; 68945296acdSMarcel Holtmann 69045296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) 691f332ec66SJohan Hedberg hdev->page_scan_type = rp->type; 692f332ec66SJohan Hedberg } 693f332ec66SJohan Hedberg 6944a3ee763SJohan Hedberg static void hci_cc_write_page_scan_type(struct hci_dev *hdev, 6954a3ee763SJohan Hedberg struct sk_buff *skb) 6964a3ee763SJohan Hedberg { 6974a3ee763SJohan Hedberg u8 status = *((u8 *) skb->data); 6984a3ee763SJohan Hedberg u8 *type; 6994a3ee763SJohan Hedberg 7004a3ee763SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 7014a3ee763SJohan Hedberg 7024a3ee763SJohan Hedberg if (status) 7034a3ee763SJohan Hedberg return; 7044a3ee763SJohan Hedberg 7054a3ee763SJohan Hedberg type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE); 7064a3ee763SJohan Hedberg if (type) 7074a3ee763SJohan Hedberg hdev->page_scan_type = *type; 7084a3ee763SJohan Hedberg } 7094a3ee763SJohan Hedberg 710350ee4cfSAndrei Emeltchenko static void hci_cc_read_data_block_size(struct hci_dev *hdev, 711350ee4cfSAndrei Emeltchenko struct sk_buff *skb) 712350ee4cfSAndrei Emeltchenko { 713350ee4cfSAndrei Emeltchenko struct hci_rp_read_data_block_size *rp = (void *) skb->data; 714350ee4cfSAndrei Emeltchenko 7159f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 716350ee4cfSAndrei Emeltchenko 717350ee4cfSAndrei Emeltchenko if (rp->status) 718350ee4cfSAndrei Emeltchenko return; 719350ee4cfSAndrei Emeltchenko 720350ee4cfSAndrei Emeltchenko hdev->block_mtu = __le16_to_cpu(rp->max_acl_len); 721350ee4cfSAndrei Emeltchenko hdev->block_len = __le16_to_cpu(rp->block_len); 722350ee4cfSAndrei Emeltchenko hdev->num_blocks = __le16_to_cpu(rp->num_blocks); 723350ee4cfSAndrei Emeltchenko 724350ee4cfSAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 725350ee4cfSAndrei Emeltchenko 726350ee4cfSAndrei Emeltchenko BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu, 727350ee4cfSAndrei Emeltchenko hdev->block_cnt, hdev->block_len); 728350ee4cfSAndrei Emeltchenko } 729350ee4cfSAndrei Emeltchenko 73033f35721SJohan Hedberg static void hci_cc_read_clock(struct hci_dev *hdev, struct sk_buff *skb) 73133f35721SJohan Hedberg { 73233f35721SJohan Hedberg struct hci_rp_read_clock *rp = (void *) skb->data; 73333f35721SJohan Hedberg struct hci_cp_read_clock *cp; 73433f35721SJohan Hedberg struct hci_conn *conn; 73533f35721SJohan Hedberg 73633f35721SJohan Hedberg BT_DBG("%s", hdev->name); 73733f35721SJohan Hedberg 73833f35721SJohan Hedberg if (skb->len < sizeof(*rp)) 73933f35721SJohan Hedberg return; 74033f35721SJohan Hedberg 74133f35721SJohan Hedberg if (rp->status) 74233f35721SJohan Hedberg return; 74333f35721SJohan Hedberg 74433f35721SJohan Hedberg hci_dev_lock(hdev); 74533f35721SJohan Hedberg 74633f35721SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK); 74733f35721SJohan Hedberg if (!cp) 74833f35721SJohan Hedberg goto unlock; 74933f35721SJohan Hedberg 75033f35721SJohan Hedberg if (cp->which == 0x00) { 75133f35721SJohan Hedberg hdev->clock = le32_to_cpu(rp->clock); 75233f35721SJohan Hedberg goto unlock; 75333f35721SJohan Hedberg } 75433f35721SJohan Hedberg 75533f35721SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 75633f35721SJohan Hedberg if (conn) { 75733f35721SJohan Hedberg conn->clock = le32_to_cpu(rp->clock); 75833f35721SJohan Hedberg conn->clock_accuracy = le16_to_cpu(rp->accuracy); 75933f35721SJohan Hedberg } 76033f35721SJohan Hedberg 76133f35721SJohan Hedberg unlock: 76233f35721SJohan Hedberg hci_dev_unlock(hdev); 76333f35721SJohan Hedberg } 76433f35721SJohan Hedberg 765928abaa7SAndrei Emeltchenko static void hci_cc_read_local_amp_info(struct hci_dev *hdev, 766928abaa7SAndrei Emeltchenko struct sk_buff *skb) 767928abaa7SAndrei Emeltchenko { 768928abaa7SAndrei Emeltchenko struct hci_rp_read_local_amp_info *rp = (void *) skb->data; 769928abaa7SAndrei Emeltchenko 7709f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 771928abaa7SAndrei Emeltchenko 772928abaa7SAndrei Emeltchenko if (rp->status) 7738e2a0d92SAndrei Emeltchenko goto a2mp_rsp; 774928abaa7SAndrei Emeltchenko 775928abaa7SAndrei Emeltchenko hdev->amp_status = rp->amp_status; 776928abaa7SAndrei Emeltchenko hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); 777928abaa7SAndrei Emeltchenko hdev->amp_max_bw = __le32_to_cpu(rp->max_bw); 778928abaa7SAndrei Emeltchenko hdev->amp_min_latency = __le32_to_cpu(rp->min_latency); 779928abaa7SAndrei Emeltchenko hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu); 780928abaa7SAndrei Emeltchenko hdev->amp_type = rp->amp_type; 781928abaa7SAndrei Emeltchenko hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap); 782928abaa7SAndrei Emeltchenko hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size); 783928abaa7SAndrei Emeltchenko hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to); 784928abaa7SAndrei Emeltchenko hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); 785928abaa7SAndrei Emeltchenko 7868e2a0d92SAndrei Emeltchenko a2mp_rsp: 7878e2a0d92SAndrei Emeltchenko a2mp_send_getinfo_rsp(hdev); 788928abaa7SAndrei Emeltchenko } 789928abaa7SAndrei Emeltchenko 790903e4541SAndrei Emeltchenko static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev, 791903e4541SAndrei Emeltchenko struct sk_buff *skb) 792903e4541SAndrei Emeltchenko { 793903e4541SAndrei Emeltchenko struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data; 794903e4541SAndrei Emeltchenko struct amp_assoc *assoc = &hdev->loc_assoc; 795903e4541SAndrei Emeltchenko size_t rem_len, frag_len; 796903e4541SAndrei Emeltchenko 797903e4541SAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 798903e4541SAndrei Emeltchenko 799903e4541SAndrei Emeltchenko if (rp->status) 800903e4541SAndrei Emeltchenko goto a2mp_rsp; 801903e4541SAndrei Emeltchenko 802903e4541SAndrei Emeltchenko frag_len = skb->len - sizeof(*rp); 803903e4541SAndrei Emeltchenko rem_len = __le16_to_cpu(rp->rem_len); 804903e4541SAndrei Emeltchenko 805903e4541SAndrei Emeltchenko if (rem_len > frag_len) { 8062e430be3SAndrei Emeltchenko BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len); 807903e4541SAndrei Emeltchenko 808903e4541SAndrei Emeltchenko memcpy(assoc->data + assoc->offset, rp->frag, frag_len); 809903e4541SAndrei Emeltchenko assoc->offset += frag_len; 810903e4541SAndrei Emeltchenko 811903e4541SAndrei Emeltchenko /* Read other fragments */ 812903e4541SAndrei Emeltchenko amp_read_loc_assoc_frag(hdev, rp->phy_handle); 813903e4541SAndrei Emeltchenko 814903e4541SAndrei Emeltchenko return; 815903e4541SAndrei Emeltchenko } 816903e4541SAndrei Emeltchenko 817903e4541SAndrei Emeltchenko memcpy(assoc->data + assoc->offset, rp->frag, rem_len); 818903e4541SAndrei Emeltchenko assoc->len = assoc->offset + rem_len; 819903e4541SAndrei Emeltchenko assoc->offset = 0; 820903e4541SAndrei Emeltchenko 821903e4541SAndrei Emeltchenko a2mp_rsp: 822903e4541SAndrei Emeltchenko /* Send A2MP Rsp when all fragments are received */ 823903e4541SAndrei Emeltchenko a2mp_send_getampassoc_rsp(hdev, rp->status); 8249495b2eeSAndrei Emeltchenko a2mp_send_create_phy_link_req(hdev, rp->status); 825903e4541SAndrei Emeltchenko } 826903e4541SAndrei Emeltchenko 827d5859e22SJohan Hedberg static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, 828d5859e22SJohan Hedberg struct sk_buff *skb) 829d5859e22SJohan Hedberg { 83091c4e9b1SMarcel Holtmann struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data; 831d5859e22SJohan Hedberg 8329f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 833d5859e22SJohan Hedberg 83445296acdSMarcel Holtmann if (rp->status) 83545296acdSMarcel Holtmann return; 83645296acdSMarcel Holtmann 83791c4e9b1SMarcel Holtmann hdev->inq_tx_power = rp->tx_power; 838d5859e22SJohan Hedberg } 839d5859e22SJohan Hedberg 840980e1a53SJohan Hedberg static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) 841980e1a53SJohan Hedberg { 842980e1a53SJohan Hedberg struct hci_rp_pin_code_reply *rp = (void *) skb->data; 843980e1a53SJohan Hedberg struct hci_cp_pin_code_reply *cp; 844980e1a53SJohan Hedberg struct hci_conn *conn; 845980e1a53SJohan Hedberg 8469f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 847980e1a53SJohan Hedberg 84856e5cb86SJohan Hedberg hci_dev_lock(hdev); 84956e5cb86SJohan Hedberg 850a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 851744cf19eSJohan Hedberg mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); 852980e1a53SJohan Hedberg 853fa1bd918SMikel Astiz if (rp->status) 85456e5cb86SJohan Hedberg goto unlock; 855980e1a53SJohan Hedberg 856980e1a53SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); 857980e1a53SJohan Hedberg if (!cp) 85856e5cb86SJohan Hedberg goto unlock; 859980e1a53SJohan Hedberg 860980e1a53SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 861980e1a53SJohan Hedberg if (conn) 862980e1a53SJohan Hedberg conn->pin_length = cp->pin_len; 86356e5cb86SJohan Hedberg 86456e5cb86SJohan Hedberg unlock: 86556e5cb86SJohan Hedberg hci_dev_unlock(hdev); 866980e1a53SJohan Hedberg } 867980e1a53SJohan Hedberg 868980e1a53SJohan Hedberg static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) 869980e1a53SJohan Hedberg { 870980e1a53SJohan Hedberg struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data; 871980e1a53SJohan Hedberg 8729f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 873980e1a53SJohan Hedberg 87456e5cb86SJohan Hedberg hci_dev_lock(hdev); 87556e5cb86SJohan Hedberg 876a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 877744cf19eSJohan Hedberg mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, 878980e1a53SJohan Hedberg rp->status); 87956e5cb86SJohan Hedberg 88056e5cb86SJohan Hedberg hci_dev_unlock(hdev); 881980e1a53SJohan Hedberg } 88256e5cb86SJohan Hedberg 8836ed58ec5SVille Tervo static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, 8846ed58ec5SVille Tervo struct sk_buff *skb) 8856ed58ec5SVille Tervo { 8866ed58ec5SVille Tervo struct hci_rp_le_read_buffer_size *rp = (void *) skb->data; 8876ed58ec5SVille Tervo 8889f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 8896ed58ec5SVille Tervo 8906ed58ec5SVille Tervo if (rp->status) 8916ed58ec5SVille Tervo return; 8926ed58ec5SVille Tervo 8936ed58ec5SVille Tervo hdev->le_mtu = __le16_to_cpu(rp->le_mtu); 8946ed58ec5SVille Tervo hdev->le_pkts = rp->le_max_pkt; 8956ed58ec5SVille Tervo 8966ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 8976ed58ec5SVille Tervo 8986ed58ec5SVille Tervo BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts); 8996ed58ec5SVille Tervo } 900980e1a53SJohan Hedberg 90160e77321SJohan Hedberg static void hci_cc_le_read_local_features(struct hci_dev *hdev, 90260e77321SJohan Hedberg struct sk_buff *skb) 90360e77321SJohan Hedberg { 90460e77321SJohan Hedberg struct hci_rp_le_read_local_features *rp = (void *) skb->data; 90560e77321SJohan Hedberg 90660e77321SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 90760e77321SJohan Hedberg 90845296acdSMarcel Holtmann if (rp->status) 90945296acdSMarcel Holtmann return; 91045296acdSMarcel Holtmann 91160e77321SJohan Hedberg memcpy(hdev->le_features, rp->features, 8); 91260e77321SJohan Hedberg } 91360e77321SJohan Hedberg 9148fa19098SJohan Hedberg static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, 9158fa19098SJohan Hedberg struct sk_buff *skb) 9168fa19098SJohan Hedberg { 9178fa19098SJohan Hedberg struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data; 9188fa19098SJohan Hedberg 9198fa19098SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9208fa19098SJohan Hedberg 92145296acdSMarcel Holtmann if (rp->status) 92245296acdSMarcel Holtmann return; 92345296acdSMarcel Holtmann 9248fa19098SJohan Hedberg hdev->adv_tx_power = rp->tx_power; 9258fa19098SJohan Hedberg } 9268fa19098SJohan Hedberg 927a5c29683SJohan Hedberg static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) 928a5c29683SJohan Hedberg { 929a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 930a5c29683SJohan Hedberg 9319f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 932a5c29683SJohan Hedberg 93356e5cb86SJohan Hedberg hci_dev_lock(hdev); 93456e5cb86SJohan Hedberg 935a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 93604124681SGustavo F. Padovan mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0, 93704124681SGustavo F. Padovan rp->status); 93856e5cb86SJohan Hedberg 93956e5cb86SJohan Hedberg hci_dev_unlock(hdev); 940a5c29683SJohan Hedberg } 941a5c29683SJohan Hedberg 942a5c29683SJohan Hedberg static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, 943a5c29683SJohan Hedberg struct sk_buff *skb) 944a5c29683SJohan Hedberg { 945a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 946a5c29683SJohan Hedberg 9479f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 948a5c29683SJohan Hedberg 94956e5cb86SJohan Hedberg hci_dev_lock(hdev); 95056e5cb86SJohan Hedberg 951a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 952744cf19eSJohan Hedberg mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, 95304124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 95456e5cb86SJohan Hedberg 95556e5cb86SJohan Hedberg hci_dev_unlock(hdev); 956a5c29683SJohan Hedberg } 957a5c29683SJohan Hedberg 9581143d458SBrian Gix static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb) 9591143d458SBrian Gix { 9601143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 9611143d458SBrian Gix 9629f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9631143d458SBrian Gix 9641143d458SBrian Gix hci_dev_lock(hdev); 9651143d458SBrian Gix 966a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 967272d90dfSJohan Hedberg mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 968272d90dfSJohan Hedberg 0, rp->status); 9691143d458SBrian Gix 9701143d458SBrian Gix hci_dev_unlock(hdev); 9711143d458SBrian Gix } 9721143d458SBrian Gix 9731143d458SBrian Gix static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, 9741143d458SBrian Gix struct sk_buff *skb) 9751143d458SBrian Gix { 9761143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 9771143d458SBrian Gix 9789f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9791143d458SBrian Gix 9801143d458SBrian Gix hci_dev_lock(hdev); 9811143d458SBrian Gix 982a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 9831143d458SBrian Gix mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr, 98404124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 9851143d458SBrian Gix 9861143d458SBrian Gix hci_dev_unlock(hdev); 9871143d458SBrian Gix } 9881143d458SBrian Gix 9894d2d2796SMarcel Holtmann static void hci_cc_read_local_oob_data(struct hci_dev *hdev, 990c35938b2SSzymon Janc struct sk_buff *skb) 991c35938b2SSzymon Janc { 992c35938b2SSzymon Janc struct hci_rp_read_local_oob_data *rp = (void *) skb->data; 993c35938b2SSzymon Janc 9949f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 995c35938b2SSzymon Janc 99656e5cb86SJohan Hedberg hci_dev_lock(hdev); 9974d2d2796SMarcel Holtmann mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->randomizer, 9984d2d2796SMarcel Holtmann NULL, NULL, rp->status); 9994d2d2796SMarcel Holtmann hci_dev_unlock(hdev); 10004d2d2796SMarcel Holtmann } 10014d2d2796SMarcel Holtmann 10024d2d2796SMarcel Holtmann static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, 10034d2d2796SMarcel Holtmann struct sk_buff *skb) 10044d2d2796SMarcel Holtmann { 10054d2d2796SMarcel Holtmann struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data; 10064d2d2796SMarcel Holtmann 10074d2d2796SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 10084d2d2796SMarcel Holtmann 10094d2d2796SMarcel Holtmann hci_dev_lock(hdev); 10104d2d2796SMarcel Holtmann mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->randomizer192, 10114d2d2796SMarcel Holtmann rp->hash256, rp->randomizer256, 10124d2d2796SMarcel Holtmann rp->status); 101356e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1014c35938b2SSzymon Janc } 1015c35938b2SSzymon Janc 10167a4cd51dSMarcel Holtmann 10177a4cd51dSMarcel Holtmann static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb) 10187a4cd51dSMarcel Holtmann { 10197a4cd51dSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 10207a4cd51dSMarcel Holtmann bdaddr_t *sent; 10217a4cd51dSMarcel Holtmann 10227a4cd51dSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 10237a4cd51dSMarcel Holtmann 102445296acdSMarcel Holtmann if (status) 102545296acdSMarcel Holtmann return; 102645296acdSMarcel Holtmann 10277a4cd51dSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR); 10287a4cd51dSMarcel Holtmann if (!sent) 10297a4cd51dSMarcel Holtmann return; 10307a4cd51dSMarcel Holtmann 10317a4cd51dSMarcel Holtmann hci_dev_lock(hdev); 10327a4cd51dSMarcel Holtmann 10337a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, sent); 10347a4cd51dSMarcel Holtmann 10357a4cd51dSMarcel Holtmann hci_dev_unlock(hdev); 10367a4cd51dSMarcel Holtmann } 10377a4cd51dSMarcel Holtmann 1038c1d5dc4aSJohan Hedberg static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) 1039c1d5dc4aSJohan Hedberg { 1040c1d5dc4aSJohan Hedberg __u8 *sent, status = *((__u8 *) skb->data); 1041c1d5dc4aSJohan Hedberg 1042c1d5dc4aSJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 1043c1d5dc4aSJohan Hedberg 104445296acdSMarcel Holtmann if (status) 1045c1d5dc4aSJohan Hedberg return; 1046c1d5dc4aSJohan Hedberg 104745296acdSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE); 104845296acdSMarcel Holtmann if (!sent) 10493c857757SJohan Hedberg return; 10503c857757SJohan Hedberg 1051c1d5dc4aSJohan Hedberg hci_dev_lock(hdev); 1052c1d5dc4aSJohan Hedberg 105349c922bbSStephen Hemminger /* If we're doing connection initiation as peripheral. Set a 10543c857757SJohan Hedberg * timeout in case something goes wrong. 10553c857757SJohan Hedberg */ 10563c857757SJohan Hedberg if (*sent) { 10573c857757SJohan Hedberg struct hci_conn *conn; 10583c857757SJohan Hedberg 105966c417c1SJohan Hedberg set_bit(HCI_LE_ADV, &hdev->dev_flags); 106066c417c1SJohan Hedberg 10613c857757SJohan Hedberg conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); 10623c857757SJohan Hedberg if (conn) 10633c857757SJohan Hedberg queue_delayed_work(hdev->workqueue, 10643c857757SJohan Hedberg &conn->le_conn_timeout, 106509ae260bSJohan Hedberg conn->conn_timeout); 106666c417c1SJohan Hedberg } else { 106766c417c1SJohan Hedberg clear_bit(HCI_LE_ADV, &hdev->dev_flags); 10683c857757SJohan Hedberg } 10693c857757SJohan Hedberg 107004b4edcbSJohan Hedberg hci_dev_unlock(hdev); 1071c1d5dc4aSJohan Hedberg } 1072c1d5dc4aSJohan Hedberg 1073533553f8SMarcel Holtmann static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) 1074533553f8SMarcel Holtmann { 1075533553f8SMarcel Holtmann struct hci_cp_le_set_scan_param *cp; 1076533553f8SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 1077533553f8SMarcel Holtmann 1078533553f8SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 1079533553f8SMarcel Holtmann 108045296acdSMarcel Holtmann if (status) 108145296acdSMarcel Holtmann return; 108245296acdSMarcel Holtmann 1083533553f8SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM); 1084533553f8SMarcel Holtmann if (!cp) 1085533553f8SMarcel Holtmann return; 1086533553f8SMarcel Holtmann 1087533553f8SMarcel Holtmann hci_dev_lock(hdev); 1088533553f8SMarcel Holtmann 1089533553f8SMarcel Holtmann hdev->le_scan_type = cp->type; 1090533553f8SMarcel Holtmann 1091533553f8SMarcel Holtmann hci_dev_unlock(hdev); 1092533553f8SMarcel Holtmann } 1093533553f8SMarcel Holtmann 1094b9a6328fSJohan Hedberg static bool has_pending_adv_report(struct hci_dev *hdev) 1095b9a6328fSJohan Hedberg { 1096b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1097b9a6328fSJohan Hedberg 1098b9a6328fSJohan Hedberg return bacmp(&d->last_adv_addr, BDADDR_ANY); 1099b9a6328fSJohan Hedberg } 1100b9a6328fSJohan Hedberg 1101b9a6328fSJohan Hedberg static void clear_pending_adv_report(struct hci_dev *hdev) 1102b9a6328fSJohan Hedberg { 1103b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1104b9a6328fSJohan Hedberg 1105b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, BDADDR_ANY); 1106b9a6328fSJohan Hedberg d->last_adv_data_len = 0; 1107b9a6328fSJohan Hedberg } 1108b9a6328fSJohan Hedberg 1109b9a6328fSJohan Hedberg static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr, 1110c70a7e4cSMarcel Holtmann u8 bdaddr_type, s8 rssi, u32 flags, 1111c70a7e4cSMarcel Holtmann u8 *data, u8 len) 1112b9a6328fSJohan Hedberg { 1113b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1114b9a6328fSJohan Hedberg 1115b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, bdaddr); 1116b9a6328fSJohan Hedberg d->last_adv_addr_type = bdaddr_type; 1117ff5cd29fSJohan Hedberg d->last_adv_rssi = rssi; 1118c70a7e4cSMarcel Holtmann d->last_adv_flags = flags; 1119b9a6328fSJohan Hedberg memcpy(d->last_adv_data, data, len); 1120b9a6328fSJohan Hedberg d->last_adv_data_len = len; 1121b9a6328fSJohan Hedberg } 1122b9a6328fSJohan Hedberg 1123eb9d91f5SAndre Guedes static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, 1124eb9d91f5SAndre Guedes struct sk_buff *skb) 1125eb9d91f5SAndre Guedes { 1126eb9d91f5SAndre Guedes struct hci_cp_le_set_scan_enable *cp; 1127eb9d91f5SAndre Guedes __u8 status = *((__u8 *) skb->data); 1128eb9d91f5SAndre Guedes 11299f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1130eb9d91f5SAndre Guedes 113145296acdSMarcel Holtmann if (status) 1132eb9d91f5SAndre Guedes return; 1133eb9d91f5SAndre Guedes 113445296acdSMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE); 113545296acdSMarcel Holtmann if (!cp) 11367ba8b4beSAndre Guedes return; 11377ba8b4beSAndre Guedes 11383fd319b8SAndre Guedes switch (cp->enable) { 11393fd319b8SAndre Guedes case LE_SCAN_ENABLE: 1140d23264a8SAndre Guedes set_bit(HCI_LE_SCAN, &hdev->dev_flags); 1141b9a6328fSJohan Hedberg if (hdev->le_scan_type == LE_SCAN_ACTIVE) 1142b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 114368a8aea4SAndrei Emeltchenko break; 114468a8aea4SAndrei Emeltchenko 114576a388beSAndre Guedes case LE_SCAN_DISABLE: 1146b9a6328fSJohan Hedberg /* We do this here instead of when setting DISCOVERY_STOPPED 1147b9a6328fSJohan Hedberg * since the latter would potentially require waiting for 1148b9a6328fSJohan Hedberg * inquiry to stop too. 1149b9a6328fSJohan Hedberg */ 1150b9a6328fSJohan Hedberg if (has_pending_adv_report(hdev)) { 1151b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1152b9a6328fSJohan Hedberg 1153b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 1154ab0aa433SJohan Hedberg d->last_adv_addr_type, NULL, 1155c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags, 1156ab0aa433SJohan Hedberg d->last_adv_data, 1157b9a6328fSJohan Hedberg d->last_adv_data_len, NULL, 0); 1158b9a6328fSJohan Hedberg } 1159b9a6328fSJohan Hedberg 1160317ac8cbSJohan Hedberg /* Cancel this timer so that we don't try to disable scanning 1161317ac8cbSJohan Hedberg * when it's already disabled. 1162317ac8cbSJohan Hedberg */ 1163317ac8cbSJohan Hedberg cancel_delayed_work(&hdev->le_scan_disable); 1164317ac8cbSJohan Hedberg 1165d23264a8SAndre Guedes clear_bit(HCI_LE_SCAN, &hdev->dev_flags); 1166e8bb6b97SJohan Hedberg 116781ad6fd9SJohan Hedberg /* The HCI_LE_SCAN_INTERRUPTED flag indicates that we 116881ad6fd9SJohan Hedberg * interrupted scanning due to a connect request. Mark 1169e8bb6b97SJohan Hedberg * therefore discovery as stopped. If this was not 1170e8bb6b97SJohan Hedberg * because of a connect request advertising might have 1171e8bb6b97SJohan Hedberg * been disabled because of active scanning, so 1172e8bb6b97SJohan Hedberg * re-enable it again if necessary. 117381ad6fd9SJohan Hedberg */ 117481ad6fd9SJohan Hedberg if (test_and_clear_bit(HCI_LE_SCAN_INTERRUPTED, 117581ad6fd9SJohan Hedberg &hdev->dev_flags)) 117681ad6fd9SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 1177e8bb6b97SJohan Hedberg else if (!test_bit(HCI_LE_ADV, &hdev->dev_flags) && 117834722277SJohan Hedberg hdev->discovery.state == DISCOVERY_FINDING) 1179e8bb6b97SJohan Hedberg mgmt_reenable_advertising(hdev); 1180e8bb6b97SJohan Hedberg 118168a8aea4SAndrei Emeltchenko break; 118268a8aea4SAndrei Emeltchenko 118368a8aea4SAndrei Emeltchenko default: 118468a8aea4SAndrei Emeltchenko BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable); 118568a8aea4SAndrei Emeltchenko break; 118635815085SAndre Guedes } 1187eb9d91f5SAndre Guedes } 1188eb9d91f5SAndre Guedes 1189cf1d081fSJohan Hedberg static void hci_cc_le_read_white_list_size(struct hci_dev *hdev, 1190cf1d081fSJohan Hedberg struct sk_buff *skb) 1191cf1d081fSJohan Hedberg { 1192cf1d081fSJohan Hedberg struct hci_rp_le_read_white_list_size *rp = (void *) skb->data; 1193cf1d081fSJohan Hedberg 1194cf1d081fSJohan Hedberg BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size); 1195cf1d081fSJohan Hedberg 119645296acdSMarcel Holtmann if (rp->status) 119745296acdSMarcel Holtmann return; 119845296acdSMarcel Holtmann 1199cf1d081fSJohan Hedberg hdev->le_white_list_size = rp->size; 1200cf1d081fSJohan Hedberg } 1201cf1d081fSJohan Hedberg 12020f36b589SMarcel Holtmann static void hci_cc_le_clear_white_list(struct hci_dev *hdev, 12030f36b589SMarcel Holtmann struct sk_buff *skb) 12040f36b589SMarcel Holtmann { 12050f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 12060f36b589SMarcel Holtmann 12070f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 12080f36b589SMarcel Holtmann 120945296acdSMarcel Holtmann if (status) 121045296acdSMarcel Holtmann return; 121145296acdSMarcel Holtmann 1212dcc36c16SJohan Hedberg hci_bdaddr_list_clear(&hdev->le_white_list); 12130f36b589SMarcel Holtmann } 12140f36b589SMarcel Holtmann 12150f36b589SMarcel Holtmann static void hci_cc_le_add_to_white_list(struct hci_dev *hdev, 12160f36b589SMarcel Holtmann struct sk_buff *skb) 12170f36b589SMarcel Holtmann { 12180f36b589SMarcel Holtmann struct hci_cp_le_add_to_white_list *sent; 12190f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 12200f36b589SMarcel Holtmann 12210f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 12220f36b589SMarcel Holtmann 122345296acdSMarcel Holtmann if (status) 122445296acdSMarcel Holtmann return; 122545296acdSMarcel Holtmann 12260f36b589SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST); 12270f36b589SMarcel Holtmann if (!sent) 12280f36b589SMarcel Holtmann return; 12290f36b589SMarcel Holtmann 1230dcc36c16SJohan Hedberg hci_bdaddr_list_add(&hdev->le_white_list, &sent->bdaddr, 1231dcc36c16SJohan Hedberg sent->bdaddr_type); 12320f36b589SMarcel Holtmann } 12330f36b589SMarcel Holtmann 12340f36b589SMarcel Holtmann static void hci_cc_le_del_from_white_list(struct hci_dev *hdev, 12350f36b589SMarcel Holtmann struct sk_buff *skb) 12360f36b589SMarcel Holtmann { 12370f36b589SMarcel Holtmann struct hci_cp_le_del_from_white_list *sent; 12380f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 12390f36b589SMarcel Holtmann 12400f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 12410f36b589SMarcel Holtmann 124245296acdSMarcel Holtmann if (status) 124345296acdSMarcel Holtmann return; 124445296acdSMarcel Holtmann 12450f36b589SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST); 12460f36b589SMarcel Holtmann if (!sent) 12470f36b589SMarcel Holtmann return; 12480f36b589SMarcel Holtmann 1249dcc36c16SJohan Hedberg hci_bdaddr_list_del(&hdev->le_white_list, &sent->bdaddr, 1250dcc36c16SJohan Hedberg sent->bdaddr_type); 12510f36b589SMarcel Holtmann } 12520f36b589SMarcel Holtmann 12539b008c04SJohan Hedberg static void hci_cc_le_read_supported_states(struct hci_dev *hdev, 12549b008c04SJohan Hedberg struct sk_buff *skb) 12559b008c04SJohan Hedberg { 12569b008c04SJohan Hedberg struct hci_rp_le_read_supported_states *rp = (void *) skb->data; 12579b008c04SJohan Hedberg 12589b008c04SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 12599b008c04SJohan Hedberg 126045296acdSMarcel Holtmann if (rp->status) 126145296acdSMarcel Holtmann return; 126245296acdSMarcel Holtmann 12639b008c04SJohan Hedberg memcpy(hdev->le_states, rp->le_states, 8); 12649b008c04SJohan Hedberg } 12659b008c04SJohan Hedberg 12666039aa73SGustavo Padovan static void hci_cc_write_le_host_supported(struct hci_dev *hdev, 1267f9b49306SAndre Guedes struct sk_buff *skb) 1268f9b49306SAndre Guedes { 126906199cf8SJohan Hedberg struct hci_cp_write_le_host_supported *sent; 1270f9b49306SAndre Guedes __u8 status = *((__u8 *) skb->data); 1271f9b49306SAndre Guedes 12729f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1273f9b49306SAndre Guedes 127445296acdSMarcel Holtmann if (status) 127545296acdSMarcel Holtmann return; 127645296acdSMarcel Holtmann 127706199cf8SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED); 12788f984dfaSJohan Hedberg if (!sent) 1279f9b49306SAndre Guedes return; 1280f9b49306SAndre Guedes 1281416a4ae5SJohan Hedberg if (sent->le) { 1282cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE; 1283416a4ae5SJohan Hedberg set_bit(HCI_LE_ENABLED, &hdev->dev_flags); 1284416a4ae5SJohan Hedberg } else { 1285cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE; 1286416a4ae5SJohan Hedberg clear_bit(HCI_LE_ENABLED, &hdev->dev_flags); 1287f3d3444aSJohan Hedberg clear_bit(HCI_ADVERTISING, &hdev->dev_flags); 1288416a4ae5SJohan Hedberg } 128953b2caabSJohan Hedberg 129053b2caabSJohan Hedberg if (sent->simul) 1291cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE_BREDR; 129253b2caabSJohan Hedberg else 1293cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE_BREDR; 12948f984dfaSJohan Hedberg } 1295f9b49306SAndre Guedes 129656ed2cb8SJohan Hedberg static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb) 129756ed2cb8SJohan Hedberg { 129856ed2cb8SJohan Hedberg struct hci_cp_le_set_adv_param *cp; 129956ed2cb8SJohan Hedberg u8 status = *((u8 *) skb->data); 130056ed2cb8SJohan Hedberg 130156ed2cb8SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 130256ed2cb8SJohan Hedberg 130356ed2cb8SJohan Hedberg if (status) 130456ed2cb8SJohan Hedberg return; 130556ed2cb8SJohan Hedberg 130656ed2cb8SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM); 130756ed2cb8SJohan Hedberg if (!cp) 130856ed2cb8SJohan Hedberg return; 130956ed2cb8SJohan Hedberg 131056ed2cb8SJohan Hedberg hci_dev_lock(hdev); 131156ed2cb8SJohan Hedberg hdev->adv_addr_type = cp->own_address_type; 131256ed2cb8SJohan Hedberg hci_dev_unlock(hdev); 131356ed2cb8SJohan Hedberg } 131456ed2cb8SJohan Hedberg 131593c284eeSAndrei Emeltchenko static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev, 131693c284eeSAndrei Emeltchenko struct sk_buff *skb) 131793c284eeSAndrei Emeltchenko { 131893c284eeSAndrei Emeltchenko struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data; 131993c284eeSAndrei Emeltchenko 132093c284eeSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x", 132193c284eeSAndrei Emeltchenko hdev->name, rp->status, rp->phy_handle); 132293c284eeSAndrei Emeltchenko 132393c284eeSAndrei Emeltchenko if (rp->status) 132493c284eeSAndrei Emeltchenko return; 132593c284eeSAndrei Emeltchenko 132693c284eeSAndrei Emeltchenko amp_write_rem_assoc_continue(hdev, rp->phy_handle); 132793c284eeSAndrei Emeltchenko } 132893c284eeSAndrei Emeltchenko 13295ae76a94SAndrzej Kaczmarek static void hci_cc_read_rssi(struct hci_dev *hdev, struct sk_buff *skb) 13305ae76a94SAndrzej Kaczmarek { 13315ae76a94SAndrzej Kaczmarek struct hci_rp_read_rssi *rp = (void *) skb->data; 13325ae76a94SAndrzej Kaczmarek struct hci_conn *conn; 13335ae76a94SAndrzej Kaczmarek 13345ae76a94SAndrzej Kaczmarek BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 13355ae76a94SAndrzej Kaczmarek 13365ae76a94SAndrzej Kaczmarek if (rp->status) 13375ae76a94SAndrzej Kaczmarek return; 13385ae76a94SAndrzej Kaczmarek 13395ae76a94SAndrzej Kaczmarek hci_dev_lock(hdev); 13405ae76a94SAndrzej Kaczmarek 13415ae76a94SAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 13425ae76a94SAndrzej Kaczmarek if (conn) 13435ae76a94SAndrzej Kaczmarek conn->rssi = rp->rssi; 13445ae76a94SAndrzej Kaczmarek 13455ae76a94SAndrzej Kaczmarek hci_dev_unlock(hdev); 13465ae76a94SAndrzej Kaczmarek } 13475ae76a94SAndrzej Kaczmarek 13485a134faeSAndrzej Kaczmarek static void hci_cc_read_tx_power(struct hci_dev *hdev, struct sk_buff *skb) 13495a134faeSAndrzej Kaczmarek { 13505a134faeSAndrzej Kaczmarek struct hci_cp_read_tx_power *sent; 13515a134faeSAndrzej Kaczmarek struct hci_rp_read_tx_power *rp = (void *) skb->data; 13525a134faeSAndrzej Kaczmarek struct hci_conn *conn; 13535a134faeSAndrzej Kaczmarek 13545a134faeSAndrzej Kaczmarek BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 13555a134faeSAndrzej Kaczmarek 13565a134faeSAndrzej Kaczmarek if (rp->status) 13575a134faeSAndrzej Kaczmarek return; 13585a134faeSAndrzej Kaczmarek 13595a134faeSAndrzej Kaczmarek sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER); 13605a134faeSAndrzej Kaczmarek if (!sent) 13615a134faeSAndrzej Kaczmarek return; 13625a134faeSAndrzej Kaczmarek 13635a134faeSAndrzej Kaczmarek hci_dev_lock(hdev); 13645a134faeSAndrzej Kaczmarek 13655a134faeSAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 1366d0455ed9SAndrzej Kaczmarek if (!conn) 1367d0455ed9SAndrzej Kaczmarek goto unlock; 13685a134faeSAndrzej Kaczmarek 1369d0455ed9SAndrzej Kaczmarek switch (sent->type) { 1370d0455ed9SAndrzej Kaczmarek case 0x00: 1371d0455ed9SAndrzej Kaczmarek conn->tx_power = rp->tx_power; 1372d0455ed9SAndrzej Kaczmarek break; 1373d0455ed9SAndrzej Kaczmarek case 0x01: 1374d0455ed9SAndrzej Kaczmarek conn->max_tx_power = rp->tx_power; 1375d0455ed9SAndrzej Kaczmarek break; 1376d0455ed9SAndrzej Kaczmarek } 1377d0455ed9SAndrzej Kaczmarek 1378d0455ed9SAndrzej Kaczmarek unlock: 13795a134faeSAndrzej Kaczmarek hci_dev_unlock(hdev); 13805a134faeSAndrzej Kaczmarek } 13815a134faeSAndrzej Kaczmarek 13826039aa73SGustavo Padovan static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) 1383a9de9248SMarcel Holtmann { 13849f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1385a9de9248SMarcel Holtmann 1386a9de9248SMarcel Holtmann if (status) { 1387a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 1388314b2381SJohan Hedberg return; 1389314b2381SJohan Hedberg } 1390314b2381SJohan Hedberg 139189352e7dSAndre Guedes set_bit(HCI_INQUIRY, &hdev->flags); 1392a9de9248SMarcel Holtmann } 1393a9de9248SMarcel Holtmann 13946039aa73SGustavo Padovan static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) 13951da177e4SLinus Torvalds { 1396a9de9248SMarcel Holtmann struct hci_cp_create_conn *cp; 13971da177e4SLinus Torvalds struct hci_conn *conn; 13981da177e4SLinus Torvalds 13999f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1400a9de9248SMarcel Holtmann 1401a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN); 14021da177e4SLinus Torvalds if (!cp) 14031da177e4SLinus Torvalds return; 14041da177e4SLinus Torvalds 14051da177e4SLinus Torvalds hci_dev_lock(hdev); 14061da177e4SLinus Torvalds 14071da177e4SLinus Torvalds conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 14081da177e4SLinus Torvalds 14096ed93dc6SAndrei Emeltchenko BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn); 14101da177e4SLinus Torvalds 14111da177e4SLinus Torvalds if (status) { 14121da177e4SLinus Torvalds if (conn && conn->state == BT_CONNECT) { 14134c67bc74SMarcel Holtmann if (status != 0x0c || conn->attempt > 2) { 14141da177e4SLinus Torvalds conn->state = BT_CLOSED; 14151da177e4SLinus Torvalds hci_proto_connect_cfm(conn, status); 14161da177e4SLinus Torvalds hci_conn_del(conn); 14174c67bc74SMarcel Holtmann } else 14184c67bc74SMarcel Holtmann conn->state = BT_CONNECT2; 14191da177e4SLinus Torvalds } 14201da177e4SLinus Torvalds } else { 14211da177e4SLinus Torvalds if (!conn) { 1422a5c4e309SJohan Hedberg conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr, 1423a5c4e309SJohan Hedberg HCI_ROLE_MASTER); 1424a5c4e309SJohan Hedberg if (!conn) 1425893ef971SGustavo F. Padovan BT_ERR("No memory for new connection"); 14261da177e4SLinus Torvalds } 14271da177e4SLinus Torvalds } 14281da177e4SLinus Torvalds 14291da177e4SLinus Torvalds hci_dev_unlock(hdev); 14301da177e4SLinus Torvalds } 14311da177e4SLinus Torvalds 1432a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status) 14331da177e4SLinus Torvalds { 1434a9de9248SMarcel Holtmann struct hci_cp_add_sco *cp; 14351da177e4SLinus Torvalds struct hci_conn *acl, *sco; 14361da177e4SLinus Torvalds __u16 handle; 14371da177e4SLinus Torvalds 14389f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1439b6a0dc82SMarcel Holtmann 1440a9de9248SMarcel Holtmann if (!status) 1441a9de9248SMarcel Holtmann return; 1442a9de9248SMarcel Holtmann 1443a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO); 14441da177e4SLinus Torvalds if (!cp) 1445a9de9248SMarcel Holtmann return; 14461da177e4SLinus Torvalds 14471da177e4SLinus Torvalds handle = __le16_to_cpu(cp->handle); 14481da177e4SLinus Torvalds 14499f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, handle); 14501da177e4SLinus Torvalds 14511da177e4SLinus Torvalds hci_dev_lock(hdev); 14521da177e4SLinus Torvalds 14531da177e4SLinus Torvalds acl = hci_conn_hash_lookup_handle(hdev, handle); 14545a08ecceSAndrei Emeltchenko if (acl) { 14555a08ecceSAndrei Emeltchenko sco = acl->link; 14565a08ecceSAndrei Emeltchenko if (sco) { 14571da177e4SLinus Torvalds sco->state = BT_CLOSED; 14581da177e4SLinus Torvalds 14591da177e4SLinus Torvalds hci_proto_connect_cfm(sco, status); 14601da177e4SLinus Torvalds hci_conn_del(sco); 14611da177e4SLinus Torvalds } 14625a08ecceSAndrei Emeltchenko } 14631da177e4SLinus Torvalds 14641da177e4SLinus Torvalds hci_dev_unlock(hdev); 14651da177e4SLinus Torvalds } 14661da177e4SLinus Torvalds 1467f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status) 1468f8558555SMarcel Holtmann { 1469f8558555SMarcel Holtmann struct hci_cp_auth_requested *cp; 1470f8558555SMarcel Holtmann struct hci_conn *conn; 1471f8558555SMarcel Holtmann 14729f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1473f8558555SMarcel Holtmann 1474f8558555SMarcel Holtmann if (!status) 1475f8558555SMarcel Holtmann return; 1476f8558555SMarcel Holtmann 1477f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED); 1478f8558555SMarcel Holtmann if (!cp) 1479f8558555SMarcel Holtmann return; 1480f8558555SMarcel Holtmann 1481f8558555SMarcel Holtmann hci_dev_lock(hdev); 1482f8558555SMarcel Holtmann 1483f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1484f8558555SMarcel Holtmann if (conn) { 1485f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1486f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, status); 148776a68ba0SDavid Herrmann hci_conn_drop(conn); 1488f8558555SMarcel Holtmann } 1489f8558555SMarcel Holtmann } 1490f8558555SMarcel Holtmann 1491f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1492f8558555SMarcel Holtmann } 1493f8558555SMarcel Holtmann 1494f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) 1495f8558555SMarcel Holtmann { 1496f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt *cp; 1497f8558555SMarcel Holtmann struct hci_conn *conn; 1498f8558555SMarcel Holtmann 14999f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1500f8558555SMarcel Holtmann 1501f8558555SMarcel Holtmann if (!status) 1502f8558555SMarcel Holtmann return; 1503f8558555SMarcel Holtmann 1504f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT); 1505f8558555SMarcel Holtmann if (!cp) 1506f8558555SMarcel Holtmann return; 1507f8558555SMarcel Holtmann 1508f8558555SMarcel Holtmann hci_dev_lock(hdev); 1509f8558555SMarcel Holtmann 1510f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1511f8558555SMarcel Holtmann if (conn) { 1512f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1513f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, status); 151476a68ba0SDavid Herrmann hci_conn_drop(conn); 1515f8558555SMarcel Holtmann } 1516f8558555SMarcel Holtmann } 1517f8558555SMarcel Holtmann 1518f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1519f8558555SMarcel Holtmann } 1520f8558555SMarcel Holtmann 1521127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev, 1522392599b9SJohan Hedberg struct hci_conn *conn) 1523392599b9SJohan Hedberg { 1524392599b9SJohan Hedberg if (conn->state != BT_CONFIG || !conn->out) 1525392599b9SJohan Hedberg return 0; 1526392599b9SJohan Hedberg 1527765c2a96SJohan Hedberg if (conn->pending_sec_level == BT_SECURITY_SDP) 1528392599b9SJohan Hedberg return 0; 1529392599b9SJohan Hedberg 1530392599b9SJohan Hedberg /* Only request authentication for SSP connections or non-SSP 1531264b8b4eSJohan Hedberg * devices with sec_level MEDIUM or HIGH or if MITM protection 1532264b8b4eSJohan Hedberg * is requested. 1533264b8b4eSJohan Hedberg */ 1534807deac2SGustavo Padovan if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) && 15357e3691e1SJohan Hedberg conn->pending_sec_level != BT_SECURITY_FIPS && 1536264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_HIGH && 1537264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_MEDIUM) 1538392599b9SJohan Hedberg return 0; 1539392599b9SJohan Hedberg 1540392599b9SJohan Hedberg return 1; 1541392599b9SJohan Hedberg } 1542392599b9SJohan Hedberg 15436039aa73SGustavo Padovan static int hci_resolve_name(struct hci_dev *hdev, 154400abfe44SGustavo F. Padovan struct inquiry_entry *e) 154530dc78e1SJohan Hedberg { 154630dc78e1SJohan Hedberg struct hci_cp_remote_name_req cp; 154730dc78e1SJohan Hedberg 154830dc78e1SJohan Hedberg memset(&cp, 0, sizeof(cp)); 154930dc78e1SJohan Hedberg 155030dc78e1SJohan Hedberg bacpy(&cp.bdaddr, &e->data.bdaddr); 155130dc78e1SJohan Hedberg cp.pscan_rep_mode = e->data.pscan_rep_mode; 155230dc78e1SJohan Hedberg cp.pscan_mode = e->data.pscan_mode; 155330dc78e1SJohan Hedberg cp.clock_offset = e->data.clock_offset; 155430dc78e1SJohan Hedberg 155530dc78e1SJohan Hedberg return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 155630dc78e1SJohan Hedberg } 155730dc78e1SJohan Hedberg 1558b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev) 155930dc78e1SJohan Hedberg { 156030dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 156130dc78e1SJohan Hedberg struct inquiry_entry *e; 156230dc78e1SJohan Hedberg 1563b644ba33SJohan Hedberg if (list_empty(&discov->resolve)) 1564b644ba33SJohan Hedberg return false; 1565b644ba33SJohan Hedberg 1566b644ba33SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 1567c810089cSRam Malovany if (!e) 1568c810089cSRam Malovany return false; 1569c810089cSRam Malovany 1570b644ba33SJohan Hedberg if (hci_resolve_name(hdev, e) == 0) { 1571b644ba33SJohan Hedberg e->name_state = NAME_PENDING; 1572b644ba33SJohan Hedberg return true; 1573b644ba33SJohan Hedberg } 1574b644ba33SJohan Hedberg 1575b644ba33SJohan Hedberg return false; 1576b644ba33SJohan Hedberg } 1577b644ba33SJohan Hedberg 1578b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, 1579b644ba33SJohan Hedberg bdaddr_t *bdaddr, u8 *name, u8 name_len) 1580b644ba33SJohan Hedberg { 1581b644ba33SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 1582b644ba33SJohan Hedberg struct inquiry_entry *e; 1583b644ba33SJohan Hedberg 1584b644ba33SJohan Hedberg if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 158548ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, name, name_len); 1586b644ba33SJohan Hedberg 1587b644ba33SJohan Hedberg if (discov->state == DISCOVERY_STOPPED) 1588b644ba33SJohan Hedberg return; 1589b644ba33SJohan Hedberg 159030dc78e1SJohan Hedberg if (discov->state == DISCOVERY_STOPPING) 159130dc78e1SJohan Hedberg goto discov_complete; 159230dc78e1SJohan Hedberg 159330dc78e1SJohan Hedberg if (discov->state != DISCOVERY_RESOLVING) 159430dc78e1SJohan Hedberg return; 159530dc78e1SJohan Hedberg 159630dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING); 15977cc8380eSRam Malovany /* If the device was not found in a list of found devices names of which 15987cc8380eSRam Malovany * are pending. there is no need to continue resolving a next name as it 15997cc8380eSRam Malovany * will be done upon receiving another Remote Name Request Complete 16007cc8380eSRam Malovany * Event */ 16017cc8380eSRam Malovany if (!e) 16027cc8380eSRam Malovany return; 16037cc8380eSRam Malovany 160430dc78e1SJohan Hedberg list_del(&e->list); 16057cc8380eSRam Malovany if (name) { 16067cc8380eSRam Malovany e->name_state = NAME_KNOWN; 1607b644ba33SJohan Hedberg mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, 1608b644ba33SJohan Hedberg e->data.rssi, name, name_len); 1609c3e7c0d9SRam Malovany } else { 1610c3e7c0d9SRam Malovany e->name_state = NAME_NOT_KNOWN; 161130dc78e1SJohan Hedberg } 161230dc78e1SJohan Hedberg 1613b644ba33SJohan Hedberg if (hci_resolve_next_name(hdev)) 161430dc78e1SJohan Hedberg return; 161530dc78e1SJohan Hedberg 161630dc78e1SJohan Hedberg discov_complete: 161730dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 161830dc78e1SJohan Hedberg } 161930dc78e1SJohan Hedberg 1620a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) 16211da177e4SLinus Torvalds { 1622127178d2SJohan Hedberg struct hci_cp_remote_name_req *cp; 1623127178d2SJohan Hedberg struct hci_conn *conn; 1624127178d2SJohan Hedberg 16259f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1626127178d2SJohan Hedberg 1627127178d2SJohan Hedberg /* If successful wait for the name req complete event before 1628127178d2SJohan Hedberg * checking for the need to do authentication */ 1629127178d2SJohan Hedberg if (!status) 1630127178d2SJohan Hedberg return; 1631127178d2SJohan Hedberg 1632127178d2SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ); 1633127178d2SJohan Hedberg if (!cp) 1634127178d2SJohan Hedberg return; 1635127178d2SJohan Hedberg 1636127178d2SJohan Hedberg hci_dev_lock(hdev); 1637127178d2SJohan Hedberg 1638127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 1639b644ba33SJohan Hedberg 1640b644ba33SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 1641b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0); 1642b644ba33SJohan Hedberg 164379c6c70cSJohan Hedberg if (!conn) 164479c6c70cSJohan Hedberg goto unlock; 164579c6c70cSJohan Hedberg 164679c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 164779c6c70cSJohan Hedberg goto unlock; 164879c6c70cSJohan Hedberg 164951a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 1650c1f23a2bSJohannes Berg struct hci_cp_auth_requested auth_cp; 1651c1f23a2bSJohannes Berg 1652977f8fceSJohan Hedberg set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags); 1653977f8fceSJohan Hedberg 1654c1f23a2bSJohannes Berg auth_cp.handle = __cpu_to_le16(conn->handle); 1655c1f23a2bSJohannes Berg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, 1656c1f23a2bSJohannes Berg sizeof(auth_cp), &auth_cp); 1657127178d2SJohan Hedberg } 1658127178d2SJohan Hedberg 165979c6c70cSJohan Hedberg unlock: 1660127178d2SJohan Hedberg hci_dev_unlock(hdev); 1661a9de9248SMarcel Holtmann } 16621da177e4SLinus Torvalds 1663769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) 1664769be974SMarcel Holtmann { 1665769be974SMarcel Holtmann struct hci_cp_read_remote_features *cp; 1666769be974SMarcel Holtmann struct hci_conn *conn; 1667769be974SMarcel Holtmann 16689f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1669769be974SMarcel Holtmann 1670769be974SMarcel Holtmann if (!status) 1671769be974SMarcel Holtmann return; 1672769be974SMarcel Holtmann 1673769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES); 1674769be974SMarcel Holtmann if (!cp) 1675769be974SMarcel Holtmann return; 1676769be974SMarcel Holtmann 1677769be974SMarcel Holtmann hci_dev_lock(hdev); 1678769be974SMarcel Holtmann 1679769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1680769be974SMarcel Holtmann if (conn) { 1681769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1682769be974SMarcel Holtmann hci_proto_connect_cfm(conn, status); 168376a68ba0SDavid Herrmann hci_conn_drop(conn); 1684769be974SMarcel Holtmann } 1685769be974SMarcel Holtmann } 1686769be974SMarcel Holtmann 1687769be974SMarcel Holtmann hci_dev_unlock(hdev); 1688769be974SMarcel Holtmann } 1689769be974SMarcel Holtmann 1690769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status) 1691769be974SMarcel Holtmann { 1692769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features *cp; 1693769be974SMarcel Holtmann struct hci_conn *conn; 1694769be974SMarcel Holtmann 16959f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1696769be974SMarcel Holtmann 1697769be974SMarcel Holtmann if (!status) 1698769be974SMarcel Holtmann return; 1699769be974SMarcel Holtmann 1700769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES); 1701769be974SMarcel Holtmann if (!cp) 1702769be974SMarcel Holtmann return; 1703769be974SMarcel Holtmann 1704769be974SMarcel Holtmann hci_dev_lock(hdev); 1705769be974SMarcel Holtmann 1706769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1707769be974SMarcel Holtmann if (conn) { 1708769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1709769be974SMarcel Holtmann hci_proto_connect_cfm(conn, status); 171076a68ba0SDavid Herrmann hci_conn_drop(conn); 1711769be974SMarcel Holtmann } 1712769be974SMarcel Holtmann } 1713769be974SMarcel Holtmann 1714769be974SMarcel Holtmann hci_dev_unlock(hdev); 1715769be974SMarcel Holtmann } 1716769be974SMarcel Holtmann 1717a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) 1718a9de9248SMarcel Holtmann { 1719b6a0dc82SMarcel Holtmann struct hci_cp_setup_sync_conn *cp; 1720b6a0dc82SMarcel Holtmann struct hci_conn *acl, *sco; 1721b6a0dc82SMarcel Holtmann __u16 handle; 1722b6a0dc82SMarcel Holtmann 17239f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1724b6a0dc82SMarcel Holtmann 1725b6a0dc82SMarcel Holtmann if (!status) 1726b6a0dc82SMarcel Holtmann return; 1727b6a0dc82SMarcel Holtmann 1728b6a0dc82SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN); 1729b6a0dc82SMarcel Holtmann if (!cp) 1730b6a0dc82SMarcel Holtmann return; 1731b6a0dc82SMarcel Holtmann 1732b6a0dc82SMarcel Holtmann handle = __le16_to_cpu(cp->handle); 1733b6a0dc82SMarcel Holtmann 17349f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, handle); 1735b6a0dc82SMarcel Holtmann 1736b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 1737b6a0dc82SMarcel Holtmann 1738b6a0dc82SMarcel Holtmann acl = hci_conn_hash_lookup_handle(hdev, handle); 17395a08ecceSAndrei Emeltchenko if (acl) { 17405a08ecceSAndrei Emeltchenko sco = acl->link; 17415a08ecceSAndrei Emeltchenko if (sco) { 1742b6a0dc82SMarcel Holtmann sco->state = BT_CLOSED; 1743b6a0dc82SMarcel Holtmann 1744b6a0dc82SMarcel Holtmann hci_proto_connect_cfm(sco, status); 1745b6a0dc82SMarcel Holtmann hci_conn_del(sco); 1746b6a0dc82SMarcel Holtmann } 17475a08ecceSAndrei Emeltchenko } 1748b6a0dc82SMarcel Holtmann 1749b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 1750a9de9248SMarcel Holtmann } 1751a9de9248SMarcel Holtmann 1752a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) 1753a9de9248SMarcel Holtmann { 1754a9de9248SMarcel Holtmann struct hci_cp_sniff_mode *cp; 175504837f64SMarcel Holtmann struct hci_conn *conn; 175604837f64SMarcel Holtmann 17579f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1758a9de9248SMarcel Holtmann 1759a9de9248SMarcel Holtmann if (!status) 1760a9de9248SMarcel Holtmann return; 1761a9de9248SMarcel Holtmann 1762a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE); 176304837f64SMarcel Holtmann if (!cp) 1764a9de9248SMarcel Holtmann return; 176504837f64SMarcel Holtmann 176604837f64SMarcel Holtmann hci_dev_lock(hdev); 176704837f64SMarcel Holtmann 176804837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1769e73439d8SMarcel Holtmann if (conn) { 177051a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 177104837f64SMarcel Holtmann 177251a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 1773e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 1774e73439d8SMarcel Holtmann } 1775e73439d8SMarcel Holtmann 177604837f64SMarcel Holtmann hci_dev_unlock(hdev); 177704837f64SMarcel Holtmann } 177804837f64SMarcel Holtmann 1779a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) 1780a9de9248SMarcel Holtmann { 1781a9de9248SMarcel Holtmann struct hci_cp_exit_sniff_mode *cp; 178204837f64SMarcel Holtmann struct hci_conn *conn; 178304837f64SMarcel Holtmann 17849f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1785a9de9248SMarcel Holtmann 1786a9de9248SMarcel Holtmann if (!status) 1787a9de9248SMarcel Holtmann return; 1788a9de9248SMarcel Holtmann 1789a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE); 179004837f64SMarcel Holtmann if (!cp) 1791a9de9248SMarcel Holtmann return; 179204837f64SMarcel Holtmann 179304837f64SMarcel Holtmann hci_dev_lock(hdev); 179404837f64SMarcel Holtmann 179504837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1796e73439d8SMarcel Holtmann if (conn) { 179751a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 179804837f64SMarcel Holtmann 179951a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 1800e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 1801e73439d8SMarcel Holtmann } 1802e73439d8SMarcel Holtmann 180304837f64SMarcel Holtmann hci_dev_unlock(hdev); 180404837f64SMarcel Holtmann } 180504837f64SMarcel Holtmann 180688c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) 180788c3df13SJohan Hedberg { 180888c3df13SJohan Hedberg struct hci_cp_disconnect *cp; 180988c3df13SJohan Hedberg struct hci_conn *conn; 181088c3df13SJohan Hedberg 181188c3df13SJohan Hedberg if (!status) 181288c3df13SJohan Hedberg return; 181388c3df13SJohan Hedberg 181488c3df13SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT); 181588c3df13SJohan Hedberg if (!cp) 181688c3df13SJohan Hedberg return; 181788c3df13SJohan Hedberg 181888c3df13SJohan Hedberg hci_dev_lock(hdev); 181988c3df13SJohan Hedberg 182088c3df13SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 182188c3df13SJohan Hedberg if (conn) 182288c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 182388c3df13SJohan Hedberg conn->dst_type, status); 182488c3df13SJohan Hedberg 182588c3df13SJohan Hedberg hci_dev_unlock(hdev); 182688c3df13SJohan Hedberg } 182788c3df13SJohan Hedberg 1828a02226d6SAndrei Emeltchenko static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status) 1829a02226d6SAndrei Emeltchenko { 183093c284eeSAndrei Emeltchenko struct hci_cp_create_phy_link *cp; 183193c284eeSAndrei Emeltchenko 1832a02226d6SAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 183393c284eeSAndrei Emeltchenko 183493c284eeSAndrei Emeltchenko cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK); 183593c284eeSAndrei Emeltchenko if (!cp) 183693c284eeSAndrei Emeltchenko return; 183793c284eeSAndrei Emeltchenko 1838e58917b9SAndrei Emeltchenko hci_dev_lock(hdev); 1839e58917b9SAndrei Emeltchenko 1840e58917b9SAndrei Emeltchenko if (status) { 1841e58917b9SAndrei Emeltchenko struct hci_conn *hcon; 1842e58917b9SAndrei Emeltchenko 1843e58917b9SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle); 1844e58917b9SAndrei Emeltchenko if (hcon) 1845e58917b9SAndrei Emeltchenko hci_conn_del(hcon); 1846e58917b9SAndrei Emeltchenko } else { 184793c284eeSAndrei Emeltchenko amp_write_remote_assoc(hdev, cp->phy_handle); 1848a02226d6SAndrei Emeltchenko } 1849a02226d6SAndrei Emeltchenko 1850e58917b9SAndrei Emeltchenko hci_dev_unlock(hdev); 1851e58917b9SAndrei Emeltchenko } 1852e58917b9SAndrei Emeltchenko 18530b26ab9dSAndrei Emeltchenko static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status) 18540b26ab9dSAndrei Emeltchenko { 18550b26ab9dSAndrei Emeltchenko struct hci_cp_accept_phy_link *cp; 18560b26ab9dSAndrei Emeltchenko 18570b26ab9dSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 18580b26ab9dSAndrei Emeltchenko 18590b26ab9dSAndrei Emeltchenko if (status) 18600b26ab9dSAndrei Emeltchenko return; 18610b26ab9dSAndrei Emeltchenko 18620b26ab9dSAndrei Emeltchenko cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK); 18630b26ab9dSAndrei Emeltchenko if (!cp) 18640b26ab9dSAndrei Emeltchenko return; 18650b26ab9dSAndrei Emeltchenko 18660b26ab9dSAndrei Emeltchenko amp_write_remote_assoc(hdev, cp->phy_handle); 18670b26ab9dSAndrei Emeltchenko } 18680b26ab9dSAndrei Emeltchenko 1869cb1d68f7SJohan Hedberg static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status) 1870cb1d68f7SJohan Hedberg { 1871cb1d68f7SJohan Hedberg struct hci_cp_le_create_conn *cp; 1872cb1d68f7SJohan Hedberg struct hci_conn *conn; 1873cb1d68f7SJohan Hedberg 1874cb1d68f7SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 1875cb1d68f7SJohan Hedberg 1876cb1d68f7SJohan Hedberg /* All connection failure handling is taken care of by the 1877cb1d68f7SJohan Hedberg * hci_le_conn_failed function which is triggered by the HCI 1878cb1d68f7SJohan Hedberg * request completion callbacks used for connecting. 1879cb1d68f7SJohan Hedberg */ 1880cb1d68f7SJohan Hedberg if (status) 1881cb1d68f7SJohan Hedberg return; 1882cb1d68f7SJohan Hedberg 1883cb1d68f7SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN); 1884cb1d68f7SJohan Hedberg if (!cp) 1885cb1d68f7SJohan Hedberg return; 1886cb1d68f7SJohan Hedberg 1887cb1d68f7SJohan Hedberg hci_dev_lock(hdev); 1888cb1d68f7SJohan Hedberg 1889cb1d68f7SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr); 1890cb1d68f7SJohan Hedberg if (!conn) 1891cb1d68f7SJohan Hedberg goto unlock; 1892cb1d68f7SJohan Hedberg 1893cb1d68f7SJohan Hedberg /* Store the initiator and responder address information which 1894cb1d68f7SJohan Hedberg * is needed for SMP. These values will not change during the 1895cb1d68f7SJohan Hedberg * lifetime of the connection. 1896cb1d68f7SJohan Hedberg */ 1897cb1d68f7SJohan Hedberg conn->init_addr_type = cp->own_address_type; 1898cb1d68f7SJohan Hedberg if (cp->own_address_type == ADDR_LE_DEV_RANDOM) 1899cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->random_addr); 1900cb1d68f7SJohan Hedberg else 1901cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->bdaddr); 1902cb1d68f7SJohan Hedberg 1903cb1d68f7SJohan Hedberg conn->resp_addr_type = cp->peer_addr_type; 1904cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &cp->peer_addr); 1905cb1d68f7SJohan Hedberg 19069489eca4SJohan Hedberg /* We don't want the connection attempt to stick around 19079489eca4SJohan Hedberg * indefinitely since LE doesn't have a page timeout concept 19089489eca4SJohan Hedberg * like BR/EDR. Set a timer for any connection that doesn't use 19099489eca4SJohan Hedberg * the white list for connecting. 19109489eca4SJohan Hedberg */ 19119489eca4SJohan Hedberg if (cp->filter_policy == HCI_LE_USE_PEER_ADDR) 19129489eca4SJohan Hedberg queue_delayed_work(conn->hdev->workqueue, 19139489eca4SJohan Hedberg &conn->le_conn_timeout, 191409ae260bSJohan Hedberg conn->conn_timeout); 19159489eca4SJohan Hedberg 1916cb1d68f7SJohan Hedberg unlock: 1917cb1d68f7SJohan Hedberg hci_dev_unlock(hdev); 1918cb1d68f7SJohan Hedberg } 1919cb1d68f7SJohan Hedberg 192081d0c8adSJohan Hedberg static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) 192181d0c8adSJohan Hedberg { 192281d0c8adSJohan Hedberg struct hci_cp_le_start_enc *cp; 192381d0c8adSJohan Hedberg struct hci_conn *conn; 192481d0c8adSJohan Hedberg 192581d0c8adSJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 192681d0c8adSJohan Hedberg 192781d0c8adSJohan Hedberg if (!status) 192881d0c8adSJohan Hedberg return; 192981d0c8adSJohan Hedberg 193081d0c8adSJohan Hedberg hci_dev_lock(hdev); 193181d0c8adSJohan Hedberg 193281d0c8adSJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC); 193381d0c8adSJohan Hedberg if (!cp) 193481d0c8adSJohan Hedberg goto unlock; 193581d0c8adSJohan Hedberg 193681d0c8adSJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 193781d0c8adSJohan Hedberg if (!conn) 193881d0c8adSJohan Hedberg goto unlock; 193981d0c8adSJohan Hedberg 194081d0c8adSJohan Hedberg if (conn->state != BT_CONNECTED) 194181d0c8adSJohan Hedberg goto unlock; 194281d0c8adSJohan Hedberg 194381d0c8adSJohan Hedberg hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 194481d0c8adSJohan Hedberg hci_conn_drop(conn); 194581d0c8adSJohan Hedberg 194681d0c8adSJohan Hedberg unlock: 194781d0c8adSJohan Hedberg hci_dev_unlock(hdev); 194881d0c8adSJohan Hedberg } 194981d0c8adSJohan Hedberg 195050fc85f1SKuba Pawlak static void hci_cs_switch_role(struct hci_dev *hdev, u8 status) 195150fc85f1SKuba Pawlak { 195250fc85f1SKuba Pawlak struct hci_cp_switch_role *cp; 195350fc85f1SKuba Pawlak struct hci_conn *conn; 195450fc85f1SKuba Pawlak 195550fc85f1SKuba Pawlak BT_DBG("%s status 0x%2.2x", hdev->name, status); 195650fc85f1SKuba Pawlak 195750fc85f1SKuba Pawlak if (!status) 195850fc85f1SKuba Pawlak return; 195950fc85f1SKuba Pawlak 196050fc85f1SKuba Pawlak cp = hci_sent_cmd_data(hdev, HCI_OP_SWITCH_ROLE); 196150fc85f1SKuba Pawlak if (!cp) 196250fc85f1SKuba Pawlak return; 196350fc85f1SKuba Pawlak 196450fc85f1SKuba Pawlak hci_dev_lock(hdev); 196550fc85f1SKuba Pawlak 196650fc85f1SKuba Pawlak conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 196750fc85f1SKuba Pawlak if (conn) 196850fc85f1SKuba Pawlak clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 196950fc85f1SKuba Pawlak 197050fc85f1SKuba Pawlak hci_dev_unlock(hdev); 197150fc85f1SKuba Pawlak } 197250fc85f1SKuba Pawlak 19736039aa73SGustavo Padovan static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 19741da177e4SLinus Torvalds { 19751da177e4SLinus Torvalds __u8 status = *((__u8 *) skb->data); 197630dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 197730dc78e1SJohan Hedberg struct inquiry_entry *e; 19781da177e4SLinus Torvalds 19799f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 19801da177e4SLinus Torvalds 1981a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 198289352e7dSAndre Guedes 198389352e7dSAndre Guedes if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) 198489352e7dSAndre Guedes return; 198589352e7dSAndre Guedes 19864e857c58SPeter Zijlstra smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */ 19873e13fa1eSAndre Guedes wake_up_bit(&hdev->flags, HCI_INQUIRY); 19883e13fa1eSAndre Guedes 1989a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 199030dc78e1SJohan Hedberg return; 199130dc78e1SJohan Hedberg 199256e5cb86SJohan Hedberg hci_dev_lock(hdev); 199330dc78e1SJohan Hedberg 1994343f935bSAndre Guedes if (discov->state != DISCOVERY_FINDING) 199530dc78e1SJohan Hedberg goto unlock; 199630dc78e1SJohan Hedberg 199730dc78e1SJohan Hedberg if (list_empty(&discov->resolve)) { 1998ff9ef578SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 199930dc78e1SJohan Hedberg goto unlock; 200030dc78e1SJohan Hedberg } 200130dc78e1SJohan Hedberg 200230dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 200330dc78e1SJohan Hedberg if (e && hci_resolve_name(hdev, e) == 0) { 200430dc78e1SJohan Hedberg e->name_state = NAME_PENDING; 200530dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_RESOLVING); 200630dc78e1SJohan Hedberg } else { 200730dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 200830dc78e1SJohan Hedberg } 200930dc78e1SJohan Hedberg 201030dc78e1SJohan Hedberg unlock: 201156e5cb86SJohan Hedberg hci_dev_unlock(hdev); 20121da177e4SLinus Torvalds } 20131da177e4SLinus Torvalds 20146039aa73SGustavo Padovan static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) 20151da177e4SLinus Torvalds { 201645bb4bf0SMarcel Holtmann struct inquiry_data data; 2017a9de9248SMarcel Holtmann struct inquiry_info *info = (void *) (skb->data + 1); 20181da177e4SLinus Torvalds int num_rsp = *((__u8 *) skb->data); 20191da177e4SLinus Torvalds 20201da177e4SLinus Torvalds BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 20211da177e4SLinus Torvalds 202245bb4bf0SMarcel Holtmann if (!num_rsp) 202345bb4bf0SMarcel Holtmann return; 202445bb4bf0SMarcel Holtmann 20251519cc17SAndre Guedes if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) 20261519cc17SAndre Guedes return; 20271519cc17SAndre Guedes 20281da177e4SLinus Torvalds hci_dev_lock(hdev); 202945bb4bf0SMarcel Holtmann 2030e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 2031af58925cSMarcel Holtmann u32 flags; 20323175405bSJohan Hedberg 20331da177e4SLinus Torvalds bacpy(&data.bdaddr, &info->bdaddr); 20341da177e4SLinus Torvalds data.pscan_rep_mode = info->pscan_rep_mode; 20351da177e4SLinus Torvalds data.pscan_period_mode = info->pscan_period_mode; 20361da177e4SLinus Torvalds data.pscan_mode = info->pscan_mode; 20371da177e4SLinus Torvalds memcpy(data.dev_class, info->dev_class, 3); 20381da177e4SLinus Torvalds data.clock_offset = info->clock_offset; 20391da177e4SLinus Torvalds data.rssi = 0x00; 204041a96212SMarcel Holtmann data.ssp_mode = 0x00; 20413175405bSJohan Hedberg 2042af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 2043af58925cSMarcel Holtmann 204448264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 2045af58925cSMarcel Holtmann info->dev_class, 0, flags, NULL, 0, NULL, 0); 20461da177e4SLinus Torvalds } 204745bb4bf0SMarcel Holtmann 20481da177e4SLinus Torvalds hci_dev_unlock(hdev); 20491da177e4SLinus Torvalds } 20501da177e4SLinus Torvalds 20516039aa73SGustavo Padovan static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 20521da177e4SLinus Torvalds { 2053a9de9248SMarcel Holtmann struct hci_ev_conn_complete *ev = (void *) skb->data; 2054a9de9248SMarcel Holtmann struct hci_conn *conn; 20551da177e4SLinus Torvalds 2056a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 205745bb4bf0SMarcel Holtmann 20581da177e4SLinus Torvalds hci_dev_lock(hdev); 205945bb4bf0SMarcel Holtmann 2060a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 20619499237aSMarcel Holtmann if (!conn) { 20629499237aSMarcel Holtmann if (ev->link_type != SCO_LINK) 20639499237aSMarcel Holtmann goto unlock; 20649499237aSMarcel Holtmann 20659499237aSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 2066a9de9248SMarcel Holtmann if (!conn) 2067a9de9248SMarcel Holtmann goto unlock; 206845bb4bf0SMarcel Holtmann 20699499237aSMarcel Holtmann conn->type = SCO_LINK; 20709499237aSMarcel Holtmann } 20719499237aSMarcel Holtmann 2072a9de9248SMarcel Holtmann if (!ev->status) { 2073a9de9248SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 2074769be974SMarcel Holtmann 2075769be974SMarcel Holtmann if (conn->type == ACL_LINK) { 2076769be974SMarcel Holtmann conn->state = BT_CONFIG; 2077769be974SMarcel Holtmann hci_conn_hold(conn); 2078a9ea3ed9SSzymon Janc 2079a9ea3ed9SSzymon Janc if (!conn->out && !hci_conn_ssp_enabled(conn) && 2080a9ea3ed9SSzymon Janc !hci_find_link_key(hdev, &ev->bdaddr)) 2081a9ea3ed9SSzymon Janc conn->disc_timeout = HCI_PAIRING_TIMEOUT; 2082a9ea3ed9SSzymon Janc else 2083052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 2084769be974SMarcel Holtmann } else 2085a9de9248SMarcel Holtmann conn->state = BT_CONNECTED; 2086a9de9248SMarcel Holtmann 20877d0db0a3SMarcel Holtmann hci_conn_add_sysfs(conn); 20887d0db0a3SMarcel Holtmann 2089a9de9248SMarcel Holtmann if (test_bit(HCI_AUTH, &hdev->flags)) 20904dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 2091a9de9248SMarcel Holtmann 2092a9de9248SMarcel Holtmann if (test_bit(HCI_ENCRYPT, &hdev->flags)) 20934dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags); 2094a9de9248SMarcel Holtmann 2095a9de9248SMarcel Holtmann /* Get remote features */ 2096a9de9248SMarcel Holtmann if (conn->type == ACL_LINK) { 2097a9de9248SMarcel Holtmann struct hci_cp_read_remote_features cp; 2098a9de9248SMarcel Holtmann cp.handle = ev->handle; 2099769be974SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, 2100769be974SMarcel Holtmann sizeof(cp), &cp); 210122f433dcSJohan Hedberg 210222f433dcSJohan Hedberg hci_update_page_scan(hdev, NULL); 210345bb4bf0SMarcel Holtmann } 2104a9de9248SMarcel Holtmann 2105a9de9248SMarcel Holtmann /* Set packet type for incoming connection */ 2106d095c1ebSAndrei Emeltchenko if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) { 2107a9de9248SMarcel Holtmann struct hci_cp_change_conn_ptype cp; 2108a9de9248SMarcel Holtmann cp.handle = ev->handle; 2109a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 211004124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), 211104124681SGustavo F. Padovan &cp); 2112a9de9248SMarcel Holtmann } 211317d5c04cSJohan Hedberg } else { 2114a9de9248SMarcel Holtmann conn->state = BT_CLOSED; 211517d5c04cSJohan Hedberg if (conn->type == ACL_LINK) 211664c7b77cSMarcel Holtmann mgmt_connect_failed(hdev, &conn->dst, conn->type, 211748264f06SJohan Hedberg conn->dst_type, ev->status); 211817d5c04cSJohan Hedberg } 211945bb4bf0SMarcel Holtmann 2120e73439d8SMarcel Holtmann if (conn->type == ACL_LINK) 2121e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 212245bb4bf0SMarcel Holtmann 2123769be974SMarcel Holtmann if (ev->status) { 2124a9de9248SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 2125a9de9248SMarcel Holtmann hci_conn_del(conn); 2126c89b6e6bSMarcel Holtmann } else if (ev->link_type != ACL_LINK) 2127c89b6e6bSMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 2128a9de9248SMarcel Holtmann 2129a9de9248SMarcel Holtmann unlock: 21301da177e4SLinus Torvalds hci_dev_unlock(hdev); 2131a9de9248SMarcel Holtmann 2132a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 21331da177e4SLinus Torvalds } 21341da177e4SLinus Torvalds 213570c46425SJohan Hedberg static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr) 213670c46425SJohan Hedberg { 213770c46425SJohan Hedberg struct hci_cp_reject_conn_req cp; 213870c46425SJohan Hedberg 213970c46425SJohan Hedberg bacpy(&cp.bdaddr, bdaddr); 214070c46425SJohan Hedberg cp.reason = HCI_ERROR_REJ_BAD_ADDR; 214170c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); 214270c46425SJohan Hedberg } 214370c46425SJohan Hedberg 21446039aa73SGustavo Padovan static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 21451da177e4SLinus Torvalds { 2146a9de9248SMarcel Holtmann struct hci_ev_conn_request *ev = (void *) skb->data; 21471da177e4SLinus Torvalds int mask = hdev->link_mode; 214870c46425SJohan Hedberg struct inquiry_entry *ie; 214970c46425SJohan Hedberg struct hci_conn *conn; 215020714bfeSFrédéric Dalleau __u8 flags = 0; 21511da177e4SLinus Torvalds 21526ed93dc6SAndrei Emeltchenko BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr, 2153807deac2SGustavo Padovan ev->link_type); 21541da177e4SLinus Torvalds 215520714bfeSFrédéric Dalleau mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type, 215620714bfeSFrédéric Dalleau &flags); 21571da177e4SLinus Torvalds 215870c46425SJohan Hedberg if (!(mask & HCI_LM_ACCEPT)) { 215970c46425SJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 216070c46425SJohan Hedberg return; 216170c46425SJohan Hedberg } 216270c46425SJohan Hedberg 2163a55bd29dSJohan Hedberg if (hci_bdaddr_list_lookup(&hdev->blacklist, &ev->bdaddr, 2164dcc36c16SJohan Hedberg BDADDR_BREDR)) { 216570c46425SJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 216670c46425SJohan Hedberg return; 216770c46425SJohan Hedberg } 216846c4c941SJohan Hedberg 216946c4c941SJohan Hedberg if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags) && 217046c4c941SJohan Hedberg !hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr, 2171a55bd29dSJohan Hedberg BDADDR_BREDR)) { 2172a55bd29dSJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 2173a55bd29dSJohan Hedberg return; 2174a55bd29dSJohan Hedberg } 217570c46425SJohan Hedberg 21761da177e4SLinus Torvalds /* Connection accepted */ 21771da177e4SLinus Torvalds 21781da177e4SLinus Torvalds hci_dev_lock(hdev); 2179b6a0dc82SMarcel Holtmann 2180cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 2181cc11b9c1SAndrei Emeltchenko if (ie) 2182c7bdd502SMarcel Holtmann memcpy(ie->data.dev_class, ev->dev_class, 3); 2183c7bdd502SMarcel Holtmann 21848fc9ced3SGustavo Padovan conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, 21858fc9ced3SGustavo Padovan &ev->bdaddr); 21861da177e4SLinus Torvalds if (!conn) { 2187a5c4e309SJohan Hedberg conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr, 2188a5c4e309SJohan Hedberg HCI_ROLE_SLAVE); 2189cc11b9c1SAndrei Emeltchenko if (!conn) { 2190893ef971SGustavo F. Padovan BT_ERR("No memory for new connection"); 21911da177e4SLinus Torvalds hci_dev_unlock(hdev); 21921da177e4SLinus Torvalds return; 21931da177e4SLinus Torvalds } 21941da177e4SLinus Torvalds } 2195b6a0dc82SMarcel Holtmann 21961da177e4SLinus Torvalds memcpy(conn->dev_class, ev->dev_class, 3); 2197b6a0dc82SMarcel Holtmann 21981da177e4SLinus Torvalds hci_dev_unlock(hdev); 21991da177e4SLinus Torvalds 220020714bfeSFrédéric Dalleau if (ev->link_type == ACL_LINK || 220120714bfeSFrédéric Dalleau (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) { 2202b6a0dc82SMarcel Holtmann struct hci_cp_accept_conn_req cp; 220320714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 2204b6a0dc82SMarcel Holtmann 22051da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 22061da177e4SLinus Torvalds 22071da177e4SLinus Torvalds if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) 22081da177e4SLinus Torvalds cp.role = 0x00; /* Become master */ 22091da177e4SLinus Torvalds else 22101da177e4SLinus Torvalds cp.role = 0x01; /* Remain slave */ 22111da177e4SLinus Torvalds 221270c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); 221320714bfeSFrédéric Dalleau } else if (!(flags & HCI_PROTO_DEFER)) { 2214b6a0dc82SMarcel Holtmann struct hci_cp_accept_sync_conn_req cp; 221520714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 2216b6a0dc82SMarcel Holtmann 2217b6a0dc82SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 2218a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 2219b6a0dc82SMarcel Holtmann 2220dcf4adbfSJoe Perches cp.tx_bandwidth = cpu_to_le32(0x00001f40); 2221dcf4adbfSJoe Perches cp.rx_bandwidth = cpu_to_le32(0x00001f40); 2222dcf4adbfSJoe Perches cp.max_latency = cpu_to_le16(0xffff); 2223b6a0dc82SMarcel Holtmann cp.content_format = cpu_to_le16(hdev->voice_setting); 2224b6a0dc82SMarcel Holtmann cp.retrans_effort = 0xff; 2225b6a0dc82SMarcel Holtmann 222670c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp), 222770c46425SJohan Hedberg &cp); 222820714bfeSFrédéric Dalleau } else { 222920714bfeSFrédéric Dalleau conn->state = BT_CONNECT2; 223020714bfeSFrédéric Dalleau hci_proto_connect_cfm(conn, 0); 2231b6a0dc82SMarcel Holtmann } 22321da177e4SLinus Torvalds } 22331da177e4SLinus Torvalds 2234f0d6a0eaSMikel Astiz static u8 hci_to_mgmt_reason(u8 err) 2235f0d6a0eaSMikel Astiz { 2236f0d6a0eaSMikel Astiz switch (err) { 2237f0d6a0eaSMikel Astiz case HCI_ERROR_CONNECTION_TIMEOUT: 2238f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_TIMEOUT; 2239f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_USER_TERM: 2240f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_LOW_RESOURCES: 2241f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_POWER_OFF: 2242f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_REMOTE; 2243f0d6a0eaSMikel Astiz case HCI_ERROR_LOCAL_HOST_TERM: 2244f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_LOCAL_HOST; 2245f0d6a0eaSMikel Astiz default: 2246f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_UNKNOWN; 2247f0d6a0eaSMikel Astiz } 2248f0d6a0eaSMikel Astiz } 2249f0d6a0eaSMikel Astiz 22506039aa73SGustavo Padovan static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 22511da177e4SLinus Torvalds { 2252a9de9248SMarcel Holtmann struct hci_ev_disconn_complete *ev = (void *) skb->data; 2253abf54a50SAndre Guedes u8 reason = hci_to_mgmt_reason(ev->reason); 22549fcb18efSAndre Guedes struct hci_conn_params *params; 225504837f64SMarcel Holtmann struct hci_conn *conn; 225612d4a3b2SJohan Hedberg bool mgmt_connected; 22573846220bSAndre Guedes u8 type; 22581da177e4SLinus Torvalds 22599f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 22601da177e4SLinus Torvalds 22611da177e4SLinus Torvalds hci_dev_lock(hdev); 22621da177e4SLinus Torvalds 226304837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2264f7520543SJohan Hedberg if (!conn) 2265f7520543SJohan Hedberg goto unlock; 2266f7520543SJohan Hedberg 2267f0d6a0eaSMikel Astiz if (ev->status) { 226888c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 226988c3df13SJohan Hedberg conn->dst_type, ev->status); 2270abf54a50SAndre Guedes goto unlock; 2271abf54a50SAndre Guedes } 2272f0d6a0eaSMikel Astiz 22733846220bSAndre Guedes conn->state = BT_CLOSED; 22743846220bSAndre Guedes 227512d4a3b2SJohan Hedberg mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags); 227612d4a3b2SJohan Hedberg mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type, 227712d4a3b2SJohan Hedberg reason, mgmt_connected); 2278f7520543SJohan Hedberg 227922f433dcSJohan Hedberg if (conn->type == ACL_LINK) { 228022f433dcSJohan Hedberg if (test_bit(HCI_CONN_FLUSH_KEY, &conn->flags)) 22816ec5bcadSVishal Agarwal hci_remove_link_key(hdev, &conn->dst); 22823846220bSAndre Guedes 228322f433dcSJohan Hedberg hci_update_page_scan(hdev, NULL); 228422f433dcSJohan Hedberg } 228522f433dcSJohan Hedberg 22869fcb18efSAndre Guedes params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); 22879fcb18efSAndre Guedes if (params) { 22889fcb18efSAndre Guedes switch (params->auto_connect) { 22899fcb18efSAndre Guedes case HCI_AUTO_CONN_LINK_LOSS: 22909fcb18efSAndre Guedes if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT) 22919fcb18efSAndre Guedes break; 22929fcb18efSAndre Guedes /* Fall through */ 22939fcb18efSAndre Guedes 22944b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_DIRECT: 22959fcb18efSAndre Guedes case HCI_AUTO_CONN_ALWAYS: 2296418025d1SJohan Hedberg list_del_init(¶ms->action); 2297418025d1SJohan Hedberg list_add(¶ms->action, &hdev->pend_le_conns); 2298418025d1SJohan Hedberg hci_update_background_scan(hdev); 22999fcb18efSAndre Guedes break; 23009fcb18efSAndre Guedes 23019fcb18efSAndre Guedes default: 23029fcb18efSAndre Guedes break; 23039fcb18efSAndre Guedes } 23049fcb18efSAndre Guedes } 23059fcb18efSAndre Guedes 23063846220bSAndre Guedes type = conn->type; 23073846220bSAndre Guedes 23082950f21aSMarcel Holtmann hci_proto_disconn_cfm(conn, ev->reason); 23091da177e4SLinus Torvalds hci_conn_del(conn); 23102210246cSJohan Hedberg 23112210246cSJohan Hedberg /* Re-enable advertising if necessary, since it might 23122210246cSJohan Hedberg * have been disabled by the connection. From the 23132210246cSJohan Hedberg * HCI_LE_Set_Advertise_Enable command description in 23142210246cSJohan Hedberg * the core specification (v4.0): 23152210246cSJohan Hedberg * "The Controller shall continue advertising until the Host 23162210246cSJohan Hedberg * issues an LE_Set_Advertise_Enable command with 23172210246cSJohan Hedberg * Advertising_Enable set to 0x00 (Advertising is disabled) 23182210246cSJohan Hedberg * or until a connection is created or until the Advertising 23192210246cSJohan Hedberg * is timed out due to Directed Advertising." 23202210246cSJohan Hedberg */ 23212210246cSJohan Hedberg if (type == LE_LINK) 23225976e608SMarcel Holtmann mgmt_reenable_advertising(hdev); 23231da177e4SLinus Torvalds 2324f7520543SJohan Hedberg unlock: 23251da177e4SLinus Torvalds hci_dev_unlock(hdev); 23261da177e4SLinus Torvalds } 23271da177e4SLinus Torvalds 23286039aa73SGustavo Padovan static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2329a9de9248SMarcel Holtmann { 2330a9de9248SMarcel Holtmann struct hci_ev_auth_complete *ev = (void *) skb->data; 2331a9de9248SMarcel Holtmann struct hci_conn *conn; 2332a9de9248SMarcel Holtmann 23339f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2334a9de9248SMarcel Holtmann 2335a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2336a9de9248SMarcel Holtmann 2337a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2338d7556e20SWaldemar Rymarkiewicz if (!conn) 2339d7556e20SWaldemar Rymarkiewicz goto unlock; 2340d7556e20SWaldemar Rymarkiewicz 2341765c2a96SJohan Hedberg if (!ev->status) { 2342aa64a8b5SJohan Hedberg if (!hci_conn_ssp_enabled(conn) && 234351a8efd7SJohan Hedberg test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { 2344d7556e20SWaldemar Rymarkiewicz BT_INFO("re-auth of legacy device is not possible."); 234519f8def0SWaldemar Rymarkiewicz } else { 23464dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 2347765c2a96SJohan Hedberg conn->sec_level = conn->pending_sec_level; 234819f8def0SWaldemar Rymarkiewicz } 23492a611692SJohan Hedberg } else { 2350e1e930f5SJohan Hedberg mgmt_auth_failed(conn, ev->status); 23512a611692SJohan Hedberg } 2352a9de9248SMarcel Holtmann 235351a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 235451a8efd7SJohan Hedberg clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags); 2355a9de9248SMarcel Holtmann 2356f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 2357aa64a8b5SJohan Hedberg if (!ev->status && hci_conn_ssp_enabled(conn)) { 2358f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 2359f8558555SMarcel Holtmann cp.handle = ev->handle; 2360f8558555SMarcel Holtmann cp.encrypt = 0x01; 2361d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 2362d7556e20SWaldemar Rymarkiewicz &cp); 2363f8558555SMarcel Holtmann } else { 2364f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 2365f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 236676a68ba0SDavid Herrmann hci_conn_drop(conn); 2367f8558555SMarcel Holtmann } 2368052b30b0SMarcel Holtmann } else { 2369a9de9248SMarcel Holtmann hci_auth_cfm(conn, ev->status); 2370a9de9248SMarcel Holtmann 2371052b30b0SMarcel Holtmann hci_conn_hold(conn); 2372052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 237376a68ba0SDavid Herrmann hci_conn_drop(conn); 2374052b30b0SMarcel Holtmann } 2375052b30b0SMarcel Holtmann 237651a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { 2377a9de9248SMarcel Holtmann if (!ev->status) { 2378a9de9248SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 2379f8558555SMarcel Holtmann cp.handle = ev->handle; 2380f8558555SMarcel Holtmann cp.encrypt = 0x01; 2381d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 2382d7556e20SWaldemar Rymarkiewicz &cp); 2383a9de9248SMarcel Holtmann } else { 238451a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 2385a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, 0x00); 2386a9de9248SMarcel Holtmann } 2387a9de9248SMarcel Holtmann } 2388a9de9248SMarcel Holtmann 2389d7556e20SWaldemar Rymarkiewicz unlock: 2390a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2391a9de9248SMarcel Holtmann } 2392a9de9248SMarcel Holtmann 23936039aa73SGustavo Padovan static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) 2394a9de9248SMarcel Holtmann { 2395127178d2SJohan Hedberg struct hci_ev_remote_name *ev = (void *) skb->data; 2396127178d2SJohan Hedberg struct hci_conn *conn; 2397127178d2SJohan Hedberg 2398a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2399a9de9248SMarcel Holtmann 2400a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 2401127178d2SJohan Hedberg 2402127178d2SJohan Hedberg hci_dev_lock(hdev); 2403127178d2SJohan Hedberg 2404127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2405b644ba33SJohan Hedberg 2406b644ba33SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2407b644ba33SJohan Hedberg goto check_auth; 2408b644ba33SJohan Hedberg 2409b644ba33SJohan Hedberg if (ev->status == 0) 2410b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name, 2411b644ba33SJohan Hedberg strnlen(ev->name, HCI_MAX_NAME_LENGTH)); 2412b644ba33SJohan Hedberg else 2413b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0); 2414b644ba33SJohan Hedberg 2415b644ba33SJohan Hedberg check_auth: 241679c6c70cSJohan Hedberg if (!conn) 241779c6c70cSJohan Hedberg goto unlock; 241879c6c70cSJohan Hedberg 241979c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 242079c6c70cSJohan Hedberg goto unlock; 242179c6c70cSJohan Hedberg 242251a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 2423127178d2SJohan Hedberg struct hci_cp_auth_requested cp; 2424977f8fceSJohan Hedberg 2425977f8fceSJohan Hedberg set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags); 2426977f8fceSJohan Hedberg 2427127178d2SJohan Hedberg cp.handle = __cpu_to_le16(conn->handle); 2428127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); 2429127178d2SJohan Hedberg } 2430127178d2SJohan Hedberg 243179c6c70cSJohan Hedberg unlock: 2432127178d2SJohan Hedberg hci_dev_unlock(hdev); 2433a9de9248SMarcel Holtmann } 2434a9de9248SMarcel Holtmann 24356039aa73SGustavo Padovan static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2436a9de9248SMarcel Holtmann { 2437a9de9248SMarcel Holtmann struct hci_ev_encrypt_change *ev = (void *) skb->data; 2438a9de9248SMarcel Holtmann struct hci_conn *conn; 2439a9de9248SMarcel Holtmann 24409f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2441a9de9248SMarcel Holtmann 2442a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2443a9de9248SMarcel Holtmann 2444a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2445dc8357ccSMarcel Holtmann if (!conn) 2446dc8357ccSMarcel Holtmann goto unlock; 2447dc8357ccSMarcel Holtmann 2448a9de9248SMarcel Holtmann if (!ev->status) { 2449ae293196SMarcel Holtmann if (ev->encrypt) { 2450ae293196SMarcel Holtmann /* Encryption implies authentication */ 24514dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 24524dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags); 2453da85e5e5SVinicius Costa Gomes conn->sec_level = conn->pending_sec_level; 2454abf76badSMarcel Holtmann 2455914a6ffeSMarcel Holtmann /* P-256 authentication key implies FIPS */ 2456914a6ffeSMarcel Holtmann if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256) 24574dae2798SJohan Hedberg set_bit(HCI_CONN_FIPS, &conn->flags); 2458914a6ffeSMarcel Holtmann 2459abf76badSMarcel Holtmann if ((conn->type == ACL_LINK && ev->encrypt == 0x02) || 2460abf76badSMarcel Holtmann conn->type == LE_LINK) 2461abf76badSMarcel Holtmann set_bit(HCI_CONN_AES_CCM, &conn->flags); 2462abf76badSMarcel Holtmann } else { 24634dae2798SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT, &conn->flags); 2464abf76badSMarcel Holtmann clear_bit(HCI_CONN_AES_CCM, &conn->flags); 2465abf76badSMarcel Holtmann } 2466a9de9248SMarcel Holtmann } 2467a9de9248SMarcel Holtmann 24687ed3fa20SJohan Hedberg /* We should disregard the current RPA and generate a new one 24697ed3fa20SJohan Hedberg * whenever the encryption procedure fails. 24707ed3fa20SJohan Hedberg */ 24717ed3fa20SJohan Hedberg if (ev->status && conn->type == LE_LINK) 24727ed3fa20SJohan Hedberg set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags); 24737ed3fa20SJohan Hedberg 247451a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 2475a9de9248SMarcel Holtmann 2476a7d7723aSGustavo Padovan if (ev->status && conn->state == BT_CONNECTED) { 2477bed71748SAndre Guedes hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 247876a68ba0SDavid Herrmann hci_conn_drop(conn); 2479a7d7723aSGustavo Padovan goto unlock; 2480a7d7723aSGustavo Padovan } 2481a7d7723aSGustavo Padovan 2482f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 2483f8558555SMarcel Holtmann if (!ev->status) 2484f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 2485f8558555SMarcel Holtmann 248640b552aaSMarcel Holtmann /* In Secure Connections Only mode, do not allow any 248740b552aaSMarcel Holtmann * connections that are not encrypted with AES-CCM 248840b552aaSMarcel Holtmann * using a P-256 authenticated combination key. 248940b552aaSMarcel Holtmann */ 249040b552aaSMarcel Holtmann if (test_bit(HCI_SC_ONLY, &hdev->dev_flags) && 249140b552aaSMarcel Holtmann (!test_bit(HCI_CONN_AES_CCM, &conn->flags) || 249240b552aaSMarcel Holtmann conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) { 249340b552aaSMarcel Holtmann hci_proto_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE); 249440b552aaSMarcel Holtmann hci_conn_drop(conn); 249540b552aaSMarcel Holtmann goto unlock; 249640b552aaSMarcel Holtmann } 249740b552aaSMarcel Holtmann 2498f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 249976a68ba0SDavid Herrmann hci_conn_drop(conn); 2500f8558555SMarcel Holtmann } else 2501a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, ev->encrypt); 2502a9de9248SMarcel Holtmann 2503a7d7723aSGustavo Padovan unlock: 2504a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2505a9de9248SMarcel Holtmann } 2506a9de9248SMarcel Holtmann 25076039aa73SGustavo Padovan static void hci_change_link_key_complete_evt(struct hci_dev *hdev, 2508807deac2SGustavo Padovan struct sk_buff *skb) 2509a9de9248SMarcel Holtmann { 2510a9de9248SMarcel Holtmann struct hci_ev_change_link_key_complete *ev = (void *) skb->data; 2511a9de9248SMarcel Holtmann struct hci_conn *conn; 2512a9de9248SMarcel Holtmann 25139f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2514a9de9248SMarcel Holtmann 2515a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2516a9de9248SMarcel Holtmann 2517a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2518a9de9248SMarcel Holtmann if (conn) { 2519a9de9248SMarcel Holtmann if (!ev->status) 25204dae2798SJohan Hedberg set_bit(HCI_CONN_SECURE, &conn->flags); 2521a9de9248SMarcel Holtmann 252251a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 2523a9de9248SMarcel Holtmann 2524a9de9248SMarcel Holtmann hci_key_change_cfm(conn, ev->status); 2525a9de9248SMarcel Holtmann } 2526a9de9248SMarcel Holtmann 2527a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2528a9de9248SMarcel Holtmann } 2529a9de9248SMarcel Holtmann 25306039aa73SGustavo Padovan static void hci_remote_features_evt(struct hci_dev *hdev, 2531807deac2SGustavo Padovan struct sk_buff *skb) 2532a9de9248SMarcel Holtmann { 2533a9de9248SMarcel Holtmann struct hci_ev_remote_features *ev = (void *) skb->data; 2534a9de9248SMarcel Holtmann struct hci_conn *conn; 2535a9de9248SMarcel Holtmann 25369f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2537a9de9248SMarcel Holtmann 2538a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2539a9de9248SMarcel Holtmann 2540a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2541ccd556feSJohan Hedberg if (!conn) 2542ccd556feSJohan Hedberg goto unlock; 2543ccd556feSJohan Hedberg 2544769be974SMarcel Holtmann if (!ev->status) 2545cad718edSJohan Hedberg memcpy(conn->features[0], ev->features, 8); 2546a9de9248SMarcel Holtmann 2547ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 2548ccd556feSJohan Hedberg goto unlock; 2549ccd556feSJohan Hedberg 2550ccd556feSJohan Hedberg if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) { 2551769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features cp; 2552769be974SMarcel Holtmann cp.handle = ev->handle; 2553769be974SMarcel Holtmann cp.page = 0x01; 2554ccd556feSJohan Hedberg hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, 2555769be974SMarcel Holtmann sizeof(cp), &cp); 2556392599b9SJohan Hedberg goto unlock; 2557392599b9SJohan Hedberg } 2558392599b9SJohan Hedberg 2559671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 2560127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 2561127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 2562127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 2563127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 2564127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 2565b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 256648ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, NULL, 0); 2567392599b9SJohan Hedberg 2568127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 2569769be974SMarcel Holtmann conn->state = BT_CONNECTED; 2570769be974SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 257176a68ba0SDavid Herrmann hci_conn_drop(conn); 2572769be974SMarcel Holtmann } 2573769be974SMarcel Holtmann 2574ccd556feSJohan Hedberg unlock: 2575a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2576a9de9248SMarcel Holtmann } 2577a9de9248SMarcel Holtmann 25786039aa73SGustavo Padovan static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2579a9de9248SMarcel Holtmann { 2580a9de9248SMarcel Holtmann struct hci_ev_cmd_complete *ev = (void *) skb->data; 25819238f36aSJohan Hedberg u8 status = skb->data[sizeof(*ev)]; 2582a9de9248SMarcel Holtmann __u16 opcode; 2583a9de9248SMarcel Holtmann 2584a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 2585a9de9248SMarcel Holtmann 2586a9de9248SMarcel Holtmann opcode = __le16_to_cpu(ev->opcode); 2587a9de9248SMarcel Holtmann 2588a9de9248SMarcel Holtmann switch (opcode) { 2589a9de9248SMarcel Holtmann case HCI_OP_INQUIRY_CANCEL: 2590a9de9248SMarcel Holtmann hci_cc_inquiry_cancel(hdev, skb); 2591a9de9248SMarcel Holtmann break; 2592a9de9248SMarcel Holtmann 25934d93483bSAndre Guedes case HCI_OP_PERIODIC_INQ: 25944d93483bSAndre Guedes hci_cc_periodic_inq(hdev, skb); 25954d93483bSAndre Guedes break; 25964d93483bSAndre Guedes 2597a9de9248SMarcel Holtmann case HCI_OP_EXIT_PERIODIC_INQ: 2598a9de9248SMarcel Holtmann hci_cc_exit_periodic_inq(hdev, skb); 2599a9de9248SMarcel Holtmann break; 2600a9de9248SMarcel Holtmann 2601a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ_CANCEL: 2602a9de9248SMarcel Holtmann hci_cc_remote_name_req_cancel(hdev, skb); 2603a9de9248SMarcel Holtmann break; 2604a9de9248SMarcel Holtmann 2605a9de9248SMarcel Holtmann case HCI_OP_ROLE_DISCOVERY: 2606a9de9248SMarcel Holtmann hci_cc_role_discovery(hdev, skb); 2607a9de9248SMarcel Holtmann break; 2608a9de9248SMarcel Holtmann 2609e4e8e37cSMarcel Holtmann case HCI_OP_READ_LINK_POLICY: 2610e4e8e37cSMarcel Holtmann hci_cc_read_link_policy(hdev, skb); 2611e4e8e37cSMarcel Holtmann break; 2612e4e8e37cSMarcel Holtmann 2613a9de9248SMarcel Holtmann case HCI_OP_WRITE_LINK_POLICY: 2614a9de9248SMarcel Holtmann hci_cc_write_link_policy(hdev, skb); 2615a9de9248SMarcel Holtmann break; 2616a9de9248SMarcel Holtmann 2617e4e8e37cSMarcel Holtmann case HCI_OP_READ_DEF_LINK_POLICY: 2618e4e8e37cSMarcel Holtmann hci_cc_read_def_link_policy(hdev, skb); 2619e4e8e37cSMarcel Holtmann break; 2620e4e8e37cSMarcel Holtmann 2621e4e8e37cSMarcel Holtmann case HCI_OP_WRITE_DEF_LINK_POLICY: 2622e4e8e37cSMarcel Holtmann hci_cc_write_def_link_policy(hdev, skb); 2623e4e8e37cSMarcel Holtmann break; 2624e4e8e37cSMarcel Holtmann 2625a9de9248SMarcel Holtmann case HCI_OP_RESET: 2626a9de9248SMarcel Holtmann hci_cc_reset(hdev, skb); 2627a9de9248SMarcel Holtmann break; 2628a9de9248SMarcel Holtmann 2629a9de9248SMarcel Holtmann case HCI_OP_WRITE_LOCAL_NAME: 2630a9de9248SMarcel Holtmann hci_cc_write_local_name(hdev, skb); 2631a9de9248SMarcel Holtmann break; 2632a9de9248SMarcel Holtmann 2633a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_NAME: 2634a9de9248SMarcel Holtmann hci_cc_read_local_name(hdev, skb); 2635a9de9248SMarcel Holtmann break; 2636a9de9248SMarcel Holtmann 2637a9de9248SMarcel Holtmann case HCI_OP_WRITE_AUTH_ENABLE: 2638a9de9248SMarcel Holtmann hci_cc_write_auth_enable(hdev, skb); 2639a9de9248SMarcel Holtmann break; 2640a9de9248SMarcel Holtmann 2641a9de9248SMarcel Holtmann case HCI_OP_WRITE_ENCRYPT_MODE: 2642a9de9248SMarcel Holtmann hci_cc_write_encrypt_mode(hdev, skb); 2643a9de9248SMarcel Holtmann break; 2644a9de9248SMarcel Holtmann 2645a9de9248SMarcel Holtmann case HCI_OP_WRITE_SCAN_ENABLE: 2646a9de9248SMarcel Holtmann hci_cc_write_scan_enable(hdev, skb); 2647a9de9248SMarcel Holtmann break; 2648a9de9248SMarcel Holtmann 2649a9de9248SMarcel Holtmann case HCI_OP_READ_CLASS_OF_DEV: 2650a9de9248SMarcel Holtmann hci_cc_read_class_of_dev(hdev, skb); 2651a9de9248SMarcel Holtmann break; 2652a9de9248SMarcel Holtmann 2653a9de9248SMarcel Holtmann case HCI_OP_WRITE_CLASS_OF_DEV: 2654a9de9248SMarcel Holtmann hci_cc_write_class_of_dev(hdev, skb); 2655a9de9248SMarcel Holtmann break; 2656a9de9248SMarcel Holtmann 2657a9de9248SMarcel Holtmann case HCI_OP_READ_VOICE_SETTING: 2658a9de9248SMarcel Holtmann hci_cc_read_voice_setting(hdev, skb); 2659a9de9248SMarcel Holtmann break; 2660a9de9248SMarcel Holtmann 2661a9de9248SMarcel Holtmann case HCI_OP_WRITE_VOICE_SETTING: 2662a9de9248SMarcel Holtmann hci_cc_write_voice_setting(hdev, skb); 2663a9de9248SMarcel Holtmann break; 2664a9de9248SMarcel Holtmann 2665b4cb9fb2SMarcel Holtmann case HCI_OP_READ_NUM_SUPPORTED_IAC: 2666b4cb9fb2SMarcel Holtmann hci_cc_read_num_supported_iac(hdev, skb); 2667b4cb9fb2SMarcel Holtmann break; 2668b4cb9fb2SMarcel Holtmann 2669333140b5SMarcel Holtmann case HCI_OP_WRITE_SSP_MODE: 2670333140b5SMarcel Holtmann hci_cc_write_ssp_mode(hdev, skb); 2671333140b5SMarcel Holtmann break; 2672333140b5SMarcel Holtmann 2673eac83dc6SMarcel Holtmann case HCI_OP_WRITE_SC_SUPPORT: 2674eac83dc6SMarcel Holtmann hci_cc_write_sc_support(hdev, skb); 2675eac83dc6SMarcel Holtmann break; 2676eac83dc6SMarcel Holtmann 2677a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_VERSION: 2678a9de9248SMarcel Holtmann hci_cc_read_local_version(hdev, skb); 2679a9de9248SMarcel Holtmann break; 2680a9de9248SMarcel Holtmann 2681a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_COMMANDS: 2682a9de9248SMarcel Holtmann hci_cc_read_local_commands(hdev, skb); 2683a9de9248SMarcel Holtmann break; 2684a9de9248SMarcel Holtmann 2685a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_FEATURES: 2686a9de9248SMarcel Holtmann hci_cc_read_local_features(hdev, skb); 2687a9de9248SMarcel Holtmann break; 2688a9de9248SMarcel Holtmann 2689971e3a4bSAndre Guedes case HCI_OP_READ_LOCAL_EXT_FEATURES: 2690971e3a4bSAndre Guedes hci_cc_read_local_ext_features(hdev, skb); 2691971e3a4bSAndre Guedes break; 2692971e3a4bSAndre Guedes 2693a9de9248SMarcel Holtmann case HCI_OP_READ_BUFFER_SIZE: 2694a9de9248SMarcel Holtmann hci_cc_read_buffer_size(hdev, skb); 2695a9de9248SMarcel Holtmann break; 2696a9de9248SMarcel Holtmann 2697a9de9248SMarcel Holtmann case HCI_OP_READ_BD_ADDR: 2698a9de9248SMarcel Holtmann hci_cc_read_bd_addr(hdev, skb); 2699a9de9248SMarcel Holtmann break; 2700a9de9248SMarcel Holtmann 2701f332ec66SJohan Hedberg case HCI_OP_READ_PAGE_SCAN_ACTIVITY: 2702f332ec66SJohan Hedberg hci_cc_read_page_scan_activity(hdev, skb); 2703f332ec66SJohan Hedberg break; 2704f332ec66SJohan Hedberg 27054a3ee763SJohan Hedberg case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY: 27064a3ee763SJohan Hedberg hci_cc_write_page_scan_activity(hdev, skb); 27074a3ee763SJohan Hedberg break; 27084a3ee763SJohan Hedberg 2709f332ec66SJohan Hedberg case HCI_OP_READ_PAGE_SCAN_TYPE: 2710f332ec66SJohan Hedberg hci_cc_read_page_scan_type(hdev, skb); 2711f332ec66SJohan Hedberg break; 2712f332ec66SJohan Hedberg 27134a3ee763SJohan Hedberg case HCI_OP_WRITE_PAGE_SCAN_TYPE: 27144a3ee763SJohan Hedberg hci_cc_write_page_scan_type(hdev, skb); 27154a3ee763SJohan Hedberg break; 27164a3ee763SJohan Hedberg 2717350ee4cfSAndrei Emeltchenko case HCI_OP_READ_DATA_BLOCK_SIZE: 2718350ee4cfSAndrei Emeltchenko hci_cc_read_data_block_size(hdev, skb); 2719350ee4cfSAndrei Emeltchenko break; 2720350ee4cfSAndrei Emeltchenko 27211e89cffbSAndrei Emeltchenko case HCI_OP_READ_FLOW_CONTROL_MODE: 27221e89cffbSAndrei Emeltchenko hci_cc_read_flow_control_mode(hdev, skb); 27231e89cffbSAndrei Emeltchenko break; 27241e89cffbSAndrei Emeltchenko 2725928abaa7SAndrei Emeltchenko case HCI_OP_READ_LOCAL_AMP_INFO: 2726928abaa7SAndrei Emeltchenko hci_cc_read_local_amp_info(hdev, skb); 2727928abaa7SAndrei Emeltchenko break; 2728928abaa7SAndrei Emeltchenko 272933f35721SJohan Hedberg case HCI_OP_READ_CLOCK: 273033f35721SJohan Hedberg hci_cc_read_clock(hdev, skb); 273133f35721SJohan Hedberg break; 273233f35721SJohan Hedberg 2733903e4541SAndrei Emeltchenko case HCI_OP_READ_LOCAL_AMP_ASSOC: 2734903e4541SAndrei Emeltchenko hci_cc_read_local_amp_assoc(hdev, skb); 2735903e4541SAndrei Emeltchenko break; 2736903e4541SAndrei Emeltchenko 2737d5859e22SJohan Hedberg case HCI_OP_READ_INQ_RSP_TX_POWER: 2738d5859e22SJohan Hedberg hci_cc_read_inq_rsp_tx_power(hdev, skb); 2739d5859e22SJohan Hedberg break; 2740d5859e22SJohan Hedberg 2741980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_REPLY: 2742980e1a53SJohan Hedberg hci_cc_pin_code_reply(hdev, skb); 2743980e1a53SJohan Hedberg break; 2744980e1a53SJohan Hedberg 2745980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_NEG_REPLY: 2746980e1a53SJohan Hedberg hci_cc_pin_code_neg_reply(hdev, skb); 2747980e1a53SJohan Hedberg break; 2748980e1a53SJohan Hedberg 2749c35938b2SSzymon Janc case HCI_OP_READ_LOCAL_OOB_DATA: 27504d2d2796SMarcel Holtmann hci_cc_read_local_oob_data(hdev, skb); 27514d2d2796SMarcel Holtmann break; 27524d2d2796SMarcel Holtmann 27534d2d2796SMarcel Holtmann case HCI_OP_READ_LOCAL_OOB_EXT_DATA: 27544d2d2796SMarcel Holtmann hci_cc_read_local_oob_ext_data(hdev, skb); 2755c35938b2SSzymon Janc break; 2756c35938b2SSzymon Janc 27576ed58ec5SVille Tervo case HCI_OP_LE_READ_BUFFER_SIZE: 27586ed58ec5SVille Tervo hci_cc_le_read_buffer_size(hdev, skb); 27596ed58ec5SVille Tervo break; 27606ed58ec5SVille Tervo 276160e77321SJohan Hedberg case HCI_OP_LE_READ_LOCAL_FEATURES: 276260e77321SJohan Hedberg hci_cc_le_read_local_features(hdev, skb); 276360e77321SJohan Hedberg break; 276460e77321SJohan Hedberg 27658fa19098SJohan Hedberg case HCI_OP_LE_READ_ADV_TX_POWER: 27668fa19098SJohan Hedberg hci_cc_le_read_adv_tx_power(hdev, skb); 27678fa19098SJohan Hedberg break; 27688fa19098SJohan Hedberg 2769a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_REPLY: 2770a5c29683SJohan Hedberg hci_cc_user_confirm_reply(hdev, skb); 2771a5c29683SJohan Hedberg break; 2772a5c29683SJohan Hedberg 2773a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_NEG_REPLY: 2774a5c29683SJohan Hedberg hci_cc_user_confirm_neg_reply(hdev, skb); 2775a5c29683SJohan Hedberg break; 2776a5c29683SJohan Hedberg 27771143d458SBrian Gix case HCI_OP_USER_PASSKEY_REPLY: 27781143d458SBrian Gix hci_cc_user_passkey_reply(hdev, skb); 27791143d458SBrian Gix break; 27801143d458SBrian Gix 27811143d458SBrian Gix case HCI_OP_USER_PASSKEY_NEG_REPLY: 27821143d458SBrian Gix hci_cc_user_passkey_neg_reply(hdev, skb); 278316cde993SSzymon Janc break; 278407f7fa5dSAndre Guedes 27857a4cd51dSMarcel Holtmann case HCI_OP_LE_SET_RANDOM_ADDR: 27867a4cd51dSMarcel Holtmann hci_cc_le_set_random_addr(hdev, skb); 27877a4cd51dSMarcel Holtmann break; 27887a4cd51dSMarcel Holtmann 2789c1d5dc4aSJohan Hedberg case HCI_OP_LE_SET_ADV_ENABLE: 2790c1d5dc4aSJohan Hedberg hci_cc_le_set_adv_enable(hdev, skb); 2791c1d5dc4aSJohan Hedberg break; 2792c1d5dc4aSJohan Hedberg 2793533553f8SMarcel Holtmann case HCI_OP_LE_SET_SCAN_PARAM: 2794533553f8SMarcel Holtmann hci_cc_le_set_scan_param(hdev, skb); 2795533553f8SMarcel Holtmann break; 2796533553f8SMarcel Holtmann 2797eb9d91f5SAndre Guedes case HCI_OP_LE_SET_SCAN_ENABLE: 2798eb9d91f5SAndre Guedes hci_cc_le_set_scan_enable(hdev, skb); 2799eb9d91f5SAndre Guedes break; 2800eb9d91f5SAndre Guedes 2801cf1d081fSJohan Hedberg case HCI_OP_LE_READ_WHITE_LIST_SIZE: 2802cf1d081fSJohan Hedberg hci_cc_le_read_white_list_size(hdev, skb); 2803cf1d081fSJohan Hedberg break; 2804cf1d081fSJohan Hedberg 28050f36b589SMarcel Holtmann case HCI_OP_LE_CLEAR_WHITE_LIST: 28060f36b589SMarcel Holtmann hci_cc_le_clear_white_list(hdev, skb); 28070f36b589SMarcel Holtmann break; 28080f36b589SMarcel Holtmann 28090f36b589SMarcel Holtmann case HCI_OP_LE_ADD_TO_WHITE_LIST: 28100f36b589SMarcel Holtmann hci_cc_le_add_to_white_list(hdev, skb); 28110f36b589SMarcel Holtmann break; 28120f36b589SMarcel Holtmann 28130f36b589SMarcel Holtmann case HCI_OP_LE_DEL_FROM_WHITE_LIST: 28140f36b589SMarcel Holtmann hci_cc_le_del_from_white_list(hdev, skb); 28150f36b589SMarcel Holtmann break; 28160f36b589SMarcel Holtmann 28179b008c04SJohan Hedberg case HCI_OP_LE_READ_SUPPORTED_STATES: 28189b008c04SJohan Hedberg hci_cc_le_read_supported_states(hdev, skb); 28199b008c04SJohan Hedberg break; 28209b008c04SJohan Hedberg 2821f9b49306SAndre Guedes case HCI_OP_WRITE_LE_HOST_SUPPORTED: 2822f9b49306SAndre Guedes hci_cc_write_le_host_supported(hdev, skb); 2823f9b49306SAndre Guedes break; 2824f9b49306SAndre Guedes 282556ed2cb8SJohan Hedberg case HCI_OP_LE_SET_ADV_PARAM: 282656ed2cb8SJohan Hedberg hci_cc_set_adv_param(hdev, skb); 282756ed2cb8SJohan Hedberg break; 282856ed2cb8SJohan Hedberg 282993c284eeSAndrei Emeltchenko case HCI_OP_WRITE_REMOTE_AMP_ASSOC: 283093c284eeSAndrei Emeltchenko hci_cc_write_remote_amp_assoc(hdev, skb); 283193c284eeSAndrei Emeltchenko break; 283293c284eeSAndrei Emeltchenko 28335ae76a94SAndrzej Kaczmarek case HCI_OP_READ_RSSI: 28345ae76a94SAndrzej Kaczmarek hci_cc_read_rssi(hdev, skb); 28355ae76a94SAndrzej Kaczmarek break; 28365ae76a94SAndrzej Kaczmarek 28375a134faeSAndrzej Kaczmarek case HCI_OP_READ_TX_POWER: 28385a134faeSAndrzej Kaczmarek hci_cc_read_tx_power(hdev, skb); 28395a134faeSAndrzej Kaczmarek break; 28405a134faeSAndrzej Kaczmarek 2841a9de9248SMarcel Holtmann default: 28429f1db00cSAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 2843a9de9248SMarcel Holtmann break; 2844a9de9248SMarcel Holtmann } 2845a9de9248SMarcel Holtmann 2846ad82cdd1SJohan Hedberg if (opcode != HCI_OP_NOP) 284765cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 28486bd32326SVille Tervo 2849ad82cdd1SJohan Hedberg hci_req_cmd_complete(hdev, opcode, status); 28509238f36aSJohan Hedberg 2851dbccd791SSzymon Janc if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { 2852a9de9248SMarcel Holtmann atomic_set(&hdev->cmd_cnt, 1); 2853a9de9248SMarcel Holtmann if (!skb_queue_empty(&hdev->cmd_q)) 2854c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 2855a9de9248SMarcel Holtmann } 2856a9de9248SMarcel Holtmann } 2857a9de9248SMarcel Holtmann 28586039aa73SGustavo Padovan static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) 2859a9de9248SMarcel Holtmann { 2860a9de9248SMarcel Holtmann struct hci_ev_cmd_status *ev = (void *) skb->data; 2861a9de9248SMarcel Holtmann __u16 opcode; 2862a9de9248SMarcel Holtmann 2863a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 2864a9de9248SMarcel Holtmann 2865a9de9248SMarcel Holtmann opcode = __le16_to_cpu(ev->opcode); 2866a9de9248SMarcel Holtmann 2867a9de9248SMarcel Holtmann switch (opcode) { 2868a9de9248SMarcel Holtmann case HCI_OP_INQUIRY: 2869a9de9248SMarcel Holtmann hci_cs_inquiry(hdev, ev->status); 2870a9de9248SMarcel Holtmann break; 2871a9de9248SMarcel Holtmann 2872a9de9248SMarcel Holtmann case HCI_OP_CREATE_CONN: 2873a9de9248SMarcel Holtmann hci_cs_create_conn(hdev, ev->status); 2874a9de9248SMarcel Holtmann break; 2875a9de9248SMarcel Holtmann 28769645c76cSKuba Pawlak case HCI_OP_DISCONNECT: 28779645c76cSKuba Pawlak hci_cs_disconnect(hdev, ev->status); 28789645c76cSKuba Pawlak break; 28799645c76cSKuba Pawlak 2880a9de9248SMarcel Holtmann case HCI_OP_ADD_SCO: 2881a9de9248SMarcel Holtmann hci_cs_add_sco(hdev, ev->status); 2882a9de9248SMarcel Holtmann break; 2883a9de9248SMarcel Holtmann 2884f8558555SMarcel Holtmann case HCI_OP_AUTH_REQUESTED: 2885f8558555SMarcel Holtmann hci_cs_auth_requested(hdev, ev->status); 2886f8558555SMarcel Holtmann break; 2887f8558555SMarcel Holtmann 2888f8558555SMarcel Holtmann case HCI_OP_SET_CONN_ENCRYPT: 2889f8558555SMarcel Holtmann hci_cs_set_conn_encrypt(hdev, ev->status); 2890f8558555SMarcel Holtmann break; 2891f8558555SMarcel Holtmann 2892a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ: 2893a9de9248SMarcel Holtmann hci_cs_remote_name_req(hdev, ev->status); 2894a9de9248SMarcel Holtmann break; 2895a9de9248SMarcel Holtmann 2896769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_FEATURES: 2897769be974SMarcel Holtmann hci_cs_read_remote_features(hdev, ev->status); 2898769be974SMarcel Holtmann break; 2899769be974SMarcel Holtmann 2900769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_EXT_FEATURES: 2901769be974SMarcel Holtmann hci_cs_read_remote_ext_features(hdev, ev->status); 2902769be974SMarcel Holtmann break; 2903769be974SMarcel Holtmann 2904a9de9248SMarcel Holtmann case HCI_OP_SETUP_SYNC_CONN: 2905a9de9248SMarcel Holtmann hci_cs_setup_sync_conn(hdev, ev->status); 2906a9de9248SMarcel Holtmann break; 2907a9de9248SMarcel Holtmann 29089645c76cSKuba Pawlak case HCI_OP_CREATE_PHY_LINK: 29099645c76cSKuba Pawlak hci_cs_create_phylink(hdev, ev->status); 29109645c76cSKuba Pawlak break; 29119645c76cSKuba Pawlak 29129645c76cSKuba Pawlak case HCI_OP_ACCEPT_PHY_LINK: 29139645c76cSKuba Pawlak hci_cs_accept_phylink(hdev, ev->status); 29149645c76cSKuba Pawlak break; 29159645c76cSKuba Pawlak 2916a9de9248SMarcel Holtmann case HCI_OP_SNIFF_MODE: 2917a9de9248SMarcel Holtmann hci_cs_sniff_mode(hdev, ev->status); 2918a9de9248SMarcel Holtmann break; 2919a9de9248SMarcel Holtmann 2920a9de9248SMarcel Holtmann case HCI_OP_EXIT_SNIFF_MODE: 2921a9de9248SMarcel Holtmann hci_cs_exit_sniff_mode(hdev, ev->status); 2922a9de9248SMarcel Holtmann break; 2923a9de9248SMarcel Holtmann 292450fc85f1SKuba Pawlak case HCI_OP_SWITCH_ROLE: 292550fc85f1SKuba Pawlak hci_cs_switch_role(hdev, ev->status); 292650fc85f1SKuba Pawlak break; 292750fc85f1SKuba Pawlak 2928cb1d68f7SJohan Hedberg case HCI_OP_LE_CREATE_CONN: 2929cb1d68f7SJohan Hedberg hci_cs_le_create_conn(hdev, ev->status); 2930cb1d68f7SJohan Hedberg break; 2931cb1d68f7SJohan Hedberg 293281d0c8adSJohan Hedberg case HCI_OP_LE_START_ENC: 293381d0c8adSJohan Hedberg hci_cs_le_start_enc(hdev, ev->status); 293481d0c8adSJohan Hedberg break; 293581d0c8adSJohan Hedberg 2936a9de9248SMarcel Holtmann default: 29379f1db00cSAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 2938a9de9248SMarcel Holtmann break; 2939a9de9248SMarcel Holtmann } 2940a9de9248SMarcel Holtmann 2941ad82cdd1SJohan Hedberg if (opcode != HCI_OP_NOP) 294265cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer); 29436bd32326SVille Tervo 294402350a72SJohan Hedberg if (ev->status || 294502350a72SJohan Hedberg (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event)) 294633720450SAndre Guedes hci_req_cmd_complete(hdev, opcode, ev->status); 29479238f36aSJohan Hedberg 294810572132SGustavo F. Padovan if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { 2949a9de9248SMarcel Holtmann atomic_set(&hdev->cmd_cnt, 1); 2950a9de9248SMarcel Holtmann if (!skb_queue_empty(&hdev->cmd_q)) 2951c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 2952a9de9248SMarcel Holtmann } 2953a9de9248SMarcel Holtmann } 2954a9de9248SMarcel Holtmann 295524dfa343SMarcel Holtmann static void hci_hardware_error_evt(struct hci_dev *hdev, struct sk_buff *skb) 295624dfa343SMarcel Holtmann { 295724dfa343SMarcel Holtmann struct hci_ev_hardware_error *ev = (void *) skb->data; 295824dfa343SMarcel Holtmann 295924dfa343SMarcel Holtmann BT_ERR("%s hardware error 0x%2.2x", hdev->name, ev->code); 296024dfa343SMarcel Holtmann } 296124dfa343SMarcel Holtmann 29626039aa73SGustavo Padovan static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2963a9de9248SMarcel Holtmann { 2964a9de9248SMarcel Holtmann struct hci_ev_role_change *ev = (void *) skb->data; 2965a9de9248SMarcel Holtmann struct hci_conn *conn; 2966a9de9248SMarcel Holtmann 29679f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2968a9de9248SMarcel Holtmann 2969a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2970a9de9248SMarcel Holtmann 2971a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2972a9de9248SMarcel Holtmann if (conn) { 297340bef302SJohan Hedberg if (!ev->status) 297440bef302SJohan Hedberg conn->role = ev->role; 2975a9de9248SMarcel Holtmann 297651a8efd7SJohan Hedberg clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 2977a9de9248SMarcel Holtmann 2978a9de9248SMarcel Holtmann hci_role_switch_cfm(conn, ev->status, ev->role); 2979a9de9248SMarcel Holtmann } 2980a9de9248SMarcel Holtmann 2981a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2982a9de9248SMarcel Holtmann } 2983a9de9248SMarcel Holtmann 29846039aa73SGustavo Padovan static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) 29851da177e4SLinus Torvalds { 2986a9de9248SMarcel Holtmann struct hci_ev_num_comp_pkts *ev = (void *) skb->data; 29871da177e4SLinus Torvalds int i; 29881da177e4SLinus Torvalds 298932ac5b9bSAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) { 299032ac5b9bSAndrei Emeltchenko BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); 299132ac5b9bSAndrei Emeltchenko return; 299232ac5b9bSAndrei Emeltchenko } 299332ac5b9bSAndrei Emeltchenko 2994c5993de8SAndrei Emeltchenko if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + 2995c5993de8SAndrei Emeltchenko ev->num_hndl * sizeof(struct hci_comp_pkts_info)) { 29961da177e4SLinus Torvalds BT_DBG("%s bad parameters", hdev->name); 29971da177e4SLinus Torvalds return; 29981da177e4SLinus Torvalds } 29991da177e4SLinus Torvalds 3000c5993de8SAndrei Emeltchenko BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl); 3001c5993de8SAndrei Emeltchenko 3002613a1c0cSAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 3003613a1c0cSAndrei Emeltchenko struct hci_comp_pkts_info *info = &ev->handles[i]; 30041da177e4SLinus Torvalds struct hci_conn *conn; 30051da177e4SLinus Torvalds __u16 handle, count; 30061da177e4SLinus Torvalds 3007613a1c0cSAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 3008613a1c0cSAndrei Emeltchenko count = __le16_to_cpu(info->count); 30091da177e4SLinus Torvalds 30101da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 3011f4280918SAndrei Emeltchenko if (!conn) 3012f4280918SAndrei Emeltchenko continue; 3013f4280918SAndrei Emeltchenko 30141da177e4SLinus Torvalds conn->sent -= count; 30151da177e4SLinus Torvalds 3016f4280918SAndrei Emeltchenko switch (conn->type) { 3017f4280918SAndrei Emeltchenko case ACL_LINK: 301870f23020SAndrei Emeltchenko hdev->acl_cnt += count; 301970f23020SAndrei Emeltchenko if (hdev->acl_cnt > hdev->acl_pkts) 30201da177e4SLinus Torvalds hdev->acl_cnt = hdev->acl_pkts; 3021f4280918SAndrei Emeltchenko break; 3022f4280918SAndrei Emeltchenko 3023f4280918SAndrei Emeltchenko case LE_LINK: 30246ed58ec5SVille Tervo if (hdev->le_pkts) { 30256ed58ec5SVille Tervo hdev->le_cnt += count; 30266ed58ec5SVille Tervo if (hdev->le_cnt > hdev->le_pkts) 30276ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 30286ed58ec5SVille Tervo } else { 30296ed58ec5SVille Tervo hdev->acl_cnt += count; 30306ed58ec5SVille Tervo if (hdev->acl_cnt > hdev->acl_pkts) 30316ed58ec5SVille Tervo hdev->acl_cnt = hdev->acl_pkts; 30326ed58ec5SVille Tervo } 3033f4280918SAndrei Emeltchenko break; 3034f4280918SAndrei Emeltchenko 3035f4280918SAndrei Emeltchenko case SCO_LINK: 303670f23020SAndrei Emeltchenko hdev->sco_cnt += count; 303770f23020SAndrei Emeltchenko if (hdev->sco_cnt > hdev->sco_pkts) 30385b7f9909SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 3039f4280918SAndrei Emeltchenko break; 3040f4280918SAndrei Emeltchenko 3041f4280918SAndrei Emeltchenko default: 3042f4280918SAndrei Emeltchenko BT_ERR("Unknown type %d conn %p", conn->type, conn); 3043f4280918SAndrei Emeltchenko break; 30441da177e4SLinus Torvalds } 30451da177e4SLinus Torvalds } 3046a9de9248SMarcel Holtmann 30473eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 30481da177e4SLinus Torvalds } 30491da177e4SLinus Torvalds 305076ef7cf7SAndrei Emeltchenko static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev, 305176ef7cf7SAndrei Emeltchenko __u16 handle) 305276ef7cf7SAndrei Emeltchenko { 305376ef7cf7SAndrei Emeltchenko struct hci_chan *chan; 305476ef7cf7SAndrei Emeltchenko 305576ef7cf7SAndrei Emeltchenko switch (hdev->dev_type) { 305676ef7cf7SAndrei Emeltchenko case HCI_BREDR: 305776ef7cf7SAndrei Emeltchenko return hci_conn_hash_lookup_handle(hdev, handle); 305876ef7cf7SAndrei Emeltchenko case HCI_AMP: 305976ef7cf7SAndrei Emeltchenko chan = hci_chan_lookup_handle(hdev, handle); 306076ef7cf7SAndrei Emeltchenko if (chan) 306176ef7cf7SAndrei Emeltchenko return chan->conn; 306276ef7cf7SAndrei Emeltchenko break; 306376ef7cf7SAndrei Emeltchenko default: 306476ef7cf7SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 306576ef7cf7SAndrei Emeltchenko break; 306676ef7cf7SAndrei Emeltchenko } 306776ef7cf7SAndrei Emeltchenko 306876ef7cf7SAndrei Emeltchenko return NULL; 306976ef7cf7SAndrei Emeltchenko } 307076ef7cf7SAndrei Emeltchenko 30716039aa73SGustavo Padovan static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) 307225e89e99SAndrei Emeltchenko { 307325e89e99SAndrei Emeltchenko struct hci_ev_num_comp_blocks *ev = (void *) skb->data; 307425e89e99SAndrei Emeltchenko int i; 307525e89e99SAndrei Emeltchenko 307625e89e99SAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) { 307725e89e99SAndrei Emeltchenko BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); 307825e89e99SAndrei Emeltchenko return; 307925e89e99SAndrei Emeltchenko } 308025e89e99SAndrei Emeltchenko 308125e89e99SAndrei Emeltchenko if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + 308225e89e99SAndrei Emeltchenko ev->num_hndl * sizeof(struct hci_comp_blocks_info)) { 308325e89e99SAndrei Emeltchenko BT_DBG("%s bad parameters", hdev->name); 308425e89e99SAndrei Emeltchenko return; 308525e89e99SAndrei Emeltchenko } 308625e89e99SAndrei Emeltchenko 308725e89e99SAndrei Emeltchenko BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks, 308825e89e99SAndrei Emeltchenko ev->num_hndl); 308925e89e99SAndrei Emeltchenko 309025e89e99SAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 309125e89e99SAndrei Emeltchenko struct hci_comp_blocks_info *info = &ev->handles[i]; 309276ef7cf7SAndrei Emeltchenko struct hci_conn *conn = NULL; 309325e89e99SAndrei Emeltchenko __u16 handle, block_count; 309425e89e99SAndrei Emeltchenko 309525e89e99SAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 309625e89e99SAndrei Emeltchenko block_count = __le16_to_cpu(info->blocks); 309725e89e99SAndrei Emeltchenko 309876ef7cf7SAndrei Emeltchenko conn = __hci_conn_lookup_handle(hdev, handle); 309925e89e99SAndrei Emeltchenko if (!conn) 310025e89e99SAndrei Emeltchenko continue; 310125e89e99SAndrei Emeltchenko 310225e89e99SAndrei Emeltchenko conn->sent -= block_count; 310325e89e99SAndrei Emeltchenko 310425e89e99SAndrei Emeltchenko switch (conn->type) { 310525e89e99SAndrei Emeltchenko case ACL_LINK: 3106bd1eb66bSAndrei Emeltchenko case AMP_LINK: 310725e89e99SAndrei Emeltchenko hdev->block_cnt += block_count; 310825e89e99SAndrei Emeltchenko if (hdev->block_cnt > hdev->num_blocks) 310925e89e99SAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 311025e89e99SAndrei Emeltchenko break; 311125e89e99SAndrei Emeltchenko 311225e89e99SAndrei Emeltchenko default: 311325e89e99SAndrei Emeltchenko BT_ERR("Unknown type %d conn %p", conn->type, conn); 311425e89e99SAndrei Emeltchenko break; 311525e89e99SAndrei Emeltchenko } 311625e89e99SAndrei Emeltchenko } 311725e89e99SAndrei Emeltchenko 311825e89e99SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->tx_work); 311925e89e99SAndrei Emeltchenko } 312025e89e99SAndrei Emeltchenko 31216039aa73SGustavo Padovan static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 31221da177e4SLinus Torvalds { 3123a9de9248SMarcel Holtmann struct hci_ev_mode_change *ev = (void *) skb->data; 312404837f64SMarcel Holtmann struct hci_conn *conn; 31251da177e4SLinus Torvalds 31269f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 31271da177e4SLinus Torvalds 31281da177e4SLinus Torvalds hci_dev_lock(hdev); 31291da177e4SLinus Torvalds 313004837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 313104837f64SMarcel Holtmann if (conn) { 313204837f64SMarcel Holtmann conn->mode = ev->mode; 313304837f64SMarcel Holtmann 31348fc9ced3SGustavo Padovan if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, 31358fc9ced3SGustavo Padovan &conn->flags)) { 313604837f64SMarcel Holtmann if (conn->mode == HCI_CM_ACTIVE) 313758a681efSJohan Hedberg set_bit(HCI_CONN_POWER_SAVE, &conn->flags); 313804837f64SMarcel Holtmann else 313958a681efSJohan Hedberg clear_bit(HCI_CONN_POWER_SAVE, &conn->flags); 314004837f64SMarcel Holtmann } 3141e73439d8SMarcel Holtmann 314251a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 3143e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 314404837f64SMarcel Holtmann } 314504837f64SMarcel Holtmann 314604837f64SMarcel Holtmann hci_dev_unlock(hdev); 314704837f64SMarcel Holtmann } 314804837f64SMarcel Holtmann 31496039aa73SGustavo Padovan static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 31501da177e4SLinus Torvalds { 3151052b30b0SMarcel Holtmann struct hci_ev_pin_code_req *ev = (void *) skb->data; 3152052b30b0SMarcel Holtmann struct hci_conn *conn; 3153052b30b0SMarcel Holtmann 3154a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 3155052b30b0SMarcel Holtmann 3156052b30b0SMarcel Holtmann hci_dev_lock(hdev); 3157052b30b0SMarcel Holtmann 3158052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 3159b6f98044SWaldemar Rymarkiewicz if (!conn) 3160b6f98044SWaldemar Rymarkiewicz goto unlock; 3161b6f98044SWaldemar Rymarkiewicz 3162b6f98044SWaldemar Rymarkiewicz if (conn->state == BT_CONNECTED) { 3163052b30b0SMarcel Holtmann hci_conn_hold(conn); 3164052b30b0SMarcel Holtmann conn->disc_timeout = HCI_PAIRING_TIMEOUT; 316576a68ba0SDavid Herrmann hci_conn_drop(conn); 3166052b30b0SMarcel Holtmann } 3167052b30b0SMarcel Holtmann 3168b6ae8457SJohan Hedberg if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) && 31692f407f0aSJohan Hedberg !test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags)) { 317003b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, 317103b555e1SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 31722f407f0aSJohan Hedberg } else if (test_bit(HCI_MGMT, &hdev->dev_flags)) { 3173a770bb5aSWaldemar Rymarkiewicz u8 secure; 3174a770bb5aSWaldemar Rymarkiewicz 3175a770bb5aSWaldemar Rymarkiewicz if (conn->pending_sec_level == BT_SECURITY_HIGH) 3176a770bb5aSWaldemar Rymarkiewicz secure = 1; 3177a770bb5aSWaldemar Rymarkiewicz else 3178a770bb5aSWaldemar Rymarkiewicz secure = 0; 3179a770bb5aSWaldemar Rymarkiewicz 3180744cf19eSJohan Hedberg mgmt_pin_code_request(hdev, &ev->bdaddr, secure); 3181a770bb5aSWaldemar Rymarkiewicz } 3182980e1a53SJohan Hedberg 3183b6f98044SWaldemar Rymarkiewicz unlock: 3184052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 31851da177e4SLinus Torvalds } 31861da177e4SLinus Torvalds 31876039aa73SGustavo Padovan static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 31881da177e4SLinus Torvalds { 318955ed8ca1SJohan Hedberg struct hci_ev_link_key_req *ev = (void *) skb->data; 319055ed8ca1SJohan Hedberg struct hci_cp_link_key_reply cp; 319155ed8ca1SJohan Hedberg struct hci_conn *conn; 319255ed8ca1SJohan Hedberg struct link_key *key; 319355ed8ca1SJohan Hedberg 3194a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 319555ed8ca1SJohan Hedberg 3196034cbea0SAndrei Emeltchenko if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 319755ed8ca1SJohan Hedberg return; 319855ed8ca1SJohan Hedberg 319955ed8ca1SJohan Hedberg hci_dev_lock(hdev); 320055ed8ca1SJohan Hedberg 320155ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, &ev->bdaddr); 320255ed8ca1SJohan Hedberg if (!key) { 32036ed93dc6SAndrei Emeltchenko BT_DBG("%s link key not found for %pMR", hdev->name, 32046ed93dc6SAndrei Emeltchenko &ev->bdaddr); 320555ed8ca1SJohan Hedberg goto not_found; 320655ed8ca1SJohan Hedberg } 320755ed8ca1SJohan Hedberg 32086ed93dc6SAndrei Emeltchenko BT_DBG("%s found key type %u for %pMR", hdev->name, key->type, 32096ed93dc6SAndrei Emeltchenko &ev->bdaddr); 321055ed8ca1SJohan Hedberg 321155ed8ca1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 321260b83f57SWaldemar Rymarkiewicz if (conn) { 321366138ce8SMarcel Holtmann if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 || 321466138ce8SMarcel Holtmann key->type == HCI_LK_UNAUTH_COMBINATION_P256) && 3215807deac2SGustavo Padovan conn->auth_type != 0xff && (conn->auth_type & 0x01)) { 321655ed8ca1SJohan Hedberg BT_DBG("%s ignoring unauthenticated key", hdev->name); 321755ed8ca1SJohan Hedberg goto not_found; 321855ed8ca1SJohan Hedberg } 321955ed8ca1SJohan Hedberg 322060b83f57SWaldemar Rymarkiewicz if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && 3221f3fb0b58SJohan Hedberg (conn->pending_sec_level == BT_SECURITY_HIGH || 3222f3fb0b58SJohan Hedberg conn->pending_sec_level == BT_SECURITY_FIPS)) { 32238fc9ced3SGustavo Padovan BT_DBG("%s ignoring key unauthenticated for high security", 32248fc9ced3SGustavo Padovan hdev->name); 322560b83f57SWaldemar Rymarkiewicz goto not_found; 322660b83f57SWaldemar Rymarkiewicz } 322760b83f57SWaldemar Rymarkiewicz 322860b83f57SWaldemar Rymarkiewicz conn->key_type = key->type; 322960b83f57SWaldemar Rymarkiewicz conn->pin_length = key->pin_len; 323060b83f57SWaldemar Rymarkiewicz } 323160b83f57SWaldemar Rymarkiewicz 323255ed8ca1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 32339b3b4460SAndrei Emeltchenko memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE); 323455ed8ca1SJohan Hedberg 323555ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp); 323655ed8ca1SJohan Hedberg 323755ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 323855ed8ca1SJohan Hedberg 323955ed8ca1SJohan Hedberg return; 324055ed8ca1SJohan Hedberg 324155ed8ca1SJohan Hedberg not_found: 324255ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr); 324355ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 32441da177e4SLinus Torvalds } 32451da177e4SLinus Torvalds 32466039aa73SGustavo Padovan static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 32471da177e4SLinus Torvalds { 3248052b30b0SMarcel Holtmann struct hci_ev_link_key_notify *ev = (void *) skb->data; 3249052b30b0SMarcel Holtmann struct hci_conn *conn; 32507652ff6aSJohan Hedberg struct link_key *key; 32517652ff6aSJohan Hedberg bool persistent; 325255ed8ca1SJohan Hedberg u8 pin_len = 0; 3253052b30b0SMarcel Holtmann 3254a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 3255052b30b0SMarcel Holtmann 3256052b30b0SMarcel Holtmann hci_dev_lock(hdev); 3257052b30b0SMarcel Holtmann 3258052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 3259052b30b0SMarcel Holtmann if (conn) { 3260052b30b0SMarcel Holtmann hci_conn_hold(conn); 3261052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 3262980e1a53SJohan Hedberg pin_len = conn->pin_length; 326313d39315SWaldemar Rymarkiewicz 326413d39315SWaldemar Rymarkiewicz if (ev->key_type != HCI_LK_CHANGED_COMBINATION) 326513d39315SWaldemar Rymarkiewicz conn->key_type = ev->key_type; 326613d39315SWaldemar Rymarkiewicz 326776a68ba0SDavid Herrmann hci_conn_drop(conn); 3268052b30b0SMarcel Holtmann } 3269052b30b0SMarcel Holtmann 32707652ff6aSJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 32717652ff6aSJohan Hedberg goto unlock; 327255ed8ca1SJohan Hedberg 32737652ff6aSJohan Hedberg key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key, 32747652ff6aSJohan Hedberg ev->key_type, pin_len, &persistent); 32757652ff6aSJohan Hedberg if (!key) 32767652ff6aSJohan Hedberg goto unlock; 32777652ff6aSJohan Hedberg 32787652ff6aSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 32797652ff6aSJohan Hedberg 32806d5650c4SJohan Hedberg /* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag 32816d5650c4SJohan Hedberg * is set. If it's not set simply remove the key from the kernel 32826d5650c4SJohan Hedberg * list (we've still notified user space about it but with 32836d5650c4SJohan Hedberg * store_hint being 0). 32846d5650c4SJohan Hedberg */ 32856d5650c4SJohan Hedberg if (key->type == HCI_LK_DEBUG_COMBINATION && 32866d5650c4SJohan Hedberg !test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags)) { 32876d5650c4SJohan Hedberg list_del(&key->list); 32886d5650c4SJohan Hedberg kfree(key); 32896d5650c4SJohan Hedberg } else if (conn) { 3290af6a9c32SJohan Hedberg if (persistent) 3291af6a9c32SJohan Hedberg clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags); 3292af6a9c32SJohan Hedberg else 3293af6a9c32SJohan Hedberg set_bit(HCI_CONN_FLUSH_KEY, &conn->flags); 32946d5650c4SJohan Hedberg } 32957652ff6aSJohan Hedberg 32967652ff6aSJohan Hedberg unlock: 3297052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 32981da177e4SLinus Torvalds } 32991da177e4SLinus Torvalds 33006039aa73SGustavo Padovan static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) 330104837f64SMarcel Holtmann { 3302a9de9248SMarcel Holtmann struct hci_ev_clock_offset *ev = (void *) skb->data; 330304837f64SMarcel Holtmann struct hci_conn *conn; 330404837f64SMarcel Holtmann 33059f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 330604837f64SMarcel Holtmann 330704837f64SMarcel Holtmann hci_dev_lock(hdev); 330804837f64SMarcel Holtmann 330904837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 33101da177e4SLinus Torvalds if (conn && !ev->status) { 33111da177e4SLinus Torvalds struct inquiry_entry *ie; 33121da177e4SLinus Torvalds 3313cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 3314cc11b9c1SAndrei Emeltchenko if (ie) { 33151da177e4SLinus Torvalds ie->data.clock_offset = ev->clock_offset; 33161da177e4SLinus Torvalds ie->timestamp = jiffies; 33171da177e4SLinus Torvalds } 33181da177e4SLinus Torvalds } 33191da177e4SLinus Torvalds 33201da177e4SLinus Torvalds hci_dev_unlock(hdev); 33211da177e4SLinus Torvalds } 33221da177e4SLinus Torvalds 33236039aa73SGustavo Padovan static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 3324a8746417SMarcel Holtmann { 3325a8746417SMarcel Holtmann struct hci_ev_pkt_type_change *ev = (void *) skb->data; 3326a8746417SMarcel Holtmann struct hci_conn *conn; 3327a8746417SMarcel Holtmann 33289f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3329a8746417SMarcel Holtmann 3330a8746417SMarcel Holtmann hci_dev_lock(hdev); 3331a8746417SMarcel Holtmann 3332a8746417SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3333a8746417SMarcel Holtmann if (conn && !ev->status) 3334a8746417SMarcel Holtmann conn->pkt_type = __le16_to_cpu(ev->pkt_type); 3335a8746417SMarcel Holtmann 3336a8746417SMarcel Holtmann hci_dev_unlock(hdev); 3337a8746417SMarcel Holtmann } 3338a8746417SMarcel Holtmann 33396039aa73SGustavo Padovan static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) 334085a1e930SMarcel Holtmann { 3341a9de9248SMarcel Holtmann struct hci_ev_pscan_rep_mode *ev = (void *) skb->data; 334285a1e930SMarcel Holtmann struct inquiry_entry *ie; 334385a1e930SMarcel Holtmann 334485a1e930SMarcel Holtmann BT_DBG("%s", hdev->name); 334585a1e930SMarcel Holtmann 334685a1e930SMarcel Holtmann hci_dev_lock(hdev); 334785a1e930SMarcel Holtmann 3348cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 3349cc11b9c1SAndrei Emeltchenko if (ie) { 335085a1e930SMarcel Holtmann ie->data.pscan_rep_mode = ev->pscan_rep_mode; 335185a1e930SMarcel Holtmann ie->timestamp = jiffies; 335285a1e930SMarcel Holtmann } 335385a1e930SMarcel Holtmann 335485a1e930SMarcel Holtmann hci_dev_unlock(hdev); 335585a1e930SMarcel Holtmann } 335685a1e930SMarcel Holtmann 33576039aa73SGustavo Padovan static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, 3358807deac2SGustavo Padovan struct sk_buff *skb) 3359a9de9248SMarcel Holtmann { 3360a9de9248SMarcel Holtmann struct inquiry_data data; 3361a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 3362a9de9248SMarcel Holtmann 3363a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 3364a9de9248SMarcel Holtmann 3365a9de9248SMarcel Holtmann if (!num_rsp) 3366a9de9248SMarcel Holtmann return; 3367a9de9248SMarcel Holtmann 33681519cc17SAndre Guedes if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) 33691519cc17SAndre Guedes return; 33701519cc17SAndre Guedes 3371a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3372a9de9248SMarcel Holtmann 3373a9de9248SMarcel Holtmann if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { 3374138d22efSSzymon Janc struct inquiry_info_with_rssi_and_pscan_mode *info; 3375138d22efSSzymon Janc info = (void *) (skb->data + 1); 3376a9de9248SMarcel Holtmann 3377e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3378af58925cSMarcel Holtmann u32 flags; 3379af58925cSMarcel Holtmann 3380a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3381a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3382a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3383a9de9248SMarcel Holtmann data.pscan_mode = info->pscan_mode; 3384a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3385a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3386a9de9248SMarcel Holtmann data.rssi = info->rssi; 338741a96212SMarcel Holtmann data.ssp_mode = 0x00; 33883175405bSJohan Hedberg 3389af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 3390af58925cSMarcel Holtmann 339148264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3392e17acd40SJohan Hedberg info->dev_class, info->rssi, 3393af58925cSMarcel Holtmann flags, NULL, 0, NULL, 0); 3394a9de9248SMarcel Holtmann } 3395a9de9248SMarcel Holtmann } else { 3396a9de9248SMarcel Holtmann struct inquiry_info_with_rssi *info = (void *) (skb->data + 1); 3397a9de9248SMarcel Holtmann 3398e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3399af58925cSMarcel Holtmann u32 flags; 3400af58925cSMarcel Holtmann 3401a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3402a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3403a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3404a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 3405a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3406a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3407a9de9248SMarcel Holtmann data.rssi = info->rssi; 340841a96212SMarcel Holtmann data.ssp_mode = 0x00; 3409af58925cSMarcel Holtmann 3410af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 3411af58925cSMarcel Holtmann 341248264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3413e17acd40SJohan Hedberg info->dev_class, info->rssi, 3414af58925cSMarcel Holtmann flags, NULL, 0, NULL, 0); 3415a9de9248SMarcel Holtmann } 3416a9de9248SMarcel Holtmann } 3417a9de9248SMarcel Holtmann 3418a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3419a9de9248SMarcel Holtmann } 3420a9de9248SMarcel Holtmann 34216039aa73SGustavo Padovan static void hci_remote_ext_features_evt(struct hci_dev *hdev, 3422807deac2SGustavo Padovan struct sk_buff *skb) 3423a9de9248SMarcel Holtmann { 342441a96212SMarcel Holtmann struct hci_ev_remote_ext_features *ev = (void *) skb->data; 342541a96212SMarcel Holtmann struct hci_conn *conn; 342641a96212SMarcel Holtmann 3427a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 342841a96212SMarcel Holtmann 342941a96212SMarcel Holtmann hci_dev_lock(hdev); 343041a96212SMarcel Holtmann 343141a96212SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3432ccd556feSJohan Hedberg if (!conn) 3433ccd556feSJohan Hedberg goto unlock; 3434ccd556feSJohan Hedberg 3435cad718edSJohan Hedberg if (ev->page < HCI_MAX_PAGES) 3436cad718edSJohan Hedberg memcpy(conn->features[ev->page], ev->features, 8); 3437cad718edSJohan Hedberg 3438769be974SMarcel Holtmann if (!ev->status && ev->page == 0x01) { 343941a96212SMarcel Holtmann struct inquiry_entry *ie; 344041a96212SMarcel Holtmann 3441cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 3442cc11b9c1SAndrei Emeltchenko if (ie) 344302b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 344441a96212SMarcel Holtmann 3445bbb0eadaSJaganath Kanakkassery if (ev->features[0] & LMP_HOST_SSP) { 344658a681efSJohan Hedberg set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 3447bbb0eadaSJaganath Kanakkassery } else { 3448bbb0eadaSJaganath Kanakkassery /* It is mandatory by the Bluetooth specification that 3449bbb0eadaSJaganath Kanakkassery * Extended Inquiry Results are only used when Secure 3450bbb0eadaSJaganath Kanakkassery * Simple Pairing is enabled, but some devices violate 3451bbb0eadaSJaganath Kanakkassery * this. 3452bbb0eadaSJaganath Kanakkassery * 3453bbb0eadaSJaganath Kanakkassery * To make these devices work, the internal SSP 3454bbb0eadaSJaganath Kanakkassery * enabled flag needs to be cleared if the remote host 3455bbb0eadaSJaganath Kanakkassery * features do not indicate SSP support */ 3456bbb0eadaSJaganath Kanakkassery clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 3457bbb0eadaSJaganath Kanakkassery } 3458eb9a8f3fSMarcel Holtmann 3459eb9a8f3fSMarcel Holtmann if (ev->features[0] & LMP_HOST_SC) 3460eb9a8f3fSMarcel Holtmann set_bit(HCI_CONN_SC_ENABLED, &conn->flags); 346141a96212SMarcel Holtmann } 346241a96212SMarcel Holtmann 3463ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 3464ccd556feSJohan Hedberg goto unlock; 3465ccd556feSJohan Hedberg 3466671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 3467127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 3468127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 3469127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 3470127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 3471127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 3472b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 347348ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, NULL, 0); 3474392599b9SJohan Hedberg 3475127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 3476769be974SMarcel Holtmann conn->state = BT_CONNECTED; 3477769be974SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 347876a68ba0SDavid Herrmann hci_conn_drop(conn); 3479769be974SMarcel Holtmann } 3480769be974SMarcel Holtmann 3481ccd556feSJohan Hedberg unlock: 348241a96212SMarcel Holtmann hci_dev_unlock(hdev); 3483a9de9248SMarcel Holtmann } 3484a9de9248SMarcel Holtmann 34856039aa73SGustavo Padovan static void hci_sync_conn_complete_evt(struct hci_dev *hdev, 3486807deac2SGustavo Padovan struct sk_buff *skb) 3487a9de9248SMarcel Holtmann { 3488b6a0dc82SMarcel Holtmann struct hci_ev_sync_conn_complete *ev = (void *) skb->data; 3489b6a0dc82SMarcel Holtmann struct hci_conn *conn; 3490b6a0dc82SMarcel Holtmann 34919f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3492b6a0dc82SMarcel Holtmann 3493b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 3494b6a0dc82SMarcel Holtmann 3495b6a0dc82SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 34969dc0a3afSMarcel Holtmann if (!conn) { 34979dc0a3afSMarcel Holtmann if (ev->link_type == ESCO_LINK) 34989dc0a3afSMarcel Holtmann goto unlock; 34999dc0a3afSMarcel Holtmann 35009dc0a3afSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 3501b6a0dc82SMarcel Holtmann if (!conn) 3502b6a0dc82SMarcel Holtmann goto unlock; 3503b6a0dc82SMarcel Holtmann 35049dc0a3afSMarcel Holtmann conn->type = SCO_LINK; 35059dc0a3afSMarcel Holtmann } 35069dc0a3afSMarcel Holtmann 3507732547f9SMarcel Holtmann switch (ev->status) { 3508732547f9SMarcel Holtmann case 0x00: 3509732547f9SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 3510732547f9SMarcel Holtmann conn->state = BT_CONNECTED; 3511732547f9SMarcel Holtmann 3512732547f9SMarcel Holtmann hci_conn_add_sysfs(conn); 3513732547f9SMarcel Holtmann break; 3514732547f9SMarcel Holtmann 351581218d20SNick Pelly case 0x10: /* Connection Accept Timeout */ 35161a4c958cSFrédéric Dalleau case 0x0d: /* Connection Rejected due to Limited Resources */ 3517705e5711SStephen Coe case 0x11: /* Unsupported Feature or Parameter Value */ 3518732547f9SMarcel Holtmann case 0x1c: /* SCO interval rejected */ 35191038a00bSNick Pelly case 0x1a: /* Unsupported Remote Feature */ 3520732547f9SMarcel Holtmann case 0x1f: /* Unspecified error */ 352127539bc4SAndrew Earl case 0x20: /* Unsupported LMP Parameter value */ 35222dea632fSFrédéric Dalleau if (conn->out) { 3523efc7688bSMarcel Holtmann conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | 3524efc7688bSMarcel Holtmann (hdev->esco_type & EDR_ESCO_MASK); 35252dea632fSFrédéric Dalleau if (hci_setup_sync(conn, conn->link->handle)) 3526efc7688bSMarcel Holtmann goto unlock; 3527efc7688bSMarcel Holtmann } 3528732547f9SMarcel Holtmann /* fall through */ 3529efc7688bSMarcel Holtmann 3530732547f9SMarcel Holtmann default: 3531b6a0dc82SMarcel Holtmann conn->state = BT_CLOSED; 3532732547f9SMarcel Holtmann break; 3533732547f9SMarcel Holtmann } 3534b6a0dc82SMarcel Holtmann 3535b6a0dc82SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 3536b6a0dc82SMarcel Holtmann if (ev->status) 3537b6a0dc82SMarcel Holtmann hci_conn_del(conn); 3538b6a0dc82SMarcel Holtmann 3539b6a0dc82SMarcel Holtmann unlock: 3540b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 3541a9de9248SMarcel Holtmann } 3542a9de9248SMarcel Holtmann 3543efdcf8e3SMarcel Holtmann static inline size_t eir_get_length(u8 *eir, size_t eir_len) 3544efdcf8e3SMarcel Holtmann { 3545efdcf8e3SMarcel Holtmann size_t parsed = 0; 3546efdcf8e3SMarcel Holtmann 3547efdcf8e3SMarcel Holtmann while (parsed < eir_len) { 3548efdcf8e3SMarcel Holtmann u8 field_len = eir[0]; 3549efdcf8e3SMarcel Holtmann 3550efdcf8e3SMarcel Holtmann if (field_len == 0) 3551efdcf8e3SMarcel Holtmann return parsed; 3552efdcf8e3SMarcel Holtmann 3553efdcf8e3SMarcel Holtmann parsed += field_len + 1; 3554efdcf8e3SMarcel Holtmann eir += field_len + 1; 3555efdcf8e3SMarcel Holtmann } 3556efdcf8e3SMarcel Holtmann 3557efdcf8e3SMarcel Holtmann return eir_len; 3558efdcf8e3SMarcel Holtmann } 3559efdcf8e3SMarcel Holtmann 35606039aa73SGustavo Padovan static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, 3561807deac2SGustavo Padovan struct sk_buff *skb) 3562a9de9248SMarcel Holtmann { 3563a9de9248SMarcel Holtmann struct inquiry_data data; 3564a9de9248SMarcel Holtmann struct extended_inquiry_info *info = (void *) (skb->data + 1); 3565a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 35669d939d94SVishal Agarwal size_t eir_len; 3567a9de9248SMarcel Holtmann 3568a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 3569a9de9248SMarcel Holtmann 3570a9de9248SMarcel Holtmann if (!num_rsp) 3571a9de9248SMarcel Holtmann return; 3572a9de9248SMarcel Holtmann 35731519cc17SAndre Guedes if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) 35741519cc17SAndre Guedes return; 35751519cc17SAndre Guedes 3576a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3577a9de9248SMarcel Holtmann 3578e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3579af58925cSMarcel Holtmann u32 flags; 3580af58925cSMarcel Holtmann bool name_known; 3581561aafbcSJohan Hedberg 3582a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3583a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3584a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3585a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 3586a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3587a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3588a9de9248SMarcel Holtmann data.rssi = info->rssi; 358941a96212SMarcel Holtmann data.ssp_mode = 0x01; 3590561aafbcSJohan Hedberg 3591a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 35924ddb1930SJohan Hedberg name_known = eir_has_data_type(info->data, 35934ddb1930SJohan Hedberg sizeof(info->data), 35944ddb1930SJohan Hedberg EIR_NAME_COMPLETE); 3595561aafbcSJohan Hedberg else 3596561aafbcSJohan Hedberg name_known = true; 3597561aafbcSJohan Hedberg 3598af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, name_known); 3599af58925cSMarcel Holtmann 36009d939d94SVishal Agarwal eir_len = eir_get_length(info->data, sizeof(info->data)); 3601af58925cSMarcel Holtmann 360248264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3603af58925cSMarcel Holtmann info->dev_class, info->rssi, 3604af58925cSMarcel Holtmann flags, info->data, eir_len, NULL, 0); 3605a9de9248SMarcel Holtmann } 3606a9de9248SMarcel Holtmann 3607a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3608a9de9248SMarcel Holtmann } 3609a9de9248SMarcel Holtmann 36101c2e0041SJohan Hedberg static void hci_key_refresh_complete_evt(struct hci_dev *hdev, 36111c2e0041SJohan Hedberg struct sk_buff *skb) 36121c2e0041SJohan Hedberg { 36131c2e0041SJohan Hedberg struct hci_ev_key_refresh_complete *ev = (void *) skb->data; 36141c2e0041SJohan Hedberg struct hci_conn *conn; 36151c2e0041SJohan Hedberg 36169f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status, 36171c2e0041SJohan Hedberg __le16_to_cpu(ev->handle)); 36181c2e0041SJohan Hedberg 36191c2e0041SJohan Hedberg hci_dev_lock(hdev); 36201c2e0041SJohan Hedberg 36211c2e0041SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 36221c2e0041SJohan Hedberg if (!conn) 36231c2e0041SJohan Hedberg goto unlock; 36241c2e0041SJohan Hedberg 36259eb1fbfaSJohan Hedberg /* For BR/EDR the necessary steps are taken through the 36269eb1fbfaSJohan Hedberg * auth_complete event. 36279eb1fbfaSJohan Hedberg */ 36289eb1fbfaSJohan Hedberg if (conn->type != LE_LINK) 36299eb1fbfaSJohan Hedberg goto unlock; 36309eb1fbfaSJohan Hedberg 36311c2e0041SJohan Hedberg if (!ev->status) 36321c2e0041SJohan Hedberg conn->sec_level = conn->pending_sec_level; 36331c2e0041SJohan Hedberg 36341c2e0041SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 36351c2e0041SJohan Hedberg 36361c2e0041SJohan Hedberg if (ev->status && conn->state == BT_CONNECTED) { 3637bed71748SAndre Guedes hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 363876a68ba0SDavid Herrmann hci_conn_drop(conn); 36391c2e0041SJohan Hedberg goto unlock; 36401c2e0041SJohan Hedberg } 36411c2e0041SJohan Hedberg 36421c2e0041SJohan Hedberg if (conn->state == BT_CONFIG) { 36431c2e0041SJohan Hedberg if (!ev->status) 36441c2e0041SJohan Hedberg conn->state = BT_CONNECTED; 36451c2e0041SJohan Hedberg 36461c2e0041SJohan Hedberg hci_proto_connect_cfm(conn, ev->status); 364776a68ba0SDavid Herrmann hci_conn_drop(conn); 36481c2e0041SJohan Hedberg } else { 36491c2e0041SJohan Hedberg hci_auth_cfm(conn, ev->status); 36501c2e0041SJohan Hedberg 36511c2e0041SJohan Hedberg hci_conn_hold(conn); 36521c2e0041SJohan Hedberg conn->disc_timeout = HCI_DISCONN_TIMEOUT; 365376a68ba0SDavid Herrmann hci_conn_drop(conn); 36541c2e0041SJohan Hedberg } 36551c2e0041SJohan Hedberg 36561c2e0041SJohan Hedberg unlock: 36571c2e0041SJohan Hedberg hci_dev_unlock(hdev); 36581c2e0041SJohan Hedberg } 36591c2e0041SJohan Hedberg 36606039aa73SGustavo Padovan static u8 hci_get_auth_req(struct hci_conn *conn) 366117fa4b9dSJohan Hedberg { 366217fa4b9dSJohan Hedberg /* If remote requests no-bonding follow that lead */ 3663acabae96SMikel Astiz if (conn->remote_auth == HCI_AT_NO_BONDING || 3664acabae96SMikel Astiz conn->remote_auth == HCI_AT_NO_BONDING_MITM) 366558797bf7SWaldemar Rymarkiewicz return conn->remote_auth | (conn->auth_type & 0x01); 366617fa4b9dSJohan Hedberg 3667b7f94c88SMikel Astiz /* If both remote and local have enough IO capabilities, require 3668b7f94c88SMikel Astiz * MITM protection 3669b7f94c88SMikel Astiz */ 3670b7f94c88SMikel Astiz if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT && 3671b7f94c88SMikel Astiz conn->io_capability != HCI_IO_NO_INPUT_OUTPUT) 3672b7f94c88SMikel Astiz return conn->remote_auth | 0x01; 3673b7f94c88SMikel Astiz 36747e74170aSTimo Mueller /* No MITM protection possible so ignore remote requirement */ 36757e74170aSTimo Mueller return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01); 367617fa4b9dSJohan Hedberg } 367717fa4b9dSJohan Hedberg 36786039aa73SGustavo Padovan static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 36790493684eSMarcel Holtmann { 36800493684eSMarcel Holtmann struct hci_ev_io_capa_request *ev = (void *) skb->data; 36810493684eSMarcel Holtmann struct hci_conn *conn; 36820493684eSMarcel Holtmann 36830493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 36840493684eSMarcel Holtmann 36850493684eSMarcel Holtmann hci_dev_lock(hdev); 36860493684eSMarcel Holtmann 36870493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 368803b555e1SJohan Hedberg if (!conn) 368903b555e1SJohan Hedberg goto unlock; 369003b555e1SJohan Hedberg 36910493684eSMarcel Holtmann hci_conn_hold(conn); 36920493684eSMarcel Holtmann 3693a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 369403b555e1SJohan Hedberg goto unlock; 369503b555e1SJohan Hedberg 36962f407f0aSJohan Hedberg /* Allow pairing if we're pairable, the initiators of the 36972f407f0aSJohan Hedberg * pairing or if the remote is not requesting bonding. 36982f407f0aSJohan Hedberg */ 3699b6ae8457SJohan Hedberg if (test_bit(HCI_BONDABLE, &hdev->dev_flags) || 37002f407f0aSJohan Hedberg test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags) || 370103b555e1SJohan Hedberg (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { 370217fa4b9dSJohan Hedberg struct hci_cp_io_capability_reply cp; 370317fa4b9dSJohan Hedberg 370417fa4b9dSJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 37057a7f1e7cSHemant Gupta /* Change the IO capability from KeyboardDisplay 37067a7f1e7cSHemant Gupta * to DisplayYesNo as it is not supported by BT spec. */ 37077a7f1e7cSHemant Gupta cp.capability = (conn->io_capability == 0x04) ? 3708a767631aSMikel Astiz HCI_IO_DISPLAY_YESNO : conn->io_capability; 3709b7f94c88SMikel Astiz 3710b7f94c88SMikel Astiz /* If we are initiators, there is no remote information yet */ 3711b7f94c88SMikel Astiz if (conn->remote_auth == 0xff) { 3712b16c6604SMikel Astiz /* Request MITM protection if our IO caps allow it 37134ad51a75SJohan Hedberg * except for the no-bonding case. 3714b16c6604SMikel Astiz */ 37156fd6b915SMikel Astiz if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT && 37169f743d74SJohan Hedberg conn->auth_type != HCI_AT_NO_BONDING) 37176c53823aSJohan Hedberg conn->auth_type |= 0x01; 3718b7f94c88SMikel Astiz } else { 37197cbc9bd9SJohan Hedberg conn->auth_type = hci_get_auth_req(conn); 3720b7f94c88SMikel Astiz } 372117fa4b9dSJohan Hedberg 372282c295b1SJohan Hedberg /* If we're not bondable, force one of the non-bondable 372382c295b1SJohan Hedberg * authentication requirement values. 372482c295b1SJohan Hedberg */ 372582c295b1SJohan Hedberg if (!test_bit(HCI_BONDABLE, &hdev->dev_flags)) 372682c295b1SJohan Hedberg conn->auth_type &= HCI_AT_NO_BONDING_MITM; 372782c295b1SJohan Hedberg 372882c295b1SJohan Hedberg cp.authentication = conn->auth_type; 372982c295b1SJohan Hedberg 37308fc9ced3SGustavo Padovan if (hci_find_remote_oob_data(hdev, &conn->dst) && 37318fc9ced3SGustavo Padovan (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags))) 3732ce85ee13SSzymon Janc cp.oob_data = 0x01; 3733ce85ee13SSzymon Janc else 3734ce85ee13SSzymon Janc cp.oob_data = 0x00; 3735ce85ee13SSzymon Janc 373617fa4b9dSJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY, 373717fa4b9dSJohan Hedberg sizeof(cp), &cp); 373803b555e1SJohan Hedberg } else { 373903b555e1SJohan Hedberg struct hci_cp_io_capability_neg_reply cp; 374003b555e1SJohan Hedberg 374103b555e1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 37429f5a0d7bSAndrei Emeltchenko cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED; 374303b555e1SJohan Hedberg 374403b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, 374503b555e1SJohan Hedberg sizeof(cp), &cp); 374603b555e1SJohan Hedberg } 374703b555e1SJohan Hedberg 374803b555e1SJohan Hedberg unlock: 374903b555e1SJohan Hedberg hci_dev_unlock(hdev); 375003b555e1SJohan Hedberg } 375103b555e1SJohan Hedberg 37526039aa73SGustavo Padovan static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) 375303b555e1SJohan Hedberg { 375403b555e1SJohan Hedberg struct hci_ev_io_capa_reply *ev = (void *) skb->data; 375503b555e1SJohan Hedberg struct hci_conn *conn; 375603b555e1SJohan Hedberg 375703b555e1SJohan Hedberg BT_DBG("%s", hdev->name); 375803b555e1SJohan Hedberg 375903b555e1SJohan Hedberg hci_dev_lock(hdev); 376003b555e1SJohan Hedberg 376103b555e1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 376203b555e1SJohan Hedberg if (!conn) 376303b555e1SJohan Hedberg goto unlock; 376403b555e1SJohan Hedberg 376503b555e1SJohan Hedberg conn->remote_cap = ev->capability; 376603b555e1SJohan Hedberg conn->remote_auth = ev->authentication; 376758a681efSJohan Hedberg if (ev->oob_data) 376858a681efSJohan Hedberg set_bit(HCI_CONN_REMOTE_OOB, &conn->flags); 376903b555e1SJohan Hedberg 377003b555e1SJohan Hedberg unlock: 37710493684eSMarcel Holtmann hci_dev_unlock(hdev); 37720493684eSMarcel Holtmann } 37730493684eSMarcel Holtmann 37746039aa73SGustavo Padovan static void hci_user_confirm_request_evt(struct hci_dev *hdev, 3775a5c29683SJohan Hedberg struct sk_buff *skb) 3776a5c29683SJohan Hedberg { 3777a5c29683SJohan Hedberg struct hci_ev_user_confirm_req *ev = (void *) skb->data; 377855bc1a37SJohan Hedberg int loc_mitm, rem_mitm, confirm_hint = 0; 37797a828908SJohan Hedberg struct hci_conn *conn; 3780a5c29683SJohan Hedberg 3781a5c29683SJohan Hedberg BT_DBG("%s", hdev->name); 3782a5c29683SJohan Hedberg 3783a5c29683SJohan Hedberg hci_dev_lock(hdev); 3784a5c29683SJohan Hedberg 3785a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 37867a828908SJohan Hedberg goto unlock; 37877a828908SJohan Hedberg 37887a828908SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 37897a828908SJohan Hedberg if (!conn) 37907a828908SJohan Hedberg goto unlock; 37917a828908SJohan Hedberg 37927a828908SJohan Hedberg loc_mitm = (conn->auth_type & 0x01); 37937a828908SJohan Hedberg rem_mitm = (conn->remote_auth & 0x01); 37947a828908SJohan Hedberg 37957a828908SJohan Hedberg /* If we require MITM but the remote device can't provide that 37966c53823aSJohan Hedberg * (it has NoInputNoOutput) then reject the confirmation 37976c53823aSJohan Hedberg * request. We check the security level here since it doesn't 37986c53823aSJohan Hedberg * necessarily match conn->auth_type. 37996fd6b915SMikel Astiz */ 38006c53823aSJohan Hedberg if (conn->pending_sec_level > BT_SECURITY_MEDIUM && 38016c53823aSJohan Hedberg conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) { 38027a828908SJohan Hedberg BT_DBG("Rejecting request: remote device can't provide MITM"); 38037a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY, 38047a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 38057a828908SJohan Hedberg goto unlock; 38067a828908SJohan Hedberg } 38077a828908SJohan Hedberg 38087a828908SJohan Hedberg /* If no side requires MITM protection; auto-accept */ 3809a767631aSMikel Astiz if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) && 3810a767631aSMikel Astiz (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) { 381155bc1a37SJohan Hedberg 381255bc1a37SJohan Hedberg /* If we're not the initiators request authorization to 381355bc1a37SJohan Hedberg * proceed from user space (mgmt_user_confirm with 3814ba15a58bSJohan Hedberg * confirm_hint set to 1). The exception is if neither 381502f3e254SJohan Hedberg * side had MITM or if the local IO capability is 381602f3e254SJohan Hedberg * NoInputNoOutput, in which case we do auto-accept 3817ba15a58bSJohan Hedberg */ 3818ba15a58bSJohan Hedberg if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && 381902f3e254SJohan Hedberg conn->io_capability != HCI_IO_NO_INPUT_OUTPUT && 3820ba15a58bSJohan Hedberg (loc_mitm || rem_mitm)) { 382155bc1a37SJohan Hedberg BT_DBG("Confirming auto-accept as acceptor"); 382255bc1a37SJohan Hedberg confirm_hint = 1; 382355bc1a37SJohan Hedberg goto confirm; 382455bc1a37SJohan Hedberg } 382555bc1a37SJohan Hedberg 38269f61656aSJohan Hedberg BT_DBG("Auto-accept of user confirmation with %ums delay", 38279f61656aSJohan Hedberg hdev->auto_accept_delay); 38289f61656aSJohan Hedberg 38299f61656aSJohan Hedberg if (hdev->auto_accept_delay > 0) { 38309f61656aSJohan Hedberg int delay = msecs_to_jiffies(hdev->auto_accept_delay); 38317bc18d9dSJohan Hedberg queue_delayed_work(conn->hdev->workqueue, 38327bc18d9dSJohan Hedberg &conn->auto_accept_work, delay); 38339f61656aSJohan Hedberg goto unlock; 38349f61656aSJohan Hedberg } 38359f61656aSJohan Hedberg 38367a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, 38377a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 38387a828908SJohan Hedberg goto unlock; 38397a828908SJohan Hedberg } 38407a828908SJohan Hedberg 384155bc1a37SJohan Hedberg confirm: 384239adbffeSJohan Hedberg mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, 384339adbffeSJohan Hedberg le32_to_cpu(ev->passkey), confirm_hint); 3844a5c29683SJohan Hedberg 38457a828908SJohan Hedberg unlock: 3846a5c29683SJohan Hedberg hci_dev_unlock(hdev); 3847a5c29683SJohan Hedberg } 3848a5c29683SJohan Hedberg 38496039aa73SGustavo Padovan static void hci_user_passkey_request_evt(struct hci_dev *hdev, 38501143d458SBrian Gix struct sk_buff *skb) 38511143d458SBrian Gix { 38521143d458SBrian Gix struct hci_ev_user_passkey_req *ev = (void *) skb->data; 38531143d458SBrian Gix 38541143d458SBrian Gix BT_DBG("%s", hdev->name); 38551143d458SBrian Gix 3856a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 3857272d90dfSJohan Hedberg mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); 38581143d458SBrian Gix } 38591143d458SBrian Gix 386092a25256SJohan Hedberg static void hci_user_passkey_notify_evt(struct hci_dev *hdev, 386192a25256SJohan Hedberg struct sk_buff *skb) 386292a25256SJohan Hedberg { 386392a25256SJohan Hedberg struct hci_ev_user_passkey_notify *ev = (void *) skb->data; 386492a25256SJohan Hedberg struct hci_conn *conn; 386592a25256SJohan Hedberg 386692a25256SJohan Hedberg BT_DBG("%s", hdev->name); 386792a25256SJohan Hedberg 386892a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 386992a25256SJohan Hedberg if (!conn) 387092a25256SJohan Hedberg return; 387192a25256SJohan Hedberg 387292a25256SJohan Hedberg conn->passkey_notify = __le32_to_cpu(ev->passkey); 387392a25256SJohan Hedberg conn->passkey_entered = 0; 387492a25256SJohan Hedberg 387592a25256SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 387692a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 387792a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 387892a25256SJohan Hedberg conn->passkey_entered); 387992a25256SJohan Hedberg } 388092a25256SJohan Hedberg 388192a25256SJohan Hedberg static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 388292a25256SJohan Hedberg { 388392a25256SJohan Hedberg struct hci_ev_keypress_notify *ev = (void *) skb->data; 388492a25256SJohan Hedberg struct hci_conn *conn; 388592a25256SJohan Hedberg 388692a25256SJohan Hedberg BT_DBG("%s", hdev->name); 388792a25256SJohan Hedberg 388892a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 388992a25256SJohan Hedberg if (!conn) 389092a25256SJohan Hedberg return; 389192a25256SJohan Hedberg 389292a25256SJohan Hedberg switch (ev->type) { 389392a25256SJohan Hedberg case HCI_KEYPRESS_STARTED: 389492a25256SJohan Hedberg conn->passkey_entered = 0; 389592a25256SJohan Hedberg return; 389692a25256SJohan Hedberg 389792a25256SJohan Hedberg case HCI_KEYPRESS_ENTERED: 389892a25256SJohan Hedberg conn->passkey_entered++; 389992a25256SJohan Hedberg break; 390092a25256SJohan Hedberg 390192a25256SJohan Hedberg case HCI_KEYPRESS_ERASED: 390292a25256SJohan Hedberg conn->passkey_entered--; 390392a25256SJohan Hedberg break; 390492a25256SJohan Hedberg 390592a25256SJohan Hedberg case HCI_KEYPRESS_CLEARED: 390692a25256SJohan Hedberg conn->passkey_entered = 0; 390792a25256SJohan Hedberg break; 390892a25256SJohan Hedberg 390992a25256SJohan Hedberg case HCI_KEYPRESS_COMPLETED: 391092a25256SJohan Hedberg return; 391192a25256SJohan Hedberg } 391292a25256SJohan Hedberg 391392a25256SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 391492a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 391592a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 391692a25256SJohan Hedberg conn->passkey_entered); 391792a25256SJohan Hedberg } 391892a25256SJohan Hedberg 39196039aa73SGustavo Padovan static void hci_simple_pair_complete_evt(struct hci_dev *hdev, 3920807deac2SGustavo Padovan struct sk_buff *skb) 39210493684eSMarcel Holtmann { 39220493684eSMarcel Holtmann struct hci_ev_simple_pair_complete *ev = (void *) skb->data; 39230493684eSMarcel Holtmann struct hci_conn *conn; 39240493684eSMarcel Holtmann 39250493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 39260493684eSMarcel Holtmann 39270493684eSMarcel Holtmann hci_dev_lock(hdev); 39280493684eSMarcel Holtmann 39290493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 39302a611692SJohan Hedberg if (!conn) 39312a611692SJohan Hedberg goto unlock; 39322a611692SJohan Hedberg 3933c1d4fa7aSJohan Hedberg /* Reset the authentication requirement to unknown */ 3934c1d4fa7aSJohan Hedberg conn->remote_auth = 0xff; 3935c1d4fa7aSJohan Hedberg 39362a611692SJohan Hedberg /* To avoid duplicate auth_failed events to user space we check 39372a611692SJohan Hedberg * the HCI_CONN_AUTH_PEND flag which will be set if we 39382a611692SJohan Hedberg * initiated the authentication. A traditional auth_complete 39392a611692SJohan Hedberg * event gets always produced as initiator and is also mapped to 39402a611692SJohan Hedberg * the mgmt_auth_failed event */ 3941fa1bd918SMikel Astiz if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status) 3942e1e930f5SJohan Hedberg mgmt_auth_failed(conn, ev->status); 39432a611692SJohan Hedberg 394476a68ba0SDavid Herrmann hci_conn_drop(conn); 39450493684eSMarcel Holtmann 39462a611692SJohan Hedberg unlock: 39470493684eSMarcel Holtmann hci_dev_unlock(hdev); 39480493684eSMarcel Holtmann } 39490493684eSMarcel Holtmann 39506039aa73SGustavo Padovan static void hci_remote_host_features_evt(struct hci_dev *hdev, 3951807deac2SGustavo Padovan struct sk_buff *skb) 395241a96212SMarcel Holtmann { 395341a96212SMarcel Holtmann struct hci_ev_remote_host_features *ev = (void *) skb->data; 395441a96212SMarcel Holtmann struct inquiry_entry *ie; 3955cad718edSJohan Hedberg struct hci_conn *conn; 395641a96212SMarcel Holtmann 395741a96212SMarcel Holtmann BT_DBG("%s", hdev->name); 395841a96212SMarcel Holtmann 395941a96212SMarcel Holtmann hci_dev_lock(hdev); 396041a96212SMarcel Holtmann 3961cad718edSJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 3962cad718edSJohan Hedberg if (conn) 3963cad718edSJohan Hedberg memcpy(conn->features[1], ev->features, 8); 3964cad718edSJohan Hedberg 3965cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 3966cc11b9c1SAndrei Emeltchenko if (ie) 396702b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 396841a96212SMarcel Holtmann 396941a96212SMarcel Holtmann hci_dev_unlock(hdev); 397041a96212SMarcel Holtmann } 397141a96212SMarcel Holtmann 39726039aa73SGustavo Padovan static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, 39732763eda6SSzymon Janc struct sk_buff *skb) 39742763eda6SSzymon Janc { 39752763eda6SSzymon Janc struct hci_ev_remote_oob_data_request *ev = (void *) skb->data; 39762763eda6SSzymon Janc struct oob_data *data; 39772763eda6SSzymon Janc 39782763eda6SSzymon Janc BT_DBG("%s", hdev->name); 39792763eda6SSzymon Janc 39802763eda6SSzymon Janc hci_dev_lock(hdev); 39812763eda6SSzymon Janc 3982a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 3983e1ba1f15SSzymon Janc goto unlock; 3984e1ba1f15SSzymon Janc 39852763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, &ev->bdaddr); 39862763eda6SSzymon Janc if (data) { 3987519ca9d0SMarcel Holtmann if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) { 3988519ca9d0SMarcel Holtmann struct hci_cp_remote_oob_ext_data_reply cp; 3989519ca9d0SMarcel Holtmann 3990519ca9d0SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 3991519ca9d0SMarcel Holtmann memcpy(cp.hash192, data->hash192, sizeof(cp.hash192)); 3992519ca9d0SMarcel Holtmann memcpy(cp.randomizer192, data->randomizer192, 3993519ca9d0SMarcel Holtmann sizeof(cp.randomizer192)); 3994519ca9d0SMarcel Holtmann memcpy(cp.hash256, data->hash256, sizeof(cp.hash256)); 3995519ca9d0SMarcel Holtmann memcpy(cp.randomizer256, data->randomizer256, 3996519ca9d0SMarcel Holtmann sizeof(cp.randomizer256)); 3997519ca9d0SMarcel Holtmann 3998519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY, 3999519ca9d0SMarcel Holtmann sizeof(cp), &cp); 4000519ca9d0SMarcel Holtmann } else { 40012763eda6SSzymon Janc struct hci_cp_remote_oob_data_reply cp; 40022763eda6SSzymon Janc 40032763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr); 4004519ca9d0SMarcel Holtmann memcpy(cp.hash, data->hash192, sizeof(cp.hash)); 4005519ca9d0SMarcel Holtmann memcpy(cp.randomizer, data->randomizer192, 4006519ca9d0SMarcel Holtmann sizeof(cp.randomizer)); 40072763eda6SSzymon Janc 4008519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, 4009519ca9d0SMarcel Holtmann sizeof(cp), &cp); 4010519ca9d0SMarcel Holtmann } 40112763eda6SSzymon Janc } else { 40122763eda6SSzymon Janc struct hci_cp_remote_oob_data_neg_reply cp; 40132763eda6SSzymon Janc 40142763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr); 4015519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, 4016519ca9d0SMarcel Holtmann sizeof(cp), &cp); 40172763eda6SSzymon Janc } 40182763eda6SSzymon Janc 4019e1ba1f15SSzymon Janc unlock: 40202763eda6SSzymon Janc hci_dev_unlock(hdev); 40212763eda6SSzymon Janc } 40222763eda6SSzymon Janc 4023d5e91192SAndrei Emeltchenko static void hci_phy_link_complete_evt(struct hci_dev *hdev, 4024d5e91192SAndrei Emeltchenko struct sk_buff *skb) 4025d5e91192SAndrei Emeltchenko { 4026d5e91192SAndrei Emeltchenko struct hci_ev_phy_link_complete *ev = (void *) skb->data; 4027d5e91192SAndrei Emeltchenko struct hci_conn *hcon, *bredr_hcon; 4028d5e91192SAndrei Emeltchenko 4029d5e91192SAndrei Emeltchenko BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle, 4030d5e91192SAndrei Emeltchenko ev->status); 4031d5e91192SAndrei Emeltchenko 4032d5e91192SAndrei Emeltchenko hci_dev_lock(hdev); 4033d5e91192SAndrei Emeltchenko 4034d5e91192SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 4035d5e91192SAndrei Emeltchenko if (!hcon) { 4036d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 4037d5e91192SAndrei Emeltchenko return; 4038d5e91192SAndrei Emeltchenko } 4039d5e91192SAndrei Emeltchenko 4040d5e91192SAndrei Emeltchenko if (ev->status) { 4041d5e91192SAndrei Emeltchenko hci_conn_del(hcon); 4042d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 4043d5e91192SAndrei Emeltchenko return; 4044d5e91192SAndrei Emeltchenko } 4045d5e91192SAndrei Emeltchenko 4046d5e91192SAndrei Emeltchenko bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon; 4047d5e91192SAndrei Emeltchenko 4048d5e91192SAndrei Emeltchenko hcon->state = BT_CONNECTED; 4049d5e91192SAndrei Emeltchenko bacpy(&hcon->dst, &bredr_hcon->dst); 4050d5e91192SAndrei Emeltchenko 4051d5e91192SAndrei Emeltchenko hci_conn_hold(hcon); 4052d5e91192SAndrei Emeltchenko hcon->disc_timeout = HCI_DISCONN_TIMEOUT; 405376a68ba0SDavid Herrmann hci_conn_drop(hcon); 4054d5e91192SAndrei Emeltchenko 4055d5e91192SAndrei Emeltchenko hci_conn_add_sysfs(hcon); 4056d5e91192SAndrei Emeltchenko 4057cf70ff22SAndrei Emeltchenko amp_physical_cfm(bredr_hcon, hcon); 4058cf70ff22SAndrei Emeltchenko 4059d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 4060d5e91192SAndrei Emeltchenko } 4061d5e91192SAndrei Emeltchenko 406227695fb4SAndrei Emeltchenko static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 406327695fb4SAndrei Emeltchenko { 406427695fb4SAndrei Emeltchenko struct hci_ev_logical_link_complete *ev = (void *) skb->data; 406527695fb4SAndrei Emeltchenko struct hci_conn *hcon; 406627695fb4SAndrei Emeltchenko struct hci_chan *hchan; 406727695fb4SAndrei Emeltchenko struct amp_mgr *mgr; 406827695fb4SAndrei Emeltchenko 406927695fb4SAndrei Emeltchenko BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x", 407027695fb4SAndrei Emeltchenko hdev->name, le16_to_cpu(ev->handle), ev->phy_handle, 407127695fb4SAndrei Emeltchenko ev->status); 407227695fb4SAndrei Emeltchenko 407327695fb4SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 407427695fb4SAndrei Emeltchenko if (!hcon) 407527695fb4SAndrei Emeltchenko return; 407627695fb4SAndrei Emeltchenko 407727695fb4SAndrei Emeltchenko /* Create AMP hchan */ 407827695fb4SAndrei Emeltchenko hchan = hci_chan_create(hcon); 407927695fb4SAndrei Emeltchenko if (!hchan) 408027695fb4SAndrei Emeltchenko return; 408127695fb4SAndrei Emeltchenko 408227695fb4SAndrei Emeltchenko hchan->handle = le16_to_cpu(ev->handle); 408327695fb4SAndrei Emeltchenko 408427695fb4SAndrei Emeltchenko BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan); 408527695fb4SAndrei Emeltchenko 408627695fb4SAndrei Emeltchenko mgr = hcon->amp_mgr; 408727695fb4SAndrei Emeltchenko if (mgr && mgr->bredr_chan) { 408827695fb4SAndrei Emeltchenko struct l2cap_chan *bredr_chan = mgr->bredr_chan; 408927695fb4SAndrei Emeltchenko 409027695fb4SAndrei Emeltchenko l2cap_chan_lock(bredr_chan); 409127695fb4SAndrei Emeltchenko 409227695fb4SAndrei Emeltchenko bredr_chan->conn->mtu = hdev->block_mtu; 409327695fb4SAndrei Emeltchenko l2cap_logical_cfm(bredr_chan, hchan, 0); 409427695fb4SAndrei Emeltchenko hci_conn_hold(hcon); 409527695fb4SAndrei Emeltchenko 409627695fb4SAndrei Emeltchenko l2cap_chan_unlock(bredr_chan); 409727695fb4SAndrei Emeltchenko } 409827695fb4SAndrei Emeltchenko } 409927695fb4SAndrei Emeltchenko 4100606e2a10SAndrei Emeltchenko static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev, 4101606e2a10SAndrei Emeltchenko struct sk_buff *skb) 4102606e2a10SAndrei Emeltchenko { 4103606e2a10SAndrei Emeltchenko struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data; 4104606e2a10SAndrei Emeltchenko struct hci_chan *hchan; 4105606e2a10SAndrei Emeltchenko 4106606e2a10SAndrei Emeltchenko BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name, 4107606e2a10SAndrei Emeltchenko le16_to_cpu(ev->handle), ev->status); 4108606e2a10SAndrei Emeltchenko 4109606e2a10SAndrei Emeltchenko if (ev->status) 4110606e2a10SAndrei Emeltchenko return; 4111606e2a10SAndrei Emeltchenko 4112606e2a10SAndrei Emeltchenko hci_dev_lock(hdev); 4113606e2a10SAndrei Emeltchenko 4114606e2a10SAndrei Emeltchenko hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle)); 4115606e2a10SAndrei Emeltchenko if (!hchan) 4116606e2a10SAndrei Emeltchenko goto unlock; 4117606e2a10SAndrei Emeltchenko 4118606e2a10SAndrei Emeltchenko amp_destroy_logical_link(hchan, ev->reason); 4119606e2a10SAndrei Emeltchenko 4120606e2a10SAndrei Emeltchenko unlock: 4121606e2a10SAndrei Emeltchenko hci_dev_unlock(hdev); 4122606e2a10SAndrei Emeltchenko } 4123606e2a10SAndrei Emeltchenko 41249eef6b3aSAndrei Emeltchenko static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, 41259eef6b3aSAndrei Emeltchenko struct sk_buff *skb) 41269eef6b3aSAndrei Emeltchenko { 41279eef6b3aSAndrei Emeltchenko struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data; 41289eef6b3aSAndrei Emeltchenko struct hci_conn *hcon; 41299eef6b3aSAndrei Emeltchenko 41309eef6b3aSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 41319eef6b3aSAndrei Emeltchenko 41329eef6b3aSAndrei Emeltchenko if (ev->status) 41339eef6b3aSAndrei Emeltchenko return; 41349eef6b3aSAndrei Emeltchenko 41359eef6b3aSAndrei Emeltchenko hci_dev_lock(hdev); 41369eef6b3aSAndrei Emeltchenko 41379eef6b3aSAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 41389eef6b3aSAndrei Emeltchenko if (hcon) { 41399eef6b3aSAndrei Emeltchenko hcon->state = BT_CLOSED; 41409eef6b3aSAndrei Emeltchenko hci_conn_del(hcon); 41419eef6b3aSAndrei Emeltchenko } 41429eef6b3aSAndrei Emeltchenko 41439eef6b3aSAndrei Emeltchenko hci_dev_unlock(hdev); 41449eef6b3aSAndrei Emeltchenko } 41459eef6b3aSAndrei Emeltchenko 41466039aa73SGustavo Padovan static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 4147fcd89c09SVille Tervo { 4148fcd89c09SVille Tervo struct hci_ev_le_conn_complete *ev = (void *) skb->data; 4149912b42efSJohan Hedberg struct hci_conn_params *params; 4150fcd89c09SVille Tervo struct hci_conn *conn; 415168d6f6deSJohan Hedberg struct smp_irk *irk; 4152837d502eSJohan Hedberg u8 addr_type; 4153fcd89c09SVille Tervo 41549f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 4155fcd89c09SVille Tervo 4156fcd89c09SVille Tervo hci_dev_lock(hdev); 4157fcd89c09SVille Tervo 4158fbd96c15SJohan Hedberg /* All controllers implicitly stop advertising in the event of a 4159fbd96c15SJohan Hedberg * connection, so ensure that the state bit is cleared. 4160fbd96c15SJohan Hedberg */ 4161fbd96c15SJohan Hedberg clear_bit(HCI_LE_ADV, &hdev->dev_flags); 4162fbd96c15SJohan Hedberg 41634f72b329SAndrzej Kaczmarek conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); 4164b62f328bSVille Tervo if (!conn) { 4165a5c4e309SJohan Hedberg conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr, ev->role); 4166b62f328bSVille Tervo if (!conn) { 4167b62f328bSVille Tervo BT_ERR("No memory for new connection"); 4168230fd16aSAndre Guedes goto unlock; 4169b62f328bSVille Tervo } 417029b7988aSAndre Guedes 417129b7988aSAndre Guedes conn->dst_type = ev->bdaddr_type; 4172b9b343d2SAndre Guedes 4173cb1d68f7SJohan Hedberg /* If we didn't have a hci_conn object previously 4174cb1d68f7SJohan Hedberg * but we're in master role this must be something 4175cb1d68f7SJohan Hedberg * initiated using a white list. Since white list based 4176cb1d68f7SJohan Hedberg * connections are not "first class citizens" we don't 4177cb1d68f7SJohan Hedberg * have full tracking of them. Therefore, we go ahead 4178cb1d68f7SJohan Hedberg * with a "best effort" approach of determining the 4179cb1d68f7SJohan Hedberg * initiator address based on the HCI_PRIVACY flag. 4180cb1d68f7SJohan Hedberg */ 4181cb1d68f7SJohan Hedberg if (conn->out) { 4182cb1d68f7SJohan Hedberg conn->resp_addr_type = ev->bdaddr_type; 4183cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &ev->bdaddr); 4184cb1d68f7SJohan Hedberg if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) { 4185cb1d68f7SJohan Hedberg conn->init_addr_type = ADDR_LE_DEV_RANDOM; 4186cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->rpa); 4187cb1d68f7SJohan Hedberg } else { 4188cb1d68f7SJohan Hedberg hci_copy_identity_address(hdev, 4189cb1d68f7SJohan Hedberg &conn->init_addr, 4190cb1d68f7SJohan Hedberg &conn->init_addr_type); 4191cb1d68f7SJohan Hedberg } 419280c24ab8SJohan Hedberg } 4193cb1d68f7SJohan Hedberg } else { 419480c24ab8SJohan Hedberg cancel_delayed_work(&conn->le_conn_timeout); 419580c24ab8SJohan Hedberg } 419680c24ab8SJohan Hedberg 419780c24ab8SJohan Hedberg if (!conn->out) { 4198cb1d68f7SJohan Hedberg /* Set the responder (our side) address type based on 4199cb1d68f7SJohan Hedberg * the advertising address type. 4200cb1d68f7SJohan Hedberg */ 4201cb1d68f7SJohan Hedberg conn->resp_addr_type = hdev->adv_addr_type; 4202cb1d68f7SJohan Hedberg if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) 4203cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &hdev->random_addr); 4204cb1d68f7SJohan Hedberg else 4205cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &hdev->bdaddr); 4206cb1d68f7SJohan Hedberg 4207cb1d68f7SJohan Hedberg conn->init_addr_type = ev->bdaddr_type; 4208cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &ev->bdaddr); 4209a720d735SMarcel Holtmann 4210a720d735SMarcel Holtmann /* For incoming connections, set the default minimum 4211a720d735SMarcel Holtmann * and maximum connection interval. They will be used 4212a720d735SMarcel Holtmann * to check if the parameters are in range and if not 4213a720d735SMarcel Holtmann * trigger the connection update procedure. 4214a720d735SMarcel Holtmann */ 4215a720d735SMarcel Holtmann conn->le_conn_min_interval = hdev->le_conn_min_interval; 4216a720d735SMarcel Holtmann conn->le_conn_max_interval = hdev->le_conn_max_interval; 4217cb1d68f7SJohan Hedberg } 42187be2edbbSJohan Hedberg 4219edb4b466SMarcel Holtmann /* Lookup the identity address from the stored connection 4220edb4b466SMarcel Holtmann * address and address type. 4221edb4b466SMarcel Holtmann * 4222edb4b466SMarcel Holtmann * When establishing connections to an identity address, the 4223edb4b466SMarcel Holtmann * connection procedure will store the resolvable random 4224edb4b466SMarcel Holtmann * address first. Now if it can be converted back into the 4225edb4b466SMarcel Holtmann * identity address, start using the identity address from 4226edb4b466SMarcel Holtmann * now on. 4227edb4b466SMarcel Holtmann */ 4228edb4b466SMarcel Holtmann irk = hci_get_irk(hdev, &conn->dst, conn->dst_type); 422968d6f6deSJohan Hedberg if (irk) { 423068d6f6deSJohan Hedberg bacpy(&conn->dst, &irk->bdaddr); 423168d6f6deSJohan Hedberg conn->dst_type = irk->addr_type; 423268d6f6deSJohan Hedberg } 423368d6f6deSJohan Hedberg 42342d3c2260SJohan Hedberg if (ev->status) { 42352d3c2260SJohan Hedberg hci_le_conn_failed(conn, ev->status); 4236837d502eSJohan Hedberg goto unlock; 4237837d502eSJohan Hedberg } 4238837d502eSJohan Hedberg 423908853f18SJohan Hedberg if (conn->dst_type == ADDR_LE_DEV_PUBLIC) 424008853f18SJohan Hedberg addr_type = BDADDR_LE_PUBLIC; 424108853f18SJohan Hedberg else 424208853f18SJohan Hedberg addr_type = BDADDR_LE_RANDOM; 424308853f18SJohan Hedberg 42442d3c2260SJohan Hedberg /* Drop the connection if the device is blocked */ 42452d3c2260SJohan Hedberg if (hci_bdaddr_list_lookup(&hdev->blacklist, &conn->dst, addr_type)) { 42462d3c2260SJohan Hedberg hci_conn_drop(conn); 4247cd17decbSAndre Guedes goto unlock; 4248cd17decbSAndre Guedes } 4249cd17decbSAndre Guedes 4250b644ba33SJohan Hedberg if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 425148ec92faSAlfonso Acosta mgmt_device_connected(hdev, conn, 0, NULL, 0); 425283bc71b4SVinicius Costa Gomes 42537b5c0d52SVinicius Costa Gomes conn->sec_level = BT_SECURITY_LOW; 4254fcd89c09SVille Tervo conn->handle = __le16_to_cpu(ev->handle); 4255fcd89c09SVille Tervo conn->state = BT_CONNECTED; 4256fcd89c09SVille Tervo 4257e04fde60SMarcel Holtmann conn->le_conn_interval = le16_to_cpu(ev->interval); 4258e04fde60SMarcel Holtmann conn->le_conn_latency = le16_to_cpu(ev->latency); 4259e04fde60SMarcel Holtmann conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout); 4260e04fde60SMarcel Holtmann 4261fcd89c09SVille Tervo hci_conn_add_sysfs(conn); 4262fcd89c09SVille Tervo 4263fcd89c09SVille Tervo hci_proto_connect_cfm(conn, ev->status); 4264fcd89c09SVille Tervo 42655477610fSJohan Hedberg params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst, 42665477610fSJohan Hedberg conn->dst_type); 4267f161dd41SJohan Hedberg if (params) { 426895305baaSJohan Hedberg list_del_init(¶ms->action); 4269f161dd41SJohan Hedberg if (params->conn) { 4270f161dd41SJohan Hedberg hci_conn_drop(params->conn); 4271f8aaf9b6SJohan Hedberg hci_conn_put(params->conn); 4272f161dd41SJohan Hedberg params->conn = NULL; 4273f161dd41SJohan Hedberg } 4274f161dd41SJohan Hedberg } 4275a4790dbdSAndre Guedes 4276fcd89c09SVille Tervo unlock: 4277223683a5SJohan Hedberg hci_update_background_scan(hdev); 4278fcd89c09SVille Tervo hci_dev_unlock(hdev); 4279fcd89c09SVille Tervo } 4280fcd89c09SVille Tervo 42811855d92dSMarcel Holtmann static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, 42821855d92dSMarcel Holtmann struct sk_buff *skb) 42831855d92dSMarcel Holtmann { 42841855d92dSMarcel Holtmann struct hci_ev_le_conn_update_complete *ev = (void *) skb->data; 42851855d92dSMarcel Holtmann struct hci_conn *conn; 42861855d92dSMarcel Holtmann 42871855d92dSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 42881855d92dSMarcel Holtmann 42891855d92dSMarcel Holtmann if (ev->status) 42901855d92dSMarcel Holtmann return; 42911855d92dSMarcel Holtmann 42921855d92dSMarcel Holtmann hci_dev_lock(hdev); 42931855d92dSMarcel Holtmann 42941855d92dSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 42951855d92dSMarcel Holtmann if (conn) { 42961855d92dSMarcel Holtmann conn->le_conn_interval = le16_to_cpu(ev->interval); 42971855d92dSMarcel Holtmann conn->le_conn_latency = le16_to_cpu(ev->latency); 42981855d92dSMarcel Holtmann conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout); 42991855d92dSMarcel Holtmann } 43001855d92dSMarcel Holtmann 43011855d92dSMarcel Holtmann hci_dev_unlock(hdev); 43021855d92dSMarcel Holtmann } 43031855d92dSMarcel Holtmann 4304a4790dbdSAndre Guedes /* This function requires the caller holds hdev->lock */ 4305fd45ada9SAlfonso Acosta static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev, 4306fd45ada9SAlfonso Acosta bdaddr_t *addr, 43071c1abcabSJohan Hedberg u8 addr_type, u8 adv_type) 4308a4790dbdSAndre Guedes { 4309a4790dbdSAndre Guedes struct hci_conn *conn; 43104b9e7e75SMarcel Holtmann struct hci_conn_params *params; 4311a4790dbdSAndre Guedes 43121c1abcabSJohan Hedberg /* If the event is not connectable don't proceed further */ 43131c1abcabSJohan Hedberg if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND) 4314fd45ada9SAlfonso Acosta return NULL; 43151c1abcabSJohan Hedberg 43161c1abcabSJohan Hedberg /* Ignore if the device is blocked */ 4317dcc36c16SJohan Hedberg if (hci_bdaddr_list_lookup(&hdev->blacklist, addr, addr_type)) 4318fd45ada9SAlfonso Acosta return NULL; 43191c1abcabSJohan Hedberg 4320f99353cfSJohan Hedberg /* Most controller will fail if we try to create new connections 4321f99353cfSJohan Hedberg * while we have an existing one in slave role. 4322f99353cfSJohan Hedberg */ 4323f99353cfSJohan Hedberg if (hdev->conn_hash.le_num_slave > 0) 4324fd45ada9SAlfonso Acosta return NULL; 4325f99353cfSJohan Hedberg 43261c1abcabSJohan Hedberg /* If we're not connectable only connect devices that we have in 43271c1abcabSJohan Hedberg * our pend_le_conns list. 43281c1abcabSJohan Hedberg */ 43294b9e7e75SMarcel Holtmann params = hci_pend_le_action_lookup(&hdev->pend_le_conns, 43304b9e7e75SMarcel Holtmann addr, addr_type); 43314b9e7e75SMarcel Holtmann if (!params) 4332fd45ada9SAlfonso Acosta return NULL; 4333a4790dbdSAndre Guedes 43344b9e7e75SMarcel Holtmann switch (params->auto_connect) { 43354b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_DIRECT: 43364b9e7e75SMarcel Holtmann /* Only devices advertising with ADV_DIRECT_IND are 43374b9e7e75SMarcel Holtmann * triggering a connection attempt. This is allowing 43384b9e7e75SMarcel Holtmann * incoming connections from slave devices. 43394b9e7e75SMarcel Holtmann */ 43404b9e7e75SMarcel Holtmann if (adv_type != LE_ADV_DIRECT_IND) 4341fd45ada9SAlfonso Acosta return NULL; 43424b9e7e75SMarcel Holtmann break; 43434b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_ALWAYS: 43444b9e7e75SMarcel Holtmann /* Devices advertising with ADV_IND or ADV_DIRECT_IND 43454b9e7e75SMarcel Holtmann * are triggering a connection attempt. This means 43464b9e7e75SMarcel Holtmann * that incoming connectioms from slave device are 43474b9e7e75SMarcel Holtmann * accepted and also outgoing connections to slave 43484b9e7e75SMarcel Holtmann * devices are established when found. 43494b9e7e75SMarcel Holtmann */ 43504b9e7e75SMarcel Holtmann break; 43514b9e7e75SMarcel Holtmann default: 4352fd45ada9SAlfonso Acosta return NULL; 43534b9e7e75SMarcel Holtmann } 43544b9e7e75SMarcel Holtmann 4355a4790dbdSAndre Guedes conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, 4356e804d25dSJohan Hedberg HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER); 4357f161dd41SJohan Hedberg if (!IS_ERR(conn)) { 4358f161dd41SJohan Hedberg /* Store the pointer since we don't really have any 4359f161dd41SJohan Hedberg * other owner of the object besides the params that 4360f161dd41SJohan Hedberg * triggered it. This way we can abort the connection if 4361f161dd41SJohan Hedberg * the parameters get removed and keep the reference 4362f161dd41SJohan Hedberg * count consistent once the connection is established. 4363f161dd41SJohan Hedberg */ 4364f8aaf9b6SJohan Hedberg params->conn = hci_conn_get(conn); 4365fd45ada9SAlfonso Acosta return conn; 4366f161dd41SJohan Hedberg } 4367a4790dbdSAndre Guedes 4368a4790dbdSAndre Guedes switch (PTR_ERR(conn)) { 4369a4790dbdSAndre Guedes case -EBUSY: 4370a4790dbdSAndre Guedes /* If hci_connect() returns -EBUSY it means there is already 4371a4790dbdSAndre Guedes * an LE connection attempt going on. Since controllers don't 4372a4790dbdSAndre Guedes * support more than one connection attempt at the time, we 4373a4790dbdSAndre Guedes * don't consider this an error case. 4374a4790dbdSAndre Guedes */ 4375a4790dbdSAndre Guedes break; 4376a4790dbdSAndre Guedes default: 4377a4790dbdSAndre Guedes BT_DBG("Failed to connect: err %ld", PTR_ERR(conn)); 4378fd45ada9SAlfonso Acosta return NULL; 4379a4790dbdSAndre Guedes } 4380fd45ada9SAlfonso Acosta 4381fd45ada9SAlfonso Acosta return NULL; 4382a4790dbdSAndre Guedes } 4383a4790dbdSAndre Guedes 43844af605d8SJohan Hedberg static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, 43854af605d8SJohan Hedberg u8 bdaddr_type, s8 rssi, u8 *data, u8 len) 43864af605d8SJohan Hedberg { 4387b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 43881c1abcabSJohan Hedberg struct smp_irk *irk; 4389fd45ada9SAlfonso Acosta struct hci_conn *conn; 4390474ee066SJohan Hedberg bool match; 4391c70a7e4cSMarcel Holtmann u32 flags; 4392b9a6328fSJohan Hedberg 4393435a13d8SJohan Hedberg /* Check if we need to convert to identity address */ 4394435a13d8SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, bdaddr_type); 4395435a13d8SJohan Hedberg if (irk) { 4396435a13d8SJohan Hedberg bdaddr = &irk->bdaddr; 4397435a13d8SJohan Hedberg bdaddr_type = irk->addr_type; 4398435a13d8SJohan Hedberg } 4399435a13d8SJohan Hedberg 44001c1abcabSJohan Hedberg /* Check if we have been requested to connect to this device */ 4401fd45ada9SAlfonso Acosta conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, type); 4402fd45ada9SAlfonso Acosta if (conn && type == LE_ADV_IND) { 4403fd45ada9SAlfonso Acosta /* Store report for later inclusion by 4404fd45ada9SAlfonso Acosta * mgmt_device_connected 4405fd45ada9SAlfonso Acosta */ 4406fd45ada9SAlfonso Acosta memcpy(conn->le_adv_data, data, len); 4407fd45ada9SAlfonso Acosta conn->le_adv_data_len = len; 4408fd45ada9SAlfonso Acosta } 440999a6768eSJohan Hedberg 44101c1abcabSJohan Hedberg /* Passive scanning shouldn't trigger any device found events, 44111c1abcabSJohan Hedberg * except for devices marked as CONN_REPORT for which we do send 44121c1abcabSJohan Hedberg * device found events. 44131c1abcabSJohan Hedberg */ 44141c1abcabSJohan Hedberg if (hdev->le_scan_type == LE_SCAN_PASSIVE) { 44150d2bf134SJohan Hedberg if (type == LE_ADV_DIRECT_IND) 44160d2bf134SJohan Hedberg return; 44170d2bf134SJohan Hedberg 44183a19b6feSJohan Hedberg if (!hci_pend_le_action_lookup(&hdev->pend_le_reports, 44193a19b6feSJohan Hedberg bdaddr, bdaddr_type)) 44200d2bf134SJohan Hedberg return; 44210d2bf134SJohan Hedberg 44220d2bf134SJohan Hedberg if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND) 44230d2bf134SJohan Hedberg flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 44240d2bf134SJohan Hedberg else 44250d2bf134SJohan Hedberg flags = 0; 44260d2bf134SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 44270d2bf134SJohan Hedberg rssi, flags, data, len, NULL, 0); 442897bf2e99SJohan Hedberg return; 4429ca5c4be7SJohan Hedberg } 44304af605d8SJohan Hedberg 4431c70a7e4cSMarcel Holtmann /* When receiving non-connectable or scannable undirected 4432c70a7e4cSMarcel Holtmann * advertising reports, this means that the remote device is 4433c70a7e4cSMarcel Holtmann * not connectable and then clearly indicate this in the 4434c70a7e4cSMarcel Holtmann * device found event. 4435c70a7e4cSMarcel Holtmann * 4436c70a7e4cSMarcel Holtmann * When receiving a scan response, then there is no way to 4437c70a7e4cSMarcel Holtmann * know if the remote device is connectable or not. However 4438c70a7e4cSMarcel Holtmann * since scan responses are merged with a previously seen 4439c70a7e4cSMarcel Holtmann * advertising report, the flags field from that report 4440c70a7e4cSMarcel Holtmann * will be used. 4441c70a7e4cSMarcel Holtmann * 4442c70a7e4cSMarcel Holtmann * In the really unlikely case that a controller get confused 4443c70a7e4cSMarcel Holtmann * and just sends a scan response event, then it is marked as 4444c70a7e4cSMarcel Holtmann * not connectable as well. 4445c70a7e4cSMarcel Holtmann */ 4446c70a7e4cSMarcel Holtmann if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND || 4447c70a7e4cSMarcel Holtmann type == LE_ADV_SCAN_RSP) 4448c70a7e4cSMarcel Holtmann flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 4449c70a7e4cSMarcel Holtmann else 4450c70a7e4cSMarcel Holtmann flags = 0; 4451c70a7e4cSMarcel Holtmann 4452b9a6328fSJohan Hedberg /* If there's nothing pending either store the data from this 4453b9a6328fSJohan Hedberg * event or send an immediate device found event if the data 4454b9a6328fSJohan Hedberg * should not be stored for later. 4455b9a6328fSJohan Hedberg */ 4456b9a6328fSJohan Hedberg if (!has_pending_adv_report(hdev)) { 4457b9a6328fSJohan Hedberg /* If the report will trigger a SCAN_REQ store it for 4458b9a6328fSJohan Hedberg * later merging. 4459b9a6328fSJohan Hedberg */ 4460b9a6328fSJohan Hedberg if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { 4461b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type, 4462c70a7e4cSMarcel Holtmann rssi, flags, data, len); 4463b9a6328fSJohan Hedberg return; 4464b9a6328fSJohan Hedberg } 4465b9a6328fSJohan Hedberg 4466b9a6328fSJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 4467c70a7e4cSMarcel Holtmann rssi, flags, data, len, NULL, 0); 4468b9a6328fSJohan Hedberg return; 4469b9a6328fSJohan Hedberg } 4470b9a6328fSJohan Hedberg 4471474ee066SJohan Hedberg /* Check if the pending report is for the same device as the new one */ 4472474ee066SJohan Hedberg match = (!bacmp(bdaddr, &d->last_adv_addr) && 4473474ee066SJohan Hedberg bdaddr_type == d->last_adv_addr_type); 4474474ee066SJohan Hedberg 4475b9a6328fSJohan Hedberg /* If the pending data doesn't match this report or this isn't a 4476b9a6328fSJohan Hedberg * scan response (e.g. we got a duplicate ADV_IND) then force 4477b9a6328fSJohan Hedberg * sending of the pending data. 4478b9a6328fSJohan Hedberg */ 4479474ee066SJohan Hedberg if (type != LE_ADV_SCAN_RSP || !match) { 4480474ee066SJohan Hedberg /* Send out whatever is in the cache, but skip duplicates */ 4481474ee066SJohan Hedberg if (!match) 4482b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 4483ff5cd29fSJohan Hedberg d->last_adv_addr_type, NULL, 4484c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags, 4485ff5cd29fSJohan Hedberg d->last_adv_data, 4486474ee066SJohan Hedberg d->last_adv_data_len, NULL, 0); 4487b9a6328fSJohan Hedberg 4488b9a6328fSJohan Hedberg /* If the new report will trigger a SCAN_REQ store it for 4489b9a6328fSJohan Hedberg * later merging. 4490b9a6328fSJohan Hedberg */ 4491b9a6328fSJohan Hedberg if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { 4492b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type, 4493c70a7e4cSMarcel Holtmann rssi, flags, data, len); 4494b9a6328fSJohan Hedberg return; 4495b9a6328fSJohan Hedberg } 4496b9a6328fSJohan Hedberg 4497b9a6328fSJohan Hedberg /* The advertising reports cannot be merged, so clear 4498b9a6328fSJohan Hedberg * the pending report and send out a device found event. 4499b9a6328fSJohan Hedberg */ 4500b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 45015c5b93e4SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 4502c70a7e4cSMarcel Holtmann rssi, flags, data, len, NULL, 0); 4503b9a6328fSJohan Hedberg return; 4504b9a6328fSJohan Hedberg } 4505b9a6328fSJohan Hedberg 4506b9a6328fSJohan Hedberg /* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and 4507b9a6328fSJohan Hedberg * the new event is a SCAN_RSP. We can therefore proceed with 4508b9a6328fSJohan Hedberg * sending a merged device found event. 4509b9a6328fSJohan Hedberg */ 4510b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 4511c70a7e4cSMarcel Holtmann d->last_adv_addr_type, NULL, rssi, d->last_adv_flags, 451242bd6a56SMarcel Holtmann d->last_adv_data, d->last_adv_data_len, data, len); 4513b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 45144af605d8SJohan Hedberg } 45154af605d8SJohan Hedberg 45166039aa73SGustavo Padovan static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) 45179aa04c91SAndre Guedes { 4518e95beb41SAndre Guedes u8 num_reports = skb->data[0]; 4519e95beb41SAndre Guedes void *ptr = &skb->data[1]; 45209aa04c91SAndre Guedes 4521a4790dbdSAndre Guedes hci_dev_lock(hdev); 4522a4790dbdSAndre Guedes 4523e95beb41SAndre Guedes while (num_reports--) { 4524e95beb41SAndre Guedes struct hci_ev_le_advertising_info *ev = ptr; 45254af605d8SJohan Hedberg s8 rssi; 4526a4790dbdSAndre Guedes 45273c9e9195SAndre Guedes rssi = ev->data[ev->length]; 45284af605d8SJohan Hedberg process_adv_report(hdev, ev->evt_type, &ev->bdaddr, 45294af605d8SJohan Hedberg ev->bdaddr_type, rssi, ev->data, ev->length); 45303c9e9195SAndre Guedes 4531e95beb41SAndre Guedes ptr += sizeof(*ev) + ev->length + 1; 45329aa04c91SAndre Guedes } 4533a4790dbdSAndre Guedes 4534a4790dbdSAndre Guedes hci_dev_unlock(hdev); 45359aa04c91SAndre Guedes } 45369aa04c91SAndre Guedes 45376039aa73SGustavo Padovan static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 4538a7a595f6SVinicius Costa Gomes { 4539a7a595f6SVinicius Costa Gomes struct hci_ev_le_ltk_req *ev = (void *) skb->data; 4540a7a595f6SVinicius Costa Gomes struct hci_cp_le_ltk_reply cp; 4541bea710feSVinicius Costa Gomes struct hci_cp_le_ltk_neg_reply neg; 4542a7a595f6SVinicius Costa Gomes struct hci_conn *conn; 4543c9839a11SVinicius Costa Gomes struct smp_ltk *ltk; 4544a7a595f6SVinicius Costa Gomes 45459f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle)); 4546a7a595f6SVinicius Costa Gomes 4547a7a595f6SVinicius Costa Gomes hci_dev_lock(hdev); 4548a7a595f6SVinicius Costa Gomes 4549a7a595f6SVinicius Costa Gomes conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 4550bea710feSVinicius Costa Gomes if (conn == NULL) 4551bea710feSVinicius Costa Gomes goto not_found; 4552a7a595f6SVinicius Costa Gomes 4553e804d25dSJohan Hedberg ltk = hci_find_ltk(hdev, ev->ediv, ev->rand, conn->role); 4554bea710feSVinicius Costa Gomes if (ltk == NULL) 4555bea710feSVinicius Costa Gomes goto not_found; 4556bea710feSVinicius Costa Gomes 4557bea710feSVinicius Costa Gomes memcpy(cp.ltk, ltk->val, sizeof(ltk->val)); 4558a7a595f6SVinicius Costa Gomes cp.handle = cpu_to_le16(conn->handle); 4559c9839a11SVinicius Costa Gomes 4560a6f7833cSJohan Hedberg conn->pending_sec_level = smp_ltk_sec_level(ltk); 4561a7a595f6SVinicius Costa Gomes 456289cbb4daSAndre Guedes conn->enc_key_size = ltk->enc_size; 4563a7a595f6SVinicius Costa Gomes 4564a7a595f6SVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); 4565a7a595f6SVinicius Costa Gomes 45665981a882SClaudio Takahasi /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a 45675981a882SClaudio Takahasi * temporary key used to encrypt a connection following 45685981a882SClaudio Takahasi * pairing. It is used during the Encrypted Session Setup to 45695981a882SClaudio Takahasi * distribute the keys. Later, security can be re-established 45705981a882SClaudio Takahasi * using a distributed LTK. 45715981a882SClaudio Takahasi */ 45722ceba539SJohan Hedberg if (ltk->type == SMP_STK) { 4573fe59a05fSJohan Hedberg set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); 4574c9839a11SVinicius Costa Gomes list_del(<k->list); 4575c9839a11SVinicius Costa Gomes kfree(ltk); 4576fe59a05fSJohan Hedberg } else { 4577fe59a05fSJohan Hedberg clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); 4578c9839a11SVinicius Costa Gomes } 4579c9839a11SVinicius Costa Gomes 4580a7a595f6SVinicius Costa Gomes hci_dev_unlock(hdev); 4581bea710feSVinicius Costa Gomes 4582bea710feSVinicius Costa Gomes return; 4583bea710feSVinicius Costa Gomes 4584bea710feSVinicius Costa Gomes not_found: 4585bea710feSVinicius Costa Gomes neg.handle = ev->handle; 4586bea710feSVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg); 4587bea710feSVinicius Costa Gomes hci_dev_unlock(hdev); 4588a7a595f6SVinicius Costa Gomes } 4589a7a595f6SVinicius Costa Gomes 45908e75b46aSAndre Guedes static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle, 45918e75b46aSAndre Guedes u8 reason) 45928e75b46aSAndre Guedes { 45938e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_neg_reply cp; 45948e75b46aSAndre Guedes 45958e75b46aSAndre Guedes cp.handle = cpu_to_le16(handle); 45968e75b46aSAndre Guedes cp.reason = reason; 45978e75b46aSAndre Guedes 45988e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp), 45998e75b46aSAndre Guedes &cp); 46008e75b46aSAndre Guedes } 46018e75b46aSAndre Guedes 46028e75b46aSAndre Guedes static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, 46038e75b46aSAndre Guedes struct sk_buff *skb) 46048e75b46aSAndre Guedes { 46058e75b46aSAndre Guedes struct hci_ev_le_remote_conn_param_req *ev = (void *) skb->data; 46068e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_reply cp; 46078e75b46aSAndre Guedes struct hci_conn *hcon; 46088e75b46aSAndre Guedes u16 handle, min, max, latency, timeout; 46098e75b46aSAndre Guedes 46108e75b46aSAndre Guedes handle = le16_to_cpu(ev->handle); 46118e75b46aSAndre Guedes min = le16_to_cpu(ev->interval_min); 46128e75b46aSAndre Guedes max = le16_to_cpu(ev->interval_max); 46138e75b46aSAndre Guedes latency = le16_to_cpu(ev->latency); 46148e75b46aSAndre Guedes timeout = le16_to_cpu(ev->timeout); 46158e75b46aSAndre Guedes 46168e75b46aSAndre Guedes hcon = hci_conn_hash_lookup_handle(hdev, handle); 46178e75b46aSAndre Guedes if (!hcon || hcon->state != BT_CONNECTED) 46188e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle, 46198e75b46aSAndre Guedes HCI_ERROR_UNKNOWN_CONN_ID); 46208e75b46aSAndre Guedes 46218e75b46aSAndre Guedes if (hci_check_conn_params(min, max, latency, timeout)) 46228e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle, 46238e75b46aSAndre Guedes HCI_ERROR_INVALID_LL_PARAMS); 46248e75b46aSAndre Guedes 462540bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) { 4626348d50b8SJohan Hedberg struct hci_conn_params *params; 4627f4869e2aSJohan Hedberg u8 store_hint; 4628348d50b8SJohan Hedberg 4629348d50b8SJohan Hedberg hci_dev_lock(hdev); 4630348d50b8SJohan Hedberg 4631348d50b8SJohan Hedberg params = hci_conn_params_lookup(hdev, &hcon->dst, 4632348d50b8SJohan Hedberg hcon->dst_type); 4633348d50b8SJohan Hedberg if (params) { 4634348d50b8SJohan Hedberg params->conn_min_interval = min; 4635348d50b8SJohan Hedberg params->conn_max_interval = max; 4636348d50b8SJohan Hedberg params->conn_latency = latency; 4637348d50b8SJohan Hedberg params->supervision_timeout = timeout; 4638f4869e2aSJohan Hedberg store_hint = 0x01; 4639f4869e2aSJohan Hedberg } else{ 4640f4869e2aSJohan Hedberg store_hint = 0x00; 4641348d50b8SJohan Hedberg } 4642348d50b8SJohan Hedberg 4643348d50b8SJohan Hedberg hci_dev_unlock(hdev); 4644348d50b8SJohan Hedberg 4645f4869e2aSJohan Hedberg mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type, 4646f4869e2aSJohan Hedberg store_hint, min, max, latency, timeout); 4647348d50b8SJohan Hedberg } 4648ffb5a827SAndre Guedes 46498e75b46aSAndre Guedes cp.handle = ev->handle; 46508e75b46aSAndre Guedes cp.interval_min = ev->interval_min; 46518e75b46aSAndre Guedes cp.interval_max = ev->interval_max; 46528e75b46aSAndre Guedes cp.latency = ev->latency; 46538e75b46aSAndre Guedes cp.timeout = ev->timeout; 46548e75b46aSAndre Guedes cp.min_ce_len = 0; 46558e75b46aSAndre Guedes cp.max_ce_len = 0; 46568e75b46aSAndre Guedes 46578e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp); 46588e75b46aSAndre Guedes } 46598e75b46aSAndre Guedes 46606039aa73SGustavo Padovan static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) 4661fcd89c09SVille Tervo { 4662fcd89c09SVille Tervo struct hci_ev_le_meta *le_ev = (void *) skb->data; 4663fcd89c09SVille Tervo 4664fcd89c09SVille Tervo skb_pull(skb, sizeof(*le_ev)); 4665fcd89c09SVille Tervo 4666fcd89c09SVille Tervo switch (le_ev->subevent) { 4667fcd89c09SVille Tervo case HCI_EV_LE_CONN_COMPLETE: 4668fcd89c09SVille Tervo hci_le_conn_complete_evt(hdev, skb); 4669fcd89c09SVille Tervo break; 4670fcd89c09SVille Tervo 46711855d92dSMarcel Holtmann case HCI_EV_LE_CONN_UPDATE_COMPLETE: 46721855d92dSMarcel Holtmann hci_le_conn_update_complete_evt(hdev, skb); 46731855d92dSMarcel Holtmann break; 46741855d92dSMarcel Holtmann 46759aa04c91SAndre Guedes case HCI_EV_LE_ADVERTISING_REPORT: 46769aa04c91SAndre Guedes hci_le_adv_report_evt(hdev, skb); 46779aa04c91SAndre Guedes break; 46789aa04c91SAndre Guedes 4679a7a595f6SVinicius Costa Gomes case HCI_EV_LE_LTK_REQ: 4680a7a595f6SVinicius Costa Gomes hci_le_ltk_request_evt(hdev, skb); 4681a7a595f6SVinicius Costa Gomes break; 4682a7a595f6SVinicius Costa Gomes 46838e75b46aSAndre Guedes case HCI_EV_LE_REMOTE_CONN_PARAM_REQ: 46848e75b46aSAndre Guedes hci_le_remote_conn_param_req_evt(hdev, skb); 46858e75b46aSAndre Guedes break; 46868e75b46aSAndre Guedes 4687fcd89c09SVille Tervo default: 4688fcd89c09SVille Tervo break; 4689fcd89c09SVille Tervo } 4690fcd89c09SVille Tervo } 4691fcd89c09SVille Tervo 46929495b2eeSAndrei Emeltchenko static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb) 46939495b2eeSAndrei Emeltchenko { 46949495b2eeSAndrei Emeltchenko struct hci_ev_channel_selected *ev = (void *) skb->data; 46959495b2eeSAndrei Emeltchenko struct hci_conn *hcon; 46969495b2eeSAndrei Emeltchenko 46979495b2eeSAndrei Emeltchenko BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle); 46989495b2eeSAndrei Emeltchenko 46999495b2eeSAndrei Emeltchenko skb_pull(skb, sizeof(*ev)); 47009495b2eeSAndrei Emeltchenko 47019495b2eeSAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 47029495b2eeSAndrei Emeltchenko if (!hcon) 47039495b2eeSAndrei Emeltchenko return; 47049495b2eeSAndrei Emeltchenko 47059495b2eeSAndrei Emeltchenko amp_read_loc_assoc_final_data(hdev, hcon); 47069495b2eeSAndrei Emeltchenko } 47079495b2eeSAndrei Emeltchenko 47081da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) 47091da177e4SLinus Torvalds { 4710a9de9248SMarcel Holtmann struct hci_event_hdr *hdr = (void *) skb->data; 4711a9de9248SMarcel Holtmann __u8 event = hdr->evt; 47121da177e4SLinus Torvalds 4713b6ddb638SJohan Hedberg hci_dev_lock(hdev); 4714b6ddb638SJohan Hedberg 4715b6ddb638SJohan Hedberg /* Received events are (currently) only needed when a request is 4716b6ddb638SJohan Hedberg * ongoing so avoid unnecessary memory allocation. 4717b6ddb638SJohan Hedberg */ 4718899de765SMarcel Holtmann if (hci_req_pending(hdev)) { 4719b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 4720b6ddb638SJohan Hedberg hdev->recv_evt = skb_clone(skb, GFP_KERNEL); 4721b6ddb638SJohan Hedberg } 4722b6ddb638SJohan Hedberg 4723b6ddb638SJohan Hedberg hci_dev_unlock(hdev); 4724b6ddb638SJohan Hedberg 47251da177e4SLinus Torvalds skb_pull(skb, HCI_EVENT_HDR_SIZE); 47261da177e4SLinus Torvalds 472702350a72SJohan Hedberg if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) { 4728c1f23a2bSJohannes Berg struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data; 4729c1f23a2bSJohannes Berg u16 opcode = __le16_to_cpu(cmd_hdr->opcode); 473002350a72SJohan Hedberg 473102350a72SJohan Hedberg hci_req_cmd_complete(hdev, opcode, 0); 473202350a72SJohan Hedberg } 473302350a72SJohan Hedberg 4734a9de9248SMarcel Holtmann switch (event) { 47351da177e4SLinus Torvalds case HCI_EV_INQUIRY_COMPLETE: 47361da177e4SLinus Torvalds hci_inquiry_complete_evt(hdev, skb); 47371da177e4SLinus Torvalds break; 47381da177e4SLinus Torvalds 47391da177e4SLinus Torvalds case HCI_EV_INQUIRY_RESULT: 47401da177e4SLinus Torvalds hci_inquiry_result_evt(hdev, skb); 47411da177e4SLinus Torvalds break; 47421da177e4SLinus Torvalds 4743a9de9248SMarcel Holtmann case HCI_EV_CONN_COMPLETE: 4744a9de9248SMarcel Holtmann hci_conn_complete_evt(hdev, skb); 474521d9e30eSMarcel Holtmann break; 474621d9e30eSMarcel Holtmann 47471da177e4SLinus Torvalds case HCI_EV_CONN_REQUEST: 47481da177e4SLinus Torvalds hci_conn_request_evt(hdev, skb); 47491da177e4SLinus Torvalds break; 47501da177e4SLinus Torvalds 47511da177e4SLinus Torvalds case HCI_EV_DISCONN_COMPLETE: 47521da177e4SLinus Torvalds hci_disconn_complete_evt(hdev, skb); 47531da177e4SLinus Torvalds break; 47541da177e4SLinus Torvalds 47551da177e4SLinus Torvalds case HCI_EV_AUTH_COMPLETE: 47561da177e4SLinus Torvalds hci_auth_complete_evt(hdev, skb); 47571da177e4SLinus Torvalds break; 47581da177e4SLinus Torvalds 4759a9de9248SMarcel Holtmann case HCI_EV_REMOTE_NAME: 4760a9de9248SMarcel Holtmann hci_remote_name_evt(hdev, skb); 4761a9de9248SMarcel Holtmann break; 4762a9de9248SMarcel Holtmann 47631da177e4SLinus Torvalds case HCI_EV_ENCRYPT_CHANGE: 47641da177e4SLinus Torvalds hci_encrypt_change_evt(hdev, skb); 47651da177e4SLinus Torvalds break; 47661da177e4SLinus Torvalds 4767a9de9248SMarcel Holtmann case HCI_EV_CHANGE_LINK_KEY_COMPLETE: 4768a9de9248SMarcel Holtmann hci_change_link_key_complete_evt(hdev, skb); 4769a9de9248SMarcel Holtmann break; 4770a9de9248SMarcel Holtmann 4771a9de9248SMarcel Holtmann case HCI_EV_REMOTE_FEATURES: 4772a9de9248SMarcel Holtmann hci_remote_features_evt(hdev, skb); 4773a9de9248SMarcel Holtmann break; 4774a9de9248SMarcel Holtmann 4775a9de9248SMarcel Holtmann case HCI_EV_CMD_COMPLETE: 4776a9de9248SMarcel Holtmann hci_cmd_complete_evt(hdev, skb); 4777a9de9248SMarcel Holtmann break; 4778a9de9248SMarcel Holtmann 4779a9de9248SMarcel Holtmann case HCI_EV_CMD_STATUS: 4780a9de9248SMarcel Holtmann hci_cmd_status_evt(hdev, skb); 4781a9de9248SMarcel Holtmann break; 4782a9de9248SMarcel Holtmann 478324dfa343SMarcel Holtmann case HCI_EV_HARDWARE_ERROR: 478424dfa343SMarcel Holtmann hci_hardware_error_evt(hdev, skb); 478524dfa343SMarcel Holtmann break; 478624dfa343SMarcel Holtmann 4787a9de9248SMarcel Holtmann case HCI_EV_ROLE_CHANGE: 4788a9de9248SMarcel Holtmann hci_role_change_evt(hdev, skb); 4789a9de9248SMarcel Holtmann break; 4790a9de9248SMarcel Holtmann 4791a9de9248SMarcel Holtmann case HCI_EV_NUM_COMP_PKTS: 4792a9de9248SMarcel Holtmann hci_num_comp_pkts_evt(hdev, skb); 4793a9de9248SMarcel Holtmann break; 4794a9de9248SMarcel Holtmann 4795a9de9248SMarcel Holtmann case HCI_EV_MODE_CHANGE: 4796a9de9248SMarcel Holtmann hci_mode_change_evt(hdev, skb); 47971da177e4SLinus Torvalds break; 47981da177e4SLinus Torvalds 47991da177e4SLinus Torvalds case HCI_EV_PIN_CODE_REQ: 48001da177e4SLinus Torvalds hci_pin_code_request_evt(hdev, skb); 48011da177e4SLinus Torvalds break; 48021da177e4SLinus Torvalds 48031da177e4SLinus Torvalds case HCI_EV_LINK_KEY_REQ: 48041da177e4SLinus Torvalds hci_link_key_request_evt(hdev, skb); 48051da177e4SLinus Torvalds break; 48061da177e4SLinus Torvalds 48071da177e4SLinus Torvalds case HCI_EV_LINK_KEY_NOTIFY: 48081da177e4SLinus Torvalds hci_link_key_notify_evt(hdev, skb); 48091da177e4SLinus Torvalds break; 48101da177e4SLinus Torvalds 48111da177e4SLinus Torvalds case HCI_EV_CLOCK_OFFSET: 48121da177e4SLinus Torvalds hci_clock_offset_evt(hdev, skb); 48131da177e4SLinus Torvalds break; 48141da177e4SLinus Torvalds 4815a8746417SMarcel Holtmann case HCI_EV_PKT_TYPE_CHANGE: 4816a8746417SMarcel Holtmann hci_pkt_type_change_evt(hdev, skb); 4817a8746417SMarcel Holtmann break; 4818a8746417SMarcel Holtmann 481985a1e930SMarcel Holtmann case HCI_EV_PSCAN_REP_MODE: 482085a1e930SMarcel Holtmann hci_pscan_rep_mode_evt(hdev, skb); 482185a1e930SMarcel Holtmann break; 482285a1e930SMarcel Holtmann 4823a9de9248SMarcel Holtmann case HCI_EV_INQUIRY_RESULT_WITH_RSSI: 4824a9de9248SMarcel Holtmann hci_inquiry_result_with_rssi_evt(hdev, skb); 4825a9de9248SMarcel Holtmann break; 4826a9de9248SMarcel Holtmann 4827a9de9248SMarcel Holtmann case HCI_EV_REMOTE_EXT_FEATURES: 4828a9de9248SMarcel Holtmann hci_remote_ext_features_evt(hdev, skb); 4829a9de9248SMarcel Holtmann break; 4830a9de9248SMarcel Holtmann 4831a9de9248SMarcel Holtmann case HCI_EV_SYNC_CONN_COMPLETE: 4832a9de9248SMarcel Holtmann hci_sync_conn_complete_evt(hdev, skb); 4833a9de9248SMarcel Holtmann break; 4834a9de9248SMarcel Holtmann 4835a9de9248SMarcel Holtmann case HCI_EV_EXTENDED_INQUIRY_RESULT: 4836a9de9248SMarcel Holtmann hci_extended_inquiry_result_evt(hdev, skb); 48371da177e4SLinus Torvalds break; 48381da177e4SLinus Torvalds 48391c2e0041SJohan Hedberg case HCI_EV_KEY_REFRESH_COMPLETE: 48401c2e0041SJohan Hedberg hci_key_refresh_complete_evt(hdev, skb); 48411c2e0041SJohan Hedberg break; 48421c2e0041SJohan Hedberg 48430493684eSMarcel Holtmann case HCI_EV_IO_CAPA_REQUEST: 48440493684eSMarcel Holtmann hci_io_capa_request_evt(hdev, skb); 48450493684eSMarcel Holtmann break; 48460493684eSMarcel Holtmann 484703b555e1SJohan Hedberg case HCI_EV_IO_CAPA_REPLY: 484803b555e1SJohan Hedberg hci_io_capa_reply_evt(hdev, skb); 484903b555e1SJohan Hedberg break; 485003b555e1SJohan Hedberg 4851a5c29683SJohan Hedberg case HCI_EV_USER_CONFIRM_REQUEST: 4852a5c29683SJohan Hedberg hci_user_confirm_request_evt(hdev, skb); 4853a5c29683SJohan Hedberg break; 4854a5c29683SJohan Hedberg 48551143d458SBrian Gix case HCI_EV_USER_PASSKEY_REQUEST: 48561143d458SBrian Gix hci_user_passkey_request_evt(hdev, skb); 48571143d458SBrian Gix break; 48581143d458SBrian Gix 485992a25256SJohan Hedberg case HCI_EV_USER_PASSKEY_NOTIFY: 486092a25256SJohan Hedberg hci_user_passkey_notify_evt(hdev, skb); 486192a25256SJohan Hedberg break; 486292a25256SJohan Hedberg 486392a25256SJohan Hedberg case HCI_EV_KEYPRESS_NOTIFY: 486492a25256SJohan Hedberg hci_keypress_notify_evt(hdev, skb); 486592a25256SJohan Hedberg break; 486692a25256SJohan Hedberg 48670493684eSMarcel Holtmann case HCI_EV_SIMPLE_PAIR_COMPLETE: 48680493684eSMarcel Holtmann hci_simple_pair_complete_evt(hdev, skb); 48690493684eSMarcel Holtmann break; 48700493684eSMarcel Holtmann 487141a96212SMarcel Holtmann case HCI_EV_REMOTE_HOST_FEATURES: 487241a96212SMarcel Holtmann hci_remote_host_features_evt(hdev, skb); 487341a96212SMarcel Holtmann break; 487441a96212SMarcel Holtmann 4875fcd89c09SVille Tervo case HCI_EV_LE_META: 4876fcd89c09SVille Tervo hci_le_meta_evt(hdev, skb); 4877fcd89c09SVille Tervo break; 4878fcd89c09SVille Tervo 48799495b2eeSAndrei Emeltchenko case HCI_EV_CHANNEL_SELECTED: 48809495b2eeSAndrei Emeltchenko hci_chan_selected_evt(hdev, skb); 48819495b2eeSAndrei Emeltchenko break; 48829495b2eeSAndrei Emeltchenko 48832763eda6SSzymon Janc case HCI_EV_REMOTE_OOB_DATA_REQUEST: 48842763eda6SSzymon Janc hci_remote_oob_data_request_evt(hdev, skb); 48852763eda6SSzymon Janc break; 48862763eda6SSzymon Janc 4887d5e91192SAndrei Emeltchenko case HCI_EV_PHY_LINK_COMPLETE: 4888d5e91192SAndrei Emeltchenko hci_phy_link_complete_evt(hdev, skb); 4889d5e91192SAndrei Emeltchenko break; 4890d5e91192SAndrei Emeltchenko 489127695fb4SAndrei Emeltchenko case HCI_EV_LOGICAL_LINK_COMPLETE: 489227695fb4SAndrei Emeltchenko hci_loglink_complete_evt(hdev, skb); 489327695fb4SAndrei Emeltchenko break; 489427695fb4SAndrei Emeltchenko 4895606e2a10SAndrei Emeltchenko case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE: 4896606e2a10SAndrei Emeltchenko hci_disconn_loglink_complete_evt(hdev, skb); 4897606e2a10SAndrei Emeltchenko break; 4898606e2a10SAndrei Emeltchenko 48999eef6b3aSAndrei Emeltchenko case HCI_EV_DISCONN_PHY_LINK_COMPLETE: 49009eef6b3aSAndrei Emeltchenko hci_disconn_phylink_complete_evt(hdev, skb); 49019eef6b3aSAndrei Emeltchenko break; 49029eef6b3aSAndrei Emeltchenko 490325e89e99SAndrei Emeltchenko case HCI_EV_NUM_COMP_BLOCKS: 490425e89e99SAndrei Emeltchenko hci_num_comp_blocks_evt(hdev, skb); 490525e89e99SAndrei Emeltchenko break; 490625e89e99SAndrei Emeltchenko 49071da177e4SLinus Torvalds default: 49089f1db00cSAndrei Emeltchenko BT_DBG("%s event 0x%2.2x", hdev->name, event); 49091da177e4SLinus Torvalds break; 49101da177e4SLinus Torvalds } 49111da177e4SLinus Torvalds 49121da177e4SLinus Torvalds kfree_skb(skb); 49131da177e4SLinus Torvalds hdev->stat.evt_rx++; 49141da177e4SLinus Torvalds } 4915