* Re: [PATCH] Provide extra query for vCard single call
From: Johan Hedberg @ 2010-10-25 16:26 UTC (permalink / raw)
To: Rafal Michalski; +Cc: linux-bluetooth
In-Reply-To: <1287997498-2576-1-git-send-email-michalski.raf@gmail.com>
Hi Rafal,
On Mon, Oct 25, 2010, Rafal Michalski wrote:
> This patch makes that additional circumstance is recognized - after
> making a call with number that is out of phonebook it can be downloaded
> as a single vCard containing number with OTHER type.
> ---
> plugins/phonebook-tracker.c | 20 ++++++++++++++++++--
> 1 files changed, 18 insertions(+), 2 deletions(-)
Pushed upstream, but I had to fix your coding style first:
> - query = g_strdup_printf(CONTACTS_QUERY_FROM_URI, id, id, id, id, id,
> - id, id, id, id, id, id, id,
> + if (strncmp(id, CONTACT_ID_PREFIX, strlen(CONTACT_ID_PREFIX)) == 0) {
> + query = g_strdup_printf(CONTACTS_QUERY_FROM_URI, id, id, id, id,
> + id, id, id, id, id, id, id, id,
> id, id, id, id, id);
> + } else {
> + query = g_strdup_printf(CONTACTS_OTHER_QUERY_FROM_URI,
> + id, id, id);
> + }
>
> ret = query_tracker(query, PULL_QUERY_COL_AMOUNT, pull_contacts, data);
Single line branches shouldn't use curly braces.
Johan
^ permalink raw reply
* Re: [PATCH 1/1] Fix fd comparison and comment
From: Johan Hedberg @ 2010-10-25 16:22 UTC (permalink / raw)
To: Elvis Pfützenreuter; +Cc: linux-bluetooth
In-Reply-To: <1288013352-23258-1-git-send-email-epx@signove.com>
Hi Elvis,
On Mon, Oct 25, 2010, Elvis Pfützenreuter wrote:
> ---
> health/hdp.c | 6 +++---
> health/mcap_sync.c | 2 +-
> 2 files changed, 4 insertions(+), 4 deletions(-)
Please don't mix coding style cleanup and real bug fixes into a single
patch. I.e. could you please split these up. Thanks.
Johan
^ permalink raw reply
* [PATCH] Send a proper configuration when a source doesn't have a first reliable
From: Santiago Carot-Nemesio @ 2010-10-25 13:43 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Santiago Carot-Nemesio
---
health/hdp.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/health/hdp.c b/health/hdp.c
index fd3b1ca..10f4c5f 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -1026,7 +1026,7 @@ static uint8_t hdp_mcap_mdl_conn_req_cb(struct mcap_mcl *mcl, uint8_t mdepid,
case HDP_NO_PREFERENCE_DC:
if (app->role == HDP_SINK)
return MCAP_CONFIGURATION_REJECTED;
- else if (app->chan_type_set)
+ else if (dev->fr && app->chan_type_set)
*conf = app->chan_type;
else
*conf = HDP_RELIABLE_DC;
--
1.7.3.1
^ permalink raw reply related
* Re: [RFC] LE connections and advertising management
From: Anderson Lizardo @ 2010-10-25 13:34 UTC (permalink / raw)
To: Claudio Takahasi; +Cc: BlueZ development
In-Reply-To: <AANLkTin8pUACCu4YYuhLpFB7DxCfsYhN3cOpYYaVcTQ6@mail.gmail.com>
On Mon, Oct 25, 2010 at 8:53 AM, Claudio Takahasi
<claudio.takahasi@openbossa.org> wrote:
> 4. Kernel manages the connection establishment, currently there isn't
> a way to change the connection parameters. BMI or ioctls will be
> required to change the default parameters and also to trigger SMP
> negotiation.
Another idea would be to use setsockopt(), like it's currently being
used for HCI filters (see lib/hci.c). E.g.:
hci_filter_clear(&nf);
hci_filter_set_ptype(HCI_EVENT_PKT, &nf);
hci_filter_set_event(EVT_LE_META_EVENT, &nf);
setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf);
Not sure if the SMP negotiation happens too soon to use it though.
Regards,
--
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil
^ permalink raw reply
* [PATCH 1/1] Fix fd comparison and comment
From: Elvis Pfützenreuter @ 2010-10-25 13:29 UTC (permalink / raw)
To: linux-bluetooth; +Cc: epx
---
health/hdp.c | 6 +++---
health/mcap_sync.c | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/health/hdp.c b/health/hdp.c
index fd3b1ca..7332cd5 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -339,7 +339,7 @@ static DBusMessage *manager_create_application(DBusConnection *conn,
"Can't get sender name");
}
- if (!set_app_path(app)){
+ if (!set_app_path(app)) {
free_application(app);
return g_dbus_create_error(msg,
ERROR_INTERFACE ".HealthError",
@@ -477,7 +477,7 @@ static void hdp_mdl_reconn_cb(struct mcap_mdl *mdl, GError *err, gpointer data)
}
fd = mcap_mdl_get_fd(dc_data->hdp_chann->mdl);
- if (fd <= 0)
+ if (fd < 0)
reply = g_dbus_create_error(dc_data->msg,
ERROR_INTERFACE ".HealthError",
"Cannot get file descriptor");
@@ -568,7 +568,7 @@ static DBusMessage *channel_acquire_continue(struct hdp_tmp_dc_data *data,
}
fd = mcap_mdl_get_fd(data->hdp_chann->mdl);
- if (fd > 0)
+ if (fd >= 0)
return g_dbus_create_reply(data->msg, DBUS_TYPE_UNIX_FD, &fd,
DBUS_TYPE_INVALID);
diff --git a/health/mcap_sync.c b/health/mcap_sync.c
index 49661a7..57ba0fd 100644
--- a/health/mcap_sync.c
+++ b/health/mcap_sync.c
@@ -350,7 +350,7 @@ static gboolean initialize_caps(struct mcap_mcl *mcl)
clock_gettime(CLK, &t1);
read_btclock_retry(mcl, &btclock, &btaccuracy);
- /* Do clock read a number of times and measure latency */
+ /* Read clock a number of times and measure latency */
avg = 0;
i = 0;
retries = MAX_RETRIES;
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH 3/6] Bluetooth: Implement the first SMP commands
From: Gustavo F. Padovan @ 2010-10-25 13:03 UTC (permalink / raw)
To: Anderson Briglia; +Cc: linux-bluetooth, Vinicius Costa Gomes
In-Reply-To: <1287791820-22693-4-git-send-email-anderson.briglia@openbossa.org>
Hi Vinicius,
* Anderson Briglia <anderson.briglia@openbossa.org> [2010-10-22 19:56:57 -0400]:
> From: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
>
> These simple commands will allow the SMP procedure to be started
> and terminated with a not supported error. This is the first step
> toward something useful.
>
> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
> ---
> net/bluetooth/l2cap.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 117 insertions(+), 0 deletions(-)
>
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index 1ac44f4..ba87c84 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -54,6 +54,7 @@
> #include <net/bluetooth/bluetooth.h>
> #include <net/bluetooth/hci_core.h>
> #include <net/bluetooth/l2cap.h>
> +#include <net/bluetooth/smp.h>
>
> #define VERSION "2.15"
>
> @@ -307,6 +308,85 @@ static void l2cap_chan_del(struct sock *sk, int err)
> }
> }
>
> +static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
> + u16 dlen, void *data)
Call this l2cap_smp_build_cmd()
> +{
> + struct sk_buff *skb;
> + struct l2cap_hdr *lh;
> + int len;
> +
> + len = L2CAP_HDR_SIZE + 1 + dlen;
> +
> + if (len > conn->mtu)
> + return NULL;
> +
> + skb = bt_skb_alloc(len, GFP_ATOMIC);
> + if (!skb)
> + return NULL;
> +
> + lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
> + lh->len = cpu_to_le16(1 + dlen);
cpu_to_le16(len - L2CAP_HDR_SIZE) here
> + lh->cid = cpu_to_le16(L2CAP_CID_SMP);
> +
> + memcpy(skb_put(skb, 1), &code, 1);
> +
> + memcpy(skb_put(skb, dlen), data, dlen);
> +
> + return skb;
> +}
> +
> +static inline void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
and this l2cap_smp_send_cmd.
> +{
> + struct sk_buff *skb = smp_build_cmd(conn, code, len, data);
> +
> + BT_DBG("code 0x%2.2x", code);
> +
> + if (!skb)
> + return;
> +
> + hci_send_acl(conn->hcon, skb, 0);
> +}
> +
> +static int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
> +{
l2cap_smp_conn_security() here.
> + __u8 authreq;
> +
> + BT_DBG("conn %p hcon %p level 0x%2.2x", conn, conn->hcon, sec_level);
> +
> + switch (sec_level) {
> + case BT_SECURITY_MEDIUM:
> + /* Encrypted, no MITM protection */
> + authreq = 0x01;
> + break;
> +
> + case BT_SECURITY_HIGH:
> + /* Bonding, MITM protection */
> + authreq = 0x05;
> + break;
> +
> + case BT_SECURITY_LOW:
> + default:
> + return 1;
> + }
> +
> + if (conn->hcon->link_mode & HCI_LM_MASTER) {
> + struct smp_cmd_pairing cp;
> + cp.io_capability = 0x00;
> + cp.oob_flag = 0x00;
> + cp.max_key_size = 16;
> + cp.init_key_dist = 0x00;
> + cp.resp_key_dist = 0x00;
> + cp.auth_req = authreq;
> + smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
> + } else {
> + struct smp_cmd_security_req cp;
> + cp.auth_req = authreq;
> + smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
> + }
> +
> + return 0;
> +}
> +
> /* Service level security */
> static inline int l2cap_check_security(struct sock *sk)
> {
> @@ -4562,6 +4642,43 @@ done:
> return 0;
> }
>
> +static inline void smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
l2cap_smp_sig_channel()
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* [RFC] LE connections and advertising management
From: Claudio Takahasi @ 2010-10-25 12:53 UTC (permalink / raw)
To: BlueZ development
Hi all,
Interleave BR/EDR/LE discovery is implemented, the next step in the
user space is how to manage advertising and LE connections.
Some aspects:
1. Only one LE connection is allowed(per peer), meaning only one
GAttrib instance will be allowed otherwise it will not be possible to
serialize commands/events
2. The remote/Peripheral can support more than one GATT primary service
3. We are planning to use "direct" connections only, meaning that we
will not use whitelist and the application interested must inform the
remote address/object to connect to.
4. Kernel manages the connection establishment, currently there isn't
a way to change the connection parameters. BMI or ioctls will be
required to change the default parameters and also to trigger SMP
negotiation.
Some ideas:
1. implement a characteristic driver: basically to provide an
abstraction to GATT clients. ex: Proximity, Health, ...
2. We don't need to implement Proximity and other GATT clients as a
plugin at the moment, it can be enabled automatically by
--enable-attrib
3. GATT clients could register a watcher/filter for advertising events
4. GATT clients doesn't need to know ATT, in theory it can handle
characteristics only
5. GATT clients needs to control/request LE connections based on the
advertisement received
An initial draft implementing part of this idea is here:
git://git.infradead.org/users/cktakahasi/bluez.git devel
Comments?
Regards,
Claudio
^ permalink raw reply
* Re: [PATCH] bluetooth: Fix NULL pointer dereference issue
From: Yuri Ershov @ 2010-10-25 12:23 UTC (permalink / raw)
To: ext Gustavo F. Padovan
Cc: marcel, davem, jprvita, linux-bluetooth, ville.tervo,
andrei.emeltchenko
In-Reply-To: <20101022135859.GA15476@vigoh>
[-- Attachment #1: Type: text/plain, Size: 1732 bytes --]
Hello Gustavo,
The problem appears in case of multiple connect-transfer-disconnect
sequence (e.g. by using l2test). The conditions are the following:
There are 2 BT devices. The first one listens and receives (l2test -r),
the second one makes "connect-disconnect-connect..." sequence (l2test -c
-b 1000 -i hci0 -P 10 <addr>). After some time this will cause the race
between functions bt_accept_dequeue and l2cap_chan_del. The fail sequence:
struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
{
...
list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
lock_sock(sk);
In this time the function l2cap_chan_del sets the socket state to
BT_CLOSED, unlinks and kills the socket.
/* FIXME: Is this check still needed */
if (sk->sk_state == BT_CLOSED) {
release_sock(sk);
bt_accept_unlink(sk);
continue;
}
...
release_sock(sk);
}
return NULL;
}
Regards,
Yuri
ext Gustavo F. Padovan wrote:
> Hi Yuri,
>
> * Yuri Ershov <ext-yuri.ershov@nokia.com> [2010-10-21 20:08:58 +0400]:
>
>
>> This patch fixes NULL pointer dereference at running test with
>> connect-transfer-disconnect in loop. Sometimes sk_state is
>> BT_CLOSED and sk_refcnt equal to 0, so there is oops in
>> bt_accept_unlink. In normal case removed block is not used.
>>
>
> Question here is: Why sk_refcnt is 0 at that point of the code? The
> socket should be destroyed if it ref is 0, but it wasn't, so something
> in another point of the code went is wrong. "Sometimes" is not a good
> description of the problem, you have to show why that happened.
>
>
[-- Attachment #2: Type: text/html, Size: 2746 bytes --]
^ permalink raw reply
* [PATCH 6/6] Bluetooth: Do not send disconn comand over LE links
From: Ville Tervo @ 2010-10-25 12:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ville Tervo
In-Reply-To: <1288009280-5149-1-git-send-email-ville.tervo@nokia.com>
l2cap over LE links can be disconnected without sending
disconnect command first.
Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
---
net/bluetooth/l2cap.c | 15 ++++++++++-----
1 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 3913ba5..2da613b 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -873,6 +873,8 @@ static void l2cap_sock_kill(struct sock *sk)
static void __l2cap_sock_close(struct sock *sk, int reason)
{
+ struct l2cap_conn *conn;
+
BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
switch (sk->sk_state) {
@@ -882,8 +884,10 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
case BT_CONNECTED:
case BT_CONFIG:
- if (sk->sk_type == SOCK_SEQPACKET ||
- sk->sk_type == SOCK_STREAM) {
+ conn = l2cap_pi(sk)->conn;
+ if ((sk->sk_type == SOCK_SEQPACKET ||
+ sk->sk_type == SOCK_STREAM) &&
+ conn->hcon->type != LE_LINK) {
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
@@ -893,9 +897,10 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
break;
case BT_CONNECT2:
- if (sk->sk_type == SOCK_SEQPACKET ||
- sk->sk_type == SOCK_STREAM) {
- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+ conn = l2cap_pi(sk)->conn;
+ if ((sk->sk_type == SOCK_SEQPACKET ||
+ sk->sk_type == SOCK_STREAM) &&
+ conn->hcon->type != LE_LINK) {
struct l2cap_conn_rsp rsp;
__u16 result;
--
1.7.1
^ permalink raw reply related
* [PATCH 5/6] Bluetooth: Add server socket support for LE connection
From: Ville Tervo @ 2010-10-25 12:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ville Tervo
In-Reply-To: <1288009280-5149-1-git-send-email-ville.tervo@nokia.com>
Add support for LE server sockets.
Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
---
include/net/bluetooth/l2cap.h | 1 +
net/bluetooth/hci_event.c | 10 +++-
net/bluetooth/l2cap.c | 101 +++++++++++++++++++++++++++++++++++++++--
3 files changed, 105 insertions(+), 7 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index cc3a140..cba4423 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -38,6 +38,7 @@
#define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */
#define L2CAP_DEFAULT_ACK_TO 200
#define L2CAP_LOCAL_BUSY_TRIES 12
+#define L2CAP_LE_DEFAULT_MTU 23
#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */
#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index da23502..464d0cc 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1914,8 +1914,14 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
- if (!conn)
- goto unlock;
+ if (!conn) {
+ conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
+ if (!conn) {
+ BT_ERR("No memory for new connection");
+ hci_dev_unlock(hdev);
+ return;
+ }
+ }
if (ev->status) {
hci_proto_connect_cfm(conn, ev->status);
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 18643af..3913ba5 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -82,6 +82,8 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
+static void l2cap_le_conn_ready(struct l2cap_conn *conn);
+
/* ---- L2CAP timers ---- */
static void l2cap_sock_timeout(unsigned long arg)
{
@@ -228,8 +230,16 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so
l2cap_pi(sk)->conn = conn;
if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) {
- /* Alloc CID for connection-oriented socket */
- l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
+ if (conn->hcon->type == LE_LINK) {
+ /* LE connection */
+ l2cap_pi(sk)->omtu = L2CAP_LE_DEFAULT_MTU;
+ l2cap_pi(sk)->scid = L2CAP_CID_LE_DATA;
+ l2cap_pi(sk)->dcid = L2CAP_CID_LE_DATA;
+ } else {
+ /* Alloc CID for connection-oriented socket */
+ l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
+ l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
+ }
} else if (sk->sk_type == SOCK_DGRAM) {
/* Connectionless socket */
l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
@@ -612,6 +622,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
BT_DBG("conn %p", conn);
+ if (!conn->hcon->out && conn->hcon->type == LE_LINK)
+ l2cap_le_conn_ready(conn);
+
read_lock(&l->lock);
for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
@@ -694,7 +707,8 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
spin_lock_init(&conn->lock);
rwlock_init(&conn->chan_list.lock);
- setup_timer(&conn->info_timer, l2cap_info_timeout,
+ if (hcon->type != LE_LINK)
+ setup_timer(&conn->info_timer, l2cap_info_timeout,
(unsigned long) conn);
conn->disc_reason = 0x13;
@@ -796,6 +810,37 @@ static void l2cap_sock_destruct(struct sock *sk)
skb_queue_purge(&sk->sk_write_queue);
}
+static inline struct sock *l2cap_get_sock_by_cid(int state, __le16 cid, bdaddr_t *src)
+{
+ struct sock *s;
+ struct sock *sk = NULL, *sk1 = NULL;
+ struct hlist_node *node;
+
+ read_lock(&l2cap_sk_list.lock);
+ sk_for_each(sk, node, &l2cap_sk_list.head) {
+ if (state && sk->sk_state != state)
+ continue;
+
+ if (l2cap_pi(sk)->dcid == cid) {
+ /* Exact match. */
+ if (!bacmp(&bt_sk(sk)->src, src))
+ break;
+
+ /* Closest match */
+ if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
+ sk1 = sk;
+ }
+ }
+
+ s = node ? sk : sk1;
+
+ if (s)
+ bh_lock_sock(s);
+ read_unlock(&l2cap_sk_list.lock);
+
+ return s;
+}
+
static void l2cap_sock_cleanup_listen(struct sock *parent)
{
struct sock *sk;
@@ -1008,7 +1053,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
len = min_t(unsigned int, sizeof(la), alen);
memcpy(&la, addr, len);
- if (la.l2_cid)
+ if (la.l2_cid && la.l2_psm)
return -EINVAL;
lock_sock(sk);
@@ -1050,6 +1095,9 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
}
+ if (la.l2_cid)
+ l2cap_pi(sk)->dcid = la.l2_cid;
+
write_unlock_bh(&l2cap_sk_list.lock);
done:
@@ -1267,7 +1315,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
goto done;
}
- if (!l2cap_pi(sk)->psm) {
+ if (!l2cap_pi(sk)->psm && !l2cap_pi(sk)->dcid) {
bdaddr_t *src = &bt_sk(sk)->src;
u16 psm;
@@ -1377,6 +1425,49 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
return 0;
}
+static void l2cap_le_conn_ready(struct l2cap_conn *conn)
+{
+ struct l2cap_chan_list *list = &conn->chan_list;
+ struct sock *parent, *uninitialized_var(sk);
+
+ BT_DBG("");
+
+ /* Check if we have socket listening on cid */
+ parent = l2cap_get_sock_by_cid(BT_LISTEN, 0x04, conn->src);
+ if (!parent)
+ goto clean;
+
+ /* Check for backlog size */
+ if (sk_acceptq_is_full(parent)) {
+ BT_DBG("backlog full %d", parent->sk_ack_backlog);
+ goto clean;
+ }
+
+ sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC);
+ if (!sk)
+ goto clean;
+
+ write_lock_bh(&list->lock);
+
+ hci_conn_hold(conn->hcon);
+
+ l2cap_sock_init(sk, parent);
+ bacpy(&bt_sk(sk)->src, conn->src);
+ bacpy(&bt_sk(sk)->dst, conn->dst);
+
+ __l2cap_chan_add(conn, sk, parent);
+
+ l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
+
+ sk->sk_state = BT_CONNECTED;
+ parent->sk_data_ready(parent, 0);
+
+ write_unlock_bh(&list->lock);
+
+clean:
+ bh_unlock_sock(parent);
+}
+
static int __l2cap_wait_ack(struct sock *sk)
{
DECLARE_WAITQUEUE(wait, current);
--
1.7.1
^ permalink raw reply related
* [PATCH 4/6] Bluetooth: Add LE connection support to L2CAP
From: Ville Tervo @ 2010-10-25 12:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ville Tervo
In-Reply-To: <1288009280-5149-1-git-send-email-ville.tervo@nokia.com>
Add basic LE connection support to L2CAP. LE
connection can be created by specifying cid
in struct sockaddr_l2
Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
---
include/net/bluetooth/l2cap.h | 3 +++
net/bluetooth/l2cap.c | 32 ++++++++++++++++++++++++--------
2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index c819c8b..cc3a140 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -160,6 +160,9 @@ struct l2cap_conn_rsp {
/* channel indentifier */
#define L2CAP_CID_SIGNALING 0x0001
#define L2CAP_CID_CONN_LESS 0x0002
+#define L2CAP_CID_LE_DATA 0x0004
+#define L2CAP_CID_LE_SIGNALING 0x0005
+#define L2CAP_CID_SMP 0x0006
#define L2CAP_CID_DYN_START 0x0040
#define L2CAP_CID_DYN_END 0xffff
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 6f931cc..18643af 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -617,6 +617,12 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
bh_lock_sock(sk);
+ if (conn->hcon->type == LE_LINK) {
+ l2cap_sock_clear_timer(sk);
+ sk->sk_state = BT_CONNECTED;
+ sk->sk_state_change(sk);
+ }
+
if (sk->sk_type != SOCK_SEQPACKET &&
sk->sk_type != SOCK_STREAM) {
l2cap_sock_clear_timer(sk);
@@ -675,7 +681,11 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
BT_DBG("hcon %p conn %p", hcon, conn);
- conn->mtu = hcon->hdev->acl_mtu;
+ if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
+ conn->mtu = hcon->hdev->le_mtu;
+ else
+ conn->mtu = hcon->hdev->acl_mtu;
+
conn->src = &hcon->hdev->bdaddr;
conn->dst = &hcon->dst;
@@ -1102,8 +1112,13 @@ static int l2cap_do_connect(struct sock *sk)
}
}
- hcon = hci_connect(hdev, ACL_LINK, dst,
+ if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA)
+ hcon = hci_connect(hdev, LE_LINK, dst,
+ l2cap_pi(sk)->sec_level, auth_type);
+ else
+ hcon = hci_connect(hdev, ACL_LINK, dst,
l2cap_pi(sk)->sec_level, auth_type);
+
if (!hcon)
goto done;
@@ -1154,13 +1169,13 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
len = min_t(unsigned int, sizeof(la), alen);
memcpy(&la, addr, len);
- if (la.l2_cid)
+ if (la.l2_cid && la.l2_psm)
return -EINVAL;
lock_sock(sk);
if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM)
- && !la.l2_psm) {
+ && !(la.l2_psm || la.l2_cid)) {
err = -EINVAL;
goto done;
}
@@ -1202,14 +1217,15 @@ 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) {
+ sk->sk_type != SOCK_RAW && !la.l2_cid) {
err = -EINVAL;
goto done;
}
- /* Set destination address and psm */
+ /* Set destination address and psm or cid */
bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
l2cap_pi(sk)->psm = la.l2_psm;
+ l2cap_pi(sk)->dcid = la.l2_cid;
err = l2cap_do_connect(sk);
if (err)
@@ -4525,7 +4541,7 @@ static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
- if (hcon->type != ACL_LINK)
+ if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
return -EINVAL;
if (!status) {
@@ -4554,7 +4570,7 @@ static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
{
BT_DBG("hcon %p reason %d", hcon, reason);
- if (hcon->type != ACL_LINK)
+ if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK))
return -EINVAL;
l2cap_conn_del(hcon, bt_err(reason));
--
1.7.1
^ permalink raw reply related
* [PATCH 3/6] Bluetooth: Use LE buffers for LE traffic
From: Ville Tervo @ 2010-10-25 12:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ville Tervo
In-Reply-To: <1288009280-5149-1-git-send-email-ville.tervo@nokia.com>
BLuetooth chips may have separate buffers for
LE traffic. This patch add support to use LE
buffers provided by the chip.
Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
---
include/net/bluetooth/hci.h | 1 +
include/net/bluetooth/hci_core.h | 5 +++
net/bluetooth/hci_conn.c | 5 +++
net/bluetooth/hci_core.c | 74 +++++++++++++++++++++++++++++++++++--
net/bluetooth/hci_event.c | 40 +++++++++++++++++++-
5 files changed, 119 insertions(+), 6 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 02055b9..2103731 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -189,6 +189,7 @@ enum {
#define LMP_EV4 0x01
#define LMP_EV5 0x02
+#define LMP_LE 0x40
#define LMP_SNIFF_SUBR 0x02
#define LMP_EDR_ESCO_2M 0x20
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 2b7f94a..e2d857a 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -103,15 +103,19 @@ struct hci_dev {
atomic_t cmd_cnt;
unsigned int acl_cnt;
unsigned int sco_cnt;
+ unsigned int le_cnt;
unsigned int acl_mtu;
unsigned int sco_mtu;
+ unsigned int le_mtu;
unsigned int acl_pkts;
unsigned int sco_pkts;
+ unsigned int le_pkts;
unsigned long cmd_last_tx;
unsigned long acl_last_tx;
unsigned long sco_last_tx;
+ unsigned long le_last_tx;
struct workqueue_struct *workqueue;
@@ -473,6 +477,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO)
#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
+#define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE)
/* ----- HCI protocols ----- */
struct hci_proto {
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 0944c0c..ddc2e5e 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -324,6 +324,11 @@ int hci_conn_del(struct hci_conn *conn)
/* Unacked frames */
hdev->acl_cnt += conn->sent;
+ } else if (conn->type == LE_LINK) {
+ if (hdev->le_pkts)
+ hdev->le_cnt += conn->sent;
+ else
+ hdev->acl_cnt += conn->sent;
} else {
struct hci_conn *acl = conn->link;
if (acl) {
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index bc2a052..45c78c2 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -254,6 +254,14 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m);
}
+static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
+{
+ BT_DBG("%s", hdev->name);
+
+ /* Read LE buffer size */
+ hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
+}
+
static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
{
__u8 scan = opt;
@@ -509,6 +517,10 @@ int hci_dev_open(__u16 dev)
ret = __hci_request(hdev, hci_init_req, 0,
msecs_to_jiffies(HCI_INIT_TIMEOUT));
+ if (lmp_le_capable(hdev))
+ ret = __hci_request(hdev, hci_le_init_req, 0,
+ msecs_to_jiffies(HCI_INIT_TIMEOUT));
+
clear_bit(HCI_INIT, &hdev->flags);
}
@@ -645,7 +657,7 @@ int hci_dev_reset(__u16 dev)
hdev->flush(hdev);
atomic_set(&hdev->cmd_cnt, 1);
- hdev->acl_cnt = 0; hdev->sco_cnt = 0;
+ hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
if (!test_bit(HCI_RAW, &hdev->flags))
ret = __hci_request(hdev, hci_reset_req, 0,
@@ -1456,8 +1468,25 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
}
if (conn) {
- int cnt = (type == ACL_LINK ? hdev->acl_cnt : hdev->sco_cnt);
- int q = cnt / num;
+ int cnt, q;
+
+ switch (conn->type) {
+ case ACL_LINK:
+ cnt = hdev->acl_cnt;
+ break;
+ case SCO_LINK:
+ case ESCO_LINK:
+ cnt = hdev->sco_cnt;
+ break;
+ case LE_LINK:
+ cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
+ break;
+ default:
+ cnt = 0;
+ BT_ERR("Unknown link type");
+ }
+
+ q = cnt / num;
*quote = q ? q : 1;
} else
*quote = 0;
@@ -1556,6 +1585,40 @@ static inline void hci_sched_esco(struct hci_dev *hdev)
}
}
+static inline void hci_sched_le(struct hci_dev *hdev)
+{
+ struct hci_conn *conn;
+ struct sk_buff *skb;
+ int quote, cnt;
+
+ BT_DBG("%s", hdev->name);
+
+ if (!test_bit(HCI_RAW, &hdev->flags)) {
+ /* ACL tx timeout must be longer than maximum
+ * link supervision timeout (40.9 seconds) */
+ if (!hdev->le_cnt &&
+ time_after(jiffies, hdev->le_last_tx + HZ * 45))
+ hci_acl_tx_to(hdev);
+ }
+
+ cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
+ while (cnt && (conn = hci_low_sent(hdev, LE_LINK, "e))) {
+ while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
+ BT_DBG("skb %p len %d", skb, skb->len);
+
+ hci_send_frame(skb);
+ hdev->le_last_tx = jiffies;
+
+ cnt--;
+ conn->sent++;
+ }
+ }
+ if (hdev->le_pkts)
+ hdev->le_cnt = cnt;
+ else
+ hdev->acl_cnt = cnt;
+}
+
static void hci_tx_task(unsigned long arg)
{
struct hci_dev *hdev = (struct hci_dev *) arg;
@@ -1563,7 +1626,8 @@ static void hci_tx_task(unsigned long arg)
read_lock(&hci_task_lock);
- BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
+ BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
+ hdev->sco_cnt, hdev->le_cnt);
/* Schedule queues and send stuff to HCI driver */
@@ -1573,6 +1637,8 @@ static void hci_tx_task(unsigned long arg)
hci_sched_esco(hdev);
+ hci_sched_le(hdev);
+
/* Send next queued raw (unknown type) packet */
while ((skb = skb_dequeue(&hdev->raw_q)))
hci_send_frame(skb);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 92c8621..da23502 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -539,6 +539,26 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
hci_req_complete(hdev, rp->status);
}
+static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
+
+ BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+ if (rp->status)
+ return;
+
+ hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
+ hdev->le_pkts = rp->le_max_pkt;
+
+ hdev->le_cnt = hdev->le_pkts;
+
+ BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
+
+ hci_req_complete(hdev, rp->status);
+}
+
static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
{
BT_DBG("%s status 0x%x", hdev->name, status);
@@ -1353,6 +1373,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_cc_read_bd_addr(hdev, skb);
break;
+ case HCI_OP_LE_READ_BUFFER_SIZE:
+ hci_cc_le_read_buffer_size(hdev, skb);
+ break;
+
default:
BT_DBG("%s opcode 0x%x", hdev->name, opcode);
break;
@@ -1490,10 +1514,22 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
conn->sent -= count;
if (conn->type == ACL_LINK) {
- if ((hdev->acl_cnt += count) > hdev->acl_pkts)
+ hdev->acl_cnt += count;
+ if (hdev->acl_cnt > hdev->acl_pkts)
hdev->acl_cnt = hdev->acl_pkts;
+ } else if (conn->type == LE_LINK) {
+ if (hdev->le_pkts) {
+ hdev->le_cnt += count;
+ if (hdev->le_cnt > hdev->le_pkts)
+ hdev->le_cnt = hdev->le_pkts;
+ } else {
+ hdev->acl_cnt += count;
+ if (hdev->acl_cnt > hdev->acl_pkts)
+ hdev->acl_cnt = hdev->acl_pkts;
+ }
} else {
- if ((hdev->sco_cnt += count) > hdev->sco_pkts)
+ hdev->sco_cnt += count;
+ if (hdev->sco_cnt > hdev->sco_pkts)
hdev->sco_cnt = hdev->sco_pkts;
}
}
--
1.7.1
^ permalink raw reply related
* [PATCH 2/6] Bluetooth: Add LE connect support
From: Ville Tervo @ 2010-10-25 12:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ville Tervo
In-Reply-To: <1288009280-5149-1-git-send-email-ville.tervo@nokia.com>
Bluetooth V4.0 adds support for Low Energy (LE)
connections. Specification introduses new set
of hci commands to control LE connection.
This patch adds logic to create, cancel and
disconnect LE connections
Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
---
include/net/bluetooth/hci.h | 2 +
include/net/bluetooth/hci_core.h | 25 +++++++++--
net/bluetooth/hci_conn.c | 51 +++++++++++++++++++-
net/bluetooth/hci_event.c | 93 ++++++++++++++++++++++++++++++++++++++
4 files changed, 164 insertions(+), 7 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index ee5beec..02055b9 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -159,6 +159,8 @@ enum {
#define SCO_LINK 0x00
#define ACL_LINK 0x01
#define ESCO_LINK 0x02
+/* Low Energy links do not have defined link type. Use invented one */
+#define LE_LINK 0x80
/* LMP features */
#define LMP_3SLOT 0x01
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ebec8c9..2b7f94a 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -60,6 +60,7 @@ struct hci_conn_hash {
spinlock_t lock;
unsigned int acl_num;
unsigned int sco_num;
+ unsigned int le_num;
};
struct bdaddr_list {
@@ -272,20 +273,36 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
{
struct hci_conn_hash *h = &hdev->conn_hash;
list_add(&c->list, &h->list);
- if (c->type == ACL_LINK)
+ switch (c->type) {
+ case ACL_LINK:
h->acl_num++;
- else
+ break;
+ case LE_LINK:
+ h->le_num++;
+ break;
+ case SCO_LINK:
+ case ESCO_LINK:
h->sco_num++;
+ break;
+ }
}
static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
{
struct hci_conn_hash *h = &hdev->conn_hash;
list_del(&c->list);
- if (c->type == ACL_LINK)
+ switch (c->type) {
+ case ACL_LINK:
h->acl_num--;
- else
+ break;
+ case LE_LINK:
+ h->le_num--;
+ break;
+ case SCO_LINK:
+ case ESCO_LINK:
h->sco_num--;
+ break;
+ }
}
static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 0b1e460..0944c0c 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -45,6 +45,32 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
+void hci_le_connect(struct hci_conn *conn)
+{
+ struct hci_dev *hdev = conn->hdev;
+ struct hci_cp_le_create_conn cp;
+
+ conn->state = BT_CONNECT;
+ conn->out = 1;
+
+ memset(&cp, 0, sizeof(cp));
+ cp.scan_interval = cpu_to_le16(0x0004);
+ cp.scan_window = cpu_to_le16(0x0004);
+ bacpy(&cp.peer_addr, &conn->dst);
+ cp.conn_interval_min = cpu_to_le16(0x0008);
+ cp.conn_interval_max = cpu_to_le16(0x0100);
+ cp.supervision_timeout = cpu_to_le16(0x0064);
+ cp.min_ce_len = cpu_to_le16(0x0001);
+ cp.max_ce_len = cpu_to_le16(0x0001);
+
+ hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
+}
+
+static void hci_le_connect_cancel(struct hci_conn *conn)
+{
+ hci_send_cmd(conn->hdev, HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL);
+}
+
void hci_acl_connect(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
@@ -192,8 +218,12 @@ static void hci_conn_timeout(unsigned long arg)
switch (conn->state) {
case BT_CONNECT:
case BT_CONNECT2:
- if (conn->type == ACL_LINK && conn->out)
- hci_acl_connect_cancel(conn);
+ if (conn->out) {
+ if (conn->type == ACL_LINK)
+ hci_acl_connect_cancel(conn);
+ else if (conn->type == LE_LINK)
+ hci_le_connect_cancel(conn);
+ }
break;
case BT_CONFIG:
case BT_CONNECTED:
@@ -359,15 +389,30 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
}
EXPORT_SYMBOL(hci_get_route);
-/* Create SCO or ACL connection.
+/* Create SCO, ACL or LE connection.
* Device _must_ be locked */
struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type)
{
struct hci_conn *acl;
struct hci_conn *sco;
+ struct hci_conn *le;
BT_DBG("%s dst %s", hdev->name, batostr(dst));
+ if (type == LE_LINK) {
+ le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
+ if (!le)
+ le = hci_conn_add(hdev, LE_LINK, dst);
+ if (!le)
+ return NULL;
+ if (le->state == BT_OPEN)
+ hci_le_connect(le);
+
+ hci_conn_hold(le);
+
+ return le;
+ }
+
if (!(acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
return NULL;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 84093b0..92c8621 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -822,6 +822,43 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
hci_dev_unlock(hdev);
}
+static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
+{
+ struct hci_cp_le_create_conn *cp;
+ struct hci_conn *conn;
+
+ BT_DBG("%s status 0x%x", hdev->name, status);
+
+ cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
+ if (!cp)
+ return;
+
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
+
+ BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
+ conn);
+
+ if (status) {
+ if (conn && conn->state == BT_CONNECT) {
+ conn->state = BT_CLOSED;
+ hci_proto_connect_cfm(conn, status);
+ hci_conn_del(conn);
+ }
+ } else {
+ if (!conn) {
+ conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
+ if (conn)
+ conn->out = 1;
+ else
+ BT_ERR("No memory for new connection");
+ }
+ }
+
+ hci_dev_unlock(hdev);
+}
+
static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
@@ -1382,6 +1419,10 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cs_exit_sniff_mode(hdev, ev->status);
break;
+ case HCI_OP_LE_CREATE_CONN:
+ hci_cs_le_create_conn(hdev, ev->status);
+ break;
+
default:
BT_DBG("%s opcode 0x%x", hdev->name, opcode);
break;
@@ -1827,6 +1868,54 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
hci_dev_unlock(hdev);
}
+static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_ev_le_conn_complete *ev = (void *) skb->data;
+ struct hci_conn *conn;
+
+ BT_DBG("%s status %d", hdev->name, ev->status);
+
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
+ if (!conn)
+ goto unlock;
+
+ if (ev->status) {
+ hci_proto_connect_cfm(conn, ev->status);
+ conn->state = BT_CLOSED;
+ hci_conn_del(conn);
+ goto unlock;
+ }
+
+ conn->handle = __le16_to_cpu(ev->handle);
+ conn->state = BT_CONNECTED;
+
+ hci_conn_hold_device(conn);
+ hci_conn_add_sysfs(conn);
+
+ hci_proto_connect_cfm(conn, ev->status);
+
+unlock:
+ hci_dev_unlock(hdev);
+}
+
+static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_ev_le_meta *le_ev = (void *) skb->data;
+
+ skb_pull(skb, sizeof(*le_ev));
+
+ switch (le_ev->subevent) {
+ case HCI_EV_LE_CONN_COMPLETE:
+ hci_le_conn_complete_evt(hdev, skb);
+ break;
+
+ default:
+ break;
+ }
+}
+
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_event_hdr *hdr = (void *) skb->data;
@@ -1963,6 +2052,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_remote_host_features_evt(hdev, skb);
break;
+ case HCI_EV_LE_META:
+ hci_le_meta_evt(hdev, skb);
+ break;
+
default:
BT_DBG("%s event 0x%x", hdev->name, event);
break;
--
1.7.1
^ permalink raw reply related
* [PATCH 1/6] Bluetooth: Add low energy commands and events
From: Ville Tervo @ 2010-10-25 12:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ville Tervo
In-Reply-To: <1288009280-5149-1-git-send-email-ville.tervo@nokia.com>
Add needed HCI command and event structs to
create LE connections.
Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
---
include/net/bluetooth/hci.h | 49 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index e30e008..ee5beec 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -593,6 +593,36 @@ struct hci_rp_read_bd_addr {
bdaddr_t bdaddr;
} __packed;
+#define HCI_OP_LE_SET_EVENT_MASK 0x2001
+struct hci_cp_le_set_event_mask {
+ __u8 mask[8];
+} __packed;
+
+#define HCI_OP_LE_READ_BUFFER_SIZE 0x2002
+struct hci_rp_le_read_buffer_size {
+ __u8 status;
+ __le16 le_mtu;
+ __u8 le_max_pkt;
+} __packed;
+
+#define HCI_OP_LE_CREATE_CONN 0x200d
+struct hci_cp_le_create_conn {
+ __le16 scan_interval;
+ __le16 scan_window;
+ __u8 filter_policy;
+ __u8 peer_addr_type;
+ bdaddr_t peer_addr;
+ __u8 own_address_type;
+ __le16 conn_interval_min;
+ __le16 conn_interval_max;
+ __le16 conn_latency;
+ __le16 supervision_timeout;
+ __le16 min_ce_len;
+ __le16 max_ce_len;
+} __packed;
+
+#define HCI_OP_LE_CREATE_CONN_CANCEL 0x200e
+
/* ---- HCI Events ---- */
#define HCI_EV_INQUIRY_COMPLETE 0x01
@@ -845,6 +875,25 @@ struct hci_ev_remote_host_features {
__u8 features[8];
} __packed;
+#define HCI_EV_LE_META 0x3e
+struct hci_ev_le_meta {
+ __u8 subevent;
+} __packed;
+
+/* Low energy meta events */
+#define HCI_EV_LE_CONN_COMPLETE 0x01
+struct hci_ev_le_conn_complete {
+ __u8 status;
+ __le16 handle;
+ __u8 role;
+ __u8 bdaddr_type;
+ bdaddr_t bdaddr;
+ __le16 interval;
+ __le16 latency;
+ __le16 supervision_timeout;
+ __u8 clk_accurancy;
+} __packed;
+
/* Internal events generated by Bluetooth stack */
#define HCI_EV_STACK_INTERNAL 0xfd
struct hci_ev_stack_internal {
--
1.7.1
^ permalink raw reply related
* [PATCH] Basic bluetooth low energy support
From: Ville Tervo @ 2010-10-25 12:21 UTC (permalink / raw)
To: linux-bluetooth
Hi,
This is V3 of patch set to enable bluetooth Low Energy traffic
over unencrypted links.
Changes from RFC V2
- Gustavo's review.
^ permalink raw reply
* Re: [PATCH 0/1] Bluetooth: fix crash in L2CAP
From: Gustavo F. Padovan @ 2010-10-25 11:15 UTC (permalink / raw)
To: Greg KH; +Cc: linux-bluetooth, stable, linux-kernel
In-Reply-To: <20101021133507.GB20184@kroah.com>
Hi Greg,
* Greg KH <greg@kroah.com> [2010-10-21 06:35:07 -0700]:
> On Thu, Oct 21, 2010 at 03:19:52AM -0200, Gustavo F. Padovan wrote:
> > Hi Greg,
> >
> > The following patch is good for 2.6.36.1. It arrived too late in linux-bluetooth
> > and we didn't had time to put it into 2.6.36. It fixes a serious crash into
> > the L2CAP layer. The issue isn't in 2.6.35 and below.
>
> It needs to get into Linus's tree before I can accept it into the
> -stable trees. Please get it there and then send stable@kernel.org the
> git commit id and I will add it.
It is now on Linus' tree, sorry for doing this wrong first time. It was
my first report to stable. ;)
commit d793fe8caa3911e6a1e826b45d4ee00d250cdec8
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* Re: [PATCH 2/2 v2] Bluetooth: Fix system crash bug of no send queue protect
From: Gustavo F. Padovan @ 2010-10-25 11:09 UTC (permalink / raw)
To: haijun liu; +Cc: Haijun Liu, linux-bluetooth
In-Reply-To: <AANLkTinbP=N-pTKG1dN9PEPFHSLk9N98cq8aC=dfzav7@mail.gmail.com>
Hi Haijun,
* haijun liu <liuhaijun.er@gmail.com> [2010-10-25 10:15:48 +0800]:
> Hi Gustavo,
>
> >> During test session with another vendor's bt stack, found that
> >> without lock protect for TX_QUEUE(sk) will cause system crash while
> >> data transfer over AMP controller. So I just add lock protect for
> >> TX_QUEUE(sk).
> >
> > We already use the default socket lock protection. Is it not working for
> > you? Why? Could you show a crash case that requires your patch to fix
> > it?
> >
>
> Yes, there is socket lock protection, but only for sk_buff, for the related
> variable we need protect them as well, such as 'sk->sk_send_head',
> because later in different context we will use it as sk_buff directly, but at
> that time maybe it has been freed and that buffer be occupied by another
> sk_buff.
sk->sk_send_head is also protected by the socket lock.
>
> Below is the crash case we met:
>
> [ 265.544145] l2cap_sock_sendmsg: sock e7f4e380, sk e015fc00, msg
> e01f5ea4, len 1668
> [ 265.544149] l2cap_sock_sendmsg: sk->scid 42, sk->dcid 5d, sk->mode 3
> [ 265.544157] block_sendmsg_condition:
> [ 265.544160] l2cap_tx_window_full:
> [ 265.544163] block_sendmsg_condition: tx_window full: 0, or
> wait_f/remote busy.
> [ 265.544168] l2cap_sar_segment_sdu: sk e015fc00 len 5736
> [ 265.544172] l2cap_create_iframe_pdu: sk e015fc00 len 1011 control
> 4000 sdulen 5736
> [ 265.544175] l2cap_loglink_validate:
> [ 265.544179] l2cap_skbuff_fromiovec:
> [ 265.544183] l2cap_create_iframe_pdu: sk e015fc00 len 1011 control
> c000 sdulen 0
> [ 265.544187] l2cap_loglink_validate:
> [ 265.544191] l2cap_skbuff_fromiovec:
> [ 265.544195] l2cap_create_iframe_pdu: sk e015fc00 len 1011 control
> c000 sdulen 0
> [ 265.544200] l2cap_loglink_validate:
> [ 265.544203] l2cap_skbuff_fromiovec:
> [ 265.544207] l2cap_create_iframe_pdu: sk e015fc00 len 1011 control
> c000 sdulen 0
> [ 265.544211] l2cap_loglink_validate:
> [ 265.544214] l2cap_skbuff_fromiovec:
> [ 265.544218] l2cap_create_iframe_pdu: sk e015fc00 len 1011 control
> c000 sdulen 0
> [ 265.544221] l2cap_loglink_validate:
> [ 265.544225] l2cap_skbuff_fromiovec:
> [ 265.544229] l2cap_create_iframe_pdu: sk e015fc00 len 681 control
> 8000 sdulen 0
> [ 265.544252] l2cap_loglink_validate:
> [ 265.544255] l2cap_skbuff_fromiovec:
> [ 265.544483] l2cap_recv_acldata:
> [ 265.544488] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.544492] l2cap_recv_frame: conn f461bcc0, skb ee91ccc0, cid 42, len 4
> [ 265.544496] l2cap_recv_frame: len 4, cid 0x0042
> [ 265.544498] l2cap_data_channel:
> [ 265.544501] l2cap_get_chan_by_scid:
> [ 265.544504] __l2cap_get_chan_by_scid:
> [ 265.544508] l2cap_data_channel: sk e015fc00, len 4
> [ 265.544511] l2cap_ertm_data_rcv:
> [ 265.544514] l2cap_check_fcs:
> [ 265.544517] l2cap_data_channel_sframe: sk e015fc00 rx_control 0x2209 len 0
> [ 265.544521] l2cap_data_channel_rnrframe: sk e015fc00, req_seq 34 ctrl 0x2209
> [ 265.544525] l2cap_drop_acked_frames:
> [ 265.544636] l2cap_recv_acldata:
> [ 265.544641] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.544645] l2cap_recv_frame: conn f461bcc0, skb ee91c6c0, cid 42, len 4
> [ 265.544649] l2cap_recv_frame: len 4, cid 0x0042
> [ 265.544652] l2cap_data_channel:
> [ 265.544655] l2cap_get_chan_by_scid:
> [ 265.544657] __l2cap_get_chan_by_scid:
> [ 265.570492] l2cap_recv_acldata:
> [ 265.570503] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.570507] l2cap_recv_frame: conn f461bcc0, skb ee91c0c0, cid 42, len 4
> [ 265.570513] l2cap_recv_frame: len 4, cid 0x0042
> [ 265.570517] l2cap_data_channel:
> [ 265.570520] l2cap_get_chan_by_scid:
> [ 265.570524] __l2cap_get_chan_by_scid:
> [ 265.570529] l2cap_data_channel: sk e015fc00, len 4
> [ 265.570533] l2cap_ertm_data_rcv:
> [ 265.570536] l2cap_check_fcs:
> [ 265.570542] l2cap_data_channel_sframe: sk e015fc00 rx_control 0x2709 len 0
> [ 265.570547] l2cap_data_channel_rnrframe: sk e015fc00, req_seq 39 ctrl 0x2709
> [ 265.570550] l2cap_drop_acked_frames:
> [ 265.570658] l2cap_recv_acldata:
> [ 265.570663] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.570668] l2cap_recv_frame: conn f461bcc0, skb ee91ca80, cid 42, len 4
> [ 265.570673] l2cap_recv_frame: len 4, cid 0x0042
> [ 265.570677] l2cap_data_channel:
> [ 265.570680] l2cap_get_chan_by_scid:
> [ 265.570683] __l2cap_get_chan_by_scid:
> [ 265.570687] l2cap_data_channel: sk e015fc00, len 4
> [ 265.570691] l2cap_ertm_data_rcv:
> [ 265.570694] l2cap_check_fcs:
> [ 265.570698] l2cap_data_channel_sframe: sk e015fc00 rx_control 0x2809 len 0
> [ 265.570702] l2cap_data_channel_rnrframe: sk e015fc00, req_seq 40 ctrl 0x2809
> [ 265.570706] l2cap_drop_acked_frames:
> [ 265.570858] l2cap_recv_acldata:
> [ 265.572903] l2cap_recv_acldata:
> [ 265.572910] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.572915] l2cap_recv_frame: conn f461bcc0, skb f469fa80, cid 42, len 4
> [ 265.572919] l2cap_recv_frame: len 4, cid 0x0042
> [ 265.572921] l2cap_data_channel:
> [ 265.572925] l2cap_get_chan_by_scid:
> [ 265.572928] __l2cap_get_chan_by_scid:
> [ 265.572933] l2cap_data_channel: sk e015fc00, len 4
> [ 265.572936] l2cap_ertm_data_rcv:
> [ 265.572938] l2cap_check_fcs:
> [ 265.572943] l2cap_data_channel_sframe: sk e015fc00 rx_control 0x2b09 len 0
> [ 265.573348] l2cap_recv_acldata:
>
> [ 265.609993] l2cap_recv_acldata:
> [ 265.610005] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.610009] l2cap_recv_frame: conn f461bcc0, skb ee91c540, cid 42, len 4
> [ 265.610013] l2cap_recv_frame: len 4, cid 0x0042
> [ 265.610016] l2cap_data_channel:
> [ 265.610019] l2cap_get_chan_by_scid:
> [ 265.610022] __l2cap_get_chan_by_scid:
> [ 265.610025] l2cap_data_channel: sk e015fc00, len 4
> [ 265.610029] l2cap_ertm_data_rcv:
> [ 265.610032] l2cap_check_fcs:
> [ 265.610036] l2cap_data_channel_sframe: sk e015fc00 rx_control 0x3801 len 0
> [ 265.610041] l2cap_data_channel_rrframe: sk e015fc00, req_seq 56 ctrl 0x3801
> [ 265.610044] l2cap_drop_acked_frames:
> [ 265.610060] l2cap_ertm_send: sk e015fc00, sk->scid 42, sk->dcid 5d
> [ 265.610064] l2cap_tx_window_full:
> [ 265.610071] l2cap_ertm_send: pi->next_tx_seq: 13, pi->buffer_seq: 2
> [ 265.610075] l2cap_do_send: sk e015fc00, cid 66 skb e0147840 len 1019
> [ 265.610078] l2cap_loglink_validate:
> [ 265.610081] l2cap_do_send: send I frame over AMP controller
> [ 265.610085] l2cap_tx_window_full:
> [ 265.610093] l2cap_ertm_send: pi->next_tx_seq: 14, pi->buffer_seq: 2
> [ 265.610096] l2cap_do_send: sk e015fc00, cid 66 skb f4801cc0 len 1019
> [ 265.610099] l2cap_loglink_validate:
> [ 265.610102] l2cap_do_send: send I frame over AMP controller
> [ 265.610105] l2cap_tx_window_full:
> [ 265.610112] l2cap_ertm_send: pi->next_tx_seq: 15, pi->buffer_seq: 2
> [ 265.610115] l2cap_do_send: sk e015fc00, cid 66 skb f4801600 len 1019
> [ 265.610118] l2cap_loglink_validate:
> [ 265.610121] l2cap_do_send: send I frame over AMP controller
> [ 265.610124] l2cap_tx_window_full:
> [ 265.610130] l2cap_ertm_send: pi->next_tx_seq: 16, pi->buffer_seq: 2
> [ 265.610133] l2cap_do_send: sk e015fc00, cid 66 skb f4801c00 len 689
> [ 265.610137] l2cap_loglink_validate:
> [ 265.610140] l2cap_do_send: send I frame over AMP controller
> [ 265.610143] l2cap_tx_window_full:
> [ 265.610153] l2cap_ertm_send: pi->next_tx_seq: 17, pi->buffer_seq: 2
> [ 265.610215] l2cap_ertm_send: pi->next_tx_seq: 20, pi->buffer_seq: 2
> [ 265.610219] l2cap_do_send: sk e015fc00, cid 66 skb f47f03c0 len 1019
> [ 265.610222] l2cap_loglink_validate:
> [ 265.619937] l2cap_recv_acldata:
> [ 265.619948] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.619952] l2cap_recv_frame: conn f461bcc0, skb ee91c300, cid 42, len 4
> [ 265.619956] l2cap_recv_frame: len 4, cid 0x0042
> [ 265.620154] l2cap_ertm_send: pi->next_tx_seq: 29, pi->buffer_seq: 2
> [ 265.629111] l2cap_recv_acldata:
> [ 265.629123] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
>
> [ 265.639371] l2cap_recv_acldata:
> [ 265.639384] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.639388] l2cap_recv_frame: conn f461bcc0, skb ee91ccc0, cid 42, len 4
> [ 265.639392] l2cap_recv_frame: len 4, cid 0x0042
> [ 265.639395] l2cap_data_channel:
> [ 265.639398] l2cap_get_chan_by_scid:
> [ 265.639401] __l2cap_get_chan_by_scid:
> [ 265.639405] l2cap_data_channel: sk e015fc00, len 4
> [ 265.639407] l2cap_ertm_data_rcv:
> [ 265.639570] l2cap_do_send: send I frame over AMP controller
> [ 265.646669] l2cap_recv_acldata:
> [ 265.646681] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.646685] l2cap_recv_frame: conn f461bcc0, skb ee91c6c0, cid 42, len 4
> [ 265.646822] l2cap_loglink_validate:
> [ 265.646825] l2cap_skbuff_fromiovec:
> [ 265.647800] l2cap_recv_acldata:
> [ 265.647808] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.649645] l2cap_recv_acldata:
> [ 265.649655] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.649659] l2cap_recv_frame: conn f461bcc0, skb ee91c180, cid 42, len 4
> [ 265.649663] l2cap_recv_frame: len 4, cid 0x0042
> [ 265.651518] l2cap_recv_acldata:
> [ 265.651527] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.651532] l2cap_recv_frame: conn f461bcc0, skb ee91c0c0, cid 42, len 4
> [ 265.655539] l2cap_recv_acldata:
> [ 265.655547] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.655550] l2cap_recv_frame: conn f461bcc0, skb e035bc00, cid 42, len 4
> [ 265.655554] l2cap_recv_frame: len 4, cid 0x0042
> [ 265.655556] l2cap_data_channel:
> [ 265.655559] l2cap_get_chan_by_scid:
> [ 265.655562] __l2cap_get_chan_by_scid:
> [ 265.663270] l2cap_recv_acldata:
> [ 265.663276] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.667987] l2cap_recv_acldata:
> [ 265.673206] l2cap_recv_acldata:
> [ 265.673217] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.673221] l2cap_recv_frame: conn f461bcc0, skb ee91c780, cid 42, len 4
> [ 265.673225] l2cap_recv_frame: len 4, cid 0x0042
> [ 265.673227] l2cap_data_channel:
> [ 265.673230] l2cap_get_chan_by_scid:
> [ 265.673233] __l2cap_get_chan_by_scid:
> [ 265.673236] l2cap_data_channel: sk e015fc00, len 4
> [ 265.673240] l2cap_ertm_data_rcv:
> [ 265.673243] l2cap_check_fcs:
> [ 265.673247] l2cap_data_channel_sframe: sk e015fc00 rx_control 0x3109 len 0
> [ 265.675265] l2cap_recv_acldata:
> [ 265.675273] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.691337] l2cap_recv_acldata:
> [ 265.691348] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
> [ 265.691352] l2cap_recv_frame: conn f461bcc0, skb ee91c000, cid 42, len 4
> [ 265.691356] l2cap_recv_frame: len 4, cid 0x0042
> [ 265.691359] l2cap_data_channel:
> [ 265.691362] l2cap_get_chan_by_scid:
> [ 265.691366] __l2cap_get_chan_by_scid:
> [ 265.691369] l2cap_data_channel: sk e015fc00, len 4
> [ 265.691372] l2cap_ertm_data_rcv:
> [ 265.691375] l2cap_check_fcs:
> [ 265.691379] l2cap_data_channel_sframe: sk e015fc00 rx_control 0x3511 len 0
> [ 265.691383] l2cap_data_channel_rrframe: sk e015fc00, req_seq 53 ctrl 0x3511
> [ 265.691386] l2cap_drop_acked_frames:
> [ 265.691389] l2cap_send_i_or_rr_or_rnr:
> [ 265.691392] l2cap_ertm_send: sk e015fc00, sk->scid 42, sk->dcid 5d
> [ 265.691396] l2cap_tx_window_full:
> [ 265.691400] l2cap_ertm_send: pi->next_tx_seq: 53, pi->buffer_seq: 2
> [ 265.691404] l2cap_do_send: sk e015fc00, cid 66 skb e0204000 len 101
> [ 265.691407] l2cap_loglink_validate:
> [ 265.691410] l2cap_do_send: send I frame over AMP controller
This dump shows that the crash happens for a code that is not mainline
yet. I can't take a patch that fix a bug for code not in mainline. You
have to show the bug using mainline code.
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* Re: [PATCH 1/2 v2] Bluetooth: Fix system crash caused by del_timer()
From: Gustavo F. Padovan @ 2010-10-25 11:01 UTC (permalink / raw)
To: haijun liu; +Cc: Haijun Liu, linux-bluetooth
In-Reply-To: <AANLkTi=C5biCuJV335yfNWkY77xK29aa5JQ+9xvaE1yr@mail.gmail.com>
Hi Haijun,
* haijun liu <liuhaijun.er@gmail.com> [2010-10-25 09:35:33 +0800]:
> Hi Gustavo,
>
> >> During test session with another vendor's bt stack, found that in
> >> l2cap_chan_del() using del_timer() caused l2cap_monitor_timeout()
> >> be called after the sock was freed, so it raised a system crash.
> >> So I just replaced del_timer() with del_timer_sync() to solve it.
> >
> > NAK on this. If you read the del_timer_sync() documentation you can
> > see that you can't call del_timer_sync() on interrupt context. The
> > possible solution here is to check in the beginning of
> > l2cap_monitor_timeout() if your sock is still valid.
> >
>
> You are right, I only considered close() interface, so missed the interrupt
> context.
>
> It's very difficult to check sock valid or not in timeout procedure, since it's
> an interrupt context, and only can get context from parameter pre-stored,
> except global variables.
I think you can check for sk == null there.
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* [PATCH] Provide extra query for vCard single call
From: Rafal Michalski @ 2010-10-25 9:04 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Rafal Michalski
This patch makes that additional circumstance is recognized - after
making a call with number that is out of phonebook it can be downloaded
as a single vCard containing number with OTHER type.
---
plugins/phonebook-tracker.c | 20 ++++++++++++++++++--
1 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 1c579d1..f25708a 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -55,6 +55,7 @@
#define COL_SENT 36
#define COL_ANSWERED 37
#define ADDR_FIELD_AMOUNT 7
+#define CONTACT_ID_PREFIX "contact:"
#define CONTACTS_QUERY_ALL \
"SELECT ?v nco:fullname(?c) " \
@@ -569,6 +570,16 @@
"} " \
"}"
+#define CONTACTS_OTHER_QUERY_FROM_URI \
+ "SELECT \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" "\
+ "\"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" " \
+ "\"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" " \
+ "nco:phoneNumber(?t) \"NOTACALL\" \"false\" \"false\" <%s> " \
+ "WHERE { " \
+ "<%s> a nco:Contact . " \
+ "<%s> nco:hasPhoneNumber ?t . " \
+ "} "
+
typedef void (*reply_list_foreach_t) (char **reply, int num_fields,
void *user_data);
@@ -1305,9 +1316,14 @@ int phonebook_get_entry(const char *folder, const char *id,
data->cb = cb;
data->vcardentry = TRUE;
- query = g_strdup_printf(CONTACTS_QUERY_FROM_URI, id, id, id, id, id,
- id, id, id, id, id, id, id,
+ if (strncmp(id, CONTACT_ID_PREFIX, strlen(CONTACT_ID_PREFIX)) == 0) {
+ query = g_strdup_printf(CONTACTS_QUERY_FROM_URI, id, id, id, id,
+ id, id, id, id, id, id, id, id,
id, id, id, id, id);
+ } else {
+ query = g_strdup_printf(CONTACTS_OTHER_QUERY_FROM_URI,
+ id, id, id);
+ }
ret = query_tracker(query, PULL_QUERY_COL_AMOUNT, pull_contacts, data);
--
1.6.3.3
^ permalink raw reply related
* Re: (Health) ChannelConnected signal when MDL aborted?
From: Santiago Carot @ 2010-10-25 7:26 UTC (permalink / raw)
To: Elvis Pfützenreuter; +Cc: linux-bluetooth
In-Reply-To: <5AA6D2CA-9EE2-49EC-BBE0-F1185DE42BF5@signove.com>
Hello Elvis,
2010/10/24 Elvis Pfützenreuter <epx@signove.com>:
>
>> sure?
>> Then you should think what happen with the First reliable data channel
>> in case that you are running multiples IEEE specializations over the
>> same HDP instance (that is pretty common in IEEE level). Remember that
>> the First Relible data channel is used for IEEE association and
>> confirmed event traffic. If you dont allow use that channel by other
>> application it won't associate with the other device at IEEE layer.
>> Please, think that with current HDP implementation you can develop
>> IEEE agent specializations too, not only managers.
>
> Ok, I think I see your point now. Thanks for the patience :)
>
Don't worry. comments are welcome, in any case, If you have more
doubts, please don't hesitate in contact with me, we can talk more
about that and others issues in IRC, the only problem may be the time
difference ;)
Regards
^ permalink raw reply
* Re: [PATCH 4/6] Bluetooth: Add LE connection support to L2CAP
From: Ville Tervo @ 2010-10-25 7:11 UTC (permalink / raw)
To: ext Gustavo F. Padovan; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <20101022191457.GE980@vigoh>
On Fri, Oct 22, 2010 at 09:14:57PM +0200, ext Gustavo F. Padovan wrote:
> Hi Ville,
>
> * Ville Tervo <ville.tervo@nokia.com> [2010-10-18 16:02:54 +0300]:
>
> > Add basic LE connection support to L2CAP. LE
> > connection can be created by specifying cid
> > in struct sockaddr_l2
> >
> > Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
> > ---
> > include/net/bluetooth/l2cap.h | 3 +++
> > net/bluetooth/l2cap.c | 32 ++++++++++++++++++++++++--------
> > 2 files changed, 27 insertions(+), 8 deletions(-)
> >
> > diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> > index c819c8b..cc3a140 100644
> > --- a/include/net/bluetooth/l2cap.h
> > +++ b/include/net/bluetooth/l2cap.h
> > @@ -160,6 +160,9 @@ struct l2cap_conn_rsp {
> > /* channel indentifier */
> > #define L2CAP_CID_SIGNALING 0x0001
> > #define L2CAP_CID_CONN_LESS 0x0002
> > +#define L2CAP_CID_LE_DATA 0x0004
> > +#define L2CAP_CID_LE_SIGNALING 0x0005
> > +#define L2CAP_CID_SMP 0x0006
> > #define L2CAP_CID_DYN_START 0x0040
> > #define L2CAP_CID_DYN_END 0xffff
> >
> > diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> > index 16049de..bf5daf3 100644
> > --- a/net/bluetooth/l2cap.c
> > +++ b/net/bluetooth/l2cap.c
> > @@ -617,6 +617,12 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
> > for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
> > bh_lock_sock(sk);
> >
> > + if (conn->hcon->type == LE_LINK) {
> > + l2cap_sock_clear_timer(sk);
> > + sk->sk_state = BT_CONNECTED;
> > + sk->sk_state_change(sk);
> > + }
> > +
> > if (sk->sk_type != SOCK_SEQPACKET &&
> > sk->sk_type != SOCK_STREAM) {
> > l2cap_sock_clear_timer(sk);
> > @@ -675,7 +681,11 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
> >
> > BT_DBG("hcon %p conn %p", hcon, conn);
> >
> > - conn->mtu = hcon->hdev->acl_mtu;
> > + if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
> > + conn->mtu = hcon->hdev->le_mtu;
> > + else
> > + conn->mtu = hcon->hdev->acl_mtu;
> > +
> > conn->src = &hcon->hdev->bdaddr;
> > conn->dst = &hcon->dst;
> >
> > @@ -1102,8 +1112,13 @@ static int l2cap_do_connect(struct sock *sk)
> > }
> > }
> >
> > - hcon = hci_connect(hdev, ACL_LINK, dst,
> > + if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA)
> > + hcon = hci_connect(hdev, LE_LINK, dst,
> > + l2cap_pi(sk)->sec_level, auth_type);
> > + else
>
>
> I think that "else if (l2cap_pi(sk)->psm)" is better here, we do not
> want to permit go ahead with psm 0.
That is checked already in l2cap_sock_connect().
--
Ville
^ permalink raw reply
* Re: [PATCH 3/6] Bluetooth: Use LE buffers for LE traffic
From: Ville Tervo @ 2010-10-25 7:09 UTC (permalink / raw)
To: ext Gustavo F. Padovan; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <20101022185358.GD980@vigoh>
On Fri, Oct 22, 2010 at 08:53:58PM +0200, ext Gustavo F. Padovan wrote:
> Hi Ville,
>
> * Ville Tervo <ville.tervo@nokia.com> [2010-10-18 16:02:53 +0300]:
>
> > BLuetooth chips may have separate buffers for
> > LE traffic. This patch add support to use LE
> > buffers provided by the chip.
> >
> > Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
> > ---
> > include/net/bluetooth/hci.h | 2 +
> > include/net/bluetooth/hci_core.h | 5 +++
> > net/bluetooth/hci_conn.c | 6 +++
> > net/bluetooth/hci_core.c | 74 +++++++++++++++++++++++++++++++++++--
> > net/bluetooth/hci_event.c | 40 +++++++++++++++++++-
> > 5 files changed, 121 insertions(+), 6 deletions(-)
> >
> > diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> > index 02055b9..b42edf0 100644
> > --- a/include/net/bluetooth/hci.h
> > +++ b/include/net/bluetooth/hci.h
> > @@ -189,6 +189,8 @@ enum {
> >
> > #define LMP_EV4 0x01
> > #define LMP_EV5 0x02
> > +#define LMP_NO_BREDR 0x20
>
> You are not using this one.
I'll remove it.
>
> > +#define LMP_LE 0x40
> >
> > #define LMP_SNIFF_SUBR 0x02
> > #define LMP_EDR_ESCO_2M 0x20
> > diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> > index fc2aaee..326d290 100644
> > --- a/include/net/bluetooth/hci_core.h
> > +++ b/include/net/bluetooth/hci_core.h
> > @@ -103,15 +103,19 @@ struct hci_dev {
> > atomic_t cmd_cnt;
> > unsigned int acl_cnt;
> > unsigned int sco_cnt;
> > + unsigned int le_cnt;
> >
> > unsigned int acl_mtu;
> > unsigned int sco_mtu;
> > + unsigned int le_mtu;
> > unsigned int acl_pkts;
> > unsigned int sco_pkts;
> > + unsigned int le_pkts;
> >
> > unsigned long cmd_last_tx;
> > unsigned long acl_last_tx;
> > unsigned long sco_last_tx;
> > + unsigned long le_last_tx;
> >
> > struct workqueue_struct *workqueue;
> >
> > @@ -469,6 +473,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
> > #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
> > #define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO)
> > #define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
> > +#define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE)
> >
> > /* ----- HCI protocols ----- */
> > struct hci_proto {
> > diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
> > index c1eb8e0..c7309e4 100644
> > --- a/net/bluetooth/hci_conn.c
> > +++ b/net/bluetooth/hci_conn.c
> > @@ -324,6 +324,11 @@ int hci_conn_del(struct hci_conn *conn)
> >
> > /* Unacked frames */
> > hdev->acl_cnt += conn->sent;
> > + } else if (conn->type == LE_LINK) {
> > + if (hdev->le_pkts)
> > + hdev->le_cnt += conn->sent;
> > + else
> > + hdev->acl_cnt += conn->sent;
> > } else {
> > struct hci_conn *acl = conn->link;
> > if (acl) {
> > @@ -409,6 +414,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
> > return NULL;
> >
> > hci_le_connect(le);
> > + hci_conn_hold(le);
> >
>
> This should be in 2/6, right?
Yes.
--
Ville
^ permalink raw reply
* Re: [PATCH 2/6] Bluetooth: Add LE connect support
From: Ville Tervo @ 2010-10-25 7:07 UTC (permalink / raw)
To: ext Gustavo F. Padovan; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <20101022184637.GC980@vigoh>
On Fri, Oct 22, 2010 at 08:46:37PM +0200, ext Gustavo F. Padovan wrote:
> * Ville Tervo <ville.tervo@nokia.com> [2010-10-18 16:02:52 +0300]:
>
> > Bluetooth V4.0 adds support for Low Energy (LE)
> > connections. Specification introduses new set
> > of hci commands to control LE connection.
> > This patch adds logic to create, cancel and
> > disconnect LE connections
> >
> > Signed-off-by: Ville Tervo <ville.tervo@nokia.com>
> > ---
> > include/net/bluetooth/hci.h | 2 +
> > include/net/bluetooth/hci_core.h | 21 +++++++--
> > net/bluetooth/hci_conn.c | 51 +++++++++++++++++++-
> > net/bluetooth/hci_event.c | 94 +++++++++++++++++++++++++++++++++++++-
> > 4 files changed, 160 insertions(+), 8 deletions(-)
> >
> > diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> > index ee5beec..02055b9 100644
> > --- a/include/net/bluetooth/hci.h
> > +++ b/include/net/bluetooth/hci.h
> > @@ -159,6 +159,8 @@ enum {
> > #define SCO_LINK 0x00
> > #define ACL_LINK 0x01
> > #define ESCO_LINK 0x02
> > +/* Low Energy links do not have defined link type. Use invented one */
> > +#define LE_LINK 0x80
> >
> > /* LMP features */
> > #define LMP_3SLOT 0x01
> > diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> > index ebec8c9..fc2aaee 100644
> > --- a/include/net/bluetooth/hci_core.h
> > +++ b/include/net/bluetooth/hci_core.h
> > @@ -60,6 +60,7 @@ struct hci_conn_hash {
> > spinlock_t lock;
> > unsigned int acl_num;
> > unsigned int sco_num;
> > + unsigned int le_num;
> > };
> >
> > struct bdaddr_list {
> > @@ -272,20 +273,32 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
> > {
> > struct hci_conn_hash *h = &hdev->conn_hash;
> > list_add(&c->list, &h->list);
> > - if (c->type == ACL_LINK)
> > + switch (c->type) {
> > + case ACL_LINK:
> > h->acl_num++;
> > - else
> > + break;
> > + case LE_LINK:
> > + h->le_num++;
> > + break;
> > + default:
>
> I would add a 'case SCO_LINK' here. It changes nothing actually, but
> make switch easy to understand.
Also ESCO_LINK needs to be added in that case. I'll add those both.
>
> > h->sco_num++;
> > + }
> > }
> >
> > static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
> > {
> > struct hci_conn_hash *h = &hdev->conn_hash;
> > list_del(&c->list);
> > - if (c->type == ACL_LINK)
> > + switch (c->type) {
> > + case ACL_LINK:
> > h->acl_num--;
> > - else
> > + break;
> > + case LE_LINK:
> > + h->le_num--;
> > + break;
> > + default:
>
> Same here.
>
> > h->sco_num--;
> > + }
> > }
> >
> > static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
> > diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
> > index 0b1e460..c1eb8e0 100644
> > --- a/net/bluetooth/hci_conn.c
> > +++ b/net/bluetooth/hci_conn.c
> > @@ -45,6 +45,32 @@
> > #include <net/bluetooth/bluetooth.h>
> > #include <net/bluetooth/hci_core.h>
> >
> > +void hci_le_connect(struct hci_conn *conn)
> > +{
> > + struct hci_dev *hdev = conn->hdev;
> > + struct hci_cp_le_create_conn cp;
> > +
> > + conn->state = BT_CONNECT;
> > + conn->out = 1;
> > +
> > + memset(&cp, 0, sizeof(cp));
> > + cp.scan_interval = cpu_to_le16(0x0004);
> > + cp.scan_window = cpu_to_le16(0x0004);
> > + bacpy(&cp.peer_addr, &conn->dst);
> > + cp.conn_interval_min = cpu_to_le16(0x0008);
> > + cp.conn_interval_max = cpu_to_le16(0x0100);
> > + cp.supervision_timeout = cpu_to_le16(0x0064);
> > + cp.min_ce_len = cpu_to_le16(0x0001);
> > + cp.max_ce_len = cpu_to_le16(0x0001);
> > +
> > + hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
> > +}
> > +
> > +static void hci_le_connect_cancel(struct hci_conn *conn)
> > +{
> > + hci_send_cmd(conn->hdev, HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL);
> > +}
> > +
> > void hci_acl_connect(struct hci_conn *conn)
> > {
> > struct hci_dev *hdev = conn->hdev;
> > @@ -192,8 +218,12 @@ static void hci_conn_timeout(unsigned long arg)
> > switch (conn->state) {
> > case BT_CONNECT:
> > case BT_CONNECT2:
> > - if (conn->type == ACL_LINK && conn->out)
> > - hci_acl_connect_cancel(conn);
> > + if (conn->out) {
> > + if (conn->type == ACL_LINK)
> > + hci_acl_connect_cancel(conn);
> > + else if (conn->type == LE_LINK)
> > + hci_le_connect_cancel(conn);
> > + }
> > break;
> > case BT_CONFIG:
> > case BT_CONNECTED:
> > @@ -359,15 +389,30 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
> > }
> > EXPORT_SYMBOL(hci_get_route);
> >
> > -/* Create SCO or ACL connection.
> > +/* Create SCO, ACL or LE connection.
> > * Device _must_ be locked */
> > struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type)
> > {
> > struct hci_conn *acl;
> > struct hci_conn *sco;
> > + struct hci_conn *le;
> >
> > BT_DBG("%s dst %s", hdev->name, batostr(dst));
> >
> > + if (type == LE_LINK) {
> > + le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
> > +
> > + if (!le)
> > + le = hci_conn_add(hdev, LE_LINK, dst);
> > +
> > + if (!le)
> > + return NULL;
> > +
> > + hci_le_connect(le);
> > +
> > + return le;
> > + }
> > +
> > if (!(acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
> > if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
> > return NULL;
> > diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> > index 84093b0..4061613 100644
> > --- a/net/bluetooth/hci_event.c
> > +++ b/net/bluetooth/hci_event.c
> > @@ -822,6 +822,43 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
> > hci_dev_unlock(hdev);
> > }
> >
> > +static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
> > +{
> > + struct hci_cp_le_create_conn *cp;
> > + struct hci_conn *conn;
> > +
> > + BT_DBG("%s status 0x%x", hdev->name, status);
> > +
> > + cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
> > + if (!cp)
> > + return;
> > +
> > + hci_dev_lock(hdev);
> > +
> > + conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
> > +
> > + BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
> > + conn);
> > +
> > + if (status) {
> > + if (conn && conn->state == BT_CONNECT) {
> > + conn->state = BT_CLOSED;
> > + hci_proto_connect_cfm(conn, status);
> > + hci_conn_del(conn);
> > + }
> > + } else {
> > + if (!conn) {
> > + conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
> > + if (conAvoid things like that in your patch.n)
> > + conn->out = 1;
> > + else
> > + BT_ERR("No memory for new connection");
> > + }
> > + }
> > +
> > + hci_dev_unlock(hdev);
> > +}
> > +
> > static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
> > {
> > __u8 status = *((__u8 *) skb->data);
> > @@ -1024,7 +1061,6 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
> > conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
> > if (conn) {
> > conn->state = BT_CLOSED;
> > -
>
> Avoid things like that in your patch.
My mistake. Will remove it.
--
Ville
^ permalink raw reply
* Re: [PATCH 1/2 v2] Bluetooth: Fix system crash caused by del_timer()
From: haijun liu @ 2010-10-25 2:21 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: Haijun Liu, linux-bluetooth
In-Reply-To: <AANLkTi=C5biCuJV335yfNWkY77xK29aa5JQ+9xvaE1yr@mail.gmail.com>
Here is a dump context:
[ 2544.321834] l2cap_do_send: sk e0325800, cid 3 skb f4839840 len 50
[ 2546.320108] l2cap_ack_timeout:
[ 2546.320122] l2cap_send_ack:
[ 2546.320129] l2cap_ertm_send: sk e0325800, sk->scid 3, sk->dcid 3
[ 2546.320138] l2cap_send_sframe:
[ 2546.320144] l2cap_send_sframe: pi e0325800, control 0x300
[ 2546.320152] l2cap_retrans_timeout: sk e0325800
[ 2546.320157] l2cap_send_rr_or_rnr:
[ 2546.320162] l2cap_send_sframe:
[ 2546.320166] l2cap_send_sframe: pi e0325800, control 0x310
[ 2548.204103] l2cap_disconn_ind: hcon f0443e00
[ 2548.273408] l2cap_disconn_cfm: hcon f0443e00 reason 22
[ 2548.273415] l2cap_conn_del:
[ 2548.273421] l2cap_conn_del: hcon f0443e00 conn f4839b40, err 103
[ 2548.273428] l2cap_free_sock_a2mp_internal: conn f4839b40 a2mp_sock e0325800
[ 2548.273438] l2cap_sock_close: sk e0325800, conn f4839b40
[ 2548.273444] l2cap_sock_clear_timer: sock e0325800 state 1
[ 2548.273450] l2cap_sock_clear_extimer: sock e0325800 state 1
[ 2548.273456] l2cap_sock_close: sk e0325800, conn f4839b40 a2mp_sock e0325800
[ 2548.273462] amp_a2mp_channel_exit: l2cap_conn f4839b40
[ 2548.273468] amp_a2mp_conn_unlink:
[ 2548.273473] amp_a2mp_channel_exit: exit
[ 2558.320031] l2cap_monitor_timeout: sk e0325800
[ 2558.320045] l2cap_send_disconn_req:
[ 2558.320051] l2cap_get_ident:
[ 2558.352291] BUG: unable to handle kernel NULL pointer dereference at 00000072
[ 2558.352325] IP: [<c0223b19>] dnotify_flush+0x19/0x100
[ 2558.352344] *pde = 00000000
[ 2558.352354] Oops: 0000 [#1] SMP
[ 2558.352364] last sysfs file:
/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/voltage_now
[ 2558.352376] Modules linked in: netconsole ar6000 binfmt_misc rfcomm
sco bridge stp ppdev bnep sha256_generic l2cap arc4
snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep
snd_pcm_oss snd_mixer_oss snd_pcm snd_seq_dummy snd_seq_oss
snd_seq_midi joydev snd_rawmidi pcmcia iwlagn snd_seq_midi_event
snd_seq mmc_block yenta_socket iwlcore rsrc_nonstatic btusb sdhci_pci
snd_timer pcmcia_core sdhci snd_seq_device thinkpad_acpi tpm_tis
led_class tpm snd mac80211 psmouse bluetooth tpm_bios uvcvideo
soundcore snd_page_alloc videodev v4l1_compat nvram cfg80211 configfs
serio_raw iptable_filter lp ip_tables x_tables parport i915 fbcon
tileblit font bitblit softcursor radeon ttm drm_kms_helper drm usbhid
ohci1394 ieee1394 intel_agp e1000e i2c_algo_bit agpgart video output
[ 2558.352675]
[ 2558.352683] Pid: 1161, comm: Xorg Not tainted 2.6.34-rc7-300 #1
278225C/278225C
[ 2558.352691] EIP: 0060:[<c0223b19>] EFLAGS: 00013282 CPU: 1
[ 2558.352697] EIP is at dnotify_flush+0x19/0x100
[ 2558.352703] EAX: cccccccc EBX: eaf51b00 ECX: 00000000 EDX: eaf51b00
[ 2558.352712] ESI: e032e600 EDI: 00000000 EBP: f487df7c ESP: f487df68
[ 2558.352717] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
[ 2558.352727] Process Xorg (pid: 1161, ti=f487c000 task=f671bfc0
task.ti=f487c000)
[ 2558.352732] Stack:
[ 2558.352737] f487dfac c047a6f0 e032e600 eaf51b00 00000000 f487df94
c01f4027 fffffff7
[ 2558.352761] <0> eaf51b00 e032e600 00000012 f487dfac c01f40d3
eaf51b40 00000012 0c9ff878
[ 2558.352795] <0> 0c91c8c0 f487c000 c0102fa3 00000012 ffffffc8
081e5ff4 0c9ff878 0c91c8c0
[ 2558.352824] Call Trace:
[ 2558.352840] [<c047a6f0>] ? sys_socketcall+0x140/0x2a0
[ 2558.352853] [<c01f4027>] ? filp_close+0x37/0x70
[ 2558.352860] [<c01f40d3>] ? sys_close+0x73/0xb0
[ 2558.352868] [<c0102fa3>] ? sysenter_do_call+0x12/0x28
[ 2558.352882] [<c0550000>] ? __down_interruptible+0x60/0xb0
[ 2558.352888] Code: f7 ff ff eb b2 8d b6 00 00 00 00 8d bc 27 00 00
00 00 55 89 e5 83 ec 14 89 5d f4 89 d3 89 75 f8 89 c6 89 7d fc 8b 40
0c 8b 78 10 <0f> b7 47 72 25 00 f0 00 00 3d 00 40 00 00 74 0f 8b 5d f4
8b 75
[ 2558.353070] EIP: [<c0223b19>] dnotify_flush+0x19/0x100 SS:ESP 0068:f487df68
[ 2558.353083] CR2: 0000000000000072
[ 2558.353307] ---[ end trace 577d994b8fcc4773 ]---
[ 2558.362500] BUG: unable to handle kernel NULL pointer dereference at 00000010
[ 2558.362531] IP: [<c01c515c>] set_page_dirty+0x1c/0x60
[ 2558.362554] *pde = 00000000
[ 2558.362563] Oops: 0000 [#2] SMP
[ 2558.362576] last sysfs file:
/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/voltage_now
[ 2558.362586] Modules linked in: netconsole ar6000 binfmt_misc rfcomm
sco bridge stp ppdev bnep sha256_generic l2cap arc4
snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep
snd_pcm_oss snd_mixer_oss snd_pcm snd_seq_dummy snd_seq_oss
snd_seq_midi joydev snd_rawmidi pcmcia iwlagn snd_seq_midi_event
snd_seq mmc_block yenta_socket iwlcore rsrc_nonstatic btusb sdhci_pci
snd_timer pcmcia_core sdhci snd_seq_device thinkpad_acpi tpm_tis
led_class tpm snd mac80211 psmouse bluetooth tpm_bios uvcvideo
soundcore snd_page_alloc videodev v4l1_compat nvram cfg80211 configfs
serio_raw iptable_filter lp ip_tables x_tables parport i915 fbcon
tileblit font bitblit softcursor radeon ttm drm_kms_helper drm usbhid
ohci1394 ieee1394 intel_agp e1000e i2c_algo_bit agpgart video output
[ 2558.362892]
[ 2558.362901] Pid: 1161, comm: Xorg Tainted: G D
2.6.34-rc7-300 #1 278225C/278225C
[ 2558.362909] EIP: 0060:[<c01c515c>] EFLAGS: 00013282 CPU: 1
[ 2558.362920] EIP is at set_page_dirty+0x1c/0x60
[ 2558.362930] EAX: c13630c0 EBX: b69d1000 ECX: 4010007c EDX: 00000000
[ 2558.362936] ESI: 00030cd2 EDI: f4873744 EBP: f487dce0 ESP: f487dce0
[ 2558.362942] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
[ 2558.362949] Process Xorg (pid: 1161, ti=f487c000 task=f671bfc0
task.ti=f487c000)
[ 2558.362954] Stack:
[ 2558.362958] f487dd64 c01d5117 f487dd00 c0109f56 00000000 f652e600
f671bfc0 00000001
[ 2558.362985] <0> 00000000 c07f7440 00000000 c1903450 f487dd7c
b69d1fff eaa58b68 b69d2000
[ 2558.363017] <0> 1b106067 f671bfc0 f04394d0 00000000 b69d0000
c1691e6c c1903440 b69d2000
[ 2558.363049] Call Trace:
[ 2558.363061] [<c01d5117>] ? unmap_vmas+0x587/0x770
[ 2558.363072] [<c0109f56>] ? __switch_to_xtra+0xb6/0x140
[ 2558.363081] [<c01db1f0>] ? exit_mmap+0x90/0x150
[ 2558.363092] [<c014350e>] ? mmput+0x2e/0xb0
[ 2558.363100] [<c0147c90>] ? exit_mm+0xe0/0x100
[ 2558.363107] [<c0147f6c>] ? do_exit+0x10c/0x740
[ 2558.363118] [<c0146999>] ? kmsg_dump+0x119/0x130
[ 2558.363128] [<c0552430>] ? oops_end+0x90/0xd0
[ 2558.363138] [<c012960e>] ? no_context+0xbe/0x150
[ 2558.363147] [<c0204768>] ? set_fd_set+0x38/0x50
[ 2558.363155] [<c01296d7>] ? __bad_area_nosemaphore+0x37/0x160
[ 2558.363163] [<c012985a>] ? __bad_area+0x3a/0x50
[ 2558.363171] [<c0129882>] ? bad_area+0x12/0x20
[ 2558.363181] [<c05545b6>] ? do_page_fault+0x406/0x410
[ 2558.363191] [<c0164ad2>] ? __hrtimer_start_range_ns+0x162/0x410
[ 2558.363199] [<c05541b0>] ? do_page_fault+0x0/0x410
[ 2558.363207] [<c0551913>] ? error_code+0x73/0x80
[ 2558.363215] [<c0223b19>] ? dnotify_flush+0x19/0x100
[ 2558.363226] [<c047a6f0>] ? sys_socketcall+0x140/0x2a0
[ 2558.363237] [<c01f4027>] ? filp_close+0x37/0x70
[ 2558.363244] [<c01f40d3>] ? sys_close+0x73/0xb0
[ 2558.363252] [<c0102fa3>] ? sysenter_do_call+0x12/0x28
[ 2558.363263] [<c0550000>] ? __down_interruptible+0x60/0xb0
[ 2558.363268] Code: da eb 9b 8d b6 00 00 00 00 8d bf 00 00 00 00 55
8b 08 89 e5 8b 50 10 f7 c1 00 00 01 00 75 3f f6 c2 01 75 22 85 d2 74
1e 8b 52 38 <8b> 52 10 85 d2 74 0d ff d2 89 c2 89 d0 5d c3 90 8d 74 26
00 ba
[ 2558.363453] EIP: [<c01c515c>] set_page_dirty+0x1c/0x60 SS:ESP 0068:f487dce0
[ 2558.363470] CR2: 0000000000000010
[ 2558.363481] ---[ end trace 577d994b8fcc4774 ]---
[ 2558.363489] Fixing recursive fault but reboot is needed!
[ 2558.363497] BUG: scheduling while atomic: Xorg/1161/0x00000001
[ 2558.363502] Modules linked in: netconsole ar6000 binfmt_misc rfcomm
sco bridge stp ppdev bnep sha256_generic l2cap arc4
snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep
snd_pcm_oss snd_mixer_oss snd_pcm snd_seq_dummy snd_seq_oss
snd_seq_midi joydev snd_rawmidi pcmcia iwlagn snd_seq_midi_event
snd_seq mmc_block yenta_socket iwlcore rsrc_nonstatic btusb sdhci_pci
snd_timer pcmcia_core sdhci snd_seq_device thinkpad_acpi tpm_tis
led_class tpm snd mac80211 psmouse bluetooth tpm_bios uvcvideo
soundcore snd_page_alloc videodev v4l1_compat nvram cfg80211 configfs
serio_raw iptable_filter lp ip_tables x_tables parport i915 fbcon
tileblit font bitblit softcursor radeon ttm drm_kms_helper drm usbhid
ohci1394 ieee1394 intel_agp e1000e i2c_algo_bit agpgart video output
[ 2558.364031] Pid: 1161, comm: Xorg Tainted: G D 2.6.34-rc7-300 #1
[ 2558.364037] Call Trace:
[ 2558.364054] [<c0134d9d>] __schedule_bug+0x5d/0x70
[ 2558.364064] [<c054ed07>] schedule+0x647/0x7e0
[ 2558.364074] [<c0148518>] do_exit+0x6b8/0x740
[ 2558.364083] [<c0146999>] ? kmsg_dump+0x119/0x130
[ 2558.364090] [<c054e548>] ? printk+0x18/0x20
[ 2558.364100] [<c0552430>] oops_end+0x90/0xd0
[ 2558.364108] [<c012960e>] no_context+0xbe/0x150
[ 2558.364116] [<c01296d7>] __bad_area_nosemaphore+0x37/0x160
[ 2558.364124] [<c0129812>] bad_area_nosemaphore+0x12/0x20
[ 2558.364132] [<c0554518>] do_page_fault+0x368/0x410
[ 2558.364141] [<c01c6860>] ? release_pages+0x190/0x1c0
[ 2558.364149] [<c05541b0>] ? do_page_fault+0x0/0x410
[ 2558.364156] [<c0551913>] error_code+0x73/0x80
[ 2558.364164] [<c012007b>] ? mask_IO_APIC_setup+0x9b/0xa0
[ 2558.364171] [<c01c515c>] ? set_page_dirty+0x1c/0x60
[ 2558.364183] [<c01d5117>] unmap_vmas+0x587/0x770
[ 2558.364194] [<c0109f56>] ? __switch_to_xtra+0xb6/0x140
[ 2558.364203] [<c01db1f0>] exit_mmap+0x90/0x150
[ 2558.364211] [<c014350e>] mmput+0x2e/0xb0
[ 2558.364217] [<c0147c90>] exit_mm+0xe0/0x100
[ 2558.364229] [<c0147f6c>] do_exit+0x10c/0x740
[ 2558.364237] [<c0146999>] ? kmsg_dump+0x119/0x130
[ 2558.364244] [<c0552430>] oops_end+0x90/0xd0
[ 2558.364252] [<c012960e>] no_context+0xbe/0x150
[ 2558.364261] [<c0204768>] ? set_fd_set+0x38/0x50
[ 2558.364268] [<c01296d7>] __bad_area_nosemaphore+0x37/0x160
[ 2558.364276] [<c012985a>] __bad_area+0x3a/0x50
[ 2558.364282] [<c0129882>] bad_area+0x12/0x20
[ 2558.364290] [<c05545b6>] do_page_fault+0x406/0x410
[ 2558.364300] [<c0164ad2>] ? __hrtimer_start_range_ns+0x162/0x410
[ 2558.364308] [<c05541b0>] ? do_page_fault+0x0/0x410
[ 2558.364315] [<c0551913>] error_code+0x73/0x80
[ 2558.364323] [<c0223b19>] ? dnotify_flush+0x19/0x100
[ 2558.364333] [<c047a6f0>] ? sys_socketcall+0x140/0x2a0
[ 2558.364344] [<c01f4027>] filp_close+0x37/0x70
[ 2558.364352] [<c01f40d3>] sys_close+0x73/0xb0
[ 2558.364359] [<c0102fa3>] sysenter_do_call+0x12/0x28
[ 2558.364370] [<c0550000>] ? __down_interruptible+0x60/0xb0
[ 2558.365152] init[1]: segfault at 0 ip (null) sp bfb4ba94 error 4 in
libnss_files-2.10.1.so[b74db000+a000]
--
Haijun Liu
^ permalink raw reply
* Re: [PATCH 2/2 v2] Bluetooth: Fix system crash bug of no send queue protect
From: haijun liu @ 2010-10-25 2:15 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: Haijun Liu, linux-bluetooth
In-Reply-To: <20101022173411.GB980@vigoh>
Hi Gustavo,
>> During test session with another vendor's bt stack, found that
>> without lock protect for TX_QUEUE(sk) will cause system crash while
>> data transfer over AMP controller. So I just add lock protect for
>> TX_QUEUE(sk).
>
> We already use the default socket lock protection. Is it not working for
> you? Why? Could you show a crash case that requires your patch to fix
> it?
>
Yes, there is socket lock protection, but only for sk_buff, for the related
variable we need protect them as well, such as 'sk->sk_send_head',
because later in different context we will use it as sk_buff directly, but at
that time maybe it has been freed and that buffer be occupied by another
sk_buff.
Below is the crash case we met:
[ 265.544145] l2cap_sock_sendmsg: sock e7f4e380, sk e015fc00, msg
e01f5ea4, len 1668
[ 265.544149] l2cap_sock_sendmsg: sk->scid 42, sk->dcid 5d, sk->mode 3
[ 265.544157] block_sendmsg_condition:
[ 265.544160] l2cap_tx_window_full:
[ 265.544163] block_sendmsg_condition: tx_window full: 0, or
wait_f/remote busy.
[ 265.544168] l2cap_sar_segment_sdu: sk e015fc00 len 5736
[ 265.544172] l2cap_create_iframe_pdu: sk e015fc00 len 1011 control
4000 sdulen 5736
[ 265.544175] l2cap_loglink_validate:
[ 265.544179] l2cap_skbuff_fromiovec:
[ 265.544183] l2cap_create_iframe_pdu: sk e015fc00 len 1011 control
c000 sdulen 0
[ 265.544187] l2cap_loglink_validate:
[ 265.544191] l2cap_skbuff_fromiovec:
[ 265.544195] l2cap_create_iframe_pdu: sk e015fc00 len 1011 control
c000 sdulen 0
[ 265.544200] l2cap_loglink_validate:
[ 265.544203] l2cap_skbuff_fromiovec:
[ 265.544207] l2cap_create_iframe_pdu: sk e015fc00 len 1011 control
c000 sdulen 0
[ 265.544211] l2cap_loglink_validate:
[ 265.544214] l2cap_skbuff_fromiovec:
[ 265.544218] l2cap_create_iframe_pdu: sk e015fc00 len 1011 control
c000 sdulen 0
[ 265.544221] l2cap_loglink_validate:
[ 265.544225] l2cap_skbuff_fromiovec:
[ 265.544229] l2cap_create_iframe_pdu: sk e015fc00 len 681 control
8000 sdulen 0
[ 265.544252] l2cap_loglink_validate:
[ 265.544255] l2cap_skbuff_fromiovec:
[ 265.544483] l2cap_recv_acldata:
[ 265.544488] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.544492] l2cap_recv_frame: conn f461bcc0, skb ee91ccc0, cid 42, len 4
[ 265.544496] l2cap_recv_frame: len 4, cid 0x0042
[ 265.544498] l2cap_data_channel:
[ 265.544501] l2cap_get_chan_by_scid:
[ 265.544504] __l2cap_get_chan_by_scid:
[ 265.544508] l2cap_data_channel: sk e015fc00, len 4
[ 265.544511] l2cap_ertm_data_rcv:
[ 265.544514] l2cap_check_fcs:
[ 265.544517] l2cap_data_channel_sframe: sk e015fc00 rx_control 0x2209 len 0
[ 265.544521] l2cap_data_channel_rnrframe: sk e015fc00, req_seq 34 ctrl 0x2209
[ 265.544525] l2cap_drop_acked_frames:
[ 265.544636] l2cap_recv_acldata:
[ 265.544641] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.544645] l2cap_recv_frame: conn f461bcc0, skb ee91c6c0, cid 42, len 4
[ 265.544649] l2cap_recv_frame: len 4, cid 0x0042
[ 265.544652] l2cap_data_channel:
[ 265.544655] l2cap_get_chan_by_scid:
[ 265.544657] __l2cap_get_chan_by_scid:
[ 265.570492] l2cap_recv_acldata:
[ 265.570503] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.570507] l2cap_recv_frame: conn f461bcc0, skb ee91c0c0, cid 42, len 4
[ 265.570513] l2cap_recv_frame: len 4, cid 0x0042
[ 265.570517] l2cap_data_channel:
[ 265.570520] l2cap_get_chan_by_scid:
[ 265.570524] __l2cap_get_chan_by_scid:
[ 265.570529] l2cap_data_channel: sk e015fc00, len 4
[ 265.570533] l2cap_ertm_data_rcv:
[ 265.570536] l2cap_check_fcs:
[ 265.570542] l2cap_data_channel_sframe: sk e015fc00 rx_control 0x2709 len 0
[ 265.570547] l2cap_data_channel_rnrframe: sk e015fc00, req_seq 39 ctrl 0x2709
[ 265.570550] l2cap_drop_acked_frames:
[ 265.570658] l2cap_recv_acldata:
[ 265.570663] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.570668] l2cap_recv_frame: conn f461bcc0, skb ee91ca80, cid 42, len 4
[ 265.570673] l2cap_recv_frame: len 4, cid 0x0042
[ 265.570677] l2cap_data_channel:
[ 265.570680] l2cap_get_chan_by_scid:
[ 265.570683] __l2cap_get_chan_by_scid:
[ 265.570687] l2cap_data_channel: sk e015fc00, len 4
[ 265.570691] l2cap_ertm_data_rcv:
[ 265.570694] l2cap_check_fcs:
[ 265.570698] l2cap_data_channel_sframe: sk e015fc00 rx_control 0x2809 len 0
[ 265.570702] l2cap_data_channel_rnrframe: sk e015fc00, req_seq 40 ctrl 0x2809
[ 265.570706] l2cap_drop_acked_frames:
[ 265.570858] l2cap_recv_acldata:
[ 265.572903] l2cap_recv_acldata:
[ 265.572910] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.572915] l2cap_recv_frame: conn f461bcc0, skb f469fa80, cid 42, len 4
[ 265.572919] l2cap_recv_frame: len 4, cid 0x0042
[ 265.572921] l2cap_data_channel:
[ 265.572925] l2cap_get_chan_by_scid:
[ 265.572928] __l2cap_get_chan_by_scid:
[ 265.572933] l2cap_data_channel: sk e015fc00, len 4
[ 265.572936] l2cap_ertm_data_rcv:
[ 265.572938] l2cap_check_fcs:
[ 265.572943] l2cap_data_channel_sframe: sk e015fc00 rx_control 0x2b09 len 0
[ 265.573348] l2cap_recv_acldata:
[ 265.609993] l2cap_recv_acldata:
[ 265.610005] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.610009] l2cap_recv_frame: conn f461bcc0, skb ee91c540, cid 42, len 4
[ 265.610013] l2cap_recv_frame: len 4, cid 0x0042
[ 265.610016] l2cap_data_channel:
[ 265.610019] l2cap_get_chan_by_scid:
[ 265.610022] __l2cap_get_chan_by_scid:
[ 265.610025] l2cap_data_channel: sk e015fc00, len 4
[ 265.610029] l2cap_ertm_data_rcv:
[ 265.610032] l2cap_check_fcs:
[ 265.610036] l2cap_data_channel_sframe: sk e015fc00 rx_control 0x3801 len 0
[ 265.610041] l2cap_data_channel_rrframe: sk e015fc00, req_seq 56 ctrl 0x3801
[ 265.610044] l2cap_drop_acked_frames:
[ 265.610060] l2cap_ertm_send: sk e015fc00, sk->scid 42, sk->dcid 5d
[ 265.610064] l2cap_tx_window_full:
[ 265.610071] l2cap_ertm_send: pi->next_tx_seq: 13, pi->buffer_seq: 2
[ 265.610075] l2cap_do_send: sk e015fc00, cid 66 skb e0147840 len 1019
[ 265.610078] l2cap_loglink_validate:
[ 265.610081] l2cap_do_send: send I frame over AMP controller
[ 265.610085] l2cap_tx_window_full:
[ 265.610093] l2cap_ertm_send: pi->next_tx_seq: 14, pi->buffer_seq: 2
[ 265.610096] l2cap_do_send: sk e015fc00, cid 66 skb f4801cc0 len 1019
[ 265.610099] l2cap_loglink_validate:
[ 265.610102] l2cap_do_send: send I frame over AMP controller
[ 265.610105] l2cap_tx_window_full:
[ 265.610112] l2cap_ertm_send: pi->next_tx_seq: 15, pi->buffer_seq: 2
[ 265.610115] l2cap_do_send: sk e015fc00, cid 66 skb f4801600 len 1019
[ 265.610118] l2cap_loglink_validate:
[ 265.610121] l2cap_do_send: send I frame over AMP controller
[ 265.610124] l2cap_tx_window_full:
[ 265.610130] l2cap_ertm_send: pi->next_tx_seq: 16, pi->buffer_seq: 2
[ 265.610133] l2cap_do_send: sk e015fc00, cid 66 skb f4801c00 len 689
[ 265.610137] l2cap_loglink_validate:
[ 265.610140] l2cap_do_send: send I frame over AMP controller
[ 265.610143] l2cap_tx_window_full:
[ 265.610153] l2cap_ertm_send: pi->next_tx_seq: 17, pi->buffer_seq: 2
[ 265.610215] l2cap_ertm_send: pi->next_tx_seq: 20, pi->buffer_seq: 2
[ 265.610219] l2cap_do_send: sk e015fc00, cid 66 skb f47f03c0 len 1019
[ 265.610222] l2cap_loglink_validate:
[ 265.619937] l2cap_recv_acldata:
[ 265.619948] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.619952] l2cap_recv_frame: conn f461bcc0, skb ee91c300, cid 42, len 4
[ 265.619956] l2cap_recv_frame: len 4, cid 0x0042
[ 265.620154] l2cap_ertm_send: pi->next_tx_seq: 29, pi->buffer_seq: 2
[ 265.629111] l2cap_recv_acldata:
[ 265.629123] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.639371] l2cap_recv_acldata:
[ 265.639384] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.639388] l2cap_recv_frame: conn f461bcc0, skb ee91ccc0, cid 42, len 4
[ 265.639392] l2cap_recv_frame: len 4, cid 0x0042
[ 265.639395] l2cap_data_channel:
[ 265.639398] l2cap_get_chan_by_scid:
[ 265.639401] __l2cap_get_chan_by_scid:
[ 265.639405] l2cap_data_channel: sk e015fc00, len 4
[ 265.639407] l2cap_ertm_data_rcv:
[ 265.639570] l2cap_do_send: send I frame over AMP controller
[ 265.646669] l2cap_recv_acldata:
[ 265.646681] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.646685] l2cap_recv_frame: conn f461bcc0, skb ee91c6c0, cid 42, len 4
[ 265.646822] l2cap_loglink_validate:
[ 265.646825] l2cap_skbuff_fromiovec:
[ 265.647800] l2cap_recv_acldata:
[ 265.647808] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.649645] l2cap_recv_acldata:
[ 265.649655] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.649659] l2cap_recv_frame: conn f461bcc0, skb ee91c180, cid 42, len 4
[ 265.649663] l2cap_recv_frame: len 4, cid 0x0042
[ 265.651518] l2cap_recv_acldata:
[ 265.651527] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.651532] l2cap_recv_frame: conn f461bcc0, skb ee91c0c0, cid 42, len 4
[ 265.655539] l2cap_recv_acldata:
[ 265.655547] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.655550] l2cap_recv_frame: conn f461bcc0, skb e035bc00, cid 42, len 4
[ 265.655554] l2cap_recv_frame: len 4, cid 0x0042
[ 265.655556] l2cap_data_channel:
[ 265.655559] l2cap_get_chan_by_scid:
[ 265.655562] __l2cap_get_chan_by_scid:
[ 265.663270] l2cap_recv_acldata:
[ 265.663276] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.667987] l2cap_recv_acldata:
[ 265.673206] l2cap_recv_acldata:
[ 265.673217] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.673221] l2cap_recv_frame: conn f461bcc0, skb ee91c780, cid 42, len 4
[ 265.673225] l2cap_recv_frame: len 4, cid 0x0042
[ 265.673227] l2cap_data_channel:
[ 265.673230] l2cap_get_chan_by_scid:
[ 265.673233] __l2cap_get_chan_by_scid:
[ 265.673236] l2cap_data_channel: sk e015fc00, len 4
[ 265.673240] l2cap_ertm_data_rcv:
[ 265.673243] l2cap_check_fcs:
[ 265.673247] l2cap_data_channel_sframe: sk e015fc00 rx_control 0x3109 len 0
[ 265.675265] l2cap_recv_acldata:
[ 265.675273] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.691337] l2cap_recv_acldata:
[ 265.691348] l2cap_recv_acldata: conn f461bcc0 len 8 flags 0x3
[ 265.691352] l2cap_recv_frame: conn f461bcc0, skb ee91c000, cid 42, len 4
[ 265.691356] l2cap_recv_frame: len 4, cid 0x0042
[ 265.691359] l2cap_data_channel:
[ 265.691362] l2cap_get_chan_by_scid:
[ 265.691366] __l2cap_get_chan_by_scid:
[ 265.691369] l2cap_data_channel: sk e015fc00, len 4
[ 265.691372] l2cap_ertm_data_rcv:
[ 265.691375] l2cap_check_fcs:
[ 265.691379] l2cap_data_channel_sframe: sk e015fc00 rx_control 0x3511 len 0
[ 265.691383] l2cap_data_channel_rrframe: sk e015fc00, req_seq 53 ctrl 0x3511
[ 265.691386] l2cap_drop_acked_frames:
[ 265.691389] l2cap_send_i_or_rr_or_rnr:
[ 265.691392] l2cap_ertm_send: sk e015fc00, sk->scid 42, sk->dcid 5d
[ 265.691396] l2cap_tx_window_full:
[ 265.691400] l2cap_ertm_send: pi->next_tx_seq: 53, pi->buffer_seq: 2
[ 265.691404] l2cap_do_send: sk e015fc00, cid 66 skb e0204000 len 101
[ 265.691407] l2cap_loglink_validate:
[ 265.691410] l2cap_do_send: send I frame over AMP controller
[ 265.691415] skb_under_panic: text:f8224a57 len:105 put:4
head:e002ba00 data:e002b9fe tail:0xe002ba2c end:0xe002ba80 dev:瘗"?
[ 265.691443] ------------[ cut here ]------------
[ 265.691446] kernel BUG at net/core/skbuff.c:147!
[ 265.691450] invalid opcode: 0000 [#1] SMP
[ 265.691456] last sysfs file:
/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/energy_full
[ 265.691460] Modules linked in:[ 265.692743] [<f822573e>]
hci_rx_task+0x2de/0x380 [bluetooth]
[ 265.692748] [<c0132921>] ? __dequeue_entity+0x21/0x40
[ 265.696007] NOHZ: local_softirq_pending 0e
>From above context, we know we expect a skb with length 1019(1011+8),
but dump context tell us, the len is 105.
--
Haijun Liu
^ 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