blob: eab83dc98f41ded071b58ef6740f4264808433bf [file] [log] [blame]
Sampa Misra032bd502019-03-06 05:03:22 -06001#include "bios.hpp"
2
3#include "libpldmresponder/utils.hpp"
Jinu Joy Thomasf666db12019-05-29 05:22:31 -05004#include "registration.hpp"
Sampa Misra032bd502019-03-06 05:03:22 -06005#include "xyz/openbmc_project/Common/error.hpp"
6
7#include <array>
8#include <chrono>
9#include <ctime>
10#include <iostream>
Deepak Kodihallic2feac92019-04-30 17:21:19 +053011#include <phosphor-logging/log.hpp>
Sampa Misra032bd502019-03-06 05:03:22 -060012#include <stdexcept>
13#include <string>
14#include <variant>
15#include <vector>
16
17namespace pldm
18{
19
20using namespace phosphor::logging;
21
22using EpochTimeUS = uint64_t;
23
24constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
25
26namespace responder
27{
28
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050029namespace bios
30{
31
32void registerHandlers()
33{
34 registerHandler(PLDM_BIOS, PLDM_GET_DATE_TIME, std::move(getDateTime));
35}
36
37} // namespace bios
38
Sampa Misra032bd502019-03-06 05:03:22 -060039namespace utils
40{
41
42void epochToBCDTime(uint64_t timeSec, uint8_t& seconds, uint8_t& minutes,
43 uint8_t& hours, uint8_t& day, uint8_t& month,
44 uint16_t& year)
45{
46 auto t = time_t(timeSec);
47 auto time = localtime(&t);
48
49 seconds = decimalToBcd(time->tm_sec);
50 minutes = decimalToBcd(time->tm_min);
51 hours = decimalToBcd(time->tm_hour);
52 day = decimalToBcd(time->tm_mday);
53 month =
54 decimalToBcd(time->tm_mon + 1); // The number of months in the range
55 // 0 to 11.PLDM expects range 1 to 12
56 year = decimalToBcd(time->tm_year + 1900); // The number of years since 1900
57}
58
59} // namespace utils
60
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050061Response getDateTime(const pldm_msg* request, size_t payloadLength)
Sampa Misra032bd502019-03-06 05:03:22 -060062{
63 uint8_t seconds = 0;
64 uint8_t minutes = 0;
65 uint8_t hours = 0;
66 uint8_t day = 0;
67 uint8_t month = 0;
68 uint16_t year = 0;
69
70 constexpr auto timeInterface = "xyz.openbmc_project.Time.EpochTime";
71 constexpr auto bmcTimePath = "/xyz/openbmc_project/time/bmc";
vkaverapa6575b82019-04-03 05:33:52 -050072 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_DATE_TIME_RESP_BYTES, 0);
73 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Sampa Misra032bd502019-03-06 05:03:22 -060074 std::variant<EpochTimeUS> value;
75
76 auto bus = sdbusplus::bus::new_default();
77 try
78 {
79 auto service = getService(bus, bmcTimePath, timeInterface);
80
81 auto method = bus.new_method_call(service.c_str(), bmcTimePath,
82 dbusProperties, "Get");
83 method.append(timeInterface, "Elapsed");
84
85 auto reply = bus.call(method);
86 reply.read(value);
87 }
88
89 catch (std::exception& e)
90 {
91 log<level::ERR>("Error getting time", entry("PATH=%s", bmcTimePath),
92 entry("TIME INTERACE=%s", timeInterface));
93
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +053094 encode_get_date_time_resp(request->hdr.instance_id, PLDM_ERROR, seconds,
95 minutes, hours, day, month, year,
96 responsePtr);
vkaverapa6575b82019-04-03 05:33:52 -050097 return response;
Sampa Misra032bd502019-03-06 05:03:22 -060098 }
99
100 uint64_t timeUsec = std::get<EpochTimeUS>(value);
101
102 uint64_t timeSec = std::chrono::duration_cast<std::chrono::seconds>(
103 std::chrono::microseconds(timeUsec))
104 .count();
105
106 utils::epochToBCDTime(timeSec, seconds, minutes, hours, day, month, year);
107
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530108 encode_get_date_time_resp(request->hdr.instance_id, PLDM_SUCCESS, seconds,
109 minutes, hours, day, month, year, responsePtr);
vkaverapa6575b82019-04-03 05:33:52 -0500110 return response;
Sampa Misra032bd502019-03-06 05:03:22 -0600111}
112
113} // namespace responder
114} // namespace pldm