diff --git a/modules/cdc-ncm/default.nix b/modules/cdc-ncm/default.nix index 93f1d6c..c6aff82 100644 --- a/modules/cdc-ncm/default.nix +++ b/modules/cdc-ncm/default.nix @@ -4,6 +4,10 @@ let inherit (lib) mkOption types; svc = config.system.service; in { + imports = [ + ../service-trigger + ]; + options = { system.service.wwan = mkOption { type = liminix.lib.types.serviceDefn; diff --git a/modules/cdc-ncm/wwan.nix b/modules/cdc-ncm/wwan.nix index b9deb4c..6c177be 100644 --- a/modules/cdc-ncm/wwan.nix +++ b/modules/cdc-ncm/wwan.nix @@ -53,11 +53,16 @@ let buildInputs = [ modeswitch ]; run = "${uevent-watch}/bin/uevent-watch -s ${modeswitch.name} devtype=usb_device product=12d1/14fe/102"; }) - (longrun { - name = "watch-for-modem"; - isTrigger = true; - buildInputs = [ atz ]; - run = "${uevent-watch}/bin/uevent-watch -n /dev/modem -s ${atz.name} subsystem=tty attrs.idVendor=12d1 attrs.idProduct=1506"; + (svc.uevent-rule.build { + service = atz; + terms = { + subsystem = "tty"; + attrs = { + idVendor = "12d1"; + idProduct = "1506"; + }; + }; + symlink = "/dev/modem"; }) ]; }; diff --git a/modules/service-trigger/default.nix b/modules/service-trigger/default.nix new file mode 100644 index 0000000..eb3f7bd --- /dev/null +++ b/modules/service-trigger/default.nix @@ -0,0 +1,37 @@ +# this is unlikely to be the final form or location of this code, it's +# an interim module which wraps the uevent-watch command + +{ lib, pkgs, config, ... }: +let + inherit (lib) mkOption types; + inherit (pkgs) liminix; +# inherit (pkgs.liminix.services) bundle; +in { + options = { + system.service.uevent-rule = mkOption { + description = "a service which starts other services based on device state (sysfs)"; + type = liminix.lib.types.serviceDefn; + }; + }; + config = { + system.service.uevent-rule = liminix.callService ./rule.nix { + service = mkOption { + description = "the service to run when the rule matches"; + type = liminix.lib.types.service; + }; + terms = mkOption { + type = types.attrs; + example = { + devtype = "usb_device"; + attrs.idVendor = "8086"; + }; + default = {}; + }; + symlink = mkOption { + description = "create symlink targeted on devpath"; + type = types.nullOr types.str; + default = null; + }; + }; + }; +} diff --git a/modules/service-trigger/rule.nix b/modules/service-trigger/rule.nix new file mode 100644 index 0000000..a0d7578 --- /dev/null +++ b/modules/service-trigger/rule.nix @@ -0,0 +1,25 @@ +{ + liminix +, uevent-watch +, serviceFns +, lib }: +{ + service, terms, symlink +}: +let + inherit (liminix.services) longrun; + inherit (lib.attrsets) collect mapAttrsRecursive; + inherit (lib.strings) concatStringsSep; + stringify = attrs : + concatStringsSep " " + (collect lib.isString + (mapAttrsRecursive + (path : value : "${concatStringsSep "." path}=${value}") + attrs)); + termsString = stringify terms; +in longrun { + name = "watch-for-${service.name}"; + isTrigger = true; + buildInputs = [ service ]; + run = "${uevent-watch}/bin/uevent-watch ${if symlink != null then "-n ${symlink}" else ""} -s ${service.name} ${termsString}"; +}