blob: dfd07b87c8b57f48fd99965e1ee4dbbdd51d39af [file] [log] [blame]
Sampa Misra032bd502019-03-06 05:03:22 -06001#include "bios.hpp"
2
3#include "libpldmresponder/utils.hpp"
4#include "xyz/openbmc_project/Common/error.hpp"
5
6#include <array>
7#include <chrono>
8#include <ctime>
9#include <iostream>
10#include <phosphor-logging/elog-errors.hpp>
11#include <stdexcept>
12#include <string>
13#include <variant>
14#include <vector>
15
16namespace pldm
17{
18
19using namespace phosphor::logging;
20
21using EpochTimeUS = uint64_t;
22
23constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
24
25namespace responder
26{
27
28namespace utils
29{
30
31void epochToBCDTime(uint64_t timeSec, uint8_t& seconds, uint8_t& minutes,
32 uint8_t& hours, uint8_t& day, uint8_t& month,
33 uint16_t& year)
34{
35 auto t = time_t(timeSec);
36 auto time = localtime(&t);
37
38 seconds = decimalToBcd(time->tm_sec);
39 minutes = decimalToBcd(time->tm_min);
40 hours = decimalToBcd(time->tm_hour);
41 day = decimalToBcd(time->tm_mday);
42 month =
43 decimalToBcd(time->tm_mon + 1); // The number of months in the range
44 // 0 to 11.PLDM expects range 1 to 12
45 year = decimalToBcd(time->tm_year + 1900); // The number of years since 1900
46}
47
48} // namespace utils
49
50void getDateTime(const pldm_msg_payload* request, pldm_msg* response)
51{
52 uint8_t seconds = 0;
53 uint8_t minutes = 0;
54 uint8_t hours = 0;
55 uint8_t day = 0;
56 uint8_t month = 0;
57 uint16_t year = 0;
58
59 constexpr auto timeInterface = "xyz.openbmc_project.Time.EpochTime";
60 constexpr auto bmcTimePath = "/xyz/openbmc_project/time/bmc";
61 std::variant<EpochTimeUS> value;
62
63 auto bus = sdbusplus::bus::new_default();
64 try
65 {
66 auto service = getService(bus, bmcTimePath, timeInterface);
67
68 auto method = bus.new_method_call(service.c_str(), bmcTimePath,
69 dbusProperties, "Get");
70 method.append(timeInterface, "Elapsed");
71
72 auto reply = bus.call(method);
73 reply.read(value);
74 }
75
76 catch (std::exception& e)
77 {
78 log<level::ERR>("Error getting time", entry("PATH=%s", bmcTimePath),
79 entry("TIME INTERACE=%s", timeInterface));
80
81 encode_get_date_time_resp(0, PLDM_ERROR, seconds, minutes, hours, day,
82 month, year, response);
83 return;
84 }
85
86 uint64_t timeUsec = std::get<EpochTimeUS>(value);
87
88 uint64_t timeSec = std::chrono::duration_cast<std::chrono::seconds>(
89 std::chrono::microseconds(timeUsec))
90 .count();
91
92 utils::epochToBCDTime(timeSec, seconds, minutes, hours, day, month, year);
93
94 encode_get_date_time_resp(0, PLDM_SUCCESS, seconds, minutes, hours, day,
95 month, year, response);
96}
97
98} // namespace responder
99} // namespace pldm