11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds BlueZ - Bluetooth protocol stack for Linux 32d0a0346SRon Shaffer Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved. 41da177e4SLinus Torvalds 51da177e4SLinus Torvalds Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 61da177e4SLinus Torvalds 71da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify 81da177e4SLinus Torvalds it under the terms of the GNU General Public License version 2 as 91da177e4SLinus Torvalds published by the Free Software Foundation; 101da177e4SLinus Torvalds 111da177e4SLinus Torvalds THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 121da177e4SLinus Torvalds OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 131da177e4SLinus Torvalds FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 141da177e4SLinus Torvalds IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 151da177e4SLinus Torvalds CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 161da177e4SLinus Torvalds WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 171da177e4SLinus Torvalds ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 181da177e4SLinus Torvalds OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 211da177e4SLinus Torvalds COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 221da177e4SLinus Torvalds SOFTWARE IS DISCLAIMED. 231da177e4SLinus Torvalds */ 241da177e4SLinus Torvalds 251da177e4SLinus Torvalds /* Bluetooth HCI event handling. */ 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds #include <asm/unaligned.h> 281da177e4SLinus Torvalds 291da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 301da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 31f0d6a0eaSMikel Astiz #include <net/bluetooth/mgmt.h> 327ef9fbf0SMarcel Holtmann 337024728eSMarcel Holtmann #include "a2mp.h" 347ef9fbf0SMarcel Holtmann #include "amp.h" 351da177e4SLinus Torvalds 361da177e4SLinus Torvalds /* Handle HCI Event packets */ 371da177e4SLinus Torvalds 38a9de9248SMarcel Holtmann static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) 391da177e4SLinus Torvalds { 40a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 411da177e4SLinus Torvalds 429f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 431da177e4SLinus Torvalds 4482f4785cSAndre Guedes if (status) 45a9de9248SMarcel Holtmann return; 461da177e4SLinus Torvalds 4789352e7dSAndre Guedes clear_bit(HCI_INQUIRY, &hdev->flags); 483e13fa1eSAndre Guedes smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */ 493e13fa1eSAndre Guedes wake_up_bit(&hdev->flags, HCI_INQUIRY); 5089352e7dSAndre Guedes 51a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 521da177e4SLinus Torvalds } 536bd57416SMarcel Holtmann 544d93483bSAndre Guedes static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) 554d93483bSAndre Guedes { 564d93483bSAndre Guedes __u8 status = *((__u8 *) skb->data); 574d93483bSAndre Guedes 589f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 59ae854a70SAndre Guedes 60ae854a70SAndre Guedes if (status) 61ae854a70SAndre Guedes return; 62ae854a70SAndre Guedes 63ae854a70SAndre Guedes set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags); 644d93483bSAndre Guedes } 654d93483bSAndre Guedes 66a9de9248SMarcel Holtmann static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) 671da177e4SLinus Torvalds { 68a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 69a9de9248SMarcel Holtmann 709f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 71a9de9248SMarcel Holtmann 72a9de9248SMarcel Holtmann if (status) 73a9de9248SMarcel Holtmann return; 74a9de9248SMarcel Holtmann 75ae854a70SAndre Guedes clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags); 76ae854a70SAndre Guedes 77a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 78a9de9248SMarcel Holtmann } 79a9de9248SMarcel Holtmann 80807deac2SGustavo Padovan static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, 81807deac2SGustavo Padovan struct sk_buff *skb) 82a9de9248SMarcel Holtmann { 83a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 84a9de9248SMarcel Holtmann } 85a9de9248SMarcel Holtmann 86a9de9248SMarcel Holtmann static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb) 87a9de9248SMarcel Holtmann { 88a9de9248SMarcel Holtmann struct hci_rp_role_discovery *rp = (void *) skb->data; 891da177e4SLinus Torvalds struct hci_conn *conn; 901da177e4SLinus Torvalds 919f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 921da177e4SLinus Torvalds 93a9de9248SMarcel Holtmann if (rp->status) 94a9de9248SMarcel Holtmann return; 951da177e4SLinus Torvalds 961da177e4SLinus Torvalds hci_dev_lock(hdev); 971da177e4SLinus Torvalds 98a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 991da177e4SLinus Torvalds if (conn) { 100a9de9248SMarcel Holtmann if (rp->role) 1011da177e4SLinus Torvalds conn->link_mode &= ~HCI_LM_MASTER; 1021da177e4SLinus Torvalds else 1031da177e4SLinus Torvalds conn->link_mode |= HCI_LM_MASTER; 1041da177e4SLinus Torvalds } 1051da177e4SLinus Torvalds 1061da177e4SLinus Torvalds hci_dev_unlock(hdev); 107a9de9248SMarcel Holtmann } 1081da177e4SLinus Torvalds 109e4e8e37cSMarcel Holtmann static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 110e4e8e37cSMarcel Holtmann { 111e4e8e37cSMarcel Holtmann struct hci_rp_read_link_policy *rp = (void *) skb->data; 112e4e8e37cSMarcel Holtmann struct hci_conn *conn; 113e4e8e37cSMarcel Holtmann 1149f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 115e4e8e37cSMarcel Holtmann 116e4e8e37cSMarcel Holtmann if (rp->status) 117e4e8e37cSMarcel Holtmann return; 118e4e8e37cSMarcel Holtmann 119e4e8e37cSMarcel Holtmann hci_dev_lock(hdev); 120e4e8e37cSMarcel Holtmann 121e4e8e37cSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 122e4e8e37cSMarcel Holtmann if (conn) 123e4e8e37cSMarcel Holtmann conn->link_policy = __le16_to_cpu(rp->policy); 124e4e8e37cSMarcel Holtmann 125e4e8e37cSMarcel Holtmann hci_dev_unlock(hdev); 126e4e8e37cSMarcel Holtmann } 127e4e8e37cSMarcel Holtmann 128a9de9248SMarcel Holtmann static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 129a9de9248SMarcel Holtmann { 130a9de9248SMarcel Holtmann struct hci_rp_write_link_policy *rp = (void *) skb->data; 131a9de9248SMarcel Holtmann struct hci_conn *conn; 132a9de9248SMarcel Holtmann void *sent; 133a9de9248SMarcel Holtmann 1349f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 135a9de9248SMarcel Holtmann 136a9de9248SMarcel Holtmann if (rp->status) 137a9de9248SMarcel Holtmann return; 138a9de9248SMarcel Holtmann 139a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY); 14004837f64SMarcel Holtmann if (!sent) 141a9de9248SMarcel Holtmann return; 14204837f64SMarcel Holtmann 14304837f64SMarcel Holtmann hci_dev_lock(hdev); 14404837f64SMarcel Holtmann 145a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 146e4e8e37cSMarcel Holtmann if (conn) 14783985319SHarvey Harrison conn->link_policy = get_unaligned_le16(sent + 2); 14804837f64SMarcel Holtmann 14904837f64SMarcel Holtmann hci_dev_unlock(hdev); 1501da177e4SLinus Torvalds } 1511da177e4SLinus Torvalds 152807deac2SGustavo Padovan static void hci_cc_read_def_link_policy(struct hci_dev *hdev, 153807deac2SGustavo Padovan struct sk_buff *skb) 154e4e8e37cSMarcel Holtmann { 155e4e8e37cSMarcel Holtmann struct hci_rp_read_def_link_policy *rp = (void *) skb->data; 156e4e8e37cSMarcel Holtmann 1579f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 158e4e8e37cSMarcel Holtmann 159e4e8e37cSMarcel Holtmann if (rp->status) 160e4e8e37cSMarcel Holtmann return; 161e4e8e37cSMarcel Holtmann 162e4e8e37cSMarcel Holtmann hdev->link_policy = __le16_to_cpu(rp->policy); 163e4e8e37cSMarcel Holtmann } 164e4e8e37cSMarcel Holtmann 165807deac2SGustavo Padovan static void hci_cc_write_def_link_policy(struct hci_dev *hdev, 166807deac2SGustavo Padovan struct sk_buff *skb) 167e4e8e37cSMarcel Holtmann { 168e4e8e37cSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 169e4e8e37cSMarcel Holtmann void *sent; 170e4e8e37cSMarcel Holtmann 1719f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 172e4e8e37cSMarcel Holtmann 173e4e8e37cSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY); 174e4e8e37cSMarcel Holtmann if (!sent) 175e4e8e37cSMarcel Holtmann return; 176e4e8e37cSMarcel Holtmann 177e4e8e37cSMarcel Holtmann if (!status) 178e4e8e37cSMarcel Holtmann hdev->link_policy = get_unaligned_le16(sent); 179e4e8e37cSMarcel Holtmann } 180e4e8e37cSMarcel Holtmann 181a9de9248SMarcel Holtmann static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) 1821da177e4SLinus Torvalds { 183a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 184a9de9248SMarcel Holtmann 1859f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 186a9de9248SMarcel Holtmann 18710572132SGustavo F. Padovan clear_bit(HCI_RESET, &hdev->flags); 18810572132SGustavo F. Padovan 189a297e97cSJohan Hedberg /* Reset all non-persistent flags */ 1902cc6fb00SJohan Hedberg hdev->dev_flags &= ~HCI_PERSISTENT_MASK; 19169775ff6SAndre Guedes 19269775ff6SAndre Guedes hdev->discovery.state = DISCOVERY_STOPPED; 193bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 194bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 1953f0f524bSJohan Hedberg 1963f0f524bSJohan Hedberg memset(hdev->adv_data, 0, sizeof(hdev->adv_data)); 1973f0f524bSJohan Hedberg hdev->adv_data_len = 0; 198f8e808bdSMarcel Holtmann 199f8e808bdSMarcel Holtmann memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data)); 200f8e808bdSMarcel Holtmann hdev->scan_rsp_data_len = 0; 20106f5b778SMarcel Holtmann 20206f5b778SMarcel Holtmann hdev->ssp_debug_mode = 0; 203a9de9248SMarcel Holtmann } 204a9de9248SMarcel Holtmann 205a9de9248SMarcel Holtmann static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) 206a9de9248SMarcel Holtmann { 207a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 2081da177e4SLinus Torvalds void *sent; 2091da177e4SLinus Torvalds 2109f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 2111da177e4SLinus Torvalds 212a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME); 2131da177e4SLinus Torvalds if (!sent) 214a9de9248SMarcel Holtmann return; 2151da177e4SLinus Torvalds 21656e5cb86SJohan Hedberg hci_dev_lock(hdev); 21756e5cb86SJohan Hedberg 218f51d5b24SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 219f51d5b24SJohan Hedberg mgmt_set_local_name_complete(hdev, sent, status); 22028cc7bdeSJohan Hedberg else if (!status) 22128cc7bdeSJohan Hedberg memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); 222f51d5b24SJohan Hedberg 22356e5cb86SJohan Hedberg hci_dev_unlock(hdev); 224a9de9248SMarcel Holtmann } 225a9de9248SMarcel Holtmann 226a9de9248SMarcel Holtmann static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) 227a9de9248SMarcel Holtmann { 228a9de9248SMarcel Holtmann struct hci_rp_read_local_name *rp = (void *) skb->data; 229a9de9248SMarcel Holtmann 2309f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 231a9de9248SMarcel Holtmann 232a9de9248SMarcel Holtmann if (rp->status) 233a9de9248SMarcel Holtmann return; 234a9de9248SMarcel Holtmann 235db99b5fcSJohan Hedberg if (test_bit(HCI_SETUP, &hdev->dev_flags)) 2361f6c6378SJohan Hedberg memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); 237a9de9248SMarcel Holtmann } 238a9de9248SMarcel Holtmann 239a9de9248SMarcel Holtmann static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) 240a9de9248SMarcel Holtmann { 241a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 242a9de9248SMarcel Holtmann void *sent; 243a9de9248SMarcel Holtmann 2449f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 245a9de9248SMarcel Holtmann 246a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE); 247a9de9248SMarcel Holtmann if (!sent) 248a9de9248SMarcel Holtmann return; 2491da177e4SLinus Torvalds 2501da177e4SLinus Torvalds if (!status) { 251a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 252a9de9248SMarcel Holtmann 2531da177e4SLinus Torvalds if (param == AUTH_ENABLED) 2541da177e4SLinus Torvalds set_bit(HCI_AUTH, &hdev->flags); 2551da177e4SLinus Torvalds else 2561da177e4SLinus Torvalds clear_bit(HCI_AUTH, &hdev->flags); 2571da177e4SLinus Torvalds } 258a9de9248SMarcel Holtmann 25933ef95edSJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 26033ef95edSJohan Hedberg mgmt_auth_enable_complete(hdev, status); 261a9de9248SMarcel Holtmann } 2621da177e4SLinus Torvalds 263a9de9248SMarcel Holtmann static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) 264a9de9248SMarcel Holtmann { 265a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 266a9de9248SMarcel Holtmann void *sent; 267a9de9248SMarcel Holtmann 2689f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 269a9de9248SMarcel Holtmann 270a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE); 2711da177e4SLinus Torvalds if (!sent) 272a9de9248SMarcel Holtmann return; 2731da177e4SLinus Torvalds 2741da177e4SLinus Torvalds if (!status) { 275a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 276a9de9248SMarcel Holtmann 2771da177e4SLinus Torvalds if (param) 2781da177e4SLinus Torvalds set_bit(HCI_ENCRYPT, &hdev->flags); 2791da177e4SLinus Torvalds else 2801da177e4SLinus Torvalds clear_bit(HCI_ENCRYPT, &hdev->flags); 2811da177e4SLinus Torvalds } 2821da177e4SLinus Torvalds } 2831da177e4SLinus Torvalds 284a9de9248SMarcel Holtmann static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) 285a9de9248SMarcel Holtmann { 28636f7fc7eSJohan Hedberg __u8 param, status = *((__u8 *) skb->data); 28736f7fc7eSJohan Hedberg int old_pscan, old_iscan; 288a9de9248SMarcel Holtmann void *sent; 2891da177e4SLinus Torvalds 2909f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 291a9de9248SMarcel Holtmann 292a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE); 2931da177e4SLinus Torvalds if (!sent) 294a9de9248SMarcel Holtmann return; 2951da177e4SLinus Torvalds 29636f7fc7eSJohan Hedberg param = *((__u8 *) sent); 297a9de9248SMarcel Holtmann 29856e5cb86SJohan Hedberg hci_dev_lock(hdev); 29956e5cb86SJohan Hedberg 300fa1bd918SMikel Astiz if (status) { 301744cf19eSJohan Hedberg mgmt_write_scan_failed(hdev, param, status); 3022d7cee58SJohan Hedberg hdev->discov_timeout = 0; 3032d7cee58SJohan Hedberg goto done; 3042d7cee58SJohan Hedberg } 3052d7cee58SJohan Hedberg 3060663ca2aSJohan Hedberg /* We need to ensure that we set this back on if someone changed 3070663ca2aSJohan Hedberg * the scan mode through a raw HCI socket. 3080663ca2aSJohan Hedberg */ 3090663ca2aSJohan Hedberg set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); 3100663ca2aSJohan Hedberg 3119fbcbb45SJohan Hedberg old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags); 3129fbcbb45SJohan Hedberg old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags); 313a9de9248SMarcel Holtmann 31473f22f62SJohan Hedberg if (param & SCAN_INQUIRY) { 3151da177e4SLinus Torvalds set_bit(HCI_ISCAN, &hdev->flags); 3169fbcbb45SJohan Hedberg if (!old_iscan) 317744cf19eSJohan Hedberg mgmt_discoverable(hdev, 1); 3189fbcbb45SJohan Hedberg } else if (old_iscan) 319744cf19eSJohan Hedberg mgmt_discoverable(hdev, 0); 3201da177e4SLinus Torvalds 3219fbcbb45SJohan Hedberg if (param & SCAN_PAGE) { 3221da177e4SLinus Torvalds set_bit(HCI_PSCAN, &hdev->flags); 3239fbcbb45SJohan Hedberg if (!old_pscan) 324744cf19eSJohan Hedberg mgmt_connectable(hdev, 1); 3259fbcbb45SJohan Hedberg } else if (old_pscan) 326744cf19eSJohan Hedberg mgmt_connectable(hdev, 0); 327a9de9248SMarcel Holtmann 32836f7fc7eSJohan Hedberg done: 32956e5cb86SJohan Hedberg hci_dev_unlock(hdev); 3301da177e4SLinus Torvalds } 3311da177e4SLinus Torvalds 332a9de9248SMarcel Holtmann static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 333a9de9248SMarcel Holtmann { 334a9de9248SMarcel Holtmann struct hci_rp_read_class_of_dev *rp = (void *) skb->data; 335a9de9248SMarcel Holtmann 3369f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 337a9de9248SMarcel Holtmann 338a9de9248SMarcel Holtmann if (rp->status) 339a9de9248SMarcel Holtmann return; 340a9de9248SMarcel Holtmann 341a9de9248SMarcel Holtmann memcpy(hdev->dev_class, rp->dev_class, 3); 342a9de9248SMarcel Holtmann 343a9de9248SMarcel Holtmann BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name, 344a9de9248SMarcel Holtmann hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); 345a9de9248SMarcel Holtmann } 346a9de9248SMarcel Holtmann 347a9de9248SMarcel Holtmann static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) 348a9de9248SMarcel Holtmann { 349a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 350a9de9248SMarcel Holtmann void *sent; 351a9de9248SMarcel Holtmann 3529f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 353a9de9248SMarcel Holtmann 354a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV); 355a9de9248SMarcel Holtmann if (!sent) 356a9de9248SMarcel Holtmann return; 357a9de9248SMarcel Holtmann 3587f9a903cSMarcel Holtmann hci_dev_lock(hdev); 3597f9a903cSMarcel Holtmann 3607f9a903cSMarcel Holtmann if (status == 0) 361a9de9248SMarcel Holtmann memcpy(hdev->dev_class, sent, 3); 3627f9a903cSMarcel Holtmann 3637f9a903cSMarcel Holtmann if (test_bit(HCI_MGMT, &hdev->dev_flags)) 3647f9a903cSMarcel Holtmann mgmt_set_class_of_dev_complete(hdev, sent, status); 3657f9a903cSMarcel Holtmann 3667f9a903cSMarcel Holtmann hci_dev_unlock(hdev); 367a9de9248SMarcel Holtmann } 368a9de9248SMarcel Holtmann 369a9de9248SMarcel Holtmann static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) 370a9de9248SMarcel Holtmann { 371a9de9248SMarcel Holtmann struct hci_rp_read_voice_setting *rp = (void *) skb->data; 372a9de9248SMarcel Holtmann __u16 setting; 373a9de9248SMarcel Holtmann 3749f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 375a9de9248SMarcel Holtmann 376a9de9248SMarcel Holtmann if (rp->status) 377a9de9248SMarcel Holtmann return; 378a9de9248SMarcel Holtmann 379a9de9248SMarcel Holtmann setting = __le16_to_cpu(rp->voice_setting); 380a9de9248SMarcel Holtmann 381a9de9248SMarcel Holtmann if (hdev->voice_setting == setting) 382a9de9248SMarcel Holtmann return; 383a9de9248SMarcel Holtmann 384a9de9248SMarcel Holtmann hdev->voice_setting = setting; 385a9de9248SMarcel Holtmann 3869f1db00cSAndrei Emeltchenko BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting); 387a9de9248SMarcel Holtmann 3883c54711cSGustavo F. Padovan if (hdev->notify) 389a9de9248SMarcel Holtmann hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 390a9de9248SMarcel Holtmann } 391a9de9248SMarcel Holtmann 3928fc9ced3SGustavo Padovan static void hci_cc_write_voice_setting(struct hci_dev *hdev, 3938fc9ced3SGustavo Padovan struct sk_buff *skb) 394a9de9248SMarcel Holtmann { 395a9de9248SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 396f383f275SMarcel Holtmann __u16 setting; 397a9de9248SMarcel Holtmann void *sent; 398a9de9248SMarcel Holtmann 3999f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 400a9de9248SMarcel Holtmann 401f383f275SMarcel Holtmann if (status) 402f383f275SMarcel Holtmann return; 403f383f275SMarcel Holtmann 404a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING); 405a9de9248SMarcel Holtmann if (!sent) 406a9de9248SMarcel Holtmann return; 407a9de9248SMarcel Holtmann 408f383f275SMarcel Holtmann setting = get_unaligned_le16(sent); 4091da177e4SLinus Torvalds 410f383f275SMarcel Holtmann if (hdev->voice_setting == setting) 411f383f275SMarcel Holtmann return; 412f383f275SMarcel Holtmann 4131da177e4SLinus Torvalds hdev->voice_setting = setting; 4141da177e4SLinus Torvalds 4159f1db00cSAndrei Emeltchenko BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting); 4161da177e4SLinus Torvalds 4173c54711cSGustavo F. Padovan if (hdev->notify) 4181da177e4SLinus Torvalds hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 4191da177e4SLinus Torvalds } 4201da177e4SLinus Torvalds 421b4cb9fb2SMarcel Holtmann static void hci_cc_read_num_supported_iac(struct hci_dev *hdev, 422b4cb9fb2SMarcel Holtmann struct sk_buff *skb) 423b4cb9fb2SMarcel Holtmann { 424b4cb9fb2SMarcel Holtmann struct hci_rp_read_num_supported_iac *rp = (void *) skb->data; 425b4cb9fb2SMarcel Holtmann 426b4cb9fb2SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 427b4cb9fb2SMarcel Holtmann 428b4cb9fb2SMarcel Holtmann if (rp->status) 429b4cb9fb2SMarcel Holtmann return; 430b4cb9fb2SMarcel Holtmann 431b4cb9fb2SMarcel Holtmann hdev->num_iac = rp->num_iac; 432b4cb9fb2SMarcel Holtmann 433b4cb9fb2SMarcel Holtmann BT_DBG("%s num iac %d", hdev->name, hdev->num_iac); 434b4cb9fb2SMarcel Holtmann } 435b4cb9fb2SMarcel Holtmann 436333140b5SMarcel Holtmann static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) 437333140b5SMarcel Holtmann { 438333140b5SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 4395ed8eb2fSJohan Hedberg struct hci_cp_write_ssp_mode *sent; 440333140b5SMarcel Holtmann 4419f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 442333140b5SMarcel Holtmann 443333140b5SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); 444333140b5SMarcel Holtmann if (!sent) 445333140b5SMarcel Holtmann return; 446333140b5SMarcel Holtmann 4475ed8eb2fSJohan Hedberg if (!status) { 4485ed8eb2fSJohan Hedberg if (sent->mode) 449cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_SSP; 4505ed8eb2fSJohan Hedberg else 451cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_SSP; 4525ed8eb2fSJohan Hedberg } 4535ed8eb2fSJohan Hedberg 454c0ecddc2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 4555ed8eb2fSJohan Hedberg mgmt_ssp_enable_complete(hdev, sent->mode, status); 456c0ecddc2SJohan Hedberg else if (!status) { 4575ed8eb2fSJohan Hedberg if (sent->mode) 45884bde9d6SJohan Hedberg set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); 45984bde9d6SJohan Hedberg else 46084bde9d6SJohan Hedberg clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); 461c0ecddc2SJohan Hedberg } 462333140b5SMarcel Holtmann } 463333140b5SMarcel Holtmann 464eac83dc6SMarcel Holtmann static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb) 465eac83dc6SMarcel Holtmann { 466eac83dc6SMarcel Holtmann u8 status = *((u8 *) skb->data); 467eac83dc6SMarcel Holtmann struct hci_cp_write_sc_support *sent; 468eac83dc6SMarcel Holtmann 469eac83dc6SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 470eac83dc6SMarcel Holtmann 471eac83dc6SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT); 472eac83dc6SMarcel Holtmann if (!sent) 473eac83dc6SMarcel Holtmann return; 474eac83dc6SMarcel Holtmann 475eac83dc6SMarcel Holtmann if (!status) { 476eac83dc6SMarcel Holtmann if (sent->support) 477eac83dc6SMarcel Holtmann hdev->features[1][0] |= LMP_HOST_SC; 478eac83dc6SMarcel Holtmann else 479eac83dc6SMarcel Holtmann hdev->features[1][0] &= ~LMP_HOST_SC; 480eac83dc6SMarcel Holtmann } 481eac83dc6SMarcel Holtmann 482eac83dc6SMarcel Holtmann if (test_bit(HCI_MGMT, &hdev->dev_flags)) 483eac83dc6SMarcel Holtmann mgmt_sc_enable_complete(hdev, sent->support, status); 484eac83dc6SMarcel Holtmann else if (!status) { 485eac83dc6SMarcel Holtmann if (sent->support) 486eac83dc6SMarcel Holtmann set_bit(HCI_SC_ENABLED, &hdev->dev_flags); 487eac83dc6SMarcel Holtmann else 488eac83dc6SMarcel Holtmann clear_bit(HCI_SC_ENABLED, &hdev->dev_flags); 489eac83dc6SMarcel Holtmann } 490eac83dc6SMarcel Holtmann } 491eac83dc6SMarcel Holtmann 492a9de9248SMarcel Holtmann static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) 493a9de9248SMarcel Holtmann { 494a9de9248SMarcel Holtmann struct hci_rp_read_local_version *rp = (void *) skb->data; 4951143e5a6SMarcel Holtmann 4969f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 4971143e5a6SMarcel Holtmann 498a9de9248SMarcel Holtmann if (rp->status) 49942c6b129SJohan Hedberg return; 5001143e5a6SMarcel Holtmann 5010d5551f5SMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) { 502a9de9248SMarcel Holtmann hdev->hci_ver = rp->hci_ver; 503e4e8e37cSMarcel Holtmann hdev->hci_rev = __le16_to_cpu(rp->hci_rev); 504d5859e22SJohan Hedberg hdev->lmp_ver = rp->lmp_ver; 505e4e8e37cSMarcel Holtmann hdev->manufacturer = __le16_to_cpu(rp->manufacturer); 506d5859e22SJohan Hedberg hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); 5070d5551f5SMarcel Holtmann } 508d5859e22SJohan Hedberg } 509d5859e22SJohan Hedberg 5108fc9ced3SGustavo Padovan static void hci_cc_read_local_commands(struct hci_dev *hdev, 5118fc9ced3SGustavo Padovan struct sk_buff *skb) 512a9de9248SMarcel Holtmann { 513a9de9248SMarcel Holtmann struct hci_rp_read_local_commands *rp = (void *) skb->data; 514a9de9248SMarcel Holtmann 5159f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 516a9de9248SMarcel Holtmann 5176a070e6eSMarcel Holtmann if (rp->status) 5186a070e6eSMarcel Holtmann return; 5196a070e6eSMarcel Holtmann 5206a070e6eSMarcel Holtmann if (test_bit(HCI_SETUP, &hdev->dev_flags)) 521a9de9248SMarcel Holtmann memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); 522a9de9248SMarcel Holtmann } 523a9de9248SMarcel Holtmann 5248fc9ced3SGustavo Padovan static void hci_cc_read_local_features(struct hci_dev *hdev, 5258fc9ced3SGustavo Padovan struct sk_buff *skb) 526a9de9248SMarcel Holtmann { 527a9de9248SMarcel Holtmann struct hci_rp_read_local_features *rp = (void *) skb->data; 528a9de9248SMarcel Holtmann 5299f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 530a9de9248SMarcel Holtmann 531a9de9248SMarcel Holtmann if (rp->status) 532a9de9248SMarcel Holtmann return; 533a9de9248SMarcel Holtmann 534a9de9248SMarcel Holtmann memcpy(hdev->features, rp->features, 8); 5351da177e4SLinus Torvalds 5361da177e4SLinus Torvalds /* Adjust default settings according to features 5371da177e4SLinus Torvalds * supported by device. */ 538a9de9248SMarcel Holtmann 539cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_3SLOT) 5401da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM3 | HCI_DH3); 5411da177e4SLinus Torvalds 542cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_5SLOT) 5431da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM5 | HCI_DH5); 5441da177e4SLinus Torvalds 545cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV2) { 5461da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV2); 5475b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV2); 5485b7f9909SMarcel Holtmann } 5491da177e4SLinus Torvalds 550cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV3) { 5511da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV3); 5525b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV3); 5535b7f9909SMarcel Holtmann } 5545b7f9909SMarcel Holtmann 55545db810fSAndre Guedes if (lmp_esco_capable(hdev)) 5565b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV3); 5575b7f9909SMarcel Holtmann 558cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV4) 5595b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV4); 5605b7f9909SMarcel Holtmann 561cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV5) 5625b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV5); 5631da177e4SLinus Torvalds 564cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_2M) 565efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV3); 566efc7688bSMarcel Holtmann 567cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_3M) 568efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_3EV3); 569efc7688bSMarcel Holtmann 570cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_3S_ESCO) 571efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); 5721da177e4SLinus Torvalds } 5731da177e4SLinus Torvalds 574971e3a4bSAndre Guedes static void hci_cc_read_local_ext_features(struct hci_dev *hdev, 575971e3a4bSAndre Guedes struct sk_buff *skb) 576971e3a4bSAndre Guedes { 577971e3a4bSAndre Guedes struct hci_rp_read_local_ext_features *rp = (void *) skb->data; 578971e3a4bSAndre Guedes 5799f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 580971e3a4bSAndre Guedes 581971e3a4bSAndre Guedes if (rp->status) 58242c6b129SJohan Hedberg return; 583971e3a4bSAndre Guedes 58457af75a8SMarcel Holtmann if (hdev->max_page < rp->max_page) 585d2c5d77fSJohan Hedberg hdev->max_page = rp->max_page; 586d2c5d77fSJohan Hedberg 587cad718edSJohan Hedberg if (rp->page < HCI_MAX_PAGES) 588cad718edSJohan Hedberg memcpy(hdev->features[rp->page], rp->features, 8); 589971e3a4bSAndre Guedes } 590971e3a4bSAndre Guedes 5911e89cffbSAndrei Emeltchenko static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, 5921e89cffbSAndrei Emeltchenko struct sk_buff *skb) 5931e89cffbSAndrei Emeltchenko { 5941e89cffbSAndrei Emeltchenko struct hci_rp_read_flow_control_mode *rp = (void *) skb->data; 5951e89cffbSAndrei Emeltchenko 5969f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 5971e89cffbSAndrei Emeltchenko 59842c6b129SJohan Hedberg if (!rp->status) 5991e89cffbSAndrei Emeltchenko hdev->flow_ctl_mode = rp->mode; 6001e89cffbSAndrei Emeltchenko } 6011e89cffbSAndrei Emeltchenko 602a9de9248SMarcel Holtmann static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) 603a9de9248SMarcel Holtmann { 604a9de9248SMarcel Holtmann struct hci_rp_read_buffer_size *rp = (void *) skb->data; 605a9de9248SMarcel Holtmann 6069f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 607a9de9248SMarcel Holtmann 608a9de9248SMarcel Holtmann if (rp->status) 609a9de9248SMarcel Holtmann return; 610a9de9248SMarcel Holtmann 611a9de9248SMarcel Holtmann hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu); 612a9de9248SMarcel Holtmann hdev->sco_mtu = rp->sco_mtu; 613a9de9248SMarcel Holtmann hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt); 614a9de9248SMarcel Holtmann hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt); 615da1f5198SMarcel Holtmann 616da1f5198SMarcel Holtmann if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) { 617da1f5198SMarcel Holtmann hdev->sco_mtu = 64; 618da1f5198SMarcel Holtmann hdev->sco_pkts = 8; 619da1f5198SMarcel Holtmann } 620da1f5198SMarcel Holtmann 621da1f5198SMarcel Holtmann hdev->acl_cnt = hdev->acl_pkts; 622da1f5198SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 6231da177e4SLinus Torvalds 624807deac2SGustavo Padovan BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu, 625807deac2SGustavo Padovan hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts); 6261da177e4SLinus Torvalds } 6271da177e4SLinus Torvalds 628a9de9248SMarcel Holtmann static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) 629a9de9248SMarcel Holtmann { 630a9de9248SMarcel Holtmann struct hci_rp_read_bd_addr *rp = (void *) skb->data; 6311da177e4SLinus Torvalds 6329f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 633a9de9248SMarcel Holtmann 634a9de9248SMarcel Holtmann if (!rp->status) 635a9de9248SMarcel Holtmann bacpy(&hdev->bdaddr, &rp->bdaddr); 63623bb5763SJohan Hedberg } 63723bb5763SJohan Hedberg 638f332ec66SJohan Hedberg static void hci_cc_read_page_scan_activity(struct hci_dev *hdev, 639f332ec66SJohan Hedberg struct sk_buff *skb) 640f332ec66SJohan Hedberg { 641f332ec66SJohan Hedberg struct hci_rp_read_page_scan_activity *rp = (void *) skb->data; 642f332ec66SJohan Hedberg 643f332ec66SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 644f332ec66SJohan Hedberg 645f332ec66SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) { 646f332ec66SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(rp->interval); 647f332ec66SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(rp->window); 648f332ec66SJohan Hedberg } 649f332ec66SJohan Hedberg } 650f332ec66SJohan Hedberg 6514a3ee763SJohan Hedberg static void hci_cc_write_page_scan_activity(struct hci_dev *hdev, 6524a3ee763SJohan Hedberg struct sk_buff *skb) 6534a3ee763SJohan Hedberg { 6544a3ee763SJohan Hedberg u8 status = *((u8 *) skb->data); 6554a3ee763SJohan Hedberg struct hci_cp_write_page_scan_activity *sent; 6564a3ee763SJohan Hedberg 6574a3ee763SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 6584a3ee763SJohan Hedberg 6594a3ee763SJohan Hedberg if (status) 6604a3ee763SJohan Hedberg return; 6614a3ee763SJohan Hedberg 6624a3ee763SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY); 6634a3ee763SJohan Hedberg if (!sent) 6644a3ee763SJohan Hedberg return; 6654a3ee763SJohan Hedberg 6664a3ee763SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(sent->interval); 6674a3ee763SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(sent->window); 6684a3ee763SJohan Hedberg } 6694a3ee763SJohan Hedberg 670f332ec66SJohan Hedberg static void hci_cc_read_page_scan_type(struct hci_dev *hdev, 671f332ec66SJohan Hedberg struct sk_buff *skb) 672f332ec66SJohan Hedberg { 673f332ec66SJohan Hedberg struct hci_rp_read_page_scan_type *rp = (void *) skb->data; 674f332ec66SJohan Hedberg 675f332ec66SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 676f332ec66SJohan Hedberg 677f332ec66SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) 678f332ec66SJohan Hedberg hdev->page_scan_type = rp->type; 679f332ec66SJohan Hedberg } 680f332ec66SJohan Hedberg 6814a3ee763SJohan Hedberg static void hci_cc_write_page_scan_type(struct hci_dev *hdev, 6824a3ee763SJohan Hedberg struct sk_buff *skb) 6834a3ee763SJohan Hedberg { 6844a3ee763SJohan Hedberg u8 status = *((u8 *) skb->data); 6854a3ee763SJohan Hedberg u8 *type; 6864a3ee763SJohan Hedberg 6874a3ee763SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 6884a3ee763SJohan Hedberg 6894a3ee763SJohan Hedberg if (status) 6904a3ee763SJohan Hedberg return; 6914a3ee763SJohan Hedberg 6924a3ee763SJohan Hedberg type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE); 6934a3ee763SJohan Hedberg if (type) 6944a3ee763SJohan Hedberg hdev->page_scan_type = *type; 6954a3ee763SJohan Hedberg } 6964a3ee763SJohan Hedberg 697350ee4cfSAndrei Emeltchenko static void hci_cc_read_data_block_size(struct hci_dev *hdev, 698350ee4cfSAndrei Emeltchenko struct sk_buff *skb) 699350ee4cfSAndrei Emeltchenko { 700350ee4cfSAndrei Emeltchenko struct hci_rp_read_data_block_size *rp = (void *) skb->data; 701350ee4cfSAndrei Emeltchenko 7029f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 703350ee4cfSAndrei Emeltchenko 704350ee4cfSAndrei Emeltchenko if (rp->status) 705350ee4cfSAndrei Emeltchenko return; 706350ee4cfSAndrei Emeltchenko 707350ee4cfSAndrei Emeltchenko hdev->block_mtu = __le16_to_cpu(rp->max_acl_len); 708350ee4cfSAndrei Emeltchenko hdev->block_len = __le16_to_cpu(rp->block_len); 709350ee4cfSAndrei Emeltchenko hdev->num_blocks = __le16_to_cpu(rp->num_blocks); 710350ee4cfSAndrei Emeltchenko 711350ee4cfSAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 712350ee4cfSAndrei Emeltchenko 713350ee4cfSAndrei Emeltchenko BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu, 714350ee4cfSAndrei Emeltchenko hdev->block_cnt, hdev->block_len); 715350ee4cfSAndrei Emeltchenko } 716350ee4cfSAndrei Emeltchenko 717928abaa7SAndrei Emeltchenko static void hci_cc_read_local_amp_info(struct hci_dev *hdev, 718928abaa7SAndrei Emeltchenko struct sk_buff *skb) 719928abaa7SAndrei Emeltchenko { 720928abaa7SAndrei Emeltchenko struct hci_rp_read_local_amp_info *rp = (void *) skb->data; 721928abaa7SAndrei Emeltchenko 7229f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 723928abaa7SAndrei Emeltchenko 724928abaa7SAndrei Emeltchenko if (rp->status) 7258e2a0d92SAndrei Emeltchenko goto a2mp_rsp; 726928abaa7SAndrei Emeltchenko 727928abaa7SAndrei Emeltchenko hdev->amp_status = rp->amp_status; 728928abaa7SAndrei Emeltchenko hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); 729928abaa7SAndrei Emeltchenko hdev->amp_max_bw = __le32_to_cpu(rp->max_bw); 730928abaa7SAndrei Emeltchenko hdev->amp_min_latency = __le32_to_cpu(rp->min_latency); 731928abaa7SAndrei Emeltchenko hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu); 732928abaa7SAndrei Emeltchenko hdev->amp_type = rp->amp_type; 733928abaa7SAndrei Emeltchenko hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap); 734928abaa7SAndrei Emeltchenko hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size); 735928abaa7SAndrei Emeltchenko hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to); 736928abaa7SAndrei Emeltchenko hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); 737928abaa7SAndrei Emeltchenko 7388e2a0d92SAndrei Emeltchenko a2mp_rsp: 7398e2a0d92SAndrei Emeltchenko a2mp_send_getinfo_rsp(hdev); 740928abaa7SAndrei Emeltchenko } 741928abaa7SAndrei Emeltchenko 742903e4541SAndrei Emeltchenko static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev, 743903e4541SAndrei Emeltchenko struct sk_buff *skb) 744903e4541SAndrei Emeltchenko { 745903e4541SAndrei Emeltchenko struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data; 746903e4541SAndrei Emeltchenko struct amp_assoc *assoc = &hdev->loc_assoc; 747903e4541SAndrei Emeltchenko size_t rem_len, frag_len; 748903e4541SAndrei Emeltchenko 749903e4541SAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 750903e4541SAndrei Emeltchenko 751903e4541SAndrei Emeltchenko if (rp->status) 752903e4541SAndrei Emeltchenko goto a2mp_rsp; 753903e4541SAndrei Emeltchenko 754903e4541SAndrei Emeltchenko frag_len = skb->len - sizeof(*rp); 755903e4541SAndrei Emeltchenko rem_len = __le16_to_cpu(rp->rem_len); 756903e4541SAndrei Emeltchenko 757903e4541SAndrei Emeltchenko if (rem_len > frag_len) { 7582e430be3SAndrei Emeltchenko BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len); 759903e4541SAndrei Emeltchenko 760903e4541SAndrei Emeltchenko memcpy(assoc->data + assoc->offset, rp->frag, frag_len); 761903e4541SAndrei Emeltchenko assoc->offset += frag_len; 762903e4541SAndrei Emeltchenko 763903e4541SAndrei Emeltchenko /* Read other fragments */ 764903e4541SAndrei Emeltchenko amp_read_loc_assoc_frag(hdev, rp->phy_handle); 765903e4541SAndrei Emeltchenko 766903e4541SAndrei Emeltchenko return; 767903e4541SAndrei Emeltchenko } 768903e4541SAndrei Emeltchenko 769903e4541SAndrei Emeltchenko memcpy(assoc->data + assoc->offset, rp->frag, rem_len); 770903e4541SAndrei Emeltchenko assoc->len = assoc->offset + rem_len; 771903e4541SAndrei Emeltchenko assoc->offset = 0; 772903e4541SAndrei Emeltchenko 773903e4541SAndrei Emeltchenko a2mp_rsp: 774903e4541SAndrei Emeltchenko /* Send A2MP Rsp when all fragments are received */ 775903e4541SAndrei Emeltchenko a2mp_send_getampassoc_rsp(hdev, rp->status); 7769495b2eeSAndrei Emeltchenko a2mp_send_create_phy_link_req(hdev, rp->status); 777903e4541SAndrei Emeltchenko } 778903e4541SAndrei Emeltchenko 779d5859e22SJohan Hedberg static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, 780d5859e22SJohan Hedberg struct sk_buff *skb) 781d5859e22SJohan Hedberg { 78291c4e9b1SMarcel Holtmann struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data; 783d5859e22SJohan Hedberg 7849f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 785d5859e22SJohan Hedberg 78691c4e9b1SMarcel Holtmann if (!rp->status) 78791c4e9b1SMarcel Holtmann hdev->inq_tx_power = rp->tx_power; 788d5859e22SJohan Hedberg } 789d5859e22SJohan Hedberg 790980e1a53SJohan Hedberg static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) 791980e1a53SJohan Hedberg { 792980e1a53SJohan Hedberg struct hci_rp_pin_code_reply *rp = (void *) skb->data; 793980e1a53SJohan Hedberg struct hci_cp_pin_code_reply *cp; 794980e1a53SJohan Hedberg struct hci_conn *conn; 795980e1a53SJohan Hedberg 7969f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 797980e1a53SJohan Hedberg 79856e5cb86SJohan Hedberg hci_dev_lock(hdev); 79956e5cb86SJohan Hedberg 800a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 801744cf19eSJohan Hedberg mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); 802980e1a53SJohan Hedberg 803fa1bd918SMikel Astiz if (rp->status) 80456e5cb86SJohan Hedberg goto unlock; 805980e1a53SJohan Hedberg 806980e1a53SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); 807980e1a53SJohan Hedberg if (!cp) 80856e5cb86SJohan Hedberg goto unlock; 809980e1a53SJohan Hedberg 810980e1a53SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 811980e1a53SJohan Hedberg if (conn) 812980e1a53SJohan Hedberg conn->pin_length = cp->pin_len; 81356e5cb86SJohan Hedberg 81456e5cb86SJohan Hedberg unlock: 81556e5cb86SJohan Hedberg hci_dev_unlock(hdev); 816980e1a53SJohan Hedberg } 817980e1a53SJohan Hedberg 818980e1a53SJohan Hedberg static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) 819980e1a53SJohan Hedberg { 820980e1a53SJohan Hedberg struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data; 821980e1a53SJohan Hedberg 8229f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 823980e1a53SJohan Hedberg 82456e5cb86SJohan Hedberg hci_dev_lock(hdev); 82556e5cb86SJohan Hedberg 826a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 827744cf19eSJohan Hedberg mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, 828980e1a53SJohan Hedberg rp->status); 82956e5cb86SJohan Hedberg 83056e5cb86SJohan Hedberg hci_dev_unlock(hdev); 831980e1a53SJohan Hedberg } 83256e5cb86SJohan Hedberg 8336ed58ec5SVille Tervo static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, 8346ed58ec5SVille Tervo struct sk_buff *skb) 8356ed58ec5SVille Tervo { 8366ed58ec5SVille Tervo struct hci_rp_le_read_buffer_size *rp = (void *) skb->data; 8376ed58ec5SVille Tervo 8389f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 8396ed58ec5SVille Tervo 8406ed58ec5SVille Tervo if (rp->status) 8416ed58ec5SVille Tervo return; 8426ed58ec5SVille Tervo 8436ed58ec5SVille Tervo hdev->le_mtu = __le16_to_cpu(rp->le_mtu); 8446ed58ec5SVille Tervo hdev->le_pkts = rp->le_max_pkt; 8456ed58ec5SVille Tervo 8466ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 8476ed58ec5SVille Tervo 8486ed58ec5SVille Tervo BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts); 8496ed58ec5SVille Tervo } 850980e1a53SJohan Hedberg 85160e77321SJohan Hedberg static void hci_cc_le_read_local_features(struct hci_dev *hdev, 85260e77321SJohan Hedberg struct sk_buff *skb) 85360e77321SJohan Hedberg { 85460e77321SJohan Hedberg struct hci_rp_le_read_local_features *rp = (void *) skb->data; 85560e77321SJohan Hedberg 85660e77321SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 85760e77321SJohan Hedberg 85860e77321SJohan Hedberg if (!rp->status) 85960e77321SJohan Hedberg memcpy(hdev->le_features, rp->features, 8); 86060e77321SJohan Hedberg } 86160e77321SJohan Hedberg 8628fa19098SJohan Hedberg static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, 8638fa19098SJohan Hedberg struct sk_buff *skb) 8648fa19098SJohan Hedberg { 8658fa19098SJohan Hedberg struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data; 8668fa19098SJohan Hedberg 8678fa19098SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 8688fa19098SJohan Hedberg 86904b4edcbSJohan Hedberg if (!rp->status) 8708fa19098SJohan Hedberg hdev->adv_tx_power = rp->tx_power; 8718fa19098SJohan Hedberg } 8728fa19098SJohan Hedberg 873a5c29683SJohan Hedberg static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) 874a5c29683SJohan Hedberg { 875a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 876a5c29683SJohan Hedberg 8779f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 878a5c29683SJohan Hedberg 87956e5cb86SJohan Hedberg hci_dev_lock(hdev); 88056e5cb86SJohan Hedberg 881a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 88204124681SGustavo F. Padovan mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0, 88304124681SGustavo F. Padovan rp->status); 88456e5cb86SJohan Hedberg 88556e5cb86SJohan Hedberg hci_dev_unlock(hdev); 886a5c29683SJohan Hedberg } 887a5c29683SJohan Hedberg 888a5c29683SJohan Hedberg static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, 889a5c29683SJohan Hedberg struct sk_buff *skb) 890a5c29683SJohan Hedberg { 891a5c29683SJohan Hedberg struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 892a5c29683SJohan Hedberg 8939f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 894a5c29683SJohan Hedberg 89556e5cb86SJohan Hedberg hci_dev_lock(hdev); 89656e5cb86SJohan Hedberg 897a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 898744cf19eSJohan Hedberg mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, 89904124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 90056e5cb86SJohan Hedberg 90156e5cb86SJohan Hedberg hci_dev_unlock(hdev); 902a5c29683SJohan Hedberg } 903a5c29683SJohan Hedberg 9041143d458SBrian Gix static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb) 9051143d458SBrian Gix { 9061143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 9071143d458SBrian Gix 9089f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9091143d458SBrian Gix 9101143d458SBrian Gix hci_dev_lock(hdev); 9111143d458SBrian Gix 912a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 913272d90dfSJohan Hedberg mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 914272d90dfSJohan Hedberg 0, rp->status); 9151143d458SBrian Gix 9161143d458SBrian Gix hci_dev_unlock(hdev); 9171143d458SBrian Gix } 9181143d458SBrian Gix 9191143d458SBrian Gix static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, 9201143d458SBrian Gix struct sk_buff *skb) 9211143d458SBrian Gix { 9221143d458SBrian Gix struct hci_rp_user_confirm_reply *rp = (void *) skb->data; 9231143d458SBrian Gix 9249f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9251143d458SBrian Gix 9261143d458SBrian Gix hci_dev_lock(hdev); 9271143d458SBrian Gix 928a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 9291143d458SBrian Gix mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr, 93004124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 9311143d458SBrian Gix 9321143d458SBrian Gix hci_dev_unlock(hdev); 9331143d458SBrian Gix } 9341143d458SBrian Gix 9354d2d2796SMarcel Holtmann static void hci_cc_read_local_oob_data(struct hci_dev *hdev, 936c35938b2SSzymon Janc struct sk_buff *skb) 937c35938b2SSzymon Janc { 938c35938b2SSzymon Janc struct hci_rp_read_local_oob_data *rp = (void *) skb->data; 939c35938b2SSzymon Janc 9409f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 941c35938b2SSzymon Janc 94256e5cb86SJohan Hedberg hci_dev_lock(hdev); 9434d2d2796SMarcel Holtmann mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->randomizer, 9444d2d2796SMarcel Holtmann NULL, NULL, rp->status); 9454d2d2796SMarcel Holtmann hci_dev_unlock(hdev); 9464d2d2796SMarcel Holtmann } 9474d2d2796SMarcel Holtmann 9484d2d2796SMarcel Holtmann static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, 9494d2d2796SMarcel Holtmann struct sk_buff *skb) 9504d2d2796SMarcel Holtmann { 9514d2d2796SMarcel Holtmann struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data; 9524d2d2796SMarcel Holtmann 9534d2d2796SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 9544d2d2796SMarcel Holtmann 9554d2d2796SMarcel Holtmann hci_dev_lock(hdev); 9564d2d2796SMarcel Holtmann mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->randomizer192, 9574d2d2796SMarcel Holtmann rp->hash256, rp->randomizer256, 9584d2d2796SMarcel Holtmann rp->status); 95956e5cb86SJohan Hedberg hci_dev_unlock(hdev); 960c35938b2SSzymon Janc } 961c35938b2SSzymon Janc 9627a4cd51dSMarcel Holtmann 9637a4cd51dSMarcel Holtmann static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb) 9647a4cd51dSMarcel Holtmann { 9657a4cd51dSMarcel Holtmann __u8 status = *((__u8 *) skb->data); 9667a4cd51dSMarcel Holtmann bdaddr_t *sent; 9677a4cd51dSMarcel Holtmann 9687a4cd51dSMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 9697a4cd51dSMarcel Holtmann 9707a4cd51dSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR); 9717a4cd51dSMarcel Holtmann if (!sent) 9727a4cd51dSMarcel Holtmann return; 9737a4cd51dSMarcel Holtmann 9747a4cd51dSMarcel Holtmann hci_dev_lock(hdev); 9757a4cd51dSMarcel Holtmann 9767a4cd51dSMarcel Holtmann if (!status) 9777a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, sent); 9787a4cd51dSMarcel Holtmann 9797a4cd51dSMarcel Holtmann hci_dev_unlock(hdev); 9807a4cd51dSMarcel Holtmann } 9817a4cd51dSMarcel Holtmann 982c1d5dc4aSJohan Hedberg static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) 983c1d5dc4aSJohan Hedberg { 984c1d5dc4aSJohan Hedberg __u8 *sent, status = *((__u8 *) skb->data); 985c1d5dc4aSJohan Hedberg 986c1d5dc4aSJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 987c1d5dc4aSJohan Hedberg 988c1d5dc4aSJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE); 989c1d5dc4aSJohan Hedberg if (!sent) 990c1d5dc4aSJohan Hedberg return; 991c1d5dc4aSJohan Hedberg 992c1d5dc4aSJohan Hedberg hci_dev_lock(hdev); 993c1d5dc4aSJohan Hedberg 994778b235aSJohan Hedberg if (!status) 995778b235aSJohan Hedberg mgmt_advertising(hdev, *sent); 996c1d5dc4aSJohan Hedberg 99704b4edcbSJohan Hedberg hci_dev_unlock(hdev); 998c1d5dc4aSJohan Hedberg } 999c1d5dc4aSJohan Hedberg 1000eb9d91f5SAndre Guedes static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, 1001eb9d91f5SAndre Guedes struct sk_buff *skb) 1002eb9d91f5SAndre Guedes { 1003eb9d91f5SAndre Guedes struct hci_cp_le_set_scan_enable *cp; 1004eb9d91f5SAndre Guedes __u8 status = *((__u8 *) skb->data); 1005eb9d91f5SAndre Guedes 10069f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1007eb9d91f5SAndre Guedes 1008eb9d91f5SAndre Guedes cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE); 1009eb9d91f5SAndre Guedes if (!cp) 1010eb9d91f5SAndre Guedes return; 1011eb9d91f5SAndre Guedes 1012fef5234aSAndre Guedes if (status) 10137ba8b4beSAndre Guedes return; 10147ba8b4beSAndre Guedes 10153fd319b8SAndre Guedes switch (cp->enable) { 10163fd319b8SAndre Guedes case LE_SCAN_ENABLE: 1017d23264a8SAndre Guedes set_bit(HCI_LE_SCAN, &hdev->dev_flags); 101868a8aea4SAndrei Emeltchenko break; 101968a8aea4SAndrei Emeltchenko 102076a388beSAndre Guedes case LE_SCAN_DISABLE: 1021d23264a8SAndre Guedes clear_bit(HCI_LE_SCAN, &hdev->dev_flags); 102268a8aea4SAndrei Emeltchenko break; 102368a8aea4SAndrei Emeltchenko 102468a8aea4SAndrei Emeltchenko default: 102568a8aea4SAndrei Emeltchenko BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable); 102668a8aea4SAndrei Emeltchenko break; 102735815085SAndre Guedes } 1028eb9d91f5SAndre Guedes } 1029eb9d91f5SAndre Guedes 1030cf1d081fSJohan Hedberg static void hci_cc_le_read_white_list_size(struct hci_dev *hdev, 1031cf1d081fSJohan Hedberg struct sk_buff *skb) 1032cf1d081fSJohan Hedberg { 1033cf1d081fSJohan Hedberg struct hci_rp_le_read_white_list_size *rp = (void *) skb->data; 1034cf1d081fSJohan Hedberg 1035cf1d081fSJohan Hedberg BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size); 1036cf1d081fSJohan Hedberg 1037cf1d081fSJohan Hedberg if (!rp->status) 1038cf1d081fSJohan Hedberg hdev->le_white_list_size = rp->size; 1039cf1d081fSJohan Hedberg } 1040cf1d081fSJohan Hedberg 10410f36b589SMarcel Holtmann static void hci_cc_le_clear_white_list(struct hci_dev *hdev, 10420f36b589SMarcel Holtmann struct sk_buff *skb) 10430f36b589SMarcel Holtmann { 10440f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 10450f36b589SMarcel Holtmann 10460f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 10470f36b589SMarcel Holtmann 10480f36b589SMarcel Holtmann if (!status) 10490f36b589SMarcel Holtmann hci_white_list_clear(hdev); 10500f36b589SMarcel Holtmann } 10510f36b589SMarcel Holtmann 10520f36b589SMarcel Holtmann static void hci_cc_le_add_to_white_list(struct hci_dev *hdev, 10530f36b589SMarcel Holtmann struct sk_buff *skb) 10540f36b589SMarcel Holtmann { 10550f36b589SMarcel Holtmann struct hci_cp_le_add_to_white_list *sent; 10560f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 10570f36b589SMarcel Holtmann 10580f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 10590f36b589SMarcel Holtmann 10600f36b589SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST); 10610f36b589SMarcel Holtmann if (!sent) 10620f36b589SMarcel Holtmann return; 10630f36b589SMarcel Holtmann 10640f36b589SMarcel Holtmann if (!status) 10650f36b589SMarcel Holtmann hci_white_list_add(hdev, &sent->bdaddr, sent->bdaddr_type); 10660f36b589SMarcel Holtmann } 10670f36b589SMarcel Holtmann 10680f36b589SMarcel Holtmann static void hci_cc_le_del_from_white_list(struct hci_dev *hdev, 10690f36b589SMarcel Holtmann struct sk_buff *skb) 10700f36b589SMarcel Holtmann { 10710f36b589SMarcel Holtmann struct hci_cp_le_del_from_white_list *sent; 10720f36b589SMarcel Holtmann __u8 status = *((__u8 *) skb->data); 10730f36b589SMarcel Holtmann 10740f36b589SMarcel Holtmann BT_DBG("%s status 0x%2.2x", hdev->name, status); 10750f36b589SMarcel Holtmann 10760f36b589SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST); 10770f36b589SMarcel Holtmann if (!sent) 10780f36b589SMarcel Holtmann return; 10790f36b589SMarcel Holtmann 10800f36b589SMarcel Holtmann if (!status) 10810f36b589SMarcel Holtmann hci_white_list_del(hdev, &sent->bdaddr, sent->bdaddr_type); 10820f36b589SMarcel Holtmann } 10830f36b589SMarcel Holtmann 10849b008c04SJohan Hedberg static void hci_cc_le_read_supported_states(struct hci_dev *hdev, 10859b008c04SJohan Hedberg struct sk_buff *skb) 10869b008c04SJohan Hedberg { 10879b008c04SJohan Hedberg struct hci_rp_le_read_supported_states *rp = (void *) skb->data; 10889b008c04SJohan Hedberg 10899b008c04SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 10909b008c04SJohan Hedberg 10919b008c04SJohan Hedberg if (!rp->status) 10929b008c04SJohan Hedberg memcpy(hdev->le_states, rp->le_states, 8); 10939b008c04SJohan Hedberg } 10949b008c04SJohan Hedberg 10956039aa73SGustavo Padovan static void hci_cc_write_le_host_supported(struct hci_dev *hdev, 1096f9b49306SAndre Guedes struct sk_buff *skb) 1097f9b49306SAndre Guedes { 109806199cf8SJohan Hedberg struct hci_cp_write_le_host_supported *sent; 1099f9b49306SAndre Guedes __u8 status = *((__u8 *) skb->data); 1100f9b49306SAndre Guedes 11019f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1102f9b49306SAndre Guedes 110306199cf8SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED); 11048f984dfaSJohan Hedberg if (!sent) 1105f9b49306SAndre Guedes return; 1106f9b49306SAndre Guedes 11078f984dfaSJohan Hedberg if (!status) { 1108416a4ae5SJohan Hedberg if (sent->le) { 1109cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE; 1110416a4ae5SJohan Hedberg set_bit(HCI_LE_ENABLED, &hdev->dev_flags); 1111416a4ae5SJohan Hedberg } else { 1112cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE; 1113416a4ae5SJohan Hedberg clear_bit(HCI_LE_ENABLED, &hdev->dev_flags); 1114f3d3444aSJohan Hedberg clear_bit(HCI_ADVERTISING, &hdev->dev_flags); 1115416a4ae5SJohan Hedberg } 111653b2caabSJohan Hedberg 111753b2caabSJohan Hedberg if (sent->simul) 1118cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE_BREDR; 111953b2caabSJohan Hedberg else 1120cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE_BREDR; 11218f984dfaSJohan Hedberg } 1122f9b49306SAndre Guedes } 1123f9b49306SAndre Guedes 112456ed2cb8SJohan Hedberg static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb) 112556ed2cb8SJohan Hedberg { 112656ed2cb8SJohan Hedberg struct hci_cp_le_set_adv_param *cp; 112756ed2cb8SJohan Hedberg u8 status = *((u8 *) skb->data); 112856ed2cb8SJohan Hedberg 112956ed2cb8SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 113056ed2cb8SJohan Hedberg 113156ed2cb8SJohan Hedberg if (status) 113256ed2cb8SJohan Hedberg return; 113356ed2cb8SJohan Hedberg 113456ed2cb8SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM); 113556ed2cb8SJohan Hedberg if (!cp) 113656ed2cb8SJohan Hedberg return; 113756ed2cb8SJohan Hedberg 113856ed2cb8SJohan Hedberg hci_dev_lock(hdev); 113956ed2cb8SJohan Hedberg hdev->adv_addr_type = cp->own_address_type; 114056ed2cb8SJohan Hedberg hci_dev_unlock(hdev); 114156ed2cb8SJohan Hedberg } 114256ed2cb8SJohan Hedberg 114393c284eeSAndrei Emeltchenko static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev, 114493c284eeSAndrei Emeltchenko struct sk_buff *skb) 114593c284eeSAndrei Emeltchenko { 114693c284eeSAndrei Emeltchenko struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data; 114793c284eeSAndrei Emeltchenko 114893c284eeSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x", 114993c284eeSAndrei Emeltchenko hdev->name, rp->status, rp->phy_handle); 115093c284eeSAndrei Emeltchenko 115193c284eeSAndrei Emeltchenko if (rp->status) 115293c284eeSAndrei Emeltchenko return; 115393c284eeSAndrei Emeltchenko 115493c284eeSAndrei Emeltchenko amp_write_rem_assoc_continue(hdev, rp->phy_handle); 115593c284eeSAndrei Emeltchenko } 115693c284eeSAndrei Emeltchenko 11576039aa73SGustavo Padovan static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) 1158a9de9248SMarcel Holtmann { 11599f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1160a9de9248SMarcel Holtmann 1161a9de9248SMarcel Holtmann if (status) { 1162a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 1163314b2381SJohan Hedberg return; 1164314b2381SJohan Hedberg } 1165314b2381SJohan Hedberg 116689352e7dSAndre Guedes set_bit(HCI_INQUIRY, &hdev->flags); 1167a9de9248SMarcel Holtmann } 1168a9de9248SMarcel Holtmann 11696039aa73SGustavo Padovan static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) 11701da177e4SLinus Torvalds { 1171a9de9248SMarcel Holtmann struct hci_cp_create_conn *cp; 11721da177e4SLinus Torvalds struct hci_conn *conn; 11731da177e4SLinus Torvalds 11749f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1175a9de9248SMarcel Holtmann 1176a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN); 11771da177e4SLinus Torvalds if (!cp) 11781da177e4SLinus Torvalds return; 11791da177e4SLinus Torvalds 11801da177e4SLinus Torvalds hci_dev_lock(hdev); 11811da177e4SLinus Torvalds 11821da177e4SLinus Torvalds conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 11831da177e4SLinus Torvalds 11846ed93dc6SAndrei Emeltchenko BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn); 11851da177e4SLinus Torvalds 11861da177e4SLinus Torvalds if (status) { 11871da177e4SLinus Torvalds if (conn && conn->state == BT_CONNECT) { 11884c67bc74SMarcel Holtmann if (status != 0x0c || conn->attempt > 2) { 11891da177e4SLinus Torvalds conn->state = BT_CLOSED; 11901da177e4SLinus Torvalds hci_proto_connect_cfm(conn, status); 11911da177e4SLinus Torvalds hci_conn_del(conn); 11924c67bc74SMarcel Holtmann } else 11934c67bc74SMarcel Holtmann conn->state = BT_CONNECT2; 11941da177e4SLinus Torvalds } 11951da177e4SLinus Torvalds } else { 11961da177e4SLinus Torvalds if (!conn) { 11971da177e4SLinus Torvalds conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr); 11981da177e4SLinus Torvalds if (conn) { 1199a0c808b3SJohan Hedberg conn->out = true; 12001da177e4SLinus Torvalds conn->link_mode |= HCI_LM_MASTER; 12011da177e4SLinus Torvalds } else 1202893ef971SGustavo F. Padovan BT_ERR("No memory for new connection"); 12031da177e4SLinus Torvalds } 12041da177e4SLinus Torvalds } 12051da177e4SLinus Torvalds 12061da177e4SLinus Torvalds hci_dev_unlock(hdev); 12071da177e4SLinus Torvalds } 12081da177e4SLinus Torvalds 1209a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status) 12101da177e4SLinus Torvalds { 1211a9de9248SMarcel Holtmann struct hci_cp_add_sco *cp; 12121da177e4SLinus Torvalds struct hci_conn *acl, *sco; 12131da177e4SLinus Torvalds __u16 handle; 12141da177e4SLinus Torvalds 12159f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1216b6a0dc82SMarcel Holtmann 1217a9de9248SMarcel Holtmann if (!status) 1218a9de9248SMarcel Holtmann return; 1219a9de9248SMarcel Holtmann 1220a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO); 12211da177e4SLinus Torvalds if (!cp) 1222a9de9248SMarcel Holtmann return; 12231da177e4SLinus Torvalds 12241da177e4SLinus Torvalds handle = __le16_to_cpu(cp->handle); 12251da177e4SLinus Torvalds 12269f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, handle); 12271da177e4SLinus Torvalds 12281da177e4SLinus Torvalds hci_dev_lock(hdev); 12291da177e4SLinus Torvalds 12301da177e4SLinus Torvalds acl = hci_conn_hash_lookup_handle(hdev, handle); 12315a08ecceSAndrei Emeltchenko if (acl) { 12325a08ecceSAndrei Emeltchenko sco = acl->link; 12335a08ecceSAndrei Emeltchenko if (sco) { 12341da177e4SLinus Torvalds sco->state = BT_CLOSED; 12351da177e4SLinus Torvalds 12361da177e4SLinus Torvalds hci_proto_connect_cfm(sco, status); 12371da177e4SLinus Torvalds hci_conn_del(sco); 12381da177e4SLinus Torvalds } 12395a08ecceSAndrei Emeltchenko } 12401da177e4SLinus Torvalds 12411da177e4SLinus Torvalds hci_dev_unlock(hdev); 12421da177e4SLinus Torvalds } 12431da177e4SLinus Torvalds 1244f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status) 1245f8558555SMarcel Holtmann { 1246f8558555SMarcel Holtmann struct hci_cp_auth_requested *cp; 1247f8558555SMarcel Holtmann struct hci_conn *conn; 1248f8558555SMarcel Holtmann 12499f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1250f8558555SMarcel Holtmann 1251f8558555SMarcel Holtmann if (!status) 1252f8558555SMarcel Holtmann return; 1253f8558555SMarcel Holtmann 1254f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED); 1255f8558555SMarcel Holtmann if (!cp) 1256f8558555SMarcel Holtmann return; 1257f8558555SMarcel Holtmann 1258f8558555SMarcel Holtmann hci_dev_lock(hdev); 1259f8558555SMarcel Holtmann 1260f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1261f8558555SMarcel Holtmann if (conn) { 1262f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1263f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, status); 126476a68ba0SDavid Herrmann hci_conn_drop(conn); 1265f8558555SMarcel Holtmann } 1266f8558555SMarcel Holtmann } 1267f8558555SMarcel Holtmann 1268f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1269f8558555SMarcel Holtmann } 1270f8558555SMarcel Holtmann 1271f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) 1272f8558555SMarcel Holtmann { 1273f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt *cp; 1274f8558555SMarcel Holtmann struct hci_conn *conn; 1275f8558555SMarcel Holtmann 12769f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1277f8558555SMarcel Holtmann 1278f8558555SMarcel Holtmann if (!status) 1279f8558555SMarcel Holtmann return; 1280f8558555SMarcel Holtmann 1281f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT); 1282f8558555SMarcel Holtmann if (!cp) 1283f8558555SMarcel Holtmann return; 1284f8558555SMarcel Holtmann 1285f8558555SMarcel Holtmann hci_dev_lock(hdev); 1286f8558555SMarcel Holtmann 1287f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1288f8558555SMarcel Holtmann if (conn) { 1289f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 1290f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, status); 129176a68ba0SDavid Herrmann hci_conn_drop(conn); 1292f8558555SMarcel Holtmann } 1293f8558555SMarcel Holtmann } 1294f8558555SMarcel Holtmann 1295f8558555SMarcel Holtmann hci_dev_unlock(hdev); 1296f8558555SMarcel Holtmann } 1297f8558555SMarcel Holtmann 1298127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev, 1299392599b9SJohan Hedberg struct hci_conn *conn) 1300392599b9SJohan Hedberg { 1301392599b9SJohan Hedberg if (conn->state != BT_CONFIG || !conn->out) 1302392599b9SJohan Hedberg return 0; 1303392599b9SJohan Hedberg 1304765c2a96SJohan Hedberg if (conn->pending_sec_level == BT_SECURITY_SDP) 1305392599b9SJohan Hedberg return 0; 1306392599b9SJohan Hedberg 1307392599b9SJohan Hedberg /* Only request authentication for SSP connections or non-SSP 1308264b8b4eSJohan Hedberg * devices with sec_level MEDIUM or HIGH or if MITM protection 1309264b8b4eSJohan Hedberg * is requested. 1310264b8b4eSJohan Hedberg */ 1311807deac2SGustavo Padovan if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) && 1312264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_HIGH && 1313264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_MEDIUM) 1314392599b9SJohan Hedberg return 0; 1315392599b9SJohan Hedberg 1316392599b9SJohan Hedberg return 1; 1317392599b9SJohan Hedberg } 1318392599b9SJohan Hedberg 13196039aa73SGustavo Padovan static int hci_resolve_name(struct hci_dev *hdev, 132000abfe44SGustavo F. Padovan struct inquiry_entry *e) 132130dc78e1SJohan Hedberg { 132230dc78e1SJohan Hedberg struct hci_cp_remote_name_req cp; 132330dc78e1SJohan Hedberg 132430dc78e1SJohan Hedberg memset(&cp, 0, sizeof(cp)); 132530dc78e1SJohan Hedberg 132630dc78e1SJohan Hedberg bacpy(&cp.bdaddr, &e->data.bdaddr); 132730dc78e1SJohan Hedberg cp.pscan_rep_mode = e->data.pscan_rep_mode; 132830dc78e1SJohan Hedberg cp.pscan_mode = e->data.pscan_mode; 132930dc78e1SJohan Hedberg cp.clock_offset = e->data.clock_offset; 133030dc78e1SJohan Hedberg 133130dc78e1SJohan Hedberg return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 133230dc78e1SJohan Hedberg } 133330dc78e1SJohan Hedberg 1334b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev) 133530dc78e1SJohan Hedberg { 133630dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 133730dc78e1SJohan Hedberg struct inquiry_entry *e; 133830dc78e1SJohan Hedberg 1339b644ba33SJohan Hedberg if (list_empty(&discov->resolve)) 1340b644ba33SJohan Hedberg return false; 1341b644ba33SJohan Hedberg 1342b644ba33SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 1343c810089cSRam Malovany if (!e) 1344c810089cSRam Malovany return false; 1345c810089cSRam Malovany 1346b644ba33SJohan Hedberg if (hci_resolve_name(hdev, e) == 0) { 1347b644ba33SJohan Hedberg e->name_state = NAME_PENDING; 1348b644ba33SJohan Hedberg return true; 1349b644ba33SJohan Hedberg } 1350b644ba33SJohan Hedberg 1351b644ba33SJohan Hedberg return false; 1352b644ba33SJohan Hedberg } 1353b644ba33SJohan Hedberg 1354b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, 1355b644ba33SJohan Hedberg bdaddr_t *bdaddr, u8 *name, u8 name_len) 1356b644ba33SJohan Hedberg { 1357b644ba33SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 1358b644ba33SJohan Hedberg struct inquiry_entry *e; 1359b644ba33SJohan Hedberg 1360b644ba33SJohan Hedberg if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 136104124681SGustavo F. Padovan mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name, 136204124681SGustavo F. Padovan name_len, conn->dev_class); 1363b644ba33SJohan Hedberg 1364b644ba33SJohan Hedberg if (discov->state == DISCOVERY_STOPPED) 1365b644ba33SJohan Hedberg return; 1366b644ba33SJohan Hedberg 136730dc78e1SJohan Hedberg if (discov->state == DISCOVERY_STOPPING) 136830dc78e1SJohan Hedberg goto discov_complete; 136930dc78e1SJohan Hedberg 137030dc78e1SJohan Hedberg if (discov->state != DISCOVERY_RESOLVING) 137130dc78e1SJohan Hedberg return; 137230dc78e1SJohan Hedberg 137330dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING); 13747cc8380eSRam Malovany /* If the device was not found in a list of found devices names of which 13757cc8380eSRam Malovany * are pending. there is no need to continue resolving a next name as it 13767cc8380eSRam Malovany * will be done upon receiving another Remote Name Request Complete 13777cc8380eSRam Malovany * Event */ 13787cc8380eSRam Malovany if (!e) 13797cc8380eSRam Malovany return; 13807cc8380eSRam Malovany 138130dc78e1SJohan Hedberg list_del(&e->list); 13827cc8380eSRam Malovany if (name) { 13837cc8380eSRam Malovany e->name_state = NAME_KNOWN; 1384b644ba33SJohan Hedberg mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, 1385b644ba33SJohan Hedberg e->data.rssi, name, name_len); 1386c3e7c0d9SRam Malovany } else { 1387c3e7c0d9SRam Malovany e->name_state = NAME_NOT_KNOWN; 138830dc78e1SJohan Hedberg } 138930dc78e1SJohan Hedberg 1390b644ba33SJohan Hedberg if (hci_resolve_next_name(hdev)) 139130dc78e1SJohan Hedberg return; 139230dc78e1SJohan Hedberg 139330dc78e1SJohan Hedberg discov_complete: 139430dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 139530dc78e1SJohan Hedberg } 139630dc78e1SJohan Hedberg 1397a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) 13981da177e4SLinus Torvalds { 1399127178d2SJohan Hedberg struct hci_cp_remote_name_req *cp; 1400127178d2SJohan Hedberg struct hci_conn *conn; 1401127178d2SJohan Hedberg 14029f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1403127178d2SJohan Hedberg 1404127178d2SJohan Hedberg /* If successful wait for the name req complete event before 1405127178d2SJohan Hedberg * checking for the need to do authentication */ 1406127178d2SJohan Hedberg if (!status) 1407127178d2SJohan Hedberg return; 1408127178d2SJohan Hedberg 1409127178d2SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ); 1410127178d2SJohan Hedberg if (!cp) 1411127178d2SJohan Hedberg return; 1412127178d2SJohan Hedberg 1413127178d2SJohan Hedberg hci_dev_lock(hdev); 1414127178d2SJohan Hedberg 1415127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 1416b644ba33SJohan Hedberg 1417b644ba33SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 1418b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0); 1419b644ba33SJohan Hedberg 142079c6c70cSJohan Hedberg if (!conn) 142179c6c70cSJohan Hedberg goto unlock; 142279c6c70cSJohan Hedberg 142379c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 142479c6c70cSJohan Hedberg goto unlock; 142579c6c70cSJohan Hedberg 142651a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 1427c1f23a2bSJohannes Berg struct hci_cp_auth_requested auth_cp; 1428c1f23a2bSJohannes Berg 1429c1f23a2bSJohannes Berg auth_cp.handle = __cpu_to_le16(conn->handle); 1430c1f23a2bSJohannes Berg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, 1431c1f23a2bSJohannes Berg sizeof(auth_cp), &auth_cp); 1432127178d2SJohan Hedberg } 1433127178d2SJohan Hedberg 143479c6c70cSJohan Hedberg unlock: 1435127178d2SJohan Hedberg hci_dev_unlock(hdev); 1436a9de9248SMarcel Holtmann } 14371da177e4SLinus Torvalds 1438769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) 1439769be974SMarcel Holtmann { 1440769be974SMarcel Holtmann struct hci_cp_read_remote_features *cp; 1441769be974SMarcel Holtmann struct hci_conn *conn; 1442769be974SMarcel Holtmann 14439f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1444769be974SMarcel Holtmann 1445769be974SMarcel Holtmann if (!status) 1446769be974SMarcel Holtmann return; 1447769be974SMarcel Holtmann 1448769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES); 1449769be974SMarcel Holtmann if (!cp) 1450769be974SMarcel Holtmann return; 1451769be974SMarcel Holtmann 1452769be974SMarcel Holtmann hci_dev_lock(hdev); 1453769be974SMarcel Holtmann 1454769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1455769be974SMarcel Holtmann if (conn) { 1456769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1457769be974SMarcel Holtmann hci_proto_connect_cfm(conn, status); 145876a68ba0SDavid Herrmann hci_conn_drop(conn); 1459769be974SMarcel Holtmann } 1460769be974SMarcel Holtmann } 1461769be974SMarcel Holtmann 1462769be974SMarcel Holtmann hci_dev_unlock(hdev); 1463769be974SMarcel Holtmann } 1464769be974SMarcel Holtmann 1465769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status) 1466769be974SMarcel Holtmann { 1467769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features *cp; 1468769be974SMarcel Holtmann struct hci_conn *conn; 1469769be974SMarcel Holtmann 14709f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1471769be974SMarcel Holtmann 1472769be974SMarcel Holtmann if (!status) 1473769be974SMarcel Holtmann return; 1474769be974SMarcel Holtmann 1475769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES); 1476769be974SMarcel Holtmann if (!cp) 1477769be974SMarcel Holtmann return; 1478769be974SMarcel Holtmann 1479769be974SMarcel Holtmann hci_dev_lock(hdev); 1480769be974SMarcel Holtmann 1481769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1482769be974SMarcel Holtmann if (conn) { 1483769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 1484769be974SMarcel Holtmann hci_proto_connect_cfm(conn, status); 148576a68ba0SDavid Herrmann hci_conn_drop(conn); 1486769be974SMarcel Holtmann } 1487769be974SMarcel Holtmann } 1488769be974SMarcel Holtmann 1489769be974SMarcel Holtmann hci_dev_unlock(hdev); 1490769be974SMarcel Holtmann } 1491769be974SMarcel Holtmann 1492a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) 1493a9de9248SMarcel Holtmann { 1494b6a0dc82SMarcel Holtmann struct hci_cp_setup_sync_conn *cp; 1495b6a0dc82SMarcel Holtmann struct hci_conn *acl, *sco; 1496b6a0dc82SMarcel Holtmann __u16 handle; 1497b6a0dc82SMarcel Holtmann 14989f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1499b6a0dc82SMarcel Holtmann 1500b6a0dc82SMarcel Holtmann if (!status) 1501b6a0dc82SMarcel Holtmann return; 1502b6a0dc82SMarcel Holtmann 1503b6a0dc82SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN); 1504b6a0dc82SMarcel Holtmann if (!cp) 1505b6a0dc82SMarcel Holtmann return; 1506b6a0dc82SMarcel Holtmann 1507b6a0dc82SMarcel Holtmann handle = __le16_to_cpu(cp->handle); 1508b6a0dc82SMarcel Holtmann 15099f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, handle); 1510b6a0dc82SMarcel Holtmann 1511b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 1512b6a0dc82SMarcel Holtmann 1513b6a0dc82SMarcel Holtmann acl = hci_conn_hash_lookup_handle(hdev, handle); 15145a08ecceSAndrei Emeltchenko if (acl) { 15155a08ecceSAndrei Emeltchenko sco = acl->link; 15165a08ecceSAndrei Emeltchenko if (sco) { 1517b6a0dc82SMarcel Holtmann sco->state = BT_CLOSED; 1518b6a0dc82SMarcel Holtmann 1519b6a0dc82SMarcel Holtmann hci_proto_connect_cfm(sco, status); 1520b6a0dc82SMarcel Holtmann hci_conn_del(sco); 1521b6a0dc82SMarcel Holtmann } 15225a08ecceSAndrei Emeltchenko } 1523b6a0dc82SMarcel Holtmann 1524b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 1525a9de9248SMarcel Holtmann } 1526a9de9248SMarcel Holtmann 1527a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) 1528a9de9248SMarcel Holtmann { 1529a9de9248SMarcel Holtmann struct hci_cp_sniff_mode *cp; 153004837f64SMarcel Holtmann struct hci_conn *conn; 153104837f64SMarcel Holtmann 15329f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1533a9de9248SMarcel Holtmann 1534a9de9248SMarcel Holtmann if (!status) 1535a9de9248SMarcel Holtmann return; 1536a9de9248SMarcel Holtmann 1537a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE); 153804837f64SMarcel Holtmann if (!cp) 1539a9de9248SMarcel Holtmann return; 154004837f64SMarcel Holtmann 154104837f64SMarcel Holtmann hci_dev_lock(hdev); 154204837f64SMarcel Holtmann 154304837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1544e73439d8SMarcel Holtmann if (conn) { 154551a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 154604837f64SMarcel Holtmann 154751a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 1548e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 1549e73439d8SMarcel Holtmann } 1550e73439d8SMarcel Holtmann 155104837f64SMarcel Holtmann hci_dev_unlock(hdev); 155204837f64SMarcel Holtmann } 155304837f64SMarcel Holtmann 1554a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) 1555a9de9248SMarcel Holtmann { 1556a9de9248SMarcel Holtmann struct hci_cp_exit_sniff_mode *cp; 155704837f64SMarcel Holtmann struct hci_conn *conn; 155804837f64SMarcel Holtmann 15599f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 1560a9de9248SMarcel Holtmann 1561a9de9248SMarcel Holtmann if (!status) 1562a9de9248SMarcel Holtmann return; 1563a9de9248SMarcel Holtmann 1564a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE); 156504837f64SMarcel Holtmann if (!cp) 1566a9de9248SMarcel Holtmann return; 156704837f64SMarcel Holtmann 156804837f64SMarcel Holtmann hci_dev_lock(hdev); 156904837f64SMarcel Holtmann 157004837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 1571e73439d8SMarcel Holtmann if (conn) { 157251a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 157304837f64SMarcel Holtmann 157451a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 1575e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 1576e73439d8SMarcel Holtmann } 1577e73439d8SMarcel Holtmann 157804837f64SMarcel Holtmann hci_dev_unlock(hdev); 157904837f64SMarcel Holtmann } 158004837f64SMarcel Holtmann 158188c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) 158288c3df13SJohan Hedberg { 158388c3df13SJohan Hedberg struct hci_cp_disconnect *cp; 158488c3df13SJohan Hedberg struct hci_conn *conn; 158588c3df13SJohan Hedberg 158688c3df13SJohan Hedberg if (!status) 158788c3df13SJohan Hedberg return; 158888c3df13SJohan Hedberg 158988c3df13SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT); 159088c3df13SJohan Hedberg if (!cp) 159188c3df13SJohan Hedberg return; 159288c3df13SJohan Hedberg 159388c3df13SJohan Hedberg hci_dev_lock(hdev); 159488c3df13SJohan Hedberg 159588c3df13SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 159688c3df13SJohan Hedberg if (conn) 159788c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 159888c3df13SJohan Hedberg conn->dst_type, status); 159988c3df13SJohan Hedberg 160088c3df13SJohan Hedberg hci_dev_unlock(hdev); 160188c3df13SJohan Hedberg } 160288c3df13SJohan Hedberg 1603a02226d6SAndrei Emeltchenko static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status) 1604a02226d6SAndrei Emeltchenko { 160593c284eeSAndrei Emeltchenko struct hci_cp_create_phy_link *cp; 160693c284eeSAndrei Emeltchenko 1607a02226d6SAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 160893c284eeSAndrei Emeltchenko 160993c284eeSAndrei Emeltchenko cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK); 161093c284eeSAndrei Emeltchenko if (!cp) 161193c284eeSAndrei Emeltchenko return; 161293c284eeSAndrei Emeltchenko 1613e58917b9SAndrei Emeltchenko hci_dev_lock(hdev); 1614e58917b9SAndrei Emeltchenko 1615e58917b9SAndrei Emeltchenko if (status) { 1616e58917b9SAndrei Emeltchenko struct hci_conn *hcon; 1617e58917b9SAndrei Emeltchenko 1618e58917b9SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle); 1619e58917b9SAndrei Emeltchenko if (hcon) 1620e58917b9SAndrei Emeltchenko hci_conn_del(hcon); 1621e58917b9SAndrei Emeltchenko } else { 162293c284eeSAndrei Emeltchenko amp_write_remote_assoc(hdev, cp->phy_handle); 1623a02226d6SAndrei Emeltchenko } 1624a02226d6SAndrei Emeltchenko 1625e58917b9SAndrei Emeltchenko hci_dev_unlock(hdev); 1626e58917b9SAndrei Emeltchenko } 1627e58917b9SAndrei Emeltchenko 16280b26ab9dSAndrei Emeltchenko static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status) 16290b26ab9dSAndrei Emeltchenko { 16300b26ab9dSAndrei Emeltchenko struct hci_cp_accept_phy_link *cp; 16310b26ab9dSAndrei Emeltchenko 16320b26ab9dSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 16330b26ab9dSAndrei Emeltchenko 16340b26ab9dSAndrei Emeltchenko if (status) 16350b26ab9dSAndrei Emeltchenko return; 16360b26ab9dSAndrei Emeltchenko 16370b26ab9dSAndrei Emeltchenko cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK); 16380b26ab9dSAndrei Emeltchenko if (!cp) 16390b26ab9dSAndrei Emeltchenko return; 16400b26ab9dSAndrei Emeltchenko 16410b26ab9dSAndrei Emeltchenko amp_write_remote_assoc(hdev, cp->phy_handle); 16420b26ab9dSAndrei Emeltchenko } 16430b26ab9dSAndrei Emeltchenko 1644cb1d68f7SJohan Hedberg static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status) 1645cb1d68f7SJohan Hedberg { 1646cb1d68f7SJohan Hedberg struct hci_cp_le_create_conn *cp; 1647cb1d68f7SJohan Hedberg struct hci_conn *conn; 1648cb1d68f7SJohan Hedberg 1649cb1d68f7SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, status); 1650cb1d68f7SJohan Hedberg 1651cb1d68f7SJohan Hedberg /* All connection failure handling is taken care of by the 1652cb1d68f7SJohan Hedberg * hci_le_conn_failed function which is triggered by the HCI 1653cb1d68f7SJohan Hedberg * request completion callbacks used for connecting. 1654cb1d68f7SJohan Hedberg */ 1655cb1d68f7SJohan Hedberg if (status) 1656cb1d68f7SJohan Hedberg return; 1657cb1d68f7SJohan Hedberg 1658cb1d68f7SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN); 1659cb1d68f7SJohan Hedberg if (!cp) 1660cb1d68f7SJohan Hedberg return; 1661cb1d68f7SJohan Hedberg 1662cb1d68f7SJohan Hedberg hci_dev_lock(hdev); 1663cb1d68f7SJohan Hedberg 1664cb1d68f7SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr); 1665cb1d68f7SJohan Hedberg if (!conn) 1666cb1d68f7SJohan Hedberg goto unlock; 1667cb1d68f7SJohan Hedberg 1668cb1d68f7SJohan Hedberg /* Store the initiator and responder address information which 1669cb1d68f7SJohan Hedberg * is needed for SMP. These values will not change during the 1670cb1d68f7SJohan Hedberg * lifetime of the connection. 1671cb1d68f7SJohan Hedberg */ 1672cb1d68f7SJohan Hedberg conn->init_addr_type = cp->own_address_type; 1673cb1d68f7SJohan Hedberg if (cp->own_address_type == ADDR_LE_DEV_RANDOM) 1674cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->random_addr); 1675cb1d68f7SJohan Hedberg else 1676cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->bdaddr); 1677cb1d68f7SJohan Hedberg 1678cb1d68f7SJohan Hedberg conn->resp_addr_type = cp->peer_addr_type; 1679cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &cp->peer_addr); 1680cb1d68f7SJohan Hedberg 16819489eca4SJohan Hedberg /* We don't want the connection attempt to stick around 16829489eca4SJohan Hedberg * indefinitely since LE doesn't have a page timeout concept 16839489eca4SJohan Hedberg * like BR/EDR. Set a timer for any connection that doesn't use 16849489eca4SJohan Hedberg * the white list for connecting. 16859489eca4SJohan Hedberg */ 16869489eca4SJohan Hedberg if (cp->filter_policy == HCI_LE_USE_PEER_ADDR) 16879489eca4SJohan Hedberg queue_delayed_work(conn->hdev->workqueue, 16889489eca4SJohan Hedberg &conn->le_conn_timeout, 16899489eca4SJohan Hedberg HCI_LE_CONN_TIMEOUT); 16909489eca4SJohan Hedberg 1691cb1d68f7SJohan Hedberg unlock: 1692cb1d68f7SJohan Hedberg hci_dev_unlock(hdev); 1693cb1d68f7SJohan Hedberg } 1694cb1d68f7SJohan Hedberg 16956039aa73SGustavo Padovan static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 16961da177e4SLinus Torvalds { 16971da177e4SLinus Torvalds __u8 status = *((__u8 *) skb->data); 169830dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 169930dc78e1SJohan Hedberg struct inquiry_entry *e; 17001da177e4SLinus Torvalds 17019f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, status); 17021da177e4SLinus Torvalds 1703a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 170489352e7dSAndre Guedes 170589352e7dSAndre Guedes if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) 170689352e7dSAndre Guedes return; 170789352e7dSAndre Guedes 17083e13fa1eSAndre Guedes smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */ 17093e13fa1eSAndre Guedes wake_up_bit(&hdev->flags, HCI_INQUIRY); 17103e13fa1eSAndre Guedes 1711a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 171230dc78e1SJohan Hedberg return; 171330dc78e1SJohan Hedberg 171456e5cb86SJohan Hedberg hci_dev_lock(hdev); 171530dc78e1SJohan Hedberg 1716343f935bSAndre Guedes if (discov->state != DISCOVERY_FINDING) 171730dc78e1SJohan Hedberg goto unlock; 171830dc78e1SJohan Hedberg 171930dc78e1SJohan Hedberg if (list_empty(&discov->resolve)) { 1720ff9ef578SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 172130dc78e1SJohan Hedberg goto unlock; 172230dc78e1SJohan Hedberg } 172330dc78e1SJohan Hedberg 172430dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 172530dc78e1SJohan Hedberg if (e && hci_resolve_name(hdev, e) == 0) { 172630dc78e1SJohan Hedberg e->name_state = NAME_PENDING; 172730dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_RESOLVING); 172830dc78e1SJohan Hedberg } else { 172930dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 173030dc78e1SJohan Hedberg } 173130dc78e1SJohan Hedberg 173230dc78e1SJohan Hedberg unlock: 173356e5cb86SJohan Hedberg hci_dev_unlock(hdev); 17341da177e4SLinus Torvalds } 17351da177e4SLinus Torvalds 17366039aa73SGustavo Padovan static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) 17371da177e4SLinus Torvalds { 173845bb4bf0SMarcel Holtmann struct inquiry_data data; 1739a9de9248SMarcel Holtmann struct inquiry_info *info = (void *) (skb->data + 1); 17401da177e4SLinus Torvalds int num_rsp = *((__u8 *) skb->data); 17411da177e4SLinus Torvalds 17421da177e4SLinus Torvalds BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 17431da177e4SLinus Torvalds 174445bb4bf0SMarcel Holtmann if (!num_rsp) 174545bb4bf0SMarcel Holtmann return; 174645bb4bf0SMarcel Holtmann 17471519cc17SAndre Guedes if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) 17481519cc17SAndre Guedes return; 17491519cc17SAndre Guedes 17501da177e4SLinus Torvalds hci_dev_lock(hdev); 175145bb4bf0SMarcel Holtmann 1752e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 1753388fc8faSJohan Hedberg bool name_known, ssp; 17543175405bSJohan Hedberg 17551da177e4SLinus Torvalds bacpy(&data.bdaddr, &info->bdaddr); 17561da177e4SLinus Torvalds data.pscan_rep_mode = info->pscan_rep_mode; 17571da177e4SLinus Torvalds data.pscan_period_mode = info->pscan_period_mode; 17581da177e4SLinus Torvalds data.pscan_mode = info->pscan_mode; 17591da177e4SLinus Torvalds memcpy(data.dev_class, info->dev_class, 3); 17601da177e4SLinus Torvalds data.clock_offset = info->clock_offset; 17611da177e4SLinus Torvalds data.rssi = 0x00; 176241a96212SMarcel Holtmann data.ssp_mode = 0x00; 17633175405bSJohan Hedberg 1764388fc8faSJohan Hedberg name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp); 176548264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 176604124681SGustavo F. Padovan info->dev_class, 0, !name_known, ssp, NULL, 176704124681SGustavo F. Padovan 0); 17681da177e4SLinus Torvalds } 176945bb4bf0SMarcel Holtmann 17701da177e4SLinus Torvalds hci_dev_unlock(hdev); 17711da177e4SLinus Torvalds } 17721da177e4SLinus Torvalds 17736039aa73SGustavo Padovan static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 17741da177e4SLinus Torvalds { 1775a9de9248SMarcel Holtmann struct hci_ev_conn_complete *ev = (void *) skb->data; 1776a9de9248SMarcel Holtmann struct hci_conn *conn; 17771da177e4SLinus Torvalds 1778a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 177945bb4bf0SMarcel Holtmann 17801da177e4SLinus Torvalds hci_dev_lock(hdev); 178145bb4bf0SMarcel Holtmann 1782a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 17839499237aSMarcel Holtmann if (!conn) { 17849499237aSMarcel Holtmann if (ev->link_type != SCO_LINK) 17859499237aSMarcel Holtmann goto unlock; 17869499237aSMarcel Holtmann 17879499237aSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 1788a9de9248SMarcel Holtmann if (!conn) 1789a9de9248SMarcel Holtmann goto unlock; 179045bb4bf0SMarcel Holtmann 17919499237aSMarcel Holtmann conn->type = SCO_LINK; 17929499237aSMarcel Holtmann } 17939499237aSMarcel Holtmann 1794a9de9248SMarcel Holtmann if (!ev->status) { 1795a9de9248SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 1796769be974SMarcel Holtmann 1797769be974SMarcel Holtmann if (conn->type == ACL_LINK) { 1798769be974SMarcel Holtmann conn->state = BT_CONFIG; 1799769be974SMarcel Holtmann hci_conn_hold(conn); 1800a9ea3ed9SSzymon Janc 1801a9ea3ed9SSzymon Janc if (!conn->out && !hci_conn_ssp_enabled(conn) && 1802a9ea3ed9SSzymon Janc !hci_find_link_key(hdev, &ev->bdaddr)) 1803a9ea3ed9SSzymon Janc conn->disc_timeout = HCI_PAIRING_TIMEOUT; 1804a9ea3ed9SSzymon Janc else 1805052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 1806769be974SMarcel Holtmann } else 1807a9de9248SMarcel Holtmann conn->state = BT_CONNECTED; 1808a9de9248SMarcel Holtmann 18097d0db0a3SMarcel Holtmann hci_conn_add_sysfs(conn); 18107d0db0a3SMarcel Holtmann 1811a9de9248SMarcel Holtmann if (test_bit(HCI_AUTH, &hdev->flags)) 1812a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_AUTH; 1813a9de9248SMarcel Holtmann 1814a9de9248SMarcel Holtmann if (test_bit(HCI_ENCRYPT, &hdev->flags)) 1815a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_ENCRYPT; 1816a9de9248SMarcel Holtmann 1817a9de9248SMarcel Holtmann /* Get remote features */ 1818a9de9248SMarcel Holtmann if (conn->type == ACL_LINK) { 1819a9de9248SMarcel Holtmann struct hci_cp_read_remote_features cp; 1820a9de9248SMarcel Holtmann cp.handle = ev->handle; 1821769be974SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, 1822769be974SMarcel Holtmann sizeof(cp), &cp); 182345bb4bf0SMarcel Holtmann } 1824a9de9248SMarcel Holtmann 1825a9de9248SMarcel Holtmann /* Set packet type for incoming connection */ 1826d095c1ebSAndrei Emeltchenko if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) { 1827a9de9248SMarcel Holtmann struct hci_cp_change_conn_ptype cp; 1828a9de9248SMarcel Holtmann cp.handle = ev->handle; 1829a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 183004124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), 183104124681SGustavo F. Padovan &cp); 1832a9de9248SMarcel Holtmann } 183317d5c04cSJohan Hedberg } else { 1834a9de9248SMarcel Holtmann conn->state = BT_CLOSED; 183517d5c04cSJohan Hedberg if (conn->type == ACL_LINK) 183664c7b77cSMarcel Holtmann mgmt_connect_failed(hdev, &conn->dst, conn->type, 183748264f06SJohan Hedberg conn->dst_type, ev->status); 183817d5c04cSJohan Hedberg } 183945bb4bf0SMarcel Holtmann 1840e73439d8SMarcel Holtmann if (conn->type == ACL_LINK) 1841e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 184245bb4bf0SMarcel Holtmann 1843769be974SMarcel Holtmann if (ev->status) { 1844a9de9248SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 1845a9de9248SMarcel Holtmann hci_conn_del(conn); 1846c89b6e6bSMarcel Holtmann } else if (ev->link_type != ACL_LINK) 1847c89b6e6bSMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 1848a9de9248SMarcel Holtmann 1849a9de9248SMarcel Holtmann unlock: 18501da177e4SLinus Torvalds hci_dev_unlock(hdev); 1851a9de9248SMarcel Holtmann 1852a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 18531da177e4SLinus Torvalds } 18541da177e4SLinus Torvalds 18556039aa73SGustavo Padovan static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 18561da177e4SLinus Torvalds { 1857a9de9248SMarcel Holtmann struct hci_ev_conn_request *ev = (void *) skb->data; 18581da177e4SLinus Torvalds int mask = hdev->link_mode; 185920714bfeSFrédéric Dalleau __u8 flags = 0; 18601da177e4SLinus Torvalds 18616ed93dc6SAndrei Emeltchenko BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr, 1862807deac2SGustavo Padovan ev->link_type); 18631da177e4SLinus Torvalds 186420714bfeSFrédéric Dalleau mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type, 186520714bfeSFrédéric Dalleau &flags); 18661da177e4SLinus Torvalds 1867138d22efSSzymon Janc if ((mask & HCI_LM_ACCEPT) && 1868b9ee0a78SMarcel Holtmann !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) { 18691da177e4SLinus Torvalds /* Connection accepted */ 1870c7bdd502SMarcel Holtmann struct inquiry_entry *ie; 18711da177e4SLinus Torvalds struct hci_conn *conn; 18721da177e4SLinus Torvalds 18731da177e4SLinus Torvalds hci_dev_lock(hdev); 1874b6a0dc82SMarcel Holtmann 1875cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 1876cc11b9c1SAndrei Emeltchenko if (ie) 1877c7bdd502SMarcel Holtmann memcpy(ie->data.dev_class, ev->dev_class, 3); 1878c7bdd502SMarcel Holtmann 18798fc9ced3SGustavo Padovan conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, 18808fc9ced3SGustavo Padovan &ev->bdaddr); 18811da177e4SLinus Torvalds if (!conn) { 1882cc11b9c1SAndrei Emeltchenko conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr); 1883cc11b9c1SAndrei Emeltchenko if (!conn) { 1884893ef971SGustavo F. Padovan BT_ERR("No memory for new connection"); 18851da177e4SLinus Torvalds hci_dev_unlock(hdev); 18861da177e4SLinus Torvalds return; 18871da177e4SLinus Torvalds } 18881da177e4SLinus Torvalds } 1889b6a0dc82SMarcel Holtmann 18901da177e4SLinus Torvalds memcpy(conn->dev_class, ev->dev_class, 3); 1891b6a0dc82SMarcel Holtmann 18921da177e4SLinus Torvalds hci_dev_unlock(hdev); 18931da177e4SLinus Torvalds 189420714bfeSFrédéric Dalleau if (ev->link_type == ACL_LINK || 189520714bfeSFrédéric Dalleau (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) { 1896b6a0dc82SMarcel Holtmann struct hci_cp_accept_conn_req cp; 189720714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 1898b6a0dc82SMarcel Holtmann 18991da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 19001da177e4SLinus Torvalds 19011da177e4SLinus Torvalds if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) 19021da177e4SLinus Torvalds cp.role = 0x00; /* Become master */ 19031da177e4SLinus Torvalds else 19041da177e4SLinus Torvalds cp.role = 0x01; /* Remain slave */ 19051da177e4SLinus Torvalds 190604124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), 190704124681SGustavo F. Padovan &cp); 190820714bfeSFrédéric Dalleau } else if (!(flags & HCI_PROTO_DEFER)) { 1909b6a0dc82SMarcel Holtmann struct hci_cp_accept_sync_conn_req cp; 191020714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 1911b6a0dc82SMarcel Holtmann 1912b6a0dc82SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 1913a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 1914b6a0dc82SMarcel Holtmann 191582781e63SAndrei Emeltchenko cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40); 191682781e63SAndrei Emeltchenko cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40); 191782781e63SAndrei Emeltchenko cp.max_latency = __constant_cpu_to_le16(0xffff); 1918b6a0dc82SMarcel Holtmann cp.content_format = cpu_to_le16(hdev->voice_setting); 1919b6a0dc82SMarcel Holtmann cp.retrans_effort = 0xff; 1920b6a0dc82SMarcel Holtmann 1921b6a0dc82SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, 1922b6a0dc82SMarcel Holtmann sizeof(cp), &cp); 192320714bfeSFrédéric Dalleau } else { 192420714bfeSFrédéric Dalleau conn->state = BT_CONNECT2; 192520714bfeSFrédéric Dalleau hci_proto_connect_cfm(conn, 0); 1926b6a0dc82SMarcel Holtmann } 19271da177e4SLinus Torvalds } else { 19281da177e4SLinus Torvalds /* Connection rejected */ 19291da177e4SLinus Torvalds struct hci_cp_reject_conn_req cp; 19301da177e4SLinus Torvalds 19311da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 19329f5a0d7bSAndrei Emeltchenko cp.reason = HCI_ERROR_REJ_BAD_ADDR; 1933a9de9248SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); 19341da177e4SLinus Torvalds } 19351da177e4SLinus Torvalds } 19361da177e4SLinus Torvalds 1937f0d6a0eaSMikel Astiz static u8 hci_to_mgmt_reason(u8 err) 1938f0d6a0eaSMikel Astiz { 1939f0d6a0eaSMikel Astiz switch (err) { 1940f0d6a0eaSMikel Astiz case HCI_ERROR_CONNECTION_TIMEOUT: 1941f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_TIMEOUT; 1942f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_USER_TERM: 1943f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_LOW_RESOURCES: 1944f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_POWER_OFF: 1945f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_REMOTE; 1946f0d6a0eaSMikel Astiz case HCI_ERROR_LOCAL_HOST_TERM: 1947f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_LOCAL_HOST; 1948f0d6a0eaSMikel Astiz default: 1949f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_UNKNOWN; 1950f0d6a0eaSMikel Astiz } 1951f0d6a0eaSMikel Astiz } 1952f0d6a0eaSMikel Astiz 19536039aa73SGustavo Padovan static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 19541da177e4SLinus Torvalds { 1955a9de9248SMarcel Holtmann struct hci_ev_disconn_complete *ev = (void *) skb->data; 1956abf54a50SAndre Guedes u8 reason = hci_to_mgmt_reason(ev->reason); 19579fcb18efSAndre Guedes struct hci_conn_params *params; 195804837f64SMarcel Holtmann struct hci_conn *conn; 195912d4a3b2SJohan Hedberg bool mgmt_connected; 19603846220bSAndre Guedes u8 type; 19611da177e4SLinus Torvalds 19629f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 19631da177e4SLinus Torvalds 19641da177e4SLinus Torvalds hci_dev_lock(hdev); 19651da177e4SLinus Torvalds 196604837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 1967f7520543SJohan Hedberg if (!conn) 1968f7520543SJohan Hedberg goto unlock; 1969f7520543SJohan Hedberg 1970f0d6a0eaSMikel Astiz if (ev->status) { 197188c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 197288c3df13SJohan Hedberg conn->dst_type, ev->status); 1973abf54a50SAndre Guedes goto unlock; 1974abf54a50SAndre Guedes } 1975f0d6a0eaSMikel Astiz 19763846220bSAndre Guedes conn->state = BT_CLOSED; 19773846220bSAndre Guedes 197812d4a3b2SJohan Hedberg mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags); 197912d4a3b2SJohan Hedberg mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type, 198012d4a3b2SJohan Hedberg reason, mgmt_connected); 1981f7520543SJohan Hedberg 19823846220bSAndre Guedes if (conn->type == ACL_LINK && conn->flush_key) 19836ec5bcadSVishal Agarwal hci_remove_link_key(hdev, &conn->dst); 19843846220bSAndre Guedes 19859fcb18efSAndre Guedes params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); 19869fcb18efSAndre Guedes if (params) { 19879fcb18efSAndre Guedes switch (params->auto_connect) { 19889fcb18efSAndre Guedes case HCI_AUTO_CONN_LINK_LOSS: 19899fcb18efSAndre Guedes if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT) 19909fcb18efSAndre Guedes break; 19919fcb18efSAndre Guedes /* Fall through */ 19929fcb18efSAndre Guedes 19939fcb18efSAndre Guedes case HCI_AUTO_CONN_ALWAYS: 19949fcb18efSAndre Guedes hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type); 19959fcb18efSAndre Guedes break; 19969fcb18efSAndre Guedes 19979fcb18efSAndre Guedes default: 19989fcb18efSAndre Guedes break; 19999fcb18efSAndre Guedes } 20009fcb18efSAndre Guedes } 20019fcb18efSAndre Guedes 20023846220bSAndre Guedes type = conn->type; 20033846220bSAndre Guedes 20042950f21aSMarcel Holtmann hci_proto_disconn_cfm(conn, ev->reason); 20051da177e4SLinus Torvalds hci_conn_del(conn); 20062210246cSJohan Hedberg 20072210246cSJohan Hedberg /* Re-enable advertising if necessary, since it might 20082210246cSJohan Hedberg * have been disabled by the connection. From the 20092210246cSJohan Hedberg * HCI_LE_Set_Advertise_Enable command description in 20102210246cSJohan Hedberg * the core specification (v4.0): 20112210246cSJohan Hedberg * "The Controller shall continue advertising until the Host 20122210246cSJohan Hedberg * issues an LE_Set_Advertise_Enable command with 20132210246cSJohan Hedberg * Advertising_Enable set to 0x00 (Advertising is disabled) 20142210246cSJohan Hedberg * or until a connection is created or until the Advertising 20152210246cSJohan Hedberg * is timed out due to Directed Advertising." 20162210246cSJohan Hedberg */ 20172210246cSJohan Hedberg if (type == LE_LINK) 20185976e608SMarcel Holtmann mgmt_reenable_advertising(hdev); 20191da177e4SLinus Torvalds 2020f7520543SJohan Hedberg unlock: 20211da177e4SLinus Torvalds hci_dev_unlock(hdev); 20221da177e4SLinus Torvalds } 20231da177e4SLinus Torvalds 20246039aa73SGustavo Padovan static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2025a9de9248SMarcel Holtmann { 2026a9de9248SMarcel Holtmann struct hci_ev_auth_complete *ev = (void *) skb->data; 2027a9de9248SMarcel Holtmann struct hci_conn *conn; 2028a9de9248SMarcel Holtmann 20299f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2030a9de9248SMarcel Holtmann 2031a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2032a9de9248SMarcel Holtmann 2033a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2034d7556e20SWaldemar Rymarkiewicz if (!conn) 2035d7556e20SWaldemar Rymarkiewicz goto unlock; 2036d7556e20SWaldemar Rymarkiewicz 2037765c2a96SJohan Hedberg if (!ev->status) { 2038aa64a8b5SJohan Hedberg if (!hci_conn_ssp_enabled(conn) && 203951a8efd7SJohan Hedberg test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { 2040d7556e20SWaldemar Rymarkiewicz BT_INFO("re-auth of legacy device is not possible."); 204119f8def0SWaldemar Rymarkiewicz } else { 2042a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_AUTH; 2043765c2a96SJohan Hedberg conn->sec_level = conn->pending_sec_level; 204419f8def0SWaldemar Rymarkiewicz } 20452a611692SJohan Hedberg } else { 2046bab73cb6SJohan Hedberg mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, 2047bab73cb6SJohan Hedberg ev->status); 20482a611692SJohan Hedberg } 2049a9de9248SMarcel Holtmann 205051a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 205151a8efd7SJohan Hedberg clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags); 2052a9de9248SMarcel Holtmann 2053f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 2054aa64a8b5SJohan Hedberg if (!ev->status && hci_conn_ssp_enabled(conn)) { 2055f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 2056f8558555SMarcel Holtmann cp.handle = ev->handle; 2057f8558555SMarcel Holtmann cp.encrypt = 0x01; 2058d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 2059d7556e20SWaldemar Rymarkiewicz &cp); 2060f8558555SMarcel Holtmann } else { 2061f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 2062f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 206376a68ba0SDavid Herrmann hci_conn_drop(conn); 2064f8558555SMarcel Holtmann } 2065052b30b0SMarcel Holtmann } else { 2066a9de9248SMarcel Holtmann hci_auth_cfm(conn, ev->status); 2067a9de9248SMarcel Holtmann 2068052b30b0SMarcel Holtmann hci_conn_hold(conn); 2069052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 207076a68ba0SDavid Herrmann hci_conn_drop(conn); 2071052b30b0SMarcel Holtmann } 2072052b30b0SMarcel Holtmann 207351a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { 2074a9de9248SMarcel Holtmann if (!ev->status) { 2075a9de9248SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 2076f8558555SMarcel Holtmann cp.handle = ev->handle; 2077f8558555SMarcel Holtmann cp.encrypt = 0x01; 2078d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 2079d7556e20SWaldemar Rymarkiewicz &cp); 2080a9de9248SMarcel Holtmann } else { 208151a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 2082a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, 0x00); 2083a9de9248SMarcel Holtmann } 2084a9de9248SMarcel Holtmann } 2085a9de9248SMarcel Holtmann 2086d7556e20SWaldemar Rymarkiewicz unlock: 2087a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2088a9de9248SMarcel Holtmann } 2089a9de9248SMarcel Holtmann 20906039aa73SGustavo Padovan static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) 2091a9de9248SMarcel Holtmann { 2092127178d2SJohan Hedberg struct hci_ev_remote_name *ev = (void *) skb->data; 2093127178d2SJohan Hedberg struct hci_conn *conn; 2094127178d2SJohan Hedberg 2095a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2096a9de9248SMarcel Holtmann 2097a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 2098127178d2SJohan Hedberg 2099127178d2SJohan Hedberg hci_dev_lock(hdev); 2100127178d2SJohan Hedberg 2101127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2102b644ba33SJohan Hedberg 2103b644ba33SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2104b644ba33SJohan Hedberg goto check_auth; 2105b644ba33SJohan Hedberg 2106b644ba33SJohan Hedberg if (ev->status == 0) 2107b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name, 2108b644ba33SJohan Hedberg strnlen(ev->name, HCI_MAX_NAME_LENGTH)); 2109b644ba33SJohan Hedberg else 2110b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0); 2111b644ba33SJohan Hedberg 2112b644ba33SJohan Hedberg check_auth: 211379c6c70cSJohan Hedberg if (!conn) 211479c6c70cSJohan Hedberg goto unlock; 211579c6c70cSJohan Hedberg 211679c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 211779c6c70cSJohan Hedberg goto unlock; 211879c6c70cSJohan Hedberg 211951a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 2120127178d2SJohan Hedberg struct hci_cp_auth_requested cp; 2121127178d2SJohan Hedberg cp.handle = __cpu_to_le16(conn->handle); 2122127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); 2123127178d2SJohan Hedberg } 2124127178d2SJohan Hedberg 212579c6c70cSJohan Hedberg unlock: 2126127178d2SJohan Hedberg hci_dev_unlock(hdev); 2127a9de9248SMarcel Holtmann } 2128a9de9248SMarcel Holtmann 21296039aa73SGustavo Padovan static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2130a9de9248SMarcel Holtmann { 2131a9de9248SMarcel Holtmann struct hci_ev_encrypt_change *ev = (void *) skb->data; 2132a9de9248SMarcel Holtmann struct hci_conn *conn; 2133a9de9248SMarcel Holtmann 21349f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2135a9de9248SMarcel Holtmann 2136a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2137a9de9248SMarcel Holtmann 2138a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2139dc8357ccSMarcel Holtmann if (!conn) 2140dc8357ccSMarcel Holtmann goto unlock; 2141dc8357ccSMarcel Holtmann 2142a9de9248SMarcel Holtmann if (!ev->status) { 2143ae293196SMarcel Holtmann if (ev->encrypt) { 2144ae293196SMarcel Holtmann /* Encryption implies authentication */ 2145ae293196SMarcel Holtmann conn->link_mode |= HCI_LM_AUTH; 2146a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_ENCRYPT; 2147da85e5e5SVinicius Costa Gomes conn->sec_level = conn->pending_sec_level; 2148abf76badSMarcel Holtmann 2149914a6ffeSMarcel Holtmann /* P-256 authentication key implies FIPS */ 2150914a6ffeSMarcel Holtmann if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256) 2151914a6ffeSMarcel Holtmann conn->link_mode |= HCI_LM_FIPS; 2152914a6ffeSMarcel Holtmann 2153abf76badSMarcel Holtmann if ((conn->type == ACL_LINK && ev->encrypt == 0x02) || 2154abf76badSMarcel Holtmann conn->type == LE_LINK) 2155abf76badSMarcel Holtmann set_bit(HCI_CONN_AES_CCM, &conn->flags); 2156abf76badSMarcel Holtmann } else { 2157a9de9248SMarcel Holtmann conn->link_mode &= ~HCI_LM_ENCRYPT; 2158abf76badSMarcel Holtmann clear_bit(HCI_CONN_AES_CCM, &conn->flags); 2159abf76badSMarcel Holtmann } 2160a9de9248SMarcel Holtmann } 2161a9de9248SMarcel Holtmann 216251a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 2163a9de9248SMarcel Holtmann 2164a7d7723aSGustavo Padovan if (ev->status && conn->state == BT_CONNECTED) { 2165bed71748SAndre Guedes hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 216676a68ba0SDavid Herrmann hci_conn_drop(conn); 2167a7d7723aSGustavo Padovan goto unlock; 2168a7d7723aSGustavo Padovan } 2169a7d7723aSGustavo Padovan 2170f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 2171f8558555SMarcel Holtmann if (!ev->status) 2172f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 2173f8558555SMarcel Holtmann 2174f8558555SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 217576a68ba0SDavid Herrmann hci_conn_drop(conn); 2176f8558555SMarcel Holtmann } else 2177a9de9248SMarcel Holtmann hci_encrypt_cfm(conn, ev->status, ev->encrypt); 2178a9de9248SMarcel Holtmann 2179a7d7723aSGustavo Padovan unlock: 2180a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2181a9de9248SMarcel Holtmann } 2182a9de9248SMarcel Holtmann 21836039aa73SGustavo Padovan static void hci_change_link_key_complete_evt(struct hci_dev *hdev, 2184807deac2SGustavo Padovan struct sk_buff *skb) 2185a9de9248SMarcel Holtmann { 2186a9de9248SMarcel Holtmann struct hci_ev_change_link_key_complete *ev = (void *) skb->data; 2187a9de9248SMarcel Holtmann struct hci_conn *conn; 2188a9de9248SMarcel Holtmann 21899f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2190a9de9248SMarcel Holtmann 2191a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2192a9de9248SMarcel Holtmann 2193a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2194a9de9248SMarcel Holtmann if (conn) { 2195a9de9248SMarcel Holtmann if (!ev->status) 2196a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_SECURE; 2197a9de9248SMarcel Holtmann 219851a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 2199a9de9248SMarcel Holtmann 2200a9de9248SMarcel Holtmann hci_key_change_cfm(conn, ev->status); 2201a9de9248SMarcel Holtmann } 2202a9de9248SMarcel Holtmann 2203a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2204a9de9248SMarcel Holtmann } 2205a9de9248SMarcel Holtmann 22066039aa73SGustavo Padovan static void hci_remote_features_evt(struct hci_dev *hdev, 2207807deac2SGustavo Padovan struct sk_buff *skb) 2208a9de9248SMarcel Holtmann { 2209a9de9248SMarcel Holtmann struct hci_ev_remote_features *ev = (void *) skb->data; 2210a9de9248SMarcel Holtmann struct hci_conn *conn; 2211a9de9248SMarcel Holtmann 22129f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2213a9de9248SMarcel Holtmann 2214a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2215a9de9248SMarcel Holtmann 2216a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2217ccd556feSJohan Hedberg if (!conn) 2218ccd556feSJohan Hedberg goto unlock; 2219ccd556feSJohan Hedberg 2220769be974SMarcel Holtmann if (!ev->status) 2221cad718edSJohan Hedberg memcpy(conn->features[0], ev->features, 8); 2222a9de9248SMarcel Holtmann 2223ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 2224ccd556feSJohan Hedberg goto unlock; 2225ccd556feSJohan Hedberg 2226ccd556feSJohan Hedberg if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) { 2227769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features cp; 2228769be974SMarcel Holtmann cp.handle = ev->handle; 2229769be974SMarcel Holtmann cp.page = 0x01; 2230ccd556feSJohan Hedberg hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, 2231769be974SMarcel Holtmann sizeof(cp), &cp); 2232392599b9SJohan Hedberg goto unlock; 2233392599b9SJohan Hedberg } 2234392599b9SJohan Hedberg 2235671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 2236127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 2237127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 2238127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 2239127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 2240127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 2241b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 2242b644ba33SJohan Hedberg mgmt_device_connected(hdev, &conn->dst, conn->type, 224308c79b61SJohan Hedberg conn->dst_type, 0, NULL, 0, 2244b644ba33SJohan Hedberg conn->dev_class); 2245392599b9SJohan Hedberg 2246127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 2247769be974SMarcel Holtmann conn->state = BT_CONNECTED; 2248769be974SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 224976a68ba0SDavid Herrmann hci_conn_drop(conn); 2250769be974SMarcel Holtmann } 2251769be974SMarcel Holtmann 2252ccd556feSJohan Hedberg unlock: 2253a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2254a9de9248SMarcel Holtmann } 2255a9de9248SMarcel Holtmann 22566039aa73SGustavo Padovan static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2257a9de9248SMarcel Holtmann { 2258a9de9248SMarcel Holtmann struct hci_ev_cmd_complete *ev = (void *) skb->data; 22599238f36aSJohan Hedberg u8 status = skb->data[sizeof(*ev)]; 2260a9de9248SMarcel Holtmann __u16 opcode; 2261a9de9248SMarcel Holtmann 2262a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 2263a9de9248SMarcel Holtmann 2264a9de9248SMarcel Holtmann opcode = __le16_to_cpu(ev->opcode); 2265a9de9248SMarcel Holtmann 2266a9de9248SMarcel Holtmann switch (opcode) { 2267a9de9248SMarcel Holtmann case HCI_OP_INQUIRY_CANCEL: 2268a9de9248SMarcel Holtmann hci_cc_inquiry_cancel(hdev, skb); 2269a9de9248SMarcel Holtmann break; 2270a9de9248SMarcel Holtmann 22714d93483bSAndre Guedes case HCI_OP_PERIODIC_INQ: 22724d93483bSAndre Guedes hci_cc_periodic_inq(hdev, skb); 22734d93483bSAndre Guedes break; 22744d93483bSAndre Guedes 2275a9de9248SMarcel Holtmann case HCI_OP_EXIT_PERIODIC_INQ: 2276a9de9248SMarcel Holtmann hci_cc_exit_periodic_inq(hdev, skb); 2277a9de9248SMarcel Holtmann break; 2278a9de9248SMarcel Holtmann 2279a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ_CANCEL: 2280a9de9248SMarcel Holtmann hci_cc_remote_name_req_cancel(hdev, skb); 2281a9de9248SMarcel Holtmann break; 2282a9de9248SMarcel Holtmann 2283a9de9248SMarcel Holtmann case HCI_OP_ROLE_DISCOVERY: 2284a9de9248SMarcel Holtmann hci_cc_role_discovery(hdev, skb); 2285a9de9248SMarcel Holtmann break; 2286a9de9248SMarcel Holtmann 2287e4e8e37cSMarcel Holtmann case HCI_OP_READ_LINK_POLICY: 2288e4e8e37cSMarcel Holtmann hci_cc_read_link_policy(hdev, skb); 2289e4e8e37cSMarcel Holtmann break; 2290e4e8e37cSMarcel Holtmann 2291a9de9248SMarcel Holtmann case HCI_OP_WRITE_LINK_POLICY: 2292a9de9248SMarcel Holtmann hci_cc_write_link_policy(hdev, skb); 2293a9de9248SMarcel Holtmann break; 2294a9de9248SMarcel Holtmann 2295e4e8e37cSMarcel Holtmann case HCI_OP_READ_DEF_LINK_POLICY: 2296e4e8e37cSMarcel Holtmann hci_cc_read_def_link_policy(hdev, skb); 2297e4e8e37cSMarcel Holtmann break; 2298e4e8e37cSMarcel Holtmann 2299e4e8e37cSMarcel Holtmann case HCI_OP_WRITE_DEF_LINK_POLICY: 2300e4e8e37cSMarcel Holtmann hci_cc_write_def_link_policy(hdev, skb); 2301e4e8e37cSMarcel Holtmann break; 2302e4e8e37cSMarcel Holtmann 2303a9de9248SMarcel Holtmann case HCI_OP_RESET: 2304a9de9248SMarcel Holtmann hci_cc_reset(hdev, skb); 2305a9de9248SMarcel Holtmann break; 2306a9de9248SMarcel Holtmann 2307a9de9248SMarcel Holtmann case HCI_OP_WRITE_LOCAL_NAME: 2308a9de9248SMarcel Holtmann hci_cc_write_local_name(hdev, skb); 2309a9de9248SMarcel Holtmann break; 2310a9de9248SMarcel Holtmann 2311a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_NAME: 2312a9de9248SMarcel Holtmann hci_cc_read_local_name(hdev, skb); 2313a9de9248SMarcel Holtmann break; 2314a9de9248SMarcel Holtmann 2315a9de9248SMarcel Holtmann case HCI_OP_WRITE_AUTH_ENABLE: 2316a9de9248SMarcel Holtmann hci_cc_write_auth_enable(hdev, skb); 2317a9de9248SMarcel Holtmann break; 2318a9de9248SMarcel Holtmann 2319a9de9248SMarcel Holtmann case HCI_OP_WRITE_ENCRYPT_MODE: 2320a9de9248SMarcel Holtmann hci_cc_write_encrypt_mode(hdev, skb); 2321a9de9248SMarcel Holtmann break; 2322a9de9248SMarcel Holtmann 2323a9de9248SMarcel Holtmann case HCI_OP_WRITE_SCAN_ENABLE: 2324a9de9248SMarcel Holtmann hci_cc_write_scan_enable(hdev, skb); 2325a9de9248SMarcel Holtmann break; 2326a9de9248SMarcel Holtmann 2327a9de9248SMarcel Holtmann case HCI_OP_READ_CLASS_OF_DEV: 2328a9de9248SMarcel Holtmann hci_cc_read_class_of_dev(hdev, skb); 2329a9de9248SMarcel Holtmann break; 2330a9de9248SMarcel Holtmann 2331a9de9248SMarcel Holtmann case HCI_OP_WRITE_CLASS_OF_DEV: 2332a9de9248SMarcel Holtmann hci_cc_write_class_of_dev(hdev, skb); 2333a9de9248SMarcel Holtmann break; 2334a9de9248SMarcel Holtmann 2335a9de9248SMarcel Holtmann case HCI_OP_READ_VOICE_SETTING: 2336a9de9248SMarcel Holtmann hci_cc_read_voice_setting(hdev, skb); 2337a9de9248SMarcel Holtmann break; 2338a9de9248SMarcel Holtmann 2339a9de9248SMarcel Holtmann case HCI_OP_WRITE_VOICE_SETTING: 2340a9de9248SMarcel Holtmann hci_cc_write_voice_setting(hdev, skb); 2341a9de9248SMarcel Holtmann break; 2342a9de9248SMarcel Holtmann 2343b4cb9fb2SMarcel Holtmann case HCI_OP_READ_NUM_SUPPORTED_IAC: 2344b4cb9fb2SMarcel Holtmann hci_cc_read_num_supported_iac(hdev, skb); 2345b4cb9fb2SMarcel Holtmann break; 2346b4cb9fb2SMarcel Holtmann 2347333140b5SMarcel Holtmann case HCI_OP_WRITE_SSP_MODE: 2348333140b5SMarcel Holtmann hci_cc_write_ssp_mode(hdev, skb); 2349333140b5SMarcel Holtmann break; 2350333140b5SMarcel Holtmann 2351eac83dc6SMarcel Holtmann case HCI_OP_WRITE_SC_SUPPORT: 2352eac83dc6SMarcel Holtmann hci_cc_write_sc_support(hdev, skb); 2353eac83dc6SMarcel Holtmann break; 2354eac83dc6SMarcel Holtmann 2355a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_VERSION: 2356a9de9248SMarcel Holtmann hci_cc_read_local_version(hdev, skb); 2357a9de9248SMarcel Holtmann break; 2358a9de9248SMarcel Holtmann 2359a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_COMMANDS: 2360a9de9248SMarcel Holtmann hci_cc_read_local_commands(hdev, skb); 2361a9de9248SMarcel Holtmann break; 2362a9de9248SMarcel Holtmann 2363a9de9248SMarcel Holtmann case HCI_OP_READ_LOCAL_FEATURES: 2364a9de9248SMarcel Holtmann hci_cc_read_local_features(hdev, skb); 2365a9de9248SMarcel Holtmann break; 2366a9de9248SMarcel Holtmann 2367971e3a4bSAndre Guedes case HCI_OP_READ_LOCAL_EXT_FEATURES: 2368971e3a4bSAndre Guedes hci_cc_read_local_ext_features(hdev, skb); 2369971e3a4bSAndre Guedes break; 2370971e3a4bSAndre Guedes 2371a9de9248SMarcel Holtmann case HCI_OP_READ_BUFFER_SIZE: 2372a9de9248SMarcel Holtmann hci_cc_read_buffer_size(hdev, skb); 2373a9de9248SMarcel Holtmann break; 2374a9de9248SMarcel Holtmann 2375a9de9248SMarcel Holtmann case HCI_OP_READ_BD_ADDR: 2376a9de9248SMarcel Holtmann hci_cc_read_bd_addr(hdev, skb); 2377a9de9248SMarcel Holtmann break; 2378a9de9248SMarcel Holtmann 2379f332ec66SJohan Hedberg case HCI_OP_READ_PAGE_SCAN_ACTIVITY: 2380f332ec66SJohan Hedberg hci_cc_read_page_scan_activity(hdev, skb); 2381f332ec66SJohan Hedberg break; 2382f332ec66SJohan Hedberg 23834a3ee763SJohan Hedberg case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY: 23844a3ee763SJohan Hedberg hci_cc_write_page_scan_activity(hdev, skb); 23854a3ee763SJohan Hedberg break; 23864a3ee763SJohan Hedberg 2387f332ec66SJohan Hedberg case HCI_OP_READ_PAGE_SCAN_TYPE: 2388f332ec66SJohan Hedberg hci_cc_read_page_scan_type(hdev, skb); 2389f332ec66SJohan Hedberg break; 2390f332ec66SJohan Hedberg 23914a3ee763SJohan Hedberg case HCI_OP_WRITE_PAGE_SCAN_TYPE: 23924a3ee763SJohan Hedberg hci_cc_write_page_scan_type(hdev, skb); 23934a3ee763SJohan Hedberg break; 23944a3ee763SJohan Hedberg 2395350ee4cfSAndrei Emeltchenko case HCI_OP_READ_DATA_BLOCK_SIZE: 2396350ee4cfSAndrei Emeltchenko hci_cc_read_data_block_size(hdev, skb); 2397350ee4cfSAndrei Emeltchenko break; 2398350ee4cfSAndrei Emeltchenko 23991e89cffbSAndrei Emeltchenko case HCI_OP_READ_FLOW_CONTROL_MODE: 24001e89cffbSAndrei Emeltchenko hci_cc_read_flow_control_mode(hdev, skb); 24011e89cffbSAndrei Emeltchenko break; 24021e89cffbSAndrei Emeltchenko 2403928abaa7SAndrei Emeltchenko case HCI_OP_READ_LOCAL_AMP_INFO: 2404928abaa7SAndrei Emeltchenko hci_cc_read_local_amp_info(hdev, skb); 2405928abaa7SAndrei Emeltchenko break; 2406928abaa7SAndrei Emeltchenko 2407903e4541SAndrei Emeltchenko case HCI_OP_READ_LOCAL_AMP_ASSOC: 2408903e4541SAndrei Emeltchenko hci_cc_read_local_amp_assoc(hdev, skb); 2409903e4541SAndrei Emeltchenko break; 2410903e4541SAndrei Emeltchenko 2411d5859e22SJohan Hedberg case HCI_OP_READ_INQ_RSP_TX_POWER: 2412d5859e22SJohan Hedberg hci_cc_read_inq_rsp_tx_power(hdev, skb); 2413d5859e22SJohan Hedberg break; 2414d5859e22SJohan Hedberg 2415980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_REPLY: 2416980e1a53SJohan Hedberg hci_cc_pin_code_reply(hdev, skb); 2417980e1a53SJohan Hedberg break; 2418980e1a53SJohan Hedberg 2419980e1a53SJohan Hedberg case HCI_OP_PIN_CODE_NEG_REPLY: 2420980e1a53SJohan Hedberg hci_cc_pin_code_neg_reply(hdev, skb); 2421980e1a53SJohan Hedberg break; 2422980e1a53SJohan Hedberg 2423c35938b2SSzymon Janc case HCI_OP_READ_LOCAL_OOB_DATA: 24244d2d2796SMarcel Holtmann hci_cc_read_local_oob_data(hdev, skb); 24254d2d2796SMarcel Holtmann break; 24264d2d2796SMarcel Holtmann 24274d2d2796SMarcel Holtmann case HCI_OP_READ_LOCAL_OOB_EXT_DATA: 24284d2d2796SMarcel Holtmann hci_cc_read_local_oob_ext_data(hdev, skb); 2429c35938b2SSzymon Janc break; 2430c35938b2SSzymon Janc 24316ed58ec5SVille Tervo case HCI_OP_LE_READ_BUFFER_SIZE: 24326ed58ec5SVille Tervo hci_cc_le_read_buffer_size(hdev, skb); 24336ed58ec5SVille Tervo break; 24346ed58ec5SVille Tervo 243560e77321SJohan Hedberg case HCI_OP_LE_READ_LOCAL_FEATURES: 243660e77321SJohan Hedberg hci_cc_le_read_local_features(hdev, skb); 243760e77321SJohan Hedberg break; 243860e77321SJohan Hedberg 24398fa19098SJohan Hedberg case HCI_OP_LE_READ_ADV_TX_POWER: 24408fa19098SJohan Hedberg hci_cc_le_read_adv_tx_power(hdev, skb); 24418fa19098SJohan Hedberg break; 24428fa19098SJohan Hedberg 2443a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_REPLY: 2444a5c29683SJohan Hedberg hci_cc_user_confirm_reply(hdev, skb); 2445a5c29683SJohan Hedberg break; 2446a5c29683SJohan Hedberg 2447a5c29683SJohan Hedberg case HCI_OP_USER_CONFIRM_NEG_REPLY: 2448a5c29683SJohan Hedberg hci_cc_user_confirm_neg_reply(hdev, skb); 2449a5c29683SJohan Hedberg break; 2450a5c29683SJohan Hedberg 24511143d458SBrian Gix case HCI_OP_USER_PASSKEY_REPLY: 24521143d458SBrian Gix hci_cc_user_passkey_reply(hdev, skb); 24531143d458SBrian Gix break; 24541143d458SBrian Gix 24551143d458SBrian Gix case HCI_OP_USER_PASSKEY_NEG_REPLY: 24561143d458SBrian Gix hci_cc_user_passkey_neg_reply(hdev, skb); 245716cde993SSzymon Janc break; 245807f7fa5dSAndre Guedes 24597a4cd51dSMarcel Holtmann case HCI_OP_LE_SET_RANDOM_ADDR: 24607a4cd51dSMarcel Holtmann hci_cc_le_set_random_addr(hdev, skb); 24617a4cd51dSMarcel Holtmann break; 24627a4cd51dSMarcel Holtmann 2463c1d5dc4aSJohan Hedberg case HCI_OP_LE_SET_ADV_ENABLE: 2464c1d5dc4aSJohan Hedberg hci_cc_le_set_adv_enable(hdev, skb); 2465c1d5dc4aSJohan Hedberg break; 2466c1d5dc4aSJohan Hedberg 2467eb9d91f5SAndre Guedes case HCI_OP_LE_SET_SCAN_ENABLE: 2468eb9d91f5SAndre Guedes hci_cc_le_set_scan_enable(hdev, skb); 2469eb9d91f5SAndre Guedes break; 2470eb9d91f5SAndre Guedes 2471cf1d081fSJohan Hedberg case HCI_OP_LE_READ_WHITE_LIST_SIZE: 2472cf1d081fSJohan Hedberg hci_cc_le_read_white_list_size(hdev, skb); 2473cf1d081fSJohan Hedberg break; 2474cf1d081fSJohan Hedberg 24750f36b589SMarcel Holtmann case HCI_OP_LE_CLEAR_WHITE_LIST: 24760f36b589SMarcel Holtmann hci_cc_le_clear_white_list(hdev, skb); 24770f36b589SMarcel Holtmann break; 24780f36b589SMarcel Holtmann 24790f36b589SMarcel Holtmann case HCI_OP_LE_ADD_TO_WHITE_LIST: 24800f36b589SMarcel Holtmann hci_cc_le_add_to_white_list(hdev, skb); 24810f36b589SMarcel Holtmann break; 24820f36b589SMarcel Holtmann 24830f36b589SMarcel Holtmann case HCI_OP_LE_DEL_FROM_WHITE_LIST: 24840f36b589SMarcel Holtmann hci_cc_le_del_from_white_list(hdev, skb); 24850f36b589SMarcel Holtmann break; 24860f36b589SMarcel Holtmann 24879b008c04SJohan Hedberg case HCI_OP_LE_READ_SUPPORTED_STATES: 24889b008c04SJohan Hedberg hci_cc_le_read_supported_states(hdev, skb); 24899b008c04SJohan Hedberg break; 24909b008c04SJohan Hedberg 2491f9b49306SAndre Guedes case HCI_OP_WRITE_LE_HOST_SUPPORTED: 2492f9b49306SAndre Guedes hci_cc_write_le_host_supported(hdev, skb); 2493f9b49306SAndre Guedes break; 2494f9b49306SAndre Guedes 249556ed2cb8SJohan Hedberg case HCI_OP_LE_SET_ADV_PARAM: 249656ed2cb8SJohan Hedberg hci_cc_set_adv_param(hdev, skb); 249756ed2cb8SJohan Hedberg break; 249856ed2cb8SJohan Hedberg 249993c284eeSAndrei Emeltchenko case HCI_OP_WRITE_REMOTE_AMP_ASSOC: 250093c284eeSAndrei Emeltchenko hci_cc_write_remote_amp_assoc(hdev, skb); 250193c284eeSAndrei Emeltchenko break; 250293c284eeSAndrei Emeltchenko 2503a9de9248SMarcel Holtmann default: 25049f1db00cSAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 2505a9de9248SMarcel Holtmann break; 2506a9de9248SMarcel Holtmann } 2507a9de9248SMarcel Holtmann 2508ad82cdd1SJohan Hedberg if (opcode != HCI_OP_NOP) 25096bd32326SVille Tervo del_timer(&hdev->cmd_timer); 25106bd32326SVille Tervo 2511ad82cdd1SJohan Hedberg hci_req_cmd_complete(hdev, opcode, status); 25129238f36aSJohan Hedberg 2513dbccd791SSzymon Janc if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { 2514a9de9248SMarcel Holtmann atomic_set(&hdev->cmd_cnt, 1); 2515a9de9248SMarcel Holtmann if (!skb_queue_empty(&hdev->cmd_q)) 2516c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 2517a9de9248SMarcel Holtmann } 2518a9de9248SMarcel Holtmann } 2519a9de9248SMarcel Holtmann 25206039aa73SGustavo Padovan static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) 2521a9de9248SMarcel Holtmann { 2522a9de9248SMarcel Holtmann struct hci_ev_cmd_status *ev = (void *) skb->data; 2523a9de9248SMarcel Holtmann __u16 opcode; 2524a9de9248SMarcel Holtmann 2525a9de9248SMarcel Holtmann skb_pull(skb, sizeof(*ev)); 2526a9de9248SMarcel Holtmann 2527a9de9248SMarcel Holtmann opcode = __le16_to_cpu(ev->opcode); 2528a9de9248SMarcel Holtmann 2529a9de9248SMarcel Holtmann switch (opcode) { 2530a9de9248SMarcel Holtmann case HCI_OP_INQUIRY: 2531a9de9248SMarcel Holtmann hci_cs_inquiry(hdev, ev->status); 2532a9de9248SMarcel Holtmann break; 2533a9de9248SMarcel Holtmann 2534a9de9248SMarcel Holtmann case HCI_OP_CREATE_CONN: 2535a9de9248SMarcel Holtmann hci_cs_create_conn(hdev, ev->status); 2536a9de9248SMarcel Holtmann break; 2537a9de9248SMarcel Holtmann 2538a9de9248SMarcel Holtmann case HCI_OP_ADD_SCO: 2539a9de9248SMarcel Holtmann hci_cs_add_sco(hdev, ev->status); 2540a9de9248SMarcel Holtmann break; 2541a9de9248SMarcel Holtmann 2542f8558555SMarcel Holtmann case HCI_OP_AUTH_REQUESTED: 2543f8558555SMarcel Holtmann hci_cs_auth_requested(hdev, ev->status); 2544f8558555SMarcel Holtmann break; 2545f8558555SMarcel Holtmann 2546f8558555SMarcel Holtmann case HCI_OP_SET_CONN_ENCRYPT: 2547f8558555SMarcel Holtmann hci_cs_set_conn_encrypt(hdev, ev->status); 2548f8558555SMarcel Holtmann break; 2549f8558555SMarcel Holtmann 2550a9de9248SMarcel Holtmann case HCI_OP_REMOTE_NAME_REQ: 2551a9de9248SMarcel Holtmann hci_cs_remote_name_req(hdev, ev->status); 2552a9de9248SMarcel Holtmann break; 2553a9de9248SMarcel Holtmann 2554769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_FEATURES: 2555769be974SMarcel Holtmann hci_cs_read_remote_features(hdev, ev->status); 2556769be974SMarcel Holtmann break; 2557769be974SMarcel Holtmann 2558769be974SMarcel Holtmann case HCI_OP_READ_REMOTE_EXT_FEATURES: 2559769be974SMarcel Holtmann hci_cs_read_remote_ext_features(hdev, ev->status); 2560769be974SMarcel Holtmann break; 2561769be974SMarcel Holtmann 2562a9de9248SMarcel Holtmann case HCI_OP_SETUP_SYNC_CONN: 2563a9de9248SMarcel Holtmann hci_cs_setup_sync_conn(hdev, ev->status); 2564a9de9248SMarcel Holtmann break; 2565a9de9248SMarcel Holtmann 2566a9de9248SMarcel Holtmann case HCI_OP_SNIFF_MODE: 2567a9de9248SMarcel Holtmann hci_cs_sniff_mode(hdev, ev->status); 2568a9de9248SMarcel Holtmann break; 2569a9de9248SMarcel Holtmann 2570a9de9248SMarcel Holtmann case HCI_OP_EXIT_SNIFF_MODE: 2571a9de9248SMarcel Holtmann hci_cs_exit_sniff_mode(hdev, ev->status); 2572a9de9248SMarcel Holtmann break; 2573a9de9248SMarcel Holtmann 25748962ee74SJohan Hedberg case HCI_OP_DISCONNECT: 257588c3df13SJohan Hedberg hci_cs_disconnect(hdev, ev->status); 25768962ee74SJohan Hedberg break; 25778962ee74SJohan Hedberg 2578a02226d6SAndrei Emeltchenko case HCI_OP_CREATE_PHY_LINK: 2579a02226d6SAndrei Emeltchenko hci_cs_create_phylink(hdev, ev->status); 2580a02226d6SAndrei Emeltchenko break; 2581a02226d6SAndrei Emeltchenko 25820b26ab9dSAndrei Emeltchenko case HCI_OP_ACCEPT_PHY_LINK: 25830b26ab9dSAndrei Emeltchenko hci_cs_accept_phylink(hdev, ev->status); 25840b26ab9dSAndrei Emeltchenko break; 25850b26ab9dSAndrei Emeltchenko 2586cb1d68f7SJohan Hedberg case HCI_OP_LE_CREATE_CONN: 2587cb1d68f7SJohan Hedberg hci_cs_le_create_conn(hdev, ev->status); 2588cb1d68f7SJohan Hedberg break; 2589cb1d68f7SJohan Hedberg 2590a9de9248SMarcel Holtmann default: 25919f1db00cSAndrei Emeltchenko BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 2592a9de9248SMarcel Holtmann break; 2593a9de9248SMarcel Holtmann } 2594a9de9248SMarcel Holtmann 2595ad82cdd1SJohan Hedberg if (opcode != HCI_OP_NOP) 25966bd32326SVille Tervo del_timer(&hdev->cmd_timer); 25976bd32326SVille Tervo 259802350a72SJohan Hedberg if (ev->status || 259902350a72SJohan Hedberg (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event)) 260033720450SAndre Guedes hci_req_cmd_complete(hdev, opcode, ev->status); 26019238f36aSJohan Hedberg 260210572132SGustavo F. Padovan if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { 2603a9de9248SMarcel Holtmann atomic_set(&hdev->cmd_cnt, 1); 2604a9de9248SMarcel Holtmann if (!skb_queue_empty(&hdev->cmd_q)) 2605c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 2606a9de9248SMarcel Holtmann } 2607a9de9248SMarcel Holtmann } 2608a9de9248SMarcel Holtmann 26096039aa73SGustavo Padovan static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2610a9de9248SMarcel Holtmann { 2611a9de9248SMarcel Holtmann struct hci_ev_role_change *ev = (void *) skb->data; 2612a9de9248SMarcel Holtmann struct hci_conn *conn; 2613a9de9248SMarcel Holtmann 26149f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2615a9de9248SMarcel Holtmann 2616a9de9248SMarcel Holtmann hci_dev_lock(hdev); 2617a9de9248SMarcel Holtmann 2618a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2619a9de9248SMarcel Holtmann if (conn) { 2620a9de9248SMarcel Holtmann if (!ev->status) { 2621a9de9248SMarcel Holtmann if (ev->role) 2622a9de9248SMarcel Holtmann conn->link_mode &= ~HCI_LM_MASTER; 2623a9de9248SMarcel Holtmann else 2624a9de9248SMarcel Holtmann conn->link_mode |= HCI_LM_MASTER; 2625a9de9248SMarcel Holtmann } 2626a9de9248SMarcel Holtmann 262751a8efd7SJohan Hedberg clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 2628a9de9248SMarcel Holtmann 2629a9de9248SMarcel Holtmann hci_role_switch_cfm(conn, ev->status, ev->role); 2630a9de9248SMarcel Holtmann } 2631a9de9248SMarcel Holtmann 2632a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 2633a9de9248SMarcel Holtmann } 2634a9de9248SMarcel Holtmann 26356039aa73SGustavo Padovan static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) 26361da177e4SLinus Torvalds { 2637a9de9248SMarcel Holtmann struct hci_ev_num_comp_pkts *ev = (void *) skb->data; 26381da177e4SLinus Torvalds int i; 26391da177e4SLinus Torvalds 264032ac5b9bSAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) { 264132ac5b9bSAndrei Emeltchenko BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); 264232ac5b9bSAndrei Emeltchenko return; 264332ac5b9bSAndrei Emeltchenko } 264432ac5b9bSAndrei Emeltchenko 2645c5993de8SAndrei Emeltchenko if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + 2646c5993de8SAndrei Emeltchenko ev->num_hndl * sizeof(struct hci_comp_pkts_info)) { 26471da177e4SLinus Torvalds BT_DBG("%s bad parameters", hdev->name); 26481da177e4SLinus Torvalds return; 26491da177e4SLinus Torvalds } 26501da177e4SLinus Torvalds 2651c5993de8SAndrei Emeltchenko BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl); 2652c5993de8SAndrei Emeltchenko 2653613a1c0cSAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 2654613a1c0cSAndrei Emeltchenko struct hci_comp_pkts_info *info = &ev->handles[i]; 26551da177e4SLinus Torvalds struct hci_conn *conn; 26561da177e4SLinus Torvalds __u16 handle, count; 26571da177e4SLinus Torvalds 2658613a1c0cSAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 2659613a1c0cSAndrei Emeltchenko count = __le16_to_cpu(info->count); 26601da177e4SLinus Torvalds 26611da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 2662f4280918SAndrei Emeltchenko if (!conn) 2663f4280918SAndrei Emeltchenko continue; 2664f4280918SAndrei Emeltchenko 26651da177e4SLinus Torvalds conn->sent -= count; 26661da177e4SLinus Torvalds 2667f4280918SAndrei Emeltchenko switch (conn->type) { 2668f4280918SAndrei Emeltchenko case ACL_LINK: 266970f23020SAndrei Emeltchenko hdev->acl_cnt += count; 267070f23020SAndrei Emeltchenko if (hdev->acl_cnt > hdev->acl_pkts) 26711da177e4SLinus Torvalds hdev->acl_cnt = hdev->acl_pkts; 2672f4280918SAndrei Emeltchenko break; 2673f4280918SAndrei Emeltchenko 2674f4280918SAndrei Emeltchenko case LE_LINK: 26756ed58ec5SVille Tervo if (hdev->le_pkts) { 26766ed58ec5SVille Tervo hdev->le_cnt += count; 26776ed58ec5SVille Tervo if (hdev->le_cnt > hdev->le_pkts) 26786ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 26796ed58ec5SVille Tervo } else { 26806ed58ec5SVille Tervo hdev->acl_cnt += count; 26816ed58ec5SVille Tervo if (hdev->acl_cnt > hdev->acl_pkts) 26826ed58ec5SVille Tervo hdev->acl_cnt = hdev->acl_pkts; 26836ed58ec5SVille Tervo } 2684f4280918SAndrei Emeltchenko break; 2685f4280918SAndrei Emeltchenko 2686f4280918SAndrei Emeltchenko case SCO_LINK: 268770f23020SAndrei Emeltchenko hdev->sco_cnt += count; 268870f23020SAndrei Emeltchenko if (hdev->sco_cnt > hdev->sco_pkts) 26895b7f9909SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 2690f4280918SAndrei Emeltchenko break; 2691f4280918SAndrei Emeltchenko 2692f4280918SAndrei Emeltchenko default: 2693f4280918SAndrei Emeltchenko BT_ERR("Unknown type %d conn %p", conn->type, conn); 2694f4280918SAndrei Emeltchenko break; 26951da177e4SLinus Torvalds } 26961da177e4SLinus Torvalds } 2697a9de9248SMarcel Holtmann 26983eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 26991da177e4SLinus Torvalds } 27001da177e4SLinus Torvalds 270176ef7cf7SAndrei Emeltchenko static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev, 270276ef7cf7SAndrei Emeltchenko __u16 handle) 270376ef7cf7SAndrei Emeltchenko { 270476ef7cf7SAndrei Emeltchenko struct hci_chan *chan; 270576ef7cf7SAndrei Emeltchenko 270676ef7cf7SAndrei Emeltchenko switch (hdev->dev_type) { 270776ef7cf7SAndrei Emeltchenko case HCI_BREDR: 270876ef7cf7SAndrei Emeltchenko return hci_conn_hash_lookup_handle(hdev, handle); 270976ef7cf7SAndrei Emeltchenko case HCI_AMP: 271076ef7cf7SAndrei Emeltchenko chan = hci_chan_lookup_handle(hdev, handle); 271176ef7cf7SAndrei Emeltchenko if (chan) 271276ef7cf7SAndrei Emeltchenko return chan->conn; 271376ef7cf7SAndrei Emeltchenko break; 271476ef7cf7SAndrei Emeltchenko default: 271576ef7cf7SAndrei Emeltchenko BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); 271676ef7cf7SAndrei Emeltchenko break; 271776ef7cf7SAndrei Emeltchenko } 271876ef7cf7SAndrei Emeltchenko 271976ef7cf7SAndrei Emeltchenko return NULL; 272076ef7cf7SAndrei Emeltchenko } 272176ef7cf7SAndrei Emeltchenko 27226039aa73SGustavo Padovan static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) 272325e89e99SAndrei Emeltchenko { 272425e89e99SAndrei Emeltchenko struct hci_ev_num_comp_blocks *ev = (void *) skb->data; 272525e89e99SAndrei Emeltchenko int i; 272625e89e99SAndrei Emeltchenko 272725e89e99SAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) { 272825e89e99SAndrei Emeltchenko BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); 272925e89e99SAndrei Emeltchenko return; 273025e89e99SAndrei Emeltchenko } 273125e89e99SAndrei Emeltchenko 273225e89e99SAndrei Emeltchenko if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + 273325e89e99SAndrei Emeltchenko ev->num_hndl * sizeof(struct hci_comp_blocks_info)) { 273425e89e99SAndrei Emeltchenko BT_DBG("%s bad parameters", hdev->name); 273525e89e99SAndrei Emeltchenko return; 273625e89e99SAndrei Emeltchenko } 273725e89e99SAndrei Emeltchenko 273825e89e99SAndrei Emeltchenko BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks, 273925e89e99SAndrei Emeltchenko ev->num_hndl); 274025e89e99SAndrei Emeltchenko 274125e89e99SAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 274225e89e99SAndrei Emeltchenko struct hci_comp_blocks_info *info = &ev->handles[i]; 274376ef7cf7SAndrei Emeltchenko struct hci_conn *conn = NULL; 274425e89e99SAndrei Emeltchenko __u16 handle, block_count; 274525e89e99SAndrei Emeltchenko 274625e89e99SAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 274725e89e99SAndrei Emeltchenko block_count = __le16_to_cpu(info->blocks); 274825e89e99SAndrei Emeltchenko 274976ef7cf7SAndrei Emeltchenko conn = __hci_conn_lookup_handle(hdev, handle); 275025e89e99SAndrei Emeltchenko if (!conn) 275125e89e99SAndrei Emeltchenko continue; 275225e89e99SAndrei Emeltchenko 275325e89e99SAndrei Emeltchenko conn->sent -= block_count; 275425e89e99SAndrei Emeltchenko 275525e89e99SAndrei Emeltchenko switch (conn->type) { 275625e89e99SAndrei Emeltchenko case ACL_LINK: 2757bd1eb66bSAndrei Emeltchenko case AMP_LINK: 275825e89e99SAndrei Emeltchenko hdev->block_cnt += block_count; 275925e89e99SAndrei Emeltchenko if (hdev->block_cnt > hdev->num_blocks) 276025e89e99SAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 276125e89e99SAndrei Emeltchenko break; 276225e89e99SAndrei Emeltchenko 276325e89e99SAndrei Emeltchenko default: 276425e89e99SAndrei Emeltchenko BT_ERR("Unknown type %d conn %p", conn->type, conn); 276525e89e99SAndrei Emeltchenko break; 276625e89e99SAndrei Emeltchenko } 276725e89e99SAndrei Emeltchenko } 276825e89e99SAndrei Emeltchenko 276925e89e99SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->tx_work); 277025e89e99SAndrei Emeltchenko } 277125e89e99SAndrei Emeltchenko 27726039aa73SGustavo Padovan static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 27731da177e4SLinus Torvalds { 2774a9de9248SMarcel Holtmann struct hci_ev_mode_change *ev = (void *) skb->data; 277504837f64SMarcel Holtmann struct hci_conn *conn; 27761da177e4SLinus Torvalds 27779f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 27781da177e4SLinus Torvalds 27791da177e4SLinus Torvalds hci_dev_lock(hdev); 27801da177e4SLinus Torvalds 278104837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 278204837f64SMarcel Holtmann if (conn) { 278304837f64SMarcel Holtmann conn->mode = ev->mode; 278404837f64SMarcel Holtmann 27858fc9ced3SGustavo Padovan if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, 27868fc9ced3SGustavo Padovan &conn->flags)) { 278704837f64SMarcel Holtmann if (conn->mode == HCI_CM_ACTIVE) 278858a681efSJohan Hedberg set_bit(HCI_CONN_POWER_SAVE, &conn->flags); 278904837f64SMarcel Holtmann else 279058a681efSJohan Hedberg clear_bit(HCI_CONN_POWER_SAVE, &conn->flags); 279104837f64SMarcel Holtmann } 2792e73439d8SMarcel Holtmann 279351a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 2794e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 279504837f64SMarcel Holtmann } 279604837f64SMarcel Holtmann 279704837f64SMarcel Holtmann hci_dev_unlock(hdev); 279804837f64SMarcel Holtmann } 279904837f64SMarcel Holtmann 28006039aa73SGustavo Padovan static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 28011da177e4SLinus Torvalds { 2802052b30b0SMarcel Holtmann struct hci_ev_pin_code_req *ev = (void *) skb->data; 2803052b30b0SMarcel Holtmann struct hci_conn *conn; 2804052b30b0SMarcel Holtmann 2805a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2806052b30b0SMarcel Holtmann 2807052b30b0SMarcel Holtmann hci_dev_lock(hdev); 2808052b30b0SMarcel Holtmann 2809052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2810b6f98044SWaldemar Rymarkiewicz if (!conn) 2811b6f98044SWaldemar Rymarkiewicz goto unlock; 2812b6f98044SWaldemar Rymarkiewicz 2813b6f98044SWaldemar Rymarkiewicz if (conn->state == BT_CONNECTED) { 2814052b30b0SMarcel Holtmann hci_conn_hold(conn); 2815052b30b0SMarcel Holtmann conn->disc_timeout = HCI_PAIRING_TIMEOUT; 281676a68ba0SDavid Herrmann hci_conn_drop(conn); 2817052b30b0SMarcel Holtmann } 2818052b30b0SMarcel Holtmann 2819a8b2d5c2SJohan Hedberg if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags)) 282003b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, 282103b555e1SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 2822a8b2d5c2SJohan Hedberg else if (test_bit(HCI_MGMT, &hdev->dev_flags)) { 2823a770bb5aSWaldemar Rymarkiewicz u8 secure; 2824a770bb5aSWaldemar Rymarkiewicz 2825a770bb5aSWaldemar Rymarkiewicz if (conn->pending_sec_level == BT_SECURITY_HIGH) 2826a770bb5aSWaldemar Rymarkiewicz secure = 1; 2827a770bb5aSWaldemar Rymarkiewicz else 2828a770bb5aSWaldemar Rymarkiewicz secure = 0; 2829a770bb5aSWaldemar Rymarkiewicz 2830744cf19eSJohan Hedberg mgmt_pin_code_request(hdev, &ev->bdaddr, secure); 2831a770bb5aSWaldemar Rymarkiewicz } 2832980e1a53SJohan Hedberg 2833b6f98044SWaldemar Rymarkiewicz unlock: 2834052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 28351da177e4SLinus Torvalds } 28361da177e4SLinus Torvalds 28376039aa73SGustavo Padovan static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 28381da177e4SLinus Torvalds { 283955ed8ca1SJohan Hedberg struct hci_ev_link_key_req *ev = (void *) skb->data; 284055ed8ca1SJohan Hedberg struct hci_cp_link_key_reply cp; 284155ed8ca1SJohan Hedberg struct hci_conn *conn; 284255ed8ca1SJohan Hedberg struct link_key *key; 284355ed8ca1SJohan Hedberg 2844a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 284555ed8ca1SJohan Hedberg 2846034cbea0SAndrei Emeltchenko if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 284755ed8ca1SJohan Hedberg return; 284855ed8ca1SJohan Hedberg 284955ed8ca1SJohan Hedberg hci_dev_lock(hdev); 285055ed8ca1SJohan Hedberg 285155ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, &ev->bdaddr); 285255ed8ca1SJohan Hedberg if (!key) { 28536ed93dc6SAndrei Emeltchenko BT_DBG("%s link key not found for %pMR", hdev->name, 28546ed93dc6SAndrei Emeltchenko &ev->bdaddr); 285555ed8ca1SJohan Hedberg goto not_found; 285655ed8ca1SJohan Hedberg } 285755ed8ca1SJohan Hedberg 28586ed93dc6SAndrei Emeltchenko BT_DBG("%s found key type %u for %pMR", hdev->name, key->type, 28596ed93dc6SAndrei Emeltchenko &ev->bdaddr); 286055ed8ca1SJohan Hedberg 2861a8b2d5c2SJohan Hedberg if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) && 2862b6020ba0SWaldemar Rymarkiewicz key->type == HCI_LK_DEBUG_COMBINATION) { 286355ed8ca1SJohan Hedberg BT_DBG("%s ignoring debug key", hdev->name); 286455ed8ca1SJohan Hedberg goto not_found; 286555ed8ca1SJohan Hedberg } 286655ed8ca1SJohan Hedberg 286755ed8ca1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 286860b83f57SWaldemar Rymarkiewicz if (conn) { 286966138ce8SMarcel Holtmann if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 || 287066138ce8SMarcel Holtmann key->type == HCI_LK_UNAUTH_COMBINATION_P256) && 2871807deac2SGustavo Padovan conn->auth_type != 0xff && (conn->auth_type & 0x01)) { 287255ed8ca1SJohan Hedberg BT_DBG("%s ignoring unauthenticated key", hdev->name); 287355ed8ca1SJohan Hedberg goto not_found; 287455ed8ca1SJohan Hedberg } 287555ed8ca1SJohan Hedberg 287660b83f57SWaldemar Rymarkiewicz if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && 287760b83f57SWaldemar Rymarkiewicz conn->pending_sec_level == BT_SECURITY_HIGH) { 28788fc9ced3SGustavo Padovan BT_DBG("%s ignoring key unauthenticated for high security", 28798fc9ced3SGustavo Padovan hdev->name); 288060b83f57SWaldemar Rymarkiewicz goto not_found; 288160b83f57SWaldemar Rymarkiewicz } 288260b83f57SWaldemar Rymarkiewicz 288360b83f57SWaldemar Rymarkiewicz conn->key_type = key->type; 288460b83f57SWaldemar Rymarkiewicz conn->pin_length = key->pin_len; 288560b83f57SWaldemar Rymarkiewicz } 288660b83f57SWaldemar Rymarkiewicz 288755ed8ca1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 28889b3b4460SAndrei Emeltchenko memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE); 288955ed8ca1SJohan Hedberg 289055ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp); 289155ed8ca1SJohan Hedberg 289255ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 289355ed8ca1SJohan Hedberg 289455ed8ca1SJohan Hedberg return; 289555ed8ca1SJohan Hedberg 289655ed8ca1SJohan Hedberg not_found: 289755ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr); 289855ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 28991da177e4SLinus Torvalds } 29001da177e4SLinus Torvalds 29016039aa73SGustavo Padovan static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 29021da177e4SLinus Torvalds { 2903052b30b0SMarcel Holtmann struct hci_ev_link_key_notify *ev = (void *) skb->data; 2904052b30b0SMarcel Holtmann struct hci_conn *conn; 290555ed8ca1SJohan Hedberg u8 pin_len = 0; 2906052b30b0SMarcel Holtmann 2907a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 2908052b30b0SMarcel Holtmann 2909052b30b0SMarcel Holtmann hci_dev_lock(hdev); 2910052b30b0SMarcel Holtmann 2911052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 2912052b30b0SMarcel Holtmann if (conn) { 2913052b30b0SMarcel Holtmann hci_conn_hold(conn); 2914052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 2915980e1a53SJohan Hedberg pin_len = conn->pin_length; 291613d39315SWaldemar Rymarkiewicz 291713d39315SWaldemar Rymarkiewicz if (ev->key_type != HCI_LK_CHANGED_COMBINATION) 291813d39315SWaldemar Rymarkiewicz conn->key_type = ev->key_type; 291913d39315SWaldemar Rymarkiewicz 292076a68ba0SDavid Herrmann hci_conn_drop(conn); 2921052b30b0SMarcel Holtmann } 2922052b30b0SMarcel Holtmann 2923034cbea0SAndrei Emeltchenko if (test_bit(HCI_MGMT, &hdev->dev_flags)) 2924d25e28abSJohan Hedberg hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key, 292555ed8ca1SJohan Hedberg ev->key_type, pin_len); 292655ed8ca1SJohan Hedberg 2927052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 29281da177e4SLinus Torvalds } 29291da177e4SLinus Torvalds 29306039aa73SGustavo Padovan static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) 293104837f64SMarcel Holtmann { 2932a9de9248SMarcel Holtmann struct hci_ev_clock_offset *ev = (void *) skb->data; 293304837f64SMarcel Holtmann struct hci_conn *conn; 293404837f64SMarcel Holtmann 29359f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 293604837f64SMarcel Holtmann 293704837f64SMarcel Holtmann hci_dev_lock(hdev); 293804837f64SMarcel Holtmann 293904837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 29401da177e4SLinus Torvalds if (conn && !ev->status) { 29411da177e4SLinus Torvalds struct inquiry_entry *ie; 29421da177e4SLinus Torvalds 2943cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 2944cc11b9c1SAndrei Emeltchenko if (ie) { 29451da177e4SLinus Torvalds ie->data.clock_offset = ev->clock_offset; 29461da177e4SLinus Torvalds ie->timestamp = jiffies; 29471da177e4SLinus Torvalds } 29481da177e4SLinus Torvalds } 29491da177e4SLinus Torvalds 29501da177e4SLinus Torvalds hci_dev_unlock(hdev); 29511da177e4SLinus Torvalds } 29521da177e4SLinus Torvalds 29536039aa73SGustavo Padovan static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) 2954a8746417SMarcel Holtmann { 2955a8746417SMarcel Holtmann struct hci_ev_pkt_type_change *ev = (void *) skb->data; 2956a8746417SMarcel Holtmann struct hci_conn *conn; 2957a8746417SMarcel Holtmann 29589f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 2959a8746417SMarcel Holtmann 2960a8746417SMarcel Holtmann hci_dev_lock(hdev); 2961a8746417SMarcel Holtmann 2962a8746417SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 2963a8746417SMarcel Holtmann if (conn && !ev->status) 2964a8746417SMarcel Holtmann conn->pkt_type = __le16_to_cpu(ev->pkt_type); 2965a8746417SMarcel Holtmann 2966a8746417SMarcel Holtmann hci_dev_unlock(hdev); 2967a8746417SMarcel Holtmann } 2968a8746417SMarcel Holtmann 29696039aa73SGustavo Padovan static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) 297085a1e930SMarcel Holtmann { 2971a9de9248SMarcel Holtmann struct hci_ev_pscan_rep_mode *ev = (void *) skb->data; 297285a1e930SMarcel Holtmann struct inquiry_entry *ie; 297385a1e930SMarcel Holtmann 297485a1e930SMarcel Holtmann BT_DBG("%s", hdev->name); 297585a1e930SMarcel Holtmann 297685a1e930SMarcel Holtmann hci_dev_lock(hdev); 297785a1e930SMarcel Holtmann 2978cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 2979cc11b9c1SAndrei Emeltchenko if (ie) { 298085a1e930SMarcel Holtmann ie->data.pscan_rep_mode = ev->pscan_rep_mode; 298185a1e930SMarcel Holtmann ie->timestamp = jiffies; 298285a1e930SMarcel Holtmann } 298385a1e930SMarcel Holtmann 298485a1e930SMarcel Holtmann hci_dev_unlock(hdev); 298585a1e930SMarcel Holtmann } 298685a1e930SMarcel Holtmann 29876039aa73SGustavo Padovan static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, 2988807deac2SGustavo Padovan struct sk_buff *skb) 2989a9de9248SMarcel Holtmann { 2990a9de9248SMarcel Holtmann struct inquiry_data data; 2991a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 2992388fc8faSJohan Hedberg bool name_known, ssp; 2993a9de9248SMarcel Holtmann 2994a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 2995a9de9248SMarcel Holtmann 2996a9de9248SMarcel Holtmann if (!num_rsp) 2997a9de9248SMarcel Holtmann return; 2998a9de9248SMarcel Holtmann 29991519cc17SAndre Guedes if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) 30001519cc17SAndre Guedes return; 30011519cc17SAndre Guedes 3002a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3003a9de9248SMarcel Holtmann 3004a9de9248SMarcel Holtmann if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { 3005138d22efSSzymon Janc struct inquiry_info_with_rssi_and_pscan_mode *info; 3006138d22efSSzymon Janc info = (void *) (skb->data + 1); 3007a9de9248SMarcel Holtmann 3008e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3009a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3010a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3011a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3012a9de9248SMarcel Holtmann data.pscan_mode = info->pscan_mode; 3013a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3014a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3015a9de9248SMarcel Holtmann data.rssi = info->rssi; 301641a96212SMarcel Holtmann data.ssp_mode = 0x00; 30173175405bSJohan Hedberg 30183175405bSJohan Hedberg name_known = hci_inquiry_cache_update(hdev, &data, 3019388fc8faSJohan Hedberg false, &ssp); 302048264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3021e17acd40SJohan Hedberg info->dev_class, info->rssi, 3022388fc8faSJohan Hedberg !name_known, ssp, NULL, 0); 3023a9de9248SMarcel Holtmann } 3024a9de9248SMarcel Holtmann } else { 3025a9de9248SMarcel Holtmann struct inquiry_info_with_rssi *info = (void *) (skb->data + 1); 3026a9de9248SMarcel Holtmann 3027e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3028a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3029a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3030a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3031a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 3032a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3033a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3034a9de9248SMarcel Holtmann data.rssi = info->rssi; 303541a96212SMarcel Holtmann data.ssp_mode = 0x00; 30363175405bSJohan Hedberg name_known = hci_inquiry_cache_update(hdev, &data, 3037388fc8faSJohan Hedberg false, &ssp); 303848264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3039e17acd40SJohan Hedberg info->dev_class, info->rssi, 3040388fc8faSJohan Hedberg !name_known, ssp, NULL, 0); 3041a9de9248SMarcel Holtmann } 3042a9de9248SMarcel Holtmann } 3043a9de9248SMarcel Holtmann 3044a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3045a9de9248SMarcel Holtmann } 3046a9de9248SMarcel Holtmann 30476039aa73SGustavo Padovan static void hci_remote_ext_features_evt(struct hci_dev *hdev, 3048807deac2SGustavo Padovan struct sk_buff *skb) 3049a9de9248SMarcel Holtmann { 305041a96212SMarcel Holtmann struct hci_ev_remote_ext_features *ev = (void *) skb->data; 305141a96212SMarcel Holtmann struct hci_conn *conn; 305241a96212SMarcel Holtmann 3053a9de9248SMarcel Holtmann BT_DBG("%s", hdev->name); 305441a96212SMarcel Holtmann 305541a96212SMarcel Holtmann hci_dev_lock(hdev); 305641a96212SMarcel Holtmann 305741a96212SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3058ccd556feSJohan Hedberg if (!conn) 3059ccd556feSJohan Hedberg goto unlock; 3060ccd556feSJohan Hedberg 3061cad718edSJohan Hedberg if (ev->page < HCI_MAX_PAGES) 3062cad718edSJohan Hedberg memcpy(conn->features[ev->page], ev->features, 8); 3063cad718edSJohan Hedberg 3064769be974SMarcel Holtmann if (!ev->status && ev->page == 0x01) { 306541a96212SMarcel Holtmann struct inquiry_entry *ie; 306641a96212SMarcel Holtmann 3067cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 3068cc11b9c1SAndrei Emeltchenko if (ie) 306902b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 307041a96212SMarcel Holtmann 3071bbb0eadaSJaganath Kanakkassery if (ev->features[0] & LMP_HOST_SSP) { 307258a681efSJohan Hedberg set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 3073bbb0eadaSJaganath Kanakkassery } else { 3074bbb0eadaSJaganath Kanakkassery /* It is mandatory by the Bluetooth specification that 3075bbb0eadaSJaganath Kanakkassery * Extended Inquiry Results are only used when Secure 3076bbb0eadaSJaganath Kanakkassery * Simple Pairing is enabled, but some devices violate 3077bbb0eadaSJaganath Kanakkassery * this. 3078bbb0eadaSJaganath Kanakkassery * 3079bbb0eadaSJaganath Kanakkassery * To make these devices work, the internal SSP 3080bbb0eadaSJaganath Kanakkassery * enabled flag needs to be cleared if the remote host 3081bbb0eadaSJaganath Kanakkassery * features do not indicate SSP support */ 3082bbb0eadaSJaganath Kanakkassery clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 3083bbb0eadaSJaganath Kanakkassery } 3084eb9a8f3fSMarcel Holtmann 3085eb9a8f3fSMarcel Holtmann if (ev->features[0] & LMP_HOST_SC) 3086eb9a8f3fSMarcel Holtmann set_bit(HCI_CONN_SC_ENABLED, &conn->flags); 308741a96212SMarcel Holtmann } 308841a96212SMarcel Holtmann 3089ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 3090ccd556feSJohan Hedberg goto unlock; 3091ccd556feSJohan Hedberg 3092671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 3093127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 3094127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 3095127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 3096127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 3097127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 3098b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 3099b644ba33SJohan Hedberg mgmt_device_connected(hdev, &conn->dst, conn->type, 310008c79b61SJohan Hedberg conn->dst_type, 0, NULL, 0, 3101b644ba33SJohan Hedberg conn->dev_class); 3102392599b9SJohan Hedberg 3103127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 3104769be974SMarcel Holtmann conn->state = BT_CONNECTED; 3105769be974SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 310676a68ba0SDavid Herrmann hci_conn_drop(conn); 3107769be974SMarcel Holtmann } 3108769be974SMarcel Holtmann 3109ccd556feSJohan Hedberg unlock: 311041a96212SMarcel Holtmann hci_dev_unlock(hdev); 3111a9de9248SMarcel Holtmann } 3112a9de9248SMarcel Holtmann 31136039aa73SGustavo Padovan static void hci_sync_conn_complete_evt(struct hci_dev *hdev, 3114807deac2SGustavo Padovan struct sk_buff *skb) 3115a9de9248SMarcel Holtmann { 3116b6a0dc82SMarcel Holtmann struct hci_ev_sync_conn_complete *ev = (void *) skb->data; 3117b6a0dc82SMarcel Holtmann struct hci_conn *conn; 3118b6a0dc82SMarcel Holtmann 31199f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3120b6a0dc82SMarcel Holtmann 3121b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 3122b6a0dc82SMarcel Holtmann 3123b6a0dc82SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 31249dc0a3afSMarcel Holtmann if (!conn) { 31259dc0a3afSMarcel Holtmann if (ev->link_type == ESCO_LINK) 31269dc0a3afSMarcel Holtmann goto unlock; 31279dc0a3afSMarcel Holtmann 31289dc0a3afSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 3129b6a0dc82SMarcel Holtmann if (!conn) 3130b6a0dc82SMarcel Holtmann goto unlock; 3131b6a0dc82SMarcel Holtmann 31329dc0a3afSMarcel Holtmann conn->type = SCO_LINK; 31339dc0a3afSMarcel Holtmann } 31349dc0a3afSMarcel Holtmann 3135732547f9SMarcel Holtmann switch (ev->status) { 3136732547f9SMarcel Holtmann case 0x00: 3137732547f9SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 3138732547f9SMarcel Holtmann conn->state = BT_CONNECTED; 3139732547f9SMarcel Holtmann 3140732547f9SMarcel Holtmann hci_conn_add_sysfs(conn); 3141732547f9SMarcel Holtmann break; 3142732547f9SMarcel Holtmann 31431a4c958cSFrédéric Dalleau case 0x0d: /* Connection Rejected due to Limited Resources */ 3144705e5711SStephen Coe case 0x11: /* Unsupported Feature or Parameter Value */ 3145732547f9SMarcel Holtmann case 0x1c: /* SCO interval rejected */ 31461038a00bSNick Pelly case 0x1a: /* Unsupported Remote Feature */ 3147732547f9SMarcel Holtmann case 0x1f: /* Unspecified error */ 31482dea632fSFrédéric Dalleau if (conn->out) { 3149efc7688bSMarcel Holtmann conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | 3150efc7688bSMarcel Holtmann (hdev->esco_type & EDR_ESCO_MASK); 31512dea632fSFrédéric Dalleau if (hci_setup_sync(conn, conn->link->handle)) 3152efc7688bSMarcel Holtmann goto unlock; 3153efc7688bSMarcel Holtmann } 3154732547f9SMarcel Holtmann /* fall through */ 3155efc7688bSMarcel Holtmann 3156732547f9SMarcel Holtmann default: 3157b6a0dc82SMarcel Holtmann conn->state = BT_CLOSED; 3158732547f9SMarcel Holtmann break; 3159732547f9SMarcel Holtmann } 3160b6a0dc82SMarcel Holtmann 3161b6a0dc82SMarcel Holtmann hci_proto_connect_cfm(conn, ev->status); 3162b6a0dc82SMarcel Holtmann if (ev->status) 3163b6a0dc82SMarcel Holtmann hci_conn_del(conn); 3164b6a0dc82SMarcel Holtmann 3165b6a0dc82SMarcel Holtmann unlock: 3166b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 3167a9de9248SMarcel Holtmann } 3168a9de9248SMarcel Holtmann 3169efdcf8e3SMarcel Holtmann static inline size_t eir_get_length(u8 *eir, size_t eir_len) 3170efdcf8e3SMarcel Holtmann { 3171efdcf8e3SMarcel Holtmann size_t parsed = 0; 3172efdcf8e3SMarcel Holtmann 3173efdcf8e3SMarcel Holtmann while (parsed < eir_len) { 3174efdcf8e3SMarcel Holtmann u8 field_len = eir[0]; 3175efdcf8e3SMarcel Holtmann 3176efdcf8e3SMarcel Holtmann if (field_len == 0) 3177efdcf8e3SMarcel Holtmann return parsed; 3178efdcf8e3SMarcel Holtmann 3179efdcf8e3SMarcel Holtmann parsed += field_len + 1; 3180efdcf8e3SMarcel Holtmann eir += field_len + 1; 3181efdcf8e3SMarcel Holtmann } 3182efdcf8e3SMarcel Holtmann 3183efdcf8e3SMarcel Holtmann return eir_len; 3184efdcf8e3SMarcel Holtmann } 3185efdcf8e3SMarcel Holtmann 31866039aa73SGustavo Padovan static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, 3187807deac2SGustavo Padovan struct sk_buff *skb) 3188a9de9248SMarcel Holtmann { 3189a9de9248SMarcel Holtmann struct inquiry_data data; 3190a9de9248SMarcel Holtmann struct extended_inquiry_info *info = (void *) (skb->data + 1); 3191a9de9248SMarcel Holtmann int num_rsp = *((__u8 *) skb->data); 31929d939d94SVishal Agarwal size_t eir_len; 3193a9de9248SMarcel Holtmann 3194a9de9248SMarcel Holtmann BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 3195a9de9248SMarcel Holtmann 3196a9de9248SMarcel Holtmann if (!num_rsp) 3197a9de9248SMarcel Holtmann return; 3198a9de9248SMarcel Holtmann 31991519cc17SAndre Guedes if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) 32001519cc17SAndre Guedes return; 32011519cc17SAndre Guedes 3202a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3203a9de9248SMarcel Holtmann 3204e17acd40SJohan Hedberg for (; num_rsp; num_rsp--, info++) { 3205388fc8faSJohan Hedberg bool name_known, ssp; 3206561aafbcSJohan Hedberg 3207a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 3208a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 3209a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 3210a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 3211a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 3212a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 3213a9de9248SMarcel Holtmann data.rssi = info->rssi; 321441a96212SMarcel Holtmann data.ssp_mode = 0x01; 3215561aafbcSJohan Hedberg 3216a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 32174ddb1930SJohan Hedberg name_known = eir_has_data_type(info->data, 32184ddb1930SJohan Hedberg sizeof(info->data), 32194ddb1930SJohan Hedberg EIR_NAME_COMPLETE); 3220561aafbcSJohan Hedberg else 3221561aafbcSJohan Hedberg name_known = true; 3222561aafbcSJohan Hedberg 3223388fc8faSJohan Hedberg name_known = hci_inquiry_cache_update(hdev, &data, name_known, 3224388fc8faSJohan Hedberg &ssp); 32259d939d94SVishal Agarwal eir_len = eir_get_length(info->data, sizeof(info->data)); 322648264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 322704124681SGustavo F. Padovan info->dev_class, info->rssi, !name_known, 32289d939d94SVishal Agarwal ssp, info->data, eir_len); 3229a9de9248SMarcel Holtmann } 3230a9de9248SMarcel Holtmann 3231a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3232a9de9248SMarcel Holtmann } 3233a9de9248SMarcel Holtmann 32341c2e0041SJohan Hedberg static void hci_key_refresh_complete_evt(struct hci_dev *hdev, 32351c2e0041SJohan Hedberg struct sk_buff *skb) 32361c2e0041SJohan Hedberg { 32371c2e0041SJohan Hedberg struct hci_ev_key_refresh_complete *ev = (void *) skb->data; 32381c2e0041SJohan Hedberg struct hci_conn *conn; 32391c2e0041SJohan Hedberg 32409f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status, 32411c2e0041SJohan Hedberg __le16_to_cpu(ev->handle)); 32421c2e0041SJohan Hedberg 32431c2e0041SJohan Hedberg hci_dev_lock(hdev); 32441c2e0041SJohan Hedberg 32451c2e0041SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 32461c2e0041SJohan Hedberg if (!conn) 32471c2e0041SJohan Hedberg goto unlock; 32481c2e0041SJohan Hedberg 32491c2e0041SJohan Hedberg if (!ev->status) 32501c2e0041SJohan Hedberg conn->sec_level = conn->pending_sec_level; 32511c2e0041SJohan Hedberg 32521c2e0041SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 32531c2e0041SJohan Hedberg 32541c2e0041SJohan Hedberg if (ev->status && conn->state == BT_CONNECTED) { 3255bed71748SAndre Guedes hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 325676a68ba0SDavid Herrmann hci_conn_drop(conn); 32571c2e0041SJohan Hedberg goto unlock; 32581c2e0041SJohan Hedberg } 32591c2e0041SJohan Hedberg 32601c2e0041SJohan Hedberg if (conn->state == BT_CONFIG) { 32611c2e0041SJohan Hedberg if (!ev->status) 32621c2e0041SJohan Hedberg conn->state = BT_CONNECTED; 32631c2e0041SJohan Hedberg 32641c2e0041SJohan Hedberg hci_proto_connect_cfm(conn, ev->status); 326576a68ba0SDavid Herrmann hci_conn_drop(conn); 32661c2e0041SJohan Hedberg } else { 32671c2e0041SJohan Hedberg hci_auth_cfm(conn, ev->status); 32681c2e0041SJohan Hedberg 32691c2e0041SJohan Hedberg hci_conn_hold(conn); 32701c2e0041SJohan Hedberg conn->disc_timeout = HCI_DISCONN_TIMEOUT; 327176a68ba0SDavid Herrmann hci_conn_drop(conn); 32721c2e0041SJohan Hedberg } 32731c2e0041SJohan Hedberg 32741c2e0041SJohan Hedberg unlock: 32751c2e0041SJohan Hedberg hci_dev_unlock(hdev); 32761c2e0041SJohan Hedberg } 32771c2e0041SJohan Hedberg 32786039aa73SGustavo Padovan static u8 hci_get_auth_req(struct hci_conn *conn) 327917fa4b9dSJohan Hedberg { 328017fa4b9dSJohan Hedberg /* If remote requests dedicated bonding follow that lead */ 3281acabae96SMikel Astiz if (conn->remote_auth == HCI_AT_DEDICATED_BONDING || 3282acabae96SMikel Astiz conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) { 328317fa4b9dSJohan Hedberg /* If both remote and local IO capabilities allow MITM 328417fa4b9dSJohan Hedberg * protection then require it, otherwise don't */ 3285acabae96SMikel Astiz if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT || 3286acabae96SMikel Astiz conn->io_capability == HCI_IO_NO_INPUT_OUTPUT) 3287acabae96SMikel Astiz return HCI_AT_DEDICATED_BONDING; 328817fa4b9dSJohan Hedberg else 3289acabae96SMikel Astiz return HCI_AT_DEDICATED_BONDING_MITM; 329017fa4b9dSJohan Hedberg } 329117fa4b9dSJohan Hedberg 329217fa4b9dSJohan Hedberg /* If remote requests no-bonding follow that lead */ 3293acabae96SMikel Astiz if (conn->remote_auth == HCI_AT_NO_BONDING || 3294acabae96SMikel Astiz conn->remote_auth == HCI_AT_NO_BONDING_MITM) 329558797bf7SWaldemar Rymarkiewicz return conn->remote_auth | (conn->auth_type & 0x01); 329617fa4b9dSJohan Hedberg 329717fa4b9dSJohan Hedberg return conn->auth_type; 329817fa4b9dSJohan Hedberg } 329917fa4b9dSJohan Hedberg 33006039aa73SGustavo Padovan static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 33010493684eSMarcel Holtmann { 33020493684eSMarcel Holtmann struct hci_ev_io_capa_request *ev = (void *) skb->data; 33030493684eSMarcel Holtmann struct hci_conn *conn; 33040493684eSMarcel Holtmann 33050493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 33060493684eSMarcel Holtmann 33070493684eSMarcel Holtmann hci_dev_lock(hdev); 33080493684eSMarcel Holtmann 33090493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 331003b555e1SJohan Hedberg if (!conn) 331103b555e1SJohan Hedberg goto unlock; 331203b555e1SJohan Hedberg 33130493684eSMarcel Holtmann hci_conn_hold(conn); 33140493684eSMarcel Holtmann 3315a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 331603b555e1SJohan Hedberg goto unlock; 331703b555e1SJohan Hedberg 3318a8b2d5c2SJohan Hedberg if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) || 331903b555e1SJohan Hedberg (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { 332017fa4b9dSJohan Hedberg struct hci_cp_io_capability_reply cp; 332117fa4b9dSJohan Hedberg 332217fa4b9dSJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 33237a7f1e7cSHemant Gupta /* Change the IO capability from KeyboardDisplay 33247a7f1e7cSHemant Gupta * to DisplayYesNo as it is not supported by BT spec. */ 33257a7f1e7cSHemant Gupta cp.capability = (conn->io_capability == 0x04) ? 3326a767631aSMikel Astiz HCI_IO_DISPLAY_YESNO : conn->io_capability; 33277cbc9bd9SJohan Hedberg conn->auth_type = hci_get_auth_req(conn); 33287cbc9bd9SJohan Hedberg cp.authentication = conn->auth_type; 332917fa4b9dSJohan Hedberg 33308fc9ced3SGustavo Padovan if (hci_find_remote_oob_data(hdev, &conn->dst) && 33318fc9ced3SGustavo Padovan (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags))) 3332ce85ee13SSzymon Janc cp.oob_data = 0x01; 3333ce85ee13SSzymon Janc else 3334ce85ee13SSzymon Janc cp.oob_data = 0x00; 3335ce85ee13SSzymon Janc 333617fa4b9dSJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY, 333717fa4b9dSJohan Hedberg sizeof(cp), &cp); 333803b555e1SJohan Hedberg } else { 333903b555e1SJohan Hedberg struct hci_cp_io_capability_neg_reply cp; 334003b555e1SJohan Hedberg 334103b555e1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 33429f5a0d7bSAndrei Emeltchenko cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED; 334303b555e1SJohan Hedberg 334403b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, 334503b555e1SJohan Hedberg sizeof(cp), &cp); 334603b555e1SJohan Hedberg } 334703b555e1SJohan Hedberg 334803b555e1SJohan Hedberg unlock: 334903b555e1SJohan Hedberg hci_dev_unlock(hdev); 335003b555e1SJohan Hedberg } 335103b555e1SJohan Hedberg 33526039aa73SGustavo Padovan static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) 335303b555e1SJohan Hedberg { 335403b555e1SJohan Hedberg struct hci_ev_io_capa_reply *ev = (void *) skb->data; 335503b555e1SJohan Hedberg struct hci_conn *conn; 335603b555e1SJohan Hedberg 335703b555e1SJohan Hedberg BT_DBG("%s", hdev->name); 335803b555e1SJohan Hedberg 335903b555e1SJohan Hedberg hci_dev_lock(hdev); 336003b555e1SJohan Hedberg 336103b555e1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 336203b555e1SJohan Hedberg if (!conn) 336303b555e1SJohan Hedberg goto unlock; 336403b555e1SJohan Hedberg 336503b555e1SJohan Hedberg conn->remote_cap = ev->capability; 336603b555e1SJohan Hedberg conn->remote_auth = ev->authentication; 336758a681efSJohan Hedberg if (ev->oob_data) 336858a681efSJohan Hedberg set_bit(HCI_CONN_REMOTE_OOB, &conn->flags); 336903b555e1SJohan Hedberg 337003b555e1SJohan Hedberg unlock: 33710493684eSMarcel Holtmann hci_dev_unlock(hdev); 33720493684eSMarcel Holtmann } 33730493684eSMarcel Holtmann 33746039aa73SGustavo Padovan static void hci_user_confirm_request_evt(struct hci_dev *hdev, 3375a5c29683SJohan Hedberg struct sk_buff *skb) 3376a5c29683SJohan Hedberg { 3377a5c29683SJohan Hedberg struct hci_ev_user_confirm_req *ev = (void *) skb->data; 337855bc1a37SJohan Hedberg int loc_mitm, rem_mitm, confirm_hint = 0; 33797a828908SJohan Hedberg struct hci_conn *conn; 3380a5c29683SJohan Hedberg 3381a5c29683SJohan Hedberg BT_DBG("%s", hdev->name); 3382a5c29683SJohan Hedberg 3383a5c29683SJohan Hedberg hci_dev_lock(hdev); 3384a5c29683SJohan Hedberg 3385a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 33867a828908SJohan Hedberg goto unlock; 33877a828908SJohan Hedberg 33887a828908SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 33897a828908SJohan Hedberg if (!conn) 33907a828908SJohan Hedberg goto unlock; 33917a828908SJohan Hedberg 33927a828908SJohan Hedberg loc_mitm = (conn->auth_type & 0x01); 33937a828908SJohan Hedberg rem_mitm = (conn->remote_auth & 0x01); 33947a828908SJohan Hedberg 33957a828908SJohan Hedberg /* If we require MITM but the remote device can't provide that 33967a828908SJohan Hedberg * (it has NoInputNoOutput) then reject the confirmation 33977a828908SJohan Hedberg * request. The only exception is when we're dedicated bonding 33987a828908SJohan Hedberg * initiators (connect_cfm_cb set) since then we always have the MITM 33997a828908SJohan Hedberg * bit set. */ 3400a767631aSMikel Astiz if (!conn->connect_cfm_cb && loc_mitm && 3401a767631aSMikel Astiz conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) { 34027a828908SJohan Hedberg BT_DBG("Rejecting request: remote device can't provide MITM"); 34037a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY, 34047a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 34057a828908SJohan Hedberg goto unlock; 34067a828908SJohan Hedberg } 34077a828908SJohan Hedberg 34087a828908SJohan Hedberg /* If no side requires MITM protection; auto-accept */ 3409a767631aSMikel Astiz if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) && 3410a767631aSMikel Astiz (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) { 341155bc1a37SJohan Hedberg 341255bc1a37SJohan Hedberg /* If we're not the initiators request authorization to 341355bc1a37SJohan Hedberg * proceed from user space (mgmt_user_confirm with 341455bc1a37SJohan Hedberg * confirm_hint set to 1). */ 341551a8efd7SJohan Hedberg if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 341655bc1a37SJohan Hedberg BT_DBG("Confirming auto-accept as acceptor"); 341755bc1a37SJohan Hedberg confirm_hint = 1; 341855bc1a37SJohan Hedberg goto confirm; 341955bc1a37SJohan Hedberg } 342055bc1a37SJohan Hedberg 34219f61656aSJohan Hedberg BT_DBG("Auto-accept of user confirmation with %ums delay", 34229f61656aSJohan Hedberg hdev->auto_accept_delay); 34239f61656aSJohan Hedberg 34249f61656aSJohan Hedberg if (hdev->auto_accept_delay > 0) { 34259f61656aSJohan Hedberg int delay = msecs_to_jiffies(hdev->auto_accept_delay); 34267bc18d9dSJohan Hedberg queue_delayed_work(conn->hdev->workqueue, 34277bc18d9dSJohan Hedberg &conn->auto_accept_work, delay); 34289f61656aSJohan Hedberg goto unlock; 34299f61656aSJohan Hedberg } 34309f61656aSJohan Hedberg 34317a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, 34327a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 34337a828908SJohan Hedberg goto unlock; 34347a828908SJohan Hedberg } 34357a828908SJohan Hedberg 343655bc1a37SJohan Hedberg confirm: 3437272d90dfSJohan Hedberg mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey, 343855bc1a37SJohan Hedberg confirm_hint); 3439a5c29683SJohan Hedberg 34407a828908SJohan Hedberg unlock: 3441a5c29683SJohan Hedberg hci_dev_unlock(hdev); 3442a5c29683SJohan Hedberg } 3443a5c29683SJohan Hedberg 34446039aa73SGustavo Padovan static void hci_user_passkey_request_evt(struct hci_dev *hdev, 34451143d458SBrian Gix struct sk_buff *skb) 34461143d458SBrian Gix { 34471143d458SBrian Gix struct hci_ev_user_passkey_req *ev = (void *) skb->data; 34481143d458SBrian Gix 34491143d458SBrian Gix BT_DBG("%s", hdev->name); 34501143d458SBrian Gix 3451a8b2d5c2SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 3452272d90dfSJohan Hedberg mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); 34531143d458SBrian Gix } 34541143d458SBrian Gix 345592a25256SJohan Hedberg static void hci_user_passkey_notify_evt(struct hci_dev *hdev, 345692a25256SJohan Hedberg struct sk_buff *skb) 345792a25256SJohan Hedberg { 345892a25256SJohan Hedberg struct hci_ev_user_passkey_notify *ev = (void *) skb->data; 345992a25256SJohan Hedberg struct hci_conn *conn; 346092a25256SJohan Hedberg 346192a25256SJohan Hedberg BT_DBG("%s", hdev->name); 346292a25256SJohan Hedberg 346392a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 346492a25256SJohan Hedberg if (!conn) 346592a25256SJohan Hedberg return; 346692a25256SJohan Hedberg 346792a25256SJohan Hedberg conn->passkey_notify = __le32_to_cpu(ev->passkey); 346892a25256SJohan Hedberg conn->passkey_entered = 0; 346992a25256SJohan Hedberg 347092a25256SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 347192a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 347292a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 347392a25256SJohan Hedberg conn->passkey_entered); 347492a25256SJohan Hedberg } 347592a25256SJohan Hedberg 347692a25256SJohan Hedberg static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 347792a25256SJohan Hedberg { 347892a25256SJohan Hedberg struct hci_ev_keypress_notify *ev = (void *) skb->data; 347992a25256SJohan Hedberg struct hci_conn *conn; 348092a25256SJohan Hedberg 348192a25256SJohan Hedberg BT_DBG("%s", hdev->name); 348292a25256SJohan Hedberg 348392a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 348492a25256SJohan Hedberg if (!conn) 348592a25256SJohan Hedberg return; 348692a25256SJohan Hedberg 348792a25256SJohan Hedberg switch (ev->type) { 348892a25256SJohan Hedberg case HCI_KEYPRESS_STARTED: 348992a25256SJohan Hedberg conn->passkey_entered = 0; 349092a25256SJohan Hedberg return; 349192a25256SJohan Hedberg 349292a25256SJohan Hedberg case HCI_KEYPRESS_ENTERED: 349392a25256SJohan Hedberg conn->passkey_entered++; 349492a25256SJohan Hedberg break; 349592a25256SJohan Hedberg 349692a25256SJohan Hedberg case HCI_KEYPRESS_ERASED: 349792a25256SJohan Hedberg conn->passkey_entered--; 349892a25256SJohan Hedberg break; 349992a25256SJohan Hedberg 350092a25256SJohan Hedberg case HCI_KEYPRESS_CLEARED: 350192a25256SJohan Hedberg conn->passkey_entered = 0; 350292a25256SJohan Hedberg break; 350392a25256SJohan Hedberg 350492a25256SJohan Hedberg case HCI_KEYPRESS_COMPLETED: 350592a25256SJohan Hedberg return; 350692a25256SJohan Hedberg } 350792a25256SJohan Hedberg 350892a25256SJohan Hedberg if (test_bit(HCI_MGMT, &hdev->dev_flags)) 350992a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 351092a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 351192a25256SJohan Hedberg conn->passkey_entered); 351292a25256SJohan Hedberg } 351392a25256SJohan Hedberg 35146039aa73SGustavo Padovan static void hci_simple_pair_complete_evt(struct hci_dev *hdev, 3515807deac2SGustavo Padovan struct sk_buff *skb) 35160493684eSMarcel Holtmann { 35170493684eSMarcel Holtmann struct hci_ev_simple_pair_complete *ev = (void *) skb->data; 35180493684eSMarcel Holtmann struct hci_conn *conn; 35190493684eSMarcel Holtmann 35200493684eSMarcel Holtmann BT_DBG("%s", hdev->name); 35210493684eSMarcel Holtmann 35220493684eSMarcel Holtmann hci_dev_lock(hdev); 35230493684eSMarcel Holtmann 35240493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 35252a611692SJohan Hedberg if (!conn) 35262a611692SJohan Hedberg goto unlock; 35272a611692SJohan Hedberg 35282a611692SJohan Hedberg /* To avoid duplicate auth_failed events to user space we check 35292a611692SJohan Hedberg * the HCI_CONN_AUTH_PEND flag which will be set if we 35302a611692SJohan Hedberg * initiated the authentication. A traditional auth_complete 35312a611692SJohan Hedberg * event gets always produced as initiator and is also mapped to 35322a611692SJohan Hedberg * the mgmt_auth_failed event */ 3533fa1bd918SMikel Astiz if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status) 3534bab73cb6SJohan Hedberg mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, 3535bab73cb6SJohan Hedberg ev->status); 35362a611692SJohan Hedberg 353776a68ba0SDavid Herrmann hci_conn_drop(conn); 35380493684eSMarcel Holtmann 35392a611692SJohan Hedberg unlock: 35400493684eSMarcel Holtmann hci_dev_unlock(hdev); 35410493684eSMarcel Holtmann } 35420493684eSMarcel Holtmann 35436039aa73SGustavo Padovan static void hci_remote_host_features_evt(struct hci_dev *hdev, 3544807deac2SGustavo Padovan struct sk_buff *skb) 354541a96212SMarcel Holtmann { 354641a96212SMarcel Holtmann struct hci_ev_remote_host_features *ev = (void *) skb->data; 354741a96212SMarcel Holtmann struct inquiry_entry *ie; 3548cad718edSJohan Hedberg struct hci_conn *conn; 354941a96212SMarcel Holtmann 355041a96212SMarcel Holtmann BT_DBG("%s", hdev->name); 355141a96212SMarcel Holtmann 355241a96212SMarcel Holtmann hci_dev_lock(hdev); 355341a96212SMarcel Holtmann 3554cad718edSJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 3555cad718edSJohan Hedberg if (conn) 3556cad718edSJohan Hedberg memcpy(conn->features[1], ev->features, 8); 3557cad718edSJohan Hedberg 3558cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 3559cc11b9c1SAndrei Emeltchenko if (ie) 356002b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 356141a96212SMarcel Holtmann 356241a96212SMarcel Holtmann hci_dev_unlock(hdev); 356341a96212SMarcel Holtmann } 356441a96212SMarcel Holtmann 35656039aa73SGustavo Padovan static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, 35662763eda6SSzymon Janc struct sk_buff *skb) 35672763eda6SSzymon Janc { 35682763eda6SSzymon Janc struct hci_ev_remote_oob_data_request *ev = (void *) skb->data; 35692763eda6SSzymon Janc struct oob_data *data; 35702763eda6SSzymon Janc 35712763eda6SSzymon Janc BT_DBG("%s", hdev->name); 35722763eda6SSzymon Janc 35732763eda6SSzymon Janc hci_dev_lock(hdev); 35742763eda6SSzymon Janc 3575a8b2d5c2SJohan Hedberg if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 3576e1ba1f15SSzymon Janc goto unlock; 3577e1ba1f15SSzymon Janc 35782763eda6SSzymon Janc data = hci_find_remote_oob_data(hdev, &ev->bdaddr); 35792763eda6SSzymon Janc if (data) { 3580519ca9d0SMarcel Holtmann if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) { 3581519ca9d0SMarcel Holtmann struct hci_cp_remote_oob_ext_data_reply cp; 3582519ca9d0SMarcel Holtmann 3583519ca9d0SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 3584519ca9d0SMarcel Holtmann memcpy(cp.hash192, data->hash192, sizeof(cp.hash192)); 3585519ca9d0SMarcel Holtmann memcpy(cp.randomizer192, data->randomizer192, 3586519ca9d0SMarcel Holtmann sizeof(cp.randomizer192)); 3587519ca9d0SMarcel Holtmann memcpy(cp.hash256, data->hash256, sizeof(cp.hash256)); 3588519ca9d0SMarcel Holtmann memcpy(cp.randomizer256, data->randomizer256, 3589519ca9d0SMarcel Holtmann sizeof(cp.randomizer256)); 3590519ca9d0SMarcel Holtmann 3591519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY, 3592519ca9d0SMarcel Holtmann sizeof(cp), &cp); 3593519ca9d0SMarcel Holtmann } else { 35942763eda6SSzymon Janc struct hci_cp_remote_oob_data_reply cp; 35952763eda6SSzymon Janc 35962763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr); 3597519ca9d0SMarcel Holtmann memcpy(cp.hash, data->hash192, sizeof(cp.hash)); 3598519ca9d0SMarcel Holtmann memcpy(cp.randomizer, data->randomizer192, 3599519ca9d0SMarcel Holtmann sizeof(cp.randomizer)); 36002763eda6SSzymon Janc 3601519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, 3602519ca9d0SMarcel Holtmann sizeof(cp), &cp); 3603519ca9d0SMarcel Holtmann } 36042763eda6SSzymon Janc } else { 36052763eda6SSzymon Janc struct hci_cp_remote_oob_data_neg_reply cp; 36062763eda6SSzymon Janc 36072763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr); 3608519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, 3609519ca9d0SMarcel Holtmann sizeof(cp), &cp); 36102763eda6SSzymon Janc } 36112763eda6SSzymon Janc 3612e1ba1f15SSzymon Janc unlock: 36132763eda6SSzymon Janc hci_dev_unlock(hdev); 36142763eda6SSzymon Janc } 36152763eda6SSzymon Janc 3616d5e91192SAndrei Emeltchenko static void hci_phy_link_complete_evt(struct hci_dev *hdev, 3617d5e91192SAndrei Emeltchenko struct sk_buff *skb) 3618d5e91192SAndrei Emeltchenko { 3619d5e91192SAndrei Emeltchenko struct hci_ev_phy_link_complete *ev = (void *) skb->data; 3620d5e91192SAndrei Emeltchenko struct hci_conn *hcon, *bredr_hcon; 3621d5e91192SAndrei Emeltchenko 3622d5e91192SAndrei Emeltchenko BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle, 3623d5e91192SAndrei Emeltchenko ev->status); 3624d5e91192SAndrei Emeltchenko 3625d5e91192SAndrei Emeltchenko hci_dev_lock(hdev); 3626d5e91192SAndrei Emeltchenko 3627d5e91192SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 3628d5e91192SAndrei Emeltchenko if (!hcon) { 3629d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 3630d5e91192SAndrei Emeltchenko return; 3631d5e91192SAndrei Emeltchenko } 3632d5e91192SAndrei Emeltchenko 3633d5e91192SAndrei Emeltchenko if (ev->status) { 3634d5e91192SAndrei Emeltchenko hci_conn_del(hcon); 3635d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 3636d5e91192SAndrei Emeltchenko return; 3637d5e91192SAndrei Emeltchenko } 3638d5e91192SAndrei Emeltchenko 3639d5e91192SAndrei Emeltchenko bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon; 3640d5e91192SAndrei Emeltchenko 3641d5e91192SAndrei Emeltchenko hcon->state = BT_CONNECTED; 3642d5e91192SAndrei Emeltchenko bacpy(&hcon->dst, &bredr_hcon->dst); 3643d5e91192SAndrei Emeltchenko 3644d5e91192SAndrei Emeltchenko hci_conn_hold(hcon); 3645d5e91192SAndrei Emeltchenko hcon->disc_timeout = HCI_DISCONN_TIMEOUT; 364676a68ba0SDavid Herrmann hci_conn_drop(hcon); 3647d5e91192SAndrei Emeltchenko 3648d5e91192SAndrei Emeltchenko hci_conn_add_sysfs(hcon); 3649d5e91192SAndrei Emeltchenko 3650cf70ff22SAndrei Emeltchenko amp_physical_cfm(bredr_hcon, hcon); 3651cf70ff22SAndrei Emeltchenko 3652d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 3653d5e91192SAndrei Emeltchenko } 3654d5e91192SAndrei Emeltchenko 365527695fb4SAndrei Emeltchenko static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 365627695fb4SAndrei Emeltchenko { 365727695fb4SAndrei Emeltchenko struct hci_ev_logical_link_complete *ev = (void *) skb->data; 365827695fb4SAndrei Emeltchenko struct hci_conn *hcon; 365927695fb4SAndrei Emeltchenko struct hci_chan *hchan; 366027695fb4SAndrei Emeltchenko struct amp_mgr *mgr; 366127695fb4SAndrei Emeltchenko 366227695fb4SAndrei Emeltchenko BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x", 366327695fb4SAndrei Emeltchenko hdev->name, le16_to_cpu(ev->handle), ev->phy_handle, 366427695fb4SAndrei Emeltchenko ev->status); 366527695fb4SAndrei Emeltchenko 366627695fb4SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 366727695fb4SAndrei Emeltchenko if (!hcon) 366827695fb4SAndrei Emeltchenko return; 366927695fb4SAndrei Emeltchenko 367027695fb4SAndrei Emeltchenko /* Create AMP hchan */ 367127695fb4SAndrei Emeltchenko hchan = hci_chan_create(hcon); 367227695fb4SAndrei Emeltchenko if (!hchan) 367327695fb4SAndrei Emeltchenko return; 367427695fb4SAndrei Emeltchenko 367527695fb4SAndrei Emeltchenko hchan->handle = le16_to_cpu(ev->handle); 367627695fb4SAndrei Emeltchenko 367727695fb4SAndrei Emeltchenko BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan); 367827695fb4SAndrei Emeltchenko 367927695fb4SAndrei Emeltchenko mgr = hcon->amp_mgr; 368027695fb4SAndrei Emeltchenko if (mgr && mgr->bredr_chan) { 368127695fb4SAndrei Emeltchenko struct l2cap_chan *bredr_chan = mgr->bredr_chan; 368227695fb4SAndrei Emeltchenko 368327695fb4SAndrei Emeltchenko l2cap_chan_lock(bredr_chan); 368427695fb4SAndrei Emeltchenko 368527695fb4SAndrei Emeltchenko bredr_chan->conn->mtu = hdev->block_mtu; 368627695fb4SAndrei Emeltchenko l2cap_logical_cfm(bredr_chan, hchan, 0); 368727695fb4SAndrei Emeltchenko hci_conn_hold(hcon); 368827695fb4SAndrei Emeltchenko 368927695fb4SAndrei Emeltchenko l2cap_chan_unlock(bredr_chan); 369027695fb4SAndrei Emeltchenko } 369127695fb4SAndrei Emeltchenko } 369227695fb4SAndrei Emeltchenko 3693606e2a10SAndrei Emeltchenko static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev, 3694606e2a10SAndrei Emeltchenko struct sk_buff *skb) 3695606e2a10SAndrei Emeltchenko { 3696606e2a10SAndrei Emeltchenko struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data; 3697606e2a10SAndrei Emeltchenko struct hci_chan *hchan; 3698606e2a10SAndrei Emeltchenko 3699606e2a10SAndrei Emeltchenko BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name, 3700606e2a10SAndrei Emeltchenko le16_to_cpu(ev->handle), ev->status); 3701606e2a10SAndrei Emeltchenko 3702606e2a10SAndrei Emeltchenko if (ev->status) 3703606e2a10SAndrei Emeltchenko return; 3704606e2a10SAndrei Emeltchenko 3705606e2a10SAndrei Emeltchenko hci_dev_lock(hdev); 3706606e2a10SAndrei Emeltchenko 3707606e2a10SAndrei Emeltchenko hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle)); 3708606e2a10SAndrei Emeltchenko if (!hchan) 3709606e2a10SAndrei Emeltchenko goto unlock; 3710606e2a10SAndrei Emeltchenko 3711606e2a10SAndrei Emeltchenko amp_destroy_logical_link(hchan, ev->reason); 3712606e2a10SAndrei Emeltchenko 3713606e2a10SAndrei Emeltchenko unlock: 3714606e2a10SAndrei Emeltchenko hci_dev_unlock(hdev); 3715606e2a10SAndrei Emeltchenko } 3716606e2a10SAndrei Emeltchenko 37179eef6b3aSAndrei Emeltchenko static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, 37189eef6b3aSAndrei Emeltchenko struct sk_buff *skb) 37199eef6b3aSAndrei Emeltchenko { 37209eef6b3aSAndrei Emeltchenko struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data; 37219eef6b3aSAndrei Emeltchenko struct hci_conn *hcon; 37229eef6b3aSAndrei Emeltchenko 37239eef6b3aSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 37249eef6b3aSAndrei Emeltchenko 37259eef6b3aSAndrei Emeltchenko if (ev->status) 37269eef6b3aSAndrei Emeltchenko return; 37279eef6b3aSAndrei Emeltchenko 37289eef6b3aSAndrei Emeltchenko hci_dev_lock(hdev); 37299eef6b3aSAndrei Emeltchenko 37309eef6b3aSAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 37319eef6b3aSAndrei Emeltchenko if (hcon) { 37329eef6b3aSAndrei Emeltchenko hcon->state = BT_CLOSED; 37339eef6b3aSAndrei Emeltchenko hci_conn_del(hcon); 37349eef6b3aSAndrei Emeltchenko } 37359eef6b3aSAndrei Emeltchenko 37369eef6b3aSAndrei Emeltchenko hci_dev_unlock(hdev); 37379eef6b3aSAndrei Emeltchenko } 37389eef6b3aSAndrei Emeltchenko 37396039aa73SGustavo Padovan static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 3740fcd89c09SVille Tervo { 3741fcd89c09SVille Tervo struct hci_ev_le_conn_complete *ev = (void *) skb->data; 3742fcd89c09SVille Tervo struct hci_conn *conn; 374368d6f6deSJohan Hedberg struct smp_irk *irk; 3744fcd89c09SVille Tervo 37459f1db00cSAndrei Emeltchenko BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); 3746fcd89c09SVille Tervo 3747fcd89c09SVille Tervo hci_dev_lock(hdev); 3748fcd89c09SVille Tervo 37494f72b329SAndrzej Kaczmarek conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); 3750b62f328bSVille Tervo if (!conn) { 3751b62f328bSVille Tervo conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr); 3752b62f328bSVille Tervo if (!conn) { 3753b62f328bSVille Tervo BT_ERR("No memory for new connection"); 3754230fd16aSAndre Guedes goto unlock; 3755b62f328bSVille Tervo } 375629b7988aSAndre Guedes 375729b7988aSAndre Guedes conn->dst_type = ev->bdaddr_type; 3758b9b343d2SAndre Guedes 3759880be4e8SMarcel Holtmann /* The advertising parameters for own address type 3760880be4e8SMarcel Holtmann * define which source address and source address 3761880be4e8SMarcel Holtmann * type this connections has. 3762880be4e8SMarcel Holtmann */ 3763880be4e8SMarcel Holtmann if (bacmp(&conn->src, BDADDR_ANY)) { 3764880be4e8SMarcel Holtmann conn->src_type = ADDR_LE_DEV_PUBLIC; 3765880be4e8SMarcel Holtmann } else { 3766880be4e8SMarcel Holtmann bacpy(&conn->src, &hdev->static_addr); 3767880be4e8SMarcel Holtmann conn->src_type = ADDR_LE_DEV_RANDOM; 3768880be4e8SMarcel Holtmann } 3769880be4e8SMarcel Holtmann 3770b9b343d2SAndre Guedes if (ev->role == LE_CONN_ROLE_MASTER) { 3771b9b343d2SAndre Guedes conn->out = true; 3772b9b343d2SAndre Guedes conn->link_mode |= HCI_LM_MASTER; 3773b9b343d2SAndre Guedes } 3774cb1d68f7SJohan Hedberg 3775cb1d68f7SJohan Hedberg /* If we didn't have a hci_conn object previously 3776cb1d68f7SJohan Hedberg * but we're in master role this must be something 3777cb1d68f7SJohan Hedberg * initiated using a white list. Since white list based 3778cb1d68f7SJohan Hedberg * connections are not "first class citizens" we don't 3779cb1d68f7SJohan Hedberg * have full tracking of them. Therefore, we go ahead 3780cb1d68f7SJohan Hedberg * with a "best effort" approach of determining the 3781cb1d68f7SJohan Hedberg * initiator address based on the HCI_PRIVACY flag. 3782cb1d68f7SJohan Hedberg */ 3783cb1d68f7SJohan Hedberg if (conn->out) { 3784cb1d68f7SJohan Hedberg conn->resp_addr_type = ev->bdaddr_type; 3785cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &ev->bdaddr); 3786cb1d68f7SJohan Hedberg if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) { 3787cb1d68f7SJohan Hedberg conn->init_addr_type = ADDR_LE_DEV_RANDOM; 3788cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->rpa); 3789cb1d68f7SJohan Hedberg } else { 3790cb1d68f7SJohan Hedberg hci_copy_identity_address(hdev, 3791cb1d68f7SJohan Hedberg &conn->init_addr, 3792cb1d68f7SJohan Hedberg &conn->init_addr_type); 3793cb1d68f7SJohan Hedberg } 3794cb1d68f7SJohan Hedberg } else { 3795cb1d68f7SJohan Hedberg /* Set the responder (our side) address type based on 3796cb1d68f7SJohan Hedberg * the advertising address type. 3797cb1d68f7SJohan Hedberg */ 3798cb1d68f7SJohan Hedberg conn->resp_addr_type = hdev->adv_addr_type; 3799cb1d68f7SJohan Hedberg if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) 3800cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &hdev->random_addr); 3801cb1d68f7SJohan Hedberg else 3802cb1d68f7SJohan Hedberg bacpy(&conn->resp_addr, &hdev->bdaddr); 3803cb1d68f7SJohan Hedberg 3804cb1d68f7SJohan Hedberg conn->init_addr_type = ev->bdaddr_type; 3805cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &ev->bdaddr); 3806cb1d68f7SJohan Hedberg } 38079489eca4SJohan Hedberg } else { 38089489eca4SJohan Hedberg cancel_delayed_work(&conn->le_conn_timeout); 3809b62f328bSVille Tervo } 3810fcd89c09SVille Tervo 38117be2edbbSJohan Hedberg /* Ensure that the hci_conn contains the identity address type 38127be2edbbSJohan Hedberg * regardless of which address the connection was made with. 38137be2edbbSJohan Hedberg */ 3814a1f4c318SJohan Hedberg hci_copy_identity_address(hdev, &conn->src, &conn->src_type); 38157be2edbbSJohan Hedberg 3816edb4b466SMarcel Holtmann /* Lookup the identity address from the stored connection 3817edb4b466SMarcel Holtmann * address and address type. 3818edb4b466SMarcel Holtmann * 3819edb4b466SMarcel Holtmann * When establishing connections to an identity address, the 3820edb4b466SMarcel Holtmann * connection procedure will store the resolvable random 3821edb4b466SMarcel Holtmann * address first. Now if it can be converted back into the 3822edb4b466SMarcel Holtmann * identity address, start using the identity address from 3823edb4b466SMarcel Holtmann * now on. 3824edb4b466SMarcel Holtmann */ 3825edb4b466SMarcel Holtmann irk = hci_get_irk(hdev, &conn->dst, conn->dst_type); 382668d6f6deSJohan Hedberg if (irk) { 382768d6f6deSJohan Hedberg bacpy(&conn->dst, &irk->bdaddr); 382868d6f6deSJohan Hedberg conn->dst_type = irk->addr_type; 382968d6f6deSJohan Hedberg } 383068d6f6deSJohan Hedberg 3831cd17decbSAndre Guedes if (ev->status) { 383206c053fbSAndre Guedes hci_le_conn_failed(conn, ev->status); 3833cd17decbSAndre Guedes goto unlock; 3834cd17decbSAndre Guedes } 3835cd17decbSAndre Guedes 3836b644ba33SJohan Hedberg if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 383701fdb0fcSMarcel Holtmann mgmt_device_connected(hdev, &conn->dst, conn->type, 383895b23582SSzymon Janc conn->dst_type, 0, NULL, 0, NULL); 383983bc71b4SVinicius Costa Gomes 38407b5c0d52SVinicius Costa Gomes conn->sec_level = BT_SECURITY_LOW; 3841fcd89c09SVille Tervo conn->handle = __le16_to_cpu(ev->handle); 3842fcd89c09SVille Tervo conn->state = BT_CONNECTED; 3843fcd89c09SVille Tervo 384418722c24SJukka Rissanen if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags)) 384518722c24SJukka Rissanen set_bit(HCI_CONN_6LOWPAN, &conn->flags); 384618722c24SJukka Rissanen 3847fcd89c09SVille Tervo hci_conn_add_sysfs(conn); 3848fcd89c09SVille Tervo 3849fcd89c09SVille Tervo hci_proto_connect_cfm(conn, ev->status); 3850fcd89c09SVille Tervo 3851a4790dbdSAndre Guedes hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type); 3852a4790dbdSAndre Guedes 3853fcd89c09SVille Tervo unlock: 3854fcd89c09SVille Tervo hci_dev_unlock(hdev); 3855fcd89c09SVille Tervo } 3856fcd89c09SVille Tervo 3857a4790dbdSAndre Guedes /* This function requires the caller holds hdev->lock */ 3858a4790dbdSAndre Guedes static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, 3859a4790dbdSAndre Guedes u8 addr_type) 3860a4790dbdSAndre Guedes { 3861a4790dbdSAndre Guedes struct hci_conn *conn; 38625b906a84SAndre Guedes struct smp_irk *irk; 38635b906a84SAndre Guedes 38645b906a84SAndre Guedes /* If this is a resolvable address, we should resolve it and then 38655b906a84SAndre Guedes * update address and address type variables. 38665b906a84SAndre Guedes */ 38675b906a84SAndre Guedes irk = hci_get_irk(hdev, addr, addr_type); 38685b906a84SAndre Guedes if (irk) { 38695b906a84SAndre Guedes addr = &irk->bdaddr; 38705b906a84SAndre Guedes addr_type = irk->addr_type; 38715b906a84SAndre Guedes } 3872a4790dbdSAndre Guedes 3873a4790dbdSAndre Guedes if (!hci_pend_le_conn_lookup(hdev, addr, addr_type)) 3874a4790dbdSAndre Guedes return; 3875a4790dbdSAndre Guedes 3876a4790dbdSAndre Guedes conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, 3877a4790dbdSAndre Guedes HCI_AT_NO_BONDING); 3878a4790dbdSAndre Guedes if (!IS_ERR(conn)) 3879a4790dbdSAndre Guedes return; 3880a4790dbdSAndre Guedes 3881a4790dbdSAndre Guedes switch (PTR_ERR(conn)) { 3882a4790dbdSAndre Guedes case -EBUSY: 3883a4790dbdSAndre Guedes /* If hci_connect() returns -EBUSY it means there is already 3884a4790dbdSAndre Guedes * an LE connection attempt going on. Since controllers don't 3885a4790dbdSAndre Guedes * support more than one connection attempt at the time, we 3886a4790dbdSAndre Guedes * don't consider this an error case. 3887a4790dbdSAndre Guedes */ 3888a4790dbdSAndre Guedes break; 3889a4790dbdSAndre Guedes default: 3890a4790dbdSAndre Guedes BT_DBG("Failed to connect: err %ld", PTR_ERR(conn)); 3891a4790dbdSAndre Guedes } 3892a4790dbdSAndre Guedes } 3893a4790dbdSAndre Guedes 38946039aa73SGustavo Padovan static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) 38959aa04c91SAndre Guedes { 3896e95beb41SAndre Guedes u8 num_reports = skb->data[0]; 3897e95beb41SAndre Guedes void *ptr = &skb->data[1]; 38983c9e9195SAndre Guedes s8 rssi; 38999aa04c91SAndre Guedes 3900a4790dbdSAndre Guedes hci_dev_lock(hdev); 3901a4790dbdSAndre Guedes 3902e95beb41SAndre Guedes while (num_reports--) { 3903e95beb41SAndre Guedes struct hci_ev_le_advertising_info *ev = ptr; 3904e95beb41SAndre Guedes 3905a4790dbdSAndre Guedes if (ev->evt_type == LE_ADV_IND || 3906a4790dbdSAndre Guedes ev->evt_type == LE_ADV_DIRECT_IND) 3907a4790dbdSAndre Guedes check_pending_le_conn(hdev, &ev->bdaddr, 3908a4790dbdSAndre Guedes ev->bdaddr_type); 3909a4790dbdSAndre Guedes 39103c9e9195SAndre Guedes rssi = ev->data[ev->length]; 39113c9e9195SAndre Guedes mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type, 391204124681SGustavo F. Padovan NULL, rssi, 0, 1, ev->data, ev->length); 39133c9e9195SAndre Guedes 3914e95beb41SAndre Guedes ptr += sizeof(*ev) + ev->length + 1; 39159aa04c91SAndre Guedes } 3916a4790dbdSAndre Guedes 3917a4790dbdSAndre Guedes hci_dev_unlock(hdev); 39189aa04c91SAndre Guedes } 39199aa04c91SAndre Guedes 39206039aa73SGustavo Padovan static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 3921a7a595f6SVinicius Costa Gomes { 3922a7a595f6SVinicius Costa Gomes struct hci_ev_le_ltk_req *ev = (void *) skb->data; 3923a7a595f6SVinicius Costa Gomes struct hci_cp_le_ltk_reply cp; 3924bea710feSVinicius Costa Gomes struct hci_cp_le_ltk_neg_reply neg; 3925a7a595f6SVinicius Costa Gomes struct hci_conn *conn; 3926c9839a11SVinicius Costa Gomes struct smp_ltk *ltk; 3927a7a595f6SVinicius Costa Gomes 39289f1db00cSAndrei Emeltchenko BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle)); 3929a7a595f6SVinicius Costa Gomes 3930a7a595f6SVinicius Costa Gomes hci_dev_lock(hdev); 3931a7a595f6SVinicius Costa Gomes 3932a7a595f6SVinicius Costa Gomes conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3933bea710feSVinicius Costa Gomes if (conn == NULL) 3934bea710feSVinicius Costa Gomes goto not_found; 3935a7a595f6SVinicius Costa Gomes 3936fe39c7b2SMarcel Holtmann ltk = hci_find_ltk(hdev, ev->ediv, ev->rand, conn->out); 3937bea710feSVinicius Costa Gomes if (ltk == NULL) 3938bea710feSVinicius Costa Gomes goto not_found; 3939bea710feSVinicius Costa Gomes 3940bea710feSVinicius Costa Gomes memcpy(cp.ltk, ltk->val, sizeof(ltk->val)); 3941a7a595f6SVinicius Costa Gomes cp.handle = cpu_to_le16(conn->handle); 3942c9839a11SVinicius Costa Gomes 3943c9839a11SVinicius Costa Gomes if (ltk->authenticated) 3944f8776218SAndre Guedes conn->pending_sec_level = BT_SECURITY_HIGH; 3945f8776218SAndre Guedes else 3946f8776218SAndre Guedes conn->pending_sec_level = BT_SECURITY_MEDIUM; 3947a7a595f6SVinicius Costa Gomes 394889cbb4daSAndre Guedes conn->enc_key_size = ltk->enc_size; 3949a7a595f6SVinicius Costa Gomes 3950a7a595f6SVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); 3951a7a595f6SVinicius Costa Gomes 3952c9839a11SVinicius Costa Gomes if (ltk->type & HCI_SMP_STK) { 3953c9839a11SVinicius Costa Gomes list_del(<k->list); 3954c9839a11SVinicius Costa Gomes kfree(ltk); 3955c9839a11SVinicius Costa Gomes } 3956c9839a11SVinicius Costa Gomes 3957a7a595f6SVinicius Costa Gomes hci_dev_unlock(hdev); 3958bea710feSVinicius Costa Gomes 3959bea710feSVinicius Costa Gomes return; 3960bea710feSVinicius Costa Gomes 3961bea710feSVinicius Costa Gomes not_found: 3962bea710feSVinicius Costa Gomes neg.handle = ev->handle; 3963bea710feSVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg); 3964bea710feSVinicius Costa Gomes hci_dev_unlock(hdev); 3965a7a595f6SVinicius Costa Gomes } 3966a7a595f6SVinicius Costa Gomes 39676039aa73SGustavo Padovan static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) 3968fcd89c09SVille Tervo { 3969fcd89c09SVille Tervo struct hci_ev_le_meta *le_ev = (void *) skb->data; 3970fcd89c09SVille Tervo 3971fcd89c09SVille Tervo skb_pull(skb, sizeof(*le_ev)); 3972fcd89c09SVille Tervo 3973fcd89c09SVille Tervo switch (le_ev->subevent) { 3974fcd89c09SVille Tervo case HCI_EV_LE_CONN_COMPLETE: 3975fcd89c09SVille Tervo hci_le_conn_complete_evt(hdev, skb); 3976fcd89c09SVille Tervo break; 3977fcd89c09SVille Tervo 39789aa04c91SAndre Guedes case HCI_EV_LE_ADVERTISING_REPORT: 39799aa04c91SAndre Guedes hci_le_adv_report_evt(hdev, skb); 39809aa04c91SAndre Guedes break; 39819aa04c91SAndre Guedes 3982a7a595f6SVinicius Costa Gomes case HCI_EV_LE_LTK_REQ: 3983a7a595f6SVinicius Costa Gomes hci_le_ltk_request_evt(hdev, skb); 3984a7a595f6SVinicius Costa Gomes break; 3985a7a595f6SVinicius Costa Gomes 3986fcd89c09SVille Tervo default: 3987fcd89c09SVille Tervo break; 3988fcd89c09SVille Tervo } 3989fcd89c09SVille Tervo } 3990fcd89c09SVille Tervo 39919495b2eeSAndrei Emeltchenko static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb) 39929495b2eeSAndrei Emeltchenko { 39939495b2eeSAndrei Emeltchenko struct hci_ev_channel_selected *ev = (void *) skb->data; 39949495b2eeSAndrei Emeltchenko struct hci_conn *hcon; 39959495b2eeSAndrei Emeltchenko 39969495b2eeSAndrei Emeltchenko BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle); 39979495b2eeSAndrei Emeltchenko 39989495b2eeSAndrei Emeltchenko skb_pull(skb, sizeof(*ev)); 39999495b2eeSAndrei Emeltchenko 40009495b2eeSAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 40019495b2eeSAndrei Emeltchenko if (!hcon) 40029495b2eeSAndrei Emeltchenko return; 40039495b2eeSAndrei Emeltchenko 40049495b2eeSAndrei Emeltchenko amp_read_loc_assoc_final_data(hdev, hcon); 40059495b2eeSAndrei Emeltchenko } 40069495b2eeSAndrei Emeltchenko 40071da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) 40081da177e4SLinus Torvalds { 4009a9de9248SMarcel Holtmann struct hci_event_hdr *hdr = (void *) skb->data; 4010a9de9248SMarcel Holtmann __u8 event = hdr->evt; 40111da177e4SLinus Torvalds 4012b6ddb638SJohan Hedberg hci_dev_lock(hdev); 4013b6ddb638SJohan Hedberg 4014b6ddb638SJohan Hedberg /* Received events are (currently) only needed when a request is 4015b6ddb638SJohan Hedberg * ongoing so avoid unnecessary memory allocation. 4016b6ddb638SJohan Hedberg */ 4017b6ddb638SJohan Hedberg if (hdev->req_status == HCI_REQ_PEND) { 4018b6ddb638SJohan Hedberg kfree_skb(hdev->recv_evt); 4019b6ddb638SJohan Hedberg hdev->recv_evt = skb_clone(skb, GFP_KERNEL); 4020b6ddb638SJohan Hedberg } 4021b6ddb638SJohan Hedberg 4022b6ddb638SJohan Hedberg hci_dev_unlock(hdev); 4023b6ddb638SJohan Hedberg 40241da177e4SLinus Torvalds skb_pull(skb, HCI_EVENT_HDR_SIZE); 40251da177e4SLinus Torvalds 402602350a72SJohan Hedberg if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) { 4027c1f23a2bSJohannes Berg struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data; 4028c1f23a2bSJohannes Berg u16 opcode = __le16_to_cpu(cmd_hdr->opcode); 402902350a72SJohan Hedberg 403002350a72SJohan Hedberg hci_req_cmd_complete(hdev, opcode, 0); 403102350a72SJohan Hedberg } 403202350a72SJohan Hedberg 4033a9de9248SMarcel Holtmann switch (event) { 40341da177e4SLinus Torvalds case HCI_EV_INQUIRY_COMPLETE: 40351da177e4SLinus Torvalds hci_inquiry_complete_evt(hdev, skb); 40361da177e4SLinus Torvalds break; 40371da177e4SLinus Torvalds 40381da177e4SLinus Torvalds case HCI_EV_INQUIRY_RESULT: 40391da177e4SLinus Torvalds hci_inquiry_result_evt(hdev, skb); 40401da177e4SLinus Torvalds break; 40411da177e4SLinus Torvalds 4042a9de9248SMarcel Holtmann case HCI_EV_CONN_COMPLETE: 4043a9de9248SMarcel Holtmann hci_conn_complete_evt(hdev, skb); 404421d9e30eSMarcel Holtmann break; 404521d9e30eSMarcel Holtmann 40461da177e4SLinus Torvalds case HCI_EV_CONN_REQUEST: 40471da177e4SLinus Torvalds hci_conn_request_evt(hdev, skb); 40481da177e4SLinus Torvalds break; 40491da177e4SLinus Torvalds 40501da177e4SLinus Torvalds case HCI_EV_DISCONN_COMPLETE: 40511da177e4SLinus Torvalds hci_disconn_complete_evt(hdev, skb); 40521da177e4SLinus Torvalds break; 40531da177e4SLinus Torvalds 40541da177e4SLinus Torvalds case HCI_EV_AUTH_COMPLETE: 40551da177e4SLinus Torvalds hci_auth_complete_evt(hdev, skb); 40561da177e4SLinus Torvalds break; 40571da177e4SLinus Torvalds 4058a9de9248SMarcel Holtmann case HCI_EV_REMOTE_NAME: 4059a9de9248SMarcel Holtmann hci_remote_name_evt(hdev, skb); 4060a9de9248SMarcel Holtmann break; 4061a9de9248SMarcel Holtmann 40621da177e4SLinus Torvalds case HCI_EV_ENCRYPT_CHANGE: 40631da177e4SLinus Torvalds hci_encrypt_change_evt(hdev, skb); 40641da177e4SLinus Torvalds break; 40651da177e4SLinus Torvalds 4066a9de9248SMarcel Holtmann case HCI_EV_CHANGE_LINK_KEY_COMPLETE: 4067a9de9248SMarcel Holtmann hci_change_link_key_complete_evt(hdev, skb); 4068a9de9248SMarcel Holtmann break; 4069a9de9248SMarcel Holtmann 4070a9de9248SMarcel Holtmann case HCI_EV_REMOTE_FEATURES: 4071a9de9248SMarcel Holtmann hci_remote_features_evt(hdev, skb); 4072a9de9248SMarcel Holtmann break; 4073a9de9248SMarcel Holtmann 4074a9de9248SMarcel Holtmann case HCI_EV_CMD_COMPLETE: 4075a9de9248SMarcel Holtmann hci_cmd_complete_evt(hdev, skb); 4076a9de9248SMarcel Holtmann break; 4077a9de9248SMarcel Holtmann 4078a9de9248SMarcel Holtmann case HCI_EV_CMD_STATUS: 4079a9de9248SMarcel Holtmann hci_cmd_status_evt(hdev, skb); 4080a9de9248SMarcel Holtmann break; 4081a9de9248SMarcel Holtmann 4082a9de9248SMarcel Holtmann case HCI_EV_ROLE_CHANGE: 4083a9de9248SMarcel Holtmann hci_role_change_evt(hdev, skb); 4084a9de9248SMarcel Holtmann break; 4085a9de9248SMarcel Holtmann 4086a9de9248SMarcel Holtmann case HCI_EV_NUM_COMP_PKTS: 4087a9de9248SMarcel Holtmann hci_num_comp_pkts_evt(hdev, skb); 4088a9de9248SMarcel Holtmann break; 4089a9de9248SMarcel Holtmann 4090a9de9248SMarcel Holtmann case HCI_EV_MODE_CHANGE: 4091a9de9248SMarcel Holtmann hci_mode_change_evt(hdev, skb); 40921da177e4SLinus Torvalds break; 40931da177e4SLinus Torvalds 40941da177e4SLinus Torvalds case HCI_EV_PIN_CODE_REQ: 40951da177e4SLinus Torvalds hci_pin_code_request_evt(hdev, skb); 40961da177e4SLinus Torvalds break; 40971da177e4SLinus Torvalds 40981da177e4SLinus Torvalds case HCI_EV_LINK_KEY_REQ: 40991da177e4SLinus Torvalds hci_link_key_request_evt(hdev, skb); 41001da177e4SLinus Torvalds break; 41011da177e4SLinus Torvalds 41021da177e4SLinus Torvalds case HCI_EV_LINK_KEY_NOTIFY: 41031da177e4SLinus Torvalds hci_link_key_notify_evt(hdev, skb); 41041da177e4SLinus Torvalds break; 41051da177e4SLinus Torvalds 41061da177e4SLinus Torvalds case HCI_EV_CLOCK_OFFSET: 41071da177e4SLinus Torvalds hci_clock_offset_evt(hdev, skb); 41081da177e4SLinus Torvalds break; 41091da177e4SLinus Torvalds 4110a8746417SMarcel Holtmann case HCI_EV_PKT_TYPE_CHANGE: 4111a8746417SMarcel Holtmann hci_pkt_type_change_evt(hdev, skb); 4112a8746417SMarcel Holtmann break; 4113a8746417SMarcel Holtmann 411485a1e930SMarcel Holtmann case HCI_EV_PSCAN_REP_MODE: 411585a1e930SMarcel Holtmann hci_pscan_rep_mode_evt(hdev, skb); 411685a1e930SMarcel Holtmann break; 411785a1e930SMarcel Holtmann 4118a9de9248SMarcel Holtmann case HCI_EV_INQUIRY_RESULT_WITH_RSSI: 4119a9de9248SMarcel Holtmann hci_inquiry_result_with_rssi_evt(hdev, skb); 4120a9de9248SMarcel Holtmann break; 4121a9de9248SMarcel Holtmann 4122a9de9248SMarcel Holtmann case HCI_EV_REMOTE_EXT_FEATURES: 4123a9de9248SMarcel Holtmann hci_remote_ext_features_evt(hdev, skb); 4124a9de9248SMarcel Holtmann break; 4125a9de9248SMarcel Holtmann 4126a9de9248SMarcel Holtmann case HCI_EV_SYNC_CONN_COMPLETE: 4127a9de9248SMarcel Holtmann hci_sync_conn_complete_evt(hdev, skb); 4128a9de9248SMarcel Holtmann break; 4129a9de9248SMarcel Holtmann 4130a9de9248SMarcel Holtmann case HCI_EV_EXTENDED_INQUIRY_RESULT: 4131a9de9248SMarcel Holtmann hci_extended_inquiry_result_evt(hdev, skb); 41321da177e4SLinus Torvalds break; 41331da177e4SLinus Torvalds 41341c2e0041SJohan Hedberg case HCI_EV_KEY_REFRESH_COMPLETE: 41351c2e0041SJohan Hedberg hci_key_refresh_complete_evt(hdev, skb); 41361c2e0041SJohan Hedberg break; 41371c2e0041SJohan Hedberg 41380493684eSMarcel Holtmann case HCI_EV_IO_CAPA_REQUEST: 41390493684eSMarcel Holtmann hci_io_capa_request_evt(hdev, skb); 41400493684eSMarcel Holtmann break; 41410493684eSMarcel Holtmann 414203b555e1SJohan Hedberg case HCI_EV_IO_CAPA_REPLY: 414303b555e1SJohan Hedberg hci_io_capa_reply_evt(hdev, skb); 414403b555e1SJohan Hedberg break; 414503b555e1SJohan Hedberg 4146a5c29683SJohan Hedberg case HCI_EV_USER_CONFIRM_REQUEST: 4147a5c29683SJohan Hedberg hci_user_confirm_request_evt(hdev, skb); 4148a5c29683SJohan Hedberg break; 4149a5c29683SJohan Hedberg 41501143d458SBrian Gix case HCI_EV_USER_PASSKEY_REQUEST: 41511143d458SBrian Gix hci_user_passkey_request_evt(hdev, skb); 41521143d458SBrian Gix break; 41531143d458SBrian Gix 415492a25256SJohan Hedberg case HCI_EV_USER_PASSKEY_NOTIFY: 415592a25256SJohan Hedberg hci_user_passkey_notify_evt(hdev, skb); 415692a25256SJohan Hedberg break; 415792a25256SJohan Hedberg 415892a25256SJohan Hedberg case HCI_EV_KEYPRESS_NOTIFY: 415992a25256SJohan Hedberg hci_keypress_notify_evt(hdev, skb); 416092a25256SJohan Hedberg break; 416192a25256SJohan Hedberg 41620493684eSMarcel Holtmann case HCI_EV_SIMPLE_PAIR_COMPLETE: 41630493684eSMarcel Holtmann hci_simple_pair_complete_evt(hdev, skb); 41640493684eSMarcel Holtmann break; 41650493684eSMarcel Holtmann 416641a96212SMarcel Holtmann case HCI_EV_REMOTE_HOST_FEATURES: 416741a96212SMarcel Holtmann hci_remote_host_features_evt(hdev, skb); 416841a96212SMarcel Holtmann break; 416941a96212SMarcel Holtmann 4170fcd89c09SVille Tervo case HCI_EV_LE_META: 4171fcd89c09SVille Tervo hci_le_meta_evt(hdev, skb); 4172fcd89c09SVille Tervo break; 4173fcd89c09SVille Tervo 41749495b2eeSAndrei Emeltchenko case HCI_EV_CHANNEL_SELECTED: 41759495b2eeSAndrei Emeltchenko hci_chan_selected_evt(hdev, skb); 41769495b2eeSAndrei Emeltchenko break; 41779495b2eeSAndrei Emeltchenko 41782763eda6SSzymon Janc case HCI_EV_REMOTE_OOB_DATA_REQUEST: 41792763eda6SSzymon Janc hci_remote_oob_data_request_evt(hdev, skb); 41802763eda6SSzymon Janc break; 41812763eda6SSzymon Janc 4182d5e91192SAndrei Emeltchenko case HCI_EV_PHY_LINK_COMPLETE: 4183d5e91192SAndrei Emeltchenko hci_phy_link_complete_evt(hdev, skb); 4184d5e91192SAndrei Emeltchenko break; 4185d5e91192SAndrei Emeltchenko 418627695fb4SAndrei Emeltchenko case HCI_EV_LOGICAL_LINK_COMPLETE: 418727695fb4SAndrei Emeltchenko hci_loglink_complete_evt(hdev, skb); 418827695fb4SAndrei Emeltchenko break; 418927695fb4SAndrei Emeltchenko 4190606e2a10SAndrei Emeltchenko case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE: 4191606e2a10SAndrei Emeltchenko hci_disconn_loglink_complete_evt(hdev, skb); 4192606e2a10SAndrei Emeltchenko break; 4193606e2a10SAndrei Emeltchenko 41949eef6b3aSAndrei Emeltchenko case HCI_EV_DISCONN_PHY_LINK_COMPLETE: 41959eef6b3aSAndrei Emeltchenko hci_disconn_phylink_complete_evt(hdev, skb); 41969eef6b3aSAndrei Emeltchenko break; 41979eef6b3aSAndrei Emeltchenko 419825e89e99SAndrei Emeltchenko case HCI_EV_NUM_COMP_BLOCKS: 419925e89e99SAndrei Emeltchenko hci_num_comp_blocks_evt(hdev, skb); 420025e89e99SAndrei Emeltchenko break; 420125e89e99SAndrei Emeltchenko 42021da177e4SLinus Torvalds default: 42039f1db00cSAndrei Emeltchenko BT_DBG("%s event 0x%2.2x", hdev->name, event); 42041da177e4SLinus Torvalds break; 42051da177e4SLinus Torvalds } 42061da177e4SLinus Torvalds 42071da177e4SLinus Torvalds kfree_skb(skb); 42081da177e4SLinus Torvalds hdev->stat.evt_rx++; 42091da177e4SLinus Torvalds } 4210