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