diff --git a/include/FruUtils.hpp b/include/FruUtils.hpp
index 5e96696..45fea07 100644
--- a/include/FruUtils.hpp
+++ b/include/FruUtils.hpp
@@ -16,18 +16,36 @@
 /// \file FruUtils.hpp
 
 #pragma once
+#include <boost/container/flat_map.hpp>
 
 #include <cstdint>
 #include <functional>
+#include <regex>
 #include <string>
+#include <utility>
 #include <vector>
-
 extern "C"
 {
 // Include for I2C_SMBUS_BLOCK_MAX
 #include <linux/i2c.h>
 }
 
+constexpr size_t fruBlockSize = 8;
+
+enum class DecodeState
+{
+    ok,
+    end,
+    err,
+};
+
+enum class resCodes
+{
+    resOK,
+    resWarn,
+    resErr
+};
+
 enum class fruAreas
 {
     fruAreaInternal = 0,
@@ -36,19 +54,78 @@
     fruAreaProduct,
     fruAreaMultirecord
 };
+
+const std::vector<std::string> FRU_AREA_NAMES = {"INTERNAL", "CHASSIS", "BOARD",
+                                                 "PRODUCT", "MULTIRECORD"};
+const std::regex NON_ASCII_REGEX("[^\x01-\x7f]");
+
+const std::vector<std::string> CHASSIS_FRU_AREAS = {"PART_NUMBER",
+                                                    "SERIAL_NUMBER"};
+
+const std::vector<std::string> BOARD_FRU_AREAS = {
+    "MANUFACTURER", "PRODUCT_NAME", "SERIAL_NUMBER", "PART_NUMBER",
+    "FRU_VERSION_ID"};
+
+const std::vector<std::string> PRODUCT_FRU_AREAS = {
+    "MANUFACTURER",  "PRODUCT_NAME", "PART_NUMBER",   "VERSION",
+    "SERIAL_NUMBER", "ASSET_TAG",    "FRU_VERSION_ID"};
+
+const std::string FRU_CUSTOM_FIELD_NAME = "INFO_AM";
+
 inline fruAreas operator++(fruAreas& x)
 {
     return x = static_cast<fruAreas>(std::underlying_type<fruAreas>::type(x) +
                                      1);
 }
 
-inline constexpr size_t fruBlockSize =
-    8; // FRU areas are measured in 8-byte blocks
-
 using ReadBlockFunc =
     std::function<int64_t(int flag, int file, uint16_t address, uint16_t offset,
                           uint8_t length, uint8_t* outBuf)>;
 
+inline const std::string& getFruAreaName(fruAreas area)
+{
+    return FRU_AREA_NAMES[static_cast<unsigned int>(area)];
+}
+
+const std::tm intelEpoch(void);
+
+char sixBitToChar(uint8_t val);
+
+/* 0xd - 0xf are reserved values, but not fatal; use a placeholder char. */
+const char bcdHighChars[] = {
+    ' ', '-', '.', 'X', 'X', 'X',
+};
+
+char bcdPlusToChar(uint8_t val);
+
+bool verifyOffset(const std::vector<uint8_t>& fruBytes, fruAreas currentArea,
+                  uint8_t len);
+
+std::pair<DecodeState, std::string>
+    decodeFRUData(std::vector<uint8_t>::const_iterator& iter,
+                  const std::vector<uint8_t>::const_iterator& end,
+                  bool isLangEng);
+
+bool checkLangEng(uint8_t lang);
+
+resCodes
+    formatFRU(const std::vector<uint8_t>& fruBytes,
+              boost::container::flat_map<std::string, std::string>& result);
+
+std::vector<uint8_t>& getFRUInfo(const uint8_t& bus, const uint8_t& address);
+
+uint8_t calculateChecksum(std::vector<uint8_t>::const_iterator iter,
+                          std::vector<uint8_t>::const_iterator end);
+
+uint8_t calculateChecksum(std::vector<uint8_t>& fruAreaData);
+
+unsigned int updateFRUAreaLenAndChecksum(std::vector<uint8_t>& fruData,
+                                         size_t fruAreaStart,
+                                         size_t fruAreaEndOfFieldsOffset,
+                                         size_t fruAreaEndOffset);
+
+ssize_t getFieldLength(uint8_t fruFieldTypeLenValue);
+
 /// \brief Read and validate FRU contents.
 /// \param flag the flag required for raw i2c
 /// \param file the open file handle
@@ -69,16 +146,3 @@
 /// \param area - the area
 /// \return the field offset
 unsigned int getHeaderAreaFieldOffset(fruAreas area);
-
-/// \brief Get name of FRU areas
-/// \param area - the area
-/// \return the name of Fru areas
-std::string getFruAreaName(fruAreas area);
-
-/// \brief verifies overlapping of other offsets against given offset area
-/// \param fruBytes Start of Fru data
-/// \param currentArea Index of current area offset to be compared
-/// \param len Length of current area space
-/// \return true on success
-bool verifyOffset(const std::vector<uint8_t>& fruBytes, fruAreas currentArea,
-                  uint8_t len);
diff --git a/src/FruDevice.cpp b/src/FruDevice.cpp
index 0b2f9fa..78d4635 100644
--- a/src/FruDevice.cpp
+++ b/src/FruDevice.cpp
@@ -70,16 +70,6 @@
 
 const static constexpr char* I2C_DEV_LOCATION = "/dev";
 
