Commit 33b44342 authored by John W. Linville's avatar John W. Linville

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
parents b476d3f1 d78a32a8
...@@ -282,6 +282,7 @@ struct bt_skb_cb { ...@@ -282,6 +282,7 @@ struct bt_skb_cb {
__u8 incoming; __u8 incoming;
__u16 expect; __u16 expect;
__u8 force_active; __u8 force_active;
struct l2cap_chan *chan;
struct l2cap_ctrl control; struct l2cap_ctrl control;
struct hci_req_ctrl req; struct hci_req_ctrl req;
bdaddr_t bdaddr; bdaddr_t bdaddr;
......
...@@ -115,6 +115,7 @@ enum { ...@@ -115,6 +115,7 @@ enum {
HCI_PAIRABLE, HCI_PAIRABLE,
HCI_SERVICE_CACHE, HCI_SERVICE_CACHE,
HCI_DEBUG_KEYS, HCI_DEBUG_KEYS,
HCI_DUT_MODE,
HCI_UNREGISTER, HCI_UNREGISTER,
HCI_USER_CHANNEL, HCI_USER_CHANNEL,
...@@ -125,6 +126,7 @@ enum { ...@@ -125,6 +126,7 @@ enum {
HCI_ADVERTISING, HCI_ADVERTISING,
HCI_CONNECTABLE, HCI_CONNECTABLE,
HCI_DISCOVERABLE, HCI_DISCOVERABLE,
HCI_LIMITED_DISCOVERABLE,
HCI_LINK_SECURITY, HCI_LINK_SECURITY,
HCI_PERIODIC_INQ, HCI_PERIODIC_INQ,
HCI_FAST_CONNECTABLE, HCI_FAST_CONNECTABLE,
...@@ -823,6 +825,12 @@ struct hci_rp_read_num_supported_iac { ...@@ -823,6 +825,12 @@ struct hci_rp_read_num_supported_iac {
#define HCI_OP_READ_CURRENT_IAC_LAP 0x0c39 #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_OP_WRITE_INQUIRY_MODE 0x0c45
#define HCI_MAX_EIR_LENGTH 240 #define HCI_MAX_EIR_LENGTH 240
...@@ -1036,6 +1044,10 @@ struct hci_rp_write_remote_amp_assoc { ...@@ -1036,6 +1044,10 @@ struct hci_rp_write_remote_amp_assoc {
__u8 phy_handle; __u8 phy_handle;
} __packed; } __packed;
#define HCI_OP_ENABLE_DUT_MODE 0x1803
#define HCI_OP_WRITE_SSP_DEBUG_MODE 0x1804
#define HCI_OP_LE_SET_EVENT_MASK 0x2001 #define HCI_OP_LE_SET_EVENT_MASK 0x2001
struct hci_cp_le_set_event_mask { struct hci_cp_le_set_event_mask {
__u8 mask[8]; __u8 mask[8];
...@@ -1056,11 +1068,6 @@ struct hci_rp_le_read_local_features { ...@@ -1056,11 +1068,6 @@ struct hci_rp_le_read_local_features {
#define HCI_OP_LE_SET_RANDOM_ADDR 0x2005 #define HCI_OP_LE_SET_RANDOM_ADDR 0x2005
#define LE_ADV_IND 0x00
#define LE_ADV_DIRECT_IND 0x01
#define LE_ADV_SCAN_IND 0x02
#define LE_ADV_NONCONN_IND 0x03
#define HCI_OP_LE_SET_ADV_PARAM 0x2006 #define HCI_OP_LE_SET_ADV_PARAM 0x2006
struct hci_cp_le_set_adv_param { struct hci_cp_le_set_adv_param {
__le16 min_interval; __le16 min_interval;
...@@ -1087,6 +1094,12 @@ struct hci_cp_le_set_adv_data { ...@@ -1087,6 +1094,12 @@ struct hci_cp_le_set_adv_data {
__u8 data[HCI_MAX_AD_LENGTH]; __u8 data[HCI_MAX_AD_LENGTH];
} __packed; } __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 HCI_OP_LE_SET_ADV_ENABLE 0x200a
#define LE_SCAN_PASSIVE 0x00 #define LE_SCAN_PASSIVE 0x00
...@@ -1567,11 +1580,11 @@ struct hci_ev_le_ltk_req { ...@@ -1567,11 +1580,11 @@ struct hci_ev_le_ltk_req {
} __packed; } __packed;
/* Advertising report event types */ /* Advertising report event types */
#define ADV_IND 0x00 #define LE_ADV_IND 0x00
#define ADV_DIRECT_IND 0x01 #define LE_ADV_DIRECT_IND 0x01
#define ADV_SCAN_IND 0x02 #define LE_ADV_SCAN_IND 0x02
#define ADV_NONCONN_IND 0x03 #define LE_ADV_NONCONN_IND 0x03
#define ADV_SCAN_RSP 0x04 #define LE_ADV_SCAN_RSP 0x04
#define ADDR_LE_DEV_PUBLIC 0x00 #define ADDR_LE_DEV_PUBLIC 0x00
#define ADDR_LE_DEV_RANDOM 0x01 #define ADDR_LE_DEV_RANDOM 0x01
...@@ -1779,6 +1792,4 @@ struct hci_inquiry_req { ...@@ -1779,6 +1792,4 @@ struct hci_inquiry_req {
}; };
#define IREQ_CACHE_FLUSH 0x0001 #define IREQ_CACHE_FLUSH 0x0001
extern bool enable_hs;
#endif /* __HCI_H */ #endif /* __HCI_H */
...@@ -81,6 +81,7 @@ struct hci_conn_hash { ...@@ -81,6 +81,7 @@ struct hci_conn_hash {
struct bdaddr_list { struct bdaddr_list {
struct list_head list; struct list_head list;
bdaddr_t bdaddr; bdaddr_t bdaddr;
u8 bdaddr_type;
}; };
struct bt_uuid { struct bt_uuid {
...@@ -141,6 +142,7 @@ struct hci_dev { ...@@ -141,6 +142,7 @@ struct hci_dev {
__u8 dev_type; __u8 dev_type;
bdaddr_t bdaddr; bdaddr_t bdaddr;
bdaddr_t static_addr; bdaddr_t static_addr;
__u8 own_addr_type;
__u8 dev_name[HCI_MAX_NAME_LENGTH]; __u8 dev_name[HCI_MAX_NAME_LENGTH];
__u8 short_name[HCI_MAX_SHORT_NAME_LENGTH]; __u8 short_name[HCI_MAX_SHORT_NAME_LENGTH];
__u8 eir[HCI_MAX_EIR_LENGTH]; __u8 eir[HCI_MAX_EIR_LENGTH];
...@@ -167,6 +169,9 @@ struct hci_dev { ...@@ -167,6 +169,9 @@ struct hci_dev {
__u8 page_scan_type; __u8 page_scan_type;
__u16 le_scan_interval; __u16 le_scan_interval;
__u16 le_scan_window; __u16 le_scan_window;
__u16 le_conn_min_interval;
__u16 le_conn_max_interval;
__u8 ssp_debug_mode;
__u16 devid_source; __u16 devid_source;
__u16 devid_vendor; __u16 devid_vendor;
...@@ -283,6 +288,8 @@ struct hci_dev { ...@@ -283,6 +288,8 @@ struct hci_dev {
__s8 adv_tx_power; __s8 adv_tx_power;
__u8 adv_data[HCI_MAX_AD_LENGTH]; __u8 adv_data[HCI_MAX_AD_LENGTH];
__u8 adv_data_len; __u8 adv_data_len;
__u8 scan_rsp_data[HCI_MAX_AD_LENGTH];
__u8 scan_rsp_data_len;
int (*open)(struct hci_dev *hdev); int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev); int (*close)(struct hci_dev *hdev);
...@@ -311,7 +318,6 @@ struct hci_conn { ...@@ -311,7 +318,6 @@ struct hci_conn {
__u8 attempt; __u8 attempt;
__u8 dev_class[3]; __u8 dev_class[3];
__u8 features[HCI_MAX_PAGES][8]; __u8 features[HCI_MAX_PAGES][8];
__u16 interval;
__u16 pkt_type; __u16 pkt_type;
__u16 link_policy; __u16 link_policy;
__u32 link_mode; __u32 link_mode;
...@@ -339,8 +345,8 @@ struct hci_conn { ...@@ -339,8 +345,8 @@ struct hci_conn {
struct list_head chan_list; struct list_head chan_list;
struct delayed_work disc_work; struct delayed_work disc_work;
struct timer_list idle_timer; struct delayed_work auto_accept_work;
struct timer_list auto_accept_timer; struct delayed_work idle_work;
struct device dev; struct device dev;
...@@ -649,7 +655,7 @@ static inline void hci_conn_drop(struct hci_conn *conn) ...@@ -649,7 +655,7 @@ static inline void hci_conn_drop(struct hci_conn *conn)
switch (conn->type) { switch (conn->type) {
case ACL_LINK: case ACL_LINK:
case LE_LINK: case LE_LINK:
del_timer(&conn->idle_timer); cancel_delayed_work(&conn->idle_work);
if (conn->state == BT_CONNECTED) { if (conn->state == BT_CONNECTED) {
timeo = conn->disc_timeout; timeo = conn->disc_timeout;
if (!conn->out) if (!conn->out)
...@@ -730,7 +736,7 @@ int hci_get_auth_info(struct hci_dev *hdev, void __user *arg); ...@@ -730,7 +736,7 @@ int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);
int hci_inquiry(void __user *arg); int hci_inquiry(void __user *arg);
struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
bdaddr_t *bdaddr); bdaddr_t *bdaddr, u8 type);
int hci_blacklist_clear(struct hci_dev *hdev); int hci_blacklist_clear(struct hci_dev *hdev);
int hci_blacklist_add(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_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
...@@ -765,8 +771,6 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); ...@@ -765,8 +771,6 @@ 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); int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count);
void hci_init_sysfs(struct hci_dev *hdev); 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_init_sysfs(struct hci_conn *conn);
void hci_conn_add_sysfs(struct hci_conn *conn); void hci_conn_add_sysfs(struct hci_conn *conn);
void hci_conn_del_sysfs(struct hci_conn *conn); void hci_conn_del_sysfs(struct hci_conn *conn);
...@@ -1009,34 +1013,6 @@ static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type) ...@@ -1009,34 +1013,6 @@ static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type)
return false; return false;
} }
static inline size_t eir_get_length(u8 *eir, size_t eir_len)
{
size_t parsed = 0;
while (parsed < eir_len) {
u8 field_len = eir[0];
if (field_len == 0)
return parsed;
parsed += field_len + 1;
eir += field_len + 1;
}
return eir_len;
}
static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
u8 data_len)
{
eir[eir_len++] = sizeof(type) + data_len;
eir[eir_len++] = type;
memcpy(&eir[eir_len], data, data_len);
eir_len += data_len;
return eir_len;
}
int hci_register_cb(struct hci_cb *hcb); int hci_register_cb(struct hci_cb *hcb);
int hci_unregister_cb(struct hci_cb *hcb); int hci_unregister_cb(struct hci_cb *hcb);
...@@ -1100,11 +1076,12 @@ void mgmt_index_added(struct hci_dev *hdev); ...@@ -1100,11 +1076,12 @@ void mgmt_index_added(struct hci_dev *hdev);
void mgmt_index_removed(struct hci_dev *hdev); void mgmt_index_removed(struct hci_dev *hdev);
void mgmt_set_powered_failed(struct hci_dev *hdev, int err); void mgmt_set_powered_failed(struct hci_dev *hdev, int err);
int mgmt_powered(struct hci_dev *hdev, u8 powered); int mgmt_powered(struct hci_dev *hdev, u8 powered);
int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); void mgmt_discoverable_timeout(struct hci_dev *hdev);
int mgmt_connectable(struct hci_dev *hdev, u8 connectable); void mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status); void mgmt_connectable(struct hci_dev *hdev, u8 connectable);
int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status);
bool persistent); 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, 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 addr_type, u32 flags, u8 *name, u8 name_len,
u8 *dev_class); u8 *dev_class);
...@@ -1114,11 +1091,11 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, ...@@ -1114,11 +1091,11 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, u8 status); u8 link_type, u8 addr_type, u8 status);
void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 status); u8 addr_type, u8 status);
int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure); void 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, void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 status); u8 status);
int mgmt_pin_code_neg_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); u8 status);
int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, 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, __le32 value,
u8 confirm_hint); u8 confirm_hint);
...@@ -1135,15 +1112,15 @@ int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, ...@@ -1135,15 +1112,15 @@ 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, int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, u32 passkey, u8 link_type, u8 addr_type, u32 passkey,
u8 entered); u8 entered);
int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, void mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 status); u8 addr_type, u8 status);
int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status); void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status);
int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); void 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, void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
u8 status); u8 status);
int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status); void 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, void mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
u8 *randomizer, u8 status); u8 *randomizer, u8 status);
void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 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 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name,
u8 ssp, u8 *eir, u16 eir_len); u8 ssp, u8 *eir, u16 eir_len);
...@@ -1152,7 +1129,7 @@ void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ...@@ -1152,7 +1129,7 @@ void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
void mgmt_discovering(struct hci_dev *hdev, u8 discovering); 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_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
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, u8 persistent);
void mgmt_reenable_advertising(struct hci_dev *hdev); void mgmt_reenable_advertising(struct hci_dev *hdev);
/* HCI info for socket */ /* HCI info for socket */
...@@ -1183,8 +1160,6 @@ struct hci_sec_filter { ...@@ -1183,8 +1160,6 @@ struct hci_sec_filter {
#define hci_req_lock(d) mutex_lock(&d->req_lock) #define hci_req_lock(d) mutex_lock(&d->req_lock)
#define hci_req_unlock(d) mutex_unlock(&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, void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
u16 latency, u16 to_multiplier); 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, __u8 rand[8],
......
...@@ -435,8 +435,6 @@ struct l2cap_seq_list { ...@@ -435,8 +435,6 @@ struct l2cap_seq_list {
#define L2CAP_SEQ_LIST_TAIL 0x8000 #define L2CAP_SEQ_LIST_TAIL 0x8000
struct l2cap_chan { struct l2cap_chan {
struct sock *sk;
struct l2cap_conn *conn; struct l2cap_conn *conn;
struct hci_conn *hs_hcon; struct hci_conn *hs_hcon;
struct hci_chan *hs_hchan; struct hci_chan *hs_hchan;
...@@ -551,10 +549,12 @@ struct l2cap_ops { ...@@ -551,10 +549,12 @@ struct l2cap_ops {
void (*teardown) (struct l2cap_chan *chan, int err); void (*teardown) (struct l2cap_chan *chan, int err);
void (*close) (struct l2cap_chan *chan); void (*close) (struct l2cap_chan *chan);
void (*state_change) (struct l2cap_chan *chan, void (*state_change) (struct l2cap_chan *chan,
int state); int state, int err);
void (*ready) (struct l2cap_chan *chan); void (*ready) (struct l2cap_chan *chan);
void (*defer) (struct l2cap_chan *chan); void (*defer) (struct l2cap_chan *chan);
void (*resume) (struct l2cap_chan *chan); void (*resume) (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, struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
unsigned long len, int nb); unsigned long len, int nb);
}; };
...@@ -795,6 +795,19 @@ static inline void l2cap_chan_no_defer(struct l2cap_chan *chan) ...@@ -795,6 +795,19 @@ 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; extern bool disable_ertm;
int l2cap_init_sockets(void); int l2cap_init_sockets(void);
...@@ -802,7 +815,6 @@ void l2cap_cleanup_sockets(void); ...@@ -802,7 +815,6 @@ void l2cap_cleanup_sockets(void);
bool l2cap_is_socket(struct socket *sock); bool l2cap_is_socket(struct socket *sock);
void __l2cap_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_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid); int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
......
...@@ -672,7 +672,8 @@ static void a2mp_chan_close_cb(struct l2cap_chan *chan) ...@@ -672,7 +672,8 @@ static void a2mp_chan_close_cb(struct l2cap_chan *chan)
l2cap_chan_put(chan); l2cap_chan_put(chan);
} }
static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state) static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state,
int err)
{ {
struct amp_mgr *mgr = chan->data; struct amp_mgr *mgr = chan->data;
...@@ -709,6 +710,9 @@ static struct l2cap_ops a2mp_chan_ops = { ...@@ -709,6 +710,9 @@ static struct l2cap_ops a2mp_chan_ops = {
.teardown = l2cap_chan_no_teardown, .teardown = l2cap_chan_no_teardown,
.ready = l2cap_chan_no_ready, .ready = l2cap_chan_no_ready,
.defer = l2cap_chan_no_defer, .defer = l2cap_chan_no_defer,
.resume = l2cap_chan_no_resume,
.set_shutdown = l2cap_chan_no_set_shutdown,
.get_sndtimeo = l2cap_chan_no_get_sndtimeo,
}; };
static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked) static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked)
...@@ -832,6 +836,9 @@ struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, ...@@ -832,6 +836,9 @@ struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn,
{ {
struct amp_mgr *mgr; struct amp_mgr *mgr;
if (conn->hcon->type != ACL_LINK)
return NULL;
mgr = amp_mgr_create(conn, false); mgr = amp_mgr_create(conn, false);
if (!mgr) { if (!mgr) {
BT_ERR("Could not create AMP manager"); BT_ERR("Could not create AMP manager");
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
/* Bluetooth address family and sockets. */ /* Bluetooth address family and sockets. */
#include <linux/module.h> #include <linux/module.h>
#include <linux/debugfs.h>
#include <asm/ioctls.h> #include <asm/ioctls.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
...@@ -708,12 +709,17 @@ static struct net_proto_family bt_sock_family_ops = { ...@@ -708,12 +709,17 @@ static struct net_proto_family bt_sock_family_ops = {
.create = bt_sock_create, .create = bt_sock_create,
}; };
struct dentry *bt_debugfs;
EXPORT_SYMBOL_GPL(bt_debugfs);
static int __init bt_init(void) static int __init bt_init(void)
{ {
int err; int err;
BT_INFO("Core ver %s", VERSION); BT_INFO("Core ver %s", VERSION);
bt_debugfs = debugfs_create_dir("bluetooth", NULL);
err = bt_sysfs_init(); err = bt_sysfs_init();
if (err < 0) if (err < 0)
return err; return err;
...@@ -754,7 +760,6 @@ static int __init bt_init(void) ...@@ -754,7 +760,6 @@ static int __init bt_init(void)
static void __exit bt_exit(void) static void __exit bt_exit(void)
{ {
sco_exit(); sco_exit();
l2cap_exit(); l2cap_exit();
...@@ -764,6 +769,8 @@ static void __exit bt_exit(void) ...@@ -764,6 +769,8 @@ static void __exit bt_exit(void)
sock_unregister(PF_BLUETOOTH); sock_unregister(PF_BLUETOOTH);
bt_sysfs_cleanup(); bt_sysfs_cleanup();
debugfs_remove_recursive(bt_debugfs);
} }
subsys_initcall(bt_init); subsys_initcall(bt_init);
......
...@@ -317,8 +317,10 @@ static void hci_conn_timeout(struct work_struct *work) ...@@ -317,8 +317,10 @@ static void hci_conn_timeout(struct work_struct *work)
} }
/* Enter sniff mode */ /* Enter sniff mode */
static void hci_conn_enter_sniff_mode(struct hci_conn *conn) static void hci_conn_idle(struct work_struct *work)
{ {
struct hci_conn *conn = container_of(work, struct hci_conn,
idle_work.work);
struct hci_dev *hdev = conn->hdev; struct hci_dev *hdev = conn->hdev;
BT_DBG("hcon %p mode %d", conn, conn->mode); BT_DBG("hcon %p mode %d", conn, conn->mode);
...@@ -352,21 +354,12 @@ static void hci_conn_enter_sniff_mode(struct hci_conn *conn) ...@@ -352,21 +354,12 @@ static void hci_conn_enter_sniff_mode(struct hci_conn *conn)
} }
} }
static void hci_conn_idle(unsigned long arg) static void hci_conn_auto_accept(struct work_struct *work)
{
struct hci_conn *conn = (void *) arg;
BT_DBG("hcon %p mode %d", conn, conn->mode);
hci_conn_enter_sniff_mode(conn);
}
static void hci_conn_auto_accept(unsigned long arg)
{ {
struct hci_conn *conn = (void *) arg; struct hci_conn *conn = container_of(work, struct hci_conn,
struct hci_dev *hdev = conn->hdev; auto_accept_work.work);
hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst), hci_send_cmd(conn->hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst),
&conn->dst); &conn->dst);
} }
...@@ -415,9 +408,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) ...@@ -415,9 +408,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
INIT_LIST_HEAD(&conn->chan_list); INIT_LIST_HEAD(&conn->chan_list);
INIT_DELAYED_WORK(&conn->disc_work, hci_conn_timeout); INIT_DELAYED_WORK(&conn->disc_work, hci_conn_timeout);
setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); INIT_DELAYED_WORK(&conn->auto_accept_work, hci_conn_auto_accept);
setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept, INIT_DELAYED_WORK(&conn->idle_work, hci_conn_idle);
(unsigned long) conn);
atomic_set(&conn->refcnt, 0); atomic_set(&conn->refcnt, 0);
...@@ -438,11 +430,9 @@ int hci_conn_del(struct hci_conn *conn) ...@@ -438,11 +430,9 @@ int hci_conn_del(struct hci_conn *conn)
BT_DBG("%s hcon %p handle %d", hdev->name, conn, conn->handle); BT_DBG("%s hcon %p handle %d", hdev->name, conn, conn->handle);
del_timer(&conn->idle_timer);
cancel_delayed_work_sync(&conn->disc_work); cancel_delayed_work_sync(&conn->disc_work);
cancel_delayed_work_sync(&conn->auto_accept_work);
del_timer(&conn->auto_accept_timer); cancel_delayed_work_sync(&conn->idle_work);
if (conn->type == ACL_LINK) { if (conn->type == ACL_LINK) {
struct hci_conn *sco = conn->link; struct hci_conn *sco = conn->link;
...@@ -568,11 +558,12 @@ static int hci_create_le_conn(struct hci_conn *conn) ...@@ -568,11 +558,12 @@ static int hci_create_le_conn(struct hci_conn *conn)
bacpy(&cp.peer_addr, &conn->dst); bacpy(&cp.peer_addr, &conn->dst);
cp.peer_addr_type = conn->dst_type; cp.peer_addr_type = conn->dst_type;
cp.own_address_type = conn->src_type; cp.own_address_type = conn->src_type;
cp.conn_interval_min = __constant_cpu_to_le16(0x0028); cp.conn_interval_min = cpu_to_le16(hdev->le_conn_min_interval);
cp.conn_interval_max = __constant_cpu_to_le16(0x0038); cp.conn_interval_max = cpu_to_le16(hdev->le_conn_max_interval);
cp.supervision_timeout = __constant_cpu_to_le16(0x002a); cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
cp.min_ce_len = __constant_cpu_to_le16(0x0000); cp.min_ce_len = __constant_cpu_to_le16(0x0000);
cp.max_ce_len = __constant_cpu_to_le16(0x0000); cp.max_ce_len = __constant_cpu_to_le16(0x0000);
hci_req_add(&req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp); hci_req_add(&req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
err = hci_req_run(&req, create_le_conn_complete); err = hci_req_run(&req, create_le_conn_complete);
...@@ -625,12 +616,7 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, ...@@ -625,12 +616,7 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
else else
conn->dst_type = ADDR_LE_DEV_RANDOM; conn->dst_type = ADDR_LE_DEV_RANDOM;
if (bacmp(&conn->src, BDADDR_ANY)) { conn->src_type = hdev->own_addr_type;
conn->src_type = ADDR_LE_DEV_PUBLIC;
} else {
bacpy(&conn->src, &hdev->static_addr);
conn->src_type = ADDR_LE_DEV_RANDOM;
}
conn->state = BT_CONNECT; conn->state = BT_CONNECT;
conn->out = true; conn->out = true;
...@@ -922,8 +908,8 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active) ...@@ -922,8 +908,8 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active)
timer: timer:
if (hdev->idle_timeout > 0) if (hdev->idle_timeout > 0)
mod_timer(&conn->idle_timer, queue_delayed_work(hdev->workqueue, &conn->idle_work,
jiffies + msecs_to_jiffies(hdev->idle_timeout)); msecs_to_jiffies(hdev->idle_timeout));
} }
/* Drop all connection on the device */ /* Drop all connection on the device */
......
This diff is collapsed.
...@@ -195,6 +195,11 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -195,6 +195,11 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
memset(hdev->adv_data, 0, sizeof(hdev->adv_data)); memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
hdev->adv_data_len = 0; hdev->adv_data_len = 0;
memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
hdev->scan_rsp_data_len = 0;
hdev->ssp_debug_mode = 0;
} }
static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
...@@ -310,11 +315,6 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -310,11 +315,6 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
set_bit(HCI_ISCAN, &hdev->flags); set_bit(HCI_ISCAN, &hdev->flags);
if (!old_iscan) if (!old_iscan)
mgmt_discoverable(hdev, 1); mgmt_discoverable(hdev, 1);
if (hdev->discov_timeout > 0) {
int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
queue_delayed_work(hdev->workqueue, &hdev->discov_off,
to);
}
} else if (old_iscan) } else if (old_iscan)
mgmt_discoverable(hdev, 0); mgmt_discoverable(hdev, 0);
...@@ -470,14 +470,13 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -470,14 +470,13 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
if (rp->status) if (rp->status)
return; return;
hdev->hci_ver = rp->hci_ver; if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
hdev->hci_rev = __le16_to_cpu(rp->hci_rev); hdev->hci_ver = rp->hci_ver;
hdev->lmp_ver = rp->lmp_ver; hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
hdev->manufacturer = __le16_to_cpu(rp->manufacturer); hdev->lmp_ver = rp->lmp_ver;
hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name, }
hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
} }
static void hci_cc_read_local_commands(struct hci_dev *hdev, static void hci_cc_read_local_commands(struct hci_dev *hdev,
...@@ -557,7 +556,8 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev, ...@@ -557,7 +556,8 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
if (rp->status) if (rp->status)
return; return;
hdev->max_page = rp->max_page; if (hdev->max_page < rp->max_page)
hdev->max_page = rp->max_page;
if (rp->page < HCI_MAX_PAGES) if (rp->page < HCI_MAX_PAGES)
memcpy(hdev->features[rp->page], rp->features, 8); memcpy(hdev->features[rp->page], rp->features, 8);
...@@ -939,14 +939,6 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -939,14 +939,6 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit(HCI_ADVERTISING, &hdev->dev_flags); clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
} }
if (*sent && !test_bit(HCI_INIT, &hdev->flags)) {
struct hci_request req;
hci_req_init(&req, hdev);
hci_update_ad(&req);
hci_req_run(&req, NULL);
}
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
} }
...@@ -1702,7 +1694,7 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -1702,7 +1694,7 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
&flags); &flags);
if ((mask & HCI_LM_ACCEPT) && if ((mask & HCI_LM_ACCEPT) &&
!hci_blacklist_lookup(hdev, &ev->bdaddr)) { !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
/* Connection accepted */ /* Connection accepted */
struct inquiry_entry *ie; struct inquiry_entry *ie;
struct hci_conn *conn; struct hci_conn *conn;
...@@ -2559,7 +2551,6 @@ static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2559,7 +2551,6 @@ static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
if (conn) { if (conn) {
conn->mode = ev->mode; conn->mode = ev->mode;
conn->interval = __le16_to_cpu(ev->interval);
if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
&conn->flags)) { &conn->flags)) {
...@@ -2941,6 +2932,23 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, ...@@ -2941,6 +2932,23 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
} }
static inline size_t eir_get_length(u8 *eir, size_t eir_len)
{
size_t parsed = 0;
while (parsed < eir_len) {
u8 field_len = eir[0];
if (field_len == 0)
return parsed;
parsed += field_len + 1;
eir += field_len + 1;
}
return eir_len;
}
static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
struct sk_buff *skb) struct sk_buff *skb)
{ {
...@@ -3181,7 +3189,8 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev, ...@@ -3181,7 +3189,8 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev,
if (hdev->auto_accept_delay > 0) { if (hdev->auto_accept_delay > 0) {
int delay = msecs_to_jiffies(hdev->auto_accept_delay); int delay = msecs_to_jiffies(hdev->auto_accept_delay);
mod_timer(&conn->auto_accept_timer, jiffies + delay); queue_delayed_work(conn->hdev->workqueue,
&conn->auto_accept_work, delay);
goto unlock; goto unlock;
} }
......
...@@ -481,7 +481,7 @@ static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg) ...@@ -481,7 +481,7 @@ static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg)
hci_dev_lock(hdev); hci_dev_lock(hdev);
err = hci_blacklist_add(hdev, &bdaddr, 0); err = hci_blacklist_add(hdev, &bdaddr, BDADDR_BREDR);
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
...@@ -498,7 +498,7 @@ static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg) ...@@ -498,7 +498,7 @@ static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
hci_dev_lock(hdev); hci_dev_lock(hdev);
err = hci_blacklist_del(hdev, &bdaddr, 0); err = hci_blacklist_del(hdev, &bdaddr, BDADDR_BREDR);
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
......
This diff is collapsed.
This diff is collapsed.
...@@ -72,6 +72,15 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) ...@@ -72,6 +72,15 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
if (!bdaddr_type_is_valid(la.l2_bdaddr_type)) if (!bdaddr_type_is_valid(la.l2_bdaddr_type))
return -EINVAL; return -EINVAL;
if (bdaddr_type_is_le(la.l2_bdaddr_type)) {
/* Connection oriented channels are not supported on LE */
if (la.l2_psm)
return -EINVAL;
/* We only allow ATT user space socket */
if (la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT))
return -EINVAL;
}
lock_sock(sk); lock_sock(sk);
if (sk->sk_state != BT_OPEN) { if (sk->sk_state != BT_OPEN) {
...@@ -150,12 +159,44 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, ...@@ -150,12 +159,44 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
if (!bdaddr_type_is_valid(la.l2_bdaddr_type)) if (!bdaddr_type_is_valid(la.l2_bdaddr_type))
return -EINVAL; return -EINVAL;
if (chan->src_type == BDADDR_BREDR && la.l2_bdaddr_type != BDADDR_BREDR) /* Check that the socket wasn't bound to something that
return -EINVAL; * conflicts with the address given to connect(). If chan->src
* is BDADDR_ANY it means bind() was never used, in which case
* chan->src_type and la.l2_bdaddr_type do not need to match.
*/
if (chan->src_type == BDADDR_BREDR && bacmp(&chan->src, BDADDR_ANY) &&
bdaddr_type_is_le(la.l2_bdaddr_type)) {
/* Old user space versions will try to incorrectly bind
* the ATT socket using BDADDR_BREDR. We need to accept
* this and fix up the source address type only when
* both the source CID and destination CID indicate
* ATT. Anything else is an invalid combination.
*/
if (chan->scid != L2CAP_CID_ATT ||
la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT))
return -EINVAL;
/* We don't have the hdev available here to make a
* better decision on random vs public, but since all
* user space versions that exhibit this issue anyway do
* not support random local addresses assuming public
* here is good enough.
*/
chan->src_type = BDADDR_LE_PUBLIC;
}
if (chan->src_type != BDADDR_BREDR && la.l2_bdaddr_type == BDADDR_BREDR) if (chan->src_type != BDADDR_BREDR && la.l2_bdaddr_type == BDADDR_BREDR)
return -EINVAL; return -EINVAL;
if (bdaddr_type_is_le(la.l2_bdaddr_type)) {
/* Connection oriented channels are not supported on LE */
if (la.l2_psm)
return -EINVAL;
/* We only allow ATT user space socket */
if (la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT))
return -EINVAL;
}
err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid), err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid),
&la.l2_bdaddr, la.l2_bdaddr_type); &la.l2_bdaddr, la.l2_bdaddr_type);
if (err) if (err)
...@@ -879,6 +920,38 @@ static void l2cap_sock_kill(struct sock *sk) ...@@ -879,6 +920,38 @@ static void l2cap_sock_kill(struct sock *sk)
sock_put(sk); sock_put(sk);
} }
static int __l2cap_wait_ack(struct sock *sk)
{
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
DECLARE_WAITQUEUE(wait, current);
int err = 0;
int timeo = HZ/5;
add_wait_queue(sk_sleep(sk), &wait);
set_current_state(TASK_INTERRUPTIBLE);
while (chan->unacked_frames > 0 && chan->conn) {
if (!timeo)
timeo = HZ/5;
if (signal_pending(current)) {
err = sock_intr_errno(timeo);
break;
}
release_sock(sk);
timeo = schedule_timeout(timeo);
lock_sock(sk);
set_current_state(TASK_INTERRUPTIBLE);
err = sock_error(sk);
if (err)
break;
}
set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait);
return err;
}
static int l2cap_sock_shutdown(struct socket *sock, int how) static int l2cap_sock_shutdown(struct socket *sock, int how)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
...@@ -969,6 +1042,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) ...@@ -969,6 +1042,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
{ {
struct sock *sk, *parent = chan->data; struct sock *sk, *parent = chan->data;
lock_sock(parent);
/* Check for backlog size */ /* Check for backlog size */
if (sk_acceptq_is_full(parent)) { if (sk_acceptq_is_full(parent)) {
BT_DBG("backlog full %d", parent->sk_ack_backlog); BT_DBG("backlog full %d", parent->sk_ack_backlog);
...@@ -986,6 +1061,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) ...@@ -986,6 +1061,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
bt_accept_enqueue(parent, sk); bt_accept_enqueue(parent, sk);
release_sock(parent);
return l2cap_pi(sk)->chan; return l2cap_pi(sk)->chan;
} }
...@@ -1072,26 +1149,33 @@ static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err) ...@@ -1072,26 +1149,33 @@ static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err)
release_sock(sk); release_sock(sk);
} }
static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state) static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,
int err)
{ {
struct sock *sk = chan->data; struct sock *sk = chan->data;
sk->sk_state = state; sk->sk_state = state;
if (err)
sk->sk_err = err;
} }
static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan, static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
unsigned long len, int nb) unsigned long len, int nb)
{ {
struct sock *sk = chan->data;
struct sk_buff *skb; struct sk_buff *skb;
int err; int err;
l2cap_chan_unlock(chan); l2cap_chan_unlock(chan);
skb = bt_skb_send_alloc(chan->sk, len, nb, &err); skb = bt_skb_send_alloc(sk, len, nb, &err);
l2cap_chan_lock(chan); l2cap_chan_lock(chan);
if (!skb) if (!skb)
return ERR_PTR(err); return ERR_PTR(err);
bt_cb(skb)->chan = chan;
return skb; return skb;
} }
...@@ -1117,11 +1201,15 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan) ...@@ -1117,11 +1201,15 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan)
static void l2cap_sock_defer_cb(struct l2cap_chan *chan) static void l2cap_sock_defer_cb(struct l2cap_chan *chan)
{ {
struct sock *sk = chan->data; struct sock *parent, *sk = chan->data;
struct sock *parent = bt_sk(sk)->parent;
lock_sock(sk);
parent = bt_sk(sk)->parent;
if (parent) if (parent)
parent->sk_data_ready(parent, 0); parent->sk_data_ready(parent, 0);
release_sock(sk);
} }
static void l2cap_sock_resume_cb(struct l2cap_chan *chan) static void l2cap_sock_resume_cb(struct l2cap_chan *chan)
...@@ -1132,6 +1220,22 @@ static void l2cap_sock_resume_cb(struct l2cap_chan *chan) ...@@ -1132,6 +1220,22 @@ static void l2cap_sock_resume_cb(struct l2cap_chan *chan)
sk->sk_state_change(sk); sk->sk_state_change(sk);
} }
static void l2cap_sock_set_shutdown_cb(struct l2cap_chan *chan)
{
struct sock *sk = chan->data;
lock_sock(sk);
sk->sk_shutdown = SHUTDOWN_MASK;
release_sock(sk);
}
static long l2cap_sock_get_sndtimeo_cb(struct l2cap_chan *chan)
{
struct sock *sk = chan->data;
return sk->sk_sndtimeo;
}
static struct l2cap_ops l2cap_chan_ops = { static struct l2cap_ops l2cap_chan_ops = {
.name = "L2CAP Socket Interface", .name = "L2CAP Socket Interface",
.new_connection = l2cap_sock_new_connection_cb, .new_connection = l2cap_sock_new_connection_cb,
...@@ -1142,6 +1246,8 @@ static struct l2cap_ops l2cap_chan_ops = { ...@@ -1142,6 +1246,8 @@ static struct l2cap_ops l2cap_chan_ops = {
.ready = l2cap_sock_ready_cb, .ready = l2cap_sock_ready_cb,
.defer = l2cap_sock_defer_cb, .defer = l2cap_sock_defer_cb,
.resume = l2cap_sock_resume_cb, .resume = l2cap_sock_resume_cb,
.set_shutdown = l2cap_sock_set_shutdown_cb,
.get_sndtimeo = l2cap_sock_get_sndtimeo_cb,
.alloc_skb = l2cap_sock_alloc_skb_cb, .alloc_skb = l2cap_sock_alloc_skb_cb,
}; };
...@@ -1268,8 +1374,6 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, ...@@ -1268,8 +1374,6 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
l2cap_chan_hold(chan); l2cap_chan_hold(chan);
chan->sk = sk;
l2cap_pi(sk)->chan = chan; l2cap_pi(sk)->chan = chan;
return sk; return sk;
......
This diff is collapsed.
...@@ -2154,13 +2154,6 @@ static int __init rfcomm_init(void) ...@@ -2154,13 +2154,6 @@ static int __init rfcomm_init(void)
goto unregister; goto unregister;
} }
if (bt_debugfs) {
rfcomm_dlc_debugfs = debugfs_create_file("rfcomm_dlc", 0444,
bt_debugfs, NULL, &rfcomm_dlc_debugfs_fops);
if (!rfcomm_dlc_debugfs)
BT_ERR("Failed to create RFCOMM debug file");
}
err = rfcomm_init_ttys(); err = rfcomm_init_ttys();
if (err < 0) if (err < 0)
goto stop; goto stop;
...@@ -2171,6 +2164,13 @@ static int __init rfcomm_init(void) ...@@ -2171,6 +2164,13 @@ static int __init rfcomm_init(void)
BT_INFO("RFCOMM ver %s", VERSION); BT_INFO("RFCOMM ver %s", VERSION);
if (IS_ERR_OR_NULL(bt_debugfs))
return 0;
rfcomm_dlc_debugfs = debugfs_create_file("rfcomm_dlc", 0444,
bt_debugfs, NULL,
&rfcomm_dlc_debugfs_fops);
return 0; return 0;
cleanup: cleanup:
......
...@@ -1051,15 +1051,15 @@ int __init rfcomm_init_sockets(void) ...@@ -1051,15 +1051,15 @@ int __init rfcomm_init_sockets(void)
goto error; goto error;
} }
if (bt_debugfs) {
rfcomm_sock_debugfs = debugfs_create_file("rfcomm", 0444,
bt_debugfs, NULL, &rfcomm_sock_debugfs_fops);
if (!rfcomm_sock_debugfs)
BT_ERR("Failed to create RFCOMM debug file");
}
BT_INFO("RFCOMM socket layer initialized"); BT_INFO("RFCOMM socket layer initialized");
if (IS_ERR_OR_NULL(bt_debugfs))
return 0;
rfcomm_sock_debugfs = debugfs_create_file("rfcomm", 0444,
bt_debugfs, NULL,
&rfcomm_sock_debugfs_fops);
return 0; return 0;
error: error:
......
...@@ -1177,15 +1177,14 @@ int __init sco_init(void) ...@@ -1177,15 +1177,14 @@ int __init sco_init(void)
goto error; goto error;
} }
if (bt_debugfs) {
sco_debugfs = debugfs_create_file("sco", 0444, bt_debugfs,
NULL, &sco_debugfs_fops);
if (!sco_debugfs)
BT_ERR("Failed to create SCO debug file");
}
BT_INFO("SCO socket layer initialized"); BT_INFO("SCO socket layer initialized");
if (IS_ERR_OR_NULL(bt_debugfs))
return 0;
sco_debugfs = debugfs_create_file("sco", 0444, bt_debugfs,
NULL, &sco_debugfs_fops);
return 0; return 0;
error: error:
......
...@@ -856,7 +856,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) ...@@ -856,7 +856,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
if (hcon->type != LE_LINK) { if (hcon->type != LE_LINK) {
kfree_skb(skb); kfree_skb(skb);
return -ENOTSUPP; return 0;
} }
if (skb->len < 1) { if (skb->len < 1) {
...@@ -864,7 +864,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) ...@@ -864,7 +864,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
return -EILSEQ; return -EILSEQ;
} }
if (!test_bit(HCI_LE_ENABLED, &conn->hcon->hdev->dev_flags)) { if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
err = -ENOTSUPP; err = -ENOTSUPP;
reason = SMP_PAIRING_NOTSUPP; reason = SMP_PAIRING_NOTSUPP;
goto done; goto done;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment