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