diff options
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); |