parent
fba98bad71
commit
a9b7300f6f
@ -0,0 +1,115 @@ |
||||
{ config, lib, pkgs, ... }: |
||||
|
||||
with lib; |
||||
|
||||
let |
||||
cfg = config.hardware.sane.brscan5; |
||||
|
||||
netDeviceList = attrValues cfg.netDevices; |
||||
|
||||
etcFiles = pkgs.callPackage ./brscan5_etc_files.nix { netDevices = netDeviceList; }; |
||||
|
||||
netDeviceOpts = { name, ... }: { |
||||
|
||||
options = { |
||||
|
||||
name = mkOption { |
||||
type = types.str; |
||||
description = '' |
||||
The friendly name you give to the network device. If undefined, |
||||
the name of attribute will be used. |
||||
''; |
||||
|
||||
example = literalExample "office1"; |
||||
}; |
||||
|
||||
model = mkOption { |
||||
type = types.str; |
||||
description = '' |
||||
The model of the network device. |
||||
''; |
||||
|
||||
example = literalExample "MFC-7860DW"; |
||||
}; |
||||
|
||||
ip = mkOption { |
||||
type = with types; nullOr str; |
||||
default = null; |
||||
description = '' |
||||
The ip address of the device. If undefined, you will have to |
||||
provide a nodename. |
||||
''; |
||||
|
||||
example = literalExample "192.168.1.2"; |
||||
}; |
||||
|
||||
nodename = mkOption { |
||||
type = with types; nullOr str; |
||||
default = null; |
||||
description = '' |
||||
The node name of the device. If undefined, you will have to |
||||
provide an ip. |
||||
''; |
||||
|
||||
example = literalExample "BRW0080927AFBCE"; |
||||
}; |
||||
|
||||
}; |
||||
|
||||
|
||||
config = |
||||
{ name = mkDefault name; |
||||
}; |
||||
}; |
||||
|
||||
in |
||||
|
||||
{ |
||||
options = { |
||||
|
||||
hardware.sane.brscan5.enable = |
||||
mkEnableOption "Brother's brscan5 scan backend" // { |
||||
description = '' |
||||
When enabled, will automatically register the "brscan5" sane |
||||
backend and bring configuration files to their expected location. |
||||
''; |
||||
}; |
||||
|
||||
hardware.sane.brscan5.netDevices = mkOption { |
||||
default = {}; |
||||
example = |
||||
{ office1 = { model = "MFC-7860DW"; ip = "192.168.1.2"; }; |
||||
office2 = { model = "MFC-7860DW"; nodename = "BRW0080927AFBCE"; }; |
||||
}; |
||||
type = with types; attrsOf (submodule netDeviceOpts); |
||||
description = '' |
||||
The list of network devices that will be registered against the brscan5 |
||||
sane backend. |
||||
''; |
||||
}; |
||||
}; |
||||
|
||||
config = mkIf (config.hardware.sane.enable && cfg.enable) { |
||||
|
||||
hardware.sane.extraBackends = [ |
||||
pkgs.brscan5 |
||||
]; |
||||
|
||||
environment.etc."opt/brother/scanner/brscan5" = |
||||
{ source = "${etcFiles}/etc/opt/brother/scanner/brscan5"; }; |
||||
environment.etc."opt/brother/scanner/models" = |
||||
{ source = "${etcFiles}/etc/opt/brother/scanner/brscan5/models"; }; |
||||
environment.etc."sane.d/dll.d/brother5.conf".source = "${pkgs.brscan5}/etc/sane.d/dll.d/brother.conf"; |
||||
|
||||
assertions = [ |
||||
{ assertion = all (x: !(null != x.ip && null != x.nodename)) netDeviceList; |
||||
message = '' |
||||
When describing a network device as part of the attribute list |
||||
`hardware.sane.brscan5.netDevices`, only one of its `ip` or `nodename` |
||||
attribute should be specified, not both! |
||||
''; |
||||
} |
||||
]; |
||||
|
||||
}; |
||||
} |
@ -0,0 +1,77 @@ |
||||
{ stdenv, lib, brscan5, netDevices ? [] }: |
||||
|
||||
/* |
||||
|
||||
Testing |
||||
------- |
||||
From nixpkgs repo |
||||
|
||||
No net devices: |
||||
|
||||
~~~ |
||||
nix-build -E 'let pkgs = import ./. {}; |
||||
brscan5-etc-files = pkgs.callPackage (import ./nixos/modules/services/hardware/sane_extra_backends/brscan5_etc_files.nix) {}; |
||||
in brscan5-etc-files' |
||||
~~~ |
||||
|
||||
Two net devices: |
||||
|
||||
~~~ |
||||
nix-build -E 'let pkgs = import ./. {}; |
||||
brscan5-etc-files = pkgs.callPackage (import ./nixos/modules/services/hardware/sane_extra_backends/brscan5_etc_files.nix) {}; |
||||
in brscan5-etc-files.override { |
||||
netDevices = [ |
||||
{name="a"; model="MFC-7860DW"; nodename="BRW0080927AFBCE";} |
||||
{name="b"; model="MFC-7860DW"; ip="192.168.1.2";} |
||||
]; |
||||
}' |
||||
~~~ |
||||
|
||||
*/ |
||||
|
||||
let |
||||
|
||||
addNetDev = nd: '' |
||||
brsaneconfig5 -a \ |
||||
name="${nd.name}" \ |
||||
model="${nd.model}" \ |
||||
${if (lib.hasAttr "nodename" nd && nd.nodename != null) then |
||||
''nodename="${nd.nodename}"'' else |
||||
''ip="${nd.ip}"''}''; |
||||
addAllNetDev = xs: lib.concatStringsSep "\n" (map addNetDev xs); |
||||
in |
||||
|
||||
stdenv.mkDerivation { |
||||
|
||||
name = "brscan5-etc-files"; |
||||
version = "1.2.6-0"; |
||||
src = "${brscan5}/opt/brother/scanner/brscan5"; |
||||
|
||||
nativeBuildInputs = [ brscan5 ]; |
||||
|
||||
dontConfigure = true; |
||||
|
||||
buildPhase = '' |
||||
TARGET_DIR="$out/etc/opt/brother/scanner/brscan5" |
||||
mkdir -p "$TARGET_DIR" |
||||
cp -rp "./models" "$TARGET_DIR" |
||||
cp -rp "./brscan5.ini" "$TARGET_DIR" |
||||
cp -rp "./brsanenetdevice.cfg" "$TARGET_DIR" |
||||
|
||||
export NIX_REDIRECTS="/etc/opt/brother/scanner/brscan5//brsanenetdevice.cfg=$TARGET_DIR/brsanenetdevice.cfg" |
||||
|
||||
printf '${addAllNetDev netDevices}\n' |
||||
|
||||
${addAllNetDev netDevices} |
||||
''; |
||||
|
||||
dontInstall = true; |
||||
|
||||
meta = with lib; { |
||||
description = "Brother brscan5 sane backend driver etc files"; |
||||
homepage = "https://www.brother.com"; |
||||
platforms = platforms.linux; |
||||
license = licenses.unfree; |
||||
maintainers = with maintainers; [ mattchrist ]; |
||||
}; |
||||
} |
@ -0,0 +1,34 @@ |
||||
# integration tests for brscan5 sane driver |
||||
# |
||||
|
||||
import ./make-test-python.nix ({ pkgs, ...} : { |
||||
name = "brscan5"; |
||||
meta = with pkgs.lib.maintainers; { |
||||
maintainers = [ mattchrist ]; |
||||
}; |
||||
|
||||
machine = { pkgs, ... }: |
||||
{ |
||||
nixpkgs.config.allowUnfree = true; |
||||
hardware.sane = { |
||||
enable = true; |
||||
brscan5 = { |
||||
enable = true; |
||||
netDevices = { |
||||
"a" = { model="MFC-7860DW"; nodename="BRW0080927AFBCE"; }; |
||||
"b" = { model="MFC-7860DW"; ip="192.168.1.2"; }; |
||||
}; |
||||
}; |
||||
}; |
||||
}; |
||||
|
||||
testScript = '' |
||||
# sane loads libsane-brother5.so.1 successfully, and scanimage doesn't die |
||||
assert 'libsane-brother5.so.1", O_RDONLY|O_CLOEXEC) = 10' in machine.succeed('strace scanimage -L 2>&1') |
||||
|
||||
# module creates a config |
||||
cfg = machine.succeed('cat /etc/opt/brother/scanner/brscan5/brsanenetdevice.cfg') |
||||
assert 'DEVICE=a , "MFC-7860DW" , Unknown , NODENAME=BRW0080927AFBCE' in cfg |
||||
assert 'DEVICE=b , "MFC-7860DW" , Unknown , IP-ADDRESS=192.168.1.2' in cfg |
||||
''; |
||||
}) |
@ -0,0 +1,98 @@ |
||||
{ stdenv, lib, fetchurl, callPackage, patchelf, makeWrapper, coreutils, libusb1, avahi-compat, glib, libredirect }: |
||||
let |
||||
myPatchElf = file: with lib; '' |
||||
patchelf --set-interpreter \ |
||||
${stdenv.glibc}/lib/ld-linux${optionalString stdenv.is64bit "-x86-64"}.so.2 \ |
||||
${file} |
||||
''; |
||||
|
||||
in |
||||
stdenv.mkDerivation rec { |
||||
pname = "brscan5"; |
||||
version = "1.2.6-0"; |
||||
src = { |
||||
"i686-linux" = fetchurl { |
||||
url = "https://download.brother.com/welcome/dlf104034/${pname}-${version}.i386.deb"; |
||||
sha256 = "102q745pc0168syggd4gym51qf3m3iqld3a4skfnbkm6yky4w4s8"; |
||||
}; |
||||
"x86_64-linux" = fetchurl { |
||||
url = "https://download.brother.com/welcome/dlf104033/${pname}-${version}.amd64.deb"; |
||||
sha256 = "1pwbzhpg5nzpw2rw936vf2cr334v8iny16y8fbb1zimgzmv427wx"; |
||||
}; |
||||
}."${stdenv.hostPlatform.system}"; |
||||
|
||||
unpackPhase = '' |
||||
ar x $src |
||||
tar xfv data.tar.xz |
||||
''; |
||||
|
||||
nativeBuildInputs = [ makeWrapper patchelf coreutils ]; |
||||
buildInputs = [ libusb1 avahi-compat stdenv.cc.cc glib ]; |
||||
dontBuild = true; |
||||
|
||||
postPatch = '' |
||||
${myPatchElf "opt/brother/scanner/brscan5/brsaneconfig5"} |
||||
${myPatchElf "opt/brother/scanner/brscan5/brscan_cnetconfig"} |
||||
${myPatchElf "opt/brother/scanner/brscan5/brscan_gnetconfig"} |
||||
|
||||
for a in opt/brother/scanner/brscan5/*.so.* opt/brother/scanner/brscan5/brscan_[cg]netconfig; do |
||||
if ! test -L $a; then |
||||
patchelf --set-rpath ${lib.makeLibraryPath buildInputs} $a |
||||
fi |
||||
done |
||||
|
||||
# driver is hardcoded to look in /opt/brother/scanner/brscan5/models for model metadata. |
||||
# patch it to look in /etc/opt/brother/scanner/models instead, so nixos environment.etc can make it available |
||||
printf '/etc/opt/brother/scanner/models\x00' | dd of=opt/brother/scanner/brscan5/libsane-brother5.so.1.0.7 bs=1 seek=84632 conv=notrunc |
||||
''; |
||||
|
||||
installPhase = with lib; '' |
||||
runHook preInstall |
||||
PATH_TO_BRSCAN5="opt/brother/scanner/brscan5" |
||||
mkdir -p $out/$PATH_TO_BRSCAN5 |
||||
cp -rp $PATH_TO_BRSCAN5/* $out/$PATH_TO_BRSCAN5 |
||||
|
||||
|
||||
pushd $out/$PATH_TO_BRSCAN5 |
||||
ln -s libLxBsDeviceAccs.so.1.0.0 libLxBsDeviceAccs.so.1 |
||||
ln -s libLxBsNetDevAccs.so.1.0.0 libLxBsNetDevAccs.so.1 |
||||
ln -s libLxBsScanCoreApi.so.3.0.0 libLxBsScanCoreApi.so.3 |
||||
ln -s libLxBsUsbDevAccs.so.1.0.0 libLxBsUsbDevAccs.so.1 |
||||
ln -s libsane-brother5.so.1.0.7 libsane-brother5.so.1 |
||||
popd |
||||
|
||||
mkdir -p $out/lib/sane |
||||
for file in $out/$PATH_TO_BRSCAN5/*.so.* ; do |
||||
ln -s $file $out/lib/sane/ |
||||
done |
||||
|
||||
makeWrapper \ |
||||
"$out/$PATH_TO_BRSCAN5/brsaneconfig5" \ |
||||
"$out/bin/brsaneconfig5" \ |
||||
--suffix-each NIX_REDIRECT ":" "/etc/opt/brother/scanner/brscan5=$out/opt/brother/scanner/brscan5 /opt/brother/scanner/brscan5=$out/opt/brother/scanner/brscan5" \ |
||||
--set LD_PRELOAD ${libredirect}/lib/libredirect.so |
||||
|
||||
mkdir -p $out/etc/sane.d/dll.d |
||||
echo "brother5" > $out/etc/sane.d/dll.d/brother5.conf |
||||
|
||||
mkdir -p $out/etc/udev/rules.d |
||||
cp -p $PATH_TO_BRSCAN5/udev-rules/NN-brother-mfp-brscan5-1.0.2-2.rules \ |
||||
$out/etc/udev/rules.d/49-brother-mfp-brscan5-1.0.2-2.rules |
||||
|
||||
ETCDIR=$out/etc/opt/brother/scanner/brscan5 |
||||
mkdir -p $ETCDIR |
||||
cp -rp $PATH_TO_BRSCAN5/{models,brscan5.ini,brsanenetdevice.cfg} $ETCDIR/ |
||||
|
||||
runHook postInstall |
||||
''; |
||||
|
||||
dontPatchELF = true; |
||||
|
||||
meta = { |
||||
description = "Brother brscan5 sane backend driver"; |
||||
homepage = "https://www.brother.com"; |
||||
platforms = [ "i686-linux" "x86_64-linux" ]; |
||||
license = lib.licenses.unfree; |
||||
maintainers = with lib.maintainers; [ mattchrist ]; |
||||
}; |
||||
} |
Loading…
Reference in new issue