aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2013-12-10 03:52:48 -0500
committerMarcel Holtmann <marcel@holtmann.org>2013-12-10 04:15:44 -0500
commit71fb419724fadab4efdf98210aa3fe053bd81d29 (patch)
treebea18a28f16b8e66904ab4a1b1108c00e7f2044c
parent53b834d2333aec1e60fcbfadfddd4ad472329570 (diff)
Bluetooth: Fix handling of L2CAP Command Reject over LE
If we receive an L2CAP command reject message over LE we should take appropriate action on the corresponding channel. This is particularly important when trying to interact with a remote pre-4.1 system using LE CoC signaling messages. If we don't react to the command reject the corresponding socket would not be notified until a connection timeout occurs. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--net/bluetooth/l2cap_core.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index ae0054ccee5b..b6bca64b320d 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -5736,6 +5736,31 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn,
5736 return 0; 5736 return 0;
5737} 5737}
5738 5738
5739static inline int l2cap_le_command_rej(struct l2cap_conn *conn,
5740 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5741 u8 *data)
5742{
5743 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
5744 struct l2cap_chan *chan;
5745
5746 if (cmd_len < sizeof(*rej))
5747 return -EPROTO;
5748
5749 mutex_lock(&conn->chan_lock);
5750
5751 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
5752 if (!chan)
5753 goto done;
5754
5755 l2cap_chan_lock(chan);
5756 l2cap_chan_del(chan, ECONNREFUSED);
5757 l2cap_chan_unlock(chan);
5758
5759done:
5760 mutex_unlock(&conn->chan_lock);
5761 return 0;
5762}
5763
5739static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn, 5764static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
5740 struct l2cap_cmd_hdr *cmd, u16 cmd_len, 5765 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5741 u8 *data) 5766 u8 *data)
@@ -5755,6 +5780,7 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
5755 5780
5756 switch (cmd->code) { 5781 switch (cmd->code) {
5757 case L2CAP_COMMAND_REJ: 5782 case L2CAP_COMMAND_REJ:
5783 l2cap_le_command_rej(conn, cmd, cmd_len, data);
5758 break; 5784 break;
5759 5785
5760 case L2CAP_CONN_PARAM_UPDATE_REQ: 5786 case L2CAP_CONN_PARAM_UPDATE_REQ: