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