blob: 428b3229fde9f0045ff1e8d1d8fd92849a0aa8c4 [file] [log] [blame]
Ed Tanousb65dc1c2023-03-07 17:41:57 -08001#include <boost/asio/io_context.hpp>
2#include <boost/asio/signal_set.hpp>
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +02003#include <sdbusplus/asio/connection.hpp>
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +02004#include <sdbusplus/asio/object_server.hpp>
Krzysztof Grobelny807419d2020-09-28 11:39:22 +02005#include <sdbusplus/asio/property.hpp>
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +02006#include <sdbusplus/bus.hpp>
7#include <sdbusplus/unpack_properties.hpp>
8
9#include <iostream>
10
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010011const std::string demoServiceName = "demo.service";
12const std::string demoObjectPath = "/xyz/demo";
13const std::string demoInterfaceName = "xyz.demo";
14const std::string propertyGrettingName = "Greetings";
15const std::string propertyGoodbyesName = "Goodbyes";
16const std::string propertyValueName = "Value";
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020017
18class Application
19{
20 public:
Ed Tanous760e66a2023-01-05 10:12:00 -080021 Application(sdbusplus::asio::connection& bus,
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020022 sdbusplus::asio::object_server& objServer) :
Ed Tanous760e66a2023-01-05 10:12:00 -080023 bus_(bus),
24 objServer_(objServer)
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020025 {
Patrick Williams1a25a102022-09-29 17:18:26 -050026 demo_ = objServer_.add_unique_interface(demoObjectPath,
27 demoInterfaceName);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020028
Krzysztof Grobelny90fab6b2022-02-18 14:21:21 +010029 demo_->register_property_r<std::string>(
30 propertyGrettingName, sdbusplus::vtable::property_::const_,
31 [this](const auto&) { return greetings_; });
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020032
Krzysztof Grobelny90fab6b2022-02-18 14:21:21 +010033 demo_->register_property_rw<std::string>(
34 propertyGoodbyesName, sdbusplus::vtable::property_::emits_change,
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020035 [this](const auto& newPropertyValue, const auto&) {
36 goodbyes_ = newPropertyValue;
Jonathan Domanae479282022-06-03 13:29:50 -070037 return true;
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020038 },
39 [this](const auto&) { return goodbyes_; });
40
Krzysztof Grobelny90fab6b2022-02-18 14:21:21 +010041 demo_->register_property_r<uint32_t>(
42 propertyValueName, sdbusplus::vtable::property_::const_,
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020043 [](const auto& value) -> uint32_t { return value; });
44
45 demo_->initialize();
46 }
47
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020048 uint32_t fatalErrors() const
49 {
50 return fatalErrors_;
51 }
52
Ed Tanous95874d92021-02-19 17:14:27 -080053 auto logSystemErrorCode(boost::system::error_code ec)
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020054 {
Ed Tanous95874d92021-02-19 17:14:27 -080055 std::cerr << "Error: " << ec << "\n";
56 ++fatalErrors_;
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020057 }
58
59 void logException(const std::exception& e)
60 {
61 std::cerr << "Error: " << e.what() << "\n";
62 ++fatalErrors_;
63 }
64
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +010065 void logUnpackError(const sdbusplus::UnpackErrorReason reason,
66 const std::string& property)
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010067 {
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +010068 std::cerr << "UnpackError: " << static_cast<int>(reason) << ", "
69 << property << "\n";
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010070 ++fatalErrors_;
71 }
72
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020073 void logExpectedException(
74 const sdbusplus::exception::UnpackPropertyError& error)
75 {
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +010076 std::cout << "As expected " << error.what() << "\n";
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020077 }
78
79 void asyncGetAllPropertiesStringTypeOnly()
80 {
81 sdbusplus::asio::getAllProperties(
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +010082 bus_, demoServiceName, demoObjectPath, demoInterfaceName,
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +010083 [this](const boost::system::error_code ec,
84 const std::vector<std::pair<
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020085 std::string, std::variant<std::monostate, std::string>>>&
Ed Tanous95874d92021-02-19 17:14:27 -080086 properties) -> void {
87 if (ec)
88 {
89 logSystemErrorCode(ec);
90 return;
91 }
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +020092 {
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +010093 const std::string* greetings = nullptr;
94 const std::string* goodbyes = nullptr;
95 const bool success = sdbusplus::unpackPropertiesNoThrow(
96 [this](const sdbusplus::UnpackErrorReason reason,
97 const std::string& property) {
98 logUnpackError(reason, property);
99 },
100 properties, propertyGrettingName, greetings,
101 propertyGoodbyesName, goodbyes);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200102
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +0100103 if (success)
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100104 {
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +0100105 std::cout << "value of greetings: " << *greetings
106 << "\n";
107 std::cout << "value of goodbyes: " << *goodbyes << "\n";
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100108 }
109 else
110 {
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +0100111 ++fatalErrors_;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100112 }
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200113 }
114
115 try
116 {
117 std::string value;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100118 sdbusplus::unpackProperties(properties, propertyValueName,
119 value);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200120
121 std::cerr << "Error: it should fail because of "
122 "not matched type\n";
123 ++fatalErrors_;
124 }
125 catch (const sdbusplus::exception::UnpackPropertyError& error)
126 {
127 logExpectedException(error);
128 }
129 });
130 }
131
132 void asyncGetAllProperties()
133 {
134 sdbusplus::asio::getAllProperties(
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100135 bus_, demoServiceName, demoObjectPath, demoInterfaceName,
Krzysztof Grobelnyc8447d52022-01-05 13:21:37 +0100136 [this](const boost::system::error_code ec,
137 const std::vector<std::pair<
Ed Tanous95874d92021-02-19 17:14:27 -0800138 std::string,
139 std::variant<std::monostate, std::string, uint32_t>>>&
140 properties) -> void {
141 if (ec)
142 {
143 logSystemErrorCode(ec);
144 return;
145 }
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200146 try
147 {
148 std::string greetings;
149 std::string goodbyes;
150 uint32_t value = 0u;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100151 sdbusplus::unpackProperties(properties,
152 propertyGrettingName, greetings,
153 propertyGoodbyesName, goodbyes,
154 propertyValueName, value);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200155
156 std::cout << "value of greetings: " << greetings << "\n";
157 std::cout << "value of goodbyes: " << goodbyes << "\n";
158 std::cout << "value of value: " << value << "\n";
159 }
160 catch (const sdbusplus::exception::UnpackPropertyError& error)
161 {
162 logException(error);
163 }
164
165 try
166 {
167 std::string unknownProperty;
168 sdbusplus::unpackProperties(
169 properties, "UnknownPropertyName", unknownProperty);
170
171 std::cerr << "Error: it should fail because of "
172 "missing property\n";
173 ++fatalErrors_;
174 }
175 catch (const sdbusplus::exception::UnpackPropertyError& error)
176 {
177 logExpectedException(error);
178 }
179
180 try
181 {
182 uint32_t notMatchingType;
Krzysztof Grobelny6adfe942021-12-21 13:57:22 +0100183 sdbusplus::unpackProperties(
184 properties, propertyGrettingName, notMatchingType);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200185
186 std::cerr << "Error: it should fail because of "
187 "not matched type\n";
188 ++fatalErrors_;
189 }
190 catch (const sdbusplus::exception::UnpackPropertyError& error)
191 {
192 logExpectedException(error);
193 }
194 });
195 }
196
197 private:
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200198 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
Ed Tanous760e66a2023-01-05 10:12:00 -0800221 Application app(*bus, *objServer);
Krzysztof Grobelny09b88f22020-09-02 14:49:01 +0200222
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}