at 25.11-pre 4.0 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 utils, 6 ... 7}: 8let 9 10 uid = config.ids.uids.gpsd; 11 gid = config.ids.gids.gpsd; 12 cfg = config.services.gpsd; 13 14in 15{ 16 17 ###### interface 18 19 imports = [ 20 (lib.mkRemovedOptionModule [ "services" "gpsd" "device" ] "Use `services.gpsd.devices` instead.") 21 ]; 22 23 options = { 24 25 services.gpsd = { 26 27 enable = lib.mkOption { 28 type = lib.types.bool; 29 default = false; 30 description = '' 31 Whether to enable `gpsd`, a GPS service daemon. 32 ''; 33 }; 34 35 devices = lib.mkOption { 36 type = lib.types.listOf lib.types.str; 37 default = [ "/dev/ttyUSB0" ]; 38 description = '' 39 List of devices that `gpsd` should subscribe to. 40 41 A device may be a local serial device for GPS input, or a 42 URL of the form: 43 `[{dgpsip|ntrip}://][user:passwd@]host[:port][/stream]` in 44 which case it specifies an input source for DGPS or ntrip 45 data. 46 ''; 47 }; 48 49 readonly = lib.mkOption { 50 type = lib.types.bool; 51 default = true; 52 description = '' 53 Whether to enable the broken-device-safety, otherwise 54 known as read-only mode. Some popular bluetooth and USB 55 receivers lock up or become totally inaccessible when 56 probed or reconfigured. This switch prevents gpsd from 57 writing to a receiver. This means that gpsd cannot 58 configure the receiver for optimal performance, but it 59 also means that gpsd cannot break the receiver. A better 60 solution would be for Bluetooth to not be so fragile. A 61 platform independent method to identify 62 serial-over-Bluetooth devices would also be nice. 63 ''; 64 }; 65 66 nowait = lib.mkOption { 67 type = lib.types.bool; 68 default = false; 69 description = '' 70 don't wait for client connects to poll GPS 71 ''; 72 }; 73 74 port = lib.mkOption { 75 type = lib.types.port; 76 default = 2947; 77 description = '' 78 The port where to listen for TCP connections. 79 ''; 80 }; 81 82 debugLevel = lib.mkOption { 83 type = lib.types.int; 84 default = 0; 85 description = '' 86 The debugging level. 87 ''; 88 }; 89 90 listenany = lib.mkOption { 91 type = lib.types.bool; 92 default = false; 93 description = '' 94 Listen on all addresses rather than just loopback. 95 ''; 96 }; 97 98 extraArgs = lib.mkOption { 99 type = lib.types.listOf lib.types.str; 100 default = [ ]; 101 example = [ 102 "-r" 103 "-s" 104 "19200" 105 ]; 106 description = '' 107 A list of extra command line arguments to pass to gpsd. 108 Check {manpage}`gpsd(8)` mangpage for possible arguments. 109 ''; 110 }; 111 112 }; 113 114 }; 115 116 ###### implementation 117 118 config = lib.mkIf cfg.enable { 119 120 users.users.gpsd = { 121 inherit uid; 122 group = "gpsd"; 123 description = "gpsd daemon user"; 124 home = "/var/empty"; 125 }; 126 127 users.groups.gpsd = { inherit gid; }; 128 129 systemd.services.gpsd = { 130 description = "GPSD daemon"; 131 wantedBy = [ "multi-user.target" ]; 132 after = [ "network.target" ]; 133 serviceConfig = { 134 Type = "forking"; 135 ExecStart = 136 let 137 devices = utils.escapeSystemdExecArgs cfg.devices; 138 extraArgs = utils.escapeSystemdExecArgs cfg.extraArgs; 139 in 140 '' 141 ${pkgs.gpsd}/sbin/gpsd -D "${toString cfg.debugLevel}" \ 142 -S "${toString cfg.port}" \ 143 ${lib.optionalString cfg.readonly "-b"} \ 144 ${lib.optionalString cfg.nowait "-n"} \ 145 ${lib.optionalString cfg.listenany "-G"} \ 146 ${extraArgs} \ 147 ${devices} 148 ''; 149 }; 150 }; 151 152 }; 153 154}