aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap.c
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2010-05-01 15:15:39 -0400
committerMarcel Holtmann <marcel@holtmann.org>2010-05-10 03:28:48 -0400
commitc1b4f43be01c2a363be021485dd18cca33cfab8a (patch)
tree3244f14f00eb6a227e52b2a8ddd7063ef0961840 /net/bluetooth/l2cap.c
parent05fbd89dd4153341717b33d9e8ae8bd29db6c1c8 (diff)
Bluetooth: Add timer to Acknowledge I-frames
We ack I-frames on each txWindow/5 I-frames received, but if the sender stop to send I-frames and it's not a txWindow multiple we can leave some frames unacked. So I added a timer to ack I-frames on this case. The timer expires in 200ms. Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi> Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/l2cap.c')
-rw-r--r--net/bluetooth/l2cap.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index f3869857ee9f..03006568f8a1 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2235,6 +2235,15 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2235 *ptr += L2CAP_CONF_OPT_SIZE + len; 2235 *ptr += L2CAP_CONF_OPT_SIZE + len;
2236} 2236}
2237 2237
2238static void l2cap_ack_timeout(unsigned long arg)
2239{
2240 struct sock *sk = (void *) arg;
2241
2242 bh_lock_sock(sk);
2243 l2cap_send_ack(l2cap_pi(sk));
2244 bh_unlock_sock(sk);
2245}
2246
2238static inline void l2cap_ertm_init(struct sock *sk) 2247static inline void l2cap_ertm_init(struct sock *sk)
2239{ 2248{
2240 l2cap_pi(sk)->expected_ack_seq = 0; 2249 l2cap_pi(sk)->expected_ack_seq = 0;
@@ -2247,6 +2256,8 @@ static inline void l2cap_ertm_init(struct sock *sk)
2247 l2cap_retrans_timeout, (unsigned long) sk); 2256 l2cap_retrans_timeout, (unsigned long) sk);
2248 setup_timer(&l2cap_pi(sk)->monitor_timer, 2257 setup_timer(&l2cap_pi(sk)->monitor_timer,
2249 l2cap_monitor_timeout, (unsigned long) sk); 2258 l2cap_monitor_timeout, (unsigned long) sk);
2259 setup_timer(&l2cap_pi(sk)->ack_timer,
2260 l2cap_ack_timeout, (unsigned long) sk);
2250 2261
2251 __skb_queue_head_init(SREJ_QUEUE(sk)); 2262 __skb_queue_head_init(SREJ_QUEUE(sk));
2252} 2263}
@@ -2975,6 +2986,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
2975 skb_queue_purge(SREJ_QUEUE(sk)); 2986 skb_queue_purge(SREJ_QUEUE(sk));
2976 del_timer(&l2cap_pi(sk)->retrans_timer); 2987 del_timer(&l2cap_pi(sk)->retrans_timer);
2977 del_timer(&l2cap_pi(sk)->monitor_timer); 2988 del_timer(&l2cap_pi(sk)->monitor_timer);
2989 del_timer(&l2cap_pi(sk)->ack_timer);
2978 } 2990 }
2979 2991
2980 l2cap_chan_del(sk, ECONNRESET); 2992 l2cap_chan_del(sk, ECONNRESET);
@@ -3005,6 +3017,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
3005 skb_queue_purge(SREJ_QUEUE(sk)); 3017 skb_queue_purge(SREJ_QUEUE(sk));
3006 del_timer(&l2cap_pi(sk)->retrans_timer); 3018 del_timer(&l2cap_pi(sk)->retrans_timer);
3007 del_timer(&l2cap_pi(sk)->monitor_timer); 3019 del_timer(&l2cap_pi(sk)->monitor_timer);
3020 del_timer(&l2cap_pi(sk)->ack_timer);
3008 } 3021 }
3009 3022
3010 l2cap_chan_del(sk, 0); 3023 l2cap_chan_del(sk, 0);
@@ -3484,6 +3497,8 @@ expected:
3484 if (err < 0) 3497 if (err < 0)
3485 return err; 3498 return err;
3486 3499
3500 __mod_ack_timer();
3501
3487 pi->num_to_ack = (pi->num_to_ack + 1) % L2CAP_DEFAULT_NUM_TO_ACK; 3502 pi->num_to_ack = (pi->num_to_ack + 1) % L2CAP_DEFAULT_NUM_TO_ACK;
3488 if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1) 3503 if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1)
3489 l2cap_send_ack(pi); 3504 l2cap_send_ack(pi);