blob: eaa2116768750a84458949e47e07f2d93e0dfa69 [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 Grobelny6adfe942021-12-21 13:57:22 +010028 demo_->register_property_r(propertyGrettingName, std::string(),
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020029 sdbusplus::vtable::property_::const_,
30 [this](const auto&) { return greetings_; });
31
32 demo_->register_property_rw(
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010033 propertyGoodbyesName, std::string(),
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020034 sdbusplus::vtable::property_::emits_change,
35 [this](const auto& newPropertyValue, const auto&) {
36 goodbyes_ = newPropertyValue;
37 return 1;
38 },
39 [this](const auto&) { return goodbyes_; });
40
41 demo_->register_property_r(
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010042 propertyValueName, uint32_t{42},
43 sdbusplus::vtable::property_::const_,
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020044 [](const auto& value) -> uint32_t { return value; });
45
46 demo_->initialize();
47 }
48
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020049 uint32_t fatalErrors() const
50 {
51 return fatalErrors_;
52 }
53
Ed Tanous95874d92021-02-19 17:14:27 -080054 auto logSystemErrorCode(boost::system::error_code ec)
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020055 {
Ed Tanous95874d92021-02-19 17:14:27 -080056 std::cerr << "Error: " << ec << "\n";
57 ++fatalErrors_;
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020058 }
59
60 void logException(const std::exception& e)
61 {
62 std::cerr << "Error: " << e.what() << "\n";
63 ++fatalErrors_;
64 }
65
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010066 void logBadProperty(const std::string& badProperty)
67 {
68 std::cerr << "BadProperty: " << badProperty << "\n";
69 ++fatalErrors_;
70 }
71
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020072 void logExpectedException(
73 const sdbusplus::exception::UnpackPropertyError& error)
74 {
75 std::cout << "As expected " << error.what() << " => "
76 << error.propertyName << " is missing because "
77 << error.reason << "\n";
78 }
79
80 void asyncGetAllPropertiesStringTypeOnly()
81 {
82 sdbusplus::asio::getAllProperties(
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010083 bus_, demoServiceName, demoObjectPath, demoInterfaceName,
Ed Tanous95874d92021-02-19 17:14:27 -080084 [this](boost::system::error_code ec,
85 std::vector<std::pair<
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020086 std::string, std::variant<std::monostate, std::string>>>&
Ed Tanous95874d92021-02-19 17:14:27 -080087 properties) -> void {
88 if (ec)
89 {
90 logSystemErrorCode(ec);
91 return;
92 }
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020093 {
94 std::string greetings;
95 std::string goodbyes;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010096 std::optional<std::string> badProperty =
97 sdbusplus::unpackPropertiesNoThrow(
98 properties, propertyGrettingName, greetings,
99 propertyGoodbyesName, goodbyes);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200100
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100101 if (badProperty)
102 {
103 logBadProperty(*badProperty);
104 }
105 else
106 {
107 std::cout << "value of greetings: " << greetings
108 << "\n";
109 std::cout << "value of goodbyes: " << goodbyes << "\n";
110 }
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200111 }
112
113 try
114 {
115 std::string value;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100116 sdbusplus::unpackProperties(properties, propertyValueName,
117 value);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200118
119 std::cerr << "Error: it should fail because of "
120 "not matched type\n";
121 ++fatalErrors_;
122 }
123 catch (const sdbusplus::exception::UnpackPropertyError& error)
124 {
125 logExpectedException(error);
126 }
127 });
128 }
129
130 void asyncGetAllProperties()
131 {
132 sdbusplus::asio::getAllProperties(
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100133 bus_, demoServiceName, demoObjectPath, demoInterfaceName,
Ed Tanous95874d92021-02-19 17:14:27 -0800134 [this](boost::system::error_code ec,
135 std::vector<std::pair<
136 std::string,
137 std::variant<std::monostate, std::string, uint32_t>>>&
138 properties) -> void {
139 if (ec)
140 {
141 logSystemErrorCode(ec);
142 return;
143 }
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200144 try
145 {
146 std::string greetings;
147 std::string goodbyes;
148 uint32_t value = 0u;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100149 sdbusplus::unpackProperties(properties,
150 propertyGrettingName, greetings,
151 propertyGoodbyesName, goodbyes,
152 propertyValueName, value);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200153
154 std::cout << "value of greetings: " << greetings << "\n";
155 std::cout << "value of goodbyes: " << goodbyes << "\n";
156 std::cout << "value of value: " << value << "\n";
157 }
158 catch (const sdbusplus::exception::UnpackPropertyError& error)
159 {
160 logException(error);
161 }
162
163 try
164 {
165 std::string unknownProperty;
166 sdbusplus::unpackProperties(
167 properties, "UnknownPropertyName", unknownProperty);
168
169 std::cerr << "Error: it should fail because of "
170 "missing property\n";
171 ++fatalErrors_;
172 }
173 catch (const sdbusplus::exception::UnpackPropertyError& error)
174 {
175 logExpectedException(error);
176 }
177
178 try
179 {
180 uint32_t notMatchingType;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100181 sdbusplus::unpackProperties(
182 properties, propertyGrettingName, notMatchingType);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200183
184 std::cerr << "Error: it should fail because of "
185 "not matched type\n";
186 ++fatalErrors_;
187 }
188 catch (const sdbusplus::exception::UnpackPropertyError& error)
189 {
190 logExpectedException(error);
191 }
192 });
193 }
194
195 private:
196 boost::asio::io_context& ioc_;
197 sdbusplus::asio::connection& bus_;
198 sdbusplus::asio::object_server& objServer_;
199
Krzysztof Grobelny8fc06392020-09-28 13:11:22 +0200200 std::unique_ptr<sdbusplus::asio::dbus_interface> demo_;
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200201 std::string greetings_ = "Hello";
202 std::string goodbyes_ = "Bye";
203
204 uint32_t fatalErrors_ = 0u;
205};
206
207int main(int, char**)
208{
209 boost::asio::io_context ioc;
210 boost::asio::signal_set signals(ioc, SIGINT, SIGTERM);
211
212 signals.async_wait(
213 [&ioc](const boost::system::error_code&, const int&) { ioc.stop(); });
214
215 auto bus = std::make_shared<sdbusplus::asio::connection>(ioc);
216 auto objServer = std::make_unique<sdbusplus::asio::object_server>(bus);
217
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100218 bus->request_name(demoServiceName.c_str());
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200219
220 Application app(ioc, *bus, *objServer);
221
222 boost::asio::post(ioc,
223 [&app] { app.asyncGetAllPropertiesStringTypeOnly(); });
224 boost::asio::post(ioc, [&app] { app.asyncGetAllProperties(); });
225
226 ioc.run();
227
228 std::cout << "Fatal errors count: " << app.fatalErrors() << "\n";
229
230 return app.fatalErrors();
231}