Large updates to webserver
Do not merge yet
Change-Id: I38c56844c1b0e3e8e5493c2705e62e6db7ee2102
diff --git a/include/dbus_monitor.hpp b/include/dbus_monitor.hpp
new file mode 100644
index 0000000..0306183
--- /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