Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH 3/3] configure.ac: build system improvements
From: Cristian Rodríguez @ 2012-12-24 18:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Cristian Rodríguez

Use AC_SYS_LARGEFILE so proper flags are set on systems
that require special settings for large file support

Use AC_PROG_CC_STDC, this macro picks the latest recommended
C standard flags for the compiler.
---
 configure.ac | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 522e349..614bf1f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,6 +5,7 @@ AM_INIT_AUTOMAKE([foreign subdir-objects color-tests silent-rules
 					tar-pax no-dist-gzip dist-xz])
 AM_CONFIG_HEADER(config.h)
 AC_USE_SYSTEM_EXTENSIONS
+AC_SYS_LARGEFILE
 
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
@@ -20,7 +21,7 @@ AC_LANG_C
 
 AC_C_RESTRICT
 
-AC_PROG_CC
+AC_PROG_CC_STDC
 AM_PROG_CC_C_O
 AC_PROG_CC_PIE
 AC_PROG_INSTALL
-- 
1.8.0.2


^ permalink raw reply related

* Re: [PATCH] lib: use %m instead of strerror
From: Cristian Rodríguez @ 2012-12-24 19:10 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1356369208.29264.46.camel@aeonflux>

On Mon 24 Dec 2012 02:13:28 PM CLST, Marcel Holtmann wrote:
> Hi Cristian,
>
>> Unlike strerror, %m is thread safe and we do not know
>> to what kind of program libbluetooh is being linked too.
>> ---
>>   lib/sdp.c | 17 ++++++++---------
>>   1 file changed, 8 insertions(+), 9 deletions(-)
>
> patch has been applied.
>
> Regards
>
> Marcel
>
>
OK, just FYI, just checked the source code.. uclibc has to be built 
with UCLIBC_HAS_PRINTF_M_SPEC=y and will be fine.

^ permalink raw reply

* [ANNOUNCE] Release of BlueZ 5.0
From: Marcel Holtmann @ 2012-12-25  2:10 UTC (permalink / raw)
  To: linux-bluetooth

Hello everyone,

it has been a yearly tradition to have a X-mas release. So it is with
great pleasure to announce that this year, the X-mas release is actually
the start of our next major development cycle. Please join me in
welcoming our BlueZ 5.0 release.

The 5.0 release has been 6 month in the making and a lot of things have
changed. The BlueZ package grew significantly over the last few month
since we consumed obexd and hcidump packages into it. This will deliver
a one stop experience for Bluetooth.

While including obexd and hcidump allows for better sharing of code and
deeper integration, we also took code out. The SBC codec support became
a separate library and has its own tree now. And we pushed the GStreamer
plugin into GStreamer upstream.

We switched the whole D-Bus API over to use the D-Bus Properties and
ObjectManager standard interfaces. This should make its usage a lot
simpler for client applications. In addition the new D-Bus API comes
with interface versions. This allows us to support multiple APIs at the
same time in the future.

Reflecting back at the 4.x development cycle, we released BlueZ 4.0 on
6th of August 2008 and BlueZ 4.101 on 22nd of June 2012. This means we
actually did 102 releases within 4 years. On average that is 2 releases
per month.

The 4.x cycle saw patches from 139 contributors and I like to thank
everybody who contributed fixes and features (in alphabetical order):

Adam Gołębiowski, Alex Elsayed, Alok Barsode, Anderson Briglia, Anderson
Lizardo, André Dieb Martins, Andre Guedes, Andrei Emeltchenko, Andrzej
Kaczmarek, Angela Bartholomaus, Ankush Bansal, Antti Julku, Arek Lichwa,
Arik Nemtsov, Arnaud Mouiche, Arun Kumar Singh, Arun Raghavan,
Balamurugan Mahalingam, Bartlomiej Grzeskowiak, Bastien Nocera, Bea Lam,
Brian Gix, Bruna Moreira, Bruno Dilly, Burt Silverman, Chan-yeol Park,
Chen Ganir, Christian Hoene, Claudio Takahasi, Colin Didier, Daniel
Orstadius, Daniel Wagner, David Herrmann, David Scherba, David
Stockwell, David Vrabel, David Woodhouse, Denis Kenzior, Dmitriy Paliy,
DoHyun Pyun, Elvis Pfützenreuter, Filippo Giunchedi, Forrest, Forrest
Zhao, Francisco Alecrim, Frédéric Dalleau, Frédéric Danis, Grant
Erickson, Gustavo F. Padovan, Harri Mahonen, Hemant Gupta, Ido Yariv,
Ilia Kolomisnky, Ilya Rubtsov, Inga Stotland, Jaganath Kanakkassery,
Jaikumar Ganesh, Jefferson Delfes, Jeff Hansen, Jiafa Liu, João Paulo
Rechi Vita, Johan Hedberg, Johan Hovold, John Crosbie, Joohi Rastogi,
Jorge Fernandez Gonzalez, José Antonio Santos Cadenas, Kay Sievers,
Keith Mok, Lennart Poettering, Lucas De Marchi, Luiz Augusto von Dentz,
Lukasz Pawlik, Lukasz Rymanowski, Łukasz Stelmach, Maarten Bosmans,
Marc-André Lureau, Marcel Holtmann, Marco Sinigaglia, Mario Limonciello,
Matthew Wilson, Michael Brudevold, Michal Labedzki, Mika Linnanoja,
Mikel Astiz, Mike Lockwood, Nick Pelly, Nobuhiro Iwamatsu, Ohad
Ben-Cohen, Olli-Pekka Salin, Pacho Ramos, Patrick Ohly, Paul Fertser,
Paulo Alcantara, Pavan Savoy, Pavel Raiskup, Pawel Wieczorkiewicz, Pekka
Pessi, Peter Hurley, Peter Krystad, Peter Zotov, Radoslaw Jablonski,
Rafael Fonseca, Rafal Michalski, Raymond Liu, RISKÓ Gergely, Santiago
Carot-Nemesio, Scott James Remnant, Scott Talbot, Sheldon Demario,
Siarhei Siamashka, Slawomir Bochenski, Smriti Gupta, Stefan Seyfried,
Steve Grubb, Steve Langasek, Steven Luo, Suraj Sumangala, Syam
Sidhardhan, Szymon Janc, Tedd Ho-Jeong An, Till Kamppeter, Timo Gienger,
Tom Gundersen, Tommi Keisala, Tom Rini, Uwe Kleine-König, Ville Tervo,
Vinicius Costa Gomes, Vishal Agarwal, Vladimir Botka, Vladimir Davydov,
Wade Brown, Waldemar Rymarkiewicz, Yegor Yefremov, Zhenhua Zhang, Zhu
Lan, Zhu Yanhai, Zygo Blaxell

Enjoy the holidays and Happy New Year.

Regards

Marcel



^ permalink raw reply

* [PATCH] Bluetooth: fix the oops due to conn->hcon == NULL in shutdown case
From: Chuansheng Liu @ 2012-12-25 10:04 UTC (permalink / raw)
  To: gustavo, marcel, johan.hedberg
  Cc: linux-bluetooth, linux-kernel, chuansheng.liu


Meet one panic issue as below stack:
<1>[11340.226404] BUG: unable to handle kernel NULL pointer dereference at 00000008
<4>[11340.226619] EIP is at __sco_sock_close+0xe8/0x1a0
<4>[11340.226629] EAX: f063a740 EBX: 00000000 ECX: f58f4544 EDX: 00000000
<4>[11340.226640] ESI: dec83e00 EDI: 5f9a081f EBP: e0fdff38 ESP: e0fdff1c
<0>[11340.226674] Stack:
<4>[11340.226682]  c184db87 c1251028 dec83e00 e0fdff38 c1754aef dec83e00 00000000 e0fdff5c
<4>[11340.226718]  c184f587 e0fdff64 e0fdff68 5f9a081f e0fdff5c c1751852 d7813800 62262f10
<4>[11340.226752]  e0fdff70 c1753c00 00000000 00000001 0000000d e0fdffac c175425c 00000041
<0>[11340.226793] Call Trace:
<4>[11340.226813]  [<c184db87>] ? sco_sock_clear_timer+0x27/0x60
<4>[11340.226831]  [<c1251028>] ? local_bh_enable+0x68/0xd0
<4>[11340.226846]  [<c1754aef>] ? lock_sock_nested+0x4f/0x60
<4>[11340.226862]  [<c184f587>] sco_sock_shutdown+0x67/0xb0
<4>[11340.226879]  [<c1751852>] ? sockfd_lookup_light+0x22/0x80
<4>[11340.226897]  [<c1753c00>] sys_shutdown+0x30/0x60
<4>[11340.226912]  [<c175425c>] sys_socketcall+0x1dc/0x2a0
<4>[11340.226929]  [<c149ba78>] ? trace_hardirqs_on_thunk+0xc/0x10
<4>[11340.226944]  [<c18860f1>] syscall_call+0x7/0xb
<4>[11340.226960]  [<c1880000>] ? restore_cur+0x5e/0xd7
<0>[11340.226969] Code: <f0> ff 4b 08 0f 94 c0 84 c0 74 20 80 7b 19 01 74 2f b8 0a 00 00

Disassemble the code:
base address of __sco_sock_close is 0xc184f410
0xc184f4f8 <+232>:   lock decl 0x8(%ebx) < == crash here, ebx is 0x0,

the related source code is:
(gdb) l *0xc184f4f8
0xc184f4f8 is in __sco_sock_close (arch/x86/include/asm/atomic.h:123)
119     static inline int atomic_dec_and_test(atomic_t *v)
123             asm volatile(LOCK_PREFIX "decl %0; sete %1"

The whole call stack is:
sys_shutdown()
  sco_sock_shutdown()
    __sco_sock_close()
      hci_conn_put()
        atomic_dec_and_test()

Due to the conn->hcon is NULL, and the member hcon->refcnt is at offset 0x8,
so "BUG: unable to handle kernel NULL pointer dereference at 00000008"
appears.

Here fix it that adding the condition if conn->hcon is NULL, just like
in sco_chan_del().

Signed-off-by: liu chuansheng <chuansheng.liu@intel.com>
---
 net/bluetooth/sco.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 531a93d..190f70c 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -355,8 +355,10 @@ static void __sco_sock_close(struct sock *sk)
 		if (sco_pi(sk)->conn) {
 			sk->sk_state = BT_DISCONN;
 			sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT);
-			hci_conn_put(sco_pi(sk)->conn->hcon);
-			sco_pi(sk)->conn->hcon = NULL;
+			if (sco_pi(sk)->conn->hcon) {
+				hci_conn_put(sco_pi(sk)->conn->hcon);
+				sco_pi(sk)->conn->hcon = NULL;
+			}
 		} else
 			sco_chan_del(sk, ECONNRESET);
 		break;
-- 
1.7.0.4

^ permalink raw reply related

* Re: [RFC/RFT] rtk_btusb: Bluetooth driver for Realtek RTL8723AE combo device
From: Ben Hutchings @ 2012-12-25 23:43 UTC (permalink / raw)
  To: Larry Finger
  Cc: linville, Marcel Holtmann, Gustavo Padovan, Johan Hedberg,
	linux-wireless, linux-bluetooth, Champion Chen
In-Reply-To: <1356058371-17152-1-git-send-email-Larry.Finger@lwfinger.net>

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

On Fri, 2012-12-21 at 02:52 +0000, Larry Finger wrote:
[...]
> --- /dev/null
> +++ b/drivers/bluetooth/rtk_btusb.c
[...]
> +#include <linux/version.h>

Not needed.

> +#include <linux/pm_runtime.h>

Move this up to the first group of #includes.

> +#define HDEV_BUS		(hdev->bus)

This is just obfuscation.

> +#define USB_RPM			1
> +
> +#define GET_DRV_DATA(x)		hci_get_drvdata(x)
> +
> +
> +#define BTUSB_RPM		0	/*1 SS enable; 0 SS disable */

Run-time power management should be enabled if it works and not included
yet if it doesn't.  This shouldn't be a compile-time option in a
production driver.

> +#define LOAD_CONFIG		0

Seems to be a rather pointless development option, but if it still has
some value then it deserves a comment.

> +#define URB_CANCELING_DELAY_MS	10   /*  Added by Realtek */

/* BWH 2012-12-25: Doesn't Realtek have version control to record this? */

[...]
> +/*******************************
> +**    Reasil patch code
> +********************************/

Another weird little bit of history which no-one cares about.

> +#include <linux/firmware.h>
> +#include <linux/suspend.h>
> +#include <net/bluetooth/hci.h>

Belong at the top of the file.

