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