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