summaryrefslogtreecommitdiffstats
path: root/ipmi_fru_info_area.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ipmi_fru_info_area.cpp')
-rw-r--r--ipmi_fru_info_area.cpp29
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);
OpenPOWER on IntegriCloud