[pulseaudio-discuss] [PATCH] bluetooth: Poll BT SCO socket for checking remote disconnect.

Tanu Kaskinen tanuk at iki.fi
Sat Jan 21 07:36:56 PST 2012


On Fri, 2011-12-16 at 14:06 +0200, Tanu Kaskinen wrote:
> From: Marko Ollonen <marko.ollonen at digia.com>
> 
> Additional comments from Tanu Kaskinen:
> 
> There's this comment in start_thread() for the SCO over PCM
> case: "FIXME: monitor stream_fd error". I guess this patch
> solves that FIXME item at least partially.
> 
> The "u->sink->state == PA_SINK_RUNNING" condition looks a
> bit strange to me - why is this only checked when the sink
> is RUNNING, why not also when IDLE?
> 
> I think it would be better to poll stream_fd in the IO
> thread (which is currently not started for the SCO over PCM
> case) so that the stream disconnection could be handled
> immediately when it happens. I'm not willing to do that
> work now, however.
> 
> ---
> 
> This is an old patch that has been made for Harmattan. I'd
> like to get this patch to upstream, since it (probably)
> does something useful and very likely doesn't break
> anything, but if this is not considered the right way to
> fix the problem, I can also understand if the patch gets
> rejected.

No comments received, but nevertheless, I'm not going to push this
patch. I've learned that this can actually break things: let's say
pulseaudio is running on a phone, and the user is having a call using a
hands-free bluetooth device. One of the features of the HFP profile is
that the user can transfer the audio from the hands-free device to the
phone. So the user does that. This causes bluetoothd to close the audio
stream between bluetoothd and Pulseaudio, and some policy thing moves
the phone streams from the SCO sink and source to somewhere else. As a
result, the sink and source become idle, and these state changes trigger
calls to this sco_over_pcm_state_update() function.

In the described scenario, this patch may or may not notice that the
stream fd has been closed by bluetoothd, and will release the transport.
Whether that will happen, depends on which became idle first: the sink
or the source. If the sink becomes idle first, the "(u->sink->state ==
PA_SINK_RUNNING) && (u->stream_fd >= 0)" condition will evaluate to
false, and the transport will not get released and the u->stream_fd will
remain non-negative. But if the source becomes idle first, then the sink
will still be in the running state when this function is called for the
first time. So the transport gets released and u->stream_fd becomes -1.

Later in the function, it is checked whether u->stream_fd is negative.
If it is, the bluetooth stream gets reinitialized, which isn't quite
what we want in this scenario! At least on Harmattan, the policy thing
will interpret this reinitialization so that the audio should get routed
to the bluetooth sink and source again, so the user's attempt to move
the audio from the hands-free device to the phone fails.

This shows that if the stream gets closed by bluetoothd, immediately
reopening the stream is not the right reaction, at least not always.
Maybe sometimes it is - otherwise I don't think this patch would have
been ever created (the original motivation for the patch unfortunately
hasn't been documented).

It's not clear to me how this kind of situation should be handled. What
to do when the user requests moving the audio away from the bluetooth
device and bluetoothd closes the stream? My proposal is to mark the HSP
ports as unavailable when the stream gets closed by bluetoothd. The
expectation is that some policy module will detect that and move the
phone streams elsewhere. If there isn't a suitable policy module loaded,
the HSP sink and source shall just sit there without processing any
audio.

When would the HSP ports become available again? Well, the ports became
unavailable as a result from the user asking the audio to be moved away
from the bluetooth device, so I think it would be logical if the ports
became available when the user asks the audio to be moved back to the
bluetooth device. I'm not familiar with the details, but I'd expect
bluetoothd to send a D-Bus signal when that request is made, and
Pulseaudio could act based on that signal.

-- 
Tanu



More information about the pulseaudio-discuss mailing list