[Bluetooth] Finish L2CAP configuration only with acceptable settings
authorMarcel Holtmann <marcel@holtmann.org>
Sat, 20 Oct 2007 11:35:42 +0000 (13:35 +0200)
committerDavid S. Miller <davem@sunset.davemloft.net>
Mon, 22 Oct 2007 09:59:40 +0000 (02:59 -0700)
The parameters of the L2CAP output configuration might not be accepted
after the first configuration round. So only indicate a finished output
configuration when acceptable settings are provided.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
net/bluetooth/l2cap.c

index 36ef27b..6ce693d 100644 (file)
@@ -1370,8 +1370,10 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
 
                if (pi->conf_mtu < pi->omtu)
                        result = L2CAP_CONF_UNACCEPT;
 
                if (pi->conf_mtu < pi->omtu)
                        result = L2CAP_CONF_UNACCEPT;
-               else
+               else {
                        pi->omtu = pi->conf_mtu;
                        pi->omtu = pi->conf_mtu;
+                       pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
+               }
 
                l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
        }
 
                l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
        }
@@ -1577,16 +1579,19 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 
        l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
 
 
        l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
 
-       /* Output config done. */
-       l2cap_pi(sk)->conf_state |= L2CAP_CONF_OUTPUT_DONE;
-
        /* Reset config buffer. */
        l2cap_pi(sk)->conf_len = 0;
 
        /* Reset config buffer. */
        l2cap_pi(sk)->conf_len = 0;
 
+       if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
+               goto unlock;
+
        if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
                sk->sk_state = BT_CONNECTED;
                l2cap_chan_ready(sk);
        if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
                sk->sk_state = BT_CONNECTED;
                l2cap_chan_ready(sk);
-       } else if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
+               goto unlock;
+       }
+
+       if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
                u8 req[64];
                l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
                                        l2cap_build_conf_req(sk, req), req);
                u8 req[64];
                l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
                                        l2cap_build_conf_req(sk, req), req);
@@ -1646,7 +1651,6 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        if (flags & 0x01)
                goto done;
 
        if (flags & 0x01)
                goto done;
 
-       /* Input config done */
        l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
 
        if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
        l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
 
        if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {