diff options
Diffstat (limited to 'include/net/bluetooth')
| -rw-r--r-- | include/net/bluetooth/hci.h | 51 | ||||
| -rw-r--r-- | include/net/bluetooth/hci_core.h | 172 | ||||
| -rw-r--r-- | include/net/bluetooth/l2cap.h | 2 | ||||
| -rw-r--r-- | include/net/bluetooth/mgmt.h | 56 | ||||
| -rw-r--r-- | include/net/bluetooth/rfcomm.h | 15 |
5 files changed, 265 insertions, 31 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 352d3d7d06b..16587dcd6a9 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -118,6 +118,7 @@ enum { HCI_DEBUG_KEYS, HCI_DUT_MODE, HCI_FORCE_SC, + HCI_FORCE_STATIC_ADDR, HCI_UNREGISTER, HCI_USER_CHANNEL, @@ -125,6 +126,9 @@ enum { HCI_SSP_ENABLED, HCI_SC_ENABLED, HCI_SC_ONLY, + HCI_PRIVACY, + HCI_RPA_EXPIRED, + HCI_RPA_RESOLVING, HCI_HS_ENABLED, HCI_LE_ENABLED, HCI_ADVERTISING, @@ -136,6 +140,7 @@ enum { 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 @@ -178,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 @@ -352,6 +359,7 @@ enum { /* ---- 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 @@ -359,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 @@ -1045,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; @@ -1055,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; @@ -1176,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; @@ -1200,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; @@ -1214,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; @@ -1626,7 +1673,7 @@ 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; diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 92fa75fce29..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 { @@ -91,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; @@ -99,7 +111,15 @@ struct smp_ltk { u8 type; u8 enc_size; __le16 ediv; - u8 rand[8]; + __le64 rand; + u8 val[16]; +}; + +struct smp_irk { + struct list_head list; + bdaddr_t rpa; + bdaddr_t bdaddr; + u8 addr_type; u8 val[16]; }; @@ -122,6 +142,13 @@ struct oob_data { #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; @@ -143,8 +170,9 @@ struct hci_dev { __u8 bus; __u8 dev_type; bdaddr_t bdaddr; + bdaddr_t random_addr; bdaddr_t static_addr; - __u8 own_addr_type; + __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]; @@ -169,10 +197,15 @@ struct hci_dev { __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; @@ -259,6 +292,7 @@ struct hci_dev { __u32 req_status; __u32 req_result; + struct crypto_blkcipher *tfm_aes; struct discovery_state discovery; struct hci_conn_hash conn_hash; @@ -268,8 +302,11 @@ struct hci_dev { 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; @@ -291,6 +328,11 @@ struct hci_dev { __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); @@ -310,6 +352,10 @@ struct hci_conn { __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; @@ -334,8 +380,13 @@ struct hci_conn { __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; @@ -349,6 +400,7 @@ struct hci_conn { struct delayed_work disc_work; struct delayed_work auto_accept_work; struct delayed_work idle_work; + struct delayed_work le_conn_timeout; struct device dev; @@ -382,6 +434,12 @@ struct hci_conn_params { 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; @@ -542,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) { @@ -615,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); @@ -627,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, @@ -758,35 +827,57 @@ int hci_inquiry(void __user *arg); struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); -int hci_blacklist_clear(struct hci_dev *hdev); 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); +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); -void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, - u16 conn_min_interval, u16 conn_max_interval); +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_uuids_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); -int hci_link_keys_clear(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], +struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand, bool master); -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_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, bool master); -int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr); -int hci_smp_ltks_clear(struct hci_dev *hdev); +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, @@ -1054,6 +1145,26 @@ static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type) return false; } +static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type) +{ + if (addr_type != 0x01) + return false; + + if ((bdaddr->b[5] & 0xc0) == 0x40) + return true; + + return false; +} + +static inline struct smp_irk *hci_get_irk(struct hci_dev *hdev, + bdaddr_t *bdaddr, u8 addr_type) +{ + if (!hci_bdaddr_is_rpa(bdaddr, addr_type)) + return NULL; + + return hci_find_irk_by_rpa(hdev, bdaddr); +} + int hci_register_cb(struct hci_cb *hcb); int hci_unregister_cb(struct hci_cb *hcb); @@ -1075,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, @@ -1107,8 +1221,8 @@ 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 @@ -1120,6 +1234,7 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered); 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); @@ -1127,7 +1242,8 @@ 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); + 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, @@ -1138,7 +1254,7 @@ void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 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); @@ -1166,14 +1282,19 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, 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 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); -void 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) @@ -1205,9 +1326,14 @@ struct hci_sec_filter { 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]); +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 #define SCO_AIRMODE_TRANSP 0x0003 diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index ae482f41594..4abdcb220e3 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -857,7 +857,6 @@ static inline long l2cap_chan_no_get_sndtimeo(struct l2cap_chan *chan) } extern bool disable_ertm; -extern bool enable_lecoc; int l2cap_init_sockets(void); void l2cap_cleanup_sockets(void); @@ -882,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 4303fa90b7c..bcffc9ae0c8 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -96,6 +96,7 @@ struct mgmt_rp_read_index_list { #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 @@ -180,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 type; __u8 master; __u8 enc_size; __le16 ediv; - __u8 rand[8]; + __le64 rand; __u8 val[16]; } __packed; @@ -389,6 +393,37 @@ struct mgmt_cp_set_scan_params { #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; @@ -524,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 c312cfc4e92..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) { @@ -324,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; |
