diff options
author | Ed Tanous <ed.tanous@intel.com> | 2017-08-15 19:37:42 +0300 |
---|---|---|
committer | Ed Tanous <ed.tanous@intel.com> | 2017-10-11 23:34:56 +0300 |
commit | 911ac31759cb7b77a856af8806b4e064d50d7422 (patch) | |
tree | c4b714fabb2b956936ab6dffc18d9ff418756cf4 /include/dbus_monitor.hpp | |
parent | 8f0c0481d2280919b38a31656ba21a4347d12620 (diff) | |
download | bmcweb-911ac31759cb7b77a856af8806b4e064d50d7422.tar.xz |
Large updates to webserver
Do not merge yet
Change-Id: I38c56844c1b0e3e8e5493c2705e62e6db7ee2102
Diffstat (limited to 'include/dbus_monitor.hpp')
-rw-r--r-- | include/dbus_monitor.hpp | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/include/dbus_monitor.hpp b/include/dbus_monitor.hpp new file mode 100644 index 0000000000..0306183df9 --- /dev/null +++ b/include/dbus_monitor.hpp @@ -0,0 +1,82 @@ +#pragma once +#include <dbus/filter.hpp> +#include <dbus/match.hpp> +#include <dbus_singleton.hpp> +#include <crow/app.h> +#include <boost/container/flat_map.hpp> + +namespace crow { +namespace dbus_monitor { + +struct DbusWebsocketSession { + std::vector<std::unique_ptr<dbus::match>> matches; + std::vector<dbus::filter> filters; +}; + +static boost::container::flat_map<crow::websocket::connection*, + DbusWebsocketSession> + sessions; + +void on_property_update(dbus::filter& filter, boost::system::error_code ec, + dbus::message s) { + if (!ec) { + std::string object_name; + std::vector<std::pair<std::string, dbus::dbus_variant>> values; + s.unpack(object_name, values); + nlohmann::json j; + for (auto& value : values) { + boost::apply_visitor([&](auto val) { j[s.get_path()] = val; }, + value.second); + } + auto data_to_send = j.dump(); + + for (auto& session : sessions) { + session.first->send_text(data_to_send); + } + } + filter.async_dispatch([&](boost::system::error_code ec, dbus::message s) { + on_property_update(filter, ec, s); + }); +}; + +template <typename... Middlewares> +void request_routes(Crow<Middlewares...>& app) { + CROW_ROUTE(app, "/dbus_monitor") + .websocket() + .onopen([&](crow::websocket::connection& conn) { + std::string path_namespace(conn.req.url_params.get("path_namespace")); + if (path_namespace.empty()) { + conn.send_text( + nlohmann::json({"error", "Did not specify path_namespace"})); + conn.close("error"); + } + sessions[&conn] = DbusWebsocketSession(); + std::string match_string( + "type='signal'," + "interface='org.freedesktop.DBus.Properties'," + "path_namespace='" + + path_namespace + "'"); + sessions[&conn].matches.push_back(std::make_unique<dbus::match>( + crow::connections::system_bus, std::move(match_string))); + + sessions[&conn].filters.emplace_back( + crow::connections::system_bus, [path_namespace](dbus::message m) { + return m.get_member() == "PropertiesChanged" && + boost::starts_with(m.get_path(), path_namespace); + }); + auto& this_filter = sessions[&conn].filters.back(); + this_filter.async_dispatch( + [&](boost::system::error_code ec, dbus::message s) { + on_property_update(this_filter, ec, s); + }); + + }) + .onclose([&](crow::websocket::connection& conn, + const std::string& reason) { sessions.erase(&conn); }) + .onmessage([&](crow::websocket::connection& conn, const std::string& data, + bool is_binary) { + CROW_LOG_ERROR << "Got unexpected message from client on sensorws"; + }); +} +} // namespace redfish +} // namespace crow |