Linux bluetooth development
 help / color / mirror / Atom feed
* [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

* Re: [PATCH 1/2 v2] Bluetooth: Fix system crash caused by del_timer()
From: haijun liu @ 2010-10-25  1:35 UTC (permalink / raw)
  To: Gustavo F. Padovan; +Cc: Haijun Liu, linux-bluetooth
In-Reply-To: <20101022171825.GA980@vigoh>

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.

Let's think about it and come up a good solution for this situation.

-- 
Haijun Liu

^ permalink raw reply

* Re: (Health) ChannelConnected signal when MDL aborted?
From: Elvis Pfützenreuter @ 2010-10-24 18:44 UTC (permalink / raw)
  To: Santiago Carot; +Cc: linux-bluetooth
In-Reply-To: <AANLkTikLByb4qKBJP_iBUw2H0EqLo1MA9bttLwBO9s-u@mail.gmail.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 :)

^ permalink raw reply

* Re: (Health) ChannelConnected signal when MDL aborted?
From: Elvis Pfützenreuter @ 2010-10-24 17:50 UTC (permalink / raw)
  To: Jose Antonio Santos Cadenas; +Cc: Santiago Carot, linux-bluetooth
In-Reply-To: <AANLkTiknmbF78BgGH+KBTfjEvw4rqLVxu3Nnhg3nshB7@mail.gmail.com>

> Sorry, you are right about that, reconnections are not mantadory in
> all cases for sources. May be we should check this flags before
> keeping the state and emitting the signal.

This could be useful even in this case of MDL abort X ChannelConnected signal. If the flags say that device is incapable of reconnections, definetively no point in emitting the signal.

But I am not sure if you will have the SDP record at hand to do this check, at that moment; certainly not worth forcing a SDP query just to round these particular corner cases.

^ permalink raw reply

* Re: (Health) ChannelConnected signal when MDL aborted?
From: Jose Antonio Santos Cadenas @ 2010-10-24 15:19 UTC (permalink / raw)
  To: Elvis Pfützenreuter; +Cc: Santiago Carot, linux-bluetooth
In-Reply-To: <3511AB9E-2F29-4E9C-845A-674A3EA437E7@signove.com>

2010/10/24 Elvis Pfützenreuter <epx@signove.com>:
> Hello,
>
>> In that case, the problem is in the remote side, because the Bluetooth
>> SIG certification requires the devices to support reconnections, so
>> the problem is not in our side but in the remote side that isn't
>> compliant with the standard. I think we don't  have to change our
>> implementation regarding buggy devices that don't follow the
>> specification correctly.
>
> I think an HDP device is NOT required to support reconnections. In HDP spec item 5.2.11   there is that bitmap in SDP record that says whether device supports reconnections and CSP.

Sorry, you are right about that, reconnections are not mantadory in
all cases for sources. May be we should check this flags before
keeping the state and emitting the signal.

>
>> More over, the situation that you mention. When receiving a
>> ChannelDeletion, the application shouldn't close the data channel,
>> because the in the normal situation, the DBus object for the data
>> channel will be removed, so no closing of the channel will be
>> performed, the only thing that should happen is that the application
>> will "forget" about this channel. When the second ChannelConnected is
>> received, the application will typically perform an acquire that, in
>> this case, will be very simple because the channel will be already
>> connected and the fd will be transmitted.
>
> So the application must follow a very specific behaviour when handling a ChannelDeleted signal, and worse yet, it must do it to fix a problem that we could fix simply by changing the way channel paths are named.
>

The only thing that the application should do when receiving a
ChannelDeleted signal is to forget about this channel because the
Channel object does not exists any more and no more calls to the
channel API could be done. Nevertheless if you close the fd get from
the Acquire petition, nothing will happen to the new channel, because
the new channel has a new btiochannel. I have to experiment with this
to be completely sure and see how DBus fd-passing deals with this, but
everything points that nothing will happen when closing the previous
get fd.

> If it was the case that we simply could not change the channel path naming, this behaviour should at least written very clearly in API.
>
>> In general, I think, guys, that we are thinking again in very estrange
>> situations. As we said in the Recife's meeting we should design the
>> implementation and the API for working with compliants devices, not
>> with buggy ones and also we have to simplify the use for the API,
>> making it simple for the application programmers in the most usual
>> cases not in the strange ones, that will happen very rarely.
>
> It's weekend, and playing devil's advocate is fun :P
>
> Seriously now, my objective is the same, avoiding that a perfectly sensible application act (closing fd after receiving a ChannelDeleted event) causing a race condition. And IMHO a condition that may happen with compliant devices as well.

Let's see what fd-passing is managing the fd and decide having this
data. Tomorrow I'll experiment with this and reply to the list with
the results.

Regards.

Jose

^ permalink raw reply

* Re: (Health) ChannelConnected signal when MDL aborted?
From: Elvis Pfützenreuter @ 2010-10-24 13:28 UTC (permalink / raw)
  To: Jose Antonio Santos Cadenas; +Cc: Santiago Carot, linux-bluetooth
In-Reply-To: <AANLkTim3m1ogwwx5MqF+z1FDKn4w3xHEN7MOAO5iW_ms@mail.gmail.com>

Hello,

> In that case, the problem is in the remote side, because the Bluetooth
> SIG certification requires the devices to support reconnections, so
> the problem is not in our side but in the remote side that isn't
> compliant with the standard. I think we don't  have to change our
> implementation regarding buggy devices that don't follow the
> specification correctly.

I think an HDP device is NOT required to support reconnections. In HDP spec item 5.2.11   there is that bitmap in SDP record that says whether device supports reconnections and CSP.

> More over, the situation that you mention. When receiving a
> ChannelDeletion, the application shouldn't close the data channel,
> because the in the normal situation, the DBus object for the data
> channel will be removed, so no closing of the channel will be
> performed, the only thing that should happen is that the application
> will "forget" about this channel. When the second ChannelConnected is
> received, the application will typically perform an acquire that, in
> this case, will be very simple because the channel will be already
> connected and the fd will be transmitted.

So the application must follow a very specific behaviour when handling a ChannelDeleted signal, and worse yet, it must do it to fix a problem that we could fix simply by changing the way channel paths are named.

If it was the case that we simply could not change the channel path naming, this behaviour should at least written very clearly in API.

> In general, I think, guys, that we are thinking again in very estrange
> situations. As we said in the Recife's meeting we should design the
> implementation and the API for working with compliants devices, not
> with buggy ones and also we have to simplify the use for the API,
> making it simple for the application programmers in the most usual
> cases not in the strange ones, that will happen very rarely.

It's weekend, and playing devil's advocate is fun :P 

Seriously now, my objective is the same, avoiding that a perfectly sensible application act (closing fd after receiving a ChannelDeleted event) causing a race condition. And IMHO a condition that may happen with compliant devices as well.

^ permalink raw reply

* 4.76 possible regression: bluetoothd segfaults when launching bluetooth programs
From: Ilya Basin @ 2010-10-24 12:38 UTC (permalink / raw)
  To: linux-bluetooth

[-- Attachment #1: Type: text/plain, Size: 1232 bytes --]

It all started after upgrading bluez from 4.69 to 4.76 .
'hcitool scan' work and bluetoothd starts normally, but when launching
any related program (e.g. Gnome bluetooth-applet), bluetoothd dies with segfault:
  Oct 24 11:31:01 IL kernel: bluetoothd[3894]: segfault at 0 ip
  b7632653 sp bfee9b5c error 4 in libc-2.12.1.so[b75be000+145000]

Downgrading to 4.69 helps, I don't even have to reboot, just
restarting bluetoothd

Additional info:
* package version(s)
kernel26 2.6.35.7
bluez 4.76
dbus 1.4.0

$ lsusb | grep lue
Bus 003 Device 002: ID 0a5c:2121 Broadcom Corp. BCM2210 Bluetooth

Compiled with debug flags, gdb output attached
dbus_message_iter_append_basic () is called 7 times after another bt
program starts.
Params seem valid:

Breakpoint 1, 0xb7e4e616 in dbus_message_iter_append_basic () from /usr/lib/libdbus-1.so.3
(gdb) print (void*)($esp+0)
$1 = (void *) 0xbffff3c0
(gdb) print *(char*)($esp+4)
$2 = 115 's'
(gdb) print **(char***)($esp+8)
$3 = 0xb80474f0 "0000110e-0000-1000-8000-00805f9b34fb"
(gdb) finish
Run till exit from #0  0xb7e4e616 in dbus_message_iter_append_basic () from /usr/lib/libdbus-1.so.3

Program received signal SIGSEGV, Segmentation fault.
0xb7d3e653 in strlen () from /lib/libc.so.6
(gdb) 

[-- Attachment #2: gdb.txt --]
[-- Type: TEXT/PLAIN, Size: 3007 bytes --]

[root@IL packages]# gdb --args /home/il/builds/bluez-debug/src/src/bluez-4.76/src/.libs/bluetoothd -n
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /.snapshots/persist/builds/bluez-debug/src/src/bluez-4.76/src/.libs/bluetoothd...(no debugging symbols found)...done.
(gdb) r
Starting program: /.snapshots/persist/builds/bluez-debug/src/src/bluez-4.76/src/.libs/bluetoothd -n
[Thread debugging using libthread_db enabled]
bluetoothd[20561]: Bluetooth deamon 4.76
bluetoothd[20561]: Starting SDP server
bluetoothd[20561]: HCI dev 0 registered
bluetoothd[20561]: HCI dev 0 up
bluetoothd[20561]: Starting security manager 0
bluetoothd[20561]: Clearing blocked list failed: Invalid argument (22)
bluetoothd[20561]: probe failed with driver input-headset for device /org/bluez/20561/hci0/dev_00_1B_98_A3_A5_2B
bluetoothd[20561]: probe failed with driver input-headset for device /org/bluez/20561/hci0/dev_00_1D_6E_4F_54_EA
bluetoothd[20561]: probe failed with driver input-headset for device /org/bluez/20561/hci0/dev_A8_7E_33_D7_29_DB
bluetoothd[20561]: Adapter /org/bluez/20561/hci0 has been enabled
bluetoothd[20561]: Inquiry Failed with status 0x12
^C
Program received signal SIGINT, Interrupt.
0xb7f73424 in __kernel_vsyscall ()
(gdb) b dbus_message_iter_append_basic
Breakpoint 1 at 0xb7e4e616
(gdb) c
Continuing.

====================
here i start another program
====================

Breakpoint 1, 0xb7e4e616 in dbus_message_iter_append_basic () from /usr/lib/libdbus-1.so.3
(gdb) c 6
Will ignore next 5 crossings of breakpoint 1.  Continuing.

Breakpoint 1, 0xb7e4e616 in dbus_message_iter_append_basic () from /usr/lib/libdbus-1.so.3
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0xb7d3e653 in strlen () from /lib/libc.so.6
(gdb) bt
#0  0xb7d3e653 in strlen () from /lib/libc.so.6
#1  0xb7e5eb10 in ?? () from /usr/lib/libdbus-1.so.3
#2  0xb7e4a34b in ?? () from /usr/lib/libdbus-1.so.3
#3  0xb7e4e7a9 in dbus_message_iter_append_basic () from /usr/lib/libdbus-1.so.3
#4  0xb7fef03d in append_array_variant ()
#5  0xb7fef799 in emit_array_property_changed ()
#6  0xb7fe4de4 in adapter_service_ins_rem ()
#7  0xb7fd7fb1 in sdp_record_add ()
#8  0xb7fd79de in service_register_req ()
#9  0xb7fd5dfc in handle_request ()
#10 0xb7fd496e in io_session_event ()
#11 0xb7ef7a2b in ?? () from /usr/lib/libglib-2.0.so.0
#12 0xb7eb0b72 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#13 0xb7eb1350 in ?? () from /usr/lib/libglib-2.0.so.0
#14 0xb7eb1a1b in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
#15 0xb7fd1bbd in main ()
(gdb) 


^ permalink raw reply

* Re: (Health) ChannelConnected signal when MDL aborted?
From: Jose Antonio Santos Cadenas @ 2010-10-24 12:10 UTC (permalink / raw)
  To: Elvis Pfützenreuter; +Cc: Santiago Carot, linux-bluetooth
In-Reply-To: <4B999390-7FFB-4B90-98BA-D9F9C17771F5@signove.com>

2010/10/23 Elvis Pfützenreuter <epx@signove.com>:
>> You are forgetting that there may be more than one health applications
>> running over HDP at the same time, if one of them creates a data
>> channel, that data data channel will be exist at MCAP level even if
>> the initiator abort the connection. If other application wants to
>> create a new data channel with the same configuration, it may be want
>> reconnect that data channel avoiding to create another data channel.
>> It is a best practise wich is recomended in MCAP and best explained in
>> the Health Device Profile white paper document to reduce the amount of
>> data interchanged between medical devices (in IEEE/11073-20601
>> terminology: "agents" and "managers"). Remember that channels may be
>> shared between applications.
>
> I'm still not convinced :) I can't see the point of sharing a HealthChannel that is not healthy (pardon the joke).
>
> Maybe I'm being too pragmatic, but I expect that most real HDP devices will be like that Nonin oximeter: incapable of reconnecting MDLs and incapable of accepting connections. Sharing a channel in that situation will make spend much more, not less, energy, because applications will Acquire() and trigger a reconnection over a channel that actually does not exist and wouldn't be accepted even if it existed.

In that case, the problem is in the remote side, because the Bluetooth
SIG certification requires the devices to support reconnections, so
the problem is not in our side but in the remote side that isn't
compliant with the standard. I think we don't  have to change our
implementation regarding buggy devices that don't follow the
specification correctly.

>
> Anyway, MDL aborts are expected to be rare, so the actual problem won't be seen often in practice.

In the other hand is this reason you mention, this is a very estrange
situation, so I don't think that the behaviour that we take will be
very important. In fact I don't think that this situation will happen
ever. In the case of the oximeter if it doesn't reconnect data
channels I think that it won't never send an abort or any other
abnormal command.

>
> I think we have another, more important problem: naming the channel after MDLID.
>
> For example, the channel that comes from oximeter has always the same path here: /org/bluez/19750/hci0/dev_00_1C_05_00_28_85/chan1. It is incapable of reconnections but always recreates the MDL with the same MDL ID = 1.
>
> Now, let's suppose a MDL is created, destroyed and re-created, but for some reason the application the application takes too long to act upon the signal. You have three signals:
>
> ChannelConnected chan1
> ChannelDeleted chan1
> ChannelConnected chan1 (a second channel with the same MDL ID)
>
> Application will Acquire() on first signal, thinking it is getting the FD for the first instance of chan1, but it will actually get the FD for the second "version" of chan1.
>
> Then it will process the ChannelDeleted signal, closing a perfectly good channel. And then it sees the third signal, and tries the Acquire() the fd it has just closed. If the other side tries to reconnect immediately but does not support MCAP reconnections, this could go on forever.
>
> A possible solution is to use a monotonic number for the channel path suffix, without relation to MDL ID.

I don't think that this naming is a problem. Think that using the same
id that the real channel is using guarantees us that all the active
channels are using unique IDs in a very "cheap" way, because is MCAP
who's dealing with the id's assignment.

More over, the situation that you mention. When receiving a
ChannelDeletion, the application shouldn't close the data channel,
because the in the normal situation, the DBus object for the data
channel will be removed, so no closing of the channel will be
performed, the only thing that should happen is that the application
will "forget" about this channel. When the second ChannelConnected is
received, the application will typically perform an acquire that, in
this case, will be very simple because the channel will be already
connected and the fd will be transmitted.

In general, I think, guys, that we are thinking again in very estrange
situations. As we said in the Recife's meeting we should design the
implementation and the API for working with compliants devices, not
with buggy ones and also we have to simplify the use for the API,
making it simple for the application programmers in the most usual
cases not in the strange ones, that will happen very rarely.

Regards.

^ permalink raw reply

* Re: (Health) ChannelConnected signal when MDL aborted?
From: Santiago Carot @ 2010-10-24  8:40 UTC (permalink / raw)
  To: Elvis Pfützenreuter; +Cc: Jose Antonio Santos Cadenas, linux-bluetooth
In-Reply-To: <AANLkTikLByb4qKBJP_iBUw2H0EqLo1MA9bttLwBO9s-u@mail.gmail.com>

2010/10/24 Santiago Carot <sancane@gmail.com>:
> Hi,
>
> 2010/10/23 Elvis Pfützenreuter <epx@signove.com>:
>>> You are forgetting that there may be more than one health applications
>>> running over HDP at the same time, if one of them creates a data
>>> channel, that data data channel will be exist at MCAP level even if
>>> the initiator abort the connection. If other application wants to
>>> create a new data channel with the same configuration, it may be want
>>> reconnect that data channel avoiding to create another data channel.
>>> It is a best practise wich is recomended in MCAP and best explained in
>>> the Health Device Profile white paper document to reduce the amount of
>>> data interchanged between medical devices (in IEEE/11073-20601
>>> terminology: "agents" and "managers"). Remember that channels may be
>>> shared between applications.
>>
>> I'm still not convinced :) I can't see the point of sharing a HealthChannel that is not healthy (pardon the joke).
>
> 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.
>
> HDP specification says:
> * The first Data Channel opened on a given MCL shall be a Reliable Data Channel.
> * Association traffic shall be carried on the first Reliable Data
> Channel that was
> opened on a given MCL.
>
> Next you are a text fragment copied from white paper (Alluding to the
> example where there are two applications on HDP):
>  "...The right side of the diagram shows two devices that typically
> both use Reliable Data Channels. In this
> case, the devices may share a common Reliable Data Channel (and MDL)
> for all data or may optionally
> have separate MDLs for their data, but share the first Reliable Data
> Channel for IEEE association and
> confirmed event traffic..."
>
>
>>
>> Maybe I'm being too pragmatic, but I expect that most real HDP devices will be like that Nonin oximeter: incapable of reconnecting MDLs and incapable of accepting connections. Sharing a channel in that situation will make spend much more, not less, energy, because applications will Acquire() and trigger a reconnection over a channel that actually does not exist and wouldn't be accepted even if it existed.
>
> There are not only Nonin oximeter devices, we have a blood pressure
> that reconnect data channels, in the past we played with a weighing
> scale wich it was waiting for data channel connections, besides it is
> expected more complex devices such as electrocardiograms, and also you
> should think about what will happen if somebody uses this
> implementation to develop a health device specialization?, for
> example, I thinking in smartphones with sensors, etc... IMHO it is
> very presumptuous to make such assumptions about the future (may be I
> am too idealist) :P
>
>>
>> Anyway, MDL aborts are expected to be rare, so the actual problem won't be seen often in practice.
>>
>> I think we have another, more important problem: naming the channel after MDLID.
>>
>> For example, the channel that comes from oximeter has always the same path here: /org/bluez/19750/hci0/dev_00_1C_05_00_28_85/chan1. It is incapable of reconnections but always recreates the MDL with the same MDL ID = 1.
>>
>> Now, let's suppose a MDL is created, destroyed and re-created, but for some reason the application the application takes too long to act upon the signal. You have three signals:
>>
>> ChannelConnected chan1
>> ChannelDeleted chan1
>> ChannelConnected chan1 (a second channel with the same MDL ID)
>>
>> Application will Acquire() on first signal, thinking it is getting the FD for the first instance of chan1, but it will actually get the FD for the second "version" of chan1.
>>
>> Then it will process the ChannelDeleted signal, closing a perfectly good channel. And then it sees the third signal, and tries the Acquire() the fd it has just closed. If the other side tries to reconnect immediately but does not support MCAP reconnections, this could go on forever.
>>
>> A possible solution is to use a monotonic number for the channel path suffix, without relation to MDL ID.
>

Sorry, please, ignore my last comment:
> That is a problem in remote side and applications shall to know how

You are right, I don't know exactly how we can address that problem,
may be we have to study this in deep.

Regards.

^ permalink raw reply

* Re: (Health) ChannelConnected signal when MDL aborted?
From: Santiago Carot @ 2010-10-24  8:34 UTC (permalink / raw)
  To: Elvis Pfützenreuter; +Cc: Jose Antonio Santos Cadenas, linux-bluetooth
In-Reply-To: <4B999390-7FFB-4B90-98BA-D9F9C17771F5@signove.com>

Hi,

2010/10/23 Elvis Pfützenreuter <epx@signove.com>:
>> You are forgetting that there may be more than one health applications
>> running over HDP at the same time, if one of them creates a data
>> channel, that data data channel will be exist at MCAP level even if
>> the initiator abort the connection. If other application wants to
>> create a new data channel with the same configuration, it may be want
>> reconnect that data channel avoiding to create another data channel.
>> It is a best practise wich is recomended in MCAP and best explained in
>> the Health Device Profile white paper document to reduce the amount of
>> data interchanged between medical devices (in IEEE/11073-20601
>> terminology: "agents" and "managers"). Remember that channels may be
>> shared between applications.
>
> I'm still not convinced :) I can't see the point of sharing a HealthChannel that is not healthy (pardon the joke).

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.

HDP specification says:
* The first Data Channel opened on a given MCL shall be a Reliable Data Channel.
* Association traffic shall be carried on the first Reliable Data
Channel that was
opened on a given MCL.

Next you are a text fragment copied from white paper (Alluding to the
example where there are two applications on HDP):
 "...The right side of the diagram shows two devices that typically
both use Reliable Data Channels. In this
case, the devices may share a common Reliable Data Channel (and MDL)
for all data or may optionally
have separate MDLs for their data, but share the first Reliable Data
Channel for IEEE association and
confirmed event traffic..."


>
> Maybe I'm being too pragmatic, but I expect that most real HDP devices will be like that Nonin oximeter: incapable of reconnecting MDLs and incapable of accepting connections. Sharing a channel in that situation will make spend much more, not less, energy, because applications will Acquire() and trigger a reconnection over a channel that actually does not exist and wouldn't be accepted even if it existed.

There are not only Nonin oximeter devices, we have a blood pressure
that reconnect data channels, in the past we played with a weighing
scale wich it was waiting for data channel connections, besides it is
expected more complex devices such as electrocardiograms, and also you
should think about what will happen if somebody uses this
implementation to develop a health device specialization?, for
example, I thinking in smartphones with sensors, etc... IMHO it is
very presumptuous to make such assumptions about the future (may be I
am too idealist) :P

>
> Anyway, MDL aborts are expected to be rare, so the actual problem won't be seen often in practice.
>
> I think we have another, more important problem: naming the channel after MDLID.
>
> For example, the channel that comes from oximeter has always the same path here: /org/bluez/19750/hci0/dev_00_1C_05_00_28_85/chan1. It is incapable of reconnections but always recreates the MDL with the same MDL ID = 1.
>
> Now, let's suppose a MDL is created, destroyed and re-created, but for some reason the application the application takes too long to act upon the signal. You have three signals:
>
> ChannelConnected chan1
> ChannelDeleted chan1
> ChannelConnected chan1 (a second channel with the same MDL ID)
>
> Application will Acquire() on first signal, thinking it is getting the FD for the first instance of chan1, but it will actually get the FD for the second "version" of chan1.
>
> Then it will process the ChannelDeleted signal, closing a perfectly good channel. And then it sees the third signal, and tries the Acquire() the fd it has just closed. If the other side tries to reconnect immediately but does not support MCAP reconnections, this could go on forever.
>
> A possible solution is to use a monotonic number for the channel path suffix, without relation to MDL ID.

That is a problem in remote side and applications shall to know how

^ permalink raw reply

* Re: (Health) ChannelConnected signal when MDL aborted?
From: Elvis Pfützenreuter @ 2010-10-23 20:35 UTC (permalink / raw)
  To: Santiago Carot; +Cc: Jose Antonio Santos Cadenas, linux-bluetooth
In-Reply-To: <AANLkTi=65C7HQXQW1Bqbgf4sNY3wbV2CzqoENBc-b04g@mail.gmail.com>

> You are forgetting that there may be more than one health applications
> running over HDP at the same time, if one of them creates a data
> channel, that data data channel will be exist at MCAP level even if
> the initiator abort the connection. If other application wants to
> create a new data channel with the same configuration, it may be want
> reconnect that data channel avoiding to create another data channel.
> It is a best practise wich is recomended in MCAP and best explained in
> the Health Device Profile white paper document to reduce the amount of
> data interchanged between medical devices (in IEEE/11073-20601
> terminology: "agents" and "managers"). Remember that channels may be
> shared between applications.

I'm still not convinced :) I can't see the point of sharing a HealthChannel that is not healthy (pardon the joke).

Maybe I'm being too pragmatic, but I expect that most real HDP devices will be like that Nonin oximeter: incapable of reconnecting MDLs and incapable of accepting connections. Sharing a channel in that situation will make spend much more, not less, energy, because applications will Acquire() and trigger a reconnection over a channel that actually does not exist and wouldn't be accepted even if it existed.

Anyway, MDL aborts are expected to be rare, so the actual problem won't be seen often in practice.

I think we have another, more important problem: naming the channel after MDLID. 

For example, the channel that comes from oximeter has always the same path here: /org/bluez/19750/hci0/dev_00_1C_05_00_28_85/chan1. It is incapable of reconnections but always recreates the MDL with the same MDL ID = 1.

Now, let's suppose a MDL is created, destroyed and re-created, but for some reason the application the application takes too long to act upon the signal. You have three signals:

ChannelConnected chan1
ChannelDeleted chan1
ChannelConnected chan1 (a second channel with the same MDL ID)

Application will Acquire() on first signal, thinking it is getting the FD for the first instance of chan1, but it will actually get the FD for the second "version" of chan1.

Then it will process the ChannelDeleted signal, closing a perfectly good channel. And then it sees the third signal, and tries the Acquire() the fd it has just closed. If the other side tries to reconnect immediately but does not support MCAP reconnections, this could go on forever.

A possible solution is to use a monotonic number for the channel path suffix, without relation to MDL ID.

^ permalink raw reply

* Re: AVRCP 1.4 : Future on Target Role
From: João Paulo Rechi Vita @ 2010-10-23 15:50 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: Sander van Grieken, Shivendra Agrawal, David Stockwell,
	Waldemar Rymarkiewicz, Luiz Augusto von Dentz, Johan Hedberg
In-Reply-To: <AANLkTikgKM1MNpwP2JL1GdERZ60dE6dkFNC=rdyQDhOV@mail.gmail.com>

Hello all,

I've seen some discuss regarding how to add support for AVRCP 1.3 and
1.4 versions on the ML lately, and some expectations over the related
work I've done in BlueZ. Sorry for the long delay on replying, I've
been pretty busy lately and just didn't got the time. I'm planing to
put some effort again on this work on the coming weeks.

On Tue, Oct 19, 2010 at 14:14, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi,
>
> On Tue, Oct 19, 2010 at 12:47 PM, Sander van Grieken
> <sander@outrightsolutions.nl> wrote:
>> I am very much in favor of not directly depending on MPRIS, but instead letting
>> applications registering themselves as a target. For two reasons:
>>
>> - AVRCP seems to be a superset of MPRIS (which is very limited IMO), and might have
>> different semantics, especially w.r.t. event notifications. So we would limit ourselves to
>> the intersecting subset of both technologies.
>> - A separate AVRCP/TG <-> MPRIS bridge agent would still allow controlling all MPRIS-
>> enabled players, so we can have both full implementation of the AVRCP spec, AND generic
>> MPRIS support.
>
> Sounds good to me, we can use Media API to register players as well.
>

I agree with Sander's opinion that MPRIS seems a bit limited for 1.4.
OTOH it's an already defined and under-adoption standard. If we have
applications registering themselves directly with us, we'll have to
define a new interface for that and push this to the player
applications. Do you guys already have a draft of these interfaces
(for the applications and extensions to the Media API)? I guess we
should try to define exactly what we need first, and them see what's
missing from MPRIS.

>>> > I am keen to receive your feedback with some ideas and thoughts to put
>>> > my effort in right direction.
>>> >
>>> > Question:
>>> > Is anyone working on AVRCP 1.4 Target role profile development?
>>>
>>> Joao Paulo (http://jprvita.wordpress.com/2010/07/22/avrcp-metadata/)
>>
>> Actually, the metadata work is not part of v1.4 of the spec, but 1.3
>>
>> Second, I have already added some boilerplate stuff (like a DBUS Connect method for RCP and
>> some fixes for CT commands), but I've based on Joao's branch, so I have to wait until his
>> stuff gets merged. Alternatively, I could rebase that stuff on HEAD, but that would overlap
>> and conflict with Joao's stuff, so I'm hesitant to go there.
>

Have you published this code somewhere?

> I hope to see this code being push upstream soon, I will try to
> contact Joao Paulo to get an idea if the code is ready to be
> reviewed/pushed so we get the things rolling.
>

I'm finally here :) I've focused mostly in the 1.3 version of the spec
and having pulseaudio as a middle-man in my work, and have written
most of the code in pulseaudio to handle these new functionality. Even
if we take the approach described above for 1.4, IMO it makes sense to
upstream this so we can have earlier support for 1.3 and also to
support Sander's work. Luiz, Johan, what do you think?

I'll review the code once more, since I've written it a few months
ago, but my main concern about pushing it upstream right now is that
it hasn't been tested yet. I have no device to test against and PTS
can't give us no guarantee whether the code really works in practice
or not (but it's still better than nothing). Sander, David, have you
tested my code against any real device?

-- 
João Paulo Rechi Vita
http://jprvita.wordpress.com/

^ permalink raw reply

* Re: [PATCH] This patch avoids a crash when org.bluez.Manager GetProperties request is received and there is not yet any adapters ready. Happens often for example when bluetoothd and ofonod is started next ot each other.
From: Johan Hedberg @ 2010-10-23 12:31 UTC (permalink / raw)
  To: Tommi Keisala; +Cc: linux-bluetooth
In-Reply-To: <1287811998-20490-2-git-send-email-ext-tommi.keisala@nokia.com>

Hi Tommi,

On Sat, Oct 23, 2010, Tommi Keisala wrote:
> ---
>  src/manager.c |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)

You seem to have somehow managed to screw up the commit message this
time: everything in the summary line and nothing in the message body.
Anyway, to avoid further feedback rounds (since the patch itself is fine
now) I went ahead and fixed the commit message and pushed your patch
upstream. Thanks.

Johan

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox