| Patrick Venture | 95269db | 2018-08-31 09:19:17 -0700 | [diff] [blame] | 1 | #include <boost/asio.hpp> | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 2 | #include <boost/asio/spawn.hpp> | 
| James Feist | fce038a | 2018-04-13 15:43:13 -0700 | [diff] [blame] | 3 | #include <chrono> | 
| Patrick Venture | 95269db | 2018-08-31 09:19:17 -0700 | [diff] [blame] | 4 | #include <ctime> | 
|  | 5 | #include <iostream> | 
| James Feist | 284a0f9 | 2018-04-05 15:28:16 -0700 | [diff] [blame] | 6 | #include <sdbusplus/asio/connection.hpp> | 
| James Feist | fce038a | 2018-04-13 15:43:13 -0700 | [diff] [blame] | 7 | #include <sdbusplus/asio/object_server.hpp> | 
| Vernon Mauery | 035c73b | 2018-09-05 12:15:27 -0700 | [diff] [blame] | 8 | #include <sdbusplus/asio/sd_event.hpp> | 
| Patrick Venture | 95269db | 2018-08-31 09:19:17 -0700 | [diff] [blame] | 9 | #include <sdbusplus/bus.hpp> | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 10 | #include <sdbusplus/exception.hpp> | 
| Patrick Venture | 95269db | 2018-08-31 09:19:17 -0700 | [diff] [blame] | 11 | #include <sdbusplus/server.hpp> | 
| Vernon Mauery | 035c73b | 2018-09-05 12:15:27 -0700 | [diff] [blame] | 12 | #include <sdbusplus/timer.hpp> | 
| William A. Kennington III | 4274c11 | 2018-11-26 09:50:13 -0800 | [diff] [blame] | 13 | #include <variant> | 
| James Feist | 284a0f9 | 2018-04-05 15:28:16 -0700 | [diff] [blame] | 14 |  | 
| William A. Kennington III | 4274c11 | 2018-11-26 09:50:13 -0800 | [diff] [blame] | 15 | using variant = std::variant<int, std::string>; | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 16 |  | 
| James Feist | fce038a | 2018-04-13 15:43:13 -0700 | [diff] [blame] | 17 | int foo(int test) | 
|  | 18 | { | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 19 | std::cout << "foo(" << test << ") -> " << (test + 1) << "\n"; | 
| James Feist | fce038a | 2018-04-13 15:43:13 -0700 | [diff] [blame] | 20 | return ++test; | 
|  | 21 | } | 
|  | 22 |  | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 23 | // called from coroutine context, can make yielding dbus calls | 
|  | 24 | int fooYield(boost::asio::yield_context yield, | 
|  | 25 | std::shared_ptr<sdbusplus::asio::connection> conn, int test) | 
|  | 26 | { | 
|  | 27 | // fetch the real value from testFunction | 
|  | 28 | boost::system::error_code ec; | 
|  | 29 | std::cout << "fooYield(yield, " << test << ")...\n"; | 
|  | 30 | int testCount = conn->yield_method_call<int>( | 
| Vernon Mauery | 37a5e61 | 2019-05-07 16:53:50 -0700 | [diff] [blame] | 31 | yield, ec, "xyz.openbmc_project.asio-test", "/xyz/openbmc_project/test", | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 32 | "xyz.openbmc_project.test", "TestFunction", test); | 
|  | 33 | if (ec || testCount != (test + 1)) | 
|  | 34 | { | 
|  | 35 | std::cout << "call to foo failed: ec = " << ec << '\n'; | 
|  | 36 | return -1; | 
|  | 37 | } | 
|  | 38 | std::cout << "yielding call to foo OK! (-> " << testCount << ")\n"; | 
|  | 39 | return testCount; | 
|  | 40 | } | 
|  | 41 |  | 
| Vernon Mauery | 8ce61e4 | 2018-08-28 08:54:59 -0700 | [diff] [blame] | 42 | int methodWithMessage(sdbusplus::message::message& m, int test) | 
|  | 43 | { | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 44 | std::cout << "methodWithMessage(m, " << test << ") -> " << (test + 1) | 
|  | 45 | << "\n"; | 
| Vernon Mauery | 8ce61e4 | 2018-08-28 08:54:59 -0700 | [diff] [blame] | 46 | return ++test; | 
|  | 47 | } | 
|  | 48 |  | 
| Vernon Mauery | 2c8f93f | 2018-09-05 12:02:39 -0700 | [diff] [blame] | 49 | int voidBar(void) | 
|  | 50 | { | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 51 | std::cout << "voidBar() -> 42\n"; | 
| Vernon Mauery | 2c8f93f | 2018-09-05 12:02:39 -0700 | [diff] [blame] | 52 | return 42; | 
|  | 53 | } | 
|  | 54 |  | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 55 | void do_start_async_method_call_one( | 
|  | 56 | std::shared_ptr<sdbusplus::asio::connection> conn, | 
|  | 57 | boost::asio::yield_context yield) | 
|  | 58 | { | 
|  | 59 | boost::system::error_code ec; | 
|  | 60 | variant testValue; | 
| Vernon Mauery | 37a5e61 | 2019-05-07 16:53:50 -0700 | [diff] [blame] | 61 | conn->yield_method_call<>(yield, ec, "xyz.openbmc_project.asio-test", | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 62 | "/xyz/openbmc_project/test", | 
|  | 63 | "org.freedesktop.DBus.Properties", "Set", | 
|  | 64 | "xyz.openbmc_project.test", "int", variant(24)); | 
|  | 65 | testValue = conn->yield_method_call<variant>( | 
| Vernon Mauery | 37a5e61 | 2019-05-07 16:53:50 -0700 | [diff] [blame] | 66 | yield, ec, "xyz.openbmc_project.asio-test", "/xyz/openbmc_project/test", | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 67 | "org.freedesktop.DBus.Properties", "Get", "xyz.openbmc_project.test", | 
|  | 68 | "int"); | 
| William A. Kennington III | 4274c11 | 2018-11-26 09:50:13 -0800 | [diff] [blame] | 69 | if (!ec && std::get<int>(testValue) == 24) | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 70 | { | 
|  | 71 | std::cout << "async call to Properties.Get serialized via yield OK!\n"; | 
|  | 72 | } | 
|  | 73 | else | 
|  | 74 | { | 
| William A. Kennington III | 4274c11 | 2018-11-26 09:50:13 -0800 | [diff] [blame] | 75 | std::cout << "ec = " << ec << ": " << std::get<int>(testValue) << "\n"; | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 76 | } | 
|  | 77 | conn->yield_method_call<void>( | 
| Vernon Mauery | 37a5e61 | 2019-05-07 16:53:50 -0700 | [diff] [blame] | 78 | yield, ec, "xyz.openbmc_project.asio-test", "/xyz/openbmc_project/test", | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 79 | "org.freedesktop.DBus.Properties", "Set", "xyz.openbmc_project.test", | 
|  | 80 | "int", variant(42)); | 
|  | 81 | testValue = conn->yield_method_call<variant>( | 
| Vernon Mauery | 37a5e61 | 2019-05-07 16:53:50 -0700 | [diff] [blame] | 82 | yield, ec, "xyz.openbmc_project.asio-test", "/xyz/openbmc_project/test", | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 83 | "org.freedesktop.DBus.Properties", "Get", "xyz.openbmc_project.test", | 
|  | 84 | "int"); | 
| William A. Kennington III | 4274c11 | 2018-11-26 09:50:13 -0800 | [diff] [blame] | 85 | if (!ec && std::get<int>(testValue) == 42) | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 86 | { | 
|  | 87 | std::cout << "async call to Properties.Get serialized via yield OK!\n"; | 
|  | 88 | } | 
|  | 89 | else | 
|  | 90 | { | 
| William A. Kennington III | 4274c11 | 2018-11-26 09:50:13 -0800 | [diff] [blame] | 91 | std::cout << "ec = " << ec << ": " << std::get<int>(testValue) << "\n"; | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 92 | } | 
|  | 93 | } | 
|  | 94 |  | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 95 | void do_start_async_ipmi_call(std::shared_ptr<sdbusplus::asio::connection> conn, | 
|  | 96 | boost::asio::yield_context yield) | 
|  | 97 | { | 
|  | 98 | auto method = conn->new_method_call("xyz.openbmc_project.asio-test", | 
|  | 99 | "/xyz/openbmc_project/test", | 
|  | 100 | "xyz.openbmc_project.test", "execute"); | 
|  | 101 | constexpr uint8_t netFn = 6; | 
|  | 102 | constexpr uint8_t lun = 0; | 
|  | 103 | constexpr uint8_t cmd = 1; | 
|  | 104 | std::map<std::string, variant> options = {{"username", variant("admin")}, | 
|  | 105 | {"privilege", variant(4)}}; | 
|  | 106 | std::vector<uint8_t> commandData = {4, 3, 2, 1}; | 
|  | 107 | method.append(netFn, lun, cmd, commandData, options); | 
|  | 108 | boost::system::error_code ec; | 
|  | 109 | sdbusplus::message::message reply = conn->async_send(method, yield[ec]); | 
|  | 110 | std::tuple<uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>> | 
|  | 111 | tupleOut; | 
|  | 112 | try | 
|  | 113 | { | 
|  | 114 | reply.read(tupleOut); | 
|  | 115 | } | 
|  | 116 | catch (const sdbusplus::exception::SdBusError& e) | 
|  | 117 | { | 
|  | 118 | std::cerr << "failed to unpack; sig is " << reply.get_signature() | 
|  | 119 | << "\n"; | 
|  | 120 | } | 
|  | 121 | auto& [rnetFn, rlun, rcmd, cc, responseData] = tupleOut; | 
|  | 122 | std::vector<uint8_t> expRsp = {1, 2, 3, 4}; | 
|  | 123 | if (rnetFn == uint8_t(netFn + 1) && rlun == lun && rcmd == cmd && cc == 0 && | 
|  | 124 | responseData == expRsp) | 
|  | 125 | { | 
|  | 126 | std::cerr << "ipmi call returns OK!\n"; | 
|  | 127 | } | 
|  | 128 | else | 
|  | 129 | { | 
|  | 130 | std::cerr << "ipmi call returns unexpected response\n"; | 
|  | 131 | } | 
|  | 132 | } | 
|  | 133 |  | 
|  | 134 | auto ipmiInterface(boost::asio::yield_context yield, uint8_t netFn, uint8_t lun, | 
|  | 135 | uint8_t cmd, std::vector<uint8_t>& data, | 
|  | 136 | const std::map<std::string, variant>& options) | 
|  | 137 | { | 
|  | 138 | std::vector<uint8_t> reply = {1, 2, 3, 4}; | 
|  | 139 | uint8_t cc = 0; | 
|  | 140 | std::cerr << "ipmiInterface:execute(" << int(netFn) << int(cmd) << ")\n"; | 
|  | 141 | return std::make_tuple(uint8_t(netFn + 1), lun, cmd, cc, reply); | 
|  | 142 | } | 
|  | 143 |  | 
|  | 144 | void do_start_async_to_yield(std::shared_ptr<sdbusplus::asio::connection> conn, | 
|  | 145 | boost::asio::yield_context yield) | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 146 | { | 
|  | 147 | boost::system::error_code ec; | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 148 | int testValue = 0; | 
| Vernon Mauery | c077190 | 2019-05-07 16:53:50 -0700 | [diff] [blame] | 149 | testValue = conn->yield_method_call<int>( | 
|  | 150 | yield, ec, "xyz.openbmc_project.asio-test", "/xyz/openbmc_project/test", | 
|  | 151 | "xyz.openbmc_project.test", "TestYieldFunction", int(41)); | 
|  | 152 |  | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 153 | if (!ec && testValue == 42) | 
|  | 154 | { | 
|  | 155 | std::cout | 
|  | 156 | << "yielding call to TestYieldFunction serialized via yield OK!\n"; | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 157 | } | 
|  | 158 | else | 
|  | 159 | { | 
|  | 160 | std::cout << "ec = " << ec << ": " << testValue << "\n"; | 
|  | 161 | } | 
| Vernon Mauery | c077190 | 2019-05-07 16:53:50 -0700 | [diff] [blame] | 162 |  | 
|  | 163 | ec.clear(); | 
|  | 164 | auto badValue = conn->yield_method_call<std::string>( | 
|  | 165 | yield, ec, "xyz.openbmc_project.asio-test", "/xyz/openbmc_project/test", | 
|  | 166 | "xyz.openbmc_project.test", "TestYieldFunction", int(41)); | 
|  | 167 |  | 
|  | 168 | if (!ec) | 
|  | 169 | { | 
|  | 170 | std::cout | 
|  | 171 | << "yielding call to TestYieldFunction returned the wrong type\n"; | 
|  | 172 | } | 
|  | 173 | else | 
|  | 174 | { | 
|  | 175 | std::cout << "TestYieldFunction expected error: " << ec << "\n"; | 
|  | 176 | } | 
|  | 177 |  | 
|  | 178 | ec.clear(); | 
|  | 179 | auto unUsedValue = conn->yield_method_call<std::string>( | 
|  | 180 | yield, ec, "xyz.openbmc_project.asio-test", "/xyz/openbmc_project/test", | 
|  | 181 | "xyz.openbmc_project.test", "TestYieldFunctionNotExits", int(41)); | 
|  | 182 |  | 
|  | 183 | if (!ec) | 
|  | 184 | { | 
|  | 185 | std::cout << "TestYieldFunctionNotExists returned unexpectedly\n"; | 
|  | 186 | } | 
|  | 187 | else | 
|  | 188 | { | 
|  | 189 | std::cout << "TestYieldFunctionNotExits expected error: " << ec << "\n"; | 
|  | 190 | } | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 191 | } | 
|  | 192 |  | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 193 | int server() | 
| James Feist | 284a0f9 | 2018-04-05 15:28:16 -0700 | [diff] [blame] | 194 | { | 
| James Feist | 284a0f9 | 2018-04-05 15:28:16 -0700 | [diff] [blame] | 195 | // setup connection to dbus | 
| Ed Tanous | c7d104d | 2019-01-02 14:15:50 -0800 | [diff] [blame] | 196 | boost::asio::io_context io; | 
| James Feist | 284a0f9 | 2018-04-05 15:28:16 -0700 | [diff] [blame] | 197 | auto conn = std::make_shared<sdbusplus::asio::connection>(io); | 
|  | 198 |  | 
| James Feist | fce038a | 2018-04-13 15:43:13 -0700 | [diff] [blame] | 199 | // test object server | 
|  | 200 | conn->request_name("xyz.openbmc_project.asio-test"); | 
|  | 201 | auto server = sdbusplus::asio::object_server(conn); | 
|  | 202 | std::shared_ptr<sdbusplus::asio::dbus_interface> iface = | 
|  | 203 | server.add_interface("/xyz/openbmc_project/test", | 
|  | 204 | "xyz.openbmc_project.test"); | 
|  | 205 | // test generic properties | 
|  | 206 | iface->register_property("int", 33, | 
|  | 207 | sdbusplus::asio::PropertyPermission::readWrite); | 
|  | 208 | std::vector<std::string> myStringVec = {"some", "test", "data"}; | 
|  | 209 | std::vector<std::string> myStringVec2 = {"more", "test", "data"}; | 
|  | 210 |  | 
|  | 211 | iface->register_property("myStringVec", myStringVec, | 
|  | 212 | sdbusplus::asio::PropertyPermission::readWrite); | 
|  | 213 | iface->register_property("myStringVec2", myStringVec2); | 
|  | 214 |  | 
|  | 215 | // test properties with specialized callbacks | 
|  | 216 | iface->register_property("lessThan50", 23, | 
|  | 217 | // custom set | 
|  | 218 | [](const int& req, int& propertyValue) { | 
|  | 219 | if (req >= 50) | 
|  | 220 | { | 
|  | 221 | return -EINVAL; | 
|  | 222 | } | 
|  | 223 | propertyValue = req; | 
|  | 224 | return 1; // success | 
|  | 225 | }); | 
|  | 226 | iface->register_property( | 
|  | 227 | "TrailTime", std::string("foo"), | 
|  | 228 | // custom set | 
|  | 229 | [](const std::string& req, std::string& propertyValue) { | 
|  | 230 | propertyValue = req; | 
|  | 231 | return 1; // success | 
|  | 232 | }, | 
|  | 233 | // custom get | 
|  | 234 | [](const std::string& property) { | 
|  | 235 | auto now = std::chrono::system_clock::now(); | 
|  | 236 | auto timePoint = std::chrono::system_clock::to_time_t(now); | 
|  | 237 | return property + std::ctime(&timePoint); | 
|  | 238 | }); | 
|  | 239 |  | 
|  | 240 | // test method creation | 
|  | 241 | iface->register_method("TestMethod", [](const int32_t& callCount) { | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 242 | return std::make_tuple(callCount, | 
|  | 243 | "success: " + std::to_string(callCount)); | 
| James Feist | fce038a | 2018-04-13 15:43:13 -0700 | [diff] [blame] | 244 | }); | 
|  | 245 |  | 
|  | 246 | iface->register_method("TestFunction", foo); | 
|  | 247 |  | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 248 | // fooYield has boost::asio::yield_context as first argument | 
|  | 249 | // so will be executed in coroutine context if called | 
|  | 250 | iface->register_method("TestYieldFunction", | 
|  | 251 | [conn](boost::asio::yield_context yield, int val) { | 
|  | 252 | return fooYield(yield, conn, val); | 
|  | 253 | }); | 
|  | 254 |  | 
| Vernon Mauery | 8ce61e4 | 2018-08-28 08:54:59 -0700 | [diff] [blame] | 255 | iface->register_method("TestMethodWithMessage", methodWithMessage); | 
|  | 256 |  | 
| Vernon Mauery | 2c8f93f | 2018-09-05 12:02:39 -0700 | [diff] [blame] | 257 | iface->register_method("VoidFunctionReturnsInt", voidBar); | 
|  | 258 |  | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 259 | iface->register_method("execute", ipmiInterface); | 
|  | 260 |  | 
| James Feist | fce038a | 2018-04-13 15:43:13 -0700 | [diff] [blame] | 261 | iface->initialize(); | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 262 |  | 
|  | 263 | io.run(); | 
|  | 264 |  | 
|  | 265 | return 0; | 
|  | 266 | } | 
|  | 267 |  | 
|  | 268 | int client() | 
|  | 269 | { | 
|  | 270 | using GetSubTreeType = std::vector<std::pair< | 
|  | 271 | std::string, | 
|  | 272 | std::vector<std::pair<std::string, std::vector<std::string>>>>>; | 
|  | 273 | using message = sdbusplus::message::message; | 
|  | 274 |  | 
|  | 275 | // setup connection to dbus | 
| Ed Tanous | c7d104d | 2019-01-02 14:15:50 -0800 | [diff] [blame] | 276 | boost::asio::io_context io; | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 277 | auto conn = std::make_shared<sdbusplus::asio::connection>(io); | 
|  | 278 |  | 
|  | 279 | int ready = 0; | 
|  | 280 | while (!ready) | 
|  | 281 | { | 
|  | 282 | auto readyMsg = conn->new_method_call( | 
|  | 283 | "xyz.openbmc_project.asio-test", "/xyz/openbmc_project/test", | 
|  | 284 | "xyz.openbmc_project.test", "VoidFunctionReturnsInt"); | 
|  | 285 | try | 
|  | 286 | { | 
|  | 287 | message intMsg = conn->call(readyMsg); | 
|  | 288 | intMsg.read(ready); | 
|  | 289 | } | 
|  | 290 | catch (sdbusplus::exception::SdBusError& e) | 
|  | 291 | { | 
|  | 292 | ready = 0; | 
|  | 293 | // pause to give the server a chance to start up | 
|  | 294 | usleep(10000); | 
|  | 295 | } | 
|  | 296 | } | 
|  | 297 |  | 
|  | 298 | // test async method call and async send | 
|  | 299 | auto mesg = | 
|  | 300 | conn->new_method_call("xyz.openbmc_project.ObjectMapper", | 
|  | 301 | "/xyz/openbmc_project/object_mapper", | 
|  | 302 | "xyz.openbmc_project.ObjectMapper", "GetSubTree"); | 
|  | 303 |  | 
|  | 304 | static const auto depth = 2; | 
|  | 305 | static const std::vector<std::string> interfaces = { | 
|  | 306 | "xyz.openbmc_project.Sensor.Value"}; | 
|  | 307 | mesg.append("/xyz/openbmc_project/Sensors", depth, interfaces); | 
|  | 308 |  | 
|  | 309 | conn->async_send(mesg, [](boost::system::error_code ec, message& ret) { | 
|  | 310 | std::cout << "async_send callback\n"; | 
|  | 311 | if (ec || ret.is_method_error()) | 
|  | 312 | { | 
|  | 313 | std::cerr << "error with async_send\n"; | 
|  | 314 | return; | 
|  | 315 | } | 
|  | 316 | GetSubTreeType data; | 
|  | 317 | ret.read(data); | 
|  | 318 | for (auto& item : data) | 
|  | 319 | { | 
|  | 320 | std::cout << item.first << "\n"; | 
|  | 321 | } | 
|  | 322 | }); | 
|  | 323 |  | 
|  | 324 | conn->async_method_call( | 
|  | 325 | [](boost::system::error_code ec, GetSubTreeType& subtree) { | 
|  | 326 | std::cout << "async_method_call callback\n"; | 
|  | 327 | if (ec) | 
|  | 328 | { | 
|  | 329 | std::cerr << "error with async_method_call\n"; | 
|  | 330 | return; | 
|  | 331 | } | 
|  | 332 | for (auto& item : subtree) | 
|  | 333 | { | 
|  | 334 | std::cout << item.first << "\n"; | 
|  | 335 | } | 
|  | 336 | }, | 
|  | 337 | "xyz.openbmc_project.ObjectMapper", | 
|  | 338 | "/xyz/openbmc_project/object_mapper", | 
|  | 339 | "xyz.openbmc_project.ObjectMapper", "GetSubTree", | 
|  | 340 | "/org/openbmc/control", 2, std::vector<std::string>()); | 
| Vernon Mauery | 035c73b | 2018-09-05 12:15:27 -0700 | [diff] [blame] | 341 |  | 
| James Feist | c14699f | 2019-06-04 14:11:48 -0700 | [diff] [blame] | 342 | std::string nonConstCapture = "lalalala"; | 
| Vernon Mauery | c077190 | 2019-05-07 16:53:50 -0700 | [diff] [blame] | 343 | conn->async_method_call( | 
| James Feist | c14699f | 2019-06-04 14:11:48 -0700 | [diff] [blame] | 344 | [nonConstCapture = std::move(nonConstCapture)]( | 
|  | 345 | boost::system::error_code ec, | 
|  | 346 | const std::vector<std::string>& things) mutable { | 
| Vernon Mauery | c077190 | 2019-05-07 16:53:50 -0700 | [diff] [blame] | 347 | std::cout << "async_method_call callback\n"; | 
| James Feist | c14699f | 2019-06-04 14:11:48 -0700 | [diff] [blame] | 348 | nonConstCapture += " stuff"; | 
| Vernon Mauery | c077190 | 2019-05-07 16:53:50 -0700 | [diff] [blame] | 349 | if (ec) | 
|  | 350 | { | 
|  | 351 | std::cerr << "async_method_call expected failure: " << ec | 
|  | 352 | << "\n"; | 
|  | 353 | } | 
|  | 354 | else | 
|  | 355 | { | 
| James Feist | c14699f | 2019-06-04 14:11:48 -0700 | [diff] [blame] | 356 | std::cerr << "async_method_call should have failed!\n"; | 
| Vernon Mauery | c077190 | 2019-05-07 16:53:50 -0700 | [diff] [blame] | 357 | } | 
|  | 358 | }, | 
|  | 359 | "xyz.openbmc_project.ObjectMapper", | 
|  | 360 | "/xyz/openbmc_project/object_mapper", | 
|  | 361 | "xyz.openbmc_project.ObjectMapper", "GetSubTree", | 
|  | 362 | "/xyz/openbmc_project/sensors", depth, interfaces); | 
|  | 363 |  | 
| Vernon Mauery | 035c73b | 2018-09-05 12:15:27 -0700 | [diff] [blame] | 364 | // sd_events work too using the default event loop | 
|  | 365 | phosphor::Timer t1([]() { std::cerr << "*** tock ***\n"; }); | 
|  | 366 | t1.start(std::chrono::microseconds(1000000)); | 
|  | 367 | phosphor::Timer t2([]() { std::cerr << "*** tick ***\n"; }); | 
|  | 368 | t2.start(std::chrono::microseconds(500000), true); | 
|  | 369 | // add the sd_event wrapper to the io object | 
|  | 370 | sdbusplus::asio::sd_event_wrapper sdEvents(io); | 
|  | 371 |  | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 372 | // set up a client to make an async call to the server | 
|  | 373 | // using coroutines (userspace cooperative multitasking) | 
|  | 374 | boost::asio::spawn(io, [conn](boost::asio::yield_context yield) { | 
|  | 375 | do_start_async_method_call_one(conn, yield); | 
|  | 376 | }); | 
|  | 377 | boost::asio::spawn(io, [conn](boost::asio::yield_context yield) { | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 378 | do_start_async_ipmi_call(conn, yield); | 
| Vernon Mauery | 261e72b | 2018-09-25 12:34:25 -0700 | [diff] [blame] | 379 | }); | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 380 | boost::asio::spawn(io, [conn](boost::asio::yield_context yield) { | 
|  | 381 | do_start_async_to_yield(conn, yield); | 
|  | 382 | }); | 
|  | 383 |  | 
|  | 384 | conn->async_method_call( | 
|  | 385 | [](boost::system::error_code ec, int32_t testValue) { | 
|  | 386 | if (ec) | 
|  | 387 | { | 
|  | 388 | std::cerr << "TestYieldFunction returned error with " | 
|  | 389 | "async_method_call (ec = " | 
|  | 390 | << ec << ")\n"; | 
|  | 391 | return; | 
|  | 392 | } | 
|  | 393 | std::cout << "TestYieldFunction return " << testValue << "\n"; | 
|  | 394 | }, | 
|  | 395 | "xyz.openbmc_project.asio-test", "/xyz/openbmc_project/test", | 
|  | 396 | "xyz.openbmc_project.test", "TestYieldFunction", int32_t(41)); | 
| James Feist | 284a0f9 | 2018-04-05 15:28:16 -0700 | [diff] [blame] | 397 | io.run(); | 
|  | 398 |  | 
|  | 399 | return 0; | 
|  | 400 | } | 
| Vernon Mauery | 076d14a | 2018-10-02 15:10:20 -0700 | [diff] [blame] | 401 |  | 
|  | 402 | int main(int argc, const char* argv[]) | 
|  | 403 | { | 
|  | 404 | if (argc == 1) | 
|  | 405 | { | 
|  | 406 | int pid = fork(); | 
|  | 407 | if (pid == 0) | 
|  | 408 | { | 
|  | 409 | return client(); | 
|  | 410 | } | 
|  | 411 | else if (pid > 0) | 
|  | 412 | { | 
|  | 413 | return server(); | 
|  | 414 | } | 
|  | 415 | return pid; | 
|  | 416 | } | 
|  | 417 | if (std::string(argv[1]) == "--server") | 
|  | 418 | { | 
|  | 419 | return server(); | 
|  | 420 | } | 
|  | 421 | if (std::string(argv[1]) == "--client") | 
|  | 422 | { | 
|  | 423 | return client(); | 
|  | 424 | } | 
|  | 425 | std::cout << "usage: " << argv[0] << " [--server | --client]\n"; | 
|  | 426 | return -1; | 
|  | 427 | } |