nixpkgs/nixos/modules/services/misc/gammu-smsd.nix
2024-08-28 22:40:21 +02:00

252 lines
7.8 KiB
Nix

{ pkgs, lib, config, ... }:
let
cfg = config.services.gammu-smsd;
configFile = pkgs.writeText "gammu-smsd.conf" ''
[gammu]
Device = ${cfg.device.path}
Connection = ${cfg.device.connection}
SynchronizeTime = ${if cfg.device.synchronizeTime then "yes" else "no"}
LogFormat = ${cfg.log.format}
${lib.optionalString (cfg.device.pin != null) "PIN = ${cfg.device.pin}"}
${cfg.extraConfig.gammu}
[smsd]
LogFile = ${cfg.log.file}
Service = ${cfg.backend.service}
${lib.optionalString (cfg.backend.service == "files") ''
InboxPath = ${cfg.backend.files.inboxPath}
OutboxPath = ${cfg.backend.files.outboxPath}
SentSMSPath = ${cfg.backend.files.sentSMSPath}
ErrorSMSPath = ${cfg.backend.files.errorSMSPath}
''}
${lib.optionalString (cfg.backend.service == "sql" && cfg.backend.sql.driver == "sqlite") ''
Driver = ${cfg.backend.sql.driver}
DBDir = ${cfg.backend.sql.database}
''}
${lib.optionalString (cfg.backend.service == "sql" && cfg.backend.sql.driver == "native_pgsql") (
with cfg.backend; ''
Driver = ${sql.driver}
${lib.optionalString (sql.database!= null) "Database = ${sql.database}"}
${lib.optionalString (sql.host != null) "Host = ${sql.host}"}
${lib.optionalString (sql.user != null) "User = ${sql.user}"}
${lib.optionalString (sql.password != null) "Password = ${sql.password}"}
'')}
${cfg.extraConfig.smsd}
'';
initDBDir = "share/doc/gammu/examples/sql";
gammuPackage = with cfg.backend; (pkgs.gammu.override {
dbiSupport = service == "sql" && sql.driver == "sqlite";
postgresSupport = service == "sql" && sql.driver == "native_pgsql";
});
in {
options = {
services.gammu-smsd = {
enable = lib.mkEnableOption "gammu-smsd daemon";
user = lib.mkOption {
type = lib.types.str;
default = "smsd";
description = "User that has access to the device";
};
device = {
path = lib.mkOption {
type = lib.types.path;
description = "Device node or address of the phone";
example = "/dev/ttyUSB2";
};
group = lib.mkOption {
type = lib.types.str;
default = "root";
description = "Owner group of the device";
example = "dialout";
};
connection = lib.mkOption {
type = lib.types.str;
default = "at";
description = "Protocol which will be used to talk to the phone";
};
synchronizeTime = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Whether to set time from computer to the phone during starting connection";
};
pin = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = "PIN code for the simcard";
};
};
log = {
file = lib.mkOption {
type = lib.types.str;
default = "syslog";
description = "Path to file where information about communication will be stored";
};
format = lib.mkOption {
type = lib.types.enum [ "nothing" "text" "textall" "textalldate" "errors" "errorsdate" "binary" ];
default = "errors";
description = "Determines what will be logged to the LogFile";
};
};
extraConfig = {
gammu = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Extra config lines to be added into [gammu] section";
};
smsd = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Extra config lines to be added into [smsd] section";
};
};
backend = {
service = lib.mkOption {
type = lib.types.enum [ "null" "files" "sql" ];
default = "null";
description = "Service to use to store sms data.";
};
files = {
inboxPath = lib.mkOption {
type = lib.types.path;
default = "/var/spool/sms/inbox/";
description = "Where the received SMSes are stored";
};
outboxPath = lib.mkOption {
type = lib.types.path;
default = "/var/spool/sms/outbox/";
description = "Where SMSes to be sent should be placed";
};
sentSMSPath = lib.mkOption {
type = lib.types.path;
default = "/var/spool/sms/sent/";
description = "Where the transmitted SMSes are placed";
};
errorSMSPath = lib.mkOption {
type = lib.types.path;
default = "/var/spool/sms/error/";
description = "Where SMSes with error in transmission is placed";
};
};
sql = {
driver = lib.mkOption {
type = lib.types.enum [ "native_mysql" "native_pgsql" "odbc" "dbi" ];
description = "DB driver to use";
};
sqlDialect = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = "SQL dialect to use (odbc driver only)";
};
database = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = "Database name to store sms data";
};
host = lib.mkOption {
type = lib.types.str;
default = "localhost";
description = "Database server address";
};
user = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = "User name used for connection to the database";
};
password = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = "User password used for connection to the database";
};
};
};
};
};
config = lib.mkIf cfg.enable {
users.users.${cfg.user} = {
description = "gammu-smsd user";
isSystemUser = true;
group = cfg.device.group;
};
environment.systemPackages = with cfg.backend; [ gammuPackage ]
++ lib.optionals (service == "sql" && sql.driver == "sqlite") [ pkgs.sqlite ];
systemd.services.gammu-smsd = {
description = "gammu-smsd daemon";
wantedBy = [ "multi-user.target" ];
wants = with cfg.backend; [ ]
++ lib.optionals (service == "sql" && sql.driver == "native_pgsql") [ "postgresql.service" ];
preStart = with cfg.backend;
lib.optionalString (service == "files") (with files; ''
mkdir -m 755 -p ${inboxPath} ${outboxPath} ${sentSMSPath} ${errorSMSPath}
chown ${cfg.user} -R ${inboxPath}
chown ${cfg.user} -R ${outboxPath}
chown ${cfg.user} -R ${sentSMSPath}
chown ${cfg.user} -R ${errorSMSPath}
'')
+ lib.optionalString (service == "sql" && sql.driver == "sqlite") ''
cat "${gammuPackage}/${initDBDir}/sqlite.sql" \
| ${pkgs.sqlite.bin}/bin/sqlite3 ${sql.database}
''
+ (let execPsql = extraArgs: lib.concatStringsSep " " [
(lib.optionalString (sql.password != null) "PGPASSWORD=${sql.password}")
"${config.services.postgresql.package}/bin/psql"
(lib.optionalString (sql.host != null) "-h ${sql.host}")
(lib.optionalString (sql.user != null) "-U ${sql.user}")
"$extraArgs"
"${sql.database}"
]; in lib.optionalString (service == "sql" && sql.driver == "native_pgsql") ''
echo '\i '"${gammuPackage}/${initDBDir}/pgsql.sql" | ${execPsql ""}
'');
serviceConfig = {
User = "${cfg.user}";
Group = "${cfg.device.group}";
PermissionsStartOnly = true;
ExecStart = "${gammuPackage}/bin/gammu-smsd -c ${configFile}";
};
};
};
}