From 85eb53c6f719523dde9e0658823dffd2664d4d1c Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Thu, 3 Jun 2010 18:43:28 -0300 Subject: [PATCH] Bluetooth: Change the way we set ERTM mode as mandatory MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit If the socket type is SOCK_STREAM we set Enhanced Retransmisson Mode or Streaming Mode as mandatory. That means that we will close the channel if the other side doesn't support or request the the mandatory mode. Basic mode can't be set as mandatory. Signed-off-by: Gustavo F. Padovan Reviewed-by: João Paulo Rechi Vita Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 65c6a989449a..e78a7504d09c 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -831,6 +831,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) 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; @@ -841,10 +842,12 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) } else { pi->imtu = L2CAP_DEFAULT_MTU; pi->omtu = 0; - if (enable_ertm && sk->sk_type == SOCK_STREAM) + if (enable_ertm && sk->sk_type == SOCK_STREAM) { pi->mode = L2CAP_MODE_ERTM; - else + pi->conf_state |= L2CAP_CONF_STATE2_DEVICE; + } else { pi->mode = L2CAP_MODE_BASIC; + } pi->max_tx = L2CAP_DEFAULT_MAX_TX; pi->fcs = L2CAP_FCS_CRC16; pi->tx_win = L2CAP_DEFAULT_TX_WINDOW; @@ -1925,6 +1928,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us l2cap_pi(sk)->mode = opts.mode; switch (l2cap_pi(sk)->mode) { case L2CAP_MODE_BASIC: + l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE; break; case L2CAP_MODE_ERTM: case L2CAP_MODE_STREAMING: @@ -2469,7 +2473,12 @@ static int l2cap_build_conf_req(struct sock *sk, void *data) switch (pi->mode) { case L2CAP_MODE_STREAMING: case L2CAP_MODE_ERTM: - pi->conf_state |= L2CAP_CONF_STATE2_DEVICE; + if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) { + pi->mode = l2cap_select_mode(rfc.mode, + pi->conn->feat_mask); + break; + } + if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask)) l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); break; @@ -2602,7 +2611,12 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data) switch (pi->mode) { case L2CAP_MODE_STREAMING: case L2CAP_MODE_ERTM: - pi->conf_state |= L2CAP_CONF_STATE2_DEVICE; + if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) { + pi->mode = l2cap_select_mode(rfc.mode, + pi->conn->feat_mask); + break; + } + if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask)) return -ECONNREFUSED; break; -- 2.11.0