Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH] Fix crash while reading from mapped file
From: Lukasz Pawlik @ 2010-12-14 15:10 UTC (permalink / raw)
  To: johan.hedberg; +Cc: linux-bluetooth
In-Reply-To: <AANLkTinVMvv9KG0oG1C=_wA6t7LhcYcCunuYGTWyn1Hs@mail.gmail.com>

> I also wonder why we didn't use g_strsplit for this, it seems it would
> actually do the same, there is a little performance impact since we
> would have to iterate on the vector generated to call the callback
> while the current code do it in-place.

Marcel, Johan any thoughts about this ? Should we reimplement this
code using glib functions ?

Lukasz Pawlik

^ permalink raw reply

* Re: [PATCH] Error should be returned instead of unnecessary dict_append_array()
From: Johan Hedberg @ 2010-12-14 14:44 UTC (permalink / raw)
  To: Pawel Wieczorkiewicz; +Cc: linux-bluetooth
In-Reply-To: <1292336427-20380-1-git-send-email-pawel.wieczorkiewicz@tieto.com>

Hi Pawel,

On Tue, Dec 14, 2010, Pawel Wieczorkiewicz wrote:
> If there are no adapter up and running, there would be
> no elements to be added using dict_append_array(). We
> should return DBus error ".DoesNotExist", rather than
> appending NULL pointer and zero elements.
> 
> On behalf of ST-Ericsson SA
> ---
>  src/manager.c |    9 +++++++++
>  1 files changed, 9 insertions(+), 0 deletions(-)

Nack. Manager.GetProperties shouldn't fail if there no adapters. There
will be more properties coming in the future (a "DefaultAdapter"
property for sure) and could either have an empty array for the Adapters
or just leave out that key from the dictionary (i.e. in the worst case
we've got an empty dictionary, but that's fine too imho).

Johan

^ permalink raw reply

* [PATCH] Error should be returned instead of unnecessary dict_append_array()
From: Pawel Wieczorkiewicz @ 2010-12-14 14:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pawel Wieczorkiewicz

If there are no adapter up and running, there would be
no elements to be added using dict_append_array(). We
should return DBus error ".DoesNotExist", rather than
appending NULL pointer and zero elements.

On behalf of ST-Ericsson SA
---
 src/manager.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/src/manager.c b/src/manager.c
index c8ec7e5..9060180 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -185,12 +185,21 @@ static DBusMessage *get_properties(DBusConnection *conn,
 		array[i] = (char *) adapter_get_path(adapter);
 		i++;
 	}
+
+	if (!i)
+		goto error;
+
 	dict_append_array(&dict, "Adapters", DBUS_TYPE_OBJECT_PATH, &array, i);
 	g_free(array);
 
 	dbus_message_iter_close_container(&iter, &dict);
 
 	return reply;
+
+error:
+	g_free(array);
+	g_free(reply);
+	return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist", "Adapter does not exist");
 }
 
 static GDBusMethodTable manager_methods[] = {
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 2/2] drivers:staging: ti-st: update the TI ST BT driver
From: pavan_savoy @ 2010-12-14 12:06 UTC (permalink / raw)
  To: gregkh, linux-kernel; +Cc: padovan, marcel, linux-bluetooth, Pavan Savoy
In-Reply-To: <1292328400-7649-2-git-send-email-pavan_savoy@ti.com>

From: Pavan Savoy <pavan_savoy@ti.com>

Update the bluetooth driver for TI-ST with the latest
bluetooth btwilink driver v7, which had undergone several
reviews.
The driver by itself was un-acceptable because of certain
design/architecture in the underlying TI ST driver.
So, park this driver here, as plans to work on the underlying
driver layer (TI-ST) is carried out.

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

diff --git a/drivers/staging/ti-st/Kconfig b/drivers/staging/ti-st/Kconfig
new file mode 100644
index 0000000..3cf6c3e
--- /dev/null
+++ b/drivers/staging/ti-st/Kconfig
@@ -0,0 +1,13 @@
+menu "Texas Instruments shared transport line discipline"
+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/staging/ti-st/Makefile b/drivers/staging/ti-st/Makefile
new file mode 100644
index 0000000..8b8a795
--- /dev/null
+++ b/drivers/staging/ti-st/Makefile
@@ -0,0 +1 @@
++obj-$(CONFIG_BT_WILINK)                += btwilink.o
diff --git a/drivers/staging/ti-st/btwilink.c b/drivers/staging/ti-st/btwilink.c
new file mode 100644
index 0000000..71e69f8
--- /dev/null
+++ b/drivers/staging/ti-st/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.6.3.3

^ permalink raw reply related

* [PATCH 1/2] drivers:staging: ti-st: remove bt_drv
From: pavan_savoy @ 2010-12-14 12:06 UTC (permalink / raw)
  To: gregkh, linux-kernel; +Cc: padovan, marcel, linux-bluetooth, Pavan Savoy
In-Reply-To: <1292328400-7649-1-git-send-email-pavan_savoy@ti.com>

From: Pavan Savoy <pavan_savoy@ti.com>

Remove the BT driver from the staging folder.
This is to update the staging folder with the
latest BT driver.

Signed-off-by: Pavan Savoy <pavan_savoy@ti.com>
---
 drivers/staging/ti-st/Kconfig   |   14 -
 drivers/staging/ti-st/Makefile  |    5 -
 drivers/staging/ti-st/bt_drv.c  |  509 ---------------------------------------
 drivers/staging/ti-st/bt_drv.h  |   61 -----
 drivers/staging/ti-st/sysfs-uim |   28 ---
 5 files changed, 0 insertions(+), 617 deletions(-)
 delete mode 100644 drivers/staging/ti-st/Kconfig
 delete mode 100644 drivers/staging/ti-st/Makefile
 delete mode 100644 drivers/staging/ti-st/bt_drv.c
 delete mode 100644 drivers/staging/ti-st/bt_drv.h
 delete mode 100644 drivers/staging/ti-st/sysfs-uim

diff --git a/drivers/staging/ti-st/Kconfig b/drivers/staging/ti-st/Kconfig
deleted file mode 100644
index 074b8e8..0000000
--- a/drivers/staging/ti-st/Kconfig
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# TI's shared transport line discipline and the protocol
-# drivers (BT, FM and GPS)
-#
-menu "Texas Instruments shared transport line discipline"
-config ST_BT
-	tristate "BlueZ bluetooth driver for ST"
-	depends on BT && RFKILL
-	select TI_ST
-	help
-	  This enables the Bluetooth driver for TI 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.
-endmenu
diff --git a/drivers/staging/ti-st/Makefile b/drivers/staging/ti-st/Makefile
deleted file mode 100644
index 5f11b82..0000000
--- a/drivers/staging/ti-st/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# Makefile for TI's shared transport line discipline
-# and its protocol drivers (BT, FM, GPS)
-#
-obj-$(CONFIG_ST_BT) 		+= bt_drv.o
diff --git a/drivers/staging/ti-st/bt_drv.c b/drivers/staging/ti-st/bt_drv.c
deleted file mode 100644
index 75065bf..0000000
--- a/drivers/staging/ti-st/bt_drv.c
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- *  Texas Instrument's Bluetooth Driver For Shared Transport.
- *
- *  Bluetooth Driver acts as interface between HCI CORE and
- *  TI Shared Transport Layer.
- *
- *  Copyright (C) 2009 Texas Instruments
- *
- *  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 <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/hci_core.h>
-
-#include <linux/ti_wilink_st.h>
-#include "bt_drv.h"
-
-/* Define this macro to get debug msg */
-#undef DEBUG
-
-#ifdef DEBUG
-#define BT_DRV_DBG(fmt, arg...)  printk(KERN_INFO "(btdrv):"fmt"\n" , ## arg)
-#define BTDRV_API_START()        printk(KERN_INFO "(btdrv): %s Start\n", \
-	__func__)
-#define BTDRV_API_EXIT(errno)    printk(KERN_INFO "(btdrv): %s Exit(%d)\n", \
-	__func__, errno)
-#else
-#define BT_DRV_DBG(fmt, arg...)
-#define BTDRV_API_START()
-#define BTDRV_API_EXIT(errno)
-#endif
-
-#define BT_DRV_ERR(fmt, arg...)  printk(KERN_ERR "(btdrv):"fmt"\n" , ## arg)
-
-static int reset;
-static struct hci_st *hst;
-
-/* Increments HCI counters based on pocket ID (cmd,acl,sco) */
-static inline void hci_st_tx_complete(struct hci_st *hst, int pkt_type)
-{
-	struct hci_dev *hdev;
-
-	BTDRV_API_START();
-
-	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.cmd_tx++;
-		break;
-	}
-
-	BTDRV_API_EXIT(0);
-}
-
-/* ------- Interfaces to Shared Transport ------ */
-
-/* Called by ST layer to indicate protocol registration completion
- * status.hci_st_open() function will wait for signal from this
- * API when st_register() function returns ST_PENDING.
- */
-static void hci_st_registration_completion_cb(void *priv_data, char data)
-{
-	struct hci_st *lhst = (struct hci_st *)priv_data;
-	BTDRV_API_START();
-
-	/* hci_st_open() function needs value of 'data' to know
-	 * the registration status(success/fail),So have a back
-	 * up of it.
-	 */
-	lhst->streg_cbdata = data;
-
-	/* Got a feedback from ST for BT driver registration
-	 * request.Wackup hci_st_open() function to continue
-	 * it's open operation.
-	 */
-	complete(&lhst->wait_for_btdrv_reg_completion);
-
-	BTDRV_API_EXIT(0);
-}
-
-/* Called by Shared Transport layer when receive data is
- * available */
-static long hci_st_receive(void *priv_data, struct sk_buff *skb)
-{
-	int err;
-	int len;
-	struct hci_st *lhst = (struct hci_st *)priv_data;
-
-	BTDRV_API_START();
-
-	err = 0;
-	len = 0;
-
-	if (skb == NULL) {
-		BT_DRV_ERR("Invalid SKB received from ST");
-		BTDRV_API_EXIT(-EFAULT);
-		return -EFAULT;
-	}
-	if (!lhst) {
-		kfree_skb(skb);
-		BT_DRV_ERR("Invalid hci_st memory,freeing SKB");
-		BTDRV_API_EXIT(-EFAULT);
-		return -EFAULT;
-	}
-	if (!test_bit(BT_DRV_RUNNING, &lhst->flags)) {
-		kfree_skb(skb);
-		BT_DRV_ERR("Device is not running,freeing SKB");
-		BTDRV_API_EXIT(-EINVAL);
-		return -EINVAL;
-	}
-
-	len = skb->len;
-	skb->dev = (struct net_device *)lhst->hdev;
-
-	/* Forward skb to HCI CORE layer */
-	err = hci_recv_frame(skb);
-	if (err) {
-		kfree_skb(skb);
-		BT_DRV_ERR("Unable to push skb to HCI CORE(%d),freeing SKB",
-			   err);
-		BTDRV_API_EXIT(err);
-		return err;
-	}
-	lhst->hdev->stat.byte_rx += len;
-
-	BTDRV_API_EXIT(0);
-	return 0;
-}
-
-/* ------- Interfaces to HCI layer ------ */
-
-/* Called from HCI core to initialize the device */
-static int hci_st_open(struct hci_dev *hdev)
-{
-	static struct st_proto_s hci_st_proto;
-	unsigned long timeleft;
-	int err;
-
-	BTDRV_API_START();
-
-	err = 0;
-
-	BT_DRV_DBG("%s %p", hdev->name, hdev);
-
-	/* Already registered with ST ? */
-	if (test_bit(BT_ST_REGISTERED, &hst->flags)) {
-		BT_DRV_ERR("Registered with ST already,open called again?");
-		BTDRV_API_EXIT(0);
-		return 0;
-	}
-
-	/* Populate BT driver info required by ST */
-	memset(&hci_st_proto, 0, sizeof(hci_st_proto));
-
-	/* BT driver ID */
-	hci_st_proto.type = ST_BT;
-
-	/* Receive function which called from ST */
-	hci_st_proto.recv = hci_st_receive;
-
-	/* Packet match function may used in future */
-	hci_st_proto.match_packet = NULL;
-
-	/* Callback to be called when registration is pending */
-	hci_st_proto.reg_complete_cb = hci_st_registration_completion_cb;
-
-	/* This is write function pointer of ST. BT driver will make use of this
-	 * for sending any packets to chip. ST will assign and give to us, so
-	 * make it as NULL */
-	hci_st_proto.write = NULL;
-
-	/* send in the hst to be received at registration complete callback
-	 * and during st's receive
-	 */
-	hci_st_proto.priv_data = hst;
-
-	/* Register with ST layer */
-	err = st_register(&hci_st_proto);
-	if (err == -EINPROGRESS) {
-		/* Prepare wait-for-completion handler data structures.
-		 * Needed to syncronize this and st_registration_completion_cb()
-		 * functions.
-		 */
-		init_completion(&hst->wait_for_btdrv_reg_completion);
-
-		/* Reset ST registration callback status flag , this value
-		 * will be updated in hci_st_registration_completion_cb()
-		 * function whenever it called from ST driver.
-		 */
-		hst->streg_cbdata = -EINPROGRESS;
-
-		/* ST is busy with other protocol registration(may be busy with
-		 * firmware download).So,Wait till the registration callback
-		 * (passed as a argument to st_register() function) getting
-		 * called from ST.
-		 */
-		BT_DRV_DBG(" %s waiting for reg completion signal from ST",
-			   __func__);
-
-		timeleft =
-		    wait_for_completion_timeout
-		    (&hst->wait_for_btdrv_reg_completion,
-		     msecs_to_jiffies(BT_REGISTER_TIMEOUT));
-		if (!timeleft) {
-			BT_DRV_ERR("Timeout(%ld sec),didn't get reg"
-				   "completion signal from ST",
-				   BT_REGISTER_TIMEOUT / 1000);
-			BTDRV_API_EXIT(-ETIMEDOUT);
-			return -ETIMEDOUT;
-		}
-
-		/* Is ST registration callback called with ERROR value? */
-		if (hst->streg_cbdata != 0) {
-			BT_DRV_ERR("ST reg completion CB called with invalid"
-				   "status %d", hst->streg_cbdata);
-			BTDRV_API_EXIT(-EAGAIN);
-			return -EAGAIN;
-		}
-		err = 0;
-	} else if (err == -1) {
-		BT_DRV_ERR("st_register failed %d", err);
-		BTDRV_API_EXIT(-EAGAIN);
-		return -EAGAIN;
-	}
-
-	/* Do we have proper ST write function? */
-	if (hci_st_proto.write != NULL) {
-		/* We need this pointer for sending any Bluetooth pkts */
-		hst->st_write = hci_st_proto.write;
-	} else {
-		BT_DRV_ERR("failed to get ST write func pointer");
-
-		/* Undo registration with ST */
-		err = st_unregister(ST_BT);
-		if (err < 0)
-			BT_DRV_ERR("st_unregister failed %d", err);
-
-		hst->st_write = NULL;
-		BTDRV_API_EXIT(-EAGAIN);
-		return -EAGAIN;
-	}
-
-	/* Registration with ST layer is completed successfully,
-	 * now chip is ready to accept commands from HCI CORE.
-	 * Mark HCI Device flag as RUNNING
-	 */
-	set_bit(HCI_RUNNING, &hdev->flags);
-
-	/* Registration with ST successful */
-	set_bit(BT_ST_REGISTERED, &hst->flags);
-
-	BTDRV_API_EXIT(err);
-	return err;
-}
-
-/* Close device */
-static int hci_st_close(struct hci_dev *hdev)
-{
-	int err;
-
-	BTDRV_API_START();
-
-	err = 0;
-
-	/* Unregister from ST layer */
-	if (test_and_clear_bit(BT_ST_REGISTERED, &hst->flags)) {
-		err = st_unregister(ST_BT);
-		if (err != 0) {
-			BT_DRV_ERR("st_unregister failed %d", err);
-			BTDRV_API_EXIT(-EBUSY);
-			return -EBUSY;
-		}
-	}
-
-	hst->st_write = NULL;
-
-	/* ST layer would have moved chip to inactive state.
-	 * So,clear HCI device RUNNING flag.
-	 */
-	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) {
-		BTDRV_API_EXIT(0);
-		return 0;
-	}
-
-	BTDRV_API_EXIT(err);
-	return err;
-}
-
-/* Called from HCI CORE , Sends frames to Shared Transport */
-static int hci_st_send_frame(struct sk_buff *skb)
-{
-	struct hci_dev *hdev;
-	struct hci_st *hst;
-	long len;
-
-	BTDRV_API_START();
-
-	if (skb == NULL) {
-		BT_DRV_ERR("Invalid skb received from HCI CORE");
-		BTDRV_API_EXIT(-ENOMEM);
-		return -ENOMEM;
-	}
-	hdev = (struct hci_dev *)skb->dev;
-	if (!hdev) {
-		BT_DRV_ERR("SKB received for invalid HCI Device (hdev=NULL)");
-		BTDRV_API_EXIT(-ENODEV);
-		return -ENODEV;
-	}
-	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
-		BT_DRV_ERR("Device is not running");
-		BTDRV_API_EXIT(-EBUSY);
-		return -EBUSY;
-	}
-
-	hst = (struct hci_st *)hdev->driver_data;
-
-	/* Prepend skb with frame type */
-	memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
-
-	BT_DRV_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.
-	 */
-	if (!hst->st_write) {
-		kfree_skb(skb);
-		BT_DRV_ERR(" Can't write to ST, st_write null?");
-		BTDRV_API_EXIT(-EAGAIN);
-		return -EAGAIN;
-	}
-	len = hst->st_write(skb);
-	if (len < 0) {
-		/* Something went wrong in st write , free skb memory */
-		kfree_skb(skb);
-		BT_DRV_ERR(" ST write failed (%ld)", len);
-		BTDRV_API_EXIT(-EAGAIN);
-		return -EAGAIN;
-	}
-
-	/* ST accepted our skb. So, Go ahead and do rest */
-	hdev->stat.byte_tx += len;
-	hci_st_tx_complete(hst, bt_cb(skb)->pkt_type);
-
-	BTDRV_API_EXIT(0);
-	return 0;
-}
-
-static void hci_st_destruct(struct hci_dev *hdev)
-{
-	BTDRV_API_START();
-
-	if (!hdev) {
-		BT_DRV_ERR("Destruct called with invalid HCI Device"
-			   "(hdev=NULL)");
-		BTDRV_API_EXIT(0);
-		return;
-	}
-
-	BT_DRV_DBG("%s", hdev->name);
-
-	/* free hci_st memory */
-	if (hdev->driver_data != NULL)
-		kfree(hdev->driver_data);
-
-	BTDRV_API_EXIT(0);
-	return;
-}
-
-/* Creates new HCI device */
-static int hci_st_register_dev(struct hci_st *hst)
-{
-	struct hci_dev *hdev;
-
-	BTDRV_API_START();
-
-	/* Initialize and register HCI device */
-	hdev = hci_alloc_dev();
-	if (!hdev) {
-		BT_DRV_ERR("Can't allocate HCI device");
-		BTDRV_API_EXIT(-ENOMEM);
-		return -ENOMEM;
-	}
-	BT_DRV_DBG(" HCI device allocated. hdev= %p", hdev);
-
-	hst->hdev = hdev;
-	hdev->bus = HCI_UART;
-	hdev->driver_data = hst;
-	hdev->open = hci_st_open;
-	hdev->close = hci_st_close;
-	hdev->flush = NULL;
-	hdev->send = hci_st_send_frame;
-	hdev->destruct = hci_st_destruct;
-	hdev->owner = THIS_MODULE;
-
-	if (reset)
-		set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
-
-	if (hci_register_dev(hdev) < 0) {
-		BT_DRV_ERR("Can't register HCI device");
-		hci_free_dev(hdev);
-		BTDRV_API_EXIT(-ENODEV);
-		return -ENODEV;
-	}
-
-	BT_DRV_DBG(" HCI device registered. hdev= %p", hdev);
-	BTDRV_API_EXIT(0);
-	return 0;
-}
-
-/* ------- Module Init interface ------ */
-
-static int __init bt_drv_init(void)
-{
-	int err;
-
-	BTDRV_API_START();
-
-	err = 0;
-
-	BT_DRV_DBG(" Bluetooth Driver Version %s", VERSION);
-
-	/* Allocate local resource memory */
-	hst = kzalloc(sizeof(struct hci_st), GFP_KERNEL);
-	if (!hst) {
-		BT_DRV_ERR("Can't allocate control structure");
-		BTDRV_API_EXIT(-ENFILE);
-		return -ENFILE;
-	}
-
-	/* Expose "hciX" device to user space */
-	err = hci_st_register_dev(hst);
-	if (err) {
-		/* Release local resource memory */
-		kfree(hst);
-
-		BT_DRV_ERR("Unable to expose hci0 device(%d)", err);
-		BTDRV_API_EXIT(err);
-		return err;
-	}
-	set_bit(BT_DRV_RUNNING, &hst->flags);
-
-	BTDRV_API_EXIT(err);
-	return err;
-}
-
-/* ------- Module Exit interface ------ */
-
-static void __exit bt_drv_exit(void)
-{
-	BTDRV_API_START();
-
-	/* Deallocate local resource's memory  */
-	if (hst) {
-		struct hci_dev *hdev = hst->hdev;
-
-		if (hdev == NULL) {
-			BT_DRV_ERR("Invalid hdev memory");
-			kfree(hst);
-		} else {
-			hci_st_close(hdev);
-			if (test_and_clear_bit(BT_DRV_RUNNING, &hst->flags)) {
-				/* Remove HCI device (hciX) created
-				 * in module init.
-				 */
-				hci_unregister_dev(hdev);
-
-				/* Free HCI device memory */
-				hci_free_dev(hdev);
-			}
-		}
-	}
-	BTDRV_API_EXIT(0);
-}
-
-module_init(bt_drv_init);
-module_exit(bt_drv_exit);
-
-/* ------ Module Info ------ */
-
-module_param(reset, bool, 0644);
-MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
-MODULE_AUTHOR("Raja Mani <raja_mani@ti.com>");
-MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION);
-MODULE_VERSION(VERSION);
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/ti-st/bt_drv.h b/drivers/staging/ti-st/bt_drv.h
deleted file mode 100644
index a0beebe..0000000
--- a/drivers/staging/ti-st/bt_drv.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *  Texas Instrument's Bluetooth Driver For Shared Transport.
- *
- *  Bluetooth Driver acts as interface between HCI CORE and
- *  TI Shared Transport Layer.
- *
- *  Copyright (C) 2009 Texas Instruments
- *
- *  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
- *
- */
-
-#ifndef _BT_DRV_H
-#define _BT_DRV_H
-
-/* Bluetooth Driver Version */
-#define VERSION               "1.0"
-
-/* Defines number of seconds to wait for reg completion
- * callback getting called from ST (in case,registration
- * with ST returns PENDING status)
- */
-#define BT_REGISTER_TIMEOUT   msecs_to_jiffies(6000)	/* 6 sec */
-
-/* BT driver's local status */
-#define BT_DRV_RUNNING        0
-#define BT_ST_REGISTERED      1
-
-/* BT driver operation structure */
-struct hci_st {
-
-	/* hci device pointer which binds to bt driver */
-	struct hci_dev *hdev;
-
-	/* used locally,to maintain various BT driver status */
-	unsigned long flags;
-
-	/* to hold ST registration callback  status */
-	char streg_cbdata;
-
-	/* write function pointer of ST driver */
-	long (*st_write) (struct sk_buff *);
-
-	/* Wait on comepletion handler needed to synchronize
-	 * hci_st_open() and hci_st_registration_completion_cb()
-	 * functions.*/
-	struct completion wait_for_btdrv_reg_completion;
-};
-
-#endif
diff --git a/drivers/staging/ti-st/sysfs-uim b/drivers/staging/ti-st/sysfs-uim
deleted file mode 100644
index 626bda5..0000000
--- a/drivers/staging/ti-st/sysfs-uim
+++ /dev/null
@@ -1,28 +0,0 @@
-What:           /sys/class/rfkill/rfkill%d/
-Date:           March 22
-Contact:        Pavan Savoy <pavan_savoy@ti.com>
-Description:
-		Creates the rfkill entries for Radio apps like
-		BT app, FM app or GPS app to toggle corresponding
-		cores of the chip
-
-What:           /dev/rfkill
-Date:           March 22
-Contact:        Pavan Savoy <pavan_savoy@ti.com>
-Description:
-		A daemon which maintains the ldisc installation and
-		uninstallation would be ppolling on this device and listening
-		on events which would suggest either to install or un-install
-		line discipline
-
-What:           /sys/kernel/debug/ti-st/version
-Contact:        Pavan Savoy <pavan_savoy@ti.com>
-Description:
-		WiLink chip's ROM version exposed to user-space for some
-		proprietary protocol stacks to make use of.
-
-What:           /sys/kernel/debug/ti-st/protocols
-Contact:        Pavan Savoy <pavan_savoy@ti.com>
-Description:
-		The reason for chip being ON, the list of protocols registered.
-
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH 0/2] keep ti-st staging updated
From: pavan_savoy @ 2010-12-14 12:06 UTC (permalink / raw)
  To: gregkh, linux-kernel; +Cc: padovan, marcel, linux-bluetooth, Pavan Savoy

