#include #include #include #include #include #include #include namespace xyz { namespace demo { const std::string path = "/xyz/demo"; const std::string name = "xyz.demo"; const std::string interface = "xyz.demo.interface"; } // namespace demo } // namespace xyz namespace name { const std::string greetings = "Greetings"; const std::string goodbyes = "Goodbyes"; const std::string value = "Value"; } // namespace name 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(xyz::demo::path, xyz::demo::interface); demo_->register_property_r(name::greetings, std::string(), sdbusplus::vtable::property_::const_, [this](const auto&) { return greetings_; }); demo_->register_property_rw( name::goodbyes, std::string(), sdbusplus::vtable::property_::emits_change, [this](const auto& newPropertyValue, const auto&) { goodbyes_ = newPropertyValue; return 1; }, [this](const auto&) { return goodbyes_; }); demo_->register_property_r( name::value, uint32_t{42}, 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 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_, xyz::demo::name, xyz::demo::path, xyz::demo::interface, [this](boost::system::error_code ec, std::vector>>& properties) -> void { if (ec) { logSystemErrorCode(ec); return; } try { std::string greetings; std::string goodbyes; sdbusplus::unpackProperties(properties, name::greetings, greetings, name::goodbyes, goodbyes); std::cout << "value of greetings: " << greetings << "\n"; std::cout << "value of goodbyes: " << goodbyes << "\n"; } catch (const sdbusplus::exception::UnpackPropertyError& error) { logException(error); } try { std::string value; sdbusplus::unpackProperties(properties, name::value, 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_, xyz::demo::name, xyz::demo::path, xyz::demo::interface, [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, name::greetings, greetings, name::goodbyes, goodbyes, name::value, 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, name::greetings, 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(xyz::demo::name.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(); }