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