1 #include <iostream> 2 #include <sdbusplus/message/append.hpp> 3 #include <cassert> 4 5 // Global to share the dbus type string between client and server. 6 static std::string verifyTypeString; 7 8 static constexpr auto SERVICE = "sdbusplus.test"; 9 static constexpr auto INTERFACE = SERVICE; 10 static constexpr auto TEST_METHOD = "test"; 11 static constexpr auto QUIT_METHOD = "quit"; 12 13 // Open up the sdbus and claim SERVICE name. 14 void serverInit(sd_bus** b) 15 { 16 assert(0 <= sd_bus_open(b)); 17 assert(0 <= sd_bus_request_name(*b, SERVICE, 0)); 18 } 19 20 // Thread to run the dbus server. 21 void* server(void* b) 22 { 23 auto bus = reinterpret_cast<sd_bus*>(b); 24 25 while(1) 26 { 27 // Wait for messages. 28 sd_bus_message *m = nullptr; 29 if (0 == sd_bus_process(bus, &m)) 30 { 31 sd_bus_wait(bus, 0); 32 continue; 33 } 34 35 if(!m) 36 { 37 continue; 38 } 39 40 if (sd_bus_message_is_method_call(m, INTERFACE, TEST_METHOD)) 41 { 42 // Verify the message type matches what the test expects. 43 // TODO: It would be nice to verify content here as well. 44 assert(verifyTypeString == sd_bus_message_get_signature(m, true)); 45 // Reply to client. 46 sd_bus_reply_method_return(m, nullptr); 47 } 48 else if (sd_bus_message_is_method_call(m, INTERFACE, QUIT_METHOD)) 49 { 50 // Reply and exit. 51 sd_bus_reply_method_return(m, nullptr); 52 break; 53 } 54 } 55 } 56 57 void newMethodCall__test(sd_bus* b, sd_bus_message** m) 58 { 59 // Allocate a method-call message for INTERFACE,TEST_METHOD. 60 assert(0 <= sd_bus_message_new_method_call(b, m, SERVICE, "/", INTERFACE, 61 TEST_METHOD)); 62 sd_bus_message_set_expect_reply(*m, true); 63 } 64 65 void runTests() 66 { 67 using namespace std::literals; 68 69 sd_bus_message* m = nullptr; 70 sd_bus* b = nullptr; 71 72 // Connect to dbus. 73 assert(0 <= sd_bus_open(&b)); 74 75 // Test r-value int. 76 { 77 newMethodCall__test(b, &m); 78 sdbusplus::message::append(m, 1); 79 verifyTypeString = "i"; 80 sd_bus_call(b, m, 0, nullptr, nullptr); 81 } 82 83 // Test l-value int. 84 { 85 newMethodCall__test(b, &m); 86 int a = 1; 87 sdbusplus::message::append(m, a, a); 88 verifyTypeString = "ii"; 89 sd_bus_call(b, m, 0, nullptr, nullptr); 90 } 91 92 // Test multiple ints. 93 { 94 newMethodCall__test(b, &m); 95 sdbusplus::message::append(m, 1, 2, 3, 4, 5); 96 verifyTypeString = "iiiii"; 97 sd_bus_call(b, m, 0, nullptr, nullptr); 98 } 99 100 // Test r-value string. 101 { 102 newMethodCall__test(b, &m); 103 sdbusplus::message::append(m, "asdf"s); 104 verifyTypeString = "s"; 105 sd_bus_call(b, m, 0, nullptr, nullptr); 106 } 107 108 // Test multiple strings, various forms. 109 { 110 newMethodCall__test(b, &m); 111 auto str = "jkl;"s; 112 auto str2 = "JKL:"s; 113 sdbusplus::message::append(m, 1, "asdf", "ASDF"s, str, 114 std::move(str2), 5); 115 verifyTypeString = "issssi"; 116 sd_bus_call(b, m, 0, nullptr, nullptr); 117 } 118 119 // Shutdown server. 120 sd_bus_call_method(b, SERVICE, "/", INTERFACE, QUIT_METHOD, 121 nullptr, nullptr, nullptr); 122 } 123 124 int main() 125 { 126 // Initialize and start server thread. 127 pthread_t t; 128 { 129 sd_bus* b; 130 serverInit(&b); 131 pthread_create(&t, NULL, server, b); 132 } 133 134 runTests(); 135 136 // Wait for server thread to exit. 137 pthread_join(t, NULL); 138 139 return 0; 140 } 141