#include #include #include #include #include #include #include const std::string demoServiceName = "demo.service"; const std::string demoObjectPath = "/xyz/demo"; const std::string demoInterfaceName = "xyz.demo"; const std::string propertyGrettingName = "Greetings"; const std::string propertyGoodbyesName = "Goodbyes"; const std::string propertyValueName = "Value"; class Application { public: Application(boost::asio::io_context& ioc, sdbusplus::asio::connection& bus, sdbusplus::asio::object_server& objServer) : ioc_(ioc), bus_(bus), objServer_(objServer) { demo_ = objServer_.add_unique_interface(demoObjectPath, demoInterfaceName); demo_->register_property_r( propertyGrettingName, sdbusplus::vtable::property_::const_, [this](const auto&) { return greetings_; }); demo_->register_property_rw( propertyGoodbyesName, sdbusplus::vtable::property_::emits_change, [this](const auto& newPropertyValue, const auto&) { goodbyes_ = newPropertyValue; return 1; }, [this](const auto&) { return goodbyes_; }); demo_->register_property_r( propertyValueName, sdbusplus::vtable::property_::const_, [](const auto& value) -> uint32_t { return value; }); demo_->initialize(); } uint32_t fatalErrors() const { return fatalErrors_; } auto logSystemErrorCode(boost::system::error_code ec) { std::cerr << "Error: " << ec << "\n"; ++fatalErrors_; } void logException(const std::exception& e) { std::cerr << "Error: " << e.what() << "\n"; ++fatalErrors_; } void logBadProperty(const std::string& badProperty) { std::cerr << "BadProperty: " << badProperty << "\n"; ++fatalErrors_; } void logExpectedException( const sdbusplus::exception::UnpackPropertyError& error) { std::cout << "As expected " << error.what() << " => " << error.propertyName << " is missing because " << error.reason << "\n"; } void asyncGetAllPropertiesStringTypeOnly() { sdbusplus::asio::getAllProperties( bus_, demoServiceName, demoObjectPath, demoInterfaceName, [this](boost::system::error_code ec, std::vector>>& properties) -> void { if (ec) { logSystemErrorCode(ec); return; } { std::string greetings; std::string goodbyes; std::optional badProperty = sdbusplus::unpackPropertiesNoThrow( properties, propertyGrettingName, greetings, propertyGoodbyesName, goodbyes); if (badProperty) { logBadProperty(*badProperty); } else { std::cout << "value of greetings: " << greetings << "\n"; std::cout << "value of goodbyes: " << goodbyes << "\n"; } } try { std::string value; sdbusplus::unpackProperties(properties, propertyValueName, value); std::cerr << "Error: it should fail because of " "not matched type\n"; ++fatalErrors_; } catch (const sdbusplus::exception::UnpackPropertyError& error) { logExpectedException(error); } }); } void asyncGetAllProperties() { sdbusplus::asio::getAllProperties( bus_, demoServiceName, demoObjectPath, demoInterfaceName, [this](boost::system::error_code ec, std::vector>>& properties) -> void { if (ec) { logSystemErrorCode(ec); return; } try { std::string greetings; std::string goodbyes; uint32_t value = 0u; sdbusplus::unpackProperties(properties, propertyGrettingName, greetings, propertyGoodbyesName, goodbyes, propertyValueName, value); std::cout << "value of greetings: " << greetings << "\n"; std::cout << "value of goodbyes: " << goodbyes << "\n"; std::cout << "value of value: " << value << "\n"; } catch (const sdbusplus::exception::UnpackPropertyError& error) { logException(error); } try { std::string unknownProperty; sdbusplus::unpackProperties( properties, "UnknownPropertyName", unknownProperty); std::cerr << "Error: it should fail because of " "missing property\n"; ++fatalErrors_; } catch (const sdbusplus::exception::UnpackPropertyError& error) { logExpectedException(error); } try { uint32_t notMatchingType; sdbusplus::unpackProperties( properties, propertyGrettingName, notMatchingType); std::cerr << "Error: it should fail because of " "not matched type\n"; ++fatalErrors_; } catch (const sdbusplus::exception::UnpackPropertyError& error) { logExpectedException(error); } }); } private: boost::asio::io_context& ioc_; sdbusplus::asio::connection& bus_; sdbusplus::asio::object_server& objServer_; std::unique_ptr demo_; std::string greetings_ = "Hello"; std::string goodbyes_ = "Bye"; uint32_t fatalErrors_ = 0u; }; int main(int, char**) { boost::asio::io_context ioc; boost::asio::signal_set signals(ioc, SIGINT, SIGTERM); signals.async_wait( [&ioc](const boost::system::error_code&, const int&) { ioc.stop(); }); auto bus = std::make_shared(ioc); auto objServer = std::make_unique(bus); bus->request_name(demoServiceName.c_str()); Application app(ioc, *bus, *objServer); boost::asio::post(ioc, [&app] { app.asyncGetAllPropertiesStringTypeOnly(); }); boost::asio::post(ioc, [&app] { app.asyncGetAllProperties(); }); ioc.run(); std::cout << "Fatal errors count: " << app.fatalErrors() << "\n"; return app.fatalErrors(); }