blob: 1b3c5089ab73f5c2c9f08523aed2a8bb85658e5c [file] [log] [blame]
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +02001#include <boost/asio.hpp>
2#include <sdbusplus/asio/connection.hpp>
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +02003#include <sdbusplus/asio/object_server.hpp>
Krzysztof Grobelny807419d2020-09-28 11:39:22 +02004#include <sdbusplus/asio/property.hpp>
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +02005#include <sdbusplus/bus.hpp>
6#include <sdbusplus/unpack_properties.hpp>
7
8#include <iostream>
9
10namespace xyz
11{
12namespace demo
13{
14
15const std::string path = "/xyz/demo";
16const std::string name = "xyz.demo";
17const std::string interface = "xyz.demo.interface";
18
19} // namespace demo
20} // namespace xyz
21
22namespace name
23{
24
25const std::string greetings = "Greetings";
26const std::string goodbyes = "Goodbyes";
27const std::string value = "Value";
28
29} // namespace name
30
31class Application
32{
33 public:
34 Application(boost::asio::io_context& ioc, sdbusplus::asio::connection& bus,
35 sdbusplus::asio::object_server& objServer) :
36 ioc_(ioc),
37 bus_(bus), objServer_(objServer)
38 {
Krzysztof Grobelny8fc06392020-09-28 13:11:22 +020039 demo_ = objServer_.add_unique_interface(xyz::demo::path,
40 xyz::demo::interface);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020041
42 demo_->register_property_r(name::greetings, std::string(),
43 sdbusplus::vtable::property_::const_,
44 [this](const auto&) { return greetings_; });
45
46 demo_->register_property_rw(
47 name::goodbyes, std::string(),
48 sdbusplus::vtable::property_::emits_change,
49 [this](const auto& newPropertyValue, const auto&) {
50 goodbyes_ = newPropertyValue;
51 return 1;
52 },
53 [this](const auto&) { return goodbyes_; });
54
55 demo_->register_property_r(
56 name::value, uint32_t{42}, sdbusplus::vtable::property_::const_,
57 [](const auto& value) -> uint32_t { return value; });
58
59 demo_->initialize();
60 }
61
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020062 uint32_t fatalErrors() const
63 {
64 return fatalErrors_;
65 }
66
Ed Tanous95874d92021-02-19 17:14:27 -080067 auto logSystemErrorCode(boost::system::error_code ec)
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020068 {
Ed Tanous95874d92021-02-19 17:14:27 -080069 std::cerr << "Error: " << ec << "\n";
70 ++fatalErrors_;
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020071 }
72
73 void logException(const std::exception& e)
74 {
75 std::cerr << "Error: " << e.what() << "\n";
76 ++fatalErrors_;
77 }
78
79 void logExpectedException(
80 const sdbusplus::exception::UnpackPropertyError& error)
81 {
82 std::cout << "As expected " << error.what() << " => "
83 << error.propertyName << " is missing because "
84 << error.reason << "\n";
85 }
86
87 void asyncGetAllPropertiesStringTypeOnly()
88 {
89 sdbusplus::asio::getAllProperties(
90 bus_, xyz::demo::name, xyz::demo::path, xyz::demo::interface,
Ed Tanous95874d92021-02-19 17:14:27 -080091 [this](boost::system::error_code ec,
92 std::vector<std::pair<
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020093 std::string, std::variant<std::monostate, std::string>>>&
Ed Tanous95874d92021-02-19 17:14:27 -080094 properties) -> void {
95 if (ec)
96 {
97 logSystemErrorCode(ec);
98 return;
99 }
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200100 try
101 {
102 std::string greetings;
103 std::string goodbyes;
104 sdbusplus::unpackProperties(properties, name::greetings,
105 greetings, name::goodbyes,
106 goodbyes);
107
108 std::cout << "value of greetings: " << greetings << "\n";
109 std::cout << "value of goodbyes: " << goodbyes << "\n";
110 }
111 catch (const sdbusplus::exception::UnpackPropertyError& error)
112 {
113 logException(error);
114 }
115
116 try
117 {
118 std::string value;
119 sdbusplus::unpackProperties(properties, name::value, value);
120
121 std::cerr << "Error: it should fail because of "
122 "not matched type\n";
123 ++fatalErrors_;
124 }
125 catch (const sdbusplus::exception::UnpackPropertyError& error)
126 {
127 logExpectedException(error);
128 }
129 });
130 }
131
132 void asyncGetAllProperties()
133 {
134 sdbusplus::asio::getAllProperties(
135 bus_, xyz::demo::name, xyz::demo::path, xyz::demo::interface,
Ed Tanous95874d92021-02-19 17:14:27 -0800136 [this](boost::system::error_code ec,
137 std::vector<std::pair<
138 std::string,
139 std::variant<std::monostate, std::string, uint32_t>>>&
140 properties) -> void {
141 if (ec)
142 {
143 logSystemErrorCode(ec);
144 return;
145 }
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200146 try
147 {
148 std::string greetings;
149 std::string goodbyes;
150 uint32_t value = 0u;
151 sdbusplus::unpackProperties(properties, name::greetings,
152 greetings, name::goodbyes,
153 goodbyes, name::value, value);
154
155 std::cout << "value of greetings: " << greetings << "\n";
156 std::cout << "value of goodbyes: " << goodbyes << "\n";
157 std::cout << "value of value: " << value << "\n";
158 }
159 catch (const sdbusplus::exception::UnpackPropertyError& error)
160 {
161 logException(error);
162 }
163
164 try
165 {
166 std::string unknownProperty;
167 sdbusplus::unpackProperties(
168 properties, "UnknownPropertyName", unknownProperty);
169
170 std::cerr << "Error: it should fail because of "
171 "missing property\n";
172 ++fatalErrors_;
173 }
174 catch (const sdbusplus::exception::UnpackPropertyError& error)
175 {
176 logExpectedException(error);
177 }
178
179 try
180 {
181 uint32_t notMatchingType;
182 sdbusplus::unpackProperties(properties, name::greetings,
183 notMatchingType);
184
185 std::cerr << "Error: it should fail because of "
186 "not matched type\n";
187 ++fatalErrors_;
188 }
189 catch (const sdbusplus::exception::UnpackPropertyError& error)
190 {
191 logExpectedException(error);
192 }
193 });
194 }
195
196 private:
197 boost::asio::io_context& ioc_;
198 sdbusplus::asio::connection& bus_;
199 sdbusplus::asio::object_server& objServer_;
200
Krzysztof Grobelny8fc06392020-09-28 13:11:22 +0200201 std::unique_ptr<sdbusplus::asio::dbus_interface> demo_;
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200202 std::string greetings_ = "Hello";
203 std::string goodbyes_ = "Bye";
204
205 uint32_t fatalErrors_ = 0u;
206};
207
208int main(int, char**)
209{
210 boost::asio::io_context ioc;
211 boost::asio::signal_set signals(ioc, SIGINT, SIGTERM);
212
213 signals.async_wait(
214 [&ioc](const boost::system::error_code&, const int&) { ioc.stop(); });
215
216 auto bus = std::make_shared<sdbusplus::asio::connection>(ioc);
217 auto objServer = std::make_unique<sdbusplus::asio::object_server>(bus);
218
219 bus->request_name(xyz::demo::name.c_str());
220
221 Application app(ioc, *bus, *objServer);
222
223 boost::asio::post(ioc,
224 [&app] { app.asyncGetAllPropertiesStringTypeOnly(); });
225 boost::asio::post(ioc, [&app] { app.asyncGetAllProperties(); });
226
227 ioc.run();
228
229 std::cout << "Fatal errors count: " << app.fatalErrors() << "\n";
230
231 return app.fatalErrors();
232}