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