-enum class resCodes
-{
-    resOK,
-    resWarn,
-    resErr
-};
-
-static const std::vector<std::string> FRU_AREA_NAMES = {
-    "INTERNAL", "CHASSIS", "BOARD", "PRODUCT", "MULTIRECORD"};
-const static std::regex NON_ASCII_REGEX("[^\x01-\x7f]");
 using DeviceMap = boost::container::flat_map<int, std::vector<uint8_t>>;
 using BusMap = boost::container::flat_map<int, std::shared_ptr<DeviceMap>>;
 
@@ -100,19 +90,6 @@
 auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
 auto objServer = sdbusplus::asio::object_server(systemBus);
 
-static const std::vector<std::string> CHASSIS_FRU_AREAS = {"PART_NUMBER",
-                                                           "SERIAL_NUMBER"};
-
-static const std::vector<std::string> BOARD_FRU_AREAS = {
-    "MANUFACTURER", "PRODUCT_NAME", "SERIAL_NUMBER", "PART_NUMBER",
-    "FRU_VERSION_ID"};
-
-static const std::vector<std::string> PRODUCT_FRU_AREAS = {
-    "MANUFACTURER",  "PRODUCT_NAME", "PART_NUMBER",   "VERSION",
-    "SERIAL_NUMBER", "ASSET_TAG",    "FRU_VERSION_ID"};
-
-static const std::string FRU_CUSTOM_FIELD_NAME = "INFO_AM";
-
 uint8_t calculateChecksum(std::vector<uint8_t>::const_iterator iter,
                           std::vector<uint8_t>::const_iterator end);
 bool updateFRUProperty(
@@ -643,368 +620,6 @@
     std::function<void(void)> _callback;
 };
 
-static const std::tm intelEpoch(void)
-{
-    std::tm val = {};
-    val.tm_year = 1996 - 1900;
-    return val;
-}
-
-static char sixBitToChar(uint8_t val)
-{
-    return static_cast<char>((val & 0x3f) + ' ');
-}
-
-/* 0xd - 0xf are reserved values, but not fatal; use a placeholder char. */
-static const char bcdHighChars[] = {
-    ' ', '-', '.', 'X', 'X', 'X',
-};
-
-static char bcdPlusToChar(uint8_t val)
-{
-    val &= 0xf;
-    return (val < 10) ? static_cast<char>(val + '0') : bcdHighChars[val - 10];
-}
-
-enum class DecodeState
-{
-    ok,
-    end,
-    err,
-};
-
-enum FRUDataEncoding
-{
-    binary = 0x0,
-    bcdPlus = 0x1,
-    sixBitASCII = 0x2,
-    languageDependent = 0x3,
-};
-
-/* Decode FRU data into a std::string, given an input iterator and end. If the
- * state returned is fruDataOk, then the resulting string is the decoded FRU
- * data. The input iterator is advanced past the data consumed.
- *
- * On fruDataErr, we have lost synchronisation with the length bytes, so the
- * iterator is no longer usable.
- */
-static std::pair<DecodeState, std::string>
-    decodeFRUData(std::vector<uint8_t>::const_iterator& iter,
-                  const std::vector<uint8_t>::const_iterator& end,
-                  bool isLangEng)
-{
-    std::string value;
-    unsigned int i;
-
-    /* we need at least one byte to decode the type/len header */
-    if (iter == end)
-    {
-        std::cerr << "Truncated FRU data\n";
-        return make_pair(DecodeState::err, value);
-    }
-
-    uint8_t c = *(iter++);
-
-    /* 0xc1 is the end marker */
-    if (c == 0xc1)
-    {
-        return make_pair(DecodeState::end, value);
-    }
-
-    /* decode type/len byte */
-    uint8_t type = static_cast<uint8_t>(c >> 6);
-    uint8_t len = static_cast<uint8_t>(c & 0x3f);
-
-    /* we should have at least len bytes of data available overall */
-    if (iter + len > end)
-    {
-        std::cerr << "FRU data field extends past end of FRU area data\n";
-        return make_pair(DecodeState::err, value);
-    }
-
-    switch (type)
-    {
-        case FRUDataEncoding::binary:
-        {
-            std::stringstream ss;
-            ss << std::hex << std::setfill('0');
-            for (i = 0; i < len; i++, iter++)
-            {
-                uint8_t val = static_cast<uint8_t>(*iter);
-                ss << std::setw(2) << static_cast<int>(val);
-            }
-            value = ss.str();
-            break;
-        }
-        case FRUDataEncoding::languageDependent:
-            /* For language-code dependent encodings, assume 8-bit ASCII */
-            value = std::string(iter, iter + len);
-            iter += len;
-
-            /* English text is encoded in 8-bit ASCII + Latin 1. All other
-             * languages are required to use 2-byte unicode. FruDevice does not
-             * handle unicode.
-             */
-            if (!isLangEng)
-            {
-                std::cerr << "Error: Non english string is not supported \n";
-                return make_pair(DecodeState::err, value);
-            }
-
-            break;
-
-        case FRUDataEncoding::bcdPlus:
-            value = std::string();
-            for (i = 0; i < len; i++, iter++)
-            {
-                uint8_t val = *iter;
-                value.push_back(bcdPlusToChar(val >> 4));
-                value.push_back(bcdPlusToChar(val & 0xf));
-            }
-            break;
-
-        case FRUDataEncoding::sixBitASCII:
-        {
-            unsigned int accum = 0;
-            unsigned int accumBitLen = 0;
-            value = std::string();
-            for (i = 0; i < len; i++, iter++)
-            {
-                accum |= *iter << accumBitLen;
-                accumBitLen += 8;
-                while (accumBitLen >= 6)
-                {
-                    value.push_back(sixBitToChar(accum & 0x3f));
-                    accum >>= 6;
-                    accumBitLen -= 6;
-                }
-            }
-        }
-        break;
-    }
-
-    return make_pair(DecodeState::ok, value);
-}
-
-static bool checkLangEng(uint8_t lang)
-{
-    // If Lang is not English then the encoding is defined as 2-byte UNICODE,
-    // but we don't support that.
-    if (lang && lang != 25)
-    {
-        std::cerr << "Warning: languages other than English is not "
-                     "supported\n";
-        // Return language flag as non english
-        return false;
-    }
-    else
-    {
-        return true;
-    }
-}
-
-resCodes formatFRU(const std::vector<uint8_t>& fruBytes,
-                   boost::container::flat_map<std::string, std::string>& result)
-{
-    resCodes ret = resCodes::resOK;
-    if (fruBytes.size() <= fruBlockSize)
-    {
-        std::cerr << "Error: trying to parse empty FRU \n";
-        return resCodes::resErr;
-    }
-    result["Common_Format_Version"] =
-        std::to_string(static_cast<int>(*fruBytes.begin()));
-
-    const std::vector<std::string>* fruAreaFieldNames;
-
-    // Don't parse Internal and Multirecord areas
-    for (fruAreas area = fruAreas::fruAreaChassis;
-         area <= fruAreas::fruAreaProduct; ++area)
-    {
-
-        size_t offset = *(fruBytes.begin() + getHeaderAreaFieldOffset(area));
-        if (offset == 0)
-        {
-            continue;
-        }
-        offset *= fruBlockSize;
-        std::vector<uint8_t>::const_iterator fruBytesIter =
-            fruBytes.begin() + offset;
-        if (fruBytesIter + fruBlockSize >= fruBytes.end())
-        {
-            std::cerr << "Not enough data to parse \n";
-            return resCodes::resErr;
-        }
-        // check for format version 1
-        if (*fruBytesIter != 0x01)
-        {
-            std::cerr << "Unexpected version " << *fruBytesIter << "\n";
-            return resCodes::resErr;
-        }
-        ++fruBytesIter;
-
-        /* Verify other area offset for overlap with current area by passing
-         * length of current area offset pointed by *fruBytesIter
-         */
-        if (!verifyOffset(fruBytes, area, *fruBytesIter))
-        {
-            return resCodes::resErr;
-        }
-
-        uint8_t fruAreaSize = *fruBytesIter * fruBlockSize;
-        std::vector<uint8_t>::const_iterator fruBytesIterEndArea =
-            fruBytes.begin() + offset + fruAreaSize - 1;
-        ++fruBytesIter;
-
-        uint8_t fruComputedChecksum =
-            calculateChecksum(fruBytes.begin() + offset, fruBytesIterEndArea);
-        if (fruComputedChecksum != *fruBytesIterEndArea)
-        {
-            std::stringstream ss;
-            ss << std::hex << std::setfill('0');
-            ss << "Checksum error in FRU area " << getFruAreaName(area) << "\n";
-            ss << "\tComputed checksum: 0x" << std::setw(2)
-               << static_cast<int>(fruComputedChecksum) << "\n";
-            ss << "\tThe read checksum: 0x" << std::setw(2)
-               << static_cast<int>(*fruBytesIterEndArea) << "\n";
-            std::cerr << ss.str();
-            ret = resCodes::resWarn;
-        }
-
-        /* Set default language flag to true as Chassis Fru area are always
-         * encoded in English defined in Section 10 of Fru specification
-         */
-        bool isLangEng = true;
-        switch (area)
-        {
-            case fruAreas::fruAreaChassis:
-            {
-                result["CHASSIS_TYPE"] =
-                    std::to_string(static_cast<int>(*fruBytesIter));
-                fruBytesIter += 1;
-                fruAreaFieldNames = &CHASSIS_FRU_AREAS;
-                break;
-            }
-            case fruAreas::fruAreaBoard:
-            {
-                uint8_t lang = *fruBytesIter;
-                result["BOARD_LANGUAGE_CODE"] =
-                    std::to_string(static_cast<int>(lang));
-                isLangEng = checkLangEng(lang);
-                fruBytesIter += 1;
-
-                unsigned int minutes = *fruBytesIter |
-                                       *(fruBytesIter + 1) << 8 |
-                                       *(fruBytesIter + 2) << 16;
-                std::tm fruTime = intelEpoch();
-                std::time_t timeValue = std::mktime(&fruTime);
-                timeValue += minutes * 60;
-                fruTime = *std::gmtime(&timeValue);
-
-                // Tue Nov 20 23:08:00 2018
-                char timeString[32] = {0};
-                auto bytes = std::strftime(timeString, sizeof(timeString),
-                                           "%Y-%m-%d - %H:%M:%S", &fruTime);
-                if (bytes == 0)
-                {
-                    std::cerr << "invalid time string encountered\n";
-                    return resCodes::resErr;
-                }
-
-                result["BOARD_MANUFACTURE_DATE"] = std::string(timeString);
-                fruBytesIter += 3;
-                fruAreaFieldNames = &BOARD_FRU_AREAS;
-                break;
-            }
-            case fruAreas::fruAreaProduct:
-            {
-                uint8_t lang = *fruBytesIter;
-                result["PRODUCT_LANGUAGE_CODE"] =
-                    std::to_string(static_cast<int>(lang));
-                isLangEng = checkLangEng(lang);
-                fruBytesIter += 1;
-                fruAreaFieldNames = &PRODUCT_FRU_AREAS;
-                break;
-            }
-            default:
-            {
-                std::cerr << "Internal error: unexpected FRU area index: "
-                          << static_cast<int>(area) << " \n";
-                return resCodes::resErr;
-            }
-        }
-        size_t fieldIndex = 0;
-        DecodeState state;
-        do
-        {
-            auto res =
-                decodeFRUData(fruBytesIter, fruBytesIterEndArea, isLangEng);
-            state = res.first;
-            std::string value = res.second;
-            std::string name;
-            if (fieldIndex < fruAreaFieldNames->size())
-            {
-                name = std::string(getFruAreaName(area)) + "_" +
-                       fruAreaFieldNames->at(fieldIndex);
-            }
-            else
-            {
-                name =
-                    std::string(getFruAreaName(area)) + "_" +
-                    FRU_CUSTOM_FIELD_NAME +
-                    std::to_string(fieldIndex - fruAreaFieldNames->size() + 1);
-            }
-
-            if (state == DecodeState::ok)
-            {
-                // Strip non null characters from the end
-                value.erase(std::find_if(value.rbegin(), value.rend(),
-                                         [](char ch) { return ch != 0; })
-                                .base(),
-                            value.end());
-
-                result[name] = std::move(value);
-                ++fieldIndex;
-            }
-            else if (state == DecodeState::err)
-            {
-                std::cerr << "Error while parsing " << name << "\n";
-                ret = resCodes::resWarn;
-                // Cancel decoding if failed to parse any of mandatory
-                // fields
-                if (fieldIndex < fruAreaFieldNames->size())
-                {
-                    std::cerr << "Failed to parse mandatory field \n";
-                    return resCodes::resErr;
-                }
-            }
-            else
-            {
-                if (fieldIndex < fruAreaFieldNames->size())
-                {
-                    std::cerr << "Mandatory fields absent in FRU area "
-                              << getFruAreaName(area) << " after " << name
-                              << "\n";
-                    ret = resCodes::resWarn;
-                }
-            }
-        } while (state == DecodeState::ok);
-        for (; fruBytesIter < fruBytesIterEndArea; fruBytesIter++)
-        {
-            uint8_t c = *fruBytesIter;
-            if (c)
-            {
-                std::cerr << "Non-zero byte after EndOfFields in FRU area "
-                          << getFruAreaName(area) << "\n";
-                ret = resCodes::resWarn;
-                break;
-            }
-        }
-    }
-
-    return ret;
-}
-
 std::vector<uint8_t>& getFRUInfo(const uint8_t& bus, const uint8_t& address)
 {
     auto deviceMap = busMap.find(bus);
@@ -1428,76 +1043,6 @@
     });
 }
 