[...]
> +static int rtkbt_pm_notify(struct notifier_block *notifier, ulong pm_event,
> +                   void *unused)
> +{
> +       struct dev_data *dev_entry;
> +       struct patch_info       *patch_entry;
> +       struct usb_device *udev;
> +
> +       dev_entry = container_of(notifier, struct dev_data, pm_notifier);
> +       patch_entry = dev_entry->patch_entry;
> +       udev = dev_entry->udev;
> +       RTKBT_DBG("rtkbt_pm_notify pm_event =%ld", pm_event);
> +       switch (pm_event) {
> +       case PM_SUSPEND_PREPARE:
> +       case PM_HIBERNATION_PREPARE:
> +               patch_entry->fw_len = load_firmware(dev_entry,
> +                                                   &patch_entry->fw_cache);

But this is done once for each device, not for each device type.  So you
potentially load the firmware multiple times here and leak all but one.

Anyway I'm not sure this caching is needed any more due to the firmware
management improvements in 3.7.

[...]
> +static int load_firmware(struct dev_data *dev_entry, uint8_t **buff)
> +{
> +#if LOAD_CONFIG
> +	const struct firmware *fw;
> +#endif
> +	struct usb_device *udev;
> +	struct patch_info *patch_entry;
> +	char *fw_name;
> +	int fw_len = 0, ret_val;
> +
> +	udev = dev_entry->udev;
> +	init_completion(&dev_entry->firmware_loading_complete);
> +	patch_entry = dev_entry->patch_entry;
> +	fw_name = patch_entry->patch_name;
> +	RTKBT_DBG("Reading firmware file %s", fw_name);
> +	ret_val = request_firmware_nowait(THIS_MODULE, 1, fw_name, &udev->dev,
> +					  GFP_KERNEL, dev_entry, bt_fw_cb);
> +	if (ret_val < 0)
> +		goto fw_fail;
> +
> +	wait_for_completion(&dev_entry->firmware_loading_complete);

What was the point of using request_firmware_nowait() then?

> +	if (!dev_entry->fw)
> +		goto fw_fail;
> +	*buff = kzalloc(dev_entry->fw->size, GFP_KERNEL);
> +	if (NULL == *buff)
> +		goto alloc_fail;
> +	memcpy(*buff, dev_entry->fw->data, dev_entry->fw->size);
> +	fw_len = dev_entry->fw->size;
> +
> +#if LOAD_CONFIG
> +	release_firmware(dev_entry->fw);
> +	fw_name = patch_entry->config_name;
> +	ret_val = request_firmware(&fw, fw_name, &udev->dev);
> +	if (ret_val < 0) {
> +		fw_len = 0;
> +		kfree(*buff);
> +		*buff = NULL;
> +		goto fw_fail;
> +	}
> +
> +	*buff = krealloc(*buff, fw_len + fw->size, GFP_KERNEL);
> +	if (NULL == *buff) {
> +		fw_len = 0;
> +		release_firmware(fw);
> +		goto fw_fail;
> +	}
> +	memcpy(*buff + fw_len, fw->data, fw->size);
> +	fw_len += fw->size;
> +#endif

It's easy to concatenate files in userland; why do it in the driver?

> +alloc_fail:
> +	release_firmware(dev_entry->fw);
> +fw_fail:
> +	return fw_len;
> +}
[...]

-- 
Ben Hutchings
Every program is either trivial or else contains at least one bug

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: [RFC/RFT] rtk_btusb: Bluetooth driver for Realtek RTL8723AE combo device
From: Larry Finger @ 2012-12-26  2:33 UTC (permalink / raw)
  To: Ben Hutchings
  Cc: linville, Marcel Holtmann, Gustavo Padovan, Johan Hedberg,
	linux-wireless, linux-bluetooth, Champion Chen
In-Reply-To: <1356479032.21837.107.camel@deadeye.wl.decadent.org.uk>

On 12/25/2012 05:43 PM, Ben Hutchings wrote:
> On Fri, 2012-12-21 at 02:52 +0000, Larry Finger wrote:
> [...]
>> --- /dev/null
>> +++ b/drivers/bluetooth/rtk_btusb.c
> [...]
>> +#include <linux/version.h>
>
> Not needed.
>
>> +#include <linux/pm_runtime.h>
>
> Move this up to the first group of #includes.
>
>> +#define HDEV_BUS		(hdev->bus)
>
> This is just obfuscation.
>
>> +#define USB_RPM			1
>> +
>> +#define GET_DRV_DATA(x)		hci_get_drvdata(x)
>> +
>> +
>> +#define BTUSB_RPM		0	/*1 SS enable; 0 SS disable */
>
> Run-time power management should be enabled if it works and not included
> yet if it doesn't.  This shouldn't be a compile-time option in a
> production driver.
>
>> +#define LOAD_CONFIG		0
>
> Seems to be a rather pointless development option, but if it still has
> some value then it deserves a comment.
>
>> +#define URB_CANCELING_DELAY_MS	10   /*  Added by Realtek */
>
> /* BWH 2012-12-25: Doesn't Realtek have version control to record this? */
>
> [...]
>> +/*******************************
>> +**    Reasil patch code
>> +********************************/
>
> Another weird little bit of history which no-one cares about.
>
>> +#include <linux/firmware.h>
>> +#include <linux/suspend.h>
>> +#include <net/bluetooth/hci.h>
>
> Belong at the top of the file.
>
> [...]
>> +static int rtkbt_pm_notify(struct notifier_block *notifier, ulong pm_event,
>> +                   void *unused)
>> +{
>> +       struct dev_data *dev_entry;
>> +       struct patch_info       *patch_entry;
>> +       struct usb_device *udev;
>> +
>> +       dev_entry = container_of(notifier, struct dev_data, pm_notifier);
>> +       patch_entry = dev_entry->patch_entry;
>> +       udev = dev_entry->udev;
>> +       RTKBT_DBG("rtkbt_pm_notify pm_event =%ld", pm_event);
>> +       switch (pm_event) {
>> +       case PM_SUSPEND_PREPARE:
>> +       case PM_HIBERNATION_PREPARE:
>> +               patch_entry->fw_len = load_firmware(dev_entry,
>> +                                                   &patch_entry->fw_cache);
>
> But this is done once for each device, not for each device type.  So you
> potentially load the firmware multiple times here and leak all but one.
>
> Anyway I'm not sure this caching is needed any more due to the firmware
> management improvements in 3.7.

I will modify this to make sure that the firmware is loaded only once.

> [...]
>> +static int load_firmware(struct dev_data *dev_entry, uint8_t **buff)
>> +{
>> +#if LOAD_CONFIG
>> +	const struct firmware *fw;
>> +#endif
>> +	struct usb_device *udev;
>> +	struct patch_info *patch_entry;
>> +	char *fw_name;
>> +	int fw_len = 0, ret_val;
>> +
>> +	udev = dev_entry->udev;
>> +	init_completion(&dev_entry->firmware_loading_complete);
>> +	patch_entry = dev_entry->patch_entry;
>> +	fw_name = patch_entry->patch_name;
>> +	RTKBT_DBG("Reading firmware file %s", fw_name);
>> +	ret_val = request_firmware_nowait(THIS_MODULE, 1, fw_name, &udev->dev,
>> +					  GFP_KERNEL, dev_entry, bt_fw_cb);
>> +	if (ret_val < 0)
>> +		goto fw_fail;
>> +
>> +	wait_for_completion(&dev_entry->firmware_loading_complete);
>
> What was the point of using request_firmware_nowait() then?

None. Obviously a synchronous firmware load will work as long as load_firmware() 
is not called from the probe routine, and this one will fail if it is.

>> +	if (!dev_entry->fw)
>> +		goto fw_fail;
>> +	*buff = kzalloc(dev_entry->fw->size, GFP_KERNEL);
>> +	if (NULL == *buff)
>> +		goto alloc_fail;
>> +	memcpy(*buff, dev_entry->fw->data, dev_entry->fw->size);
>> +	fw_len = dev_entry->fw->size;
>> +
>> +#if LOAD_CONFIG
>> +	release_firmware(dev_entry->fw);
>> +	fw_name = patch_entry->config_name;
>> +	ret_val = request_firmware(&fw, fw_name, &udev->dev);
>> +	if (ret_val < 0) {
>> +		fw_len = 0;
>> +		kfree(*buff);
>> +		*buff = NULL;
>> +		goto fw_fail;
>> +	}
>> +
>> +	*buff = krealloc(*buff, fw_len + fw->size, GFP_KERNEL);
>> +	if (NULL == *buff) {
>> +		fw_len = 0;
>> +		release_firmware(fw);
>> +		goto fw_fail;
>> +	}
>> +	memcpy(*buff + fw_len, fw->data, fw->size);
>> +	fw_len += fw->size;
>> +#endif
>
> It's easy to concatenate files in userland; why do it in the driver?
>
>> +alloc_fail:
>> +	release_firmware(dev_entry->fw);
>> +fw_fail:
>> +	return fw_len;
>> +}
> [...]
>

Thanks for the review. Following the previous suggestions, I am trying to use 
btusb.c for this device with the mini-driver proposed by Tedd Ho-Jeong An.

Larry


^ permalink raw reply

* Re: [RFC/RFT] rtk_btusb: Bluetooth driver for Realtek RTL8723AE combo device
From: Larry Finger @ 2012-12-26  2:45 UTC (permalink / raw)
  To: Oliver Neukum
  Cc: linville, Marcel Holtmann, Gustavo Padovan, Johan Hedberg,
	linux-wireless, linux-bluetooth, Champion Chen
In-Reply-To: <6432515.NlhvICzq3b@linux-lqwf.site>

On 12/23/2012 03:00 PM, Oliver Neukum wrote:
> On Thursday 20 December 2012 20:52:51 Larry Finger wrote:
>> This new driver works with the RTL8723AE wireless/BT combo device. The
>> corresponding firmware has been submitted to linux-firmware.
>>
>> Signed-off-by: Champion Chen <champion_chen@realsil.com.cn>
>> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
>> ---
>>   drivers/bluetooth/Kconfig     |   10 +
>>   drivers/bluetooth/Makefile    |    1 +
>>   drivers/bluetooth/rtk_btusb.c | 1649 +++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 1660 insertions(+)
>>   create mode 100644 drivers/bluetooth/rtk_btusb.c
>>
>> diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
>> index e9f203e..efd3766 100644
>> --- a/drivers/bluetooth/Kconfig
>> +++ b/drivers/bluetooth/Kconfig
>> @@ -241,4 +241,14 @@ config BT_WILINK
>>
>>   	  Say Y here to compile support for Texas Instrument's WiLink7 driver
>>   	  into the kernel or say M to compile it as module.
>> +
>> +config BT_RTKUSB
>> +	tristate "Realtek BT driver for RTL8723AE"
>> +	select FW_LOADER
>> +	help
>> +	  This enables the Bluetooth driver for the Realtek RTL8723AE Wifi/BT
>> +	  combo device.
>> +
>> +	  Say Y here to compile support for these devices into the kernel
>> +	  or say M to build it as a module.
>>   endmenu
>> diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
>> index 4afae20..167ccc0 100644
>> --- a/drivers/bluetooth/Makefile
>> +++ b/drivers/bluetooth/Makefile
>> @@ -19,6 +19,7 @@ obj-$(CONFIG_BT_ATH3K)		+= ath3k.o
>>   obj-$(CONFIG_BT_MRVL)		+= btmrvl.o
>>   obj-$(CONFIG_BT_MRVL_SDIO)	+= btmrvl_sdio.o
>>   obj-$(CONFIG_BT_WILINK)		+= btwilink.o
>> +obj-$(CONFIG_BT_RTKUSB)		+= rtk_btusb.o
>>
>>   btmrvl-y			:= btmrvl_main.o
>>   btmrvl-$(CONFIG_DEBUG_FS)	+= btmrvl_debugfs.o
>> diff --git a/drivers/bluetooth/rtk_btusb.c b/drivers/bluetooth/rtk_btusb.c
>> new file mode 100644
>> index 0000000..31c128a
>> --- /dev/null
>> +++ b/drivers/bluetooth/rtk_btusb.c
>> @@ -0,0 +1,1650 @@
>> +/*
>> + *
>> + *  Realtek Bluetooth USB driver
>> + *
>> + *  Copyright (C) 2012-2015  Edward Bian <edward_bian@realsil.com.cn>
>> + *
>> + *
>> + *  This program is free software; you can redistribute it and/or modify
>> + *  it under the terms of the GNU General Public License as published by
>> + *  the Free Software Foundation; either version 2 of the License, or
>> + *  (at your option) any later version.
>> + *
>> + *  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/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/init.h>
>> +#include <linux/slab.h>
>> +#include <linux/types.h>
>> +#include <linux/sched.h>
>> +#include <linux/errno.h>
>> +#include <linux/skbuff.h>
>> +#include <linux/usb.h>
>> +#include <linux/completion.h>
>> +#include <net/bluetooth/bluetooth.h>
>> +#include <net/bluetooth/hci_core.h>
>> +
>> +#define VERSION "0.8"
>> +
>> +static struct usb_driv> diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
>> index e9f203e..efd3766 100644
>
>> +static struct usb_driver btusb_driver;
>> +#if 1
>> +#define RTKBT_DBG(fmt, arg...) pr_info("rtk_btusb: " fmt "\n" , ## arg)
>
> No new debug macros please.

OK.

>
>> +
>> +static int btusb_open(struct hci_dev *hdev)
>> +{
>> +	struct btusb_data *data = GET_DRV_DATA(hdev);
>> +	int err;
>> +
>> +	err = usb_autopm_get_interface(data->intf);
>> +	if (err < 0)
>> +		return err;
>> +
>> +	data->intf->needs_remote_wakeup = 1;
>> +	RTKBT_DBG("%s start pm_usage_cnt(0x%x)", __func__,
>> +		  atomic_read(&(data->intf->pm_usage_cnt)));
>> +
>> +	/*******************************/
>> +	if (0 == atomic_read(&hdev->promisc)) {
>> +		RTKBT_DBG("btusb_open hdev->promisc == 0");
>> +		err = -1;
>
> This makes no sense

I will need to talk to the Realtek guys about this code to see what they meant.

>
>> +	}
>> +	err = download_patch(data->intf);
>> +	if (err < 0)
>> +		goto failed;
>
> On every open?
>
>> +	/*******************************/
>> +
>> +	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
>> +		goto done;
>> +
>> +	if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
>> +		goto done;
>> +
>> +	err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
>> +	if (err < 0)
>> +		goto failed;
>> +
>> +	err = btusb_submit_bulk_urb(hdev, GFP_KERNEL);
>> +	if (err < 0) {
>> +		mdelay(URB_CANCELING_DELAY_MS);      /*  Added by Realtek */
>> +		usb_kill_anchored_urbs(&data->intr_anchor);
>> +		goto failed;
>> +	}
>> +
>> +	set_bit(BTUSB_BULK_RUNNING, &data->flags);
>> +	btusb_submit_bulk_urb(hdev, GFP_KERNEL);
>> +
>> +done:
>> +	usb_autopm_put_interface(data->intf);
>> +	RTKBT_DBG("%s end  pm_usage_cnt(0x%x)", __func__,
>> +		  atomic_read(&(data->intf->pm_usage_cnt)));
>> +
>> +	return 0;
>> +
>> +failed:
>> +	clear_bit(BTUSB_INTR_RUNNING, &data->flags);
>> +	clear_bit(HCI_RUNNING, &hdev->flags);
>> +	usb_autopm_put_interface(data->intf);
>> +	RTKBT_DBG("%s failed  pm_usage_cnt(0x%x)", __func__,
>> +		  atomic_read(&(data->intf->pm_usage_cnt)));
>> +	return err;
>> +}
>> +
>> +static void btusb_stop_traffic(struct btusb_data *data)
>> +{
>> +	mdelay(URB_CANCELING_DELAY_MS);    /*  Added by Realtek */
>> +	usb_kill_anchored_urbs(&data->intr_anchor);
>> +	usb_kill_anchored_urbs(&data->bulk_anchor);
>> +	usb_kill_anchored_urbs(&data->isoc_anchor);
>> +}
>> +
>> +static int btusb_close(struct hci_dev *hdev)
>> +{
>> +	struct btusb_data *data = GET_DRV_DATA(hdev);
>> +	int i, err;
>> +
>> +	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
>> +		return 0;
>> +
>> +	RTKBT_DBG("btusb_close");
>> +	/*******************************/
>> +	for (i = 0; i < NUM_REASSEMBLY; i++) {
>> +		if (hdev->reassembly[i])	{
>> +			kfree_skb(hdev->reassembly[i]);
>> +			hdev->reassembly[i] = NULL;
>> +			RTKBT_DBG("%s free ressembly i =%d", __func__, i);
>> +		}
>> +	}
>> +	/*******************************/
>> +	cancel_work_sync(&data->work);
>> +	cancel_work_sync(&data->waker);
>> +
>> +	clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
>> +	clear_bit(BTUSB_BULK_RUNNING, &data->flags);
>> +	clear_bit(BTUSB_INTR_RUNNING, &data->flags);
>> +
>> +	btusb_stop_traffic(data);
>> +	err = usb_autopm_get_interface(data->intf);
>> +	if (err < 0)
>> +		goto failed;
>> +
>> +	data->intf->needs_remote_wakeup = 0;
>> +	usb_autopm_put_interface(data->intf);
>> +
>> +failed:
>> +	mdelay(URB_CANCELING_DELAY_MS);     /*  Added by Realtek */
>
> This makes no sense. Those URBs never went over the wire.

Agreed.

>> +	usb_scuttle_anchored_urbs(&data->deferred);
>> +	return 0;
>> +}
>> +
>> +static int btusb_flush(struct hci_dev *hdev)
>> +{
>> +	struct btusb_data *data = GET_DRV_DATA(hdev);
>> +
>> +	RTKBT_DBG("%s add delay ", __func__);
>> +	mdelay(URB_CANCELING_DELAY_MS);     /*  Added by Realtek */
>> +	usb_kill_anchored_urbs(&data->tx_anchor);
>> +
>> +	return 0;
>> +}
>> +
>
>
>> +
>> +static void btusb_work(struct work_struct *work)
>> +{
>> +	struct btusb_data *data = container_of(work, struct btusb_data, work);
>> +	struct hci_dev *hdev = data->hdev;
>> +	int err;
>> +
>> +	if (hdev->conn_hash.sco_num > 0) {
>> +		if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
>> +			err = usb_autopm_get_interface(data->isoc ? data->isoc :
>> +						       data->intf);
>> +			if (err < 0) {
>> +				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
>> +				/*  Delay added by Realtek */
>> +				mdelay(URB_CANCELING_DELAY_MS);
>> +				usb_kill_anchored_urbs(&data->isoc_anchor);
>> +				return;
>> +			}
>> +
>> +			set_bit(BTUSB_DID_ISO_RESUME, &data->flags);
>> +		}
>> +		if (data->isoc_altsetting != 2) {
>> +			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
>> +			mdelay(URB_CANCELING_DELAY_MS);  /*  Added by Realtek */
>> +			usb_kill_anchored_urbs(&data->isoc_anchor);
>> +
>> +			if (__set_isoc_interface(hdev, 2) < 0)
>> +				return;
>> +		}
>> +
>> +		if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
>> +			if (btusb_submit_isoc_urb(hdev, GFP_KERNEL) < 0)
>> +				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
>> +			else
>> +				btusb_submit_isoc_urb(hdev, GFP_KERNEL);
>> +		}
>> +	} else {
>> +		clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
>> +		mdelay(URB_CANCELING_DELAY_MS);      /*  Added by Realtek */
>> +		usb_kill_anchored_urbs(&data->isoc_anchor);
>> +
>> +		__set_isoc_interface(hdev, 0);
>> +		if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
>> +			usb_autopm_put_interface(data->isoc ? data->isoc :
>> +						 data->intf);
>> +	}
>> +}
>
>> +static int btusb_probe(struct usb_interface *intf,
>> +				const struct usb_device_id *id)
>> +{
>> +	struct usb_endpoint_descriptor *ep_desc;
>> +	struct btusb_data *data;
>> +	struct hci_dev *hdev;
>> +	int i, err, flag1, flag2;
>> +	struct usb_device *udev;
>> +	udev = interface_to_usbdev(intf);
>> +
>> +	/* interface numbers are hardcoded in the spec */
>> +	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
>> +		return -ENODEV;
>> +
>> +	/*******************************/
>> +	flag1 = device_can_wakeup(&udev->dev);
>> +	flag2 = device_may_wakeup(&udev->dev);
>> +	RTKBT_DBG("btusb_probe 1 ========== can_wakeup =%x	 flag2 =%x",
>> +		  flag1, flag2);
>> +	device_wakeup_disable(&udev->dev);
>
> Why?

Another question for Realtek.

>
>> +	flag1 = device_can_wakeup(&udev->dev);
>> +	flag2 = device_may_wakeup(&udev->dev);
>> +	RTKBT_DBG("wakeup_disable ========== can_wakeup =%x	 flag2 =%x",
>> +		  flag1, flag2);
>> +	err = patch_add(intf);
>> +	if (err < 0)
>> +		return -1;
>> +	/*******************************/
>> +
>> +	data = kzalloc(sizeof(*data), GFP_KERNEL);
>> +	if (!data)
>> +		return -ENOMEM;
>> +
>> +
>> +	for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
>> +		ep_desc = &intf->cur_altsetting->endpoint[i].desc;
>> +
>> +		if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) {
>> +			data->intr_ep = ep_desc;
>> +			continue;
>> +		}
>> +
>> +		if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) {
>> +			data->bulk_tx_ep = ep_desc;
>> +			continue;
>> +		}
>> +
>> +		if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) {
>> +			data->bulk_rx_ep = ep_desc;
>> +			continue;
>> +		}
>> +	}
>> +
>> +	if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) {
>> +		kfree(data);
>> +		return -ENODEV;
>> +	}
>> +
>> +	data->cmdreq_type = USB_TYPE_CLASS;
>> +
>> +	data->udev = interface_to_usbdev(intf);
>> +	data->intf = intf;
>> +
>> +	spin_lock_init(&data->lock);
>> +
>> +	INIT_WORK(&data->work, btusb_work);
>> +	INIT_WORK(&data->waker, btusb_waker);
>> +	spin_lock_init(&data->txlock);
>> +
>> +	init_usb_anchor(&data->tx_anchor);
>> +	init_usb_anchor(&data->intr_anchor);
>> +	init_usb_anchor(&data->bulk_anchor);
>> +	init_usb_anchor(&data->isoc_anchor);
>> +	init_usb_anchor(&data->deferred);
>> +
>> +	hdev = hci_alloc_dev();
>> +	if (!hdev) {
>> +		kfree(data);
>> +		return -ENOMEM;
>> +	}
>> +
>> +	HDEV_BUS = HCI_USB;
>> +
>> +	data->hdev = hdev;
>> +
>> +	SET_HCIDEV_DEV(hdev, &intf->dev);
>> +
>> +	hdev->open     = btusb_open;
>> +	hdev->close    = btusb_close;
>> +	hdev->flush    = btusb_flush;
>> +	hdev->send     = btusb_send_frame;
>> +	hdev->notify   = btusb_notify;
>> +
>> +
>> +	hci_set_drvdata(hdev, data);
>> +
>> +	/* Interface numbers are hardcoded in the specification */
>> +	data->isoc = usb_ifnum_to_if(data->udev, 1);
>> +
>> +	if (data->isoc) {
>> +		err = usb_driver_claim_interface(&btusb_driver,
>> +						 data->isoc, data);
>> +		if (err < 0) {
>> +			hci_free_dev(hdev);
>> +			kfree(data);
>> +			return err;
>> +		}
>> +	}
>> +
>> +	err = hci_register_dev(hdev);
>> +	if (err < 0) {
>> +		hci_free_dev(hdev);
>> +		kfree(data);
>> +		return err;
>> +	}
>> +
>> +	usb_set_intfdata(intf, data);
>> +
>> +	return 0;
>> +}
>> +
>> +static void btusb_disconnect(struct usb_interface *intf)
>> +{
>> +	struct btusb_data *data = usb_get_intfdata(intf);
>> +	struct hci_dev *hdev;
>> +	struct usb_device *udev;
>> +	udev = interface_to_usbdev(intf);
>> +
>> +	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
>> +		return;
>> +
>> +	if (!data)
>> +		return;
>> +
>> +	RTKBT_DBG("btusb_disconnect");
>> +	/*******************************/
>> +	patch_remove(intf);
>
> This is a race. The device is not dead at this time.

Noted.

>
>> +	/*******************************/
>> +
>> +	hdev = data->hdev;
>> +
>> +	usb_set_intfdata(data->intf, NULL);
>> +
>> +	if (data->isoc)
>> +		usb_set_intfdata(data->isoc, NULL);
>> +
>> +	hci_unregister_dev(hdev);
>> +
>> +	if (intf == data->isoc)
>> +		usb_driver_release_interface(&btusb_driver, data->intf);
>> +	else if (data->isoc)
>> +		usb_driver_release_interface(&btusb_driver, data->isoc);
>> +
>> +	hci_free_dev(hdev);
>> +	kfree(data);
>> +}
>> +
>> +#ifdef CONFIG_PM
>> +static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
>> +{
>> +	struct btusb_data *data = usb_get_intfdata(intf);
>> +
>> +	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
>> +		return 0;
>> +
>> +	/*******************************/
>> +	RTKBT_DBG("btusb_suspend message.event = 0x%x, data->suspend_count =%d",
>> +		  message.event, data->suspend_count);
>> +	if (!test_bit(HCI_RUNNING, &data->hdev->flags)) {
>> +		RTKBT_DBG("btusb_suspend-----bt is off");
>> +		set_btoff(data->intf);
>
> Why repeat this if the device is already suspended?

Good point!

>
>> +	}
>> +	/*******************************/
>> +
>> +	if (data->suspend_count++)
>> +		return 0;
>> +
>> +	spin_lock_irq(&data->txlock);
>> +	if (!((message.event & PM_EVENT_AUTO) && data->tx_in_flight)) {
>> +		set_bit(BTUSB_SUSPENDING, &data->flags);
>> +		spin_unlock_irq(&data->txlock);
>> +	} else {
>> +		spin_unlock_irq(&data->txlock);
>> +		data->suspend_count--;
>> +		return -EBUSY;
>> +	}
>> +
>> +	cancel_work_sync(&data->work);
>> +
>> +	btusb_stop_traffic(data);
>> +	mdelay(URB_CANCELING_DELAY_MS);      /*  Added by Realtek */
>> +	usb_kill_anchored_urbs(&data->tx_anchor);
>> +
>> +	return 0;
>> +}
>> +
>> +static void play_deferred(struct btusb_data *data)
>> +{
>> +	struct urb *urb;
>> +	int err;
>> +
>> +	while ((urb = usb_get_from_anchor(&data->deferred))) {
>> +
>> +		/************************************/
>> +		usb_anchor_urb(urb, &data->tx_anchor);
>> +		err = usb_submit_urb(urb, GFP_ATOMIC);
>> +		if (err < 0) {
>> +			BT_ERR("play_deferred urb %p submission failed",  urb);
>> +			kfree(urb->setup_packet);
>> +			usb_unanchor_urb(urb);
>> +		} else {
>> +			usb_mark_last_busy(data->udev);
>> +		}
>> +		usb_free_urb(urb);
>> +		/************************************/
>> +		data->tx_in_flight++;
>> +	}
>> +	mdelay(URB_CANCELING_DELAY_MS);     /*  Added by Realtek */
>
> These URBs never went over the wire. Why a delay?

Agreed.

>
>> +	usb_scuttle_anchored_urbs(&data->deferred);
>> +}
>> +
>> +static int btusb_resume(struct usb_interface *intf)
>> +{
>> +	struct btusb_data *data = usb_get_intfdata(intf);
>> +	struct hci_dev *hdev = data->hdev;
>> +	int err = 0;
>> +
>> +	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
>> +		return 0;
>> +
>> +
>> +	/*******************************/
>> +	RTKBT_DBG("btusb_resume data->suspend_count =%d", data->suspend_count);
>> +
>> +	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
>> +		RTKBT_DBG("btusb_resume-----bt is off, download patch");
>> +		download_patch(intf);
>> +	} else {
>> +		RTKBT_DBG("btusb_resume,----bt is on");
>> +	}
>> +	/*******************************/
>> +	if (--data->suspend_count)
>> +		return 0;
>> +
>> +	if (test_bit(BTUSB_INTR_RUNNING, &data->flags)) {
>> +		err = btusb_submit_intr_urb(hdev, GFP_NOIO);
>> +		if (err < 0) {
>> +			clear_bit(BTUSB_INTR_RUNNING, &data->flags);
>> +			goto failed;
>> +		}
>> +	}
>> +
>> +	if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
>> +		err = btusb_submit_bulk_urb(hdev, GFP_NOIO);
>> +		if (err < 0) {
>> +			clear_bit(BTUSB_BULK_RUNNING, &data->flags);
>> +			goto failed;
>> +		}
>> +
>> +		btusb_submit_bulk_urb(hdev, GFP_NOIO);
>> +	}
>> +
>> +	if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
>> +		if (btusb_submit_isoc_urb(hdev, GFP_NOIO) < 0)
>> +			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
>> +		else
>> +			btusb_submit_isoc_urb(hdev, GFP_NOIO);
>> +	}
>> +
>> +	spin_lock_irq(&data->txlock);
>> +	play_deferred(data);
>> +	clear_bit(BTUSB_SUSPENDING, &data->flags);
>> +	spin_unlock_irq(&data->txlock);
>> +	schedule_work(&data->work);
>> +
>> +	return 0;
>> +
>> +failed:
>> +	mdelay(URB_CANCELING_DELAY_MS);      /*  Added by Realtek */
>
> Again, why?

Again, no good reason.

>> +	usb_scuttle_anchored_urbs(&data->deferred);
>> +/* done: */
>> +	spin_lock_irq(&data->txlock);
>> +	clear_bit(BTUSB_SUSPENDING, &data->flags);
>> +	spin_unlock_irq(&data->txlock);
>> +
>> +	return err;
>> +}
>> +#endif
>> +
>> +static struct usb_driver btusb_driver = {
>> +	.name		= "rtk_btusb",
>> +	.probe		= btusb_probe,
>> +	.disconnect	= btusb_disconnect,
>> +#ifdef CONFIG_PM
>> +	.suspend	= btusb_suspend,
>> +	.resume		= btusb_resume,
>> +#endif
>> +	.id_table	= btusb_table,
>> +	.supports_autosuspend = 1,
>> +};
>> +
>> +static int __init btusb_init(void)
>> +{
>> +	RTKBT_DBG("Realtek Bluetooth USB driver ver %s", VERSION);
>> +
>> +	return usb_register(&btusb_driver);
>> +}
>> +
>> +static void __exit btusb_exit(void)
>> +{
>> +	usb_deregister(&btusb_driver);
>> +}
>> +
>> +module_init(btusb_init);
>> +module_exit(btusb_exit);
>> +
>> +MODULE_AUTHOR("Edward Bian <edward_bian@realsil.com.cn>");
>> +MODULE_DESCRIPTION("Realtek Bluetooth USB driver ver " VERSION);
>> +MODULE_VERSION(VERSION);
>> +MODULE_LICENSE("GPL");
>> +MODULE_FIRMWARE("rtl_bt/rtl8723a.bin");
>> +
>> +/*******************************
>> +**    Reasil patch code
>> +********************************/
>> +
>> +
>> +#include <linux/firmware.h>
>> +#include <linux/suspend.h>
>> +#include <net/bluetooth/hci.h>
>> +
>> +
>> +#define CMD_CMP_EVT		0x0e
>> +#define PKT_LEN			300
>> +#define MSG_TO			1000
>> +#define PATCH_SEG_MAX	252
>> +#define DATA_END		0x80
>> +#define DOWNLOAD_OPCODE	0xfc20
>> +#define BTOFF_OPCODE	0xfc28
>> +#define TRUE			1
>> +#define FALSE			0
>> +#define CMD_HDR_LEN		sizeof(struct hci_command_hdr)
>> +#define EVT_HDR_LEN		sizeof(struct hci_event_hdr)
>> +#define CMD_CMP_LEN		sizeof(struct hci_ev_cmd_complete)
>> +
>> +
>> +enum rtk_endpoit {
>> +	CTRL_EP = 0,
>> +	INTR_EP = 1,
>> +	BULK_EP = 2,
>> +	ISOC_EP = 3
>> +};
>> +
>> +struct patch_info {
>> +	uint16_t	prod_id;
>> +	uint16_t	lmp_sub;
>> +	char		*patch_name;
>> +	char		*config_name;
>> +	uint8_t		*fw_cache;
>> +	int		fw_len;
>> +};
>> +
>> +struct xchange_data {
>> +	struct dev_data	*dev_entry;
>> +	int pipe_in, pipe_out;
>> +	uint8_t send_pkt[PKT_LEN];
>> +	uint8_t rcv_pkt[PKT_LEN];
>
> Violations of the DMA coherency rules, fails on non-x86

I see that the buffers are not 64-bit aligned. What other conditions are necessary?

>
>> +	struct hci_command_hdr *cmd_hdr;
>> +	struct hci_event_hdr *evt_hdr;
>> +	struct hci_ev_cmd_complete *cmd_cmp;
>> +	uint8_t *req_para, *rsp_para;
>> +	uint8_t *fw_data;
>> +	int pkt_len, fw_len;
>> +};
>> +
>> +struct dev_data {
>> +	struct list_head	list_node;
>> +	struct usb_interface	*intf;
>> +	struct usb_device	*udev;
>> +	struct notifier_block	pm_notifier;
>> +	struct patch_info	*patch_entry;
>> +	struct xchange_data	xdata;
>> +	struct completion firmware_loading_complete;
>> +	const struct firmware *fw;
>> +};
>> +
>> +struct download_cp {
>> +	uint8_t index;
>> +	uint8_t data[PATCH_SEG_MAX];
>
> DMA coherency
>
>> +} __packed;
>> +
>> +struct download_rp {
>> +	uint8_t status;
>> +	uint8_t index;
>> +} __packed;
>> +
>> +
>> +static struct dev_data *dev_data_find(struct usb_interface *intf);
>> +static struct patch_info *get_patch_entry(struct usb_device *udev);
>> +static int rtkbt_pm_notify(struct notifier_block *notifier, ulong pm_event,
>> +			   void *unused);
>> +static int load_firmware(struct dev_data *dev_entry, uint8_t **buff);
>> +static void init_xdata(struct xchange_data *xdata, struct dev_data *dev_entry);
>> +static int check_fw_version(struct xchange_data *xdata);
>> +static int get_firmware(struct xchange_data *xdata);
>> +static int download_data(struct xchange_data *xdata);
>> +static int send_hci_cmd(struct xchange_data *xdata);
>> +static int rcv_hci_evt(struct xchange_data *xdata);
>> +
>> +
>> +static struct patch_info patch_table[] = {
>> +	{0, 0x1200, "rtl_bt/rtl8723a.bin", "rtk8723_bt_config", NULL, 0}
>> +};
>> +
>> +static LIST_HEAD(dev_data_list);
>> +
>> +
>> +static int patch_add(struct usb_interface *intf)
>> +{
>> +	struct dev_data	*dev_entry;
>> +	struct usb_device *udev;
>> +
>> +	RTKBT_DBG("patch_add");
>> +	dev_entry = dev_data_find(intf);
>> +	if (NULL != dev_entry)
>> +		return -1;
>> +
>> +	udev = interface_to_usbdev(intf);
>> +#if BTUSB_RPM
>> +	RTKBT_DBG("auto suspend is enabled");
>> +	usb_enable_autosuspend(udev);
>> +	pm_runtime_set_autosuspend_delay(&(udev->dev), 2000);
>
> There is no good reason to overwrite the system values.

Noted.

Thanks for the review. As suggested by you and Marcel, a complete rewrite is 
needed. I plan to use the mini-driver approach of Tedd Ho-Jeong An; however, 
your comments will be used when constructing that code.

Larry

^ permalink raw reply

* Re: [PATCH BlueZ 1/8] gdbus: Introduce G_DBUS_METHOD_FLAG_EXPERIMENTAL
From: Luiz Augusto von Dentz @ 2012-12-27  8:42 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZ+Vci+JtKXK1wNfGSuGdC=D7rpAZ7op4UAOXq51c+bnBA@mail.gmail.com>

Hi Marcel,

On Mon, Dec 24, 2012 at 2:12 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> HI Marcel,
>
> On Mon, Dec 24, 2012 at 1:35 AM, Marcel Holtmann <marcel@holtmann.org> wrote:
>> Hi Luiz,
>>
>>> >> This flag can be used to mark methods as experimental, the marked
>>> >> methods with this flag can be enabled by setting the environment variable
>>> >> GDBUS_EXPERIMENTAL=1
>>> >> ---
>>> >>  gdbus/gdbus.h  | 21 ++++++++++++++++++---
>>> >>  gdbus/object.c | 17 +++++++++++++++++
>>> >>  2 files changed, 35 insertions(+), 3 deletions(-)
>>> >>
>>> >> diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
>>> >> index 0e5c012..00fbb1c 100644
>>> >> --- a/gdbus/gdbus.h
>>> >> +++ b/gdbus/gdbus.h
>>> >> @@ -89,9 +89,10 @@ typedef void (* GDBusSecurityFunction) (DBusConnection *connection,
>>> >>                                               GDBusPendingReply pending);
>>> >>
>>> >>  enum GDBusMethodFlags {
>>> >> -     G_DBUS_METHOD_FLAG_DEPRECATED = (1 << 0),
>>> >> -     G_DBUS_METHOD_FLAG_NOREPLY    = (1 << 1),
>>> >> -     G_DBUS_METHOD_FLAG_ASYNC      = (1 << 2),
>>> >> +     G_DBUS_METHOD_FLAG_DEPRECATED   = (1 << 0),
>>> >> +     G_DBUS_METHOD_FLAG_NOREPLY      = (1 << 1),
>>> >> +     G_DBUS_METHOD_FLAG_ASYNC        = (1 << 2),
>>> >> +     G_DBUS_METHOD_FLAG_EXPERIMENTAL = (1 << 3),
>>> >>  };
>>> >>
>>> >>  enum GDBusSignalFlags {
>>> >> @@ -173,6 +174,20 @@ struct GDBusSecurityTable {
>>> >>       .function = _function, \
>>> >>       .flags = G_DBUS_METHOD_FLAG_ASYNC | G_DBUS_METHOD_FLAG_DEPRECATED
>>> >>
>>> >> +#define GDBUS_EXPERIMENTAL_METHOD(_name, _in_args, _out_args, _function) \
>>> >> +     .name = _name, \
>>> >> +     .in_args = _in_args, \
>>> >> +     .out_args = _out_args, \
>>> >> +     .function = _function, \
>>> >> +     .flags = G_DBUS_METHOD_FLAG_EXPERIMENTAL
>>> >> +
>>> >> +#define GDBUS_EXPERIMENTAL_ASYNC_METHOD(_name, _in_args, _out_args, _function) \
>>> >> +     .name = _name, \
>>> >> +     .in_args = _in_args, \
>>> >> +     .out_args = _out_args, \
>>> >> +     .function = _function, \
>>> >> +     .flags = G_DBUS_METHOD_FLAG_ASYNC | G_DBUS_METHOD_FLAG_EXPERIMENTAL
>>> >> +
>>> >>  #define GDBUS_NOREPLY_METHOD(_name, _in_args, _out_args, _function) \
>>> >>       .name = _name, \
>>> >>       .in_args = _in_args, \
>>> >> diff --git a/gdbus/object.c b/gdbus/object.c
>>> >> index 776d35e..30dbbc2 100644
>>> >> --- a/gdbus/object.c
>>> >> +++ b/gdbus/object.c
>>> >> @@ -129,6 +129,14 @@ static void generate_interface_xml(GString *gstr, struct interface_data *iface)
>>> >>                                               G_DBUS_METHOD_FLAG_DEPRECATED;
>>> >>               gboolean noreply = method->flags &
>>> >>                                               G_DBUS_METHOD_FLAG_NOREPLY;
>>> >> +             gboolean experimental = method->flags &
>>> >> +                                     G_DBUS_METHOD_FLAG_EXPERIMENTAL;
>>> >> +
>>> >> +             if (experimental) {
>>> >> +                     const char *env = g_getenv("GDBUS_EXPERIMENTAL");
>>> >> +                     if (g_strcmp0(env, "1") != 0)
>>> >> +                             continue;
>>> >> +             }
>>> >
>>> > actually since this is a library, doing it this way is a bad idea.
>>>
>>> I thought it was a common practice to use environment variables with
>>> libraries to change certain defaults, glib does that with things like
>>> G_SLICE=always-malloc, and it is quite convenient since you can change
>>> easily without recompiling.
>>
>> GLib does this, but we never did this. GAtChat, GDHCP, GWeb etc.
>> provided a function to enable it. The hooking up to environment variable
>> is then the responsibility of the main program.
>
> GObex does have it on environment variables and I can even enable them
> while running make check so if a test fail I can debug like the daemon
> itself.
>
>>> > Lets do something like g_dbus_enable_experimental(DBusConnection)
>>>
>>> But this is not really per connection, anyway doing so you have to
>>> handle this directly on the application code which IMO is not as
>>> convenient.
>>
>> Making this per connection would be pretty convenient if you are
>> connected to more than one bus.
>
> Except that we don't actually change during runtime to be able to use
> the connection and it would probably confuse applications that already
> read the introspection data if we do so.

Now that the release is out I guess we should try to get this changes
in, I would like to make similar changes to disable deprecated in a
similar way using, so we probably have to settle on a way this should
be done. Since we diverge in the way to use environment variable I was
thinking in an alternative, what about using binary parameter e.g.
-E/--experimental and -D/--deprecated?

--
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH 1/2 v1] Bluetooth: Fix to update EIR for uuid16
From: Syam Sidhardhan @ 2012-12-27 13:36 UTC (permalink / raw)
  To: linux-bluetooth

If we register a uuid other than uuid16, especially custom 128 bit uuid
then EIR is not updating properly.

After registering a 16 bit uuid. ex: "sdptool add SP", we can see the
uuid16 in the EIR as shown below.
< 0000: 01 52 0c f1 00 08 09 52  65 64 77 6f 6f 64 15 03  .R.....Redwood..
  0010: 01 11 32 11 2f 11 06 11  05 11 0a 11 0e 11 0c 11  ..2./...........
  0020: 1f 11 12 11 00 00 00 00  00 00 00 00 00 00 00 00  ................
  0030: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  0040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  0050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  0060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  0070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  0080: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  0090: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  00a0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  00b0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  00c0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  00d0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  00e0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  00f0: 00 00 00 00 00                                    .....
> 0000: 04 0e 04 01 52 0c 00                              ....R..

But after register a user defined 128 bit uuid, EIR is not
updated.

< 0000: 01 52 0c f1 00 08 09 52  65 64 77 6f 6f 64 00 00  .R.....Redwood..
  0010: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  0020: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  0030: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  0040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  0050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  0060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  0070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  0080: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  0090: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  00a0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  00b0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  00c0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  00d0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  00e0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
  00f0: 00 00 00 00 00                                    .....
> 0000: 04 0e 04 01 52 0c 00                              ....R..

With this fix, we can see the EIR is updated properly.

Signed-off-by: Syam Sidhardhan <s.syam@samsung.com>
---
v1 -> Incorporated the comment mentioned by Johan.

 net/bluetooth/mgmt.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index f559b96..ab25edf 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -515,7 +515,7 @@ static void create_eir(struct hci_dev *hdev, u8 *data)
 
 		uuid16 = get_uuid16(uuid->uuid);
 		if (uuid16 == 0)
-			return;
+			continue;
 
 		if (uuid16 < 0x1100)
 			continue;
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 2/2] Bluetooth: Update management interface revision
From: Syam Sidhardhan @ 2012-12-27 13:36 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1356615418-4351-1-git-send-email-s.syam@samsung.com>

This enable us to introduce a check in user space to know
whether it's safe to pass non-16bit UUID's to kernel or not.
Currently the kernel support only 16bit UUID's in the EIR.

Signed-off-by: Syam Sidhardhan <s.syam@samsung.com>
---
 net/bluetooth/mgmt.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index ab25edf..ba7c38a 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -35,7 +35,7 @@
 bool enable_hs;
 
 #define MGMT_VERSION	1
-#define MGMT_REVISION	2
+#define MGMT_REVISION	3
 
 static const u16 mgmt_commands[] = {
 	MGMT_OP_READ_INDEX_LIST,
-- 
1.7.9.5


^ permalink raw reply related

* Re: [PATCH 2/2] Bluetooth: Update management interface revision
From: Marcel Holtmann @ 2012-12-27 17:45 UTC (permalink / raw)
  To: Syam Sidhardhan; +Cc: linux-bluetooth
In-Reply-To: <1356615418-4351-2-git-send-email-s.syam@samsung.com>

Hi Syam,

> This enable us to introduce a check in user space to know
> whether it's safe to pass non-16bit UUID's to kernel or not.
> Currently the kernel support only 16bit UUID's in the EIR.
> 
> Signed-off-by: Syam Sidhardhan <s.syam@samsung.com>
> ---
>  net/bluetooth/mgmt.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

NAK. As I said before, I want the kernel to support 32-bit and 128-bit
UUIDs. There is no point in doing a minimal fix. I want to see this
fixed properly.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH BlueZ 1/8] gdbus: Introduce G_DBUS_METHOD_FLAG_EXPERIMENTAL
From: Marcel Holtmann @ 2012-12-27 17:49 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZL8ZK49=3ToDktkZ13Sx8UxMTrTRDGxw6UwPqDwusj+RA@mail.gmail.com>

Hi Luiz,

> >>> >> This flag can be used to mark methods as experimental, the marked
> >>> >> methods with this flag can be enabled by setting the environment variable
> >>> >> GDBUS_EXPERIMENTAL=1
> >>> >> ---
> >>> >>  gdbus/gdbus.h  | 21 ++++++++++++++++++---
> >>> >>  gdbus/object.c | 17 +++++++++++++++++
> >>> >>  2 files changed, 35 insertions(+), 3 deletions(-)
> >>> >>
> >>> >> diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
> >>> >> index 0e5c012..00fbb1c 100644
> >>> >> --- a/gdbus/gdbus.h
> >>> >> +++ b/gdbus/gdbus.h
> >>> >> @@ -89,9 +89,10 @@ typedef void (* GDBusSecurityFunction) (DBusConnection *connection,
> >>> >>                                               GDBusPendingReply pending);
> >>> >>
> >>> >>  enum GDBusMethodFlags {
> >>> >> -     G_DBUS_METHOD_FLAG_DEPRECATED = (1 << 0),
> >>> >> -     G_DBUS_METHOD_FLAG_NOREPLY    = (1 << 1),
> >>> >> -     G_DBUS_METHOD_FLAG_ASYNC      = (1 << 2),
> >>> >> +     G_DBUS_METHOD_FLAG_DEPRECATED   = (1 << 0),
> >>> >> +     G_DBUS_METHOD_FLAG_NOREPLY      = (1 << 1),
> >>> >> +     G_DBUS_METHOD_FLAG_ASYNC        = (1 << 2),
> >>> >> +     G_DBUS_METHOD_FLAG_EXPERIMENTAL = (1 << 3),
> >>> >>  };
> >>> >>
> >>> >>  enum GDBusSignalFlags {
> >>> >> @@ -173,6 +174,20 @@ struct GDBusSecurityTable {
> >>> >>       .function = _function, \
> >>> >>       .flags = G_DBUS_METHOD_FLAG_ASYNC | G_DBUS_METHOD_FLAG_DEPRECATED
> >>> >>
> >>> >> +#define GDBUS_EXPERIMENTAL_METHOD(_name, _in_args, _out_args, _function) \
> >>> >> +     .name = _name, \
> >>> >> +     .in_args = _in_args, \
> >>> >> +     .out_args = _out_args, \
> >>> >> +     .function = _function, \
> >>> >> +     .flags = G_DBUS_METHOD_FLAG_EXPERIMENTAL
> >>> >> +
> >>> >> +#define GDBUS_EXPERIMENTAL_ASYNC_METHOD(_name, _in_args, _out_args, _function) \
> >>> >> +     .name = _name, \
> >>> >> +     .in_args = _in_args, \
> >>> >> +     .out_args = _out_args, \
> >>> >> +     .function = _function, \
> >>> >> +     .flags = G_DBUS_METHOD_FLAG_ASYNC | G_DBUS_METHOD_FLAG_EXPERIMENTAL
> >>> >> +
> >>> >>  #define GDBUS_NOREPLY_METHOD(_name, _in_args, _out_args, _function) \
> >>> >>       .name = _name, \
> >>> >>       .in_args = _in_args, \
> >>> >> diff --git a/gdbus/object.c b/gdbus/object.c
> >>> >> index 776d35e..30dbbc2 100644
> >>> >> --- a/gdbus/object.c
> >>> >> +++ b/gdbus/object.c
> >>> >> @@ -129,6 +129,14 @@ static void generate_interface_xml(GString *gstr, struct interface_data *iface)
> >>> >>                                               G_DBUS_METHOD_FLAG_DEPRECATED;
> >>> >>               gboolean noreply = method->flags &
> >>> >>                                               G_DBUS_METHOD_FLAG_NOREPLY;
> >>> >> +             gboolean experimental = method->flags &
> >>> >> +                                     G_DBUS_METHOD_FLAG_EXPERIMENTAL;
> >>> >> +
> >>> >> +             if (experimental) {
> >>> >> +                     const char *env = g_getenv("GDBUS_EXPERIMENTAL");
> >>> >> +                     if (g_strcmp0(env, "1") != 0)
> >>> >> +                             continue;
> >>> >> +             }
> >>> >
> >>> > actually since this is a library, doing it this way is a bad idea.
> >>>
> >>> I thought it was a common practice to use environment variables with
> >>> libraries to change certain defaults, glib does that with things like
> >>> G_SLICE=always-malloc, and it is quite convenient since you can change
> >>> easily without recompiling.
> >>
> >> GLib does this, but we never did this. GAtChat, GDHCP, GWeb etc.
> >> provided a function to enable it. The hooking up to environment variable
> >> is then the responsibility of the main program.
> >
> > GObex does have it on environment variables and I can even enable them
> > while running make check so if a test fail I can debug like the daemon
> > itself.
> >
> >>> > Lets do something like g_dbus_enable_experimental(DBusConnection)
> >>>
> >>> But this is not really per connection, anyway doing so you have to
> >>> handle this directly on the application code which IMO is not as
> >>> convenient.
> >>
> >> Making this per connection would be pretty convenient if you are
> >> connected to more than one bus.
> >
> > Except that we don't actually change during runtime to be able to use
> > the connection and it would probably confuse applications that already
> > read the introspection data if we do so.
> 
> Now that the release is out I guess we should try to get this changes
> in, I would like to make similar changes to disable deprecated in a
> similar way using, so we probably have to settle on a way this should
> be done. Since we diverge in the way to use environment variable I was
> thinking in an alternative, what about using binary parameter e.g.
> -E/--experimental and -D/--deprecated?

I dislike the library to take environment variables to change behavior.
While gobex might do this, none of the other helpers do it that way. The
main program checks for the environment variable and then sets it. So we
should do it the same way.

That said, yes, having a command line switch for the daemon seems
sensible to enable experimental interfaces or disable deprecated ones.

Regards

Marcel



^ permalink raw reply

* How to pair device from CLI?
From: Kamil Jońca @ 2012-12-28  0:23 UTC (permalink / raw)
  To: linux-bluetooth


I don't know if this is proper list, but I cannot find any (active) bluez users
list. 

I tried to pair my phone:

--8<---------------cut here---------------start------------->8---
$hcitool scan                         
Scanning ...
        D4:E8:B2:AA:15:FA       theta

$bluez-simple-agent hci0 D4:E8:B2:AA:15:FA
RequestPasskey (/org/bluez/3086/hci0/dev_D4_E8_B2_AA_15_FA)
Enter passkey: 0000
Creating device failed: org.bluez.Error.AuthenticationFailed: Authentication Failed
--8<---------------cut here---------------end--------------->8---

What do I should check? (s)trace?

Distribution is pretty fresh debian sid.

-- 
http://blogdebart.pl/2012/06/24/hiena/
  We're overpaying him, but he's worth it. -Samuel Goldwyn

^ permalink raw reply

* Re: How to pair device from CLI?
From: Johan Hedberg @ 2012-12-28  8:08 UTC (permalink / raw)
  To: Kamil Jońca; +Cc: linux-bluetooth
In-Reply-To: <871uebt47d.fsf@alfa.kjonca>

Hi Kamil,

On Fri, Dec 28, 2012, Kamil Jońca wrote:
> I don't know if this is proper list, but I cannot find any (active)
> bluez users list. 
> 
> I tried to pair my phone:
> 
> --8<---------------cut here---------------start------------->8---
> $hcitool scan                         
> Scanning ...
>         D4:E8:B2:AA:15:FA       theta
> 
> $bluez-simple-agent hci0 D4:E8:B2:AA:15:FA
> RequestPasskey (/org/bluez/3086/hci0/dev_D4_E8_B2_AA_15_FA)
> Enter passkey: 0000
> Creating device failed: org.bluez.Error.AuthenticationFailed: Authentication Failed
> --8<---------------cut here---------------end--------------->8---

It's quite odd that you should get RequestPasskey. That's something that
should only happen if you're pretending to be a keyboard in which case
you should enter the passkey displayed on the remote device (your phone
in this case).

> What do I should check? (s)trace?
> 
> Distribution is pretty fresh debian sid.

The most useful too would be hcidump (bluez-hcidump package). The output
of hcidump -X for the full pairing process would be interesting.

Johan


^ permalink raw reply

* [PATCH BlueZ 00/11] Add experimental command line switch option
From: Luiz Augusto von Dentz @ 2012-12-28 12:50 UTC (permalink / raw)
  To: linux-bluetooth

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

These set of patches introduces g_dbus_set_flags along with experimental flags,
g_dbus_set_flags is not per connection as originally suggested to avoid using
dbus_connection_allocate_data_slot which requires calling
dbus_connection_free_data_slot once done but currently we don't keep any data
associated with connections, besides the flags comes from command line options
which would end up setting the same flags for every connection anyway.

In addition to experimental it also add support to enable deprecated via compat
swith option, this makes any API marked as deprecated to be disabled if compat
is not set. This is on purpose to expose applications using deprecated APIs.

Luiz Augusto von Dentz (11):
  gdbus: Introduce G_DBUS_METHOD_FLAG_EXPERIMENTAL
  gdbus: Introduce G_DBUS_SIGNAL_FLAG_EXPERIMENTAL
  gdbus: Introduce G_DBUS_PROPERTY_FLAG_EXPERIMENTAL
  gdbus: Check if the interface being registered is valid
  gdbus: Call check_signals when sending signals with
    g_dbus_send_message
  gdbus: Introduce G_DBUS_FLAG_ENABLE_DEPRECATED
  core: Add command line switch for enabling experimental interfaces
  core: Reuse --compat/-C switch for enabling deprecated interfaces
  media: Enable RegisterPlayer and UnregisterPlayer methods as
    experimental
  player: Enable MediaPlayer1 interface as experimental
  AVRCP: Fix not checking for media_player_controller_create

 gdbus/gdbus.h           |  39 ++++++++++--
 gdbus/object.c          | 153 ++++++++++++++++++++++++++++++++++++++++++++----
 profiles/audio/avrcp.c  |   7 ++-
 profiles/audio/media.c  |  10 +---
 profiles/audio/player.c |  28 +++++----
 src/main.c              |  13 +++-
 6 files changed, 211 insertions(+), 39 deletions(-)

-- 
1.8.0.1


^ permalink raw reply

* [PATCH BlueZ 01/11] gdbus: Introduce G_DBUS_METHOD_FLAG_EXPERIMENTAL
From: Luiz Augusto von Dentz @ 2012-12-28 12:50 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1356699069-5469-1-git-send-email-luiz.dentz@gmail.com>

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

This flag can be used to mark methods as experimental, marked
methods are disable by default and can be enabled by setting
G_DBUS_FLAG_ENABLE_EXPERIMENTAL using g_dbus_set_flags.
---
 gdbus/gdbus.h  | 27 ++++++++++++++++++++++++---
 gdbus/object.c | 21 +++++++++++++++++++++
 2 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index 0e5c012..01ff9d4 100644
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -88,10 +88,15 @@ typedef void (* GDBusSecurityFunction) (DBusConnection *connection,
 						gboolean interaction,
 						GDBusPendingReply pending);
 
+enum GDBusFlags {
+	G_DBUS_FLAG_ENABLE_EXPERIMENTAL = (1 << 0),
+};
+
 enum GDBusMethodFlags {
-	G_DBUS_METHOD_FLAG_DEPRECATED = (1 << 0),
-	G_DBUS_METHOD_FLAG_NOREPLY    = (1 << 1),
-	G_DBUS_METHOD_FLAG_ASYNC      = (1 << 2),
+	G_DBUS_METHOD_FLAG_DEPRECATED   = (1 << 0),
+	G_DBUS_METHOD_FLAG_NOREPLY      = (1 << 1),
+	G_DBUS_METHOD_FLAG_ASYNC        = (1 << 2),
+	G_DBUS_METHOD_FLAG_EXPERIMENTAL = (1 << 3),
 };
 
 enum GDBusSignalFlags {
@@ -173,6 +178,20 @@ struct GDBusSecurityTable {
 	.function = _function, \
 	.flags = G_DBUS_METHOD_FLAG_ASYNC | G_DBUS_METHOD_FLAG_DEPRECATED
 
+#define GDBUS_EXPERIMENTAL_METHOD(_name, _in_args, _out_args, _function) \
+	.name = _name, \
+	.in_args = _in_args, \
+	.out_args = _out_args, \
+	.function = _function, \
+	.flags = G_DBUS_METHOD_FLAG_EXPERIMENTAL
+
+#define GDBUS_EXPERIMENTAL_ASYNC_METHOD(_name, _in_args, _out_args, _function) \
+	.name = _name, \
+	.in_args = _in_args, \
+	.out_args = _out_args, \
+	.function = _function, \
+	.flags = G_DBUS_METHOD_FLAG_ASYNC | G_DBUS_METHOD_FLAG_EXPERIMENTAL
+
 #define GDBUS_NOREPLY_METHOD(_name, _in_args, _out_args, _function) \
 	.name = _name, \
 	.in_args = _in_args, \
@@ -189,6 +208,8 @@ struct GDBusSecurityTable {
 	.args = _args, \
 	.flags = G_DBUS_SIGNAL_FLAG_DEPRECATED
 
+void g_dbus_set_flags(int flags);
+
 gboolean g_dbus_register_interface(DBusConnection *connection,
 					const char *path, const char *name,
 					const GDBusMethodTable *methods,
diff --git a/gdbus/object.c b/gdbus/object.c
index 776d35e..89e2a75 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -84,6 +84,7 @@ struct property_data {
 	DBusMessage *message;
 };
 
+static int global_flags = 0;
 static struct generic_data *root;
 
 static gboolean process_changes(gpointer user_data);
@@ -129,6 +130,12 @@ static void generate_interface_xml(GString *gstr, struct interface_data *iface)
 						G_DBUS_METHOD_FLAG_DEPRECATED;
 		gboolean noreply = method->flags &
 						G_DBUS_METHOD_FLAG_NOREPLY;
+		gboolean experimental = method->flags &
+					G_DBUS_METHOD_FLAG_EXPERIMENTAL;
+
+		if (!(global_flags & G_DBUS_FLAG_ENABLE_EXPERIMENTAL) &&
+							experimental)
+			continue;
 
 		if (!deprecated && !noreply &&
 				!(method->in_args && method->in_args->name) &&
@@ -1022,10 +1029,19 @@ static DBusHandlerResult generic_message(DBusConnection *connection,
 
 	for (method = iface->methods; method &&
 			method->name && method->function; method++) {
+		gboolean experimental = method->flags &
+					G_DBUS_METHOD_FLAG_EXPERIMENTAL;
+
 		if (dbus_message_is_method_call(message, iface->name,
 							method->name) == FALSE)
 			continue;
 
+		if (experimental) {
+			const char *env = g_getenv("GDBUS_EXPERIMENTAL");
+			if (g_strcmp0(env, "1") != 0)
+				return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+		}
+
 		if (g_dbus_args_have_signature(method->in_args,
 							message) == FALSE)
 			continue;
@@ -1689,3 +1705,8 @@ gboolean g_dbus_detach_object_manager(DBusConnection *connection)
 
 	return TRUE;
 }
+
+void g_dbus_set_flags(int flags)
+{
+	global_flags = flags;
+}
-- 
1.8.0.1


^ permalink raw reply related

* [PATCH BlueZ 02/11] gdbus: Introduce G_DBUS_SIGNAL_FLAG_EXPERIMENTAL
From: Luiz Augusto von Dentz @ 2012-12-28 12:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1356699069-5469-1-git-send-email-luiz.dentz@gmail.com>

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

This flag can be used to mark signals as experimental, marked
signals are disabled by default and can be enabled by setting
G_DBUS_FLAG_ENABLE_EXPERIMENTAL using g_dbus_set_flags.
---
 gdbus/gdbus.h  |  8 +++++++-
 gdbus/object.c | 19 ++++++++++++++++---
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index 01ff9d4..edc1f53 100644
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -100,7 +100,8 @@ enum GDBusMethodFlags {
 };
 
 enum GDBusSignalFlags {
-	G_DBUS_SIGNAL_FLAG_DEPRECATED = (1 << 0),
+	G_DBUS_SIGNAL_FLAG_DEPRECATED   = (1 << 0),
+	G_DBUS_SIGNAL_FLAG_EXPERIMENTAL = (1 << 1),
 };
 
 enum GDBusPropertyFlags {
@@ -208,6 +209,11 @@ struct GDBusSecurityTable {
 	.args = _args, \
 	.flags = G_DBUS_SIGNAL_FLAG_DEPRECATED
 
+#define GDBUS_EXPERIMENTAL_SIGNAL(_name, _args) \
+	.name = _name, \
+	.args = _args, \
+	.flags = G_DBUS_SIGNAL_FLAG_EXPERIMENTAL
+
 void g_dbus_set_flags(int flags);
 
 gboolean g_dbus_register_interface(DBusConnection *connection,
diff --git a/gdbus/object.c b/gdbus/object.c
index 89e2a75..13a183f 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -164,6 +164,12 @@ static void generate_interface_xml(GString *gstr, struct interface_data *iface)
 	for (signal = iface->signals; signal && signal->name; signal++) {
 		gboolean deprecated = signal->flags &
 						G_DBUS_SIGNAL_FLAG_DEPRECATED;
+		gboolean experimental = signal->flags &
+					G_DBUS_SIGNAL_FLAG_EXPERIMENTAL;
+
+		if (!(global_flags & G_DBUS_FLAG_ENABLE_EXPERIMENTAL) &&
+							experimental)
+			continue;
 
 		if (!deprecated && !(signal->args && signal->args->name))
 			g_string_append_printf(gstr,
@@ -1266,10 +1272,17 @@ static gboolean check_signal(DBusConnection *conn, const char *path,
 	}
 
 	for (signal = iface->signals; signal && signal->name; signal++) {
-		if (!strcmp(signal->name, name)) {
-			*args = signal->args;
-			return TRUE;
+		if (strcmp(signal->name, name) != 0)
+			continue;
+
+		if (signal->flags & G_DBUS_SIGNAL_FLAG_EXPERIMENTAL) {
+			const char *env = g_getenv("GDBUS_EXPERIMENTAL");
+			if (g_strcmp0(env, "1") != 0)
+				break;
 		}
+
+		*args = signal->args;
+		return TRUE;
 	}
 
 	error("No signal named %s on interface %s", name, interface);
-- 
1.8.0.1


^ permalink raw reply related

* [PATCH BlueZ 03/11] gdbus: Introduce G_DBUS_PROPERTY_FLAG_EXPERIMENTAL
From: Luiz Augusto von Dentz @ 2012-12-28 12:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1356699069-5469-1-git-send-email-luiz.dentz@gmail.com>

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

This flag can be used to mark properties as experimental, marked
properties are disabled by default and can be enabled by setting
G_DBUS_FLAG_ENABLE_EXPERIMENTAL using g_dbus_set_flags.
---
 gdbus/gdbus.h  |  3 ++-
 gdbus/object.c | 48 +++++++++++++++++++++++++++++++-----------------
 2 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index edc1f53..87fd185 100644
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -105,7 +105,8 @@ enum GDBusSignalFlags {
 };
 
 enum GDBusPropertyFlags {
-	G_DBUS_PROPERTY_FLAG_DEPRECATED = (1 << 0),
+	G_DBUS_PROPERTY_FLAG_DEPRECATED   = (1 << 0),
+	G_DBUS_PROPERTY_FLAG_EXPERIMENTAL = (1 << 1),
 };
 
 enum GDBusSecurityFlags {
diff --git a/gdbus/object.c b/gdbus/object.c
index 13a183f..86d1c53 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -119,6 +119,14 @@ static void print_arguments(GString *gstr, const GDBusArgInfo *args,
 #define G_DBUS_ANNOTATE_NOREPLY(prefix_) \
 	G_DBUS_ANNOTATE(prefix_, "Method.NoReply", "true")
 
+static gboolean check_experimental(int flags, int flag)
+{
+	if (!(flags & flag))
+		return FALSE;
+
+	return !(global_flags & G_DBUS_FLAG_ENABLE_EXPERIMENTAL);
+}
+
 static void generate_interface_xml(GString *gstr, struct interface_data *iface)
 {
 	const GDBusMethodTable *method;
@@ -130,11 +138,9 @@ static void generate_interface_xml(GString *gstr, struct interface_data *iface)
 						G_DBUS_METHOD_FLAG_DEPRECATED;
 		gboolean noreply = method->flags &
 						G_DBUS_METHOD_FLAG_NOREPLY;
-		gboolean experimental = method->flags &
-					G_DBUS_METHOD_FLAG_EXPERIMENTAL;
 
-		if (!(global_flags & G_DBUS_FLAG_ENABLE_EXPERIMENTAL) &&
-							experimental)
+		if (check_experimental(method->flags,
+					G_DBUS_METHOD_FLAG_EXPERIMENTAL))
 			continue;
 
 		if (!deprecated && !noreply &&
@@ -164,11 +170,9 @@ static void generate_interface_xml(GString *gstr, struct interface_data *iface)
 	for (signal = iface->signals; signal && signal->name; signal++) {
 		gboolean deprecated = signal->flags &
 						G_DBUS_SIGNAL_FLAG_DEPRECATED;
-		gboolean experimental = signal->flags &
-					G_DBUS_SIGNAL_FLAG_EXPERIMENTAL;
 
-		if (!(global_flags & G_DBUS_FLAG_ENABLE_EXPERIMENTAL) &&
-							experimental)
+		if (check_experimental(signal->flags,
+					G_DBUS_SIGNAL_FLAG_EXPERIMENTAL))
 			continue;
 
 		if (!deprecated && !(signal->args && signal->args->name))
@@ -194,6 +198,10 @@ static void generate_interface_xml(GString *gstr, struct interface_data *iface)
 		gboolean deprecated = property->flags &
 					G_DBUS_PROPERTY_FLAG_DEPRECATED;
 
+		if (check_experimental(property->flags,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL))
+			continue;
+
 		g_string_append_printf(gstr, "\t\t<property name=\"%s\""
 					" type=\"%s\" access=\"%s%s\"",
 					property->name,	property->type,
@@ -555,6 +563,10 @@ static void append_properties(struct interface_data *data,
 				DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
 
 	for (p = data->properties; p && p->name; p++) {
+		if (check_experimental(p->flags,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL))
+			continue;
+
 		if (p->get == NULL)
 			continue;
 
@@ -756,8 +768,14 @@ static inline const GDBusPropertyTable *find_property(const GDBusPropertyTable *
 	const GDBusPropertyTable *p;
 
 	for (p = properties; p && p->name; p++) {
-		if (strcmp(name, p->name) == 0)
-			return p;
+		if (strcmp(name, p->name) != 0)
+			continue;
+
+		if (check_experimental(p->flags,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL))
+			break;
+
+		return p;
 	}
 
 	return NULL;
@@ -1035,18 +1053,14 @@ static DBusHandlerResult generic_message(DBusConnection *connection,
 
 	for (method = iface->methods; method &&
 			method->name && method->function; method++) {
-		gboolean experimental = method->flags &
-					G_DBUS_METHOD_FLAG_EXPERIMENTAL;
 
 		if (dbus_message_is_method_call(message, iface->name,
 							method->name) == FALSE)
 			continue;
 
-		if (experimental) {
-			const char *env = g_getenv("GDBUS_EXPERIMENTAL");
-			if (g_strcmp0(env, "1") != 0)
-				return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-		}
+		if (check_experimental(method->flags,
+					G_DBUS_METHOD_FLAG_EXPERIMENTAL))
+			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
 		if (g_dbus_args_have_signature(method->in_args,
 							message) == FALSE)
-- 
1.8.0.1


^ permalink raw reply related

* [PATCH BlueZ 04/11] gdbus: Check if the interface being registered is valid
From: Luiz Augusto von Dentz @ 2012-12-28 12:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1356699069-5469-1-git-send-email-luiz.dentz@gmail.com>

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

This prevent registering interfaces that are empty or have all members
marked as experiemental.
---
 gdbus/object.c | 42 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/gdbus/object.c b/gdbus/object.c
index 86d1c53..c9cf595 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -1174,7 +1174,7 @@ static const GDBusSignalTable manager_signals[] = {
 	{ }
 };
 
-static void add_interface(struct generic_data *data,
+static gboolean add_interface(struct generic_data *data,
 				const char *name,
 				const GDBusMethodTable *methods,
 				const GDBusSignalTable *signals,
@@ -1183,7 +1183,32 @@ static void add_interface(struct generic_data *data,
 				GDBusDestroyFunction destroy)
 {
 	struct interface_data *iface;
+	const GDBusMethodTable *method;
+	const GDBusSignalTable *signal;
+	const GDBusPropertyTable *property;
+
+	for (method = methods; method && method->name; method++) {
+		if (!check_experimental(method->flags,
+					G_DBUS_METHOD_FLAG_EXPERIMENTAL))
+			goto done;
+	}
+
+	for (signal = signals; signal && signal->name; signal++) {
+		if (!check_experimental(signal->flags,
+					G_DBUS_SIGNAL_FLAG_EXPERIMENTAL))
+			goto done;
+	}
+
+	for (property = properties; property && property->name; property++) {
+		if (!check_experimental(property->flags,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL))
+			goto done;
+	}
 
+	/* Nothing to register */
+	return FALSE;
+
+done:
 	iface = g_new0(struct interface_data, 1);
 	iface->name = g_strdup(name);
 	iface->methods = methods;
@@ -1194,13 +1219,15 @@ static void add_interface(struct generic_data *data,
 
 	data->interfaces = g_slist_append(data->interfaces, iface);
 	if (data->parent == NULL)
-		return;
+		return TRUE;
 
 	data->added = g_slist_append(data->added, iface);
 	if (data->process_id > 0)
-		return;
+		return TRUE;
 
 	data->process_id = g_idle_add(process_changes, data);
+
+	return TRUE;
 }
 
 static struct generic_data *object_path_ref(DBusConnection *connection,
@@ -1361,15 +1388,18 @@ gboolean g_dbus_register_interface(DBusConnection *connection,
 		return FALSE;
 	}
 
+	if (!add_interface(data, name, methods, signals, properties, user_data,
+								destroy)) {
+		object_path_unref(connection, path);
+		return FALSE;
+	}
+
 	if (properties != NULL && !find_interface(data->interfaces,
 						DBUS_INTERFACE_PROPERTIES))
 		add_interface(data, DBUS_INTERFACE_PROPERTIES,
 				properties_methods, properties_signals, NULL,
 				data, NULL);
 
-	add_interface(data, name, methods, signals, properties, user_data,
-								destroy);
-
 	g_free(data->introspect);
 	data->introspect = NULL;
 
-- 
1.8.0.1


^ permalink raw reply related

* [PATCH BlueZ 05/11] gdbus: Call check_signals when sending signals with g_dbus_send_message
From: Luiz Augusto von Dentz @ 2012-12-28 12:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1356699069-5469-1-git-send-email-luiz.dentz@gmail.com>

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

If message passed to g_dbus_send_message is a signal verify if it is a
valid and there really exists an interface with respective signal name.
---
 gdbus/object.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/gdbus/object.c b/gdbus/object.c
index c9cf595..d5eb267 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -1511,6 +1511,15 @@ gboolean g_dbus_send_message(DBusConnection *connection, DBusMessage *message)
 
 	if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
 		dbus_message_set_no_reply(message, TRUE);
+	else if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL) {
+		const char *path = dbus_message_get_path(message);
+		const char *interface = dbus_message_get_interface(message);
+		const char *name = dbus_message_get_member(message);
+		const GDBusArgInfo *args;
+
+		if (!check_signal(connection, path, interface, name, &args))
+			return FALSE;
+	}
 
 	result = dbus_connection_send(connection, message, NULL);
 
-- 
1.8.0.1


^ permalink raw reply related

* [PATCH BlueZ 06/11] gdbus: Introduce G_DBUS_FLAG_ENABLE_DEPRECATED
From: Luiz Augusto von Dentz @ 2012-12-28 12:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1356699069-5469-1-git-send-email-luiz.dentz@gmail.com>

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

This flag can be set using g_dbus_set_flags to enable deprecated
interfaces, default is unset.
---
 gdbus/gdbus.h  |  3 ++-
 gdbus/object.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index 87fd185..c22c472 100644
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -89,7 +89,8 @@ typedef void (* GDBusSecurityFunction) (DBusConnection *connection,
 						GDBusPendingReply pending);
 
 enum GDBusFlags {
-	G_DBUS_FLAG_ENABLE_EXPERIMENTAL = (1 << 0),
+	G_DBUS_FLAG_ENABLE_DEPRECATED   = (1 << 0),
+	G_DBUS_FLAG_ENABLE_EXPERIMENTAL = (1 << 1),
 };
 
 enum GDBusMethodFlags {
diff --git a/gdbus/object.c b/gdbus/object.c
index d5eb267..364cc60 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -127,6 +127,14 @@ static gboolean check_experimental(int flags, int flag)
 	return !(global_flags & G_DBUS_FLAG_ENABLE_EXPERIMENTAL);
 }
 
+static gboolean check_deprecated(int flags, int flag)
+{
+	if (!(flags & flag))
+		return FALSE;
+
+	return !(global_flags & G_DBUS_FLAG_ENABLE_DEPRECATED);
+}
+
 static void generate_interface_xml(GString *gstr, struct interface_data *iface)
 {
 	const GDBusMethodTable *method;
@@ -143,6 +151,10 @@ static void generate_interface_xml(GString *gstr, struct interface_data *iface)
 					G_DBUS_METHOD_FLAG_EXPERIMENTAL))
 			continue;
 
+		if (check_deprecated(method->flags,
+					G_DBUS_METHOD_FLAG_DEPRECATED))
+			continue;
+
 		if (!deprecated && !noreply &&
 				!(method->in_args && method->in_args->name) &&
 				!(method->out_args && method->out_args->name))
@@ -175,6 +187,10 @@ static void generate_interface_xml(GString *gstr, struct interface_data *iface)
 					G_DBUS_SIGNAL_FLAG_EXPERIMENTAL))
 			continue;
 
+		if (check_deprecated(signal->flags,
+					G_DBUS_SIGNAL_FLAG_DEPRECATED))
+			continue;
+
 		if (!deprecated && !(signal->args && signal->args->name))
 			g_string_append_printf(gstr,
 						"\t\t<signal name=\"%s\"/>\n",
@@ -202,6 +218,10 @@ static void generate_interface_xml(GString *gstr, struct interface_data *iface)
 					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL))
 			continue;
 
+		if (check_deprecated(property->flags,
+					G_DBUS_PROPERTY_FLAG_DEPRECATED))
+			continue;
+
 		g_string_append_printf(gstr, "\t\t<property name=\"%s\""
 					" type=\"%s\" access=\"%s%s\"",
 					property->name,	property->type,
@@ -567,6 +587,10 @@ static void append_properties(struct interface_data *data,
 					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL))
 			continue;
 
+		if (check_deprecated(p->flags,
+					G_DBUS_PROPERTY_FLAG_DEPRECATED))
+			continue;
+
 		if (p->get == NULL)
 			continue;
 
@@ -775,6 +799,10 @@ static inline const GDBusPropertyTable *find_property(const GDBusPropertyTable *
 					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL))
 			break;
 
+		if (check_deprecated(p->flags,
+					G_DBUS_PROPERTY_FLAG_DEPRECATED))
+			break;
+
 		return p;
 	}
 
@@ -1062,6 +1090,10 @@ static DBusHandlerResult generic_message(DBusConnection *connection,
 					G_DBUS_METHOD_FLAG_EXPERIMENTAL))
 			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
+		if (check_deprecated(method->flags,
+					G_DBUS_METHOD_FLAG_DEPRECATED))
+			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
 		if (g_dbus_args_have_signature(method->in_args,
 							message) == FALSE)
 			continue;
@@ -1191,18 +1223,30 @@ static gboolean add_interface(struct generic_data *data,
 		if (!check_experimental(method->flags,
 					G_DBUS_METHOD_FLAG_EXPERIMENTAL))
 			goto done;
+
+		if (!check_deprecated(method->flags,
+					G_DBUS_METHOD_FLAG_DEPRECATED))
+			goto done;
 	}
 
 	for (signal = signals; signal && signal->name; signal++) {
 		if (!check_experimental(signal->flags,
 					G_DBUS_SIGNAL_FLAG_EXPERIMENTAL))
 			goto done;
+
+		if (!check_deprecated(signal->flags,
+					G_DBUS_SIGNAL_FLAG_DEPRECATED))
+			goto done;
 	}
 
 	for (property = properties; property && property->name; property++) {
 		if (!check_experimental(property->flags,
 					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL))
 			goto done;
+
+		if (!check_deprecated(property->flags,
+					G_DBUS_PROPERTY_FLAG_DEPRECATED))
+			goto done;
 	}
 
 	/* Nothing to register */
-- 
1.8.0.1


^ permalink raw reply related

* [PATCH BlueZ 07/11] core: Add command line switch for enabling experimental interfaces
From: Luiz Augusto von Dentz @ 2012-12-28 12:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1356699069-5469-1-git-send-email-luiz.dentz@gmail.com>

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

This enable passing --experimental/-E to enable experimental interfaces
---
 src/main.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/main.c b/src/main.c
index 4a67e0f..2e8ba34 100644
--- a/src/main.c
+++ b/src/main.c
@@ -368,6 +368,7 @@ static gchar *option_noplugin = NULL;
 static gboolean option_compat = FALSE;
 static gboolean option_detach = TRUE;
 static gboolean option_version = FALSE;
+static gboolean option_experimental = FALSE;
 
 static void free_options(void)
 {
@@ -453,6 +454,8 @@ static GOptionEntry options[] = {
 				"Specify plugins not to load", "NAME,..." },
 	{ "compat", 'C', 0, G_OPTION_ARG_NONE, &option_compat,
 				"Provide deprecated command line interfaces" },
+	{ "experimental", 'E', 0, G_OPTION_ARG_NONE, &option_experimental,
+				"Enable experimental interfaces" },
 	{ "nodetach", 'n', G_OPTION_FLAG_REVERSE,
 				G_OPTION_ARG_NONE, &option_detach,
 				"Run with logging in foreground" },
@@ -467,6 +470,7 @@ int main(int argc, char *argv[])
 	GError *err = NULL;
 	uint16_t sdp_mtu = 0;
 	uint32_t sdp_flags = 0;
+	int gdbus_flags = 0;
 	GKeyFile *config;
 	guint signal, watchdog;
 	const char *watchdog_usec;
@@ -517,6 +521,11 @@ int main(int argc, char *argv[])
 		exit(1);
 	}
 
+	if (option_experimental)
+		gdbus_flags = G_DBUS_FLAG_ENABLE_EXPERIMENTAL;
+
+	g_dbus_set_flags(gdbus_flags);
+
 	if (option_compat == TRUE)
 		sdp_flags |= SDP_SERVER_COMPAT;
 
-- 
1.8.0.1


^ permalink raw reply related

* [PATCH BlueZ 08/11] core: Reuse --compat/-C switch for enabling deprecated interfaces
From: Luiz Augusto von Dentz @ 2012-12-28 12:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1356699069-5469-1-git-send-email-luiz.dentz@gmail.com>

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

---
 src/main.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/main.c b/src/main.c
index 2e8ba34..f6c4ee6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -524,10 +524,12 @@ int main(int argc, char *argv[])
 	if (option_experimental)
 		gdbus_flags = G_DBUS_FLAG_ENABLE_EXPERIMENTAL;
 
-	g_dbus_set_flags(gdbus_flags);
-
-	if (option_compat == TRUE)
+	if (option_compat == TRUE) {
 		sdp_flags |= SDP_SERVER_COMPAT;
+		gdbus_flags |= G_DBUS_FLAG_ENABLE_DEPRECATED;
+	}
+
+	g_dbus_set_flags(gdbus_flags);
 
 	start_sdp_server(sdp_mtu, sdp_flags);
 
-- 
1.8.0.1


^ permalink raw reply related

* [PATCH BlueZ 09/11] media: Enable RegisterPlayer and UnregisterPlayer methods as experimental
From: Luiz Augusto von Dentz @ 2012-12-28 12:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1356699069-5469-1-git-send-email-luiz.dentz@gmail.com>

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

---
 profiles/audio/media.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/profiles/audio/media.c b/profiles/audio/media.c
index f728460..e4206e3 100644
--- a/profiles/audio/media.c
+++ b/profiles/audio/media.c
@@ -868,7 +868,6 @@ static DBusMessage *unregister_endpoint(DBusConnection *conn, DBusMessage *msg,
 	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 }
 
-#if 0
 static struct media_player *media_adapter_find_player(
 						struct media_adapter *adapter,
 						const char *sender,
@@ -1533,7 +1532,6 @@ static DBusMessage *unregister_player(DBusConnection *conn, DBusMessage *msg,
 
 	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 }
-#endif
 
 static const GDBusMethodTable media_methods[] = {
 	{ GDBUS_METHOD("RegisterEndpoint",
@@ -1541,14 +1539,12 @@ static const GDBusMethodTable media_methods[] = {
 		NULL, register_endpoint) },
 	{ GDBUS_METHOD("UnregisterEndpoint",
 		GDBUS_ARGS({ "endpoint", "o" }), NULL, unregister_endpoint) },
-#if 0
-	{ GDBUS_METHOD("RegisterPlayer",
+	{ GDBUS_EXPERIMENTAL_METHOD("RegisterPlayer",
 		GDBUS_ARGS({ "player", "o" }, { "properties", "a{sv}" },
 						{ "metadata", "a{sv}" }),
 		NULL, register_player) },
-	{ GDBUS_METHOD("UnregisterPlayer",
+	{ GDBUS_EXPERIMENTAL_METHOD("UnregisterPlayer",
 		GDBUS_ARGS({ "player", "o" }), NULL, unregister_player) },
-#endif
 	{ },
 };
 
@@ -1559,10 +1555,8 @@ static void path_free(void *data)
 	while (adapter->endpoints)
 		release_endpoint(adapter->endpoints->data);
 
-#if 0
 	while (adapter->players)
 		media_player_destroy(adapter->players->data);
-#endif
 
 	adapters = g_slist_remove(adapters, adapter);
 
-- 
1.8.0.1


^ permalink raw reply related

* [PATCH BlueZ 10/11] player: Enable MediaPlayer1 interface as experimental
From: Luiz Augusto von Dentz @ 2012-12-28 12:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1356699069-5469-1-git-send-email-luiz.dentz@gmail.com>

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

This enable MediaPlayer1 when GDBUS_EXPERIMENTAL=1
---
 profiles/audio/player.c | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/profiles/audio/player.c b/profiles/audio/player.c
index 005d0d1..693a590 100644
--- a/profiles/audio/player.c
+++ b/profiles/audio/player.c
@@ -239,25 +239,31 @@ static void set_setting(const GDBusPropertyTable *property,
 }
 
 static const GDBusMethodTable media_player_methods[] = {
-	{ GDBUS_METHOD("GetTrack",
+	{ GDBUS_EXPERIMENTAL_METHOD("GetTrack",
 			NULL, GDBUS_ARGS({ "metadata", "a{sv}" }),
 			media_player_get_track) },
 	{ }
 };
 
 static const GDBusSignalTable media_player_signals[] = {
-	{ GDBUS_SIGNAL("TrackChanged",
+	{ GDBUS_EXPERIMENTAL_SIGNAL("TrackChanged",
 			GDBUS_ARGS({ "metadata", "a{sv}" })) },
 	{ }
 };
 
 static const GDBusPropertyTable media_player_properties[] = {
-	{ "Position", "u", get_position },
-	{ "Status", "s", get_status, NULL, status_exists },
-	{ "Equalizer", "s", get_setting, set_setting, setting_exists },
-	{ "Repeat", "s", get_setting, set_setting, setting_exists },
-	{ "Shuffle", "s", get_setting, set_setting, setting_exists },
-	{ "Scan", "s", get_setting, set_setting, setting_exists },
+	{ "Position", "u", get_position, NULL, NULL,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "Status", "s", get_status, NULL, status_exists,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "Equalizer", "s", get_setting, set_setting, setting_exists,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "Repeat", "s", get_setting, set_setting, setting_exists,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "Shuffle", "s", get_setting, set_setting, setting_exists,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "Scan", "s", get_setting, set_setting, setting_exists,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
 	{ }
 };
 
@@ -298,7 +304,6 @@ struct media_player *media_player_controller_create(const char *path)
 							g_free, g_free);
 	mp->progress = g_timer_new();
 
-#if 0
 	if (!g_dbus_register_interface(btd_get_dbus_connection(),
 					mp->path, MEDIA_PLAYER_INTERFACE,
 					media_player_methods,
@@ -308,7 +313,7 @@ struct media_player *media_player_controller_create(const char *path)
 		media_player_destroy(mp);
 		return NULL;
 	}
-#endif
+
 	DBG("%s", mp->path);
 
 	return mp;
@@ -410,7 +415,6 @@ void media_player_set_status(struct media_player *mp, const char *status)
 
 static gboolean process_metadata_changed(void *user_data)
 {
-#if 0
 	struct media_player *mp = user_data;
 	DBusMessage *signal;
 	DBusMessageIter iter, dict;
@@ -439,7 +443,7 @@ static gboolean process_metadata_changed(void *user_data)
 	dbus_message_iter_close_container(&iter, &dict);
 
 	g_dbus_send_message(btd_get_dbus_connection(), signal);
-#endif
+
 	return FALSE;
 }
 
-- 
1.8.0.1


^ permalink raw reply related


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