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