Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : :
3 : : #include "sd-bus.h"
4 : :
5 : : #include "alloc-util.h"
6 : : #include "bus-internal.h"
7 : : #include "bus-protocol.h"
8 : : #include "bus-util.h"
9 : : #include "in-addr-util.h"
10 : : #include "log.h"
11 : : #include "macro.h"
12 : : #include "time-util.h"
13 : : #include "timesyncd-bus.h"
14 : :
15 : 0 : static int property_get_servers(
16 : : sd_bus *bus,
17 : : const char *path,
18 : : const char *interface,
19 : : const char *property,
20 : : sd_bus_message *reply,
21 : : void *userdata,
22 : : sd_bus_error *error) {
23 : :
24 : 0 : ServerName *p, **s = userdata;
25 : : int r;
26 : :
27 [ # # ]: 0 : assert(s);
28 [ # # ]: 0 : assert(bus);
29 [ # # ]: 0 : assert(reply);
30 : :
31 : 0 : r = sd_bus_message_open_container(reply, 'a', "s");
32 [ # # ]: 0 : if (r < 0)
33 : 0 : return r;
34 : :
35 [ # # ]: 0 : LIST_FOREACH(names, p, *s) {
36 : 0 : r = sd_bus_message_append(reply, "s", p->string);
37 [ # # ]: 0 : if (r < 0)
38 : 0 : return r;
39 : : }
40 : :
41 : 0 : return sd_bus_message_close_container(reply);
42 : : }
43 : :
44 : 0 : static int property_get_current_server_name(
45 : : sd_bus *bus,
46 : : const char *path,
47 : : const char *interface,
48 : : const char *property,
49 : : sd_bus_message *reply,
50 : : void *userdata,
51 : : sd_bus_error *error) {
52 : :
53 : 0 : ServerName **s = userdata;
54 : :
55 [ # # ]: 0 : assert(s);
56 [ # # ]: 0 : assert(bus);
57 [ # # ]: 0 : assert(reply);
58 : :
59 [ # # ]: 0 : return sd_bus_message_append(reply, "s", *s ? (*s)->string : NULL);
60 : : }
61 : :
62 : 0 : static int property_get_current_server_address(
63 : : sd_bus *bus,
64 : : const char *path,
65 : : const char *interface,
66 : : const char *property,
67 : : sd_bus_message *reply,
68 : : void *userdata,
69 : : sd_bus_error *error) {
70 : :
71 : : ServerAddress *a;
72 : : int r;
73 : :
74 [ # # ]: 0 : assert(bus);
75 [ # # ]: 0 : assert(reply);
76 [ # # ]: 0 : assert(userdata);
77 : :
78 : 0 : a = *(ServerAddress **) userdata;
79 : :
80 [ # # ]: 0 : if (!a)
81 : 0 : return sd_bus_message_append(reply, "(iay)", AF_UNSPEC, 0);
82 : :
83 [ # # # # ]: 0 : assert(IN_SET(a->sockaddr.sa.sa_family, AF_INET, AF_INET6));
84 : :
85 : 0 : r = sd_bus_message_open_container(reply, 'r', "iay");
86 [ # # ]: 0 : if (r < 0)
87 : 0 : return r;
88 : :
89 : 0 : r = sd_bus_message_append(reply, "i", a->sockaddr.sa.sa_family);
90 [ # # ]: 0 : if (r < 0)
91 : 0 : return r;
92 : :
93 : 0 : r = sd_bus_message_append_array(reply, 'y',
94 [ # # ]: 0 : a->sockaddr.sa.sa_family == AF_INET ? (void*) &a->sockaddr.in.sin_addr : (void*) &a->sockaddr.in6.sin6_addr,
95 : 0 : FAMILY_ADDRESS_SIZE(a->sockaddr.sa.sa_family));
96 [ # # ]: 0 : if (r < 0)
97 : 0 : return r;
98 : :
99 : 0 : return sd_bus_message_close_container(reply);
100 : : }
101 : :
102 : 0 : static usec_t ntp_ts_short_to_usec(const struct ntp_ts_short *ts) {
103 : 0 : return be16toh(ts->sec) * USEC_PER_SEC + (be16toh(ts->frac) * USEC_PER_SEC) / (usec_t) 0x10000ULL;
104 : : }
105 : :
106 : 0 : static usec_t ntp_ts_to_usec(const struct ntp_ts *ts) {
107 : 0 : return (be32toh(ts->sec) - OFFSET_1900_1970) * USEC_PER_SEC + (be32toh(ts->frac) * USEC_PER_SEC) / (usec_t) 0x100000000ULL;
108 : : }
109 : :
110 : 0 : static int property_get_ntp_message(
111 : : sd_bus *bus,
112 : : const char *path,
113 : : const char *interface,
114 : : const char *property,
115 : : sd_bus_message *reply,
116 : : void *userdata,
117 : : sd_bus_error *error) {
118 : :
119 : 0 : Manager *m = userdata;
120 : : int r;
121 : :
122 [ # # ]: 0 : assert(m);
123 [ # # ]: 0 : assert(reply);
124 : :
125 : 0 : r = sd_bus_message_open_container(reply, 'r', "uuuuittayttttbtt");
126 [ # # ]: 0 : if (r < 0)
127 : 0 : return r;
128 : :
129 : 0 : r = sd_bus_message_append(reply, "uuuuitt",
130 : 0 : NTP_FIELD_LEAP(m->ntpmsg.field),
131 : 0 : NTP_FIELD_VERSION(m->ntpmsg.field),
132 : 0 : NTP_FIELD_MODE(m->ntpmsg.field),
133 : 0 : m->ntpmsg.stratum,
134 : 0 : m->ntpmsg.precision,
135 : 0 : ntp_ts_short_to_usec(&m->ntpmsg.root_delay),
136 : 0 : ntp_ts_short_to_usec(&m->ntpmsg.root_dispersion));
137 [ # # ]: 0 : if (r < 0)
138 : 0 : return r;
139 : :
140 : 0 : r = sd_bus_message_append_array(reply, 'y', m->ntpmsg.refid, 4);
141 [ # # ]: 0 : if (r < 0)
142 : 0 : return r;
143 : :
144 : 0 : r = sd_bus_message_append(reply, "ttttbtt",
145 : 0 : timespec_load(&m->origin_time),
146 : 0 : ntp_ts_to_usec(&m->ntpmsg.recv_time),
147 : 0 : ntp_ts_to_usec(&m->ntpmsg.trans_time),
148 : 0 : timespec_load(&m->dest_time),
149 : 0 : m->spike,
150 : : m->packet_count,
151 : 0 : (usec_t) (m->samples_jitter * USEC_PER_SEC));
152 [ # # ]: 0 : if (r < 0)
153 : 0 : return r;
154 : :
155 : 0 : return sd_bus_message_close_container(reply);
156 : : }
157 : :
158 : : static const sd_bus_vtable manager_vtable[] = {
159 : : SD_BUS_VTABLE_START(0),
160 : :
161 : : SD_BUS_PROPERTY("LinkNTPServers", "as", property_get_servers, offsetof(Manager, link_servers), 0),
162 : : SD_BUS_PROPERTY("SystemNTPServers", "as", property_get_servers, offsetof(Manager, system_servers), SD_BUS_VTABLE_PROPERTY_CONST),
163 : : SD_BUS_PROPERTY("FallbackNTPServers", "as", property_get_servers, offsetof(Manager, fallback_servers), SD_BUS_VTABLE_PROPERTY_CONST),
164 : : SD_BUS_PROPERTY("ServerName", "s", property_get_current_server_name, offsetof(Manager, current_server_name), 0),
165 : : SD_BUS_PROPERTY("ServerAddress", "(iay)", property_get_current_server_address, offsetof(Manager, current_server_address), 0),
166 : : SD_BUS_PROPERTY("RootDistanceMaxUSec", "t", bus_property_get_usec, offsetof(Manager, max_root_distance_usec), SD_BUS_VTABLE_PROPERTY_CONST),
167 : : SD_BUS_PROPERTY("PollIntervalMinUSec", "t", bus_property_get_usec, offsetof(Manager, poll_interval_min_usec), SD_BUS_VTABLE_PROPERTY_CONST),
168 : : SD_BUS_PROPERTY("PollIntervalMaxUSec", "t", bus_property_get_usec, offsetof(Manager, poll_interval_max_usec), SD_BUS_VTABLE_PROPERTY_CONST),
169 : : SD_BUS_PROPERTY("PollIntervalUSec", "t", bus_property_get_usec, offsetof(Manager, poll_interval_usec), 0),
170 : : SD_BUS_PROPERTY("NTPMessage", "(uuuuittayttttbtt)", property_get_ntp_message, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
171 : : SD_BUS_PROPERTY("Frequency", "x", NULL, offsetof(Manager, drift_freq), 0),
172 : :
173 : : SD_BUS_VTABLE_END
174 : : };
175 : :
176 : 0 : int manager_connect_bus(Manager *m) {
177 : : int r;
178 : :
179 [ # # ]: 0 : assert(m);
180 : :
181 [ # # ]: 0 : if (m->bus)
182 : 0 : return 0;
183 : :
184 : 0 : r = bus_open_system_watch_bind_with_description(&m->bus, "bus-api-timesync");
185 [ # # ]: 0 : if (r < 0)
186 [ # # ]: 0 : return log_error_errno(r, "Failed to connect to bus: %m");
187 : :
188 : 0 : r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/timesync1", "org.freedesktop.timesync1.Manager", manager_vtable, m);
189 [ # # ]: 0 : if (r < 0)
190 [ # # ]: 0 : return log_error_errno(r, "Failed to add manager object vtable: %m");
191 : :
192 : 0 : r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.timesync1", 0, NULL, NULL);
193 [ # # ]: 0 : if (r < 0)
194 [ # # ]: 0 : return log_error_errno(r, "Failed to request name: %m");
195 : :
196 : 0 : r = sd_bus_attach_event(m->bus, m->event, 0);
197 [ # # ]: 0 : if (r < 0)
198 [ # # ]: 0 : return log_error_errno(r, "Failed to attach bus to event loop: %m");
199 : :
200 : 0 : return 0;
201 : : }
|