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 <linux/module.h> 281da177e4SLinus Torvalds 291da177e4SLinus Torvalds #include <linux/types.h> 301da177e4SLinus Torvalds #include <linux/errno.h> 311da177e4SLinus Torvalds #include <linux/kernel.h> 321da177e4SLinus Torvalds #include <linux/slab.h> 331da177e4SLinus Torvalds #include <linux/poll.h> 341da177e4SLinus Torvalds #include <linux/fcntl.h> 351da177e4SLinus Torvalds #include <linux/init.h> 361da177e4SLinus Torvalds #include <linux/skbuff.h> 371da177e4SLinus Torvalds #include <linux/interrupt.h> 381da177e4SLinus Torvalds #include <net/sock.h> 391da177e4SLinus Torvalds 4070f23020SAndrei Emeltchenko #include <linux/uaccess.h> 411da177e4SLinus Torvalds #include <asm/unaligned.h> 421da177e4SLinus Torvalds 431da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 441da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds /* Handle HCI Event packets */ 471da177e4SLinus Torvalds 48a9de9248SMarcel Holtmann static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) 491da177e4SLinus Torvalds { 50a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 511da177e4SLinus Torvalds 52a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 531da177e4SLinus Torvalds 54e6d465cbSAndre Guedes if (status) { 55e6d465cbSAndre Guedes hci_dev_lock(hdev); 56e6d465cbSAndre Guedes mgmt_stop_discovery_failed(hdev, status); 57e6d465cbSAndre Guedes hci_dev_unlock(hdev); 58a9de9248SMarcel Holtmann return; 59e6d465cbSAndre Guedes } 601da177e4SLinus Torvalds 6189352e7dSAndre Guedes clear_bit(HCI_INQUIRY, &hdev->flags); 6289352e7dSAndre Guedes 6356e5cb86SJohan Hedberg hci_dev_lock(hdev); 64ff9ef578SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 6556e5cb86SJohan Hedberg hci_dev_unlock(hdev); 66a9de9248SMarcel Holtmann 6723bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); 68a9de9248SMarcel Holtmann 69a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 701da177e4SLinus Torvalds } 716bd57416SMarcel Holtmann 72a9de9248SMarcel Holtmann static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) 731da177e4SLinus Torvalds { 74a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 75a9de9248SMarcel Holtmann 76a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 77a9de9248SMarcel Holtmann 78a9de9248SMarcel Holtmann if (status) 79a9de9248SMarcel Holtmann return; 80a9de9248SMarcel Holtmann 81a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 82a9de9248SMarcel Holtmann } 83a9de9248SMarcel Holtmann 84a9de9248SMarcel Holtmann static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb) 85a9de9248SMarcel Holtmann { 86a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 87a9de9248SMarcel Holtmann } 88a9de9248SMarcel Holtmann 89a9de9248SMarcel Holtmann static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb) 90a9de9248SMarcel Holtmann { 91a9de9248SMarcel Holtmann struct hci_rp_role_discovery *rp = (void *) skb->data; 921da177e4SLinus Torvalds struct hci_conn *conn; 931da177e4SLinus Torvalds 94a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 951da177e4SLinus Torvalds 96a9de9248SMarcel Holtmann if (rp->status) 97a9de9248SMarcel Holtmann return; 981da177e4SLinus Torvalds 991da177e4SLinus Torvalds hci_dev_lock(hdev); 1001da177e4SLinus Torvalds 101a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 1021da177e4SLinus Torvalds if (conn) { 103a9de9248SMarcel Holtmann if (rp->role) 1041da177e4SLinus Torvalds conn->link_mode &= ~HCI_LM_MASTER; 1051da177e4SLinus Torvalds else 1061da177e4SLinus Torvalds conn->link_mode |= HCI_LM_MASTER; 1071da177e4SLinus Torvalds } 1081da177e4SLinus Torvalds 1091da177e4SLinus Torvalds hci_dev_unlock(hdev); 110a9de9248SMarcel Holtmann } 1111da177e4SLinus Torvalds 112e4e8e37cSMarcel Holtmann static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 113e4e8e37cSMarcel Holtmann { 114e4e8e37cSMarcel Holtmann struct hci_rp_read_link_policy *rp = (void *) skb->data; 115e4e8e37cSMarcel Holtmann struct hci_conn *conn; 116e4e8e37cSMarcel Holtmann 117e4e8e37cSMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 118e4e8e37cSMarcel Holtmann 119e4e8e37cSMarcel Holtmann if (rp->status) 120e4e8e37cSMarcel Holtmann return; 121e4e8e37cSMarcel Holtmann 122e4e8e37cSMarcel Holtmann hci_dev_lock(hdev); 123e4e8e37cSMarcel Holtmann 124e4e8e37cSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 125e4e8e37cSMarcel Holtmann if (conn) 126e4e8e37cSMarcel Holtmann conn->link_policy = __le16_to_cpu(rp->policy); 127e4e8e37cSMarcel Holtmann 128e4e8e37cSMarcel Holtmann hci_dev_unlock(hdev); 129e4e8e37cSMarcel Holtmann } 130e4e8e37cSMarcel Holtmann 131a9de9248SMarcel Holtmann static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 132a9de9248SMarcel Holtmann { 133a9de9248SMarcel Holtmann struct hci_rp_write_link_policy *rp = (void *) skb->data; 134a9de9248SMarcel Holtmann struct hci_conn *conn; 135a9de9248SMarcel Holtmann void *sent; 136a9de9248SMarcel Holtmann 137a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 138a9de9248SMarcel Holtmann 139a9de9248SMarcel Holtmann if (rp->status) 140a9de9248SMarcel Holtmann return; 141a9de9248SMarcel Holtmann 142a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY); 14304837f64SMarcel Holtmann if (!sent) 144a9de9248SMarcel Holtmann return; 14504837f64SMarcel Holtmann 14604837f64SMarcel Holtmann hci_dev_lock(hdev); 14704837f64SMarcel Holtmann 148a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 149e4e8e37cSMarcel Holtmann if (conn) 15083985319SHarvey Harrison conn->link_policy = get_unaligned_le16(sent + 2); 15104837f64SMarcel Holtmann 15204837f64SMarcel Holtmann hci_dev_unlock(hdev); 1531da177e4SLinus Torvalds } 1541da177e4SLinus Torvalds 155e4e8e37cSMarcel Holtmann static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 156e4e8e37cSMarcel Holtmann { 157e4e8e37cSMarcel Holtmann struct hci_rp_read_def_link_policy *rp = (void *) skb->data; 158e4e8e37cSMarcel Holtmann 159e4e8e37cSMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 160e4e8e37cSMarcel Holtmann 161e4e8e37cSMarcel Holtmann if (rp->status) 162e4e8e37cSMarcel Holtmann return; 163e4e8e37cSMarcel Holtmann 164e4e8e37cSMarcel Holtmann hdev->link_policy = __le16_to_cpu(rp->policy); 165e4e8e37cSMarcel Holtmann } 166e4e8e37cSMarcel Holtmann 167e4e8e37cSMarcel Holtmann static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 168e4e8e37cSMarcel Holtmann { 169e4e8e37cSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 170e4e8e37cSMarcel Holtmann void *sent; 171e4e8e37cSMarcel Holtmann 172e4e8e37cSMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 173e4e8e37cSMarcel Holtmann 174e4e8e37cSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY); 175e4e8e37cSMarcel Holtmann if (!sent) 176e4e8e37cSMarcel Holtmann return; 177e4e8e37cSMarcel Holtmann 178e4e8e37cSMarcel Holtmann if (!status) 179e4e8e37cSMarcel Holtmann hdev->link_policy = get_unaligned_le16(sent); 180e4e8e37cSMarcel Holtmann 18123bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status); 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 188a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 189a9de9248SMarcel Holtmann 19010572132SGustavo F. Padovan clear_bit(HCI_RESET, &hdev->flags); 19110572132SGustavo F. Padovan 19223bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_RESET, status); 193d23264a8SAndre Guedes 194a297e97cSJohan Hedberg /* Reset all non-persistent flags */ 1959f8ce967SJohan Hedberg hdev->dev_flags &= ~(BIT(HCI_LE_SCAN) | BIT(HCI_PENDING_CLASS)); 19669775ff6SAndre Guedes 19769775ff6SAndre Guedes hdev->discovery.state = DISCOVERY_STOPPED; 198a9de9248SMarcel Holtmann } 199a9de9248SMarcel Holtmann 200a9de9248SMarcel Holtmann static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) 201a9de9248SMarcel Holtmann { 202a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 2031da177e4SLinus Torvalds void *sent; 2041da177e4SLinus Torvalds 205a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 2061da177e4SLinus Torvalds 207a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME); 2081da177e4SLinus Torvalds if (!sent) 209a9de9248SMarcel Holtmann return; 2101da177e4SLinus Torvalds 21156e5cb86SJohan Hedberg hci_dev_lock(hdev); 21256e5cb86SJohan Hedberg 213f51d5b24SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 214f51d5b24SJohan Hedberg mgmt_set_local_name_complete(hdev, sent, status); 21528cc7bdeSJohan Hedberg else if (!status) 21628cc7bdeSJohan Hedberg memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); 217f51d5b24SJohan Hedberg 21856e5cb86SJohan Hedberg hci_dev_unlock(hdev); 2193159d384SJohan Hedberg 2203159d384SJohan Hedberg hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status); 221a9de9248SMarcel Holtmann } 222a9de9248SMarcel Holtmann 223a9de9248SMarcel Holtmann static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) 224a9de9248SMarcel Holtmann { 225a9de9248SMarcel Holtmann struct hci_rp_read_local_name *rp = (void *) skb->data; 226a9de9248SMarcel Holtmann 227a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 228a9de9248SMarcel Holtmann 229a9de9248SMarcel Holtmann if (rp->status) 230a9de9248SMarcel Holtmann return; 231a9de9248SMarcel Holtmann 232db99b5fcSJohan Hedberg if (test_bit(HCI_SETUP, &hdev->dev_flags)) 2331f6c6378SJohan Hedberg memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); 234a9de9248SMarcel Holtmann } 235a9de9248SMarcel Holtmann 236a9de9248SMarcel Holtmann static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) 237a9de9248SMarcel Holtmann { 238a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 239a9de9248SMarcel Holtmann void *sent; 240a9de9248SMarcel Holtmann 241a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 242a9de9248SMarcel Holtmann 243a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE); 244a9de9248SMarcel Holtmann if (!sent) 245a9de9248SMarcel Holtmann return; 2461da177e4SLinus Torvalds 2471da177e4SLinus Torvalds if (!status) { 248a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 249a9de9248SMarcel Holtmann 2501da177e4SLinus Torvalds if (param == AUTH_ENABLED) 2511da177e4SLinus Torvalds set_bit(HCI_AUTH, &hdev->flags); 2521da177e4SLinus Torvalds else 2531da177e4SLinus Torvalds clear_bit(HCI_AUTH, &hdev->flags); 2541da177e4SLinus Torvalds } 255a9de9248SMarcel Holtmann 25633ef95edSJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 25733ef95edSJohan Hedberg mgmt_auth_enable_complete(hdev, status); 25833ef95edSJohan Hedberg 25923bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status); 260a9de9248SMarcel Holtmann } 2611da177e4SLinus Torvalds 262a9de9248SMarcel Holtmann static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) 263a9de9248SMarcel Holtmann { 264a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 265a9de9248SMarcel Holtmann void *sent; 266a9de9248SMarcel Holtmann 267a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 268a9de9248SMarcel Holtmann 269a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE); 2701da177e4SLinus Torvalds if (!sent) 271a9de9248SMarcel Holtmann return; 2721da177e4SLinus Torvalds 2731da177e4SLinus Torvalds if (!status) { 274a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 275a9de9248SMarcel Holtmann 2761da177e4SLinus Torvalds if (param) 2771da177e4SLinus Torvalds set_bit(HCI_ENCRYPT, &hdev->flags); 2781da177e4SLinus Torvalds else 2791da177e4SLinus Torvalds clear_bit(HCI_ENCRYPT, &hdev->flags); 2801da177e4SLinus Torvalds } 281a9de9248SMarcel Holtmann 28223bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status); 2831da177e4SLinus Torvalds } 2841da177e4SLinus Torvalds 285a9de9248SMarcel Holtmann static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) 286a9de9248SMarcel Holtmann { 28736f7fc7eSJohan Hedberg __u8 param, status = *((__u8 *) skb->data); 28836f7fc7eSJohan Hedberg int old_pscan, old_iscan; 289a9de9248SMarcel Holtmann void *sent; 2901da177e4SLinus Torvalds 291a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 292a9de9248SMarcel Holtmann 293a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE); 2941da177e4SLinus Torvalds if (!sent) 295a9de9248SMarcel Holtmann return; 2961da177e4SLinus Torvalds 29736f7fc7eSJohan Hedberg param = *((__u8 *) sent); 298a9de9248SMarcel Holtmann 29956e5cb86SJohan Hedberg hci_dev_lock(hdev); 30056e5cb86SJohan Hedberg 3012d7cee58SJohan Hedberg if (status != 0) { 302744cf19eSJohan Hedberg mgmt_write_scan_failed(hdev, param, status); 3032d7cee58SJohan Hedberg hdev->discov_timeout = 0; 3042d7cee58SJohan Hedberg goto done; 3052d7cee58SJohan Hedberg } 3062d7cee58SJohan Hedberg 3079fbcbb45SJohan Hedberg old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags); 3089fbcbb45SJohan Hedberg old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags); 309a9de9248SMarcel Holtmann 31073f22f62SJohan Hedberg if (param & SCAN_INQUIRY) { 3111da177e4SLinus Torvalds set_bit(HCI_ISCAN, &hdev->flags); 3129fbcbb45SJohan Hedberg if (!old_iscan) 313744cf19eSJohan Hedberg mgmt_discoverable(hdev, 1); 31416ab91abSJohan Hedberg if (hdev->discov_timeout > 0) { 31516ab91abSJohan Hedberg int to = msecs_to_jiffies(hdev->discov_timeout * 1000); 31616ab91abSJohan Hedberg queue_delayed_work(hdev->workqueue, &hdev->discov_off, 31716ab91abSJohan Hedberg to); 31816ab91abSJohan Hedberg } 3199fbcbb45SJohan Hedberg } else if (old_iscan) 320744cf19eSJohan Hedberg mgmt_discoverable(hdev, 0); 3211da177e4SLinus Torvalds 3229fbcbb45SJohan Hedberg if (param & SCAN_PAGE) { 3231da177e4SLinus Torvalds set_bit(HCI_PSCAN, &hdev->flags); 3249fbcbb45SJohan Hedberg if (!old_pscan) 325744cf19eSJohan Hedberg mgmt_connectable(hdev, 1); 3269fbcbb45SJohan Hedberg } else if (old_pscan) 327744cf19eSJohan Hedberg mgmt_connectable(hdev, 0); 328a9de9248SMarcel Holtmann 32936f7fc7eSJohan Hedberg done: 33056e5cb86SJohan Hedberg hci_dev_unlock(hdev); 33123bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status); 3321da177e4SLinus Torvalds } 3331da177e4SLinus Torvalds 334a9de9248SMarcel Holtmann static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 335a9de9248SMarcel Holtmann { 336a9de9248SMarcel Holtmann struct hci_rp_read_class_of_dev *rp = (void *) skb->data; 337a9de9248SMarcel Holtmann 338a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 339a9de9248SMarcel Holtmann 340a9de9248SMarcel Holtmann if (rp->status) 341a9de9248SMarcel Holtmann return; 342a9de9248SMarcel Holtmann 343a9de9248SMarcel Holtmann memcpy(hdev->dev_class, rp->dev_class, 3); 344a9de9248SMarcel Holtmann 345a9de9248SMarcel Holtmann BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name, 346a9de9248SMarcel Holtmann hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); 347a9de9248SMarcel Holtmann } 348a9de9248SMarcel Holtmann 349a9de9248SMarcel Holtmann static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 350a9de9248SMarcel Holtmann { 351a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 352a9de9248SMarcel Holtmann void *sent; 353a9de9248SMarcel Holtmann 354a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 355a9de9248SMarcel Holtmann 356a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV); 357a9de9248SMarcel Holtmann if (!sent) 358a9de9248SMarcel Holtmann return; 359a9de9248SMarcel Holtmann 3607f9a903cSMarcel Holtmann hci_dev_lock(hdev); 3617f9a903cSMarcel Holtmann 3627f9a903cSMarcel Holtmann if (status == 0) 363a9de9248SMarcel Holtmann memcpy(hdev->dev_class, sent, 3); 3647f9a903cSMarcel Holtmann 3657f9a903cSMarcel Holtmann if (test_bit(HCI_MGMT, &hdev->dev_flags)) 3667f9a903cSMarcel Holtmann mgmt_set_class_of_dev_complete(hdev, sent, status); 3677f9a903cSMarcel Holtmann 3687f9a903cSMarcel Holtmann hci_dev_unlock(hdev); 369a9de9248SMarcel Holtmann } 370a9de9248SMarcel Holtmann 371a9de9248SMarcel Holtmann static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) 372a9de9248SMarcel Holtmann { 373a9de9248SMarcel Holtmann struct hci_rp_read_voice_setting *rp = (void *) skb->data; 374a9de9248SMarcel Holtmann __u16 setting; 375a9de9248SMarcel Holtmann 376a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 377a9de9248SMarcel Holtmann 378a9de9248SMarcel Holtmann if (rp->status) 379a9de9248SMarcel Holtmann return; 380a9de9248SMarcel Holtmann 381a9de9248SMarcel Holtmann setting = __le16_to_cpu(rp->voice_setting); 382a9de9248SMarcel Holtmann 383a9de9248SMarcel Holtmann if (hdev->voice_setting == setting) 384a9de9248SMarcel Holtmann return; 385a9de9248SMarcel Holtmann 386a9de9248SMarcel Holtmann hdev->voice_setting = setting; 387a9de9248SMarcel Holtmann 388a9de9248SMarcel Holtmann BT_DBG("%s voice setting 0x%04x", hdev->name, setting); 389a9de9248SMarcel Holtmann 3903c54711cSGustavo F. Padovan if (hdev->notify) 391a9de9248SMarcel Holtmann hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 392a9de9248SMarcel Holtmann } 393a9de9248SMarcel Holtmann 394a9de9248SMarcel Holtmann static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) 395a9de9248SMarcel Holtmann { 396a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 397f383f275SMarcel Holtmann __u16 setting; 398a9de9248SMarcel Holtmann void *sent; 399a9de9248SMarcel Holtmann 400a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 401a9de9248SMarcel Holtmann 402f383f275SMarcel Holtmann if (status) 403f383f275SMarcel Holtmann return; 404f383f275SMarcel Holtmann 405a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING); 406a9de9248SMarcel Holtmann if (!sent) 407a9de9248SMarcel Holtmann return; 408a9de9248SMarcel Holtmann 409f383f275SMarcel Holtmann setting = get_unaligned_le16(sent); 4101da177e4SLinus Torvalds 411f383f275SMarcel Holtmann if (hdev->voice_setting == setting) 412f383f275SMarcel Holtmann return; 413f383f275SMarcel Holtmann 4141da177e4SLinus Torvalds hdev->voice_setting = setting; 4151da177e4SLinus Torvalds 416a9de9248SMarcel Holtmann BT_DBG("%s voice setting 0x%04x", hdev->name, setting); 4171da177e4SLinus Torvalds 4183c54711cSGustavo F. Padovan if (hdev->notify) 4191da177e4SLinus Torvalds hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 4201da177e4SLinus Torvalds } 4211da177e4SLinus Torvalds 422a9de9248SMarcel Holtmann static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) 4231da177e4SLinus Torvalds { 424a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 4251da177e4SLinus Torvalds 426a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 4271da177e4SLinus Torvalds 42823bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status); 4291143e5a6SMarcel Holtmann } 4301143e5a6SMarcel Holtmann 431333140b5SMarcel Holtmann static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) 432333140b5SMarcel Holtmann { 433333140b5SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 434333140b5SMarcel Holtmann void *sent; 435333140b5SMarcel Holtmann 436333140b5SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 437333140b5SMarcel Holtmann 438333140b5SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); 439333140b5SMarcel Holtmann if (!sent) 440333140b5SMarcel Holtmann return; 441333140b5SMarcel Holtmann 442c0ecddc2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 443c0ecddc2SJohan Hedberg mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status); 444c0ecddc2SJohan Hedberg else if (!status) { 44584bde9d6SJohan Hedberg if (*((u8 *) sent)) 44684bde9d6SJohan Hedberg set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); 44784bde9d6SJohan Hedberg else 44884bde9d6SJohan Hedberg clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); 449c0ecddc2SJohan Hedberg } 450333140b5SMarcel Holtmann } 451333140b5SMarcel Holtmann 452d5859e22SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev) 453d5859e22SJohan Hedberg { 454d5859e22SJohan Hedberg if (hdev->features[6] & LMP_EXT_INQ) 455d5859e22SJohan Hedberg return 2; 456d5859e22SJohan Hedberg 457d5859e22SJohan Hedberg if (hdev->features[3] & LMP_RSSI_INQ) 458d5859e22SJohan Hedberg return 1; 459d5859e22SJohan Hedberg 460d5859e22SJohan Hedberg if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && 461d5859e22SJohan Hedberg hdev->lmp_subver == 0x0757) 462d5859e22SJohan Hedberg return 1; 463d5859e22SJohan Hedberg 464d5859e22SJohan Hedberg if (hdev->manufacturer == 15) { 465d5859e22SJohan Hedberg if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) 466d5859e22SJohan Hedberg return 1; 467d5859e22SJohan Hedberg if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) 468d5859e22SJohan Hedberg return 1; 469d5859e22SJohan Hedberg if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) 470d5859e22SJohan Hedberg return 1; 471d5859e22SJohan Hedberg } 472d5859e22SJohan Hedberg 473d5859e22SJohan Hedberg if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && 474d5859e22SJohan Hedberg hdev->lmp_subver == 0x1805) 475d5859e22SJohan Hedberg return 1; 476d5859e22SJohan Hedberg 477d5859e22SJohan Hedberg return 0; 478d5859e22SJohan Hedberg } 479d5859e22SJohan Hedberg 480d5859e22SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_dev *hdev) 481d5859e22SJohan Hedberg { 482d5859e22SJohan Hedberg u8 mode; 483d5859e22SJohan Hedberg 484d5859e22SJohan Hedberg mode = hci_get_inquiry_mode(hdev); 485d5859e22SJohan Hedberg 486d5859e22SJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); 487d5859e22SJohan Hedberg } 488d5859e22SJohan Hedberg 489d5859e22SJohan Hedberg static void hci_setup_event_mask(struct hci_dev *hdev) 490d5859e22SJohan Hedberg { 491d5859e22SJohan Hedberg /* The second byte is 0xff instead of 0x9f (two reserved bits 492d5859e22SJohan Hedberg * disabled) since a Broadcom 1.2 dongle doesn't respond to the 493d5859e22SJohan Hedberg * command otherwise */ 494d5859e22SJohan Hedberg u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; 495d5859e22SJohan Hedberg 4966de6c18dSVille Tervo /* CSR 1.1 dongles does not accept any bitfield so don't try to set 4976de6c18dSVille Tervo * any event mask for pre 1.2 devices */ 4985a13b095SAndrei Emeltchenko if (hdev->hci_ver < BLUETOOTH_VER_1_2) 4996de6c18dSVille Tervo return; 5006de6c18dSVille Tervo 501d5859e22SJohan Hedberg events[4] |= 0x01; /* Flow Specification Complete */ 502d5859e22SJohan Hedberg events[4] |= 0x02; /* Inquiry Result with RSSI */ 503d5859e22SJohan Hedberg events[4] |= 0x04; /* Read Remote Extended Features Complete */ 504d5859e22SJohan Hedberg events[5] |= 0x08; /* Synchronous Connection Complete */ 505d5859e22SJohan Hedberg events[5] |= 0x10; /* Synchronous Connection Changed */ 506d5859e22SJohan Hedberg 507d5859e22SJohan Hedberg if (hdev->features[3] & LMP_RSSI_INQ) 508d5859e22SJohan Hedberg events[4] |= 0x04; /* Inquiry Result with RSSI */ 509d5859e22SJohan Hedberg 510d5859e22SJohan Hedberg if (hdev->features[5] & LMP_SNIFF_SUBR) 511d5859e22SJohan Hedberg events[5] |= 0x20; /* Sniff Subrating */ 512d5859e22SJohan Hedberg 513d5859e22SJohan Hedberg if (hdev->features[5] & LMP_PAUSE_ENC) 514d5859e22SJohan Hedberg events[5] |= 0x80; /* Encryption Key Refresh Complete */ 515d5859e22SJohan Hedberg 516d5859e22SJohan Hedberg if (hdev->features[6] & LMP_EXT_INQ) 517d5859e22SJohan Hedberg events[5] |= 0x40; /* Extended Inquiry Result */ 518d5859e22SJohan Hedberg 519d5859e22SJohan Hedberg if (hdev->features[6] & LMP_NO_FLUSH) 520d5859e22SJohan Hedberg events[7] |= 0x01; /* Enhanced Flush Complete */ 521d5859e22SJohan Hedberg 522d5859e22SJohan Hedberg if (hdev->features[7] & LMP_LSTO) 523d5859e22SJohan Hedberg events[6] |= 0x80; /* Link Supervision Timeout Changed */ 524d5859e22SJohan Hedberg 525d5859e22SJohan Hedberg if (hdev->features[6] & LMP_SIMPLE_PAIR) { 526d5859e22SJohan Hedberg events[6] |= 0x01; /* IO Capability Request */ 527d5859e22SJohan Hedberg events[6] |= 0x02; /* IO Capability Response */ 528d5859e22SJohan Hedberg events[6] |= 0x04; /* User Confirmation Request */ 529d5859e22SJohan Hedberg events[6] |= 0x08; /* User Passkey Request */ 530d5859e22SJohan Hedberg events[6] |= 0x10; /* Remote OOB Data Request */ 531d5859e22SJohan Hedberg events[6] |= 0x20; /* Simple Pairing Complete */ 532d5859e22SJohan Hedberg events[7] |= 0x04; /* User Passkey Notification */ 533d5859e22SJohan Hedberg events[7] |= 0x08; /* Keypress Notification */ 534d5859e22SJohan Hedberg events[7] |= 0x10; /* Remote Host Supported 535d5859e22SJohan Hedberg * Features Notification */ 536d5859e22SJohan Hedberg } 537d5859e22SJohan Hedberg 538d5859e22SJohan Hedberg if (hdev->features[4] & LMP_LE) 539d5859e22SJohan Hedberg events[7] |= 0x20; /* LE Meta-Event */ 540d5859e22SJohan Hedberg 541d5859e22SJohan Hedberg hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); 542d5859e22SJohan Hedberg } 543d5859e22SJohan Hedberg 544d5859e22SJohan Hedberg static void hci_setup(struct hci_dev *hdev) 545d5859e22SJohan Hedberg { 546e61ef499SAndrei Emeltchenko if (hdev->dev_type != HCI_BREDR) 547e61ef499SAndrei Emeltchenko return; 548e61ef499SAndrei Emeltchenko 549d5859e22SJohan Hedberg hci_setup_event_mask(hdev); 550d5859e22SJohan Hedberg 551d095c1ebSAndrei Emeltchenko if (hdev->hci_ver > BLUETOOTH_VER_1_1) 552d5859e22SJohan Hedberg hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 553d5859e22SJohan Hedberg 55454d04dbbSJohan Hedberg if (hdev->features[6] & LMP_SIMPLE_PAIR) { 55554d04dbbSJohan Hedberg if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { 556d5859e22SJohan Hedberg u8 mode = 0x01; 55754d04dbbSJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, 55854d04dbbSJohan Hedberg sizeof(mode), &mode); 55954d04dbbSJohan Hedberg } else { 56054d04dbbSJohan Hedberg struct hci_cp_write_eir cp; 56154d04dbbSJohan Hedberg 56254d04dbbSJohan Hedberg memset(hdev->eir, 0, sizeof(hdev->eir)); 56354d04dbbSJohan Hedberg memset(&cp, 0, sizeof(cp)); 56454d04dbbSJohan Hedberg 56554d04dbbSJohan Hedberg hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp); 56654d04dbbSJohan Hedberg } 567d5859e22SJohan Hedberg } 568d5859e22SJohan Hedberg 569d5859e22SJohan Hedberg if (hdev->features[3] & LMP_RSSI_INQ) 570d5859e22SJohan Hedberg hci_setup_inquiry_mode(hdev); 571d5859e22SJohan Hedberg 572d5859e22SJohan Hedberg if (hdev->features[7] & LMP_INQ_TX_PWR) 573d5859e22SJohan Hedberg hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); 574971e3a4bSAndre Guedes 575971e3a4bSAndre Guedes if (hdev->features[7] & LMP_EXTFEATURES) { 576971e3a4bSAndre Guedes struct hci_cp_read_local_ext_features cp; 577971e3a4bSAndre Guedes 578971e3a4bSAndre Guedes cp.page = 0x01; 57904124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), 58004124681SGustavo F. Padovan &cp); 581971e3a4bSAndre Guedes } 582e6100a25SAndre Guedes 58347990ea0SJohan Hedberg if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) { 58447990ea0SJohan Hedberg u8 enable = 1; 58504124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable), 58604124681SGustavo F. Padovan &enable); 58747990ea0SJohan Hedberg } 588d5859e22SJohan Hedberg } 589d5859e22SJohan Hedberg 590a9de9248SMarcel Holtmann static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) 591a9de9248SMarcel Holtmann { 592a9de9248SMarcel Holtmann struct hci_rp_read_local_version *rp = (void *) skb->data; 5931143e5a6SMarcel Holtmann 594a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 5951143e5a6SMarcel Holtmann 596a9de9248SMarcel Holtmann if (rp->status) 59728b8df77SAndrei Emeltchenko goto done; 5981143e5a6SMarcel Holtmann 599a9de9248SMarcel Holtmann hdev->hci_ver = rp->hci_ver; 600e4e8e37cSMarcel Holtmann hdev->hci_rev = __le16_to_cpu(rp->hci_rev); 601d5859e22SJohan Hedberg hdev->lmp_ver = rp->lmp_ver; 602e4e8e37cSMarcel Holtmann hdev->manufacturer = __le16_to_cpu(rp->manufacturer); 603d5859e22SJohan Hedberg hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); 6041da177e4SLinus Torvalds 605a9de9248SMarcel Holtmann BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name, 606a9de9248SMarcel Holtmann hdev->manufacturer, 607a9de9248SMarcel Holtmann hdev->hci_ver, hdev->hci_rev); 608d5859e22SJohan Hedberg 609d5859e22SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags)) 610d5859e22SJohan Hedberg hci_setup(hdev); 61128b8df77SAndrei Emeltchenko 61228b8df77SAndrei Emeltchenko done: 61328b8df77SAndrei Emeltchenko hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status); 614d5859e22SJohan Hedberg } 615d5859e22SJohan Hedberg 616d5859e22SJohan Hedberg static void hci_setup_link_policy(struct hci_dev *hdev) 617d5859e22SJohan Hedberg { 618d5859e22SJohan Hedberg u16 link_policy = 0; 619d5859e22SJohan Hedberg 620d5859e22SJohan Hedberg if (hdev->features[0] & LMP_RSWITCH) 621d5859e22SJohan Hedberg link_policy |= HCI_LP_RSWITCH; 622d5859e22SJohan Hedberg if (hdev->features[0] & LMP_HOLD) 623d5859e22SJohan Hedberg link_policy |= HCI_LP_HOLD; 624d5859e22SJohan Hedberg if (hdev->features[0] & LMP_SNIFF) 625d5859e22SJohan Hedberg link_policy |= HCI_LP_SNIFF; 626d5859e22SJohan Hedberg if (hdev->features[1] & LMP_PARK) 627d5859e22SJohan Hedberg link_policy |= HCI_LP_PARK; 628d5859e22SJohan Hedberg 629d5859e22SJohan Hedberg link_policy = cpu_to_le16(link_policy); 63004124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(link_policy), 63104124681SGustavo F. Padovan &link_policy); 6321da177e4SLinus Torvalds } 6331da177e4SLinus Torvalds 634a9de9248SMarcel Holtmann static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb) 635a9de9248SMarcel Holtmann { 636a9de9248SMarcel Holtmann struct hci_rp_read_local_commands *rp = (void *) skb->data; 637a9de9248SMarcel Holtmann 638a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 639a9de9248SMarcel Holtmann 640a9de9248SMarcel Holtmann if (rp->status) 641d5859e22SJohan Hedberg goto done; 642a9de9248SMarcel Holtmann 643a9de9248SMarcel Holtmann memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); 644d5859e22SJohan Hedberg 645d5859e22SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10)) 646d5859e22SJohan Hedberg hci_setup_link_policy(hdev); 647d5859e22SJohan Hedberg 648d5859e22SJohan Hedberg done: 649d5859e22SJohan Hedberg hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status); 650a9de9248SMarcel Holtmann } 651a9de9248SMarcel Holtmann 652a9de9248SMarcel Holtmann static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb) 653a9de9248SMarcel Holtmann { 654a9de9248SMarcel Holtmann struct hci_rp_read_local_features *rp = (void *) skb->data; 655a9de9248SMarcel Holtmann 656a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 657a9de9248SMarcel Holtmann 658a9de9248SMarcel Holtmann if (rp->status) 659a9de9248SMarcel Holtmann return; 660a9de9248SMarcel Holtmann 661a9de9248SMarcel Holtmann memcpy(hdev->features, rp->features, 8); 6621da177e4SLinus Torvalds 6631da177e4SLinus Torvalds /* Adjust default settings according to features 6641da177e4SLinus Torvalds * supported by device. */ 665a9de9248SMarcel Holtmann 6661da177e4SLinus Torvalds if (hdev->features[0] & LMP_3SLOT) 6671da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM3 | HCI_DH3); 6681da177e4SLinus Torvalds 6691da177e4SLinus Torvalds if (hdev->features[0] & LMP_5SLOT) 6701da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM5 | HCI_DH5); 6711da177e4SLinus Torvalds 6725b7f9909SMarcel Holtmann if (hdev->features[1] & LMP_HV2) { 6731da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV2); 6745b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV2); 6755b7f9909SMarcel Holtmann } 6761da177e4SLinus Torvalds 6775b7f9909SMarcel Holtmann if (hdev->features[1] & LMP_HV3) { 6781da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV3); 6795b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV3); 6805b7f9909SMarcel Holtmann } 6815b7f9909SMarcel Holtmann 6825b7f9909SMarcel Holtmann if (hdev->features[3] & LMP_ESCO) 6835b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV3); 6845b7f9909SMarcel Holtmann 6855b7f9909SMarcel Holtmann if (hdev->features[4] & LMP_EV4) 6865b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV4); 6875b7f9909SMarcel Holtmann 6885b7f9909SMarcel Holtmann if (hdev->features[4] & LMP_EV5) 6895b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV5); 6901da177e4SLinus Torvalds 691efc7688bSMarcel Holtmann if (hdev->features[5] & LMP_EDR_ESCO_2M) 692efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV3); 693efc7688bSMarcel Holtmann 694efc7688bSMarcel Holtmann if (hdev->features[5] & LMP_EDR_ESCO_3M) 695efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_3EV3); 696efc7688bSMarcel Holtmann 697efc7688bSMarcel Holtmann if (hdev->features[5] & LMP_EDR_3S_ESCO) 698efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); 699efc7688bSMarcel Holtmann 700a9de9248SMarcel Holtmann BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name, 701a9de9248SMarcel Holtmann hdev->features[0], hdev->features[1], 702a9de9248SMarcel Holtmann hdev->features[2], hdev->features[3], 703a9de9248SMarcel Holtmann hdev->features[4], hdev->features[5], 704a9de9248SMarcel Holtmann hdev->features[6], hdev->features[7]); 7051da177e4SLinus Torvalds } 7061da177e4SLinus Torvalds 7078f984dfaSJohan Hedberg static void hci_set_le_support(struct hci_dev *hdev) 7088f984dfaSJohan Hedberg { 7098f984dfaSJohan Hedberg struct hci_cp_write_le_host_supported cp; 7108f984dfaSJohan Hedberg 7118f984dfaSJohan Hedberg memset(&cp, 0, sizeof(cp)); 7128f984dfaSJohan Hedberg 7138f984dfaSJohan Hedberg if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 7148f984dfaSJohan Hedberg cp.le = 1; 7158f984dfaSJohan Hedberg cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); 7168f984dfaSJohan Hedberg } 7178f984dfaSJohan Hedberg 7188f984dfaSJohan Hedberg if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE)) 71904124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 72004124681SGustavo F. Padovan &cp); 7218f984dfaSJohan Hedberg } 7228f984dfaSJohan Hedberg 723971e3a4bSAndre Guedes static void hci_cc_read_local_ext_features(struct hci_dev *hdev, 724971e3a4bSAndre Guedes struct sk_buff *skb) 725971e3a4bSAndre Guedes { 726971e3a4bSAndre Guedes struct hci_rp_read_local_ext_features *rp = (void *) skb->data; 727971e3a4bSAndre Guedes 728971e3a4bSAndre Guedes BT_DBG("%s status 0x%x", hdev->name, rp->status); 729971e3a4bSAndre Guedes 730971e3a4bSAndre Guedes if (rp->status) 7318f984dfaSJohan Hedberg goto done; 732971e3a4bSAndre Guedes 733b5b32b65SAndre Guedes switch (rp->page) { 734b5b32b65SAndre Guedes case 0: 735b5b32b65SAndre Guedes memcpy(hdev->features, rp->features, 8); 736b5b32b65SAndre Guedes break; 737b5b32b65SAndre Guedes case 1: 73859e29406SAndre Guedes memcpy(hdev->host_features, rp->features, 8); 739b5b32b65SAndre Guedes break; 740b5b32b65SAndre Guedes } 741971e3a4bSAndre Guedes 7428f984dfaSJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && hdev->features[4] & LMP_LE) 7438f984dfaSJohan Hedberg hci_set_le_support(hdev); 7448f984dfaSJohan Hedberg 7458f984dfaSJohan Hedberg done: 746971e3a4bSAndre Guedes hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status); 747971e3a4bSAndre Guedes } 748971e3a4bSAndre Guedes 7491e89cffbSAndrei Emeltchenko static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, 7501e89cffbSAndrei Emeltchenko struct sk_buff *skb) 7511e89cffbSAndrei Emeltchenko { 7521e89cffbSAndrei Emeltchenko struct hci_rp_read_flow_control_mode *rp = (void *) skb->data; 7531e89cffbSAndrei Emeltchenko 7541e89cffbSAndrei Emeltchenko BT_DBG("%s status 0x%x", hdev->name, rp->status); 7551e89cffbSAndrei Emeltchenko 7561e89cffbSAndrei Emeltchenko if (rp->status) 7571e89cffbSAndrei Emeltchenko return; 7581e89cffbSAndrei Emeltchenko 7591e89cffbSAndrei Emeltchenko hdev->flow_ctl_mode = rp->mode; 7601e89cffbSAndrei Emeltchenko 7611e89cffbSAndrei Emeltchenko hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status); 7621e89cffbSAndrei Emeltchenko } 7631e89cffbSAndrei Emeltchenko 764a9de9248SMarcel Holtmann static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) 765a9de9248SMarcel Holtmann { 766a9de9248SMarcel Holtmann struct hci_rp_read_buffer_size *rp = (void *) skb->data; 767a9de9248SMarcel Holtmann 768a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 769a9de9248SMarcel Holtmann 770a9de9248SMarcel Holtmann if (rp->status) 771a9de9248SMarcel Holtmann return; 772a9de9248SMarcel Holtmann 773a9de9248SMarcel Holtmann hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu); 774a9de9248SMarcel Holtmann hdev->sco_mtu = rp->sco_mtu; 775a9de9248SMarcel Holtmann hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt); 776a9de9248SMarcel Holtmann hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt); 777da1f5198SMarcel Holtmann 778da1f5198SMarcel Holtmann if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) { 779da1f5198SMarcel Holtmann hdev->sco_mtu = 64; 780da1f5198SMarcel Holtmann hdev->sco_pkts = 8; 781da1f5198SMarcel Holtmann } 782da1f5198SMarcel Holtmann 783da1f5198SMarcel Holtmann hdev->acl_cnt = hdev->acl_pkts; 784da1f5198SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 7851da177e4SLinus Torvalds 786a9de9248SMarcel Holtmann BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, 787a9de9248SMarcel Holtmann hdev->acl_mtu, hdev->acl_pkts, 788a9de9248SMarcel Holtmann hdev->sco_mtu, hdev->sco_pkts); 7891da177e4SLinus Torvalds } 7901da177e4SLinus Torvalds 791a9de9248SMarcel Holtmann static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) 792a9de9248SMarcel Holtmann { 793a9de9248SMarcel Holtmann struct hci_rp_read_bd_addr *rp = (void *) skb->data; 7941da177e4SLinus Torvalds 795a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, rp->status); 796a9de9248SMarcel Holtmann 797a9de9248SMarcel Holtmann if (!rp->status) 798a9de9248SMarcel Holtmann bacpy(&hdev->bdaddr, &rp->bdaddr); 799a9de9248SMarcel Holtmann 80023bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status); 80123bb5763SJohan Hedberg } 80223bb5763SJohan Hedberg 803350ee4cfSAndrei Emeltchenko static void hci_cc_read_data_block_size(struct hci_dev *hdev, 804350ee4cfSAndrei Emeltchenko struct sk_buff *skb) 805350ee4cfSAndrei Emeltchenko { 806350ee4cfSAndrei Emeltchenko struct hci_rp_read_data_block_size *rp = (void *) skb->data; 807350ee4cfSAndrei Emeltchenko 808350ee4cfSAndrei Emeltchenko BT_DBG("%s status 0x%x", hdev->name, rp->status); 809350ee4cfSAndrei Emeltchenko 810350ee4cfSAndrei Emeltchenko if (rp->status) 811350ee4cfSAndrei Emeltchenko return; 812350ee4cfSAndrei Emeltchenko 813350ee4cfSAndrei Emeltchenko hdev->block_mtu = __le16_to_cpu(rp->max_acl_len); 814350ee4cfSAndrei Emeltchenko hdev->block_len = __le16_to_cpu(rp->block_len); 815350ee4cfSAndrei Emeltchenko hdev->num_blocks = __le16_to_cpu(rp->num_blocks); 816350ee4cfSAndrei Emeltchenko 817350ee4cfSAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 818350ee4cfSAndrei Emeltchenko 819350ee4cfSAndrei Emeltchenko BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu, 820350ee4cfSAndrei Emeltchenko hdev->block_cnt, hdev->block_len); 821350ee4cfSAndrei Emeltchenko 822350ee4cfSAndrei Emeltchenko hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status); 823350ee4cfSAndrei Emeltchenko } 824350ee4cfSAndrei Emeltchenko 82523bb5763SJohan Hedberg static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb) 82623bb5763SJohan Hedberg { 82723bb5763SJohan Hedberg __u8 status = *((__u8 *) skb->data); 82823bb5763SJohan Hedberg 82923bb5763SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, status); 83023bb5763SJohan Hedberg 83123bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status); 8321da177e4SLinus Torvalds } 8331da177e4SLinus Torvalds 834928abaa7SAndrei Emeltchenko static void hci_cc_read_local_amp_info(struct hci_dev *hdev, 835928abaa7SAndrei Emeltchenko struct sk_buff *skb) 836928abaa7SAndrei Emeltchenko { 837928abaa7SAndrei Emeltchenko struct hci_rp_read_local_amp_info *rp = (void *) skb->data; 838928abaa7SAndrei Emeltchenko 839928abaa7SAndrei Emeltchenko BT_DBG("%s status 0x%x", hdev->name, rp->status); 840928abaa7SAndrei Emeltchenko 841928abaa7SAndrei Emeltchenko if (rp->status) 842928abaa7SAndrei Emeltchenko return; 843928abaa7SAndrei Emeltchenko 844928abaa7SAndrei Emeltchenko hdev->amp_status = rp->amp_status; 845928abaa7SAndrei Emeltchenko hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); 846928abaa7SAndrei Emeltchenko hdev->amp_max_bw = __le32_to_cpu(rp->max_bw); 847928abaa7SAndrei Emeltchenko hdev->amp_min_latency = __le32_to_cpu(rp->min_latency); 848928abaa7SAndrei Emeltchenko hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu); 849928abaa7SAndrei Emeltchenko hdev->amp_type = rp->amp_type; 850928abaa7SAndrei Emeltchenko hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap); 851928abaa7SAndrei Emeltchenko hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size); 852928abaa7SAndrei Emeltchenko hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to); 853928abaa7SAndrei Emeltchenko hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); 854928abaa7SAndrei Emeltchenko 855928abaa7SAndrei Emeltchenko hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status); 856928abaa7SAndrei Emeltchenko } 857928abaa7SAndrei Emeltchenko 858b0916ea0SJohan Hedberg static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, 859b0916ea0SJohan Hedberg struct sk_buff *skb) 860b0916ea0SJohan Hedberg { 861b0916ea0SJohan Hedberg __u8 status = *((__u8 *) skb->data); 862b0916ea0SJohan Hedberg 863b0916ea0SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, status); 864b0916ea0SJohan Hedberg 865b0916ea0SJohan Hedberg hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status); 866b0916ea0SJohan Hedberg } 867b0916ea0SJohan Hedberg 868d5859e22SJohan Hedberg static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb) 869d5859e22SJohan Hedberg { 870d5859e22SJohan Hedberg __u8 status = *((__u8 *) skb->data); 871d5859e22SJohan Hedberg 872d5859e22SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, status); 873d5859e22SJohan Hedberg 874d5859e22SJohan Hedberg hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status); 875d5859e22SJohan Hedberg } 876d5859e22SJohan Hedberg 877d5859e22SJohan Hedberg static void hci_cc_write_inquiry_mode(struct hci_dev *hdev, 878d5859e22SJohan Hedberg struct sk_buff *skb) 879d5859e22SJohan Hedberg { 880d5859e22SJohan Hedberg __u8 status = *((__u8 *) skb->data); 881d5859e22SJohan Hedberg 882d5859e22SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, status); 883d5859e22SJohan Hedberg 884d5859e22SJohan Hedberg hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status); 885d5859e22SJohan Hedberg } 886d5859e22SJohan Hedberg 887d5859e22SJohan Hedberg static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, 888d5859e22SJohan Hedberg struct sk_buff *skb) 889d5859e22SJohan Hedberg { 890d5859e22SJohan Hedberg __u8 status = *((__u8 *) skb->data); 891d5859e22SJohan Hedberg 892d5859e22SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, status); 893d5859e22SJohan Hedberg 894d5859e22SJohan Hedberg hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status); 895d5859e22SJohan Hedberg } 896d5859e22SJohan Hedberg 897d5859e22SJohan Hedberg static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb) 898d5859e22SJohan Hedberg { 899d5859e22SJohan Hedberg __u8 status = *((__u8 *) skb->data); 900d5859e22SJohan Hedberg 901d5859e22SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, status); 902d5859e22SJohan Hedberg 903d5859e22SJohan Hedberg hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status); 904d5859e22SJohan Hedberg } 905d5859e22SJohan Hedberg 906980e1a53SJohan Hedberg static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) 907980e1a53SJohan Hedberg { 908980e1a53SJohan Hedberg struct hci_rp_pin_code_reply *rp = (void *) skb->data; 909980e1a53SJohan Hedberg struct hci_cp_pin_code_reply *cp; 910980e1a53SJohan Hedberg struct hci_conn *conn; 911980e1a53SJohan Hedberg 912980e1a53SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, rp->status); 913980e1a53SJohan Hedberg 91456e5cb86SJohan Hedberg hci_dev_lock(hdev); 91556e5cb86SJohan Hedberg 916a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 917744cf19eSJohan Hedberg mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); 918980e1a53SJohan Hedberg 919980e1a53SJohan Hedberg if (rp->status != 0) 92056e5cb86SJohan Hedberg goto unlock; 921980e1a53SJohan Hedberg 922980e1a53SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); 923980e1a53SJohan Hedberg if (!cp) 92456e5cb86SJohan Hedberg goto unlock; 925980e1a53SJohan Hedberg 926980e1a53SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 927980e1a53SJohan Hedberg if (conn) 928980e1a53SJohan Hedberg conn->pin_length = cp->pin_len; 92956e5cb86SJohan Hedberg 93056e5cb86SJohan Hedberg unlock: 93156e5cb86SJohan Hedberg hci_dev_unlock(hdev); 932980e1a53SJohan Hedberg } 933980e1a53SJohan Hedberg 934980e1a53SJohan Hedberg static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) 935980e1a53SJohan Hedberg { 936980e1a53SJohan Hedberg struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data; 937980e1a53SJohan Hedberg 938980e1a53SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, rp->status); 939980e1a53SJohan Hedberg 94056e5cb86SJohan Hedberg hci_dev_lock(hdev); 94156e5cb86SJohan Hedberg 942a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 943744cf19eSJohan Hedberg mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, 944980e1a53SJohan Hedberg rp->status); 94556e5cb86SJohan Hedberg 94656e5cb86SJohan Hedberg hci_dev_unlock(hdev); 947980e1a53SJohan Hedberg } 94856e5cb86SJohan Hedberg 9496ed58ec5SVille Tervo static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, 9506ed58ec5SVille Tervo struct sk_buff *skb) 9516ed58ec5SVille Tervo { 9526ed58ec5SVille Tervo struct hci_rp_le_read_buffer_size *rp = (void *) skb->data; 9536ed58ec5SVille Tervo 9546ed58ec5SVille Tervo BT_DBG("%s status 0x%x", hdev->name, rp->status); 9556ed58ec5SVille Tervo 9566ed58ec5SVille Tervo if (rp->status) 9576ed58ec5SVille Tervo return; 9586ed58ec5SVille Tervo 9596ed58ec5SVille Tervo hdev->le_mtu = __le16_to_cpu(rp->le_mtu); 9606ed58ec5SVille Tervo hdev->le_pkts = rp->le_max_pkt; 9616ed58ec5SVille Tervo 9626ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 9636ed58ec5SVille Tervo 9646ed58ec5SVille Tervo BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts); 9656ed58ec5SVille Tervo 9666ed58ec5SVille Tervo hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status); 9676ed58ec5SVille Tervo } 968980e1a53SJohan Hedberg 969a5c29683SJohan Hedberg static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) 970a5c29683SJohan Hedberg { 971a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 972a5c29683SJohan Hedberg 973a5c29683SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, rp->status); 974a5c29683SJohan Hedberg 97556e5cb86SJohan Hedberg hci_dev_lock(hdev); 97656e5cb86SJohan Hedberg 977a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 97804124681SGustavo F. Padovan mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0, 97904124681SGustavo F. Padovan rp->status); 98056e5cb86SJohan Hedberg 98156e5cb86SJohan Hedberg hci_dev_unlock(hdev); 982a5c29683SJohan Hedberg } 983a5c29683SJohan Hedberg 984a5c29683SJohan Hedberg static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, 985a5c29683SJohan Hedberg struct sk_buff *skb) 986a5c29683SJohan Hedberg { 987a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 988a5c29683SJohan Hedberg 989a5c29683SJohan Hedberg BT_DBG("%s status 0x%x", hdev->name, rp->status); 990a5c29683SJohan Hedberg 99156e5cb86SJohan Hedberg hci_dev_lock(hdev); 99256e5cb86SJohan Hedberg 993a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 994744cf19eSJohan Hedberg mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, 99504124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 99656e5cb86SJohan Hedberg 99756e5cb86SJohan Hedberg hci_dev_unlock(hdev); 998a5c29683SJohan Hedberg } 999a5c29683SJohan Hedberg 10001143d458SBrian Gix static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb) 10011143d458SBrian Gix { 10021143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 10031143d458SBrian Gix 10041143d458SBrian Gix BT_DBG("%s status 0x%x", hdev->name, rp->status); 10051143d458SBrian Gix 10061143d458SBrian Gix hci_dev_lock(hdev); 10071143d458SBrian Gix 1008a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 1009272d90dfSJohan Hedberg mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 1010272d90dfSJohan Hedberg 0, rp->status); 10111143d458SBrian Gix 10121143d458SBrian Gix hci_dev_unlock(hdev); 10131143d458SBrian Gix } 10141143d458SBrian Gix 10151143d458SBrian Gix static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, 10161143d458SBrian Gix struct sk_buff *skb) 10171143d458SBrian Gix { 10181143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 10191143d458SBrian Gix 10201143d458SBrian Gix BT_DBG("%s status 0x%x", hdev->name, rp->status); 10211143d458SBrian Gix 10221143d458SBrian Gix hci_dev_lock(hdev); 10231143d458SBrian Gix 1024a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 10251143d458SBrian Gix mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr, 102604124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 10271143d458SBrian Gix 10281143d458SBrian Gix hci_dev_unlock(hdev); 10291143d458SBrian Gix } 10301143d458SBrian Gix 1031c35938b2SSzymon Janc static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, 1032c35938b2SSzymon Janc struct sk_buff *skb) 1033c35938b2SSzymon Janc { 1034c35938b2SSzymon Janc struct hci_rp_read_local_oob_data *rp = (void *) skb->data; 1035c35938b2SSzymon Janc 1036c35938b2SSzymon Janc BT_DBG("%s status 0x%x", hdev->name, rp->status); 1037c35938b2SSzymon Janc 103856e5cb86SJohan Hedberg hci_dev_lock(hdev); 1039744cf19eSJohan Hedberg mgmt_read_local_oob_data_reply_complete(hdev, rp->hash, 1040c35938b2SSzymon Janc rp->randomizer, rp->status); 104156e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1042c35938b2SSzymon Janc } 1043c35938b2SSzymon Janc 104407f7fa5dSAndre Guedes static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) 104507f7fa5dSAndre Guedes { 104607f7fa5dSAndre Guedes __u8 status = *((__u8 *) skb->data); 104707f7fa5dSAndre Guedes 104807f7fa5dSAndre Guedes BT_DBG("%s status 0x%x", hdev->name, status); 10497ba8b4beSAndre Guedes 10507ba8b4beSAndre Guedes hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status); 10513fd24153SAndre Guedes 10523fd24153SAndre Guedes if (status) { 10533fd24153SAndre Guedes hci_dev_lock(hdev); 10543fd24153SAndre Guedes mgmt_start_discovery_failed(hdev, status); 10553fd24153SAndre Guedes hci_dev_unlock(hdev); 10563fd24153SAndre Guedes return; 10573fd24153SAndre Guedes } 105807f7fa5dSAndre Guedes } 105907f7fa5dSAndre Guedes 1060eb9d91f5SAndre Guedes static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, 1061eb9d91f5SAndre Guedes struct sk_buff *skb) 1062eb9d91f5SAndre Guedes { 1063eb9d91f5SAndre Guedes struct hci_cp_le_set_scan_enable *cp; 1064eb9d91f5SAndre Guedes __u8 status = *((__u8 *) skb->data); 1065eb9d91f5SAndre Guedes 1066eb9d91f5SAndre Guedes BT_DBG("%s status 0x%x", hdev->name, status); 1067eb9d91f5SAndre Guedes 1068eb9d91f5SAndre Guedes cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE); 1069eb9d91f5SAndre Guedes if (!cp) 1070eb9d91f5SAndre Guedes return; 1071eb9d91f5SAndre Guedes 107268a8aea4SAndrei Emeltchenko switch (cp->enable) { 107368a8aea4SAndrei Emeltchenko case LE_SCANNING_ENABLED: 10747ba8b4beSAndre Guedes hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status); 10757ba8b4beSAndre Guedes 10763fd24153SAndre Guedes if (status) { 10773fd24153SAndre Guedes hci_dev_lock(hdev); 10783fd24153SAndre Guedes mgmt_start_discovery_failed(hdev, status); 10793fd24153SAndre Guedes hci_dev_unlock(hdev); 10807ba8b4beSAndre Guedes return; 10813fd24153SAndre Guedes } 10827ba8b4beSAndre Guedes 1083d23264a8SAndre Guedes set_bit(HCI_LE_SCAN, &hdev->dev_flags); 1084d23264a8SAndre Guedes 1085db323f2fSGustavo F. Padovan cancel_delayed_work_sync(&hdev->adv_work); 1086a8f13c8cSAndre Guedes 1087a8f13c8cSAndre Guedes hci_dev_lock(hdev); 1088eb9d91f5SAndre Guedes hci_adv_entries_clear(hdev); 1089343f935bSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_FINDING); 1090a8f13c8cSAndre Guedes hci_dev_unlock(hdev); 109168a8aea4SAndrei Emeltchenko break; 109268a8aea4SAndrei Emeltchenko 109368a8aea4SAndrei Emeltchenko case LE_SCANNING_DISABLED: 10947ba8b4beSAndre Guedes if (status) 10957ba8b4beSAndre Guedes return; 10967ba8b4beSAndre Guedes 1097d23264a8SAndre Guedes clear_bit(HCI_LE_SCAN, &hdev->dev_flags); 1098d23264a8SAndre Guedes 10995e0452c0SAndre Guedes schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT); 11005e0452c0SAndre Guedes 1101bc3dd33cSAndre Guedes if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED && 1102bc3dd33cSAndre Guedes hdev->discovery.state == DISCOVERY_FINDING) { 11035e0452c0SAndre Guedes mgmt_interleaved_discovery(hdev); 11045e0452c0SAndre Guedes } else { 1105c599008fSAndre Guedes hci_dev_lock(hdev); 1106c599008fSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 1107c599008fSAndre Guedes hci_dev_unlock(hdev); 11085e0452c0SAndre Guedes } 1109c599008fSAndre Guedes 111068a8aea4SAndrei Emeltchenko break; 111168a8aea4SAndrei Emeltchenko 111268a8aea4SAndrei Emeltchenko default: 111368a8aea4SAndrei Emeltchenko BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable); 111468a8aea4SAndrei Emeltchenko break; 111535815085SAndre Guedes } 1116eb9d91f5SAndre Guedes } 1117eb9d91f5SAndre Guedes 1118a7a595f6SVinicius Costa Gomes static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb) 1119a7a595f6SVinicius Costa Gomes { 1120a7a595f6SVinicius Costa Gomes struct hci_rp_le_ltk_reply *rp = (void *) skb->data; 1121a7a595f6SVinicius Costa Gomes 1122a7a595f6SVinicius Costa Gomes BT_DBG("%s status 0x%x", hdev->name, rp->status); 1123a7a595f6SVinicius Costa Gomes 1124a7a595f6SVinicius Costa Gomes if (rp->status) 1125a7a595f6SVinicius Costa Gomes return; 1126a7a595f6SVinicius Costa Gomes 1127a7a595f6SVinicius Costa Gomes hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status); 1128a7a595f6SVinicius Costa Gomes } 1129a7a595f6SVinicius Costa Gomes 1130a7a595f6SVinicius Costa Gomes static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) 1131a7a595f6SVinicius Costa Gomes { 1132a7a595f6SVinicius Costa Gomes struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data; 1133a7a595f6SVinicius Costa Gomes 1134a7a595f6SVinicius Costa Gomes BT_DBG("%s status 0x%x", hdev->name, rp->status); 1135a7a595f6SVinicius Costa Gomes 1136a7a595f6SVinicius Costa Gomes if (rp->status) 1137a7a595f6SVinicius Costa Gomes return; 1138a7a595f6SVinicius Costa Gomes 1139a7a595f6SVinicius Costa Gomes hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status); 1140a7a595f6SVinicius Costa Gomes } 1141a7a595f6SVinicius Costa Gomes 1142f9b49306SAndre Guedes static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev, 1143f9b49306SAndre Guedes struct sk_buff *skb) 1144f9b49306SAndre Guedes { 114506199cf8SJohan Hedberg struct hci_cp_write_le_host_supported *sent; 1146f9b49306SAndre Guedes __u8 status = *((__u8 *) skb->data); 1147f9b49306SAndre Guedes 1148f9b49306SAndre Guedes BT_DBG("%s status 0x%x", hdev->name, status); 1149f9b49306SAndre Guedes 115006199cf8SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED); 11518f984dfaSJohan Hedberg if (!sent) 1152f9b49306SAndre Guedes return; 1153f9b49306SAndre Guedes 11548f984dfaSJohan Hedberg if (!status) { 11558f984dfaSJohan Hedberg if (sent->le) 11568f984dfaSJohan Hedberg hdev->host_features[0] |= LMP_HOST_LE; 11578f984dfaSJohan Hedberg else 11588f984dfaSJohan Hedberg hdev->host_features[0] &= ~LMP_HOST_LE; 11598f984dfaSJohan Hedberg } 11608f984dfaSJohan Hedberg 11618f984dfaSJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags) && 11628f984dfaSJohan Hedberg !test_bit(HCI_INIT, &hdev->flags)) 11638f984dfaSJohan Hedberg mgmt_le_enable_complete(hdev, sent->le, status); 11648f984dfaSJohan Hedberg 11658f984dfaSJohan Hedberg hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status); 1166f9b49306SAndre Guedes } 1167f9b49306SAndre Guedes 1168a9de9248SMarcel Holtmann static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) 1169a9de9248SMarcel Holtmann { 1170a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1171a9de9248SMarcel Holtmann 1172a9de9248SMarcel Holtmann if (status) { 117323bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_INQUIRY, status); 1174a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 117556e5cb86SJohan Hedberg hci_dev_lock(hdev); 1176a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 11777a135109SAndre Guedes mgmt_start_discovery_failed(hdev, status); 117856e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1179314b2381SJohan Hedberg return; 1180314b2381SJohan Hedberg } 1181314b2381SJohan Hedberg 118289352e7dSAndre Guedes set_bit(HCI_INQUIRY, &hdev->flags); 118389352e7dSAndre Guedes 118456e5cb86SJohan Hedberg hci_dev_lock(hdev); 1185343f935bSAndre Guedes hci_discovery_set_state(hdev, DISCOVERY_FINDING); 118656e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1187a9de9248SMarcel Holtmann } 1188a9de9248SMarcel Holtmann 11891da177e4SLinus Torvalds static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) 11901da177e4SLinus Torvalds { 1191a9de9248SMarcel Holtmann struct hci_cp_create_conn *cp; 11921da177e4SLinus Torvalds struct hci_conn *conn; 11931da177e4SLinus Torvalds 1194a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1195a9de9248SMarcel Holtmann 1196a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN); 11971da177e4SLinus Torvalds if (!cp) 11981da177e4SLinus Torvalds return; 11991da177e4SLinus Torvalds 12001da177e4SLinus Torvalds hci_dev_lock(hdev); 12011da177e4SLinus Torvalds 12021da177e4SLinus Torvalds conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 12031da177e4SLinus Torvalds 1204a9de9248SMarcel Holtmann BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn); 12051da177e4SLinus Torvalds 12061da177e4SLinus Torvalds if (status) { 12071da177e4SLinus Torvalds if (conn && conn->state == BT_CONNECT) { 12084c67bc74SMarcel Holtmann if (status != 0x0c || conn->attempt > 2) { 12091da177e4SLinus Torvalds conn->state = BT_CLOSED; 12101da177e4SLinus Torvalds hci_proto_connect_cfm(conn, status); 12111da177e4SLinus Torvalds hci_conn_del(conn); 12124c67bc74SMarcel Holtmann } else 12134c67bc74SMarcel Holtmann conn->state = BT_CONNECT2; 12141da177e4SLinus Torvalds } 12151da177e4SLinus Torvalds } else { 12161da177e4SLinus Torvalds if (!conn) { 12171da177e4SLinus Torvalds conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr); 12181da177e4SLinus Torvalds if (conn) { 1219a0c808b3SJohan Hedberg conn->out = true; 12201da177e4SLinus Torvalds conn->link_mode |= HCI_LM_MASTER; 12211da177e4SLinus Torvalds } else 1222893ef971SGustavo F. Padovan BT_ERR("No memory for new connection"); 12231da177e4SLinus Torvalds } 12241da177e4SLinus Torvalds } 12251da177e4SLinus Torvalds 12261da177e4SLinus Torvalds hci_dev_unlock(hdev); 12271da177e4SLinus Torvalds } 12281da177e4SLinus Torvalds 1229a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status) 12301da177e4SLinus Torvalds { 1231a9de9248SMarcel Holtmann struct hci_cp_add_sco *cp; 12321da177e4SLinus Torvalds struct hci_conn *acl, *sco; 12331da177e4SLinus Torvalds __u16 handle; 12341da177e4SLinus Torvalds 1235b6a0dc82SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1236b6a0dc82SMarcel Holtmann 1237a9de9248SMarcel Holtmann if (!status) 1238a9de9248SMarcel Holtmann return; 1239a9de9248SMarcel Holtmann 1240a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO); 12411da177e4SLinus Torvalds if (!cp) 1242a9de9248SMarcel Holtmann return; 12431da177e4SLinus Torvalds 12441da177e4SLinus Torvalds handle = __le16_to_cpu(cp->handle); 12451da177e4SLinus Torvalds 1246a9de9248SMarcel Holtmann BT_DBG("%s handle %d", hdev->name, handle); 12471da177e4SLinus Torvalds 12481da177e4SLinus Torvalds hci_dev_lock(hdev); 12491da177e4SLinus Torvalds 12501da177e4SLinus Torvalds acl = hci_conn_hash_lookup_handle(hdev, handle); 12515a08ecceSAndrei Emeltchenko if (acl) { 12525a08ecceSAndrei Emeltchenko sco = acl->link; 12535a08ecceSAndrei Emeltchenko if (sco) { 12541da177e4SLinus Torvalds sco->state = BT_CLOSED; 12551da177e4SLinus Torvalds 12561da177e4SLinus Torvalds hci_proto_connect_cfm(sco, status); 12571da177e4SLinus Torvalds hci_conn_del(sco); 12581da177e4SLinus Torvalds } 12595a08ecceSAndrei Emeltchenko } 12601da177e4SLinus Torvalds 12611da177e4SLinus Torvalds hci_dev_unlock(hdev); 12621da177e4SLinus Torvalds } 12631da177e4SLinus Torvalds 1264f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status) 1265f8558555SMarcel Holtmann { 1266f8558555SMarcel Holtmann struct hci_cp_auth_requested *cp; 1267f8558555SMarcel Holtmann struct hci_conn *conn; 1268f8558555SMarcel Holtmann 1269f8558555SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1270f8558555SMarcel Holtmann 1271f8558555SMarcel Holtmann if (!status) 1272f8558555SMarcel Holtmann return; 1273f8558555SMarcel Holtmann 1274f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED); 1275f8558555SMarcel Holtmann if (!cp) 1276f8558555SMarcel Holtmann return; 1277f8558555SMarcel Holtmann 1278f8558555SMarcel Holtmann hci_dev_lock(hdev); 1279f8558555SMarcel Holtmann 1280f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1281f8558555SMarcel Holtmann if (conn) { 1282f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1283f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, status); 1284f8558555SMarcel Holtmann hci_conn_put(conn); 1285f8558555SMarcel Holtmann } 1286f8558555SMarcel Holtmann } 1287f8558555SMarcel Holtmann 1288f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1289f8558555SMarcel Holtmann } 1290f8558555SMarcel Holtmann 1291f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) 1292f8558555SMarcel Holtmann { 1293f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt *cp; 1294f8558555SMarcel Holtmann struct hci_conn *conn; 1295f8558555SMarcel Holtmann 1296f8558555SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1297f8558555SMarcel Holtmann 1298f8558555SMarcel Holtmann if (!status) 1299f8558555SMarcel Holtmann return; 1300f8558555SMarcel Holtmann 1301f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT); 1302f8558555SMarcel Holtmann if (!cp) 1303f8558555SMarcel Holtmann return; 1304f8558555SMarcel Holtmann 1305f8558555SMarcel Holtmann hci_dev_lock(hdev); 1306f8558555SMarcel Holtmann 1307f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1308f8558555SMarcel Holtmann if (conn) { 1309f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1310f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, status); 1311f8558555SMarcel Holtmann hci_conn_put(conn); 1312f8558555SMarcel Holtmann } 1313f8558555SMarcel Holtmann } 1314f8558555SMarcel Holtmann 1315f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1316f8558555SMarcel Holtmann } 1317f8558555SMarcel Holtmann 1318127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev, 1319392599b9SJohan Hedberg struct hci_conn *conn) 1320392599b9SJohan Hedberg { 1321392599b9SJohan Hedberg if (conn->state != BT_CONFIG || !conn->out) 1322392599b9SJohan Hedberg return 0; 1323392599b9SJohan Hedberg 1324765c2a96SJohan Hedberg if (conn->pending_sec_level == BT_SECURITY_SDP) 1325392599b9SJohan Hedberg return 0; 1326392599b9SJohan Hedberg 1327392599b9SJohan Hedberg /* Only request authentication for SSP connections or non-SSP 1328e9bf2bf0SVinicius Costa Gomes * devices with sec_level HIGH or if MITM protection is requested */ 1329aa64a8b5SJohan Hedberg if (!hci_conn_ssp_enabled(conn) && 1330e9bf2bf0SVinicius Costa Gomes conn->pending_sec_level != BT_SECURITY_HIGH && 1331e9bf2bf0SVinicius Costa Gomes !(conn->auth_type & 0x01)) 1332392599b9SJohan Hedberg return 0; 1333392599b9SJohan Hedberg 1334392599b9SJohan Hedberg return 1; 1335392599b9SJohan Hedberg } 1336392599b9SJohan Hedberg 133700abfe44SGustavo F. Padovan static inline int hci_resolve_name(struct hci_dev *hdev, 133800abfe44SGustavo F. Padovan struct inquiry_entry *e) 133930dc78e1SJohan Hedberg { 134030dc78e1SJohan Hedberg struct hci_cp_remote_name_req cp; 134130dc78e1SJohan Hedberg 134230dc78e1SJohan Hedberg memset(&cp, 0, sizeof(cp)); 134330dc78e1SJohan Hedberg 134430dc78e1SJohan Hedberg bacpy(&cp.bdaddr, &e->data.bdaddr); 134530dc78e1SJohan Hedberg cp.pscan_rep_mode = e->data.pscan_rep_mode; 134630dc78e1SJohan Hedberg cp.pscan_mode = e->data.pscan_mode; 134730dc78e1SJohan Hedberg cp.clock_offset = e->data.clock_offset; 134830dc78e1SJohan Hedberg 134930dc78e1SJohan Hedberg return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 135030dc78e1SJohan Hedberg } 135130dc78e1SJohan Hedberg 1352b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev) 135330dc78e1SJohan Hedberg { 135430dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 135530dc78e1SJohan Hedberg struct inquiry_entry *e; 135630dc78e1SJohan Hedberg 1357b644ba33SJohan Hedberg if (list_empty(&discov->resolve)) 1358b644ba33SJohan Hedberg return false; 1359b644ba33SJohan Hedberg 1360b644ba33SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 1361b644ba33SJohan Hedberg if (hci_resolve_name(hdev, e) == 0) { 1362b644ba33SJohan Hedberg e->name_state = NAME_PENDING; 1363b644ba33SJohan Hedberg return true; 1364b644ba33SJohan Hedberg } 1365b644ba33SJohan Hedberg 1366b644ba33SJohan Hedberg return false; 1367b644ba33SJohan Hedberg } 1368b644ba33SJohan Hedberg 1369b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, 1370b644ba33SJohan Hedberg bdaddr_t *bdaddr, u8 *name, u8 name_len) 1371b644ba33SJohan Hedberg { 1372b644ba33SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 1373b644ba33SJohan Hedberg struct inquiry_entry *e; 1374b644ba33SJohan Hedberg 1375b644ba33SJohan Hedberg if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 137604124681SGustavo F. Padovan mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name, 137704124681SGustavo F. Padovan name_len, conn->dev_class); 1378b644ba33SJohan Hedberg 1379b644ba33SJohan Hedberg if (discov->state == DISCOVERY_STOPPED) 1380b644ba33SJohan Hedberg return; 1381b644ba33SJohan Hedberg 138230dc78e1SJohan Hedberg if (discov->state == DISCOVERY_STOPPING) 138330dc78e1SJohan Hedberg goto discov_complete; 138430dc78e1SJohan Hedberg 138530dc78e1SJohan Hedberg if (discov->state != DISCOVERY_RESOLVING) 138630dc78e1SJohan Hedberg return; 138730dc78e1SJohan Hedberg 138830dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING); 138930dc78e1SJohan Hedberg if (e) { 139030dc78e1SJohan Hedberg e->name_state = NAME_KNOWN; 139130dc78e1SJohan Hedberg list_del(&e->list); 1392b644ba33SJohan Hedberg if (name) 1393b644ba33SJohan Hedberg mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, 1394b644ba33SJohan Hedberg e->data.rssi, name, name_len); 139530dc78e1SJohan Hedberg } 139630dc78e1SJohan Hedberg 1397b644ba33SJohan Hedberg if (hci_resolve_next_name(hdev)) 139830dc78e1SJohan Hedberg return; 139930dc78e1SJohan Hedberg 140030dc78e1SJohan Hedberg discov_complete: 140130dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 140230dc78e1SJohan Hedberg } 140330dc78e1SJohan Hedberg 1404a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) 14051da177e4SLinus Torvalds { 1406127178d2SJohan Hedberg struct hci_cp_remote_name_req *cp; 1407127178d2SJohan Hedberg struct hci_conn *conn; 1408127178d2SJohan Hedberg 1409a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1410127178d2SJohan Hedberg 1411127178d2SJohan Hedberg /* If successful wait for the name req complete event before 1412127178d2SJohan Hedberg * checking for the need to do authentication */ 1413127178d2SJohan Hedberg if (!status) 1414127178d2SJohan Hedberg return; 1415127178d2SJohan Hedberg 1416127178d2SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ); 1417127178d2SJohan Hedberg if (!cp) 1418127178d2SJohan Hedberg return; 1419127178d2SJohan Hedberg 1420127178d2SJohan Hedberg hci_dev_lock(hdev); 1421127178d2SJohan Hedberg 1422127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 1423b644ba33SJohan Hedberg 1424b644ba33SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 1425b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0); 1426b644ba33SJohan Hedberg 142779c6c70cSJohan Hedberg if (!conn) 142879c6c70cSJohan Hedberg goto unlock; 142979c6c70cSJohan Hedberg 143079c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 143179c6c70cSJohan Hedberg goto unlock; 143279c6c70cSJohan Hedberg 143351a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 1434127178d2SJohan Hedberg struct hci_cp_auth_requested cp; 1435127178d2SJohan Hedberg cp.handle = __cpu_to_le16(conn->handle); 1436127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); 1437127178d2SJohan Hedberg } 1438127178d2SJohan Hedberg 143979c6c70cSJohan Hedberg unlock: 1440127178d2SJohan Hedberg hci_dev_unlock(hdev); 1441a9de9248SMarcel Holtmann } 14421da177e4SLinus Torvalds 1443769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) 1444769be974SMarcel Holtmann { 1445769be974SMarcel Holtmann struct hci_cp_read_remote_features *cp; 1446769be974SMarcel Holtmann struct hci_conn *conn; 1447769be974SMarcel Holtmann 1448769be974SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1449769be974SMarcel Holtmann 1450769be974SMarcel Holtmann if (!status) 1451769be974SMarcel Holtmann return; 1452769be974SMarcel Holtmann 1453769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES); 1454769be974SMarcel Holtmann if (!cp) 1455769be974SMarcel Holtmann return; 1456769be974SMarcel Holtmann 1457769be974SMarcel Holtmann hci_dev_lock(hdev); 1458769be974SMarcel Holtmann 1459769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1460769be974SMarcel Holtmann if (conn) { 1461769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1462769be974SMarcel Holtmann hci_proto_connect_cfm(conn, status); 1463769be974SMarcel Holtmann hci_conn_put(conn); 1464769be974SMarcel Holtmann } 1465769be974SMarcel Holtmann } 1466769be974SMarcel Holtmann 1467769be974SMarcel Holtmann hci_dev_unlock(hdev); 1468769be974SMarcel Holtmann } 1469769be974SMarcel Holtmann 1470769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status) 1471769be974SMarcel Holtmann { 1472769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features *cp; 1473769be974SMarcel Holtmann struct hci_conn *conn; 1474769be974SMarcel Holtmann 1475769be974SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1476769be974SMarcel Holtmann 1477769be974SMarcel Holtmann if (!status) 1478769be974SMarcel Holtmann return; 1479769be974SMarcel Holtmann 1480769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES); 1481769be974SMarcel Holtmann if (!cp) 1482769be974SMarcel Holtmann return; 1483769be974SMarcel Holtmann 1484769be974SMarcel Holtmann hci_dev_lock(hdev); 1485769be974SMarcel Holtmann 1486769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1487769be974SMarcel Holtmann if (conn) { 1488769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1489769be974SMarcel Holtmann hci_proto_connect_cfm(conn, status); 1490769be974SMarcel Holtmann hci_conn_put(conn); 1491769be974SMarcel Holtmann } 1492769be974SMarcel Holtmann } 1493769be974SMarcel Holtmann 1494769be974SMarcel Holtmann hci_dev_unlock(hdev); 1495769be974SMarcel Holtmann } 1496769be974SMarcel Holtmann 1497a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) 1498a9de9248SMarcel Holtmann { 1499b6a0dc82SMarcel Holtmann struct hci_cp_setup_sync_conn *cp; 1500b6a0dc82SMarcel Holtmann struct hci_conn *acl, *sco; 1501b6a0dc82SMarcel Holtmann __u16 handle; 1502b6a0dc82SMarcel Holtmann 1503a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1504b6a0dc82SMarcel Holtmann 1505b6a0dc82SMarcel Holtmann if (!status) 1506b6a0dc82SMarcel Holtmann return; 1507b6a0dc82SMarcel Holtmann 1508b6a0dc82SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN); 1509b6a0dc82SMarcel Holtmann if (!cp) 1510b6a0dc82SMarcel Holtmann return; 1511b6a0dc82SMarcel Holtmann 1512b6a0dc82SMarcel Holtmann handle = __le16_to_cpu(cp->handle); 1513b6a0dc82SMarcel Holtmann 1514b6a0dc82SMarcel Holtmann BT_DBG("%s handle %d", hdev->name, handle); 1515b6a0dc82SMarcel Holtmann 1516b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 1517b6a0dc82SMarcel Holtmann 1518b6a0dc82SMarcel Holtmann acl = hci_conn_hash_lookup_handle(hdev, handle); 15195a08ecceSAndrei Emeltchenko if (acl) { 15205a08ecceSAndrei Emeltchenko sco = acl->link; 15215a08ecceSAndrei Emeltchenko if (sco) { 1522b6a0dc82SMarcel Holtmann sco->state = BT_CLOSED; 1523b6a0dc82SMarcel Holtmann 1524b6a0dc82SMarcel Holtmann hci_proto_connect_cfm(sco, status); 1525b6a0dc82SMarcel Holtmann hci_conn_del(sco); 1526b6a0dc82SMarcel Holtmann } 15275a08ecceSAndrei Emeltchenko } 1528b6a0dc82SMarcel Holtmann 1529b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 1530a9de9248SMarcel Holtmann } 1531a9de9248SMarcel Holtmann 1532a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) 1533a9de9248SMarcel Holtmann { 1534a9de9248SMarcel Holtmann struct hci_cp_sniff_mode *cp; 153504837f64SMarcel Holtmann struct hci_conn *conn; 153604837f64SMarcel Holtmann 1537a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1538a9de9248SMarcel Holtmann 1539a9de9248SMarcel Holtmann if (!status) 1540a9de9248SMarcel Holtmann return; 1541a9de9248SMarcel Holtmann 1542a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE); 154304837f64SMarcel Holtmann if (!cp) 1544a9de9248SMarcel Holtmann return; 154504837f64SMarcel Holtmann 154604837f64SMarcel Holtmann hci_dev_lock(hdev); 154704837f64SMarcel Holtmann 154804837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1549e73439d8SMarcel Holtmann if (conn) { 155051a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 155104837f64SMarcel Holtmann 155251a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 1553e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 1554e73439d8SMarcel Holtmann } 1555e73439d8SMarcel Holtmann 155604837f64SMarcel Holtmann hci_dev_unlock(hdev); 155704837f64SMarcel Holtmann } 155804837f64SMarcel Holtmann 1559a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) 1560a9de9248SMarcel Holtmann { 1561a9de9248SMarcel Holtmann struct hci_cp_exit_sniff_mode *cp; 156204837f64SMarcel Holtmann struct hci_conn *conn; 156304837f64SMarcel Holtmann 1564a9de9248SMarcel Holtmann BT_DBG("%s status 0x%x", hdev->name, status); 1565a9de9248SMarcel Holtmann 1566a9de9248SMarcel Holtmann if (!status) 1567a9de9248SMarcel Holtmann return; 1568a9de9248SMarcel Holtmann 1569a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE); 157004837f64SMarcel Holtmann if (!cp) 1571a9de9248SMarcel Holtmann return; 157204837f64SMarcel Holtmann 157304837f64SMarcel Holtmann hci_dev_lock(hdev); 157404837f64SMarcel Holtmann 157504837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1576e73439d8SMarcel Holtmann if (conn) { 157751a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 157804837f64SMarcel Holtmann 157951a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 1580e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 1581e73439d8SMarcel Holtmann } 1582e73439d8SMarcel Holtmann 158304837f64SMarcel Holtmann hci_dev_unlock(hdev); 158404837f64SMarcel Holtmann } 158504837f64SMarcel Holtmann 158688c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) 158788c3df13SJohan Hedberg { 158888c3df13SJohan Hedberg struct hci_cp_disconnect *cp; 158988c3df13SJohan Hedberg struct hci_conn *conn; 159088c3df13SJohan Hedberg 159188c3df13SJohan Hedberg if (!status) 159288c3df13SJohan Hedberg return; 159388c3df13SJohan Hedberg 159488c3df13SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT); 159588c3df13SJohan Hedberg if (!cp) 159688c3df13SJohan Hedberg return; 159788c3df13SJohan Hedberg 159888c3df13SJohan Hedberg hci_dev_lock(hdev); 159988c3df13SJohan Hedberg 160088c3df13SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 160188c3df13SJohan Hedberg if (conn) 160288c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 160388c3df13SJohan Hedberg conn->dst_type, status); 160488c3df13SJohan Hedberg 160588c3df13SJohan Hedberg hci_dev_unlock(hdev); 160688c3df13SJohan Hedberg } 160788c3df13SJohan Hedberg 1608fcd89c09SVille Tervo static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) 1609fcd89c09SVille Tervo { 1610fcd89c09SVille Tervo struct hci_cp_le_create_conn *cp; 1611fcd89c09SVille Tervo struct hci_conn *conn; 1612fcd89c09SVille Tervo 1613fcd89c09SVille Tervo BT_DBG("%s status 0x%x", hdev->name, status); 1614fcd89c09SVille Tervo 1615fcd89c09SVille Tervo cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN); 1616fcd89c09SVille Tervo if (!cp) 1617fcd89c09SVille Tervo return; 1618fcd89c09SVille Tervo 1619fcd89c09SVille Tervo hci_dev_lock(hdev); 1620fcd89c09SVille Tervo 1621fcd89c09SVille Tervo conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr); 1622fcd89c09SVille Tervo 1623fcd89c09SVille Tervo BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr), 1624fcd89c09SVille Tervo conn); 1625fcd89c09SVille Tervo 1626fcd89c09SVille Tervo if (status) { 1627fcd89c09SVille Tervo if (conn && conn->state == BT_CONNECT) { 1628fcd89c09SVille Tervo conn->state = BT_CLOSED; 1629fcd89c09SVille Tervo hci_proto_connect_cfm(conn, status); 1630fcd89c09SVille Tervo hci_conn_del(conn); 1631fcd89c09SVille Tervo } 1632fcd89c09SVille Tervo } else { 1633fcd89c09SVille Tervo if (!conn) { 1634fcd89c09SVille Tervo conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr); 163529b7988aSAndre Guedes if (conn) { 163629b7988aSAndre Guedes conn->dst_type = cp->peer_addr_type; 1637a0c808b3SJohan Hedberg conn->out = true; 163829b7988aSAndre Guedes } else { 1639fcd89c09SVille Tervo BT_ERR("No memory for new connection"); 1640fcd89c09SVille Tervo } 1641fcd89c09SVille Tervo } 164229b7988aSAndre Guedes } 1643fcd89c09SVille Tervo 1644fcd89c09SVille Tervo hci_dev_unlock(hdev); 1645fcd89c09SVille Tervo } 1646fcd89c09SVille Tervo 1647a7a595f6SVinicius Costa Gomes static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) 1648a7a595f6SVinicius Costa Gomes { 1649a7a595f6SVinicius Costa Gomes BT_DBG("%s status 0x%x", hdev->name, status); 1650a7a595f6SVinicius Costa Gomes } 1651a7a595f6SVinicius Costa Gomes 16521da177e4SLinus Torvalds static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 16531da177e4SLinus Torvalds { 16541da177e4SLinus Torvalds __u8 status = *((__u8 *) skb->data); 165530dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 165630dc78e1SJohan Hedberg struct inquiry_entry *e; 16571da177e4SLinus Torvalds 16581da177e4SLinus Torvalds BT_DBG("%s status %d", hdev->name, status); 16591da177e4SLinus Torvalds 166023bb5763SJohan Hedberg hci_req_complete(hdev, HCI_OP_INQUIRY, status); 16616bd57416SMarcel Holtmann 1662a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 166389352e7dSAndre Guedes 166489352e7dSAndre Guedes if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) 166589352e7dSAndre Guedes return; 166689352e7dSAndre Guedes 1667a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 166830dc78e1SJohan Hedberg return; 166930dc78e1SJohan Hedberg 167056e5cb86SJohan Hedberg hci_dev_lock(hdev); 167130dc78e1SJohan Hedberg 1672343f935bSAndre Guedes if (discov->state != DISCOVERY_FINDING) 167330dc78e1SJohan Hedberg goto unlock; 167430dc78e1SJohan Hedberg 167530dc78e1SJohan Hedberg if (list_empty(&discov->resolve)) { 1676ff9ef578SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 167730dc78e1SJohan Hedberg goto unlock; 167830dc78e1SJohan Hedberg } 167930dc78e1SJohan Hedberg 168030dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 168130dc78e1SJohan Hedberg if (e && hci_resolve_name(hdev, e) == 0) { 168230dc78e1SJohan Hedberg e->name_state = NAME_PENDING; 168330dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_RESOLVING); 168430dc78e1SJohan Hedberg } else { 168530dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 168630dc78e1SJohan Hedberg } 168730dc78e1SJohan Hedberg 168830dc78e1SJohan Hedberg unlock: 168956e5cb86SJohan Hedberg hci_dev_unlock(hdev); 16901da177e4SLinus Torvalds } 16911da177e4SLinus Torvalds 16921da177e4SLinus Torvalds static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) 16931da177e4SLinus Torvalds { 169445bb4bf0SMarcel Holtmann struct inquiry_data data; 1695a9de9248SMarcel Holtmann struct inquiry_info *info = (void *) (skb->data + 1); 16961da177e4SLinus Torvalds int num_rsp = *((__u8 *) skb->data); 16971da177e4SLinus Torvalds 16981da177e4SLinus Torvalds BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 16991da177e4SLinus Torvalds 170045bb4bf0SMarcel Holtmann if (!num_rsp) 170145bb4bf0SMarcel Holtmann return; 170245bb4bf0SMarcel Holtmann 17031da177e4SLinus Torvalds hci_dev_lock(hdev); 170445bb4bf0SMarcel Holtmann 1705e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 1706388fc8faSJohan Hedberg bool name_known, ssp; 17073175405bSJohan Hedberg 17081da177e4SLinus Torvalds bacpy(&data.bdaddr, &info->bdaddr); 17091da177e4SLinus Torvalds data.pscan_rep_mode = info->pscan_rep_mode; 17101da177e4SLinus Torvalds data.pscan_period_mode = info->pscan_period_mode; 17111da177e4SLinus Torvalds data.pscan_mode = info->pscan_mode; 17121da177e4SLinus Torvalds memcpy(data.dev_class, info->dev_class, 3); 17131da177e4SLinus Torvalds data.clock_offset = info->clock_offset; 17141da177e4SLinus Torvalds data.rssi = 0x00; 171541a96212SMarcel Holtmann data.ssp_mode = 0x00; 17163175405bSJohan Hedberg 1717388fc8faSJohan Hedberg name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp); 171848264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 171904124681SGustavo F. Padovan info->dev_class, 0, !name_known, ssp, NULL, 172004124681SGustavo F. Padovan 0); 17211da177e4SLinus Torvalds } 172245bb4bf0SMarcel Holtmann 17231da177e4SLinus Torvalds hci_dev_unlock(hdev); 17241da177e4SLinus Torvalds } 17251da177e4SLinus Torvalds 1726a9de9248SMarcel Holtmann static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 17271da177e4SLinus Torvalds { 1728a9de9248SMarcel Holtmann struct hci_ev_conn_complete *ev = (void *) skb->data; 1729a9de9248SMarcel Holtmann struct hci_conn *conn; 17301da177e4SLinus Torvalds 1731a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 173245bb4bf0SMarcel Holtmann 17331da177e4SLinus Torvalds hci_dev_lock(hdev); 173445bb4bf0SMarcel Holtmann 1735a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 17369499237aSMarcel Holtmann if (!conn) { 17379499237aSMarcel Holtmann if (ev->link_type != SCO_LINK) 17389499237aSMarcel Holtmann goto unlock; 17399499237aSMarcel Holtmann 17409499237aSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 1741a9de9248SMarcel Holtmann if (!conn) 1742a9de9248SMarcel Holtmann goto unlock; 174345bb4bf0SMarcel Holtmann 17449499237aSMarcel Holtmann conn->type = SCO_LINK; 17459499237aSMarcel Holtmann } 17469499237aSMarcel Holtmann 1747a9de9248SMarcel Holtmann if (!ev->status) { 1748a9de9248SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 1749769be974SMarcel Holtmann 1750769be974SMarcel Holtmann if (conn->type == ACL_LINK) { 1751769be974SMarcel Holtmann conn->state = BT_CONFIG; 1752769be974SMarcel Holtmann hci_conn_hold(conn); 1753052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 1754769be974SMarcel Holtmann } else 1755a9de9248SMarcel Holtmann conn->state = BT_CONNECTED; 1756a9de9248SMarcel Holtmann 17579eba32b8SMarcel Holtmann hci_conn_hold_device(conn); 17587d0db0a3SMarcel Holtmann hci_conn_add_sysfs(conn); 17597d0db0a3SMarcel Holtmann 1760a9de9248SMarcel Holtmann if (test_bit(HCI_AUTH, &hdev->flags)) 1761a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_AUTH; 1762a9de9248SMarcel Holtmann 1763a9de9248SMarcel Holtmann if (test_bit(HCI_ENCRYPT, &hdev->flags)) 1764a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_ENCRYPT; 1765a9de9248SMarcel Holtmann 1766a9de9248SMarcel Holtmann /* Get remote features */ 1767a9de9248SMarcel Holtmann if (conn->type == ACL_LINK) { 1768a9de9248SMarcel Holtmann struct hci_cp_read_remote_features cp; 1769a9de9248SMarcel Holtmann cp.handle = ev->handle; 1770769be974SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, 1771769be974SMarcel Holtmann sizeof(cp), &cp); 177245bb4bf0SMarcel Holtmann } 1773a9de9248SMarcel Holtmann 1774a9de9248SMarcel Holtmann /* Set packet type for incoming connection */ 1775d095c1ebSAndrei Emeltchenko if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) { 1776a9de9248SMarcel Holtmann struct hci_cp_change_conn_ptype cp; 1777a9de9248SMarcel Holtmann cp.handle = ev->handle; 1778a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 177904124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), 178004124681SGustavo F. Padovan &cp); 1781a9de9248SMarcel Holtmann } 178217d5c04cSJohan Hedberg } else { 1783a9de9248SMarcel Holtmann conn->state = BT_CLOSED; 178417d5c04cSJohan Hedberg if (conn->type == ACL_LINK) 1785744cf19eSJohan Hedberg mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, 178648264f06SJohan Hedberg conn->dst_type, ev->status); 178717d5c04cSJohan Hedberg } 178845bb4bf0SMarcel Holtmann 1789e73439d8SMarcel Holtmann if (conn->type == ACL_LINK) 1790e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 179145bb4bf0SMarcel Holtmann 1792769be974SMarcel Holtmann if (ev->status) { 1793a9de9248SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 1794a9de9248SMarcel Holtmann hci_conn_del(conn); 1795c89b6e6bSMarcel Holtmann } else if (ev->link_type != ACL_LINK) 1796c89b6e6bSMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 1797a9de9248SMarcel Holtmann 1798a9de9248SMarcel Holtmann unlock: 17991da177e4SLinus Torvalds hci_dev_unlock(hdev); 1800a9de9248SMarcel Holtmann 1801a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 18021da177e4SLinus Torvalds } 18031da177e4SLinus Torvalds 18041da177e4SLinus Torvalds static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 18051da177e4SLinus Torvalds { 1806a9de9248SMarcel Holtmann struct hci_ev_conn_request *ev = (void *) skb->data; 18071da177e4SLinus Torvalds int mask = hdev->link_mode; 18081da177e4SLinus Torvalds 1809a9de9248SMarcel Holtmann BT_DBG("%s bdaddr %s type 0x%x", hdev->name, 18101da177e4SLinus Torvalds batostr(&ev->bdaddr), ev->link_type); 18111da177e4SLinus Torvalds 18121da177e4SLinus Torvalds mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); 18131da177e4SLinus Torvalds 1814138d22efSSzymon Janc if ((mask & HCI_LM_ACCEPT) && 1815138d22efSSzymon Janc !hci_blacklist_lookup(hdev, &ev->bdaddr)) { 18161da177e4SLinus Torvalds /* Connection accepted */ 1817c7bdd502SMarcel Holtmann struct inquiry_entry *ie; 18181da177e4SLinus Torvalds struct hci_conn *conn; 18191da177e4SLinus Torvalds 18201da177e4SLinus Torvalds hci_dev_lock(hdev); 1821b6a0dc82SMarcel Holtmann 1822cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 1823cc11b9c1SAndrei Emeltchenko if (ie) 1824c7bdd502SMarcel Holtmann memcpy(ie->data.dev_class, ev->dev_class, 3); 1825c7bdd502SMarcel Holtmann 18261da177e4SLinus Torvalds conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 18271da177e4SLinus Torvalds if (!conn) { 1828cc11b9c1SAndrei Emeltchenko conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr); 1829cc11b9c1SAndrei Emeltchenko if (!conn) { 1830893ef971SGustavo F. Padovan BT_ERR("No memory for new connection"); 18311da177e4SLinus Torvalds hci_dev_unlock(hdev); 18321da177e4SLinus Torvalds return; 18331da177e4SLinus Torvalds } 18341da177e4SLinus Torvalds } 1835b6a0dc82SMarcel Holtmann 18361da177e4SLinus Torvalds memcpy(conn->dev_class, ev->dev_class, 3); 18371da177e4SLinus Torvalds conn->state = BT_CONNECT; 1838b6a0dc82SMarcel Holtmann 18391da177e4SLinus Torvalds hci_dev_unlock(hdev); 18401da177e4SLinus Torvalds 1841b6a0dc82SMarcel Holtmann if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) { 1842b6a0dc82SMarcel Holtmann struct hci_cp_accept_conn_req cp; 1843b6a0dc82SMarcel Holtmann 18441da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 18451da177e4SLinus Torvalds 18461da177e4SLinus Torvalds if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) 18471da177e4SLinus Torvalds cp.role = 0x00; /* Become master */ 18481da177e4SLinus Torvalds else 18491da177e4SLinus Torvalds cp.role = 0x01; /* Remain slave */ 18501da177e4SLinus Torvalds 185104124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), 185204124681SGustavo F. Padovan &cp); 1853b6a0dc82SMarcel Holtmann } else { 1854b6a0dc82SMarcel Holtmann struct hci_cp_accept_sync_conn_req cp; 1855b6a0dc82SMarcel Holtmann 1856b6a0dc82SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 1857a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 1858b6a0dc82SMarcel Holtmann 1859b6a0dc82SMarcel Holtmann cp.tx_bandwidth = cpu_to_le32(0x00001f40); 1860b6a0dc82SMarcel Holtmann cp.rx_bandwidth = cpu_to_le32(0x00001f40); 1861b6a0dc82SMarcel Holtmann cp.max_latency = cpu_to_le16(0xffff); 1862b6a0dc82SMarcel Holtmann cp.content_format = cpu_to_le16(hdev->voice_setting); 1863b6a0dc82SMarcel Holtmann cp.retrans_effort = 0xff; 1864b6a0dc82SMarcel Holtmann 1865b6a0dc82SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, 1866b6a0dc82SMarcel Holtmann sizeof(cp), &cp); 1867b6a0dc82SMarcel Holtmann } 18681da177e4SLinus Torvalds } else { 18691da177e4SLinus Torvalds /* Connection rejected */ 18701da177e4SLinus Torvalds struct hci_cp_reject_conn_req cp; 18711da177e4SLinus Torvalds 18721da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 18739f5a0d7bSAndrei Emeltchenko cp.reason = HCI_ERROR_REJ_BAD_ADDR; 1874a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); 18751da177e4SLinus Torvalds } 18761da177e4SLinus Torvalds } 18771da177e4SLinus Torvalds 18781da177e4SLinus Torvalds static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 18791da177e4SLinus Torvalds { 1880a9de9248SMarcel Holtmann struct hci_ev_disconn_complete *ev = (void *) skb->data; 188104837f64SMarcel Holtmann struct hci_conn *conn; 18821da177e4SLinus Torvalds 18831da177e4SLinus Torvalds BT_DBG("%s status %d", hdev->name, ev->status); 18841da177e4SLinus Torvalds 18851da177e4SLinus Torvalds hci_dev_lock(hdev); 18861da177e4SLinus Torvalds 188704837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 1888f7520543SJohan Hedberg if (!conn) 1889f7520543SJohan Hedberg goto unlock; 1890f7520543SJohan Hedberg 189137d9ef76SJohan Hedberg if (ev->status == 0) 18921da177e4SLinus Torvalds conn->state = BT_CLOSED; 18937d0db0a3SMarcel Holtmann 1894b644ba33SJohan Hedberg if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) && 1895b644ba33SJohan Hedberg (conn->type == ACL_LINK || conn->type == LE_LINK)) { 189637d9ef76SJohan Hedberg if (ev->status != 0) 189788c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 189888c3df13SJohan Hedberg conn->dst_type, ev->status); 189937d9ef76SJohan Hedberg else 1900afc747a6SJohan Hedberg mgmt_device_disconnected(hdev, &conn->dst, conn->type, 190148264f06SJohan Hedberg conn->dst_type); 190237d9ef76SJohan Hedberg } 1903f7520543SJohan Hedberg 190437d9ef76SJohan Hedberg if (ev->status == 0) { 19056ec5bcadSVishal Agarwal if (conn->type == ACL_LINK && conn->flush_key) 19066ec5bcadSVishal Agarwal hci_remove_link_key(hdev, &conn->dst); 19072950f21aSMarcel Holtmann hci_proto_disconn_cfm(conn, ev->reason); 19081da177e4SLinus Torvalds hci_conn_del(conn); 190937d9ef76SJohan Hedberg } 19101da177e4SLinus Torvalds 1911f7520543SJohan Hedberg unlock: 19121da177e4SLinus Torvalds hci_dev_unlock(hdev); 19131da177e4SLinus Torvalds } 19141da177e4SLinus Torvalds 1915a9de9248SMarcel Holtmann static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1916a9de9248SMarcel Holtmann { 1917a9de9248SMarcel Holtmann struct hci_ev_auth_complete *ev = (void *) skb->data; 1918a9de9248SMarcel Holtmann struct hci_conn *conn; 1919a9de9248SMarcel Holtmann 1920a9de9248SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 1921a9de9248SMarcel Holtmann 1922a9de9248SMarcel Holtmann hci_dev_lock(hdev); 1923a9de9248SMarcel Holtmann 1924a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 1925d7556e20SWaldemar Rymarkiewicz if (!conn) 1926d7556e20SWaldemar Rymarkiewicz goto unlock; 1927d7556e20SWaldemar Rymarkiewicz 1928765c2a96SJohan Hedberg if (!ev->status) { 1929aa64a8b5SJohan Hedberg if (!hci_conn_ssp_enabled(conn) && 193051a8efd7SJohan Hedberg test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { 1931d7556e20SWaldemar Rymarkiewicz BT_INFO("re-auth of legacy device is not possible."); 193219f8def0SWaldemar Rymarkiewicz } else { 1933a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_AUTH; 1934765c2a96SJohan Hedberg conn->sec_level = conn->pending_sec_level; 193519f8def0SWaldemar Rymarkiewicz } 19362a611692SJohan Hedberg } else { 1937bab73cb6SJohan Hedberg mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, 1938bab73cb6SJohan Hedberg ev->status); 19392a611692SJohan Hedberg } 1940a9de9248SMarcel Holtmann 194151a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 194251a8efd7SJohan Hedberg clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags); 1943a9de9248SMarcel Holtmann 1944f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1945aa64a8b5SJohan Hedberg if (!ev->status && hci_conn_ssp_enabled(conn)) { 1946f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 1947f8558555SMarcel Holtmann cp.handle = ev->handle; 1948f8558555SMarcel Holtmann cp.encrypt = 0x01; 1949d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 1950d7556e20SWaldemar Rymarkiewicz &cp); 1951f8558555SMarcel Holtmann } else { 1952f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 1953f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 1954f8558555SMarcel Holtmann hci_conn_put(conn); 1955f8558555SMarcel Holtmann } 1956052b30b0SMarcel Holtmann } else { 1957a9de9248SMarcel Holtmann hci_auth_cfm(conn, ev->status); 1958a9de9248SMarcel Holtmann 1959052b30b0SMarcel Holtmann hci_conn_hold(conn); 1960052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 1961052b30b0SMarcel Holtmann hci_conn_put(conn); 1962052b30b0SMarcel Holtmann } 1963052b30b0SMarcel Holtmann 196451a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { 1965a9de9248SMarcel Holtmann if (!ev->status) { 1966a9de9248SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 1967f8558555SMarcel Holtmann cp.handle = ev->handle; 1968f8558555SMarcel Holtmann cp.encrypt = 0x01; 1969d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 1970d7556e20SWaldemar Rymarkiewicz &cp); 1971a9de9248SMarcel Holtmann } else { 197251a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 1973a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, 0x00); 1974a9de9248SMarcel Holtmann } 1975a9de9248SMarcel Holtmann } 1976a9de9248SMarcel Holtmann 1977d7556e20SWaldemar Rymarkiewicz unlock: 1978a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 1979a9de9248SMarcel Holtmann } 1980a9de9248SMarcel Holtmann 1981a9de9248SMarcel Holtmann static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) 1982a9de9248SMarcel Holtmann { 1983127178d2SJohan Hedberg struct hci_ev_remote_name *ev = (void *) skb->data; 1984127178d2SJohan Hedberg struct hci_conn *conn; 1985127178d2SJohan Hedberg 1986a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 1987a9de9248SMarcel Holtmann 1988a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 1989127178d2SJohan Hedberg 1990127178d2SJohan Hedberg hci_dev_lock(hdev); 1991127178d2SJohan Hedberg 1992127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 1993b644ba33SJohan Hedberg 1994b644ba33SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1995b644ba33SJohan Hedberg goto check_auth; 1996b644ba33SJohan Hedberg 1997b644ba33SJohan Hedberg if (ev->status == 0) 1998b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name, 1999b644ba33SJohan Hedberg strnlen(ev->name, HCI_MAX_NAME_LENGTH)); 2000b644ba33SJohan Hedberg else 2001b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0); 2002b644ba33SJohan Hedberg 2003b644ba33SJohan Hedberg check_auth: 200479c6c70cSJohan Hedberg if (!conn) 200579c6c70cSJohan Hedberg goto unlock; 200679c6c70cSJohan Hedberg 200779c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 200879c6c70cSJohan Hedberg goto unlock; 200979c6c70cSJohan Hedberg 201051a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 2011127178d2SJohan Hedberg struct hci_cp_auth_requested cp; 2012127178d2SJohan Hedberg cp.handle = __cpu_to_le16(conn->handle); 2013127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); 2014127178d2SJohan Hedberg } 2015127178d2SJohan Hedberg 201679c6c70cSJohan Hedberg unlock: 2017127178d2SJohan Hedberg hci_dev_unlock(hdev); 2018a9de9248SMarcel Holtmann } 2019a9de9248SMarcel Holtmann 2020a9de9248SMarcel Holtmann static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2021a9de9248SMarcel Holtmann { 2022a9de9248SMarcel Holtmann struct hci_ev_encrypt_change *ev = (void *) skb->data; 2023a9de9248SMarcel Holtmann struct hci_conn *conn; 2024a9de9248SMarcel Holtmann 2025a9de9248SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 2026a9de9248SMarcel Holtmann 2027a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2028a9de9248SMarcel Holtmann 2029a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2030a9de9248SMarcel Holtmann if (conn) { 2031a9de9248SMarcel Holtmann if (!ev->status) { 2032ae293196SMarcel Holtmann if (ev->encrypt) { 2033ae293196SMarcel Holtmann /* Encryption implies authentication */ 2034ae293196SMarcel Holtmann conn->link_mode |= HCI_LM_AUTH; 2035a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_ENCRYPT; 2036da85e5e5SVinicius Costa Gomes conn->sec_level = conn->pending_sec_level; 2037ae293196SMarcel Holtmann } else 2038a9de9248SMarcel Holtmann conn->link_mode &= ~HCI_LM_ENCRYPT; 2039a9de9248SMarcel Holtmann } 2040a9de9248SMarcel Holtmann 204151a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 2042a9de9248SMarcel Holtmann 2043f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 2044f8558555SMarcel Holtmann if (!ev->status) 2045f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 2046f8558555SMarcel Holtmann 2047f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 2048f8558555SMarcel Holtmann hci_conn_put(conn); 2049f8558555SMarcel Holtmann } else 2050a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, ev->encrypt); 2051a9de9248SMarcel Holtmann } 2052a9de9248SMarcel Holtmann 2053a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2054a9de9248SMarcel Holtmann } 2055a9de9248SMarcel Holtmann 2056a9de9248SMarcel Holtmann static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2057a9de9248SMarcel Holtmann { 2058a9de9248SMarcel Holtmann struct hci_ev_change_link_key_complete *ev = (void *) skb->data; 2059a9de9248SMarcel Holtmann struct hci_conn *conn; 2060a9de9248SMarcel Holtmann 2061a9de9248SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 2062a9de9248SMarcel Holtmann 2063a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2064a9de9248SMarcel Holtmann 2065a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2066a9de9248SMarcel Holtmann if (conn) { 2067a9de9248SMarcel Holtmann if (!ev->status) 2068a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_SECURE; 2069a9de9248SMarcel Holtmann 207051a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 2071a9de9248SMarcel Holtmann 2072a9de9248SMarcel Holtmann hci_key_change_cfm(conn, ev->status); 2073a9de9248SMarcel Holtmann } 2074a9de9248SMarcel Holtmann 2075a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2076a9de9248SMarcel Holtmann } 2077a9de9248SMarcel Holtmann 2078a9de9248SMarcel Holtmann static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb) 2079a9de9248SMarcel Holtmann { 2080a9de9248SMarcel Holtmann struct hci_ev_remote_features *ev = (void *) skb->data; 2081a9de9248SMarcel Holtmann struct hci_conn *conn; 2082a9de9248SMarcel Holtmann 2083a9de9248SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 2084a9de9248SMarcel Holtmann 2085a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2086a9de9248SMarcel Holtmann 2087a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2088ccd556feSJohan Hedberg if (!conn) 2089ccd556feSJohan Hedberg goto unlock; 2090ccd556feSJohan Hedberg 2091769be974SMarcel Holtmann if (!ev->status) 2092a9de9248SMarcel Holtmann memcpy(conn->features, ev->features, 8); 2093a9de9248SMarcel Holtmann 2094ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 2095ccd556feSJohan Hedberg goto unlock; 2096ccd556feSJohan Hedberg 2097ccd556feSJohan Hedberg if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) { 2098769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features cp; 2099769be974SMarcel Holtmann cp.handle = ev->handle; 2100769be974SMarcel Holtmann cp.page = 0x01; 2101ccd556feSJohan Hedberg hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, 2102769be974SMarcel Holtmann sizeof(cp), &cp); 2103392599b9SJohan Hedberg goto unlock; 2104392599b9SJohan Hedberg } 2105392599b9SJohan Hedberg 2106127178d2SJohan Hedberg if (!ev->status) { 2107127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 2108127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 2109127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 2110127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 2111127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 2112b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 2113b644ba33SJohan Hedberg mgmt_device_connected(hdev, &conn->dst, conn->type, 211408c79b61SJohan Hedberg conn->dst_type, 0, NULL, 0, 2115b644ba33SJohan Hedberg conn->dev_class); 2116392599b9SJohan Hedberg 2117127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 2118769be974SMarcel Holtmann conn->state = BT_CONNECTED; 2119769be974SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 2120769be974SMarcel Holtmann hci_conn_put(conn); 2121769be974SMarcel Holtmann } 2122769be974SMarcel Holtmann 2123ccd556feSJohan Hedberg unlock: 2124a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2125a9de9248SMarcel Holtmann } 2126a9de9248SMarcel Holtmann 2127a9de9248SMarcel Holtmann static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb) 2128a9de9248SMarcel Holtmann { 2129a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2130a9de9248SMarcel Holtmann } 2131a9de9248SMarcel Holtmann 2132a9de9248SMarcel Holtmann static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2133a9de9248SMarcel Holtmann { 2134a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2135a9de9248SMarcel Holtmann } 2136a9de9248SMarcel Holtmann 2137a9de9248SMarcel Holtmann static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2138a9de9248SMarcel Holtmann { 2139a9de9248SMarcel Holtmann struct hci_ev_cmd_complete *ev = (void *) skb->data; 2140a9de9248SMarcel Holtmann __u16 opcode; 2141a9de9248SMarcel Holtmann 2142a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 2143a9de9248SMarcel Holtmann 2144a9de9248SMarcel Holtmann opcode = __le16_to_cpu(ev->opcode); 2145a9de9248SMarcel Holtmann 2146a9de9248SMarcel Holtmann switch (opcode) { 2147a9de9248SMarcel Holtmann case HCI_OP_INQUIRY_CANCEL: 2148a9de9248SMarcel Holtmann hci_cc_inquiry_cancel(hdev, skb); 2149a9de9248SMarcel Holtmann break; 2150a9de9248SMarcel Holtmann 2151a9de9248SMarcel Holtmann case HCI_OP_EXIT_PERIODIC_INQ: 2152a9de9248SMarcel Holtmann hci_cc_exit_periodic_inq(hdev, skb); 2153a9de9248SMarcel Holtmann break; 2154a9de9248SMarcel Holtmann 2155a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ_CANCEL: 2156a9de9248SMarcel Holtmann hci_cc_remote_name_req_cancel(hdev, skb); 2157a9de9248SMarcel Holtmann break; 2158a9de9248SMarcel Holtmann 2159a9de9248SMarcel Holtmann case HCI_OP_ROLE_DISCOVERY: 2160a9de9248SMarcel Holtmann hci_cc_role_discovery(hdev, skb); 2161a9de9248SMarcel Holtmann break; 2162a9de9248SMarcel Holtmann 2163e4e8e37cSMarcel Holtmann case HCI_OP_READ_LINK_POLICY: 2164e4e8e37cSMarcel Holtmann hci_cc_read_link_policy(hdev, skb); 2165e4e8e37cSMarcel Holtmann break; 2166e4e8e37cSMarcel Holtmann 2167a9de9248SMarcel Holtmann case HCI_OP_WRITE_LINK_POLICY: 2168a9de9248SMarcel Holtmann hci_cc_write_link_policy(hdev, skb); 2169a9de9248SMarcel Holtmann break; 2170a9de9248SMarcel Holtmann 2171e4e8e37cSMarcel Holtmann case HCI_OP_READ_DEF_LINK_POLICY: 2172e4e8e37cSMarcel Holtmann hci_cc_read_def_link_policy(hdev, skb); 2173e4e8e37cSMarcel Holtmann break; 2174e4e8e37cSMarcel Holtmann 2175e4e8e37cSMarcel Holtmann case HCI_OP_WRITE_DEF_LINK_POLICY: 2176e4e8e37cSMarcel Holtmann hci_cc_write_def_link_policy(hdev, skb); 2177e4e8e37cSMarcel Holtmann break; 2178e4e8e37cSMarcel Holtmann 2179a9de9248SMarcel Holtmann case HCI_OP_RESET: 2180a9de9248SMarcel Holtmann hci_cc_reset(hdev, skb); 2181a9de9248SMarcel Holtmann break; 2182a9de9248SMarcel Holtmann 2183a9de9248SMarcel Holtmann case HCI_OP_WRITE_LOCAL_NAME: 2184a9de9248SMarcel Holtmann hci_cc_write_local_name(hdev, skb); 2185a9de9248SMarcel Holtmann break; 2186a9de9248SMarcel Holtmann 2187a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_NAME: 2188a9de9248SMarcel Holtmann hci_cc_read_local_name(hdev, skb); 2189a9de9248SMarcel Holtmann break; 2190a9de9248SMarcel Holtmann 2191a9de9248SMarcel Holtmann case HCI_OP_WRITE_AUTH_ENABLE: 2192a9de9248SMarcel Holtmann hci_cc_write_auth_enable(hdev, skb); 2193a9de9248SMarcel Holtmann break; 2194a9de9248SMarcel Holtmann 2195a9de9248SMarcel Holtmann case HCI_OP_WRITE_ENCRYPT_MODE: 2196a9de9248SMarcel Holtmann hci_cc_write_encrypt_mode(hdev, skb); 2197a9de9248SMarcel Holtmann break; 2198a9de9248SMarcel Holtmann 2199a9de9248SMarcel Holtmann case HCI_OP_WRITE_SCAN_ENABLE: 2200a9de9248SMarcel Holtmann hci_cc_write_scan_enable(hdev, skb); 2201a9de9248SMarcel Holtmann break; 2202a9de9248SMarcel Holtmann 2203a9de9248SMarcel Holtmann case HCI_OP_READ_CLASS_OF_DEV: 2204a9de9248SMarcel Holtmann hci_cc_read_class_of_dev(hdev, skb); 2205a9de9248SMarcel Holtmann break; 2206a9de9248SMarcel Holtmann 2207a9de9248SMarcel Holtmann case HCI_OP_WRITE_CLASS_OF_DEV: 2208a9de9248SMarcel Holtmann hci_cc_write_class_of_dev(hdev, skb); 2209a9de9248SMarcel Holtmann break; 2210a9de9248SMarcel Holtmann 2211a9de9248SMarcel Holtmann case HCI_OP_READ_VOICE_SETTING: 2212a9de9248SMarcel Holtmann hci_cc_read_voice_setting(hdev, skb); 2213a9de9248SMarcel Holtmann break; 2214a9de9248SMarcel Holtmann 2215a9de9248SMarcel Holtmann case HCI_OP_WRITE_VOICE_SETTING: 2216a9de9248SMarcel Holtmann hci_cc_write_voice_setting(hdev, skb); 2217a9de9248SMarcel Holtmann break; 2218a9de9248SMarcel Holtmann 2219a9de9248SMarcel Holtmann case HCI_OP_HOST_BUFFER_SIZE: 2220a9de9248SMarcel Holtmann hci_cc_host_buffer_size(hdev, skb); 2221a9de9248SMarcel Holtmann break; 2222a9de9248SMarcel Holtmann 2223333140b5SMarcel Holtmann case HCI_OP_WRITE_SSP_MODE: 2224333140b5SMarcel Holtmann hci_cc_write_ssp_mode(hdev, skb); 2225333140b5SMarcel Holtmann break; 2226333140b5SMarcel Holtmann 2227a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_VERSION: 2228a9de9248SMarcel Holtmann hci_cc_read_local_version(hdev, skb); 2229a9de9248SMarcel Holtmann break; 2230a9de9248SMarcel Holtmann 2231a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_COMMANDS: 2232a9de9248SMarcel Holtmann hci_cc_read_local_commands(hdev, skb); 2233a9de9248SMarcel Holtmann break; 2234a9de9248SMarcel Holtmann 2235a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_FEATURES: 2236a9de9248SMarcel Holtmann hci_cc_read_local_features(hdev, skb); 2237a9de9248SMarcel Holtmann break; 2238a9de9248SMarcel Holtmann 2239971e3a4bSAndre Guedes case HCI_OP_READ_LOCAL_EXT_FEATURES: 2240971e3a4bSAndre Guedes hci_cc_read_local_ext_features(hdev, skb); 2241971e3a4bSAndre Guedes break; 2242971e3a4bSAndre Guedes 2243a9de9248SMarcel Holtmann case HCI_OP_READ_BUFFER_SIZE: 2244a9de9248SMarcel Holtmann hci_cc_read_buffer_size(hdev, skb); 2245a9de9248SMarcel Holtmann break; 2246a9de9248SMarcel Holtmann 2247a9de9248SMarcel Holtmann case HCI_OP_READ_BD_ADDR: 2248a9de9248SMarcel Holtmann hci_cc_read_bd_addr(hdev, skb); 2249a9de9248SMarcel Holtmann break; 2250a9de9248SMarcel Holtmann 2251350ee4cfSAndrei Emeltchenko case HCI_OP_READ_DATA_BLOCK_SIZE: 2252350ee4cfSAndrei Emeltchenko hci_cc_read_data_block_size(hdev, skb); 2253350ee4cfSAndrei Emeltchenko break; 2254350ee4cfSAndrei Emeltchenko 225523bb5763SJohan Hedberg case HCI_OP_WRITE_CA_TIMEOUT: 225623bb5763SJohan Hedberg hci_cc_write_ca_timeout(hdev, skb); 225723bb5763SJohan Hedberg break; 225823bb5763SJohan Hedberg 22591e89cffbSAndrei Emeltchenko case HCI_OP_READ_FLOW_CONTROL_MODE: 22601e89cffbSAndrei Emeltchenko hci_cc_read_flow_control_mode(hdev, skb); 22611e89cffbSAndrei Emeltchenko break; 22621e89cffbSAndrei Emeltchenko 2263928abaa7SAndrei Emeltchenko case HCI_OP_READ_LOCAL_AMP_INFO: 2264928abaa7SAndrei Emeltchenko hci_cc_read_local_amp_info(hdev, skb); 2265928abaa7SAndrei Emeltchenko break; 2266928abaa7SAndrei Emeltchenko 2267b0916ea0SJohan Hedberg case HCI_OP_DELETE_STORED_LINK_KEY: 2268b0916ea0SJohan Hedberg hci_cc_delete_stored_link_key(hdev, skb); 2269b0916ea0SJohan Hedberg break; 2270b0916ea0SJohan Hedberg 2271d5859e22SJohan Hedberg case HCI_OP_SET_EVENT_MASK: 2272d5859e22SJohan Hedberg hci_cc_set_event_mask(hdev, skb); 2273d5859e22SJohan Hedberg break; 2274d5859e22SJohan Hedberg 2275d5859e22SJohan Hedberg case HCI_OP_WRITE_INQUIRY_MODE: 2276d5859e22SJohan Hedberg hci_cc_write_inquiry_mode(hdev, skb); 2277d5859e22SJohan Hedberg break; 2278d5859e22SJohan Hedberg 2279d5859e22SJohan Hedberg case HCI_OP_READ_INQ_RSP_TX_POWER: 2280d5859e22SJohan Hedberg hci_cc_read_inq_rsp_tx_power(hdev, skb); 2281d5859e22SJohan Hedberg break; 2282d5859e22SJohan Hedberg 2283d5859e22SJohan Hedberg case HCI_OP_SET_EVENT_FLT: 2284d5859e22SJohan Hedberg hci_cc_set_event_flt(hdev, skb); 2285d5859e22SJohan Hedberg break; 2286d5859e22SJohan Hedberg 2287980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_REPLY: 2288980e1a53SJohan Hedberg hci_cc_pin_code_reply(hdev, skb); 2289980e1a53SJohan Hedberg break; 2290980e1a53SJohan Hedberg 2291980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_NEG_REPLY: 2292980e1a53SJohan Hedberg hci_cc_pin_code_neg_reply(hdev, skb); 2293980e1a53SJohan Hedberg break; 2294980e1a53SJohan Hedberg 2295c35938b2SSzymon Janc case HCI_OP_READ_LOCAL_OOB_DATA: 2296c35938b2SSzymon Janc hci_cc_read_local_oob_data_reply(hdev, skb); 2297c35938b2SSzymon Janc break; 2298c35938b2SSzymon Janc 22996ed58ec5SVille Tervo case HCI_OP_LE_READ_BUFFER_SIZE: 23006ed58ec5SVille Tervo hci_cc_le_read_buffer_size(hdev, skb); 23016ed58ec5SVille Tervo break; 23026ed58ec5SVille Tervo 2303a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_REPLY: 2304a5c29683SJohan Hedberg hci_cc_user_confirm_reply(hdev, skb); 2305a5c29683SJohan Hedberg break; 2306a5c29683SJohan Hedberg 2307a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_NEG_REPLY: 2308a5c29683SJohan Hedberg hci_cc_user_confirm_neg_reply(hdev, skb); 2309a5c29683SJohan Hedberg break; 2310a5c29683SJohan Hedberg 23111143d458SBrian Gix case HCI_OP_USER_PASSKEY_REPLY: 23121143d458SBrian Gix hci_cc_user_passkey_reply(hdev, skb); 23131143d458SBrian Gix break; 23141143d458SBrian Gix 23151143d458SBrian Gix case HCI_OP_USER_PASSKEY_NEG_REPLY: 23161143d458SBrian Gix hci_cc_user_passkey_neg_reply(hdev, skb); 231716cde993SSzymon Janc break; 231807f7fa5dSAndre Guedes 231907f7fa5dSAndre Guedes case HCI_OP_LE_SET_SCAN_PARAM: 232007f7fa5dSAndre Guedes hci_cc_le_set_scan_param(hdev, skb); 23211143d458SBrian Gix break; 23221143d458SBrian Gix 2323eb9d91f5SAndre Guedes case HCI_OP_LE_SET_SCAN_ENABLE: 2324eb9d91f5SAndre Guedes hci_cc_le_set_scan_enable(hdev, skb); 2325eb9d91f5SAndre Guedes break; 2326eb9d91f5SAndre Guedes 2327a7a595f6SVinicius Costa Gomes case HCI_OP_LE_LTK_REPLY: 2328a7a595f6SVinicius Costa Gomes hci_cc_le_ltk_reply(hdev, skb); 2329a7a595f6SVinicius Costa Gomes break; 2330a7a595f6SVinicius Costa Gomes 2331a7a595f6SVinicius Costa Gomes case HCI_OP_LE_LTK_NEG_REPLY: 2332a7a595f6SVinicius Costa Gomes hci_cc_le_ltk_neg_reply(hdev, skb); 2333a7a595f6SVinicius Costa Gomes break; 2334a7a595f6SVinicius Costa Gomes 2335f9b49306SAndre Guedes case HCI_OP_WRITE_LE_HOST_SUPPORTED: 2336f9b49306SAndre Guedes hci_cc_write_le_host_supported(hdev, skb); 2337f9b49306SAndre Guedes break; 2338f9b49306SAndre Guedes 2339a9de9248SMarcel Holtmann default: 2340a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x", hdev->name, opcode); 2341a9de9248SMarcel Holtmann break; 2342a9de9248SMarcel Holtmann } 2343a9de9248SMarcel Holtmann 23446bd32326SVille Tervo if (ev->opcode != HCI_OP_NOP) 23456bd32326SVille Tervo del_timer(&hdev->cmd_timer); 23466bd32326SVille Tervo 2347a9de9248SMarcel Holtmann if (ev->ncmd) { 2348a9de9248SMarcel Holtmann atomic_set(&hdev->cmd_cnt, 1); 2349a9de9248SMarcel Holtmann if (!skb_queue_empty(&hdev->cmd_q)) 2350c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 2351a9de9248SMarcel Holtmann } 2352a9de9248SMarcel Holtmann } 2353a9de9248SMarcel Holtmann 2354a9de9248SMarcel Holtmann static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) 2355a9de9248SMarcel Holtmann { 2356a9de9248SMarcel Holtmann struct hci_ev_cmd_status *ev = (void *) skb->data; 2357a9de9248SMarcel Holtmann __u16 opcode; 2358a9de9248SMarcel Holtmann 2359a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 2360a9de9248SMarcel Holtmann 2361a9de9248SMarcel Holtmann opcode = __le16_to_cpu(ev->opcode); 2362a9de9248SMarcel Holtmann 2363a9de9248SMarcel Holtmann switch (opcode) { 2364a9de9248SMarcel Holtmann case HCI_OP_INQUIRY: 2365a9de9248SMarcel Holtmann hci_cs_inquiry(hdev, ev->status); 2366a9de9248SMarcel Holtmann break; 2367a9de9248SMarcel Holtmann 2368a9de9248SMarcel Holtmann case HCI_OP_CREATE_CONN: 2369a9de9248SMarcel Holtmann hci_cs_create_conn(hdev, ev->status); 2370a9de9248SMarcel Holtmann break; 2371a9de9248SMarcel Holtmann 2372a9de9248SMarcel Holtmann case HCI_OP_ADD_SCO: 2373a9de9248SMarcel Holtmann hci_cs_add_sco(hdev, ev->status); 2374a9de9248SMarcel Holtmann break; 2375a9de9248SMarcel Holtmann 2376f8558555SMarcel Holtmann case HCI_OP_AUTH_REQUESTED: 2377f8558555SMarcel Holtmann hci_cs_auth_requested(hdev, ev->status); 2378f8558555SMarcel Holtmann break; 2379f8558555SMarcel Holtmann 2380f8558555SMarcel Holtmann case HCI_OP_SET_CONN_ENCRYPT: 2381f8558555SMarcel Holtmann hci_cs_set_conn_encrypt(hdev, ev->status); 2382f8558555SMarcel Holtmann break; 2383f8558555SMarcel Holtmann 2384a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ: 2385a9de9248SMarcel Holtmann hci_cs_remote_name_req(hdev, ev->status); 2386a9de9248SMarcel Holtmann break; 2387a9de9248SMarcel Holtmann 2388769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_FEATURES: 2389769be974SMarcel Holtmann hci_cs_read_remote_features(hdev, ev->status); 2390769be974SMarcel Holtmann break; 2391769be974SMarcel Holtmann 2392769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_EXT_FEATURES: 2393769be974SMarcel Holtmann hci_cs_read_remote_ext_features(hdev, ev->status); 2394769be974SMarcel Holtmann break; 2395769be974SMarcel Holtmann 2396a9de9248SMarcel Holtmann case HCI_OP_SETUP_SYNC_CONN: 2397a9de9248SMarcel Holtmann hci_cs_setup_sync_conn(hdev, ev->status); 2398a9de9248SMarcel Holtmann break; 2399a9de9248SMarcel Holtmann 2400a9de9248SMarcel Holtmann case HCI_OP_SNIFF_MODE: 2401a9de9248SMarcel Holtmann hci_cs_sniff_mode(hdev, ev->status); 2402a9de9248SMarcel Holtmann break; 2403a9de9248SMarcel Holtmann 2404a9de9248SMarcel Holtmann case HCI_OP_EXIT_SNIFF_MODE: 2405a9de9248SMarcel Holtmann hci_cs_exit_sniff_mode(hdev, ev->status); 2406a9de9248SMarcel Holtmann break; 2407a9de9248SMarcel Holtmann 24088962ee74SJohan Hedberg case HCI_OP_DISCONNECT: 240988c3df13SJohan Hedberg hci_cs_disconnect(hdev, ev->status); 24108962ee74SJohan Hedberg break; 24118962ee74SJohan Hedberg 2412fcd89c09SVille Tervo case HCI_OP_LE_CREATE_CONN: 2413fcd89c09SVille Tervo hci_cs_le_create_conn(hdev, ev->status); 2414fcd89c09SVille Tervo break; 2415fcd89c09SVille Tervo 2416a7a595f6SVinicius Costa Gomes case HCI_OP_LE_START_ENC: 2417a7a595f6SVinicius Costa Gomes hci_cs_le_start_enc(hdev, ev->status); 2418a7a595f6SVinicius Costa Gomes break; 2419a7a595f6SVinicius Costa Gomes 2420a9de9248SMarcel Holtmann default: 2421a9de9248SMarcel Holtmann BT_DBG("%s opcode 0x%x", hdev->name, opcode); 2422a9de9248SMarcel Holtmann break; 2423a9de9248SMarcel Holtmann } 2424a9de9248SMarcel Holtmann 24256bd32326SVille Tervo if (ev->opcode != HCI_OP_NOP) 24266bd32326SVille Tervo del_timer(&hdev->cmd_timer); 24276bd32326SVille Tervo 242810572132SGustavo F. Padovan if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { 2429a9de9248SMarcel Holtmann atomic_set(&hdev->cmd_cnt, 1); 2430a9de9248SMarcel Holtmann if (!skb_queue_empty(&hdev->cmd_q)) 2431c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 2432a9de9248SMarcel Holtmann } 2433a9de9248SMarcel Holtmann } 2434a9de9248SMarcel Holtmann 2435a9de9248SMarcel Holtmann static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2436a9de9248SMarcel Holtmann { 2437a9de9248SMarcel Holtmann struct hci_ev_role_change *ev = (void *) skb->data; 2438a9de9248SMarcel Holtmann struct hci_conn *conn; 2439a9de9248SMarcel Holtmann 2440a9de9248SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 2441a9de9248SMarcel Holtmann 2442a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2443a9de9248SMarcel Holtmann 2444a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2445a9de9248SMarcel Holtmann if (conn) { 2446a9de9248SMarcel Holtmann if (!ev->status) { 2447a9de9248SMarcel Holtmann if (ev->role) 2448a9de9248SMarcel Holtmann conn->link_mode &= ~HCI_LM_MASTER; 2449a9de9248SMarcel Holtmann else 2450a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_MASTER; 2451a9de9248SMarcel Holtmann } 2452a9de9248SMarcel Holtmann 245351a8efd7SJohan Hedberg clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 2454a9de9248SMarcel Holtmann 2455a9de9248SMarcel Holtmann hci_role_switch_cfm(conn, ev->status, ev->role); 2456a9de9248SMarcel Holtmann } 2457a9de9248SMarcel Holtmann 2458a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2459a9de9248SMarcel Holtmann } 2460a9de9248SMarcel Holtmann 24611da177e4SLinus Torvalds static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) 24621da177e4SLinus Torvalds { 2463a9de9248SMarcel Holtmann struct hci_ev_num_comp_pkts *ev = (void *) skb->data; 24641da177e4SLinus Torvalds int i; 24651da177e4SLinus Torvalds 246632ac5b9bSAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) { 246732ac5b9bSAndrei Emeltchenko BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); 246832ac5b9bSAndrei Emeltchenko return; 246932ac5b9bSAndrei Emeltchenko } 247032ac5b9bSAndrei Emeltchenko 2471c5993de8SAndrei Emeltchenko if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + 2472c5993de8SAndrei Emeltchenko ev->num_hndl * sizeof(struct hci_comp_pkts_info)) { 24731da177e4SLinus Torvalds BT_DBG("%s bad parameters", hdev->name); 24741da177e4SLinus Torvalds return; 24751da177e4SLinus Torvalds } 24761da177e4SLinus Torvalds 2477c5993de8SAndrei Emeltchenko BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl); 2478c5993de8SAndrei Emeltchenko 2479613a1c0cSAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 2480613a1c0cSAndrei Emeltchenko struct hci_comp_pkts_info *info = &ev->handles[i]; 24811da177e4SLinus Torvalds struct hci_conn *conn; 24821da177e4SLinus Torvalds __u16 handle, count; 24831da177e4SLinus Torvalds 2484613a1c0cSAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 2485613a1c0cSAndrei Emeltchenko count = __le16_to_cpu(info->count); 24861da177e4SLinus Torvalds 24871da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 2488f4280918SAndrei Emeltchenko if (!conn) 2489f4280918SAndrei Emeltchenko continue; 2490f4280918SAndrei Emeltchenko 24911da177e4SLinus Torvalds conn->sent -= count; 24921da177e4SLinus Torvalds 2493f4280918SAndrei Emeltchenko switch (conn->type) { 2494f4280918SAndrei Emeltchenko case ACL_LINK: 249570f23020SAndrei Emeltchenko hdev->acl_cnt += count; 249670f23020SAndrei Emeltchenko if (hdev->acl_cnt > hdev->acl_pkts) 24971da177e4SLinus Torvalds hdev->acl_cnt = hdev->acl_pkts; 2498f4280918SAndrei Emeltchenko break; 2499f4280918SAndrei Emeltchenko 2500f4280918SAndrei Emeltchenko case LE_LINK: 25016ed58ec5SVille Tervo if (hdev->le_pkts) { 25026ed58ec5SVille Tervo hdev->le_cnt += count; 25036ed58ec5SVille Tervo if (hdev->le_cnt > hdev->le_pkts) 25046ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 25056ed58ec5SVille Tervo } else { 25066ed58ec5SVille Tervo hdev->acl_cnt += count; 25076ed58ec5SVille Tervo if (hdev->acl_cnt > hdev->acl_pkts) 25086ed58ec5SVille Tervo hdev->acl_cnt = hdev->acl_pkts; 25096ed58ec5SVille Tervo } 2510f4280918SAndrei Emeltchenko break; 2511f4280918SAndrei Emeltchenko 2512f4280918SAndrei Emeltchenko case SCO_LINK: 251370f23020SAndrei Emeltchenko hdev->sco_cnt += count; 251470f23020SAndrei Emeltchenko if (hdev->sco_cnt > hdev->sco_pkts) 25155b7f9909SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 2516f4280918SAndrei Emeltchenko break; 2517f4280918SAndrei Emeltchenko 2518f4280918SAndrei Emeltchenko default: 2519f4280918SAndrei Emeltchenko BT_ERR("Unknown type %d conn %p", conn->type, conn); 2520f4280918SAndrei Emeltchenko break; 25211da177e4SLinus Torvalds } 25221da177e4SLinus Torvalds } 2523a9de9248SMarcel Holtmann 25243eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 25251da177e4SLinus Torvalds } 25261da177e4SLinus Torvalds 252725e89e99SAndrei Emeltchenko static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev, 252825e89e99SAndrei Emeltchenko struct sk_buff *skb) 252925e89e99SAndrei Emeltchenko { 253025e89e99SAndrei Emeltchenko struct hci_ev_num_comp_blocks *ev = (void *) skb->data; 253125e89e99SAndrei Emeltchenko int i; 253225e89e99SAndrei Emeltchenko 253325e89e99SAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) { 253425e89e99SAndrei Emeltchenko BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); 253525e89e99SAndrei Emeltchenko return; 253625e89e99SAndrei Emeltchenko } 253725e89e99SAndrei Emeltchenko 253825e89e99SAndrei Emeltchenko if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + 253925e89e99SAndrei Emeltchenko ev->num_hndl * sizeof(struct hci_comp_blocks_info)) { 254025e89e99SAndrei Emeltchenko BT_DBG("%s bad parameters", hdev->name); 254125e89e99SAndrei Emeltchenko return; 254225e89e99SAndrei Emeltchenko } 254325e89e99SAndrei Emeltchenko 254425e89e99SAndrei Emeltchenko BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks, 254525e89e99SAndrei Emeltchenko ev->num_hndl); 254625e89e99SAndrei Emeltchenko 254725e89e99SAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 254825e89e99SAndrei Emeltchenko struct hci_comp_blocks_info *info = &ev->handles[i]; 254925e89e99SAndrei Emeltchenko struct hci_conn *conn; 255025e89e99SAndrei Emeltchenko __u16 handle, block_count; 255125e89e99SAndrei Emeltchenko 255225e89e99SAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 255325e89e99SAndrei Emeltchenko block_count = __le16_to_cpu(info->blocks); 255425e89e99SAndrei Emeltchenko 255525e89e99SAndrei Emeltchenko conn = hci_conn_hash_lookup_handle(hdev, handle); 255625e89e99SAndrei Emeltchenko if (!conn) 255725e89e99SAndrei Emeltchenko continue; 255825e89e99SAndrei Emeltchenko 255925e89e99SAndrei Emeltchenko conn->sent -= block_count; 256025e89e99SAndrei Emeltchenko 256125e89e99SAndrei Emeltchenko switch (conn->type) { 256225e89e99SAndrei Emeltchenko case ACL_LINK: 256325e89e99SAndrei Emeltchenko hdev->block_cnt += block_count; 256425e89e99SAndrei Emeltchenko if (hdev->block_cnt > hdev->num_blocks) 256525e89e99SAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 256625e89e99SAndrei Emeltchenko break; 256725e89e99SAndrei Emeltchenko 256825e89e99SAndrei Emeltchenko default: 256925e89e99SAndrei Emeltchenko BT_ERR("Unknown type %d conn %p", conn->type, conn); 257025e89e99SAndrei Emeltchenko break; 257125e89e99SAndrei Emeltchenko } 257225e89e99SAndrei Emeltchenko } 257325e89e99SAndrei Emeltchenko 257425e89e99SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->tx_work); 257525e89e99SAndrei Emeltchenko } 257625e89e99SAndrei Emeltchenko 257704837f64SMarcel Holtmann static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 25781da177e4SLinus Torvalds { 2579a9de9248SMarcel Holtmann struct hci_ev_mode_change *ev = (void *) skb->data; 258004837f64SMarcel Holtmann struct hci_conn *conn; 25811da177e4SLinus Torvalds 25821da177e4SLinus Torvalds BT_DBG("%s status %d", hdev->name, ev->status); 25831da177e4SLinus Torvalds 25841da177e4SLinus Torvalds hci_dev_lock(hdev); 25851da177e4SLinus Torvalds 258604837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 258704837f64SMarcel Holtmann if (conn) { 258804837f64SMarcel Holtmann conn->mode = ev->mode; 258904837f64SMarcel Holtmann conn->interval = __le16_to_cpu(ev->interval); 259004837f64SMarcel Holtmann 259151a8efd7SJohan Hedberg if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) { 259204837f64SMarcel Holtmann if (conn->mode == HCI_CM_ACTIVE) 259358a681efSJohan Hedberg set_bit(HCI_CONN_POWER_SAVE, &conn->flags); 259404837f64SMarcel Holtmann else 259558a681efSJohan Hedberg clear_bit(HCI_CONN_POWER_SAVE, &conn->flags); 259604837f64SMarcel Holtmann } 2597e73439d8SMarcel Holtmann 259851a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 2599e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 260004837f64SMarcel Holtmann } 260104837f64SMarcel Holtmann 260204837f64SMarcel Holtmann hci_dev_unlock(hdev); 260304837f64SMarcel Holtmann } 260404837f64SMarcel Holtmann 26051da177e4SLinus Torvalds static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 26061da177e4SLinus Torvalds { 2607052b30b0SMarcel Holtmann struct hci_ev_pin_code_req *ev = (void *) skb->data; 2608052b30b0SMarcel Holtmann struct hci_conn *conn; 2609052b30b0SMarcel Holtmann 2610a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2611052b30b0SMarcel Holtmann 2612052b30b0SMarcel Holtmann hci_dev_lock(hdev); 2613052b30b0SMarcel Holtmann 2614052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2615b6f98044SWaldemar Rymarkiewicz if (!conn) 2616b6f98044SWaldemar Rymarkiewicz goto unlock; 2617b6f98044SWaldemar Rymarkiewicz 2618b6f98044SWaldemar Rymarkiewicz if (conn->state == BT_CONNECTED) { 2619052b30b0SMarcel Holtmann hci_conn_hold(conn); 2620052b30b0SMarcel Holtmann conn->disc_timeout = HCI_PAIRING_TIMEOUT; 2621052b30b0SMarcel Holtmann hci_conn_put(conn); 2622052b30b0SMarcel Holtmann } 2623052b30b0SMarcel Holtmann 2624a8b2d5c2SJohan Hedberg if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags)) 262503b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, 262603b555e1SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 2627a8b2d5c2SJohan Hedberg else if (test_bit(HCI_MGMT, &hdev->dev_flags)) { 2628a770bb5aSWaldemar Rymarkiewicz u8 secure; 2629a770bb5aSWaldemar Rymarkiewicz 2630a770bb5aSWaldemar Rymarkiewicz if (conn->pending_sec_level == BT_SECURITY_HIGH) 2631a770bb5aSWaldemar Rymarkiewicz secure = 1; 2632a770bb5aSWaldemar Rymarkiewicz else 2633a770bb5aSWaldemar Rymarkiewicz secure = 0; 2634a770bb5aSWaldemar Rymarkiewicz 2635744cf19eSJohan Hedberg mgmt_pin_code_request(hdev, &ev->bdaddr, secure); 2636a770bb5aSWaldemar Rymarkiewicz } 2637980e1a53SJohan Hedberg 2638b6f98044SWaldemar Rymarkiewicz unlock: 2639052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 26401da177e4SLinus Torvalds } 26411da177e4SLinus Torvalds 26421da177e4SLinus Torvalds static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 26431da177e4SLinus Torvalds { 264455ed8ca1SJohan Hedberg struct hci_ev_link_key_req *ev = (void *) skb->data; 264555ed8ca1SJohan Hedberg struct hci_cp_link_key_reply cp; 264655ed8ca1SJohan Hedberg struct hci_conn *conn; 264755ed8ca1SJohan Hedberg struct link_key *key; 264855ed8ca1SJohan Hedberg 2649a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 265055ed8ca1SJohan Hedberg 2651a8b2d5c2SJohan Hedberg if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) 265255ed8ca1SJohan Hedberg return; 265355ed8ca1SJohan Hedberg 265455ed8ca1SJohan Hedberg hci_dev_lock(hdev); 265555ed8ca1SJohan Hedberg 265655ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, &ev->bdaddr); 265755ed8ca1SJohan Hedberg if (!key) { 265855ed8ca1SJohan Hedberg BT_DBG("%s link key not found for %s", hdev->name, 265955ed8ca1SJohan Hedberg batostr(&ev->bdaddr)); 266055ed8ca1SJohan Hedberg goto not_found; 266155ed8ca1SJohan Hedberg } 266255ed8ca1SJohan Hedberg 266355ed8ca1SJohan Hedberg BT_DBG("%s found key type %u for %s", hdev->name, key->type, 266455ed8ca1SJohan Hedberg batostr(&ev->bdaddr)); 266555ed8ca1SJohan Hedberg 2666a8b2d5c2SJohan Hedberg if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) && 2667b6020ba0SWaldemar Rymarkiewicz key->type == HCI_LK_DEBUG_COMBINATION) { 266855ed8ca1SJohan Hedberg BT_DBG("%s ignoring debug key", hdev->name); 266955ed8ca1SJohan Hedberg goto not_found; 267055ed8ca1SJohan Hedberg } 267155ed8ca1SJohan Hedberg 267255ed8ca1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 267360b83f57SWaldemar Rymarkiewicz if (conn) { 267460b83f57SWaldemar Rymarkiewicz if (key->type == HCI_LK_UNAUTH_COMBINATION && 267560b83f57SWaldemar Rymarkiewicz conn->auth_type != 0xff && 267660b83f57SWaldemar Rymarkiewicz (conn->auth_type & 0x01)) { 267755ed8ca1SJohan Hedberg BT_DBG("%s ignoring unauthenticated key", hdev->name); 267855ed8ca1SJohan Hedberg goto not_found; 267955ed8ca1SJohan Hedberg } 268055ed8ca1SJohan Hedberg 268160b83f57SWaldemar Rymarkiewicz if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && 268260b83f57SWaldemar Rymarkiewicz conn->pending_sec_level == BT_SECURITY_HIGH) { 268360b83f57SWaldemar Rymarkiewicz BT_DBG("%s ignoring key unauthenticated for high \ 268460b83f57SWaldemar Rymarkiewicz security", hdev->name); 268560b83f57SWaldemar Rymarkiewicz goto not_found; 268660b83f57SWaldemar Rymarkiewicz } 268760b83f57SWaldemar Rymarkiewicz 268860b83f57SWaldemar Rymarkiewicz conn->key_type = key->type; 268960b83f57SWaldemar Rymarkiewicz conn->pin_length = key->pin_len; 269060b83f57SWaldemar Rymarkiewicz } 269160b83f57SWaldemar Rymarkiewicz 269255ed8ca1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 269355ed8ca1SJohan Hedberg memcpy(cp.link_key, key->val, 16); 269455ed8ca1SJohan Hedberg 269555ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp); 269655ed8ca1SJohan Hedberg 269755ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 269855ed8ca1SJohan Hedberg 269955ed8ca1SJohan Hedberg return; 270055ed8ca1SJohan Hedberg 270155ed8ca1SJohan Hedberg not_found: 270255ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr); 270355ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 27041da177e4SLinus Torvalds } 27051da177e4SLinus Torvalds 27061da177e4SLinus Torvalds static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 27071da177e4SLinus Torvalds { 2708052b30b0SMarcel Holtmann struct hci_ev_link_key_notify *ev = (void *) skb->data; 2709052b30b0SMarcel Holtmann struct hci_conn *conn; 271055ed8ca1SJohan Hedberg u8 pin_len = 0; 2711052b30b0SMarcel Holtmann 2712a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2713052b30b0SMarcel Holtmann 2714052b30b0SMarcel Holtmann hci_dev_lock(hdev); 2715052b30b0SMarcel Holtmann 2716052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2717052b30b0SMarcel Holtmann if (conn) { 2718052b30b0SMarcel Holtmann hci_conn_hold(conn); 2719052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 2720980e1a53SJohan Hedberg pin_len = conn->pin_length; 272113d39315SWaldemar Rymarkiewicz 272213d39315SWaldemar Rymarkiewicz if (ev->key_type != HCI_LK_CHANGED_COMBINATION) 272313d39315SWaldemar Rymarkiewicz conn->key_type = ev->key_type; 272413d39315SWaldemar Rymarkiewicz 2725052b30b0SMarcel Holtmann hci_conn_put(conn); 2726052b30b0SMarcel Holtmann } 2727052b30b0SMarcel Holtmann 2728a8b2d5c2SJohan Hedberg if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) 2729d25e28abSJohan Hedberg hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key, 273055ed8ca1SJohan Hedberg ev->key_type, pin_len); 273155ed8ca1SJohan Hedberg 2732052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 27331da177e4SLinus Torvalds } 27341da177e4SLinus Torvalds 273504837f64SMarcel Holtmann static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) 273604837f64SMarcel Holtmann { 2737a9de9248SMarcel Holtmann struct hci_ev_clock_offset *ev = (void *) skb->data; 273804837f64SMarcel Holtmann struct hci_conn *conn; 273904837f64SMarcel Holtmann 274004837f64SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 274104837f64SMarcel Holtmann 274204837f64SMarcel Holtmann hci_dev_lock(hdev); 274304837f64SMarcel Holtmann 274404837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 27451da177e4SLinus Torvalds if (conn && !ev->status) { 27461da177e4SLinus Torvalds struct inquiry_entry *ie; 27471da177e4SLinus Torvalds 2748cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 2749cc11b9c1SAndrei Emeltchenko if (ie) { 27501da177e4SLinus Torvalds ie->data.clock_offset = ev->clock_offset; 27511da177e4SLinus Torvalds ie->timestamp = jiffies; 27521da177e4SLinus Torvalds } 27531da177e4SLinus Torvalds } 27541da177e4SLinus Torvalds 27551da177e4SLinus Torvalds hci_dev_unlock(hdev); 27561da177e4SLinus Torvalds } 27571da177e4SLinus Torvalds 2758a8746417SMarcel Holtmann static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2759a8746417SMarcel Holtmann { 2760a8746417SMarcel Holtmann struct hci_ev_pkt_type_change *ev = (void *) skb->data; 2761a8746417SMarcel Holtmann struct hci_conn *conn; 2762a8746417SMarcel Holtmann 2763a8746417SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 2764a8746417SMarcel Holtmann 2765a8746417SMarcel Holtmann hci_dev_lock(hdev); 2766a8746417SMarcel Holtmann 2767a8746417SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2768a8746417SMarcel Holtmann if (conn && !ev->status) 2769a8746417SMarcel Holtmann conn->pkt_type = __le16_to_cpu(ev->pkt_type); 2770a8746417SMarcel Holtmann 2771a8746417SMarcel Holtmann hci_dev_unlock(hdev); 2772a8746417SMarcel Holtmann } 2773a8746417SMarcel Holtmann 277485a1e930SMarcel Holtmann static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) 277585a1e930SMarcel Holtmann { 2776a9de9248SMarcel Holtmann struct hci_ev_pscan_rep_mode *ev = (void *) skb->data; 277785a1e930SMarcel Holtmann struct inquiry_entry *ie; 277885a1e930SMarcel Holtmann 277985a1e930SMarcel Holtmann BT_DBG("%s", hdev->name); 278085a1e930SMarcel Holtmann 278185a1e930SMarcel Holtmann hci_dev_lock(hdev); 278285a1e930SMarcel Holtmann 2783cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 2784cc11b9c1SAndrei Emeltchenko if (ie) { 278585a1e930SMarcel Holtmann ie->data.pscan_rep_mode = ev->pscan_rep_mode; 278685a1e930SMarcel Holtmann ie->timestamp = jiffies; 278785a1e930SMarcel Holtmann } 278885a1e930SMarcel Holtmann 278985a1e930SMarcel Holtmann hci_dev_unlock(hdev); 279085a1e930SMarcel Holtmann } 279185a1e930SMarcel Holtmann 2792a9de9248SMarcel Holtmann static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb) 2793a9de9248SMarcel Holtmann { 2794a9de9248SMarcel Holtmann struct inquiry_data data; 2795a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 2796388fc8faSJohan Hedberg bool name_known, ssp; 2797a9de9248SMarcel Holtmann 2798a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 2799a9de9248SMarcel Holtmann 2800a9de9248SMarcel Holtmann if (!num_rsp) 2801a9de9248SMarcel Holtmann return; 2802a9de9248SMarcel Holtmann 2803a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2804a9de9248SMarcel Holtmann 2805a9de9248SMarcel Holtmann if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { 2806138d22efSSzymon Janc struct inquiry_info_with_rssi_and_pscan_mode *info; 2807138d22efSSzymon Janc info = (void *) (skb->data + 1); 2808a9de9248SMarcel Holtmann 2809e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 2810a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 2811a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 2812a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 2813a9de9248SMarcel Holtmann data.pscan_mode = info->pscan_mode; 2814a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 2815a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 2816a9de9248SMarcel Holtmann data.rssi = info->rssi; 281741a96212SMarcel Holtmann data.ssp_mode = 0x00; 28183175405bSJohan Hedberg 28193175405bSJohan Hedberg name_known = hci_inquiry_cache_update(hdev, &data, 2820388fc8faSJohan Hedberg false, &ssp); 282148264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 2822e17acd40SJohan Hedberg info->dev_class, info->rssi, 2823388fc8faSJohan Hedberg !name_known, ssp, NULL, 0); 2824a9de9248SMarcel Holtmann } 2825a9de9248SMarcel Holtmann } else { 2826a9de9248SMarcel Holtmann struct inquiry_info_with_rssi *info = (void *) (skb->data + 1); 2827a9de9248SMarcel Holtmann 2828e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 2829a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 2830a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 2831a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 2832a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 2833a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 2834a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 2835a9de9248SMarcel Holtmann data.rssi = info->rssi; 283641a96212SMarcel Holtmann data.ssp_mode = 0x00; 28373175405bSJohan Hedberg name_known = hci_inquiry_cache_update(hdev, &data, 2838388fc8faSJohan Hedberg false, &ssp); 283948264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 2840e17acd40SJohan Hedberg info->dev_class, info->rssi, 2841388fc8faSJohan Hedberg !name_known, ssp, NULL, 0); 2842a9de9248SMarcel Holtmann } 2843a9de9248SMarcel Holtmann } 2844a9de9248SMarcel Holtmann 2845a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2846a9de9248SMarcel Holtmann } 2847a9de9248SMarcel Holtmann 2848a9de9248SMarcel Holtmann static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb) 2849a9de9248SMarcel Holtmann { 285041a96212SMarcel Holtmann struct hci_ev_remote_ext_features *ev = (void *) skb->data; 285141a96212SMarcel Holtmann struct hci_conn *conn; 285241a96212SMarcel Holtmann 2853a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 285441a96212SMarcel Holtmann 285541a96212SMarcel Holtmann hci_dev_lock(hdev); 285641a96212SMarcel Holtmann 285741a96212SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2858ccd556feSJohan Hedberg if (!conn) 2859ccd556feSJohan Hedberg goto unlock; 2860ccd556feSJohan Hedberg 2861769be974SMarcel Holtmann if (!ev->status && ev->page == 0x01) { 286241a96212SMarcel Holtmann struct inquiry_entry *ie; 286341a96212SMarcel Holtmann 2864cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 2865cc11b9c1SAndrei Emeltchenko if (ie) 286602b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 286741a96212SMarcel Holtmann 286802b7cc62SJohan Hedberg if (ev->features[0] & LMP_HOST_SSP) 286958a681efSJohan Hedberg set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 287041a96212SMarcel Holtmann } 287141a96212SMarcel Holtmann 2872ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 2873ccd556feSJohan Hedberg goto unlock; 2874ccd556feSJohan Hedberg 2875127178d2SJohan Hedberg if (!ev->status) { 2876127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 2877127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 2878127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 2879127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 2880127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 2881b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 2882b644ba33SJohan Hedberg mgmt_device_connected(hdev, &conn->dst, conn->type, 288308c79b61SJohan Hedberg conn->dst_type, 0, NULL, 0, 2884b644ba33SJohan Hedberg conn->dev_class); 2885392599b9SJohan Hedberg 2886127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 2887769be974SMarcel Holtmann conn->state = BT_CONNECTED; 2888769be974SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 2889769be974SMarcel Holtmann hci_conn_put(conn); 2890769be974SMarcel Holtmann } 2891769be974SMarcel Holtmann 2892ccd556feSJohan Hedberg unlock: 289341a96212SMarcel Holtmann hci_dev_unlock(hdev); 2894a9de9248SMarcel Holtmann } 2895a9de9248SMarcel Holtmann 2896a9de9248SMarcel Holtmann static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2897a9de9248SMarcel Holtmann { 2898b6a0dc82SMarcel Holtmann struct hci_ev_sync_conn_complete *ev = (void *) skb->data; 2899b6a0dc82SMarcel Holtmann struct hci_conn *conn; 2900b6a0dc82SMarcel Holtmann 2901b6a0dc82SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 2902b6a0dc82SMarcel Holtmann 2903b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 2904b6a0dc82SMarcel Holtmann 2905b6a0dc82SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 29069dc0a3afSMarcel Holtmann if (!conn) { 29079dc0a3afSMarcel Holtmann if (ev->link_type == ESCO_LINK) 29089dc0a3afSMarcel Holtmann goto unlock; 29099dc0a3afSMarcel Holtmann 29109dc0a3afSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 2911b6a0dc82SMarcel Holtmann if (!conn) 2912b6a0dc82SMarcel Holtmann goto unlock; 2913b6a0dc82SMarcel Holtmann 29149dc0a3afSMarcel Holtmann conn->type = SCO_LINK; 29159dc0a3afSMarcel Holtmann } 29169dc0a3afSMarcel Holtmann 2917732547f9SMarcel Holtmann switch (ev->status) { 2918732547f9SMarcel Holtmann case 0x00: 2919732547f9SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 2920732547f9SMarcel Holtmann conn->state = BT_CONNECTED; 2921732547f9SMarcel Holtmann 29229eba32b8SMarcel Holtmann hci_conn_hold_device(conn); 2923732547f9SMarcel Holtmann hci_conn_add_sysfs(conn); 2924732547f9SMarcel Holtmann break; 2925732547f9SMarcel Holtmann 2926705e5711SStephen Coe case 0x11: /* Unsupported Feature or Parameter Value */ 2927732547f9SMarcel Holtmann case 0x1c: /* SCO interval rejected */ 29281038a00bSNick Pelly case 0x1a: /* Unsupported Remote Feature */ 2929732547f9SMarcel Holtmann case 0x1f: /* Unspecified error */ 2930732547f9SMarcel Holtmann if (conn->out && conn->attempt < 2) { 2931efc7688bSMarcel Holtmann conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | 2932efc7688bSMarcel Holtmann (hdev->esco_type & EDR_ESCO_MASK); 2933efc7688bSMarcel Holtmann hci_setup_sync(conn, conn->link->handle); 2934efc7688bSMarcel Holtmann goto unlock; 2935efc7688bSMarcel Holtmann } 2936732547f9SMarcel Holtmann /* fall through */ 2937efc7688bSMarcel Holtmann 2938732547f9SMarcel Holtmann default: 2939b6a0dc82SMarcel Holtmann conn->state = BT_CLOSED; 2940732547f9SMarcel Holtmann break; 2941732547f9SMarcel Holtmann } 2942b6a0dc82SMarcel Holtmann 2943b6a0dc82SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 2944b6a0dc82SMarcel Holtmann if (ev->status) 2945b6a0dc82SMarcel Holtmann hci_conn_del(conn); 2946b6a0dc82SMarcel Holtmann 2947b6a0dc82SMarcel Holtmann unlock: 2948b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 2949a9de9248SMarcel Holtmann } 2950a9de9248SMarcel Holtmann 2951a9de9248SMarcel Holtmann static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb) 2952a9de9248SMarcel Holtmann { 2953a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2954a9de9248SMarcel Holtmann } 2955a9de9248SMarcel Holtmann 295604837f64SMarcel Holtmann static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb) 295704837f64SMarcel Holtmann { 2958a9de9248SMarcel Holtmann struct hci_ev_sniff_subrate *ev = (void *) skb->data; 295904837f64SMarcel Holtmann 296004837f64SMarcel Holtmann BT_DBG("%s status %d", hdev->name, ev->status); 296104837f64SMarcel Holtmann } 296204837f64SMarcel Holtmann 2963a9de9248SMarcel Holtmann static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) 2964a9de9248SMarcel Holtmann { 2965a9de9248SMarcel Holtmann struct inquiry_data data; 2966a9de9248SMarcel Holtmann struct extended_inquiry_info *info = (void *) (skb->data + 1); 2967a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 2968a9de9248SMarcel Holtmann 2969a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 2970a9de9248SMarcel Holtmann 2971a9de9248SMarcel Holtmann if (!num_rsp) 2972a9de9248SMarcel Holtmann return; 2973a9de9248SMarcel Holtmann 2974a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2975a9de9248SMarcel Holtmann 2976e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 2977388fc8faSJohan Hedberg bool name_known, ssp; 2978561aafbcSJohan Hedberg 2979a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 2980a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 2981a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 2982a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 2983a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 2984a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 2985a9de9248SMarcel Holtmann data.rssi = info->rssi; 298641a96212SMarcel Holtmann data.ssp_mode = 0x01; 2987561aafbcSJohan Hedberg 2988a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 29894ddb1930SJohan Hedberg name_known = eir_has_data_type(info->data, 29904ddb1930SJohan Hedberg sizeof(info->data), 29914ddb1930SJohan Hedberg EIR_NAME_COMPLETE); 2992561aafbcSJohan Hedberg else 2993561aafbcSJohan Hedberg name_known = true; 2994561aafbcSJohan Hedberg 2995388fc8faSJohan Hedberg name_known = hci_inquiry_cache_update(hdev, &data, name_known, 2996388fc8faSJohan Hedberg &ssp); 299748264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 299804124681SGustavo F. Padovan info->dev_class, info->rssi, !name_known, 299904124681SGustavo F. Padovan ssp, info->data, sizeof(info->data)); 3000a9de9248SMarcel Holtmann } 3001a9de9248SMarcel Holtmann 3002a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3003a9de9248SMarcel Holtmann } 3004a9de9248SMarcel Holtmann 300517fa4b9dSJohan Hedberg static inline u8 hci_get_auth_req(struct hci_conn *conn) 300617fa4b9dSJohan Hedberg { 300717fa4b9dSJohan Hedberg /* If remote requests dedicated bonding follow that lead */ 300817fa4b9dSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) { 300917fa4b9dSJohan Hedberg /* If both remote and local IO capabilities allow MITM 301017fa4b9dSJohan Hedberg * protection then require it, otherwise don't */ 301117fa4b9dSJohan Hedberg if (conn->remote_cap == 0x03 || conn->io_capability == 0x03) 301217fa4b9dSJohan Hedberg return 0x02; 301317fa4b9dSJohan Hedberg else 301417fa4b9dSJohan Hedberg return 0x03; 301517fa4b9dSJohan Hedberg } 301617fa4b9dSJohan Hedberg 301717fa4b9dSJohan Hedberg /* If remote requests no-bonding follow that lead */ 301817fa4b9dSJohan Hedberg if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01) 301958797bf7SWaldemar Rymarkiewicz return conn->remote_auth | (conn->auth_type & 0x01); 302017fa4b9dSJohan Hedberg 302117fa4b9dSJohan Hedberg return conn->auth_type; 302217fa4b9dSJohan Hedberg } 302317fa4b9dSJohan Hedberg 30240493684eSMarcel Holtmann static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 30250493684eSMarcel Holtmann { 30260493684eSMarcel Holtmann struct hci_ev_io_capa_request *ev = (void *) skb->data; 30270493684eSMarcel Holtmann struct hci_conn *conn; 30280493684eSMarcel Holtmann 30290493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 30300493684eSMarcel Holtmann 30310493684eSMarcel Holtmann hci_dev_lock(hdev); 30320493684eSMarcel Holtmann 30330493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 303403b555e1SJohan Hedberg if (!conn) 303503b555e1SJohan Hedberg goto unlock; 303603b555e1SJohan Hedberg 30370493684eSMarcel Holtmann hci_conn_hold(conn); 30380493684eSMarcel Holtmann 3039a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 304003b555e1SJohan Hedberg goto unlock; 304103b555e1SJohan Hedberg 3042a8b2d5c2SJohan Hedberg if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) || 304303b555e1SJohan Hedberg (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { 304417fa4b9dSJohan Hedberg struct hci_cp_io_capability_reply cp; 304517fa4b9dSJohan Hedberg 304617fa4b9dSJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 30477a7f1e7cSHemant Gupta /* Change the IO capability from KeyboardDisplay 30487a7f1e7cSHemant Gupta * to DisplayYesNo as it is not supported by BT spec. */ 30497a7f1e7cSHemant Gupta cp.capability = (conn->io_capability == 0x04) ? 30507a7f1e7cSHemant Gupta 0x01 : conn->io_capability; 30517cbc9bd9SJohan Hedberg conn->auth_type = hci_get_auth_req(conn); 30527cbc9bd9SJohan Hedberg cp.authentication = conn->auth_type; 305317fa4b9dSJohan Hedberg 305458a681efSJohan Hedberg if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) && 3055ce85ee13SSzymon Janc hci_find_remote_oob_data(hdev, &conn->dst)) 3056ce85ee13SSzymon Janc cp.oob_data = 0x01; 3057ce85ee13SSzymon Janc else 3058ce85ee13SSzymon Janc cp.oob_data = 0x00; 3059ce85ee13SSzymon Janc 306017fa4b9dSJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY, 306117fa4b9dSJohan Hedberg sizeof(cp), &cp); 306203b555e1SJohan Hedberg } else { 306303b555e1SJohan Hedberg struct hci_cp_io_capability_neg_reply cp; 306403b555e1SJohan Hedberg 306503b555e1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 30669f5a0d7bSAndrei Emeltchenko cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED; 306703b555e1SJohan Hedberg 306803b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, 306903b555e1SJohan Hedberg sizeof(cp), &cp); 307003b555e1SJohan Hedberg } 307103b555e1SJohan Hedberg 307203b555e1SJohan Hedberg unlock: 307303b555e1SJohan Hedberg hci_dev_unlock(hdev); 307403b555e1SJohan Hedberg } 307503b555e1SJohan Hedberg 307603b555e1SJohan Hedberg static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) 307703b555e1SJohan Hedberg { 307803b555e1SJohan Hedberg struct hci_ev_io_capa_reply *ev = (void *) skb->data; 307903b555e1SJohan Hedberg struct hci_conn *conn; 308003b555e1SJohan Hedberg 308103b555e1SJohan Hedberg BT_DBG("%s", hdev->name); 308203b555e1SJohan Hedberg 308303b555e1SJohan Hedberg hci_dev_lock(hdev); 308403b555e1SJohan Hedberg 308503b555e1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 308603b555e1SJohan Hedberg if (!conn) 308703b555e1SJohan Hedberg goto unlock; 308803b555e1SJohan Hedberg 308903b555e1SJohan Hedberg conn->remote_cap = ev->capability; 309003b555e1SJohan Hedberg conn->remote_auth = ev->authentication; 309158a681efSJohan Hedberg if (ev->oob_data) 309258a681efSJohan Hedberg set_bit(HCI_CONN_REMOTE_OOB, &conn->flags); 309303b555e1SJohan Hedberg 309403b555e1SJohan Hedberg unlock: 30950493684eSMarcel Holtmann hci_dev_unlock(hdev); 30960493684eSMarcel Holtmann } 30970493684eSMarcel Holtmann 3098a5c29683SJohan Hedberg static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, 3099a5c29683SJohan Hedberg struct sk_buff *skb) 3100a5c29683SJohan Hedberg { 3101a5c29683SJohan Hedberg struct hci_ev_user_confirm_req *ev = (void *) skb->data; 310255bc1a37SJohan Hedberg int loc_mitm, rem_mitm, confirm_hint = 0; 31037a828908SJohan Hedberg struct hci_conn *conn; 3104a5c29683SJohan Hedberg 3105a5c29683SJohan Hedberg BT_DBG("%s", hdev->name); 3106a5c29683SJohan Hedberg 3107a5c29683SJohan Hedberg hci_dev_lock(hdev); 3108a5c29683SJohan Hedberg 3109a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 31107a828908SJohan Hedberg goto unlock; 31117a828908SJohan Hedberg 31127a828908SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 31137a828908SJohan Hedberg if (!conn) 31147a828908SJohan Hedberg goto unlock; 31157a828908SJohan Hedberg 31167a828908SJohan Hedberg loc_mitm = (conn->auth_type & 0x01); 31177a828908SJohan Hedberg rem_mitm = (conn->remote_auth & 0x01); 31187a828908SJohan Hedberg 31197a828908SJohan Hedberg /* If we require MITM but the remote device can't provide that 31207a828908SJohan Hedberg * (it has NoInputNoOutput) then reject the confirmation 31217a828908SJohan Hedberg * request. The only exception is when we're dedicated bonding 31227a828908SJohan Hedberg * initiators (connect_cfm_cb set) since then we always have the MITM 31237a828908SJohan Hedberg * bit set. */ 31247a828908SJohan Hedberg if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) { 31257a828908SJohan Hedberg BT_DBG("Rejecting request: remote device can't provide MITM"); 31267a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY, 31277a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 31287a828908SJohan Hedberg goto unlock; 31297a828908SJohan Hedberg } 31307a828908SJohan Hedberg 31317a828908SJohan Hedberg /* If no side requires MITM protection; auto-accept */ 31327a828908SJohan Hedberg if ((!loc_mitm || conn->remote_cap == 0x03) && 31337a828908SJohan Hedberg (!rem_mitm || conn->io_capability == 0x03)) { 313455bc1a37SJohan Hedberg 313555bc1a37SJohan Hedberg /* If we're not the initiators request authorization to 313655bc1a37SJohan Hedberg * proceed from user space (mgmt_user_confirm with 313755bc1a37SJohan Hedberg * confirm_hint set to 1). */ 313851a8efd7SJohan Hedberg if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 313955bc1a37SJohan Hedberg BT_DBG("Confirming auto-accept as acceptor"); 314055bc1a37SJohan Hedberg confirm_hint = 1; 314155bc1a37SJohan Hedberg goto confirm; 314255bc1a37SJohan Hedberg } 314355bc1a37SJohan Hedberg 31449f61656aSJohan Hedberg BT_DBG("Auto-accept of user confirmation with %ums delay", 31459f61656aSJohan Hedberg hdev->auto_accept_delay); 31469f61656aSJohan Hedberg 31479f61656aSJohan Hedberg if (hdev->auto_accept_delay > 0) { 31489f61656aSJohan Hedberg int delay = msecs_to_jiffies(hdev->auto_accept_delay); 31499f61656aSJohan Hedberg mod_timer(&conn->auto_accept_timer, jiffies + delay); 31509f61656aSJohan Hedberg goto unlock; 31519f61656aSJohan Hedberg } 31529f61656aSJohan Hedberg 31537a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, 31547a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 31557a828908SJohan Hedberg goto unlock; 31567a828908SJohan Hedberg } 31577a828908SJohan Hedberg 315855bc1a37SJohan Hedberg confirm: 3159272d90dfSJohan Hedberg mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey, 316055bc1a37SJohan Hedberg confirm_hint); 3161a5c29683SJohan Hedberg 31627a828908SJohan Hedberg unlock: 3163a5c29683SJohan Hedberg hci_dev_unlock(hdev); 3164a5c29683SJohan Hedberg } 3165a5c29683SJohan Hedberg 31661143d458SBrian Gix static inline void hci_user_passkey_request_evt(struct hci_dev *hdev, 31671143d458SBrian Gix struct sk_buff *skb) 31681143d458SBrian Gix { 31691143d458SBrian Gix struct hci_ev_user_passkey_req *ev = (void *) skb->data; 31701143d458SBrian Gix 31711143d458SBrian Gix BT_DBG("%s", hdev->name); 31721143d458SBrian Gix 31731143d458SBrian Gix hci_dev_lock(hdev); 31741143d458SBrian Gix 3175a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 3176272d90dfSJohan Hedberg mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); 31771143d458SBrian Gix 31781143d458SBrian Gix hci_dev_unlock(hdev); 31791143d458SBrian Gix } 31801143d458SBrian Gix 31810493684eSMarcel Holtmann static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 31820493684eSMarcel Holtmann { 31830493684eSMarcel Holtmann struct hci_ev_simple_pair_complete *ev = (void *) skb->data; 31840493684eSMarcel Holtmann struct hci_conn *conn; 31850493684eSMarcel Holtmann 31860493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 31870493684eSMarcel Holtmann 31880493684eSMarcel Holtmann hci_dev_lock(hdev); 31890493684eSMarcel Holtmann 31900493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 31912a611692SJohan Hedberg if (!conn) 31922a611692SJohan Hedberg goto unlock; 31932a611692SJohan Hedberg 31942a611692SJohan Hedberg /* To avoid duplicate auth_failed events to user space we check 31952a611692SJohan Hedberg * the HCI_CONN_AUTH_PEND flag which will be set if we 31962a611692SJohan Hedberg * initiated the authentication. A traditional auth_complete 31972a611692SJohan Hedberg * event gets always produced as initiator and is also mapped to 31982a611692SJohan Hedberg * the mgmt_auth_failed event */ 319951a8efd7SJohan Hedberg if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0) 3200bab73cb6SJohan Hedberg mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, 3201bab73cb6SJohan Hedberg ev->status); 32022a611692SJohan Hedberg 32030493684eSMarcel Holtmann hci_conn_put(conn); 32040493684eSMarcel Holtmann 32052a611692SJohan Hedberg unlock: 32060493684eSMarcel Holtmann hci_dev_unlock(hdev); 32070493684eSMarcel Holtmann } 32080493684eSMarcel Holtmann 320941a96212SMarcel Holtmann static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb) 321041a96212SMarcel Holtmann { 321141a96212SMarcel Holtmann struct hci_ev_remote_host_features *ev = (void *) skb->data; 321241a96212SMarcel Holtmann struct inquiry_entry *ie; 321341a96212SMarcel Holtmann 321441a96212SMarcel Holtmann BT_DBG("%s", hdev->name); 321541a96212SMarcel Holtmann 321641a96212SMarcel Holtmann hci_dev_lock(hdev); 321741a96212SMarcel Holtmann 3218cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 3219cc11b9c1SAndrei Emeltchenko if (ie) 322002b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 322141a96212SMarcel Holtmann 322241a96212SMarcel Holtmann hci_dev_unlock(hdev); 322341a96212SMarcel Holtmann } 322441a96212SMarcel Holtmann 32252763eda6SSzymon Janc static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev, 32262763eda6SSzymon Janc struct sk_buff *skb) 32272763eda6SSzymon Janc { 32282763eda6SSzymon Janc struct hci_ev_remote_oob_data_request *ev = (void *) skb->data; 32292763eda6SSzymon Janc struct oob_data *data; 32302763eda6SSzymon Janc 32312763eda6SSzymon Janc BT_DBG("%s", hdev->name); 32322763eda6SSzymon Janc 32332763eda6SSzymon Janc hci_dev_lock(hdev); 32342763eda6SSzymon Janc 3235a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 3236e1ba1f15SSzymon Janc goto unlock; 3237e1ba1f15SSzymon Janc 32382763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, &ev->bdaddr); 32392763eda6SSzymon Janc if (data) { 32402763eda6SSzymon Janc struct hci_cp_remote_oob_data_reply cp; 32412763eda6SSzymon Janc 32422763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr); 32432763eda6SSzymon Janc memcpy(cp.hash, data->hash, sizeof(cp.hash)); 32442763eda6SSzymon Janc memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer)); 32452763eda6SSzymon Janc 32462763eda6SSzymon Janc hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp), 32472763eda6SSzymon Janc &cp); 32482763eda6SSzymon Janc } else { 32492763eda6SSzymon Janc struct hci_cp_remote_oob_data_neg_reply cp; 32502763eda6SSzymon Janc 32512763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr); 32522763eda6SSzymon Janc hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp), 32532763eda6SSzymon Janc &cp); 32542763eda6SSzymon Janc } 32552763eda6SSzymon Janc 3256e1ba1f15SSzymon Janc unlock: 32572763eda6SSzymon Janc hci_dev_unlock(hdev); 32582763eda6SSzymon Janc } 32592763eda6SSzymon Janc 3260fcd89c09SVille Tervo static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 3261fcd89c09SVille Tervo { 3262fcd89c09SVille Tervo struct hci_ev_le_conn_complete *ev = (void *) skb->data; 3263fcd89c09SVille Tervo struct hci_conn *conn; 3264fcd89c09SVille Tervo 3265fcd89c09SVille Tervo BT_DBG("%s status %d", hdev->name, ev->status); 3266fcd89c09SVille Tervo 3267fcd89c09SVille Tervo hci_dev_lock(hdev); 3268fcd89c09SVille Tervo 3269fcd89c09SVille Tervo conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr); 3270b62f328bSVille Tervo if (!conn) { 3271b62f328bSVille Tervo conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr); 3272b62f328bSVille Tervo if (!conn) { 3273b62f328bSVille Tervo BT_ERR("No memory for new connection"); 3274b62f328bSVille Tervo hci_dev_unlock(hdev); 3275b62f328bSVille Tervo return; 3276b62f328bSVille Tervo } 327729b7988aSAndre Guedes 327829b7988aSAndre Guedes conn->dst_type = ev->bdaddr_type; 3279b62f328bSVille Tervo } 3280fcd89c09SVille Tervo 3281fcd89c09SVille Tervo if (ev->status) { 328248264f06SJohan Hedberg mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, 328348264f06SJohan Hedberg conn->dst_type, ev->status); 3284fcd89c09SVille Tervo hci_proto_connect_cfm(conn, ev->status); 3285fcd89c09SVille Tervo conn->state = BT_CLOSED; 3286fcd89c09SVille Tervo hci_conn_del(conn); 3287fcd89c09SVille Tervo goto unlock; 3288fcd89c09SVille Tervo } 3289fcd89c09SVille Tervo 3290b644ba33SJohan Hedberg if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 3291b644ba33SJohan Hedberg mgmt_device_connected(hdev, &ev->bdaddr, conn->type, 329295b23582SSzymon Janc conn->dst_type, 0, NULL, 0, NULL); 329383bc71b4SVinicius Costa Gomes 32947b5c0d52SVinicius Costa Gomes conn->sec_level = BT_SECURITY_LOW; 3295fcd89c09SVille Tervo conn->handle = __le16_to_cpu(ev->handle); 3296fcd89c09SVille Tervo conn->state = BT_CONNECTED; 3297fcd89c09SVille Tervo 3298fcd89c09SVille Tervo hci_conn_hold_device(conn); 3299fcd89c09SVille Tervo hci_conn_add_sysfs(conn); 3300fcd89c09SVille Tervo 3301fcd89c09SVille Tervo hci_proto_connect_cfm(conn, ev->status); 3302fcd89c09SVille Tervo 3303fcd89c09SVille Tervo unlock: 3304fcd89c09SVille Tervo hci_dev_unlock(hdev); 3305fcd89c09SVille Tervo } 3306fcd89c09SVille Tervo 33079aa04c91SAndre Guedes static inline void hci_le_adv_report_evt(struct hci_dev *hdev, 33089aa04c91SAndre Guedes struct sk_buff *skb) 33099aa04c91SAndre Guedes { 3310e95beb41SAndre Guedes u8 num_reports = skb->data[0]; 3311e95beb41SAndre Guedes void *ptr = &skb->data[1]; 33123c9e9195SAndre Guedes s8 rssi; 33139aa04c91SAndre Guedes 33149aa04c91SAndre Guedes hci_dev_lock(hdev); 33159aa04c91SAndre Guedes 3316e95beb41SAndre Guedes while (num_reports--) { 3317e95beb41SAndre Guedes struct hci_ev_le_advertising_info *ev = ptr; 3318e95beb41SAndre Guedes 33199aa04c91SAndre Guedes hci_add_adv_entry(hdev, ev); 33209aa04c91SAndre Guedes 33213c9e9195SAndre Guedes rssi = ev->data[ev->length]; 33223c9e9195SAndre Guedes mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type, 332304124681SGustavo F. Padovan NULL, rssi, 0, 1, ev->data, ev->length); 33243c9e9195SAndre Guedes 3325e95beb41SAndre Guedes ptr += sizeof(*ev) + ev->length + 1; 33269aa04c91SAndre Guedes } 33279aa04c91SAndre Guedes 33289aa04c91SAndre Guedes hci_dev_unlock(hdev); 33299aa04c91SAndre Guedes } 33309aa04c91SAndre Guedes 3331a7a595f6SVinicius Costa Gomes static inline void hci_le_ltk_request_evt(struct hci_dev *hdev, 3332a7a595f6SVinicius Costa Gomes struct sk_buff *skb) 3333a7a595f6SVinicius Costa Gomes { 3334a7a595f6SVinicius Costa Gomes struct hci_ev_le_ltk_req *ev = (void *) skb->data; 3335a7a595f6SVinicius Costa Gomes struct hci_cp_le_ltk_reply cp; 3336bea710feSVinicius Costa Gomes struct hci_cp_le_ltk_neg_reply neg; 3337a7a595f6SVinicius Costa Gomes struct hci_conn *conn; 3338c9839a11SVinicius Costa Gomes struct smp_ltk *ltk; 3339a7a595f6SVinicius Costa Gomes 3340e4666881SAndrei Emeltchenko BT_DBG("%s handle %d", hdev->name, __le16_to_cpu(ev->handle)); 3341a7a595f6SVinicius Costa Gomes 3342a7a595f6SVinicius Costa Gomes hci_dev_lock(hdev); 3343a7a595f6SVinicius Costa Gomes 3344a7a595f6SVinicius Costa Gomes conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3345bea710feSVinicius Costa Gomes if (conn == NULL) 3346bea710feSVinicius Costa Gomes goto not_found; 3347a7a595f6SVinicius Costa Gomes 3348bea710feSVinicius Costa Gomes ltk = hci_find_ltk(hdev, ev->ediv, ev->random); 3349bea710feSVinicius Costa Gomes if (ltk == NULL) 3350bea710feSVinicius Costa Gomes goto not_found; 3351bea710feSVinicius Costa Gomes 3352bea710feSVinicius Costa Gomes memcpy(cp.ltk, ltk->val, sizeof(ltk->val)); 3353a7a595f6SVinicius Costa Gomes cp.handle = cpu_to_le16(conn->handle); 3354c9839a11SVinicius Costa Gomes 3355c9839a11SVinicius Costa Gomes if (ltk->authenticated) 3356c9839a11SVinicius Costa Gomes conn->sec_level = BT_SECURITY_HIGH; 3357a7a595f6SVinicius Costa Gomes 3358a7a595f6SVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); 3359a7a595f6SVinicius Costa Gomes 3360c9839a11SVinicius Costa Gomes if (ltk->type & HCI_SMP_STK) { 3361c9839a11SVinicius Costa Gomes list_del(<k->list); 3362c9839a11SVinicius Costa Gomes kfree(ltk); 3363c9839a11SVinicius Costa Gomes } 3364c9839a11SVinicius Costa Gomes 3365a7a595f6SVinicius Costa Gomes hci_dev_unlock(hdev); 3366bea710feSVinicius Costa Gomes 3367bea710feSVinicius Costa Gomes return; 3368bea710feSVinicius Costa Gomes 3369bea710feSVinicius Costa Gomes not_found: 3370bea710feSVinicius Costa Gomes neg.handle = ev->handle; 3371bea710feSVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg); 3372bea710feSVinicius Costa Gomes hci_dev_unlock(hdev); 3373a7a595f6SVinicius Costa Gomes } 3374a7a595f6SVinicius Costa Gomes 3375fcd89c09SVille Tervo static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) 3376fcd89c09SVille Tervo { 3377fcd89c09SVille Tervo struct hci_ev_le_meta *le_ev = (void *) skb->data; 3378fcd89c09SVille Tervo 3379fcd89c09SVille Tervo skb_pull(skb, sizeof(*le_ev)); 3380fcd89c09SVille Tervo 3381fcd89c09SVille Tervo switch (le_ev->subevent) { 3382fcd89c09SVille Tervo case HCI_EV_LE_CONN_COMPLETE: 3383fcd89c09SVille Tervo hci_le_conn_complete_evt(hdev, skb); 3384fcd89c09SVille Tervo break; 3385fcd89c09SVille Tervo 33869aa04c91SAndre Guedes case HCI_EV_LE_ADVERTISING_REPORT: 33879aa04c91SAndre Guedes hci_le_adv_report_evt(hdev, skb); 33889aa04c91SAndre Guedes break; 33899aa04c91SAndre Guedes 3390a7a595f6SVinicius Costa Gomes case HCI_EV_LE_LTK_REQ: 3391a7a595f6SVinicius Costa Gomes hci_le_ltk_request_evt(hdev, skb); 3392a7a595f6SVinicius Costa Gomes break; 3393a7a595f6SVinicius Costa Gomes 3394fcd89c09SVille Tervo default: 3395fcd89c09SVille Tervo break; 3396fcd89c09SVille Tervo } 3397fcd89c09SVille Tervo } 3398fcd89c09SVille Tervo 33991da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) 34001da177e4SLinus Torvalds { 3401a9de9248SMarcel Holtmann struct hci_event_hdr *hdr = (void *) skb->data; 3402a9de9248SMarcel Holtmann __u8 event = hdr->evt; 34031da177e4SLinus Torvalds 34041da177e4SLinus Torvalds skb_pull(skb, HCI_EVENT_HDR_SIZE); 34051da177e4SLinus Torvalds 3406a9de9248SMarcel Holtmann switch (event) { 34071da177e4SLinus Torvalds case HCI_EV_INQUIRY_COMPLETE: 34081da177e4SLinus Torvalds hci_inquiry_complete_evt(hdev, skb); 34091da177e4SLinus Torvalds break; 34101da177e4SLinus Torvalds 34111da177e4SLinus Torvalds case HCI_EV_INQUIRY_RESULT: 34121da177e4SLinus Torvalds hci_inquiry_result_evt(hdev, skb); 34131da177e4SLinus Torvalds break; 34141da177e4SLinus Torvalds 3415a9de9248SMarcel Holtmann case HCI_EV_CONN_COMPLETE: 3416a9de9248SMarcel Holtmann hci_conn_complete_evt(hdev, skb); 341721d9e30eSMarcel Holtmann break; 341821d9e30eSMarcel Holtmann 34191da177e4SLinus Torvalds case HCI_EV_CONN_REQUEST: 34201da177e4SLinus Torvalds hci_conn_request_evt(hdev, skb); 34211da177e4SLinus Torvalds break; 34221da177e4SLinus Torvalds 34231da177e4SLinus Torvalds case HCI_EV_DISCONN_COMPLETE: 34241da177e4SLinus Torvalds hci_disconn_complete_evt(hdev, skb); 34251da177e4SLinus Torvalds break; 34261da177e4SLinus Torvalds 34271da177e4SLinus Torvalds case HCI_EV_AUTH_COMPLETE: 34281da177e4SLinus Torvalds hci_auth_complete_evt(hdev, skb); 34291da177e4SLinus Torvalds break; 34301da177e4SLinus Torvalds 3431a9de9248SMarcel Holtmann case HCI_EV_REMOTE_NAME: 3432a9de9248SMarcel Holtmann hci_remote_name_evt(hdev, skb); 3433a9de9248SMarcel Holtmann break; 3434a9de9248SMarcel Holtmann 34351da177e4SLinus Torvalds case HCI_EV_ENCRYPT_CHANGE: 34361da177e4SLinus Torvalds hci_encrypt_change_evt(hdev, skb); 34371da177e4SLinus Torvalds break; 34381da177e4SLinus Torvalds 3439a9de9248SMarcel Holtmann case HCI_EV_CHANGE_LINK_KEY_COMPLETE: 3440a9de9248SMarcel Holtmann hci_change_link_key_complete_evt(hdev, skb); 3441a9de9248SMarcel Holtmann break; 3442a9de9248SMarcel Holtmann 3443a9de9248SMarcel Holtmann case HCI_EV_REMOTE_FEATURES: 3444a9de9248SMarcel Holtmann hci_remote_features_evt(hdev, skb); 3445a9de9248SMarcel Holtmann break; 3446a9de9248SMarcel Holtmann 3447a9de9248SMarcel Holtmann case HCI_EV_REMOTE_VERSION: 3448a9de9248SMarcel Holtmann hci_remote_version_evt(hdev, skb); 3449a9de9248SMarcel Holtmann break; 3450a9de9248SMarcel Holtmann 3451a9de9248SMarcel Holtmann case HCI_EV_QOS_SETUP_COMPLETE: 3452a9de9248SMarcel Holtmann hci_qos_setup_complete_evt(hdev, skb); 3453a9de9248SMarcel Holtmann break; 3454a9de9248SMarcel Holtmann 3455a9de9248SMarcel Holtmann case HCI_EV_CMD_COMPLETE: 3456a9de9248SMarcel Holtmann hci_cmd_complete_evt(hdev, skb); 3457a9de9248SMarcel Holtmann break; 3458a9de9248SMarcel Holtmann 3459a9de9248SMarcel Holtmann case HCI_EV_CMD_STATUS: 3460a9de9248SMarcel Holtmann hci_cmd_status_evt(hdev, skb); 3461a9de9248SMarcel Holtmann break; 3462a9de9248SMarcel Holtmann 3463a9de9248SMarcel Holtmann case HCI_EV_ROLE_CHANGE: 3464a9de9248SMarcel Holtmann hci_role_change_evt(hdev, skb); 3465a9de9248SMarcel Holtmann break; 3466a9de9248SMarcel Holtmann 3467a9de9248SMarcel Holtmann case HCI_EV_NUM_COMP_PKTS: 3468a9de9248SMarcel Holtmann hci_num_comp_pkts_evt(hdev, skb); 3469a9de9248SMarcel Holtmann break; 3470a9de9248SMarcel Holtmann 3471a9de9248SMarcel Holtmann case HCI_EV_MODE_CHANGE: 3472a9de9248SMarcel Holtmann hci_mode_change_evt(hdev, skb); 34731da177e4SLinus Torvalds break; 34741da177e4SLinus Torvalds 34751da177e4SLinus Torvalds case HCI_EV_PIN_CODE_REQ: 34761da177e4SLinus Torvalds hci_pin_code_request_evt(hdev, skb); 34771da177e4SLinus Torvalds break; 34781da177e4SLinus Torvalds 34791da177e4SLinus Torvalds case HCI_EV_LINK_KEY_REQ: 34801da177e4SLinus Torvalds hci_link_key_request_evt(hdev, skb); 34811da177e4SLinus Torvalds break; 34821da177e4SLinus Torvalds 34831da177e4SLinus Torvalds case HCI_EV_LINK_KEY_NOTIFY: 34841da177e4SLinus Torvalds hci_link_key_notify_evt(hdev, skb); 34851da177e4SLinus Torvalds break; 34861da177e4SLinus Torvalds 34871da177e4SLinus Torvalds case HCI_EV_CLOCK_OFFSET: 34881da177e4SLinus Torvalds hci_clock_offset_evt(hdev, skb); 34891da177e4SLinus Torvalds break; 34901da177e4SLinus Torvalds 3491a8746417SMarcel Holtmann case HCI_EV_PKT_TYPE_CHANGE: 3492a8746417SMarcel Holtmann hci_pkt_type_change_evt(hdev, skb); 3493a8746417SMarcel Holtmann break; 3494a8746417SMarcel Holtmann 349585a1e930SMarcel Holtmann case HCI_EV_PSCAN_REP_MODE: 349685a1e930SMarcel Holtmann hci_pscan_rep_mode_evt(hdev, skb); 349785a1e930SMarcel Holtmann break; 349885a1e930SMarcel Holtmann 3499a9de9248SMarcel Holtmann case HCI_EV_INQUIRY_RESULT_WITH_RSSI: 3500a9de9248SMarcel Holtmann hci_inquiry_result_with_rssi_evt(hdev, skb); 3501a9de9248SMarcel Holtmann break; 3502a9de9248SMarcel Holtmann 3503a9de9248SMarcel Holtmann case HCI_EV_REMOTE_EXT_FEATURES: 3504a9de9248SMarcel Holtmann hci_remote_ext_features_evt(hdev, skb); 3505a9de9248SMarcel Holtmann break; 3506a9de9248SMarcel Holtmann 3507a9de9248SMarcel Holtmann case HCI_EV_SYNC_CONN_COMPLETE: 3508a9de9248SMarcel Holtmann hci_sync_conn_complete_evt(hdev, skb); 3509a9de9248SMarcel Holtmann break; 3510a9de9248SMarcel Holtmann 3511a9de9248SMarcel Holtmann case HCI_EV_SYNC_CONN_CHANGED: 3512a9de9248SMarcel Holtmann hci_sync_conn_changed_evt(hdev, skb); 3513a9de9248SMarcel Holtmann break; 3514a9de9248SMarcel Holtmann 351504837f64SMarcel Holtmann case HCI_EV_SNIFF_SUBRATE: 351604837f64SMarcel Holtmann hci_sniff_subrate_evt(hdev, skb); 351704837f64SMarcel Holtmann break; 351804837f64SMarcel Holtmann 3519a9de9248SMarcel Holtmann case HCI_EV_EXTENDED_INQUIRY_RESULT: 3520a9de9248SMarcel Holtmann hci_extended_inquiry_result_evt(hdev, skb); 35211da177e4SLinus Torvalds break; 35221da177e4SLinus Torvalds 35230493684eSMarcel Holtmann case HCI_EV_IO_CAPA_REQUEST: 35240493684eSMarcel Holtmann hci_io_capa_request_evt(hdev, skb); 35250493684eSMarcel Holtmann break; 35260493684eSMarcel Holtmann 352703b555e1SJohan Hedberg case HCI_EV_IO_CAPA_REPLY: 352803b555e1SJohan Hedberg hci_io_capa_reply_evt(hdev, skb); 352903b555e1SJohan Hedberg break; 353003b555e1SJohan Hedberg 3531a5c29683SJohan Hedberg case HCI_EV_USER_CONFIRM_REQUEST: 3532a5c29683SJohan Hedberg hci_user_confirm_request_evt(hdev, skb); 3533a5c29683SJohan Hedberg break; 3534a5c29683SJohan Hedberg 35351143d458SBrian Gix case HCI_EV_USER_PASSKEY_REQUEST: 35361143d458SBrian Gix hci_user_passkey_request_evt(hdev, skb); 35371143d458SBrian Gix break; 35381143d458SBrian Gix 35390493684eSMarcel Holtmann case HCI_EV_SIMPLE_PAIR_COMPLETE: 35400493684eSMarcel Holtmann hci_simple_pair_complete_evt(hdev, skb); 35410493684eSMarcel Holtmann break; 35420493684eSMarcel Holtmann 354341a96212SMarcel Holtmann case HCI_EV_REMOTE_HOST_FEATURES: 354441a96212SMarcel Holtmann hci_remote_host_features_evt(hdev, skb); 354541a96212SMarcel Holtmann break; 354641a96212SMarcel Holtmann 3547fcd89c09SVille Tervo case HCI_EV_LE_META: 3548fcd89c09SVille Tervo hci_le_meta_evt(hdev, skb); 3549fcd89c09SVille Tervo break; 3550fcd89c09SVille Tervo 35512763eda6SSzymon Janc case HCI_EV_REMOTE_OOB_DATA_REQUEST: 35522763eda6SSzymon Janc hci_remote_oob_data_request_evt(hdev, skb); 35532763eda6SSzymon Janc break; 35542763eda6SSzymon Janc 355525e89e99SAndrei Emeltchenko case HCI_EV_NUM_COMP_BLOCKS: 355625e89e99SAndrei Emeltchenko hci_num_comp_blocks_evt(hdev, skb); 355725e89e99SAndrei Emeltchenko break; 355825e89e99SAndrei Emeltchenko 35591da177e4SLinus Torvalds default: 3560a9de9248SMarcel Holtmann BT_DBG("%s event 0x%x", hdev->name, event); 35611da177e4SLinus Torvalds break; 35621da177e4SLinus Torvalds } 35631da177e4SLinus Torvalds 35641da177e4SLinus Torvalds kfree_skb(skb); 35651da177e4SLinus Torvalds hdev->stat.evt_rx++; 35661da177e4SLinus Torvalds } 3567