Enable use of L2CAP_MODE_EXT_FLOWCTL
Subsystems (2)
Luiz Augusto von Dentz
maintainerv5 cover Enable use of L2CAP_MODE_EXT_FLOWCTL
From: Luiz Augusto von Dentz <[email protected]>
This enables use of BT_MODE_EXT_FLOWCTL with BT_MODE socketopt, in addition to that add support for DEFER_SETUP to be used with client sockets so they can be grouped and sent together.
BT_MODE is not compatible with L2CAP_OPTIONS so attempting to use them both will cause an error to be returned to the applicatio.
This has been tested by introducing support for L2CAP_MODE_EXT_FLOWCTL into l2cap-tester which now produces the following trace:
Enable ecred PDUs:
#echo 1 > /sys/module/bluetooth/parameters/enable_ecred
#sudo tools/l2cap-tester -p "L2CAP Ext-Flowctl"
L2CAP Ext-Flowctl Client - Success - init
Read Index List callback
Status: 0x00
New hciemu instance created
Index Added callback
Index: 0x0000
Read Info callback
Status: 0x00
Address: 00:AA:01:00:00:00
Version: 0x09
Manufacturer: 0x003f
Supported settings: 0x0001be1b
Current settings: 0x00000200
Class: 0x000000
Name:
Short name:L2CAP Ext-Flowctl Client - Success - setup
Powering on controller
Controller powered on
Client set connectable status 0x00
L2CAP Ext-Flowctl Client - Success - setup complete L2CAP Ext-Flowctl Client - Success - run
Connect in progress
Successfully connected
L2CAP Ext-Flowctl Client - Success - test passed L2CAP Ext-Flowctl Client - Success - teardown
Index Removed callback
Index: 0x0000
L2CAP Ext-Flowctl Client - Success - teardown complete L2CAP Ext-Flowctl Client - Success - done
L2CAP Ext-Flowctl Client, Direct Advertising - Success - init
Read Index List callback
Status: 0x00
New hciemu instance created
Index Added callback
Index: 0x0000
Read Info callback
Status: 0x00
Address: 00:AA:01:00:00:00
Version: 0x09
Manufacturer: 0x003f
Supported settings: 0x0001be1b
Current settings: 0x00000200
Class: 0x000000
Name:
Short name:L2CAP Ext-Flowctl Client, Direct Advertising - Success - setup
Powering on controller
Controller powered on
Client set connectable status 0x00
L2CAP Ext-Flowctl Client, Direct Advertising - Success - setup complete L2CAP Ext-Flowctl Client, Direct Advertising - Success - run
Connect in progress
Received advertising parameters HCI command
L2CAP Ext-Flowctl Client, Direct Advertising - Success - test passed L2CAP Ext-Flowctl Client, Direct Advertising - Success - teardown
Index Removed callback
Index: 0x0000
L2CAP Ext-Flowctl Client, Direct Advertising - Success - teardown complete L2CAP Ext-Flowctl Client, Direct Advertising - Success - done
L2CAP Ext-Flowctl Client SMP - Success - init
Read Index List callback
Status: 0x00
New hciemu instance created
Index Added callback
Index: 0x0000
Read Info callback
Status: 0x00
Address: 00:AA:01:00:00:00
Version: 0x09
Manufacturer: 0x003f
Supported settings: 0x0001be1b
Current settings: 0x00000200
Class: 0x000000
Name:
Short name:L2CAP Ext-Flowctl Client SMP - Success - setup
Powering on controller
Controller powered on
Client set connectable status 0x00
L2CAP Ext-Flowctl Client SMP - Success - setup complete L2CAP Ext-Flowctl Client SMP - Success - run
Connect in progress
Successfully connected
L2CAP Ext-Flowctl Client SMP - Success - test passed L2CAP Ext-Flowctl Client SMP - Success - teardown
Index Removed callback
Index: 0x0000
L2CAP Ext-Flowctl Client SMP - Success - teardown complete L2CAP Ext-Flowctl Client SMP - Success - done
L2CAP Ext-Flowctl Client - Command Reject - init
Read Index List callback
Status: 0x00
New hciemu instance created
Index Added callback
Index: 0x0000
Read Info callback
Status: 0x00
Address: 00:AA:01:00:00:00
Version: 0x09
Manufacturer: 0x003f
Supported settings: 0x0001be1b
Current settings: 0x00000200
Class: 0x000000
Name:
Short name:L2CAP Ext-Flowctl Client - Command Reject - setup
Powering on controller
Controller powered on
Client set connectable status 0x00
L2CAP Ext-Flowctl Client - Command Reject - setup complete L2CAP Ext-Flowctl Client - Command Reject - run
Connect in progress
New connection with handle 0x002a
Connect failed: Connection refused (111)
L2CAP Ext-Flowctl Client - Command Reject - test passed L2CAP Ext-Flowctl Client - Command Reject - teardown
Index Removed callback
Index: 0x0000
L2CAP Ext-Flowctl Client - Command Reject - teardown complete L2CAP Ext-Flowctl Client - Command Reject - done
L2CAP Ext-Flowctl Client - Open two sockets - init
Read Index List callback
Status: 0x00
New hciemu instance created
Index Added callback
Index: 0x0000
Read Info callback
Status: 0x00
Address: 00:AA:01:00:00:00
Version: 0x09
Manufacturer: 0x003f
Supported settings: 0x0001be1b
Current settings: 0x00000200
Class: 0x000000
Name:
Short name:L2CAP Ext-Flowctl Client - Open two sockets - setup
Powering on controller
Controller powered on
L2CAP Ext-Flowctl Client - Open two sockets - setup complete L2CAP Ext-Flowctl Client - Open two sockets - run
Connect in progress, sk = 19 (deferred)
HCI Command 0x200b length 7
HCI Command 0x200c length 2
Connect in progress, sk = 20
Client set connectable status 0x00
HCI Command 0x200c length 2
HCI Command 0x200d length 25
HCI Command 0x2016 length 2
Successfully connected
Successfully connected
L2CAP Ext-Flowctl Client - Open two sockets - test passed L2CAP Ext-Flowctl Client - Open two sockets - teardown
Index Removed callback
Index: 0x0000
L2CAP Ext-Flowctl Client - Open two sockets - teardown complete L2CAP Ext-Flowctl Client - Open two sockets - done
L2CAP Ext-Flowctl Client - Open two sockets close one - init
Read Index List callback
Status: 0x00
New hciemu instance created
Index Added callback
Index: 0x0000
Read Info callback
Status: 0x00
Address: 00:AA:01:00:00:00
Version: 0x09
Manufacturer: 0x003f
Supported settings: 0x0001be1b
Current settings: 0x00000200
Class: 0x000000
Name:
Short name:L2CAP Ext-Flowctl Client - Open two sockets close one - setup
Powering on controller
Controller powered on
L2CAP Ext-Flowctl Client - Open two sockets close one - setup complete L2CAP Ext-Flowctl Client - Open two sockets close one - run
Connect in progress, sk = 19 (deferred)
HCI Command 0x200b length 7
HCI Command 0x200c length 2
Connect in progress, sk = 20
Closing first socket! -1
Client set connectable status 0x00
HCI Command 0x200c length 2
HCI Command 0x200d length 25
HCI Command 0x2016 length 2
Successfully connected
L2CAP Ext-Flowctl Client - Open two sockets close one - test passed L2CAP Ext-Flowctl Client - Open two sockets close one - teardown
Index Removed callback
Index: 0x0000
L2CAP Ext-Flowctl Client - Open two sockets close one - teardown complete L2CAP Ext-Flowctl Client - Open two sockets close one - done
Test Summary
------------
L2CAP Ext-Flowctl Client - Success Passed 0.068 seconds
L2CAP Ext-Flowctl Client, Direct Advertising - Success Passed 0.023 seconds
L2CAP Ext-Flowctl Client SMP - Success Passed 0.027 seconds L2CAP Ext-Flowctl Client - Command Reject Passed 0.046 seconds L2CAP Ext-Flowctl Client - Open two sockets Passed 0.014 seconds
L2CAP Ext-Flowctl Client - Open two sockets close one Passed 0.066 seconds
Total: 6, Passed: 6 (100.0%), Failed: 0, Not Run: 0 Overall execution time: 0.247 seconds
Luiz Augusto von Dentz (3):
Bluetooth: L2CAP: Add get_peer_pid callback
Bluetooth: L2CAP: Use DEFER_SETUP to group ECRED connections
Bluetooth: Add BT_MODE socket option
include/net/bluetooth/bluetooth.h | 11 +++ include/net/bluetooth/l2cap.h | 5 ++ net/bluetooth/l2cap_core.c | 136 +++++++++++++++++++++++++++--- net/bluetooth/l2cap_sock.c | 104 +++++++++++++++++++++++ 4 files changed, 246 insertions(+), 10 deletions(-)
Signature · 1 line
2.21.1
Luiz Augusto von Dentz
maintainerPATCH v5 1/3 Bluetooth: L2CAP: Add get_peer_pid callback
From: Luiz Augusto von Dentz <[email protected]>
This adds a callback to read the socket pid.
--- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/l2cap_sock.c | 8 ++++++++ 2 files changed, 9 insertions(+)
include/net/bluetooth/l2cap.h +1 -0
@@ -660,6 +660,7 @@ struct l2cap_ops {void (*suspend) (struct l2cap_chan *chan);void (*set_shutdown) (struct l2cap_chan *chan);long (*get_sndtimeo) (struct l2cap_chan *chan); +struct pid *(*get_peer_pid) (struct l2cap_chan *chan);struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,unsigned long hdr_len,unsigned long len,int nb);
net/bluetooth/l2cap_sock.c +8 -0
@@ -1504,6 +1504,13 @@ static long l2cap_sock_get_sndtimeo_cb(struct l2cap_chan *chan)return sk->sk_sndtimeo; } +static struct pid *l2cap_sock_get_peer_pid_cb (struct l2cap_chan *chan) +{ +struct sock *sk = chan->data; + +return sk->sk_peer_pid; +} +static void l2cap_sock_suspend_cb (struct l2cap_chan *chan) {struct sock *sk = chan->data;
@@ -1525,6 +1532,7 @@ static const struct l2cap_ops l2cap_chan_ops = { .suspend = l2cap_sock_suspend_cb, .set_shutdown = l2cap_sock_set_shutdown_cb, .get_sndtimeo = l2cap_sock_get_sndtimeo_cb, + .get_peer_pid = l2cap_sock_get_peer_pid_cb, .alloc_skb = l2cap_sock_alloc_skb_cb, };
Signature · 1 line
2.21.1
Marcel Holtmann
maintainerRe: [PATCH v5 1/3] Bluetooth: L2CAP: Add get_peer_pid callback
Hi Luiz,
Quoted 7 lines
This adds a callback to read the socket pid.
Signed-off-by Luiz Augusto von Dentz <[email protected]>---
include/net/bluetooth/l2cap.h| 1 +net/bluetooth/l2cap_sock.c| 8 ++++++++2 files changed, 9 insertions(+)
patch has been applied to bluetooth-next tree.
Regards
Marcel
Luiz Augusto von Dentz
maintainerPATCH v5 2/3 Bluetooth: L2CAP: Use DEFER_SETUP to group ECRED connections
In reply to Luiz Augusto von DentzFrom: Luiz Augusto von Dentz <[email protected]>
This uses the DEFER_SETUP flag to group channels with L2CAP_CREDIT_BASED_CONNECTION_REQ.
--- include/net/bluetooth/l2cap.h | 4 + net/bluetooth/l2cap_core.c | 136 +++++++++++++++++++++++++++++++--- 2 files changed, 130 insertions(+), 10 deletions(-)
include/net/bluetooth/l2cap.h +4 -0
@@ -47,6 +47,7 @@#define L2CAP_DEFAULT_ACC_LAT 0xFFFFFFFF#define L2CAP_BREDR_MAX_PAYLOAD 1019/* 3-DH5 packet */ #define L2CAP_LE_MIN_MTU 23 +#define L2CAP_ECRED_CONN_SCID_MAX 5#define L2CAP_DISC_TIMEOUT msecs_to_jiffies(100)#define L2CAP_DISC_REJ_TIMEOUT msecs_to_jiffies(5000)
@@ -984,6 +985,9 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan);int l2cap_ertm_init (struct l2cap_chan *chan);void l2cap_chan_add (struct l2cap_conn *conn,struct l2cap_chan *chan);void __l2cap_chan_add (struct l2cap_conn *conn,struct l2cap_chan *chan); +typedef void (*l2cap_chan_func_t )(struct l2cap_chan *chan,void *data); +void l2cap_chan_list (struct l2cap_conn *conn,l2cap_chan_func_t func, +void *data);void l2cap_chan_del (struct l2cap_chan *chan,int err);void l2cap_send_conn_req (struct l2cap_chan *chan);void l2cap_move_start (struct l2cap_chan *chan);
net/bluetooth/l2cap_core.c +126 -10
173 lines not on this page · raw message
Signature · 1 line
2.21.1
Marcel Holtmann
maintainerRe: [PATCH v5 2/3] Bluetooth: L2CAP: Use DEFER_SETUP to group ECRED connections
Hi Luiz,
Quoted 191 lines
This uses the
DEFER_SETUPflag to group channels withL2CAP_CREDIT_BASED_CONNECTION_REQ.Signed-off-by Luiz Augusto von Dentz <[email protected]>---
include/net/bluetooth/l2cap.h| 4 +net/bluetooth/l2cap_core.c| 136 +++++++++++++++++++++++++++++++---2 files changed, 130 insertions(+), 10 deletions(-)include/net/bluetooth/l2cap.h +4
-0@@ -47,6 +47,7 @@#define L2CAP_DEFAULT_ACC_LAT 0xFFFFFFFF#define L2CAP_BREDR_MAX_PAYLOAD 1019/* 3-DH5 packet */ #define L2CAP_LE_MIN_MTU 23 +#define L2CAP_ECRED_CONN_SCID_MAX 5#define L2CAP_DISC_TIMEOUT msecs_to_jiffies(100)#define L2CAP_DISC_REJ_TIMEOUT msecs_to_jiffies(5000)@@ -984,6 +985,9 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan);int l2cap_ertm_init (struct l2cap_chan *chan);void l2cap_chan_add (struct l2cap_conn *conn,struct l2cap_chan *chan);void __l2cap_chan_add (struct l2cap_conn *conn,struct l2cap_chan *chan); +typedef void (*l2cap_chan_func_t )(struct l2cap_chan *chan,void *data); +void l2cap_chan_list (struct l2cap_conn *conn,l2cap_chan_func_t func, +void *data);void l2cap_chan_del (struct l2cap_chan *chan,int err);void l2cap_send_conn_req (struct l2cap_chan *chan);void l2cap_move_start (struct l2cap_chan *chan);net/bluetooth/l2cap_core.c +110
-10@@ -678,6 +678,29 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) }EXPORT_SYMBOL_GPL (l2cap_chan_del); +static void __l2cap_chan_list (struct l2cap_conn *conn,l2cap_chan_func_t func, +void *data) +{ +struct l2cap_chan *chan; + +list_for_each_entry (chan, &conn->chan_l, list) { +func (chan, data); + } +} + +void l2cap_chan_list (struct l2cap_conn *conn,l2cap_chan_func_t func, +void *data) +{ +if (!conn) +return ; + +mutex_lock (&conn->chan_lock); +__l2cap_chan_list (conn, func, data); +mutex_unlock (&conn->chan_lock); +} + +EXPORT_SYMBOL_GPL (l2cap_chan_list); +static void l2cap_conn_update_id_addr (struct work_struct *work) { struct l2cap_conn *conn = container_of(work, struct l2cap_conn,@@ -1356,29 +1379,79 @@ static void l2cap_le_connect(struct l2cap_chan *chan) sizeof(req), &req); } -static void l2cap_ecred_connect (struct l2cap_chan *chan) -{ -struct l2cap_conn *conn = chan->conn; +struct l2cap_ecred_conn_data {struct {struct l2cap_ecred_conn_req req; -__le16 scid; +__le16 scid[5 ]; } __packed pdu; +struct l2cap_chan *chan; +struct pid *pid; +int count; +}; + +static void l2cap_ecred_defer_connect (struct l2cap_chan *chan,void *data) +{ +struct l2cap_ecred_conn_data *conn = data; +struct pid *pid; + +if (chan == conn->chan) +return ; + +if (!test_and_clear_bit (FLAG_DEFER_SETUP , &chan->flags)) +return ; + + pid = chan->ops->get_peer_pid (chan); + +/* Only add deferred channels with the same PID/PSM */ +if (conn->pid != pid || chan->psm != conn->chan->psm || chan->ident || + chan->mode !=L2CAP_MODE_EXT_FLOWCTL || chan->state !=BT_CONNECT ) +return ; + +if (test_and_set_bit (FLAG_ECRED_CONN_REQ_SENT , &chan->flags)) +return ; + +l2cap_ecred_init (chan,0 ); + +/* Set the same ident so we can match on the rsp */ + chan->ident = conn->chan->ident; + +/* Include all channels deferred */ + conn->pdu.scid[conn->count] =cpu_to_le16 (chan->scid); + + conn->count++; +} + +static void l2cap_ecred_connect (struct l2cap_chan *chan) +{ +struct l2cap_conn *conn = chan->conn; +struct l2cap_ecred_conn_data data; + +if (test_bit (FLAG_DEFER_SETUP , &chan->flags)) +return ;if (test_and_set_bit (FLAG_ECRED_CONN_REQ_SENT , &chan->flags))return ;l2cap_ecred_init (chan,0 ); - pdu.req.psm = chan->psm; - pdu.req.mtu =cpu_to_le16 (chan->imtu); - pdu.req.mps =cpu_to_le16 (chan->mps); - pdu.req.credits =cpu_to_le16 (chan->rx_credits); - pdu.scid =cpu_to_le16 (chan->scid); + data.pdu.req.psm = chan->psm; + data.pdu.req.mtu =cpu_to_le16 (chan->imtu); + data.pdu.req.mps =cpu_to_le16 (chan->mps); + data.pdu.req.credits =cpu_to_le16 (chan->rx_credits); + data.pdu.scid[0 ] =cpu_to_le16 (chan->scid); chan->ident =l2cap_get_ident (conn); + data.pid = chan->ops->get_peer_pid (chan); + + data.count =1 ; + data.chan = chan; + data.pid = chan->ops->get_peer_pid (chan); + +__l2cap_chan_list (conn, l2cap_ecred_defer_connect, &data);l2cap_send_cmd (conn, chan->ident,L2CAP_ECRED_CONN_REQ , -sizeof (pdu), &pdu); +sizeof (data.pdu.req) + data.count *sizeof (__le16), + &data.pdu); }static void l2cap_le_start (struct l2cap_chan *chan)@@ -7694,6 +7767,33 @@ static bool is_valid_psm(u16 psm, u8 dst_type) {return ((psm &0x0101 ) ==0x0001 ); } +struct l2cap_chan_data { +struct l2cap_chan *chan; +struct pid *pid; +int count; +}; + +static void l2cap_chan_by_pid (struct l2cap_chan *chan,void *data) +{ +struct l2cap_chan_data *d = data; +struct pid *pid; + +if (chan == d->chan) +return ; + +if (!test_bit (FLAG_DEFER_SETUP , &chan->flags)) +return ; + + pid = chan->ops->get_peer_pid (chan); + +/* Only count deferred channels with the same PID/PSM */ +if (d->pid != pid || chan->psm != d->chan->psm || chan->ident || + chan->mode !=L2CAP_MODE_EXT_FLOWCTL || chan->state !=BT_CONNECT ) +return ; + + d->count++; +} +int l2cap_chan_connect (struct l2cap_chan *chan,__le16 psm,u16 cid,bdaddr_t *dst,u8 dst_type) {@@ -7813,6 +7913,22 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, goto done;
net/bluetooth/l2cap_core.c int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, · line 7923
Quoted 10 lines
net/bluetooth/l2cap_core.c +8
-0} +if (chan->mode ==L2CAP_MODE_EXT_FLOWCTL ) { +struct l2cap_chan_data data; + + data.chan = chan; + data.pid = chan->ops->get_peer_pid (chan); + data.count =0 ; + +l2cap_chan_list (conn, l2cap_chan_by_pid, &data);
Put an empty line after this. It gives emphasis to the comment.
net/bluetooth/l2cap_core.c int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, · line 7925
Quoted 2 lines
net/bluetooth/l2cap_core.c +2
-0+/* Check if there isn't too many channels being connected */ +if (!(data.count <L2CAP_ECRED_CONN_SCID_MAX -1 )) {
If (data.count > L2CAP_ECRED_CONN_SCID_MIX) ???
net/bluetooth/l2cap_core.c int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, · line 7933
Quoted 8 lines
net/bluetooth/l2cap_core.c +6
-0+hci_conn_drop (hcon); + err = -EPROTO ; + goto done; + } + } +mutex_lock (&conn->chan_lock);l2cap_chan_lock (chan);
Regards
Marcel
Luiz Augusto von Dentz
maintainerRe: [PATCH v5 2/3] Bluetooth: L2CAP: Use DEFER_SETUP to group ECRED connections
Hi Marcel,
Quoted 207 lines · Marcel Holtmann
Hi Luiz,
Quoted 191 lines
This uses the
DEFER_SETUPflag to group channels withL2CAP_CREDIT_BASED_CONNECTION_REQ.Signed-off-by Luiz Augusto von Dentz <[email protected]>---
include/net/bluetooth/l2cap.h| 4 +net/bluetooth/l2cap_core.c| 136 +++++++++++++++++++++++++++++++---2 files changed, 130 insertions(+), 10 deletions(-)include/net/bluetooth/l2cap.h +4
-0@@ -47,6 +47,7 @@#define L2CAP_DEFAULT_ACC_LAT 0xFFFFFFFF#define L2CAP_BREDR_MAX_PAYLOAD 1019/* 3-DH5 packet */ #define L2CAP_LE_MIN_MTU 23 +#define L2CAP_ECRED_CONN_SCID_MAX 5#define L2CAP_DISC_TIMEOUT msecs_to_jiffies(100)#define L2CAP_DISC_REJ_TIMEOUT msecs_to_jiffies(5000)@@ -984,6 +985,9 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan);int l2cap_ertm_init (struct l2cap_chan *chan);void l2cap_chan_add (struct l2cap_conn *conn,struct l2cap_chan *chan);void __l2cap_chan_add (struct l2cap_conn *conn,struct l2cap_chan *chan); +typedef void (*l2cap_chan_func_t )(struct l2cap_chan *chan,void *data); +void l2cap_chan_list (struct l2cap_conn *conn,l2cap_chan_func_t func, +void *data);void l2cap_chan_del (struct l2cap_chan *chan,int err);void l2cap_send_conn_req (struct l2cap_chan *chan);void l2cap_move_start (struct l2cap_chan *chan);net/bluetooth/l2cap_core.c +110
-10@@ -678,6 +678,29 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) }EXPORT_SYMBOL_GPL (l2cap_chan_del); +static void __l2cap_chan_list (struct l2cap_conn *conn,l2cap_chan_func_t func, +void *data) +{ +struct l2cap_chan *chan; + +list_for_each_entry (chan, &conn->chan_l, list) { +func (chan, data); + } +} + +void l2cap_chan_list (struct l2cap_conn *conn,l2cap_chan_func_t func, +void *data) +{ +if (!conn) +return ; + +mutex_lock (&conn->chan_lock); +__l2cap_chan_list (conn, func, data); +mutex_unlock (&conn->chan_lock); +} + +EXPORT_SYMBOL_GPL (l2cap_chan_list); +static void l2cap_conn_update_id_addr (struct work_struct *work) { struct l2cap_conn *conn = container_of(work, struct l2cap_conn,@@ -1356,29 +1379,79 @@ static void l2cap_le_connect(struct l2cap_chan *chan) sizeof(req), &req); } -static void l2cap_ecred_connect (struct l2cap_chan *chan) -{ -struct l2cap_conn *conn = chan->conn; +struct l2cap_ecred_conn_data {struct {struct l2cap_ecred_conn_req req; -__le16 scid; +__le16 scid[5 ]; } __packed pdu; +struct l2cap_chan *chan; +struct pid *pid; +int count; +}; + +static void l2cap_ecred_defer_connect (struct l2cap_chan *chan,void *data) +{ +struct l2cap_ecred_conn_data *conn = data; +struct pid *pid; + +if (chan == conn->chan) +return ; + +if (!test_and_clear_bit (FLAG_DEFER_SETUP , &chan->flags)) +return ; + + pid = chan->ops->get_peer_pid (chan); + +/* Only add deferred channels with the same PID/PSM */ +if (conn->pid != pid || chan->psm != conn->chan->psm || chan->ident || + chan->mode !=L2CAP_MODE_EXT_FLOWCTL || chan->state !=BT_CONNECT ) +return ; + +if (test_and_set_bit (FLAG_ECRED_CONN_REQ_SENT , &chan->flags)) +return ; + +l2cap_ecred_init (chan,0 ); + +/* Set the same ident so we can match on the rsp */ + chan->ident = conn->chan->ident; + +/* Include all channels deferred */ + conn->pdu.scid[conn->count] =cpu_to_le16 (chan->scid); + + conn->count++; +} + +static void l2cap_ecred_connect (struct l2cap_chan *chan) +{ +struct l2cap_conn *conn = chan->conn; +struct l2cap_ecred_conn_data data; + +if (test_bit (FLAG_DEFER_SETUP , &chan->flags)) +return ;if (test_and_set_bit (FLAG_ECRED_CONN_REQ_SENT , &chan->flags))return ;l2cap_ecred_init (chan,0 ); - pdu.req.psm = chan->psm; - pdu.req.mtu =cpu_to_le16 (chan->imtu); - pdu.req.mps =cpu_to_le16 (chan->mps); - pdu.req.credits =cpu_to_le16 (chan->rx_credits); - pdu.scid =cpu_to_le16 (chan->scid); + data.pdu.req.psm = chan->psm; + data.pdu.req.mtu =cpu_to_le16 (chan->imtu); + data.pdu.req.mps =cpu_to_le16 (chan->mps); + data.pdu.req.credits =cpu_to_le16 (chan->rx_credits); + data.pdu.scid[0 ] =cpu_to_le16 (chan->scid); chan->ident =l2cap_get_ident (conn); + data.pid = chan->ops->get_peer_pid (chan); + + data.count =1 ; + data.chan = chan; + data.pid = chan->ops->get_peer_pid (chan); + +__l2cap_chan_list (conn, l2cap_ecred_defer_connect, &data);l2cap_send_cmd (conn, chan->ident,L2CAP_ECRED_CONN_REQ , -sizeof (pdu), &pdu); +sizeof (data.pdu.req) + data.count *sizeof (__le16), + &data.pdu); }static void l2cap_le_start (struct l2cap_chan *chan)@@ -7694,6 +7767,33 @@ static bool is_valid_psm(u16 psm, u8 dst_type) {return ((psm &0x0101 ) ==0x0001 ); } +struct l2cap_chan_data { +struct l2cap_chan *chan; +struct pid *pid; +int count; +}; + +static void l2cap_chan_by_pid (struct l2cap_chan *chan,void *data) +{ +struct l2cap_chan_data *d = data; +struct pid *pid; + +if (chan == d->chan) +return ; + +if (!test_bit (FLAG_DEFER_SETUP , &chan->flags)) +return ; + + pid = chan->ops->get_peer_pid (chan); + +/* Only count deferred channels with the same PID/PSM */ +if (d->pid != pid || chan->psm != d->chan->psm || chan->ident || + chan->mode !=L2CAP_MODE_EXT_FLOWCTL || chan->state !=BT_CONNECT ) +return ; + + d->count++; +} +int l2cap_chan_connect (struct l2cap_chan *chan,__le16 psm,u16 cid,bdaddr_t *dst,u8 dst_type) {@@ -7813,6 +7913,22 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, goto done;net/bluetooth/l2cap_core.c int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, · line 7923
Quoted 10 lines
net/bluetooth/l2cap_core.c +8
-0} +if (chan->mode ==L2CAP_MODE_EXT_FLOWCTL ) { +struct l2cap_chan_data data; + + data.chan = chan; + data.pid = chan->ops->get_peer_pid (chan); + data.count =0 ; + +l2cap_chan_list (conn, l2cap_chan_by_pid, &data);Put an empty line after this. It gives emphasis to the comment.
Quoted 4 lines
net/bluetooth/l2cap_core.c int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, · line 7925
Quoted 2 lines
net/bluetooth/l2cap_core.c +2
-0+/* Check if there isn't too many channels being connected */ +if (!(data.count <L2CAP_ECRED_CONN_SCID_MAX -1 )) {If (data.count >
L2CAP_ECRED_CONN_SCID_MIX) ???
We need to take into account the chan itself is not part of the list yet, so that means data.count + 1 or we initialize the it as 1 a couple lines before, I will change the logic to use > operation.
Quoted 13 lines
net/bluetooth/l2cap_core.c int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, · line 7933
Quoted 8 lines
net/bluetooth/l2cap_core.c +6
-0+hci_conn_drop (hcon); + err = -EPROTO ; + goto done; + } + } +mutex_lock (&conn->chan_lock);l2cap_chan_lock (chan);Regards
Marcel
Signature · 1 line
Luiz Augusto von Dentz
Luiz Augusto von Dentz
maintainerPATCH v5 3/3 Bluetooth: Add BT_MODE socket option
In reply to Luiz Augusto von DentzFrom: Luiz Augusto von Dentz <[email protected]>
This adds BT_MODE socket option which can be used to set L2CAP modes, including modes only supported over LE which were not supported using the L2CAP_OPTIONS.
--- include/net/bluetooth/bluetooth.h | 8 ++ include/net/bluetooth/l2cap.h | 6 ++ net/bluetooth/l2cap_sock.c | 124 ++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+)
include/net/bluetooth/bluetooth.h +8 -0
@@ -139,6 +139,14 @@ struct bt_voice {#define BT_PHY_LE_CODED_TX 0x00002000#define BT_PHY_LE_CODED_RX 0x00004000 +#define BT_MODE 15 + +#define BT_MODE_BASIC 0x00 +#define BT_MODE_ERTM 0x01 +#define BT_MODE_STREAMING 0x02 +#define BT_MODE_LE_FLOWCTL 0x03 +#define BT_MODE_EXT_FLOWCTL 0x04 + __printf(1, 2)void bt_info (const char *fmt, ...);__printf (1 ,2 )
include/net/bluetooth/l2cap.h +6 -0
@@ -720,9 +720,15 @@ struct l2cap_user {/* ----- L2CAP socket info ----- */ #define l2cap_pi (sk) ((struct l2cap_pinfo *) sk) +#define L2CAP_PI_OPTION_UNSET 0x00 +#define L2CAP_PI_OPTION_LEGACY 0x01 +#define L2CAP_PI_OPTION_BT_MODE 0x02 +struct l2cap_pinfo {struct bt_sock bt;struct l2cap_chan *chan; +u8 option; +u8 bt_mode;struct sk_buff *rx_busy_skb; };
net/bluetooth/l2cap_sock.c +124 -0
160 lines not on this page · raw message
Signature · 1 line
2.21.1
Marcel Holtmann
maintainerRe: [PATCH v5 3/3] Bluetooth: Add BT_MODE socket option
Hi Luiz,
Quoted 39 lines
This adds
BT_MODEsocket option which can be used to set L2CAP modes, including modes only supported over LE which were not supported using theL2CAP_OPTIONS.Signed-off-by Luiz Augusto von Dentz <[email protected]>---
include/net/bluetooth/bluetooth.h | 8 ++ include/net/bluetooth/l2cap.h | 6 ++ net/bluetooth/l2cap_sock.c | 124 ++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+)include/net/bluetooth/bluetooth.h +8
-0@@ -139,6 +139,14 @@ struct bt_voice {#define BT_PHY_LE_CODED_TX 0x00002000#define BT_PHY_LE_CODED_RX 0x00004000 +#define BT_MODE 15 + +#define BT_MODE_BASIC 0x00 +#define BT_MODE_ERTM 0x01 +#define BT_MODE_STREAMING 0x02 +#define BT_MODE_LE_FLOWCTL 0x03 +#define BT_MODE_EXT_FLOWCTL 0x04 + __printf(1, 2)void bt_info (const char *fmt, ...);__printf (1 ,2 )include/net/bluetooth/l2cap.h +1
-0@@ -720,9 +720,15 @@ struct l2cap_user {/* ----- L2CAP socket info ----- */ #define l2cap_pi (sk) ((struct l2cap_pinfo *) sk) +#define L2CAP_PI_OPTION_UNSET 0x00
include/net/bluetooth/l2cap.h struct l2cap_user { · line 733
Quoted 10 lines
include/net/bluetooth/l2cap.h +5
-0+#define L2CAP_PI_OPTION_LEGACY 0x01 +#define L2CAP_PI_OPTION_BT_MODE 0x02 +struct l2cap_pinfo {struct bt_sock bt;struct l2cap_chan *chan; +u8 option; +u8 bt_mode;struct sk_buff *rx_busy_skb; };
why do you want to store bt_mode here. Whatever we have in l2cap_chan should be plenty.
I also looked at l2cap_sock_setsockopt_old and if you use L2CAP_OPTIONS and want to read BT_MODE, then everything should be fine. Same as setting BT_MODE (except EXT_FLOWCTL) and then reading L2CAP_OPTIONS is fine as well. We can all translate this properly and with have EINVAL return errors for not supported / disabled modes.
So the only time L2CAP_OPTIONS read should fail is if you use BT_MODE with EXT_FLOWCTL as mode. So you can just check the mode set in l2cap_chan. And we start using our new mode definition there and then convert it for L2CAP_OPTIONS.
Regards
Marcel
Luiz Augusto von Dentz
maintainerRe: [PATCH v5 3/3] Bluetooth: Add BT_MODE socket option
Hi Marcel,
Quoted 41 lines · Marcel Holtmann
Hi Luiz,
Quoted 38 lines
This adds
BT_MODEsocket option which can be used to set L2CAP modes, including modes only supported over LE which were not supported using theL2CAP_OPTIONS.Signed-off-by Luiz Augusto von Dentz <[email protected]>---
include/net/bluetooth/bluetooth.h | 8 ++ include/net/bluetooth/l2cap.h | 6 ++ net/bluetooth/l2cap_sock.c | 124 ++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+)include/net/bluetooth/bluetooth.h +8
-0@@ -139,6 +139,14 @@ struct bt_voice {#define BT_PHY_LE_CODED_TX 0x00002000#define BT_PHY_LE_CODED_RX 0x00004000 +#define BT_MODE 15 + +#define BT_MODE_BASIC 0x00 +#define BT_MODE_ERTM 0x01 +#define BT_MODE_STREAMING 0x02 +#define BT_MODE_LE_FLOWCTL 0x03 +#define BT_MODE_EXT_FLOWCTL 0x04 + __printf(1, 2)void bt_info (const char *fmt, ...);__printf (1 ,2 )include/net/bluetooth/l2cap.h +0
-0@@ -720,9 +720,15 @@ struct l2cap_user {/* ----- L2CAP socket info ----- */ #define l2cap_pi (sk) ((struct l2cap_pinfo *) sk)
Quoted 13 lines
include/net/bluetooth/l2cap.h struct l2cap_user { · line 733
Quoted 11 lines
include/net/bluetooth/l2cap.h +6
-0+#define L2CAP_PI_OPTION_UNSET 0x00 +#define L2CAP_PI_OPTION_LEGACY 0x01 +#define L2CAP_PI_OPTION_BT_MODE 0x02 +struct l2cap_pinfo {struct bt_sock bt;struct l2cap_chan *chan; +u8 option; +u8 bt_mode;struct sk_buff *rx_busy_skb; };why do you want to store
bt_modehere. Whatever we have inl2cap_chanshould be plenty.
Ive thought it would be cleaner to mess with types that comes from the spec itself so l2cap_chan would continue to use them.
Quoted 3 lines
I also looked at
l2cap_sock_setsockopt_oldand if you useL2CAP_OPTIONSand want to readBT_MODE, then everything should be fine. Same as settingBT_MODE(exceptEXT_FLOWCTL) and then readingL2CAP_OPTIONSis fine as well. We can all translate this properly and with have EINVAL return errors for not supported / disabled modes.So the only time
L2CAP_OPTIONSread should fail is if you useBT_MODEwithEXT_FLOWCTLas mode. So you can just check the mode set inl2cap_chan. And we start using our new mode definition there and then convert it forL2CAP_OPTIONS.
Sure, I thought it would be more efficient to not have conversions back and forth but Im fine either way.
Quoted 4 lines
Regards
Marcel
Signature · 1 line
Luiz Augusto von Dentz
Marcel Holtmann
maintainerRe: [PATCH v5 3/3] Bluetooth: Add BT_MODE socket option
Hi Luiz,
Quoted 52 lines
Quoted 38 lines
Quoted 38 lines
This adds
BT_MODEsocket option which can be used to set L2CAP modes, including modes only supported over LE which were not supported using theL2CAP_OPTIONS.Signed-off-by Luiz Augusto von Dentz <[email protected]>---
include/net/bluetooth/bluetooth.h | 8 ++ include/net/bluetooth/l2cap.h | 6 ++ net/bluetooth/l2cap_sock.c | 124 ++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+)include/net/bluetooth/bluetooth.h +8
-0@@ -139,6 +139,14 @@ struct bt_voice {#define BT_PHY_LE_CODED_TX 0x00002000#define BT_PHY_LE_CODED_RX 0x00004000 +#define BT_MODE 15 + +#define BT_MODE_BASIC 0x00 +#define BT_MODE_ERTM 0x01 +#define BT_MODE_STREAMING 0x02 +#define BT_MODE_LE_FLOWCTL 0x03 +#define BT_MODE_EXT_FLOWCTL 0x04 + __printf(1, 2)void bt_info (const char *fmt, ...);__printf (1 ,2 )include/net/bluetooth/l2cap.h +0
-0@@ -720,9 +720,15 @@ struct l2cap_user {/* ----- L2CAP socket info ----- */ #define l2cap_pi (sk) ((struct l2cap_pinfo *) sk)Quoted 13 lines
include/net/bluetooth/l2cap.h struct l2cap_user { · line 733
Quoted 11 lines
include/net/bluetooth/l2cap.h +6
-0+#define L2CAP_PI_OPTION_UNSET 0x00 +#define L2CAP_PI_OPTION_LEGACY 0x01 +#define L2CAP_PI_OPTION_BT_MODE 0x02 +struct l2cap_pinfo {struct bt_sock bt;struct l2cap_chan *chan; +u8 option; +u8 bt_mode;struct sk_buff *rx_busy_skb; };why do you want to store
bt_modehere. Whatever we have inl2cap_chanshould be plenty.
Quoted 2 lines
Ive thought it would be cleaner to mess with types that comes from the spec itself so
l2cap_chanwould continue to use them.
Actually the LE_FLOWCTL and EXT_FLOWCTL are not spec values either. Frankly I don’t care which ones we store right now. I am fine keeping the spec one for now and just translate it to BT_MODE.
Quoted 6 lines
Quoted 3 lines
I also looked at
l2cap_sock_setsockopt_oldand if you useL2CAP_OPTIONSand want to readBT_MODE, then everything should be fine. Same as settingBT_MODE(exceptEXT_FLOWCTL) and then readingL2CAP_OPTIONSis fine as well. We can all translate this properly and with have EINVAL return errors for not supported / disabled modes.So the only time
L2CAP_OPTIONSread should fail is if you useBT_MODEwithEXT_FLOWCTLas mode. So you can just check the mode set inl2cap_chan. And we start using our new mode definition there and then convert it forL2CAP_OPTIONS.Sure, I thought it would be more efficient to not have conversions back and forth but Im fine either way.
In the end it makes the code simpler to just do the conversion. And once we add a kernel option to disable setsockopt_old, we have less code.
Regards
Marcel