blob: ab7ebef92854ea029877b221b6d1705606872996 [file] [log] [blame]
Ed Tanous911ac312017-08-15 09:37:42 -07001#pragma once
Ed Tanous911ac312017-08-15 09:37:42 -07002#include <dbus_singleton.hpp>
Ed Tanousaa2e59c2018-04-12 12:17:20 -07003#include <sdbusplus/bus/match.hpp>
Ed Tanous911ac312017-08-15 09:37:42 -07004#include <crow/app.h>
5#include <boost/container/flat_map.hpp>
6
7namespace crow {
8namespace dbus_monitor {
9
10struct DbusWebsocketSession {
Ed Tanousaa2e59c2018-04-12 12:17:20 -070011 std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
Ed Tanous911ac312017-08-15 09:37:42 -070012};
13
14static boost::container::flat_map<crow::websocket::connection*,
15 DbusWebsocketSession>
16 sessions;
17
Ed Tanousaa2e59c2018-04-12 12:17:20 -070018int 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 Tanous911ac312017-08-15 09:37:42 -070023 }
Ed Tanousaa2e59c2018-04-12 12:17:20 -070024 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 Tanous911ac312017-08-15 09:37:42 -070043};
44
45template <typename... Middlewares>
46void 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 Tanousaa2e59c2018-04-12 12:17:20 -070062 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 Tanous911ac312017-08-15 09:37:42 -070066
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 Tanousaa2e59c2018-04-12 12:17:20 -070075} // namespace dbus_monitor
Ed Tanous911ac312017-08-15 09:37:42 -070076} // namespace crow