1 #pragma once
2 
3 #include <systemd/sd-bus.h>
4 
5 #include <chrono>
6 
7 // ABC for sdbus implementation.
8 namespace sdbusplus
9 {
10 
11 // Defined by systemd taking uint64_t usec params
12 using SdBusDuration =
13     std::chrono::duration<uint64_t, std::chrono::microseconds::period>;
14 
15 // A wrapper for interfacing or testing sd-bus.  This will hold methods for
16 // buses, messages, etc.
17 class SdBusInterface
18 {
19   public:
20     virtual ~SdBusInterface() = default;
21 
22     virtual int sd_bus_add_object_manager(sd_bus* bus, sd_bus_slot** slot,
23                                           const char* path) = 0;
24 
25     virtual int sd_bus_add_object_vtable(sd_bus* bus, sd_bus_slot** slot,
26                                          const char* path,
27                                          const char* interface,
28                                          const sd_bus_vtable* vtable,
29                                          void* userdata) = 0;
30 
31     virtual int sd_bus_attach_event(sd_bus* bus, sd_event* e, int priority) = 0;
32 
33     virtual int sd_bus_call(sd_bus* bus, sd_bus_message* m, uint64_t usec,
34                             sd_bus_error* ret_error,
35                             sd_bus_message** reply) = 0;
36 
37     virtual int sd_bus_detach_event(sd_bus* bus) = 0;
38 
39     virtual int sd_bus_emit_interfaces_added_strv(sd_bus* bus, const char* path,
40                                                   char** interfaces) = 0;
41     virtual int sd_bus_emit_interfaces_removed_strv(sd_bus* bus,
42                                                     const char* path,
43                                                     char** interfaces) = 0;
44     virtual int sd_bus_emit_object_added(sd_bus* bus, const char* path) = 0;
45     virtual int sd_bus_emit_object_removed(sd_bus* bus, const char* path) = 0;
46     virtual int sd_bus_emit_properties_changed_strv(sd_bus* bus,
47                                                     const char* path,
48                                                     const char* interface,
49                                                     const char** names) = 0;
50 
51     virtual int sd_bus_error_set(sd_bus_error* e, const char* name,
52                                  const char* message) = 0;
53     virtual int sd_bus_error_set_const(sd_bus_error* e, const char* name,
54                                        const char* message) = 0;
55     virtual int sd_bus_error_get_errno(const sd_bus_error* e) = 0;
56     virtual int sd_bus_error_set_errno(sd_bus_error* e, int error) = 0;
57     virtual int sd_bus_error_is_set(const sd_bus_error* e) = 0;
58     virtual void sd_bus_error_free(sd_bus_error* e) = 0;
59 
60     virtual sd_event* sd_bus_get_event(sd_bus* bus) = 0;
61     virtual int sd_bus_get_fd(sd_bus* bus) = 0;
62     virtual int sd_bus_get_unique_name(sd_bus* bus, const char** unique) = 0;
63 
64     virtual int sd_bus_list_names(sd_bus* bus, char*** acquired,
65                                   char*** activatable) = 0;
66 
67     // https://github.com/systemd/systemd/blob/master/src/systemd/sd-bus.h
68     virtual int sd_bus_message_append_basic(sd_bus_message* message, char type,
69                                             const void* value) = 0;
70 
71     virtual int sd_bus_message_at_end(sd_bus_message* m, int complete) = 0;
72 
73     virtual int sd_bus_message_close_container(sd_bus_message* m) = 0;
74 
75     virtual int sd_bus_message_enter_container(sd_bus_message* m, char type,
76                                                const char* contents) = 0;
77 
78     virtual int sd_bus_message_exit_container(sd_bus_message* m) = 0;
79 
80     virtual sd_bus* sd_bus_message_get_bus(sd_bus_message* m) = 0;
81     virtual int sd_bus_message_get_type(sd_bus_message* m, uint8_t* type) = 0;
82     virtual int sd_bus_message_get_cookie(sd_bus_message* m,
83                                           uint64_t* cookie) = 0;
84     virtual int sd_bus_message_get_reply_cookie(sd_bus_message* m,
85                                                 uint64_t* cookie) = 0;
86     virtual const char* sd_bus_message_get_destination(sd_bus_message* m) = 0;
87     virtual const char* sd_bus_message_get_interface(sd_bus_message* m) = 0;
88     virtual const char* sd_bus_message_get_member(sd_bus_message* m) = 0;
89     virtual const char* sd_bus_message_get_path(sd_bus_message* m) = 0;
90     virtual const char* sd_bus_message_get_sender(sd_bus_message* m) = 0;
91     virtual const char* sd_bus_message_get_signature(sd_bus_message* m,
92                                                      int complete) = 0;
93     virtual int sd_bus_message_get_errno(sd_bus_message* m) = 0;
94     virtual const sd_bus_error* sd_bus_message_get_error(sd_bus_message* m) = 0;
95 
96     virtual int sd_bus_message_is_method_call(sd_bus_message* m,
97                                               const char* interface,
98                                               const char* member) = 0;
99     virtual int sd_bus_message_is_method_error(sd_bus_message* m,
100                                                const char* name) = 0;
101     virtual int sd_bus_message_is_signal(sd_bus_message* m,
102                                          const char* interface,
103                                          const char* member) = 0;
104 
105     virtual int sd_bus_message_new_method_call(sd_bus* bus, sd_bus_message** m,
106                                                const char* destination,
107                                                const char* path,
108                                                const char* interface,
109                                                const char* member) = 0;
110 
111     virtual int sd_bus_message_new_method_return(sd_bus_message* call,
112                                                  sd_bus_message** m) = 0;
113 
114     virtual int sd_bus_message_new_method_error(sd_bus_message* call,
115                                                 sd_bus_message** m,
116                                                 const char* name,
117                                                 const char* description) = 0;
118 
119     virtual int sd_bus_message_new_method_errno(sd_bus_message* call,
120                                                 sd_bus_message** m, int error,
121                                                 const sd_bus_error* p) = 0;
122 
123     virtual int sd_bus_message_new_signal(sd_bus* bus, sd_bus_message** m,
124                                           const char* path,
125                                           const char* interface,
126                                           const char* member) = 0;
127 
128     virtual int sd_bus_message_open_container(sd_bus_message* m, char type,
129                                               const char* contents) = 0;
130 
131     virtual int sd_bus_message_read_basic(sd_bus_message* m, char type,
132                                           void* p) = 0;
133 
134     virtual sd_bus_message* sd_bus_message_ref(sd_bus_message* m) = 0;
135 
136     virtual int sd_bus_message_skip(sd_bus_message* m, const char* types) = 0;
137 
138     virtual int sd_bus_message_verify_type(sd_bus_message* m, char type,
139                                            const char* contents) = 0;
140 
141     virtual int sd_bus_process(sd_bus* bus, sd_bus_message** r) = 0;
142 
143     virtual sd_bus* sd_bus_ref(sd_bus* bus) = 0;
144 
145     virtual int sd_bus_request_name(sd_bus* bus, const char* name,
146                                     uint64_t flags) = 0;
147 
148     virtual int sd_bus_send(sd_bus* bus, sd_bus_message* m,
149                             uint64_t* cookie) = 0;
150 
151     virtual sd_bus* sd_bus_unref(sd_bus* bus) = 0;
152     virtual sd_bus* sd_bus_flush_close_unref(sd_bus* bus) = 0;
153 
154     virtual int sd_bus_flush(sd_bus* bus) = 0;
155     virtual void sd_bus_close(sd_bus* bus) = 0;
156 
157     virtual int sd_bus_wait(sd_bus* bus, uint64_t timeout_usec) = 0;
158 };
159 
160 class SdBusImpl : public SdBusInterface
161 {
162   public:
163     SdBusImpl() = default;
164     ~SdBusImpl() = default;
165     SdBusImpl(const SdBusImpl&) = default;
166     SdBusImpl& operator=(const SdBusImpl&) = default;
167     SdBusImpl(SdBusImpl&&) = default;
168     SdBusImpl& operator=(SdBusImpl&&) = default;
169 
170     int sd_bus_add_object_manager(sd_bus* bus, sd_bus_slot** slot,
171                                   const char* path) override
172     {
173         return ::sd_bus_add_object_manager(bus, slot, path);
174     }
175 
176     int sd_bus_add_object_vtable(sd_bus* bus, sd_bus_slot** slot,
177                                  const char* path, const char* interface,
178                                  const sd_bus_vtable* vtable,
179                                  void* userdata) override
180     {
181         return ::sd_bus_add_object_vtable(bus, slot, path, interface, vtable,
182                                           userdata);
183     }
184 
185     int sd_bus_attach_event(sd_bus* bus, sd_event* e, int priority) override
186     {
187         return ::sd_bus_attach_event(bus, e, priority);
188     }
189 
190     int sd_bus_call(sd_bus* bus, sd_bus_message* m, uint64_t usec,
191                     sd_bus_error* ret_error, sd_bus_message** reply) override
192     {
193         return ::sd_bus_call(bus, m, usec, ret_error, reply);
194     }
195 
196     int sd_bus_detach_event(sd_bus* bus) override
197     {
198         return ::sd_bus_detach_event(bus);
199     }
200 
201     int sd_bus_emit_interfaces_added_strv(sd_bus* bus, const char* path,
202                                           char** interfaces) override
203     {
204         return ::sd_bus_emit_interfaces_added_strv(bus, path, interfaces);
205     }
206 
207     int sd_bus_emit_interfaces_removed_strv(sd_bus* bus, const char* path,
208                                             char** interfaces) override
209     {
210         return ::sd_bus_emit_interfaces_removed_strv(bus, path, interfaces);
211     }
212 
213     int sd_bus_emit_object_added(sd_bus* bus, const char* path) override
214     {
215         return ::sd_bus_emit_object_added(bus, path);
216     }
217 
218     int sd_bus_emit_object_removed(sd_bus* bus, const char* path) override
219     {
220         return ::sd_bus_emit_object_removed(bus, path);
221     }
222 
223     int sd_bus_emit_properties_changed_strv(sd_bus* bus, const char* path,
224                                             const char* interface,
225                                             const char** names) override
226     {
227         return ::sd_bus_emit_properties_changed_strv(bus, path, interface,
228                                                      const_cast<char**>(names));
229         // The const_cast above may seem unsafe, but it safe.  sd_bus's manpage
230         // shows a 'const char*' but the header does not.  I examined the code
231         // and no modification of the strings is done.  I tried to change sdbus
232         // directly but due to quirks of C you cannot implicitly convert a
233         // 'char **' to a 'const char**', so changing the implementation causes
234         // lots of compile failures due to an incompatible API change.
235         //
236         // Performing a const_cast allows us to avoid a memory allocation of
237         // the contained strings in 'interface::property_changed'.
238     }
239 
240     int sd_bus_error_set(sd_bus_error* e, const char* name,
241                          const char* message) override
242     {
243         return ::sd_bus_error_set(e, name, message);
244     }
245 
246     int sd_bus_error_set_const(sd_bus_error* e, const char* name,
247                                const char* message) override
248     {
249         return ::sd_bus_error_set_const(e, name, message);
250     }
251 
252     int sd_bus_error_get_errno(const sd_bus_error* e) override
253     {
254         return ::sd_bus_error_get_errno(e);
255     }
256 
257     int sd_bus_error_set_errno(sd_bus_error* e, int error) override
258     {
259         return ::sd_bus_error_set_errno(e, error);
260     }
261 
262     int sd_bus_error_is_set(const sd_bus_error* e) override
263     {
264         return ::sd_bus_error_is_set(e);
265     }
266 
267     void sd_bus_error_free(sd_bus_error* e) override
268     {
269         return ::sd_bus_error_free(e);
270     }
271 
272     sd_event* sd_bus_get_event(sd_bus* bus) override
273     {
274         return ::sd_bus_get_event(bus);
275     }
276 
277     int sd_bus_get_fd(sd_bus* bus) override
278     {
279         return ::sd_bus_get_fd(bus);
280     }
281 
282     int sd_bus_get_unique_name(sd_bus* bus, const char** unique) override
283     {
284         return ::sd_bus_get_unique_name(bus, unique);
285     }
286 
287     int sd_bus_list_names(sd_bus* bus, char*** acquired,
288                           char*** activatable) override
289     {
290         return ::sd_bus_list_names(bus, acquired, activatable);
291     }
292 
293     int sd_bus_message_append_basic(sd_bus_message* message, char type,
294                                     const void* value) override
295     {
296         return ::sd_bus_message_append_basic(message, type, value);
297     }
298 
299     int sd_bus_message_at_end(sd_bus_message* m, int complete) override
300     {
301         return ::sd_bus_message_at_end(m, complete);
302     }
303 
304     int sd_bus_message_close_container(sd_bus_message* m) override
305     {
306         return ::sd_bus_message_close_container(m);
307     }
308 
309     int sd_bus_message_enter_container(sd_bus_message* m, char type,
310                                        const char* contents) override
311     {
312         return ::sd_bus_message_enter_container(m, type, contents);
313     }
314 
315     int sd_bus_message_exit_container(sd_bus_message* m) override
316     {
317         return ::sd_bus_message_exit_container(m);
318     }
319 
320     sd_bus* sd_bus_message_get_bus(sd_bus_message* m) override
321     {
322         return ::sd_bus_message_get_bus(m);
323     }
324 
325     int sd_bus_message_get_type(sd_bus_message* m, uint8_t* type) override
326     {
327         return ::sd_bus_message_get_type(m, type);
328     }
329 
330     int sd_bus_message_get_cookie(sd_bus_message* m, uint64_t* cookie) override
331     {
332         return ::sd_bus_message_get_cookie(m, cookie);
333     }
334 
335     int sd_bus_message_get_reply_cookie(sd_bus_message* m,
336                                         uint64_t* cookie) override
337     {
338         return ::sd_bus_message_get_reply_cookie(m, cookie);
339     }
340 
341     const char* sd_bus_message_get_destination(sd_bus_message* m) override
342     {
343         return ::sd_bus_message_get_destination(m);
344     }
345 
346     const char* sd_bus_message_get_interface(sd_bus_message* m) override
347     {
348         return ::sd_bus_message_get_interface(m);
349     }
350 
351     const char* sd_bus_message_get_member(sd_bus_message* m) override
352     {
353         return ::sd_bus_message_get_member(m);
354     }
355 
356     const char* sd_bus_message_get_path(sd_bus_message* m) override
357     {
358         return ::sd_bus_message_get_path(m);
359     }
360 
361     const char* sd_bus_message_get_sender(sd_bus_message* m) override
362     {
363         return ::sd_bus_message_get_sender(m);
364     }
365 
366     const char* sd_bus_message_get_signature(sd_bus_message* m,
367                                              int complete) override
368     {
369         return ::sd_bus_message_get_signature(m, complete);
370     }
371 
372     int sd_bus_message_get_errno(sd_bus_message* m) override
373     {
374         return ::sd_bus_message_get_errno(m);
375     }
376 
377     const sd_bus_error* sd_bus_message_get_error(sd_bus_message* m) override
378     {
379         return ::sd_bus_message_get_error(m);
380     }
381 
382     int sd_bus_message_is_method_call(sd_bus_message* m, const char* interface,
383                                       const char* member) override
384     {
385         return ::sd_bus_message_is_method_call(m, interface, member);
386     }
387 
388     int sd_bus_message_is_method_error(sd_bus_message* m,
389                                        const char* name) override
390     {
391         return ::sd_bus_message_is_method_error(m, name);
392     }
393 
394     int sd_bus_message_is_signal(sd_bus_message* m, const char* interface,
395                                  const char* member) override
396     {
397         return ::sd_bus_message_is_signal(m, interface, member);
398     }
399 
400     int sd_bus_message_new_method_call(sd_bus* bus, sd_bus_message** m,
401                                        const char* destination,
402                                        const char* path, const char* interface,
403                                        const char* member) override
404     {
405         return ::sd_bus_message_new_method_call(bus, m, destination, path,
406                                                 interface, member);
407     }
408 
409     int sd_bus_message_new_method_return(sd_bus_message* call,
410                                          sd_bus_message** m) override
411     {
412         return ::sd_bus_message_new_method_return(call, m);
413     }
414 
415     int sd_bus_message_new_method_error(sd_bus_message* call,
416                                         sd_bus_message** m, const char* name,
417                                         const char* description) override
418     {
419         return ::sd_bus_message_new_method_errorf(call, m, name, "%s",
420                                                   description);
421     }
422 
423     int sd_bus_message_new_method_errno(sd_bus_message* call,
424                                         sd_bus_message** m, int error,
425                                         const sd_bus_error* p) override
426     {
427         return ::sd_bus_message_new_method_errno(call, m, error, p);
428     }
429 
430     int sd_bus_message_new_signal(sd_bus* bus, sd_bus_message** m,
431                                   const char* path, const char* interface,
432                                   const char* member) override
433     {
434         return ::sd_bus_message_new_signal(bus, m, path, interface, member);
435     }
436 
437     int sd_bus_message_open_container(sd_bus_message* m, char type,
438                                       const char* contents) override
439     {
440         return ::sd_bus_message_open_container(m, type, contents);
441     }
442 
443     int sd_bus_message_read_basic(sd_bus_message* m, char type,
444                                   void* p) override
445     {
446         return ::sd_bus_message_read_basic(m, type, p);
447     }
448 
449     sd_bus_message* sd_bus_message_ref(sd_bus_message* m) override
450     {
451         return ::sd_bus_message_ref(m);
452     }
453 
454     int sd_bus_message_skip(sd_bus_message* m, const char* types) override
455     {
456         return ::sd_bus_message_skip(m, types);
457     }
458 
459     int sd_bus_message_verify_type(sd_bus_message* m, char type,
460                                    const char* contents) override
461     {
462         return ::sd_bus_message_verify_type(m, type, contents);
463     }
464 
465     int sd_bus_process(sd_bus* bus, sd_bus_message** r) override
466     {
467         return ::sd_bus_process(bus, r);
468     }
469 
470     sd_bus* sd_bus_ref(sd_bus* bus) override
471     {
472         return ::sd_bus_ref(bus);
473     }
474 
475     int sd_bus_request_name(sd_bus* bus, const char* name,
476                             uint64_t flags) override
477     {
478         return ::sd_bus_request_name(bus, name, flags);
479     }
480 
481     int sd_bus_send(sd_bus* bus, sd_bus_message* m, uint64_t* cookie) override
482     {
483         return ::sd_bus_send(bus, m, cookie);
484     }
485 
486     sd_bus* sd_bus_unref(sd_bus* bus) override
487     {
488         return ::sd_bus_unref(bus);
489     }
490 
491     sd_bus* sd_bus_flush_close_unref(sd_bus* bus) override
492     {
493         return ::sd_bus_flush_close_unref(bus);
494     }
495 
496     int sd_bus_flush(sd_bus* bus) override
497     {
498         return ::sd_bus_flush(bus);
499     }
500 
501     void sd_bus_close(sd_bus* bus) override
502     {
503         ::sd_bus_close(bus);
504     }
505 
506     int sd_bus_wait(sd_bus* bus, uint64_t timeout_usec) override
507     {
508         return ::sd_bus_wait(bus, timeout_usec);
509     }
510 };
511 
512 extern SdBusImpl sdbus_impl;
513 
514 } // namespace sdbusplus
515