Skip to content

Commit

Permalink
Bluetooth: EFS: add efs option in L2CAP conf req
Browse files Browse the repository at this point in the history
Add Extended Flow Specification option when building L2CAP
Configuration Request. EFS is added if both the local and
remote L2CAP entities have indicated support for the
Extended Flow Specification for BR/EDR.

...
< 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 0x01f8
        Enhanced Retransmission mode
        Streaming mode
        FCS Option
        Extended Flow Specification
        Fixed Channels
        Extended Window Size
...
< ACL data: handle 1 flags 0x00 dlen 45
    L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 33
      RFC 0x03 (Enhanced Retransmission, TxWin 63, MaxTx 3, RTo 0, MTo 0, MPS 498)
      EFS (Id 0x01, SerType Best Effort, MaxSDU 0xffff, SDUitime 0xffffffff,
          AccLat 0xffffffff, FlushTO 0x0000ffff)
...

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>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
  • Loading branch information
Andrei Emeltchenko authored and Gustavo F. Padovan committed Oct 13, 2011
1 parent 8f7975b commit f89cef0
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions net/bluetooth/l2cap_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1870,6 +1870,37 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
*ptr += L2CAP_CONF_OPT_SIZE + len;
}

static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
{
struct l2cap_conf_efs efs;

switch(chan->mode) {
case L2CAP_MODE_ERTM:
efs.id = chan->local_id;
efs.stype = chan->local_stype;
efs.msdu = cpu_to_le16(chan->local_msdu);
efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
efs.acc_lat = cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
efs.flush_to = cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
break;

case L2CAP_MODE_STREAMING:
efs.id = 1;
efs.stype = L2CAP_SERV_BESTEFFORT;
efs.msdu = cpu_to_le16(chan->local_msdu);
efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
efs.acc_lat = 0;
efs.flush_to = 0;
break;

default:
return;
}

l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
(unsigned long) &efs);
}

static void l2cap_ack_timeout(unsigned long arg)
{
struct l2cap_chan *chan = (void *) arg;
Expand Down Expand Up @@ -1921,6 +1952,11 @@ static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
}

static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
{
return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
}

static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
{
if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Expand Down Expand Up @@ -1949,6 +1985,9 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
break;

if (__l2cap_efs_supported(chan))
set_bit(FLAG_EFS_ENABLE, &chan->flags);

/* fall through */
default:
chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Expand Down Expand Up @@ -1993,6 +2032,9 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
(unsigned long) &rfc);

if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
l2cap_add_opt_efs(&ptr, chan);

if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
break;

Expand Down Expand Up @@ -2020,6 +2062,9 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
(unsigned long) &rfc);

if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
l2cap_add_opt_efs(&ptr, chan);

if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
break;

Expand Down

0 comments on commit f89cef0

Please sign in to comment.