Re: [pulseaudio-discuss] [PATCH 00/56] Refactor of BlueZ 5 support
Hi João Paulo, On Fri, Jul 12, 2013 at 8:06 PM, jprv...@gmail.com wrote: From: João Paulo Rechi Vita jprv...@openbossa.org This series reverts the previous support for BlueZ 5, renames the bluetooth portion of the old modules name for bluez4, creates a new set of modules for BlueZ 5 supporting A2DP sink and source roles, and provides configuration options to independently enable/disable each modules set during build. The transport acquire/release operations have been reworked to provide a way to implement this operations in transport backends out of the bluez5 modules core. What's the reason to follow the revert-approach instead of doing a simple split of the existing code? Is it perhaps because the resulting code is very different to the original one? Splitting would be much easier to review instead of starting from scratch. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [PATCH v2 18/22] bluetooth: Avoid suspend-on-idle for HFGW
Hi, On Fri, Aug 31, 2012 at 12:51 PM, Mikel Astiz mikel.astiz@gmail.com wrote: From: Mikel Astiz mikel.as...@bmw-carit.de The hfgw card profile (headset role of the HFP Bluetooth profile) has some particularities that make it unsuitable for idle-timeout-based suspension. The motivation starts with the fact that the remote end (the phone) will report to the user whether the audio is being routed to the headset or not. However, several use-cases require that the user is not reported such condition: outband ringing, simulated held calls where the audio is just silenced, multi-phone use-cases, etc. Additionally, there are IOP issues: some phones do not handle correctly suspending and resuming SCO. Therefore this patch exploits a module-specific property such that module-suspend-on-idle will not suspend the sink and source of the hfgw card profile. --- src/modules/bluetooth/module-bluetooth-device.c |5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 2d5c072..aac7e9d 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -1723,6 +1723,9 @@ static int add_sink(struct userdata *u) { pa_proplist_sets(data.proplist, bluetooth.protocol, profile_to_string(u-profile)); if (u-profile == PROFILE_HSP) pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, phone); +else if (u-profile == PROFILE_HFGW) +pa_proplist_sets(data.proplist, module-suspend-on-idle.timeout, 3600); + data.card = u-card; data.name = get_name(sink, u-modargs, u-address, b); data.namereg_fail = b; @@ -1784,6 +1787,8 @@ static int add_source(struct userdata *u) { pa_proplist_sets(data.proplist, bluetooth.protocol, profile_to_string(u-profile)); if (u-profile == PROFILE_HSP) pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, phone); +else if (u-profile == PROFILE_HFGW) +pa_proplist_sets(data.proplist, module-suspend-on-idle.timeout, 3600); data.card = u-card; data.name = get_name(source, u-modargs, u-address, b); -- 1.7.7.6 Going through the list of non-merged patches, I came across this one. IIRC it was nack-ed because such inter-module policies are discouraged. Is there any other approach to solve this issue? Most of the users won't care much about this issue if module-bluetooth-policy is normally loaded, since it keeps a module-loopback and thus the sink and source never enter idle. However, when some alternative approach is used instead of module-bluetooth-policy, the patch might become relevant. One simple example to illustrate this problem is the ring-tone: some setups require that a specific (user-defined) ring-tone is used when a phone starts ringing, regardless of the ring-tone provided by the phone (assuming this phone supports in-band ringing, e.g. iPhone). During this time, the audio coming from the phone needs to be ignored (source idle), but it can't be suspended because otherwise the phone will start ringing because the audio is not being routed to the headset (e.g. laptop or car). Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [PATCH v0] loopback: Fix cork state not updated after move
Hi Tanu, On Mon, Jul 8, 2013 at 3:06 PM, Tanu Kaskinen tanu.kaski...@linux.intel.com wrote: On Mon, 2013-07-01 at 10:27 +0200, Mikel Astiz wrote: From: Mikel Astiz mikel.as...@bmw-carit.de The source output and sink inputs should be corked if the corresponding sink/source is suspended, as handled during module initialization. This also needs to be handled during stream move, because the suspend state of the destination sink/source might be different to the previous one. This fixes the issue with an infinite number of Requesting rewind due to end of underrun traces after a stream move. module-loopback should certainly update the stream cork states when the streams are moved, but this patch looks like it will cause crashing. Did you test the patch? The moving() callback is called when i-sink is NULL, and pa_sink_input_cork() looks like it will crash in that situation. I did test the patch and didn't reproduce the issue you describe, neither did Georg, as it seems ([1]). Can you explain how this can be reproduced? You mention i-sink is NULL but how could that be the case during *source*-output-moving? As an aside, it's not clear to me why there would be endless rewind requests if the cork state is wrong. I would expect there to be just loads of Could not peek into queue messages. The issue can be reproduced easily by moving a stream from a suspended source to a running one. Cheers, Mikel [1] http://lists.freedesktop.org/archives/pulseaudio-discuss/2013-July/017735.html -- Tanu ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [PATCH v0] loopback: Fix cork state not updated after move
From: Mikel Astiz mikel.as...@bmw-carit.de The source output and sink inputs should be corked if the corresponding sink/source is suspended, as handled during module initialization. This also needs to be handled during stream move, because the suspend state of the destination sink/source might be different to the previous one. This fixes the issue with an infinite number of Requesting rewind due to end of underrun traces after a stream move. --- src/modules/module-loopback.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c index 4a32af4..9f897e0 100644 --- a/src/modules/module-loopback.c +++ b/src/modules/module-loopback.c @@ -419,6 +419,13 @@ static void source_output_moving_cb(pa_source_output *o, pa_source *dest) { pa_sink_input_update_proplist(u-sink_input, PA_UPDATE_REPLACE, p); pa_proplist_free(p); + +if (pa_source_get_state(dest) == PA_SOURCE_SUSPENDED) +pa_sink_input_cork(u-sink_input, TRUE); +else +pa_sink_input_cork(u-sink_input, FALSE); + +update_adjust_timer(u); } /* Called from main thread */ @@ -684,6 +691,13 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) { pa_source_output_update_proplist(u-source_output, PA_UPDATE_REPLACE, p); pa_proplist_free(p); + +if (pa_sink_get_state(dest) == PA_SINK_SUSPENDED) +pa_source_output_cork(u-source_output, TRUE); +else +pa_source_output_cork(u-source_output, FALSE); + +update_adjust_timer(u); } /* Called from main thread */ -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] Bluetooth devices no longer detected after upgrade from 2.0 to 4.0
Hi Georg, On Sun, Jun 30, 2013 at 2:48 PM, Georg Chini ge...@chini.tk wrote: Hi again, On 30.06.2013 12:57, Mikel Astiz wrote: Hi Georg, On Sun, Jun 30, 2013 at 11:00 AM, Georg Chini ge...@chini.tk wrote: On 30.06.2013 10:28, Mikel Astiz wrote: Hi Georg, On Sat, Jun 29, 2013 at 9:39 PM, Georg Chini ge...@chini.tk wrote: On 28.06.2013 08:23, Mikel Astiz wrote: Hi Georg, On Thu, Jun 27, 2013 at 1:31 PM, Georg Chini ge...@chini.tk wrote: On 27.06.2013 08:22, Mikel Astiz wrote: Hi Georg, On Wed, Jun 26, 2013 at 8:45 PM, Georg Chini ge...@chini.tk wrote: Hi Mikel, On 26.06.2013 16:54, Mikel Astiz wrote: Hi Georg, On Wed, Jun 26, 2013 at 3:27 PM, Georg Chini ge...@chini.tk wrote: Later on I decided to keep the modules around and just move them to the right source/sink when needed and move them to the default sound card and mute them when not in use. As a side suggestion, you probably want to use the profile availability to do this (if profile is available, it means 'playing'). The problem is that this does no longer work. Pavucontrol still shows the correct sink/source but I do not get any sound when the modules are reused. It seems to be a problem of resampling, the modules start to behave strangely as soon as sink and source are moved the first time. In the debug output I get endless repetition of: [alsa-sink-VT1828S Analog] module-loopback.c: Could not peek into queue [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. The initial approach of using fresh modules each time the phone goes to playing still works fine. I think you hit a real issue here. I've experienced similar issues too at some point, but I can't reproduce it anymore. Can you tell us which exact states the source (assuming A2DP from the phone) and the source-output have? They should in theory be both in RUNNING state. Sorry, I cannot find out. You can find a log of a complete session on http://philipp.chini.tk/pulse/pulse-session.log Maybe there is something useful in it. If not, please tell me how to get the state of the source or what else I can do to locate the problem. You should use 'pactl list sources' and 'pactl list source-outputs', during the issue you describe about rewind requests. All sources and source-outputs are in RUNNING state. The output for the relevant module (now it's A2DP from the phone, so only one module needed) looks like this: index: 6 driver: module-loopback.c flags: START_CORKED state: RUNNING This looks good. Have you checked if the bar in pavucontrol shows some audio corresponding to this source? source: 2 alsa_input.pci-_00_1b.0.analog-stereo volume: 0: 100% 1: 100% 0: -0,00 dB 1: -0,00 dB balance 0,00 muted: yes Is it muted? current latency: 0,00 ms requested latency: 135,29 ms sample spec: s16le 2ch 44100Hz channel map: front-left,front-right Stereo resample method: (null) owner module: 27 properties: media.role = abstract module-stream-restore.id = source-output-by-media-role:abstract media.name = Loopback to Internes Audio Analog Stereo media.icon_name = audio-card-pci Maybe the resample method: (null) is the problem? No, I don't think the resample method is relevant here. It also shows as null for me, and the audio just works. Cheers, Mikel Hi Mikel, after a bit of testing, I found an easy way to reproduce the problem. It seems to occur when the phone is in connected state and you try to move the source away from the loopback module. Pacmd shows the bluetooth source as SUSPENDED while the source-output is RUNNING. This looks perfectly fine to me. The Bluetooth source is no longer in use (you moved away the source-output) and therefore SUSPENDED, as opposed to the source-output which is pulling audio from the alsa card (your sound card, I guess). You should check whether your alsa source is RUNNING. If not, you might have hit an issue. I however think this is completely unrelated to the Bluetooth modules. Doing the following triggers the problem: 1) insert a loopback module with source=your_phone 2) wait until the phone is no longer playing 3) with pavucontrol move the source of the loopback module to another device What is strange is that the messages start after the source has already changed. I inserted a few log statements in module
Re: [pulseaudio-discuss] Bluetooth devices no longer detected after upgrade from 2.0 to 4.0
Hi Georg, On Sat, Jun 29, 2013 at 9:39 PM, Georg Chini ge...@chini.tk wrote: On 28.06.2013 08:23, Mikel Astiz wrote: Hi Georg, On Thu, Jun 27, 2013 at 1:31 PM, Georg Chini ge...@chini.tk wrote: On 27.06.2013 08:22, Mikel Astiz wrote: Hi Georg, On Wed, Jun 26, 2013 at 8:45 PM, Georg Chini ge...@chini.tk wrote: Hi Mikel, On 26.06.2013 16:54, Mikel Astiz wrote: Hi Georg, On Wed, Jun 26, 2013 at 3:27 PM, Georg Chini ge...@chini.tk wrote: Later on I decided to keep the modules around and just move them to the right source/sink when needed and move them to the default sound card and mute them when not in use. As a side suggestion, you probably want to use the profile availability to do this (if profile is available, it means 'playing'). The problem is that this does no longer work. Pavucontrol still shows the correct sink/source but I do not get any sound when the modules are reused. It seems to be a problem of resampling, the modules start to behave strangely as soon as sink and source are moved the first time. In the debug output I get endless repetition of: [alsa-sink-VT1828S Analog] module-loopback.c: Could not peek into queue [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. The initial approach of using fresh modules each time the phone goes to playing still works fine. I think you hit a real issue here. I've experienced similar issues too at some point, but I can't reproduce it anymore. Can you tell us which exact states the source (assuming A2DP from the phone) and the source-output have? They should in theory be both in RUNNING state. Sorry, I cannot find out. You can find a log of a complete session on http://philipp.chini.tk/pulse/pulse-session.log Maybe there is something useful in it. If not, please tell me how to get the state of the source or what else I can do to locate the problem. You should use 'pactl list sources' and 'pactl list source-outputs', during the issue you describe about rewind requests. All sources and source-outputs are in RUNNING state. The output for the relevant module (now it's A2DP from the phone, so only one module needed) looks like this: index: 6 driver: module-loopback.c flags: START_CORKED state: RUNNING This looks good. Have you checked if the bar in pavucontrol shows some audio corresponding to this source? source: 2 alsa_input.pci-_00_1b.0.analog-stereo volume: 0: 100% 1: 100% 0: -0,00 dB 1: -0,00 dB balance 0,00 muted: yes Is it muted? current latency: 0,00 ms requested latency: 135,29 ms sample spec: s16le 2ch 44100Hz channel map: front-left,front-right Stereo resample method: (null) owner module: 27 properties: media.role = abstract module-stream-restore.id = source-output-by-media-role:abstract media.name = Loopback to Internes Audio Analog Stereo media.icon_name = audio-card-pci Maybe the resample method: (null) is the problem? No, I don't think the resample method is relevant here. It also shows as null for me, and the audio just works. Cheers, Mikel Hi Mikel, after a bit of testing, I found an easy way to reproduce the problem. It seems to occur when the phone is in connected state and you try to move the source away from the loopback module. Pacmd shows the bluetooth source as SUSPENDED while the source-output is RUNNING. This looks perfectly fine to me. The Bluetooth source is no longer in use (you moved away the source-output) and therefore SUSPENDED, as opposed to the source-output which is pulling audio from the alsa card (your sound card, I guess). You should check whether your alsa source is RUNNING. If not, you might have hit an issue. I however think this is completely unrelated to the Bluetooth modules. Doing the following triggers the problem: 1) insert a loopback module with source=your_phone 2) wait until the phone is no longer playing 3) with pavucontrol move the source of the loopback module to another device What is strange is that the messages start after the source has already changed. I inserted a few log statements in module-loopback.c and got: [bluetooth] module-loopback.c: Source Output detach bluez_source.00_12_D1_8C_FC_80 [pulseaudio] module-loopback.c: Source Output moving to alsa_input.pci-_00_1b.0.analog-stereo [alsa-source-VT1828S Analog] module-loopback.c: Source Output attach alsa_input.pci-_00_1b.0.analog-stereo [alsa-sink-USB
Re: [pulseaudio-discuss] Bluetooth devices no longer detected after upgrade from 2.0 to 4.0
Hi Georg, On Sun, Jun 30, 2013 at 11:00 AM, Georg Chini ge...@chini.tk wrote: On 30.06.2013 10:28, Mikel Astiz wrote: Hi Georg, On Sat, Jun 29, 2013 at 9:39 PM, Georg Chini ge...@chini.tk wrote: On 28.06.2013 08:23, Mikel Astiz wrote: Hi Georg, On Thu, Jun 27, 2013 at 1:31 PM, Georg Chini ge...@chini.tk wrote: On 27.06.2013 08:22, Mikel Astiz wrote: Hi Georg, On Wed, Jun 26, 2013 at 8:45 PM, Georg Chini ge...@chini.tk wrote: Hi Mikel, On 26.06.2013 16:54, Mikel Astiz wrote: Hi Georg, On Wed, Jun 26, 2013 at 3:27 PM, Georg Chini ge...@chini.tk wrote: Later on I decided to keep the modules around and just move them to the right source/sink when needed and move them to the default sound card and mute them when not in use. As a side suggestion, you probably want to use the profile availability to do this (if profile is available, it means 'playing'). The problem is that this does no longer work. Pavucontrol still shows the correct sink/source but I do not get any sound when the modules are reused. It seems to be a problem of resampling, the modules start to behave strangely as soon as sink and source are moved the first time. In the debug output I get endless repetition of: [alsa-sink-VT1828S Analog] module-loopback.c: Could not peek into queue [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. The initial approach of using fresh modules each time the phone goes to playing still works fine. I think you hit a real issue here. I've experienced similar issues too at some point, but I can't reproduce it anymore. Can you tell us which exact states the source (assuming A2DP from the phone) and the source-output have? They should in theory be both in RUNNING state. Sorry, I cannot find out. You can find a log of a complete session on http://philipp.chini.tk/pulse/pulse-session.log Maybe there is something useful in it. If not, please tell me how to get the state of the source or what else I can do to locate the problem. You should use 'pactl list sources' and 'pactl list source-outputs', during the issue you describe about rewind requests. All sources and source-outputs are in RUNNING state. The output for the relevant module (now it's A2DP from the phone, so only one module needed) looks like this: index: 6 driver: module-loopback.c flags: START_CORKED state: RUNNING This looks good. Have you checked if the bar in pavucontrol shows some audio corresponding to this source? source: 2 alsa_input.pci-_00_1b.0.analog-stereo volume: 0: 100% 1: 100% 0: -0,00 dB 1: -0,00 dB balance 0,00 muted: yes Is it muted? current latency: 0,00 ms requested latency: 135,29 ms sample spec: s16le 2ch 44100Hz channel map: front-left,front-right Stereo resample method: (null) owner module: 27 properties: media.role = abstract module-stream-restore.id = source-output-by-media-role:abstract media.name = Loopback to Internes Audio Analog Stereo media.icon_name = audio-card-pci Maybe the resample method: (null) is the problem? No, I don't think the resample method is relevant here. It also shows as null for me, and the audio just works. Cheers, Mikel Hi Mikel, after a bit of testing, I found an easy way to reproduce the problem. It seems to occur when the phone is in connected state and you try to move the source away from the loopback module. Pacmd shows the bluetooth source as SUSPENDED while the source-output is RUNNING. This looks perfectly fine to me. The Bluetooth source is no longer in use (you moved away the source-output) and therefore SUSPENDED, as opposed to the source-output which is pulling audio from the alsa card (your sound card, I guess). You should check whether your alsa source is RUNNING. If not, you might have hit an issue. I however think this is completely unrelated to the Bluetooth modules. Doing the following triggers the problem: 1) insert a loopback module with source=your_phone 2) wait until the phone is no longer playing 3) with pavucontrol move the source of the loopback module to another device What is strange is that the messages start after the source has already changed. I inserted a few log statements in module-loopback.c and got: [bluetooth] module-loopback.c: Source Output detach bluez_source.00_12_D1_8C_FC_80 [pulseaudio] module-loopback.c: Source Output moving
Re: [pulseaudio-discuss] Bluetooth devices no longer detected after upgrade from 2.0 to 4.0
Hi Georg, On Thu, Jun 27, 2013 at 1:31 PM, Georg Chini ge...@chini.tk wrote: On 27.06.2013 08:22, Mikel Astiz wrote: Hi Georg, On Wed, Jun 26, 2013 at 8:45 PM, Georg Chini ge...@chini.tk wrote: Hi Mikel, On 26.06.2013 16:54, Mikel Astiz wrote: Hi Georg, On Wed, Jun 26, 2013 at 3:27 PM, Georg Chini ge...@chini.tk wrote: Later on I decided to keep the modules around and just move them to the right source/sink when needed and move them to the default sound card and mute them when not in use. As a side suggestion, you probably want to use the profile availability to do this (if profile is available, it means 'playing'). The problem is that this does no longer work. Pavucontrol still shows the correct sink/source but I do not get any sound when the modules are reused. It seems to be a problem of resampling, the modules start to behave strangely as soon as sink and source are moved the first time. In the debug output I get endless repetition of: [alsa-sink-VT1828S Analog] module-loopback.c: Could not peek into queue [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. The initial approach of using fresh modules each time the phone goes to playing still works fine. I think you hit a real issue here. I've experienced similar issues too at some point, but I can't reproduce it anymore. Can you tell us which exact states the source (assuming A2DP from the phone) and the source-output have? They should in theory be both in RUNNING state. Sorry, I cannot find out. You can find a log of a complete session on http://philipp.chini.tk/pulse/pulse-session.log Maybe there is something useful in it. If not, please tell me how to get the state of the source or what else I can do to locate the problem. You should use 'pactl list sources' and 'pactl list source-outputs', during the issue you describe about rewind requests. All sources and source-outputs are in RUNNING state. The output for the relevant module (now it's A2DP from the phone, so only one module needed) looks like this: index: 6 driver: module-loopback.c flags: START_CORKED state: RUNNING This looks good. Have you checked if the bar in pavucontrol shows some audio corresponding to this source? source: 2 alsa_input.pci-_00_1b.0.analog-stereo volume: 0: 100% 1: 100% 0: -0,00 dB 1: -0,00 dB balance 0,00 muted: yes Is it muted? current latency: 0,00 ms requested latency: 135,29 ms sample spec: s16le 2ch 44100Hz channel map: front-left,front-right Stereo resample method: (null) owner module: 27 properties: media.role = abstract module-stream-restore.id = source-output-by-media-role:abstract media.name = Loopback to Internes Audio Analog Stereo media.icon_name = audio-card-pci Maybe the resample method: (null) is the problem? No, I don't think the resample method is relevant here. It also shows as null for me, and the audio just works. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC v0] bluetooth: Send time-based output audio
From: Mikel Astiz mikel.as...@bmw-carit.de The previous implementation to send 2 packets first and then try to account the received packets vs sent packets seems to generate some issues in several devices. The alternative is to always do it time-based. --- This is WIP and thus not intended to be merged. I'm submitting this to see if it improves some issues recently reported with several devices, leading to no audio when using HSP/HFP. hcidump showed that no packets were being sent by neither of the ends. src/modules/bluetooth/module-bluetooth-device.c | 25 ++--- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index ea3db48..bdaa3ad 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -989,8 +989,6 @@ static void a2dp_reduce_bitpool(struct userdata *u) { static void thread_func(void *userdata) { struct userdata *u = userdata; -unsigned do_write = 0; -unsigned pending_read_bytes = 0; bool writable = false; pa_assert(u); @@ -1011,17 +1009,11 @@ static void thread_func(void *userdata) { struct pollfd *pollfd; int ret; bool disable_timer = true; +unsigned do_write = 0; pollfd = u-rtpoll_item ? pa_rtpoll_item_get_pollfd(u-rtpoll_item, NULL) : NULL; if (u-source PA_SOURCE_IS_LINKED(u-source-thread_info.state)) { - -/* We should send two blocks to the device before we expect - * a response. */ - -if (u-write_index == 0 u-read_index = 0) -do_write = 2; - if (pollfd (pollfd-revents POLLIN)) { int n_read; @@ -1032,11 +1024,6 @@ static void thread_func(void *userdata) { if (n_read 0) goto io_fail; - -/* We just read something, so we are supposed to write something, too */ -pending_read_bytes += n_read; -do_write += pending_read_bytes / u-write_block_size; -pending_read_bytes = pending_read_bytes % u-write_block_size; } } @@ -1049,7 +1036,8 @@ static void thread_func(void *userdata) { if (pollfd-revents POLLOUT) writable = true; -if ((!u-source || !PA_SOURCE_IS_LINKED(u-source-thread_info.state)) do_write = 0 writable) { +/* Force time based scheduling for outgoing packets */ +if (writable) { pa_usec_t time_passed; pa_usec_t audio_sent; @@ -1061,6 +1049,7 @@ static void thread_func(void *userdata) { if (audio_sent = time_passed) { pa_usec_t audio_to_send = time_passed - audio_sent; +size_t bytes_to_send = bytes_to_send = pa_usec_to_bytes(audio_to_send, u-sample_spec); /* Never try to catch up for more than 100ms */ if (u-write_index 0 audio_to_send MAX_PLAYBACK_CATCH_UP_USEC) { @@ -1080,14 +1069,14 @@ static void thread_func(void *userdata) { pa_sink_render_full(u-sink, skip_bytes, tmp); pa_memblock_unref(tmp.memblock); u-write_index += skip_bytes; +bytes_to_send -= skip_bytes; if (u-profile == PROFILE_A2DP) a2dp_reduce_bitpool(u); } } -do_write = 1; -pending_read_bytes = 0; +do_write = bytes_to_send / u-write_block_size; } } @@ -1169,8 +1158,6 @@ io_fail: if (!pollfd || (pollfd-revents POLLHUP) == 0) goto fail; -do_write = 0; -pending_read_bytes = 0; writable = false; teardown_stream(u); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] Bluetooth devices no longer detected after upgrade from 2.0 to 4.0
Hi Georg, On Wed, Jun 26, 2013 at 8:45 PM, Georg Chini ge...@chini.tk wrote: Hi Mikel, On 26.06.2013 16:54, Mikel Astiz wrote: Hi Georg, On Wed, Jun 26, 2013 at 3:27 PM, Georg Chini ge...@chini.tk wrote: Hi Mikel, On 24.06.2013 11:22, Mikel Astiz wrote: This seems a successful connection of HSP/HFP. The module is however not loaded because the overall connection procedure (org.bluez.Audio) is still ongoing, and therefore the load of the module is postponed. D: [lt-pulseaudio] bluetooth-util.c: dbus: interface=org.bluez.MediaEndpoint, path=/MediaEndpoint/HFPAG, member=SetConfiguration D: [lt-pulseaudio] module-console-kit.c: dbus: interface=org.bluez.MediaEndpoint, path=/MediaEndpoint/HFPAG, member=SetConfiguration D: [lt-pulseaudio] bluetooth-util.c: dbus: path=/MediaEndpoint/HFPAG, interface=org.bluez.MediaEndpoint, member=SetConfiguration E: [lt-pulseaudio] bluetooth-util.c: Cannot configure transport /org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E/fd41 because profile 2 is already used You hit the first issue here. It looks to me that BlueZ is starting the connection procedure twice, for the same profile, using a different transport. This looks like a bug in BlueZ. Any chance you can upgrade to 4.101? I've had a look at the commits between 4.99 and 4.101 and there seem to be a bunch of fixes which could be related to this issue. Thanks a lot. You were right here. Upgrading to bluez 4.101 solved this problem. But now I have another one: For pulseaudio 2 I wrote a python application which is basically a more comfortable version of module-bluetooth-policy. It makes it easy to use your mobile from your desktop. It lets you direct the sound to a sound card of your choice (which may be different for a2dpsource and HFP gateway), change it on the fly and switch echo cancellation on and off. With the help of ofono you can also accept calls or make calls from your desktop. I believe you could implement similar policies within pulseaudio without the need of additional scripts, but anyway... Maybe. But when I started using pulse a few month ago I could not figure out how. When I started programming I inserted loopback modules each time the mobile changed state to playing and unloaded them when the phone went back to connected. (In pulseaudio 2 the profile was then set to off, so source and sink were no longer available) module-bluetooth-policy will take care of switching between profiles automatically. If you're not interested in the module-loopback part, then you might want to load module-bluetooth-policy with the arguments hfgw=0 a2dp_source=0. Thanks for the hint. I was under the impression that the module does nothing when you set both parameters to 0. Later on I decided to keep the modules around and just move them to the right source/sink when needed and move them to the default sound card and mute them when not in use. As a side suggestion, you probably want to use the profile availability to do this (if profile is available, it means 'playing'). The problem is that this does no longer work. Pavucontrol still shows the correct sink/source but I do not get any sound when the modules are reused. It seems to be a problem of resampling, the modules start to behave strangely as soon as sink and source are moved the first time. In the debug output I get endless repetition of: [alsa-sink-VT1828S Analog] module-loopback.c: Could not peek into queue [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. The initial approach of using fresh modules each time the phone goes to playing still works fine. I think you hit a real issue here. I've experienced similar issues too at some point, but I can't reproduce it anymore. Can you tell us which exact states the source (assuming A2DP from the phone) and the source-output have? They should in theory be both in RUNNING state. Sorry, I cannot find out. You can find a log of a complete session on http://philipp.chini.tk/pulse/pulse-session.log Maybe there is something useful in it. If not, please tell me how to get the state of the source or what else I can do to locate the problem. You should use 'pactl list sources' and 'pactl list source-outputs', during the issue you describe about rewind requests. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] Bluetooth devices no longer detected after upgrade from 2.0 to 4.0
Hi Georg, On Wed, Jun 26, 2013 at 3:27 PM, Georg Chini ge...@chini.tk wrote: Hi Mikel, On 24.06.2013 11:22, Mikel Astiz wrote: This seems a successful connection of HSP/HFP. The module is however not loaded because the overall connection procedure (org.bluez.Audio) is still ongoing, and therefore the load of the module is postponed. D: [lt-pulseaudio] bluetooth-util.c: dbus: interface=org.bluez.MediaEndpoint, path=/MediaEndpoint/HFPAG, member=SetConfiguration D: [lt-pulseaudio] module-console-kit.c: dbus: interface=org.bluez.MediaEndpoint, path=/MediaEndpoint/HFPAG, member=SetConfiguration D: [lt-pulseaudio] bluetooth-util.c: dbus: path=/MediaEndpoint/HFPAG, interface=org.bluez.MediaEndpoint, member=SetConfiguration E: [lt-pulseaudio] bluetooth-util.c: Cannot configure transport /org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E/fd41 because profile 2 is already used You hit the first issue here. It looks to me that BlueZ is starting the connection procedure twice, for the same profile, using a different transport. This looks like a bug in BlueZ. Any chance you can upgrade to 4.101? I've had a look at the commits between 4.99 and 4.101 and there seem to be a bunch of fixes which could be related to this issue. Thanks a lot. You were right here. Upgrading to bluez 4.101 solved this problem. But now I have another one: For pulseaudio 2 I wrote a python application which is basically a more comfortable version of module-bluetooth-policy. It makes it easy to use your mobile from your desktop. It lets you direct the sound to a sound card of your choice (which may be different for a2dpsource and HFP gateway), change it on the fly and switch echo cancellation on and off. With the help of ofono you can also accept calls or make calls from your desktop. I believe you could implement similar policies within pulseaudio without the need of additional scripts, but anyway... When I started programming I inserted loopback modules each time the mobile changed state to playing and unloaded them when the phone went back to connected. (In pulseaudio 2 the profile was then set to off, so source and sink were no longer available) module-bluetooth-policy will take care of switching between profiles automatically. If you're not interested in the module-loopback part, then you might want to load module-bluetooth-policy with the arguments hfgw=0 a2dp_source=0. Later on I decided to keep the modules around and just move them to the right source/sink when needed and move them to the default sound card and mute them when not in use. As a side suggestion, you probably want to use the profile availability to do this (if profile is available, it means 'playing'). The problem is that this does no longer work. Pavucontrol still shows the correct sink/source but I do not get any sound when the modules are reused. It seems to be a problem of resampling, the modules start to behave strangely as soon as sink and source are moved the first time. In the debug output I get endless repetition of: [alsa-sink-VT1828S Analog] module-loopback.c: Could not peek into queue [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. [alsa-sink-VT1828S Analog] module-loopback.c: Requesting rewind due to end of underrun. The initial approach of using fresh modules each time the phone goes to playing still works fine. I think you hit a real issue here. I've experienced similar issues too at some point, but I can't reproduce it anymore. Can you tell us which exact states the source (assuming A2DP from the phone) and the source-output have? They should in theory be both in RUNNING state. Any ideas what might cause this? Again any help or hint is welcome. Regards Georg Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] Bluetooth devices no longer detected after upgrade from 2.0 to 4.0
Hi Georg, On Thu, Jun 20, 2013 at 5:02 PM, Georg Chini ge...@chini.tk wrote: Hello, after upgrading to Pulseaudio 4.0 my bluetooth devices (headset, 2 mobiles) are no longer discovered. I am running Debian unstable on an amd64 CPU, the new Debian package was released a few days ago. I also filed a bug with Debian but did not receive a reply so far. To make sure this is not a problem of the package I compiled pulse from GIT. I also made sure, that that the headset is properly connected by using ALSA to play something. This worked fine. Pulseaudio 2.0 discovered the devices when I connected them. Running Pulse with debug output gives slightly different results, if Media is enabled in Bluez or not. Bluez version is 4.99. With Media enabled: During startup: D: [lt-pulseaudio] bluetooth-util.c: Device /org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E interface org.bluez.Headset property 'State' changed to value 'disconnected' D: [lt-pulseaudio] bluetooth-util.c: Device /org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E interface org.bluez.AudioSink property 'State' changed to value 'disconnected' D: [lt-pulseaudio] bluetooth-util.c: Device /org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E interface org.bluez.Headset property 'State' changed to value 'disconnected' D: [lt-pulseaudio] bluetooth-util.c: Device /org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E interface org.bluez.Audio property 'State' changed to value 'disconnected' And when I connect the headset: D: [lt-pulseaudio] bluetooth-util.c: dbus: interface=org.bluez.Device, path=/org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E, member=PropertyChanged D: [lt-pulseaudio] module-console-kit.c: dbus: interface=org.bluez.Device, path=/org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E, member=PropertyChanged D: [lt-pulseaudio] bluetooth-util.c: dbus: interface=org.bluez.Headset, path=/org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E, member=PropertyChanged D: [lt-pulseaudio] bluetooth-util.c: Device /org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E interface org.bluez.Headset property 'State' changed to value 'connecting' D: [lt-pulseaudio] module-console-kit.c: dbus: interface=org.bluez.Headset, path=/org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E, member=PropertyChanged D: [lt-pulseaudio] bluetooth-util.c: dbus: interface=org.bluez.Audio, path=/org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E, member=PropertyChanged D: [lt-pulseaudio] bluetooth-util.c: Device /org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E interface org.bluez.Audio property 'State' changed to value 'connecting' D: [lt-pulseaudio] module-console-kit.c: dbus: interface=org.bluez.Audio, path=/org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E, member=PropertyChanged D: [lt-pulseaudio] bluetooth-util.c: dbus: interface=org.bluez.MediaEndpoint, path=/MediaEndpoint/HFPAG, member=SetConfiguration D: [lt-pulseaudio] module-console-kit.c: dbus: interface=org.bluez.MediaEndpoint, path=/MediaEndpoint/HFPAG, member=SetConfiguration D: [lt-pulseaudio] bluetooth-util.c: dbus: path=/MediaEndpoint/HFPAG, interface=org.bluez.MediaEndpoint, member=SetConfiguration D: [lt-pulseaudio] bluetooth-util.c: Transport /org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E/fd40 profile 2 available This seems a successful connection of HSP/HFP. The module is however not loaded because the overall connection procedure (org.bluez.Audio) is still ongoing, and therefore the load of the module is postponed. D: [lt-pulseaudio] bluetooth-util.c: dbus: interface=org.bluez.MediaEndpoint, path=/MediaEndpoint/HFPAG, member=SetConfiguration D: [lt-pulseaudio] module-console-kit.c: dbus: interface=org.bluez.MediaEndpoint, path=/MediaEndpoint/HFPAG, member=SetConfiguration D: [lt-pulseaudio] bluetooth-util.c: dbus: path=/MediaEndpoint/HFPAG, interface=org.bluez.MediaEndpoint, member=SetConfiguration E: [lt-pulseaudio] bluetooth-util.c: Cannot configure transport /org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E/fd41 because profile 2 is already used You hit the first issue here. It looks to me that BlueZ is starting the connection procedure twice, for the same profile, using a different transport. This looks like a bug in BlueZ. Any chance you can upgrade to 4.101? I've had a look at the commits between 4.99 and 4.101 and there seem to be a bunch of fixes which could be related to this issue. D: [lt-pulseaudio] bluetooth-util.c: dbus: interface=org.bluez.Headset, path=/org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E, member=PropertyChanged D: [lt-pulseaudio] bluetooth-util.c: Device /org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E interface org.bluez.Headset property 'State' changed to value 'disconnected' D: [lt-pulseaudio] module-console-kit.c: dbus: interface=org.bluez.Headset, path=/org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E, member=PropertyChanged D: [lt-pulseaudio] bluetooth-util.c: dbus: interface=org.bluez.Audio, path=/org/bluez/7417/hci1/dev_00_19_7F_41_DB_2E, member=PropertyChanged D: [lt-pulseaudio] bluetooth-util.c: Device
Re: [pulseaudio-discuss] Bluetooth + HSP + Raspberry?
Hi Bram, On Fri, Jun 14, 2013 at 10:20 AM, Bram de Jong bram.dej...@gmail.com wrote: Hi Mikel, As Tanu mentioned, this can be done calling HandsfreeGateway.Connect(). You can do this in command line or using a tool such as d-feet. People tend to think that Audio.Connect() connects all audio profiles but this is not the case in BlueZ 4: you have to explicitly call HandsfreeGateway.Connect() for HSP/HFP and AudioSource.Connect() for A2DP. Aha! Hmm, I'm using d-feet but I can't see the method HandsfreeGateway.Connect on bluez. I do see Audio.Connect, but no mention of HandsfreeGateway. That's because oFono is not running or correctly set up. Alternatively, you can initiate the connection from the phone. This should work out of the box assuming the device is marked as trusted. I'm actually always initiating from the phone side. On Android I do have a checkbox on the phone that reads Media audio: connected to media audio which to me sounds a bit like A2DP and not HFS. Exactly (but HFS should be HSP/HFP). More importantly, in order to make all this work, you'll also need a telephony component which implements the headset role (note that BlueZ doesn't do this). I would recommend oFono 1.12 but older versions should also work fine. Is there anything specific I need to configure for this to work or does the package just need to be there? Also, as I said before, I'm only trying to OUTPUT the audio to the HSP/HFP, not use the Pi as a microphone, or does ofono need to be present anyway? oFono needs to be present anyway, it makes no difference that you're interested in one-way audio. Installing oFono should generally be fine assuming it was compiled with --enable-bluetooth. In a similar way, BlueZ should be compiled with --with-telephony=ofono. If it doesn't work, make sure your BlueZ audio.conf includes Enable=Gateway. This might be necessary depending on the exact BlueZ version you're using (e.g. some distros have patches to enable this profile/role by default). Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] Bluetooth + HSP + Raspberry?
Hi Bram, On Jun 14, 2013 3:09 PM, Bram de Jong bram.dej...@gmail.com wrote: Hi Mikel, Please avoid top-posting. Thanks for all the help so far! I've gotten a bit further again, but no sigar yet! Enable=Gateway was definitely the ticket: I set it and now HandsfreeGateway.Connect shows up and executes correctly, my phone suddenly shows a new checkbox Phone audio: Connected to phone audio. Superb! So I called myself as a test and -lo and behold- the bluetooth symbol shows up when I pick up. Sounds good. However, after this I checked the PA sources and no bluetooth source is to be seen. Not only that, when I hung up the phone my kernel bailed out on me :-) (I suppose this now takes me to ofono configuration land?) One good thing about oFono is there's not much you can configure. If you reached the point where the profile connects, you're basically done with oFono. I would strongly encourage to upgrade to a more recent version of PA. Some of the fixes after 2.1 were specifically addressing this Bluetooth role. Cheers, Mikel - bram On Fri, Jun 14, 2013 at 12:03 PM, Mikel Astiz mikel.astiz@gmail.com wrote: Hi Bram, On Fri, Jun 14, 2013 at 10:20 AM, Bram de Jong bram.dej...@gmail.com wrote: Hi Mikel, As Tanu mentioned, this can be done calling HandsfreeGateway.Connect(). You can do this in command line or using a tool such as d-feet. People tend to think that Audio.Connect() connects all audio profiles but this is not the case in BlueZ 4: you have to explicitly call HandsfreeGateway.Connect() for HSP/HFP and AudioSource.Connect() for A2DP. Aha! Hmm, I'm using d-feet but I can't see the method HandsfreeGateway.Connect on bluez. I do see Audio.Connect, but no mention of HandsfreeGateway. That's because oFono is not running or correctly set up. Alternatively, you can initiate the connection from the phone. This should work out of the box assuming the device is marked as trusted. I'm actually always initiating from the phone side. On Android I do have a checkbox on the phone that reads Media audio: connected to media audio which to me sounds a bit like A2DP and not HFS. Exactly (but HFS should be HSP/HFP). More importantly, in order to make all this work, you'll also need a telephony component which implements the headset role (note that BlueZ doesn't do this). I would recommend oFono 1.12 but older versions should also work fine. Is there anything specific I need to configure for this to work or does the package just need to be there? Also, as I said before, I'm only trying to OUTPUT the audio to the HSP/HFP, not use the Pi as a microphone, or does ofono need to be present anyway? oFono needs to be present anyway, it makes no difference that you're interested in one-way audio. Installing oFono should generally be fine assuming it was compiled with --enable-bluetooth. In a similar way, BlueZ should be compiled with --with-telephony=ofono. If it doesn't work, make sure your BlueZ audio.conf includes Enable=Gateway. This might be necessary depending on the exact BlueZ version you're using (e.g. some distros have patches to enable this profile/role by default). Cheers, Mikel -- http://www.samplesumo.com http://www.freesound.org http://www.smartelectronix.com http://www.musicdsp.org office: +32 (0) 9 335 59 25 mobile: +32 (0) 484 154 730 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] Bluetooth + HSP + Raspberry?
Hi Bram, On Thu, Jun 13, 2013 at 3:59 PM, Bram de Jong bram.dej...@gmail.com wrote: On Thu, Jun 13, 2013 at 1:39 PM, Tanu Kaskinen tanu.kaski...@linux.intel.com wrote: What I want to do is use the Raspberry as a speaker only using the low-latency HSP (which you cann HFGW) bluetooth profile. This should mainly be for making calls from another computer. You mean the method that is used to create the source for PA or the method that really connected the device? You need to connect the HSP/HFP profile in BlueZ in order to be able to use it in PA. As Tanu mentioned, this can be done calling HandsfreeGateway.Connect(). You can do this in command line or using a tool such as d-feet. People tend to think that Audio.Connect() connects all audio profiles but this is not the case in BlueZ 4: you have to explicitly call HandsfreeGateway.Connect() for HSP/HFP and AudioSource.Connect() for A2DP. Alternatively, you can initiate the connection from the phone. This should work out of the box assuming the device is marked as trusted. More importantly, in order to make all this work, you'll also need a telephony component which implements the headset role (note that BlueZ doesn't do this). I would recommend oFono 1.12 but older versions should also work fine. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [BUG] Using bluez 5.5 pulseaudio a bluetooth headset cannot be used as a recording device.
Hi Alex, On Sat, Jun 8, 2013 at 8:45 PM, Alexander Winnig vernehmlass...@googlemail.com wrote: So I managed to install pulseaudio 4.0 including sbc, speex, bluez and d-bus and I encounter the same problem. I installed D-feet to monitor dbus. This didn't really help move things forward as there's only listed what I already know from the python example. Play is not working here aswell as it's based on python again. Geez, I've been trying to make this work for about 2 weeks or more. Just to speak into my headset's microphone and to record it with linux. It worked exactly zero times. I ran out clocks, no solution in sight so far. Sigh. As pointed out before, it seems your specific headsets presents issues with BlueZ and/or PulseAudio, and I would suggest you test a different headset to confirm this. Perhaps I'm wrong but I believe there's no easy way to make you headset work. If you really want to go deep into this issue, you'd have to write or test a few PulseAudio patches, until the issue gets fixed or at least the root cause is identified. But beware that this will require a considerable time. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [BUG] Using bluez 5.5 pulseaudio a bluetooth headset cannot be used as a recording device.
Hi Alex, On Wed, Jun 5, 2013 at 11:15 AM, Alexander Winnig vernehmlass...@googlemail.com wrote: Thanks. Hi Alex, On Tue, Jun 4, 2013 at 9:45 PM, Alexander Winnig vernehmlass...@googlemail.com wrote: Thanks Mikel. Am 04.06.2013 14:02, schrieb Mikel Astiz: parecord -r --device=bluez_source.00_1A_7D_11_C0_66 mm.wav in my case. Creates a crackling sound in the earpiece and a mm.wav of zero bytes, no matter how long I record. I tried to reproduce your issue without success, with two different headsets. It could be an issue with your specific headset (any chance you can test a different one?) or more likely, according to your previous messages, your system is broken with multiple versions of the same component or an incorrect configuration (PulseAudio, BlueZ). I re-copied a new wheezy-image on my sd-card. Now pactl list sources short shows the bluez-device. But still, an empty file is the output. So a broken system/incorrect configuration is unlikely now. A possible checklist you could follow is: 1. Make sure BlueZ's audio.conf is properly set. You might need to add a line with Disable=Socket. Done. 2. Make sure the headset is connected (PA card exists) and profile is set to hsp. Done. 3. During recording, make sure the profile's state is set to available: yes. You can see this with pacmd list-cards. This is what I get: pi@raspberrypi ~ $ parecord -r -d bluez_source.00_1A_7D_11_C0_66 mm.wav [1] 2828 pi@raspberrypi ~ $ pacmd list-cards . index: 4 name: bluez_card.00_1A_7D_11_C0_66 driver: module-bluetooth-device.c owner module: 24 properties: device.description = Iqua Slim device.string = 00:1A:7D:11:C0:66 device.api = bluez device.class = sound device.bus = bluetooth device.form_factor = headset bluez.path = /org/bluez/1981/hci0/dev_00_1A_7D_11_C0_66 bluez.class = 0x240404 bluez.name = Iqua Slim device.icon_name = audio-headset-bluetooth device.intended_roles = phone profiles: a2dp: High Fidelity Playback (A2DP) (priority 10) hsp: Telephony Duplex (HSP/HFP) (priority 20) Which version of PulseAudio/pacmd are you using? 4.0 would have shown the profile availability here. pulseaudio 2.0 pacmd 2.0(Compiled with libpulse 2.0.0, Linked with libpulse 2.0.0) I can't help you much with such a version. I however did follow your steps with 2.0 and couldn't reproduce the issue either. So it points to be an issue with your specific headset. I would suggest you try with a different one to confirm. If I have to get the newest pulseaudio for my purpose, please tell me how to exactly configure, make and make install it for it to work this time. I won't install it if it's just nice-to-have. It's your choice to decide if you want to test a more recent version or not, nothing's guaranteed. You will find the instructions in the documentation but I can at least point out that you'll need to install the sbc library, which is a new dependency. In any case, the state of the source below already confims the SCO state. off: Off (priority 0) active profile: hsp sinks: bluez_sink.00_1A_7D_11_C0_66/#3: Iqua Slim sources: bluez_sink.00_1A_7D_11_C0_66.monitor/#5: Monitor of Iqua Slim bluez_source.00_1A_7D_11_C0_66/#6: Iqua Slim ports: 4. During recording, make sure the source is state: RUNNING (pacmd list-sources). This confirms (3) meaning that SCO audio is streaming fine. I used pactl list sources short. It showed 1 bluez_sink.00_1A_7D_11_C0_66.monitormodule-bluetooth-device.c s16le 1ch 8000HzSUSPENDED 2 bluez_source.00_1A_7D_11_C0_66 module-bluetooth-device.c s16le 1ch 8000HzRUNNING This looks good. Can you check list-sinks? I believe the headset sink will be suspended, but let's confirm it. index: 1 name: bluez_sink.00_1A_7D_11_C0_66 driver: module-bluetooth-device.c flags: HARDWARE HW_VOLUME_CTRL LATENCY state: IDLE suspend cause: priority: 9030 volume: 0: 53% balance 0.00 base volume: 100% volume steps: 16 muted: no current latency: 137.00 ms max request: 0 KiB max rewind: 0 KiB monitor source: 1 sample spec: s16le 1ch 8000Hz channel map: mono Mono used by: 0 linked by: 0 fixed latency: 128.00 ms card: 1 bluez_card.00_1A_7D_11_C0_66 module: 6 properties: bluetooth.protocol = sco device.intended_roles = phone device.description = Iqua Slim
Re: [pulseaudio-discuss] [BUG] Using bluez 5.5 pulseaudio a bluetooth headset cannot be used as a recording device.
Hi Alex, On Tue, Jun 4, 2013 at 9:45 PM, Alexander Winnig vernehmlass...@googlemail.com wrote: Thanks Mikel. Am 04.06.2013 14:02, schrieb Mikel Astiz: parecord -r --device=bluez_source.00_1A_7D_11_C0_66 mm.wav in my case. Creates a crackling sound in the earpiece and a mm.wav of zero bytes, no matter how long I record. I tried to reproduce your issue without success, with two different headsets. It could be an issue with your specific headset (any chance you can test a different one?) or more likely, according to your previous messages, your system is broken with multiple versions of the same component or an incorrect configuration (PulseAudio, BlueZ). I re-copied a new wheezy-image on my sd-card. Now pactl list sources short shows the bluez-device. But still, an empty file is the output. So a broken system/incorrect configuration is unlikely now. A possible checklist you could follow is: 1. Make sure BlueZ's audio.conf is properly set. You might need to add a line with Disable=Socket. Done. 2. Make sure the headset is connected (PA card exists) and profile is set to hsp. Done. 3. During recording, make sure the profile's state is set to available: yes. You can see this with pacmd list-cards. This is what I get: pi@raspberrypi ~ $ parecord -r -d bluez_source.00_1A_7D_11_C0_66 mm.wav [1] 2828 pi@raspberrypi ~ $ pacmd list-cards . index: 4 name: bluez_card.00_1A_7D_11_C0_66 driver: module-bluetooth-device.c owner module: 24 properties: device.description = Iqua Slim device.string = 00:1A:7D:11:C0:66 device.api = bluez device.class = sound device.bus = bluetooth device.form_factor = headset bluez.path = /org/bluez/1981/hci0/dev_00_1A_7D_11_C0_66 bluez.class = 0x240404 bluez.name = Iqua Slim device.icon_name = audio-headset-bluetooth device.intended_roles = phone profiles: a2dp: High Fidelity Playback (A2DP) (priority 10) hsp: Telephony Duplex (HSP/HFP) (priority 20) Which version of PulseAudio/pacmd are you using? 4.0 would have shown the profile availability here. In any case, the state of the source below already confims the SCO state. off: Off (priority 0) active profile: hsp sinks: bluez_sink.00_1A_7D_11_C0_66/#3: Iqua Slim sources: bluez_sink.00_1A_7D_11_C0_66.monitor/#5: Monitor of Iqua Slim bluez_source.00_1A_7D_11_C0_66/#6: Iqua Slim ports: 4. During recording, make sure the source is state: RUNNING (pacmd list-sources). This confirms (3) meaning that SCO audio is streaming fine. I used pactl list sources short. It showed 1 bluez_sink.00_1A_7D_11_C0_66.monitormodule-bluetooth-device.c s16le 1ch 8000HzSUSPENDED 2 bluez_source.00_1A_7D_11_C0_66 module-bluetooth-device.c s16le 1ch 8000HzRUNNING This looks good. Can you check list-sinks? I believe the headset sink will be suspended, but let's confirm it. If all this work fine but the issue persists, I'd have to see the output of hcidump during recording. This is all hcidump gives: HCI sniffer - Bluetooth packet analyzer ver 2.4 device: hci0 snap_len: 1028 filter: 0x and a waiting green square not returning to the command line. When I disconnected the headset I got HCI Event: Inquiry Result (0x02) plen 20 bdaddr 00:A0:02:00:0C:00 mode 19 clkoffset 0x1300 class 0x02000c bdaddr 00:02:00:0C:01:05 mode 0 clkoffset 0x class 0x00 bdaddr 00:00:00:00:00:00 mode 0 clkoffset 0x class 0x00 bdaddr 00:00:00:00:00:00 mode 0 clkoffset 0x class 0x00 bdaddr 00:00:00:00:00:00 mode 0 clkoffset 0x class 0x00 bdaddr 00:00:00:00:00:00 mode 0 clkoffset 0x class 0x00 Stream-Fehler: Entität terminiert HCI Event: Disconn Complete (0x05) plen 4 status 0x00 handle 12 reason 0x13 Reason: Remote User Terminated Connection It seems the SCO link (the actual audio stream) is up but there's no audio flowing. Which hardware are you testing this on? You mentioned you're using a raspberry pi, which I believe doesn't have a built-in bluetooth chip. Are you using some conventional USB dongle? I ask this because the hardware could be set up for SCO over PCM (as opposed to SCO over HCI) which would lead to the described behavior. Otherwise, assuming it's SCO over HCI, the hcidump above would be pretty bad. I haven't seen this before but it's definitely possible that the headset doesn't send any audio unless it receives some, which is not happening in this case. You should be able to confirm this by sending some audio to the headset with paplay during the recording, and checking if parecord works during this time
Re: [pulseaudio-discuss] [PATCH v1] bluetooth: Dynamically change outgoing MTU
Hi, On Wed, Mar 13, 2013 at 9:20 AM, Tanu Kaskinen ta...@iki.fi wrote: On Tue, 2013-03-12 at 14:02 +0100, Mikel Astiz wrote: On Tue, Mar 12, 2013 at 1:42 PM, Tanu Kaskinen ta...@iki.fi wrote: If the MTU is initially set to 128, it sounds logical that it may be reconfigured to 128 too. This wouldn't work with the proposed code: 128 - 96 - 128. The proposed code specifically handles only two possible transitions: either 48-96 or 96-48. If the MTU is set to something else other than 48 or 96, the code won't change the previous behavior. That's what I meant when I said it was 'conservative', since it handles only the cases that have been experimentally observed. We can try to generalize this for any random MTU value, as I was trying to do in my first proposal, but I see very little benefit unless someone proves that similar policies are useful in other working conditions (e.g. using a non-USB Bluetooth adapter). In this case I would agree that something like MAX_SCO_READ_MTU would be required. I forgot to say that I didn't see much point in being conservative here, so that's why I was ignoring the 48/96 special casing. While writing this reply, however, I realized that there is a good reason for being conservative. We recently added handling for packets with non-aligned size, and receiving such packets means that there are temporary glitches that can cause any random packet size. We shouldn't reconfigure the MTU in those cases. What would you think about this: replace the unaligned size check with checking that the received size is the same as the read MTU. If it's different, check if it's 48 or 96, in which case reconfigure the MTU, and otherwise ignore the packet? So what do you think? I don't want to rely on undocumented behavior. If BlueZ guarantees that the MTUs will always be symmetric (also in the future), it's fine to update the write MTU in PulseAudio when the read MTU changes. But if there's no such guarantee, I wouldn't change the write MTU, unless there's a really good reason to do so. So, what horrible things happen if we don't update the write MTU? If you don't update the MTU as proposed by this patch, the Bluetooth adapter typically powers down. OK, that's horrible enough :) Concerning the 'undocumented behavior', you're completely right, starting from the fact that I found no reference in the spec about all this. Regarding what BlueZ's API guarantees, we shouldn't assume the MTUs are symmetric. If you're concerned about this, I could extend the patch in such a way that the policy is triggered if and only if this condition holds true (input MTU == output MTU). I prefer adding that check, but that's not a strong opinion. -- Tanu For the record, this v1 patch ([1]) is still needed if anybody is interested in having two simultaneous SCO streams (two heaDsets/phones doing HSP/HFP). A later v2 bluetooth: Read SCO MTU from socket options was also submitted ([2]) but this approach doesn't seem as stable as the v1 approach. As mentioned several times, the patch has been tested and seems to work, but we found no documentation supporting this behavior. I would suggest it gets merged nevertheless and have an eye on it in case it introduces regressions. Cheers, Mikel [1] http://thread.gmane.org/gmane.comp.audio.pulseaudio.general/16128 [2] http://thread.gmane.org/gmane.comp.audio.pulseaudio.general/16273 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [BUG] Using bluez 5.5 pulseaudio a bluetooth headset cannot be used as a recording device.
Hi Alex, On Tue, Jun 4, 2013 at 1:10 PM, Alexander Winnig vernehmlass...@googlemail.com wrote: I re-copied a new wheezy-image on my sd-card. Now pactl list sources short shows the bluez-device. But still, an empty file is the output. How exactly did you record the file? Did you ensure that you're recording from the right source? If you use parecord, you can give the source name with --device=sourcenamehere parecord -r --device=bluez_source.00_1A_7D_11_C0_66 mm.wav in my case. Creates a crackling sound in the earpiece and a mm.wav of zero bytes, no matter how long I record. I tried to reproduce your issue without success, with two different headsets. It could be an issue with your specific headset (any chance you can test a different one?) or more likely, according to your previous messages, your system is broken with multiple versions of the same component or an incorrect configuration (PulseAudio, BlueZ). A possible checklist you could follow is: 1. Make sure BlueZ's audio.conf is properly set. You might need to add a line with Disable=Socket. 2. Make sure the headset is connected (PA card exists) and profile is set to hsp. 3. During recording, make sure the profile's state is set to available: yes. You can see this with pacmd list-cards. 4. During recording, make sure the source is state: RUNNING (pacmd list-sources). This confirms (3) meaning that SCO audio is streaming fine. If all this work fine but the issue persists, I'd have to see the output of hcidump during recording. You can also repeat the test with module-suspend-on-idle unloaded before connecting the headset (e.g. disable it in default.pa). Perhaps the headset has issues with audio suspendresume. I have the impression that you need to make the headset believe that a phone call is coming in for it's mike to become active. The audio stream (SCO) should start streaming as soon as parecord is launched. No need for phone calls or anything. I've never heard of such headsets. At least my headset allows PulseAudio to use the microphone at any time. By Headset I mean this http://www.iqua.com/sites/default/files/images/slim_high5.jpg So I talked to the carwhisperer author martin. He said that he couldn't help me in this case as he doesn't know his code anymore well enough. If you are interested, find his code at http://trifinite.org/trifinite_stuff_carwhisperer.html#downloads Maybe you / someone else can find the real cause. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] Connecting a phone over bluetooth (was: [PATCH v0 0/2] bluetooth: Port-profile association)
Hi David, On Wed, May 22, 2013 at 12:00 PM, David Henningsson david.hennings...@canonical.com wrote: On 05/21/2013 05:18 PM, Mikel Astiz wrote: Hi David, On Tue, May 21, 2013 at 3:55 PM, David Henningsson david.hennings...@canonical.com wrote: On 05/21/2013 02:58 PM, Mikel Astiz wrote: Hi David, On Tue, May 21, 2013 at 2:37 PM, David Henningsson david.hennings...@canonical.com wrote: On 05/20/2013 11:48 AM, Mikel Astiz wrote: From: Mikel Astiz mikel.as...@bmw-carit.de These patches address a regression existing in the master branch, which specially affects the gnome UI. More info in https://bugs.freedesktop.org/show_bug.cgi?id=64713. Thanks, I have now tested them and confirmed that they solve the problem here! The proposed solution is fairly simple but triggers the question whether something like PA_CORE_HOOK_PORT_PROFILE_ADDED is needed in the case of late Bluetooth UUIDs. In this scenario, the port has already been created by the time a new profile needs to be registered, typically after a Bluetooth-pairing procedure (for reference, see d4368aa608b79f58a279018eb74abd5a6bff30ac). I'm not really familiar with the late UUID problem, how common is that really? I have never seen it myself, but then my range of hardware is limited to a simple headset and a laptop. It's fairly common when pairing phones but I've never seen it with headsets. In practice, I'd say it's hardly possible to hit this issue when the pairing procedure (the Bluetooth device discovery) is initiated from our side, which is the case for all headsets. Besides, obviously, it's only possible with devices that support multiple profiles (HSP/HFP + A2DP). Actually, I have a phone running Android 4.0 here, so I tried pairing it with the laptop from the phone side, but there was no bluetooth card showing up at all on the laptop side, and all in the gnome bluetooth GUI is a checkbox asking me for network connections. Maybe Android 4.0 (or my version of bluez?) does not support relaying audio to (or from?) the phone? This should be working assuming BlueZ is configured properly. You might need to configure BlueZ's audio.conf with: Enable=Media,Headset,Gateway,Sink,Source This might not be necessary if your BlueZ is patched which is probably the case. If this was not the case, there should not have been an AudioSource.Connect method at all, right? Correct. Another possible issue is that you never connected the profiles. You can try by calling the D-Bus AudioSource.Connect() (for A2DP) or When I do this, my phone lights up, the following is added to syslog, bluetoothd[1066]: Connection refused (111) and the call, after some time, returns GDBus.Error:org.bluez.Error.Failed: Stream Setup Failed This is weird. Any chance you might have overlooked a confirmation UI on the phone? Some phones prompt the user for incoming connections, but this is nowadays less common. HandsfreeGateway.Connect() (for HFP). This returns GDBus.Error:org.bluez.Error.AgentNotAvailable: Agent Not Available. This is because you're not running oFono, where this role of HFP is implemented. This is likely if the phone didn't initiate the connection automatically after pairing. You can also play around by manually initiating the connection on the phone's UI. I can't do much in the UI (Samsung). The two checkboxes saying something like Use for phone sound and Use for media sound are both checked. This would be the first phone I know of that doesn't have a UI to initiate connections to a headset (in this case, your laptop). Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [PATCH v0 0/2] bluetooth: Port-profile association
Hi David, On Tue, May 21, 2013 at 2:37 PM, David Henningsson david.hennings...@canonical.com wrote: On 05/20/2013 11:48 AM, Mikel Astiz wrote: From: Mikel Astiz mikel.as...@bmw-carit.de These patches address a regression existing in the master branch, which specially affects the gnome UI. More info in https://bugs.freedesktop.org/show_bug.cgi?id=64713. Thanks, I have now tested them and confirmed that they solve the problem here! The proposed solution is fairly simple but triggers the question whether something like PA_CORE_HOOK_PORT_PROFILE_ADDED is needed in the case of late Bluetooth UUIDs. In this scenario, the port has already been created by the time a new profile needs to be registered, typically after a Bluetooth-pairing procedure (for reference, see d4368aa608b79f58a279018eb74abd5a6bff30ac). I'm not really familiar with the late UUID problem, how common is that really? I have never seen it myself, but then my range of hardware is limited to a simple headset and a laptop. It's fairly common when pairing phones but I've never seen it with headsets. In practice, I'd say it's hardly possible to hit this issue when the pairing procedure (the Bluetooth device discovery) is initiated from our side, which is the case for all headsets. Besides, obviously, it's only possible with devices that support multiple profiles (HSP/HFP + A2DP). This patchset ignores such possible issue and simply modifies the port's profile hashmap without triggering any event. As long as a card change subscription event is sent after both the new profile is added and the port-profile hashmap is updated, we should be fine w r t clients. (Except that no clients actually support new profiles AFAIK...) Similarly, right now I think we're fine with the existing PA_CORE_HOOK_CARD_PROFILE_ADDED hook (which I assume is correctly fired?), Yes, this hook should be correctly fired. that could trigger that the port-profile hashmap might have been updated too. If we in the future need to add a separate per-port hook to tell that the profile hashmap has changed, we can add it later. Sounds good to me. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [PATCH v0 0/2] bluetooth: Port-profile association
Hi David, On Tue, May 21, 2013 at 3:55 PM, David Henningsson david.hennings...@canonical.com wrote: On 05/21/2013 02:58 PM, Mikel Astiz wrote: Hi David, On Tue, May 21, 2013 at 2:37 PM, David Henningsson david.hennings...@canonical.com wrote: On 05/20/2013 11:48 AM, Mikel Astiz wrote: From: Mikel Astiz mikel.as...@bmw-carit.de These patches address a regression existing in the master branch, which specially affects the gnome UI. More info in https://bugs.freedesktop.org/show_bug.cgi?id=64713. Thanks, I have now tested them and confirmed that they solve the problem here! The proposed solution is fairly simple but triggers the question whether something like PA_CORE_HOOK_PORT_PROFILE_ADDED is needed in the case of late Bluetooth UUIDs. In this scenario, the port has already been created by the time a new profile needs to be registered, typically after a Bluetooth-pairing procedure (for reference, see d4368aa608b79f58a279018eb74abd5a6bff30ac). I'm not really familiar with the late UUID problem, how common is that really? I have never seen it myself, but then my range of hardware is limited to a simple headset and a laptop. It's fairly common when pairing phones but I've never seen it with headsets. In practice, I'd say it's hardly possible to hit this issue when the pairing procedure (the Bluetooth device discovery) is initiated from our side, which is the case for all headsets. Besides, obviously, it's only possible with devices that support multiple profiles (HSP/HFP + A2DP). Actually, I have a phone running Android 4.0 here, so I tried pairing it with the laptop from the phone side, but there was no bluetooth card showing up at all on the laptop side, and all in the gnome bluetooth GUI is a checkbox asking me for network connections. Maybe Android 4.0 (or my version of bluez?) does not support relaying audio to (or from?) the phone? This should be working assuming BlueZ is configured properly. You might need to configure BlueZ's audio.conf with: Enable=Media,Headset,Gateway,Sink,Source This might not be necessary if your BlueZ is patched which is probably the case. Another possible issue is that you never connected the profiles. You can try by calling the D-Bus AudioSource.Connect() (for A2DP) or HandsfreeGateway.Connect() (for HFP). This is likely if the phone didn't initiate the connection automatically after pairing. You can also play around by manually initiating the connection on the phone's UI. Note that Audio.Connect() does not connect these profiles, which can be misleading. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [PATCH v0 0/2] bluetooth: Port-profile association
From: Mikel Astiz mikel.as...@bmw-carit.de These patches address a regression existing in the master branch, which specially affects the gnome UI. More info in https://bugs.freedesktop.org/show_bug.cgi?id=64713. The proposed solution is fairly simple but triggers the question whether something like PA_CORE_HOOK_PORT_PROFILE_ADDED is needed in the case of late Bluetooth UUIDs. In this scenario, the port has already been created by the time a new profile needs to be registered, typically after a Bluetooth-pairing procedure (for reference, see d4368aa608b79f58a279018eb74abd5a6bff30ac). This patchset ignores such possible issue and simply modifies the port's profile hashmap without triggering any event. Mikel Astiz (2): bluetooth: Create ports before card profiles bluetooth: Fix missing port-profile association src/modules/bluetooth/module-bluetooth-device.c | 22 +- 1 file changed, 17 insertions(+), 5 deletions(-) -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [PATCH v0 1/2] bluetooth: Create ports before card profiles
From: Mikel Astiz mikel.as...@bmw-carit.de Both operations are currently independent and their order can therefore be swapped. --- src/modules/bluetooth/module-bluetooth-device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index c877df2..47bed2f 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2252,6 +2252,8 @@ static int add_card(struct userdata *u) { return -1; } +create_card_ports(u, data.ports); + PA_LLIST_FOREACH(uuid, device-uuids) { p = create_card_profile(u, uuid-uuid); @@ -2268,8 +2270,6 @@ static int add_card(struct userdata *u) { pa_assert(!pa_hashmap_isempty(data.profiles)); -create_card_ports(u, data.ports); - p = pa_card_profile_new(off, _(Off), sizeof(enum profile)); p-available = PA_AVAILABLE_YES; d = PA_CARD_PROFILE_DATA(p); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [PATCH v0 2/2] bluetooth: Fix missing port-profile association
From: Mikel Astiz mikel.as...@bmw-carit.de Commit 17b3cb954b179392e80b0a46d8f2ba4693aec386 merged Bluetooth ports into two ports (one for input, one for output) but the association between ports and profiles was lost. BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=64713 --- src/modules/bluetooth/module-bluetooth-device.c | 18 +++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 47bed2f..fd6739d 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2154,10 +2154,16 @@ static void create_card_ports(struct userdata *u, pa_hashmap *ports) { } /* Run from main thread */ -static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid) { +static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid, pa_hashmap *ports) { +pa_device_port *input_port, *output_port; pa_card_profile *p = NULL; enum profile *d; +pa_assert(u-input_port_name); +pa_assert(u-output_port_name); +pa_assert_se(input_port = pa_hashmap_get(ports, u-input_port_name)); +pa_assert_se(output_port = pa_hashmap_get(ports, u-output_port_name)); + if (pa_streq(uuid, A2DP_SINK_UUID)) { p = pa_card_profile_new(a2dp, _(High Fidelity Playback (A2DP)), sizeof(enum profile)); p-priority = 10; @@ -2165,6 +2171,7 @@ static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid p-n_sources = 0; p-max_sink_channels = 2; p-max_source_channels = 0; +pa_hashmap_put(output_port-profiles, p-name, p); d = PA_CARD_PROFILE_DATA(p); *d = PROFILE_A2DP; @@ -2175,6 +2182,7 @@ static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid p-n_sources = 1; p-max_sink_channels = 0; p-max_source_channels = 2; +pa_hashmap_put(input_port-profiles, p-name, p); d = PA_CARD_PROFILE_DATA(p); *d = PROFILE_A2DP_SOURCE; @@ -2185,6 +2193,8 @@ static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid p-n_sources = 1; p-max_sink_channels = 1; p-max_source_channels = 1; +pa_hashmap_put(input_port-profiles, p-name, p); +pa_hashmap_put(output_port-profiles, p-name, p); d = PA_CARD_PROFILE_DATA(p); *d = PROFILE_HSP; @@ -2195,6 +2205,8 @@ static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid p-n_sources = 1; p-max_sink_channels = 1; p-max_source_channels = 1; +pa_hashmap_put(input_port-profiles, p-name, p); +pa_hashmap_put(output_port-profiles, p-name, p); d = PA_CARD_PROFILE_DATA(p); *d = PROFILE_HFGW; @@ -2255,7 +2267,7 @@ static int add_card(struct userdata *u) { create_card_ports(u, data.ports); PA_LLIST_FOREACH(uuid, device-uuids) { -p = create_card_profile(u, uuid-uuid); +p = create_card_profile(u, uuid-uuid, data.ports); if (!p) continue; @@ -2362,7 +2374,7 @@ static pa_hook_result_t uuid_added_cb(pa_bluetooth_discovery *y, const struct pa if (data-device != u-device) return PA_HOOK_OK; -p = create_card_profile(u, data-uuid); +p = create_card_profile(u, data-uuid, u-card-ports); if (!p) return PA_HOOK_OK; -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v0 00/11] bluetooth: Add backend infrastructure
From: Mikel Astiz mikel.as...@bmw-carit.de There's some ongoing work by João Paulo to add oFono support to PulseAudio. This requires the adoption of some backend infrastructure in order to keep the codebase and dependencies clean, which is exactly what this patchset is proposing. For reasons already discussed in the mailing list, I would rather have these patches merged before the oFono-specific patches, which should also make the review easier. However, if some of the maintainers prefer to merge oFono first and later refactor the codebase, you can raise the point now so we focus on the other patchset and this one would have to be reworked later. Note that this patchset alone does not make much sense unless the oFono patches are going to be merged afterwards, so I submit this as WIP where João Paulo's work could be rebased on. Mikel Astiz (11): bluetooth: Add backend infrastructure with core-backend reporting bluetooth: Add basic backend-core notifications bluetooth: Add backend-core notification of new transports bluetooth: Add embedded BlueZ backend inside bluetooth-util bluetooth: Avoid using transport path in traces bluetooth: Split BlueZ backend data to separate structs bluetooth: Add device removed callback to backend bluetooth: Add transport acquire/release callbacks to backend bluetooth: Add microphone gain callback to backend bluetooth: Add speaker gain callback to backend bluetooth: Use bluez_backend_private for endpoint userdata src/modules/bluetooth/bluetooth-util.c | 462 ++-- src/modules/bluetooth/bluetooth-util.h | 48 ++- src/modules/bluetooth/module-bluetooth-device.c | 11 +- 3 files changed, 412 insertions(+), 109 deletions(-) -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v0 01/11] bluetooth: Add backend infrastructure with core-backend reporting
From: Mikel Astiz mikel.as...@bmw-carit.de Components other than BlueZ can also implement Bluetooth profiles and some infrastructure is required to keep the codebase cleanly split. --- src/modules/bluetooth/bluetooth-util.c | 32 src/modules/bluetooth/bluetooth-util.h | 12 2 files changed, 44 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 5924736..b8fe450 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -91,6 +91,11 @@ typedef enum pa_bluez_version { BLUEZ_VERSION_5, } pa_bluez_version_t; +struct profile_data { +pa_bluetooth_backend *backend; +void *backend_private; +}; + struct pa_bluetooth_discovery { PA_REFCNT_DECLARE; @@ -101,6 +106,7 @@ struct pa_bluetooth_discovery { bool adapters_listed; pa_hashmap *devices; pa_hashmap *transports; +struct profile_data profiles[PA_BLUETOOTH_PROFILE_COUNT]; pa_hook hooks[PA_BLUETOOTH_HOOK_MAX]; bool filter_added; }; @@ -2281,3 +2287,29 @@ bool pa_bluetooth_uuid_has(pa_bluetooth_uuid *uuids, const char *uuid) { return false; } + +int pa_bt_backend_register(pa_bluetooth_discovery *y, pa_bluetooth_backend *b, enum profile p, void *bp) { +pa_assert(y); +pa_assert(b); + +if (y-profiles[p].backend) { +pa_log_error(Bluetooth backend already exists for profile %s, pa_bt_profile_to_string(p)); +return -1; +} + +y-profiles[p].backend = b; +y-profiles[p].backend_private = bp; + +return 0; +} + +void pa_bt_backend_unregister(pa_bluetooth_discovery *y, pa_bluetooth_backend *b, enum profile p) { +pa_assert(y); +pa_assert(b); + +if (y-profiles[p].backend != b) +return; + +y-profiles[p].backend = NULL; +y-profiles[p].backend_private = NULL; +} diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index 3361b0f..969f489 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -175,4 +175,16 @@ char *pa_bluetooth_cleanup_name(const char *name); bool pa_bluetooth_uuid_has(pa_bluetooth_uuid *uuids, const char *uuid); const char *pa_bt_profile_to_string(enum profile profile); +/* + * Backend registration mechanism + */ +struct pa_bluetooth_backend; +typedef struct pa_bluetooth_backend pa_bluetooth_backend; + +struct pa_bluetooth_backend { +}; + +int pa_bt_backend_register(pa_bluetooth_discovery *y, pa_bluetooth_backend *b, enum profile p, void *bp); +void pa_bt_backend_unregister(pa_bluetooth_discovery *y, pa_bluetooth_backend *b, enum profile p); + #endif -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v0 02/11] bluetooth: Add basic backend-core notifications
From: Mikel Astiz mikel.as...@bmw-carit.de Make a clear split to define an API implementing transport operations, and how these backends should report the events to the Bluetooth core. --- src/modules/bluetooth/bluetooth-util.c | 143 +++-- src/modules/bluetooth/bluetooth-util.h | 7 ++ 2 files changed, 106 insertions(+), 44 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index b8fe450..2e3203e 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -588,7 +588,6 @@ static int parse_audio_property(pa_bluetooth_device *d, const char *interface, D if (pa_streq(key, State)) { pa_bt_audio_state_t state = audio_state_from_string(value); -pa_bluetooth_transport_state_t old_state; pa_log_debug(Device %s interface %s property 'State' changed to value '%s', d-path, interface, value); @@ -607,16 +606,7 @@ static int parse_audio_property(pa_bluetooth_device *d, const char *interface, D if (!transport) break; -old_state = transport-state; -transport-state = audio_state_to_transport_state(state); - -if (transport-state != old_state) { -pa_log_debug(Transport %s (profile %s) changed state from %s to %s., transport-path, - pa_bt_profile_to_string(transport-profile), transport_state_to_string(old_state), - transport_state_to_string(transport-state)); - - pa_hook_fire(d-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED], transport); -} +pa_bt_backend_notify_state(transport, audio_state_to_transport_state(state)); } break; @@ -628,8 +618,6 @@ static int parse_audio_property(pa_bluetooth_device *d, const char *interface, D dbus_message_iter_get_basic(variant_i, value); if (pa_streq(key, MicrophoneGain)) { -uint16_t gain; - pa_log_debug(dbus: property '%s' changed to value '%u', key, value); if (!transport) { @@ -637,14 +625,8 @@ static int parse_audio_property(pa_bluetooth_device *d, const char *interface, D return -1; } -if ((gain = PA_MIN(value, HSP_MAX_GAIN)) == transport-microphone_gain) -break; - -transport-microphone_gain = gain; - pa_hook_fire(d-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED], transport); +pa_bt_backend_notify_microphone_gain(transport, PA_MIN(value, HSP_MAX_GAIN)); } else if (pa_streq(key, SpeakerGain)) { -uint16_t gain; - pa_log_debug(dbus: property '%s' changed to value '%u', key, value); if (!transport) { @@ -652,11 +634,7 @@ static int parse_audio_property(pa_bluetooth_device *d, const char *interface, D return -1; } -if ((gain = PA_MIN(value, HSP_MAX_GAIN)) == transport-speaker_gain) -break; - -transport-speaker_gain = gain; - pa_hook_fire(d-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED], transport); +pa_bt_backend_notify_speaker_gain(transport, PA_MIN(value, HSP_MAX_GAIN)); } break; @@ -1101,11 +1079,8 @@ static int transport_parse_property(pa_bluetooth_transport *t, DBusMessageIter * dbus_bool_t value; dbus_message_iter_get_basic(variant_i, value); -if (pa_streq(key, NREC) t-nrec != value) { -t-nrec = value; -pa_log_debug(Transport %s: Property 'NREC' changed to %s., t-path, t-nrec ? True : False); - pa_hook_fire(t-device-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_NREC_CHANGED], t); -} +if (pa_streq(key, NREC)) +pa_bt_backend_notify_nrec(t, value); break; } @@ -1777,20 +1752,8 @@ static DBusMessage *endpoint_clear_configuration(DBusConnection *c, DBusMessage goto fail; } -if ((t = pa_hashmap_get(y-transports, path))) { -bool old_any_connected = pa_bluetooth_device_any_audio_connected(t-device); - -pa_log_debug(Clearing transport %s profile %d, t-path, t-profile); -t-device-transports[t-profile] = NULL; -pa_hashmap_remove(y-transports, t-path); -t-state = PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED; -pa_hook_fire(y-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED], t); - -if (old_any_connected != pa_bluetooth_device_any_audio_connected(t-device)) -run_callback(t-device, false); - -transport_free(t); -} +if ((t
[pulseaudio-discuss] [RFC next v0 03/11] bluetooth: Add backend-core notification of new transports
From: Mikel Astiz mikel.as...@bmw-carit.de Backends are responsible for the notification of new transports, which is backend-dependant. The core still holds ownership of the transport objects. --- src/modules/bluetooth/bluetooth-util.c | 45 -- src/modules/bluetooth/bluetooth-util.h | 13 ++ 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 2e3203e..56156a9 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1594,23 +1594,22 @@ static int setup_dbus(pa_bluetooth_discovery *y) { static pa_bluetooth_transport *transport_new(pa_bluetooth_device *d, const char *owner, const char *path, enum profile p, const uint8_t *config, int size) { pa_bluetooth_transport *t; +pa_bluetooth_transport_new_data data; -t = pa_xnew0(pa_bluetooth_transport, 1); -t-device = d; -t-owner = pa_xstrdup(owner); -t-path = pa_xstrdup(path); -t-profile = p; -t-config_size = size; - -if (size 0) { -t-config = pa_xnew(uint8_t, size); -memcpy(t-config, config, size); -} +data.device = d; +data.profile = p; +data.config_size = size; +data.config = config; if (d-discovery-version == BLUEZ_VERSION_4) -t-state = audio_state_to_transport_state(d-profile_state[p]); +data.state = audio_state_to_transport_state(d-profile_state[p]); else -t-state = PA_BLUETOOTH_TRANSPORT_STATE_IDLE; +data.state = PA_BLUETOOTH_TRANSPORT_STATE_IDLE; + +t = pa_bt_backend_notify_transport_added(data); + +t-owner = pa_xstrdup(owner); +t-path = pa_xstrdup(path); return t; } @@ -2277,6 +2276,26 @@ void pa_bt_backend_unregister(pa_bluetooth_discovery *y, pa_bluetooth_backend *b y-profiles[p].backend_private = NULL; } +pa_bluetooth_transport *pa_bt_backend_notify_transport_added(pa_bluetooth_transport_new_data *data) { +pa_bluetooth_transport *t; + +pa_assert(data); + +t = pa_xnew0(pa_bluetooth_transport, 1); +t-device = data-device; +t-profile = data-profile; +t-state = data-state; + +if ((t-config_size = data-config_size) 0) { +pa_assert(data-config); + +t-config = pa_xnew(uint8_t, data-config_size); +memcpy(t-config, data-config, data-config_size); +} + +return t; +} + void pa_bt_backend_notify_transport_removed(pa_bluetooth_transport *t) { pa_bluetooth_discovery *y; pa_bluetooth_device *d; diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index 3f54802..1a72ca6 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -188,6 +188,19 @@ int pa_bt_backend_register(pa_bluetooth_discovery *y, pa_bluetooth_backend *b, e void pa_bt_backend_unregister(pa_bluetooth_discovery *y, pa_bluetooth_backend *b, enum profile p); /* Reporting of events from backend to Bluetooth core */ +typedef struct pa_bluetooth_transport_new_data { +pa_bluetooth_device *device; +enum profile profile; +uint8_t codec; +const uint8_t *config; +int config_size; +pa_bluetooth_transport_state_t state; +bool nrec; +uint16_t microphone_gain; +uint16_t speaker_gain; +} pa_bluetooth_transport_new_data; + +pa_bluetooth_transport *pa_bt_backend_notify_transport_added(pa_bluetooth_transport_new_data *data); void pa_bt_backend_notify_transport_removed(pa_bluetooth_transport *t); void pa_bt_backend_notify_state(pa_bluetooth_transport *t, pa_bluetooth_transport_state_t state); void pa_bt_backend_notify_nrec(pa_bluetooth_transport *t, bool nrec); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v0 04/11] bluetooth: Add embedded BlueZ backend inside bluetooth-util
From: Mikel Astiz mikel.as...@bmw-carit.de BlueZ 5 supports external profiles, meaning that certain Bluetooth profiles (e.g. HFP/HSP) are completely handled outside BlueZ. However, some other profiles (i.e. A2DP) are still implemented inside BlueZ, so let's keep a BlueZ-specific backend inside bluetooth-util. Furthermore, in the case of BlueZ 4, this embedded backend also supports HSP/HFP. --- src/modules/bluetooth/bluetooth-util.c | 36 ++ 1 file changed, 36 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 56156a9..9f7cf77 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -96,6 +96,9 @@ struct profile_data { void *backend_private; }; +typedef struct bluez_backend_private { +} bluez_backend_private; + struct pa_bluetooth_discovery { PA_REFCNT_DECLARE; @@ -109,6 +112,8 @@ struct pa_bluetooth_discovery { struct profile_data profiles[PA_BLUETOOTH_PROFILE_COUNT]; pa_hook hooks[PA_BLUETOOTH_HOOK_MAX]; bool filter_added; + +bluez_backend_private backend_private; }; static void get_properties_reply(DBusPendingCall *pending, void *userdata); @@ -1975,6 +1980,33 @@ static DBusHandlerResult endpoint_handler(DBusConnection *c, DBusMessage *m, voi return DBUS_HANDLER_RESULT_HANDLED; } +pa_bluetooth_backend bluez_backend = { +}; + +static void bluez_backend_init(pa_bluetooth_discovery *y) { +bluez_backend_private *bbp = y-backend_private; + +pa_bt_backend_register(y, bluez_backend, PROFILE_A2DP, bbp); +pa_bt_backend_register(y, bluez_backend, PROFILE_A2DP_SOURCE, bbp); + +if (y-version = BLUEZ_VERSION_5) +return; + +pa_bt_backend_register(y, bluez_backend, PROFILE_HSP, bbp); +pa_bt_backend_register(y, bluez_backend, PROFILE_HFGW, bbp); +} + +static void bluez_backend_done(pa_bluetooth_discovery *y) { +pa_bt_backend_unregister(y, bluez_backend, PROFILE_A2DP); +pa_bt_backend_unregister(y, bluez_backend, PROFILE_A2DP_SOURCE); + +if (y-version = BLUEZ_VERSION_5) +return; + +pa_bt_backend_unregister(y, bluez_backend, PROFILE_HSP); +pa_bt_backend_unregister(y, bluez_backend, PROFILE_HFGW); +} + pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { DBusError err; pa_bluetooth_discovery *y; @@ -2003,6 +2035,8 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { pa_shared_set(c, bluetooth-discovery, y); +bluez_backend_init(y); + if (setup_dbus(y) 0) goto fail; @@ -2079,6 +2113,8 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) { pa_dbus_free_pending_list(y-pending); +bluez_backend_done(y); + if (y-devices) { remove_all_devices(y); pa_hashmap_free(y-devices, NULL); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v0 05/11] bluetooth: Avoid using transport path in traces
From: Mikel Astiz mikel.as...@bmw-carit.de Replace the transport path with the device path and the profile id, which should be more relevant and also backend-agnostic. --- src/modules/bluetooth/bluetooth-util.c | 9 + src/modules/bluetooth/module-bluetooth-device.c | 11 +++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 9f7cf77..34db2ac 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1266,7 +1266,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us goto fail; if (!dbus_message_iter_init(m, arg_i)) { -pa_log(Failed to parse PropertyChanged for transport %s, t-path); +pa_log(Failed to parse PropertyChanged for transport %s, dbus_message_get_path(m)); goto fail; } @@ -2343,7 +2343,7 @@ void pa_bt_backend_notify_transport_removed(pa_bluetooth_transport *t) { old_any_connected = pa_bluetooth_device_any_audio_connected(d); -pa_log_debug(Removing transport %s profile %d, t-path, t-profile); +pa_log_debug(Removing transport for device %s profile %s, d-path, pa_bt_profile_to_string(t-profile)); d-transports[t-profile] = NULL; pa_hashmap_remove(y-transports, t-path); @@ -2367,7 +2367,7 @@ void pa_bt_backend_notify_state(pa_bluetooth_transport *t, pa_bluetooth_transpor if (t-state == state) return; -pa_log_debug(Transport %s (profile %s) changed state from %s to %s., t-path, +pa_log_debug(Transport for device %s profile %s changed state from %s to %s., d-path, pa_bt_profile_to_string(t-profile), transport_state_to_string(t-state), transport_state_to_string(state)); @@ -2388,7 +2388,8 @@ void pa_bt_backend_notify_nrec(pa_bluetooth_transport *t, bool nrec) { return; t-nrec = nrec; -pa_log_debug(Transport %s: Property 'NREC' changed to %s., t-path, t-nrec ? True : False); +pa_log_debug(Transport for device %s profile %s: 'NREC' changed to %s., d-path, pa_bt_profile_to_string(t-profile), + t-nrec ? True : False); pa_hook_fire(y-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_NREC_CHANGED], t); } diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 290f5ce..d397646 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -284,7 +284,7 @@ static void setup_stream(struct userdata *u) { struct pollfd *pollfd; int one; -pa_log_info(Transport %s resuming, u-transport-path); +pa_log_info(Transport for device %s profile %s resuming, u-device-path, pa_bt_profile_to_string(u-transport-profile)); bt_transport_config_mtu(u); @@ -350,7 +350,8 @@ static void bt_transport_release(struct userdata *u) { if (!u-transport_acquired) return; -pa_log_debug(Releasing transport %s, u-transport-path); +pa_log_debug(Releasing transport for device %s profile %s, u-device-path, + pa_bt_profile_to_string(u-transport-profile)); pa_bluetooth_transport_release(u-transport); @@ -365,14 +366,16 @@ static int bt_transport_acquire(struct userdata *u, bool optional) { if (u-transport_acquired) return 0; -pa_log_debug(Acquiring transport %s, u-transport-path); +pa_log_debug(Acquiring transport for device %s profile %s, u-device-path, + pa_bt_profile_to_string(u-transport-profile)); u-stream_fd = pa_bluetooth_transport_acquire(u-transport, optional, u-read_link_mtu, u-write_link_mtu); if (u-stream_fd 0) return -1; u-transport_acquired = true; -pa_log_info(Transport %s acquired: fd %d, u-transport-path, u-stream_fd); +pa_log_info(Transport for device %s profile %s acquired: fd %d, u-device-path, +pa_bt_profile_to_string(u-transport-profile), u-stream_fd); return 0; } -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v0 06/11] bluetooth: Split BlueZ backend data to separate structs
From: Mikel Astiz mikel.as...@bmw-carit.de bluetooth-util internally implements a backend for BlueZ Media API but it's nevertheless convenient to have the backend-specific data split into separated data structures. --- src/modules/bluetooth/bluetooth-util.c | 108 +++-- src/modules/bluetooth/bluetooth-util.h | 4 +- 2 files changed, 79 insertions(+), 33 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 34db2ac..be82331 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -97,8 +97,14 @@ struct profile_data { }; typedef struct bluez_backend_private { +pa_hashmap *transports; } bluez_backend_private; +typedef struct bluez_transport_private { +char *owner; +char *path; +} bluez_transport_private; + struct pa_bluetooth_discovery { PA_REFCNT_DECLARE; @@ -108,7 +114,6 @@ struct pa_bluetooth_discovery { pa_bluez_version_t version; bool adapters_listed; pa_hashmap *devices; -pa_hashmap *transports; struct profile_data profiles[PA_BLUETOOTH_PROFILE_COUNT]; pa_hook hooks[PA_BLUETOOTH_HOOK_MAX]; bool filter_added; @@ -252,15 +257,32 @@ static pa_bluetooth_device* device_new(pa_bluetooth_discovery *discovery, const return d; } +static void bluez_transport_free(bluez_transport_private *p) { +pa_assert(p); + +pa_xfree(p-owner); +pa_xfree(p-path); +pa_xfree(p); +} + static void transport_free(pa_bluetooth_transport *t) { pa_assert(t); -pa_xfree(t-owner); -pa_xfree(t-path); +bluez_transport_free(t-backend_private); + pa_xfree(t-config); pa_xfree(t); } +static void bluez_backend_transport_removed(bluez_backend_private *bbp, pa_bluetooth_transport *t) { +bluez_transport_private *p; + +pa_assert(t); +pa_assert_se(p = t-backend_private); + +pa_hashmap_remove(bbp-transports, p-path); +} + static void device_free(pa_bluetooth_device *d) { pa_bluetooth_uuid *u; pa_bluetooth_transport *t; @@ -273,7 +295,7 @@ static void device_free(pa_bluetooth_device *d) { continue; d-transports[i] = NULL; -pa_hashmap_remove(d-discovery-transports, t-path); +bluez_backend_transport_removed(d-discovery-backend_private, t); t-state = PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED; pa_hook_fire(d-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED], t); transport_free(t); @@ -1070,6 +1092,10 @@ static void init_bluez(pa_bluetooth_discovery *y) { static int transport_parse_property(pa_bluetooth_transport *t, DBusMessageIter *i) { const char *key; DBusMessageIter variant_i; +bluez_transport_private *p; + +pa_assert(t); +pa_assert_se(p = t-backend_private); key = check_variant_property(i); if (key == NULL) @@ -1099,11 +1125,11 @@ static int transport_parse_property(pa_bluetooth_transport *t, DBusMessageIter * bool old_any_connected = pa_bluetooth_device_any_audio_connected(t-device); if (transport_state_from_string(value, t-state) 0) { -pa_log(Transport %s has an invalid state: '%s', t-path, value); +pa_log(Transport %s has an invalid state: '%s', p-path, value); return -1; } -pa_log_debug(dbus: transport %s set to state '%s', t-path, value); +pa_log_debug(dbus: transport %s set to state '%s', p-path, value); pa_hook_fire(t-device-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED], t); if (old_any_connected != pa_bluetooth_device_any_audio_connected(t-device)) @@ -1138,12 +1164,15 @@ static int parse_transport_properties(pa_bluetooth_transport *t, DBusMessageIter static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *userdata) { DBusError err; pa_bluetooth_discovery *y; +bluez_backend_private *bbp; pa_assert(bus); pa_assert(m); pa_assert_se(y = userdata); +bbp = y-backend_private; + dbus_error_init(err); pa_log_debug(dbus: interface=%s, path=%s, member=%s\n, @@ -1262,7 +1291,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us pa_bluetooth_transport *t; DBusMessageIter arg_i; -if (!(t = pa_hashmap_get(y-transports, dbus_message_get_path(m +if (!(t = pa_hashmap_get(bbp-transports, dbus_message_get_path(m goto fail; if (!dbus_message_iter_init(m, arg_i)) { @@ -1359,7 +1388,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us } else if (pa_streq(interface, org.bluez.MediaTransport1)) { pa_bluetooth_transport *t; -if (!(t = pa_hashmap_get(y-transports, dbus_message_get_path(m +if (!(t = pa_hashmap_get(bbp
[pulseaudio-discuss] [RFC next v0 07/11] bluetooth: Add device removed callback to backend
From: Mikel Astiz mikel.as...@bmw-carit.de This callback notifies the backend that the core needs to destroy the transport. --- src/modules/bluetooth/bluetooth-util.c | 12 ++-- src/modules/bluetooth/bluetooth-util.h | 3 +++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index be82331..744a036 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -274,9 +274,11 @@ static void transport_free(pa_bluetooth_transport *t) { pa_xfree(t); } -static void bluez_backend_transport_removed(bluez_backend_private *bbp, pa_bluetooth_transport *t) { +static void bluez_backend_transport_removed(void *bp, pa_bluetooth_transport *t) { +bluez_backend_private *bbp; bluez_transport_private *p; +pa_assert_se(bbp = bp); pa_assert(t); pa_assert_se(p = t-backend_private); @@ -291,11 +293,16 @@ static void device_free(pa_bluetooth_device *d) { pa_assert(d); for (i = 0; i PA_BLUETOOTH_PROFILE_COUNT; i++) { +pa_bluetooth_backend *backend; + if (!(t = d-transports[i])) continue; d-transports[i] = NULL; -bluez_backend_transport_removed(d-discovery-backend_private, t); + +if ((backend = d-discovery-profiles[i].backend)) + backend-transport_removed(d-discovery-profiles[i].backend_private, t); + t-state = PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED; pa_hook_fire(d-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED], t); transport_free(t); @@ -2025,6 +2032,7 @@ static DBusHandlerResult endpoint_handler(DBusConnection *c, DBusMessage *m, voi } pa_bluetooth_backend bluez_backend = { +.transport_removed = bluez_backend_transport_removed, }; static void bluez_backend_init(pa_bluetooth_discovery *y) { diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index a4d365e..e683551 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -181,7 +181,10 @@ const char *pa_bt_profile_to_string(enum profile profile); struct pa_bluetooth_backend; typedef struct pa_bluetooth_backend pa_bluetooth_backend; +typedef void (*pa_bt_backend_transport_removed_cb)(void *bp, pa_bluetooth_transport *t); + struct pa_bluetooth_backend { +pa_bt_backend_transport_removed_cb transport_removed; }; int pa_bt_backend_register(pa_bluetooth_discovery *y, pa_bluetooth_backend *b, enum profile p, void *bp); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v0 08/11] bluetooth: Add transport acquire/release callbacks to backend
From: Mikel Astiz mikel.as...@bmw-carit.de Transport acquisition and release are backend-dependant so add the necessary callbacks to struct pa_bluetooth_backend. --- src/modules/bluetooth/bluetooth-util.c | 28 src/modules/bluetooth/bluetooth-util.h | 5 + 2 files changed, 33 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 744a036..d89c7a7 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1474,6 +1474,18 @@ bool pa_bluetooth_device_any_audio_connected(const pa_bluetooth_device *d) { } int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) { +struct pa_bluetooth_discovery *y; +pa_bluetooth_backend *backend; + +pa_assert(t); +pa_assert(t-device); +pa_assert_se(y = t-device-discovery); +pa_assert_se(backend = y-profiles[t-profile].backend); + +return backend-transport_acquire(y-profiles[t-profile].backend_private, t, optional, imtu, omtu); +} + +static int bluez_backend_transport_acquire(void *bp, pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) { DBusMessage *m, *r; DBusError err; int ret; @@ -1486,6 +1498,8 @@ int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, siz pa_assert(t-device-discovery); pa_assert_se(p = t-backend_private); +assert(t); + dbus_error_init(err); if (t-device-discovery-version == BLUEZ_VERSION_4) { @@ -1546,6 +1560,18 @@ fail: } void pa_bluetooth_transport_release(pa_bluetooth_transport *t) { +struct pa_bluetooth_discovery *y; +pa_bluetooth_backend *backend; + +pa_assert(t); +pa_assert(t-device); +pa_assert_se(y = t-device-discovery); +pa_assert_se(backend = y-profiles[t-profile].backend); + +return backend-transport_release(y-profiles[t-profile].backend_private, t); +} + +static void bluez_backend_transport_release(void *bp, pa_bluetooth_transport *t) { DBusMessage *m; DBusError err; bluez_transport_private *p; @@ -2033,6 +2059,8 @@ static DBusHandlerResult endpoint_handler(DBusConnection *c, DBusMessage *m, voi pa_bluetooth_backend bluez_backend = { .transport_removed = bluez_backend_transport_removed, +.transport_acquire = bluez_backend_transport_acquire, +.transport_release = bluez_backend_transport_release, }; static void bluez_backend_init(pa_bluetooth_discovery *y) { diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index e683551..3495a1b 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -182,9 +182,14 @@ struct pa_bluetooth_backend; typedef struct pa_bluetooth_backend pa_bluetooth_backend; typedef void (*pa_bt_backend_transport_removed_cb)(void *bp, pa_bluetooth_transport *t); +typedef int (*pa_bt_backend_transport_acquire_cb)(void *bp, pa_bluetooth_transport *t, bool optional, size_t *imtu, + size_t *omtu); +typedef void (*pa_bt_backend_transport_release_cb)(void *bp, pa_bluetooth_transport *t); struct pa_bluetooth_backend { pa_bt_backend_transport_removed_cb transport_removed; +pa_bt_backend_transport_acquire_cb transport_acquire; +pa_bt_backend_transport_release_cb transport_release; }; int pa_bt_backend_register(pa_bluetooth_discovery *y, pa_bluetooth_backend *b, enum profile p, void *bp); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v0 09/11] bluetooth: Add microphone gain callback to backend
From: Mikel Astiz mikel.as...@bmw-carit.de --- src/modules/bluetooth/bluetooth-util.c | 20 +--- src/modules/bluetooth/bluetooth-util.h | 2 ++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index d89c7a7..19072d0 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1629,13 +1629,15 @@ static void set_property(pa_bluetooth_discovery *y, const char *bus, const char } void pa_bluetooth_transport_set_microphone_gain(pa_bluetooth_transport *t, uint16_t value) { -dbus_uint16_t gain = PA_MIN(value, HSP_MAX_GAIN); +pa_bluetooth_discovery *y; +pa_bluetooth_backend *backend; pa_assert(t); pa_assert(t-profile == PROFILE_HSP); +pa_assert_se(y = t-device-discovery); +pa_assert_se(backend = y-profiles[t-profile].backend); -set_property(t-device-discovery, org.bluez, t-device-path, org.bluez.Headset, - MicrophoneGain, DBUS_TYPE_UINT16, gain); +backend-set_microphone_gain(y-profiles[t-profile].backend_private, t, PA_MIN(value, HSP_MAX_GAIN)); } void pa_bluetooth_transport_set_speaker_gain(pa_bluetooth_transport *t, uint16_t value) { @@ -2057,10 +2059,22 @@ static DBusHandlerResult endpoint_handler(DBusConnection *c, DBusMessage *m, voi return DBUS_HANDLER_RESULT_HANDLED; } +static void bluez_backend_set_microphone_gain(void *bp, pa_bluetooth_transport *t, uint16_t value) +{ +dbus_uint16_t gain = value; + +pa_assert(t); +pa_assert(t-profile == PROFILE_HSP); + +set_property(t-device-discovery, org.bluez, t-device-path, org.bluez.Headset, + MicrophoneGain, DBUS_TYPE_UINT16, gain); +} + pa_bluetooth_backend bluez_backend = { .transport_removed = bluez_backend_transport_removed, .transport_acquire = bluez_backend_transport_acquire, .transport_release = bluez_backend_transport_release, +.set_microphone_gain = bluez_backend_set_microphone_gain, }; static void bluez_backend_init(pa_bluetooth_discovery *y) { diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index 3495a1b..28ab209 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -185,11 +185,13 @@ typedef void (*pa_bt_backend_transport_removed_cb)(void *bp, pa_bluetooth_transp typedef int (*pa_bt_backend_transport_acquire_cb)(void *bp, pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu); typedef void (*pa_bt_backend_transport_release_cb)(void *bp, pa_bluetooth_transport *t); +typedef void (*pa_bt_backend_set_microphone_gain_cb)(void *bp, pa_bluetooth_transport *t, uint16_t value); struct pa_bluetooth_backend { pa_bt_backend_transport_removed_cb transport_removed; pa_bt_backend_transport_acquire_cb transport_acquire; pa_bt_backend_transport_release_cb transport_release; +pa_bt_backend_set_microphone_gain_cb set_microphone_gain; }; int pa_bt_backend_register(pa_bluetooth_discovery *y, pa_bluetooth_backend *b, enum profile p, void *bp); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v0 10/11] bluetooth: Add speaker gain callback to backend
From: Mikel Astiz mikel.as...@bmw-carit.de --- src/modules/bluetooth/bluetooth-util.c | 20 +--- src/modules/bluetooth/bluetooth-util.h | 2 ++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 19072d0..92094bf 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1641,13 +1641,15 @@ void pa_bluetooth_transport_set_microphone_gain(pa_bluetooth_transport *t, uint1 } void pa_bluetooth_transport_set_speaker_gain(pa_bluetooth_transport *t, uint16_t value) { -dbus_uint16_t gain = PA_MIN(value, HSP_MAX_GAIN); +pa_bluetooth_discovery *y; +pa_bluetooth_backend *backend; pa_assert(t); pa_assert(t-profile == PROFILE_HSP); +pa_assert_se(y = t-device-discovery); +pa_assert_se(backend = y-profiles[t-profile].backend); -set_property(t-device-discovery, org.bluez, t-device-path, org.bluez.Headset, - SpeakerGain, DBUS_TYPE_UINT16, gain); +backend-set_speaker_gain(y-profiles[t-profile].backend_private, t, PA_MIN(value, HSP_MAX_GAIN)); } static int setup_dbus(pa_bluetooth_discovery *y) { @@ -2070,11 +2072,23 @@ static void bluez_backend_set_microphone_gain(void *bp, pa_bluetooth_transport * MicrophoneGain, DBUS_TYPE_UINT16, gain); } +static void bluez_backend_set_speaker_gain(void *bp, pa_bluetooth_transport *t, uint16_t value) +{ +dbus_uint16_t gain = value; + +pa_assert(t); +pa_assert(t-profile == PROFILE_HSP); + +set_property(t-device-discovery, org.bluez, t-device-path, org.bluez.Headset, + SpeakerGain, DBUS_TYPE_UINT16, gain); +} + pa_bluetooth_backend bluez_backend = { .transport_removed = bluez_backend_transport_removed, .transport_acquire = bluez_backend_transport_acquire, .transport_release = bluez_backend_transport_release, .set_microphone_gain = bluez_backend_set_microphone_gain, +.set_speaker_gain = bluez_backend_set_speaker_gain, }; static void bluez_backend_init(pa_bluetooth_discovery *y) { diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index 28ab209..1e26274 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -186,12 +186,14 @@ typedef int (*pa_bt_backend_transport_acquire_cb)(void *bp, pa_bluetooth_transpo size_t *omtu); typedef void (*pa_bt_backend_transport_release_cb)(void *bp, pa_bluetooth_transport *t); typedef void (*pa_bt_backend_set_microphone_gain_cb)(void *bp, pa_bluetooth_transport *t, uint16_t value); +typedef void (*pa_bt_backend_set_speaker_gain_cb)(void *bp, pa_bluetooth_transport *t, uint16_t value); struct pa_bluetooth_backend { pa_bt_backend_transport_removed_cb transport_removed; pa_bt_backend_transport_acquire_cb transport_acquire; pa_bt_backend_transport_release_cb transport_release; pa_bt_backend_set_microphone_gain_cb set_microphone_gain; +pa_bt_backend_set_speaker_gain_cb set_speaker_gain; }; int pa_bt_backend_register(pa_bluetooth_discovery *y, pa_bluetooth_backend *b, enum profile p, void *bp); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [RFC next v4 12/16] bluetooth: Register HSP/HFP endpoints in BlueZ 5 Media API
Hi Tanu, On Fri, May 10, 2013 at 10:01 AM, Tanu Kaskinen tanu.kaski...@intel.com wrote: On Fri, 2013-05-10 at 09:06 +0200, Mikel Astiz wrote: Hi Tanu, On Fri, May 10, 2013 at 7:48 AM, Tanu Kaskinen tanu.kaski...@intel.com wrote: On Mon, 2013-04-29 at 18:28 +0200, Mikel Astiz wrote: From: Mikel Astiz mikel.as...@bmw-carit.de Register the HSP/HFP endpoints in BlueZ 5 Media API for the sake of completeness, despite the fact that there's currently no known user of such an endpoint. --- src/modules/bluetooth/bluetooth-util.c | 5 - 1 file changed, 5 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index e3de01e..e46cbda 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -911,11 +911,6 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const static void register_adapter_endpoints(pa_bluetooth_discovery *y, const char *path) { register_endpoint(y, path, A2DP_SOURCE_ENDPOINT, A2DP_SOURCE_UUID); register_endpoint(y, path, A2DP_SINK_ENDPOINT, A2DP_SINK_UUID); - -/* For BlueZ 5, only A2DP is registered in the Media API */ -if (y-version = BLUEZ_VERSION_5) -return; - register_endpoint(y, path, HFP_AG_ENDPOINT, HFP_AG_UUID); register_endpoint(y, path, HFP_HS_ENDPOINT, HFP_HS_UUID); } So there was some discussion about whether to do this or not? Could someone reiterate the arguments for and against, or point to a relevant thread in the mail archive? The argument in favor of merging these last patches is about feature completion, as argued in [1]. BlueZ 5's Media API was designed in a way that an external telephony component could use it and automatically interact with PulseAudio. In this scenario, BlueZ not only defines the API but it also acts a component registry, in particular for org.bluez.MediaEndpoint instances which PulseAudio implements (to be more precise, the two endpoints for HFP/HSP, which are now subject of discussion). oFono was the first telephony component addressing this approach but in the early stage of implementation, it was decided that this D-Bus mechanism was not desirable. Instead, a oFono-specific API was designed to handle the interactions between oFono and PulseAudio (or other audio components). Therefore, there is no current user of BlueZ 5's MediaEndpoint1 for HFP/HSP, except for old development branches of oFono. To me the important question is: if there was a user for these endpoints, would the current code in PulseAudio work? There was a time when this patchset was working with a branch of oFono, although these patches never made upstream. It's still quite likely that issues exist and it's always going to be difficult to maintain a codebase without active users, so I see the point about leaving this endpoint out until someone actually has real interest in it. Right, I agree that we should avoid code that isn't used, so I will not push this patch. Was it so that also the rest of the set is then not necessary? As explained in the cover-letter, the decision involves the last 5 patches, that is, v4 12/16, 13/16, 14/16, 15/16 and 16/16. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v5 00/11] bluetooth: BlueZ 5 development patches
From: Mikel Astiz mikel.as...@bmw-carit.de Sending v5 with the following changes: - Leaked D-Bus matches removed as pointed out by João Paulo. - Several warning messages added as suggested by Tanu. - Minor code refactoring in pa_bluetooth_transport_release(). Again, the last 5 patches are sent for completeness despite the general consensus not to merge them. The patchset is very similar to v4 as you can see in the following diff: diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index a7b146d..27af48a 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1385,8 +1385,10 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us if (pa_streq(interface, org.bluez.Device1)) { pa_bluetooth_device *d; -if ((d = pa_hashmap_remove(y-devices, path))) { -pa_log_debug(Device %s removed, d-path); +if (!(d = pa_hashmap_remove(y-devices, path))) +pa_log_warn(Unknown device removed %s, path); +else { +pa_log_debug(Device %s removed, path); run_callback(d, true); device_free(d); } @@ -1416,8 +1418,10 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us if (pa_streq(interface, org.bluez.Device1)) { pa_bluetooth_device *d; -if (!(d = pa_hashmap_get(y-devices, dbus_message_get_path(m -return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* Device not being tracked */ +if (!(d = pa_hashmap_get(y-devices, dbus_message_get_path(m { +pa_log_warn(Property change in unknown device %s, dbus_message_get_path(m)); +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} parse_device_properties(d, arg_i, true); } else if (pa_streq(interface, org.bluez.MediaTransport1)) { @@ -1586,11 +1590,14 @@ void pa_bluetooth_transport_release(pa_bluetooth_transport *t) { pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport, Release)); pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, accesstype, DBUS_TYPE_INVALID)); -} else if (t-state = PA_BLUETOOTH_TRANSPORT_STATE_IDLE) { -pa_log_info(Transport %s auto-released by BlueZ or already released, t-path); -return; } else { pa_assert(t-device-discovery-version == BLUEZ_VERSION_5); + +if (t-state = PA_BLUETOOTH_TRANSPORT_STATE_IDLE) { +pa_log_info(Transport %s auto-released by BlueZ or already released, t-path); +return; +} + pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport1, Release)); } @@ -2245,6 +2252,10 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) { type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' +,arg0='org.bluez.Device1', + type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' +,arg0='org.bluez.MediaTransport1', NULL); if (y-filter_added) Mikel Astiz (10): bluetooth: Support ObjectManager interface add/remove bluetooth: Support Properties.PropertiesChanged signal bluetooth: Parse media transport's properties bluetooth: Support media transport's State property bluetooth: Update to new BlueZ 5 transport acquire/release API bluetooth: Support transport auto-release bluetooth: Register HSP/HFP endpoints in BlueZ 5 Media API bluetooth: Handle transports configured before UUID received bluetooth: Update to new property setter API in BlueZ 5 bluetooth: Update to volume control in BlueZ 5 Vinicius Costa Gomes (1): bluetooth: Add HFP 1.6 codec ID src/modules/bluetooth/bluetooth-util.c | 359 +--- src/modules/bluetooth/module-bluetooth-device.c | 8 +- 2 files changed, 327 insertions(+), 40 deletions(-) -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v5 01/11] bluetooth: Support ObjectManager interface add/remove
From: Mikel Astiz mikel.as...@bmw-carit.de Install matches for signals ObjectManager.InterfacesAdded and ObjectManager.InterfacesRemoved, and process the devices that are registered and unregistered dynamically. --- src/modules/bluetooth/bluetooth-util.c | 60 ++ 1 file changed, 60 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index fb8f753..cb7d3c4 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1233,6 +1233,62 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us goto fail; return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} else if (dbus_message_is_signal(m, org.freedesktop.DBus.ObjectManager, InterfacesAdded)) { +DBusMessageIter arg_i; + +if (y-version != BLUEZ_VERSION_5) +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */ + +if (!dbus_message_iter_init(m, arg_i) || !pa_streq(dbus_message_get_signature(m), oa{sa{sv}})) { +pa_log(Invalid signature found in InterfacesAdded); +goto fail; +} + +if (parse_interfaces_and_properties(y, arg_i) 0) +goto fail; + +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} else if (dbus_message_is_signal(m, org.freedesktop.DBus.ObjectManager, InterfacesRemoved)) { +const char *path; +DBusMessageIter arg_i; +DBusMessageIter element_i; + +if (y-version != BLUEZ_VERSION_5) +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */ + +if (!dbus_message_iter_init(m, arg_i) || !pa_streq(dbus_message_get_signature(m), oas)) { +pa_log(Invalid signature found in InterfacesRemoved); +goto fail; +} + +dbus_message_iter_get_basic(arg_i, path); + +pa_assert_se(dbus_message_iter_next(arg_i)); +pa_assert(dbus_message_iter_get_arg_type(arg_i) == DBUS_TYPE_ARRAY); + +dbus_message_iter_recurse(arg_i, element_i); + +while (dbus_message_iter_get_arg_type(element_i) == DBUS_TYPE_STRING) { +const char *interface; + +dbus_message_iter_get_basic(element_i, interface); + +if (pa_streq(interface, org.bluez.Device1)) { +pa_bluetooth_device *d; + +if (!(d = pa_hashmap_remove(y-devices, path))) +pa_log_warn(Unknown device removed %s, path); +else { +pa_log_debug(Device %s removed, path); +run_callback(d, true); +device_free(d); +} +} + +dbus_message_iter_next(element_i); +} + +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } fail: @@ -1890,6 +1946,8 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', NULL) 0) { pa_log(Failed to add D-Bus matches: %s, err.message); goto fail; @@ -1963,6 +2021,8 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) { type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', NULL); if (y-filter_added) -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v5 02/11] bluetooth: Support Properties.PropertiesChanged signal
From: Mikel Astiz mikel.as...@bmw-carit.de Install matches for signal Properties.PropertiesChanged and process the properties corresponding to the tracked devices. --- src/modules/bluetooth/bluetooth-util.c | 33 + 1 file changed, 33 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index cb7d3c4..a32227a 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1289,6 +1289,35 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} else if (dbus_message_is_signal(m, org.freedesktop.DBus.Properties, PropertiesChanged)) { +DBusMessageIter arg_i; +const char *interface; + +if (y-version != BLUEZ_VERSION_5) +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */ + +if (!dbus_message_iter_init(m, arg_i) || !pa_streq(dbus_message_get_signature(m), sa{sv}as)) { +pa_log(Invalid signature found in PropertiesChanged); +goto fail; +} + +dbus_message_iter_get_basic(arg_i, interface); + +pa_assert_se(dbus_message_iter_next(arg_i)); +pa_assert(dbus_message_iter_get_arg_type(arg_i) == DBUS_TYPE_ARRAY); + +if (pa_streq(interface, org.bluez.Device1)) { +pa_bluetooth_device *d; + +if (!(d = pa_hashmap_get(y-devices, dbus_message_get_path(m { +pa_log_warn(Property change in unknown device %s, dbus_message_get_path(m)); +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +parse_device_properties(d, arg_i, true); +} + +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } fail: @@ -1948,6 +1977,8 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' +,arg0='org.bluez.Device1', NULL) 0) { pa_log(Failed to add D-Bus matches: %s, err.message); goto fail; @@ -2023,6 +2054,8 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) { type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' +,arg0='org.bluez.Device1', NULL); if (y-filter_added) -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v5 03/11] bluetooth: Parse media transport's properties
From: Mikel Astiz mikel.as...@bmw-carit.de Add the code to parse the properties of the media transport object when a PropertiesChanged signal is received. Note that the transport might have an owner other than BlueZ, and thus the property changes would be emitted from arbitrary senders. For performance reasons, the installed match considers the interface name where the property has changed. It could be possible to install and remove the D-Bus matches dynamically when a new owner is registered/unregistered, but filtering based on the interface name seems good enough already. --- src/modules/bluetooth/bluetooth-util.c | 29 + 1 file changed, 29 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index a32227a..a0e6811 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1094,6 +1094,24 @@ static int transport_parse_property(pa_bluetooth_transport *t, DBusMessageIter * return 0; } +static int parse_transport_properties(pa_bluetooth_transport *t, DBusMessageIter *i) { +DBusMessageIter element_i; + +dbus_message_iter_recurse(i, element_i); + +while (dbus_message_iter_get_arg_type(element_i) == DBUS_TYPE_DICT_ENTRY) { +DBusMessageIter dict_i; + +dbus_message_iter_recurse(element_i, dict_i); + +transport_parse_property(t, dict_i); + +dbus_message_iter_next(element_i); +} + +return 0; +} + static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *userdata) { DBusError err; pa_bluetooth_discovery *y; @@ -1315,6 +1333,13 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us } parse_device_properties(d, arg_i, true); +} else if (pa_streq(interface, org.bluez.MediaTransport1)) { +pa_bluetooth_transport *t; + +if (!(t = pa_hashmap_get(y-transports, dbus_message_get_path(m +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + +parse_transport_properties(t, arg_i); } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -1979,6 +2004,8 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' ,arg0='org.bluez.Device1', + type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' +,arg0='org.bluez.MediaTransport1', NULL) 0) { pa_log(Failed to add D-Bus matches: %s, err.message); goto fail; @@ -2056,6 +2083,8 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) { type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' ,arg0='org.bluez.Device1', + type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' +,arg0='org.bluez.MediaTransport1', NULL); if (y-filter_added) -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v5 04/11] bluetooth: Support media transport's State property
From: Mikel Astiz mikel.as...@bmw-carit.de BlueZ 5 exposes a 'State' property in the media transport interface. With regard to PA, this replaces the profile-specific interfaces, since they were being used to know if the audio was streaming or not. --- src/modules/bluetooth/bluetooth-util.c | 42 +- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index a0e6811..ff8afaa 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -126,6 +126,20 @@ static pa_bt_audio_state_t audio_state_from_string(const char* value) { return PA_BT_AUDIO_STATE_INVALID; } +static int transport_state_from_string(const char* value, pa_bluetooth_transport_state_t *state) { +pa_assert(value); +pa_assert(state); + +if (pa_streq(value, idle)) +*state = PA_BLUETOOTH_TRANSPORT_STATE_IDLE; +else if (pa_streq(value, pending) || pa_streq(value, active)) /* We don't need such a separation */ +*state = PA_BLUETOOTH_TRANSPORT_STATE_PLAYING; +else +return -1; + +return 0; +} + const char *pa_bt_profile_to_string(enum profile profile) { switch(profile) { case PROFILE_A2DP: @@ -1089,6 +1103,29 @@ static int transport_parse_property(pa_bluetooth_transport *t, DBusMessageIter * break; } + +case DBUS_TYPE_STRING: { + +const char *value; +dbus_message_iter_get_basic(variant_i, value); + +if (pa_streq(key, State)) { /* Added in BlueZ 5.0 */ +bool old_any_connected = pa_bluetooth_device_any_audio_connected(t-device); + +if (transport_state_from_string(value, t-state) 0) { +pa_log(Transport %s has an invalid state: '%s', t-path, value); +return -1; +} + +pa_log_debug(dbus: transport %s set to state '%s', t-path, value); + pa_hook_fire(t-device-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED], t); + +if (old_any_connected != pa_bluetooth_device_any_audio_connected(t-device)) +run_callback(t-device, old_any_connected); +} + +break; +} } return 0; @@ -1567,7 +1604,10 @@ static pa_bluetooth_transport *transport_new(pa_bluetooth_device *d, const char memcpy(t-config, config, size); } -t-state = audio_state_to_transport_state(d-profile_state[p]); +if (d-discovery-version == BLUEZ_VERSION_4) +t-state = audio_state_to_transport_state(d-profile_state[p]); +else +t-state = PA_BLUETOOTH_TRANSPORT_STATE_IDLE; return t; } -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v5 05/11] bluetooth: Update to new BlueZ 5 transport acquire/release API
From: Mikel Astiz mikel.as...@bmw-carit.de The new D-Bus API doesn't support access rights, which weren't used by PulseAudio anyway, but it does solve a race condition: now optional acquires can be implemented by bluetooth-util atomically using the D-Bus TryAcquire() method. --- src/modules/bluetooth/bluetooth-util.c | 66 +++-- src/modules/bluetooth/module-bluetooth-device.c | 8 +-- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index ff8afaa..2e794ac 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1452,40 +1452,52 @@ bool pa_bluetooth_device_any_audio_connected(const pa_bluetooth_device *d) { } int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) { -const char *accesstype = rw; -const char *interface; DBusMessage *m, *r; DBusError err; int ret; uint16_t i, o; +const char *method; pa_assert(t); pa_assert(t-device); pa_assert(t-device-discovery); -interface = t-device-discovery-version == BLUEZ_VERSION_4 ? org.bluez.MediaTransport : org.bluez.MediaTransport1; - -if (optional) { -/* FIXME: we are trying to acquire the transport only if the stream is - playing, without actually initiating the stream request from our side - (which is typically undesireable specially for hfgw use-cases. - However this approach is racy, since the stream could have been - suspended in the meantime, so we can't really guarantee that the - stream will not be requested until BlueZ's API supports this - atomically. */ -if (t-state PA_BLUETOOTH_TRANSPORT_STATE_PLAYING) { -pa_log_info(Failed optional acquire of transport %s, t-path); -return -1; +dbus_error_init(err); + +if (t-device-discovery-version == BLUEZ_VERSION_4) { +const char *accesstype = rw; + +if (optional) { +/* We are trying to acquire the transport only if the stream is + playing, without actually initiating the stream request from our side + (which is typically undesireable specially for hfgw use-cases. + However this approach is racy, since the stream could have been + suspended in the meantime, so we can't really guarantee that the + stream will not be requested with the API in BlueZ 4.x */ +if (t-state PA_BLUETOOTH_TRANSPORT_STATE_PLAYING) { +pa_log_info(Failed optional acquire of unavailable transport %s, t-path); +return -1; +} } -} -dbus_error_init(err); +method = Acquire; +pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport, method)); +pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, accesstype, DBUS_TYPE_INVALID)); +} else { +pa_assert(t-device-discovery-version == BLUEZ_VERSION_5); + +method = optional ? TryAcquire : Acquire; +pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport1, method)); +} -pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, interface, Acquire)); -pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, accesstype, DBUS_TYPE_INVALID)); r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t-device-discovery-connection), m, -1, err); if (!r) { +if (optional pa_streq(err.name, org.bluez.Error.NotAvailable)) +pa_log_info(Failed optional acquire of unavailable transport %s, t-path); +else +pa_log(Transport %s() failed for transport %s (%s), method, t-path, err.message); + dbus_error_free(err); return -1; } @@ -1510,8 +1522,6 @@ fail: } void pa_bluetooth_transport_release(pa_bluetooth_transport *t) { -const char *accesstype = rw; -const char *interface; DBusMessage *m; DBusError err; @@ -1519,12 +1529,18 @@ void pa_bluetooth_transport_release(pa_bluetooth_transport *t) { pa_assert(t-device); pa_assert(t-device-discovery); -interface = t-device-discovery-version == BLUEZ_VERSION_4 ? org.bluez.MediaTransport : org.bluez.MediaTransport1; - dbus_error_init(err); -pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, interface, Release)); -pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, accesstype, DBUS_TYPE_INVALID)); +if (t-device-discovery-version == BLUEZ_VERSION_4) { +const char *accesstype = rw; + +pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport, Release)); +pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, accesstype, DBUS_TYPE_INVALID)); +} else
[pulseaudio-discuss] [RFC next v5 06/11] bluetooth: Support transport auto-release
From: Mikel Astiz mikel.as...@bmw-carit.de With BlueZ 5, if the remote device suspends the audio, the transport state will change to idle and the endpoint is not required to release the transport, since this could introduce race conditions. Therefore, ignore the call to pa_bluetooth_transport_release() if the transport is not acquired any more. --- src/modules/bluetooth/bluetooth-util.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 2e794ac..5924736 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1538,6 +1538,12 @@ void pa_bluetooth_transport_release(pa_bluetooth_transport *t) { pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, accesstype, DBUS_TYPE_INVALID)); } else { pa_assert(t-device-discovery-version == BLUEZ_VERSION_5); + +if (t-state = PA_BLUETOOTH_TRANSPORT_STATE_IDLE) { +pa_log_info(Transport %s auto-released by BlueZ or already released, t-path); +return; +} + pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport1, Release)); } -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v5 07/11] bluetooth: Register HSP/HFP endpoints in BlueZ 5 Media API
From: Mikel Astiz mikel.as...@bmw-carit.de Register the HSP/HFP endpoints in BlueZ 5 Media API for the sake of completeness, despite the fact that there's currently no known user of such an endpoint. --- src/modules/bluetooth/bluetooth-util.c | 5 - 1 file changed, 5 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 5924736..2418f2d 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -911,11 +911,6 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const static void register_adapter_endpoints(pa_bluetooth_discovery *y, const char *path) { register_endpoint(y, path, A2DP_SOURCE_ENDPOINT, A2DP_SOURCE_UUID); register_endpoint(y, path, A2DP_SINK_ENDPOINT, A2DP_SINK_UUID); - -/* For BlueZ 5, only A2DP is registered in the Media API */ -if (y-version = BLUEZ_VERSION_5) -return; - register_endpoint(y, path, HFP_AG_ENDPOINT, HFP_AG_UUID); register_endpoint(y, path, HFP_HS_ENDPOINT, HFP_HS_UUID); } -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v5 09/11] bluetooth: Handle transports configured before UUID received
From: Mikel Astiz mikel.as...@bmw-carit.de Now that the transport can be configured from some other process (i.e. oFono), there is no guarantee that the UUID from BlueZ will already have been received. This requires PulseAudio to assume that the UUID is actually supported by the device and that BlueZ will eventually propagate it. --- src/modules/bluetooth/bluetooth-util.c | 53 ++ 1 file changed, 53 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index d9f268d..9b76ce5 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -178,6 +178,33 @@ static int profile_from_interface(const char *interface, enum profile *p) { return -1; } +static void profile_to_remote_uuid(enum profile p, const char *res[2]) { +pa_assert(p != PROFILE_OFF); + +switch(p) { +case PROFILE_A2DP: +res[0] = A2DP_SINK_UUID; +res[1] = NULL; +return; +case PROFILE_A2DP_SOURCE: +res[0] = A2DP_SOURCE_UUID; +res[1] = NULL; +return; +case PROFILE_HSP: +res[0] = HSP_HS_UUID; +res[1] = HFP_HS_UUID; +return; +case PROFILE_HFGW: +res[0] = HSP_AG_UUID; +res[1] = HFP_AG_UUID; +return; +case PROFILE_OFF: +break; +} + +pa_assert_not_reached(); +} + static pa_bluetooth_transport_state_t audio_state_to_transport_state(pa_bt_audio_state_t state) { switch (state) { case PA_BT_AUDIO_STATE_INVALID: /* Typically if state hasn't been received yet */ @@ -1647,6 +1674,7 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage DBusMessageIter args, props; DBusMessage *r; bool old_any_connected; +const char *remote_uuid[2]; if (!dbus_message_iter_init(m, args) || !pa_streq(dbus_message_get_signature(m), oa{sv})) { pa_log(Invalid signature for method SetConfiguration); @@ -1709,6 +1737,10 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage dbus_message_iter_next(props); } +/* FIXME: with BlueZ 5, check if this is racy in case a newly paired + * device gets connected very fast, before BlueZ has created it. This is + * very unlikely since the device will be created before the pairing + * procedure is complete */ d = found_device(y, dev_path); if (!d) goto fail; @@ -1722,6 +1754,27 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage else p = PROFILE_A2DP_SOURCE; +/* Check if the UUID was already reported by BlueZ, since the telephony + * component (oFono) could be faster than BlueZ */ +profile_to_remote_uuid(p, remote_uuid); + +if (!pa_bluetooth_uuid_has(d-uuids, remote_uuid[0]) !pa_bluetooth_uuid_has(d-uuids, remote_uuid[1])) { +pa_bluetooth_uuid *node; +struct pa_bluetooth_hook_uuid_data uuiddata; + +pa_log_info(Endpoint with UUID '%s' configured before remote UUID was reported by BlueZ., uuid); + +/* This might generate duplicated UUID_ADDED hooks since the endpoint + * doesn't receive the exact remote UUID (HSP cannot be distinguished + * from HFP). However, these duplicated hooks should do no harm */ +node = uuid_new(remote_uuid[0]); +PA_LLIST_PREPEND(pa_bluetooth_uuid, d-uuids, node); + +uuiddata.device = d; +uuiddata.uuid = uuid; + pa_hook_fire(d-discovery-hooks[PA_BLUETOOTH_HOOK_DEVICE_UUID_ADDED], uuiddata); +} + if (d-transports[p] != NULL) { pa_log(Cannot configure transport %s because profile %d is already used, path, p); goto fail2; -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v5 10/11] bluetooth: Update to new property setter API in BlueZ 5
From: Mikel Astiz mikel.as...@bmw-carit.de If BlueZ 5 is in use, the standard org.freedesktop.DBus.Properties needs to be used instead of the old SetProperty() method. --- src/modules/bluetooth/bluetooth-util.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 9b76ce5..faad5b2 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1594,6 +1594,20 @@ static void set_property(pa_bluetooth_discovery *y, const char *bus, const char pa_assert(interface); pa_assert(prop_name); +if (y-version = BLUEZ_VERSION_5) { +pa_assert_se(m = dbus_message_new_method_call(bus, path, org.freedesktop.DBus.Properties, Set)); +dbus_message_iter_init_append(m, i); +dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, interface); +dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, prop_name); +pa_dbus_append_basic_variant(i, prop_type, prop_value); + +dbus_message_set_no_reply(m, true); + pa_assert_se(dbus_connection_send(pa_dbus_connection_get(y-connection), m, NULL)); +dbus_message_unref(m); + +return; +} + pa_assert_se(m = dbus_message_new_method_call(bus, path, interface, SetProperty)); dbus_message_iter_init_append(m, i); dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, prop_name); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v5 11/11] bluetooth: Update to volume control in BlueZ 5
From: Mikel Astiz mikel.as...@bmw-carit.de In BlueZ 5, the microphone and speaker gains are exposed as properties of the MediaTransport1 interface. --- src/modules/bluetooth/bluetooth-util.c | 41 ++ 1 file changed, 41 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index faad5b2..27af48a 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1154,6 +1154,32 @@ static int transport_parse_property(pa_bluetooth_transport *t, DBusMessageIter * break; } + +case DBUS_TYPE_BYTE: { +uint8_t value; + +dbus_message_iter_get_basic(variant_i, value); + +if (pa_streq(key, MicrophoneGain)) { +uint8_t gain; + +if ((gain = PA_MIN(value, HSP_MAX_GAIN)) == t-microphone_gain) +break; + +t-microphone_gain = gain; + pa_hook_fire(t-device-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED], t); +} else if (pa_streq(key, SpeakerGain)) { +uint8_t gain; + +if ((gain = PA_MIN(value, HSP_MAX_GAIN)) == t-speaker_gain) +break; + +t-speaker_gain = gain; + pa_hook_fire(t-device-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED], t); +} + +break; +} } return 0; @@ -1624,6 +1650,14 @@ void pa_bluetooth_transport_set_microphone_gain(pa_bluetooth_transport *t, uint1 pa_assert(t); pa_assert(t-profile == PROFILE_HSP); +if (t-device-discovery-version = BLUEZ_VERSION_5) { +uint8_t g = (uint8_t) gain; + +set_property(t-device-discovery, t-owner, t-path, org.bluez.MediaTransport1, + MicrophoneGain, DBUS_TYPE_BYTE, g); +return; +} + set_property(t-device-discovery, org.bluez, t-device-path, org.bluez.Headset, MicrophoneGain, DBUS_TYPE_UINT16, gain); } @@ -1634,6 +1668,13 @@ void pa_bluetooth_transport_set_speaker_gain(pa_bluetooth_transport *t, uint16_t pa_assert(t); pa_assert(t-profile == PROFILE_HSP); +if (t-device-discovery-version = BLUEZ_VERSION_5) { +uint8_t g = (uint8_t) gain; + +set_property(t-device-discovery, t-owner, t-path, org.bluez.MediaTransport1, SpeakerGain, DBUS_TYPE_BYTE, g); +return; +} + set_property(t-device-discovery, org.bluez, t-device-path, org.bluez.Headset, SpeakerGain, DBUS_TYPE_UINT16, gain); } -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v5 08/11] bluetooth: Add HFP 1.6 codec ID
From: Vinicius Costa Gomes vinicius.go...@openbossa.org According to the HFP 1.6 spec, the default codec (CVSD) has ID 0x01. This change has no effect in older versions of BlueZ since the codec ID was ignored for HFP, due to the fact that HFP versions prior to 1.6 do not have such a field. --- src/modules/bluetooth/bluetooth-util.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 2418f2d..d9f268d 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -864,7 +864,7 @@ finish: static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const char *endpoint, const char *uuid) { DBusMessage *m; DBusMessageIter i, d; -uint8_t codec = 0; +uint8_t codec; const char *interface = y-version == BLUEZ_VERSION_4 ? org.bluez.Media : org.bluez.Media1; pa_log_debug(Registering %s on adapter %s., endpoint, path); @@ -881,14 +881,18 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const pa_dbus_append_basic_variant_dict_entry(d, UUID, DBUS_TYPE_STRING, uuid); -pa_dbus_append_basic_variant_dict_entry(d, Codec, DBUS_TYPE_BYTE, codec); if (pa_streq(uuid, HFP_AG_UUID) || pa_streq(uuid, HFP_HS_UUID)) { uint8_t capability = 0; + +codec = 1; + pa_dbus_append_basic_array_variant_dict_entry(d, Capabilities, DBUS_TYPE_BYTE, capability, 1); } else { a2dp_sbc_t capabilities; +codec = 0; + capabilities.channel_mode = SBC_CHANNEL_MODE_MONO | SBC_CHANNEL_MODE_DUAL_CHANNEL | SBC_CHANNEL_MODE_STEREO | SBC_CHANNEL_MODE_JOINT_STEREO; capabilities.frequency = SBC_SAMPLING_FREQ_16000 | SBC_SAMPLING_FREQ_32000 | @@ -903,6 +907,8 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const pa_dbus_append_basic_array_variant_dict_entry(d, Capabilities, DBUS_TYPE_BYTE, capabilities, sizeof(capabilities)); } +pa_dbus_append_basic_variant_dict_entry(d, Codec, DBUS_TYPE_BYTE, codec); + dbus_message_iter_close_container(i, d); send_and_add_to_pending(y, m, register_endpoint_reply, pa_xstrdup(endpoint)); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [RFC next v4 04/16] bluetooth: Support Properties.PropertiesChanged signal
Hi Tanu, On Thu, May 9, 2013 at 10:30 AM, Tanu Kaskinen tanu.kaski...@intel.com wrote: On Mon, 2013-04-29 at 18:28 +0200, Mikel Astiz wrote: From: Mikel Astiz mikel.as...@bmw-carit.de Install matches for signal Properties.PropertiesChanged and process the properties corresponding to the tracked devices. --- src/modules/bluetooth/bluetooth-util.c | 29 + 1 file changed, 29 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index c60f3ff..cd72ffd 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1263,6 +1263,33 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} else if (dbus_message_is_signal(m, org.freedesktop.DBus.Properties, PropertiesChanged)) { +DBusMessageIter arg_i; +const char *interface; + +if (y-version != BLUEZ_VERSION_5) +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */ + +if (!dbus_message_iter_init(m, arg_i) || !pa_streq(dbus_message_get_signature(m), sa{sv}as)) { +pa_log(Invalid signature found in PropertiesChanged); +goto fail; +} + +dbus_message_iter_get_basic(arg_i, interface); + +pa_assert_se(dbus_message_iter_next(arg_i)); +pa_assert(dbus_message_iter_get_arg_type(arg_i) == DBUS_TYPE_ARRAY); + +if (pa_streq(interface, org.bluez.Device1)) { +pa_bluetooth_device *d; + +if (!(d = pa_hashmap_get(y-devices, dbus_message_get_path(m +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* Device not being tracked */ Can it really happen that a device is not being tracked? If not, a warning or error should be logged. Current approach should track all devices and mark device_info_valid == -1 in case some inconsistency is found. I believe this error-case is only possible if BlueZ is misbehaving or we have a bug in PulseAudio, so a warning sounds fine to me. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [RFC next v4 04/16] bluetooth: Support Properties.PropertiesChanged signal
Hi João Paulo, On Tue, May 7, 2013 at 12:01 AM, João Paulo Rechi Vita jprv...@gmail.com wrote: On Mon, Apr 29, 2013 at 1:28 PM, Mikel Astiz mikel.astiz@gmail.com wrote: From: Mikel Astiz mikel.as...@bmw-carit.de Install matches for signal Properties.PropertiesChanged and process the properties corresponding to the tracked devices. --- src/modules/bluetooth/bluetooth-util.c | 29 + 1 file changed, 29 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index c60f3ff..cd72ffd 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1263,6 +1263,33 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} else if (dbus_message_is_signal(m, org.freedesktop.DBus.Properties, PropertiesChanged)) { +DBusMessageIter arg_i; +const char *interface; + +if (y-version != BLUEZ_VERSION_5) +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */ + +if (!dbus_message_iter_init(m, arg_i) || !pa_streq(dbus_message_get_signature(m), sa{sv}as)) { +pa_log(Invalid signature found in PropertiesChanged); +goto fail; +} + +dbus_message_iter_get_basic(arg_i, interface); + +pa_assert_se(dbus_message_iter_next(arg_i)); +pa_assert(dbus_message_iter_get_arg_type(arg_i) == DBUS_TYPE_ARRAY); + +if (pa_streq(interface, org.bluez.Device1)) { +pa_bluetooth_device *d; + +if (!(d = pa_hashmap_get(y-devices, dbus_message_get_path(m +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* Device not being tracked */ + +parse_device_properties(d, arg_i, true); +} + +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } fail: @@ -1917,6 +1944,8 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' +,arg0='org.bluez.Device1', Why are you not removing this match on pa_bluetooth_discovery_unref()? Both matches should be removed pa_bluetooth_discovery_unref(), thanks for pointing it out. I'll fix this for v5. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [RFC next v4 00/16] bluetooth: BlueZ 5 development patches
Hi João Paulo, On Thu, May 2, 2013 at 10:05 PM, João Paulo Rechi Vita jprv...@gmail.com wrote: On Thu, May 2, 2013 at 4:17 AM, Mikel Astiz mikel.astiz@gmail.com wrote: Hi João Paulo, On Tue, Apr 30, 2013 at 9:13 PM, João Paulo Rechi Vita jprv...@gmail.com wrote: On Tue, Apr 30, 2013 at 7:20 AM, Luiz Augusto von Dentz luiz.de...@gmail.com wrote: Hi Mikel, On Mon, Apr 29, 2013 at 7:27 PM, Mikel Astiz mikel.astiz@gmail.com wrote: From: Mikel Astiz mikel.as...@bmw-carit.de Resending v3 with a small change in patch 3/16, where the Name property of org.bluez.Device1 is now considered as optional. This version is intended for the next branch since it depends on module-bluetooth-device not making use of device-name, which could now be potentially NULL. Note that the last 5 patches are somewhat controversial (see below) and it might therefore be desireable to keep them on hold. From previous cover-letter: The discussion raised by João Paulo is whether the HSP/HFP endpoint should be registered or not, and the few associated features implemented. Luiz suggested it'd be good in any case to have the patches for reference, so I'm sending the full patchset (including the HSP/HFP part) reworked in a way that such code is grouped in the end (starting with v3 12/16). Mikel Astiz (15): bluetooth: Detect BlueZ 5 bluetooth: Parse the tree returned by ObjectManager bluetooth: Support ObjectManager interface add/remove bluetooth: Support Properties.PropertiesChanged signal bluetooth: BlueZ 5 interface rename to org.bluez.MediaEndpoint1 bluetooth: BlueZ 5 interface rename to org.bluez.Media1 bluetooth: BlueZ 5 interface rename to org.bluez.MediaTransport1 bluetooth: Parse media transport's properties bluetooth: Support media transport's State property bluetooth: Update to new BlueZ 5 transport acquire/release API bluetooth: Support transport auto-release bluetooth: Register HSP/HFP endpoints in BlueZ 5 Media API bluetooth: Handle transports configured before UUID received bluetooth: Update to new property setter API in BlueZ 5 bluetooth: Update to volume control in BlueZ 5 Vinicius Costa Gomes (1): bluetooth: Add HFP 1.6 codec ID src/modules/bluetooth/bluetooth-util.c | 568 ++-- src/modules/bluetooth/module-bluetooth-device.c | 8 +- 2 files changed, 521 insertions(+), 55 deletions(-) -- 1.8.1.4 Ack from my side. As I mentioned before, if we want to split transport backends BlueZ 4 and BlueZ 5 should be implemented as backends as well. I don't see the point of having only oFono as a separate backend. The point is just practical: this patchset has been around for quite a while a several people have reviewed and tested it. I agree that the backend-specific code of both BlueZ 4 and 5 could be moved somewhere outside bluetooth-util, but I don't find it critical. It's definitely not comparable to the need to separate the oFono backend. In a similar way, we shouldn't necessarily separate the oFono backend from ofono-util, which could potentially support other functionality beyond the backend itself (e.g. call-state tracking). So being pragmatic and in order to avoid more delays, I insist on merging this patchset first and then discussing further steps. If so I think we should treat the oFono patches in the same way, merge it first and separate it later, which was what I preferred in the first place. I disagree with this as pointed out several times. bluetooth-util already has a dependecy to BlueZ as opposed to oFono which makes a big difference. I see no strong argument to merge oFono code before having a nice split of backends. Besides, I already proposed a first approach to add the backend infrastructure so I believe we should be able to have progress quickly once the BlueZ 5 patchset gets merged. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [RFC next v4 00/16] bluetooth: BlueZ 5 development patches
Hi João Paulo, On Tue, Apr 30, 2013 at 9:13 PM, João Paulo Rechi Vita jprv...@gmail.com wrote: On Tue, Apr 30, 2013 at 7:20 AM, Luiz Augusto von Dentz luiz.de...@gmail.com wrote: Hi Mikel, On Mon, Apr 29, 2013 at 7:27 PM, Mikel Astiz mikel.astiz@gmail.com wrote: From: Mikel Astiz mikel.as...@bmw-carit.de Resending v3 with a small change in patch 3/16, where the Name property of org.bluez.Device1 is now considered as optional. This version is intended for the next branch since it depends on module-bluetooth-device not making use of device-name, which could now be potentially NULL. Note that the last 5 patches are somewhat controversial (see below) and it might therefore be desireable to keep them on hold. From previous cover-letter: The discussion raised by João Paulo is whether the HSP/HFP endpoint should be registered or not, and the few associated features implemented. Luiz suggested it'd be good in any case to have the patches for reference, so I'm sending the full patchset (including the HSP/HFP part) reworked in a way that such code is grouped in the end (starting with v3 12/16). Mikel Astiz (15): bluetooth: Detect BlueZ 5 bluetooth: Parse the tree returned by ObjectManager bluetooth: Support ObjectManager interface add/remove bluetooth: Support Properties.PropertiesChanged signal bluetooth: BlueZ 5 interface rename to org.bluez.MediaEndpoint1 bluetooth: BlueZ 5 interface rename to org.bluez.Media1 bluetooth: BlueZ 5 interface rename to org.bluez.MediaTransport1 bluetooth: Parse media transport's properties bluetooth: Support media transport's State property bluetooth: Update to new BlueZ 5 transport acquire/release API bluetooth: Support transport auto-release bluetooth: Register HSP/HFP endpoints in BlueZ 5 Media API bluetooth: Handle transports configured before UUID received bluetooth: Update to new property setter API in BlueZ 5 bluetooth: Update to volume control in BlueZ 5 Vinicius Costa Gomes (1): bluetooth: Add HFP 1.6 codec ID src/modules/bluetooth/bluetooth-util.c | 568 ++-- src/modules/bluetooth/module-bluetooth-device.c | 8 +- 2 files changed, 521 insertions(+), 55 deletions(-) -- 1.8.1.4 Ack from my side. As I mentioned before, if we want to split transport backends BlueZ 4 and BlueZ 5 should be implemented as backends as well. I don't see the point of having only oFono as a separate backend. The point is just practical: this patchset has been around for quite a while a several people have reviewed and tested it. I agree that the backend-specific code of both BlueZ 4 and 5 could be moved somewhere outside bluetooth-util, but I don't find it critical. It's definitely not comparable to the need to separate the oFono backend. In a similar way, we shouldn't necessarily separate the oFono backend from ofono-util, which could potentially support other functionality beyond the backend itself (e.g. call-state tracking). So being pragmatic and in order to avoid more delays, I insist on merging this patchset first and then discussing further steps. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [PATCH 1/3] bluetooth: Add 'bluez.alias' property
Hi Tanu, On Mon, Apr 29, 2013 at 4:01 PM, Tanu Kaskinen tanu.kaski...@intel.com wrote: On Fri, 2013-04-26 at 12:30 -0300, jprv...@gmail.com wrote: From: João Paulo Rechi Vita jprv...@openbossa.org --- As already discussed with Tanuk and Mikel, this series should be applied to the master branch. I don't remember there being any talk about pushing this series to the master branch. I will use next, unless you have a good reason why this needs to be in 4.0. Sounds good. src/modules/bluetooth/module-bluetooth-device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index c877df2..8695c80 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2243,6 +2243,7 @@ static int add_card(struct userdata *u) { pa_proplist_sets(data.proplist, bluez.path, device-path); pa_proplist_setf(data.proplist, bluez.class, 0x%06x, (unsigned) device-class); pa_proplist_sets(data.proplist, bluez.name, device-name); +pa_proplist_sets(data.proplist, bluez.alias, device-alias); device-alias is not guaranteed to be non-NULL, so this code can crash. If the Alias property is non-optional in Bluez, bluetooth-util should ensure that it is indeed always set. BlueZ 4 API guarantees the property will be present, and therefore device-alias should always be set. The obvious exception is BlueZ misbehaving, but this condition might hold true for device-name as well, which we're not checking either. I don't think there's any other scenario where the alias could be NULL and the name be set outside bluetooth-util. So while your point is valid, I suggest we fix this in a later patch, in a similar way that the BlueZ 5 patchset does (set device_info_valid to -1 if any non-optional property is missing). Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [PATCH 1/3] bluetooth: Add 'bluez.alias' property
Hi Tanu, On Mon, Apr 29, 2013 at 4:38 PM, Tanu Kaskinen tanu.kaski...@intel.com wrote: On Mon, 2013-04-29 at 16:20 +0200, Mikel Astiz wrote: On Mon, Apr 29, 2013 at 4:01 PM, Tanu Kaskinen tanu.kaski...@intel.com wrote: On Fri, 2013-04-26 at 12:30 -0300, jprv...@gmail.com wrote: src/modules/bluetooth/module-bluetooth-device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index c877df2..8695c80 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2243,6 +2243,7 @@ static int add_card(struct userdata *u) { pa_proplist_sets(data.proplist, bluez.path, device-path); pa_proplist_setf(data.proplist, bluez.class, 0x%06x, (unsigned) device-class); pa_proplist_sets(data.proplist, bluez.name, device-name); +pa_proplist_sets(data.proplist, bluez.alias, device-alias); device-alias is not guaranteed to be non-NULL, so this code can crash. If the Alias property is non-optional in Bluez, bluetooth-util should ensure that it is indeed always set. BlueZ 4 API guarantees the property will be present, and therefore device-alias should always be set. The obvious exception is BlueZ misbehaving, but this condition might hold true for device-name as well, which we're not checking either. I don't think there's any other scenario where the alias could be NULL and the name be set outside bluetooth-util. So while your point is valid, I suggest we fix this in a later patch, in a similar way that the BlueZ 5 patchset does (set device_info_valid to -1 if any non-optional property is missing). Ah, so this is fixed at least for BlueZ 5. Will the same property parsing code be used for BlueZ 4? If not, does somebody promise to write the fix for BlueZ 4? The codepath will be completely different for BlueZ 4 and 5, due to the fundamental difference in how objects and properties are gathered with or without the ObjectManager interface. Fixing this for BlueZ 4 is desirable but not critical IMO, since it's very unlikely that we hit this issue (based on how BlueZ 4 implements GetProperties()). Besides, the fix seems non-trivial and there's always the possibility to introduce regressions. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [PATCH 1/3] bluetooth: Add 'bluez.alias' property
Hi João Paulo, On Mon, Apr 29, 2013 at 5:51 PM, João Paulo Rechi Vita jprv...@openbossa.org wrote: On Mon, Apr 29, 2013 at 11:59 AM, Tanu Kaskinen tanu.kaski...@intel.com wrote: On Mon, 2013-04-29 at 11:49 -0300, João Paulo Rechi Vita wrote: On Mon, Apr 29, 2013 at 11:38 AM, Tanu Kaskinen tanu.kaski...@intel.com wrote: On Mon, 2013-04-29 at 16:20 +0200, Mikel Astiz wrote: On Mon, Apr 29, 2013 at 4:01 PM, Tanu Kaskinen tanu.kaski...@intel.com wrote: On Fri, 2013-04-26 at 12:30 -0300, jprv...@gmail.com wrote: src/modules/bluetooth/module-bluetooth-device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index c877df2..8695c80 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2243,6 +2243,7 @@ static int add_card(struct userdata *u) { pa_proplist_sets(data.proplist, bluez.path, device-path); pa_proplist_setf(data.proplist, bluez.class, 0x%06x, (unsigned) device-class); pa_proplist_sets(data.proplist, bluez.name, device-name); +pa_proplist_sets(data.proplist, bluez.alias, device-alias); device-alias is not guaranteed to be non-NULL, so this code can crash. If the Alias property is non-optional in Bluez, bluetooth-util should ensure that it is indeed always set. BlueZ 4 API guarantees the property will be present, and therefore device-alias should always be set. The obvious exception is BlueZ misbehaving, but this condition might hold true for device-name as well, which we're not checking either. I don't think there's any other scenario where the alias could be NULL and the name be set outside bluetooth-util. So while your point is valid, I suggest we fix this in a later patch, in a similar way that the BlueZ 5 patchset does (set device_info_valid to -1 if any non-optional property is missing). Ah, so this is fixed at least for BlueZ 5. Will the same property parsing code be used for BlueZ 4? If not, does somebody promise to write the fix for BlueZ 4? Both in BlueZ 5 and BlueZ 4 the 'Alias' property is not optional, if it's not present it's a bug in BlueZ. I don't think we should protect ourselfs more than the usual asserts before dereferencing pointers. Yes, but our policy is to use assertions only for guarding against bugs in our own process. Assertions are not used for handling bugs in other processes, such as bluetoothd. If the property is not set but everything else is fine the only thing that will be missing is a value for PA_PROP_DEVICE_DESCRIPTION. Depending on how PulseAudio deals with description-less devices we can either not care or set a default description. Setting the device_info to invalid makes the device unusable. I'm not sure if you're saying that it's fine to call pa_proplist_sets() with a NULL value? It's not fine, it will cause a crash (due to an assertion in pa_proplist_sets()). No, I'm asking if it's fine not to call 'pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, Some string here)' before calling 'pa_card_new(core, data)', that is, never setting the value of PA_PROP_DEVICE_DESCRIPTION. If it's not fine (that is, we cannot leave PA_PROP_DEVICE_DESCRIPTION empty) I suggest we set it to a default value, or an empty string, instead of making the device unusable. Making the device unusable is an acceptable (and IMHO the best) way of handling BlueZ bugs. But if everybody else thinks that doing it for BlueZ 4 is waste of time, I won't insist on doing it. I don't think is a waste of time, and this discussion is also valid for how this case should be handled in BlueZ 5. I agree the bug is in BlueZ in this case, but if we can recover without any operational loss from it, I think it's better to do so. As Tanu already pointed out, assertions should be limited to detecting internal issues in PulseAudio, regardless of external misbehaviors (with the exception of libraries IIRC). There have been similar discussions in the mailing list before. In the particular case of D-Bus misbehaviors, I believe we should theoretically reset the connection completely, since we can't make any assumptions about a component that is not behaving as expected. However, being more pragmatic, having a fallback mechanism in some cases seems reasonable, like in this example, where we can ignore objects (i.e. devices) that lack some of the non-optional properties. We should IMO avoid trying to set default values for missing non-optional properties, since this obfuscates the codebase and might hide the root issue. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v4 00/16] bluetooth: BlueZ 5 development patches
From: Mikel Astiz mikel.as...@bmw-carit.de Resending v3 with a small change in patch 3/16, where the Name property of org.bluez.Device1 is now considered as optional. This version is intended for the next branch since it depends on module-bluetooth-device not making use of device-name, which could now be potentially NULL. Note that the last 5 patches are somewhat controversial (see below) and it might therefore be desireable to keep them on hold. From previous cover-letter: The discussion raised by João Paulo is whether the HSP/HFP endpoint should be registered or not, and the few associated features implemented. Luiz suggested it'd be good in any case to have the patches for reference, so I'm sending the full patchset (including the HSP/HFP part) reworked in a way that such code is grouped in the end (starting with v3 12/16). Mikel Astiz (15): bluetooth: Detect BlueZ 5 bluetooth: Parse the tree returned by ObjectManager bluetooth: Support ObjectManager interface add/remove bluetooth: Support Properties.PropertiesChanged signal bluetooth: BlueZ 5 interface rename to org.bluez.MediaEndpoint1 bluetooth: BlueZ 5 interface rename to org.bluez.Media1 bluetooth: BlueZ 5 interface rename to org.bluez.MediaTransport1 bluetooth: Parse media transport's properties bluetooth: Support media transport's State property bluetooth: Update to new BlueZ 5 transport acquire/release API bluetooth: Support transport auto-release bluetooth: Register HSP/HFP endpoints in BlueZ 5 Media API bluetooth: Handle transports configured before UUID received bluetooth: Update to new property setter API in BlueZ 5 bluetooth: Update to volume control in BlueZ 5 Vinicius Costa Gomes (1): bluetooth: Add HFP 1.6 codec ID src/modules/bluetooth/bluetooth-util.c | 568 ++-- src/modules/bluetooth/module-bluetooth-device.c | 8 +- 2 files changed, 521 insertions(+), 55 deletions(-) -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v4 01/16] bluetooth: Detect BlueZ 5
From: Mikel Astiz mikel.as...@bmw-carit.de Check the existence of ObjectManager to detect the version of the running daemon. If the interface exists, it should be BlueZ 5. --- src/modules/bluetooth/bluetooth-util.c | 52 -- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index c15ecd1..1883c8a 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -61,12 +61,19 @@ /interface \ /node +typedef enum pa_bluez_version { +BLUEZ_VERSION_UNKNOWN, +BLUEZ_VERSION_4, +BLUEZ_VERSION_5, +} pa_bluez_version_t; + struct pa_bluetooth_discovery { PA_REFCNT_DECLARE; pa_core *core; pa_dbus_connection *connection; PA_LLIST_HEAD(pa_dbus_pending, pending); +pa_bluez_version_t version; bool adapters_listed; pa_hashmap *devices; pa_hashmap *transports; @@ -880,6 +887,46 @@ static void list_adapters(pa_bluetooth_discovery *y) { send_and_add_to_pending(y, m, get_properties_reply, NULL); } +static void get_managed_objects_reply(DBusPendingCall *pending, void *userdata) { +DBusMessage *r; +pa_dbus_pending *p; +pa_bluetooth_discovery *y; + +pa_assert_se(p = userdata); +pa_assert_se(y = p-context_data); +pa_assert_se(r = dbus_pending_call_steal_reply(pending)); + +if (dbus_message_is_error(r, DBUS_ERROR_UNKNOWN_METHOD)) { +pa_log_info(D-Bus ObjectManager not detected so falling back to BlueZ version 4 API.); +y-version = BLUEZ_VERSION_4; +list_adapters(y); +goto finish; +} + +if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { +pa_log(GetManagedObjects() failed: %s: %s, dbus_message_get_error_name(r), pa_dbus_get_error_message(r)); +goto finish; +} + +pa_log_info(D-Bus ObjectManager detected so assuming BlueZ version 5.); +y-version = BLUEZ_VERSION_5; + +finish: +dbus_message_unref(r); + +PA_LLIST_REMOVE(pa_dbus_pending, y-pending, p); +pa_dbus_pending_free(p); +} + +static void init_bluez(pa_bluetooth_discovery *y) { +DBusMessage *m; +pa_assert(y); + +pa_assert_se(m = dbus_message_new_method_call(org.bluez, /, org.freedesktop.DBus.ObjectManager, + GetManagedObjects)); +send_and_add_to_pending(y, m, get_managed_objects_reply, NULL); +} + static int transport_parse_property(pa_bluetooth_transport *t, DBusMessageIter *i) { const char *key; DBusMessageIter variant_i; @@ -1023,11 +1070,12 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us pa_log_debug(Bluetooth daemon disappeared.); remove_all_devices(y); y-adapters_listed = false; +y-version = BLUEZ_VERSION_UNKNOWN; } if (new_owner *new_owner) { pa_log_debug(Bluetooth daemon appeared.); -list_adapters(y); +init_bluez(y); } } @@ -1710,7 +1758,7 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { pa_assert_se(dbus_connection_register_object_path(conn, A2DP_SOURCE_ENDPOINT, vtable_endpoint, y)); pa_assert_se(dbus_connection_register_object_path(conn, A2DP_SINK_ENDPOINT, vtable_endpoint, y)); -list_adapters(y); +init_bluez(y); return y; -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v4 02/16] bluetooth: Parse the tree returned by ObjectManager
From: Mikel Astiz mikel.as...@bmw-carit.de Parse the result of ObjectManager.GetManagedObjects(), which includes all objects registered, their interfaces and the corresponding properties per interface. --- src/modules/bluetooth/bluetooth-util.c | 125 +++-- 1 file changed, 119 insertions(+), 6 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 1883c8a..cee283e 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -362,8 +362,6 @@ static int parse_device_property(pa_bluetooth_device *d, DBusMessageIter *i, boo dbus_message_iter_recurse(i, variant_i); -/* pa_log_debug(Parsing property org.bluez.Device.%s, key); */ - switch (dbus_message_iter_get_arg_type(variant_i)) { case DBUS_TYPE_STRING: { @@ -452,6 +450,11 @@ static int parse_device_property(pa_bluetooth_device *d, DBusMessageIter *i, boo uuiddata.uuid = value; pa_hook_fire(d-discovery-hooks[PA_BLUETOOTH_HOOK_DEVICE_UUID_ADDED], uuiddata); +if (d-discovery-version = BLUEZ_VERSION_5) { +dbus_message_iter_next(ai); +continue; +} + /* Vudentz said the interfaces are here when the UUIDs are announced */ if (strcasecmp(HSP_AG_UUID, value) == 0 || strcasecmp(HFP_AG_UUID, value) == 0) { pa_assert_se(m = dbus_message_new_method_call(org.bluez, d-path, org.bluez.HandsfreeGateway, @@ -867,16 +870,25 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const send_and_add_to_pending(y, m, register_endpoint_reply, pa_xstrdup(endpoint)); } +static void register_adapter_endpoints(pa_bluetooth_discovery *y, const char *path) { +register_endpoint(y, path, A2DP_SOURCE_ENDPOINT, A2DP_SOURCE_UUID); +register_endpoint(y, path, A2DP_SINK_ENDPOINT, A2DP_SINK_UUID); + +/* For BlueZ 5, only A2DP is registered in the Media API */ +if (y-version = BLUEZ_VERSION_5) +return; + +register_endpoint(y, path, HFP_AG_ENDPOINT, HFP_AG_UUID); +register_endpoint(y, path, HFP_HS_ENDPOINT, HFP_HS_UUID); +} + static void found_adapter(pa_bluetooth_discovery *y, const char *path) { DBusMessage *m; pa_assert_se(m = dbus_message_new_method_call(org.bluez, path, org.bluez.Adapter, GetProperties)); send_and_add_to_pending(y, m, get_properties_reply, NULL); -register_endpoint(y, path, HFP_AG_ENDPOINT, HFP_AG_UUID); -register_endpoint(y, path, HFP_HS_ENDPOINT, HFP_HS_UUID); -register_endpoint(y, path, A2DP_SOURCE_ENDPOINT, A2DP_SOURCE_UUID); -register_endpoint(y, path, A2DP_SINK_ENDPOINT, A2DP_SINK_UUID); +register_adapter_endpoints(y, path); } static void list_adapters(pa_bluetooth_discovery *y) { @@ -887,10 +899,94 @@ static void list_adapters(pa_bluetooth_discovery *y) { send_and_add_to_pending(y, m, get_properties_reply, NULL); } +static int parse_device_properties(pa_bluetooth_device *d, DBusMessageIter *i, bool is_property_change) { +DBusMessageIter element_i; +int ret = 0; + +dbus_message_iter_recurse(i, element_i); + +while (dbus_message_iter_get_arg_type(element_i) == DBUS_TYPE_DICT_ENTRY) { +DBusMessageIter dict_i; + +dbus_message_iter_recurse(element_i, dict_i); + +if (parse_device_property(d, dict_i, is_property_change)) +ret = -1; + +dbus_message_iter_next(element_i); +} + +if (!d-address || !d-alias || d-paired 0 || d-trusted 0) { +pa_log_error(Non-optional information missing for device %s, d-path); +d-device_info_valid = -1; +return -1; +} + +d-device_info_valid = 1; +return ret; +} + +static int parse_interfaces_and_properties(pa_bluetooth_discovery *y, DBusMessageIter *dict_i) { +DBusMessageIter element_i; +const char *path; + +pa_assert(dbus_message_iter_get_arg_type(dict_i) == DBUS_TYPE_OBJECT_PATH); +dbus_message_iter_get_basic(dict_i, path); + +pa_assert_se(dbus_message_iter_next(dict_i)); +pa_assert(dbus_message_iter_get_arg_type(dict_i) == DBUS_TYPE_ARRAY); + +dbus_message_iter_recurse(dict_i, element_i); + +while (dbus_message_iter_get_arg_type(element_i) == DBUS_TYPE_DICT_ENTRY) { +DBusMessageIter iface_i; +const char *interface; + +dbus_message_iter_recurse(element_i, iface_i); + +pa_assert(dbus_message_iter_get_arg_type(iface_i) == DBUS_TYPE_STRING); +dbus_message_iter_get_basic(iface_i, interface); + +pa_assert_se(dbus_message_iter_next(iface_i)); +pa_assert(dbus_message_iter_get_arg_type(iface_i) == DBUS_TYPE_ARRAY); + +if (pa_streq(interface, org.bluez.Adapter1)) { +pa_log_debug(Adapter %s found, path); +register_adapter_endpoints(y, path); +} else
[pulseaudio-discuss] [RFC next v4 03/16] bluetooth: Support ObjectManager interface add/remove
From: Mikel Astiz mikel.as...@bmw-carit.de Install matches for signals ObjectManager.InterfacesAdded and ObjectManager.InterfacesRemoved, and process the devices that are registered and unregistered dynamically. --- src/modules/bluetooth/bluetooth-util.c | 58 ++ 1 file changed, 58 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index cee283e..c60f3ff 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1209,6 +1209,60 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us goto fail; return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} else if (dbus_message_is_signal(m, org.freedesktop.DBus.ObjectManager, InterfacesAdded)) { +DBusMessageIter arg_i; + +if (y-version != BLUEZ_VERSION_5) +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */ + +if (!dbus_message_iter_init(m, arg_i) || !pa_streq(dbus_message_get_signature(m), oa{sa{sv}})) { +pa_log(Invalid signature found in InterfacesAdded); +goto fail; +} + +if (parse_interfaces_and_properties(y, arg_i) 0) +goto fail; + +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} else if (dbus_message_is_signal(m, org.freedesktop.DBus.ObjectManager, InterfacesRemoved)) { +const char *path; +DBusMessageIter arg_i; +DBusMessageIter element_i; + +if (y-version != BLUEZ_VERSION_5) +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */ + +if (!dbus_message_iter_init(m, arg_i) || !pa_streq(dbus_message_get_signature(m), oas)) { +pa_log(Invalid signature found in InterfacesRemoved); +goto fail; +} + +dbus_message_iter_get_basic(arg_i, path); + +pa_assert_se(dbus_message_iter_next(arg_i)); +pa_assert(dbus_message_iter_get_arg_type(arg_i) == DBUS_TYPE_ARRAY); + +dbus_message_iter_recurse(arg_i, element_i); + +while (dbus_message_iter_get_arg_type(element_i) == DBUS_TYPE_STRING) { +const char *interface; + +dbus_message_iter_get_basic(element_i, interface); + +if (pa_streq(interface, org.bluez.Device1)) { +pa_bluetooth_device *d; + +if ((d = pa_hashmap_remove(y-devices, path))) { +pa_log_debug(Device %s removed, d-path); +run_callback(d, true); +device_free(d); +} +} + +dbus_message_iter_next(element_i); +} + +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } fail: @@ -1861,6 +1915,8 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', NULL) 0) { pa_log(Failed to add D-Bus matches: %s, err.message); goto fail; @@ -1934,6 +1990,8 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) { type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', NULL); if (y-filter_added) -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v4 04/16] bluetooth: Support Properties.PropertiesChanged signal
From: Mikel Astiz mikel.as...@bmw-carit.de Install matches for signal Properties.PropertiesChanged and process the properties corresponding to the tracked devices. --- src/modules/bluetooth/bluetooth-util.c | 29 + 1 file changed, 29 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index c60f3ff..cd72ffd 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1263,6 +1263,33 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} else if (dbus_message_is_signal(m, org.freedesktop.DBus.Properties, PropertiesChanged)) { +DBusMessageIter arg_i; +const char *interface; + +if (y-version != BLUEZ_VERSION_5) +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */ + +if (!dbus_message_iter_init(m, arg_i) || !pa_streq(dbus_message_get_signature(m), sa{sv}as)) { +pa_log(Invalid signature found in PropertiesChanged); +goto fail; +} + +dbus_message_iter_get_basic(arg_i, interface); + +pa_assert_se(dbus_message_iter_next(arg_i)); +pa_assert(dbus_message_iter_get_arg_type(arg_i) == DBUS_TYPE_ARRAY); + +if (pa_streq(interface, org.bluez.Device1)) { +pa_bluetooth_device *d; + +if (!(d = pa_hashmap_get(y-devices, dbus_message_get_path(m +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* Device not being tracked */ + +parse_device_properties(d, arg_i, true); +} + +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } fail: @@ -1917,6 +1944,8 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' +,arg0='org.bluez.Device1', NULL) 0) { pa_log(Failed to add D-Bus matches: %s, err.message); goto fail; -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v4 05/16] bluetooth: BlueZ 5 interface rename to org.bluez.MediaEndpoint1
From: Mikel Astiz mikel.as...@bmw-carit.de Use the new interface name if BlueZ 5 has been detected. --- src/modules/bluetooth/bluetooth-util.c | 51 -- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index cd72ffd..5fe3f0c 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -61,6 +61,30 @@ /interface \ /node +#define MEDIA_ENDPOINT_1_INTROSPECT_XML \ +DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ +node\ + interface name=\org.bluez.MediaEndpoint1\\ + method name=\SetConfiguration\ \ + arg name=\transport\ direction=\in\ type=\o\/ \ + arg name=\configuration\ direction=\in\ type=\ay\/ \ + /method \ + method name=\SelectConfiguration\ \ + arg name=\capabilities\ direction=\in\ type=\ay\/ \ + arg name=\configuration\ direction=\out\ type=\ay\/\ + /method \ + method name=\ClearConfiguration\\ + /method \ + method name=\Release\ \ + /method \ + /interface \ + interface name=\org.freedesktop.DBus.Introspectable\ \ + method name=\Introspect\\ + arg name=\data\ type=\s\ direction=\out\/ \ + /method \ + /interface \ +/node + typedef enum pa_bluez_version { BLUEZ_VERSION_UNKNOWN, BLUEZ_VERSION_4, @@ -1534,7 +1558,7 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage dbus_message_iter_get_basic(args, path); if (pa_hashmap_get(y-transports, path)) { -pa_log(org.bluez.MediaEndpoint.SetConfiguration: Transport %s is already configured., path); +pa_log(Endpoint SetConfiguration: Transport %s is already configured., path); goto fail2; } @@ -1628,11 +1652,10 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage return NULL; fail: -pa_log(org.bluez.MediaEndpoint.SetConfiguration: invalid arguments); +pa_log(Endpoint SetConfiguration: invalid arguments); fail2: -pa_assert_se(r = dbus_message_new_error(m, org.bluez.MediaEndpoint.Error.InvalidArguments, -Unable to set configuration)); +pa_assert_se(r = dbus_message_new_error(m, org.bluez.Error.InvalidArguments, Unable to set configuration)); return r; } @@ -1646,7 +1669,7 @@ static DBusMessage *endpoint_clear_configuration(DBusConnection *c, DBusMessage dbus_error_init(e); if (!dbus_message_get_args(m, e, DBUS_TYPE_OBJECT_PATH, path, DBUS_TYPE_INVALID)) { -pa_log(org.bluez.MediaEndpoint.ClearConfiguration: %s, e.message); +pa_log(Endpoint ClearConfiguration: %s, e.message); dbus_error_free(e); goto fail; } @@ -1671,8 +1694,7 @@ static DBusMessage *endpoint_clear_configuration(DBusConnection *c, DBusMessage return r; fail: -pa_assert_se(r = dbus_message_new_error(m, org.bluez.MediaEndpoint.Error.InvalidArguments, -Unable to clear configuration)); +pa_assert_se(r = dbus_message_new_error(m, org.bluez.Error.InvalidArguments, Unable to clear configuration)); return r; } @@ -1742,7 +1764,7 @@ static DBusMessage *endpoint_select_configuration(DBusConnection *c, DBusMessage dbus_error_init(e); if (!dbus_message_get_args(m, e, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, cap, size, DBUS_TYPE_INVALID)) { -pa_log(org.bluez.MediaEndpoint.SelectConfiguration: %s, e.message); +pa_log(Endpoint SelectConfiguration: %s, e.message); dbus_error_free(e); goto fail; } @@ -1839,8 +1861,7 @@ done: return r; fail: -pa_assert_se(r = dbus_message_new_error(m, org.bluez.MediaEndpoint.Error.InvalidArguments, -Unable to select configuration)); +pa_assert_se(r = dbus_message_new_error(m, org.bluez.Error.InvalidArguments, Unable to select configuration)); return r; } @@ -1864,17 +1885,19 @@ static DBusHandlerResult endpoint_handler(DBusConnection *c, DBusMessage *m, voi !pa_streq(path, HFP_HS_ENDPOINT)) return
[pulseaudio-discuss] [RFC next v4 06/16] bluetooth: BlueZ 5 interface rename to org.bluez.Media1
From: Mikel Astiz mikel.as...@bmw-carit.de Use the new interface name if BlueZ 5 has been detected. --- src/modules/bluetooth/bluetooth-util.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 5fe3f0c..0a5f70e 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -834,8 +834,7 @@ static void register_endpoint_reply(DBusPendingCall *pending, void *userdata) { } if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { -pa_log(org.bluez.Media.RegisterEndpoint() failed: %s: %s, dbus_message_get_error_name(r), - pa_dbus_get_error_message(r)); +pa_log(RegisterEndpoint() failed: %s: %s, dbus_message_get_error_name(r), pa_dbus_get_error_message(r)); goto finish; } @@ -852,10 +851,11 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const DBusMessage *m; DBusMessageIter i, d; uint8_t codec = 0; +const char *interface = y-version == BLUEZ_VERSION_4 ? org.bluez.Media : org.bluez.Media1; pa_log_debug(Registering %s on adapter %s., endpoint, path); -pa_assert_se(m = dbus_message_new_method_call(org.bluez, path, org.bluez.Media, RegisterEndpoint)); +pa_assert_se(m = dbus_message_new_method_call(org.bluez, path, interface, RegisterEndpoint)); dbus_message_iter_init_append(m, i); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v4 07/16] bluetooth: BlueZ 5 interface rename to org.bluez.MediaTransport1
From: Mikel Astiz mikel.as...@bmw-carit.de Use the new interface name if BlueZ 5 has been detected. --- src/modules/bluetooth/bluetooth-util.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 0a5f70e..14bd3ea 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1387,6 +1387,7 @@ bool pa_bluetooth_device_any_audio_connected(const pa_bluetooth_device *d) { int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) { const char *accesstype = rw; +const char *interface; DBusMessage *m, *r; DBusError err; int ret; @@ -1396,6 +1397,8 @@ int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, siz pa_assert(t-device); pa_assert(t-device-discovery); +interface = t-device-discovery-version == BLUEZ_VERSION_4 ? org.bluez.MediaTransport : org.bluez.MediaTransport1; + if (optional) { /* FIXME: we are trying to acquire the transport only if the stream is playing, without actually initiating the stream request from our side @@ -1412,7 +1415,7 @@ int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, siz dbus_error_init(err); -pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport, Acquire)); +pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, interface, Acquire)); pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, accesstype, DBUS_TYPE_INVALID)); r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t-device-discovery-connection), m, -1, err); @@ -1423,7 +1426,7 @@ int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, siz if (!dbus_message_get_args(r, err, DBUS_TYPE_UNIX_FD, ret, DBUS_TYPE_UINT16, i, DBUS_TYPE_UINT16, o, DBUS_TYPE_INVALID)) { -pa_log(Failed to parse org.bluez.MediaTransport.Acquire(): %s, err.message); +pa_log(Failed to parse the media transport Acquire() reply: %s, err.message); ret = -1; dbus_error_free(err); goto fail; @@ -1442,6 +1445,7 @@ fail: void pa_bluetooth_transport_release(pa_bluetooth_transport *t) { const char *accesstype = rw; +const char *interface; DBusMessage *m; DBusError err; @@ -1449,9 +1453,11 @@ void pa_bluetooth_transport_release(pa_bluetooth_transport *t) { pa_assert(t-device); pa_assert(t-device-discovery); +interface = t-device-discovery-version == BLUEZ_VERSION_4 ? org.bluez.MediaTransport : org.bluez.MediaTransport1; + dbus_error_init(err); -pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport, Release)); +pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, interface, Release)); pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, accesstype, DBUS_TYPE_INVALID)); dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t-device-discovery-connection), m, -1, err); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v4 08/16] bluetooth: Parse media transport's properties
From: Mikel Astiz mikel.as...@bmw-carit.de Add the code to parse the properties of the media transport object when a PropertiesChanged signal is received. Note that the transport might have an owner other than BlueZ, and thus the property changes would be emitted from arbitrary senders. For performance reasons, the installed match considers the interface name where the property has changed. It could be possible to install and remove the D-Bus matches dynamically when a new owner is registered/unregistered, but filtering based on the interface name seems good enough already. --- src/modules/bluetooth/bluetooth-util.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 14bd3ea..871341d 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1094,6 +1094,24 @@ static int transport_parse_property(pa_bluetooth_transport *t, DBusMessageIter * return 0; } +static int parse_transport_properties(pa_bluetooth_transport *t, DBusMessageIter *i) { +DBusMessageIter element_i; + +dbus_message_iter_recurse(i, element_i); + +while (dbus_message_iter_get_arg_type(element_i) == DBUS_TYPE_DICT_ENTRY) { +DBusMessageIter dict_i; + +dbus_message_iter_recurse(element_i, dict_i); + +transport_parse_property(t, dict_i); + +dbus_message_iter_next(element_i); +} + +return 0; +} + static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *userdata) { DBusError err; pa_bluetooth_discovery *y; @@ -1311,6 +1329,13 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* Device not being tracked */ parse_device_properties(d, arg_i, true); +} else if (pa_streq(interface, org.bluez.MediaTransport1)) { +pa_bluetooth_transport *t; + +if (!(t = pa_hashmap_get(y-transports, dbus_message_get_path(m +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + +parse_transport_properties(t, arg_i); } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -1975,6 +2000,8 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' ,arg0='org.bluez.Device1', + type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' +,arg0='org.bluez.MediaTransport1', NULL) 0) { pa_log(Failed to add D-Bus matches: %s, err.message); goto fail; -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v4 10/16] bluetooth: Update to new BlueZ 5 transport acquire/release API
From: Mikel Astiz mikel.as...@bmw-carit.de The new D-Bus API doesn't support access rights, which weren't used by PulseAudio anyway, but it does solve a race condition: now optional acquires can be implemented by bluetooth-util atomically using the D-Bus TryAcquire() method. --- src/modules/bluetooth/bluetooth-util.c | 66 +++-- src/modules/bluetooth/module-bluetooth-device.c | 8 +-- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 396325d..8554d5d 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1448,40 +1448,52 @@ bool pa_bluetooth_device_any_audio_connected(const pa_bluetooth_device *d) { } int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) { -const char *accesstype = rw; -const char *interface; DBusMessage *m, *r; DBusError err; int ret; uint16_t i, o; +const char *method; pa_assert(t); pa_assert(t-device); pa_assert(t-device-discovery); -interface = t-device-discovery-version == BLUEZ_VERSION_4 ? org.bluez.MediaTransport : org.bluez.MediaTransport1; - -if (optional) { -/* FIXME: we are trying to acquire the transport only if the stream is - playing, without actually initiating the stream request from our side - (which is typically undesireable specially for hfgw use-cases. - However this approach is racy, since the stream could have been - suspended in the meantime, so we can't really guarantee that the - stream will not be requested until BlueZ's API supports this - atomically. */ -if (t-state PA_BLUETOOTH_TRANSPORT_STATE_PLAYING) { -pa_log_info(Failed optional acquire of transport %s, t-path); -return -1; +dbus_error_init(err); + +if (t-device-discovery-version == BLUEZ_VERSION_4) { +const char *accesstype = rw; + +if (optional) { +/* We are trying to acquire the transport only if the stream is + playing, without actually initiating the stream request from our side + (which is typically undesireable specially for hfgw use-cases. + However this approach is racy, since the stream could have been + suspended in the meantime, so we can't really guarantee that the + stream will not be requested with the API in BlueZ 4.x */ +if (t-state PA_BLUETOOTH_TRANSPORT_STATE_PLAYING) { +pa_log_info(Failed optional acquire of unavailable transport %s, t-path); +return -1; +} } -} -dbus_error_init(err); +method = Acquire; +pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport, method)); +pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, accesstype, DBUS_TYPE_INVALID)); +} else { +pa_assert(t-device-discovery-version == BLUEZ_VERSION_5); + +method = optional ? TryAcquire : Acquire; +pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport1, method)); +} -pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, interface, Acquire)); -pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, accesstype, DBUS_TYPE_INVALID)); r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t-device-discovery-connection), m, -1, err); if (!r) { +if (optional pa_streq(err.name, org.bluez.Error.NotAvailable)) +pa_log_info(Failed optional acquire of unavailable transport %s, t-path); +else +pa_log(Transport %s() failed for transport %s (%s), method, t-path, err.message); + dbus_error_free(err); return -1; } @@ -1506,8 +1518,6 @@ fail: } void pa_bluetooth_transport_release(pa_bluetooth_transport *t) { -const char *accesstype = rw; -const char *interface; DBusMessage *m; DBusError err; @@ -1515,12 +1525,18 @@ void pa_bluetooth_transport_release(pa_bluetooth_transport *t) { pa_assert(t-device); pa_assert(t-device-discovery); -interface = t-device-discovery-version == BLUEZ_VERSION_4 ? org.bluez.MediaTransport : org.bluez.MediaTransport1; - dbus_error_init(err); -pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, interface, Release)); -pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, accesstype, DBUS_TYPE_INVALID)); +if (t-device-discovery-version == BLUEZ_VERSION_4) { +const char *accesstype = rw; + +pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport, Release)); +pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, accesstype, DBUS_TYPE_INVALID)); +} else
[pulseaudio-discuss] [RFC next v4 11/16] bluetooth: Support transport auto-release
From: Mikel Astiz mikel.as...@bmw-carit.de With BlueZ 5, if the remote device suspends the audio, the transport state will change to idle and the endpoint is not required to release the transport, since this could introduce race conditions. Therefore, ignore the call to pa_bluetooth_transport_release() if the transport is not acquired any more. --- src/modules/bluetooth/bluetooth-util.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 8554d5d..e3de01e 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1532,6 +1532,9 @@ void pa_bluetooth_transport_release(pa_bluetooth_transport *t) { pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport, Release)); pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, accesstype, DBUS_TYPE_INVALID)); +} else if (t-state = PA_BLUETOOTH_TRANSPORT_STATE_IDLE) { +pa_log_info(Transport %s auto-released by BlueZ or already released, t-path); +return; } else { pa_assert(t-device-discovery-version == BLUEZ_VERSION_5); pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport1, Release)); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v4 12/16] bluetooth: Register HSP/HFP endpoints in BlueZ 5 Media API
From: Mikel Astiz mikel.as...@bmw-carit.de Register the HSP/HFP endpoints in BlueZ 5 Media API for the sake of completeness, despite the fact that there's currently no known user of such an endpoint. --- src/modules/bluetooth/bluetooth-util.c | 5 - 1 file changed, 5 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index e3de01e..e46cbda 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -911,11 +911,6 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const static void register_adapter_endpoints(pa_bluetooth_discovery *y, const char *path) { register_endpoint(y, path, A2DP_SOURCE_ENDPOINT, A2DP_SOURCE_UUID); register_endpoint(y, path, A2DP_SINK_ENDPOINT, A2DP_SINK_UUID); - -/* For BlueZ 5, only A2DP is registered in the Media API */ -if (y-version = BLUEZ_VERSION_5) -return; - register_endpoint(y, path, HFP_AG_ENDPOINT, HFP_AG_UUID); register_endpoint(y, path, HFP_HS_ENDPOINT, HFP_HS_UUID); } -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v4 14/16] bluetooth: Handle transports configured before UUID received
From: Mikel Astiz mikel.as...@bmw-carit.de Now that the transport can be configured from some other process (i.e. oFono), there is no guarantee that the UUID from BlueZ will already have been received. This requires PulseAudio to assume that the UUID is actually supported by the device and that BlueZ will eventually propagate it. --- src/modules/bluetooth/bluetooth-util.c | 53 ++ 1 file changed, 53 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 09d9948..0bb6bf0 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -178,6 +178,33 @@ static int profile_from_interface(const char *interface, enum profile *p) { return -1; } +static void profile_to_remote_uuid(enum profile p, const char *res[2]) { +pa_assert(p != PROFILE_OFF); + +switch(p) { +case PROFILE_A2DP: +res[0] = A2DP_SINK_UUID; +res[1] = NULL; +return; +case PROFILE_A2DP_SOURCE: +res[0] = A2DP_SOURCE_UUID; +res[1] = NULL; +return; +case PROFILE_HSP: +res[0] = HSP_HS_UUID; +res[1] = HFP_HS_UUID; +return; +case PROFILE_HFGW: +res[0] = HSP_AG_UUID; +res[1] = HFP_AG_UUID; +return; +case PROFILE_OFF: +break; +} + +pa_assert_not_reached(); +} + static pa_bluetooth_transport_state_t audio_state_to_transport_state(pa_bt_audio_state_t state) { switch (state) { case PA_BT_AUDIO_STATE_INVALID: /* Typically if state hasn't been received yet */ @@ -1640,6 +1667,7 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage DBusMessageIter args, props; DBusMessage *r; bool old_any_connected; +const char *remote_uuid[2]; if (!dbus_message_iter_init(m, args) || !pa_streq(dbus_message_get_signature(m), oa{sv})) { pa_log(Invalid signature for method SetConfiguration); @@ -1702,6 +1730,10 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage dbus_message_iter_next(props); } +/* FIXME: with BlueZ 5, check if this is racy in case a newly paired + * device gets connected very fast, before BlueZ has created it. This is + * very unlikely since the device will be created before the pairing + * procedure is complete */ d = found_device(y, dev_path); if (!d) goto fail; @@ -1715,6 +1747,27 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage else p = PROFILE_A2DP_SOURCE; +/* Check if the UUID was already reported by BlueZ, since the telephony + * component (oFono) could be faster than BlueZ */ +profile_to_remote_uuid(p, remote_uuid); + +if (!pa_bluetooth_uuid_has(d-uuids, remote_uuid[0]) !pa_bluetooth_uuid_has(d-uuids, remote_uuid[1])) { +pa_bluetooth_uuid *node; +struct pa_bluetooth_hook_uuid_data uuiddata; + +pa_log_info(Endpoint with UUID '%s' configured before remote UUID was reported by BlueZ., uuid); + +/* This might generate duplicated UUID_ADDED hooks since the endpoint + * doesn't receive the exact remote UUID (HSP cannot be distinguished + * from HFP). However, these duplicated hooks should do no harm */ +node = uuid_new(remote_uuid[0]); +PA_LLIST_PREPEND(pa_bluetooth_uuid, d-uuids, node); + +uuiddata.device = d; +uuiddata.uuid = uuid; + pa_hook_fire(d-discovery-hooks[PA_BLUETOOTH_HOOK_DEVICE_UUID_ADDED], uuiddata); +} + if (d-transports[p] != NULL) { pa_log(Cannot configure transport %s because profile %d is already used, path, p); goto fail2; -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v4 13/16] bluetooth: Add HFP 1.6 codec ID
From: Vinicius Costa Gomes vinicius.go...@openbossa.org According to the HFP 1.6 spec, the default codec (CVSD) has ID 0x01. This change has no effect in older versions of BlueZ since the codec ID was ignored for HFP, due to the fact that HFP versions prior to 1.6 do not have such a field. --- src/modules/bluetooth/bluetooth-util.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index e46cbda..09d9948 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -864,7 +864,7 @@ finish: static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const char *endpoint, const char *uuid) { DBusMessage *m; DBusMessageIter i, d; -uint8_t codec = 0; +uint8_t codec; const char *interface = y-version == BLUEZ_VERSION_4 ? org.bluez.Media : org.bluez.Media1; pa_log_debug(Registering %s on adapter %s., endpoint, path); @@ -881,14 +881,18 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const pa_dbus_append_basic_variant_dict_entry(d, UUID, DBUS_TYPE_STRING, uuid); -pa_dbus_append_basic_variant_dict_entry(d, Codec, DBUS_TYPE_BYTE, codec); if (pa_streq(uuid, HFP_AG_UUID) || pa_streq(uuid, HFP_HS_UUID)) { uint8_t capability = 0; + +codec = 1; + pa_dbus_append_basic_array_variant_dict_entry(d, Capabilities, DBUS_TYPE_BYTE, capability, 1); } else { a2dp_sbc_t capabilities; +codec = 0; + capabilities.channel_mode = SBC_CHANNEL_MODE_MONO | SBC_CHANNEL_MODE_DUAL_CHANNEL | SBC_CHANNEL_MODE_STEREO | SBC_CHANNEL_MODE_JOINT_STEREO; capabilities.frequency = SBC_SAMPLING_FREQ_16000 | SBC_SAMPLING_FREQ_32000 | @@ -903,6 +907,8 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const pa_dbus_append_basic_array_variant_dict_entry(d, Capabilities, DBUS_TYPE_BYTE, capabilities, sizeof(capabilities)); } +pa_dbus_append_basic_variant_dict_entry(d, Codec, DBUS_TYPE_BYTE, codec); + dbus_message_iter_close_container(i, d); send_and_add_to_pending(y, m, register_endpoint_reply, pa_xstrdup(endpoint)); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v4 15/16] bluetooth: Update to new property setter API in BlueZ 5
From: Mikel Astiz mikel.as...@bmw-carit.de If BlueZ 5 is in use, the standard org.freedesktop.DBus.Properties needs to be used instead of the old SetProperty() method. --- src/modules/bluetooth/bluetooth-util.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 0bb6bf0..a6559cb 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1587,6 +1587,20 @@ static void set_property(pa_bluetooth_discovery *y, const char *bus, const char pa_assert(interface); pa_assert(prop_name); +if (y-version = BLUEZ_VERSION_5) { +pa_assert_se(m = dbus_message_new_method_call(bus, path, org.freedesktop.DBus.Properties, Set)); +dbus_message_iter_init_append(m, i); +dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, interface); +dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, prop_name); +pa_dbus_append_basic_variant(i, prop_type, prop_value); + +dbus_message_set_no_reply(m, true); + pa_assert_se(dbus_connection_send(pa_dbus_connection_get(y-connection), m, NULL)); +dbus_message_unref(m); + +return; +} + pa_assert_se(m = dbus_message_new_method_call(bus, path, interface, SetProperty)); dbus_message_iter_init_append(m, i); dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, prop_name); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC next v4 16/16] bluetooth: Update to volume control in BlueZ 5
From: Mikel Astiz mikel.as...@bmw-carit.de In BlueZ 5, the microphone and speaker gains are exposed as properties of the MediaTransport1 interface. --- src/modules/bluetooth/bluetooth-util.c | 41 ++ 1 file changed, 41 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index a6559cb..049c479 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1154,6 +1154,32 @@ static int transport_parse_property(pa_bluetooth_transport *t, DBusMessageIter * break; } + +case DBUS_TYPE_BYTE: { +uint8_t value; + +dbus_message_iter_get_basic(variant_i, value); + +if (pa_streq(key, MicrophoneGain)) { +uint8_t gain; + +if ((gain = PA_MIN(value, HSP_MAX_GAIN)) == t-microphone_gain) +break; + +t-microphone_gain = gain; + pa_hook_fire(t-device-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED], t); +} else if (pa_streq(key, SpeakerGain)) { +uint8_t gain; + +if ((gain = PA_MIN(value, HSP_MAX_GAIN)) == t-speaker_gain) +break; + +t-speaker_gain = gain; + pa_hook_fire(t-device-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED], t); +} + +break; +} } return 0; @@ -1617,6 +1643,14 @@ void pa_bluetooth_transport_set_microphone_gain(pa_bluetooth_transport *t, uint1 pa_assert(t); pa_assert(t-profile == PROFILE_HSP); +if (t-device-discovery-version = BLUEZ_VERSION_5) { +uint8_t g = (uint8_t) gain; + +set_property(t-device-discovery, t-owner, t-path, org.bluez.MediaTransport1, + MicrophoneGain, DBUS_TYPE_BYTE, g); +return; +} + set_property(t-device-discovery, org.bluez, t-device-path, org.bluez.Headset, MicrophoneGain, DBUS_TYPE_UINT16, gain); } @@ -1627,6 +1661,13 @@ void pa_bluetooth_transport_set_speaker_gain(pa_bluetooth_transport *t, uint16_t pa_assert(t); pa_assert(t-profile == PROFILE_HSP); +if (t-device-discovery-version = BLUEZ_VERSION_5) { +uint8_t g = (uint8_t) gain; + +set_property(t-device-discovery, t-owner, t-path, org.bluez.MediaTransport1, SpeakerGain, DBUS_TYPE_BYTE, g); +return; +} + set_property(t-device-discovery, org.bluez, t-device-path, org.bluez.Headset, SpeakerGain, DBUS_TYPE_UINT16, gain); } -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [PATCH 3/3] bluetooth: Remove the 'bluez.name' property
Hi João Paulo, On Fri, Apr 26, 2013 at 5:30 PM, jprv...@gmail.com wrote: From: João Paulo Rechi Vita jprv...@openbossa.org The org.bluez.Device1.Name property is optional and may not be present (that happens with the PTS 4.7.0), so it's better not to expose it to clients so they don't rely on its existence. --- src/modules/bluetooth/module-bluetooth-device.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 11c6e5f..542f0af 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2242,7 +2242,6 @@ static int add_card(struct userdata *u) { pa_proplist_sets(data.proplist, bluez.path, device-path); pa_proplist_setf(data.proplist, bluez.class, 0x%06x, (unsigned) device-class); -pa_proplist_sets(data.proplist, bluez.name, device-name); pa_proplist_sets(data.proplist, bluez.alias, device-alias); data.name = get_name(card, u-modargs, device-address, b); data.namereg_fail = b; -- Ack from my side to the three patches, also for the master branch. As a minor improvement, the commit messages in patches 2 and 3 could avoid referring to the org.bluez.Device1 interface, which is BlueZ 5-specific. In particular, the commit message in this patch should mention that this is future-proof, even though BlueZ 5 is not supported yet (given that the property is actually *not* optional in BlueZ 4). Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [PATCH] bluetooth: Use 'Alias' instead of 'Name'
Hi João, On Wed, Apr 24, 2013 at 7:51 PM, João Paulo Rechi Vita jprv...@openbossa.org wrote: On Wed, Apr 24, 2013 at 3:29 AM, Mikel Astiz mikel.astiz@gmail.com wrote: Hi João Paulo, On Tue, Apr 23, 2013 at 10:48 PM, jprv...@gmail.com wrote: From: João Paulo Rechi Vita jprv...@openbossa.org According to the BlueZ API documentation the 'Alias' property should be preffered over the 'Name' property. Also, if the device doesn't have a remote name the 'Name' property may not be set, but the 'Alias' property will always be. Can you point to the documentation you refer to? 'Alias' is a user-modifiable property, while 'Name' is what the remote device reports. They just have different purposes, so I don't think one of them is preferred over the other as a general rule. doc/device-api.txt in BlueZ repository explicitly states that 'Alias' should be preferred over 'Name'. If you go back in history you'll see that it was first mentioned before BlueZ 4.0. I'm still not convinced. These are two different properties, both exposed by BlueZ for some reason, and it can be misleading that we start using a different terminology inside PA, and map alias-name. I'm fine encouraging the use of 'bluez.alias' over 'bluez.name', but renaming it internally should be avoided IMO. --- src/modules/bluetooth/bluetooth-util.c | 7 +-- src/modules/bluetooth/bluetooth-util.h | 1 - src/modules/bluetooth/module-bluetooth-device.c | 4 ++-- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index c15ecd1..b0ee62c 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -179,7 +179,6 @@ static pa_bluetooth_device* device_new(pa_bluetooth_discovery *discovery, const d-device_info_valid = 0; -d-name = NULL; d-path = pa_xstrdup(path); d-paired = -1; d-alias = NULL; @@ -228,7 +227,6 @@ static void device_free(pa_bluetooth_device *d) { uuid_free(u); } -pa_xfree(d-name); pa_xfree(d-path); pa_xfree(d-alias); pa_xfree(d-address); @@ -364,10 +362,7 @@ static int parse_device_property(pa_bluetooth_device *d, DBusMessageIter *i, boo const char *value; dbus_message_iter_get_basic(variant_i, value); -if (pa_streq(key, Name)) { -pa_xfree(d-name); -d-name = pa_xstrdup(value); -} else if (pa_streq(key, Alias)) { +if (pa_streq(key, Alias)) { pa_xfree(d-alias); d-alias = pa_xstrdup(value); } else if (pa_streq(key, Address)) { diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index 3361b0f..1040d5b 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -120,7 +120,6 @@ struct pa_bluetooth_device { int device_info_valid; /* 0: no results yet; 1: good results; -1: bad results ... */ /* Device information */ -char *name; I don't see the removal as part of this patch, regardless of what you do with pa_proplist_sets() below. Ok, I can split it in a separate patch. char *path; pa_bluetooth_transport *transports[PA_BLUETOOTH_PROFILE_COUNT]; int paired; diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index cd0a515..ddf658f 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2237,7 +2237,7 @@ static int add_card(struct userdata *u) { data.driver = __FILE__; data.module = u-module; -n = pa_bluetooth_cleanup_name(device-name); +n = pa_bluetooth_cleanup_name(device-alias); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, n); pa_xfree(n); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, device-address); @@ -2250,7 +2250,7 @@ static int add_card(struct userdata *u) { pa_proplist_sets(data.proplist, bluez.path, device-path); pa_proplist_setf(data.proplist, bluez.class, 0x%06x, (unsigned) device-class); -pa_proplist_sets(data.proplist, bluez.name, device-name); +pa_proplist_sets(data.proplist, bluez.name, device-alias); What's the purpose of replacing this existing property instead of adding 'bluez.alias'? As mentioned before, we should only use the 'Alias' value and not the 'Name' one, so there is no point in storing it. I'm not sure when (regarding PulseAudio release versions) we can change the property from 'bluez.name' to 'bluez.alias', since IIRC these properties are exposed to PulseAudio clients. I'd first add bluez.alias and we can discuss afterwards whether bluez.name should be dropped. Changing the internal mapping seems obscure and error-prone to me, not to mention
Re: [pulseaudio-discuss] [PATCH] bluetooth: Use 'Alias' instead of 'Name'
Hi João Paulo, On Thu, Apr 25, 2013 at 9:36 AM, Mikel Astiz mikel.astiz@gmail.com wrote: Hi João, On Wed, Apr 24, 2013 at 7:51 PM, João Paulo Rechi Vita jprv...@openbossa.org wrote: On Wed, Apr 24, 2013 at 3:29 AM, Mikel Astiz mikel.astiz@gmail.com wrote: Hi João Paulo, On Tue, Apr 23, 2013 at 10:48 PM, jprv...@gmail.com wrote: From: João Paulo Rechi Vita jprv...@openbossa.org According to the BlueZ API documentation the 'Alias' property should be preffered over the 'Name' property. Also, if the device doesn't have a remote name the 'Name' property may not be set, but the 'Alias' property will always be. Can you point to the documentation you refer to? 'Alias' is a user-modifiable property, while 'Name' is what the remote device reports. They just have different purposes, so I don't think one of them is preferred over the other as a general rule. doc/device-api.txt in BlueZ repository explicitly states that 'Alias' should be preferred over 'Name'. If you go back in history you'll see that it was first mentioned before BlueZ 4.0. I'm still not convinced. These are two different properties, both exposed by BlueZ for some reason, and it can be misleading that we start using a different terminology inside PA, and map alias-name. I'm fine encouraging the use of 'bluez.alias' over 'bluez.name', but renaming it internally should be avoided IMO. --- src/modules/bluetooth/bluetooth-util.c | 7 +-- src/modules/bluetooth/bluetooth-util.h | 1 - src/modules/bluetooth/module-bluetooth-device.c | 4 ++-- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index c15ecd1..b0ee62c 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -179,7 +179,6 @@ static pa_bluetooth_device* device_new(pa_bluetooth_discovery *discovery, const d-device_info_valid = 0; -d-name = NULL; d-path = pa_xstrdup(path); d-paired = -1; d-alias = NULL; @@ -228,7 +227,6 @@ static void device_free(pa_bluetooth_device *d) { uuid_free(u); } -pa_xfree(d-name); pa_xfree(d-path); pa_xfree(d-alias); pa_xfree(d-address); @@ -364,10 +362,7 @@ static int parse_device_property(pa_bluetooth_device *d, DBusMessageIter *i, boo const char *value; dbus_message_iter_get_basic(variant_i, value); -if (pa_streq(key, Name)) { -pa_xfree(d-name); -d-name = pa_xstrdup(value); -} else if (pa_streq(key, Alias)) { +if (pa_streq(key, Alias)) { pa_xfree(d-alias); d-alias = pa_xstrdup(value); } else if (pa_streq(key, Address)) { diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index 3361b0f..1040d5b 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -120,7 +120,6 @@ struct pa_bluetooth_device { int device_info_valid; /* 0: no results yet; 1: good results; -1: bad results ... */ /* Device information */ -char *name; I don't see the removal as part of this patch, regardless of what you do with pa_proplist_sets() below. Ok, I can split it in a separate patch. char *path; pa_bluetooth_transport *transports[PA_BLUETOOTH_PROFILE_COUNT]; int paired; diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index cd0a515..ddf658f 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2237,7 +2237,7 @@ static int add_card(struct userdata *u) { data.driver = __FILE__; data.module = u-module; -n = pa_bluetooth_cleanup_name(device-name); +n = pa_bluetooth_cleanup_name(device-alias); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, n); pa_xfree(n); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, device-address); @@ -2250,7 +2250,7 @@ static int add_card(struct userdata *u) { pa_proplist_sets(data.proplist, bluez.path, device-path); pa_proplist_setf(data.proplist, bluez.class, 0x%06x, (unsigned) device-class); -pa_proplist_sets(data.proplist, bluez.name, device-name); +pa_proplist_sets(data.proplist, bluez.name, device-alias); What's the purpose of replacing this existing property instead of adding 'bluez.alias'? As mentioned before, we should only use the 'Alias' value and not the 'Name' one, so there is no point in storing it. I'm not sure when (regarding PulseAudio release versions) we can change the property from 'bluez.name' to 'bluez.alias', since IIRC these properties are exposed to PulseAudio clients. I'd first add bluez.alias and we can discuss afterwards whether bluez.name
Re: [pulseaudio-discuss] [PATCH] bluetooth: Use 'Alias' instead of 'Name'
Hi João Paulo, On Tue, Apr 23, 2013 at 10:48 PM, jprv...@gmail.com wrote: From: João Paulo Rechi Vita jprv...@openbossa.org According to the BlueZ API documentation the 'Alias' property should be preffered over the 'Name' property. Also, if the device doesn't have a remote name the 'Name' property may not be set, but the 'Alias' property will always be. Can you point to the documentation you refer to? 'Alias' is a user-modifiable property, while 'Name' is what the remote device reports. They just have different purposes, so I don't think one of them is preferred over the other as a general rule. --- src/modules/bluetooth/bluetooth-util.c | 7 +-- src/modules/bluetooth/bluetooth-util.h | 1 - src/modules/bluetooth/module-bluetooth-device.c | 4 ++-- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index c15ecd1..b0ee62c 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -179,7 +179,6 @@ static pa_bluetooth_device* device_new(pa_bluetooth_discovery *discovery, const d-device_info_valid = 0; -d-name = NULL; d-path = pa_xstrdup(path); d-paired = -1; d-alias = NULL; @@ -228,7 +227,6 @@ static void device_free(pa_bluetooth_device *d) { uuid_free(u); } -pa_xfree(d-name); pa_xfree(d-path); pa_xfree(d-alias); pa_xfree(d-address); @@ -364,10 +362,7 @@ static int parse_device_property(pa_bluetooth_device *d, DBusMessageIter *i, boo const char *value; dbus_message_iter_get_basic(variant_i, value); -if (pa_streq(key, Name)) { -pa_xfree(d-name); -d-name = pa_xstrdup(value); -} else if (pa_streq(key, Alias)) { +if (pa_streq(key, Alias)) { pa_xfree(d-alias); d-alias = pa_xstrdup(value); } else if (pa_streq(key, Address)) { diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index 3361b0f..1040d5b 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -120,7 +120,6 @@ struct pa_bluetooth_device { int device_info_valid; /* 0: no results yet; 1: good results; -1: bad results ... */ /* Device information */ -char *name; I don't see the removal as part of this patch, regardless of what you do with pa_proplist_sets() below. char *path; pa_bluetooth_transport *transports[PA_BLUETOOTH_PROFILE_COUNT]; int paired; diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index cd0a515..ddf658f 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2237,7 +2237,7 @@ static int add_card(struct userdata *u) { data.driver = __FILE__; data.module = u-module; -n = pa_bluetooth_cleanup_name(device-name); +n = pa_bluetooth_cleanup_name(device-alias); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, n); pa_xfree(n); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, device-address); @@ -2250,7 +2250,7 @@ static int add_card(struct userdata *u) { pa_proplist_sets(data.proplist, bluez.path, device-path); pa_proplist_setf(data.proplist, bluez.class, 0x%06x, (unsigned) device-class); -pa_proplist_sets(data.proplist, bluez.name, device-name); +pa_proplist_sets(data.proplist, bluez.name, device-alias); What's the purpose of replacing this existing property instead of adding 'bluez.alias'? Btw, I'm not seeing any user of this property so I'm wondering why you're interested in such a change. Is it for development and testing purposes? data.name = get_name(card, u-modargs, device-address, b); data.namereg_fail = b; -- Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [RFCv3 18/20] bluetooth: Call HandsfreeAudioCard.Connect() on non-optional acquire
Hi João, On Mon, Apr 22, 2013 at 3:30 PM, João Paulo Rechi Vita jprv...@openbossa.org wrote: On Mon, Apr 22, 2013 at 4:43 AM, Mikel Astiz mikel.astiz@gmail.com wrote: Hi João Paulo, On Mon, Apr 22, 2013 at 5:07 AM, jprv...@gmail.com wrote: From: João Paulo Rechi Vita jprv...@openbossa.org When the HFP sink/source is resumed and the transport is not acquired a new Audio Connection should be started by the HF. This is needed to support audio call transfer from the AG to the HF triggered by the HF. --- src/modules/bluetooth/bluetooth-util.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index a00dac7..0fd4c8e 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1873,6 +1873,12 @@ int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, siz if (t-profile == PROFILE_HFGW) { struct handsfree_card *hf_card = pa_hashmap_get(t-device-discovery-hf_cards, t-path); +if (!optional) { +pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.ofono.HandsfreeAudioCard, Connect)); + pa_assert_se(dbus_connection_send(pa_dbus_connection_get(t-device-discovery-connection), m, NULL)); +return -1; +} + I don't see how this improves the problem considering you're supposed to block and return the fd, along with imtu and omtu. Sorry, I wrote this a bit late in the evening and didn't make myself clear enough. The solution to the problem is actually implemented by this commit plus the previous one. The whole idea is that when the It's not clear to me what v3 17/20 is achieving, since I thought returning -1 would be enough without having to skip the call to process_msg(). If this is assumption is wrong, patch v3 17/20 should probably be considered a fix, independent of the rest of the patchset, and be submitted to the stable branch. sink/source is resumed we do a non-optional acquire, and if that acquire fails we do not resume it (what makes sense even without taking this problem into consideration, since there is no stream fd to be handled). This behavior is implemented in the previous commit. Your description above seems to (or should) fit the existing approach, but you still need the blocking call. Otherwise you can't know whether the non-optional acquire failed or not. And this information is needed, because the sink/source resume depends on this operation, and should fail otherwise. In this commit we handle the non-optional acquire for (PROFILE_HFGW BLUEZ_VERSION_5), calling Connect() and failing the acquire, since we can't return a valid stream fd at this point. The Connect() will This is exactly what is not acceptable without major changes in module-bluetooth-device. It was possible with BlueZ 4, and it seems to me that it's more difficult with oFono only because the Connect() method does not return the fd. trigger an AT+BCC command to the AG and the AG will start an audio connection establishment that will end up in a call to NewConnection(), so we'll handle this through the regular NewConnection() flow. This would be valid provided that you could block the thread until the NewConnection() is received. This idea has worked on my tests, the only drawback is that since we're not resuming the sink/source right away, the sink-input/source-output might get moved to the fallback sink/source. I'm not sure if this is a problem from the client perspective. I believe it's a big issue not only from the practical perspective, but also from the design's point of view. All resumes would initially fail and then get automatically triggered afterwards. Regarding blocking at this point, I think this may not be a good idea because this is called from I/O thread context. It's been like this for some time and there's no known related issues. Note that the I/O thread can't do much while an acquire operation is in progress. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC v3 00/16] bluetooth: BlueZ 5 development patches
From: Mikel Astiz mikel.as...@bmw-carit.de The patchset has been hanging around for a while and several efforts exist that depend on this series, so it seems we should merge this despite the existing discussions about how different backends (BlueZ 4, BlueZ 5, oFono, etc.) should be supported inside PulseAudio (next big patchset in the pipeline). The discussion raised by João Paulo is whether the HSP/HFP endpoint should be registered or not, and the few associated features implemented. Luiz suggested it'd be good in any case to have the patches for reference, so I'm sending the full patchset (including the HSP/HFP part) reworked in a way that such code is grouped in the end (starting with v3 12/16). Other changes from v2: - Issue fixed in patch v2 07/15 (now v3 05/16) as pointed out by João. - Improved commit message for patch v2 10/15 (now v3 08/16). Mikel Astiz (15): bluetooth: Detect BlueZ 5 bluetooth: Parse the tree returned by ObjectManager bluetooth: Support ObjectManager interface add/remove bluetooth: Support Properties.PropertiesChanged signal bluetooth: BlueZ 5 interface rename to org.bluez.MediaEndpoint1 bluetooth: BlueZ 5 interface rename to org.bluez.Media1 bluetooth: BlueZ 5 interface rename to org.bluez.MediaTransport1 bluetooth: Parse media transport's properties bluetooth: Support media transport's State property bluetooth: Update to new BlueZ 5 transport acquire/release API bluetooth: Support transport auto-release bluetooth: Register HSP/HFP endpoints in BlueZ 5 Media API bluetooth: Handle transports configured before UUID received bluetooth: Update to new property setter API in BlueZ 5 bluetooth: Update to volume control in BlueZ 5 Vinicius Costa Gomes (1): bluetooth: Add HFP 1.6 codec ID src/modules/bluetooth/bluetooth-util.c | 568 ++-- src/modules/bluetooth/module-bluetooth-device.c | 8 +- 2 files changed, 521 insertions(+), 55 deletions(-) -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC v3 02/16] bluetooth: Parse the tree returned by ObjectManager
From: Mikel Astiz mikel.as...@bmw-carit.de Parse the result of ObjectManager.GetManagedObjects(), which includes all objects registered, their interfaces and the corresponding properties per interface. --- src/modules/bluetooth/bluetooth-util.c | 125 +++-- 1 file changed, 119 insertions(+), 6 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 1883c8a..9a0a2e1 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -362,8 +362,6 @@ static int parse_device_property(pa_bluetooth_device *d, DBusMessageIter *i, boo dbus_message_iter_recurse(i, variant_i); -/* pa_log_debug(Parsing property org.bluez.Device.%s, key); */ - switch (dbus_message_iter_get_arg_type(variant_i)) { case DBUS_TYPE_STRING: { @@ -452,6 +450,11 @@ static int parse_device_property(pa_bluetooth_device *d, DBusMessageIter *i, boo uuiddata.uuid = value; pa_hook_fire(d-discovery-hooks[PA_BLUETOOTH_HOOK_DEVICE_UUID_ADDED], uuiddata); +if (d-discovery-version = BLUEZ_VERSION_5) { +dbus_message_iter_next(ai); +continue; +} + /* Vudentz said the interfaces are here when the UUIDs are announced */ if (strcasecmp(HSP_AG_UUID, value) == 0 || strcasecmp(HFP_AG_UUID, value) == 0) { pa_assert_se(m = dbus_message_new_method_call(org.bluez, d-path, org.bluez.HandsfreeGateway, @@ -867,16 +870,25 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const send_and_add_to_pending(y, m, register_endpoint_reply, pa_xstrdup(endpoint)); } +static void register_adapter_endpoints(pa_bluetooth_discovery *y, const char *path) { +register_endpoint(y, path, A2DP_SOURCE_ENDPOINT, A2DP_SOURCE_UUID); +register_endpoint(y, path, A2DP_SINK_ENDPOINT, A2DP_SINK_UUID); + +/* For BlueZ 5, only A2DP is registered in the Media API */ +if (y-version = BLUEZ_VERSION_5) +return; + +register_endpoint(y, path, HFP_AG_ENDPOINT, HFP_AG_UUID); +register_endpoint(y, path, HFP_HS_ENDPOINT, HFP_HS_UUID); +} + static void found_adapter(pa_bluetooth_discovery *y, const char *path) { DBusMessage *m; pa_assert_se(m = dbus_message_new_method_call(org.bluez, path, org.bluez.Adapter, GetProperties)); send_and_add_to_pending(y, m, get_properties_reply, NULL); -register_endpoint(y, path, HFP_AG_ENDPOINT, HFP_AG_UUID); -register_endpoint(y, path, HFP_HS_ENDPOINT, HFP_HS_UUID); -register_endpoint(y, path, A2DP_SOURCE_ENDPOINT, A2DP_SOURCE_UUID); -register_endpoint(y, path, A2DP_SINK_ENDPOINT, A2DP_SINK_UUID); +register_adapter_endpoints(y, path); } static void list_adapters(pa_bluetooth_discovery *y) { @@ -887,10 +899,94 @@ static void list_adapters(pa_bluetooth_discovery *y) { send_and_add_to_pending(y, m, get_properties_reply, NULL); } +static int parse_device_properties(pa_bluetooth_device *d, DBusMessageIter *i, bool is_property_change) { +DBusMessageIter element_i; +int ret = 0; + +dbus_message_iter_recurse(i, element_i); + +while (dbus_message_iter_get_arg_type(element_i) == DBUS_TYPE_DICT_ENTRY) { +DBusMessageIter dict_i; + +dbus_message_iter_recurse(element_i, dict_i); + +if (parse_device_property(d, dict_i, is_property_change)) +ret = -1; + +dbus_message_iter_next(element_i); +} + +if (!d-name || !d-address || !d-alias || d-paired 0 || d-trusted 0) { +pa_log_error(Non-optional information missing for device %s, d-path); +d-device_info_valid = -1; +return -1; +} + +d-device_info_valid = 1; +return ret; +} + +static int parse_interfaces_and_properties(pa_bluetooth_discovery *y, DBusMessageIter *dict_i) { +DBusMessageIter element_i; +const char *path; + +pa_assert(dbus_message_iter_get_arg_type(dict_i) == DBUS_TYPE_OBJECT_PATH); +dbus_message_iter_get_basic(dict_i, path); + +pa_assert_se(dbus_message_iter_next(dict_i)); +pa_assert(dbus_message_iter_get_arg_type(dict_i) == DBUS_TYPE_ARRAY); + +dbus_message_iter_recurse(dict_i, element_i); + +while (dbus_message_iter_get_arg_type(element_i) == DBUS_TYPE_DICT_ENTRY) { +DBusMessageIter iface_i; +const char *interface; + +dbus_message_iter_recurse(element_i, iface_i); + +pa_assert(dbus_message_iter_get_arg_type(iface_i) == DBUS_TYPE_STRING); +dbus_message_iter_get_basic(iface_i, interface); + +pa_assert_se(dbus_message_iter_next(iface_i)); +pa_assert(dbus_message_iter_get_arg_type(iface_i) == DBUS_TYPE_ARRAY); + +if (pa_streq(interface, org.bluez.Adapter1)) { +pa_log_debug(Adapter %s found, path); +register_adapter_endpoints(y, path
[pulseaudio-discuss] [RFC v3 03/16] bluetooth: Support ObjectManager interface add/remove
From: Mikel Astiz mikel.as...@bmw-carit.de Install matches for signals ObjectManager.InterfacesAdded and ObjectManager.InterfacesRemoved, and process the devices that are registered and unregistered dynamically. --- src/modules/bluetooth/bluetooth-util.c | 58 ++ 1 file changed, 58 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 9a0a2e1..880e329 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1209,6 +1209,60 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us goto fail; return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} else if (dbus_message_is_signal(m, org.freedesktop.DBus.ObjectManager, InterfacesAdded)) { +DBusMessageIter arg_i; + +if (y-version != BLUEZ_VERSION_5) +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */ + +if (!dbus_message_iter_init(m, arg_i) || !pa_streq(dbus_message_get_signature(m), oa{sa{sv}})) { +pa_log(Invalid signature found in InterfacesAdded); +goto fail; +} + +if (parse_interfaces_and_properties(y, arg_i) 0) +goto fail; + +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} else if (dbus_message_is_signal(m, org.freedesktop.DBus.ObjectManager, InterfacesRemoved)) { +const char *path; +DBusMessageIter arg_i; +DBusMessageIter element_i; + +if (y-version != BLUEZ_VERSION_5) +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */ + +if (!dbus_message_iter_init(m, arg_i) || !pa_streq(dbus_message_get_signature(m), oas)) { +pa_log(Invalid signature found in InterfacesRemoved); +goto fail; +} + +dbus_message_iter_get_basic(arg_i, path); + +pa_assert_se(dbus_message_iter_next(arg_i)); +pa_assert(dbus_message_iter_get_arg_type(arg_i) == DBUS_TYPE_ARRAY); + +dbus_message_iter_recurse(arg_i, element_i); + +while (dbus_message_iter_get_arg_type(element_i) == DBUS_TYPE_STRING) { +const char *interface; + +dbus_message_iter_get_basic(element_i, interface); + +if (pa_streq(interface, org.bluez.Device1)) { +pa_bluetooth_device *d; + +if ((d = pa_hashmap_remove(y-devices, path))) { +pa_log_debug(Device %s removed, d-path); +run_callback(d, true); +device_free(d); +} +} + +dbus_message_iter_next(element_i); +} + +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } fail: @@ -1861,6 +1915,8 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', NULL) 0) { pa_log(Failed to add D-Bus matches: %s, err.message); goto fail; @@ -1934,6 +1990,8 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) { type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', NULL); if (y-filter_added) -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC v3 04/16] bluetooth: Support Properties.PropertiesChanged signal
From: Mikel Astiz mikel.as...@bmw-carit.de Install matches for signal Properties.PropertiesChanged and process the properties corresponding to the tracked devices. --- src/modules/bluetooth/bluetooth-util.c | 29 + 1 file changed, 29 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 880e329..7e7a3b1 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1263,6 +1263,33 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} else if (dbus_message_is_signal(m, org.freedesktop.DBus.Properties, PropertiesChanged)) { +DBusMessageIter arg_i; +const char *interface; + +if (y-version != BLUEZ_VERSION_5) +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */ + +if (!dbus_message_iter_init(m, arg_i) || !pa_streq(dbus_message_get_signature(m), sa{sv}as)) { +pa_log(Invalid signature found in PropertiesChanged); +goto fail; +} + +dbus_message_iter_get_basic(arg_i, interface); + +pa_assert_se(dbus_message_iter_next(arg_i)); +pa_assert(dbus_message_iter_get_arg_type(arg_i) == DBUS_TYPE_ARRAY); + +if (pa_streq(interface, org.bluez.Device1)) { +pa_bluetooth_device *d; + +if (!(d = pa_hashmap_get(y-devices, dbus_message_get_path(m +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* Device not being tracked */ + +parse_device_properties(d, arg_i, true); +} + +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } fail: @@ -1917,6 +1944,8 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' +,arg0='org.bluez.Device1', NULL) 0) { pa_log(Failed to add D-Bus matches: %s, err.message); goto fail; -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC v3 05/16] bluetooth: BlueZ 5 interface rename to org.bluez.MediaEndpoint1
From: Mikel Astiz mikel.as...@bmw-carit.de Use the new interface name if BlueZ 5 has been detected. --- src/modules/bluetooth/bluetooth-util.c | 51 -- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 7e7a3b1..3560227 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -61,6 +61,30 @@ /interface \ /node +#define MEDIA_ENDPOINT_1_INTROSPECT_XML \ +DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ +node\ + interface name=\org.bluez.MediaEndpoint1\\ + method name=\SetConfiguration\ \ + arg name=\transport\ direction=\in\ type=\o\/ \ + arg name=\configuration\ direction=\in\ type=\ay\/ \ + /method \ + method name=\SelectConfiguration\ \ + arg name=\capabilities\ direction=\in\ type=\ay\/ \ + arg name=\configuration\ direction=\out\ type=\ay\/\ + /method \ + method name=\ClearConfiguration\\ + /method \ + method name=\Release\ \ + /method \ + /interface \ + interface name=\org.freedesktop.DBus.Introspectable\ \ + method name=\Introspect\\ + arg name=\data\ type=\s\ direction=\out\/ \ + /method \ + /interface \ +/node + typedef enum pa_bluez_version { BLUEZ_VERSION_UNKNOWN, BLUEZ_VERSION_4, @@ -1534,7 +1558,7 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage dbus_message_iter_get_basic(args, path); if (pa_hashmap_get(y-transports, path)) { -pa_log(org.bluez.MediaEndpoint.SetConfiguration: Transport %s is already configured., path); +pa_log(Endpoint SetConfiguration: Transport %s is already configured., path); goto fail2; } @@ -1628,11 +1652,10 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage return NULL; fail: -pa_log(org.bluez.MediaEndpoint.SetConfiguration: invalid arguments); +pa_log(Endpoint SetConfiguration: invalid arguments); fail2: -pa_assert_se(r = dbus_message_new_error(m, org.bluez.MediaEndpoint.Error.InvalidArguments, -Unable to set configuration)); +pa_assert_se(r = dbus_message_new_error(m, org.bluez.Error.InvalidArguments, Unable to set configuration)); return r; } @@ -1646,7 +1669,7 @@ static DBusMessage *endpoint_clear_configuration(DBusConnection *c, DBusMessage dbus_error_init(e); if (!dbus_message_get_args(m, e, DBUS_TYPE_OBJECT_PATH, path, DBUS_TYPE_INVALID)) { -pa_log(org.bluez.MediaEndpoint.ClearConfiguration: %s, e.message); +pa_log(Endpoint ClearConfiguration: %s, e.message); dbus_error_free(e); goto fail; } @@ -1671,8 +1694,7 @@ static DBusMessage *endpoint_clear_configuration(DBusConnection *c, DBusMessage return r; fail: -pa_assert_se(r = dbus_message_new_error(m, org.bluez.MediaEndpoint.Error.InvalidArguments, -Unable to clear configuration)); +pa_assert_se(r = dbus_message_new_error(m, org.bluez.Error.InvalidArguments, Unable to clear configuration)); return r; } @@ -1742,7 +1764,7 @@ static DBusMessage *endpoint_select_configuration(DBusConnection *c, DBusMessage dbus_error_init(e); if (!dbus_message_get_args(m, e, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, cap, size, DBUS_TYPE_INVALID)) { -pa_log(org.bluez.MediaEndpoint.SelectConfiguration: %s, e.message); +pa_log(Endpoint SelectConfiguration: %s, e.message); dbus_error_free(e); goto fail; } @@ -1839,8 +1861,7 @@ done: return r; fail: -pa_assert_se(r = dbus_message_new_error(m, org.bluez.MediaEndpoint.Error.InvalidArguments, -Unable to select configuration)); +pa_assert_se(r = dbus_message_new_error(m, org.bluez.Error.InvalidArguments, Unable to select configuration)); return r; } @@ -1864,17 +1885,19 @@ static DBusHandlerResult endpoint_handler(DBusConnection *c, DBusMessage *m, voi !pa_streq(path, HFP_HS_ENDPOINT)) return
[pulseaudio-discuss] [RFC v3 06/16] bluetooth: BlueZ 5 interface rename to org.bluez.Media1
From: Mikel Astiz mikel.as...@bmw-carit.de Use the new interface name if BlueZ 5 has been detected. --- src/modules/bluetooth/bluetooth-util.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 3560227..c9c60d1 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -834,8 +834,7 @@ static void register_endpoint_reply(DBusPendingCall *pending, void *userdata) { } if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { -pa_log(org.bluez.Media.RegisterEndpoint() failed: %s: %s, dbus_message_get_error_name(r), - pa_dbus_get_error_message(r)); +pa_log(RegisterEndpoint() failed: %s: %s, dbus_message_get_error_name(r), pa_dbus_get_error_message(r)); goto finish; } @@ -852,10 +851,11 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const DBusMessage *m; DBusMessageIter i, d; uint8_t codec = 0; +const char *interface = y-version == BLUEZ_VERSION_4 ? org.bluez.Media : org.bluez.Media1; pa_log_debug(Registering %s on adapter %s., endpoint, path); -pa_assert_se(m = dbus_message_new_method_call(org.bluez, path, org.bluez.Media, RegisterEndpoint)); +pa_assert_se(m = dbus_message_new_method_call(org.bluez, path, interface, RegisterEndpoint)); dbus_message_iter_init_append(m, i); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC v3 07/16] bluetooth: BlueZ 5 interface rename to org.bluez.MediaTransport1
From: Mikel Astiz mikel.as...@bmw-carit.de Use the new interface name if BlueZ 5 has been detected. --- src/modules/bluetooth/bluetooth-util.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index c9c60d1..08f07d5 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1387,6 +1387,7 @@ bool pa_bluetooth_device_any_audio_connected(const pa_bluetooth_device *d) { int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) { const char *accesstype = rw; +const char *interface; DBusMessage *m, *r; DBusError err; int ret; @@ -1396,6 +1397,8 @@ int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, siz pa_assert(t-device); pa_assert(t-device-discovery); +interface = t-device-discovery-version == BLUEZ_VERSION_4 ? org.bluez.MediaTransport : org.bluez.MediaTransport1; + if (optional) { /* FIXME: we are trying to acquire the transport only if the stream is playing, without actually initiating the stream request from our side @@ -1412,7 +1415,7 @@ int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, siz dbus_error_init(err); -pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport, Acquire)); +pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, interface, Acquire)); pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, accesstype, DBUS_TYPE_INVALID)); r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t-device-discovery-connection), m, -1, err); @@ -1423,7 +1426,7 @@ int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, siz if (!dbus_message_get_args(r, err, DBUS_TYPE_UNIX_FD, ret, DBUS_TYPE_UINT16, i, DBUS_TYPE_UINT16, o, DBUS_TYPE_INVALID)) { -pa_log(Failed to parse org.bluez.MediaTransport.Acquire(): %s, err.message); +pa_log(Failed to parse the media transport Acquire() reply: %s, err.message); ret = -1; dbus_error_free(err); goto fail; @@ -1442,6 +1445,7 @@ fail: void pa_bluetooth_transport_release(pa_bluetooth_transport *t) { const char *accesstype = rw; +const char *interface; DBusMessage *m; DBusError err; @@ -1449,9 +1453,11 @@ void pa_bluetooth_transport_release(pa_bluetooth_transport *t) { pa_assert(t-device); pa_assert(t-device-discovery); +interface = t-device-discovery-version == BLUEZ_VERSION_4 ? org.bluez.MediaTransport : org.bluez.MediaTransport1; + dbus_error_init(err); -pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport, Release)); +pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, interface, Release)); pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, accesstype, DBUS_TYPE_INVALID)); dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t-device-discovery-connection), m, -1, err); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC v3 09/16] bluetooth: Support media transport's State property
From: Mikel Astiz mikel.as...@bmw-carit.de BlueZ 5 exposes a 'State' property in the media transport interface. With regard to PA, this replaces the profile-specific interfaces, since they were being used to know if the audio was streaming or not. --- src/modules/bluetooth/bluetooth-util.c | 42 +- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index d078cdb..7bc8afc 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -126,6 +126,20 @@ static pa_bt_audio_state_t audio_state_from_string(const char* value) { return PA_BT_AUDIO_STATE_INVALID; } +static int transport_state_from_string(const char* value, pa_bluetooth_transport_state_t *state) { +pa_assert(value); +pa_assert(state); + +if (pa_streq(value, idle)) +*state = PA_BLUETOOTH_TRANSPORT_STATE_IDLE; +else if (pa_streq(value, pending) || pa_streq(value, active)) /* We don't need such a separation */ +*state = PA_BLUETOOTH_TRANSPORT_STATE_PLAYING; +else +return -1; + +return 0; +} + const char *pa_bt_profile_to_string(enum profile profile) { switch(profile) { case PROFILE_A2DP: @@ -1089,6 +1103,29 @@ static int transport_parse_property(pa_bluetooth_transport *t, DBusMessageIter * break; } + +case DBUS_TYPE_STRING: { + +const char *value; +dbus_message_iter_get_basic(variant_i, value); + +if (pa_streq(key, State)) { /* Added in BlueZ 5.0 */ +bool old_any_connected = pa_bluetooth_device_any_audio_connected(t-device); + +if (transport_state_from_string(value, t-state) 0) { +pa_log(Transport %s has an invalid state: '%s', t-path, value); +return -1; +} + +pa_log_debug(dbus: transport %s set to state '%s', t-path, value); + pa_hook_fire(t-device-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED], t); + +if (old_any_connected != pa_bluetooth_device_any_audio_connected(t-device)) +run_callback(t-device, old_any_connected); +} + +break; +} } return 0; @@ -1563,7 +1600,10 @@ static pa_bluetooth_transport *transport_new(pa_bluetooth_device *d, const char memcpy(t-config, config, size); } -t-state = audio_state_to_transport_state(d-profile_state[p]); +if (d-discovery-version == BLUEZ_VERSION_4) +t-state = audio_state_to_transport_state(d-profile_state[p]); +else +t-state = PA_BLUETOOTH_TRANSPORT_STATE_IDLE; return t; } -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC v3 12/16] bluetooth: Register HSP/HFP endpoints in BlueZ 5 Media API
From: Mikel Astiz mikel.as...@bmw-carit.de Register the HSP/HFP endpoints in BlueZ 5 Media API for the sake of completeness, despite the fact that there's currently no known user of such an endpoint. --- src/modules/bluetooth/bluetooth-util.c | 5 - 1 file changed, 5 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 2d958d5..1eaa249 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -911,11 +911,6 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const static void register_adapter_endpoints(pa_bluetooth_discovery *y, const char *path) { register_endpoint(y, path, A2DP_SOURCE_ENDPOINT, A2DP_SOURCE_UUID); register_endpoint(y, path, A2DP_SINK_ENDPOINT, A2DP_SINK_UUID); - -/* For BlueZ 5, only A2DP is registered in the Media API */ -if (y-version = BLUEZ_VERSION_5) -return; - register_endpoint(y, path, HFP_AG_ENDPOINT, HFP_AG_UUID); register_endpoint(y, path, HFP_HS_ENDPOINT, HFP_HS_UUID); } -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC v3 13/16] bluetooth: Add HFP 1.6 codec ID
From: Vinicius Costa Gomes vinicius.go...@openbossa.org According to the HFP 1.6 spec, the default codec (CVSD) has ID 0x01. This change has no effect in older versions of BlueZ since the codec ID was ignored for HFP, due to the fact that HFP versions prior to 1.6 do not have such a field. --- src/modules/bluetooth/bluetooth-util.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 1eaa249..4b93ab2 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -864,7 +864,7 @@ finish: static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const char *endpoint, const char *uuid) { DBusMessage *m; DBusMessageIter i, d; -uint8_t codec = 0; +uint8_t codec; const char *interface = y-version == BLUEZ_VERSION_4 ? org.bluez.Media : org.bluez.Media1; pa_log_debug(Registering %s on adapter %s., endpoint, path); @@ -881,14 +881,18 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const pa_dbus_append_basic_variant_dict_entry(d, UUID, DBUS_TYPE_STRING, uuid); -pa_dbus_append_basic_variant_dict_entry(d, Codec, DBUS_TYPE_BYTE, codec); if (pa_streq(uuid, HFP_AG_UUID) || pa_streq(uuid, HFP_HS_UUID)) { uint8_t capability = 0; + +codec = 1; + pa_dbus_append_basic_array_variant_dict_entry(d, Capabilities, DBUS_TYPE_BYTE, capability, 1); } else { a2dp_sbc_t capabilities; +codec = 0; + capabilities.channel_mode = SBC_CHANNEL_MODE_MONO | SBC_CHANNEL_MODE_DUAL_CHANNEL | SBC_CHANNEL_MODE_STEREO | SBC_CHANNEL_MODE_JOINT_STEREO; capabilities.frequency = SBC_SAMPLING_FREQ_16000 | SBC_SAMPLING_FREQ_32000 | @@ -903,6 +907,8 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const pa_dbus_append_basic_array_variant_dict_entry(d, Capabilities, DBUS_TYPE_BYTE, capabilities, sizeof(capabilities)); } +pa_dbus_append_basic_variant_dict_entry(d, Codec, DBUS_TYPE_BYTE, codec); + dbus_message_iter_close_container(i, d); send_and_add_to_pending(y, m, register_endpoint_reply, pa_xstrdup(endpoint)); -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC v3 14/16] bluetooth: Handle transports configured before UUID received
From: Mikel Astiz mikel.as...@bmw-carit.de Now that the transport can be configured from some other process (i.e. oFono), there is no guarantee that the UUID from BlueZ will already have been received. This requires PulseAudio to assume that the UUID is actually supported by the device and that BlueZ will eventually propagate it. --- src/modules/bluetooth/bluetooth-util.c | 53 ++ 1 file changed, 53 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 4b93ab2..5cea246 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -178,6 +178,33 @@ static int profile_from_interface(const char *interface, enum profile *p) { return -1; } +static void profile_to_remote_uuid(enum profile p, const char *res[2]) { +pa_assert(p != PROFILE_OFF); + +switch(p) { +case PROFILE_A2DP: +res[0] = A2DP_SINK_UUID; +res[1] = NULL; +return; +case PROFILE_A2DP_SOURCE: +res[0] = A2DP_SOURCE_UUID; +res[1] = NULL; +return; +case PROFILE_HSP: +res[0] = HSP_HS_UUID; +res[1] = HFP_HS_UUID; +return; +case PROFILE_HFGW: +res[0] = HSP_AG_UUID; +res[1] = HFP_AG_UUID; +return; +case PROFILE_OFF: +break; +} + +pa_assert_not_reached(); +} + static pa_bluetooth_transport_state_t audio_state_to_transport_state(pa_bt_audio_state_t state) { switch (state) { case PA_BT_AUDIO_STATE_INVALID: /* Typically if state hasn't been received yet */ @@ -1640,6 +1667,7 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage DBusMessageIter args, props; DBusMessage *r; bool old_any_connected; +const char *remote_uuid[2]; if (!dbus_message_iter_init(m, args) || !pa_streq(dbus_message_get_signature(m), oa{sv})) { pa_log(Invalid signature for method SetConfiguration); @@ -1702,6 +1730,10 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage dbus_message_iter_next(props); } +/* FIXME: with BlueZ 5, check if this is racy in case a newly paired + * device gets connected very fast, before BlueZ has created it. This is + * very unlikely since the device will be created before the pairing + * procedure is complete */ d = found_device(y, dev_path); if (!d) goto fail; @@ -1715,6 +1747,27 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage else p = PROFILE_A2DP_SOURCE; +/* Check if the UUID was already reported by BlueZ, since the telephony + * component (oFono) could be faster than BlueZ */ +profile_to_remote_uuid(p, remote_uuid); + +if (!pa_bluetooth_uuid_has(d-uuids, remote_uuid[0]) !pa_bluetooth_uuid_has(d-uuids, remote_uuid[1])) { +pa_bluetooth_uuid *node; +struct pa_bluetooth_hook_uuid_data uuiddata; + +pa_log_info(Endpoint with UUID '%s' configured before remote UUID was reported by BlueZ., uuid); + +/* This might generate duplicated UUID_ADDED hooks since the endpoint + * doesn't receive the exact remote UUID (HSP cannot be distinguished + * from HFP). However, these duplicated hooks should do no harm */ +node = uuid_new(remote_uuid[0]); +PA_LLIST_PREPEND(pa_bluetooth_uuid, d-uuids, node); + +uuiddata.device = d; +uuiddata.uuid = uuid; + pa_hook_fire(d-discovery-hooks[PA_BLUETOOTH_HOOK_DEVICE_UUID_ADDED], uuiddata); +} + if (d-transports[p] != NULL) { pa_log(Cannot configure transport %s because profile %d is already used, path, p); goto fail2; -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC v3 16/16] bluetooth: Update to volume control in BlueZ 5
From: Mikel Astiz mikel.as...@bmw-carit.de In BlueZ 5, the microphone and speaker gains are exposed as properties of the MediaTransport1 interface. --- src/modules/bluetooth/bluetooth-util.c | 41 ++ 1 file changed, 41 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 30ed071..728c86d 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1154,6 +1154,32 @@ static int transport_parse_property(pa_bluetooth_transport *t, DBusMessageIter * break; } + +case DBUS_TYPE_BYTE: { +uint8_t value; + +dbus_message_iter_get_basic(variant_i, value); + +if (pa_streq(key, MicrophoneGain)) { +uint8_t gain; + +if ((gain = PA_MIN(value, HSP_MAX_GAIN)) == t-microphone_gain) +break; + +t-microphone_gain = gain; + pa_hook_fire(t-device-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED], t); +} else if (pa_streq(key, SpeakerGain)) { +uint8_t gain; + +if ((gain = PA_MIN(value, HSP_MAX_GAIN)) == t-speaker_gain) +break; + +t-speaker_gain = gain; + pa_hook_fire(t-device-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED], t); +} + +break; +} } return 0; @@ -1617,6 +1643,14 @@ void pa_bluetooth_transport_set_microphone_gain(pa_bluetooth_transport *t, uint1 pa_assert(t); pa_assert(t-profile == PROFILE_HSP); +if (t-device-discovery-version = BLUEZ_VERSION_5) { +uint8_t g = (uint8_t) gain; + +set_property(t-device-discovery, t-owner, t-path, org.bluez.MediaTransport1, + MicrophoneGain, DBUS_TYPE_BYTE, g); +return; +} + set_property(t-device-discovery, org.bluez, t-device-path, org.bluez.Headset, MicrophoneGain, DBUS_TYPE_UINT16, gain); } @@ -1627,6 +1661,13 @@ void pa_bluetooth_transport_set_speaker_gain(pa_bluetooth_transport *t, uint16_t pa_assert(t); pa_assert(t-profile == PROFILE_HSP); +if (t-device-discovery-version = BLUEZ_VERSION_5) { +uint8_t g = (uint8_t) gain; + +set_property(t-device-discovery, t-owner, t-path, org.bluez.MediaTransport1, SpeakerGain, DBUS_TYPE_BYTE, g); +return; +} + set_property(t-device-discovery, org.bluez, t-device-path, org.bluez.Headset, SpeakerGain, DBUS_TYPE_UINT16, gain); } -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [RFC v2 15/15] bluetooth: Update to volume control in BlueZ 5
Hi João, On Wed, Apr 17, 2013 at 7:02 PM, João Paulo Rechi Vita jprv...@gmail.com wrote: On Tue, Apr 16, 2013 at 10:40 AM, Mikel Astiz mikel.astiz@gmail.com wrote: From: Mikel Astiz mikel.as...@bmw-carit.de In BlueZ 5, the microphone and speaker gains are exposed as properties of the MediaTransport1 interface. There is no HSP implementation in BlueZ 5 and for HFP these interfaces will be exposed in the oFono API, so this code will never be used. IMO we shouldn't merge this patch util these properties are actually used by someone. I already mentioned this in the cover-letter and basically I agree with your proposal. Cheers, Mikel --- src/modules/bluetooth/bluetooth-util.c | 41 ++ 1 file changed, 41 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 7589c22..de4dbce 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1154,6 +1154,32 @@ static int transport_parse_property(pa_bluetooth_transport *t, DBusMessageIter * break; } + +case DBUS_TYPE_BYTE: { +uint8_t value; + +dbus_message_iter_get_basic(variant_i, value); + +if (pa_streq(key, MicrophoneGain)) { +uint8_t gain; + +if ((gain = PA_MIN(value, HSP_MAX_GAIN)) == t-microphone_gain) +break; + +t-microphone_gain = gain; + pa_hook_fire(t-device-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED], t); +} else if (pa_streq(key, SpeakerGain)) { +uint8_t gain; + +if ((gain = PA_MIN(value, HSP_MAX_GAIN)) == t-speaker_gain) +break; + +t-speaker_gain = gain; + pa_hook_fire(t-device-discovery-hooks[PA_BLUETOOTH_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED], t); +} + +break; +} } return 0; @@ -1617,6 +1643,14 @@ void pa_bluetooth_transport_set_microphone_gain(pa_bluetooth_transport *t, uint1 pa_assert(t); pa_assert(t-profile == PROFILE_HSP); +if (t-device-discovery-version = BLUEZ_VERSION_5) { +uint8_t g = (uint8_t) gain; + +set_property(t-device-discovery, t-owner, t-path, org.bluez.MediaTransport1, + MicrophoneGain, DBUS_TYPE_BYTE, g); +return; +} + set_property(t-device-discovery, org.bluez, t-device-path, org.bluez.Headset, MicrophoneGain, DBUS_TYPE_UINT16, gain); } @@ -1627,6 +1661,13 @@ void pa_bluetooth_transport_set_speaker_gain(pa_bluetooth_transport *t, uint16_t pa_assert(t); pa_assert(t-profile == PROFILE_HSP); +if (t-device-discovery-version = BLUEZ_VERSION_5) { +uint8_t g = (uint8_t) gain; + +set_property(t-device-discovery, t-owner, t-path, org.bluez.MediaTransport1, SpeakerGain, DBUS_TYPE_BYTE, g); +return; +} + set_property(t-device-discovery, org.bluez, t-device-path, org.bluez.Headset, SpeakerGain, DBUS_TYPE_UINT16, gain); } -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss -- João Paulo Rechi Vita http://about.me/jprvita ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [RFC v2 06/15] bluetooth: Handle transports configured before UUID received
Hi João Paulo, On Wed, Apr 17, 2013 at 7:00 PM, João Paulo Rechi Vita jprv...@gmail.com wrote: On Tue, Apr 16, 2013 at 10:40 AM, Mikel Astiz mikel.astiz@gmail.com wrote: From: Mikel Astiz mikel.as...@bmw-carit.de Now that the transport can be configured from some other process (i.e. oFono), there is no guarantee that the UUID from BlueZ will already have been received. This requires PulseAudio to assume that the UUID is actually supported by the device and that BlueZ will eventually propagate it. oFono never calls EndpointSetConfiguration(), so I think we don't need this patch. Agreed to drop this despite the fact that your argumentation is oFono-specific. Cheers, Mikel --- src/modules/bluetooth/bluetooth-util.c | 53 ++ 1 file changed, 53 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index eb504e5..f2de3c8 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -140,6 +140,33 @@ static int profile_from_interface(const char *interface, enum profile *p) { return -1; } +static void profile_to_remote_uuid(enum profile p, const char *res[2]) { +pa_assert(p != PROFILE_OFF); + +switch(p) { +case PROFILE_A2DP: +res[0] = A2DP_SINK_UUID; +res[1] = NULL; +return; +case PROFILE_A2DP_SOURCE: +res[0] = A2DP_SOURCE_UUID; +res[1] = NULL; +return; +case PROFILE_HSP: +res[0] = HSP_HS_UUID; +res[1] = HFP_HS_UUID; +return; +case PROFILE_HFGW: +res[0] = HSP_AG_UUID; +res[1] = HFP_AG_UUID; +return; +case PROFILE_OFF: +break; +} + +pa_assert_not_reached(); +} + static pa_bluetooth_transport_state_t audio_state_to_transport_state(pa_bt_audio_state_t state) { switch (state) { case PA_BT_AUDIO_STATE_INVALID: /* Typically if state hasn't been received yet */ @@ -1526,6 +1553,7 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage DBusMessageIter args, props; DBusMessage *r; bool old_any_connected; +const char *remote_uuid[2]; if (!dbus_message_iter_init(m, args) || !pa_streq(dbus_message_get_signature(m), oa{sv})) { pa_log(Invalid signature for method SetConfiguration); @@ -1588,6 +1616,10 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage dbus_message_iter_next(props); } +/* FIXME: with BlueZ 5, check if this is racy in case a newly paired + * device gets connected very fast, before BlueZ has created it. This is + * very unlikely since the device will be created before the pairing + * procedure is complete */ d = found_device(y, dev_path); if (!d) goto fail; @@ -1601,6 +1633,27 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage else p = PROFILE_A2DP_SOURCE; +/* Check if the UUID was already reported by BlueZ, since the telephony + * component (oFono) could be faster than BlueZ */ +profile_to_remote_uuid(p, remote_uuid); + +if (!pa_bluetooth_uuid_has(d-uuids, remote_uuid[0]) !pa_bluetooth_uuid_has(d-uuids, remote_uuid[1])) { +pa_bluetooth_uuid *node; +struct pa_bluetooth_hook_uuid_data uuiddata; + +pa_log_info(Endpoint with UUID '%s' configured before remote UUID was reported by BlueZ., uuid); + +/* This might generate duplicated UUID_ADDED hooks since the endpoint + * doesn't receive the exact remote UUID (HSP cannot be distinguished + * from HFP). However, these duplicated hooks should do no harm */ +node = uuid_new(remote_uuid[0]); +PA_LLIST_PREPEND(pa_bluetooth_uuid, d-uuids, node); + +uuiddata.device = d; +uuiddata.uuid = uuid; + pa_hook_fire(d-discovery-hooks[PA_BLUETOOTH_HOOK_DEVICE_UUID_ADDED], uuiddata); +} + if (d-transports[p] != NULL) { pa_log(Cannot configure transport %s because profile %d is already used, path, p); goto fail2; -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss -- João Paulo Rechi Vita http://about.me/jprvita ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [RFCv2 01/17] bluetooth: Track org.ofono service
Hi João Paulo, On Mon, Apr 15, 2013 at 11:53 PM, jprv...@gmail.com wrote: From: João Paulo Rechi Vita jprv...@openbossa.org --- src/modules/bluetooth/bluetooth-util.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 01bdc3e..260c24e 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1325,7 +1325,18 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us } } +if (pa_streq(name, org.ofono)) { +if (old_owner *old_owner) { +pa_log_debug(oFono disappeared); +} No braces needed. + +if (new_owner *new_owner) { +pa_log_debug(oFono appeared); +} Same here. +} + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + Unrelated line added. } else if (dbus_message_is_signal(m, org.bluez.MediaTransport, PropertyChanged)) { pa_bluetooth_transport *t; DBusMessageIter arg_i; @@ -2170,6 +2181,8 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { ,arg0='org.bluez.Device1', type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' ,arg0='org.bluez.MediaTransport1', + type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged', +arg0='org.ofono', NULL) 0) { pa_log(Failed to add D-Bus matches: %s, err.message); goto fail; @@ -2245,6 +2258,8 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) { type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', + type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged', +arg0='org.ofono', As a general comment beyond this specific patch, as already discussed, it'd be good that we have the backends in place before mixing all this. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [RFCv2 13/17] bluetooth: Only call *Acquire() if using BlueZ' Media API
Hi João Paulo, On Mon, Apr 15, 2013 at 11:53 PM, jprv...@gmail.com wrote: From: João Paulo Rechi Vita jprv...@openbossa.org When the transport backend is oFono the stream file descriptor is passed through the NewConnection() method call. Additionally, set the kernel default SCO MTU value for block size (since this information is not available) and the transport codec, which also comes in the NewConnection() method call. --- src/modules/bluetooth/bluetooth-util.c | 20 1 file changed, 20 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index ae98029..d72137b 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1854,6 +1854,26 @@ int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, siz } else { pa_assert(t-device-discovery-version == BLUEZ_VERSION_5); +if (t-profile == PROFILE_HFGW) { +struct handsfree_card *hf_card = pa_hashmap_get(t-device-discovery-hf_cards, t-path); + +/* The correct block size should take into account the SCO MTU from + * the Bluetooth adapter and (for adapters in the USB bus) the MxPS + * value from the Isoc USB endpoint in use by btusb and should be + * made available to userspace by the Bluetooth kernel subsystem. + * The empiric value will be used meanwhile. */ Why not take the MTU from the socket options? +if (imtu) +*imtu = 48; +if (omtu) +*omtu = 48; + +if (hf_card) { +t-codec = hf_card-codec; +return hf_card-fd; As already mentioned before, this is not enough. You're handling the optional case only, while PA also relies on triggering an SCO connection actively and blocking until we get the fd. Considering this seems quite tricky with the current oFono API, I'd suggest it gets changed for the convenience of PA and other similar clients. Perhaps I'm missing some D-Bus magic to achieve this though. +} else +return -1; +} + method = optional ? TryAcquire : Acquire; pa_assert_se(m = dbus_message_new_method_call(t-owner, t-path, org.bluez.MediaTransport1, method)); } -- Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [RFCv2 17/17] bluetooth: Postpone sink and source creation for BlueZ 5 HFP
Hi João Paulo, On Wed, Apr 17, 2013 at 9:20 PM, João Paulo Rechi Vita jprv...@openbossa.org wrote: On Mon, Apr 15, 2013 at 6:53 PM, jprv...@gmail.com wrote: From: João Paulo Rechi Vita jprv...@openbossa.org CVSD and mSBC stream have different sample rates, and the CODEC of the Audio Connection is only on NewConnection(). Since the sample rate is needed to create the sink/source their creation is postponed to when the transport changes its state to 'playing'. Ideally instead of postponing the sink/source creation what I want here is to update their sample rate, otherwise I can't support (1) subsequent calls with different sample rates and (2) HF-initiated call transfer from the HF to the AG. For (1) a workaround would be destroying the sink after the call ends (HUP on stream fd) but I couldn't think of anything to cover (2). As you already point out, postponing the creation seems a bad idea since the current approach relies on their existence to for example resume them automatically (connect SCO) when some audio gets streamed (e.g. point (2) above). This seems now more tricky with HFP 1.6 so we might have to reconsider this assumption if there's no other alternative. I've played a bit with pa_sink_update_rate() but I always got a message complaining that the attached monitor source was not idle, even when the sink was idle. Can someone give me any help on that? I'm not familiar with _update_rate but basically what you need is to be able to change the sample rate of a *suspended* sink/source. This sounds like a feature that the core should provide, regardless of the state of the monitor. Cheers, Mikel --- src/modules/bluetooth/module-bluetooth-device.c | 21 +++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 22880c6..1f5bcbc 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -1579,6 +1579,11 @@ static pa_available_t get_port_availability(struct userdata *u, pa_direction_t d return result; } +static void bt_transport_config(struct userdata *u); +static int add_source(struct userdata *u); +static int add_sink(struct userdata *u); +static int start_thread(struct userdata *u); + /* Run from main thread */ static void handle_transport_state_change(struct userdata *u, struct pa_bluetooth_transport *transport) { bool acquire = false; @@ -1613,6 +1618,18 @@ static void handle_transport_state_change(struct userdata *u, struct pa_bluetoot if (acquire) if (bt_transport_acquire(u, true) = 0) { + +/* Create sink and source with the correct sample rate for PROFILE_HFGW BLUEZ5 */ +if ((pa_bluetooth_discovery_get_bluez_version(u-discovery) == BLUEZ_VERSION_5) profile == PROFILE_HFGW +(!u-sink || !u-source)) { + +bt_transport_config(u); +add_sink(u); +add_source(u); +if (u-sink || u-source) +start_thread(u); +} + if (u-source) { pa_log_debug(Resuming source %s, because the bluetooth audio state changed to 'playing'., u-source-name); pa_source_suspend(u-source, false, PA_SUSPEND_IDLE|PA_SUSPEND_USER); @@ -2194,13 +2211,13 @@ static int init_profile(struct userdata *u) { if (u-profile == PROFILE_A2DP || u-profile == PROFILE_HSP || -u-profile == PROFILE_HFGW) +(u-profile == PROFILE_HFGW pa_bluetooth_discovery_get_bluez_version(u-discovery) == BLUEZ_VERSION_4)) if (add_sink(u) 0) r = -1; if (u-profile == PROFILE_HSP || u-profile == PROFILE_A2DP_SOURCE || -u-profile == PROFILE_HFGW) +(u-profile == PROFILE_HFGW pa_bluetooth_discovery_get_bluez_version(u-discovery) == BLUEZ_VERSION_4)) if (add_source(u) 0) r = -1; -- 1.7.11.7 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] [RFCv2 13/17] bluetooth: Only call *Acquire() if using BlueZ' Media API
Hi João Paulo, On Thu, Apr 18, 2013 at 4:04 PM, João Paulo Rechi Vita jprv...@openbossa.org wrote: On Thu, Apr 18, 2013 at 10:43 AM, Mikel Astiz mikel.astiz@gmail.com wrote: Hi João Paulo, On Mon, Apr 15, 2013 at 11:53 PM, jprv...@gmail.com wrote: From: João Paulo Rechi Vita jprv...@openbossa.org When the transport backend is oFono the stream file descriptor is passed through the NewConnection() method call. Additionally, set the kernel default SCO MTU value for block size (since this information is not available) and the transport codec, which also comes in the NewConnection() method call. --- src/modules/bluetooth/bluetooth-util.c | 20 1 file changed, 20 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index ae98029..d72137b 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1854,6 +1854,26 @@ int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, siz } else { pa_assert(t-device-discovery-version == BLUEZ_VERSION_5); +if (t-profile == PROFILE_HFGW) { +struct handsfree_card *hf_card = pa_hashmap_get(t-device-discovery-hf_cards, t-path); + +/* The correct block size should take into account the SCO MTU from + * the Bluetooth adapter and (for adapters in the USB bus) the MxPS + * value from the Isoc USB endpoint in use by btusb and should be + * made available to userspace by the Bluetooth kernel subsystem. + * The empiric value will be used meanwhile. */ Why not take the MTU from the socket options? The MTU informed through the SCO socket option informs the adapter MTU, it doesn't take the USB endpoint MxPS into consideration. So if we use that value the USB endpoint gets flooded (I imagine) and resets the Bluetooth adapter. Vinicius is investigating this issue, but hardcoding this value to 48 is the best we can do so far :( You're right that it doesn't take the MxPS into consideration but neither does the hardcoded 48. My experience is that 96 works better than 48, for example, specially when 2 SCO streams exist. +if (imtu) +*imtu = 48; +if (omtu) +*omtu = 48; + +if (hf_card) { +t-codec = hf_card-codec; +return hf_card-fd; As already mentioned before, this is not enough. You're handling the optional case only, while PA also relies on triggering an SCO connection actively and blocking until we get the fd. Yes, I left this use case to be handled later on and I'm working on it That's fine but we should definitely address this issue before merging this patchset. right now, to see what we can do. How are you doing to trigger this? I'm trying with module-sine, setting the bluetooth sink as the fallback one, but this doesn't seem to trigger a sink resume. You can use pacmd and commands like suspend-source/sink. The reason is that within this role (role HF, PA-card-profile hfgw), the suspend is considered user-driven (PA_SUSPEND_USER), and won't automatically resume. Cheers, Mikel ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC v2 00/15] bluetooth: BlueZ 5 development patches
From: Mikel Astiz mikel.as...@bmw-carit.de I resubmit this patchset as-is after updating it according to the latest upstream changes. The patchset has been hanging around for a while and several efforts exist that depend on this series, so it seems we should merge this despite the existing discussions about how different backends (BlueZ 4, BlueZ 5, oFono, etc.) should be supported inside PulseAudio (next big patchset in the pipeline). The last patch makes less sense right now (given that the Media API will not be used for HSP/HFP) but I'm sending the whole series for the sake of completeness. Mikel Astiz (14): bluetooth: Detect BlueZ 5 bluetooth: Parse the tree returned by ObjectManager bluetooth: Support ObjectManager interface add/remove bluetooth: Support Properties.PropertiesChanged signal bluetooth: Handle transports configured before UUID received bluetooth: BlueZ 5 interface rename to org.bluez.MediaEndpoint1 bluetooth: BlueZ 5 interface rename to org.bluez.Media1 bluetooth: BlueZ 5 interface rename to org.bluez.MediaTransport1 bluetooth: Parse media transport's properties bluetooth: Support media transport's State property bluetooth: Update to new BlueZ 5 transport acquire/release API bluetooth: Support transport auto-release bluetooth: Update to new property setter API in BlueZ 5 bluetooth: Update to volume control in BlueZ 5 Vinicius Costa Gomes (1): bluetooth: Add HFP 1.6 codec ID src/modules/bluetooth/bluetooth-util.c | 573 ++-- src/modules/bluetooth/module-bluetooth-device.c | 8 +- 2 files changed, 526 insertions(+), 55 deletions(-) -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC v2 02/15] bluetooth: Parse the tree returned by ObjectManager
From: Mikel Astiz mikel.as...@bmw-carit.de Parse the result of ObjectManager.GetManagedObjects(), which includes all objects registered, their interfaces and the corresponding properties per interface. --- src/modules/bluetooth/bluetooth-util.c | 120 +++-- 1 file changed, 114 insertions(+), 6 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 1883c8a..ebdb684 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -362,8 +362,6 @@ static int parse_device_property(pa_bluetooth_device *d, DBusMessageIter *i, boo dbus_message_iter_recurse(i, variant_i); -/* pa_log_debug(Parsing property org.bluez.Device.%s, key); */ - switch (dbus_message_iter_get_arg_type(variant_i)) { case DBUS_TYPE_STRING: { @@ -452,6 +450,11 @@ static int parse_device_property(pa_bluetooth_device *d, DBusMessageIter *i, boo uuiddata.uuid = value; pa_hook_fire(d-discovery-hooks[PA_BLUETOOTH_HOOK_DEVICE_UUID_ADDED], uuiddata); +if (d-discovery-version = BLUEZ_VERSION_5) { +dbus_message_iter_next(ai); +continue; +} + /* Vudentz said the interfaces are here when the UUIDs are announced */ if (strcasecmp(HSP_AG_UUID, value) == 0 || strcasecmp(HFP_AG_UUID, value) == 0) { pa_assert_se(m = dbus_message_new_method_call(org.bluez, d-path, org.bluez.HandsfreeGateway, @@ -867,16 +870,20 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const send_and_add_to_pending(y, m, register_endpoint_reply, pa_xstrdup(endpoint)); } +static void register_adapter_endpoints(pa_bluetooth_discovery *y, const char *path) { +register_endpoint(y, path, HFP_AG_ENDPOINT, HFP_AG_UUID); +register_endpoint(y, path, HFP_HS_ENDPOINT, HFP_HS_UUID); +register_endpoint(y, path, A2DP_SOURCE_ENDPOINT, A2DP_SOURCE_UUID); +register_endpoint(y, path, A2DP_SINK_ENDPOINT, A2DP_SINK_UUID); +} + static void found_adapter(pa_bluetooth_discovery *y, const char *path) { DBusMessage *m; pa_assert_se(m = dbus_message_new_method_call(org.bluez, path, org.bluez.Adapter, GetProperties)); send_and_add_to_pending(y, m, get_properties_reply, NULL); -register_endpoint(y, path, HFP_AG_ENDPOINT, HFP_AG_UUID); -register_endpoint(y, path, HFP_HS_ENDPOINT, HFP_HS_UUID); -register_endpoint(y, path, A2DP_SOURCE_ENDPOINT, A2DP_SOURCE_UUID); -register_endpoint(y, path, A2DP_SINK_ENDPOINT, A2DP_SINK_UUID); +register_adapter_endpoints(y, path); } static void list_adapters(pa_bluetooth_discovery *y) { @@ -887,10 +894,94 @@ static void list_adapters(pa_bluetooth_discovery *y) { send_and_add_to_pending(y, m, get_properties_reply, NULL); } +static int parse_device_properties(pa_bluetooth_device *d, DBusMessageIter *i, bool is_property_change) { +DBusMessageIter element_i; +int ret = 0; + +dbus_message_iter_recurse(i, element_i); + +while (dbus_message_iter_get_arg_type(element_i) == DBUS_TYPE_DICT_ENTRY) { +DBusMessageIter dict_i; + +dbus_message_iter_recurse(element_i, dict_i); + +if (parse_device_property(d, dict_i, is_property_change)) +ret = -1; + +dbus_message_iter_next(element_i); +} + +if (!d-name || !d-address || !d-alias || d-paired 0 || d-trusted 0) { +pa_log_error(Non-optional information missing for device %s, d-path); +d-device_info_valid = -1; +return -1; +} + +d-device_info_valid = 1; +return ret; +} + +static int parse_interfaces_and_properties(pa_bluetooth_discovery *y, DBusMessageIter *dict_i) { +DBusMessageIter element_i; +const char *path; + +pa_assert(dbus_message_iter_get_arg_type(dict_i) == DBUS_TYPE_OBJECT_PATH); +dbus_message_iter_get_basic(dict_i, path); + +pa_assert_se(dbus_message_iter_next(dict_i)); +pa_assert(dbus_message_iter_get_arg_type(dict_i) == DBUS_TYPE_ARRAY); + +dbus_message_iter_recurse(dict_i, element_i); + +while (dbus_message_iter_get_arg_type(element_i) == DBUS_TYPE_DICT_ENTRY) { +DBusMessageIter iface_i; +const char *interface; + +dbus_message_iter_recurse(element_i, iface_i); + +pa_assert(dbus_message_iter_get_arg_type(iface_i) == DBUS_TYPE_STRING); +dbus_message_iter_get_basic(iface_i, interface); + +pa_assert_se(dbus_message_iter_next(iface_i)); +pa_assert(dbus_message_iter_get_arg_type(iface_i) == DBUS_TYPE_ARRAY); + +if (pa_streq(interface, org.bluez.Adapter1)) { +pa_log_debug(Adapter %s found, path); +register_adapter_endpoints(y, path); +} else if (pa_streq(interface, org.bluez.Device1)) { +pa_bluetooth_device *d
[pulseaudio-discuss] [RFC v2 03/15] bluetooth: Support ObjectManager interface add/remove
From: Mikel Astiz mikel.as...@bmw-carit.de Install matches for signals ObjectManager.InterfacesAdded and ObjectManager.InterfacesRemoved, and process the devices that are registered and unregistered dynamically. --- src/modules/bluetooth/bluetooth-util.c | 58 ++ 1 file changed, 58 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index ebdb684..acf704a 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1204,6 +1204,60 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us goto fail; return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} else if (dbus_message_is_signal(m, org.freedesktop.DBus.ObjectManager, InterfacesAdded)) { +DBusMessageIter arg_i; + +if (y-version != BLUEZ_VERSION_5) +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */ + +if (!dbus_message_iter_init(m, arg_i) || !pa_streq(dbus_message_get_signature(m), oa{sa{sv}})) { +pa_log(Invalid signature found in InterfacesAdded); +goto fail; +} + +if (parse_interfaces_and_properties(y, arg_i) 0) +goto fail; + +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} else if (dbus_message_is_signal(m, org.freedesktop.DBus.ObjectManager, InterfacesRemoved)) { +const char *path; +DBusMessageIter arg_i; +DBusMessageIter element_i; + +if (y-version != BLUEZ_VERSION_5) +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */ + +if (!dbus_message_iter_init(m, arg_i) || !pa_streq(dbus_message_get_signature(m), oas)) { +pa_log(Invalid signature found in InterfacesRemoved); +goto fail; +} + +dbus_message_iter_get_basic(arg_i, path); + +pa_assert_se(dbus_message_iter_next(arg_i)); +pa_assert(dbus_message_iter_get_arg_type(arg_i) == DBUS_TYPE_ARRAY); + +dbus_message_iter_recurse(arg_i, element_i); + +while (dbus_message_iter_get_arg_type(element_i) == DBUS_TYPE_STRING) { +const char *interface; + +dbus_message_iter_get_basic(element_i, interface); + +if (pa_streq(interface, org.bluez.Device1)) { +pa_bluetooth_device *d; + +if ((d = pa_hashmap_remove(y-devices, path))) { +pa_log_debug(Device %s removed, d-path); +run_callback(d, true); +device_free(d); +} +} + +dbus_message_iter_next(element_i); +} + +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } fail: @@ -1856,6 +1910,8 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', NULL) 0) { pa_log(Failed to add D-Bus matches: %s, err.message); goto fail; @@ -1929,6 +1985,8 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) { type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', NULL); if (y-filter_added) -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [RFC v2 04/15] bluetooth: Support Properties.PropertiesChanged signal
From: Mikel Astiz mikel.as...@bmw-carit.de Install matches for signal Properties.PropertiesChanged and process the properties corresponding to the tracked devices. --- src/modules/bluetooth/bluetooth-util.c | 29 + 1 file changed, 29 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index acf704a..e7dea39 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1258,6 +1258,33 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} else if (dbus_message_is_signal(m, org.freedesktop.DBus.Properties, PropertiesChanged)) { +DBusMessageIter arg_i; +const char *interface; + +if (y-version != BLUEZ_VERSION_5) +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */ + +if (!dbus_message_iter_init(m, arg_i) || !pa_streq(dbus_message_get_signature(m), sa{sv}as)) { +pa_log(Invalid signature found in PropertiesChanged); +goto fail; +} + +dbus_message_iter_get_basic(arg_i, interface); + +pa_assert_se(dbus_message_iter_next(arg_i)); +pa_assert(dbus_message_iter_get_arg_type(arg_i) == DBUS_TYPE_ARRAY); + +if (pa_streq(interface, org.bluez.Device1)) { +pa_bluetooth_device *d; + +if (!(d = pa_hashmap_get(y-devices, dbus_message_get_path(m +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* Device not being tracked */ + +parse_device_properties(d, arg_i, true); +} + +return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } fail: @@ -1912,6 +1939,8 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded', type='signal',sender='org.bluez',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved', + type='signal',sender='org.bluez',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' +,arg0='org.bluez.Device1', NULL) 0) { pa_log(Failed to add D-Bus matches: %s, err.message); goto fail; -- 1.8.1.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss