blob: ec21f6d48d4ea4946c36faf8baefc275128bcdc6 [file] [log] [blame]
Ed Tanousf9273472017-02-28 16:05:13 -08001#include "crow/app.h"
Ed Tanousc4771fb2017-03-13 13:39:49 -07002#include "crow/ci_map.h"
Ed Tanousf9273472017-02-28 16:05:13 -08003#include "crow/common.h"
4#include "crow/dumb_timer_queue.h"
5#include "crow/http_connection.h"
Ed Tanousc4771fb2017-03-13 13:39:49 -07006#include "crow/http_parser_merged.h"
Ed Tanousf9273472017-02-28 16:05:13 -08007#include "crow/http_request.h"
8#include "crow/http_response.h"
9#include "crow/http_server.h"
10#include "crow/json.h"
11#include "crow/logging.h"
12#include "crow/middleware.h"
13#include "crow/middleware_context.h"
14#include "crow/mustache.h"
15#include "crow/parser.h"
Ed Tanousc4771fb2017-03-13 13:39:49 -070016#include "crow/query_string.h"
Ed Tanousf9273472017-02-28 16:05:13 -080017#include "crow/routing.h"
Ed Tanous0fdddb12017-02-28 11:06:34 -080018#include "crow/settings.h"
19#include "crow/socket_adaptors.h"
Ed Tanous0fdddb12017-02-28 11:06:34 -080020#include "crow/utility.h"
Ed Tanous0fdddb12017-02-28 11:06:34 -080021#include "crow/websocket.h"
Ed Tanous0fdddb12017-02-28 11:06:34 -080022
Ed Tanous7d3dba42017-04-05 13:04:39 -070023#include "security_headers_middleware.hpp"
Ed Tanous9140a672017-04-24 17:01:32 -070024#include "ssl_key_handler.hpp"
Ed Tanous7d3dba42017-04-05 13:04:39 -070025#include "token_authorization_middleware.hpp"
Ed Tanous9140a672017-04-24 17:01:32 -070026#include "web_kvm.hpp"
27#include "webassets.hpp"
Ed Tanousb4d29f42017-03-24 16:39:25 -070028
29#include <boost/asio.hpp>
30#include <boost/endian/arithmetic.hpp>
31
Ed Tanousc9b55212017-06-12 13:25:51 -070032#include <dbus/connection.hpp>
33#include <dbus/endpoint.hpp>
34#include <dbus/filter.hpp>
35#include <dbus/match.hpp>
36#include <dbus/message.hpp>
37#include <dbus/utility.hpp>
Ed Tanouscc5a37f2017-05-11 10:27:23 -070038
Ed Tanous0fdddb12017-02-28 11:06:34 -080039#include <iostream>
Ed Tanousc4771fb2017-03-13 13:39:49 -070040#include <memory>
Ed Tanous0fdddb12017-02-28 11:06:34 -080041#include <string>
Ed Tanousc4771fb2017-03-13 13:39:49 -070042#include <unordered_set>
Ed Tanous9b65f1f2017-03-07 15:17:13 -080043
Ed Tanous4d92cbf2017-06-22 15:41:02 -070044static std::shared_ptr<dbus::connection> system_bus;
45static std::shared_ptr<dbus::match> sensor_match;
46static std::shared_ptr<dbus::filter> sensor_filter;
47static std::shared_ptr<dbus::filter> sensor_callback;
Ed Tanouscc5a37f2017-05-11 10:27:23 -070048
Ed Tanous4d92cbf2017-06-22 15:41:02 -070049std::unordered_set<crow::websocket::connection*> users;
Ed Tanouscc5a37f2017-05-11 10:27:23 -070050
Ed Tanous4d92cbf2017-06-22 15:41:02 -070051void on_sensor_update(boost::system::error_code ec, dbus::message s) {
52 std::string object_name;
53 std::vector<std::pair<std::string, dbus::dbus_variant>> values;
54 s.unpack(object_name).unpack(values);
55 crow::json::wvalue j;
56 for (auto& value : values) {
Ed Tanous7b4e3da2017-06-26 11:08:40 -070057 // std::cout << "Got sensor value for " << s.get_path() << "\n";
Ed Tanous4d92cbf2017-06-22 15:41:02 -070058 boost::apply_visitor([&](auto val) { j[s.get_path()] = val; },
59 value.second);
Ed Tanouscc5a37f2017-05-11 10:27:23 -070060 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070061 for (auto conn : users) {
62 conn->send_text(crow::json::dump(j));
Ed Tanouscc5a37f2017-05-11 10:27:23 -070063 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -070064 sensor_filter->async_dispatch(on_sensor_update);
65};
Ed Tanouscc5a37f2017-05-11 10:27:23 -070066
Ed Tanous99923322017-03-03 14:21:24 -080067int main(int argc, char** argv) {
Ed Tanous4758d5b2017-06-06 15:28:13 -070068 bool enable_ssl = true;
Ed Tanous99923322017-03-03 14:21:24 -080069 std::string ssl_pem_file("server.pem");
Ed Tanous0fdddb12017-02-28 11:06:34 -080070
Ed Tanous4758d5b2017-06-06 15:28:13 -070071 if (enable_ssl) {
72 ensuressl::ensure_openssl_key_present_and_valid(ssl_pem_file);
73 }
74
Ed Tanousc9b55212017-06-12 13:25:51 -070075 crow::App<crow::TokenAuthorizationMiddleware, crow::SecurityHeadersMiddleware>
Ed Tanous7d3dba42017-04-05 13:04:39 -070076 app;
Ed Tanousb4d29f42017-03-24 16:39:25 -070077
Ed Tanous99923322017-03-03 14:21:24 -080078 crow::webassets::request_routes(app);
Ed Tanousc81ca422017-03-21 16:18:49 -070079 crow::kvm::request_routes(app);
Ed Tanous0fdddb12017-02-28 11:06:34 -080080
Ed Tanous9b65f1f2017-03-07 15:17:13 -080081 crow::logger::setLogLevel(crow::LogLevel::INFO);
Ed Tanousc4771fb2017-03-13 13:39:49 -070082 CROW_ROUTE(app, "/systeminfo")
83 ([]() {
84
85 crow::json::wvalue j;
86 j["device_id"] = 0x7B;
87 j["device_provides_sdrs"] = true;
88 j["device_revision"] = true;
89 j["device_available"] = true;
90 j["firmware_revision"] = "0.68";
91
92 j["ipmi_revision"] = "2.0";
93 j["supports_chassis_device"] = true;
94 j["supports_bridge"] = true;
95 j["supports_ipmb_event_generator"] = true;
96 j["supports_ipmb_event_receiver"] = true;
97 j["supports_fru_inventory_device"] = true;
98 j["supports_sel_device"] = true;
99 j["supports_sdr_repository_device"] = true;
100 j["supports_sensor_device"] = true;
101
102 j["firmware_aux_revision"] = "0.60.foobar";
103
104 return j;
105 });
106
Ed Tanousf3d847c2017-06-12 16:01:42 -0700107 CROW_ROUTE(app, "/sensorws")
Ed Tanousc4771fb2017-03-13 13:39:49 -0700108 .websocket()
109 .onopen([&](crow::websocket::connection& conn) {
Ed Tanous7b4e3da2017-06-26 11:08:40 -0700110 if (!system_bus) {
111 system_bus = std::make_shared<dbus::connection>(conn.get_io_service(),
112 dbus::bus::system);
113 }
114 if (!sensor_match) {
115 sensor_match = std::make_shared<dbus::match>(
116 *system_bus,
117 "type='signal',path_namespace='/xyz/openbmc_project/sensors'");
118 }
119 if (!sensor_filter) {
120 sensor_filter =
121 std::make_shared<dbus::filter>(*system_bus, [](dbus::message& m) {
122 auto member = m.get_member();
123 return member == "PropertiesChanged";
124 });
125 sensor_filter->async_dispatch(on_sensor_update);
126 }
Ed Tanousf3d847c2017-06-12 16:01:42 -0700127
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700128 users.insert(&conn);
Ed Tanousc4771fb2017-03-13 13:39:49 -0700129 })
Ed Tanous1ccd57c2017-03-21 13:15:58 -0700130 .onclose(
131 [&](crow::websocket::connection& conn, const std::string& reason) {
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700132 // TODO(ed) needs lock
133 users.erase(&conn);
Ed Tanous1ccd57c2017-03-21 13:15:58 -0700134 })
135 .onmessage([&](crow::websocket::connection& conn, const std::string& data,
136 bool is_binary) {
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700137 CROW_LOG_ERROR << "Got unexpected message from client on sensorws";
Ed Tanousc4771fb2017-03-13 13:39:49 -0700138 });
Ed Tanouscc5a37f2017-05-11 10:27:23 -0700139
140 CROW_ROUTE(app, "/sensortest")
Ed Tanousc9b55212017-06-12 13:25:51 -0700141 ([](const crow::request& req, crow::response& res) {
Ed Tanousf3d847c2017-06-12 16:01:42 -0700142 crow::json::wvalue j;
Ed Tanousf3d847c2017-06-12 16:01:42 -0700143
Ed Tanousc9b55212017-06-12 13:25:51 -0700144 dbus::connection system_bus(*req.io_service, dbus::bus::system);
Ed Tanousf3d847c2017-06-12 16:01:42 -0700145 dbus::endpoint test_daemon("org.openbmc.Sensors",
146 "/org/openbmc/sensors/tach",
147 "org.freedesktop.DBus.Introspectable");
148 dbus::message m = dbus::message::new_call(test_daemon, "Introspect");
149 system_bus.async_send(
150 m,
151 [&j, &system_bus](const boost::system::error_code ec, dbus::message r) {
152 std::string xml;
153 r.unpack(xml);
154 std::vector<std::string> dbus_objects;
155 dbus::read_dbus_xml_names(xml, dbus_objects);
Ed Tanouscc5a37f2017-05-11 10:27:23 -0700156
Ed Tanousf3d847c2017-06-12 16:01:42 -0700157 for (auto& object : dbus_objects) {
158 dbus::endpoint test_daemon("org.openbmc.Sensors",
159 "/org/openbmc/sensors/tach/" + object,
160 "org.openbmc.SensorValue");
161 dbus::message m2 = dbus::message::new_call(test_daemon, "getValue");
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700162
Ed Tanousf3d847c2017-06-12 16:01:42 -0700163 system_bus.async_send(
164 m2, [&](const boost::system::error_code ec, dbus::message r) {
165 int32_t value;
166 r.unpack(value);
167 // TODO(ed) if we ever go multithread, j needs a lock
168 j[object] = value;
169 });
170 }
Ed Tanousc9b55212017-06-12 13:25:51 -0700171
Ed Tanousf3d847c2017-06-12 16:01:42 -0700172 });
Ed Tanousc9b55212017-06-12 13:25:51 -0700173
Ed Tanouscc5a37f2017-05-11 10:27:23 -0700174 });
Ed Tanous4758d5b2017-06-06 15:28:13 -0700175
176 CROW_ROUTE(app, "/intel/firmwareupload")
177 .methods("POST"_method)([](const crow::request& req) {
178 // TODO(ed) handle errors here (file exists already and is locked, ect)
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700179 std::ofstream out(
180 "/tmp/fw_update_image",
181 std::ofstream::out | std::ofstream::binary | std::ofstream::trunc);
Ed Tanous4758d5b2017-06-06 15:28:13 -0700182 out << req.body;
183 out.close();
184
185 crow::json::wvalue j;
186 j["status"] = "Upload Successfull";
187
188 return j;
189 });
190
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700191 std::cout << "Building SSL context\n";
Ed Tanous4758d5b2017-06-06 15:28:13 -0700192
Ed Tanous4c3cbc62017-05-16 09:17:42 -0700193 int port = 18080;
Ed Tanousf0226cd2017-05-16 12:35:38 -0700194
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700195 std::cout << "Starting webserver on port " << port << "\n";
Ed Tanous4758d5b2017-06-06 15:28:13 -0700196 app.port(port);
197 if (enable_ssl) {
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700198 std::cout << "SSL Enabled\n";
Ed Tanous4758d5b2017-06-06 15:28:13 -0700199 auto ssl_context = ensuressl::get_ssl_context(ssl_pem_file);
200 app.ssl(std::move(ssl_context));
201 }
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700202 // app.concurrency(4);
Ed Tanous4758d5b2017-06-06 15:28:13 -0700203 app.run();
Ed Tanous0fdddb12017-02-28 11:06:34 -0800204}