aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorGustavo F. Padovan <gustavo@las.ic.unicamp.br>2009-08-20 21:26:00 -0400
committerMarcel Holtmann <marcel@holtmann.org>2009-08-22 17:56:15 -0400
commite90bac061b17cd81bd0df30606c64f4543bf5ca0 (patch)
tree3529111fa5ba07bdd8ed9627d10d623f77416ace /net
parent30afb5b2aa83adf4f69e5090d48e1bb04b64c58a (diff)
Bluetooth: Add support for Retransmission and Monitor Timers
L2CAP uses retransmission and monitor timers to inquiry the other side about unacked I-frames. After sending 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, try again, at a maximum of L2CAP_DEFAULT_MAX_TX. Signed-off-by: Gustavo F. Padovan <gustavo@las.ic.unicamp.br> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/l2cap.c86
1 files changed, 82 insertions, 4 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 35e9f5b80545..97172f7c0a6a 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1178,6 +1178,39 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
1178 return 0; 1178 return 0;
1179} 1179}
1180 1180
1181static void l2cap_monitor_timeout(unsigned long arg)
1182{
1183 struct sock *sk = (void *) arg;
1184 u16 control;
1185
1186 if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
1187 l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
1188 return;
1189 }
1190
1191 l2cap_pi(sk)->retry_count++;
1192 __mod_monitor_timer();
1193
1194 control = L2CAP_CTRL_POLL;
1195 control |= L2CAP_SUPER_RCV_READY;
1196 l2cap_send_sframe(l2cap_pi(sk), control);
1197}
1198
1199static void l2cap_retrans_timeout(unsigned long arg)
1200{
1201 struct sock *sk = (void *) arg;
1202 u16 control;
1203
1204 l2cap_pi(sk)->retry_count = 1;
1205 __mod_monitor_timer();
1206
1207 l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
1208
1209 control = L2CAP_CTRL_POLL;
1210 control |= L2CAP_SUPER_RCV_READY;
1211 l2cap_send_sframe(l2cap_pi(sk), control);
1212}
1213
1181static void l2cap_drop_acked_frames(struct sock *sk) 1214static void l2cap_drop_acked_frames(struct sock *sk)
1182{ 1215{
1183 struct sk_buff *skb; 1216 struct sk_buff *skb;
@@ -1192,6 +1225,9 @@ static void l2cap_drop_acked_frames(struct sock *sk)
1192 l2cap_pi(sk)->unacked_frames--; 1225 l2cap_pi(sk)->unacked_frames--;
1193 } 1226 }
1194 1227
1228 if (!l2cap_pi(sk)->unacked_frames)
1229 del_timer(&l2cap_pi(sk)->retrans_timer);
1230
1195 return; 1231 return;
1196} 1232}
1197 1233
@@ -1216,19 +1252,32 @@ static int l2cap_ertm_send(struct sock *sk)
1216 u16 control; 1252 u16 control;
1217 int err; 1253 int err;
1218 1254
1255 if (pi->conn_state & L2CAP_CONN_WAIT_F)
1256 return 0;
1257
1219 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) { 1258 while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
1220 tx_skb = skb_clone(skb, GFP_ATOMIC); 1259 tx_skb = skb_clone(skb, GFP_ATOMIC);
1221 1260
1261 if (pi->remote_max_tx &&
1262 bt_cb(skb)->retries == pi->remote_max_tx) {
1263 l2cap_send_disconn_req(pi->conn, sk);
1264 break;
1265 }
1266
1267 bt_cb(skb)->retries++;
1268
1222 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); 1269 control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
1223 control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT) 1270 control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT)
1224 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); 1271 | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
1225 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); 1272 put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
1226 1273
1274
1227 err = l2cap_do_send(sk, tx_skb); 1275 err = l2cap_do_send(sk, tx_skb);
1228 if (err < 0) { 1276 if (err < 0) {
1229 l2cap_send_disconn_req(pi->conn, sk); 1277 l2cap_send_disconn_req(pi->conn, sk);
1230 return err; 1278 return err;
1231 } 1279 }
1280 __mod_retrans_timer();
1232 1281
1233 bt_cb(skb)->tx_seq = pi->next_tx_seq; 1282 bt_cb(skb)->tx_seq = pi->next_tx_seq;
1234 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; 1283 pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
@@ -1365,6 +1414,8 @@ static struct sk_buff *l2cap_create_ertm_pdu(struct sock *sk, struct msghdr *msg
1365 kfree_skb(skb); 1414 kfree_skb(skb);
1366 return ERR_PTR(err); 1415 return ERR_PTR(err);
1367 } 1416 }
1417
1418 bt_cb(skb)->retries = 0;
1368 return skb; 1419 return skb;
1369} 1420}
1370 1421
@@ -2058,7 +2109,7 @@ done:
2058 case L2CAP_MODE_ERTM: 2109 case L2CAP_MODE_ERTM:
2059 rfc.mode = L2CAP_MODE_ERTM; 2110 rfc.mode = L2CAP_MODE_ERTM;
2060 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW; 2111 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
2061 rfc.max_transmit = L2CAP_DEFAULT_MAX_RECEIVE; 2112 rfc.max_transmit = L2CAP_DEFAULT_MAX_TX;
2062 rfc.retrans_timeout = 0; 2113 rfc.retrans_timeout = 0;
2063 rfc.monitor_timeout = 0; 2114 rfc.monitor_timeout = 0;
2064 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); 2115 rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
@@ -2553,6 +2604,12 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
2553 l2cap_pi(sk)->next_tx_seq = 0; 2604 l2cap_pi(sk)->next_tx_seq = 0;
2554 l2cap_pi(sk)->expected_ack_seq = 0; 2605 l2cap_pi(sk)->expected_ack_seq = 0;
2555 l2cap_pi(sk)->unacked_frames = 0; 2606 l2cap_pi(sk)->unacked_frames = 0;
2607
2608 setup_timer(&l2cap_pi(sk)->retrans_timer,
2609 l2cap_retrans_timeout, (unsigned long) sk);
2610 setup_timer(&l2cap_pi(sk)->monitor_timer,
2611 l2cap_monitor_timeout, (unsigned long) sk);
2612
2556 __skb_queue_head_init(TX_QUEUE(sk)); 2613 __skb_queue_head_init(TX_QUEUE(sk));
2557 l2cap_chan_ready(sk); 2614 l2cap_chan_ready(sk);
2558 goto unlock; 2615 goto unlock;
@@ -2662,6 +2719,8 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
2662 sk->sk_shutdown = SHUTDOWN_MASK; 2719 sk->sk_shutdown = SHUTDOWN_MASK;
2663 2720
2664 skb_queue_purge(TX_QUEUE(sk)); 2721 skb_queue_purge(TX_QUEUE(sk));
2722 del_timer(&l2cap_pi(sk)->retrans_timer);
2723 del_timer(&l2cap_pi(sk)->monitor_timer);
2665 2724
2666 l2cap_chan_del(sk, ECONNRESET); 2725 l2cap_chan_del(sk, ECONNRESET);
2667 bh_unlock_sock(sk); 2726 bh_unlock_sock(sk);
@@ -2686,6 +2745,8 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
2686 return 0; 2745 return 0;
2687 2746
2688 skb_queue_purge(TX_QUEUE(sk)); 2747 skb_queue_purge(TX_QUEUE(sk));
2748 del_timer(&l2cap_pi(sk)->retrans_timer);
2749 del_timer(&l2cap_pi(sk)->monitor_timer);
2689 2750
2690 l2cap_chan_del(sk, 0); 2751 l2cap_chan_del(sk, 0);
2691 bh_unlock_sock(sk); 2752 bh_unlock_sock(sk);
@@ -2991,9 +3052,26 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str
2991 3052
2992 switch (rx_control & L2CAP_CTRL_SUPERVISE) { 3053 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
2993 case L2CAP_SUPER_RCV_READY: 3054 case L2CAP_SUPER_RCV_READY:
2994 pi->expected_ack_seq = __get_reqseq(rx_control); 3055 if (rx_control & L2CAP_CTRL_POLL) {
2995 l2cap_drop_acked_frames(sk); 3056 u16 control = L2CAP_CTRL_FINAL;
2996 l2cap_ertm_send(sk); 3057 control |= L2CAP_SUPER_RCV_READY;
3058 l2cap_send_sframe(l2cap_pi(sk), control);
3059 } else if (rx_control & L2CAP_CTRL_FINAL) {
3060 if (!(pi->conn_state & L2CAP_CONN_WAIT_F))
3061 break;
3062
3063 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3064 del_timer(&pi->monitor_timer);
3065
3066 if (pi->unacked_frames > 0)
3067 __mod_retrans_timer();
3068 } else {
3069 pi->expected_ack_seq = __get_reqseq(rx_control);
3070 l2cap_drop_acked_frames(sk);
3071 if (pi->unacked_frames > 0)
3072 __mod_retrans_timer();
3073 l2cap_ertm_send(sk);
3074 }
2997 break; 3075 break;
2998 3076
2999 case L2CAP_SUPER_REJECT: 3077 case L2CAP_SUPER_REJECT: