Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH v7] Bluetooth: btwilink driver
From: pavan_savoy @ 2010-11-26  9:20 UTC (permalink / raw)
  To: padovan, marcel; +Cc: linux-bluetooth, linux-kernel, Pavan Savoy

From: Pavan Savoy <pavan_savoy@ti.com>

Marcel, Gustavo,

comments attended to from v5 and v6,

1. Inside ti_st_open, I previously only checked for EINPROGRESS & EPERM,
Now I handle for EINPROGRESS - which is not really an error and
return during all other error cases.

2. _write is still a function pointer and not an exported function, I
need to change the underlying driver's code for this.
However, previous lkml comments on the underlying driver's code
suggested it to be kept as a function pointer and not EXPORT.
Gustavo, Marcel - Please comment on this.
Is this absolutely required? If so why?

3. test_and_set_bit of HCI_RUNNING is done at beginning of
ti_st_open, and did not see issues during firmware download.
However ideally I would still like to set HCI_RUNNING once the firmware
download is done, because I don't want to allow a _send_frame during
firmware download - Marcel, Gustavo - Please comment.

4. test_and_clear of HCI_RUNNING now done @ beginning of close.

5. EAGAIN on failure of st_write is to suggest to try and write again.
I have never this happen - However only if UART goes bad this case may
occur.

6. ti_st_tx_complete is very similar to hci_ldisc's tx_complete - in
fact the code is pretty much borrowed from there.
Marcel, Gustavo - Please suggest where should it be done? If not here.

7. comments cleaned-up + hst memory leak fixed when hci_alloc_dev fails.

8. platform_driver registration inside module_init now is similar to
other drivers.

9. Dan Carpenter's comments on leaking hst memory on failed
hci_register_dev and empty space after quotes in debug statements
fixed.

Thanks for the comments...
Sorry, for previously not being very clear on which comments were
handled and which were not.

-- patch description --

This is the bluetooth protocol driver for the TI WiLink7 chipsets.
Texas Instrument's WiLink chipsets combine wireless technologies
like BT, FM, GPS and WLAN onto a single chip.

This Bluetooth driver works on top of the TI_ST shared transport
line discipline driver which also allows other drivers like
FM V4L2 and GPS character driver to make use of the same UART interface.

Kconfig and Makefile modifications to enable the Bluetooth
driver for Texas Instrument's WiLink 7 chipset.

Signed-off-by: Pavan Savoy <pavan_savoy@ti.com>
---
 drivers/bluetooth/Kconfig    |   10 ++
 drivers/bluetooth/Makefile   |    1 +
 drivers/bluetooth/btwilink.c |  363 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 374 insertions(+), 0 deletions(-)
 create mode 100644 drivers/bluetooth/btwilink.c

diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index 02deef4..8e0de9a 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -219,4 +219,14 @@ config BT_ATH3K
 	  Say Y here to compile support for "Atheros firmware download driver"
 	  into the kernel or say M to compile it as module (ath3k).
 
+config BT_WILINK
+	tristate "Texas Instruments WiLink7 driver"
+	depends on TI_ST
+	help
+	  This enables the Bluetooth driver for Texas Instrument's BT/FM/GPS
+	  combo devices. This makes use of shared transport line discipline
+	  core driver to communicate with the BT core of the combo chip.
+
+	  Say Y here to compile support for Texas Instrument's WiLink7 driver
+	  into the kernel or say M to compile it as module.
 endmenu
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 71bdf13..f4460f4 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_BT_HCIBTSDIO)	+= btsdio.o
 obj-$(CONFIG_BT_ATH3K)		+= ath3k.o
 obj-$(CONFIG_BT_MRVL)		+= btmrvl.o
 obj-$(CONFIG_BT_MRVL_SDIO)	+= btmrvl_sdio.o
+obj-$(CONFIG_BT_WILINK)		+= btwilink.o
 
 btmrvl-y			:= btmrvl_main.o
 btmrvl-$(CONFIG_DEBUG_FS)	+= btmrvl_debugfs.o
diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c
new file mode 100644
index 0000000..71e69f8
--- /dev/null
+++ b/drivers/bluetooth/btwilink.c
@@ -0,0 +1,363 @@
+/*
+ *  Texas Instrument's Bluetooth Driver For Shared Transport.
+ *
+ *  Bluetooth Driver acts as interface between HCI core and
+ *  TI Shared Transport Layer.
+ *
+ *  Copyright (C) 2009-2010 Texas Instruments
+ *  Author: Raja Mani <raja_mani@ti.com>
+ *	Pavan Savoy <pavan_savoy@ti.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include <linux/ti_wilink_st.h>
+
+/* Bluetooth Driver Version */
+#define VERSION               "1.0"
+
+/* Number of seconds to wait for registration completion
+ * when ST returns PENDING status.
+ */
+#define BT_REGISTER_TIMEOUT   6000	/* 6 sec */
+
+/**
+ * struct ti_st - driver operation structure
+ * @hdev: hci device pointer which binds to bt driver
+ * @reg_status: ST registration callback status
+ * @st_write: write function provided by the ST driver
+ *	to be used by the driver during send_frame.
+ * @wait_reg_completion - completion sync between ti_st_open
+ *	and ti_st_registration_completion_cb.
+ */
+struct ti_st {
+	struct hci_dev *hdev;
+	char reg_status;
+	long (*st_write) (struct sk_buff *);
+	struct completion wait_reg_completion;
+};
+
+/* Increments HCI counters based on pocket ID (cmd,acl,sco) */
+static inline void ti_st_tx_complete(struct ti_st *hst, int pkt_type)
+{
+	struct hci_dev *hdev = hst->hdev;
+
+	/* Update HCI stat counters */
+	switch (pkt_type) {
+	case HCI_COMMAND_PKT:
+		hdev->stat.cmd_tx++;
+		break;
+
+	case HCI_ACLDATA_PKT:
+		hdev->stat.acl_tx++;
+		break;
+
+	case HCI_SCODATA_PKT:
+		hdev->stat.sco_tx++;
+		break;
+	}
+}
+
+/* ------- Interfaces to Shared Transport ------ */
+
+/* Called by ST layer to indicate protocol registration completion
+ * status.ti_st_open() function will wait for signal from this
+ * API when st_register() function returns ST_PENDING.
+ */
+static void st_registration_completion_cb(void *priv_data, char data)
+{
+	struct ti_st *lhst = priv_data;
+
+	/* Save registration status for use in ti_st_open() */
+	lhst->reg_status = data;
+	/* complete the wait in ti_st_open() */
+	complete(&lhst->wait_reg_completion);
+}
+
+/* Called by Shared Transport layer when receive data is
+ * available */
+static long st_receive(void *priv_data, struct sk_buff *skb)
+{
+	struct ti_st *lhst = priv_data;
+	int err;
+
+	if (!skb)
+		return -EFAULT;
+
+	if (!lhst) {
+		kfree_skb(skb);
+		return -EFAULT;
+	}
+
+	skb->dev = (void *) lhst->hdev;
+
+	/* Forward skb to HCI core layer */
+	err = hci_recv_frame(skb);
+	if (err < 0) {
+		BT_ERR("Unable to push skb to HCI core(%d)", err);
+		return err;
+	}
+
+	lhst->hdev->stat.byte_rx += skb->len;
+
+	return 0;
+}
+
+/* ------- Interfaces to HCI layer ------ */
+/* protocol structure registered with shared transport */
+static struct st_proto_s ti_st_proto = {
+	.type = ST_BT,
+	.recv = st_receive,
+	.reg_complete_cb = st_registration_completion_cb,
+};
+
+/* Called from HCI core to initialize the device */
+static int ti_st_open(struct hci_dev *hdev)
+{
+	unsigned long timeleft;
+	struct ti_st *hst;
+	int err;
+
+	BT_DBG("%s %p", hdev->name, hdev);
+	if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) {
+		BT_ERR("btwilink already opened");
+		return -EBUSY;
+	}
+
+	/* provide contexts for callbacks from ST */
+	hst = hdev->driver_data;
+	ti_st_proto.priv_data = hst;
+
+	err = st_register(&ti_st_proto);
+	if (err == -EINPROGRESS) {
+		/* ST is busy with either protocol registration or firmware
+		 * download.
+		 */
+		/* Prepare wait-for-completion handler data structures.
+		 */
+		init_completion(&hst->wait_reg_completion);
+
+		/* Reset ST registration callback status flag , this value
+		 * will be updated in ti_st_registration_completion_cb()
+		 * function whenever it called from ST driver.
+		 */
+		hst->reg_status = -EINPROGRESS;
+
+		BT_DBG("waiting for registration completion signal from ST");
+		timeleft = wait_for_completion_timeout
+			(&hst->wait_reg_completion,
+			 msecs_to_jiffies(BT_REGISTER_TIMEOUT));
+		if (!timeleft) {
+			clear_bit(HCI_RUNNING, &hdev->flags);
+			BT_ERR("Timeout(%d sec),didn't get reg "
+					"completion signal from ST",
+					BT_REGISTER_TIMEOUT / 1000);
+			return -ETIMEDOUT;
+		}
+
+		/* Is ST registration callback called with ERROR status? */
+		if (hst->reg_status != 0) {
+			clear_bit(HCI_RUNNING, &hdev->flags);
+			BT_ERR("ST registration completed with invalid "
+					"status %d", hst->reg_status);
+			return -EAGAIN;
+		}
+		err = 0;
+	} else if (err != 0) {
+		clear_bit(HCI_RUNNING, &hdev->flags);
+		BT_ERR("st_register failed %d", err);
+		return err;
+	}
+
+	/* ti_st_proto.write is filled up by the underlying shared
+	 * transport driver upon registration
+	 */
+	hst->st_write = ti_st_proto.write;
+	if (!hst->st_write) {
+		BT_ERR("undefined ST write function");
+		clear_bit(HCI_RUNNING, &hdev->flags);
+
+		/* Undo registration with ST */
+		err = st_unregister(ST_BT);
+		if (err)
+			BT_ERR("st_unregister() failed with error %d", err);
+
+		hst->st_write = NULL;
+		return err;
+	}
+
+	return err;
+}
+
+/* Close device */
+static int ti_st_close(struct hci_dev *hdev)
+{
+	int err;
+	struct ti_st *hst = hdev->driver_data;
+
+	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+		return 0;
+
+	/* continue to unregister from transport */
+	err = st_unregister(ST_BT);
+	if (err)
+		BT_ERR("st_unregister() failed with error %d", err);
+
+	hst->st_write = NULL;
+
+	return err;
+}
+
+static int ti_st_send_frame(struct sk_buff *skb)
+{
+	struct hci_dev *hdev;
+	struct ti_st *hst;
+	long len;
+
+	hdev = (struct hci_dev *)skb->dev;
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		return -EBUSY;
+
+	hst = hdev->driver_data;
+
+	/* Prepend skb with frame type */
+	memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
+
+	BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type,
+			skb->len);
+
+	/* Insert skb to shared transport layer's transmit queue.
+	 * Freeing skb memory is taken care in shared transport layer,
+	 * so don't free skb memory here.
+	 */
+	len = hst->st_write(skb);
+	if (len < 0) {
+		kfree_skb(skb);
+		BT_ERR("ST write failed (%ld)", len);
+		/* Try Again, would only fail if UART has gone bad */
+		return -EAGAIN;
+	}
+
+	/* ST accepted our skb. So, Go ahead and do rest */
+	hdev->stat.byte_tx += len;
+	ti_st_tx_complete(hst, bt_cb(skb)->pkt_type);
+
+	return 0;
+}
+
+static void ti_st_destruct(struct hci_dev *hdev)
+{
+	BT_DBG("%s", hdev->name);
+	kfree(hdev->driver_data);
+}
+
+static int bt_ti_probe(struct platform_device *pdev)
+{
+	static struct ti_st *hst;
+	struct hci_dev *hdev;
+	int err;
+
+	hst = kzalloc(sizeof(struct ti_st), GFP_KERNEL);
+	if (!hst)
+		return -ENOMEM;
+
+	/* Expose "hciX" device to user space */
+	hdev = hci_alloc_dev();
+	if (!hdev) {
+		kfree(hst);
+		return -ENOMEM;
+	}
+
+	BT_DBG("hdev %p", hdev);
+
+	hst->hdev = hdev;
+	hdev->bus = HCI_UART;
+	hdev->driver_data = hst;
+	hdev->open = ti_st_open;
+	hdev->close = ti_st_close;
+	hdev->flush = NULL;
+	hdev->send = ti_st_send_frame;
+	hdev->destruct = ti_st_destruct;
+	hdev->owner = THIS_MODULE;
+
+	err = hci_register_dev(hdev);
+	if (err < 0) {
+		BT_ERR("Can't register HCI device error %d", err);
+		kfree(hst);
+		hci_free_dev(hdev);
+		return err;
+	}
+
+	BT_DBG("HCI device registered (hdev %p)", hdev);
+
+	dev_set_drvdata(&pdev->dev, hst);
+	return err;
+}
+
+static int bt_ti_remove(struct platform_device *pdev)
+{
+	struct hci_dev *hdev;
+	struct ti_st *hst = dev_get_drvdata(&pdev->dev);
+
+	if (!hst)
+		return -EFAULT;
+
+	hdev = hst->hdev;
+	ti_st_close(hdev);
+	hci_unregister_dev(hdev);
+
+	hci_free_dev(hdev);
+	kfree(hst);
+
+	dev_set_drvdata(&pdev->dev, NULL);
+	return 0;
+}
+
+static struct platform_driver btwilink_driver = {
+	.probe = bt_ti_probe,
+	.remove = bt_ti_remove,
+	.driver = {
+		.name = "btwilink",
+		.owner = THIS_MODULE,
+	},
+};
+
+/* ------- Module Init/Exit interfaces ------ */
+static int __init btwilink_init(void)
+{
+	BT_INFO("Bluetooth Driver for TI WiLink - Version %s", VERSION);
+
+	return platform_driver_register(&btwilink_driver);
+}
+
+static void __exit btwilink_exit(void)
+{
+	platform_driver_unregister(&btwilink_driver);
+}
+
+module_init(btwilink_init);
+module_exit(btwilink_exit);
+
+/* ------ Module Info ------ */
+
+MODULE_AUTHOR("Raja Mani <raja_mani@ti.com>");
+MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
-- 
1.5.6.3

^ permalink raw reply related

* Re: [PATCH 1/1] bluetooth: Fix NULL pointer dereference issue
From: Yuri Ershov @ 2010-11-26  8:50 UTC (permalink / raw)
  To: ext Gustavo F. Padovan
  Cc: marcel, davem, jprvita, linux-bluetooth, ville.tervo,
	andrei.emeltchenko
In-Reply-To: <20101125181614.GA25686@vigoh>

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

ext Gustavo F. Padovan wrote:
> Hi Yuri,
>
> * Yuri Ershov <ext-yuri.ershov@nokia.com> [2010-11-25 12:55:33 +0300]:
>
>   
>> This patch is an addition to my previous patch for this issue.
>> The problem is in resynchronization between two loops:
>> 1. Main controlling loop (l2cap_connect_req, l2cap_config_req,
>> l2cap_config_rsp, l2cap_disconnect_req, etc.)
>> 2. Loop waiting of BT_CONNECTED state of socket (l2cap_sock_accept,
>> bt_accept_dequeue, etc.).
>> In case of fast sequence of connect/disconnect operations the loop #1
>> makes several cycles, while the loop #2 only has time to make one
>> cycle and it results crash.
>>     
>
> What is the crash point? Can you provide a log?
>
>   
Hello,

There are two situations depending on timing:
1. Dereferencing in "bt_accept_unlink of NULL pointer bt_sk(sk)->parent 
of already freed socket.

