aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/l2cap.h20
-rw-r--r--net/bluetooth/l2cap.c43
2 files changed, 50 insertions, 13 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 17a689f27a6a..d9c20c3d6f3d 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -320,7 +320,7 @@ struct l2cap_pinfo {
320 __u8 conf_req[64]; 320 __u8 conf_req[64];
321 __u8 conf_len; 321 __u8 conf_len;
322 __u8 conf_state; 322 __u8 conf_state;
323 __u8 conn_state; 323 __u16 conn_state;
324 324
325 __u8 next_tx_seq; 325 __u8 next_tx_seq;
326 __u8 expected_ack_seq; 326 __u8 expected_ack_seq;
@@ -328,6 +328,7 @@ struct l2cap_pinfo {
328 __u8 buffer_seq; 328 __u8 buffer_seq;
329 __u8 buffer_seq_srej; 329 __u8 buffer_seq_srej;
330 __u8 srej_save_reqseq; 330 __u8 srej_save_reqseq;
331 __u8 frames_sent;
331 __u8 unacked_frames; 332 __u8 unacked_frames;
332 __u8 retry_count; 333 __u8 retry_count;
333 __u8 num_to_ack; 334 __u8 num_to_ack;
@@ -367,14 +368,15 @@ struct l2cap_pinfo {
367#define L2CAP_CONF_MAX_CONF_REQ 2 368#define L2CAP_CONF_MAX_CONF_REQ 2
368#define L2CAP_CONF_MAX_CONF_RSP 2 369#define L2CAP_CONF_MAX_CONF_RSP 2
369 370
370#define L2CAP_CONN_SAR_SDU 0x01 371#define L2CAP_CONN_SAR_SDU 0x0001
371#define L2CAP_CONN_SREJ_SENT 0x02 372#define L2CAP_CONN_SREJ_SENT 0x0002
372#define L2CAP_CONN_WAIT_F 0x04 373#define L2CAP_CONN_WAIT_F 0x0004
373#define L2CAP_CONN_SREJ_ACT 0x08 374#define L2CAP_CONN_SREJ_ACT 0x0008
374#define L2CAP_CONN_SEND_PBIT 0x10 375#define L2CAP_CONN_SEND_PBIT 0x0010
375#define L2CAP_CONN_REMOTE_BUSY 0x20 376#define L2CAP_CONN_REMOTE_BUSY 0x0020
376#define L2CAP_CONN_LOCAL_BUSY 0x40 377#define L2CAP_CONN_LOCAL_BUSY 0x0040
377#define L2CAP_CONN_REJ_ACT 0x80 378#define L2CAP_CONN_REJ_ACT 0x0080
379#define L2CAP_CONN_SEND_FBIT 0x0100
378 380
379#define __mod_retrans_timer() mod_timer(&l2cap_pi(sk)->retrans_timer, \ 381#define __mod_retrans_timer() mod_timer(&l2cap_pi(sk)->retrans_timer, \
380 jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO)); 382 jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index a9c152a09f0b..06687e264703 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1383,6 +1383,10 @@ static int l2cap_ertm_send(struct sock *sk)
1383 bt_cb(skb)->retries++; 1383 bt_cb(skb)->retries++;
1384 1384
1385 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); 1385 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1386 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
1387 control |= L2CAP_CTRL_FINAL;
1388 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
1389 }
1386 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) 1390 control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1387 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); 1391 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1388 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); 1392 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
@@ -1404,6 +1408,7 @@ static int l2cap_ertm_send(struct sock *sk)
1404 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; 1408 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
1405 1409
1406 pi->unacked_frames++; 1410 pi->unacked_frames++;
1411 pi->frames_sent++;
1407 1412
1408 if (skb_queue_is_last(TX_QUEUE(sk), skb)) 1413 if (skb_queue_is_last(TX_QUEUE(sk), skb))
1409 sk->sk_send_head = NULL; 1414 sk->sk_send_head = NULL;
@@ -2191,6 +2196,7 @@ static inline void l2cap_ertm_init(struct sock *sk)
2191 l2cap_pi(sk)->unacked_frames = 0; 2196 l2cap_pi(sk)->unacked_frames = 0;
2192 l2cap_pi(sk)->buffer_seq = 0; 2197 l2cap_pi(sk)->buffer_seq = 0;
2193 l2cap_pi(sk)->num_to_ack = 0; 2198 l2cap_pi(sk)->num_to_ack = 0;
2199 l2cap_pi(sk)->frames_sent = 0;
2194 2200
2195 setup_timer(&l2cap_pi(sk)->retrans_timer, 2201 setup_timer(&l2cap_pi(sk)->retrans_timer,
2196 l2cap_retrans_timeout, (unsigned long) sk); 2202 l2cap_retrans_timeout, (unsigned long) sk);
@@ -3148,6 +3154,38 @@ static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
3148 return 0; 3154 return 0;
3149} 3155}
3150 3156
3157static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
3158{
3159 struct l2cap_pinfo *pi = l2cap_pi(sk);
3160 u16 control = 0;
3161
3162 pi->frames_sent = 0;
3163 pi->conn_state |= L2CAP_CONN_SEND_FBIT;
3164
3165 control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3166
3167 if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
3168 control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
3169 l2cap_send_sframe(pi, control);
3170 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3171 }
3172
3173 if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
3174 __mod_retrans_timer();
3175
3176 l2cap_ertm_send(sk);
3177
3178 if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
3179 pi->frames_sent == 0) {
3180 control |= L2CAP_SUPER_RCV_READY;
3181 if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
3182 control |= L2CAP_CTRL_FINAL;
3183 pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
3184 }
3185 l2cap_send_sframe(pi, control);
3186 }
3187}
3188
3151static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar) 3189static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
3152{ 3190{
3153 struct sk_buff *next_skb; 3191 struct sk_buff *next_skb;
@@ -3418,10 +3456,7 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str
3418 switch (rx_control & L2CAP_CTRL_SUPERVISE) { 3456 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3419 case L2CAP_SUPER_RCV_READY: 3457 case L2CAP_SUPER_RCV_READY:
3420 if (rx_control & L2CAP_CTRL_POLL) { 3458 if (rx_control & L2CAP_CTRL_POLL) {
3421 u16 control = L2CAP_CTRL_FINAL; 3459 l2cap_send_i_or_rr_or_rnr(sk);
3422 control |= L2CAP_SUPER_RCV_READY |
3423 (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT);
3424 l2cap_send_sframe(l2cap_pi(sk), control);
3425 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; 3460 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3426 3461
3427 } else if (rx_control & L2CAP_CTRL_FINAL) { 3462 } else if (rx_control & L2CAP_CTRL_FINAL) {