summaryrefslogtreecommitdiff
path: root/include/net/bluetooth
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/bluetooth')
-rw-r--r--include/net/bluetooth/bluetooth.h31
-rw-r--r--include/net/bluetooth/hci.h55
-rw-r--r--include/net/bluetooth/hci_core.h151
-rw-r--r--include/net/bluetooth/hci_sock.h4
-rw-r--r--include/net/bluetooth/l2cap.h8
-rw-r--r--include/net/bluetooth/mgmt.h187
-rw-r--r--include/net/bluetooth/sco.h2
7 files changed, 395 insertions, 43 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 1576353a2773..9125effbf448 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -41,6 +41,8 @@
#define BLUETOOTH_VER_1_1 1
#define BLUETOOTH_VER_1_2 2
#define BLUETOOTH_VER_2_0 3
+#define BLUETOOTH_VER_2_1 4
+#define BLUETOOTH_VER_4_0 6
/* Reserv for core and drivers use */
#define BT_SKB_RESERVE 8
@@ -139,12 +141,30 @@ struct bt_voice {
#define BT_PHY_LE_CODED_TX 0x00002000
#define BT_PHY_LE_CODED_RX 0x00004000
+#define BT_MODE 15
+
+#define BT_MODE_BASIC 0x00
+#define BT_MODE_ERTM 0x01
+#define BT_MODE_STREAMING 0x02
+#define BT_MODE_LE_FLOWCTL 0x03
+#define BT_MODE_EXT_FLOWCTL 0x04
+
+#define BT_PKT_STATUS 16
+
+#define BT_SCM_PKT_STATUS 0x03
+
__printf(1, 2)
void bt_info(const char *fmt, ...);
__printf(1, 2)
void bt_warn(const char *fmt, ...);
__printf(1, 2)
void bt_err(const char *fmt, ...);
+#if IS_ENABLED(CONFIG_BT_FEATURE_DEBUG)
+void bt_dbg_set(bool enable);
+bool bt_dbg_get(void);
+__printf(1, 2)
+void bt_dbg(const char *fmt, ...);
+#endif
__printf(1, 2)
void bt_warn_ratelimited(const char *fmt, ...);
__printf(1, 2)
@@ -153,7 +173,12 @@ void bt_err_ratelimited(const char *fmt, ...);
#define BT_INFO(fmt, ...) bt_info(fmt "\n", ##__VA_ARGS__)
#define BT_WARN(fmt, ...) bt_warn(fmt "\n", ##__VA_ARGS__)
#define BT_ERR(fmt, ...) bt_err(fmt "\n", ##__VA_ARGS__)
+
+#if IS_ENABLED(CONFIG_BT_FEATURE_DEBUG)
+#define BT_DBG(fmt, ...) bt_dbg(fmt "\n", ##__VA_ARGS__)
+#else
#define BT_DBG(fmt, ...) pr_debug(fmt "\n", ##__VA_ARGS__)
+#endif
#define bt_dev_info(hdev, fmt, ...) \
BT_INFO("%s: " fmt, (hdev)->name, ##__VA_ARGS__)
@@ -267,6 +292,7 @@ struct bt_sock {
struct sock *parent;
unsigned long flags;
void (*skb_msg_name)(struct sk_buff *, void *, int *);
+ void (*skb_put_cmsg)(struct sk_buff *, struct msghdr *, struct sock *);
};
enum {
@@ -316,6 +342,10 @@ struct l2cap_ctrl {
struct l2cap_chan *chan;
};
+struct sco_ctrl {
+ u8 pkt_status;
+};
+
struct hci_dev;
typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status, u16 opcode);
@@ -342,6 +372,7 @@ struct bt_skb_cb {
u8 incoming:1;
union {
struct l2cap_ctrl l2cap;
+ struct sco_ctrl sco;
struct hci_ctrl hci;
};
};
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 5f60e135aeb6..c8e67042a3b1 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -53,6 +53,9 @@
#define HCI_NOTIFY_CONN_ADD 1
#define HCI_NOTIFY_CONN_DEL 2
#define HCI_NOTIFY_VOICE_SETTING 3
+#define HCI_NOTIFY_ENABLE_SCO_CVSD 4
+#define HCI_NOTIFY_ENABLE_SCO_TRANSP 5
+#define HCI_NOTIFY_DISABLE_SCO 6
/* HCI bus types */
#define HCI_VIRTUAL 0
@@ -65,6 +68,7 @@
#define HCI_SPI 7
#define HCI_I2C 8
#define HCI_SMD 9
+#define HCI_VIRTIO 10
/* HCI controller types */
#define HCI_PRIMARY 0x00
@@ -214,6 +218,26 @@ enum {
* This quirk must be set before hci_register_dev is called.
*/
HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
+
+ /* When this quirk is set, the controller has validated that
+ * LE states reported through the HCI_LE_READ_SUPPORTED_STATES are
+ * valid. This mechanism is necessary as many controllers have
+ * been seen has having trouble initiating a connectable
+ * advertisement despite the state combination being reported as
+ * supported.
+ */
+ HCI_QUIRK_VALID_LE_STATES,
+
+ /* When this quirk is set, then erroneous data reporting
+ * is ignored. This is mainly due to the fact that the HCI
+ * Read Default Erroneous Data Reporting command is advertised,
+ * but not supported; these controllers often reply with unknown
+ * command and tend to lock up randomly. Needing a hard reset.
+ *
+ * This quirk can be set before hci_register_dev is called or
+ * during the hdev->setup vendor callback.
+ */
+ HCI_QUIRK_BROKEN_ERR_DATA_REPORTING,
};
/* HCI device flags */
@@ -245,6 +269,7 @@ enum {
HCI_MGMT_DEV_CLASS_EVENTS,
HCI_MGMT_LOCAL_NAME_EVENTS,
HCI_MGMT_OOB_DATA_EVENTS,
+ HCI_MGMT_EXP_FEATURE_EVENTS,
};
/*
@@ -293,7 +318,9 @@ enum {
HCI_FORCE_BREDR_SMP,
HCI_FORCE_STATIC_ADDR,
HCI_LL_RPA_RESOLUTION,
+ HCI_ENABLE_LL_PRIVACY,
HCI_CMD_PENDING,
+ HCI_FORCE_NO_MITM,
__HCI_NUM_FLAGS,
};
@@ -455,12 +482,11 @@ enum {
#define HCI_LE_SLAVE_FEATURES 0x08
#define HCI_LE_PING 0x10
#define HCI_LE_DATA_LEN_EXT 0x20
-#define HCI_LE_PHY_2M 0x01
-#define HCI_LE_PHY_CODED 0x08
-#define HCI_LE_EXT_ADV 0x10
+#define HCI_LE_LL_PRIVACY 0x40
#define HCI_LE_EXT_SCAN_POLICY 0x80
#define HCI_LE_PHY_2M 0x01
#define HCI_LE_PHY_CODED 0x08
+#define HCI_LE_EXT_ADV 0x10
#define HCI_LE_CHAN_SEL_ALG2 0x40
#define HCI_LE_CIS_MASTER 0x10
#define HCI_LE_CIS_SLAVE 0x20
@@ -1272,6 +1298,13 @@ struct hci_rp_read_data_block_size {
#define HCI_OP_READ_LOCAL_CODECS 0x100b
+#define HCI_OP_READ_LOCAL_PAIRING_OPTS 0x100c
+struct hci_rp_read_local_pairing_opts {
+ __u8 status;
+ __u8 pairing_opts;
+ __u8 max_key_size;
+} __packed;
+
#define HCI_OP_READ_PAGE_SCAN_ACTIVITY 0x0c1b
struct hci_rp_read_page_scan_activity {
__u8 status;
@@ -1616,6 +1649,8 @@ struct hci_rp_le_read_resolv_list_size {
#define HCI_OP_LE_SET_ADDR_RESOLV_ENABLE 0x202d
+#define HCI_OP_LE_SET_RPA_TIMEOUT 0x202e
+
#define HCI_OP_LE_READ_MAX_DATA_LEN 0x202f
struct hci_rp_le_read_max_data_len {
__u8 status;
@@ -2247,8 +2282,10 @@ struct hci_ev_le_conn_complete {
#define LE_EXT_ADV_SCAN_RSP 0x0008
#define LE_EXT_ADV_LEGACY_PDU 0x0010
-#define ADDR_LE_DEV_PUBLIC 0x00
-#define ADDR_LE_DEV_RANDOM 0x01
+#define ADDR_LE_DEV_PUBLIC 0x00
+#define ADDR_LE_DEV_RANDOM 0x01
+#define ADDR_LE_DEV_PUBLIC_RESOLVED 0x02
+#define ADDR_LE_DEV_RANDOM_RESOLVED 0x03
#define HCI_EV_LE_ADVERTISING_REPORT 0x02
struct hci_ev_le_advertising_info {
@@ -2495,4 +2532,12 @@ static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb)
#define hci_iso_data_len(h) ((h) & 0x3fff)
#define hci_iso_data_flags(h) ((h) >> 14)
+/* le24 support */
+static inline void hci_cpu_to_le24(__u32 val, __u8 dst[3])
+{
+ dst[0] = val & 0xff;
+ dst[1] = (val & 0xff00) >> 8;
+ dst[2] = (val & 0xff0000) >> 16;
+}
+
#endif /* __HCI_H */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index d4e28773d378..9873e1c8cd16 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -25,6 +25,7 @@
#ifndef __HCI_CORE_H
#define __HCI_CORE_H
+#include <linux/idr.h>
#include <linux/leds.h>
#include <linux/rculist.h>
@@ -110,7 +111,7 @@ enum suspend_tasks {
enum suspended_state {
BT_RUNNING = 0,
BT_SUSPEND_DISCONNECT,
- BT_SUSPEND_COMPLETE,
+ BT_SUSPEND_CONFIGURE_WAKE,
};
struct hci_conn_hash {
@@ -136,6 +137,23 @@ struct bdaddr_list_with_irk {
u8 local_irk[16];
};
+struct bdaddr_list_with_flags {
+ struct list_head list;
+ bdaddr_t bdaddr;
+ u8 bdaddr_type;
+ u32 current_flags;
+};
+
+enum hci_conn_flags {
+ HCI_CONN_FLAG_REMOTE_WAKEUP,
+ HCI_CONN_FLAG_MAX
+};
+
+#define hci_conn_test_flag(nr, flags) ((flags) & (1U << nr))
+
+/* Make sure number of flags doesn't exceed sizeof(current_flags) */
+static_assert(HCI_CONN_FLAG_MAX < 32);
+
struct bt_uuid {
struct list_head list;
u8 uuid[16];
@@ -220,6 +238,24 @@ struct adv_info {
#define HCI_MAX_ADV_INSTANCES 5
#define HCI_DEFAULT_ADV_DURATION 2
+struct adv_pattern {
+ struct list_head list;
+ __u8 ad_type;
+ __u8 offset;
+ __u8 length;
+ __u8 value[HCI_MAX_AD_LENGTH];
+};
+
+struct adv_monitor {
+ struct list_head patterns;
+ bool active;
+ __u16 handle;
+};
+
+#define HCI_MIN_ADV_MONITOR_HANDLE 1
+#define HCI_MAX_ADV_MONITOR_NUM_HANDLES 32
+#define HCI_MAX_ADV_MONITOR_NUM_PATTERNS 16
+
#define HCI_MAX_SHORT_NAME_LENGTH 10
/* Min encryption key size to match with SMP */
@@ -295,6 +331,14 @@ struct hci_dev {
__u8 le_scan_type;
__u16 le_scan_interval;
__u16 le_scan_window;
+ __u16 le_scan_int_suspend;
+ __u16 le_scan_window_suspend;
+ __u16 le_scan_int_discovery;
+ __u16 le_scan_window_discovery;
+ __u16 le_scan_int_adv_monitor;
+ __u16 le_scan_window_adv_monitor;
+ __u16 le_scan_int_connect;
+ __u16 le_scan_window_connect;
__u16 le_conn_min_interval;
__u16 le_conn_max_interval;
__u16 le_conn_latency;
@@ -312,6 +356,8 @@ struct hci_dev {
__u16 conn_info_max_age;
__u16 auth_payload_timeout;
__u8 min_enc_key_size;
+ __u8 max_enc_key_size;
+ __u8 pairing_opts;
__u8 ssp_debug_mode;
__u8 hw_error_code;
__u32 clock;
@@ -321,6 +367,17 @@ struct hci_dev {
__u16 devid_product;
__u16 devid_version;
+ __u8 def_page_scan_type;
+ __u16 def_page_scan_int;
+ __u16 def_page_scan_window;
+ __u8 def_inq_scan_type;
+ __u16 def_inq_scan_int;
+ __u16 def_inq_scan_window;
+ __u16 def_br_lsto;
+ __u16 def_page_timeout;
+ __u16 def_multi_adv_rotation_duration;
+ __u16 def_le_autoconnect_timeout;
+
__u16 pkt_type;
__u16 esco_type;
__u16 link_policy;
@@ -427,6 +484,9 @@ struct hci_dev {
enum suspended_state suspend_state;
bool scanning_paused;
bool suspended;
+ u8 wake_reason;
+ bdaddr_t wake_addr;
+ u8 wake_addr_type;
wait_queue_head_t suspend_wait_q;
DECLARE_BITMAP(suspend_tasks, __SUSPEND_NUM_TASKS);
@@ -436,7 +496,6 @@ struct hci_dev {
struct list_head mgmt_pending;
struct list_head blacklist;
struct list_head whitelist;
- struct list_head wakeable;
struct list_head uuids;
struct list_head link_keys;
struct list_head long_term_keys;
@@ -475,6 +534,9 @@ struct hci_dev {
__u16 adv_instance_timeout;
struct delayed_work adv_instance_expire;
+ struct idr adv_monitors_idr;
+ unsigned int adv_monitors_cnt;
+
__u8 irk[16];
__u32 rpa_timeout;
struct delayed_work rpa_expired;
@@ -484,6 +546,11 @@ struct hci_dev {
struct led_trigger *power_led;
#endif
+#if IS_ENABLED(CONFIG_BT_MSFTEXT)
+ __u16 msft_opcode;
+ void *msft_data;
+#endif
+
int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
int (*flush)(struct hci_dev *hdev);
@@ -496,10 +563,17 @@ struct hci_dev {
int (*set_diag)(struct hci_dev *hdev, bool enable);
int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr);
void (*cmd_timeout)(struct hci_dev *hdev);
+ bool (*prevent_wake)(struct hci_dev *hdev);
};
#define HCI_PHY_HANDLE(handle) (handle & 0xff)
+enum conn_reasons {
+ CONN_REASON_PAIR_DEVICE,
+ CONN_REASON_L2CAP_CHAN,
+ CONN_REASON_SCO_CONNECT,
+};
+
struct hci_conn {
struct list_head list;
@@ -551,6 +625,8 @@ struct hci_conn {
__s8 max_tx_power;
unsigned long flags;
+ enum conn_reasons conn_reason;
+
__u32 clock;
__u16 clock_accuracy;
@@ -618,7 +694,7 @@ struct hci_conn_params {
struct hci_conn *conn;
bool explicit_connect;
- bool wakeable;
+ u32 current_flags;
};
extern struct list_head hci_dev_list;
@@ -638,6 +714,7 @@ extern struct mutex hci_cb_list_lock;
do { \
hci_dev_clear_flag(hdev, HCI_LE_SCAN); \
hci_dev_clear_flag(hdev, HCI_LE_ADV); \
+ hci_dev_clear_flag(hdev, HCI_LL_RPA_RESOLUTION);\
hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ); \
} while (0)
@@ -975,12 +1052,14 @@ struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);
struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
u8 dst_type, u8 sec_level,
- u16 conn_timeout);
+ u16 conn_timeout,
+ enum conn_reasons conn_reason);
struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
u8 dst_type, u8 sec_level, u16 conn_timeout,
u8 role, bdaddr_t *direct_rpa);
struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
- u8 sec_level, u8 auth_type);
+ u8 sec_level, u8 auth_type,
+ enum conn_reasons conn_reason);
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);
@@ -1116,6 +1195,14 @@ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb);
int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb);
__printf(2, 3) void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...);
__printf(2, 3) void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...);
+
+static inline void hci_set_msft_opcode(struct hci_dev *hdev, __u16 opcode)
+{
+#if IS_ENABLED(CONFIG_BT_MSFTEXT)
+ hdev->msft_opcode = opcode;
+#endif
+}
+
int hci_dev_open(__u16 dev);
int hci_dev_close(__u16 dev);
int hci_dev_do_close(struct hci_dev *hdev);
@@ -1134,12 +1221,19 @@ struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *list,
struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
struct list_head *list, bdaddr_t *bdaddr,
u8 type);
+struct bdaddr_list_with_flags *
+hci_bdaddr_list_lookup_with_flags(struct list_head *list, bdaddr_t *bdaddr,
+ u8 type);
int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type);
int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
- u8 type, u8 *peer_irk, u8 *local_irk);
+ u8 type, u8 *peer_irk, u8 *local_irk);
+int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
+ u8 type, u32 flags);
int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type);
int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
- u8 type);
+ u8 type);
+int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
+ u8 type);
void hci_bdaddr_list_clear(struct list_head *list);
struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
@@ -1200,6 +1294,12 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance);
void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired);
+void hci_adv_monitors_clear(struct hci_dev *hdev);
+void hci_free_adv_monitor(struct adv_monitor *monitor);
+int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor);
+int hci_remove_adv_monitor(struct hci_dev *hdev, u16 handle);
+bool hci_is_adv_monitoring(struct hci_dev *hdev);
+
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
void hci_init_sysfs(struct hci_dev *hdev);
@@ -1262,6 +1362,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define scan_coded(dev) (((dev)->le_tx_def_phys & HCI_LE_SET_PHY_CODED) || \
((dev)->le_rx_def_phys & HCI_LE_SET_PHY_CODED))
+/* Use LL Privacy based address resolution if supported */
+#define use_ll_privacy(dev) ((dev)->le_features[0] & HCI_LE_LL_PRIVACY)
+
/* Use ext scanning if set ext scan param and ext scan enable is supported */
#define use_ext_scan(dev) (((dev)->commands[37] & 0x20) && \
((dev)->commands[37] & 0x40))
@@ -1364,16 +1467,34 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
conn->security_cfm_cb(conn, status);
}
-static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status,
- __u8 encrypt)
+static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
{
struct hci_cb *cb;
+ __u8 encrypt;
- if (conn->sec_level == BT_SECURITY_SDP)
- conn->sec_level = BT_SECURITY_LOW;
+ if (conn->state == BT_CONFIG) {
+ if (!status)
+ conn->state = BT_CONNECTED;
- if (conn->pending_sec_level > conn->sec_level)
- conn->sec_level = conn->pending_sec_level;
+ hci_connect_cfm(conn, status);
+ hci_conn_drop(conn);
+ return;
+ }
+
+ if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
+ encrypt = 0x00;
+ else if (test_bit(HCI_CONN_AES_CCM, &conn->flags))
+ encrypt = 0x02;
+ else
+ encrypt = 0x01;
+
+ if (!status) {
+ if (conn->sec_level == BT_SECURITY_SDP)
+ conn->sec_level = BT_SECURITY_LOW;
+
+ if (conn->pending_sec_level > conn->sec_level)
+ conn->sec_level = conn->pending_sec_level;
+ }
mutex_lock(&hci_cb_list_lock);
list_for_each_entry(cb, &hci_cb_list, list) {
@@ -1538,6 +1659,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
#define HCI_MGMT_NO_HDEV BIT(1)
#define HCI_MGMT_UNTRUSTED BIT(2)
#define HCI_MGMT_UNCONFIGURED BIT(3)
+#define HCI_MGMT_HDEV_OPTIONAL BIT(4)
struct hci_mgmt_handler {
int (*func) (struct sock *sk, struct hci_dev *hdev, void *data,
@@ -1631,6 +1753,9 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
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);
+void mgmt_suspending(struct hci_dev *hdev, u8 state);
+void mgmt_resuming(struct hci_dev *hdev, u8 reason, bdaddr_t *bdaddr,
+ u8 addr_type);
bool mgmt_powering_down(struct hci_dev *hdev);
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, bool persistent);
diff --git a/include/net/bluetooth/hci_sock.h b/include/net/bluetooth/hci_sock.h
index 9352bb1bf34c..9949870f7d78 100644
--- a/include/net/bluetooth/hci_sock.h
+++ b/include/net/bluetooth/hci_sock.h
@@ -31,8 +31,8 @@
#define HCI_TIME_STAMP 3
/* CMSG flags */
-#define HCI_CMSG_DIR 0x0001
-#define HCI_CMSG_TSTAMP 0x0002
+#define HCI_CMSG_DIR 0x01
+#define HCI_CMSG_TSTAMP 0x02
struct sockaddr_hci {
sa_family_t hci_family;
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index dada14d0622c..1d1232917de7 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -499,7 +499,7 @@ struct l2cap_ecred_conn_req {
__le16 mtu;
__le16 mps;
__le16 credits;
- __le16 scid[0];
+ __le16 scid[];
} __packed;
struct l2cap_ecred_conn_rsp {
@@ -507,13 +507,13 @@ struct l2cap_ecred_conn_rsp {
__le16 mps;
__le16 credits;
__le16 result;
- __le16 dcid[0];
+ __le16 dcid[];
};
struct l2cap_ecred_reconf_req {
__le16 mtu;
__le16 mps;
- __le16 scid[0];
+ __le16 scid[];
} __packed;
#define L2CAP_RECONF_SUCCESS 0x0000
@@ -665,6 +665,8 @@ struct l2cap_ops {
struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
unsigned long hdr_len,
unsigned long len, int nb);
+ int (*filter) (struct l2cap_chan * chan,
+ struct sk_buff *skb);
};
struct l2cap_conn {
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index f41cd87550dc..6b55155e05e9 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -52,6 +52,12 @@ struct mgmt_hdr {
__le16 len;
} __packed;
+struct mgmt_tlv {
+ __le16 type;
+ __u8 length;
+ __u8 value[];
+} __packed;
+
struct mgmt_addr_info {
bdaddr_t bdaddr;
__u8 type;
@@ -70,14 +76,14 @@ struct mgmt_rp_read_version {
struct mgmt_rp_read_commands {
__le16 num_commands;
__le16 num_events;
- __le16 opcodes[0];
+ __le16 opcodes[];
} __packed;
#define MGMT_OP_READ_INDEX_LIST 0x0003
#define MGMT_READ_INDEX_LIST_SIZE 0
struct mgmt_rp_read_index_list {
__le16 num_controllers;
- __le16 index[0];
+ __le16 index[];
} __packed;
/* Reserve one extra byte for names in management messages so that they
@@ -183,7 +189,7 @@ struct mgmt_link_key_info {
struct mgmt_cp_load_link_keys {
__u8 debug_keys;
__le16 key_count;
- struct mgmt_link_key_info keys[0];
+ struct mgmt_link_key_info keys[];
} __packed;
#define MGMT_LOAD_LINK_KEYS_SIZE 3
@@ -206,7 +212,7 @@ struct mgmt_ltk_info {
#define MGMT_OP_LOAD_LONG_TERM_KEYS 0x0013
struct mgmt_cp_load_long_term_keys {
__le16 key_count;
- struct mgmt_ltk_info keys[0];
+ struct mgmt_ltk_info keys[];
} __packed;
#define MGMT_LOAD_LONG_TERM_KEYS_SIZE 2
@@ -223,7 +229,7 @@ struct mgmt_rp_disconnect {
#define MGMT_GET_CONNECTIONS_SIZE 0
struct mgmt_rp_get_connections {
__le16 conn_count;
- struct mgmt_addr_info addr[0];
+ struct mgmt_addr_info addr[];
} __packed;
#define MGMT_OP_PIN_CODE_REPLY 0x0016
@@ -413,7 +419,7 @@ struct mgmt_irk_info {
#define MGMT_OP_LOAD_IRKS 0x0030
struct mgmt_cp_load_irks {
__le16 irk_count;
- struct mgmt_irk_info irks[0];
+ struct mgmt_irk_info irks[];
} __packed;
#define MGMT_LOAD_IRKS_SIZE 2
@@ -465,7 +471,7 @@ struct mgmt_conn_param {
#define MGMT_OP_LOAD_CONN_PARAM 0x0035
struct mgmt_cp_load_conn_param {
__le16 param_count;
- struct mgmt_conn_param params[0];
+ struct mgmt_conn_param params[];
} __packed;
#define MGMT_LOAD_CONN_PARAM_SIZE 2
@@ -473,7 +479,7 @@ struct mgmt_cp_load_conn_param {
#define MGMT_READ_UNCONF_INDEX_LIST_SIZE 0
struct mgmt_rp_read_unconf_index_list {
__le16 num_controllers;
- __le16 index[0];
+ __le16 index[];
} __packed;
#define MGMT_OPTION_EXTERNAL_CONFIG 0x00000001
@@ -504,7 +510,7 @@ struct mgmt_cp_start_service_discovery {
__u8 type;
__s8 rssi;
__le16 uuid_count;
- __u8 uuids[0][16];
+ __u8 uuids[][16];
} __packed;
#define MGMT_START_SERVICE_DISCOVERY_SIZE 4
@@ -516,7 +522,7 @@ struct mgmt_cp_read_local_oob_ext_data {
struct mgmt_rp_read_local_oob_ext_data {
__u8 type;
__le16 eir_len;
- __u8 eir[0];
+ __u8 eir[];
} __packed;
#define MGMT_OP_READ_EXT_INDEX_LIST 0x003C
@@ -527,7 +533,7 @@ struct mgmt_rp_read_ext_index_list {
__le16 index;
__u8 type;
__u8 bus;
- } entry[0];
+ } entry[];
} __packed;
#define MGMT_OP_READ_ADV_FEATURES 0x0003D
@@ -538,7 +544,7 @@ struct mgmt_rp_read_adv_features {
__u8 max_scan_rsp_len;
__u8 max_instances;
__u8 num_instances;
- __u8 instance[0];
+ __u8 instance[];
} __packed;
#define MGMT_OP_ADD_ADVERTISING 0x003E
@@ -549,7 +555,7 @@ struct mgmt_cp_add_advertising {
__le16 timeout;
__u8 adv_data_len;
__u8 scan_rsp_len;
- __u8 data[0];
+ __u8 data[];
} __packed;
#define MGMT_ADD_ADVERTISING_SIZE 11
struct mgmt_rp_add_advertising {
@@ -566,6 +572,8 @@ struct mgmt_rp_add_advertising {
#define MGMT_ADV_FLAG_SEC_1M BIT(7)
#define MGMT_ADV_FLAG_SEC_2M BIT(8)
#define MGMT_ADV_FLAG_SEC_CODED BIT(9)
+#define MGMT_ADV_FLAG_CAN_SET_TX_POWER BIT(10)
+#define MGMT_ADV_FLAG_HW_OFFLOAD BIT(11)
#define MGMT_ADV_FLAG_SEC_MASK (MGMT_ADV_FLAG_SEC_1M | MGMT_ADV_FLAG_SEC_2M | \
MGMT_ADV_FLAG_SEC_CODED)
@@ -603,7 +611,7 @@ struct mgmt_rp_read_ext_info {
__le32 supported_settings;
__le32 current_settings;
__le16 eir_len;
- __u8 eir[0];
+ __u8 eir[];
} __packed;
#define MGMT_OP_SET_APPEARANCE 0x0043
@@ -668,17 +676,117 @@ struct mgmt_blocked_key_info {
struct mgmt_cp_set_blocked_keys {
__le16 key_count;
- struct mgmt_blocked_key_info keys[0];
+ struct mgmt_blocked_key_info keys[];
} __packed;
#define MGMT_OP_SET_BLOCKED_KEYS_SIZE 2
#define MGMT_OP_SET_WIDEBAND_SPEECH 0x0047
+#define MGMT_OP_READ_SECURITY_INFO 0x0048
+#define MGMT_READ_SECURITY_INFO_SIZE 0
+struct mgmt_rp_read_security_info {
+ __le16 sec_len;
+ __u8 sec[];
+} __packed;
+
+#define MGMT_OP_READ_EXP_FEATURES_INFO 0x0049
+#define MGMT_READ_EXP_FEATURES_INFO_SIZE 0
+struct mgmt_rp_read_exp_features_info {
+ __le16 feature_count;
+ struct {
+ __u8 uuid[16];
+ __le32 flags;
+ } features[];
+} __packed;
+
+#define MGMT_OP_SET_EXP_FEATURE 0x004a
+struct mgmt_cp_set_exp_feature {
+ __u8 uuid[16];
+ __u8 param[];
+} __packed;
+#define MGMT_SET_EXP_FEATURE_SIZE 16
+struct mgmt_rp_set_exp_feature {
+ __u8 uuid[16];
+ __le32 flags;
+} __packed;
+
+#define MGMT_OP_READ_DEF_SYSTEM_CONFIG 0x004b
+#define MGMT_READ_DEF_SYSTEM_CONFIG_SIZE 0
+
+#define MGMT_OP_SET_DEF_SYSTEM_CONFIG 0x004c
+#define MGMT_SET_DEF_SYSTEM_CONFIG_SIZE 0
+
+#define MGMT_OP_READ_DEF_RUNTIME_CONFIG 0x004d
+#define MGMT_READ_DEF_RUNTIME_CONFIG_SIZE 0
+
+#define MGMT_OP_SET_DEF_RUNTIME_CONFIG 0x004e
+#define MGMT_SET_DEF_RUNTIME_CONFIG_SIZE 0
+
+#define MGMT_OP_GET_DEVICE_FLAGS 0x004F
+#define MGMT_GET_DEVICE_FLAGS_SIZE 7
+struct mgmt_cp_get_device_flags {
+ struct mgmt_addr_info addr;
+} __packed;
+struct mgmt_rp_get_device_flags {
+ struct mgmt_addr_info addr;
+ __le32 supported_flags;
+ __le32 current_flags;
+} __packed;
+
+#define MGMT_OP_SET_DEVICE_FLAGS 0x0050
+#define MGMT_SET_DEVICE_FLAGS_SIZE 11
+struct mgmt_cp_set_device_flags {
+ struct mgmt_addr_info addr;
+ __le32 current_flags;
+} __packed;
+struct mgmt_rp_set_device_flags {
+ struct mgmt_addr_info addr;
+} __packed;
+
+#define MGMT_ADV_MONITOR_FEATURE_MASK_OR_PATTERNS BIT(0)
+
+#define MGMT_OP_READ_ADV_MONITOR_FEATURES 0x0051
+#define MGMT_READ_ADV_MONITOR_FEATURES_SIZE 0
+struct mgmt_rp_read_adv_monitor_features {
+ __le32 supported_features;
+ __le32 enabled_features;
+ __le16 max_num_handles;
+ __u8 max_num_patterns;
+ __le16 num_handles;
+ __le16 handles[];
+} __packed;
+
+struct mgmt_adv_pattern {
+ __u8 ad_type;
+ __u8 offset;
+ __u8 length;
+ __u8 value[31];
+} __packed;
+
+#define MGMT_OP_ADD_ADV_PATTERNS_MONITOR 0x0052
+struct mgmt_cp_add_adv_patterns_monitor {
+ __u8 pattern_count;
+ struct mgmt_adv_pattern patterns[];
+} __packed;
+#define MGMT_ADD_ADV_PATTERNS_MONITOR_SIZE 1
+struct mgmt_rp_add_adv_patterns_monitor {
+ __le16 monitor_handle;
+} __packed;
+
+#define MGMT_OP_REMOVE_ADV_MONITOR 0x0053
+struct mgmt_cp_remove_adv_monitor {
+ __le16 monitor_handle;
+} __packed;
+#define MGMT_REMOVE_ADV_MONITOR_SIZE 2
+struct mgmt_rp_remove_adv_monitor {
+ __le16 monitor_handle;
+} __packed;
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
__u8 status;
- __u8 data[0];
+ __u8 data[];
} __packed;
#define MGMT_EV_CMD_STATUS 0x0002
@@ -726,7 +834,7 @@ struct mgmt_ev_device_connected {
struct mgmt_addr_info addr;
__le32 flags;
__le16 eir_len;
- __u8 eir[0];
+ __u8 eir[];
} __packed;
#define MGMT_DEV_DISCONN_UNKNOWN 0x00
@@ -734,6 +842,7 @@ struct mgmt_ev_device_connected {
#define MGMT_DEV_DISCONN_LOCAL_HOST 0x02
#define MGMT_DEV_DISCONN_REMOTE 0x03
#define MGMT_DEV_DISCONN_AUTH_FAILURE 0x04
+#define MGMT_DEV_DISCONN_LOCAL_HOST_SUSPEND 0x05
#define MGMT_EV_DEVICE_DISCONNECTED 0x000C
struct mgmt_ev_device_disconnected {
@@ -781,7 +890,7 @@ struct mgmt_ev_device_found {
__s8 rssi;
__le32 flags;
__le16 eir_len;
- __u8 eir[0];
+ __u8 eir[];
} __packed;
#define MGMT_EV_DISCOVERING 0x0013
@@ -876,7 +985,7 @@ struct mgmt_ev_ext_index {
struct mgmt_ev_local_oob_data_updated {
__u8 type;
__le16 eir_len;
- __u8 eir[0];
+ __u8 eir[];
} __packed;
#define MGMT_EV_ADVERTISING_ADDED 0x0023
@@ -892,10 +1001,48 @@ struct mgmt_ev_advertising_removed {
#define MGMT_EV_EXT_INFO_CHANGED 0x0025
struct mgmt_ev_ext_info_changed {
__le16 eir_len;
- __u8 eir[0];
+ __u8 eir[];
} __packed;
#define MGMT_EV_PHY_CONFIGURATION_CHANGED 0x0026
struct mgmt_ev_phy_configuration_changed {
__le32 selected_phys;
} __packed;
+
+#define MGMT_EV_EXP_FEATURE_CHANGED 0x0027
+struct mgmt_ev_exp_feature_changed {
+ __u8 uuid[16];
+ __le32 flags;
+} __packed;
+
+#define MGMT_EV_DEVICE_FLAGS_CHANGED 0x002a
+struct mgmt_ev_device_flags_changed {
+ struct mgmt_addr_info addr;
+ __le32 supported_flags;
+ __le32 current_flags;
+} __packed;
+
+#define MGMT_EV_ADV_MONITOR_ADDED 0x002b
+struct mgmt_ev_adv_monitor_added {
+ __le16 monitor_handle;
+} __packed;
+
+#define MGMT_EV_ADV_MONITOR_REMOVED 0x002c
+struct mgmt_ev_adv_monitor_removed {
+ __le16 monitor_handle;
+} __packed;
+
+#define MGMT_EV_CONTROLLER_SUSPEND 0x002d
+struct mgmt_ev_controller_suspend {
+ __u8 suspend_state;
+} __packed;
+
+#define MGMT_EV_CONTROLLER_RESUME 0x002e
+struct mgmt_ev_controller_resume {
+ __u8 wake_reason;
+ struct mgmt_addr_info addr;
+} __packed;
+
+#define MGMT_WAKE_REASON_NON_BT_WAKE 0x0
+#define MGMT_WAKE_REASON_UNEXPECTED 0x1
+#define MGMT_WAKE_REASON_REMOTE_WAKE 0x2
diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h
index f40ddb4264fc..1aa2e14b6c94 100644
--- a/include/net/bluetooth/sco.h
+++ b/include/net/bluetooth/sco.h
@@ -46,4 +46,6 @@ struct sco_conninfo {
__u8 dev_class[3];
};
+#define SCO_CMSG_PKT_STATUS 0x01
+
#endif /* __SCO_H */