11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds BlueZ - Bluetooth protocol stack for Linux 32d0a0346SRon Shaffer Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved. 41da177e4SLinus Torvalds 51da177e4SLinus Torvalds Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 61da177e4SLinus Torvalds 71da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify 81da177e4SLinus Torvalds it under the terms of the GNU General Public License version 2 as 91da177e4SLinus Torvalds published by the Free Software Foundation; 101da177e4SLinus Torvalds 111da177e4SLinus Torvalds THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 121da177e4SLinus Torvalds OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 131da177e4SLinus Torvalds FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 141da177e4SLinus Torvalds IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 151da177e4SLinus Torvalds CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 161da177e4SLinus Torvalds WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 171da177e4SLinus Torvalds ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 181da177e4SLinus Torvalds OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 211da177e4SLinus Torvalds COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 221da177e4SLinus Torvalds SOFTWARE IS DISCLAIMED. 231da177e4SLinus Torvalds */ 241da177e4SLinus Torvalds 251da177e4SLinus Torvalds /* Bluetooth HCI event handling. */ 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds #include <asm/unaligned.h> 281da177e4SLinus Torvalds 291da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h> 301da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h> 31f0d6a0eaSMikel Astiz #include <net/bluetooth/mgmt.h> 327ef9fbf0SMarcel Holtmann 330857dd3bSJohan Hedberg #include "hci_request.h" 3423b9ceb7SMarcel Holtmann #include "hci_debugfs.h" 357024728eSMarcel Holtmann #include "a2mp.h" 367ef9fbf0SMarcel Holtmann #include "amp.h" 372ceba539SJohan Hedberg #include "smp.h" 38145373cbSMiao-chen Chou #include "msft.h" 3901ce70b0SLuiz Augusto von Dentz #include "eir.h" 401da177e4SLinus Torvalds 41aa5b0345SMarcel Holtmann #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \ 42aa5b0345SMarcel Holtmann "\x00\x00\x00\x00\x00\x00\x00\x00" 43aa5b0345SMarcel Holtmann 44c45074d6SLuiz Augusto von Dentz #define secs_to_jiffies(_secs) msecs_to_jiffies((_secs) * 1000) 45c45074d6SLuiz Augusto von Dentz 461da177e4SLinus Torvalds /* Handle HCI Event packets */ 471da177e4SLinus Torvalds 48ae61a10dSLuiz Augusto von Dentz static void *hci_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb, 49ae61a10dSLuiz Augusto von Dentz u8 ev, size_t len) 50ae61a10dSLuiz Augusto von Dentz { 51ae61a10dSLuiz Augusto von Dentz void *data; 52ae61a10dSLuiz Augusto von Dentz 53ae61a10dSLuiz Augusto von Dentz data = skb_pull_data(skb, len); 54ae61a10dSLuiz Augusto von Dentz if (!data) 55ae61a10dSLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed Event: 0x%2.2x", ev); 56ae61a10dSLuiz Augusto von Dentz 57ae61a10dSLuiz Augusto von Dentz return data; 58ae61a10dSLuiz Augusto von Dentz } 59ae61a10dSLuiz Augusto von Dentz 60e3f3a1aeSLuiz Augusto von Dentz static void *hci_cc_skb_pull(struct hci_dev *hdev, struct sk_buff *skb, 61e3f3a1aeSLuiz Augusto von Dentz u16 op, size_t len) 62e3f3a1aeSLuiz Augusto von Dentz { 63e3f3a1aeSLuiz Augusto von Dentz void *data; 64e3f3a1aeSLuiz Augusto von Dentz 65e3f3a1aeSLuiz Augusto von Dentz data = skb_pull_data(skb, len); 66e3f3a1aeSLuiz Augusto von Dentz if (!data) 67e3f3a1aeSLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed Command Complete: 0x%4.4x", op); 68e3f3a1aeSLuiz Augusto von Dentz 69e3f3a1aeSLuiz Augusto von Dentz return data; 70e3f3a1aeSLuiz Augusto von Dentz } 71e3f3a1aeSLuiz Augusto von Dentz 7212cfe417SLuiz Augusto von Dentz static void *hci_le_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb, 7312cfe417SLuiz Augusto von Dentz u8 ev, size_t len) 7412cfe417SLuiz Augusto von Dentz { 7512cfe417SLuiz Augusto von Dentz void *data; 7612cfe417SLuiz Augusto von Dentz 7712cfe417SLuiz Augusto von Dentz data = skb_pull_data(skb, len); 7812cfe417SLuiz Augusto von Dentz if (!data) 7912cfe417SLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed LE Event: 0x%2.2x", ev); 8012cfe417SLuiz Augusto von Dentz 8112cfe417SLuiz Augusto von Dentz return data; 8212cfe417SLuiz Augusto von Dentz } 8312cfe417SLuiz Augusto von Dentz 84c8992cffSLuiz Augusto von Dentz static u8 hci_cc_inquiry_cancel(struct hci_dev *hdev, void *data, 85c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 861da177e4SLinus Torvalds { 87c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 88e3f3a1aeSLuiz Augusto von Dentz 89e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 901da177e4SLinus Torvalds 91adf1d692SSonny Sasaka /* It is possible that we receive Inquiry Complete event right 92adf1d692SSonny Sasaka * before we receive Inquiry Cancel Command Complete event, in 93adf1d692SSonny Sasaka * which case the latter event should have status of Command 94adf1d692SSonny Sasaka * Disallowed (0x0c). This should not be treated as error, since 95adf1d692SSonny Sasaka * we actually achieve what Inquiry Cancel wants to achieve, 96adf1d692SSonny Sasaka * which is to end the last Inquiry session. 97adf1d692SSonny Sasaka */ 98e3f3a1aeSLuiz Augusto von Dentz if (rp->status == 0x0c && !test_bit(HCI_INQUIRY, &hdev->flags)) { 99adf1d692SSonny Sasaka bt_dev_warn(hdev, "Ignoring error of Inquiry Cancel command"); 100e3f3a1aeSLuiz Augusto von Dentz rp->status = 0x00; 101adf1d692SSonny Sasaka } 102adf1d692SSonny Sasaka 103e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 104c8992cffSLuiz Augusto von Dentz return rp->status; 1051da177e4SLinus Torvalds 10689352e7dSAndre Guedes clear_bit(HCI_INQUIRY, &hdev->flags); 1074e857c58SPeter Zijlstra smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */ 1083e13fa1eSAndre Guedes wake_up_bit(&hdev->flags, HCI_INQUIRY); 10989352e7dSAndre Guedes 11050143a43SJohan Hedberg hci_dev_lock(hdev); 111168b8a25SJakub Pawlowski /* Set discovery state to stopped if we're not doing LE active 112168b8a25SJakub Pawlowski * scanning. 113168b8a25SJakub Pawlowski */ 114168b8a25SJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) || 115168b8a25SJakub Pawlowski hdev->le_scan_type != LE_SCAN_ACTIVE) 11650143a43SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 11750143a43SJohan Hedberg hci_dev_unlock(hdev); 11850143a43SJohan Hedberg 119a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 120c8992cffSLuiz Augusto von Dentz 121c8992cffSLuiz Augusto von Dentz return rp->status; 1221da177e4SLinus Torvalds } 1236bd57416SMarcel Holtmann 124c8992cffSLuiz Augusto von Dentz static u8 hci_cc_periodic_inq(struct hci_dev *hdev, void *data, 125c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1264d93483bSAndre Guedes { 127c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 128ae854a70SAndre Guedes 129e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 130e3f3a1aeSLuiz Augusto von Dentz 131e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 132c8992cffSLuiz Augusto von Dentz return rp->status; 133ae854a70SAndre Guedes 134a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_PERIODIC_INQ); 135c8992cffSLuiz Augusto von Dentz 136c8992cffSLuiz Augusto von Dentz return rp->status; 1374d93483bSAndre Guedes } 1384d93483bSAndre Guedes 139c8992cffSLuiz Augusto von Dentz static u8 hci_cc_exit_periodic_inq(struct hci_dev *hdev, void *data, 140c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1411da177e4SLinus Torvalds { 142c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 143a9de9248SMarcel Holtmann 144e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 145e3f3a1aeSLuiz Augusto von Dentz 146e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 147c8992cffSLuiz Augusto von Dentz return rp->status; 148a9de9248SMarcel Holtmann 149a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ); 150ae854a70SAndre Guedes 151a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 152c8992cffSLuiz Augusto von Dentz 153c8992cffSLuiz Augusto von Dentz return rp->status; 154a9de9248SMarcel Holtmann } 155a9de9248SMarcel Holtmann 156c8992cffSLuiz Augusto von Dentz static u8 hci_cc_remote_name_req_cancel(struct hci_dev *hdev, void *data, 157807deac2SGustavo Padovan struct sk_buff *skb) 158a9de9248SMarcel Holtmann { 159c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 160e3f3a1aeSLuiz Augusto von Dentz 161e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 162c8992cffSLuiz Augusto von Dentz 163c8992cffSLuiz Augusto von Dentz return rp->status; 164a9de9248SMarcel Holtmann } 165a9de9248SMarcel Holtmann 166c8992cffSLuiz Augusto von Dentz static u8 hci_cc_role_discovery(struct hci_dev *hdev, void *data, 167c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 168a9de9248SMarcel Holtmann { 169c8992cffSLuiz Augusto von Dentz struct hci_rp_role_discovery *rp = data; 1701da177e4SLinus Torvalds struct hci_conn *conn; 1711da177e4SLinus Torvalds 172e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1731da177e4SLinus Torvalds 174a9de9248SMarcel Holtmann if (rp->status) 175c8992cffSLuiz Augusto von Dentz return rp->status; 1761da177e4SLinus Torvalds 1771da177e4SLinus Torvalds hci_dev_lock(hdev); 1781da177e4SLinus Torvalds 179a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 18040bef302SJohan Hedberg if (conn) 18140bef302SJohan Hedberg conn->role = rp->role; 1821da177e4SLinus Torvalds 1831da177e4SLinus Torvalds hci_dev_unlock(hdev); 184c8992cffSLuiz Augusto von Dentz 185c8992cffSLuiz Augusto von Dentz return rp->status; 186a9de9248SMarcel Holtmann } 1871da177e4SLinus Torvalds 188c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_link_policy(struct hci_dev *hdev, void *data, 189c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 190e4e8e37cSMarcel Holtmann { 191c8992cffSLuiz Augusto von Dentz struct hci_rp_read_link_policy *rp = data; 192e4e8e37cSMarcel Holtmann struct hci_conn *conn; 193e4e8e37cSMarcel Holtmann 194e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 195e4e8e37cSMarcel Holtmann 196e4e8e37cSMarcel Holtmann if (rp->status) 197c8992cffSLuiz Augusto von Dentz return rp->status; 198e4e8e37cSMarcel Holtmann 199e4e8e37cSMarcel Holtmann hci_dev_lock(hdev); 200e4e8e37cSMarcel Holtmann 201e4e8e37cSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 202e4e8e37cSMarcel Holtmann if (conn) 203e4e8e37cSMarcel Holtmann conn->link_policy = __le16_to_cpu(rp->policy); 204e4e8e37cSMarcel Holtmann 205e4e8e37cSMarcel Holtmann hci_dev_unlock(hdev); 206c8992cffSLuiz Augusto von Dentz 207c8992cffSLuiz Augusto von Dentz return rp->status; 208e4e8e37cSMarcel Holtmann } 209e4e8e37cSMarcel Holtmann 210c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_link_policy(struct hci_dev *hdev, void *data, 211c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 212a9de9248SMarcel Holtmann { 213c8992cffSLuiz Augusto von Dentz struct hci_rp_write_link_policy *rp = data; 214a9de9248SMarcel Holtmann struct hci_conn *conn; 215a9de9248SMarcel Holtmann void *sent; 216a9de9248SMarcel Holtmann 217e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 218a9de9248SMarcel Holtmann 219a9de9248SMarcel Holtmann if (rp->status) 220c8992cffSLuiz Augusto von Dentz return rp->status; 221a9de9248SMarcel Holtmann 222a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY); 22304837f64SMarcel Holtmann if (!sent) 224c8992cffSLuiz Augusto von Dentz return rp->status; 22504837f64SMarcel Holtmann 22604837f64SMarcel Holtmann hci_dev_lock(hdev); 22704837f64SMarcel Holtmann 228a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 229e4e8e37cSMarcel Holtmann if (conn) 23083985319SHarvey Harrison conn->link_policy = get_unaligned_le16(sent + 2); 23104837f64SMarcel Holtmann 23204837f64SMarcel Holtmann hci_dev_unlock(hdev); 233c8992cffSLuiz Augusto von Dentz 234c8992cffSLuiz Augusto von Dentz return rp->status; 2351da177e4SLinus Torvalds } 2361da177e4SLinus Torvalds 237c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_def_link_policy(struct hci_dev *hdev, void *data, 238807deac2SGustavo Padovan struct sk_buff *skb) 239e4e8e37cSMarcel Holtmann { 240c8992cffSLuiz Augusto von Dentz struct hci_rp_read_def_link_policy *rp = data; 241e3f3a1aeSLuiz Augusto von Dentz 242e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 243e4e8e37cSMarcel Holtmann 244e4e8e37cSMarcel Holtmann if (rp->status) 245c8992cffSLuiz Augusto von Dentz return rp->status; 246e4e8e37cSMarcel Holtmann 247e4e8e37cSMarcel Holtmann hdev->link_policy = __le16_to_cpu(rp->policy); 248c8992cffSLuiz Augusto von Dentz 249c8992cffSLuiz Augusto von Dentz return rp->status; 250e4e8e37cSMarcel Holtmann } 251e4e8e37cSMarcel Holtmann 252c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_def_link_policy(struct hci_dev *hdev, void *data, 253807deac2SGustavo Padovan struct sk_buff *skb) 254e4e8e37cSMarcel Holtmann { 255c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 256e4e8e37cSMarcel Holtmann void *sent; 257e4e8e37cSMarcel Holtmann 258e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 259e3f3a1aeSLuiz Augusto von Dentz 260e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 261c8992cffSLuiz Augusto von Dentz return rp->status; 26245296acdSMarcel Holtmann 263e4e8e37cSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY); 264e4e8e37cSMarcel Holtmann if (!sent) 265c8992cffSLuiz Augusto von Dentz return rp->status; 266e4e8e37cSMarcel Holtmann 267e4e8e37cSMarcel Holtmann hdev->link_policy = get_unaligned_le16(sent); 268c8992cffSLuiz Augusto von Dentz 269c8992cffSLuiz Augusto von Dentz return rp->status; 270e4e8e37cSMarcel Holtmann } 271e4e8e37cSMarcel Holtmann 272c8992cffSLuiz Augusto von Dentz static u8 hci_cc_reset(struct hci_dev *hdev, void *data, struct sk_buff *skb) 2731da177e4SLinus Torvalds { 274c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 275e3f3a1aeSLuiz Augusto von Dentz 276e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 277a9de9248SMarcel Holtmann 27810572132SGustavo F. Padovan clear_bit(HCI_RESET, &hdev->flags); 27910572132SGustavo F. Padovan 280e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 281c8992cffSLuiz Augusto von Dentz return rp->status; 2828761f9d6SMarcel Holtmann 283a297e97cSJohan Hedberg /* Reset all non-persistent flags */ 284eacb44dfSMarcel Holtmann hci_dev_clear_volatile_flags(hdev); 28569775ff6SAndre Guedes 28639c5d970SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 28739c5d970SJohan Hedberg 288bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID; 289bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID; 2903f0f524bSJohan Hedberg 2913f0f524bSJohan Hedberg memset(hdev->adv_data, 0, sizeof(hdev->adv_data)); 2923f0f524bSJohan Hedberg hdev->adv_data_len = 0; 293f8e808bdSMarcel Holtmann 294f8e808bdSMarcel Holtmann memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data)); 295f8e808bdSMarcel Holtmann hdev->scan_rsp_data_len = 0; 29606f5b778SMarcel Holtmann 297533553f8SMarcel Holtmann hdev->le_scan_type = LE_SCAN_PASSIVE; 298533553f8SMarcel Holtmann 29906f5b778SMarcel Holtmann hdev->ssp_debug_mode = 0; 300a4d5504dSMarcel Holtmann 3013d4f9c00SArchie Pusaka hci_bdaddr_list_clear(&hdev->le_accept_list); 302cfdb0c2dSAnkit Navik hci_bdaddr_list_clear(&hdev->le_resolv_list); 303c8992cffSLuiz Augusto von Dentz 304c8992cffSLuiz Augusto von Dentz return rp->status; 305a9de9248SMarcel Holtmann } 306a9de9248SMarcel Holtmann 307c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_stored_link_key(struct hci_dev *hdev, void *data, 308c2f0f979SMarcel Holtmann struct sk_buff *skb) 309c2f0f979SMarcel Holtmann { 310c8992cffSLuiz Augusto von Dentz struct hci_rp_read_stored_link_key *rp = data; 311c2f0f979SMarcel Holtmann struct hci_cp_read_stored_link_key *sent; 312c2f0f979SMarcel Holtmann 313e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 314c2f0f979SMarcel Holtmann 315c2f0f979SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_READ_STORED_LINK_KEY); 316c2f0f979SMarcel Holtmann if (!sent) 317c8992cffSLuiz Augusto von Dentz return rp->status; 318c2f0f979SMarcel Holtmann 319c2f0f979SMarcel Holtmann if (!rp->status && sent->read_all == 0x01) { 320e88422bcSLuiz Augusto von Dentz hdev->stored_max_keys = le16_to_cpu(rp->max_keys); 321e88422bcSLuiz Augusto von Dentz hdev->stored_num_keys = le16_to_cpu(rp->num_keys); 322c2f0f979SMarcel Holtmann } 323c8992cffSLuiz Augusto von Dentz 324c8992cffSLuiz Augusto von Dentz return rp->status; 325c2f0f979SMarcel Holtmann } 326c2f0f979SMarcel Holtmann 327c8992cffSLuiz Augusto von Dentz static u8 hci_cc_delete_stored_link_key(struct hci_dev *hdev, void *data, 328a9366120SMarcel Holtmann struct sk_buff *skb) 329a9366120SMarcel Holtmann { 330c8992cffSLuiz Augusto von Dentz struct hci_rp_delete_stored_link_key *rp = data; 331e3f3a1aeSLuiz Augusto von Dentz 332e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 333a9366120SMarcel Holtmann 334a9366120SMarcel Holtmann if (rp->status) 335c8992cffSLuiz Augusto von Dentz return rp->status; 336a9366120SMarcel Holtmann 337a9366120SMarcel Holtmann if (rp->num_keys <= hdev->stored_num_keys) 3387978656cSLuiz Augusto von Dentz hdev->stored_num_keys -= le16_to_cpu(rp->num_keys); 339a9366120SMarcel Holtmann else 340a9366120SMarcel Holtmann hdev->stored_num_keys = 0; 341c8992cffSLuiz Augusto von Dentz 342c8992cffSLuiz Augusto von Dentz return rp->status; 343a9366120SMarcel Holtmann } 344a9366120SMarcel Holtmann 345c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_local_name(struct hci_dev *hdev, void *data, 346c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 347a9de9248SMarcel Holtmann { 348c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 3491da177e4SLinus Torvalds void *sent; 3501da177e4SLinus Torvalds 351e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 3521da177e4SLinus Torvalds 353a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME); 3541da177e4SLinus Torvalds if (!sent) 355c8992cffSLuiz Augusto von Dentz return rp->status; 3561da177e4SLinus Torvalds 35756e5cb86SJohan Hedberg hci_dev_lock(hdev); 35856e5cb86SJohan Hedberg 359d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 360e3f3a1aeSLuiz Augusto von Dentz mgmt_set_local_name_complete(hdev, sent, rp->status); 361e3f3a1aeSLuiz Augusto von Dentz else if (!rp->status) 36228cc7bdeSJohan Hedberg memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); 363f51d5b24SJohan Hedberg 36456e5cb86SJohan Hedberg hci_dev_unlock(hdev); 365c8992cffSLuiz Augusto von Dentz 366c8992cffSLuiz Augusto von Dentz return rp->status; 367a9de9248SMarcel Holtmann } 368a9de9248SMarcel Holtmann 369c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_name(struct hci_dev *hdev, void *data, 370c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 371a9de9248SMarcel Holtmann { 372c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_name *rp = data; 373e3f3a1aeSLuiz Augusto von Dentz 374e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 375a9de9248SMarcel Holtmann 376a9de9248SMarcel Holtmann if (rp->status) 377c8992cffSLuiz Augusto von Dentz return rp->status; 378a9de9248SMarcel Holtmann 379d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 380d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) 3811f6c6378SJohan Hedberg memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); 382c8992cffSLuiz Augusto von Dentz 383c8992cffSLuiz Augusto von Dentz return rp->status; 384a9de9248SMarcel Holtmann } 385a9de9248SMarcel Holtmann 386c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_auth_enable(struct hci_dev *hdev, void *data, 387c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 388a9de9248SMarcel Holtmann { 389c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 390a9de9248SMarcel Holtmann void *sent; 391a9de9248SMarcel Holtmann 392e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 393a9de9248SMarcel Holtmann 394a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE); 395a9de9248SMarcel Holtmann if (!sent) 396c8992cffSLuiz Augusto von Dentz return rp->status; 3971da177e4SLinus Torvalds 3985c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 3995c1a4c8fSJaganath Kanakkassery 400e3f3a1aeSLuiz Augusto von Dentz if (!rp->status) { 401a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent); 402a9de9248SMarcel Holtmann 4031da177e4SLinus Torvalds if (param == AUTH_ENABLED) 4041da177e4SLinus Torvalds set_bit(HCI_AUTH, &hdev->flags); 4051da177e4SLinus Torvalds else 4061da177e4SLinus Torvalds clear_bit(HCI_AUTH, &hdev->flags); 4071da177e4SLinus Torvalds } 408a9de9248SMarcel Holtmann 409d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 410e3f3a1aeSLuiz Augusto von Dentz mgmt_auth_enable_complete(hdev, rp->status); 4115c1a4c8fSJaganath Kanakkassery 4125c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 413c8992cffSLuiz Augusto von Dentz 414c8992cffSLuiz Augusto von Dentz return rp->status; 415a9de9248SMarcel Holtmann } 4161da177e4SLinus Torvalds 417c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_encrypt_mode(struct hci_dev *hdev, void *data, 418c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 419a9de9248SMarcel Holtmann { 420c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 42145296acdSMarcel Holtmann __u8 param; 422a9de9248SMarcel Holtmann void *sent; 423a9de9248SMarcel Holtmann 424e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 425e3f3a1aeSLuiz Augusto von Dentz 426e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 427c8992cffSLuiz Augusto von Dentz return rp->status; 42845296acdSMarcel Holtmann 429a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE); 4301da177e4SLinus Torvalds if (!sent) 431c8992cffSLuiz Augusto von Dentz return rp->status; 4321da177e4SLinus Torvalds 43345296acdSMarcel Holtmann param = *((__u8 *) sent); 434a9de9248SMarcel Holtmann 4351da177e4SLinus Torvalds if (param) 4361da177e4SLinus Torvalds set_bit(HCI_ENCRYPT, &hdev->flags); 4371da177e4SLinus Torvalds else 4381da177e4SLinus Torvalds clear_bit(HCI_ENCRYPT, &hdev->flags); 439c8992cffSLuiz Augusto von Dentz 440c8992cffSLuiz Augusto von Dentz return rp->status; 4411da177e4SLinus Torvalds } 4421da177e4SLinus Torvalds 443c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_scan_enable(struct hci_dev *hdev, void *data, 444c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 445a9de9248SMarcel Holtmann { 446c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 44745296acdSMarcel Holtmann __u8 param; 448a9de9248SMarcel Holtmann void *sent; 4491da177e4SLinus Torvalds 450e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 451a9de9248SMarcel Holtmann 452a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE); 4531da177e4SLinus Torvalds if (!sent) 454c8992cffSLuiz Augusto von Dentz return rp->status; 4551da177e4SLinus Torvalds 45636f7fc7eSJohan Hedberg param = *((__u8 *) sent); 457a9de9248SMarcel Holtmann 45856e5cb86SJohan Hedberg hci_dev_lock(hdev); 45956e5cb86SJohan Hedberg 460e3f3a1aeSLuiz Augusto von Dentz if (rp->status) { 4612d7cee58SJohan Hedberg hdev->discov_timeout = 0; 4622d7cee58SJohan Hedberg goto done; 4632d7cee58SJohan Hedberg } 4642d7cee58SJohan Hedberg 465bc6d2d04SJohan Hedberg if (param & SCAN_INQUIRY) 4661da177e4SLinus Torvalds set_bit(HCI_ISCAN, &hdev->flags); 467bc6d2d04SJohan Hedberg else 468bc6d2d04SJohan Hedberg clear_bit(HCI_ISCAN, &hdev->flags); 4691da177e4SLinus Torvalds 470031547d8SJohan Hedberg if (param & SCAN_PAGE) 4711da177e4SLinus Torvalds set_bit(HCI_PSCAN, &hdev->flags); 472bc6d2d04SJohan Hedberg else 473204e3990SJohan Hedberg clear_bit(HCI_PSCAN, &hdev->flags); 474a9de9248SMarcel Holtmann 47536f7fc7eSJohan Hedberg done: 47656e5cb86SJohan Hedberg hci_dev_unlock(hdev); 477c8992cffSLuiz Augusto von Dentz 478c8992cffSLuiz Augusto von Dentz return rp->status; 4791da177e4SLinus Torvalds } 4801da177e4SLinus Torvalds 481c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_event_filter(struct hci_dev *hdev, void *data, 482c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 483e5b0ad69SAbhishek Pandit-Subedi { 484c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 485e5b0ad69SAbhishek Pandit-Subedi struct hci_cp_set_event_filter *cp; 486e5b0ad69SAbhishek Pandit-Subedi void *sent; 487e5b0ad69SAbhishek Pandit-Subedi 488e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 489e3f3a1aeSLuiz Augusto von Dentz 490e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 491c8992cffSLuiz Augusto von Dentz return rp->status; 492e5b0ad69SAbhishek Pandit-Subedi 493e5b0ad69SAbhishek Pandit-Subedi sent = hci_sent_cmd_data(hdev, HCI_OP_SET_EVENT_FLT); 494e5b0ad69SAbhishek Pandit-Subedi if (!sent) 495c8992cffSLuiz Augusto von Dentz return rp->status; 496e5b0ad69SAbhishek Pandit-Subedi 497e5b0ad69SAbhishek Pandit-Subedi cp = (struct hci_cp_set_event_filter *)sent; 498e5b0ad69SAbhishek Pandit-Subedi 499e5b0ad69SAbhishek Pandit-Subedi if (cp->flt_type == HCI_FLT_CLEAR_ALL) 500e5b0ad69SAbhishek Pandit-Subedi hci_dev_clear_flag(hdev, HCI_EVENT_FILTER_CONFIGURED); 501e5b0ad69SAbhishek Pandit-Subedi else 502e5b0ad69SAbhishek Pandit-Subedi hci_dev_set_flag(hdev, HCI_EVENT_FILTER_CONFIGURED); 503c8992cffSLuiz Augusto von Dentz 504c8992cffSLuiz Augusto von Dentz return rp->status; 505e5b0ad69SAbhishek Pandit-Subedi } 506e5b0ad69SAbhishek Pandit-Subedi 507c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_class_of_dev(struct hci_dev *hdev, void *data, 508c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 509a9de9248SMarcel Holtmann { 510c8992cffSLuiz Augusto von Dentz struct hci_rp_read_class_of_dev *rp = data; 511e3f3a1aeSLuiz Augusto von Dentz 512e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 513a9de9248SMarcel Holtmann 514a9de9248SMarcel Holtmann if (rp->status) 515c8992cffSLuiz Augusto von Dentz return rp->status; 516a9de9248SMarcel Holtmann 517a9de9248SMarcel Holtmann memcpy(hdev->dev_class, rp->dev_class, 3); 518a9de9248SMarcel Holtmann 519e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "class 0x%.2x%.2x%.2x", hdev->dev_class[2], 520e3f3a1aeSLuiz Augusto von Dentz hdev->dev_class[1], hdev->dev_class[0]); 521c8992cffSLuiz Augusto von Dentz 522c8992cffSLuiz Augusto von Dentz return rp->status; 523a9de9248SMarcel Holtmann } 524a9de9248SMarcel Holtmann 525c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_class_of_dev(struct hci_dev *hdev, void *data, 526c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 527a9de9248SMarcel Holtmann { 528c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 529a9de9248SMarcel Holtmann void *sent; 530a9de9248SMarcel Holtmann 531e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 532a9de9248SMarcel Holtmann 533a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV); 534a9de9248SMarcel Holtmann if (!sent) 535c8992cffSLuiz Augusto von Dentz return rp->status; 536a9de9248SMarcel Holtmann 5377f9a903cSMarcel Holtmann hci_dev_lock(hdev); 5387f9a903cSMarcel Holtmann 539e3f3a1aeSLuiz Augusto von Dentz if (!rp->status) 540a9de9248SMarcel Holtmann memcpy(hdev->dev_class, sent, 3); 5417f9a903cSMarcel Holtmann 542d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 543e3f3a1aeSLuiz Augusto von Dentz mgmt_set_class_of_dev_complete(hdev, sent, rp->status); 5447f9a903cSMarcel Holtmann 5457f9a903cSMarcel Holtmann hci_dev_unlock(hdev); 546c8992cffSLuiz Augusto von Dentz 547c8992cffSLuiz Augusto von Dentz return rp->status; 548a9de9248SMarcel Holtmann } 549a9de9248SMarcel Holtmann 550c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_voice_setting(struct hci_dev *hdev, void *data, 551c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 552a9de9248SMarcel Holtmann { 553c8992cffSLuiz Augusto von Dentz struct hci_rp_read_voice_setting *rp = data; 554a9de9248SMarcel Holtmann __u16 setting; 555a9de9248SMarcel Holtmann 556e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 557a9de9248SMarcel Holtmann 558a9de9248SMarcel Holtmann if (rp->status) 559c8992cffSLuiz Augusto von Dentz return rp->status; 560a9de9248SMarcel Holtmann 561a9de9248SMarcel Holtmann setting = __le16_to_cpu(rp->voice_setting); 562a9de9248SMarcel Holtmann 563a9de9248SMarcel Holtmann if (hdev->voice_setting == setting) 564c8992cffSLuiz Augusto von Dentz return rp->status; 565a9de9248SMarcel Holtmann 566a9de9248SMarcel Holtmann hdev->voice_setting = setting; 567a9de9248SMarcel Holtmann 568e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "voice setting 0x%4.4x", setting); 569a9de9248SMarcel Holtmann 5703c54711cSGustavo F. Padovan if (hdev->notify) 571a9de9248SMarcel Holtmann hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 572c8992cffSLuiz Augusto von Dentz 573c8992cffSLuiz Augusto von Dentz return rp->status; 574a9de9248SMarcel Holtmann } 575a9de9248SMarcel Holtmann 576c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_voice_setting(struct hci_dev *hdev, void *data, 5778fc9ced3SGustavo Padovan struct sk_buff *skb) 578a9de9248SMarcel Holtmann { 579c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 580f383f275SMarcel Holtmann __u16 setting; 581a9de9248SMarcel Holtmann void *sent; 582a9de9248SMarcel Holtmann 583e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 584e3f3a1aeSLuiz Augusto von Dentz 585e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 586c8992cffSLuiz Augusto von Dentz return rp->status; 587f383f275SMarcel Holtmann 588a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING); 589a9de9248SMarcel Holtmann if (!sent) 590c8992cffSLuiz Augusto von Dentz return rp->status; 591a9de9248SMarcel Holtmann 592f383f275SMarcel Holtmann setting = get_unaligned_le16(sent); 5931da177e4SLinus Torvalds 594f383f275SMarcel Holtmann if (hdev->voice_setting == setting) 595c8992cffSLuiz Augusto von Dentz return rp->status; 596f383f275SMarcel Holtmann 5971da177e4SLinus Torvalds hdev->voice_setting = setting; 5981da177e4SLinus Torvalds 599e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "voice setting 0x%4.4x", setting); 6001da177e4SLinus Torvalds 6013c54711cSGustavo F. Padovan if (hdev->notify) 6021da177e4SLinus Torvalds hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); 603c8992cffSLuiz Augusto von Dentz 604c8992cffSLuiz Augusto von Dentz return rp->status; 6051da177e4SLinus Torvalds } 6061da177e4SLinus Torvalds 607c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_num_supported_iac(struct hci_dev *hdev, void *data, 608b4cb9fb2SMarcel Holtmann struct sk_buff *skb) 609b4cb9fb2SMarcel Holtmann { 610c8992cffSLuiz Augusto von Dentz struct hci_rp_read_num_supported_iac *rp = data; 611e3f3a1aeSLuiz Augusto von Dentz 612e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 613b4cb9fb2SMarcel Holtmann 614b4cb9fb2SMarcel Holtmann if (rp->status) 615c8992cffSLuiz Augusto von Dentz return rp->status; 616b4cb9fb2SMarcel Holtmann 617b4cb9fb2SMarcel Holtmann hdev->num_iac = rp->num_iac; 618b4cb9fb2SMarcel Holtmann 619e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "num iac %d", hdev->num_iac); 620c8992cffSLuiz Augusto von Dentz 621c8992cffSLuiz Augusto von Dentz return rp->status; 622b4cb9fb2SMarcel Holtmann } 623b4cb9fb2SMarcel Holtmann 624c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_ssp_mode(struct hci_dev *hdev, void *data, 625c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 626333140b5SMarcel Holtmann { 627c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 6285ed8eb2fSJohan Hedberg struct hci_cp_write_ssp_mode *sent; 629333140b5SMarcel Holtmann 630e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 631333140b5SMarcel Holtmann 632333140b5SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); 633333140b5SMarcel Holtmann if (!sent) 634c8992cffSLuiz Augusto von Dentz return rp->status; 635333140b5SMarcel Holtmann 6365c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 6375c1a4c8fSJaganath Kanakkassery 638e3f3a1aeSLuiz Augusto von Dentz if (!rp->status) { 6395ed8eb2fSJohan Hedberg if (sent->mode) 640cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_SSP; 6415ed8eb2fSJohan Hedberg else 642cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_SSP; 6435ed8eb2fSJohan Hedberg } 6445ed8eb2fSJohan Hedberg 645e3f3a1aeSLuiz Augusto von Dentz if (!rp->status) { 6465ed8eb2fSJohan Hedberg if (sent->mode) 647a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SSP_ENABLED); 64884bde9d6SJohan Hedberg else 649a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_SSP_ENABLED); 650c0ecddc2SJohan Hedberg } 6515c1a4c8fSJaganath Kanakkassery 6525c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 653c8992cffSLuiz Augusto von Dentz 654c8992cffSLuiz Augusto von Dentz return rp->status; 655333140b5SMarcel Holtmann } 656333140b5SMarcel Holtmann 657c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_sc_support(struct hci_dev *hdev, void *data, 658c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 659eac83dc6SMarcel Holtmann { 660c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 661eac83dc6SMarcel Holtmann struct hci_cp_write_sc_support *sent; 662eac83dc6SMarcel Holtmann 663e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 664eac83dc6SMarcel Holtmann 665eac83dc6SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT); 666eac83dc6SMarcel Holtmann if (!sent) 667c8992cffSLuiz Augusto von Dentz return rp->status; 668eac83dc6SMarcel Holtmann 6695c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 6705c1a4c8fSJaganath Kanakkassery 671e3f3a1aeSLuiz Augusto von Dentz if (!rp->status) { 672eac83dc6SMarcel Holtmann if (sent->support) 673eac83dc6SMarcel Holtmann hdev->features[1][0] |= LMP_HOST_SC; 674eac83dc6SMarcel Holtmann else 675eac83dc6SMarcel Holtmann hdev->features[1][0] &= ~LMP_HOST_SC; 676eac83dc6SMarcel Holtmann } 677eac83dc6SMarcel Holtmann 678e3f3a1aeSLuiz Augusto von Dentz if (!hci_dev_test_flag(hdev, HCI_MGMT) && !rp->status) { 679eac83dc6SMarcel Holtmann if (sent->support) 680a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SC_ENABLED); 681eac83dc6SMarcel Holtmann else 682a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_SC_ENABLED); 683eac83dc6SMarcel Holtmann } 6845c1a4c8fSJaganath Kanakkassery 6855c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 686c8992cffSLuiz Augusto von Dentz 687c8992cffSLuiz Augusto von Dentz return rp->status; 688eac83dc6SMarcel Holtmann } 689eac83dc6SMarcel Holtmann 690c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_version(struct hci_dev *hdev, void *data, 691c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 692a9de9248SMarcel Holtmann { 693c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_version *rp = data; 694e3f3a1aeSLuiz Augusto von Dentz 695e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 6961143e5a6SMarcel Holtmann 697a9de9248SMarcel Holtmann if (rp->status) 698c8992cffSLuiz Augusto von Dentz return rp->status; 6991143e5a6SMarcel Holtmann 700d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 701d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) { 702a9de9248SMarcel Holtmann hdev->hci_ver = rp->hci_ver; 703e4e8e37cSMarcel Holtmann hdev->hci_rev = __le16_to_cpu(rp->hci_rev); 704d5859e22SJohan Hedberg hdev->lmp_ver = rp->lmp_ver; 705e4e8e37cSMarcel Holtmann hdev->manufacturer = __le16_to_cpu(rp->manufacturer); 706d5859e22SJohan Hedberg hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); 7070d5551f5SMarcel Holtmann } 708c8992cffSLuiz Augusto von Dentz 709c8992cffSLuiz Augusto von Dentz return rp->status; 710d5859e22SJohan Hedberg } 711d5859e22SJohan Hedberg 712c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_commands(struct hci_dev *hdev, void *data, 7138fc9ced3SGustavo Padovan struct sk_buff *skb) 714a9de9248SMarcel Holtmann { 715c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_commands *rp = data; 716e3f3a1aeSLuiz Augusto von Dentz 717e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 718a9de9248SMarcel Holtmann 7196a070e6eSMarcel Holtmann if (rp->status) 720c8992cffSLuiz Augusto von Dentz return rp->status; 7216a070e6eSMarcel Holtmann 722d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 723d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) 724a9de9248SMarcel Holtmann memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); 725c8992cffSLuiz Augusto von Dentz 726c8992cffSLuiz Augusto von Dentz return rp->status; 727a9de9248SMarcel Holtmann } 728a9de9248SMarcel Holtmann 729c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_auth_payload_timeout(struct hci_dev *hdev, void *data, 730302975cbSSpoorthi Ravishankar Koppad struct sk_buff *skb) 731302975cbSSpoorthi Ravishankar Koppad { 732c8992cffSLuiz Augusto von Dentz struct hci_rp_read_auth_payload_to *rp = data; 733302975cbSSpoorthi Ravishankar Koppad struct hci_conn *conn; 734302975cbSSpoorthi Ravishankar Koppad 735e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 736302975cbSSpoorthi Ravishankar Koppad 737302975cbSSpoorthi Ravishankar Koppad if (rp->status) 738c8992cffSLuiz Augusto von Dentz return rp->status; 739302975cbSSpoorthi Ravishankar Koppad 740302975cbSSpoorthi Ravishankar Koppad hci_dev_lock(hdev); 741302975cbSSpoorthi Ravishankar Koppad 742302975cbSSpoorthi Ravishankar Koppad conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 743302975cbSSpoorthi Ravishankar Koppad if (conn) 744302975cbSSpoorthi Ravishankar Koppad conn->auth_payload_timeout = __le16_to_cpu(rp->timeout); 745302975cbSSpoorthi Ravishankar Koppad 746302975cbSSpoorthi Ravishankar Koppad hci_dev_unlock(hdev); 747c8992cffSLuiz Augusto von Dentz 748c8992cffSLuiz Augusto von Dentz return rp->status; 749302975cbSSpoorthi Ravishankar Koppad } 750302975cbSSpoorthi Ravishankar Koppad 751c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_auth_payload_timeout(struct hci_dev *hdev, void *data, 752302975cbSSpoorthi Ravishankar Koppad struct sk_buff *skb) 753302975cbSSpoorthi Ravishankar Koppad { 754c8992cffSLuiz Augusto von Dentz struct hci_rp_write_auth_payload_to *rp = data; 755302975cbSSpoorthi Ravishankar Koppad struct hci_conn *conn; 756302975cbSSpoorthi Ravishankar Koppad void *sent; 757302975cbSSpoorthi Ravishankar Koppad 758e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 759302975cbSSpoorthi Ravishankar Koppad 760302975cbSSpoorthi Ravishankar Koppad if (rp->status) 761c8992cffSLuiz Augusto von Dentz return rp->status; 762302975cbSSpoorthi Ravishankar Koppad 763302975cbSSpoorthi Ravishankar Koppad sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO); 764302975cbSSpoorthi Ravishankar Koppad if (!sent) 765c8992cffSLuiz Augusto von Dentz return rp->status; 766302975cbSSpoorthi Ravishankar Koppad 767302975cbSSpoorthi Ravishankar Koppad hci_dev_lock(hdev); 768302975cbSSpoorthi Ravishankar Koppad 769302975cbSSpoorthi Ravishankar Koppad conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 770302975cbSSpoorthi Ravishankar Koppad if (conn) 771302975cbSSpoorthi Ravishankar Koppad conn->auth_payload_timeout = get_unaligned_le16(sent + 2); 772302975cbSSpoorthi Ravishankar Koppad 773302975cbSSpoorthi Ravishankar Koppad hci_dev_unlock(hdev); 774c8992cffSLuiz Augusto von Dentz 775c8992cffSLuiz Augusto von Dentz return rp->status; 776302975cbSSpoorthi Ravishankar Koppad } 777302975cbSSpoorthi Ravishankar Koppad 778c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_features(struct hci_dev *hdev, void *data, 7798fc9ced3SGustavo Padovan struct sk_buff *skb) 780a9de9248SMarcel Holtmann { 781c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_features *rp = data; 782e3f3a1aeSLuiz Augusto von Dentz 783e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 784a9de9248SMarcel Holtmann 785a9de9248SMarcel Holtmann if (rp->status) 786c8992cffSLuiz Augusto von Dentz return rp->status; 787a9de9248SMarcel Holtmann 788a9de9248SMarcel Holtmann memcpy(hdev->features, rp->features, 8); 7891da177e4SLinus Torvalds 7901da177e4SLinus Torvalds /* Adjust default settings according to features 7911da177e4SLinus Torvalds * supported by device. */ 792a9de9248SMarcel Holtmann 793cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_3SLOT) 7941da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM3 | HCI_DH3); 7951da177e4SLinus Torvalds 796cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_5SLOT) 7971da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM5 | HCI_DH5); 7981da177e4SLinus Torvalds 799cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV2) { 8001da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV2); 8015b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV2); 8025b7f9909SMarcel Holtmann } 8031da177e4SLinus Torvalds 804cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV3) { 8051da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV3); 8065b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV3); 8075b7f9909SMarcel Holtmann } 8085b7f9909SMarcel Holtmann 80945db810fSAndre Guedes if (lmp_esco_capable(hdev)) 8105b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV3); 8115b7f9909SMarcel Holtmann 812cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV4) 8135b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV4); 8145b7f9909SMarcel Holtmann 815cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV5) 8165b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV5); 8171da177e4SLinus Torvalds 818cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_2M) 819efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV3); 820efc7688bSMarcel Holtmann 821cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_3M) 822efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_3EV3); 823efc7688bSMarcel Holtmann 824cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_3S_ESCO) 825efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); 826c8992cffSLuiz Augusto von Dentz 827c8992cffSLuiz Augusto von Dentz return rp->status; 8281da177e4SLinus Torvalds } 8291da177e4SLinus Torvalds 830c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_ext_features(struct hci_dev *hdev, void *data, 831971e3a4bSAndre Guedes struct sk_buff *skb) 832971e3a4bSAndre Guedes { 833c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_ext_features *rp = data; 834e3f3a1aeSLuiz Augusto von Dentz 835e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 836971e3a4bSAndre Guedes 837971e3a4bSAndre Guedes if (rp->status) 838c8992cffSLuiz Augusto von Dentz return rp->status; 839971e3a4bSAndre Guedes 84057af75a8SMarcel Holtmann if (hdev->max_page < rp->max_page) 841d2c5d77fSJohan Hedberg hdev->max_page = rp->max_page; 842d2c5d77fSJohan Hedberg 843cad718edSJohan Hedberg if (rp->page < HCI_MAX_PAGES) 844cad718edSJohan Hedberg memcpy(hdev->features[rp->page], rp->features, 8); 845c8992cffSLuiz Augusto von Dentz 846c8992cffSLuiz Augusto von Dentz return rp->status; 847971e3a4bSAndre Guedes } 848971e3a4bSAndre Guedes 849c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_flow_control_mode(struct hci_dev *hdev, void *data, 8501e89cffbSAndrei Emeltchenko struct sk_buff *skb) 8511e89cffbSAndrei Emeltchenko { 852c8992cffSLuiz Augusto von Dentz struct hci_rp_read_flow_control_mode *rp = data; 853e3f3a1aeSLuiz Augusto von Dentz 854e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 8551e89cffbSAndrei Emeltchenko 85645296acdSMarcel Holtmann if (rp->status) 857c8992cffSLuiz Augusto von Dentz return rp->status; 85845296acdSMarcel Holtmann 8591e89cffbSAndrei Emeltchenko hdev->flow_ctl_mode = rp->mode; 860c8992cffSLuiz Augusto von Dentz 861c8992cffSLuiz Augusto von Dentz return rp->status; 8621e89cffbSAndrei Emeltchenko } 8631e89cffbSAndrei Emeltchenko 864c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_buffer_size(struct hci_dev *hdev, void *data, 865c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 866a9de9248SMarcel Holtmann { 867c8992cffSLuiz Augusto von Dentz struct hci_rp_read_buffer_size *rp = data; 868e3f3a1aeSLuiz Augusto von Dentz 869e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 870a9de9248SMarcel Holtmann 871a9de9248SMarcel Holtmann if (rp->status) 872c8992cffSLuiz Augusto von Dentz return rp->status; 873a9de9248SMarcel Holtmann 874a9de9248SMarcel Holtmann hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu); 875a9de9248SMarcel Holtmann hdev->sco_mtu = rp->sco_mtu; 876a9de9248SMarcel Holtmann hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt); 877a9de9248SMarcel Holtmann hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt); 878da1f5198SMarcel Holtmann 879da1f5198SMarcel Holtmann if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) { 880da1f5198SMarcel Holtmann hdev->sco_mtu = 64; 881da1f5198SMarcel Holtmann hdev->sco_pkts = 8; 882da1f5198SMarcel Holtmann } 883da1f5198SMarcel Holtmann 884da1f5198SMarcel Holtmann hdev->acl_cnt = hdev->acl_pkts; 885da1f5198SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 8861da177e4SLinus Torvalds 887807deac2SGustavo Padovan BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu, 888807deac2SGustavo Padovan hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts); 889c8992cffSLuiz Augusto von Dentz 890c8992cffSLuiz Augusto von Dentz return rp->status; 8911da177e4SLinus Torvalds } 8921da177e4SLinus Torvalds 893c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_bd_addr(struct hci_dev *hdev, void *data, 894c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 895a9de9248SMarcel Holtmann { 896c8992cffSLuiz Augusto von Dentz struct hci_rp_read_bd_addr *rp = data; 897e3f3a1aeSLuiz Augusto von Dentz 898e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 899a9de9248SMarcel Holtmann 900e30d3f5fSMarcel Holtmann if (rp->status) 901c8992cffSLuiz Augusto von Dentz return rp->status; 902e30d3f5fSMarcel Holtmann 903e30d3f5fSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) 904a9de9248SMarcel Holtmann bacpy(&hdev->bdaddr, &rp->bdaddr); 905e30d3f5fSMarcel Holtmann 906d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP)) 907e30d3f5fSMarcel Holtmann bacpy(&hdev->setup_addr, &rp->bdaddr); 908c8992cffSLuiz Augusto von Dentz 909c8992cffSLuiz Augusto von Dentz return rp->status; 91023bb5763SJohan Hedberg } 91123bb5763SJohan Hedberg 912c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_pairing_opts(struct hci_dev *hdev, void *data, 913a4790360SMarcel Holtmann struct sk_buff *skb) 914a4790360SMarcel Holtmann { 915c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_pairing_opts *rp = data; 916e3f3a1aeSLuiz Augusto von Dentz 917e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 918a4790360SMarcel Holtmann 919a4790360SMarcel Holtmann if (rp->status) 920c8992cffSLuiz Augusto von Dentz return rp->status; 921a4790360SMarcel Holtmann 922a4790360SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) || 923a4790360SMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) { 924a4790360SMarcel Holtmann hdev->pairing_opts = rp->pairing_opts; 925a4790360SMarcel Holtmann hdev->max_enc_key_size = rp->max_key_size; 926a4790360SMarcel Holtmann } 927c8992cffSLuiz Augusto von Dentz 928c8992cffSLuiz Augusto von Dentz return rp->status; 929a4790360SMarcel Holtmann } 930a4790360SMarcel Holtmann 931c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_page_scan_activity(struct hci_dev *hdev, void *data, 932f332ec66SJohan Hedberg struct sk_buff *skb) 933f332ec66SJohan Hedberg { 934c8992cffSLuiz Augusto von Dentz struct hci_rp_read_page_scan_activity *rp = data; 935e3f3a1aeSLuiz Augusto von Dentz 936e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 937f332ec66SJohan Hedberg 93845296acdSMarcel Holtmann if (rp->status) 939c8992cffSLuiz Augusto von Dentz return rp->status; 94045296acdSMarcel Holtmann 94145296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) { 942f332ec66SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(rp->interval); 943f332ec66SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(rp->window); 944f332ec66SJohan Hedberg } 945c8992cffSLuiz Augusto von Dentz 946c8992cffSLuiz Augusto von Dentz return rp->status; 947f332ec66SJohan Hedberg } 948f332ec66SJohan Hedberg 949c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_page_scan_activity(struct hci_dev *hdev, void *data, 9504a3ee763SJohan Hedberg struct sk_buff *skb) 9514a3ee763SJohan Hedberg { 952c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 9534a3ee763SJohan Hedberg struct hci_cp_write_page_scan_activity *sent; 9544a3ee763SJohan Hedberg 955e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 956e3f3a1aeSLuiz Augusto von Dentz 957e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 958c8992cffSLuiz Augusto von Dentz return rp->status; 9594a3ee763SJohan Hedberg 9604a3ee763SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY); 9614a3ee763SJohan Hedberg if (!sent) 962c8992cffSLuiz Augusto von Dentz return rp->status; 9634a3ee763SJohan Hedberg 9644a3ee763SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(sent->interval); 9654a3ee763SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(sent->window); 966c8992cffSLuiz Augusto von Dentz 967c8992cffSLuiz Augusto von Dentz return rp->status; 9684a3ee763SJohan Hedberg } 9694a3ee763SJohan Hedberg 970c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_page_scan_type(struct hci_dev *hdev, void *data, 971f332ec66SJohan Hedberg struct sk_buff *skb) 972f332ec66SJohan Hedberg { 973c8992cffSLuiz Augusto von Dentz struct hci_rp_read_page_scan_type *rp = data; 974e3f3a1aeSLuiz Augusto von Dentz 975e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 976f332ec66SJohan Hedberg 97745296acdSMarcel Holtmann if (rp->status) 978c8992cffSLuiz Augusto von Dentz return rp->status; 97945296acdSMarcel Holtmann 98045296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) 981f332ec66SJohan Hedberg hdev->page_scan_type = rp->type; 982c8992cffSLuiz Augusto von Dentz 983c8992cffSLuiz Augusto von Dentz return rp->status; 984f332ec66SJohan Hedberg } 985f332ec66SJohan Hedberg 986c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_page_scan_type(struct hci_dev *hdev, void *data, 9874a3ee763SJohan Hedberg struct sk_buff *skb) 9884a3ee763SJohan Hedberg { 989c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 9904a3ee763SJohan Hedberg u8 *type; 9914a3ee763SJohan Hedberg 992e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 993e3f3a1aeSLuiz Augusto von Dentz 994e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 995c8992cffSLuiz Augusto von Dentz return rp->status; 9964a3ee763SJohan Hedberg 9974a3ee763SJohan Hedberg type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE); 9984a3ee763SJohan Hedberg if (type) 9994a3ee763SJohan Hedberg hdev->page_scan_type = *type; 1000c8992cffSLuiz Augusto von Dentz 1001c8992cffSLuiz Augusto von Dentz return rp->status; 10024a3ee763SJohan Hedberg } 10034a3ee763SJohan Hedberg 1004c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_data_block_size(struct hci_dev *hdev, void *data, 1005350ee4cfSAndrei Emeltchenko struct sk_buff *skb) 1006350ee4cfSAndrei Emeltchenko { 1007c8992cffSLuiz Augusto von Dentz struct hci_rp_read_data_block_size *rp = data; 1008e3f3a1aeSLuiz Augusto von Dentz 1009e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1010350ee4cfSAndrei Emeltchenko 1011350ee4cfSAndrei Emeltchenko if (rp->status) 1012c8992cffSLuiz Augusto von Dentz return rp->status; 1013350ee4cfSAndrei Emeltchenko 1014350ee4cfSAndrei Emeltchenko hdev->block_mtu = __le16_to_cpu(rp->max_acl_len); 1015350ee4cfSAndrei Emeltchenko hdev->block_len = __le16_to_cpu(rp->block_len); 1016350ee4cfSAndrei Emeltchenko hdev->num_blocks = __le16_to_cpu(rp->num_blocks); 1017350ee4cfSAndrei Emeltchenko 1018350ee4cfSAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 1019350ee4cfSAndrei Emeltchenko 1020350ee4cfSAndrei Emeltchenko BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu, 1021350ee4cfSAndrei Emeltchenko hdev->block_cnt, hdev->block_len); 1022c8992cffSLuiz Augusto von Dentz 1023c8992cffSLuiz Augusto von Dentz return rp->status; 1024350ee4cfSAndrei Emeltchenko } 1025350ee4cfSAndrei Emeltchenko 1026c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_clock(struct hci_dev *hdev, void *data, 1027c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 102833f35721SJohan Hedberg { 1029c8992cffSLuiz Augusto von Dentz struct hci_rp_read_clock *rp = data; 103033f35721SJohan Hedberg struct hci_cp_read_clock *cp; 103133f35721SJohan Hedberg struct hci_conn *conn; 103233f35721SJohan Hedberg 1033e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1034e3f3a1aeSLuiz Augusto von Dentz 103533f35721SJohan Hedberg if (rp->status) 1036c8992cffSLuiz Augusto von Dentz return rp->status; 103733f35721SJohan Hedberg 103833f35721SJohan Hedberg hci_dev_lock(hdev); 103933f35721SJohan Hedberg 104033f35721SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK); 104133f35721SJohan Hedberg if (!cp) 104233f35721SJohan Hedberg goto unlock; 104333f35721SJohan Hedberg 104433f35721SJohan Hedberg if (cp->which == 0x00) { 104533f35721SJohan Hedberg hdev->clock = le32_to_cpu(rp->clock); 104633f35721SJohan Hedberg goto unlock; 104733f35721SJohan Hedberg } 104833f35721SJohan Hedberg 104933f35721SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 105033f35721SJohan Hedberg if (conn) { 105133f35721SJohan Hedberg conn->clock = le32_to_cpu(rp->clock); 105233f35721SJohan Hedberg conn->clock_accuracy = le16_to_cpu(rp->accuracy); 105333f35721SJohan Hedberg } 105433f35721SJohan Hedberg 105533f35721SJohan Hedberg unlock: 105633f35721SJohan Hedberg hci_dev_unlock(hdev); 1057c8992cffSLuiz Augusto von Dentz return rp->status; 105833f35721SJohan Hedberg } 105933f35721SJohan Hedberg 1060c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_amp_info(struct hci_dev *hdev, void *data, 1061928abaa7SAndrei Emeltchenko struct sk_buff *skb) 1062928abaa7SAndrei Emeltchenko { 1063c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_amp_info *rp = data; 1064e3f3a1aeSLuiz Augusto von Dentz 1065e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1066928abaa7SAndrei Emeltchenko 1067928abaa7SAndrei Emeltchenko if (rp->status) 1068c8992cffSLuiz Augusto von Dentz return rp->status; 1069928abaa7SAndrei Emeltchenko 1070928abaa7SAndrei Emeltchenko hdev->amp_status = rp->amp_status; 1071928abaa7SAndrei Emeltchenko hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); 1072928abaa7SAndrei Emeltchenko hdev->amp_max_bw = __le32_to_cpu(rp->max_bw); 1073928abaa7SAndrei Emeltchenko hdev->amp_min_latency = __le32_to_cpu(rp->min_latency); 1074928abaa7SAndrei Emeltchenko hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu); 1075928abaa7SAndrei Emeltchenko hdev->amp_type = rp->amp_type; 1076928abaa7SAndrei Emeltchenko hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap); 1077928abaa7SAndrei Emeltchenko hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size); 1078928abaa7SAndrei Emeltchenko hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to); 1079928abaa7SAndrei Emeltchenko hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); 1080c8992cffSLuiz Augusto von Dentz 1081c8992cffSLuiz Augusto von Dentz return rp->status; 1082928abaa7SAndrei Emeltchenko } 1083928abaa7SAndrei Emeltchenko 1084c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, void *data, 1085d5859e22SJohan Hedberg struct sk_buff *skb) 1086d5859e22SJohan Hedberg { 1087c8992cffSLuiz Augusto von Dentz struct hci_rp_read_inq_rsp_tx_power *rp = data; 1088e3f3a1aeSLuiz Augusto von Dentz 1089e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1090d5859e22SJohan Hedberg 109145296acdSMarcel Holtmann if (rp->status) 1092c8992cffSLuiz Augusto von Dentz return rp->status; 109345296acdSMarcel Holtmann 109491c4e9b1SMarcel Holtmann hdev->inq_tx_power = rp->tx_power; 1095c8992cffSLuiz Augusto von Dentz 1096c8992cffSLuiz Augusto von Dentz return rp->status; 1097d5859e22SJohan Hedberg } 1098d5859e22SJohan Hedberg 1099c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_def_err_data_reporting(struct hci_dev *hdev, void *data, 110000bce3fbSAlain Michaud struct sk_buff *skb) 110100bce3fbSAlain Michaud { 1102c8992cffSLuiz Augusto von Dentz struct hci_rp_read_def_err_data_reporting *rp = data; 1103e3f3a1aeSLuiz Augusto von Dentz 1104e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 110500bce3fbSAlain Michaud 110600bce3fbSAlain Michaud if (rp->status) 1107c8992cffSLuiz Augusto von Dentz return rp->status; 110800bce3fbSAlain Michaud 110900bce3fbSAlain Michaud hdev->err_data_reporting = rp->err_data_reporting; 1110c8992cffSLuiz Augusto von Dentz 1111c8992cffSLuiz Augusto von Dentz return rp->status; 111200bce3fbSAlain Michaud } 111300bce3fbSAlain Michaud 1114c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_def_err_data_reporting(struct hci_dev *hdev, void *data, 111500bce3fbSAlain Michaud struct sk_buff *skb) 111600bce3fbSAlain Michaud { 1117c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 111800bce3fbSAlain Michaud struct hci_cp_write_def_err_data_reporting *cp; 111900bce3fbSAlain Michaud 1120e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1121e3f3a1aeSLuiz Augusto von Dentz 1122e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1123c8992cffSLuiz Augusto von Dentz return rp->status; 112400bce3fbSAlain Michaud 112500bce3fbSAlain Michaud cp = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING); 112600bce3fbSAlain Michaud if (!cp) 1127c8992cffSLuiz Augusto von Dentz return rp->status; 112800bce3fbSAlain Michaud 112900bce3fbSAlain Michaud hdev->err_data_reporting = cp->err_data_reporting; 1130c8992cffSLuiz Augusto von Dentz 1131c8992cffSLuiz Augusto von Dentz return rp->status; 113200bce3fbSAlain Michaud } 113300bce3fbSAlain Michaud 1134c8992cffSLuiz Augusto von Dentz static u8 hci_cc_pin_code_reply(struct hci_dev *hdev, void *data, 1135c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1136980e1a53SJohan Hedberg { 1137c8992cffSLuiz Augusto von Dentz struct hci_rp_pin_code_reply *rp = data; 1138980e1a53SJohan Hedberg struct hci_cp_pin_code_reply *cp; 1139980e1a53SJohan Hedberg struct hci_conn *conn; 1140980e1a53SJohan Hedberg 1141e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1142980e1a53SJohan Hedberg 114356e5cb86SJohan Hedberg hci_dev_lock(hdev); 114456e5cb86SJohan Hedberg 1145d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 1146744cf19eSJohan Hedberg mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); 1147980e1a53SJohan Hedberg 1148fa1bd918SMikel Astiz if (rp->status) 114956e5cb86SJohan Hedberg goto unlock; 1150980e1a53SJohan Hedberg 1151980e1a53SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); 1152980e1a53SJohan Hedberg if (!cp) 115356e5cb86SJohan Hedberg goto unlock; 1154980e1a53SJohan Hedberg 1155980e1a53SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 1156980e1a53SJohan Hedberg if (conn) 1157980e1a53SJohan Hedberg conn->pin_length = cp->pin_len; 115856e5cb86SJohan Hedberg 115956e5cb86SJohan Hedberg unlock: 116056e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1161c8992cffSLuiz Augusto von Dentz return rp->status; 1162980e1a53SJohan Hedberg } 1163980e1a53SJohan Hedberg 1164c8992cffSLuiz Augusto von Dentz static u8 hci_cc_pin_code_neg_reply(struct hci_dev *hdev, void *data, 1165c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1166980e1a53SJohan Hedberg { 1167c8992cffSLuiz Augusto von Dentz struct hci_rp_pin_code_neg_reply *rp = data; 1168e3f3a1aeSLuiz Augusto von Dentz 1169e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1170980e1a53SJohan Hedberg 117156e5cb86SJohan Hedberg hci_dev_lock(hdev); 117256e5cb86SJohan Hedberg 1173d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 1174744cf19eSJohan Hedberg mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, 1175980e1a53SJohan Hedberg rp->status); 117656e5cb86SJohan Hedberg 117756e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1178c8992cffSLuiz Augusto von Dentz 1179c8992cffSLuiz Augusto von Dentz return rp->status; 1180980e1a53SJohan Hedberg } 118156e5cb86SJohan Hedberg 1182c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_buffer_size(struct hci_dev *hdev, void *data, 11836ed58ec5SVille Tervo struct sk_buff *skb) 11846ed58ec5SVille Tervo { 1185c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_buffer_size *rp = data; 1186e3f3a1aeSLuiz Augusto von Dentz 1187e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 11886ed58ec5SVille Tervo 11896ed58ec5SVille Tervo if (rp->status) 1190c8992cffSLuiz Augusto von Dentz return rp->status; 11916ed58ec5SVille Tervo 11926ed58ec5SVille Tervo hdev->le_mtu = __le16_to_cpu(rp->le_mtu); 11936ed58ec5SVille Tervo hdev->le_pkts = rp->le_max_pkt; 11946ed58ec5SVille Tervo 11956ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 11966ed58ec5SVille Tervo 11976ed58ec5SVille Tervo BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts); 1198c8992cffSLuiz Augusto von Dentz 1199c8992cffSLuiz Augusto von Dentz return rp->status; 12006ed58ec5SVille Tervo } 1201980e1a53SJohan Hedberg 1202c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_local_features(struct hci_dev *hdev, void *data, 120360e77321SJohan Hedberg struct sk_buff *skb) 120460e77321SJohan Hedberg { 1205c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_local_features *rp = data; 120660e77321SJohan Hedberg 120760e77321SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 120860e77321SJohan Hedberg 120945296acdSMarcel Holtmann if (rp->status) 1210c8992cffSLuiz Augusto von Dentz return rp->status; 121145296acdSMarcel Holtmann 121260e77321SJohan Hedberg memcpy(hdev->le_features, rp->features, 8); 1213c8992cffSLuiz Augusto von Dentz 1214c8992cffSLuiz Augusto von Dentz return rp->status; 121560e77321SJohan Hedberg } 121660e77321SJohan Hedberg 1217c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, void *data, 12188fa19098SJohan Hedberg struct sk_buff *skb) 12198fa19098SJohan Hedberg { 1220c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_adv_tx_power *rp = data; 1221e3f3a1aeSLuiz Augusto von Dentz 1222e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 12238fa19098SJohan Hedberg 122445296acdSMarcel Holtmann if (rp->status) 1225c8992cffSLuiz Augusto von Dentz return rp->status; 122645296acdSMarcel Holtmann 12278fa19098SJohan Hedberg hdev->adv_tx_power = rp->tx_power; 1228c8992cffSLuiz Augusto von Dentz 1229c8992cffSLuiz Augusto von Dentz return rp->status; 12308fa19098SJohan Hedberg } 12318fa19098SJohan Hedberg 1232c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_confirm_reply(struct hci_dev *hdev, void *data, 1233c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1234a5c29683SJohan Hedberg { 1235c8992cffSLuiz Augusto von Dentz struct hci_rp_user_confirm_reply *rp = data; 1236e3f3a1aeSLuiz Augusto von Dentz 1237e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1238a5c29683SJohan Hedberg 123956e5cb86SJohan Hedberg hci_dev_lock(hdev); 124056e5cb86SJohan Hedberg 1241d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 124204124681SGustavo F. Padovan mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0, 124304124681SGustavo F. Padovan rp->status); 124456e5cb86SJohan Hedberg 124556e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1246c8992cffSLuiz Augusto von Dentz 1247c8992cffSLuiz Augusto von Dentz return rp->status; 1248a5c29683SJohan Hedberg } 1249a5c29683SJohan Hedberg 1250c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, void *data, 1251a5c29683SJohan Hedberg struct sk_buff *skb) 1252a5c29683SJohan Hedberg { 1253c8992cffSLuiz Augusto von Dentz struct hci_rp_user_confirm_reply *rp = data; 1254e3f3a1aeSLuiz Augusto von Dentz 1255e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1256a5c29683SJohan Hedberg 125756e5cb86SJohan Hedberg hci_dev_lock(hdev); 125856e5cb86SJohan Hedberg 1259d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 1260744cf19eSJohan Hedberg mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, 126104124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 126256e5cb86SJohan Hedberg 126356e5cb86SJohan Hedberg hci_dev_unlock(hdev); 1264c8992cffSLuiz Augusto von Dentz 1265c8992cffSLuiz Augusto von Dentz return rp->status; 1266a5c29683SJohan Hedberg } 1267a5c29683SJohan Hedberg 1268c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_passkey_reply(struct hci_dev *hdev, void *data, 1269c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 12701143d458SBrian Gix { 1271c8992cffSLuiz Augusto von Dentz struct hci_rp_user_confirm_reply *rp = data; 1272e3f3a1aeSLuiz Augusto von Dentz 1273e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 12741143d458SBrian Gix 12751143d458SBrian Gix hci_dev_lock(hdev); 12761143d458SBrian Gix 1277d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 1278272d90dfSJohan Hedberg mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 1279272d90dfSJohan Hedberg 0, rp->status); 12801143d458SBrian Gix 12811143d458SBrian Gix hci_dev_unlock(hdev); 1282c8992cffSLuiz Augusto von Dentz 1283c8992cffSLuiz Augusto von Dentz return rp->status; 12841143d458SBrian Gix } 12851143d458SBrian Gix 1286c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, void *data, 12871143d458SBrian Gix struct sk_buff *skb) 12881143d458SBrian Gix { 1289c8992cffSLuiz Augusto von Dentz struct hci_rp_user_confirm_reply *rp = data; 1290e3f3a1aeSLuiz Augusto von Dentz 1291e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 12921143d458SBrian Gix 12931143d458SBrian Gix hci_dev_lock(hdev); 12941143d458SBrian Gix 1295d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 12961143d458SBrian Gix mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr, 129704124681SGustavo F. Padovan ACL_LINK, 0, rp->status); 12981143d458SBrian Gix 12991143d458SBrian Gix hci_dev_unlock(hdev); 1300c8992cffSLuiz Augusto von Dentz 1301c8992cffSLuiz Augusto von Dentz return rp->status; 13021143d458SBrian Gix } 13031143d458SBrian Gix 1304c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_oob_data(struct hci_dev *hdev, void *data, 1305c35938b2SSzymon Janc struct sk_buff *skb) 1306c35938b2SSzymon Janc { 1307c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_oob_data *rp = data; 1308e3f3a1aeSLuiz Augusto von Dentz 1309e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1310c8992cffSLuiz Augusto von Dentz 1311c8992cffSLuiz Augusto von Dentz return rp->status; 13124d2d2796SMarcel Holtmann } 13134d2d2796SMarcel Holtmann 1314c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, void *data, 13154d2d2796SMarcel Holtmann struct sk_buff *skb) 13164d2d2796SMarcel Holtmann { 1317c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_oob_ext_data *rp = data; 1318e3f3a1aeSLuiz Augusto von Dentz 1319e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1320c8992cffSLuiz Augusto von Dentz 1321c8992cffSLuiz Augusto von Dentz return rp->status; 1322c35938b2SSzymon Janc } 1323c35938b2SSzymon Janc 1324c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_random_addr(struct hci_dev *hdev, void *data, 1325c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 13267a4cd51dSMarcel Holtmann { 1327c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 13287a4cd51dSMarcel Holtmann bdaddr_t *sent; 13297a4cd51dSMarcel Holtmann 1330e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1331e3f3a1aeSLuiz Augusto von Dentz 1332e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1333c8992cffSLuiz Augusto von Dentz return rp->status; 133445296acdSMarcel Holtmann 13357a4cd51dSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR); 13367a4cd51dSMarcel Holtmann if (!sent) 1337c8992cffSLuiz Augusto von Dentz return rp->status; 13387a4cd51dSMarcel Holtmann 13397a4cd51dSMarcel Holtmann hci_dev_lock(hdev); 13407a4cd51dSMarcel Holtmann 13417a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, sent); 13427a4cd51dSMarcel Holtmann 1343c45074d6SLuiz Augusto von Dentz if (!bacmp(&hdev->rpa, sent)) { 1344c45074d6SLuiz Augusto von Dentz hci_dev_clear_flag(hdev, HCI_RPA_EXPIRED); 1345c45074d6SLuiz Augusto von Dentz queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, 1346c45074d6SLuiz Augusto von Dentz secs_to_jiffies(hdev->rpa_timeout)); 1347c45074d6SLuiz Augusto von Dentz } 1348c45074d6SLuiz Augusto von Dentz 13497a4cd51dSMarcel Holtmann hci_dev_unlock(hdev); 1350c8992cffSLuiz Augusto von Dentz 1351c8992cffSLuiz Augusto von Dentz return rp->status; 13527a4cd51dSMarcel Holtmann } 13537a4cd51dSMarcel Holtmann 1354c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_default_phy(struct hci_dev *hdev, void *data, 1355c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 13560314f286SJaganath Kanakkassery { 1357c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 13580314f286SJaganath Kanakkassery struct hci_cp_le_set_default_phy *cp; 13590314f286SJaganath Kanakkassery 1360e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1361e3f3a1aeSLuiz Augusto von Dentz 1362e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1363c8992cffSLuiz Augusto von Dentz return rp->status; 13640314f286SJaganath Kanakkassery 13650314f286SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_DEFAULT_PHY); 13660314f286SJaganath Kanakkassery if (!cp) 1367c8992cffSLuiz Augusto von Dentz return rp->status; 13680314f286SJaganath Kanakkassery 13690314f286SJaganath Kanakkassery hci_dev_lock(hdev); 13700314f286SJaganath Kanakkassery 13710314f286SJaganath Kanakkassery hdev->le_tx_def_phys = cp->tx_phys; 13720314f286SJaganath Kanakkassery hdev->le_rx_def_phys = cp->rx_phys; 13730314f286SJaganath Kanakkassery 13740314f286SJaganath Kanakkassery hci_dev_unlock(hdev); 1375c8992cffSLuiz Augusto von Dentz 1376c8992cffSLuiz Augusto von Dentz return rp->status; 13770314f286SJaganath Kanakkassery } 13780314f286SJaganath Kanakkassery 1379c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_adv_set_random_addr(struct hci_dev *hdev, void *data, 1380a73c046aSJaganath Kanakkassery struct sk_buff *skb) 1381a73c046aSJaganath Kanakkassery { 1382c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1383a73c046aSJaganath Kanakkassery struct hci_cp_le_set_adv_set_rand_addr *cp; 1384c45074d6SLuiz Augusto von Dentz struct adv_info *adv; 1385a73c046aSJaganath Kanakkassery 1386e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1387e3f3a1aeSLuiz Augusto von Dentz 1388e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1389c8992cffSLuiz Augusto von Dentz return rp->status; 1390a73c046aSJaganath Kanakkassery 1391a73c046aSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR); 1392c45074d6SLuiz Augusto von Dentz /* Update only in case the adv instance since handle 0x00 shall be using 1393c45074d6SLuiz Augusto von Dentz * HCI_OP_LE_SET_RANDOM_ADDR since that allows both extended and 1394c45074d6SLuiz Augusto von Dentz * non-extended adverting. 1395c45074d6SLuiz Augusto von Dentz */ 1396c45074d6SLuiz Augusto von Dentz if (!cp || !cp->handle) 1397c8992cffSLuiz Augusto von Dentz return rp->status; 1398a73c046aSJaganath Kanakkassery 1399a73c046aSJaganath Kanakkassery hci_dev_lock(hdev); 1400a73c046aSJaganath Kanakkassery 1401c45074d6SLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, cp->handle); 1402c45074d6SLuiz Augusto von Dentz if (adv) { 1403c45074d6SLuiz Augusto von Dentz bacpy(&adv->random_addr, &cp->bdaddr); 1404c45074d6SLuiz Augusto von Dentz if (!bacmp(&hdev->rpa, &cp->bdaddr)) { 1405c45074d6SLuiz Augusto von Dentz adv->rpa_expired = false; 1406c45074d6SLuiz Augusto von Dentz queue_delayed_work(hdev->workqueue, 1407c45074d6SLuiz Augusto von Dentz &adv->rpa_expired_cb, 1408c45074d6SLuiz Augusto von Dentz secs_to_jiffies(hdev->rpa_timeout)); 1409c45074d6SLuiz Augusto von Dentz } 1410a73c046aSJaganath Kanakkassery } 1411a73c046aSJaganath Kanakkassery 1412a73c046aSJaganath Kanakkassery hci_dev_unlock(hdev); 1413c8992cffSLuiz Augusto von Dentz 1414c8992cffSLuiz Augusto von Dentz return rp->status; 1415a73c046aSJaganath Kanakkassery } 1416a73c046aSJaganath Kanakkassery 1417c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_remove_adv_set(struct hci_dev *hdev, void *data, 1418c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1419cba6b758SLuiz Augusto von Dentz { 1420c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1421cba6b758SLuiz Augusto von Dentz u8 *instance; 1422cba6b758SLuiz Augusto von Dentz int err; 1423cba6b758SLuiz Augusto von Dentz 1424e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1425e3f3a1aeSLuiz Augusto von Dentz 1426e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1427c8992cffSLuiz Augusto von Dentz return rp->status; 1428cba6b758SLuiz Augusto von Dentz 1429cba6b758SLuiz Augusto von Dentz instance = hci_sent_cmd_data(hdev, HCI_OP_LE_REMOVE_ADV_SET); 1430cba6b758SLuiz Augusto von Dentz if (!instance) 1431c8992cffSLuiz Augusto von Dentz return rp->status; 1432cba6b758SLuiz Augusto von Dentz 1433cba6b758SLuiz Augusto von Dentz hci_dev_lock(hdev); 1434cba6b758SLuiz Augusto von Dentz 1435cba6b758SLuiz Augusto von Dentz err = hci_remove_adv_instance(hdev, *instance); 1436cba6b758SLuiz Augusto von Dentz if (!err) 1437cba6b758SLuiz Augusto von Dentz mgmt_advertising_removed(hci_skb_sk(hdev->sent_cmd), hdev, 1438cba6b758SLuiz Augusto von Dentz *instance); 1439cba6b758SLuiz Augusto von Dentz 1440cba6b758SLuiz Augusto von Dentz hci_dev_unlock(hdev); 1441c8992cffSLuiz Augusto von Dentz 1442c8992cffSLuiz Augusto von Dentz return rp->status; 1443cba6b758SLuiz Augusto von Dentz } 1444cba6b758SLuiz Augusto von Dentz 1445c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_adv_sets(struct hci_dev *hdev, void *data, 1446c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1447cba6b758SLuiz Augusto von Dentz { 1448c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1449cba6b758SLuiz Augusto von Dentz struct adv_info *adv, *n; 1450cba6b758SLuiz Augusto von Dentz int err; 1451cba6b758SLuiz Augusto von Dentz 1452e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1453e3f3a1aeSLuiz Augusto von Dentz 1454e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1455c8992cffSLuiz Augusto von Dentz return rp->status; 1456cba6b758SLuiz Augusto von Dentz 1457cba6b758SLuiz Augusto von Dentz if (!hci_sent_cmd_data(hdev, HCI_OP_LE_CLEAR_ADV_SETS)) 1458c8992cffSLuiz Augusto von Dentz return rp->status; 1459cba6b758SLuiz Augusto von Dentz 1460cba6b758SLuiz Augusto von Dentz hci_dev_lock(hdev); 1461cba6b758SLuiz Augusto von Dentz 1462cba6b758SLuiz Augusto von Dentz list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) { 1463cba6b758SLuiz Augusto von Dentz u8 instance = adv->instance; 1464cba6b758SLuiz Augusto von Dentz 1465cba6b758SLuiz Augusto von Dentz err = hci_remove_adv_instance(hdev, instance); 1466cba6b758SLuiz Augusto von Dentz if (!err) 1467cba6b758SLuiz Augusto von Dentz mgmt_advertising_removed(hci_skb_sk(hdev->sent_cmd), 1468cba6b758SLuiz Augusto von Dentz hdev, instance); 1469cba6b758SLuiz Augusto von Dentz } 1470cba6b758SLuiz Augusto von Dentz 1471cba6b758SLuiz Augusto von Dentz hci_dev_unlock(hdev); 1472c8992cffSLuiz Augusto von Dentz 1473c8992cffSLuiz Augusto von Dentz return rp->status; 1474cba6b758SLuiz Augusto von Dentz } 1475cba6b758SLuiz Augusto von Dentz 1476c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_transmit_power(struct hci_dev *hdev, void *data, 14777c395ea5SDaniel Winkler struct sk_buff *skb) 14787c395ea5SDaniel Winkler { 1479c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_transmit_power *rp = data; 1480e3f3a1aeSLuiz Augusto von Dentz 1481e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 14827c395ea5SDaniel Winkler 14837c395ea5SDaniel Winkler if (rp->status) 1484c8992cffSLuiz Augusto von Dentz return rp->status; 14857c395ea5SDaniel Winkler 14867c395ea5SDaniel Winkler hdev->min_le_tx_power = rp->min_le_tx_power; 14877c395ea5SDaniel Winkler hdev->max_le_tx_power = rp->max_le_tx_power; 1488c8992cffSLuiz Augusto von Dentz 1489c8992cffSLuiz Augusto von Dentz return rp->status; 14907c395ea5SDaniel Winkler } 14917c395ea5SDaniel Winkler 1492*853b70b5SLuiz Augusto von Dentz static u8 hci_cc_le_set_privacy_mode(struct hci_dev *hdev, void *data, 1493*853b70b5SLuiz Augusto von Dentz struct sk_buff *skb) 1494*853b70b5SLuiz Augusto von Dentz { 1495*853b70b5SLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1496*853b70b5SLuiz Augusto von Dentz struct hci_cp_le_set_privacy_mode *cp; 1497*853b70b5SLuiz Augusto von Dentz struct hci_conn_params *params; 1498*853b70b5SLuiz Augusto von Dentz 1499*853b70b5SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1500*853b70b5SLuiz Augusto von Dentz 1501*853b70b5SLuiz Augusto von Dentz if (rp->status) 1502*853b70b5SLuiz Augusto von Dentz return rp->status; 1503*853b70b5SLuiz Augusto von Dentz 1504*853b70b5SLuiz Augusto von Dentz cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PRIVACY_MODE); 1505*853b70b5SLuiz Augusto von Dentz if (!cp) 1506*853b70b5SLuiz Augusto von Dentz return rp->status; 1507*853b70b5SLuiz Augusto von Dentz 1508*853b70b5SLuiz Augusto von Dentz hci_dev_lock(hdev); 1509*853b70b5SLuiz Augusto von Dentz 1510*853b70b5SLuiz Augusto von Dentz params = hci_conn_params_lookup(hdev, &cp->bdaddr, cp->bdaddr_type); 1511*853b70b5SLuiz Augusto von Dentz if (params) 1512*853b70b5SLuiz Augusto von Dentz params->privacy_mode = cp->mode; 1513*853b70b5SLuiz Augusto von Dentz 1514*853b70b5SLuiz Augusto von Dentz hci_dev_unlock(hdev); 1515*853b70b5SLuiz Augusto von Dentz 1516*853b70b5SLuiz Augusto von Dentz return rp->status; 1517*853b70b5SLuiz Augusto von Dentz } 1518*853b70b5SLuiz Augusto von Dentz 1519c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_adv_enable(struct hci_dev *hdev, void *data, 1520c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1521c1d5dc4aSJohan Hedberg { 1522c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1523e3f3a1aeSLuiz Augusto von Dentz __u8 *sent; 1524c1d5dc4aSJohan Hedberg 1525e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1526e3f3a1aeSLuiz Augusto von Dentz 1527e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1528c8992cffSLuiz Augusto von Dentz return rp->status; 1529c1d5dc4aSJohan Hedberg 153045296acdSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE); 153145296acdSMarcel Holtmann if (!sent) 1532c8992cffSLuiz Augusto von Dentz return rp->status; 15333c857757SJohan Hedberg 1534c1d5dc4aSJohan Hedberg hci_dev_lock(hdev); 1535c1d5dc4aSJohan Hedberg 153649c922bbSStephen Hemminger /* If we're doing connection initiation as peripheral. Set a 15373c857757SJohan Hedberg * timeout in case something goes wrong. 15383c857757SJohan Hedberg */ 15393c857757SJohan Hedberg if (*sent) { 15403c857757SJohan Hedberg struct hci_conn *conn; 15413c857757SJohan Hedberg 1542a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ADV); 154366c417c1SJohan Hedberg 1544e7d9ab73SJakub Pawlowski conn = hci_lookup_le_connect(hdev); 15453c857757SJohan Hedberg if (conn) 15463c857757SJohan Hedberg queue_delayed_work(hdev->workqueue, 15473c857757SJohan Hedberg &conn->le_conn_timeout, 154809ae260bSJohan Hedberg conn->conn_timeout); 154966c417c1SJohan Hedberg } else { 1550a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ADV); 15513c857757SJohan Hedberg } 15523c857757SJohan Hedberg 155304b4edcbSJohan Hedberg hci_dev_unlock(hdev); 1554c8992cffSLuiz Augusto von Dentz 1555c8992cffSLuiz Augusto von Dentz return rp->status; 1556c1d5dc4aSJohan Hedberg } 1557c1d5dc4aSJohan Hedberg 1558c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, void *data, 1559de181e88SJaganath Kanakkassery struct sk_buff *skb) 1560de181e88SJaganath Kanakkassery { 1561de181e88SJaganath Kanakkassery struct hci_cp_le_set_ext_adv_enable *cp; 156210279313SLuiz Augusto von Dentz struct hci_cp_ext_adv_set *set; 156310279313SLuiz Augusto von Dentz struct adv_info *adv = NULL, *n; 1564c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1565de181e88SJaganath Kanakkassery 1566e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1567e3f3a1aeSLuiz Augusto von Dentz 1568e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1569c8992cffSLuiz Augusto von Dentz return rp->status; 1570de181e88SJaganath Kanakkassery 1571de181e88SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_ENABLE); 1572de181e88SJaganath Kanakkassery if (!cp) 1573c8992cffSLuiz Augusto von Dentz return rp->status; 1574de181e88SJaganath Kanakkassery 157510279313SLuiz Augusto von Dentz set = (void *)cp->data; 157610279313SLuiz Augusto von Dentz 1577de181e88SJaganath Kanakkassery hci_dev_lock(hdev); 1578de181e88SJaganath Kanakkassery 157910279313SLuiz Augusto von Dentz if (cp->num_of_sets) 158010279313SLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, set->handle); 158110279313SLuiz Augusto von Dentz 1582de181e88SJaganath Kanakkassery if (cp->enable) { 1583de181e88SJaganath Kanakkassery struct hci_conn *conn; 1584de181e88SJaganath Kanakkassery 1585de181e88SJaganath Kanakkassery hci_dev_set_flag(hdev, HCI_LE_ADV); 1586de181e88SJaganath Kanakkassery 158710279313SLuiz Augusto von Dentz if (adv) 158810279313SLuiz Augusto von Dentz adv->enabled = true; 158910279313SLuiz Augusto von Dentz 1590de181e88SJaganath Kanakkassery conn = hci_lookup_le_connect(hdev); 1591de181e88SJaganath Kanakkassery if (conn) 1592de181e88SJaganath Kanakkassery queue_delayed_work(hdev->workqueue, 1593de181e88SJaganath Kanakkassery &conn->le_conn_timeout, 1594de181e88SJaganath Kanakkassery conn->conn_timeout); 159545b7749fSJaganath Kanakkassery } else { 15962128939fSArchie Pusaka if (cp->num_of_sets) { 15972128939fSArchie Pusaka if (adv) 159810279313SLuiz Augusto von Dentz adv->enabled = false; 15992128939fSArchie Pusaka 160010279313SLuiz Augusto von Dentz /* If just one instance was disabled check if there are 160110279313SLuiz Augusto von Dentz * any other instance enabled before clearing HCI_LE_ADV 160210279313SLuiz Augusto von Dentz */ 160310279313SLuiz Augusto von Dentz list_for_each_entry_safe(adv, n, &hdev->adv_instances, 160410279313SLuiz Augusto von Dentz list) { 160510279313SLuiz Augusto von Dentz if (adv->enabled) 160610279313SLuiz Augusto von Dentz goto unlock; 160710279313SLuiz Augusto von Dentz } 160810279313SLuiz Augusto von Dentz } else { 160910279313SLuiz Augusto von Dentz /* All instances shall be considered disabled */ 161010279313SLuiz Augusto von Dentz list_for_each_entry_safe(adv, n, &hdev->adv_instances, 161110279313SLuiz Augusto von Dentz list) 161210279313SLuiz Augusto von Dentz adv->enabled = false; 161310279313SLuiz Augusto von Dentz } 161410279313SLuiz Augusto von Dentz 161545b7749fSJaganath Kanakkassery hci_dev_clear_flag(hdev, HCI_LE_ADV); 1616de181e88SJaganath Kanakkassery } 1617de181e88SJaganath Kanakkassery 161810279313SLuiz Augusto von Dentz unlock: 1619de181e88SJaganath Kanakkassery hci_dev_unlock(hdev); 1620c8992cffSLuiz Augusto von Dentz return rp->status; 1621de181e88SJaganath Kanakkassery } 1622de181e88SJaganath Kanakkassery 1623c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_scan_param(struct hci_dev *hdev, void *data, 1624c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 1625533553f8SMarcel Holtmann { 1626533553f8SMarcel Holtmann struct hci_cp_le_set_scan_param *cp; 1627c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1628533553f8SMarcel Holtmann 1629e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1630e3f3a1aeSLuiz Augusto von Dentz 1631e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1632c8992cffSLuiz Augusto von Dentz return rp->status; 163345296acdSMarcel Holtmann 1634533553f8SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM); 1635533553f8SMarcel Holtmann if (!cp) 1636c8992cffSLuiz Augusto von Dentz return rp->status; 1637533553f8SMarcel Holtmann 1638533553f8SMarcel Holtmann hci_dev_lock(hdev); 1639533553f8SMarcel Holtmann 1640533553f8SMarcel Holtmann hdev->le_scan_type = cp->type; 1641533553f8SMarcel Holtmann 1642533553f8SMarcel Holtmann hci_dev_unlock(hdev); 1643c8992cffSLuiz Augusto von Dentz 1644c8992cffSLuiz Augusto von Dentz return rp->status; 1645533553f8SMarcel Holtmann } 1646533553f8SMarcel Holtmann 1647c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_scan_param(struct hci_dev *hdev, void *data, 1648a2344b9eSJaganath Kanakkassery struct sk_buff *skb) 1649a2344b9eSJaganath Kanakkassery { 1650a2344b9eSJaganath Kanakkassery struct hci_cp_le_set_ext_scan_params *cp; 1651c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1652a2344b9eSJaganath Kanakkassery struct hci_cp_le_scan_phy_params *phy_param; 1653a2344b9eSJaganath Kanakkassery 1654e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1655e3f3a1aeSLuiz Augusto von Dentz 1656e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1657c8992cffSLuiz Augusto von Dentz return rp->status; 1658a2344b9eSJaganath Kanakkassery 1659a2344b9eSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_PARAMS); 1660a2344b9eSJaganath Kanakkassery if (!cp) 1661c8992cffSLuiz Augusto von Dentz return rp->status; 1662a2344b9eSJaganath Kanakkassery 1663a2344b9eSJaganath Kanakkassery phy_param = (void *)cp->data; 1664a2344b9eSJaganath Kanakkassery 1665a2344b9eSJaganath Kanakkassery hci_dev_lock(hdev); 1666a2344b9eSJaganath Kanakkassery 1667a2344b9eSJaganath Kanakkassery hdev->le_scan_type = phy_param->type; 1668a2344b9eSJaganath Kanakkassery 1669a2344b9eSJaganath Kanakkassery hci_dev_unlock(hdev); 1670c8992cffSLuiz Augusto von Dentz 1671c8992cffSLuiz Augusto von Dentz return rp->status; 1672a2344b9eSJaganath Kanakkassery } 1673a2344b9eSJaganath Kanakkassery 1674b9a6328fSJohan Hedberg static bool has_pending_adv_report(struct hci_dev *hdev) 1675b9a6328fSJohan Hedberg { 1676b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1677b9a6328fSJohan Hedberg 1678b9a6328fSJohan Hedberg return bacmp(&d->last_adv_addr, BDADDR_ANY); 1679b9a6328fSJohan Hedberg } 1680b9a6328fSJohan Hedberg 1681b9a6328fSJohan Hedberg static void clear_pending_adv_report(struct hci_dev *hdev) 1682b9a6328fSJohan Hedberg { 1683b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1684b9a6328fSJohan Hedberg 1685b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, BDADDR_ANY); 1686b9a6328fSJohan Hedberg d->last_adv_data_len = 0; 1687b9a6328fSJohan Hedberg } 1688b9a6328fSJohan Hedberg 1689b9a6328fSJohan Hedberg static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr, 1690c70a7e4cSMarcel Holtmann u8 bdaddr_type, s8 rssi, u32 flags, 1691c70a7e4cSMarcel Holtmann u8 *data, u8 len) 1692b9a6328fSJohan Hedberg { 1693b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1694b9a6328fSJohan Hedberg 1695a2ec905dSAlain Michaud if (len > HCI_MAX_AD_LENGTH) 1696a2ec905dSAlain Michaud return; 1697a2ec905dSAlain Michaud 1698b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, bdaddr); 1699b9a6328fSJohan Hedberg d->last_adv_addr_type = bdaddr_type; 1700ff5cd29fSJohan Hedberg d->last_adv_rssi = rssi; 1701c70a7e4cSMarcel Holtmann d->last_adv_flags = flags; 1702b9a6328fSJohan Hedberg memcpy(d->last_adv_data, data, len); 1703b9a6328fSJohan Hedberg d->last_adv_data_len = len; 1704b9a6328fSJohan Hedberg } 1705b9a6328fSJohan Hedberg 17063baef810SJaganath Kanakkassery static void le_set_scan_enable_complete(struct hci_dev *hdev, u8 enable) 1707eb9d91f5SAndre Guedes { 17085c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 17095c1a4c8fSJaganath Kanakkassery 17103baef810SJaganath Kanakkassery switch (enable) { 17113fd319b8SAndre Guedes case LE_SCAN_ENABLE: 1712a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_SCAN); 1713b9a6328fSJohan Hedberg if (hdev->le_scan_type == LE_SCAN_ACTIVE) 1714b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 171568a8aea4SAndrei Emeltchenko break; 171668a8aea4SAndrei Emeltchenko 171776a388beSAndre Guedes case LE_SCAN_DISABLE: 1718b9a6328fSJohan Hedberg /* We do this here instead of when setting DISCOVERY_STOPPED 1719b9a6328fSJohan Hedberg * since the latter would potentially require waiting for 1720b9a6328fSJohan Hedberg * inquiry to stop too. 1721b9a6328fSJohan Hedberg */ 1722b9a6328fSJohan Hedberg if (has_pending_adv_report(hdev)) { 1723b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 1724b9a6328fSJohan Hedberg 1725b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 1726ab0aa433SJohan Hedberg d->last_adv_addr_type, NULL, 1727c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags, 1728ab0aa433SJohan Hedberg d->last_adv_data, 1729b9a6328fSJohan Hedberg d->last_adv_data_len, NULL, 0); 1730b9a6328fSJohan Hedberg } 1731b9a6328fSJohan Hedberg 1732317ac8cbSJohan Hedberg /* Cancel this timer so that we don't try to disable scanning 1733317ac8cbSJohan Hedberg * when it's already disabled. 1734317ac8cbSJohan Hedberg */ 1735317ac8cbSJohan Hedberg cancel_delayed_work(&hdev->le_scan_disable); 1736317ac8cbSJohan Hedberg 1737a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_SCAN); 1738e8bb6b97SJohan Hedberg 173981ad6fd9SJohan Hedberg /* The HCI_LE_SCAN_INTERRUPTED flag indicates that we 174081ad6fd9SJohan Hedberg * interrupted scanning due to a connect request. Mark 1741abfeea47SLuiz Augusto von Dentz * therefore discovery as stopped. 174281ad6fd9SJohan Hedberg */ 1743a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_LE_SCAN_INTERRUPTED)) 174481ad6fd9SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 1745e8bb6b97SJohan Hedberg 174668a8aea4SAndrei Emeltchenko break; 174768a8aea4SAndrei Emeltchenko 174868a8aea4SAndrei Emeltchenko default: 17492064ee33SMarcel Holtmann bt_dev_err(hdev, "use of reserved LE_Scan_Enable param %d", 17503baef810SJaganath Kanakkassery enable); 175168a8aea4SAndrei Emeltchenko break; 175235815085SAndre Guedes } 17535c1a4c8fSJaganath Kanakkassery 17545c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 1755eb9d91f5SAndre Guedes } 1756eb9d91f5SAndre Guedes 1757c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_scan_enable(struct hci_dev *hdev, void *data, 17583baef810SJaganath Kanakkassery struct sk_buff *skb) 17593baef810SJaganath Kanakkassery { 17603baef810SJaganath Kanakkassery struct hci_cp_le_set_scan_enable *cp; 1761c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 17623baef810SJaganath Kanakkassery 1763e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1764e3f3a1aeSLuiz Augusto von Dentz 1765e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1766c8992cffSLuiz Augusto von Dentz return rp->status; 17673baef810SJaganath Kanakkassery 17683baef810SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE); 17693baef810SJaganath Kanakkassery if (!cp) 1770c8992cffSLuiz Augusto von Dentz return rp->status; 17713baef810SJaganath Kanakkassery 17723baef810SJaganath Kanakkassery le_set_scan_enable_complete(hdev, cp->enable); 1773c8992cffSLuiz Augusto von Dentz 1774c8992cffSLuiz Augusto von Dentz return rp->status; 17753baef810SJaganath Kanakkassery } 17763baef810SJaganath Kanakkassery 1777c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_scan_enable(struct hci_dev *hdev, void *data, 1778a2344b9eSJaganath Kanakkassery struct sk_buff *skb) 1779a2344b9eSJaganath Kanakkassery { 1780a2344b9eSJaganath Kanakkassery struct hci_cp_le_set_ext_scan_enable *cp; 1781c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1782a2344b9eSJaganath Kanakkassery 1783e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1784e3f3a1aeSLuiz Augusto von Dentz 1785e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1786c8992cffSLuiz Augusto von Dentz return rp->status; 1787a2344b9eSJaganath Kanakkassery 1788a2344b9eSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_ENABLE); 1789a2344b9eSJaganath Kanakkassery if (!cp) 1790c8992cffSLuiz Augusto von Dentz return rp->status; 1791a2344b9eSJaganath Kanakkassery 1792a2344b9eSJaganath Kanakkassery le_set_scan_enable_complete(hdev, cp->enable); 1793c8992cffSLuiz Augusto von Dentz 1794c8992cffSLuiz Augusto von Dentz return rp->status; 1795a2344b9eSJaganath Kanakkassery } 1796a2344b9eSJaganath Kanakkassery 1797c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_num_adv_sets(struct hci_dev *hdev, void *data, 17986b49bcb4SJaganath Kanakkassery struct sk_buff *skb) 17996b49bcb4SJaganath Kanakkassery { 1800c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_num_supported_adv_sets *rp = data; 1801e3f3a1aeSLuiz Augusto von Dentz 1802e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x No of Adv sets %u", rp->status, 18036b49bcb4SJaganath Kanakkassery rp->num_of_sets); 18046b49bcb4SJaganath Kanakkassery 18056b49bcb4SJaganath Kanakkassery if (rp->status) 1806c8992cffSLuiz Augusto von Dentz return rp->status; 18076b49bcb4SJaganath Kanakkassery 18086b49bcb4SJaganath Kanakkassery hdev->le_num_of_adv_sets = rp->num_of_sets; 1809c8992cffSLuiz Augusto von Dentz 1810c8992cffSLuiz Augusto von Dentz return rp->status; 18116b49bcb4SJaganath Kanakkassery } 18126b49bcb4SJaganath Kanakkassery 1813c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_accept_list_size(struct hci_dev *hdev, void *data, 1814cf1d081fSJohan Hedberg struct sk_buff *skb) 1815cf1d081fSJohan Hedberg { 1816c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_accept_list_size *rp = data; 1817e3f3a1aeSLuiz Augusto von Dentz 1818e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x size %u", rp->status, rp->size); 1819cf1d081fSJohan Hedberg 182045296acdSMarcel Holtmann if (rp->status) 1821c8992cffSLuiz Augusto von Dentz return rp->status; 182245296acdSMarcel Holtmann 18233d4f9c00SArchie Pusaka hdev->le_accept_list_size = rp->size; 1824c8992cffSLuiz Augusto von Dentz 1825c8992cffSLuiz Augusto von Dentz return rp->status; 1826cf1d081fSJohan Hedberg } 1827cf1d081fSJohan Hedberg 1828c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_accept_list(struct hci_dev *hdev, void *data, 18290f36b589SMarcel Holtmann struct sk_buff *skb) 18300f36b589SMarcel Holtmann { 1831c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 18320f36b589SMarcel Holtmann 1833e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1834e3f3a1aeSLuiz Augusto von Dentz 1835e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1836c8992cffSLuiz Augusto von Dentz return rp->status; 183745296acdSMarcel Holtmann 18383d4f9c00SArchie Pusaka hci_bdaddr_list_clear(&hdev->le_accept_list); 1839c8992cffSLuiz Augusto von Dentz 1840c8992cffSLuiz Augusto von Dentz return rp->status; 18410f36b589SMarcel Holtmann } 18420f36b589SMarcel Holtmann 1843c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_add_to_accept_list(struct hci_dev *hdev, void *data, 18440f36b589SMarcel Holtmann struct sk_buff *skb) 18450f36b589SMarcel Holtmann { 18463d4f9c00SArchie Pusaka struct hci_cp_le_add_to_accept_list *sent; 1847c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 18480f36b589SMarcel Holtmann 1849e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1850e3f3a1aeSLuiz Augusto von Dentz 1851e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1852c8992cffSLuiz Augusto von Dentz return rp->status; 185345296acdSMarcel Holtmann 18543d4f9c00SArchie Pusaka sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_ACCEPT_LIST); 18550f36b589SMarcel Holtmann if (!sent) 1856c8992cffSLuiz Augusto von Dentz return rp->status; 18570f36b589SMarcel Holtmann 18583d4f9c00SArchie Pusaka hci_bdaddr_list_add(&hdev->le_accept_list, &sent->bdaddr, 1859dcc36c16SJohan Hedberg sent->bdaddr_type); 1860c8992cffSLuiz Augusto von Dentz 1861c8992cffSLuiz Augusto von Dentz return rp->status; 18620f36b589SMarcel Holtmann } 18630f36b589SMarcel Holtmann 1864c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_del_from_accept_list(struct hci_dev *hdev, void *data, 18650f36b589SMarcel Holtmann struct sk_buff *skb) 18660f36b589SMarcel Holtmann { 18673d4f9c00SArchie Pusaka struct hci_cp_le_del_from_accept_list *sent; 1868c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 18690f36b589SMarcel Holtmann 1870e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1871e3f3a1aeSLuiz Augusto von Dentz 1872e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1873c8992cffSLuiz Augusto von Dentz return rp->status; 187445296acdSMarcel Holtmann 18753d4f9c00SArchie Pusaka sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_ACCEPT_LIST); 18760f36b589SMarcel Holtmann if (!sent) 1877c8992cffSLuiz Augusto von Dentz return rp->status; 18780f36b589SMarcel Holtmann 18793d4f9c00SArchie Pusaka hci_bdaddr_list_del(&hdev->le_accept_list, &sent->bdaddr, 1880dcc36c16SJohan Hedberg sent->bdaddr_type); 1881c8992cffSLuiz Augusto von Dentz 1882c8992cffSLuiz Augusto von Dentz return rp->status; 18830f36b589SMarcel Holtmann } 18840f36b589SMarcel Holtmann 1885c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_supported_states(struct hci_dev *hdev, void *data, 18869b008c04SJohan Hedberg struct sk_buff *skb) 18879b008c04SJohan Hedberg { 1888c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_supported_states *rp = data; 1889e3f3a1aeSLuiz Augusto von Dentz 1890e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 18919b008c04SJohan Hedberg 189245296acdSMarcel Holtmann if (rp->status) 1893c8992cffSLuiz Augusto von Dentz return rp->status; 189445296acdSMarcel Holtmann 18959b008c04SJohan Hedberg memcpy(hdev->le_states, rp->le_states, 8); 1896c8992cffSLuiz Augusto von Dentz 1897c8992cffSLuiz Augusto von Dentz return rp->status; 18989b008c04SJohan Hedberg } 18999b008c04SJohan Hedberg 1900c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_def_data_len(struct hci_dev *hdev, void *data, 1901a8e1bfaaSMarcel Holtmann struct sk_buff *skb) 1902a8e1bfaaSMarcel Holtmann { 1903c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_def_data_len *rp = data; 1904e3f3a1aeSLuiz Augusto von Dentz 1905e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1906a8e1bfaaSMarcel Holtmann 1907a8e1bfaaSMarcel Holtmann if (rp->status) 1908c8992cffSLuiz Augusto von Dentz return rp->status; 1909a8e1bfaaSMarcel Holtmann 1910a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = le16_to_cpu(rp->tx_len); 1911a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = le16_to_cpu(rp->tx_time); 1912c8992cffSLuiz Augusto von Dentz 1913c8992cffSLuiz Augusto von Dentz return rp->status; 1914a8e1bfaaSMarcel Holtmann } 1915a8e1bfaaSMarcel Holtmann 1916c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_write_def_data_len(struct hci_dev *hdev, void *data, 1917a8e1bfaaSMarcel Holtmann struct sk_buff *skb) 1918a8e1bfaaSMarcel Holtmann { 1919a8e1bfaaSMarcel Holtmann struct hci_cp_le_write_def_data_len *sent; 1920c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1921a8e1bfaaSMarcel Holtmann 1922e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1923e3f3a1aeSLuiz Augusto von Dentz 1924e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1925c8992cffSLuiz Augusto von Dentz return rp->status; 1926a8e1bfaaSMarcel Holtmann 1927a8e1bfaaSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN); 1928a8e1bfaaSMarcel Holtmann if (!sent) 1929c8992cffSLuiz Augusto von Dentz return rp->status; 1930a8e1bfaaSMarcel Holtmann 1931a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = le16_to_cpu(sent->tx_len); 1932a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = le16_to_cpu(sent->tx_time); 1933c8992cffSLuiz Augusto von Dentz 1934c8992cffSLuiz Augusto von Dentz return rp->status; 1935a8e1bfaaSMarcel Holtmann } 1936a8e1bfaaSMarcel Holtmann 1937c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_add_to_resolv_list(struct hci_dev *hdev, void *data, 1938b950aa88SAnkit Navik struct sk_buff *skb) 1939b950aa88SAnkit Navik { 1940b950aa88SAnkit Navik struct hci_cp_le_add_to_resolv_list *sent; 1941c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1942b950aa88SAnkit Navik 1943e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1944e3f3a1aeSLuiz Augusto von Dentz 1945e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1946c8992cffSLuiz Augusto von Dentz return rp->status; 1947b950aa88SAnkit Navik 1948b950aa88SAnkit Navik sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_RESOLV_LIST); 1949b950aa88SAnkit Navik if (!sent) 1950c8992cffSLuiz Augusto von Dentz return rp->status; 1951b950aa88SAnkit Navik 1952b950aa88SAnkit Navik hci_bdaddr_list_add_with_irk(&hdev->le_resolv_list, &sent->bdaddr, 1953b950aa88SAnkit Navik sent->bdaddr_type, sent->peer_irk, 1954b950aa88SAnkit Navik sent->local_irk); 1955c8992cffSLuiz Augusto von Dentz 1956c8992cffSLuiz Augusto von Dentz return rp->status; 1957b950aa88SAnkit Navik } 1958b950aa88SAnkit Navik 1959c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_del_from_resolv_list(struct hci_dev *hdev, void *data, 1960b950aa88SAnkit Navik struct sk_buff *skb) 1961b950aa88SAnkit Navik { 1962b950aa88SAnkit Navik struct hci_cp_le_del_from_resolv_list *sent; 1963c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1964b950aa88SAnkit Navik 1965e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1966e3f3a1aeSLuiz Augusto von Dentz 1967e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1968c8992cffSLuiz Augusto von Dentz return rp->status; 1969b950aa88SAnkit Navik 1970b950aa88SAnkit Navik sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_RESOLV_LIST); 1971b950aa88SAnkit Navik if (!sent) 1972c8992cffSLuiz Augusto von Dentz return rp->status; 1973b950aa88SAnkit Navik 1974b950aa88SAnkit Navik hci_bdaddr_list_del_with_irk(&hdev->le_resolv_list, &sent->bdaddr, 1975b950aa88SAnkit Navik sent->bdaddr_type); 1976c8992cffSLuiz Augusto von Dentz 1977c8992cffSLuiz Augusto von Dentz return rp->status; 1978b950aa88SAnkit Navik } 1979b950aa88SAnkit Navik 1980c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_resolv_list(struct hci_dev *hdev, void *data, 1981545f2596SAnkit Navik struct sk_buff *skb) 1982545f2596SAnkit Navik { 1983c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 1984545f2596SAnkit Navik 1985e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 1986e3f3a1aeSLuiz Augusto von Dentz 1987e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 1988c8992cffSLuiz Augusto von Dentz return rp->status; 1989545f2596SAnkit Navik 1990545f2596SAnkit Navik hci_bdaddr_list_clear(&hdev->le_resolv_list); 1991c8992cffSLuiz Augusto von Dentz 1992c8992cffSLuiz Augusto von Dentz return rp->status; 1993545f2596SAnkit Navik } 1994545f2596SAnkit Navik 1995c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_resolv_list_size(struct hci_dev *hdev, void *data, 1996cfdb0c2dSAnkit Navik struct sk_buff *skb) 1997cfdb0c2dSAnkit Navik { 1998c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_resolv_list_size *rp = data; 1999e3f3a1aeSLuiz Augusto von Dentz 2000e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x size %u", rp->status, rp->size); 2001cfdb0c2dSAnkit Navik 2002cfdb0c2dSAnkit Navik if (rp->status) 2003c8992cffSLuiz Augusto von Dentz return rp->status; 2004cfdb0c2dSAnkit Navik 2005cfdb0c2dSAnkit Navik hdev->le_resolv_list_size = rp->size; 2006c8992cffSLuiz Augusto von Dentz 2007c8992cffSLuiz Augusto von Dentz return rp->status; 2008cfdb0c2dSAnkit Navik } 2009cfdb0c2dSAnkit Navik 2010c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_addr_resolution_enable(struct hci_dev *hdev, void *data, 2011aa12af77SAnkit Navik struct sk_buff *skb) 2012aa12af77SAnkit Navik { 2013c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 2014e3f3a1aeSLuiz Augusto von Dentz __u8 *sent; 2015aa12af77SAnkit Navik 2016e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2017e3f3a1aeSLuiz Augusto von Dentz 2018e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 2019c8992cffSLuiz Augusto von Dentz return rp->status; 2020aa12af77SAnkit Navik 2021aa12af77SAnkit Navik sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE); 2022aa12af77SAnkit Navik if (!sent) 2023c8992cffSLuiz Augusto von Dentz return rp->status; 2024aa12af77SAnkit Navik 2025aa12af77SAnkit Navik hci_dev_lock(hdev); 2026aa12af77SAnkit Navik 2027aa12af77SAnkit Navik if (*sent) 2028aa12af77SAnkit Navik hci_dev_set_flag(hdev, HCI_LL_RPA_RESOLUTION); 2029aa12af77SAnkit Navik else 2030aa12af77SAnkit Navik hci_dev_clear_flag(hdev, HCI_LL_RPA_RESOLUTION); 2031aa12af77SAnkit Navik 2032aa12af77SAnkit Navik hci_dev_unlock(hdev); 2033c8992cffSLuiz Augusto von Dentz 2034c8992cffSLuiz Augusto von Dentz return rp->status; 2035aa12af77SAnkit Navik } 2036aa12af77SAnkit Navik 2037c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_max_data_len(struct hci_dev *hdev, void *data, 2038a8e1bfaaSMarcel Holtmann struct sk_buff *skb) 2039a8e1bfaaSMarcel Holtmann { 2040c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_max_data_len *rp = data; 2041e3f3a1aeSLuiz Augusto von Dentz 2042e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2043a8e1bfaaSMarcel Holtmann 2044a8e1bfaaSMarcel Holtmann if (rp->status) 2045c8992cffSLuiz Augusto von Dentz return rp->status; 2046a8e1bfaaSMarcel Holtmann 2047a8e1bfaaSMarcel Holtmann hdev->le_max_tx_len = le16_to_cpu(rp->tx_len); 2048a8e1bfaaSMarcel Holtmann hdev->le_max_tx_time = le16_to_cpu(rp->tx_time); 2049a8e1bfaaSMarcel Holtmann hdev->le_max_rx_len = le16_to_cpu(rp->rx_len); 2050a8e1bfaaSMarcel Holtmann hdev->le_max_rx_time = le16_to_cpu(rp->rx_time); 2051c8992cffSLuiz Augusto von Dentz 2052c8992cffSLuiz Augusto von Dentz return rp->status; 2053a8e1bfaaSMarcel Holtmann } 2054a8e1bfaaSMarcel Holtmann 2055c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_le_host_supported(struct hci_dev *hdev, void *data, 2056f9b49306SAndre Guedes struct sk_buff *skb) 2057f9b49306SAndre Guedes { 205806199cf8SJohan Hedberg struct hci_cp_write_le_host_supported *sent; 2059c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 2060f9b49306SAndre Guedes 2061e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2062e3f3a1aeSLuiz Augusto von Dentz 2063e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 2064c8992cffSLuiz Augusto von Dentz return rp->status; 206545296acdSMarcel Holtmann 206606199cf8SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED); 20678f984dfaSJohan Hedberg if (!sent) 2068c8992cffSLuiz Augusto von Dentz return rp->status; 2069f9b49306SAndre Guedes 20705c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev); 20715c1a4c8fSJaganath Kanakkassery 2072416a4ae5SJohan Hedberg if (sent->le) { 2073cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE; 2074a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ENABLED); 2075416a4ae5SJohan Hedberg } else { 2076cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE; 2077a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ENABLED); 2078a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_ADVERTISING); 2079416a4ae5SJohan Hedberg } 208053b2caabSJohan Hedberg 208153b2caabSJohan Hedberg if (sent->simul) 2082cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE_BREDR; 208353b2caabSJohan Hedberg else 2084cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE_BREDR; 20855c1a4c8fSJaganath Kanakkassery 20865c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev); 2087c8992cffSLuiz Augusto von Dentz 2088c8992cffSLuiz Augusto von Dentz return rp->status; 20898f984dfaSJohan Hedberg } 2090f9b49306SAndre Guedes 2091c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_adv_param(struct hci_dev *hdev, void *data, 2092c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 209356ed2cb8SJohan Hedberg { 209456ed2cb8SJohan Hedberg struct hci_cp_le_set_adv_param *cp; 2095c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 209656ed2cb8SJohan Hedberg 2097e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2098e3f3a1aeSLuiz Augusto von Dentz 2099e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 2100c8992cffSLuiz Augusto von Dentz return rp->status; 210156ed2cb8SJohan Hedberg 210256ed2cb8SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM); 210356ed2cb8SJohan Hedberg if (!cp) 2104c8992cffSLuiz Augusto von Dentz return rp->status; 210556ed2cb8SJohan Hedberg 210656ed2cb8SJohan Hedberg hci_dev_lock(hdev); 210756ed2cb8SJohan Hedberg hdev->adv_addr_type = cp->own_address_type; 210856ed2cb8SJohan Hedberg hci_dev_unlock(hdev); 2109c8992cffSLuiz Augusto von Dentz 2110c8992cffSLuiz Augusto von Dentz return rp->status; 211156ed2cb8SJohan Hedberg } 211256ed2cb8SJohan Hedberg 2113c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_ext_adv_param(struct hci_dev *hdev, void *data, 2114c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 2115de181e88SJaganath Kanakkassery { 2116c8992cffSLuiz Augusto von Dentz struct hci_rp_le_set_ext_adv_params *rp = data; 2117de181e88SJaganath Kanakkassery struct hci_cp_le_set_ext_adv_params *cp; 2118de181e88SJaganath Kanakkassery struct adv_info *adv_instance; 2119de181e88SJaganath Kanakkassery 2120e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2121de181e88SJaganath Kanakkassery 2122de181e88SJaganath Kanakkassery if (rp->status) 2123c8992cffSLuiz Augusto von Dentz return rp->status; 2124de181e88SJaganath Kanakkassery 2125de181e88SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS); 2126de181e88SJaganath Kanakkassery if (!cp) 2127c8992cffSLuiz Augusto von Dentz return rp->status; 2128de181e88SJaganath Kanakkassery 2129de181e88SJaganath Kanakkassery hci_dev_lock(hdev); 2130de181e88SJaganath Kanakkassery hdev->adv_addr_type = cp->own_addr_type; 213125e70886SDaniel Winkler if (!cp->handle) { 2132de181e88SJaganath Kanakkassery /* Store in hdev for instance 0 */ 2133de181e88SJaganath Kanakkassery hdev->adv_tx_power = rp->tx_power; 2134de181e88SJaganath Kanakkassery } else { 213525e70886SDaniel Winkler adv_instance = hci_find_adv_instance(hdev, cp->handle); 2136de181e88SJaganath Kanakkassery if (adv_instance) 2137de181e88SJaganath Kanakkassery adv_instance->tx_power = rp->tx_power; 2138de181e88SJaganath Kanakkassery } 2139a0fb3726SJaganath Kanakkassery /* Update adv data as tx power is known now */ 214025e70886SDaniel Winkler hci_req_update_adv_data(hdev, cp->handle); 214112410572SDaniel Winkler 2142de181e88SJaganath Kanakkassery hci_dev_unlock(hdev); 2143c8992cffSLuiz Augusto von Dentz 2144c8992cffSLuiz Augusto von Dentz return rp->status; 2145de181e88SJaganath Kanakkassery } 2146de181e88SJaganath Kanakkassery 2147c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_rssi(struct hci_dev *hdev, void *data, 2148c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 21495ae76a94SAndrzej Kaczmarek { 2150c8992cffSLuiz Augusto von Dentz struct hci_rp_read_rssi *rp = data; 21515ae76a94SAndrzej Kaczmarek struct hci_conn *conn; 21525ae76a94SAndrzej Kaczmarek 2153e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 21545ae76a94SAndrzej Kaczmarek 21555ae76a94SAndrzej Kaczmarek if (rp->status) 2156c8992cffSLuiz Augusto von Dentz return rp->status; 21575ae76a94SAndrzej Kaczmarek 21585ae76a94SAndrzej Kaczmarek hci_dev_lock(hdev); 21595ae76a94SAndrzej Kaczmarek 21605ae76a94SAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 21615ae76a94SAndrzej Kaczmarek if (conn) 21625ae76a94SAndrzej Kaczmarek conn->rssi = rp->rssi; 21635ae76a94SAndrzej Kaczmarek 21645ae76a94SAndrzej Kaczmarek hci_dev_unlock(hdev); 2165c8992cffSLuiz Augusto von Dentz 2166c8992cffSLuiz Augusto von Dentz return rp->status; 21675ae76a94SAndrzej Kaczmarek } 21685ae76a94SAndrzej Kaczmarek 2169c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_tx_power(struct hci_dev *hdev, void *data, 2170c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 21715a134faeSAndrzej Kaczmarek { 21725a134faeSAndrzej Kaczmarek struct hci_cp_read_tx_power *sent; 2173c8992cffSLuiz Augusto von Dentz struct hci_rp_read_tx_power *rp = data; 21745a134faeSAndrzej Kaczmarek struct hci_conn *conn; 21755a134faeSAndrzej Kaczmarek 2176e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 21775a134faeSAndrzej Kaczmarek 21785a134faeSAndrzej Kaczmarek if (rp->status) 2179c8992cffSLuiz Augusto von Dentz return rp->status; 21805a134faeSAndrzej Kaczmarek 21815a134faeSAndrzej Kaczmarek sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER); 21825a134faeSAndrzej Kaczmarek if (!sent) 2183c8992cffSLuiz Augusto von Dentz return rp->status; 21845a134faeSAndrzej Kaczmarek 21855a134faeSAndrzej Kaczmarek hci_dev_lock(hdev); 21865a134faeSAndrzej Kaczmarek 21875a134faeSAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 2188d0455ed9SAndrzej Kaczmarek if (!conn) 2189d0455ed9SAndrzej Kaczmarek goto unlock; 21905a134faeSAndrzej Kaczmarek 2191d0455ed9SAndrzej Kaczmarek switch (sent->type) { 2192d0455ed9SAndrzej Kaczmarek case 0x00: 2193d0455ed9SAndrzej Kaczmarek conn->tx_power = rp->tx_power; 2194d0455ed9SAndrzej Kaczmarek break; 2195d0455ed9SAndrzej Kaczmarek case 0x01: 2196d0455ed9SAndrzej Kaczmarek conn->max_tx_power = rp->tx_power; 2197d0455ed9SAndrzej Kaczmarek break; 2198d0455ed9SAndrzej Kaczmarek } 2199d0455ed9SAndrzej Kaczmarek 2200d0455ed9SAndrzej Kaczmarek unlock: 22015a134faeSAndrzej Kaczmarek hci_dev_unlock(hdev); 2202c8992cffSLuiz Augusto von Dentz return rp->status; 22035a134faeSAndrzej Kaczmarek } 22045a134faeSAndrzej Kaczmarek 2205c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_ssp_debug_mode(struct hci_dev *hdev, void *data, 2206c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 2207c50b33c8SMarcel Holtmann { 2208c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data; 2209c50b33c8SMarcel Holtmann u8 *mode; 2210c50b33c8SMarcel Holtmann 2211e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); 2212e3f3a1aeSLuiz Augusto von Dentz 2213e3f3a1aeSLuiz Augusto von Dentz if (rp->status) 2214c8992cffSLuiz Augusto von Dentz return rp->status; 2215c50b33c8SMarcel Holtmann 2216c50b33c8SMarcel Holtmann mode = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE); 2217c50b33c8SMarcel Holtmann if (mode) 2218c50b33c8SMarcel Holtmann hdev->ssp_debug_mode = *mode; 2219c8992cffSLuiz Augusto von Dentz 2220c8992cffSLuiz Augusto von Dentz return rp->status; 2221c50b33c8SMarcel Holtmann } 2222c50b33c8SMarcel Holtmann 22236039aa73SGustavo Padovan static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) 2224a9de9248SMarcel Holtmann { 2225147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2226a9de9248SMarcel Holtmann 2227a9de9248SMarcel Holtmann if (status) { 2228a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 2229314b2381SJohan Hedberg return; 2230314b2381SJohan Hedberg } 2231314b2381SJohan Hedberg 223289352e7dSAndre Guedes set_bit(HCI_INQUIRY, &hdev->flags); 2233a9de9248SMarcel Holtmann } 2234a9de9248SMarcel Holtmann 22356039aa73SGustavo Padovan static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) 22361da177e4SLinus Torvalds { 2237a9de9248SMarcel Holtmann struct hci_cp_create_conn *cp; 22381da177e4SLinus Torvalds struct hci_conn *conn; 22391da177e4SLinus Torvalds 2240147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2241a9de9248SMarcel Holtmann 2242a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN); 22431da177e4SLinus Torvalds if (!cp) 22441da177e4SLinus Torvalds return; 22451da177e4SLinus Torvalds 22461da177e4SLinus Torvalds hci_dev_lock(hdev); 22471da177e4SLinus Torvalds 22481da177e4SLinus Torvalds conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 22491da177e4SLinus Torvalds 2250147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "bdaddr %pMR hcon %p", &cp->bdaddr, conn); 22511da177e4SLinus Torvalds 22521da177e4SLinus Torvalds if (status) { 22531da177e4SLinus Torvalds if (conn && conn->state == BT_CONNECT) { 22544c67bc74SMarcel Holtmann if (status != 0x0c || conn->attempt > 2) { 22551da177e4SLinus Torvalds conn->state = BT_CLOSED; 2256539c496dSJohan Hedberg hci_connect_cfm(conn, status); 22571da177e4SLinus Torvalds hci_conn_del(conn); 22584c67bc74SMarcel Holtmann } else 22594c67bc74SMarcel Holtmann conn->state = BT_CONNECT2; 22601da177e4SLinus Torvalds } 22611da177e4SLinus Torvalds } else { 22621da177e4SLinus Torvalds if (!conn) { 2263a5c4e309SJohan Hedberg conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr, 2264a5c4e309SJohan Hedberg HCI_ROLE_MASTER); 2265a5c4e309SJohan Hedberg if (!conn) 22662064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for new connection"); 22671da177e4SLinus Torvalds } 22681da177e4SLinus Torvalds } 22691da177e4SLinus Torvalds 22701da177e4SLinus Torvalds hci_dev_unlock(hdev); 22711da177e4SLinus Torvalds } 22721da177e4SLinus Torvalds 2273a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status) 22741da177e4SLinus Torvalds { 2275a9de9248SMarcel Holtmann struct hci_cp_add_sco *cp; 22761da177e4SLinus Torvalds struct hci_conn *acl, *sco; 22771da177e4SLinus Torvalds __u16 handle; 22781da177e4SLinus Torvalds 2279147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2280b6a0dc82SMarcel Holtmann 2281a9de9248SMarcel Holtmann if (!status) 2282a9de9248SMarcel Holtmann return; 2283a9de9248SMarcel Holtmann 2284a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO); 22851da177e4SLinus Torvalds if (!cp) 2286a9de9248SMarcel Holtmann return; 22871da177e4SLinus Torvalds 22881da177e4SLinus Torvalds handle = __le16_to_cpu(cp->handle); 22891da177e4SLinus Torvalds 2290147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%4.4x", handle); 22911da177e4SLinus Torvalds 22921da177e4SLinus Torvalds hci_dev_lock(hdev); 22931da177e4SLinus Torvalds 22941da177e4SLinus Torvalds acl = hci_conn_hash_lookup_handle(hdev, handle); 22955a08ecceSAndrei Emeltchenko if (acl) { 22965a08ecceSAndrei Emeltchenko sco = acl->link; 22975a08ecceSAndrei Emeltchenko if (sco) { 22981da177e4SLinus Torvalds sco->state = BT_CLOSED; 22991da177e4SLinus Torvalds 2300539c496dSJohan Hedberg hci_connect_cfm(sco, status); 23011da177e4SLinus Torvalds hci_conn_del(sco); 23021da177e4SLinus Torvalds } 23035a08ecceSAndrei Emeltchenko } 23041da177e4SLinus Torvalds 23051da177e4SLinus Torvalds hci_dev_unlock(hdev); 23061da177e4SLinus Torvalds } 23071da177e4SLinus Torvalds 2308f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status) 2309f8558555SMarcel Holtmann { 2310f8558555SMarcel Holtmann struct hci_cp_auth_requested *cp; 2311f8558555SMarcel Holtmann struct hci_conn *conn; 2312f8558555SMarcel Holtmann 2313147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2314f8558555SMarcel Holtmann 2315f8558555SMarcel Holtmann if (!status) 2316f8558555SMarcel Holtmann return; 2317f8558555SMarcel Holtmann 2318f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED); 2319f8558555SMarcel Holtmann if (!cp) 2320f8558555SMarcel Holtmann return; 2321f8558555SMarcel Holtmann 2322f8558555SMarcel Holtmann hci_dev_lock(hdev); 2323f8558555SMarcel Holtmann 2324f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2325f8558555SMarcel Holtmann if (conn) { 2326f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 2327539c496dSJohan Hedberg hci_connect_cfm(conn, status); 232876a68ba0SDavid Herrmann hci_conn_drop(conn); 2329f8558555SMarcel Holtmann } 2330f8558555SMarcel Holtmann } 2331f8558555SMarcel Holtmann 2332f8558555SMarcel Holtmann hci_dev_unlock(hdev); 2333f8558555SMarcel Holtmann } 2334f8558555SMarcel Holtmann 2335f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) 2336f8558555SMarcel Holtmann { 2337f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt *cp; 2338f8558555SMarcel Holtmann struct hci_conn *conn; 2339f8558555SMarcel Holtmann 2340147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2341f8558555SMarcel Holtmann 2342f8558555SMarcel Holtmann if (!status) 2343f8558555SMarcel Holtmann return; 2344f8558555SMarcel Holtmann 2345f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT); 2346f8558555SMarcel Holtmann if (!cp) 2347f8558555SMarcel Holtmann return; 2348f8558555SMarcel Holtmann 2349f8558555SMarcel Holtmann hci_dev_lock(hdev); 2350f8558555SMarcel Holtmann 2351f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2352f8558555SMarcel Holtmann if (conn) { 2353f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 2354539c496dSJohan Hedberg hci_connect_cfm(conn, status); 235576a68ba0SDavid Herrmann hci_conn_drop(conn); 2356f8558555SMarcel Holtmann } 2357f8558555SMarcel Holtmann } 2358f8558555SMarcel Holtmann 2359f8558555SMarcel Holtmann hci_dev_unlock(hdev); 2360f8558555SMarcel Holtmann } 2361f8558555SMarcel Holtmann 2362127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev, 2363392599b9SJohan Hedberg struct hci_conn *conn) 2364392599b9SJohan Hedberg { 2365392599b9SJohan Hedberg if (conn->state != BT_CONFIG || !conn->out) 2366392599b9SJohan Hedberg return 0; 2367392599b9SJohan Hedberg 2368765c2a96SJohan Hedberg if (conn->pending_sec_level == BT_SECURITY_SDP) 2369392599b9SJohan Hedberg return 0; 2370392599b9SJohan Hedberg 2371392599b9SJohan Hedberg /* Only request authentication for SSP connections or non-SSP 2372264b8b4eSJohan Hedberg * devices with sec_level MEDIUM or HIGH or if MITM protection 2373264b8b4eSJohan Hedberg * is requested. 2374264b8b4eSJohan Hedberg */ 2375807deac2SGustavo Padovan if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) && 23767e3691e1SJohan Hedberg conn->pending_sec_level != BT_SECURITY_FIPS && 2377264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_HIGH && 2378264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_MEDIUM) 2379392599b9SJohan Hedberg return 0; 2380392599b9SJohan Hedberg 2381392599b9SJohan Hedberg return 1; 2382392599b9SJohan Hedberg } 2383392599b9SJohan Hedberg 23846039aa73SGustavo Padovan static int hci_resolve_name(struct hci_dev *hdev, 238500abfe44SGustavo F. Padovan struct inquiry_entry *e) 238630dc78e1SJohan Hedberg { 238730dc78e1SJohan Hedberg struct hci_cp_remote_name_req cp; 238830dc78e1SJohan Hedberg 238930dc78e1SJohan Hedberg memset(&cp, 0, sizeof(cp)); 239030dc78e1SJohan Hedberg 239130dc78e1SJohan Hedberg bacpy(&cp.bdaddr, &e->data.bdaddr); 239230dc78e1SJohan Hedberg cp.pscan_rep_mode = e->data.pscan_rep_mode; 239330dc78e1SJohan Hedberg cp.pscan_mode = e->data.pscan_mode; 239430dc78e1SJohan Hedberg cp.clock_offset = e->data.clock_offset; 239530dc78e1SJohan Hedberg 239630dc78e1SJohan Hedberg return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 239730dc78e1SJohan Hedberg } 239830dc78e1SJohan Hedberg 2399b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev) 240030dc78e1SJohan Hedberg { 240130dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 240230dc78e1SJohan Hedberg struct inquiry_entry *e; 240330dc78e1SJohan Hedberg 2404b644ba33SJohan Hedberg if (list_empty(&discov->resolve)) 2405b644ba33SJohan Hedberg return false; 2406b644ba33SJohan Hedberg 2407dbf6811aSArchie Pusaka /* We should stop if we already spent too much time resolving names. */ 2408dbf6811aSArchie Pusaka if (time_after(jiffies, discov->name_resolve_timeout)) { 2409dbf6811aSArchie Pusaka bt_dev_warn_ratelimited(hdev, "Name resolve takes too long."); 2410dbf6811aSArchie Pusaka return false; 2411dbf6811aSArchie Pusaka } 2412dbf6811aSArchie Pusaka 2413b644ba33SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 2414c810089cSRam Malovany if (!e) 2415c810089cSRam Malovany return false; 2416c810089cSRam Malovany 2417b644ba33SJohan Hedberg if (hci_resolve_name(hdev, e) == 0) { 2418b644ba33SJohan Hedberg e->name_state = NAME_PENDING; 2419b644ba33SJohan Hedberg return true; 2420b644ba33SJohan Hedberg } 2421b644ba33SJohan Hedberg 2422b644ba33SJohan Hedberg return false; 2423b644ba33SJohan Hedberg } 2424b644ba33SJohan Hedberg 2425b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, 2426b644ba33SJohan Hedberg bdaddr_t *bdaddr, u8 *name, u8 name_len) 2427b644ba33SJohan Hedberg { 2428b644ba33SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 2429b644ba33SJohan Hedberg struct inquiry_entry *e; 2430b644ba33SJohan Hedberg 243160cb49d2SJohan Hedberg /* Update the mgmt connected state if necessary. Be careful with 243260cb49d2SJohan Hedberg * conn objects that exist but are not (yet) connected however. 243360cb49d2SJohan Hedberg * Only those in BT_CONFIG or BT_CONNECTED states can be 243460cb49d2SJohan Hedberg * considered connected. 243560cb49d2SJohan Hedberg */ 243660cb49d2SJohan Hedberg if (conn && 243760cb49d2SJohan Hedberg (conn->state == BT_CONFIG || conn->state == BT_CONNECTED) && 2438cb77c3ecSJaganath Kanakkassery !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 24391c6ed31bSYu Liu mgmt_device_connected(hdev, conn, name, name_len); 2440b644ba33SJohan Hedberg 2441b644ba33SJohan Hedberg if (discov->state == DISCOVERY_STOPPED) 2442b644ba33SJohan Hedberg return; 2443b644ba33SJohan Hedberg 244430dc78e1SJohan Hedberg if (discov->state == DISCOVERY_STOPPING) 244530dc78e1SJohan Hedberg goto discov_complete; 244630dc78e1SJohan Hedberg 244730dc78e1SJohan Hedberg if (discov->state != DISCOVERY_RESOLVING) 244830dc78e1SJohan Hedberg return; 244930dc78e1SJohan Hedberg 245030dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING); 24517cc8380eSRam Malovany /* If the device was not found in a list of found devices names of which 24527cc8380eSRam Malovany * are pending. there is no need to continue resolving a next name as it 24537cc8380eSRam Malovany * will be done upon receiving another Remote Name Request Complete 24547cc8380eSRam Malovany * Event */ 24557cc8380eSRam Malovany if (!e) 24567cc8380eSRam Malovany return; 24577cc8380eSRam Malovany 245830dc78e1SJohan Hedberg list_del(&e->list); 2459ea13aed5SArchie Pusaka 2460ea13aed5SArchie Pusaka e->name_state = name ? NAME_KNOWN : NAME_NOT_KNOWN; 2461ea13aed5SArchie Pusaka mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, e->data.rssi, 2462ea13aed5SArchie Pusaka name, name_len); 246330dc78e1SJohan Hedberg 2464b644ba33SJohan Hedberg if (hci_resolve_next_name(hdev)) 246530dc78e1SJohan Hedberg return; 246630dc78e1SJohan Hedberg 246730dc78e1SJohan Hedberg discov_complete: 246830dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 246930dc78e1SJohan Hedberg } 247030dc78e1SJohan Hedberg 2471a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) 24721da177e4SLinus Torvalds { 2473127178d2SJohan Hedberg struct hci_cp_remote_name_req *cp; 2474127178d2SJohan Hedberg struct hci_conn *conn; 2475127178d2SJohan Hedberg 2476147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2477127178d2SJohan Hedberg 2478127178d2SJohan Hedberg /* If successful wait for the name req complete event before 2479127178d2SJohan Hedberg * checking for the need to do authentication */ 2480127178d2SJohan Hedberg if (!status) 2481127178d2SJohan Hedberg return; 2482127178d2SJohan Hedberg 2483127178d2SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ); 2484127178d2SJohan Hedberg if (!cp) 2485127178d2SJohan Hedberg return; 2486127178d2SJohan Hedberg 2487127178d2SJohan Hedberg hci_dev_lock(hdev); 2488127178d2SJohan Hedberg 2489127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 2490b644ba33SJohan Hedberg 2491d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 2492b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0); 2493b644ba33SJohan Hedberg 249479c6c70cSJohan Hedberg if (!conn) 249579c6c70cSJohan Hedberg goto unlock; 249679c6c70cSJohan Hedberg 249779c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 249879c6c70cSJohan Hedberg goto unlock; 249979c6c70cSJohan Hedberg 250051a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 2501c1f23a2bSJohannes Berg struct hci_cp_auth_requested auth_cp; 2502c1f23a2bSJohannes Berg 2503977f8fceSJohan Hedberg set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags); 2504977f8fceSJohan Hedberg 2505c1f23a2bSJohannes Berg auth_cp.handle = __cpu_to_le16(conn->handle); 2506c1f23a2bSJohannes Berg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, 2507c1f23a2bSJohannes Berg sizeof(auth_cp), &auth_cp); 2508127178d2SJohan Hedberg } 2509127178d2SJohan Hedberg 251079c6c70cSJohan Hedberg unlock: 2511127178d2SJohan Hedberg hci_dev_unlock(hdev); 2512a9de9248SMarcel Holtmann } 25131da177e4SLinus Torvalds 2514769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) 2515769be974SMarcel Holtmann { 2516769be974SMarcel Holtmann struct hci_cp_read_remote_features *cp; 2517769be974SMarcel Holtmann struct hci_conn *conn; 2518769be974SMarcel Holtmann 2519147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2520769be974SMarcel Holtmann 2521769be974SMarcel Holtmann if (!status) 2522769be974SMarcel Holtmann return; 2523769be974SMarcel Holtmann 2524769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES); 2525769be974SMarcel Holtmann if (!cp) 2526769be974SMarcel Holtmann return; 2527769be974SMarcel Holtmann 2528769be974SMarcel Holtmann hci_dev_lock(hdev); 2529769be974SMarcel Holtmann 2530769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2531769be974SMarcel Holtmann if (conn) { 2532769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 2533539c496dSJohan Hedberg hci_connect_cfm(conn, status); 253476a68ba0SDavid Herrmann hci_conn_drop(conn); 2535769be974SMarcel Holtmann } 2536769be974SMarcel Holtmann } 2537769be974SMarcel Holtmann 2538769be974SMarcel Holtmann hci_dev_unlock(hdev); 2539769be974SMarcel Holtmann } 2540769be974SMarcel Holtmann 2541769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status) 2542769be974SMarcel Holtmann { 2543769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features *cp; 2544769be974SMarcel Holtmann struct hci_conn *conn; 2545769be974SMarcel Holtmann 2546147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2547769be974SMarcel Holtmann 2548769be974SMarcel Holtmann if (!status) 2549769be974SMarcel Holtmann return; 2550769be974SMarcel Holtmann 2551769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES); 2552769be974SMarcel Holtmann if (!cp) 2553769be974SMarcel Holtmann return; 2554769be974SMarcel Holtmann 2555769be974SMarcel Holtmann hci_dev_lock(hdev); 2556769be974SMarcel Holtmann 2557769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2558769be974SMarcel Holtmann if (conn) { 2559769be974SMarcel Holtmann if (conn->state == BT_CONFIG) { 2560539c496dSJohan Hedberg hci_connect_cfm(conn, status); 256176a68ba0SDavid Herrmann hci_conn_drop(conn); 2562769be974SMarcel Holtmann } 2563769be974SMarcel Holtmann } 2564769be974SMarcel Holtmann 2565769be974SMarcel Holtmann hci_dev_unlock(hdev); 2566769be974SMarcel Holtmann } 2567769be974SMarcel Holtmann 2568a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) 2569a9de9248SMarcel Holtmann { 2570b6a0dc82SMarcel Holtmann struct hci_cp_setup_sync_conn *cp; 2571b6a0dc82SMarcel Holtmann struct hci_conn *acl, *sco; 2572b6a0dc82SMarcel Holtmann __u16 handle; 2573b6a0dc82SMarcel Holtmann 2574147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2575b6a0dc82SMarcel Holtmann 2576b6a0dc82SMarcel Holtmann if (!status) 2577b6a0dc82SMarcel Holtmann return; 2578b6a0dc82SMarcel Holtmann 2579b6a0dc82SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN); 2580b6a0dc82SMarcel Holtmann if (!cp) 2581b6a0dc82SMarcel Holtmann return; 2582b6a0dc82SMarcel Holtmann 2583b6a0dc82SMarcel Holtmann handle = __le16_to_cpu(cp->handle); 2584b6a0dc82SMarcel Holtmann 2585147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%4.4x", handle); 2586b6a0dc82SMarcel Holtmann 2587b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 2588b6a0dc82SMarcel Holtmann 2589b6a0dc82SMarcel Holtmann acl = hci_conn_hash_lookup_handle(hdev, handle); 25905a08ecceSAndrei Emeltchenko if (acl) { 25915a08ecceSAndrei Emeltchenko sco = acl->link; 25925a08ecceSAndrei Emeltchenko if (sco) { 2593b6a0dc82SMarcel Holtmann sco->state = BT_CLOSED; 2594b6a0dc82SMarcel Holtmann 2595539c496dSJohan Hedberg hci_connect_cfm(sco, status); 2596b6a0dc82SMarcel Holtmann hci_conn_del(sco); 2597b6a0dc82SMarcel Holtmann } 25985a08ecceSAndrei Emeltchenko } 2599b6a0dc82SMarcel Holtmann 2600b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 2601a9de9248SMarcel Holtmann } 2602a9de9248SMarcel Holtmann 2603b2af264aSKiran K static void hci_cs_enhanced_setup_sync_conn(struct hci_dev *hdev, __u8 status) 2604b2af264aSKiran K { 2605b2af264aSKiran K struct hci_cp_enhanced_setup_sync_conn *cp; 2606b2af264aSKiran K struct hci_conn *acl, *sco; 2607b2af264aSKiran K __u16 handle; 2608b2af264aSKiran K 2609b2af264aSKiran K bt_dev_dbg(hdev, "status 0x%2.2x", status); 2610b2af264aSKiran K 2611b2af264aSKiran K if (!status) 2612b2af264aSKiran K return; 2613b2af264aSKiran K 2614b2af264aSKiran K cp = hci_sent_cmd_data(hdev, HCI_OP_ENHANCED_SETUP_SYNC_CONN); 2615b2af264aSKiran K if (!cp) 2616b2af264aSKiran K return; 2617b2af264aSKiran K 2618b2af264aSKiran K handle = __le16_to_cpu(cp->handle); 2619b2af264aSKiran K 2620b2af264aSKiran K bt_dev_dbg(hdev, "handle 0x%4.4x", handle); 2621b2af264aSKiran K 2622b2af264aSKiran K hci_dev_lock(hdev); 2623b2af264aSKiran K 2624b2af264aSKiran K acl = hci_conn_hash_lookup_handle(hdev, handle); 2625b2af264aSKiran K if (acl) { 2626b2af264aSKiran K sco = acl->link; 2627b2af264aSKiran K if (sco) { 2628b2af264aSKiran K sco->state = BT_CLOSED; 2629b2af264aSKiran K 2630b2af264aSKiran K hci_connect_cfm(sco, status); 2631b2af264aSKiran K hci_conn_del(sco); 2632b2af264aSKiran K } 2633b2af264aSKiran K } 2634b2af264aSKiran K 2635b2af264aSKiran K hci_dev_unlock(hdev); 2636b2af264aSKiran K } 2637b2af264aSKiran K 2638a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) 2639a9de9248SMarcel Holtmann { 2640a9de9248SMarcel Holtmann struct hci_cp_sniff_mode *cp; 264104837f64SMarcel Holtmann struct hci_conn *conn; 264204837f64SMarcel Holtmann 2643147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2644a9de9248SMarcel Holtmann 2645a9de9248SMarcel Holtmann if (!status) 2646a9de9248SMarcel Holtmann return; 2647a9de9248SMarcel Holtmann 2648a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE); 264904837f64SMarcel Holtmann if (!cp) 2650a9de9248SMarcel Holtmann return; 265104837f64SMarcel Holtmann 265204837f64SMarcel Holtmann hci_dev_lock(hdev); 265304837f64SMarcel Holtmann 265404837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2655e73439d8SMarcel Holtmann if (conn) { 265651a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 265704837f64SMarcel Holtmann 265851a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 2659e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 2660e73439d8SMarcel Holtmann } 2661e73439d8SMarcel Holtmann 266204837f64SMarcel Holtmann hci_dev_unlock(hdev); 266304837f64SMarcel Holtmann } 266404837f64SMarcel Holtmann 2665a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) 2666a9de9248SMarcel Holtmann { 2667a9de9248SMarcel Holtmann struct hci_cp_exit_sniff_mode *cp; 266804837f64SMarcel Holtmann struct hci_conn *conn; 266904837f64SMarcel Holtmann 2670147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2671a9de9248SMarcel Holtmann 2672a9de9248SMarcel Holtmann if (!status) 2673a9de9248SMarcel Holtmann return; 2674a9de9248SMarcel Holtmann 2675a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE); 267604837f64SMarcel Holtmann if (!cp) 2677a9de9248SMarcel Holtmann return; 267804837f64SMarcel Holtmann 267904837f64SMarcel Holtmann hci_dev_lock(hdev); 268004837f64SMarcel Holtmann 268104837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2682e73439d8SMarcel Holtmann if (conn) { 268351a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags); 268404837f64SMarcel Holtmann 268551a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 2686e73439d8SMarcel Holtmann hci_sco_setup(conn, status); 2687e73439d8SMarcel Holtmann } 2688e73439d8SMarcel Holtmann 268904837f64SMarcel Holtmann hci_dev_unlock(hdev); 269004837f64SMarcel Holtmann } 269104837f64SMarcel Holtmann 269288c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) 269388c3df13SJohan Hedberg { 269488c3df13SJohan Hedberg struct hci_cp_disconnect *cp; 2695182ee45dSLuiz Augusto von Dentz struct hci_conn_params *params; 269688c3df13SJohan Hedberg struct hci_conn *conn; 2697182ee45dSLuiz Augusto von Dentz bool mgmt_conn; 269888c3df13SJohan Hedberg 2699147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2700147306ccSLuiz Augusto von Dentz 2701182ee45dSLuiz Augusto von Dentz /* Wait for HCI_EV_DISCONN_COMPLETE if status 0x00 and not suspended 2702182ee45dSLuiz Augusto von Dentz * otherwise cleanup the connection immediately. 2703182ee45dSLuiz Augusto von Dentz */ 2704182ee45dSLuiz Augusto von Dentz if (!status && !hdev->suspended) 270588c3df13SJohan Hedberg return; 270688c3df13SJohan Hedberg 270788c3df13SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT); 270888c3df13SJohan Hedberg if (!cp) 270988c3df13SJohan Hedberg return; 271088c3df13SJohan Hedberg 271188c3df13SJohan Hedberg hci_dev_lock(hdev); 271288c3df13SJohan Hedberg 271388c3df13SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 2714182ee45dSLuiz Augusto von Dentz if (!conn) 2715182ee45dSLuiz Augusto von Dentz goto unlock; 2716182ee45dSLuiz Augusto von Dentz 2717182ee45dSLuiz Augusto von Dentz if (status) { 271888c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 271988c3df13SJohan Hedberg conn->dst_type, status); 272088c3df13SJohan Hedberg 27211eeaa1aeSLuiz Augusto von Dentz if (conn->type == LE_LINK && conn->role == HCI_ROLE_SLAVE) { 27227087c4f6SLuiz Augusto von Dentz hdev->cur_adv_instance = conn->adv_instance; 2723abfeea47SLuiz Augusto von Dentz hci_enable_advertising(hdev); 27247087c4f6SLuiz Augusto von Dentz } 27257087c4f6SLuiz Augusto von Dentz 2726182ee45dSLuiz Augusto von Dentz goto done; 2727182ee45dSLuiz Augusto von Dentz } 2728182ee45dSLuiz Augusto von Dentz 2729182ee45dSLuiz Augusto von Dentz mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags); 2730182ee45dSLuiz Augusto von Dentz 2731182ee45dSLuiz Augusto von Dentz if (conn->type == ACL_LINK) { 2732182ee45dSLuiz Augusto von Dentz if (test_bit(HCI_CONN_FLUSH_KEY, &conn->flags)) 2733182ee45dSLuiz Augusto von Dentz hci_remove_link_key(hdev, &conn->dst); 2734182ee45dSLuiz Augusto von Dentz } 2735182ee45dSLuiz Augusto von Dentz 2736182ee45dSLuiz Augusto von Dentz params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); 2737182ee45dSLuiz Augusto von Dentz if (params) { 2738182ee45dSLuiz Augusto von Dentz switch (params->auto_connect) { 2739182ee45dSLuiz Augusto von Dentz case HCI_AUTO_CONN_LINK_LOSS: 2740182ee45dSLuiz Augusto von Dentz if (cp->reason != HCI_ERROR_CONNECTION_TIMEOUT) 2741182ee45dSLuiz Augusto von Dentz break; 2742182ee45dSLuiz Augusto von Dentz fallthrough; 2743182ee45dSLuiz Augusto von Dentz 2744182ee45dSLuiz Augusto von Dentz case HCI_AUTO_CONN_DIRECT: 2745182ee45dSLuiz Augusto von Dentz case HCI_AUTO_CONN_ALWAYS: 2746182ee45dSLuiz Augusto von Dentz list_del_init(¶ms->action); 2747182ee45dSLuiz Augusto von Dentz list_add(¶ms->action, &hdev->pend_le_conns); 2748182ee45dSLuiz Augusto von Dentz break; 2749182ee45dSLuiz Augusto von Dentz 2750182ee45dSLuiz Augusto von Dentz default: 2751182ee45dSLuiz Augusto von Dentz break; 2752182ee45dSLuiz Augusto von Dentz } 2753182ee45dSLuiz Augusto von Dentz } 2754182ee45dSLuiz Augusto von Dentz 2755182ee45dSLuiz Augusto von Dentz mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type, 2756182ee45dSLuiz Augusto von Dentz cp->reason, mgmt_conn); 2757182ee45dSLuiz Augusto von Dentz 2758182ee45dSLuiz Augusto von Dentz hci_disconn_cfm(conn, cp->reason); 2759182ee45dSLuiz Augusto von Dentz 2760182ee45dSLuiz Augusto von Dentz done: 2761b8d29052SJoseph Hwang /* If the disconnection failed for any reason, the upper layer 2762b8d29052SJoseph Hwang * does not retry to disconnect in current implementation. 2763b8d29052SJoseph Hwang * Hence, we need to do some basic cleanup here and re-enable 2764b8d29052SJoseph Hwang * advertising if necessary. 2765b8d29052SJoseph Hwang */ 2766b8d29052SJoseph Hwang hci_conn_del(conn); 2767182ee45dSLuiz Augusto von Dentz unlock: 276888c3df13SJohan Hedberg hci_dev_unlock(hdev); 276988c3df13SJohan Hedberg } 277088c3df13SJohan Hedberg 2771d850bf08SLuiz Augusto von Dentz static u8 ev_bdaddr_type(struct hci_dev *hdev, u8 type, bool *resolved) 27724ec4d63bSLuiz Augusto von Dentz { 27734ec4d63bSLuiz Augusto von Dentz /* When using controller based address resolution, then the new 27744ec4d63bSLuiz Augusto von Dentz * address types 0x02 and 0x03 are used. These types need to be 27754ec4d63bSLuiz Augusto von Dentz * converted back into either public address or random address type 27764ec4d63bSLuiz Augusto von Dentz */ 27774ec4d63bSLuiz Augusto von Dentz switch (type) { 27784ec4d63bSLuiz Augusto von Dentz case ADDR_LE_DEV_PUBLIC_RESOLVED: 2779d850bf08SLuiz Augusto von Dentz if (resolved) 2780d850bf08SLuiz Augusto von Dentz *resolved = true; 27814ec4d63bSLuiz Augusto von Dentz return ADDR_LE_DEV_PUBLIC; 27824ec4d63bSLuiz Augusto von Dentz case ADDR_LE_DEV_RANDOM_RESOLVED: 2783d850bf08SLuiz Augusto von Dentz if (resolved) 2784d850bf08SLuiz Augusto von Dentz *resolved = true; 27854ec4d63bSLuiz Augusto von Dentz return ADDR_LE_DEV_RANDOM; 27864ec4d63bSLuiz Augusto von Dentz } 27874ec4d63bSLuiz Augusto von Dentz 2788d850bf08SLuiz Augusto von Dentz if (resolved) 2789d850bf08SLuiz Augusto von Dentz *resolved = false; 27904ec4d63bSLuiz Augusto von Dentz return type; 27914ec4d63bSLuiz Augusto von Dentz } 27924ec4d63bSLuiz Augusto von Dentz 2793d12fb056SJaganath Kanakkassery static void cs_le_create_conn(struct hci_dev *hdev, bdaddr_t *peer_addr, 2794d12fb056SJaganath Kanakkassery u8 peer_addr_type, u8 own_address_type, 2795d12fb056SJaganath Kanakkassery u8 filter_policy) 2796d12fb056SJaganath Kanakkassery { 2797d12fb056SJaganath Kanakkassery struct hci_conn *conn; 2798d12fb056SJaganath Kanakkassery 2799d12fb056SJaganath Kanakkassery conn = hci_conn_hash_lookup_le(hdev, peer_addr, 2800d12fb056SJaganath Kanakkassery peer_addr_type); 2801d12fb056SJaganath Kanakkassery if (!conn) 2802d12fb056SJaganath Kanakkassery return; 2803d12fb056SJaganath Kanakkassery 2804d850bf08SLuiz Augusto von Dentz own_address_type = ev_bdaddr_type(hdev, own_address_type, NULL); 2805b31bc00bSSathish Narasimman 2806d12fb056SJaganath Kanakkassery /* Store the initiator and responder address information which 2807d12fb056SJaganath Kanakkassery * is needed for SMP. These values will not change during the 2808d12fb056SJaganath Kanakkassery * lifetime of the connection. 2809d12fb056SJaganath Kanakkassery */ 2810d12fb056SJaganath Kanakkassery conn->init_addr_type = own_address_type; 2811d12fb056SJaganath Kanakkassery if (own_address_type == ADDR_LE_DEV_RANDOM) 2812d12fb056SJaganath Kanakkassery bacpy(&conn->init_addr, &hdev->random_addr); 2813d12fb056SJaganath Kanakkassery else 2814d12fb056SJaganath Kanakkassery bacpy(&conn->init_addr, &hdev->bdaddr); 2815d12fb056SJaganath Kanakkassery 2816d12fb056SJaganath Kanakkassery conn->resp_addr_type = peer_addr_type; 2817d12fb056SJaganath Kanakkassery bacpy(&conn->resp_addr, peer_addr); 2818d12fb056SJaganath Kanakkassery 2819d12fb056SJaganath Kanakkassery /* We don't want the connection attempt to stick around 2820d12fb056SJaganath Kanakkassery * indefinitely since LE doesn't have a page timeout concept 2821d12fb056SJaganath Kanakkassery * like BR/EDR. Set a timer for any connection that doesn't use 28223d4f9c00SArchie Pusaka * the accept list for connecting. 2823d12fb056SJaganath Kanakkassery */ 2824d12fb056SJaganath Kanakkassery if (filter_policy == HCI_LE_USE_PEER_ADDR) 2825d12fb056SJaganath Kanakkassery queue_delayed_work(conn->hdev->workqueue, 2826d12fb056SJaganath Kanakkassery &conn->le_conn_timeout, 2827d12fb056SJaganath Kanakkassery conn->conn_timeout); 2828d12fb056SJaganath Kanakkassery } 2829d12fb056SJaganath Kanakkassery 2830cb1d68f7SJohan Hedberg static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status) 2831cb1d68f7SJohan Hedberg { 2832cb1d68f7SJohan Hedberg struct hci_cp_le_create_conn *cp; 2833cb1d68f7SJohan Hedberg 2834147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 2835cb1d68f7SJohan Hedberg 2836cb1d68f7SJohan Hedberg /* All connection failure handling is taken care of by the 2837cb1d68f7SJohan Hedberg * hci_le_conn_failed function which is triggered by the HCI 2838cb1d68f7SJohan Hedberg * request completion callbacks used for connecting. 2839cb1d68f7SJohan Hedberg */ 2840cb1d68f7SJohan Hedberg if (status) 2841cb1d68f7SJohan Hedberg return; 2842cb1d68f7SJohan Hedberg 2843cb1d68f7SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN); 2844cb1d68f7SJohan Hedberg if (!cp) 2845cb1d68f7SJohan Hedberg return; 2846cb1d68f7SJohan Hedberg 2847cb1d68f7SJohan Hedberg hci_dev_lock(hdev); 2848cb1d68f7SJohan Hedberg 2849d12fb056SJaganath Kanakkassery cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type, 2850d12fb056SJaganath Kanakkassery cp->own_address_type, cp->filter_policy); 2851cb1d68f7SJohan Hedberg 2852cb1d68f7SJohan Hedberg hci_dev_unlock(hdev); 2853cb1d68f7SJohan Hedberg } 2854cb1d68f7SJohan Hedberg 28554d94f95dSJaganath Kanakkassery static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status) 28564d94f95dSJaganath Kanakkassery { 28574d94f95dSJaganath Kanakkassery struct hci_cp_le_ext_create_conn *cp; 28584d94f95dSJaganath Kanakkassery 2859147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 28604d94f95dSJaganath Kanakkassery 28614d94f95dSJaganath Kanakkassery /* All connection failure handling is taken care of by the 28624d94f95dSJaganath Kanakkassery * hci_le_conn_failed function which is triggered by the HCI 28634d94f95dSJaganath Kanakkassery * request completion callbacks used for connecting. 28644d94f95dSJaganath Kanakkassery */ 28654d94f95dSJaganath Kanakkassery if (status) 28664d94f95dSJaganath Kanakkassery return; 28674d94f95dSJaganath Kanakkassery 28684d94f95dSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_EXT_CREATE_CONN); 28694d94f95dSJaganath Kanakkassery if (!cp) 28704d94f95dSJaganath Kanakkassery return; 28714d94f95dSJaganath Kanakkassery 28724d94f95dSJaganath Kanakkassery hci_dev_lock(hdev); 28734d94f95dSJaganath Kanakkassery 28744d94f95dSJaganath Kanakkassery cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type, 28754d94f95dSJaganath Kanakkassery cp->own_addr_type, cp->filter_policy); 28764d94f95dSJaganath Kanakkassery 28774d94f95dSJaganath Kanakkassery hci_dev_unlock(hdev); 28784d94f95dSJaganath Kanakkassery } 28794d94f95dSJaganath Kanakkassery 28800fe29fd1SMarcel Holtmann static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status) 28810fe29fd1SMarcel Holtmann { 28820fe29fd1SMarcel Holtmann struct hci_cp_le_read_remote_features *cp; 28830fe29fd1SMarcel Holtmann struct hci_conn *conn; 28840fe29fd1SMarcel Holtmann 2885147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 28860fe29fd1SMarcel Holtmann 28870fe29fd1SMarcel Holtmann if (!status) 28880fe29fd1SMarcel Holtmann return; 28890fe29fd1SMarcel Holtmann 28900fe29fd1SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_READ_REMOTE_FEATURES); 28910fe29fd1SMarcel Holtmann if (!cp) 28920fe29fd1SMarcel Holtmann return; 28930fe29fd1SMarcel Holtmann 28940fe29fd1SMarcel Holtmann hci_dev_lock(hdev); 28950fe29fd1SMarcel Holtmann 28960fe29fd1SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 28970fe29fd1SMarcel Holtmann if (conn) { 28980fe29fd1SMarcel Holtmann if (conn->state == BT_CONFIG) { 28990fe29fd1SMarcel Holtmann hci_connect_cfm(conn, status); 29000fe29fd1SMarcel Holtmann hci_conn_drop(conn); 29010fe29fd1SMarcel Holtmann } 29020fe29fd1SMarcel Holtmann } 29030fe29fd1SMarcel Holtmann 29040fe29fd1SMarcel Holtmann hci_dev_unlock(hdev); 29050fe29fd1SMarcel Holtmann } 29060fe29fd1SMarcel Holtmann 290781d0c8adSJohan Hedberg static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) 290881d0c8adSJohan Hedberg { 290981d0c8adSJohan Hedberg struct hci_cp_le_start_enc *cp; 291081d0c8adSJohan Hedberg struct hci_conn *conn; 291181d0c8adSJohan Hedberg 2912147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status); 291381d0c8adSJohan Hedberg 291481d0c8adSJohan Hedberg if (!status) 291581d0c8adSJohan Hedberg return; 291681d0c8adSJohan Hedberg 291781d0c8adSJohan Hedberg hci_dev_lock(hdev); 291881d0c8adSJohan Hedberg 291981d0c8adSJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC); 292081d0c8adSJohan Hedberg if (!cp) 292181d0c8adSJohan Hedberg goto unlock; 292281d0c8adSJohan Hedberg 292381d0c8adSJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 292481d0c8adSJohan Hedberg if (!conn) 292581d0c8adSJohan Hedberg goto unlock; 292681d0c8adSJohan Hedberg 292781d0c8adSJohan Hedberg if (conn->state != BT_CONNECTED) 292881d0c8adSJohan Hedberg goto unlock; 292981d0c8adSJohan Hedberg 293081d0c8adSJohan Hedberg hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 293181d0c8adSJohan Hedberg hci_conn_drop(conn); 293281d0c8adSJohan Hedberg 293381d0c8adSJohan Hedberg unlock: 293481d0c8adSJohan Hedberg hci_dev_unlock(hdev); 293581d0c8adSJohan Hedberg } 293681d0c8adSJohan Hedberg 293750fc85f1SKuba Pawlak static void hci_cs_switch_role(struct hci_dev *hdev, u8 status) 293850fc85f1SKuba Pawlak { 293950fc85f1SKuba Pawlak struct hci_cp_switch_role *cp; 294050fc85f1SKuba Pawlak struct hci_conn *conn; 294150fc85f1SKuba Pawlak 294250fc85f1SKuba Pawlak BT_DBG("%s status 0x%2.2x", hdev->name, status); 294350fc85f1SKuba Pawlak 294450fc85f1SKuba Pawlak if (!status) 294550fc85f1SKuba Pawlak return; 294650fc85f1SKuba Pawlak 294750fc85f1SKuba Pawlak cp = hci_sent_cmd_data(hdev, HCI_OP_SWITCH_ROLE); 294850fc85f1SKuba Pawlak if (!cp) 294950fc85f1SKuba Pawlak return; 295050fc85f1SKuba Pawlak 295150fc85f1SKuba Pawlak hci_dev_lock(hdev); 295250fc85f1SKuba Pawlak 295350fc85f1SKuba Pawlak conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 295450fc85f1SKuba Pawlak if (conn) 295550fc85f1SKuba Pawlak clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 295650fc85f1SKuba Pawlak 295750fc85f1SKuba Pawlak hci_dev_unlock(hdev); 295850fc85f1SKuba Pawlak } 295950fc85f1SKuba Pawlak 29603e54c589SLuiz Augusto von Dentz static void hci_inquiry_complete_evt(struct hci_dev *hdev, void *data, 29613e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 29621da177e4SLinus Torvalds { 29633e54c589SLuiz Augusto von Dentz struct hci_ev_status *ev = data; 296430dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery; 296530dc78e1SJohan Hedberg struct inquiry_entry *e; 29661da177e4SLinus Torvalds 29673e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 29681da177e4SLinus Torvalds 2969a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 297089352e7dSAndre Guedes 297189352e7dSAndre Guedes if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) 297289352e7dSAndre Guedes return; 297389352e7dSAndre Guedes 29744e857c58SPeter Zijlstra smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */ 29753e13fa1eSAndre Guedes wake_up_bit(&hdev->flags, HCI_INQUIRY); 29763e13fa1eSAndre Guedes 2977d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 297830dc78e1SJohan Hedberg return; 297930dc78e1SJohan Hedberg 298056e5cb86SJohan Hedberg hci_dev_lock(hdev); 298130dc78e1SJohan Hedberg 2982343f935bSAndre Guedes if (discov->state != DISCOVERY_FINDING) 298330dc78e1SJohan Hedberg goto unlock; 298430dc78e1SJohan Hedberg 298530dc78e1SJohan Hedberg if (list_empty(&discov->resolve)) { 298607d2334aSJakub Pawlowski /* When BR/EDR inquiry is active and no LE scanning is in 298707d2334aSJakub Pawlowski * progress, then change discovery state to indicate completion. 298807d2334aSJakub Pawlowski * 298907d2334aSJakub Pawlowski * When running LE scanning and BR/EDR inquiry simultaneously 299007d2334aSJakub Pawlowski * and the LE scan already finished, then change the discovery 299107d2334aSJakub Pawlowski * state to indicate completion. 299207d2334aSJakub Pawlowski */ 299307d2334aSJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) || 299407d2334aSJakub Pawlowski !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks)) 2995ff9ef578SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 299630dc78e1SJohan Hedberg goto unlock; 299730dc78e1SJohan Hedberg } 299830dc78e1SJohan Hedberg 299930dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); 300030dc78e1SJohan Hedberg if (e && hci_resolve_name(hdev, e) == 0) { 300130dc78e1SJohan Hedberg e->name_state = NAME_PENDING; 300230dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_RESOLVING); 3003dbf6811aSArchie Pusaka discov->name_resolve_timeout = jiffies + NAME_RESOLVE_DURATION; 300430dc78e1SJohan Hedberg } else { 300507d2334aSJakub Pawlowski /* When BR/EDR inquiry is active and no LE scanning is in 300607d2334aSJakub Pawlowski * progress, then change discovery state to indicate completion. 300707d2334aSJakub Pawlowski * 300807d2334aSJakub Pawlowski * When running LE scanning and BR/EDR inquiry simultaneously 300907d2334aSJakub Pawlowski * and the LE scan already finished, then change the discovery 301007d2334aSJakub Pawlowski * state to indicate completion. 301107d2334aSJakub Pawlowski */ 301207d2334aSJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) || 301307d2334aSJakub Pawlowski !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks)) 301430dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 301530dc78e1SJohan Hedberg } 301630dc78e1SJohan Hedberg 301730dc78e1SJohan Hedberg unlock: 301856e5cb86SJohan Hedberg hci_dev_unlock(hdev); 30191da177e4SLinus Torvalds } 30201da177e4SLinus Torvalds 30213e54c589SLuiz Augusto von Dentz static void hci_inquiry_result_evt(struct hci_dev *hdev, void *edata, 30223e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 30231da177e4SLinus Torvalds { 30243e54c589SLuiz Augusto von Dentz struct hci_ev_inquiry_result *ev = edata; 302545bb4bf0SMarcel Holtmann struct inquiry_data data; 302627d9eb4bSLuiz Augusto von Dentz int i; 30271da177e4SLinus Torvalds 302827d9eb4bSLuiz Augusto von Dentz if (!hci_ev_skb_pull(hdev, skb, HCI_EV_INQUIRY_RESULT, 302927d9eb4bSLuiz Augusto von Dentz flex_array_size(ev, info, ev->num))) 303027d9eb4bSLuiz Augusto von Dentz return; 303127d9eb4bSLuiz Augusto von Dentz 30323e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "num %d", ev->num); 303327d9eb4bSLuiz Augusto von Dentz 303427d9eb4bSLuiz Augusto von Dentz if (!ev->num) 303545bb4bf0SMarcel Holtmann return; 303645bb4bf0SMarcel Holtmann 3037d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) 30381519cc17SAndre Guedes return; 30391519cc17SAndre Guedes 30401da177e4SLinus Torvalds hci_dev_lock(hdev); 304145bb4bf0SMarcel Holtmann 304227d9eb4bSLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) { 304327d9eb4bSLuiz Augusto von Dentz struct inquiry_info *info = &ev->info[i]; 3044af58925cSMarcel Holtmann u32 flags; 30453175405bSJohan Hedberg 30461da177e4SLinus Torvalds bacpy(&data.bdaddr, &info->bdaddr); 30471da177e4SLinus Torvalds data.pscan_rep_mode = info->pscan_rep_mode; 30481da177e4SLinus Torvalds data.pscan_period_mode = info->pscan_period_mode; 30491da177e4SLinus Torvalds data.pscan_mode = info->pscan_mode; 30501da177e4SLinus Torvalds memcpy(data.dev_class, info->dev_class, 3); 30511da177e4SLinus Torvalds data.clock_offset = info->clock_offset; 3052efb2513fSMarcel Holtmann data.rssi = HCI_RSSI_INVALID; 305341a96212SMarcel Holtmann data.ssp_mode = 0x00; 30543175405bSJohan Hedberg 3055af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 3056af58925cSMarcel Holtmann 305748264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3058efb2513fSMarcel Holtmann info->dev_class, HCI_RSSI_INVALID, 3059efb2513fSMarcel Holtmann flags, NULL, 0, NULL, 0); 30601da177e4SLinus Torvalds } 306145bb4bf0SMarcel Holtmann 30621da177e4SLinus Torvalds hci_dev_unlock(hdev); 30631da177e4SLinus Torvalds } 30641da177e4SLinus Torvalds 30653e54c589SLuiz Augusto von Dentz static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, 30663e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 30671da177e4SLinus Torvalds { 30683e54c589SLuiz Augusto von Dentz struct hci_ev_conn_complete *ev = data; 3069a9de9248SMarcel Holtmann struct hci_conn *conn; 30701da177e4SLinus Torvalds 30713e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 307245bb4bf0SMarcel Holtmann 30731da177e4SLinus Torvalds hci_dev_lock(hdev); 307445bb4bf0SMarcel Holtmann 3075a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 30769499237aSMarcel Holtmann if (!conn) { 3077a46b7ed4SSonny Sasaka /* Connection may not exist if auto-connected. Check the bredr 3078a46b7ed4SSonny Sasaka * allowlist to see if this device is allowed to auto connect. 3079a46b7ed4SSonny Sasaka * If link is an ACL type, create a connection class 30804f40afc6SAbhishek Pandit-Subedi * automatically. 3081a46b7ed4SSonny Sasaka * 3082a46b7ed4SSonny Sasaka * Auto-connect will only occur if the event filter is 3083a46b7ed4SSonny Sasaka * programmed with a given address. Right now, event filter is 3084a46b7ed4SSonny Sasaka * only used during suspend. 30854f40afc6SAbhishek Pandit-Subedi */ 3086a46b7ed4SSonny Sasaka if (ev->link_type == ACL_LINK && 30873d4f9c00SArchie Pusaka hci_bdaddr_list_lookup_with_flags(&hdev->accept_list, 3088a46b7ed4SSonny Sasaka &ev->bdaddr, 3089a46b7ed4SSonny Sasaka BDADDR_BREDR)) { 30904f40afc6SAbhishek Pandit-Subedi conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr, 30914f40afc6SAbhishek Pandit-Subedi HCI_ROLE_SLAVE); 30924f40afc6SAbhishek Pandit-Subedi if (!conn) { 30934f40afc6SAbhishek Pandit-Subedi bt_dev_err(hdev, "no memory for new conn"); 30944f40afc6SAbhishek Pandit-Subedi goto unlock; 30954f40afc6SAbhishek Pandit-Subedi } 30962d186fcdSAbhishek Pandit-Subedi } else { 30979499237aSMarcel Holtmann if (ev->link_type != SCO_LINK) 30989499237aSMarcel Holtmann goto unlock; 30999499237aSMarcel Holtmann 31002d186fcdSAbhishek Pandit-Subedi conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, 31012d186fcdSAbhishek Pandit-Subedi &ev->bdaddr); 3102a9de9248SMarcel Holtmann if (!conn) 3103a9de9248SMarcel Holtmann goto unlock; 310445bb4bf0SMarcel Holtmann 31059499237aSMarcel Holtmann conn->type = SCO_LINK; 31069499237aSMarcel Holtmann } 31072d186fcdSAbhishek Pandit-Subedi } 31089499237aSMarcel Holtmann 3109a9de9248SMarcel Holtmann if (!ev->status) { 3110a9de9248SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 3111769be974SMarcel Holtmann 3112769be974SMarcel Holtmann if (conn->type == ACL_LINK) { 3113769be974SMarcel Holtmann conn->state = BT_CONFIG; 3114769be974SMarcel Holtmann hci_conn_hold(conn); 3115a9ea3ed9SSzymon Janc 3116a9ea3ed9SSzymon Janc if (!conn->out && !hci_conn_ssp_enabled(conn) && 3117a9ea3ed9SSzymon Janc !hci_find_link_key(hdev, &ev->bdaddr)) 3118a9ea3ed9SSzymon Janc conn->disc_timeout = HCI_PAIRING_TIMEOUT; 3119a9ea3ed9SSzymon Janc else 3120052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 3121769be974SMarcel Holtmann } else 3122a9de9248SMarcel Holtmann conn->state = BT_CONNECTED; 3123a9de9248SMarcel Holtmann 312423b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn); 31257d0db0a3SMarcel Holtmann hci_conn_add_sysfs(conn); 31267d0db0a3SMarcel Holtmann 3127a9de9248SMarcel Holtmann if (test_bit(HCI_AUTH, &hdev->flags)) 31284dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 3129a9de9248SMarcel Holtmann 3130a9de9248SMarcel Holtmann if (test_bit(HCI_ENCRYPT, &hdev->flags)) 31314dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags); 3132a9de9248SMarcel Holtmann 3133a9de9248SMarcel Holtmann /* Get remote features */ 3134a9de9248SMarcel Holtmann if (conn->type == ACL_LINK) { 3135a9de9248SMarcel Holtmann struct hci_cp_read_remote_features cp; 3136a9de9248SMarcel Holtmann cp.handle = ev->handle; 3137769be974SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, 3138769be974SMarcel Holtmann sizeof(cp), &cp); 313922f433dcSJohan Hedberg 314001b1cb87SJohan Hedberg hci_req_update_scan(hdev); 314145bb4bf0SMarcel Holtmann } 3142a9de9248SMarcel Holtmann 3143a9de9248SMarcel Holtmann /* Set packet type for incoming connection */ 3144d095c1ebSAndrei Emeltchenko if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) { 3145a9de9248SMarcel Holtmann struct hci_cp_change_conn_ptype cp; 3146a9de9248SMarcel Holtmann cp.handle = ev->handle; 3147a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 314804124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), 314904124681SGustavo F. Padovan &cp); 3150a9de9248SMarcel Holtmann } 315117d5c04cSJohan Hedberg } else { 3152a9de9248SMarcel Holtmann conn->state = BT_CLOSED; 315317d5c04cSJohan Hedberg if (conn->type == ACL_LINK) 315464c7b77cSMarcel Holtmann mgmt_connect_failed(hdev, &conn->dst, conn->type, 315548264f06SJohan Hedberg conn->dst_type, ev->status); 315617d5c04cSJohan Hedberg } 315745bb4bf0SMarcel Holtmann 3158e73439d8SMarcel Holtmann if (conn->type == ACL_LINK) 3159e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 316045bb4bf0SMarcel Holtmann 3161769be974SMarcel Holtmann if (ev->status) { 3162539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 3163a9de9248SMarcel Holtmann hci_conn_del(conn); 31641f8330eaSSathish Narsimman } else if (ev->link_type == SCO_LINK) { 31651f8330eaSSathish Narsimman switch (conn->setting & SCO_AIRMODE_MASK) { 31661f8330eaSSathish Narsimman case SCO_AIRMODE_CVSD: 31671f8330eaSSathish Narsimman if (hdev->notify) 31681f8330eaSSathish Narsimman hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD); 31691f8330eaSSathish Narsimman break; 31701f8330eaSSathish Narsimman } 31711f8330eaSSathish Narsimman 3172539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 31731f8330eaSSathish Narsimman } 3174a9de9248SMarcel Holtmann 3175a9de9248SMarcel Holtmann unlock: 31761da177e4SLinus Torvalds hci_dev_unlock(hdev); 3177a9de9248SMarcel Holtmann 3178a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 31791da177e4SLinus Torvalds } 31801da177e4SLinus Torvalds 318170c46425SJohan Hedberg static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr) 318270c46425SJohan Hedberg { 318370c46425SJohan Hedberg struct hci_cp_reject_conn_req cp; 318470c46425SJohan Hedberg 318570c46425SJohan Hedberg bacpy(&cp.bdaddr, bdaddr); 318670c46425SJohan Hedberg cp.reason = HCI_ERROR_REJ_BAD_ADDR; 318770c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); 318870c46425SJohan Hedberg } 318970c46425SJohan Hedberg 31903e54c589SLuiz Augusto von Dentz static void hci_conn_request_evt(struct hci_dev *hdev, void *data, 31913e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 31921da177e4SLinus Torvalds { 31933e54c589SLuiz Augusto von Dentz struct hci_ev_conn_request *ev = data; 31941da177e4SLinus Torvalds int mask = hdev->link_mode; 319570c46425SJohan Hedberg struct inquiry_entry *ie; 319670c46425SJohan Hedberg struct hci_conn *conn; 319720714bfeSFrédéric Dalleau __u8 flags = 0; 31981da177e4SLinus Torvalds 31993e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type); 32001da177e4SLinus Torvalds 320120714bfeSFrédéric Dalleau mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type, 320220714bfeSFrédéric Dalleau &flags); 32031da177e4SLinus Torvalds 320470c46425SJohan Hedberg if (!(mask & HCI_LM_ACCEPT)) { 320570c46425SJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 320670c46425SJohan Hedberg return; 320770c46425SJohan Hedberg } 320870c46425SJohan Hedberg 32093d4f9c00SArchie Pusaka if (hci_bdaddr_list_lookup(&hdev->reject_list, &ev->bdaddr, 3210dcc36c16SJohan Hedberg BDADDR_BREDR)) { 321170c46425SJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 321270c46425SJohan Hedberg return; 321370c46425SJohan Hedberg } 321446c4c941SJohan Hedberg 32153d4f9c00SArchie Pusaka /* Require HCI_CONNECTABLE or an accept list entry to accept the 32166a8fc95cSJohan Hedberg * connection. These features are only touched through mgmt so 32176a8fc95cSJohan Hedberg * only do the checks if HCI_MGMT is set. 32186a8fc95cSJohan Hedberg */ 3219d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT) && 3220d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONNECTABLE) && 32213d4f9c00SArchie Pusaka !hci_bdaddr_list_lookup_with_flags(&hdev->accept_list, &ev->bdaddr, 3222a55bd29dSJohan Hedberg BDADDR_BREDR)) { 3223a55bd29dSJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr); 3224a55bd29dSJohan Hedberg return; 3225a55bd29dSJohan Hedberg } 322670c46425SJohan Hedberg 32271da177e4SLinus Torvalds /* Connection accepted */ 32281da177e4SLinus Torvalds 32291da177e4SLinus Torvalds hci_dev_lock(hdev); 3230b6a0dc82SMarcel Holtmann 3231cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 3232cc11b9c1SAndrei Emeltchenko if (ie) 3233c7bdd502SMarcel Holtmann memcpy(ie->data.dev_class, ev->dev_class, 3); 3234c7bdd502SMarcel Holtmann 32358fc9ced3SGustavo Padovan conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, 32368fc9ced3SGustavo Padovan &ev->bdaddr); 32371da177e4SLinus Torvalds if (!conn) { 3238a5c4e309SJohan Hedberg conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr, 3239a5c4e309SJohan Hedberg HCI_ROLE_SLAVE); 3240cc11b9c1SAndrei Emeltchenko if (!conn) { 32412064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for new connection"); 32421da177e4SLinus Torvalds hci_dev_unlock(hdev); 32431da177e4SLinus Torvalds return; 32441da177e4SLinus Torvalds } 32451da177e4SLinus Torvalds } 3246b6a0dc82SMarcel Holtmann 32471da177e4SLinus Torvalds memcpy(conn->dev_class, ev->dev_class, 3); 3248b6a0dc82SMarcel Holtmann 32491da177e4SLinus Torvalds hci_dev_unlock(hdev); 32501da177e4SLinus Torvalds 325120714bfeSFrédéric Dalleau if (ev->link_type == ACL_LINK || 325220714bfeSFrédéric Dalleau (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) { 3253b6a0dc82SMarcel Holtmann struct hci_cp_accept_conn_req cp; 325420714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 3255b6a0dc82SMarcel Holtmann 32561da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr); 32571da177e4SLinus Torvalds 32581da177e4SLinus Torvalds if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) 325974be523cSArchie Pusaka cp.role = 0x00; /* Become central */ 32601da177e4SLinus Torvalds else 326174be523cSArchie Pusaka cp.role = 0x01; /* Remain peripheral */ 32621da177e4SLinus Torvalds 326370c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); 326420714bfeSFrédéric Dalleau } else if (!(flags & HCI_PROTO_DEFER)) { 3265b6a0dc82SMarcel Holtmann struct hci_cp_accept_sync_conn_req cp; 326620714bfeSFrédéric Dalleau conn->state = BT_CONNECT; 3267b6a0dc82SMarcel Holtmann 3268b6a0dc82SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 3269a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type); 3270b6a0dc82SMarcel Holtmann 3271dcf4adbfSJoe Perches cp.tx_bandwidth = cpu_to_le32(0x00001f40); 3272dcf4adbfSJoe Perches cp.rx_bandwidth = cpu_to_le32(0x00001f40); 3273dcf4adbfSJoe Perches cp.max_latency = cpu_to_le16(0xffff); 3274b6a0dc82SMarcel Holtmann cp.content_format = cpu_to_le16(hdev->voice_setting); 3275b6a0dc82SMarcel Holtmann cp.retrans_effort = 0xff; 3276b6a0dc82SMarcel Holtmann 327770c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp), 327870c46425SJohan Hedberg &cp); 327920714bfeSFrédéric Dalleau } else { 328020714bfeSFrédéric Dalleau conn->state = BT_CONNECT2; 3281539c496dSJohan Hedberg hci_connect_cfm(conn, 0); 3282b6a0dc82SMarcel Holtmann } 32831da177e4SLinus Torvalds } 32841da177e4SLinus Torvalds 3285f0d6a0eaSMikel Astiz static u8 hci_to_mgmt_reason(u8 err) 3286f0d6a0eaSMikel Astiz { 3287f0d6a0eaSMikel Astiz switch (err) { 3288f0d6a0eaSMikel Astiz case HCI_ERROR_CONNECTION_TIMEOUT: 3289f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_TIMEOUT; 3290f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_USER_TERM: 3291f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_LOW_RESOURCES: 3292f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_POWER_OFF: 3293f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_REMOTE; 3294f0d6a0eaSMikel Astiz case HCI_ERROR_LOCAL_HOST_TERM: 3295f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_LOCAL_HOST; 3296f0d6a0eaSMikel Astiz default: 3297f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_UNKNOWN; 3298f0d6a0eaSMikel Astiz } 3299f0d6a0eaSMikel Astiz } 3300f0d6a0eaSMikel Astiz 33013e54c589SLuiz Augusto von Dentz static void hci_disconn_complete_evt(struct hci_dev *hdev, void *data, 33023e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 33031da177e4SLinus Torvalds { 33043e54c589SLuiz Augusto von Dentz struct hci_ev_disconn_complete *ev = data; 3305160b9251SSzymon Janc u8 reason; 33069fcb18efSAndre Guedes struct hci_conn_params *params; 330704837f64SMarcel Holtmann struct hci_conn *conn; 330812d4a3b2SJohan Hedberg bool mgmt_connected; 33091da177e4SLinus Torvalds 33103e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 33111da177e4SLinus Torvalds 33121da177e4SLinus Torvalds hci_dev_lock(hdev); 33131da177e4SLinus Torvalds 331404837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3315f7520543SJohan Hedberg if (!conn) 3316f7520543SJohan Hedberg goto unlock; 3317f7520543SJohan Hedberg 3318f0d6a0eaSMikel Astiz if (ev->status) { 331988c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type, 332088c3df13SJohan Hedberg conn->dst_type, ev->status); 3321abf54a50SAndre Guedes goto unlock; 3322abf54a50SAndre Guedes } 3323f0d6a0eaSMikel Astiz 33243846220bSAndre Guedes conn->state = BT_CLOSED; 33253846220bSAndre Guedes 332612d4a3b2SJohan Hedberg mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags); 3327160b9251SSzymon Janc 3328160b9251SSzymon Janc if (test_bit(HCI_CONN_AUTH_FAILURE, &conn->flags)) 3329160b9251SSzymon Janc reason = MGMT_DEV_DISCONN_AUTH_FAILURE; 3330160b9251SSzymon Janc else 3331160b9251SSzymon Janc reason = hci_to_mgmt_reason(ev->reason); 3332160b9251SSzymon Janc 333312d4a3b2SJohan Hedberg mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type, 333412d4a3b2SJohan Hedberg reason, mgmt_connected); 3335f7520543SJohan Hedberg 333622f433dcSJohan Hedberg if (conn->type == ACL_LINK) { 333722f433dcSJohan Hedberg if (test_bit(HCI_CONN_FLUSH_KEY, &conn->flags)) 33386ec5bcadSVishal Agarwal hci_remove_link_key(hdev, &conn->dst); 33393846220bSAndre Guedes 334001b1cb87SJohan Hedberg hci_req_update_scan(hdev); 334122f433dcSJohan Hedberg } 334222f433dcSJohan Hedberg 33439fcb18efSAndre Guedes params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); 33449fcb18efSAndre Guedes if (params) { 33459fcb18efSAndre Guedes switch (params->auto_connect) { 33469fcb18efSAndre Guedes case HCI_AUTO_CONN_LINK_LOSS: 33479fcb18efSAndre Guedes if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT) 33489fcb18efSAndre Guedes break; 334919186c7bSGustavo A. R. Silva fallthrough; 33509fcb18efSAndre Guedes 33514b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_DIRECT: 33529fcb18efSAndre Guedes case HCI_AUTO_CONN_ALWAYS: 3353418025d1SJohan Hedberg list_del_init(¶ms->action); 3354418025d1SJohan Hedberg list_add(¶ms->action, &hdev->pend_le_conns); 33555bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan(hdev); 33569fcb18efSAndre Guedes break; 33579fcb18efSAndre Guedes 33589fcb18efSAndre Guedes default: 33599fcb18efSAndre Guedes break; 33609fcb18efSAndre Guedes } 33619fcb18efSAndre Guedes } 33629fcb18efSAndre Guedes 33633a6d576bSJohan Hedberg hci_disconn_cfm(conn, ev->reason); 33642210246cSJohan Hedberg 33652210246cSJohan Hedberg /* Re-enable advertising if necessary, since it might 33662210246cSJohan Hedberg * have been disabled by the connection. From the 33672210246cSJohan Hedberg * HCI_LE_Set_Advertise_Enable command description in 33682210246cSJohan Hedberg * the core specification (v4.0): 33692210246cSJohan Hedberg * "The Controller shall continue advertising until the Host 33702210246cSJohan Hedberg * issues an LE_Set_Advertise_Enable command with 33712210246cSJohan Hedberg * Advertising_Enable set to 0x00 (Advertising is disabled) 33722210246cSJohan Hedberg * or until a connection is created or until the Advertising 33732210246cSJohan Hedberg * is timed out due to Directed Advertising." 33742210246cSJohan Hedberg */ 33751eeaa1aeSLuiz Augusto von Dentz if (conn->type == LE_LINK && conn->role == HCI_ROLE_SLAVE) { 33767087c4f6SLuiz Augusto von Dentz hdev->cur_adv_instance = conn->adv_instance; 3377abfeea47SLuiz Augusto von Dentz hci_enable_advertising(hdev); 33787087c4f6SLuiz Augusto von Dentz } 33797087c4f6SLuiz Augusto von Dentz 33807087c4f6SLuiz Augusto von Dentz hci_conn_del(conn); 33811da177e4SLinus Torvalds 3382f7520543SJohan Hedberg unlock: 33831da177e4SLinus Torvalds hci_dev_unlock(hdev); 33841da177e4SLinus Torvalds } 33851da177e4SLinus Torvalds 33863e54c589SLuiz Augusto von Dentz static void hci_auth_complete_evt(struct hci_dev *hdev, void *data, 33873e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 3388a9de9248SMarcel Holtmann { 33893e54c589SLuiz Augusto von Dentz struct hci_ev_auth_complete *ev = data; 3390a9de9248SMarcel Holtmann struct hci_conn *conn; 3391a9de9248SMarcel Holtmann 33923e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 3393a9de9248SMarcel Holtmann 3394a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3395a9de9248SMarcel Holtmann 3396a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3397d7556e20SWaldemar Rymarkiewicz if (!conn) 3398d7556e20SWaldemar Rymarkiewicz goto unlock; 3399d7556e20SWaldemar Rymarkiewicz 3400765c2a96SJohan Hedberg if (!ev->status) { 3401160b9251SSzymon Janc clear_bit(HCI_CONN_AUTH_FAILURE, &conn->flags); 3402160b9251SSzymon Janc 3403aa64a8b5SJohan Hedberg if (!hci_conn_ssp_enabled(conn) && 340451a8efd7SJohan Hedberg test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { 34052064ee33SMarcel Holtmann bt_dev_info(hdev, "re-auth of legacy device is not possible."); 340619f8def0SWaldemar Rymarkiewicz } else { 34074dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 3408765c2a96SJohan Hedberg conn->sec_level = conn->pending_sec_level; 340919f8def0SWaldemar Rymarkiewicz } 34102a611692SJohan Hedberg } else { 3411160b9251SSzymon Janc if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING) 3412160b9251SSzymon Janc set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags); 3413160b9251SSzymon Janc 3414e1e930f5SJohan Hedberg mgmt_auth_failed(conn, ev->status); 34152a611692SJohan Hedberg } 3416a9de9248SMarcel Holtmann 341751a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 341851a8efd7SJohan Hedberg clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags); 3419a9de9248SMarcel Holtmann 3420f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) { 3421aa64a8b5SJohan Hedberg if (!ev->status && hci_conn_ssp_enabled(conn)) { 3422f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 3423f8558555SMarcel Holtmann cp.handle = ev->handle; 3424f8558555SMarcel Holtmann cp.encrypt = 0x01; 3425d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 3426d7556e20SWaldemar Rymarkiewicz &cp); 3427f8558555SMarcel Holtmann } else { 3428f8558555SMarcel Holtmann conn->state = BT_CONNECTED; 3429539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 343076a68ba0SDavid Herrmann hci_conn_drop(conn); 3431f8558555SMarcel Holtmann } 3432052b30b0SMarcel Holtmann } else { 3433a9de9248SMarcel Holtmann hci_auth_cfm(conn, ev->status); 3434a9de9248SMarcel Holtmann 3435052b30b0SMarcel Holtmann hci_conn_hold(conn); 3436052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 343776a68ba0SDavid Herrmann hci_conn_drop(conn); 3438052b30b0SMarcel Holtmann } 3439052b30b0SMarcel Holtmann 344051a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { 3441a9de9248SMarcel Holtmann if (!ev->status) { 3442a9de9248SMarcel Holtmann struct hci_cp_set_conn_encrypt cp; 3443f8558555SMarcel Holtmann cp.handle = ev->handle; 3444f8558555SMarcel Holtmann cp.encrypt = 0x01; 3445d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), 3446d7556e20SWaldemar Rymarkiewicz &cp); 3447a9de9248SMarcel Holtmann } else { 344851a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 34493ca44c16SLuiz Augusto von Dentz hci_encrypt_cfm(conn, ev->status); 3450a9de9248SMarcel Holtmann } 3451a9de9248SMarcel Holtmann } 3452a9de9248SMarcel Holtmann 3453d7556e20SWaldemar Rymarkiewicz unlock: 3454a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3455a9de9248SMarcel Holtmann } 3456a9de9248SMarcel Holtmann 34573e54c589SLuiz Augusto von Dentz static void hci_remote_name_evt(struct hci_dev *hdev, void *data, 34583e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 3459a9de9248SMarcel Holtmann { 34603e54c589SLuiz Augusto von Dentz struct hci_ev_remote_name *ev = data; 3461127178d2SJohan Hedberg struct hci_conn *conn; 3462127178d2SJohan Hedberg 34633e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 3464a9de9248SMarcel Holtmann 3465a9de9248SMarcel Holtmann hci_conn_check_pending(hdev); 3466127178d2SJohan Hedberg 3467127178d2SJohan Hedberg hci_dev_lock(hdev); 3468127178d2SJohan Hedberg 3469127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 3470b644ba33SJohan Hedberg 3471d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 3472b644ba33SJohan Hedberg goto check_auth; 3473b644ba33SJohan Hedberg 3474b644ba33SJohan Hedberg if (ev->status == 0) 3475b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name, 3476b644ba33SJohan Hedberg strnlen(ev->name, HCI_MAX_NAME_LENGTH)); 3477b644ba33SJohan Hedberg else 3478b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0); 3479b644ba33SJohan Hedberg 3480b644ba33SJohan Hedberg check_auth: 348179c6c70cSJohan Hedberg if (!conn) 348279c6c70cSJohan Hedberg goto unlock; 348379c6c70cSJohan Hedberg 348479c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) 348579c6c70cSJohan Hedberg goto unlock; 348679c6c70cSJohan Hedberg 348751a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { 3488127178d2SJohan Hedberg struct hci_cp_auth_requested cp; 3489977f8fceSJohan Hedberg 3490977f8fceSJohan Hedberg set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags); 3491977f8fceSJohan Hedberg 3492127178d2SJohan Hedberg cp.handle = __cpu_to_le16(conn->handle); 3493127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); 3494127178d2SJohan Hedberg } 3495127178d2SJohan Hedberg 349679c6c70cSJohan Hedberg unlock: 3497127178d2SJohan Hedberg hci_dev_unlock(hdev); 3498a9de9248SMarcel Holtmann } 3499a9de9248SMarcel Holtmann 3500821f3766SJohan Hedberg static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status, 3501821f3766SJohan Hedberg u16 opcode, struct sk_buff *skb) 3502821f3766SJohan Hedberg { 3503821f3766SJohan Hedberg const struct hci_rp_read_enc_key_size *rp; 3504821f3766SJohan Hedberg struct hci_conn *conn; 3505821f3766SJohan Hedberg u16 handle; 3506821f3766SJohan Hedberg 3507821f3766SJohan Hedberg BT_DBG("%s status 0x%02x", hdev->name, status); 3508821f3766SJohan Hedberg 3509821f3766SJohan Hedberg if (!skb || skb->len < sizeof(*rp)) { 35102064ee33SMarcel Holtmann bt_dev_err(hdev, "invalid read key size response"); 3511821f3766SJohan Hedberg return; 3512821f3766SJohan Hedberg } 3513821f3766SJohan Hedberg 3514821f3766SJohan Hedberg rp = (void *)skb->data; 3515821f3766SJohan Hedberg handle = le16_to_cpu(rp->handle); 3516821f3766SJohan Hedberg 3517821f3766SJohan Hedberg hci_dev_lock(hdev); 3518821f3766SJohan Hedberg 3519821f3766SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, handle); 3520821f3766SJohan Hedberg if (!conn) 3521821f3766SJohan Hedberg goto unlock; 3522821f3766SJohan Hedberg 352332b50729SAlain Michaud /* While unexpected, the read_enc_key_size command may fail. The most 352432b50729SAlain Michaud * secure approach is to then assume the key size is 0 to force a 352532b50729SAlain Michaud * disconnection. 3526821f3766SJohan Hedberg */ 3527821f3766SJohan Hedberg if (rp->status) { 35282064ee33SMarcel Holtmann bt_dev_err(hdev, "failed to read key size for handle %u", 3529821f3766SJohan Hedberg handle); 353032b50729SAlain Michaud conn->enc_key_size = 0; 3531821f3766SJohan Hedberg } else { 3532821f3766SJohan Hedberg conn->enc_key_size = rp->key_size; 3533821f3766SJohan Hedberg } 3534821f3766SJohan Hedberg 35353ca44c16SLuiz Augusto von Dentz hci_encrypt_cfm(conn, 0); 3536821f3766SJohan Hedberg 3537821f3766SJohan Hedberg unlock: 3538821f3766SJohan Hedberg hci_dev_unlock(hdev); 3539821f3766SJohan Hedberg } 3540821f3766SJohan Hedberg 35413e54c589SLuiz Augusto von Dentz static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data, 35423e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 3543a9de9248SMarcel Holtmann { 35443e54c589SLuiz Augusto von Dentz struct hci_ev_encrypt_change *ev = data; 3545a9de9248SMarcel Holtmann struct hci_conn *conn; 3546a9de9248SMarcel Holtmann 35473e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 3548a9de9248SMarcel Holtmann 3549a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3550a9de9248SMarcel Holtmann 3551a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3552dc8357ccSMarcel Holtmann if (!conn) 3553dc8357ccSMarcel Holtmann goto unlock; 3554dc8357ccSMarcel Holtmann 3555a9de9248SMarcel Holtmann if (!ev->status) { 3556ae293196SMarcel Holtmann if (ev->encrypt) { 3557ae293196SMarcel Holtmann /* Encryption implies authentication */ 35584dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags); 35594dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags); 3560da85e5e5SVinicius Costa Gomes conn->sec_level = conn->pending_sec_level; 3561abf76badSMarcel Holtmann 3562914a6ffeSMarcel Holtmann /* P-256 authentication key implies FIPS */ 3563914a6ffeSMarcel Holtmann if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256) 35644dae2798SJohan Hedberg set_bit(HCI_CONN_FIPS, &conn->flags); 3565914a6ffeSMarcel Holtmann 3566abf76badSMarcel Holtmann if ((conn->type == ACL_LINK && ev->encrypt == 0x02) || 3567abf76badSMarcel Holtmann conn->type == LE_LINK) 3568abf76badSMarcel Holtmann set_bit(HCI_CONN_AES_CCM, &conn->flags); 3569abf76badSMarcel Holtmann } else { 35704dae2798SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT, &conn->flags); 3571abf76badSMarcel Holtmann clear_bit(HCI_CONN_AES_CCM, &conn->flags); 3572abf76badSMarcel Holtmann } 3573a9de9248SMarcel Holtmann } 3574a9de9248SMarcel Holtmann 35757ed3fa20SJohan Hedberg /* We should disregard the current RPA and generate a new one 35767ed3fa20SJohan Hedberg * whenever the encryption procedure fails. 35777ed3fa20SJohan Hedberg */ 3578a73c046aSJaganath Kanakkassery if (ev->status && conn->type == LE_LINK) { 3579a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); 3580a73c046aSJaganath Kanakkassery hci_adv_instances_set_rpa_expired(hdev, true); 3581a73c046aSJaganath Kanakkassery } 35827ed3fa20SJohan Hedberg 358351a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 3584a9de9248SMarcel Holtmann 35858746f135SLuiz Augusto von Dentz /* Check link security requirements are met */ 35868746f135SLuiz Augusto von Dentz if (!hci_conn_check_link_mode(conn)) 35878746f135SLuiz Augusto von Dentz ev->status = HCI_ERROR_AUTH_FAILURE; 35888746f135SLuiz Augusto von Dentz 3589a7d7723aSGustavo Padovan if (ev->status && conn->state == BT_CONNECTED) { 3590160b9251SSzymon Janc if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING) 3591160b9251SSzymon Janc set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags); 3592160b9251SSzymon Janc 35938746f135SLuiz Augusto von Dentz /* Notify upper layers so they can cleanup before 35948746f135SLuiz Augusto von Dentz * disconnecting. 359540b552aaSMarcel Holtmann */ 35968746f135SLuiz Augusto von Dentz hci_encrypt_cfm(conn, ev->status); 35978746f135SLuiz Augusto von Dentz hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 359840b552aaSMarcel Holtmann hci_conn_drop(conn); 359940b552aaSMarcel Holtmann goto unlock; 360040b552aaSMarcel Holtmann } 360140b552aaSMarcel Holtmann 3602821f3766SJohan Hedberg /* Try reading the encryption key size for encrypted ACL links */ 3603821f3766SJohan Hedberg if (!ev->status && ev->encrypt && conn->type == ACL_LINK) { 3604821f3766SJohan Hedberg struct hci_cp_read_enc_key_size cp; 3605821f3766SJohan Hedberg struct hci_request req; 3606821f3766SJohan Hedberg 3607821f3766SJohan Hedberg /* Only send HCI_Read_Encryption_Key_Size if the 3608821f3766SJohan Hedberg * controller really supports it. If it doesn't, assume 3609821f3766SJohan Hedberg * the default size (16). 3610821f3766SJohan Hedberg */ 3611821f3766SJohan Hedberg if (!(hdev->commands[20] & 0x10)) { 3612821f3766SJohan Hedberg conn->enc_key_size = HCI_LINK_KEY_SIZE; 3613821f3766SJohan Hedberg goto notify; 3614821f3766SJohan Hedberg } 3615821f3766SJohan Hedberg 3616821f3766SJohan Hedberg hci_req_init(&req, hdev); 3617821f3766SJohan Hedberg 3618821f3766SJohan Hedberg cp.handle = cpu_to_le16(conn->handle); 3619821f3766SJohan Hedberg hci_req_add(&req, HCI_OP_READ_ENC_KEY_SIZE, sizeof(cp), &cp); 3620821f3766SJohan Hedberg 3621821f3766SJohan Hedberg if (hci_req_run_skb(&req, read_enc_key_size_complete)) { 36222064ee33SMarcel Holtmann bt_dev_err(hdev, "sending read key size failed"); 3623821f3766SJohan Hedberg conn->enc_key_size = HCI_LINK_KEY_SIZE; 3624821f3766SJohan Hedberg goto notify; 3625821f3766SJohan Hedberg } 3626821f3766SJohan Hedberg 3627821f3766SJohan Hedberg goto unlock; 3628821f3766SJohan Hedberg } 3629821f3766SJohan Hedberg 3630302975cbSSpoorthi Ravishankar Koppad /* Set the default Authenticated Payload Timeout after 3631302975cbSSpoorthi Ravishankar Koppad * an LE Link is established. As per Core Spec v5.0, Vol 2, Part B 3632302975cbSSpoorthi Ravishankar Koppad * Section 3.3, the HCI command WRITE_AUTH_PAYLOAD_TIMEOUT should be 3633302975cbSSpoorthi Ravishankar Koppad * sent when the link is active and Encryption is enabled, the conn 3634302975cbSSpoorthi Ravishankar Koppad * type can be either LE or ACL and controller must support LMP Ping. 3635302975cbSSpoorthi Ravishankar Koppad * Ensure for AES-CCM encryption as well. 3636302975cbSSpoorthi Ravishankar Koppad */ 3637302975cbSSpoorthi Ravishankar Koppad if (test_bit(HCI_CONN_ENCRYPT, &conn->flags) && 3638302975cbSSpoorthi Ravishankar Koppad test_bit(HCI_CONN_AES_CCM, &conn->flags) && 3639302975cbSSpoorthi Ravishankar Koppad ((conn->type == ACL_LINK && lmp_ping_capable(hdev)) || 3640302975cbSSpoorthi Ravishankar Koppad (conn->type == LE_LINK && (hdev->le_features[0] & HCI_LE_PING)))) { 3641302975cbSSpoorthi Ravishankar Koppad struct hci_cp_write_auth_payload_to cp; 3642302975cbSSpoorthi Ravishankar Koppad 3643302975cbSSpoorthi Ravishankar Koppad cp.handle = cpu_to_le16(conn->handle); 3644302975cbSSpoorthi Ravishankar Koppad cp.timeout = cpu_to_le16(hdev->auth_payload_timeout); 3645302975cbSSpoorthi Ravishankar Koppad hci_send_cmd(conn->hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO, 3646302975cbSSpoorthi Ravishankar Koppad sizeof(cp), &cp); 3647302975cbSSpoorthi Ravishankar Koppad } 3648302975cbSSpoorthi Ravishankar Koppad 3649821f3766SJohan Hedberg notify: 36503ca44c16SLuiz Augusto von Dentz hci_encrypt_cfm(conn, ev->status); 3651a9de9248SMarcel Holtmann 3652a7d7723aSGustavo Padovan unlock: 3653a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3654a9de9248SMarcel Holtmann } 3655a9de9248SMarcel Holtmann 36563e54c589SLuiz Augusto von Dentz static void hci_change_link_key_complete_evt(struct hci_dev *hdev, void *data, 3657807deac2SGustavo Padovan struct sk_buff *skb) 3658a9de9248SMarcel Holtmann { 36593e54c589SLuiz Augusto von Dentz struct hci_ev_change_link_key_complete *ev = data; 3660a9de9248SMarcel Holtmann struct hci_conn *conn; 3661a9de9248SMarcel Holtmann 36623e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 3663a9de9248SMarcel Holtmann 3664a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3665a9de9248SMarcel Holtmann 3666a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3667a9de9248SMarcel Holtmann if (conn) { 3668a9de9248SMarcel Holtmann if (!ev->status) 36694dae2798SJohan Hedberg set_bit(HCI_CONN_SECURE, &conn->flags); 3670a9de9248SMarcel Holtmann 367151a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); 3672a9de9248SMarcel Holtmann 3673a9de9248SMarcel Holtmann hci_key_change_cfm(conn, ev->status); 3674a9de9248SMarcel Holtmann } 3675a9de9248SMarcel Holtmann 3676a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3677a9de9248SMarcel Holtmann } 3678a9de9248SMarcel Holtmann 36793e54c589SLuiz Augusto von Dentz static void hci_remote_features_evt(struct hci_dev *hdev, void *data, 3680807deac2SGustavo Padovan struct sk_buff *skb) 3681a9de9248SMarcel Holtmann { 36823e54c589SLuiz Augusto von Dentz struct hci_ev_remote_features *ev = data; 3683a9de9248SMarcel Holtmann struct hci_conn *conn; 3684a9de9248SMarcel Holtmann 36853e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 3686a9de9248SMarcel Holtmann 3687a9de9248SMarcel Holtmann hci_dev_lock(hdev); 3688a9de9248SMarcel Holtmann 3689a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 3690ccd556feSJohan Hedberg if (!conn) 3691ccd556feSJohan Hedberg goto unlock; 3692ccd556feSJohan Hedberg 3693769be974SMarcel Holtmann if (!ev->status) 3694cad718edSJohan Hedberg memcpy(conn->features[0], ev->features, 8); 3695a9de9248SMarcel Holtmann 3696ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 3697ccd556feSJohan Hedberg goto unlock; 3698ccd556feSJohan Hedberg 3699ac363cf9SSzymon Janc if (!ev->status && lmp_ext_feat_capable(hdev) && 3700ac363cf9SSzymon Janc lmp_ext_feat_capable(conn)) { 3701769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features cp; 3702769be974SMarcel Holtmann cp.handle = ev->handle; 3703769be974SMarcel Holtmann cp.page = 0x01; 3704ccd556feSJohan Hedberg hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, 3705769be974SMarcel Holtmann sizeof(cp), &cp); 3706392599b9SJohan Hedberg goto unlock; 3707392599b9SJohan Hedberg } 3708392599b9SJohan Hedberg 3709671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 3710127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 3711127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 3712127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 3713127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 3714127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 3715b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 37161c6ed31bSYu Liu mgmt_device_connected(hdev, conn, NULL, 0); 3717392599b9SJohan Hedberg 3718127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 3719769be974SMarcel Holtmann conn->state = BT_CONNECTED; 3720539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 372176a68ba0SDavid Herrmann hci_conn_drop(conn); 3722769be974SMarcel Holtmann } 3723769be974SMarcel Holtmann 3724ccd556feSJohan Hedberg unlock: 3725a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 3726a9de9248SMarcel Holtmann } 3727a9de9248SMarcel Holtmann 3728ecb71f25SKiran K static inline void handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd) 3729de75cd0dSManish Mandlik { 3730de75cd0dSManish Mandlik cancel_delayed_work(&hdev->cmd_timer); 3731de75cd0dSManish Mandlik 3732de75cd0dSManish Mandlik if (!test_bit(HCI_RESET, &hdev->flags)) { 3733de75cd0dSManish Mandlik if (ncmd) { 3734de75cd0dSManish Mandlik cancel_delayed_work(&hdev->ncmd_timer); 3735de75cd0dSManish Mandlik atomic_set(&hdev->cmd_cnt, 1); 3736de75cd0dSManish Mandlik } else { 3737de75cd0dSManish Mandlik schedule_delayed_work(&hdev->ncmd_timer, 3738de75cd0dSManish Mandlik HCI_NCMD_TIMEOUT); 3739de75cd0dSManish Mandlik } 3740de75cd0dSManish Mandlik } 3741de75cd0dSManish Mandlik } 3742de75cd0dSManish Mandlik 3743c8992cffSLuiz Augusto von Dentz #define HCI_CC_VL(_op, _func, _min, _max) \ 3744c8992cffSLuiz Augusto von Dentz { \ 3745c8992cffSLuiz Augusto von Dentz .op = _op, \ 3746c8992cffSLuiz Augusto von Dentz .func = _func, \ 3747c8992cffSLuiz Augusto von Dentz .min_len = _min, \ 3748c8992cffSLuiz Augusto von Dentz .max_len = _max, \ 3749c8992cffSLuiz Augusto von Dentz } 3750c8992cffSLuiz Augusto von Dentz 3751c8992cffSLuiz Augusto von Dentz #define HCI_CC(_op, _func, _len) \ 3752c8992cffSLuiz Augusto von Dentz HCI_CC_VL(_op, _func, _len, _len) 3753c8992cffSLuiz Augusto von Dentz 3754c8992cffSLuiz Augusto von Dentz #define HCI_CC_STATUS(_op, _func) \ 3755c8992cffSLuiz Augusto von Dentz HCI_CC(_op, _func, sizeof(struct hci_ev_status)) 3756c8992cffSLuiz Augusto von Dentz 3757c8992cffSLuiz Augusto von Dentz static const struct hci_cc { 3758c8992cffSLuiz Augusto von Dentz u16 op; 3759c8992cffSLuiz Augusto von Dentz u8 (*func)(struct hci_dev *hdev, void *data, struct sk_buff *skb); 3760c8992cffSLuiz Augusto von Dentz u16 min_len; 3761c8992cffSLuiz Augusto von Dentz u16 max_len; 3762c8992cffSLuiz Augusto von Dentz } hci_cc_table[] = { 3763c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_INQUIRY_CANCEL, hci_cc_inquiry_cancel), 3764c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_PERIODIC_INQ, hci_cc_periodic_inq), 3765c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_EXIT_PERIODIC_INQ, hci_cc_exit_periodic_inq), 3766c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_REMOTE_NAME_REQ_CANCEL, 3767c8992cffSLuiz Augusto von Dentz hci_cc_remote_name_req_cancel), 3768c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_ROLE_DISCOVERY, hci_cc_role_discovery, 3769c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_role_discovery)), 3770c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LINK_POLICY, hci_cc_read_link_policy, 3771c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_link_policy)), 3772c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_WRITE_LINK_POLICY, hci_cc_write_link_policy, 3773c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_write_link_policy)), 3774c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_DEF_LINK_POLICY, hci_cc_read_def_link_policy, 3775c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_def_link_policy)), 3776c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_DEF_LINK_POLICY, 3777c8992cffSLuiz Augusto von Dentz hci_cc_write_def_link_policy), 3778c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_RESET, hci_cc_reset), 3779c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_STORED_LINK_KEY, hci_cc_read_stored_link_key, 3780c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_stored_link_key)), 3781c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_DELETE_STORED_LINK_KEY, hci_cc_delete_stored_link_key, 3782c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_delete_stored_link_key)), 3783c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_LOCAL_NAME, hci_cc_write_local_name), 3784c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_NAME, hci_cc_read_local_name, 3785c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_name)), 3786c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_AUTH_ENABLE, hci_cc_write_auth_enable), 3787c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_ENCRYPT_MODE, hci_cc_write_encrypt_mode), 3788c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_SCAN_ENABLE, hci_cc_write_scan_enable), 3789c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_SET_EVENT_FLT, hci_cc_set_event_filter), 3790c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_CLASS_OF_DEV, hci_cc_read_class_of_dev, 3791c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_class_of_dev)), 3792c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_CLASS_OF_DEV, hci_cc_write_class_of_dev), 3793c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_VOICE_SETTING, hci_cc_read_voice_setting, 3794c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_voice_setting)), 3795c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_VOICE_SETTING, hci_cc_write_voice_setting), 3796c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_NUM_SUPPORTED_IAC, hci_cc_read_num_supported_iac, 3797c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_num_supported_iac)), 3798c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_SSP_MODE, hci_cc_write_ssp_mode), 3799c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_SC_SUPPORT, hci_cc_write_sc_support), 3800c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_AUTH_PAYLOAD_TO, hci_cc_read_auth_payload_timeout, 3801c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_auth_payload_to)), 3802c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_WRITE_AUTH_PAYLOAD_TO, hci_cc_write_auth_payload_timeout, 3803c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_write_auth_payload_to)), 3804c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_VERSION, hci_cc_read_local_version, 3805c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_version)), 3806c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_COMMANDS, hci_cc_read_local_commands, 3807c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_commands)), 3808c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_FEATURES, hci_cc_read_local_features, 3809c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_features)), 3810c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_EXT_FEATURES, hci_cc_read_local_ext_features, 3811c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_ext_features)), 3812c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_BUFFER_SIZE, hci_cc_read_buffer_size, 3813c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_buffer_size)), 3814c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_BD_ADDR, hci_cc_read_bd_addr, 3815c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_bd_addr)), 3816c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_PAIRING_OPTS, hci_cc_read_local_pairing_opts, 3817c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_pairing_opts)), 3818c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_PAGE_SCAN_ACTIVITY, hci_cc_read_page_scan_activity, 3819c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_page_scan_activity)), 3820c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_PAGE_SCAN_ACTIVITY, 3821c8992cffSLuiz Augusto von Dentz hci_cc_write_page_scan_activity), 3822c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_PAGE_SCAN_TYPE, hci_cc_read_page_scan_type, 3823c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_page_scan_type)), 3824c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_PAGE_SCAN_TYPE, hci_cc_write_page_scan_type), 3825c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_DATA_BLOCK_SIZE, hci_cc_read_data_block_size, 3826c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_data_block_size)), 3827c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_FLOW_CONTROL_MODE, hci_cc_read_flow_control_mode, 3828c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_flow_control_mode)), 3829c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_AMP_INFO, hci_cc_read_local_amp_info, 3830c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_amp_info)), 3831c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_CLOCK, hci_cc_read_clock, 3832c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_clock)), 3833c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_INQ_RSP_TX_POWER, hci_cc_read_inq_rsp_tx_power, 3834c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_inq_rsp_tx_power)), 3835c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_DEF_ERR_DATA_REPORTING, 3836c8992cffSLuiz Augusto von Dentz hci_cc_read_def_err_data_reporting, 3837c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_def_err_data_reporting)), 3838c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_DEF_ERR_DATA_REPORTING, 3839c8992cffSLuiz Augusto von Dentz hci_cc_write_def_err_data_reporting), 3840c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_PIN_CODE_REPLY, hci_cc_pin_code_reply, 3841c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_pin_code_reply)), 3842c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_PIN_CODE_NEG_REPLY, hci_cc_pin_code_neg_reply, 3843c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_pin_code_neg_reply)), 3844c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_OOB_DATA, hci_cc_read_local_oob_data, 3845c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_oob_data)), 3846c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_OOB_EXT_DATA, hci_cc_read_local_oob_ext_data, 3847c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_oob_ext_data)), 3848c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_BUFFER_SIZE, hci_cc_le_read_buffer_size, 3849c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_buffer_size)), 3850c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_LOCAL_FEATURES, hci_cc_le_read_local_features, 3851c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_local_features)), 3852c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_ADV_TX_POWER, hci_cc_le_read_adv_tx_power, 3853c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_adv_tx_power)), 3854c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_USER_CONFIRM_REPLY, hci_cc_user_confirm_reply, 3855c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_user_confirm_reply)), 3856c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_USER_CONFIRM_NEG_REPLY, hci_cc_user_confirm_neg_reply, 3857c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_user_confirm_reply)), 3858c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_USER_PASSKEY_REPLY, hci_cc_user_passkey_reply, 3859c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_user_confirm_reply)), 3860c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_USER_PASSKEY_NEG_REPLY, hci_cc_user_passkey_neg_reply, 3861c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_user_confirm_reply)), 3862c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_RANDOM_ADDR, hci_cc_le_set_random_addr), 3863c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_ADV_ENABLE, hci_cc_le_set_adv_enable), 3864c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_SCAN_PARAM, hci_cc_le_set_scan_param), 3865c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_SCAN_ENABLE, hci_cc_le_set_scan_enable), 3866c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_ACCEPT_LIST_SIZE, 3867c8992cffSLuiz Augusto von Dentz hci_cc_le_read_accept_list_size, 3868c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_accept_list_size)), 3869c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_CLEAR_ACCEPT_LIST, hci_cc_le_clear_accept_list), 3870c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_ADD_TO_ACCEPT_LIST, 3871c8992cffSLuiz Augusto von Dentz hci_cc_le_add_to_accept_list), 3872c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_DEL_FROM_ACCEPT_LIST, 3873c8992cffSLuiz Augusto von Dentz hci_cc_le_del_from_accept_list), 3874c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_SUPPORTED_STATES, hci_cc_le_read_supported_states, 3875c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_supported_states)), 3876c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_DEF_DATA_LEN, hci_cc_le_read_def_data_len, 3877c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_def_data_len)), 3878c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_WRITE_DEF_DATA_LEN, 3879c8992cffSLuiz Augusto von Dentz hci_cc_le_write_def_data_len), 3880c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_ADD_TO_RESOLV_LIST, 3881c8992cffSLuiz Augusto von Dentz hci_cc_le_add_to_resolv_list), 3882c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_DEL_FROM_RESOLV_LIST, 3883c8992cffSLuiz Augusto von Dentz hci_cc_le_del_from_resolv_list), 3884c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_CLEAR_RESOLV_LIST, 3885c8992cffSLuiz Augusto von Dentz hci_cc_le_clear_resolv_list), 3886c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_RESOLV_LIST_SIZE, hci_cc_le_read_resolv_list_size, 3887c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_resolv_list_size)), 3888c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 3889c8992cffSLuiz Augusto von Dentz hci_cc_le_set_addr_resolution_enable), 3890c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_MAX_DATA_LEN, hci_cc_le_read_max_data_len, 3891c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_max_data_len)), 3892c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_LE_HOST_SUPPORTED, 3893c8992cffSLuiz Augusto von Dentz hci_cc_write_le_host_supported), 3894c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_ADV_PARAM, hci_cc_set_adv_param), 3895c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_RSSI, hci_cc_read_rssi, 3896c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_rssi)), 3897c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_TX_POWER, hci_cc_read_tx_power, 3898c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_tx_power)), 3899c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_SSP_DEBUG_MODE, hci_cc_write_ssp_debug_mode), 3900c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_EXT_SCAN_PARAMS, 3901c8992cffSLuiz Augusto von Dentz hci_cc_le_set_ext_scan_param), 3902c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_EXT_SCAN_ENABLE, 3903c8992cffSLuiz Augusto von Dentz hci_cc_le_set_ext_scan_enable), 3904c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_DEFAULT_PHY, hci_cc_le_set_default_phy), 3905c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS, 3906c8992cffSLuiz Augusto von Dentz hci_cc_le_read_num_adv_sets, 3907c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_num_supported_adv_sets)), 3908c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_SET_EXT_ADV_PARAMS, hci_cc_set_ext_adv_param, 3909c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_set_ext_adv_params)), 3910c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_EXT_ADV_ENABLE, 3911c8992cffSLuiz Augusto von Dentz hci_cc_le_set_ext_adv_enable), 3912c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_ADV_SET_RAND_ADDR, 3913c8992cffSLuiz Augusto von Dentz hci_cc_le_set_adv_set_random_addr), 3914c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_REMOVE_ADV_SET, hci_cc_le_remove_adv_set), 3915c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_CLEAR_ADV_SETS, hci_cc_le_clear_adv_sets), 3916c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_TRANSMIT_POWER, hci_cc_le_read_transmit_power, 3917*853b70b5SLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_transmit_power)), 3918*853b70b5SLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_PRIVACY_MODE, hci_cc_le_set_privacy_mode) 3919c8992cffSLuiz Augusto von Dentz }; 3920c8992cffSLuiz Augusto von Dentz 3921c8992cffSLuiz Augusto von Dentz static u8 hci_cc_func(struct hci_dev *hdev, const struct hci_cc *cc, 3922c8992cffSLuiz Augusto von Dentz struct sk_buff *skb) 3923c8992cffSLuiz Augusto von Dentz { 3924c8992cffSLuiz Augusto von Dentz void *data; 3925c8992cffSLuiz Augusto von Dentz 3926c8992cffSLuiz Augusto von Dentz if (skb->len < cc->min_len) { 3927c8992cffSLuiz Augusto von Dentz bt_dev_err(hdev, "unexpected cc 0x%4.4x length: %u < %u", 3928c8992cffSLuiz Augusto von Dentz cc->op, skb->len, cc->min_len); 3929c8992cffSLuiz Augusto von Dentz return HCI_ERROR_UNSPECIFIED; 3930c8992cffSLuiz Augusto von Dentz } 3931c8992cffSLuiz Augusto von Dentz 3932c8992cffSLuiz Augusto von Dentz /* Just warn if the length is over max_len size it still be possible to 3933c8992cffSLuiz Augusto von Dentz * partially parse the cc so leave to callback to decide if that is 3934c8992cffSLuiz Augusto von Dentz * acceptable. 3935c8992cffSLuiz Augusto von Dentz */ 3936c8992cffSLuiz Augusto von Dentz if (skb->len > cc->max_len) 3937c8992cffSLuiz Augusto von Dentz bt_dev_warn(hdev, "unexpected cc 0x%4.4x length: %u > %u", 3938c8992cffSLuiz Augusto von Dentz cc->op, skb->len, cc->max_len); 3939c8992cffSLuiz Augusto von Dentz 3940c8992cffSLuiz Augusto von Dentz data = hci_cc_skb_pull(hdev, skb, cc->op, cc->min_len); 3941c8992cffSLuiz Augusto von Dentz if (!data) 3942c8992cffSLuiz Augusto von Dentz return HCI_ERROR_UNSPECIFIED; 3943c8992cffSLuiz Augusto von Dentz 3944c8992cffSLuiz Augusto von Dentz return cc->func(hdev, data, skb); 3945c8992cffSLuiz Augusto von Dentz } 3946c8992cffSLuiz Augusto von Dentz 39473e54c589SLuiz Augusto von Dentz static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data, 39483e54c589SLuiz Augusto von Dentz struct sk_buff *skb, u16 *opcode, u8 *status, 3949e6214487SJohan Hedberg hci_req_complete_t *req_complete, 3950e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 3951a9de9248SMarcel Holtmann { 39523e54c589SLuiz Augusto von Dentz struct hci_ev_cmd_complete *ev = data; 3953c8992cffSLuiz Augusto von Dentz int i; 3954e6214487SJohan Hedberg 3955e6214487SJohan Hedberg *opcode = __le16_to_cpu(ev->opcode); 3956a9de9248SMarcel Holtmann 3957c8992cffSLuiz Augusto von Dentz bt_dev_dbg(hdev, "opcode 0x%4.4x", *opcode); 3958a9de9248SMarcel Holtmann 3959c8992cffSLuiz Augusto von Dentz for (i = 0; i < ARRAY_SIZE(hci_cc_table); i++) { 3960c8992cffSLuiz Augusto von Dentz if (hci_cc_table[i].op == *opcode) { 3961c8992cffSLuiz Augusto von Dentz *status = hci_cc_func(hdev, &hci_cc_table[i], skb); 39624d93483bSAndre Guedes break; 3963c8992cffSLuiz Augusto von Dentz } 3964a9de9248SMarcel Holtmann } 3965a9de9248SMarcel Holtmann 3966ecb71f25SKiran K handle_cmd_cnt_and_timer(hdev, ev->ncmd); 3967600b2150SJohan Hedberg 3968e6214487SJohan Hedberg hci_req_cmd_complete(hdev, *opcode, *status, req_complete, 3969e6214487SJohan Hedberg req_complete_skb); 39709238f36aSJohan Hedberg 3971f80c5dadSJoão Paulo Rechi Vita if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) { 3972f80c5dadSJoão Paulo Rechi Vita bt_dev_err(hdev, 3973f80c5dadSJoão Paulo Rechi Vita "unexpected event for opcode 0x%4.4x", *opcode); 3974f80c5dadSJoão Paulo Rechi Vita return; 3975f80c5dadSJoão Paulo Rechi Vita } 3976f80c5dadSJoão Paulo Rechi Vita 3977600b2150SJohan Hedberg if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q)) 3978c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 3979a9de9248SMarcel Holtmann } 3980a9de9248SMarcel Holtmann 3981147306ccSLuiz Augusto von Dentz #define HCI_CS(_op, _func) \ 3982147306ccSLuiz Augusto von Dentz { \ 3983147306ccSLuiz Augusto von Dentz .op = _op, \ 3984147306ccSLuiz Augusto von Dentz .func = _func, \ 3985147306ccSLuiz Augusto von Dentz } 3986147306ccSLuiz Augusto von Dentz 3987147306ccSLuiz Augusto von Dentz static const struct hci_cs { 3988147306ccSLuiz Augusto von Dentz u16 op; 3989147306ccSLuiz Augusto von Dentz void (*func)(struct hci_dev *hdev, __u8 status); 3990147306ccSLuiz Augusto von Dentz } hci_cs_table[] = { 3991147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_INQUIRY, hci_cs_inquiry), 3992147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_CREATE_CONN, hci_cs_create_conn), 3993147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_DISCONNECT, hci_cs_disconnect), 3994147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_ADD_SCO, hci_cs_add_sco), 3995147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_AUTH_REQUESTED, hci_cs_auth_requested), 3996147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_SET_CONN_ENCRYPT, hci_cs_set_conn_encrypt), 3997147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_REMOTE_NAME_REQ, hci_cs_remote_name_req), 3998147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_READ_REMOTE_FEATURES, hci_cs_read_remote_features), 3999147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_READ_REMOTE_EXT_FEATURES, 4000147306ccSLuiz Augusto von Dentz hci_cs_read_remote_ext_features), 4001147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_SETUP_SYNC_CONN, hci_cs_setup_sync_conn), 4002147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_ENHANCED_SETUP_SYNC_CONN, 4003147306ccSLuiz Augusto von Dentz hci_cs_enhanced_setup_sync_conn), 4004147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_SNIFF_MODE, hci_cs_sniff_mode), 4005147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_EXIT_SNIFF_MODE, hci_cs_exit_sniff_mode), 4006147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_SWITCH_ROLE, hci_cs_switch_role), 4007147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_CREATE_CONN, hci_cs_le_create_conn), 4008147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_READ_REMOTE_FEATURES, hci_cs_le_read_remote_features), 4009147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_START_ENC, hci_cs_le_start_enc), 4010147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_EXT_CREATE_CONN, hci_cs_le_ext_create_conn) 4011147306ccSLuiz Augusto von Dentz }; 4012147306ccSLuiz Augusto von Dentz 40133e54c589SLuiz Augusto von Dentz static void hci_cmd_status_evt(struct hci_dev *hdev, void *data, 40143e54c589SLuiz Augusto von Dentz struct sk_buff *skb, u16 *opcode, u8 *status, 4015e6214487SJohan Hedberg hci_req_complete_t *req_complete, 4016e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb) 4017a9de9248SMarcel Holtmann { 40183e54c589SLuiz Augusto von Dentz struct hci_ev_cmd_status *ev = data; 4019147306ccSLuiz Augusto von Dentz int i; 4020a9de9248SMarcel Holtmann 4021e6214487SJohan Hedberg *opcode = __le16_to_cpu(ev->opcode); 4022e6214487SJohan Hedberg *status = ev->status; 4023a9de9248SMarcel Holtmann 4024147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "opcode 0x%4.4x", *opcode); 4025a9de9248SMarcel Holtmann 4026147306ccSLuiz Augusto von Dentz for (i = 0; i < ARRAY_SIZE(hci_cs_table); i++) { 4027147306ccSLuiz Augusto von Dentz if (hci_cs_table[i].op == *opcode) { 4028147306ccSLuiz Augusto von Dentz hci_cs_table[i].func(hdev, ev->status); 4029a9de9248SMarcel Holtmann break; 4030147306ccSLuiz Augusto von Dentz } 4031a9de9248SMarcel Holtmann } 4032a9de9248SMarcel Holtmann 4033ecb71f25SKiran K handle_cmd_cnt_and_timer(hdev, ev->ncmd); 4034600b2150SJohan Hedberg 4035444c6dd5SJohan Hedberg /* Indicate request completion if the command failed. Also, if 4036444c6dd5SJohan Hedberg * we're not waiting for a special event and we get a success 4037444c6dd5SJohan Hedberg * command status we should try to flag the request as completed 4038444c6dd5SJohan Hedberg * (since for this kind of commands there will not be a command 4039444c6dd5SJohan Hedberg * complete event). 4040444c6dd5SJohan Hedberg */ 404102350a72SJohan Hedberg if (ev->status || 4042242c0ebdSMarcel Holtmann (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->hci.req_event)) 4043e6214487SJohan Hedberg hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete, 4044e6214487SJohan Hedberg req_complete_skb); 40459238f36aSJohan Hedberg 4046f80c5dadSJoão Paulo Rechi Vita if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) { 4047f80c5dadSJoão Paulo Rechi Vita bt_dev_err(hdev, 4048f80c5dadSJoão Paulo Rechi Vita "unexpected event for opcode 0x%4.4x", *opcode); 4049f80c5dadSJoão Paulo Rechi Vita return; 4050f80c5dadSJoão Paulo Rechi Vita } 4051f80c5dadSJoão Paulo Rechi Vita 4052600b2150SJohan Hedberg if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q)) 4053c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work); 4054a9de9248SMarcel Holtmann } 4055a9de9248SMarcel Holtmann 40563e54c589SLuiz Augusto von Dentz static void hci_hardware_error_evt(struct hci_dev *hdev, void *data, 40573e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 405824dfa343SMarcel Holtmann { 40593e54c589SLuiz Augusto von Dentz struct hci_ev_hardware_error *ev = data; 4060ae61a10dSLuiz Augusto von Dentz 40613e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "code 0x%2.2x", ev->code); 406224dfa343SMarcel Holtmann 4063c7741d16SMarcel Holtmann hdev->hw_error_code = ev->code; 4064c7741d16SMarcel Holtmann 4065c7741d16SMarcel Holtmann queue_work(hdev->req_workqueue, &hdev->error_reset); 406624dfa343SMarcel Holtmann } 406724dfa343SMarcel Holtmann 40683e54c589SLuiz Augusto von Dentz static void hci_role_change_evt(struct hci_dev *hdev, void *data, 40693e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 4070a9de9248SMarcel Holtmann { 40713e54c589SLuiz Augusto von Dentz struct hci_ev_role_change *ev = data; 4072a9de9248SMarcel Holtmann struct hci_conn *conn; 4073a9de9248SMarcel Holtmann 40743e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 4075a9de9248SMarcel Holtmann 4076a9de9248SMarcel Holtmann hci_dev_lock(hdev); 4077a9de9248SMarcel Holtmann 4078a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 4079a9de9248SMarcel Holtmann if (conn) { 408040bef302SJohan Hedberg if (!ev->status) 408140bef302SJohan Hedberg conn->role = ev->role; 4082a9de9248SMarcel Holtmann 408351a8efd7SJohan Hedberg clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags); 4084a9de9248SMarcel Holtmann 4085a9de9248SMarcel Holtmann hci_role_switch_cfm(conn, ev->status, ev->role); 4086a9de9248SMarcel Holtmann } 4087a9de9248SMarcel Holtmann 4088a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 4089a9de9248SMarcel Holtmann } 4090a9de9248SMarcel Holtmann 40913e54c589SLuiz Augusto von Dentz static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data, 40923e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 40931da177e4SLinus Torvalds { 40943e54c589SLuiz Augusto von Dentz struct hci_ev_num_comp_pkts *ev = data; 40951da177e4SLinus Torvalds int i; 40961da177e4SLinus Torvalds 4097aadc3d2fSLuiz Augusto von Dentz if (!hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_PKTS, 4098aadc3d2fSLuiz Augusto von Dentz flex_array_size(ev, handles, ev->num))) 4099aadc3d2fSLuiz Augusto von Dentz return; 4100aadc3d2fSLuiz Augusto von Dentz 410132ac5b9bSAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) { 41022064ee33SMarcel Holtmann bt_dev_err(hdev, "wrong event for mode %d", hdev->flow_ctl_mode); 410332ac5b9bSAndrei Emeltchenko return; 410432ac5b9bSAndrei Emeltchenko } 410532ac5b9bSAndrei Emeltchenko 41063e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "num %d", ev->num); 41071da177e4SLinus Torvalds 4108aadc3d2fSLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) { 4109613a1c0cSAndrei Emeltchenko struct hci_comp_pkts_info *info = &ev->handles[i]; 41101da177e4SLinus Torvalds struct hci_conn *conn; 41111da177e4SLinus Torvalds __u16 handle, count; 41121da177e4SLinus Torvalds 4113613a1c0cSAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 4114613a1c0cSAndrei Emeltchenko count = __le16_to_cpu(info->count); 41151da177e4SLinus Torvalds 41161da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle); 4117f4280918SAndrei Emeltchenko if (!conn) 4118f4280918SAndrei Emeltchenko continue; 4119f4280918SAndrei Emeltchenko 41201da177e4SLinus Torvalds conn->sent -= count; 41211da177e4SLinus Torvalds 4122f4280918SAndrei Emeltchenko switch (conn->type) { 4123f4280918SAndrei Emeltchenko case ACL_LINK: 412470f23020SAndrei Emeltchenko hdev->acl_cnt += count; 412570f23020SAndrei Emeltchenko if (hdev->acl_cnt > hdev->acl_pkts) 41261da177e4SLinus Torvalds hdev->acl_cnt = hdev->acl_pkts; 4127f4280918SAndrei Emeltchenko break; 4128f4280918SAndrei Emeltchenko 4129f4280918SAndrei Emeltchenko case LE_LINK: 41306ed58ec5SVille Tervo if (hdev->le_pkts) { 41316ed58ec5SVille Tervo hdev->le_cnt += count; 41326ed58ec5SVille Tervo if (hdev->le_cnt > hdev->le_pkts) 41336ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts; 41346ed58ec5SVille Tervo } else { 41356ed58ec5SVille Tervo hdev->acl_cnt += count; 41366ed58ec5SVille Tervo if (hdev->acl_cnt > hdev->acl_pkts) 41376ed58ec5SVille Tervo hdev->acl_cnt = hdev->acl_pkts; 41386ed58ec5SVille Tervo } 4139f4280918SAndrei Emeltchenko break; 4140f4280918SAndrei Emeltchenko 4141f4280918SAndrei Emeltchenko case SCO_LINK: 414270f23020SAndrei Emeltchenko hdev->sco_cnt += count; 414370f23020SAndrei Emeltchenko if (hdev->sco_cnt > hdev->sco_pkts) 41445b7f9909SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts; 4145f4280918SAndrei Emeltchenko break; 4146f4280918SAndrei Emeltchenko 4147f4280918SAndrei Emeltchenko default: 41482064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown type %d conn %p", 41492064ee33SMarcel Holtmann conn->type, conn); 4150f4280918SAndrei Emeltchenko break; 41511da177e4SLinus Torvalds } 41521da177e4SLinus Torvalds } 4153a9de9248SMarcel Holtmann 41543eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work); 41551da177e4SLinus Torvalds } 41561da177e4SLinus Torvalds 415776ef7cf7SAndrei Emeltchenko static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev, 415876ef7cf7SAndrei Emeltchenko __u16 handle) 415976ef7cf7SAndrei Emeltchenko { 416076ef7cf7SAndrei Emeltchenko struct hci_chan *chan; 416176ef7cf7SAndrei Emeltchenko 416276ef7cf7SAndrei Emeltchenko switch (hdev->dev_type) { 4163ca8bee5dSMarcel Holtmann case HCI_PRIMARY: 416476ef7cf7SAndrei Emeltchenko return hci_conn_hash_lookup_handle(hdev, handle); 416576ef7cf7SAndrei Emeltchenko case HCI_AMP: 416676ef7cf7SAndrei Emeltchenko chan = hci_chan_lookup_handle(hdev, handle); 416776ef7cf7SAndrei Emeltchenko if (chan) 416876ef7cf7SAndrei Emeltchenko return chan->conn; 416976ef7cf7SAndrei Emeltchenko break; 417076ef7cf7SAndrei Emeltchenko default: 41712064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type); 417276ef7cf7SAndrei Emeltchenko break; 417376ef7cf7SAndrei Emeltchenko } 417476ef7cf7SAndrei Emeltchenko 417576ef7cf7SAndrei Emeltchenko return NULL; 417676ef7cf7SAndrei Emeltchenko } 417776ef7cf7SAndrei Emeltchenko 41783e54c589SLuiz Augusto von Dentz static void hci_num_comp_blocks_evt(struct hci_dev *hdev, void *data, 41793e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 418025e89e99SAndrei Emeltchenko { 41813e54c589SLuiz Augusto von Dentz struct hci_ev_num_comp_blocks *ev = data; 418225e89e99SAndrei Emeltchenko int i; 418325e89e99SAndrei Emeltchenko 4184ae61a10dSLuiz Augusto von Dentz if (!hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_BLOCKS, 4185ae61a10dSLuiz Augusto von Dentz flex_array_size(ev, handles, ev->num_hndl))) 4186ae61a10dSLuiz Augusto von Dentz return; 4187ae61a10dSLuiz Augusto von Dentz 418825e89e99SAndrei Emeltchenko if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) { 41893e54c589SLuiz Augusto von Dentz bt_dev_err(hdev, "wrong event for mode %d", 41903e54c589SLuiz Augusto von Dentz hdev->flow_ctl_mode); 419125e89e99SAndrei Emeltchenko return; 419225e89e99SAndrei Emeltchenko } 419325e89e99SAndrei Emeltchenko 41943e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "num_blocks %d num_hndl %d", ev->num_blocks, 419525e89e99SAndrei Emeltchenko ev->num_hndl); 419625e89e99SAndrei Emeltchenko 419725e89e99SAndrei Emeltchenko for (i = 0; i < ev->num_hndl; i++) { 419825e89e99SAndrei Emeltchenko struct hci_comp_blocks_info *info = &ev->handles[i]; 419976ef7cf7SAndrei Emeltchenko struct hci_conn *conn = NULL; 420025e89e99SAndrei Emeltchenko __u16 handle, block_count; 420125e89e99SAndrei Emeltchenko 420225e89e99SAndrei Emeltchenko handle = __le16_to_cpu(info->handle); 420325e89e99SAndrei Emeltchenko block_count = __le16_to_cpu(info->blocks); 420425e89e99SAndrei Emeltchenko 420576ef7cf7SAndrei Emeltchenko conn = __hci_conn_lookup_handle(hdev, handle); 420625e89e99SAndrei Emeltchenko if (!conn) 420725e89e99SAndrei Emeltchenko continue; 420825e89e99SAndrei Emeltchenko 420925e89e99SAndrei Emeltchenko conn->sent -= block_count; 421025e89e99SAndrei Emeltchenko 421125e89e99SAndrei Emeltchenko switch (conn->type) { 421225e89e99SAndrei Emeltchenko case ACL_LINK: 4213bd1eb66bSAndrei Emeltchenko case AMP_LINK: 421425e89e99SAndrei Emeltchenko hdev->block_cnt += block_count; 421525e89e99SAndrei Emeltchenko if (hdev->block_cnt > hdev->num_blocks) 421625e89e99SAndrei Emeltchenko hdev->block_cnt = hdev->num_blocks; 421725e89e99SAndrei Emeltchenko break; 421825e89e99SAndrei Emeltchenko 421925e89e99SAndrei Emeltchenko default: 42202064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown type %d conn %p", 42212064ee33SMarcel Holtmann conn->type, conn); 422225e89e99SAndrei Emeltchenko break; 422325e89e99SAndrei Emeltchenko } 422425e89e99SAndrei Emeltchenko } 422525e89e99SAndrei Emeltchenko 422625e89e99SAndrei Emeltchenko queue_work(hdev->workqueue, &hdev->tx_work); 422725e89e99SAndrei Emeltchenko } 422825e89e99SAndrei Emeltchenko 42293e54c589SLuiz Augusto von Dentz static void hci_mode_change_evt(struct hci_dev *hdev, void *data, 42303e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 42311da177e4SLinus Torvalds { 42323e54c589SLuiz Augusto von Dentz struct hci_ev_mode_change *ev = data; 423304837f64SMarcel Holtmann struct hci_conn *conn; 42341da177e4SLinus Torvalds 42353e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 42361da177e4SLinus Torvalds 42371da177e4SLinus Torvalds hci_dev_lock(hdev); 42381da177e4SLinus Torvalds 423904837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 424004837f64SMarcel Holtmann if (conn) { 424104837f64SMarcel Holtmann conn->mode = ev->mode; 424204837f64SMarcel Holtmann 42438fc9ced3SGustavo Padovan if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, 42448fc9ced3SGustavo Padovan &conn->flags)) { 424504837f64SMarcel Holtmann if (conn->mode == HCI_CM_ACTIVE) 424658a681efSJohan Hedberg set_bit(HCI_CONN_POWER_SAVE, &conn->flags); 424704837f64SMarcel Holtmann else 424858a681efSJohan Hedberg clear_bit(HCI_CONN_POWER_SAVE, &conn->flags); 424904837f64SMarcel Holtmann } 4250e73439d8SMarcel Holtmann 425151a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags)) 4252e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status); 425304837f64SMarcel Holtmann } 425404837f64SMarcel Holtmann 425504837f64SMarcel Holtmann hci_dev_unlock(hdev); 425604837f64SMarcel Holtmann } 425704837f64SMarcel Holtmann 42583e54c589SLuiz Augusto von Dentz static void hci_pin_code_request_evt(struct hci_dev *hdev, void *data, 42593e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 42601da177e4SLinus Torvalds { 42613e54c589SLuiz Augusto von Dentz struct hci_ev_pin_code_req *ev = data; 4262052b30b0SMarcel Holtmann struct hci_conn *conn; 4263052b30b0SMarcel Holtmann 42643e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 4265052b30b0SMarcel Holtmann 4266052b30b0SMarcel Holtmann hci_dev_lock(hdev); 4267052b30b0SMarcel Holtmann 4268052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 4269b6f98044SWaldemar Rymarkiewicz if (!conn) 4270b6f98044SWaldemar Rymarkiewicz goto unlock; 4271b6f98044SWaldemar Rymarkiewicz 4272b6f98044SWaldemar Rymarkiewicz if (conn->state == BT_CONNECTED) { 4273052b30b0SMarcel Holtmann hci_conn_hold(conn); 4274052b30b0SMarcel Holtmann conn->disc_timeout = HCI_PAIRING_TIMEOUT; 427576a68ba0SDavid Herrmann hci_conn_drop(conn); 4276052b30b0SMarcel Holtmann } 4277052b30b0SMarcel Holtmann 4278d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE) && 42792f407f0aSJohan Hedberg !test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags)) { 428003b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, 428103b555e1SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 4282d7a5a11dSMarcel Holtmann } else if (hci_dev_test_flag(hdev, HCI_MGMT)) { 4283a770bb5aSWaldemar Rymarkiewicz u8 secure; 4284a770bb5aSWaldemar Rymarkiewicz 4285a770bb5aSWaldemar Rymarkiewicz if (conn->pending_sec_level == BT_SECURITY_HIGH) 4286a770bb5aSWaldemar Rymarkiewicz secure = 1; 4287a770bb5aSWaldemar Rymarkiewicz else 4288a770bb5aSWaldemar Rymarkiewicz secure = 0; 4289a770bb5aSWaldemar Rymarkiewicz 4290744cf19eSJohan Hedberg mgmt_pin_code_request(hdev, &ev->bdaddr, secure); 4291a770bb5aSWaldemar Rymarkiewicz } 4292980e1a53SJohan Hedberg 4293b6f98044SWaldemar Rymarkiewicz unlock: 4294052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 42951da177e4SLinus Torvalds } 42961da177e4SLinus Torvalds 4297cb6f3f7aSJohan Hedberg static void conn_set_key(struct hci_conn *conn, u8 key_type, u8 pin_len) 4298cb6f3f7aSJohan Hedberg { 4299cb6f3f7aSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION) 4300cb6f3f7aSJohan Hedberg return; 4301cb6f3f7aSJohan Hedberg 4302cb6f3f7aSJohan Hedberg conn->pin_length = pin_len; 4303cb6f3f7aSJohan Hedberg conn->key_type = key_type; 4304cb6f3f7aSJohan Hedberg 4305cb6f3f7aSJohan Hedberg switch (key_type) { 4306cb6f3f7aSJohan Hedberg case HCI_LK_LOCAL_UNIT: 4307cb6f3f7aSJohan Hedberg case HCI_LK_REMOTE_UNIT: 4308cb6f3f7aSJohan Hedberg case HCI_LK_DEBUG_COMBINATION: 4309cb6f3f7aSJohan Hedberg return; 4310cb6f3f7aSJohan Hedberg case HCI_LK_COMBINATION: 4311cb6f3f7aSJohan Hedberg if (pin_len == 16) 4312cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_HIGH; 4313cb6f3f7aSJohan Hedberg else 4314cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_MEDIUM; 4315cb6f3f7aSJohan Hedberg break; 4316cb6f3f7aSJohan Hedberg case HCI_LK_UNAUTH_COMBINATION_P192: 4317cb6f3f7aSJohan Hedberg case HCI_LK_UNAUTH_COMBINATION_P256: 4318cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_MEDIUM; 4319cb6f3f7aSJohan Hedberg break; 4320cb6f3f7aSJohan Hedberg case HCI_LK_AUTH_COMBINATION_P192: 4321cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_HIGH; 4322cb6f3f7aSJohan Hedberg break; 4323cb6f3f7aSJohan Hedberg case HCI_LK_AUTH_COMBINATION_P256: 4324cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_FIPS; 4325cb6f3f7aSJohan Hedberg break; 4326cb6f3f7aSJohan Hedberg } 4327cb6f3f7aSJohan Hedberg } 4328cb6f3f7aSJohan Hedberg 43293e54c589SLuiz Augusto von Dentz static void hci_link_key_request_evt(struct hci_dev *hdev, void *data, 43303e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 43311da177e4SLinus Torvalds { 43323e54c589SLuiz Augusto von Dentz struct hci_ev_link_key_req *ev = data; 433355ed8ca1SJohan Hedberg struct hci_cp_link_key_reply cp; 433455ed8ca1SJohan Hedberg struct hci_conn *conn; 433555ed8ca1SJohan Hedberg struct link_key *key; 433655ed8ca1SJohan Hedberg 43373e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 433855ed8ca1SJohan Hedberg 4339d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 434055ed8ca1SJohan Hedberg return; 434155ed8ca1SJohan Hedberg 434255ed8ca1SJohan Hedberg hci_dev_lock(hdev); 434355ed8ca1SJohan Hedberg 434455ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, &ev->bdaddr); 434555ed8ca1SJohan Hedberg if (!key) { 43463e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "link key not found for %pMR", &ev->bdaddr); 434755ed8ca1SJohan Hedberg goto not_found; 434855ed8ca1SJohan Hedberg } 434955ed8ca1SJohan Hedberg 43503e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "found key type %u for %pMR", key->type, &ev->bdaddr); 435155ed8ca1SJohan Hedberg 435255ed8ca1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 435360b83f57SWaldemar Rymarkiewicz if (conn) { 4354fe8bc5acSJohan Hedberg clear_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags); 4355fe8bc5acSJohan Hedberg 435666138ce8SMarcel Holtmann if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 || 435766138ce8SMarcel Holtmann key->type == HCI_LK_UNAUTH_COMBINATION_P256) && 4358807deac2SGustavo Padovan conn->auth_type != 0xff && (conn->auth_type & 0x01)) { 43593e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "ignoring unauthenticated key"); 436055ed8ca1SJohan Hedberg goto not_found; 436155ed8ca1SJohan Hedberg } 436255ed8ca1SJohan Hedberg 436360b83f57SWaldemar Rymarkiewicz if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && 4364f3fb0b58SJohan Hedberg (conn->pending_sec_level == BT_SECURITY_HIGH || 4365f3fb0b58SJohan Hedberg conn->pending_sec_level == BT_SECURITY_FIPS)) { 43663e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "ignoring key unauthenticated for high security"); 436760b83f57SWaldemar Rymarkiewicz goto not_found; 436860b83f57SWaldemar Rymarkiewicz } 436960b83f57SWaldemar Rymarkiewicz 4370cb6f3f7aSJohan Hedberg conn_set_key(conn, key->type, key->pin_len); 437160b83f57SWaldemar Rymarkiewicz } 437260b83f57SWaldemar Rymarkiewicz 437355ed8ca1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 43749b3b4460SAndrei Emeltchenko memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE); 437555ed8ca1SJohan Hedberg 437655ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp); 437755ed8ca1SJohan Hedberg 437855ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 437955ed8ca1SJohan Hedberg 438055ed8ca1SJohan Hedberg return; 438155ed8ca1SJohan Hedberg 438255ed8ca1SJohan Hedberg not_found: 438355ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr); 438455ed8ca1SJohan Hedberg hci_dev_unlock(hdev); 43851da177e4SLinus Torvalds } 43861da177e4SLinus Torvalds 43873e54c589SLuiz Augusto von Dentz static void hci_link_key_notify_evt(struct hci_dev *hdev, void *data, 43883e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 43891da177e4SLinus Torvalds { 43903e54c589SLuiz Augusto von Dentz struct hci_ev_link_key_notify *ev = data; 4391052b30b0SMarcel Holtmann struct hci_conn *conn; 43927652ff6aSJohan Hedberg struct link_key *key; 43937652ff6aSJohan Hedberg bool persistent; 439455ed8ca1SJohan Hedberg u8 pin_len = 0; 4395052b30b0SMarcel Holtmann 43963e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 4397052b30b0SMarcel Holtmann 4398052b30b0SMarcel Holtmann hci_dev_lock(hdev); 4399052b30b0SMarcel Holtmann 4400052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 440182c13d42SJohan Hedberg if (!conn) 440282c13d42SJohan Hedberg goto unlock; 440382c13d42SJohan Hedberg 4404052b30b0SMarcel Holtmann hci_conn_hold(conn); 4405052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT; 440676a68ba0SDavid Herrmann hci_conn_drop(conn); 440782c13d42SJohan Hedberg 4408fe8bc5acSJohan Hedberg set_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags); 4409cb6f3f7aSJohan Hedberg conn_set_key(conn, ev->key_type, conn->pin_length); 4410052b30b0SMarcel Holtmann 4411d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 44127652ff6aSJohan Hedberg goto unlock; 441355ed8ca1SJohan Hedberg 44147652ff6aSJohan Hedberg key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key, 44157652ff6aSJohan Hedberg ev->key_type, pin_len, &persistent); 44167652ff6aSJohan Hedberg if (!key) 44177652ff6aSJohan Hedberg goto unlock; 44187652ff6aSJohan Hedberg 4419cb6f3f7aSJohan Hedberg /* Update connection information since adding the key will have 4420cb6f3f7aSJohan Hedberg * fixed up the type in the case of changed combination keys. 4421cb6f3f7aSJohan Hedberg */ 4422cb6f3f7aSJohan Hedberg if (ev->key_type == HCI_LK_CHANGED_COMBINATION) 4423cb6f3f7aSJohan Hedberg conn_set_key(conn, key->type, key->pin_len); 4424cb6f3f7aSJohan Hedberg 44257652ff6aSJohan Hedberg mgmt_new_link_key(hdev, key, persistent); 44267652ff6aSJohan Hedberg 44276d5650c4SJohan Hedberg /* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag 44286d5650c4SJohan Hedberg * is set. If it's not set simply remove the key from the kernel 44296d5650c4SJohan Hedberg * list (we've still notified user space about it but with 44306d5650c4SJohan Hedberg * store_hint being 0). 44316d5650c4SJohan Hedberg */ 44326d5650c4SJohan Hedberg if (key->type == HCI_LK_DEBUG_COMBINATION && 4433d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS)) { 44340378b597SJohan Hedberg list_del_rcu(&key->list); 44350378b597SJohan Hedberg kfree_rcu(key, rcu); 443682c13d42SJohan Hedberg goto unlock; 443782c13d42SJohan Hedberg } 443882c13d42SJohan Hedberg 4439af6a9c32SJohan Hedberg if (persistent) 4440af6a9c32SJohan Hedberg clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags); 4441af6a9c32SJohan Hedberg else 4442af6a9c32SJohan Hedberg set_bit(HCI_CONN_FLUSH_KEY, &conn->flags); 44437652ff6aSJohan Hedberg 44447652ff6aSJohan Hedberg unlock: 4445052b30b0SMarcel Holtmann hci_dev_unlock(hdev); 44461da177e4SLinus Torvalds } 44471da177e4SLinus Torvalds 44483e54c589SLuiz Augusto von Dentz static void hci_clock_offset_evt(struct hci_dev *hdev, void *data, 44493e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 445004837f64SMarcel Holtmann { 44513e54c589SLuiz Augusto von Dentz struct hci_ev_clock_offset *ev = data; 445204837f64SMarcel Holtmann struct hci_conn *conn; 445304837f64SMarcel Holtmann 44543e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 445504837f64SMarcel Holtmann 445604837f64SMarcel Holtmann hci_dev_lock(hdev); 445704837f64SMarcel Holtmann 445804837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 44591da177e4SLinus Torvalds if (conn && !ev->status) { 44601da177e4SLinus Torvalds struct inquiry_entry *ie; 44611da177e4SLinus Torvalds 4462cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 4463cc11b9c1SAndrei Emeltchenko if (ie) { 44641da177e4SLinus Torvalds ie->data.clock_offset = ev->clock_offset; 44651da177e4SLinus Torvalds ie->timestamp = jiffies; 44661da177e4SLinus Torvalds } 44671da177e4SLinus Torvalds } 44681da177e4SLinus Torvalds 44691da177e4SLinus Torvalds hci_dev_unlock(hdev); 44701da177e4SLinus Torvalds } 44711da177e4SLinus Torvalds 44723e54c589SLuiz Augusto von Dentz static void hci_pkt_type_change_evt(struct hci_dev *hdev, void *data, 44733e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 4474a8746417SMarcel Holtmann { 44753e54c589SLuiz Augusto von Dentz struct hci_ev_pkt_type_change *ev = data; 4476a8746417SMarcel Holtmann struct hci_conn *conn; 4477a8746417SMarcel Holtmann 44783e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 4479a8746417SMarcel Holtmann 4480a8746417SMarcel Holtmann hci_dev_lock(hdev); 4481a8746417SMarcel Holtmann 4482a8746417SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 4483a8746417SMarcel Holtmann if (conn && !ev->status) 4484a8746417SMarcel Holtmann conn->pkt_type = __le16_to_cpu(ev->pkt_type); 4485a8746417SMarcel Holtmann 4486a8746417SMarcel Holtmann hci_dev_unlock(hdev); 4487a8746417SMarcel Holtmann } 4488a8746417SMarcel Holtmann 44893e54c589SLuiz Augusto von Dentz static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, void *data, 44903e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 449185a1e930SMarcel Holtmann { 44923e54c589SLuiz Augusto von Dentz struct hci_ev_pscan_rep_mode *ev = data; 449385a1e930SMarcel Holtmann struct inquiry_entry *ie; 449485a1e930SMarcel Holtmann 44953e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 449685a1e930SMarcel Holtmann 449785a1e930SMarcel Holtmann hci_dev_lock(hdev); 449885a1e930SMarcel Holtmann 4499cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 4500cc11b9c1SAndrei Emeltchenko if (ie) { 450185a1e930SMarcel Holtmann ie->data.pscan_rep_mode = ev->pscan_rep_mode; 450285a1e930SMarcel Holtmann ie->timestamp = jiffies; 450385a1e930SMarcel Holtmann } 450485a1e930SMarcel Holtmann 450585a1e930SMarcel Holtmann hci_dev_unlock(hdev); 450685a1e930SMarcel Holtmann } 450785a1e930SMarcel Holtmann 45083e54c589SLuiz Augusto von Dentz static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, void *edata, 4509807deac2SGustavo Padovan struct sk_buff *skb) 4510a9de9248SMarcel Holtmann { 45118d08d324SLuiz Augusto von Dentz union { 45128d08d324SLuiz Augusto von Dentz struct hci_ev_inquiry_result_rssi *res1; 45138d08d324SLuiz Augusto von Dentz struct hci_ev_inquiry_result_rssi_pscan *res2; 45143e54c589SLuiz Augusto von Dentz } *ev = edata; 4515a9de9248SMarcel Holtmann struct inquiry_data data; 45168d08d324SLuiz Augusto von Dentz int i; 4517a9de9248SMarcel Holtmann 45183e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "num_rsp %d", ev->res1->num); 45198d08d324SLuiz Augusto von Dentz 45208d08d324SLuiz Augusto von Dentz if (!ev->res1->num) 4521a9de9248SMarcel Holtmann return; 4522a9de9248SMarcel Holtmann 4523d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) 45241519cc17SAndre Guedes return; 45251519cc17SAndre Guedes 4526a9de9248SMarcel Holtmann hci_dev_lock(hdev); 4527a9de9248SMarcel Holtmann 45288d08d324SLuiz Augusto von Dentz if (skb->len == flex_array_size(ev, res2->info, ev->res2->num)) { 45298d08d324SLuiz Augusto von Dentz struct inquiry_info_rssi_pscan *info; 4530a9de9248SMarcel Holtmann 45318d08d324SLuiz Augusto von Dentz for (i = 0; i < ev->res2->num; i++) { 4532af58925cSMarcel Holtmann u32 flags; 4533af58925cSMarcel Holtmann 45348d08d324SLuiz Augusto von Dentz info = &ev->res2->info[i]; 4535a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 4536a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 4537a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 4538a9de9248SMarcel Holtmann data.pscan_mode = info->pscan_mode; 4539a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 4540a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 4541a9de9248SMarcel Holtmann data.rssi = info->rssi; 454241a96212SMarcel Holtmann data.ssp_mode = 0x00; 45433175405bSJohan Hedberg 4544af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 4545af58925cSMarcel Holtmann 454648264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 4547e17acd40SJohan Hedberg info->dev_class, info->rssi, 4548af58925cSMarcel Holtmann flags, NULL, 0, NULL, 0); 4549a9de9248SMarcel Holtmann } 45508d08d324SLuiz Augusto von Dentz } else if (skb->len == flex_array_size(ev, res1->info, ev->res1->num)) { 45518d08d324SLuiz Augusto von Dentz struct inquiry_info_rssi *info; 4552a9de9248SMarcel Holtmann 45538d08d324SLuiz Augusto von Dentz for (i = 0; i < ev->res1->num; i++) { 4554af58925cSMarcel Holtmann u32 flags; 4555af58925cSMarcel Holtmann 45568d08d324SLuiz Augusto von Dentz info = &ev->res1->info[i]; 4557a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 4558a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 4559a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 4560a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 4561a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 4562a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 4563a9de9248SMarcel Holtmann data.rssi = info->rssi; 456441a96212SMarcel Holtmann data.ssp_mode = 0x00; 4565af58925cSMarcel Holtmann 4566af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false); 4567af58925cSMarcel Holtmann 456848264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 4569e17acd40SJohan Hedberg info->dev_class, info->rssi, 4570af58925cSMarcel Holtmann flags, NULL, 0, NULL, 0); 4571a9de9248SMarcel Holtmann } 45728d08d324SLuiz Augusto von Dentz } else { 45738d08d324SLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x", 45748d08d324SLuiz Augusto von Dentz HCI_EV_INQUIRY_RESULT_WITH_RSSI); 4575a9de9248SMarcel Holtmann } 4576a9de9248SMarcel Holtmann 4577a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 4578a9de9248SMarcel Holtmann } 4579a9de9248SMarcel Holtmann 45803e54c589SLuiz Augusto von Dentz static void hci_remote_ext_features_evt(struct hci_dev *hdev, void *data, 4581807deac2SGustavo Padovan struct sk_buff *skb) 4582a9de9248SMarcel Holtmann { 45833e54c589SLuiz Augusto von Dentz struct hci_ev_remote_ext_features *ev = data; 458441a96212SMarcel Holtmann struct hci_conn *conn; 458541a96212SMarcel Holtmann 45863e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 458741a96212SMarcel Holtmann 458841a96212SMarcel Holtmann hci_dev_lock(hdev); 458941a96212SMarcel Holtmann 459041a96212SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 4591ccd556feSJohan Hedberg if (!conn) 4592ccd556feSJohan Hedberg goto unlock; 4593ccd556feSJohan Hedberg 4594cad718edSJohan Hedberg if (ev->page < HCI_MAX_PAGES) 4595cad718edSJohan Hedberg memcpy(conn->features[ev->page], ev->features, 8); 4596cad718edSJohan Hedberg 4597769be974SMarcel Holtmann if (!ev->status && ev->page == 0x01) { 459841a96212SMarcel Holtmann struct inquiry_entry *ie; 459941a96212SMarcel Holtmann 4600cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst); 4601cc11b9c1SAndrei Emeltchenko if (ie) 460202b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 460341a96212SMarcel Holtmann 4604bbb0eadaSJaganath Kanakkassery if (ev->features[0] & LMP_HOST_SSP) { 460558a681efSJohan Hedberg set_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 4606bbb0eadaSJaganath Kanakkassery } else { 4607bbb0eadaSJaganath Kanakkassery /* It is mandatory by the Bluetooth specification that 4608bbb0eadaSJaganath Kanakkassery * Extended Inquiry Results are only used when Secure 4609bbb0eadaSJaganath Kanakkassery * Simple Pairing is enabled, but some devices violate 4610bbb0eadaSJaganath Kanakkassery * this. 4611bbb0eadaSJaganath Kanakkassery * 4612bbb0eadaSJaganath Kanakkassery * To make these devices work, the internal SSP 4613bbb0eadaSJaganath Kanakkassery * enabled flag needs to be cleared if the remote host 4614bbb0eadaSJaganath Kanakkassery * features do not indicate SSP support */ 4615bbb0eadaSJaganath Kanakkassery clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 4616bbb0eadaSJaganath Kanakkassery } 4617eb9a8f3fSMarcel Holtmann 4618eb9a8f3fSMarcel Holtmann if (ev->features[0] & LMP_HOST_SC) 4619eb9a8f3fSMarcel Holtmann set_bit(HCI_CONN_SC_ENABLED, &conn->flags); 462041a96212SMarcel Holtmann } 462141a96212SMarcel Holtmann 4622ccd556feSJohan Hedberg if (conn->state != BT_CONFIG) 4623ccd556feSJohan Hedberg goto unlock; 4624ccd556feSJohan Hedberg 4625671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { 4626127178d2SJohan Hedberg struct hci_cp_remote_name_req cp; 4627127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp)); 4628127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst); 4629127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02; 4630127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); 4631b644ba33SJohan Hedberg } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 46321c6ed31bSYu Liu mgmt_device_connected(hdev, conn, NULL, 0); 4633392599b9SJohan Hedberg 4634127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) { 4635769be974SMarcel Holtmann conn->state = BT_CONNECTED; 4636539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 463776a68ba0SDavid Herrmann hci_conn_drop(conn); 4638769be974SMarcel Holtmann } 4639769be974SMarcel Holtmann 4640ccd556feSJohan Hedberg unlock: 464141a96212SMarcel Holtmann hci_dev_unlock(hdev); 4642a9de9248SMarcel Holtmann } 4643a9de9248SMarcel Holtmann 46443e54c589SLuiz Augusto von Dentz static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data, 4645807deac2SGustavo Padovan struct sk_buff *skb) 4646a9de9248SMarcel Holtmann { 46473e54c589SLuiz Augusto von Dentz struct hci_ev_sync_conn_complete *ev = data; 4648b6a0dc82SMarcel Holtmann struct hci_conn *conn; 4649b6a0dc82SMarcel Holtmann 46503e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 4651b6a0dc82SMarcel Holtmann 4652b6a0dc82SMarcel Holtmann hci_dev_lock(hdev); 4653b6a0dc82SMarcel Holtmann 4654b6a0dc82SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 46559dc0a3afSMarcel Holtmann if (!conn) { 46569dc0a3afSMarcel Holtmann if (ev->link_type == ESCO_LINK) 46579dc0a3afSMarcel Holtmann goto unlock; 46589dc0a3afSMarcel Holtmann 4659618353b1SKuba Pawlak /* When the link type in the event indicates SCO connection 4660618353b1SKuba Pawlak * and lookup of the connection object fails, then check 4661618353b1SKuba Pawlak * if an eSCO connection object exists. 4662618353b1SKuba Pawlak * 4663618353b1SKuba Pawlak * The core limits the synchronous connections to either 4664618353b1SKuba Pawlak * SCO or eSCO. The eSCO connection is preferred and tried 4665618353b1SKuba Pawlak * to be setup first and until successfully established, 4666618353b1SKuba Pawlak * the link type will be hinted as eSCO. 4667618353b1SKuba Pawlak */ 46689dc0a3afSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); 4669b6a0dc82SMarcel Holtmann if (!conn) 4670b6a0dc82SMarcel Holtmann goto unlock; 46719dc0a3afSMarcel Holtmann } 46729dc0a3afSMarcel Holtmann 4673732547f9SMarcel Holtmann switch (ev->status) { 4674732547f9SMarcel Holtmann case 0x00: 467592fe24a7SDesmond Cheong Zhi Xi /* The synchronous connection complete event should only be 467692fe24a7SDesmond Cheong Zhi Xi * sent once per new connection. Receiving a successful 467792fe24a7SDesmond Cheong Zhi Xi * complete event when the connection status is already 467892fe24a7SDesmond Cheong Zhi Xi * BT_CONNECTED means that the device is misbehaving and sent 467992fe24a7SDesmond Cheong Zhi Xi * multiple complete event packets for the same new connection. 468092fe24a7SDesmond Cheong Zhi Xi * 468192fe24a7SDesmond Cheong Zhi Xi * Registering the device more than once can corrupt kernel 468292fe24a7SDesmond Cheong Zhi Xi * memory, hence upon detecting this invalid event, we report 468392fe24a7SDesmond Cheong Zhi Xi * an error and ignore the packet. 468492fe24a7SDesmond Cheong Zhi Xi */ 468592fe24a7SDesmond Cheong Zhi Xi if (conn->state == BT_CONNECTED) { 468692fe24a7SDesmond Cheong Zhi Xi bt_dev_err(hdev, "Ignoring connect complete event for existing connection"); 468792fe24a7SDesmond Cheong Zhi Xi goto unlock; 468892fe24a7SDesmond Cheong Zhi Xi } 468992fe24a7SDesmond Cheong Zhi Xi 4690732547f9SMarcel Holtmann conn->handle = __le16_to_cpu(ev->handle); 4691732547f9SMarcel Holtmann conn->state = BT_CONNECTED; 4692618353b1SKuba Pawlak conn->type = ev->link_type; 4693732547f9SMarcel Holtmann 469423b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn); 4695732547f9SMarcel Holtmann hci_conn_add_sysfs(conn); 4696732547f9SMarcel Holtmann break; 4697732547f9SMarcel Holtmann 469881218d20SNick Pelly case 0x10: /* Connection Accept Timeout */ 46991a4c958cSFrédéric Dalleau case 0x0d: /* Connection Rejected due to Limited Resources */ 4700705e5711SStephen Coe case 0x11: /* Unsupported Feature or Parameter Value */ 4701732547f9SMarcel Holtmann case 0x1c: /* SCO interval rejected */ 47021038a00bSNick Pelly case 0x1a: /* Unsupported Remote Feature */ 470356b5453aSHsin-Yu Chao case 0x1e: /* Invalid LMP Parameters */ 4704732547f9SMarcel Holtmann case 0x1f: /* Unspecified error */ 470527539bc4SAndrew Earl case 0x20: /* Unsupported LMP Parameter value */ 47062dea632fSFrédéric Dalleau if (conn->out) { 4707efc7688bSMarcel Holtmann conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | 4708efc7688bSMarcel Holtmann (hdev->esco_type & EDR_ESCO_MASK); 47092dea632fSFrédéric Dalleau if (hci_setup_sync(conn, conn->link->handle)) 4710efc7688bSMarcel Holtmann goto unlock; 4711efc7688bSMarcel Holtmann } 471219186c7bSGustavo A. R. Silva fallthrough; 4713efc7688bSMarcel Holtmann 4714732547f9SMarcel Holtmann default: 4715b6a0dc82SMarcel Holtmann conn->state = BT_CLOSED; 4716732547f9SMarcel Holtmann break; 4717732547f9SMarcel Holtmann } 4718b6a0dc82SMarcel Holtmann 47191f8330eaSSathish Narsimman bt_dev_dbg(hdev, "SCO connected with air mode: %02x", ev->air_mode); 4720f4f9fa0cSChethan T N /* Notify only in case of SCO over HCI transport data path which 4721f4f9fa0cSChethan T N * is zero and non-zero value shall be non-HCI transport data path 4722f4f9fa0cSChethan T N */ 4723a27c519aSJackie Liu if (conn->codec.data_path == 0 && hdev->notify) { 4724a27c519aSJackie Liu switch (ev->air_mode) { 4725a27c519aSJackie Liu case 0x02: 4726a27c519aSJackie Liu hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD); 4727a27c519aSJackie Liu break; 4728a27c519aSJackie Liu case 0x03: 4729a27c519aSJackie Liu hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP); 4730a27c519aSJackie Liu break; 4731a27c519aSJackie Liu } 4732f4f9fa0cSChethan T N } 4733f4f9fa0cSChethan T N 4734539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 4735b6a0dc82SMarcel Holtmann if (ev->status) 4736b6a0dc82SMarcel Holtmann hci_conn_del(conn); 4737b6a0dc82SMarcel Holtmann 4738b6a0dc82SMarcel Holtmann unlock: 4739b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev); 4740a9de9248SMarcel Holtmann } 4741a9de9248SMarcel Holtmann 4742efdcf8e3SMarcel Holtmann static inline size_t eir_get_length(u8 *eir, size_t eir_len) 4743efdcf8e3SMarcel Holtmann { 4744efdcf8e3SMarcel Holtmann size_t parsed = 0; 4745efdcf8e3SMarcel Holtmann 4746efdcf8e3SMarcel Holtmann while (parsed < eir_len) { 4747efdcf8e3SMarcel Holtmann u8 field_len = eir[0]; 4748efdcf8e3SMarcel Holtmann 4749efdcf8e3SMarcel Holtmann if (field_len == 0) 4750efdcf8e3SMarcel Holtmann return parsed; 4751efdcf8e3SMarcel Holtmann 4752efdcf8e3SMarcel Holtmann parsed += field_len + 1; 4753efdcf8e3SMarcel Holtmann eir += field_len + 1; 4754efdcf8e3SMarcel Holtmann } 4755efdcf8e3SMarcel Holtmann 4756efdcf8e3SMarcel Holtmann return eir_len; 4757efdcf8e3SMarcel Holtmann } 4758efdcf8e3SMarcel Holtmann 47593e54c589SLuiz Augusto von Dentz static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, void *edata, 4760807deac2SGustavo Padovan struct sk_buff *skb) 4761a9de9248SMarcel Holtmann { 47623e54c589SLuiz Augusto von Dentz struct hci_ev_ext_inquiry_result *ev = edata; 4763a9de9248SMarcel Holtmann struct inquiry_data data; 47649d939d94SVishal Agarwal size_t eir_len; 476570a6b8deSLuiz Augusto von Dentz int i; 4766a9de9248SMarcel Holtmann 476770a6b8deSLuiz Augusto von Dentz if (!hci_ev_skb_pull(hdev, skb, HCI_EV_EXTENDED_INQUIRY_RESULT, 476870a6b8deSLuiz Augusto von Dentz flex_array_size(ev, info, ev->num))) 476970a6b8deSLuiz Augusto von Dentz return; 477070a6b8deSLuiz Augusto von Dentz 47713e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "num %d", ev->num); 477270a6b8deSLuiz Augusto von Dentz 477370a6b8deSLuiz Augusto von Dentz if (!ev->num) 4774a9de9248SMarcel Holtmann return; 4775a9de9248SMarcel Holtmann 4776d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) 47771519cc17SAndre Guedes return; 47781519cc17SAndre Guedes 4779a9de9248SMarcel Holtmann hci_dev_lock(hdev); 4780a9de9248SMarcel Holtmann 478170a6b8deSLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) { 478270a6b8deSLuiz Augusto von Dentz struct extended_inquiry_info *info = &ev->info[i]; 4783af58925cSMarcel Holtmann u32 flags; 4784af58925cSMarcel Holtmann bool name_known; 4785561aafbcSJohan Hedberg 4786a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr); 4787a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode; 4788a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode; 4789a9de9248SMarcel Holtmann data.pscan_mode = 0x00; 4790a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3); 4791a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset; 4792a9de9248SMarcel Holtmann data.rssi = info->rssi; 479341a96212SMarcel Holtmann data.ssp_mode = 0x01; 4794561aafbcSJohan Hedberg 4795d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 47960d3b7f64SJohan Hedberg name_known = eir_get_data(info->data, 47974ddb1930SJohan Hedberg sizeof(info->data), 47980d3b7f64SJohan Hedberg EIR_NAME_COMPLETE, NULL); 4799561aafbcSJohan Hedberg else 4800561aafbcSJohan Hedberg name_known = true; 4801561aafbcSJohan Hedberg 4802af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, name_known); 4803af58925cSMarcel Holtmann 48049d939d94SVishal Agarwal eir_len = eir_get_length(info->data, sizeof(info->data)); 4805af58925cSMarcel Holtmann 480648264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 4807af58925cSMarcel Holtmann info->dev_class, info->rssi, 4808af58925cSMarcel Holtmann flags, info->data, eir_len, NULL, 0); 4809a9de9248SMarcel Holtmann } 4810a9de9248SMarcel Holtmann 4811a9de9248SMarcel Holtmann hci_dev_unlock(hdev); 4812a9de9248SMarcel Holtmann } 4813a9de9248SMarcel Holtmann 48143e54c589SLuiz Augusto von Dentz static void hci_key_refresh_complete_evt(struct hci_dev *hdev, void *data, 48151c2e0041SJohan Hedberg struct sk_buff *skb) 48161c2e0041SJohan Hedberg { 48173e54c589SLuiz Augusto von Dentz struct hci_ev_key_refresh_complete *ev = data; 48181c2e0041SJohan Hedberg struct hci_conn *conn; 48191c2e0041SJohan Hedberg 48203e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x handle 0x%4.4x", ev->status, 48211c2e0041SJohan Hedberg __le16_to_cpu(ev->handle)); 48221c2e0041SJohan Hedberg 48231c2e0041SJohan Hedberg hci_dev_lock(hdev); 48241c2e0041SJohan Hedberg 48251c2e0041SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 48261c2e0041SJohan Hedberg if (!conn) 48271c2e0041SJohan Hedberg goto unlock; 48281c2e0041SJohan Hedberg 48299eb1fbfaSJohan Hedberg /* For BR/EDR the necessary steps are taken through the 48309eb1fbfaSJohan Hedberg * auth_complete event. 48319eb1fbfaSJohan Hedberg */ 48329eb1fbfaSJohan Hedberg if (conn->type != LE_LINK) 48339eb1fbfaSJohan Hedberg goto unlock; 48349eb1fbfaSJohan Hedberg 48351c2e0041SJohan Hedberg if (!ev->status) 48361c2e0041SJohan Hedberg conn->sec_level = conn->pending_sec_level; 48371c2e0041SJohan Hedberg 48381c2e0041SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); 48391c2e0041SJohan Hedberg 48401c2e0041SJohan Hedberg if (ev->status && conn->state == BT_CONNECTED) { 4841bed71748SAndre Guedes hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); 484276a68ba0SDavid Herrmann hci_conn_drop(conn); 48431c2e0041SJohan Hedberg goto unlock; 48441c2e0041SJohan Hedberg } 48451c2e0041SJohan Hedberg 48461c2e0041SJohan Hedberg if (conn->state == BT_CONFIG) { 48471c2e0041SJohan Hedberg if (!ev->status) 48481c2e0041SJohan Hedberg conn->state = BT_CONNECTED; 48491c2e0041SJohan Hedberg 4850539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status); 485176a68ba0SDavid Herrmann hci_conn_drop(conn); 48521c2e0041SJohan Hedberg } else { 48531c2e0041SJohan Hedberg hci_auth_cfm(conn, ev->status); 48541c2e0041SJohan Hedberg 48551c2e0041SJohan Hedberg hci_conn_hold(conn); 48561c2e0041SJohan Hedberg conn->disc_timeout = HCI_DISCONN_TIMEOUT; 485776a68ba0SDavid Herrmann hci_conn_drop(conn); 48581c2e0041SJohan Hedberg } 48591c2e0041SJohan Hedberg 48601c2e0041SJohan Hedberg unlock: 48611c2e0041SJohan Hedberg hci_dev_unlock(hdev); 48621c2e0041SJohan Hedberg } 48631c2e0041SJohan Hedberg 48646039aa73SGustavo Padovan static u8 hci_get_auth_req(struct hci_conn *conn) 486517fa4b9dSJohan Hedberg { 486617fa4b9dSJohan Hedberg /* If remote requests no-bonding follow that lead */ 4867acabae96SMikel Astiz if (conn->remote_auth == HCI_AT_NO_BONDING || 4868acabae96SMikel Astiz conn->remote_auth == HCI_AT_NO_BONDING_MITM) 486958797bf7SWaldemar Rymarkiewicz return conn->remote_auth | (conn->auth_type & 0x01); 487017fa4b9dSJohan Hedberg 4871b7f94c88SMikel Astiz /* If both remote and local have enough IO capabilities, require 4872b7f94c88SMikel Astiz * MITM protection 4873b7f94c88SMikel Astiz */ 4874b7f94c88SMikel Astiz if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT && 4875b7f94c88SMikel Astiz conn->io_capability != HCI_IO_NO_INPUT_OUTPUT) 4876b7f94c88SMikel Astiz return conn->remote_auth | 0x01; 4877b7f94c88SMikel Astiz 48787e74170aSTimo Mueller /* No MITM protection possible so ignore remote requirement */ 48797e74170aSTimo Mueller return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01); 488017fa4b9dSJohan Hedberg } 488117fa4b9dSJohan Hedberg 4882a83ed81eSMarcel Holtmann static u8 bredr_oob_data_present(struct hci_conn *conn) 4883a83ed81eSMarcel Holtmann { 4884a83ed81eSMarcel Holtmann struct hci_dev *hdev = conn->hdev; 4885a83ed81eSMarcel Holtmann struct oob_data *data; 4886a83ed81eSMarcel Holtmann 4887a83ed81eSMarcel Holtmann data = hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR); 4888a83ed81eSMarcel Holtmann if (!data) 4889a83ed81eSMarcel Holtmann return 0x00; 4890a83ed81eSMarcel Holtmann 4891bf21d793SMarcel Holtmann if (bredr_sc_enabled(hdev)) { 4892bf21d793SMarcel Holtmann /* When Secure Connections is enabled, then just 4893bf21d793SMarcel Holtmann * return the present value stored with the OOB 4894bf21d793SMarcel Holtmann * data. The stored value contains the right present 4895bf21d793SMarcel Holtmann * information. However it can only be trusted when 4896bf21d793SMarcel Holtmann * not in Secure Connection Only mode. 4897aa5b0345SMarcel Holtmann */ 4898d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SC_ONLY)) 4899bf21d793SMarcel Holtmann return data->present; 4900bf21d793SMarcel Holtmann 4901bf21d793SMarcel Holtmann /* When Secure Connections Only mode is enabled, then 4902bf21d793SMarcel Holtmann * the P-256 values are required. If they are not 4903bf21d793SMarcel Holtmann * available, then do not declare that OOB data is 4904bf21d793SMarcel Holtmann * present. 4905bf21d793SMarcel Holtmann */ 4906bf21d793SMarcel Holtmann if (!memcmp(data->rand256, ZERO_KEY, 16) || 4907bf21d793SMarcel Holtmann !memcmp(data->hash256, ZERO_KEY, 16)) 4908aa5b0345SMarcel Holtmann return 0x00; 4909aa5b0345SMarcel Holtmann 4910bf21d793SMarcel Holtmann return 0x02; 4911bf21d793SMarcel Holtmann } 4912659c7fb0SMarcel Holtmann 4913659c7fb0SMarcel Holtmann /* When Secure Connections is not enabled or actually 4914659c7fb0SMarcel Holtmann * not supported by the hardware, then check that if 4915659c7fb0SMarcel Holtmann * P-192 data values are present. 4916659c7fb0SMarcel Holtmann */ 4917659c7fb0SMarcel Holtmann if (!memcmp(data->rand192, ZERO_KEY, 16) || 4918659c7fb0SMarcel Holtmann !memcmp(data->hash192, ZERO_KEY, 16)) 4919659c7fb0SMarcel Holtmann return 0x00; 4920659c7fb0SMarcel Holtmann 4921a83ed81eSMarcel Holtmann return 0x01; 4922659c7fb0SMarcel Holtmann } 4923a83ed81eSMarcel Holtmann 49243e54c589SLuiz Augusto von Dentz static void hci_io_capa_request_evt(struct hci_dev *hdev, void *data, 49253e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 49260493684eSMarcel Holtmann { 49273e54c589SLuiz Augusto von Dentz struct hci_ev_io_capa_request *ev = data; 49280493684eSMarcel Holtmann struct hci_conn *conn; 49290493684eSMarcel Holtmann 49303e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 49310493684eSMarcel Holtmann 49320493684eSMarcel Holtmann hci_dev_lock(hdev); 49330493684eSMarcel Holtmann 49340493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 493503b555e1SJohan Hedberg if (!conn) 493603b555e1SJohan Hedberg goto unlock; 493703b555e1SJohan Hedberg 49380493684eSMarcel Holtmann hci_conn_hold(conn); 49390493684eSMarcel Holtmann 4940d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 494103b555e1SJohan Hedberg goto unlock; 494203b555e1SJohan Hedberg 49432f407f0aSJohan Hedberg /* Allow pairing if we're pairable, the initiators of the 49442f407f0aSJohan Hedberg * pairing or if the remote is not requesting bonding. 49452f407f0aSJohan Hedberg */ 4946d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_BONDABLE) || 49472f407f0aSJohan Hedberg test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags) || 494803b555e1SJohan Hedberg (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { 494917fa4b9dSJohan Hedberg struct hci_cp_io_capability_reply cp; 495017fa4b9dSJohan Hedberg 495117fa4b9dSJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 49527a7f1e7cSHemant Gupta /* Change the IO capability from KeyboardDisplay 49537a7f1e7cSHemant Gupta * to DisplayYesNo as it is not supported by BT spec. */ 49547a7f1e7cSHemant Gupta cp.capability = (conn->io_capability == 0x04) ? 4955a767631aSMikel Astiz HCI_IO_DISPLAY_YESNO : conn->io_capability; 4956b7f94c88SMikel Astiz 4957b7f94c88SMikel Astiz /* If we are initiators, there is no remote information yet */ 4958b7f94c88SMikel Astiz if (conn->remote_auth == 0xff) { 4959b16c6604SMikel Astiz /* Request MITM protection if our IO caps allow it 49604ad51a75SJohan Hedberg * except for the no-bonding case. 4961b16c6604SMikel Astiz */ 49626fd6b915SMikel Astiz if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT && 49639f743d74SJohan Hedberg conn->auth_type != HCI_AT_NO_BONDING) 49646c53823aSJohan Hedberg conn->auth_type |= 0x01; 4965b7f94c88SMikel Astiz } else { 49667cbc9bd9SJohan Hedberg conn->auth_type = hci_get_auth_req(conn); 4967b7f94c88SMikel Astiz } 496817fa4b9dSJohan Hedberg 496982c295b1SJohan Hedberg /* If we're not bondable, force one of the non-bondable 497082c295b1SJohan Hedberg * authentication requirement values. 497182c295b1SJohan Hedberg */ 4972d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE)) 497382c295b1SJohan Hedberg conn->auth_type &= HCI_AT_NO_BONDING_MITM; 497482c295b1SJohan Hedberg 497582c295b1SJohan Hedberg cp.authentication = conn->auth_type; 4976a83ed81eSMarcel Holtmann cp.oob_data = bredr_oob_data_present(conn); 4977ce85ee13SSzymon Janc 497817fa4b9dSJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY, 497917fa4b9dSJohan Hedberg sizeof(cp), &cp); 498003b555e1SJohan Hedberg } else { 498103b555e1SJohan Hedberg struct hci_cp_io_capability_neg_reply cp; 498203b555e1SJohan Hedberg 498303b555e1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr); 49849f5a0d7bSAndrei Emeltchenko cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED; 498503b555e1SJohan Hedberg 498603b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, 498703b555e1SJohan Hedberg sizeof(cp), &cp); 498803b555e1SJohan Hedberg } 498903b555e1SJohan Hedberg 499003b555e1SJohan Hedberg unlock: 499103b555e1SJohan Hedberg hci_dev_unlock(hdev); 499203b555e1SJohan Hedberg } 499303b555e1SJohan Hedberg 49943e54c589SLuiz Augusto von Dentz static void hci_io_capa_reply_evt(struct hci_dev *hdev, void *data, 49953e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 499603b555e1SJohan Hedberg { 49973e54c589SLuiz Augusto von Dentz struct hci_ev_io_capa_reply *ev = data; 499803b555e1SJohan Hedberg struct hci_conn *conn; 499903b555e1SJohan Hedberg 50003e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 500103b555e1SJohan Hedberg 500203b555e1SJohan Hedberg hci_dev_lock(hdev); 500303b555e1SJohan Hedberg 500403b555e1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 500503b555e1SJohan Hedberg if (!conn) 500603b555e1SJohan Hedberg goto unlock; 500703b555e1SJohan Hedberg 500803b555e1SJohan Hedberg conn->remote_cap = ev->capability; 500903b555e1SJohan Hedberg conn->remote_auth = ev->authentication; 501003b555e1SJohan Hedberg 501103b555e1SJohan Hedberg unlock: 50120493684eSMarcel Holtmann hci_dev_unlock(hdev); 50130493684eSMarcel Holtmann } 50140493684eSMarcel Holtmann 50153e54c589SLuiz Augusto von Dentz static void hci_user_confirm_request_evt(struct hci_dev *hdev, void *data, 5016a5c29683SJohan Hedberg struct sk_buff *skb) 5017a5c29683SJohan Hedberg { 50183e54c589SLuiz Augusto von Dentz struct hci_ev_user_confirm_req *ev = data; 501955bc1a37SJohan Hedberg int loc_mitm, rem_mitm, confirm_hint = 0; 50207a828908SJohan Hedberg struct hci_conn *conn; 5021a5c29683SJohan Hedberg 50223e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 5023a5c29683SJohan Hedberg 5024a5c29683SJohan Hedberg hci_dev_lock(hdev); 5025a5c29683SJohan Hedberg 5026d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 50277a828908SJohan Hedberg goto unlock; 50287a828908SJohan Hedberg 50297a828908SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 50307a828908SJohan Hedberg if (!conn) 50317a828908SJohan Hedberg goto unlock; 50327a828908SJohan Hedberg 50337a828908SJohan Hedberg loc_mitm = (conn->auth_type & 0x01); 50347a828908SJohan Hedberg rem_mitm = (conn->remote_auth & 0x01); 50357a828908SJohan Hedberg 50367a828908SJohan Hedberg /* If we require MITM but the remote device can't provide that 50376c53823aSJohan Hedberg * (it has NoInputNoOutput) then reject the confirmation 50386c53823aSJohan Hedberg * request. We check the security level here since it doesn't 50396c53823aSJohan Hedberg * necessarily match conn->auth_type. 50406fd6b915SMikel Astiz */ 50416c53823aSJohan Hedberg if (conn->pending_sec_level > BT_SECURITY_MEDIUM && 50426c53823aSJohan Hedberg conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) { 50433e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "Rejecting request: remote device can't provide MITM"); 50447a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY, 50457a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 50467a828908SJohan Hedberg goto unlock; 50477a828908SJohan Hedberg } 50487a828908SJohan Hedberg 50497a828908SJohan Hedberg /* If no side requires MITM protection; auto-accept */ 5050a767631aSMikel Astiz if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) && 5051a767631aSMikel Astiz (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) { 505255bc1a37SJohan Hedberg 505355bc1a37SJohan Hedberg /* If we're not the initiators request authorization to 505455bc1a37SJohan Hedberg * proceed from user space (mgmt_user_confirm with 5055ba15a58bSJohan Hedberg * confirm_hint set to 1). The exception is if neither 505602f3e254SJohan Hedberg * side had MITM or if the local IO capability is 505702f3e254SJohan Hedberg * NoInputNoOutput, in which case we do auto-accept 5058ba15a58bSJohan Hedberg */ 5059ba15a58bSJohan Hedberg if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && 506002f3e254SJohan Hedberg conn->io_capability != HCI_IO_NO_INPUT_OUTPUT && 5061ba15a58bSJohan Hedberg (loc_mitm || rem_mitm)) { 50623e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "Confirming auto-accept as acceptor"); 506355bc1a37SJohan Hedberg confirm_hint = 1; 506455bc1a37SJohan Hedberg goto confirm; 506555bc1a37SJohan Hedberg } 506655bc1a37SJohan Hedberg 5067cee5f20fSHoward Chung /* If there already exists link key in local host, leave the 5068cee5f20fSHoward Chung * decision to user space since the remote device could be 5069cee5f20fSHoward Chung * legitimate or malicious. 5070cee5f20fSHoward Chung */ 5071cee5f20fSHoward Chung if (hci_find_link_key(hdev, &ev->bdaddr)) { 5072cee5f20fSHoward Chung bt_dev_dbg(hdev, "Local host already has link key"); 5073cee5f20fSHoward Chung confirm_hint = 1; 5074cee5f20fSHoward Chung goto confirm; 5075cee5f20fSHoward Chung } 5076cee5f20fSHoward Chung 50779f61656aSJohan Hedberg BT_DBG("Auto-accept of user confirmation with %ums delay", 50789f61656aSJohan Hedberg hdev->auto_accept_delay); 50799f61656aSJohan Hedberg 50809f61656aSJohan Hedberg if (hdev->auto_accept_delay > 0) { 50819f61656aSJohan Hedberg int delay = msecs_to_jiffies(hdev->auto_accept_delay); 50827bc18d9dSJohan Hedberg queue_delayed_work(conn->hdev->workqueue, 50837bc18d9dSJohan Hedberg &conn->auto_accept_work, delay); 50849f61656aSJohan Hedberg goto unlock; 50859f61656aSJohan Hedberg } 50869f61656aSJohan Hedberg 50877a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, 50887a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr); 50897a828908SJohan Hedberg goto unlock; 50907a828908SJohan Hedberg } 50917a828908SJohan Hedberg 509255bc1a37SJohan Hedberg confirm: 509339adbffeSJohan Hedberg mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, 509439adbffeSJohan Hedberg le32_to_cpu(ev->passkey), confirm_hint); 5095a5c29683SJohan Hedberg 50967a828908SJohan Hedberg unlock: 5097a5c29683SJohan Hedberg hci_dev_unlock(hdev); 5098a5c29683SJohan Hedberg } 5099a5c29683SJohan Hedberg 51003e54c589SLuiz Augusto von Dentz static void hci_user_passkey_request_evt(struct hci_dev *hdev, void *data, 51011143d458SBrian Gix struct sk_buff *skb) 51021143d458SBrian Gix { 51033e54c589SLuiz Augusto von Dentz struct hci_ev_user_passkey_req *ev = data; 5104ae61a10dSLuiz Augusto von Dentz 51053e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 51061143d458SBrian Gix 5107d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 5108272d90dfSJohan Hedberg mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); 51091143d458SBrian Gix } 51101143d458SBrian Gix 51113e54c589SLuiz Augusto von Dentz static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data, 511292a25256SJohan Hedberg struct sk_buff *skb) 511392a25256SJohan Hedberg { 51143e54c589SLuiz Augusto von Dentz struct hci_ev_user_passkey_notify *ev = data; 511592a25256SJohan Hedberg struct hci_conn *conn; 511692a25256SJohan Hedberg 51173e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 511892a25256SJohan Hedberg 511992a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 512092a25256SJohan Hedberg if (!conn) 512192a25256SJohan Hedberg return; 512292a25256SJohan Hedberg 512392a25256SJohan Hedberg conn->passkey_notify = __le32_to_cpu(ev->passkey); 512492a25256SJohan Hedberg conn->passkey_entered = 0; 512592a25256SJohan Hedberg 5126d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 512792a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 512892a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 512992a25256SJohan Hedberg conn->passkey_entered); 513092a25256SJohan Hedberg } 513192a25256SJohan Hedberg 51323e54c589SLuiz Augusto von Dentz static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data, 51333e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 513492a25256SJohan Hedberg { 51353e54c589SLuiz Augusto von Dentz struct hci_ev_keypress_notify *ev = data; 513692a25256SJohan Hedberg struct hci_conn *conn; 513792a25256SJohan Hedberg 51383e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 513992a25256SJohan Hedberg 514092a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 514192a25256SJohan Hedberg if (!conn) 514292a25256SJohan Hedberg return; 514392a25256SJohan Hedberg 514492a25256SJohan Hedberg switch (ev->type) { 514592a25256SJohan Hedberg case HCI_KEYPRESS_STARTED: 514692a25256SJohan Hedberg conn->passkey_entered = 0; 514792a25256SJohan Hedberg return; 514892a25256SJohan Hedberg 514992a25256SJohan Hedberg case HCI_KEYPRESS_ENTERED: 515092a25256SJohan Hedberg conn->passkey_entered++; 515192a25256SJohan Hedberg break; 515292a25256SJohan Hedberg 515392a25256SJohan Hedberg case HCI_KEYPRESS_ERASED: 515492a25256SJohan Hedberg conn->passkey_entered--; 515592a25256SJohan Hedberg break; 515692a25256SJohan Hedberg 515792a25256SJohan Hedberg case HCI_KEYPRESS_CLEARED: 515892a25256SJohan Hedberg conn->passkey_entered = 0; 515992a25256SJohan Hedberg break; 516092a25256SJohan Hedberg 516192a25256SJohan Hedberg case HCI_KEYPRESS_COMPLETED: 516292a25256SJohan Hedberg return; 516392a25256SJohan Hedberg } 516492a25256SJohan Hedberg 5165d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT)) 516692a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, 516792a25256SJohan Hedberg conn->dst_type, conn->passkey_notify, 516892a25256SJohan Hedberg conn->passkey_entered); 516992a25256SJohan Hedberg } 517092a25256SJohan Hedberg 51713e54c589SLuiz Augusto von Dentz static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data, 5172807deac2SGustavo Padovan struct sk_buff *skb) 51730493684eSMarcel Holtmann { 51743e54c589SLuiz Augusto von Dentz struct hci_ev_simple_pair_complete *ev = data; 51750493684eSMarcel Holtmann struct hci_conn *conn; 51760493684eSMarcel Holtmann 51773e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 51780493684eSMarcel Holtmann 51790493684eSMarcel Holtmann hci_dev_lock(hdev); 51800493684eSMarcel Holtmann 51810493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 51822a611692SJohan Hedberg if (!conn) 51832a611692SJohan Hedberg goto unlock; 51842a611692SJohan Hedberg 5185c1d4fa7aSJohan Hedberg /* Reset the authentication requirement to unknown */ 5186c1d4fa7aSJohan Hedberg conn->remote_auth = 0xff; 5187c1d4fa7aSJohan Hedberg 51882a611692SJohan Hedberg /* To avoid duplicate auth_failed events to user space we check 51892a611692SJohan Hedberg * the HCI_CONN_AUTH_PEND flag which will be set if we 51902a611692SJohan Hedberg * initiated the authentication. A traditional auth_complete 51912a611692SJohan Hedberg * event gets always produced as initiator and is also mapped to 51922a611692SJohan Hedberg * the mgmt_auth_failed event */ 5193fa1bd918SMikel Astiz if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status) 5194e1e930f5SJohan Hedberg mgmt_auth_failed(conn, ev->status); 51952a611692SJohan Hedberg 519676a68ba0SDavid Herrmann hci_conn_drop(conn); 51970493684eSMarcel Holtmann 51982a611692SJohan Hedberg unlock: 51990493684eSMarcel Holtmann hci_dev_unlock(hdev); 52000493684eSMarcel Holtmann } 52010493684eSMarcel Holtmann 52023e54c589SLuiz Augusto von Dentz static void hci_remote_host_features_evt(struct hci_dev *hdev, void *data, 5203807deac2SGustavo Padovan struct sk_buff *skb) 520441a96212SMarcel Holtmann { 52053e54c589SLuiz Augusto von Dentz struct hci_ev_remote_host_features *ev = data; 520641a96212SMarcel Holtmann struct inquiry_entry *ie; 5207cad718edSJohan Hedberg struct hci_conn *conn; 520841a96212SMarcel Holtmann 52093e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 521041a96212SMarcel Holtmann 521141a96212SMarcel Holtmann hci_dev_lock(hdev); 521241a96212SMarcel Holtmann 5213cad718edSJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 5214cad718edSJohan Hedberg if (conn) 5215cad718edSJohan Hedberg memcpy(conn->features[1], ev->features, 8); 5216cad718edSJohan Hedberg 5217cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 5218cc11b9c1SAndrei Emeltchenko if (ie) 521902b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 522041a96212SMarcel Holtmann 522141a96212SMarcel Holtmann hci_dev_unlock(hdev); 522241a96212SMarcel Holtmann } 522341a96212SMarcel Holtmann 52243e54c589SLuiz Augusto von Dentz static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, void *edata, 52252763eda6SSzymon Janc struct sk_buff *skb) 52262763eda6SSzymon Janc { 52273e54c589SLuiz Augusto von Dentz struct hci_ev_remote_oob_data_request *ev = edata; 52282763eda6SSzymon Janc struct oob_data *data; 52292763eda6SSzymon Janc 52303e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, ""); 52312763eda6SSzymon Janc 52322763eda6SSzymon Janc hci_dev_lock(hdev); 52332763eda6SSzymon Janc 5234d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT)) 5235e1ba1f15SSzymon Janc goto unlock; 5236e1ba1f15SSzymon Janc 52376928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, &ev->bdaddr, BDADDR_BREDR); 52386665d057SMarcel Holtmann if (!data) { 52396665d057SMarcel Holtmann struct hci_cp_remote_oob_data_neg_reply cp; 52406665d057SMarcel Holtmann 52416665d057SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 52426665d057SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, 52436665d057SMarcel Holtmann sizeof(cp), &cp); 52446665d057SMarcel Holtmann goto unlock; 52456665d057SMarcel Holtmann } 52466665d057SMarcel Holtmann 5247710f11c0SJohan Hedberg if (bredr_sc_enabled(hdev)) { 5248519ca9d0SMarcel Holtmann struct hci_cp_remote_oob_ext_data_reply cp; 5249519ca9d0SMarcel Holtmann 5250519ca9d0SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr); 5251d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) { 52526665d057SMarcel Holtmann memset(cp.hash192, 0, sizeof(cp.hash192)); 52536665d057SMarcel Holtmann memset(cp.rand192, 0, sizeof(cp.rand192)); 52546665d057SMarcel Holtmann } else { 5255519ca9d0SMarcel Holtmann memcpy(cp.hash192, data->hash192, sizeof(cp.hash192)); 525638da1703SJohan Hedberg memcpy(cp.rand192, data->rand192, sizeof(cp.rand192)); 52576665d057SMarcel Holtmann } 5258519ca9d0SMarcel Holtmann memcpy(cp.hash256, data->hash256, sizeof(cp.hash256)); 525938da1703SJohan Hedberg memcpy(cp.rand256, data->rand256, sizeof(cp.rand256)); 5260519ca9d0SMarcel Holtmann 5261519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY, 5262519ca9d0SMarcel Holtmann sizeof(cp), &cp); 5263519ca9d0SMarcel Holtmann } else { 52642763eda6SSzymon Janc struct hci_cp_remote_oob_data_reply cp; 52652763eda6SSzymon Janc 52662763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr); 5267519ca9d0SMarcel Holtmann memcpy(cp.hash, data->hash192, sizeof(cp.hash)); 526838da1703SJohan Hedberg memcpy(cp.rand, data->rand192, sizeof(cp.rand)); 52692763eda6SSzymon Janc 5270519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, 5271519ca9d0SMarcel Holtmann sizeof(cp), &cp); 5272519ca9d0SMarcel Holtmann } 52732763eda6SSzymon Janc 5274e1ba1f15SSzymon Janc unlock: 52752763eda6SSzymon Janc hci_dev_unlock(hdev); 52762763eda6SSzymon Janc } 52772763eda6SSzymon Janc 5278a77a6a14SArron Wang #if IS_ENABLED(CONFIG_BT_HS) 52793e54c589SLuiz Augusto von Dentz static void hci_chan_selected_evt(struct hci_dev *hdev, void *data, 52803e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 5281a77a6a14SArron Wang { 52823e54c589SLuiz Augusto von Dentz struct hci_ev_channel_selected *ev = data; 5283a77a6a14SArron Wang struct hci_conn *hcon; 5284a77a6a14SArron Wang 52853e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%2.2x", ev->phy_handle); 5286a77a6a14SArron Wang 5287a77a6a14SArron Wang hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 5288a77a6a14SArron Wang if (!hcon) 5289a77a6a14SArron Wang return; 5290a77a6a14SArron Wang 5291a77a6a14SArron Wang amp_read_loc_assoc_final_data(hdev, hcon); 5292a77a6a14SArron Wang } 5293a77a6a14SArron Wang 52943e54c589SLuiz Augusto von Dentz static void hci_phy_link_complete_evt(struct hci_dev *hdev, void *data, 5295d5e91192SAndrei Emeltchenko struct sk_buff *skb) 5296d5e91192SAndrei Emeltchenko { 52973e54c589SLuiz Augusto von Dentz struct hci_ev_phy_link_complete *ev = data; 5298d5e91192SAndrei Emeltchenko struct hci_conn *hcon, *bredr_hcon; 5299d5e91192SAndrei Emeltchenko 53003e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%2.2x status 0x%2.2x", ev->phy_handle, 5301d5e91192SAndrei Emeltchenko ev->status); 5302d5e91192SAndrei Emeltchenko 5303d5e91192SAndrei Emeltchenko hci_dev_lock(hdev); 5304d5e91192SAndrei Emeltchenko 5305d5e91192SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 53063ae1dc75SSergey Shtylyov if (!hcon) 53073ae1dc75SSergey Shtylyov goto unlock; 5308d5e91192SAndrei Emeltchenko 53093ae1dc75SSergey Shtylyov if (!hcon->amp_mgr) 53103ae1dc75SSergey Shtylyov goto unlock; 53116dfccd13SAnmol Karn 5312d5e91192SAndrei Emeltchenko if (ev->status) { 5313d5e91192SAndrei Emeltchenko hci_conn_del(hcon); 53143ae1dc75SSergey Shtylyov goto unlock; 5315d5e91192SAndrei Emeltchenko } 5316d5e91192SAndrei Emeltchenko 5317d5e91192SAndrei Emeltchenko bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon; 5318d5e91192SAndrei Emeltchenko 5319d5e91192SAndrei Emeltchenko hcon->state = BT_CONNECTED; 5320d5e91192SAndrei Emeltchenko bacpy(&hcon->dst, &bredr_hcon->dst); 5321d5e91192SAndrei Emeltchenko 5322d5e91192SAndrei Emeltchenko hci_conn_hold(hcon); 5323d5e91192SAndrei Emeltchenko hcon->disc_timeout = HCI_DISCONN_TIMEOUT; 532476a68ba0SDavid Herrmann hci_conn_drop(hcon); 5325d5e91192SAndrei Emeltchenko 532623b9ceb7SMarcel Holtmann hci_debugfs_create_conn(hcon); 5327d5e91192SAndrei Emeltchenko hci_conn_add_sysfs(hcon); 5328d5e91192SAndrei Emeltchenko 5329cf70ff22SAndrei Emeltchenko amp_physical_cfm(bredr_hcon, hcon); 5330cf70ff22SAndrei Emeltchenko 53313ae1dc75SSergey Shtylyov unlock: 5332d5e91192SAndrei Emeltchenko hci_dev_unlock(hdev); 5333d5e91192SAndrei Emeltchenko } 5334d5e91192SAndrei Emeltchenko 53353e54c589SLuiz Augusto von Dentz static void hci_loglink_complete_evt(struct hci_dev *hdev, void *data, 53363e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 533727695fb4SAndrei Emeltchenko { 53383e54c589SLuiz Augusto von Dentz struct hci_ev_logical_link_complete *ev = data; 533927695fb4SAndrei Emeltchenko struct hci_conn *hcon; 534027695fb4SAndrei Emeltchenko struct hci_chan *hchan; 534127695fb4SAndrei Emeltchenko struct amp_mgr *mgr; 534227695fb4SAndrei Emeltchenko 53433e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x", 53443e54c589SLuiz Augusto von Dentz le16_to_cpu(ev->handle), ev->phy_handle, ev->status); 534527695fb4SAndrei Emeltchenko 534627695fb4SAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 534727695fb4SAndrei Emeltchenko if (!hcon) 534827695fb4SAndrei Emeltchenko return; 534927695fb4SAndrei Emeltchenko 535027695fb4SAndrei Emeltchenko /* Create AMP hchan */ 535127695fb4SAndrei Emeltchenko hchan = hci_chan_create(hcon); 535227695fb4SAndrei Emeltchenko if (!hchan) 535327695fb4SAndrei Emeltchenko return; 535427695fb4SAndrei Emeltchenko 535527695fb4SAndrei Emeltchenko hchan->handle = le16_to_cpu(ev->handle); 53565c4c8c95SArchie Pusaka hchan->amp = true; 535727695fb4SAndrei Emeltchenko 535827695fb4SAndrei Emeltchenko BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan); 535927695fb4SAndrei Emeltchenko 536027695fb4SAndrei Emeltchenko mgr = hcon->amp_mgr; 536127695fb4SAndrei Emeltchenko if (mgr && mgr->bredr_chan) { 536227695fb4SAndrei Emeltchenko struct l2cap_chan *bredr_chan = mgr->bredr_chan; 536327695fb4SAndrei Emeltchenko 536427695fb4SAndrei Emeltchenko l2cap_chan_lock(bredr_chan); 536527695fb4SAndrei Emeltchenko 536627695fb4SAndrei Emeltchenko bredr_chan->conn->mtu = hdev->block_mtu; 536727695fb4SAndrei Emeltchenko l2cap_logical_cfm(bredr_chan, hchan, 0); 536827695fb4SAndrei Emeltchenko hci_conn_hold(hcon); 536927695fb4SAndrei Emeltchenko 537027695fb4SAndrei Emeltchenko l2cap_chan_unlock(bredr_chan); 537127695fb4SAndrei Emeltchenko } 537227695fb4SAndrei Emeltchenko } 537327695fb4SAndrei Emeltchenko 53743e54c589SLuiz Augusto von Dentz static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev, void *data, 5375606e2a10SAndrei Emeltchenko struct sk_buff *skb) 5376606e2a10SAndrei Emeltchenko { 53773e54c589SLuiz Augusto von Dentz struct hci_ev_disconn_logical_link_complete *ev = data; 5378606e2a10SAndrei Emeltchenko struct hci_chan *hchan; 5379606e2a10SAndrei Emeltchenko 53803e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%4.4x status 0x%2.2x", 5381606e2a10SAndrei Emeltchenko le16_to_cpu(ev->handle), ev->status); 5382606e2a10SAndrei Emeltchenko 5383606e2a10SAndrei Emeltchenko if (ev->status) 5384606e2a10SAndrei Emeltchenko return; 5385606e2a10SAndrei Emeltchenko 5386606e2a10SAndrei Emeltchenko hci_dev_lock(hdev); 5387606e2a10SAndrei Emeltchenko 5388606e2a10SAndrei Emeltchenko hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle)); 53895c4c8c95SArchie Pusaka if (!hchan || !hchan->amp) 5390606e2a10SAndrei Emeltchenko goto unlock; 5391606e2a10SAndrei Emeltchenko 5392606e2a10SAndrei Emeltchenko amp_destroy_logical_link(hchan, ev->reason); 5393606e2a10SAndrei Emeltchenko 5394606e2a10SAndrei Emeltchenko unlock: 5395606e2a10SAndrei Emeltchenko hci_dev_unlock(hdev); 5396606e2a10SAndrei Emeltchenko } 5397606e2a10SAndrei Emeltchenko 53983e54c589SLuiz Augusto von Dentz static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, void *data, 53999eef6b3aSAndrei Emeltchenko struct sk_buff *skb) 54009eef6b3aSAndrei Emeltchenko { 54013e54c589SLuiz Augusto von Dentz struct hci_ev_disconn_phy_link_complete *ev = data; 54029eef6b3aSAndrei Emeltchenko struct hci_conn *hcon; 54039eef6b3aSAndrei Emeltchenko 54043e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 54059eef6b3aSAndrei Emeltchenko 54069eef6b3aSAndrei Emeltchenko if (ev->status) 54079eef6b3aSAndrei Emeltchenko return; 54089eef6b3aSAndrei Emeltchenko 54099eef6b3aSAndrei Emeltchenko hci_dev_lock(hdev); 54109eef6b3aSAndrei Emeltchenko 54119eef6b3aSAndrei Emeltchenko hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); 54129eef6b3aSAndrei Emeltchenko if (hcon) { 54139eef6b3aSAndrei Emeltchenko hcon->state = BT_CLOSED; 54149eef6b3aSAndrei Emeltchenko hci_conn_del(hcon); 54159eef6b3aSAndrei Emeltchenko } 54169eef6b3aSAndrei Emeltchenko 54179eef6b3aSAndrei Emeltchenko hci_dev_unlock(hdev); 54189eef6b3aSAndrei Emeltchenko } 5419a77a6a14SArron Wang #endif 54209eef6b3aSAndrei Emeltchenko 5421cafae4cdSLuiz Augusto von Dentz static void le_conn_update_addr(struct hci_conn *conn, bdaddr_t *bdaddr, 5422cafae4cdSLuiz Augusto von Dentz u8 bdaddr_type, bdaddr_t *local_rpa) 5423cafae4cdSLuiz Augusto von Dentz { 5424cafae4cdSLuiz Augusto von Dentz if (conn->out) { 5425cafae4cdSLuiz Augusto von Dentz conn->dst_type = bdaddr_type; 5426cafae4cdSLuiz Augusto von Dentz conn->resp_addr_type = bdaddr_type; 5427cafae4cdSLuiz Augusto von Dentz bacpy(&conn->resp_addr, bdaddr); 5428cafae4cdSLuiz Augusto von Dentz 5429cafae4cdSLuiz Augusto von Dentz /* Check if the controller has set a Local RPA then it must be 5430cafae4cdSLuiz Augusto von Dentz * used instead or hdev->rpa. 5431cafae4cdSLuiz Augusto von Dentz */ 5432cafae4cdSLuiz Augusto von Dentz if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) { 5433cafae4cdSLuiz Augusto von Dentz conn->init_addr_type = ADDR_LE_DEV_RANDOM; 5434cafae4cdSLuiz Augusto von Dentz bacpy(&conn->init_addr, local_rpa); 5435cafae4cdSLuiz Augusto von Dentz } else if (hci_dev_test_flag(conn->hdev, HCI_PRIVACY)) { 5436cafae4cdSLuiz Augusto von Dentz conn->init_addr_type = ADDR_LE_DEV_RANDOM; 5437cafae4cdSLuiz Augusto von Dentz bacpy(&conn->init_addr, &conn->hdev->rpa); 5438cafae4cdSLuiz Augusto von Dentz } else { 5439cafae4cdSLuiz Augusto von Dentz hci_copy_identity_address(conn->hdev, &conn->init_addr, 5440cafae4cdSLuiz Augusto von Dentz &conn->init_addr_type); 5441cafae4cdSLuiz Augusto von Dentz } 5442cafae4cdSLuiz Augusto von Dentz } else { 5443cafae4cdSLuiz Augusto von Dentz conn->resp_addr_type = conn->hdev->adv_addr_type; 5444cafae4cdSLuiz Augusto von Dentz /* Check if the controller has set a Local RPA then it must be 5445cafae4cdSLuiz Augusto von Dentz * used instead or hdev->rpa. 5446cafae4cdSLuiz Augusto von Dentz */ 5447cafae4cdSLuiz Augusto von Dentz if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) { 5448cafae4cdSLuiz Augusto von Dentz conn->resp_addr_type = ADDR_LE_DEV_RANDOM; 5449cafae4cdSLuiz Augusto von Dentz bacpy(&conn->resp_addr, local_rpa); 5450cafae4cdSLuiz Augusto von Dentz } else if (conn->hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) { 5451cafae4cdSLuiz Augusto von Dentz /* In case of ext adv, resp_addr will be updated in 5452cafae4cdSLuiz Augusto von Dentz * Adv Terminated event. 5453cafae4cdSLuiz Augusto von Dentz */ 5454cafae4cdSLuiz Augusto von Dentz if (!ext_adv_capable(conn->hdev)) 5455cafae4cdSLuiz Augusto von Dentz bacpy(&conn->resp_addr, 5456cafae4cdSLuiz Augusto von Dentz &conn->hdev->random_addr); 5457cafae4cdSLuiz Augusto von Dentz } else { 5458cafae4cdSLuiz Augusto von Dentz bacpy(&conn->resp_addr, &conn->hdev->bdaddr); 5459cafae4cdSLuiz Augusto von Dentz } 5460cafae4cdSLuiz Augusto von Dentz 5461cafae4cdSLuiz Augusto von Dentz conn->init_addr_type = bdaddr_type; 5462cafae4cdSLuiz Augusto von Dentz bacpy(&conn->init_addr, bdaddr); 5463cafae4cdSLuiz Augusto von Dentz 5464cafae4cdSLuiz Augusto von Dentz /* For incoming connections, set the default minimum 5465cafae4cdSLuiz Augusto von Dentz * and maximum connection interval. They will be used 5466cafae4cdSLuiz Augusto von Dentz * to check if the parameters are in range and if not 5467cafae4cdSLuiz Augusto von Dentz * trigger the connection update procedure. 5468cafae4cdSLuiz Augusto von Dentz */ 5469cafae4cdSLuiz Augusto von Dentz conn->le_conn_min_interval = conn->hdev->le_conn_min_interval; 5470cafae4cdSLuiz Augusto von Dentz conn->le_conn_max_interval = conn->hdev->le_conn_max_interval; 5471cafae4cdSLuiz Augusto von Dentz } 5472cafae4cdSLuiz Augusto von Dentz } 5473cafae4cdSLuiz Augusto von Dentz 5474d12fb056SJaganath Kanakkassery static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, 5475cafae4cdSLuiz Augusto von Dentz bdaddr_t *bdaddr, u8 bdaddr_type, 5476cafae4cdSLuiz Augusto von Dentz bdaddr_t *local_rpa, u8 role, u16 handle, 5477cafae4cdSLuiz Augusto von Dentz u16 interval, u16 latency, 5478cafae4cdSLuiz Augusto von Dentz u16 supervision_timeout) 5479fcd89c09SVille Tervo { 5480912b42efSJohan Hedberg struct hci_conn_params *params; 5481fcd89c09SVille Tervo struct hci_conn *conn; 548268d6f6deSJohan Hedberg struct smp_irk *irk; 5483837d502eSJohan Hedberg u8 addr_type; 5484fcd89c09SVille Tervo 5485fcd89c09SVille Tervo hci_dev_lock(hdev); 5486fcd89c09SVille Tervo 5487fbd96c15SJohan Hedberg /* All controllers implicitly stop advertising in the event of a 5488fbd96c15SJohan Hedberg * connection, so ensure that the state bit is cleared. 5489fbd96c15SJohan Hedberg */ 5490a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ADV); 5491fbd96c15SJohan Hedberg 5492e7d9ab73SJakub Pawlowski conn = hci_lookup_le_connect(hdev); 5493b62f328bSVille Tervo if (!conn) { 5494d12fb056SJaganath Kanakkassery conn = hci_conn_add(hdev, LE_LINK, bdaddr, role); 5495b62f328bSVille Tervo if (!conn) { 54962064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for new connection"); 5497230fd16aSAndre Guedes goto unlock; 5498b62f328bSVille Tervo } 549929b7988aSAndre Guedes 5500d12fb056SJaganath Kanakkassery conn->dst_type = bdaddr_type; 5501b9b343d2SAndre Guedes 5502cb1d68f7SJohan Hedberg /* If we didn't have a hci_conn object previously 550374be523cSArchie Pusaka * but we're in central role this must be something 55043d4f9c00SArchie Pusaka * initiated using an accept list. Since accept list based 5505cb1d68f7SJohan Hedberg * connections are not "first class citizens" we don't 5506cb1d68f7SJohan Hedberg * have full tracking of them. Therefore, we go ahead 5507cb1d68f7SJohan Hedberg * with a "best effort" approach of determining the 5508cb1d68f7SJohan Hedberg * initiator address based on the HCI_PRIVACY flag. 5509cb1d68f7SJohan Hedberg */ 5510cb1d68f7SJohan Hedberg if (conn->out) { 5511d12fb056SJaganath Kanakkassery conn->resp_addr_type = bdaddr_type; 5512d12fb056SJaganath Kanakkassery bacpy(&conn->resp_addr, bdaddr); 5513d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PRIVACY)) { 5514cb1d68f7SJohan Hedberg conn->init_addr_type = ADDR_LE_DEV_RANDOM; 5515cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->rpa); 5516cb1d68f7SJohan Hedberg } else { 5517cb1d68f7SJohan Hedberg hci_copy_identity_address(hdev, 5518cb1d68f7SJohan Hedberg &conn->init_addr, 5519cb1d68f7SJohan Hedberg &conn->init_addr_type); 5520cb1d68f7SJohan Hedberg } 552180c24ab8SJohan Hedberg } 5522cb1d68f7SJohan Hedberg } else { 552380c24ab8SJohan Hedberg cancel_delayed_work(&conn->le_conn_timeout); 552480c24ab8SJohan Hedberg } 552580c24ab8SJohan Hedberg 5526cafae4cdSLuiz Augusto von Dentz le_conn_update_addr(conn, bdaddr, bdaddr_type, local_rpa); 55277be2edbbSJohan Hedberg 5528edb4b466SMarcel Holtmann /* Lookup the identity address from the stored connection 5529edb4b466SMarcel Holtmann * address and address type. 5530edb4b466SMarcel Holtmann * 5531edb4b466SMarcel Holtmann * When establishing connections to an identity address, the 5532edb4b466SMarcel Holtmann * connection procedure will store the resolvable random 5533edb4b466SMarcel Holtmann * address first. Now if it can be converted back into the 5534edb4b466SMarcel Holtmann * identity address, start using the identity address from 5535edb4b466SMarcel Holtmann * now on. 5536edb4b466SMarcel Holtmann */ 5537edb4b466SMarcel Holtmann irk = hci_get_irk(hdev, &conn->dst, conn->dst_type); 553868d6f6deSJohan Hedberg if (irk) { 553968d6f6deSJohan Hedberg bacpy(&conn->dst, &irk->bdaddr); 554068d6f6deSJohan Hedberg conn->dst_type = irk->addr_type; 554168d6f6deSJohan Hedberg } 554268d6f6deSJohan Hedberg 5543d850bf08SLuiz Augusto von Dentz conn->dst_type = ev_bdaddr_type(hdev, conn->dst_type, NULL); 554479699a70SSathish Narasimman 5545d12fb056SJaganath Kanakkassery if (status) { 5546d12fb056SJaganath Kanakkassery hci_le_conn_failed(conn, status); 5547837d502eSJohan Hedberg goto unlock; 5548837d502eSJohan Hedberg } 5549837d502eSJohan Hedberg 555008853f18SJohan Hedberg if (conn->dst_type == ADDR_LE_DEV_PUBLIC) 555108853f18SJohan Hedberg addr_type = BDADDR_LE_PUBLIC; 555208853f18SJohan Hedberg else 555308853f18SJohan Hedberg addr_type = BDADDR_LE_RANDOM; 555408853f18SJohan Hedberg 55552d3c2260SJohan Hedberg /* Drop the connection if the device is blocked */ 55563d4f9c00SArchie Pusaka if (hci_bdaddr_list_lookup(&hdev->reject_list, &conn->dst, addr_type)) { 55572d3c2260SJohan Hedberg hci_conn_drop(conn); 5558cd17decbSAndre Guedes goto unlock; 5559cd17decbSAndre Guedes } 5560cd17decbSAndre Guedes 5561b644ba33SJohan Hedberg if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 55621c6ed31bSYu Liu mgmt_device_connected(hdev, conn, NULL, 0); 556383bc71b4SVinicius Costa Gomes 55647b5c0d52SVinicius Costa Gomes conn->sec_level = BT_SECURITY_LOW; 5565d12fb056SJaganath Kanakkassery conn->handle = handle; 55660fe29fd1SMarcel Holtmann conn->state = BT_CONFIG; 5567fcd89c09SVille Tervo 55687087c4f6SLuiz Augusto von Dentz /* Store current advertising instance as connection advertising instance 55697087c4f6SLuiz Augusto von Dentz * when sotfware rotation is in use so it can be re-enabled when 55707087c4f6SLuiz Augusto von Dentz * disconnected. 55717087c4f6SLuiz Augusto von Dentz */ 55727087c4f6SLuiz Augusto von Dentz if (!ext_adv_capable(hdev)) 55737087c4f6SLuiz Augusto von Dentz conn->adv_instance = hdev->cur_adv_instance; 55747087c4f6SLuiz Augusto von Dentz 5575d12fb056SJaganath Kanakkassery conn->le_conn_interval = interval; 5576d12fb056SJaganath Kanakkassery conn->le_conn_latency = latency; 5577d12fb056SJaganath Kanakkassery conn->le_supv_timeout = supervision_timeout; 5578e04fde60SMarcel Holtmann 557923b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn); 5580fcd89c09SVille Tervo hci_conn_add_sysfs(conn); 5581fcd89c09SVille Tervo 5582ef365da1SArchie Pusaka /* The remote features procedure is defined for central 55830fe29fd1SMarcel Holtmann * role only. So only in case of an initiated connection 55840fe29fd1SMarcel Holtmann * request the remote features. 55850fe29fd1SMarcel Holtmann * 5586ef365da1SArchie Pusaka * If the local controller supports peripheral-initiated features 5587ef365da1SArchie Pusaka * exchange, then requesting the remote features in peripheral 55880fe29fd1SMarcel Holtmann * role is possible. Otherwise just transition into the 55890fe29fd1SMarcel Holtmann * connected state without requesting the remote features. 55900fe29fd1SMarcel Holtmann */ 55910fe29fd1SMarcel Holtmann if (conn->out || 5592ef365da1SArchie Pusaka (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES)) { 55930fe29fd1SMarcel Holtmann struct hci_cp_le_read_remote_features cp; 55940fe29fd1SMarcel Holtmann 55950fe29fd1SMarcel Holtmann cp.handle = __cpu_to_le16(conn->handle); 55960fe29fd1SMarcel Holtmann 55970fe29fd1SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_LE_READ_REMOTE_FEATURES, 55980fe29fd1SMarcel Holtmann sizeof(cp), &cp); 55990fe29fd1SMarcel Holtmann 56000fe29fd1SMarcel Holtmann hci_conn_hold(conn); 56010fe29fd1SMarcel Holtmann } else { 56020fe29fd1SMarcel Holtmann conn->state = BT_CONNECTED; 5603d12fb056SJaganath Kanakkassery hci_connect_cfm(conn, status); 56040fe29fd1SMarcel Holtmann } 5605fcd89c09SVille Tervo 56065477610fSJohan Hedberg params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst, 56075477610fSJohan Hedberg conn->dst_type); 5608f161dd41SJohan Hedberg if (params) { 560995305baaSJohan Hedberg list_del_init(¶ms->action); 5610f161dd41SJohan Hedberg if (params->conn) { 5611f161dd41SJohan Hedberg hci_conn_drop(params->conn); 5612f8aaf9b6SJohan Hedberg hci_conn_put(params->conn); 5613f161dd41SJohan Hedberg params->conn = NULL; 5614f161dd41SJohan Hedberg } 5615f161dd41SJohan Hedberg } 5616a4790dbdSAndre Guedes 5617fcd89c09SVille Tervo unlock: 56185bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan(hdev); 5619fcd89c09SVille Tervo hci_dev_unlock(hdev); 5620fcd89c09SVille Tervo } 5621fcd89c09SVille Tervo 562295118dd4SLuiz Augusto von Dentz static void hci_le_conn_complete_evt(struct hci_dev *hdev, void *data, 562395118dd4SLuiz Augusto von Dentz struct sk_buff *skb) 5624d12fb056SJaganath Kanakkassery { 562595118dd4SLuiz Augusto von Dentz struct hci_ev_le_conn_complete *ev = data; 562612cfe417SLuiz Augusto von Dentz 562795118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 5628d12fb056SJaganath Kanakkassery 5629d12fb056SJaganath Kanakkassery le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type, 5630cafae4cdSLuiz Augusto von Dentz NULL, ev->role, le16_to_cpu(ev->handle), 5631d12fb056SJaganath Kanakkassery le16_to_cpu(ev->interval), 5632d12fb056SJaganath Kanakkassery le16_to_cpu(ev->latency), 5633d12fb056SJaganath Kanakkassery le16_to_cpu(ev->supervision_timeout)); 5634d12fb056SJaganath Kanakkassery } 5635d12fb056SJaganath Kanakkassery 563695118dd4SLuiz Augusto von Dentz static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev, void *data, 56374d94f95dSJaganath Kanakkassery struct sk_buff *skb) 56384d94f95dSJaganath Kanakkassery { 563995118dd4SLuiz Augusto von Dentz struct hci_ev_le_enh_conn_complete *ev = data; 564012cfe417SLuiz Augusto von Dentz 564195118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 56424d94f95dSJaganath Kanakkassery 56434d94f95dSJaganath Kanakkassery le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type, 5644cafae4cdSLuiz Augusto von Dentz &ev->local_rpa, ev->role, le16_to_cpu(ev->handle), 56454d94f95dSJaganath Kanakkassery le16_to_cpu(ev->interval), 56464d94f95dSJaganath Kanakkassery le16_to_cpu(ev->latency), 56474d94f95dSJaganath Kanakkassery le16_to_cpu(ev->supervision_timeout)); 56484d94f95dSJaganath Kanakkassery } 56494d94f95dSJaganath Kanakkassery 565095118dd4SLuiz Augusto von Dentz static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data, 565195118dd4SLuiz Augusto von Dentz struct sk_buff *skb) 5652acf0aeaeSJaganath Kanakkassery { 565395118dd4SLuiz Augusto von Dentz struct hci_evt_le_ext_adv_set_term *ev = data; 5654acf0aeaeSJaganath Kanakkassery struct hci_conn *conn; 56551f9d5657SArchie Pusaka struct adv_info *adv, *n; 5656acf0aeaeSJaganath Kanakkassery 565795118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 5658acf0aeaeSJaganath Kanakkassery 565923837a6dSLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, ev->handle); 56607087c4f6SLuiz Augusto von Dentz 56610f281a5eSArchie Pusaka /* The Bluetooth Core 5.3 specification clearly states that this event 56620f281a5eSArchie Pusaka * shall not be sent when the Host disables the advertising set. So in 56630f281a5eSArchie Pusaka * case of HCI_ERROR_CANCELLED_BY_HOST, just ignore the event. 56640f281a5eSArchie Pusaka * 56650f281a5eSArchie Pusaka * When the Host disables an advertising set, all cleanup is done via 56660f281a5eSArchie Pusaka * its command callback and not needed to be duplicated here. 56670f281a5eSArchie Pusaka */ 56680f281a5eSArchie Pusaka if (ev->status == HCI_ERROR_CANCELLED_BY_HOST) { 56690f281a5eSArchie Pusaka bt_dev_warn_ratelimited(hdev, "Unexpected advertising set terminated event"); 56700f281a5eSArchie Pusaka return; 56710f281a5eSArchie Pusaka } 56720f281a5eSArchie Pusaka 56737087c4f6SLuiz Augusto von Dentz if (ev->status) { 567423837a6dSLuiz Augusto von Dentz if (!adv) 5675acf0aeaeSJaganath Kanakkassery return; 5676acf0aeaeSJaganath Kanakkassery 567723837a6dSLuiz Augusto von Dentz /* Remove advertising as it has been terminated */ 567823837a6dSLuiz Augusto von Dentz hci_remove_adv_instance(hdev, ev->handle); 567923837a6dSLuiz Augusto von Dentz mgmt_advertising_removed(NULL, hdev, ev->handle); 568023837a6dSLuiz Augusto von Dentz 56811f9d5657SArchie Pusaka list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) { 56821f9d5657SArchie Pusaka if (adv->enabled) 56831f9d5657SArchie Pusaka return; 56841f9d5657SArchie Pusaka } 56851f9d5657SArchie Pusaka 56861f9d5657SArchie Pusaka /* We are no longer advertising, clear HCI_LE_ADV */ 56871f9d5657SArchie Pusaka hci_dev_clear_flag(hdev, HCI_LE_ADV); 568823837a6dSLuiz Augusto von Dentz return; 568923837a6dSLuiz Augusto von Dentz } 569023837a6dSLuiz Augusto von Dentz 56917087c4f6SLuiz Augusto von Dentz if (adv) 56927087c4f6SLuiz Augusto von Dentz adv->enabled = false; 56937087c4f6SLuiz Augusto von Dentz 5694acf0aeaeSJaganath Kanakkassery conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle)); 5695acf0aeaeSJaganath Kanakkassery if (conn) { 56967087c4f6SLuiz Augusto von Dentz /* Store handle in the connection so the correct advertising 56977087c4f6SLuiz Augusto von Dentz * instance can be re-enabled when disconnected. 56987087c4f6SLuiz Augusto von Dentz */ 56997087c4f6SLuiz Augusto von Dentz conn->adv_instance = ev->handle; 5700acf0aeaeSJaganath Kanakkassery 5701cafae4cdSLuiz Augusto von Dentz if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM || 5702cafae4cdSLuiz Augusto von Dentz bacmp(&conn->resp_addr, BDADDR_ANY)) 5703acf0aeaeSJaganath Kanakkassery return; 5704acf0aeaeSJaganath Kanakkassery 570525e70886SDaniel Winkler if (!ev->handle) { 5706acf0aeaeSJaganath Kanakkassery bacpy(&conn->resp_addr, &hdev->random_addr); 5707acf0aeaeSJaganath Kanakkassery return; 5708acf0aeaeSJaganath Kanakkassery } 5709acf0aeaeSJaganath Kanakkassery 57107087c4f6SLuiz Augusto von Dentz if (adv) 57117087c4f6SLuiz Augusto von Dentz bacpy(&conn->resp_addr, &adv->random_addr); 5712acf0aeaeSJaganath Kanakkassery } 5713acf0aeaeSJaganath Kanakkassery } 5714acf0aeaeSJaganath Kanakkassery 571595118dd4SLuiz Augusto von Dentz static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, void *data, 57161855d92dSMarcel Holtmann struct sk_buff *skb) 57171855d92dSMarcel Holtmann { 571895118dd4SLuiz Augusto von Dentz struct hci_ev_le_conn_update_complete *ev = data; 57191855d92dSMarcel Holtmann struct hci_conn *conn; 57201855d92dSMarcel Holtmann 572195118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 57221855d92dSMarcel Holtmann 57231855d92dSMarcel Holtmann if (ev->status) 57241855d92dSMarcel Holtmann return; 57251855d92dSMarcel Holtmann 57261855d92dSMarcel Holtmann hci_dev_lock(hdev); 57271855d92dSMarcel Holtmann 57281855d92dSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 57291855d92dSMarcel Holtmann if (conn) { 57301855d92dSMarcel Holtmann conn->le_conn_interval = le16_to_cpu(ev->interval); 57311855d92dSMarcel Holtmann conn->le_conn_latency = le16_to_cpu(ev->latency); 57321855d92dSMarcel Holtmann conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout); 57331855d92dSMarcel Holtmann } 57341855d92dSMarcel Holtmann 57351855d92dSMarcel Holtmann hci_dev_unlock(hdev); 57361855d92dSMarcel Holtmann } 57371855d92dSMarcel Holtmann 5738a4790dbdSAndre Guedes /* This function requires the caller holds hdev->lock */ 5739fd45ada9SAlfonso Acosta static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev, 5740fd45ada9SAlfonso Acosta bdaddr_t *addr, 5741d850bf08SLuiz Augusto von Dentz u8 addr_type, bool addr_resolved, 5742d850bf08SLuiz Augusto von Dentz u8 adv_type, bdaddr_t *direct_rpa) 5743a4790dbdSAndre Guedes { 5744a4790dbdSAndre Guedes struct hci_conn *conn; 57454b9e7e75SMarcel Holtmann struct hci_conn_params *params; 5746a4790dbdSAndre Guedes 57471c1abcabSJohan Hedberg /* If the event is not connectable don't proceed further */ 57481c1abcabSJohan Hedberg if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND) 5749fd45ada9SAlfonso Acosta return NULL; 57501c1abcabSJohan Hedberg 5751182ee45dSLuiz Augusto von Dentz /* Ignore if the device is blocked or hdev is suspended */ 5752182ee45dSLuiz Augusto von Dentz if (hci_bdaddr_list_lookup(&hdev->reject_list, addr, addr_type) || 5753182ee45dSLuiz Augusto von Dentz hdev->suspended) 5754fd45ada9SAlfonso Acosta return NULL; 57551c1abcabSJohan Hedberg 5756f99353cfSJohan Hedberg /* Most controller will fail if we try to create new connections 575739bc74caSArchie Pusaka * while we have an existing one in peripheral role. 5758f99353cfSJohan Hedberg */ 575939bc74caSArchie Pusaka if (hdev->conn_hash.le_num_peripheral > 0 && 57604364f2e9SAlain Michaud (!test_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks) || 57614364f2e9SAlain Michaud !(hdev->le_states[3] & 0x10))) 5762fd45ada9SAlfonso Acosta return NULL; 5763f99353cfSJohan Hedberg 57641c1abcabSJohan Hedberg /* If we're not connectable only connect devices that we have in 57651c1abcabSJohan Hedberg * our pend_le_conns list. 57661c1abcabSJohan Hedberg */ 576749c50922SJohan Hedberg params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr, 576849c50922SJohan Hedberg addr_type); 57694b9e7e75SMarcel Holtmann if (!params) 5770fd45ada9SAlfonso Acosta return NULL; 5771a4790dbdSAndre Guedes 577228a667c9SJakub Pawlowski if (!params->explicit_connect) { 57734b9e7e75SMarcel Holtmann switch (params->auto_connect) { 57744b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_DIRECT: 57754b9e7e75SMarcel Holtmann /* Only devices advertising with ADV_DIRECT_IND are 57764b9e7e75SMarcel Holtmann * triggering a connection attempt. This is allowing 577767ffb185SArchie Pusaka * incoming connections from peripheral devices. 57784b9e7e75SMarcel Holtmann */ 57794b9e7e75SMarcel Holtmann if (adv_type != LE_ADV_DIRECT_IND) 5780fd45ada9SAlfonso Acosta return NULL; 57814b9e7e75SMarcel Holtmann break; 57824b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_ALWAYS: 57834b9e7e75SMarcel Holtmann /* Devices advertising with ADV_IND or ADV_DIRECT_IND 57844b9e7e75SMarcel Holtmann * are triggering a connection attempt. This means 578567ffb185SArchie Pusaka * that incoming connections from peripheral device are 578667ffb185SArchie Pusaka * accepted and also outgoing connections to peripheral 57874b9e7e75SMarcel Holtmann * devices are established when found. 57884b9e7e75SMarcel Holtmann */ 57894b9e7e75SMarcel Holtmann break; 57904b9e7e75SMarcel Holtmann default: 5791fd45ada9SAlfonso Acosta return NULL; 57924b9e7e75SMarcel Holtmann } 579328a667c9SJakub Pawlowski } 57944b9e7e75SMarcel Holtmann 5795d850bf08SLuiz Augusto von Dentz conn = hci_connect_le(hdev, addr, addr_type, addr_resolved, 5796d850bf08SLuiz Augusto von Dentz BT_SECURITY_LOW, hdev->def_le_autoconnect_timeout, 5797d850bf08SLuiz Augusto von Dentz HCI_ROLE_MASTER, direct_rpa); 5798f161dd41SJohan Hedberg if (!IS_ERR(conn)) { 579928a667c9SJakub Pawlowski /* If HCI_AUTO_CONN_EXPLICIT is set, conn is already owned 580028a667c9SJakub Pawlowski * by higher layer that tried to connect, if no then 580128a667c9SJakub Pawlowski * store the pointer since we don't really have any 5802f161dd41SJohan Hedberg * other owner of the object besides the params that 5803f161dd41SJohan Hedberg * triggered it. This way we can abort the connection if 5804f161dd41SJohan Hedberg * the parameters get removed and keep the reference 5805f161dd41SJohan Hedberg * count consistent once the connection is established. 5806f161dd41SJohan Hedberg */ 580728a667c9SJakub Pawlowski 580828a667c9SJakub Pawlowski if (!params->explicit_connect) 5809f8aaf9b6SJohan Hedberg params->conn = hci_conn_get(conn); 581028a667c9SJakub Pawlowski 5811fd45ada9SAlfonso Acosta return conn; 5812f161dd41SJohan Hedberg } 5813a4790dbdSAndre Guedes 5814a4790dbdSAndre Guedes switch (PTR_ERR(conn)) { 5815a4790dbdSAndre Guedes case -EBUSY: 5816a4790dbdSAndre Guedes /* If hci_connect() returns -EBUSY it means there is already 5817a4790dbdSAndre Guedes * an LE connection attempt going on. Since controllers don't 5818a4790dbdSAndre Guedes * support more than one connection attempt at the time, we 5819a4790dbdSAndre Guedes * don't consider this an error case. 5820a4790dbdSAndre Guedes */ 5821a4790dbdSAndre Guedes break; 5822a4790dbdSAndre Guedes default: 5823a4790dbdSAndre Guedes BT_DBG("Failed to connect: err %ld", PTR_ERR(conn)); 5824fd45ada9SAlfonso Acosta return NULL; 5825a4790dbdSAndre Guedes } 5826fd45ada9SAlfonso Acosta 5827fd45ada9SAlfonso Acosta return NULL; 5828a4790dbdSAndre Guedes } 5829a4790dbdSAndre Guedes 58304af605d8SJohan Hedberg static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, 58312f010b55SMarcel Holtmann u8 bdaddr_type, bdaddr_t *direct_addr, 5832a2ec905dSAlain Michaud u8 direct_addr_type, s8 rssi, u8 *data, u8 len, 5833a2ec905dSAlain Michaud bool ext_adv) 58344af605d8SJohan Hedberg { 5835b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery; 58361c1abcabSJohan Hedberg struct smp_irk *irk; 5837fd45ada9SAlfonso Acosta struct hci_conn *conn; 5838d850bf08SLuiz Augusto von Dentz bool match, bdaddr_resolved; 5839c70a7e4cSMarcel Holtmann u32 flags; 58401c58e933SSzymon Janc u8 *ptr; 58416818375eSSzymon Janc 584256b40fbfSJohan Hedberg switch (type) { 584356b40fbfSJohan Hedberg case LE_ADV_IND: 584456b40fbfSJohan Hedberg case LE_ADV_DIRECT_IND: 584556b40fbfSJohan Hedberg case LE_ADV_SCAN_IND: 584656b40fbfSJohan Hedberg case LE_ADV_NONCONN_IND: 584756b40fbfSJohan Hedberg case LE_ADV_SCAN_RSP: 584856b40fbfSJohan Hedberg break; 584956b40fbfSJohan Hedberg default: 58502064ee33SMarcel Holtmann bt_dev_err_ratelimited(hdev, "unknown advertising packet " 58512064ee33SMarcel Holtmann "type: 0x%02x", type); 585256b40fbfSJohan Hedberg return; 585356b40fbfSJohan Hedberg } 585456b40fbfSJohan Hedberg 5855a2ec905dSAlain Michaud if (!ext_adv && len > HCI_MAX_AD_LENGTH) { 5856a2ec905dSAlain Michaud bt_dev_err_ratelimited(hdev, "legacy adv larger than 31 bytes"); 5857a2ec905dSAlain Michaud return; 5858a2ec905dSAlain Michaud } 5859a2ec905dSAlain Michaud 58606818375eSSzymon Janc /* Find the end of the data in case the report contains padded zero 58616818375eSSzymon Janc * bytes at the end causing an invalid length value. 58626818375eSSzymon Janc * 58636818375eSSzymon Janc * When data is NULL, len is 0 so there is no need for extra ptr 58646818375eSSzymon Janc * check as 'ptr < data + 0' is already false in such case. 58656818375eSSzymon Janc */ 58666818375eSSzymon Janc for (ptr = data; ptr < data + len && *ptr; ptr += *ptr + 1) { 58676818375eSSzymon Janc if (ptr + 1 + *ptr > data + len) 58686818375eSSzymon Janc break; 58696818375eSSzymon Janc } 58706818375eSSzymon Janc 58711c58e933SSzymon Janc /* Adjust for actual length. This handles the case when remote 58721c58e933SSzymon Janc * device is advertising with incorrect data length. 58731c58e933SSzymon Janc */ 58741c58e933SSzymon Janc len = ptr - data; 5875b9a6328fSJohan Hedberg 58762f010b55SMarcel Holtmann /* If the direct address is present, then this report is from 58772f010b55SMarcel Holtmann * a LE Direct Advertising Report event. In that case it is 58782f010b55SMarcel Holtmann * important to see if the address is matching the local 58792f010b55SMarcel Holtmann * controller address. 58802f010b55SMarcel Holtmann */ 58812f010b55SMarcel Holtmann if (direct_addr) { 5882d850bf08SLuiz Augusto von Dentz direct_addr_type = ev_bdaddr_type(hdev, direct_addr_type, 5883d850bf08SLuiz Augusto von Dentz &bdaddr_resolved); 58844ec4d63bSLuiz Augusto von Dentz 58852f010b55SMarcel Holtmann /* Only resolvable random addresses are valid for these 58862f010b55SMarcel Holtmann * kind of reports and others can be ignored. 58872f010b55SMarcel Holtmann */ 58882f010b55SMarcel Holtmann if (!hci_bdaddr_is_rpa(direct_addr, direct_addr_type)) 58892f010b55SMarcel Holtmann return; 58902f010b55SMarcel Holtmann 58912f010b55SMarcel Holtmann /* If the controller is not using resolvable random 58922f010b55SMarcel Holtmann * addresses, then this report can be ignored. 58932f010b55SMarcel Holtmann */ 5894d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_PRIVACY)) 58952f010b55SMarcel Holtmann return; 58962f010b55SMarcel Holtmann 58972f010b55SMarcel Holtmann /* If the local IRK of the controller does not match 58982f010b55SMarcel Holtmann * with the resolvable random address provided, then 58992f010b55SMarcel Holtmann * this report can be ignored. 59002f010b55SMarcel Holtmann */ 59012f010b55SMarcel Holtmann if (!smp_irk_matches(hdev, hdev->irk, direct_addr)) 59022f010b55SMarcel Holtmann return; 59032f010b55SMarcel Holtmann } 59042f010b55SMarcel Holtmann 5905435a13d8SJohan Hedberg /* Check if we need to convert to identity address */ 5906435a13d8SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, bdaddr_type); 5907435a13d8SJohan Hedberg if (irk) { 5908435a13d8SJohan Hedberg bdaddr = &irk->bdaddr; 5909435a13d8SJohan Hedberg bdaddr_type = irk->addr_type; 5910435a13d8SJohan Hedberg } 5911435a13d8SJohan Hedberg 5912d850bf08SLuiz Augusto von Dentz bdaddr_type = ev_bdaddr_type(hdev, bdaddr_type, &bdaddr_resolved); 59134ec4d63bSLuiz Augusto von Dentz 5914082f2300SSzymon Janc /* Check if we have been requested to connect to this device. 5915082f2300SSzymon Janc * 5916082f2300SSzymon Janc * direct_addr is set only for directed advertising reports (it is NULL 5917082f2300SSzymon Janc * for advertising reports) and is already verified to be RPA above. 5918082f2300SSzymon Janc */ 5919d850bf08SLuiz Augusto von Dentz conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, bdaddr_resolved, 5920d850bf08SLuiz Augusto von Dentz type, direct_addr); 5921a2ec905dSAlain Michaud if (!ext_adv && conn && type == LE_ADV_IND && len <= HCI_MAX_AD_LENGTH) { 5922fd45ada9SAlfonso Acosta /* Store report for later inclusion by 5923fd45ada9SAlfonso Acosta * mgmt_device_connected 5924fd45ada9SAlfonso Acosta */ 5925fd45ada9SAlfonso Acosta memcpy(conn->le_adv_data, data, len); 5926fd45ada9SAlfonso Acosta conn->le_adv_data_len = len; 5927fd45ada9SAlfonso Acosta } 592899a6768eSJohan Hedberg 59291c1abcabSJohan Hedberg /* Passive scanning shouldn't trigger any device found events, 59301c1abcabSJohan Hedberg * except for devices marked as CONN_REPORT for which we do send 59318208f5a9SMiao-chen Chou * device found events, or advertisement monitoring requested. 59321c1abcabSJohan Hedberg */ 59331c1abcabSJohan Hedberg if (hdev->le_scan_type == LE_SCAN_PASSIVE) { 59340d2bf134SJohan Hedberg if (type == LE_ADV_DIRECT_IND) 59350d2bf134SJohan Hedberg return; 59360d2bf134SJohan Hedberg 59373a19b6feSJohan Hedberg if (!hci_pend_le_action_lookup(&hdev->pend_le_reports, 59388208f5a9SMiao-chen Chou bdaddr, bdaddr_type) && 59398208f5a9SMiao-chen Chou idr_is_empty(&hdev->adv_monitors_idr)) 59400d2bf134SJohan Hedberg return; 59410d2bf134SJohan Hedberg 59420d2bf134SJohan Hedberg if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND) 59430d2bf134SJohan Hedberg flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 59440d2bf134SJohan Hedberg else 59450d2bf134SJohan Hedberg flags = 0; 59460d2bf134SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 59470d2bf134SJohan Hedberg rssi, flags, data, len, NULL, 0); 594897bf2e99SJohan Hedberg return; 5949ca5c4be7SJohan Hedberg } 59504af605d8SJohan Hedberg 5951c70a7e4cSMarcel Holtmann /* When receiving non-connectable or scannable undirected 5952c70a7e4cSMarcel Holtmann * advertising reports, this means that the remote device is 5953c70a7e4cSMarcel Holtmann * not connectable and then clearly indicate this in the 5954c70a7e4cSMarcel Holtmann * device found event. 5955c70a7e4cSMarcel Holtmann * 5956c70a7e4cSMarcel Holtmann * When receiving a scan response, then there is no way to 5957c70a7e4cSMarcel Holtmann * know if the remote device is connectable or not. However 5958c70a7e4cSMarcel Holtmann * since scan responses are merged with a previously seen 5959c70a7e4cSMarcel Holtmann * advertising report, the flags field from that report 5960c70a7e4cSMarcel Holtmann * will be used. 5961c70a7e4cSMarcel Holtmann * 5962c70a7e4cSMarcel Holtmann * In the really unlikely case that a controller get confused 5963c70a7e4cSMarcel Holtmann * and just sends a scan response event, then it is marked as 5964c70a7e4cSMarcel Holtmann * not connectable as well. 5965c70a7e4cSMarcel Holtmann */ 5966c70a7e4cSMarcel Holtmann if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND || 5967c70a7e4cSMarcel Holtmann type == LE_ADV_SCAN_RSP) 5968c70a7e4cSMarcel Holtmann flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 5969c70a7e4cSMarcel Holtmann else 5970c70a7e4cSMarcel Holtmann flags = 0; 5971c70a7e4cSMarcel Holtmann 5972b9a6328fSJohan Hedberg /* If there's nothing pending either store the data from this 5973b9a6328fSJohan Hedberg * event or send an immediate device found event if the data 5974b9a6328fSJohan Hedberg * should not be stored for later. 5975b9a6328fSJohan Hedberg */ 5976a2ec905dSAlain Michaud if (!ext_adv && !has_pending_adv_report(hdev)) { 5977b9a6328fSJohan Hedberg /* If the report will trigger a SCAN_REQ store it for 5978b9a6328fSJohan Hedberg * later merging. 5979b9a6328fSJohan Hedberg */ 5980b9a6328fSJohan Hedberg if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { 5981b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type, 5982c70a7e4cSMarcel Holtmann rssi, flags, data, len); 5983b9a6328fSJohan Hedberg return; 5984b9a6328fSJohan Hedberg } 5985b9a6328fSJohan Hedberg 5986b9a6328fSJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 5987c70a7e4cSMarcel Holtmann rssi, flags, data, len, NULL, 0); 5988b9a6328fSJohan Hedberg return; 5989b9a6328fSJohan Hedberg } 5990b9a6328fSJohan Hedberg 5991474ee066SJohan Hedberg /* Check if the pending report is for the same device as the new one */ 5992474ee066SJohan Hedberg match = (!bacmp(bdaddr, &d->last_adv_addr) && 5993474ee066SJohan Hedberg bdaddr_type == d->last_adv_addr_type); 5994474ee066SJohan Hedberg 5995b9a6328fSJohan Hedberg /* If the pending data doesn't match this report or this isn't a 5996b9a6328fSJohan Hedberg * scan response (e.g. we got a duplicate ADV_IND) then force 5997b9a6328fSJohan Hedberg * sending of the pending data. 5998b9a6328fSJohan Hedberg */ 5999474ee066SJohan Hedberg if (type != LE_ADV_SCAN_RSP || !match) { 6000474ee066SJohan Hedberg /* Send out whatever is in the cache, but skip duplicates */ 6001474ee066SJohan Hedberg if (!match) 6002b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 6003ff5cd29fSJohan Hedberg d->last_adv_addr_type, NULL, 6004c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags, 6005ff5cd29fSJohan Hedberg d->last_adv_data, 6006474ee066SJohan Hedberg d->last_adv_data_len, NULL, 0); 6007b9a6328fSJohan Hedberg 6008b9a6328fSJohan Hedberg /* If the new report will trigger a SCAN_REQ store it for 6009b9a6328fSJohan Hedberg * later merging. 6010b9a6328fSJohan Hedberg */ 6011a2ec905dSAlain Michaud if (!ext_adv && (type == LE_ADV_IND || 6012a2ec905dSAlain Michaud type == LE_ADV_SCAN_IND)) { 6013b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type, 6014c70a7e4cSMarcel Holtmann rssi, flags, data, len); 6015b9a6328fSJohan Hedberg return; 6016b9a6328fSJohan Hedberg } 6017b9a6328fSJohan Hedberg 6018b9a6328fSJohan Hedberg /* The advertising reports cannot be merged, so clear 6019b9a6328fSJohan Hedberg * the pending report and send out a device found event. 6020b9a6328fSJohan Hedberg */ 6021b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 60225c5b93e4SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 6023c70a7e4cSMarcel Holtmann rssi, flags, data, len, NULL, 0); 6024b9a6328fSJohan Hedberg return; 6025b9a6328fSJohan Hedberg } 6026b9a6328fSJohan Hedberg 6027b9a6328fSJohan Hedberg /* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and 6028b9a6328fSJohan Hedberg * the new event is a SCAN_RSP. We can therefore proceed with 6029b9a6328fSJohan Hedberg * sending a merged device found event. 6030b9a6328fSJohan Hedberg */ 6031b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 6032c70a7e4cSMarcel Holtmann d->last_adv_addr_type, NULL, rssi, d->last_adv_flags, 603342bd6a56SMarcel Holtmann d->last_adv_data, d->last_adv_data_len, data, len); 6034b9a6328fSJohan Hedberg clear_pending_adv_report(hdev); 60354af605d8SJohan Hedberg } 60364af605d8SJohan Hedberg 603795118dd4SLuiz Augusto von Dentz static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data, 603895118dd4SLuiz Augusto von Dentz struct sk_buff *skb) 60399aa04c91SAndre Guedes { 604095118dd4SLuiz Augusto von Dentz struct hci_ev_le_advertising_report *ev = data; 604147afe93cSLuiz Augusto von Dentz 604247afe93cSLuiz Augusto von Dentz if (!ev->num) 604347afe93cSLuiz Augusto von Dentz return; 60449aa04c91SAndre Guedes 6045a4790dbdSAndre Guedes hci_dev_lock(hdev); 6046a4790dbdSAndre Guedes 604747afe93cSLuiz Augusto von Dentz while (ev->num--) { 604847afe93cSLuiz Augusto von Dentz struct hci_ev_le_advertising_info *info; 60494af605d8SJohan Hedberg s8 rssi; 6050a4790dbdSAndre Guedes 605147afe93cSLuiz Augusto von Dentz info = hci_le_ev_skb_pull(hdev, skb, 605247afe93cSLuiz Augusto von Dentz HCI_EV_LE_ADVERTISING_REPORT, 605347afe93cSLuiz Augusto von Dentz sizeof(*info)); 605447afe93cSLuiz Augusto von Dentz if (!info) 6055899663beSBrian Gix break; 6056899663beSBrian Gix 605747afe93cSLuiz Augusto von Dentz if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_ADVERTISING_REPORT, 605847afe93cSLuiz Augusto von Dentz info->length + 1)) 605947afe93cSLuiz Augusto von Dentz break; 606047afe93cSLuiz Augusto von Dentz 606147afe93cSLuiz Augusto von Dentz if (info->length <= HCI_MAX_AD_LENGTH) { 606247afe93cSLuiz Augusto von Dentz rssi = info->data[info->length]; 606347afe93cSLuiz Augusto von Dentz process_adv_report(hdev, info->type, &info->bdaddr, 606447afe93cSLuiz Augusto von Dentz info->bdaddr_type, NULL, 0, rssi, 606547afe93cSLuiz Augusto von Dentz info->data, info->length, false); 6066ee649346SChriz Chow } else { 6067ee649346SChriz Chow bt_dev_err(hdev, "Dropping invalid advertising data"); 6068ee649346SChriz Chow } 60699aa04c91SAndre Guedes } 6070a4790dbdSAndre Guedes 6071a4790dbdSAndre Guedes hci_dev_unlock(hdev); 60729aa04c91SAndre Guedes } 60739aa04c91SAndre Guedes 6074657cc646SMarcel Holtmann static u8 ext_evt_type_to_legacy(struct hci_dev *hdev, u16 evt_type) 6075c215e939SJaganath Kanakkassery { 6076b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_LEGACY_PDU) { 6077c215e939SJaganath Kanakkassery switch (evt_type) { 6078c215e939SJaganath Kanakkassery case LE_LEGACY_ADV_IND: 6079c215e939SJaganath Kanakkassery return LE_ADV_IND; 6080c215e939SJaganath Kanakkassery case LE_LEGACY_ADV_DIRECT_IND: 6081c215e939SJaganath Kanakkassery return LE_ADV_DIRECT_IND; 6082c215e939SJaganath Kanakkassery case LE_LEGACY_ADV_SCAN_IND: 6083c215e939SJaganath Kanakkassery return LE_ADV_SCAN_IND; 6084c215e939SJaganath Kanakkassery case LE_LEGACY_NONCONN_IND: 6085c215e939SJaganath Kanakkassery return LE_ADV_NONCONN_IND; 6086c215e939SJaganath Kanakkassery case LE_LEGACY_SCAN_RSP_ADV: 6087c215e939SJaganath Kanakkassery case LE_LEGACY_SCAN_RSP_ADV_SCAN: 6088c215e939SJaganath Kanakkassery return LE_ADV_SCAN_RSP; 6089c215e939SJaganath Kanakkassery } 6090c215e939SJaganath Kanakkassery 6091657cc646SMarcel Holtmann goto invalid; 6092c215e939SJaganath Kanakkassery } 6093c215e939SJaganath Kanakkassery 6094b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_CONN_IND) { 6095b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_DIRECT_IND) 6096b2cc9761SJaganath Kanakkassery return LE_ADV_DIRECT_IND; 6097b2cc9761SJaganath Kanakkassery 6098b2cc9761SJaganath Kanakkassery return LE_ADV_IND; 6099b2cc9761SJaganath Kanakkassery } 6100b2cc9761SJaganath Kanakkassery 6101b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_SCAN_RSP) 6102b2cc9761SJaganath Kanakkassery return LE_ADV_SCAN_RSP; 6103b2cc9761SJaganath Kanakkassery 6104b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_SCAN_IND) 6105b2cc9761SJaganath Kanakkassery return LE_ADV_SCAN_IND; 6106b2cc9761SJaganath Kanakkassery 6107b2cc9761SJaganath Kanakkassery if (evt_type == LE_EXT_ADV_NON_CONN_IND || 6108b2cc9761SJaganath Kanakkassery evt_type & LE_EXT_ADV_DIRECT_IND) 6109b2cc9761SJaganath Kanakkassery return LE_ADV_NONCONN_IND; 6110b2cc9761SJaganath Kanakkassery 6111657cc646SMarcel Holtmann invalid: 6112657cc646SMarcel Holtmann bt_dev_err_ratelimited(hdev, "Unknown advertising packet type: 0x%02x", 6113b2cc9761SJaganath Kanakkassery evt_type); 6114b2cc9761SJaganath Kanakkassery 6115b2cc9761SJaganath Kanakkassery return LE_ADV_INVALID; 6116b2cc9761SJaganath Kanakkassery } 6117b2cc9761SJaganath Kanakkassery 611895118dd4SLuiz Augusto von Dentz static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data, 611995118dd4SLuiz Augusto von Dentz struct sk_buff *skb) 6120c215e939SJaganath Kanakkassery { 612195118dd4SLuiz Augusto von Dentz struct hci_ev_le_ext_adv_report *ev = data; 6122b48b833fSLuiz Augusto von Dentz 6123b48b833fSLuiz Augusto von Dentz if (!ev->num) 6124b48b833fSLuiz Augusto von Dentz return; 6125c215e939SJaganath Kanakkassery 6126c215e939SJaganath Kanakkassery hci_dev_lock(hdev); 6127c215e939SJaganath Kanakkassery 6128b48b833fSLuiz Augusto von Dentz while (ev->num--) { 6129b48b833fSLuiz Augusto von Dentz struct hci_ev_le_ext_adv_info *info; 6130c215e939SJaganath Kanakkassery u8 legacy_evt_type; 6131c215e939SJaganath Kanakkassery u16 evt_type; 6132c215e939SJaganath Kanakkassery 6133b48b833fSLuiz Augusto von Dentz info = hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_EXT_ADV_REPORT, 6134b48b833fSLuiz Augusto von Dentz sizeof(*info)); 6135b48b833fSLuiz Augusto von Dentz if (!info) 6136b48b833fSLuiz Augusto von Dentz break; 6137b48b833fSLuiz Augusto von Dentz 6138b48b833fSLuiz Augusto von Dentz if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_EXT_ADV_REPORT, 6139b48b833fSLuiz Augusto von Dentz info->length)) 6140b48b833fSLuiz Augusto von Dentz break; 6141b48b833fSLuiz Augusto von Dentz 6142b48b833fSLuiz Augusto von Dentz evt_type = __le16_to_cpu(info->type); 6143657cc646SMarcel Holtmann legacy_evt_type = ext_evt_type_to_legacy(hdev, evt_type); 6144c215e939SJaganath Kanakkassery if (legacy_evt_type != LE_ADV_INVALID) { 6145b48b833fSLuiz Augusto von Dentz process_adv_report(hdev, legacy_evt_type, &info->bdaddr, 6146b48b833fSLuiz Augusto von Dentz info->bdaddr_type, NULL, 0, 6147b48b833fSLuiz Augusto von Dentz info->rssi, info->data, info->length, 6148a2ec905dSAlain Michaud !(evt_type & LE_EXT_ADV_LEGACY_PDU)); 6149c215e939SJaganath Kanakkassery } 6150c215e939SJaganath Kanakkassery } 6151c215e939SJaganath Kanakkassery 6152c215e939SJaganath Kanakkassery hci_dev_unlock(hdev); 6153c215e939SJaganath Kanakkassery } 6154c215e939SJaganath Kanakkassery 615595118dd4SLuiz Augusto von Dentz static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev, void *data, 61560fe29fd1SMarcel Holtmann struct sk_buff *skb) 61570fe29fd1SMarcel Holtmann { 615895118dd4SLuiz Augusto von Dentz struct hci_ev_le_remote_feat_complete *ev = data; 61590fe29fd1SMarcel Holtmann struct hci_conn *conn; 61600fe29fd1SMarcel Holtmann 616195118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 61620fe29fd1SMarcel Holtmann 61630fe29fd1SMarcel Holtmann hci_dev_lock(hdev); 61640fe29fd1SMarcel Holtmann 61650fe29fd1SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 61660fe29fd1SMarcel Holtmann if (conn) { 61670fe29fd1SMarcel Holtmann if (!ev->status) 61680fe29fd1SMarcel Holtmann memcpy(conn->features[0], ev->features, 8); 61690fe29fd1SMarcel Holtmann 61700fe29fd1SMarcel Holtmann if (conn->state == BT_CONFIG) { 61710fe29fd1SMarcel Holtmann __u8 status; 61720fe29fd1SMarcel Holtmann 6173ef365da1SArchie Pusaka /* If the local controller supports peripheral-initiated 61740fe29fd1SMarcel Holtmann * features exchange, but the remote controller does 61750fe29fd1SMarcel Holtmann * not, then it is possible that the error code 0x1a 61760fe29fd1SMarcel Holtmann * for unsupported remote feature gets returned. 61770fe29fd1SMarcel Holtmann * 61780fe29fd1SMarcel Holtmann * In this specific case, allow the connection to 61790fe29fd1SMarcel Holtmann * transition into connected state and mark it as 61800fe29fd1SMarcel Holtmann * successful. 61810fe29fd1SMarcel Holtmann */ 6182ef365da1SArchie Pusaka if (!conn->out && ev->status == 0x1a && 6183ef365da1SArchie Pusaka (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES)) 61840fe29fd1SMarcel Holtmann status = 0x00; 61850fe29fd1SMarcel Holtmann else 61860fe29fd1SMarcel Holtmann status = ev->status; 61870fe29fd1SMarcel Holtmann 61880fe29fd1SMarcel Holtmann conn->state = BT_CONNECTED; 61890fe29fd1SMarcel Holtmann hci_connect_cfm(conn, status); 61900fe29fd1SMarcel Holtmann hci_conn_drop(conn); 61910fe29fd1SMarcel Holtmann } 61920fe29fd1SMarcel Holtmann } 61930fe29fd1SMarcel Holtmann 61940fe29fd1SMarcel Holtmann hci_dev_unlock(hdev); 61950fe29fd1SMarcel Holtmann } 61960fe29fd1SMarcel Holtmann 619795118dd4SLuiz Augusto von Dentz static void hci_le_ltk_request_evt(struct hci_dev *hdev, void *data, 619895118dd4SLuiz Augusto von Dentz struct sk_buff *skb) 6199a7a595f6SVinicius Costa Gomes { 620095118dd4SLuiz Augusto von Dentz struct hci_ev_le_ltk_req *ev = data; 6201a7a595f6SVinicius Costa Gomes struct hci_cp_le_ltk_reply cp; 6202bea710feSVinicius Costa Gomes struct hci_cp_le_ltk_neg_reply neg; 6203a7a595f6SVinicius Costa Gomes struct hci_conn *conn; 6204c9839a11SVinicius Costa Gomes struct smp_ltk *ltk; 6205a7a595f6SVinicius Costa Gomes 620695118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%4.4x", __le16_to_cpu(ev->handle)); 6207a7a595f6SVinicius Costa Gomes 6208a7a595f6SVinicius Costa Gomes hci_dev_lock(hdev); 6209a7a595f6SVinicius Costa Gomes 6210a7a595f6SVinicius Costa Gomes conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 6211bea710feSVinicius Costa Gomes if (conn == NULL) 6212bea710feSVinicius Costa Gomes goto not_found; 6213a7a595f6SVinicius Costa Gomes 6214f3a73d97SJohan Hedberg ltk = hci_find_ltk(hdev, &conn->dst, conn->dst_type, conn->role); 62155378bc56SJohan Hedberg if (!ltk) 6216bea710feSVinicius Costa Gomes goto not_found; 6217bea710feSVinicius Costa Gomes 62185378bc56SJohan Hedberg if (smp_ltk_is_sc(ltk)) { 62195378bc56SJohan Hedberg /* With SC both EDiv and Rand are set to zero */ 62205378bc56SJohan Hedberg if (ev->ediv || ev->rand) 62215378bc56SJohan Hedberg goto not_found; 62225378bc56SJohan Hedberg } else { 62235378bc56SJohan Hedberg /* For non-SC keys check that EDiv and Rand match */ 62245378bc56SJohan Hedberg if (ev->ediv != ltk->ediv || ev->rand != ltk->rand) 62255378bc56SJohan Hedberg goto not_found; 62265378bc56SJohan Hedberg } 62275378bc56SJohan Hedberg 62288b76ce34SJohan Hedberg memcpy(cp.ltk, ltk->val, ltk->enc_size); 62298b76ce34SJohan Hedberg memset(cp.ltk + ltk->enc_size, 0, sizeof(cp.ltk) - ltk->enc_size); 6230a7a595f6SVinicius Costa Gomes cp.handle = cpu_to_le16(conn->handle); 6231c9839a11SVinicius Costa Gomes 6232a6f7833cSJohan Hedberg conn->pending_sec_level = smp_ltk_sec_level(ltk); 6233a7a595f6SVinicius Costa Gomes 623489cbb4daSAndre Guedes conn->enc_key_size = ltk->enc_size; 6235a7a595f6SVinicius Costa Gomes 6236a7a595f6SVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); 6237a7a595f6SVinicius Costa Gomes 62385981a882SClaudio Takahasi /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a 62395981a882SClaudio Takahasi * temporary key used to encrypt a connection following 62405981a882SClaudio Takahasi * pairing. It is used during the Encrypted Session Setup to 62415981a882SClaudio Takahasi * distribute the keys. Later, security can be re-established 62425981a882SClaudio Takahasi * using a distributed LTK. 62435981a882SClaudio Takahasi */ 62442ceba539SJohan Hedberg if (ltk->type == SMP_STK) { 6245fe59a05fSJohan Hedberg set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); 6246970d0f1bSJohan Hedberg list_del_rcu(<k->list); 6247970d0f1bSJohan Hedberg kfree_rcu(ltk, rcu); 6248fe59a05fSJohan Hedberg } else { 6249fe59a05fSJohan Hedberg clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags); 6250c9839a11SVinicius Costa Gomes } 6251c9839a11SVinicius Costa Gomes 6252a7a595f6SVinicius Costa Gomes hci_dev_unlock(hdev); 6253bea710feSVinicius Costa Gomes 6254bea710feSVinicius Costa Gomes return; 6255bea710feSVinicius Costa Gomes 6256bea710feSVinicius Costa Gomes not_found: 6257bea710feSVinicius Costa Gomes neg.handle = ev->handle; 6258bea710feSVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg); 6259bea710feSVinicius Costa Gomes hci_dev_unlock(hdev); 6260a7a595f6SVinicius Costa Gomes } 6261a7a595f6SVinicius Costa Gomes 62628e75b46aSAndre Guedes static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle, 62638e75b46aSAndre Guedes u8 reason) 62648e75b46aSAndre Guedes { 62658e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_neg_reply cp; 62668e75b46aSAndre Guedes 62678e75b46aSAndre Guedes cp.handle = cpu_to_le16(handle); 62688e75b46aSAndre Guedes cp.reason = reason; 62698e75b46aSAndre Guedes 62708e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp), 62718e75b46aSAndre Guedes &cp); 62728e75b46aSAndre Guedes } 62738e75b46aSAndre Guedes 627495118dd4SLuiz Augusto von Dentz static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, void *data, 62758e75b46aSAndre Guedes struct sk_buff *skb) 62768e75b46aSAndre Guedes { 627795118dd4SLuiz Augusto von Dentz struct hci_ev_le_remote_conn_param_req *ev = data; 62788e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_reply cp; 62798e75b46aSAndre Guedes struct hci_conn *hcon; 62808e75b46aSAndre Guedes u16 handle, min, max, latency, timeout; 62818e75b46aSAndre Guedes 628295118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%4.4x", __le16_to_cpu(ev->handle)); 628312cfe417SLuiz Augusto von Dentz 62848e75b46aSAndre Guedes handle = le16_to_cpu(ev->handle); 62858e75b46aSAndre Guedes min = le16_to_cpu(ev->interval_min); 62868e75b46aSAndre Guedes max = le16_to_cpu(ev->interval_max); 62878e75b46aSAndre Guedes latency = le16_to_cpu(ev->latency); 62888e75b46aSAndre Guedes timeout = le16_to_cpu(ev->timeout); 62898e75b46aSAndre Guedes 62908e75b46aSAndre Guedes hcon = hci_conn_hash_lookup_handle(hdev, handle); 62918e75b46aSAndre Guedes if (!hcon || hcon->state != BT_CONNECTED) 62928e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle, 62938e75b46aSAndre Guedes HCI_ERROR_UNKNOWN_CONN_ID); 62948e75b46aSAndre Guedes 62958e75b46aSAndre Guedes if (hci_check_conn_params(min, max, latency, timeout)) 62968e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle, 62978e75b46aSAndre Guedes HCI_ERROR_INVALID_LL_PARAMS); 62988e75b46aSAndre Guedes 629940bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) { 6300348d50b8SJohan Hedberg struct hci_conn_params *params; 6301f4869e2aSJohan Hedberg u8 store_hint; 6302348d50b8SJohan Hedberg 6303348d50b8SJohan Hedberg hci_dev_lock(hdev); 6304348d50b8SJohan Hedberg 6305348d50b8SJohan Hedberg params = hci_conn_params_lookup(hdev, &hcon->dst, 6306348d50b8SJohan Hedberg hcon->dst_type); 6307348d50b8SJohan Hedberg if (params) { 6308348d50b8SJohan Hedberg params->conn_min_interval = min; 6309348d50b8SJohan Hedberg params->conn_max_interval = max; 6310348d50b8SJohan Hedberg params->conn_latency = latency; 6311348d50b8SJohan Hedberg params->supervision_timeout = timeout; 6312f4869e2aSJohan Hedberg store_hint = 0x01; 6313f4869e2aSJohan Hedberg } else { 6314f4869e2aSJohan Hedberg store_hint = 0x00; 6315348d50b8SJohan Hedberg } 6316348d50b8SJohan Hedberg 6317348d50b8SJohan Hedberg hci_dev_unlock(hdev); 6318348d50b8SJohan Hedberg 6319f4869e2aSJohan Hedberg mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type, 6320f4869e2aSJohan Hedberg store_hint, min, max, latency, timeout); 6321348d50b8SJohan Hedberg } 6322ffb5a827SAndre Guedes 63238e75b46aSAndre Guedes cp.handle = ev->handle; 63248e75b46aSAndre Guedes cp.interval_min = ev->interval_min; 63258e75b46aSAndre Guedes cp.interval_max = ev->interval_max; 63268e75b46aSAndre Guedes cp.latency = ev->latency; 63278e75b46aSAndre Guedes cp.timeout = ev->timeout; 63288e75b46aSAndre Guedes cp.min_ce_len = 0; 63298e75b46aSAndre Guedes cp.max_ce_len = 0; 63308e75b46aSAndre Guedes 63318e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp); 63328e75b46aSAndre Guedes } 63338e75b46aSAndre Guedes 633495118dd4SLuiz Augusto von Dentz static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, void *data, 63352f010b55SMarcel Holtmann struct sk_buff *skb) 63362f010b55SMarcel Holtmann { 633795118dd4SLuiz Augusto von Dentz struct hci_ev_le_direct_adv_report *ev = data; 6338a3679649SLuiz Augusto von Dentz int i; 6339f7e0e8b2SPeilin Ye 6340a3679649SLuiz Augusto von Dentz if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_DIRECT_ADV_REPORT, 6341a3679649SLuiz Augusto von Dentz flex_array_size(ev, info, ev->num))) 6342a3679649SLuiz Augusto von Dentz return; 6343a3679649SLuiz Augusto von Dentz 6344a3679649SLuiz Augusto von Dentz if (!ev->num) 6345f7e0e8b2SPeilin Ye return; 63462f010b55SMarcel Holtmann 63472f010b55SMarcel Holtmann hci_dev_lock(hdev); 63482f010b55SMarcel Holtmann 6349a3679649SLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) { 6350a3679649SLuiz Augusto von Dentz struct hci_ev_le_direct_adv_info *info = &ev->info[i]; 6351a3679649SLuiz Augusto von Dentz 6352a3679649SLuiz Augusto von Dentz process_adv_report(hdev, info->type, &info->bdaddr, 6353a3679649SLuiz Augusto von Dentz info->bdaddr_type, &info->direct_addr, 6354a3679649SLuiz Augusto von Dentz info->direct_addr_type, info->rssi, NULL, 0, 6355a2ec905dSAlain Michaud false); 6356a3679649SLuiz Augusto von Dentz } 63572f010b55SMarcel Holtmann 63582f010b55SMarcel Holtmann hci_dev_unlock(hdev); 63592f010b55SMarcel Holtmann } 63602f010b55SMarcel Holtmann 636195118dd4SLuiz Augusto von Dentz static void hci_le_phy_update_evt(struct hci_dev *hdev, void *data, 636295118dd4SLuiz Augusto von Dentz struct sk_buff *skb) 63631efd927dSLuiz Augusto von Dentz { 636495118dd4SLuiz Augusto von Dentz struct hci_ev_le_phy_update_complete *ev = data; 63651efd927dSLuiz Augusto von Dentz struct hci_conn *conn; 63661efd927dSLuiz Augusto von Dentz 636795118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); 63681efd927dSLuiz Augusto von Dentz 636987df8bccSAyush Garg if (ev->status) 63701efd927dSLuiz Augusto von Dentz return; 63711efd927dSLuiz Augusto von Dentz 63721efd927dSLuiz Augusto von Dentz hci_dev_lock(hdev); 63731efd927dSLuiz Augusto von Dentz 63741efd927dSLuiz Augusto von Dentz conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); 63751efd927dSLuiz Augusto von Dentz if (!conn) 63761efd927dSLuiz Augusto von Dentz goto unlock; 63771efd927dSLuiz Augusto von Dentz 63781efd927dSLuiz Augusto von Dentz conn->le_tx_phy = ev->tx_phy; 63791efd927dSLuiz Augusto von Dentz conn->le_rx_phy = ev->rx_phy; 63801efd927dSLuiz Augusto von Dentz 63811efd927dSLuiz Augusto von Dentz unlock: 63821efd927dSLuiz Augusto von Dentz hci_dev_unlock(hdev); 63831efd927dSLuiz Augusto von Dentz } 63841efd927dSLuiz Augusto von Dentz 638595118dd4SLuiz Augusto von Dentz #define HCI_LE_EV_VL(_op, _func, _min_len, _max_len) \ 638695118dd4SLuiz Augusto von Dentz [_op] = { \ 638795118dd4SLuiz Augusto von Dentz .func = _func, \ 638895118dd4SLuiz Augusto von Dentz .min_len = _min_len, \ 638995118dd4SLuiz Augusto von Dentz .max_len = _max_len, \ 639095118dd4SLuiz Augusto von Dentz } 639195118dd4SLuiz Augusto von Dentz 639295118dd4SLuiz Augusto von Dentz #define HCI_LE_EV(_op, _func, _len) \ 639395118dd4SLuiz Augusto von Dentz HCI_LE_EV_VL(_op, _func, _len, _len) 639495118dd4SLuiz Augusto von Dentz 639595118dd4SLuiz Augusto von Dentz #define HCI_LE_EV_STATUS(_op, _func) \ 639695118dd4SLuiz Augusto von Dentz HCI_LE_EV(_op, _func, sizeof(struct hci_ev_status)) 639795118dd4SLuiz Augusto von Dentz 639895118dd4SLuiz Augusto von Dentz /* Entries in this table shall have their position according to the subevent 639995118dd4SLuiz Augusto von Dentz * opcode they handle so the use of the macros above is recommend since it does 640095118dd4SLuiz Augusto von Dentz * attempt to initialize at its proper index using Designated Initializers that 640195118dd4SLuiz Augusto von Dentz * way events without a callback function can be ommited. 640295118dd4SLuiz Augusto von Dentz */ 640395118dd4SLuiz Augusto von Dentz static const struct hci_le_ev { 640495118dd4SLuiz Augusto von Dentz void (*func)(struct hci_dev *hdev, void *data, struct sk_buff *skb); 640595118dd4SLuiz Augusto von Dentz u16 min_len; 640695118dd4SLuiz Augusto von Dentz u16 max_len; 640795118dd4SLuiz Augusto von Dentz } hci_le_ev_table[U8_MAX + 1] = { 640895118dd4SLuiz Augusto von Dentz /* [0x01 = HCI_EV_LE_CONN_COMPLETE] */ 640995118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_CONN_COMPLETE, hci_le_conn_complete_evt, 641095118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_conn_complete)), 641195118dd4SLuiz Augusto von Dentz /* [0x02 = HCI_EV_LE_ADVERTISING_REPORT] */ 641295118dd4SLuiz Augusto von Dentz HCI_LE_EV_VL(HCI_EV_LE_ADVERTISING_REPORT, hci_le_adv_report_evt, 641395118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_advertising_report), 641495118dd4SLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE), 641595118dd4SLuiz Augusto von Dentz /* [0x03 = HCI_EV_LE_CONN_UPDATE_COMPLETE] */ 641695118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_CONN_UPDATE_COMPLETE, 641795118dd4SLuiz Augusto von Dentz hci_le_conn_update_complete_evt, 641895118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_conn_update_complete)), 641995118dd4SLuiz Augusto von Dentz /* [0x04 = HCI_EV_LE_REMOTE_FEAT_COMPLETE] */ 642095118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_REMOTE_FEAT_COMPLETE, 642195118dd4SLuiz Augusto von Dentz hci_le_remote_feat_complete_evt, 642295118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_remote_feat_complete)), 642395118dd4SLuiz Augusto von Dentz /* [0x05 = HCI_EV_LE_LTK_REQ] */ 642495118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_LTK_REQ, hci_le_ltk_request_evt, 642595118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_ltk_req)), 642695118dd4SLuiz Augusto von Dentz /* [0x06 = HCI_EV_LE_REMOTE_CONN_PARAM_REQ] */ 642795118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_REMOTE_CONN_PARAM_REQ, 642895118dd4SLuiz Augusto von Dentz hci_le_remote_conn_param_req_evt, 642995118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_remote_conn_param_req)), 643095118dd4SLuiz Augusto von Dentz /* [0x0a = HCI_EV_LE_ENHANCED_CONN_COMPLETE] */ 643195118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_ENHANCED_CONN_COMPLETE, 643295118dd4SLuiz Augusto von Dentz hci_le_enh_conn_complete_evt, 643395118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_enh_conn_complete)), 643495118dd4SLuiz Augusto von Dentz /* [0x0b = HCI_EV_LE_DIRECT_ADV_REPORT] */ 643595118dd4SLuiz Augusto von Dentz HCI_LE_EV_VL(HCI_EV_LE_DIRECT_ADV_REPORT, hci_le_direct_adv_report_evt, 643695118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_direct_adv_report), 643795118dd4SLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE), 643895118dd4SLuiz Augusto von Dentz /* [0x0c = HCI_EV_LE_PHY_UPDATE_COMPLETE] */ 643995118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_PHY_UPDATE_COMPLETE, hci_le_phy_update_evt, 644095118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_phy_update_complete)), 644195118dd4SLuiz Augusto von Dentz /* [0x0d = HCI_EV_LE_EXT_ADV_REPORT] */ 644295118dd4SLuiz Augusto von Dentz HCI_LE_EV_VL(HCI_EV_LE_EXT_ADV_REPORT, hci_le_ext_adv_report_evt, 644395118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_ext_adv_report), 644495118dd4SLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE), 644595118dd4SLuiz Augusto von Dentz /* [0x12 = HCI_EV_LE_EXT_ADV_SET_TERM] */ 644695118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_EXT_ADV_SET_TERM, hci_le_ext_adv_term_evt, 644795118dd4SLuiz Augusto von Dentz sizeof(struct hci_evt_le_ext_adv_set_term)), 644895118dd4SLuiz Augusto von Dentz }; 644995118dd4SLuiz Augusto von Dentz 64503e54c589SLuiz Augusto von Dentz static void hci_le_meta_evt(struct hci_dev *hdev, void *data, 64513e54c589SLuiz Augusto von Dentz struct sk_buff *skb) 6452fcd89c09SVille Tervo { 64533e54c589SLuiz Augusto von Dentz struct hci_ev_le_meta *ev = data; 645495118dd4SLuiz Augusto von Dentz const struct hci_le_ev *subev; 6455fcd89c09SVille Tervo 645695118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "subevent 0x%2.2x", ev->subevent); 6457fcd89c09SVille Tervo 645895118dd4SLuiz Augusto von Dentz subev = &hci_le_ev_table[ev->subevent]; 645995118dd4SLuiz Augusto von Dentz if (!subev->func) 646095118dd4SLuiz Augusto von Dentz return; 64611855d92dSMarcel Holtmann 646295118dd4SLuiz Augusto von Dentz if (skb->len < subev->min_len) { 646395118dd4SLuiz Augusto von Dentz bt_dev_err(hdev, "unexpected subevent 0x%2.2x length: %u < %u", 646495118dd4SLuiz Augusto von Dentz ev->subevent, skb->len, subev->min_len); 646595118dd4SLuiz Augusto von Dentz return; 6466fcd89c09SVille Tervo } 646795118dd4SLuiz Augusto von Dentz 646895118dd4SLuiz Augusto von Dentz /* Just warn if the length is over max_len size it still be 646995118dd4SLuiz Augusto von Dentz * possible to partially parse the event so leave to callback to 647095118dd4SLuiz Augusto von Dentz * decide if that is acceptable. 647195118dd4SLuiz Augusto von Dentz */ 647295118dd4SLuiz Augusto von Dentz if (skb->len > subev->max_len) 647395118dd4SLuiz Augusto von Dentz bt_dev_warn(hdev, "unexpected subevent 0x%2.2x length: %u > %u", 647495118dd4SLuiz Augusto von Dentz ev->subevent, skb->len, subev->max_len); 647595118dd4SLuiz Augusto von Dentz 647695118dd4SLuiz Augusto von Dentz data = hci_le_ev_skb_pull(hdev, skb, ev->subevent, subev->min_len); 647795118dd4SLuiz Augusto von Dentz if (!data) 647895118dd4SLuiz Augusto von Dentz return; 647995118dd4SLuiz Augusto von Dentz 648095118dd4SLuiz Augusto von Dentz subev->func(hdev, data, skb); 6481fcd89c09SVille Tervo } 6482fcd89c09SVille Tervo 6483757aa0b5SJohan Hedberg static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, 6484757aa0b5SJohan Hedberg u8 event, struct sk_buff *skb) 6485757aa0b5SJohan Hedberg { 6486757aa0b5SJohan Hedberg struct hci_ev_cmd_complete *ev; 6487757aa0b5SJohan Hedberg struct hci_event_hdr *hdr; 6488757aa0b5SJohan Hedberg 6489757aa0b5SJohan Hedberg if (!skb) 6490757aa0b5SJohan Hedberg return false; 6491757aa0b5SJohan Hedberg 6492e3f3a1aeSLuiz Augusto von Dentz hdr = hci_ev_skb_pull(hdev, skb, event, sizeof(*hdr)); 6493e3f3a1aeSLuiz Augusto von Dentz if (!hdr) 6494757aa0b5SJohan Hedberg return false; 6495757aa0b5SJohan Hedberg 6496757aa0b5SJohan Hedberg if (event) { 6497757aa0b5SJohan Hedberg if (hdr->evt != event) 6498757aa0b5SJohan Hedberg return false; 6499757aa0b5SJohan Hedberg return true; 6500757aa0b5SJohan Hedberg } 6501757aa0b5SJohan Hedberg 650291641b79SZheng Yongjun /* Check if request ended in Command Status - no way to retrieve 65031629db9cSJohan Hedberg * any extra parameters in this case. 65041629db9cSJohan Hedberg */ 65051629db9cSJohan Hedberg if (hdr->evt == HCI_EV_CMD_STATUS) 65061629db9cSJohan Hedberg return false; 65071629db9cSJohan Hedberg 6508757aa0b5SJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) { 65092064ee33SMarcel Holtmann bt_dev_err(hdev, "last event is not cmd complete (0x%2.2x)", 65102064ee33SMarcel Holtmann hdr->evt); 6511757aa0b5SJohan Hedberg return false; 6512757aa0b5SJohan Hedberg } 6513757aa0b5SJohan Hedberg 6514e3f3a1aeSLuiz Augusto von Dentz ev = hci_cc_skb_pull(hdev, skb, opcode, sizeof(*ev)); 6515e3f3a1aeSLuiz Augusto von Dentz if (!ev) 6516757aa0b5SJohan Hedberg return false; 6517757aa0b5SJohan Hedberg 6518757aa0b5SJohan Hedberg if (opcode != __le16_to_cpu(ev->opcode)) { 6519757aa0b5SJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, 6520757aa0b5SJohan Hedberg __le16_to_cpu(ev->opcode)); 6521757aa0b5SJohan Hedberg return false; 6522757aa0b5SJohan Hedberg } 6523757aa0b5SJohan Hedberg 6524757aa0b5SJohan Hedberg return true; 6525757aa0b5SJohan Hedberg } 6526757aa0b5SJohan Hedberg 65272f20216cSAbhishek Pandit-Subedi static void hci_store_wake_reason(struct hci_dev *hdev, u8 event, 65282f20216cSAbhishek Pandit-Subedi struct sk_buff *skb) 65292f20216cSAbhishek Pandit-Subedi { 65302f20216cSAbhishek Pandit-Subedi struct hci_ev_le_advertising_info *adv; 65312f20216cSAbhishek Pandit-Subedi struct hci_ev_le_direct_adv_info *direct_adv; 6532b48b833fSLuiz Augusto von Dentz struct hci_ev_le_ext_adv_info *ext_adv; 65332f20216cSAbhishek Pandit-Subedi const struct hci_ev_conn_complete *conn_complete = (void *)skb->data; 65342f20216cSAbhishek Pandit-Subedi const struct hci_ev_conn_request *conn_request = (void *)skb->data; 65352f20216cSAbhishek Pandit-Subedi 65362f20216cSAbhishek Pandit-Subedi hci_dev_lock(hdev); 65372f20216cSAbhishek Pandit-Subedi 65382f20216cSAbhishek Pandit-Subedi /* If we are currently suspended and this is the first BT event seen, 65392f20216cSAbhishek Pandit-Subedi * save the wake reason associated with the event. 65402f20216cSAbhishek Pandit-Subedi */ 65412f20216cSAbhishek Pandit-Subedi if (!hdev->suspended || hdev->wake_reason) 65422f20216cSAbhishek Pandit-Subedi goto unlock; 65432f20216cSAbhishek Pandit-Subedi 65442f20216cSAbhishek Pandit-Subedi /* Default to remote wake. Values for wake_reason are documented in the 65452f20216cSAbhishek Pandit-Subedi * Bluez mgmt api docs. 65462f20216cSAbhishek Pandit-Subedi */ 65472f20216cSAbhishek Pandit-Subedi hdev->wake_reason = MGMT_WAKE_REASON_REMOTE_WAKE; 65482f20216cSAbhishek Pandit-Subedi 65492f20216cSAbhishek Pandit-Subedi /* Once configured for remote wakeup, we should only wake up for 65502f20216cSAbhishek Pandit-Subedi * reconnections. It's useful to see which device is waking us up so 65512f20216cSAbhishek Pandit-Subedi * keep track of the bdaddr of the connection event that woke us up. 65522f20216cSAbhishek Pandit-Subedi */ 65532f20216cSAbhishek Pandit-Subedi if (event == HCI_EV_CONN_REQUEST) { 65542f20216cSAbhishek Pandit-Subedi bacpy(&hdev->wake_addr, &conn_complete->bdaddr); 65552f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = BDADDR_BREDR; 65562f20216cSAbhishek Pandit-Subedi } else if (event == HCI_EV_CONN_COMPLETE) { 65572f20216cSAbhishek Pandit-Subedi bacpy(&hdev->wake_addr, &conn_request->bdaddr); 65582f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = BDADDR_BREDR; 65592f20216cSAbhishek Pandit-Subedi } else if (event == HCI_EV_LE_META) { 65602f20216cSAbhishek Pandit-Subedi struct hci_ev_le_meta *le_ev = (void *)skb->data; 65612f20216cSAbhishek Pandit-Subedi u8 subevent = le_ev->subevent; 65622f20216cSAbhishek Pandit-Subedi u8 *ptr = &skb->data[sizeof(*le_ev)]; 65632f20216cSAbhishek Pandit-Subedi u8 num_reports = *ptr; 65642f20216cSAbhishek Pandit-Subedi 65652f20216cSAbhishek Pandit-Subedi if ((subevent == HCI_EV_LE_ADVERTISING_REPORT || 65662f20216cSAbhishek Pandit-Subedi subevent == HCI_EV_LE_DIRECT_ADV_REPORT || 65672f20216cSAbhishek Pandit-Subedi subevent == HCI_EV_LE_EXT_ADV_REPORT) && 65682f20216cSAbhishek Pandit-Subedi num_reports) { 65692f20216cSAbhishek Pandit-Subedi adv = (void *)(ptr + 1); 65702f20216cSAbhishek Pandit-Subedi direct_adv = (void *)(ptr + 1); 65712f20216cSAbhishek Pandit-Subedi ext_adv = (void *)(ptr + 1); 65722f20216cSAbhishek Pandit-Subedi 65732f20216cSAbhishek Pandit-Subedi switch (subevent) { 65742f20216cSAbhishek Pandit-Subedi case HCI_EV_LE_ADVERTISING_REPORT: 65752f20216cSAbhishek Pandit-Subedi bacpy(&hdev->wake_addr, &adv->bdaddr); 65762f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = adv->bdaddr_type; 65772f20216cSAbhishek Pandit-Subedi break; 65782f20216cSAbhishek Pandit-Subedi case HCI_EV_LE_DIRECT_ADV_REPORT: 65792f20216cSAbhishek Pandit-Subedi bacpy(&hdev->wake_addr, &direct_adv->bdaddr); 65802f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = direct_adv->bdaddr_type; 65812f20216cSAbhishek Pandit-Subedi break; 65822f20216cSAbhishek Pandit-Subedi case HCI_EV_LE_EXT_ADV_REPORT: 65832f20216cSAbhishek Pandit-Subedi bacpy(&hdev->wake_addr, &ext_adv->bdaddr); 65842f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = ext_adv->bdaddr_type; 65852f20216cSAbhishek Pandit-Subedi break; 65862f20216cSAbhishek Pandit-Subedi } 65872f20216cSAbhishek Pandit-Subedi } 65882f20216cSAbhishek Pandit-Subedi } else { 65892f20216cSAbhishek Pandit-Subedi hdev->wake_reason = MGMT_WAKE_REASON_UNEXPECTED; 65902f20216cSAbhishek Pandit-Subedi } 65912f20216cSAbhishek Pandit-Subedi 65922f20216cSAbhishek Pandit-Subedi unlock: 65932f20216cSAbhishek Pandit-Subedi hci_dev_unlock(hdev); 65942f20216cSAbhishek Pandit-Subedi } 65952f20216cSAbhishek Pandit-Subedi 65963e54c589SLuiz Augusto von Dentz #define HCI_EV_VL(_op, _func, _min_len, _max_len) \ 65973e54c589SLuiz Augusto von Dentz [_op] = { \ 65983e54c589SLuiz Augusto von Dentz .req = false, \ 65993e54c589SLuiz Augusto von Dentz .func = _func, \ 66003e54c589SLuiz Augusto von Dentz .min_len = _min_len, \ 66013e54c589SLuiz Augusto von Dentz .max_len = _max_len, \ 66023e54c589SLuiz Augusto von Dentz } 66033e54c589SLuiz Augusto von Dentz 66043e54c589SLuiz Augusto von Dentz #define HCI_EV(_op, _func, _len) \ 66053e54c589SLuiz Augusto von Dentz HCI_EV_VL(_op, _func, _len, _len) 66063e54c589SLuiz Augusto von Dentz 66073e54c589SLuiz Augusto von Dentz #define HCI_EV_STATUS(_op, _func) \ 66083e54c589SLuiz Augusto von Dentz HCI_EV(_op, _func, sizeof(struct hci_ev_status)) 66093e54c589SLuiz Augusto von Dentz 66103e54c589SLuiz Augusto von Dentz #define HCI_EV_REQ_VL(_op, _func, _min_len, _max_len) \ 66113e54c589SLuiz Augusto von Dentz [_op] = { \ 66123e54c589SLuiz Augusto von Dentz .req = true, \ 66133e54c589SLuiz Augusto von Dentz .func_req = _func, \ 66143e54c589SLuiz Augusto von Dentz .min_len = _min_len, \ 66153e54c589SLuiz Augusto von Dentz .max_len = _max_len, \ 66163e54c589SLuiz Augusto von Dentz } 66173e54c589SLuiz Augusto von Dentz 66183e54c589SLuiz Augusto von Dentz #define HCI_EV_REQ(_op, _func, _len) \ 66193e54c589SLuiz Augusto von Dentz HCI_EV_REQ_VL(_op, _func, _len, _len) 66203e54c589SLuiz Augusto von Dentz 66213e54c589SLuiz Augusto von Dentz /* Entries in this table shall have their position according to the event opcode 66223e54c589SLuiz Augusto von Dentz * they handle so the use of the macros above is recommend since it does attempt 66233e54c589SLuiz Augusto von Dentz * to initialize at its proper index using Designated Initializers that way 66243e54c589SLuiz Augusto von Dentz * events without a callback function don't have entered. 66253e54c589SLuiz Augusto von Dentz */ 66263e54c589SLuiz Augusto von Dentz static const struct hci_ev { 66273e54c589SLuiz Augusto von Dentz bool req; 66283e54c589SLuiz Augusto von Dentz union { 66293e54c589SLuiz Augusto von Dentz void (*func)(struct hci_dev *hdev, void *data, 66303e54c589SLuiz Augusto von Dentz struct sk_buff *skb); 66313e54c589SLuiz Augusto von Dentz void (*func_req)(struct hci_dev *hdev, void *data, 66323e54c589SLuiz Augusto von Dentz struct sk_buff *skb, u16 *opcode, u8 *status, 66333e54c589SLuiz Augusto von Dentz hci_req_complete_t *req_complete, 66343e54c589SLuiz Augusto von Dentz hci_req_complete_skb_t *req_complete_skb); 66353e54c589SLuiz Augusto von Dentz }; 66363e54c589SLuiz Augusto von Dentz u16 min_len; 66373e54c589SLuiz Augusto von Dentz u16 max_len; 66383e54c589SLuiz Augusto von Dentz } hci_ev_table[U8_MAX + 1] = { 66393e54c589SLuiz Augusto von Dentz /* [0x01 = HCI_EV_INQUIRY_COMPLETE] */ 66403e54c589SLuiz Augusto von Dentz HCI_EV_STATUS(HCI_EV_INQUIRY_COMPLETE, hci_inquiry_complete_evt), 66413e54c589SLuiz Augusto von Dentz /* [0x02 = HCI_EV_INQUIRY_RESULT] */ 66423e54c589SLuiz Augusto von Dentz HCI_EV_VL(HCI_EV_INQUIRY_RESULT, hci_inquiry_result_evt, 66433e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_inquiry_result), HCI_MAX_EVENT_SIZE), 66443e54c589SLuiz Augusto von Dentz /* [0x03 = HCI_EV_CONN_COMPLETE] */ 66453e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_CONN_COMPLETE, hci_conn_complete_evt, 66463e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_conn_complete)), 66473e54c589SLuiz Augusto von Dentz /* [0x04 = HCI_EV_CONN_REQUEST] */ 66483e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_CONN_REQUEST, hci_conn_request_evt, 66493e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_conn_request)), 66503e54c589SLuiz Augusto von Dentz /* [0x05 = HCI_EV_DISCONN_COMPLETE] */ 66513e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_DISCONN_COMPLETE, hci_disconn_complete_evt, 66523e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_disconn_complete)), 66533e54c589SLuiz Augusto von Dentz /* [0x06 = HCI_EV_AUTH_COMPLETE] */ 66543e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_AUTH_COMPLETE, hci_auth_complete_evt, 66553e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_auth_complete)), 66563e54c589SLuiz Augusto von Dentz /* [0x07 = HCI_EV_REMOTE_NAME] */ 66573e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_REMOTE_NAME, hci_remote_name_evt, 66583e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_remote_name)), 66593e54c589SLuiz Augusto von Dentz /* [0x08 = HCI_EV_ENCRYPT_CHANGE] */ 66603e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_ENCRYPT_CHANGE, hci_encrypt_change_evt, 66613e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_encrypt_change)), 66623e54c589SLuiz Augusto von Dentz /* [0x09 = HCI_EV_CHANGE_LINK_KEY_COMPLETE] */ 66633e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_CHANGE_LINK_KEY_COMPLETE, 66643e54c589SLuiz Augusto von Dentz hci_change_link_key_complete_evt, 66653e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_change_link_key_complete)), 66663e54c589SLuiz Augusto von Dentz /* [0x0b = HCI_EV_REMOTE_FEATURES] */ 66673e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_REMOTE_FEATURES, hci_remote_features_evt, 66683e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_remote_features)), 66693e54c589SLuiz Augusto von Dentz /* [0x0e = HCI_EV_CMD_COMPLETE] */ 66703e54c589SLuiz Augusto von Dentz HCI_EV_REQ_VL(HCI_EV_CMD_COMPLETE, hci_cmd_complete_evt, 66713e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_cmd_complete), HCI_MAX_EVENT_SIZE), 66723e54c589SLuiz Augusto von Dentz /* [0x0f = HCI_EV_CMD_STATUS] */ 66733e54c589SLuiz Augusto von Dentz HCI_EV_REQ(HCI_EV_CMD_STATUS, hci_cmd_status_evt, 66743e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_cmd_status)), 66753e54c589SLuiz Augusto von Dentz /* [0x10 = HCI_EV_CMD_STATUS] */ 66763e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_HARDWARE_ERROR, hci_hardware_error_evt, 66773e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_hardware_error)), 66783e54c589SLuiz Augusto von Dentz /* [0x12 = HCI_EV_ROLE_CHANGE] */ 66793e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_ROLE_CHANGE, hci_role_change_evt, 66803e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_role_change)), 66813e54c589SLuiz Augusto von Dentz /* [0x13 = HCI_EV_NUM_COMP_PKTS] */ 66823e54c589SLuiz Augusto von Dentz HCI_EV_VL(HCI_EV_NUM_COMP_PKTS, hci_num_comp_pkts_evt, 66833e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_num_comp_pkts), HCI_MAX_EVENT_SIZE), 66843e54c589SLuiz Augusto von Dentz /* [0x14 = HCI_EV_MODE_CHANGE] */ 66853e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_MODE_CHANGE, hci_mode_change_evt, 66863e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_mode_change)), 66873e54c589SLuiz Augusto von Dentz /* [0x16 = HCI_EV_PIN_CODE_REQ] */ 66883e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_PIN_CODE_REQ, hci_pin_code_request_evt, 66893e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_pin_code_req)), 66903e54c589SLuiz Augusto von Dentz /* [0x17 = HCI_EV_LINK_KEY_REQ] */ 66913e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_LINK_KEY_REQ, hci_link_key_request_evt, 66923e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_link_key_req)), 66933e54c589SLuiz Augusto von Dentz /* [0x18 = HCI_EV_LINK_KEY_NOTIFY] */ 66943e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_LINK_KEY_NOTIFY, hci_link_key_notify_evt, 66953e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_link_key_notify)), 66963e54c589SLuiz Augusto von Dentz /* [0x1c = HCI_EV_CLOCK_OFFSET] */ 66973e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_CLOCK_OFFSET, hci_clock_offset_evt, 66983e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_clock_offset)), 66993e54c589SLuiz Augusto von Dentz /* [0x1d = HCI_EV_PKT_TYPE_CHANGE] */ 67003e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_PKT_TYPE_CHANGE, hci_pkt_type_change_evt, 67013e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_pkt_type_change)), 67023e54c589SLuiz Augusto von Dentz /* [0x20 = HCI_EV_PSCAN_REP_MODE] */ 67033e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_PSCAN_REP_MODE, hci_pscan_rep_mode_evt, 67043e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_pscan_rep_mode)), 67053e54c589SLuiz Augusto von Dentz /* [0x22 = HCI_EV_INQUIRY_RESULT_WITH_RSSI] */ 67063e54c589SLuiz Augusto von Dentz HCI_EV_VL(HCI_EV_INQUIRY_RESULT_WITH_RSSI, 67073e54c589SLuiz Augusto von Dentz hci_inquiry_result_with_rssi_evt, 67083e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_inquiry_result_rssi), 67093e54c589SLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE), 67103e54c589SLuiz Augusto von Dentz /* [0x23 = HCI_EV_REMOTE_EXT_FEATURES] */ 67113e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_REMOTE_EXT_FEATURES, hci_remote_ext_features_evt, 67123e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_remote_ext_features)), 67133e54c589SLuiz Augusto von Dentz /* [0x2c = HCI_EV_SYNC_CONN_COMPLETE] */ 67143e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_SYNC_CONN_COMPLETE, hci_sync_conn_complete_evt, 67153e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_sync_conn_complete)), 67163e54c589SLuiz Augusto von Dentz /* [0x2d = HCI_EV_EXTENDED_INQUIRY_RESULT] */ 67173e54c589SLuiz Augusto von Dentz HCI_EV_VL(HCI_EV_EXTENDED_INQUIRY_RESULT, 67183e54c589SLuiz Augusto von Dentz hci_extended_inquiry_result_evt, 67193e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_ext_inquiry_result), HCI_MAX_EVENT_SIZE), 67203e54c589SLuiz Augusto von Dentz /* [0x30 = HCI_EV_KEY_REFRESH_COMPLETE] */ 67213e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_KEY_REFRESH_COMPLETE, hci_key_refresh_complete_evt, 67223e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_key_refresh_complete)), 67233e54c589SLuiz Augusto von Dentz /* [0x31 = HCI_EV_IO_CAPA_REQUEST] */ 67243e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_IO_CAPA_REQUEST, hci_io_capa_request_evt, 67253e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_io_capa_request)), 67263e54c589SLuiz Augusto von Dentz /* [0x32 = HCI_EV_IO_CAPA_REPLY] */ 67273e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_IO_CAPA_REPLY, hci_io_capa_reply_evt, 67283e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_io_capa_reply)), 67293e54c589SLuiz Augusto von Dentz /* [0x33 = HCI_EV_USER_CONFIRM_REQUEST] */ 67303e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_USER_CONFIRM_REQUEST, hci_user_confirm_request_evt, 67313e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_user_confirm_req)), 67323e54c589SLuiz Augusto von Dentz /* [0x34 = HCI_EV_USER_PASSKEY_REQUEST] */ 67333e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_USER_PASSKEY_REQUEST, hci_user_passkey_request_evt, 67343e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_user_passkey_req)), 67353e54c589SLuiz Augusto von Dentz /* [0x35 = HCI_EV_REMOTE_OOB_DATA_REQUEST] */ 67363e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_REMOTE_OOB_DATA_REQUEST, hci_remote_oob_data_request_evt, 67373e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_remote_oob_data_request)), 67383e54c589SLuiz Augusto von Dentz /* [0x36 = HCI_EV_SIMPLE_PAIR_COMPLETE] */ 67393e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_SIMPLE_PAIR_COMPLETE, hci_simple_pair_complete_evt, 67403e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_simple_pair_complete)), 67413e54c589SLuiz Augusto von Dentz /* [0x3b = HCI_EV_USER_PASSKEY_NOTIFY] */ 67423e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_USER_PASSKEY_NOTIFY, hci_user_passkey_notify_evt, 67433e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_user_passkey_notify)), 67443e54c589SLuiz Augusto von Dentz /* [0x3c = HCI_EV_KEYPRESS_NOTIFY] */ 67453e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_KEYPRESS_NOTIFY, hci_keypress_notify_evt, 67463e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_keypress_notify)), 67473e54c589SLuiz Augusto von Dentz /* [0x3d = HCI_EV_REMOTE_HOST_FEATURES] */ 67483e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_REMOTE_HOST_FEATURES, hci_remote_host_features_evt, 67493e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_remote_host_features)), 67503e54c589SLuiz Augusto von Dentz /* [0x3e = HCI_EV_LE_META] */ 67513e54c589SLuiz Augusto von Dentz HCI_EV_VL(HCI_EV_LE_META, hci_le_meta_evt, 67523e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_le_meta), HCI_MAX_EVENT_SIZE), 67533e54c589SLuiz Augusto von Dentz #if IS_ENABLED(CONFIG_BT_HS) 67543e54c589SLuiz Augusto von Dentz /* [0x40 = HCI_EV_PHY_LINK_COMPLETE] */ 67553e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_PHY_LINK_COMPLETE, hci_phy_link_complete_evt, 67563e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_phy_link_complete)), 67573e54c589SLuiz Augusto von Dentz /* [0x41 = HCI_EV_CHANNEL_SELECTED] */ 67583e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_CHANNEL_SELECTED, hci_chan_selected_evt, 67593e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_channel_selected)), 67603e54c589SLuiz Augusto von Dentz /* [0x42 = HCI_EV_DISCONN_PHY_LINK_COMPLETE] */ 67613e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE, 67623e54c589SLuiz Augusto von Dentz hci_disconn_loglink_complete_evt, 67633e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_disconn_logical_link_complete)), 67643e54c589SLuiz Augusto von Dentz /* [0x45 = HCI_EV_LOGICAL_LINK_COMPLETE] */ 67653e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_LOGICAL_LINK_COMPLETE, hci_loglink_complete_evt, 67663e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_logical_link_complete)), 67673e54c589SLuiz Augusto von Dentz /* [0x46 = HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE] */ 67683e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_DISCONN_PHY_LINK_COMPLETE, 67693e54c589SLuiz Augusto von Dentz hci_disconn_phylink_complete_evt, 67703e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_disconn_phy_link_complete)), 67713e54c589SLuiz Augusto von Dentz #endif 67723e54c589SLuiz Augusto von Dentz /* [0x48 = HCI_EV_NUM_COMP_BLOCKS] */ 67733e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_NUM_COMP_BLOCKS, hci_num_comp_blocks_evt, 67743e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_num_comp_blocks)), 67753e54c589SLuiz Augusto von Dentz /* [0xff = HCI_EV_VENDOR] */ 67763e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_VENDOR, msft_vendor_evt, 0), 67773e54c589SLuiz Augusto von Dentz }; 67783e54c589SLuiz Augusto von Dentz 67793e54c589SLuiz Augusto von Dentz static void hci_event_func(struct hci_dev *hdev, u8 event, struct sk_buff *skb, 67803e54c589SLuiz Augusto von Dentz u16 *opcode, u8 *status, 67813e54c589SLuiz Augusto von Dentz hci_req_complete_t *req_complete, 67823e54c589SLuiz Augusto von Dentz hci_req_complete_skb_t *req_complete_skb) 67833e54c589SLuiz Augusto von Dentz { 67843e54c589SLuiz Augusto von Dentz const struct hci_ev *ev = &hci_ev_table[event]; 67853e54c589SLuiz Augusto von Dentz void *data; 67863e54c589SLuiz Augusto von Dentz 67873e54c589SLuiz Augusto von Dentz if (!ev->func) 67883e54c589SLuiz Augusto von Dentz return; 67893e54c589SLuiz Augusto von Dentz 67903e54c589SLuiz Augusto von Dentz if (skb->len < ev->min_len) { 67913e54c589SLuiz Augusto von Dentz bt_dev_err(hdev, "unexpected event 0x%2.2x length: %u < %u", 67923e54c589SLuiz Augusto von Dentz event, skb->len, ev->min_len); 67933e54c589SLuiz Augusto von Dentz return; 67943e54c589SLuiz Augusto von Dentz } 67953e54c589SLuiz Augusto von Dentz 67963e54c589SLuiz Augusto von Dentz /* Just warn if the length is over max_len size it still be 67973e54c589SLuiz Augusto von Dentz * possible to partially parse the event so leave to callback to 67983e54c589SLuiz Augusto von Dentz * decide if that is acceptable. 67993e54c589SLuiz Augusto von Dentz */ 68003e54c589SLuiz Augusto von Dentz if (skb->len > ev->max_len) 68013e54c589SLuiz Augusto von Dentz bt_dev_warn(hdev, "unexpected event 0x%2.2x length: %u > %u", 68023e54c589SLuiz Augusto von Dentz event, skb->len, ev->max_len); 68033e54c589SLuiz Augusto von Dentz 68043e54c589SLuiz Augusto von Dentz data = hci_ev_skb_pull(hdev, skb, event, ev->min_len); 68053e54c589SLuiz Augusto von Dentz if (!data) 68063e54c589SLuiz Augusto von Dentz return; 68073e54c589SLuiz Augusto von Dentz 68083e54c589SLuiz Augusto von Dentz if (ev->req) 68093e54c589SLuiz Augusto von Dentz ev->func_req(hdev, data, skb, opcode, status, req_complete, 68103e54c589SLuiz Augusto von Dentz req_complete_skb); 68113e54c589SLuiz Augusto von Dentz else 68123e54c589SLuiz Augusto von Dentz ev->func(hdev, data, skb); 68133e54c589SLuiz Augusto von Dentz } 68143e54c589SLuiz Augusto von Dentz 68151da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) 68161da177e4SLinus Torvalds { 6817a9de9248SMarcel Holtmann struct hci_event_hdr *hdr = (void *) skb->data; 6818e6214487SJohan Hedberg hci_req_complete_t req_complete = NULL; 6819e6214487SJohan Hedberg hci_req_complete_skb_t req_complete_skb = NULL; 6820e6214487SJohan Hedberg struct sk_buff *orig_skb = NULL; 6821e3f3a1aeSLuiz Augusto von Dentz u8 status = 0, event, req_evt = 0; 6822e6214487SJohan Hedberg u16 opcode = HCI_OP_NOP; 68231da177e4SLinus Torvalds 6824e3f3a1aeSLuiz Augusto von Dentz if (skb->len < sizeof(*hdr)) { 6825e3f3a1aeSLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed HCI Event"); 6826e3f3a1aeSLuiz Augusto von Dentz goto done; 6827e3f3a1aeSLuiz Augusto von Dentz } 6828e3f3a1aeSLuiz Augusto von Dentz 6829e3f3a1aeSLuiz Augusto von Dentz event = hdr->evt; 683008bb4da9SAlain Michaud if (!event) { 68313e54c589SLuiz Augusto von Dentz bt_dev_warn(hdev, "Received unexpected HCI Event 0x%2.2x", 68323e54c589SLuiz Augusto von Dentz event); 683308bb4da9SAlain Michaud goto done; 683408bb4da9SAlain Michaud } 683508bb4da9SAlain Michaud 6836242c0ebdSMarcel Holtmann if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->hci.req_event == event) { 6837c1f23a2bSJohannes Berg struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data; 6838e6214487SJohan Hedberg opcode = __le16_to_cpu(cmd_hdr->opcode); 6839e6214487SJohan Hedberg hci_req_cmd_complete(hdev, opcode, status, &req_complete, 6840e6214487SJohan Hedberg &req_complete_skb); 6841757aa0b5SJohan Hedberg req_evt = event; 684202350a72SJohan Hedberg } 684302350a72SJohan Hedberg 6844e6214487SJohan Hedberg /* If it looks like we might end up having to call 6845e6214487SJohan Hedberg * req_complete_skb, store a pristine copy of the skb since the 6846e6214487SJohan Hedberg * various handlers may modify the original one through 6847e6214487SJohan Hedberg * skb_pull() calls, etc. 6848e6214487SJohan Hedberg */ 6849e6214487SJohan Hedberg if (req_complete_skb || event == HCI_EV_CMD_STATUS || 6850e6214487SJohan Hedberg event == HCI_EV_CMD_COMPLETE) 6851e6214487SJohan Hedberg orig_skb = skb_clone(skb, GFP_KERNEL); 6852e6214487SJohan Hedberg 6853e6214487SJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE); 6854e6214487SJohan Hedberg 68552f20216cSAbhishek Pandit-Subedi /* Store wake reason if we're suspended */ 68562f20216cSAbhishek Pandit-Subedi hci_store_wake_reason(hdev, event, skb); 68572f20216cSAbhishek Pandit-Subedi 68583e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "event 0x%2.2x", event); 68591da177e4SLinus Torvalds 68603e54c589SLuiz Augusto von Dentz hci_event_func(hdev, event, skb, &opcode, &status, &req_complete, 6861e6214487SJohan Hedberg &req_complete_skb); 68621da177e4SLinus Torvalds 6863757aa0b5SJohan Hedberg if (req_complete) { 6864e6214487SJohan Hedberg req_complete(hdev, status, opcode); 6865757aa0b5SJohan Hedberg } else if (req_complete_skb) { 6866757aa0b5SJohan Hedberg if (!hci_get_cmd_complete(hdev, opcode, req_evt, orig_skb)) { 6867757aa0b5SJohan Hedberg kfree_skb(orig_skb); 6868757aa0b5SJohan Hedberg orig_skb = NULL; 6869757aa0b5SJohan Hedberg } 6870e6214487SJohan Hedberg req_complete_skb(hdev, status, opcode, orig_skb); 6871757aa0b5SJohan Hedberg } 6872e6214487SJohan Hedberg 687308bb4da9SAlain Michaud done: 6874e6214487SJohan Hedberg kfree_skb(orig_skb); 68751da177e4SLinus Torvalds kfree_skb(skb); 68761da177e4SLinus Torvalds hdev->stat.evt_rx++; 68771da177e4SLinus Torvalds } 6878