* Re: [PATCH BlueZ 02/10] gdbus: Remove connection from g_dbus_remove_watch
From: Luiz Augusto von Dentz @ 2012-10-04 8:42 UTC (permalink / raw)
To: Lucas De Marchi, Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <CABBYNZKtES_LgxOBjx-aaDCKionV039M+mDHF5WJ3SZVAn2ABQ@mail.gmail.com>
Hi Marcel,
On Tue, Oct 2, 2012 at 4:57 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi Lucas,
>
> On Tue, Oct 2, 2012 at 1:49 PM, Lucas De Marchi
> <lucas.demarchi@profusion.mobi> wrote:
>> On Tue, Oct 2, 2012 at 5:05 AM, Luiz Augusto von Dentz
>> <luiz.dentz@gmail.com> wrote:
>>> Hi Lucas,
>>>
>>> On Tue, Oct 2, 2012 at 7:23 AM, Lucas De Marchi
>>> <lucas.demarchi@profusion.mobi> wrote:
>>>> On Mon, Oct 1, 2012 at 2:53 PM, Luiz Augusto von Dentz
>>>> <luiz.dentz@gmail.com> wrote:
>>>>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>>>>
>>>>> The connection is not really needed since the list of listeners is
>>>>> global not per connection, besides it is more convenient this way as
>>>>> only the id is needed.
>>>>> ---
>>>>> gdbus/gdbus.h | 2 +-
>>>>> gdbus/watch.c | 4 ++--
>>>>> 2 files changed, 3 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
>>>>> index 0a8a27c..3bd8986 100644
>>>>> --- a/gdbus/gdbus.h
>>>>> +++ b/gdbus/gdbus.h
>>>>> @@ -217,7 +217,7 @@ guint g_dbus_add_signal_watch(DBusConnection *connection,
>>>>> const char *interface, const char *member,
>>>>> GDBusSignalFunction function, void *user_data,
>>>>> GDBusDestroyFunction destroy);
>>>>> -gboolean g_dbus_remove_watch(DBusConnection *connection, guint tag);
>>>>> +gboolean g_dbus_remove_watch(guint id);
>>>>> void g_dbus_remove_all_watches(DBusConnection *connection);
>>>>>
>>>>> #ifdef __cplusplus
>>>>> diff --git a/gdbus/watch.c b/gdbus/watch.c
>>>>> index 07feb61..00cedae 100644
>>>>> --- a/gdbus/watch.c
>>>>> +++ b/gdbus/watch.c
>>>>> @@ -285,7 +285,7 @@ static void filter_data_free(struct filter_data *data)
>>>>> g_free(l->data);
>>>>>
>>>>> g_slist_free(data->callbacks);
>>>>> - g_dbus_remove_watch(data->connection, data->name_watch);
>>>>> + g_dbus_remove_watch(data->name_watch);
>>>>> g_free(data->name);
>>>>> g_free(data->owner);
>>>>> g_free(data->path);
>>>>> @@ -752,7 +752,7 @@ guint g_dbus_add_signal_watch(DBusConnection *connection,
>>>>> return cb->id;
>>>>> }
>>>>>
>>>>> -gboolean g_dbus_remove_watch(DBusConnection *connection, guint id)
>>>>> +gboolean g_dbus_remove_watch(guint id)
>>>>> {
>>>>> struct filter_data *data;
>>>>> struct filter_callback *cb;
>>>>> --
>>>>
>>>> This will lead to a broken build which is not nice to bisect. Any
>>>> other option besides adding with another name, converting everybody
>>>> and then renaming?
>>>>
>>>> The only other option I can think of is adding an ifdef and an option
>>>> to build-sys... this would avoid the final renaming.
>>>
>>> I guess this time it worth having the break of bisect in favor of a
>>> more convenient API, if you look at what the code is doing the
>>> connection is useless and normally we end up having to call the core
>>> to figure out a connection that is not used for anything.
>>
>> Ahn? did you read what I proposed as an option? I proposed splitting
>> the patch in 4 as opposed to 2 as you did.
>>
>> 0001) WARNING, whitespace error below
>>
>> diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
>> index 0a8a27c..d254562 100644
>> --- a/gdbus/gdbus.h
>> +++ b/gdbus/gdbus.h
>> @@ -217,7 +217,12 @@ guint g_dbus_add_signal_watch(DBusConnection *connection,
>> const char *interface, const char *member,
>> GDBusSignalFunction function, void *user_data,
>> GDBusDestroyFunction destroy);
>> -gboolean g_dbus_remove_watch(DBusConnection *connection, guint tag);
>> +#ifdef _GDBUS_WITH_NEW_REMOVE_WATCH
>> +gboolean g_dbus_remove_watch(guint tag);
>> +#else
>> +gboolean g_dbus_remove_watch(DBusConnection *connection, guint tag);
>> +#endif
>> +
>> void g_dbus_remove_all_watches(DBusConnection *connection);
>>
>> #ifdef __cplusplus
>>
>>
>> 0002) Convert everybody adding the definition on Makefile.am
>>
>> 0003) Remove the define from Makefile.am
>>
>> 0004) Remove the old code from gdbus/
>
> That sounds overkill for so simple change, I will send updates to
> other projects using gdbus to see their reception, if they are
> receptive to the changes I think we can ignore the bisect problem.
Apparently you raised some concerns about this changes, but note that
this should not affect watches to different/private connections since
the watch itself carries a reference to the connection, in fact if you
look at the changes the connection given as parameter is completely
ignored, you could even pass NULL and it would still work.
--
Luiz Augusto von Dentz
^ permalink raw reply
* [PATCH] Bluetooth: AMP: Register AMP only if High Speed enabled
From: Andrei Emeltchenko @ 2012-10-04 8:26 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Make sure that AMP controller is registered only if HS enables.
Return EINVAL if High Speed is not enabled and dev_type is HCI_AMP.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
net/bluetooth/hci_core.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index bd26cb5..746af2d 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1708,7 +1708,10 @@ int hci_register_dev(struct hci_dev *hdev)
id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
break;
case HCI_AMP:
- id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
+ if (enable_hs)
+ id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
+ else
+ return -EINVAL;
break;
default:
return -EINVAL;
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH BlueZ 1/2] build-sys: Don't use deprecated AM_PROG_MKDIR_P
From: Johan Hedberg @ 2012-10-04 8:26 UTC (permalink / raw)
To: Lucas De Marchi; +Cc: linux-bluetooth, Lucas De Marchi
In-Reply-To: <1349332630-8901-1-git-send-email-lucas.de.marchi@gmail.com>
Hi Lucas,
On Thu, Oct 04, 2012, Lucas De Marchi wrote:
> AM_PROG_MKDIR_P is deprecated since:
>
> configure.ac:23: warning: The 'AM_PROG_MKDIR_P' macro is deprecated, and will soon be removed.
> configure.ac:23: You should use the Autoconf-provided 'AC_PROG_MKDIR_P' macro instead,
> configure.ac:23: and use '$(MKDIR_P)' instead of '$(mkdir_p)'in your Makefile.am files.
>
> We are already using $(MKDIR_P) so we just need to call the right macro.
> ---
> configure.ac | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Both patches have been applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH BlueZ 1/2] AVCTP: Remove hand-written function name from log
From: Johan Hedberg @ 2012-10-04 8:26 UTC (permalink / raw)
To: Lucas De Marchi; +Cc: linux-bluetooth, Lucas De Marchi
In-Reply-To: <1349327674-23672-1-git-send-email-lucas.demarchi@profusion.mobi>
Hi Lucas,
On Thu, Oct 04, 2012, Lucas De Marchi wrote:
> Besides being hand-written, it was wrong which leads to confusion with
> the AVDTP.
> ---
> audio/avctp.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Both patches have been applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH BlueZ] core: Fix walking the list while removing elements
From: Johan Hedberg @ 2012-10-04 7:49 UTC (permalink / raw)
To: Lucas De Marchi; +Cc: linux-bluetooth, Lucas De Marchi
In-Reply-To: <1349330786-30166-1-git-send-email-lucas.de.marchi@gmail.com>
Hi Lucas,
On Thu, Oct 04, 2012, Lucas De Marchi wrote:
> If we are walking a GSList and remove the element we are pointing to,
> the next iteration g_slist_next() will access previously freed
> memory.
> ---
>
> This was caught only by inspecting the code. I don't know why valgrind
> didn't complain about accessing previously freed memory region.
>
> src/device.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/src/device.c b/src/device.c
> index c659164..6150963 100644
> --- a/src/device.c
> +++ b/src/device.c
> @@ -1498,7 +1498,7 @@ static void device_remove_profiles(struct btd_device *device, GSList *uuids)
> if (records)
> sdp_list_free(records, (sdp_free_func_t) sdp_record_free);
>
> - for (l = device->profiles; l != NULL; l = g_slist_next(l)) {
> + for (l = device->profiles; l != NULL;) {
> struct btd_profile *profile = l->data;
> GSList *probe_uuids;
>
> @@ -1506,9 +1506,11 @@ static void device_remove_profiles(struct btd_device *device, GSList *uuids)
> device->uuids);
> if (probe_uuids != NULL) {
> g_slist_free(probe_uuids);
> + l = l->next;
> continue;
> }
>
> + l = l->next;
> profile->device_remove(profile, device);
> device->profiles = g_slist_remove(device->profiles, profile);
> }
Thanks for catching this, however could you fix it the same way most
other similar loops in the code-base do it, i.e. add a GSList *next
helper variable:
GSList *l, *next;
for (l = device->profiles; l != NULL; l = next) {
<variable declarations>
next = l->next;
<rest of the loop code>
}
Johan
^ permalink raw reply
* [PATCH v2 resend 2/2] broadcom patchram firmware loader
From: Jesse Sung @ 2012-10-04 7:30 UTC (permalink / raw)
To: Marcel Holtmann, Gustavo Padovan, Johan Hedberg, linux-bluetooth
In-Reply-To: <1349335847-1615-1-git-send-email-jesse.sung@canonical.com>
From: Wen-chien Jesse Sung <jesse.sung@canonical.com>
There is an user space firmware loading tool which can be found at
http://marc.info/?l=linux-bluetooth&m=132039175324993&w=2
This tool requires hci device to do the firmware loading, but this
may cause some race condition between patchram tool and bluetoothd
or something that also works on hci interface.
Also it needs some hooks to make firmware loads after bootup, s3,
s4, rfkill, and device hotplug events. Implement this loader in kernel
module would make things more easier.
The supported firmware is in hcd format, which is a collection of
hci commands. The download process would be:
1. reset command
2. download command
3. firmware image in hcd file
4. reset command
/sys/kernel/debug/usb/devices before loading firmware:
T: Bus=01 Lev=02 Prnt=02 Port=04 Cnt=02 Dev#= 4 Spd=12 MxCh= 0
D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=0a5c ProdID=21d3 Rev= 1.12
S: Manufacturer=Broadcom Corp
S: Product=BCM43142A0
S: SerialNumber=3859F9D6199A
C:* #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr= 0mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
I: If#= 1 Alt= 1 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
I: If#= 1 Alt= 2 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
I: If#= 1 Alt= 3 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
I: If#= 1 Alt= 4 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
I: If#= 1 Alt= 5 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
E: Ad=84(I) Atr=02(Bulk) MxPS= 32 Ivl=0ms
E: Ad=04(O) Atr=02(Bulk) MxPS= 32 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none)
/sys/kernel/debug/usb/devices after loading firmware:
T: Bus=01 Lev=02 Prnt=02 Port=04 Cnt=02 Dev#= 4 Spd=12 MxCh= 0
D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=0a5c ProdID=21d3 Rev= 1.12
S: Manufacturer=Broadcom Corp
S: Product=BCM43142A0
S: SerialNumber=3859F9D6199A
C:* #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr= 0mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
I: If#= 1 Alt= 1 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
I: If#= 1 Alt= 2 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
I: If#= 1 Alt= 3 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
I: If#= 1 Alt= 4 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
I: If#= 1 Alt= 5 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
E: Ad=84(I) Atr=02(Bulk) MxPS= 32 Ivl=0ms
E: Ad=04(O) Atr=02(Bulk) MxPS= 32 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none)
Signed-off-by: Wen-chien Jesse Sung <jesse.sung@canonical.com>
---
drivers/bluetooth/btusb.c | 75 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 73 insertions(+), 2 deletions(-)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index fbfb069..408a5c6 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -23,6 +23,8 @@
#include <linux/module.h>
#include <linux/usb.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -47,6 +49,7 @@ static struct usb_driver btusb_driver;
#define BTUSB_BROKEN_ISOC 0x20
#define BTUSB_WRONG_SCO_MTU 0x40
#define BTUSB_ATH3012 0x80
+#define BTUSB_BCM_PATCHRAM 0x100
static struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
@@ -97,13 +100,13 @@ static struct usb_device_id btusb_table[] = {
/* Broadcom BCM20702A0 */
{ USB_DEVICE(0x0489, 0xe042) },
- { USB_DEVICE(0x413c, 0x8197) },
+ { USB_DEVICE(0x413c, 0x8197), .driver_info = BTUSB_BCM_PATCHRAM },
/* Foxconn - Hon Hai */
{ USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xff, 0x01, 0x01) },
/*Broadcom devices with vendor specific id */
- { USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) },
+ { USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01), .driver_info = BTUSB_BCM_PATCHRAM },
{ } /* Terminating entry */
};
@@ -204,12 +207,14 @@ static struct usb_device_id blacklist_table[] = {
#define BTUSB_ISOC_RUNNING 2
#define BTUSB_SUSPENDING 3
#define BTUSB_DID_ISO_RESUME 4
+#define BTUSB_FIRMWARE_DONE 5
struct btusb_data {
struct hci_dev *hdev;
struct usb_device *udev;
struct usb_interface *intf;
struct usb_interface *isoc;
+ const struct usb_device_id *id;
spinlock_t lock;
@@ -914,6 +919,69 @@ static void btusb_waker(struct work_struct *work)
usb_autopm_put_interface(data->intf);
}
+#define PATCHRAM_TIMEOUT 1000
+#define PATCHRAM_NAME_LEN 20
+
+static void btusb_load_firmware(struct hci_dev *hdev)
+{
+ struct btusb_data *data = hci_get_drvdata(hdev);
+ struct usb_device *udev = data->udev;
+ const struct usb_device_id *id = data->id;
+ size_t pos = 0;
+ int err = 0;
+ char filename[PATCHRAM_NAME_LEN];
+ const struct firmware *fw;
+
+ unsigned char reset_cmd[] = { 0x03, 0x0c, 0x00 };
+ unsigned char download_cmd[] = { 0x2e, 0xfc, 0x00 };
+
+ if (!(id->driver_info & BTUSB_BCM_PATCHRAM))
+ return;
+ if (test_and_set_bit(BTUSB_FIRMWARE_DONE, &data->flags))
+ return;
+
+ snprintf(filename, PATCHRAM_NAME_LEN, "fw-%04x_%04x.hcd",
+ id->idVendor, id->idProduct);
+ if (request_firmware(&fw, (const char *) filename, &udev->dev) < 0) {
+ BT_INFO("can't load firmware, may not work correctly");
+ return;
+ }
+
+ if (usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0, USB_TYPE_CLASS, 0, 0,
+ reset_cmd, sizeof(reset_cmd), PATCHRAM_TIMEOUT) < 0) {
+ err = -1;
+ goto out;
+ }
+ msleep(300);
+
+ if (usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0, USB_TYPE_CLASS, 0, 0,
+ download_cmd, sizeof(download_cmd), PATCHRAM_TIMEOUT) < 0) {
+ err = -1;
+ goto out;
+ }
+ msleep(300);
+
+ while (pos < fw->size) {
+ size_t len;
+ len = fw->data[pos + 2] + 3;
+ if ((pos + len > fw->size) ||
+ (usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
+ USB_TYPE_CLASS, 0, 0, (void *)fw->data + pos, len,
+ PATCHRAM_TIMEOUT) < 0)) {
+ err = -1;
+ goto out;
+ }
+ pos += len;
+ }
+
+ err = (usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0, USB_TYPE_CLASS, 0, 0,
+ reset_cmd, sizeof(reset_cmd), PATCHRAM_TIMEOUT) < 0);
+out:
+ if (err)
+ BT_INFO("fail to load firmware, may not work correctly");
+ release_firmware(fw);
+}
+
static int btusb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
@@ -1001,6 +1069,8 @@ static int btusb_probe(struct usb_interface *intf,
init_usb_anchor(&data->isoc_anchor);
init_usb_anchor(&data->deferred);
+ data->id = id;
+
hdev = hci_alloc_dev();
if (!hdev) {
kfree(data);
@@ -1019,6 +1089,7 @@ static int btusb_probe(struct usb_interface *intf,
hdev->flush = btusb_flush;
hdev->send = btusb_send_frame;
hdev->notify = btusb_notify;
+ hdev->load_firmware = btusb_load_firmware;
/* Interface numbers are hardcoded in the specification */
data->isoc = usb_ifnum_to_if(data->udev, 1);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 resend 1/2] Introduced a load_firmware callback to struct hci_dev
From: Jesse Sung @ 2012-10-04 7:30 UTC (permalink / raw)
To: Marcel Holtmann, Gustavo Padovan, Johan Hedberg, linux-bluetooth
In-Reply-To: <1349335847-1615-1-git-send-email-jesse.sung@canonical.com>
From: Wen-chien Jesse Sung <jesse.sung@canonical.com>
load_firmware will be called at the end of hci_dev_open() if it
is defined.
Signed-off-by: Wen-chien Jesse Sung <jesse.sung@canonical.com>
---
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/hci_core.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 593cd1d..40972a3 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -281,6 +281,7 @@ struct hci_dev {
int (*send)(struct sk_buff *skb);
void (*notify)(struct hci_dev *hdev, unsigned int evt);
int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
+ void (*load_firmware)(struct hci_dev *hdev);
};
struct hci_conn {
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index d4de5db..49be87a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -725,6 +725,8 @@ int hci_dev_open(__u16 dev)
done:
hci_req_unlock(hdev);
hci_dev_put(hdev);
+ if (!ret && hdev->load_firmware)
+ hdev->load_firmware(hdev);
return ret;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 resend 0/2] broadcom patchram firmware loader
From: Jesse Sung @ 2012-10-04 7:30 UTC (permalink / raw)
To: Marcel Holtmann, Gustavo Padovan, Johan Hedberg, linux-bluetooth
In-Reply-To: <cover.1347959921.git.jesse.sung@canonical.com>
From: Wen-chien Jesse Sung <jesse.sung@canonical.com>
There is an user space firmware loading tool which can be found at
http://marc.info/?l=linux-bluetooth&m=132039175324993&w=2
This tool requires hci device to do the firmware loading, but this
may cause some race condition between patchram tool and bluetoothd
or something that also works on hci interface.
Also it needs some hooks to make firmware loads after bootup, s3,
s4, rfkill, and device hotplug events. Implement this loader in kernel
module would make things more easier.
Wen-chien Jesse Sung (2):
Introduced a load_firmware callback to struct hci_dev
broadcom patchram firmware loader
drivers/bluetooth/btusb.c | 75 +++++++++++++++++++++++++++++++++++++-
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/hci_core.c | 2 +
3 files changed, 76 insertions(+), 2 deletions(-)
--
1.7.9.5
^ permalink raw reply
* [PATCH BlueZ v4 15/15] Use DBus.Properties on Manager interface
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>
---
src/manager.c | 81 ++++++++++++++++++-----------------------------------------
1 file changed, 25 insertions(+), 56 deletions(-)
diff --git a/src/manager.c b/src/manager.c
index f1f0f4d..2ceeed1 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -132,46 +132,30 @@ done:
return reply;
}
-static DBusMessage *get_properties(DBusConnection *conn,
- DBusMessage *msg, void *data)
+static gboolean manager_property_get_adapters(
+ const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
{
- DBusMessage *reply;
- DBusMessageIter iter;
- DBusMessageIter dict;
- GSList *list;
- char **array;
- int i;
-
- reply = dbus_message_new_method_return(msg);
- if (!reply)
- return NULL;
-
- dbus_message_iter_init_append(reply, &iter);
+ DBusMessageIter entry;
+ GSList *l;
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_OBJECT_PATH_AS_STRING, &entry);
- array = g_new0(char *, g_slist_length(adapters) + 1);
- for (i = 0, list = adapters; list; list = list->next) {
- struct btd_adapter *adapter = list->data;
+ for (l = adapters; l != NULL; l = l->next) {
+ struct btd_adapter *adapter = l->data;
+ const char *path = adapter_get_path(adapter);
- array[i] = (char *) adapter_get_path(adapter);
- i++;
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
+ &path);
}
- dict_append_array(&dict, "Adapters", DBUS_TYPE_OBJECT_PATH, &array, i);
- g_free(array);
- dbus_message_iter_close_container(&iter, &dict);
+ dbus_message_iter_close_container(iter, &entry);
- return reply;
+ return TRUE;
}
static const GDBusMethodTable manager_methods[] = {
- { GDBUS_METHOD("GetProperties",
- NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
- get_properties) },
{ GDBUS_METHOD("DefaultAdapter",
NULL, GDBUS_ARGS({ "adapter", "o" }),
default_adapter) },
@@ -189,8 +173,6 @@ static const GDBusMethodTable manager_methods[] = {
};
static const GDBusSignalTable manager_signals[] = {
- { GDBUS_SIGNAL("PropertyChanged",
- GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
{ GDBUS_SIGNAL("AdapterAdded",
GDBUS_ARGS({ "adapter", "o" })) },
{ GDBUS_SIGNAL("AdapterRemoved",
@@ -200,34 +182,19 @@ static const GDBusSignalTable manager_signals[] = {
{ }
};
+static const GDBusPropertyTable manager_properties[] = {
+ { "Adapters", "ao", manager_property_get_adapters },
+ { }
+};
+
dbus_bool_t manager_init(const char *path)
{
snprintf(base_path, sizeof(base_path), "/org/bluez/%d", getpid());
return g_dbus_register_interface(btd_get_dbus_connection(),
"/", MANAGER_INTERFACE,
- manager_methods, manager_signals, NULL,
- NULL, NULL);
-}
-
-static void manager_update_adapters(void)
-{
- GSList *list;
- char **array;
- int i;
-
- array = g_new0(char *, g_slist_length(adapters) + 1);
- for (i = 0, list = adapters; list; list = list->next) {
- struct btd_adapter *adapter = list->data;
-
- array[i] = (char *) adapter_get_path(adapter);
- i++;
- }
-
- emit_array_property_changed("/", MANAGER_INTERFACE, "Adapters",
- DBUS_TYPE_OBJECT_PATH, &array, i);
-
- g_free(array);
+ manager_methods, manager_signals,
+ manager_properties, NULL, NULL);
}
static void manager_set_default_adapter(int id)
@@ -261,7 +228,8 @@ static void manager_remove_adapter(struct btd_adapter *adapter)
adapters = g_slist_remove(adapters, adapter);
- manager_update_adapters();
+ g_dbus_emit_property_changed(btd_get_dbus_connection(), "/",
+ MANAGER_INTERFACE, "Adapters");
if (default_adapter_id == dev_id || default_adapter_id < 0) {
int new_default = hci_get_route(NULL);
@@ -381,7 +349,8 @@ struct btd_adapter *btd_manager_register_adapter(int id, gboolean up)
DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID);
- manager_update_adapters();
+ g_dbus_emit_property_changed(btd_get_dbus_connection(), "/",
+ MANAGER_INTERFACE, "Adapters");
btd_stop_exit_timer();
--
1.7.12.2
^ permalink raw reply related
* [PATCH BlueZ v4 14/15] Use DBus.Properties on Control interface
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>
---
audio/control.c | 57 ++++++++++++++++++---------------------------------------
1 file changed, 18 insertions(+), 39 deletions(-)
diff --git a/audio/control.c b/audio/control.c
index 896bc48..5ec8ca3 100644
--- a/audio/control.c
+++ b/audio/control.c
@@ -68,7 +68,6 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
{
DBusConnection *conn = btd_get_dbus_connection();
struct control *control = dev->control;
- gboolean value;
switch (new_state) {
case AVCTP_STATE_DISCONNECTED:
@@ -77,13 +76,11 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
if (old_state != AVCTP_STATE_CONNECTED)
break;
- value = FALSE;
g_dbus_emit_signal(conn, dev->path,
AUDIO_CONTROL_INTERFACE,
"Disconnected", DBUS_TYPE_INVALID);
- emit_property_changed(dev->path,
- AUDIO_CONTROL_INTERFACE, "Connected",
- DBUS_TYPE_BOOLEAN, &value);
+ g_dbus_emit_property_changed(conn, dev->path,
+ AUDIO_CONTROL_INTERFACE, "Connected");
break;
case AVCTP_STATE_CONNECTING:
@@ -94,13 +91,11 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
break;
case AVCTP_STATE_CONNECTED:
- value = TRUE;
g_dbus_emit_signal(conn, dev->path,
AUDIO_CONTROL_INTERFACE, "Connected",
DBUS_TYPE_INVALID);
- emit_property_changed(dev->path,
- AUDIO_CONTROL_INTERFACE, "Connected",
- DBUS_TYPE_BOOLEAN, &value);
+ g_dbus_emit_property_changed(conn, dev->path,
+ AUDIO_CONTROL_INTERFACE, "Connected");
break;
default:
return;
@@ -168,42 +163,22 @@ static DBusMessage *volume_down(DBusConnection *conn, DBusMessage *msg,
return dbus_message_new_method_return(msg);
}
-static DBusMessage *control_get_properties(DBusConnection *conn,
- DBusMessage *msg, void *data)
+static gboolean control_property_get_connected(
+ const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
{
struct audio_device *device = data;
- DBusMessage *reply;
- DBusMessageIter iter;
- DBusMessageIter dict;
- gboolean value;
-
- reply = dbus_message_new_method_return(msg);
- if (!reply)
- return NULL;
-
- dbus_message_iter_init_append(reply, &iter);
+ dbus_bool_t value = (device->control->session != NULL);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
- /* Connected */
- value = (device->control->session != NULL);
- dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, &value);
-
- dbus_message_iter_close_container(&iter, &dict);
-
- return reply;
+ return TRUE;
}
static const GDBusMethodTable control_methods[] = {
{ GDBUS_DEPRECATED_METHOD("IsConnected",
NULL, GDBUS_ARGS({ "connected", "b" }),
control_is_connected) },
- { GDBUS_METHOD("GetProperties",
- NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
- control_get_properties) },
{ GDBUS_METHOD("VolumeUp", NULL, NULL, volume_up) },
{ GDBUS_METHOD("VolumeDown", NULL, NULL, volume_down) },
{ }
@@ -212,8 +187,11 @@ static const GDBusMethodTable control_methods[] = {
static const GDBusSignalTable control_signals[] = {
{ GDBUS_DEPRECATED_SIGNAL("Connected", NULL) },
{ GDBUS_DEPRECATED_SIGNAL("Disconnected", NULL) },
- { GDBUS_SIGNAL("PropertyChanged",
- GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
+ { }
+};
+
+static const GDBusPropertyTable control_properties[] = {
+ { "Connected", "b", control_property_get_connected },
{ }
};
@@ -250,8 +228,9 @@ struct control *control_init(struct audio_device *dev, GSList *uuids)
if (!g_dbus_register_interface(btd_get_dbus_connection(), dev->path,
AUDIO_CONTROL_INTERFACE,
- control_methods, control_signals, NULL,
- dev, path_unregister))
+ control_methods, control_signals,
+ control_properties, dev,
+ path_unregister))
return NULL;
DBG("Registered interface %s on path %s",
--
1.7.12.2
^ permalink raw reply related
* [PATCH BlueZ v4 13/15] gdbus: Implement PropertiesChanged signal
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>
From: Lucas De Marchi <lucas.demarchi@profusion.mobi>
---
gdbus/gdbus.h | 3 ++
gdbus/object.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 109 insertions(+), 2 deletions(-)
diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index ec7b1ef..a96c97f 100644
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -254,6 +254,9 @@ void g_dbus_pending_property_error_valist(DBusConnection *connection,
void g_dbus_pending_property_error(DBusConnection *connection,
GDBusPendingReply id, const char *name,
const char *format, ...);
+void g_dbus_emit_property_changed(DBusConnection *connection,
+ const char *path, const char *interface,
+ const char *name);
#ifdef __cplusplus
}
diff --git a/gdbus/object.c b/gdbus/object.c
index bb0aa4d..b352fc4 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -48,6 +48,7 @@ struct generic_data {
GSList *added;
GSList *removed;
guint process_id;
+ gboolean pending_prop;
char *introspect;
struct generic_data *parent;
};
@@ -57,6 +58,7 @@ struct interface_data {
const GDBusMethodTable *methods;
const GDBusSignalTable *signals;
const GDBusPropertyTable *properties;
+ GSList *pending_prop;
void *user_data;
GDBusDestroyFunction destroy;
};
@@ -74,6 +76,9 @@ struct property_data {
};
static gboolean process_changes(gpointer user_data);
+static void process_properties_from_interface(struct generic_data *data,
+ struct interface_data *iface);
+static void process_property_changes(struct generic_data *data);
static void print_arguments(GString *gstr, const GDBusArgInfo *args,
const char *direction)
@@ -952,6 +957,10 @@ static gboolean process_changes(gpointer user_data)
if (data->added != NULL)
emit_interfaces_added(data);
+ /* Flush pending properties */
+ if (data->pending_prop == TRUE)
+ process_property_changes(data);
+
if (data->removed != NULL)
emit_interfaces_removed(data);
@@ -968,8 +977,7 @@ static void generic_unregister(DBusConnection *connection, void *user_data)
if (data->process_id > 0) {
g_source_remove(data->process_id);
- if (data->removed != NULL)
- emit_interfaces_removed(data);
+ process_changes(data);
}
g_slist_foreach(data->objects, reset_parent, data->parent);
@@ -1481,3 +1489,99 @@ gboolean g_dbus_emit_signal_valist(DBusConnection *connection,
return emit_signal_valist(connection, path, interface,
name, type, args);
}
+
+static void process_properties_from_interface(struct generic_data *data,
+ struct interface_data *iface)
+{
+ GSList *l;
+ DBusMessage *signal;
+ DBusMessageIter iter, dict, array;
+
+ if (iface->pending_prop == NULL)
+ return;
+
+ signal = dbus_message_new_signal(data->path,
+ DBUS_INTERFACE_PROPERTIES, "PropertiesChanged");
+ if (signal == NULL) {
+ error("Unable to allocate new " DBUS_INTERFACE_PROPERTIES
+ ".PropertiesChanged signal");
+ return;
+ }
+
+ iface->pending_prop = g_slist_reverse(iface->pending_prop);
+
+ dbus_message_iter_init_append(signal, &iter);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &iface->name);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+ for (l = iface->pending_prop; l != NULL; l = l->next) {
+ GDBusPropertyTable *p = l->data;
+
+ if (p->get == NULL)
+ continue;
+
+ if (p->exists != NULL && !p->exists(p, iface->user_data))
+ continue;
+
+ append_property(iface, p, &dict);
+ }
+
+ dbus_message_iter_close_container(&iter, &dict);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING, &array);
+ dbus_message_iter_close_container(&iter, &array);
+
+ g_dbus_send_message(data->conn, signal);
+
+ g_slist_free(iface->pending_prop);
+ iface->pending_prop = NULL;
+}
+
+static void process_property_changes(struct generic_data *data)
+{
+ GSList *l;
+
+ for (l = data->interfaces; l != NULL; l = l->next) {
+ struct interface_data *iface = l->data;
+
+ process_properties_from_interface(data, iface);
+ }
+
+ data->pending_prop = FALSE;
+}
+
+void g_dbus_emit_property_changed(DBusConnection *connection,
+ const char *path, const char *interface,
+ const char *name)
+{
+ const GDBusPropertyTable *property;
+ struct generic_data *data;
+ struct interface_data *iface;
+
+ if (!dbus_connection_get_object_path_data(connection, path,
+ (void **) &data) || data == NULL)
+ return;
+
+ iface = find_interface(data->interfaces, interface);
+ if (iface == NULL)
+ return;
+
+ property = find_property(iface->properties, name);
+ if (property == NULL) {
+ error("Could not find property %s in %p", name,
+ iface->properties);
+ return;
+ }
+
+ data->pending_prop = TRUE;
+ iface->pending_prop = g_slist_prepend(iface->pending_prop,
+ (void *) property);
+
+ if (!data->process_id) {
+ data->process_id = g_idle_add(process_changes, data);
+ return;
+ }
+}
--
1.7.12.2
^ permalink raw reply related
* [PATCH BlueZ v4 12/15] gdbus: Simplify code for appending properties
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Luiz Augusto von Dentz
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This reuse append_properties for GetAll and GetManagedObjects
---
gdbus/object.c | 34 ++--------------------------------
1 file changed, 2 insertions(+), 32 deletions(-)
diff --git a/gdbus/object.c b/gdbus/object.c
index 066f1a6..bb0aa4d 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -784,9 +784,8 @@ static DBusMessage *properties_get_all(DBusConnection *connection,
{
struct generic_data *data = user_data;
struct interface_data *iface;
- const GDBusPropertyTable *p;
const char *interface;
- DBusMessageIter iter, dict;
+ DBusMessageIter iter;
DBusMessage *reply;
if (!dbus_message_get_args(message, NULL,
@@ -804,37 +803,8 @@ static DBusMessage *properties_get_all(DBusConnection *connection,
return NULL;
dbus_message_iter_init_append(reply, &iter);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
-
- for (p = iface->properties; p && p->name; p++) {
- DBusMessageIter entry, value;
-
- if (p->get == NULL)
- continue;
-
- if (p->exists != NULL && !p->exists(p, iface->user_data))
- continue;
-
- dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY,
- NULL, &entry);
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
- p->name);
- dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
- p->type, &value);
-
- if (!p->get(p, &value, iface->user_data)) {
- dbus_message_unref(reply);
- return NULL;
- }
-
- dbus_message_iter_close_container(&entry, &value);
- dbus_message_iter_close_container(&dict, &entry);
- }
- dbus_message_iter_close_container(&iter, &dict);
+ append_properties(iface, &iter);
return reply;
}
--
1.7.12.2
^ permalink raw reply related
* [PATCH BlueZ v4 11/15] gdbus: Integrates ObjectManager with Properties interface
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Luiz Augusto von Dentz
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This appends the properties and its values when using ObjectManager.
---
gdbus/object.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/gdbus/object.c b/gdbus/object.c
index e96a2bf..066f1a6 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -496,10 +496,28 @@ static void reset_parent(gpointer data, gpointer user_data)
child->parent = parent;
}
+static void append_property(struct interface_data *iface,
+ const GDBusPropertyTable *p, DBusMessageIter *dict)
+{
+ DBusMessageIter entry, value;
+
+ dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, NULL,
+ &entry);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &p->name);
+ dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT, p->type,
+ &value);
+
+ p->get(p, &value, iface->user_data);
+
+ dbus_message_iter_close_container(&entry, &value);
+ dbus_message_iter_close_container(dict, &entry);
+}
+
static void append_properties(struct interface_data *data,
DBusMessageIter *iter)
{
DBusMessageIter dict;
+ const GDBusPropertyTable *p;
dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
@@ -507,7 +525,15 @@ static void append_properties(struct interface_data *data,
DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
- /* TODO: list properties */
+ for (p = data->properties; p && p->name; p++) {
+ if (p->get == NULL)
+ continue;
+
+ if (p->exists != NULL && !p->exists(p, data->user_data))
+ continue;
+
+ append_property(data, p, &dict);
+ }
dbus_message_iter_close_container(iter, &dict);
}
--
1.7.12.2
^ permalink raw reply related
* [PATCH BlueZ v4 10/15] gdbus: Only export ObjectManager interface on root path
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Luiz Augusto von Dentz
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
ObjectManager should be exported only in the root path and list all
the children paths.
---
gdbus/object.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/gdbus/object.c b/gdbus/object.c
index 5b5dc7e..e96a2bf 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -534,6 +534,10 @@ static void emit_interfaces_added(struct generic_data *data)
if (parent == NULL)
return;
+ /* Find root data */
+ while (parent->parent)
+ parent = parent->parent;
+
signal = dbus_message_new_signal(parent->path,
DBUS_INTERFACE_OBJECT_MANAGER,
"InterfacesAdded");
@@ -918,6 +922,10 @@ static void emit_interfaces_removed(struct generic_data *data)
if (parent == NULL)
return;
+ /* Find root data */
+ while (parent->parent)
+ parent = parent->parent;
+
signal = dbus_message_new_signal(parent->path,
DBUS_INTERFACE_OBJECT_MANAGER,
"InterfacesRemoved");
@@ -1054,6 +1062,8 @@ static void append_object(gpointer data, gpointer user_data)
&child->path);
append_interfaces(child, &entry);
dbus_message_iter_close_container(array, &entry);
+
+ g_slist_foreach(child->objects, append_object, user_data);
}
static DBusMessage *get_objects(DBusConnection *connection,
@@ -1168,8 +1178,11 @@ static struct generic_data *object_path_ref(DBusConnection *connection,
add_interface(data, DBUS_INTERFACE_INTROSPECTABLE, introspect_methods,
NULL, NULL, data, NULL);
- add_interface(data, DBUS_INTERFACE_OBJECT_MANAGER, manager_methods,
- manager_signals, NULL, data, NULL);
+ /* Only root path export ObjectManager interface */
+ if (data->parent == NULL)
+ add_interface(data, DBUS_INTERFACE_OBJECT_MANAGER,
+ manager_methods, manager_signals,
+ NULL, data, NULL);
add_interface(data, DBUS_INTERFACE_PROPERTIES, properties_methods,
properties_signals, NULL, data, NULL);
--
1.7.12.2
^ permalink raw reply related
* [PATCH BlueZ v4 09/15] gdbus: Group interface changes to reduce the amount of signals emitted
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Luiz Augusto von Dentz
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
InterfacesAdded and InterfacesRemoved can group all the interfaces
changes together in one message.
---
gdbus/object.c | 362 +++++++++++++++++++++++++++++++++------------------------
1 file changed, 208 insertions(+), 154 deletions(-)
diff --git a/gdbus/object.c b/gdbus/object.c
index 6f5958a..5b5dc7e 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -45,6 +45,9 @@ struct generic_data {
char *path;
GSList *interfaces;
GSList *objects;
+ GSList *added;
+ GSList *removed;
+ guint process_id;
char *introspect;
struct generic_data *parent;
};
@@ -70,6 +73,8 @@ struct property_data {
DBusMessage *message;
};
+static gboolean process_changes(gpointer user_data);
+
static void print_arguments(GString *gstr, const GDBusArgInfo *args,
const char *direction)
{
@@ -491,21 +496,71 @@ static void reset_parent(gpointer data, gpointer user_data)
child->parent = parent;
}
-static void generic_unregister(DBusConnection *connection, void *user_data)
+static void append_properties(struct interface_data *data,
+ DBusMessageIter *iter)
{
- struct generic_data *data = user_data;
+ DBusMessageIter dict;
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+ /* TODO: list properties */
+
+ dbus_message_iter_close_container(iter, &dict);
+}
+
+static void append_interface(gpointer data, gpointer user_data)
+{
+ struct interface_data *iface = data;
+ DBusMessageIter *array = user_data;
+ DBusMessageIter entry;
+
+ dbus_message_iter_open_container(array, DBUS_TYPE_DICT_ENTRY, NULL,
+ &entry);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &iface->name);
+ append_properties(data, &entry);
+ dbus_message_iter_close_container(array, &entry);
+}
+
+static void emit_interfaces_added(struct generic_data *data)
+{
+ DBusMessage *signal;
+ DBusMessageIter iter, array;
struct generic_data *parent = data->parent;
- if (parent != NULL)
- parent->objects = g_slist_remove(parent->objects, data);
+ if (parent == NULL)
+ return;
- g_slist_foreach(data->objects, reset_parent, data->parent);
- g_slist_free(data->objects);
+ signal = dbus_message_new_signal(parent->path,
+ DBUS_INTERFACE_OBJECT_MANAGER,
+ "InterfacesAdded");
+ if (signal == NULL)
+ return;
- dbus_connection_unref(data->conn);
- g_free(data->introspect);
- g_free(data->path);
- g_free(data);
+ dbus_message_iter_init_append(signal, &iter);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+ &data->path);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array);
+
+ g_slist_foreach(data->added, append_interface, &array);
+ g_slist_free(data->added);
+ data->added = NULL;
+
+ dbus_message_iter_close_container(&iter, &array);
+
+ g_dbus_send_message(data->conn, signal);
}
static struct interface_data *find_interface(GSList *interfaces,
@@ -546,45 +601,37 @@ static gboolean g_dbus_args_have_signature(const GDBusArgInfo *args,
return TRUE;
}
-static DBusHandlerResult generic_message(DBusConnection *connection,
- DBusMessage *message, void *user_data)
+static gboolean remove_interface(struct generic_data *data, const char *name)
{
- struct generic_data *data = user_data;
struct interface_data *iface;
- const GDBusMethodTable *method;
- const char *interface;
- interface = dbus_message_get_interface(message);
-
- iface = find_interface(data->interfaces, interface);
+ iface = find_interface(data->interfaces, name);
if (iface == NULL)
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- for (method = iface->methods; method &&
- method->name && method->function; method++) {
- if (dbus_message_is_method_call(message, iface->name,
- method->name) == FALSE)
- continue;
+ return FALSE;
- if (g_dbus_args_have_signature(method->in_args,
- message) == FALSE)
- continue;
+ data->interfaces = g_slist_remove(data->interfaces, iface);
- if (check_privilege(connection, message, method,
- iface->user_data) == TRUE)
- return DBUS_HANDLER_RESULT_HANDLED;
+ if (iface->destroy) {
+ iface->destroy(iface->user_data);
+ iface->user_data = NULL;
+ }
- return process_message(connection, message, method,
- iface->user_data);
+ if (data->parent == NULL) {
+ g_free(iface->name);
+ g_free(iface);
+ return TRUE;
}
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
+ data->removed = g_slist_prepend(data->removed, iface->name);
+ g_free(iface);
-static DBusObjectPathVTable generic_table = {
- .unregister_function = generic_unregister,
- .message_function = generic_message,
-};
+ if (data->process_id > 0)
+ return TRUE;
+
+ data->process_id = g_idle_add(process_changes, data);
+
+ return TRUE;
+}
static struct generic_data *invalidate_parent_data(DBusConnection *conn,
const char *child_path)
@@ -636,12 +683,6 @@ done:
return data;
}
-static const GDBusMethodTable introspect_methods[] = {
- { GDBUS_METHOD("Introspect", NULL,
- GDBUS_ARGS({ "xml", "s" }), introspect) },
- { }
-};
-
static inline const GDBusPropertyTable *find_property(const GDBusPropertyTable *properties,
const char *name)
{
@@ -860,35 +901,128 @@ static const GDBusSignalTable properties_signals[] = {
{ }
};
-static void append_properties(struct interface_data *data,
- DBusMessageIter *iter)
+static void append_name(gpointer data, gpointer user_data)
{
- DBusMessageIter dict;
+ char *name = data;
+ DBusMessageIter *iter = user_data;
- dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &name);
+}
- /* TODO: list properties */
+static void emit_interfaces_removed(struct generic_data *data)
+{
+ DBusMessage *signal;
+ DBusMessageIter iter, array;
+ struct generic_data *parent = data->parent;
- dbus_message_iter_close_container(iter, &dict);
+ if (parent == NULL)
+ return;
+
+ signal = dbus_message_new_signal(parent->path,
+ DBUS_INTERFACE_OBJECT_MANAGER,
+ "InterfacesRemoved");
+ if (signal == NULL)
+ return;
+
+ dbus_message_iter_init_append(signal, &iter);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+ &data->path);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING, &array);
+
+ g_slist_foreach(data->removed, append_name, &array);
+ g_slist_free_full(data->removed, g_free);
+ data->removed = NULL;
+
+ dbus_message_iter_close_container(&iter, &array);
+
+ g_dbus_send_message(data->conn, signal);
}
-static void append_interface(gpointer data, gpointer user_data)
+static gboolean process_changes(gpointer user_data)
{
- struct interface_data *iface = data;
- DBusMessageIter *array = user_data;
- DBusMessageIter entry;
+ struct generic_data *data = user_data;
- dbus_message_iter_open_container(array, DBUS_TYPE_DICT_ENTRY, NULL,
- &entry);
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &iface->name);
- append_properties(data, &entry);
- dbus_message_iter_close_container(array, &entry);
+ data->process_id = 0;
+
+ if (data->added != NULL)
+ emit_interfaces_added(data);
+
+ if (data->removed != NULL)
+ emit_interfaces_removed(data);
+
+ return FALSE;
}
+static void generic_unregister(DBusConnection *connection, void *user_data)
+{
+ struct generic_data *data = user_data;
+ struct generic_data *parent = data->parent;
+
+ if (parent != NULL)
+ parent->objects = g_slist_remove(parent->objects, data);
+
+ if (data->process_id > 0) {
+ g_source_remove(data->process_id);
+ if (data->removed != NULL)
+ emit_interfaces_removed(data);
+ }
+
+ g_slist_foreach(data->objects, reset_parent, data->parent);
+ g_slist_free(data->objects);
+
+ dbus_connection_unref(data->conn);
+ g_free(data->introspect);
+ g_free(data->path);
+ g_free(data);
+}
+
+static DBusHandlerResult generic_message(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct generic_data *data = user_data;
+ struct interface_data *iface;
+ const GDBusMethodTable *method;
+ const char *interface;
+
+ interface = dbus_message_get_interface(message);
+
+ iface = find_interface(data->interfaces, interface);
+ if (iface == NULL)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ for (method = iface->methods; method &&
+ method->name && method->function; method++) {
+ if (dbus_message_is_method_call(message, iface->name,
+ method->name) == FALSE)
+ continue;
+
+ if (g_dbus_args_have_signature(method->in_args,
+ message) == FALSE)
+ continue;
+
+ if (check_privilege(connection, message, method,
+ iface->user_data) == TRUE)
+ return DBUS_HANDLER_RESULT_HANDLED;
+
+ return process_message(connection, message, method,
+ iface->user_data);
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static DBusObjectPathVTable generic_table = {
+ .unregister_function = generic_unregister,
+ .message_function = generic_message,
+};
+
+static const GDBusMethodTable introspect_methods[] = {
+ { GDBUS_METHOD("Introspect", NULL,
+ GDBUS_ARGS({ "xml", "s" }), introspect) },
+ { }
+};
+
static void append_interfaces(struct generic_data *data, DBusMessageIter *iter)
{
DBusMessageIter array;
@@ -973,43 +1107,6 @@ static const GDBusSignalTable manager_signals[] = {
{ }
};
-static void emit_interface_added(struct generic_data *data,
- struct interface_data *iface)
-{
- DBusMessage *signal;
- DBusMessageIter iter, array;
- struct generic_data *parent = data->parent;
-
- if (parent == NULL)
- return;
-
- signal = dbus_message_new_signal(parent->path,
- DBUS_INTERFACE_OBJECT_MANAGER,
- "InterfacesAdded");
- if (signal == NULL)
- return;
-
- dbus_message_iter_init_append(signal, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &data->path);
-
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_ARRAY_AS_STRING
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array);
-
- append_interface(iface, &array);
-
- dbus_message_iter_close_container(&iter, &array);
-
- g_dbus_send_message(data->conn, signal);
-}
-
static void add_interface(struct generic_data *data,
const char *name,
const GDBusMethodTable *methods,
@@ -1029,8 +1126,14 @@ static void add_interface(struct generic_data *data,
iface->destroy = destroy;
data->interfaces = g_slist_append(data->interfaces, iface);
+ if (data->parent == NULL)
+ return;
+
+ data->added = g_slist_append(data->added, iface);
+ if (data->process_id > 0)
+ return;
- emit_interface_added(data, iface);
+ data->process_id = g_idle_add(process_changes, data);
}
static struct generic_data *object_path_ref(DBusConnection *connection,
@@ -1074,55 +1177,6 @@ static struct generic_data *object_path_ref(DBusConnection *connection,
return data;
}
-static void emit_interface_remove(struct generic_data *data,
- struct interface_data *iface)
-{
- DBusMessage *signal;
- DBusMessageIter iter, array;
- struct generic_data *parent = data->parent;
-
- if (parent == NULL)
- return;
-
- signal = dbus_message_new_signal(parent->path,
- DBUS_INTERFACE_OBJECT_MANAGER,
- "InterfacesRemoved");
- if (signal == NULL)
- return;
-
- dbus_message_iter_init_append(signal, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &data->path);
-
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_STRING_AS_STRING, &array);
- dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &iface->name);
- dbus_message_iter_close_container(&iter, &array);
-
- g_dbus_send_message(data->conn, signal);
-}
-
-static gboolean remove_interface(struct generic_data *data, const char *name)
-{
- struct interface_data *iface;
-
- iface = find_interface(data->interfaces, name);
- if (iface == NULL)
- return FALSE;
-
- emit_interface_remove(data, iface);
-
- data->interfaces = g_slist_remove(data->interfaces, iface);
-
- if (iface->destroy)
- iface->destroy(iface->user_data);
-
- g_free(iface->name);
- g_free(iface);
-
- return TRUE;
-}
-
static void object_path_unref(DBusConnection *connection, const char *path)
{
struct generic_data *data = NULL;
@@ -1143,9 +1197,9 @@ static void object_path_unref(DBusConnection *connection, const char *path)
remove_interface(data, DBUS_INTERFACE_PROPERTIES);
remove_interface(data, DBUS_INTERFACE_OBJECT_MANAGER);
- invalidate_parent_data(connection, path);
+ invalidate_parent_data(data->conn, data->path);
- dbus_connection_unregister_object_path(connection, path);
+ dbus_connection_unregister_object_path(data->conn, data->path);
}
static gboolean check_signal(DBusConnection *conn, const char *path,
@@ -1270,7 +1324,7 @@ gboolean g_dbus_unregister_interface(DBusConnection *connection,
g_free(data->introspect);
data->introspect = NULL;
- object_path_unref(connection, path);
+ object_path_unref(connection, data->path);
return TRUE;
}
--
1.7.12.2
^ permalink raw reply related
* [PATCH BlueZ v4 08/15] gdbus: Add support for org.freedesktop.DBus.ObjectManager interface
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Luiz Augusto von Dentz
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This implements initial support for ObjectManager, it automatically adds
objects to its parents so no action is needed by daemons to get their
objects managed by this interface.
ObjectManager is part of D-Bus spec since revision 0.17:
http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager
---
gdbus/object.c | 247 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 237 insertions(+), 10 deletions(-)
diff --git a/gdbus/object.c b/gdbus/object.c
index c145328..6f5958a 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -37,10 +37,16 @@
#define error(fmt...)
#define debug(fmt...)
+#define DBUS_INTERFACE_OBJECT_MANAGER "org.freedesktop.DBus.ObjectManager"
+
struct generic_data {
unsigned int refcount;
+ DBusConnection *conn;
+ char *path;
GSList *interfaces;
+ GSList *objects;
char *introspect;
+ struct generic_data *parent;
};
struct interface_data {
@@ -477,11 +483,28 @@ void g_dbus_pending_property_error(DBusConnection *connection,
va_end(args);
}
+static void reset_parent(gpointer data, gpointer user_data)
+{
+ struct generic_data *child = data;
+ struct generic_data *parent = user_data;
+
+ child->parent = parent;
+}
+
static void generic_unregister(DBusConnection *connection, void *user_data)
{
struct generic_data *data = user_data;
+ struct generic_data *parent = data->parent;
+ if (parent != NULL)
+ parent->objects = g_slist_remove(parent->objects, data);
+
+ g_slist_foreach(data->objects, reset_parent, data->parent);
+ g_slist_free(data->objects);
+
+ dbus_connection_unref(data->conn);
g_free(data->introspect);
+ g_free(data->path);
g_free(data);
}
@@ -563,9 +586,10 @@ static DBusObjectPathVTable generic_table = {
.message_function = generic_message,
};
-static void invalidate_parent_data(DBusConnection *conn, const char *child_path)
+static struct generic_data *invalidate_parent_data(DBusConnection *conn,
+ const char *child_path)
{
- struct generic_data *data = NULL;
+ struct generic_data *data = NULL, *child = NULL, *parent = NULL;
char *parent_path, *slash;
parent_path = g_strdup(child_path);
@@ -586,16 +610,30 @@ static void invalidate_parent_data(DBusConnection *conn, const char *child_path)
goto done;
}
- invalidate_parent_data(conn, parent_path);
+ parent = invalidate_parent_data(conn, parent_path);
- if (data == NULL)
- goto done;
+ if (data == NULL) {
+ data = parent;
+ if (data == NULL)
+ goto done;
+ }
g_free(data->introspect);
data->introspect = NULL;
+ if (!dbus_connection_get_object_path_data(conn, child_path,
+ (void *) &child))
+ goto done;
+
+ if (child == NULL || g_slist_find(data->objects, child) != NULL)
+ goto done;
+
+ data->objects = g_slist_prepend(data->objects, child);
+ child->parent = data;
+
done:
g_free(parent_path);
+ return data;
}
static const GDBusMethodTable introspect_methods[] = {
@@ -822,7 +860,158 @@ static const GDBusSignalTable properties_signals[] = {
{ }
};
-static void add_interface(struct generic_data *data, const char *name,
+static void append_properties(struct interface_data *data,
+ DBusMessageIter *iter)
+{
+ DBusMessageIter dict;
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+ /* TODO: list properties */
+
+ dbus_message_iter_close_container(iter, &dict);
+}
+
+static void append_interface(gpointer data, gpointer user_data)
+{
+ struct interface_data *iface = data;
+ DBusMessageIter *array = user_data;
+ DBusMessageIter entry;
+
+ dbus_message_iter_open_container(array, DBUS_TYPE_DICT_ENTRY, NULL,
+ &entry);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &iface->name);
+ append_properties(data, &entry);
+ dbus_message_iter_close_container(array, &entry);
+}
+
+static void append_interfaces(struct generic_data *data, DBusMessageIter *iter)
+{
+ DBusMessageIter array;
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array);
+
+ g_slist_foreach(data->interfaces, append_interface, &array);
+
+ dbus_message_iter_close_container(iter, &array);
+}
+
+static void append_object(gpointer data, gpointer user_data)
+{
+ struct generic_data *child = data;
+ DBusMessageIter *array = user_data;
+ DBusMessageIter entry;
+
+ dbus_message_iter_open_container(array, DBUS_TYPE_DICT_ENTRY, NULL,
+ &entry);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
+ &child->path);
+ append_interfaces(child, &entry);
+ dbus_message_iter_close_container(array, &entry);
+}
+
+static DBusMessage *get_objects(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct generic_data *data = user_data;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusMessageIter array;
+
+ reply = dbus_message_new_method_return(message);
+ if (reply == NULL)
+ return NULL;
+
+ dbus_message_iter_init_append(reply, &iter);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_OBJECT_PATH_AS_STRING
+ DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &array);
+
+ g_slist_foreach(data->objects, append_object, &array);
+
+ dbus_message_iter_close_container(&iter, &array);
+
+ return reply;
+}
+
+static const GDBusMethodTable manager_methods[] = {
+ { GDBUS_METHOD("GetManagedObjects", NULL,
+ GDBUS_ARGS({ "objects", "a{oa{sa{sv}}}" }), get_objects) },
+ { }
+};
+
+static const GDBusSignalTable manager_signals[] = {
+ { GDBUS_SIGNAL("InterfacesAdded",
+ GDBUS_ARGS({ "object", "o" },
+ { "interfaces", "a{sa{sv}}" })) },
+ { GDBUS_SIGNAL("InterfacesRemoved",
+ GDBUS_ARGS({ "object", "o" }, { "interfaces", "as" })) },
+ { }
+};
+
+static void emit_interface_added(struct generic_data *data,
+ struct interface_data *iface)
+{
+ DBusMessage *signal;
+ DBusMessageIter iter, array;
+ struct generic_data *parent = data->parent;
+
+ if (parent == NULL)
+ return;
+
+ signal = dbus_message_new_signal(parent->path,
+ DBUS_INTERFACE_OBJECT_MANAGER,
+ "InterfacesAdded");
+ if (signal == NULL)
+ return;
+
+ dbus_message_iter_init_append(signal, &iter);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+ &data->path);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array);
+
+ append_interface(iface, &array);
+
+ dbus_message_iter_close_container(&iter, &array);
+
+ g_dbus_send_message(data->conn, signal);
+}
+
+static void add_interface(struct generic_data *data,
+ const char *name,
const GDBusMethodTable *methods,
const GDBusSignalTable *signals,
const GDBusPropertyTable *properties,
@@ -840,6 +1029,8 @@ static void add_interface(struct generic_data *data, const char *name,
iface->destroy = destroy;
data->interfaces = g_slist_append(data->interfaces, iface);
+
+ emit_interface_added(data, iface);
}
static struct generic_data *object_path_ref(DBusConnection *connection,
@@ -856,6 +1047,8 @@ static struct generic_data *object_path_ref(DBusConnection *connection,
}
data = g_new0(struct generic_data, 1);
+ data->conn = dbus_connection_ref(connection);
+ data->path = g_strdup(path);
data->refcount = 1;
data->introspect = g_strdup(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<node></node>");
@@ -869,8 +1062,11 @@ static struct generic_data *object_path_ref(DBusConnection *connection,
invalidate_parent_data(connection, path);
- add_interface(data, DBUS_INTERFACE_INTROSPECTABLE,
- introspect_methods, NULL, NULL, data, NULL);
+ add_interface(data, DBUS_INTERFACE_INTROSPECTABLE, introspect_methods,
+ NULL, NULL, data, NULL);
+
+ add_interface(data, DBUS_INTERFACE_OBJECT_MANAGER, manager_methods,
+ manager_signals, NULL, data, NULL);
add_interface(data, DBUS_INTERFACE_PROPERTIES, properties_methods,
properties_signals, NULL, data, NULL);
@@ -878,6 +1074,34 @@ static struct generic_data *object_path_ref(DBusConnection *connection,
return data;
}
+static void emit_interface_remove(struct generic_data *data,
+ struct interface_data *iface)
+{
+ DBusMessage *signal;
+ DBusMessageIter iter, array;
+ struct generic_data *parent = data->parent;
+
+ if (parent == NULL)
+ return;
+
+ signal = dbus_message_new_signal(parent->path,
+ DBUS_INTERFACE_OBJECT_MANAGER,
+ "InterfacesRemoved");
+ if (signal == NULL)
+ return;
+
+ dbus_message_iter_init_append(signal, &iter);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+ &data->path);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING, &array);
+ dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &iface->name);
+ dbus_message_iter_close_container(&iter, &array);
+
+ g_dbus_send_message(data->conn, signal);
+}
+
static gboolean remove_interface(struct generic_data *data, const char *name)
{
struct interface_data *iface;
@@ -886,6 +1110,8 @@ static gboolean remove_interface(struct generic_data *data, const char *name)
if (iface == NULL)
return FALSE;
+ emit_interface_remove(data, iface);
+
data->interfaces = g_slist_remove(data->interfaces, iface);
if (iface->destroy)
@@ -915,6 +1141,7 @@ static void object_path_unref(DBusConnection *connection, const char *path)
remove_interface(data, DBUS_INTERFACE_INTROSPECTABLE);
remove_interface(data, DBUS_INTERFACE_PROPERTIES);
+ remove_interface(data, DBUS_INTERFACE_OBJECT_MANAGER);
invalidate_parent_data(connection, path);
@@ -1013,8 +1240,8 @@ gboolean g_dbus_register_interface(DBusConnection *connection,
return FALSE;
}
- add_interface(data, name, methods, signals,
- properties, user_data, destroy);
+ add_interface(data, name, methods, signals, properties, user_data,
+ destroy);
g_free(data->introspect);
data->introspect = NULL;
--
1.7.12.2
^ permalink raw reply related
* [PATCH BlueZ v4 07/15] gdbus: Add properties into Introspectable interface
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>
From: Lucas De Marchi <lucas.demarchi@profusion.mobi>
---
gdbus/object.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/gdbus/object.c b/gdbus/object.c
index 4509f76..c145328 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -95,6 +95,7 @@ static void generate_interface_xml(GString *gstr, struct interface_data *iface)
{
const GDBusMethodTable *method;
const GDBusSignalTable *signal;
+ const GDBusPropertyTable *property;
for (method = iface->methods; method && method->name; method++) {
gboolean deprecated = method->flags &
@@ -147,6 +148,24 @@ static void generate_interface_xml(GString *gstr, struct interface_data *iface)
g_string_append_printf(gstr, "\t\t</signal>\n");
}
}
+
+ for (property = iface->properties; property && property->name;
+ property++) {
+ gboolean deprecated = property->flags &
+ G_DBUS_PROPERTY_FLAG_DEPRECATED;
+
+ g_string_append_printf(gstr, "\t\t<property name=\"%s\""
+ " type=\"%s\" access=\"%s%s\"",
+ property->name, property->type,
+ property->get ? "read" : "",
+ property->set ? "write" : "");
+
+ if (!deprecated)
+ g_string_append_printf(gstr, "/>\n");
+ else
+ g_string_append_printf(gstr,
+ G_DBUS_ANNOTATE_DEPRECATED(">\n\t\t\t"));
+ }
}
static void generate_introspection_xml(DBusConnection *conn,
--
1.7.12.2
^ permalink raw reply related
* [PATCH BlueZ v4 06/15] gdbus: Implement DBus.Properties.Set method
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>
From: Lucas De Marchi <lucas.demarchi@profusion.mobi>
Contrary to Get() and GetAll(), Set() is asynchronous so we pass an id
to the setter so later it can declare the Set() as successful or
otherwise.
---
gdbus/gdbus.h | 16 +++++++
gdbus/object.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 157 insertions(+), 1 deletion(-)
diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index b2e78c4..ec7b1ef 100644
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -69,6 +69,12 @@ typedef DBusMessage * (* GDBusMethodFunction) (DBusConnection *connection,
typedef gboolean (*GDBusPropertyGetter)(const GDBusPropertyTable *property,
DBusMessageIter *iter, void *data);
+typedef guint32 GDBusPendingPropertySet;
+
+typedef void (*GDBusPropertySetter)(const GDBusPropertyTable *property,
+ DBusMessageIter *value, GDBusPendingPropertySet id,
+ void *data);
+
typedef gboolean (*GDBusPropertyExists)(const GDBusPropertyTable *property,
void *data);
@@ -123,6 +129,7 @@ struct GDBusPropertyTable {
const char *name;
const char *type;
GDBusPropertyGetter get;
+ GDBusPropertySetter set;
GDBusPropertyExists exists;
GDBusPropertyFlags flags;
};
@@ -239,6 +246,15 @@ guint g_dbus_add_signal_watch(DBusConnection *connection,
gboolean g_dbus_remove_watch(DBusConnection *connection, guint tag);
void g_dbus_remove_all_watches(DBusConnection *connection);
+void g_dbus_pending_property_success(DBusConnection *connection,
+ GDBusPendingPropertySet id);
+void g_dbus_pending_property_error_valist(DBusConnection *connection,
+ GDBusPendingReply id, const char *name,
+ const char *format, va_list args);
+void g_dbus_pending_property_error(DBusConnection *connection,
+ GDBusPendingReply id, const char *name,
+ const char *format, ...);
+
#ifdef __cplusplus
}
#endif
diff --git a/gdbus/object.c b/gdbus/object.c
index c6e4a53..4509f76 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -59,6 +59,11 @@ struct security_data {
void *iface_user_data;
};
+struct property_data {
+ GDBusPendingPropertySet id;
+ DBusMessage *message;
+};
+
static void print_arguments(GString *gstr, const GDBusArgInfo *args,
const char *direction)
{
@@ -380,6 +385,79 @@ static gboolean check_privilege(DBusConnection *conn, DBusMessage *msg,
return FALSE;
}
+static GDBusPendingPropertySet next_pending_property = 1;
+static GSList *pending_property_set;
+
+static struct property_data *remove_pending_property_data(
+ GDBusPendingPropertySet id)
+{
+ struct property_data *propdata;
+ GSList *l;
+
+ for (l = pending_property_set; l != NULL; l = l->next) {
+ propdata = l->data;
+ if (propdata->id != id)
+ continue;
+ }
+
+ if (l == NULL)
+ return NULL;
+
+ pending_property_set = g_slist_delete_link(pending_property_set, l);
+
+ return propdata;
+}
+
+void g_dbus_pending_property_success(DBusConnection *connection,
+ GDBusPendingPropertySet id)
+{
+ struct property_data *propdata;
+
+ propdata = remove_pending_property_data(id);
+ if (propdata == NULL)
+ return;
+
+ g_dbus_send_reply(connection, propdata->message, DBUS_TYPE_INVALID);
+ dbus_message_unref(propdata->message);
+ g_free(propdata);
+}
+
+void g_dbus_pending_property_error_valist(DBusConnection *connection,
+ GDBusPendingReply id, const char *name,
+ const char *format, va_list args)
+{
+ struct property_data *propdata;
+ DBusMessage *reply;
+
+ propdata = remove_pending_property_data(id);
+ if (propdata == NULL)
+ return;
+
+ reply = g_dbus_create_error_valist(propdata->message, name, format,
+ args);
+ if (reply != NULL) {
+ dbus_connection_send(connection, reply, NULL);
+ dbus_message_unref(reply);
+ }
+
+ dbus_message_unref(propdata->message);
+ g_free(propdata);
+}
+
+void g_dbus_pending_property_error(DBusConnection *connection,
+ GDBusPendingReply id, const char *name,
+ const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+
+ g_dbus_pending_property_error_valist(connection, id, name, format,
+ args);
+
+ va_end(args);
+}
+
static void generic_unregister(DBusConnection *connection, void *user_data)
{
struct generic_data *data = user_data;
@@ -636,7 +714,69 @@ static DBusMessage *properties_get_all(DBusConnection *connection,
static DBusMessage *properties_set(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- return dbus_message_new_method_return(message);
+ struct generic_data *data = user_data;
+ DBusMessageIter iter, sub;
+ struct interface_data *iface;
+ const GDBusPropertyTable *property;
+ const char *name, *interface;
+ struct property_data *propdata;
+
+ if (!dbus_message_iter_init(message, &iter))
+ return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
+ "No arguments given");
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
+ "Invalid argument type: '%c'",
+ dbus_message_iter_get_arg_type(&iter));
+
+ dbus_message_iter_get_basic(&iter, &name);
+ dbus_message_iter_next(&iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
+ "Invalid argument type: '%c'",
+ dbus_message_iter_get_arg_type(&iter));
+
+ dbus_message_iter_get_basic(&iter, &interface);
+ dbus_message_iter_next(&iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
+ return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
+ "Invalid argument type: '%c'",
+ dbus_message_iter_get_arg_type(&iter));
+
+ dbus_message_iter_recurse(&iter, &sub);
+
+ iface = find_interface(data->interfaces, interface);
+ if (iface == NULL)
+ return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
+ "No such interface '%s'", interface);
+
+ property = find_property(iface->properties, name);
+ if (property == NULL)
+ return g_dbus_create_error(message,
+ DBUS_ERROR_UNKNOWN_PROPERTY,
+ "No such property '%s'", name);
+
+ if (property->set == NULL)
+ return g_dbus_create_error(message,
+ DBUS_ERROR_PROPERTY_READ_ONLY,
+ "Property '%s' is not writable", name);
+
+ if (property->exists != NULL &&
+ !property->exists(property, iface->user_data))
+ return g_dbus_create_error(message,
+ DBUS_ERROR_UNKNOWN_PROPERTY,
+ "No such property '%s'", name);
+
+ propdata = g_new(struct property_data, 1);
+ propdata->id = next_pending_property++;
+ propdata->message = dbus_message_ref(message);
+
+ property->set(property, &sub, propdata->id, iface->user_data);
+
+ return NULL;
}
static const GDBusMethodTable properties_methods[] = {
--
1.7.12.2
^ permalink raw reply related
* [PATCH BlueZ v4 05/15] gdbus: Implement DBus.Properties.GetAll method
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>
From: Lucas De Marchi <lucas.demarchi@profusion.mobi>
---
gdbus/object.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 55 insertions(+), 1 deletion(-)
diff --git a/gdbus/object.c b/gdbus/object.c
index 89138f7..c6e4a53 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -576,7 +576,61 @@ static DBusMessage *properties_get(DBusConnection *connection,
static DBusMessage *properties_get_all(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- return NULL;
+ struct generic_data *data = user_data;
+ struct interface_data *iface;
+ const GDBusPropertyTable *p;
+ const char *interface;
+ DBusMessageIter iter, dict;
+ DBusMessage *reply;
+
+ if (!dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &interface,
+ DBUS_TYPE_INVALID))
+ return NULL;
+
+ iface = find_interface(data->interfaces, interface);
+ if (iface == NULL)
+ return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
+ "No such interface '%s'", interface);
+
+ reply = dbus_message_new_method_return(message);
+ if (reply == NULL)
+ return NULL;
+
+ dbus_message_iter_init_append(reply, &iter);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+ for (p = iface->properties; p && p->name; p++) {
+ DBusMessageIter entry, value;
+
+ if (p->get == NULL)
+ continue;
+
+ if (p->exists != NULL && !p->exists(p, iface->user_data))
+ continue;
+
+ dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
+ p->name);
+ dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
+ p->type, &value);
+
+ if (!p->get(p, &value, iface->user_data)) {
+ dbus_message_unref(reply);
+ return NULL;
+ }
+
+ dbus_message_iter_close_container(&entry, &value);
+ dbus_message_iter_close_container(&dict, &entry);
+ }
+
+ dbus_message_iter_close_container(&iter, &dict);
+
+ return reply;
}
static DBusMessage *properties_set(DBusConnection *connection,
--
1.7.12.2
^ permalink raw reply related
* [PATCH BlueZ v4 04/15] gdbus: Implement DBus.Properties.Get method
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>
From: Lucas De Marchi <lucas.demarchi@profusion.mobi>
---
gdbus/gdbus.h | 8 ++++++++
gdbus/object.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 69 insertions(+), 1 deletion(-)
diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index 34e3cb3..b2e78c4 100644
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -66,6 +66,12 @@ typedef void (* GDBusDestroyFunction) (void *user_data);
typedef DBusMessage * (* GDBusMethodFunction) (DBusConnection *connection,
DBusMessage *message, void *user_data);
+typedef gboolean (*GDBusPropertyGetter)(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data);
+
+typedef gboolean (*GDBusPropertyExists)(const GDBusPropertyTable *property,
+ void *data);
+
typedef guint32 GDBusPendingReply;
typedef void (* GDBusSecurityFunction) (DBusConnection *connection,
@@ -116,6 +122,8 @@ struct GDBusSignalTable {
struct GDBusPropertyTable {
const char *name;
const char *type;
+ GDBusPropertyGetter get;
+ GDBusPropertyExists exists;
GDBusPropertyFlags flags;
};
diff --git a/gdbus/object.c b/gdbus/object.c
index 6c11528..89138f7 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -507,10 +507,70 @@ static const GDBusMethodTable introspect_methods[] = {
{ }
};
+static inline const GDBusPropertyTable *find_property(const GDBusPropertyTable *properties,
+ const char *name)
+{
+ const GDBusPropertyTable *p;
+
+ for (p = properties; p && p->name; p++) {
+ if (strcmp(name, p->name) == 0)
+ return p;
+ }
+
+ return NULL;
+}
+
static DBusMessage *properties_get(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- return NULL;
+ struct generic_data *data = user_data;
+ struct interface_data *iface;
+ const GDBusPropertyTable *property;
+ const char *interface, *name;
+ DBusMessageIter iter, value;
+ DBusMessage *reply;
+
+ if (!dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &interface,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_INVALID))
+ return NULL;
+
+ iface = find_interface(data->interfaces, interface);
+ if (iface == NULL)
+ return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
+ "No such interface '%s'", interface);
+
+ property = find_property(iface->properties, name);
+ if (property == NULL)
+ return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
+ "No such property '%s'", name);
+
+ if (property->exists != NULL &&
+ !property->exists(property, iface->user_data))
+ return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
+ "No such property '%s'", name);
+
+ if (property->get == NULL)
+ return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS,
+ "Property '%s' is not readable", name);
+
+ reply = dbus_message_new_method_return(message);
+ if (reply == NULL)
+ return NULL;
+
+ dbus_message_iter_init_append(reply, &iter);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
+ property->type, &value);
+
+ if (!property->get(property, &value, iface->user_data)) {
+ dbus_message_unref(reply);
+ return NULL;
+ }
+
+ dbus_message_iter_close_container(&iter, &value);
+
+ return reply;
}
static DBusMessage *properties_get_all(DBusConnection *connection,
--
1.7.12.2
^ permalink raw reply related
* [PATCH BlueZ v4 03/15] gdbus: Add skeleton of DBus.Properties interface
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>
From: Lucas De Marchi <lucas.demarchi@profusion.mobi>
This interface is responsible for handling properties of all objects in
a given path. Right now it only registers itself, doing nothing useful.
A conversion to this new layout will be done by subsequent patches.
org.freedesktop.org.DBus.Properties spec can be found at
http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties
---
gdbus/object.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/gdbus/object.c b/gdbus/object.c
index 24e8285..6c11528 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -507,6 +507,48 @@ static const GDBusMethodTable introspect_methods[] = {
{ }
};
+static DBusMessage *properties_get(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ return NULL;
+}
+
+static DBusMessage *properties_get_all(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ return NULL;
+}
+
+static DBusMessage *properties_set(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ return dbus_message_new_method_return(message);
+}
+
+static const GDBusMethodTable properties_methods[] = {
+ { GDBUS_METHOD("Get",
+ GDBUS_ARGS({ "interface", "s" }, { "name", "s" }),
+ GDBUS_ARGS({ "value", "v" }),
+ properties_get) },
+ { GDBUS_ASYNC_METHOD("Set", NULL,
+ GDBUS_ARGS({ "interface", "s" }, { "name", "s" },
+ { "value", "v" }),
+ properties_set) },
+ { GDBUS_METHOD("GetAll",
+ GDBUS_ARGS({ "interface", "s" }),
+ GDBUS_ARGS({ "properties", "a{sv}" }),
+ properties_get_all) },
+ { }
+};
+
+static const GDBusSignalTable properties_signals[] = {
+ { GDBUS_SIGNAL("PropertiesChanged",
+ GDBUS_ARGS({ "interface", "s" },
+ { "changed_properties", "a{sv}" },
+ { "invalidated_properties", "as"})) },
+ { }
+};
+
static void add_interface(struct generic_data *data, const char *name,
const GDBusMethodTable *methods,
const GDBusSignalTable *signals,
@@ -557,6 +599,9 @@ static struct generic_data *object_path_ref(DBusConnection *connection,
add_interface(data, DBUS_INTERFACE_INTROSPECTABLE,
introspect_methods, NULL, NULL, data, NULL);
+ add_interface(data, DBUS_INTERFACE_PROPERTIES, properties_methods,
+ properties_signals, NULL, data, NULL);
+
return data;
}
@@ -596,6 +641,7 @@ static void object_path_unref(DBusConnection *connection, const char *path)
return;
remove_interface(data, DBUS_INTERFACE_INTROSPECTABLE);
+ remove_interface(data, DBUS_INTERFACE_PROPERTIES);
invalidate_parent_data(connection, path);
--
1.7.12.2
^ permalink raw reply related
* [PATCH BlueZ v4 02/15] gdbus: Use macros to add annotations
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>
From: Lucas De Marchi <lucas.demarchi@profusion.mobi>
Besides being more readable this way it avoids going over 80 chars.
---
gdbus/object.c | 40 ++++++++++++++++++++++++++++------------
1 file changed, 28 insertions(+), 12 deletions(-)
diff --git a/gdbus/object.c b/gdbus/object.c
index 9689006..24e8285 100644
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -76,6 +76,16 @@ static void print_arguments(GString *gstr, const GDBusArgInfo *args,
}
}
+#define G_DBUS_ANNOTATE(prefix_, name_, value_) \
+ prefix_ "<annotation name=\"org.freedesktop.DBus." name_ "\" " \
+ "value=\"" value_ "\"/>\n"
+
+#define G_DBUS_ANNOTATE_DEPRECATED(prefix_) \
+ G_DBUS_ANNOTATE(prefix_, "Deprecated", "true")
+
+#define G_DBUS_ANNOTATE_NOREPLY(prefix_) \
+ G_DBUS_ANNOTATE(prefix_, "Method.NoReply", "true")
+
static void generate_interface_xml(GString *gstr, struct interface_data *iface)
{
const GDBusMethodTable *method;
@@ -90,19 +100,22 @@ static void generate_interface_xml(GString *gstr, struct interface_data *iface)
if (!deprecated && !noreply &&
!(method->in_args && method->in_args->name) &&
!(method->out_args && method->out_args->name))
- g_string_append_printf(gstr, "\t\t<method name=\"%s\"/>\n",
- method->name);
+ g_string_append_printf(gstr,
+ "\t\t<method name=\"%s\"/>\n",
+ method->name);
else {
- g_string_append_printf(gstr, "\t\t<method name=\"%s\">\n",
- method->name);
+ g_string_append_printf(gstr,
+ "\t\t<method name=\"%s\">\n",
+ method->name);
print_arguments(gstr, method->in_args, "in");
print_arguments(gstr, method->out_args, "out");
if (deprecated)
- g_string_append_printf(gstr, "\t\t\t<annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n");
-
+ g_string_append_printf(gstr,
+ G_DBUS_ANNOTATE_DEPRECATED("\t\t\t"));
if (noreply)
- g_string_append_printf(gstr, "\t\t\t<annotation name=\"org.freedesktop.DBus.Method.NoReply\" value=\"true\"/>\n");
+ g_string_append_printf(gstr,
+ G_DBUS_ANNOTATE_NOREPLY("\t\t\t"));
g_string_append_printf(gstr, "\t\t</method>\n");
}
@@ -113,15 +126,18 @@ static void generate_interface_xml(GString *gstr, struct interface_data *iface)
G_DBUS_SIGNAL_FLAG_DEPRECATED;
if (!deprecated && !(signal->args && signal->args->name))
- g_string_append_printf(gstr, "\t\t<signal name=\"%s\"/>\n",
- signal->name);
+ g_string_append_printf(gstr,
+ "\t\t<signal name=\"%s\"/>\n",
+ signal->name);
else {
- g_string_append_printf(gstr, "\t\t<signal name=\"%s\">\n",
- signal->name);
+ g_string_append_printf(gstr,
+ "\t\t<signal name=\"%s\">\n",
+ signal->name);
print_arguments(gstr, signal->args, NULL);
if (deprecated)
- g_string_append_printf(gstr, "\t\t\t<annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n");
+ g_string_append_printf(gstr,
+ G_DBUS_ANNOTATE_DEPRECATED("\t\t\t"));
g_string_append_printf(gstr, "\t\t</signal>\n");
}
--
1.7.12.2
^ permalink raw reply related
* [PATCH BlueZ v4 01/15] gdbus: Move typedefs up
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>
From: Lucas De Marchi <lucas.demarchi@profusion.mobi>
Move the typedefs up so they can be used by functions and callbacks.
---
gdbus/gdbus.h | 47 +++++++++++++++++++++++++++++------------------
1 file changed, 29 insertions(+), 18 deletions(-)
diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index 0a8a27c..34e3cb3 100644
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -31,6 +31,17 @@ extern "C" {
#include <dbus/dbus.h>
#include <glib.h>
+typedef enum GDBusMethodFlags GDBusMethodFlags;
+typedef enum GDBusSignalFlags GDBusSignalFlags;
+typedef enum GDBusPropertyFlags GDBusPropertyFlags;
+typedef enum GDBusSecurityFlags GDBusSecurityFlags;
+
+typedef struct GDBusArgInfo GDBusArgInfo;
+typedef struct GDBusMethodTable GDBusMethodTable;
+typedef struct GDBusSignalTable GDBusSignalTable;
+typedef struct GDBusPropertyTable GDBusPropertyTable;
+typedef struct GDBusSecurityTable GDBusSecurityTable;
+
typedef void (* GDBusWatchFunction) (DBusConnection *connection,
void *user_data);
@@ -62,58 +73,58 @@ typedef void (* GDBusSecurityFunction) (DBusConnection *connection,
gboolean interaction,
GDBusPendingReply pending);
-typedef enum {
+enum GDBusMethodFlags {
G_DBUS_METHOD_FLAG_DEPRECATED = (1 << 0),
G_DBUS_METHOD_FLAG_NOREPLY = (1 << 1),
G_DBUS_METHOD_FLAG_ASYNC = (1 << 2),
-} GDBusMethodFlags;
+};
-typedef enum {
+enum GDBusSignalFlags {
G_DBUS_SIGNAL_FLAG_DEPRECATED = (1 << 0),
-} GDBusSignalFlags;
+};
-typedef enum {
+enum GDBusPropertyFlags {
G_DBUS_PROPERTY_FLAG_DEPRECATED = (1 << 0),
-} GDBusPropertyFlags;
+};
-typedef enum {
+enum GDBusSecurityFlags {
G_DBUS_SECURITY_FLAG_DEPRECATED = (1 << 0),
G_DBUS_SECURITY_FLAG_BUILTIN = (1 << 1),
G_DBUS_SECURITY_FLAG_ALLOW_INTERACTION = (1 << 2),
-} GDBusSecurityFlags;
+};
-typedef struct {
+struct GDBusArgInfo {
const char *name;
const char *signature;
-} GDBusArgInfo;
+};
-typedef struct {
+struct GDBusMethodTable {
const char *name;
GDBusMethodFunction function;
GDBusMethodFlags flags;
unsigned int privilege;
const GDBusArgInfo *in_args;
const GDBusArgInfo *out_args;
-} GDBusMethodTable;
+};
-typedef struct {
+struct GDBusSignalTable {
const char *name;
GDBusSignalFlags flags;
const GDBusArgInfo *args;
-} GDBusSignalTable;
+};
-typedef struct {
+struct GDBusPropertyTable {
const char *name;
const char *type;
GDBusPropertyFlags flags;
-} GDBusPropertyTable;
+};
-typedef struct {
+struct GDBusSecurityTable {
unsigned int privilege;
const char *action;
GDBusSecurityFlags flags;
GDBusSecurityFunction function;
-} GDBusSecurityTable;
+};
#define GDBUS_ARGS(args...) (const GDBusArgInfo[]) { args, { } }
--
1.7.12.2
^ permalink raw reply related
* [PATCH BlueZ v4 00/15] Properties + ObjectManager
From: Lucas De Marchi @ 2012-10-04 7:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lucas De Marchi
Here is a rebased version of the patches. Most notable change is on patch
implementing the Set() method after feedback from Marcel. It doesn't cover the
concerns from Luiz about checking privileges per-property since I think this
could be added in a separate patch. As far as I could see the only user is
MediaTransport interface. The most obvious way would be to add another hook in
GDBusPropertyTable in order to check the privileges. Suggestions?
First 2 patches could be applied nonetheles. Get and GetAll are well tested,
both now and in the previous version of this patch set. Set() is still a
bit raw - the users implementing it are very big (adapter, device) so
they are not converted yet (previous patch doesn't apply anymore and there's a
change in the API that requires them to be rewritten).
Lucas De Marchi (10):
gdbus: Move typedefs up
gdbus: Use macros to add annotations
gdbus: Add skeleton of DBus.Properties interface
gdbus: Implement DBus.Properties.Get method
gdbus: Implement DBus.Properties.GetAll method
gdbus: Implement DBus.Properties.Set method
gdbus: Add properties into Introspectable interface
gdbus: Implement PropertiesChanged signal
Use DBus.Properties on Control interface
Use DBus.Properties on Manager interface
Luiz Augusto von Dentz (5):
gdbus: Add support for org.freedesktop.DBus.ObjectManager interface
gdbus: Group interface changes to reduce the amount of signals
emitted
gdbus: Only export ObjectManager interface on root path
gdbus: Integrates ObjectManager with Properties interface
gdbus: Simplify code for appending properties
audio/control.c | 57 ++--
gdbus/gdbus.h | 74 +++--
gdbus/object.c | 867 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
src/manager.c | 81 ++----
4 files changed, 897 insertions(+), 182 deletions(-)
--
1.7.12.2
^ permalink raw reply
* [PATCH BlueZ 2/2] build-sys: Don't use deprecated INCLUDES variable
From: Lucas De Marchi @ 2012-10-04 6:37 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349332630-8901-1-git-send-email-lucas.de.marchi@gmail.com>
Makefile.am:410: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
---
Makefile.am | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index dea207e..3b08f9a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -407,13 +407,13 @@ AM_YFLAGS = -d
AM_CFLAGS += @DBUS_CFLAGS@ @GLIB_CFLAGS@
-INCLUDES = -I$(builddir)/lib -I$(builddir)/src -I$(srcdir)/src \
+AM_CPPFLAGS = -I$(builddir)/lib -I$(builddir)/src -I$(srcdir)/src \
-I$(srcdir)/audio -I$(srcdir)/sbc -I$(srcdir)/gdbus \
-I$(srcdir)/attrib -I$(srcdir)/btio -I$(srcdir)/tools \
-I$(builddir)/tools -I$(srcdir)/monitor
if MCAP
-INCLUDES += -I$(builddir)/health
+AM_CPPFLAGS += -I$(builddir)/health
endif
unit_objects =
--
1.7.12.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox