Fix decoding of MB

The BuildDate property value is incorrect when testing via ipmitool
command and should be parsed as MB keyword instead of RAW.

Testd: BuildDate property value is correct via dbus, ipmitool commands
and unit test.

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I6dd14d82df3b7f46b1717960a0a97df4a4c7e30e
diff --git a/impl.cpp b/impl.cpp
index ba85346..765b1ac 100644
--- a/impl.cpp
+++ b/impl.cpp
@@ -29,6 +29,14 @@
 static constexpr auto UUID_TIME_HIGH_END = 18;
 static constexpr auto UUID_CLK_SEQ_END = 23;
 
+static constexpr auto MB_RESULT_LEN = 19;
+static constexpr auto MB_LEN_BYTES = 8;
+static constexpr auto MB_YEAR_END = 4;
+static constexpr auto MB_MONTH_END = 7;
+static constexpr auto MB_DAY_END = 10;
+static constexpr auto MB_HOUR_END = 13;
+static constexpr auto MB_MIN_END = 16;
+
 static const std::unordered_map<std::string, internal::KeywordInfo>
     supportedKeywords = {
         {"DR", std::make_tuple(record::Keyword::DR, keyword::Encoding::ASCII)},
@@ -38,7 +46,7 @@
         {"HW", std::make_tuple(record::Keyword::HW, keyword::Encoding::RAW)},
         {"B1", std::make_tuple(record::Keyword::B1, keyword::Encoding::B1)},
         {"VN", std::make_tuple(record::Keyword::VN, keyword::Encoding::ASCII)},
-        {"MB", std::make_tuple(record::Keyword::MB, keyword::Encoding::RAW)},
+        {"MB", std::make_tuple(record::Keyword::MB, keyword::Encoding::MB)},
         {"MM", std::make_tuple(record::Keyword::MM, keyword::Encoding::ASCII)},
         {"UD", std::make_tuple(record::Keyword::UD, keyword::Encoding::UD)},
         {"VP", std::make_tuple(record::Keyword::VP, keyword::Encoding::ASCII)},
@@ -221,6 +229,31 @@
             return result;
         }
 
+        case keyword::Encoding::MB:
+        {
+            // MB is BuildDate, represent as
+            // 1997-01-01-08:30:00
+            // <year>-<month>-<day>-<hour>:<min>:<sec>
+            auto stop = std::next(iterator, MB_LEN_BYTES);
+            std::string data(iterator, stop);
+            std::string result;
+            result.reserve(MB_LEN_BYTES);
+            auto strItr = data.cbegin();
+            std::advance(strItr, 1);
+            std::for_each(strItr, data.cend(), [&result](size_t c) {
+                result += toHex(c >> 4);
+                result += toHex(c & 0x0F);
+            });
+
+            result.insert(MB_YEAR_END, 1, '-');
+            result.insert(MB_MONTH_END, 1, '-');
+            result.insert(MB_DAY_END, 1, '-');
+            result.insert(MB_HOUR_END, 1, ':');
+            result.insert(MB_MIN_END, 1, ':');
+
+            return result;
+        }
+
         case keyword::Encoding::B1:
         {
             // B1 is MAC address, represent as AA:BB:CC:DD:EE:FF