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