1b65dc1c6SEd Tanous #include <boost/asio/io_context.hpp>
2b65dc1c6SEd Tanous #include <boost/asio/signal_set.hpp>
32be0e173SKrzysztof Grobelny #include <sdbusplus/asio/connection.hpp>
42be0e173SKrzysztof Grobelny #include <sdbusplus/asio/object_server.hpp>
5807419d3SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
62be0e173SKrzysztof Grobelny #include <sdbusplus/bus.hpp>
72be0e173SKrzysztof Grobelny 
82be0e173SKrzysztof Grobelny #include <iostream>
92be0e173SKrzysztof Grobelny 
106adfe948SKrzysztof Grobelny const std::string demoServiceName = "demo.service";
116adfe948SKrzysztof Grobelny const std::string demoObjectPath = "/xyz/demo";
126adfe948SKrzysztof Grobelny const std::string demoInterfaceName = "xyz.demo";
136adfe948SKrzysztof Grobelny const std::string propertyGrettingName = "Greetings";
146adfe948SKrzysztof Grobelny const std::string propertyGoodbyesName = "Goodbyes";
152be0e173SKrzysztof Grobelny 
162be0e173SKrzysztof Grobelny class Application
172be0e173SKrzysztof Grobelny {
182be0e173SKrzysztof Grobelny   public:
Application(boost::asio::io_context & ioc,sdbusplus::asio::connection & bus,sdbusplus::asio::object_server & objServer)192be0e173SKrzysztof Grobelny     Application(boost::asio::io_context& ioc, sdbusplus::asio::connection& bus,
202be0e173SKrzysztof Grobelny                 sdbusplus::asio::object_server& objServer) :
212be0e173SKrzysztof Grobelny         ioc_(ioc),
222be0e173SKrzysztof Grobelny         bus_(bus), objServer_(objServer)
232be0e173SKrzysztof Grobelny     {
248fc06397SKrzysztof Grobelny         demo_ = objServer_.add_unique_interface(
256adfe948SKrzysztof Grobelny             demoObjectPath, demoInterfaceName,
268fc06397SKrzysztof Grobelny             [this](sdbusplus::asio::dbus_interface& demo) {
2790fab6bbSKrzysztof Grobelny             demo.register_property_r<std::string>(
2890fab6bbSKrzysztof Grobelny                 propertyGrettingName, sdbusplus::vtable::property_::const_,
292be0e173SKrzysztof Grobelny                 [this](const auto&) { return greetings_; });
302be0e173SKrzysztof Grobelny 
3190fab6bbSKrzysztof Grobelny             demo.register_property_rw<std::string>(
3290fab6bbSKrzysztof Grobelny                 propertyGoodbyesName,
332be0e173SKrzysztof Grobelny                 sdbusplus::vtable::property_::emits_change,
342be0e173SKrzysztof Grobelny                 [this](const auto& newPropertyValue, const auto&) {
352be0e173SKrzysztof Grobelny                 goodbyes_ = newPropertyValue;
36ae47928bSJonathan Doman                 return true;
372be0e173SKrzysztof Grobelny             },
382be0e173SKrzysztof Grobelny                 [this](const auto&) { return goodbyes_; });
398fc06397SKrzysztof Grobelny         });
402be0e173SKrzysztof Grobelny     }
412be0e173SKrzysztof Grobelny 
fatalErrors() const42807419d3SKrzysztof Grobelny     uint32_t fatalErrors() const
43807419d3SKrzysztof Grobelny     {
44807419d3SKrzysztof Grobelny         return fatalErrors_;
45807419d3SKrzysztof Grobelny     }
46807419d3SKrzysztof Grobelny 
getFailed()47807419d3SKrzysztof Grobelny     auto getFailed()
48807419d3SKrzysztof Grobelny     {
49807419d3SKrzysztof Grobelny         return [this](boost::system::error_code error) {
50807419d3SKrzysztof Grobelny             std::cerr << "Error: getProperty failed " << error << "\n";
51807419d3SKrzysztof Grobelny             ++fatalErrors_;
52807419d3SKrzysztof Grobelny         };
53807419d3SKrzysztof Grobelny     }
54807419d3SKrzysztof Grobelny 
asyncReadPropertyWithIncorrectType()55807419d3SKrzysztof Grobelny     void asyncReadPropertyWithIncorrectType()
56807419d3SKrzysztof Grobelny     {
576adfe948SKrzysztof Grobelny         sdbusplus::asio::getProperty<uint32_t>(
586adfe948SKrzysztof Grobelny             bus_, demoServiceName, demoObjectPath, demoInterfaceName,
596adfe948SKrzysztof Grobelny             propertyGrettingName,
606adfe948SKrzysztof Grobelny             [this](boost::system::error_code ec, uint32_t) {
616adfe948SKrzysztof Grobelny             if (ec)
6295874d93SEd Tanous             {
63807419d3SKrzysztof Grobelny                 std::cout
64807419d3SKrzysztof Grobelny                     << "As expected failed to getProperty with wrong type: "
656adfe948SKrzysztof Grobelny                     << ec << "\n";
6695874d93SEd Tanous                 return;
6795874d93SEd Tanous             }
6895874d93SEd Tanous 
69807419d3SKrzysztof Grobelny             std::cerr << "Error: it was expected to fail getProperty due "
70807419d3SKrzysztof Grobelny                          "to wrong type\n";
71807419d3SKrzysztof Grobelny             ++fatalErrors_;
72807419d3SKrzysztof Grobelny         });
73807419d3SKrzysztof Grobelny     }
74807419d3SKrzysztof Grobelny 
asyncReadProperties()752be0e173SKrzysztof Grobelny     void asyncReadProperties()
762be0e173SKrzysztof Grobelny     {
776adfe948SKrzysztof Grobelny         sdbusplus::asio::getProperty<std::string>(
786adfe948SKrzysztof Grobelny             bus_, demoServiceName, demoObjectPath, demoInterfaceName,
796adfe948SKrzysztof Grobelny             propertyGrettingName,
8095874d93SEd Tanous             [this](boost::system::error_code ec, std::string value) {
8195874d93SEd Tanous             if (ec)
8295874d93SEd Tanous             {
8395874d93SEd Tanous                 getFailed();
8495874d93SEd Tanous                 return;
8595874d93SEd Tanous             }
86807419d3SKrzysztof Grobelny             std::cout << "Greetings value is: " << value << "\n";
872be0e173SKrzysztof Grobelny         });
882be0e173SKrzysztof Grobelny 
896adfe948SKrzysztof Grobelny         sdbusplus::asio::getProperty<std::string>(
906adfe948SKrzysztof Grobelny             bus_, demoServiceName, demoObjectPath, demoInterfaceName,
916adfe948SKrzysztof Grobelny             propertyGoodbyesName,
9295874d93SEd Tanous             [this](boost::system::error_code ec, std::string value) {
9395874d93SEd Tanous             if (ec)
9495874d93SEd Tanous             {
9595874d93SEd Tanous                 getFailed();
9695874d93SEd Tanous                 return;
9795874d93SEd Tanous             }
98807419d3SKrzysztof Grobelny             std::cout << "Goodbyes value is: " << value << "\n";
992be0e173SKrzysztof Grobelny         });
1002be0e173SKrzysztof Grobelny     }
1012be0e173SKrzysztof Grobelny 
asyncChangeProperty()1022be0e173SKrzysztof Grobelny     void asyncChangeProperty()
1032be0e173SKrzysztof Grobelny     {
1046adfe948SKrzysztof Grobelny         sdbusplus::asio::setProperty(
1056adfe948SKrzysztof Grobelny             bus_, demoServiceName, demoObjectPath, demoInterfaceName,
1066adfe948SKrzysztof Grobelny             propertyGrettingName, "Hi, hey, hello",
1076adfe948SKrzysztof Grobelny             [this](const boost::system::error_code& ec) {
1086adfe948SKrzysztof Grobelny             if (ec)
10995874d93SEd Tanous             {
110*d2149044SPatrick Williams                 std::cout << "As expected, failed to set greetings property: "
1116adfe948SKrzysztof Grobelny                           << ec << "\n";
11295874d93SEd Tanous                 return;
11395874d93SEd Tanous             }
11495874d93SEd Tanous 
115*d2149044SPatrick Williams             std::cout << "Error: it was expected to fail to change greetings\n";
116807419d3SKrzysztof Grobelny             ++fatalErrors_;
1172be0e173SKrzysztof Grobelny         });
1182be0e173SKrzysztof Grobelny 
1196adfe948SKrzysztof Grobelny         sdbusplus::asio::setProperty(
1206adfe948SKrzysztof Grobelny             bus_, demoServiceName, demoObjectPath, demoInterfaceName,
1216adfe948SKrzysztof Grobelny             propertyGoodbyesName, "Bye bye",
1226adfe948SKrzysztof Grobelny             [this](const boost::system::error_code& ec) {
1236adfe948SKrzysztof Grobelny             if (ec)
12495874d93SEd Tanous             {
125*d2149044SPatrick Williams                 std::cout << "Error: it supposed to be ok to change goodbyes "
126807419d3SKrzysztof Grobelny                              "property: "
1276adfe948SKrzysztof Grobelny                           << ec << "\n";
128807419d3SKrzysztof Grobelny                 ++fatalErrors_;
12995874d93SEd Tanous                 return;
13095874d93SEd Tanous             }
1312be0e173SKrzysztof Grobelny             std::cout << "Changed goodbyes property as expected\n";
1322be0e173SKrzysztof Grobelny             boost::asio::post(ioc_, [this] { asyncReadProperties(); });
1332be0e173SKrzysztof Grobelny         });
1342be0e173SKrzysztof Grobelny     }
1352be0e173SKrzysztof Grobelny 
syncChangeGoodbyes(std::string_view value)1368fc06397SKrzysztof Grobelny     void syncChangeGoodbyes(std::string_view value)
1378fc06397SKrzysztof Grobelny     {
1388fc06397SKrzysztof Grobelny         goodbyes_ = value;
1396adfe948SKrzysztof Grobelny         demo_->signal_property(propertyGoodbyesName);
1408fc06397SKrzysztof Grobelny     }
1418fc06397SKrzysztof Grobelny 
1422be0e173SKrzysztof Grobelny   private:
1432be0e173SKrzysztof Grobelny     boost::asio::io_context& ioc_;
1442be0e173SKrzysztof Grobelny     sdbusplus::asio::connection& bus_;
1452be0e173SKrzysztof Grobelny     sdbusplus::asio::object_server& objServer_;
1462be0e173SKrzysztof Grobelny 
1478fc06397SKrzysztof Grobelny     std::unique_ptr<sdbusplus::asio::dbus_interface> demo_;
1482be0e173SKrzysztof Grobelny     std::string greetings_ = "Hello";
1492be0e173SKrzysztof Grobelny     std::string goodbyes_ = "Bye";
1502be0e173SKrzysztof Grobelny 
151807419d3SKrzysztof Grobelny     uint32_t fatalErrors_ = 0u;
1522be0e173SKrzysztof Grobelny };
1532be0e173SKrzysztof Grobelny 
main(int,char **)1542be0e173SKrzysztof Grobelny int main(int, char**)
1552be0e173SKrzysztof Grobelny {
1562be0e173SKrzysztof Grobelny     boost::asio::io_context ioc;
1572be0e173SKrzysztof Grobelny     boost::asio::signal_set signals(ioc, SIGINT, SIGTERM);
1582be0e173SKrzysztof Grobelny 
1592be0e173SKrzysztof Grobelny     signals.async_wait(
1602be0e173SKrzysztof Grobelny         [&ioc](const boost::system::error_code&, const int&) { ioc.stop(); });
1612be0e173SKrzysztof Grobelny 
1622be0e173SKrzysztof Grobelny     auto bus = std::make_shared<sdbusplus::asio::connection>(ioc);
1632be0e173SKrzysztof Grobelny     auto objServer = std::make_unique<sdbusplus::asio::object_server>(bus);
1642be0e173SKrzysztof Grobelny 
1656adfe948SKrzysztof Grobelny     bus->request_name(demoServiceName.c_str());
1662be0e173SKrzysztof Grobelny 
1672be0e173SKrzysztof Grobelny     Application app(ioc, *bus, *objServer);
1682be0e173SKrzysztof Grobelny 
1698fc06397SKrzysztof Grobelny     app.syncChangeGoodbyes("Good bye");
1708fc06397SKrzysztof Grobelny 
171807419d3SKrzysztof Grobelny     boost::asio::post(ioc,
172807419d3SKrzysztof Grobelny                       [&app] { app.asyncReadPropertyWithIncorrectType(); });
1732be0e173SKrzysztof Grobelny     boost::asio::post(ioc, [&app] { app.asyncReadProperties(); });
1742be0e173SKrzysztof Grobelny     boost::asio::post(ioc, [&app] { app.asyncChangeProperty(); });
1752be0e173SKrzysztof Grobelny 
1762be0e173SKrzysztof Grobelny     ioc.run();
1772be0e173SKrzysztof Grobelny 
178807419d3SKrzysztof Grobelny     std::cout << "Fatal errors count: " << app.fatalErrors() << "\n";
179807419d3SKrzysztof Grobelny 
180807419d3SKrzysztof Grobelny     return app.fatalErrors();
1812be0e173SKrzysztof Grobelny }
182