Bluetooth: L2CAP: Fix L2CAP_ECRED_CONN_RSP response
L2CAP_ECRED_CONN_RSP needs to respond DCID in the same order received as
SCID but the order is reversed due to use of list_add which actually
prepend channels to the list so the response is reversed:
> ACL Data RX: Handle 16 flags 0x02 dlen 26
LE L2CAP: Enhanced Credit Connection Request (0x17) ident 2 len 18
PSM: 39 (0x0027)
MTU: 256
MPS: 251
Credits: 65535
Source CID: 116
Source CID: 117
Source CID: 118
Source CID: 119
Source CID: 120
< ACL Data TX: Handle 16 flags 0x00 dlen 26
LE L2CAP: Enhanced Credit Connection Response (0x18) ident 2 len 18
MTU: 517
MPS: 247
Credits: 3
Result: Connection successful (0x0000)
Destination CID: 68
Destination CID: 67
Destination CID: 66
Destination CID: 65
Destination CID: 64
Also make sure the response don't include channels that are not on
BT_CONNECT2 since the chan->ident can be set to the same value as in the
following trace:
< ACL Data TX: Handle 16 flags 0x00 dlen 12
LE L2CAP: LE Flow Control Credit (0x16) ident 6 len 4
Source CID: 64
Credits: 1
...
> ACL Data RX: Handle 16 flags 0x02 dlen 18
LE L2CAP: Enhanced Credit Connection Request (0x17) ident 6 len 10
PSM: 39 (0x0027)
MTU: 517
MPS: 251
Credits: 255
Source CID: 70
< ACL Data TX: Handle 16 flags 0x00 dlen 20
LE L2CAP: Enhanced Credit Connection Response (0x18) ident 6 len 12
MTU: 517
MPS: 247
Credits: 3
Result: Connection successful (0x0000)
Destination CID: 64
Destination CID: 68
Closes: https://github.com/bluez/bluez/issues/1094
Fixes: 9aa9d9473f
("Bluetooth: L2CAP: Fix responding with wrong PDU type")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
bd30e8d7bf
commit
b25120e1d5
1 changed files with 7 additions and 2 deletions
|
@ -632,7 +632,8 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
|
|||
test_bit(FLAG_HOLD_HCI_CONN, &chan->flags))
|
||||
hci_conn_hold(conn->hcon);
|
||||
|
||||
list_add(&chan->list, &conn->chan_l);
|
||||
/* Append to the list since the order matters for ECRED */
|
||||
list_add_tail(&chan->list, &conn->chan_l);
|
||||
}
|
||||
|
||||
void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
|
||||
|
@ -3771,7 +3772,11 @@ static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data)
|
|||
struct l2cap_ecred_conn_rsp *rsp_flex =
|
||||
container_of(&rsp->pdu.rsp, struct l2cap_ecred_conn_rsp, hdr);
|
||||
|
||||
if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
|
||||
/* Check if channel for outgoing connection or if it wasn't deferred
|
||||
* since in those cases it must be skipped.
|
||||
*/
|
||||
if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags) ||
|
||||
!test_and_clear_bit(FLAG_DEFER_SETUP, &chan->flags))
|
||||
return;
|
||||
|
||||
/* Reset ident so only one response is sent */
|
||||
|
|
Loading…
Add table
Reference in a new issue