xref: /openbmc/bmcweb/features/redfish/lib/manager_diagnostic_data.hpp (revision 62598e31d0988d589506d5091bd38f72d61faf5e)
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>
125ace29d2SEd Tanous #include <sdbusplus/asio/property.hpp>
13a51fc2d2SSui Chen 
14a51fc2d2SSui Chen #include <string>
15a51fc2d2SSui Chen 
16a51fc2d2SSui Chen namespace redfish
17a51fc2d2SSui Chen {
18a51fc2d2SSui Chen 
19ac106bf6SEd Tanous inline void afterGetManagerStartTime(
20ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
21ac106bf6SEd Tanous     const boost::system::error_code& ec, uint64_t bmcwebResetTime)
225ace29d2SEd Tanous {
235ace29d2SEd Tanous     if (ec)
245ace29d2SEd Tanous     {
255ace29d2SEd Tanous         // Not all servers will be running in systemd, so ignore the error.
265ace29d2SEd Tanous         return;
275ace29d2SEd Tanous     }
285ace29d2SEd Tanous     using std::chrono::steady_clock;
295ace29d2SEd Tanous 
305ace29d2SEd Tanous     std::chrono::duration<steady_clock::rep, std::micro> usReset{
315ace29d2SEd Tanous         bmcwebResetTime};
325ace29d2SEd Tanous     steady_clock::time_point resetTime{usReset};
335ace29d2SEd Tanous 
345ace29d2SEd Tanous     steady_clock::time_point now = steady_clock::now();
355ace29d2SEd Tanous 
365ace29d2SEd Tanous     steady_clock::duration runTime = now - resetTime;
375ace29d2SEd Tanous 
385ace29d2SEd Tanous     if (runTime < steady_clock::duration::zero())
395ace29d2SEd Tanous     {
40*62598e31SEd Tanous         BMCWEB_LOG_CRITICAL("Uptime was negative????");
41ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
425ace29d2SEd Tanous         return;
435ace29d2SEd Tanous     }
445ace29d2SEd Tanous 
455ace29d2SEd Tanous     // Floor to the closest millisecond
465ace29d2SEd Tanous     using Milli = std::chrono::duration<steady_clock::rep, std::milli>;
475ace29d2SEd Tanous     Milli milli = std::chrono::floor<Milli>(runTime);
485ace29d2SEd Tanous 
495ace29d2SEd Tanous     using SecondsFloat = std::chrono::duration<double>;
505ace29d2SEd Tanous     SecondsFloat sec = std::chrono::duration_cast<SecondsFloat>(milli);
515ace29d2SEd Tanous 
52ac106bf6SEd Tanous     asyncResp->res.jsonValue["ServiceRootUptimeSeconds"] = sec.count();
535ace29d2SEd Tanous }
545ace29d2SEd Tanous 
55ac106bf6SEd Tanous inline void managerGetServiceRootUptime(
56ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
575ace29d2SEd Tanous {
585ace29d2SEd Tanous     sdbusplus::asio::getProperty<uint64_t>(
595ace29d2SEd Tanous         *crow::connections::systemBus, "org.freedesktop.systemd1",
605ace29d2SEd Tanous         "/org/freedesktop/systemd1/unit/bmcweb_2eservice",
615ace29d2SEd Tanous         "org.freedesktop.systemd1.Unit", "ActiveEnterTimestampMonotonic",
62ac106bf6SEd Tanous         std::bind_front(afterGetManagerStartTime, asyncResp));
635ace29d2SEd Tanous }
64a51fc2d2SSui Chen /**
65a51fc2d2SSui Chen  * handleManagerDiagnosticData supports ManagerDiagnosticData.
66a51fc2d2SSui Chen  * It retrieves BMC health information from various DBus resources and returns
67a51fc2d2SSui Chen  * the information through the response.
68a51fc2d2SSui Chen  */
69a51fc2d2SSui Chen inline void handleManagerDiagnosticDataGet(
70a51fc2d2SSui Chen     crow::App& app, const crow::Request& req,
71a51fc2d2SSui Chen     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
72a51fc2d2SSui Chen {
73a51fc2d2SSui Chen     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
74a51fc2d2SSui Chen     {
75a51fc2d2SSui Chen         return;
76a51fc2d2SSui Chen     }
77a51fc2d2SSui Chen     asyncResp->res.jsonValue["@odata.type"] =
785ace29d2SEd Tanous         "#ManagerDiagnosticData.v1_2_0.ManagerDiagnosticData";
79a51fc2d2SSui Chen     asyncResp->res.jsonValue["@odata.id"] =
80a51fc2d2SSui Chen         "/redfish/v1/Managers/bmc/ManagerDiagnosticData";
81a51fc2d2SSui Chen     asyncResp->res.jsonValue["Id"] = "ManagerDiagnosticData";
82a51fc2d2SSui Chen     asyncResp->res.jsonValue["Name"] = "Manager Diagnostic Data";
835ace29d2SEd Tanous 
845ace29d2SEd Tanous     managerGetServiceRootUptime(asyncResp);
85a51fc2d2SSui Chen }
86a51fc2d2SSui Chen 
87a51fc2d2SSui Chen inline void requestRoutesManagerDiagnosticData(App& app)
88a51fc2d2SSui Chen {
89a51fc2d2SSui Chen     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/ManagerDiagnosticData")
90a51fc2d2SSui Chen         .privileges(redfish::privileges::getManagerDiagnosticData)
91a51fc2d2SSui Chen         .methods(boost::beast::http::verb::get)(
92a51fc2d2SSui Chen             std::bind_front(handleManagerDiagnosticDataGet, std::ref(app)));
93a51fc2d2SSui Chen }
94a51fc2d2SSui Chen 
95a51fc2d2SSui Chen } // namespace redfish
96