2013-05-07 23:47:23

by Alex Deymo

[permalink] [raw]
Subject: Audio sink stream remains suspended on reconnection

Hello!
I'm trying to debug a problem we have while playing audio on a Monster
ClarityHD. I can reproduce the following problem several times,
although not always. The procedures is the following:
1. Power on and put the Monster ClarityHD bluetooth speaker in discovery mode.
2. Using bluetoothctl: scan, pair, trust and connect the device.
3. Play some music and keep it playing. The music plays on the
bluetooth speakers.
4. Power off the bluetooth speakers. The device then shows as
disconnected shortly after.
5. Power on the bluetooth speakers again and attempt a "connect" from
the bluetoothctl.

Then the music play for a second or two back in the bluetooth speakers
and stops playing. I can see the audio traffic still going with btmon
even when the music is not getting out of the bluetooth speakers. The
music start and stop in the bluetooth speakers corresponds with the
START_CMD and SUSPEND events in the log bellow. The blank lines
represent a gap in time of 1 or 2 seconds.

Does anyone have any idea on what's going on?
It looks to me like the "SUSPEND request succeeded" of a previous
SUSPEND_CMD arrives just after "Received START_CMD" and the device
remains suspended, but I have no idea how to fix that =/

Thanks,
Alex.

bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_connect_cb() AVDTP:
connected transport channel to 10:B7:F6:01:31:ED
bluetoothd[21017]: profiles/audio/avdtp.c:handle_transport_connect()
Flushable packets enabled
bluetoothd[21017]: profiles/audio/avdtp.c:handle_transport_connect()
sk 20, omtu 895, send buffer size 106496
bluetoothd[21017]: profiles/audio/a2dp.c:open_cfm() Source
0x7f2acd437a00: Open_Cfm
bluetoothd[21017]: profiles/audio/sink.c:stream_setup_complete()
Stream successfully created
bluetoothd[21017]: src/device.c:device_profile_connected() audio-sink
Success (0)
bluetoothd[21017]: src/device.c:device_profile_connected() returning
response to :1.1473
bluetoothd[21017]: profiles/audio/a2dp.c:setup_unref() 0x7f2acd43e3b0: ref=1
bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_sep_set_state() stream
state changed: CONFIGURED -> OPEN
bluetoothd[21017]: profiles/audio/sink.c:sink_set_state() State
changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED: SINK_STATE_CONNECTING
-> SINK_STATE_CONNECTED
bluetoothd[21017]:
profiles/audio/transport.c:transport_update_playing()
/org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3
State=TRANSPORT_STATE_REQUESTING Playing=0
bluetoothd[21017]: profiles/audio/avdtp.c:session_cb()
bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_parse_resp() START
request succeeded
bluetoothd[21017]: profiles/audio/a2dp.c:start_cfm() Source
0x7f2acd437a00: Start_Cfm
bluetoothd[21017]: /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3: fd(20) ready
bluetoothd[21017]: profiles/audio/transport.c:media_owner_remove()
Owner :1.1198 Request Acquire
bluetoothd[21017]: profiles/audio/transport.c:transport_set_state()
State changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3:
TRANSPORT_STATE_REQUESTING -> TRANSPORT_STATE_ACTIVE
bluetoothd[21017]: profiles/audio/a2dp.c:setup_unref() 0x7f2acd43e3b0: ref=0
bluetoothd[21017]: profiles/audio/a2dp.c:setup_free() 0x7f2acd43e3b0
bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_unref() 0x7f2acd43ce70: ref=2
bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_sep_set_state() stream
state changed: OPEN -> STREAMING
bluetoothd[21017]: profiles/audio/sink.c:sink_set_state() State
changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED: SINK_STATE_CONNECTED ->
SINK_STATE_PLAYING
bluetoothd[21017]:
profiles/audio/transport.c:transport_update_playing()
/org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3 State=TRANSPORT_STATE_ACTIVE
Playing=1


bluetoothd[21017]: profiles/audio/avdtp.c:session_cb()
bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_parse_cmd() Received SUSPEND_CMD
bluetoothd[21017]: profiles/audio/a2dp.c:suspend_ind() Source
0x7f2acd437a00: Suspend_Ind
bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_sep_set_state() stream
state changed: STREAMING -> OPEN
bluetoothd[21017]: profiles/audio/sink.c:sink_set_state() State
changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED: SINK_STATE_PLAYING ->
SINK_STATE_CONNECTED
bluetoothd[21017]:
profiles/audio/transport.c:transport_update_playing()
/org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3 State=TRANSPORT_STATE_ACTIVE
Playing=0
bluetoothd[21017]:
profiles/audio/transport.c:media_transport_remove_owner() Transport
/org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3 Owner :1.1198
bluetoothd[21017]: profiles/audio/transport.c:media_owner_free() Owner :1.1198
bluetoothd[21017]: profiles/audio/transport.c:transport_set_state()
State changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3:
TRANSPORT_STATE_ACTIVE -> TRANSPORT_STATE_IDLE
bluetoothd[21017]: profiles/audio/a2dp.c:a2dp_sep_unlock() SEP
0x7f2acd437a00 unlocked


bluetoothd[21017]: profiles/audio/avdtp.c:session_cb()
bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_parse_cmd() Received START_CMD
bluetoothd[21017]: profiles/audio/a2dp.c:start_ind() Source
0x7f2acd437a00: Start_Ind
bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_ref() 0x7f2acd43ce70: ref=3
bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_sep_set_state() stream
state changed: OPEN -> STREAMING
bluetoothd[21017]: profiles/audio/sink.c:sink_set_state() State
changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED: SINK_STATE_CONNECTED ->
SINK_STATE_PLAYING
bluetoothd[21017]:
profiles/audio/transport.c:transport_update_playing()
/org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3 State=TRANSPORT_STATE_IDLE
Playing=1
bluetoothd[21017]: profiles/audio/transport.c:transport_set_state()
State changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3:
TRANSPORT_STATE_IDLE -> TRANSPORT_STATE_PENDING
bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_unref() 0x7f2acd43ce70: ref=2


bluetoothd[21017]: profiles/audio/avdtp.c:session_cb()
bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_parse_resp() SUSPEND
request succeeded
bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_sep_set_state() stream
state changed: STREAMING -> OPEN
bluetoothd[21017]: profiles/audio/sink.c:sink_set_state() State
changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED: SINK_STATE_PLAYING ->
SINK_STATE_CONNECTED
bluetoothd[21017]:
profiles/audio/transport.c:transport_update_playing()
/org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3
State=TRANSPORT_STATE_PENDING Playing=0
bluetoothd[21017]: profiles/audio/transport.c:transport_set_state()
State changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3:
TRANSPORT_STATE_PENDING -> TRANSPORT_STATE_IDLE
bluetoothd[21017]: profiles/audio/a2dp.c:suspend_cfm() Source
0x7f2acd437a00: Suspend_Cfm


2013-05-15 16:25:54

by Scott James Remnant

[permalink] [raw]
Subject: Re: Audio sink stream remains suspended on reconnection

On Wed, May 15, 2013 at 9:00 AM, Luiz Augusto von Dentz
<[email protected]> wrote:
> Hi Scott,
>
> On Wed, May 15, 2013 at 6:33 PM, Scott James Remnant
> <[email protected]> wrote:
>> It's still not fully clear to me how the state could be handled. For
>> example, the following:
>>
>> We only acquire the transport stream when we have actual sound to be
>> played, and once we've finished playback we release the transport
>> stream again. In most circumstances this seems correct, and matches
>> what we see on other platforms - with a suspend being sent to the
>> device, and a start being sent when we have more sound to play.
>>
>> What I can't figure out is what we're supposed to do in the case where
>> the device sends the start (state goes to pending) when we _don't_
>> have any sound to play.
>>
>> Are we still expected to acquire the transport stream? What happens if we don't?
>
> No top posting, please.
>

I wasn't replying to anything particular in your message

> The headset controlling the A2DP stream like this is normally a bad
> behavior/implementation, it should be using AVRCP Play/Pause, but
> anyway it is possible that the headset takes over the control in fact
> I remember someone trying to use those commands to do some kind of
> audio transfer like in HFP.
>
> Anyway the answer for your question about pending state is probably
> don't Acquire if you wont gonna use it, the start will fail and the
> stream will stay suspended, you could also attempt to assume control
> and Acquire the stream but if this is to work like audio transfer the
> headset wants to override the routing so the speakers are used
> instead.

