1*4fe85a30SPatrick Williams #include <iostream> 2*4fe85a30SPatrick Williams #include <cassert> 3*4fe85a30SPatrick Williams #include <sdbusplus/message.hpp> 4*4fe85a30SPatrick Williams #include <sdbusplus/bus.hpp> 5*4fe85a30SPatrick Williams 6*4fe85a30SPatrick Williams // Global to share the dbus type string between client and server. 7*4fe85a30SPatrick Williams static std::string verifyTypeString; 8*4fe85a30SPatrick Williams 9*4fe85a30SPatrick Williams using verifyCallback_t = void(*)(sdbusplus::message::message&); 10*4fe85a30SPatrick Williams verifyCallback_t verifyCallback = nullptr; 11*4fe85a30SPatrick Williams 12*4fe85a30SPatrick Williams static constexpr auto SERVICE = "sdbusplus.test"; 13*4fe85a30SPatrick Williams static constexpr auto INTERFACE = SERVICE; 14*4fe85a30SPatrick Williams static constexpr auto TEST_METHOD = "test"; 15*4fe85a30SPatrick Williams static constexpr auto QUIT_METHOD = "quit"; 16*4fe85a30SPatrick Williams 17*4fe85a30SPatrick Williams // Open up the sdbus and claim SERVICE name. 18*4fe85a30SPatrick Williams auto serverInit() 19*4fe85a30SPatrick Williams { 20*4fe85a30SPatrick Williams auto b = sdbusplus::bus::new_default(); 21*4fe85a30SPatrick Williams b.request_name(SERVICE); 22*4fe85a30SPatrick Williams 23*4fe85a30SPatrick Williams return std::move(b); 24*4fe85a30SPatrick Williams } 25*4fe85a30SPatrick Williams 26*4fe85a30SPatrick Williams // Thread to run the dbus server. 27*4fe85a30SPatrick Williams void* server(void* b) 28*4fe85a30SPatrick Williams { 29*4fe85a30SPatrick Williams auto bus = sdbusplus::bus::bus(reinterpret_cast<sdbusplus::bus::busp_t>(b)); 30*4fe85a30SPatrick Williams 31*4fe85a30SPatrick Williams while(1) 32*4fe85a30SPatrick Williams { 33*4fe85a30SPatrick Williams // Wait for messages. 34*4fe85a30SPatrick Williams auto m = bus.process(); 35*4fe85a30SPatrick Williams 36*4fe85a30SPatrick Williams if(!m) 37*4fe85a30SPatrick Williams { 38*4fe85a30SPatrick Williams bus.wait(); 39*4fe85a30SPatrick Williams continue; 40*4fe85a30SPatrick Williams } 41*4fe85a30SPatrick Williams 42*4fe85a30SPatrick Williams if (m.is_method_call(INTERFACE, TEST_METHOD)) 43*4fe85a30SPatrick Williams { 44*4fe85a30SPatrick Williams // Verify the message type matches what the test expects. 45*4fe85a30SPatrick Williams assert(verifyTypeString == m.get_signature()); 46*4fe85a30SPatrick Williams 47*4fe85a30SPatrick Williams if (verifyCallback) 48*4fe85a30SPatrick Williams { 49*4fe85a30SPatrick Williams 50*4fe85a30SPatrick Williams verifyCallback(m); 51*4fe85a30SPatrick Williams verifyCallback = nullptr; 52*4fe85a30SPatrick Williams } 53*4fe85a30SPatrick Williams else 54*4fe85a30SPatrick Williams { 55*4fe85a30SPatrick Williams std::cout << "Warning: No verification for " 56*4fe85a30SPatrick Williams << verifyTypeString << std::endl; 57*4fe85a30SPatrick Williams } 58*4fe85a30SPatrick Williams // Reply to client. 59*4fe85a30SPatrick Williams sd_bus_reply_method_return(m.release(), nullptr); 60*4fe85a30SPatrick Williams } 61*4fe85a30SPatrick Williams else if (m.is_method_call(INTERFACE, QUIT_METHOD)) 62*4fe85a30SPatrick Williams { 63*4fe85a30SPatrick Williams // Reply and exit. 64*4fe85a30SPatrick Williams sd_bus_reply_method_return(m.release(), nullptr); 65*4fe85a30SPatrick Williams break; 66*4fe85a30SPatrick Williams } 67*4fe85a30SPatrick Williams } 68*4fe85a30SPatrick Williams } 69*4fe85a30SPatrick Williams 70*4fe85a30SPatrick Williams auto newMethodCall__test(sdbusplus::bus::bus& b) 71*4fe85a30SPatrick Williams { 72*4fe85a30SPatrick Williams // Allocate a method-call message for INTERFACE,TEST_METHOD. 73*4fe85a30SPatrick Williams return b.new_method_call(SERVICE, "/", INTERFACE, TEST_METHOD); 74*4fe85a30SPatrick Williams } 75*4fe85a30SPatrick Williams 76*4fe85a30SPatrick Williams void runTests() 77*4fe85a30SPatrick Williams { 78*4fe85a30SPatrick Williams using namespace std::literals; 79*4fe85a30SPatrick Williams 80*4fe85a30SPatrick Williams auto b = sdbusplus::bus::new_default(); 81*4fe85a30SPatrick Williams 82*4fe85a30SPatrick Williams // Test r-value int. 83*4fe85a30SPatrick Williams { 84*4fe85a30SPatrick Williams auto m = newMethodCall__test(b); 85*4fe85a30SPatrick Williams m.append(1); 86*4fe85a30SPatrick Williams verifyTypeString = "i"; 87*4fe85a30SPatrick Williams 88*4fe85a30SPatrick Williams struct verify 89*4fe85a30SPatrick Williams { 90*4fe85a30SPatrick Williams static void op(sdbusplus::message::message& m) 91*4fe85a30SPatrick Williams { 92*4fe85a30SPatrick Williams int32_t i = 0; 93*4fe85a30SPatrick Williams m.read(i); 94*4fe85a30SPatrick Williams assert(i == 1); 95*4fe85a30SPatrick Williams } 96*4fe85a30SPatrick Williams }; 97*4fe85a30SPatrick Williams verifyCallback = &verify::op; 98*4fe85a30SPatrick Williams 99*4fe85a30SPatrick Williams b.call_noreply(m); 100*4fe85a30SPatrick Williams } 101*4fe85a30SPatrick Williams // Test l-value int. 102*4fe85a30SPatrick Williams { 103*4fe85a30SPatrick Williams auto m = newMethodCall__test(b); 104*4fe85a30SPatrick Williams int a = 1; 105*4fe85a30SPatrick Williams m.append(a, a); 106*4fe85a30SPatrick Williams verifyTypeString = "ii"; 107*4fe85a30SPatrick Williams 108*4fe85a30SPatrick Williams struct verify 109*4fe85a30SPatrick Williams { 110*4fe85a30SPatrick Williams static void op(sdbusplus::message::message& m) 111*4fe85a30SPatrick Williams { 112*4fe85a30SPatrick Williams int32_t a = 0, b = 0; 113*4fe85a30SPatrick Williams m.read(a, b); 114*4fe85a30SPatrick Williams assert(a == 1); 115*4fe85a30SPatrick Williams assert(b == 1); 116*4fe85a30SPatrick Williams } 117*4fe85a30SPatrick Williams }; 118*4fe85a30SPatrick Williams verifyCallback = &verify::op; 119*4fe85a30SPatrick Williams 120*4fe85a30SPatrick Williams b.call_noreply(m); 121*4fe85a30SPatrick Williams } 122*4fe85a30SPatrick Williams 123*4fe85a30SPatrick Williams // Test multiple ints. 124*4fe85a30SPatrick Williams { 125*4fe85a30SPatrick Williams auto m = newMethodCall__test(b); 126*4fe85a30SPatrick Williams m.append(1, 2, 3, 4, 5); 127*4fe85a30SPatrick Williams verifyTypeString = "iiiii"; 128*4fe85a30SPatrick Williams 129*4fe85a30SPatrick Williams struct verify 130*4fe85a30SPatrick Williams { 131*4fe85a30SPatrick Williams static void op(sdbusplus::message::message& m) 132*4fe85a30SPatrick Williams { 133*4fe85a30SPatrick Williams int32_t a = 0, b = 0, c = 0, d = 0, e = 0; 134*4fe85a30SPatrick Williams m.read(a,b,c,d,e); 135*4fe85a30SPatrick Williams assert(a == 1); 136*4fe85a30SPatrick Williams assert(b == 2); 137*4fe85a30SPatrick Williams assert(c == 3); 138*4fe85a30SPatrick Williams assert(d == 4); 139*4fe85a30SPatrick Williams assert(e == 5); 140*4fe85a30SPatrick Williams } 141*4fe85a30SPatrick Williams }; 142*4fe85a30SPatrick Williams verifyCallback = &verify::op; 143*4fe85a30SPatrick Williams 144*4fe85a30SPatrick Williams b.call_noreply(m); 145*4fe85a30SPatrick Williams } 146*4fe85a30SPatrick Williams 147*4fe85a30SPatrick Williams // Test r-value string. 148*4fe85a30SPatrick Williams { 149*4fe85a30SPatrick Williams auto m = newMethodCall__test(b); 150*4fe85a30SPatrick Williams m.append("asdf"s); 151*4fe85a30SPatrick Williams verifyTypeString = "s"; 152*4fe85a30SPatrick Williams 153*4fe85a30SPatrick Williams struct verify 154*4fe85a30SPatrick Williams { 155*4fe85a30SPatrick Williams static void op(sdbusplus::message::message& m) 156*4fe85a30SPatrick Williams { 157*4fe85a30SPatrick Williams const char* s = nullptr; 158*4fe85a30SPatrick Williams m.read(s); 159*4fe85a30SPatrick Williams assert(0 == strcmp("asdf", s)); 160*4fe85a30SPatrick Williams } 161*4fe85a30SPatrick Williams }; 162*4fe85a30SPatrick Williams verifyCallback = &verify::op; 163*4fe85a30SPatrick Williams 164*4fe85a30SPatrick Williams b.call_noreply(m); 165*4fe85a30SPatrick Williams } 166*4fe85a30SPatrick Williams 167*4fe85a30SPatrick Williams // Test multiple strings, various forms. 168*4fe85a30SPatrick Williams { 169*4fe85a30SPatrick Williams auto m = newMethodCall__test(b); 170*4fe85a30SPatrick Williams auto str = "jkl;"s; 171*4fe85a30SPatrick Williams auto str2 = "JKL:"s; 172*4fe85a30SPatrick Williams m.append(1, "asdf", "ASDF"s, str, 173*4fe85a30SPatrick Williams std::move(str2), 5); 174*4fe85a30SPatrick Williams verifyTypeString = "issssi"; 175*4fe85a30SPatrick Williams 176*4fe85a30SPatrick Williams struct verify 177*4fe85a30SPatrick Williams { 178*4fe85a30SPatrick Williams static void op(sdbusplus::message::message& m) 179*4fe85a30SPatrick Williams { 180*4fe85a30SPatrick Williams int32_t a = 0, b = 0; 181*4fe85a30SPatrick Williams std::string s0, s1, s2, s3; 182*4fe85a30SPatrick Williams m.read(a, s0, s1, s2, s3, b); 183*4fe85a30SPatrick Williams assert(a == 1); 184*4fe85a30SPatrick Williams assert(b == 5); 185*4fe85a30SPatrick Williams assert(s0 == "asdf"s); 186*4fe85a30SPatrick Williams assert(s1 == "ASDF"s); 187*4fe85a30SPatrick Williams assert(s2 == "jkl;"s); 188*4fe85a30SPatrick Williams assert(s3 == "JKL:"); 189*4fe85a30SPatrick Williams } 190*4fe85a30SPatrick Williams }; 191*4fe85a30SPatrick Williams verifyCallback = &verify::op; 192*4fe85a30SPatrick Williams 193*4fe85a30SPatrick Williams b.call_noreply(m); 194*4fe85a30SPatrick Williams } 195*4fe85a30SPatrick Williams 196*4fe85a30SPatrick Williams // Shutdown server. 197*4fe85a30SPatrick Williams { 198*4fe85a30SPatrick Williams auto m = b.new_method_call(SERVICE, "/", INTERFACE, QUIT_METHOD); 199*4fe85a30SPatrick Williams b.call_noreply(m); 200*4fe85a30SPatrick Williams } 201*4fe85a30SPatrick Williams } 202*4fe85a30SPatrick Williams 203*4fe85a30SPatrick Williams int main() 204*4fe85a30SPatrick Williams { 205*4fe85a30SPatrick Williams 206*4fe85a30SPatrick Williams // Initialize and start server thread. 207*4fe85a30SPatrick Williams pthread_t t; 208*4fe85a30SPatrick Williams { 209*4fe85a30SPatrick Williams auto b = serverInit(); 210*4fe85a30SPatrick Williams pthread_create(&t, NULL, server, b.release()); 211*4fe85a30SPatrick Williams } 212*4fe85a30SPatrick Williams 213*4fe85a30SPatrick Williams runTests(); 214*4fe85a30SPatrick Williams 215*4fe85a30SPatrick Williams // Wait for server thread to exit. 216*4fe85a30SPatrick Williams pthread_join(t, NULL); 217*4fe85a30SPatrick Williams 218*4fe85a30SPatrick Williams return 0; 219*4fe85a30SPatrick Williams } 220