From: Marcel Holtmann <marcel@holtmann.org>
To: "Gustavo F. Padovan" <gustavo@las.ic.unicamp.br>
Cc: linux-bluetooth@vger.kernel.org, gustavo@padovan.org
Subject: Re: [PATCH 4/4] Bluetooth: Add support for Retransmission and Monitor Timers
Date: Mon, 27 Jul 2009 12:08:44 +0200 [thread overview]
Message-ID: <1248689324.28545.194.camel@violet> (raw)
In-Reply-To: <1248675424-20977-5-git-send-email-gustavo@las.ic.unicamp.br>
Hi Gustavo,
> L2CAP uses rentransmission and monitor timers to inquiry the other side
> about unacked I-frames. After send each I-frame we (re)start the
> retransmission timer, if it expires, we start a monitor timer that send a
> S-frame with P bit set and wait for S-frame with F bit set.
> If monitor timer expires, it try again, at a maximum of
> L2CAP_DEFAULT_MAX_TX.
>
> Signed-off-by: Gustavo F. Padovan <gustavo@las.ic.unicamp.br>
> ---
> include/net/bluetooth/bluetooth.h | 1 +
> include/net/bluetooth/l2cap.h | 15 +++++-
> net/bluetooth/l2cap.c | 83 +++++++++++++++++++++++++++++++++++--
> 3 files changed, 92 insertions(+), 7 deletions(-)
>
> diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
> index 65a5cf8..b8b9a84 100644
> --- a/include/net/bluetooth/bluetooth.h
> +++ b/include/net/bluetooth/bluetooth.h
> @@ -139,6 +139,7 @@ struct bt_skb_cb {
> __u8 pkt_type;
> __u8 incoming;
> __u8 tx_seq;
> + __u8 retries;
> };
> #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
>
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index 653c313..02871df 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -31,9 +31,9 @@
> #define L2CAP_DEFAULT_FLUSH_TO 0xffff
> #define L2CAP_DEFAULT_TX_WINDOW 63
> #define L2CAP_DEFAULT_NUM_TO_ACK (L2CAP_DEFAULT_TX_WINDOW/5)
> -#define L2CAP_DEFAULT_MAX_RECEIVE 1
> -#define L2CAP_DEFAULT_RETRANS_TO 300 /* 300 milliseconds */
> -#define L2CAP_DEFAULT_MONITOR_TO 1000 /* 1 second */
> +#define L2CAP_DEFAULT_MAX_TX 3
> +#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_CONN_TIMEOUT (40000) /* 40 seconds */
> @@ -320,6 +320,7 @@ struct l2cap_pinfo {
> __u8 req_seq;
> __u8 expected_tx_seq;
> __u8 unacked_frames;
> + __u8 retry_count;
> __u8 num_to_ack;
> __u16 sdu_len;
> __u16 partial_sdu_len;
> @@ -336,6 +337,8 @@ struct l2cap_pinfo {
>
> __le16 sport;
>
> + struct timer_list retrans_timer;
> + struct timer_list monitor_timer;
> struct sk_buff_head tx_queue;
> struct l2cap_conn *conn;
> struct sock *next_c;
> @@ -355,6 +358,12 @@ struct l2cap_pinfo {
>
> #define L2CAP_CONN_SAR_SDU 0x01
> #define L2CAP_CONN_UNDER_REJ 0x02
> +#define L2CAP_CONN_WAIT_ACK 0x04
> +
> +#define __mod_retrans_timer() mod_timer(&l2cap_pi(sk)->retrans_timer, \
> + 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));
>
> static inline int l2cap_tx_window_full(struct sock *sk)
> {
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index 938d6db..bcfa9b9 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -1179,6 +1179,37 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
> return 0;
> }
>
> +static void l2cap_monitor_timeout(unsigned long arg)
> +{
> + struct sock *sk = (void *) arg;
> + u16 control;
> +
> + if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
> + l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
> + return;
> + }
> +
> + l2cap_pi(sk)->retry_count++;
> + __mod_monitor_timer();
> +
> + control = L2CAP_CTRL_POLL;
> + l2cap_send_sframe(l2cap_pi(sk), control);
> +}
> +
> +static void l2cap_retrans_timeout(unsigned long arg)
> +{
> + struct sock *sk = (void *) arg;
> + u16 control;
> +
> + l2cap_pi(sk)->retry_count = 1;
> + __mod_monitor_timer();
> +
> + l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_ACK;
> +
> + control = L2CAP_CTRL_POLL;
> + l2cap_send_sframe(l2cap_pi(sk), control);
> +}
> +
> static void l2cap_drop_acked_frames(struct sock *sk)
> {
> struct sk_buff *skb;
> @@ -1193,6 +1224,9 @@ static void l2cap_drop_acked_frames(struct sock *sk)
> l2cap_pi(sk)->unacked_frames--;
> }
>
> + if (!l2cap_pi(sk)->unacked_frames)
> + del_timer(&l2cap_pi(sk)->retrans_timer);
> +
> return;
> }
>
> @@ -1219,10 +1253,21 @@ static int l2cap_ertm_send(struct sock *sk)
> u16 *control;
> int err;
>
> + if (pi->conn_state & L2CAP_CONN_WAIT_ACK)
> + return 0;
> +
> while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
> tx_seq = pi->next_tx_seq;
> tx_skb = skb_clone(skb, GFP_ATOMIC);
>
> + if (pi->remote_max_tx &&
> + bt_cb(skb)->retries == pi->remote_max_tx) {
> + l2cap_send_disconn_req(pi->conn, sk);
> + break;
> + }
> +
> + bt_cb(skb)->retries++;
> +
> control = (u16 *)(skb->data + L2CAP_HDR_SIZE);
> *control |= cpu_to_le16(
> (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT)
> @@ -1234,6 +1279,8 @@ static int l2cap_ertm_send(struct sock *sk)
> return err;
> }
>
> + __mod_retrans_timer();
> +
> L2CAP_SEQ_NUM_INC(pi->next_tx_seq);
> bt_cb(skb)->tx_seq = tx_seq;
>
> @@ -1323,6 +1370,8 @@ static struct sk_buff *l2cap_create_pdu(struct sock *sk, struct msghdr *msg, siz
> kfree_skb(skb);
> return ERR_PTR(err);
> }
> +
> + bt_cb(skb)->retries = 0;
> return skb;
> }
>
> @@ -2011,7 +2060,7 @@ done:
> case L2CAP_MODE_ERTM:
> rfc.mode = L2CAP_MODE_ERTM;
> rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
> - rfc.max_transmit = L2CAP_DEFAULT_MAX_RECEIVE;
> + rfc.max_transmit = L2CAP_DEFAULT_MAX_TX;
> rfc.retrans_timeout = 0;
> rfc.monitor_timeout = 0;
> rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
> @@ -2506,6 +2555,12 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
> l2cap_pi(sk)->next_tx_seq = 0;
> l2cap_pi(sk)->expected_ack_seq = 0;
> l2cap_pi(sk)->unacked_frames = 0;
> +
> + setup_timer(&l2cap_pi(sk)->retrans_timer,
> + l2cap_retrans_timeout, (unsigned long) sk);
> + setup_timer(&l2cap_pi(sk)->monitor_timer,
> + l2cap_monitor_timeout, (unsigned long) sk);
> +
> __skb_queue_head_init(TX_QUEUE(sk));
> l2cap_chan_ready(sk);
> goto unlock;
> @@ -2615,6 +2670,8 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
> sk->sk_shutdown = SHUTDOWN_MASK;
>
> skb_queue_purge(TX_QUEUE(sk));
> + del_timer(&l2cap_pi(sk)->retrans_timer);
> + del_timer(&l2cap_pi(sk)->monitor_timer);
>
> l2cap_chan_del(sk, ECONNRESET);
> bh_unlock_sock(sk);
> @@ -2639,6 +2696,8 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
> return 0;
>
> skb_queue_purge(TX_QUEUE(sk));
> + del_timer(&l2cap_pi(sk)->retrans_timer);
> + del_timer(&l2cap_pi(sk)->monitor_timer);
>
> l2cap_chan_del(sk, 0);
> bh_unlock_sock(sk);
> @@ -2944,9 +3003,25 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str
>
> switch (rx_control & L2CAP_CTRL_SUPERVISE) {
> case L2CAP_SUPER_RCV_READY:
> - pi->expected_ack_seq = __get_reqseq(rx_control);
> - l2cap_drop_acked_frames(sk);
> - l2cap_ertm_send(sk);
> + if (rx_control & L2CAP_CTRL_POLL) {
> + u16 control = L2CAP_CTRL_FINAL;
> + l2cap_send_sframe(l2cap_pi(sk), control);
> + }
> + else if (rx_control & L2CAP_CTRL_FINAL) {
Coding style is } else if.
> + if (pi->conn_state & L2CAP_CONN_WAIT_ACK)
> + break;
> +
> + pi->conn_state &= !L2CAP_CONN_WAIT_ACK;
> + del_timer(&pi->monitor_timer);
> +
> + if (pi->unacked_frames > 0)
> + __mod_retrans_timer();
> + }
> + else {
Same here.
> + pi->expected_ack_seq = __get_reqseq(rx_control);
> + l2cap_drop_acked_frames(sk);
> + l2cap_ertm_send(sk);
> + }
> break;
>
> case L2CAP_SUPER_REJECT:
Regards
Marcel
next prev parent reply other threads:[~2009-07-27 10:08 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-27 6:17 [PATCH 0/4] Bluetooth: Patch set for ERTM Gustavo F. Padovan
2009-07-27 6:17 ` [PATCH 1/4] Bluetooth: Add initial support for ERTM packets transfers Gustavo F. Padovan
2009-07-27 6:17 ` [PATCH 2/4] Bluetooth: Add support for Segmentation and Reassembly of SDUs Gustavo F. Padovan
2009-07-27 6:17 ` [PATCH 3/4] Bluetooth: Initial support for retransmission of packets with REJ frames Gustavo F. Padovan
2009-07-27 6:17 ` [PATCH 4/4] Bluetooth: Add support for Retransmission and Monitor Timers Gustavo F. Padovan
2009-07-27 10:08 ` Marcel Holtmann [this message]
2009-07-27 10:06 ` [PATCH 3/4] Bluetooth: Initial support for retransmission of packets with REJ frames Marcel Holtmann
2009-07-27 10:05 ` [PATCH 2/4] Bluetooth: Add support for Segmentation and Reassembly of SDUs Marcel Holtmann
2009-07-28 11:30 ` Gustavo F. Padovan
2009-07-27 9:59 ` [PATCH 1/4] Bluetooth: Add initial support for ERTM packets transfers Marcel Holtmann
2009-07-28 11:24 ` Gustavo F. Padovan
[not found] <1249080824-6780-1-git-send-email-gustavo@las.ic.unicamp.br>
2009-07-31 22:53 ` [PATCH 2/4] Bluetooth: Add support for Segmentation and Reassembly of SDUs Gustavo F. Padovan
2009-07-31 22:53 ` [PATCH 3/4] Bluetooth: Initial support for retransmission of packets with REJ frames Gustavo F. Padovan
2009-07-31 22:53 ` [PATCH 4/4] Bluetooth: Add support for Retransmission and Monitor Timers Gustavo F. Padovan
-- strict thread matches above, loose matches on Subject: below --
2009-07-31 22:57 [PATCH 1/4] Bluetooth: Add initial support for ERTM packets transfers Gustavo F. Padovan
2009-07-31 22:57 ` [PATCH 2/4] Bluetooth: Add support for Segmentation and Reassembly of SDUs Gustavo F. Padovan
2009-07-31 22:57 ` [PATCH 3/4] Bluetooth: Initial support for retransmission of packets with REJ frames Gustavo F. Padovan
2009-07-31 22:57 ` [PATCH 4/4] Bluetooth: Add support for Retransmission and Monitor Timers Gustavo F. Padovan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1248689324.28545.194.camel@violet \
--to=marcel@holtmann.org \
--cc=gustavo@las.ic.unicamp.br \
--cc=gustavo@padovan.org \
--cc=linux-bluetooth@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.