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> 29f49daa81SMarcel Holtmann #include <net/bluetooth/hci_sock.h> 301da177e4SLinus Torvalds 315e59b791SLuiz Augusto von Dentz /* HCI priority */ 325e59b791SLuiz Augusto von Dentz #define HCI_PRIO_MAX 7 335e59b791SLuiz Augusto von Dentz 341da177e4SLinus Torvalds /* HCI Core structures */ 351da177e4SLinus Torvalds struct inquiry_data { 361da177e4SLinus Torvalds bdaddr_t bdaddr; 371da177e4SLinus Torvalds __u8 pscan_rep_mode; 381da177e4SLinus Torvalds __u8 pscan_period_mode; 391da177e4SLinus Torvalds __u8 pscan_mode; 401da177e4SLinus Torvalds __u8 dev_class[3]; 411ebb9252SMarcel Holtmann __le16 clock_offset; 421da177e4SLinus Torvalds __s8 rssi; 4341a96212SMarcel Holtmann __u8 ssp_mode; 441da177e4SLinus Torvalds }; 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds struct inquiry_entry { 47561aafbcSJohan Hedberg struct list_head all; /* inq_cache.all */ 48561aafbcSJohan Hedberg struct list_head list; /* unknown or resolve */ 49561aafbcSJohan Hedberg enum { 50561aafbcSJohan Hedberg NAME_NOT_KNOWN, 51561aafbcSJohan Hedberg NAME_NEEDED, 52561aafbcSJohan Hedberg NAME_PENDING, 53561aafbcSJohan Hedberg NAME_KNOWN, 54561aafbcSJohan Hedberg } name_state; 551da177e4SLinus Torvalds __u32 timestamp; 561da177e4SLinus Torvalds struct inquiry_data data; 571da177e4SLinus Torvalds }; 581da177e4SLinus Torvalds 5930883512SJohan Hedberg struct discovery_state { 604aab14e5SAndre Guedes int type; 61ff9ef578SJohan Hedberg enum { 62ff9ef578SJohan Hedberg DISCOVERY_STOPPED, 63ff9ef578SJohan Hedberg DISCOVERY_STARTING, 64343f935bSAndre Guedes DISCOVERY_FINDING, 6530dc78e1SJohan Hedberg DISCOVERY_RESOLVING, 66ff9ef578SJohan Hedberg DISCOVERY_STOPPING, 67ff9ef578SJohan Hedberg } state; 68561aafbcSJohan Hedberg struct list_head all; /* All devices found during inquiry */ 69561aafbcSJohan Hedberg struct list_head unknown; /* Name state not known */ 70561aafbcSJohan Hedberg struct list_head resolve; /* Name needs to be resolved */ 711da177e4SLinus Torvalds __u32 timestamp; 72b9a6328fSJohan Hedberg bdaddr_t last_adv_addr; 73b9a6328fSJohan Hedberg u8 last_adv_addr_type; 74ff5cd29fSJohan Hedberg s8 last_adv_rssi; 75c70a7e4cSMarcel Holtmann u32 last_adv_flags; 76b9a6328fSJohan Hedberg u8 last_adv_data[HCI_MAX_AD_LENGTH]; 77b9a6328fSJohan Hedberg u8 last_adv_data_len; 7837eab042SJakub Pawlowski s8 rssi; 7937eab042SJakub Pawlowski u16 uuid_count; 8037eab042SJakub Pawlowski u8 (*uuids)[16]; 811da177e4SLinus Torvalds }; 821da177e4SLinus Torvalds 831da177e4SLinus Torvalds struct hci_conn_hash { 841da177e4SLinus Torvalds struct list_head list; 851da177e4SLinus Torvalds unsigned int acl_num; 86bd1eb66bSAndrei Emeltchenko unsigned int amp_num; 871da177e4SLinus Torvalds unsigned int sco_num; 88fcd89c09SVille Tervo unsigned int le_num; 89f8218dc6SJohan Hedberg unsigned int le_num_slave; 901da177e4SLinus Torvalds }; 911da177e4SLinus Torvalds 92f0358568SJohan Hedberg struct bdaddr_list { 93f0358568SJohan Hedberg struct list_head list; 94f0358568SJohan Hedberg bdaddr_t bdaddr; 95b9ee0a78SMarcel Holtmann u8 bdaddr_type; 96f0358568SJohan Hedberg }; 972aeb9a1aSJohan Hedberg 982aeb9a1aSJohan Hedberg struct bt_uuid { 992aeb9a1aSJohan Hedberg struct list_head list; 1002aeb9a1aSJohan Hedberg u8 uuid[16]; 10183be8ecaSJohan Hedberg u8 size; 1021aff6f09SJohan Hedberg u8 svc_hint; 1032aeb9a1aSJohan Hedberg }; 1042aeb9a1aSJohan Hedberg 1057ee4ea36SMarcel Holtmann struct smp_csrk { 1067ee4ea36SMarcel Holtmann bdaddr_t bdaddr; 1077ee4ea36SMarcel Holtmann u8 bdaddr_type; 1087ee4ea36SMarcel Holtmann u8 master; 1097ee4ea36SMarcel Holtmann u8 val[16]; 1107ee4ea36SMarcel Holtmann }; 1117ee4ea36SMarcel Holtmann 112b899efafSVinicius Costa Gomes struct smp_ltk { 113b899efafSVinicius Costa Gomes struct list_head list; 114970d0f1bSJohan Hedberg struct rcu_head rcu; 115b899efafSVinicius Costa Gomes bdaddr_t bdaddr; 116b899efafSVinicius Costa Gomes u8 bdaddr_type; 117b899efafSVinicius Costa Gomes u8 authenticated; 118b899efafSVinicius Costa Gomes u8 type; 119b899efafSVinicius Costa Gomes u8 enc_size; 120b899efafSVinicius Costa Gomes __le16 ediv; 121fe39c7b2SMarcel Holtmann __le64 rand; 122b899efafSVinicius Costa Gomes u8 val[16]; 12303c515d7SMarcel Holtmann }; 124b899efafSVinicius Costa Gomes 125970c4e46SJohan Hedberg struct smp_irk { 126970c4e46SJohan Hedberg struct list_head list; 127adae20cbSJohan Hedberg struct rcu_head rcu; 128970c4e46SJohan Hedberg bdaddr_t rpa; 129970c4e46SJohan Hedberg bdaddr_t bdaddr; 130970c4e46SJohan Hedberg u8 addr_type; 131970c4e46SJohan Hedberg u8 val[16]; 132970c4e46SJohan Hedberg }; 133970c4e46SJohan Hedberg 13455ed8ca1SJohan Hedberg struct link_key { 13555ed8ca1SJohan Hedberg struct list_head list; 1360378b597SJohan Hedberg struct rcu_head rcu; 13755ed8ca1SJohan Hedberg bdaddr_t bdaddr; 13855ed8ca1SJohan Hedberg u8 type; 1399b3b4460SAndrei Emeltchenko u8 val[HCI_LINK_KEY_SIZE]; 14055ed8ca1SJohan Hedberg u8 pin_len; 14155ed8ca1SJohan Hedberg }; 14255ed8ca1SJohan Hedberg 1432763eda6SSzymon Janc struct oob_data { 1442763eda6SSzymon Janc struct list_head list; 1452763eda6SSzymon Janc bdaddr_t bdaddr; 1466928a924SJohan Hedberg u8 bdaddr_type; 147519ca9d0SMarcel Holtmann u8 hash192[16]; 14838da1703SJohan Hedberg u8 rand192[16]; 149519ca9d0SMarcel Holtmann u8 hash256[16]; 15038da1703SJohan Hedberg u8 rand256[16]; 1512763eda6SSzymon Janc }; 1522763eda6SSzymon Janc 153490c5babSJohan Hedberg #define HCI_MAX_SHORT_NAME_LENGTH 10 154490c5babSJohan Hedberg 155d6bfd59cSJohan Hedberg /* Default LE RPA expiry time, 15 minutes */ 156d6bfd59cSJohan Hedberg #define HCI_DEFAULT_RPA_TIMEOUT (15 * 60) 157d6bfd59cSJohan Hedberg 15831ad1691SAndrzej Kaczmarek /* Default min/max age of connection information (1s/3s) */ 15931ad1691SAndrzej Kaczmarek #define DEFAULT_CONN_INFO_MIN_AGE 1000 16031ad1691SAndrzej Kaczmarek #define DEFAULT_CONN_INFO_MAX_AGE 3000 16131ad1691SAndrzej Kaczmarek 162903e4541SAndrei Emeltchenko struct amp_assoc { 163903e4541SAndrei Emeltchenko __u16 len; 164903e4541SAndrei Emeltchenko __u16 offset; 16593c284eeSAndrei Emeltchenko __u16 rem_len; 16693c284eeSAndrei Emeltchenko __u16 len_so_far; 167903e4541SAndrei Emeltchenko __u8 data[HCI_MAX_AMP_ASSOC_SIZE]; 168903e4541SAndrei Emeltchenko }; 169903e4541SAndrei Emeltchenko 170d2c5d77fSJohan Hedberg #define HCI_MAX_PAGES 3 171cad718edSJohan Hedberg 172cd4c5391SSuraj Sumangala #define NUM_REASSEMBLY 4 1731da177e4SLinus Torvalds struct hci_dev { 1741da177e4SLinus Torvalds struct list_head list; 17509fd0de5SGustavo F. Padovan struct mutex lock; 1761da177e4SLinus Torvalds 1771da177e4SLinus Torvalds char name[8]; 1781da177e4SLinus Torvalds unsigned long flags; 1791da177e4SLinus Torvalds __u16 id; 180c13854ceSMarcel Holtmann __u8 bus; 181943da25dSMarcel Holtmann __u8 dev_type; 1821da177e4SLinus Torvalds bdaddr_t bdaddr; 183e30d3f5fSMarcel Holtmann bdaddr_t setup_addr; 18424c457e2SMarcel Holtmann bdaddr_t public_addr; 1857a4cd51dSMarcel Holtmann bdaddr_t random_addr; 186d13eafceSMarcel Holtmann bdaddr_t static_addr; 18756ed2cb8SJohan Hedberg __u8 adv_addr_type; 1881f6c6378SJohan Hedberg __u8 dev_name[HCI_MAX_NAME_LENGTH]; 189490c5babSJohan Hedberg __u8 short_name[HCI_MAX_SHORT_NAME_LENGTH]; 19080a1e1dbSJohan Hedberg __u8 eir[HCI_MAX_EIR_LENGTH]; 191a9de9248SMarcel Holtmann __u8 dev_class[3]; 1921aff6f09SJohan Hedberg __u8 major_class; 1931aff6f09SJohan Hedberg __u8 minor_class; 194d2c5d77fSJohan Hedberg __u8 max_page; 195cad718edSJohan Hedberg __u8 features[HCI_MAX_PAGES][8]; 19660e77321SJohan Hedberg __u8 le_features[8]; 197cf1d081fSJohan Hedberg __u8 le_white_list_size; 1989b008c04SJohan Hedberg __u8 le_states[8]; 199a9de9248SMarcel Holtmann __u8 commands[64]; 2001143e5a6SMarcel Holtmann __u8 hci_ver; 2011143e5a6SMarcel Holtmann __u16 hci_rev; 202d5859e22SJohan Hedberg __u8 lmp_ver; 2031143e5a6SMarcel Holtmann __u16 manufacturer; 2047d69230cSAndrei Emeltchenko __u16 lmp_subver; 2051da177e4SLinus Torvalds __u16 voice_setting; 206b4cb9fb2SMarcel Holtmann __u8 num_iac; 20717fa4b9dSJohan Hedberg __u8 io_capability; 20891c4e9b1SMarcel Holtmann __s8 inq_tx_power; 209f332ec66SJohan Hedberg __u16 page_scan_interval; 210f332ec66SJohan Hedberg __u16 page_scan_window; 211f332ec66SJohan Hedberg __u8 page_scan_type; 2123f959d46SMarcel Holtmann __u8 le_adv_channel_map; 213628531c9SGeorg Lukas __u16 le_adv_min_interval; 214628531c9SGeorg Lukas __u16 le_adv_max_interval; 215533553f8SMarcel Holtmann __u8 le_scan_type; 216bef64738SMarcel Holtmann __u16 le_scan_interval; 217bef64738SMarcel Holtmann __u16 le_scan_window; 2184e70c7e7SMarcel Holtmann __u16 le_conn_min_interval; 2194e70c7e7SMarcel Holtmann __u16 le_conn_max_interval; 22004fb7d90SMarcel Holtmann __u16 le_conn_latency; 22104fb7d90SMarcel Holtmann __u16 le_supv_timeout; 222b9a7a61eSLukasz Rymanowski __u16 discov_interleaved_timeout; 22331ad1691SAndrzej Kaczmarek __u16 conn_info_min_age; 22431ad1691SAndrzej Kaczmarek __u16 conn_info_max_age; 22506f5b778SMarcel Holtmann __u8 ssp_debug_mode; 22633f35721SJohan Hedberg __u32 clock; 227f332ec66SJohan Hedberg 2282b9be137SMarcel Holtmann __u16 devid_source; 2292b9be137SMarcel Holtmann __u16 devid_vendor; 2302b9be137SMarcel Holtmann __u16 devid_product; 2312b9be137SMarcel Holtmann __u16 devid_version; 2321da177e4SLinus Torvalds 2331da177e4SLinus Torvalds __u16 pkt_type; 2345b7f9909SMarcel Holtmann __u16 esco_type; 2351da177e4SLinus Torvalds __u16 link_policy; 2361da177e4SLinus Torvalds __u16 link_mode; 2371da177e4SLinus Torvalds 23804837f64SMarcel Holtmann __u32 idle_timeout; 23904837f64SMarcel Holtmann __u16 sniff_min_interval; 24004837f64SMarcel Holtmann __u16 sniff_max_interval; 24104837f64SMarcel Holtmann 242928abaa7SAndrei Emeltchenko __u8 amp_status; 243928abaa7SAndrei Emeltchenko __u32 amp_total_bw; 244928abaa7SAndrei Emeltchenko __u32 amp_max_bw; 245928abaa7SAndrei Emeltchenko __u32 amp_min_latency; 246928abaa7SAndrei Emeltchenko __u32 amp_max_pdu; 247928abaa7SAndrei Emeltchenko __u8 amp_type; 248928abaa7SAndrei Emeltchenko __u16 amp_pal_cap; 249928abaa7SAndrei Emeltchenko __u16 amp_assoc_size; 250928abaa7SAndrei Emeltchenko __u32 amp_max_flush_to; 251928abaa7SAndrei Emeltchenko __u32 amp_be_flush_to; 252928abaa7SAndrei Emeltchenko 253903e4541SAndrei Emeltchenko struct amp_assoc loc_assoc; 254903e4541SAndrei Emeltchenko 2551e89cffbSAndrei Emeltchenko __u8 flow_ctl_mode; 2561e89cffbSAndrei Emeltchenko 2579f61656aSJohan Hedberg unsigned int auto_accept_delay; 2589f61656aSJohan Hedberg 2591da177e4SLinus Torvalds unsigned long quirks; 2601da177e4SLinus Torvalds 2611da177e4SLinus Torvalds atomic_t cmd_cnt; 2621da177e4SLinus Torvalds unsigned int acl_cnt; 2631da177e4SLinus Torvalds unsigned int sco_cnt; 2646ed58ec5SVille Tervo unsigned int le_cnt; 2651da177e4SLinus Torvalds 2661da177e4SLinus Torvalds unsigned int acl_mtu; 2671da177e4SLinus Torvalds unsigned int sco_mtu; 2686ed58ec5SVille Tervo unsigned int le_mtu; 2691da177e4SLinus Torvalds unsigned int acl_pkts; 2701da177e4SLinus Torvalds unsigned int sco_pkts; 2716ed58ec5SVille Tervo unsigned int le_pkts; 2721da177e4SLinus Torvalds 273350ee4cfSAndrei Emeltchenko __u16 block_len; 274350ee4cfSAndrei Emeltchenko __u16 block_mtu; 275350ee4cfSAndrei Emeltchenko __u16 num_blocks; 276350ee4cfSAndrei Emeltchenko __u16 block_cnt; 277350ee4cfSAndrei Emeltchenko 2781da177e4SLinus Torvalds unsigned long acl_last_tx; 2791da177e4SLinus Torvalds unsigned long sco_last_tx; 2806ed58ec5SVille Tervo unsigned long le_last_tx; 2811da177e4SLinus Torvalds 282f48fd9c8SMarcel Holtmann struct workqueue_struct *workqueue; 2836ead1bbcSJohan Hedberg struct workqueue_struct *req_workqueue; 284f48fd9c8SMarcel Holtmann 285ab81cbf9SJohan Hedberg struct work_struct power_on; 2863243553fSJohan Hedberg struct delayed_work power_off; 287ab81cbf9SJohan Hedberg 28816ab91abSJohan Hedberg __u16 discov_timeout; 28916ab91abSJohan Hedberg struct delayed_work discov_off; 29016ab91abSJohan Hedberg 2917d78525dSJohan Hedberg struct delayed_work service_cache; 2927d78525dSJohan Hedberg 29365cc2b49SMarcel Holtmann struct delayed_work cmd_timer; 294b78752ccSMarcel Holtmann 295b78752ccSMarcel Holtmann struct work_struct rx_work; 296c347b765SGustavo F. Padovan struct work_struct cmd_work; 2973eff45eaSGustavo F. Padovan struct work_struct tx_work; 2981da177e4SLinus Torvalds 2991da177e4SLinus Torvalds struct sk_buff_head rx_q; 3001da177e4SLinus Torvalds struct sk_buff_head raw_q; 3011da177e4SLinus Torvalds struct sk_buff_head cmd_q; 3021da177e4SLinus Torvalds 303b6ddb638SJohan Hedberg struct sk_buff *recv_evt; 3041da177e4SLinus Torvalds struct sk_buff *sent_cmd; 305cd4c5391SSuraj Sumangala struct sk_buff *reassembly[NUM_REASSEMBLY]; 3061da177e4SLinus Torvalds 307a6a67efdSThomas Gleixner struct mutex req_lock; 3081da177e4SLinus Torvalds wait_queue_head_t req_wait_q; 3091da177e4SLinus Torvalds __u32 req_status; 3101da177e4SLinus Torvalds __u32 req_result; 311a5040efaSJohan Hedberg 31270db83c4SJohan Hedberg void *smp_data; 313ef8efe4bSJohan Hedberg void *smp_bredr_data; 3142e58ef3eSJohan Hedberg 31530883512SJohan Hedberg struct discovery_state discovery; 3161da177e4SLinus Torvalds struct hci_conn_hash conn_hash; 3175c136e90SAndre Guedes 3185c136e90SAndre Guedes struct list_head mgmt_pending; 319ea4bd8baSDavid Miller struct list_head blacklist; 3206659358eSJohan Hedberg struct list_head whitelist; 3212aeb9a1aSJohan Hedberg struct list_head uuids; 32255ed8ca1SJohan Hedberg struct list_head link_keys; 323b899efafSVinicius Costa Gomes struct list_head long_term_keys; 324970c4e46SJohan Hedberg struct list_head identity_resolving_keys; 3252763eda6SSzymon Janc struct list_head remote_oob_data; 326d2ab0ac1SMarcel Holtmann struct list_head le_white_list; 32715819a70SAndre Guedes struct list_head le_conn_params; 32877a77a30SAndre Guedes struct list_head pend_le_conns; 32966f8455aSJohan Hedberg struct list_head pend_le_reports; 3302763eda6SSzymon Janc 3311da177e4SLinus Torvalds struct hci_dev_stats stat; 3321da177e4SLinus Torvalds 3331da177e4SLinus Torvalds atomic_t promisc; 3341da177e4SLinus Torvalds 335ca325f69SMarcel Holtmann struct dentry *debugfs; 336ca325f69SMarcel Holtmann 337a91f2e39SMarcel Holtmann struct device dev; 3381da177e4SLinus Torvalds 339611b30f7SMarcel Holtmann struct rfkill *rfkill; 340611b30f7SMarcel Holtmann 341111902f7SMarcel Holtmann unsigned long dbg_flags; 342d23264a8SAndre Guedes unsigned long dev_flags; 343d23264a8SAndre Guedes 3447ba8b4beSAndre Guedes struct delayed_work le_scan_disable; 3457ba8b4beSAndre Guedes 3468fa19098SJohan Hedberg __s8 adv_tx_power; 3473f0f524bSJohan Hedberg __u8 adv_data[HCI_MAX_AD_LENGTH]; 3483f0f524bSJohan Hedberg __u8 adv_data_len; 349f8e808bdSMarcel Holtmann __u8 scan_rsp_data[HCI_MAX_AD_LENGTH]; 350f8e808bdSMarcel Holtmann __u8 scan_rsp_data_len; 3518fa19098SJohan Hedberg 352863efaf2SJohan Hedberg __u8 irk[16]; 353d6bfd59cSJohan Hedberg __u32 rpa_timeout; 354d6bfd59cSJohan Hedberg struct delayed_work rpa_expired; 3552b5224dcSMarcel Holtmann bdaddr_t rpa; 356863efaf2SJohan Hedberg 3571da177e4SLinus Torvalds int (*open)(struct hci_dev *hdev); 3581da177e4SLinus Torvalds int (*close)(struct hci_dev *hdev); 3591da177e4SLinus Torvalds int (*flush)(struct hci_dev *hdev); 360f41c70c4SMarcel Holtmann int (*setup)(struct hci_dev *hdev); 3617bd8f09fSMarcel Holtmann int (*send)(struct hci_dev *hdev, struct sk_buff *skb); 3621da177e4SLinus Torvalds void (*notify)(struct hci_dev *hdev, unsigned int evt); 36324c457e2SMarcel Holtmann int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr); 3641da177e4SLinus Torvalds }; 3651da177e4SLinus Torvalds 36653502d69SAndrei Emeltchenko #define HCI_PHY_HANDLE(handle) (handle & 0xff) 36753502d69SAndrei Emeltchenko 3681da177e4SLinus Torvalds struct hci_conn { 3691da177e4SLinus Torvalds struct list_head list; 3701da177e4SLinus Torvalds 3711da177e4SLinus Torvalds atomic_t refcnt; 3721da177e4SLinus Torvalds 3731da177e4SLinus Torvalds bdaddr_t dst; 37429b7988aSAndre Guedes __u8 dst_type; 375662e8820SMarcel Holtmann bdaddr_t src; 376e7c4096eSMarcel Holtmann __u8 src_type; 377cb1d68f7SJohan Hedberg bdaddr_t init_addr; 378cb1d68f7SJohan Hedberg __u8 init_addr_type; 379cb1d68f7SJohan Hedberg bdaddr_t resp_addr; 380cb1d68f7SJohan Hedberg __u8 resp_addr_type; 3811da177e4SLinus Torvalds __u16 handle; 3821da177e4SLinus Torvalds __u16 state; 38304837f64SMarcel Holtmann __u8 mode; 3841da177e4SLinus Torvalds __u8 type; 38540bef302SJohan Hedberg __u8 role; 386a0c808b3SJohan Hedberg bool out; 3874c67bc74SMarcel Holtmann __u8 attempt; 3881da177e4SLinus Torvalds __u8 dev_class[3]; 389cad718edSJohan Hedberg __u8 features[HCI_MAX_PAGES][8]; 390a8746417SMarcel Holtmann __u16 pkt_type; 39104837f64SMarcel Holtmann __u16 link_policy; 39213d39315SWaldemar Rymarkiewicz __u8 key_type; 39340be492fSMarcel Holtmann __u8 auth_type; 3948c1b2355SMarcel Holtmann __u8 sec_level; 395765c2a96SJohan Hedberg __u8 pending_sec_level; 396980e1a53SJohan Hedberg __u8 pin_length; 397726b4ffcSVinicius Costa Gomes __u8 enc_key_size; 39817fa4b9dSJohan Hedberg __u8 io_capability; 39992a25256SJohan Hedberg __u32 passkey_notify; 40092a25256SJohan Hedberg __u8 passkey_entered; 401052b30b0SMarcel Holtmann __u16 disc_timeout; 40209ae260bSJohan Hedberg __u16 conn_timeout; 40310c62ddcSFrédéric Dalleau __u16 setting; 4041e406eefSAndre Guedes __u16 le_conn_min_interval; 4051e406eefSAndre Guedes __u16 le_conn_max_interval; 406e04fde60SMarcel Holtmann __u16 le_conn_interval; 407e04fde60SMarcel Holtmann __u16 le_conn_latency; 408e04fde60SMarcel Holtmann __u16 le_supv_timeout; 409fd45ada9SAlfonso Acosta __u8 le_adv_data[HCI_MAX_AD_LENGTH]; 410fd45ada9SAlfonso Acosta __u8 le_adv_data_len; 4115ae76a94SAndrzej Kaczmarek __s8 rssi; 4125a134faeSAndrzej Kaczmarek __s8 tx_power; 413d0455ed9SAndrzej Kaczmarek __s8 max_tx_power; 41451a8efd7SJohan Hedberg unsigned long flags; 4151da177e4SLinus Torvalds 41633f35721SJohan Hedberg __u32 clock; 41733f35721SJohan Hedberg __u16 clock_accuracy; 41833f35721SJohan Hedberg 419dd983808SAndrzej Kaczmarek unsigned long conn_info_timestamp; 420dd983808SAndrzej Kaczmarek 42103b555e1SJohan Hedberg __u8 remote_cap; 42203b555e1SJohan Hedberg __u8 remote_auth; 4233161ae1cSAndrei Emeltchenko __u8 remote_id; 42403b555e1SJohan Hedberg 4251da177e4SLinus Torvalds unsigned int sent; 4261da177e4SLinus Torvalds 4271da177e4SLinus Torvalds struct sk_buff_head data_q; 4282c33c06aSGustavo F. Padovan struct list_head chan_list; 4291da177e4SLinus Torvalds 43019c40e3bSGustavo F. Padovan struct delayed_work disc_work; 4317bc18d9dSJohan Hedberg struct delayed_work auto_accept_work; 432a74a84f6SJohan Hedberg struct delayed_work idle_work; 4339489eca4SJohan Hedberg struct delayed_work le_conn_timeout; 4341da177e4SLinus Torvalds 435b219e3acSMarcel Holtmann struct device dev; 436b219e3acSMarcel Holtmann 4371da177e4SLinus Torvalds struct hci_dev *hdev; 4381da177e4SLinus Torvalds void *l2cap_data; 4391da177e4SLinus Torvalds void *sco_data; 4409740e49dSAndrei Emeltchenko struct amp_mgr *amp_mgr; 4411da177e4SLinus Torvalds 4421da177e4SLinus Torvalds struct hci_conn *link; 443e9a416b5SJohan Hedberg 444e9a416b5SJohan Hedberg void (*connect_cfm_cb) (struct hci_conn *conn, u8 status); 445e9a416b5SJohan Hedberg void (*security_cfm_cb) (struct hci_conn *conn, u8 status); 446e9a416b5SJohan Hedberg void (*disconn_cfm_cb) (struct hci_conn *conn, u8 reason); 4471da177e4SLinus Torvalds }; 4481da177e4SLinus Torvalds 44973d80debSLuiz Augusto von Dentz struct hci_chan { 45073d80debSLuiz Augusto von Dentz struct list_head list; 45142c4e53eSAndrei Emeltchenko __u16 handle; 45273d80debSLuiz Augusto von Dentz struct hci_conn *conn; 45373d80debSLuiz Augusto von Dentz struct sk_buff_head data_q; 45473d80debSLuiz Augusto von Dentz unsigned int sent; 455168df8e5SMat Martineau __u8 state; 45673d80debSLuiz Augusto von Dentz }; 45773d80debSLuiz Augusto von Dentz 45815819a70SAndre Guedes struct hci_conn_params { 45915819a70SAndre Guedes struct list_head list; 46093450c75SJohan Hedberg struct list_head action; 46115819a70SAndre Guedes 46215819a70SAndre Guedes bdaddr_t addr; 46315819a70SAndre Guedes u8 addr_type; 46415819a70SAndre Guedes 46515819a70SAndre Guedes u16 conn_min_interval; 46615819a70SAndre Guedes u16 conn_max_interval; 467f044eb05SMarcel Holtmann u16 conn_latency; 468f044eb05SMarcel Holtmann u16 supervision_timeout; 4699fcb18efSAndre Guedes 4709fcb18efSAndre Guedes enum { 4719fcb18efSAndre Guedes HCI_AUTO_CONN_DISABLED, 472a3451d27SJohan Hedberg HCI_AUTO_CONN_REPORT, 4734b9e7e75SMarcel Holtmann HCI_AUTO_CONN_DIRECT, 4749fcb18efSAndre Guedes HCI_AUTO_CONN_ALWAYS, 4759fcb18efSAndre Guedes HCI_AUTO_CONN_LINK_LOSS, 4769fcb18efSAndre Guedes } auto_connect; 477f161dd41SJohan Hedberg 478f161dd41SJohan Hedberg struct hci_conn *conn; 47915819a70SAndre Guedes }; 48015819a70SAndre Guedes 4811da177e4SLinus Torvalds extern struct list_head hci_dev_list; 4821da177e4SLinus Torvalds extern struct list_head hci_cb_list; 4831da177e4SLinus Torvalds extern rwlock_t hci_dev_list_lock; 4841da177e4SLinus Torvalds extern rwlock_t hci_cb_list_lock; 4851da177e4SLinus Torvalds 486686ebf28SUlisses Furquim /* ----- HCI interface to upper protocols ----- */ 487e74e58f8SJoe Perches int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); 488e74e58f8SJoe Perches void l2cap_connect_cfm(struct hci_conn *hcon, u8 status); 489e74e58f8SJoe Perches int l2cap_disconn_ind(struct hci_conn *hcon); 490e74e58f8SJoe Perches void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason); 491e74e58f8SJoe Perches int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt); 492e74e58f8SJoe Perches int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags); 493686ebf28SUlisses Furquim 494e74e58f8SJoe Perches int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags); 495e74e58f8SJoe Perches void sco_connect_cfm(struct hci_conn *hcon, __u8 status); 496e74e58f8SJoe Perches void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason); 497e74e58f8SJoe Perches int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb); 498686ebf28SUlisses Furquim 4991da177e4SLinus Torvalds /* ----- Inquiry cache ----- */ 50070f23020SAndrei Emeltchenko #define INQUIRY_CACHE_AGE_MAX (HZ*30) /* 30 seconds */ 50170f23020SAndrei Emeltchenko #define INQUIRY_ENTRY_AGE_MAX (HZ*60) /* 60 seconds */ 5021da177e4SLinus Torvalds 50330883512SJohan Hedberg static inline void discovery_init(struct hci_dev *hdev) 5041da177e4SLinus Torvalds { 505ff9ef578SJohan Hedberg hdev->discovery.state = DISCOVERY_STOPPED; 50630883512SJohan Hedberg INIT_LIST_HEAD(&hdev->discovery.all); 50730883512SJohan Hedberg INIT_LIST_HEAD(&hdev->discovery.unknown); 50830883512SJohan Hedberg INIT_LIST_HEAD(&hdev->discovery.resolve); 50937eab042SJakub Pawlowski hdev->discovery.rssi = HCI_RSSI_INVALID; 5101da177e4SLinus Torvalds } 5111da177e4SLinus Torvalds 5120256325eSMarcel Holtmann static inline void hci_discovery_filter_clear(struct hci_dev *hdev) 5130256325eSMarcel Holtmann { 5140256325eSMarcel Holtmann hdev->discovery.rssi = HCI_RSSI_INVALID; 5150256325eSMarcel Holtmann hdev->discovery.uuid_count = 0; 5160256325eSMarcel Holtmann kfree(hdev->discovery.uuids); 5170256325eSMarcel Holtmann hdev->discovery.uuids = NULL; 5180256325eSMarcel Holtmann } 5190256325eSMarcel Holtmann 52030dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev); 52130dc78e1SJohan Hedberg 522ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state); 523ff9ef578SJohan Hedberg 5241da177e4SLinus Torvalds static inline int inquiry_cache_empty(struct hci_dev *hdev) 5251da177e4SLinus Torvalds { 52630883512SJohan Hedberg return list_empty(&hdev->discovery.all); 5271da177e4SLinus Torvalds } 5281da177e4SLinus Torvalds 5291da177e4SLinus Torvalds static inline long inquiry_cache_age(struct hci_dev *hdev) 5301da177e4SLinus Torvalds { 53130883512SJohan Hedberg struct discovery_state *c = &hdev->discovery; 5321da177e4SLinus Torvalds return jiffies - c->timestamp; 5331da177e4SLinus Torvalds } 5341da177e4SLinus Torvalds 5351da177e4SLinus Torvalds static inline long inquiry_entry_age(struct inquiry_entry *e) 5361da177e4SLinus Torvalds { 5371da177e4SLinus Torvalds return jiffies - e->timestamp; 5381da177e4SLinus Torvalds } 5391da177e4SLinus Torvalds 5405a9d0a3fSWaldemar Rymarkiewicz struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 5415a9d0a3fSWaldemar Rymarkiewicz bdaddr_t *bdaddr); 542561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 543561aafbcSJohan Hedberg bdaddr_t *bdaddr); 54430dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 54530dc78e1SJohan Hedberg bdaddr_t *bdaddr, 54630dc78e1SJohan Hedberg int state); 547a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 548a3d4e20aSJohan Hedberg struct inquiry_entry *ie); 549af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 550af58925cSMarcel Holtmann bool name_known); 5511f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev); 5521da177e4SLinus Torvalds 5531da177e4SLinus Torvalds /* ----- HCI Connections ----- */ 5541da177e4SLinus Torvalds enum { 5551da177e4SLinus Torvalds HCI_CONN_AUTH_PEND, 55619f8def0SWaldemar Rymarkiewicz HCI_CONN_REAUTH_PEND, 5571da177e4SLinus Torvalds HCI_CONN_ENCRYPT_PEND, 55804837f64SMarcel Holtmann HCI_CONN_RSWITCH_PEND, 55904837f64SMarcel Holtmann HCI_CONN_MODE_CHANGE_PEND, 560e73439d8SMarcel Holtmann HCI_CONN_SCO_SETUP_PEND, 561b644ba33SJohan Hedberg HCI_CONN_MGMT_CONNECTED, 56258a681efSJohan Hedberg HCI_CONN_SSP_ENABLED, 563eb9a8f3fSMarcel Holtmann HCI_CONN_SC_ENABLED, 564abf76badSMarcel Holtmann HCI_CONN_AES_CCM, 56558a681efSJohan Hedberg HCI_CONN_POWER_SAVE, 56658a681efSJohan Hedberg HCI_CONN_REMOTE_OOB, 567af6a9c32SJohan Hedberg HCI_CONN_FLUSH_KEY, 5684dae2798SJohan Hedberg HCI_CONN_ENCRYPT, 5694dae2798SJohan Hedberg HCI_CONN_AUTH, 5704dae2798SJohan Hedberg HCI_CONN_SECURE, 5714dae2798SJohan Hedberg HCI_CONN_FIPS, 572fe59a05fSJohan Hedberg HCI_CONN_STK_ENCRYPT, 573977f8fceSJohan Hedberg HCI_CONN_AUTH_INITIATOR, 574f94b665dSJohan Hedberg HCI_CONN_DROP, 57589cbb063SAlfonso Acosta HCI_CONN_PARAM_REMOVAL_PEND, 576fe8bc5acSJohan Hedberg HCI_CONN_NEW_LINK_KEY, 5771da177e4SLinus Torvalds }; 5781da177e4SLinus Torvalds 579aa64a8b5SJohan Hedberg static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) 580aa64a8b5SJohan Hedberg { 581aa64a8b5SJohan Hedberg struct hci_dev *hdev = conn->hdev; 582c3c7ea65SGustavo Padovan return test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && 583c3c7ea65SGustavo Padovan test_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 584aa64a8b5SJohan Hedberg } 585aa64a8b5SJohan Hedberg 586eb9a8f3fSMarcel Holtmann static inline bool hci_conn_sc_enabled(struct hci_conn *conn) 587eb9a8f3fSMarcel Holtmann { 588eb9a8f3fSMarcel Holtmann struct hci_dev *hdev = conn->hdev; 589eb9a8f3fSMarcel Holtmann return test_bit(HCI_SC_ENABLED, &hdev->dev_flags) && 590eb9a8f3fSMarcel Holtmann test_bit(HCI_CONN_SC_ENABLED, &conn->flags); 591eb9a8f3fSMarcel Holtmann } 592eb9a8f3fSMarcel Holtmann 5931da177e4SLinus Torvalds static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) 5941da177e4SLinus Torvalds { 5951da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 596bf4c6325SGustavo F. Padovan list_add_rcu(&c->list, &h->list); 597fcd89c09SVille Tervo switch (c->type) { 598fcd89c09SVille Tervo case ACL_LINK: 5991da177e4SLinus Torvalds h->acl_num++; 600fcd89c09SVille Tervo break; 601bd1eb66bSAndrei Emeltchenko case AMP_LINK: 602bd1eb66bSAndrei Emeltchenko h->amp_num++; 603bd1eb66bSAndrei Emeltchenko break; 604fcd89c09SVille Tervo case LE_LINK: 605fcd89c09SVille Tervo h->le_num++; 606f8218dc6SJohan Hedberg if (c->role == HCI_ROLE_SLAVE) 607f8218dc6SJohan Hedberg h->le_num_slave++; 608fcd89c09SVille Tervo break; 609fcd89c09SVille Tervo case SCO_LINK: 610fcd89c09SVille Tervo case ESCO_LINK: 6111da177e4SLinus Torvalds h->sco_num++; 612fcd89c09SVille Tervo break; 613fcd89c09SVille Tervo } 6141da177e4SLinus Torvalds } 6151da177e4SLinus Torvalds 6161da177e4SLinus Torvalds static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) 6171da177e4SLinus Torvalds { 6181da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 619bf4c6325SGustavo F. Padovan 620bf4c6325SGustavo F. Padovan list_del_rcu(&c->list); 621bf4c6325SGustavo F. Padovan synchronize_rcu(); 622bf4c6325SGustavo F. Padovan 623fcd89c09SVille Tervo switch (c->type) { 624fcd89c09SVille Tervo case ACL_LINK: 6251da177e4SLinus Torvalds h->acl_num--; 626fcd89c09SVille Tervo break; 627bd1eb66bSAndrei Emeltchenko case AMP_LINK: 628bd1eb66bSAndrei Emeltchenko h->amp_num--; 629bd1eb66bSAndrei Emeltchenko break; 630fcd89c09SVille Tervo case LE_LINK: 631fcd89c09SVille Tervo h->le_num--; 632f8218dc6SJohan Hedberg if (c->role == HCI_ROLE_SLAVE) 633f8218dc6SJohan Hedberg h->le_num_slave--; 634fcd89c09SVille Tervo break; 635fcd89c09SVille Tervo case SCO_LINK: 636fcd89c09SVille Tervo case ESCO_LINK: 6371da177e4SLinus Torvalds h->sco_num--; 638fcd89c09SVille Tervo break; 639fcd89c09SVille Tervo } 6401da177e4SLinus Torvalds } 6411da177e4SLinus Torvalds 64252087a79SLuiz Augusto von Dentz static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type) 64352087a79SLuiz Augusto von Dentz { 64452087a79SLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 64552087a79SLuiz Augusto von Dentz switch (type) { 64652087a79SLuiz Augusto von Dentz case ACL_LINK: 64752087a79SLuiz Augusto von Dentz return h->acl_num; 648bd1eb66bSAndrei Emeltchenko case AMP_LINK: 649bd1eb66bSAndrei Emeltchenko return h->amp_num; 65052087a79SLuiz Augusto von Dentz case LE_LINK: 65152087a79SLuiz Augusto von Dentz return h->le_num; 65252087a79SLuiz Augusto von Dentz case SCO_LINK: 65352087a79SLuiz Augusto von Dentz case ESCO_LINK: 65452087a79SLuiz Augusto von Dentz return h->sco_num; 65552087a79SLuiz Augusto von Dentz default: 65652087a79SLuiz Augusto von Dentz return 0; 65752087a79SLuiz Augusto von Dentz } 65852087a79SLuiz Augusto von Dentz } 65952087a79SLuiz Augusto von Dentz 660f4f07505SJohan Hedberg static inline unsigned int hci_conn_count(struct hci_dev *hdev) 661f4f07505SJohan Hedberg { 662f4f07505SJohan Hedberg struct hci_conn_hash *c = &hdev->conn_hash; 663f4f07505SJohan Hedberg 664f4f07505SJohan Hedberg return c->acl_num + c->amp_num + c->sco_num + c->le_num; 665f4f07505SJohan Hedberg } 666f4f07505SJohan Hedberg 667845472e8SMarcel Holtmann static inline __u8 hci_conn_lookup_type(struct hci_dev *hdev, __u16 handle) 668845472e8SMarcel Holtmann { 669845472e8SMarcel Holtmann struct hci_conn_hash *h = &hdev->conn_hash; 670845472e8SMarcel Holtmann struct hci_conn *c; 671845472e8SMarcel Holtmann __u8 type = INVALID_LINK; 672845472e8SMarcel Holtmann 673845472e8SMarcel Holtmann rcu_read_lock(); 674845472e8SMarcel Holtmann 675845472e8SMarcel Holtmann list_for_each_entry_rcu(c, &h->list, list) { 676845472e8SMarcel Holtmann if (c->handle == handle) { 677845472e8SMarcel Holtmann type = c->type; 678845472e8SMarcel Holtmann break; 679845472e8SMarcel Holtmann } 680845472e8SMarcel Holtmann } 681845472e8SMarcel Holtmann 682845472e8SMarcel Holtmann rcu_read_unlock(); 683845472e8SMarcel Holtmann 684845472e8SMarcel Holtmann return type; 685845472e8SMarcel Holtmann } 686845472e8SMarcel Holtmann 6871da177e4SLinus Torvalds static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev, 6881da177e4SLinus Torvalds __u16 handle) 6891da177e4SLinus Torvalds { 6901da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 6911da177e4SLinus Torvalds struct hci_conn *c; 6921da177e4SLinus Torvalds 693bf4c6325SGustavo F. Padovan rcu_read_lock(); 694bf4c6325SGustavo F. Padovan 695bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 696bf4c6325SGustavo F. Padovan if (c->handle == handle) { 697bf4c6325SGustavo F. Padovan rcu_read_unlock(); 6981da177e4SLinus Torvalds return c; 6991da177e4SLinus Torvalds } 700bf4c6325SGustavo F. Padovan } 701bf4c6325SGustavo F. Padovan rcu_read_unlock(); 702bf4c6325SGustavo F. Padovan 7031da177e4SLinus Torvalds return NULL; 7041da177e4SLinus Torvalds } 7051da177e4SLinus Torvalds 7061da177e4SLinus Torvalds static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev, 7071da177e4SLinus Torvalds __u8 type, bdaddr_t *ba) 7081da177e4SLinus Torvalds { 7091da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 7101da177e4SLinus Torvalds struct hci_conn *c; 7111da177e4SLinus Torvalds 712bf4c6325SGustavo F. Padovan rcu_read_lock(); 713bf4c6325SGustavo F. Padovan 714bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 715bf4c6325SGustavo F. Padovan if (c->type == type && !bacmp(&c->dst, ba)) { 716bf4c6325SGustavo F. Padovan rcu_read_unlock(); 7171da177e4SLinus Torvalds return c; 7181da177e4SLinus Torvalds } 719bf4c6325SGustavo F. Padovan } 720bf4c6325SGustavo F. Padovan 721bf4c6325SGustavo F. Padovan rcu_read_unlock(); 722bf4c6325SGustavo F. Padovan 7231da177e4SLinus Torvalds return NULL; 7241da177e4SLinus Torvalds } 7251da177e4SLinus Torvalds 7264c67bc74SMarcel Holtmann static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev, 7274c67bc74SMarcel Holtmann __u8 type, __u16 state) 7284c67bc74SMarcel Holtmann { 7294c67bc74SMarcel Holtmann struct hci_conn_hash *h = &hdev->conn_hash; 7304c67bc74SMarcel Holtmann struct hci_conn *c; 7314c67bc74SMarcel Holtmann 732bf4c6325SGustavo F. Padovan rcu_read_lock(); 733bf4c6325SGustavo F. Padovan 734bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 735bf4c6325SGustavo F. Padovan if (c->type == type && c->state == state) { 736bf4c6325SGustavo F. Padovan rcu_read_unlock(); 7374c67bc74SMarcel Holtmann return c; 7384c67bc74SMarcel Holtmann } 739bf4c6325SGustavo F. Padovan } 740bf4c6325SGustavo F. Padovan 741bf4c6325SGustavo F. Padovan rcu_read_unlock(); 742bf4c6325SGustavo F. Padovan 7434c67bc74SMarcel Holtmann return NULL; 7444c67bc74SMarcel Holtmann } 7454c67bc74SMarcel Holtmann 746e3b679d5SJohan Hedberg int hci_disconnect(struct hci_conn *conn, __u8 reason); 7472dea632fSFrédéric Dalleau bool hci_setup_sync(struct hci_conn *conn, __u16 handle); 748e73439d8SMarcel Holtmann void hci_sco_setup(struct hci_conn *conn, __u8 status); 7491da177e4SLinus Torvalds 750a5c4e309SJohan Hedberg struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, 751a5c4e309SJohan Hedberg u8 role); 7521da177e4SLinus Torvalds int hci_conn_del(struct hci_conn *conn); 7531da177e4SLinus Torvalds void hci_conn_hash_flush(struct hci_dev *hdev); 754a9de9248SMarcel Holtmann void hci_conn_check_pending(struct hci_dev *hdev); 7551da177e4SLinus Torvalds 75673d80debSLuiz Augusto von Dentz struct hci_chan *hci_chan_create(struct hci_conn *conn); 7579472007cSAndrei Emeltchenko void hci_chan_del(struct hci_chan *chan); 7582c33c06aSGustavo F. Padovan void hci_chan_list_flush(struct hci_conn *conn); 75942c4e53eSAndrei Emeltchenko struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle); 76073d80debSLuiz Augusto von Dentz 76104a6c589SAndre Guedes struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, 762cdd6275eSJohan Hedberg u8 dst_type, u8 sec_level, u16 conn_timeout, 763e804d25dSJohan Hedberg u8 role); 76404a6c589SAndre Guedes struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, 76504a6c589SAndre Guedes u8 sec_level, u8 auth_type); 76610c62ddcSFrédéric Dalleau struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst, 76710c62ddcSFrédéric Dalleau __u16 setting); 768e7c29cb1SMarcel Holtmann int hci_conn_check_link_mode(struct hci_conn *conn); 769b3b1b061SWaldemar Rymarkiewicz int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level); 770e7cafc45SJohan Hedberg int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type, 771e7cafc45SJohan Hedberg bool initiator); 7721da177e4SLinus Torvalds int hci_conn_change_link_key(struct hci_conn *conn); 7738c1b2355SMarcel Holtmann int hci_conn_switch_role(struct hci_conn *conn, __u8 role); 7741da177e4SLinus Torvalds 77514b12d0bSJaikumar Ganesh void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); 7761da177e4SLinus Torvalds 77706c053fbSAndre Guedes void hci_le_conn_failed(struct hci_conn *conn, u8 status); 77806c053fbSAndre Guedes 7798d12356fSDavid Herrmann /* 7808d12356fSDavid Herrmann * hci_conn_get() and hci_conn_put() are used to control the life-time of an 7818d12356fSDavid Herrmann * "hci_conn" object. They do not guarantee that the hci_conn object is running, 7828d12356fSDavid Herrmann * working or anything else. They just guarantee that the object is available 7838d12356fSDavid Herrmann * and can be dereferenced. So you can use its locks, local variables and any 7848d12356fSDavid Herrmann * other constant data. 7858d12356fSDavid Herrmann * Before accessing runtime data, you _must_ lock the object and then check that 7868d12356fSDavid Herrmann * it is still running. As soon as you release the locks, the connection might 7878d12356fSDavid Herrmann * get dropped, though. 7888d12356fSDavid Herrmann * 7898d12356fSDavid Herrmann * On the other hand, hci_conn_hold() and hci_conn_drop() are used to control 7908d12356fSDavid Herrmann * how long the underlying connection is held. So every channel that runs on the 7918d12356fSDavid Herrmann * hci_conn object calls this to prevent the connection from disappearing. As 7928d12356fSDavid Herrmann * long as you hold a device, you must also guarantee that you have a valid 7938d12356fSDavid Herrmann * reference to the device via hci_conn_get() (or the initial reference from 7948d12356fSDavid Herrmann * hci_conn_add()). 7958d12356fSDavid Herrmann * The hold()/drop() ref-count is known to drop below 0 sometimes, which doesn't 7968d12356fSDavid Herrmann * break because nobody cares for that. But this means, we cannot use 7978d12356fSDavid Herrmann * _get()/_drop() in it, but require the caller to have a valid ref (FIXME). 7988d12356fSDavid Herrmann */ 7998d12356fSDavid Herrmann 80051bb8457SJohan Hedberg static inline struct hci_conn *hci_conn_get(struct hci_conn *conn) 8018d12356fSDavid Herrmann { 8028d12356fSDavid Herrmann get_device(&conn->dev); 80351bb8457SJohan Hedberg return conn; 8048d12356fSDavid Herrmann } 8058d12356fSDavid Herrmann 8068d12356fSDavid Herrmann static inline void hci_conn_put(struct hci_conn *conn) 8078d12356fSDavid Herrmann { 8088d12356fSDavid Herrmann put_device(&conn->dev); 8098d12356fSDavid Herrmann } 8108d12356fSDavid Herrmann 8111da177e4SLinus Torvalds static inline void hci_conn_hold(struct hci_conn *conn) 8121da177e4SLinus Torvalds { 81371becf0cSAndrei Emeltchenko BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt)); 81438b3fef1SAndrei Emeltchenko 8151da177e4SLinus Torvalds atomic_inc(&conn->refcnt); 8162f304d1eSAndre Guedes cancel_delayed_work(&conn->disc_work); 8171da177e4SLinus Torvalds } 8181da177e4SLinus Torvalds 81976a68ba0SDavid Herrmann static inline void hci_conn_drop(struct hci_conn *conn) 8201da177e4SLinus Torvalds { 82171becf0cSAndrei Emeltchenko BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt)); 82238b3fef1SAndrei Emeltchenko 8231da177e4SLinus Torvalds if (atomic_dec_and_test(&conn->refcnt)) { 82404837f64SMarcel Holtmann unsigned long timeo; 825716e4ab5SAndrei Emeltchenko 826716e4ab5SAndrei Emeltchenko switch (conn->type) { 827716e4ab5SAndrei Emeltchenko case ACL_LINK: 828716e4ab5SAndrei Emeltchenko case LE_LINK: 829a74a84f6SJohan Hedberg cancel_delayed_work(&conn->idle_work); 8306ac59344SMarcel Holtmann if (conn->state == BT_CONNECTED) { 8315f246e89SAndrei Emeltchenko timeo = conn->disc_timeout; 83204837f64SMarcel Holtmann if (!conn->out) 833052b30b0SMarcel Holtmann timeo *= 2; 8345a9d0a3fSWaldemar Rymarkiewicz } else { 835eb78d7e5SJohan Hedberg timeo = 0; 8365a9d0a3fSWaldemar Rymarkiewicz } 837716e4ab5SAndrei Emeltchenko break; 838716e4ab5SAndrei Emeltchenko 839716e4ab5SAndrei Emeltchenko case AMP_LINK: 840716e4ab5SAndrei Emeltchenko timeo = conn->disc_timeout; 841716e4ab5SAndrei Emeltchenko break; 842716e4ab5SAndrei Emeltchenko 843716e4ab5SAndrei Emeltchenko default: 844eb78d7e5SJohan Hedberg timeo = 0; 845716e4ab5SAndrei Emeltchenko break; 8465a9d0a3fSWaldemar Rymarkiewicz } 847716e4ab5SAndrei Emeltchenko 8482f304d1eSAndre Guedes cancel_delayed_work(&conn->disc_work); 84919c40e3bSGustavo F. Padovan queue_delayed_work(conn->hdev->workqueue, 8501931782bSVinicius Costa Gomes &conn->disc_work, timeo); 8511da177e4SLinus Torvalds } 8521da177e4SLinus Torvalds } 8531da177e4SLinus Torvalds 8541da177e4SLinus Torvalds /* ----- HCI Devices ----- */ 855dc946bd8SDavid Herrmann static inline void hci_dev_put(struct hci_dev *d) 8561da177e4SLinus Torvalds { 857376261aeSAndrei Emeltchenko BT_DBG("%s orig refcnt %d", d->name, 858376261aeSAndrei Emeltchenko atomic_read(&d->dev.kobj.kref.refcount)); 859376261aeSAndrei Emeltchenko 8604c724c71SDavid Herrmann put_device(&d->dev); 861010666a1SDavid Herrmann } 8621da177e4SLinus Torvalds 863dc946bd8SDavid Herrmann static inline struct hci_dev *hci_dev_hold(struct hci_dev *d) 8641da177e4SLinus Torvalds { 865376261aeSAndrei Emeltchenko BT_DBG("%s orig refcnt %d", d->name, 866376261aeSAndrei Emeltchenko atomic_read(&d->dev.kobj.kref.refcount)); 867376261aeSAndrei Emeltchenko 8684c724c71SDavid Herrmann get_device(&d->dev); 8691da177e4SLinus Torvalds return d; 8701da177e4SLinus Torvalds } 8711da177e4SLinus Torvalds 87209fd0de5SGustavo F. Padovan #define hci_dev_lock(d) mutex_lock(&d->lock) 87309fd0de5SGustavo F. Padovan #define hci_dev_unlock(d) mutex_unlock(&d->lock) 8741da177e4SLinus Torvalds 875aa2b86d7SDavid Herrmann #define to_hci_dev(d) container_of(d, struct hci_dev, dev) 8763dc07322SDavid Herrmann #define to_hci_conn(c) container_of(c, struct hci_conn, dev) 877aa2b86d7SDavid Herrmann 878155961e8SDavid Herrmann static inline void *hci_get_drvdata(struct hci_dev *hdev) 879155961e8SDavid Herrmann { 880155961e8SDavid Herrmann return dev_get_drvdata(&hdev->dev); 881155961e8SDavid Herrmann } 882155961e8SDavid Herrmann 883155961e8SDavid Herrmann static inline void hci_set_drvdata(struct hci_dev *hdev, void *data) 884155961e8SDavid Herrmann { 885155961e8SDavid Herrmann dev_set_drvdata(&hdev->dev, data); 886155961e8SDavid Herrmann } 887155961e8SDavid Herrmann 8881da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index); 8890c0afedfSJohan Hedberg struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src); 8901da177e4SLinus Torvalds 8911da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void); 8921da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev); 8931da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev); 89459735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev); 8951da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev); 8961da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev); 89775e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev); 8981da177e4SLinus Torvalds int hci_dev_open(__u16 dev); 8991da177e4SLinus Torvalds int hci_dev_close(__u16 dev); 9001da177e4SLinus Torvalds int hci_dev_reset(__u16 dev); 9011da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev); 9021da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg); 9031da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg); 9041da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg); 9051da177e4SLinus Torvalds int hci_get_conn_list(void __user *arg); 9061da177e4SLinus Torvalds int hci_get_conn_info(struct hci_dev *hdev, void __user *arg); 90740be492fSMarcel Holtmann int hci_get_auth_info(struct hci_dev *hdev, void __user *arg); 9081da177e4SLinus Torvalds int hci_inquiry(void __user *arg); 9091da177e4SLinus Torvalds 910dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *list, 911b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type); 912dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type); 913dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type); 914dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *list); 915d2ab0ac1SMarcel Holtmann 91615819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 91715819a70SAndre Guedes bdaddr_t *addr, u8 addr_type); 91851d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, 91951d167c0SMarcel Holtmann bdaddr_t *addr, u8 addr_type); 920bf5b3c8bSMarcel Holtmann int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, 921d06b50ceSMarcel Holtmann u8 auto_connect); 92215819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type); 923373110c5SJohan Hedberg void hci_conn_params_clear_all(struct hci_dev *hdev); 92455af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev); 92515819a70SAndre Guedes 926501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, 927501f8827SJohan Hedberg bdaddr_t *addr, 928501f8827SJohan Hedberg u8 addr_type); 92977a77a30SAndre Guedes 930a4790dbdSAndre Guedes void hci_update_background_scan(struct hci_dev *hdev); 931a4790dbdSAndre Guedes 93235f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev); 9332aeb9a1aSJohan Hedberg 93435f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev); 93555ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); 936567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, 9377652ff6aSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, 9387652ff6aSJohan Hedberg u8 pin_len, bool *persistent); 939ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 94035d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 941fe39c7b2SMarcel Holtmann u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand); 942f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 943e804d25dSJohan Hedberg u8 addr_type, u8 role); 944e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type); 94535f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev); 94655ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); 94755ed8ca1SJohan Hedberg 948970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa); 949970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 950970c4e46SJohan Hedberg u8 addr_type); 951ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 952ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa); 953a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type); 954970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev); 955970c4e46SJohan Hedberg 95635f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev); 9572763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 9586928a924SJohan Hedberg bdaddr_t *bdaddr, u8 bdaddr_type); 9590798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 9606928a924SJohan Hedberg u8 bdaddr_type, u8 *hash192, u8 *rand192, 96138da1703SJohan Hedberg u8 *hash256, u8 *rand256); 9626928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 9636928a924SJohan Hedberg u8 bdaddr_type); 9642763eda6SSzymon Janc 9651da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); 9661da177e4SLinus Torvalds 967e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb); 96899811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count); 969ef222013SMarcel Holtmann 9700ac7e700SDavid Herrmann void hci_init_sysfs(struct hci_dev *hdev); 971a67e899cSMarcel Holtmann void hci_conn_init_sysfs(struct hci_conn *conn); 972b219e3acSMarcel Holtmann void hci_conn_add_sysfs(struct hci_conn *conn); 973b219e3acSMarcel Holtmann void hci_conn_del_sysfs(struct hci_conn *conn); 9741da177e4SLinus Torvalds 9756935e0f5SDavid Herrmann #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev)) 9761da177e4SLinus Torvalds 9771da177e4SLinus Torvalds /* ----- LMP capabilities ----- */ 978cad718edSJohan Hedberg #define lmp_encrypt_capable(dev) ((dev)->features[0][0] & LMP_ENCRYPT) 979cad718edSJohan Hedberg #define lmp_rswitch_capable(dev) ((dev)->features[0][0] & LMP_RSWITCH) 980cad718edSJohan Hedberg #define lmp_hold_capable(dev) ((dev)->features[0][0] & LMP_HOLD) 981cad718edSJohan Hedberg #define lmp_sniff_capable(dev) ((dev)->features[0][0] & LMP_SNIFF) 982cad718edSJohan Hedberg #define lmp_park_capable(dev) ((dev)->features[0][1] & LMP_PARK) 983cad718edSJohan Hedberg #define lmp_inq_rssi_capable(dev) ((dev)->features[0][3] & LMP_RSSI_INQ) 984cad718edSJohan Hedberg #define lmp_esco_capable(dev) ((dev)->features[0][3] & LMP_ESCO) 985cad718edSJohan Hedberg #define lmp_bredr_capable(dev) (!((dev)->features[0][4] & LMP_NO_BREDR)) 986cad718edSJohan Hedberg #define lmp_le_capable(dev) ((dev)->features[0][4] & LMP_LE) 987cad718edSJohan Hedberg #define lmp_sniffsubr_capable(dev) ((dev)->features[0][5] & LMP_SNIFF_SUBR) 988cad718edSJohan Hedberg #define lmp_pause_enc_capable(dev) ((dev)->features[0][5] & LMP_PAUSE_ENC) 989cad718edSJohan Hedberg #define lmp_ext_inq_capable(dev) ((dev)->features[0][6] & LMP_EXT_INQ) 990cad718edSJohan Hedberg #define lmp_le_br_capable(dev) (!!((dev)->features[0][6] & LMP_SIMUL_LE_BR)) 991cad718edSJohan Hedberg #define lmp_ssp_capable(dev) ((dev)->features[0][6] & LMP_SIMPLE_PAIR) 992cad718edSJohan Hedberg #define lmp_no_flush_capable(dev) ((dev)->features[0][6] & LMP_NO_FLUSH) 993cad718edSJohan Hedberg #define lmp_lsto_capable(dev) ((dev)->features[0][7] & LMP_LSTO) 994cad718edSJohan Hedberg #define lmp_inq_tx_pwr_capable(dev) ((dev)->features[0][7] & LMP_INQ_TX_PWR) 995cad718edSJohan Hedberg #define lmp_ext_feat_capable(dev) ((dev)->features[0][7] & LMP_EXTFEATURES) 99607a5c61eSFrédéric Dalleau #define lmp_transp_capable(dev) ((dev)->features[0][2] & LMP_TRANSPARENT) 9971da177e4SLinus Torvalds 998eead27daSAndre Guedes /* ----- Extended LMP capabilities ----- */ 99953b834d2SMarcel Holtmann #define lmp_csb_master_capable(dev) ((dev)->features[2][0] & LMP_CSB_MASTER) 100053b834d2SMarcel Holtmann #define lmp_csb_slave_capable(dev) ((dev)->features[2][0] & LMP_CSB_SLAVE) 100153b834d2SMarcel Holtmann #define lmp_sync_train_capable(dev) ((dev)->features[2][0] & LMP_SYNC_TRAIN) 100253b834d2SMarcel Holtmann #define lmp_sync_scan_capable(dev) ((dev)->features[2][0] & LMP_SYNC_SCAN) 1003d5991585SMarcel Holtmann #define lmp_sc_capable(dev) ((dev)->features[2][1] & LMP_SC) 1004d5991585SMarcel Holtmann #define lmp_ping_capable(dev) ((dev)->features[2][1] & LMP_PING) 100553b834d2SMarcel Holtmann 100653b834d2SMarcel Holtmann /* ----- Host capabilities ----- */ 1007cad718edSJohan Hedberg #define lmp_host_ssp_capable(dev) ((dev)->features[1][0] & LMP_HOST_SSP) 1008d5991585SMarcel Holtmann #define lmp_host_sc_capable(dev) ((dev)->features[1][0] & LMP_HOST_SC) 1009cad718edSJohan Hedberg #define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE)) 1010cad718edSJohan Hedberg #define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR)) 1011eead27daSAndre Guedes 1012432df05eSJohan Hedberg #define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \ 1013432df05eSJohan Hedberg !test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) 1014710f11c0SJohan Hedberg #define bredr_sc_enabled(dev) ((lmp_sc_capable(dev) || \ 1015710f11c0SJohan Hedberg test_bit(HCI_FORCE_SC, &(dev)->dbg_flags)) && \ 1016710f11c0SJohan Hedberg test_bit(HCI_SC_ENABLED, &(dev)->dev_flags)) 1017432df05eSJohan Hedberg 10181da177e4SLinus Torvalds /* ----- HCI protocols ----- */ 101920714bfeSFrédéric Dalleau #define HCI_PROTO_DEFER 0x01 102020714bfeSFrédéric Dalleau 10215a9d0a3fSWaldemar Rymarkiewicz static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, 102220714bfeSFrédéric Dalleau __u8 type, __u8 *flags) 10231da177e4SLinus Torvalds { 1024686ebf28SUlisses Furquim switch (type) { 1025686ebf28SUlisses Furquim case ACL_LINK: 1026686ebf28SUlisses Furquim return l2cap_connect_ind(hdev, bdaddr); 10271da177e4SLinus Torvalds 1028686ebf28SUlisses Furquim case SCO_LINK: 1029686ebf28SUlisses Furquim case ESCO_LINK: 103020714bfeSFrédéric Dalleau return sco_connect_ind(hdev, bdaddr, flags); 10311da177e4SLinus Torvalds 1032686ebf28SUlisses Furquim default: 1033686ebf28SUlisses Furquim BT_ERR("unknown link type %d", type); 1034686ebf28SUlisses Furquim return -EINVAL; 1035686ebf28SUlisses Furquim } 10361da177e4SLinus Torvalds } 10371da177e4SLinus Torvalds 10381da177e4SLinus Torvalds static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status) 10391da177e4SLinus Torvalds { 1040686ebf28SUlisses Furquim switch (conn->type) { 1041686ebf28SUlisses Furquim case ACL_LINK: 1042686ebf28SUlisses Furquim case LE_LINK: 1043686ebf28SUlisses Furquim l2cap_connect_cfm(conn, status); 1044686ebf28SUlisses Furquim break; 10451da177e4SLinus Torvalds 1046686ebf28SUlisses Furquim case SCO_LINK: 1047686ebf28SUlisses Furquim case ESCO_LINK: 1048686ebf28SUlisses Furquim sco_connect_cfm(conn, status); 1049686ebf28SUlisses Furquim break; 10501da177e4SLinus Torvalds 1051686ebf28SUlisses Furquim default: 1052686ebf28SUlisses Furquim BT_ERR("unknown link type %d", conn->type); 1053686ebf28SUlisses Furquim break; 1054686ebf28SUlisses Furquim } 1055e9a416b5SJohan Hedberg 1056e9a416b5SJohan Hedberg if (conn->connect_cfm_cb) 1057e9a416b5SJohan Hedberg conn->connect_cfm_cb(conn, status); 10581da177e4SLinus Torvalds } 10591da177e4SLinus Torvalds 10602950f21aSMarcel Holtmann static inline int hci_proto_disconn_ind(struct hci_conn *conn) 10612950f21aSMarcel Holtmann { 1062686ebf28SUlisses Furquim if (conn->type != ACL_LINK && conn->type != LE_LINK) 1063686ebf28SUlisses Furquim return HCI_ERROR_REMOTE_USER_TERM; 10642950f21aSMarcel Holtmann 1065686ebf28SUlisses Furquim return l2cap_disconn_ind(conn); 10662950f21aSMarcel Holtmann } 10672950f21aSMarcel Holtmann 10682950f21aSMarcel Holtmann static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason) 10691da177e4SLinus Torvalds { 1070686ebf28SUlisses Furquim switch (conn->type) { 1071686ebf28SUlisses Furquim case ACL_LINK: 1072686ebf28SUlisses Furquim case LE_LINK: 1073686ebf28SUlisses Furquim l2cap_disconn_cfm(conn, reason); 1074686ebf28SUlisses Furquim break; 10751da177e4SLinus Torvalds 1076686ebf28SUlisses Furquim case SCO_LINK: 1077686ebf28SUlisses Furquim case ESCO_LINK: 1078686ebf28SUlisses Furquim sco_disconn_cfm(conn, reason); 1079686ebf28SUlisses Furquim break; 10801da177e4SLinus Torvalds 1081bd1eb66bSAndrei Emeltchenko /* L2CAP would be handled for BREDR chan */ 1082bd1eb66bSAndrei Emeltchenko case AMP_LINK: 1083bd1eb66bSAndrei Emeltchenko break; 1084bd1eb66bSAndrei Emeltchenko 1085686ebf28SUlisses Furquim default: 1086686ebf28SUlisses Furquim BT_ERR("unknown link type %d", conn->type); 1087686ebf28SUlisses Furquim break; 1088686ebf28SUlisses Furquim } 1089e9a416b5SJohan Hedberg 1090e9a416b5SJohan Hedberg if (conn->disconn_cfm_cb) 1091e9a416b5SJohan Hedberg conn->disconn_cfm_cb(conn, reason); 10921da177e4SLinus Torvalds } 10931da177e4SLinus Torvalds 10941da177e4SLinus Torvalds static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) 10951da177e4SLinus Torvalds { 10968c1b2355SMarcel Holtmann __u8 encrypt; 10978c1b2355SMarcel Holtmann 1098686ebf28SUlisses Furquim if (conn->type != ACL_LINK && conn->type != LE_LINK) 1099686ebf28SUlisses Furquim return; 1100686ebf28SUlisses Furquim 110151a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) 11028c1b2355SMarcel Holtmann return; 11038c1b2355SMarcel Holtmann 11044dae2798SJohan Hedberg encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00; 1105686ebf28SUlisses Furquim l2cap_security_cfm(conn, status, encrypt); 1106e9a416b5SJohan Hedberg 1107e9a416b5SJohan Hedberg if (conn->security_cfm_cb) 1108e9a416b5SJohan Hedberg conn->security_cfm_cb(conn, status); 11091da177e4SLinus Torvalds } 11101da177e4SLinus Torvalds 11115a9d0a3fSWaldemar Rymarkiewicz static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, 11125a9d0a3fSWaldemar Rymarkiewicz __u8 encrypt) 11131da177e4SLinus Torvalds { 1114686ebf28SUlisses Furquim if (conn->type != ACL_LINK && conn->type != LE_LINK) 1115686ebf28SUlisses Furquim return; 11161da177e4SLinus Torvalds 1117686ebf28SUlisses Furquim l2cap_security_cfm(conn, status, encrypt); 1118e9a416b5SJohan Hedberg 1119e9a416b5SJohan Hedberg if (conn->security_cfm_cb) 1120e9a416b5SJohan Hedberg conn->security_cfm_cb(conn, status); 11211da177e4SLinus Torvalds } 11221da177e4SLinus Torvalds 11231da177e4SLinus Torvalds /* ----- HCI callbacks ----- */ 11241da177e4SLinus Torvalds struct hci_cb { 11251da177e4SLinus Torvalds struct list_head list; 11261da177e4SLinus Torvalds 11271da177e4SLinus Torvalds char *name; 11281da177e4SLinus Torvalds 11295a9d0a3fSWaldemar Rymarkiewicz void (*security_cfm) (struct hci_conn *conn, __u8 status, 11305a9d0a3fSWaldemar Rymarkiewicz __u8 encrypt); 11311da177e4SLinus Torvalds void (*key_change_cfm) (struct hci_conn *conn, __u8 status); 11321da177e4SLinus Torvalds void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role); 11331da177e4SLinus Torvalds }; 11341da177e4SLinus Torvalds 11351da177e4SLinus Torvalds static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) 11361da177e4SLinus Torvalds { 1137711584eaSDenis Kirjanov struct hci_cb *cb; 11388c1b2355SMarcel Holtmann __u8 encrypt; 11391da177e4SLinus Torvalds 11401da177e4SLinus Torvalds hci_proto_auth_cfm(conn, status); 11411da177e4SLinus Torvalds 114251a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) 11438c1b2355SMarcel Holtmann return; 11448c1b2355SMarcel Holtmann 11454dae2798SJohan Hedberg encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00; 11468c1b2355SMarcel Holtmann 1147f20d09d5SGustavo F. Padovan read_lock(&hci_cb_list_lock); 1148711584eaSDenis Kirjanov list_for_each_entry(cb, &hci_cb_list, list) { 11498c1b2355SMarcel Holtmann if (cb->security_cfm) 11508c1b2355SMarcel Holtmann cb->security_cfm(conn, status, encrypt); 11511da177e4SLinus Torvalds } 1152f20d09d5SGustavo F. Padovan read_unlock(&hci_cb_list_lock); 11531da177e4SLinus Torvalds } 11541da177e4SLinus Torvalds 11555a9d0a3fSWaldemar Rymarkiewicz static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, 11565a9d0a3fSWaldemar Rymarkiewicz __u8 encrypt) 11571da177e4SLinus Torvalds { 1158711584eaSDenis Kirjanov struct hci_cb *cb; 11591da177e4SLinus Torvalds 1160435fef20SMarcel Holtmann if (conn->sec_level == BT_SECURITY_SDP) 1161435fef20SMarcel Holtmann conn->sec_level = BT_SECURITY_LOW; 1162435fef20SMarcel Holtmann 116388167aedSVinicius Costa Gomes if (conn->pending_sec_level > conn->sec_level) 116488167aedSVinicius Costa Gomes conn->sec_level = conn->pending_sec_level; 116588167aedSVinicius Costa Gomes 11669719f8afSMarcel Holtmann hci_proto_encrypt_cfm(conn, status, encrypt); 11671da177e4SLinus Torvalds 1168f20d09d5SGustavo F. Padovan read_lock(&hci_cb_list_lock); 1169711584eaSDenis Kirjanov list_for_each_entry(cb, &hci_cb_list, list) { 11708c1b2355SMarcel Holtmann if (cb->security_cfm) 11718c1b2355SMarcel Holtmann cb->security_cfm(conn, status, encrypt); 11721da177e4SLinus Torvalds } 1173f20d09d5SGustavo F. Padovan read_unlock(&hci_cb_list_lock); 11741da177e4SLinus Torvalds } 11751da177e4SLinus Torvalds 11761da177e4SLinus Torvalds static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) 11771da177e4SLinus Torvalds { 1178711584eaSDenis Kirjanov struct hci_cb *cb; 11791da177e4SLinus Torvalds 1180f20d09d5SGustavo F. Padovan read_lock(&hci_cb_list_lock); 1181711584eaSDenis Kirjanov list_for_each_entry(cb, &hci_cb_list, list) { 11821da177e4SLinus Torvalds if (cb->key_change_cfm) 11831da177e4SLinus Torvalds cb->key_change_cfm(conn, status); 11841da177e4SLinus Torvalds } 1185f20d09d5SGustavo F. Padovan read_unlock(&hci_cb_list_lock); 11861da177e4SLinus Torvalds } 11871da177e4SLinus Torvalds 11885a9d0a3fSWaldemar Rymarkiewicz static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, 11895a9d0a3fSWaldemar Rymarkiewicz __u8 role) 11901da177e4SLinus Torvalds { 1191711584eaSDenis Kirjanov struct hci_cb *cb; 11921da177e4SLinus Torvalds 1193f20d09d5SGustavo F. Padovan read_lock(&hci_cb_list_lock); 1194711584eaSDenis Kirjanov list_for_each_entry(cb, &hci_cb_list, list) { 11951da177e4SLinus Torvalds if (cb->role_switch_cfm) 11961da177e4SLinus Torvalds cb->role_switch_cfm(conn, status, role); 11971da177e4SLinus Torvalds } 1198f20d09d5SGustavo F. Padovan read_unlock(&hci_cb_list_lock); 11991da177e4SLinus Torvalds } 12001da177e4SLinus Torvalds 12016759a675SJohan Hedberg static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type) 12026759a675SJohan Hedberg { 120384d9d071SJohan Hedberg size_t parsed = 0; 12046759a675SJohan Hedberg 12056c0c331eSJohan Hedberg if (data_len < 2) 12066c0c331eSJohan Hedberg return false; 12076c0c331eSJohan Hedberg 120884d9d071SJohan Hedberg while (parsed < data_len - 1) { 120984d9d071SJohan Hedberg u8 field_len = data[0]; 12106759a675SJohan Hedberg 12116759a675SJohan Hedberg if (field_len == 0) 12126759a675SJohan Hedberg break; 12136759a675SJohan Hedberg 12146759a675SJohan Hedberg parsed += field_len + 1; 12156759a675SJohan Hedberg 12166759a675SJohan Hedberg if (parsed > data_len) 12176759a675SJohan Hedberg break; 12186759a675SJohan Hedberg 12196759a675SJohan Hedberg if (data[1] == type) 12206759a675SJohan Hedberg return true; 12216759a675SJohan Hedberg 12226759a675SJohan Hedberg data += field_len + 1; 12236759a675SJohan Hedberg } 12246759a675SJohan Hedberg 12256759a675SJohan Hedberg return false; 12266759a675SJohan Hedberg } 12276759a675SJohan Hedberg 1228301cb2d8SJohan Hedberg static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type) 1229301cb2d8SJohan Hedberg { 1230dbbfa2abSAndre Guedes if (addr_type != ADDR_LE_DEV_RANDOM) 1231301cb2d8SJohan Hedberg return false; 1232301cb2d8SJohan Hedberg 1233301cb2d8SJohan Hedberg if ((bdaddr->b[5] & 0xc0) == 0x40) 1234301cb2d8SJohan Hedberg return true; 1235301cb2d8SJohan Hedberg 1236301cb2d8SJohan Hedberg return false; 1237301cb2d8SJohan Hedberg } 1238301cb2d8SJohan Hedberg 1239c46245b3SJohan Hedberg static inline bool hci_is_identity_address(bdaddr_t *addr, u8 addr_type) 1240c46245b3SJohan Hedberg { 1241c46245b3SJohan Hedberg if (addr_type == ADDR_LE_DEV_PUBLIC) 1242c46245b3SJohan Hedberg return true; 1243c46245b3SJohan Hedberg 1244c46245b3SJohan Hedberg /* Check for Random Static address type */ 1245c46245b3SJohan Hedberg if ((addr->b[5] & 0xc0) == 0xc0) 1246c46245b3SJohan Hedberg return true; 1247c46245b3SJohan Hedberg 1248c46245b3SJohan Hedberg return false; 1249c46245b3SJohan Hedberg } 1250c46245b3SJohan Hedberg 12512426f3a5SJohan Hedberg static inline struct smp_irk *hci_get_irk(struct hci_dev *hdev, 12522426f3a5SJohan Hedberg bdaddr_t *bdaddr, u8 addr_type) 12532426f3a5SJohan Hedberg { 12542426f3a5SJohan Hedberg if (!hci_bdaddr_is_rpa(bdaddr, addr_type)) 12552426f3a5SJohan Hedberg return NULL; 12562426f3a5SJohan Hedberg 12572426f3a5SJohan Hedberg return hci_find_irk_by_rpa(hdev, bdaddr); 12582426f3a5SJohan Hedberg } 12592426f3a5SJohan Hedberg 1260d4905f24SAndre Guedes static inline int hci_check_conn_params(u16 min, u16 max, u16 latency, 1261d4905f24SAndre Guedes u16 to_multiplier) 1262d4905f24SAndre Guedes { 1263d4905f24SAndre Guedes u16 max_latency; 1264d4905f24SAndre Guedes 1265d4905f24SAndre Guedes if (min > max || min < 6 || max > 3200) 1266d4905f24SAndre Guedes return -EINVAL; 1267d4905f24SAndre Guedes 1268d4905f24SAndre Guedes if (to_multiplier < 10 || to_multiplier > 3200) 1269d4905f24SAndre Guedes return -EINVAL; 1270d4905f24SAndre Guedes 1271d4905f24SAndre Guedes if (max >= to_multiplier * 8) 1272d4905f24SAndre Guedes return -EINVAL; 1273d4905f24SAndre Guedes 1274d4905f24SAndre Guedes max_latency = (to_multiplier * 8 / max) - 1; 1275d4905f24SAndre Guedes if (latency > 499 || latency > max_latency) 1276d4905f24SAndre Guedes return -EINVAL; 1277d4905f24SAndre Guedes 1278d4905f24SAndre Guedes return 0; 1279d4905f24SAndre Guedes } 1280d4905f24SAndre Guedes 12811da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *hcb); 12821da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *hcb); 12831da177e4SLinus Torvalds 12843119ae95SJohan Hedberg struct hci_request { 12853119ae95SJohan Hedberg struct hci_dev *hdev; 12863119ae95SJohan Hedberg struct sk_buff_head cmd_q; 12875d73e034SAndre Guedes 12885d73e034SAndre Guedes /* If something goes wrong when building the HCI request, the error 12895d73e034SAndre Guedes * value is stored in this field. 12905d73e034SAndre Guedes */ 12915d73e034SAndre Guedes int err; 12923119ae95SJohan Hedberg }; 12933119ae95SJohan Hedberg 12943119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev); 12953119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete); 129607dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, 129707dc93ddSJohan Hedberg const void *param); 129807dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, 129907dc93ddSJohan Hedberg const void *param, u8 event); 13009238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); 1301899de765SMarcel Holtmann bool hci_req_pending(struct hci_dev *hdev); 13023119ae95SJohan Hedberg 1303b1efcc28SAndre Guedes void hci_req_add_le_scan_disable(struct hci_request *req); 13048ef30fd3SAndre Guedes void hci_req_add_le_passive_scan(struct hci_request *req); 1305b1efcc28SAndre Guedes 1306432df05eSJohan Hedberg void hci_update_page_scan(struct hci_dev *hdev, struct hci_request *req); 1307432df05eSJohan Hedberg 130875e84b7cSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 130907dc93ddSJohan Hedberg const void *param, u32 timeout); 13107b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 131107dc93ddSJohan Hedberg const void *param, u8 event, u32 timeout); 131275e84b7cSJohan Hedberg 131307dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 131407dc93ddSJohan Hedberg const void *param); 131573d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); 13160d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); 13171da177e4SLinus Torvalds 1318a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); 13191da177e4SLinus Torvalds 13201da177e4SLinus Torvalds /* ----- HCI Sockets ----- */ 1321470fe1b5SMarcel Holtmann void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); 1322470fe1b5SMarcel Holtmann void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk); 1323cd82e61cSMarcel Holtmann void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb); 13241da177e4SLinus Torvalds 1325040030efSMarcel Holtmann void hci_sock_dev_event(struct hci_dev *hdev, int event); 1326040030efSMarcel Holtmann 13270381101fSJohan Hedberg /* Management interface */ 1328591f47f3SAndre Guedes #define DISCOV_TYPE_BREDR (BIT(BDADDR_BREDR)) 1329591f47f3SAndre Guedes #define DISCOV_TYPE_LE (BIT(BDADDR_LE_PUBLIC) | \ 1330591f47f3SAndre Guedes BIT(BDADDR_LE_RANDOM)) 1331591f47f3SAndre Guedes #define DISCOV_TYPE_INTERLEAVED (BIT(BDADDR_BREDR) | \ 1332591f47f3SAndre Guedes BIT(BDADDR_LE_PUBLIC) | \ 1333591f47f3SAndre Guedes BIT(BDADDR_LE_RANDOM)) 1334f39799f5SAndre Guedes 13350d8cc935SAndre Guedes /* These LE scan and inquiry parameters were chosen according to LE General 13360d8cc935SAndre Guedes * Discovery Procedure specification. 13370d8cc935SAndre Guedes */ 13380d8cc935SAndre Guedes #define DISCOV_LE_SCAN_WIN 0x12 13390d8cc935SAndre Guedes #define DISCOV_LE_SCAN_INT 0x12 13403d5a76f0SLukasz Rymanowski #define DISCOV_LE_TIMEOUT 10240 /* msec */ 1341ae55f598SLukasz Rymanowski #define DISCOV_INTERLEAVED_TIMEOUT 5120 /* msec */ 13420d8cc935SAndre Guedes #define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04 13430d8cc935SAndre Guedes #define DISCOV_BREDR_INQUIRY_LEN 0x08 13440d8cc935SAndre Guedes 13450381101fSJohan Hedberg int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); 134691a668b0SJohan Hedberg int mgmt_new_settings(struct hci_dev *hdev); 1347bf6b56dbSMarcel Holtmann void mgmt_index_added(struct hci_dev *hdev); 1348bf6b56dbSMarcel Holtmann void mgmt_index_removed(struct hci_dev *hdev); 13493eec705eSMarcel Holtmann void mgmt_set_powered_failed(struct hci_dev *hdev, int err); 1350744cf19eSJohan Hedberg int mgmt_powered(struct hci_dev *hdev, u8 powered); 1351bc6d2d04SJohan Hedberg int mgmt_update_adv_data(struct hci_dev *hdev); 1352d1967ff8SMarcel Holtmann void mgmt_discoverable_timeout(struct hci_dev *hdev); 1353dc4a5ee2SMarcel Holtmann void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, 1354745c0ce3SVishal Agarwal bool persistent); 135548ec92faSAlfonso Acosta void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, 135648ec92faSAlfonso Acosta u32 flags, u8 *name, u8 name_len); 13579b80ec5eSMarcel Holtmann void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, 135812d4a3b2SJohan Hedberg u8 link_type, u8 addr_type, u8 reason, 135912d4a3b2SJohan Hedberg bool mgmt_connected); 13607892924cSMarcel Holtmann void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, 136188c3df13SJohan Hedberg u8 link_type, u8 addr_type, u8 status); 1362445608d0SMarcel Holtmann void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 136348264f06SJohan Hedberg u8 addr_type, u8 status); 1364ce0e4a0dSMarcel Holtmann void mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure); 1365e669cf80SMarcel Holtmann void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1366c35938b2SSzymon Janc u8 status); 13673eb38528SMarcel Holtmann void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1368744cf19eSJohan Hedberg u8 status); 1369744cf19eSJohan Hedberg int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, 137039adbffeSJohan Hedberg u8 link_type, u8 addr_type, u32 value, 1371272d90dfSJohan Hedberg u8 confirm_hint); 1372744cf19eSJohan Hedberg int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1373272d90dfSJohan Hedberg u8 link_type, u8 addr_type, u8 status); 1374272d90dfSJohan Hedberg int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1375272d90dfSJohan Hedberg u8 link_type, u8 addr_type, u8 status); 1376272d90dfSJohan Hedberg int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr, 1377272d90dfSJohan Hedberg u8 link_type, u8 addr_type); 1378604086b7SBrian Gix int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1379272d90dfSJohan Hedberg u8 link_type, u8 addr_type, u8 status); 1380272d90dfSJohan Hedberg int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1381272d90dfSJohan Hedberg u8 link_type, u8 addr_type, u8 status); 138292a25256SJohan Hedberg int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr, 138392a25256SJohan Hedberg u8 link_type, u8 addr_type, u32 passkey, 138492a25256SJohan Hedberg u8 entered); 1385e1e930f5SJohan Hedberg void mgmt_auth_failed(struct hci_conn *conn, u8 status); 1386464996aeSMarcel Holtmann void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status); 13873e248560SMarcel Holtmann void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); 1388eac83dc6SMarcel Holtmann void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); 13894e1b0245SMarcel Holtmann void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, 13907f9a903cSMarcel Holtmann u8 status); 13917667da34SMarcel Holtmann void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status); 13924d2d2796SMarcel Holtmann void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, 139338da1703SJohan Hedberg u8 *rand192, u8 *hash256, u8 *rand256, 139438da1703SJohan Hedberg u8 status); 1395901801b9SMarcel Holtmann void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 1396af58925cSMarcel Holtmann u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, 1397af58925cSMarcel Holtmann u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len); 13989cf12aeeSMarcel Holtmann void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 1399b644ba33SJohan Hedberg u8 addr_type, s8 rssi, u8 *name, u8 name_len); 14002f1e063bSMarcel Holtmann void mgmt_discovering(struct hci_dev *hdev, u8 discovering); 140184c61d92SJohan Hedberg bool mgmt_powering_down(struct hci_dev *hdev); 140253ac6ab6SMarcel Holtmann void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent); 140395fbac8aSJohan Hedberg void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk); 140453ac6ab6SMarcel Holtmann void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk, 140553ac6ab6SMarcel Holtmann bool persistent); 1406ffb5a827SAndre Guedes void mgmt_new_conn_param(struct hci_dev *hdev, bdaddr_t *bdaddr, 1407f4869e2aSJohan Hedberg u8 bdaddr_type, u8 store_hint, u16 min_interval, 1408f4869e2aSJohan Hedberg u16 max_interval, u16 latency, u16 timeout); 14095976e608SMarcel Holtmann void mgmt_reenable_advertising(struct hci_dev *hdev); 1410f4a407beSJohan Hedberg void mgmt_smp_complete(struct hci_conn *conn, bool complete); 1411346af67bSVinicius Costa Gomes 14127d6ca693SJohan Hedberg u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency, 14137d6ca693SJohan Hedberg u16 to_multiplier); 1414fe39c7b2SMarcel Holtmann void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand, 1415a7a595f6SVinicius Costa Gomes __u8 ltk[16]); 14162519a1fcSAndre Guedes 141794b1fc92SMarcel Holtmann int hci_update_random_address(struct hci_request *req, bool require_privacy, 141894b1fc92SMarcel Holtmann u8 *own_addr_type); 1419a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, 1420a1f4c318SJohan Hedberg u8 *bdaddr_type); 1421ebd3a747SJohan Hedberg 14225d4d62f6SFrédéric Dalleau #define SCO_AIRMODE_MASK 0x0003 14235d4d62f6SFrédéric Dalleau #define SCO_AIRMODE_CVSD 0x0000 14245d4d62f6SFrédéric Dalleau #define SCO_AIRMODE_TRANSP 0x0003 14255d4d62f6SFrédéric Dalleau 14261da177e4SLinus Torvalds #endif /* __HCI_CORE_H */ 1427