Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0cd75f7e authored by Johan Hedberg's avatar Johan Hedberg Committed by Marcel Holtmann
Browse files

Bluetooth: Track LE L2CAP credits in l2cap_chan



This patch adds tracking of L2CAP connection oriented channel local and
remote credits to struct l2cap_chan and ensures that connect requests
and responses contain the right values.

Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 38319713
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -514,6 +514,9 @@ struct l2cap_chan {
	__u16		monitor_timeout;
	__u16		mps;

	__u16		tx_credits;
	__u16		rx_credits;

	__u8		tx_state;
	__u8		rx_state;

+11 −5
Original line number Diff line number Diff line
@@ -495,6 +495,8 @@ void l2cap_le_flowctl_init(struct l2cap_chan *chan)
	chan->imtu = L2CAP_DEFAULT_MTU;
	chan->omtu = L2CAP_LE_MIN_MTU;
	chan->mode = L2CAP_MODE_LE_FLOWCTL;
	chan->tx_credits = 0;
	chan->rx_credits = L2CAP_LE_MAX_CREDITS;
}

void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
@@ -643,7 +645,7 @@ static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
	rsp.dcid    = cpu_to_le16(chan->scid);
	rsp.mtu     = cpu_to_le16(chan->imtu);
	rsp.mps     = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
	rsp.credits = __constant_cpu_to_le16(L2CAP_LE_MAX_CREDITS);
	rsp.credits = cpu_to_le16(chan->rx_credits);
	rsp.result  = cpu_to_le16(result);

	l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
@@ -1212,7 +1214,7 @@ static void l2cap_le_connect(struct l2cap_chan *chan)
	req.scid    = cpu_to_le16(chan->scid);
	req.mtu     = cpu_to_le16(chan->imtu);
	req.mps     = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
	req.credits = __constant_cpu_to_le16(L2CAP_LE_MAX_CREDITS);
	req.credits = cpu_to_le16(chan->rx_credits);

	chan->ident = l2cap_get_ident(conn);

@@ -3690,7 +3692,7 @@ void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
	rsp.dcid    = cpu_to_le16(chan->scid);
	rsp.mtu     = cpu_to_le16(chan->imtu);
	rsp.mps     = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
	rsp.credits = __constant_cpu_to_le16(L2CAP_LE_MAX_CREDITS);
	rsp.credits = cpu_to_le16(chan->rx_credits);
	rsp.result  = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);

	l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
@@ -5342,6 +5344,7 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
		chan->dcid = dcid;
		chan->omtu = mtu;
		chan->remote_mps = mps;
		chan->tx_credits = credits;
		l2cap_chan_ready(chan);
		break;

@@ -5445,7 +5448,7 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
	struct l2cap_le_conn_req *req = (struct l2cap_le_conn_req *) data;
	struct l2cap_le_conn_rsp rsp;
	struct l2cap_chan *chan, *pchan;
	u16 dcid, scid, mtu, mps;
	u16 dcid, scid, credits, mtu, mps;
	__le16 psm;
	u8 result;

@@ -5457,6 +5460,7 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
	mps  = __le16_to_cpu(req->mps);
	psm  = req->psm;
	dcid = 0;
	credits = 0;

	if (mtu < 23 || mps < 23)
		return -EPROTO;
@@ -5503,9 +5507,11 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
	chan->dcid = scid;
	chan->omtu = mtu;
	chan->remote_mps = mps;
	chan->tx_credits = __le16_to_cpu(req->credits);

	__l2cap_chan_add(conn, chan);
	dcid = chan->scid;
	credits = chan->rx_credits;

	__set_chan_timer(chan, chan->ops->get_sndtimeo(chan));

@@ -5537,7 +5543,7 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
	}

	rsp.dcid    = cpu_to_le16(dcid);
	rsp.credits = __constant_cpu_to_le16(L2CAP_LE_MAX_CREDITS);
	rsp.credits = cpu_to_le16(credits);
	rsp.result  = cpu_to_le16(result);

	l2cap_send_cmd(conn, cmd->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp);
+2 −0
Original line number Diff line number Diff line
@@ -1321,6 +1321,8 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
		chan->tx_win_max = pchan->tx_win_max;
		chan->sec_level = pchan->sec_level;
		chan->flags = pchan->flags;
		chan->tx_credits = pchan->tx_credits;
		chan->rx_credits = pchan->rx_credits;

		security_sk_clone(parent, sk);
	} else {