1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 uid = config.ids.uids.gpsd;
8 gid = config.ids.gids.gpsd;
9 cfg = config.services.gpsd;
10
11in
12
13{
14
15 ###### interface
16
17 options = {
18
19 services.gpsd = {
20
21 enable = mkOption {
22 type = types.bool;
23 default = false;
24 description = ''
25 Whether to enable `gpsd', a GPS service daemon.
26 '';
27 };
28
29 device = mkOption {
30 type = types.str;
31 default = "/dev/ttyUSB0";
32 description = ''
33 A device may be a local serial device for GPS input, or a URL of the form:
34 <literal>[{dgpsip|ntrip}://][user:passwd@]host[:port][/stream]</literal>
35 in which case it specifies an input source for DGPS or ntrip data.
36 '';
37 };
38
39 readonly = mkOption {
40 type = types.bool;
41 default = true;
42 description = ''
43 Whether to enable the broken-device-safety, otherwise
44 known as read-only mode. Some popular bluetooth and USB
45 receivers lock up or become totally inaccessible when
46 probed or reconfigured. This switch prevents gpsd from
47 writing to a receiver. This means that gpsd cannot
48 configure the receiver for optimal performance, but it
49 also means that gpsd cannot break the receiver. A better
50 solution would be for Bluetooth to not be so fragile. A
51 platform independent method to identify
52 serial-over-Bluetooth devices would also be nice.
53 '';
54 };
55
56 port = mkOption {
57 type = types.int;
58 default = 2947;
59 description = ''
60 The port where to listen for TCP connections.
61 '';
62 };
63
64 debugLevel = mkOption {
65 type = types.int;
66 default = 0;
67 description = ''
68 The debugging level.
69 '';
70 };
71
72 };
73
74 };
75
76
77 ###### implementation
78
79 config = mkIf cfg.enable {
80
81 users.extraUsers = singleton
82 { name = "gpsd";
83 inherit uid;
84 description = "gpsd daemon user";
85 home = "/var/empty";
86 };
87
88 users.extraGroups = singleton
89 { name = "gpsd";
90 inherit gid;
91 };
92
93 systemd.services.gpsd = {
94 description = "GPSD daemon";
95 wantedBy = [ "multi-user.target" ];
96 after = [ "network.target" ];
97 serviceConfig = {
98 Type = "forking";
99 ExecStart = ''
100 ${pkgs.gpsd}/sbin/gpsd -D "${toString cfg.debugLevel}" \
101 -S "${toString cfg.port}" \
102 ${if cfg.readonly then "-b" else ""} \
103 "${cfg.device}"
104 '';
105 };
106 };
107
108 };
109
110}