blob: 11c82518a64d9b37884a297ae21e2ea40be1ffed [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>
Deepak Kodihallic2feac92019-04-30 17:21:19 +053010#include <phosphor-logging/log.hpp>
Sampa Misra032bd502019-03-06 05:03:22 -060011#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
vkaverapa6575b82019-04-03 05:33:52 -050050Response getDateTime(const pldm_msg* request)
Sampa Misra032bd502019-03-06 05:03:22 -060051{
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";
vkaverapa6575b82019-04-03 05:33:52 -050061 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_DATE_TIME_RESP_BYTES, 0);
62 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Sampa Misra032bd502019-03-06 05:03:22 -060063 std::variant<EpochTimeUS> value;
64
65 auto bus = sdbusplus::bus::new_default();
66 try
67 {
68 auto service = getService(bus, bmcTimePath, timeInterface);
69
70 auto method = bus.new_method_call(service.c_str(), bmcTimePath,
71 dbusProperties, "Get");
72 method.append(timeInterface, "Elapsed");
73
74 auto reply = bus.call(method);
75 reply.read(value);
76 }
77
78 catch (std::exception& e)
79 {
80 log<level::ERR>("Error getting time", entry("PATH=%s", bmcTimePath),
81 entry("TIME INTERACE=%s", timeInterface));
82
83 encode_get_date_time_resp(0, PLDM_ERROR, seconds, minutes, hours, day,
vkaverapa6575b82019-04-03 05:33:52 -050084 month, year, responsePtr);
85 return response;
Sampa Misra032bd502019-03-06 05:03:22 -060086 }
87
88 uint64_t timeUsec = std::get<EpochTimeUS>(value);
89
90 uint64_t timeSec = std::chrono::duration_cast<std::chrono::seconds>(
91 std::chrono::microseconds(timeUsec))
92 .count();
93
94 utils::epochToBCDTime(timeSec, seconds, minutes, hours, day, month, year);
95
96 encode_get_date_time_resp(0, PLDM_SUCCESS, seconds, minutes, hours, day,
vkaverapa6575b82019-04-03 05:33:52 -050097 month, year, responsePtr);
98 return response;
Sampa Misra032bd502019-03-06 05:03:22 -060099}
100
101} // namespace responder
102} // namespace pldm