All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Add #defines and data structures for enhanced L2CAP
@ 2009-04-30  1:44 ngh
  2009-04-30  1:44 ` [PATCH] Reassemble segmented L2CAP PDUs upon reception ngh
  2009-04-30  2:18 ` [PATCH] Add #defines and data structures for enhanced L2CAP Marcel Holtmann
  0 siblings, 2 replies; 3+ messages in thread
From: ngh @ 2009-04-30  1:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Nathan Holstein

From: Nathan Holstein <nathan@lampreynetworks.com>

This patch #defines many constants used for implementation of Enhanced
Retranmission and Streaming modes within L2CAP.

This also adds the necessary members to the socket data structures to support
the additional modes.
---
 include/net/bluetooth/bluetooth.h |    3 +-
 include/net/bluetooth/l2cap.h     |  118 ++++++++++++++++++++++++++++++++++---
 net/bluetooth/l2cap.c             |   17 ++++-
 3 files changed, 124 insertions(+), 14 deletions(-)

diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 3ad5390..f532e2d 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -144,8 +144,9 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
 struct bt_skb_cb {
 	__u8 pkt_type;
 	__u8 incoming;
+	__u8 tx_seq;
 };
-#define bt_cb(skb) ((struct bt_skb_cb *)(skb->cb)) 
+#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
 
 static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how)
 {
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 300b63f..3770fb6 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -1,4 +1,4 @@
-/* 
+/*
    BlueZ - Bluetooth protocol stack for Linux
    Copyright (C) 2000-2001 Qualcomm Incorporated
 
@@ -12,13 +12,13 @@
    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
    SOFTWARE IS DISCLAIMED.
 */
 
@@ -26,12 +26,29 @@
 #define __L2CAP_H
 
 /* L2CAP defaults */
-#define L2CAP_DEFAULT_MTU	672
-#define L2CAP_DEFAULT_FLUSH_TO	0xFFFF
+#define L2CAP_DEFAULT_MTU		672
+#define L2CAP_DEFAULT_FLUSH_TO		0xFFFF
+#define L2CAP_DEFAULT_RX_WINDOW		1
+#define L2CAP_DEFAULT_MAX_RECEIVE	1
+#define L2CAP_DEFAULT_RETRANS_TIMEOUT	300    /* 300 milliseconds */
+#define L2CAP_DEFAULT_MONITOR_TIMEOUT	1000   /* 1 second */
+#define L2CAP_DEFAULT_MAX_RX_APDU	0xFFF7
 
 #define L2CAP_CONN_TIMEOUT	(40000) /* 40 seconds */
 #define L2CAP_INFO_TIMEOUT	(4000)  /*  4 seconds */
 
+#define L2CAP_FCS_GENERATOR	((u16)0xA001)
+
+/* L2CAP feature bits */
+#define L2CAP_FEATURE_FLOW	0x00000001
+#define L2CAP_FEATURE_RETRANS	0x00000002
+#define L2CAP_FEATURE_QOS	0x00000004
+#define L2CAP_FEATURE_E_RETRANS	0x00000008
+#define L2CAP_FEATURE_STREAM	0x00000010
+#define L2CAP_FEATURE_FCS	0x00000020
+#define L2CAP_FEATURE_FIX_CHAN	0x00000080
+#define L2CAP_FEATURE_RESERVED	0x80000000
+
 /* L2CAP socket address */
 struct sockaddr_l2 {
 	sa_family_t	l2_family;
@@ -76,6 +93,66 @@ struct l2cap_conninfo {
 #define L2CAP_INFO_REQ    0x0a
 #define L2CAP_INFO_RSP    0x0b
 
+/* L2CAP Control Field bit masks */
+#define L2CAP_CONTROL_SAR_MASK		0xC000
+#define L2CAP_CONTROL_REQSEQ_MASK	0x3F00
+#define L2CAP_CONTROL_TXSEQ_MASK	0x007E
+#define L2CAP_CONTROL_RETRANS_MASK	0x0080
+#define L2CAP_CONTROL_FINAL_MASK	0x0080
+#define L2CAP_CONTROL_POLL_MASK		0x0010
+#define L2CAP_CONTROL_SUPERVISE_MASK	0x000C
+#define L2CAP_CONTROL_TYPE_MASK		0x0001 /* I- or S-Frame */
+
+#define L2CAP_CONTROL_TXSEQ_SHIFT	1
+#define L2CAP_CONTROL_REQSEQ_SHIFT	8
+
+#define L2CAP_SEQ_NUM_INC(seq) ((seq) = (seq + 1) % 64)
+
+static inline u8 l2cap_control_txseq(u16 control)
+{
+	return (control & L2CAP_CONTROL_TXSEQ_MASK) >>
+			L2CAP_CONTROL_TXSEQ_SHIFT;
+}
+
+static inline u8 l2cap_control_reqseq(u16 control)
+{
+	return (control & L2CAP_CONTROL_REQSEQ_MASK) >>
+			L2CAP_CONTROL_REQSEQ_SHIFT;
+}
+
+static inline u16 l2cap_txseq_to_reqseq(u16 control)
+{
+	return (control & L2CAP_CONTROL_TXSEQ_MASK) <<
+			(L2CAP_CONTROL_REQSEQ_SHIFT - L2CAP_CONTROL_TXSEQ_SHIFT);
+}
+
+static inline int l2cap_is_I_frame(u16 control)
+{
+	return !(control & L2CAP_CONTROL_TYPE_MASK);
+}
+
+static inline int l2cap_is_S_frame(u16 control)
+{
+	return (control & L2CAP_CONTROL_TYPE_MASK);
+}
+
+/* L2CAP Segmentation and Reassembly */
+#define L2CAP_SAR_UNSEGMENTED	0x0000
+#define L2CAP_SAR_SDU_START	0x4000
+#define L2CAP_SAR_SDU_END	0x8000
+#define L2CAP_SAR_SDU_CONTINUE	0xC000
+
+/* L2CAP Supervisory Function */
+#define L2CAP_SUPER_RCV_READY		0x0000
+#define L2CAP_SUPER_REJECT		0x0004
+#define L2CAP_SUPER_RCV_NOT_READY	0x0008
+#define L2CAP_SUPER_SELECT_REJECT	0x000C
+
+/* L2CAP Optional FCS */
+#define L2CAP_FCS_DISABLE	0x00
+#define L2CAP_FCS_ENABLE	0x01
+#define L2CAP_FCS_DEFAULT	L2CAP_FCS_ENABLE
+
 /* L2CAP structures */
 struct l2cap_hdr {
 	__le16     len;
@@ -149,12 +226,14 @@ struct l2cap_conf_opt {
 } __attribute__ ((packed));
 #define L2CAP_CONF_OPT_SIZE	2
 
-#define L2CAP_CONF_HINT		0x80
+#define L2CAP_CONF_HINT		((u8)0x80)
+#define L2CAP_CONF_MIN_MTU	48
 
 #define L2CAP_CONF_MTU		0x01
 #define L2CAP_CONF_FLUSH_TO	0x02
 #define L2CAP_CONF_QOS		0x03
 #define L2CAP_CONF_RFC		0x04
+#define L2CAP_CONF_FCS		0x05
 
 #define L2CAP_CONF_MAX_SIZE	22
 
@@ -170,6 +249,8 @@ struct l2cap_conf_rfc {
 #define L2CAP_MODE_BASIC	0x00
 #define L2CAP_MODE_RETRANS	0x01
 #define L2CAP_MODE_FLOWCTL	0x02
+#define L2CAP_MODE_ENH_RETRANS	0x03
+#define L2CAP_MODE_STREAMING	0x04
 
 struct l2cap_disconn_req {
 	__le16     dcid;
@@ -259,10 +340,29 @@ struct l2cap_pinfo {
 	__u8		conf_state;
 	__u8		conf_retry;
 
+	__u8		tx_seq;
+	__u8		req_seq;
+
+	__u8		fcs;
+
 	__u8		ident;
 
 	__le16		sport;
 
+	__u8		mode;
+	__u8		txwin_size;
+	__u8		remote_tx_win;
+	__u8		remote_max_tx;
+	__u16		retrans_timeout;
+	__u16		monitor_timeout;
+	__u16		max_pdu_size;
+
+	__u16		sdu_next;
+	__u16		sdu_len;
+
+	struct timer_list	 retrans_timer;
+	struct timer_list	 monitor_timer;
+	struct sk_buff		*tx_buf;
 	struct l2cap_conn	*conn;
 	struct sock		*next_c;
 	struct sock		*prev_c;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index f6a82f2..31b1cbc 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -52,7 +52,8 @@
 
 #define VERSION "2.13"
 
-static u32 l2cap_feat_mask = 0x0080;
+static u32 l2cap_feat_mask =
+	L2CAP_FEATURE_FIX_CHAN;
 static u8 l2cap_fixed_chan[8] = { 0x02, };
 
 static const struct proto_ops l2cap_sock_ops;
@@ -718,12 +719,20 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
 		pi->sec_level = l2cap_pi(parent)->sec_level;
 		pi->role_switch = l2cap_pi(parent)->role_switch;
 		pi->force_reliable = l2cap_pi(parent)->force_reliable;
+		pi->fcs = l2cap_pi(parent)->fcs;
+		pi->mode = l2cap_pi(parent)->mode;
 	} else {
 		pi->imtu = L2CAP_DEFAULT_MTU;
 		pi->omtu = 0;
 		pi->sec_level = BT_SECURITY_LOW;
 		pi->role_switch = 0;
 		pi->force_reliable = 0;
+		pi->fcs = L2CAP_FCS_DEFAULT;
+		if (sk->sk_type == SOCK_STREAM)
+			pi->mode = L2CAP_MODE_ENH_RETRANS;
+		else
+			pi->mode = L2CAP_MODE_BASIC;
+
 	}
 
 	/* Default config options */
@@ -770,7 +779,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol)
 
 	sock->state = SS_UNCONNECTED;
 
-	if (sock->type != SOCK_SEQPACKET &&
+	if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
 			sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
 		return -ESOCKTNOSUPPORT;
 
@@ -1747,7 +1756,7 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
 		len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
 
 		hint  = type & L2CAP_CONF_HINT;
-		type &= 0x7f;
+		type &= ~L2CAP_CONF_HINT;
 
 		switch (type) {
 		case L2CAP_CONF_MTU:
@@ -2244,7 +2253,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
 	if (type == L2CAP_IT_FEAT_MASK) {
 		conn->feat_mask = get_unaligned_le32(rsp->data);
 
-		if (conn->feat_mask & 0x0080) {
+		if (conn->feat_mask & L2CAP_FEATURE_FIX_CHAN) {
 			struct l2cap_info_req req;
 			req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
 
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH] Reassemble segmented L2CAP PDUs upon reception
  2009-04-30  1:44 [PATCH] Add #defines and data structures for enhanced L2CAP ngh
@ 2009-04-30  1:44 ` ngh
  2009-04-30  2:18 ` [PATCH] Add #defines and data structures for enhanced L2CAP Marcel Holtmann
  1 sibling, 0 replies; 3+ messages in thread
From: ngh @ 2009-04-30  1:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Nathan Holstein

From: Nathan Holstein <nathan@lampreynetworks.com>

When configured in Enhanced Retransmission of Streaming modes, data sent over
L2CAP can be broken up into multiple L2CAP SDUs.  This patch adds support for
reassembling these packets upon reception.
---
 net/bluetooth/l2cap.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 6328fb8..7505137 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2595,6 +2595,43 @@ static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct l2cap_hdr *lh, struct
 	return 0;
 }
 
+static int l2cap_check_sar(struct l2cap_pinfo *pi, u16 control, struct sk_buff *skb)
+{
+	u16 mask = control & L2CAP_CONTROL_SAR_MASK;
+
+	switch (mask)
+	{
+	case L2CAP_SAR_UNSEGMENTED:
+		if (pi->sdu_next != 0)
+			return -1;
+		break;
+
+	case L2CAP_SAR_SDU_START:
+		if (pi->sdu_next != 0 || skb->len < 2)
+			return -1;
+		pi->sdu_next = 1;
+		pi->sdu_len = get_unaligned((__le16 *) skb->data);
+		skb_pull(skb, 2);
+		break;
+
+	case L2CAP_SAR_SDU_CONTINUE:
+		if (pi->sdu_next >= pi->sdu_len)
+			return -1;
+		++pi->sdu_next;
+		break;
+
+	case L2CAP_SAR_SDU_END:
+		/* TODO:
+		 * How do we correctly signal MSG_EOR? */
+		if (pi->sdu_next != pi->sdu_len)
+			return -1;
+		pi->sdu_next = pi->sdu_len = 0;
+		break;
+	}
+
+	return 0;
+}
+
 static inline int l2cap_data_channel_i_frame(struct sock *sk, u16 rx_control, struct sk_buff *skb)
 {
 	struct l2cap_pinfo *pi = l2cap_pi(sk);
@@ -2614,6 +2651,17 @@ static inline int l2cap_data_channel_i_frame(struct sock *sk, u16 rx_control, st
 	L2CAP_SEQ_NUM_INC(pi->req_seq);
 	tx_control = pi->req_seq << L2CAP_CONTROL_REQSEQ_SHIFT;
 
+	/* TODO:
+	 * l2cap_check_sar() call side effects!  After calling this function,
+	 * we can't reject the SDU without possibly screwing up reassembly.
+	 * We need to ensure the sequence number is correct, and that we can
+	 * queue the skb before calling l2cap_check_sar(). */
+	if (l2cap_check_sar(pi, rx_control, skb)) {
+		tx_control |= L2CAP_SUPER_REJECT;
+		err = -1;
+		goto respond;
+	}
+
 	if ((err = sock_queue_rcv_skb(sk, skb))) {
 		tx_control |= L2CAP_SUPER_RCV_NOT_READY;
 		goto respond;
@@ -2694,6 +2742,11 @@ static int l2cap_data_channel_streaming(struct sock *sk, struct l2cap_hdr *lh, s
 	control = get_unaligned((__le16 *) skb->data);
 	skb_pull(skb, 2);
 
+	/* Todo:
+	 * is this the proper behavior? */
+	if (l2cap_is_I_frame(control) && l2cap_check_sar(pi, control, skb))
+		return -1;
+
 	if (!sock_queue_rcv_skb(sk, skb))
 		return -1;
 
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] Add #defines and data structures for enhanced L2CAP
  2009-04-30  1:44 [PATCH] Add #defines and data structures for enhanced L2CAP ngh
  2009-04-30  1:44 ` [PATCH] Reassemble segmented L2CAP PDUs upon reception ngh
@ 2009-04-30  2:18 ` Marcel Holtmann
  1 sibling, 0 replies; 3+ messages in thread
From: Marcel Holtmann @ 2009-04-30  2:18 UTC (permalink / raw)
  To: ngh; +Cc: linux-bluetooth, Nathan Holstein

Hi Nathan,

> This patch #defines many constants used for implementation of Enhanced
> Retranmission and Streaming modes within L2CAP.
> 
> This also adds the necessary members to the socket data structures to support
> the additional modes.

please don't mix them up. These are different. I want the constants
going in first.

> ---
>  include/net/bluetooth/bluetooth.h |    3 +-
>  include/net/bluetooth/l2cap.h     |  118 ++++++++++++++++++++++++++++++++++---
>  net/bluetooth/l2cap.c             |   17 ++++-
>  3 files changed, 124 insertions(+), 14 deletions(-)
> 
> diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
> index 3ad5390..f532e2d 100644
> --- a/include/net/bluetooth/bluetooth.h
> +++ b/include/net/bluetooth/bluetooth.h
> @@ -144,8 +144,9 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
>  struct bt_skb_cb {
>  	__u8 pkt_type;
>  	__u8 incoming;
> +	__u8 tx_seq;
>  };
> -#define bt_cb(skb) ((struct bt_skb_cb *)(skb->cb)) 
> +#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
>  
>  static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how)
>  {
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index 300b63f..3770fb6 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -1,4 +1,4 @@
> -/* 
> +/*
>     BlueZ - Bluetooth protocol stack for Linux
>     Copyright (C) 2000-2001 Qualcomm Incorporated
>  
> @@ -12,13 +12,13 @@
>     OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
>     IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
> -   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
> -   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
> -   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
> +   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
> +   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> +   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
>     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>  
> -   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
> -   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
> +   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
> +   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
>     SOFTWARE IS DISCLAIMED.
>  */

Don't touch this. If copyright header needs changing I will do it and
will do in a separate patch.
 
> @@ -26,12 +26,29 @@
>  #define __L2CAP_H
>  
>  /* L2CAP defaults */
> -#define L2CAP_DEFAULT_MTU	672
> -#define L2CAP_DEFAULT_FLUSH_TO	0xFFFF
> +#define L2CAP_DEFAULT_MTU		672
> +#define L2CAP_DEFAULT_FLUSH_TO		0xFFFF
> +#define L2CAP_DEFAULT_RX_WINDOW		1
> +#define L2CAP_DEFAULT_MAX_RECEIVE	1
> +#define L2CAP_DEFAULT_RETRANS_TIMEOUT	300    /* 300 milliseconds */
> +#define L2CAP_DEFAULT_MONITOR_TIMEOUT	1000   /* 1 second */
> +#define L2CAP_DEFAULT_MAX_RX_APDU	0xFFF7

call it RETRANS_TO and MONITOR_TO to make it similar for FLUSH_TO.
 
> +#define L2CAP_FCS_GENERATOR	((u16)0xA001)
> +

Not needed since we should use the kernel FCS stuff.

> +/* L2CAP feature bits */
> +#define L2CAP_FEATURE_FLOW	0x00000001
> +#define L2CAP_FEATURE_RETRANS	0x00000002
> +#define L2CAP_FEATURE_QOS	0x00000004
> +#define L2CAP_FEATURE_E_RETRANS	0x00000008
> +#define L2CAP_FEATURE_STREAM	0x00000010
> +#define L2CAP_FEATURE_FCS	0x00000020
> +#define L2CAP_FEATURE_FIX_CHAN	0x00000080
> +#define L2CAP_FEATURE_RESERVED	0x80000000

I prefer if we only list the features we are going to support. So I like
to have them named like this:

	L2CAP_FEAT_ERTM
	L2CAP_FEAT_STREAM
	L2CAP_FEAT_FCS
	L2CAP_FEAT_FIXED_CHAN

> +
>  /* L2CAP socket address */
>  struct sockaddr_l2 {
>  	sa_family_t	l2_family;
> @@ -76,6 +93,66 @@ struct l2cap_conninfo {
>  #define L2CAP_INFO_REQ    0x0a
>  #define L2CAP_INFO_RSP    0x0b
>  
> +/* L2CAP Control Field bit masks */
> +#define L2CAP_CONTROL_SAR_MASK		0xC000
> +#define L2CAP_CONTROL_REQSEQ_MASK	0x3F00
> +#define L2CAP_CONTROL_TXSEQ_MASK	0x007E
> +#define L2CAP_CONTROL_RETRANS_MASK	0x0080
> +#define L2CAP_CONTROL_FINAL_MASK	0x0080
> +#define L2CAP_CONTROL_POLL_MASK		0x0010
> +#define L2CAP_CONTROL_SUPERVISE_MASK	0x000C
> +#define L2CAP_CONTROL_TYPE_MASK		0x0001 /* I- or S-Frame */
> +
> +#define L2CAP_CONTROL_TXSEQ_SHIFT	1
> +#define L2CAP_CONTROL_REQSEQ_SHIFT	8
> +
> +#define L2CAP_SEQ_NUM_INC(seq) ((seq) = (seq + 1) % 64)
> +
> +static inline u8 l2cap_control_txseq(u16 control)
> +{
> +	return (control & L2CAP_CONTROL_TXSEQ_MASK) >>
> +			L2CAP_CONTROL_TXSEQ_SHIFT;
> +}
> +
> +static inline u8 l2cap_control_reqseq(u16 control)
> +{
> +	return (control & L2CAP_CONTROL_REQSEQ_MASK) >>
> +			L2CAP_CONTROL_REQSEQ_SHIFT;
> +}
> +
> +static inline u16 l2cap_txseq_to_reqseq(u16 control)
> +{
> +	return (control & L2CAP_CONTROL_TXSEQ_MASK) <<
> +			(L2CAP_CONTROL_REQSEQ_SHIFT - L2CAP_CONTROL_TXSEQ_SHIFT);
> +}
> +
> +static inline int l2cap_is_I_frame(u16 control)
> +{
> +	return !(control & L2CAP_CONTROL_TYPE_MASK);
> +}
> +
> +static inline int l2cap_is_S_frame(u16 control)
> +{
> +	return (control & L2CAP_CONTROL_TYPE_MASK);
> +}
> +
> +/* L2CAP Segmentation and Reassembly */
> +#define L2CAP_SAR_UNSEGMENTED	0x0000
> +#define L2CAP_SAR_SDU_START	0x4000
> +#define L2CAP_SAR_SDU_END	0x8000
> +#define L2CAP_SAR_SDU_CONTINUE	0xC000
> +
> +/* L2CAP Supervisory Function */
> +#define L2CAP_SUPER_RCV_READY		0x0000
> +#define L2CAP_SUPER_REJECT		0x0004
> +#define L2CAP_SUPER_RCV_NOT_READY	0x0008
> +#define L2CAP_SUPER_SELECT_REJECT	0x000C

I want these in a a separate patch.
+
> +/* L2CAP Optional FCS */
> +#define L2CAP_FCS_DISABLE	0x00
> +#define L2CAP_FCS_ENABLE	0x01
> +#define L2CAP_FCS_DEFAULT	L2CAP_FCS_ENABLE

This is actually L2CAP_FCS_NONE, L2CAP_FCS_CRC16. It is defined in a way
that it could be extended with other FCS.

> +
>  /* L2CAP structures */
>  struct l2cap_hdr {
>  	__le16     len;
> @@ -149,12 +226,14 @@ struct l2cap_conf_opt {
>  } __attribute__ ((packed));
>  #define L2CAP_CONF_OPT_SIZE	2
>  
> -#define L2CAP_CONF_HINT		0x80
> +#define L2CAP_CONF_HINT		((u8)0x80)
> +#define L2CAP_CONF_MIN_MTU	48

Non of these should be needed right now. Especially the (u8) is unclear
to me.
 
>  #define L2CAP_CONF_MTU		0x01
>  #define L2CAP_CONF_FLUSH_TO	0x02
>  #define L2CAP_CONF_QOS		0x03
>  #define L2CAP_CONF_RFC		0x04
> +#define L2CAP_CONF_FCS		0x05
>  
>  #define L2CAP_CONF_MAX_SIZE	22
>  
> @@ -170,6 +249,8 @@ struct l2cap_conf_rfc {
>  #define L2CAP_MODE_BASIC	0x00
>  #define L2CAP_MODE_RETRANS	0x01
>  #define L2CAP_MODE_FLOWCTL	0x02
> +#define L2CAP_MODE_ENH_RETRANS	0x03
> +#define L2CAP_MODE_STREAMING	0x04

Name this MODE_ERTM and MODE_STREAM to match FEAT_*.
 
>  struct l2cap_disconn_req {
>  	__le16     dcid;
> @@ -259,10 +340,29 @@ struct l2cap_pinfo {
>  	__u8		conf_state;
>  	__u8		conf_retry;
>  
> +	__u8		tx_seq;
> +	__u8		req_seq;
> +
> +	__u8		fcs;
> +
>  	__u8		ident;
>  
>  	__le16		sport;
>  
> +	__u8		mode;
> +	__u8		txwin_size;
> +	__u8		remote_tx_win;
> +	__u8		remote_max_tx;
> +	__u16		retrans_timeout;
> +	__u16		monitor_timeout;
> +	__u16		max_pdu_size;
> +
> +	__u16		sdu_next;
> +	__u16		sdu_len;
> +
> +	struct timer_list	 retrans_timer;
> +	struct timer_list	 monitor_timer;
> +	struct sk_buff		*tx_buf;
>  	struct l2cap_conn	*conn;
>  	struct sock		*next_c;
>  	struct sock		*prev_c;

Separate patch.

> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index f6a82f2..31b1cbc 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -52,7 +52,8 @@
>  
>  #define VERSION "2.13"
>  
> -static u32 l2cap_feat_mask = 0x0080;
> +static u32 l2cap_feat_mask =
> +	L2CAP_FEATURE_FIX_CHAN;

Put in on the same line please.

>  static u8 l2cap_fixed_chan[8] = { 0x02, };
>  
>  static const struct proto_ops l2cap_sock_ops;
> @@ -718,12 +719,20 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
>  		pi->sec_level = l2cap_pi(parent)->sec_level;
>  		pi->role_switch = l2cap_pi(parent)->role_switch;
>  		pi->force_reliable = l2cap_pi(parent)->force_reliable;
> +		pi->fcs = l2cap_pi(parent)->fcs;
> +		pi->mode = l2cap_pi(parent)->mode;
>  	} else {
>  		pi->imtu = L2CAP_DEFAULT_MTU;
>  		pi->omtu = 0;
>  		pi->sec_level = BT_SECURITY_LOW;
>  		pi->role_switch = 0;
>  		pi->force_reliable = 0;
> +		pi->fcs = L2CAP_FCS_DEFAULT;
> +		if (sk->sk_type == SOCK_STREAM)
> +			pi->mode = L2CAP_MODE_ENH_RETRANS;
> +		else
> +			pi->mode = L2CAP_MODE_BASIC;
> +
>  	}

Separate patch.
 
>  	/* Default config options */
> @@ -770,7 +779,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol)
>  
>  	sock->state = SS_UNCONNECTED;
>  
> -	if (sock->type != SOCK_SEQPACKET &&
> +	if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
>  			sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
>  		return -ESOCKTNOSUPPORT;

we can not do that right now. This will break proper bi-section.
 
> @@ -1747,7 +1756,7 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
>  		len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
>  
>  		hint  = type & L2CAP_CONF_HINT;
> -		type &= 0x7f;
> +		type &= ~L2CAP_CONF_HINT;

Using something like L2CAP_CONF_MASK is way better here.
 
>  		switch (type) {
>  		case L2CAP_CONF_MTU:
> @@ -2244,7 +2253,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
>  	if (type == L2CAP_IT_FEAT_MASK) {
>  		conn->feat_mask = get_unaligned_le32(rsp->data);
>  
> -		if (conn->feat_mask & 0x0080) {
> +		if (conn->feat_mask & L2CAP_FEATURE_FIX_CHAN) {
>  			struct l2cap_info_req req;
>  			req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
>  

Regards

Marcel



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-04-30  2:18 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-30  1:44 [PATCH] Add #defines and data structures for enhanced L2CAP ngh
2009-04-30  1:44 ` [PATCH] Reassemble segmented L2CAP PDUs upon reception ngh
2009-04-30  2:18 ` [PATCH] Add #defines and data structures for enhanced L2CAP Marcel Holtmann

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.