blob: 330e0c12570e35ae6c2f51661d3d629bfdcb205e [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 Grobelny6adfe942021-12-21 13:57:22 +010064 void logBadProperty(const std::string& badProperty)
65 {
66 std::cerr << "BadProperty: " << badProperty << "\n";
67 ++fatalErrors_;
68 }
69
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020070 void logExpectedException(
71 const sdbusplus::exception::UnpackPropertyError& error)
72 {
73 std::cout << "As expected " << error.what() << " => "
74 << error.propertyName << " is missing because "
75 << error.reason << "\n";
76 }
77
78 void asyncGetAllPropertiesStringTypeOnly()
79 {
80 sdbusplus::asio::getAllProperties(
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010081 bus_, demoServiceName, demoObjectPath, demoInterfaceName,
Ed Tanous95874d92021-02-19 17:14:27 -080082 [this](boost::system::error_code ec,
83 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 {
92 std::string greetings;
93 std::string goodbyes;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010094 std::optional<std::string> badProperty =
95 sdbusplus::unpackPropertiesNoThrow(
96 properties, propertyGrettingName, greetings,
97 propertyGoodbyesName, goodbyes);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020098
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010099 if (badProperty)
100 {
101 logBadProperty(*badProperty);
102 }
103 else
104 {
105 std::cout << "value of greetings: " << greetings
106 << "\n";
107 std::cout << "value of goodbyes: " << goodbyes << "\n";
108 }
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200109 }
110
111 try
112 {
113 std::string value;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100114 sdbusplus::unpackProperties(properties, propertyValueName,
115 value);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200116
117 std::cerr << "Error: it should fail because of "
118 "not matched type\n";
119 ++fatalErrors_;
120 }
121 catch (const sdbusplus::exception::UnpackPropertyError& error)
122 {
123 logExpectedException(error);
124 }
125 });
126 }
127
128 void asyncGetAllProperties()
129 {
130 sdbusplus::asio::getAllProperties(
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100131 bus_, demoServiceName, demoObjectPath, demoInterfaceName,
Ed Tanous95874d92021-02-19 17:14:27 -0800132 [this](boost::system::error_code ec,
133 std::vector<std::pair<
134 std::string,
135 std::variant<std::monostate, std::string, uint32_t>>>&
136 properties) -> void {
137 if (ec)
138 {
139 logSystemErrorCode(ec);
140 return;
141 }
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200142 try
143 {
144 std::string greetings;
145 std::string goodbyes;
146 uint32_t value = 0u;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100147 sdbusplus::unpackProperties(properties,
148 propertyGrettingName, greetings,
149 propertyGoodbyesName, goodbyes,
150 propertyValueName, value);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200151
152 std::cout << "value of greetings: " << greetings << "\n";
153 std::cout << "value of goodbyes: " << goodbyes << "\n";
154 std::cout << "value of value: " << value << "\n";
155 }
156 catch (const sdbusplus::exception::UnpackPropertyError& error)
157 {
158 logException(error);
159 }
160
161 try
162 {
163 std::string unknownProperty;
164 sdbusplus::unpackProperties(
165 properties, "UnknownPropertyName", unknownProperty);
166
167 std::cerr << "Error: it should fail because of "
168 "missing property\n";
169 ++fatalErrors_;
170 }
171 catch (const sdbusplus::exception::UnpackPropertyError& error)
172 {
173 logExpectedException(error);
174 }
175
176 try
177 {
178 uint32_t notMatchingType;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100179 sdbusplus::unpackProperties(
180 properties, propertyGrettingName, notMatchingType);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200181
182 std::cerr << "Error: it should fail because of "
183 "not matched type\n";
184 ++fatalErrors_;
185 }
186 catch (const sdbusplus::exception::UnpackPropertyError& error)
187 {
188 logExpectedException(error);
189 }
190 });
191 }
192
193 private:
194 boost::asio::io_context& ioc_;
195 sdbusplus::asio::connection& bus_;
196 sdbusplus::asio::object_server& objServer_;
197
Krzysztof Grobelny8fc06392020-09-28 13:11:22 +0200198 std::unique_ptr<sdbusplus::asio::dbus_interface> demo_;
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200199 std::string greetings_ = "Hello";
200 std::string goodbyes_ = "Bye";
201
202 uint32_t fatalErrors_ = 0u;
203};
204
205int main(int, char**)
206{
207 boost::asio::io_context ioc;
208 boost::asio::signal_set signals(ioc, SIGINT, SIGTERM);
209
210 signals.async_wait(
211 [&ioc](const boost::system::error_code&, const int&) { ioc.stop(); });
212
213 auto bus = std::make_shared<sdbusplus::asio::connection>(ioc);
214 auto objServer = std::make_unique<sdbusplus::asio::object_server>(bus);
215
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100216 bus->request_name(demoServiceName.c_str());
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200217
218 Application app(ioc, *bus, *objServer);
219
220 boost::asio::post(ioc,
221 [&app] { app.asyncGetAllPropertiesStringTypeOnly(); });
222 boost::asio::post(ioc, [&app] { app.asyncGetAllProperties(); });
223
224 ioc.run();
225
226 std::cout << "Fatal errors count: " << app.fatalErrors() << "\n";
227
228 return app.fatalErrors();
229}