[ 3555.897247] Unable to handle kernel NULL pointer dereference at virtual
address 000000bc
[ 3555.915039] pgd = cab9c000
[ 3555.917785] [000000bc] *pgd=8bf3d031, *pte=00000000, *ppte=00000000
[ 3555.928314] Internal error: Oops: 17 [#1] PREEMPT
[ 3555.933044] last sysfs file:
/sys/devices/platform/hci_h4p/firmware/hci_h4p/loading
[ 3555.940734] Modules linked in: wl1271_spi iptable_filter ip_tables rfcomm
sco l2cap xt_IDLETIMER x_tables arc4 ecb crc7 wl1271 mac80211 ]
[ 3555.999786] CPU: 0    Not tainted  (2.6.32.21-13874-g67918ef #65)
[ 3556.005981] PC is at bt_accept_unlink+0x20/0x58 [bluetooth]
[ 3556.011627] LR is at bt_accept_dequeue+0x3c/0xe8 [bluetooth]
[ 3556.017303] pc : [<bf0007fc>]    lr : [<bf000870>]    psr: 68000153
[ 3556.017333] sp : cfa7fea8  ip : df24a95c  fp : bee2eab4
[ 3556.028869] r10: df24ac00  r9 : df24a800  r8 : c8231c00
[ 3556.034118] r7 : df24ad5c  r6 : df24ad5c  r5 : df24a800  r4 : df24a95c
[ 3556.040679] r3 : df24a95c  r2 : 00000000  r1 : 00000000  r0 : df24a800
[ 3556.047241] Flags: nZCv  IRQs on  FIQs off  Mode SVC_32  ISA ARM  Segment
user
[ 3556.054504] Control: 10c5387d  Table: 8ab9c019  DAC: 00000015
[ 3556.060272] Process l2test (pid: 9298, stack limit = 0xcfa7e2e8)
[ 3556.066314] Stack: (0xcfa7fea8 to 0xcfa80000)
[ 3556.070709] fea0:                   7fffffff df24ac00 cfa7e000 00000001
c8231c00 cfa7e000
[ 3556.078948] fec0: bee2ea8c bf324df8 c04640e0 00000001 ca1bb0c0 c005c0b8
c8231910 c8231910
[ 3556.087158] fee0: c8231c00 00000005 00000000 c8231900 bee2ea6c c026a0a8
0000081f cfa7ffb0
[ 3556.095397] ff00: 4019=4a4 4001e2e0 00001040 c002c2b4 da87e080 ca1bb0c0
c041c5f8 00000002
[ 3556.103607] ff20: 00000000 00000000 cfa7ff4c c005939c c041c5f8 da87e080
000025a4 00000000
[ 3556.111846] ff40: 00000000 00000000 cfa7ff64 c005c47c 00000000 60000053
da87e080 01200011
[ 3556.120086] ff60: bee2ea1c c005e290 df92c480 00000000 dfe6d9c0 df92c480
00000000 c00cc0b4
[ 3556.128295] ff80: 00000000 df92c500 dfe6d9c0 00000000 bee2ea8c bee2ea74
0000011d c002cb24
[ 3556.136535] ffa0: 000147c8 c002c9a0 00000000 bee2ea8c 00000003 bee2ea6c
bee2ea8c 00000001
[ 3556.144744] ffc0: 00000000 bem2ea8c bee2ea74 0000011d 00000005 00014800
000147c8 bee2eab4
[ 3556.152984] ffe0: bee2ea70 bee2ea20 00009f64 4012d6ec 40000050 00000003
00000000 00000000
[ 3556.161285] [<bf0007fc>] (bt_accept_unlink+0x20/0x58 [bluetooth]) from
[<bf000870>] (bt_accept_dequeue+0x3c/0xe8 [bluetooth])
[ 3556.172729] [<bf000870>] (bt_accept_dequeue+0x3c/0xe8 [bluetooth]) from
[<bf324df8>] (l2cap_sock_accept+0x100/0x15c [l2cap])
[ 3556.184082] [<bf324df8>] (l2cap_sock_accept+0x100/0x15c [l2cap]) from
[<c026a0a8>] (sys_accept4+0x120/0x1e0)
[ 3556.193969] [<c026a0a8>] (sys_accept4+0x120/0x1e0) from [<c002c9a0>]
(ret_fast_syscall+0x0/0x2c)
[ 3556.202819] Code: e5813000 e5901164 e580c160 e580c15c (e1d13bbc) 
[ 3556.215393] ---[ end trace f11f032273933575 ]---

This was partially fixed by Andrei Emeltchenko by checking of 
sock_owned_by_user in l2cap_disconnect_req.

2. Attempt of access to non-valid pointer of freed socket.

[  997.846099] Unable to handle kernel paging request at virtual address
65756c62
[  997.853424] pgd = b2680000
[  997.856140] [65756c62] *pgd=00000000
[  997.859771] Internal error: Oops: 5 [#1] PREEMPT
[  997.864410] last sysfs file:
/sys/devices/platform/i2c_omap.2/i2c-2/2-0032/engine1_mode
[  997.872467] Modules linked in: rfcomm sco xt_IDLETIMER x_tables l2cap arc4
ecb wl1271_spi crc7 wl1271 mac80211 cfg80211 pn_pep as3645a ad58xx smiapp
smiaregs board_rm680_camera omap3_isp v4l2_common iovmm omap3_iommu g_nokia
iommu2 iommu fuse mtdswap mtd_blkdevs bridgedriver omaplfb iphb uinput
cmt_speech ssi_protocol cmt hsi_char phonet radio_wl1273 hci_h4p videodev
pvrsrvkm omap_ssi lis3lv02d_i2c mailbox_mach twl5031_aci lis3lv02d
hid_twl4030_vibra leds_lp5523 rtc_twl4030 mailbox media bcm4751_gps ak8974
bhsfh led_class rtc_core input_polldev twl4030_pwrbutton twl4030_keypad
gpio_keys eci ff_memless bluetooth [last unloaded: g_file_storage]
[  997.930175] CPU: 0    Not tainted  (2.6.32.23-13390-g03b424f #314)
[  997.936401] PC is at release_sock+0x5c/0xe4
[  997.940612] LR is at release_sock+0x18/0xe4
[  997.944793] pc : [<b02868d4>]    lr : [<b0286890>]    psr: 60000053
[  997.944824] sp : ba17de88  ip : 00000000  fp : aeff5ab4
[  997.956359] r10: ba16d000  r9 : b33b0c00  r8 : c545d300
[  997.961608] r7 : 65756c62  r6 : ba17c000  r5 : b33b0c00  r4 : b33b0c00
[  997.968170] r3 : 00000000  r2 : ba17c000  r1 : 00000000  r0 : b33b0c00
[  997.974731] Flags: nZCv  IRQs on  FIQs off  Mode SVC_32  ISA ARM  Segment
user
[  997.981964] Control: 10c5387d  Table: 82680019  DAC: 00000015
[  997.987762] Process l2test (pid: 3973, stack limit = 0xba17c2e8)
[  997.993774] Stack: (0xba17de88 to 0xba17e000)
[  997.998168] de80:                   b33b0c00 b33b0d5c ba16d15c b33b0d5c
c545d300 af000c2c
[  998.006378] dea0: ba17c000 ba16d000 7fffffff 00000001 00000000 ba17c000
c545d300 af16fac4
[  998.014617] dec0: b032d040 00000001 b27416c0 b006427c c545d610 c545d610
00000005 c545d300
[  998.022827] dee0: 00000005 00000000 c545d600 aeff5a6c aeff5a8c b028590c
0000081f ba17dfb0
[  998.031066] df00: 3ac5d490 00001258 3ac5e264 b002d2b4 b2742080 b27416c0
b044c600 00000003
[  998.039276] df20: 00000000 00000000 ba17df4c b00617d8 b044c600 b2742080
000015f1 00000000
[  998.047515] df40: 00000000 00000000 ba17df64 b0064600 00000000 60000053
b2742080 01200011
[  998.055725] df60: aeff5a14 b0066420 cbad2700 00000000 b6e98780 cbad2700
00000000 b00d4698
[  998.063934] df80: 00000000 cbad2480 b6e98780 00015214 000151e0 00000003
0000011d b002db24
[  998.072174] dfa0: aeff5a8c b002d9a0 00015214 000151e0 00000003 aeff5a6c
aeff5a8c 0000000c
[  998.080383] dfc0: 00015214 000151e0 00000003 0000011d 00000000 aeff5a74
aeff5a8c aeff5ab4
[  998.088623] dfe0: aeff5a6c aeff5a18 0000a6f8 3abee76c 40000050 00000003
00000000 00000000
[  998.096923] [<b02868d4>] (release_sock+0x5c/0xe4) from [<af000c2c>]
(bt_accept_dequeue+0xec/0x13c [bluetooth])
[  998.107055] [<af000c2c>] (bt_accept_dequeue+0xec/0x13c [bluetooth]) from
[<af16fac4>] (l2cap_sock_accept+0x148/0x234 [l2cap])
[  998.118469] [<af16fac4>] (l2cap_sock_accept+0x148/0x234 [l2cap]) from
[<b028590c>] (sys_accept4+0x120/0x1e0)
[  998.128356] [<b028590c>] (sys_accept4+0x120/0x1e0) from [<b002d9a0>]
(ret_fast_syscall+0x0/0x2c)
[  998.137207] Code: e5963000 e3130002 0a000000 eb01f2d8 (e5974000) 
[  998.143341] ---[ end trace 2b5f71a75cc62b96 ]---
[  998.148010] Kernel panic - not syncing: Fatal exception in interrupt
[  998.154418] [<b003266c>] (unwind_backtrace+0x0/0x150) from [<b0302cec>]
(panic+0x58/0x130)
[  998.162750] [<b0302cec>] (panic+0x58/0x130) from [<b003107c>]
(die+0x27c/0x2b8)
[  998.170135] [<b003107c>] (die+0x27c/0x2b8) from [<b0033530>]
(__do_kernel_fault+0x64/0x74)
[  998.178466] [<b0033530>] (__do_kernel_fault+0x64/0x74) from [<b03070b8>]
(do_page_fault+0x240/0x258)
[  998.187683] [<b03070b8>] (do_page_fault+0x240/0x258) from [<b002d2b4>]
(do_DataAbort+0x34/0x94)
[  998.196441] [<b002d2b4>] (do_DataAbort+0x34/0x94) from [<b030522c>]
(__dabt_svc+0x4c/0x60)
[  998.204772] Exception stack(0xba17de40 to 0xba17de88)
[  998.209838] de40: b33b0c00 00000000 ba17c000 00000000 b33b0c00 b33b0c00
ba17c000 65756c62
[  998.218078] de60: c545d300 b33b0c00 ba16d000 aeff5ab4 00000000 ba17de88
b0286890 b02868d4
[  998.226318] de80: 60000053 ffffffff
[  998.229858] [<b030522c>] (__dabt_svc+0x4c/0x60) from [<b02868d4>]
(release_sock+0x5c/0xe4)
[  998.238220] [<b02868d4>] (release_sock+0x5c/0xe4) from [<af000c2c>]
(bt_accept_dequeue+0xec/0x13c [bluetooth])
[  998.248352] [<af000c2c>] (bt_accept_dequeue+0xec/0x13c [bluetooth]) from
[<af16fac4>] (l2cap_sock_accept+0x148/0x234 [l2cap])
[  998.259765] [<af16fac4>] (l2cap_sock_accept+0x148/0x234 [l2cap]) from
[<b028590c>] (sys_accept4+0x120/0x1e0)
[  998.269653] [<b028590c>] (sys_accept4+0x120/0x1e0) from [<b002d9a0>]
(ret_fast_syscall+0x0/0x2c)


Regards,
Yuri


[-- Attachment #2: Type: text/html, Size: 9664 bytes --]

^ permalink raw reply

* Re: [PATCH] Fix crash after simultaneous authentication requests
From: Johan Hedberg @ 2010-11-25 20:11 UTC (permalink / raw)
  To: Rafal Michalski; +Cc: linux-bluetooth
In-Reply-To: <1290679615-26273-1-git-send-email-michalski.raf@gmail.com>

Hi Rafal,

On Thu, Nov 25, 2010, Rafal Michalski wrote:
> Previously simultaneous authentication requests to the same device caused
> bluetoothd crash. Now if ongoing authentication occurs error is returned,
> preventing from simultaneous requests to the same device.
> ---
>  src/device.c |    5 +++++
>  1 files changed, 5 insertions(+), 0 deletions(-)

Pushed upstream. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] sdpd header cleanup
From: Johan Hedberg @ 2010-11-25 20:04 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <1290622616-26505-1-git-send-email-claudio.takahasi@openbossa.org>

Hi Claudio,

On Wed, Nov 24, 2010, Claudio Takahasi wrote:
> ---
>  src/sdpd-request.c |   12 +++++++++++-
>  src/sdpd.h         |   14 --------------
>  2 files changed, 11 insertions(+), 15 deletions(-)

Thanks. Pushed upstream.

Johan

^ permalink raw reply

* Re: [PATCH 1/3] Fix not deinitializing telephony driver when there is no adapter powered
From: Johan Hedberg @ 2010-11-25 20:01 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1290698551-8706-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Thu, Nov 25, 2010, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
> 
> This changes hook telephony driver de/initialization to powered state so
> telephony drivers can now free their resources when there is no adapter
> active in the system.
> ---
>  audio/manager.c |   59 ++++++++++++++++++++++++++++++++++++++++++++++++++----
>  1 files changed, 54 insertions(+), 5 deletions(-)

All three patches (v2 of 3/3) have been pushed upstream. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH 1/1] bluetooth: Fix NULL pointer dereference issue
From: Gustavo F. Padovan @ 2010-11-25 18:16 UTC (permalink / raw)
  To: Yuri Ershov
  Cc: marcel, davem, jprvita, linux-bluetooth, ville.tervo,
	andrei.emeltchenko
In-Reply-To: <e98b2c6fd02b11300d82577cb54cfdb63e8400d2.1290678703.git.ext-yuri.ershov@nokia.com>

Hi Yuri,

* Yuri Ershov <ext-yuri.ershov@nokia.com> [2010-11-25 12:55:33 +0300]:

> This patch is an addition to my previous patch for this issue.
> The problem is in resynchronization between two loops:
> 1. Main controlling loop (l2cap_connect_req, l2cap_config_req,
> l2cap_config_rsp, l2cap_disconnect_req, etc.)
> 2. Loop waiting of BT_CONNECTED state of socket (l2cap_sock_accept,
> bt_accept_dequeue, etc.).
> In case of fast sequence of connect/disconnect operations the loop #1
> makes several cycles, while the loop #2 only has time to make one
> cycle and it results crash.

What is the crash point? Can you provide a log?

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* [PATCH] Emit Connect signal for LE capable devices
From: Sheldon Demario @ 2010-11-25 17:22 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

---
 plugins/hciops.c |   61 ++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 43 insertions(+), 18 deletions(-)

diff --git a/plugins/hciops.c b/plugins/hciops.c
index 9abe477..308908a 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -1207,12 +1207,14 @@ static inline void remote_features_information(int index, void *ptr)
 	write_features_info(&BDADDR(index), &dba, evt->features, NULL);
 }
 
-static inline void conn_complete(int index, void *ptr)
+static inline void conn_complete(int index, gboolean le, void *ptr)
 {
-	evt_conn_complete *evt = ptr;
 	char filename[PATH_MAX];
 	char local_addr[18], peer_addr[18], *str;
 	struct btd_adapter *adapter;
+	bdaddr_t *evt_bdaddr;
+	uint16_t evt_handle;
+	uint8_t evt_status;
 
 	adapter = manager_find_adapter(&BDADDR(index));
 	if (!adapter) {
@@ -1220,27 +1222,39 @@ static inline void conn_complete(int index, void *ptr)
 		return;
 	}
 
-	if (evt->link_type != ACL_LINK)
-		return;
+	if (le) {
+		evt_le_connection_complete *evt = ptr;
+		evt_bdaddr = &evt->peer_bdaddr;
+		evt_handle = evt->handle;
+		evt_status = evt->status;
+	}  else {
+		evt_conn_complete *evt = ptr;
+		evt_bdaddr = &evt->bdaddr;
+		evt_handle = evt->handle;
+		evt_status = evt->status;
+
+		if (evt->link_type != ACL_LINK)
+			return;
+	}
 
-	btd_event_conn_complete(&BDADDR(index), evt->status,
-					btohs(evt->handle), &evt->bdaddr);
+	btd_event_conn_complete(&BDADDR(index), evt_status,
+					btohs(evt_handle), evt_bdaddr);
 
-	if (evt->status)
+	if (evt_status)
 		return;
 
-	update_lastused(&BDADDR(index), &evt->bdaddr);
+	update_lastused(&BDADDR(index), evt_bdaddr);
 
 	/* check if the remote version needs be requested */
 	ba2str(&BDADDR(index), local_addr);
-	ba2str(&evt->bdaddr, peer_addr);
+	ba2str(evt_bdaddr, peer_addr);
 
 	create_name(filename, sizeof(filename), STORAGEDIR, local_addr,
 							"manufacturers");
 
 	str = textfile_get(filename, peer_addr);
 	if (!str)
-		btd_adapter_get_remote_version(adapter, btohs(evt->handle),
+		btd_adapter_get_remote_version(adapter, btohs(evt_handle),
 									TRUE);
 	else
 		free(str);
@@ -1282,17 +1296,11 @@ static inline void conn_request(int index, void *ptr)
 	btd_event_remote_class(&BDADDR(index), &evt->bdaddr, class);
 }
 
-static inline void le_metaevent(int index, void *ptr)
+static inline void le_advertising_report(int index, evt_le_meta_event *meta)
 {
-	evt_le_meta_event *meta = ptr;
 	le_advertising_info *info;
 	uint8_t num, i;
 
-	DBG("LE Meta Event");
-
-	if (meta->subevent != EVT_LE_ADVERTISING_REPORT)
-		return;
-
 	num = meta->data[0];
 	info = (le_advertising_info *) (meta->data + 1);
 
@@ -1302,6 +1310,23 @@ static inline void le_metaevent(int index, void *ptr)
 	}
 }
 
+static inline void le_metaevent(int index, void *ptr)
+{
+	evt_le_meta_event *meta = ptr;
+
+	DBG("LE Meta Event");
+
+	switch (meta->subevent) {
+	case EVT_LE_ADVERTISING_REPORT:
+		le_advertising_report(index, meta);
+		break;
+
+	case EVT_LE_CONN_COMPLETE:
+		conn_complete(index, TRUE, meta->data);
+		break;
+	}
+}
+
 static void stop_hci_dev(int index)
 {
 	GIOChannel *chan = CHANNEL(index);
@@ -1399,7 +1424,7 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond,
 		break;
 
 	case EVT_CONN_COMPLETE:
-		conn_complete(index, ptr);
+		conn_complete(index, FALSE, ptr);
 		break;
 
 	case EVT_DISCONN_COMPLETE:
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 3/3 v2] Fix telephony maemo6 driver deinitialization
From: Luiz Augusto von Dentz @ 2010-11-25 16:07 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>

Remove all match rules and unregister its interface when telephony_exit
is called.
---
 audio/telephony-maemo6.c |  168 +++++++++++++++++++++++----------------------
 1 files changed, 86 insertions(+), 82 deletions(-)

diff --git a/audio/telephony-maemo6.c b/audio/telephony-maemo6.c
index 72c8e36..2e01fb1 100644
--- a/audio/telephony-maemo6.c
+++ b/audio/telephony-maemo6.c
@@ -149,6 +149,7 @@ static int get_property(const char *iface, const char *prop);
 static DBusConnection *connection = NULL;
 
 static GSList *calls = NULL;
+static GSList *watches = NULL;
 
 /* Reference count for determining the call indicator status */
 static GSList *active_calls = NULL;
@@ -1616,59 +1617,6 @@ done:
 	dbus_message_unref(reply);
 }
 
-static void hal_find_device_reply(DBusPendingCall *call, void *user_data)
-{
-	DBusError err;
-	DBusMessage *reply;
-	DBusMessageIter iter, sub;
-	const char *path;
-	char match_string[256];
-	int type;
-
-	reply = dbus_pending_call_steal_reply(call);
-
-	dbus_error_init(&err);
-	if (dbus_set_error_from_message(&err, reply)) {
-		error("hald replied with an error: %s, %s",
-				err.name, err.message);
-		dbus_error_free(&err);
-		goto done;
-	}
-
-	dbus_message_iter_init(reply, &iter);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
-		error("Unexpected signature in FindDeviceByCapability return");
-		goto done;
-	}
-
-	dbus_message_iter_recurse(&iter, &sub);
-
-	type = dbus_message_iter_get_arg_type(&sub);
-
-	if (type != DBUS_TYPE_OBJECT_PATH && type != DBUS_TYPE_STRING) {
-		error("No hal device with battery capability found");
-		goto done;
-	}
-
-	dbus_message_iter_get_basic(&sub, &path);
-
-	DBG("telephony-maemo6: found battery device at %s", path);
-
-	snprintf(match_string, sizeof(match_string),
-			"type='signal',"
-			"path='%s',"
-			"interface='org.freedesktop.Hal.Device',"
-			"member='PropertyModified'", path);
-	dbus_bus_add_match(connection, match_string, NULL);
-
-	hal_get_integer(path, "battery.charge_level.last_full", &battchg_last);
-	hal_get_integer(path, "battery.charge_level.current", &battchg_cur);
-	hal_get_integer(path, "battery.charge_level.design", &battchg_design);
-
-done:
-	dbus_message_unref(reply);
-}
 
 static void phonebook_read_reply(DBusPendingCall *call, void *user_data)
 {
@@ -1897,14 +1845,11 @@ static void modem_state_reply(DBusPendingCall *call, void *user_data)
 	dbus_message_unref(reply);
 }
 
-static DBusHandlerResult signal_filter(DBusConnection *conn,
-						DBusMessage *msg, void *data)
+static gboolean signal_filter(DBusConnection *conn, DBusMessage *msg,
+								void *data)
 {
 	const char *path = dbus_message_get_path(msg);
 
-	if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
-		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
 	if (dbus_message_is_signal(msg, CSD_CALL_INTERFACE, "Coming"))
 		handle_incoming_call(msg);
 	else if (dbus_message_is_signal(msg, CSD_CALL_INTERFACE, "Created"))
@@ -1934,7 +1879,67 @@ static DBusHandlerResult signal_filter(DBusConnection *conn,
 						"modem_state_changed_ind"))
 		handle_modem_state(msg);
 
-	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	return TRUE;
+}
+
+static void add_watch(const char *sender, const char *path,
+				const char *interface, const char *member)
+{
+	guint watch;
+
+	watch = g_dbus_add_signal_watch(connection, sender, path, interface,
+					member, signal_filter, NULL, NULL);
+
+	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
+}
+
+static void hal_find_device_reply(DBusPendingCall *call, void *user_data)
+{
+	DBusError err;
+	DBusMessage *reply;
+	DBusMessageIter iter, sub;
+	const char *path;
+	int type;
+
+	reply = dbus_pending_call_steal_reply(call);
+
+	dbus_error_init(&err);
+	if (dbus_set_error_from_message(&err, reply)) {
+		error("hald replied with an error: %s, %s",
+				err.name, err.message);
+		dbus_error_free(&err);
+		goto done;
+	}
+
+	dbus_message_iter_init(reply, &iter);
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
+		error("Unexpected signature in FindDeviceByCapability return");
+		goto done;
+	}
+
+	dbus_message_iter_recurse(&iter, &sub);
+
+	type = dbus_message_iter_get_arg_type(&sub);
+
+	if (type != DBUS_TYPE_OBJECT_PATH && type != DBUS_TYPE_STRING) {
+		error("No hal device with battery capability found");
+		goto done;
+	}
+
+	dbus_message_iter_get_basic(&sub, &path);
+
+	DBG("telephony-maemo6: found battery device at %s", path);
+
+	add_watch(NULL, path, "org.freedesktop.Hal.Device",
+							"PropertyModified");
+
+	hal_get_integer(path, "battery.charge_level.last_full", &battchg_last);
+	hal_get_integer(path, "battery.charge_level.current", &battchg_cur);
+	hal_get_integer(path, "battery.charge_level.design", &battchg_design);
+
+done:
+	dbus_message_unref(reply);
 }
 
 int telephony_init(void)
@@ -1948,30 +1953,17 @@ int telephony_init(void)
 				AG_FEATURE_EXTENDED_ERROR_RESULT_CODES |
 				AG_FEATURE_THREE_WAY_CALLING;
 
+	DBG("");
+
 	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
 
-	if (!dbus_connection_add_filter(connection, signal_filter,
-						NULL, NULL))
-		error("Can't add signal filter");
-
-	dbus_bus_add_match(connection,
-			"type=signal,interface=" CSD_CALL_INTERFACE, NULL);
-	dbus_bus_add_match(connection,
-			"type=signal,interface=" CSD_CALL_INSTANCE, NULL);
-	dbus_bus_add_match(connection,
-			"type=signal,interface=" CSD_CALL_CONFERENCE, NULL);
-	dbus_bus_add_match(connection,
-			"type=signal,interface=" CSD_CSNET_REGISTRATION,
-			NULL);
-	dbus_bus_add_match(connection,
-			"type=signal,interface=" CSD_CSNET_OPERATOR,
-			NULL);
-	dbus_bus_add_match(connection,
-			"type=signal,interface=" CSD_CSNET_SIGNAL,
-			NULL);
-	dbus_bus_add_match(connection,
-				"type=signal,interface=" SSC_DBUS_IFACE
-				",member=modem_state_changed_ind", NULL);
+	add_watch(NULL, NULL, CSD_CALL_INTERFACE, NULL);
+	add_watch(NULL, NULL, CSD_CALL_INSTANCE, NULL);
+	add_watch(NULL, NULL, CSD_CALL_CONFERENCE, NULL);
+	add_watch(NULL, NULL, CSD_CSNET_REGISTRATION, NULL);
+	add_watch(NULL, NULL, CSD_CSNET_OPERATOR, NULL);
+	add_watch(NULL, NULL, CSD_CSNET_SIGNAL, NULL);
+	add_watch(NULL, NULL, CSD_CSNET_SIGNAL, "modem_state_changed_ind");
 
 	if (send_method_call(SSC_DBUS_NAME, SSC_DBUS_PATH, SSC_DBUS_IFACE,
 					"get_modem_state", modem_state_reply,
@@ -2005,8 +1997,15 @@ int telephony_init(void)
 	return 0;
 }
 
+static void remove_watch(gpointer data)
+{
+	g_dbus_remove_watch(connection, GPOINTER_TO_UINT(data));
+}
+
 void telephony_exit(void)
 {
+	DBG("");
+
 	g_free(net.operator_name);
 	net.operator_name = NULL;
 
@@ -2017,7 +2016,12 @@ void telephony_exit(void)
 	g_slist_free(calls);
 	calls = NULL;
 
-	dbus_connection_remove_filter(connection, signal_filter, NULL);
+	g_slist_foreach(watches, (GFunc) remove_watch, NULL);
+	g_slist_free(watches);
+	watches = NULL;
+
+	g_dbus_unregister_interface(connection, TELEPHONY_MAEMO_PATH,
+						TELEPHONY_MAEMO_INTERFACE);
 
 	dbus_connection_unref(connection);
 	connection = NULL;
-- 
1.7.1


^ permalink raw reply related

* [PATCH 3/3] Fix telephony maemo6 driver deinitialization
From: Luiz Augusto von Dentz @ 2010-11-25 15:22 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1290698551-8706-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>

Remove all match rules and unregister its interface when telephony_exit
is called.
---
 audio/telephony-maemo6.c |  198 +++++++++++++++++++++++++++-------------------
 1 files changed, 116 insertions(+), 82 deletions(-)

diff --git a/audio/telephony-maemo6.c b/audio/telephony-maemo6.c
index 72c8e36..542fab9 100644
--- a/audio/telephony-maemo6.c
+++ b/audio/telephony-maemo6.c
@@ -149,6 +149,7 @@ static int get_property(const char *iface, const char *prop);
 static DBusConnection *connection = NULL;
 
 static GSList *calls = NULL;
+static GSList *watches = NULL;
 
 /* Reference count for determining the call indicator status */
 static GSList *active_calls = NULL;
@@ -1616,59 +1617,6 @@ done:
 	dbus_message_unref(reply);
 }
 
-static void hal_find_device_reply(DBusPendingCall *call, void *user_data)
-{
-	DBusError err;
-	DBusMessage *reply;
-	DBusMessageIter iter, sub;
-	const char *path;
-	char match_string[256];
-	int type;
-
-	reply = dbus_pending_call_steal_reply(call);
-
-	dbus_error_init(&err);
-	if (dbus_set_error_from_message(&err, reply)) {
-		error("hald replied with an error: %s, %s",
-				err.name, err.message);
-		dbus_error_free(&err);
-		goto done;
-	}
-
-	dbus_message_iter_init(reply, &iter);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
-		error("Unexpected signature in FindDeviceByCapability return");
-		goto done;
-	}
-
-	dbus_message_iter_recurse(&iter, &sub);
-
-	type = dbus_message_iter_get_arg_type(&sub);
-
-	if (type != DBUS_TYPE_OBJECT_PATH && type != DBUS_TYPE_STRING) {
-		error("No hal device with battery capability found");
-		goto done;
-	}
-
-	dbus_message_iter_get_basic(&sub, &path);
-
-	DBG("telephony-maemo6: found battery device at %s", path);
-
-	snprintf(match_string, sizeof(match_string),
-			"type='signal',"
-			"path='%s',"
-			"interface='org.freedesktop.Hal.Device',"
-			"member='PropertyModified'", path);
-	dbus_bus_add_match(connection, match_string, NULL);
-
-	hal_get_integer(path, "battery.charge_level.last_full", &battchg_last);
-	hal_get_integer(path, "battery.charge_level.current", &battchg_cur);
-	hal_get_integer(path, "battery.charge_level.design", &battchg_design);
-
-done:
-	dbus_message_unref(reply);
-}
 
 static void phonebook_read_reply(DBusPendingCall *call, void *user_data)
 {
@@ -1897,14 +1845,11 @@ static void modem_state_reply(DBusPendingCall *call, void *user_data)
 	dbus_message_unref(reply);
 }
 