From: Pavan Savoy <pavan_savoy@ti.com>

Greg,

In my attempt to upstream BT driver based on TI ST driver,
I had posted several patches to linux-bluetooth.

At this point, there are no review comments as such specifically
to bluetooth driver but there are few concerns regarding the TI-ST driver itself.

As I await the responses from Gustavo, Marcel on how best to proceed
in improving btwilink driver, I am deleting the very old bt_drv from
the staging and updating it with relatively acceptable btwilink driver.

Pavan Savoy (2):
  drivers:staging: ti-st: remove bt_drv
  drivers:staging: ti-st: update the TI ST BT driver

 drivers/staging/ti-st/Kconfig    |   25 +-
 drivers/staging/ti-st/Makefile   |    6 +-
 drivers/staging/ti-st/bt_drv.c   |  509 --------------------------------------
 drivers/staging/ti-st/bt_drv.h   |   61 -----
 drivers/staging/ti-st/btwilink.c |  363 +++++++++++++++++++++++++++
 drivers/staging/ti-st/sysfs-uim  |   28 --
 6 files changed, 376 insertions(+), 616 deletions(-)
 delete mode 100644 drivers/staging/ti-st/bt_drv.c
 delete mode 100644 drivers/staging/ti-st/bt_drv.h
 create mode 100644 drivers/staging/ti-st/btwilink.c
 delete mode 100644 drivers/staging/ti-st/sysfs-uim

^ permalink raw reply

* [PATCH 2/2] Bluetooth: Fix __hci_request synchronization for hci_open_dev
From: johan.hedberg @ 2010-12-14 12:04 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292328244-5335-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@nokia.com>

The initialization function used by hci_open_dev (hci_init_req) sends
many different HCI commands. The __hci_request function should only
return when all of these commands have completed (or a timeout occurs).
Several of these commands cause hci_req_complete to be called which
causes __hci_request to return prematurely.

This patch fixes the issue by making use of the HCI_INIT flag which is
set during the initialization procedure. The hci_req_comple function
will no longer do anything when this flag is set and a new
hci_init_complete function is added which ignores the flag and gets
called when the last hci_init_req HCI command completes.

Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
 include/net/bluetooth/hci_core.h |    1 +
 net/bluetooth/hci_core.c         |   14 ++++++++++++++
 net/bluetooth/hci_event.c        |   14 ++++++++++++++
 3 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 3786ee8..1f421df 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -694,5 +694,6 @@ struct hci_sec_filter {
 #define hci_req_unlock(d)	mutex_unlock(&d->req_lock)
 
 void hci_req_complete(struct hci_dev *hdev, int result);
+void hci_init_complete(struct hci_dev *hdev, int result);
 
 #endif /* __HCI_CORE_H */
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 6374054..8d08538 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -91,10 +91,24 @@ static void hci_notify(struct hci_dev *hdev, int event)
 
 /* ---- HCI requests ---- */
 
+void hci_init_complete(struct hci_dev *hdev, int result)
+{
+	BT_DBG("%s result 0x%2.2x", hdev->name, result);
+
+	if (hdev->req_status == HCI_REQ_PEND) {
+		hdev->req_result = result;
+		hdev->req_status = HCI_REQ_DONE;
+		wake_up_interruptible(&hdev->req_wait_q);
+	}
+}
+
 void hci_req_complete(struct hci_dev *hdev, int result)
 {
 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
 
+	if (test_bit(HCI_INIT, &hdev->flags))
+		return;
+
 	if (hdev->req_status == HCI_REQ_PEND) {
 		hdev->req_result = result;
 		hdev->req_status = HCI_REQ_DONE;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8923b36..939ba9f 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -539,6 +539,16 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_req_complete(hdev, rp->status);
 }
 
+static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status = *((__u8 *) skb->data);
+
+	BT_DBG("%s status 0x%x", hdev->name, status);
+
+	if (test_bit(HCI_INIT, &hdev->flags))
+		hci_init_complete(hdev, status);
+}
+
 static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
 {
 	BT_DBG("%s status 0x%x", hdev->name, status);
@@ -1379,6 +1389,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
 		hci_cc_read_bd_addr(hdev, skb);
 		break;
 
+	case HCI_OP_WRITE_CA_TIMEOUT:
+		hci_cc_write_ca_timeout(hdev, skb);
+		break;
+
 	default:
 		BT_DBG("%s opcode 0x%x", hdev->name, opcode);
 		break;
-- 
1.7.2.3


^ permalink raw reply related

* [PATCH 1/2] Bluetooth: Introduce a new HCI_CLOSE flag for hci_dev_close()
From: johan.hedberg @ 2010-12-14 12:04 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292328244-5335-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@nokia.com>

To be able to handle the intialization state differently from the
closing state (e.g. different sets of HCI commands are sent in them) a
distinct state flag should be used when closing a device.

Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
 include/net/bluetooth/hci.h |    1 +
 net/bluetooth/hci_core.c    |   10 ++++++----
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 29a7a8c..517a652 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -68,6 +68,7 @@ enum {
 	HCI_UP,
 	HCI_INIT,
 	HCI_RUNNING,
+	HCI_CLOSE,
 
 	HCI_PSCAN,
 	HCI_ISCAN,
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 1a4ec97..6374054 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -581,10 +581,10 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 	skb_queue_purge(&hdev->cmd_q);
 	atomic_set(&hdev->cmd_cnt, 1);
 	if (!test_bit(HCI_RAW, &hdev->flags)) {
-		set_bit(HCI_INIT, &hdev->flags);
+		set_bit(HCI_CLOSE, &hdev->flags);
 		__hci_request(hdev, hci_reset_req, 0,
 					msecs_to_jiffies(250));
-		clear_bit(HCI_INIT, &hdev->flags);
+		clear_bit(HCI_CLOSE, &hdev->flags);
 	}
 
 	/* Kill cmd task */
@@ -1029,7 +1029,8 @@ int hci_recv_frame(struct sk_buff *skb)
 {
 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
-				&& !test_bit(HCI_INIT, &hdev->flags))) {
+				&& !test_bit(HCI_INIT, &hdev->flags)
+				&& !test_bit(HCI_CLOSE, &hdev->flags))) {
 		kfree_skb(skb);
 		return -ENXIO;
 	}
@@ -1695,7 +1696,8 @@ static void hci_rx_task(unsigned long arg)
 			continue;
 		}
 
