Logo

HomeAboutCommunityDownloadDocumentationPlanet


Bluetooth

PulseAudio depends on BlueZ for all Bluetooth functionality, and additionally oFono is required for HFP support.

Profiles

The bluetooth standard specifies three audio profiles. Try not to confuse these with the "card profile" concept in PulseAudio. A bluetooth device shows up in PulseAudio as a card, and the card will have some set of profiles depending on what bluetooth profiles the device supports, but the "bluetooth profile" <-> "card profile" mapping is not one-to-one. The three bluetooth profiles are:

  • A2DP (Advanced Audio Distribution Profile) - high-quality audio playback, appropriate for e.g. listening to music.
  • HSP (HeadSet Profile) - phone-quality audio playback and recording, appropriate for phone calls.
  • HFP (Hands-Free Profile) - same as HSP, but with additional functionality for managing phone calls.

Each of the profiles are further divided into two roles:

  • A2DP:
    • Source role - the device that sends audio.
    • Sink role - the device that receives audio.
  • HSP:
    • Audio Gateway role - the device that the headset is connected to. The HSP profile is typically used in phone calls, and this is the device that is connected to the cellular network (for cellular phone calls) or to the internet (for VoIP calls). Typically a cellular phone or a PC.
    • Headset role - the headset, obviously. This is where the speakers and microphone are.
  • HFP:
    • Audio Gateway role - the device that the hands-free device is connected to. The HFP profile is typically used for cellular phone calls, and this is the device that is connected to the cellular network. Typically a cellular phone.
    • Hands-Free Unit role - the device with the speakers and microphone.

A2DP

PulseAudio supports A2DP in both source and sink roles. When PulseAudio acts in the source role, a sink is created where applications can play to. When PulseAudio acts in the sink role, a source is created where applications can record from.

A2DP works generally without a hassle, although when watching videos, the audio can get badly out of sync. It seems that in case of transmission problems (weak signal, or out of signal range) the kernel can buffer quite a lot of audio. Here's a bug report about this issue: https://bugs.freedesktop.org/show_bug.cgi?id=58746. A patch is available in the bug report (see comment #8), but it breaks HSP, so it can't be accepted. The general idea of the patch seems fine, though. Help with improving the patch would be very welcome.

HSP/HFP

PulseAudio supports both HSP roles, and with oFono also both HFP roles. In the default configuration, if oFono isn't running, only HSP is enabled. If oFono is running, the audio gateway role of HSP is enabled plus both HFP roles. The headset role of HSP is disabled, because otherwise PulseAudio and oFono would conflict as both would try to listen for new connections from audio gateway devices.

It's possible to force PulseAudio to only enable HSP or HFP with the "headset" option of module-bluetooth-discover (configured in /etc/pulse/default.pa). By default the option is set to "auto", but if it's set to "native", then only HSP is enabled, and if the option is set to "ofono", then only HFP is enabled.

When connected to a HSP or HFP device, the bluetooth card in PulseAudio will have the "Headset Head Unit (HSP/HFP)" and/or "Headset Audio Gateway (HSP/HFP)" profiles available. When those profiles are activated, a sink and a source are created where applications can play and record audio.

When PulseAudio is acting as a headset or a hands-free unit, it's rarely necessary to manually change the card profile. When the audio gateway initiates audio streaming, module-bluetooth-policy will automatically change to the appropriate profile. module-bluetooth-policy will also load module-loopback instances to loop the audio from bluetooth to the local speakers and microphone.

Being able to use HFP headsets without oFono would be nice, and James Bottomley has submitted patches for that: https://www.mail-archive.com/pulseaudio-discuss@lists.freedesktop.org/msg16443.html. The patches need some work, but nothing has happened for a long time. Someone else could relatively easily finish off the work - just read the review discussion, and address the points raised.

Using bluetooth when running PulseAudio in the system mode

For some reason the bluetooth modules aren't included in /etc/pulse/system.pa by default, so if you want to use bluetooth, add this to /etc/pulse/system.pa:

load-module module-bluetooth-discover
load-module module-bluetooth-policy

It's generally recommended to disallow module loading when using PulseAudio in the system mode, because if the system administrator doesn't trust the users, allowing users to load modules may not be a good idea. However, bluetooth doesn't work if module loading is disallowed (this is a bug that somebody should fix), so if it's more important to have bluetooth support than to prevent users from loading (and unloading) modules, make sure you don't disallow module loading (by default module loading is allowed).