-static DBusHandlerResult signal_filter(DBusConnection *conn,
-						DBusMessage *msg, void *data)
+static gboolean signal_filter(DBusConnection *conn, DBusMessage *msg,
+								void *data)
 {
 	const char *path = dbus_message_get_path(msg);
 
-	if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
-		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
 	if (dbus_message_is_signal(msg, CSD_CALL_INTERFACE, "Coming"))
 		handle_incoming_call(msg);
 	else if (dbus_message_is_signal(msg, CSD_CALL_INTERFACE, "Created"))
@@ -1934,7 +1879,61 @@ static DBusHandlerResult signal_filter(DBusConnection *conn,
 						"modem_state_changed_ind"))
 		handle_modem_state(msg);
 
-	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	return TRUE;
+}
+
+static void hal_find_device_reply(DBusPendingCall *call, void *user_data)
+{
+	DBusError err;
+	DBusMessage *reply;
+	DBusMessageIter iter, sub;
+	const char *path;
+	int type;
+	guint watch;
+
+	reply = dbus_pending_call_steal_reply(call);
+
+	dbus_error_init(&err);
+	if (dbus_set_error_from_message(&err, reply)) {
+		error("hald replied with an error: %s, %s",
+				err.name, err.message);
+		dbus_error_free(&err);
+		goto done;
+	}
+
+	dbus_message_iter_init(reply, &iter);
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
+		error("Unexpected signature in FindDeviceByCapability return");
+		goto done;
+	}
+
+	dbus_message_iter_recurse(&iter, &sub);
+
+	type = dbus_message_iter_get_arg_type(&sub);
+
+	if (type != DBUS_TYPE_OBJECT_PATH && type != DBUS_TYPE_STRING) {
+		error("No hal device with battery capability found");
+		goto done;
+	}
+
+	dbus_message_iter_get_basic(&sub, &path);
+
+	DBG("telephony-maemo6: found battery device at %s", path);
+
+	watch = g_dbus_add_signal_watch(connection, NULL, path,
+					"org.freedesktop.Hal.Device",
+					"PropertyModified", signal_filter,
+					NULL, NULL);
+
+	watches = g_slist_prepend(watches, GINT_TO_POINTER(watch));
+
+	hal_get_integer(path, "battery.charge_level.last_full", &battchg_last);
+	hal_get_integer(path, "battery.charge_level.current", &battchg_cur);
+	hal_get_integer(path, "battery.charge_level.design", &battchg_design);
+
+done:
+	dbus_message_unref(reply);
 }
 
 int telephony_init(void)
@@ -1947,31 +1946,54 @@ int telephony_init(void)
 				AG_FEATURE_ENHANCED_CALL_CONTROL |
 				AG_FEATURE_EXTENDED_ERROR_RESULT_CODES |
 				AG_FEATURE_THREE_WAY_CALLING;
+	guint watch;
+
+	DBG("");
 
 	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
 
-	if (!dbus_connection_add_filter(connection, signal_filter,
-						NULL, NULL))
-		error("Can't add signal filter");
-
-	dbus_bus_add_match(connection,
-			"type=signal,interface=" CSD_CALL_INTERFACE, NULL);
-	dbus_bus_add_match(connection,
-			"type=signal,interface=" CSD_CALL_INSTANCE, NULL);
-	dbus_bus_add_match(connection,
-			"type=signal,interface=" CSD_CALL_CONFERENCE, NULL);
-	dbus_bus_add_match(connection,
-			"type=signal,interface=" CSD_CSNET_REGISTRATION,
-			NULL);
-	dbus_bus_add_match(connection,
-			"type=signal,interface=" CSD_CSNET_OPERATOR,
-			NULL);
-	dbus_bus_add_match(connection,
-			"type=signal,interface=" CSD_CSNET_SIGNAL,
-			NULL);
-	dbus_bus_add_match(connection,
-				"type=signal,interface=" SSC_DBUS_IFACE
-				",member=modem_state_changed_ind", NULL);
+	watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+					CSD_CALL_INTERFACE, NULL,
+					signal_filter, NULL, NULL);
+
+	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
+
+	watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+					CSD_CALL_INSTANCE, NULL,
+					signal_filter, NULL, NULL);
+
+	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
+
+	watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+					CSD_CALL_CONFERENCE, NULL,
+					signal_filter, NULL, NULL);
+
+	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
+
+	watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+					CSD_CSNET_REGISTRATION, NULL,
+					signal_filter, NULL, NULL);
+
+	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
+
+	watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+					CSD_CSNET_OPERATOR, NULL,
+					signal_filter, NULL, NULL);
+
+	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
+
+	watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+					CSD_CSNET_SIGNAL, NULL,
+					signal_filter, NULL, NULL);
+
+	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
+
+	watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+					SSC_DBUS_IFACE,
+					"modem_state_changed_ind",
+					signal_filter, NULL, NULL);
+
+	watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
 
 	if (send_method_call(SSC_DBUS_NAME, SSC_DBUS_PATH, SSC_DBUS_IFACE,
 					"get_modem_state", modem_state_reply,
@@ -2005,8 +2027,15 @@ int telephony_init(void)
 	return 0;
 }
 
+static void remove_watch(gpointer data)
+{
+	g_dbus_remove_watch(connection, GPOINTER_TO_UINT(data));
+}
+
 void telephony_exit(void)
 {
+	DBG("");
+
 	g_free(net.operator_name);
 	net.operator_name = NULL;
 
@@ -2017,7 +2046,12 @@ void telephony_exit(void)
 	g_slist_free(calls);
 	calls = NULL;
 
-	dbus_connection_remove_filter(connection, signal_filter, NULL);
+	g_slist_foreach(watches, (GFunc) remove_watch, NULL);
+	g_slist_free(watches);
+	watches = NULL;
+
+	g_dbus_unregister_interface(connection, TELEPHONY_MAEMO_PATH,
+						TELEPHONY_MAEMO_INTERFACE);
 
 	dbus_connection_unref(connection);
 	connection = NULL;
-- 
1.7.1


^ permalink raw reply related

* [PATCH 2/3] Fix telephony dummy driver
From: Luiz Augusto von Dentz @ 2010-11-25 15:22 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1290698551-8706-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>

Make it unregister its interface on telephony_exit
---
 audio/telephony-dummy.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/audio/telephony-dummy.c b/audio/telephony-dummy.c
index 06cb798..54b1857 100644
--- a/audio/telephony-dummy.c
+++ b/audio/telephony-dummy.c
@@ -417,6 +417,8 @@ int telephony_init(void)
 				AG_FEATURE_ENHANCED_CALL_STATUS |
 				AG_FEATURE_EXTENDED_ERROR_RESULT_CODES;
 
+	DBG("");
+
 	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
 
 	if (g_dbus_register_interface(connection, TELEPHONY_DUMMY_PATH,
@@ -436,6 +438,10 @@ int telephony_init(void)
 
 void telephony_exit(void)
 {
+	DBG("");
+
+	g_dbus_unregister_interface(connection, TELEPHONY_DUMMY_PATH,
+						TELEPHONY_DUMMY_IFACE);
 	dbus_connection_unref(connection);
 	connection = NULL;
 }
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/3] Fix not deinitializing telephony driver when there is no adapter powered
From: Luiz Augusto von Dentz @ 2010-11-25 15:22 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>

This changes hook telephony driver de/initialization to powered state so
telephony drivers can now free their resources when there is no adapter
active in the system.
---
 audio/manager.c |   59 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/audio/manager.c b/audio/manager.c
index 816c807..8a5616d 100644
--- a/audio/manager.c
+++ b/audio/manager.c
@@ -96,6 +96,7 @@ typedef enum {
 
 struct audio_adapter {
 	struct btd_adapter *btd_adapter;
+	gboolean powered;
 	uint32_t hsp_ag_record_id;
 	uint32_t hfp_ag_record_id;
 	uint32_t hfp_hs_record_id;
@@ -858,6 +859,49 @@ static struct audio_adapter *audio_adapter_get(struct btd_adapter *adapter)
 	return adp;
 }
 
+static void state_changed(struct btd_adapter *adapter, gboolean powered)
+{
+	struct audio_adapter *adp;
+	static gboolean telephony = FALSE;
+	GSList *l;
+
+	DBG("%s powered %s", adapter_get_path(adapter),
+						powered ? "on" : "off");
+
+	/* ignore powered change, adapter is powering down */
+	if (powered && adapter_powering_down(adapter))
+		return;
+
+	adp = find_adapter(adapters, adapter);
+	if (!adp)
+		return;
+
+	adp->powered = powered;
+
+	if (powered) {
+		/* telephony driver already initialized*/
+		if (telephony == TRUE)
+			return;
+		telephony_init();
+		telephony = TRUE;
+		return;
+	}
+
+	/* telephony not initialized just ignore power down */
+	if (telephony == FALSE)
+		return;
+
+	for (l = adapters; l; l = l->next) {
+		adp = l->data;
+
+		if (adp->powered == TRUE)
+			return;
+	}
+
+	telephony_exit();
+	telephony = FALSE;
+}
+
 static int headset_server_probe(struct btd_adapter *adapter)
 {
 	struct audio_adapter *adp;
@@ -871,10 +915,15 @@ static int headset_server_probe(struct btd_adapter *adapter)
 		return -EINVAL;
 
 	err = headset_server_init(adp);
-	if (err < 0)
+	if (err < 0) {
 		audio_adapter_unref(adp);
+		return err;
+	}
 
-	return err;
+	btd_adapter_register_powered_callback(adapter, state_changed);
+	state_changed(adapter, TRUE);
+
+	return 0;
 }
 
 static void headset_server_remove(struct btd_adapter *adapter)
@@ -910,6 +959,8 @@ static void headset_server_remove(struct btd_adapter *adapter)
 		adp->hfp_ag_server = NULL;
 	}
 
+	btd_adapter_unregister_powered_callback(adapter, state_changed);
+
 	audio_adapter_unref(adp);
 }
 
@@ -1177,10 +1228,8 @@ proceed:
 	if (enabled.media)
 		btd_register_adapter_driver(&media_server_driver);
 
-	if (enabled.headset) {
-		telephony_init();
+	if (enabled.headset)
 		btd_register_adapter_driver(&headset_server_driver);
-	}
 
 	if (enabled.gateway)
 		btd_register_adapter_driver(&gateway_server_driver);
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH] Extend discover characteristic by UUID in gatttool to fetch all values
From: Johan Hedberg @ 2010-11-25 12:21 UTC (permalink / raw)
  To: Sheldon Demario; +Cc: linux-bluetooth
In-Reply-To: <1290515839-11867-1-git-send-email-sheldon.demario@openbossa.org>

Hi Sheldon,

On Tue, Nov 23, 2010, Sheldon Demario wrote:
> If the number of characteristics returned exceeds the MTU size, it will
> be needed to ask for more data until the handle range is entirely
> searched.
> ---
>  attrib/gatttool.c |   24 +++++++++++++++++++++++-
>  1 files changed, 23 insertions(+), 1 deletions(-)

Thanks.

> +	if ((status == ATT_ECODE_ATTR_NOT_FOUND) &&
> +			(char_data->start != opt_start))
> +		goto done;

No need for the extra () here. However, since it was the only issue I
found I fixed it myself and pushed the patch upstream.

Johan

^ permalink raw reply

* [PATCH] Fix crash after simultaneous authentication requests
From: Rafal Michalski @ 2010-11-25 10:06 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Rafal Michalski

Previously simultaneous authentication requests to the same device caused
bluetoothd crash. Now if ongoing authentication occurs error is returned,
preventing from simultaneous requests to the same device.
---
 src/device.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/src/device.c b/src/device.c
index 7c421e3..4427cd4 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2178,6 +2178,11 @@ int device_request_authentication(struct btd_device *device, auth_type_t type,
 	struct agent *agent;
 	int err;
 
+	if (device->authr) {
+		error("%s: authentication already requested", device->path);
+		return -EALREADY;
+	}
+
 	DBG("%s: requesting agent authentication", device->path);
 
 	agent = device_get_agent(device);
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 1/1] bluetooth: Fix NULL pointer dereference issue
From: Yuri Ershov @ 2010-11-25  9:55 UTC (permalink / raw)
  To: marcel, davem, padovan, jprvita
  Cc: linux-bluetooth, ville.tervo, andrei.emeltchenko, Yuri Ershov

This patch is an addition to my previous patch for this issue.
The problem is in resynchronization between two loops:
1. Main controlling loop (l2cap_connect_req, l2cap_config_req,
l2cap_config_rsp, l2cap_disconnect_req, etc.)
2. Loop waiting of BT_CONNECTED state of socket (l2cap_sock_accept,
bt_accept_dequeue, etc.).
In case of fast sequence of connect/disconnect operations the loop #1
makes several cycles, while the loop #2 only has time to make one
cycle and it results crash.
The aim of the patch is to skeep handling of sockets queued for
deletion.

Signed-off-by: Yuri Ershov <ext-yuri.ershov@nokia.com>
---
 net/bluetooth/af_bluetooth.c |    2 ++
 net/bluetooth/l2cap.c        |    6 ++++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index c4cf3f5..f9389da 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -200,6 +200,8 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
 	BT_DBG("parent %p", parent);
 
 	list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
+		if (n == p)
+			break;
 		sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
 
 		lock_sock(sk);
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 12b4aa2..29f30b0 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -133,7 +133,8 @@ static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
 {
 	struct sock *s;
 	for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-		if (l2cap_pi(s)->dcid == cid)
+		if ((l2cap_pi(s)->dcid == cid) &&
+		    (sk->sk_state != BT_DISCONN) && (sk->sk_state != BT_CLOSED))
 			break;
 	}
 	return s;
@@ -143,7 +144,8 @@ static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid)
 {
 	struct sock *s;
 	for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-		if (l2cap_pi(s)->scid == cid)
+		if ((l2cap_pi(s)->scid == cid) &&
+		    (sk->sk_state != BT_DISCONN) && (sk->sk_state != BT_CLOSED))
 			break;
 	}
 	return s;
