aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/l2cap.c')
-rw-r--r--net/bluetooth/l2cap.c59
1 files changed, 37 insertions, 22 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 4af8fc0d512c..4415eb48c6ae 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -272,6 +272,24 @@ static void l2cap_chan_del(struct sock *sk, int err)
272 parent->sk_data_ready(parent, 0); 272 parent->sk_data_ready(parent, 0);
273 } else 273 } else
274 sk->sk_state_change(sk); 274 sk->sk_state_change(sk);
275
276 skb_queue_purge(TX_QUEUE(sk));
277
278 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
279 struct srej_list *l, *tmp;
280
281 del_timer(&l2cap_pi(sk)->retrans_timer);
282 del_timer(&l2cap_pi(sk)->monitor_timer);
283 del_timer(&l2cap_pi(sk)->ack_timer);
284
285 skb_queue_purge(SREJ_QUEUE(sk));
286 skb_queue_purge(BUSY_QUEUE(sk));
287
288 list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) {
289 list_del(&l->list);
290 kfree(l);
291 }
292 }
275} 293}
276 294
277/* Service level security */ 295/* Service level security */
@@ -345,8 +363,12 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
345 struct sk_buff *skb; 363 struct sk_buff *skb;
346 struct l2cap_hdr *lh; 364 struct l2cap_hdr *lh;
347 struct l2cap_conn *conn = pi->conn; 365 struct l2cap_conn *conn = pi->conn;
366 struct sock *sk = (struct sock *)pi;
348 int count, hlen = L2CAP_HDR_SIZE + 2; 367 int count, hlen = L2CAP_HDR_SIZE + 2;
349 368
369 if (sk->sk_state != BT_CONNECTED)
370 return;
371
350 if (pi->fcs == L2CAP_FCS_CRC16) 372 if (pi->fcs == L2CAP_FCS_CRC16)
351 hlen += 2; 373 hlen += 2;
352 374
@@ -438,10 +460,23 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
438{ 460{
439 struct l2cap_disconn_req req; 461 struct l2cap_disconn_req req;
440 462
463 if (!conn)
464 return;
465
466 skb_queue_purge(TX_QUEUE(sk));
467
468 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
469 del_timer(&l2cap_pi(sk)->retrans_timer);
470 del_timer(&l2cap_pi(sk)->monitor_timer);
471 del_timer(&l2cap_pi(sk)->ack_timer);
472 }
473
441 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid); 474 req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
442 req.scid = cpu_to_le16(l2cap_pi(sk)->scid); 475 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
443 l2cap_send_cmd(conn, l2cap_get_ident(conn), 476 l2cap_send_cmd(conn, l2cap_get_ident(conn),
444 L2CAP_DISCONN_REQ, sizeof(req), &req); 477 L2CAP_DISCONN_REQ, sizeof(req), &req);
478
479 sk->sk_state = BT_DISCONN;
445} 480}
446 481
447/* ---- L2CAP connections ---- */ 482/* ---- L2CAP connections ---- */
@@ -734,7 +769,6 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
734 sk->sk_type == SOCK_STREAM) { 769 sk->sk_type == SOCK_STREAM) {
735 struct l2cap_conn *conn = l2cap_pi(sk)->conn; 770 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
736 771
737 sk->sk_state = BT_DISCONN;
738 l2cap_sock_set_timer(sk, sk->sk_sndtimeo); 772 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
739 l2cap_send_disconn_req(conn, sk); 773 l2cap_send_disconn_req(conn, sk);
740 } else 774 } else
@@ -1415,6 +1449,8 @@ static int l2cap_ertm_send(struct sock *sk)
1415 u16 control, fcs; 1449 u16 control, fcs;
1416 int nsent = 0; 1450 int nsent = 0;
1417 1451
1452 if (sk->sk_state != BT_CONNECTED)
1453 return -ENOTCONN;
1418 1454
1419 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) { 1455 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
1420 1456
@@ -3072,7 +3108,6 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
3072 } 3108 }
3073 3109
3074 default: 3110 default:
3075 sk->sk_state = BT_DISCONN;
3076 sk->sk_err = ECONNRESET; 3111 sk->sk_err = ECONNRESET;
3077 l2cap_sock_set_timer(sk, HZ * 5); 3112 l2cap_sock_set_timer(sk, HZ * 5);
3078 l2cap_send_disconn_req(conn, sk); 3113 l2cap_send_disconn_req(conn, sk);
@@ -3126,16 +3161,6 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
3126 3161
3127 sk->sk_shutdown = SHUTDOWN_MASK; 3162 sk->sk_shutdown = SHUTDOWN_MASK;
3128 3163
3129 skb_queue_purge(TX_QUEUE(sk));
3130
3131 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3132 skb_queue_purge(SREJ_QUEUE(sk));
3133 skb_queue_purge(BUSY_QUEUE(sk));
3134 del_timer(&l2cap_pi(sk)->retrans_timer);
3135 del_timer(&l2cap_pi(sk)->monitor_timer);
3136 del_timer(&l2cap_pi(sk)->ack_timer);
3137 }
3138
3139 l2cap_chan_del(sk, ECONNRESET); 3164 l2cap_chan_del(sk, ECONNRESET);
3140 bh_unlock_sock(sk); 3165 bh_unlock_sock(sk);
3141 3166
@@ -3158,16 +3183,6 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
3158 if (!sk) 3183 if (!sk)
3159 return 0; 3184 return 0;
3160 3185
3161 skb_queue_purge(TX_QUEUE(sk));
3162
3163 if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) {
3164 skb_queue_purge(SREJ_QUEUE(sk));
3165 skb_queue_purge(BUSY_QUEUE(sk));
3166 del_timer(&l2cap_pi(sk)->retrans_timer);
3167 del_timer(&l2cap_pi(sk)->monitor_timer);
3168 del_timer(&l2cap_pi(sk)->ack_timer);
3169 }
3170
3171 l2cap_chan_del(sk, 0); 3186 l2cap_chan_del(sk, 0);
3172 bh_unlock_sock(sk); 3187 bh_unlock_sock(sk);
3173 3188