1 #include "crow/app.h" 2 #include "crow/ci_map.h" 3 #include "crow/common.h" 4 #include "crow/dumb_timer_queue.h" 5 #include "crow/http_connection.h" 6 #include "crow/http_parser_merged.h" 7 #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" 16 #include "crow/query_string.h" 17 #include "crow/routing.h" 18 #include "crow/settings.h" 19 #include "crow/socket_adaptors.h" 20 #include "crow/utility.h" 21 #include "crow/websocket.h" 22 23 #include "security_headers_middleware.hpp" 24 #include "ssl_key_handler.hpp" 25 #include "token_authorization_middleware.hpp" 26 #include "web_kvm.hpp" 27 #include "webassets.hpp" 28 29 #include <boost/asio.hpp> 30 #include <boost/endian/arithmetic.hpp> 31 32 #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> 38 39 #include <iostream> 40 #include <memory> 41 #include <string> 42 #include <unordered_set> 43 44 static std::shared_ptr<dbus::connection> system_bus; 45 static std::shared_ptr<dbus::match> sensor_match; 46 static std::shared_ptr<dbus::filter> sensor_filter; 47 static std::shared_ptr<dbus::filter> sensor_callback; 48 49 std::unordered_set<crow::websocket::connection*> users; 50 51 void 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) { 57 // std::cout << "Got sensor value for " << s.get_path() << "\n"; 58 boost::apply_visitor([&](auto val) { j[s.get_path()] = val; }, 59 value.second); 60 } 61 for (auto conn : users) { 62 conn->send_text(crow::json::dump(j)); 63 } 64 sensor_filter->async_dispatch(on_sensor_update); 65 }; 66 67 int main(int argc, char** argv) { 68 bool enable_ssl = true; 69 std::string ssl_pem_file("server.pem"); 70 71 if (enable_ssl) { 72 ensuressl::ensure_openssl_key_present_and_valid(ssl_pem_file); 73 } 74 75 crow::App<crow::TokenAuthorizationMiddleware, crow::SecurityHeadersMiddleware> 76 app; 77 78 crow::webassets::request_routes(app); 79 crow::kvm::request_routes(app); 80 81 crow::logger::setLogLevel(crow::LogLevel::INFO); 82 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 107 CROW_ROUTE(app, "/sensorws") 108 .websocket() 109 .onopen([&](crow::websocket::connection& conn) { 110 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 } 127 128 users.insert(&conn); 129 }) 130 .onclose( 131 [&](crow::websocket::connection& conn, const std::string& reason) { 132 // TODO(ed) needs lock 133 users.erase(&conn); 134 }) 135 .onmessage([&](crow::websocket::connection& conn, const std::string& data, 136 bool is_binary) { 137 CROW_LOG_ERROR << "Got unexpected message from client on sensorws"; 138 }); 139 140 CROW_ROUTE(app, "/sensortest") 141 ([](const crow::request& req, crow::response& res) { 142 crow::json::wvalue j; 143 144 dbus::connection system_bus(*req.io_service, dbus::bus::system); 145 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); 156 157 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"); 162 163 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 } 171 172 }); 173 174 }); 175 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) 179 std::ofstream out( 180 "/tmp/fw_update_image", 181 std::ofstream::out | std::ofstream::binary | std::ofstream::trunc); 182 out << req.body; 183 out.close(); 184 185 crow::json::wvalue j; 186 j["status"] = "Upload Successfull"; 187 188 return j; 189 }); 190 191 std::cout << "Building SSL context\n"; 192 193 int port = 18080; 194 195 std::cout << "Starting webserver on port " << port << "\n"; 196 app.port(port); 197 if (enable_ssl) { 198 std::cout << "SSL Enabled\n"; 199 auto ssl_context = ensuressl::get_ssl_context(ssl_pem_file); 200 app.ssl(std::move(ssl_context)); 201 } 202 // app.concurrency(4); 203 app.run(); 204 } 205