diff options
Diffstat (limited to 'include/net/bluetooth')
| -rw-r--r-- | include/net/bluetooth/a2mp.h | 150 | ||||
| -rw-r--r-- | include/net/bluetooth/amp.h | 54 | ||||
| -rw-r--r-- | include/net/bluetooth/bluetooth.h | 31 | ||||
| -rw-r--r-- | include/net/bluetooth/hci.h | 263 | ||||
| -rw-r--r-- | include/net/bluetooth/hci_core.h | 401 | ||||
| -rw-r--r-- | include/net/bluetooth/l2cap.h | 89 | ||||
| -rw-r--r-- | include/net/bluetooth/mgmt.h | 96 | ||||
| -rw-r--r-- | include/net/bluetooth/rfcomm.h | 22 | ||||
| -rw-r--r-- | include/net/bluetooth/sco.h | 5 | ||||
| -rw-r--r-- | include/net/bluetooth/smp.h | 146 | 
10 files changed, 707 insertions, 550 deletions
diff --git a/include/net/bluetooth/a2mp.h b/include/net/bluetooth/a2mp.h deleted file mode 100644 index 487b54c1308..00000000000 --- a/include/net/bluetooth/a2mp.h +++ /dev/null @@ -1,150 +0,0 @@ -/* -   Copyright (c) 2010,2011 Code Aurora Forum.  All rights reserved. -   Copyright (c) 2011,2012 Intel Corp. - -   This program is free software; you can redistribute it and/or modify -   it under the terms of the GNU General Public License version 2 and -   only version 2 as published by the Free Software Foundation. - -   This program is distributed in the hope that it will be useful, -   but WITHOUT ANY WARRANTY; without even the implied warranty of -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -   GNU General Public License for more details. -*/ - -#ifndef __A2MP_H -#define __A2MP_H - -#include <net/bluetooth/l2cap.h> - -#define A2MP_FEAT_EXT	0x8000 - -enum amp_mgr_state { -	READ_LOC_AMP_INFO, -	READ_LOC_AMP_ASSOC, -	READ_LOC_AMP_ASSOC_FINAL, -	WRITE_REMOTE_AMP_ASSOC, -}; - -struct amp_mgr { -	struct list_head	list; -	struct l2cap_conn	*l2cap_conn; -	struct l2cap_chan	*a2mp_chan; -	struct l2cap_chan	*bredr_chan; -	struct kref		kref; -	__u8			ident; -	__u8			handle; -	unsigned long		state; -	unsigned long		flags; - -	struct list_head	amp_ctrls; -	struct mutex		amp_ctrls_lock; -}; - -struct a2mp_cmd { -	__u8	code; -	__u8	ident; -	__le16	len; -	__u8	data[0]; -} __packed; - -/* A2MP command codes */ -#define A2MP_COMMAND_REJ         0x01 -struct a2mp_cmd_rej { -	__le16	reason; -	__u8	data[0]; -} __packed; - -#define A2MP_DISCOVER_REQ        0x02 -struct a2mp_discov_req { -	__le16	mtu; -	__le16	ext_feat; -} __packed; - -struct a2mp_cl { -	__u8	id; -	__u8	type; -	__u8	status; -} __packed; - -#define A2MP_DISCOVER_RSP        0x03 -struct a2mp_discov_rsp { -	__le16     mtu; -	__le16     ext_feat; -	struct a2mp_cl cl[0]; -} __packed; - -#define A2MP_CHANGE_NOTIFY       0x04 -#define A2MP_CHANGE_RSP          0x05 - -#define A2MP_GETINFO_REQ         0x06 -struct a2mp_info_req { -	__u8       id; -} __packed; - -#define A2MP_GETINFO_RSP         0x07 -struct a2mp_info_rsp { -	__u8	id; -	__u8	status; -	__le32	total_bw; -	__le32	max_bw; -	__le32	min_latency; -	__le16	pal_cap; -	__le16	assoc_size; -} __packed; - -#define A2MP_GETAMPASSOC_REQ     0x08 -struct a2mp_amp_assoc_req { -	__u8	id; -} __packed; - -#define A2MP_GETAMPASSOC_RSP     0x09 -struct a2mp_amp_assoc_rsp { -	__u8	id; -	__u8	status; -	__u8	amp_assoc[0]; -} __packed; - -#define A2MP_CREATEPHYSLINK_REQ  0x0A -#define A2MP_DISCONNPHYSLINK_REQ 0x0C -struct a2mp_physlink_req { -	__u8	local_id; -	__u8	remote_id; -	__u8	amp_assoc[0]; -} __packed; - -#define A2MP_CREATEPHYSLINK_RSP  0x0B -#define A2MP_DISCONNPHYSLINK_RSP 0x0D -struct a2mp_physlink_rsp { -	__u8	local_id; -	__u8	remote_id; -	__u8	status; -} __packed; - -/* A2MP response status */ -#define A2MP_STATUS_SUCCESS			0x00 -#define A2MP_STATUS_INVALID_CTRL_ID		0x01 -#define A2MP_STATUS_UNABLE_START_LINK_CREATION	0x02 -#define A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS	0x02 -#define A2MP_STATUS_COLLISION_OCCURED		0x03 -#define A2MP_STATUS_DISCONN_REQ_RECVD		0x04 -#define A2MP_STATUS_PHYS_LINK_EXISTS		0x05 -#define A2MP_STATUS_SECURITY_VIOLATION		0x06 - -extern struct list_head amp_mgr_list; -extern struct mutex amp_mgr_list_lock; - -struct amp_mgr *amp_mgr_get(struct amp_mgr *mgr); -int amp_mgr_put(struct amp_mgr *mgr); -u8 __next_ident(struct amp_mgr *mgr); -struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, -				       struct sk_buff *skb); -struct amp_mgr *amp_mgr_lookup_by_state(u8 state); -void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data); -void a2mp_discover_amp(struct l2cap_chan *chan); -void a2mp_send_getinfo_rsp(struct hci_dev *hdev); -void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status); -void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status); -void a2mp_send_create_phy_link_rsp(struct hci_dev *hdev, u8 status); - -#endif /* __A2MP_H */ diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h deleted file mode 100644 index 7ea3db77ba8..00000000000 --- a/include/net/bluetooth/amp.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -   Copyright (c) 2011,2012 Intel Corp. - -   This program is free software; you can redistribute it and/or modify -   it under the terms of the GNU General Public License version 2 and -   only version 2 as published by the Free Software Foundation. - -   This program is distributed in the hope that it will be useful, -   but WITHOUT ANY WARRANTY; without even the implied warranty of -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -   GNU General Public License for more details. -*/ - -#ifndef __AMP_H -#define __AMP_H - -struct amp_ctrl { -	struct list_head	list; -	struct kref		kref; -	__u8			id; -	__u16			assoc_len_so_far; -	__u16			assoc_rem_len; -	__u16			assoc_len; -	__u8			*assoc; -}; - -int amp_ctrl_put(struct amp_ctrl *ctrl); -void amp_ctrl_get(struct amp_ctrl *ctrl); -struct amp_ctrl *amp_ctrl_add(struct amp_mgr *mgr, u8 id); -struct amp_ctrl *amp_ctrl_lookup(struct amp_mgr *mgr, u8 id); -void amp_ctrl_list_flush(struct amp_mgr *mgr); - -struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr, -			     u8 remote_id, bool out); - -int phylink_gen_key(struct hci_conn *hcon, u8 *data, u8 *len, u8 *type); - -void amp_read_loc_info(struct hci_dev *hdev, struct amp_mgr *mgr); -void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle); -void amp_read_loc_assoc(struct hci_dev *hdev, struct amp_mgr *mgr); -void amp_read_loc_assoc_final_data(struct hci_dev *hdev, -				   struct hci_conn *hcon); -void amp_create_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, -			struct hci_conn *hcon); -void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, -			struct hci_conn *hcon); -void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle); -void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle); -void amp_physical_cfm(struct hci_conn *bredr_hcon, struct hci_conn *hs_hcon); -void amp_create_logical_link(struct l2cap_chan *chan); -void amp_disconnect_logical_link(struct hci_chan *hchan); -void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason); - -#endif /* __AMP_H */ diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 10d43d8c703..904777c1cd2 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -65,6 +65,7 @@ struct bt_security {  #define BT_SECURITY_LOW		1  #define BT_SECURITY_MEDIUM	2  #define BT_SECURITY_HIGH	3 +#define BT_SECURITY_FIPS	4  #define BT_DEFER_SETUP	7 @@ -115,6 +116,9 @@ struct bt_voice {  #define BT_VOICE_TRANSPARENT			0x0003  #define BT_VOICE_CVSD_16BIT			0x0060 +#define BT_SNDMTU		12 +#define BT_RCVMTU		13 +  __printf(1, 2)  int bt_info(const char *fmt, ...);  __printf(1, 2) @@ -197,8 +201,8 @@ static inline bool bdaddr_type_is_le(__u8 type)  	return false;  } -#define BDADDR_ANY   (&(bdaddr_t) {{0, 0, 0, 0, 0, 0} }) -#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff} }) +#define BDADDR_ANY  (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}}) +#define BDADDR_NONE (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}})  /* Copy, swap, convert BD Address */  static inline int bacmp(const bdaddr_t *ba1, const bdaddr_t *ba2) @@ -218,11 +222,10 @@ void baswap(bdaddr_t *dst, bdaddr_t *src);  struct bt_sock {  	struct sock sk; -	bdaddr_t    src; -	bdaddr_t    dst;  	struct list_head accept_q;  	struct sock *parent;  	unsigned long flags; +	void (*skb_msg_name)(struct sk_buff *, void *, int *);  };  enum { @@ -249,6 +252,7 @@ int  bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,  uint bt_sock_poll(struct file *file, struct socket *sock, poll_table *wait);  int  bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);  int  bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo); +int  bt_sock_wait_ready(struct sock *sk, unsigned long flags);  void bt_accept_enqueue(struct sock *parent, struct sock *sk);  void bt_accept_unlink(struct sock *sk); @@ -282,8 +286,11 @@ struct bt_skb_cb {  	__u8 incoming;  	__u16 expect;  	__u8 force_active; +	struct l2cap_chan *chan;  	struct l2cap_ctrl control;  	struct hci_req_ctrl req; +	bdaddr_t bdaddr; +	__le16 psm;  };  #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) @@ -331,16 +338,16 @@ out:  int bt_to_errno(__u16 code); -extern int hci_sock_init(void); -extern void hci_sock_cleanup(void); +int hci_sock_init(void); +void hci_sock_cleanup(void); -extern int bt_sysfs_init(void); -extern void bt_sysfs_cleanup(void); +int bt_sysfs_init(void); +void bt_sysfs_cleanup(void); -extern int  bt_procfs_init(struct net *net, const char *name, -			   struct bt_sock_list* sk_list, -			   int (* seq_show)(struct seq_file *, void *)); -extern void bt_procfs_cleanup(struct net *net, const char *name); +int bt_procfs_init(struct net *net, const char *name, +		   struct bt_sock_list *sk_list, +		   int (*seq_show)(struct seq_file *, void *)); +void bt_procfs_cleanup(struct net *net, const char *name);  extern struct dentry *bt_debugfs; diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 15f10841e2b..16587dcd6a9 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -35,6 +35,8 @@  #define HCI_MAX_AMP_ASSOC_SIZE	672 +#define HCI_MAX_CSB_DATA_SIZE	252 +  /* HCI dev events */  #define HCI_DEV_REG			1  #define HCI_DEV_UNREG			2 @@ -62,22 +64,27 @@  #define HCI_AMP		0x01  /* First BR/EDR Controller shall have ID = 0 */ -#define HCI_BREDR_ID	0 +#define AMP_ID_BREDR	0x00 + +/* AMP controller types */ +#define AMP_TYPE_BREDR	0x00 +#define AMP_TYPE_80211	0x01  /* AMP controller status */ -#define AMP_CTRL_POWERED_DOWN			0x00 -#define AMP_CTRL_BLUETOOTH_ONLY			0x01 -#define AMP_CTRL_NO_CAPACITY			0x02 -#define AMP_CTRL_LOW_CAPACITY			0x03 -#define AMP_CTRL_MEDIUM_CAPACITY		0x04 -#define AMP_CTRL_HIGH_CAPACITY			0x05 -#define AMP_CTRL_FULL_CAPACITY			0x06 +#define AMP_STATUS_POWERED_DOWN			0x00 +#define AMP_STATUS_BLUETOOTH_ONLY		0x01 +#define AMP_STATUS_NO_CAPACITY			0x02 +#define AMP_STATUS_LOW_CAPACITY			0x03 +#define AMP_STATUS_MEDIUM_CAPACITY		0x04 +#define AMP_STATUS_HIGH_CAPACITY		0x05 +#define AMP_STATUS_FULL_CAPACITY		0x06  /* HCI device quirks */  enum {  	HCI_QUIRK_RESET_ON_CLOSE,  	HCI_QUIRK_RAW_DEVICE, -	HCI_QUIRK_FIXUP_BUFFER_SIZE +	HCI_QUIRK_FIXUP_BUFFER_SIZE, +	HCI_QUIRK_BROKEN_STORED_LINK_KEY,  };  /* HCI device flags */ @@ -109,18 +116,31 @@ enum {  	HCI_PAIRABLE,  	HCI_SERVICE_CACHE,  	HCI_DEBUG_KEYS, +	HCI_DUT_MODE, +	HCI_FORCE_SC, +	HCI_FORCE_STATIC_ADDR,  	HCI_UNREGISTER, +	HCI_USER_CHANNEL,  	HCI_LE_SCAN,  	HCI_SSP_ENABLED, +	HCI_SC_ENABLED, +	HCI_SC_ONLY, +	HCI_PRIVACY, +	HCI_RPA_EXPIRED, +	HCI_RPA_RESOLVING,  	HCI_HS_ENABLED,  	HCI_LE_ENABLED, -	HCI_LE_PERIPHERAL, +	HCI_ADVERTISING,  	HCI_CONNECTABLE,  	HCI_DISCOVERABLE, +	HCI_LIMITED_DISCOVERABLE,  	HCI_LINK_SECURITY,  	HCI_PERIODIC_INQ,  	HCI_FAST_CONNECTABLE, +	HCI_BREDR_ENABLED, +	HCI_6LOWPAN_ENABLED, +	HCI_LE_SCAN_INTERRUPTED,  };  /* A mask for the flags that are supposed to remain when a reset happens @@ -163,6 +183,8 @@ enum {  #define HCI_CMD_TIMEOUT		msecs_to_jiffies(2000)	/* 2 seconds */  #define HCI_ACL_TX_TIMEOUT	msecs_to_jiffies(45000)	/* 45 seconds */  #define HCI_AUTO_OFF_TIMEOUT	msecs_to_jiffies(2000)	/* 2 seconds */ +#define HCI_POWER_OFF_TIMEOUT	msecs_to_jiffies(5000)	/* 5 seconds */ +#define HCI_LE_CONN_TIMEOUT	msecs_to_jiffies(20000)	/* 20 seconds */  /* HCI data types */  #define HCI_COMMAND_PKT		0x01 @@ -265,9 +287,19 @@ enum {  #define LMP_EXTFEATURES	0x80  /* Extended LMP features */ +#define LMP_CSB_MASTER	0x01 +#define LMP_CSB_SLAVE	0x02 +#define LMP_SYNC_TRAIN	0x04 +#define LMP_SYNC_SCAN	0x08 + +#define LMP_SC		0x01 +#define LMP_PING	0x02 + +/* Host features */  #define LMP_HOST_SSP		0x01  #define LMP_HOST_LE		0x02  #define LMP_HOST_LE_BREDR	0x04 +#define LMP_HOST_SC		0x08  /* Connection modes */  #define HCI_CM_ACTIVE	0x0000 @@ -289,6 +321,7 @@ enum {  #define HCI_LM_TRUSTED	0x0008  #define HCI_LM_RELIABLE	0x0010  #define HCI_LM_SECURE	0x0020 +#define HCI_LM_FIPS	0x0040  /* Authentication types */  #define HCI_AT_NO_BONDING		0x00 @@ -309,17 +342,24 @@ enum {  #define HCI_LK_LOCAL_UNIT		0x01  #define HCI_LK_REMOTE_UNIT		0x02  #define HCI_LK_DEBUG_COMBINATION	0x03 -#define HCI_LK_UNAUTH_COMBINATION	0x04 -#define HCI_LK_AUTH_COMBINATION		0x05 +#define HCI_LK_UNAUTH_COMBINATION_P192	0x04 +#define HCI_LK_AUTH_COMBINATION_P192	0x05  #define HCI_LK_CHANGED_COMBINATION	0x06 +#define HCI_LK_UNAUTH_COMBINATION_P256	0x07 +#define HCI_LK_AUTH_COMBINATION_P256	0x08  /* The spec doesn't define types for SMP keys, the _MASTER suffix is implied */  #define HCI_SMP_STK			0x80  #define HCI_SMP_STK_SLAVE		0x81  #define HCI_SMP_LTK			0x82  #define HCI_SMP_LTK_SLAVE		0x83 +/* Long Term Key types */ +#define HCI_LTK_UNAUTH			0x00 +#define HCI_LTK_AUTH			0x01 +  /* ---- HCI Error Codes ---- */  #define HCI_ERROR_AUTH_FAILURE		0x05 +#define HCI_ERROR_MEMORY_EXCEEDED	0x07  #define HCI_ERROR_CONNECTION_TIMEOUT	0x08  #define HCI_ERROR_REJ_BAD_ADDR		0x0f  #define HCI_ERROR_REMOTE_USER_TERM	0x13 @@ -327,6 +367,7 @@ enum {  #define HCI_ERROR_REMOTE_POWER_OFF	0x15  #define HCI_ERROR_LOCAL_HOST_TERM	0x16  #define HCI_ERROR_PAIRING_NOT_ALLOWED	0x18 +#define HCI_ERROR_ADVERTISING_TIMEOUT	0x3c  /* Flow control modes */  #define HCI_FLOW_CTL_MODE_PACKET_BASED	0x00 @@ -624,6 +665,33 @@ struct hci_rp_logical_link_cancel {  	__u8     flow_spec_id;  } __packed; +#define HCI_OP_SET_CSB			0x0441 +struct hci_cp_set_csb { +	__u8	enable; +	__u8	lt_addr; +	__u8	lpo_allowed; +	__le16	packet_type; +	__le16	interval_min; +	__le16	interval_max; +	__le16	csb_sv_tout; +} __packed; +struct hci_rp_set_csb { +	__u8	status; +	__u8	lt_addr; +	__le16	interval; +} __packed; + +#define HCI_OP_START_SYNC_TRAIN		0x0443 + +#define HCI_OP_REMOTE_OOB_EXT_DATA_REPLY	0x0445 +struct hci_cp_remote_oob_ext_data_reply { +	bdaddr_t bdaddr; +	__u8     hash192[16]; +	__u8     randomizer192[16]; +	__u8     hash256[16]; +	__u8     randomizer256[16]; +} __packed; +  #define HCI_OP_SNIFF_MODE		0x0803  struct hci_cp_sniff_mode {  	__le16   handle; @@ -694,9 +762,6 @@ struct hci_cp_sniff_subrate {  } __packed;  #define HCI_OP_SET_EVENT_MASK		0x0c01 -struct hci_cp_set_event_mask { -	__u8     mask[8]; -} __packed;  #define HCI_OP_RESET			0x0c03 @@ -792,6 +857,20 @@ struct hci_cp_host_buffer_size {  	__le16   sco_max_pkt;  } __packed; +#define HCI_OP_READ_NUM_SUPPORTED_IAC	0x0c38 +struct hci_rp_read_num_supported_iac { +	__u8	status; +	__u8	num_iac; +} __packed; + +#define HCI_OP_READ_CURRENT_IAC_LAP	0x0c39 + +#define HCI_OP_WRITE_CURRENT_IAC_LAP	0x0c3a +struct hci_cp_write_current_iac_lap { +	__u8	num_iac; +	__u8	iac_lap[6]; +} __packed; +  #define HCI_OP_WRITE_INQUIRY_MODE	0x0c45  #define HCI_MAX_EIR_LENGTH		240 @@ -826,6 +905,10 @@ struct hci_rp_read_inq_rsp_tx_power {  	__s8     tx_power;  } __packed; +#define HCI_OP_SET_EVENT_MASK_PAGE_2	0x0c63 + +#define HCI_OP_READ_LOCATION_DATA	0x0c64 +  #define HCI_OP_READ_FLOW_CONTROL_MODE	0x0c66  struct hci_rp_read_flow_control_mode {  	__u8     status; @@ -838,6 +921,70 @@ struct hci_cp_write_le_host_supported {  	__u8	simul;  } __packed; +#define HCI_OP_SET_RESERVED_LT_ADDR	0x0c74 +struct hci_cp_set_reserved_lt_addr { +	__u8	lt_addr; +} __packed; +struct hci_rp_set_reserved_lt_addr { +	__u8	status; +	__u8	lt_addr; +} __packed; + +#define HCI_OP_DELETE_RESERVED_LT_ADDR	0x0c75 +struct hci_cp_delete_reserved_lt_addr { +	__u8	lt_addr; +} __packed; +struct hci_rp_delete_reserved_lt_addr { +	__u8	status; +	__u8	lt_addr; +} __packed; + +#define HCI_OP_SET_CSB_DATA		0x0c76 +struct hci_cp_set_csb_data { +	__u8	lt_addr; +	__u8	fragment; +	__u8	data_length; +	__u8	data[HCI_MAX_CSB_DATA_SIZE]; +} __packed; +struct hci_rp_set_csb_data { +	__u8	status; +	__u8	lt_addr; +} __packed; + +#define HCI_OP_READ_SYNC_TRAIN_PARAMS	0x0c77 + +#define HCI_OP_WRITE_SYNC_TRAIN_PARAMS	0x0c78 +struct hci_cp_write_sync_train_params { +	__le16	interval_min; +	__le16	interval_max; +	__le32	sync_train_tout; +	__u8	service_data; +} __packed; +struct hci_rp_write_sync_train_params { +	__u8	status; +	__le16	sync_train_int; +} __packed; + +#define HCI_OP_READ_SC_SUPPORT		0x0c79 +struct hci_rp_read_sc_support { +	__u8	status; +	__u8	support; +} __packed; + +#define HCI_OP_WRITE_SC_SUPPORT		0x0c7a +struct hci_cp_write_sc_support { +	__u8	support; +} __packed; + +#define HCI_OP_READ_LOCAL_OOB_EXT_DATA	0x0c7d +struct hci_rp_read_local_oob_ext_data { +	__u8     status; +	__u8     hash192[16]; +	__u8     randomizer192[16]; +	__u8     hash256[16]; +	__u8     randomizer256[16]; +} __packed; +  #define HCI_OP_READ_LOCAL_VERSION	0x1001  struct hci_rp_read_local_version {  	__u8     status; @@ -907,6 +1054,17 @@ struct hci_cp_write_page_scan_activity {  	__le16   window;  } __packed; +#define HCI_OP_READ_TX_POWER		0x0c2d +struct hci_cp_read_tx_power { +	__le16   handle; +	__u8     type; +} __packed; +struct hci_rp_read_tx_power { +	__u8     status; +	__le16   handle; +	__s8     tx_power; +} __packed; +  #define HCI_OP_READ_PAGE_SCAN_TYPE	0x0c46  struct hci_rp_read_page_scan_type {  	__u8     status; @@ -917,6 +1075,16 @@ struct hci_rp_read_page_scan_type {  	#define PAGE_SCAN_TYPE_STANDARD		0x00  	#define PAGE_SCAN_TYPE_INTERLACED	0x01 +#define HCI_OP_READ_RSSI		0x1405 +struct hci_cp_read_rssi { +	__le16   handle; +} __packed; +struct hci_rp_read_rssi { +	__u8     status; +	__le16   handle; +	__s8     rssi; +} __packed; +  #define HCI_OP_READ_LOCAL_AMP_INFO	0x1409  struct hci_rp_read_local_amp_info {  	__u8     status; @@ -957,6 +1125,10 @@ struct hci_rp_write_remote_amp_assoc {  	__u8     phy_handle;  } __packed; +#define HCI_OP_ENABLE_DUT_MODE		0x1803 + +#define HCI_OP_WRITE_SSP_DEBUG_MODE	0x1804 +  #define HCI_OP_LE_SET_EVENT_MASK	0x2001  struct hci_cp_le_set_event_mask {  	__u8     mask[8]; @@ -975,6 +1147,20 @@ struct hci_rp_le_read_local_features {  	__u8     features[8];  } __packed; +#define HCI_OP_LE_SET_RANDOM_ADDR	0x2005 + +#define HCI_OP_LE_SET_ADV_PARAM		0x2006 +struct hci_cp_le_set_adv_param { +	__le16   min_interval; +	__le16   max_interval; +	__u8     type; +	__u8     own_address_type; +	__u8     direct_addr_type; +	bdaddr_t direct_addr; +	__u8     channel_map; +	__u8     filter_policy; +} __packed; +  #define HCI_OP_LE_READ_ADV_TX_POWER	0x2007  struct hci_rp_le_read_adv_tx_power {  	__u8	status; @@ -989,6 +1175,12 @@ struct hci_cp_le_set_adv_data {  	__u8	data[HCI_MAX_AD_LENGTH];  } __packed; +#define HCI_OP_LE_SET_SCAN_RSP_DATA	0x2009 +struct hci_cp_le_set_scan_rsp_data { +	__u8	length; +	__u8	data[HCI_MAX_AD_LENGTH]; +} __packed; +  #define HCI_OP_LE_SET_ADV_ENABLE	0x200a  #define LE_SCAN_PASSIVE			0x00 @@ -1014,6 +1206,9 @@ struct hci_cp_le_set_scan_enable {  	__u8     filter_dup;  } __packed; +#define HCI_LE_USE_PEER_ADDR		0x00 +#define HCI_LE_USE_WHITELIST		0x01 +  #define HCI_OP_LE_CREATE_CONN		0x200d  struct hci_cp_le_create_conn {  	__le16   scan_interval; @@ -1038,6 +1233,20 @@ struct hci_rp_le_read_white_list_size {  	__u8	size;  } __packed; +#define HCI_OP_LE_CLEAR_WHITE_LIST	0x2010 + +#define HCI_OP_LE_ADD_TO_WHITE_LIST	0x2011 +struct hci_cp_le_add_to_white_list { +	__u8     bdaddr_type; +	bdaddr_t bdaddr; +} __packed; + +#define HCI_OP_LE_DEL_FROM_WHITE_LIST	0x2012 +struct hci_cp_le_del_from_white_list { +	__u8     bdaddr_type; +	bdaddr_t bdaddr; +} __packed; +  #define HCI_OP_LE_CONN_UPDATE		0x2013  struct hci_cp_le_conn_update {  	__le16   handle; @@ -1052,7 +1261,7 @@ struct hci_cp_le_conn_update {  #define HCI_OP_LE_START_ENC		0x2019  struct hci_cp_le_start_enc {  	__le16	handle; -	__u8	rand[8]; +	__le64	rand;  	__le16	ediv;  	__u8	ltk[16];  } __packed; @@ -1438,6 +1647,13 @@ struct hci_ev_num_comp_blocks {  	struct hci_comp_blocks_info handles[0];  } __packed; +#define HCI_EV_SYNC_TRAIN_COMPLETE	0x4F +struct hci_ev_sync_train_complete { +	__u8	status; +} __packed; + +#define HCI_EV_SLAVE_PAGE_RESP_TIMEOUT	0x54 +  /* Low energy meta events */  #define LE_CONN_ROLE_MASTER	0x00 @@ -1457,16 +1673,16 @@ struct hci_ev_le_conn_complete {  #define HCI_EV_LE_LTK_REQ		0x05  struct hci_ev_le_ltk_req {  	__le16	handle; -	__u8	random[8]; +	__le64	rand;  	__le16	ediv;  } __packed;  /* Advertising report event types */ -#define ADV_IND		0x00 -#define ADV_DIRECT_IND	0x01 -#define ADV_SCAN_IND	0x02 -#define ADV_NONCONN_IND	0x03 -#define ADV_SCAN_RSP	0x04 +#define LE_ADV_IND		0x00 +#define LE_ADV_DIRECT_IND	0x01 +#define LE_ADV_SCAN_IND		0x02 +#define LE_ADV_NONCONN_IND	0x03 +#define LE_ADV_SCAN_RSP		0x04  #define ADDR_LE_DEV_PUBLIC	0x00  #define ADDR_LE_DEV_RANDOM	0x01 @@ -1571,6 +1787,7 @@ struct sockaddr_hci {  #define HCI_DEV_NONE	0xffff  #define HCI_CHANNEL_RAW		0 +#define HCI_CHANNEL_USER	1  #define HCI_CHANNEL_MONITOR	2  #define HCI_CHANNEL_CONTROL	3 @@ -1673,6 +1890,4 @@ struct hci_inquiry_req {  };  #define IREQ_CACHE_FLUSH 0x0001 -extern bool enable_hs; -  #endif /* __HCI_H */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 3ede820d328..b386bf17e6c 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -68,6 +68,11 @@ struct discovery_state {  	struct list_head	unknown;	/* Name state not known */  	struct list_head	resolve;	/* Name needs to be resolved */  	__u32			timestamp; +	bdaddr_t		last_adv_addr; +	u8			last_adv_addr_type; +	s8			last_adv_rssi; +	u8			last_adv_data[HCI_MAX_AD_LENGTH]; +	u8			last_adv_data_len;  };  struct hci_conn_hash { @@ -81,6 +86,7 @@ struct hci_conn_hash {  struct bdaddr_list {  	struct list_head list;  	bdaddr_t bdaddr; +	u8 bdaddr_type;  };  struct bt_uuid { @@ -90,6 +96,13 @@ struct bt_uuid {  	u8 svc_hint;  }; +struct smp_csrk { +	bdaddr_t bdaddr; +	u8 bdaddr_type; +	u8 master; +	u8 val[16]; +}; +  struct smp_ltk {  	struct list_head list;  	bdaddr_t bdaddr; @@ -98,9 +111,17 @@ struct smp_ltk {  	u8 type;  	u8 enc_size;  	__le16 ediv; -	u8 rand[8]; +	__le64 rand;  	u8 val[16]; -} __packed; +}; + +struct smp_irk { +	struct list_head list; +	bdaddr_t rpa; +	bdaddr_t bdaddr; +	u8 addr_type; +	u8 val[16]; +};  struct link_key {  	struct list_head list; @@ -113,12 +134,21 @@ struct link_key {  struct oob_data {  	struct list_head list;  	bdaddr_t bdaddr; -	u8 hash[16]; -	u8 randomizer[16]; +	u8 hash192[16]; +	u8 randomizer192[16]; +	u8 hash256[16]; +	u8 randomizer256[16];  };  #define HCI_MAX_SHORT_NAME_LENGTH	10 +/* Default LE RPA expiry time, 15 minutes */ +#define HCI_DEFAULT_RPA_TIMEOUT		(15 * 60) + +/* Default min/max age of connection information (1s/3s) */ +#define DEFAULT_CONN_INFO_MIN_AGE	1000 +#define DEFAULT_CONN_INFO_MAX_AGE	3000 +  struct amp_assoc {  	__u16	len;  	__u16	offset; @@ -140,6 +170,9 @@ struct hci_dev {  	__u8		bus;  	__u8		dev_type;  	bdaddr_t	bdaddr; +	bdaddr_t	random_addr; +	bdaddr_t	static_addr; +	__u8		adv_addr_type;  	__u8		dev_name[HCI_MAX_NAME_LENGTH];  	__u8		short_name[HCI_MAX_SHORT_NAME_LENGTH];  	__u8		eir[HCI_MAX_EIR_LENGTH]; @@ -158,11 +191,22 @@ struct hci_dev {  	__u16		manufacturer;  	__u16		lmp_subver;  	__u16		voice_setting; +	__u8		num_iac;  	__u8		io_capability;  	__s8		inq_tx_power;  	__u16		page_scan_interval;  	__u16		page_scan_window;  	__u8		page_scan_type; +	__u8		le_adv_channel_map; +	__u8		le_scan_type; +	__u16		le_scan_interval; +	__u16		le_scan_window; +	__u16		le_conn_min_interval; +	__u16		le_conn_max_interval; +	__u16		discov_interleaved_timeout; +	__u16		conn_info_min_age; +	__u16		conn_info_max_age; +	__u8		ssp_debug_mode;  	__u16		devid_source;  	__u16		devid_vendor; @@ -248,19 +292,21 @@ struct hci_dev {  	__u32			req_status;  	__u32			req_result; -	struct list_head	mgmt_pending; +	struct crypto_blkcipher	*tfm_aes;  	struct discovery_state	discovery;  	struct hci_conn_hash	conn_hash; -	struct list_head	blacklist; +	struct list_head	mgmt_pending; +	struct list_head	blacklist;  	struct list_head	uuids; -  	struct list_head	link_keys; -  	struct list_head	long_term_keys; - +	struct list_head	identity_resolving_keys;  	struct list_head	remote_oob_data; +	struct list_head	le_white_list; +	struct list_head	le_conn_params; +	struct list_head	pend_le_conns;  	struct hci_dev_stats	stat; @@ -279,14 +325,20 @@ struct hci_dev {  	__s8			adv_tx_power;  	__u8			adv_data[HCI_MAX_AD_LENGTH];  	__u8			adv_data_len; +	__u8			scan_rsp_data[HCI_MAX_AD_LENGTH]; +	__u8			scan_rsp_data_len; + +	__u8			irk[16]; +	__u32			rpa_timeout; +	struct delayed_work	rpa_expired; +	bdaddr_t		rpa;  	int (*open)(struct hci_dev *hdev);  	int (*close)(struct hci_dev *hdev);  	int (*flush)(struct hci_dev *hdev);  	int (*setup)(struct hci_dev *hdev); -	int (*send)(struct sk_buff *skb); +	int (*send)(struct hci_dev *hdev, struct sk_buff *skb);  	void (*notify)(struct hci_dev *hdev, unsigned int evt); -	int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);  };  #define HCI_PHY_HANDLE(handle)	(handle & 0xff) @@ -298,6 +350,12 @@ struct hci_conn {  	bdaddr_t	dst;  	__u8		dst_type; +	bdaddr_t	src; +	__u8		src_type; +	bdaddr_t	init_addr; +	__u8		init_addr_type; +	bdaddr_t	resp_addr; +	__u8		resp_addr_type;  	__u16		handle;  	__u16		state;  	__u8		mode; @@ -306,7 +364,6 @@ struct hci_conn {  	__u8		attempt;  	__u8		dev_class[3];  	__u8		features[HCI_MAX_PAGES][8]; -	__u16		interval;  	__u16		pkt_type;  	__u16		link_policy;  	__u32		link_mode; @@ -321,8 +378,15 @@ struct hci_conn {  	__u8		passkey_entered;  	__u16		disc_timeout;  	__u16		setting; +	__u16		le_conn_min_interval; +	__u16		le_conn_max_interval; +	__s8		rssi; +	__s8		tx_power; +	__s8		max_tx_power;  	unsigned long	flags; +	unsigned long	conn_info_timestamp; +  	__u8		remote_cap;  	__u8		remote_auth;  	__u8		remote_id; @@ -334,8 +398,9 @@ struct hci_conn {  	struct list_head chan_list;  	struct delayed_work disc_work; -	struct timer_list idle_timer; -	struct timer_list auto_accept_timer; +	struct delayed_work auto_accept_work; +	struct delayed_work idle_work; +	struct delayed_work le_conn_timeout;  	struct device	dev; @@ -361,24 +426,39 @@ struct hci_chan {  	__u8		state;  }; +struct hci_conn_params { +	struct list_head list; + +	bdaddr_t addr; +	u8 addr_type; + +	u16 conn_min_interval; +	u16 conn_max_interval; + +	enum { +		HCI_AUTO_CONN_DISABLED, +		HCI_AUTO_CONN_ALWAYS, +		HCI_AUTO_CONN_LINK_LOSS, +	} auto_connect; +}; +  extern struct list_head hci_dev_list;  extern struct list_head hci_cb_list;  extern rwlock_t hci_dev_list_lock;  extern rwlock_t hci_cb_list_lock;  /* ----- HCI interface to upper protocols ----- */ -extern int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); -extern void l2cap_connect_cfm(struct hci_conn *hcon, u8 status); -extern int l2cap_disconn_ind(struct hci_conn *hcon); -extern void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason); -extern int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt); -extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, -			      u16 flags); - -extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags); -extern void sco_connect_cfm(struct hci_conn *hcon, __u8 status); -extern void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason); -extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb); +int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); +void l2cap_connect_cfm(struct hci_conn *hcon, u8 status); +int l2cap_disconn_ind(struct hci_conn *hcon); +void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason); +int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt); +int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags); + +int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags); +void sco_connect_cfm(struct hci_conn *hcon, __u8 status); +void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason); +int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);  /* ----- Inquiry cache ----- */  #define INQUIRY_CACHE_AGE_MAX   (HZ*30)   /* 30 seconds */ @@ -436,8 +516,11 @@ enum {  	HCI_CONN_LE_SMP_PEND,  	HCI_CONN_MGMT_CONNECTED,  	HCI_CONN_SSP_ENABLED, +	HCI_CONN_SC_ENABLED, +	HCI_CONN_AES_CCM,  	HCI_CONN_POWER_SAVE,  	HCI_CONN_REMOTE_OOB, +	HCI_CONN_6LOWPAN,  };  static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) @@ -447,6 +530,13 @@ static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)  	       test_bit(HCI_CONN_SSP_ENABLED, &conn->flags);  } +static inline bool hci_conn_sc_enabled(struct hci_conn *conn) +{ +	struct hci_dev *hdev = conn->hdev; +	return test_bit(HCI_SC_ENABLED, &hdev->dev_flags) && +	       test_bit(HCI_CONN_SC_ENABLED, &conn->flags); +} +  static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)  {  	struct hci_conn_hash *h = &hdev->conn_hash; @@ -510,6 +600,13 @@ static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type)  	}  } +static inline unsigned int hci_conn_count(struct hci_dev *hdev) +{ +	struct hci_conn_hash *c = &hdev->conn_hash; + +	return c->acl_num + c->amp_num + c->sco_num + c->le_num; +} +  static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,  								__u16 handle)  { @@ -583,8 +680,10 @@ void hci_chan_del(struct hci_chan *chan);  void hci_chan_list_flush(struct hci_conn *conn);  struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle); -struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, -			     __u8 dst_type, __u8 sec_level, __u8 auth_type); +struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, +				u8 dst_type, u8 sec_level, u8 auth_type); +struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, +				 u8 sec_level, u8 auth_type);  struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,  				 __u16 setting);  int hci_conn_check_link_mode(struct hci_conn *conn); @@ -595,6 +694,8 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role);  void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); +void hci_le_conn_failed(struct hci_conn *conn, u8 status); +  /*   * hci_conn_get() and hci_conn_put() are used to control the life-time of an   * "hci_conn" object. They do not guarantee that the hci_conn object is running, @@ -644,7 +745,7 @@ static inline void hci_conn_drop(struct hci_conn *conn)  		switch (conn->type) {  		case ACL_LINK:  		case LE_LINK: -			del_timer(&conn->idle_timer); +			cancel_delayed_work(&conn->idle_work);  			if (conn->state == BT_CONNECTED) {  				timeo = conn->disc_timeout;  				if (!conn->out) @@ -703,19 +804,6 @@ static inline void hci_set_drvdata(struct hci_dev *hdev, void *data)  	dev_set_drvdata(&hdev->dev, data);  } -/* hci_dev_list shall be locked */ -static inline uint8_t __hci_num_ctrl(void) -{ -	uint8_t count = 0; -	struct list_head *p; - -	list_for_each(p, &hci_dev_list) { -		count++; -	} - -	return count; -} -  struct hci_dev *hci_dev_get(int index);  struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src); @@ -738,43 +826,74 @@ int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);  int hci_inquiry(void __user *arg);  struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, -					 bdaddr_t *bdaddr); -int hci_blacklist_clear(struct hci_dev *hdev); +					 bdaddr_t *bdaddr, u8 type);  int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);  int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); -int hci_uuids_clear(struct hci_dev *hdev); +struct bdaddr_list *hci_white_list_lookup(struct hci_dev *hdev, +					  bdaddr_t *bdaddr, u8 type); +void hci_white_list_clear(struct hci_dev *hdev); +int hci_white_list_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); +int hci_white_list_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); + +struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, +					       bdaddr_t *addr, u8 addr_type); +int hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, +			u8 auto_connect, u16 conn_min_interval, +			u16 conn_max_interval); +void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type); +void hci_conn_params_clear(struct hci_dev *hdev); -int hci_link_keys_clear(struct hci_dev *hdev); +struct bdaddr_list *hci_pend_le_conn_lookup(struct hci_dev *hdev, +					    bdaddr_t *addr, u8 addr_type); +void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type); +void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type); +void hci_pend_le_conns_clear(struct hci_dev *hdev); + +void hci_update_background_scan(struct hci_dev *hdev); + +void hci_uuids_clear(struct hci_dev *hdev); + +void hci_link_keys_clear(struct hci_dev *hdev);  struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);  int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,  		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len); -struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]); -int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, -		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, -		__le16 ediv, u8 rand[8]); +struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand, +			     bool master); +struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, +			    u8 addr_type, u8 type, u8 authenticated, +			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand);  struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, -				     u8 addr_type); -int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr); -int hci_smp_ltks_clear(struct hci_dev *hdev); +				     u8 addr_type, bool master); +int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type); +void hci_smp_ltks_clear(struct hci_dev *hdev);  int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); -int hci_remote_oob_data_clear(struct hci_dev *hdev); +struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa); +struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, +				     u8 addr_type); +struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, +			    u8 addr_type, u8 val[16], bdaddr_t *rpa); +void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type); +void hci_smp_irks_clear(struct hci_dev *hdev); + +void hci_remote_oob_data_clear(struct hci_dev *hdev);  struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, -							bdaddr_t *bdaddr); -int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, -								u8 *randomizer); +					  bdaddr_t *bdaddr); +int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, +			    u8 *hash, u8 *randomizer); +int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr, +				u8 *hash192, u8 *randomizer192, +				u8 *hash256, u8 *randomizer256);  int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);  void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); -int hci_recv_frame(struct sk_buff *skb); +int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb);  int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count);  int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count);  void hci_init_sysfs(struct hci_dev *hdev); -int hci_add_sysfs(struct hci_dev *hdev); -void hci_del_sysfs(struct hci_dev *hdev);  void hci_conn_init_sysfs(struct hci_conn *conn);  void hci_conn_add_sysfs(struct hci_conn *conn);  void hci_conn_del_sysfs(struct hci_conn *conn); @@ -803,26 +922,19 @@ void hci_conn_del_sysfs(struct hci_conn *conn);  #define lmp_transp_capable(dev)    ((dev)->features[0][2] & LMP_TRANSPARENT)  /* ----- Extended LMP capabilities ----- */ +#define lmp_csb_master_capable(dev) ((dev)->features[2][0] & LMP_CSB_MASTER) +#define lmp_csb_slave_capable(dev)  ((dev)->features[2][0] & LMP_CSB_SLAVE) +#define lmp_sync_train_capable(dev) ((dev)->features[2][0] & LMP_SYNC_TRAIN) +#define lmp_sync_scan_capable(dev)  ((dev)->features[2][0] & LMP_SYNC_SCAN) +#define lmp_sc_capable(dev)         ((dev)->features[2][1] & LMP_SC) +#define lmp_ping_capable(dev)       ((dev)->features[2][1] & LMP_PING) + +/* ----- Host capabilities ----- */  #define lmp_host_ssp_capable(dev)  ((dev)->features[1][0] & LMP_HOST_SSP) +#define lmp_host_sc_capable(dev)   ((dev)->features[1][0] & LMP_HOST_SC)  #define lmp_host_le_capable(dev)   (!!((dev)->features[1][0] & LMP_HOST_LE))  #define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR)) -/* returns true if at least one AMP active */ -static inline bool hci_amp_capable(void) -{ -	struct hci_dev *hdev; -	bool ret = false; - -	read_lock(&hci_dev_list_lock); -	list_for_each_entry(hdev, &hci_dev_list, list) -		if (hdev->amp_type == HCI_AMP && -		    test_bit(HCI_UP, &hdev->flags)) -			ret = true; -	read_unlock(&hci_dev_list_lock); - -	return ret; -} -  /* ----- HCI protocols ----- */  #define HCI_PROTO_DEFER             0x01 @@ -1033,32 +1145,24 @@ static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type)  	return false;  } -static inline size_t eir_get_length(u8 *eir, size_t eir_len) +static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type)  { -	size_t parsed = 0; - -	while (parsed < eir_len) { -		u8 field_len = eir[0]; - -		if (field_len == 0) -			return parsed; +	if (addr_type != 0x01) +		return false; -		parsed += field_len + 1; -		eir += field_len + 1; -	} +	if ((bdaddr->b[5] & 0xc0) == 0x40) +	       return true; -	return eir_len; +	return false;  } -static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data, -				  u8 data_len) +static inline struct smp_irk *hci_get_irk(struct hci_dev *hdev, +					  bdaddr_t *bdaddr, u8 addr_type)  { -	eir[eir_len++] = sizeof(type) + data_len; -	eir[eir_len++] = type; -	memcpy(&eir[eir_len], data, data_len); -	eir_len += data_len; +	if (!hci_bdaddr_is_rpa(bdaddr, addr_type)) +		return NULL; -	return eir_len; +	return hci_find_irk_by_rpa(hdev, bdaddr);  }  int hci_register_cb(struct hci_cb *hcb); @@ -1082,6 +1186,9 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,  		    const void *param, u8 event);  void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); +void hci_req_add_le_scan_disable(struct hci_request *req); +void hci_req_add_le_passive_scan(struct hci_request *req); +  struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,  			       const void *param, u32 timeout);  struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, @@ -1114,37 +1221,40 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);   */  #define DISCOV_LE_SCAN_WIN		0x12  #define DISCOV_LE_SCAN_INT		0x12 -#define DISCOV_LE_TIMEOUT		msecs_to_jiffies(10240) -#define DISCOV_INTERLEAVED_TIMEOUT	msecs_to_jiffies(5120) +#define DISCOV_LE_TIMEOUT		10240	/* msec */ +#define DISCOV_INTERLEAVED_TIMEOUT	5120	/* msec */  #define DISCOV_INTERLEAVED_INQUIRY_LEN	0x04  #define DISCOV_BREDR_INQUIRY_LEN	0x08  int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); -int mgmt_index_added(struct hci_dev *hdev); -int mgmt_index_removed(struct hci_dev *hdev); -int mgmt_set_powered_failed(struct hci_dev *hdev, int err); +void mgmt_index_added(struct hci_dev *hdev); +void mgmt_index_removed(struct hci_dev *hdev); +void mgmt_set_powered_failed(struct hci_dev *hdev, int err);  int mgmt_powered(struct hci_dev *hdev, u8 powered); -int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); -int mgmt_connectable(struct hci_dev *hdev, u8 connectable); -int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status); -int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, -		      bool persistent); -int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, -			  u8 addr_type, u32 flags, u8 *name, u8 name_len, -			  u8 *dev_class); -int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, -			     u8 link_type, u8 addr_type, u8 reason); -int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, -			   u8 link_type, u8 addr_type, u8 status); -int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, -			u8 addr_type, u8 status); -int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure); -int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, -				 u8 status); -int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, -				     u8 status); +void mgmt_discoverable_timeout(struct hci_dev *hdev); +void mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); +void mgmt_connectable(struct hci_dev *hdev, u8 connectable); +void mgmt_advertising(struct hci_dev *hdev, u8 advertising); +void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status); +void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, +		       bool persistent); +void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, +			   u8 addr_type, u32 flags, u8 *name, u8 name_len, +			   u8 *dev_class); +void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, +			      u8 link_type, u8 addr_type, u8 reason, +			      bool mgmt_connected); +void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, +			    u8 link_type, u8 addr_type, u8 status); +void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, +			 u8 addr_type, u8 status); +void mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure); +void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, +				  u8 status); +void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, +				      u8 status);  int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, -			      u8 link_type, u8 addr_type, __le32 value, +			      u8 link_type, u8 addr_type, u32 value,  			      u8 confirm_hint);  int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,  				     u8 link_type, u8 addr_type, u8 status); @@ -1159,26 +1269,32 @@ int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,  int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr,  			     u8 link_type, u8 addr_type, u32 passkey,  			     u8 entered); -int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, -		     u8 addr_type, u8 status); -int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status); -int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); -int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, -				   u8 status); -int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status); -int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, -					    u8 *randomizer, u8 status); -int mgmt_le_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); -int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, -		      u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name, -		      u8 ssp, u8 *eir, u16 eir_len); -int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, -		     u8 addr_type, s8 rssi, u8 *name, u8 name_len); -int mgmt_discovering(struct hci_dev *hdev, u8 discovering); +void mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, +		      u8 addr_type, u8 status); +void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status); +void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); +void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); +void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, +				    u8 status); +void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status); +void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, +				       u8 *randomizer192, u8 *hash256, +				       u8 *randomizer256, u8 status); +void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, +		       u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name, +		       u8 ssp, u8 *eir, u16 eir_len, u8 *scan_rsp, +		       u8 scan_rsp_len); +void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, +		      u8 addr_type, s8 rssi, u8 *name, u8 name_len); +void mgmt_discovering(struct hci_dev *hdev, u8 discovering);  int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);  int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); -bool mgmt_valid_hdev(struct hci_dev *hdev); -int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent); +void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent); +void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk); +void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk, +		   bool persistent); +void mgmt_reenable_advertising(struct hci_dev *hdev); +void mgmt_smp_complete(struct hci_conn *conn, bool complete);  /* HCI info for socket */  #define hci_pi(sk) ((struct hci_pinfo *) sk) @@ -1208,14 +1324,15 @@ struct hci_sec_filter {  #define hci_req_lock(d)		mutex_lock(&d->req_lock)  #define hci_req_unlock(d)	mutex_unlock(&d->req_lock) -void hci_update_ad(struct hci_request *req); -  void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,  					u16 latency, u16 to_multiplier); -void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], +void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,  							__u8 ltk[16]); -u8 bdaddr_to_le(u8 bdaddr_type); +int hci_update_random_address(struct hci_request *req, bool require_privacy, +			      u8 *own_addr_type); +void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, +			       u8 *bdaddr_type);  #define SCO_AIRMODE_MASK       0x0003  #define SCO_AIRMODE_CVSD       0x0000 diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 1a966afbbfa..4abdcb220e3 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -91,6 +91,7 @@ struct l2cap_conninfo {  #define L2CAP_LM_TRUSTED	0x0008  #define L2CAP_LM_RELIABLE	0x0010  #define L2CAP_LM_SECURE		0x0020 +#define L2CAP_LM_FIPS		0x0040  /* L2CAP command codes */  #define L2CAP_COMMAND_REJ	0x01 @@ -112,6 +113,9 @@ struct l2cap_conninfo {  #define L2CAP_MOVE_CHAN_CFM_RSP	0x11  #define L2CAP_CONN_PARAM_UPDATE_REQ	0x12  #define L2CAP_CONN_PARAM_UPDATE_RSP	0x13 +#define L2CAP_LE_CONN_REQ	0x14 +#define L2CAP_LE_CONN_RSP	0x15 +#define L2CAP_LE_CREDITS	0x16  /* L2CAP extended feature mask */  #define L2CAP_FEAT_FLOWCTL	0x00000001 @@ -131,7 +135,9 @@ struct l2cap_conninfo {  /* L2CAP fixed channels */  #define L2CAP_FC_L2CAP		0x02 +#define L2CAP_FC_CONNLESS	0x04  #define L2CAP_FC_A2MP		0x08 +#define L2CAP_FC_6LOWPAN        0x3e /* reserved and temporary value */  /* L2CAP Control Field bit masks */  #define L2CAP_CTRL_SAR			0xC000 @@ -237,8 +243,9 @@ struct l2cap_conn_rsp {  /* protocol/service multiplexer (PSM) */  #define L2CAP_PSM_SDP		0x0001  #define L2CAP_PSM_RFCOMM	0x0003 +#define L2CAP_PSM_3DSP		0x0021 -/* channel indentifier */ +/* channel identifier */  #define L2CAP_CID_SIGNALING	0x0001  #define L2CAP_CID_CONN_LESS	0x0002  #define L2CAP_CID_A2MP		0x0003 @@ -247,6 +254,7 @@ struct l2cap_conn_rsp {  #define L2CAP_CID_SMP		0x0006  #define L2CAP_CID_DYN_START	0x0040  #define L2CAP_CID_DYN_END	0xffff +#define L2CAP_CID_LE_DYN_END	0x007f  /* connect/create channel results */  #define L2CAP_CR_SUCCESS	0x0000 @@ -255,6 +263,10 @@ struct l2cap_conn_rsp {  #define L2CAP_CR_SEC_BLOCK	0x0003  #define L2CAP_CR_NO_MEM		0x0004  #define L2CAP_CR_BAD_AMP	0x0005 +#define L2CAP_CR_AUTHENTICATION	0x0005 +#define L2CAP_CR_AUTHORIZATION	0x0006 +#define L2CAP_CR_BAD_KEY_SIZE	0x0007 +#define L2CAP_CR_ENCRYPTION	0x0008  /* connect/create channel status */  #define L2CAP_CS_NO_INFO	0x0000 @@ -319,6 +331,12 @@ struct l2cap_conf_rfc {  #define L2CAP_MODE_ERTM		0x03  #define L2CAP_MODE_STREAMING	0x04 +/* Unlike the above this one doesn't actually map to anything that would + * ever be sent over the air. Therefore, use a value that's unlikely to + * ever be used in the BR/EDR configuration phase. + */ +#define L2CAP_MODE_LE_FLOWCTL	0x80 +  struct l2cap_conf_efs {  	__u8	id;  	__u8	stype; @@ -421,6 +439,30 @@ struct l2cap_conn_param_update_rsp {  #define L2CAP_CONN_PARAM_ACCEPTED	0x0000  #define L2CAP_CONN_PARAM_REJECTED	0x0001 +#define L2CAP_LE_MAX_CREDITS		10 +#define L2CAP_LE_DEFAULT_MPS		230 + +struct l2cap_le_conn_req { +	__le16     psm; +	__le16     scid; +	__le16     mtu; +	__le16     mps; +	__le16     credits; +} __packed; + +struct l2cap_le_conn_rsp { +	__le16     dcid; +	__le16     mtu; +	__le16     mps; +	__le16     credits; +	__le16     result; +} __packed; + +struct l2cap_le_credits { +	__le16     cid; +	__le16     credits; +} __packed; +  /* ----- L2CAP channels and connections ----- */  struct l2cap_seq_list {  	__u16	head; @@ -433,8 +475,6 @@ struct l2cap_seq_list {  #define L2CAP_SEQ_LIST_TAIL	0x8000  struct l2cap_chan { -	struct sock *sk; -  	struct l2cap_conn	*conn;  	struct hci_conn		*hs_hcon;  	struct hci_chan		*hs_hchan; @@ -442,7 +482,12 @@ struct l2cap_chan {  	__u8		state; +	bdaddr_t	dst; +	__u8		dst_type; +	bdaddr_t	src; +	__u8		src_type;  	__le16		psm; +	__le16		sport;  	__u16		dcid;  	__u16		scid; @@ -453,8 +498,6 @@ struct l2cap_chan {  	__u8		chan_type;  	__u8		chan_policy; -	__le16		sport; -  	__u8		sec_level;  	__u8		ident; @@ -474,6 +517,9 @@ struct l2cap_chan {  	__u16		monitor_timeout;  	__u16		mps; +	__u16		tx_credits; +	__u16		rx_credits; +  	__u8		tx_state;  	__u8		rx_state; @@ -546,9 +592,13 @@ struct l2cap_ops {  	void			(*teardown) (struct l2cap_chan *chan, int err);  	void			(*close) (struct l2cap_chan *chan);  	void			(*state_change) (struct l2cap_chan *chan, -						 int state); +						 int state, int err);  	void			(*ready) (struct l2cap_chan *chan);  	void			(*defer) (struct l2cap_chan *chan); +	void			(*resume) (struct l2cap_chan *chan); +	void			(*suspend) (struct l2cap_chan *chan); +	void			(*set_shutdown) (struct l2cap_chan *chan); +	long			(*get_sndtimeo) (struct l2cap_chan *chan);  	struct sk_buff		*(*alloc_skb) (struct l2cap_chan *chan,  					       unsigned long len, int nb);  }; @@ -557,13 +607,11 @@ struct l2cap_conn {  	struct hci_conn		*hcon;  	struct hci_chan		*hchan; -	bdaddr_t		*dst; -	bdaddr_t		*src; -  	unsigned int		mtu;  	__u32			feat_mask;  	__u8			fixed_chan_mask; +	bool			hs_enabled;  	__u8			info_state;  	__u8			info_ident; @@ -576,6 +624,9 @@ struct l2cap_conn {  	__u32			rx_len;  	__u8			tx_ident; +	struct sk_buff_head	pending_rx; +	struct work_struct	pending_rx_work; +  	__u8			disc_reason;  	struct delayed_work	security_timer; @@ -600,7 +651,7 @@ struct l2cap_user {  #define L2CAP_CHAN_RAW			1  #define L2CAP_CHAN_CONN_LESS		2  #define L2CAP_CHAN_CONN_ORIENTED	3 -#define L2CAP_CHAN_CONN_FIX_A2MP	4 +#define L2CAP_CHAN_FIXED		4  /* ----- L2CAP socket info ----- */  #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) @@ -649,6 +700,8 @@ enum {  	FLAG_FLUSHABLE,  	FLAG_EXT_CTRL,  	FLAG_EFS_ENABLE, +	FLAG_DEFER_SETUP, +	FLAG_LE_CONN_REQ_SENT,  };  enum { @@ -790,14 +843,27 @@ static inline void l2cap_chan_no_defer(struct l2cap_chan *chan)  {  } +static inline void l2cap_chan_no_resume(struct l2cap_chan *chan) +{ +} + +static inline void l2cap_chan_no_set_shutdown(struct l2cap_chan *chan) +{ +} + +static inline long l2cap_chan_no_get_sndtimeo(struct l2cap_chan *chan) +{ +	return 0; +} +  extern bool disable_ertm;  int l2cap_init_sockets(void);  void l2cap_cleanup_sockets(void);  bool l2cap_is_socket(struct socket *sock); +void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan);  void __l2cap_connect_rsp_defer(struct l2cap_chan *chan); -int __l2cap_wait_ack(struct sock *sk);  int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);  int l2cap_add_scid(struct l2cap_chan *chan,  __u16 scid); @@ -815,6 +881,7 @@ int l2cap_ertm_init(struct l2cap_chan *chan);  void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);  void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);  void l2cap_chan_del(struct l2cap_chan *chan, int err); +void l2cap_conn_update_id_addr(struct hci_conn *hcon);  void l2cap_send_conn_req(struct l2cap_chan *chan);  void l2cap_move_start(struct l2cap_chan *chan);  void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 9944c3e68c5..bcffc9ae0c8 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -93,6 +93,10 @@ struct mgmt_rp_read_index_list {  #define MGMT_SETTING_BREDR		0x00000080  #define MGMT_SETTING_HS			0x00000100  #define MGMT_SETTING_LE			0x00000200 +#define MGMT_SETTING_ADVERTISING	0x00000400 +#define MGMT_SETTING_SECURE_CONN	0x00000800 +#define MGMT_SETTING_DEBUG_KEYS		0x00001000 +#define MGMT_SETTING_PRIVACY		0x00002000  #define MGMT_OP_READ_INFO		0x0004  #define MGMT_READ_INFO_SIZE		0 @@ -177,13 +181,16 @@ struct mgmt_cp_load_link_keys {  } __packed;  #define MGMT_LOAD_LINK_KEYS_SIZE	3 +#define MGMT_LTK_UNAUTHENTICATED	0x00 +#define MGMT_LTK_AUTHENTICATED		0x01 +  struct mgmt_ltk_info {  	struct mgmt_addr_info addr; -	__u8	authenticated; +	__u8	type;  	__u8	master;  	__u8	enc_size;  	__le16	ediv; -	__u8	rand[8]; +	__le64	rand;  	__u8	val[16];  } __packed; @@ -293,6 +300,12 @@ struct mgmt_rp_read_local_oob_data {  	__u8	hash[16];  	__u8	randomizer[16];  } __packed; +struct mgmt_rp_read_local_oob_ext_data { +	__u8	hash192[16]; +	__u8	randomizer192[16]; +	__u8	hash256[16]; +	__u8	randomizer256[16]; +} __packed;  #define MGMT_OP_ADD_REMOTE_OOB_DATA	0x0021  struct mgmt_cp_add_remote_oob_data { @@ -301,6 +314,14 @@ struct mgmt_cp_add_remote_oob_data {  	__u8	randomizer[16];  } __packed;  #define MGMT_ADD_REMOTE_OOB_DATA_SIZE	(MGMT_ADDR_INFO_SIZE + 32) +struct mgmt_cp_add_remote_oob_ext_data { +	struct mgmt_addr_info addr; +	__u8	hash192[16]; +	__u8	randomizer192[16]; +	__u8	hash256[16]; +	__u8	randomizer256[16]; +} __packed; +#define MGMT_ADD_REMOTE_OOB_EXT_DATA_SIZE (MGMT_ADDR_INFO_SIZE + 64)  #define MGMT_OP_REMOVE_REMOTE_OOB_DATA	0x0022  struct mgmt_cp_remove_remote_oob_data { @@ -351,6 +372,58 @@ struct mgmt_cp_set_device_id {  } __packed;  #define MGMT_SET_DEVICE_ID_SIZE		8 +#define MGMT_OP_SET_ADVERTISING		0x0029 + +#define MGMT_OP_SET_BREDR		0x002A + +#define MGMT_OP_SET_STATIC_ADDRESS	0x002B +struct mgmt_cp_set_static_address { +	bdaddr_t bdaddr; +} __packed; +#define MGMT_SET_STATIC_ADDRESS_SIZE	6 + +#define MGMT_OP_SET_SCAN_PARAMS		0x002C +struct mgmt_cp_set_scan_params { +	__le16	interval; +	__le16	window; +} __packed; +#define MGMT_SET_SCAN_PARAMS_SIZE	4 + +#define MGMT_OP_SET_SECURE_CONN		0x002D + +#define MGMT_OP_SET_DEBUG_KEYS		0x002E + +#define MGMT_OP_SET_PRIVACY		0x002F +struct mgmt_cp_set_privacy { +	__u8 privacy; +	__u8 irk[16]; +} __packed; +#define MGMT_SET_PRIVACY_SIZE		17 + +struct mgmt_irk_info { +	struct mgmt_addr_info addr; +	__u8 val[16]; +} __packed; + +#define MGMT_OP_LOAD_IRKS		0x0030 +struct mgmt_cp_load_irks { +	__le16 irk_count; +	struct mgmt_irk_info irks[0]; +} __packed; +#define MGMT_LOAD_IRKS_SIZE		2 + +#define MGMT_OP_GET_CONN_INFO		0x0031 +struct mgmt_cp_get_conn_info { +	struct mgmt_addr_info addr; +} __packed; +#define MGMT_GET_CONN_INFO_SIZE		MGMT_ADDR_INFO_SIZE +struct mgmt_rp_get_conn_info { +	struct mgmt_addr_info addr; +	__s8	rssi; +	__s8	tx_power; +	__s8	max_tx_power; +} __packed; +  #define MGMT_EV_CMD_COMPLETE		0x0001  struct mgmt_ev_cmd_complete {  	__le16	opcode; @@ -486,3 +559,22 @@ struct mgmt_ev_passkey_notify {  	__le32	passkey;  	__u8	entered;  } __packed; + +#define MGMT_EV_NEW_IRK			0x0018 +struct mgmt_ev_new_irk { +	__u8     store_hint; +	bdaddr_t rpa; +	struct mgmt_irk_info irk; +} __packed; + +struct mgmt_csrk_info { +	struct mgmt_addr_info addr; +	__u8 master; +	__u8 val[16]; +} __packed; + +#define MGMT_EV_NEW_CSRK		0x0019 +struct mgmt_ev_new_csrk { +	__u8 store_hint; +	struct mgmt_csrk_info key; +} __packed; diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index 7afd4199d6b..578b83127af 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -173,7 +173,7 @@ struct rfcomm_dlc {  	struct sk_buff_head   tx_queue;  	struct timer_list     timer; -	spinlock_t    lock; +	struct mutex  lock;  	unsigned long state;  	unsigned long flags;  	atomic_t      refcnt; @@ -238,12 +238,14 @@ int  rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,  								u8 channel);  int  rfcomm_dlc_close(struct rfcomm_dlc *d, int reason);  int  rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb); +void rfcomm_dlc_send_noerror(struct rfcomm_dlc *d, struct sk_buff *skb);  int  rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig);  int  rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig);  void rfcomm_dlc_accept(struct rfcomm_dlc *d); +struct rfcomm_dlc *rfcomm_dlc_exists(bdaddr_t *src, bdaddr_t *dst, u8 channel); -#define rfcomm_dlc_lock(d)     spin_lock(&d->lock) -#define rfcomm_dlc_unlock(d)   spin_unlock(&d->lock) +#define rfcomm_dlc_lock(d)     mutex_lock(&d->lock) +#define rfcomm_dlc_unlock(d)   mutex_unlock(&d->lock)  static inline void rfcomm_dlc_hold(struct rfcomm_dlc *d)  { @@ -256,8 +258,8 @@ static inline void rfcomm_dlc_put(struct rfcomm_dlc *d)  		rfcomm_dlc_free(d);  } -extern void __rfcomm_dlc_throttle(struct rfcomm_dlc *d); -extern void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d); +void __rfcomm_dlc_throttle(struct rfcomm_dlc *d); +void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d);  static inline void rfcomm_dlc_throttle(struct rfcomm_dlc *d)  { @@ -295,11 +297,14 @@ struct rfcomm_conninfo {  #define RFCOMM_LM_TRUSTED	0x0008  #define RFCOMM_LM_RELIABLE	0x0010  #define RFCOMM_LM_SECURE	0x0020 +#define RFCOMM_LM_FIPS		0x0040  #define rfcomm_pi(sk) ((struct rfcomm_pinfo *) sk)  struct rfcomm_pinfo {  	struct bt_sock bt; +	bdaddr_t src; +	bdaddr_t dst;  	struct rfcomm_dlc   *dlc;  	u8     channel;  	u8     sec_level; @@ -321,11 +326,16 @@ int  rfcomm_connect_ind(struct rfcomm_session *s, u8 channel,  #define RFCOMMGETDEVINFO	_IOR('R', 211, int)  #define RFCOMMSTEALDLC		_IOW('R', 220, int) +/* rfcomm_dev.flags bit definitions */  #define RFCOMM_REUSE_DLC      0  #define RFCOMM_RELEASE_ONHUP  1  #define RFCOMM_HANGUP_NOW     2  #define RFCOMM_TTY_ATTACHED   3 -#define RFCOMM_TTY_RELEASED   4 +#define RFCOMM_DEFUNCT_BIT4   4	  /* don't reuse this bit - userspace visible */ + +/* rfcomm_dev.status bit definitions */ +#define RFCOMM_DEV_RELEASED   0 +#define RFCOMM_TTY_OWNED      1  struct rfcomm_dev_req {  	s16      dev_id; diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h index e252a31ee6b..2019d1a0996 100644 --- a/include/net/bluetooth/sco.h +++ b/include/net/bluetooth/sco.h @@ -55,9 +55,6 @@ struct sco_conninfo {  struct sco_conn {  	struct hci_conn	*hcon; -	bdaddr_t	*dst; -	bdaddr_t	*src; -  	spinlock_t	lock;  	struct sock	*sk; @@ -72,6 +69,8 @@ struct sco_conn {  struct sco_pinfo {  	struct bt_sock	bt; +	bdaddr_t	src; +	bdaddr_t	dst;  	__u32		flags;  	__u16		setting;  	struct sco_conn	*conn; diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h deleted file mode 100644 index f8ba07f3e5f..00000000000 --- a/include/net/bluetooth/smp.h +++ /dev/null @@ -1,146 +0,0 @@ -/* -   BlueZ - Bluetooth protocol stack for Linux -   Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). - -   This program is free software; you can redistribute it and/or modify -   it under the terms of the GNU General Public License version 2 as -   published by the Free Software Foundation; - -   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. -   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY -   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES -   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, -   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS -   SOFTWARE IS DISCLAIMED. -*/ - -#ifndef __SMP_H -#define __SMP_H - -struct smp_command_hdr { -	__u8	code; -} __packed; - -#define SMP_CMD_PAIRING_REQ	0x01 -#define SMP_CMD_PAIRING_RSP	0x02 -struct smp_cmd_pairing { -	__u8	io_capability; -	__u8	oob_flag; -	__u8	auth_req; -	__u8	max_key_size; -	__u8	init_key_dist; -	__u8	resp_key_dist; -} __packed; - -#define SMP_IO_DISPLAY_ONLY	0x00 -#define SMP_IO_DISPLAY_YESNO	0x01 -#define SMP_IO_KEYBOARD_ONLY	0x02 -#define SMP_IO_NO_INPUT_OUTPUT	0x03 -#define SMP_IO_KEYBOARD_DISPLAY	0x04 - -#define SMP_OOB_NOT_PRESENT	0x00 -#define SMP_OOB_PRESENT		0x01 - -#define SMP_DIST_ENC_KEY	0x01 -#define SMP_DIST_ID_KEY		0x02 -#define SMP_DIST_SIGN		0x04 - -#define SMP_AUTH_NONE		0x00 -#define SMP_AUTH_BONDING	0x01 -#define SMP_AUTH_MITM		0x04 - -#define SMP_CMD_PAIRING_CONFIRM	0x03 -struct smp_cmd_pairing_confirm { -	__u8	confirm_val[16]; -} __packed; - -#define SMP_CMD_PAIRING_RANDOM	0x04 -struct smp_cmd_pairing_random { -	__u8	rand_val[16]; -} __packed; - -#define SMP_CMD_PAIRING_FAIL	0x05 -struct smp_cmd_pairing_fail { -	__u8	reason; -} __packed; - -#define SMP_CMD_ENCRYPT_INFO	0x06 -struct smp_cmd_encrypt_info { -	__u8	ltk[16]; -} __packed; - -#define SMP_CMD_MASTER_IDENT	0x07 -struct smp_cmd_master_ident { -	__le16	ediv; -	__u8	rand[8]; -} __packed; - -#define SMP_CMD_IDENT_INFO	0x08 -struct smp_cmd_ident_info { -	__u8	irk[16]; -} __packed; - -#define SMP_CMD_IDENT_ADDR_INFO	0x09 -struct smp_cmd_ident_addr_info { -	__u8	addr_type; -	bdaddr_t bdaddr; -} __packed; - -#define SMP_CMD_SIGN_INFO	0x0a -struct smp_cmd_sign_info { -	__u8	csrk[16]; -} __packed; - -#define SMP_CMD_SECURITY_REQ	0x0b -struct smp_cmd_security_req { -	__u8	auth_req; -} __packed; - -#define SMP_PASSKEY_ENTRY_FAILED	0x01 -#define SMP_OOB_NOT_AVAIL		0x02 -#define SMP_AUTH_REQUIREMENTS		0x03 -#define SMP_CONFIRM_FAILED		0x04 -#define SMP_PAIRING_NOTSUPP		0x05 -#define SMP_ENC_KEY_SIZE		0x06 -#define SMP_CMD_NOTSUPP			0x07 -#define SMP_UNSPECIFIED			0x08 -#define SMP_REPEATED_ATTEMPTS		0x09 - -#define SMP_MIN_ENC_KEY_SIZE		7 -#define SMP_MAX_ENC_KEY_SIZE		16 - -#define SMP_FLAG_TK_VALID	1 -#define SMP_FLAG_CFM_PENDING	2 -#define SMP_FLAG_MITM_AUTH	3 - -struct smp_chan { -	struct l2cap_conn *conn; -	u8		preq[7]; /* SMP Pairing Request */ -	u8		prsp[7]; /* SMP Pairing Response */ -	u8		prnd[16]; /* SMP Pairing Random (local) */ -	u8		rrnd[16]; /* SMP Pairing Random (remote) */ -	u8		pcnf[16]; /* SMP Pairing Confirm */ -	u8		tk[16]; /* SMP Temporary Key */ -	u8		enc_key_size; -	unsigned long	smp_flags; -	struct crypto_blkcipher	*tfm; -	struct work_struct confirm; -	struct work_struct random; - -}; - -/* SMP Commands */ -int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); -int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb); -int smp_distribute_keys(struct l2cap_conn *conn, __u8 force); -int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); - -void smp_chan_destroy(struct l2cap_conn *conn); - -#endif /* __SMP_H */  | 
