* Patches for eL2CAP
@ 2010-04-01 20:23 Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 01/34] Bluetooth: Implement 'Send IorRRorRNR' event Gustavo F. Padovan
2010-04-19 20:15 ` Patches for eL2CAP Gustavo F. Padovan
0 siblings, 2 replies; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
Hi Marcel,
Here are all patches rebased against -rc3. Most of then are a resend unless
the last five patches.
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 01/34] Bluetooth: Implement 'Send IorRRorRNR' event
2010-04-01 20:23 Patches for eL2CAP Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 02/34] Bluetooth: Support case with F bit set under WAIT_F state Gustavo F. Padovan
2010-04-19 20:15 ` Patches for eL2CAP Gustavo F. Padovan
1 sibling, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Support case with F bit set under WAIT_F state.
2010-04-01 20:23 ` [PATCH 01/34] Bluetooth: Implement 'Send IorRRorRNR' event Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 03/34] 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-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Fix memory leak of S-frames into L2CAP
2010-04-01 20:23 ` [PATCH 02/34] Bluetooth: Support case with F bit set under WAIT_F state Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 04/34] Bluetooth: Check the minimum {I,S}-frame size " Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Check the minimum {I,S}-frame size into L2CAP
2010-04-01 20:23 ` [PATCH 03/34] Bluetooth: Fix memory leak of S-frames into L2CAP Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 05/34] 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-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Check if SDU size is greater than MTU on L2CAP
2010-04-01 20:23 ` [PATCH 04/34] Bluetooth: Check the minimum {I,S}-frame size " Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 06/34] Bluetooth: Fix expected_tx_seq calculation " Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Fix expected_tx_seq calculation on L2CAP
2010-04-01 20:23 ` [PATCH 05/34] Bluetooth: Check if SDU size is greater than MTU on L2CAP Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 07/34] Bluetooth: Implement SendAck() Action on ERTM Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Implement SendAck() Action on ERTM.
2010-04-01 20:23 ` [PATCH 06/34] Bluetooth: Fix expected_tx_seq calculation " Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 08/34] 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-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Move set of P-bit to l2cap_send_sframe()
2010-04-01 20:23 ` [PATCH 07/34] Bluetooth: Implement SendAck() Action on ERTM Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 09/34] 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-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Add Recv RR (P=0)(F=0) for SREJ_SENT state on ERTM
2010-04-01 20:23 ` [PATCH 08/34] Bluetooth: Move set of P-bit to l2cap_send_sframe() Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 10/34] 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-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Use a l2cap_pinfo struct instead l2cap_pi() macro
2010-04-01 20:23 ` [PATCH 09/34] Bluetooth: Add Recv RR (P=0)(F=0) for SREJ_SENT state on ERTM Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 11/34] Bluetooth: Fix ACL MTU issue Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Fix ACL MTU issue
2010-04-01 20:23 ` [PATCH 10/34] Bluetooth: Use a l2cap_pinfo struct instead l2cap_pi() macro Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 12/34] Bluetooth: Split l2cap_data_channel_sframe() Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Split l2cap_data_channel_sframe()
2010-04-01 20:23 ` [PATCH 11/34] Bluetooth: Fix ACL MTU issue Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 13/34] 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-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Handle all cases of receipt of RNR-frames into L2CAP
2010-04-01 20:23 ` [PATCH 12/34] Bluetooth: Split l2cap_data_channel_sframe() Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 14/34] 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-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Group the ack of I-frames into l2cap_data_channel_rrframe()
2010-04-01 20:23 ` [PATCH 13/34] Bluetooth: Handle all cases of receipt of RNR-frames into L2CAP Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 15/34] 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-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Remove duplicate use of __get_reqseq() macro on L2CAP
2010-04-01 20:23 ` [PATCH 14/34] Bluetooth: Group the ack of I-frames into l2cap_data_channel_rrframe() Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 16/34] 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-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Finish implementation for Rec RR (P=1) on ERTM
2010-04-01 20:23 ` [PATCH 15/34] Bluetooth: Remove duplicate use of __get_reqseq() macro on L2CAP Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 17/34] Bluetooth: Ignore I-frames with a duplicated txSeq Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Ignore I-frames with a duplicated txSeq
2010-04-01 20:23 ` [PATCH 16/34] Bluetooth: Finish implementation for Rec RR (P=1) on ERTM Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 18/34] Bluetooth: Add timer to Acknowledge I-frames Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Add timer to Acknowledge I-frames
2010-04-01 20:23 ` [PATCH 17/34] Bluetooth: Ignore I-frames with a duplicated txSeq Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 19/34] 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-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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/34] Bluetooth: Move specific Basic Mode code to the right place
2010-04-01 20:23 ` [PATCH 18/34] Bluetooth: Add timer to Acknowledge I-frames Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 20/34] Bluetooth: Ignore Tx Window value with Streaming mode Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
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 20/34] Bluetooth: Ignore Tx Window value with Streaming mode
2010-04-01 20:23 ` [PATCH 19/34] Bluetooth: Move specific Basic Mode code to the right place Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 21/34] Bluetooth: Read RFC conf option on a successful Conf RSP Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 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 21/34] Bluetooth: Read RFC conf option on a successful Conf RSP
2010-04-01 20:23 ` [PATCH 20/34] Bluetooth: Ignore Tx Window value with Streaming mode Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 22/34] Bluetooth: Fix configuration of the MPS value Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 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 22/34] Bluetooth: Fix configuration of the MPS value
2010-04-01 20:23 ` [PATCH 21/34] Bluetooth: Read RFC conf option on a successful Conf RSP Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 23/34] 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-04-01 20:23 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 23/34] Bluetooth: Add le16 macro to Retransmission and Monitor Timeouts values
2010-04-01 20:23 ` [PATCH 22/34] Bluetooth: Fix configuration of the MPS value Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 24/34] 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-04-01 20:23 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 24/34] Bluetooth: Check the SDU size against the MTU value
2010-04-01 20:23 ` [PATCH 23/34] Bluetooth: Add le16 macro to Retransmission and Monitor Timeouts values Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 25/34] Bluetooth: Send Ack after clear the SREJ list Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 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 25/34] Bluetooth: Send Ack after clear the SREJ list
2010-04-01 20:23 ` [PATCH 24/34] Bluetooth: Check the SDU size against the MTU value Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 26/34] Bluetooth: Add sockopt configuration for txWindow on L2CAP Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 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 26/34] Bluetooth: Add sockopt configuration for txWindow on L2CAP
2010-04-01 20:23 ` [PATCH 25/34] Bluetooth: Send Ack after clear the SREJ list Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 27/34] 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-04-01 20:23 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 27/34] Bluetooth: Change acknowledgement to use the value of txWindow
2010-04-01 20:23 ` [PATCH 26/34] Bluetooth: Add sockopt configuration for txWindow on L2CAP Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 28/34] 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-04-01 20:23 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 28/34] Bluetooth: Add module parameter for txWindow size on L2CAP
2010-04-01 20:23 ` [PATCH 27/34] Bluetooth: Change acknowledgement to use the value of txWindow Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 29/34] 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-04-01 20:23 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 29/34] Bluetooth: Enable option to configure Max Transmission value via sockopt
2010-04-01 20:23 ` [PATCH 28/34] Bluetooth: Add module parameter for txWindow size on L2CAP Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 30/34] Bluetooth: Make hci_send_acl() void Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 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>
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 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
* [PATCH 30/34] Bluetooth: Make hci_send_acl() void
2010-04-01 20:23 ` [PATCH 29/34] Bluetooth: Enable option to configure Max Transmission value via sockopt Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 31/34] Bluetooth: Make hci_send_sco() void Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
hci_send_acl can't fail, so we can make it void. This patch changes
that and all the funcions that use hci_send_acl().
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
include/net/bluetooth/hci_core.h | 2 +-
net/bluetooth/hci_core.c | 4 +-
net/bluetooth/l2cap.c | 67 +++++++++++++-------------------------
3 files changed, 26 insertions(+), 47 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ce3c99e..21ff787 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -636,7 +636,7 @@ int hci_register_notifier(struct notifier_block *nb);
int hci_unregister_notifier(struct notifier_block *nb);
int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
-int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
+void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 4ad2319..cc8074b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1260,7 +1260,7 @@ static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
hdr->dlen = cpu_to_le16(len);
}
-int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
+void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
{
struct hci_dev *hdev = conn->hdev;
struct sk_buff *list;
@@ -1303,7 +1303,7 @@ int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
tasklet_schedule(&hdev->tx_task);
- return 0;
+ return;
}
EXPORT_SYMBOL(hci_send_acl);
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index d5a34a5..12a93af 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -326,19 +326,19 @@ static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
return id;
}
-static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
+static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
{
struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
BT_DBG("code 0x%2.2x", code);
if (!skb)
- return -ENOMEM;
+ return;
- return hci_send_acl(conn->hcon, skb, 0);
+ hci_send_acl(conn->hcon, skb, 0);
}
-static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
+static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
{
struct sk_buff *skb;
struct l2cap_hdr *lh;
@@ -365,7 +365,7 @@ static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
skb = bt_skb_alloc(count, GFP_ATOMIC);
if (!skb)
- return -ENOMEM;
+ return;
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
@@ -377,10 +377,10 @@ static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
put_unaligned_le16(fcs, skb_put(skb, 2));
}
- return hci_send_acl(pi->conn->hcon, skb, 0);
+ hci_send_acl(pi->conn->hcon, skb, 0);
}
-static inline int l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
+static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
{
if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY)
control |= L2CAP_SUPER_RCV_NOT_READY;
@@ -389,7 +389,7 @@ static inline int l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
- return l2cap_send_sframe(pi, control);
+ l2cap_send_sframe(pi, control);
}
static void l2cap_do_start(struct sock *sk)
@@ -1277,18 +1277,13 @@ static void l2cap_drop_acked_frames(struct sock *sk)
return;
}
-static inline int l2cap_do_send(struct sock *sk, struct sk_buff *skb)
+static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
{
struct l2cap_pinfo *pi = l2cap_pi(sk);
- int err;
BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
- err = hci_send_acl(pi->conn->hcon, skb, 0);
- if (err < 0)
- kfree_skb(skb);
-
- return err;
+ hci_send_acl(pi->conn->hcon, skb, 0);
}
static int l2cap_streaming_send(struct sock *sk)
@@ -1296,7 +1291,6 @@ static int l2cap_streaming_send(struct sock *sk)
struct sk_buff *skb, *tx_skb;
struct l2cap_pinfo *pi = l2cap_pi(sk);
u16 control, fcs;
- int err;
while ((skb = sk->sk_send_head)) {
tx_skb = skb_clone(skb, GFP_ATOMIC);
@@ -1310,11 +1304,7 @@ static int l2cap_streaming_send(struct sock *sk)
put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
}
- err = l2cap_do_send(sk, tx_skb);
- if (err < 0) {
- l2cap_send_disconn_req(pi->conn, sk);
- return err;
- }
+ l2cap_do_send(sk, tx_skb);
pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
@@ -1334,7 +1324,6 @@ static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
struct l2cap_pinfo *pi = l2cap_pi(sk);
struct sk_buff *skb, *tx_skb;
u16 control, fcs;
- int err;
skb = skb_peek(TX_QUEUE(sk));
do {
@@ -1363,11 +1352,7 @@ static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
}
- err = l2cap_do_send(sk, tx_skb);
- if (err < 0) {
- l2cap_send_disconn_req(pi->conn, sk);
- return err;
- }
+ l2cap_do_send(sk, tx_skb);
break;
} while(1);
return 0;
@@ -1378,7 +1363,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, nsent = 0;
+ int nsent = 0;
if (pi->conn_state & L2CAP_CONN_WAIT_F)
return 0;
@@ -1411,11 +1396,8 @@ static int l2cap_ertm_send(struct sock *sk)
put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
}
- err = l2cap_do_send(sk, tx_skb);
- if (err < 0) {
- l2cap_send_disconn_req(pi->conn, sk);
- return err;
- }
+ l2cap_do_send(sk, tx_skb);
+
__mod_retrans_timer();
bt_cb(skb)->tx_seq = pi->next_tx_seq;
@@ -1435,7 +1417,7 @@ static int l2cap_ertm_send(struct sock *sk)
return nsent;
}
-static int l2cap_send_ack(struct l2cap_pinfo *pi)
+static void l2cap_send_ack(struct l2cap_pinfo *pi)
{
struct sock *sk = (struct sock *)pi;
u16 control = 0;
@@ -1444,15 +1426,15 @@ static int l2cap_send_ack(struct l2cap_pinfo *pi)
if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
control |= L2CAP_SUPER_RCV_NOT_READY;
- return l2cap_send_sframe(pi, control);
+ l2cap_send_sframe(pi, control);
+ return;
} else if (l2cap_ertm_send(sk) == 0) {
control |= L2CAP_SUPER_RCV_READY;
- return l2cap_send_sframe(pi, control);
+ l2cap_send_sframe(pi, control);
}
- return 0;
}
-static int l2cap_send_srejtail(struct sock *sk)
+static void l2cap_send_srejtail(struct sock *sk)
{
struct srej_list *tail;
u16 control;
@@ -1464,8 +1446,6 @@ static int l2cap_send_srejtail(struct sock *sk)
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)
@@ -1675,7 +1655,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
/* Connectionless channel */
if (sk->sk_type == SOCK_DGRAM) {
skb = l2cap_create_connless_pdu(sk, msg, len);
- err = l2cap_do_send(sk, skb);
+ l2cap_do_send(sk, skb);
goto done;
}
@@ -1694,9 +1674,8 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
goto done;
}
- err = l2cap_do_send(sk, skb);
- if (!err)
- err = len;
+ l2cap_do_send(sk, skb);
+ err = len;
break;
case L2CAP_MODE_ERTM:
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 31/34] Bluetooth: Make hci_send_sco() void
2010-04-01 20:23 ` [PATCH 30/34] Bluetooth: Make hci_send_acl() void Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 32/34] Bluetooth: Return the data length sent on connectionless channels Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
It also removes an unneeded check for the MTU. The is done before on
sco_send_frame()
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
include/net/bluetooth/hci_core.h | 2 +-
net/bluetooth/hci_core.c | 9 +--------
net/bluetooth/sco.c | 3 +--
3 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 21ff787..4511df2 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -637,7 +637,7 @@ int hci_unregister_notifier(struct notifier_block *nb);
int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
-int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
+void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index cc8074b..904f1e8 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1308,18 +1308,13 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
EXPORT_SYMBOL(hci_send_acl);
/* Send SCO data */
-int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
+void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
{
struct hci_dev *hdev = conn->hdev;
struct hci_sco_hdr hdr;
BT_DBG("%s len %d", hdev->name, skb->len);
- if (skb->len > hdev->sco_mtu) {
- kfree_skb(skb);
- return -EINVAL;
- }
-
hdr.handle = cpu_to_le16(conn->handle);
hdr.dlen = skb->len;
@@ -1332,8 +1327,6 @@ int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
skb_queue_tail(&conn->data_q, skb);
tasklet_schedule(&hdev->tx_task);
-
- return 0;
}
EXPORT_SYMBOL(hci_send_sco);
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index e5b16b7..50a9af8 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -249,8 +249,7 @@ static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
goto fail;
}
- if ((err = hci_send_sco(conn->hcon, skb)) < 0)
- return err;
+ hci_send_sco(conn->hcon, skb);
return count;
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 32/34] Bluetooth: Return the data length sent on connectionless channels
2010-04-01 20:23 ` [PATCH 31/34] Bluetooth: Make hci_send_sco() void Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 33/34] Bluetooth: Clean sco_send_frame() flow Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
Although the data was sent, userspace was receiving a "Send failed"
error.
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 12a93af..c699fe9 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1656,6 +1656,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
if (sk->sk_type == SOCK_DGRAM) {
skb = l2cap_create_connless_pdu(sk, msg, len);
l2cap_do_send(sk, skb);
+ err = len;
goto done;
}
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 33/34] Bluetooth: Clean sco_send_frame() flow
2010-04-01 20:23 ` [PATCH 32/34] Bluetooth: Return the data length sent on connectionless channels Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 34/34] Bluetooth: Remove unneeded check for MTU on sco_send_frame() Gustavo F. Padovan
0 siblings, 1 reply; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/sco.c | 8 ++------
1 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 50a9af8..1dc7856 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -245,17 +245,13 @@ static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
return err;
if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
- err = -EFAULT;
- goto fail;
+ kfree_skb(skb);
+ return -EFAULT;
}
hci_send_sco(conn->hcon, skb);
return count;
-
-fail:
- kfree_skb(skb);
- return err;
}
static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 34/34] Bluetooth: Remove unneeded check for MTU on sco_send_frame()
2010-04-01 20:23 ` [PATCH 33/34] Bluetooth: Clean sco_send_frame() flow Gustavo F. Padovan
@ 2010-04-01 20:23 ` Gustavo F. Padovan
0 siblings, 0 replies; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-01 20:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, jprvita
We have
count = min_t(unsigned int, conn->mtu, len);
there, so no need to return on len > conn->mtu.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
---
net/bluetooth/sco.c | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 1dc7856..e2da719 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -234,10 +234,6 @@ static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
struct sk_buff *skb;
int err, count;
- /* Check outgoing MTU */
- if (len > conn->mtu)
- return -EINVAL;
-
BT_DBG("sk %p len %d", sk, len);
count = min_t(unsigned int, conn->mtu, len);
--
1.6.4.4
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: Patches for eL2CAP
2010-04-01 20:23 Patches for eL2CAP Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 01/34] Bluetooth: Implement 'Send IorRRorRNR' event Gustavo F. Padovan
@ 2010-04-19 20:15 ` Gustavo F. Padovan
1 sibling, 0 replies; 36+ messages in thread
From: Gustavo F. Padovan @ 2010-04-19 20:15 UTC (permalink / raw)
To: marcel; +Cc: linux-bluetooth, jprvita
Hi Marcel,
* Gustavo F. Padovan <padovan@profusion.mobi> [2010-04-01 17:23:18 -0300]:
> Hi Marcel,
>
> Here are all patches rebased against -rc3. Most of then are a resend unless
> the last five patches.
What about these patches? Merge window is coming and would be good if we
have a try on linux-next before push these patches to mainline. ;)
Please, review them.
Regards,
--
Gustavo F. Padovan
http://padovan.org
^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2010-04-19 20:15 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-04-01 20:23 Patches for eL2CAP Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 01/34] Bluetooth: Implement 'Send IorRRorRNR' event Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 02/34] Bluetooth: Support case with F bit set under WAIT_F state Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 03/34] Bluetooth: Fix memory leak of S-frames into L2CAP Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 04/34] Bluetooth: Check the minimum {I,S}-frame size " Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 05/34] Bluetooth: Check if SDU size is greater than MTU on L2CAP Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 06/34] Bluetooth: Fix expected_tx_seq calculation " Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 07/34] Bluetooth: Implement SendAck() Action on ERTM Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 08/34] Bluetooth: Move set of P-bit to l2cap_send_sframe() Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 09/34] Bluetooth: Add Recv RR (P=0)(F=0) for SREJ_SENT state on ERTM Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 10/34] Bluetooth: Use a l2cap_pinfo struct instead l2cap_pi() macro Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 11/34] Bluetooth: Fix ACL MTU issue Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 12/34] Bluetooth: Split l2cap_data_channel_sframe() Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 13/34] Bluetooth: Handle all cases of receipt of RNR-frames into L2CAP Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 14/34] Bluetooth: Group the ack of I-frames into l2cap_data_channel_rrframe() Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 15/34] Bluetooth: Remove duplicate use of __get_reqseq() macro on L2CAP Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 16/34] Bluetooth: Finish implementation for Rec RR (P=1) on ERTM Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 17/34] Bluetooth: Ignore I-frames with a duplicated txSeq Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 18/34] Bluetooth: Add timer to Acknowledge I-frames Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 19/34] Bluetooth: Move specific Basic Mode code to the right place Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 20/34] Bluetooth: Ignore Tx Window value with Streaming mode Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 21/34] Bluetooth: Read RFC conf option on a successful Conf RSP Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 22/34] Bluetooth: Fix configuration of the MPS value Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 23/34] Bluetooth: Add le16 macro to Retransmission and Monitor Timeouts values Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 24/34] Bluetooth: Check the SDU size against the MTU value Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 25/34] Bluetooth: Send Ack after clear the SREJ list Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 26/34] Bluetooth: Add sockopt configuration for txWindow on L2CAP Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 27/34] Bluetooth: Change acknowledgement to use the value of txWindow Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 28/34] Bluetooth: Add module parameter for txWindow size on L2CAP Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 29/34] Bluetooth: Enable option to configure Max Transmission value via sockopt Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 30/34] Bluetooth: Make hci_send_acl() void Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 31/34] Bluetooth: Make hci_send_sco() void Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 32/34] Bluetooth: Return the data length sent on connectionless channels Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 33/34] Bluetooth: Clean sco_send_frame() flow Gustavo F. Padovan
2010-04-01 20:23 ` [PATCH 34/34] Bluetooth: Remove unneeded check for MTU on sco_send_frame() Gustavo F. Padovan
2010-04-19 20:15 ` Patches for eL2CAP Gustavo F. Padovan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).