* [RFC 0/7] EFS initial support
@ 2011-08-18 7:44 Emeltchenko Andrei
2011-08-18 7:44 ` [RFC 1/7] Bluetooth: L2CAP extended feature mask update Emeltchenko Andrei
` (6 more replies)
0 siblings, 7 replies; 19+ messages in thread
From: Emeltchenko Andrei @ 2011-08-18 7:44 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add basic support for Extended Flow Specification option in L2CAP
Patch series based on patches sent by haijun.liu <haijun.liu@atheros.com> about
one year ago. L2CAP sequence looks like the one below:
(my patches for decoding EFS have been applied to hcidump)
...
< ACL data: handle 1 flags 0x00 dlen 10
L2CAP(s): Info req: type 2
> ACL data: handle 1 flags 0x02 dlen 16
L2CAP(s): Info rsp: type 2 result 0
Extended feature mask 0x00f8
Enhanced Retransmission mode
Streaming mode
FCS Option
Extended Flow Specification
Fixed Channels
< ACL data: handle 1 flags 0x00 dlen 10
L2CAP(s): Info req: type 3
> ACL data: handle 1 flags 0x02 dlen 20
L2CAP(s): Info rsp: type 3 result 0
Fixed channel list
< ACL data: handle 1 flags 0x00 dlen 12
L2CAP(s): Connect req: psm 4113 scid 0x0040
> ACL data: handle 1 flags 0x02 dlen 16
L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0040 result 1 status 0
Connection pending - No futher information available
> ACL data: handle 1 flags 0x02 dlen 10
L2CAP(s): Info req: type 2
< ACL data: handle 1 flags 0x00 dlen 16
L2CAP(s): Info rsp: type 2 result 0
Extended feature mask 0x00f8
Enhanced Retransmission mode
Streaming mode
FCS Option
Extended Flow Specification
Fixed Channels
> ACL data: handle 1 flags 0x02 dlen 10
L2CAP(s): Info req: type 3
< ACL data: handle 1 flags 0x00 dlen 20
L2CAP(s): Info rsp: type 3 result 0
Fixed channel list
> ACL data: handle 1 flags 0x02 dlen 16
L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0040 result 0 status 0
Connection successful
< ACL data: handle 1 flags 0x00 dlen 41
L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 29
RFC 0x03 (Enhanced Retransmission, TxWin 63, MaxTx 3, RTo 0,
MTo 0, MPS 500)
EFS (Id 0x01, SerType Best Effort, MaxSDU 0xffff, SDUitime
0xffffffff, AccLat 0xffffffff, FlushTO 0x0000ffff)
> ACL data: handle 1 flags 0x02 dlen 41
L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 29
RFC 0x03 (Enhanced Retransmission, TxWin 63, MaxTx 3, RTo 0, MTo 0,
MPS 1009)
EFS (Id 0x01, SerType Best Effort, MaxSDU 0xffff, SDUitime 0xffffffff,
AccLat 0xffffffff, FlushTO 0x0000ffff)
< ACL data: handle 1 flags 0x00 dlen 47
L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 4 clen 33
Pending
MTU 672
RFC 0x03 (Enhanced Retransmission, TxWin 63, MaxTx 3, RTo 2000, MTo 12000,
MPS 500)
EFS (Id 0x01, SerType Best Effort, MaxSDU 0xffff, SDUitime 0xffffffff,
AccLat 0xffffffff, FlushTO 0x0000ffff)
> ACL data: handle 1 flags 0x02 dlen 47
L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 4 clen 33
Pending
MTU 672
RFC 0x03 (Enhanced Retransmission, TxWin 63, MaxTx 3, RTo 2000, MTo 12000,
MPS 500)
EFS (Id 0x01, SerType Best Effort, MaxSDU 0xffff, SDUitime 0xffffffff,
AccLat 0xffffffff, FlushTO 0x0000ffff)
< ACL data: handle 1 flags 0x00 dlen 14
L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 0
Success
> ACL data: handle 1 flags 0x02 dlen 14
L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 0
Success
...
< ACL data: handle 1 flags 0x00 dlen 510
L2CAP(d): cid 0x0040 len 506 ctrl 0x4000 fcs 0x5337 [psm 4113]
I-frame: Start (len 672) TxSeq 0 ReqSeq 0
...
Andrei Emeltchenko (7):
Bluetooth: L2CAP extended feature mask update
Bluetooth: EFS: definitions and headers for EFS
Bluetooth: EFS: add disable_flowspec kernel param
Bluetooth: parse EFS in l2cap config request
Bluetooth: parse EFS in l2cap config response
Bluetooth: add EFS option in l2cap conf req
Bluetooth: EFS: parse l2cap config rsp pending
include/net/bluetooth/l2cap.h | 45 +++++++++-
net/bluetooth/l2cap_core.c | 216 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 256 insertions(+), 5 deletions(-)
--
1.7.4.1
^ permalink raw reply [flat|nested] 19+ messages in thread
* [RFC 1/7] Bluetooth: L2CAP extended feature mask update
2011-08-18 7:44 [RFC 0/7] EFS initial support Emeltchenko Andrei
@ 2011-08-18 7:44 ` Emeltchenko Andrei
2011-08-18 7:44 ` [RFC 2/7] Bluetooth: EFS: definitions and headers for EFS Emeltchenko Andrei
` (5 subsequent siblings)
6 siblings, 0 replies; 19+ messages in thread
From: Emeltchenko Andrei @ 2011-08-18 7:44 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Update L2CAP extended feature mask to reflect recent BT spec.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
include/net/bluetooth/l2cap.h | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 6fa1140..9850cb5 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -91,13 +91,17 @@ struct l2cap_conninfo {
#define L2CAP_CONN_PARAM_UPDATE_REQ 0x12
#define L2CAP_CONN_PARAM_UPDATE_RSP 0x13
-/* L2CAP feature mask */
+/* L2CAP extended feature mask */
#define L2CAP_FEAT_FLOWCTL 0x00000001
#define L2CAP_FEAT_RETRANS 0x00000002
+#define L2CAP_FEAT_BIDIR_QOS 0x00000004
#define L2CAP_FEAT_ERTM 0x00000008
#define L2CAP_FEAT_STREAMING 0x00000010
#define L2CAP_FEAT_FCS 0x00000020
+#define L2CAP_FEAT_EXT_FLOW 0x00000040
#define L2CAP_FEAT_FIXED_CHAN 0x00000080
+#define L2CAP_FEAT_EXT_WINDOW 0x00000100
+#define L2CAP_FEAT_UCD 0x00000200
/* L2CAP checksum option */
#define L2CAP_FCS_NONE 0x00
--
1.7.4.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [RFC 2/7] Bluetooth: EFS: definitions and headers for EFS
2011-08-18 7:44 [RFC 0/7] EFS initial support Emeltchenko Andrei
2011-08-18 7:44 ` [RFC 1/7] Bluetooth: L2CAP extended feature mask update Emeltchenko Andrei
@ 2011-08-18 7:44 ` Emeltchenko Andrei
2011-08-24 20:43 ` Gustavo Padovan
2011-08-24 20:46 ` Gustavo Padovan
2011-08-18 7:44 ` [RFC 3/7] Bluetooth: EFS: add disable_flowspec kernel param Emeltchenko Andrei
` (4 subsequent siblings)
6 siblings, 2 replies; 19+ messages in thread
From: Emeltchenko Andrei @ 2011-08-18 7:44 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Based upon haijun.liu <haijun.liu@atheros.com> series of patches
(sent Sun, 22 Aug 2010)
---
include/net/bluetooth/l2cap.h | 37 +++++++++++++++++++++++++++++++++++++
1 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 9850cb5..d2154e0 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -38,6 +38,9 @@
#define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */
#define L2CAP_DEFAULT_ACK_TO 200
#define L2CAP_LE_DEFAULT_MTU 23
+#define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF
+#define L2CAP_DEFAULT_SDU_ARRIVAL_TIME 0xFFFFFFFF
+#define L2CAP_DEFAULT_ACCESS_LATENCY 0xFFFFFFFF
#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */
#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */
@@ -218,6 +221,8 @@ struct l2cap_conf_rsp {
#define L2CAP_CONF_UNACCEPT 0x0001
#define L2CAP_CONF_REJECT 0x0002
#define L2CAP_CONF_UNKNOWN 0x0003
+#define L2CAP_CONF_PENDING 0x0004
+#define L2CAP_CONF_EFS_REJECT 0x0005
struct l2cap_conf_opt {
__u8 type;
@@ -234,6 +239,7 @@ struct l2cap_conf_opt {
#define L2CAP_CONF_QOS 0x03
#define L2CAP_CONF_RFC 0x04
#define L2CAP_CONF_FCS 0x05
+#define L2CAP_CONF_EFS 0x06
#define L2CAP_CONF_MAX_SIZE 22
@@ -252,6 +258,19 @@ struct l2cap_conf_rfc {
#define L2CAP_MODE_ERTM 0x03
#define L2CAP_MODE_STREAMING 0x04
+struct l2cap_conf_efs {
+ __u8 id;
+ __u8 service_type;
+ __le16 max_sdu_size;
+ __le32 sdu_inter_time;
+ __le32 access_latency;
+ __le32 flush_timeout;
+} __packed;
+
+#define L2CAP_SERVTYPE_NOTRAFIC 0x00
+#define L2CAP_SERVTYPE_BESTEFFORT 0x01
+#define L2CAP_SERVTYPE_GUARANTEED 0x02
+
struct l2cap_disconn_req {
__le16 dcid;
__le16 scid;
@@ -365,6 +384,22 @@ struct l2cap_chan {
__u8 remote_max_tx;
__u16 remote_mps;
+ __u8 local_id;
+ __u8 local_stype;
+ __u16 local_msdu;
+ __u32 local_sdu_itime;
+ __u32 local_acc_lat;
+ __u32 local_flush_to;
+
+ __u8 remote_id;
+ __u8 remote_stype;
+ __u16 remote_msdu;
+ __u32 remote_sdu_itime;
+ __u32 remote_acc_lat;
+ __u32 remote_flush_to;
+
+ __u8 ext_flowspec_enable;
+
struct timer_list chan_timer;
struct timer_list retrans_timer;
struct timer_list monitor_timer;
@@ -452,6 +487,8 @@ enum {
CONF_CONNECT_PEND,
CONF_NO_FCS_RECV,
CONF_STATE2_DEVICE,
+ CONF_LOCAL_PEND,
+ CONF_REMOTE_PEND,
};
#define L2CAP_CONF_MAX_CONF_REQ 2
--
1.7.4.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [RFC 3/7] Bluetooth: EFS: add disable_flowspec kernel param
2011-08-18 7:44 [RFC 0/7] EFS initial support Emeltchenko Andrei
2011-08-18 7:44 ` [RFC 1/7] Bluetooth: L2CAP extended feature mask update Emeltchenko Andrei
2011-08-18 7:44 ` [RFC 2/7] Bluetooth: EFS: definitions and headers for EFS Emeltchenko Andrei
@ 2011-08-18 7:44 ` Emeltchenko Andrei
2011-08-18 7:44 ` [RFC 4/7] Bluetooth: parse EFS in l2cap config request Emeltchenko Andrei
` (3 subsequent siblings)
6 siblings, 0 replies; 19+ messages in thread
From: Emeltchenko Andrei @ 2011-08-18 7:44 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Make extended flowspec option kernel parameter. Disabled by default.
---
net/bluetooth/l2cap_core.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index be30c32..4167cb0 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -57,6 +57,7 @@
#include <net/bluetooth/smp.h>
int disable_ertm;
+int disable_flowspec = 1;
static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
static u8 l2cap_fixed_chan[8] = { 0x02, };
@@ -2775,6 +2776,9 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cm
if (!disable_ertm)
feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
| L2CAP_FEAT_FCS;
+ if (!disable_flowspec)
+ feat_mask |= L2CAP_FEAT_EXT_FLOW;
+
put_unaligned_le32(feat_mask, rsp->data);
l2cap_send_cmd(conn, cmd->ident,
L2CAP_INFO_RSP, sizeof(buf), buf);
@@ -4296,3 +4300,6 @@ void l2cap_exit(void)
module_param(disable_ertm, bool, 0644);
MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");
+
+module_param(disable_flowspec, bool, 0644);
+MODULE_PARM_DESC(disable_flowspec, "Disable Extended Flow Specification");
--
1.7.4.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [RFC 4/7] Bluetooth: parse EFS in l2cap config request
2011-08-18 7:44 [RFC 0/7] EFS initial support Emeltchenko Andrei
` (2 preceding siblings ...)
2011-08-18 7:44 ` [RFC 3/7] Bluetooth: EFS: add disable_flowspec kernel param Emeltchenko Andrei
@ 2011-08-18 7:44 ` Emeltchenko Andrei
2011-08-24 21:13 ` Gustavo Padovan
2011-08-18 7:45 ` [RFC 5/7] Bluetooth: parse EFS in l2cap config response Emeltchenko Andrei
` (2 subsequent siblings)
6 siblings, 1 reply; 19+ messages in thread
From: Emeltchenko Andrei @ 2011-08-18 7:44 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add parsing extended flowspec option in L2cap config request
Based upon haijun.liu <haijun.liu@atheros.com> series of patches
(sent Sun, 22 Aug 2010)
---
net/bluetooth/l2cap_core.c | 70 ++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 4167cb0..5378bc6 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1890,6 +1890,12 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
}
}
+static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
+{
+ return !disable_flowspec &&
+ chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
+}
+
static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
{
struct l2cap_conf_req *req = data;
@@ -1996,6 +2002,8 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
int type, hint, olen;
unsigned long val;
struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
+ struct l2cap_conf_efs efs = { .service_type = L2CAP_SERVTYPE_BESTEFFORT };
+ u8 ext_flowspec_enable = 0;
u16 mtu = L2CAP_DEFAULT_MTU;
u16 result = L2CAP_CONF_SUCCESS;
@@ -2030,6 +2038,12 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
break;
+ case L2CAP_CONF_EFS:
+ ext_flowspec_enable = 1;
+ if (olen == sizeof(efs))
+ memcpy(&efs, (void *) val, olen);
+ break;
+
default:
if (hint)
break;
@@ -2052,7 +2066,17 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
break;
}
- if (chan->mode != rfc.mode)
+ if (ext_flowspec_enable && __l2cap_efs_supported(chan)) {
+ chan->ext_flowspec_enable = 1;
+
+ chan->local_stype = L2CAP_SERVTYPE_BESTEFFORT;
+ chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
+ chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ARRIVAL_TIME;
+ chan->local_acc_lat = L2CAP_DEFAULT_ACCESS_LATENCY;
+ chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
+ }
+
+ if (!l2cap_mode_supported(chan->mode, chan->conn->feat_mask))
return -ECONNREFUSED;
break;
@@ -2070,8 +2094,34 @@ done:
sizeof(rfc), (unsigned long) &rfc);
}
+ /*
+ Add the ext flow spec and ext win size option parameters check here.
+ */
+ if (result == L2CAP_CONF_SUCCESS && ext_flowspec_enable) {
+ if (!chan->ext_flowspec_enable) {
+ /* remote efs support , local efs not supported */
+
+ result = L2CAP_CONF_REJECT;
+ return -ECONNREFUSED;
+ } else if (chan->local_stype != L2CAP_SERVTYPE_NOTRAFIC &&
+ efs.service_type != L2CAP_SERVTYPE_NOTRAFIC &&
+ efs.service_type != chan->local_stype) {
- if (result == L2CAP_CONF_SUCCESS) {
+ result = L2CAP_CONF_UNACCEPT;
+
+ if (chan->num_conf_req >= 1)
+ return -ECONNREFUSED;
+
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
+ sizeof(efs), (unsigned long) &efs);
+
+ } else {
+ result = L2CAP_CONF_PENDING;
+ set_bit(CONF_LOCAL_PEND, &chan->conf_state);
+ }
+ }
+
+ if (result == L2CAP_CONF_SUCCESS || result == L2CAP_CONF_PENDING) {
/* Configure output options and let the other side know
* which ones we don't like. */
@@ -2108,6 +2158,22 @@ done:
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
+ if (chan->ext_flowspec_enable) {
+ /* record the extend flow spec parameters */
+ chan->remote_id = efs.id;
+ chan->remote_stype = efs.service_type;
+ chan->remote_msdu =
+ le16_to_cpu(efs.max_sdu_size);
+ chan->remote_flush_to =
+ le32_to_cpu(efs.flush_timeout);
+ chan->remote_acc_lat =
+ le32_to_cpu(efs.access_latency);
+ chan->remote_sdu_itime =
+ le32_to_cpu(efs.sdu_inter_time);
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
+ sizeof(efs), (unsigned long) &efs);
+ }
+
break;
case L2CAP_MODE_STREAMING:
--
1.7.4.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [RFC 5/7] Bluetooth: parse EFS in l2cap config response
2011-08-18 7:44 [RFC 0/7] EFS initial support Emeltchenko Andrei
` (3 preceding siblings ...)
2011-08-18 7:44 ` [RFC 4/7] Bluetooth: parse EFS in l2cap config request Emeltchenko Andrei
@ 2011-08-18 7:45 ` Emeltchenko Andrei
2011-08-24 21:15 ` Gustavo Padovan
2011-08-18 7:45 ` [RFC 6/7] Bluetooth: add EFS option in l2cap conf req Emeltchenko Andrei
2011-08-18 7:45 ` [RFC 7/7] Bluetooth: EFS: parse l2cap config rsp pending Emeltchenko Andrei
6 siblings, 1 reply; 19+ messages in thread
From: Emeltchenko Andrei @ 2011-08-18 7:45 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add parsing extended flowspec in l2cap config response
Based upon haijun.liu <haijun.liu@atheros.com> series of patches
(sent Sun, 22 Aug 2010)
---
net/bluetooth/l2cap_core.c | 28 +++++++++++++++++++++++++++-
1 files changed, 27 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 5378bc6..f64c9cb 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2213,6 +2213,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi
int type, olen;
unsigned long val;
struct l2cap_conf_rfc rfc;
+ struct l2cap_conf_efs efs;
BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
@@ -2248,6 +2249,19 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
break;
+
+ case L2CAP_CONF_EFS:
+ if (olen == sizeof(efs))
+ memcpy(&efs, (void *)val, olen);
+
+ if (chan->local_stype != L2CAP_SERVTYPE_NOTRAFIC &&
+ efs.service_type != L2CAP_SERVTYPE_NOTRAFIC &&
+ efs.service_type != chan->local_stype)
+ return -ECONNREFUSED;
+
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
+ sizeof(efs), (unsigned long) &efs);
+ break;
}
}
@@ -2256,13 +2270,25 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi
chan->mode = rfc.mode;
- if (*result == L2CAP_CONF_SUCCESS) {
+ if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
switch (rfc.mode) {
case L2CAP_MODE_ERTM:
chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
chan->mps = le16_to_cpu(rfc.max_pdu_size);
+ if (chan->ext_flowspec_enable) {
+ /* id, service type should not be changed */
+ chan->local_msdu =
+ le16_to_cpu(efs.max_sdu_size);
+ chan->local_sdu_itime =
+ le32_to_cpu(efs.sdu_inter_time);
+ chan->local_acc_lat =
+ le32_to_cpu(efs.access_latency);
+ chan->local_flush_to =
+ le32_to_cpu(efs.flush_timeout);
+ }
break;
+
case L2CAP_MODE_STREAMING:
chan->mps = le16_to_cpu(rfc.max_pdu_size);
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [RFC 6/7] Bluetooth: add EFS option in l2cap conf req
2011-08-18 7:44 [RFC 0/7] EFS initial support Emeltchenko Andrei
` (4 preceding siblings ...)
2011-08-18 7:45 ` [RFC 5/7] Bluetooth: parse EFS in l2cap config response Emeltchenko Andrei
@ 2011-08-18 7:45 ` Emeltchenko Andrei
2011-08-24 21:30 ` Gustavo Padovan
2011-08-24 21:33 ` Gustavo Padovan
2011-08-18 7:45 ` [RFC 7/7] Bluetooth: EFS: parse l2cap config rsp pending Emeltchenko Andrei
6 siblings, 2 replies; 19+ messages in thread
From: Emeltchenko Andrei @ 2011-08-18 7:45 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Adds extended flowspec option when building l2cap config request
Based upon haijun.liu <haijun.liu@atheros.com> series of patches
(sent Sun, 22 Aug 2010)
---
include/net/bluetooth/l2cap.h | 2 +
net/bluetooth/l2cap_core.c | 79 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 80 insertions(+), 1 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index d2154e0..2350057 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -446,6 +446,8 @@ struct l2cap_conn {
__u32 rx_len;
__u8 tx_ident;
+ __u8 flowspec_ident;
+
__u8 disc_reason;
__u8 preq[7]; /* SMP Pairing Request */
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index f64c9cb..f3663ac 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -541,6 +541,26 @@ static u8 l2cap_get_ident(struct l2cap_conn *conn)
return id;
}
+static inline u8 l2cap_flowspec_ident(struct l2cap_conn *conn)
+{
+ u8 id;
+
+ /* Get next available ident for the flow spec of guaranteed channel.
+ * 2 - 255 are used.
+ */
+
+ spin_lock_bh(&conn->lock);
+
+ if (++conn->flowspec_ident > 256)
+ conn->flowspec_ident = 2;
+
+ id = conn->flowspec_ident;
+
+ spin_unlock_bh(&conn->lock);
+
+ return id;
+}
+
static 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);
@@ -1900,6 +1920,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
{
struct l2cap_conf_req *req = data;
struct l2cap_conf_rfc rfc = { .mode = chan->mode };
+ struct l2cap_conf_efs efs = { .service_type = L2CAP_SERVTYPE_BESTEFFORT };
void *ptr = req->data;
BT_DBG("chan %p", chan);
@@ -1913,7 +1934,20 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
break;
- /* fall through */
+ if (__l2cap_efs_supported(chan)) {
+ chan->ext_flowspec_enable = 1;
+
+ chan->local_stype = L2CAP_SERVTYPE_BESTEFFORT;
+ chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
+ chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ARRIVAL_TIME;
+ chan->local_acc_lat = L2CAP_DEFAULT_ACCESS_LATENCY;
+ chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
+ }
+
+ if (!l2cap_mode_supported(chan->mode, chan->conn->feat_mask))
+ l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
+ break;
+
default:
chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
break;
@@ -1961,6 +1995,34 @@ done:
chan->fcs = L2CAP_FCS_NONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
}
+
+ if (chan->ext_flowspec_enable) {
+ efs.service_type = chan->local_stype;
+ efs.max_sdu_size = cpu_to_le16(chan->local_msdu);
+ efs.sdu_inter_time = cpu_to_le32(chan->local_sdu_itime);
+
+ if (chan->local_stype == L2CAP_SERVTYPE_BESTEFFORT) {
+ chan->local_id = 1;
+ efs.id = chan->local_id;
+ efs.access_latency =
+ cpu_to_le32(L2CAP_DEFAULT_ACCESS_LATENCY);
+ efs.flush_timeout =
+ cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
+ } else {
+ /* As spec, the ident shall be unique within
+ the scope of a physical link.
+ */
+ chan->local_id = l2cap_flowspec_ident(chan->conn);
+ efs.id = chan->local_id;
+ efs.access_latency =
+ cpu_to_le32(chan->local_acc_lat);
+ efs.flush_timeout =
+ cpu_to_le32(chan->local_flush_to);
+ }
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
+ sizeof(efs), (unsigned long) &efs);
+ }
+
break;
case L2CAP_MODE_STREAMING:
@@ -1984,6 +2046,21 @@ done:
chan->fcs = L2CAP_FCS_NONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
}
+
+ if (chan->ext_flowspec_enable) {
+ efs.id = 1;
+ efs.service_type = L2CAP_SERVTYPE_BESTEFFORT;
+ efs.max_sdu_size =
+ cpu_to_le16(chan->local_msdu);
+ efs.sdu_inter_time =
+ cpu_to_le32(chan->local_sdu_itime);
+ efs.access_latency = 0;
+ efs.flush_timeout = 0;
+
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
+ sizeof(efs), (unsigned long) &efs);
+ }
+
break;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [RFC 7/7] Bluetooth: EFS: parse l2cap config rsp pending
2011-08-18 7:44 [RFC 0/7] EFS initial support Emeltchenko Andrei
` (5 preceding siblings ...)
2011-08-18 7:45 ` [RFC 6/7] Bluetooth: add EFS option in l2cap conf req Emeltchenko Andrei
@ 2011-08-18 7:45 ` Emeltchenko Andrei
6 siblings, 0 replies; 19+ messages in thread
From: Emeltchenko Andrei @ 2011-08-18 7:45 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add parsing for L2CAP pending response for EFS. Currently
respond with success when we receive both configuration responses
pending.
---
net/bluetooth/l2cap_core.c | 32 ++++++++++++++++++++++++++++++++
1 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index f3663ac..de9995d 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2765,6 +2765,15 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
chan->num_conf_req++;
}
+ if (test_bit(CONF_REMOTE_PEND, &chan->conf_state)) {
+ /* check compatibility */
+ clear_bit(CONF_LOCAL_PEND, &chan->conf_state);
+ set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
+ l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
+ l2cap_build_conf_rsp(chan, rsp,
+ L2CAP_CONF_SUCCESS, 0x0000), rsp);
+ }
+
unlock:
bh_unlock_sock(sk);
return 0;
@@ -2794,8 +2803,31 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
switch (result) {
case L2CAP_CONF_SUCCESS:
l2cap_conf_rfc_get(chan, rsp->data, len);
+ clear_bit(CONF_REMOTE_PEND, &chan->conf_state);
break;
+ case L2CAP_CONF_PENDING:
+ set_bit(CONF_REMOTE_PEND, &chan->conf_state);
+
+ if (test_bit(CONF_LOCAL_PEND, &chan->conf_state)) {
+ char buf[64];
+
+ len = l2cap_parse_conf_rsp(chan, rsp->data, len,
+ buf, &result);
+ if (len < 0) {
+ l2cap_send_disconn_req(conn, chan, ECONNRESET);
+ goto done;
+ }
+
+ /* check compatibility */
+ clear_bit(CONF_LOCAL_PEND, &chan->conf_state);
+ set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
+ l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
+ l2cap_build_conf_rsp(chan, buf,
+ L2CAP_CONF_SUCCESS, 0x0000), buf);
+ }
+ goto done;
+
case L2CAP_CONF_UNACCEPT:
if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
char req[64];
--
1.7.4.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [RFC 2/7] Bluetooth: EFS: definitions and headers for EFS
2011-08-18 7:44 ` [RFC 2/7] Bluetooth: EFS: definitions and headers for EFS Emeltchenko Andrei
@ 2011-08-24 20:43 ` Gustavo Padovan
2011-08-30 7:52 ` Emeltchenko Andrei
2011-08-24 20:46 ` Gustavo Padovan
1 sibling, 1 reply; 19+ messages in thread
From: Gustavo Padovan @ 2011-08-24 20:43 UTC (permalink / raw)
To: Emeltchenko Andrei; +Cc: linux-bluetooth
Hi Andrei,
* Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2011-08-18 10:44:57 +0300]:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Based upon haijun.liu <haijun.liu@atheros.com> series of patches
> (sent Sun, 22 Aug 2010)
> ---
> include/net/bluetooth/l2cap.h | 37 +++++++++++++++++++++++++++++++++++++
> 1 files changed, 37 insertions(+), 0 deletions(-)
>
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index 9850cb5..d2154e0 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -38,6 +38,9 @@
> #define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */
> #define L2CAP_DEFAULT_ACK_TO 200
> #define L2CAP_LE_DEFAULT_MTU 23
> +#define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF
> +#define L2CAP_DEFAULT_SDU_ARRIVAL_TIME 0xFFFFFFFF
> +#define L2CAP_DEFAULT_ACCESS_LATENCY 0xFFFFFFFF
>
> #define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */
> #define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */
> @@ -218,6 +221,8 @@ struct l2cap_conf_rsp {
> #define L2CAP_CONF_UNACCEPT 0x0001
> #define L2CAP_CONF_REJECT 0x0002
> #define L2CAP_CONF_UNKNOWN 0x0003
> +#define L2CAP_CONF_PENDING 0x0004
> +#define L2CAP_CONF_EFS_REJECT 0x0005
>
> struct l2cap_conf_opt {
> __u8 type;
> @@ -234,6 +239,7 @@ struct l2cap_conf_opt {
> #define L2CAP_CONF_QOS 0x03
> #define L2CAP_CONF_RFC 0x04
> #define L2CAP_CONF_FCS 0x05
> +#define L2CAP_CONF_EFS 0x06
>
> #define L2CAP_CONF_MAX_SIZE 22
>
> @@ -252,6 +258,19 @@ struct l2cap_conf_rfc {
> #define L2CAP_MODE_ERTM 0x03
> #define L2CAP_MODE_STREAMING 0x04
>
> +struct l2cap_conf_efs {
> + __u8 id;
> + __u8 service_type;
> + __le16 max_sdu_size;
> + __le32 sdu_inter_time;
> + __le32 access_latency;
> + __le32 flush_timeout;
> +} __packed;
> +
> +#define L2CAP_SERVTYPE_NOTRAFIC 0x00
> +#define L2CAP_SERVTYPE_BESTEFFORT 0x01
> +#define L2CAP_SERVTYPE_GUARANTEED 0x02
> +
> struct l2cap_disconn_req {
> __le16 dcid;
> __le16 scid;
> @@ -365,6 +384,22 @@ struct l2cap_chan {
> __u8 remote_max_tx;
> __u16 remote_mps;
>
> + __u8 local_id;
> + __u8 local_stype;
> + __u16 local_msdu;
> + __u32 local_sdu_itime;
> + __u32 local_acc_lat;
> + __u32 local_flush_to;
> +
> + __u8 remote_id;
> + __u8 remote_stype;
> + __u16 remote_msdu;
> + __u32 remote_sdu_itime;
> + __u32 remote_acc_lat;
> + __u32 remote_flush_to;
> +
> + __u8 ext_flowspec_enable;
this one could be a flag into conf_state or conn_state.
> +
> struct timer_list chan_timer;
> struct timer_list retrans_timer;
> struct timer_list monitor_timer;
> @@ -452,6 +487,8 @@ enum {
> CONF_CONNECT_PEND,
> CONF_NO_FCS_RECV,
> CONF_STATE2_DEVICE,
> + CONF_LOCAL_PEND,
> + CONF_REMOTE_PEND,
What do CONF_LOCAL_PEND and CONF_REMOTE_PEND mean?
Gustavo
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 2/7] Bluetooth: EFS: definitions and headers for EFS
2011-08-18 7:44 ` [RFC 2/7] Bluetooth: EFS: definitions and headers for EFS Emeltchenko Andrei
2011-08-24 20:43 ` Gustavo Padovan
@ 2011-08-24 20:46 ` Gustavo Padovan
1 sibling, 0 replies; 19+ messages in thread
From: Gustavo Padovan @ 2011-08-24 20:46 UTC (permalink / raw)
To: Emeltchenko Andrei; +Cc: linux-bluetooth
* Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2011-08-18 10:44:57 +0300]:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Based upon haijun.liu <haijun.liu@atheros.com> series of patches
> (sent Sun, 22 Aug 2010)
> ---
> include/net/bluetooth/l2cap.h | 37 +++++++++++++++++++++++++++++++++++++
> 1 files changed, 37 insertions(+), 0 deletions(-)
>
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index 9850cb5..d2154e0 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -38,6 +38,9 @@
> #define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */
> #define L2CAP_DEFAULT_ACK_TO 200
> #define L2CAP_LE_DEFAULT_MTU 23
> +#define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF
> +#define L2CAP_DEFAULT_SDU_ARRIVAL_TIME 0xFFFFFFFF
> +#define L2CAP_DEFAULT_ACCESS_LATENCY 0xFFFFFFFF
>
> #define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */
> #define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */
> @@ -218,6 +221,8 @@ struct l2cap_conf_rsp {
> #define L2CAP_CONF_UNACCEPT 0x0001
> #define L2CAP_CONF_REJECT 0x0002
> #define L2CAP_CONF_UNKNOWN 0x0003
> +#define L2CAP_CONF_PENDING 0x0004
> +#define L2CAP_CONF_EFS_REJECT 0x0005
>
> struct l2cap_conf_opt {
> __u8 type;
> @@ -234,6 +239,7 @@ struct l2cap_conf_opt {
> #define L2CAP_CONF_QOS 0x03
> #define L2CAP_CONF_RFC 0x04
> #define L2CAP_CONF_FCS 0x05
> +#define L2CAP_CONF_EFS 0x06
>
> #define L2CAP_CONF_MAX_SIZE 22
>
> @@ -252,6 +258,19 @@ struct l2cap_conf_rfc {
> #define L2CAP_MODE_ERTM 0x03
> #define L2CAP_MODE_STREAMING 0x04
>
> +struct l2cap_conf_efs {
> + __u8 id;
> + __u8 service_type;
> + __le16 max_sdu_size;
> + __le32 sdu_inter_time;
> + __le32 access_latency;
> + __le32 flush_timeout;
> +} __packed;
> +
> +#define L2CAP_SERVTYPE_NOTRAFIC 0x00
> +#define L2CAP_SERVTYPE_BESTEFFORT 0x01
> +#define L2CAP_SERVTYPE_GUARANTEED 0x02
And these could be only SERV instead of SERVTYPE
Gustavo
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 4/7] Bluetooth: parse EFS in l2cap config request
2011-08-18 7:44 ` [RFC 4/7] Bluetooth: parse EFS in l2cap config request Emeltchenko Andrei
@ 2011-08-24 21:13 ` Gustavo Padovan
2011-08-30 12:28 ` Emeltchenko Andrei
0 siblings, 1 reply; 19+ messages in thread
From: Gustavo Padovan @ 2011-08-24 21:13 UTC (permalink / raw)
To: Emeltchenko Andrei; +Cc: linux-bluetooth
Hi Andrei,
* Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2011-08-18 10:44:59 +0300]:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Add parsing extended flowspec option in L2cap config request
> Based upon haijun.liu <haijun.liu@atheros.com> series of patches
> (sent Sun, 22 Aug 2010)
> ---
> net/bluetooth/l2cap_core.c | 70 ++++++++++++++++++++++++++++++++++++++++++-
> 1 files changed, 68 insertions(+), 2 deletions(-)
>
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index 4167cb0..5378bc6 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -1890,6 +1890,12 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
> }
> }
>
> +static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
> +{
> + return !disable_flowspec &&
> + chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
> +}
> +
> static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
> {
> struct l2cap_conf_req *req = data;
> @@ -1996,6 +2002,8 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
> int type, hint, olen;
> unsigned long val;
> struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
> + struct l2cap_conf_efs efs = { .service_type = L2CAP_SERVTYPE_BESTEFFORT };
> + u8 ext_flowspec_enable = 0;
u8 remote_efs is better and shorter name.
> u16 mtu = L2CAP_DEFAULT_MTU;
> u16 result = L2CAP_CONF_SUCCESS;
>
> @@ -2030,6 +2038,12 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
>
> break;
>
> + case L2CAP_CONF_EFS:
> + ext_flowspec_enable = 1;
> + if (olen == sizeof(efs))
> + memcpy(&efs, (void *) val, olen);
> + break;
> +
> default:
> if (hint)
> break;
> @@ -2052,7 +2066,17 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
> break;
> }
>
> - if (chan->mode != rfc.mode)
> + if (ext_flowspec_enable && __l2cap_efs_supported(chan)) {
> + chan->ext_flowspec_enable = 1;
> +
> + chan->local_stype = L2CAP_SERVTYPE_BESTEFFORT;
> + chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
> + chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ARRIVAL_TIME;
> + chan->local_acc_lat = L2CAP_DEFAULT_ACCESS_LATENCY;
> + chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
> + }
> +
parse_conf_req isn't the best place to initialize channel data. Do in at
channel initializions procedure.
> + if (!l2cap_mode_supported(chan->mode, chan->conn->feat_mask))
> return -ECONNREFUSED;
>
> break;
> @@ -2070,8 +2094,34 @@ done:
> sizeof(rfc), (unsigned long) &rfc);
> }
>
> + /*
> + Add the ext flow spec and ext win size option parameters check here.
> + */
> + if (result == L2CAP_CONF_SUCCESS && ext_flowspec_enable) {
> + if (!chan->ext_flowspec_enable) {
> + /* remote efs support , local efs not supported */
> +
> + result = L2CAP_CONF_REJECT;
> + return -ECONNREFUSED;
> + } else if (chan->local_stype != L2CAP_SERVTYPE_NOTRAFIC &&
> + efs.service_type != L2CAP_SERVTYPE_NOTRAFIC &&
> + efs.service_type != chan->local_stype) {
No need for else, just "if". And what do you want to check for here.
>
> - if (result == L2CAP_CONF_SUCCESS) {
> + result = L2CAP_CONF_UNACCEPT;
> +
> + if (chan->num_conf_req >= 1)
> + return -ECONNREFUSED;
> +
> + l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
> + sizeof(efs), (unsigned long) &efs);
> +
> + } else {
> + result = L2CAP_CONF_PENDING;
> + set_bit(CONF_LOCAL_PEND, &chan->conf_state);
> + }
> + }
> +
> + if (result == L2CAP_CONF_SUCCESS || result == L2CAP_CONF_PENDING) {
> /* Configure output options and let the other side know
> * which ones we don't like. */
If the result is pending do we need to send configurations like RFC again?
what does the spec says about it?
Gustavo
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 5/7] Bluetooth: parse EFS in l2cap config response
2011-08-18 7:45 ` [RFC 5/7] Bluetooth: parse EFS in l2cap config response Emeltchenko Andrei
@ 2011-08-24 21:15 ` Gustavo Padovan
2011-08-30 12:47 ` Emeltchenko Andrei
0 siblings, 1 reply; 19+ messages in thread
From: Gustavo Padovan @ 2011-08-24 21:15 UTC (permalink / raw)
To: Emeltchenko Andrei; +Cc: linux-bluetooth
Hi Andrei,
* Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2011-08-18 10:45:00 +0300]:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Add parsing extended flowspec in l2cap config response
> Based upon haijun.liu <haijun.liu@atheros.com> series of patches
> (sent Sun, 22 Aug 2010)
> ---
> net/bluetooth/l2cap_core.c | 28 +++++++++++++++++++++++++++-
> 1 files changed, 27 insertions(+), 1 deletions(-)
>
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index 5378bc6..f64c9cb 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -2213,6 +2213,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi
> int type, olen;
> unsigned long val;
> struct l2cap_conf_rfc rfc;
> + struct l2cap_conf_efs efs;
>
> BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
>
> @@ -2248,6 +2249,19 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi
> l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
> sizeof(rfc), (unsigned long) &rfc);
> break;
> +
> + case L2CAP_CONF_EFS:
> + if (olen == sizeof(efs))
> + memcpy(&efs, (void *)val, olen);
> +
> + if (chan->local_stype != L2CAP_SERVTYPE_NOTRAFIC &&
> + efs.service_type != L2CAP_SERVTYPE_NOTRAFIC &&
> + efs.service_type != chan->local_stype)
> + return -ECONNREFUSED;
> +
> + l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
> + sizeof(efs), (unsigned long) &efs);
> + break;
> }
> }
>
> @@ -2256,13 +2270,25 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi
>
> chan->mode = rfc.mode;
>
> - if (*result == L2CAP_CONF_SUCCESS) {
> + if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
> switch (rfc.mode) {
> case L2CAP_MODE_ERTM:
> chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
> chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
> chan->mps = le16_to_cpu(rfc.max_pdu_size);
> + if (chan->ext_flowspec_enable) {
> + /* id, service type should not be changed */
> + chan->local_msdu =
> + le16_to_cpu(efs.max_sdu_size);
> + chan->local_sdu_itime =
> + le32_to_cpu(efs.sdu_inter_time);
> + chan->local_acc_lat =
> + le32_to_cpu(efs.access_latency);
> + chan->local_flush_to =
> + le32_to_cpu(efs.flush_timeout);
> + }
These should be the remote_ not the local_ values.
Gustavo
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 6/7] Bluetooth: add EFS option in l2cap conf req
2011-08-18 7:45 ` [RFC 6/7] Bluetooth: add EFS option in l2cap conf req Emeltchenko Andrei
@ 2011-08-24 21:30 ` Gustavo Padovan
2011-08-30 13:54 ` Emeltchenko Andrei
2011-08-24 21:33 ` Gustavo Padovan
1 sibling, 1 reply; 19+ messages in thread
From: Gustavo Padovan @ 2011-08-24 21:30 UTC (permalink / raw)
To: Emeltchenko Andrei; +Cc: linux-bluetooth
Hi Andrei,
* Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2011-08-18 10:45:01 +0300]:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Adds extended flowspec option when building l2cap config request
> Based upon haijun.liu <haijun.liu@atheros.com> series of patches
> (sent Sun, 22 Aug 2010)
Please provide more details in your commit message.
> ---
> include/net/bluetooth/l2cap.h | 2 +
> net/bluetooth/l2cap_core.c | 79 ++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 80 insertions(+), 1 deletions(-)
>
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index d2154e0..2350057 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -446,6 +446,8 @@ struct l2cap_conn {
> __u32 rx_len;
> __u8 tx_ident;
>
> + __u8 flowspec_ident;
> +
> __u8 disc_reason;
>
> __u8 preq[7]; /* SMP Pairing Request */
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index f64c9cb..f3663ac 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -541,6 +541,26 @@ static u8 l2cap_get_ident(struct l2cap_conn *conn)
> return id;
> }
>
> +static inline u8 l2cap_flowspec_ident(struct l2cap_conn *conn)
> +{
> + u8 id;
> +
> + /* Get next available ident for the flow spec of guaranteed channel.
> + * 2 - 255 are used.
> + */
> +
> + spin_lock_bh(&conn->lock);
> +
> + if (++conn->flowspec_ident > 256)
> + conn->flowspec_ident = 2;
> +
> + id = conn->flowspec_ident;
> +
> + spin_unlock_bh(&conn->lock);
> +
> + return id;
> +}
> +
> static 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);
> @@ -1900,6 +1920,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
> {
> struct l2cap_conf_req *req = data;
> struct l2cap_conf_rfc rfc = { .mode = chan->mode };
> + struct l2cap_conf_efs efs = { .service_type = L2CAP_SERVTYPE_BESTEFFORT };
> void *ptr = req->data;
>
> BT_DBG("chan %p", chan);
> @@ -1913,7 +1934,20 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
> if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
> break;
>
> - /* fall through */
> + if (__l2cap_efs_supported(chan)) {
> + chan->ext_flowspec_enable = 1;
> +
> + chan->local_stype = L2CAP_SERVTYPE_BESTEFFORT;
> + chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
> + chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ARRIVAL_TIME;
> + chan->local_acc_lat = L2CAP_DEFAULT_ACCESS_LATENCY;
> + chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
> + }
> +
> + if (!l2cap_mode_supported(chan->mode, chan->conn->feat_mask))
> + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
> + break;
> +
> default:
> chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
> break;
> @@ -1961,6 +1995,34 @@ done:
> chan->fcs = L2CAP_FCS_NONE;
> l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
> }
> +
> + if (chan->ext_flowspec_enable) {
> + efs.service_type = chan->local_stype;
> + efs.max_sdu_size = cpu_to_le16(chan->local_msdu);
> + efs.sdu_inter_time = cpu_to_le32(chan->local_sdu_itime);
> +
> + if (chan->local_stype == L2CAP_SERVTYPE_BESTEFFORT) {
> + chan->local_id = 1;
> + efs.id = chan->local_id;
> + efs.access_latency =
> + cpu_to_le32(L2CAP_DEFAULT_ACCESS_LATENCY);
> + efs.flush_timeout =
> + cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
> + } else {
> + /* As spec, the ident shall be unique within
> + the scope of a physical link.
> + */
> + chan->local_id = l2cap_flowspec_ident(chan->conn);
> + efs.id = chan->local_id;
> + efs.access_latency =
> + cpu_to_le32(chan->local_acc_lat);
> + efs.flush_timeout =
> + cpu_to_le32(chan->local_flush_to);
> + }
> + l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
> + sizeof(efs), (unsigned long) &efs);
> + }
> +
> break;
>
> case L2CAP_MODE_STREAMING:
> @@ -1984,6 +2046,21 @@ done:
> chan->fcs = L2CAP_FCS_NONE;
> l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
> }
> +
> + if (chan->ext_flowspec_enable) {
> + efs.id = 1;
> + efs.service_type = L2CAP_SERVTYPE_BESTEFFORT;
If this patches only adds supports for Best Effort why should care about the
others services types now like the code you added above. Why is the if
(local_service == L2CAP_SERVTYPE_BESTEFFORT) needed then?
Gustavo
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 6/7] Bluetooth: add EFS option in l2cap conf req
2011-08-18 7:45 ` [RFC 6/7] Bluetooth: add EFS option in l2cap conf req Emeltchenko Andrei
2011-08-24 21:30 ` Gustavo Padovan
@ 2011-08-24 21:33 ` Gustavo Padovan
2011-08-30 13:57 ` Emeltchenko Andrei
1 sibling, 1 reply; 19+ messages in thread
From: Gustavo Padovan @ 2011-08-24 21:33 UTC (permalink / raw)
To: Emeltchenko Andrei; +Cc: linux-bluetooth
* Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2011-08-18 10:45:01 +0300]:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Adds extended flowspec option when building l2cap config request
> Based upon haijun.liu <haijun.liu@atheros.com> series of patches
> (sent Sun, 22 Aug 2010)
> ---
> include/net/bluetooth/l2cap.h | 2 +
> net/bluetooth/l2cap_core.c | 79 ++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 80 insertions(+), 1 deletions(-)
>
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index d2154e0..2350057 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -446,6 +446,8 @@ struct l2cap_conn {
> __u32 rx_len;
> __u8 tx_ident;
>
> + __u8 flowspec_ident;
> +
> __u8 disc_reason;
>
> __u8 preq[7]; /* SMP Pairing Request */
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index f64c9cb..f3663ac 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -541,6 +541,26 @@ static u8 l2cap_get_ident(struct l2cap_conn *conn)
> return id;
> }
>
> +static inline u8 l2cap_flowspec_ident(struct l2cap_conn *conn)
> +{
> + u8 id;
> +
> + /* Get next available ident for the flow spec of guaranteed channel.
> + * 2 - 255 are used.
> + */
> +
> + spin_lock_bh(&conn->lock);
> +
> + if (++conn->flowspec_ident > 256)
> + conn->flowspec_ident = 2;
> +
> + id = conn->flowspec_ident;
> +
> + spin_unlock_bh(&conn->lock);
> +
> + return id;
> +}
> +
> static 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);
> @@ -1900,6 +1920,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
> {
> struct l2cap_conf_req *req = data;
> struct l2cap_conf_rfc rfc = { .mode = chan->mode };
> + struct l2cap_conf_efs efs = { .service_type = L2CAP_SERVTYPE_BESTEFFORT };
> void *ptr = req->data;
>
> BT_DBG("chan %p", chan);
> @@ -1913,7 +1934,20 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
> if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
> break;
>
> - /* fall through */
> + if (__l2cap_efs_supported(chan)) {
> + chan->ext_flowspec_enable = 1;
> +
> + chan->local_stype = L2CAP_SERVTYPE_BESTEFFORT;
> + chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
> + chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ARRIVAL_TIME;
> + chan->local_acc_lat = L2CAP_DEFAULT_ACCESS_LATENCY;
> + chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
> + }
> +
> + if (!l2cap_mode_supported(chan->mode, chan->conn->feat_mask))
> + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
> + break;
Could you tell me what this l2cap_send_disconn_req is doing here? it wasn't in
the original code.
Gustavo
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 2/7] Bluetooth: EFS: definitions and headers for EFS
2011-08-24 20:43 ` Gustavo Padovan
@ 2011-08-30 7:52 ` Emeltchenko Andrei
0 siblings, 0 replies; 19+ messages in thread
From: Emeltchenko Andrei @ 2011-08-30 7:52 UTC (permalink / raw)
To: linux-bluetooth
Hi Gustavo,
On Wed, Aug 24, 2011 at 05:43:04PM -0300, Gustavo Padovan wrote:
> Hi Andrei,
>
> * Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2011-08-18 10:44:57 +0300]:
>
> > From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> >
> > Based upon haijun.liu <haijun.liu@atheros.com> series of patches
> > (sent Sun, 22 Aug 2010)
> > ---
> > include/net/bluetooth/l2cap.h | 37 +++++++++++++++++++++++++++++++++++++
> > 1 files changed, 37 insertions(+), 0 deletions(-)
> >
> > diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> > index 9850cb5..d2154e0 100644
> > --- a/include/net/bluetooth/l2cap.h
> > +++ b/include/net/bluetooth/l2cap.h
> > @@ -38,6 +38,9 @@
> > #define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */
> > #define L2CAP_DEFAULT_ACK_TO 200
> > #define L2CAP_LE_DEFAULT_MTU 23
> > +#define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF
> > +#define L2CAP_DEFAULT_SDU_ARRIVAL_TIME 0xFFFFFFFF
> > +#define L2CAP_DEFAULT_ACCESS_LATENCY 0xFFFFFFFF
> >
> > #define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */
> > #define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */
> > @@ -218,6 +221,8 @@ struct l2cap_conf_rsp {
> > #define L2CAP_CONF_UNACCEPT 0x0001
> > #define L2CAP_CONF_REJECT 0x0002
> > #define L2CAP_CONF_UNKNOWN 0x0003
> > +#define L2CAP_CONF_PENDING 0x0004
> > +#define L2CAP_CONF_EFS_REJECT 0x0005
> >
> > struct l2cap_conf_opt {
> > __u8 type;
> > @@ -234,6 +239,7 @@ struct l2cap_conf_opt {
> > #define L2CAP_CONF_QOS 0x03
> > #define L2CAP_CONF_RFC 0x04
> > #define L2CAP_CONF_FCS 0x05
> > +#define L2CAP_CONF_EFS 0x06
> >
> > #define L2CAP_CONF_MAX_SIZE 22
> >
> > @@ -252,6 +258,19 @@ struct l2cap_conf_rfc {
> > #define L2CAP_MODE_ERTM 0x03
> > #define L2CAP_MODE_STREAMING 0x04
> >
> > +struct l2cap_conf_efs {
> > + __u8 id;
> > + __u8 service_type;
> > + __le16 max_sdu_size;
> > + __le32 sdu_inter_time;
> > + __le32 access_latency;
> > + __le32 flush_timeout;
> > +} __packed;
> > +
> > +#define L2CAP_SERVTYPE_NOTRAFIC 0x00
> > +#define L2CAP_SERVTYPE_BESTEFFORT 0x01
> > +#define L2CAP_SERVTYPE_GUARANTEED 0x02
> > +
> > struct l2cap_disconn_req {
> > __le16 dcid;
> > __le16 scid;
> > @@ -365,6 +384,22 @@ struct l2cap_chan {
> > __u8 remote_max_tx;
> > __u16 remote_mps;
> >
> > + __u8 local_id;
> > + __u8 local_stype;
> > + __u16 local_msdu;
> > + __u32 local_sdu_itime;
> > + __u32 local_acc_lat;
> > + __u32 local_flush_to;
> > +
> > + __u8 remote_id;
> > + __u8 remote_stype;
> > + __u16 remote_msdu;
> > + __u32 remote_sdu_itime;
> > + __u32 remote_acc_lat;
> > + __u32 remote_flush_to;
> > +
> > + __u8 ext_flowspec_enable;
>
> this one could be a flag into conf_state or conn_state.
Maybe more logical would be to create flags otherwise it gets mixed
with configuration state flags or connection state flags. Like:
unsigned long flags;
and move other flags here (like flushable)
> > +
> > struct timer_list chan_timer;
> > struct timer_list retrans_timer;
> > struct timer_list monitor_timer;
> > @@ -452,6 +487,8 @@ enum {
> > CONF_CONNECT_PEND,
> > CONF_NO_FCS_RECV,
> > CONF_STATE2_DEVICE,
> > + CONF_LOCAL_PEND,
> > + CONF_REMOTE_PEND,
>
> What do CONF_LOCAL_PEND and CONF_REMOTE_PEND mean?
those pending states mean that configuration request sent with
L2CAP_CONF_PENDING and cleared after receiving L2CAP_CONF_SUCCESS.
Best regards
Andrei Emeltchenko
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 4/7] Bluetooth: parse EFS in l2cap config request
2011-08-24 21:13 ` Gustavo Padovan
@ 2011-08-30 12:28 ` Emeltchenko Andrei
0 siblings, 0 replies; 19+ messages in thread
From: Emeltchenko Andrei @ 2011-08-30 12:28 UTC (permalink / raw)
To: linux-bluetooth
Hi Gustavo,
On Wed, Aug 24, 2011 at 06:13:59PM -0300, Gustavo Padovan wrote:
> Hi Andrei,
>
> * Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2011-08-18 10:44:59 +0300]:
>
> > From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> >
> > Add parsing extended flowspec option in L2cap config request
> > Based upon haijun.liu <haijun.liu@atheros.com> series of patches
> > (sent Sun, 22 Aug 2010)
> > ---
> > net/bluetooth/l2cap_core.c | 70 ++++++++++++++++++++++++++++++++++++++++++-
> > 1 files changed, 68 insertions(+), 2 deletions(-)
> >
> > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> > index 4167cb0..5378bc6 100644
> > --- a/net/bluetooth/l2cap_core.c
> > +++ b/net/bluetooth/l2cap_core.c
> > @@ -1890,6 +1890,12 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
> > }
> > }
> >
> > +static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
> > +{
> > + return !disable_flowspec &&
> > + chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
> > +}
> > +
> > static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
> > {
> > struct l2cap_conf_req *req = data;
> > @@ -1996,6 +2002,8 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
> > int type, hint, olen;
> > unsigned long val;
> > struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
> > + struct l2cap_conf_efs efs = { .service_type = L2CAP_SERVTYPE_BESTEFFORT };
> > + u8 ext_flowspec_enable = 0;
>
> u8 remote_efs is better and shorter name.
OK
>
> > u16 mtu = L2CAP_DEFAULT_MTU;
> > u16 result = L2CAP_CONF_SUCCESS;
> >
> > @@ -2030,6 +2038,12 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
> >
> > break;
> >
> > + case L2CAP_CONF_EFS:
> > + ext_flowspec_enable = 1;
> > + if (olen == sizeof(efs))
> > + memcpy(&efs, (void *) val, olen);
> > + break;
> > +
> > default:
> > if (hint)
> > break;
> > @@ -2052,7 +2066,17 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
> > break;
> > }
> >
> > - if (chan->mode != rfc.mode)
> > + if (ext_flowspec_enable && __l2cap_efs_supported(chan)) {
> > + chan->ext_flowspec_enable = 1;
> > +
> > + chan->local_stype = L2CAP_SERVTYPE_BESTEFFORT;
> > + chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
> > + chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ARRIVAL_TIME;
> > + chan->local_acc_lat = L2CAP_DEFAULT_ACCESS_LATENCY;
> > + chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
> > + }
> > +
>
> parse_conf_req isn't the best place to initialize channel data. Do in at
> channel initializions procedure.
OK, I will move initialization to chan_add but in this case those
parameters will always initialize without checking that other side
supports EFS.
>
> > + if (!l2cap_mode_supported(chan->mode, chan->conn->feat_mask))
> > return -ECONNREFUSED;
> >
> > break;
> > @@ -2070,8 +2094,34 @@ done:
> > sizeof(rfc), (unsigned long) &rfc);
> > }
> >
> > + /*
> > + Add the ext flow spec and ext win size option parameters check here.
> > + */
> > + if (result == L2CAP_CONF_SUCCESS && ext_flowspec_enable) {
> > + if (!chan->ext_flowspec_enable) {
> > + /* remote efs support , local efs not supported */
> > +
> > + result = L2CAP_CONF_REJECT;
> > + return -ECONNREFUSED;
> > + } else if (chan->local_stype != L2CAP_SERVTYPE_NOTRAFIC &&
> > + efs.service_type != L2CAP_SERVTYPE_NOTRAFIC &&
> > + efs.service_type != chan->local_stype) {
>
> No need for else, just "if". And what do you want to check for here.
it checks that service type is the same for sent and receiving Conf Req.
>
> >
> > - if (result == L2CAP_CONF_SUCCESS) {
> > + result = L2CAP_CONF_UNACCEPT;
> > +
> > + if (chan->num_conf_req >= 1)
> > + return -ECONNREFUSED;
> > +
> > + l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
> > + sizeof(efs), (unsigned long) &efs);
> > +
> > + } else {
> > + result = L2CAP_CONF_PENDING;
> > + set_bit(CONF_LOCAL_PEND, &chan->conf_state);
> > + }
> > + }
> > +
> > + if (result == L2CAP_CONF_SUCCESS || result == L2CAP_CONF_PENDING) {
> > /* Configure output options and let the other side know
> > * which ones we don't like. */
>
> If the result is pending do we need to send configurations like RFC again?
> what does the spec says about it?
As I understood if we do not make allowed modification (in rare cases) we
do not need to send EFS again.
Best regards
Andrei Emeltchenko
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 5/7] Bluetooth: parse EFS in l2cap config response
2011-08-24 21:15 ` Gustavo Padovan
@ 2011-08-30 12:47 ` Emeltchenko Andrei
0 siblings, 0 replies; 19+ messages in thread
From: Emeltchenko Andrei @ 2011-08-30 12:47 UTC (permalink / raw)
To: linux-bluetooth
Hi Gustavo,
On Wed, Aug 24, 2011 at 06:15:48PM -0300, Gustavo Padovan wrote:
> Hi Andrei,
>
> * Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2011-08-18 10:45:00 +0300]:
>
> > From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> >
> > Add parsing extended flowspec in l2cap config response
> > Based upon haijun.liu <haijun.liu@atheros.com> series of patches
> > (sent Sun, 22 Aug 2010)
> > ---
> > net/bluetooth/l2cap_core.c | 28 +++++++++++++++++++++++++++-
> > 1 files changed, 27 insertions(+), 1 deletions(-)
> >
> > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> > index 5378bc6..f64c9cb 100644
> > --- a/net/bluetooth/l2cap_core.c
> > +++ b/net/bluetooth/l2cap_core.c
> > @@ -2213,6 +2213,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi
> > int type, olen;
> > unsigned long val;
> > struct l2cap_conf_rfc rfc;
> > + struct l2cap_conf_efs efs;
> >
> > BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
> >
> > @@ -2248,6 +2249,19 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi
> > l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
> > sizeof(rfc), (unsigned long) &rfc);
> > break;
> > +
> > + case L2CAP_CONF_EFS:
> > + if (olen == sizeof(efs))
> > + memcpy(&efs, (void *)val, olen);
> > +
> > + if (chan->local_stype != L2CAP_SERVTYPE_NOTRAFIC &&
> > + efs.service_type != L2CAP_SERVTYPE_NOTRAFIC &&
> > + efs.service_type != chan->local_stype)
> > + return -ECONNREFUSED;
> > +
> > + l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
> > + sizeof(efs), (unsigned long) &efs);
> > + break;
> > }
> > }
> >
> > @@ -2256,13 +2270,25 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi
> >
> > chan->mode = rfc.mode;
> >
> > - if (*result == L2CAP_CONF_SUCCESS) {
> > + if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
> > switch (rfc.mode) {
> > case L2CAP_MODE_ERTM:
> > chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
> > chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
> > chan->mps = le16_to_cpu(rfc.max_pdu_size);
> > + if (chan->ext_flowspec_enable) {
> > + /* id, service type should not be changed */
> > + chan->local_msdu =
> > + le16_to_cpu(efs.max_sdu_size);
> > + chan->local_sdu_itime =
> > + le32_to_cpu(efs.sdu_inter_time);
> > + chan->local_acc_lat =
> > + le32_to_cpu(efs.access_latency);
> > + chan->local_flush_to =
> > + le32_to_cpu(efs.flush_timeout);
> > + }
>
> These should be the remote_ not the local_ values.
As I understood from the Spec:
<------8<-----------------------------------------------------------------------------
| ...
| If the service type is “Best Effort” then values for certain parameters may be
| sent in a Configuration Response with result “Pending” to indicate the
| maximum bandwidth the sender of the Configuration Response is capable to
| receive.
| ...
<------8<-----------------------------------------------------------------------------
BLUETOOTH SPECIFICATION Version 4.0 [Vol 3] page 124 of 656
I have interpreted it as local outgoing parameters.
Best regards
Andrei Emeltchenko
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 6/7] Bluetooth: add EFS option in l2cap conf req
2011-08-24 21:30 ` Gustavo Padovan
@ 2011-08-30 13:54 ` Emeltchenko Andrei
0 siblings, 0 replies; 19+ messages in thread
From: Emeltchenko Andrei @ 2011-08-30 13:54 UTC (permalink / raw)
To: linux-bluetooth
Hi Gustavo,
On Wed, Aug 24, 2011 at 06:30:46PM -0300, Gustavo Padovan wrote:
> Hi Andrei,
>
> * Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2011-08-18 10:45:01 +0300]:
>
> > From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> >
> > Adds extended flowspec option when building l2cap config request
> > Based upon haijun.liu <haijun.liu@atheros.com> series of patches
> > (sent Sun, 22 Aug 2010)
>
> Please provide more details in your commit message.
>
> > ---
> > include/net/bluetooth/l2cap.h | 2 +
> > net/bluetooth/l2cap_core.c | 79 ++++++++++++++++++++++++++++++++++++++++-
> > 2 files changed, 80 insertions(+), 1 deletions(-)
> >
> > diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> > index d2154e0..2350057 100644
> > --- a/include/net/bluetooth/l2cap.h
> > +++ b/include/net/bluetooth/l2cap.h
> > @@ -446,6 +446,8 @@ struct l2cap_conn {
> > __u32 rx_len;
> > __u8 tx_ident;
> >
> > + __u8 flowspec_ident;
> > +
> > __u8 disc_reason;
> >
> > __u8 preq[7]; /* SMP Pairing Request */
> > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> > index f64c9cb..f3663ac 100644
> > --- a/net/bluetooth/l2cap_core.c
> > +++ b/net/bluetooth/l2cap_core.c
> > @@ -541,6 +541,26 @@ static u8 l2cap_get_ident(struct l2cap_conn *conn)
> > return id;
> > }
> >
> > +static inline u8 l2cap_flowspec_ident(struct l2cap_conn *conn)
> > +{
> > + u8 id;
> > +
> > + /* Get next available ident for the flow spec of guaranteed channel.
> > + * 2 - 255 are used.
> > + */
> > +
> > + spin_lock_bh(&conn->lock);
> > +
> > + if (++conn->flowspec_ident > 256)
> > + conn->flowspec_ident = 2;
> > +
> > + id = conn->flowspec_ident;
> > +
> > + spin_unlock_bh(&conn->lock);
> > +
> > + return id;
> > +}
> > +
> > static 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);
> > @@ -1900,6 +1920,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
> > {
> > struct l2cap_conf_req *req = data;
> > struct l2cap_conf_rfc rfc = { .mode = chan->mode };
> > + struct l2cap_conf_efs efs = { .service_type = L2CAP_SERVTYPE_BESTEFFORT };
> > void *ptr = req->data;
> >
> > BT_DBG("chan %p", chan);
> > @@ -1913,7 +1934,20 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
> > if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
> > break;
> >
> > - /* fall through */
> > + if (__l2cap_efs_supported(chan)) {
> > + chan->ext_flowspec_enable = 1;
> > +
> > + chan->local_stype = L2CAP_SERVTYPE_BESTEFFORT;
> > + chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
> > + chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ARRIVAL_TIME;
> > + chan->local_acc_lat = L2CAP_DEFAULT_ACCESS_LATENCY;
> > + chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
> > + }
> > +
> > + if (!l2cap_mode_supported(chan->mode, chan->conn->feat_mask))
> > + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
> > + break;
> > +
> > default:
> > chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
> > break;
> > @@ -1961,6 +1995,34 @@ done:
> > chan->fcs = L2CAP_FCS_NONE;
> > l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
> > }
> > +
> > + if (chan->ext_flowspec_enable) {
> > + efs.service_type = chan->local_stype;
> > + efs.max_sdu_size = cpu_to_le16(chan->local_msdu);
> > + efs.sdu_inter_time = cpu_to_le32(chan->local_sdu_itime);
> > +
> > + if (chan->local_stype == L2CAP_SERVTYPE_BESTEFFORT) {
> > + chan->local_id = 1;
> > + efs.id = chan->local_id;
> > + efs.access_latency =
> > + cpu_to_le32(L2CAP_DEFAULT_ACCESS_LATENCY);
> > + efs.flush_timeout =
> > + cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
> > + } else {
> > + /* As spec, the ident shall be unique within
> > + the scope of a physical link.
> > + */
> > + chan->local_id = l2cap_flowspec_ident(chan->conn);
> > + efs.id = chan->local_id;
> > + efs.access_latency =
> > + cpu_to_le32(chan->local_acc_lat);
> > + efs.flush_timeout =
> > + cpu_to_le32(chan->local_flush_to);
> > + }
> > + l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
> > + sizeof(efs), (unsigned long) &efs);
> > + }
> > +
> > break;
> >
> > case L2CAP_MODE_STREAMING:
> > @@ -1984,6 +2046,21 @@ done:
> > chan->fcs = L2CAP_FCS_NONE;
> > l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
> > }
> > +
> > + if (chan->ext_flowspec_enable) {
> > + efs.id = 1;
> > + efs.service_type = L2CAP_SERVTYPE_BESTEFFORT;
>
> If this patches only adds supports for Best Effort why should care about the
> others services types now like the code you added above. Why is the if
> (local_service == L2CAP_SERVTYPE_BESTEFFORT) needed then?
This is done for the future development.
Best regards
Andrei Emeltchenko
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC 6/7] Bluetooth: add EFS option in l2cap conf req
2011-08-24 21:33 ` Gustavo Padovan
@ 2011-08-30 13:57 ` Emeltchenko Andrei
0 siblings, 0 replies; 19+ messages in thread
From: Emeltchenko Andrei @ 2011-08-30 13:57 UTC (permalink / raw)
To: linux-bluetooth
Hi Gustavo,
On Wed, Aug 24, 2011 at 06:33:24PM -0300, Gustavo Padovan wrote:
> * Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2011-08-18 10:45:01 +0300]:
>
> > From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> >
> > Adds extended flowspec option when building l2cap config request
> > Based upon haijun.liu <haijun.liu@atheros.com> series of patches
> > (sent Sun, 22 Aug 2010)
> > ---
> > include/net/bluetooth/l2cap.h | 2 +
> > net/bluetooth/l2cap_core.c | 79 ++++++++++++++++++++++++++++++++++++++++-
> > 2 files changed, 80 insertions(+), 1 deletions(-)
> >
> > diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> > index d2154e0..2350057 100644
> > --- a/include/net/bluetooth/l2cap.h
> > +++ b/include/net/bluetooth/l2cap.h
> > @@ -446,6 +446,8 @@ struct l2cap_conn {
> > __u32 rx_len;
> > __u8 tx_ident;
> >
> > + __u8 flowspec_ident;
> > +
> > __u8 disc_reason;
> >
> > __u8 preq[7]; /* SMP Pairing Request */
> > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> > index f64c9cb..f3663ac 100644
> > --- a/net/bluetooth/l2cap_core.c
> > +++ b/net/bluetooth/l2cap_core.c
> > @@ -541,6 +541,26 @@ static u8 l2cap_get_ident(struct l2cap_conn *conn)
> > return id;
> > }
> >
> > +static inline u8 l2cap_flowspec_ident(struct l2cap_conn *conn)
> > +{
> > + u8 id;
> > +
> > + /* Get next available ident for the flow spec of guaranteed channel.
> > + * 2 - 255 are used.
> > + */
> > +
> > + spin_lock_bh(&conn->lock);
> > +
> > + if (++conn->flowspec_ident > 256)
> > + conn->flowspec_ident = 2;
> > +
> > + id = conn->flowspec_ident;
> > +
> > + spin_unlock_bh(&conn->lock);
> > +
> > + return id;
> > +}
> > +
> > static 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);
> > @@ -1900,6 +1920,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
> > {
> > struct l2cap_conf_req *req = data;
> > struct l2cap_conf_rfc rfc = { .mode = chan->mode };
> > + struct l2cap_conf_efs efs = { .service_type = L2CAP_SERVTYPE_BESTEFFORT };
> > void *ptr = req->data;
> >
> > BT_DBG("chan %p", chan);
> > @@ -1913,7 +1934,20 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
> > if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
> > break;
> >
> > - /* fall through */
> > + if (__l2cap_efs_supported(chan)) {
> > + chan->ext_flowspec_enable = 1;
> > +
> > + chan->local_stype = L2CAP_SERVTYPE_BESTEFFORT;
> > + chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
> > + chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ARRIVAL_TIME;
> > + chan->local_acc_lat = L2CAP_DEFAULT_ACCESS_LATENCY;
> > + chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
> > + }
> > +
> > + if (!l2cap_mode_supported(chan->mode, chan->conn->feat_mask))
> > + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
> > + break;
>
> Could you tell me what this l2cap_send_disconn_req is doing here? it wasn't in
> the original code.
Removed. The chunk was in the Atheros code.
Best regards
Andrei Emeltchenko
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2011-08-30 13:57 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-18 7:44 [RFC 0/7] EFS initial support Emeltchenko Andrei
2011-08-18 7:44 ` [RFC 1/7] Bluetooth: L2CAP extended feature mask update Emeltchenko Andrei
2011-08-18 7:44 ` [RFC 2/7] Bluetooth: EFS: definitions and headers for EFS Emeltchenko Andrei
2011-08-24 20:43 ` Gustavo Padovan
2011-08-30 7:52 ` Emeltchenko Andrei
2011-08-24 20:46 ` Gustavo Padovan
2011-08-18 7:44 ` [RFC 3/7] Bluetooth: EFS: add disable_flowspec kernel param Emeltchenko Andrei
2011-08-18 7:44 ` [RFC 4/7] Bluetooth: parse EFS in l2cap config request Emeltchenko Andrei
2011-08-24 21:13 ` Gustavo Padovan
2011-08-30 12:28 ` Emeltchenko Andrei
2011-08-18 7:45 ` [RFC 5/7] Bluetooth: parse EFS in l2cap config response Emeltchenko Andrei
2011-08-24 21:15 ` Gustavo Padovan
2011-08-30 12:47 ` Emeltchenko Andrei
2011-08-18 7:45 ` [RFC 6/7] Bluetooth: add EFS option in l2cap conf req Emeltchenko Andrei
2011-08-24 21:30 ` Gustavo Padovan
2011-08-30 13:54 ` Emeltchenko Andrei
2011-08-24 21:33 ` Gustavo Padovan
2011-08-30 13:57 ` Emeltchenko Andrei
2011-08-18 7:45 ` [RFC 7/7] Bluetooth: EFS: parse l2cap config rsp pending Emeltchenko Andrei
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.