* RE: [PATCH v6] staging: Add ST-Ericsson CG2900 driver
From: Par-Gunnar HJALMDAHL @ 2011-05-12 11:54 UTC (permalink / raw)
To: Greg KH
Cc: Greg Kroah-Hartman, devel@driverdev.osuosl.org, Linus Walleij,
linux-kernel@vger.kernel.org, linux-bluetooth@vger.kernel.org,
Pavan Savoy, Vitaly Wool, Alan Cox, Arnd Bergmann,
Marcel Holtmann, Lukasz Rymanowski, Linus WALLEIJ,
Par-Gunnar Hjalmdahl, Lee Jones, Mathieu Poirier
In-Reply-To: <20110511134859.GB12717@kroah.com>
PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBHcmVnIEtIIFttYWlsdG86Z3Jl
Z0Brcm9haC5jb21dDQo+IFNlbnQ6IGRlbiAxMSBtYWogMjAxMSAxNTo0OQ0KPg0KPiA+IEkgdXNl
ZCBuZXh0LTIwMTEwNTEwIGFuZCBpbiB0aGF0IHRhZyB0aGUgZmlsZQ0KPiBpbmNsdWRlL0xpbnV4
L21mZC9jb3JlLmgNCj4gPiBUaGUgc3RydWN0IG1mZF9jZWxsIGhhcyBhIHBhcmFtZXRlciBjYWxs
ZWQgcGxhdGZvcm1fZGF0YSwgd2hpbGUgaW4NCj4geW91cg0KPiA+IGJ1aWxkIGl0IHNlZW1zIGl0
IGRvZXNuJ3QuDQo+ID4gVGhpcyB3YXMgY2hhbmdlZCB2ZXJ5IHJlY2VudGx5IGluIHRoZSBjb3Jl
LmggZmlsZSAob24gQXByaWwgNikuDQo+ID4gU28gZm9yIGNvcmUuaCB0aGUgbGFzdCBjb21taXQg
SUQgSSBoYXZlIGluIHRoZSB0YWcgSSBidWlsdCB1cG9uIGlzDQo+ID4gNTU4YWE5YzBkNjIwYjkx
YTg5NmQ1ZTM5Y2U4YTU3MGJlZDY1NTg5Yi4NCj4gDQo+IFNvIGRvIEkgbmVlZCB0aGF0IHBhdGNo
IG9uIHRoZSBzdGFnaW5nLW5leHQgdHJlZSBhbHNvPw0KPiANCj4gT3IgaXMgaXQgYW4gaXNzdWUg
b2YgYnVpbGRpbmcgdGhpcyBvbiB4ODYtNjQuLi4NCj4gDQo+IHRoYW5rcywNCj4gDQo+IGdyZWcg
ay1oDQoNCkhpIEdyZWcsDQoNCkkgZG93bmxvYWRlZCB5b3Ugc3RhZ2luZyB0cmVlIGFuZCBjb21w
YXJlZCB0aGUgbG9ncyBmb3IgdGhlIGNvcmUuaCBmaWxlLg0KQ29tcGFyZWQgdG8gbGludXgtbmV4
dCB0YWcgbmV4dC0yMDExMDUxMCBpdCBpcyBtaXNzaW5nIDIgY29tbWl0czoNCjRkYmVlNmI3NmZm
ZmQ1NzQwZTg3ZTI4NmY0ZjRjMWMxNTkwMWJjYWUNCjU1OGFhOWMwZDYyMGI5MWE4OTZkNWUzOWNl
OGE1NzBiZWQ2NTU4OWINCndoZXJlIHRoZSBmaXJzdCBvbmUgaXMgdGhlICJvbGRlc3QiIG9uZSBp
biB0aGUgbG9nIGFuZCBpcyB0aGUgbW9zdA0KaW1wb3J0YW50IG9uZSBmb3IgbXkgcGF0Y2guDQpB
bm90aGVyIG9wdGlvbiB3b3VsZCBiZSBmb3IgbWUgdG8gZml4IHRoZSBwYXRjaCBmb3IgeW91ciB0
cmVlLCBidXQNCnRoZW4gSSB3b3VsZCBwcm9iYWJseSBoYXZlIHRvIGZpeCBpdCBiYWNrIGluIGEg
ZmV3IGRheXMgd2hlbiB5b3UgdXBkYXRlDQp5b3VyIHN0YWdpbmcgdHJlZSB0byBMaW51eC1uZXh0
LiBIb3cgb2Z0ZW4gaXMgeW91ciB0cmVlIHVwZGF0ZWQ/DQoNClRoZSBlYXNpZXN0IGlzIHByb2Jh
Ymx5IHRvIHdhaXQgYSBmZXcgZGF5cyB1bnRpbCB5b3UgaGF2ZSB0aGUgbmV4dC0yMDExMDUxMA0K
dGFnIGluIHlvdXIgdHJlZSBhbmQgdGhlbiBhcHBseSB0aGUgcGF0Y2guDQoNClRoYW5rcywNClAt
Rw0KDQo=
^ permalink raw reply
* Re: HCI data payload not getting through when using BlueZ
From: Eponymous - @ 2011-05-12 10:19 UTC (permalink / raw)
To: Eponymous -, linux-bluetooth
In-Reply-To: <20110511164736.GA22065@joana>
Hi,
I've just downloaded the 4.91 sources and done a make and the only
program I can see starting "l2" is "l2ping". There is no l2test.
On Wed, May 11, 2011 at 5:47 PM, Gustavo F. Padovan
<padovan@profusion.mobi> wrote:
> * Eponymous - <the.epon@gmail.com> [2011-05-11 09:52:28 +0100]:
>
>> Hi,
>>
>> I've ran into an issue where data doesn't seem to be received by a slave device.
>>
>> I do the following:
>>
>> Using Gentoo Linux (2.6.34-gentoo-r1)
>> Using BlueZ 4.81
>>
>> 1. Use BlueZ to connect to two Bluetooth devices using HCI only. This
>> is over USB.
>>
>> 2. I set one device as a slave and then create a connection between
>> the two. This completes sucessfully and can be seen on both sides.
>>
>> 3. I then try to send an acl packet with the word "hi" in it and it is
>> not received on the other side.
>
> There a utility called l2test in the bluez sources. Check if it works for you.
> Using -r in one side to listen and -s in the other side to send data. Or
> l2test -h and see all options.
>
> --
> Gustavo F. Padovan
> http://profusion.mobi
>
^ permalink raw reply
* [PATCH] bluetooth: fix shutdown on SCO sockets
From: Luiz Augusto von Dentz @ 2011-05-12 8:13 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
shutdown should wait for SCO link to be properly disconnected before
detroying the socket, otherwise an application using the socket may
assume link is properly disconnected before it really happens which
can be a problem when e.g synchronizing profile switch.
Signed-off-by: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
---
net/bluetooth/sco.c | 13 ++++++++++++-
1 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 42fdffd..cb4fb78 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -369,6 +369,15 @@ static void __sco_sock_close(struct sock *sk)
case BT_CONNECTED:
case BT_CONFIG:
+ if (sco_pi(sk)->conn) {
+ sk->sk_state = BT_DISCONN;
+ sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT);
+ hci_conn_put(sco_pi(sk)->conn->hcon);
+ sco_pi(sk)->conn->hcon = NULL;
+ } else
+ sco_chan_del(sk, ECONNRESET);
+ break;
+
case BT_CONNECT:
case BT_DISCONN:
sco_chan_del(sk, ECONNRESET);
@@ -819,7 +828,9 @@ static void sco_chan_del(struct sock *sk, int err)
conn->sk = NULL;
sco_pi(sk)->conn = NULL;
sco_conn_unlock(conn);
- hci_conn_put(conn->hcon);
+
+ if (conn->hcon)
+ hci_conn_put(conn->hcon);
}
sk->sk_state = BT_CLOSED;
--
1.7.1
^ permalink raw reply related
* [PATCH 6/6] Bluetooth: Rename __l2cap_chan_close() to l2cap_chan_close()
From: Gustavo F. Padovan @ 2011-05-12 5:32 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1305178350-7568-5-git-send-email-padovan@profusion.mobi>
To make it consistent with the rest of the API.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 2 +-
net/bluetooth/l2cap_core.c | 29 ++++++++++++-----------------
net/bluetooth/l2cap_sock.c | 2 +-
3 files changed, 14 insertions(+), 19 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 86a076f..f78bb23 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -464,7 +464,7 @@ struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
int proto, gfp_t prio);
struct l2cap_chan *l2cap_chan_create(struct sock *sk);
-void __l2cap_chan_close(struct l2cap_chan *chan, int reason);
+void l2cap_chan_close(struct l2cap_chan *chan, int reason);
void l2cap_chan_destroy(struct l2cap_chan *chan);
int l2cap_chan_connect(struct l2cap_chan *chan);
int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index c4e8b1d..2ea5ea9 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -250,7 +250,7 @@ static void l2cap_chan_timeout(unsigned long arg)
else
reason = ETIMEDOUT;
- __l2cap_chan_close(chan, reason);
+ l2cap_chan_close(chan, reason);
bh_unlock_sock(sk);
@@ -383,16 +383,6 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err)
}
}
-/* Must be called on unlocked socket. */
-static void l2cap_chan_close(struct sock *sk)
-{
- l2cap_chan_clear_timer(l2cap_pi(sk)->chan);
- lock_sock(sk);
- __l2cap_chan_close(l2cap_pi(sk)->chan, ECONNRESET);
- release_sock(sk);
- l2cap_sock_kill(sk);
-}
-
static void l2cap_chan_cleanup_listen(struct sock *parent)
{
struct sock *sk;
@@ -400,14 +390,19 @@ static void l2cap_chan_cleanup_listen(struct sock *parent)
BT_DBG("parent %p", parent);
/* Close not yet accepted channels */
- while ((sk = bt_accept_dequeue(parent, NULL)))
- l2cap_chan_close(sk);
+ while ((sk = bt_accept_dequeue(parent, NULL))) {
+ l2cap_chan_clear_timer(l2cap_pi(sk)->chan);
+ lock_sock(sk);
+ l2cap_chan_close(l2cap_pi(sk)->chan, ECONNRESET);
+ release_sock(sk);
+ l2cap_sock_kill(sk);
+ }
parent->sk_state = BT_CLOSED;
sock_set_flag(parent, SOCK_ZAPPED);
}
-void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
+void l2cap_chan_close(struct l2cap_chan *chan, int reason)
{
struct l2cap_conn *conn = chan->conn;
struct sock *sk = chan->sk;
@@ -724,10 +719,10 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
conn->feat_mask)
&& chan->conf_state &
L2CAP_CONF_STATE2_DEVICE) {
- /* __l2cap_chan_close() calls list_del(chan)
+ /* l2cap_chan_close() calls list_del(chan)
* so release the lock */
read_unlock_bh(&conn->chan_lock);
- __l2cap_chan_close(chan, ECONNRESET);
+ l2cap_chan_close(chan, ECONNRESET);
read_lock_bh(&conn->chan_lock);
bh_unlock_sock(sk);
continue;
@@ -4156,7 +4151,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
l2cap_chan_clear_timer(chan);
l2cap_chan_set_timer(chan, HZ * 5);
} else if (chan->sec_level == BT_SECURITY_HIGH)
- __l2cap_chan_close(chan, ECONNREFUSED);
+ l2cap_chan_close(chan, ECONNREFUSED);
} else {
if (chan->sec_level == BT_SECURITY_MEDIUM)
l2cap_chan_clear_timer(chan);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 993846c..a6bfe85 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -707,7 +707,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
err = __l2cap_wait_ack(sk);
sk->sk_shutdown = SHUTDOWN_MASK;
- __l2cap_chan_close(chan, 0);
+ l2cap_chan_close(chan, 0);
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
err = bt_sock_wait_state(sk, BT_CLOSED,
--
1.7.5.rc3
^ permalink raw reply related
* [PATCH 5/6] Bluetooth: Remove export of l2cap_chan_clear_timer()
From: Gustavo F. Padovan @ 2011-05-12 5:32 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1305178350-7568-4-git-send-email-padovan@profusion.mobi>
The call to l2cap_chan_clear_timer() is not really needed in l2cap_sock.c.
This patch also adds a call to l2cap_chan_clear_timer() to the only place
in __l2cap_sock_close() that wasn't calling it. It's safe call it there
because l2cap_chan_clear_timer() check first for timer_peding().
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 1 -
net/bluetooth/l2cap_core.c | 3 ++-
net/bluetooth/l2cap_sock.c | 1 -
3 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index e14b806..86a076f 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -463,7 +463,6 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent);
struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
int proto, gfp_t prio);
-void l2cap_chan_clear_timer(struct l2cap_chan *chan);
struct l2cap_chan *l2cap_chan_create(struct sock *sk);
void __l2cap_chan_close(struct l2cap_chan *chan, int reason);
void l2cap_chan_destroy(struct l2cap_chan *chan);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index ddb72bb..c4e8b1d 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -216,7 +216,7 @@ static void l2cap_chan_set_timer(struct l2cap_chan *chan, long timeout)
sock_hold(chan->sk);
}
-void l2cap_chan_clear_timer(struct l2cap_chan *chan)
+static void l2cap_chan_clear_timer(struct l2cap_chan *chan)
{
BT_DBG("chan %p state %d", chan, chan->sk->sk_state);
@@ -423,6 +423,7 @@ void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
case BT_CONFIG:
if (chan->link_type == L2CAP_LINK_ORIENTED &&
conn->hcon->type == ACL_LINK) {
+ l2cap_chan_clear_timer(chan);
l2cap_chan_set_timer(chan, sk->sk_sndtimeo);
l2cap_send_disconn_req(conn, chan, reason);
} else
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 56c301a..993846c 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -707,7 +707,6 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
err = __l2cap_wait_ack(sk);
sk->sk_shutdown = SHUTDOWN_MASK;
- l2cap_chan_clear_timer(chan);
__l2cap_chan_close(chan, 0);
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
--
1.7.5.rc3
^ permalink raw reply related
* [PATCH 4/6] Bluetooth: create channel timer to replace sk_timer
From: Gustavo F. Padovan @ 2011-05-12 5:32 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1305178350-7568-3-git-send-email-padovan@profusion.mobi>
The new timer does not belong to struct sock, tought it still touch some
sock things, but this will be sorted out soon.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 5 +-
net/bluetooth/l2cap_core.c | 100 ++++++++++++++++++++++++++++++----------
net/bluetooth/l2cap_sock.c | 50 +--------------------
3 files changed, 79 insertions(+), 76 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 6915c43..e14b806 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -340,6 +340,7 @@ struct l2cap_chan {
__u8 remote_max_tx;
__u16 remote_mps;
+ struct timer_list chan_timer;
struct timer_list retrans_timer;
struct timer_list monitor_timer;
struct timer_list ack_timer;
@@ -457,12 +458,12 @@ int __l2cap_wait_ack(struct sock *sk);
int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
-void l2cap_sock_set_timer(struct sock *sk, long timeout);
-void l2cap_sock_clear_timer(struct sock *sk);
void l2cap_sock_kill(struct sock *sk);
void l2cap_sock_init(struct sock *sk, struct sock *parent);
struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
int proto, gfp_t prio);
+
+void l2cap_chan_clear_timer(struct l2cap_chan *chan);
struct l2cap_chan *l2cap_chan_create(struct sock *sk);
void __l2cap_chan_close(struct l2cap_chan *chan, int reason);
void l2cap_chan_destroy(struct l2cap_chan *chan);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index e1731b9..ddb72bb 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -208,6 +208,56 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
return 0;
}
+static void l2cap_chan_set_timer(struct l2cap_chan *chan, long timeout)
+{
+ BT_DBG("chan %p state %d timeout %ld", chan->sk, chan->sk->sk_state,
+ timeout);
+ if (!mod_timer(&chan->chan_timer, jiffies + timeout))
+ sock_hold(chan->sk);
+}
+
+void l2cap_chan_clear_timer(struct l2cap_chan *chan)
+{
+ BT_DBG("chan %p state %d", chan, chan->sk->sk_state);
+
+ if (timer_pending(&chan->chan_timer) && del_timer(&chan->chan_timer))
+ __sock_put(chan->sk);
+}
+
+static void l2cap_chan_timeout(unsigned long arg)
+{
+ struct l2cap_chan *chan = (struct l2cap_chan *) arg;
+ struct sock *sk = chan->sk;
+ int reason;
+
+ BT_DBG("chan %p state %d", chan, sk->sk_state);
+
+ bh_lock_sock(sk);
+
+ if (sock_owned_by_user(sk)) {
+ /* sk is owned by user. Try again later */
+ l2cap_chan_set_timer(chan, HZ / 5);
+ bh_unlock_sock(sk);
+ sock_put(sk);
+ return;
+ }
+
+ if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
+ reason = ECONNREFUSED;
+ else if (sk->sk_state == BT_CONNECT &&
+ chan->sec_level != BT_SECURITY_SDP)
+ reason = ECONNREFUSED;
+ else
+ reason = ETIMEDOUT;
+
+ __l2cap_chan_close(chan, reason);
+
+ bh_unlock_sock(sk);
+
+ l2cap_sock_kill(sk);
+ sock_put(sk);
+}
+
struct l2cap_chan *l2cap_chan_create(struct sock *sk)
{
struct l2cap_chan *chan;
@@ -222,6 +272,8 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk)
list_add(&chan->global_l, &chan_list);
write_unlock_bh(&chan_list_lock);
+ setup_timer(&chan->chan_timer, l2cap_chan_timeout, (unsigned long) chan);
+
return chan;
}
@@ -281,7 +333,7 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err)
struct l2cap_conn *conn = chan->conn;
struct sock *parent = bt_sk(sk)->parent;
- l2cap_sock_clear_timer(sk);
+ l2cap_chan_clear_timer(chan);
BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
@@ -334,7 +386,7 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err)
/* Must be called on unlocked socket. */
static void l2cap_chan_close(struct sock *sk)
{
- l2cap_sock_clear_timer(sk);
+ l2cap_chan_clear_timer(l2cap_pi(sk)->chan);
lock_sock(sk);
__l2cap_chan_close(l2cap_pi(sk)->chan, ECONNRESET);
release_sock(sk);
@@ -371,7 +423,7 @@ void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
case BT_CONFIG:
if (chan->link_type == L2CAP_LINK_ORIENTED &&
conn->hcon->type == ACL_LINK) {
- l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
+ l2cap_chan_set_timer(chan, sk->sk_sndtimeo);
l2cap_send_disconn_req(conn, chan, reason);
} else
l2cap_chan_del(chan, reason);
@@ -814,7 +866,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
__l2cap_chan_add(conn, chan);
- l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
+ l2cap_chan_set_timer(chan, sk->sk_sndtimeo);
sk->sk_state = BT_CONNECTED;
parent->sk_data_ready(parent, 0);
@@ -842,13 +894,13 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
bh_lock_sock(sk);
if (conn->hcon->type == LE_LINK) {
- l2cap_sock_clear_timer(sk);
+ l2cap_chan_clear_timer(chan);
sk->sk_state = BT_CONNECTED;
sk->sk_state_change(sk);
}
if (chan->link_type != L2CAP_LINK_ORIENTED) {
- l2cap_sock_clear_timer(sk);
+ l2cap_chan_clear_timer(chan);
sk->sk_state = BT_CONNECTED;
sk->sk_state_change(sk);
} else if (sk->sk_state == BT_CONNECT)
@@ -1047,11 +1099,11 @@ int l2cap_chan_connect(struct l2cap_chan *chan)
l2cap_chan_add(conn, chan);
sk->sk_state = BT_CONNECT;
- l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
+ l2cap_chan_set_timer(chan, sk->sk_sndtimeo);
if (hcon->state == BT_CONNECTED) {
if (chan->link_type != L2CAP_LINK_ORIENTED) {
- l2cap_sock_clear_timer(sk);
+ l2cap_chan_clear_timer(chan);
if (l2cap_check_security(chan))
sk->sk_state = BT_CONNECTED;
} else
@@ -1614,7 +1666,7 @@ static void l2cap_chan_ready(struct sock *sk)
BT_DBG("sk %p, parent %p", sk, parent);
chan->conf_state = 0;
- l2cap_sock_clear_timer(sk);
+ l2cap_chan_clear_timer(chan);
if (!parent) {
/* Outgoing channel.
@@ -2316,7 +2368,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
dcid = chan->scid;
- l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
+ l2cap_chan_set_timer(chan, sk->sk_sndtimeo);
chan->ident = cmd->ident;
@@ -2433,8 +2485,8 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
/* don't delete l2cap channel if sk is owned by user */
if (sock_owned_by_user(sk)) {
sk->sk_state = BT_DISCONN;
- l2cap_sock_clear_timer(sk);
- l2cap_sock_set_timer(sk, HZ / 5);
+ l2cap_chan_clear_timer(chan);
+ l2cap_chan_set_timer(chan, HZ / 5);
break;
}
@@ -2607,7 +2659,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
default:
sk->sk_err = ECONNRESET;
- l2cap_sock_set_timer(sk, HZ * 5);
+ l2cap_chan_set_timer(chan, HZ * 5);
l2cap_send_disconn_req(conn, chan, ECONNRESET);
goto done;
}
@@ -2663,8 +2715,8 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
/* don't delete l2cap channel if sk is owned by user */
if (sock_owned_by_user(sk)) {
sk->sk_state = BT_DISCONN;
- l2cap_sock_clear_timer(sk);
- l2cap_sock_set_timer(sk, HZ / 5);
+ l2cap_chan_clear_timer(chan);
+ l2cap_chan_set_timer(chan, HZ / 5);
bh_unlock_sock(sk);
return 0;
}
@@ -2697,8 +2749,8 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
/* don't delete l2cap channel if sk is owned by user */
if (sock_owned_by_user(sk)) {
sk->sk_state = BT_DISCONN;
- l2cap_sock_clear_timer(sk);
- l2cap_sock_set_timer(sk, HZ / 5);
+ l2cap_chan_clear_timer(chan);
+ l2cap_chan_set_timer(chan, HZ / 5);
bh_unlock_sock(sk);
return 0;
}
@@ -4095,20 +4147,18 @@ static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
{
- struct sock *sk = chan->sk;
-
if (chan->link_type != L2CAP_LINK_ORIENTED)
return;
if (encrypt == 0x00) {
if (chan->sec_level == BT_SECURITY_MEDIUM) {
- l2cap_sock_clear_timer(sk);
- l2cap_sock_set_timer(sk, HZ * 5);
+ l2cap_chan_clear_timer(chan);
+ l2cap_chan_set_timer(chan, HZ * 5);
} else if (chan->sec_level == BT_SECURITY_HIGH)
__l2cap_chan_close(chan, ECONNREFUSED);
} else {
if (chan->sec_level == BT_SECURITY_MEDIUM)
- l2cap_sock_clear_timer(sk);
+ l2cap_chan_clear_timer(chan);
}
}
@@ -4153,8 +4203,8 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
l2cap_send_cmd(conn, chan->ident,
L2CAP_CONN_REQ, sizeof(req), &req);
} else {
- l2cap_sock_clear_timer(sk);
- l2cap_sock_set_timer(sk, HZ / 10);
+ l2cap_chan_clear_timer(chan);
+ l2cap_chan_set_timer(chan, HZ / 10);
}
} else if (sk->sk_state == BT_CONNECT2) {
struct l2cap_conn_rsp rsp;
@@ -4165,7 +4215,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
result = L2CAP_CR_SUCCESS;
} else {
sk->sk_state = BT_DISCONN;
- l2cap_sock_set_timer(sk, HZ / 10);
+ l2cap_chan_set_timer(chan, HZ / 10);
result = L2CAP_CR_SEC_BLOCK;
}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 6d5ecca..56c301a 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -32,52 +32,6 @@
static const struct proto_ops l2cap_sock_ops;
-/* ---- L2CAP timers ---- */
-static void l2cap_sock_timeout(unsigned long arg)
-{
- struct sock *sk = (struct sock *) arg;
- int reason;
-
- BT_DBG("sock %p state %d", sk, sk->sk_state);
-
- bh_lock_sock(sk);
-
- if (sock_owned_by_user(sk)) {
- /* sk is owned by user. Try again later */
- l2cap_sock_set_timer(sk, HZ / 5);
- bh_unlock_sock(sk);
- sock_put(sk);
- return;
- }
-
- if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
- reason = ECONNREFUSED;
- else if (sk->sk_state == BT_CONNECT &&
- l2cap_pi(sk)->chan->sec_level != BT_SECURITY_SDP)
- reason = ECONNREFUSED;
- else
- reason = ETIMEDOUT;
-
- __l2cap_chan_close(l2cap_pi(sk)->chan, reason);
-
- bh_unlock_sock(sk);
-
- l2cap_sock_kill(sk);
- sock_put(sk);
-}
-
-void l2cap_sock_set_timer(struct sock *sk, long timeout)
-{
- BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
- sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
-}
-
-void l2cap_sock_clear_timer(struct sock *sk)
-{
- BT_DBG("sock %p state %d", sk, sk->sk_state);
- sk_stop_timer(sk, &sk->sk_timer);
-}
-
static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
{
struct sock *sk = sock->sk;
@@ -753,7 +707,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
err = __l2cap_wait_ack(sk);
sk->sk_shutdown = SHUTDOWN_MASK;
- l2cap_sock_clear_timer(sk);
+ l2cap_chan_clear_timer(chan);
__l2cap_chan_close(chan, 0);
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
@@ -880,8 +834,6 @@ struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, g
sk->sk_protocol = proto;
sk->sk_state = BT_OPEN;
- setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
-
return sk;
}
--
1.7.5.rc3
^ permalink raw reply related
* [PATCH 3/6] Bluetooth: Add chan->link_type struct member
From: Gustavo F. Padovan @ 2011-05-12 5:32 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1305178350-7568-2-git-send-email-padovan@profusion.mobi>
link_type says if our link is raw, connection less or connection oriented.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 5 +++++
net/bluetooth/l2cap_core.c | 30 +++++++++++-------------------
net/bluetooth/l2cap_sock.c | 30 +++++++++++++++++++++++-------
3 files changed, 39 insertions(+), 26 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index dc721ca..6915c43 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -295,6 +295,7 @@ struct l2cap_chan {
__u16 omtu;
__u16 flush_to;
__u8 mode;
+ __u8 link_type;
__le16 sport;
@@ -384,6 +385,10 @@ struct l2cap_conn {
#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04
#define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08
+#define L2CAP_LINK_RAW 1
+#define L2CAP_LINK_CONNLESS 2
+#define L2CAP_LINK_ORIENTED 3
+
/* ----- L2CAP socket info ----- */
#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 5473fc9..e1731b9 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -245,7 +245,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
chan->conn = conn;
- if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
+ if (chan->link_type == L2CAP_LINK_ORIENTED) {
if (conn->hcon->type == LE_LINK) {
/* LE connection */
chan->omtu = L2CAP_LE_DEFAULT_MTU;
@@ -256,7 +256,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
chan->scid = l2cap_alloc_cid(conn);
chan->omtu = L2CAP_DEFAULT_MTU;
}
- } else if (sk->sk_type == SOCK_DGRAM) {
+ } else if (chan->link_type == L2CAP_LINK_CONNLESS) {
/* Connectionless socket */
chan->scid = L2CAP_CID_CONN_LESS;
chan->dcid = L2CAP_CID_CONN_LESS;
@@ -369,8 +369,7 @@ void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
case BT_CONNECTED:
case BT_CONFIG:
- if ((sk->sk_type == SOCK_SEQPACKET ||
- sk->sk_type == SOCK_STREAM) &&
+ if (chan->link_type == L2CAP_LINK_ORIENTED &&
conn->hcon->type == ACL_LINK) {
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
l2cap_send_disconn_req(conn, chan, reason);
@@ -379,8 +378,7 @@ void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
break;
case BT_CONNECT2:
- if ((sk->sk_type == SOCK_SEQPACKET ||
- sk->sk_type == SOCK_STREAM) &&
+ if (chan->link_type == L2CAP_LINK_ORIENTED &&
conn->hcon->type == ACL_LINK) {
struct l2cap_conn_rsp rsp;
__u16 result;
@@ -414,9 +412,7 @@ void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
{
- struct sock *sk = chan->sk;
-
- if (sk->sk_type == SOCK_RAW) {
+ if (chan->link_type == L2CAP_LINK_RAW) {
switch (chan->sec_level) {
case BT_SECURITY_HIGH:
return HCI_AT_DEDICATED_BONDING_MITM;
@@ -657,8 +653,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
bh_lock_sock(sk);
- if (sk->sk_type != SOCK_SEQPACKET &&
- sk->sk_type != SOCK_STREAM) {
+ if (chan->link_type != L2CAP_LINK_ORIENTED) {
bh_unlock_sock(sk);
continue;
}
@@ -852,8 +847,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
sk->sk_state_change(sk);
}
- if (sk->sk_type != SOCK_SEQPACKET &&
- sk->sk_type != SOCK_STREAM) {
+ if (chan->link_type != L2CAP_LINK_ORIENTED) {
l2cap_sock_clear_timer(sk);
sk->sk_state = BT_CONNECTED;
sk->sk_state_change(sk);
@@ -1056,8 +1050,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan)
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
if (hcon->state == BT_CONNECTED) {
- if (sk->sk_type != SOCK_SEQPACKET &&
- sk->sk_type != SOCK_STREAM) {
+ if (chan->link_type != L2CAP_LINK_ORIENTED) {
l2cap_sock_clear_timer(sk);
if (l2cap_check_security(chan))
sk->sk_state = BT_CONNECTED;
@@ -1537,13 +1530,12 @@ int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t le
int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
{
- struct sock *sk = chan->sk;
struct sk_buff *skb;
u16 control;
int err;
/* Connectionless channel */
- if (sk->sk_type == SOCK_DGRAM) {
+ if (chan->link_type == L2CAP_LINK_CONNLESS) {
skb = l2cap_create_connless_pdu(chan, msg, len);
if (IS_ERR(skb))
return PTR_ERR(skb);
@@ -1649,7 +1641,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
read_lock(&conn->chan_lock);
list_for_each_entry(chan, &conn->chan_l, list) {
struct sock *sk = chan->sk;
- if (sk->sk_type != SOCK_RAW)
+ if (chan->link_type != L2CAP_LINK_RAW)
continue;
/* Don't send frame to the socket it came from */
@@ -4105,7 +4097,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
{
struct sock *sk = chan->sk;
- if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM)
+ if (chan->link_type != L2CAP_LINK_ORIENTED)
return;
if (encrypt == 0x00) {
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index f36776e..6d5ecca 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -162,7 +162,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
lock_sock(sk);
- if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
+ if (chan->link_type == L2CAP_LINK_ORIENTED
&& !(la.l2_psm || la.l2_cid)) {
err = -EINVAL;
goto done;
@@ -204,8 +204,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
}
/* PSM must be odd and lsb of upper byte must be 0 */
- if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 &&
- sk->sk_type != SOCK_RAW && !la.l2_cid) {
+ if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && !la.l2_cid &&
+ chan->link_type == L2CAP_LINK_RAW) {
err = -EINVAL;
goto done;
}
@@ -453,8 +453,8 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
switch (optname) {
case BT_SECURITY:
- if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
- && sk->sk_type != SOCK_RAW) {
+ if (chan->link_type != L2CAP_LINK_ORIENTED &&
+ chan->link_type != L2CAP_LINK_RAW) {
err = -EINVAL;
break;
}
@@ -599,8 +599,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
switch (optname) {
case BT_SECURITY:
- if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
- && sk->sk_type != SOCK_RAW) {
+ if (chan->link_type != L2CAP_LINK_ORIENTED &&
+ chan->link_type != L2CAP_LINK_RAW) {
err = -EINVAL;
break;
}
@@ -806,6 +806,7 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
sk->sk_type = parent->sk_type;
bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
+ chan->link_type = pchan->link_type;
chan->imtu = pchan->imtu;
chan->omtu = pchan->omtu;
chan->conf_state = pchan->conf_state;
@@ -818,6 +819,20 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
chan->force_reliable = pchan->force_reliable;
chan->flushable = pchan->flushable;
} else {
+
+ switch (sk->sk_type) {
+ case SOCK_RAW:
+ chan->link_type = L2CAP_LINK_RAW;
+ break;
+ case SOCK_DGRAM:
+ chan->link_type = L2CAP_LINK_CONNLESS;
+ break;
+ case SOCK_SEQPACKET:
+ case SOCK_STREAM:
+ chan->link_type = L2CAP_LINK_ORIENTED;
+ break;
+ }
+
chan->imtu = L2CAP_DEFAULT_MTU;
chan->omtu = 0;
if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
@@ -826,6 +841,7 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
} else {
chan->mode = L2CAP_MODE_BASIC;
}
+
chan->max_tx = L2CAP_DEFAULT_MAX_TX;
chan->fcs = L2CAP_FCS_CRC16;
chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
--
1.7.5.rc3
^ permalink raw reply related
* [PATCH 2/6] Bluetooth: Create l2cap_chan_send()
From: Gustavo F. Padovan @ 2011-05-12 5:32 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1305178350-7568-1-git-send-email-padovan@profusion.mobi>
This move all the sending logic to l2cap_core.c, but we still have a
socket dependence there, struct msghdr. It will be removed in some of the
further commits.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 9 +----
net/bluetooth/l2cap_core.c | 79 +++++++++++++++++++++++++++++++++++++++
net/bluetooth/l2cap_sock.c | 83 +---------------------------------------
3 files changed, 83 insertions(+), 88 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index ed75e65..dc721ca 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -449,14 +449,6 @@ void l2cap_cleanup_sockets(void);
void __l2cap_connect_rsp_defer(struct l2cap_chan *chan);
int __l2cap_wait_ack(struct sock *sk);
-struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
-struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
-struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len, u16 control, u16 sdulen);
-int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
-void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb);
-void l2cap_streaming_send(struct l2cap_chan *chan);
-int l2cap_ertm_send(struct l2cap_chan *chan);
-
int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
@@ -470,5 +462,6 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk);
void __l2cap_chan_close(struct l2cap_chan *chan, int reason);
void l2cap_chan_destroy(struct l2cap_chan *chan);
int l2cap_chan_connect(struct l2cap_chan *chan);
+int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
#endif /* __L2CAP_H */
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 7a943de..5473fc9 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1535,6 +1535,85 @@ int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t le
return size;
}
+int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
+{
+ struct sock *sk = chan->sk;
+ struct sk_buff *skb;
+ u16 control;
+ int err;
+
+ /* Connectionless channel */
+ if (sk->sk_type == SOCK_DGRAM) {
+ skb = l2cap_create_connless_pdu(chan, msg, len);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ l2cap_do_send(chan, skb);
+ return len;
+ }
+
+ switch (chan->mode) {
+ case L2CAP_MODE_BASIC:
+ /* Check outgoing MTU */
+ if (len > chan->omtu)
+ return -EMSGSIZE;
+
+ /* Create a basic PDU */
+ skb = l2cap_create_basic_pdu(chan, msg, len);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ l2cap_do_send(chan, skb);
+ err = len;
+ break;
+
+ case L2CAP_MODE_ERTM:
+ case L2CAP_MODE_STREAMING:
+ /* Entire SDU fits into one PDU */
+ if (len <= chan->remote_mps) {
+ control = L2CAP_SDU_UNSEGMENTED;
+ skb = l2cap_create_iframe_pdu(chan, msg, len, control,
+ 0);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ __skb_queue_tail(&chan->tx_q, skb);
+
+ if (chan->tx_send_head == NULL)
+ chan->tx_send_head = skb;
+
+ } else {
+ /* Segment SDU into multiples PDUs */
+ err = l2cap_sar_segment_sdu(chan, msg, len);
+ if (err < 0)
+ return err;
+ }
+
+ if (chan->mode == L2CAP_MODE_STREAMING) {
+ l2cap_streaming_send(chan);
+ err = len;
+ break;
+ }
+
+ if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
+ (chan->conn_state & L2CAP_CONN_WAIT_F)) {
+ err = len;
+ break;
+ }
+ err = l2cap_ertm_send(chan);
+
+ if (err >= 0)
+ err = len;
+ break;
+
+ default:
+ BT_DBG("bad state %1.1x", chan->mode);
+ err = -EBADFD;
+ }
+
+ return err;
+}
+
static void l2cap_chan_ready(struct sock *sk)
{
struct sock *parent = bt_sk(sk)->parent;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index f57afa5..f36776e 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -673,8 +673,6 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
{
struct sock *sk = sock->sk;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
- struct sk_buff *skb;
- u16 control;
int err;
BT_DBG("sock %p, sk %p", sock, sk);
@@ -689,87 +687,12 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
lock_sock(sk);
if (sk->sk_state != BT_CONNECTED) {
- err = -ENOTCONN;
- goto done;
+ release_sock(sk);
+ return -ENOTCONN;
}
- /* Connectionless channel */
- if (sk->sk_type == SOCK_DGRAM) {
- skb = l2cap_create_connless_pdu(chan, msg, len);
- if (IS_ERR(skb)) {
- err = PTR_ERR(skb);
- } else {
- l2cap_do_send(chan, skb);
- err = len;
- }
- goto done;
- }
+ err = l2cap_chan_send(chan, msg, len);
- switch (chan->mode) {
- case L2CAP_MODE_BASIC:
- /* Check outgoing MTU */
- if (len > chan->omtu) {
- err = -EMSGSIZE;
- goto done;
- }
-
- /* Create a basic PDU */
- skb = l2cap_create_basic_pdu(chan, msg, len);
- if (IS_ERR(skb)) {
- err = PTR_ERR(skb);
- goto done;
- }
-
- l2cap_do_send(chan, skb);
- err = len;
- break;
-
- case L2CAP_MODE_ERTM:
- case L2CAP_MODE_STREAMING:
- /* Entire SDU fits into one PDU */
- if (len <= chan->remote_mps) {
- control = L2CAP_SDU_UNSEGMENTED;
- skb = l2cap_create_iframe_pdu(chan, msg, len, control,
- 0);
- if (IS_ERR(skb)) {
- err = PTR_ERR(skb);
- goto done;
- }
- __skb_queue_tail(&chan->tx_q, skb);
-
- if (chan->tx_send_head == NULL)
- chan->tx_send_head = skb;
-
- } else {
- /* Segment SDU into multiples PDUs */
- err = l2cap_sar_segment_sdu(chan, msg, len);
- if (err < 0)
- goto done;
- }
-
- if (chan->mode == L2CAP_MODE_STREAMING) {
- l2cap_streaming_send(chan);
- err = len;
- break;
- }
-
- if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
- (chan->conn_state & L2CAP_CONN_WAIT_F)) {
- err = len;
- break;
- }
- err = l2cap_ertm_send(chan);
-
- if (err >= 0)
- err = len;
- break;
-
- default:
- BT_DBG("bad state %1.1x", chan->mode);
- err = -EBADFD;
- }
-
-done:
release_sock(sk);
return err;
}
--
1.7.5.rc3
^ permalink raw reply related
* [PATCH 1/6] Bluetooth: Create __l2cap_chan_close()
From: Gustavo F. Padovan @ 2011-05-12 5:32 UTC (permalink / raw)
To: linux-bluetooth
This is actually __l2cap_sock_close() renamed to __l2cap_chan_close().
At a first look it may not make sense, but with the further cleanups that
will come it will.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 5 +--
net/bluetooth/l2cap_core.c | 97 ++++++++++++++++++++++++++++++++++++++---
net/bluetooth/l2cap_sock.c | 85 +-----------------------------------
3 files changed, 94 insertions(+), 93 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index d09c9b1..ed75e65 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -446,7 +446,6 @@ extern int disable_ertm;
int l2cap_init_sockets(void);
void l2cap_cleanup_sockets(void);
-void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data);
void __l2cap_connect_rsp_defer(struct l2cap_chan *chan);
int __l2cap_wait_ack(struct sock *sk);
@@ -463,14 +462,12 @@ int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
void l2cap_sock_set_timer(struct sock *sk, long timeout);
void l2cap_sock_clear_timer(struct sock *sk);
-void __l2cap_sock_close(struct sock *sk, int reason);
void l2cap_sock_kill(struct sock *sk);
void l2cap_sock_init(struct sock *sk, struct sock *parent);
struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
int proto, gfp_t prio);
-void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err);
struct l2cap_chan *l2cap_chan_create(struct sock *sk);
-void l2cap_chan_del(struct l2cap_chan *chan, int err);
+void __l2cap_chan_close(struct l2cap_chan *chan, int reason);
void l2cap_chan_destroy(struct l2cap_chan *chan);
int l2cap_chan_connect(struct l2cap_chan *chan);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a5ab4a2..7a943de 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -69,7 +69,11 @@ static void l2cap_busy_work(struct work_struct *work);
static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
u8 code, u8 ident, u16 dlen, void *data);
+static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
+ void *data);
static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
+static void l2cap_send_disconn_req(struct l2cap_conn *conn,
+ struct l2cap_chan *chan, int err);
static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
@@ -271,7 +275,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
/* Delete channel.
* Must be called on the locked socket. */
-void l2cap_chan_del(struct l2cap_chan *chan, int err)
+static void l2cap_chan_del(struct l2cap_chan *chan, int err)
{
struct sock *sk = chan->sk;
struct l2cap_conn *conn = chan->conn;
@@ -327,6 +331,87 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
}
}
+/* Must be called on unlocked socket. */
+static void l2cap_chan_close(struct sock *sk)
+{
+ l2cap_sock_clear_timer(sk);
+ lock_sock(sk);
+ __l2cap_chan_close(l2cap_pi(sk)->chan, ECONNRESET);
+ release_sock(sk);
+ l2cap_sock_kill(sk);
+}
+
+static void l2cap_chan_cleanup_listen(struct sock *parent)
+{
+ struct sock *sk;
+
+ BT_DBG("parent %p", parent);
+
+ /* Close not yet accepted channels */
+ while ((sk = bt_accept_dequeue(parent, NULL)))
+ l2cap_chan_close(sk);
+
+ parent->sk_state = BT_CLOSED;
+ sock_set_flag(parent, SOCK_ZAPPED);
+}
+
+void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
+{
+ struct l2cap_conn *conn = chan->conn;
+ struct sock *sk = chan->sk;
+
+ BT_DBG("chan %p state %d socket %p", chan, sk->sk_state, sk->sk_socket);
+
+ switch (sk->sk_state) {
+ case BT_LISTEN:
+ l2cap_chan_cleanup_listen(chan->sk);
+ break;
+
+ case BT_CONNECTED:
+ case BT_CONFIG:
+ if ((sk->sk_type == SOCK_SEQPACKET ||
+ sk->sk_type == SOCK_STREAM) &&
+ conn->hcon->type == ACL_LINK) {
+ l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
+ l2cap_send_disconn_req(conn, chan, reason);
+ } else
+ l2cap_chan_del(chan, reason);
+ break;
+
+ case BT_CONNECT2:
+ if ((sk->sk_type == SOCK_SEQPACKET ||
+ sk->sk_type == SOCK_STREAM) &&
+ conn->hcon->type == ACL_LINK) {
+ struct l2cap_conn_rsp rsp;
+ __u16 result;
+
+ if (bt_sk(sk)->defer_setup)
+ result = L2CAP_CR_SEC_BLOCK;
+ else
+ result = L2CAP_CR_BAD_PSM;
+
+ rsp.scid = cpu_to_le16(chan->dcid);
+ rsp.dcid = cpu_to_le16(chan->scid);
+ rsp.result = cpu_to_le16(result);
+ rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
+ l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
+ sizeof(rsp), &rsp);
+ }
+
+ l2cap_chan_del(chan, reason);
+ break;
+
+ case BT_CONNECT:
+ case BT_DISCONN:
+ l2cap_chan_del(chan, reason);
+ break;
+
+ default:
+ sock_set_flag(sk, SOCK_ZAPPED);
+ break;
+ }
+}
+
static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
{
struct sock *sk = chan->sk;
@@ -393,7 +478,7 @@ u8 l2cap_get_ident(struct l2cap_conn *conn)
return id;
}
-void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
+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);
u8 flags;
@@ -533,7 +618,7 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
}
}
-void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
+static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
{
struct sock *sk;
struct l2cap_disconn_req req;
@@ -591,10 +676,10 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
conn->feat_mask)
&& chan->conf_state &
L2CAP_CONF_STATE2_DEVICE) {
- /* __l2cap_sock_close() calls list_del(chan)
+ /* __l2cap_chan_close() calls list_del(chan)
* so release the lock */
read_unlock_bh(&conn->chan_lock);
- __l2cap_sock_close(sk, ECONNRESET);
+ __l2cap_chan_close(chan, ECONNRESET);
read_lock_bh(&conn->chan_lock);
bh_unlock_sock(sk);
continue;
@@ -3949,7 +4034,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
l2cap_sock_clear_timer(sk);
l2cap_sock_set_timer(sk, HZ * 5);
} else if (chan->sec_level == BT_SECURITY_HIGH)
- __l2cap_sock_close(sk, ECONNREFUSED);
+ __l2cap_chan_close(chan, ECONNREFUSED);
} else {
if (chan->sec_level == BT_SECURITY_MEDIUM)
l2cap_sock_clear_timer(sk);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index c98360d..f57afa5 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -58,7 +58,7 @@ static void l2cap_sock_timeout(unsigned long arg)
else
reason = ETIMEDOUT;
- __l2cap_sock_close(sk, reason);
+ __l2cap_chan_close(l2cap_pi(sk)->chan, reason);
bh_unlock_sock(sk);
@@ -813,87 +813,6 @@ void l2cap_sock_kill(struct sock *sk)
sock_put(sk);
}
-/* Must be called on unlocked socket. */
-static void l2cap_sock_close(struct sock *sk)
-{
- l2cap_sock_clear_timer(sk);
- lock_sock(sk);
- __l2cap_sock_close(sk, ECONNRESET);
- release_sock(sk);
- l2cap_sock_kill(sk);
-}
-
-static void l2cap_sock_cleanup_listen(struct sock *parent)
-{
- struct sock *sk;
-
- BT_DBG("parent %p", parent);
-
- /* Close not yet accepted channels */
- while ((sk = bt_accept_dequeue(parent, NULL)))
- l2cap_sock_close(sk);
-
- parent->sk_state = BT_CLOSED;
- sock_set_flag(parent, SOCK_ZAPPED);
-}
-
-void __l2cap_sock_close(struct sock *sk, int reason)
-{
- struct l2cap_chan *chan = l2cap_pi(sk)->chan;
- struct l2cap_conn *conn = chan->conn;
-
- BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
-
- switch (sk->sk_state) {
- case BT_LISTEN:
- l2cap_sock_cleanup_listen(sk);
- break;
-
- case BT_CONNECTED:
- case BT_CONFIG:
- if ((sk->sk_type == SOCK_SEQPACKET ||
- sk->sk_type == SOCK_STREAM) &&
- conn->hcon->type == ACL_LINK) {
- l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
- l2cap_send_disconn_req(conn, chan, reason);
- } else
- l2cap_chan_del(chan, reason);
- break;
-
- case BT_CONNECT2:
- if ((sk->sk_type == SOCK_SEQPACKET ||
- sk->sk_type == SOCK_STREAM) &&
- conn->hcon->type == ACL_LINK) {
- struct l2cap_conn_rsp rsp;
- __u16 result;
-
- if (bt_sk(sk)->defer_setup)
- result = L2CAP_CR_SEC_BLOCK;
- else
- result = L2CAP_CR_BAD_PSM;
-
- rsp.scid = cpu_to_le16(chan->dcid);
- rsp.dcid = cpu_to_le16(chan->scid);
- rsp.result = cpu_to_le16(result);
- rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
- l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
- sizeof(rsp), &rsp);
- }
-
- l2cap_chan_del(chan, reason);
- break;
-
- case BT_CONNECT:
- case BT_DISCONN:
- l2cap_chan_del(chan, reason);
- break;
-
- default:
- sock_set_flag(sk, SOCK_ZAPPED);
- break;
- }
-}
-
static int l2cap_sock_shutdown(struct socket *sock, int how)
{
struct sock *sk = sock->sk;
@@ -912,7 +831,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
sk->sk_shutdown = SHUTDOWN_MASK;
l2cap_sock_clear_timer(sk);
- __l2cap_sock_close(sk, 0);
+ __l2cap_chan_close(chan, 0);
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
err = bt_sock_wait_state(sk, BT_CLOSED,
--
1.7.5.rc3
^ permalink raw reply related
* pull request: bluetooth-next-2.6 2011-05-12
From: Gustavo F. Padovan @ 2011-05-12 5:29 UTC (permalink / raw)
To: linville, linux-wireless, linux-bluetooth
Hi John,
I hope I'm in time for the merge window, I have a few patches I want push in.
Device ID for a new device in ath3k firmware loader by Andy Ross, more L2CAP
rewrite patches by me, Two fixes to enable LE usage by Vinicius Costa Gomes and
a patch from Waldemar Rymarkiewicz that was left behind in the last pull
request.
Please pull, thanks.
The following changes since commit bbe6ad6dcb1eb26bd12ec85320f402721c3383ae:
cfg80211/nl80211: add interval attribute for scheduled scans (2011-05-11 15:12:27 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next-2.6.git master
Andy Ross (1):
Bluetooth: Device ids for ath3k on Pegatron Lucid tablets
Gustavo F. Padovan (4):
Bluetooth: Add l2cap_add_psm() and l2cap_add_scid()
Bluetooth: Handle psm == 0 case inside l2cap_add_psm()
Bluetooth: Remove l2cap_sk_list
Bluetooth: Remove leftover debug messages
Vinicius Costa Gomes (2):
Bluetooth: Add support for sending connection events for LE links
Bluetooth: Add support for disconnecting LE links via mgmt
Waldemar Rymarkiewicz (1):
Bluetooth: Double check sec req for pre 2.1 device
drivers/bluetooth/ath3k.c | 1 +
drivers/bluetooth/btusb.c | 1 +
include/net/bluetooth/hci_core.h | 1 +
include/net/bluetooth/l2cap.h | 9 +-
net/bluetooth/hci_conn.c | 17 ++++
net/bluetooth/hci_event.c | 5 +-
net/bluetooth/l2cap_core.c | 193 ++++++++++++++++++++++++++------------
net/bluetooth/l2cap_sock.c | 72 +++------------
net/bluetooth/mgmt.c | 3 +
net/bluetooth/rfcomm/core.c | 2 +-
10 files changed, 180 insertions(+), 124 deletions(-)
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: btusb and non-standard descriptors
From: Marcel Holtmann @ 2011-05-12 1:32 UTC (permalink / raw)
To: Cufi, Carles; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <5B4B9A479BF6994B88EA975675EC5B790575861F5C@MES1OS2SXC003.mes1.tconet.net>
Hi Carles,
> Just wondering, what intefaces/endpoints does btusb use when there's no standard "USB_DEVICE_INFO(0xe0, 0x01, 0x01)" descriptor and instead it's using a hardcoded VID/PID?
the ones described in the Bluetooth USB HCI (aka H:2) standard.
Regards
Marcel
^ permalink raw reply
* Re: Bluetooth: l2cap and rfcomm: fix 1 byte infoleak to userspace.
From: Marcel Holtmann @ 2011-05-12 1:30 UTC (permalink / raw)
To: Filip Palian; +Cc: Gustavo F. Padovan, David S. Miller, linux-bluetooth
In-Reply-To: <BANLkTik7WyQ977-+8XapTgBrVRMyexyHKg@mail.gmail.com>
Hi Filip,
> Structures "l2cap_conninfo" and "rfcomm_conninfo" have one padding
> byte each. This byte in "cinfo" is copied to userspace uninitialized.
>
> patch no.1:
> -- cut --
> --- a/net/bluetooth/l2cap_sock.c 2011-05-04 03:59:13.000000000 +0100
> +++ b/net/bluetooth/l2cap_sock.c 2011-05-08 18:57:20.000000000 +0100
> @@ -446,6 +446,7 @@ static int l2cap_sock_getsockopt_old(str
> break;
> }
>
> + memset(&cinfo, 0, sizeof(cinfo));
> cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
> memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
nice catch, but please create a patch via git format-patch and don't
forget a Signed-off-by line.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 09/12] Bluetooth: Add hci_le_conn_add()
From: Marcel Holtmann @ 2011-05-12 1:27 UTC (permalink / raw)
To: Andre Guedes; +Cc: linux-bluetooth
In-Reply-To: <1304701521-26459-10-git-send-email-andre.guedes@openbossa.org>
Hi Andre,
> This patch implements a wrapper function to hci_conn_add() which
> takes the address type as argument. This patch also replaces
> hci_conn_add() calls by hci_le_conn_add() in LE related code.
>
> hci_le_conn_add() was created to consider the destination address
> type when creating a new LE hci_conn.
>
> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
> ---
> include/net/bluetooth/hci_core.h | 2 ++
> net/bluetooth/hci_conn.c | 14 +++++++++++++-
> net/bluetooth/hci_event.c | 5 +++--
> 3 files changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index 5e64d3f..6dd7cad 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -427,6 +427,8 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle);
> void hci_sco_setup(struct hci_conn *conn, __u8 status);
>
> struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
> +struct hci_conn *hci_le_conn_add(struct hci_dev *hdev, bdaddr_t *dst,
> + __u8 addr_type);
the reason why we never split hci_conn_add is too keep it simple. So
better just add the dst_type there directly and only use it when LE_LINK
or we split this clearly in SCO, ACL and LE links. This way is just
half-baked.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 03/12] Bluetooth: Protect 'adv_entries' with a RW lock
From: Marcel Holtmann @ 2011-05-12 1:24 UTC (permalink / raw)
To: Andre Guedes; +Cc: linux-bluetooth
In-Reply-To: <1304701521-26459-4-git-send-email-andre.guedes@openbossa.org>
Hi Andre,
> This patch adds a RW lock to protect concurrent operations on
> adv_entries list.
>
> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
> ---
> include/net/bluetooth/hci_core.h | 1 +
> net/bluetooth/hci_core.c | 21 +++++++++++++++++----
> 2 files changed, 18 insertions(+), 4 deletions(-)
>
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index 65135f8..2ceeadf 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -188,6 +188,7 @@ struct hci_dev {
> struct list_head remote_oob_data;
>
> struct list_head adv_entries;
> + rwlock_t adv_entries_lock;
we might wanna consider just using spinlocks and not rwlocks. Also can
you please look into using RCU.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 00/12] Caching LE advertising information
From: Marcel Holtmann @ 2011-05-12 1:23 UTC (permalink / raw)
To: Andre Guedes; +Cc: linux-bluetooth
In-Reply-To: <1304701521-26459-1-git-send-email-andre.guedes@openbossa.org>
Hi Andre,
> This patchset implements the LE advertising cache which is used
> to establish LE connections.
>
> Today, we cannot establish LE connections (via l2cap socket) with
> devices which use random address type. To achieve that, we came up
> with a solution where the host should be able to infer the address
> type (public or random) from the device it wants to connect to.
>
> The approach this patchset implements is: during the LE scanning,
> the host stores the address and the address type gathered from
> advertising reports. These information are stored at the advertising
> cache. So, during a LE connection, the host looks up the advertising
> cache and gets the address type from the device it wants to connect
> to.
I would prefer if we try using the cache as long as possible. As long as
this works out it should be fine. Adding the BDADDR_TYPE to all public
socket address structures seems a bit of a pain to me.
And as backup we can always revert to that, but we can never ever remove
that address from the socket structure. While we can remove the cache if
we no longer need it.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH v2 02/13] Add Bluetooth address type definition
From: Marcel Holtmann @ 2011-05-12 1:20 UTC (permalink / raw)
To: Johan Hedberg; +Cc: Claudio Takahasi, linux-bluetooth
In-Reply-To: <20110504060357.GA3711@jh-x301>
Hi Johan,
> > Values defined to LE(public and random) are defined in the Bluetooth
> > Core Specification. For basic rate, there isn't address type concept.
> > The constants introduced by this commit will be used to identify the
> > remote address type, basically to distinguish LE/BR devices before
> > to request the L2CAP connection.
> > ---
> > lib/bluetooth.h | 4 ++++
> > 1 files changed, 4 insertions(+), 0 deletions(-)
> >
> > diff --git a/lib/bluetooth.h b/lib/bluetooth.h
> > index 738e07a..98b8f1c 100644
> > --- a/lib/bluetooth.h
> > +++ b/lib/bluetooth.h
> > @@ -130,6 +130,10 @@ typedef struct {
> > #define BDADDR_ALL (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}})
> > #define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
> >
> > +#define BDADDR_TYPE_LE_PUBLIC 0x00
> > +#define BRADDR_TYPE_LE_RANDOM 0x01
> > +#define BDADDR_TYPE_BR 0xff
>
> Firstly this still needs Marcel's blessing (though I don't really see
> any other solution than an address type with three possible values).
> Secondly, if this is ever going to be added to the L2CAP socket address
> you'd have to have 0x00 as BDADDR_TYPE_BR for backwards compatibility.
I am still not 100% convinced, but yes, the default 0x00 then needs to
be BDADDR_TYPE_BREDR. Otherwise we break APIs.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] bluetooth: fix shutdown on SCO sockets
From: Gustavo F. Padovan @ 2011-05-11 20:52 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <BANLkTimatFYD2Jn1o0DqxKpv+RRC6+3uSg@mail.gmail.com>
Hi Luiz,
* Luiz Augusto von Dentz <luiz.dentz@gmail.com> [2011-05-11 23:49:51 +0300]:
> Hi Gustavo,
>
> On Wed, May 11, 2011 at 8:09 PM, Gustavo F. Padovan
> <padovan@profusion.mobi> wrote:
> > Hi Luiz,
> >
> > * Luiz Augusto von Dentz <luiz.dentz@gmail.com> [2011-05-05 17:50:53 +0300]:
> >
> >> Hi Gustavo,
> >>
> >> On Mon, Apr 18, 2011 at 8:56 PM, Gustavo F. Padovan
> >> <padovan@profusion.mobi> wrote:
> >> > * Luiz Augusto von Dentz <luiz.dentz@gmail.com> [2011-04-17 20:26:53 +0300]:
> >> >
> >> >> Hi Gustavo,
> >> >>
> >> >> On Fri, Apr 15, 2011 at 9:58 PM, Gustavo F. Padovan
> >> >> <padovan@profusion.mobi> wrote:
> >> >> > Hi Luiz,
> >> >> >
> >> >> > * Luiz Augusto von Dentz <luiz.dentz@gmail.com> [2011-04-08 17:10:41 +0300]:
> >> >> >
> >> >> >> From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
> >> >> >>
> >> >> >> shutdown should wait for SCO link to be properly disconnected before
> >> >> >> detroying the socket, otherwise an application using the socket may
> >> >> >> assume link is properly disconnected before it really happens which
> >> >> >> can be a problem when e.g synchronizing profile switch.
> >> >> >>
> >> >> >> Signed-off-by: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
> >> >> >
> >> >> > I applied it, but in bluetooth-next. Let's see its behaviour there and if no
> >> >> > problems show up we can move it to bluetooth-2.6
> >> >>
> >> >> I tested this against Nokia BH-504 and Sony Ericsson W600, both have
> >> >> problem when switching from hfp to a2dp where the avdtp start is sent
> >> >> before SCO is fully disconnected, this patch fixes with those
> >> >> headsets.
> >> >
> >> > Ok, I also pushed it to bluetooth-2.6.
> >>
> >>
> >> Apparently this cause a regression, since we set conn to NULL but an
> >> application may not wait for shutdown to complete and call
> >> close/release which will cause sco_chan_del to be called which destroy
> >> the socket without resetting conn->sk to NULL so on disconn_cfm it
> >> will access invalid memory.
> >>
> >> To fix this what about the following:
> >>
> >> diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
> >> index 94954c7..cb4fb78 100644
> >> --- a/net/bluetooth/sco.c
> >> +++ b/net/bluetooth/sco.c
> >> @@ -373,7 +373,7 @@ static void __sco_sock_close(struct sock *sk)
> >> sk->sk_state = BT_DISCONN;
> >> sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT);
> >> hci_conn_put(sco_pi(sk)->conn->hcon);
> >> - sco_pi(sk)->conn = NULL;
> >> + sco_pi(sk)->conn->hcon = NULL;
> >> } else
> >> sco_chan_del(sk, ECONNRESET);
> >> break;
> >> @@ -828,7 +828,9 @@ static void sco_chan_del(struct sock *sk, int err)
> >> conn->sk = NULL;
> >> sco_pi(sk)->conn = NULL;
> >> sco_conn_unlock(conn);
> >> - hci_conn_put(conn->hcon);
> >> +
> >> + if (conn->hcon)
> >> + hci_conn_put(conn->hcon);
> >
> > I think first we need to revert the patch on linus' tree. There isn't time to
> > a proper fix and test. It may have introduced other bugs too. I don't wanna
> > take this risk.
>
> Ville and I tested the suggested changes and see no regression
> anymore, so I can either create a new patch or update the other in
> case we revert it.
So update the patch and resend, I already asked Linus to revert it.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH] bluetooth: fix shutdown on SCO sockets
From: Luiz Augusto von Dentz @ 2011-05-11 20:49 UTC (permalink / raw)
To: Luiz Augusto von Dentz, linux-bluetooth
In-Reply-To: <20110511170951.GB22065@joana>
Hi Gustavo,
On Wed, May 11, 2011 at 8:09 PM, Gustavo F. Padovan
<padovan@profusion.mobi> wrote:
> Hi Luiz,
>
> * Luiz Augusto von Dentz <luiz.dentz@gmail.com> [2011-05-05 17:50:53 +0300]:
>
>> Hi Gustavo,
>>
>> On Mon, Apr 18, 2011 at 8:56 PM, Gustavo F. Padovan
>> <padovan@profusion.mobi> wrote:
>> > * Luiz Augusto von Dentz <luiz.dentz@gmail.com> [2011-04-17 20:26:53 +0300]:
>> >
>> >> Hi Gustavo,
>> >>
>> >> On Fri, Apr 15, 2011 at 9:58 PM, Gustavo F. Padovan
>> >> <padovan@profusion.mobi> wrote:
>> >> > Hi Luiz,
>> >> >
>> >> > * Luiz Augusto von Dentz <luiz.dentz@gmail.com> [2011-04-08 17:10:41 +0300]:
>> >> >
>> >> >> From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
>> >> >>
>> >> >> shutdown should wait for SCO link to be properly disconnected before
>> >> >> detroying the socket, otherwise an application using the socket may
>> >> >> assume link is properly disconnected before it really happens which
>> >> >> can be a problem when e.g synchronizing profile switch.
>> >> >>
>> >> >> Signed-off-by: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
>> >> >
>> >> > I applied it, but in bluetooth-next. Let's see its behaviour there and if no
>> >> > problems show up we can move it to bluetooth-2.6
>> >>
>> >> I tested this against Nokia BH-504 and Sony Ericsson W600, both have
>> >> problem when switching from hfp to a2dp where the avdtp start is sent
>> >> before SCO is fully disconnected, this patch fixes with those
>> >> headsets.
>> >
>> > Ok, I also pushed it to bluetooth-2.6.
>>
>>
>> Apparently this cause a regression, since we set conn to NULL but an
>> application may not wait for shutdown to complete and call
>> close/release which will cause sco_chan_del to be called which destroy
>> the socket without resetting conn->sk to NULL so on disconn_cfm it
>> will access invalid memory.
>>
>> To fix this what about the following:
>>
>> diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
>> index 94954c7..cb4fb78 100644
>> --- a/net/bluetooth/sco.c
>> +++ b/net/bluetooth/sco.c
>> @@ -373,7 +373,7 @@ static void __sco_sock_close(struct sock *sk)
>> sk->sk_state = BT_DISCONN;
>> sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT);
>> hci_conn_put(sco_pi(sk)->conn->hcon);
>> - sco_pi(sk)->conn = NULL;
>> + sco_pi(sk)->conn->hcon = NULL;
>> } else
>> sco_chan_del(sk, ECONNRESET);
>> break;
>> @@ -828,7 +828,9 @@ static void sco_chan_del(struct sock *sk, int err)
>> conn->sk = NULL;
>> sco_pi(sk)->conn = NULL;
>> sco_conn_unlock(conn);
>> - hci_conn_put(conn->hcon);
>> +
>> + if (conn->hcon)
>> + hci_conn_put(conn->hcon);
>
> I think first we need to revert the patch on linus' tree. There isn't time to
> a proper fix and test. It may have introduced other bugs too. I don't wanna
> take this risk.
Ville and I tested the suggested changes and see no regression
anymore, so I can either create a new patch or update the other in
case we revert it.
--
Luiz Augusto von Dentz
Computer Engineer
^ permalink raw reply
* Revert "Bluetooth: fix shutdown on SCO sockets"
From: Gustavo F. Padovan @ 2011-05-11 20:05 UTC (permalink / raw)
To: torvalds; +Cc: linux-bluetooth, linux-kernel, davem, linville
Hi Linus,
Commit f21ca5fff6e548833fa5ee8867239a8378623150 can cause a NULL dereference
if we call shutdown in a bluetooth SCO socket and doesn't wait the shutdown
completion to call close(). Please revert it. I may have a fix for it soon,
but we don't have time anymore, so revert is the way to go. ;)
Regards,
commit f21ca5fff6e548833fa5ee8867239a8378623150
Author: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
Date: Fri Apr 8 17:10:41 2011 +0300
Bluetooth: fix shutdown on SCO sockets
shutdown should wait for SCO link to be properly disconnected before
detroying the socket, otherwise an application using the socket may
assume link is properly disconnected before it really happens which
can be a problem when e.g synchronizing profile switch.
Signed-off-by: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH 2/2] Bluetooth: Add support for disconnecting LE links via mgmt
From: Gustavo F. Padovan @ 2011-05-11 19:42 UTC (permalink / raw)
To: Vinicius Costa Gomes; +Cc: linux-bluetooth
In-Reply-To: <1304718104-6448-2-git-send-email-vinicius.gomes@openbossa.org>
Hi Vinicius,
* Vinicius Costa Gomes <vinicius.gomes@openbossa.org> [2011-05-06 18:41:44 -0300]:
> If we can't find a ACL link between the devices, we search
> the connection list one second time looking for LE links.
Both patches have been applied. Thanks.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH v2] Bluetooth: Double check sec req for pre 2.1 device
From: Gustavo F. Padovan @ 2011-05-11 18:01 UTC (permalink / raw)
To: Waldemar Rymarkiewicz; +Cc: linux-bluetooth
In-Reply-To: <1304667751-21670-1-git-send-email-waldemar.rymarkiewicz@tieto.com>
Hi Waldemar,
* Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> [2011-05-06 09:42:31 +0200]:
> In case of pre v2.1 devices authentication request will return
> success immediately if the link key already exists without any
> authentication process.
>
> That means, it's not possible to re-authenticate the link if you
> already have combination key and for instance want to re-authenticate
> to get the high security (use 16 digit pin).
>
> Therefore, it's necessary to check security requirements on auth
> complete event to prevent not enough secure connection.
>
> Signed-off-by: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
> ---
> include/net/bluetooth/hci_core.h | 1 +
> net/bluetooth/hci_conn.c | 17 +++++++++++++++++
> net/bluetooth/rfcomm/core.c | 2 +-
> 3 files changed, 19 insertions(+), 1 deletions(-)
Patch has been applied. Thanks.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH v2] Bluetooth: Allow unsegmented SDU retries on sock_queue_rcv_skb failure.
From: Gustavo F. Padovan @ 2011-05-11 17:55 UTC (permalink / raw)
To: Ruiyi Zhang; +Cc: linux-bluetooth
In-Reply-To: <1304657051-26453-1-git-send-email-Ruiyi.zhang@atheros.com>
Hi Ruiyi,
* Ruiyi Zhang <Ruiyi.zhang@atheros.com> [2011-05-06 12:44:11 +0800]:
> In L2CAP_SDU_UNSEGMENTED case, if sock_queue_rcv_skb returns error,
> l2cap_ertm_reassembly_sdu should not return 0 so as to insert the
> skb into BUSY_QUEUE for later retries.
>
> Signed-off-by: Ruiyi Zhang <Ruiyi.zhang@atheros.com>
> ---
> net/bluetooth/l2cap_core.c | 6 +-----
> 1 files changed, 1 insertions(+), 5 deletions(-)
Patch has not applied upstream. Please rebase onto bluetooth-next. Thanks.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH] btusb: Device ids for ath3k on Pegatron Lucid tablets
From: Gustavo F. Padovan @ 2011-05-11 17:52 UTC (permalink / raw)
To: Andy Ross; +Cc: Marcel Holtmann, linux-bluetooth
In-Reply-To: <4DC87494.4070203@windriver.com>
Hi Andy,
* Andy Ross <andy.ross@windriver.com> [2011-05-09 16:11:16 -0700]:
> MeeGo has been carrying this patch for a while, and I'd forgotten
> about it until it accidentally got dropped. I think I remember
> finding the IDs on a mailing list, but as of now they're still
> unmerged and I can't find the original source. Device IDs for ath3k
> bluetooth on the WeTab/ExoPC.
>
> Andy
>
> From ff4a4cdbbb847901bd5e64e2510f2c0cda11497b Mon Sep 17 00:00:00 2001
> From: Andy Ross <andy.ross@windriver.com>
> Date: Mon, 9 May 2011 15:59:49 -0700
> Subject: [PATCH] btusb: Device ids for ath3k on Pegatron Lucid tablets
>
> New ath3k device IDs used on the Pegatron Lucid (ExoPC and WeTab) units.
>
> Signed-off-by: Andy Ross <andy.ross@windriver.com>
> ---
> drivers/bluetooth/ath3k.c | 1 +
> drivers/bluetooth/btusb.c | 1 +
> 2 files changed, 2 insertions(+), 0 deletions(-)
Applied, thanks.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH] Bluetooth: Fix possible NULL pointer derefence in l2cap code
From: Gustavo F. Padovan @ 2011-05-11 17:37 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth, par-gunnar.p.hjalmdahl
In-Reply-To: <1305119698-22888-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
* Szymon Janc <szymon.janc@tieto.com> [2011-05-11 15:14:58 +0200]:
> Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
> ---
> net/bluetooth/l2cap_core.c | 5 +++++
> 1 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index d0769a8..d9833d1 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -3292,6 +3292,11 @@ static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq)
> l2cap_send_sframe(chan, control);
>
> new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
> + if (!new) {
> + BT_ERR("Memory allocation failed on tx_seq = %d",
> + chan->expected_tx_seq);
> + break;
I think a proper behavior here is disconnect the channel. The Enhanced
Retransmission mode is reliable and we have to guarantee that all data is
delivered. Skip adding to the list doesn't seem to be safe here.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH] bluetooth: fix shutdown on SCO sockets
From: Gustavo F. Padovan @ 2011-05-11 17:09 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <BANLkTikgZBh5SyXJvFE6z+F2V-JxC5Y9YQ@mail.gmail.com>
Hi Luiz,
* Luiz Augusto von Dentz <luiz.dentz@gmail.com> [2011-05-05 17:50:53 +0300]:
> Hi Gustavo,
>
> On Mon, Apr 18, 2011 at 8:56 PM, Gustavo F. Padovan
> <padovan@profusion.mobi> wrote:
> > * Luiz Augusto von Dentz <luiz.dentz@gmail.com> [2011-04-17 20:26:53 +0300]:
> >
> >> Hi Gustavo,
> >>
> >> On Fri, Apr 15, 2011 at 9:58 PM, Gustavo F. Padovan
> >> <padovan@profusion.mobi> wrote:
> >> > Hi Luiz,
> >> >
> >> > * Luiz Augusto von Dentz <luiz.dentz@gmail.com> [2011-04-08 17:10:41 +0300]:
> >> >
> >> >> From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
> >> >>
> >> >> shutdown should wait for SCO link to be properly disconnected before
> >> >> detroying the socket, otherwise an application using the socket may
> >> >> assume link is properly disconnected before it really happens which
> >> >> can be a problem when e.g synchronizing profile switch.
> >> >>
> >> >> Signed-off-by: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
> >> >
> >> > I applied it, but in bluetooth-next. Let's see its behaviour there and if no
> >> > problems show up we can move it to bluetooth-2.6
> >>
> >> I tested this against Nokia BH-504 and Sony Ericsson W600, both have
> >> problem when switching from hfp to a2dp where the avdtp start is sent
> >> before SCO is fully disconnected, this patch fixes with those
> >> headsets.
> >
> > Ok, I also pushed it to bluetooth-2.6.
>
>
> Apparently this cause a regression, since we set conn to NULL but an
> application may not wait for shutdown to complete and call
> close/release which will cause sco_chan_del to be called which destroy
> the socket without resetting conn->sk to NULL so on disconn_cfm it
> will access invalid memory.
>
> To fix this what about the following:
>
> diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
> index 94954c7..cb4fb78 100644
> --- a/net/bluetooth/sco.c
> +++ b/net/bluetooth/sco.c
> @@ -373,7 +373,7 @@ static void __sco_sock_close(struct sock *sk)
> sk->sk_state = BT_DISCONN;
> sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT);
> hci_conn_put(sco_pi(sk)->conn->hcon);
> - sco_pi(sk)->conn = NULL;
> + sco_pi(sk)->conn->hcon = NULL;
> } else
> sco_chan_del(sk, ECONNRESET);
> break;
> @@ -828,7 +828,9 @@ static void sco_chan_del(struct sock *sk, int err)
> conn->sk = NULL;
> sco_pi(sk)->conn = NULL;
> sco_conn_unlock(conn);
> - hci_conn_put(conn->hcon);
> +
> + if (conn->hcon)
> + hci_conn_put(conn->hcon);
I think first we need to revert the patch on linus' tree. There isn't time to
a proper fix and test. It may have introduced other bugs too. I don't wanna
take this risk.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox