Bluetooth: Difference between revisions

imported>Grahamc
m Update anchor
(33 intermediate revisions by 23 users not shown)
Line 1: Line 1:
==Enabling Bluetooth support==
==Enabling Bluetooth support==
To enable support for Bluetooth devices, add {{nixos:option|hardware.bluetooth.enable}} to <tt>/etc/nixos/configuration.nix</tt>:
To enable support for Bluetooth devices, amend your system configuration as follows:
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
<syntaxhighlight lang="nix">{
{
   ...
   ...
   hardware.bluetooth.enable = true;
   hardware.bluetooth.enable = true; # enables support for Bluetooth
  hardware.bluetooth.powerOnBoot = true; # powers up the default Bluetooth controller on boot
   ...
   ...
}</syntaxhighlight>
}
 
</nowiki>}}
{{evaluate}}
{{evaluate}}
==Pairing Bluetooth devices==
==Pairing Bluetooth devices==
{{expansion}}
In order to use Bluetooth devices, they must be paired with your NixOS machine. Heavier desktop environments will usually provide a Bluetooth management GUI which you can use to pair devices.
In order to use Bluetooth devices, they must be paired with your NixOS machine. Heavier desktop environments will usually provide a Bluetooth management GUI which you can use to pair devices.


If your desktop environment does not provide such a GUI, you can install the <tt>blueman</tt> package. This provides a tray icon process (<tt>blueman-applet</tt>) and a GUI management application (<tt>blueman-manager</tt>).
If your desktop environment does not provide such a GUI, you can additionally enable the blueman service, which provides blueman-applet and blueman-manager with the snippet below.
<syntaxhighlight lang="nix">
services.blueman.enable = true;
</syntaxhighlight>


===Pairing devices from the command line===
===Pairing devices from the command line===
Line 28: Line 29:
[bluetooth] # pair [hex-address]
[bluetooth] # pair [hex-address]
[bluetooth] # connect [hex-address]</syntaxhighlight>
[bluetooth] # connect [hex-address]</syntaxhighlight>
Bluetooth devices automatically connect with <tt>bluetoothctl</tt> as well:
<syntaxhighlight lang="console">
$ bluetoothctl
[bluetooth] # trust [hex-address]
</syntaxhighlight>


==Using Bluetooth headsets with PulseAudio==
==Using Bluetooth headsets with PulseAudio==
Line 34: Line 42:


<syntaxhighlight lang="nix">{
<syntaxhighlight lang="nix">{
  ...
   hardware.pulseaudio.enable = true;
   hardware.pulseaudio = {
    enable = true;
 
    # NixOS allows either a lightweight build (default) or full build of PulseAudio to be installed.
    # Only the full build has Bluetooth support, so it must be selected here.
    package = pkgs.pulseaudioFull;
  };
 
   hardware.bluetooth.enable = true;
   hardware.bluetooth.enable = true;
  ...
}</syntaxhighlight>
}</syntaxhighlight>


Line 52: Line 51:


You can verify that PulseAudio has loaded the Bluetooth module by running <tt>pactl list | grep -i 'Name.*module.*blue'</tt>; Bluetooth modules should be present in the list.
You can verify that PulseAudio has loaded the Bluetooth module by running <tt>pactl list | grep -i 'Name.*module.*blue'</tt>; Bluetooth modules should be present in the list.
== Using Bluetooth headset buttons to control media player ==
Some bluetooth headsets have buttons for  pause/play or to skip to the next track.
To make these buttons usable with media players supporting the dbus-based [https://specifications.freedesktop.org/mpris-spec/latest/ MPRIS] standard,
one can use <code>mpris-proxy</code> that is part of bluez package.
The following snippet can be used in [[Home Manager]] to start this program as a daemon:
<syntaxHighlight lang="nix">
systemd.user.services.mpris-proxy = {
    description = "Mpris proxy";
    after = [ "network.target" "sound.target" ];
    wantedBy = [ "default.target" ];
    serviceConfig.ExecStart = "${pkgs.bluez}/bin/mpris-proxy";
};
</syntaxHighlight>
Or, starting with Home Manager 21.05, enable the <code>mpris-proxy</code> service.
===System-Wide PulseAudio ===
{{Expansion|When setting up pulseaudio systemWide extra policies needs to be deployed for pulse to be able to connect to the bluetooth stack. The Info below is not enough.}}
When you are running PulseAudio system-wide then you will need to add the following modules to your <code>default.pa</code> configuration:
<syntaxHighlight lang="nix">
hardware.pulseaudio.configFile = pkgs.writeText "default.pa" ''
  load-module module-bluetooth-policy
  load-module module-bluetooth-discover
  ## module fails to load with
  ##  module-bluez5-device.c: Failed to get device path from module arguments
  ##  module.c: Failed to load module "module-bluez5-device" (argument: ""): initialization failed.
  # load-module module-bluez5-device
  # load-module module-bluez5-discover
'';
</syntaxHighlight>
===Enabling extra codecs===
While pulseaudio itself only has support for the SBC bluetooth codec there is out-of-tree support for AAC, APTX, APTX-HD and LDAC.
To enable extra codecs add the following to <tt>/etc/nixos/configuration.nix</tt>:
<syntaxHighlight lang="nix">
{
...
  hardware.pulseaudio = {
    enable = true;
    package = pkgs.pulseaudioFull;
  };
...
}
</syntaxHighlight>


===Enabling A2DP Sink===
===Enabling A2DP Sink===
Modern headsets will generally try to connect using the A2DP profile. To enable this for your bluetooth connection, add the following to <tt>/etc/nixos/configuration.nix</tt>
Modern headsets will generally try to connect using the A2DP profile. To enable this for your bluetooth connection, add the following to <tt>/etc/nixos/configuration.nix</tt>


<syntaxhighlight lang="nix">{
<syntaxhighlight lang="nix">
...
{
hardware.bluetooth.extraConfig = "
  hardware.bluetooth.settings = {
  [general]
    General = {
  Enable=Source,Sink,Media,Socket
      Enable = "Source,Sink,Media,Socket";
"
    };
...
  };
}</syntaxhighlight>
}
</syntaxhighlight>
This configuration may be unnecessary and does not work with bluez5 (<tt>Unknown key Enable for group General</tt> ).


===Managing audio devices===
===Managing audio devices===
Line 75: Line 125:
* To enable A2DP, run: <syntaxhighlight lang="console">$ pacmd set-card-profile "$(pactl list cards short | egrep -o bluez_card[[:alnum:]._]+)" a2dp_sink</syntaxhighlight>
* To enable A2DP, run: <syntaxhighlight lang="console">$ pacmd set-card-profile "$(pactl list cards short | egrep -o bluez_card[[:alnum:]._]+)" a2dp_sink</syntaxhighlight>
* To set the device as the default audio output, run: <syntaxhighlight lang="console">$ pacmd set-default-sink "$(pactl list sinks short | egrep -o bluez_sink[[:alnum:]._]+)"</syntaxhighlight>
* To set the device as the default audio output, run: <syntaxhighlight lang="console">$ pacmd set-default-sink "$(pactl list sinks short | egrep -o bluez_sink[[:alnum:]._]+)"</syntaxhighlight>
You can also set pulseaudio to automatically switch audio to the connected bluetooth device when it connects, in order to do this add the following entry into the pulseaudio config
<syntaxhighlight lang="nix">{
...
hardware.pulseaudio.extraConfig = "
  load-module module-switch-on-connect
";
...
}</syntaxhighlight>
Note that you may need to clear the pulseaudio config located at ~/.config/pulse to get this to work. Also you may have to unset and then set the default audio device to the bluetooth device, see https://github.com/NixOS/nixpkgs/issues/86441 for more info
==Showing battery charge of bluetooth devices==
If you want to see what charge your bluetooth devices have you have to enable experimental features, which might lead to bugs (according to [https://wiki.archlinux.org/title/Bluetooth_headset#Battery_level_reporting Arch Wiki). You can add the following to your config to enable experimental feature for bluetooth:
<syntaxhighlight lang="nix">{
...
hardware.bluetooth.settings = {
General = {
Experimental = true;
};
};
...
}</syntaxhighlight>
Afterwards rebuild your system and then restart your bluetooth service by executing  <syntaxhighlight lang="console">$ systemctl restart bluetooth</syntaxhighlight>.


==Troubleshooting==
==Troubleshooting==
Line 87: Line 162:


You need to use pulseaudioFull, see [[#Using Bluetooth headsets with PulseAudio]].
You need to use pulseaudioFull, see [[#Using Bluetooth headsets with PulseAudio]].
===Bluetooth fails to power on with Failed to set power on: org.bluez.Error.Blocked===
If <tt>journalctl -eu bluetooth</tt> shows <tt>Failed to set mode: Blocked through rfkill (0x12)</tt>, rfkill might be blocking it:
<syntaxhighlight lang="console">
$ rfkill
ID TYPE      DEVICE      SOFT      HARD
1 wlan      phy0  unblocked unblocked
37 bluetooth hci0  blocked unblocked
</syntaxhighlight>
Unblock it first:
<syntaxhighlight lang="console">
$ sudo rfkill unblock bluetooth
</syntaxhighlight>
=== Cannot use bluetooth while it previously worked ===
Symptoms:
* When using <code>bluetoothctl</code>, getting "No agent is registered".
* When using <code>blueman</code> or anything using dbus to talk to bluez, getting <code>dbus.exceptions.DBusException: org.freedesktop.DBus.Error.AccessDenied: Rejected send message"</code>
This possibly can be fixed by restarting the display-manager session. The session management may have had an issue with registering your current session and doesn't allow you to control bluetooth.
<syntaxhighlight lang="console">
$ sudo systemctl restart display-manager.service
</syntaxhighlight>
=== No audio when using headset in HSP/HFP mode ===
If the output of <code>dmesg | grep Bluetooth</code> shows a line similar to <code>Bluetooth: hci0: BCM: Patch brcm/BCM-0a5c-6410.hcd not found</code> then your machine uses a Broadcom chipset without the required firmware installed.
To fix this, add <code>hardware.enableAllFirmware = true;</code> to your <tt>/etc/nixos/configuration.nix</tt> then reboot.


==See also==
==See also==
* [http://anderspapitto.com/posts/2016-11-07-scripting_pulseaudio_bluetooth_jack.html Scripting PulseAudio, Bluetooth, JACK]
* [http://anderspapitto.com/posts/2016-11-07-scripting_pulseaudio_bluetooth_jack.html Scripting PulseAudio, Bluetooth, JACK]
* [https://wiki.gentoo.org/wiki/Bluetooth Bluetooth (Gentoo Wiki)]
* [https://wiki.archlinux.org/index.php/Bluetooth Bluetooth (Arch Linux Wiki)]
* [https://wiki.archlinux.org/index.php/Bluetooth Bluetooth (Arch Linux Wiki)]


[[Category:Installation]][[Category:Configuration]][[Category:Hardware]]
[[Category:Audio]][[Category:Configuration]][[Category:Hardware]]