The D-Bus access policy doesn't allow pulseaudio to communicate with bluetoothd by default when running pulseaudio in the system mode. Add the user "pulse" to group "bluetooth" to grant the permission.

The D-Bus access policy also doesn't allow pulseaudio to communicate with ofonod by default when running pulseaudio in the system mode. To grant the permission, add this to /etc/dbus-1/system.d/ofono.conf:

  <policy user="pulse">
    <allow send_destination="org.ofono"/>
  </policy>

Using HFP with oFono

Currently HFP support in pulseaudio is only available through oFono. The additional dependency makes device setup somewhat difficult because oFono is designed for mobile telephony and not for audio applications.

Within oFono, a mobile telephony device is represented as a modem. oFono will only work if there is at least one enabled modem in your system. To simplify modem control, you should download the source code of oFono (git://git.kernel.org/pub/scm/network/ofono/ofono.git), which contains a "test" directory with several useful python scripts. A list of available modems can be obtained by running

test/list-modems

A modem can be enabled with

test/enable-modem /modem_path

and disabled again with

test/disable-modem /modem_path

Headset Setup

The necessity to provide a modem to oFono makes the headset setup rather cumbersome. If you do not have a GSM/UMTS modem connected to your system (like in most desktop environments), you need a modem emulator. Unfortunately oFono does not allow to use a mobile (hfp modem, see below) as a modem to support headsets.

The best emulator choice is "phonesim" because there is a version that is maintained together with ofono. Most distributions contain a package ofono-phonesim or similar while the git version can be found at git://git.kernel.org/pub/scm/network/ofono/phonesim.git.

To set up phonesim, first create or edit the file phonesim.conf in /etc/ofono. It should contain the following lines:

[phonesim]
Driver=phonesim
Address=127.0.0.1
Port=12345

Restart oFono and check with list-modems if the phonesim modem was found. Start phonesim with

phonesim -p 12345 /usr/share/phonesim/default.xml&

The paths to phonesim.conf and default.xml might be different if you compiled ofono and/or phonesim from source. Now you can enable the modem either by using the enable-modem script or by issuing the following command:

dbus-send --print-reply --system --dest=org.ofono /phonesim org.ofono.Modem.SetProperty string:"Powered" variant:boolean:"true"

list-modems should show that the modem is powered and online. If you want to play with the modem emulator, you can add the -gui option to the phonesim command. Then a GUI will pop up as soon as you enable the modem.

Once the modem is set up properly, you can connect your headset and the "Headset Head Unit (HSP/HFP)" profile should be available in pulseaudio.

Mobile phone Setup

After connecting your mobile to the system, the phone should already be available without further configuration. Use list-modems to find it (there will be a modem with Type=hfp). If it is not online (Online=1 and Powered=1), you need to enable it first by running enable-modem with the appropriate path. While the device is enabled, you can test that audio works by calling someone using the phone. You can also try to command the phone to make the call from your computer with this command:

test/dial-number /hfp_path 12345

Similar to HSP, module-bluetooth-policy will load module-loopback instances to loop the audio from bluetooth to the local speakers and microphone. To hangup all ongoing calls, this command can be used:

test/hangup-all /hfp_path

History of bluetooth features in PulseAudio

11.0

  • HSP headset role implemented, which means that PulseAudio can act as a headset.
  • HFP audio gateway role implemented (via oFono), which means that PulseAudio can use bluetooth headsets via HFP instead of HSP (good especially for headsets that only support HFP).
  • The HSP audio gateway and HFP headset roles can be enabled simultaneously.
  • Bluetooth device priority got bumped higher than internal sound cards, which means that it's not any more necessary to set the bluetooth device as the default sink manually when connecting it.
  • The "auto_switch" option of module-bluetooth-policy got a new mode: mode "2" can be used to enable automatic profile switching from A2DP to HSP when a recording stream appears without any role set.
  • HSP MTU configuration changed from always using 48 bytes to asking the kernel for an appropriate packet size.

More details in the release notes.

10.0

  • module-bluetooth-policy got a new option: "auto_switch" can be used to enable automatic profile switches from A2DP to HSP when a recording stream appears with role "phone".
  • Separate volumes for A2DP and HSP.

More details in the release notes.

6.0

  • HSP audio gateway role implemented, so HSP headsets can again be used with PulseAudio.
  • HFP hands-free unit role implemented (via oFono), so PulseAudio can act as a headset or other hands-free device.

More details in the release notes.

5.0

  • Initial BlueZ 5 support added. Only A2DP is supported. (BlueZ 4 support is retained, though, so systems that still use BlueZ 4 keep working as before.)

More details in the release notes.

Troubleshooting

Check first that your version of PulseAudio supports the feature you're trying to use. Refer to the history section above to see when a particular bluetooth feature was added to PulseAudio.

HSP problem: HSP stopped working when upgrading PulseAudio from 10.0 to 11.0

From the 11.0 release notes:

The packet size (a.k.a. MTU, "maximum transmission unit") that PulseAudio uses with the bluetooth HSP profile was previously always configured to be 48 bytes. That worked with most hardware, but some adapters require a different packet size. Now PulseAudio asks the kernel what packet size should be used, which fixes the problem.

However, a new problem appeared: some adapters that used to work with 48 byte packet size don't any more work with the size that the kernel tells PulseAudio to use. If you find that HSP audio stopped working when upgrading to PulseAudio 11.0, you can revert to the old behaviour by passing option "autodetect_mtu=no" to module-bluetooth-discover in /etc/pulse/default.pa. If that fixes the problem, then please report the problem to the BlueZ and/or PulseAudio developers, so that the kernel can be fixed.

HSP problem: the bluetooth sink and source are created, but no audio is being transmitted

This is often not PulseAudio's fault, and not specific to any particular headset. Instead, the problem tends to be in the bluetooth adapter. The bluetooth adapter may be missing firmware, or the adapter's SCO audio routing may be wrong (SCO is the audio protocol used by HSP and HFP, and SCO audio needs to be routed via the HCI interface in order to work with PulseAudio). Bug 97064 has discussion about this, and solutions for a couple of adapters. If you have different hardware and are suffering from this problem AND you find a working solution, please comment on the bug.

Here are the adapters with known solutions (these adapters/chipsets are probably used in multiple products under different brands, so use lsusb/lspci/etc to figure out the chipset of your bluetooth adapter):

TI WL1837: http://www.ti.com/product/WL1837MOD

This adapter may have wrong SCO audio routing. Use this command (as root) to route the SCO audio through HCI:

hcitool cmd 0x3F 0x0210 0x01 120 511 0xFF

Broadcom BCM20702

This adapter requires proprietary firmware. Installation instructions: http://plugable.com/2014/06/23/plugable-usb-bluetooth-adapter-solving-hfphsp-profile-issues-on-linux/

HSP problem: "Protocol not supported"

There was some regression in the kernel that was introduced in 3.12 and fixed in 3.18 that caused failure when trying to activate HSP with some headsets. This problem can be identified by this error message in pulseaudio log:

backend-native.c: connect(): Protocol not supported

Getting a log from bluetoothd

Sometimes inspecting the bluetoothd log is helpful. Here are instructions for getting the log:

First, stop bluetoothd and preferably also prevent it from getting started automatically. Here's how to do that with systemd:

sudo systemctl disable bluetooth.service
sudo systemctl stop bluetooth.service

Then, run bluetoothd in a terminal with verbose logging:

sudo /usr/lib/bluetooth/bluetoothd -n -d

Now you can read the log, or copy it from the terminal for later reading.

When you want to stop bluetoothd, press ctrl-c. When you're done, you probably want to re-enable the bluetooth service. Here's how to do that with systemd:

sudo systemctl enable bluetooth.service
sudo systemctl start bluetooth.service

Sometimes it's useful to have both bluetoothd and pulseaudio logs interleaved, because that makes it easier to match events in the bluetoothd log with events in the pulseaudio log. To do this, add "&" to the end of the bluetoothd command, like this:

sudo /usr/lib/bluetooth/bluetoothd -n -d &

Now bluetoothd will run as a background process, but it will still print log messages to the terminal. You can now start pulseaudio in the same terminal. TODO: Write instructions for getting the log from pulseaudio.

When bluetoothd is running in the background, ctrl-c won't stop it, so use this command instead:

sudo killall bluetoothd

Specifications

Here are some links to relevant specifications: