blob: 9819ebaac1b9a70cfbbb114ccd60d723d830b3d0 [file] [log] [blame]
Patrick Venture95269db2018-08-31 09:19:17 -07001#include <boost/asio.hpp>
Vernon Mauery261e72b2018-09-25 12:34:25 -07002#include <boost/asio/spawn.hpp>
James Feistfce038a2018-04-13 15:43:13 -07003#include <chrono>
Patrick Venture95269db2018-08-31 09:19:17 -07004#include <ctime>
5#include <iostream>
James Feist284a0f92018-04-05 15:28:16 -07006#include <sdbusplus/asio/connection.hpp>
James Feistfce038a2018-04-13 15:43:13 -07007#include <sdbusplus/asio/object_server.hpp>
Vernon Mauery035c73b2018-09-05 12:15:27 -07008#include <sdbusplus/asio/sd_event.hpp>
Patrick Venture95269db2018-08-31 09:19:17 -07009#include <sdbusplus/bus.hpp>
10#include <sdbusplus/server.hpp>
Vernon Mauery035c73b2018-09-05 12:15:27 -070011#include <sdbusplus/timer.hpp>
James Feist284a0f92018-04-05 15:28:16 -070012
Vernon Mauery261e72b2018-09-25 12:34:25 -070013using variant = sdbusplus::message::variant<int, std::string>;
James Feistfce038a2018-04-13 15:43:13 -070014int foo(int test)
15{
16 return ++test;
17}
18
Vernon Mauery8ce61e42018-08-28 08:54:59 -070019int methodWithMessage(sdbusplus::message::message& m, int test)
20{
21 return ++test;
22}
23
Vernon Mauery2c8f93f2018-09-05 12:02:39 -070024int voidBar(void)
25{
26 return 42;
27}
28
Vernon Mauery261e72b2018-09-25 12:34:25 -070029void do_start_async_method_call_one(
30 std::shared_ptr<sdbusplus::asio::connection> conn,
31 boost::asio::yield_context yield)
32{
33 boost::system::error_code ec;
34 variant testValue;
35 conn->yield_method_call<>(yield[ec], "xyz.openbmc_project.asio-test",
36 "/xyz/openbmc_project/test",
37 "org.freedesktop.DBus.Properties", "Set",
38 "xyz.openbmc_project.test", "int", variant(24));
39 testValue = conn->yield_method_call<variant>(
40 yield[ec], "xyz.openbmc_project.asio-test", "/xyz/openbmc_project/test",
41 "org.freedesktop.DBus.Properties", "Get", "xyz.openbmc_project.test",
42 "int");
43 if (!ec && testValue.get<int>() == 24)
44 {
45 std::cout << "async call to Properties.Get serialized via yield OK!\n";
46 }
47 else
48 {
49 std::cout << "ec = " << ec << ": " << testValue.get<int>() << "\n";
50 }
51 conn->yield_method_call<void>(
52 yield[ec], "xyz.openbmc_project.asio-test", "/xyz/openbmc_project/test",
53 "org.freedesktop.DBus.Properties", "Set", "xyz.openbmc_project.test",
54 "int", variant(42));
55 testValue = conn->yield_method_call<variant>(
56 yield[ec], "xyz.openbmc_project.asio-test", "/xyz/openbmc_project/test",
57 "org.freedesktop.DBus.Properties", "Get", "xyz.openbmc_project.test",
58 "int");
59 if (!ec && testValue.get<int>() == 42)
60 {
61 std::cout << "async call to Properties.Get serialized via yield OK!\n";
62 }
63 else
64 {
65 std::cout << "ec = " << ec << ": " << testValue.get<int>() << "\n";
66 }
67}
68
69void do_start_async_method_call_two(
70 std::shared_ptr<sdbusplus::asio::connection> conn,
71 boost::asio::yield_context yield)
72{
73 boost::system::error_code ec;
74 int32_t testCount;
75 std::string testValue;
76 std::tie(testCount, testValue) =
77 conn->yield_method_call<int32_t, std::string>(
78 yield[ec], "xyz.openbmc_project.asio-test",
79 "/xyz/openbmc_project/test", "xyz.openbmc_project.test",
80 "TestMethod", int32_t(42));
81 if (!ec && testCount == 42 && testValue == "success: 42")
82 {
83 std::cout << "async call to TestMethod serialized via yield OK!\n";
84 }
85 else
86 {
87 std::cout << "ec = " << ec << ": " << testValue << "\n";
88 }
89}
90
James Feist284a0f92018-04-05 15:28:16 -070091int main()
92{
93 using GetSubTreeType = std::vector<std::pair<
94 std::string,
95 std::vector<std::pair<std::string, std::vector<std::string>>>>>;
96 using message = sdbusplus::message::message;
97 // setup connection to dbus
98 boost::asio::io_service io;
99 auto conn = std::make_shared<sdbusplus::asio::connection>(io);
100
101 // test async method call and async send
102 auto mesg =
103 conn->new_method_call("xyz.openbmc_project.ObjectMapper",
104 "/xyz/openbmc_project/object_mapper",
105 "xyz.openbmc_project.ObjectMapper", "GetSubTree");
106
107 static const auto depth = 2;
108 static const std::vector<std::string> interfaces = {
109 "xyz.openbmc_project.Sensor.Value"};
110 mesg.append("/xyz/openbmc_project/Sensors", depth, interfaces);
111
112 conn->async_send(mesg, [](boost::system::error_code ec, message& ret) {
113 std::cout << "async_send callback\n";
114 if (ec || ret.is_method_error())
115 {
116 std::cerr << "error with async_send\n";
117 return;
118 }
119 GetSubTreeType data;
120 ret.read(data);
121 for (auto& item : data)
122 {
123 std::cout << item.first << "\n";
124 }
125 });
126
127 conn->async_method_call(
128 [](boost::system::error_code ec, GetSubTreeType& subtree) {
129 std::cout << "async_method_call callback\n";
130 if (ec)
131 {
132 std::cerr << "error with async_method_call\n";
133 return;
134 }
135 for (auto& item : subtree)
136 {
137 std::cout << item.first << "\n";
138 }
James Feist284a0f92018-04-05 15:28:16 -0700139 },
140 "xyz.openbmc_project.ObjectMapper",
141 "/xyz/openbmc_project/object_mapper",
142 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
143 "/org/openbmc/control", 2, std::vector<std::string>());
144
James Feistfce038a2018-04-13 15:43:13 -0700145 // test object server
146 conn->request_name("xyz.openbmc_project.asio-test");
147 auto server = sdbusplus::asio::object_server(conn);
148 std::shared_ptr<sdbusplus::asio::dbus_interface> iface =
149 server.add_interface("/xyz/openbmc_project/test",
150 "xyz.openbmc_project.test");
151 // test generic properties
152 iface->register_property("int", 33,
153 sdbusplus::asio::PropertyPermission::readWrite);
154 std::vector<std::string> myStringVec = {"some", "test", "data"};
155 std::vector<std::string> myStringVec2 = {"more", "test", "data"};
156
157 iface->register_property("myStringVec", myStringVec,
158 sdbusplus::asio::PropertyPermission::readWrite);
159 iface->register_property("myStringVec2", myStringVec2);
160
161 // test properties with specialized callbacks
162 iface->register_property("lessThan50", 23,
163 // custom set
164 [](const int& req, int& propertyValue) {
165 if (req >= 50)
166 {
167 return -EINVAL;
168 }
169 propertyValue = req;
170 return 1; // success
171 });
172 iface->register_property(
173 "TrailTime", std::string("foo"),
174 // custom set
175 [](const std::string& req, std::string& propertyValue) {
176 propertyValue = req;
177 return 1; // success
178 },
179 // custom get
180 [](const std::string& property) {
181 auto now = std::chrono::system_clock::now();
182 auto timePoint = std::chrono::system_clock::to_time_t(now);
183 return property + std::ctime(&timePoint);
184 });
185
186 // test method creation
187 iface->register_method("TestMethod", [](const int32_t& callCount) {
Vernon Mauery261e72b2018-09-25 12:34:25 -0700188 return std::make_tuple(callCount,
189 "success: " + std::to_string(callCount));
James Feistfce038a2018-04-13 15:43:13 -0700190 });
191
192 iface->register_method("TestFunction", foo);
193
Vernon Mauery8ce61e42018-08-28 08:54:59 -0700194 iface->register_method("TestMethodWithMessage", methodWithMessage);
195
Vernon Mauery2c8f93f2018-09-05 12:02:39 -0700196 iface->register_method("VoidFunctionReturnsInt", voidBar);
197
James Feistfce038a2018-04-13 15:43:13 -0700198 iface->initialize();
199 iface->set_property("int", 45);
Vernon Mauery035c73b2018-09-05 12:15:27 -0700200
201 // sd_events work too using the default event loop
202 phosphor::Timer t1([]() { std::cerr << "*** tock ***\n"; });
203 t1.start(std::chrono::microseconds(1000000));
204 phosphor::Timer t2([]() { std::cerr << "*** tick ***\n"; });
205 t2.start(std::chrono::microseconds(500000), true);
206 // add the sd_event wrapper to the io object
207 sdbusplus::asio::sd_event_wrapper sdEvents(io);
208
Vernon Mauery261e72b2018-09-25 12:34:25 -0700209 // set up a client to make an async call to the server
210 // using coroutines (userspace cooperative multitasking)
211 boost::asio::spawn(io, [conn](boost::asio::yield_context yield) {
212 do_start_async_method_call_one(conn, yield);
213 });
214 boost::asio::spawn(io, [conn](boost::asio::yield_context yield) {
215 do_start_async_method_call_two(conn, yield);
216 });
James Feist284a0f92018-04-05 15:28:16 -0700217 io.run();
218
219 return 0;
220}