Ed Tanous | 911ac31 | 2017-08-15 09:37:42 -0700 | [diff] [blame] | 1 | #pragma once |
Ed Tanous | 911ac31 | 2017-08-15 09:37:42 -0700 | [diff] [blame] | 2 | #include <dbus_singleton.hpp> |
Ed Tanous | aa2e59c | 2018-04-12 12:17:20 -0700 | [diff] [blame^] | 3 | #include <sdbusplus/bus/match.hpp> |
Ed Tanous | 911ac31 | 2017-08-15 09:37:42 -0700 | [diff] [blame] | 4 | #include <crow/app.h> |
| 5 | #include <boost/container/flat_map.hpp> |
| 6 | |
| 7 | namespace crow { |
| 8 | namespace dbus_monitor { |
| 9 | |
| 10 | struct DbusWebsocketSession { |
Ed Tanous | aa2e59c | 2018-04-12 12:17:20 -0700 | [diff] [blame^] | 11 | std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches; |
Ed Tanous | 911ac31 | 2017-08-15 09:37:42 -0700 | [diff] [blame] | 12 | }; |
| 13 | |
| 14 | static boost::container::flat_map<crow::websocket::connection*, |
| 15 | DbusWebsocketSession> |
| 16 | sessions; |
| 17 | |
Ed Tanous | aa2e59c | 2018-04-12 12:17:20 -0700 | [diff] [blame^] | 18 | int on_property_update(sd_bus_message* m, void* userdata, |
| 19 | sd_bus_error* ret_error) { |
| 20 | if (ret_error == nullptr || sd_bus_error_is_set(ret_error)) { |
| 21 | CROW_LOG_ERROR << "Sdbus error in on_property_update"; |
| 22 | return 0; |
Ed Tanous | 911ac31 | 2017-08-15 09:37:42 -0700 | [diff] [blame] | 23 | } |
Ed Tanous | aa2e59c | 2018-04-12 12:17:20 -0700 | [diff] [blame^] | 24 | sdbusplus::message::message message(m); |
| 25 | std::string object_name; |
| 26 | std::vector< |
| 27 | std::pair<std::string, sdbusplus::message::variant< |
| 28 | std::string, bool, int64_t, uint64_t, double>>> |
| 29 | values; |
| 30 | message.read(object_name, values); |
| 31 | nlohmann::json j; |
| 32 | const std::string& path = message.get_path(); |
| 33 | for (auto& value : values) { |
| 34 | mapbox::util::apply_visitor([&](auto&& val) { j[path] = val; }, |
| 35 | value.second); |
| 36 | } |
| 37 | std::string data_to_send = j.dump(); |
| 38 | |
| 39 | for (const std::pair<crow::websocket::connection*, DbusWebsocketSession>& |
| 40 | session : sessions) { |
| 41 | session.first->send_text(data_to_send); |
| 42 | } |
Ed Tanous | 911ac31 | 2017-08-15 09:37:42 -0700 | [diff] [blame] | 43 | }; |
| 44 | |
| 45 | template <typename... Middlewares> |
| 46 | void request_routes(Crow<Middlewares...>& app) { |
| 47 | CROW_ROUTE(app, "/dbus_monitor") |
| 48 | .websocket() |
| 49 | .onopen([&](crow::websocket::connection& conn) { |
| 50 | std::string path_namespace(conn.req.url_params.get("path_namespace")); |
| 51 | if (path_namespace.empty()) { |
| 52 | conn.send_text( |
| 53 | nlohmann::json({"error", "Did not specify path_namespace"})); |
| 54 | conn.close("error"); |
| 55 | } |
| 56 | sessions[&conn] = DbusWebsocketSession(); |
| 57 | std::string match_string( |
| 58 | "type='signal'," |
| 59 | "interface='org.freedesktop.DBus.Properties'," |
| 60 | "path_namespace='" + |
| 61 | path_namespace + "'"); |
Ed Tanous | aa2e59c | 2018-04-12 12:17:20 -0700 | [diff] [blame^] | 62 | sessions[&conn].matches.emplace_back( |
| 63 | std::make_unique<sdbusplus::bus::match::match>( |
| 64 | *crow::connections::system_bus, match_string, |
| 65 | on_property_update)); |
Ed Tanous | 911ac31 | 2017-08-15 09:37:42 -0700 | [diff] [blame] | 66 | |
| 67 | }) |
| 68 | .onclose([&](crow::websocket::connection& conn, |
| 69 | const std::string& reason) { sessions.erase(&conn); }) |
| 70 | .onmessage([&](crow::websocket::connection& conn, const std::string& data, |
| 71 | bool is_binary) { |
| 72 | CROW_LOG_ERROR << "Got unexpected message from client on sensorws"; |
| 73 | }); |
| 74 | } |
Ed Tanous | aa2e59c | 2018-04-12 12:17:20 -0700 | [diff] [blame^] | 75 | } // namespace dbus_monitor |
Ed Tanous | 911ac31 | 2017-08-15 09:37:42 -0700 | [diff] [blame] | 76 | } // namespace crow |