| Ed Tanous | b65dc1c | 2023-03-07 17:41:57 -0800 | [diff] [blame] | 1 | #include <boost/asio/io_context.hpp> | 
|  | 2 | #include <boost/asio/signal_set.hpp> | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 3 | #include <sdbusplus/asio/connection.hpp> | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 4 | #include <sdbusplus/asio/object_server.hpp> | 
| Krzysztof Grobelny | 807419d | 2020-09-28 11:39:22 +0200 | [diff] [blame] | 5 | #include <sdbusplus/asio/property.hpp> | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 6 | #include <sdbusplus/bus.hpp> | 
|  | 7 | #include <sdbusplus/unpack_properties.hpp> | 
|  | 8 |  | 
|  | 9 | #include <iostream> | 
|  | 10 |  | 
| Krzysztof Grobelny | 6adfe94 | 2021-12-21 13:57:22 +0100 | [diff] [blame] | 11 | const std::string demoServiceName = "demo.service"; | 
|  | 12 | const std::string demoObjectPath = "/xyz/demo"; | 
|  | 13 | const std::string demoInterfaceName = "xyz.demo"; | 
|  | 14 | const std::string propertyGrettingName = "Greetings"; | 
|  | 15 | const std::string propertyGoodbyesName = "Goodbyes"; | 
|  | 16 | const std::string propertyValueName = "Value"; | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 17 |  | 
|  | 18 | class Application | 
|  | 19 | { | 
|  | 20 | public: | 
| Ed Tanous | 760e66a | 2023-01-05 10:12:00 -0800 | [diff] [blame] | 21 | Application(sdbusplus::asio::connection& bus, | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 22 | sdbusplus::asio::object_server& objServer) : | 
| Ed Tanous | 760e66a | 2023-01-05 10:12:00 -0800 | [diff] [blame] | 23 | bus_(bus), | 
|  | 24 | objServer_(objServer) | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 25 | { | 
| Patrick Williams | 1a25a10 | 2022-09-29 17:18:26 -0500 | [diff] [blame] | 26 | demo_ = objServer_.add_unique_interface(demoObjectPath, | 
|  | 27 | demoInterfaceName); | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 28 |  | 
| Krzysztof Grobelny | 90fab6b | 2022-02-18 14:21:21 +0100 | [diff] [blame] | 29 | demo_->register_property_r<std::string>( | 
|  | 30 | propertyGrettingName, sdbusplus::vtable::property_::const_, | 
|  | 31 | [this](const auto&) { return greetings_; }); | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 32 |  | 
| Krzysztof Grobelny | 90fab6b | 2022-02-18 14:21:21 +0100 | [diff] [blame] | 33 | demo_->register_property_rw<std::string>( | 
|  | 34 | propertyGoodbyesName, sdbusplus::vtable::property_::emits_change, | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 35 | [this](const auto& newPropertyValue, const auto&) { | 
|  | 36 | goodbyes_ = newPropertyValue; | 
| Jonathan Doman | ae47928 | 2022-06-03 13:29:50 -0700 | [diff] [blame] | 37 | return true; | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 38 | }, | 
|  | 39 | [this](const auto&) { return goodbyes_; }); | 
|  | 40 |  | 
| Krzysztof Grobelny | 90fab6b | 2022-02-18 14:21:21 +0100 | [diff] [blame] | 41 | demo_->register_property_r<uint32_t>( | 
|  | 42 | propertyValueName, sdbusplus::vtable::property_::const_, | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 43 | [](const auto& value) -> uint32_t { return value; }); | 
|  | 44 |  | 
|  | 45 | demo_->initialize(); | 
|  | 46 | } | 
|  | 47 |  | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 48 | uint32_t fatalErrors() const | 
|  | 49 | { | 
|  | 50 | return fatalErrors_; | 
|  | 51 | } | 
|  | 52 |  | 
| Ed Tanous | 95874d9 | 2021-02-19 17:14:27 -0800 | [diff] [blame] | 53 | auto logSystemErrorCode(boost::system::error_code ec) | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 54 | { | 
| Ed Tanous | 95874d9 | 2021-02-19 17:14:27 -0800 | [diff] [blame] | 55 | std::cerr << "Error: " << ec << "\n"; | 
|  | 56 | ++fatalErrors_; | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 57 | } | 
|  | 58 |  | 
|  | 59 | void logException(const std::exception& e) | 
|  | 60 | { | 
|  | 61 | std::cerr << "Error: " << e.what() << "\n"; | 
|  | 62 | ++fatalErrors_; | 
|  | 63 | } | 
|  | 64 |  | 
| Krzysztof Grobelny | c8447d5 | 2022-01-05 13:21:37 +0100 | [diff] [blame] | 65 | void logUnpackError(const sdbusplus::UnpackErrorReason reason, | 
|  | 66 | const std::string& property) | 
| Krzysztof Grobelny | 6adfe94 | 2021-12-21 13:57:22 +0100 | [diff] [blame] | 67 | { | 
| Krzysztof Grobelny | c8447d5 | 2022-01-05 13:21:37 +0100 | [diff] [blame] | 68 | std::cerr << "UnpackError: " << static_cast<int>(reason) << ", " | 
|  | 69 | << property << "\n"; | 
| Krzysztof Grobelny | 6adfe94 | 2021-12-21 13:57:22 +0100 | [diff] [blame] | 70 | ++fatalErrors_; | 
|  | 71 | } | 
|  | 72 |  | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 73 | void logExpectedException( | 
|  | 74 | const sdbusplus::exception::UnpackPropertyError& error) | 
|  | 75 | { | 
| Krzysztof Grobelny | c8447d5 | 2022-01-05 13:21:37 +0100 | [diff] [blame] | 76 | std::cout << "As expected " << error.what() << "\n"; | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 77 | } | 
|  | 78 |  | 
|  | 79 | void asyncGetAllPropertiesStringTypeOnly() | 
|  | 80 | { | 
|  | 81 | sdbusplus::asio::getAllProperties( | 
| Krzysztof Grobelny | 6adfe94 | 2021-12-21 13:57:22 +0100 | [diff] [blame] | 82 | bus_, demoServiceName, demoObjectPath, demoInterfaceName, | 
| Krzysztof Grobelny | c8447d5 | 2022-01-05 13:21:37 +0100 | [diff] [blame] | 83 | [this](const boost::system::error_code ec, | 
|  | 84 | const std::vector<std::pair< | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 85 | std::string, std::variant<std::monostate, std::string>>>& | 
| Ed Tanous | 95874d9 | 2021-02-19 17:14:27 -0800 | [diff] [blame] | 86 | properties) -> void { | 
|  | 87 | if (ec) | 
|  | 88 | { | 
|  | 89 | logSystemErrorCode(ec); | 
|  | 90 | return; | 
|  | 91 | } | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 92 | { | 
| Krzysztof Grobelny | c8447d5 | 2022-01-05 13:21:37 +0100 | [diff] [blame] | 93 | 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 Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 102 |  | 
| Krzysztof Grobelny | c8447d5 | 2022-01-05 13:21:37 +0100 | [diff] [blame] | 103 | if (success) | 
| Krzysztof Grobelny | 6adfe94 | 2021-12-21 13:57:22 +0100 | [diff] [blame] | 104 | { | 
| Krzysztof Grobelny | c8447d5 | 2022-01-05 13:21:37 +0100 | [diff] [blame] | 105 | std::cout << "value of greetings: " << *greetings | 
|  | 106 | << "\n"; | 
|  | 107 | std::cout << "value of goodbyes: " << *goodbyes << "\n"; | 
| Krzysztof Grobelny | 6adfe94 | 2021-12-21 13:57:22 +0100 | [diff] [blame] | 108 | } | 
|  | 109 | else | 
|  | 110 | { | 
| Krzysztof Grobelny | c8447d5 | 2022-01-05 13:21:37 +0100 | [diff] [blame] | 111 | ++fatalErrors_; | 
| Krzysztof Grobelny | 6adfe94 | 2021-12-21 13:57:22 +0100 | [diff] [blame] | 112 | } | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 113 | } | 
|  | 114 |  | 
|  | 115 | try | 
|  | 116 | { | 
|  | 117 | std::string value; | 
| Krzysztof Grobelny | 6adfe94 | 2021-12-21 13:57:22 +0100 | [diff] [blame] | 118 | sdbusplus::unpackProperties(properties, propertyValueName, | 
|  | 119 | value); | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 120 |  | 
|  | 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 Grobelny | 6adfe94 | 2021-12-21 13:57:22 +0100 | [diff] [blame] | 135 | bus_, demoServiceName, demoObjectPath, demoInterfaceName, | 
| Krzysztof Grobelny | c8447d5 | 2022-01-05 13:21:37 +0100 | [diff] [blame] | 136 | [this](const boost::system::error_code ec, | 
|  | 137 | const std::vector<std::pair< | 
| Ed Tanous | 95874d9 | 2021-02-19 17:14:27 -0800 | [diff] [blame] | 138 | 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 Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 146 | try | 
|  | 147 | { | 
|  | 148 | std::string greetings; | 
|  | 149 | std::string goodbyes; | 
|  | 150 | uint32_t value = 0u; | 
| Krzysztof Grobelny | 6adfe94 | 2021-12-21 13:57:22 +0100 | [diff] [blame] | 151 | sdbusplus::unpackProperties(properties, | 
|  | 152 | propertyGrettingName, greetings, | 
|  | 153 | propertyGoodbyesName, goodbyes, | 
|  | 154 | propertyValueName, value); | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 155 |  | 
|  | 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 Grobelny | 6adfe94 | 2021-12-21 13:57:22 +0100 | [diff] [blame] | 183 | sdbusplus::unpackProperties( | 
|  | 184 | properties, propertyGrettingName, notMatchingType); | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 185 |  | 
|  | 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 Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 198 | sdbusplus::asio::connection& bus_; | 
|  | 199 | sdbusplus::asio::object_server& objServer_; | 
|  | 200 |  | 
| Krzysztof Grobelny | 8fc0639 | 2020-09-28 13:11:22 +0200 | [diff] [blame] | 201 | std::unique_ptr<sdbusplus::asio::dbus_interface> demo_; | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 202 | std::string greetings_ = "Hello"; | 
|  | 203 | std::string goodbyes_ = "Bye"; | 
|  | 204 |  | 
|  | 205 | uint32_t fatalErrors_ = 0u; | 
|  | 206 | }; | 
|  | 207 |  | 
|  | 208 | int 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 Grobelny | 6adfe94 | 2021-12-21 13:57:22 +0100 | [diff] [blame] | 219 | bus->request_name(demoServiceName.c_str()); | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 220 |  | 
| Ed Tanous | 760e66a | 2023-01-05 10:12:00 -0800 | [diff] [blame] | 221 | Application app(*bus, *objServer); | 
| Krzysztof Grobelny | 09b88f2 | 2020-09-02 14:49:01 +0200 | [diff] [blame] | 222 |  | 
|  | 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 | } |