* [RFCv2 1/7] Bluetooth: L2CAP extended feature mask update
2011-09-01 11:07 [RFCv2 0/7] EFS: extended flow specification option support Emeltchenko Andrei
@ 2011-09-01 11:07 ` Emeltchenko Andrei
2011-09-01 11:07 ` [RFCv2 2/7] Bluetooth: EFS: definitions and headers for EFS Emeltchenko Andrei
` (5 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Emeltchenko Andrei @ 2011-09-01 11:07 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] 15+ messages in thread
* [RFCv2 2/7] Bluetooth: EFS: definitions and headers for EFS
2011-09-01 11:07 [RFCv2 0/7] EFS: extended flow specification option support Emeltchenko Andrei
2011-09-01 11:07 ` [RFCv2 1/7] Bluetooth: L2CAP extended feature mask update Emeltchenko Andrei
@ 2011-09-01 11:07 ` Emeltchenko Andrei
2011-09-01 11:07 ` [RFCv2 3/7] Bluetooth: EFS: add disable_flowspec kernel param Emeltchenko Andrei
` (4 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Emeltchenko Andrei @ 2011-09-01 11:07 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)
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
include/net/bluetooth/l2cap.h | 41 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 9850cb5..1f26a39 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_SERV_NOTRAFIC 0x00
+#define L2CAP_SERV_BESTEFFORT 0x01
+#define L2CAP_SERV_GUARANTEED 0x02
+
struct l2cap_disconn_req {
__le16 dcid;
__le16 scid;
@@ -346,6 +365,7 @@ struct l2cap_chan {
unsigned long conf_state;
unsigned long conn_state;
+ unsigned long flags;
__u8 next_tx_seq;
__u8 expected_ack_seq;
@@ -365,6 +385,20 @@ 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;
+
struct timer_list chan_timer;
struct timer_list retrans_timer;
struct timer_list monitor_timer;
@@ -452,6 +486,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
@@ -469,6 +505,11 @@ enum {
CONN_RNR_SENT,
};
+/* Definitions for flags in l2cap_chan */
+enum {
+ FLAG_EFS_ENABLE,
+};
+
#define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t))
#define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer)
#define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \
--
1.7.4.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [RFCv2 3/7] Bluetooth: EFS: add disable_flowspec kernel param
2011-09-01 11:07 [RFCv2 0/7] EFS: extended flow specification option support Emeltchenko Andrei
2011-09-01 11:07 ` [RFCv2 1/7] Bluetooth: L2CAP extended feature mask update Emeltchenko Andrei
2011-09-01 11:07 ` [RFCv2 2/7] Bluetooth: EFS: definitions and headers for EFS Emeltchenko Andrei
@ 2011-09-01 11:07 ` Emeltchenko Andrei
2011-09-13 20:17 ` Gustavo Padovan
2011-09-01 11:07 ` [RFCv2 4/7] Bluetooth: parse EFS in l2cap config request Emeltchenko Andrei
` (3 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Emeltchenko Andrei @ 2011-09-01 11:07 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Make extended flowspec option kernel parameter. Disabled by default.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
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] 15+ messages in thread
* Re: [RFCv2 3/7] Bluetooth: EFS: add disable_flowspec kernel param
2011-09-01 11:07 ` [RFCv2 3/7] Bluetooth: EFS: add disable_flowspec kernel param Emeltchenko Andrei
@ 2011-09-13 20:17 ` Gustavo Padovan
2011-09-14 5:30 ` Marcel Holtmann
0 siblings, 1 reply; 15+ messages in thread
From: Gustavo Padovan @ 2011-09-13 20:17 UTC (permalink / raw)
To: Emeltchenko Andrei; +Cc: linux-bluetooth
Hi Andrei,
* Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2011-09-01 14:07:32 +0300]:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Make extended flowspec option kernel parameter. Disabled by default.
>
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> ---
> 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;
I'm not sure if we need one parameter for each feature, I think a
disable_hs (for high speed) could work. This is only to keep the code upstream
while it is not qualified.
Gustavo
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFCv2 3/7] Bluetooth: EFS: add disable_flowspec kernel param
2011-09-13 20:17 ` Gustavo Padovan
@ 2011-09-14 5:30 ` Marcel Holtmann
2011-09-14 8:30 ` Emeltchenko Andrei
0 siblings, 1 reply; 15+ messages in thread
From: Marcel Holtmann @ 2011-09-14 5:30 UTC (permalink / raw)
To: Gustavo Padovan; +Cc: Emeltchenko Andrei, linux-bluetooth
Hi Gustavo,
> >
> > int disable_ertm;
> > +int disable_flowspec = 1;
>
> I'm not sure if we need one parameter for each feature, I think a
> disable_hs (for high speed) could work. This is only to keep the code upstream
> while it is not qualified.
and it should be named enable_hs similar to enable_le.
Regards
Marcel
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFCv2 3/7] Bluetooth: EFS: add disable_flowspec kernel param
2011-09-14 5:30 ` Marcel Holtmann
@ 2011-09-14 8:30 ` Emeltchenko Andrei
2011-09-14 13:38 ` Gustavo Padovan
0 siblings, 1 reply; 15+ messages in thread
From: Emeltchenko Andrei @ 2011-09-14 8:30 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: Gustavo Padovan, linux-bluetooth
Hi,
On Wed, Sep 14, 2011 at 07:30:11AM +0200, Marcel Holtmann wrote:
> > > int disable_ertm;
> > > +int disable_flowspec = 1;
> >
> > I'm not sure if we need one parameter for each feature, I think a
> > disable_hs (for high speed) could work. This is only to keep the code upstream
> > while it is not qualified.
>
> and it should be named enable_hs similar to enable_le.
I can change this to enable_hs despite IMO those L2CAP features are not
tight to HS.
Best regards
Andrei Emeltchenko
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFCv2 3/7] Bluetooth: EFS: add disable_flowspec kernel param
2011-09-14 8:30 ` Emeltchenko Andrei
@ 2011-09-14 13:38 ` Gustavo Padovan
0 siblings, 0 replies; 15+ messages in thread
From: Gustavo Padovan @ 2011-09-14 13:38 UTC (permalink / raw)
To: Emeltchenko Andrei, Marcel Holtmann, linux-bluetooth
* Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2011-09-14 11:30:59 +0300]:
> Hi,
>
> On Wed, Sep 14, 2011 at 07:30:11AM +0200, Marcel Holtmann wrote:
> > > > int disable_ertm;
> > > > +int disable_flowspec = 1;
> > >
> > > I'm not sure if we need one parameter for each feature, I think a
> > > disable_hs (for high speed) could work. This is only to keep the code upstream
> > > while it is not qualified.
> >
> > and it should be named enable_hs similar to enable_le.
>
> I can change this to enable_hs despite IMO those L2CAP features are not
> tight to HS.
Sure, but they will be used most with high_speed, so enable_hs makes sense.
Gustavo
^ permalink raw reply [flat|nested] 15+ messages in thread
* [RFCv2 4/7] Bluetooth: parse EFS in l2cap config request
2011-09-01 11:07 [RFCv2 0/7] EFS: extended flow specification option support Emeltchenko Andrei
` (2 preceding siblings ...)
2011-09-01 11:07 ` [RFCv2 3/7] Bluetooth: EFS: add disable_flowspec kernel param Emeltchenko Andrei
@ 2011-09-01 11:07 ` Emeltchenko Andrei
2011-09-13 20:32 ` Gustavo Padovan
2011-09-01 11:07 ` [RFCv2 5/7] Bluetooth: parse EFS in l2cap config response Emeltchenko Andrei
` (2 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Emeltchenko Andrei @ 2011-09-01 11:07 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)
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
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..b7f36da 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -338,6 +338,14 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
chan->omtu = L2CAP_DEFAULT_MTU;
}
+ if (!disable_flowspec) {
+ chan->local_stype = L2CAP_SERV_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;
+ }
+
chan_hold(chan);
list_add(&chan->list, &conn->chan_l);
@@ -1890,6 +1898,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 +2010,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_SERV_BESTEFFORT };
+ u8 remote_efs = 0;
u16 mtu = L2CAP_DEFAULT_MTU;
u16 result = L2CAP_CONF_SUCCESS;
@@ -2027,7 +2043,12 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
case L2CAP_CONF_FCS:
if (val == L2CAP_FCS_NONE)
set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
+ break;
+ case L2CAP_CONF_EFS:
+ remote_efs = 1;
+ if (olen == sizeof(efs))
+ memcpy(&efs, (void *) val, olen);
break;
default:
@@ -2052,7 +2073,10 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
break;
}
- if (chan->mode != rfc.mode)
+ if (remote_efs && __l2cap_efs_supported(chan))
+ set_bit(FLAG_EFS_ENABLE, &chan->flags);
+
+ if (!l2cap_mode_supported(chan->mode, chan->conn->feat_mask))
return -ECONNREFUSED;
break;
@@ -2070,8 +2094,35 @@ done:
sizeof(rfc), (unsigned long) &rfc);
}
+ /*
+ Add extended flow specification option check here.
+ */
+ if (result == L2CAP_CONF_SUCCESS && remote_efs) {
+ if (!test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
+ /* remote efs support , local efs not supported */
+
+ result = L2CAP_CONF_REJECT;
+ return -ECONNREFUSED;
+ }
+
+ if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
+ efs.service_type != L2CAP_SERV_NOTRAFIC &&
+ efs.service_type != chan->local_stype) {
+
+ result = L2CAP_CONF_UNACCEPT;
+
+ if (chan->num_conf_req >= 1)
+ return -ECONNREFUSED;
- if (result == L2CAP_CONF_SUCCESS) {
+ 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 +2159,21 @@ done:
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
sizeof(rfc), (unsigned long) &rfc);
+ if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
+ 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] 15+ messages in thread
* Re: [RFCv2 4/7] Bluetooth: parse EFS in l2cap config request
2011-09-01 11:07 ` [RFCv2 4/7] Bluetooth: parse EFS in l2cap config request Emeltchenko Andrei
@ 2011-09-13 20:32 ` Gustavo Padovan
0 siblings, 0 replies; 15+ messages in thread
From: Gustavo Padovan @ 2011-09-13 20:32 UTC (permalink / raw)
To: Emeltchenko Andrei; +Cc: linux-bluetooth
Hi Andrei,
* Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2011-09-01 14:07:33 +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)
>
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> ---
> 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..b7f36da 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -338,6 +338,14 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
> chan->omtu = L2CAP_DEFAULT_MTU;
> }
>
> + if (!disable_flowspec) {
We don't need this check, it doesn't hurt set these param wihout flowspec
enabled.
Gustavo
^ permalink raw reply [flat|nested] 15+ messages in thread
* [RFCv2 5/7] Bluetooth: parse EFS in l2cap config response
2011-09-01 11:07 [RFCv2 0/7] EFS: extended flow specification option support Emeltchenko Andrei
` (3 preceding siblings ...)
2011-09-01 11:07 ` [RFCv2 4/7] Bluetooth: parse EFS in l2cap config request Emeltchenko Andrei
@ 2011-09-01 11:07 ` Emeltchenko Andrei
2011-09-01 11:07 ` [RFCv2 6/7] Bluetooth: add EFS option in l2cap conf req Emeltchenko Andrei
2011-09-01 11:07 ` [RFCv2 7/7] Bluetooth: EFS: parse l2cap config rsp pending Emeltchenko Andrei
6 siblings, 0 replies; 15+ messages in thread
From: Emeltchenko Andrei @ 2011-09-01 11:07 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)
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
net/bluetooth/l2cap_core.c | 29 ++++++++++++++++++++++++++++-
1 files changed, 28 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index b7f36da..02908f0 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_SERV_NOTRAFIC &&
+ efs.service_type != L2CAP_SERV_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,26 @@ 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 (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
+ /* 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] 15+ messages in thread
* [RFCv2 6/7] Bluetooth: add EFS option in l2cap conf req
2011-09-01 11:07 [RFCv2 0/7] EFS: extended flow specification option support Emeltchenko Andrei
` (4 preceding siblings ...)
2011-09-01 11:07 ` [RFCv2 5/7] Bluetooth: parse EFS in l2cap config response Emeltchenko Andrei
@ 2011-09-01 11:07 ` Emeltchenko Andrei
2011-09-01 12:45 ` Szymon Janc
2011-09-01 11:07 ` [RFCv2 7/7] Bluetooth: EFS: parse l2cap config rsp pending Emeltchenko Andrei
6 siblings, 1 reply; 15+ messages in thread
From: Emeltchenko Andrei @ 2011-09-01 11:07 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Adds extended flowspec option when building l2cap config request
EFS is added if both the local and remote L2CAP entities have
indicated support for the Extended Flow Specification for BR/EDR
Based upon haijun.liu <haijun.liu@atheros.com> series of patches
(sent Sun, 22 Aug 2010)
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
include/net/bluetooth/l2cap.h | 2 +
net/bluetooth/l2cap_core.c | 70 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 71 insertions(+), 1 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 1f26a39..fc81771 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -445,6 +445,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 02908f0..c2c5eb7 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -549,6 +549,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);
@@ -1908,6 +1928,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_SERV_BESTEFFORT };
void *ptr = req->data;
BT_DBG("chan %p", chan);
@@ -1921,7 +1942,11 @@ 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))
+ set_bit(FLAG_EFS_ENABLE, &chan->flags);
+
+ break;
+
default:
chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
break;
@@ -1961,6 +1986,33 @@ done:
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
(unsigned long) &rfc);
+ if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
+ 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_SERV_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);
+ }
+
if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
break;
@@ -1969,6 +2021,7 @@ done:
chan->fcs = L2CAP_FCS_NONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
}
+
break;
case L2CAP_MODE_STREAMING:
@@ -1984,6 +2037,20 @@ done:
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
(unsigned long) &rfc);
+ if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
+ efs.id = 1;
+ efs.service_type = L2CAP_SERV_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);
+ }
+
if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
break;
@@ -1992,6 +2059,7 @@ done:
chan->fcs = L2CAP_FCS_NONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
}
+
break;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [RFCv2 6/7] Bluetooth: add EFS option in l2cap conf req
2011-09-01 11:07 ` [RFCv2 6/7] Bluetooth: add EFS option in l2cap conf req Emeltchenko Andrei
@ 2011-09-01 12:45 ` Szymon Janc
2011-09-02 7:25 ` Emeltchenko Andrei
0 siblings, 1 reply; 15+ messages in thread
From: Szymon Janc @ 2011-09-01 12:45 UTC (permalink / raw)
To: Emeltchenko Andrei; +Cc: linux-bluetooth
Hi Andrei,
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Adds extended flowspec option when building l2cap config request
> EFS is added if both the local and remote L2CAP entities have
> indicated support for the Extended Flow Specification for BR/EDR
>
> Based upon haijun.liu <haijun.liu@atheros.com> series of patches
> (sent Sun, 22 Aug 2010)
>
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> ---
> include/net/bluetooth/l2cap.h | 2 +
> net/bluetooth/l2cap_core.c | 70 ++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 71 insertions(+), 1 deletions(-)
>
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index 1f26a39..fc81771 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -445,6 +445,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 02908f0..c2c5eb7 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -549,6 +549,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;
flowspec_ident is u8, shouldn't this be 'if (++conn->flowspec_ident < 2)' ?
Also shouldn't you check if there is no channel with specified id before using that id?
> +
> + 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);
> @@ -1908,6 +1928,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_SERV_BESTEFFORT };
> void *ptr = req->data;
>
> BT_DBG("chan %p", chan);
> @@ -1921,7 +1942,11 @@ 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))
> + set_bit(FLAG_EFS_ENABLE, &chan->flags);
> +
> + break;
> +
> default:
> chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
> break;
> @@ -1961,6 +1986,33 @@ done:
> l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
> (unsigned long) &rfc);
>
> + if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
> + 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_SERV_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);
> + }
> +
> if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
> break;
>
> @@ -1969,6 +2021,7 @@ done:
> chan->fcs = L2CAP_FCS_NONE;
> l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
> }
> +
> break;
>
> case L2CAP_MODE_STREAMING:
> @@ -1984,6 +2037,20 @@ done:
> l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
> (unsigned long) &rfc);
>
> + if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
> + efs.id = 1;
> + efs.service_type = L2CAP_SERV_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);
> + }
> +
> if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
> break;
>
> @@ -1992,6 +2059,7 @@ done:
> chan->fcs = L2CAP_FCS_NONE;
> l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
> }
> +
> break;
> }
>
>
--
BR
Szymon Janc
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFCv2 6/7] Bluetooth: add EFS option in l2cap conf req
2011-09-01 12:45 ` Szymon Janc
@ 2011-09-02 7:25 ` Emeltchenko Andrei
0 siblings, 0 replies; 15+ messages in thread
From: Emeltchenko Andrei @ 2011-09-02 7:25 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
Hi Szymon,
On Thu, Sep 01, 2011 at 02:45:03PM +0200, Szymon Janc wrote:
> Hi Andrei,
>
> > From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> >
> > Adds extended flowspec option when building l2cap config request
> > EFS is added if both the local and remote L2CAP entities have
> > indicated support for the Extended Flow Specification for BR/EDR
> >
> > Based upon haijun.liu <haijun.liu@atheros.com> series of patches
> > (sent Sun, 22 Aug 2010)
> >
> > Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> > ---
> > include/net/bluetooth/l2cap.h | 2 +
> > net/bluetooth/l2cap_core.c | 70 ++++++++++++++++++++++++++++++++++++++++-
> > 2 files changed, 71 insertions(+), 1 deletions(-)
> >
> > diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> > index 1f26a39..fc81771 100644
> > --- a/include/net/bluetooth/l2cap.h
> > +++ b/include/net/bluetooth/l2cap.h
> > @@ -445,6 +445,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 02908f0..c2c5eb7 100644
> > --- a/net/bluetooth/l2cap_core.c
> > +++ b/net/bluetooth/l2cap_core.c
> > @@ -549,6 +549,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;
>
> flowspec_ident is u8, shouldn't this be 'if (++conn->flowspec_ident < 2)' ?
> Also shouldn't you check if there is no channel with specified id before using that id?
Yes you are right here. But I am thinking to drop this function as we
might to support only Best Effort with fixed ident.
Best regards
Andrei Emeltchenko
>
> > +
> > + 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);
> > @@ -1908,6 +1928,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_SERV_BESTEFFORT };
> > void *ptr = req->data;
> >
> > BT_DBG("chan %p", chan);
> > @@ -1921,7 +1942,11 @@ 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))
> > + set_bit(FLAG_EFS_ENABLE, &chan->flags);
> > +
> > + break;
> > +
> > default:
> > chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
> > break;
> > @@ -1961,6 +1986,33 @@ done:
> > l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
> > (unsigned long) &rfc);
> >
> > + if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
> > + 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_SERV_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);
> > + }
> > +
> > if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
> > break;
> >
> > @@ -1969,6 +2021,7 @@ done:
> > chan->fcs = L2CAP_FCS_NONE;
> > l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
> > }
> > +
> > break;
> >
> > case L2CAP_MODE_STREAMING:
> > @@ -1984,6 +2037,20 @@ done:
> > l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
> > (unsigned long) &rfc);
> >
> > + if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
> > + efs.id = 1;
> > + efs.service_type = L2CAP_SERV_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);
> > + }
> > +
> > if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
> > break;
> >
> > @@ -1992,6 +2059,7 @@ done:
> > chan->fcs = L2CAP_FCS_NONE;
> > l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
> > }
> > +
> > break;
> > }
> >
> >
>
> --
> BR
> Szymon Janc
^ permalink raw reply [flat|nested] 15+ messages in thread
* [RFCv2 7/7] Bluetooth: EFS: parse l2cap config rsp pending
2011-09-01 11:07 [RFCv2 0/7] EFS: extended flow specification option support Emeltchenko Andrei
` (5 preceding siblings ...)
2011-09-01 11:07 ` [RFCv2 6/7] Bluetooth: add EFS option in l2cap conf req Emeltchenko Andrei
@ 2011-09-01 11:07 ` Emeltchenko Andrei
6 siblings, 0 replies; 15+ messages in thread
From: Emeltchenko Andrei @ 2011-09-01 11:07 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.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
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 c2c5eb7..cb5ddbf 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2757,6 +2757,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;
@@ -2786,8 +2795,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] 15+ messages in thread