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