1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7
8let
9 inherit (lib)
10 types
11 ;
12
13 inherit (lib.strings)
14 concatStringsSep
15 optionalString
16 ;
17
18 inherit (lib.attrsets)
19 filterAttrs
20 mapAttrsToList
21 mapAttrs'
22 ;
23
24 inherit (lib.modules)
25 mkIf
26 ;
27
28 inherit (lib.options)
29 mkEnableOption
30 mkOption
31 mkPackageOption
32 ;
33
34 cfg = config.services.ax25.axports;
35
36 enabledAxports = filterAttrs (ax25Name: cfg: cfg.enable) cfg;
37
38 axportsOpts = {
39
40 options = {
41 enable = mkEnableOption "Enables the axport interface";
42
43 package = mkPackageOption pkgs "ax25-tools" { };
44
45 tty = mkOption {
46 type = types.str;
47 example = "/dev/ttyACM0";
48 description = ''
49 Location of hardware kiss tnc for this interface.
50 '';
51 };
52
53 callsign = mkOption {
54 type = types.str;
55 example = "WB6WLV-7";
56 description = ''
57 The callsign of the physical interface to bind to.
58 '';
59 };
60
61 description = mkOption {
62 type = types.str;
63 # This cannot be empty since some ax25 tools cant parse /etc/ax25/axports without it
64 default = "NixOS managed tnc";
65 description = ''
66 Free format description of this interface.
67 '';
68 };
69
70 baud = mkOption {
71 type = types.int;
72 example = 57600;
73 description = ''
74 The serial port speed of this interface.
75 '';
76 };
77
78 paclen = mkOption {
79 type = types.int;
80 default = 255;
81 description = ''
82 Default maximum packet size for this interface.
83 '';
84 };
85
86 window = mkOption {
87 type = types.int;
88 default = 7;
89 description = ''
90 Default window size for this interface.
91 '';
92 };
93
94 kissParams = mkOption {
95 type = types.nullOr types.str;
96 default = null;
97 example = "-t 300 -l 10 -s 12 -r 80 -f n";
98 description = ''
99 Kissattach parameters for this interface.
100 '';
101 };
102 };
103 };
104in
105{
106
107 options = {
108
109 services.ax25.axports = mkOption {
110 type = types.attrsOf (types.submodule axportsOpts);
111 default = { };
112 description = "Specification of one or more AX.25 ports.";
113 };
114 };
115
116 config = mkIf (enabledAxports != { }) {
117
118 environment.etc."ax25/axports" = {
119 text = concatStringsSep "\n" (
120 mapAttrsToList (
121 portName: portCfg:
122 "${portName} ${portCfg.callsign} ${toString portCfg.baud} ${toString portCfg.paclen} ${toString portCfg.window} ${portCfg.description}"
123 ) enabledAxports
124 );
125 mode = "0644";
126 };
127
128 systemd.targets.ax25-axports = {
129 description = "AX.25 axports group target";
130 };
131
132 systemd.services = mapAttrs' (portName: portCfg: {
133 name = "ax25-kissattach-${portName}";
134 value = {
135 description = "AX.25 KISS attached interface for ${portName}";
136 wantedBy = [ "multi-user.target" ];
137 before = [ "ax25-axports.target" ];
138 partOf = [ "ax25-axports.target" ];
139 serviceConfig = {
140 Type = "exec";
141 ExecStart = "${portCfg.package}/bin/kissattach ${portCfg.tty} ${portName}";
142 };
143 postStart = optionalString (portCfg.kissParams != null) ''
144 ${portCfg.package}/bin/kissparms -p ${portName} ${portCfg.kissParams}
145 '';
146 };
147 }) enabledAxports;
148 };
149}