]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Bluetooth: Check rules when setting retransmit or monitor timers
authorMat Martineau <mathewm@codeaurora.org>
Fri, 18 May 2012 03:53:49 +0000 (20:53 -0700)
committerJohan Hedberg <johan.hedberg@intel.com>
Tue, 5 Jun 2012 03:34:04 +0000 (06:34 +0300)
The ERTM specification requires the retransmit timer to be cancelled
when the monitor timer is set.  The retransmit timer cannot be set
again while the monitor timer is pending.

Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
include/net/bluetooth/l2cap.h
net/bluetooth/l2cap_core.c

index 7d1da5a7d11ebf340f5bf0b6f80e45162dee3b29..117db8e4a5f49e40df708e4dd0093b8b88dea358 100644 (file)
@@ -706,11 +706,7 @@ static inline bool l2cap_clear_timer(struct l2cap_chan *chan,
 
 #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t))
 #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer)
-#define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \
-               msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));
 #define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer)
-#define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \
-               msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO));
 #define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer)
 #define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \
                msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO));
index 8ea9ec648bfdb3b202584a14a953a799d80acbfb..38e9a0ea4f486ab2f8c0c95ae16366076731fa99 100644 (file)
@@ -227,6 +227,24 @@ static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
        release_sock(sk);
 }
 
+static void __set_retrans_timer(struct l2cap_chan *chan)
+{
+       if (!delayed_work_pending(&chan->monitor_timer) &&
+           chan->retrans_timeout) {
+               l2cap_set_timer(chan, &chan->retrans_timer,
+                               msecs_to_jiffies(chan->retrans_timeout));
+       }
+}
+
+static void __set_monitor_timer(struct l2cap_chan *chan)
+{
+       __clear_retrans_timer(chan);
+       if (chan->monitor_timeout) {
+               l2cap_set_timer(chan, &chan->monitor_timer,
+                               msecs_to_jiffies(chan->monitor_timeout));
+       }
+}
+
 static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
                                               u16 seq)
 {
@@ -1619,7 +1637,7 @@ int __l2cap_wait_ack(struct sock *sk)
 static void l2cap_monitor_timeout(struct work_struct *work)
 {
        struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
-                                                       monitor_timer.work);
+                                              monitor_timer.work);
 
        BT_DBG("chan %p", chan);
 
@@ -1643,7 +1661,7 @@ static void l2cap_monitor_timeout(struct work_struct *work)
 static void l2cap_retrans_timeout(struct work_struct *work)
 {
        struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
-                                                       retrans_timer.work);
+                                              retrans_timer.work);
 
        BT_DBG("chan %p", chan);