aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>2011-10-17 07:35:32 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-11-07 14:24:43 -0500
commit0e8b207e8a4442f1a662e1a3827e61e40279630a (patch)
treef739fe7996b50d3e6ea434bf68e380d4dbf6ed7f /net
parentc3eae82a844bb33e8182c7ee81828516b51ad642 (diff)
Bluetooth: EFS: implement L2CAP config pending state
Add L2CAP Config Pending state for EFS. Currently after receiving Config Response Pending respond with Config Response Success. ... > 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 0x02 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 1009) EFS (Id 0x01, SerType Best Effort, MaxSDU 0xffff, SDUitime 0xffffffff, AccLat 0xffffffff, FlushTO 0x0000ffff) < 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) < 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 498) 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 498) EFS (Id 0x01, SerType Best Effort, MaxSDU 0xffff, SDUitime 0xffffffff, AccLat 0xffffffff, FlushTO 0x0000ffff) > 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 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 ext_ctrl 0x00010000 fcs 0xebe0 [psm 4113] I-frame: Start (len 672) TxSeq 0 ReqSeq 0 ... Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/l2cap_core.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index bda6da797734..c12d3bf08a42 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2239,6 +2239,11 @@ done:
2239 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, 2239 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
2240 sizeof(efs), 2240 sizeof(efs),
2241 (unsigned long) &efs); 2241 (unsigned long) &efs);
2242 } else {
2243 /* Send PENDING Conf Rsp and mark state
2244 local PENDING */
2245 result = L2CAP_CONF_PENDING;
2246 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
2242 } 2247 }
2243 } 2248 }
2244 2249
@@ -2379,7 +2384,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi
2379 2384
2380 chan->mode = rfc.mode; 2385 chan->mode = rfc.mode;
2381 2386
2382 if (*result == L2CAP_CONF_SUCCESS) { 2387 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
2383 switch (rfc.mode) { 2388 switch (rfc.mode) {
2384 case L2CAP_MODE_ERTM: 2389 case L2CAP_MODE_ERTM:
2385 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); 2390 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
@@ -2785,6 +2790,21 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
2785 chan->num_conf_req++; 2790 chan->num_conf_req++;
2786 } 2791 }
2787 2792
2793 /* Got Conf Rsp PENDING from remote side and asume we sent
2794 Conf Rsp PENDING in the code above */
2795 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
2796 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
2797
2798 /* check compatibility */
2799
2800 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
2801 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
2802
2803 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2804 l2cap_build_conf_rsp(chan, rsp,
2805 L2CAP_CONF_SUCCESS, 0x0000), rsp);
2806 }
2807
2788unlock: 2808unlock:
2789 bh_unlock_sock(sk); 2809 bh_unlock_sock(sk);
2790 return 0; 2810 return 0;
@@ -2814,8 +2834,33 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
2814 switch (result) { 2834 switch (result) {
2815 case L2CAP_CONF_SUCCESS: 2835 case L2CAP_CONF_SUCCESS:
2816 l2cap_conf_rfc_get(chan, rsp->data, len); 2836 l2cap_conf_rfc_get(chan, rsp->data, len);
2837 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
2817 break; 2838 break;
2818 2839
2840 case L2CAP_CONF_PENDING:
2841 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
2842
2843 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
2844 char buf[64];
2845
2846 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
2847 buf, &result);
2848 if (len < 0) {
2849 l2cap_send_disconn_req(conn, chan, ECONNRESET);
2850 goto done;
2851 }
2852
2853 /* check compatibility */
2854
2855 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
2856 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
2857
2858 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
2859 l2cap_build_conf_rsp(chan, buf,
2860 L2CAP_CONF_SUCCESS, 0x0000), buf);
2861 }
2862 goto done;
2863
2819 case L2CAP_CONF_UNACCEPT: 2864 case L2CAP_CONF_UNACCEPT:
2820 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) { 2865 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
2821 char req[64]; 2866 char req[64];