mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
05fbd89dd4
commit
c1b4f43be0
|
@ -35,6 +35,7 @@
|
|||
#define L2CAP_DEFAULT_RETRANS_TO 1000 /* 1 second */
|
||||
#define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */
|
||||
#define L2CAP_DEFAULT_MAX_PDU_SIZE 672
|
||||
#define L2CAP_DEFAULT_ACK_TO 200
|
||||
|
||||
#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */
|
||||
#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */
|
||||
|
@ -348,6 +349,7 @@ struct l2cap_pinfo {
|
|||
|
||||
struct timer_list retrans_timer;
|
||||
struct timer_list monitor_timer;
|
||||
struct timer_list ack_timer;
|
||||
struct sk_buff_head tx_queue;
|
||||
struct sk_buff_head srej_queue;
|
||||
struct srej_list srej_l;
|
||||
|
@ -382,6 +384,8 @@ struct l2cap_pinfo {
|
|||
jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));
|
||||
#define __mod_monitor_timer() mod_timer(&l2cap_pi(sk)->monitor_timer, \
|
||||
jiffies + msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO));
|
||||
#define __mod_ack_timer() mod_timer(&l2cap_pi(sk)->ack_timer, \
|
||||
jiffies + msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO));
|
||||
|
||||
static inline int l2cap_tx_window_full(struct sock *sk)
|
||||
{
|
||||
|
|
|
@ -2235,6 +2235,15 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
|
|||
*ptr += L2CAP_CONF_OPT_SIZE + len;
|
||||
}
|
||||
|
||||
static void l2cap_ack_timeout(unsigned long arg)
|
||||
{
|
||||
struct sock *sk = (void *) arg;
|
||||
|
||||
bh_lock_sock(sk);
|
||||
l2cap_send_ack(l2cap_pi(sk));
|
||||
bh_unlock_sock(sk);
|
||||
}
|
||||
|
||||
static inline void l2cap_ertm_init(struct sock *sk)
|
||||
{
|
||||
l2cap_pi(sk)->expected_ack_seq = 0;
|
||||
|
@ -2247,6 +2256,8 @@ static inline void l2cap_ertm_init(struct sock *sk)
|
|||
l2cap_retrans_timeout, (unsigned long) sk);
|
||||
setup_timer(&l2cap_pi(sk)->monitor_timer,
|
||||
l2cap_monitor_timeout, (unsigned long) sk);
|
||||
setup_timer(&l2cap_pi(sk)->ack_timer,
|
||||
l2cap_ack_timeout, (unsigned long) sk);
|
||||
|
||||
__skb_queue_head_init(SREJ_QUEUE(sk));
|
||||
}
|
||||
|
@ -2975,6 +2986,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
|
|||
skb_queue_purge(SREJ_QUEUE(sk));
|
||||
del_timer(&l2cap_pi(sk)->retrans_timer);
|
||||
del_timer(&l2cap_pi(sk)->monitor_timer);
|
||||
del_timer(&l2cap_pi(sk)->ack_timer);
|
||||
}
|
||||
|
||||
l2cap_chan_del(sk, ECONNRESET);
|
||||
|
@ -3005,6 +3017,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
|
|||
skb_queue_purge(SREJ_QUEUE(sk));
|
||||
del_timer(&l2cap_pi(sk)->retrans_timer);
|
||||
del_timer(&l2cap_pi(sk)->monitor_timer);
|
||||
del_timer(&l2cap_pi(sk)->ack_timer);
|
||||
}
|
||||
|
||||
l2cap_chan_del(sk, 0);
|
||||
|
@ -3484,6 +3497,8 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
|
|||
if (err < 0)
|
||||
return err;
|
||||
|
||||
__mod_ack_timer();
|
||||
|
||||
pi->num_to_ack = (pi->num_to_ack + 1) % L2CAP_DEFAULT_NUM_TO_ACK;
|
||||
if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1)
|
||||
l2cap_send_ack(pi);
|
||||
|
|
Loading…
Reference in New Issue