* [PATCH 00/19] Patches for eL2CAP
@ 2010-03-23 19:48 Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 01/19] Bluetooth: Implement 'Send IorRRorRNR' event Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
Hi,
In the following e-mails there is a patch set for the Enhanced Retransmission Mode. Part of them are new features implementation and the other part is bug fixes.
Gustavo F. Padovan (19):
Bluetooth: Implement 'Send IorRRorRNR' event
Bluetooth: Support case with F bit set under WAIT_F state.
Bluetooth: Fix memory leak of S-frames into L2CAP
Bluetooth: Check the minimum {I,S}-frame size into L2CAP
Bluetooth: Check if SDU size is greater than MTU on L2CAP
Bluetooth: Fix expected_tx_seq calculation on L2CAP
Bluetooth: Implement SendAck() Action on ERTM.
Bluetooth: Move set of P-bit to l2cap_send_sframe()
Bluetooth: Add Recv RR (P=0)(F=0) for SREJ_SENT state on ERTM
Bluetooth: Use a l2cap_pinfo struct instead l2cap_pi() macro
Bluetooth: Fix ACL MTU issue
Bluetooth: Split l2cap_data_channel_sframe()
Bluetooth: Handle all cases of receipt of RNR-frames into L2CAP
Bluetooth: Group the ack of I-frames into l2cap_data_channel_rrframe()
Bluetooth: Remove duplicate use of __get_reqseq() macro on L2CAP
Bluetooth: Finish implementation for Rec RR (P=1) on ERTM
Bluetooth: Ignore I-frames with a duplicated txSeq
Bluetooth: Add timer to Acknowledge I-frames
Bluetooth: Move specific Basic Mode code to the right place
include/net/bluetooth/l2cap.h | 24 ++-
net/bluetooth/l2cap.c | 382 +++++++++++++++++++++++++++++------------
2 files changed, 286 insertions(+), 120 deletions(-)
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 01/19] Bluetooth: Implement 'Send IorRRorRNR' event
2010-03-23 19:48 [PATCH 00/19] Patches for eL2CAP Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 02/19] Bluetooth: Support case with F bit set under WAIT_F state Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
After receive a RR with P bit set ERTM shall use this funcion to choose
what type of frame to reply with F bit = 1.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 20 ++++++++++--------
net/bluetooth/l2cap.c | 44 +++++++++++++++++++++++++++++++++++++---
2 files changed, 51 insertions(+), 13 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 17a689f..d9c20c3 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -320,7 +320,7 @@ struct l2cap_pinfo {
__u8 conf_req[64];
__u8 conf_len;
__u8 conf_state;
- __u8 conn_state;
+ __u16 conn_state;
__u8 next_tx_seq;
__u8 expected_ack_seq;
@@ -328,6 +328,7 @@ struct l2cap_pinfo {
__u8 buffer_seq;
__u8 buffer_seq_srej;
__u8 srej_save_reqseq;
+ __u8 frames_sent;
__u8 unacked_frames;
__u8 retry_count;
__u8 num_to_ack;
@@ -367,14 +368,15 @@ struct l2cap_pinfo {
#define L2CAP_CONF_MAX_CONF_REQ 2
#define L2CAP_CONF_MAX_CONF_RSP 2
-#define L2CAP_CONN_SAR_SDU 0x01
-#define L2CAP_CONN_SREJ_SENT 0x02
-#define L2CAP_CONN_WAIT_F 0x04
-#define L2CAP_CONN_SREJ_ACT 0x08
-#define L2CAP_CONN_SEND_PBIT 0x10
-#define L2CAP_CONN_REMOTE_BUSY 0x20
-#define L2CAP_CONN_LOCAL_BUSY 0x40
-#define L2CAP_CONN_REJ_ACT 0x80
+#define L2CAP_CONN_SAR_SDU 0x0001
+#define L2CAP_CONN_SREJ_SENT 0x0002
+#define L2CAP_CONN_WAIT_F 0x0004
+#define L2CAP_CONN_SREJ_ACT 0x0008
+#define L2CAP_CONN_SEND_PBIT 0x0010
+#define L2CAP_CONN_REMOTE_BUSY 0x0020
+#define L2CAP_CONN_LOCAL_BUSY 0x0040
+#define L2CAP_CONN_REJ_ACT 0x0080
+#define L2CAP_CONN_SEND_FBIT 0x0100
#define __mod_retrans_timer() mod_timer(&l2cap_pi(sk)->retrans_timer, \
jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 7794a2e..18328a4 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1382,6 +1382,10 @@ static int l2cap_ertm_send(struct sock *sk)
bt_cb(skb)->retries++;
control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
+ if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
+ control |= L2CAP_CTRL_FINAL;
+ pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
+ }
control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
| (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
@@ -1403,6 +1407,7 @@ static int l2cap_ertm_send(struct sock *sk)
pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
pi->unacked_frames++;
+ pi->frames_sent++;
if (skb_queue_is_last(TX_QUEUE(sk), skb))
sk->sk_send_head = NULL;
@@ -2186,6 +2191,7 @@ static inline void l2cap_ertm_init(struct sock *sk)
l2cap_pi(sk)->unacked_frames = 0;
l2cap_pi(sk)->buffer_seq = 0;
l2cap_pi(sk)->num_to_ack = 0;
+ l2cap_pi(sk)->frames_sent = 0;
setup_timer(&l2cap_pi(sk)->retrans_timer,
l2cap_retrans_timeout, (unsigned long) sk);
@@ -3139,6 +3145,39 @@ static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb)
return 0;
}
+static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
+{
+ struct l2cap_pinfo *pi = l2cap_pi(sk);
+ u16 control = 0;
+
+ pi->frames_sent = 0;
+ pi->conn_state |= L2CAP_CONN_SEND_FBIT;
+
+ control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+
+ if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
+ control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL;
+ l2cap_send_sframe(pi, control);
+ pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
+
+ }
+
+ if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0)
+ __mod_retrans_timer();
+
+ l2cap_ertm_send(sk);
+
+ if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
+ pi->frames_sent == 0) {
+ control |= L2CAP_SUPER_RCV_READY;
+ if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
+ control |= L2CAP_CTRL_FINAL;
+ pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
+ }
+ l2cap_send_sframe(pi, control);
+ }
+}
+
static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
{
struct sk_buff *next_skb;
@@ -3409,10 +3448,7 @@ 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:
if (rx_control & L2CAP_CTRL_POLL) {
- u16 control = L2CAP_CTRL_FINAL;
- control |= L2CAP_SUPER_RCV_READY |
- (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT);
- l2cap_send_sframe(l2cap_pi(sk), control);
+ l2cap_send_i_or_rr_or_rnr(sk);
pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
} else if (rx_control & L2CAP_CTRL_FINAL) {
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 02/19] Bluetooth: Support case with F bit set under WAIT_F state.
2010-03-23 19:48 ` [PATCH 01/19] Bluetooth: Implement 'Send IorRRorRNR' event Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 03/19] Bluetooth: Fix memory leak of S-frames into L2CAP Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
On receipt of a F=1 under WAIT_F state ERTM shall stop monitor timer and
start retransmission timer (if there are unacked frames).
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 22 ++++++++++++++--------
1 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 18328a4..ab3f0c4 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3356,6 +3356,13 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
+ if (L2CAP_CTRL_FINAL & rx_control) {
+ del_timer(&pi->monitor_timer);
+ if (pi->unacked_frames > 0)
+ __mod_retrans_timer();
+ pi->conn_state &= ~L2CAP_CONN_WAIT_F;
+ }
+
pi->expected_ack_seq = req_seq;
l2cap_drop_acked_frames(sk);
@@ -3445,6 +3452,13 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str
BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
+ if (L2CAP_CTRL_FINAL & rx_control) {
+ del_timer(&pi->monitor_timer);
+ if (pi->unacked_frames > 0)
+ __mod_retrans_timer();
+ pi->conn_state &= ~L2CAP_CONN_WAIT_F;
+ }
+
switch (rx_control & L2CAP_CTRL_SUPERVISE) {
case L2CAP_SUPER_RCV_READY:
if (rx_control & L2CAP_CTRL_POLL) {
@@ -3464,14 +3478,6 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str
l2cap_ertm_send(sk);
}
- if (!(pi->conn_state & L2CAP_CONN_WAIT_F))
- break;
-
- pi->conn_state &= ~L2CAP_CONN_WAIT_F;
- del_timer(&pi->monitor_timer);
-
- if (pi->unacked_frames > 0)
- __mod_retrans_timer();
} else {
pi->expected_ack_seq = tx_seq;
l2cap_drop_acked_frames(sk);
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 03/19] Bluetooth: Fix memory leak of S-frames into L2CAP
2010-03-23 19:48 ` [PATCH 02/19] Bluetooth: Support case with F bit set under WAIT_F state Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 04/19] Bluetooth: Check the minimum {I,S}-frame size " Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
l2cap_data_channel do not free the S-frame, so we free it here.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index ab3f0c4..a020b9f 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3559,6 +3559,7 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str
break;
}
+ kfree_skb(skb);
return 0;
}
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 04/19] Bluetooth: Check the minimum {I,S}-frame size into L2CAP
2010-03-23 19:48 ` [PATCH 03/19] Bluetooth: Fix memory leak of S-frames into L2CAP Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 05/19] Bluetooth: Check if SDU size is greater than MTU on L2CAP Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
All packets with size fewer than the minimum specified is dropped.
Note that the size of the l2cap basic header, FCS and SAR fields are
already subtracted of len at the moment of the size check.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 14 +++++++++++---
1 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index a020b9f..e78fc16 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3619,10 +3619,17 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
if (l2cap_check_fcs(pi, skb))
goto drop;
- if (__is_iframe(control))
+ if (__is_iframe(control)) {
+ if (len < 4)
+ goto drop;
+
l2cap_data_channel_iframe(sk, control, skb);
- else
+ } else {
+ if (len != 0)
+ goto drop;
+
l2cap_data_channel_sframe(sk, control, skb);
+ }
goto done;
@@ -3637,7 +3644,8 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
if (pi->fcs == L2CAP_FCS_CRC16)
len -= 2;
- if (len > L2CAP_DEFAULT_MAX_PDU_SIZE || __is_sframe(control))
+ if (len > L2CAP_DEFAULT_MAX_PDU_SIZE || len < 4
+ || __is_sframe(control))
goto drop;
if (l2cap_check_fcs(pi, skb))
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 05/19] Bluetooth: Check if SDU size is greater than MTU on L2CAP
2010-03-23 19:48 ` [PATCH 04/19] Bluetooth: Check the minimum {I,S}-frame size " Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 06/19] Bluetooth: Fix expected_tx_seq calculation " Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
After reassembly the SDU we need to check his size. It can't overflow
the MTU size.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index e78fc16..36fac64 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3269,15 +3269,19 @@ static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 co
pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
pi->partial_sdu_len += skb->len;
+ if (pi->partial_sdu_len > pi->imtu)
+ goto drop;
+
if (pi->partial_sdu_len == pi->sdu_len) {
_skb = skb_clone(pi->sdu, GFP_ATOMIC);
err = sock_queue_rcv_skb(sk, _skb);
if (err < 0)
kfree_skb(_skb);
}
- kfree_skb(pi->sdu);
err = 0;
+drop:
+ kfree_skb(pi->sdu);
break;
}
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 06/19] Bluetooth: Fix expected_tx_seq calculation on L2CAP
2010-03-23 19:48 ` [PATCH 05/19] Bluetooth: Check if SDU size is greater than MTU on L2CAP Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 07/19] Bluetooth: Implement SendAck() Action on ERTM Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
All operation related to the txWindow should be modulo 64.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 36fac64..03caa2c 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3660,7 +3660,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
if (pi->expected_tx_seq == tx_seq)
pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
else
- pi->expected_tx_seq = tx_seq + 1;
+ pi->expected_tx_seq = (tx_seq + 1) % 64;
l2cap_sar_reassembly_sdu(sk, skb, control);
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 07/19] Bluetooth: Implement SendAck() Action on ERTM.
2010-03-23 19:48 ` [PATCH 06/19] Bluetooth: Fix expected_tx_seq calculation " Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 08/19] Bluetooth: Move set of P-bit to l2cap_send_sframe() Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
Shall be used to ack received frames, It must decide type of
acknowledgment between a RR frame, a RNR frame or transmission of
pending I-frames.
It also modifies l2cap_ertm_send() to report the number of frames sent.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 41 +++++++++++++++++++++++++++++------------
1 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 03caa2c..6368cb2 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -352,6 +352,11 @@ static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
count = min_t(unsigned int, conn->mtu, hlen);
control |= L2CAP_CTRL_FRAME_TYPE;
+ if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
+ control |= L2CAP_CTRL_FINAL;
+ pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
+ }
+
skb = bt_skb_alloc(count, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
@@ -1363,7 +1368,7 @@ static int l2cap_ertm_send(struct sock *sk)
struct sk_buff *skb, *tx_skb;
struct l2cap_pinfo *pi = l2cap_pi(sk);
u16 control, fcs;
- int err;
+ int err, nsent = 0;
if (pi->conn_state & L2CAP_CONN_WAIT_F)
return 0;
@@ -1413,8 +1418,27 @@ static int l2cap_ertm_send(struct sock *sk)
sk->sk_send_head = NULL;
else
sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
+
+ nsent++;
}
+ return nsent;
+}
+
+static int l2cap_send_ack(struct l2cap_pinfo *pi)
+{
+ struct sock *sk = (struct sock *)pi;
+ u16 control = 0;
+
+ control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+
+ if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
+ control |= L2CAP_SUPER_RCV_NOT_READY;
+ return l2cap_send_sframe(pi, control);
+ } else if (l2cap_ertm_send(sk) == 0) {
+ control |= L2CAP_SUPER_RCV_READY;
+ return l2cap_send_sframe(pi, control);
+ }
return 0;
}
@@ -1673,7 +1697,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
else
err = l2cap_ertm_send(sk);
- if (!err)
+ if (err >= 0)
err = len;
break;
@@ -3170,10 +3194,6 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) &&
pi->frames_sent == 0) {
control |= L2CAP_SUPER_RCV_READY;
- if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
- control |= L2CAP_CTRL_FINAL;
- pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
- }
l2cap_send_sframe(pi, control);
}
}
@@ -3354,7 +3374,6 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
struct l2cap_pinfo *pi = l2cap_pi(sk);
u8 tx_seq = __get_txseq(rx_control);
u8 req_seq = __get_reqseq(rx_control);
- u16 tx_control = 0;
u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
int err = 0;
@@ -3441,11 +3460,9 @@ expected:
return err;
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) {
- tx_control |= L2CAP_SUPER_RCV_READY;
- tx_control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
- l2cap_send_sframe(pi, tx_control);
- }
+ if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1)
+ l2cap_send_ack(pi);
+
return 0;
}
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 08/19] Bluetooth: Move set of P-bit to l2cap_send_sframe()
2010-03-23 19:48 ` [PATCH 07/19] Bluetooth: Implement SendAck() Action on ERTM Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 09/19] Bluetooth: Add Recv RR (P=0)(F=0) for SREJ_SENT state on ERTM Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
Abstract the send of of P-bit and avoids code duplication like we
did with the setting of F-bit.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 6368cb2..2e1884b 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -357,6 +357,11 @@ static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;
}
+ if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
+ control |= L2CAP_CTRL_POLL;
+ pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
+ }
+
skb = bt_skb_alloc(count, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
@@ -3356,10 +3361,6 @@ static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
while (tx_seq != pi->expected_tx_seq) {
control = L2CAP_SUPER_SELECT_REJECT;
control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
- if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
- control |= L2CAP_CTRL_POLL;
- pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
- }
l2cap_send_sframe(pi, control);
new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 09/19] Bluetooth: Add Recv RR (P=0)(F=0) for SREJ_SENT state on ERTM
2010-03-23 19:48 ` [PATCH 08/19] Bluetooth: Move set of P-bit to l2cap_send_sframe() Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 10/19] Bluetooth: Use a l2cap_pinfo struct instead l2cap_pi() macro Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
This finishes the implementation of Recv RR (P=0)(F=0) for the Enhanced
Retransmission Mode on L2CAP.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 2e1884b..4dd130d 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3509,7 +3509,10 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str
__mod_retrans_timer();
pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- l2cap_ertm_send(sk);
+ if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
+ l2cap_send_ack(pi);
+ else
+ l2cap_ertm_send(sk);
}
break;
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 10/19] Bluetooth: Use a l2cap_pinfo struct instead l2cap_pi() macro
2010-03-23 19:48 ` [PATCH 09/19] Bluetooth: Add Recv RR (P=0)(F=0) for SREJ_SENT state on ERTM Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 11/19] Bluetooth: Fix ACL MTU issue Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
Trivial clean up.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 4dd130d..428be03 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1300,7 +1300,7 @@ static int l2cap_streaming_send(struct sock *sk)
control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
- if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
+ if (pi->fcs == L2CAP_FCS_CRC16) {
fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
}
@@ -1353,7 +1353,7 @@ static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
| (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
- if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
+ if (pi->fcs == L2CAP_FCS_CRC16) {
fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
}
@@ -1401,7 +1401,7 @@ static int l2cap_ertm_send(struct sock *sk)
put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
- if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
+ if (pi->fcs == L2CAP_FCS_CRC16) {
fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
}
@@ -3576,10 +3576,10 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str
pi->expected_ack_seq = tx_seq;
l2cap_drop_acked_frames(sk);
- del_timer(&l2cap_pi(sk)->retrans_timer);
+ del_timer(&pi->retrans_timer);
if (rx_control & L2CAP_CTRL_POLL) {
u16 control = L2CAP_CTRL_FINAL;
- l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
+ l2cap_send_rr_or_rnr(pi, control);
}
break;
}
@@ -3688,7 +3688,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
goto done;
default:
- BT_DBG("sk %p: bad mode 0x%2.2x", sk, l2cap_pi(sk)->mode);
+ BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode);
break;
}
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 11/19] Bluetooth: Fix ACL MTU issue
2010-03-23 19:48 ` [PATCH 10/19] Bluetooth: Use a l2cap_pinfo struct instead l2cap_pi() macro Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 12/19] Bluetooth: Split l2cap_data_channel_sframe() Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
ERTM and Streaming Modes was having problems when the ACL MTU is lower
than MPS. The 'minus 10' is to take in account the header and fcs
lenghts.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 428be03..12104f4 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2297,6 +2297,8 @@ done:
rfc.retrans_timeout = 0;
rfc.monitor_timeout = 0;
rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
+ if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
+ rfc.max_pdu_size = pi->conn->mtu - 10;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
@@ -2318,6 +2320,8 @@ done:
rfc.retrans_timeout = 0;
rfc.monitor_timeout = 0;
rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
+ if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
+ rfc.max_pdu_size = pi->conn->mtu - 10;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 12/19] Bluetooth: Split l2cap_data_channel_sframe()
2010-03-23 19:48 ` [PATCH 11/19] Bluetooth: Fix ACL MTU issue Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 13/19] Bluetooth: Handle all cases of receipt of RNR-frames into L2CAP Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
Create a function for each type fo S-frame and avoid a lot of nested
code.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 205 ++++++++++++++++++++++++++++---------------------
1 files changed, 116 insertions(+), 89 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 12104f4..2f32e91 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3471,120 +3471,147 @@ expected:
return 0;
}
-static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
+static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
{
struct l2cap_pinfo *pi = l2cap_pi(sk);
u8 tx_seq = __get_reqseq(rx_control);
- BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
-
- if (L2CAP_CTRL_FINAL & rx_control) {
- del_timer(&pi->monitor_timer);
- if (pi->unacked_frames > 0)
- __mod_retrans_timer();
- pi->conn_state &= ~L2CAP_CONN_WAIT_F;
- }
+ if (rx_control & L2CAP_CTRL_POLL) {
+ l2cap_send_i_or_rr_or_rnr(sk);
+ pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- switch (rx_control & L2CAP_CTRL_SUPERVISE) {
- case L2CAP_SUPER_RCV_READY:
- if (rx_control & L2CAP_CTRL_POLL) {
- l2cap_send_i_or_rr_or_rnr(sk);
- pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
-
- } else if (rx_control & L2CAP_CTRL_FINAL) {
- pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(sk);
-
- if (pi->conn_state & L2CAP_CONN_REJ_ACT)
- pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
- else {
- sk->sk_send_head = TX_QUEUE(sk)->next;
- pi->next_tx_seq = pi->expected_ack_seq;
- l2cap_ertm_send(sk);
- }
+ } else if (rx_control & L2CAP_CTRL_FINAL) {
+ pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ pi->expected_ack_seq = tx_seq;
+ l2cap_drop_acked_frames(sk);
- } else {
- pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(sk);
+ if (pi->conn_state & L2CAP_CONN_REJ_ACT)
+ pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
+ else {
+ sk->sk_send_head = TX_QUEUE(sk)->next;
+ pi->next_tx_seq = pi->expected_ack_seq;
+ l2cap_ertm_send(sk);
+ }
- if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
- (pi->unacked_frames > 0))
- __mod_retrans_timer();
+ } else {
+ pi->expected_ack_seq = tx_seq;
+ l2cap_drop_acked_frames(sk);
- pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
- l2cap_send_ack(pi);
- else
- l2cap_ertm_send(sk);
- }
- break;
+ if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
+ (pi->unacked_frames > 0))
+ __mod_retrans_timer();
- case L2CAP_SUPER_REJECT:
pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
+ l2cap_send_ack(pi);
+ else
+ l2cap_ertm_send(sk);
+ }
+}
- pi->expected_ack_seq = __get_reqseq(rx_control);
- l2cap_drop_acked_frames(sk);
+static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
+{
+ struct l2cap_pinfo *pi = l2cap_pi(sk);
+ u8 tx_seq = __get_reqseq(rx_control);
- if (rx_control & L2CAP_CTRL_FINAL) {
- if (pi->conn_state & L2CAP_CONN_REJ_ACT)
- pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
- else {
- sk->sk_send_head = TX_QUEUE(sk)->next;
- pi->next_tx_seq = pi->expected_ack_seq;
- l2cap_ertm_send(sk);
- }
- } else {
+ pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+
+ pi->expected_ack_seq = __get_reqseq(rx_control);
+ l2cap_drop_acked_frames(sk);
+
+ if (rx_control & L2CAP_CTRL_FINAL) {
+ if (pi->conn_state & L2CAP_CONN_REJ_ACT)
+ pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
+ else {
sk->sk_send_head = TX_QUEUE(sk)->next;
pi->next_tx_seq = pi->expected_ack_seq;
l2cap_ertm_send(sk);
-
- if (pi->conn_state & L2CAP_CONN_WAIT_F) {
- pi->srej_save_reqseq = tx_seq;
- pi->conn_state |= L2CAP_CONN_REJ_ACT;
- }
}
+ } else {
+ sk->sk_send_head = TX_QUEUE(sk)->next;
+ pi->next_tx_seq = pi->expected_ack_seq;
+ l2cap_ertm_send(sk);
- break;
+ if (pi->conn_state & L2CAP_CONN_WAIT_F) {
+ pi->srej_save_reqseq = tx_seq;
+ pi->conn_state |= L2CAP_CONN_REJ_ACT;
+ }
+ }
+}
+static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
+{
+ struct l2cap_pinfo *pi = l2cap_pi(sk);
+ u8 tx_seq = __get_reqseq(rx_control);
- case L2CAP_SUPER_SELECT_REJECT:
- pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- if (rx_control & L2CAP_CTRL_POLL) {
- pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(sk);
- l2cap_retransmit_frame(sk, tx_seq);
- l2cap_ertm_send(sk);
- if (pi->conn_state & L2CAP_CONN_WAIT_F) {
- pi->srej_save_reqseq = tx_seq;
- pi->conn_state |= L2CAP_CONN_SREJ_ACT;
- }
- } else if (rx_control & L2CAP_CTRL_FINAL) {
- if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
- pi->srej_save_reqseq == tx_seq)
- pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
- else
- l2cap_retransmit_frame(sk, tx_seq);
+ if (rx_control & L2CAP_CTRL_POLL) {
+ pi->expected_ack_seq = tx_seq;
+ l2cap_drop_acked_frames(sk);
+ l2cap_retransmit_frame(sk, tx_seq);
+ l2cap_ertm_send(sk);
+ if (pi->conn_state & L2CAP_CONN_WAIT_F) {
+ pi->srej_save_reqseq = tx_seq;
+ pi->conn_state |= L2CAP_CONN_SREJ_ACT;
}
- else {
+ } else if (rx_control & L2CAP_CTRL_FINAL) {
+ if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
+ pi->srej_save_reqseq == tx_seq)
+ pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
+ else
l2cap_retransmit_frame(sk, tx_seq);
- if (pi->conn_state & L2CAP_CONN_WAIT_F) {
- pi->srej_save_reqseq = tx_seq;
- pi->conn_state |= L2CAP_CONN_SREJ_ACT;
- }
+ }
+ else {
+ l2cap_retransmit_frame(sk, tx_seq);
+ if (pi->conn_state & L2CAP_CONN_WAIT_F) {
+ pi->srej_save_reqseq = tx_seq;
+ pi->conn_state |= L2CAP_CONN_SREJ_ACT;
}
+ }
+}
+
+static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
+{
+ struct l2cap_pinfo *pi = l2cap_pi(sk);
+ u8 tx_seq = __get_reqseq(rx_control);
+
+ pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
+ pi->expected_ack_seq = tx_seq;
+ l2cap_drop_acked_frames(sk);
+
+ del_timer(&pi->retrans_timer);
+ if (rx_control & L2CAP_CTRL_POLL) {
+ u16 control = L2CAP_CTRL_FINAL;
+ l2cap_send_rr_or_rnr(pi, control);
+ }
+}
+
+static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
+{
+ BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
+
+ if (L2CAP_CTRL_FINAL & rx_control) {
+ del_timer(&l2cap_pi(sk)->monitor_timer);
+ if (l2cap_pi(sk)->unacked_frames > 0)
+ __mod_retrans_timer();
+ l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
+ }
+
+ switch (rx_control & L2CAP_CTRL_SUPERVISE) {
+ case L2CAP_SUPER_RCV_READY:
+ l2cap_data_channel_rrframe(sk, rx_control);
break;
- case L2CAP_SUPER_RCV_NOT_READY:
- pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
- pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(sk);
+ case L2CAP_SUPER_REJECT:
+ l2cap_data_channel_rejframe(sk, rx_control);
+ break;
- del_timer(&pi->retrans_timer);
- if (rx_control & L2CAP_CTRL_POLL) {
- u16 control = L2CAP_CTRL_FINAL;
- l2cap_send_rr_or_rnr(pi, control);
- }
+ case L2CAP_SUPER_SELECT_REJECT:
+ l2cap_data_channel_srejframe(sk, rx_control);
+ break;
+
+ case L2CAP_SUPER_RCV_NOT_READY:
+ l2cap_data_channel_rnrframe(sk, rx_control);
break;
}
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 13/19] Bluetooth: Handle all cases of receipt of RNR-frames into L2CAP
2010-03-23 19:48 ` [PATCH 12/19] Bluetooth: Split l2cap_data_channel_sframe() Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 14/19] Bluetooth: Group the ack of I-frames into l2cap_data_channel_rrframe() Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
We weren't handling the receipt under SREJ_SENT state table.
It also introduce l2cap_send_srejtail(). It will be used in the nexts
commits too.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 32 ++++++++++++++++++++++++++++----
1 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 2f32e91..f966ed3 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1447,6 +1447,22 @@ static int l2cap_send_ack(struct l2cap_pinfo *pi)
return 0;
}
+static int l2cap_send_srejtail(struct sock *sk)
+{
+ struct srej_list *tail;
+ u16 control;
+
+ control = L2CAP_SUPER_SELECT_REJECT;
+ control |= L2CAP_CTRL_FINAL;
+
+ tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list);
+ control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+
+ l2cap_send_sframe(l2cap_pi(sk), control);
+
+ return 0;
+}
+
static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb)
{
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
@@ -3579,11 +3595,19 @@ static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
pi->expected_ack_seq = tx_seq;
l2cap_drop_acked_frames(sk);
- del_timer(&pi->retrans_timer);
- if (rx_control & L2CAP_CTRL_POLL) {
- u16 control = L2CAP_CTRL_FINAL;
- l2cap_send_rr_or_rnr(pi, control);
+ if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) {
+ del_timer(&pi->retrans_timer);
+ if (rx_control & L2CAP_CTRL_POLL) {
+ u16 control = L2CAP_CTRL_FINAL;
+ l2cap_send_rr_or_rnr(pi, control);
+ }
+ return;
}
+
+ if (rx_control & L2CAP_CTRL_POLL)
+ l2cap_send_srejtail(sk);
+ else
+ l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY);
}
static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 14/19] Bluetooth: Group the ack of I-frames into l2cap_data_channel_rrframe()
2010-03-23 19:48 ` [PATCH 13/19] Bluetooth: Handle all cases of receipt of RNR-frames into L2CAP Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 15/19] Bluetooth: Remove duplicate use of __get_reqseq() macro on L2CAP Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
It also fix a bug: we weren't acknowledging I-frames when P=1.
Note that when F=1 we are acknowledging packets before setting
RemoteBusy to False. The spec says we should do that in the opposite
order, but acknowledment of packets doesn't care about RemoteBusy flag
so we can do that in the order we want.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index f966ed3..d6667fa 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3490,7 +3490,9 @@ expected:
static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
{
struct l2cap_pinfo *pi = l2cap_pi(sk);
- u8 tx_seq = __get_reqseq(rx_control);
+
+ pi->expected_ack_seq = __get_reqseq(rx_control);
+ l2cap_drop_acked_frames(sk);
if (rx_control & L2CAP_CTRL_POLL) {
l2cap_send_i_or_rr_or_rnr(sk);
@@ -3498,8 +3500,6 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
} else if (rx_control & L2CAP_CTRL_FINAL) {
pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(sk);
if (pi->conn_state & L2CAP_CONN_REJ_ACT)
pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
@@ -3510,9 +3510,6 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
}
} else {
- pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(sk);
-
if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
(pi->unacked_frames > 0))
__mod_retrans_timer();
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 15/19] Bluetooth: Remove duplicate use of __get_reqseq() macro on L2CAP
2010-03-23 19:48 ` [PATCH 14/19] Bluetooth: Group the ack of I-frames into l2cap_data_channel_rrframe() Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 16/19] Bluetooth: Finish implementation for Rec RR (P=1) on ERTM Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
tx_seq var already has the value of __get_reqseq().
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index d6667fa..9546f59 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3529,7 +3529,7 @@ static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- pi->expected_ack_seq = __get_reqseq(rx_control);
+ pi->expected_ack_seq = tx_seq;
l2cap_drop_acked_frames(sk);
if (rx_control & L2CAP_CTRL_FINAL) {
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 16/19] Bluetooth: Finish implementation for Rec RR (P=1) on ERTM
2010-03-23 19:48 ` [PATCH 15/19] Bluetooth: Remove duplicate use of __get_reqseq() macro on L2CAP Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 17/19] Bluetooth: Ignore I-frames with a duplicated txSeq Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
Now the code handles the case under SREJ_SENT state.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 13 +++++++++++--
1 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 9546f59..85f97b9 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3495,8 +3495,17 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
l2cap_drop_acked_frames(sk);
if (rx_control & L2CAP_CTRL_POLL) {
- l2cap_send_i_or_rr_or_rnr(sk);
- pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
+ if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
+ (pi->unacked_frames > 0))
+ __mod_retrans_timer();
+
+ pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ l2cap_send_srejtail(sk);
+ } else {
+ l2cap_send_i_or_rr_or_rnr(sk);
+ pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+ }
} else if (rx_control & L2CAP_CTRL_FINAL) {
pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 17/19] Bluetooth: Ignore I-frames with a duplicated txSeq
2010-03-23 19:48 ` [PATCH 16/19] Bluetooth: Finish implementation for Rec RR (P=1) on ERTM Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 18/19] Bluetooth: Add timer to Acknowledge I-frames Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
L2CAP Enhanced Retransmission Mode shall ignore all I-frames with a
duplicated txSeq.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 85f97b9..b431dc5 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3413,6 +3413,13 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
if (tx_seq == pi->expected_tx_seq)
goto expected;
+ /* Check for duplicated tx_seq. This actually
+ * subtracts 1 from expected_tx_seq */
+ if (tx_seq == (pi->expected_tx_seq + 63) % 64) {
+ kfree_skb(skb);
+ return 0;
+ }
+
if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
struct srej_list *first;
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 18/19] Bluetooth: Add timer to Acknowledge I-frames
2010-03-23 19:48 ` [PATCH 17/19] Bluetooth: Ignore I-frames with a duplicated txSeq Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 19/19] Bluetooth: Move specific Basic Mode code to the right place Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
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>
---
include/net/bluetooth/l2cap.h | 4 ++++
net/bluetooth/l2cap.c | 15 +++++++++++++++
2 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index d9c20c3..48f10f4 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -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)
{
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index b431dc5..0dc7b95 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2230,6 +2230,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;
@@ -2242,6 +2251,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));
}
@@ -2970,6 +2981,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);
@@ -3000,6 +3012,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);
@@ -3487,6 +3500,8 @@ expected:
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);
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 19/19] Bluetooth: Move specific Basic Mode code to the right place
2010-03-23 19:48 ` [PATCH 18/19] Bluetooth: Add timer to Acknowledge I-frames Gustavo F. Padovan
@ 2010-03-23 19:48 ` Gustavo F. Padovan
2010-03-26 19:19 ` [PATCH 1/6] Bluetooth: Ignore Tx Window value with Streaming mode Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 01/10] Bluetooth: Ignore Tx Window value with Streaming mode Gustavo F. Padovan
0 siblings, 2 replies; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-23 19:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita, ulisses
Inside "case L2CAP_MODE_BASIC:" we don't need to check for sk_type and
L2CAP mode. So only the length check is fine.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 0dc7b95..8c8b5d9 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1660,11 +1660,6 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
if (msg->msg_flags & MSG_OOB)
return -EOPNOTSUPP;
- /* Check outgoing MTU */
- if (sk->sk_type == SOCK_SEQPACKET && pi->mode == L2CAP_MODE_BASIC &&
- len > pi->omtu)
- return -EINVAL;
-
lock_sock(sk);
if (sk->sk_state != BT_CONNECTED) {
@@ -1681,6 +1676,12 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
switch (pi->mode) {
case L2CAP_MODE_BASIC:
+ /* Check outgoing MTU */
+ if (len > pi->omtu) {
+ err = -EINVAL;
+ goto done;
+ }
+
/* Create a basic PDU */
skb = l2cap_create_basic_pdu(sk, msg, len);
if (IS_ERR(skb)) {
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 1/6] Bluetooth: Ignore Tx Window value with Streaming mode
2010-03-23 19:48 ` [PATCH 19/19] Bluetooth: Move specific Basic Mode code to the right place Gustavo F. Padovan
@ 2010-03-26 19:19 ` Gustavo F. Padovan
2010-03-26 19:19 ` [PATCH 2/6] Bluetooth: Read RFC conf option on a successful Conf RSP Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 01/10] Bluetooth: Ignore Tx Window value with Streaming mode Gustavo F. Padovan
1 sibling, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-26 19:19 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo
Tx Window value shall not be used with Streaming Mode and the receiver
of the config Request shall ignore its value.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 8c8b5d9..2cfad45 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2491,7 +2491,6 @@ done:
break;
case L2CAP_MODE_STREAMING:
- pi->remote_tx_win = rfc.txwin_size;
pi->max_pdu_size = rfc.max_pdu_size;
pi->conf_state |= L2CAP_CONF_MODE_DONE;
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 2/6] Bluetooth: Read RFC conf option on a successful Conf RSP
2010-03-26 19:19 ` [PATCH 1/6] Bluetooth: Ignore Tx Window value with Streaming mode Gustavo F. Padovan
@ 2010-03-26 19:19 ` Gustavo F. Padovan
2010-03-26 19:19 ` [PATCH 3/6] Bluetooth: Fix configuration of the MPS value Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-26 19:19 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo
On Enhanced Retransmission Mode and Streaming Mode a entity can send, on
a successful Conf RSP, new values for the RFC fields. For example, the
entity can send txWindow and MPS values less than the value received on
a Conf REQ.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/l2cap.c | 39 ++++++++++++++++++++++++++++++++++++++-
1 files changed, 38 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 2cfad45..40aff8d 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2598,6 +2598,42 @@ static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 fla
return ptr - data;
}
+static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
+{
+ struct l2cap_pinfo *pi = l2cap_pi(sk);
+ int type, olen;
+ unsigned long val;
+ struct l2cap_conf_rfc rfc;
+
+ BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
+
+ if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
+ return;
+
+ while (len >= L2CAP_CONF_OPT_SIZE) {
+ len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
+
+ switch (type) {
+ case L2CAP_CONF_RFC:
+ if (olen == sizeof(rfc))
+ memcpy(&rfc, (void *)val, olen);
+ goto done;
+ }
+ }
+
+done:
+ switch (rfc.mode) {
+ case L2CAP_MODE_ERTM:
+ pi->remote_tx_win = rfc.txwin_size;
+ pi->retrans_timeout = rfc.retrans_timeout;
+ pi->monitor_timeout = rfc.monitor_timeout;
+ pi->mps = le16_to_cpu(rfc.max_pdu_size);
+ break;
+ case L2CAP_MODE_STREAMING:
+ pi->mps = le16_to_cpu(rfc.max_pdu_size);
+ }
+}
+
static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
{
struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
@@ -2877,6 +2913,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
u16 scid, flags, result;
struct sock *sk;
+ int len = cmd->len - sizeof(*rsp);
scid = __le16_to_cpu(rsp->scid);
flags = __le16_to_cpu(rsp->flags);
@@ -2891,11 +2928,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
switch (result) {
case L2CAP_CONF_SUCCESS:
+ l2cap_conf_rfc_get(sk, rsp->data, len);
break;
case L2CAP_CONF_UNACCEPT:
if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
- int len = cmd->len - sizeof(*rsp);
char req[64];
if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 3/6] Bluetooth: Fix configuration of the MPS value
2010-03-26 19:19 ` [PATCH 2/6] Bluetooth: Read RFC conf option on a successful Conf RSP Gustavo F. Padovan
@ 2010-03-26 19:19 ` Gustavo F. Padovan
2010-03-26 19:19 ` [PATCH 4/6] Bluetooth: Add le16 macro to Retransmission and Monitor Timeouts values Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-26 19:19 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo
We were accepting values bigger than we can accept. This was leading
ERTM to drop packets because of wrong FCS checks.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 3 ++-
net/bluetooth/l2cap.c | 36 ++++++++++++++++++++----------------
2 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 48f10f4..0f4e423 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -343,7 +343,8 @@ struct l2cap_pinfo {
__u8 remote_max_tx;
__u16 retrans_timeout;
__u16 monitor_timeout;
- __u16 max_pdu_size;
+ __u16 remote_mps;
+ __u16 mps;
__le16 sport;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 40aff8d..4c98e3c 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1605,21 +1605,21 @@ static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, siz
__skb_queue_head_init(&sar_queue);
control = L2CAP_SDU_START;
- skb = l2cap_create_iframe_pdu(sk, msg, pi->max_pdu_size, control, len);
+ skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
if (IS_ERR(skb))
return PTR_ERR(skb);
__skb_queue_tail(&sar_queue, skb);
- len -= pi->max_pdu_size;
- size +=pi->max_pdu_size;
+ len -= pi->remote_mps;
+ size +=pi->remote_mps;
control = 0;
while (len > 0) {
size_t buflen;
- if (len > pi->max_pdu_size) {
+ if (len > pi->remote_mps) {
control |= L2CAP_SDU_CONTINUE;
- buflen = pi->max_pdu_size;
+ buflen = pi->remote_mps;
} else {
control |= L2CAP_SDU_END;
buflen = len;
@@ -1697,7 +1697,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
case L2CAP_MODE_ERTM:
case L2CAP_MODE_STREAMING:
/* Entire SDU fits into one PDU */
- if (len <= pi->max_pdu_size) {
+ if (len <= pi->remote_mps) {
control = L2CAP_SDU_UNSEGMENTED;
skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
if (IS_ERR(skb)) {
@@ -2326,7 +2326,7 @@ done:
rfc.monitor_timeout = 0;
rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
- rfc.max_pdu_size = pi->conn->mtu - 10;
+ rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
@@ -2349,7 +2349,7 @@ done:
rfc.monitor_timeout = 0;
rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
- rfc.max_pdu_size = pi->conn->mtu - 10;
+ rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
@@ -2478,7 +2478,10 @@ done:
case L2CAP_MODE_ERTM:
pi->remote_tx_win = rfc.txwin_size;
pi->remote_max_tx = rfc.max_transmit;
- pi->max_pdu_size = rfc.max_pdu_size;
+ if (rfc.max_pdu_size > pi->conn->mtu - 10)
+ rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
+
+ pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
@@ -2491,7 +2494,10 @@ done:
break;
case L2CAP_MODE_STREAMING:
- pi->max_pdu_size = rfc.max_pdu_size;
+ if (rfc.max_pdu_size > pi->conn->mtu - 10)
+ rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
+
+ pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
pi->conf_state |= L2CAP_CONF_MODE_DONE;
@@ -2570,11 +2576,10 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
pi->remote_tx_win = rfc.txwin_size;
pi->retrans_timeout = rfc.retrans_timeout;
pi->monitor_timeout = rfc.monitor_timeout;
- pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
+ pi->mps = le16_to_cpu(rfc.max_pdu_size);
break;
case L2CAP_MODE_STREAMING:
- pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
- break;
+ pi->mps = le16_to_cpu(rfc.max_pdu_size);
}
}
@@ -3758,7 +3763,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
* Receiver will miss it and start proper recovery
* procedures and ask retransmission.
*/
- if (len > L2CAP_DEFAULT_MAX_PDU_SIZE)
+ if (len > pi->mps)
goto drop;
if (l2cap_check_fcs(pi, skb))
@@ -3789,8 +3794,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
if (pi->fcs == L2CAP_FCS_CRC16)
len -= 2;
- if (len > L2CAP_DEFAULT_MAX_PDU_SIZE || len < 4
- || __is_sframe(control))
+ if (len > pi->mps || len < 4 || __is_sframe(control))
goto drop;
if (l2cap_check_fcs(pi, skb))
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 4/6] Bluetooth: Add le16 macro to Retransmission and Monitor Timeouts values
2010-03-26 19:19 ` [PATCH 3/6] Bluetooth: Fix configuration of the MPS value Gustavo F. Padovan
@ 2010-03-26 19:19 ` Gustavo F. Padovan
2010-03-26 19:19 ` [PATCH 5/6] Bluetooth: Check the SDU size against the MTU value Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-26 19:19 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo
Fix a possible problem with Big Endian machines.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/l2cap.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 4c98e3c..e6e2351 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2483,8 +2483,10 @@ done:
pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
- rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
- rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
+ rfc.retrans_timeout =
+ le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
+ rfc.monitor_timeout =
+ le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
pi->conf_state |= L2CAP_CONF_MODE_DONE;
@@ -2574,8 +2576,8 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
switch (rfc.mode) {
case L2CAP_MODE_ERTM:
pi->remote_tx_win = rfc.txwin_size;
- pi->retrans_timeout = rfc.retrans_timeout;
- pi->monitor_timeout = rfc.monitor_timeout;
+ pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
+ pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
pi->mps = le16_to_cpu(rfc.max_pdu_size);
break;
case L2CAP_MODE_STREAMING:
@@ -2630,8 +2632,8 @@ done:
switch (rfc.mode) {
case L2CAP_MODE_ERTM:
pi->remote_tx_win = rfc.txwin_size;
- pi->retrans_timeout = rfc.retrans_timeout;
- pi->monitor_timeout = rfc.monitor_timeout;
+ pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
+ pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
pi->mps = le16_to_cpu(rfc.max_pdu_size);
break;
case L2CAP_MODE_STREAMING:
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 5/6] Bluetooth: Check the SDU size against the MTU value
2010-03-26 19:19 ` [PATCH 4/6] Bluetooth: Add le16 macro to Retransmission and Monitor Timeouts values Gustavo F. Padovan
@ 2010-03-26 19:19 ` Gustavo F. Padovan
2010-03-26 19:19 ` [PATCH 6/6] Bluetooth: Close channel when an invalid ReqSeq is received Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-26 19:19 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo
If the SDU size is greater than the MTU something is wrong, so report
an error.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/l2cap.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index e6e2351..20c3f53 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3335,6 +3335,9 @@ static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 co
pi->sdu_len = get_unaligned_le16(skb->data);
skb_pull(skb, 2);
+ if (pi->sdu_len > pi->imtu)
+ break;
+
pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
if (!pi->sdu) {
err = -ENOMEM;
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 6/6] Bluetooth: Close channel when an invalid ReqSeq is received
2010-03-26 19:19 ` [PATCH 5/6] Bluetooth: Check the SDU size against the MTU value Gustavo F. Padovan
@ 2010-03-26 19:19 ` Gustavo F. Padovan
0 siblings, 0 replies; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-26 19:19 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo
When we receive a frame With-Invalid-ReqSeq and
With-Invalid-ReqSeq-Retrans we shall close the channel.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/l2cap.c | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 20c3f53..b978782 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3460,6 +3460,13 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
+ if ((req_seq - pi->expected_ack_seq) % 64 >
+ (pi->next_tx_seq - pi->expected_ack_seq) % 64) {
+ kfree_skb(skb);
+ l2cap_send_disconn_req(pi->conn, sk);
+ return 0;
+ }
+
if (L2CAP_CTRL_FINAL & rx_control) {
del_timer(&pi->monitor_timer);
if (pi->unacked_frames > 0)
@@ -3687,8 +3694,18 @@ static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
{
+ struct l2cap_pinfo *pi = l2cap_pi(sk);
+ u8 tx_seq = __get_reqseq(rx_control);
+
BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
+ if ((tx_seq - pi->expected_ack_seq) % 64 >
+ (pi->next_tx_seq - pi->expected_ack_seq) % 64) {
+ kfree_skb(skb);
+ l2cap_send_disconn_req(pi->conn, sk);
+ return 0;
+ }
+
if (L2CAP_CTRL_FINAL & rx_control) {
del_timer(&l2cap_pi(sk)->monitor_timer);
if (l2cap_pi(sk)->unacked_frames > 0)
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 01/10] Bluetooth: Ignore Tx Window value with Streaming mode
2010-03-23 19:48 ` [PATCH 19/19] Bluetooth: Move specific Basic Mode code to the right place Gustavo F. Padovan
2010-03-26 19:19 ` [PATCH 1/6] Bluetooth: Ignore Tx Window value with Streaming mode Gustavo F. Padovan
@ 2010-03-30 18:52 ` Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 02/10] Bluetooth: Read RFC conf option on a successful Conf RSP Gustavo F. Padovan
1 sibling, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-30 18:52 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
Tx Window value shall not be used with Streaming Mode and the receiver
of the config Request shall ignore its value.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 8c8b5d9..2cfad45 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2491,7 +2491,6 @@ done:
break;
case L2CAP_MODE_STREAMING:
- pi->remote_tx_win = rfc.txwin_size;
pi->max_pdu_size = rfc.max_pdu_size;
pi->conf_state |= L2CAP_CONF_MODE_DONE;
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 02/10] Bluetooth: Read RFC conf option on a successful Conf RSP
2010-03-30 18:52 ` [PATCH 01/10] Bluetooth: Ignore Tx Window value with Streaming mode Gustavo F. Padovan
@ 2010-03-30 18:52 ` Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 03/10] Bluetooth: Fix configuration of the MPS value Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-30 18:52 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
On Enhanced Retransmission Mode and Streaming Mode a entity can send, on
a successful Conf RSP, new values for the RFC fields. For example, the
entity can send txWindow and MPS values less than the value received on
a Conf REQ.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 39 ++++++++++++++++++++++++++++++++++++++-
1 files changed, 38 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 2cfad45..40aff8d 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2598,6 +2598,42 @@ static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 fla
return ptr - data;
}
+static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
+{
+ struct l2cap_pinfo *pi = l2cap_pi(sk);
+ int type, olen;
+ unsigned long val;
+ struct l2cap_conf_rfc rfc;
+
+ BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len);
+
+ if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
+ return;
+
+ while (len >= L2CAP_CONF_OPT_SIZE) {
+ len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
+
+ switch (type) {
+ case L2CAP_CONF_RFC:
+ if (olen == sizeof(rfc))
+ memcpy(&rfc, (void *)val, olen);
+ goto done;
+ }
+ }
+
+done:
+ switch (rfc.mode) {
+ case L2CAP_MODE_ERTM:
+ pi->remote_tx_win = rfc.txwin_size;
+ pi->retrans_timeout = rfc.retrans_timeout;
+ pi->monitor_timeout = rfc.monitor_timeout;
+ pi->mps = le16_to_cpu(rfc.max_pdu_size);
+ break;
+ case L2CAP_MODE_STREAMING:
+ pi->mps = le16_to_cpu(rfc.max_pdu_size);
+ }
+}
+
static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
{
struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
@@ -2877,6 +2913,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
u16 scid, flags, result;
struct sock *sk;
+ int len = cmd->len - sizeof(*rsp);
scid = __le16_to_cpu(rsp->scid);
flags = __le16_to_cpu(rsp->flags);
@@ -2891,11 +2928,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
switch (result) {
case L2CAP_CONF_SUCCESS:
+ l2cap_conf_rfc_get(sk, rsp->data, len);
break;
case L2CAP_CONF_UNACCEPT:
if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
- int len = cmd->len - sizeof(*rsp);
char req[64];
if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 03/10] Bluetooth: Fix configuration of the MPS value
2010-03-30 18:52 ` [PATCH 02/10] Bluetooth: Read RFC conf option on a successful Conf RSP Gustavo F. Padovan
@ 2010-03-30 18:52 ` Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 04/10] Bluetooth: Add le16 macro to Retransmission and Monitor Timeouts values Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-30 18:52 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
We were accepting values bigger than we can accept. This was leading
ERTM to drop packets because of wrong FCS checks.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 3 ++-
net/bluetooth/l2cap.c | 36 ++++++++++++++++++++----------------
2 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 48f10f4..0f4e423 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -343,7 +343,8 @@ struct l2cap_pinfo {
__u8 remote_max_tx;
__u16 retrans_timeout;
__u16 monitor_timeout;
- __u16 max_pdu_size;
+ __u16 remote_mps;
+ __u16 mps;
__le16 sport;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 40aff8d..4c98e3c 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1605,21 +1605,21 @@ static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, siz
__skb_queue_head_init(&sar_queue);
control = L2CAP_SDU_START;
- skb = l2cap_create_iframe_pdu(sk, msg, pi->max_pdu_size, control, len);
+ skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len);
if (IS_ERR(skb))
return PTR_ERR(skb);
__skb_queue_tail(&sar_queue, skb);
- len -= pi->max_pdu_size;
- size +=pi->max_pdu_size;
+ len -= pi->remote_mps;
+ size +=pi->remote_mps;
control = 0;
while (len > 0) {
size_t buflen;
- if (len > pi->max_pdu_size) {
+ if (len > pi->remote_mps) {
control |= L2CAP_SDU_CONTINUE;
- buflen = pi->max_pdu_size;
+ buflen = pi->remote_mps;
} else {
control |= L2CAP_SDU_END;
buflen = len;
@@ -1697,7 +1697,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
case L2CAP_MODE_ERTM:
case L2CAP_MODE_STREAMING:
/* Entire SDU fits into one PDU */
- if (len <= pi->max_pdu_size) {
+ if (len <= pi->remote_mps) {
control = L2CAP_SDU_UNSEGMENTED;
skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
if (IS_ERR(skb)) {
@@ -2326,7 +2326,7 @@ done:
rfc.monitor_timeout = 0;
rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
- rfc.max_pdu_size = pi->conn->mtu - 10;
+ rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
@@ -2349,7 +2349,7 @@ done:
rfc.monitor_timeout = 0;
rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
- rfc.max_pdu_size = pi->conn->mtu - 10;
+ rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
@@ -2478,7 +2478,10 @@ done:
case L2CAP_MODE_ERTM:
pi->remote_tx_win = rfc.txwin_size;
pi->remote_max_tx = rfc.max_transmit;
- pi->max_pdu_size = rfc.max_pdu_size;
+ if (rfc.max_pdu_size > pi->conn->mtu - 10)
+ rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
+
+ pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
@@ -2491,7 +2494,10 @@ done:
break;
case L2CAP_MODE_STREAMING:
- pi->max_pdu_size = rfc.max_pdu_size;
+ if (rfc.max_pdu_size > pi->conn->mtu - 10)
+ rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
+
+ pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
pi->conf_state |= L2CAP_CONF_MODE_DONE;
@@ -2570,11 +2576,10 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
pi->remote_tx_win = rfc.txwin_size;
pi->retrans_timeout = rfc.retrans_timeout;
pi->monitor_timeout = rfc.monitor_timeout;
- pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
+ pi->mps = le16_to_cpu(rfc.max_pdu_size);
break;
case L2CAP_MODE_STREAMING:
- pi->max_pdu_size = le16_to_cpu(rfc.max_pdu_size);
- break;
+ pi->mps = le16_to_cpu(rfc.max_pdu_size);
}
}
@@ -3758,7 +3763,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
* Receiver will miss it and start proper recovery
* procedures and ask retransmission.
*/
- if (len > L2CAP_DEFAULT_MAX_PDU_SIZE)
+ if (len > pi->mps)
goto drop;
if (l2cap_check_fcs(pi, skb))
@@ -3789,8 +3794,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
if (pi->fcs == L2CAP_FCS_CRC16)
len -= 2;
- if (len > L2CAP_DEFAULT_MAX_PDU_SIZE || len < 4
- || __is_sframe(control))
+ if (len > pi->mps || len < 4 || __is_sframe(control))
goto drop;
if (l2cap_check_fcs(pi, skb))
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 04/10] Bluetooth: Add le16 macro to Retransmission and Monitor Timeouts values
2010-03-30 18:52 ` [PATCH 03/10] Bluetooth: Fix configuration of the MPS value Gustavo F. Padovan
@ 2010-03-30 18:52 ` Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 05/10] Bluetooth: Check the SDU size against the MTU value Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-30 18:52 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
Fix a possible problem with Big Endian machines.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 4c98e3c..e6e2351 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2483,8 +2483,10 @@ done:
pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
- rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
- rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
+ rfc.retrans_timeout =
+ le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
+ rfc.monitor_timeout =
+ le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
pi->conf_state |= L2CAP_CONF_MODE_DONE;
@@ -2574,8 +2576,8 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
switch (rfc.mode) {
case L2CAP_MODE_ERTM:
pi->remote_tx_win = rfc.txwin_size;
- pi->retrans_timeout = rfc.retrans_timeout;
- pi->monitor_timeout = rfc.monitor_timeout;
+ pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
+ pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
pi->mps = le16_to_cpu(rfc.max_pdu_size);
break;
case L2CAP_MODE_STREAMING:
@@ -2630,8 +2632,8 @@ done:
switch (rfc.mode) {
case L2CAP_MODE_ERTM:
pi->remote_tx_win = rfc.txwin_size;
- pi->retrans_timeout = rfc.retrans_timeout;
- pi->monitor_timeout = rfc.monitor_timeout;
+ pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
+ pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
pi->mps = le16_to_cpu(rfc.max_pdu_size);
break;
case L2CAP_MODE_STREAMING:
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 05/10] Bluetooth: Check the SDU size against the MTU value
2010-03-30 18:52 ` [PATCH 04/10] Bluetooth: Add le16 macro to Retransmission and Monitor Timeouts values Gustavo F. Padovan
@ 2010-03-30 18:52 ` Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 06/10] Bluetooth: Send Ack after clear the SREJ list Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-30 18:52 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
If the SDU size is greater than the MTU something is wrong, so report
an error.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
[jprvita@profusion.mobi: set err to appropriate errno value]
Signed-off-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index e6e2351..6196f2c 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3335,6 +3335,11 @@ static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 co
pi->sdu_len = get_unaligned_le16(skb->data);
skb_pull(skb, 2);
+ if (pi->sdu_len > pi->imtu) {
+ err = -EMSGSIZE;
+ break;
+ }
+
pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
if (!pi->sdu) {
err = -ENOMEM;
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 06/10] Bluetooth: Send Ack after clear the SREJ list
2010-03-30 18:52 ` [PATCH 05/10] Bluetooth: Check the SDU size against the MTU value Gustavo F. Padovan
@ 2010-03-30 18:52 ` Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 07/10] Bluetooth: Add sockopt configuration for txWindow on L2CAP Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-30 18:52 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
As specified by Bluetooth 3.0 spec we shall send an acknowledgment using
the Send-Ack() after clear the SREJ list.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 6196f2c..4580fcf 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3497,6 +3497,7 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
if (list_empty(SREJ_LIST(sk))) {
pi->buffer_seq = pi->buffer_seq_srej;
pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
+ l2cap_send_ack(pi);
}
} else {
struct srej_list *l;
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 07/10] Bluetooth: Add sockopt configuration for txWindow on L2CAP
2010-03-30 18:52 ` [PATCH 06/10] Bluetooth: Send Ack after clear the SREJ list Gustavo F. Padovan
@ 2010-03-30 18:52 ` Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 08/10] Bluetooth: Change acknowledgement to use the value of txWindow Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-30 18:52 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
Now can set/get Transmission Window size via sockopt.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 2 ++
net/bluetooth/l2cap.c | 7 ++++++-
2 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 0f4e423..fdbe8ee 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -56,6 +56,7 @@ struct l2cap_options {
__u16 flush_to;
__u8 mode;
__u8 fcs;
+ __u16 txwin_size;
};
#define L2CAP_CONNINFO 0x02
@@ -339,6 +340,7 @@ struct l2cap_pinfo {
__u8 ident;
+ __u8 tx_win;
__u8 remote_tx_win;
__u8 remote_max_tx;
__u16 retrans_timeout;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 4580fcf..79c9ac7 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -782,6 +782,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
pi->omtu = l2cap_pi(parent)->omtu;
pi->mode = l2cap_pi(parent)->mode;
pi->fcs = l2cap_pi(parent)->fcs;
+ pi->tx_win = l2cap_pi(parent)->tx_win;
pi->sec_level = l2cap_pi(parent)->sec_level;
pi->role_switch = l2cap_pi(parent)->role_switch;
pi->force_reliable = l2cap_pi(parent)->force_reliable;
@@ -790,6 +791,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
pi->omtu = 0;
pi->mode = L2CAP_MODE_BASIC;
pi->fcs = L2CAP_FCS_CRC16;
+ pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
pi->sec_level = BT_SECURITY_LOW;
pi->role_switch = 0;
pi->force_reliable = 0;
@@ -1778,6 +1780,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
opts.flush_to = l2cap_pi(sk)->flush_to;
opts.mode = l2cap_pi(sk)->mode;
opts.fcs = l2cap_pi(sk)->fcs;
+ opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
len = min_t(unsigned int, sizeof(opts), optlen);
if (copy_from_user((char *) &opts, optval, len)) {
@@ -1789,6 +1792,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
l2cap_pi(sk)->omtu = opts.omtu;
l2cap_pi(sk)->mode = opts.mode;
l2cap_pi(sk)->fcs = opts.fcs;
+ l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
break;
case L2CAP_LM:
@@ -1903,6 +1907,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
opts.flush_to = l2cap_pi(sk)->flush_to;
opts.mode = l2cap_pi(sk)->mode;
opts.fcs = l2cap_pi(sk)->fcs;
+ opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
len = min_t(unsigned int, len, sizeof(opts));
if (copy_to_user(optval, (char *) &opts, len))
@@ -2320,7 +2325,7 @@ done:
case L2CAP_MODE_ERTM:
rfc.mode = L2CAP_MODE_ERTM;
- rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
+ rfc.txwin_size = pi->tx_win;
rfc.max_transmit = max_transmit;
rfc.retrans_timeout = 0;
rfc.monitor_timeout = 0;
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 08/10] Bluetooth: Change acknowledgement to use the value of txWindow
2010-03-30 18:52 ` [PATCH 07/10] Bluetooth: Add sockopt configuration for txWindow on L2CAP Gustavo F. Padovan
@ 2010-03-30 18:52 ` Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 09/10] Bluetooth: Add module parameter for txWindow size on L2CAP Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-30 18:52 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
Now that we can set the txWindow we need to change the acknowledgement
procedure to ack after each (pi->txWindow/6 + 1). The plus 1 is to avoid
the zero value.
It also renames pi->num_to_ack to a better name: pi->num_acked.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 3 +--
net/bluetooth/l2cap.c | 7 ++++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index fdbe8ee..44dd961 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -30,7 +30,6 @@
#define L2CAP_DEFAULT_MIN_MTU 48
#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_TX 3
#define L2CAP_DEFAULT_RETRANS_TO 1000 /* 1 second */
#define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */
@@ -333,7 +332,7 @@ struct l2cap_pinfo {
__u8 frames_sent;
__u8 unacked_frames;
__u8 retry_count;
- __u8 num_to_ack;
+ __u8 num_acked;
__u16 sdu_len;
__u16 partial_sdu_len;
struct sk_buff *sdu;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 79c9ac7..8a6d073 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2250,7 +2250,7 @@ static inline void l2cap_ertm_init(struct sock *sk)
l2cap_pi(sk)->expected_ack_seq = 0;
l2cap_pi(sk)->unacked_frames = 0;
l2cap_pi(sk)->buffer_seq = 0;
- l2cap_pi(sk)->num_to_ack = 0;
+ l2cap_pi(sk)->num_acked = 0;
l2cap_pi(sk)->frames_sent = 0;
setup_timer(&l2cap_pi(sk)->retrans_timer,
@@ -3463,6 +3463,7 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
u8 tx_seq = __get_txseq(rx_control);
u8 req_seq = __get_reqseq(rx_control);
u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
+ int num_to_ack = (pi->tx_win/6) + 1;
int err = 0;
BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
@@ -3557,8 +3558,8 @@ expected:
__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)
+ pi->num_acked = (pi->num_acked + 1) % num_to_ack;
+ if (pi->num_acked == num_to_ack - 1)
l2cap_send_ack(pi);
return 0;
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 09/10] Bluetooth: Add module parameter for txWindow size on L2CAP
2010-03-30 18:52 ` [PATCH 08/10] Bluetooth: Change acknowledgement to use the value of txWindow Gustavo F. Padovan
@ 2010-03-30 18:52 ` Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 10/10] Bluetooth: Enable option to configure Max Transmission value via sockopt Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-30 18:52 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
Very useful for testing purposes.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
[jprvita@profusion.mobi: improved parameter description]
Signed-off-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/l2cap.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 8a6d073..32824b9 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -57,6 +57,7 @@
static int enable_ertm = 0;
static int max_transmit = L2CAP_DEFAULT_MAX_TX;
+static int tx_window = L2CAP_DEFAULT_TX_WINDOW;
static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
static u8 l2cap_fixed_chan[8] = { 0x02, };
@@ -791,7 +792,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
pi->omtu = 0;
pi->mode = L2CAP_MODE_BASIC;
pi->fcs = L2CAP_FCS_CRC16;
- pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
+ pi->tx_win = tx_window;
pi->sec_level = BT_SECURITY_LOW;
pi->role_switch = 0;
pi->force_reliable = 0;
@@ -4301,6 +4302,9 @@ MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
module_param(max_transmit, uint, 0644);
MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)");
+module_param(tx_window, uint, 0644);
+MODULE_PARM_DESC(tx_window, "Transmission window size value (default = 63)");
+
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
MODULE_VERSION(VERSION);
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 10/10] Bluetooth: Enable option to configure Max Transmission value via sockopt
2010-03-30 18:52 ` [PATCH 09/10] Bluetooth: Add module parameter for txWindow size on L2CAP Gustavo F. Padovan
@ 2010-03-30 18:52 ` Gustavo F. Padovan
0 siblings, 0 replies; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-03-30 18:52 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
With the sockopt extension we can set a per-channel MaxTx value.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 2 ++
net/bluetooth/l2cap.c | 7 ++++++-
2 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 44dd961..15f6e55 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -55,6 +55,7 @@ struct l2cap_options {
__u16 flush_to;
__u8 mode;
__u8 fcs;
+ __u8 max_tx;
__u16 txwin_size;
};
@@ -340,6 +341,7 @@ struct l2cap_pinfo {
__u8 ident;
__u8 tx_win;
+ __u8 max_tx;
__u8 remote_tx_win;
__u8 remote_max_tx;
__u16 retrans_timeout;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 32824b9..d5a34a5 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -783,6 +783,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
pi->omtu = l2cap_pi(parent)->omtu;
pi->mode = l2cap_pi(parent)->mode;
pi->fcs = l2cap_pi(parent)->fcs;
+ pi->max_tx = l2cap_pi(parent)->max_tx;
pi->tx_win = l2cap_pi(parent)->tx_win;
pi->sec_level = l2cap_pi(parent)->sec_level;
pi->role_switch = l2cap_pi(parent)->role_switch;
@@ -791,6 +792,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
pi->imtu = L2CAP_DEFAULT_MTU;
pi->omtu = 0;
pi->mode = L2CAP_MODE_BASIC;
+ pi->max_tx = max_transmit;
pi->fcs = L2CAP_FCS_CRC16;
pi->tx_win = tx_window;
pi->sec_level = BT_SECURITY_LOW;
@@ -1781,6 +1783,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
opts.flush_to = l2cap_pi(sk)->flush_to;
opts.mode = l2cap_pi(sk)->mode;
opts.fcs = l2cap_pi(sk)->fcs;
+ opts.max_tx = l2cap_pi(sk)->max_tx;
opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
len = min_t(unsigned int, sizeof(opts), optlen);
@@ -1793,6 +1796,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
l2cap_pi(sk)->omtu = opts.omtu;
l2cap_pi(sk)->mode = opts.mode;
l2cap_pi(sk)->fcs = opts.fcs;
+ l2cap_pi(sk)->max_tx = opts.max_tx;
l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
break;
@@ -1908,6 +1912,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
opts.flush_to = l2cap_pi(sk)->flush_to;
opts.mode = l2cap_pi(sk)->mode;
opts.fcs = l2cap_pi(sk)->fcs;
+ opts.max_tx = l2cap_pi(sk)->max_tx;
opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
len = min_t(unsigned int, len, sizeof(opts));
@@ -2327,7 +2332,7 @@ done:
case L2CAP_MODE_ERTM:
rfc.mode = L2CAP_MODE_ERTM;
rfc.txwin_size = pi->tx_win;
- rfc.max_transmit = max_transmit;
+ rfc.max_transmit = pi->max_tx;
rfc.retrans_timeout = 0;
rfc.monitor_timeout = 0;
rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
end of thread, other threads:[~2010-03-30 18:52 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-23 19:48 [PATCH 00/19] Patches for eL2CAP Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 01/19] Bluetooth: Implement 'Send IorRRorRNR' event Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 02/19] Bluetooth: Support case with F bit set under WAIT_F state Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 03/19] Bluetooth: Fix memory leak of S-frames into L2CAP Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 04/19] Bluetooth: Check the minimum {I,S}-frame size " Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 05/19] Bluetooth: Check if SDU size is greater than MTU on L2CAP Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 06/19] Bluetooth: Fix expected_tx_seq calculation " Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 07/19] Bluetooth: Implement SendAck() Action on ERTM Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 08/19] Bluetooth: Move set of P-bit to l2cap_send_sframe() Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 09/19] Bluetooth: Add Recv RR (P=0)(F=0) for SREJ_SENT state on ERTM Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 10/19] Bluetooth: Use a l2cap_pinfo struct instead l2cap_pi() macro Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 11/19] Bluetooth: Fix ACL MTU issue Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 12/19] Bluetooth: Split l2cap_data_channel_sframe() Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 13/19] Bluetooth: Handle all cases of receipt of RNR-frames into L2CAP Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 14/19] Bluetooth: Group the ack of I-frames into l2cap_data_channel_rrframe() Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 15/19] Bluetooth: Remove duplicate use of __get_reqseq() macro on L2CAP Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 16/19] Bluetooth: Finish implementation for Rec RR (P=1) on ERTM Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 17/19] Bluetooth: Ignore I-frames with a duplicated txSeq Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 18/19] Bluetooth: Add timer to Acknowledge I-frames Gustavo F. Padovan
2010-03-23 19:48 ` [PATCH 19/19] Bluetooth: Move specific Basic Mode code to the right place Gustavo F. Padovan
2010-03-26 19:19 ` [PATCH 1/6] Bluetooth: Ignore Tx Window value with Streaming mode Gustavo F. Padovan
2010-03-26 19:19 ` [PATCH 2/6] Bluetooth: Read RFC conf option on a successful Conf RSP Gustavo F. Padovan
2010-03-26 19:19 ` [PATCH 3/6] Bluetooth: Fix configuration of the MPS value Gustavo F. Padovan
2010-03-26 19:19 ` [PATCH 4/6] Bluetooth: Add le16 macro to Retransmission and Monitor Timeouts values Gustavo F. Padovan
2010-03-26 19:19 ` [PATCH 5/6] Bluetooth: Check the SDU size against the MTU value Gustavo F. Padovan
2010-03-26 19:19 ` [PATCH 6/6] Bluetooth: Close channel when an invalid ReqSeq is received Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 01/10] Bluetooth: Ignore Tx Window value with Streaming mode Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 02/10] Bluetooth: Read RFC conf option on a successful Conf RSP Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 03/10] Bluetooth: Fix configuration of the MPS value Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 04/10] Bluetooth: Add le16 macro to Retransmission and Monitor Timeouts values Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 05/10] Bluetooth: Check the SDU size against the MTU value Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 06/10] Bluetooth: Send Ack after clear the SREJ list Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 07/10] Bluetooth: Add sockopt configuration for txWindow on L2CAP Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 08/10] Bluetooth: Change acknowledgement to use the value of txWindow Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 09/10] Bluetooth: Add module parameter for txWindow size on L2CAP Gustavo F. Padovan
2010-03-30 18:52 ` [PATCH 10/10] Bluetooth: Enable option to configure Max Transmission value via sockopt Gustavo F. Padovan
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.