| #include <iostream> |
| #include <sdbusplus/message/append.hpp> |
| #include <cassert> |
| |
| // Global to share the dbus type string between client and server. |
| static std::string verifyTypeString; |
| |
| static constexpr auto SERVICE = "sdbusplus.test"; |
| static constexpr auto INTERFACE = SERVICE; |
| static constexpr auto TEST_METHOD = "test"; |
| static constexpr auto QUIT_METHOD = "quit"; |
| |
| // Open up the sdbus and claim SERVICE name. |
| void serverInit(sd_bus** b) |
| { |
| assert(0 <= sd_bus_open(b)); |
| assert(0 <= sd_bus_request_name(*b, SERVICE, 0)); |
| } |
| |
| // Thread to run the dbus server. |
| void* server(void* b) |
| { |
| auto bus = reinterpret_cast<sd_bus*>(b); |
| |
| while(1) |
| { |
| // Wait for messages. |
| sd_bus_message *m = nullptr; |
| if (0 == sd_bus_process(bus, &m)) |
| { |
| sd_bus_wait(bus, 0); |
| continue; |
| } |
| |
| if(!m) |
| { |
| continue; |
| } |
| |
| if (sd_bus_message_is_method_call(m, INTERFACE, TEST_METHOD)) |
| { |
| // Verify the message type matches what the test expects. |
| // TODO: It would be nice to verify content here as well. |
| assert(verifyTypeString == sd_bus_message_get_signature(m, true)); |
| // Reply to client. |
| sd_bus_reply_method_return(m, nullptr); |
| } |
| else if (sd_bus_message_is_method_call(m, INTERFACE, QUIT_METHOD)) |
| { |
| // Reply and exit. |
| sd_bus_reply_method_return(m, nullptr); |
| break; |
| } |
| } |
| } |
| |
| void newMethodCall__test(sd_bus* b, sd_bus_message** m) |
| { |
| // Allocate a method-call message for INTERFACE,TEST_METHOD. |
| assert(0 <= sd_bus_message_new_method_call(b, m, SERVICE, "/", INTERFACE, |
| TEST_METHOD)); |
| sd_bus_message_set_expect_reply(*m, true); |
| } |
| |
| void runTests() |
| { |
| using namespace std::literals; |
| |
| sd_bus_message* m = nullptr; |
| sd_bus* b = nullptr; |
| |
| // Connect to dbus. |
| assert(0 <= sd_bus_open(&b)); |
| |
| // Test r-value int. |
| { |
| newMethodCall__test(b, &m); |
| sdbusplus::message::append(m, 1); |
| verifyTypeString = "i"; |
| sd_bus_call(b, m, 0, nullptr, nullptr); |
| } |
| |
| // Test l-value int. |
| { |
| newMethodCall__test(b, &m); |
| int a = 1; |
| sdbusplus::message::append(m, a, a); |
| verifyTypeString = "ii"; |
| sd_bus_call(b, m, 0, nullptr, nullptr); |
| } |
| |
| // Test multiple ints. |
| { |
| newMethodCall__test(b, &m); |
| sdbusplus::message::append(m, 1, 2, 3, 4, 5); |
| verifyTypeString = "iiiii"; |
| sd_bus_call(b, m, 0, nullptr, nullptr); |
| } |
| |
| // Test r-value string. |
| { |
| newMethodCall__test(b, &m); |
| sdbusplus::message::append(m, "asdf"s); |
| verifyTypeString = "s"; |
| sd_bus_call(b, m, 0, nullptr, nullptr); |
| } |
| |
| // Test multiple strings, various forms. |
| { |
| newMethodCall__test(b, &m); |
| auto str = "jkl;"s; |
| auto str2 = "JKL:"s; |
| sdbusplus::message::append(m, 1, "asdf", "ASDF"s, str, |
| std::move(str2), 5); |
| verifyTypeString = "issssi"; |
| sd_bus_call(b, m, 0, nullptr, nullptr); |
| } |
| |
| // Shutdown server. |
| sd_bus_call_method(b, SERVICE, "/", INTERFACE, QUIT_METHOD, |
| nullptr, nullptr, nullptr); |
| } |
| |
| int main() |
| { |
| // Initialize and start server thread. |
| pthread_t t; |
| { |
| sd_bus* b; |
| serverInit(&b); |
| pthread_create(&t, NULL, server, b); |
| } |
| |
| runTests(); |
| |
| // Wait for server thread to exit. |
| pthread_join(t, NULL); |
| |
| return 0; |
| } |