-		if (test_bit(HCI_INIT, &hdev->flags)) {
+		if (test_bit(HCI_INIT, &hdev->flags) ||
+					test_bit(HCI_CLOSE, &hdev->flags)) {
 			/* Don't process data packets in this states. */
 			switch (bt_cb(skb)->pkt_type) {
 			case HCI_ACLDATA_PKT:
-- 
1.7.2.3


^ permalink raw reply related

* Patches to fix kernel side init/deinit of adapters
From: johan.hedberg @ 2010-12-14 12:04 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

Before I start implementing support for powering on and off adapters
through the management interface some basic things in the current code
need fixing. The first issue is that the __hci_request doesn't work the
way it's supposed to when called from hci_open_dev. It's supposed to
return when the entire request is complete but right now it returns as
soon as the first command in the request is complete.

The first patch in this set is needed to make it possible to take
advantage of the HCI_INIT flag in the second patch.

Johan


^ permalink raw reply

* Re: [PATCH 00/10] More btd_error_* patches
From: Johan Hedberg @ 2010-12-14  8:56 UTC (permalink / raw)
  To: Gustavo F. Padovan; +Cc: linux-bluetooth
In-Reply-To: <1292275987-13799-1-git-send-email-padovan@profusion.mobi>

Hi Gustavo,

On Mon, Dec 13, 2010, Gustavo F. Padovan wrote:
> This patch set adds a new error function btd_error_failed(), which has a str
> parameter to enable a more accurate error report in the case the usual
> btd_error_* does not fit.
> 
> After this patch set there will 10 occurrences of g_dbus_create_error() inside
> bluez code (not counting health/ here)

Thanks. The patches are now upstream. However, I did have to push other
fixes on top of them since a few functions that you assumed were
returning a proper negative errno value were in fact only returning -1.

Johan

^ permalink raw reply

* Re: [RFC] Bluetooth: Use non-flushable pb flag by default for ACL data on capable chipsets.
From: Suraj Sumangala @ 2010-12-14  6:34 UTC (permalink / raw)
  To: Emeltchenko Andrei; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1292251105-31130-2-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On 12/13/2010 8:08 PM, Emeltchenko Andrei wrote:
>   static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
>   {
>   	struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
> +	u8 flags;
>
>   	BT_DBG("code 0x%2.2x", code);
>
>   	if (!skb)
>   		return;
>
> -	hci_send_acl(conn->hcon, skb, 0);
> +	if (lmp_no_flush_capable(conn->hcon->hdev))
> +		flags = ACL_START_NO_FLUSH;
> +	else
> +		flags = ACL_START;
> +
> +	hci_send_acl(conn->hcon, skb, flags);
>   }
>
Should we send L2CAP command packets also as flushable packets? Should 
it be non-flushable?
I thought only L2CAP data frames should be sent as flushable.

Regards
Suraj


^ permalink raw reply

* LE Compound Procedure strategy
From: Brian Gix @ 2010-12-13 21:46 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth


Hi Vinicius,

I am breaking this out into a new conversation.

How about we create a new parameter to g_attrib_send, which is a boolean 
that indicates wether or not the command being sent may be the start (or 
continuation) of a Compound GATT procedure?

If this flag is TRUE, then when gattrib.c creates the command record for 
it, it will see if it is continuing a prior procedure, and if so add it 
to the head of the queue. Perhaps even *replace* the current head, which 
would presumably be recognized as the original command.

This would allow it to reuse the Command ID (allowing the upper layers 
to cancel as needed) and ensure the single-threaded intent of compound 
GATT procedures.

An additional gattrib.c API could then be added which must be called at 
the conclusion of all compound GATT procedures. This new API would 
perform final clean-up on the procedure, including allowing the next 
(following) items in the command queue to be serviced.

Your Thoughts?


-- 
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply

* Re: [PATCH 1/1] Support for reading long Characteristic Values.
From: Brian Gix @ 2010-12-13 21:33 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth, padovan, rshaffer
In-Reply-To: <20101213203336.GC7549@eris>

Hi Vinicius,

On 12/13/2010 12:33 PM, Vinicius Costa Gomes wrote:
> On 11:56 Mon 13 Dec, Brian Gix wrote:
> [trimmed]
 >
 >>>> +
 >>>> +	if (ret_val != 0)
 >>>> +		return;
 >>>> +
 >>>> +	status = ATT_ECODE_INSUFF_RESOURCES;
 >>>> +
 >>>> +done:
 >>>> +	long_read->func(status, res_pdu, res_len, long_read->user_data);
 >>>
 >>> If g_attrib_send() fails, load_read->result_data may be leaking here.
>>
>> Is there no guarantee that the GAttribResultFunc parameter will be
>> invoked if there is a non-Zero return value from g_attrib_send?
>>
>> If there is paths that could result in a non-response (abnormal link
>> termination?) then you are correct, and I will need to rethink clean-up.
>
> The case I was referring was when g_attrib_send() cannot allocate memory for
> the command.
>

I don't think this is an issue, because if g_attrib_send() cannot 
allocate memory, then it will return a 0, and fall through to the 
completion and clean-up. However, I like the idea of doing all clean-up 
in the destructor anyway, which resolves the memory leak potential.


>>>  [...]
>> Also:
>> If we intend to use the ID of the (original) command to cancel the GATT
>> procedure, I propose the following:
>>
>> Compound GATT procedure such as the Read Long procedure that I am
>> implementing, should save the original ID returned by g_attrib_send in
>> the nested user_data structure such as I have done. When subsequent ATT
>> commands are sent as part of the same GATT procedure, the new command
>> shall be assigned the same ID as the original.  This could be done with
>> a function in gattrib.c with the prototype:
>>
>> g_attrib_set_id(GAttrib *attrib, guint old_id, guint new_id);
>>
>> This would allow the upper layer to cancel the entire GATT procedure,
>> even if it is partially completed.
>>
>> This same methodology could then be applied to long writes, and other
>> compound GATT procedures.
>>
>> What do you think?
>
> Sounds good, I just don't know about messing with the commands id's,
> maybe having some thing like command groups.
>
> For example, adding these funtions:
>
> guint g_attrib_send_full(GAttrib *attrib, guint8 opcode, const guint8 *pdu,
> 				guint16 len, guint group, GAttribResultFunc func,
> 				gpointer user_data, GDestroyNotify notify);
>
> gboolean g_attrib_cancel_group(GAttrib *attrib, guint group);
>
> How do this look?
>

My biggest objection would be that to go this route, I think we would 
want to extend this "command group" to all GATT procedures, and not just 
the ones known or suspected to be Compound.  I don't think that 
canceling a "Characteristic Value Read" procedure should be any 
different (or use a different parameter type) than canceling "Find 
Primary Service", for example.

Do you think everything in gatt.c should use these "command groups"? 
And if so, by what mechanism would the "group number" remain unique?

It doesn't seem to me to be such a horrible overloading of the id. I do 
see that when a cancel is called, that it is important that only one 
command with that ID is in the queue. However, this reclaimation/reuse 
of the old ID would only occur after the prior instance is in the 
process of being destroyed. The danger I suppose would be the misuse of 
this renumbering capability by an entity other than gatt.c.


I'm sorry this is getting long winded BUT:

This also highlights the inherent danger of allowing multiple Requests 
to be queued up. If are to allow a Read-Value, Write-Value, Read-Value 
sequence of commands to be enqueued onto the attrib->queue, it will be 
impossible to correctly implement any of the compound Read or Write 
commands, because the subsequent "Read-Blob" would be added to the end 
of the queue, and the read could be split around a write.  GATT/ATT was 
always intended to be a single outstanding request (and procedure) at a 
time kind of protocol, and having a FIFO attrib->queue subverts that intent.

To get compound GATT procedures to work properly (while maintaining the 
Attrib queuing mechanism) we may need to restructure gattrib.c such that 
we can add the subsequent commands to the *head* of the queue, and not 
call wake_up_sender in the received_data() function until after the 
cmd->func() has been invoked, and given the opportunity to "continue the 
current procedure".

>
> Cheers,


-- 
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply

* [PATCH 10/10] src: use btd_error_failed()
From: Gustavo F. Padovan @ 2010-12-13 21:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-10-git-send-email-padovan@profusion.mobi>

---
 src/adapter.c |   37 +++++++++++++------------------------
 src/device.c  |   44 ++++++++++++--------------------------------
 2 files changed, 25 insertions(+), 56 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index e37b200..47ee26a 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -146,12 +146,6 @@ static inline DBusMessage *adapter_not_ready(DBusMessage *msg)
 			"Adapter is not ready");
 }
 
-static inline DBusMessage *failed_strerror(DBusMessage *msg, int err)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", strerror(err));
-}
-
 static inline DBusMessage *not_in_progress(DBusMessage *msg, const char *str)
 {
 	return g_dbus_create_error(msg, ERROR_INTERFACE ".NotInProgress",
@@ -523,7 +517,7 @@ static DBusMessage *set_discoverable(DBusConnection *conn, DBusMessage *msg,
 
 	err = set_mode(adapter, mode, msg);
 	if (err < 0)
-		return failed_strerror(msg, -err);
+		return btd_error_failed(msg, strerror(-err));
 
 	return NULL;
 }
@@ -548,7 +542,7 @@ static DBusMessage *set_powered(DBusConnection *conn, DBusMessage *msg,
 
 	err = set_mode(adapter, mode, msg);
 	if (err < 0)
-		return failed_strerror(msg, -err);
+		return btd_error_failed(msg, strerror(-err));
 
 	return NULL;
 }
@@ -570,7 +564,7 @@ static DBusMessage *set_pairable(DBusConnection *conn, DBusMessage *msg,
 
 	err = set_mode(adapter, MODE_DISCOVERABLE, NULL);
 	if (err < 0 && msg)
-		return failed_strerror(msg, -err);
+		return btd_error_failed(msg, strerror(-err));
 
 store:
 
@@ -775,7 +769,7 @@ static void confirm_mode_cb(struct agent *agent, DBusError *derr, void *data)
 
 	err = set_mode(req->adapter, req->mode, NULL);
 	if (err < 0)
-		reply = failed_strerror(req->msg, -err);
+		reply = btd_error_failed(req->msg, strerror(-err));
 	else
 		reply = dbus_message_new_method_return(req->msg);
 
@@ -906,7 +900,7 @@ static DBusMessage *set_name(DBusConnection *conn, DBusMessage *msg,
 	if (adapter->up) {
 		int err = adapter_ops->set_name(adapter->dev_id, name);
 		if (err < 0)
-			return failed_strerror(msg, err);
+			return btd_error_failed(msg, strerror(-err));
 
 		adapter->name_stored = TRUE;
 	}
@@ -1185,7 +1179,7 @@ static DBusMessage *adapter_start_discovery(DBusConnection *conn,
 
 	err = start_discovery(adapter);
 	if (err < 0)
-		return failed_strerror(msg, -err);
+		return btd_error_failed(msg, strerror(-err));
 
 done:
 	req = create_session(adapter, conn, msg, 0,
@@ -1208,8 +1202,7 @@ static DBusMessage *adapter_stop_discovery(DBusConnection *conn,
 
 	req = find_session(adapter->disc_sessions, sender);
 	if (!req)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-				"Invalid discovery session");
+		return btd_error_failed(msg, "Invalid discovery session");
 
 	session_unref(req);
 	info("Stopping discovery");
@@ -1446,7 +1439,7 @@ static DBusMessage *request_session(DBusConnection *conn,
 					confirm_mode_cb, req, NULL);
 	if (err < 0) {
 		session_unref(req);
-		return failed_strerror(msg, -err);
+		return btd_error_failed(msg, strerror(-err));
 	}
 
 	return NULL;
@@ -1461,8 +1454,7 @@ static DBusMessage *release_session(DBusConnection *conn,
 
 	req = find_session(adapter->mode_sessions, sender);
 	if (!req)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-				"No Mode to release");
+		return btd_error_failed(msg, "Invalid Session");
 
 	session_unref(req);
 
@@ -1622,7 +1614,7 @@ static DBusMessage *create_device(DBusConnection *conn,
 	err = device_browse(device, conn, msg, NULL, FALSE);
 	if (err < 0) {
 		adapter_remove_device(conn, adapter, device, TRUE);
-		return failed_strerror(msg, -err);
+		return btd_error_failed(msg, strerror(-err));
 	}
 
 	return NULL;
@@ -1676,8 +1668,7 @@ static DBusMessage *create_paired_device(DBusConnection *conn,
 
 	device = adapter_get_device(conn, adapter, address);
 	if (!device)
-		return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".Failed",
+		return btd_error_failed(msg,
 				"Unable to create a new device object");
 
 	return device_create_bonding(device, conn, msg, agent_path, cap);
@@ -1788,9 +1779,7 @@ static DBusMessage *register_agent(DBusConnection *conn, DBusMessage *msg,
 	agent = agent_create(adapter, name, path, cap,
 				(agent_remove_cb) agent_removed, adapter);
 	if (!agent)
-		return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".Failed",
-				"Failed to create a new agent");
+		return btd_error_failed(msg, "Failed to create a new agent");
 
 	adapter->agent = agent;
 
@@ -2334,7 +2323,7 @@ static void set_mode_complete(struct btd_adapter *adapter)
 		DBusMessage *reply;
 
 		if (err < 0)
-			reply = failed_strerror(msg, -err);
+			reply = btd_error_failed(msg, strerror(-err));
 		else
 			reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 
diff --git a/src/device.c b/src/device.c
index 0f4dc0b..cec2153 100644
--- a/src/device.c
+++ b/src/device.c
@@ -157,20 +157,6 @@ static uint16_t uuid_list[] = {
 
 static GSList *device_drivers = NULL;
 
-static DBusHandlerResult error_failed(DBusConnection *conn,
-					DBusMessage *msg, const char * desc)
-{
-	return error_common_reply(conn, msg, ERROR_INTERFACE ".Failed", desc);
-}
-
-static DBusHandlerResult error_failed_errno(DBusConnection *conn,
-						DBusMessage *msg, int err)
-{
-	const char *desc = strerror(err);
-
-	return error_failed(conn, msg, desc);
-}
-
 static void browse_request_free(struct browse_req *req)
 {
 	if (req->listener_id)
@@ -380,9 +366,7 @@ static DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg,
 	err = write_device_alias(srcaddr, dstaddr,
 			g_str_equal(alias, "") ? NULL : alias);
 	if (err < 0)
-		return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".Failed",
-				"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	g_free(device->alias);
 	device->alias = g_str_equal(alias, "") ? NULL : g_strdup(alias);
@@ -412,9 +396,7 @@ static DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg,
 
 	err = write_trust(srcaddr, dstaddr, GLOBAL_TRUST, value);
 	if (err < 0)
-		return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".Failed",
-				"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	device->trusted = value;
 
@@ -526,12 +508,9 @@ static DBusMessage *set_blocked(DBusConnection *conn, DBusMessage *msg,
 	case 0:
 		return dbus_message_new_method_return(msg);
 	case EINVAL:
-		return g_dbus_create_error(msg,
-					ERROR_INTERFACE ".NotSupported",
-					"Kernel lacks blacklist support");
+		return btd_error_failed(msg, "Kernel lacks blacklist support");
 	default:
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 	}
 }
 
@@ -627,8 +606,7 @@ static DBusMessage *discover_services(DBusConnection *conn,
 	return NULL;
 
 fail:
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-					"Discovery Failed");
+	return btd_error_failed(msg, strerror(-err));
 }
 
 static const char *browse_request_get_requestor(struct browse_req *req)
@@ -1473,7 +1451,9 @@ send_reply:
 	else if (dbus_message_is_method_call(req->msg, ADAPTER_INTERFACE,
 						"CreateDevice")) {
 		if (err < 0) {
-			error_failed_errno(req->conn, req->msg, -err);
+			DBusMessage *reply;
+			reply = btd_error_failed(req->msg, strerror(-err));
+			g_dbus_send_message(req->conn, reply);
 			goto cleanup;
 		}
 
@@ -1544,7 +1524,9 @@ static void primary_cb(GSList *services, int err, gpointer user_data)
 	struct btd_device *device = req->device;
 
 	if (err) {
-		error_failed_errno(req->conn, req->msg, -err);
+		DBusMessage *reply;
+		reply = btd_error_failed(req->msg, strerror(-err));
+		g_dbus_send_message(req->conn, reply);
 		goto done;
 	}
 
@@ -2000,9 +1982,7 @@ DBusMessage *device_create_bonding(struct btd_device *device,
 				BT_IO_OPT_INVALID);
 	if (io == NULL) {
 		DBusMessage *reply;
-		reply = g_dbus_create_error(msg,
-				ERROR_INTERFACE ".ConnectionAttemptFailed",
-				"%s", err->message);
+		reply = btd_error_failed(msg, err->message);
 		error("bt_io_connect: %s", err->message);
 		g_error_free(err);
 		return reply;
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 09/10] serial: use btd_error_failed()
From: Gustavo F. Padovan @ 2010-12-13 21:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-9-git-send-email-padovan@profusion.mobi>

---
 serial/port.c  |   20 +++++++++-----------
 serial/proxy.c |    8 ++------
 2 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/serial/port.c b/serial/port.c
index 0d1e600..1458f06 100644
--- a/serial/port.c
+++ b/serial/port.c
@@ -248,7 +248,7 @@ static void open_notify(int fd, int err, struct serial_port *port)
 	if (err) {
 		/* Max tries exceeded */
 		port_release(port);
-		reply = failed(port->msg, strerror(err));
+		reply = btd_error_failed(port->msg, strerror(err));
 	} else {
 		port->fd = fd;
 		reply = g_dbus_create_reply(port->msg,
@@ -316,7 +316,7 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *conn_err,
 
 	if (conn_err) {
 		error("%s", conn_err->message);
-		reply = failed(port->msg, conn_err->message);
+		reply = btd_error_failed(port->msg, conn_err->message);
 		goto fail;
 	}
 
@@ -335,7 +335,7 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *conn_err,
 	if (port->id < 0) {
 		int err = errno;
 		error("ioctl(RFCOMMCREATEDEV): %s (%d)", strerror(err), err);
-		reply = failed(port->msg, strerror(err));
+		reply = btd_error_failed(port->msg, strerror(err));
 		g_io_channel_shutdown(chan, TRUE, NULL);
 		goto fail;
 	}
@@ -378,13 +378,13 @@ static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
 	if (err < 0) {
 		error("Unable to get service record: %s (%d)", strerror(-err),
 			-err);
-		reply = failed(port->msg, strerror(-err));
+		reply = btd_error_failed(port->msg, strerror(-err));
 		goto failed;
 	}
 
 	if (!recs || !recs->data) {
 		error("No record found");
-		reply = failed(port->msg, "No record found");
+		reply = btd_error_failed(port->msg, "No record found");
 		goto failed;
 	}
 
@@ -392,7 +392,7 @@ static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
 
 	if (sdp_get_access_protos(record, &protos) < 0) {
 		error("Unable to get access protos from port record");
-		reply = failed(port->msg, "Invalid channel");
+		reply = btd_error_failed(port->msg, "Invalid channel");
 		goto failed;
 	}
 
@@ -409,7 +409,7 @@ static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
 				BT_IO_OPT_INVALID);
 	if (!port->io) {
 		error("%s", gerr->message);
-		reply = failed(port->msg, gerr->message);
+		reply = btd_error_failed(port->msg, gerr->message);
 		g_error_free(gerr);
 		goto failed;
 	}
@@ -505,13 +505,11 @@ static DBusMessage *port_connect(DBusConnection *conn,
 
 	err = connect_port(port);
 	if (err < 0) {
-		DBusMessage *reply;
-
 		error("%s", strerror(-err));
 		g_dbus_remove_watch(conn, port->listener_id);
 		port->listener_id = 0;
-		reply = failed(msg, strerror(-err));
-		return reply;
+
+		return btd_error_failed(msg, strerror(-err));
 	}
 
 	return NULL;
diff --git a/serial/proxy.c b/serial/proxy.c
index c779c4e..20aea7d 100644
--- a/serial/proxy.c
+++ b/serial/proxy.c
@@ -553,11 +553,8 @@ static DBusMessage *proxy_enable(DBusConnection *conn,
 	err = enable_proxy(prx);
 	if (err == -EALREADY)
 		return failed(msg, "Already enabled");
-	else if (err == -ENOMEM)
-		return failed(msg, "Unable to allocate new service record");
 	else if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE "Failed",
-				"Proxy enable failed (%s)", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	return dbus_message_new_method_return(msg);
 }
@@ -1051,8 +1048,7 @@ static DBusMessage *create_proxy(DBusConnection *conn,
 	else if (err == -EALREADY)
 		return btd_error_already_exists(msg);
 	else if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE "Failed",
-				"Proxy creation failed (%s)", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	proxy->owner = g_strdup(dbus_message_get_sender(msg));
 	proxy->watch = g_dbus_add_disconnect_watch(conn, proxy->owner,
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 08/10] audio: use btd_error_failed()
From: Gustavo F. Padovan @ 2010-12-13 21:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-8-git-send-email-padovan@profusion.mobi>

---
 audio/control.c   |    6 ++----
 audio/device.c    |   14 +++++---------
 audio/gateway.c   |   11 +++++------
 audio/headset.c   |   18 +++++-------------
 audio/sink.c      |    9 +++------
 audio/source.c    |    9 +++------
 audio/transport.c |    7 +------
 7 files changed, 24 insertions(+), 50 deletions(-)

diff --git a/audio/control.c b/audio/control.c
index 98b6682..75c0b51 100644
--- a/audio/control.c
+++ b/audio/control.c
@@ -1021,8 +1021,7 @@ static DBusMessage *volume_up(DBusConnection *conn, DBusMessage *msg,
 
 	err = avctp_send_passthrough(control, VOL_UP_OP);
 	if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	return dbus_message_new_method_return(msg);
 }
@@ -1047,8 +1046,7 @@ static DBusMessage *volume_down(DBusConnection *conn, DBusMessage *msg,
 
 	err = avctp_send_passthrough(control, VOL_DOWN_OP);
 	if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	return dbus_message_new_method_return(msg);
 }
diff --git a/audio/device.c b/audio/device.c
index fe7aed4..e38e598 100644
--- a/audio/device.c
+++ b/audio/device.c
@@ -271,10 +271,9 @@ static void device_set_state(struct audio_device *dev, audio_state_t new_state)
 		if (new_state == AUDIO_STATE_CONNECTED)
 			reply = dbus_message_new_method_return(priv->conn_req);
 		else
-			reply = g_dbus_create_error(priv->conn_req,
-							ERROR_INTERFACE
-							".ConnectFailed",
-							"Connecting failed");
+			reply = btd_error_failed(priv->conn_req,
+							"Connect Failed");
+
 		dbus_message_unref(priv->conn_req);
 		priv->conn_req = NULL;
 		g_dbus_send_message(dev->conn, reply);
@@ -532,8 +531,7 @@ static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg,
 		struct avdtp *session = avdtp_get(&dev->src, &dev->dst);
 
 		if (!session)
-			return g_dbus_create_error(msg, ERROR_INTERFACE
-					".Failed",
+			return btd_error_failed(msg,
 					"Failed to get AVDTP session");
 
 		sink_setup_stream(dev->sink, session);
@@ -543,9 +541,7 @@ static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg,
 	/* The previous calls should cause a call to the state callback to
 	 * indicate AUDIO_STATE_CONNECTING */
 	if (priv->state != AUDIO_STATE_CONNECTING)
-		return g_dbus_create_error(msg, ERROR_INTERFACE
-				".ConnectFailed",
-				"Headset connect failed");
+		return btd_error_failed(msg, "Connect Failed");
 
 	priv->conn_req = dbus_message_ref(msg);
 
diff --git a/audio/gateway.c b/audio/gateway.c
index 05b9ff7..4d38be7 100644
--- a/audio/gateway.c
+++ b/audio/gateway.c
@@ -247,8 +247,7 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *err,
 	if (ret)
 		reply = dbus_message_new_method_return(gw->msg);
 	else
-		reply = g_dbus_create_error(gw->msg, ERROR_INTERFACE ".Failed",
-					"Can not pass file descriptor");
+		reply = btd_error_failed(gw->msg, "Can't pass file descriptor");
 
 	g_dbus_send_message(dev->conn, reply);
 
@@ -365,15 +364,15 @@ static DBusMessage *ag_connect(DBusConnection *conn, DBusMessage *msg,
 {
 	struct audio_device *au_dev = (struct audio_device *) data;
 	struct gateway *gw = au_dev->gateway;
+	int err;
 
 	if (!gw->agent)
 		return g_dbus_create_error(msg, ERROR_INTERFACE
 				".Failed", "Agent not assigned");
 
-	if (get_records(au_dev) < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE
-					".ConnectAttemptFailed",
-					"Connect Attempt Failed");
+	err = get_records(au_dev);
+	if (err < 0)
+		return btd_error_failed(msg, strerror(-err));
 
 	gw->msg = dbus_message_ref(msg);
 
diff --git a/audio/headset.c b/audio/headset.c
index 18fd866..34b2b89 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -1709,13 +1709,8 @@ static DBusMessage *hs_connect(DBusConnection *conn, DBusMessage *msg,
 	device->auto_connect = FALSE;
 
 	err = rfcomm_connect(device, NULL, NULL, NULL);
-	if (err == -ECONNREFUSED)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAllowed",
-						"Too many connected devices");
-	else if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE
-						".ConnectAttemptFailed",
-						"Connect Attempt Failed");
+	if (err < 0)
+		return btd_error_failed(msg, strerror(-err));
 
 	hs->auto_dc = FALSE;
 
@@ -1747,8 +1742,7 @@ static DBusMessage *hs_ring(DBusConnection *conn, DBusMessage *msg,
 	err = headset_send(hs, "\r\nRING\r\n");
 	if (err < 0) {
 		dbus_message_unref(reply);
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 	}
 
 	ring_timer_cb(NULL);
@@ -1815,8 +1809,7 @@ static DBusMessage *hs_play(DBusConnection *conn, DBusMessage *msg,
 
 	err = sco_connect(device, NULL, NULL, NULL);
 	if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	hs->pending->msg = dbus_message_ref(msg);
 
@@ -1900,8 +1893,7 @@ static DBusMessage *hs_set_gain(DBusConnection *conn,
 		err = headset_send(hs, "\r\n+VG%c=%u\r\n", type, gain);
 		if (err < 0) {
 			dbus_message_unref(reply);
-			return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"%s", strerror(-err));
+			return btd_error_failed(msg, strerror(-err));
 		}
 	}
 
diff --git a/audio/sink.c b/audio/sink.c
index 176a4ed..5746c55 100644
--- a/audio/sink.c
+++ b/audio/sink.c
@@ -435,8 +435,7 @@ static DBusMessage *sink_connect(DBusConnection *conn,
 		sink->session = avdtp_get(&dev->src, &dev->dst);
 
 	if (!sink->session)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"Unable to get a session");
+		return btd_error_failed(msg, "Unable to get a session");
 
 	if (sink->connect || sink->disconnect)
 		return btd_error_busy(msg);
@@ -445,8 +444,7 @@ static DBusMessage *sink_connect(DBusConnection *conn,
 		return btd_error_already_connected(msg);
 
 	if (!sink_setup_stream(sink, NULL))
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"Failed to create a stream");
+		return btd_error_failed(msg, "Failed to create a stream");
 
 	dev->auto_connect = FALSE;
 
@@ -485,8 +483,7 @@ static DBusMessage *sink_disconnect(DBusConnection *conn,
 
 	err = avdtp_close(sink->session, sink->stream, FALSE);
 	if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	pending = g_new0(struct pending_request, 1);
 	pending->conn = dbus_connection_ref(conn);
diff --git a/audio/source.c b/audio/source.c
index c106eaa..29ceb0f 100644
--- a/audio/source.c
+++ b/audio/source.c
@@ -386,8 +386,7 @@ static DBusMessage *source_connect(DBusConnection *conn,
 		source->session = avdtp_get(&dev->src, &dev->dst);
 
 	if (!source->session)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"Unable to get a session");
+		return btd_error_failed(msg, "Unable to get a session");
 
 	if (source->connect || source->disconnect)
 		return btd_error_busy(msg);
@@ -396,8 +395,7 @@ static DBusMessage *source_connect(DBusConnection *conn,
 		return btd_error_already_connected(msg);
 
 	if (!source_setup_stream(source, NULL))
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"Failed to create a stream");
+		return btd_error_failed(msg, "Failed to create a stream");
 
 	dev->auto_connect = FALSE;
 
@@ -436,8 +434,7 @@ static DBusMessage *source_disconnect(DBusConnection *conn,
 
 	err = avdtp_close(source->session, source->stream, FALSE);
 	if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	pending = g_new0(struct pending_request, 1);
 	pending->conn = dbus_connection_ref(conn);
diff --git a/audio/transport.c b/audio/transport.c
index e2ee400..bdec157 100644
--- a/audio/transport.c
+++ b/audio/transport.c
@@ -93,11 +93,6 @@ struct media_transport {
 					DBusMessageIter *value);
 };
 
-static inline DBusMessage *error_failed(DBusMessage *msg, const char *desc)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "%s", desc);
-}
-
 void media_transport_remove(struct media_transport *transport)
 {
 	char *path;
@@ -572,7 +567,7 @@ static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
 	if (err < 0) {
 		if (err == -EINVAL)
 			return btd_error_invalid_args(msg);
-		return error_failed(msg, strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 	}
 
 	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 07/10] input: use btd_error_failed()
From: Gustavo F. Padovan @ 2010-12-13 21:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-7-git-send-email-padovan@profusion.mobi>

---
 input/device.c |   31 ++++++++-----------------------
 1 files changed, 8 insertions(+), 23 deletions(-)

diff --git a/input/device.c b/input/device.c
index dee943b..0543fe6 100644
--- a/input/device.c
+++ b/input/device.c
@@ -315,14 +315,6 @@ failed:
 	return FALSE;
 }
 
-static inline DBusMessage *connection_attempt_failed(DBusMessage *msg,
-							const char *err)
-{
-	return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".ConnectionAttemptFailed",
-				"%s", err ? err : "Connection attempt failed");
-}
-
 static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 {
 	struct input_conn *iconn = user_data;
@@ -331,8 +323,7 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	DBusMessage *reply;
 
 	if (err) {
-		reply = connection_attempt_failed(iconn->pending_connect,
-								err->message);
+		reply = btd_error_failed(iconn->pending_connect, err->message);
 		goto failed;
 	}
 
@@ -345,7 +336,7 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	fake->uinput = uinput_create(idev->name);
 	if (fake->uinput < 0) {
 		g_io_channel_shutdown(chan, TRUE, NULL);
-		reply = connection_attempt_failed(iconn->pending_connect,
+		reply = btd_error_failed(iconn->pending_connect,
 							strerror(errno));
 		goto failed;
 	}
@@ -834,7 +825,7 @@ static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
 
 failed:
 	error("%s", err_msg);
-	reply = connection_attempt_failed(iconn->pending_connect, err_msg);
+	reply = btd_error_failed(iconn->pending_connect, err_msg);
 	g_dbus_send_message(idev->conn, reply);
 
 	if (iconn->ctrl_io)
@@ -859,8 +850,8 @@ static void control_connect_cb(GIOChannel *chan, GError *conn_err,
 
 	if (conn_err) {
 		error("%s", conn_err->message);
-		reply = connection_attempt_failed(iconn->pending_connect,
-							conn_err->message);
+		reply = btd_error_failed(iconn->pending_connect,
+						conn_err->message);
 		goto failed;
 	}
 
@@ -874,7 +865,7 @@ static void control_connect_cb(GIOChannel *chan, GError *conn_err,
 				BT_IO_OPT_INVALID);
 	if (!io) {
 		error("%s", err->message);
-		reply = connection_attempt_failed(iconn->pending_connect,
+		reply = btd_error_failed(iconn->pending_connect,
 							err->message);
 		g_error_free(err);
 		g_io_channel_shutdown(chan, TRUE, NULL);
@@ -960,17 +951,11 @@ static DBusMessage *input_device_connect(DBusConnection *conn,
 	error("%s", err->message);
 	dbus_message_unref(iconn->pending_connect);
 	iconn->pending_connect = NULL;
-	reply = connection_attempt_failed(msg, err->message);
+	reply = btd_error_failed(msg, err->message);
 	g_error_free(err);
 	return reply;
 }
 
-static DBusMessage *create_errno_message(DBusMessage *msg, int err)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", strerror(err));
-}
-
 static DBusMessage *input_device_disconnect(DBusConnection *conn,
 						DBusMessage *msg, void *data)
 {
@@ -979,7 +964,7 @@ static DBusMessage *input_device_disconnect(DBusConnection *conn,
 
 	err = disconnect(idev, 0);
 	if (err < 0)
-		return create_errno_message(msg, -err);
+		return btd_error_failed(msg, strerror(-err));
 
 	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 }
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 06/10] network: use btd_error_failed()
From: Gustavo F. Padovan @ 2010-12-13 21:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-6-git-send-email-padovan@profusion.mobi>

---
 network/connection.c |   30 ++----------------------------
 network/server.c     |   13 +++----------
 2 files changed, 5 insertions(+), 38 deletions(-)

diff --git a/network/connection.c b/network/connection.c
index 89c38d8..09a4f3c 100644
--- a/network/connection.c
+++ b/network/connection.c
@@ -111,32 +111,6 @@ static struct network_conn *find_connection(GSList *list, uint16_t id)
 	return NULL;
 }
 
-static inline DBusMessage *not_supported(DBusMessage *msg)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"Not supported");
-}
-
-static inline DBusMessage *already_connected(DBusMessage *msg)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"Device already connected");
-}
-
-static inline DBusMessage *not_permited(DBusMessage *msg)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"Operation not permited");
-}
-
-static inline DBusMessage *connection_attempt_failed(DBusMessage *msg,
-							const char *err)
-{
-	return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".ConnectionAttemptFailed",
-				"%s", err ? err : "Connection attempt failed");
-}
-
 static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
 				gpointer data)
 {
@@ -182,7 +156,7 @@ static void cancel_connection(struct network_conn *nc, const char *err_msg)
 	}
 
 	if (nc->msg && err_msg) {
-		reply = connection_attempt_failed(nc->msg, err_msg);
+		reply = btd_error_failed(nc->msg, err_msg);
 		g_dbus_send_message(connection, reply);
 	}
 
@@ -409,7 +383,7 @@ static DBusMessage *connection_connect(DBusConnection *conn,
 	if (!nc->io) {
 		DBusMessage *reply;
 		error("%s", err->message);
-		reply = connection_attempt_failed(msg, err->message);
+		reply = btd_error_failed(msg, err->message);
 		g_error_free(err);
 		return reply;
 	}
diff --git a/network/server.c b/network/server.c
index 60e1a81..7c63c3e 100644
--- a/network/server.c
+++ b/network/server.c
@@ -566,13 +566,6 @@ static uint32_t register_server_record(struct network_server *ns)
 	return record->handle;
 }
 
-
-static inline DBusMessage *failed(DBusMessage *msg, const char *description)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", description);
-}
-
 static void server_disconnect(DBusConnection *conn, void *user_data)
 {
 	struct network_server *ns = user_data;
@@ -600,7 +593,7 @@ static DBusMessage *register_server(DBusConnection *conn,
 		return NULL;
 
 	if (g_strcmp0(uuid, "nap"))
-		return failed(msg, "Invalid UUID");
+		return btd_error_failed(msg, "Invalid UUID");
 
 	if (ns->record_id)
 		return btd_error_already_exists(msg);
@@ -611,7 +604,7 @@ static DBusMessage *register_server(DBusConnection *conn,
 
 	ns->record_id = register_server_record(ns);
 	if (!ns->record_id)
-		return failed(msg, "SDP record registration failed");
+		return btd_error_failed(msg, "SDP record registration failed");
 
 	g_free(ns->bridge);
 	ns->bridge = g_strdup(bridge);
@@ -635,7 +628,7 @@ static DBusMessage *unregister_server(DBusConnection *conn,
 		return NULL;
 
 	if (g_strcmp0(uuid, "nap"))
-		return failed(msg, "Invalid UUID");
+		return btd_error_failed(msg, "Invalid UUID");
 
 	reply = dbus_message_new_method_return(msg);
 	if (!reply)
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 05/10] attrib: use btd_error_failed()
From: Gustavo F. Padovan @ 2010-12-13 21:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-5-git-send-email-padovan@profusion.mobi>

---
 attrib/client.c |   10 ++--------
 1 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/attrib/client.c b/attrib/client.c
index 0805492..8e96af4 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -457,11 +457,8 @@ static DBusMessage *register_watcher(DBusConnection *conn,
 		return btd_error_invalid_args(msg);
 
 	if (l2cap_connect(prim->gatt, &gerr, TRUE) < 0) {
-		DBusMessage *reply;
-		reply = g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", gerr->message);
+		DBusMessage *reply = btd_error_failed(msg, gerr->message);
 		g_error_free(gerr);
-
 		return reply;
 	}
 
@@ -533,11 +530,8 @@ static DBusMessage *set_value(DBusConnection *conn, DBusMessage *msg,
 	dbus_message_iter_get_fixed_array(&sub, &value, &len);
 
 	if (l2cap_connect(gatt, &gerr, FALSE) < 0) {
-		DBusMessage *reply;
-		reply = g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", gerr->message);
+		DBusMessage *reply = btd_error_failed(msg, gerr->message);
 		g_error_free(gerr);
-
 		return reply;
 	}
 
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 04/10] plugins: use btd_error_failed()
From: Gustavo F. Padovan @ 2010-12-13 21:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-4-git-send-email-padovan@profusion.mobi>

---
 plugins/service.c |   22 ++++------------------
 1 files changed, 4 insertions(+), 18 deletions(-)

diff --git a/plugins/service.c b/plugins/service.c
index a442d53..f44aa92 100644
--- a/plugins/service.c
+++ b/plugins/service.c
@@ -337,17 +337,6 @@ static void exit_callback(DBusConnection *conn, void *user_data)
 	g_free(user_record);
 }
 
-static inline DBusMessage *failed(DBusMessage *msg)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "Failed");
-}
-
-static inline DBusMessage *failed_strerror(DBusMessage *msg, int err)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", strerror(err));
-}
-
 static int add_xml_record(DBusConnection *conn, const char *sender,
 			struct service_adapter *serv_adapter,
 			const char *record, dbus_uint32_t *handle)
@@ -412,9 +401,7 @@ static DBusMessage *update_record(DBusConnection *conn, DBusMessage *msg,
 	if (err < 0) {
 		sdp_record_free(sdp_record);
 		error("Failed to update the service record");
-		return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".Failed",
-				"%s", strerror(EIO));
+		return btd_error_failed(msg, strerror(-err));
 	}
 
 	return dbus_message_new_method_return(msg);
@@ -449,9 +436,8 @@ static DBusMessage *update_xml_record(DBusConnection *conn,
 	if (!sdp_record) {
 		error("Parsing of XML service record failed");
 		sdp_record_free(sdp_record);
-		return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".Failed",
-				"%s", strerror(EIO));
+		return btd_error_failed(msg,
+					"Parsing of XML service record failed");
 	}
 
 	return update_record(conn, msg, serv_adapter, handle, sdp_record);
@@ -494,7 +480,7 @@ static DBusMessage *add_service_record(DBusConnection *conn,
 	sender = dbus_message_get_sender(msg);
 	err = add_xml_record(conn, sender, serv_adapter, record, &handle);
 	if (err < 0)
-		return failed_strerror(msg, err);
+		return btd_error_failed(msg, strerror(-err));
 
 	reply = dbus_message_new_method_return(msg);
 	if (!reply)
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 03/10] Add btd_error_failed()
From: Gustavo F. Padovan @ 2010-12-13 21:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-3-git-send-email-padovan@profusion.mobi>

This is a special error type. It has a more general meaning and allows you
to add a string to the error.
---
 src/error.c |    6 ++++++
 src/error.h |    1 +
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/src/error.c b/src/error.c
index 013de96..3a78628 100644
--- a/src/error.c
+++ b/src/error.c
@@ -114,3 +114,9 @@ DBusMessage *btd_error_no_such_adapter(DBusMessage *msg)
 	return g_dbus_create_error(msg, ERROR_INTERFACE ".NoSuchAdapter",
 					"No such adapter");
 }
+
+DBusMessage *btd_error_failed(DBusMessage *msg, const char *str)
+{
+	return g_dbus_create_error(msg, ERROR_INTERFACE
+					".Failed", "%s", str);
+}
diff --git a/src/error.h b/src/error.h
index a4e32fe..faaef0a 100644
--- a/src/error.h
+++ b/src/error.h
@@ -41,3 +41,4 @@ DBusMessage *btd_error_in_progress(DBusMessage *msg);
 DBusMessage *btd_error_does_not_exist(DBusMessage *msg);
 DBusMessage *btd_error_not_authorized(DBusMessage *msg);
 DBusMessage *btd_error_no_such_adapter(DBusMessage *msg);
+DBusMessage *btd_error_failed(DBusMessage *msg, const char *str);
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 02/10] src: use btd_error_invalid_args()
From: Gustavo F. Padovan @ 2010-12-13 21:32 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-2-git-send-email-padovan@profusion.mobi>

---
 src/device.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/device.c b/src/device.c
index 7ceac8b..0f4dc0b 100644
--- a/src/device.c
+++ b/src/device.c
@@ -605,7 +605,7 @@ static DBusMessage *discover_services(DBusConnection *conn,
 
 	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
 						DBUS_TYPE_INVALID) == FALSE)
-		goto fail;
+		return btd_error_invalid_args(msg);
 
 	if (strlen(pattern) == 0) {
 		err = device_browse(device, conn, msg, NULL, FALSE);
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 01/10] Add btd_error_no_such_adapter()
From: Gustavo F. Padovan @ 2010-12-13 21:32 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-1-git-send-email-padovan@profusion.mobi>

---
 src/device.c  |    6 ------
 src/error.c   |    6 ++++++
 src/error.h   |    1 +
 src/manager.c |   13 +++----------
 4 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/src/device.c b/src/device.c
index 91b9d23..7ceac8b 100644
--- a/src/device.c
+++ b/src/device.c
@@ -171,12 +171,6 @@ static DBusHandlerResult error_failed_errno(DBusConnection *conn,
 	return error_failed(conn, msg, desc);
 }
 
-static inline DBusMessage *no_such_adapter(DBusMessage *msg)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".NoSuchAdapter",
-							"No such adapter");
-}
-
 static void browse_request_free(struct browse_req *req)
 {
 	if (req->listener_id)
diff --git a/src/error.c b/src/error.c
index e1f0598..013de96 100644
--- a/src/error.c
+++ b/src/error.c
@@ -108,3 +108,9 @@ DBusMessage *btd_error_not_authorized(DBusMessage *msg)
 	return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAuthorized",
 					"Operation Not Authorized");
 }
+
+DBusMessage *btd_error_no_such_adapter(DBusMessage *msg)
+{
+	return g_dbus_create_error(msg, ERROR_INTERFACE ".NoSuchAdapter",
+					"No such adapter");
+}
diff --git a/src/error.h b/src/error.h
index 9d80fa0..a4e32fe 100644
--- a/src/error.h
+++ b/src/error.h
@@ -40,3 +40,4 @@ DBusMessage *btd_error_not_available(DBusMessage *msg);
 DBusMessage *btd_error_in_progress(DBusMessage *msg);
 DBusMessage *btd_error_does_not_exist(DBusMessage *msg);
 DBusMessage *btd_error_not_authorized(DBusMessage *msg);
+DBusMessage *btd_error_no_such_adapter(DBusMessage *msg);
diff --git a/src/manager.c b/src/manager.c
index ccaa1a2..c8ec7e5 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -59,13 +59,6 @@ const char *manager_get_base_path(void)
 	return base_path;
 }
 