-- 
1.6.3.3

^ permalink raw reply related

* Re: sdptool hanging remote
From: Vinicius Gomes @ 2010-11-24 22:55 UTC (permalink / raw)
  To: Grahame Jordan; +Cc: linux-bluetooth
In-Reply-To: <4CED942E.8080204@theforce.com.au>

Hi,

On Wed, Nov 24, 2010 at 7:39 PM, Grahame Jordan <gbj@theforce.com.au> wrote:
> Hi,
>
> I have tested 4.77 4.80 and git. All appear to have the same issue.
>
>
> 2000-01-02 07:35:12.360814 < ACL data: handle 256 flags 0x02 dlen 18
>    L2CAP(s): Config rsp: scid 0x0041 flags 0x00 result 0 clen 4
>      MTU 672
> 2000-01-02 07:35:12.360884 < ACL data: handle 256 flags 0x02 dlen 12
>    L2CAP(s): Config req: dcid 0x0041 flags 0x00 clen 0
> 2000-01-02 07:35:12.370559 > HCI Event: Number of Completed Packets (0x13)
> plen 5
>    handle 256 packets 1
> 2000-01-02 07:35:12.380596 > HCI Event: Number of Completed Packets (0x13)
> plen 5
>    handle 256 packets 1
> 2000-01-02 07:35:12.380628 > ACL data: handle 256 flags 0x02 dlen 18
>    L2CAP(s): Config rsp: scid 0x0041 flags 0x00 result 0 clen 4
>      MTU 672
> 2000-01-02 07:35:12.410670 > ACL data: handle 256 flags 0x02 dlen 23
>    L2CAP(d): cid 0x0041 len 19 [psm 1]
>        SDP SA Req: tid 0x0 len 0xe
>          handle 0x1001e
>          max 65535
>          aid(s) 0x0000 - 0xffff
>          cont 00
> 2000-01-02 07:35:12.412008 < ACL data: handle 256 flags 0x02 dlen 11
>    L2CAP(d): cid 0x0041 len 7 [psm 1]
>        SDP Error Rsp: tid 0x0 len 0x2
>          code 0x2 info none
> 2000-01-02 07:35:12.430720 > HCI Event: Number of Completed Packets (0x13)
> plen 5
>    handle 256 packets 1
> 2000-01-02 07:35:12.430756 > ACL data: handle 256 flags 0x02 dlen 12
>    L2CAP(s): Disconn req: dcid 0x0041 scid 0x0041
> 2000-01-02 07:35:12.430979 < ACL data: handle 256 flags 0x02 dlen 12
>    L2CAP(s): Disconn rsp: dcid 0x0041 scid 0x0041
> 2000-01-02 07:35:12.440583 > HCI Event: Number of Completed Packets (0x13)
> plen 5
>    handle 256 packets 1
> 2000-01-02 07:35:12.460651 > ACL data: ha
> # Hang here
>
> # Resumed after about 10 seconds
> ndle 256 flags 0x02 dlen 12
>    L2CAP(s): Connect req: psm 1 scid 0x0042
> 2000-01-02 07:35:12.460904 < ACL data: handle 256 flags 0x02 dlen 16
>    L2CAP(s)i2c: error: timeout

This ("i2c: error: timeout") looks strange. But could be unrelated.

Another thing that could be interesting to have is the hcidump of an
attempt using Ubuntu 8.04 (that you said that had no problems).

The output of "sdptool browse local", from the gumstix would be also useful.

> : Connect rsp: dcid 0x0041 scid 0x0042 result 0 status 0
>      i2c: msg_num: 0 msg_idx: 1 msg_ptr: 0
> Connection successful
> 2000-01-02 07:35:12.480629 > HCI Event: Ni2c: ICR: 000097e0 ISR: 00000000
> umber of Completed Packets (0x13) plen 5
>    handle 256 packets 1
> 2000-01-02 07:35:12.510724 > ACL data: handle 256 flags 0x02 dlen 12
>    L2CAP(s): Config req: dcid 0x0041 flags 0x00 clen 0
> 2000-01-02 07:35:12.510946 < ACL data: handle 256 flags 0x02 dlen 18
>    L2CAP(s): Config rsp: scid 0x0042 flags 0x00 result 0 clen 4
>      MTU 672
> ....
>
> 2000-01-02 07:35:34.220696 > ACL data: handle 256 flags 0x02 dlen 23
>    L2CAP(d): cid 0x0041 len 19 [psm 1]
>        SDP SA Req: tid 0x0 len 0xe
>          handle 0x1030a
>          max 65535
>          aid(s) 0x0000 - 0xffff
>          cont 00
> 2000-01-02 07:35:34.222038 < ACL data: handle 256 flags 0x02 dlen 11
>    L2CAP(d): cid 0x0041 len 7 [psm 1]
>        SDP Error Rsp: tid 0x0 len 0x2
>          code 0x2 info none
> 2000-01-02 07:35:34.250696 > HCI Event: Number of Completed Packets (0x13)
> plen 5
>    handle 256 packets 1
> 2000-01-02 07:35:34.250733 > ACL data: handle 256 flags 0x02 dlen 12
>    L2CAP(s): Disconn req: dcid 0x0041 scid 0x0041
> 2000-01-02 07:35:34.250962 < ACL data: handle 256 flags 0x02 dlen 12
>    L2CAP(s): Disconn rsp: dcid 0x0041 scid 0x0041
> 2000-01-02
> # Hang here
>
> # Pressed CTL-C on remote "sdptool records 00:80:37:2F:5A:77"
> 07:35:34.260581 > HCI Event: Number of Completed Packets (0x13) plen 5
>    handle 256 packets 1
> 2000-01-02 07:35:34.280679 > ACL data: handle 256 flags 0x02 dlen 12
>    L2CAP(s): Connect req: psm 1 scid 0x0042
> 2000-01-02 07:35:34.280930 < ACL data: handle 256 flags 0x02 dlen 16
>    L2CAP(s): Connect rsp: dcid 0x0041 scid 0x0042 result 0 status 0
>      Connection successful
> 2000-01-02 07:35:34.300522 > HCI Event: Number of Completed Packets (0x13)
> plen 5
>    handle 256 packets 1
>
> ...
>
>
> Thanks
>
> Grahame Jordan
>
>
> On 24/11/10 04:51, Vinicius Costa Gomes wrote:
>>
>> On 16:37 Tue 23 Nov     , Grahame Jordan wrote:
>>
>>> Hi,
>>>
>>> I am using bluez-4.77 on a Gumstix Verdex kernel 2.4.32 patch 21
>>>
>>> When I run:
>>> sdptool records 00:80:37:2F:06:08"
>>> from the Workstation Ubuntu 10.04 Bluez-4.6? to the Gumstix the Gumstix
>>> hangs.
>>> It does not hang completely but is very busy. It hangs for about 20
>>> seconds and then releases for about 1 second
>>> before it locks up again.
>>>
>> I couldn't find anything that could solve this kind of problem in the logs
>> between 4.6 and the git head. But anyway, could you give a try to 4.80, or
>> better yet, the git head[1]? and see if the problem still happens?
>>
>>
>>> I have tried this on several different Gumstix with the same issue.
>>>
>>> Changing workstations from Ubuntu 10.04 to Ubuntu 8.04 does make a
>>> difference.
>>>  From Ubuntu 8.04 there seems to be no problem. blue-utils 3.26?
>>>
>>>
>> A really helpful piece of information that you could provide is the
>> hcidump[2]
>> logs of both cases, just be sure to give hcidump the options "-V" (verbose
>> output) and "-t" (timestamps, to see where the hang happens).
>>
>>
>>> Appreciate help
>>>
>>>
>>> Thanks
>>>
>>> Grahame Jordan
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe
>>> linux-bluetooth" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>
>> Cheers,
>>
>
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth"
> in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


Cheers,
-- 
Vinicius

^ permalink raw reply

* Re: sdptool hanging remote
From: Grahame Jordan @ 2010-11-24 22:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20101123175156.GA30860@eris.indt.org>

Hi,

I have tested 4.77 4.80 and git. All appear to have the same issue.


2000-01-02 07:35:12.360814 < ACL data: handle 256 flags 0x02 dlen 18
     L2CAP(s): Config rsp: scid 0x0041 flags 0x00 result 0 clen 4
       MTU 672
2000-01-02 07:35:12.360884 < ACL data: handle 256 flags 0x02 dlen 12
     L2CAP(s): Config req: dcid 0x0041 flags 0x00 clen 0
2000-01-02 07:35:12.370559 > HCI Event: Number of Completed Packets 
(0x13) plen 5
     handle 256 packets 1
2000-01-02 07:35:12.380596 > HCI Event: Number of Completed Packets 
(0x13) plen 5
     handle 256 packets 1
2000-01-02 07:35:12.380628 > ACL data: handle 256 flags 0x02 dlen 18
     L2CAP(s): Config rsp: scid 0x0041 flags 0x00 result 0 clen 4
       MTU 672
2000-01-02 07:35:12.410670 > ACL data: handle 256 flags 0x02 dlen 23
     L2CAP(d): cid 0x0041 len 19 [psm 1]
         SDP SA Req: tid 0x0 len 0xe
           handle 0x1001e
           max 65535
           aid(s) 0x0000 - 0xffff
           cont 00
2000-01-02 07:35:12.412008 < ACL data: handle 256 flags 0x02 dlen 11
     L2CAP(d): cid 0x0041 len 7 [psm 1]
         SDP Error Rsp: tid 0x0 len 0x2
           code 0x2 info none
2000-01-02 07:35:12.430720 > HCI Event: Number of Completed Packets 
(0x13) plen 5
     handle 256 packets 1
2000-01-02 07:35:12.430756 > ACL data: handle 256 flags 0x02 dlen 12
     L2CAP(s): Disconn req: dcid 0x0041 scid 0x0041
2000-01-02 07:35:12.430979 < ACL data: handle 256 flags 0x02 dlen 12
     L2CAP(s): Disconn rsp: dcid 0x0041 scid 0x0041
2000-01-02 07:35:12.440583 > HCI Event: Number of Completed Packets 
(0x13) plen 5
     handle 256 packets 1
2000-01-02 07:35:12.460651 > ACL data: ha
# Hang here

# Resumed after about 10 seconds
ndle 256 flags 0x02 dlen 12
     L2CAP(s): Connect req: psm 1 scid 0x0042
2000-01-02 07:35:12.460904 < ACL data: handle 256 flags 0x02 dlen 16
     L2CAP(s)i2c: error: timeout
: Connect rsp: dcid 0x0041 scid 0x0042 result 0 status 0
       i2c: msg_num: 0 msg_idx: 1 msg_ptr: 0
Connection successful
2000-01-02 07:35:12.480629 > HCI Event: Ni2c: ICR: 000097e0 ISR: 00000000
umber of Completed Packets (0x13) plen 5
     handle 256 packets 1
2000-01-02 07:35:12.510724 > ACL data: handle 256 flags 0x02 dlen 12
     L2CAP(s): Config req: dcid 0x0041 flags 0x00 clen 0
2000-01-02 07:35:12.510946 < ACL data: handle 256 flags 0x02 dlen 18
     L2CAP(s): Config rsp: scid 0x0042 flags 0x00 result 0 clen 4
       MTU 672
....

2000-01-02 07:35:34.220696 > ACL data: handle 256 flags 0x02 dlen 23
     L2CAP(d): cid 0x0041 len 19 [psm 1]
         SDP SA Req: tid 0x0 len 0xe
           handle 0x1030a
           max 65535
           aid(s) 0x0000 - 0xffff
           cont 00
2000-01-02 07:35:34.222038 < ACL data: handle 256 flags 0x02 dlen 11
     L2CAP(d): cid 0x0041 len 7 [psm 1]
         SDP Error Rsp: tid 0x0 len 0x2
           code 0x2 info none
2000-01-02 07:35:34.250696 > HCI Event: Number of Completed Packets 
(0x13) plen 5
     handle 256 packets 1
2000-01-02 07:35:34.250733 > ACL data: handle 256 flags 0x02 dlen 12
     L2CAP(s): Disconn req: dcid 0x0041 scid 0x0041
2000-01-02 07:35:34.250962 < ACL data: handle 256 flags 0x02 dlen 12
     L2CAP(s): Disconn rsp: dcid 0x0041 scid 0x0041
2000-01-02
# Hang here

# Pressed CTL-C on remote "sdptool records 00:80:37:2F:5A:77"
07:35:34.260581 > HCI Event: Number of Completed Packets (0x13) plen 5
     handle 256 packets 1
2000-01-02 07:35:34.280679 > ACL data: handle 256 flags 0x02 dlen 12
     L2CAP(s): Connect req: psm 1 scid 0x0042
2000-01-02 07:35:34.280930 < ACL data: handle 256 flags 0x02 dlen 16
     L2CAP(s): Connect rsp: dcid 0x0041 scid 0x0042 result 0 status 0
       Connection successful
2000-01-02 07:35:34.300522 > HCI Event: Number of Completed Packets 
(0x13) plen 5
     handle 256 packets 1

...


Thanks

Grahame Jordan


On 24/11/10 04:51, Vinicius Costa Gomes wrote:
> On 16:37 Tue 23 Nov     , Grahame Jordan wrote:
>
>> Hi,
>>
>> I am using bluez-4.77 on a Gumstix Verdex kernel 2.4.32 patch 21
>>
>> When I run:
>> sdptool records 00:80:37:2F:06:08"
>> from the Workstation Ubuntu 10.04 Bluez-4.6? to the Gumstix the Gumstix
>> hangs.
>> It does not hang completely but is very busy. It hangs for about 20
>> seconds and then releases for about 1 second
>> before it locks up again.
>>
> I couldn't find anything that could solve this kind of problem in the logs
> between 4.6 and the git head. But anyway, could you give a try to 4.80, or
> better yet, the git head[1]? and see if the problem still happens?
>
>
>> I have tried this on several different Gumstix with the same issue.
>>
>> Changing workstations from Ubuntu 10.04 to Ubuntu 8.04 does make a
>> difference.
>>   From Ubuntu 8.04 there seems to be no problem. blue-utils 3.26?
>>
>>
> A really helpful piece of information that you could provide is the hcidump[2]
> logs of both cases, just be sure to give hcidump the options "-V" (verbose
> output) and "-t" (timestamps, to see where the hang happens).
>
>
>> Appreciate help
>>
>>
>> Thanks
>>
>> Grahame Jordan
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>
> Cheers,
>





^ permalink raw reply

* Re: [PATCH 2/3] Bluetooth: Add initial Bluetooth Management interface callbacks
From: Gustavo F. Padovan @ 2010-11-24 21:58 UTC (permalink / raw)
  To: Andrei Emeltchenko, linux-bluetooth
In-Reply-To: <20101124214747.GA8626@jh-x301>

* Johan Hedberg <johan.hedberg@gmail.com> [2010-11-24 23:47:47 +0200]:

