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