Difference between revisions of "Bluetooth"

From NixOS Wiki
Jump to: navigation, search
(Create Legacy section for information that predates NixOS 25.05 to help newcomers.)
m (Consolidated guidance to enable battery charge support. Experimental is misleading. It is stable.)
Line 1: Line 1:
==Enabling Bluetooth support==
+
==Enabling Bluetooth Support==
 +
 
 +
''' Presumptions '''
 +
 
 +
* NixOS 25.05
 +
* Classic channels configuration
 +
 
 +
''Please extrapolate for other NixOS versions, configurations, flakes, hardware, et cetera.''
 +
 
 
To enable support for Bluetooth devices, amend your system configuration as follows:
 
To enable support for Bluetooth devices, amend your system configuration as follows:
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{
+
hardware.bluetooth = {
   ...
+
   enable = true;
   hardware.bluetooth.enable = true; # enables support for Bluetooth
+
   powerOnBoot = true;
   hardware.bluetooth.powerOnBoot = true; # powers up the default Bluetooth controller on boot
+
   settings = {
  ...
+
    General = {
}
+
      Experimental = true; # Show battery charge of Bluetooth devices
 +
    };
 
</nowiki>}}
 
</nowiki>}}
 +
 
{{evaluate}}
 
{{evaluate}}
 +
 
==Pairing Bluetooth devices==
 
==Pairing Bluetooth 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.
 
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.
Line 56: Line 67:
  
 
{{Warning|This is unnecessary and may cause issues if using PipeWire & Wireplumber, which is the default over PulseAudio on NixOS since 24.11}}
 
{{Warning|This is unnecessary and may cause issues if using PipeWire & Wireplumber, which is the default over PulseAudio on NixOS since 24.11}}
 
==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==

Revision as of 21:23, 31 July 2025

Enabling Bluetooth Support

Presumptions

  • NixOS 25.05
  • Classic channels configuration

Please extrapolate for other NixOS versions, configurations, flakes, hardware, et cetera.

To enable support for Bluetooth devices, amend your system configuration as follows:

Breeze-text-x-plain.png
/etc/nixos/configuration.nix
hardware.bluetooth = {
  enable = true;
  powerOnBoot = true;
  settings = {
    General = {
      Experimental = true; # Show battery charge of Bluetooth devices
    };


Pairing Bluetooth 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 additionally enable the blueman service, which provides blueman-applet and blueman-manager with the snippet below.

services.blueman.enable = true;

Pairing devices from the command line

Alternatively, Bluetooth devices can be paired from the command line using bluetoothctl.

$ bluetoothctl
[bluetooth] # power on
[bluetooth] # agent on
[bluetooth] # default-agent
[bluetooth] # scan on
...put device in pairing mode and wait [hex-address] to appear here...
[bluetooth] # pair [hex-address]
[bluetooth] # connect [hex-address]

Bluetooth devices automatically connect with bluetoothctl as well:

$ bluetoothctl
[bluetooth] # trust [hex-address]

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 MPRIS standard, one can use mpris-proxy that is part of bluez package. The following snippet can be used in Home Manager to start this program as a daemon:

systemd.user.services.mpris-proxy = {
    description = "Mpris proxy";
    after = [ "network.target" "sound.target" ];
    wantedBy = [ "default.target" ];
    serviceConfig.ExecStart = "${pkgs.bluez}/bin/mpris-proxy";
};

Or, starting with Home Manager 21.05, enable the mpris-proxy service.

Warning: This is unnecessary and may cause issues if using PipeWire & Wireplumber, which is the default over PulseAudio on NixOS since 24.11

Troubleshooting

USB device needs to be unplugged/re-plugged after suspend

Some USB device/host combinations don't play well with the suspend/resume cycle, and need to be unplugged and then re-plugged to work again.

It is possible to simulate a unplug/re-plug cycle using the /sys filesystem.

This gist provides a script and instructions to set-up a workaround for these devices.

When connecting to an audio device: Failed to connect: org.bluez.Error.Failed

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 journalctl -eu bluetooth shows Failed to set mode: Blocked through rfkill (0x12), rfkill might be blocking it:

$ rfkill
ID TYPE      DEVICE      SOFT      HARD
 1 wlan      phy0   unblocked unblocked
37 bluetooth hci0   blocked unblocked

Unblock it first:

$ sudo rfkill unblock bluetooth

Cannot use bluetooth while it previously worked

Symptoms:

  • When using bluetoothctl, getting "No agent is registered".
  • When using blueman or anything using dbus to talk to bluez, getting dbus.exceptions.DBusException: org.freedesktop.DBus.Error.AccessDenied: Rejected send message"

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.

$ sudo systemctl restart display-manager.service

No audio when using headset in HSP/HFP mode

If the output of dmesg | grep Bluetooth shows a line similar to Bluetooth: hci0: BCM: Patch brcm/BCM-0a5c-6410.hcd not found then your machine uses a Broadcom chipset without the required firmware installed.

To fix this, add hardware.enableAllFirmware = true; to your /etc/nixos/configuration.nix then reboot.

See also


Legacy

Using Bluetooth headsets with PulseAudio

To allow Bluetooth audio devices to be used with PulseAudio, amend /etc/nixos/configuration.nix as follows:

{
  hardware.pulseaudio.enable = true;
  hardware.bluetooth.enable = true;
}

You will need to restart PulseAudio; try systemctl --user daemon-reload; systemctl --user restart pulseaudio.

You can verify that PulseAudio has loaded the Bluetooth module by running pactl list | grep -i 'Name.*module.*blue'; Bluetooth modules should be present in the list.

System-Wide PulseAudio

When you are running PulseAudio system-wide then you will need to add the following modules to your default.pa configuration:

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
'';

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 /etc/nixos/configuration.nix:

{
...
  hardware.pulseaudio = {
    enable = true;
    package = pkgs.pulseaudioFull;
  };
...
}

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 /etc/nixos/configuration.nix

{
  hardware.bluetooth.settings = {
    General = {
      Enable = "Source,Sink,Media,Socket";
    };
  };
}

This configuration may be unnecessary and does not work with bluez5 (Unknown key Enable for group General ).

Managing audio devices

pavucontrol can be used to reconfigure the device:

  • To enable A2DP, change the profile to “High Fidelity Playback (A2DP Sink)” on the “Configuration” tab.
  • To set the device as the default audio output, select “set as fallback” on the “Output Devices” tab.

Alternatively, the device can be configured via the command line:

  • To enable A2DP, run:
    $ pacmd set-card-profile "$(pactl list cards short | egrep -o bluez_card[[:alnum:]._]+)" a2dp_sink
    
  • To set the device as the default audio output, run:
    $ pacmd set-default-sink "$(pactl list sinks short | egrep -o bluez_sink[[:alnum:]._]+)"
    

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

{
...
hardware.pulseaudio.extraConfig = "
  load-module module-switch-on-connect
";
...
}

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

See also