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