at 21.11-pre 4.4 kB view raw
1{ config, lib, pkgs, ... }: 2let 3 cfg = config.hardware.bluetooth; 4 package = cfg.package; 5 6 inherit (lib) 7 mkDefault mkEnableOption mkIf mkOption 8 mkRenamedOptionModule mkRemovedOptionModule 9 concatStringsSep escapeShellArgs 10 optional optionals optionalAttrs recursiveUpdate types; 11 12 cfgFmt = pkgs.formats.ini { }; 13 14 # bluez will complain if some of the sections are not found, so just make them 15 # empty (but present in the file) for now 16 defaults = { 17 General.ControllerMode = "dual"; 18 Controller = { }; 19 GATT = { }; 20 Policy.AutoEnable = cfg.powerOnBoot; 21 }; 22 23 hasDisabledPlugins = builtins.length cfg.disabledPlugins > 0; 24 25in 26{ 27 imports = [ 28 (mkRenamedOptionModule [ "hardware" "bluetooth" "config" ] [ "hardware" "bluetooth" "settings" ]) 29 (mkRemovedOptionModule [ "hardware" "bluetooth" "extraConfig" ] '' 30 Use hardware.bluetooth.settings instead. 31 32 This is part of the general move to use structured settings instead of raw 33 text for config as introduced by RFC0042: 34 https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md 35 '') 36 ]; 37 38 ###### interface 39 40 options = { 41 42 hardware.bluetooth = { 43 enable = mkEnableOption "support for Bluetooth"; 44 45 hsphfpd.enable = mkEnableOption "support for hsphfpd[-prototype] implementation"; 46 47 powerOnBoot = mkOption { 48 type = types.bool; 49 default = true; 50 description = "Whether to power up the default Bluetooth controller on boot."; 51 }; 52 53 package = mkOption { 54 type = types.package; 55 default = pkgs.bluez; 56 defaultText = "pkgs.bluez"; 57 example = "pkgs.bluezFull"; 58 description = '' 59 Which BlueZ package to use. 60 61 <note><para> 62 Use the <literal>pkgs.bluezFull</literal> package to enable all 63 bluez plugins. 64 </para></note> 65 ''; 66 }; 67 68 disabledPlugins = mkOption { 69 type = types.listOf types.str; 70 default = [ ]; 71 description = "Built-in plugins to disable"; 72 }; 73 74 settings = mkOption { 75 type = cfgFmt.type; 76 default = { }; 77 example = { 78 General = { 79 ControllerMode = "bredr"; 80 }; 81 }; 82 description = "Set configuration for system-wide bluetooth (/etc/bluetooth/main.conf)."; 83 }; 84 }; 85 }; 86 87 ###### implementation 88 89 config = mkIf cfg.enable { 90 environment.systemPackages = [ package ] 91 ++ optional cfg.hsphfpd.enable pkgs.hsphfpd; 92 93 environment.etc."bluetooth/main.conf".source = 94 cfgFmt.generate "main.conf" (recursiveUpdate defaults cfg.settings); 95 services.udev.packages = [ package ]; 96 services.dbus.packages = [ package ] 97 ++ optional cfg.hsphfpd.enable pkgs.hsphfpd; 98 systemd.packages = [ package ]; 99 100 systemd.services = { 101 bluetooth = 102 let 103 # `man bluetoothd` will refer to main.conf in the nix store but bluez 104 # will in fact load the configuration file at /etc/bluetooth/main.conf 105 # so force it here to avoid any ambiguity and things suddenly breaking 106 # if/when the bluez derivation is changed. 107 args = [ "-f" "/etc/bluetooth/main.conf" ] 108 ++ optional hasDisabledPlugins 109 "--noplugin=${concatStringsSep "," cfg.disabledPlugins}"; 110 in 111 { 112 wantedBy = [ "bluetooth.target" ]; 113 aliases = [ "dbus-org.bluez.service" ]; 114 serviceConfig.ExecStart = [ 115 "" 116 "${package}/libexec/bluetooth/bluetoothd ${escapeShellArgs args}" 117 ]; 118 # restarting can leave people without a mouse/keyboard 119 unitConfig.X-RestartIfChanged = false; 120 }; 121 } 122 // (optionalAttrs cfg.hsphfpd.enable { 123 hsphfpd = { 124 after = [ "bluetooth.service" ]; 125 requires = [ "bluetooth.service" ]; 126 wantedBy = [ "bluetooth.target" ]; 127 128 description = "A prototype implementation used for connecting HSP/HFP Bluetooth devices"; 129 serviceConfig.ExecStart = "${pkgs.hsphfpd}/bin/hsphfpd.pl"; 130 }; 131 }); 132 133 systemd.user.services = { 134 obex.aliases = [ "dbus-org.bluez.obex.service" ]; 135 } 136 // optionalAttrs cfg.hsphfpd.enable { 137 telephony_client = { 138 wantedBy = [ "default.target" ]; 139 140 description = "telephony_client for hsphfpd"; 141 serviceConfig.ExecStart = "${pkgs.hsphfpd}/bin/telephony_client.pl"; 142 }; 143 }; 144 }; 145}