|
@@ -210,27 +210,33 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
|
|
|
|
|
|
static void l2cap_chan_set_timer(struct l2cap_chan *chan, long timeout)
|
|
static void l2cap_chan_set_timer(struct l2cap_chan *chan, long timeout)
|
|
{
|
|
{
|
|
- BT_DBG("chan %p state %d timeout %ld", chan->sk, chan->sk->sk_state,
|
|
|
|
- timeout);
|
|
|
|
|
|
+ BT_DBG("chan %p state %d timeout %ld", chan->sk, chan->state, timeout);
|
|
|
|
+
|
|
if (!mod_timer(&chan->chan_timer, jiffies + timeout))
|
|
if (!mod_timer(&chan->chan_timer, jiffies + timeout))
|
|
sock_hold(chan->sk);
|
|
sock_hold(chan->sk);
|
|
}
|
|
}
|
|
|
|
|
|
static void l2cap_chan_clear_timer(struct l2cap_chan *chan)
|
|
static void l2cap_chan_clear_timer(struct l2cap_chan *chan)
|
|
{
|
|
{
|
|
- BT_DBG("chan %p state %d", chan, chan->sk->sk_state);
|
|
|
|
|
|
+ BT_DBG("chan %p state %d", chan, chan->state);
|
|
|
|
|
|
if (timer_pending(&chan->chan_timer) && del_timer(&chan->chan_timer))
|
|
if (timer_pending(&chan->chan_timer) && del_timer(&chan->chan_timer))
|
|
__sock_put(chan->sk);
|
|
__sock_put(chan->sk);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void l2cap_state_change(struct l2cap_chan *chan, int state)
|
|
|
|
+{
|
|
|
|
+ chan->state = state;
|
|
|
|
+ chan->ops->state_change(chan->data, state);
|
|
|
|
+}
|
|
|
|
+
|
|
static void l2cap_chan_timeout(unsigned long arg)
|
|
static void l2cap_chan_timeout(unsigned long arg)
|
|
{
|
|
{
|
|
struct l2cap_chan *chan = (struct l2cap_chan *) arg;
|
|
struct l2cap_chan *chan = (struct l2cap_chan *) arg;
|
|
struct sock *sk = chan->sk;
|
|
struct sock *sk = chan->sk;
|
|
int reason;
|
|
int reason;
|
|
|
|
|
|
- BT_DBG("chan %p state %d", chan, sk->sk_state);
|
|
|
|
|
|
+ BT_DBG("chan %p state %d", chan, chan->state);
|
|
|
|
|
|
bh_lock_sock(sk);
|
|
bh_lock_sock(sk);
|
|
|
|
|
|
@@ -242,9 +248,9 @@ static void l2cap_chan_timeout(unsigned long arg)
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
|
|
|
|
|
|
+ if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
|
|
reason = ECONNREFUSED;
|
|
reason = ECONNREFUSED;
|
|
- else if (sk->sk_state == BT_CONNECT &&
|
|
|
|
|
|
+ else if (chan->state == BT_CONNECT &&
|
|
chan->sec_level != BT_SECURITY_SDP)
|
|
chan->sec_level != BT_SECURITY_SDP)
|
|
reason = ECONNREFUSED;
|
|
reason = ECONNREFUSED;
|
|
else
|
|
else
|
|
@@ -274,6 +280,8 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk)
|
|
|
|
|
|
setup_timer(&chan->chan_timer, l2cap_chan_timeout, (unsigned long) chan);
|
|
setup_timer(&chan->chan_timer, l2cap_chan_timeout, (unsigned long) chan);
|
|
|
|
|
|
|
|
+ chan->state = BT_OPEN;
|
|
|
|
+
|
|
return chan;
|
|
return chan;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -348,7 +356,7 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err)
|
|
hci_conn_put(conn->hcon);
|
|
hci_conn_put(conn->hcon);
|
|
}
|
|
}
|
|
|
|
|
|
- sk->sk_state = BT_CLOSED;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CLOSED);
|
|
sock_set_flag(sk, SOCK_ZAPPED);
|
|
sock_set_flag(sk, SOCK_ZAPPED);
|
|
|
|
|
|
if (err)
|
|
if (err)
|
|
@@ -398,9 +406,6 @@ static void l2cap_chan_cleanup_listen(struct sock *parent)
|
|
release_sock(sk);
|
|
release_sock(sk);
|
|
chan->ops->close(chan->data);
|
|
chan->ops->close(chan->data);
|
|
}
|
|
}
|
|
-
|
|
|
|
- parent->sk_state = BT_CLOSED;
|
|
|
|
- sock_set_flag(parent, SOCK_ZAPPED);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void l2cap_chan_close(struct l2cap_chan *chan, int reason)
|
|
void l2cap_chan_close(struct l2cap_chan *chan, int reason)
|
|
@@ -408,11 +413,14 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
|
|
struct l2cap_conn *conn = chan->conn;
|
|
struct l2cap_conn *conn = chan->conn;
|
|
struct sock *sk = chan->sk;
|
|
struct sock *sk = chan->sk;
|
|
|
|
|
|
- BT_DBG("chan %p state %d socket %p", chan, sk->sk_state, sk->sk_socket);
|
|
|
|
|
|
+ BT_DBG("chan %p state %d socket %p", chan, chan->state, sk->sk_socket);
|
|
|
|
|
|
- switch (sk->sk_state) {
|
|
|
|
|
|
+ switch (chan->state) {
|
|
case BT_LISTEN:
|
|
case BT_LISTEN:
|
|
l2cap_chan_cleanup_listen(sk);
|
|
l2cap_chan_cleanup_listen(sk);
|
|
|
|
+
|
|
|
|
+ l2cap_state_change(chan, BT_CLOSED);
|
|
|
|
+ sock_set_flag(sk, SOCK_ZAPPED);
|
|
break;
|
|
break;
|
|
|
|
|
|
case BT_CONNECTED:
|
|
case BT_CONNECTED:
|
|
@@ -436,7 +444,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
|
|
result = L2CAP_CR_SEC_BLOCK;
|
|
result = L2CAP_CR_SEC_BLOCK;
|
|
else
|
|
else
|
|
result = L2CAP_CR_BAD_PSM;
|
|
result = L2CAP_CR_BAD_PSM;
|
|
- sk->sk_state = BT_DISCONN;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_DISCONN);
|
|
|
|
|
|
rsp.scid = cpu_to_le16(chan->dcid);
|
|
rsp.scid = cpu_to_le16(chan->dcid);
|
|
rsp.dcid = cpu_to_le16(chan->scid);
|
|
rsp.dcid = cpu_to_le16(chan->scid);
|
|
@@ -548,13 +556,11 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control)
|
|
{
|
|
{
|
|
struct sk_buff *skb;
|
|
struct sk_buff *skb;
|
|
struct l2cap_hdr *lh;
|
|
struct l2cap_hdr *lh;
|
|
- struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
|
|
|
|
struct l2cap_conn *conn = chan->conn;
|
|
struct l2cap_conn *conn = chan->conn;
|
|
- struct sock *sk = (struct sock *)pi;
|
|
|
|
int count, hlen = L2CAP_HDR_SIZE + 2;
|
|
int count, hlen = L2CAP_HDR_SIZE + 2;
|
|
u8 flags;
|
|
u8 flags;
|
|
|
|
|
|
- if (sk->sk_state != BT_CONNECTED)
|
|
|
|
|
|
+ if (chan->state != BT_CONNECTED)
|
|
return;
|
|
return;
|
|
|
|
|
|
if (chan->fcs == L2CAP_FCS_CRC16)
|
|
if (chan->fcs == L2CAP_FCS_CRC16)
|
|
@@ -689,7 +695,7 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *c
|
|
l2cap_send_cmd(conn, l2cap_get_ident(conn),
|
|
l2cap_send_cmd(conn, l2cap_get_ident(conn),
|
|
L2CAP_DISCONN_REQ, sizeof(req), &req);
|
|
L2CAP_DISCONN_REQ, sizeof(req), &req);
|
|
|
|
|
|
- sk->sk_state = BT_DISCONN;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_DISCONN);
|
|
sk->sk_err = err;
|
|
sk->sk_err = err;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -712,7 +718,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- if (sk->sk_state == BT_CONNECT) {
|
|
|
|
|
|
+ if (chan->state == BT_CONNECT) {
|
|
struct l2cap_conn_req req;
|
|
struct l2cap_conn_req req;
|
|
|
|
|
|
if (!l2cap_check_security(chan) ||
|
|
if (!l2cap_check_security(chan) ||
|
|
@@ -728,7 +734,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
|
|
/* l2cap_chan_close() calls list_del(chan)
|
|
/* l2cap_chan_close() calls list_del(chan)
|
|
* so release the lock */
|
|
* so release the lock */
|
|
read_unlock_bh(&conn->chan_lock);
|
|
read_unlock_bh(&conn->chan_lock);
|
|
- l2cap_chan_close(chan, ECONNRESET);
|
|
|
|
|
|
+ l2cap_chan_close(chan, ECONNRESET);
|
|
read_lock_bh(&conn->chan_lock);
|
|
read_lock_bh(&conn->chan_lock);
|
|
bh_unlock_sock(sk);
|
|
bh_unlock_sock(sk);
|
|
continue;
|
|
continue;
|
|
@@ -743,7 +749,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
|
|
l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ,
|
|
l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ,
|
|
sizeof(req), &req);
|
|
sizeof(req), &req);
|
|
|
|
|
|
- } else if (sk->sk_state == BT_CONNECT2) {
|
|
|
|
|
|
+ } else if (chan->state == BT_CONNECT2) {
|
|
struct l2cap_conn_rsp rsp;
|
|
struct l2cap_conn_rsp rsp;
|
|
char buf[128];
|
|
char buf[128];
|
|
rsp.scid = cpu_to_le16(chan->dcid);
|
|
rsp.scid = cpu_to_le16(chan->dcid);
|
|
@@ -757,7 +763,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
|
|
parent->sk_data_ready(parent, 0);
|
|
parent->sk_data_ready(parent, 0);
|
|
|
|
|
|
} else {
|
|
} else {
|
|
- sk->sk_state = BT_CONFIG;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CONFIG);
|
|
rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
|
|
rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
|
|
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
|
|
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
|
|
}
|
|
}
|
|
@@ -799,7 +805,7 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, __le16 cid, bdadd
|
|
list_for_each_entry(c, &chan_list, global_l) {
|
|
list_for_each_entry(c, &chan_list, global_l) {
|
|
struct sock *sk = c->sk;
|
|
struct sock *sk = c->sk;
|
|
|
|
|
|
- if (state && sk->sk_state != state)
|
|
|
|
|
|
+ if (state && c->state != state)
|
|
continue;
|
|
continue;
|
|
|
|
|
|
if (c->scid == cid) {
|
|
if (c->scid == cid) {
|
|
@@ -862,7 +868,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
|
|
|
|
|
|
l2cap_chan_set_timer(chan, sk->sk_sndtimeo);
|
|
l2cap_chan_set_timer(chan, sk->sk_sndtimeo);
|
|
|
|
|
|
- sk->sk_state = BT_CONNECTED;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CONNECTED);
|
|
parent->sk_data_ready(parent, 0);
|
|
parent->sk_data_ready(parent, 0);
|
|
|
|
|
|
write_unlock_bh(&conn->chan_lock);
|
|
write_unlock_bh(&conn->chan_lock);
|
|
@@ -889,15 +895,15 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
|
|
|
|
|
|
if (conn->hcon->type == LE_LINK) {
|
|
if (conn->hcon->type == LE_LINK) {
|
|
l2cap_chan_clear_timer(chan);
|
|
l2cap_chan_clear_timer(chan);
|
|
- sk->sk_state = BT_CONNECTED;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CONNECTED);
|
|
sk->sk_state_change(sk);
|
|
sk->sk_state_change(sk);
|
|
}
|
|
}
|
|
|
|
|
|
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
|
|
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
|
|
l2cap_chan_clear_timer(chan);
|
|
l2cap_chan_clear_timer(chan);
|
|
- sk->sk_state = BT_CONNECTED;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CONNECTED);
|
|
sk->sk_state_change(sk);
|
|
sk->sk_state_change(sk);
|
|
- } else if (sk->sk_state == BT_CONNECT)
|
|
|
|
|
|
+ } else if (chan->state == BT_CONNECT)
|
|
l2cap_do_start(chan);
|
|
l2cap_do_start(chan);
|
|
|
|
|
|
bh_unlock_sock(sk);
|
|
bh_unlock_sock(sk);
|
|
@@ -1025,7 +1031,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr
|
|
list_for_each_entry(c, &chan_list, global_l) {
|
|
list_for_each_entry(c, &chan_list, global_l) {
|
|
struct sock *sk = c->sk;
|
|
struct sock *sk = c->sk;
|
|
|
|
|
|
- if (state && sk->sk_state != state)
|
|
|
|
|
|
+ if (state && c->state != state)
|
|
continue;
|
|
continue;
|
|
|
|
|
|
if (c->psm == psm) {
|
|
if (c->psm == psm) {
|
|
@@ -1092,14 +1098,14 @@ int l2cap_chan_connect(struct l2cap_chan *chan)
|
|
|
|
|
|
l2cap_chan_add(conn, chan);
|
|
l2cap_chan_add(conn, chan);
|
|
|
|
|
|
- sk->sk_state = BT_CONNECT;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CONNECT);
|
|
l2cap_chan_set_timer(chan, sk->sk_sndtimeo);
|
|
l2cap_chan_set_timer(chan, sk->sk_sndtimeo);
|
|
|
|
|
|
if (hcon->state == BT_CONNECTED) {
|
|
if (hcon->state == BT_CONNECTED) {
|
|
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
|
|
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
|
|
l2cap_chan_clear_timer(chan);
|
|
l2cap_chan_clear_timer(chan);
|
|
if (l2cap_check_security(chan))
|
|
if (l2cap_check_security(chan))
|
|
- sk->sk_state = BT_CONNECTED;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CONNECTED);
|
|
} else
|
|
} else
|
|
l2cap_do_start(chan);
|
|
l2cap_do_start(chan);
|
|
}
|
|
}
|
|
@@ -1288,11 +1294,10 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq)
|
|
int l2cap_ertm_send(struct l2cap_chan *chan)
|
|
int l2cap_ertm_send(struct l2cap_chan *chan)
|
|
{
|
|
{
|
|
struct sk_buff *skb, *tx_skb;
|
|
struct sk_buff *skb, *tx_skb;
|
|
- struct sock *sk = chan->sk;
|
|
|
|
u16 control, fcs;
|
|
u16 control, fcs;
|
|
int nsent = 0;
|
|
int nsent = 0;
|
|
|
|
|
|
- if (sk->sk_state != BT_CONNECTED)
|
|
|
|
|
|
+ if (chan->state != BT_CONNECTED)
|
|
return -ENOTCONN;
|
|
return -ENOTCONN;
|
|
|
|
|
|
while ((skb = chan->tx_send_head) && (!l2cap_tx_window_full(chan))) {
|
|
while ((skb = chan->tx_send_head) && (!l2cap_tx_window_full(chan))) {
|
|
@@ -1668,7 +1673,7 @@ static void l2cap_chan_ready(struct sock *sk)
|
|
/* Outgoing channel.
|
|
/* Outgoing channel.
|
|
* Wake up socket sleeping on connect.
|
|
* Wake up socket sleeping on connect.
|
|
*/
|
|
*/
|
|
- sk->sk_state = BT_CONNECTED;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CONNECTED);
|
|
sk->sk_state_change(sk);
|
|
sk->sk_state_change(sk);
|
|
} else {
|
|
} else {
|
|
/* Incoming channel.
|
|
/* Incoming channel.
|
|
@@ -2364,22 +2369,22 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
|
|
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
|
|
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
|
|
if (l2cap_check_security(chan)) {
|
|
if (l2cap_check_security(chan)) {
|
|
if (bt_sk(sk)->defer_setup) {
|
|
if (bt_sk(sk)->defer_setup) {
|
|
- sk->sk_state = BT_CONNECT2;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CONNECT2);
|
|
result = L2CAP_CR_PEND;
|
|
result = L2CAP_CR_PEND;
|
|
status = L2CAP_CS_AUTHOR_PEND;
|
|
status = L2CAP_CS_AUTHOR_PEND;
|
|
parent->sk_data_ready(parent, 0);
|
|
parent->sk_data_ready(parent, 0);
|
|
} else {
|
|
} else {
|
|
- sk->sk_state = BT_CONFIG;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CONFIG);
|
|
result = L2CAP_CR_SUCCESS;
|
|
result = L2CAP_CR_SUCCESS;
|
|
status = L2CAP_CS_NO_INFO;
|
|
status = L2CAP_CS_NO_INFO;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- sk->sk_state = BT_CONNECT2;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CONNECT2);
|
|
result = L2CAP_CR_PEND;
|
|
result = L2CAP_CR_PEND;
|
|
status = L2CAP_CS_AUTHEN_PEND;
|
|
status = L2CAP_CS_AUTHEN_PEND;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- sk->sk_state = BT_CONNECT2;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CONNECT2);
|
|
result = L2CAP_CR_PEND;
|
|
result = L2CAP_CR_PEND;
|
|
status = L2CAP_CS_NO_INFO;
|
|
status = L2CAP_CS_NO_INFO;
|
|
}
|
|
}
|
|
@@ -2451,7 +2456,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
|
|
|
|
|
|
switch (result) {
|
|
switch (result) {
|
|
case L2CAP_CR_SUCCESS:
|
|
case L2CAP_CR_SUCCESS:
|
|
- sk->sk_state = BT_CONFIG;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CONFIG);
|
|
chan->ident = 0;
|
|
chan->ident = 0;
|
|
chan->dcid = dcid;
|
|
chan->dcid = dcid;
|
|
chan->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
|
|
chan->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
|
|
@@ -2473,7 +2478,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
|
|
default:
|
|
default:
|
|
/* don't delete l2cap channel if sk is owned by user */
|
|
/* don't delete l2cap channel if sk is owned by user */
|
|
if (sock_owned_by_user(sk)) {
|
|
if (sock_owned_by_user(sk)) {
|
|
- sk->sk_state = BT_DISCONN;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_DISCONN);
|
|
l2cap_chan_clear_timer(chan);
|
|
l2cap_chan_clear_timer(chan);
|
|
l2cap_chan_set_timer(chan, HZ / 5);
|
|
l2cap_chan_set_timer(chan, HZ / 5);
|
|
break;
|
|
break;
|
|
@@ -2520,7 +2525,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
|
|
|
|
|
|
sk = chan->sk;
|
|
sk = chan->sk;
|
|
|
|
|
|
- if (sk->sk_state != BT_CONFIG) {
|
|
|
|
|
|
+ if (chan->state != BT_CONFIG) {
|
|
struct l2cap_cmd_rej rej;
|
|
struct l2cap_cmd_rej rej;
|
|
|
|
|
|
rej.reason = cpu_to_le16(0x0002);
|
|
rej.reason = cpu_to_le16(0x0002);
|
|
@@ -2569,7 +2574,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
|
|
if (chan->conf_state & L2CAP_CONF_INPUT_DONE) {
|
|
if (chan->conf_state & L2CAP_CONF_INPUT_DONE) {
|
|
set_default_fcs(chan);
|
|
set_default_fcs(chan);
|
|
|
|
|
|
- sk->sk_state = BT_CONNECTED;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CONNECTED);
|
|
|
|
|
|
chan->next_tx_seq = 0;
|
|
chan->next_tx_seq = 0;
|
|
chan->expected_tx_seq = 0;
|
|
chan->expected_tx_seq = 0;
|
|
@@ -2661,7 +2666,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
|
|
if (chan->conf_state & L2CAP_CONF_OUTPUT_DONE) {
|
|
if (chan->conf_state & L2CAP_CONF_OUTPUT_DONE) {
|
|
set_default_fcs(chan);
|
|
set_default_fcs(chan);
|
|
|
|
|
|
- sk->sk_state = BT_CONNECTED;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CONNECTED);
|
|
chan->next_tx_seq = 0;
|
|
chan->next_tx_seq = 0;
|
|
chan->expected_tx_seq = 0;
|
|
chan->expected_tx_seq = 0;
|
|
skb_queue_head_init(&chan->tx_q);
|
|
skb_queue_head_init(&chan->tx_q);
|
|
@@ -2703,7 +2708,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
|
|
|
|
|
|
/* don't delete l2cap channel if sk is owned by user */
|
|
/* don't delete l2cap channel if sk is owned by user */
|
|
if (sock_owned_by_user(sk)) {
|
|
if (sock_owned_by_user(sk)) {
|
|
- sk->sk_state = BT_DISCONN;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_DISCONN);
|
|
l2cap_chan_clear_timer(chan);
|
|
l2cap_chan_clear_timer(chan);
|
|
l2cap_chan_set_timer(chan, HZ / 5);
|
|
l2cap_chan_set_timer(chan, HZ / 5);
|
|
bh_unlock_sock(sk);
|
|
bh_unlock_sock(sk);
|
|
@@ -2737,7 +2742,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
|
|
|
|
|
|
/* don't delete l2cap channel if sk is owned by user */
|
|
/* don't delete l2cap channel if sk is owned by user */
|
|
if (sock_owned_by_user(sk)) {
|
|
if (sock_owned_by_user(sk)) {
|
|
- sk->sk_state = BT_DISCONN;
|
|
|
|
|
|
+ l2cap_state_change(chan,BT_DISCONN);
|
|
l2cap_chan_clear_timer(chan);
|
|
l2cap_chan_clear_timer(chan);
|
|
l2cap_chan_set_timer(chan, HZ / 5);
|
|
l2cap_chan_set_timer(chan, HZ / 5);
|
|
bh_unlock_sock(sk);
|
|
bh_unlock_sock(sk);
|
|
@@ -3874,7 +3879,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
|
|
|
|
|
|
BT_DBG("chan %p, len %d", chan, skb->len);
|
|
BT_DBG("chan %p, len %d", chan, skb->len);
|
|
|
|
|
|
- if (sk->sk_state != BT_CONNECTED)
|
|
|
|
|
|
+ if (chan->state != BT_CONNECTED)
|
|
goto drop;
|
|
goto drop;
|
|
|
|
|
|
switch (chan->mode) {
|
|
switch (chan->mode) {
|
|
@@ -3959,7 +3964,7 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str
|
|
|
|
|
|
BT_DBG("sk %p, len %d", sk, skb->len);
|
|
BT_DBG("sk %p, len %d", sk, skb->len);
|
|
|
|
|
|
- if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
|
|
|
|
|
|
+ if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
|
|
goto drop;
|
|
goto drop;
|
|
|
|
|
|
if (l2cap_pi(sk)->chan->imtu < skb->len)
|
|
if (l2cap_pi(sk)->chan->imtu < skb->len)
|
|
@@ -3992,7 +3997,7 @@ static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct
|
|
|
|
|
|
BT_DBG("sk %p, len %d", sk, skb->len);
|
|
BT_DBG("sk %p, len %d", sk, skb->len);
|
|
|
|
|
|
- if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
|
|
|
|
|
|
+ if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
|
|
goto drop;
|
|
goto drop;
|
|
|
|
|
|
if (l2cap_pi(sk)->chan->imtu < skb->len)
|
|
if (l2cap_pi(sk)->chan->imtu < skb->len)
|
|
@@ -4066,7 +4071,7 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
|
|
list_for_each_entry(c, &chan_list, global_l) {
|
|
list_for_each_entry(c, &chan_list, global_l) {
|
|
struct sock *sk = c->sk;
|
|
struct sock *sk = c->sk;
|
|
|
|
|
|
- if (sk->sk_state != BT_LISTEN)
|
|
|
|
|
|
+ if (c->state != BT_LISTEN)
|
|
continue;
|
|
continue;
|
|
|
|
|
|
if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
|
|
if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
|
|
@@ -4167,14 +4172,14 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- if (!status && (sk->sk_state == BT_CONNECTED ||
|
|
|
|
- sk->sk_state == BT_CONFIG)) {
|
|
|
|
|
|
+ if (!status && (chan->state == BT_CONNECTED ||
|
|
|
|
+ chan->state == BT_CONFIG)) {
|
|
l2cap_check_encryption(chan, encrypt);
|
|
l2cap_check_encryption(chan, encrypt);
|
|
bh_unlock_sock(sk);
|
|
bh_unlock_sock(sk);
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- if (sk->sk_state == BT_CONNECT) {
|
|
|
|
|
|
+ if (chan->state == BT_CONNECT) {
|
|
if (!status) {
|
|
if (!status) {
|
|
struct l2cap_conn_req req;
|
|
struct l2cap_conn_req req;
|
|
req.scid = cpu_to_le16(chan->scid);
|
|
req.scid = cpu_to_le16(chan->scid);
|
|
@@ -4189,15 +4194,15 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
|
|
l2cap_chan_clear_timer(chan);
|
|
l2cap_chan_clear_timer(chan);
|
|
l2cap_chan_set_timer(chan, HZ / 10);
|
|
l2cap_chan_set_timer(chan, HZ / 10);
|
|
}
|
|
}
|
|
- } else if (sk->sk_state == BT_CONNECT2) {
|
|
|
|
|
|
+ } else if (chan->state == BT_CONNECT2) {
|
|
struct l2cap_conn_rsp rsp;
|
|
struct l2cap_conn_rsp rsp;
|
|
__u16 result;
|
|
__u16 result;
|
|
|
|
|
|
if (!status) {
|
|
if (!status) {
|
|
- sk->sk_state = BT_CONFIG;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_CONFIG);
|
|
result = L2CAP_CR_SUCCESS;
|
|
result = L2CAP_CR_SUCCESS;
|
|
} else {
|
|
} else {
|
|
- sk->sk_state = BT_DISCONN;
|
|
|
|
|
|
+ l2cap_state_change(chan, BT_DISCONN);
|
|
l2cap_chan_set_timer(chan, HZ / 10);
|
|
l2cap_chan_set_timer(chan, HZ / 10);
|
|
result = L2CAP_CR_SEC_BLOCK;
|
|
result = L2CAP_CR_SEC_BLOCK;
|
|
}
|
|
}
|
|
@@ -4341,7 +4346,7 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p)
|
|
seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
|
|
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)->src),
|
|
batostr(&bt_sk(sk)->dst),
|
|
batostr(&bt_sk(sk)->dst),
|
|
- sk->sk_state, __le16_to_cpu(c->psm),
|
|
|
|
|
|
+ c->state, __le16_to_cpu(c->psm),
|
|
c->scid, c->dcid, c->imtu, c->omtu,
|
|
c->scid, c->dcid, c->imtu, c->omtu,
|
|
c->sec_level, c->mode);
|
|
c->sec_level, c->mode);
|
|
}
|
|
}
|