Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode
This adds the initial code for Enhanced Credit Based Mode which introduces a new socket mode called L2CAP_MODE_EXT_FLOWCTL, which for the most part work the same as L2CAP_MODE_LE_FLOWCTL but uses different PDUs to setup the connections and also works over BR/EDR. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:

committed by
Marcel Holtmann

parent
145720963b
commit
15f02b9105
@@ -232,7 +232,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (chan->psm && bdaddr_type_is_le(chan->src_type))
|
||||
if (chan->psm && bdaddr_type_is_le(chan->src_type) && !chan->mode)
|
||||
chan->mode = L2CAP_MODE_LE_FLOWCTL;
|
||||
|
||||
err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid),
|
||||
@@ -273,6 +273,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
|
||||
switch (chan->mode) {
|
||||
case L2CAP_MODE_BASIC:
|
||||
case L2CAP_MODE_LE_FLOWCTL:
|
||||
case L2CAP_MODE_EXT_FLOWCTL:
|
||||
break;
|
||||
case L2CAP_MODE_ERTM:
|
||||
case L2CAP_MODE_STREAMING:
|
||||
@@ -427,6 +428,8 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname,
|
||||
opts.max_tx = chan->max_tx;
|
||||
opts.txwin_size = chan->tx_win;
|
||||
|
||||
BT_DBG("mode 0x%2.2x", chan->mode);
|
||||
|
||||
len = min_t(unsigned int, len, sizeof(opts));
|
||||
if (copy_to_user(optval, (char *) &opts, len))
|
||||
err = -EFAULT;
|
||||
@@ -707,6 +710,8 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
|
||||
break;
|
||||
}
|
||||
|
||||
BT_DBG("mode 0x%2.2x", chan->mode);
|
||||
|
||||
chan->imtu = opts.imtu;
|
||||
chan->omtu = opts.omtu;
|
||||
chan->fcs = opts.fcs;
|
||||
@@ -939,7 +944,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||
break;
|
||||
}
|
||||
|
||||
if (sk->sk_state == BT_CONNECTED) {
|
||||
if (chan->mode == L2CAP_MODE_LE_FLOWCTL &&
|
||||
sk->sk_state == BT_CONNECTED) {
|
||||
err = -EISCONN;
|
||||
break;
|
||||
}
|
||||
@@ -949,7 +955,12 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||
break;
|
||||
}
|
||||
|
||||
chan->imtu = opt;
|
||||
if (chan->mode == L2CAP_MODE_EXT_FLOWCTL &&
|
||||
sk->sk_state == BT_CONNECTED)
|
||||
err = l2cap_chan_reconfigure(chan, opt);
|
||||
else
|
||||
chan->imtu = opt;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1004,7 +1015,11 @@ static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
|
||||
if (sk->sk_state == BT_CONNECT2 && test_bit(BT_SK_DEFER_SETUP,
|
||||
&bt_sk(sk)->flags)) {
|
||||
if (bdaddr_type_is_le(pi->chan->src_type)) {
|
||||
if (pi->chan->mode == L2CAP_MODE_EXT_FLOWCTL) {
|
||||
sk->sk_state = BT_CONNECTED;
|
||||
pi->chan->state = BT_CONNECTED;
|
||||
__l2cap_ecred_conn_rsp_defer(pi->chan);
|
||||
} if (bdaddr_type_is_le(pi->chan->src_type)) {
|
||||
sk->sk_state = BT_CONNECTED;
|
||||
pi->chan->state = BT_CONNECTED;
|
||||
__l2cap_le_connect_rsp_defer(pi->chan);
|
||||
|
Reference in New Issue
Block a user