diff options
author | Ilia Kolomisnky <iliak@ti.com> | 2011-07-10 01:47:44 -0400 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-07-11 00:43:25 -0400 |
commit | e2fd318e3a9208245ee1041f6d413c8593fba29d (patch) | |
tree | 09eb380881b2c82922f69cdf5dced58143e6695e | |
parent | 8f360119243c214eb5c5549c61981d51a276154a (diff) |
Bluetooth: Fixes l2cap "command reject" reply according to spec
There can 3 reasons for the "command reject" reply produced
by the stack. Each such reply should be accompanied by the
relevand data ( as defined in spec. ). Currently there is one
instance of "command reject" reply with reason "invalid cid"
wich is fixed. Also, added clean-up definitions related to the
"command reject" replies.
Signed-off-by: Ilia Kolomisnky <iliak@ti.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r-- | include/net/bluetooth/l2cap.h | 19 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 15 |
2 files changed, 27 insertions, 7 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 578545a2a492..4f34ad25e75c 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -129,6 +129,12 @@ struct l2cap_conninfo { | |||
129 | #define L2CAP_SDU_END 0x8000 | 129 | #define L2CAP_SDU_END 0x8000 |
130 | #define L2CAP_SDU_CONTINUE 0xC000 | 130 | #define L2CAP_SDU_CONTINUE 0xC000 |
131 | 131 | ||
132 | /* L2CAP Command rej. reasons */ | ||
133 | #define L2CAP_REJ_NOT_UNDERSTOOD 0x0000 | ||
134 | #define L2CAP_REJ_MTU_EXCEEDED 0x0001 | ||
135 | #define L2CAP_REJ_INVALID_CID 0x0002 | ||
136 | |||
137 | |||
132 | /* L2CAP structures */ | 138 | /* L2CAP structures */ |
133 | struct l2cap_hdr { | 139 | struct l2cap_hdr { |
134 | __le16 len; | 140 | __le16 len; |
@@ -143,8 +149,19 @@ struct l2cap_cmd_hdr { | |||
143 | } __packed; | 149 | } __packed; |
144 | #define L2CAP_CMD_HDR_SIZE 4 | 150 | #define L2CAP_CMD_HDR_SIZE 4 |
145 | 151 | ||
146 | struct l2cap_cmd_rej { | 152 | struct l2cap_cmd_rej_unk { |
153 | __le16 reason; | ||
154 | } __packed; | ||
155 | |||
156 | struct l2cap_cmd_rej_mtu { | ||
147 | __le16 reason; | 157 | __le16 reason; |
158 | __le16 max_mtu; | ||
159 | } __packed; | ||
160 | |||
161 | struct l2cap_cmd_rej_cid { | ||
162 | __le16 reason; | ||
163 | __le16 scid; | ||
164 | __le16 dcid; | ||
148 | } __packed; | 165 | } __packed; |
149 | 166 | ||
150 | struct l2cap_conn_req { | 167 | struct l2cap_conn_req { |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index ab2e244a76c4..52c791ed038d 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -2277,9 +2277,9 @@ done: | |||
2277 | 2277 | ||
2278 | static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) | 2278 | static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) |
2279 | { | 2279 | { |
2280 | struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data; | 2280 | struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data; |
2281 | 2281 | ||
2282 | if (rej->reason != 0x0000) | 2282 | if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD) |
2283 | return 0; | 2283 | return 0; |
2284 | 2284 | ||
2285 | if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) && | 2285 | if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) && |
@@ -2524,9 +2524,12 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2524 | sk = chan->sk; | 2524 | sk = chan->sk; |
2525 | 2525 | ||
2526 | if (chan->state != BT_CONFIG) { | 2526 | if (chan->state != BT_CONFIG) { |
2527 | struct l2cap_cmd_rej rej; | 2527 | struct l2cap_cmd_rej_cid rej; |
2528 | |||
2529 | rej.reason = cpu_to_le16(L2CAP_REJ_INVALID_CID); | ||
2530 | rej.scid = cpu_to_le16(chan->scid); | ||
2531 | rej.dcid = cpu_to_le16(chan->dcid); | ||
2528 | 2532 | ||
2529 | rej.reason = cpu_to_le16(0x0002); | ||
2530 | l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, | 2533 | l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, |
2531 | sizeof(rej), &rej); | 2534 | sizeof(rej), &rej); |
2532 | goto unlock; | 2535 | goto unlock; |
@@ -3017,12 +3020,12 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, | |||
3017 | err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data); | 3020 | err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data); |
3018 | 3021 | ||
3019 | if (err) { | 3022 | if (err) { |
3020 | struct l2cap_cmd_rej rej; | 3023 | struct l2cap_cmd_rej_unk rej; |
3021 | 3024 | ||
3022 | BT_ERR("Wrong link type (%d)", err); | 3025 | BT_ERR("Wrong link type (%d)", err); |
3023 | 3026 | ||
3024 | /* FIXME: Map err to a valid reason */ | 3027 | /* FIXME: Map err to a valid reason */ |
3025 | rej.reason = cpu_to_le16(0); | 3028 | rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); |
3026 | l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); | 3029 | l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); |
3027 | } | 3030 | } |
3028 | 3031 | ||