diff options
author | Andres Oportus <andresoportus@google.com> | 2018-04-09 10:35:21 -0700 |
---|---|---|
committer | Emily Shaffer <emilyshaffer@google.com> | 2018-04-17 22:32:17 +0000 |
commit | 7ebd246403417294fc6fa1914967b6e60a92f062 (patch) | |
tree | b3963d8a8b0022428de920ece9162554d54f2e79 /ipmi_fru_info_area.cpp | |
parent | 7cbe22866c633d8e5b427503e1b1a363f45641a3 (diff) | |
download | phosphor-host-ipmid-7ebd246403417294fc6fa1914967b6e60a92f062.tar.gz phosphor-host-ipmid-7ebd246403417294fc6fa1914967b6e60a92f062.zip |
Fix FRU BuildDate DBus/IPMI exporting
When BMC exports the date into DBUS it translates/expands the 3 bytes FRU
format date into an easy to read string as in "2015-11-06 - 22:23:00", when
exporting the DBUS date back to IPMI it needs to translate back this date
into the 3 bytes FRU format, without this fix we get a build date in 1996
that is the epoch for the FRU date format. This change reconstructs the
FRU date from the easy to read string for exporting into IPMI.
Tested: Manual check that BuildDate from busctl and ipmitool match
Resolves openbmc/openbmc#3013
Change-Id: I0fd1dd8f945f18b53c14bff321c9e233fdb2d742
Signed-off-by: Andres Oportus <andresoportus@google.com>
Diffstat (limited to 'ipmi_fru_info_area.cpp')
-rw-r--r-- | ipmi_fru_info_area.cpp | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/ipmi_fru_info_area.cpp b/ipmi_fru_info_area.cpp index 386b164..1951f8c 100644 --- a/ipmi_fru_info_area.cpp +++ b/ipmi_fru_info_area.cpp @@ -1,6 +1,9 @@ #include <algorithm> #include <map> #include <numeric> + +#include <ctime> + #include "ipmi_fru_info_area.hpp" #include <phosphor-logging/elog.hpp> namespace ipmi @@ -36,6 +39,9 @@ static constexpr auto areaSizeOffset = 0x1; static constexpr uint8_t typeASCII = 0xC0; static constexpr auto maxRecordAttributeValue = 0x1F; +static constexpr auto secs_from_1970_1996 = 820454400; +static constexpr auto secs_per_min = 60; + /** * @brief Format Beginning of Individual IPMI FRU Data Section * @@ -156,13 +162,28 @@ void appendMfgDate(const PropertyMap& propMap, FruAreaData& data) auto iter = propMap.find(buildDate); if (iter != propMap.end()) { - auto& value = iter->second; - if (value.length() == manufacturingDateSize) + tm time = {}; + strptime(iter->second.c_str(), "%F - %H:%M:%S", &time); + time_t raw = mktime(&time); + + // From FRU Spec: + // "Mfg. Date / Time + // Number of minutes from 0:00 hrs 1/1/96. + // LSbyte first (little endian) + // 00_00_00h = unspecified." + if (raw > secs_from_1970_1996) { - std::copy( - value.begin(), value.end(), std::back_inserter(data)); + raw -= secs_from_1970_1996; + raw /= secs_per_min; + uint8_t fru_raw[3]; + fru_raw[0] = raw & 0xFF; + fru_raw[1] = (raw >> 8) & 0xFF; + fru_raw[2] = (raw >> 16) & 0xFF; + std::copy(fru_raw, fru_raw + 3, std::back_inserter(data)); return; } + fprintf(stderr, "MgfDate invalid date: %u secs since UNIX epoch\n", + static_cast<unsigned int>(raw)); } //Blank date data.emplace_back(0); |