1 #include <boost/asio.hpp> 2 #include <chrono> 3 #include <ctime> 4 #include <iostream> 5 #include <sdbusplus/asio/connection.hpp> 6 #include <sdbusplus/asio/object_server.hpp> 7 #include <sdbusplus/asio/sd_event.hpp> 8 #include <sdbusplus/bus.hpp> 9 #include <sdbusplus/server.hpp> 10 #include <sdbusplus/timer.hpp> 11 12 int foo(int test) 13 { 14 return ++test; 15 } 16 17 int methodWithMessage(sdbusplus::message::message& m, int test) 18 { 19 return ++test; 20 } 21 22 int voidBar(void) 23 { 24 return 42; 25 } 26 27 int main() 28 { 29 using GetSubTreeType = std::vector<std::pair< 30 std::string, 31 std::vector<std::pair<std::string, std::vector<std::string>>>>>; 32 using message = sdbusplus::message::message; 33 // setup connection to dbus 34 boost::asio::io_service io; 35 auto conn = std::make_shared<sdbusplus::asio::connection>(io); 36 37 // test async method call and async send 38 auto mesg = 39 conn->new_method_call("xyz.openbmc_project.ObjectMapper", 40 "/xyz/openbmc_project/object_mapper", 41 "xyz.openbmc_project.ObjectMapper", "GetSubTree"); 42 43 static const auto depth = 2; 44 static const std::vector<std::string> interfaces = { 45 "xyz.openbmc_project.Sensor.Value"}; 46 mesg.append("/xyz/openbmc_project/Sensors", depth, interfaces); 47 48 conn->async_send(mesg, [](boost::system::error_code ec, message& ret) { 49 std::cout << "async_send callback\n"; 50 if (ec || ret.is_method_error()) 51 { 52 std::cerr << "error with async_send\n"; 53 return; 54 } 55 GetSubTreeType data; 56 ret.read(data); 57 for (auto& item : data) 58 { 59 std::cout << item.first << "\n"; 60 } 61 }); 62 63 conn->async_method_call( 64 [](boost::system::error_code ec, GetSubTreeType& subtree) { 65 std::cout << "async_method_call callback\n"; 66 if (ec) 67 { 68 std::cerr << "error with async_method_call\n"; 69 return; 70 } 71 for (auto& item : subtree) 72 { 73 std::cout << item.first << "\n"; 74 } 75 }, 76 "xyz.openbmc_project.ObjectMapper", 77 "/xyz/openbmc_project/object_mapper", 78 "xyz.openbmc_project.ObjectMapper", "GetSubTree", 79 "/org/openbmc/control", 2, std::vector<std::string>()); 80 81 // test object server 82 conn->request_name("xyz.openbmc_project.asio-test"); 83 auto server = sdbusplus::asio::object_server(conn); 84 std::shared_ptr<sdbusplus::asio::dbus_interface> iface = 85 server.add_interface("/xyz/openbmc_project/test", 86 "xyz.openbmc_project.test"); 87 // test generic properties 88 iface->register_property("int", 33, 89 sdbusplus::asio::PropertyPermission::readWrite); 90 std::vector<std::string> myStringVec = {"some", "test", "data"}; 91 std::vector<std::string> myStringVec2 = {"more", "test", "data"}; 92 93 iface->register_property("myStringVec", myStringVec, 94 sdbusplus::asio::PropertyPermission::readWrite); 95 iface->register_property("myStringVec2", myStringVec2); 96 97 // test properties with specialized callbacks 98 iface->register_property("lessThan50", 23, 99 // custom set 100 [](const int& req, int& propertyValue) { 101 if (req >= 50) 102 { 103 return -EINVAL; 104 } 105 propertyValue = req; 106 return 1; // success 107 }); 108 iface->register_property( 109 "TrailTime", std::string("foo"), 110 // custom set 111 [](const std::string& req, std::string& propertyValue) { 112 propertyValue = req; 113 return 1; // success 114 }, 115 // custom get 116 [](const std::string& property) { 117 auto now = std::chrono::system_clock::now(); 118 auto timePoint = std::chrono::system_clock::to_time_t(now); 119 return property + std::ctime(&timePoint); 120 }); 121 122 // test method creation 123 iface->register_method("TestMethod", [](const int32_t& callCount) { 124 return "success: " + std::to_string(callCount); 125 }); 126 127 iface->register_method("TestFunction", foo); 128 129 iface->register_method("TestMethodWithMessage", methodWithMessage); 130 131 iface->register_method("VoidFunctionReturnsInt", voidBar); 132 133 iface->initialize(); 134 iface->set_property("int", 45); 135 136 // sd_events work too using the default event loop 137 phosphor::Timer t1([]() { std::cerr << "*** tock ***\n"; }); 138 t1.start(std::chrono::microseconds(1000000)); 139 phosphor::Timer t2([]() { std::cerr << "*** tick ***\n"; }); 140 t2.start(std::chrono::microseconds(500000), true); 141 // add the sd_event wrapper to the io object 142 sdbusplus::asio::sd_event_wrapper sdEvents(io); 143 144 io.run(); 145 146 return 0; 147 } 148