The device appears to sulk and drop the ACL entirely :-/

2013-05-15 16:00:27

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: Audio sink stream remains suspended on reconnection

Hi Scott,

On Wed, May 15, 2013 at 6:33 PM, Scott James Remnant
<[email protected]> wrote:
> It's still not fully clear to me how the state could be handled. For
> example, the following:
>
> We only acquire the transport stream when we have actual sound to be
> played, and once we've finished playback we release the transport
> stream again. In most circumstances this seems correct, and matches
> what we see on other platforms - with a suspend being sent to the
> device, and a start being sent when we have more sound to play.
>
> What I can't figure out is what we're supposed to do in the case where
> the device sends the start (state goes to pending) when we _don't_
> have any sound to play.
>
> Are we still expected to acquire the transport stream? What happens if we don't?

No top posting, please.

The headset controlling the A2DP stream like this is normally a bad
behavior/implementation, it should be using AVRCP Play/Pause, but
anyway it is possible that the headset takes over the control in fact
I remember someone trying to use those commands to do some kind of
audio transfer like in HFP.

Anyway the answer for your question about pending state is probably
don't Acquire if you wont gonna use it, the start will fail and the
stream will stay suspended, you could also attempt to assume control
and Acquire the stream but if this is to work like audio transfer the
headset wants to override the routing so the speakers are used
instead.

2013-05-15 15:33:45

by Scott James Remnant

[permalink] [raw]
Subject: Re: Audio sink stream remains suspended on reconnection

It's still not fully clear to me how the state could be handled. For
example, the following:

We only acquire the transport stream when we have actual sound to be
played, and once we've finished playback we release the transport
stream again. In most circumstances this seems correct, and matches
what we see on other platforms - with a suspend being sent to the
device, and a start being sent when we have more sound to play.

What I can't figure out is what we're supposed to do in the case where
the device sends the start (state goes to pending) when we _don't_
have any sound to play.

Are we still expected to acquire the transport stream? What happens if we don't?

Scott

