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, const char* name,
119         const char* description) = 0;
120 
121     virtual int sd_bus_message_new_method_errno(sd_bus_message* call,
122                                                 sd_bus_message** m, int error,
123                                                 const sd_bus_error* p) = 0;
124 
125     virtual int sd_bus_message_new_signal(
126         sd_bus* bus, sd_bus_message** m, const char* path,
127         const char* interface, const char* member) = 0;
128 
129     virtual int sd_bus_message_open_container(sd_bus_message* m, char type,
130                                               const char* contents) = 0;
131 
132     virtual int sd_bus_message_read_basic(sd_bus_message* m, char type,
133                                           void* p) = 0;
134 
135     virtual sd_bus_message* sd_bus_message_ref(sd_bus_message* m) = 0;
136 
137     virtual int sd_bus_message_skip(sd_bus_message* m, const char* types) = 0;
138 
139     virtual int sd_bus_message_verify_type(sd_bus_message* m, char type,
140                                            const char* contents) = 0;
141 
142     virtual int sd_bus_slot_set_destroy_callback(sd_bus_slot* slot,
143                                                  sd_bus_destroy_t callback) = 0;
144 
145     virtual void* sd_bus_slot_set_userdata(sd_bus_slot* slot,
146                                            void* userdata) = 0;
147 
148     virtual int sd_bus_process(sd_bus* bus, sd_bus_message** r) = 0;
149 
150     virtual sd_bus* sd_bus_ref(sd_bus* bus) = 0;
151 
152     virtual int sd_bus_request_name(sd_bus* bus, const char* name,
153                                     uint64_t flags) = 0;
154 
155     virtual int sd_bus_send(sd_bus* bus, sd_bus_message* m,
156                             uint64_t* cookie) = 0;
157 
158     virtual sd_bus* sd_bus_unref(sd_bus* bus) = 0;
159     virtual sd_bus_slot* sd_bus_slot_unref(sd_bus_slot* slot) = 0;
160     virtual sd_bus* sd_bus_flush_close_unref(sd_bus* bus) = 0;
161 
162     virtual int sd_bus_flush(sd_bus* bus) = 0;
163     virtual void sd_bus_close(sd_bus* bus) = 0;
164     virtual int sd_bus_is_open(sd_bus* bus) = 0;
165 
166     virtual int sd_bus_wait(sd_bus* bus, uint64_t timeout_usec) = 0;
167 };
168 
169 class SdBusImpl : public SdBusInterface
170 {
171   public:
172     SdBusImpl() = default;
173     ~SdBusImpl() override = default;
174     SdBusImpl(const SdBusImpl&) = default;
175     SdBusImpl& operator=(const SdBusImpl&) = default;
176     SdBusImpl(SdBusImpl&&) = default;
177     SdBusImpl& operator=(SdBusImpl&&) = default;
178 
179     int sd_bus_add_object_manager(sd_bus* bus, sd_bus_slot** slot,
180                                   const char* path) override
181     {
182         return ::sd_bus_add_object_manager(bus, slot, path);
183     }
184 
185     int sd_bus_add_object_vtable(sd_bus* bus, sd_bus_slot** slot,
186                                  const char* path, const char* interface,
187                                  const sd_bus_vtable* vtable,
188                                  void* userdata) override
189     {
190         return ::sd_bus_add_object_vtable(bus, slot, path, interface, vtable,
191                                           userdata);
192     }
193 
194     int sd_bus_add_match(sd_bus* bus, sd_bus_slot** slot, const char* path,
195                          sd_bus_message_handler_t callback,
196                          void* userdata) override
197     {
198         return ::sd_bus_add_match(bus, slot, path, callback, 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(
323         sd_bus_message* message, const struct iovec* iov, int iovcnt) override
324     {
325         return ::sd_bus_message_append_string_iovec(message, iov, iovcnt);
326     }
327 
328     int sd_bus_message_at_end(sd_bus_message* m, int complete) override
329     {
330         return ::sd_bus_message_at_end(m, complete);
331     }
332 
333     int sd_bus_message_close_container(sd_bus_message* m) override
334     {
335         return ::sd_bus_message_close_container(m);
336     }
337 
338     int sd_bus_message_enter_container(sd_bus_message* m, char type,
339                                        const char* contents) override
340     {
341         return ::sd_bus_message_enter_container(m, type, contents);
342     }
343 
344     int sd_bus_message_exit_container(sd_bus_message* m) override
345     {
346         return ::sd_bus_message_exit_container(m);
347     }
348 
349     sd_bus* sd_bus_message_get_bus(sd_bus_message* m) override
350     {
351         return ::sd_bus_message_get_bus(m);
352     }
353 
354     int sd_bus_message_get_type(sd_bus_message* m, uint8_t* type) override
355     {
356         return ::sd_bus_message_get_type(m, type);
357     }
358 
359     int sd_bus_message_get_cookie(sd_bus_message* m, uint64_t* cookie) override
360     {
361         return ::sd_bus_message_get_cookie(m, cookie);
362     }
363 
364     int sd_bus_message_get_reply_cookie(sd_bus_message* m,
365                                         uint64_t* cookie) override
366     {
367         return ::sd_bus_message_get_reply_cookie(m, cookie);
368     }
369 
370     const char* sd_bus_message_get_destination(sd_bus_message* m) override
371     {
372         return ::sd_bus_message_get_destination(m);
373     }
374 
375     const char* sd_bus_message_get_interface(sd_bus_message* m) override
376     {
377         return ::sd_bus_message_get_interface(m);
378     }
379 
380     const char* sd_bus_message_get_member(sd_bus_message* m) override
381     {
382         return ::sd_bus_message_get_member(m);
383     }
384 
385     const char* sd_bus_message_get_path(sd_bus_message* m) override
386     {
387         return ::sd_bus_message_get_path(m);
388     }
389 
390     const char* sd_bus_message_get_sender(sd_bus_message* m) override
391     {
392         return ::sd_bus_message_get_sender(m);
393     }
394 
395     const char* sd_bus_message_get_signature(sd_bus_message* m,
396                                              int complete) override
397     {
398         return ::sd_bus_message_get_signature(m, complete);
399     }
400 
401     int sd_bus_message_get_errno(sd_bus_message* m) override
402     {
403         return ::sd_bus_message_get_errno(m);
404     }
405 
406     const sd_bus_error* sd_bus_message_get_error(sd_bus_message* m) override
407     {
408         return ::sd_bus_message_get_error(m);
409     }
410 
411     int sd_bus_message_is_method_call(sd_bus_message* m, const char* interface,
412                                       const char* member) override
413     {
414         return ::sd_bus_message_is_method_call(m, interface, member);
415     }
416 
417     int sd_bus_message_is_method_error(sd_bus_message* m,
418                                        const char* name) override
419     {
420         return ::sd_bus_message_is_method_error(m, name);
421     }
422 
423     int sd_bus_message_is_signal(sd_bus_message* m, const char* interface,
424                                  const char* member) override
425     {
426         return ::sd_bus_message_is_signal(m, interface, member);
427     }
428 
429     int sd_bus_message_new_method_call(
430         sd_bus* bus, sd_bus_message** m, const char* destination,
431         const char* path, const char* interface, const char* member) override
432     {
433         return ::sd_bus_message_new_method_call(bus, m, destination, path,
434                                                 interface, member);
435     }
436 
437     int sd_bus_message_new_method_return(sd_bus_message* call,
438                                          sd_bus_message** m) override
439     {
440         return ::sd_bus_message_new_method_return(call, m);
441     }
442 
443     int sd_bus_message_new_method_error(sd_bus_message* call,
444                                         sd_bus_message** m, const char* name,
445                                         const char* description) override
446     {
447         return ::sd_bus_message_new_method_errorf(call, m, name, "%s",
448                                                   description);
449     }
450 
451     int sd_bus_message_new_method_errno(sd_bus_message* call,
452                                         sd_bus_message** m, int error,
453                                         const sd_bus_error* p) override
454     {
455         return ::sd_bus_message_new_method_errno(call, m, error, p);
456     }
457 
458     int sd_bus_message_new_signal(sd_bus* bus, sd_bus_message** m,
459                                   const char* path, const char* interface,
460                                   const char* member) override
461     {
462         return ::sd_bus_message_new_signal(bus, m, path, interface, member);
463     }
464 
465     int sd_bus_message_open_container(sd_bus_message* m, char type,
466                                       const char* contents) override
467     {
468         return ::sd_bus_message_open_container(m, type, contents);
469     }
470 
471     int sd_bus_message_read_basic(sd_bus_message* m, char type,
472                                   void* p) override
473     {
474         return ::sd_bus_message_read_basic(m, type, p);
475     }
476 
477     sd_bus_message* sd_bus_message_ref(sd_bus_message* m) override
478     {
479         return ::sd_bus_message_ref(m);
480     }
481 
482     int sd_bus_message_skip(sd_bus_message* m, const char* types) override
483     {
484         return ::sd_bus_message_skip(m, types);
485     }
486 
487     int sd_bus_message_verify_type(sd_bus_message* m, char type,
488                                    const char* contents) override
489     {
490         return ::sd_bus_message_verify_type(m, type, contents);
491     }
492 
493     int sd_bus_slot_set_destroy_callback(sd_bus_slot* slot,
494                                          sd_bus_destroy_t callback) override
495     {
496         return ::sd_bus_slot_set_destroy_callback(slot, callback);
497     }
498 
499     void* sd_bus_slot_set_userdata(sd_bus_slot* slot, void* userdata) override
500     {
501         return ::sd_bus_slot_set_userdata(slot, userdata);
502     }
503 
504     int sd_bus_process(sd_bus* bus, sd_bus_message** r) override
505     {
506         return ::sd_bus_process(bus, r);
507     }
508 
509     sd_bus* sd_bus_ref(sd_bus* bus) override
510     {
511         return ::sd_bus_ref(bus);
512     }
513 
514     int sd_bus_request_name(sd_bus* bus, const char* name,
515                             uint64_t flags) override
516     {
517         return ::sd_bus_request_name(bus, name, flags);
518     }
519 
520     int sd_bus_send(sd_bus* bus, sd_bus_message* m, uint64_t* cookie) override
521     {
522         return ::sd_bus_send(bus, m, cookie);
523     }
524 
525     sd_bus* sd_bus_unref(sd_bus* bus) override
526     {
527         return ::sd_bus_unref(bus);
528     }
529 
530     sd_bus_slot* sd_bus_slot_unref(sd_bus_slot* slot) override
531     {
532         return ::sd_bus_slot_unref(slot);
533     }
534 
535     sd_bus* sd_bus_flush_close_unref(sd_bus* bus) override
536     {
537         return ::sd_bus_flush_close_unref(bus);
538     }
539 
540     int sd_bus_flush(sd_bus* bus) override
541     {
542         return ::sd_bus_flush(bus);
543     }
544 
545     void sd_bus_close(sd_bus* bus) override
546     {
547         ::sd_bus_close(bus);
548     }
549 
550     int sd_bus_is_open(sd_bus* bus) override
551     {
552         return ::sd_bus_is_open(bus);
553     }
554 
555     int sd_bus_wait(sd_bus* bus, uint64_t timeout_usec) override
556     {
557         return ::sd_bus_wait(bus, timeout_usec);
558     }
559 };
560 
561 extern SdBusImpl sdbus_impl;
562 
563 } // namespace sdbusplus
564