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