{ config, ... }: let address = "10.0.10.2"; in { imports = [ ./hardware.nix ./disko.nix ../../modules/voip ]; networking.hostName = "telefonmann"; networking.interfaces.ens19 = { ipv4.addresses = [{ address = address; prefixLength = 24; }]; }; services.voip = { enable = true; serverAddress = address; ntpServer = "10.0.10.1"; # directoryName = "tel.baubs.net"; # shown in phone directory title and HTML page header # directoryPort = 8080; # HTTP port for directory, intercom XML, and status page # sipPort = 5060; # SIP TCP/UDP port # rtpStart = 10000; # RTP port range start # rtpEnd = 20000; # RTP port range end sharedPhones = { "e0899d946ccc" = { model = "cisco-8961"; extension = "20"; displayName = "Küche"; label = "Küchentelefon"; # shown on the phone screen (max ~12 chars) password = "changeme100"; }; "e0899d947650" = { model = "cisco-8961"; extension = "22"; displayName = "Flur"; label = "Flur"; password = "changeme100"; }; "fromschofon" = { model = "sip-client"; extension = "23"; displayName = "Frosch"; label = "Frosch"; password = "changeme102"; }; }; persons = { "jannel" = { extension = "21"; displayName = "Jannel"; mailbox = true; # ringTimeout = 30; # seconds to ring before going to voicemail mailboxGreeting = ./greetings/anrufbeantworter.wav; phones = { "jannel-mobile" = { model = "sip-client"; password = "changeme101"; }; }; }; }; backgroundImages = { "Wombel" = ./backgrounds/wombel.png; }; intercomPrefix = "*80"; # generates e.g. *8020, *8021, *8022 per extension mohClasses = { "default" = { files = [ ./music/vapor.mp3 ]; sort = "random"; # sort = "alphabetical"; }; # add more classes here and reference them per-DID via musicOnHold = "classname" }; sipTrunks = { "ewe1" = { hostFile = config.age.secrets."voip-trunk-ewe-host".path; usernameFile = config.age.secrets."voip-trunk-ewe1-username".path; passwordFile = config.age.secrets."voip-trunk-ewe1-password".path; callerIdFile = config.age.secrets."voip-trunk-ewe1-callerid".path; codecs = [ "g722" "alaw" "ulaw" ]; }; "ewe2" = { hostFile = config.age.secrets."voip-trunk-ewe-host".path; usernameFile = config.age.secrets."voip-trunk-ewe2-username".path; passwordFile = config.age.secrets."voip-trunk-ewe2-password".path; callerIdFile = config.age.secrets."voip-trunk-ewe2-callerid".path; codecs = [ "g722" "alaw" "ulaw" ]; }; "ewe3" = { hostFile = config.age.secrets."voip-trunk-ewe-host".path; usernameFile = config.age.secrets."voip-trunk-ewe3-username".path; passwordFile = config.age.secrets."voip-trunk-ewe3-password".path; callerIdFile = config.age.secrets."voip-trunk-ewe3-callerid".path; codecs = [ "g722" "alaw" "ulaw" ]; }; }; sharedMailbox = { mailboxId = "200"; checkExtension = "*98"; displayName = "Baubse"; greeting = ./greetings/anrufbeantworter.wav; }; dids = { "baubse" = { numberFile = config.age.secrets."voip-trunk-ewe1-callerid".path; trunk = "ewe1"; displayName = "Baubse"; routing = { type = "all"; # ring all phones (sharedPhones + persons) on their L2 line # timeout = 30; # seconds to ring before falling through to mailbox }; mailbox = "shared"; # → sharedMailbox on no answer musicOnHold = "default"; }; "jannel" = { numberFile = config.age.secrets."voip-trunk-ewe2-callerid".path; trunk = "ewe2"; displayName = "Jannel"; routing = { type = "person"; person = "jannel"; # ring jannel's phones on their L1 line # timeout = 30; }; mailbox = "person"; # → jannel's personal mailbox on no answer # musicOnHold = "default"; }; # ewe3 DID — uncomment and fill in number when known: # "ewe3-main" = { # number = ""; # or: numberFile = ./secrets/did-ewe3; # trunk = "ewe3"; # displayName = "..."; # routing = { type = "all"; }; # mailbox = "shared"; # }; }; extensions = { "*99" = { mode = "page"; displayName = "Durchsage an alle"; }; "*100" = { mode = "all"; displayName = "Alle rufen"; }; # custom app extension example: # "*00" = { mode = "app"; displayName = "Echo test"; app = "Echo()"; }; }; }; # Age-encrypted secrets (decrypted on the host at activation time). age.secrets = let asteriskSecret = file: { inherit file; owner = "asterisk"; group = "voip-keys"; mode = "0640"; }; in { "voip-trunk-ewe-host" = asteriskSecret ../../secrets/voip-trunk-ewe-host.age; "voip-trunk-ewe1-username" = asteriskSecret ../../secrets/voip-trunk-ewe1-username.age; "voip-trunk-ewe1-password" = asteriskSecret ../../secrets/voip-trunk-ewe1-password.age; "voip-trunk-ewe1-callerid" = asteriskSecret ../../secrets/voip-trunk-ewe1-callerid.age; "voip-trunk-ewe2-username" = asteriskSecret ../../secrets/voip-trunk-ewe2-username.age; "voip-trunk-ewe2-password" = asteriskSecret ../../secrets/voip-trunk-ewe2-password.age; "voip-trunk-ewe2-callerid" = asteriskSecret ../../secrets/voip-trunk-ewe2-callerid.age; "voip-trunk-ewe3-username" = asteriskSecret ../../secrets/voip-trunk-ewe3-username.age; "voip-trunk-ewe3-password" = asteriskSecret ../../secrets/voip-trunk-ewe3-password.age; "voip-trunk-ewe3-callerid" = asteriskSecret ../../secrets/voip-trunk-ewe3-callerid.age; }; }