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 #ifndef __HCI_CORE_H 261da177e4SLinus Torvalds #define __HCI_CORE_H 271da177e4SLinus Torvalds 281da177e4SLinus Torvalds #include <net/bluetooth/hci.h> 291da177e4SLinus Torvalds 305e59b791SLuiz Augusto von Dentz /* HCI priority */ 315e59b791SLuiz Augusto von Dentz #define HCI_PRIO_MAX 7 325e59b791SLuiz Augusto von Dentz 331da177e4SLinus Torvalds /* HCI Core structures */ 341da177e4SLinus Torvalds struct inquiry_data { 351da177e4SLinus Torvalds bdaddr_t bdaddr; 361da177e4SLinus Torvalds __u8 pscan_rep_mode; 371da177e4SLinus Torvalds __u8 pscan_period_mode; 381da177e4SLinus Torvalds __u8 pscan_mode; 391da177e4SLinus Torvalds __u8 dev_class[3]; 401ebb9252SMarcel Holtmann __le16 clock_offset; 411da177e4SLinus Torvalds __s8 rssi; 4241a96212SMarcel Holtmann __u8 ssp_mode; 431da177e4SLinus Torvalds }; 441da177e4SLinus Torvalds 451da177e4SLinus Torvalds struct inquiry_entry { 46561aafbcSJohan Hedberg struct list_head all; /* inq_cache.all */ 47561aafbcSJohan Hedberg struct list_head list; /* unknown or resolve */ 48561aafbcSJohan Hedberg enum { 49561aafbcSJohan Hedberg NAME_NOT_KNOWN, 50561aafbcSJohan Hedberg NAME_NEEDED, 51561aafbcSJohan Hedberg NAME_PENDING, 52561aafbcSJohan Hedberg NAME_KNOWN, 53561aafbcSJohan Hedberg } name_state; 541da177e4SLinus Torvalds __u32 timestamp; 551da177e4SLinus Torvalds struct inquiry_data data; 561da177e4SLinus Torvalds }; 571da177e4SLinus Torvalds 5830883512SJohan Hedberg struct discovery_state { 594aab14e5SAndre Guedes int type; 60ff9ef578SJohan Hedberg enum { 61ff9ef578SJohan Hedberg DISCOVERY_STOPPED, 62ff9ef578SJohan Hedberg DISCOVERY_STARTING, 63343f935bSAndre Guedes DISCOVERY_FINDING, 6430dc78e1SJohan Hedberg DISCOVERY_RESOLVING, 65ff9ef578SJohan Hedberg DISCOVERY_STOPPING, 66ff9ef578SJohan Hedberg } state; 67561aafbcSJohan Hedberg struct list_head all; /* All devices found during inquiry */ 68561aafbcSJohan Hedberg struct list_head unknown; /* Name state not known */ 69561aafbcSJohan Hedberg struct list_head resolve; /* Name needs to be resolved */ 701da177e4SLinus Torvalds __u32 timestamp; 71b9a6328fSJohan Hedberg bdaddr_t last_adv_addr; 72b9a6328fSJohan Hedberg u8 last_adv_addr_type; 73ff5cd29fSJohan Hedberg s8 last_adv_rssi; 74c70a7e4cSMarcel Holtmann u32 last_adv_flags; 75b9a6328fSJohan Hedberg u8 last_adv_data[HCI_MAX_AD_LENGTH]; 76b9a6328fSJohan Hedberg u8 last_adv_data_len; 771da177e4SLinus Torvalds }; 781da177e4SLinus Torvalds 791da177e4SLinus Torvalds struct hci_conn_hash { 801da177e4SLinus Torvalds struct list_head list; 811da177e4SLinus Torvalds unsigned int acl_num; 82bd1eb66bSAndrei Emeltchenko unsigned int amp_num; 831da177e4SLinus Torvalds unsigned int sco_num; 84fcd89c09SVille Tervo unsigned int le_num; 851da177e4SLinus Torvalds }; 861da177e4SLinus Torvalds 87f0358568SJohan Hedberg struct bdaddr_list { 88f0358568SJohan Hedberg struct list_head list; 89f0358568SJohan Hedberg bdaddr_t bdaddr; 90b9ee0a78SMarcel Holtmann u8 bdaddr_type; 91f0358568SJohan Hedberg }; 922aeb9a1aSJohan Hedberg 932aeb9a1aSJohan Hedberg struct bt_uuid { 942aeb9a1aSJohan Hedberg struct list_head list; 952aeb9a1aSJohan Hedberg u8 uuid[16]; 9683be8ecaSJohan Hedberg u8 size; 971aff6f09SJohan Hedberg u8 svc_hint; 982aeb9a1aSJohan Hedberg }; 992aeb9a1aSJohan Hedberg 1007ee4ea36SMarcel Holtmann struct smp_csrk { 1017ee4ea36SMarcel Holtmann bdaddr_t bdaddr; 1027ee4ea36SMarcel Holtmann u8 bdaddr_type; 1037ee4ea36SMarcel Holtmann u8 master; 1047ee4ea36SMarcel Holtmann u8 val[16]; 1057ee4ea36SMarcel Holtmann }; 1067ee4ea36SMarcel Holtmann 107b899efafSVinicius Costa Gomes struct smp_ltk { 108b899efafSVinicius Costa Gomes struct list_head list; 109b899efafSVinicius Costa Gomes bdaddr_t bdaddr; 110b899efafSVinicius Costa Gomes u8 bdaddr_type; 111b899efafSVinicius Costa Gomes u8 authenticated; 112b899efafSVinicius Costa Gomes u8 type; 113b899efafSVinicius Costa Gomes u8 enc_size; 114b899efafSVinicius Costa Gomes __le16 ediv; 115fe39c7b2SMarcel Holtmann __le64 rand; 116b899efafSVinicius Costa Gomes u8 val[16]; 11703c515d7SMarcel Holtmann }; 118b899efafSVinicius Costa Gomes 119970c4e46SJohan Hedberg struct smp_irk { 120970c4e46SJohan Hedberg struct list_head list; 121970c4e46SJohan Hedberg bdaddr_t rpa; 122970c4e46SJohan Hedberg bdaddr_t bdaddr; 123970c4e46SJohan Hedberg u8 addr_type; 124970c4e46SJohan Hedberg u8 val[16]; 125970c4e46SJohan Hedberg }; 126970c4e46SJohan Hedberg 12755ed8ca1SJohan Hedberg struct link_key { 12855ed8ca1SJohan Hedberg struct list_head list; 12955ed8ca1SJohan Hedberg bdaddr_t bdaddr; 13055ed8ca1SJohan Hedberg u8 type; 1319b3b4460SAndrei Emeltchenko u8 val[HCI_LINK_KEY_SIZE]; 13255ed8ca1SJohan Hedberg u8 pin_len; 13355ed8ca1SJohan Hedberg }; 13455ed8ca1SJohan Hedberg 1352763eda6SSzymon Janc struct oob_data { 1362763eda6SSzymon Janc struct list_head list; 1372763eda6SSzymon Janc bdaddr_t bdaddr; 138519ca9d0SMarcel Holtmann u8 hash192[16]; 139519ca9d0SMarcel Holtmann u8 randomizer192[16]; 140519ca9d0SMarcel Holtmann u8 hash256[16]; 141519ca9d0SMarcel Holtmann u8 randomizer256[16]; 1422763eda6SSzymon Janc }; 1432763eda6SSzymon Janc 144490c5babSJohan Hedberg #define HCI_MAX_SHORT_NAME_LENGTH 10 145490c5babSJohan Hedberg 146d6bfd59cSJohan Hedberg /* Default LE RPA expiry time, 15 minutes */ 147d6bfd59cSJohan Hedberg #define HCI_DEFAULT_RPA_TIMEOUT (15 * 60) 148d6bfd59cSJohan Hedberg 14931ad1691SAndrzej Kaczmarek /* Default min/max age of connection information (1s/3s) */ 15031ad1691SAndrzej Kaczmarek #define DEFAULT_CONN_INFO_MIN_AGE 1000 15131ad1691SAndrzej Kaczmarek #define DEFAULT_CONN_INFO_MAX_AGE 3000 15231ad1691SAndrzej Kaczmarek 153903e4541SAndrei Emeltchenko struct amp_assoc { 154903e4541SAndrei Emeltchenko __u16 len; 155903e4541SAndrei Emeltchenko __u16 offset; 15693c284eeSAndrei Emeltchenko __u16 rem_len; 15793c284eeSAndrei Emeltchenko __u16 len_so_far; 158903e4541SAndrei Emeltchenko __u8 data[HCI_MAX_AMP_ASSOC_SIZE]; 159903e4541SAndrei Emeltchenko }; 160903e4541SAndrei Emeltchenko 161d2c5d77fSJohan Hedberg #define HCI_MAX_PAGES 3 162cad718edSJohan Hedberg 163cd4c5391SSuraj Sumangala #define NUM_REASSEMBLY 4 1641da177e4SLinus Torvalds struct hci_dev { 1651da177e4SLinus Torvalds struct list_head list; 16609fd0de5SGustavo F. Padovan struct mutex lock; 1671da177e4SLinus Torvalds 1681da177e4SLinus Torvalds char name[8]; 1691da177e4SLinus Torvalds unsigned long flags; 1701da177e4SLinus Torvalds __u16 id; 171c13854ceSMarcel Holtmann __u8 bus; 172943da25dSMarcel Holtmann __u8 dev_type; 1731da177e4SLinus Torvalds bdaddr_t bdaddr; 174e30d3f5fSMarcel Holtmann bdaddr_t setup_addr; 17524c457e2SMarcel Holtmann bdaddr_t public_addr; 1767a4cd51dSMarcel Holtmann bdaddr_t random_addr; 177d13eafceSMarcel Holtmann bdaddr_t static_addr; 17856ed2cb8SJohan Hedberg __u8 adv_addr_type; 1791f6c6378SJohan Hedberg __u8 dev_name[HCI_MAX_NAME_LENGTH]; 180490c5babSJohan Hedberg __u8 short_name[HCI_MAX_SHORT_NAME_LENGTH]; 18180a1e1dbSJohan Hedberg __u8 eir[HCI_MAX_EIR_LENGTH]; 182a9de9248SMarcel Holtmann __u8 dev_class[3]; 1831aff6f09SJohan Hedberg __u8 major_class; 1841aff6f09SJohan Hedberg __u8 minor_class; 185d2c5d77fSJohan Hedberg __u8 max_page; 186cad718edSJohan Hedberg __u8 features[HCI_MAX_PAGES][8]; 18760e77321SJohan Hedberg __u8 le_features[8]; 188cf1d081fSJohan Hedberg __u8 le_white_list_size; 1899b008c04SJohan Hedberg __u8 le_states[8]; 190a9de9248SMarcel Holtmann __u8 commands[64]; 1911143e5a6SMarcel Holtmann __u8 hci_ver; 1921143e5a6SMarcel Holtmann __u16 hci_rev; 193d5859e22SJohan Hedberg __u8 lmp_ver; 1941143e5a6SMarcel Holtmann __u16 manufacturer; 1957d69230cSAndrei Emeltchenko __u16 lmp_subver; 1961da177e4SLinus Torvalds __u16 voice_setting; 197b4cb9fb2SMarcel Holtmann __u8 num_iac; 19817fa4b9dSJohan Hedberg __u8 io_capability; 19991c4e9b1SMarcel Holtmann __s8 inq_tx_power; 200f332ec66SJohan Hedberg __u16 page_scan_interval; 201f332ec66SJohan Hedberg __u16 page_scan_window; 202f332ec66SJohan Hedberg __u8 page_scan_type; 2033f959d46SMarcel Holtmann __u8 le_adv_channel_map; 204533553f8SMarcel Holtmann __u8 le_scan_type; 205bef64738SMarcel Holtmann __u16 le_scan_interval; 206bef64738SMarcel Holtmann __u16 le_scan_window; 2074e70c7e7SMarcel Holtmann __u16 le_conn_min_interval; 2084e70c7e7SMarcel Holtmann __u16 le_conn_max_interval; 20904fb7d90SMarcel Holtmann __u16 le_conn_latency; 21004fb7d90SMarcel Holtmann __u16 le_supv_timeout; 211b9a7a61eSLukasz Rymanowski __u16 discov_interleaved_timeout; 21231ad1691SAndrzej Kaczmarek __u16 conn_info_min_age; 21331ad1691SAndrzej Kaczmarek __u16 conn_info_max_age; 21406f5b778SMarcel Holtmann __u8 ssp_debug_mode; 21533f35721SJohan Hedberg __u32 clock; 216f332ec66SJohan Hedberg 2172b9be137SMarcel Holtmann __u16 devid_source; 2182b9be137SMarcel Holtmann __u16 devid_vendor; 2192b9be137SMarcel Holtmann __u16 devid_product; 2202b9be137SMarcel Holtmann __u16 devid_version; 2211da177e4SLinus Torvalds 2221da177e4SLinus Torvalds __u16 pkt_type; 2235b7f9909SMarcel Holtmann __u16 esco_type; 2241da177e4SLinus Torvalds __u16 link_policy; 2251da177e4SLinus Torvalds __u16 link_mode; 2261da177e4SLinus Torvalds 22704837f64SMarcel Holtmann __u32 idle_timeout; 22804837f64SMarcel Holtmann __u16 sniff_min_interval; 22904837f64SMarcel Holtmann __u16 sniff_max_interval; 23004837f64SMarcel Holtmann 231928abaa7SAndrei Emeltchenko __u8 amp_status; 232928abaa7SAndrei Emeltchenko __u32 amp_total_bw; 233928abaa7SAndrei Emeltchenko __u32 amp_max_bw; 234928abaa7SAndrei Emeltchenko __u32 amp_min_latency; 235928abaa7SAndrei Emeltchenko __u32 amp_max_pdu; 236928abaa7SAndrei Emeltchenko __u8 amp_type; 237928abaa7SAndrei Emeltchenko __u16 amp_pal_cap; 238928abaa7SAndrei Emeltchenko __u16 amp_assoc_size; 239928abaa7SAndrei Emeltchenko __u32 amp_max_flush_to; 240928abaa7SAndrei Emeltchenko __u32 amp_be_flush_to; 241928abaa7SAndrei Emeltchenko 242903e4541SAndrei Emeltchenko struct amp_assoc loc_assoc; 243903e4541SAndrei Emeltchenko 2441e89cffbSAndrei Emeltchenko __u8 flow_ctl_mode; 2451e89cffbSAndrei Emeltchenko 2469f61656aSJohan Hedberg unsigned int auto_accept_delay; 2479f61656aSJohan Hedberg 2481da177e4SLinus Torvalds unsigned long quirks; 2491da177e4SLinus Torvalds 2501da177e4SLinus Torvalds atomic_t cmd_cnt; 2511da177e4SLinus Torvalds unsigned int acl_cnt; 2521da177e4SLinus Torvalds unsigned int sco_cnt; 2536ed58ec5SVille Tervo unsigned int le_cnt; 2541da177e4SLinus Torvalds 2551da177e4SLinus Torvalds unsigned int acl_mtu; 2561da177e4SLinus Torvalds unsigned int sco_mtu; 2576ed58ec5SVille Tervo unsigned int le_mtu; 2581da177e4SLinus Torvalds unsigned int acl_pkts; 2591da177e4SLinus Torvalds unsigned int sco_pkts; 2606ed58ec5SVille Tervo unsigned int le_pkts; 2611da177e4SLinus Torvalds 262350ee4cfSAndrei Emeltchenko __u16 block_len; 263350ee4cfSAndrei Emeltchenko __u16 block_mtu; 264350ee4cfSAndrei Emeltchenko __u16 num_blocks; 265350ee4cfSAndrei Emeltchenko __u16 block_cnt; 266350ee4cfSAndrei Emeltchenko 2671da177e4SLinus Torvalds unsigned long acl_last_tx; 2681da177e4SLinus Torvalds unsigned long sco_last_tx; 2696ed58ec5SVille Tervo unsigned long le_last_tx; 2701da177e4SLinus Torvalds 271f48fd9c8SMarcel Holtmann struct workqueue_struct *workqueue; 2726ead1bbcSJohan Hedberg struct workqueue_struct *req_workqueue; 273f48fd9c8SMarcel Holtmann 274ab81cbf9SJohan Hedberg struct work_struct power_on; 2753243553fSJohan Hedberg struct delayed_work power_off; 276ab81cbf9SJohan Hedberg 27716ab91abSJohan Hedberg __u16 discov_timeout; 27816ab91abSJohan Hedberg struct delayed_work discov_off; 27916ab91abSJohan Hedberg 2807d78525dSJohan Hedberg struct delayed_work service_cache; 2817d78525dSJohan Hedberg 28265cc2b49SMarcel Holtmann struct delayed_work cmd_timer; 283b78752ccSMarcel Holtmann 284b78752ccSMarcel Holtmann struct work_struct rx_work; 285c347b765SGustavo F. Padovan struct work_struct cmd_work; 2863eff45eaSGustavo F. Padovan struct work_struct tx_work; 2871da177e4SLinus Torvalds 2881da177e4SLinus Torvalds struct sk_buff_head rx_q; 2891da177e4SLinus Torvalds struct sk_buff_head raw_q; 2901da177e4SLinus Torvalds struct sk_buff_head cmd_q; 2911da177e4SLinus Torvalds 292b6ddb638SJohan Hedberg struct sk_buff *recv_evt; 2931da177e4SLinus Torvalds struct sk_buff *sent_cmd; 294cd4c5391SSuraj Sumangala struct sk_buff *reassembly[NUM_REASSEMBLY]; 2951da177e4SLinus Torvalds 296a6a67efdSThomas Gleixner struct mutex req_lock; 2971da177e4SLinus Torvalds wait_queue_head_t req_wait_q; 2981da177e4SLinus Torvalds __u32 req_status; 2991da177e4SLinus Torvalds __u32 req_result; 300a5040efaSJohan Hedberg 30199780a7bSJohan Hedberg struct crypto_blkcipher *tfm_aes; 3022e58ef3eSJohan Hedberg 30330883512SJohan Hedberg struct discovery_state discovery; 3041da177e4SLinus Torvalds struct hci_conn_hash conn_hash; 3055c136e90SAndre Guedes 3065c136e90SAndre Guedes struct list_head mgmt_pending; 307ea4bd8baSDavid Miller struct list_head blacklist; 3082aeb9a1aSJohan Hedberg struct list_head uuids; 30955ed8ca1SJohan Hedberg struct list_head link_keys; 310b899efafSVinicius Costa Gomes struct list_head long_term_keys; 311970c4e46SJohan Hedberg struct list_head identity_resolving_keys; 3122763eda6SSzymon Janc struct list_head remote_oob_data; 313d2ab0ac1SMarcel Holtmann struct list_head le_white_list; 31415819a70SAndre Guedes struct list_head le_conn_params; 31577a77a30SAndre Guedes struct list_head pend_le_conns; 31666f8455aSJohan Hedberg struct list_head pend_le_reports; 3172763eda6SSzymon Janc 3181da177e4SLinus Torvalds struct hci_dev_stats stat; 3191da177e4SLinus Torvalds 3201da177e4SLinus Torvalds atomic_t promisc; 3211da177e4SLinus Torvalds 322ca325f69SMarcel Holtmann struct dentry *debugfs; 323ca325f69SMarcel Holtmann 324a91f2e39SMarcel Holtmann struct device dev; 3251da177e4SLinus Torvalds 326611b30f7SMarcel Holtmann struct rfkill *rfkill; 327611b30f7SMarcel Holtmann 328111902f7SMarcel Holtmann unsigned long dbg_flags; 329d23264a8SAndre Guedes unsigned long dev_flags; 330d23264a8SAndre Guedes 3317ba8b4beSAndre Guedes struct delayed_work le_scan_disable; 3327ba8b4beSAndre Guedes 3338fa19098SJohan Hedberg __s8 adv_tx_power; 3343f0f524bSJohan Hedberg __u8 adv_data[HCI_MAX_AD_LENGTH]; 3353f0f524bSJohan Hedberg __u8 adv_data_len; 336f8e808bdSMarcel Holtmann __u8 scan_rsp_data[HCI_MAX_AD_LENGTH]; 337f8e808bdSMarcel Holtmann __u8 scan_rsp_data_len; 3388fa19098SJohan Hedberg 339863efaf2SJohan Hedberg __u8 irk[16]; 340d6bfd59cSJohan Hedberg __u32 rpa_timeout; 341d6bfd59cSJohan Hedberg struct delayed_work rpa_expired; 3422b5224dcSMarcel Holtmann bdaddr_t rpa; 343863efaf2SJohan Hedberg 3441da177e4SLinus Torvalds int (*open)(struct hci_dev *hdev); 3451da177e4SLinus Torvalds int (*close)(struct hci_dev *hdev); 3461da177e4SLinus Torvalds int (*flush)(struct hci_dev *hdev); 347f41c70c4SMarcel Holtmann int (*setup)(struct hci_dev *hdev); 3487bd8f09fSMarcel Holtmann int (*send)(struct hci_dev *hdev, struct sk_buff *skb); 3491da177e4SLinus Torvalds void (*notify)(struct hci_dev *hdev, unsigned int evt); 35024c457e2SMarcel Holtmann int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr); 3511da177e4SLinus Torvalds }; 3521da177e4SLinus Torvalds 35353502d69SAndrei Emeltchenko #define HCI_PHY_HANDLE(handle) (handle & 0xff) 35453502d69SAndrei Emeltchenko 3551da177e4SLinus Torvalds struct hci_conn { 3561da177e4SLinus Torvalds struct list_head list; 3571da177e4SLinus Torvalds 3581da177e4SLinus Torvalds atomic_t refcnt; 3591da177e4SLinus Torvalds 3601da177e4SLinus Torvalds bdaddr_t dst; 36129b7988aSAndre Guedes __u8 dst_type; 362662e8820SMarcel Holtmann bdaddr_t src; 363e7c4096eSMarcel Holtmann __u8 src_type; 364cb1d68f7SJohan Hedberg bdaddr_t init_addr; 365cb1d68f7SJohan Hedberg __u8 init_addr_type; 366cb1d68f7SJohan Hedberg bdaddr_t resp_addr; 367cb1d68f7SJohan Hedberg __u8 resp_addr_type; 3681da177e4SLinus Torvalds __u16 handle; 3691da177e4SLinus Torvalds __u16 state; 37004837f64SMarcel Holtmann __u8 mode; 3711da177e4SLinus Torvalds __u8 type; 372a0c808b3SJohan Hedberg bool out; 3734c67bc74SMarcel Holtmann __u8 attempt; 3741da177e4SLinus Torvalds __u8 dev_class[3]; 375cad718edSJohan Hedberg __u8 features[HCI_MAX_PAGES][8]; 376a8746417SMarcel Holtmann __u16 pkt_type; 37704837f64SMarcel Holtmann __u16 link_policy; 37813d39315SWaldemar Rymarkiewicz __u8 key_type; 37940be492fSMarcel Holtmann __u8 auth_type; 3808c1b2355SMarcel Holtmann __u8 sec_level; 381765c2a96SJohan Hedberg __u8 pending_sec_level; 382980e1a53SJohan Hedberg __u8 pin_length; 383726b4ffcSVinicius Costa Gomes __u8 enc_key_size; 38417fa4b9dSJohan Hedberg __u8 io_capability; 38592a25256SJohan Hedberg __u32 passkey_notify; 38692a25256SJohan Hedberg __u8 passkey_entered; 387052b30b0SMarcel Holtmann __u16 disc_timeout; 38810c62ddcSFrédéric Dalleau __u16 setting; 3891e406eefSAndre Guedes __u16 le_conn_min_interval; 3901e406eefSAndre Guedes __u16 le_conn_max_interval; 391e04fde60SMarcel Holtmann __u16 le_conn_interval; 392e04fde60SMarcel Holtmann __u16 le_conn_latency; 393e04fde60SMarcel Holtmann __u16 le_supv_timeout; 3945ae76a94SAndrzej Kaczmarek __s8 rssi; 3955a134faeSAndrzej Kaczmarek __s8 tx_power; 396d0455ed9SAndrzej Kaczmarek __s8 max_tx_power; 39751a8efd7SJohan Hedberg unsigned long flags; 3981da177e4SLinus Torvalds 39933f35721SJohan Hedberg __u32 clock; 40033f35721SJohan Hedberg __u16 clock_accuracy; 40133f35721SJohan Hedberg 402dd983808SAndrzej Kaczmarek unsigned long conn_info_timestamp; 403dd983808SAndrzej Kaczmarek 40403b555e1SJohan Hedberg __u8 remote_cap; 40503b555e1SJohan Hedberg __u8 remote_auth; 4063161ae1cSAndrei Emeltchenko __u8 remote_id; 40703b555e1SJohan Hedberg 4081da177e4SLinus Torvalds unsigned int sent; 4091da177e4SLinus Torvalds 4101da177e4SLinus Torvalds struct sk_buff_head data_q; 4112c33c06aSGustavo F. Padovan struct list_head chan_list; 4121da177e4SLinus Torvalds 41319c40e3bSGustavo F. Padovan struct delayed_work disc_work; 4147bc18d9dSJohan Hedberg struct delayed_work auto_accept_work; 415a74a84f6SJohan Hedberg struct delayed_work idle_work; 4169489eca4SJohan Hedberg struct delayed_work le_conn_timeout; 4171da177e4SLinus Torvalds 418b219e3acSMarcel Holtmann struct device dev; 419b219e3acSMarcel Holtmann 4201da177e4SLinus Torvalds struct hci_dev *hdev; 4211da177e4SLinus Torvalds void *l2cap_data; 4221da177e4SLinus Torvalds void *sco_data; 4239740e49dSAndrei Emeltchenko struct amp_mgr *amp_mgr; 4241da177e4SLinus Torvalds 4251da177e4SLinus Torvalds struct hci_conn *link; 426e9a416b5SJohan Hedberg 427e9a416b5SJohan Hedberg void (*connect_cfm_cb) (struct hci_conn *conn, u8 status); 428e9a416b5SJohan Hedberg void (*security_cfm_cb) (struct hci_conn *conn, u8 status); 429e9a416b5SJohan Hedberg void (*disconn_cfm_cb) (struct hci_conn *conn, u8 reason); 4301da177e4SLinus Torvalds }; 4311da177e4SLinus Torvalds 43273d80debSLuiz Augusto von Dentz struct hci_chan { 43373d80debSLuiz Augusto von Dentz struct list_head list; 43442c4e53eSAndrei Emeltchenko __u16 handle; 43573d80debSLuiz Augusto von Dentz struct hci_conn *conn; 43673d80debSLuiz Augusto von Dentz struct sk_buff_head data_q; 43773d80debSLuiz Augusto von Dentz unsigned int sent; 438168df8e5SMat Martineau __u8 state; 43973d80debSLuiz Augusto von Dentz }; 44073d80debSLuiz Augusto von Dentz 44115819a70SAndre Guedes struct hci_conn_params { 44215819a70SAndre Guedes struct list_head list; 44393450c75SJohan Hedberg struct list_head action; 44415819a70SAndre Guedes 44515819a70SAndre Guedes bdaddr_t addr; 44615819a70SAndre Guedes u8 addr_type; 44715819a70SAndre Guedes 44815819a70SAndre Guedes u16 conn_min_interval; 44915819a70SAndre Guedes u16 conn_max_interval; 450f044eb05SMarcel Holtmann u16 conn_latency; 451f044eb05SMarcel Holtmann u16 supervision_timeout; 4529fcb18efSAndre Guedes 4539fcb18efSAndre Guedes enum { 4549fcb18efSAndre Guedes HCI_AUTO_CONN_DISABLED, 455a3451d27SJohan Hedberg HCI_AUTO_CONN_REPORT, 4569fcb18efSAndre Guedes HCI_AUTO_CONN_ALWAYS, 4579fcb18efSAndre Guedes HCI_AUTO_CONN_LINK_LOSS, 4589fcb18efSAndre Guedes } auto_connect; 45915819a70SAndre Guedes }; 46015819a70SAndre Guedes 4611da177e4SLinus Torvalds extern struct list_head hci_dev_list; 4621da177e4SLinus Torvalds extern struct list_head hci_cb_list; 4631da177e4SLinus Torvalds extern rwlock_t hci_dev_list_lock; 4641da177e4SLinus Torvalds extern rwlock_t hci_cb_list_lock; 4651da177e4SLinus Torvalds 466686ebf28SUlisses Furquim /* ----- HCI interface to upper protocols ----- */ 467e74e58f8SJoe Perches int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); 468e74e58f8SJoe Perches void l2cap_connect_cfm(struct hci_conn *hcon, u8 status); 469e74e58f8SJoe Perches int l2cap_disconn_ind(struct hci_conn *hcon); 470e74e58f8SJoe Perches void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason); 471e74e58f8SJoe Perches int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt); 472e74e58f8SJoe Perches int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags); 473686ebf28SUlisses Furquim 474e74e58f8SJoe Perches int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags); 475e74e58f8SJoe Perches void sco_connect_cfm(struct hci_conn *hcon, __u8 status); 476e74e58f8SJoe Perches void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason); 477e74e58f8SJoe Perches int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb); 478686ebf28SUlisses Furquim 4791da177e4SLinus Torvalds /* ----- Inquiry cache ----- */ 48070f23020SAndrei Emeltchenko #define INQUIRY_CACHE_AGE_MAX (HZ*30) /* 30 seconds */ 48170f23020SAndrei Emeltchenko #define INQUIRY_ENTRY_AGE_MAX (HZ*60) /* 60 seconds */ 4821da177e4SLinus Torvalds 48330883512SJohan Hedberg static inline void discovery_init(struct hci_dev *hdev) 4841da177e4SLinus Torvalds { 485ff9ef578SJohan Hedberg hdev->discovery.state = DISCOVERY_STOPPED; 48630883512SJohan Hedberg INIT_LIST_HEAD(&hdev->discovery.all); 48730883512SJohan Hedberg INIT_LIST_HEAD(&hdev->discovery.unknown); 48830883512SJohan Hedberg INIT_LIST_HEAD(&hdev->discovery.resolve); 4891da177e4SLinus Torvalds } 4901da177e4SLinus Torvalds 49130dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev); 49230dc78e1SJohan Hedberg 493ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state); 494ff9ef578SJohan Hedberg 4951da177e4SLinus Torvalds static inline int inquiry_cache_empty(struct hci_dev *hdev) 4961da177e4SLinus Torvalds { 49730883512SJohan Hedberg return list_empty(&hdev->discovery.all); 4981da177e4SLinus Torvalds } 4991da177e4SLinus Torvalds 5001da177e4SLinus Torvalds static inline long inquiry_cache_age(struct hci_dev *hdev) 5011da177e4SLinus Torvalds { 50230883512SJohan Hedberg struct discovery_state *c = &hdev->discovery; 5031da177e4SLinus Torvalds return jiffies - c->timestamp; 5041da177e4SLinus Torvalds } 5051da177e4SLinus Torvalds 5061da177e4SLinus Torvalds static inline long inquiry_entry_age(struct inquiry_entry *e) 5071da177e4SLinus Torvalds { 5081da177e4SLinus Torvalds return jiffies - e->timestamp; 5091da177e4SLinus Torvalds } 5101da177e4SLinus Torvalds 5115a9d0a3fSWaldemar Rymarkiewicz struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 5125a9d0a3fSWaldemar Rymarkiewicz bdaddr_t *bdaddr); 513561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 514561aafbcSJohan Hedberg bdaddr_t *bdaddr); 51530dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 51630dc78e1SJohan Hedberg bdaddr_t *bdaddr, 51730dc78e1SJohan Hedberg int state); 518a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 519a3d4e20aSJohan Hedberg struct inquiry_entry *ie); 520af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 521af58925cSMarcel Holtmann bool name_known); 5221f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev); 5231da177e4SLinus Torvalds 5241da177e4SLinus Torvalds /* ----- HCI Connections ----- */ 5251da177e4SLinus Torvalds enum { 5261da177e4SLinus Torvalds HCI_CONN_AUTH_PEND, 52719f8def0SWaldemar Rymarkiewicz HCI_CONN_REAUTH_PEND, 5281da177e4SLinus Torvalds HCI_CONN_ENCRYPT_PEND, 52904837f64SMarcel Holtmann HCI_CONN_RSWITCH_PEND, 53004837f64SMarcel Holtmann HCI_CONN_MODE_CHANGE_PEND, 531e73439d8SMarcel Holtmann HCI_CONN_SCO_SETUP_PEND, 532d26a2345SVinicius Costa Gomes HCI_CONN_LE_SMP_PEND, 533b644ba33SJohan Hedberg HCI_CONN_MGMT_CONNECTED, 53458a681efSJohan Hedberg HCI_CONN_SSP_ENABLED, 535eb9a8f3fSMarcel Holtmann HCI_CONN_SC_ENABLED, 536abf76badSMarcel Holtmann HCI_CONN_AES_CCM, 53758a681efSJohan Hedberg HCI_CONN_POWER_SAVE, 53858a681efSJohan Hedberg HCI_CONN_REMOTE_OOB, 539af6a9c32SJohan Hedberg HCI_CONN_FLUSH_KEY, 5404dae2798SJohan Hedberg HCI_CONN_MASTER, 5414dae2798SJohan Hedberg HCI_CONN_ENCRYPT, 5424dae2798SJohan Hedberg HCI_CONN_AUTH, 5434dae2798SJohan Hedberg HCI_CONN_SECURE, 5444dae2798SJohan Hedberg HCI_CONN_FIPS, 545fe59a05fSJohan Hedberg HCI_CONN_STK_ENCRYPT, 5461da177e4SLinus Torvalds }; 5471da177e4SLinus Torvalds 548aa64a8b5SJohan Hedberg static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) 549aa64a8b5SJohan Hedberg { 550aa64a8b5SJohan Hedberg struct hci_dev *hdev = conn->hdev; 551c3c7ea65SGustavo Padovan return test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && 552c3c7ea65SGustavo Padovan test_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 553aa64a8b5SJohan Hedberg } 554aa64a8b5SJohan Hedberg 555eb9a8f3fSMarcel Holtmann static inline bool hci_conn_sc_enabled(struct hci_conn *conn) 556eb9a8f3fSMarcel Holtmann { 557eb9a8f3fSMarcel Holtmann struct hci_dev *hdev = conn->hdev; 558eb9a8f3fSMarcel Holtmann return test_bit(HCI_SC_ENABLED, &hdev->dev_flags) && 559eb9a8f3fSMarcel Holtmann test_bit(HCI_CONN_SC_ENABLED, &conn->flags); 560eb9a8f3fSMarcel Holtmann } 561eb9a8f3fSMarcel Holtmann 5621da177e4SLinus Torvalds static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) 5631da177e4SLinus Torvalds { 5641da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 565bf4c6325SGustavo F. Padovan list_add_rcu(&c->list, &h->list); 566fcd89c09SVille Tervo switch (c->type) { 567fcd89c09SVille Tervo case ACL_LINK: 5681da177e4SLinus Torvalds h->acl_num++; 569fcd89c09SVille Tervo break; 570bd1eb66bSAndrei Emeltchenko case AMP_LINK: 571bd1eb66bSAndrei Emeltchenko h->amp_num++; 572bd1eb66bSAndrei Emeltchenko break; 573fcd89c09SVille Tervo case LE_LINK: 574fcd89c09SVille Tervo h->le_num++; 575fcd89c09SVille Tervo break; 576fcd89c09SVille Tervo case SCO_LINK: 577fcd89c09SVille Tervo case ESCO_LINK: 5781da177e4SLinus Torvalds h->sco_num++; 579fcd89c09SVille Tervo break; 580fcd89c09SVille Tervo } 5811da177e4SLinus Torvalds } 5821da177e4SLinus Torvalds 5831da177e4SLinus Torvalds static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) 5841da177e4SLinus Torvalds { 5851da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 586bf4c6325SGustavo F. Padovan 587bf4c6325SGustavo F. Padovan list_del_rcu(&c->list); 588bf4c6325SGustavo F. Padovan synchronize_rcu(); 589bf4c6325SGustavo F. Padovan 590fcd89c09SVille Tervo switch (c->type) { 591fcd89c09SVille Tervo case ACL_LINK: 5921da177e4SLinus Torvalds h->acl_num--; 593fcd89c09SVille Tervo break; 594bd1eb66bSAndrei Emeltchenko case AMP_LINK: 595bd1eb66bSAndrei Emeltchenko h->amp_num--; 596bd1eb66bSAndrei Emeltchenko break; 597fcd89c09SVille Tervo case LE_LINK: 598fcd89c09SVille Tervo h->le_num--; 599fcd89c09SVille Tervo break; 600fcd89c09SVille Tervo case SCO_LINK: 601fcd89c09SVille Tervo case ESCO_LINK: 6021da177e4SLinus Torvalds h->sco_num--; 603fcd89c09SVille Tervo break; 604fcd89c09SVille Tervo } 6051da177e4SLinus Torvalds } 6061da177e4SLinus Torvalds 60752087a79SLuiz Augusto von Dentz static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type) 60852087a79SLuiz Augusto von Dentz { 60952087a79SLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 61052087a79SLuiz Augusto von Dentz switch (type) { 61152087a79SLuiz Augusto von Dentz case ACL_LINK: 61252087a79SLuiz Augusto von Dentz return h->acl_num; 613bd1eb66bSAndrei Emeltchenko case AMP_LINK: 614bd1eb66bSAndrei Emeltchenko return h->amp_num; 61552087a79SLuiz Augusto von Dentz case LE_LINK: 61652087a79SLuiz Augusto von Dentz return h->le_num; 61752087a79SLuiz Augusto von Dentz case SCO_LINK: 61852087a79SLuiz Augusto von Dentz case ESCO_LINK: 61952087a79SLuiz Augusto von Dentz return h->sco_num; 62052087a79SLuiz Augusto von Dentz default: 62152087a79SLuiz Augusto von Dentz return 0; 62252087a79SLuiz Augusto von Dentz } 62352087a79SLuiz Augusto von Dentz } 62452087a79SLuiz Augusto von Dentz 625f4f07505SJohan Hedberg static inline unsigned int hci_conn_count(struct hci_dev *hdev) 626f4f07505SJohan Hedberg { 627f4f07505SJohan Hedberg struct hci_conn_hash *c = &hdev->conn_hash; 628f4f07505SJohan Hedberg 629f4f07505SJohan Hedberg return c->acl_num + c->amp_num + c->sco_num + c->le_num; 630f4f07505SJohan Hedberg } 631f4f07505SJohan Hedberg 6321da177e4SLinus Torvalds static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev, 6331da177e4SLinus Torvalds __u16 handle) 6341da177e4SLinus Torvalds { 6351da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 6361da177e4SLinus Torvalds struct hci_conn *c; 6371da177e4SLinus Torvalds 638bf4c6325SGustavo F. Padovan rcu_read_lock(); 639bf4c6325SGustavo F. Padovan 640bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 641bf4c6325SGustavo F. Padovan if (c->handle == handle) { 642bf4c6325SGustavo F. Padovan rcu_read_unlock(); 6431da177e4SLinus Torvalds return c; 6441da177e4SLinus Torvalds } 645bf4c6325SGustavo F. Padovan } 646bf4c6325SGustavo F. Padovan rcu_read_unlock(); 647bf4c6325SGustavo F. Padovan 6481da177e4SLinus Torvalds return NULL; 6491da177e4SLinus Torvalds } 6501da177e4SLinus Torvalds 6511da177e4SLinus Torvalds static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev, 6521da177e4SLinus Torvalds __u8 type, bdaddr_t *ba) 6531da177e4SLinus Torvalds { 6541da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 6551da177e4SLinus Torvalds struct hci_conn *c; 6561da177e4SLinus Torvalds 657bf4c6325SGustavo F. Padovan rcu_read_lock(); 658bf4c6325SGustavo F. Padovan 659bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 660bf4c6325SGustavo F. Padovan if (c->type == type && !bacmp(&c->dst, ba)) { 661bf4c6325SGustavo F. Padovan rcu_read_unlock(); 6621da177e4SLinus Torvalds return c; 6631da177e4SLinus Torvalds } 664bf4c6325SGustavo F. Padovan } 665bf4c6325SGustavo F. Padovan 666bf4c6325SGustavo F. Padovan rcu_read_unlock(); 667bf4c6325SGustavo F. Padovan 6681da177e4SLinus Torvalds return NULL; 6691da177e4SLinus Torvalds } 6701da177e4SLinus Torvalds 6714c67bc74SMarcel Holtmann static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev, 6724c67bc74SMarcel Holtmann __u8 type, __u16 state) 6734c67bc74SMarcel Holtmann { 6744c67bc74SMarcel Holtmann struct hci_conn_hash *h = &hdev->conn_hash; 6754c67bc74SMarcel Holtmann struct hci_conn *c; 6764c67bc74SMarcel Holtmann 677bf4c6325SGustavo F. Padovan rcu_read_lock(); 678bf4c6325SGustavo F. Padovan 679bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 680bf4c6325SGustavo F. Padovan if (c->type == type && c->state == state) { 681bf4c6325SGustavo F. Padovan rcu_read_unlock(); 6824c67bc74SMarcel Holtmann return c; 6834c67bc74SMarcel Holtmann } 684bf4c6325SGustavo F. Padovan } 685bf4c6325SGustavo F. Padovan 686bf4c6325SGustavo F. Padovan rcu_read_unlock(); 687bf4c6325SGustavo F. Padovan 6884c67bc74SMarcel Holtmann return NULL; 6894c67bc74SMarcel Holtmann } 6904c67bc74SMarcel Holtmann 691bed71748SAndre Guedes void hci_disconnect(struct hci_conn *conn, __u8 reason); 6922dea632fSFrédéric Dalleau bool hci_setup_sync(struct hci_conn *conn, __u16 handle); 693e73439d8SMarcel Holtmann void hci_sco_setup(struct hci_conn *conn, __u8 status); 6941da177e4SLinus Torvalds 6951da177e4SLinus Torvalds struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst); 6961da177e4SLinus Torvalds int hci_conn_del(struct hci_conn *conn); 6971da177e4SLinus Torvalds void hci_conn_hash_flush(struct hci_dev *hdev); 698a9de9248SMarcel Holtmann void hci_conn_check_pending(struct hci_dev *hdev); 6991da177e4SLinus Torvalds 70073d80debSLuiz Augusto von Dentz struct hci_chan *hci_chan_create(struct hci_conn *conn); 7019472007cSAndrei Emeltchenko void hci_chan_del(struct hci_chan *chan); 7022c33c06aSGustavo F. Padovan void hci_chan_list_flush(struct hci_conn *conn); 70342c4e53eSAndrei Emeltchenko struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle); 70473d80debSLuiz Augusto von Dentz 70504a6c589SAndre Guedes struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, 70604a6c589SAndre Guedes u8 dst_type, u8 sec_level, u8 auth_type); 70704a6c589SAndre Guedes struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, 70804a6c589SAndre Guedes u8 sec_level, u8 auth_type); 70910c62ddcSFrédéric Dalleau struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst, 71010c62ddcSFrédéric Dalleau __u16 setting); 711e7c29cb1SMarcel Holtmann int hci_conn_check_link_mode(struct hci_conn *conn); 712b3b1b061SWaldemar Rymarkiewicz int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level); 7130684e5f9SMarcel Holtmann int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type); 7141da177e4SLinus Torvalds int hci_conn_change_link_key(struct hci_conn *conn); 7158c1b2355SMarcel Holtmann int hci_conn_switch_role(struct hci_conn *conn, __u8 role); 7161da177e4SLinus Torvalds 71714b12d0bSJaikumar Ganesh void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); 7181da177e4SLinus Torvalds 71906c053fbSAndre Guedes void hci_le_conn_failed(struct hci_conn *conn, u8 status); 72006c053fbSAndre Guedes 7218d12356fSDavid Herrmann /* 7228d12356fSDavid Herrmann * hci_conn_get() and hci_conn_put() are used to control the life-time of an 7238d12356fSDavid Herrmann * "hci_conn" object. They do not guarantee that the hci_conn object is running, 7248d12356fSDavid Herrmann * working or anything else. They just guarantee that the object is available 7258d12356fSDavid Herrmann * and can be dereferenced. So you can use its locks, local variables and any 7268d12356fSDavid Herrmann * other constant data. 7278d12356fSDavid Herrmann * Before accessing runtime data, you _must_ lock the object and then check that 7288d12356fSDavid Herrmann * it is still running. As soon as you release the locks, the connection might 7298d12356fSDavid Herrmann * get dropped, though. 7308d12356fSDavid Herrmann * 7318d12356fSDavid Herrmann * On the other hand, hci_conn_hold() and hci_conn_drop() are used to control 7328d12356fSDavid Herrmann * how long the underlying connection is held. So every channel that runs on the 7338d12356fSDavid Herrmann * hci_conn object calls this to prevent the connection from disappearing. As 7348d12356fSDavid Herrmann * long as you hold a device, you must also guarantee that you have a valid 7358d12356fSDavid Herrmann * reference to the device via hci_conn_get() (or the initial reference from 7368d12356fSDavid Herrmann * hci_conn_add()). 7378d12356fSDavid Herrmann * The hold()/drop() ref-count is known to drop below 0 sometimes, which doesn't 7388d12356fSDavid Herrmann * break because nobody cares for that. But this means, we cannot use 7398d12356fSDavid Herrmann * _get()/_drop() in it, but require the caller to have a valid ref (FIXME). 7408d12356fSDavid Herrmann */ 7418d12356fSDavid Herrmann 7428d12356fSDavid Herrmann static inline void hci_conn_get(struct hci_conn *conn) 7438d12356fSDavid Herrmann { 7448d12356fSDavid Herrmann get_device(&conn->dev); 7458d12356fSDavid Herrmann } 7468d12356fSDavid Herrmann 7478d12356fSDavid Herrmann static inline void hci_conn_put(struct hci_conn *conn) 7488d12356fSDavid Herrmann { 7498d12356fSDavid Herrmann put_device(&conn->dev); 7508d12356fSDavid Herrmann } 7518d12356fSDavid Herrmann 7521da177e4SLinus Torvalds static inline void hci_conn_hold(struct hci_conn *conn) 7531da177e4SLinus Torvalds { 75471becf0cSAndrei Emeltchenko BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt)); 75538b3fef1SAndrei Emeltchenko 7561da177e4SLinus Torvalds atomic_inc(&conn->refcnt); 7572f304d1eSAndre Guedes cancel_delayed_work(&conn->disc_work); 7581da177e4SLinus Torvalds } 7591da177e4SLinus Torvalds 76076a68ba0SDavid Herrmann static inline void hci_conn_drop(struct hci_conn *conn) 7611da177e4SLinus Torvalds { 76271becf0cSAndrei Emeltchenko BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt)); 76338b3fef1SAndrei Emeltchenko 7641da177e4SLinus Torvalds if (atomic_dec_and_test(&conn->refcnt)) { 76504837f64SMarcel Holtmann unsigned long timeo; 766716e4ab5SAndrei Emeltchenko 767716e4ab5SAndrei Emeltchenko switch (conn->type) { 768716e4ab5SAndrei Emeltchenko case ACL_LINK: 769716e4ab5SAndrei Emeltchenko case LE_LINK: 770a74a84f6SJohan Hedberg cancel_delayed_work(&conn->idle_work); 7716ac59344SMarcel Holtmann if (conn->state == BT_CONNECTED) { 7725f246e89SAndrei Emeltchenko timeo = conn->disc_timeout; 77304837f64SMarcel Holtmann if (!conn->out) 774052b30b0SMarcel Holtmann timeo *= 2; 7755a9d0a3fSWaldemar Rymarkiewicz } else { 7766ac59344SMarcel Holtmann timeo = msecs_to_jiffies(10); 7775a9d0a3fSWaldemar Rymarkiewicz } 778716e4ab5SAndrei Emeltchenko break; 779716e4ab5SAndrei Emeltchenko 780716e4ab5SAndrei Emeltchenko case AMP_LINK: 781716e4ab5SAndrei Emeltchenko timeo = conn->disc_timeout; 782716e4ab5SAndrei Emeltchenko break; 783716e4ab5SAndrei Emeltchenko 784716e4ab5SAndrei Emeltchenko default: 78504837f64SMarcel Holtmann timeo = msecs_to_jiffies(10); 786716e4ab5SAndrei Emeltchenko break; 7875a9d0a3fSWaldemar Rymarkiewicz } 788716e4ab5SAndrei Emeltchenko 7892f304d1eSAndre Guedes cancel_delayed_work(&conn->disc_work); 79019c40e3bSGustavo F. Padovan queue_delayed_work(conn->hdev->workqueue, 7911931782bSVinicius Costa Gomes &conn->disc_work, timeo); 7921da177e4SLinus Torvalds } 7931da177e4SLinus Torvalds } 7941da177e4SLinus Torvalds 7951da177e4SLinus Torvalds /* ----- HCI Devices ----- */ 796dc946bd8SDavid Herrmann static inline void hci_dev_put(struct hci_dev *d) 7971da177e4SLinus Torvalds { 798376261aeSAndrei Emeltchenko BT_DBG("%s orig refcnt %d", d->name, 799376261aeSAndrei Emeltchenko atomic_read(&d->dev.kobj.kref.refcount)); 800376261aeSAndrei Emeltchenko 8014c724c71SDavid Herrmann put_device(&d->dev); 802010666a1SDavid Herrmann } 8031da177e4SLinus Torvalds 804dc946bd8SDavid Herrmann static inline struct hci_dev *hci_dev_hold(struct hci_dev *d) 8051da177e4SLinus Torvalds { 806376261aeSAndrei Emeltchenko BT_DBG("%s orig refcnt %d", d->name, 807376261aeSAndrei Emeltchenko atomic_read(&d->dev.kobj.kref.refcount)); 808376261aeSAndrei Emeltchenko 8094c724c71SDavid Herrmann get_device(&d->dev); 8101da177e4SLinus Torvalds return d; 8111da177e4SLinus Torvalds } 8121da177e4SLinus Torvalds 81309fd0de5SGustavo F. Padovan #define hci_dev_lock(d) mutex_lock(&d->lock) 81409fd0de5SGustavo F. Padovan #define hci_dev_unlock(d) mutex_unlock(&d->lock) 8151da177e4SLinus Torvalds 816aa2b86d7SDavid Herrmann #define to_hci_dev(d) container_of(d, struct hci_dev, dev) 8173dc07322SDavid Herrmann #define to_hci_conn(c) container_of(c, struct hci_conn, dev) 818aa2b86d7SDavid Herrmann 819155961e8SDavid Herrmann static inline void *hci_get_drvdata(struct hci_dev *hdev) 820155961e8SDavid Herrmann { 821155961e8SDavid Herrmann return dev_get_drvdata(&hdev->dev); 822155961e8SDavid Herrmann } 823155961e8SDavid Herrmann 824155961e8SDavid Herrmann static inline void hci_set_drvdata(struct hci_dev *hdev, void *data) 825155961e8SDavid Herrmann { 826155961e8SDavid Herrmann dev_set_drvdata(&hdev->dev, data); 827155961e8SDavid Herrmann } 828155961e8SDavid Herrmann 8291da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index); 8300c0afedfSJohan Hedberg struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src); 8311da177e4SLinus Torvalds 8321da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void); 8331da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev); 8341da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev); 83559735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev); 8361da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev); 8371da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev); 8381da177e4SLinus Torvalds int hci_dev_open(__u16 dev); 8391da177e4SLinus Torvalds int hci_dev_close(__u16 dev); 8401da177e4SLinus Torvalds int hci_dev_reset(__u16 dev); 8411da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev); 8421da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg); 8431da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg); 8441da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg); 8451da177e4SLinus Torvalds int hci_get_conn_list(void __user *arg); 8461da177e4SLinus Torvalds int hci_get_conn_info(struct hci_dev *hdev, void __user *arg); 84740be492fSMarcel Holtmann int hci_get_auth_info(struct hci_dev *hdev, void __user *arg); 8481da177e4SLinus Torvalds int hci_inquiry(void __user *arg); 8491da177e4SLinus Torvalds 850c3c7ea65SGustavo Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, 851b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type); 85288c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); 85388c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); 854f0358568SJohan Hedberg 855d2ab0ac1SMarcel Holtmann struct bdaddr_list *hci_white_list_lookup(struct hci_dev *hdev, 856d2ab0ac1SMarcel Holtmann bdaddr_t *bdaddr, u8 type); 857d2ab0ac1SMarcel Holtmann void hci_white_list_clear(struct hci_dev *hdev); 858d2ab0ac1SMarcel Holtmann int hci_white_list_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); 859d2ab0ac1SMarcel Holtmann int hci_white_list_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); 860d2ab0ac1SMarcel Holtmann 86115819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 86215819a70SAndre Guedes bdaddr_t *addr, u8 addr_type); 86351d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, 86451d167c0SMarcel Holtmann bdaddr_t *addr, u8 addr_type); 865bf5b3c8bSMarcel Holtmann int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, 866d06b50ceSMarcel Holtmann u8 auto_connect); 86715819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type); 868373110c5SJohan Hedberg void hci_conn_params_clear_all(struct hci_dev *hdev); 86955af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev); 87055af49a8SJohan Hedberg void hci_conn_params_clear_enabled(struct hci_dev *hdev); 87115819a70SAndre Guedes 872501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, 873501f8827SJohan Hedberg bdaddr_t *addr, 874501f8827SJohan Hedberg u8 addr_type); 87577a77a30SAndre Guedes 876a4790dbdSAndre Guedes void hci_update_background_scan(struct hci_dev *hdev); 877a4790dbdSAndre Guedes 87835f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev); 8792aeb9a1aSJohan Hedberg 88035f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev); 88155ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); 882567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, 8837652ff6aSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, 8847652ff6aSJohan Hedberg u8 pin_len, bool *persistent); 885fe39c7b2SMarcel Holtmann struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand, 88698a0b845SJohan Hedberg bool master); 887ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 88835d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 889fe39c7b2SMarcel Holtmann u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand); 890c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 89198a0b845SJohan Hedberg u8 addr_type, bool master); 892e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type); 89335f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev); 89455ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); 89555ed8ca1SJohan Hedberg 896970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa); 897970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 898970c4e46SJohan Hedberg u8 addr_type); 899ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 900ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa); 901a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type); 902970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev); 903970c4e46SJohan Hedberg 90435f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev); 9052763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 9062763eda6SSzymon Janc bdaddr_t *bdaddr); 9070798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 9080798872eSMarcel Holtmann u8 *hash, u8 *randomizer); 9090798872eSMarcel Holtmann int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 9100798872eSMarcel Holtmann u8 *hash192, u8 *randomizer192, 9110798872eSMarcel Holtmann u8 *hash256, u8 *randomizer256); 9122763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); 9132763eda6SSzymon Janc 9141da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); 9151da177e4SLinus Torvalds 916e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb); 917ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); 91899811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count); 919ef222013SMarcel Holtmann 9200ac7e700SDavid Herrmann void hci_init_sysfs(struct hci_dev *hdev); 921a67e899cSMarcel Holtmann void hci_conn_init_sysfs(struct hci_conn *conn); 922b219e3acSMarcel Holtmann void hci_conn_add_sysfs(struct hci_conn *conn); 923b219e3acSMarcel Holtmann void hci_conn_del_sysfs(struct hci_conn *conn); 9241da177e4SLinus Torvalds 9256935e0f5SDavid Herrmann #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev)) 9261da177e4SLinus Torvalds 9271da177e4SLinus Torvalds /* ----- LMP capabilities ----- */ 928cad718edSJohan Hedberg #define lmp_encrypt_capable(dev) ((dev)->features[0][0] & LMP_ENCRYPT) 929cad718edSJohan Hedberg #define lmp_rswitch_capable(dev) ((dev)->features[0][0] & LMP_RSWITCH) 930cad718edSJohan Hedberg #define lmp_hold_capable(dev) ((dev)->features[0][0] & LMP_HOLD) 931cad718edSJohan Hedberg #define lmp_sniff_capable(dev) ((dev)->features[0][0] & LMP_SNIFF) 932cad718edSJohan Hedberg #define lmp_park_capable(dev) ((dev)->features[0][1] & LMP_PARK) 933cad718edSJohan Hedberg #define lmp_inq_rssi_capable(dev) ((dev)->features[0][3] & LMP_RSSI_INQ) 934cad718edSJohan Hedberg #define lmp_esco_capable(dev) ((dev)->features[0][3] & LMP_ESCO) 935cad718edSJohan Hedberg #define lmp_bredr_capable(dev) (!((dev)->features[0][4] & LMP_NO_BREDR)) 936cad718edSJohan Hedberg #define lmp_le_capable(dev) ((dev)->features[0][4] & LMP_LE) 937cad718edSJohan Hedberg #define lmp_sniffsubr_capable(dev) ((dev)->features[0][5] & LMP_SNIFF_SUBR) 938cad718edSJohan Hedberg #define lmp_pause_enc_capable(dev) ((dev)->features[0][5] & LMP_PAUSE_ENC) 939cad718edSJohan Hedberg #define lmp_ext_inq_capable(dev) ((dev)->features[0][6] & LMP_EXT_INQ) 940cad718edSJohan Hedberg #define lmp_le_br_capable(dev) (!!((dev)->features[0][6] & LMP_SIMUL_LE_BR)) 941cad718edSJohan Hedberg #define lmp_ssp_capable(dev) ((dev)->features[0][6] & LMP_SIMPLE_PAIR) 942cad718edSJohan Hedberg #define lmp_no_flush_capable(dev) ((dev)->features[0][6] & LMP_NO_FLUSH) 943cad718edSJohan Hedberg #define lmp_lsto_capable(dev) ((dev)->features[0][7] & LMP_LSTO) 944cad718edSJohan Hedberg #define lmp_inq_tx_pwr_capable(dev) ((dev)->features[0][7] & LMP_INQ_TX_PWR) 945cad718edSJohan Hedberg #define lmp_ext_feat_capable(dev) ((dev)->features[0][7] & LMP_EXTFEATURES) 94607a5c61eSFrédéric Dalleau #define lmp_transp_capable(dev) ((dev)->features[0][2] & LMP_TRANSPARENT) 9471da177e4SLinus Torvalds 948eead27daSAndre Guedes /* ----- Extended LMP capabilities ----- */ 94953b834d2SMarcel Holtmann #define lmp_csb_master_capable(dev) ((dev)->features[2][0] & LMP_CSB_MASTER) 95053b834d2SMarcel Holtmann #define lmp_csb_slave_capable(dev) ((dev)->features[2][0] & LMP_CSB_SLAVE) 95153b834d2SMarcel Holtmann #define lmp_sync_train_capable(dev) ((dev)->features[2][0] & LMP_SYNC_TRAIN) 95253b834d2SMarcel Holtmann #define lmp_sync_scan_capable(dev) ((dev)->features[2][0] & LMP_SYNC_SCAN) 953d5991585SMarcel Holtmann #define lmp_sc_capable(dev) ((dev)->features[2][1] & LMP_SC) 954d5991585SMarcel Holtmann #define lmp_ping_capable(dev) ((dev)->features[2][1] & LMP_PING) 95553b834d2SMarcel Holtmann 95653b834d2SMarcel Holtmann /* ----- Host capabilities ----- */ 957cad718edSJohan Hedberg #define lmp_host_ssp_capable(dev) ((dev)->features[1][0] & LMP_HOST_SSP) 958d5991585SMarcel Holtmann #define lmp_host_sc_capable(dev) ((dev)->features[1][0] & LMP_HOST_SC) 959cad718edSJohan Hedberg #define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE)) 960cad718edSJohan Hedberg #define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR)) 961eead27daSAndre Guedes 9621da177e4SLinus Torvalds /* ----- HCI protocols ----- */ 96320714bfeSFrédéric Dalleau #define HCI_PROTO_DEFER 0x01 96420714bfeSFrédéric Dalleau 9655a9d0a3fSWaldemar Rymarkiewicz static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, 96620714bfeSFrédéric Dalleau __u8 type, __u8 *flags) 9671da177e4SLinus Torvalds { 968686ebf28SUlisses Furquim switch (type) { 969686ebf28SUlisses Furquim case ACL_LINK: 970686ebf28SUlisses Furquim return l2cap_connect_ind(hdev, bdaddr); 9711da177e4SLinus Torvalds 972686ebf28SUlisses Furquim case SCO_LINK: 973686ebf28SUlisses Furquim case ESCO_LINK: 97420714bfeSFrédéric Dalleau return sco_connect_ind(hdev, bdaddr, flags); 9751da177e4SLinus Torvalds 976686ebf28SUlisses Furquim default: 977686ebf28SUlisses Furquim BT_ERR("unknown link type %d", type); 978686ebf28SUlisses Furquim return -EINVAL; 979686ebf28SUlisses Furquim } 9801da177e4SLinus Torvalds } 9811da177e4SLinus Torvalds 9821da177e4SLinus Torvalds static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status) 9831da177e4SLinus Torvalds { 984686ebf28SUlisses Furquim switch (conn->type) { 985686ebf28SUlisses Furquim case ACL_LINK: 986686ebf28SUlisses Furquim case LE_LINK: 987686ebf28SUlisses Furquim l2cap_connect_cfm(conn, status); 988686ebf28SUlisses Furquim break; 9891da177e4SLinus Torvalds 990686ebf28SUlisses Furquim case SCO_LINK: 991686ebf28SUlisses Furquim case ESCO_LINK: 992686ebf28SUlisses Furquim sco_connect_cfm(conn, status); 993686ebf28SUlisses Furquim break; 9941da177e4SLinus Torvalds 995686ebf28SUlisses Furquim default: 996686ebf28SUlisses Furquim BT_ERR("unknown link type %d", conn->type); 997686ebf28SUlisses Furquim break; 998686ebf28SUlisses Furquim } 999e9a416b5SJohan Hedberg 1000e9a416b5SJohan Hedberg if (conn->connect_cfm_cb) 1001e9a416b5SJohan Hedberg conn->connect_cfm_cb(conn, status); 10021da177e4SLinus Torvalds } 10031da177e4SLinus Torvalds 10042950f21aSMarcel Holtmann static inline int hci_proto_disconn_ind(struct hci_conn *conn) 10052950f21aSMarcel Holtmann { 1006686ebf28SUlisses Furquim if (conn->type != ACL_LINK && conn->type != LE_LINK) 1007686ebf28SUlisses Furquim return HCI_ERROR_REMOTE_USER_TERM; 10082950f21aSMarcel Holtmann 1009686ebf28SUlisses Furquim return l2cap_disconn_ind(conn); 10102950f21aSMarcel Holtmann } 10112950f21aSMarcel Holtmann 10122950f21aSMarcel Holtmann static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason) 10131da177e4SLinus Torvalds { 1014686ebf28SUlisses Furquim switch (conn->type) { 1015686ebf28SUlisses Furquim case ACL_LINK: 1016686ebf28SUlisses Furquim case LE_LINK: 1017686ebf28SUlisses Furquim l2cap_disconn_cfm(conn, reason); 1018686ebf28SUlisses Furquim break; 10191da177e4SLinus Torvalds 1020686ebf28SUlisses Furquim case SCO_LINK: 1021686ebf28SUlisses Furquim case ESCO_LINK: 1022686ebf28SUlisses Furquim sco_disconn_cfm(conn, reason); 1023686ebf28SUlisses Furquim break; 10241da177e4SLinus Torvalds 1025bd1eb66bSAndrei Emeltchenko /* L2CAP would be handled for BREDR chan */ 1026bd1eb66bSAndrei Emeltchenko case AMP_LINK: 1027bd1eb66bSAndrei Emeltchenko break; 1028bd1eb66bSAndrei Emeltchenko 1029686ebf28SUlisses Furquim default: 1030686ebf28SUlisses Furquim BT_ERR("unknown link type %d", conn->type); 1031686ebf28SUlisses Furquim break; 1032686ebf28SUlisses Furquim } 1033e9a416b5SJohan Hedberg 1034e9a416b5SJohan Hedberg if (conn->disconn_cfm_cb) 1035e9a416b5SJohan Hedberg conn->disconn_cfm_cb(conn, reason); 10361da177e4SLinus Torvalds } 10371da177e4SLinus Torvalds 10381da177e4SLinus Torvalds static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) 10391da177e4SLinus Torvalds { 10408c1b2355SMarcel Holtmann __u8 encrypt; 10418c1b2355SMarcel Holtmann 1042686ebf28SUlisses Furquim if (conn->type != ACL_LINK && conn->type != LE_LINK) 1043686ebf28SUlisses Furquim return; 1044686ebf28SUlisses Furquim 104551a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) 10468c1b2355SMarcel Holtmann return; 10478c1b2355SMarcel Holtmann 10484dae2798SJohan Hedberg encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00; 1049686ebf28SUlisses Furquim l2cap_security_cfm(conn, status, encrypt); 1050e9a416b5SJohan Hedberg 1051e9a416b5SJohan Hedberg if (conn->security_cfm_cb) 1052e9a416b5SJohan Hedberg conn->security_cfm_cb(conn, status); 10531da177e4SLinus Torvalds } 10541da177e4SLinus Torvalds 10555a9d0a3fSWaldemar Rymarkiewicz static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, 10565a9d0a3fSWaldemar Rymarkiewicz __u8 encrypt) 10571da177e4SLinus Torvalds { 1058686ebf28SUlisses Furquim if (conn->type != ACL_LINK && conn->type != LE_LINK) 1059686ebf28SUlisses Furquim return; 10601da177e4SLinus Torvalds 1061686ebf28SUlisses Furquim l2cap_security_cfm(conn, status, encrypt); 1062e9a416b5SJohan Hedberg 1063e9a416b5SJohan Hedberg if (conn->security_cfm_cb) 1064e9a416b5SJohan Hedberg conn->security_cfm_cb(conn, status); 10651da177e4SLinus Torvalds } 10661da177e4SLinus Torvalds 10671da177e4SLinus Torvalds /* ----- HCI callbacks ----- */ 10681da177e4SLinus Torvalds struct hci_cb { 10691da177e4SLinus Torvalds struct list_head list; 10701da177e4SLinus Torvalds 10711da177e4SLinus Torvalds char *name; 10721da177e4SLinus Torvalds 10735a9d0a3fSWaldemar Rymarkiewicz void (*security_cfm) (struct hci_conn *conn, __u8 status, 10745a9d0a3fSWaldemar Rymarkiewicz __u8 encrypt); 10751da177e4SLinus Torvalds void (*key_change_cfm) (struct hci_conn *conn, __u8 status); 10761da177e4SLinus Torvalds void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role); 10771da177e4SLinus Torvalds }; 10781da177e4SLinus Torvalds 10791da177e4SLinus Torvalds static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) 10801da177e4SLinus Torvalds { 1081711584eaSDenis Kirjanov struct hci_cb *cb; 10828c1b2355SMarcel Holtmann __u8 encrypt; 10831da177e4SLinus Torvalds 10841da177e4SLinus Torvalds hci_proto_auth_cfm(conn, status); 10851da177e4SLinus Torvalds 108651a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) 10878c1b2355SMarcel Holtmann return; 10888c1b2355SMarcel Holtmann 10894dae2798SJohan Hedberg encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00; 10908c1b2355SMarcel Holtmann 1091f20d09d5SGustavo F. Padovan read_lock(&hci_cb_list_lock); 1092711584eaSDenis Kirjanov list_for_each_entry(cb, &hci_cb_list, list) { 10938c1b2355SMarcel Holtmann if (cb->security_cfm) 10948c1b2355SMarcel Holtmann cb->security_cfm(conn, status, encrypt); 10951da177e4SLinus Torvalds } 1096f20d09d5SGustavo F. Padovan read_unlock(&hci_cb_list_lock); 10971da177e4SLinus Torvalds } 10981da177e4SLinus Torvalds 10995a9d0a3fSWaldemar Rymarkiewicz static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, 11005a9d0a3fSWaldemar Rymarkiewicz __u8 encrypt) 11011da177e4SLinus Torvalds { 1102711584eaSDenis Kirjanov struct hci_cb *cb; 11031da177e4SLinus Torvalds 1104435fef20SMarcel Holtmann if (conn->sec_level == BT_SECURITY_SDP) 1105435fef20SMarcel Holtmann conn->sec_level = BT_SECURITY_LOW; 1106435fef20SMarcel Holtmann 110788167aedSVinicius Costa Gomes if (conn->pending_sec_level > conn->sec_level) 110888167aedSVinicius Costa Gomes conn->sec_level = conn->pending_sec_level; 110988167aedSVinicius Costa Gomes 11109719f8afSMarcel Holtmann hci_proto_encrypt_cfm(conn, status, encrypt); 11111da177e4SLinus Torvalds 1112f20d09d5SGustavo F. Padovan read_lock(&hci_cb_list_lock); 1113711584eaSDenis Kirjanov list_for_each_entry(cb, &hci_cb_list, list) { 11148c1b2355SMarcel Holtmann if (cb->security_cfm) 11158c1b2355SMarcel Holtmann cb->security_cfm(conn, status, encrypt); 11161da177e4SLinus Torvalds } 1117f20d09d5SGustavo F. Padovan read_unlock(&hci_cb_list_lock); 11181da177e4SLinus Torvalds } 11191da177e4SLinus Torvalds 11201da177e4SLinus Torvalds static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) 11211da177e4SLinus Torvalds { 1122711584eaSDenis Kirjanov struct hci_cb *cb; 11231da177e4SLinus Torvalds 1124f20d09d5SGustavo F. Padovan read_lock(&hci_cb_list_lock); 1125711584eaSDenis Kirjanov list_for_each_entry(cb, &hci_cb_list, list) { 11261da177e4SLinus Torvalds if (cb->key_change_cfm) 11271da177e4SLinus Torvalds cb->key_change_cfm(conn, status); 11281da177e4SLinus Torvalds } 1129f20d09d5SGustavo F. Padovan read_unlock(&hci_cb_list_lock); 11301da177e4SLinus Torvalds } 11311da177e4SLinus Torvalds 11325a9d0a3fSWaldemar Rymarkiewicz static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, 11335a9d0a3fSWaldemar Rymarkiewicz __u8 role) 11341da177e4SLinus Torvalds { 1135711584eaSDenis Kirjanov struct hci_cb *cb; 11361da177e4SLinus Torvalds 1137f20d09d5SGustavo F. Padovan read_lock(&hci_cb_list_lock); 1138711584eaSDenis Kirjanov list_for_each_entry(cb, &hci_cb_list, list) { 11391da177e4SLinus Torvalds if (cb->role_switch_cfm) 11401da177e4SLinus Torvalds cb->role_switch_cfm(conn, status, role); 11411da177e4SLinus Torvalds } 1142f20d09d5SGustavo F. Padovan read_unlock(&hci_cb_list_lock); 11431da177e4SLinus Torvalds } 11441da177e4SLinus Torvalds 11456759a675SJohan Hedberg static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type) 11466759a675SJohan Hedberg { 114784d9d071SJohan Hedberg size_t parsed = 0; 11486759a675SJohan Hedberg 11496c0c331eSJohan Hedberg if (data_len < 2) 11506c0c331eSJohan Hedberg return false; 11516c0c331eSJohan Hedberg 115284d9d071SJohan Hedberg while (parsed < data_len - 1) { 115384d9d071SJohan Hedberg u8 field_len = data[0]; 11546759a675SJohan Hedberg 11556759a675SJohan Hedberg if (field_len == 0) 11566759a675SJohan Hedberg break; 11576759a675SJohan Hedberg 11586759a675SJohan Hedberg parsed += field_len + 1; 11596759a675SJohan Hedberg 11606759a675SJohan Hedberg if (parsed > data_len) 11616759a675SJohan Hedberg break; 11626759a675SJohan Hedberg 11636759a675SJohan Hedberg if (data[1] == type) 11646759a675SJohan Hedberg return true; 11656759a675SJohan Hedberg 11666759a675SJohan Hedberg data += field_len + 1; 11676759a675SJohan Hedberg } 11686759a675SJohan Hedberg 11696759a675SJohan Hedberg return false; 11706759a675SJohan Hedberg } 11716759a675SJohan Hedberg 1172301cb2d8SJohan Hedberg static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type) 1173301cb2d8SJohan Hedberg { 1174dbbfa2abSAndre Guedes if (addr_type != ADDR_LE_DEV_RANDOM) 1175301cb2d8SJohan Hedberg return false; 1176301cb2d8SJohan Hedberg 1177301cb2d8SJohan Hedberg if ((bdaddr->b[5] & 0xc0) == 0x40) 1178301cb2d8SJohan Hedberg return true; 1179301cb2d8SJohan Hedberg 1180301cb2d8SJohan Hedberg return false; 1181301cb2d8SJohan Hedberg } 1182301cb2d8SJohan Hedberg 1183c46245b3SJohan Hedberg static inline bool hci_is_identity_address(bdaddr_t *addr, u8 addr_type) 1184c46245b3SJohan Hedberg { 1185c46245b3SJohan Hedberg if (addr_type == ADDR_LE_DEV_PUBLIC) 1186c46245b3SJohan Hedberg return true; 1187c46245b3SJohan Hedberg 1188c46245b3SJohan Hedberg /* Check for Random Static address type */ 1189c46245b3SJohan Hedberg if ((addr->b[5] & 0xc0) == 0xc0) 1190c46245b3SJohan Hedberg return true; 1191c46245b3SJohan Hedberg 1192c46245b3SJohan Hedberg return false; 1193c46245b3SJohan Hedberg } 1194c46245b3SJohan Hedberg 11952426f3a5SJohan Hedberg static inline struct smp_irk *hci_get_irk(struct hci_dev *hdev, 11962426f3a5SJohan Hedberg bdaddr_t *bdaddr, u8 addr_type) 11972426f3a5SJohan Hedberg { 11982426f3a5SJohan Hedberg if (!hci_bdaddr_is_rpa(bdaddr, addr_type)) 11992426f3a5SJohan Hedberg return NULL; 12002426f3a5SJohan Hedberg 12012426f3a5SJohan Hedberg return hci_find_irk_by_rpa(hdev, bdaddr); 12022426f3a5SJohan Hedberg } 12032426f3a5SJohan Hedberg 1204d4905f24SAndre Guedes static inline int hci_check_conn_params(u16 min, u16 max, u16 latency, 1205d4905f24SAndre Guedes u16 to_multiplier) 1206d4905f24SAndre Guedes { 1207d4905f24SAndre Guedes u16 max_latency; 1208d4905f24SAndre Guedes 1209d4905f24SAndre Guedes if (min > max || min < 6 || max > 3200) 1210d4905f24SAndre Guedes return -EINVAL; 1211d4905f24SAndre Guedes 1212d4905f24SAndre Guedes if (to_multiplier < 10 || to_multiplier > 3200) 1213d4905f24SAndre Guedes return -EINVAL; 1214d4905f24SAndre Guedes 1215d4905f24SAndre Guedes if (max >= to_multiplier * 8) 1216d4905f24SAndre Guedes return -EINVAL; 1217d4905f24SAndre Guedes 1218d4905f24SAndre Guedes max_latency = (to_multiplier * 8 / max) - 1; 1219d4905f24SAndre Guedes if (latency > 499 || latency > max_latency) 1220d4905f24SAndre Guedes return -EINVAL; 1221d4905f24SAndre Guedes 1222d4905f24SAndre Guedes return 0; 1223d4905f24SAndre Guedes } 1224d4905f24SAndre Guedes 12251da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *hcb); 12261da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *hcb); 12271da177e4SLinus Torvalds 12283119ae95SJohan Hedberg struct hci_request { 12293119ae95SJohan Hedberg struct hci_dev *hdev; 12303119ae95SJohan Hedberg struct sk_buff_head cmd_q; 12315d73e034SAndre Guedes 12325d73e034SAndre Guedes /* If something goes wrong when building the HCI request, the error 12335d73e034SAndre Guedes * value is stored in this field. 12345d73e034SAndre Guedes */ 12355d73e034SAndre Guedes int err; 12363119ae95SJohan Hedberg }; 12373119ae95SJohan Hedberg 12383119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev); 12393119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete); 124007dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, 124107dc93ddSJohan Hedberg const void *param); 124207dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, 124307dc93ddSJohan Hedberg const void *param, u8 event); 12449238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); 12453119ae95SJohan Hedberg 1246b1efcc28SAndre Guedes void hci_req_add_le_scan_disable(struct hci_request *req); 12478ef30fd3SAndre Guedes void hci_req_add_le_passive_scan(struct hci_request *req); 1248b1efcc28SAndre Guedes 124975e84b7cSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 125007dc93ddSJohan Hedberg const void *param, u32 timeout); 12517b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 125207dc93ddSJohan Hedberg const void *param, u8 event, u32 timeout); 125375e84b7cSJohan Hedberg 125407dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 125507dc93ddSJohan Hedberg const void *param); 125673d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); 12570d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); 12581da177e4SLinus Torvalds 1259a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); 12601da177e4SLinus Torvalds 12611da177e4SLinus Torvalds /* ----- HCI Sockets ----- */ 1262470fe1b5SMarcel Holtmann void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); 1263470fe1b5SMarcel Holtmann void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk); 1264cd82e61cSMarcel Holtmann void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb); 12651da177e4SLinus Torvalds 1266040030efSMarcel Holtmann void hci_sock_dev_event(struct hci_dev *hdev, int event); 1267040030efSMarcel Holtmann 12680381101fSJohan Hedberg /* Management interface */ 1269591f47f3SAndre Guedes #define DISCOV_TYPE_BREDR (BIT(BDADDR_BREDR)) 1270591f47f3SAndre Guedes #define DISCOV_TYPE_LE (BIT(BDADDR_LE_PUBLIC) | \ 1271591f47f3SAndre Guedes BIT(BDADDR_LE_RANDOM)) 1272591f47f3SAndre Guedes #define DISCOV_TYPE_INTERLEAVED (BIT(BDADDR_BREDR) | \ 1273591f47f3SAndre Guedes BIT(BDADDR_LE_PUBLIC) | \ 1274591f47f3SAndre Guedes BIT(BDADDR_LE_RANDOM)) 1275f39799f5SAndre Guedes 12760d8cc935SAndre Guedes /* These LE scan and inquiry parameters were chosen according to LE General 12770d8cc935SAndre Guedes * Discovery Procedure specification. 12780d8cc935SAndre Guedes */ 12790d8cc935SAndre Guedes #define DISCOV_LE_SCAN_WIN 0x12 12800d8cc935SAndre Guedes #define DISCOV_LE_SCAN_INT 0x12 12813d5a76f0SLukasz Rymanowski #define DISCOV_LE_TIMEOUT 10240 /* msec */ 1282ae55f598SLukasz Rymanowski #define DISCOV_INTERLEAVED_TIMEOUT 5120 /* msec */ 12830d8cc935SAndre Guedes #define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04 12840d8cc935SAndre Guedes #define DISCOV_BREDR_INQUIRY_LEN 0x08 12850d8cc935SAndre Guedes 12860381101fSJohan Hedberg int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); 1287bf6b56dbSMarcel Holtmann void mgmt_index_added(struct hci_dev *hdev); 1288bf6b56dbSMarcel Holtmann void mgmt_index_removed(struct hci_dev *hdev); 12893eec705eSMarcel Holtmann void mgmt_set_powered_failed(struct hci_dev *hdev, int err); 1290744cf19eSJohan Hedberg int mgmt_powered(struct hci_dev *hdev, u8 powered); 1291d1967ff8SMarcel Holtmann void mgmt_discoverable_timeout(struct hci_dev *hdev); 129286a75645SMarcel Holtmann void mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); 1293a330916cSMarcel Holtmann void mgmt_connectable(struct hci_dev *hdev, u8 connectable); 1294778b235aSJohan Hedberg void mgmt_advertising(struct hci_dev *hdev, u8 advertising); 12954796e8afSMarcel Holtmann void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status); 1296dc4a5ee2SMarcel Holtmann void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, 1297745c0ce3SVishal Agarwal bool persistent); 1298ecd90ae7SMarcel Holtmann void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 129904124681SGustavo F. Padovan u8 addr_type, u32 flags, u8 *name, u8 name_len, 130004124681SGustavo F. Padovan u8 *dev_class); 13019b80ec5eSMarcel Holtmann void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, 130212d4a3b2SJohan Hedberg u8 link_type, u8 addr_type, u8 reason, 130312d4a3b2SJohan Hedberg bool mgmt_connected); 13047892924cSMarcel Holtmann void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, 130588c3df13SJohan Hedberg u8 link_type, u8 addr_type, u8 status); 1306445608d0SMarcel Holtmann void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 130748264f06SJohan Hedberg u8 addr_type, u8 status); 1308ce0e4a0dSMarcel Holtmann void mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure); 1309e669cf80SMarcel Holtmann void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1310c35938b2SSzymon Janc u8 status); 13113eb38528SMarcel Holtmann void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1312744cf19eSJohan Hedberg u8 status); 1313744cf19eSJohan Hedberg int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, 131439adbffeSJohan Hedberg u8 link_type, u8 addr_type, u32 value, 1315272d90dfSJohan Hedberg u8 confirm_hint); 1316744cf19eSJohan Hedberg int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1317272d90dfSJohan Hedberg u8 link_type, u8 addr_type, u8 status); 1318272d90dfSJohan Hedberg int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1319272d90dfSJohan Hedberg u8 link_type, u8 addr_type, u8 status); 1320272d90dfSJohan Hedberg int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr, 1321272d90dfSJohan Hedberg u8 link_type, u8 addr_type); 1322604086b7SBrian Gix int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1323272d90dfSJohan Hedberg u8 link_type, u8 addr_type, u8 status); 1324272d90dfSJohan Hedberg int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1325272d90dfSJohan Hedberg u8 link_type, u8 addr_type, u8 status); 132692a25256SJohan Hedberg int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr, 132792a25256SJohan Hedberg u8 link_type, u8 addr_type, u32 passkey, 132892a25256SJohan Hedberg u8 entered); 1329e546099cSMarcel Holtmann void mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 1330bab73cb6SJohan Hedberg u8 addr_type, u8 status); 1331464996aeSMarcel Holtmann void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status); 13323e248560SMarcel Holtmann void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); 1333eac83dc6SMarcel Holtmann void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); 13344e1b0245SMarcel Holtmann void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, 13357f9a903cSMarcel Holtmann u8 status); 13367667da34SMarcel Holtmann void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status); 13374d2d2796SMarcel Holtmann void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, 13384d2d2796SMarcel Holtmann u8 *randomizer192, u8 *hash256, 13394d2d2796SMarcel Holtmann u8 *randomizer256, u8 status); 1340901801b9SMarcel Holtmann void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 1341af58925cSMarcel Holtmann u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, 1342af58925cSMarcel Holtmann u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len); 13439cf12aeeSMarcel Holtmann void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 1344b644ba33SJohan Hedberg u8 addr_type, s8 rssi, u8 *name, u8 name_len); 13452f1e063bSMarcel Holtmann void mgmt_discovering(struct hci_dev *hdev, u8 discovering); 134653ac6ab6SMarcel Holtmann void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent); 134795fbac8aSJohan Hedberg void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk); 134853ac6ab6SMarcel Holtmann void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk, 134953ac6ab6SMarcel Holtmann bool persistent); 1350ffb5a827SAndre Guedes void mgmt_new_conn_param(struct hci_dev *hdev, bdaddr_t *bdaddr, 1351f4869e2aSJohan Hedberg u8 bdaddr_type, u8 store_hint, u16 min_interval, 1352f4869e2aSJohan Hedberg u16 max_interval, u16 latency, u16 timeout); 13535976e608SMarcel Holtmann void mgmt_reenable_advertising(struct hci_dev *hdev); 1354f4a407beSJohan Hedberg void mgmt_smp_complete(struct hci_conn *conn, bool complete); 1355346af67bSVinicius Costa Gomes 13561da177e4SLinus Torvalds /* HCI info for socket */ 13571da177e4SLinus Torvalds #define hci_pi(sk) ((struct hci_pinfo *) sk) 13581da177e4SLinus Torvalds 13591da177e4SLinus Torvalds struct hci_pinfo { 13601da177e4SLinus Torvalds struct bt_sock bt; 13611da177e4SLinus Torvalds struct hci_dev *hdev; 13621da177e4SLinus Torvalds struct hci_filter filter; 13631da177e4SLinus Torvalds __u32 cmsg_mask; 1364c02178d2SJohan Hedberg unsigned short channel; 13651da177e4SLinus Torvalds }; 13661da177e4SLinus Torvalds 13671da177e4SLinus Torvalds /* HCI security filter */ 13681da177e4SLinus Torvalds #define HCI_SFLT_MAX_OGF 5 13691da177e4SLinus Torvalds 13701da177e4SLinus Torvalds struct hci_sec_filter { 13711da177e4SLinus Torvalds __u32 type_mask; 13721da177e4SLinus Torvalds __u32 event_mask[2]; 13731da177e4SLinus Torvalds __u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4]; 13741da177e4SLinus Torvalds }; 13751da177e4SLinus Torvalds 13761da177e4SLinus Torvalds /* ----- HCI requests ----- */ 13771da177e4SLinus Torvalds #define HCI_REQ_DONE 0 13781da177e4SLinus Torvalds #define HCI_REQ_PEND 1 13791da177e4SLinus Torvalds #define HCI_REQ_CANCELED 2 13801da177e4SLinus Torvalds 1381a6a67efdSThomas Gleixner #define hci_req_lock(d) mutex_lock(&d->req_lock) 1382a6a67efdSThomas Gleixner #define hci_req_unlock(d) mutex_unlock(&d->req_lock) 13831da177e4SLinus Torvalds 13847d6ca693SJohan Hedberg u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency, 13857d6ca693SJohan Hedberg u16 to_multiplier); 1386fe39c7b2SMarcel Holtmann void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand, 1387a7a595f6SVinicius Costa Gomes __u8 ltk[16]); 13882519a1fcSAndre Guedes 138994b1fc92SMarcel Holtmann int hci_update_random_address(struct hci_request *req, bool require_privacy, 139094b1fc92SMarcel Holtmann u8 *own_addr_type); 1391a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, 1392a1f4c318SJohan Hedberg u8 *bdaddr_type); 1393ebd3a747SJohan Hedberg 13945d4d62f6SFrédéric Dalleau #define SCO_AIRMODE_MASK 0x0003 13955d4d62f6SFrédéric Dalleau #define SCO_AIRMODE_CVSD 0x0000 13965d4d62f6SFrédéric Dalleau #define SCO_AIRMODE_TRANSP 0x0003 13975d4d62f6SFrédéric Dalleau 13981da177e4SLinus Torvalds #endif /* __HCI_CORE_H */ 1399