-// Calculate new checksum for fru info area
-uint8_t calculateChecksum(std::vector<uint8_t>::const_iterator iter,
-                          std::vector<uint8_t>::const_iterator end)
-{
-    constexpr int checksumMod = 256;
-    constexpr uint8_t modVal = 0xFF;
-    int sum = std::accumulate(iter, end, 0);
-    int checksum = (checksumMod - sum) & modVal;
-    return static_cast<uint8_t>(checksum);
-}
-uint8_t calculateChecksum(std::vector<uint8_t>& fruAreaData)
-{
-    return calculateChecksum(fruAreaData.begin(), fruAreaData.end());
-}
-
-// Update new fru area length &
-// Update checksum at new checksum location
-// Return the offset of the area checksum byte
-static unsigned int updateFRUAreaLenAndChecksum(std::vector<uint8_t>& fruData,
-                                                size_t fruAreaStart,
-                                                size_t fruAreaEndOfFieldsOffset,
-                                                size_t fruAreaEndOffset)
-{
-    size_t traverseFRUAreaIndex = fruAreaEndOfFieldsOffset - fruAreaStart;
-
-    // fill zeros for any remaining unused space
-    std::fill(fruData.begin() + fruAreaEndOfFieldsOffset,
-              fruData.begin() + fruAreaEndOffset, 0);
-
-    size_t mod = traverseFRUAreaIndex % fruBlockSize;
-    size_t checksumLoc;
-    if (!mod)
-    {
-        traverseFRUAreaIndex += (fruBlockSize);
-        checksumLoc = fruAreaEndOfFieldsOffset + (fruBlockSize - 1);
-    }
-    else
-    {
-        traverseFRUAreaIndex += (fruBlockSize - mod);
-        checksumLoc = fruAreaEndOfFieldsOffset + (fruBlockSize - mod - 1);
-    }
-
-    size_t newFRUAreaLen = (traverseFRUAreaIndex / fruBlockSize) +
-                           ((traverseFRUAreaIndex % fruBlockSize) != 0);
-    size_t fruAreaLengthLoc = fruAreaStart + 1;
-    fruData[fruAreaLengthLoc] = static_cast<uint8_t>(newFRUAreaLen);
-
-    // Calculate new checksum
-    std::vector<uint8_t> finalFRUData;
-    std::copy_n(fruData.begin() + fruAreaStart, checksumLoc - fruAreaStart,
-                std::back_inserter(finalFRUData));
-
-    fruData[checksumLoc] = calculateChecksum(finalFRUData);
-    return checksumLoc;
-}
-
-static ssize_t getFieldLength(uint8_t fruFieldTypeLenValue)
-{
-    constexpr uint8_t typeLenMask = 0x3F;
-    constexpr uint8_t endOfFields = 0xC1;
-    if (fruFieldTypeLenValue == endOfFields)
-    {
-        return -1;
-    }
-    else
-    {
-        return fruFieldTypeLenValue & typeLenMask;
-    }
-}
-
 // Details with example of Asset Tag Update
 // To find location of Product Info Area asset tag as per FRU specification
 // 1. Find product Info area starting offset (*8 - as header will be in
