blob: 7a2d037d4191456e172417b9567ae5d48cb0b56c [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 {
39 demo_ = objServer_.add_interface(xyz::demo::path, xyz::demo::interface);
40
41 demo_->register_property_r(name::greetings, std::string(),
42 sdbusplus::vtable::property_::const_,
43 [this](const auto&) { return greetings_; });
44
45 demo_->register_property_rw(
46 name::goodbyes, std::string(),
47 sdbusplus::vtable::property_::emits_change,
48 [this](const auto& newPropertyValue, const auto&) {
49 goodbyes_ = newPropertyValue;
50 return 1;
51 },
52 [this](const auto&) { return goodbyes_; });
53
54 demo_->register_property_r(
55 name::value, uint32_t{42}, sdbusplus::vtable::property_::const_,
56 [](const auto& value) -> uint32_t { return value; });
57
58 demo_->initialize();
59 }
60
61 ~Application()
62 {
63 objServer_.remove_interface(demo_);
64 }
65
66 uint32_t fatalErrors() const
67 {
68 return fatalErrors_;
69 }
70
71 auto logSystemErrorCode()
72 {
73 return [this](boost::system::error_code ec) {
74 std::cerr << "Error: " << ec << "\n";
75 ++fatalErrors_;
76 };
77 }
78
79 void logException(const std::exception& e)
80 {
81 std::cerr << "Error: " << e.what() << "\n";
82 ++fatalErrors_;
83 }
84
85 void logExpectedException(
86 const sdbusplus::exception::UnpackPropertyError& error)
87 {
88 std::cout << "As expected " << error.what() << " => "
89 << error.propertyName << " is missing because "
90 << error.reason << "\n";
91 }
92
93 void asyncGetAllPropertiesStringTypeOnly()
94 {
95 sdbusplus::asio::getAllProperties(
96 bus_, xyz::demo::name, xyz::demo::path, xyz::demo::interface,
97 logSystemErrorCode(),
98 [this](std::vector<std::pair<
99 std::string, std::variant<std::monostate, std::string>>>&
100 properties) {
101 try
102 {
103 std::string greetings;
104 std::string goodbyes;
105 sdbusplus::unpackProperties(properties, name::greetings,
106 greetings, name::goodbyes,
107 goodbyes);
108
109 std::cout << "value of greetings: " << greetings << "\n";
110 std::cout << "value of goodbyes: " << goodbyes << "\n";
111 }
112 catch (const sdbusplus::exception::UnpackPropertyError& error)
113 {
114 logException(error);
115 }
116
117 try
118 {
119 std::string value;
120 sdbusplus::unpackProperties(properties, name::value, value);
121
122 std::cerr << "Error: it should fail because of "
123 "not matched type\n";
124 ++fatalErrors_;
125 }
126 catch (const sdbusplus::exception::UnpackPropertyError& error)
127 {
128 logExpectedException(error);
129 }
130 });
131 }
132
133 void asyncGetAllProperties()
134 {
135 sdbusplus::asio::getAllProperties(
136 bus_, xyz::demo::name, xyz::demo::path, xyz::demo::interface,
137 logSystemErrorCode(),
138 [this](
139 std::vector<std::pair<std::string,
140 std::variant<std::monostate, std::string,
141 uint32_t>>>& properties) {
142 try
143 {
144 std::string greetings;
145 std::string goodbyes;
146 uint32_t value = 0u;
147 sdbusplus::unpackProperties(properties, name::greetings,
148 greetings, name::goodbyes,
149 goodbyes, name::value, value);
150
151 std::cout << "value of greetings: " << greetings << "\n";
152 std::cout << "value of goodbyes: " << goodbyes << "\n";
153 std::cout << "value of value: " << value << "\n";
154 }
155 catch (const sdbusplus::exception::UnpackPropertyError& error)
156 {
157 logException(error);
158 }
159
160 try
161 {
162 std::string unknownProperty;
163 sdbusplus::unpackProperties(
164 properties, "UnknownPropertyName", unknownProperty);
165
166 std::cerr << "Error: it should fail because of "
167 "missing property\n";
168 ++fatalErrors_;
169 }
170 catch (const sdbusplus::exception::UnpackPropertyError& error)
171 {
172 logExpectedException(error);
173 }
174
175 try
176 {
177 uint32_t notMatchingType;
178 sdbusplus::unpackProperties(properties, name::greetings,
179 notMatchingType);
180
181 std::cerr << "Error: it should fail because of "
182 "not matched type\n";
183 ++fatalErrors_;
184 }
185 catch (const sdbusplus::exception::UnpackPropertyError& error)
186 {
187 logExpectedException(error);
188 }
189 });
190 }
191
192 private:
193 boost::asio::io_context& ioc_;
194 sdbusplus::asio::connection& bus_;
195 sdbusplus::asio::object_server& objServer_;
196
197 std::shared_ptr<sdbusplus::asio::dbus_interface> demo_;
198 std::string greetings_ = "Hello";
199 std::string goodbyes_ = "Bye";
200
201 uint32_t fatalErrors_ = 0u;
202};
203
204int main(int, char**)
205{
206 boost::asio::io_context ioc;
207 boost::asio::signal_set signals(ioc, SIGINT, SIGTERM);
208
209 signals.async_wait(
210 [&ioc](const boost::system::error_code&, const int&) { ioc.stop(); });
211
212 auto bus = std::make_shared<sdbusplus::asio::connection>(ioc);
213 auto objServer = std::make_unique<sdbusplus::asio::object_server>(bus);
214
215 bus->request_name(xyz::demo::name.c_str());
216
217 Application app(ioc, *bus, *objServer);
218
219 boost::asio::post(ioc,
220 [&app] { app.asyncGetAllPropertiesStringTypeOnly(); });
221 boost::asio::post(ioc, [&app] { app.asyncGetAllProperties(); });
222
223 ioc.run();
224
225 std::cout << "Fatal errors count: " << app.fatalErrors() << "\n";
226
227 return app.fatalErrors();
228}