> Hi Andrei,
> 
> On Wed, Nov 24, 2010, Andrei Emeltchenko wrote:
> > > -       if (haddr->hci_dev != HCI_DEV_NONE) {
> > > -               if (!(hdev = hci_dev_get(haddr->hci_dev))) {
> > > +       if (haddr.hci_dev != HCI_DEV_NONE) {
> > > +               if (!(hdev = hci_dev_get(haddr.hci_dev))) {
> > 
> > doesn't checkpatch give errors here?
> 
> Probably, but I've understood that it's ok if it's the existing code
> that contains the coding style issue.
> 
> > Would be more clean like:
> > ...
> > hdev = hci_dev_get(haddr.hci_dev);
> > if (!hdev)
> > ...
> > 
> > At some point shall be fixed in the old code also
> 
> Agreed. A separate code cleanup patch would be nice. I've intentionally
> kept the old style to not mix coding style and functional changes into
> the same patch and to make it clear that I'm not introducing any changes
> to the code logic at this place.

Yes, that should be a separated patch.

Johan, your patches are fine, but I have to wait the wireless-next-2.6
be synced with the net-next-2.6 tree. Then I'll able to apply it.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [PATCH 2/3] Bluetooth: Add initial Bluetooth Management interface callbacks
From: Johan Hedberg @ 2010-11-24 21:47 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <AANLkTik0x3tjnM85Mu=vwU6GB2pXAgWXnqe28aKS+QkN@mail.gmail.com>

Hi Andrei,

On Wed, Nov 24, 2010, Andrei Emeltchenko wrote:
> > -       if (haddr->hci_dev != HCI_DEV_NONE) {
> > -               if (!(hdev = hci_dev_get(haddr->hci_dev))) {
> > +       if (haddr.hci_dev != HCI_DEV_NONE) {
> > +               if (!(hdev = hci_dev_get(haddr.hci_dev))) {
> 
> doesn't checkpatch give errors here?

Probably, but I've understood that it's ok if it's the existing code
that contains the coding style issue.

> Would be more clean like:
> ...
> hdev = hci_dev_get(haddr.hci_dev);
> if (!hdev)
> ...
> 
> At some point shall be fixed in the old code also

Agreed. A separate code cleanup patch would be nice. I've intentionally
kept the old style to not mix coding style and functional changes into
the same patch and to make it clear that I'm not introducing any changes
to the code logic at this place.

Johan

^ permalink raw reply

* Re: [RFC 00/20] Simple SMP Just Works implementation
From: Gustavo F. Padovan @ 2010-11-24 21:08 UTC (permalink / raw)
  To: Ville Tervo; +Cc: ext Vinicius Costa Gomes, linux-bluetooth
In-Reply-To: <20101124054211.GI874@null>

Hi Ville,

* Ville Tervo <ville.tervo@nokia.com> [2010-11-24 07:42:11 +0200]:

> Hi,
> 
> 
> On Tue, Nov 23, 2010 at 12:06:16PM -0300, ext Vinicius Costa Gomes wrote:
> > Hi,
> > 
> > This is an implementation of the Just Works SMP procedure, on top of the work
> > done by Ville (included in this series to give some context). The SMP stuff
> > starts at 11/20.
> > 
> > The most important thing about this series is the discussion that (I hope)
> > it will cause.
> > 
> > Some things that I would like to point (in no order):
> > 
> > - the SMP function names follow the spec nomeclature, would it be better to
> >   use more meaningful names?
> > 
> > - the crypto transform is allocated during the adapter registration, is this
> >   the best place to do this?
> > 
> > - renaming l2cap.c to l2cap_core.c was the only way we could find to keep the
> >   SMP implementation separated from the "core" l2cap.
> 
> Gustavo do you have something against this change?

I'm ok with this change.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [PATCH v2] Bluetooth: Fix error handling for l2cap_init()
From: Gustavo F. Padovan @ 2010-11-24 21:05 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: Marcel Holtmann, linux-bluetooth
In-Reply-To: <AANLkTi=pwDA5JQCoz4QNO=mLAHuW+moNOEO4Nqz3jQrJ@mail.gmail.com>

Hi Anderson,

* Anderson Lizardo <anderson.lizardo@openbossa.org> [2010-11-24 11:13:30 -0=
400]:

> Hi Marcel,
>=20
> On Wed, Nov 24, 2010 at 8:42 AM, Marcel Holtmann <marcel@holtmann.org> wr=
ote:
> >> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> >> index 18a802c..7980e24 100644
> >> --- a/net/bluetooth/l2cap.c
> >> +++ b/net/bluetooth/l2cap.c
> >> @@ -4875,8 +4875,10 @@ static int __init l2cap_init(void)
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 return err;
> >>
> >> =A0 =A0 =A0 _busy_wq =3D create_singlethread_workqueue("l2cap");
> >> - =A0 =A0 if (!_busy_wq)
> >> - =A0 =A0 =A0 =A0 =A0 =A0 goto error;
> >> + =A0 =A0 if (!_busy_wq) {
> >> + =A0 =A0 =A0 =A0 =A0 =A0 err =3D -ENOMEM;
> >> + =A0 =A0 =A0 =A0 =A0 =A0 goto error_busy_wq;
> >> + =A0 =A0 }
> >
> > aren't these returning PTR_ERR etc.?
>=20
> No, create_singlethread_workqueue() is just a wrapper around
> __alloc_workqueue_key(), which returns eiter a kzalloc()'ed pointer,
> or NULL on error. There is no way to get the actual reason of the
> error, but by taking a look at the function we can see most (if not
> all) errors are -ENOMEM. Thus why I used it here.
>=20
> Padovan: so how to proceed here: keep the patch as is and keep
> semantics, of make your proposed changes (with a slightly risk of a
> race condition and having _busy_wq NULL) ?

I'm not sure that my idea is right, so I have another option here. On
create_singlethread_workqueue error, just call proto_unregister() and
then return -ENOMEM, and destroy your workqueue under the label error.
This way we avoid create a new label and also have a simple error
handling there.

--=20
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [PATCH 2/3] Bluetooth: Add initial Bluetooth Management interface callbacks
From: Gustavo F. Padovan @ 2010-11-24 19:10 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: johan.hedberg, linux-bluetooth, Johan Hedberg
In-Reply-To: <AANLkTimFz=FRPiGT31xt9wMjWoxC5cuKBubEqYNT0s=5@mail.gmail.com>

Hi Anderson,

* Anderson Lizardo <anderson.lizardo@openbossa.org> [2010-11-24 11:38:22 -0400]:

> Hi Johan,
> 
> On Wed, Nov 24, 2010 at 10:39 AM,  <johan.hedberg@gmail.com> wrote:
> >  static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
> >  {
> > -       struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
> > +       struct sockaddr_hci haddr;
> 
> Just out of curiosity: why is this change necessary (i.e. make a stack
> copy of addr data and use it instead of using a cast of addr)?
> 
> >        struct sock *sk = sock->sk;
> >        struct hci_dev *hdev = NULL;
> > -       int err = 0;
> > +       int len, err = 0;
> >
> >        BT_DBG("sock %p sk %p", sock, sk);
> >
> > -       if (!haddr || haddr->hci_family != AF_BLUETOOTH)
> > +       if (!addr)
> > +               return -EINVAL;
> > +
> > +       memset(&haddr, 0, sizeof(haddr));
> > +       len = min_t(unsigned int, sizeof(haddr), addr_len);
> > +       memcpy(&haddr, addr, len);
> 
> Looks like you are playing safe here, but looking at least a few
> ->bind() implementations I see most just cast the original struct
> sockaddr, which is has size (sizeof(unsigned short) + 14).

Older userspace versions can use smaller struct sockaddr, so it's a
better idea move to th stack and zero-filling the the struct before the
copy the data, this way if the size of the data copied is smaller than
the struct, the fields in the end of the struct will be filled with
zeros and not something stranger.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* [PATCH] sdpd header cleanup
From: Claudio Takahasi @ 2010-11-24 18:16 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 src/sdpd-request.c |   12 +++++++++++-
 src/sdpd.h         |   14 --------------
 2 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/src/sdpd-request.c b/src/sdpd-request.c
index 025de60..9e4b6b8 100644
--- a/src/sdpd-request.c
+++ b/src/sdpd-request.c
@@ -45,6 +45,16 @@
 #include "sdpd.h"
 #include "log.h"
 
+typedef struct {
+	uint32_t timestamp;
+	union {
+		uint16_t maxBytesSent;
+		uint16_t lastIndexSent;
+	} cStateValue;
+} sdp_cont_state_t;
+
+#define SDP_CONT_STATE_SIZE (sizeof(uint8_t) + sizeof(sdp_cont_state_t))
+
 #define MIN(x, y) ((x) < (y)) ? (x): (y)
 
 typedef struct _sdp_cstate_list sdp_cstate_list_t;
@@ -58,7 +68,7 @@ struct _sdp_cstate_list {
 static sdp_cstate_list_t *cstates;
 
 // FIXME: should probably remove it when it's found
-sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate)
+static sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate)
 {
 	sdp_cstate_list_t *p;
 
diff --git a/src/sdpd.h b/src/sdpd.h
index a46ad3c..f8e6ee7 100644
--- a/src/sdpd.h
+++ b/src/sdpd.h
@@ -79,20 +79,6 @@ void register_server_service(void);
 void register_device_id(const uint16_t vendor, const uint16_t product,
 						const uint16_t version);
 
-typedef struct {
-	uint32_t timestamp;
-	union {
-		uint16_t maxBytesSent;
-		uint16_t lastIndexSent;
-	} cStateValue;
-} sdp_cont_state_t;
-
-#define SDP_CONT_STATE_SIZE (sizeof(uint8_t) + sizeof(sdp_cont_state_t))
-
-sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate);
-void sdp_cstate_cache_init(void);
-void sdp_cstate_clean_buf(void);
-
 int record_sort(const void *r1, const void *r2);
 void sdp_svcdb_reset(void);
 void sdp_svcdb_collect_all(int sock);
-- 
1.7.3.2


^ permalink raw reply related

* Re: [PATCH 2/3] Bluetooth: Add initial Bluetooth Management interface callbacks
From: Anderson Lizardo @ 2010-11-24 15:38 UTC (permalink / raw)
  To: johan.hedberg; +Cc: linux-bluetooth, Johan Hedberg
In-Reply-To: <1290609575-28435-3-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

On Wed, Nov 24, 2010 at 10:39 AM,  <johan.hedberg@gmail.com> wrote:
>  static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
>  {
> -       struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
> +       struct sockaddr_hci haddr;

Just out of curiosity: why is this change necessary (i.e. make a stack
copy of addr data and use it instead of using a cast of addr)?

>        struct sock *sk = sock->sk;
>        struct hci_dev *hdev = NULL;
> -       int err = 0;
> +       int len, err = 0;
>
>        BT_DBG("sock %p sk %p", sock, sk);
>
> -       if (!haddr || haddr->hci_family != AF_BLUETOOTH)
> +       if (!addr)
> +               return -EINVAL;
> +
> +       memset(&haddr, 0, sizeof(haddr));
> +       len = min_t(unsigned int, sizeof(haddr), addr_len);
> +       memcpy(&haddr, addr, len);

Looks like you are playing safe here, but looking at least a few
->bind() implementations I see most just cast the original struct
sockaddr, which is has size (sizeof(unsigned short) + 14).

Regards,
-- 
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil

^ permalink raw reply

* Re: [PATCH v2] Bluetooth: Fix error handling for l2cap_init()
From: Anderson Lizardo @ 2010-11-24 15:13 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth, padovan
In-Reply-To: <1290602554.13641.13.camel@aeonflux.mpl.access-company.com>

Hi Marcel,

On Wed, Nov 24, 2010 at 8:42 AM, Marcel Holtmann <marcel@holtmann.org> wrot=
e:
>> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
>> index 18a802c..7980e24 100644
>> --- a/net/bluetooth/l2cap.c
>> +++ b/net/bluetooth/l2cap.c
>> @@ -4875,8 +4875,10 @@ static int __init l2cap_init(void)
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 return err;
>>
>> =A0 =A0 =A0 _busy_wq =3D create_singlethread_workqueue("l2cap");
>> - =A0 =A0 if (!_busy_wq)
>> - =A0 =A0 =A0 =A0 =A0 =A0 goto error;
>> + =A0 =A0 if (!_busy_wq) {
>> + =A0 =A0 =A0 =A0 =A0 =A0 err =3D -ENOMEM;
>> + =A0 =A0 =A0 =A0 =A0 =A0 goto error_busy_wq;
>> + =A0 =A0 }
>
> aren't these returning PTR_ERR etc.?

No, create_singlethread_workqueue() is just a wrapper around
__alloc_workqueue_key(), which returns eiter a kzalloc()'ed pointer,
or NULL on error. There is no way to get the actual reason of the
error, but by taking a look at the function we can see most (if not
all) errors are -ENOMEM. Thus why I used it here.

Padovan: so how to proceed here: keep the patch as is and keep
semantics, of make your proposed changes (with a slightly risk of a
race condition and having _busy_wq NULL) ?

Regards,
--=20
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil

^ permalink raw reply

* [PATCH 6/6] Code clean-up: lines longer 80 symbols removed
From: Dmitriy Paliy @ 2010-11-24 15:07 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Dmitriy Paliy
In-Reply-To: <1290611236-25656-1-git-send-email-dmitriy.paliy@nokia.com>

---
 plugins/pbap.c |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/plugins/pbap.c b/plugins/pbap.c
index e0df444..9d166d9 100644
--- a/plugins/pbap.c
+++ b/plugins/pbap.c
@@ -263,8 +263,8 @@ static void query_result(const char *buffer, size_t bufsize, int vcards,
 	if (!pbap->obj->buffer)
 		pbap->obj->buffer = g_string_new_len(buffer, bufsize);
 	else
-		pbap->obj->buffer = g_string_append_len(pbap->obj->buffer, buffer,
-								bufsize);
+		pbap->obj->buffer = g_string_append_len(pbap->obj->buffer,
+							buffer, bufsize);
 
 	obex_object_set_io_flags(pbap->obj, G_IO_IN, 0);
 }
@@ -423,11 +423,12 @@ static void cache_ready_notify(void *user_data)
 	for (; l && max; l = l->next, max--) {
 		const struct cache_entry *entry = l->data;
 
-		g_string_append_printf(pbap->obj->buffer, VCARD_LISTING_ELEMENT,
-						entry->handle, entry->name);
+		g_string_append_printf(pbap->obj->buffer,
+			VCARD_LISTING_ELEMENT, entry->handle, entry->name);
 	}
 
-	pbap->obj->buffer = g_string_append(pbap->obj->buffer, VCARD_LISTING_END);
+	pbap->obj->buffer = g_string_append(pbap->obj->buffer,
+							VCARD_LISTING_END);
 
 	g_slist_free(sorted);
 
-- 
1.7.0.4


^ permalink raw reply related


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