1 #pragma once 2 3 #include "app.hpp" 4 #include "async_resp.hpp" 5 #include "http_request.hpp" 6 #include "privileges.hpp" 7 #include "query.hpp" 8 #include "registries/privilege_registry.hpp" 9 #include "routing.hpp" 10 11 #include <nlohmann/json.hpp> 12 #include <sdbusplus/asio/property.hpp> 13 14 #include <string> 15 16 namespace redfish 17 { 18 19 inline void afterGetManagerStartTime( 20 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 21 const boost::system::error_code& ec, uint64_t bmcwebResetTime) 22 { 23 if (ec) 24 { 25 // Not all servers will be running in systemd, so ignore the error. 26 return; 27 } 28 using std::chrono::steady_clock; 29 30 std::chrono::duration<steady_clock::rep, std::micro> usReset{ 31 bmcwebResetTime}; 32 steady_clock::time_point resetTime{usReset}; 33 34 steady_clock::time_point now = steady_clock::now(); 35 36 steady_clock::duration runTime = now - resetTime; 37 38 if (runTime < steady_clock::duration::zero()) 39 { 40 BMCWEB_LOG_CRITICAL << "Uptime was negative????"; 41 messages::internalError(asyncResp->res); 42 return; 43 } 44 45 // Floor to the closest millisecond 46 using Milli = std::chrono::duration<steady_clock::rep, std::milli>; 47 Milli milli = std::chrono::floor<Milli>(runTime); 48 49 using SecondsFloat = std::chrono::duration<double>; 50 SecondsFloat sec = std::chrono::duration_cast<SecondsFloat>(milli); 51 52 asyncResp->res.jsonValue["ServiceRootUptimeSeconds"] = sec.count(); 53 } 54 55 inline void managerGetServiceRootUptime( 56 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 57 { 58 sdbusplus::asio::getProperty<uint64_t>( 59 *crow::connections::systemBus, "org.freedesktop.systemd1", 60 "/org/freedesktop/systemd1/unit/bmcweb_2eservice", 61 "org.freedesktop.systemd1.Unit", "ActiveEnterTimestampMonotonic", 62 std::bind_front(afterGetManagerStartTime, asyncResp)); 63 } 64 /** 65 * handleManagerDiagnosticData supports ManagerDiagnosticData. 66 * It retrieves BMC health information from various DBus resources and returns 67 * the information through the response. 68 */ 69 inline void handleManagerDiagnosticDataGet( 70 crow::App& app, const crow::Request& req, 71 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 72 { 73 if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 74 { 75 return; 76 } 77 asyncResp->res.jsonValue["@odata.type"] = 78 "#ManagerDiagnosticData.v1_2_0.ManagerDiagnosticData"; 79 asyncResp->res.jsonValue["@odata.id"] = 80 "/redfish/v1/Managers/bmc/ManagerDiagnosticData"; 81 asyncResp->res.jsonValue["Id"] = "ManagerDiagnosticData"; 82 asyncResp->res.jsonValue["Name"] = "Manager Diagnostic Data"; 83 84 managerGetServiceRootUptime(asyncResp); 85 } 86 87 inline void requestRoutesManagerDiagnosticData(App& app) 88 { 89 BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/ManagerDiagnosticData") 90 .privileges(redfish::privileges::getManagerDiagnosticData) 91 .methods(boost::beast::http::verb::get)( 92 std::bind_front(handleManagerDiagnosticDataGet, std::ref(app))); 93 } 94 95 } // namespace redfish 96