-static inline DBusMessage *no_such_adapter(DBusMessage *msg)
-{
-	return g_dbus_create_error(msg,
-			ERROR_INTERFACE ".NoSuchAdapter",
-			"No such adapter");
-}
-
 static DBusMessage *default_adapter(DBusConnection *conn,
 					DBusMessage *msg, void *data)
 {
@@ -75,7 +68,7 @@ static DBusMessage *default_adapter(DBusConnection *conn,
 
 	adapter = manager_find_adapter_by_id(default_adapter_id);
 	if (!adapter)
-		return no_such_adapter(msg);
+		return btd_error_no_such_adapter(msg);
 
 	reply = dbus_message_new_method_return(msg);
 	if (!reply)
@@ -108,7 +101,7 @@ static DBusMessage *find_adapter(DBusConnection *conn,
 		path = adapter_any_get_path();
 		if (path != NULL)
 			goto done;
-		return no_such_adapter(msg);
+		return btd_error_no_such_adapter(msg);
 	} else if (!strncmp(pattern, "hci", 3) && strlen(pattern) >= 4) {
 		dev_id = atoi(pattern + 3);
 		adapter = manager_find_adapter_by_id(dev_id);
@@ -116,7 +109,7 @@ static DBusMessage *find_adapter(DBusConnection *conn,
 		adapter = manager_find_adapter_by_address(pattern);
 
 	if (!adapter)
-		return no_such_adapter(msg);
+		return btd_error_no_such_adapter(msg);
 
 	path = adapter_get_path(adapter);
 
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 00/10] More btd_error_* patches
From: Gustavo F. Padovan @ 2010-12-13 21:32 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

This patch set adds a new error function btd_error_failed(), which has a str
parameter to enable a more accurate error report in the case the usual
btd_error_* does not fit.

After this patch set there will 10 occurrences of g_dbus_create_error() inside
bluez code (not counting health/ here)

Please review!

Gustavo F. Padovan (10):
  Add btd_error_no_such_adapter()
  src: use btd_error_invalid_args()
  Add btd_error_failed()
  plugins: use btd_error_failed()
  attrib: use btd_error_failed()
  network: use btd_error_failed()
  input: use btd_error_failed()
  audio: use btd_error_failed()
  serial: use btd_error_failed()
  src: use btd_error_failed()

 attrib/client.c      |   10 +-------
 audio/control.c      |    6 +---
 audio/device.c       |   14 ++++--------
 audio/gateway.c      |   11 ++++-----
 audio/headset.c      |   18 ++++------------
 audio/sink.c         |    9 ++-----
 audio/source.c       |    9 ++-----
 audio/transport.c    |    7 +-----
 input/device.c       |   31 +++++++----------------------
 network/connection.c |   30 +--------------------------
 network/server.c     |   13 ++---------
 plugins/service.c    |   22 +++-----------------
 serial/port.c        |   20 ++++++++----------
 serial/proxy.c       |    8 +-----
 src/adapter.c        |   37 ++++++++++++-----------------------
 src/device.c         |   52 ++++++++++++-------------------------------------
 src/error.c          |   12 +++++++++++
 src/error.h          |    2 +
 src/manager.c        |   13 ++---------
 19 files changed, 97 insertions(+), 227 deletions(-)

-- 
1.7.3.2


^ permalink raw reply

* Re: [PATCH 1/1] Support for reading long Characteristic Values.
From: Vinicius Costa Gomes @ 2010-12-13 20:33 UTC (permalink / raw)
  To: Brian Gix; +Cc: linux-bluetooth, padovan, rshaffer
In-Reply-To: <4D067A6C.6080404@codeaurora.org>

On 11:56 Mon 13 Dec, Brian Gix wrote:
> Hi Vinicius,
> 
> On 12/13/2010 10:39 AM, Vinicius Costa Gomes wrote:
> > On 09:24 Mon 13 Dec, Brian Gix wrote:
> >> Modify existing gatt_read_char() function support the reading of
> >> attributes (specifically Characteristic Values) that are longer than
> >> the MTU would otherwise allow.  When a result to an ATT_OP_READ_REQ
> >> is received, it will be passed to the requester as always if the total
> >> result was shorter than the Default MTU (23). Any results equal to or
> >> longer will cause a series of READ_BLOB requests to be made, with the
> >> additional results built up until the end of the Attribute is detected.
> >> The full result will then be passed to the original requester.
> >>
> >> The end of the Attribute is detected by either a successful result to
> >> the READ_BLOB request that is shorter than the Default MTU, or by an
> >> error result that indicates that a read is being attempted beyond the
> >> length of the attribute, or that the Attribute wasn't "Long".
> >>
> >> This patch is dependant on the earlier patch:
> >> 0001-Implempent-READ_BLOB-encoding-for-ATT.patch
> >>
> >> The packet composed conforms to the Bluetooth Core v4.0 specification.
> >>
> >> Brian Gix
> >> bgix@codeaurora.org
> >> Employee of Qualcomm Innovation Center, Inc.
> >> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
> 
> I will omit the sig in the annotation in the future.
> 
> Also, I will examine the subsequent submissions for non-TAB ws.  I need 
> to work on my gvim settings a bit, I think.
> 
> >>
> >> ---
> >>   attrib/gatt.c |  114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> >>   1 files changed, 112 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/attrib/gatt.c b/attrib/gatt.c
> >> index bca8b49..d888f1d 100644
> >> --- a/attrib/gatt.c
> >> +++ b/attrib/gatt.c
> >> @@ -97,15 +97,125 @@ guint gatt_read_char_by_uuid(GAttrib *attrib, uint16_t start, uint16_t end,
> >>   					pdu, plen, func, user_data, NULL);
> >>   }
> >>
> >> +struct read_long_data {
> >> +	GAttrib *attrib;
> >> +	GAttribResultFunc func;
> >> +	gpointer user_data;
> >> +	guint8 *result_data;
> >> +	guint16 result_len;
> >
> > I would call result_data "buffer" (or something like it) and result_len "size"
> > (or total). What do you think?
> 
> Will rename to buffer and size. I often avoid "size" to avoid keyword 
> collisions, but I don't believe it applies here.
> 
> >
> >> +	guint16 handle;
> >> +};
> >> +
> >> +static void read_blob_helper(guint8 status, const guint8 *res_pdu,
> >> +					guint16 res_len, gpointer user_data)
> >> +{
> >> +	struct read_long_data *long_read = user_data;
> >> +	uint8_t pdu[ATT_DEFAULT_MTU];
> >> +	guint8 *tmp;
> >> +	guint16 plen;
> >> +	guint ret_val;
> >> +
> >> +	if (status == ATT_ECODE_ATTR_NOT_LONG ||
> >> +	    status == ATT_ECODE_INVALID_OFFSET) {
> >> +		status = 0;
> >> +		goto done;
> >> +	}
> >> +
> >> +	if (status != 0 || res_len == 1)
> >> +		goto done;
> >> +
> >> +	tmp = g_try_realloc(long_read->result_data,
> >> +			    	long_read->result_len + res_len - 1);
> >> +
> >> +	if (tmp == NULL) {
> >> +		status = ATT_ECODE_INSUFF_RESOURCES;
> >> +		goto done;
> >> +	}
> >> +
> >> +	memcpy(&tmp[long_read->result_len],&res_pdu[1], res_len-1);
> >
> > It should be "res - 1".
> >
> >> +	long_read->result_data = tmp;
> >> +	long_read->result_len += res_len-1;
> >
> > Same here.
> >
> >> +
> >> +	if (res_len<  ATT_DEFAULT_MTU)
> >> +		goto done;
> >> +
> >> +	plen = enc_read_blob_req(long_read->handle, long_read->result_len-1,
> >
> > And here.
> 
> done, done, done.
> 
> >
> >> +			 				pdu, sizeof(pdu));
> >> +	ret_val = g_attrib_send(long_read->attrib, ATT_OP_READ_BLOB_REQ, pdu,
> >> +				plen, read_blob_helper, long_read, NULL);
> >> +
> >> +	if (ret_val != 0)
> >> +		return;
> >> +
> >> +	status = ATT_ECODE_INSUFF_RESOURCES;
> >> +
> >> +done:
> >> +	long_read->func(status, long_read->result_data, long_read->result_len,
> >> +							long_read->user_data);
> >> +	g_free(long_read->result_data);
> >> +	g_free(long_read);
> >> +}
> >> +
> >> +static void read_char_helper(guint8 status, const guint8 *res_pdu,
> >> +					guint16 res_len, gpointer user_data)
> >> +{
> >> +	struct read_long_data *long_read = user_data;
> >> +	uint8_t pdu[ATT_DEFAULT_MTU];
> >> +	guint16 plen;
> >> +	guint ret_val;
> >> +
> >> +	if (status != 0 || res_len<  ATT_DEFAULT_MTU)
> >> +		goto done;
> >> +
> >> +	long_read->result_data = g_malloc(res_len);
> >> +
> >> +	if (long_read->result_data == NULL)
> >> +		goto done;
> >> +
> >> +	memcpy(long_read->result_data, res_pdu, res_len);
> >> +	long_read->result_len = res_len;
> >> +
> >> +	plen = enc_read_blob_req(long_read->handle, res_len-1, pdu,
> >> +				 				sizeof(pdu));
> >> +	ret_val = g_attrib_send(long_read->attrib, ATT_OP_READ_BLOB_REQ,
> >> +			pdu, plen, read_blob_helper, long_read, NULL);
> >
> > g_attrib_send() returns an command id (something that could be used to cancel
> > the command later, if needed), so I think it would make more sense to call
> > ret_val "id" or just "ret". And thinking about it, I guess that the "res_"
> > prefix doesn't add much meaning to "res_pdu" and "res_len". Do you agree?
> 
> renamed res_pdu to "rpdu", to avoid name collision with outbound local 
> pdu variable.
> 
> renamed res_len to "rlen" to keep the two together, and distinct from 
> plen, which is also used for the outbound pdu.
> 
> renamed ret_val to "ret".  In two of the functions, it has lost the 
> ability to be used to cancel the GATT procedure. It can cancel the 
> original ATT_OP_READ_REQ opcodes, but not the subsequent 
> ATT_OP_READ_BLOB_REQ opcodes.
> 
> >
> >> +
> >> +	if (ret_val != 0)
> >> +		return;
> >> +
> >> +	status = ATT_ECODE_INSUFF_RESOURCES;
> >> +
> >> +done:
> >> +	long_read->func(status, res_pdu, res_len, long_read->user_data);
> >
> > If g_attrib_send() fails, load_read->result_data may be leaking here.
> 
> Is there no guarantee that the GAttribResultFunc parameter will be 
> invoked if there is a non-Zero return value from g_attrib_send?
> 
> If there is paths that could result in a non-response (abnormal link 
> termination?) then you are correct, and I will need to rethink clean-up.

The case I was referring was when g_attrib_send() cannot allocate memory for
the command. 

> 
> If I am correctly reading the code, I can pass a function to the 
> GDestroyNotify parameter of g_attrib_send, which will alert me to the 
> destruction of the command, at which point I could do clean-up. Is that 
> path foolproof? This would also entail removing all g_free clean-ups 
> from the helper functions, because the destroy function is always 
> called, including after invoking the GAttribResultFunc function.
> 

Yeah, this path should be foolproof. The destroy function should be called
even for abnormal cases, the ResultFunc is called just when the command
finishes (with a response or an error).

> Also:
> If we intend to use the ID of the (original) command to cancel the GATT
> procedure, I propose the following:
> 
> Compound GATT procedure such as the Read Long procedure that I am 
> implementing, should save the original ID returned by g_attrib_send in 
> the nested user_data structure such as I have done. When subsequent ATT 
> commands are sent as part of the same GATT procedure, the new command 
> shall be assigned the same ID as the original.  This could be done with 
> a function in gattrib.c with the prototype:
> 
> g_attrib_set_id(GAttrib *attrib, guint old_id, guint new_id);
> 
> This would allow the upper layer to cancel the entire GATT procedure, 
> even if it is partially completed.
> 
> This same methodology could then be applied to long writes, and other 
> compound GATT procedures.
> 
> What do you think?

Sounds good, I just don't know about messing with the commands id's, 
maybe having some thing like command groups. 

For example, adding these funtions:

guint g_attrib_send_full(GAttrib *attrib, guint8 opcode, const guint8 *pdu,
				guint16 len, guint group, GAttribResultFunc func,
				gpointer user_data, GDestroyNotify notify);

gboolean g_attrib_cancel_group(GAttrib *attrib, guint group);

How do this look?

> 
> >
> >> +	g_free(long_read);
> >> +}
> >> +
> >>   guint gatt_read_char(GAttrib *attrib, uint16_t handle, GAttribResultFunc func,
> >>   							gpointer user_data)
> >>   {
> >>   	uint8_t pdu[ATT_DEFAULT_MTU];
> >>   	guint16 plen;
> >> +	guint ret_val;
> >> +	struct read_long_data *long_read;
> >> +
> >> +	long_read = g_try_new0(struct read_long_data, 1);
> >> +
> >> +	if (long_read == NULL)
> >> +		return 0;
> >> +
> >> +	long_read->attrib = attrib;
> >> +	long_read->func = func;
> >> +	long_read->user_data = user_data;
> >> +	long_read->handle = handle;
> >>
> >>   	plen = enc_read_req(handle, pdu, sizeof(pdu));
> >> -	return g_attrib_send(attrib, ATT_OP_READ_REQ, pdu, plen, func,
> >> -							user_data, NULL);
> >> +	ret_val = g_attrib_send(attrib, ATT_OP_READ_REQ, pdu, plen,
> >> +			     		read_char_helper, long_read, NULL);
> >> +
> >> +	if (ret_val == 0)
> >> +		g_free(long_read);
> >> +
> >> +	return ret_val;
> >>   }
> >>
> >>   guint gatt_write_char(GAttrib *attrib, uint16_t handle, uint8_t *value,
> >> --
> >> 1.7.1
> >>
> >> --
> >> 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,
> 
> Thanks,
> 
> -- 
> Brian Gix
> bgix@codeaurora.org
> Employee of Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

Cheers,
-- 
Vinicius

^ 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