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