blob: 3af461bca4620fca8c25cf715b980eb0d87317b7 [file] [log] [blame]
#include <boost/asio.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/container/stable_vector.hpp>
#include "crow/app.h"
#include "crow/ci_map.h"
#include "crow/common.h"
#include "crow/dumb_timer_queue.h"
#include "crow/http_connection.h"
#include "crow/http_parser_merged.h"
#include "crow/http_request.h"
#include "crow/http_response.h"
#include "crow/http_server.h"
#include "crow/logging.h"
#include "crow/middleware.h"
#include "crow/middleware_context.h"
#include "crow/mustache.h"
#include "crow/parser.h"
#include "crow/query_string.h"
#include "crow/routing.h"
#include "crow/settings.h"
#include "crow/socket_adaptors.h"
#include "crow/utility.h"
#include "crow/websocket.h"
#include "redfish_v1.hpp"
#include "security_headers_middleware.hpp"
#include "ssl_key_handler.hpp"
#include "token_authorization_middleware.hpp"
#include "web_kvm.hpp"
#include "webassets.hpp"
#include "nlohmann/json.hpp"
#include <dbus/connection.hpp>
#include <dbus/endpoint.hpp>
#include <dbus/filter.hpp>
#include <dbus/match.hpp>
#include <dbus/message.hpp>
#include <chrono>
#include <iostream>
#include <memory>
#include <string>
#include <unordered_set>
static std::shared_ptr<dbus::connection> system_bus;
static std::vector<dbus::match> dbus_matches;
static std::shared_ptr<dbus::filter> sensor_filter;
struct DbusWebsocketSession {
std::vector<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) {
std::string object_name;
std::vector<std::pair<std::string, dbus::dbus_variant>> values;
s.unpack(object_name).unpack(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);;
});
};
int main(int argc, char** argv) {
// Build an io_service (there should only be 1)
auto io = std::make_shared<boost::asio::io_service>();
bool enable_ssl = true;
std::string ssl_pem_file("server.pem");
if (enable_ssl) {
ensuressl::ensure_openssl_key_present_and_valid(ssl_pem_file);
}
crow::App<
crow::TokenAuthorizationMiddleware, crow::SecurityHeadersMiddleware>
app(io);
crow::webassets::request_routes(app);
crow::kvm::request_routes(app);
crow::redfish::request_routes(app);
crow::logger::setLogLevel(crow::LogLevel::INFO);
CROW_ROUTE(app, "/dbus_monitor")
.websocket()
.onopen([&](crow::websocket::connection& conn) {
sessions[&conn] = DbusWebsocketSession();
sessions[&conn].matches.emplace_back(
system_bus,
"type='signal',path_namespace='/xyz/openbmc_project/sensors'");
sessions[&conn].filters.emplace_back(system_bus, [](dbus::message m) {
auto member = m.get_member();
return member == "PropertiesChanged";
});
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";
});
CROW_ROUTE(app, "/intel/firmwareupload")
.methods("POST"_method)([](const crow::request& req) {
auto filepath = "/tmp/fw_update_image";
std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
std::ofstream::trunc);
out << req.body;
out.close();
nlohmann::json j;
j["status"] = "Upload Successfull";
dbus::endpoint fw_update_endpoint(
"xyz.openbmc_project.fwupdate1.server",
"/xyz/openbmc_project/fwupdate1", "xyz.openbmc_project.fwupdate1");
auto m = dbus::message::new_call(fw_update_endpoint, "start");
m.pack(std::string("file://") + filepath);
system_bus->send(m);
return j;
});
crow::logger::setLogLevel(crow::LogLevel::DEBUG);
auto test = app.get_routes();
app.debug_print();
std::cout << "Building SSL context\n";
int port = 18080;
std::cout << "Starting webserver on port " << port << "\n";
app.port(port);
if (enable_ssl) {
std::cout << "SSL Enabled\n";
auto ssl_context = ensuressl::get_ssl_context(ssl_pem_file);
app.ssl(std::move(ssl_context));
}
// app.concurrency(4);
// Start dbus connection
system_bus = std::make_shared<dbus::connection>(*io, dbus::bus::system);
app.run();
}