|
@@ -917,10 +917,38 @@ static void l2cap_send_conn_req(struct l2cap_chan *chan)
|
|
l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
|
|
l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void l2cap_chan_ready(struct l2cap_chan *chan)
|
|
|
|
+{
|
|
|
|
+ struct sock *sk = chan->sk;
|
|
|
|
+ struct sock *parent;
|
|
|
|
+
|
|
|
|
+ lock_sock(sk);
|
|
|
|
+
|
|
|
|
+ parent = bt_sk(sk)->parent;
|
|
|
|
+
|
|
|
|
+ BT_DBG("sk %p, parent %p", sk, parent);
|
|
|
|
+
|
|
|
|
+ chan->conf_state = 0;
|
|
|
|
+ __clear_chan_timer(chan);
|
|
|
|
+
|
|
|
|
+ __l2cap_state_change(chan, BT_CONNECTED);
|
|
|
|
+ sk->sk_state_change(sk);
|
|
|
|
+
|
|
|
|
+ if (parent)
|
|
|
|
+ parent->sk_data_ready(parent, 0);
|
|
|
|
+
|
|
|
|
+ release_sock(sk);
|
|
|
|
+}
|
|
|
|
+
|
|
static void l2cap_do_start(struct l2cap_chan *chan)
|
|
static void l2cap_do_start(struct l2cap_chan *chan)
|
|
{
|
|
{
|
|
struct l2cap_conn *conn = chan->conn;
|
|
struct l2cap_conn *conn = chan->conn;
|
|
|
|
|
|
|
|
+ if (conn->hcon->type == LE_LINK) {
|
|
|
|
+ l2cap_chan_ready(chan);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
|
|
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
|
|
if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
|
|
if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
|
|
return;
|
|
return;
|
|
@@ -1156,29 +1184,6 @@ clean:
|
|
release_sock(parent);
|
|
release_sock(parent);
|
|
}
|
|
}
|
|
|
|
|
|
-static void l2cap_chan_ready(struct l2cap_chan *chan)
|
|
|
|
-{
|
|
|
|
- struct sock *sk = chan->sk;
|
|
|
|
- struct sock *parent;
|
|
|
|
-
|
|
|
|
- lock_sock(sk);
|
|
|
|
-
|
|
|
|
- parent = bt_sk(sk)->parent;
|
|
|
|
-
|
|
|
|
- BT_DBG("sk %p, parent %p", sk, parent);
|
|
|
|
-
|
|
|
|
- chan->conf_state = 0;
|
|
|
|
- __clear_chan_timer(chan);
|
|
|
|
-
|
|
|
|
- __l2cap_state_change(chan, BT_CONNECTED);
|
|
|
|
- sk->sk_state_change(sk);
|
|
|
|
-
|
|
|
|
- if (parent)
|
|
|
|
- parent->sk_data_ready(parent, 0);
|
|
|
|
-
|
|
|
|
- release_sock(sk);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static void l2cap_conn_ready(struct l2cap_conn *conn)
|
|
static void l2cap_conn_ready(struct l2cap_conn *conn)
|
|
{
|
|
{
|
|
struct l2cap_chan *chan;
|
|
struct l2cap_chan *chan;
|
|
@@ -1492,6 +1497,18 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *d
|
|
goto done;
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (hcon->type == LE_LINK) {
|
|
|
|
+ err = 0;
|
|
|
|
+
|
|
|
|
+ if (!list_empty(&conn->chan_l)) {
|
|
|
|
+ err = -EBUSY;
|
|
|
|
+ hci_conn_put(hcon);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (err)
|
|
|
|
+ goto done;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* Update source addr of the socket */
|
|
/* Update source addr of the socket */
|
|
bacpy(src, conn->src);
|
|
bacpy(src, conn->src);
|
|
|
|
|