On Mon, May 13, 2013 at 10:04 AM, Luiz Augusto von Dentz
<[email protected]> wrote:
> Hi Alex,
>
> On Sat, May 11, 2013 at 4:51 AM, Alex Deymo <[email protected]> wrote:
>> Hi Luiz,
>>
>> On Fri, May 10, 2013 at 1:09 AM, Luiz Augusto von Dentz
>> <[email protected]> wrote:
>>> Yes, you should release the fd once the state change to idle, in the
>>> future we might actually use frevoke (http://lwn.net/Articles/192632/)
>>> to revoke the permissions but for now we have to assume the endpoint
>>> will behave and close whenever the transport became idle. You are also
>>> right, we should probably update the documentation to state the fd is
>>> considered revoked in this case and the endpoint has to acquired
>>> again. Btw PulseAudio does that already so Im curious why you are not
>>> using PA, or is this for another Audio daemon?
>>
>> Oh, thank you very much for that information. I would never guessed
>> that was the problem!
>> Having the documentation clear and updated is good not only because
>> not everyone uses PA, but also because definitively we don't want to
>> use PA for testing (we may want to fake and control the interaction
>> with the audio server to run a test). Actually, as Scott mentioned we
>> are not using PA on Chromium/ChromiumOS laptops, we are using CRAS
>> (ChromeOS Audio Server) which is basically the minimum we need to have
>> low latency dynamic audio routing with a low CPU impact... and that's
>> basically the "why". If you are curious, you can find the original
>> design doc here [1], the code is opensource and here [2] and actually
>> also works on ubuntu [3], but need applications (like chrome) that
>> know how to talk with cras.
>
> If you fill that you can put some effort in improving the
> documentation patches are welcome, I hope now it is clear how the
> state should handled, you can still overwrite and request to resume by
> doing Acquire but the remote stack may refuse to do so, it is actually
> recommended that whoever suspend should resume.
>
> Regarding PulseAudio, it is a bit frustrating to see very little
> effort for adapting PA for whatever you guys need and btw Arun did
> ported PA to Android and compared it with AudioFlinger:
>
> http://arunraghavan.net/2012/01/pulseaudio-vs-audioflinger-fight/
>
> It doesn't look like PA is power hog, it can get low latency as well,
> anyway it is probably not a good idea to talk about this in
> linux-bluetooth, there are very competent guys in PA mailing list to
> discuss about this.

2013-05-13 17:04:31

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: Audio sink stream remains suspended on reconnection

Hi Alex,

On Sat, May 11, 2013 at 4:51 AM, Alex Deymo <[email protected]> wrote:
> Hi Luiz,
>
> On Fri, May 10, 2013 at 1:09 AM, Luiz Augusto von Dentz
> <[email protected]> wrote:
>> Yes, you should release the fd once the state change to idle, in the
>> future we might actually use frevoke (http://lwn.net/Articles/192632/)
>> to revoke the permissions but for now we have to assume the endpoint
>> will behave and close whenever the transport became idle. You are also
>> right, we should probably update the documentation to state the fd is
>> considered revoked in this case and the endpoint has to acquired
>> again. Btw PulseAudio does that already so Im curious why you are not
>> using PA, or is this for another Audio daemon?
>
> Oh, thank you very much for that information. I would never guessed
> that was the problem!
> Having the documentation clear and updated is good not only because
> not everyone uses PA, but also because definitively we don't want to
> use PA for testing (we may want to fake and control the interaction
> with the audio server to run a test). Actually, as Scott mentioned we
> are not using PA on Chromium/ChromiumOS laptops, we are using CRAS
> (ChromeOS Audio Server) which is basically the minimum we need to have
> low latency dynamic audio routing with a low CPU impact... and that's
> basically the "why". If you are curious, you can find the original
> design doc here [1], the code is opensource and here [2] and actually
> also works on ubuntu [3], but need applications (like chrome) that
> know how to talk with cras.

If you fill that you can put some effort in improving the
documentation patches are welcome, I hope now it is clear how the
state should handled, you can still overwrite and request to resume by
doing Acquire but the remote stack may refuse to do so, it is actually
recommended that whoever suspend should resume.

Regarding PulseAudio, it is a bit frustrating to see very little
effort for adapting PA for whatever you guys need and btw Arun did
ported PA to Android and compared it with AudioFlinger:

http://arunraghavan.net/2012/01/pulseaudio-vs-audioflinger-fight/

It doesn't look like PA is power hog, it can get low latency as well,
anyway it is probably not a good idea to talk about this in
linux-bluetooth, there are very competent guys in PA mailing list to
discuss about this.

2013-05-11 01:51:20

by Alex Deymo

[permalink] [raw]
Subject: Re: Audio sink stream remains suspended on reconnection

Hi Luiz,

On Fri, May 10, 2013 at 1:09 AM, Luiz Augusto von Dentz
<[email protected]> wrote:
> Yes, you should release the fd once the state change to idle, in the
> future we might actually use frevoke (http://lwn.net/Articles/192632/)
> to revoke the permissions but for now we have to assume the endpoint
> will behave and close whenever the transport became idle. You are also
> right, we should probably update the documentation to state the fd is
> considered revoked in this case and the endpoint has to acquired
> again. Btw PulseAudio does that already so Im curious why you are not
> using PA, or is this for another Audio daemon?

Oh, thank you very much for that information. I would never guessed
that was the problem!
Having the documentation clear and updated is good not only because
not everyone uses PA, but also because definitively we don't want to
use PA for testing (we may want to fake and control the interaction
with the audio server to run a test). Actually, as Scott mentioned we
are not using PA on Chromium/ChromiumOS laptops, we are using CRAS
(ChromeOS Audio Server) which is basically the minimum we need to have
low latency dynamic audio routing with a low CPU impact... and that's
basically the "why". If you are curious, you can find the original
design doc here [1], the code is opensource and here [2] and actually
also works on ubuntu [3], but need applications (like chrome) that
know how to talk with cras.

Again, thanks for the help.
Alex.

[1] http://www.chromium.org/chromium-os/chromiumos-design-docs/cras-chromeos-audio-server
[2] http://git.chromium.org/gitweb/?p=chromiumos/third_party/adhd.git;a=summary
[3] http://www.chromium.org/chromium-os/how-tos-and-troubleshooting/chrome-with-libcras-on-gprecise

2013-05-10 21:48:31

by Scott James Remnant

[permalink] [raw]
Subject: Re: Audio sink stream remains suspended on reconnection

We don't use PA in Chrome OS, we have our own Audio Daemon.

I couldn't find any documentation on the Media API other than the
actual D-Bus interface docs when I wrote the code so pretty much
hacked it until it worked :)

Could you clarify for me at which points we should Acquire and which
points we should Release the transport? Reading this and the PA code I
would assume:

- we should only acquire when the state is "pending"

- we should release when the state is changed to "idle" if we still have it.

Is that about right?

Scott

On Fri, May 10, 2013 at 1:09 AM, Luiz Augusto von Dentz
<[email protected]> wrote:
> Hi Alex,
>
> On Thu, May 9, 2013 at 7:40 AM, Alex Deymo <[email protected]> wrote:
>> Hi Luiz,
>>
>> On Wed, May 8, 2013 at 7:25 AM, Luiz Augusto von Dentz
>> <[email protected]> wrote:
>>> Hi Alex,
>>>
>>> On Wed, May 8, 2013 at 2:47 AM, Alex Deymo <[email protected]> wrote:
>>>> bluetoothd[21017]: profiles/audio/avdtp.c:session_cb()
>>>> bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_parse_resp() SUSPEND
>>>> request succeeded
>>>> bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_sep_set_state() stream
>>>> state changed: STREAMING -> OPEN
>>>> bluetoothd[21017]: profiles/audio/sink.c:sink_set_state() State
>>>> changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED: SINK_STATE_PLAYING ->
>>>> SINK_STATE_CONNECTED
>>>> bluetoothd[21017]:
>>>> profiles/audio/transport.c:transport_update_playing()
>>>> /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3
>>>> State=TRANSPORT_STATE_PENDING Playing=0
>>>> bluetoothd[21017]: profiles/audio/transport.c:transport_set_state()
>>>> State changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3:
>>>> TRANSPORT_STATE_PENDING -> TRANSPORT_STATE_IDLE
>>>> bluetoothd[21017]: profiles/audio/a2dp.c:suspend_cfm() Source
>>>> 0x7f2acd437a00: Suspend_Cfm
>>>
>>> The endpoint probably didn't acquire the fd so we suspend the stream.
>>> Anyway the device is misbehaving if it is sending suspend and start
>>> commands like that (perhaps you are pressing play/pause buttons?) but
>>> if you don't wan't the stream to auto suspend you just need to Acquire
>>> when the transport is in pending state.
>>
>> I did call org.bluez.MediaTransport1.Acquire before all this and the
>> State went to active at that point and music was playing well. Then
>> with the SUSPEND_CMD I see the State property going from active to
>> idle and later from idle to pending (and later to suspend) If I
>> understand well from what you say... Should I call Acquire again on
>> the same /fd3 when I see the State going to pending?? Should I also
>> Release it before? (for example when I see the State going to idle?) I
>> don't see a clear answer from the doc/.
>
> Yes, you should release the fd once the state change to idle, in the
> future we might actually use frevoke (http://lwn.net/Articles/192632/)
> to revoke the permissions but for now we have to assume the endpoint
> will behave and close whenever the transport became idle. You are also
> right, we should probably update the documentation to state the fd is
> considered revoked in this case and the endpoint has to acquired
> again. Btw PulseAudio does that already so Im curious why you are not
> using PA, or is this for another Audio daemon?
>
>
> --
> Luiz Augusto von Dentz

2013-05-10 08:09:21

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: Audio sink stream remains suspended on reconnection

Hi Alex,

On Thu, May 9, 2013 at 7:40 AM, Alex Deymo <[email protected]> wrote:
> Hi Luiz,
>
> On Wed, May 8, 2013 at 7:25 AM, Luiz Augusto von Dentz
> <[email protected]> wrote:
>> Hi Alex,
>>
>> On Wed, May 8, 2013 at 2:47 AM, Alex Deymo <[email protected]> wrote:
>>> bluetoothd[21017]: profiles/audio/avdtp.c:session_cb()
>>> bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_parse_resp() SUSPEND
>>> request succeeded
>>> bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_sep_set_state() stream
>>> state changed: STREAMING -> OPEN
>>> bluetoothd[21017]: profiles/audio/sink.c:sink_set_state() State
>>> changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED: SINK_STATE_PLAYING ->
>>> SINK_STATE_CONNECTED
>>> bluetoothd[21017]:
>>> profiles/audio/transport.c:transport_update_playing()
>>> /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3
>>> State=TRANSPORT_STATE_PENDING Playing=0
>>> bluetoothd[21017]: profiles/audio/transport.c:transport_set_state()
>>> State changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3:
>>> TRANSPORT_STATE_PENDING -> TRANSPORT_STATE_IDLE
>>> bluetoothd[21017]: profiles/audio/a2dp.c:suspend_cfm() Source
>>> 0x7f2acd437a00: Suspend_Cfm
>>
>> The endpoint probably didn't acquire the fd so we suspend the stream.
>> Anyway the device is misbehaving if it is sending suspend and start
>> commands like that (perhaps you are pressing play/pause buttons?) but
>> if you don't wan't the stream to auto suspend you just need to Acquire
>> when the transport is in pending state.
>
> I did call org.bluez.MediaTransport1.Acquire before all this and the
> State went to active at that point and music was playing well. Then
> with the SUSPEND_CMD I see the State property going from active to
> idle and later from idle to pending (and later to suspend) If I
> understand well from what you say... Should I call Acquire again on
> the same /fd3 when I see the State going to pending?? Should I also
> Release it before? (for example when I see the State going to idle?) I
> don't see a clear answer from the doc/.

Yes, you should release the fd once the state change to idle, in the
future we might actually use frevoke (http://lwn.net/Articles/192632/)
to revoke the permissions but for now we have to assume the endpoint
will behave and close whenever the transport became idle. You are also
right, we should probably update the documentation to state the fd is
considered revoked in this case and the endpoint has to acquired
again. Btw PulseAudio does that already so Im curious why you are not
using PA, or is this for another Audio daemon?


--
Luiz Augusto von Dentz

2013-05-09 04:40:29

by Alex Deymo

[permalink] [raw]
Subject: Re: Audio sink stream remains suspended on reconnection

Hi Luiz,

On Wed, May 8, 2013 at 7:25 AM, Luiz Augusto von Dentz
<[email protected]> wrote:
> Hi Alex,
>
> On Wed, May 8, 2013 at 2:47 AM, Alex Deymo <[email protected]> wrote:
>> bluetoothd[21017]: profiles/audio/avdtp.c:session_cb()
>> bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_parse_resp() SUSPEND
>> request succeeded
>> bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_sep_set_state() stream
>> state changed: STREAMING -> OPEN
>> bluetoothd[21017]: profiles/audio/sink.c:sink_set_state() State
>> changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED: SINK_STATE_PLAYING ->
>> SINK_STATE_CONNECTED
>> bluetoothd[21017]:
>> profiles/audio/transport.c:transport_update_playing()
>> /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3
>> State=TRANSPORT_STATE_PENDING Playing=0
>> bluetoothd[21017]: profiles/audio/transport.c:transport_set_state()
>> State changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3:
>> TRANSPORT_STATE_PENDING -> TRANSPORT_STATE_IDLE
>> bluetoothd[21017]: profiles/audio/a2dp.c:suspend_cfm() Source
>> 0x7f2acd437a00: Suspend_Cfm
>
> The endpoint probably didn't acquire the fd so we suspend the stream.
> Anyway the device is misbehaving if it is sending suspend and start
> commands like that (perhaps you are pressing play/pause buttons?) but
> if you don't wan't the stream to auto suspend you just need to Acquire
> when the transport is in pending state.

I did call org.bluez.MediaTransport1.Acquire before all this and the
State went to active at that point and music was playing well. Then
with the SUSPEND_CMD I see the State property going from active to
idle and later from idle to pending (and later to suspend) If I
understand well from what you say... Should I call Acquire again on
the same /fd3 when I see the State going to pending?? Should I also
Release it before? (for example when I see the State going to idle?) I
don't see a clear answer from the doc/.

Thanks for the help!
Alex.

2013-05-08 14:25:59

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: Audio sink stream remains suspended on reconnection

Hi Alex,

On Wed, May 8, 2013 at 2:47 AM, Alex Deymo <[email protected]> wrote:
> bluetoothd[21017]: profiles/audio/avdtp.c:session_cb()
> bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_parse_cmd() Received SUSPEND_CMD
> bluetoothd[21017]: profiles/audio/a2dp.c:suspend_ind() Source
> 0x7f2acd437a00: Suspend_Ind
> bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_sep_set_state() stream
> state changed: STREAMING -> OPEN
> bluetoothd[21017]: profiles/audio/sink.c:sink_set_state() State
> changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED: SINK_STATE_PLAYING ->
> SINK_STATE_CONNECTED
> bluetoothd[21017]:
> profiles/audio/transport.c:transport_update_playing()
> /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3 State=TRANSPORT_STATE_ACTIVE
> Playing=0
> bluetoothd[21017]:
> profiles/audio/transport.c:media_transport_remove_owner() Transport
> /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3 Owner :1.1198
> bluetoothd[21017]: profiles/audio/transport.c:media_owner_free() Owner :1.1198
> bluetoothd[21017]: profiles/audio/transport.c:transport_set_state()
> State changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3:
> TRANSPORT_STATE_ACTIVE -> TRANSPORT_STATE_IDLE
> bluetoothd[21017]: profiles/audio/a2dp.c:a2dp_sep_unlock() SEP
> 0x7f2acd437a00 unlocked

There device request the stream to be suspended, which is what it
happens and the transport is then set to idle state which should
indicate to the endpoint what happened.

>
> bluetoothd[21017]: profiles/audio/avdtp.c:session_cb()
> bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_parse_cmd() Received START_CMD
> bluetoothd[21017]: profiles/audio/a2dp.c:start_ind() Source
> 0x7f2acd437a00: Start_Ind
> bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_ref() 0x7f2acd43ce70: ref=3
> bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_sep_set_state() stream
> state changed: OPEN -> STREAMING
> bluetoothd[21017]: profiles/audio/sink.c:sink_set_state() State
> changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED: SINK_STATE_CONNECTED ->
> SINK_STATE_PLAYING
> bluetoothd[21017]:
> profiles/audio/transport.c:transport_update_playing()
> /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3 State=TRANSPORT_STATE_IDLE
> Playing=1
> bluetoothd[21017]: profiles/audio/transport.c:transport_set_state()
> State changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3:
> TRANSPORT_STATE_IDLE -> TRANSPORT_STATE_PENDING
> bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_unref() 0x7f2acd43ce70: ref=2

Here it asks the stream to resume, transport state goes to pending
which normally triggers the endpoint to Acquire the fd.

>
> bluetoothd[21017]: profiles/audio/avdtp.c:session_cb()
> bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_parse_resp() SUSPEND
> request succeeded
> bluetoothd[21017]: profiles/audio/avdtp.c:avdtp_sep_set_state() stream
> state changed: STREAMING -> OPEN
> bluetoothd[21017]: profiles/audio/sink.c:sink_set_state() State
> changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED: SINK_STATE_PLAYING ->
> SINK_STATE_CONNECTED
> bluetoothd[21017]:
> profiles/audio/transport.c:transport_update_playing()
> /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3
> State=TRANSPORT_STATE_PENDING Playing=0
> bluetoothd[21017]: profiles/audio/transport.c:transport_set_state()
> State changed /org/bluez/hci0/dev_10_B7_F6_01_31_ED/fd3:
> TRANSPORT_STATE_PENDING -> TRANSPORT_STATE_IDLE
> bluetoothd[21017]: profiles/audio/a2dp.c:suspend_cfm() Source
> 0x7f2acd437a00: Suspend_Cfm

The endpoint probably didn't acquire the fd so we suspend the stream.
Anyway the device is misbehaving if it is sending suspend and start
commands like that (perhaps you are pressing play/pause buttons?) but
if you don't wan't the stream to auto suspend you just need to Acquire
when the transport is in pending state.


--
Luiz Augusto von Dentz