blob: 53d2466351bc712b3415d08123c20a5b53942b50 [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
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010010const std::string demoServiceName = "demo.service";
11const std::string demoObjectPath = "/xyz/demo";
12const std::string demoInterfaceName = "xyz.demo";
13const std::string propertyGrettingName = "Greetings";
14const std::string propertyGoodbyesName = "Goodbyes";
15const std::string propertyValueName = "Value";
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020016
17class Application
18{
19 public:
20 Application(boost::asio::io_context& ioc, sdbusplus::asio::connection& bus,
21 sdbusplus::asio::object_server& objServer) :
22 ioc_(ioc),
23 bus_(bus), objServer_(objServer)
24 {
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010025 demo_ =
26 objServer_.add_unique_interface(demoObjectPath, demoInterfaceName);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020027
Krzysztof Grobelny90fab6b2022-02-18 14:21:21 +010028 demo_->register_property_r<std::string>(
29 propertyGrettingName, sdbusplus::vtable::property_::const_,
30 [this](const auto&) { return greetings_; });
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020031
Krzysztof Grobelny90fab6b2022-02-18 14:21:21 +010032 demo_->register_property_rw<std::string>(
33 propertyGoodbyesName, sdbusplus::vtable::property_::emits_change,
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020034 [this](const auto& newPropertyValue, const auto&) {
35 goodbyes_ = newPropertyValue;
36 return 1;
37 },
38 [this](const auto&) { return goodbyes_; });
39
Krzysztof Grobelny90fab6b2022-02-18 14:21:21 +010040 demo_->register_property_r<uint32_t>(
41 propertyValueName, sdbusplus::vtable::property_::const_,
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020042 [](const auto& value) -> uint32_t { return value; });
43
44 demo_->initialize();
45 }
46
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020047 uint32_t fatalErrors() const
48 {
49 return fatalErrors_;
50 }
51
Ed Tanous95874d92021-02-19 17:14:27 -080052 auto logSystemErrorCode(boost::system::error_code ec)
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020053 {
Ed Tanous95874d92021-02-19 17:14:27 -080054 std::cerr << "Error: " << ec << "\n";
55 ++fatalErrors_;
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020056 }
57
58 void logException(const std::exception& e)
59 {
60 std::cerr << "Error: " << e.what() << "\n";
61 ++fatalErrors_;
62 }
63
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +010064 void logUnpackError(const sdbusplus::UnpackErrorReason reason,
65 const std::string& property)
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010066 {
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +010067 std::cerr << "UnpackError: " << static_cast<int>(reason) << ", "
68 << property << "\n";
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010069 ++fatalErrors_;
70 }
71
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020072 void logExpectedException(
73 const sdbusplus::exception::UnpackPropertyError& error)
74 {
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +010075 std::cout << "As expected " << error.what() << "\n";
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020076 }
77
78 void asyncGetAllPropertiesStringTypeOnly()
79 {
80 sdbusplus::asio::getAllProperties(
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010081 bus_, demoServiceName, demoObjectPath, demoInterfaceName,
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +010082 [this](const boost::system::error_code ec,
83 const std::vector<std::pair<
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020084 std::string, std::variant<std::monostate, std::string>>>&
Ed Tanous95874d92021-02-19 17:14:27 -080085 properties) -> void {
86 if (ec)
87 {
88 logSystemErrorCode(ec);
89 return;
90 }
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020091 {
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +010092 const std::string* greetings = nullptr;
93 const std::string* goodbyes = nullptr;
94 const bool success = sdbusplus::unpackPropertiesNoThrow(
95 [this](const sdbusplus::UnpackErrorReason reason,
96 const std::string& property) {
97 logUnpackError(reason, property);
98 },
99 properties, propertyGrettingName, greetings,
100 propertyGoodbyesName, goodbyes);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200101
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +0100102 if (success)
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100103 {
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +0100104 std::cout << "value of greetings: " << *greetings
105 << "\n";
106 std::cout << "value of goodbyes: " << *goodbyes << "\n";
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100107 }
108 else
109 {
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +0100110 ++fatalErrors_;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100111 }
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200112 }
113
114 try
115 {
116 std::string value;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100117 sdbusplus::unpackProperties(properties, propertyValueName,
118 value);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200119
120 std::cerr << "Error: it should fail because of "
121 "not matched type\n";
122 ++fatalErrors_;
123 }
124 catch (const sdbusplus::exception::UnpackPropertyError& error)
125 {
126 logExpectedException(error);
127 }
128 });
129 }
130
131 void asyncGetAllProperties()
132 {
133 sdbusplus::asio::getAllProperties(
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100134 bus_, demoServiceName, demoObjectPath, demoInterfaceName,
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +0100135 [this](const boost::system::error_code ec,
136 const std::vector<std::pair<
Ed Tanous95874d92021-02-19 17:14:27 -0800137 std::string,
138 std::variant<std::monostate, std::string, uint32_t>>>&
139 properties) -> void {
140 if (ec)
141 {
142 logSystemErrorCode(ec);
143 return;
144 }
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200145 try
146 {
147 std::string greetings;
148 std::string goodbyes;
149 uint32_t value = 0u;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100150 sdbusplus::unpackProperties(properties,
151 propertyGrettingName, greetings,
152 propertyGoodbyesName, goodbyes,
153 propertyValueName, value);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200154
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;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100182 sdbusplus::unpackProperties(
183 properties, propertyGrettingName, notMatchingType);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200184
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
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100219 bus->request_name(demoServiceName.c_str());
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200220
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}