diff options
author | David S. Miller <davem@davemloft.net> | 2013-10-07 15:40:44 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-10-07 15:40:44 -0400 |
commit | 7009deab19d7be03e05f67ceac56cfdfc73aa71c (patch) | |
tree | 106f789a079e606753809fad4290644a9310d62d /net/bluetooth/l2cap_core.c | |
parent | 5cde282938915f36a2e6769b51c24c4159654859 (diff) | |
parent | 274dede8c52036a1849ea970fab8d185fb0dce2b (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
Conflicts:
drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
drivers/net/wireless/rtlwifi/rtl8188ee/phy.h
drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
drivers/net/wireless/rtlwifi/rtl8192de/phy.h
drivers/net/wireless/rtlwifi/rtl8723ae/phy.h
Just some minor conflicts between the wireless-next changes
and Joe Perches's "extern" removal from function prototypes
in header files.
John W. Linville says:
====================
Regarding the Bluetooth bits, Gustavo says:
"The big work here is from Marcel and Johan. They did a lot of work
in the L2CAP, HCI and MGMT layers. The most important ones are the
addition of a new MGMT command to enable/disable LE advertisement
and the introduction of the HCI user channel to allow applications
to get directly and exclusive access to Bluetooth devices."
As to the ath10k bits, Kalle says:
"Bartosz dropped support for qca98xx hw1.0 hardware from ath10k, it's
just too much to support it. Michal added support for the new firmware
interface. Marek fixed WEP in AP and IBSS mode. Rest of the changes are
minor fixes or cleanups."
And also:
"Major changes are:
* throughput improvements including aligning the RX frames correctly and
optimising HTT layer (Michal)
* remove qca98xx hw1.0 support (Bartosz)
* add support for firmware version 999.999.0.636 (Michal)
* firmware htt statistics support (Kalle)
* fix WEP in AP and IBSS mode (Marek)
* fix a mutex unlock balance in debugfs file (Shafi)
And of course there's a lot of smaller fixes and cleanup."
For the wl12xx bits, Luca says:
"Here are some patches intended for 3.13. Eliad is upstreaming a bunch
of patches that have been pending in the internal tree. Mostly bugfixes
and other small improvements."
Along with that...
Arend and friends bring us a batch of brcmfmac updates, Larry Finger
offers some rtlwifi refactoring, and Sujith sends the usual batch of
ath9k updates. As usual, there are a number of other small updates
from a variety of players as well.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bluetooth/l2cap_core.c')
-rw-r--r-- | net/bluetooth/l2cap_core.c | 162 |
1 files changed, 94 insertions, 68 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 63fa11109a1c..02dba4e6df96 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -1016,13 +1016,12 @@ static bool __amp_capable(struct l2cap_chan *chan) | |||
1016 | { | 1016 | { |
1017 | struct l2cap_conn *conn = chan->conn; | 1017 | struct l2cap_conn *conn = chan->conn; |
1018 | 1018 | ||
1019 | if (enable_hs && | 1019 | if (conn->hs_enabled && hci_amp_capable() && |
1020 | hci_amp_capable() && | ||
1021 | chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED && | 1020 | chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED && |
1022 | conn->fixed_chan_mask & L2CAP_FC_A2MP) | 1021 | conn->fixed_chan_mask & L2CAP_FC_A2MP) |
1023 | return true; | 1022 | return true; |
1024 | else | 1023 | |
1025 | return false; | 1024 | return false; |
1026 | } | 1025 | } |
1027 | 1026 | ||
1028 | static bool l2cap_check_efs(struct l2cap_chan *chan) | 1027 | static bool l2cap_check_efs(struct l2cap_chan *chan) |
@@ -1638,6 +1637,10 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) | |||
1638 | 1637 | ||
1639 | conn->feat_mask = 0; | 1638 | conn->feat_mask = 0; |
1640 | 1639 | ||
1640 | if (hcon->type == ACL_LINK) | ||
1641 | conn->hs_enabled = test_bit(HCI_HS_ENABLED, | ||
1642 | &hcon->hdev->dev_flags); | ||
1643 | |||
1641 | spin_lock_init(&conn->lock); | 1644 | spin_lock_init(&conn->lock); |
1642 | mutex_init(&conn->chan_lock); | 1645 | mutex_init(&conn->chan_lock); |
1643 | 1646 | ||
@@ -3084,14 +3087,14 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) | |||
3084 | } | 3087 | } |
3085 | } | 3088 | } |
3086 | 3089 | ||
3087 | static inline bool __l2cap_ews_supported(struct l2cap_chan *chan) | 3090 | static inline bool __l2cap_ews_supported(struct l2cap_conn *conn) |
3088 | { | 3091 | { |
3089 | return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW; | 3092 | return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW; |
3090 | } | 3093 | } |
3091 | 3094 | ||
3092 | static inline bool __l2cap_efs_supported(struct l2cap_chan *chan) | 3095 | static inline bool __l2cap_efs_supported(struct l2cap_conn *conn) |
3093 | { | 3096 | { |
3094 | return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW; | 3097 | return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW; |
3095 | } | 3098 | } |
3096 | 3099 | ||
3097 | static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan, | 3100 | static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan, |
@@ -3135,7 +3138,7 @@ static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan, | |||
3135 | static inline void l2cap_txwin_setup(struct l2cap_chan *chan) | 3138 | static inline void l2cap_txwin_setup(struct l2cap_chan *chan) |
3136 | { | 3139 | { |
3137 | if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW && | 3140 | if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW && |
3138 | __l2cap_ews_supported(chan)) { | 3141 | __l2cap_ews_supported(chan->conn)) { |
3139 | /* use extended control field */ | 3142 | /* use extended control field */ |
3140 | set_bit(FLAG_EXT_CTRL, &chan->flags); | 3143 | set_bit(FLAG_EXT_CTRL, &chan->flags); |
3141 | chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW; | 3144 | chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW; |
@@ -3165,7 +3168,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) | |||
3165 | if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) | 3168 | if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) |
3166 | break; | 3169 | break; |
3167 | 3170 | ||
3168 | if (__l2cap_efs_supported(chan)) | 3171 | if (__l2cap_efs_supported(chan->conn)) |
3169 | set_bit(FLAG_EFS_ENABLE, &chan->flags); | 3172 | set_bit(FLAG_EFS_ENABLE, &chan->flags); |
3170 | 3173 | ||
3171 | /* fall through */ | 3174 | /* fall through */ |
@@ -3317,7 +3320,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | |||
3317 | break; | 3320 | break; |
3318 | 3321 | ||
3319 | case L2CAP_CONF_EWS: | 3322 | case L2CAP_CONF_EWS: |
3320 | if (!enable_hs) | 3323 | if (!chan->conn->hs_enabled) |
3321 | return -ECONNREFUSED; | 3324 | return -ECONNREFUSED; |
3322 | 3325 | ||
3323 | set_bit(FLAG_EXT_CTRL, &chan->flags); | 3326 | set_bit(FLAG_EXT_CTRL, &chan->flags); |
@@ -3349,7 +3352,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | |||
3349 | } | 3352 | } |
3350 | 3353 | ||
3351 | if (remote_efs) { | 3354 | if (remote_efs) { |
3352 | if (__l2cap_efs_supported(chan)) | 3355 | if (__l2cap_efs_supported(chan->conn)) |
3353 | set_bit(FLAG_EFS_ENABLE, &chan->flags); | 3356 | set_bit(FLAG_EFS_ENABLE, &chan->flags); |
3354 | else | 3357 | else |
3355 | return -ECONNREFUSED; | 3358 | return -ECONNREFUSED; |
@@ -3891,13 +3894,13 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, | |||
3891 | if (scid) { | 3894 | if (scid) { |
3892 | chan = __l2cap_get_chan_by_scid(conn, scid); | 3895 | chan = __l2cap_get_chan_by_scid(conn, scid); |
3893 | if (!chan) { | 3896 | if (!chan) { |
3894 | err = -EFAULT; | 3897 | err = -EBADSLT; |
3895 | goto unlock; | 3898 | goto unlock; |
3896 | } | 3899 | } |
3897 | } else { | 3900 | } else { |
3898 | chan = __l2cap_get_chan_by_ident(conn, cmd->ident); | 3901 | chan = __l2cap_get_chan_by_ident(conn, cmd->ident); |
3899 | if (!chan) { | 3902 | if (!chan) { |
3900 | err = -EFAULT; | 3903 | err = -EBADSLT; |
3901 | goto unlock; | 3904 | goto unlock; |
3902 | } | 3905 | } |
3903 | } | 3906 | } |
@@ -3985,7 +3988,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, | |||
3985 | 3988 | ||
3986 | chan = l2cap_get_chan_by_scid(conn, dcid); | 3989 | chan = l2cap_get_chan_by_scid(conn, dcid); |
3987 | if (!chan) | 3990 | if (!chan) |
3988 | return -ENOENT; | 3991 | return -EBADSLT; |
3989 | 3992 | ||
3990 | if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) { | 3993 | if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) { |
3991 | struct l2cap_cmd_rej_cid rej; | 3994 | struct l2cap_cmd_rej_cid rej; |
@@ -4213,7 +4216,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, | |||
4213 | chan = __l2cap_get_chan_by_scid(conn, dcid); | 4216 | chan = __l2cap_get_chan_by_scid(conn, dcid); |
4214 | if (!chan) { | 4217 | if (!chan) { |
4215 | mutex_unlock(&conn->chan_lock); | 4218 | mutex_unlock(&conn->chan_lock); |
4216 | return 0; | 4219 | return -EBADSLT; |
4217 | } | 4220 | } |
4218 | 4221 | ||
4219 | l2cap_chan_lock(chan); | 4222 | l2cap_chan_lock(chan); |
@@ -4303,7 +4306,7 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, | |||
4303 | if (!disable_ertm) | 4306 | if (!disable_ertm) |
4304 | feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING | 4307 | feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING |
4305 | | L2CAP_FEAT_FCS; | 4308 | | L2CAP_FEAT_FCS; |
4306 | if (enable_hs) | 4309 | if (conn->hs_enabled) |
4307 | feat_mask |= L2CAP_FEAT_EXT_FLOW | 4310 | feat_mask |= L2CAP_FEAT_EXT_FLOW |
4308 | | L2CAP_FEAT_EXT_WINDOW; | 4311 | | L2CAP_FEAT_EXT_WINDOW; |
4309 | 4312 | ||
@@ -4314,7 +4317,7 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, | |||
4314 | u8 buf[12]; | 4317 | u8 buf[12]; |
4315 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; | 4318 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; |
4316 | 4319 | ||
4317 | if (enable_hs) | 4320 | if (conn->hs_enabled) |
4318 | l2cap_fixed_chan[0] |= L2CAP_FC_A2MP; | 4321 | l2cap_fixed_chan[0] |= L2CAP_FC_A2MP; |
4319 | else | 4322 | else |
4320 | l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP; | 4323 | l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP; |
@@ -4411,7 +4414,7 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn, | |||
4411 | if (cmd_len != sizeof(*req)) | 4414 | if (cmd_len != sizeof(*req)) |
4412 | return -EPROTO; | 4415 | return -EPROTO; |
4413 | 4416 | ||
4414 | if (!enable_hs) | 4417 | if (!conn->hs_enabled) |
4415 | return -EINVAL; | 4418 | return -EINVAL; |
4416 | 4419 | ||
4417 | psm = le16_to_cpu(req->psm); | 4420 | psm = le16_to_cpu(req->psm); |
@@ -4445,7 +4448,7 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn, | |||
4445 | hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst); | 4448 | hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst); |
4446 | if (!hs_hcon) { | 4449 | if (!hs_hcon) { |
4447 | hci_dev_put(hdev); | 4450 | hci_dev_put(hdev); |
4448 | return -EFAULT; | 4451 | return -EBADSLT; |
4449 | } | 4452 | } |
4450 | 4453 | ||
4451 | BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon); | 4454 | BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon); |
@@ -4469,7 +4472,7 @@ error: | |||
4469 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP, | 4472 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP, |
4470 | sizeof(rsp), &rsp); | 4473 | sizeof(rsp), &rsp); |
4471 | 4474 | ||
4472 | return -EFAULT; | 4475 | return 0; |
4473 | } | 4476 | } |
4474 | 4477 | ||
4475 | static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id) | 4478 | static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id) |
@@ -4838,7 +4841,7 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn, | |||
4838 | 4841 | ||
4839 | BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id); | 4842 | BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id); |
4840 | 4843 | ||
4841 | if (!enable_hs) | 4844 | if (!conn->hs_enabled) |
4842 | return -EINVAL; | 4845 | return -EINVAL; |
4843 | 4846 | ||
4844 | chan = l2cap_get_chan_by_dcid(conn, icid); | 4847 | chan = l2cap_get_chan_by_dcid(conn, icid); |
@@ -5219,7 +5222,7 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | |||
5219 | 5222 | ||
5220 | case L2CAP_CONN_RSP: | 5223 | case L2CAP_CONN_RSP: |
5221 | case L2CAP_CREATE_CHAN_RSP: | 5224 | case L2CAP_CREATE_CHAN_RSP: |
5222 | err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data); | 5225 | l2cap_connect_create_rsp(conn, cmd, cmd_len, data); |
5223 | break; | 5226 | break; |
5224 | 5227 | ||
5225 | case L2CAP_CONF_REQ: | 5228 | case L2CAP_CONF_REQ: |
@@ -5227,7 +5230,7 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | |||
5227 | break; | 5230 | break; |
5228 | 5231 | ||
5229 | case L2CAP_CONF_RSP: | 5232 | case L2CAP_CONF_RSP: |
5230 | err = l2cap_config_rsp(conn, cmd, cmd_len, data); | 5233 | l2cap_config_rsp(conn, cmd, cmd_len, data); |
5231 | break; | 5234 | break; |
5232 | 5235 | ||
5233 | case L2CAP_DISCONN_REQ: | 5236 | case L2CAP_DISCONN_REQ: |
@@ -5235,7 +5238,7 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | |||
5235 | break; | 5238 | break; |
5236 | 5239 | ||
5237 | case L2CAP_DISCONN_RSP: | 5240 | case L2CAP_DISCONN_RSP: |
5238 | err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data); | 5241 | l2cap_disconnect_rsp(conn, cmd, cmd_len, data); |
5239 | break; | 5242 | break; |
5240 | 5243 | ||
5241 | case L2CAP_ECHO_REQ: | 5244 | case L2CAP_ECHO_REQ: |
@@ -5250,7 +5253,7 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | |||
5250 | break; | 5253 | break; |
5251 | 5254 | ||
5252 | case L2CAP_INFO_RSP: | 5255 | case L2CAP_INFO_RSP: |
5253 | err = l2cap_information_rsp(conn, cmd, cmd_len, data); | 5256 | l2cap_information_rsp(conn, cmd, cmd_len, data); |
5254 | break; | 5257 | break; |
5255 | 5258 | ||
5256 | case L2CAP_CREATE_CHAN_REQ: | 5259 | case L2CAP_CREATE_CHAN_REQ: |
@@ -5262,7 +5265,7 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | |||
5262 | break; | 5265 | break; |
5263 | 5266 | ||
5264 | case L2CAP_MOVE_CHAN_RSP: | 5267 | case L2CAP_MOVE_CHAN_RSP: |
5265 | err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data); | 5268 | l2cap_move_channel_rsp(conn, cmd, cmd_len, data); |
5266 | break; | 5269 | break; |
5267 | 5270 | ||
5268 | case L2CAP_MOVE_CHAN_CFM: | 5271 | case L2CAP_MOVE_CHAN_CFM: |
@@ -5270,7 +5273,7 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | |||
5270 | break; | 5273 | break; |
5271 | 5274 | ||
5272 | case L2CAP_MOVE_CHAN_CFM_RSP: | 5275 | case L2CAP_MOVE_CHAN_CFM_RSP: |
5273 | err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data); | 5276 | l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data); |
5274 | break; | 5277 | break; |
5275 | 5278 | ||
5276 | default: | 5279 | default: |
@@ -5301,54 +5304,65 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn, | |||
5301 | } | 5304 | } |
5302 | } | 5305 | } |
5303 | 5306 | ||
5307 | static __le16 l2cap_err_to_reason(int err) | ||
5308 | { | ||
5309 | switch (err) { | ||
5310 | case -EBADSLT: | ||
5311 | return __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID); | ||
5312 | case -EMSGSIZE: | ||
5313 | return __constant_cpu_to_le16(L2CAP_REJ_MTU_EXCEEDED); | ||
5314 | case -EINVAL: | ||
5315 | case -EPROTO: | ||
5316 | default: | ||
5317 | return __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); | ||
5318 | } | ||
5319 | } | ||
5320 | |||
5304 | static inline void l2cap_le_sig_channel(struct l2cap_conn *conn, | 5321 | static inline void l2cap_le_sig_channel(struct l2cap_conn *conn, |
5305 | struct sk_buff *skb) | 5322 | struct sk_buff *skb) |
5306 | { | 5323 | { |
5307 | u8 *data = skb->data; | 5324 | struct hci_conn *hcon = conn->hcon; |
5308 | int len = skb->len; | 5325 | struct l2cap_cmd_hdr *cmd; |
5309 | struct l2cap_cmd_hdr cmd; | 5326 | u16 len; |
5310 | int err; | 5327 | int err; |
5311 | 5328 | ||
5312 | l2cap_raw_recv(conn, skb); | 5329 | if (hcon->type != LE_LINK) |
5330 | goto drop; | ||
5313 | 5331 | ||
5314 | while (len >= L2CAP_CMD_HDR_SIZE) { | 5332 | if (skb->len < L2CAP_CMD_HDR_SIZE) |
5315 | u16 cmd_len; | 5333 | goto drop; |
5316 | memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE); | ||
5317 | data += L2CAP_CMD_HDR_SIZE; | ||
5318 | len -= L2CAP_CMD_HDR_SIZE; | ||
5319 | 5334 | ||
5320 | cmd_len = le16_to_cpu(cmd.len); | 5335 | cmd = (void *) skb->data; |
5336 | skb_pull(skb, L2CAP_CMD_HDR_SIZE); | ||
5321 | 5337 | ||
5322 | BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, | 5338 | len = le16_to_cpu(cmd->len); |
5323 | cmd.ident); | ||
5324 | 5339 | ||
5325 | if (cmd_len > len || !cmd.ident) { | 5340 | BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident); |
5326 | BT_DBG("corrupted command"); | ||
5327 | break; | ||
5328 | } | ||
5329 | 5341 | ||
5330 | err = l2cap_le_sig_cmd(conn, &cmd, data); | 5342 | if (len != skb->len || !cmd->ident) { |
5331 | if (err) { | 5343 | BT_DBG("corrupted command"); |
5332 | struct l2cap_cmd_rej_unk rej; | 5344 | goto drop; |
5345 | } | ||
5333 | 5346 | ||
5334 | BT_ERR("Wrong link type (%d)", err); | 5347 | err = l2cap_le_sig_cmd(conn, cmd, skb->data); |
5348 | if (err) { | ||
5349 | struct l2cap_cmd_rej_unk rej; | ||
5335 | 5350 | ||
5336 | /* FIXME: Map err to a valid reason */ | 5351 | BT_ERR("Wrong link type (%d)", err); |
5337 | rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); | ||
5338 | l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, | ||
5339 | sizeof(rej), &rej); | ||
5340 | } | ||
5341 | 5352 | ||
5342 | data += cmd_len; | 5353 | rej.reason = l2cap_err_to_reason(err); |
5343 | len -= cmd_len; | 5354 | l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, |
5355 | sizeof(rej), &rej); | ||
5344 | } | 5356 | } |
5345 | 5357 | ||
5358 | drop: | ||
5346 | kfree_skb(skb); | 5359 | kfree_skb(skb); |
5347 | } | 5360 | } |
5348 | 5361 | ||
5349 | static inline void l2cap_sig_channel(struct l2cap_conn *conn, | 5362 | static inline void l2cap_sig_channel(struct l2cap_conn *conn, |
5350 | struct sk_buff *skb) | 5363 | struct sk_buff *skb) |
5351 | { | 5364 | { |
5365 | struct hci_conn *hcon = conn->hcon; | ||
5352 | u8 *data = skb->data; | 5366 | u8 *data = skb->data; |
5353 | int len = skb->len; | 5367 | int len = skb->len; |
5354 | struct l2cap_cmd_hdr cmd; | 5368 | struct l2cap_cmd_hdr cmd; |
@@ -5356,6 +5370,9 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, | |||
5356 | 5370 | ||
5357 | l2cap_raw_recv(conn, skb); | 5371 | l2cap_raw_recv(conn, skb); |
5358 | 5372 | ||
5373 | if (hcon->type != ACL_LINK) | ||
5374 | goto drop; | ||
5375 | |||
5359 | while (len >= L2CAP_CMD_HDR_SIZE) { | 5376 | while (len >= L2CAP_CMD_HDR_SIZE) { |
5360 | u16 cmd_len; | 5377 | u16 cmd_len; |
5361 | memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE); | 5378 | memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE); |
@@ -5378,8 +5395,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, | |||
5378 | 5395 | ||
5379 | BT_ERR("Wrong link type (%d)", err); | 5396 | BT_ERR("Wrong link type (%d)", err); |
5380 | 5397 | ||
5381 | /* FIXME: Map err to a valid reason */ | 5398 | rej.reason = l2cap_err_to_reason(err); |
5382 | rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); | ||
5383 | l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, | 5399 | l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, |
5384 | sizeof(rej), &rej); | 5400 | sizeof(rej), &rej); |
5385 | } | 5401 | } |
@@ -5388,6 +5404,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, | |||
5388 | len -= cmd_len; | 5404 | len -= cmd_len; |
5389 | } | 5405 | } |
5390 | 5406 | ||
5407 | drop: | ||
5391 | kfree_skb(skb); | 5408 | kfree_skb(skb); |
5392 | } | 5409 | } |
5393 | 5410 | ||
@@ -5784,7 +5801,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, | |||
5784 | struct sk_buff *skb, u8 event) | 5801 | struct sk_buff *skb, u8 event) |
5785 | { | 5802 | { |
5786 | int err = 0; | 5803 | int err = 0; |
5787 | bool skb_in_use = 0; | 5804 | bool skb_in_use = false; |
5788 | 5805 | ||
5789 | BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, | 5806 | BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, |
5790 | event); | 5807 | event); |
@@ -5805,7 +5822,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, | |||
5805 | control->txseq); | 5822 | control->txseq); |
5806 | 5823 | ||
5807 | chan->buffer_seq = chan->expected_tx_seq; | 5824 | chan->buffer_seq = chan->expected_tx_seq; |
5808 | skb_in_use = 1; | 5825 | skb_in_use = true; |
5809 | 5826 | ||
5810 | err = l2cap_reassemble_sdu(chan, skb, control); | 5827 | err = l2cap_reassemble_sdu(chan, skb, control); |
5811 | if (err) | 5828 | if (err) |
@@ -5841,7 +5858,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, | |||
5841 | * current frame is stored for later use. | 5858 | * current frame is stored for later use. |
5842 | */ | 5859 | */ |
5843 | skb_queue_tail(&chan->srej_q, skb); | 5860 | skb_queue_tail(&chan->srej_q, skb); |
5844 | skb_in_use = 1; | 5861 | skb_in_use = true; |
5845 | BT_DBG("Queued %p (queue len %d)", skb, | 5862 | BT_DBG("Queued %p (queue len %d)", skb, |
5846 | skb_queue_len(&chan->srej_q)); | 5863 | skb_queue_len(&chan->srej_q)); |
5847 | 5864 | ||
@@ -5919,7 +5936,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, | |||
5919 | { | 5936 | { |
5920 | int err = 0; | 5937 | int err = 0; |
5921 | u16 txseq = control->txseq; | 5938 | u16 txseq = control->txseq; |
5922 | bool skb_in_use = 0; | 5939 | bool skb_in_use = false; |
5923 | 5940 | ||
5924 | BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, | 5941 | BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, |
5925 | event); | 5942 | event); |
@@ -5931,7 +5948,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, | |||
5931 | /* Keep frame for reassembly later */ | 5948 | /* Keep frame for reassembly later */ |
5932 | l2cap_pass_to_tx(chan, control); | 5949 | l2cap_pass_to_tx(chan, control); |
5933 | skb_queue_tail(&chan->srej_q, skb); | 5950 | skb_queue_tail(&chan->srej_q, skb); |
5934 | skb_in_use = 1; | 5951 | skb_in_use = true; |
5935 | BT_DBG("Queued %p (queue len %d)", skb, | 5952 | BT_DBG("Queued %p (queue len %d)", skb, |
5936 | skb_queue_len(&chan->srej_q)); | 5953 | skb_queue_len(&chan->srej_q)); |
5937 | 5954 | ||
@@ -5942,7 +5959,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, | |||
5942 | 5959 | ||
5943 | l2cap_pass_to_tx(chan, control); | 5960 | l2cap_pass_to_tx(chan, control); |
5944 | skb_queue_tail(&chan->srej_q, skb); | 5961 | skb_queue_tail(&chan->srej_q, skb); |
5945 | skb_in_use = 1; | 5962 | skb_in_use = true; |
5946 | BT_DBG("Queued %p (queue len %d)", skb, | 5963 | BT_DBG("Queued %p (queue len %d)", skb, |
5947 | skb_queue_len(&chan->srej_q)); | 5964 | skb_queue_len(&chan->srej_q)); |
5948 | 5965 | ||
@@ -5957,7 +5974,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, | |||
5957 | * the missing frames. | 5974 | * the missing frames. |
5958 | */ | 5975 | */ |
5959 | skb_queue_tail(&chan->srej_q, skb); | 5976 | skb_queue_tail(&chan->srej_q, skb); |
5960 | skb_in_use = 1; | 5977 | skb_in_use = true; |
5961 | BT_DBG("Queued %p (queue len %d)", skb, | 5978 | BT_DBG("Queued %p (queue len %d)", skb, |
5962 | skb_queue_len(&chan->srej_q)); | 5979 | skb_queue_len(&chan->srej_q)); |
5963 | 5980 | ||
@@ -5971,7 +5988,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, | |||
5971 | * SREJ'd frames. | 5988 | * SREJ'd frames. |
5972 | */ | 5989 | */ |
5973 | skb_queue_tail(&chan->srej_q, skb); | 5990 | skb_queue_tail(&chan->srej_q, skb); |
5974 | skb_in_use = 1; | 5991 | skb_in_use = true; |
5975 | BT_DBG("Queued %p (queue len %d)", skb, | 5992 | BT_DBG("Queued %p (queue len %d)", skb, |
5976 | skb_queue_len(&chan->srej_q)); | 5993 | skb_queue_len(&chan->srej_q)); |
5977 | 5994 | ||
@@ -6380,8 +6397,12 @@ done: | |||
6380 | static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, | 6397 | static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, |
6381 | struct sk_buff *skb) | 6398 | struct sk_buff *skb) |
6382 | { | 6399 | { |
6400 | struct hci_conn *hcon = conn->hcon; | ||
6383 | struct l2cap_chan *chan; | 6401 | struct l2cap_chan *chan; |
6384 | 6402 | ||
6403 | if (hcon->type != ACL_LINK) | ||
6404 | goto drop; | ||
6405 | |||
6385 | chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst); | 6406 | chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst); |
6386 | if (!chan) | 6407 | if (!chan) |
6387 | goto drop; | 6408 | goto drop; |
@@ -6404,8 +6425,12 @@ drop: | |||
6404 | static void l2cap_att_channel(struct l2cap_conn *conn, | 6425 | static void l2cap_att_channel(struct l2cap_conn *conn, |
6405 | struct sk_buff *skb) | 6426 | struct sk_buff *skb) |
6406 | { | 6427 | { |
6428 | struct hci_conn *hcon = conn->hcon; | ||
6407 | struct l2cap_chan *chan; | 6429 | struct l2cap_chan *chan; |
6408 | 6430 | ||
6431 | if (hcon->type != LE_LINK) | ||
6432 | goto drop; | ||
6433 | |||
6409 | chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT, | 6434 | chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT, |
6410 | conn->src, conn->dst); | 6435 | conn->src, conn->dst); |
6411 | if (!chan) | 6436 | if (!chan) |
@@ -6441,9 +6466,6 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | |||
6441 | BT_DBG("len %d, cid 0x%4.4x", len, cid); | 6466 | BT_DBG("len %d, cid 0x%4.4x", len, cid); |
6442 | 6467 | ||
6443 | switch (cid) { | 6468 | switch (cid) { |
6444 | case L2CAP_CID_LE_SIGNALING: | ||
6445 | l2cap_le_sig_channel(conn, skb); | ||
6446 | break; | ||
6447 | case L2CAP_CID_SIGNALING: | 6469 | case L2CAP_CID_SIGNALING: |
6448 | l2cap_sig_channel(conn, skb); | 6470 | l2cap_sig_channel(conn, skb); |
6449 | break; | 6471 | break; |
@@ -6458,6 +6480,10 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | |||
6458 | l2cap_att_channel(conn, skb); | 6480 | l2cap_att_channel(conn, skb); |
6459 | break; | 6481 | break; |
6460 | 6482 | ||
6483 | case L2CAP_CID_LE_SIGNALING: | ||
6484 | l2cap_le_sig_channel(conn, skb); | ||
6485 | break; | ||
6486 | |||
6461 | case L2CAP_CID_SMP: | 6487 | case L2CAP_CID_SMP: |
6462 | if (smp_sig_channel(conn, skb)) | 6488 | if (smp_sig_channel(conn, skb)) |
6463 | l2cap_conn_del(conn->hcon, EACCES); | 6489 | l2cap_conn_del(conn->hcon, EACCES); |