{ lib, pkgs, cfg, models, allPhones }: let hasTrunk = cfg.sipTrunks != {}; # Import provisioning templates for models that support it. # Each template exports: desktopSize, thumbnailSize, mkFiles templates = lib.mapAttrs (modelName: _: import ./templates/${modelName}.nix { inherit lib; } ) (lib.filterAttrs (_: m: m.hasProvisioning) models); # Page extensions for the intercom button auto-dial pageExtension = let pages = lib.attrNames (lib.filterAttrs (_: e: e.mode == "page") cfg.extensions); in if pages != [] then lib.head pages else null; hasIntercomButton = cfg.intercomPrefix != null && pageExtension != null; # Collect all internal extension numbers to generate exact-match patterns. # This tells the phone "this number is complete" so it dials immediately # rather than waiting for the timeout or firing on the first digit. allExtensions = lib.unique ( lib.mapAttrsToList (_: p: p.extension) cfg.sharedPhones ++ lib.mapAttrsToList (_: p: p.extension) cfg.persons ); # Star extensions: intercom prefix + each extension, plus custom extensions. allStarExtensions = (lib.optionals (cfg.intercomPrefix != null) (map (ext: "${cfg.intercomPrefix}${ext}") allExtensions)) ++ lib.attrNames cfg.extensions ++ lib.optional (cfg.sharedMailbox != null) cfg.sharedMailbox.checkExtension; backgroundEntries = import ./backgrounds.nix { inherit lib pkgs cfg templates allPhones; }; in pkgs.linkFarm "voip-tftp-root" ( lib.concatLists (lib.mapAttrsToList (key: phone: let m = models.${phone.model}; in lib.optionals m.hasProvisioning ( let t = templates.${phone.model}; familyLineEnabled = hasTrunk && phone.personKey != null && phone.sharedLine; intercomLineIndex = if familyLineEnabled then 3 else 2; # BLF targets: all persons except the one owning this phone blfPersons = lib.filter (p: p.extension != phone.extension) (lib.mapAttrsToList (_: person: { inherit (person) extension displayName; }) cfg.persons); files = t.mkFiles ({ mac = key; inherit (phone) label password displayName; inherit blfPersons; serverAddress = cfg.serverAddress; ntpServer = cfg.ntpServer; sipPort = cfg.sipPort; directoryPort = cfg.directoryPort; inherit allExtensions allStarExtensions hasTrunk hasIntercomButton pageExtension intercomLineIndex; } // lib.optionalAttrs (cfg.intercomPrefix != null) { intercomEnabled = true; intercomPassword = phone.password; } // lib.optionalAttrs familyLineEnabled { inherit familyLineEnabled; familyLineLabel = if cfg.sharedMailbox != null then cfg.sharedMailbox.displayName else "Familie"; familyLinePassword = phone.password; }); in map (f: { inherit (f) name; path = pkgs.writeText f.name f.content; }) files ) ) allPhones) ++ backgroundEntries )