diff --git a/src/FruUtils.cpp b/src/FruUtils.cpp
index 9bfcf30..32647d9 100644
--- a/src/FruUtils.cpp
+++ b/src/FruUtils.cpp
@@ -19,7 +19,9 @@
 
 #include <array>
 #include <cstdint>
+#include <filesystem>
 #include <iostream>
+#include <numeric>
 #include <set>
 #include <string>
 #include <vector>
@@ -33,80 +35,152 @@
 static constexpr bool DEBUG = false;
 constexpr size_t fruVersion = 1; // Current FRU spec version number is 1
 
-static constexpr std::array<const char*, 5> FRU_AREAS_NAMES = {
-    "INTERNAL", "CHASSIS", "BOARD", "PRODUCT", "MULTIRECORD"};
-
-std::string getFruAreaName(fruAreas area)
+const std::tm intelEpoch(void)
 {
-    // Check range of passed area value
-    if (static_cast<unsigned int>(area) >= FRU_AREAS_NAMES.size())
-    {
-        std::cerr << "Error: Fru area is out of range\n";
-        return "";
-    }
-
-    return std::string(FRU_AREAS_NAMES[static_cast<unsigned int>(area)]);
+    std::tm val = {};
+    val.tm_year = 1996 - 1900;
+    return val;
 }
 
-bool validateHeader(const std::array<uint8_t, I2C_SMBUS_BLOCK_MAX>& blockData)
+char sixBitToChar(uint8_t val)
 {
-    // ipmi spec format version number is currently at 1, verify it
-    if (blockData[0] != fruVersion)
+    return static_cast<char>((val & 0x3f) + ' ');
+}
+
+char bcdPlusToChar(uint8_t val)
+{
+    val &= 0xf;
+    return (val < 10) ? static_cast<char>(val + '0') : bcdHighChars[val - 10];
+}
+
+enum FRUDataEncoding
+{
+    binary = 0x0,
+    bcdPlus = 0x1,
+    sixBitASCII = 0x2,
+    languageDependent = 0x3,
+};
+
+/* Decode FRU data into a std::string, given an input iterator and end. If the
+ * state returned is fruDataOk, then the resulting string is the decoded FRU
+ * data. The input iterator is advanced past the data consumed.
+ *
+ * On fruDataErr, we have lost synchronisation with the length bytes, so the
+ * iterator is no longer usable.
+ */
+std::pair<DecodeState, std::string>
+    decodeFRUData(std::vector<uint8_t>::const_iterator& iter,
+                  const std::vector<uint8_t>::const_iterator& end,
+                  bool isLangEng)
+{
+    std::string value;
+    unsigned int i;
+
+    /* we need at least one byte to decode the type/len header */
+    if (iter == end)
     {
-        if (DEBUG)
+        std::cerr << "Truncated FRU data\n";
+        return make_pair(DecodeState::err, value);
+    }
+
+    uint8_t c = *(iter++);
+
+    /* 0xc1 is the end marker */
+    if (c == 0xc1)
+    {
+        return make_pair(DecodeState::end, value);
+    }
+
+    /* decode type/len byte */
+    uint8_t type = static_cast<uint8_t>(c >> 6);
+    uint8_t len = static_cast<uint8_t>(c & 0x3f);
+
+    /* we should have at least len bytes of data available overall */
+    if (iter + len > end)
+    {
+        std::cerr << "FRU data field extends past end of FRU area data\n";
+        return make_pair(DecodeState::err, value);
+    }
+
+    switch (type)
+    {
+        case FRUDataEncoding::binary:
         {
-            std::cerr << "FRU spec version " << (int)(blockData[0])
-                      << " not supported. Supported version is "
-                      << (int)(fruVersion) << "\n";
+            std::stringstream ss;
+            ss << std::hex << std::setfill('0');
+            for (i = 0; i < len; i++, iter++)
+            {
+                uint8_t val = static_cast<uint8_t>(*iter);
+                ss << std::setw(2) << static_cast<int>(val);
+            }
+            value = ss.str();
+            break;
         }
+        case FRUDataEncoding::languageDependent:
+            /* For language-code dependent encodings, assume 8-bit ASCII */
+            value = std::string(iter, iter + len);
+            iter += len;
+
+            /* English text is encoded in 8-bit ASCII + Latin 1. All other
+             * languages are required to use 2-byte unicode. FruDevice does not
+             * handle unicode.
+             */
+            if (!isLangEng)
+            {
+                std::cerr << "Error: Non english string is not supported \n";
+                return make_pair(DecodeState::err, value);
+            }
+
+            break;
+
+        case FRUDataEncoding::bcdPlus:
+            value = std::string();
+            for (i = 0; i < len; i++, iter++)
+            {
+                uint8_t val = *iter;
+                value.push_back(bcdPlusToChar(val >> 4));
+                value.push_back(bcdPlusToChar(val & 0xf));
+            }
+            break;
+
+        case FRUDataEncoding::sixBitASCII:
+        {
+            unsigned int accum = 0;
+            unsigned int accumBitLen = 0;
+            value = std::string();
+            for (i = 0; i < len; i++, iter++)
+            {
+                accum |= *iter << accumBitLen;
+                accumBitLen += 8;
+                while (accumBitLen >= 6)
+                {
+                    value.push_back(sixBitToChar(accum & 0x3f));
+                    accum >>= 6;
+                    accumBitLen -= 6;
+                }
+            }
+        }
+        break;
+    }
+
+    return make_pair(DecodeState::ok, value);
+}
+
+bool checkLangEng(uint8_t lang)
+{
+    // If Lang is not English then the encoding is defined as 2-byte UNICODE,
+    // but we don't support that.
+    if (lang && lang != 25)
+    {
+        std::cerr << "Warning: languages other than English is not "
+                     "supported\n";
+        // Return language flag as non english
         return false;
     }
-
-    // verify pad is set to 0
-    if (blockData[6] != 0x0)
+    else
     {
-        if (DEBUG)
-        {
-            std::cerr << "PAD value in header is non zero, value is "
-                      << (int)(blockData[6]) << "\n";
-        }
-        return false;
+        return true;
     }
-
-    // verify offsets are 0, or don't point to another offset
-    std::set<uint8_t> foundOffsets;
-    for (int ii = 1; ii < 6; ii++)
-    {
-        if (blockData[ii] == 0)
-        {
-            continue;
-        }
-        auto inserted = foundOffsets.insert(blockData[ii]);
-        if (!inserted.second)
-        {
-            return false;
-        }
-    }
-
-    // validate checksum
-    size_t sum = 0;
-    for (int jj = 0; jj < 7; jj++)
-    {
-        sum += blockData[jj];
-    }
-    sum = (256 - sum) & 0xFF;
-
-    if (sum != blockData[7])
-    {
-        if (DEBUG)
-        {
-            std::cerr << "Checksum " << (int)(blockData[7])
-                      << " is invalid. calculated checksum is " << (int)(sum)
-                      << "\n";
-        }
-        return false;
-    }
-    return true;
 }
 
 /* This function verifies for other offsets to check if they are not
@@ -184,6 +258,340 @@
     return true;
 }
 
+resCodes formatFRU(const std::vector<uint8_t>& fruBytes,
+                   boost::container::flat_map<std::string, std::string>& result)
+{
+    resCodes ret = resCodes::resOK;
+    if (fruBytes.size() <= fruBlockSize)
+    {
+        std::cerr << "Error: trying to parse empty FRU \n";
+        return resCodes::resErr;
+    }
+    result["Common_Format_Version"] =
+        std::to_string(static_cast<int>(*fruBytes.begin()));
+
+    const std::vector<std::string>* fruAreaFieldNames;
+
+    // Don't parse Internal and Multirecord areas
+    for (fruAreas area = fruAreas::fruAreaChassis;
+         area <= fruAreas::fruAreaProduct; ++area)
+    {
+
+        size_t offset = *(fruBytes.begin() + getHeaderAreaFieldOffset(area));
+        if (offset == 0)
+        {
+            continue;
+        }
+        offset *= fruBlockSize;
+        std::vector<uint8_t>::const_iterator fruBytesIter =
+            fruBytes.begin() + offset;
+        if (fruBytesIter + fruBlockSize >= fruBytes.end())
+        {
+            std::cerr << "Not enough data to parse \n";
+            return resCodes::resErr;
+        }
+        // check for format version 1
+        if (*fruBytesIter != 0x01)
+        {
+            std::cerr << "Unexpected version " << *fruBytesIter << "\n";
+            return resCodes::resErr;
+        }
+        ++fruBytesIter;
+
+        /* Verify other area offset for overlap with current area by passing
+         * length of current area offset pointed by *fruBytesIter
+         */
+        if (!verifyOffset(fruBytes, area, *fruBytesIter))
+        {
+            return resCodes::resErr;
+        }
+
+        uint8_t fruAreaSize = *fruBytesIter * fruBlockSize;
+        std::vector<uint8_t>::const_iterator fruBytesIterEndArea =
+            fruBytes.begin() + offset + fruAreaSize - 1;
+        ++fruBytesIter;
+
+        uint8_t fruComputedChecksum =
+            calculateChecksum(fruBytes.begin() + offset, fruBytesIterEndArea);
+        if (fruComputedChecksum != *fruBytesIterEndArea)
+        {
+            std::stringstream ss;
+            ss << std::hex << std::setfill('0');
+            ss << "Checksum error in FRU area " << getFruAreaName(area) << "\n";
+            ss << "\tComputed checksum: 0x" << std::setw(2)
+               << static_cast<int>(fruComputedChecksum) << "\n";
+            ss << "\tThe read checksum: 0x" << std::setw(2)
+               << static_cast<int>(*fruBytesIterEndArea) << "\n";
+            std::cerr << ss.str();
+            ret = resCodes::resWarn;
+        }
+
+        /* Set default language flag to true as Chassis Fru area are always
+         * encoded in English defined in Section 10 of Fru specification
+         */
+
+        bool isLangEng = true;
+        switch (area)
+        {
+            case fruAreas::fruAreaChassis:
+            {
+                result["CHASSIS_TYPE"] =
+                    std::to_string(static_cast<int>(*fruBytesIter));
+                fruBytesIter += 1;
+                fruAreaFieldNames = &CHASSIS_FRU_AREAS;
+                break;
+            }
+            case fruAreas::fruAreaBoard:
+            {
+                uint8_t lang = *fruBytesIter;
+                result["BOARD_LANGUAGE_CODE"] =
+                    std::to_string(static_cast<int>(lang));
+                isLangEng = checkLangEng(lang);
+                fruBytesIter += 1;
+
+                unsigned int minutes = *fruBytesIter |
+                                       *(fruBytesIter + 1) << 8 |
+                                       *(fruBytesIter + 2) << 16;
+                std::tm fruTime = intelEpoch();
+                std::time_t timeValue = std::mktime(&fruTime);
+                timeValue += minutes * 60;
+                fruTime = *std::gmtime(&timeValue);
+
+                // Tue Nov 20 23:08:00 2018
+                char timeString[32] = {0};
+                auto bytes = std::strftime(timeString, sizeof(timeString),
+                                           "%Y-%m-%d - %H:%M:%S", &fruTime);
+                if (bytes == 0)
+                {
+                    std::cerr << "invalid time string encountered\n";
+                    return resCodes::resErr;
+                }
+
+                result["BOARD_MANUFACTURE_DATE"] = std::string(timeString);
+                fruBytesIter += 3;
+                fruAreaFieldNames = &BOARD_FRU_AREAS;
+                break;
+            }
+            case fruAreas::fruAreaProduct:
+            {
+                uint8_t lang = *fruBytesIter;
+                result["PRODUCT_LANGUAGE_CODE"] =
+                    std::to_string(static_cast<int>(lang));
+                isLangEng = checkLangEng(lang);
+                fruBytesIter += 1;
+                fruAreaFieldNames = &PRODUCT_FRU_AREAS;
+                break;
+            }
+            default:
+            {
+                std::cerr << "Internal error: unexpected FRU area index: "
+                          << static_cast<int>(area) << " \n";
+                return resCodes::resErr;
+            }
+        }
+        size_t fieldIndex = 0;
+        DecodeState state;
+        do
+        {
+            auto res =
+                decodeFRUData(fruBytesIter, fruBytesIterEndArea, isLangEng);
+            state = res.first;
+            std::string value = res.second;
+            std::string name;
+            if (fieldIndex < fruAreaFieldNames->size())
+            {
+                name = std::string(getFruAreaName(area)) + "_" +
+                       fruAreaFieldNames->at(fieldIndex);
+            }
+            {
+                name =
+                    std::string(getFruAreaName(area)) + "_" +
+                    FRU_CUSTOM_FIELD_NAME +
+                    std::to_string(fieldIndex - fruAreaFieldNames->size() + 1);
+            }
+
+            if (state == DecodeState::ok)
+            {
+                // Strip non null characters from the end
+                value.erase(std::find_if(value.rbegin(), value.rend(),
+                                         [](char ch) { return ch != 0; })
+                                .base(),
+                            value.end());
+
+                result[name] = std::move(value);
+                ++fieldIndex;
+            }
+            else if (state == DecodeState::err)
+            {
+                std::cerr << "Error while parsing " << name << "\n";
+                ret = resCodes::resWarn;
+                // Cancel decoding if failed to parse any of mandatory
+                // fields
+                if (fieldIndex < fruAreaFieldNames->size())
+                {
+                    std::cerr << "Failed to parse mandatory field \n";
+                    return resCodes::resErr;
+                }
+            }
+            else
+            {
+                if (fieldIndex < fruAreaFieldNames->size())
+                {
+                    std::cerr << "Mandatory fields absent in FRU area "
+                              << getFruAreaName(area) << " after " << name
+                              << "\n";
+                    ret = resCodes::resWarn;
+                }
+            }
+        } while (state == DecodeState::ok);
+        for (; fruBytesIter < fruBytesIterEndArea; fruBytesIter++)
+        {
+            uint8_t c = *fruBytesIter;
+            if (c)
+            {
+                std::cerr << "Non-zero byte after EndOfFields in FRU area "
+                          << getFruAreaName(area) << "\n";
+                ret = resCodes::resWarn;
+                break;
+            }
+        }
+    }
+
+    return ret;
+}
+
+// Calculate new checksum for fru info area
+uint8_t calculateChecksum(std::vector<uint8_t>::const_iterator iter,
+                          std::vector<uint8_t>::const_iterator end)
+{
+    constexpr int checksumMod = 256;
+    constexpr uint8_t modVal = 0xFF;
+    int sum = std::accumulate(iter, end, 0);
+    int checksum = (checksumMod - sum) & modVal;
+    return static_cast<uint8_t>(checksum);
+}
+
+uint8_t calculateChecksum(std::vector<uint8_t>& fruAreaData)
+{
+    return calculateChecksum(fruAreaData.begin(), fruAreaData.end());
+}
+
+// Update new fru area length &
+// Update checksum at new checksum location
+// Return the offset of the area checksum byte
+unsigned int updateFRUAreaLenAndChecksum(std::vector<uint8_t>& fruData,
+                                         size_t fruAreaStart,
+                                         size_t fruAreaEndOfFieldsOffset,
+                                         size_t fruAreaEndOffset)
+{
+    size_t traverseFRUAreaIndex = fruAreaEndOfFieldsOffset - fruAreaStart;
+
+    // fill zeros for any remaining unused space
+    std::fill(fruData.begin() + fruAreaEndOfFieldsOffset,
+              fruData.begin() + fruAreaEndOffset, 0);
+
+    size_t mod = traverseFRUAreaIndex % fruBlockSize;
+    size_t checksumLoc;
+    if (!mod)
+    {
+        traverseFRUAreaIndex += (fruBlockSize);
+        checksumLoc = fruAreaEndOfFieldsOffset + (fruBlockSize - 1);
+    }
+    else
+    {
+        traverseFRUAreaIndex += (fruBlockSize - mod);
+        checksumLoc = fruAreaEndOfFieldsOffset + (fruBlockSize - mod - 1);
+    }
+
+    size_t newFRUAreaLen = (traverseFRUAreaIndex / fruBlockSize) +
+                           ((traverseFRUAreaIndex % fruBlockSize) != 0);
+    size_t fruAreaLengthLoc = fruAreaStart + 1;
+    fruData[fruAreaLengthLoc] = static_cast<uint8_t>(newFRUAreaLen);
+
+    // Calculate new checksum
+    std::vector<uint8_t> finalFRUData;
+    std::copy_n(fruData.begin() + fruAreaStart, checksumLoc - fruAreaStart,
+                std::back_inserter(finalFRUData));
+
+    fruData[checksumLoc] = calculateChecksum(finalFRUData);
+    return checksumLoc;
+}
+
+ssize_t getFieldLength(uint8_t fruFieldTypeLenValue)
+{
+    constexpr uint8_t typeLenMask = 0x3F;
+    constexpr uint8_t endOfFields = 0xC1;
+    if (fruFieldTypeLenValue == endOfFields)
+    {
+        return -1;
+    }
+    else
+    {
+        return fruFieldTypeLenValue & typeLenMask;
+    }
+}
+
+bool validateHeader(const std::array<uint8_t, I2C_SMBUS_BLOCK_MAX>& blockData)
+{
+    // ipmi spec format version number is currently at 1, verify it
+    if (blockData[0] != fruVersion)
+    {
+        if (DEBUG)
+        {
+            std::cerr << "FRU spec version " << (int)(blockData[0])
+                      << " not supported. Supported version is "
+                      << (int)(fruVersion) << "\n";
+        }
+        return false;
+    }
+
+    // verify pad is set to 0
+    if (blockData[6] != 0x0)
+    {
+        if (DEBUG)
+        {
+            std::cerr << "PAD value in header is non zero, value is "
+                      << (int)(blockData[6]) << "\n";
+        }
+        return false;
+    }
+
+    // verify offsets are 0, or don't point to another offset
+    std::set<uint8_t> foundOffsets;
+    for (int ii = 1; ii < 6; ii++)
+    {
+        if (blockData[ii] == 0)
+        {
+            continue;
+        }
+        auto inserted = foundOffsets.insert(blockData[ii]);
+        if (!inserted.second)
+        {
+            return false;
+        }
+    }
+
+    // validate checksum
+    size_t sum = 0;
+    for (int jj = 0; jj < 7; jj++)
+    {
+        sum += blockData[jj];
+    }
+    sum = (256 - sum) & 0xFF;
+
+    if (sum != blockData[7])
+    {
+        if (DEBUG)
+        {
+            std::cerr << "Checksum " << (int)(blockData[7])
+                      << " is invalid. calculated checksum is " << (int)(sum)
+                      << "\n";
+        }
+        return false;
+    }
+    return true;
+}
+
 std::vector<uint8_t> readFRUContents(int flag, int file, uint16_t address,
                                      ReadBlockFunc readBlock,
                                      const std::string& errorHelp)
