diff --git a/nix/configuration.nix b/nix/configuration.nix index c52c50f..461f410 100644 --- a/nix/configuration.nix +++ b/nix/configuration.nix @@ -22,6 +22,9 @@ }; cleanTmpDir = true; kernelPackages = pkgs.linuxPackages_latest; + extraModulePackages = with config.boot.kernelPackages; [ + rtl8821ce + ]; }; networking = { @@ -110,6 +113,13 @@ cliphist jq bash-language-server + duckdb + sqlite + usbutils + llvmPackages_19.clang-tools + ghc + hyprpaper + (anki-bin.overrideAttrs { src = pkgs.fetchurl { url = "https://github.com/ankitects/anki/releases/download/24.11rc2/anki-24.11-linux-qt6.tar.zst"; @@ -177,6 +187,7 @@ }; }; + hardware.enableAllFirmware = true; hardware.bluetooth = { enable = true; powerOnBoot = true; @@ -328,4 +339,12 @@ services.usbmuxd.enable = true; programs.nix-ld.enable = true; + + systemd.services.fix-crappy-bluetooth = { + wantedBy = [ "post-resume.target" ]; + after = [ "post-resume.target" ]; + script = builtins.readFile ./scripts/hack.usb.reset; + scriptArgs = "0bda:c831"; + serviceConfig.Type = "oneshot"; + }; } diff --git a/nix/flake.lock b/nix/flake.lock index 2f5a6dc..160d333 100644 --- a/nix/flake.lock +++ b/nix/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1732014248, - "narHash": "sha256-y/MEyuJ5oBWrWAic/14LaIr/u5E0wRVzyYsouYY3W6w=", + "lastModified": 1732521221, + "narHash": "sha256-2ThgXBUXAE1oFsVATK1ZX9IjPcS4nKFOAjhPNKuiMn0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "23e89b7da85c3640bbc2173fe04f4bd114342367", + "rev": "4633a7c72337ea8fd23a4f2ba3972865e3ec685d", "type": "github" }, "original": { diff --git a/nix/scripts/hack.usb.reset b/nix/scripts/hack.usb.reset new file mode 100644 index 0000000..09fe9f1 --- /dev/null +++ b/nix/scripts/hack.usb.reset @@ -0,0 +1,81 @@ +#!/usr/bin/env bash + +# +# Resets the specified bluetooth USB adapter. +# Restarts bluetooth service. +# +# This is to work around an issue where after suspend, the bluetooth adapter is +# not working and needed to be unplugged and re-plugged. +# +# This inelegant script basically automates this. +# + +set -e +set -u +PS4=" $ " +#set -x + +# +# Values can be found using `lsusb`: +# +# Bus xxx Device yyy: ID VVVV:PPPP Integrated System Solution Corp. Bluetooth Device +# ^ ^ +# ID_VENDOR-/ / +# ID_PRODUCT-/ +# +ID_VENDOR="${1/:*/}" +ID_PRODUCT="${1/*:/}" + +_reset_paths() { + for p in "$@"; do + echo 0 > "$p"/authorized + sleep 1 + echo 1 > "$p"/authorized + done +} + +# +# Main function for the script. +# +main() { + echo "Resetting USB bluetooth devices." + # Not strictly needed, but stops bluetooth. + # It will, in any way, be started at the end. + systemctl stop bluetooth + sleep 4 + + # Using a function allows use of local and declare. + local p + local found_vnd + local found_prd + declare -a paths + + # For all usb devices, + for p in /sys/bus/usb/devices/*; do + # Try to check vendor/product IDs + found_vnd="$(cat "$p/idVendor" 2>/dev/null)" || : + found_prd="$(cat "$p/idProduct" 2>/dev/null)" || : + + # When both match + if [[ "$found_vnd" == "$ID_VENDOR" && "$found_prd" == "$ID_PRODUCT" ]]; then + # Add to valid paths + paths+=("$p") + fi + done + + # Reset all paths + _reset_paths "${paths[@]}" + sleep 1 + # Twice for good luck + _reset_paths "${paths[@]}" + + # Waits for everything to settle down + sleep 2 + + # Restarts bluetooth. + systemctl restart bluetooth + echo "Done resetting USB bluetooth devices." +} + +# Calls up main. +main "$@"