Commit dee04cac authored by John W. Linville's avatar John W. Linville
parents ce6cac88 7cbc9bd9
......@@ -246,6 +246,15 @@ enum {
#define HCI_AT_GENERAL_BONDING 0x04
#define HCI_AT_GENERAL_BONDING_MITM 0x05
/* Link Key types */
#define HCI_LK_COMBINATION 0x00
#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_CHANGED_COMBINATION 0x06
/* ----- HCI Commands ---- */
#define HCI_OP_NOP 0x0000
......
......@@ -126,6 +126,8 @@ struct hci_dev {
__u16 sniff_min_interval;
__u16 sniff_max_interval;
unsigned int auto_accept_delay;
unsigned long quirks;
atomic_t cmd_cnt;
......@@ -226,6 +228,7 @@ struct hci_conn {
__u16 pkt_type;
__u16 link_policy;
__u32 link_mode;
__u8 key_type;
__u8 auth_type;
__u8 sec_level;
__u8 pending_sec_level;
......@@ -245,6 +248,7 @@ struct hci_conn {
struct timer_list disc_timer;
struct timer_list idle_timer;
struct timer_list auto_accept_timer;
struct work_struct work_add;
struct work_struct work_del;
......@@ -511,8 +515,8 @@ int hci_uuids_clear(struct hci_dev *hdev);
int 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, int new_key, bdaddr_t *bdaddr,
u8 *key, u8 type, u8 pin_len);
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);
int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_remote_oob_data_clear(struct hci_dev *hdev);
......@@ -771,15 +775,16 @@ int mgmt_index_removed(u16 index);
int mgmt_powered(u16 index, u8 powered);
int mgmt_discoverable(u16 index, u8 discoverable);
int mgmt_connectable(u16 index, u8 connectable);
int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type);
int mgmt_new_key(u16 index, struct link_key *key, u8 persistent);
int mgmt_connected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnect_failed(u16 index);
int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr);
int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure);
int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value);
int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value,
u8 confirm_hint);
int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr,
u8 status);
......@@ -790,6 +795,7 @@ int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi,
u8 *eir);
int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name);
int mgmt_discovering(u16 index, u8 discovering);
/* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) sk)
......
......@@ -284,6 +284,25 @@ struct srej_list {
struct l2cap_chan {
struct sock *sk;
struct l2cap_conn *conn;
__le16 psm;
__u16 dcid;
__u16 scid;
__u16 imtu;
__u16 omtu;
__u16 flush_to;
__u8 mode;
__le16 sport;
__u8 sec_level;
__u8 role_switch;
__u8 force_reliable;
__u8 flushable;
__u8 ident;
__u8 conf_req[64];
......@@ -291,6 +310,15 @@ struct l2cap_chan {
__u8 num_conf_req;
__u8 num_conf_rsp;
__u8 fcs;
__u8 tx_win;
__u8 max_tx;
__u16 retrans_timeout;
__u16 monitor_timeout;
__u16 mps;
__u8 conf_state;
__u16 conn_state;
__u8 next_tx_seq;
......@@ -360,32 +388,6 @@ struct l2cap_conn {
struct l2cap_pinfo {
struct bt_sock bt;
__le16 psm;
__u16 dcid;
__u16 scid;
__u16 imtu;
__u16 omtu;
__u16 flush_to;
__u8 mode;
__u8 fcs;
__u8 sec_level;
__u8 role_switch;
__u8 force_reliable;
__u8 flushable;
__u8 conf_state;
__u8 tx_win;
__u8 max_tx;
__u16 retrans_timeout;
__u16 monitor_timeout;
__u16 mps;
__le16 sport;
struct l2cap_conn *conn;
struct l2cap_chan *chan;
};
......@@ -439,21 +441,20 @@ static inline int l2cap_tx_window_full(struct l2cap_chan *ch)
#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START)
extern int disable_ertm;
extern const struct proto_ops l2cap_sock_ops;
extern struct bt_sock_list l2cap_sk_list;
int l2cap_init_sockets(void);
void l2cap_cleanup_sockets(void);
void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data);
void __l2cap_connect_rsp_defer(struct sock *sk);
void __l2cap_connect_rsp_defer(struct l2cap_chan *chan);
int __l2cap_wait_ack(struct sock *sk);
struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len);
struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len);
struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen);
struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len, u16 control, u16 sdulen);
int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
void l2cap_do_send(struct sock *sk, struct sk_buff *skb);
void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb);
void l2cap_streaming_send(struct l2cap_chan *chan);
int l2cap_ertm_send(struct l2cap_chan *chan);
......@@ -465,7 +466,9 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent);
struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
int proto, gfp_t prio);
void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err);
struct l2cap_chan *l2cap_chan_alloc(struct sock *sk);
void l2cap_chan_del(struct l2cap_chan *chan, int err);
int l2cap_do_connect(struct sock *sk);
void l2cap_chan_free(struct l2cap_chan *chan);
int l2cap_chan_connect(struct l2cap_chan *chan);
#endif /* __L2CAP_H */
......@@ -195,6 +195,10 @@ struct mgmt_cp_remove_remote_oob_data {
bdaddr_t bdaddr;
} __packed;
#define MGMT_OP_START_DISCOVERY 0x001B
#define MGMT_OP_STOP_DISCOVERY 0x001C
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
......@@ -226,8 +230,8 @@ struct mgmt_ev_controller_error {
#define MGMT_EV_NEW_KEY 0x000A
struct mgmt_ev_new_key {
__u8 store_hint;
struct mgmt_key_info key;
__u8 old_key_type;
} __packed;
#define MGMT_EV_CONNECTED 0x000B
......@@ -249,11 +253,13 @@ struct mgmt_ev_connect_failed {
#define MGMT_EV_PIN_CODE_REQUEST 0x000E
struct mgmt_ev_pin_code_request {
bdaddr_t bdaddr;
__u8 secure;
} __packed;
#define MGMT_EV_USER_CONFIRM_REQUEST 0x000F
struct mgmt_ev_user_confirm_request {
bdaddr_t bdaddr;
__u8 confirm_hint;
__le32 value;
} __packed;
......@@ -281,3 +287,5 @@ struct mgmt_ev_remote_name {
bdaddr_t bdaddr;
__u8 name[MGMT_MAX_NAME_LENGTH];
} __packed;
#define MGMT_EV_DISCOVERING 0x0014
......@@ -346,7 +346,8 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
bacpy(&session->bdaddr, &bt_sk(sock->sk)->dst);
session->mtu = min_t(uint, l2cap_pi(sock->sk)->omtu, l2cap_pi(sock->sk)->imtu);
session->mtu = min_t(uint, l2cap_pi(sock->sk)->chan->omtu,
l2cap_pi(sock->sk)->chan->imtu);
BT_DBG("mtu %d", session->mtu);
......
......@@ -269,6 +269,19 @@ static void hci_conn_idle(unsigned long arg)
hci_conn_enter_sniff_mode(conn);
}
static void hci_conn_auto_accept(unsigned long arg)
{
struct hci_conn *conn = (void *) arg;
struct hci_dev *hdev = conn->hdev;
hci_dev_lock(hdev);
hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst),
&conn->dst);
hci_dev_unlock(hdev);
}
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
{
struct hci_conn *conn;
......@@ -287,6 +300,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
conn->auth_type = HCI_AT_GENERAL_BONDING;
conn->io_capability = hdev->io_capability;
conn->remote_auth = 0xff;
conn->key_type = 0xff;
conn->power_save = 1;
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
......@@ -311,6 +325,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn);
setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn);
setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept,
(unsigned long) conn);
atomic_set(&conn->refcnt, 0);
......@@ -341,6 +357,8 @@ int hci_conn_del(struct hci_conn *conn)
del_timer(&conn->disc_timer);
del_timer(&conn->auto_accept_timer);
if (conn->type == ACL_LINK) {
struct hci_conn *sco = conn->link;
if (sco)
......@@ -535,32 +553,72 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
return 0;
}
/* Encrypt the the link */
static void hci_conn_encrypt(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);
if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
struct hci_cp_set_conn_encrypt cp;
cp.handle = cpu_to_le16(conn->handle);
cp.encrypt = 0x01;
hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
&cp);
}
}
/* Enable security */
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
{
BT_DBG("conn %p", conn);
/* For sdp we don't need the link key. */
if (sec_level == BT_SECURITY_SDP)
return 1;
/* For non 2.1 devices and low security level we don't need the link
key. */
if (sec_level == BT_SECURITY_LOW &&
(!conn->ssp_mode || !conn->hdev->ssp_mode))
return 1;
if (conn->link_mode & HCI_LM_ENCRYPT)
return hci_conn_auth(conn, sec_level, auth_type);
/* For other security levels we need the link key. */
if (!(conn->link_mode & HCI_LM_AUTH))
goto auth;
/* An authenticated combination key has sufficient security for any
security level. */
if (conn->key_type == HCI_LK_AUTH_COMBINATION)
goto encrypt;
/* An unauthenticated combination key has sufficient security for
security level 1 and 2. */
if (conn->key_type == HCI_LK_UNAUTH_COMBINATION &&
(sec_level == BT_SECURITY_MEDIUM ||
sec_level == BT_SECURITY_LOW))
goto encrypt;
/* A combination key has always sufficient security for the security
levels 1 or 2. High security level requires the combination key
is generated using maximum PIN code length (16).
For pre 2.1 units. */
if (conn->key_type == HCI_LK_COMBINATION &&
(sec_level != BT_SECURITY_HIGH ||
conn->pin_length == 16))
goto encrypt;
auth:
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
return 0;
if (hci_conn_auth(conn, sec_level, auth_type)) {
struct hci_cp_set_conn_encrypt cp;
cp.handle = cpu_to_le16(conn->handle);
cp.encrypt = 1;
hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT,
sizeof(cp), &cp);
}
hci_conn_auth(conn, sec_level, auth_type);
return 0;
encrypt:
if (conn->link_mode & HCI_LM_ENCRYPT)
return 1;
hci_conn_encrypt(conn);
return 0;
}
EXPORT_SYMBOL(hci_conn_security);
......
......@@ -1020,18 +1020,54 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
return NULL;
}
int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
u8 *val, u8 type, u8 pin_len)
static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
u8 key_type, u8 old_key_type)
{
/* Legacy key */
if (key_type < 0x03)
return 1;
/* Debug keys are insecure so don't store them persistently */
if (key_type == HCI_LK_DEBUG_COMBINATION)
return 0;
/* Changed combination key and there's no previous one */
if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
return 0;
/* Security mode 3 case */
if (!conn)
return 1;
/* Neither local nor remote side had no-bonding as requirement */
if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
return 1;
/* Local side had dedicated bonding as requirement */
if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
return 1;
/* Remote side had dedicated bonding as requirement */
if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
return 1;
/* If none of the above criteria match, then don't store the key
* persistently */
return 0;
}
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 link_key *key, *old_key;
u8 old_key_type;
u8 old_key_type, persistent;
old_key = hci_find_link_key(hdev, bdaddr);
if (old_key) {
old_key_type = old_key->type;
key = old_key;
} else {
old_key_type = 0xff;
old_key_type = conn ? conn->key_type : 0xff;
key = kzalloc(sizeof(*key), GFP_ATOMIC);
if (!key)
return -ENOMEM;
......@@ -1040,16 +1076,37 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
/* Some buggy controller combinations generate a changed
* combination key for legacy pairing even when there's no
* previous key */
if (type == HCI_LK_CHANGED_COMBINATION &&
(!conn || conn->remote_auth == 0xff) &&
old_key_type == 0xff) {
type = HCI_LK_COMBINATION;
if (conn)
conn->key_type = type;
}
bacpy(&key->bdaddr, bdaddr);
memcpy(key->val, val, 16);
key->type = type;
key->pin_len = pin_len;
if (new_key)
mgmt_new_key(hdev->id, key, old_key_type);
if (type == 0x06)
if (type == HCI_LK_CHANGED_COMBINATION)
key->type = old_key_type;
else
key->type = type;
if (!new_key)
return 0;
persistent = hci_persistent_key(hdev, conn, type, old_key_type);
mgmt_new_key(hdev->id, key, persistent);
if (!persistent) {
list_del(&key->list);
kfree(key);
}
return 0;
}
......
......@@ -56,7 +56,9 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
if (status)
return;
clear_bit(HCI_INQUIRY, &hdev->flags);
if (test_bit(HCI_MGMT, &hdev->flags) &&
test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
mgmt_discovering(hdev->id, 0);
hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
......@@ -72,7 +74,9 @@ static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
if (status)
return;
clear_bit(HCI_INQUIRY, &hdev->flags);
if (test_bit(HCI_MGMT, &hdev->flags) &&
test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
mgmt_discovering(hdev->id, 0);
hci_conn_check_pending(hdev);
}
......@@ -841,10 +845,14 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
if (status) {
hci_req_complete(hdev, HCI_OP_INQUIRY, status);
hci_conn_check_pending(hdev);
} else
set_bit(HCI_INQUIRY, &hdev->flags);
return;
}
if (test_bit(HCI_MGMT, &hdev->flags) &&
!test_and_set_bit(HCI_INQUIRY,
&hdev->flags))
mgmt_discovering(hdev->id, 1);
}
static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
......@@ -1013,12 +1021,19 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
if (conn && hci_outgoing_auth_needed(hdev, conn)) {
if (!conn)
goto unlock;
if (!hci_outgoing_auth_needed(hdev, conn))
goto unlock;
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
struct hci_cp_auth_requested cp;
cp.handle = __cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
}
unlock:
hci_dev_unlock(hdev);
}
......@@ -1208,7 +1223,9 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff
BT_DBG("%s status %d", hdev->name, status);
clear_bit(HCI_INQUIRY, &hdev->flags);
if (test_bit(HCI_MGMT, &hdev->flags) &&
test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
mgmt_discovering(hdev->id, 0);
hci_req_complete(hdev, HCI_OP_INQUIRY, status);
......@@ -1228,6 +1245,12 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
hci_dev_lock(hdev);
if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) {
if (test_bit(HCI_MGMT, &hdev->flags))
mgmt_discovering(hdev->id, 1);
}
for (; num_rsp; num_rsp--, info++) {
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
......@@ -1443,7 +1466,6 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
conn->sec_level = conn->pending_sec_level;
} else {
mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
conn->sec_level = BT_SECURITY_LOW;
}
clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
......@@ -1501,12 +1523,19 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb
mgmt_remote_name(hdev->id, &ev->bdaddr, ev->name);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (conn && hci_outgoing_auth_needed(hdev, conn)) {
if (!conn)
goto unlock;
if (!hci_outgoing_auth_needed(hdev, conn))
goto unlock;
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
struct hci_cp_auth_requested cp;
cp.handle = __cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
}
unlock:
hci_dev_unlock(hdev);
}
......@@ -2006,9 +2035,16 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff
if (!test_bit(HCI_PAIRABLE, &hdev->flags))
hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
sizeof(ev->bdaddr), &ev->bdaddr);
else if (test_bit(HCI_MGMT, &hdev->flags)) {
u8 secure;
if (test_bit(HCI_MGMT, &hdev->flags))
mgmt_pin_code_request(hdev->id, &ev->bdaddr);
if (conn->pending_sec_level == BT_SECURITY_HIGH)
secure = 1;
else
secure = 0;
mgmt_pin_code_request(hdev->id, &ev->bdaddr, secure);
}
hci_dev_unlock(hdev);
}
......@@ -2037,19 +2073,32 @@ static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff
BT_DBG("%s found key type %u for %s", hdev->name, key->type,
batostr(&ev->bdaddr));
if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && key->type == 0x03) {
if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) &&
key->type == HCI_LK_DEBUG_COMBINATION) {
BT_DBG("%s ignoring debug key", hdev->name);
goto not_found;
}
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (key->type == 0x04 && conn && conn->auth_type != 0xff &&
if (conn) {
if (key->type == HCI_LK_UNAUTH_COMBINATION &&
conn->auth_type != 0xff &&
(conn->auth_type & 0x01)) {
BT_DBG("%s ignoring unauthenticated key", hdev->name);
goto not_found;
}
if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
conn->pending_sec_level == BT_SECURITY_HIGH) {
BT_DBG("%s ignoring key unauthenticated for high \
security", hdev->name);
goto not_found;
}
conn->key_type = key->type;
conn->pin_length = key->pin_len;
}
bacpy(&cp.bdaddr, &ev->bdaddr);
memcpy(cp.link_key, key->val, 16);
......@@ -2079,11 +2128,15 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff
hci_conn_hold(conn);
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
pin_len = conn->pin_length;
if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
conn->key_type = ev->key_type;
hci_conn_put(conn);
}
if (test_bit(HCI_LINK_KEYS, &hdev->flags))
hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key,
hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
ev->key_type, pin_len);
hci_dev_unlock(hdev);
......@@ -2158,6 +2211,12 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
hci_dev_lock(hdev);
if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) {
if (test_bit(HCI_MGMT, &hdev->flags))
mgmt_discovering(hdev->id, 1);
}
if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
struct inquiry_info_with_rssi_and_pscan_mode *info;
info = (void *) (skb->data + 1);
......@@ -2320,6 +2379,12 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
if (!num_rsp)
return;
if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) {
if (test_bit(HCI_MGMT, &hdev->flags))
mgmt_discovering(hdev->id, 1);
}
hci_dev_lock(hdev);
for (; num_rsp; num_rsp--, info++) {
......@@ -2353,7 +2418,7 @@ static inline u8 hci_get_auth_req(struct hci_conn *conn)
/* If remote requests no-bonding follow that lead */
if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
return 0x00;
return conn->remote_auth | (conn->auth_type & 0x01);
return conn->auth_type;
}
......@@ -2382,7 +2447,8 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
bacpy(&cp.bdaddr, &ev->bdaddr);
cp.capability = conn->io_capability;
cp.authentication = hci_get_auth_req(conn);
conn->auth_type = hci_get_auth_req(conn);
cp.authentication = conn->auth_type;
if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
hci_find_remote_oob_data(hdev, &conn->dst))
......@@ -2396,7 +2462,7 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
struct hci_cp_io_capability_neg_reply cp;
bacpy(&cp.bdaddr, &ev->bdaddr);
cp.reason = 0x16; /* Pairing not allowed */
cp.reason = 0x18; /* Pairing not allowed */
hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
sizeof(cp), &cp);
......@@ -2431,14 +2497,67 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_ev_user_confirm_req *ev = (void *) skb->data;
int loc_mitm, rem_mitm, confirm_hint = 0;
struct hci_conn *conn;
BT_DBG("%s", hdev->name);
hci_dev_lock(hdev);
if (test_bit(HCI_MGMT, &hdev->flags))
mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey);
if (!test_bit(HCI_MGMT, &hdev->flags))
goto unlock;
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (!conn)
goto unlock;
loc_mitm = (conn->auth_type & 0x01);
rem_mitm = (conn->remote_auth & 0x01);
/* If we require MITM but the remote device can't provide that
* (it has NoInputNoOutput) then reject the confirmation
* request. The only exception is when we're dedicated bonding
* initiators (connect_cfm_cb set) since then we always have the MITM
* bit set. */
if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
BT_DBG("Rejecting request: remote device can't provide MITM");
hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
sizeof(ev->bdaddr), &ev->bdaddr);
goto unlock;
}
/* If no side requires MITM protection; auto-accept */
if ((!loc_mitm || conn->remote_cap == 0x03) &&
(!rem_mitm || conn->io_capability == 0x03)) {
/* If we're not the initiators request authorization to
* proceed from user space (mgmt_user_confirm with
* confirm_hint set to 1). */
if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
BT_DBG("Confirming auto-accept as acceptor");
confirm_hint = 1;
goto confirm;
}
BT_DBG("Auto-accept of user confirmation with %ums delay",
hdev->auto_accept_delay);
if (hdev->auto_accept_delay > 0) {
int delay = msecs_to_jiffies(hdev->auto_accept_delay);
mod_timer(&conn->auto_accept_timer, jiffies + delay);
goto unlock;
}
hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
sizeof(ev->bdaddr), &ev->bdaddr);
goto unlock;
}
confirm:
mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey,
confirm_hint);
unlock:
hci_dev_unlock(hdev);
}
......
......@@ -511,6 +511,35 @@ static const struct file_operations uuids_fops = {
.release = single_release,
};
static int auto_accept_delay_set(void *data, u64 val)
{
struct hci_dev *hdev = data;
hci_dev_lock_bh(hdev);
hdev->auto_accept_delay = val;
hci_dev_unlock_bh(hdev);
return 0;
}
static int auto_accept_delay_get(void *data, u64 *val)
{
struct hci_dev *hdev = data;
hci_dev_lock_bh(hdev);
*val = hdev->auto_accept_delay;
hci_dev_unlock_bh(hdev);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
auto_accept_delay_set, "%llu\n");
int hci_register_sysfs(struct hci_dev *hdev)
{
struct device *dev = &hdev->dev;
......@@ -545,6 +574,8 @@ int hci_register_sysfs(struct hci_dev *hdev)
debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
debugfs_create_file("auto_accept_delay", 0444, hdev->debugfs, hdev,
&auto_accept_delay_fops);
return 0;
}
......
......@@ -979,8 +979,10 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst);
session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->omtu, l2cap_pi(ctrl_sock->sk)->imtu);
session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->omtu, l2cap_pi(intr_sock->sk)->imtu);
session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->chan->omtu,
l2cap_pi(ctrl_sock->sk)->chan->imtu);
session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->chan->omtu,
l2cap_pi(intr_sock->sk)->chan->imtu);
BT_DBG("ctrl mtu %d intr mtu %d", session->ctrl_mtu, session->intr_mtu);
......
......@@ -80,8 +80,7 @@ static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16
struct l2cap_chan *c;
list_for_each_entry(c, &conn->chan_l, list) {
struct sock *s = c->sk;
if (l2cap_pi(s)->dcid == cid)
if (c->dcid == cid)
return c;
}
return NULL;
......@@ -93,8 +92,7 @@ static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16
struct l2cap_chan *c;
list_for_each_entry(c, &conn->chan_l, list) {
struct sock *s = c->sk;
if (l2cap_pi(s)->scid == cid)
if (c->scid == cid)
return c;
}
return NULL;
......@@ -149,7 +147,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
return 0;
}
static struct l2cap_chan *l2cap_chan_alloc(struct sock *sk)
struct l2cap_chan *l2cap_chan_alloc(struct sock *sk)
{
struct l2cap_chan *chan;
......@@ -162,38 +160,43 @@ static struct l2cap_chan *l2cap_chan_alloc(struct sock *sk)
return chan;
}
void l2cap_chan_free(struct l2cap_chan *chan)
{
kfree(chan);
}
static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
{
struct sock *sk = chan->sk;
BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
chan->psm, chan->dcid);
conn->disc_reason = 0x13;
l2cap_pi(sk)->conn = conn;
chan->conn = conn;
if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
if (conn->hcon->type == LE_LINK) {
/* LE connection */
l2cap_pi(sk)->omtu = L2CAP_LE_DEFAULT_MTU;
l2cap_pi(sk)->scid = L2CAP_CID_LE_DATA;
l2cap_pi(sk)->dcid = L2CAP_CID_LE_DATA;
chan->omtu = L2CAP_LE_DEFAULT_MTU;
chan->scid = L2CAP_CID_LE_DATA;
chan->dcid = L2CAP_CID_LE_DATA;
} else {
/* Alloc CID for connection-oriented socket */
l2cap_pi(sk)->scid = l2cap_alloc_cid(conn);
l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
chan->scid = l2cap_alloc_cid(conn);
chan->omtu = L2CAP_DEFAULT_MTU;
}
} else if (sk->sk_type == SOCK_DGRAM) {
/* Connectionless socket */
l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
chan->scid = L2CAP_CID_CONN_LESS;
chan->dcid = L2CAP_CID_CONN_LESS;
chan->omtu = L2CAP_DEFAULT_MTU;
} else {
/* Raw socket can send/recv signalling messages only */
l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
chan->scid = L2CAP_CID_SIGNALING;
chan->dcid = L2CAP_CID_SIGNALING;
chan->omtu = L2CAP_DEFAULT_MTU;
}
sock_hold(sk);
......@@ -206,7 +209,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
void l2cap_chan_del(struct l2cap_chan *chan, int err)
{
struct sock *sk = chan->sk;
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
struct l2cap_conn *conn = chan->conn;
struct sock *parent = bt_sk(sk)->parent;
l2cap_sock_clear_timer(sk);
......@@ -220,7 +223,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
write_unlock_bh(&conn->chan_lock);
__sock_put(sk);
l2cap_pi(sk)->conn = NULL;
chan->conn = NULL;
hci_conn_put(conn->hcon);
}
......@@ -236,13 +239,13 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
} else
sk->sk_state_change(sk);
if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE &&
l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE))
goto free;
if (!(chan->conf_state & L2CAP_CONF_OUTPUT_DONE &&
chan->conf_state & L2CAP_CONF_INPUT_DONE))
return;
skb_queue_purge(&chan->tx_q);
if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
if (chan->mode == L2CAP_MODE_ERTM) {
struct srej_list *l, *tmp;
del_timer(&chan->retrans_timer);
......@@ -257,15 +260,14 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
kfree(l);
}
}
free:
kfree(chan);
}
static inline u8 l2cap_get_auth_type(struct sock *sk)
static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
{
struct sock *sk = chan->sk;
if (sk->sk_type == SOCK_RAW) {
switch (l2cap_pi(sk)->sec_level) {
switch (chan->sec_level) {
case BT_SECURITY_HIGH:
return HCI_AT_DEDICATED_BONDING_MITM;
case BT_SECURITY_MEDIUM:
......@@ -273,16 +275,16 @@ static inline u8 l2cap_get_auth_type(struct sock *sk)
default:
return HCI_AT_NO_BONDING;
}
} else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
} else if (chan->psm == cpu_to_le16(0x0001)) {
if (chan->sec_level == BT_SECURITY_LOW)
chan->sec_level = BT_SECURITY_SDP;
if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
if (chan->sec_level == BT_SECURITY_HIGH)
return HCI_AT_NO_BONDING_MITM;
else
return HCI_AT_NO_BONDING;
} else {
switch (l2cap_pi(sk)->sec_level) {
switch (chan->sec_level) {
case BT_SECURITY_HIGH:
return HCI_AT_GENERAL_BONDING_MITM;
case BT_SECURITY_MEDIUM:
......@@ -294,15 +296,14 @@ static inline u8 l2cap_get_auth_type(struct sock *sk)
}
/* Service level security */
static inline int l2cap_check_security(struct sock *sk)
static inline int l2cap_check_security(struct l2cap_chan *chan)
{
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
struct l2cap_conn *conn = chan->conn;
__u8 auth_type;
auth_type = l2cap_get_auth_type(sk);
auth_type = l2cap_get_auth_type(chan);
return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
auth_type);
return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
}
u8 l2cap_get_ident(struct l2cap_conn *conn)
......@@ -350,7 +351,7 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control)
struct sk_buff *skb;
struct l2cap_hdr *lh;
struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
struct l2cap_conn *conn = pi->conn;
struct l2cap_conn *conn = chan->conn;
struct sock *sk = (struct sock *)pi;
int count, hlen = L2CAP_HDR_SIZE + 2;
u8 flags;
......@@ -358,7 +359,7 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control)
if (sk->sk_state != BT_CONNECTED)
return;
if (pi->fcs == L2CAP_FCS_CRC16)
if (chan->fcs == L2CAP_FCS_CRC16)
hlen += 2;
BT_DBG("chan %p, control 0x%2.2x", chan, control);
......@@ -382,10 +383,10 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control)
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
lh->cid = cpu_to_le16(pi->dcid);
lh->cid = cpu_to_le16(chan->dcid);
put_unaligned_le16(control, skb_put(skb, 2));
if (pi->fcs == L2CAP_FCS_CRC16) {
if (chan->fcs == L2CAP_FCS_CRC16) {
u16 fcs = crc16(0, (u8 *)lh, count - 2);
put_unaligned_le16(fcs, skb_put(skb, 2));
}
......@@ -395,7 +396,7 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control)
else
flags = ACL_START;
hci_send_acl(pi->conn->hcon, skb, flags);
hci_send_acl(chan->conn->hcon, skb, flags);
}
static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control)
......@@ -411,27 +412,27 @@ static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control)
l2cap_send_sframe(chan, control);
}
static inline int __l2cap_no_conn_pending(struct sock *sk)
static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
{
return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
return !(chan->conf_state & L2CAP_CONF_CONNECT_PEND);
}
static void l2cap_do_start(struct l2cap_chan *chan)
{
struct sock *sk = chan->sk;
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
struct l2cap_conn *conn = chan->conn;
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
return;
if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
if (l2cap_check_security(chan) &&
__l2cap_no_conn_pending(chan)) {
struct l2cap_conn_req req;
req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
req.psm = l2cap_pi(sk)->psm;
req.scid = cpu_to_le16(chan->scid);
req.psm = chan->psm;
chan->ident = l2cap_get_ident(conn);
l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
chan->conf_state |= L2CAP_CONF_CONNECT_PEND;
l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ,
sizeof(req), &req);
......@@ -477,14 +478,14 @@ void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, in
sk = chan->sk;
if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
if (chan->mode == L2CAP_MODE_ERTM) {
del_timer(&chan->retrans_timer);
del_timer(&chan->monitor_timer);
del_timer(&chan->ack_timer);
}
req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
req.dcid = cpu_to_le16(chan->dcid);
req.scid = cpu_to_le16(chan->scid);
l2cap_send_cmd(conn, l2cap_get_ident(conn),
L2CAP_DISCONN_REQ, sizeof(req), &req);
......@@ -515,15 +516,15 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
if (sk->sk_state == BT_CONNECT) {
struct l2cap_conn_req req;
if (!l2cap_check_security(sk) ||
!__l2cap_no_conn_pending(sk)) {
if (!l2cap_check_security(chan) ||
!__l2cap_no_conn_pending(chan)) {
bh_unlock_sock(sk);
continue;
}
if (!l2cap_mode_supported(l2cap_pi(sk)->mode,
if (!l2cap_mode_supported(chan->mode,
conn->feat_mask)
&& l2cap_pi(sk)->conf_state &
&& chan->conf_state &
L2CAP_CONF_STATE2_DEVICE) {
/* __l2cap_sock_close() calls list_del(chan)
* so release the lock */
......@@ -534,11 +535,11 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
continue;
}
req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
req.psm = l2cap_pi(sk)->psm;
req.scid = cpu_to_le16(chan->scid);
req.psm = chan->psm;
chan->ident = l2cap_get_ident(conn);
l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
chan->conf_state |= L2CAP_CONF_CONNECT_PEND;
l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ,
sizeof(req), &req);
......@@ -546,10 +547,10 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
} else if (sk->sk_state == BT_CONNECT2) {
struct l2cap_conn_rsp rsp;
char buf[128];
rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
rsp.scid = cpu_to_le16(chan->dcid);
rsp.dcid = cpu_to_le16(chan->scid);
if (l2cap_check_security(sk)) {
if (l2cap_check_security(chan)) {
if (bt_sk(sk)->defer_setup) {
struct sock *parent = bt_sk(sk)->parent;
rsp.result = cpu_to_le16(L2CAP_CR_PEND);
......@@ -569,13 +570,13 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
sizeof(rsp), &rsp);
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT ||
if (chan->conf_state & L2CAP_CONF_REQ_SENT ||
rsp.result != L2CAP_CR_SUCCESS) {
bh_unlock_sock(sk);
continue;
}
l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
chan->conf_state |= L2CAP_CONF_REQ_SENT;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
l2cap_build_conf_req(chan, buf), buf);
chan->num_conf_req++;
......@@ -598,10 +599,12 @@ static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src)
read_lock(&l2cap_sk_list.lock);
sk_for_each(sk, node, &l2cap_sk_list.head) {
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
if (state && sk->sk_state != state)
continue;
if (l2cap_pi(sk)->scid == cid) {
if (chan->scid == cid) {
/* Exact match. */
if (!bacmp(&bt_sk(sk)->src, src))
break;
......@@ -648,6 +651,8 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
goto clean;
}
l2cap_pi(sk)->chan = chan;
write_lock_bh(&conn->chan_lock);
hci_conn_hold(conn->hcon);
......@@ -661,8 +666,6 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
__l2cap_chan_add(conn, chan);
l2cap_pi(sk)->chan = chan;
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
sk->sk_state = BT_CONNECTED;
......@@ -722,7 +725,7 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
list_for_each_entry(chan, &conn->chan_l, list) {
struct sock *sk = chan->sk;
if (l2cap_pi(sk)->force_reliable)
if (chan->force_reliable)
sk->sk_err = err;
}
......@@ -828,10 +831,12 @@ static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
read_lock(&l2cap_sk_list.lock);
sk_for_each(sk, node, &l2cap_sk_list.head) {
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
if (state && sk->sk_state != state)
continue;
if (l2cap_pi(sk)->psm == psm) {
if (chan->psm == psm) {
/* Exact match. */
if (!bacmp(&bt_sk(sk)->src, src))
break;
......@@ -847,19 +852,19 @@ static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
return node ? sk : sk1;
}
int l2cap_do_connect(struct sock *sk)
int l2cap_chan_connect(struct l2cap_chan *chan)
{
struct sock *sk = chan->sk;
bdaddr_t *src = &bt_sk(sk)->src;
bdaddr_t *dst = &bt_sk(sk)->dst;
struct l2cap_conn *conn;
struct l2cap_chan *chan;
struct hci_conn *hcon;
struct hci_dev *hdev;
__u8 auth_type;
int err;
BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
l2cap_pi(sk)->psm);
chan->psm);
hdev = hci_get_route(dst, src);
if (!hdev)
......@@ -867,14 +872,14 @@ int l2cap_do_connect(struct sock *sk)
hci_dev_lock_bh(hdev);
auth_type = l2cap_get_auth_type(sk);
auth_type = l2cap_get_auth_type(chan);
if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA)
if (chan->dcid == L2CAP_CID_LE_DATA)
hcon = hci_connect(hdev, LE_LINK, dst,
l2cap_pi(sk)->sec_level, auth_type);
chan->sec_level, auth_type);
else
hcon = hci_connect(hdev, ACL_LINK, dst,
l2cap_pi(sk)->sec_level, auth_type);
chan->sec_level, auth_type);
if (IS_ERR(hcon)) {
err = PTR_ERR(hcon);
......@@ -888,20 +893,11 @@ int l2cap_do_connect(struct sock *sk)
goto done;
}
chan = l2cap_chan_alloc(sk);
if (!chan) {
hci_conn_put(hcon);
err = -ENOMEM;
goto done;
}
/* Update source addr of the socket */
bacpy(src, conn->src);
l2cap_chan_add(conn, chan);
l2cap_pi(sk)->chan = chan;
sk->sk_state = BT_CONNECT;
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
......@@ -909,7 +905,7 @@ int l2cap_do_connect(struct sock *sk)
if (sk->sk_type != SOCK_SEQPACKET &&
sk->sk_type != SOCK_STREAM) {
l2cap_sock_clear_timer(sk);
if (l2cap_check_security(sk))
if (l2cap_check_security(chan))
sk->sk_state = BT_CONNECTED;
} else
l2cap_do_start(chan);
......@@ -925,12 +921,13 @@ int l2cap_do_connect(struct sock *sk)
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);
while ((l2cap_pi(sk)->chan->unacked_frames > 0 && l2cap_pi(sk)->conn)) {
while ((chan->unacked_frames > 0 && chan->conn)) {
set_current_state(TASK_INTERRUPTIBLE);
if (!timeo)
......@@ -963,7 +960,7 @@ static void l2cap_monitor_timeout(unsigned long arg)
bh_lock_sock(sk);
if (chan->retry_count >= chan->remote_max_tx) {
l2cap_send_disconn_req(l2cap_pi(sk)->conn, chan, ECONNABORTED);
l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
bh_unlock_sock(sk);
return;
}
......@@ -1011,15 +1008,14 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
del_timer(&chan->retrans_timer);
}
void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
{
struct l2cap_pinfo *pi = l2cap_pi(sk);
struct hci_conn *hcon = pi->conn->hcon;
struct hci_conn *hcon = chan->conn->hcon;
u16 flags;
BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
BT_DBG("chan %p, skb %p len %d", chan, skb, skb->len);
if (!pi->flushable && lmp_no_flush_capable(hcon->hdev))
if (!chan->flushable && lmp_no_flush_capable(hcon->hdev))
flags = ACL_START_NO_FLUSH;
else
flags = ACL_START;
......@@ -1029,9 +1025,7 @@ void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
void l2cap_streaming_send(struct l2cap_chan *chan)
{
struct sock *sk = chan->sk;
struct sk_buff *skb;
struct l2cap_pinfo *pi = l2cap_pi(sk);
u16 control, fcs;
while ((skb = skb_dequeue(&chan->tx_q))) {
......@@ -1039,12 +1033,12 @@ void l2cap_streaming_send(struct l2cap_chan *chan)
control |= chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
if (pi->fcs == L2CAP_FCS_CRC16) {
if (chan->fcs == L2CAP_FCS_CRC16) {
fcs = crc16(0, (u8 *)skb->data, skb->len - 2);
put_unaligned_le16(fcs, skb->data + skb->len - 2);
}
l2cap_do_send(sk, skb);
l2cap_do_send(chan, skb);
chan->next_tx_seq = (chan->next_tx_seq + 1) % 64;
}
......@@ -1052,8 +1046,6 @@ void l2cap_streaming_send(struct l2cap_chan *chan)
static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq)
{
struct sock *sk = chan->sk;
struct l2cap_pinfo *pi = l2cap_pi(sk);
struct sk_buff *skb, *tx_skb;
u16 control, fcs;
......@@ -1072,7 +1064,7 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq)
if (chan->remote_max_tx &&
bt_cb(skb)->retries == chan->remote_max_tx) {
l2cap_send_disconn_req(pi->conn, chan, ECONNABORTED);
l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
return;
}
......@@ -1091,19 +1083,18 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq)
put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
if (pi->fcs == L2CAP_FCS_CRC16) {
if (chan->fcs == L2CAP_FCS_CRC16) {
fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
}
l2cap_do_send(sk, tx_skb);
l2cap_do_send(chan, tx_skb);
}
int l2cap_ertm_send(struct l2cap_chan *chan)
{
struct sk_buff *skb, *tx_skb;
struct sock *sk = chan->sk;
struct l2cap_pinfo *pi = l2cap_pi(sk);
u16 control, fcs;
int nsent = 0;
......@@ -1114,7 +1105,7 @@ int l2cap_ertm_send(struct l2cap_chan *chan)
if (chan->remote_max_tx &&
bt_cb(skb)->retries == chan->remote_max_tx) {
l2cap_send_disconn_req(pi->conn, chan, ECONNABORTED);
l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
break;
}
......@@ -1134,12 +1125,12 @@ int l2cap_ertm_send(struct l2cap_chan *chan)
put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
if (pi->fcs == L2CAP_FCS_CRC16) {
if (chan->fcs == L2CAP_FCS_CRC16) {
fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
}
l2cap_do_send(sk, tx_skb);
l2cap_do_send(chan, tx_skb);
__mod_retrans_timer();
......@@ -1210,7 +1201,7 @@ static void l2cap_send_srejtail(struct l2cap_chan *chan)
static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb)
{
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
struct sk_buff **frag;
int err, sent = 0;
......@@ -1240,9 +1231,10 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in
return sent;
}
struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
{
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
struct sock *sk = chan->sk;
struct l2cap_conn *conn = chan->conn;
struct sk_buff *skb;
int err, count, hlen = L2CAP_HDR_SIZE + 2;
struct l2cap_hdr *lh;
......@@ -1257,9 +1249,9 @@ struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, s
/* Create L2CAP header */
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
lh->cid = cpu_to_le16(chan->dcid);
lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
put_unaligned_le16(chan->psm, skb_put(skb, 2));
err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
if (unlikely(err < 0)) {
......@@ -1269,9 +1261,10 @@ struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, s
return skb;
}
struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
{
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
struct sock *sk = chan->sk;
struct l2cap_conn *conn = chan->conn;
struct sk_buff *skb;
int err, count, hlen = L2CAP_HDR_SIZE;
struct l2cap_hdr *lh;
......@@ -1286,7 +1279,7 @@ struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size
/* Create L2CAP header */
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
lh->cid = cpu_to_le16(chan->dcid);
lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
......@@ -1297,9 +1290,10 @@ struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size
return skb;
}
struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
{
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
struct sock *sk = chan->sk;
struct l2cap_conn *conn = chan->conn;
struct sk_buff *skb;
int err, count, hlen = L2CAP_HDR_SIZE + 2;
struct l2cap_hdr *lh;
......@@ -1312,7 +1306,7 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz
if (sdulen)
hlen += 2;
if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
if (chan->fcs == L2CAP_FCS_CRC16)
hlen += 2;
count = min_t(unsigned int, (conn->mtu - hlen), len);
......@@ -1323,7 +1317,7 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz
/* Create L2CAP header */
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
lh->cid = cpu_to_le16(chan->dcid);
lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
put_unaligned_le16(control, skb_put(skb, 2));
if (sdulen)
......@@ -1335,7 +1329,7 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz
return ERR_PTR(err);
}
if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
if (chan->fcs == L2CAP_FCS_CRC16)
put_unaligned_le16(0, skb_put(skb, 2));
bt_cb(skb)->retries = 0;
......@@ -1344,7 +1338,6 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz
int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
{
struct sock *sk = chan->sk;
struct sk_buff *skb;
struct sk_buff_head sar_queue;
u16 control;
......@@ -1352,7 +1345,7 @@ int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t le
skb_queue_head_init(&sar_queue);
control = L2CAP_SDU_START;
skb = l2cap_create_iframe_pdu(sk, msg, chan->remote_mps, control, len);
skb = l2cap_create_iframe_pdu(chan, msg, chan->remote_mps, control, len);
if (IS_ERR(skb))
return PTR_ERR(skb);
......@@ -1371,7 +1364,7 @@ int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t le
buflen = len;
}
skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
skb = l2cap_create_iframe_pdu(chan, msg, buflen, control, 0);
if (IS_ERR(skb)) {
skb_queue_purge(&sar_queue);
return PTR_ERR(skb);
......@@ -1391,10 +1384,11 @@ int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t le
static void l2cap_chan_ready(struct sock *sk)
{
struct sock *parent = bt_sk(sk)->parent;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
BT_DBG("sk %p, parent %p", sk, parent);
l2cap_pi(sk)->conf_state = 0;
chan->conf_state = 0;
l2cap_sock_clear_timer(sk);
if (!parent) {
......@@ -1615,9 +1609,8 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
{
struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
struct l2cap_conf_req *req = data;
struct l2cap_conf_rfc rfc = { .mode = pi->mode };
struct l2cap_conf_rfc rfc = { .mode = chan->mode };
void *ptr = req->data;
BT_DBG("chan %p", chan);
......@@ -1625,26 +1618,26 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
if (chan->num_conf_req || chan->num_conf_rsp)
goto done;
switch (pi->mode) {
switch (chan->mode) {
case L2CAP_MODE_STREAMING:
case L2CAP_MODE_ERTM:
if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE)
if (chan->conf_state & L2CAP_CONF_STATE2_DEVICE)
break;
/* fall through */
default:
pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
break;
}
done:
if (pi->imtu != L2CAP_DEFAULT_MTU)
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
if (chan->imtu != L2CAP_DEFAULT_MTU)
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
switch (pi->mode) {
switch (chan->mode) {
case L2CAP_MODE_BASIC:
if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) &&
!(pi->conn->feat_mask & L2CAP_FEAT_STREAMING))
if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
!(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
break;
rfc.mode = L2CAP_MODE_BASIC;
......@@ -1660,24 +1653,24 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
case L2CAP_MODE_ERTM:
rfc.mode = L2CAP_MODE_ERTM;
rfc.txwin_size = pi->tx_win;
rfc.max_transmit = pi->max_tx;
rfc.txwin_size = chan->tx_win;
rfc.max_transmit = chan->max_tx;
rfc.retrans_timeout = 0;
rfc.monitor_timeout = 0;
rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
if (L2CAP_DEFAULT_MAX_PDU_SIZE > chan->conn->mtu - 10)
rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
(unsigned long) &rfc);
if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
break;
if (pi->fcs == L2CAP_FCS_NONE ||
pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
pi->fcs = L2CAP_FCS_NONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
if (chan->fcs == L2CAP_FCS_NONE ||
chan->conf_state & L2CAP_CONF_NO_FCS_RECV) {
chan->fcs = L2CAP_FCS_NONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
}
break;
......@@ -1688,24 +1681,24 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
rfc.retrans_timeout = 0;
rfc.monitor_timeout = 0;
rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
if (L2CAP_DEFAULT_MAX_PDU_SIZE > chan->conn->mtu - 10)
rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
(unsigned long) &rfc);
if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
break;
if (pi->fcs == L2CAP_FCS_NONE ||
pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
pi->fcs = L2CAP_FCS_NONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
if (chan->fcs == L2CAP_FCS_NONE ||
chan->conf_state & L2CAP_CONF_NO_FCS_RECV) {
chan->fcs = L2CAP_FCS_NONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
}
break;
}
req->dcid = cpu_to_le16(pi->dcid);
req->dcid = cpu_to_le16(chan->dcid);
req->flags = cpu_to_le16(0);
return ptr - data;
......@@ -1713,7 +1706,6 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
{
struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
struct l2cap_conf_rsp *rsp = data;
void *ptr = rsp->data;
void *req = chan->conf_req;
......@@ -1738,7 +1730,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
break;
case L2CAP_CONF_FLUSH_TO:
pi->flush_to = val;
chan->flush_to = val;
break;
case L2CAP_CONF_QOS:
......@@ -1751,7 +1743,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
case L2CAP_CONF_FCS:
if (val == L2CAP_FCS_NONE)
pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
chan->conf_state |= L2CAP_CONF_NO_FCS_RECV;
break;
......@@ -1768,25 +1760,25 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
if (chan->num_conf_rsp || chan->num_conf_req > 1)
goto done;
switch (pi->mode) {
switch (chan->mode) {
case L2CAP_MODE_STREAMING:
case L2CAP_MODE_ERTM:
if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
pi->mode = l2cap_select_mode(rfc.mode,
pi->conn->feat_mask);
if (!(chan->conf_state & L2CAP_CONF_STATE2_DEVICE)) {
chan->mode = l2cap_select_mode(rfc.mode,
chan->conn->feat_mask);
break;
}
if (pi->mode != rfc.mode)
if (chan->mode != rfc.mode)
return -ECONNREFUSED;
break;
}
done:
if (pi->mode != rfc.mode) {
if (chan->mode != rfc.mode) {
result = L2CAP_CONF_UNACCEPT;
rfc.mode = pi->mode;
rfc.mode = chan->mode;
if (chan->num_conf_rsp == 1)
return -ECONNREFUSED;
......@@ -1803,23 +1795,23 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
if (mtu < L2CAP_DEFAULT_MIN_MTU)
result = L2CAP_CONF_UNACCEPT;
else {
pi->omtu = mtu;
pi->conf_state |= L2CAP_CONF_MTU_DONE;
chan->omtu = mtu;
chan->conf_state |= L2CAP_CONF_MTU_DONE;
}
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
switch (rfc.mode) {
case L2CAP_MODE_BASIC:
pi->fcs = L2CAP_FCS_NONE;
pi->conf_state |= L2CAP_CONF_MODE_DONE;
chan->fcs = L2CAP_FCS_NONE;
chan->conf_state |= L2CAP_CONF_MODE_DONE;
break;
case L2CAP_MODE_ERTM:
chan->remote_tx_win = rfc.txwin_size;
chan->remote_max_tx = rfc.max_transmit;
if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
if (le16_to_cpu(rfc.max_pdu_size) > chan->conn->mtu - 10)
rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10);
chan->remote_mps = le16_to_cpu(rfc.max_pdu_size);
......@@ -1828,7 +1820,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
rfc.monitor_timeout =
le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
pi->conf_state |= L2CAP_CONF_MODE_DONE;
chan->conf_state |= L2CAP_CONF_MODE_DONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
......@@ -1836,12 +1828,12 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
break;
case L2CAP_MODE_STREAMING:
if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
if (le16_to_cpu(rfc.max_pdu_size) > chan->conn->mtu - 10)
rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10);
chan->remote_mps = le16_to_cpu(rfc.max_pdu_size);
pi->conf_state |= L2CAP_CONF_MODE_DONE;
chan->conf_state |= L2CAP_CONF_MODE_DONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
......@@ -1852,29 +1844,28 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
result = L2CAP_CONF_UNACCEPT;
memset(&rfc, 0, sizeof(rfc));
rfc.mode = pi->mode;
rfc.mode = chan->mode;
}
if (result == L2CAP_CONF_SUCCESS)
pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
chan->conf_state |= L2CAP_CONF_OUTPUT_DONE;
}
rsp->scid = cpu_to_le16(pi->dcid);
rsp->scid = cpu_to_le16(chan->dcid);
rsp->result = cpu_to_le16(result);
rsp->flags = cpu_to_le16(0x0000);
return ptr - data;
}
static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, void *data, u16 *result)
{
struct l2cap_pinfo *pi = l2cap_pi(sk);
struct l2cap_conf_req *req = data;
void *ptr = req->data;
int type, olen;
unsigned long val;
struct l2cap_conf_rfc rfc;
BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
while (len >= L2CAP_CONF_OPT_SIZE) {
len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
......@@ -1883,27 +1874,27 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
case L2CAP_CONF_MTU:
if (val < L2CAP_DEFAULT_MIN_MTU) {
*result = L2CAP_CONF_UNACCEPT;
pi->imtu = L2CAP_DEFAULT_MIN_MTU;
chan->imtu = L2CAP_DEFAULT_MIN_MTU;
} else
pi->imtu = val;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
chan->imtu = val;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
break;
case L2CAP_CONF_FLUSH_TO:
pi->flush_to = val;
chan->flush_to = val;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
2, pi->flush_to);
2, chan->flush_to);
break;
case L2CAP_CONF_RFC:
if (olen == sizeof(rfc))
memcpy(&rfc, (void *)val, olen);
if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
rfc.mode != pi->mode)
if ((chan->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
rfc.mode != chan->mode)
return -ECONNREFUSED;
pi->fcs = 0;
chan->fcs = 0;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
......@@ -1911,78 +1902,74 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
}
}
if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode)
if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
return -ECONNREFUSED;
pi->mode = rfc.mode;
chan->mode = rfc.mode;
if (*result == L2CAP_CONF_SUCCESS) {
switch (rfc.mode) {
case L2CAP_MODE_ERTM:
pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
pi->mps = le16_to_cpu(rfc.max_pdu_size);
chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
chan->mps = le16_to_cpu(rfc.max_pdu_size);
break;
case L2CAP_MODE_STREAMING:
pi->mps = le16_to_cpu(rfc.max_pdu_size);
chan->mps = le16_to_cpu(rfc.max_pdu_size);
}
}
req->dcid = cpu_to_le16(pi->dcid);
req->dcid = cpu_to_le16(chan->dcid);
req->flags = cpu_to_le16(0x0000);
return ptr - data;
}
static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, u16 result, u16 flags)
{
struct l2cap_conf_rsp *rsp = data;
void *ptr = rsp->data;
BT_DBG("sk %p", sk);
BT_DBG("chan %p", chan);
rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
rsp->scid = cpu_to_le16(chan->dcid);
rsp->result = cpu_to_le16(result);
rsp->flags = cpu_to_le16(flags);
return ptr - data;
}
void __l2cap_connect_rsp_defer(struct sock *sk)
void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
{
struct l2cap_conn_rsp rsp;
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct l2cap_conn *conn = chan->conn;
u8 buf[128];
sk->sk_state = BT_CONFIG;
rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
rsp.scid = cpu_to_le16(chan->dcid);
rsp.dcid = cpu_to_le16(chan->scid);
rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
l2cap_send_cmd(conn, chan->ident,
L2CAP_CONN_RSP, sizeof(rsp), &rsp);
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)
if (chan->conf_state & L2CAP_CONF_REQ_SENT)
return;
l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
chan->conf_state |= L2CAP_CONF_REQ_SENT;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
l2cap_build_conf_req(chan, buf), buf);
chan->num_conf_req++;
}
static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
{
struct l2cap_pinfo *pi = l2cap_pi(sk);
int type, olen;
unsigned long val;
struct l2cap_conf_rfc rfc;
BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
return;
while (len >= L2CAP_CONF_OPT_SIZE) {
......@@ -1999,12 +1986,12 @@ static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
done:
switch (rfc.mode) {
case L2CAP_MODE_ERTM:
pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
pi->mps = le16_to_cpu(rfc.max_pdu_size);
chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
chan->mps = le16_to_cpu(rfc.max_pdu_size);
break;
case L2CAP_MODE_STREAMING:
pi->mps = le16_to_cpu(rfc.max_pdu_size);
chan->mps = le16_to_cpu(rfc.max_pdu_size);
}
}
......@@ -2076,6 +2063,8 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
goto response;
}
l2cap_pi(sk)->chan = chan;
write_lock_bh(&conn->chan_lock);
/* Check if we already have channel with that dcid */
......@@ -2091,23 +2080,21 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
l2cap_sock_init(sk, parent);
bacpy(&bt_sk(sk)->src, conn->src);
bacpy(&bt_sk(sk)->dst, conn->dst);
l2cap_pi(sk)->psm = psm;
l2cap_pi(sk)->dcid = scid;
chan->psm = psm;
chan->dcid = scid;
bt_accept_enqueue(parent, sk);
__l2cap_chan_add(conn, chan);
l2cap_pi(sk)->chan = chan;
dcid = l2cap_pi(sk)->scid;
dcid = chan->scid;
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
chan->ident = cmd->ident;
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
if (l2cap_check_security(sk)) {
if (l2cap_check_security(chan)) {
if (bt_sk(sk)->defer_setup) {
sk->sk_state = BT_CONNECT2;
result = L2CAP_CR_PEND;
......@@ -2155,10 +2142,10 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
L2CAP_INFO_REQ, sizeof(info), &info);
}
if (chan && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
if (chan && !(chan->conf_state & L2CAP_CONF_REQ_SENT) &&
result == L2CAP_CR_SUCCESS) {
u8 buf[128];
l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
chan->conf_state |= L2CAP_CONF_REQ_SENT;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
l2cap_build_conf_req(chan, buf), buf);
chan->num_conf_req++;
......@@ -2198,13 +2185,13 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
case L2CAP_CR_SUCCESS:
sk->sk_state = BT_CONFIG;
chan->ident = 0;
l2cap_pi(sk)->dcid = dcid;
l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
chan->dcid = dcid;
chan->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)
if (chan->conf_state & L2CAP_CONF_REQ_SENT)
break;
l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
chan->conf_state |= L2CAP_CONF_REQ_SENT;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
l2cap_build_conf_req(chan, req), req);
......@@ -2212,7 +2199,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
break;
case L2CAP_CR_PEND:
l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
chan->conf_state |= L2CAP_CONF_CONNECT_PEND;
break;
default:
......@@ -2232,15 +2219,17 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
return 0;
}
static inline void set_default_fcs(struct l2cap_pinfo *pi)
static inline void set_default_fcs(struct l2cap_chan *chan)
{
struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
/* FCS is enabled only in ERTM or streaming mode, if one or both
* sides request it.
*/
if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
pi->fcs = L2CAP_FCS_NONE;
else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV))
pi->fcs = L2CAP_FCS_CRC16;
if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
chan->fcs = L2CAP_FCS_NONE;
else if (!(pi->chan->conf_state & L2CAP_CONF_NO_FCS_RECV))
chan->fcs = L2CAP_FCS_CRC16;
}
static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
......@@ -2276,7 +2265,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
len = cmd_len - sizeof(*req);
if (chan->conf_len + len > sizeof(chan->conf_req)) {
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
l2cap_build_conf_rsp(sk, rsp,
l2cap_build_conf_rsp(chan, rsp,
L2CAP_CONF_REJECT, flags), rsp);
goto unlock;
}
......@@ -2288,7 +2277,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
if (flags & 0x0001) {
/* Incomplete config. Send empty response. */
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
l2cap_build_conf_rsp(sk, rsp,
l2cap_build_conf_rsp(chan, rsp,
L2CAP_CONF_SUCCESS, 0x0001), rsp);
goto unlock;
}
......@@ -2306,27 +2295,27 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
/* Reset config buffer. */
chan->conf_len = 0;
if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
if (!(chan->conf_state & L2CAP_CONF_OUTPUT_DONE))
goto unlock;
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
set_default_fcs(l2cap_pi(sk));
if (chan->conf_state & L2CAP_CONF_INPUT_DONE) {
set_default_fcs(chan);
sk->sk_state = BT_CONNECTED;
chan->next_tx_seq = 0;
chan->expected_tx_seq = 0;
skb_queue_head_init(&chan->tx_q);
if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
if (chan->mode == L2CAP_MODE_ERTM)
l2cap_ertm_init(chan);
l2cap_chan_ready(sk);
goto unlock;
}
if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
if (!(chan->conf_state & L2CAP_CONF_REQ_SENT)) {
u8 buf[64];
l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
chan->conf_state |= L2CAP_CONF_REQ_SENT;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
l2cap_build_conf_req(chan, buf), buf);
chan->num_conf_req++;
......@@ -2360,7 +2349,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
switch (result) {
case L2CAP_CONF_SUCCESS:
l2cap_conf_rfc_get(sk, rsp->data, len);
l2cap_conf_rfc_get(chan, rsp->data, len);
break;
case L2CAP_CONF_UNACCEPT:
......@@ -2374,8 +2363,8 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
/* throw out any old stored conf requests */
result = L2CAP_CONF_SUCCESS;
len = l2cap_parse_conf_rsp(sk, rsp->data,
len, req, &result);
len = l2cap_parse_conf_rsp(chan, rsp->data, len,
req, &result);
if (len < 0) {
l2cap_send_disconn_req(conn, chan, ECONNRESET);
goto done;
......@@ -2399,16 +2388,16 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
if (flags & 0x01)
goto done;
l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
chan->conf_state |= L2CAP_CONF_INPUT_DONE;
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
set_default_fcs(l2cap_pi(sk));
if (chan->conf_state & L2CAP_CONF_OUTPUT_DONE) {
set_default_fcs(chan);
sk->sk_state = BT_CONNECTED;
chan->next_tx_seq = 0;
chan->expected_tx_seq = 0;
skb_queue_head_init(&chan->tx_q);
if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
if (chan->mode == L2CAP_MODE_ERTM)
l2cap_ertm_init(chan);
l2cap_chan_ready(sk);
......@@ -2438,8 +2427,8 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
sk = chan->sk;
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
rsp.dcid = cpu_to_le16(chan->scid);
rsp.scid = cpu_to_le16(chan->dcid);
l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
sk->sk_shutdown = SHUTDOWN_MASK;
......@@ -2774,12 +2763,12 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn,
kfree_skb(skb);
}
static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
{
u16 our_fcs, rcv_fcs;
int hdr_size = L2CAP_HDR_SIZE + 2;
if (pi->fcs == L2CAP_FCS_CRC16) {
if (chan->fcs == L2CAP_FCS_CRC16) {
skb_trim(skb, skb->len - 2);
rcv_fcs = get_unaligned_le16(skb->data + skb->len);
our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
......@@ -2860,7 +2849,6 @@ static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb,
static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control)
{
struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
struct sk_buff *_skb;
int err;
......@@ -2881,7 +2869,7 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk
chan->sdu_len = get_unaligned_le16(skb->data);
if (chan->sdu_len > pi->imtu)
if (chan->sdu_len > chan->imtu)
goto disconnect;
chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC);
......@@ -2924,7 +2912,7 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk
if (!(chan->conn_state & L2CAP_CONN_SAR_RETRY)) {
chan->partial_sdu_len += skb->len;
if (chan->partial_sdu_len > pi->imtu)
if (chan->partial_sdu_len > chan->imtu)
goto drop;
if (chan->partial_sdu_len != chan->sdu_len)
......@@ -2961,7 +2949,7 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk
chan->sdu = NULL;
disconnect:
l2cap_send_disconn_req(pi->conn, chan, ECONNRESET);
l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
kfree_skb(skb);
return 0;
}
......@@ -3022,7 +3010,7 @@ static void l2cap_busy_work(struct work_struct *work)
if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) {
err = -EBUSY;
l2cap_send_disconn_req(l2cap_pi(sk)->conn, chan, EBUSY);
l2cap_send_disconn_req(chan->conn, chan, EBUSY);
break;
}
......@@ -3092,7 +3080,6 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c
static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control)
{
struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
struct sk_buff *_skb;
int err = -EINVAL;
......@@ -3123,7 +3110,7 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf
chan->sdu_len = get_unaligned_le16(skb->data);
skb_pull(skb, 2);
if (chan->sdu_len > pi->imtu) {
if (chan->sdu_len > chan->imtu) {
err = -EMSGSIZE;
break;
}
......@@ -3164,7 +3151,7 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf
chan->conn_state &= ~L2CAP_CONN_SAR_SDU;
chan->partial_sdu_len += skb->len;
if (chan->partial_sdu_len > pi->imtu)
if (chan->partial_sdu_len > chan->imtu)
goto drop;
if (chan->partial_sdu_len == chan->sdu_len) {
......@@ -3241,12 +3228,11 @@ static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq)
static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb)
{
struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
u8 tx_seq = __get_txseq(rx_control);
u8 req_seq = __get_reqseq(rx_control);
u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
int tx_seq_offset, expected_tx_seq_offset;
int num_to_ack = (pi->tx_win/6) + 1;
int num_to_ack = (chan->tx_win/6) + 1;
int err = 0;
BT_DBG("chan %p len %d tx_seq %d rx_control 0x%4.4x", chan, skb->len,
......@@ -3271,8 +3257,8 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont
tx_seq_offset += 64;
/* invalid tx_seq */
if (tx_seq_offset >= pi->tx_win) {
l2cap_send_disconn_req(pi->conn, chan, ECONNRESET);
if (tx_seq_offset >= chan->tx_win) {
l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
goto drop;
}
......@@ -3539,7 +3525,6 @@ static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_cont
static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
{
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct l2cap_pinfo *pi = l2cap_pi(sk);
u16 control;
u8 req_seq;
int len, next_tx_seq_offset, req_seq_offset;
......@@ -3553,17 +3538,17 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
* Receiver will miss it and start proper recovery
* procedures and ask retransmission.
*/
if (l2cap_check_fcs(pi, skb))
if (l2cap_check_fcs(chan, skb))
goto drop;
if (__is_sar_start(control) && __is_iframe(control))
len -= 2;
if (pi->fcs == L2CAP_FCS_CRC16)
if (chan->fcs == L2CAP_FCS_CRC16)
len -= 2;
if (len > pi->mps) {
l2cap_send_disconn_req(pi->conn, chan, ECONNRESET);
if (len > chan->mps) {
l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
goto drop;
}
......@@ -3579,13 +3564,13 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
/* check for invalid req-seq */
if (req_seq_offset > next_tx_seq_offset) {
l2cap_send_disconn_req(pi->conn, chan, ECONNRESET);
l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
goto drop;
}
if (__is_iframe(control)) {
if (len < 0) {
l2cap_send_disconn_req(pi->conn, chan, ECONNRESET);
l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
goto drop;
}
......@@ -3593,7 +3578,7 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
} else {
if (len != 0) {
BT_ERR("%d", len);
l2cap_send_disconn_req(pi->conn, chan, ECONNRESET);
l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
goto drop;
}
......@@ -3630,14 +3615,14 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
if (sk->sk_state != BT_CONNECTED)
goto drop;
switch (pi->mode) {
switch (chan->mode) {
case L2CAP_MODE_BASIC:
/* If socket recv buffers overflows we drop data here
* which is *bad* because L2CAP has to be reliable.
* But we don't have any other choice. L2CAP doesn't
* provide flow control mechanism. */
if (pi->imtu < skb->len)
if (chan->imtu < skb->len)
goto drop;
if (!sock_queue_rcv_skb(sk, skb))
......@@ -3659,16 +3644,16 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
skb_pull(skb, 2);
len = skb->len;
if (l2cap_check_fcs(pi, skb))
if (l2cap_check_fcs(chan, skb))
goto drop;
if (__is_sar_start(control))
len -= 2;
if (pi->fcs == L2CAP_FCS_CRC16)
if (chan->fcs == L2CAP_FCS_CRC16)
len -= 2;
if (len > pi->mps || len < 0 || __is_sframe(control))
if (len > chan->mps || len < 0 || __is_sframe(control))
goto drop;
tx_seq = __get_txseq(control);
......@@ -3683,7 +3668,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
goto done;
default:
BT_DBG("chan %p: bad mode 0x%2.2x", chan, pi->mode);
BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
break;
}
......@@ -3712,7 +3697,7 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str
if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
goto drop;
if (l2cap_pi(sk)->imtu < skb->len)
if (l2cap_pi(sk)->chan->imtu < skb->len)
goto drop;
if (!sock_queue_rcv_skb(sk, skb))
......@@ -3742,7 +3727,7 @@ static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct
if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
goto drop;
if (l2cap_pi(sk)->imtu < skb->len)
if (l2cap_pi(sk)->chan->imtu < skb->len)
goto drop;
if (!sock_queue_rcv_skb(sk, skb))
......@@ -3812,17 +3797,19 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
/* Find listening sockets and check their link_mode */
read_lock(&l2cap_sk_list.lock);
sk_for_each(sk, node, &l2cap_sk_list.head) {
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
if (sk->sk_state != BT_LISTEN)
continue;
if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
lm1 |= HCI_LM_ACCEPT;
if (l2cap_pi(sk)->role_switch)
if (chan->role_switch)
lm1 |= HCI_LM_MASTER;
exact++;
} else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
lm2 |= HCI_LM_ACCEPT;
if (l2cap_pi(sk)->role_switch)
if (chan->role_switch)
lm2 |= HCI_LM_MASTER;
}
}
......@@ -3874,19 +3861,21 @@ static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
return 0;
}
static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt)
static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
{
struct sock *sk = chan->sk;
if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
return;
if (encrypt == 0x00) {
if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) {
if (chan->sec_level == BT_SECURITY_MEDIUM) {
l2cap_sock_clear_timer(sk);
l2cap_sock_set_timer(sk, HZ * 5);
} else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
} else if (chan->sec_level == BT_SECURITY_HIGH)
__l2cap_sock_close(sk, ECONNREFUSED);
} else {
if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM)
if (chan->sec_level == BT_SECURITY_MEDIUM)
l2cap_sock_clear_timer(sk);
}
}
......@@ -3908,14 +3897,14 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
bh_lock_sock(sk);
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
if (chan->conf_state & L2CAP_CONF_CONNECT_PEND) {
bh_unlock_sock(sk);
continue;
}
if (!status && (sk->sk_state == BT_CONNECTED ||
sk->sk_state == BT_CONFIG)) {
l2cap_check_encryption(sk, encrypt);
l2cap_check_encryption(chan, encrypt);
bh_unlock_sock(sk);
continue;
}
......@@ -3923,11 +3912,11 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
if (sk->sk_state == BT_CONNECT) {
if (!status) {
struct l2cap_conn_req req;
req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
req.psm = l2cap_pi(sk)->psm;
req.scid = cpu_to_le16(chan->scid);
req.psm = chan->psm;
chan->ident = l2cap_get_ident(conn);
l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
chan->conf_state |= L2CAP_CONF_CONNECT_PEND;
l2cap_send_cmd(conn, chan->ident,
L2CAP_CONN_REQ, sizeof(req), &req);
......@@ -3948,8 +3937,8 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
result = L2CAP_CR_SEC_BLOCK;
}
rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
rsp.scid = cpu_to_le16(chan->dcid);
rsp.dcid = cpu_to_le16(chan->scid);
rsp.result = cpu_to_le16(result);
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
......@@ -4021,10 +4010,10 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
if (chan && chan->sk) {
struct sock *sk = chan->sk;
if (l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) {
if (chan->imtu < len - L2CAP_HDR_SIZE) {
BT_ERR("Frame exceeding recv MTU (len %d, "
"MTU %d)", len,
l2cap_pi(sk)->imtu);
chan->imtu);
bh_unlock_sock(sk);
l2cap_conn_unreliable(conn, ECOMM);
goto drop;
......@@ -4084,14 +4073,15 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p)
sk_for_each(sk, node, &l2cap_sk_list.head) {
struct l2cap_pinfo *pi = l2cap_pi(sk);
struct l2cap_chan *chan = pi->chan;
seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
batostr(&bt_sk(sk)->src),
batostr(&bt_sk(sk)->dst),
sk->sk_state, __le16_to_cpu(pi->psm),
pi->scid, pi->dcid,
pi->imtu, pi->omtu, pi->sec_level,
pi->mode);
sk->sk_state, __le16_to_cpu(chan->psm),
chan->scid, chan->dcid,
chan->imtu, chan->omtu, chan->sec_level,
chan->mode);
}
read_unlock_bh(&l2cap_sk_list.lock);
......
......@@ -30,6 +30,8 @@
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
static const struct proto_ops l2cap_sock_ops;
/* ---- L2CAP timers ---- */
static void l2cap_sock_timeout(unsigned long arg)
{
......@@ -51,7 +53,7 @@ static void l2cap_sock_timeout(unsigned long arg)
if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
reason = ECONNREFUSED;
else if (sk->sk_state == BT_CONNECT &&
l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
l2cap_pi(sk)->chan->sec_level != BT_SECURITY_SDP)
reason = ECONNREFUSED;
else
reason = ETIMEDOUT;
......@@ -80,9 +82,13 @@ static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
{
struct sock *sk;
struct hlist_node *node;
sk_for_each(sk, node, &l2cap_sk_list.head)
if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
sk_for_each(sk, node, &l2cap_sk_list.head) {
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
if (chan->sport == psm && !bacmp(&bt_sk(sk)->src, src))
goto found;
}
sk = NULL;
found:
return sk;
......@@ -91,6 +97,7 @@ static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
{
struct sock *sk = sock->sk;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct sockaddr_l2 la;
int len, err = 0;
......@@ -136,17 +143,17 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
} else {
/* Save source address */
bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
l2cap_pi(sk)->psm = la.l2_psm;
l2cap_pi(sk)->sport = la.l2_psm;
chan->psm = la.l2_psm;
chan->sport = la.l2_psm;
sk->sk_state = BT_BOUND;
if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
__le16_to_cpu(la.l2_psm) == 0x0003)
l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
chan->sec_level = BT_SECURITY_SDP;
}
if (la.l2_cid)
l2cap_pi(sk)->scid = la.l2_cid;
chan->scid = la.l2_cid;
write_unlock_bh(&l2cap_sk_list.lock);
......@@ -158,6 +165,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
{
struct sock *sk = sock->sk;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct sockaddr_l2 la;
int len, err = 0;
......@@ -182,7 +190,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
goto done;
}
switch (l2cap_pi(sk)->mode) {
switch (chan->mode) {
case L2CAP_MODE_BASIC:
break;
case L2CAP_MODE_ERTM:
......@@ -226,10 +234,10 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
/* Set destination address and psm */
bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
l2cap_pi(sk)->psm = la.l2_psm;
l2cap_pi(sk)->dcid = la.l2_cid;
chan->psm = la.l2_psm;
chan->dcid = la.l2_cid;
err = l2cap_do_connect(sk);
err = l2cap_chan_connect(l2cap_pi(sk)->chan);
if (err)
goto done;
......@@ -244,6 +252,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
static int l2cap_sock_listen(struct socket *sock, int backlog)
{
struct sock *sk = sock->sk;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
int err = 0;
BT_DBG("sk %p backlog %d", sk, backlog);
......@@ -256,7 +265,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
goto done;
}
switch (l2cap_pi(sk)->mode) {
switch (chan->mode) {
case L2CAP_MODE_BASIC:
break;
case L2CAP_MODE_ERTM:
......@@ -269,7 +278,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
goto done;
}
if (!l2cap_pi(sk)->psm && !l2cap_pi(sk)->scid) {
if (!chan->psm && !chan->scid) {
bdaddr_t *src = &bt_sk(sk)->src;
u16 psm;
......@@ -279,8 +288,8 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
for (psm = 0x1001; psm < 0x1100; psm += 2)
if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
l2cap_pi(sk)->psm = cpu_to_le16(psm);
l2cap_pi(sk)->sport = cpu_to_le16(psm);
chan->psm = cpu_to_le16(psm);
chan->sport = cpu_to_le16(psm);
err = 0;
break;
}
......@@ -360,6 +369,7 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
{
struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
struct sock *sk = sock->sk;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
BT_DBG("sock %p, sk %p", sock, sk);
......@@ -367,13 +377,13 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
*len = sizeof(struct sockaddr_l2);
if (peer) {
la->l2_psm = l2cap_pi(sk)->psm;
la->l2_psm = chan->psm;
bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
la->l2_cid = cpu_to_le16(chan->dcid);
} else {
la->l2_psm = l2cap_pi(sk)->sport;
la->l2_psm = chan->sport;
bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
la->l2_cid = cpu_to_le16(chan->scid);
}
return 0;
......@@ -382,6 +392,7 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
{
struct sock *sk = sock->sk;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct l2cap_options opts;
struct l2cap_conninfo cinfo;
int len, err = 0;
......@@ -397,13 +408,13 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
switch (optname) {
case L2CAP_OPTIONS:
memset(&opts, 0, sizeof(opts));
opts.imtu = l2cap_pi(sk)->imtu;
opts.omtu = l2cap_pi(sk)->omtu;
opts.flush_to = l2cap_pi(sk)->flush_to;
opts.mode = l2cap_pi(sk)->mode;
opts.fcs = l2cap_pi(sk)->fcs;
opts.max_tx = l2cap_pi(sk)->max_tx;
opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
opts.imtu = chan->imtu;
opts.omtu = chan->omtu;
opts.flush_to = chan->flush_to;
opts.mode = chan->mode;
opts.fcs = chan->fcs;
opts.max_tx = chan->max_tx;
opts.txwin_size = (__u16)chan->tx_win;
len = min_t(unsigned int, len, sizeof(opts));
if (copy_to_user(optval, (char *) &opts, len))
......@@ -412,7 +423,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
break;
case L2CAP_LM:
switch (l2cap_pi(sk)->sec_level) {
switch (chan->sec_level) {
case BT_SECURITY_LOW:
opt = L2CAP_LM_AUTH;
break;
......@@ -428,10 +439,10 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
break;
}
if (l2cap_pi(sk)->role_switch)
if (chan->role_switch)
opt |= L2CAP_LM_MASTER;
if (l2cap_pi(sk)->force_reliable)
if (chan->force_reliable)
opt |= L2CAP_LM_RELIABLE;
if (put_user(opt, (u32 __user *) optval))
......@@ -446,8 +457,8 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
break;
}
cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
cinfo.hci_handle = chan->conn->hcon->handle;
memcpy(cinfo.dev_class, chan->conn->hcon->dev_class, 3);
len = min_t(unsigned int, len, sizeof(cinfo));
if (copy_to_user(optval, (char *) &cinfo, len))
......@@ -467,6 +478,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
{
struct sock *sk = sock->sk;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct bt_security sec;
int len, err = 0;
......@@ -491,7 +503,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
break;
}
sec.level = l2cap_pi(sk)->sec_level;
sec.level = chan->sec_level;
len = min_t(unsigned int, len, sizeof(sec));
if (copy_to_user(optval, (char *) &sec, len))
......@@ -511,7 +523,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
break;
case BT_FLUSHABLE:
if (put_user(l2cap_pi(sk)->flushable, (u32 __user *) optval))
if (put_user(chan->flushable, (u32 __user *) optval))
err = -EFAULT;
break;
......@@ -528,6 +540,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct l2cap_options opts;
int len, err = 0;
u32 opt;
......@@ -543,13 +556,13 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
break;
}
opts.imtu = l2cap_pi(sk)->imtu;
opts.omtu = l2cap_pi(sk)->omtu;
opts.flush_to = l2cap_pi(sk)->flush_to;
opts.mode = l2cap_pi(sk)->mode;
opts.fcs = l2cap_pi(sk)->fcs;
opts.max_tx = l2cap_pi(sk)->max_tx;
opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
opts.imtu = chan->imtu;
opts.omtu = chan->omtu;
opts.flush_to = chan->flush_to;
opts.mode = chan->mode;
opts.fcs = chan->fcs;
opts.max_tx = chan->max_tx;
opts.txwin_size = (__u16)chan->tx_win;
len = min_t(unsigned int, sizeof(opts), optlen);
if (copy_from_user((char *) &opts, optval, len)) {
......@@ -562,10 +575,10 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
break;
}
l2cap_pi(sk)->mode = opts.mode;
switch (l2cap_pi(sk)->mode) {
chan->mode = opts.mode;
switch (chan->mode) {
case L2CAP_MODE_BASIC:
l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE;
chan->conf_state &= ~L2CAP_CONF_STATE2_DEVICE;
break;
case L2CAP_MODE_ERTM:
case L2CAP_MODE_STREAMING:
......@@ -577,11 +590,11 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
break;
}
l2cap_pi(sk)->imtu = opts.imtu;
l2cap_pi(sk)->omtu = opts.omtu;
l2cap_pi(sk)->fcs = opts.fcs;
l2cap_pi(sk)->max_tx = opts.max_tx;
l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
chan->imtu = opts.imtu;
chan->omtu = opts.omtu;
chan->fcs = opts.fcs;
chan->max_tx = opts.max_tx;
chan->tx_win = (__u8)opts.txwin_size;
break;
case L2CAP_LM:
......@@ -591,14 +604,14 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
}
if (opt & L2CAP_LM_AUTH)
l2cap_pi(sk)->sec_level = BT_SECURITY_LOW;
chan->sec_level = BT_SECURITY_LOW;
if (opt & L2CAP_LM_ENCRYPT)
l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM;
chan->sec_level = BT_SECURITY_MEDIUM;
if (opt & L2CAP_LM_SECURE)
l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH;
chan->sec_level = BT_SECURITY_HIGH;
l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER);
l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
chan->role_switch = (opt & L2CAP_LM_MASTER);
chan->force_reliable = (opt & L2CAP_LM_RELIABLE);
break;
default:
......@@ -613,6 +626,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct bt_security sec;
int len, err = 0;
u32 opt;
......@@ -649,7 +663,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
break;
}
l2cap_pi(sk)->sec_level = sec.level;
chan->sec_level = sec.level;
break;
case BT_DEFER_SETUP:
......@@ -678,7 +692,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
}
if (opt == BT_FLUSHABLE_OFF) {
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
struct l2cap_conn *conn = chan->conn;
/* proceed futher only when we have l2cap_conn and
No Flush support in the LM */
if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) {
......@@ -687,7 +701,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
}
}
l2cap_pi(sk)->flushable = opt;
chan->flushable = opt;
break;
default:
......@@ -702,7 +716,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
{
struct sock *sk = sock->sk;
struct l2cap_pinfo *pi = l2cap_pi(sk);
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct sk_buff *skb;
u16 control;
int err;
......@@ -725,76 +739,77 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
/* Connectionless channel */
if (sk->sk_type == SOCK_DGRAM) {
skb = l2cap_create_connless_pdu(sk, msg, len);
skb = l2cap_create_connless_pdu(chan, msg, len);
if (IS_ERR(skb)) {
err = PTR_ERR(skb);
} else {
l2cap_do_send(sk, skb);
l2cap_do_send(chan, skb);
err = len;
}
goto done;
}
switch (pi->mode) {
switch (chan->mode) {
case L2CAP_MODE_BASIC:
/* Check outgoing MTU */
if (len > pi->omtu) {
if (len > chan->omtu) {
err = -EMSGSIZE;
goto done;
}
/* Create a basic PDU */
skb = l2cap_create_basic_pdu(sk, msg, len);
skb = l2cap_create_basic_pdu(chan, msg, len);
if (IS_ERR(skb)) {
err = PTR_ERR(skb);
goto done;
}
l2cap_do_send(sk, skb);
l2cap_do_send(chan, skb);
err = len;
break;
case L2CAP_MODE_ERTM:
case L2CAP_MODE_STREAMING:
/* Entire SDU fits into one PDU */
if (len <= pi->chan->remote_mps) {
if (len <= chan->remote_mps) {
control = L2CAP_SDU_UNSEGMENTED;
skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
skb = l2cap_create_iframe_pdu(chan, msg, len, control,
0);
if (IS_ERR(skb)) {
err = PTR_ERR(skb);
goto done;
}
__skb_queue_tail(&pi->chan->tx_q, skb);
__skb_queue_tail(&chan->tx_q, skb);
if (pi->chan->tx_send_head == NULL)
pi->chan->tx_send_head = skb;
if (chan->tx_send_head == NULL)
chan->tx_send_head = skb;
} else {
/* Segment SDU into multiples PDUs */
err = l2cap_sar_segment_sdu(pi->chan, msg, len);
err = l2cap_sar_segment_sdu(chan, msg, len);
if (err < 0)
goto done;
}
if (pi->mode == L2CAP_MODE_STREAMING) {
l2cap_streaming_send(pi->chan);
if (chan->mode == L2CAP_MODE_STREAMING) {
l2cap_streaming_send(chan);
err = len;
break;
}
if ((pi->chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
(pi->chan->conn_state & L2CAP_CONN_WAIT_F)) {
if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
(chan->conn_state & L2CAP_CONN_WAIT_F)) {
err = len;
break;
}
err = l2cap_ertm_send(pi->chan);
err = l2cap_ertm_send(chan);
if (err >= 0)
err = len;
break;
default:
BT_DBG("bad state %1.1x", pi->mode);
BT_DBG("bad state %1.1x", chan->mode);
err = -EBADFD;
}
......@@ -810,7 +825,9 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms
lock_sock(sk);
if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) {
__l2cap_connect_rsp_defer(sk);
sk->sk_state = BT_CONFIG;
__l2cap_connect_rsp_defer(l2cap_pi(sk)->chan);
release_sock(sk);
return 0;
}
......@@ -834,6 +851,8 @@ void l2cap_sock_kill(struct sock *sk)
BT_DBG("sk %p state %d", sk, sk->sk_state);
/* Kill poor orphan */
l2cap_chan_free(l2cap_pi(sk)->chan);
bt_sock_unlink(&l2cap_sk_list, sk);
sock_set_flag(sk, SOCK_DEAD);
sock_put(sk);
......@@ -865,8 +884,8 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
void __l2cap_sock_close(struct sock *sk, int reason)
{
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct l2cap_conn *conn = chan->conn;
BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
......@@ -898,8 +917,8 @@ void __l2cap_sock_close(struct sock *sk, int reason)
else
result = L2CAP_CR_BAD_PSM;
rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
rsp.scid = cpu_to_le16(chan->dcid);
rsp.dcid = cpu_to_le16(chan->scid);
rsp.result = cpu_to_le16(result);
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
......@@ -923,6 +942,7 @@ void __l2cap_sock_close(struct sock *sk, int reason)
static int l2cap_sock_shutdown(struct socket *sock, int how)
{
struct sock *sk = sock->sk;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
int err = 0;
BT_DBG("sock %p, sk %p", sock, sk);
......@@ -932,7 +952,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
lock_sock(sk);
if (!sk->sk_shutdown) {
if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
if (chan->mode == L2CAP_MODE_ERTM)
err = __l2cap_wait_ack(sk);
sk->sk_shutdown = SHUTDOWN_MASK;
......@@ -979,44 +999,47 @@ static void l2cap_sock_destruct(struct sock *sk)
void l2cap_sock_init(struct sock *sk, struct sock *parent)
{
struct l2cap_pinfo *pi = l2cap_pi(sk);
struct l2cap_chan *chan = pi->chan;
BT_DBG("sk %p", sk);
if (parent) {
struct l2cap_chan *pchan = l2cap_pi(parent)->chan;
sk->sk_type = parent->sk_type;
bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
pi->imtu = l2cap_pi(parent)->imtu;
pi->omtu = l2cap_pi(parent)->omtu;
pi->conf_state = l2cap_pi(parent)->conf_state;
pi->mode = l2cap_pi(parent)->mode;
pi->fcs = l2cap_pi(parent)->fcs;
pi->max_tx = l2cap_pi(parent)->max_tx;
pi->tx_win = l2cap_pi(parent)->tx_win;
pi->sec_level = l2cap_pi(parent)->sec_level;
pi->role_switch = l2cap_pi(parent)->role_switch;
pi->force_reliable = l2cap_pi(parent)->force_reliable;
pi->flushable = l2cap_pi(parent)->flushable;
chan->imtu = pchan->imtu;
chan->omtu = pchan->omtu;
chan->conf_state = pchan->conf_state;
chan->mode = pchan->mode;
chan->fcs = pchan->fcs;
chan->max_tx = pchan->max_tx;
chan->tx_win = pchan->tx_win;
chan->sec_level = pchan->sec_level;
chan->role_switch = pchan->role_switch;
chan->force_reliable = pchan->force_reliable;
chan->flushable = pchan->flushable;
} else {
pi->imtu = L2CAP_DEFAULT_MTU;
pi->omtu = 0;
chan->imtu = L2CAP_DEFAULT_MTU;
chan->omtu = 0;
if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
pi->mode = L2CAP_MODE_ERTM;
pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
chan->mode = L2CAP_MODE_ERTM;
chan->conf_state |= L2CAP_CONF_STATE2_DEVICE;
} else {
pi->mode = L2CAP_MODE_BASIC;
chan->mode = L2CAP_MODE_BASIC;
}
pi->max_tx = L2CAP_DEFAULT_MAX_TX;
pi->fcs = L2CAP_FCS_CRC16;
pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
pi->sec_level = BT_SECURITY_LOW;
pi->role_switch = 0;
pi->force_reliable = 0;
pi->flushable = BT_FLUSHABLE_OFF;
chan->max_tx = L2CAP_DEFAULT_MAX_TX;
chan->fcs = L2CAP_FCS_CRC16;
chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
chan->sec_level = BT_SECURITY_LOW;
chan->role_switch = 0;
chan->force_reliable = 0;
chan->flushable = BT_FLUSHABLE_OFF;
}
/* Default config options */
pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
}
static struct proto l2cap_proto = {
......@@ -1054,6 +1077,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
int kern)
{
struct sock *sk;
struct l2cap_chan *chan;
BT_DBG("sock %p", sock);
......@@ -1072,11 +1096,19 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
if (!sk)
return -ENOMEM;
chan = l2cap_chan_alloc(sk);
if (!chan) {
l2cap_sock_kill(sk);
return -ENOMEM;
}
l2cap_pi(sk)->chan = chan;
l2cap_sock_init(sk, NULL);
return 0;
}
const struct proto_ops l2cap_sock_ops = {
static const struct proto_ops l2cap_sock_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = l2cap_sock_release,
......
......@@ -945,7 +945,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
for (i = 0; i < key_count; i++) {
struct mgmt_key_info *key = &cp->keys[i];
hci_add_link_key(hdev, 0, &key->bdaddr, key->val, key->type,
hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type,
key->pin_len);
}
......@@ -1569,6 +1569,75 @@ static int remove_remote_oob_data(struct sock *sk, u16 index,
return err;
}
static int start_discovery(struct sock *sk, u16 index)
{
u8 lap[3] = { 0x33, 0x8b, 0x9e };
struct hci_cp_inquiry cp;
struct pending_cmd *cmd;
struct hci_dev *hdev;
int err;
BT_DBG("hci%u", index);
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_START_DISCOVERY, ENODEV);
hci_dev_lock_bh(hdev);
cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, index, NULL, 0);
if (!cmd) {
err = -ENOMEM;
goto failed;
}
memset(&cp, 0, sizeof(cp));
memcpy(&cp.lap, lap, 3);
cp.length = 0x08;
cp.num_rsp = 0x00;
err = hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
if (err < 0)
mgmt_pending_remove(cmd);
failed:
hci_dev_unlock_bh(hdev);
hci_dev_put(hdev);
return err;
}
static int stop_discovery(struct sock *sk, u16 index)
{
struct hci_dev *hdev;
struct pending_cmd *cmd;
int err;
BT_DBG("hci%u", index);
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY, ENODEV);
hci_dev_lock_bh(hdev);
cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, index, NULL, 0);
if (!cmd) {
err = -ENOMEM;
goto failed;
}
err = hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
if (err < 0)
mgmt_pending_remove(cmd);
failed:
hci_dev_unlock_bh(hdev);
hci_dev_put(hdev);
return err;
}
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
{
unsigned char *buf;
......@@ -1677,7 +1746,12 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
err = remove_remote_oob_data(sk, index, buf + sizeof(*hdr),
len);
break;
case MGMT_OP_START_DISCOVERY:
err = start_discovery(sk, index);
break;
case MGMT_OP_STOP_DISCOVERY:
err = stop_discovery(sk, index);
break;
default:
BT_DBG("Unknown op %u", opcode);
err = cmd_status(sk, index, opcode, 0x01);
......@@ -1784,17 +1858,17 @@ int mgmt_connectable(u16 index, u8 connectable)
return ret;
}
int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type)
int mgmt_new_key(u16 index, struct link_key *key, u8 persistent)
{
struct mgmt_ev_new_key ev;
memset(&ev, 0, sizeof(ev));
ev.store_hint = persistent;
bacpy(&ev.key.bdaddr, &key->bdaddr);
ev.key.type = key->type;
memcpy(ev.key.val, key->val, 16);
ev.key.pin_len = key->pin_len;
ev.old_key_type = old_key_type;
return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL);
}
......@@ -1868,11 +1942,12 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status)
return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL);
}
int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr)
int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure)
{
struct mgmt_ev_pin_code_request ev;
bacpy(&ev.bdaddr, bdaddr);
ev.secure = secure;
return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev),
NULL);
......@@ -1920,13 +1995,15 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
return err;
}
int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value)
int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value,
u8 confirm_hint)
{
struct mgmt_ev_user_confirm_request ev;
BT_DBG("hci%u", index);
bacpy(&ev.bdaddr, bdaddr);
ev.confirm_hint = confirm_hint;
put_unaligned_le32(value, &ev.value);
return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev),
......@@ -2075,3 +2152,9 @@ int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name)
return mgmt_event(MGMT_EV_REMOTE_NAME, index, &ev, sizeof(ev), NULL);
}
int mgmt_discovering(u16 index, u8 discovering)
{
return mgmt_event(MGMT_EV_DISCOVERING, index, &discovering,
sizeof(discovering), NULL);
}
......@@ -232,6 +232,8 @@ static int rfcomm_l2sock_create(struct socket **sock)
static inline int rfcomm_check_security(struct rfcomm_dlc *d)
{
struct sock *sk = d->session->sock->sk;
struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
__u8 auth_type;
switch (d->sec_level) {
......@@ -246,8 +248,7 @@ static inline int rfcomm_check_security(struct rfcomm_dlc *d)
break;
}
return hci_conn_security(l2cap_pi(sk)->conn->hcon, d->sec_level,
auth_type);
return hci_conn_security(conn->hcon, d->sec_level, auth_type);
}
static void rfcomm_session_timeout(unsigned long arg)
......@@ -710,10 +711,10 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
/* Set L2CAP options */
sk = sock->sk;
lock_sock(sk);
l2cap_pi(sk)->imtu = l2cap_mtu;
l2cap_pi(sk)->sec_level = sec_level;
l2cap_pi(sk)->chan->imtu = l2cap_mtu;
l2cap_pi(sk)->chan->sec_level = sec_level;
if (l2cap_ertm)
l2cap_pi(sk)->mode = L2CAP_MODE_ERTM;
l2cap_pi(sk)->chan->mode = L2CAP_MODE_ERTM;
release_sock(sk);
s = rfcomm_session_add(sock, BT_BOUND);
......@@ -1241,6 +1242,7 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
void rfcomm_dlc_accept(struct rfcomm_dlc *d)
{
struct sock *sk = d->session->sock->sk;
struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
BT_DBG("dlc %p", d);
......@@ -1254,7 +1256,7 @@ void rfcomm_dlc_accept(struct rfcomm_dlc *d)
rfcomm_dlc_unlock(d);
if (d->role_switch)
hci_conn_switch_role(l2cap_pi(sk)->conn->hcon, 0x00);
hci_conn_switch_role(conn->hcon, 0x00);
rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
}
......@@ -1890,7 +1892,8 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s)
/* We should adjust MTU on incoming sessions.
* L2CAP MTU minus UIH header and FCS. */
s->mtu = min(l2cap_pi(nsock->sk)->omtu, l2cap_pi(nsock->sk)->imtu) - 5;
s->mtu = min(l2cap_pi(nsock->sk)->chan->omtu,
l2cap_pi(nsock->sk)->chan->imtu) - 5;
rfcomm_schedule();
} else
......@@ -1909,7 +1912,7 @@ static inline void rfcomm_check_connection(struct rfcomm_session *s)
/* We can adjust MTU on outgoing sessions.
* L2CAP MTU minus UIH header and FCS. */
s->mtu = min(l2cap_pi(sk)->omtu, l2cap_pi(sk)->imtu) - 5;
s->mtu = min(l2cap_pi(sk)->chan->omtu, l2cap_pi(sk)->chan->imtu) - 5;
rfcomm_send_sabm(s, 0);
break;
......@@ -1992,7 +1995,7 @@ static int rfcomm_add_listener(bdaddr_t *ba)
/* Set L2CAP options */
sk = sock->sk;
lock_sock(sk);
l2cap_pi(sk)->imtu = l2cap_mtu;
l2cap_pi(sk)->chan->imtu = l2cap_mtu;
release_sock(sk);
/* Start listening on the socket */
......
......@@ -743,6 +743,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
struct sock *sk = sock->sk;
struct sock *l2cap_sk;
struct rfcomm_conninfo cinfo;
struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
int len, err = 0;
u32 opt;
......@@ -787,8 +788,8 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk;
cinfo.hci_handle = l2cap_pi(l2cap_sk)->conn->hcon->handle;
memcpy(cinfo.dev_class, l2cap_pi(l2cap_sk)->conn->hcon->dev_class, 3);
cinfo.hci_handle = conn->hcon->handle;
memcpy(cinfo.dev_class, conn->hcon->dev_class, 3);
len = min_t(unsigned int, len, sizeof(cinfo));
if (copy_to_user(optval, (char *) &cinfo, len))
......
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