diff --git a/libpldmresponder/bios.cpp b/libpldmresponder/bios.cpp
index f9f3a55..93e8302 100644
--- a/libpldmresponder/bios.cpp
+++ b/libpldmresponder/bios.cpp
@@ -18,26 +18,9 @@
 #include <variant>
 #include <vector>
 
-namespace fs = std::filesystem;
-using namespace pldm::responder::bios;
-using namespace bios_parser;
-using namespace pldm::utils;
-
-constexpr auto stringTableFile = "stringTable";
-constexpr auto attrTableFile = "attributeTable";
-constexpr auto attrValTableFile = "attributeValueTable";
-
 namespace pldm
 {
 
-using namespace sdbusplus::xyz::openbmc_project::Common::Error;
-using EpochTimeUS = uint64_t;
-using BIOSTableRow = std::vector<uint8_t>;
-using BIOSJsonName = std::string;
-
-constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
-constexpr auto padChksumMax = 7;
-
 namespace responder
 {
 
@@ -80,40 +63,20 @@
     return timegm(&stm);
 }
 
-size_t getTableTotalsize(size_t sizeWithoutPad)
-{
-    return sizeWithoutPad + pldm_bios_table_pad_checksum_size(sizeWithoutPad);
-}
-
-void padAndChecksum(Table& table)
-{
-    auto sizeWithoutPad = table.size();
-    auto padAndChecksumSize = pldm_bios_table_pad_checksum_size(sizeWithoutPad);
-    table.resize(table.size() + padAndChecksumSize);
-
-    pldm_bios_table_append_pad_checksum(table.data(), table.size(),
-                                        sizeWithoutPad);
-}
-
 } // namespace utils
 
 namespace bios
 {
 
-Handler::Handler()
+using EpochTimeUS = uint64_t;
+
+DBusHandler dbusHandler;
+
+Handler::Handler() : biosConfig(BIOS_JSONS_DIR, BIOS_TABLES_DIR, &dbusHandler)
 {
-    try
-    {
-        fs::remove(
-            fs::path(std::string(BIOS_TABLES_DIR) + "/" + stringTableFile));
-        fs::remove(
-            fs::path(std::string(BIOS_TABLES_DIR) + "/" + attrTableFile));
-        fs::remove(
-            fs::path(std::string(BIOS_TABLES_DIR) + "/" + attrValTableFile));
-    }
-    catch (const std::exception& e)
-    {
-    }
+    biosConfig.removeTables();
+    biosConfig.buildTables();
+
     handlers.emplace(PLDM_SET_DATE_TIME,
                      [this](const pldm_msg* request, size_t payloadLength) {
                          return this->setDateTime(request, payloadLength);
@@ -229,610 +192,37 @@
     return ccOnlyResponse(request, PLDM_SUCCESS);
 }
 
-/** @brief Construct the BIOS string table
- *
- *  @param[in,out] biosStringTable - the string table
- *  @param[in] request - Request message
- */
-Response getBIOSStringTable(BIOSTable& biosStringTable, const pldm_msg* request)
-
-{
-    Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
-                      0);
-    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-    if (!biosStringTable.isEmpty())
-    {
-        auto rc = encode_get_bios_table_resp(
-            request->hdr.instance_id, PLDM_SUCCESS,
-            0, /* next transfer handle */
-            PLDM_START_AND_END, nullptr, response.size(),
-            responsePtr); // filling up the header here
-        if (rc != PLDM_SUCCESS)
-        {
-            return CmdHandler::ccOnlyResponse(request, rc);
-        }
-
-        biosStringTable.load(response);
-        return response;
-    }
-    auto biosStrings = bios_parser::getStrings();
-    std::sort(biosStrings.begin(), biosStrings.end());
-    // remove all duplicate strings received from bios json
-    biosStrings.erase(std::unique(biosStrings.begin(), biosStrings.end()),
-                      biosStrings.end());
-
-    size_t sizeWithoutPad = std::accumulate(
-        biosStrings.begin(), biosStrings.end(), 0,
-        [](size_t sum, const std::string& elem) {
-            return sum +
-                   pldm_bios_table_string_entry_encode_length(elem.length());
-        });
-
-    Table stringTable;
-    stringTable.reserve(
-        pldm::responder::utils::getTableTotalsize(sizeWithoutPad));
-
-    stringTable.resize(sizeWithoutPad);
-    auto tablePtr = stringTable.data();
-    for (const auto& elem : biosStrings)
-    {
-        auto entry_length =
-            pldm_bios_table_string_entry_encode_length(elem.length());
-        pldm_bios_table_string_entry_encode(tablePtr, sizeWithoutPad,
-                                            elem.c_str(), elem.length());
-        tablePtr += entry_length;
-        sizeWithoutPad -= entry_length;
-    }
-
-    pldm::responder::utils::padAndChecksum(stringTable);
-    biosStringTable.store(stringTable);
-    response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
-                        stringTable.size(),
-                    0);
-    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-    auto rc = encode_get_bios_table_resp(
-        request->hdr.instance_id, PLDM_SUCCESS, 0 /* nxtTransferHandle */,
-        PLDM_START_AND_END, stringTable.data(), response.size(), responsePtr);
-    if (rc != PLDM_SUCCESS)
-    {
-        return CmdHandler::ccOnlyResponse(request, rc);
-    }
-
-    return response;
-}
-
-namespace bios_type_enum
-{
-
-using namespace bios_parser::bios_enum;
-
-/** @brief Find the indices  into the array of the possible values of string
- *  handles for the current values.This is used in attribute value table
- *
- *  @param[in] possiVals - vector of string handles comprising all the possible
- *                         values for an attribute
- *  @param[in] currVals - vector of strings comprising all current values
- *                        for an attribute
- *  @param[in] biosStringTable - the string table
- *
- *  @return - std::vector<uint8_t> - indices into the array of the possible
- *                                   values of string handles
- */
-std::vector<uint8_t> findStrIndices(PossibleValuesByHandle possiVals,
-                                    CurrentValues currVals,
-                                    const BIOSStringTable& biosStringTable)
-{
-    std::vector<uint8_t> stringIndices;
-
-    for (const auto& currVal : currVals)
-    {
-        StringHandle curHdl;
-        try
-        {
-            curHdl = biosStringTable.findHandle(currVal);
-        }
-        catch (const std::exception& e)
-        {
-            std::cerr << "Exception fetching handle for the string, STRING="
-                      << currVal.c_str() << "\n";
-            continue;
-        }
-
-        uint8_t i = 0;
-        for (auto possiHdl : possiVals)
-        {
-            if (possiHdl == curHdl)
-            {
-                stringIndices.push_back(i);
-                break;
-            }
-            i++;
-        }
-    }
-    return stringIndices;
-}
-
-/** @brief Find the indices into the array of the possible values of string
- *  handles for the default values. This is used in attribute table
- *
- *  @param[in] possiVals - vector of strings comprising all the possible values
- *                         for an attribute
- *  @param[in] defVals - vector of strings comprising all the default values
- *                       for an attribute
- *  @return - std::vector<uint8_t> - indices into the array of the possible
- *                                   values of string
- */
-std::vector<uint8_t> findDefaultValHandle(const PossibleValues& possiVals,
-                                          const DefaultValues& defVals)
-{
-    std::vector<uint8_t> defHdls;
-    for (const auto& defs : defVals)
-    {
-        auto index = std::find_if(possiVals.begin(), possiVals.end(),
-                                  [&defs](const auto& v) { return defs == v; });
-        if (index != possiVals.end())
-        {
-            defHdls.push_back(index - possiVals.begin());
-        }
-    }
-
-    return defHdls;
-}
-
-/** @brief Construct the attibute table for BIOS type Enumeration and
- *         Enumeration ReadOnly
- *  @param[in] biosStringTable - the string table
- *  @param[in] biosJsonDir - path where the BIOS json files are present
- *  @param[in,out] attributeTable - the attribute table
- *
- */
-void constructAttrTable(const BIOSStringTable& biosStringTable,
-                        Table& attributeTable)
-{
-    const auto& attributeMap = getValues();
-    StringHandle strHandle;
-
-    for (const auto& [key, value] : attributeMap)
-    {
-        try
-        {
-            strHandle = biosStringTable.findHandle(key);
-        }
-        catch (const std::exception& e)
-        {
-            std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
-                      << key.c_str() << "\n";
-            continue;
-        }
-        bool readOnly = (std::get<0>(value));
-        const PossibleValues& possiVals = std::get<1>(value);
-        const DefaultValues& defVals = std::get<2>(value);
-
-        std::vector<StringHandle> possiValsByHdl;
-        for (const auto& elem : possiVals)
-        {
-            try
-            {
-                auto hdl = biosStringTable.findHandle(elem);
-                possiValsByHdl.push_back(std::move(hdl));
-            }
-            catch (const std::exception& e)
-            {
-                std::cerr << "Could not find handle for BIOS string, STRING="
-                          << elem.c_str() << "\n";
-                continue;
-            }
-        }
-        auto defValsByHdl = findDefaultValHandle(possiVals, defVals);
-        auto entryLength = pldm_bios_table_attr_entry_enum_encode_length(
-            possiValsByHdl.size(), defValsByHdl.size());
-
-        auto attrTableSize = attributeTable.size();
-        attributeTable.resize(attrTableSize + entryLength, 0);
-        struct pldm_bios_table_attr_entry_enum_info info = {
-            strHandle,
-            readOnly,
-            (uint8_t)possiValsByHdl.size(),
-            possiValsByHdl.data(),
-            (uint8_t)defValsByHdl.size(),
-            defValsByHdl.data(),
-        };
-        pldm_bios_table_attr_entry_enum_encode(
-            attributeTable.data() + attrTableSize, entryLength, &info);
-    }
-}
-
-void constructAttrValueEntry(
-    const struct pldm_bios_attr_table_entry* attrTableEntry,
-    const std::string& attrName, const BIOSStringTable& biosStringTable,
-    Table& attrValueTable)
-{
-    CurrentValues currVals;
-    try
-    {
-        currVals = getAttrValue(attrName);
-    }
-    catch (const std::exception& e)
-    {
-        std::cerr << "getAttrValue returned error for attribute, NAME="
-                  << attrName.c_str() << " ERROR=" << e.what() << "\n";
-        return;
-    }
-    uint8_t pv_num =
-        pldm_bios_table_attr_entry_enum_decode_pv_num(attrTableEntry);
-    PossibleValuesByHandle pvHdls(pv_num, 0);
-    pldm_bios_table_attr_entry_enum_decode_pv_hdls(attrTableEntry,
-                                                   pvHdls.data(), pv_num);
-    std::sort(currVals.begin(), currVals.end());
-
-    auto currValStrIndices = findStrIndices(pvHdls, currVals, biosStringTable);
-
-    auto entryLength = pldm_bios_table_attr_value_entry_encode_enum_length(
-        currValStrIndices.size());
-    auto tableSize = attrValueTable.size();
-    attrValueTable.resize(tableSize + entryLength);
-    pldm_bios_table_attr_value_entry_encode_enum(
-        attrValueTable.data() + tableSize, entryLength,
-        attrTableEntry->attr_handle, attrTableEntry->attr_type,
-        currValStrIndices.size(), currValStrIndices.data());
-}
-
-} // end namespace bios_type_enum
-
-namespace bios_type_string
-{
-
-using namespace bios_parser::bios_string;
-
-/** @brief Construct the attibute table for BIOS type String and
- *         String ReadOnly
- *  @param[in] biosStringTable - the string table
- *  @param[in] biosJsonDir - path where the BIOS json files are present
- *  @param[in,out] attributeTable - the attribute table
- *
- */
-void constructAttrTable(const BIOSStringTable& biosStringTable,
-                        Table& attributeTable)
-{
-    const auto& attributeMap = getValues();
-    StringHandle strHandle;
-    for (const auto& [key, value] : attributeMap)
-    {
-        try
-        {
-            strHandle = biosStringTable.findHandle(key);
-        }
-        catch (const std::exception& e)
-        {
-            std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
-                      << key.c_str() << "\n";
-            continue;
-        }
-
-        const auto& [readOnly, strType, minStrLen, maxStrLen, defaultStrLen,
-                     defaultStr] = value;
-        auto entryLength =
-            pldm_bios_table_attr_entry_string_encode_length(defaultStrLen);
-
-        struct pldm_bios_table_attr_entry_string_info info = {
-            strHandle, readOnly,      strType,           minStrLen,
-            maxStrLen, defaultStrLen, defaultStr.data(),
-        };
-        auto attrTableSize = attributeTable.size();
-        attributeTable.resize(attrTableSize + entryLength, 0);
-        pldm_bios_table_attr_entry_string_encode(
-            attributeTable.data() + attrTableSize, entryLength, &info);
-    }
-}
-
-void constructAttrValueEntry(const pldm_bios_attr_table_entry* attrTableEntry,
-                             const std::string& attrName,
-                             const BIOSStringTable& biosStringTable,
-                             Table& attrValueTable)
-{
-    std::ignore = biosStringTable;
-    std::string currStr;
-    uint16_t currStrLen = 0;
-    try
-    {
-        currStr = getAttrValue(attrName);
-        currStrLen = currStr.size();
-    }
-    catch (const std::exception& e)
-    {
-        std::cerr << "getAttrValue returned error for attribute, NAME="
-                  << attrName.c_str() << " ERROR=" << e.what() << "\n";
-        return;
-    }
-    auto entryLength =
-        pldm_bios_table_attr_value_entry_encode_string_length(currStrLen);
-    auto tableSize = attrValueTable.size();
-    attrValueTable.resize(tableSize + entryLength);
-    pldm_bios_table_attr_value_entry_encode_string(
-        attrValueTable.data() + tableSize, entryLength,
-        attrTableEntry->attr_handle, attrTableEntry->attr_type, currStrLen,
-        currStr.c_str());
-}
-
-} // end namespace bios_type_string
-
-namespace bios_type_integer
-{
-
-using namespace bios_parser::bios_integer;
-
-/** @brief Construct the attibute table for BIOS type Integer and
- *         Integer ReadOnly
- *  @param[in] biosStringTable - the string table
- *  @param[in,out] attributeTable - the attribute table
- *
- */
-void constructAttrTable(const BIOSStringTable& biosStringTable,
-                        Table& attributeTable)
-{
-    const auto& attributeMap = getValues();
-    StringHandle strHandle;
-    for (const auto& [key, value] : attributeMap)
-    {
-        try
-        {
-            strHandle = biosStringTable.findHandle(key);
-        }
-        catch (const std::exception& e)
-        {
-            std::cerr << "Could not find handle for BIOS string, ATTRIBUTE="
-                      << key.c_str() << "\n";
-            continue;
-        }
-
-        const auto& [readOnly, lowerBound, upperBound, scalarIncrement,
-                     defaultValue] = value;
-        auto entryLength = pldm_bios_table_attr_entry_integer_encode_length();
-
-        struct pldm_bios_table_attr_entry_integer_info info = {
-            strHandle,  readOnly,        lowerBound,
-            upperBound, scalarIncrement, defaultValue,
-        };
-        auto attrTableSize = attributeTable.size();
-        attributeTable.resize(attrTableSize + entryLength, 0);
-        pldm_bios_table_attr_entry_integer_encode(
-            attributeTable.data() + attrTableSize, entryLength, &info);
-    }
-}
-
-void constructAttrValueEntry(const pldm_bios_attr_table_entry* attrTableEntry,
-                             const std::string& attrName,
-                             const BIOSStringTable& biosStringTable,
-                             Table& attrValueTable)
-{
-    std::ignore = biosStringTable;
-    uint64_t currentValue;
-    try
-    {
-        currentValue = getAttrValue(attrName);
-    }
-    catch (const std::exception& e)
-    {
-        std::cerr << "Failed to get attribute value, NAME=" << attrName.c_str()
-                  << " ERROR=" << e.what() << "\n";
-        return;
-    }
-    auto entryLength = pldm_bios_table_attr_value_entry_encode_integer_length();
-    auto tableSize = attrValueTable.size();
-    attrValueTable.resize(tableSize + entryLength);
-    pldm_bios_table_attr_value_entry_encode_integer(
-        attrValueTable.data() + tableSize, entryLength,
-        attrTableEntry->attr_handle, attrTableEntry->attr_type, currentValue);
-}
-
-} // namespace bios_type_integer
-
-void traverseBIOSAttrTable(const Table& biosAttrTable,
-                           AttrTableEntryHandler handler)
-{
-    std::unique_ptr<pldm_bios_table_iter, decltype(&pldm_bios_table_iter_free)>
-        iter(pldm_bios_table_iter_create(biosAttrTable.data(),
-                                         biosAttrTable.size(),
-                                         PLDM_BIOS_ATTR_TABLE),
-             pldm_bios_table_iter_free);
-    while (!pldm_bios_table_iter_is_end(iter.get()))
-    {
-        auto table_entry = pldm_bios_table_iter_attr_entry_value(iter.get());
-        try
-        {
-            handler(table_entry);
-        }
-        catch (const std::exception& e)
-        {
-            std::cerr << "handler fails when traversing BIOSAttrTable, ERROR="
-                      << e.what() << "\n";
-        }
-        pldm_bios_table_iter_next(iter.get());
-    }
-}
-
-using typeHandler = std::function<void(const BIOSStringTable& biosStringTable,
-                                       Table& attributeTable)>;
-std::map<BIOSJsonName, typeHandler> attrTypeHandlers{
-    {bios_parser::bIOSEnumJson, bios_type_enum::constructAttrTable},
-    {bios_parser::bIOSStrJson, bios_type_string::constructAttrTable},
-    {bios_parser::bIOSIntegerJson, bios_type_integer::constructAttrTable},
-};
-
-/** @brief Construct the BIOS attribute table
- *
- *  @param[in,out] biosAttributeTable - the attribute table
- *  @param[in] biosStringTable - the string table
- *  @param[in] biosJsonDir - path where the BIOS json files are present
- *  @param[in] request - Request message
- */
-Response getBIOSAttributeTable(BIOSTable& biosAttributeTable,
-                               const BIOSStringTable& biosStringTable,
-                               const char* biosJsonDir, const pldm_msg* request)
-{
-    Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
-                      0);
-    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-    uint32_t nxtTransferHandle = 0;
-    uint8_t transferFlag = PLDM_START_AND_END;
-
-    if (biosAttributeTable.isEmpty())
-    { // no persisted table, constructing fresh table and response
-        Table attributeTable;
-        fs::path dir(biosJsonDir);
-
-        for (auto it = attrTypeHandlers.begin(); it != attrTypeHandlers.end();
-             it++)
-        {
-            fs::path file = dir / it->first;
-            if (fs::exists(file))
-            {
-                it->second(biosStringTable, attributeTable);
-            }
-        }
-
-        if (attributeTable.empty())
-        { // no available json file is found
-            return CmdHandler::ccOnlyResponse(request,
-                                              PLDM_BIOS_TABLE_UNAVAILABLE);
-        }
-        pldm::responder::utils::padAndChecksum(attributeTable);
-        biosAttributeTable.store(attributeTable);
-        response.resize(sizeof(pldm_msg_hdr) +
-                        PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
-                        attributeTable.size());
-        responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-
-        auto rc = encode_get_bios_table_resp(
-            request->hdr.instance_id, PLDM_SUCCESS, nxtTransferHandle,
-            transferFlag, attributeTable.data(), response.size(), responsePtr);
-        if (rc != PLDM_SUCCESS)
-        {
-            return CmdHandler::ccOnlyResponse(request, rc);
-        }
-    }
-    else
-    { // persisted table present, constructing response
-        auto rc = encode_get_bios_table_resp(
-            request->hdr.instance_id, PLDM_SUCCESS, nxtTransferHandle,
-            transferFlag, nullptr, response.size(),
-            responsePtr); // filling up the header here
-        if (rc != PLDM_SUCCESS)
-        {
-            return CmdHandler::ccOnlyResponse(request, rc);
-        }
-        biosAttributeTable.load(response);
-    }
-
-    return response;
-}
-
-using AttrValTableEntryConstructHandler =
-    std::function<void(const struct pldm_bios_attr_table_entry* tableEntry,
-                       const std::string& attrName,
-                       const BIOSStringTable& biosStringTable, Table& table)>;
-
-using AttrType = uint8_t;
-const std::map<AttrType, AttrValTableEntryConstructHandler>
-    AttrValTableConstructMap{
-        {PLDM_BIOS_STRING, bios_type_string::constructAttrValueEntry},
-        {PLDM_BIOS_STRING_READ_ONLY, bios_type_string::constructAttrValueEntry},
-        {PLDM_BIOS_ENUMERATION, bios_type_enum::constructAttrValueEntry},
-        {PLDM_BIOS_ENUMERATION_READ_ONLY,
-         bios_type_enum::constructAttrValueEntry},
-        {PLDM_BIOS_INTEGER, bios_type_integer::constructAttrValueEntry},
-        {PLDM_BIOS_INTEGER_READ_ONLY,
-         bios_type_integer::constructAttrValueEntry},
-    };
-
-void constructAttrValueTableEntry(
-    const struct pldm_bios_attr_table_entry* attrEntry,
-    const BIOSStringTable& biosStringTable, Table& attributeValueTable)
-{
-    auto stringHandle =
-        pldm_bios_table_attr_entry_decode_string_handle(attrEntry);
-    try
-    {
-        auto attrName = biosStringTable.findString(stringHandle);
-        AttrValTableConstructMap.at(attrEntry->attr_type)(
-            attrEntry, attrName, biosStringTable, attributeValueTable);
-    }
-    catch (const std::exception& e)
-    {
-        std::cerr << "constructAttrValueTableEntry Error: " << e.what()
-                  << std::endl;
-    }
-}
-
-/** @brief Construct the BIOS attribute value table
- *
- *  @param[in,out] biosAttributeValueTable - the attribute value table
- *  @param[in] biosAttributeTable - the attribute table
- *  @param[in] biosStringTable - the string table
- *  @param[in] request - Request message
- */
-Response getBIOSAttributeValueTable(BIOSTable& biosAttributeValueTable,
-                                    const BIOSTable& biosAttributeTable,
-                                    const BIOSStringTable& biosStringTable,
-                                    const pldm_msg* request)
-{
-    Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
-                      0);
-    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-    uint32_t nxtTransferHandle = 0;
-    uint8_t transferFlag = PLDM_START_AND_END;
-
-    if (!biosAttributeValueTable.isEmpty())
-    {
-        auto rc = encode_get_bios_table_resp(
-            request->hdr.instance_id, PLDM_SUCCESS, nxtTransferHandle,
-            transferFlag, nullptr, response.size(),
-            responsePtr); // filling up the header here
-        if (rc != PLDM_SUCCESS)
-        {
-            return CmdHandler::ccOnlyResponse(request, rc);
-        }
-
-        biosAttributeValueTable.load(response);
-        return response;
-    }
-
-    Table attributeValueTable;
-    Table attributeTable;
-    biosAttributeTable.load(attributeTable);
-    traverseBIOSAttrTable(
-        attributeTable,
-        [&biosStringTable, &attributeValueTable](
-            const struct pldm_bios_attr_table_entry* tableEntry) {
-            constructAttrValueTableEntry(tableEntry, biosStringTable,
-                                         attributeValueTable);
-        });
-    if (attributeValueTable.empty())
-    {
-        return CmdHandler::ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
-    }
-    pldm::responder::utils::padAndChecksum(attributeValueTable);
-    biosAttributeValueTable.store(attributeValueTable);
-
-    response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES +
-                    attributeValueTable.size());
-    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-    auto rc = encode_get_bios_table_resp(
-        request->hdr.instance_id, PLDM_SUCCESS, nxtTransferHandle, transferFlag,
-        attributeValueTable.data(), response.size(), responsePtr);
-    if (rc != PLDM_SUCCESS)
-    {
-        return CmdHandler::ccOnlyResponse(request, rc);
-    }
-
-    return response;
-}
-
 Response Handler::getBIOSTable(const pldm_msg* request, size_t payloadLength)
 {
-    fs::create_directory(BIOS_TABLES_DIR);
-    auto response = internal::buildBIOSTables(request, payloadLength,
-                                              BIOS_JSONS_DIR, BIOS_TABLES_DIR);
+    uint32_t transferHandle{};
+    uint8_t transferOpFlag{};
+    uint8_t tableType{};
+
+    auto rc = decode_get_bios_table_req(request, payloadLength, &transferHandle,
+                                        &transferOpFlag, &tableType);
+    if (rc != PLDM_SUCCESS)
+    {
+        return ccOnlyResponse(request, rc);
+    }
+
+    auto table =
+        biosConfig.getBIOSTable(static_cast<pldm_bios_table_types>(tableType));
+    if (!table)
+    {
+        return ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
+    }
+
+    Response response(sizeof(pldm_msg_hdr) +
+                      PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES + table->size());
+    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+    rc = encode_get_bios_table_resp(
+        request->hdr.instance_id, PLDM_SUCCESS, 0 /* nxtTransferHandle */,
+        PLDM_START_AND_END, table->data(), response.size(), responsePtr);
+    if (rc != PLDM_SUCCESS)
+    {
+        return ccOnlyResponse(request, rc);
+    }
 
     return response;
 }
@@ -852,44 +242,14 @@
         return ccOnlyResponse(request, rc);
     }
 
-    fs::path tablesPath(BIOS_TABLES_DIR);
-    auto stringTablePath = tablesPath / stringTableFile;
-    BIOSTable biosStringTable(stringTablePath.c_str());
-    auto attrTablePath = tablesPath / attrTableFile;
-    BIOSTable biosAttributeTable(attrTablePath.c_str());
-    if (biosAttributeTable.isEmpty() || biosStringTable.isEmpty())
+    auto table = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
+    if (!table)
     {
         return ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
     }
 
-    auto attrValueTablePath = tablesPath / attrValTableFile;
-    BIOSTable biosAttributeValueTable(attrValueTablePath.c_str());
-
-    if (biosAttributeValueTable.isEmpty())
-    {
-        Table attributeValueTable;
-        Table attributeTable;
-        biosAttributeTable.load(attributeTable);
-        traverseBIOSAttrTable(
-            attributeTable,
-            [&biosStringTable, &attributeValueTable](
-                const struct pldm_bios_attr_table_entry* tableEntry) {
-                constructAttrValueTableEntry(tableEntry, biosStringTable,
-                                             attributeValueTable);
-            });
-        if (attributeValueTable.empty())
-        {
-            return ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
-        }
-        pldm::responder::utils::padAndChecksum(attributeValueTable);
-        biosAttributeValueTable.store(attributeValueTable);
-    }
-
-    Response table;
-    biosAttributeValueTable.load(table);
-
     auto entry = pldm_bios_table_attr_value_find_by_handle(
-        table.data(), table.size(), attributeHandle);
+        table->data(), table->size(), attributeHandle);
     if (entry == nullptr)
     {
         return ccOnlyResponse(request, PLDM_INVALID_BIOS_ATTR_HANDLE);
@@ -927,141 +287,11 @@
         return ccOnlyResponse(request, rc);
     }
 
-    fs::path tablesPath(BIOS_TABLES_DIR);
-    auto stringTablePath = tablesPath / stringTableFile;
-    BIOSStringTable biosStringTable(stringTablePath.c_str());
-    auto attrTablePath = tablesPath / attrTableFile;
-    BIOSTable biosAttributeTable(attrTablePath.c_str());
-    auto attrValueTablePath = tablesPath / attrValTableFile;
-    BIOSTable biosAttributeValueTable(attrValueTablePath.c_str());
-    // TODO: Construct attribute value table if it's empty. (another commit)
+    rc = biosConfig.setAttrValue(attributeField.ptr, attributeField.length);
 
-    Response srcTable;
-    biosAttributeValueTable.load(srcTable);
-
-    // Replace the old attribute with the new attribute, the size of table will
-    // change:
-    //   sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) -
-    //                      sizeof(oldAttribute) + pad(4-byte alignment, max =
-    //                      3)
-    // For simplicity, we use
-    //   sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) + 3
-    size_t destBufferLength = srcTable.size() + attributeField.length + 3;
-    Response destTable(destBufferLength);
-    size_t destTableLen = destTable.size();
-
-    rc = pldm_bios_table_attr_value_copy_and_update(
-        srcTable.data(), srcTable.size(), destTable.data(), &destTableLen,
-        attributeField.ptr, attributeField.length);
-    destTable.resize(destTableLen);
-
-    if (rc != PLDM_SUCCESS)
-    {
-        return ccOnlyResponse(request, rc);
-    }
-
-    rc = setAttributeValueOnDbus(&attributeField, biosAttributeTable,
-                                 biosStringTable);
-    if (rc != PLDM_SUCCESS)
-    {
-        return ccOnlyResponse(request, rc);
-    }
-
-    biosAttributeValueTable.store(destTable);
-
-    return ccOnlyResponse(request, PLDM_SUCCESS);
+    return ccOnlyResponse(request, rc);
 }
 
-namespace internal
-{
-
-Response buildBIOSTables(const pldm_msg* request, size_t payloadLength,
-                         const char* biosJsonDir, const char* biosTablePath)
-{
-    Response response(sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES,
-                      0);
-
-    if (setupConfig(biosJsonDir) != 0)
-    {
-        return CmdHandler::ccOnlyResponse(request, PLDM_BIOS_TABLE_UNAVAILABLE);
-    }
-
-    uint32_t transferHandle{};
-    uint8_t transferOpFlag{};
-    uint8_t tableType{};
-
-    auto rc = decode_get_bios_table_req(request, payloadLength, &transferHandle,
-                                        &transferOpFlag, &tableType);
-    if (rc != PLDM_SUCCESS)
-    {
-        return CmdHandler::ccOnlyResponse(request, rc);
-    }
-
-    BIOSTable biosStringTable(
-        (std::string(biosTablePath) + "/" + stringTableFile).c_str());
-    BIOSTable biosAttributeTable(
-        (std::string(biosTablePath) + "/" + attrTableFile).c_str());
-    BIOSTable biosAttributeValueTable(
-        (std::string(biosTablePath) + "/" + attrValTableFile).c_str());
-    switch (tableType)
-    {
-        case PLDM_BIOS_STRING_TABLE:
-        {
-            try
-            {
-                fs::remove(fs::path(std::string(BIOS_TABLES_DIR) + "/" +
-                                    stringTableFile));
-                fs::remove(fs::path(std::string(BIOS_TABLES_DIR) + "/" +
-                                    attrTableFile));
-                fs::remove(fs::path(std::string(BIOS_TABLES_DIR) + "/" +
-                                    attrValTableFile));
-            }
-            catch (const std::exception& e)
-            {
-            }
-
-            response = getBIOSStringTable(biosStringTable, request);
-        }
-        break;
-        case PLDM_BIOS_ATTR_TABLE:
-
-            if (biosStringTable.isEmpty())
-            {
-                rc = PLDM_BIOS_TABLE_UNAVAILABLE;
-            }
-            else
-            {
-                response = getBIOSAttributeTable(
-                    biosAttributeTable, biosStringTable, biosJsonDir, request);
-            }
-            break;
-        case PLDM_BIOS_ATTR_VAL_TABLE:
-            if (biosAttributeTable.isEmpty() || biosStringTable.isEmpty())
-            {
-                rc = PLDM_BIOS_TABLE_UNAVAILABLE;
-            }
-            else
-            {
-                response = getBIOSAttributeValueTable(biosAttributeValueTable,
-                                                      biosAttributeTable,
-                                                      biosStringTable, request);
-            }
-            break;
-        default:
-            rc = PLDM_INVALID_BIOS_TABLE_TYPE;
-            break;
-    }
-
-    if (rc != PLDM_SUCCESS)
-    {
-        return CmdHandler::ccOnlyResponse(request, rc);
-    }
-
-    return response;
-}
-
-} // namespace internal
-
 } // namespace bios
 } // namespace responder
 } // namespace pldm
diff --git a/libpldmresponder/bios.hpp b/libpldmresponder/bios.hpp
index d023ce9..be0d403 100644
--- a/libpldmresponder/bios.hpp
+++ b/libpldmresponder/bios.hpp
@@ -2,7 +2,7 @@
 
 #include "config.h"
 
-#include "bios_parser.hpp"
+#include "bios_config.hpp"
 #include "bios_table.hpp"
 #include "handler.hpp"
 
@@ -19,36 +19,12 @@
 namespace pldm
 {
 
-using AttributeHandle = uint16_t;
-using StringHandle = uint16_t;
-using PossibleValuesByHandle = std::vector<StringHandle>;
-
 namespace responder
 {
 
 namespace bios
 {
 
-using AttrTableEntryHandler =
-    std::function<void(const struct pldm_bios_attr_table_entry*)>;
-
-void traverseBIOSAttrTable(const bios::Table& BIOSAttrTable,
-                           AttrTableEntryHandler handler);
-
-namespace internal
-{
-
-/** @brief Constructs all the BIOS Tables
- *
- *  @param[in] request - Request message
- *  @param[in] payload_length - Request message payload length
- *  @param[in] biosJsonDir - path to fetch the BIOS json files
- *  @param[in] biosTablePath - path where the BIOS tables will be persisted
- */
-Response buildBIOSTables(const pldm_msg* request, size_t payloadLength,
-                         const char* biosJsonDir, const char* biosTablePath);
-} // namespace internal
-
 class Handler : public CmdHandler
 {
   public:
@@ -94,6 +70,9 @@
      */
     Response setBIOSAttributeCurrentValue(const pldm_msg* request,
                                           size_t payloadLength);
+
+  private:
+    BIOSConfig biosConfig;
 };
 
 } // namespace bios
diff --git a/libpldmresponder/bios_parser.cpp b/libpldmresponder/bios_parser.cpp
deleted file mode 100644
index 3a45f3d..0000000
--- a/libpldmresponder/bios_parser.cpp
+++ /dev/null
@@ -1,685 +0,0 @@
-#include "bios_parser.hpp"
-
-#include "bios_table.hpp"
-#include "utils.hpp"
-
-#include <cassert>
-#include <filesystem>
-#include <fstream>
-#include <iostream>
-#include <nlohmann/json.hpp>
-#include <optional>
-#include <set>
-
-#include "libpldm/bios.h"
-#include "libpldm/bios_table.h"
-
-namespace bios_parser
-{
-
-using namespace pldm::utils;
-using Json = nlohmann::json;
-namespace fs = std::filesystem;
-using namespace pldm::responder::bios;
-
-const std::vector<Json> emptyJsonList{};
-const Json emptyJson{};
-
-using AttrType = uint8_t;
-using Table = std::vector<uint8_t>;
-using BIOSJsonName = std::string;
-using AttrLookup = std::map<AttrName, std::optional<DBusMapping>>;
-
-const std::set<std::string> SupportedDbusPropertyTypes = {
-    "bool",     "uint8_t", "int16_t",  "uint16_t", "int32_t",
-    "uint32_t", "int64_t", "uint64_t", "double",   "string"};
-
-using BIOSStringHandler =
-    std::function<int(const Json& entry, Strings& strings)>;
-using AttrLookupHandler = std::function<int(const Json& entry, AttrLookup)>;
-using typeHandler = std::function<int(const Json& entry)>;
-
-Strings BIOSStrings;
-AttrLookup BIOSAttrLookup;
-
-const Strings& getStrings()
-{
-    return BIOSStrings;
-}
-
-int parseBIOSJsonFile(const fs::path& dirPath, const std::string& fileName,
-                      Json& fileData)
-{
-    int rc = 0;
-
-    fs::path filePath = dirPath / fileName;
-
-    std::ifstream jsonFile(filePath);
-    if (!jsonFile.is_open())
-    {
-        std::cerr << "BIOS config file does not exist, FILE="
-                  << filePath.c_str() << "\n";
-        rc = -1;
-    }
-    else
-    {
-        fileData = Json::parse(jsonFile, nullptr, false);
-        if (fileData.is_discarded())
-        {
-            std::cerr << "Parsing config file failed, FILE=" << filePath.c_str()
-                      << "\n";
-            rc = -1;
-        }
-    }
-
-    return rc;
-}
-
-namespace bios_enum
-{
-
-namespace internal
-{
-
-using Value = std::string;
-
-/** @brief Map of DBus property value to attribute value
- */
-using DbusValToValMap = std::map<PropertyValue, Value>;
-
-/** @brief Map containing the DBus property value to attribute value map for the
- * BIOS enumeration type attributes
- */
-std::map<AttrName, DbusValToValMap> dbusValToValMaps;
-
-/** @brief Map containing the possible and the default values for the BIOS
- *         enumeration type attributes.
- */
-AttrValuesMap valueMap;
-
-/** @brief Populate the mapping between D-Bus property value and attribute value
- *         for the BIOS enumeration attribute.
- *
- *  @param[in] type - type of the D-Bus property
- *  @param[in] dBusValues - json array of D-Bus property values
- *  @param[in] pv - Possible values for the BIOS enumeration attribute
- *
- */
-DbusValToValMap populateMapping(const std::string& type, const Json& dBusValues,
-                                const PossibleValues& pv)
-{
-    size_t pos = 0;
-    PropertyValue value;
-    DbusValToValMap valueMap;
-    for (auto it = dBusValues.begin(); it != dBusValues.end(); ++it, ++pos)
-    {
-        if (type == "uint8_t")
-        {
-            value = static_cast<uint8_t>(it.value());
-        }
-        else if (type == "uint16_t")
-        {
-            value = static_cast<uint16_t>(it.value());
-        }
-        else if (type == "uint32_t")
-        {
-            value = static_cast<uint32_t>(it.value());
-        }
-        else if (type == "uint64_t")
-        {
-            value = static_cast<uint64_t>(it.value());
-        }
-        else if (type == "int16_t")
-        {
-            value = static_cast<int16_t>(it.value());
-        }
-        else if (type == "int32_t")
-        {
-            value = static_cast<int32_t>(it.value());
-        }
-        else if (type == "int64_t")
-        {
-            value = static_cast<int64_t>(it.value());
-        }
-        else if (type == "bool")
-        {
-            value = static_cast<bool>(it.value());
-        }
-        else if (type == "double")
-        {
-            value = static_cast<double>(it.value());
-        }
-        else if (type == "string")
-        {
-            value = static_cast<std::string>(it.value());
-        }
-        else
-        {
-            std::cerr << "Unknown D-Bus property type, TYPE=" << type.c_str()
-                      << "\n";
-        }
-
-        valueMap.emplace(value, pv[pos]);
-    }
-
-    return valueMap;
-}
-} // namespace internal
-
-int setupBIOSStrings(const Json& entry, Strings& strings)
-{
-    Json pvs = entry.value("possible_values", emptyJsonList);
-
-    for (auto& pv : pvs)
-    {
-        strings.emplace_back(std::move(pv.get<std::string>()));
-    }
-
-    return 0;
-}
-
-int setup(const Json& entry)
-{
-    PossibleValues possibleValues;
-    DefaultValues defaultValues;
-
-    std::string attrName = entry.value("attribute_name", "");
-    Json pv = entry["possible_values"];
-    for (auto& val : pv)
-    {
-        possibleValues.emplace_back(std::move(val));
-    }
-    Json dv = entry["default_values"];
-    for (auto& val : dv)
-    {
-        defaultValues.emplace_back(std::move(val));
-    }
-    if (entry.count("dbus") != 0)
-    {
-        auto dbusEntry = entry.value("dbus", emptyJson);
-        std::string propertyType = dbusEntry.value("property_type", "");
-        Json propValues = dbusEntry["property_values"];
-        internal::dbusValToValMaps.emplace(
-            attrName, internal::populateMapping(propertyType, propValues,
-                                                possibleValues));
-    }
-    // Defaulting all the types of attributes to BIOSEnumeration
-    internal::valueMap.emplace(std::move(attrName),
-                               std::make_tuple(entry.count("dbus") == 0,
-                                               std::move(possibleValues),
-                                               std::move(defaultValues)));
-    return 0;
-}
-
-const AttrValuesMap& getValues()
-{
-    return internal::valueMap;
-}
-
-CurrentValues getAttrValue(const AttrName& attrName)
-{
-    const auto& dBusMap = BIOSAttrLookup.at(attrName);
-    CurrentValues currentValues;
-    PropertyValue propValue;
-
-    if (dBusMap == std::nullopt)
-    {
-        const auto& valueEntry = internal::valueMap.at(attrName);
-        const auto& [readOnly, possibleValues, currentValues] = valueEntry;
-        return currentValues;
-    }
-
-    const auto& dbusValToValMap = internal::dbusValToValMaps.at(attrName);
-    propValue = pldm::utils::DBusHandler().getDbusPropertyVariant(
-        dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
-        dBusMap->interface.c_str());
-
-    auto iter = dbusValToValMap.find(propValue);
-    if (iter != dbusValToValMap.end())
-    {
-        currentValues.push_back(iter->second);
-    }
-
-    return currentValues;
-}
-
-int setAttrValue(const AttrName& attrName,
-                 const pldm_bios_attr_val_table_entry* attrValueEntry,
-                 const pldm_bios_attr_table_entry* attrEntry,
-                 const BIOSStringTable& stringTable)
-{
-    const auto& dBusMap = BIOSAttrLookup.at(attrName);
-    if (dBusMap == std::nullopt)
-    {
-        return PLDM_SUCCESS;
-    }
-
-    uint8_t pvNum = pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry);
-    std::vector<uint16_t> pvHdls(pvNum, 0);
-    pldm_bios_table_attr_entry_enum_decode_pv_hdls(attrEntry, pvHdls.data(),
-                                                   pvNum);
-
-    uint8_t defNum =
-        pldm_bios_table_attr_value_entry_enum_decode_number(attrValueEntry);
-
-    assert(defNum == 1);
-
-    std::vector<uint8_t> currHdls(1, 0);
-    pldm_bios_table_attr_value_entry_enum_decode_handles(
-        attrValueEntry, currHdls.data(), currHdls.size());
-
-    auto valueString = stringTable.findString(pvHdls[currHdls[0]]);
-
-    const auto& dbusValToValMap = internal::dbusValToValMaps.at(attrName);
-
-    auto it = std::find_if(dbusValToValMap.begin(), dbusValToValMap.end(),
-                           [&valueString](const auto& typePair) {
-                               return typePair.second == valueString;
-                           });
-    if (it == dbusValToValMap.end())
-    {
-        std::cerr << "Invalid Enum Value\n";
-        return PLDM_ERROR;
-    }
-
-    pldm::utils::DBusHandler().setDbusProperty(dBusMap.value(), it->first);
-
-    return PLDM_SUCCESS;
-}
-
-} // namespace bios_enum
-
-namespace bios_string
-{
-
-/** @brief BIOS string types
- */
-enum BIOSStringEncoding
-{
-    UNKNOWN = 0x00,
-    ASCII = 0x01,
-    HEX = 0x02,
-    UTF_8 = 0x03,
-    UTF_16LE = 0x04,
-    UTF_16BE = 0x05,
-    VENDOR_SPECIFIC = 0xFF
-};
-
-const std::map<std::string, uint8_t> strTypeMap{
-    {"Unknown", UNKNOWN},
-    {"ASCII", ASCII},
-    {"Hex", HEX},
-    {"UTF-8", UTF_8},
-    {"UTF-16LE", UTF_16LE},
-    {"UTF-16LE", UTF_16LE},
-    {"Vendor Specific", VENDOR_SPECIFIC}};
-
-namespace internal
-{
-
-/** @brief Map containing the possible and the default values for the BIOS
- *         string type attributes.
- */
-AttrValuesMap valueMap;
-
-} // namespace internal
-
-int setup(const Json& jsonEntry)
-{
-
-    std::string attr = jsonEntry.value("attribute_name", "");
-    // Transfer string type from string to enum
-    std::string strTypeTmp = jsonEntry.value("string_type", "Unknown");
-    auto iter = strTypeMap.find(strTypeTmp);
-    if (iter == strTypeMap.end())
-    {
-        std::cerr << "Wrong string type, STRING_TYPE=" << strTypeTmp.c_str()
-                  << " ATTRIBUTE_NAME=" << attr.c_str() << "\n";
-        return -1;
-    }
-    uint8_t strType = iter->second;
-
-    uint16_t minStrLen = jsonEntry.value("minimum_string_length", 0);
-    uint16_t maxStrLen = jsonEntry.value("maximum_string_length", 0);
-    uint16_t defaultStrLen = jsonEntry.value("default_string_length", 0);
-    std::string defaultStr = jsonEntry.value("default_string", "");
-
-    pldm_bios_table_attr_entry_string_info info = {
-        0,     /* name handle */
-        false, /* read only */
-        strType, minStrLen, maxStrLen, defaultStrLen, defaultStr.data(),
-    };
-
-    const char* errmsg;
-    auto rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg);
-    if (rc != PLDM_SUCCESS)
-    {
-        std::cerr << "Wrong filed for string attribute, ATTRIBUTE_NAME="
-                  << attr.c_str() << " ERRMSG=" << errmsg
-                  << " MINIMUM_STRING_LENGTH=" << minStrLen
-                  << " MAXIMUM_STRING_LENGTH=" << maxStrLen
-                  << " DEFAULT_STRING_LENGTH=" << defaultStrLen
-                  << " DEFAULT_STRING=" << defaultStr.data() << "\n";
-        return -1;
-    }
-
-    // Defaulting all the types of attributes to BIOSString
-    internal::valueMap.emplace(
-        std::move(attr),
-        std::make_tuple(jsonEntry.count("dbus") == 0, strType, minStrLen,
-                        maxStrLen, defaultStrLen, std::move(defaultStr)));
-
-    return 0;
-}
-
-const AttrValuesMap& getValues()
-{
-    return internal::valueMap;
-}
-
-std::string getAttrValue(const AttrName& attrName)
-{
-    const auto& dBusMap = BIOSAttrLookup.at(attrName);
-    std::variant<std::string> propValue;
-
-    if (dBusMap == std::nullopt)
-    { // return default string
-        const auto& valueEntry = internal::valueMap.at(attrName);
-        return std::get<DefaultStr>(valueEntry);
-    }
-
-    return pldm::utils::DBusHandler().getDbusProperty<std::string>(
-        dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
-        dBusMap->interface.c_str());
-}
-
-std::string stringToUtf8(BIOSStringEncoding stringType,
-                         const std::vector<uint8_t>& data)
-{
-    switch (stringType)
-    {
-        case ASCII:
-        case UTF_8:
-        case HEX:
-            return std::string(data.begin(), data.end());
-        case UTF_16BE:
-        case UTF_16LE: // TODO
-            return std::string(data.begin(), data.end());
-        case VENDOR_SPECIFIC:
-            throw std::invalid_argument("Vendor Specific is unsupported");
-        case UNKNOWN:
-            throw std::invalid_argument("Unknown String Type");
-    }
-    throw std::invalid_argument("String Type Error");
-}
-
-int setAttrValue(const AttrName& attrName,
-                 const pldm_bios_attr_val_table_entry* attrValueEntry,
-                 const pldm_bios_attr_table_entry* attrEntry,
-                 const BIOSStringTable&)
-{
-    const auto& dBusMap = BIOSAttrLookup.at(attrName);
-    if (dBusMap == std::nullopt)
-    {
-        return PLDM_SUCCESS;
-    }
-
-    auto stringType =
-        pldm_bios_table_attr_entry_string_decode_string_type(attrEntry);
-
-    variable_field currentString{};
-    pldm_bios_table_attr_value_entry_string_decode_string(attrValueEntry,
-                                                          &currentString);
-    std::vector<uint8_t> data(currentString.ptr,
-                              currentString.ptr + currentString.length);
-
-    PropertyValue value =
-        stringToUtf8(static_cast<BIOSStringEncoding>(stringType), data);
-    pldm::utils::DBusHandler().setDbusProperty(dBusMap.value(), value);
-
-    return PLDM_SUCCESS;
-}
-
-} // namespace bios_string
-
-namespace bios_integer
-{
-
-AttrValuesMap valueMap;
-
-int setup(const Json& jsonEntry)
-{
-
-    std::string attr = jsonEntry.value("attribute_name", "");
-    // Transfer string type from string to enum
-
-    uint64_t lowerBound = jsonEntry.value("lower_bound", 0);
-    uint64_t upperBound = jsonEntry.value("upper_bound", 0);
-    uint32_t scalarIncrement = jsonEntry.value("scalar_increment", 1);
-    uint64_t defaultValue = jsonEntry.value("default_value", 0);
-    pldm_bios_table_attr_entry_integer_info info = {
-        0,     /* name handle*/
-        false, /* read only */
-        lowerBound, upperBound, scalarIncrement, defaultValue,
-    };
-    const char* errmsg = nullptr;
-    auto rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg);
-    if (rc != PLDM_SUCCESS)
-    {
-        std::cerr << "Wrong filed for integer attribute, ATTRIBUTE_NAME="
-                  << attr.c_str() << " ERRMSG=" << errmsg
-                  << " LOWER_BOUND=" << lowerBound
-                  << " UPPER_BOUND=" << upperBound
-                  << " DEFAULT_VALUE=" << defaultValue
-                  << " SCALAR_INCREMENT=" << scalarIncrement << "\n";
-        return -1;
-    }
-
-    valueMap.emplace(std::move(attr),
-                     std::make_tuple(jsonEntry.count("dbus") == 0, lowerBound,
-                                     upperBound, scalarIncrement,
-                                     defaultValue));
-
-    return 0;
-}
-
-const AttrValuesMap& getValues()
-{
-    return valueMap;
-}
-
-uint64_t getAttrValue(const AttrName& attrName)
-{
-    const auto& dBusMap = BIOSAttrLookup.at(attrName);
-    std::variant<std::string> propValue;
-
-    if (dBusMap == std::nullopt)
-    { // return default string
-        const auto& valueEntry = valueMap.at(attrName);
-        return std::get<AttrDefaultValue>(valueEntry);
-    }
-
-    return pldm::utils::DBusHandler().getDbusProperty<uint64_t>(
-        dBusMap->objectPath.c_str(), dBusMap->propertyName.c_str(),
-        dBusMap->interface.c_str());
-}
-
-int setAttrValue(const AttrName& attrName,
-                 const pldm_bios_attr_val_table_entry* attrValueEntry,
-                 const pldm_bios_attr_table_entry*, const BIOSStringTable&)
-{
-    const auto& dBusMap = BIOSAttrLookup.at(attrName);
-    if (dBusMap == std::nullopt)
-    {
-        return PLDM_SUCCESS;
-    }
-
-    uint64_t currentValue =
-        pldm_bios_table_attr_value_entry_integer_decode_cv(attrValueEntry);
-
-    PropertyValue value = static_cast<uint64_t>(currentValue);
-    pldm::utils::DBusHandler().setDbusProperty(dBusMap.value(), value);
-
-    return PLDM_SUCCESS;
-}
-
-} // namespace bios_integer
-
-const std::map<BIOSJsonName, BIOSStringHandler> BIOSStringHandlers = {
-    {bIOSEnumJson, bios_enum::setupBIOSStrings},
-};
-
-const std::map<BIOSJsonName, typeHandler> BIOSTypeHandlers = {
-    {bIOSEnumJson, bios_enum::setup},
-    {bIOSStrJson, bios_string::setup},
-    {bIOSIntegerJson, bios_integer::setup},
-};
-
-void setupBIOSStrings(const BIOSJsonName& jsonName, const Json& entry,
-                      Strings& strings)
-{
-    strings.emplace_back(entry.value("attribute_name", ""));
-    auto iter = BIOSStringHandlers.find(jsonName);
-    if (iter != BIOSStringHandlers.end())
-    {
-        iter->second(entry, strings);
-    }
-}
-
-void setupBIOSAttrLookup(const Json& jsonEntry, AttrLookup& lookup)
-{
-    std::optional<DBusMapping> dBusMap;
-    std::string attrName = jsonEntry.value("attribute_name", "");
-
-    if (jsonEntry.count("dbus") != 0)
-    {
-        auto dBusEntry = jsonEntry.value("dbus", emptyJson);
-        std::string objectPath = dBusEntry.value("object_path", "");
-        std::string interface = dBusEntry.value("interface", "");
-        std::string propertyName = dBusEntry.value("property_name", "");
-        std::string propertyType = dBusEntry.value("property_type", "");
-        if (!objectPath.empty() && !interface.empty() &&
-            !propertyName.empty() &&
-            (SupportedDbusPropertyTypes.find(propertyType) !=
-             SupportedDbusPropertyTypes.end()))
-        {
-            dBusMap = std::optional<DBusMapping>(
-                {objectPath, interface, propertyName, propertyType});
-        }
-        else
-        {
-            std::cerr << "Invalid dbus config, OBJPATH="
-                      << dBusMap->objectPath.c_str()
-                      << " INTERFACE=" << dBusMap->interface.c_str()
-                      << " PROPERTY_NAME=" << dBusMap->propertyName.c_str()
-                      << " PROPERTY_TYPE=" << dBusMap->propertyType.c_str()
-                      << "\n";
-        }
-    }
-    lookup.emplace(attrName, dBusMap);
-}
-
-int setupBIOSType(const BIOSJsonName& jsonName, const Json& entry)
-{
-    auto iter = BIOSTypeHandlers.find(jsonName);
-    if (iter != BIOSTypeHandlers.end())
-    {
-        iter->second(entry);
-    }
-    return 0;
-}
-
-const std::vector<BIOSJsonName> BIOSConfigFiles = {bIOSEnumJson, bIOSStrJson,
-                                                   bIOSIntegerJson};
-
-int setupConfig(const char* dirPath)
-{
-    if (!BIOSStrings.empty() && !BIOSAttrLookup.empty())
-    {
-        return 0;
-    }
-
-    fs::path dir(dirPath);
-    if (!fs::exists(dir) || fs::is_empty(dir))
-    {
-        std::cerr << "BIOS config directory does not exist or empty, DIR="
-                  << dirPath << "\n";
-        return -1;
-    }
-    for (auto jsonName : BIOSConfigFiles)
-    {
-        Json json;
-        if (parseBIOSJsonFile(dir, jsonName, json) < 0)
-        {
-            continue;
-        }
-        auto entries = json.value("entries", emptyJsonList);
-        for (auto& entry : entries)
-        {
-            setupBIOSStrings(jsonName, entry, BIOSStrings);
-            setupBIOSAttrLookup(entry, BIOSAttrLookup);
-            setupBIOSType(jsonName, entry);
-        }
-    }
-    if (BIOSStrings.empty())
-    { // means there is no attribute
-        std::cerr << "No attribute is found in the config directory, DIR="
-                  << dirPath << "\n";
-        return -1;
-    }
-    return 0;
-}
-
-using setAttrValueHandler = std::function<int(
-    const AttrName&, const pldm_bios_attr_val_table_entry*,
-    const pldm_bios_attr_table_entry*, const BIOSStringTable&)>;
-
-const std::map<AttrType, setAttrValueHandler> SetAttrValueMap{{
-    {PLDM_BIOS_STRING, bios_string::setAttrValue},
-    {PLDM_BIOS_STRING_READ_ONLY, bios_string::setAttrValue},
-    {PLDM_BIOS_ENUMERATION, bios_enum::setAttrValue},
-    {PLDM_BIOS_ENUMERATION_READ_ONLY, bios_enum::setAttrValue},
-    {PLDM_BIOS_INTEGER, bios_integer::setAttrValue},
-    {PLDM_BIOS_INTEGER_READ_ONLY, bios_integer::setAttrValue},
-
-}};
-
-int setAttributeValueOnDbus(const variable_field* attributeData,
-                            const BIOSTable& biosAttributeTable,
-                            const BIOSStringTable& stringTable)
-{
-    Table attributeTable;
-    biosAttributeTable.load(attributeTable);
-    auto attrValueEntry =
-        reinterpret_cast<const pldm_bios_attr_val_table_entry*>(
-            attributeData->ptr);
-
-    auto attrType =
-        pldm_bios_table_attr_value_entry_decode_attribute_type(attrValueEntry);
-    auto attrHandle = pldm_bios_table_attr_value_entry_decode_attribute_handle(
-        attrValueEntry);
-
-    auto attrEntry = pldm_bios_table_attr_find_by_handle(
-        attributeTable.data(), attributeTable.size(), attrHandle);
-
-    assert(attrEntry != nullptr);
-
-    auto attrNameHandle =
-        pldm_bios_table_attr_entry_decode_string_handle(attrEntry);
-
-    auto attrName = stringTable.findString(attrNameHandle);
-
-    try
-    {
-        auto rc = SetAttrValueMap.at(attrType)(attrName, attrValueEntry,
-                                               attrEntry, stringTable);
-        return rc;
-    }
-    catch (const std::exception& e)
-    {
-        std::cerr << "setAttributeValueOnDbus Error: " << e.what() << std::endl;
-        return PLDM_ERROR;
-    }
-}
-
-} // namespace bios_parser
diff --git a/libpldmresponder/bios_parser.hpp b/libpldmresponder/bios_parser.hpp
deleted file mode 100644
index 581ac1d..0000000
--- a/libpldmresponder/bios_parser.hpp
+++ /dev/null
@@ -1,153 +0,0 @@
-#pragma once
-
-#include "bios_table.hpp"
-
-#include <map>
-#include <string>
-#include <tuple>
-#include <variant>
-#include <vector>
-
-/*
- * BIOS Parser API usage:
- *
- * 1) bios_parser::getStrings gets all the attribute names and the preconfigured
- *    strings used in representing the values of the attributes. This will be
- *    used to populate the BIOS String table.
- *
- * 2) bios_parser::setupConfig has to be invoked to setup the lookup data
- *    structure all the attributes of that type. This API needs to be invoked
- *    before invoking bios_enum::getValues and bios_enum::getAttrValue.
- *
- * 3) bios_enum::getValues is invoked to populate the BIOS attribute table for
- *    BIOSEnumeration and BIOSEnumerationReadonly types.(similar API for other
- *    BIOS attribute types)
- *
- * 4) bios_enum::getAttrValue will return the current values for the BIOS
- *    enumeration attribute. If there is no D-Bus mapping for the attribute then
- *    default value is returned.(similar API for other BIOS attribute types).
- *
- */
-namespace bios_parser
-{
-
-using namespace pldm::responder::bios;
-using AttrName = std::string;
-using Strings = std::vector<std::string>;
-inline constexpr auto bIOSEnumJson = "enum_attrs.json";
-inline constexpr auto bIOSStrJson = "string_attrs.json";
-inline constexpr auto bIOSIntegerJson = "integer_attrs.json";
-
-/** @brief Get all the preconfigured strings
- *  @return all the preconfigurated strings
- */
-const Strings& getStrings();
-
-/** @brief Parse every BIOS Configuration JSON file in the directory path
- *  @param[in] dirPath - directory path where all the bios configuration JSON
- * files exist
- */
-int setupConfig(const char* dirPath);
-
-int setAttributeValueOnDbus(const variable_field* attributeData,
-                            const BIOSTable& attributeTable,
-                            const BIOSStringTable& stringTable);
-
-namespace bios_enum
-{
-
-using IsReadOnly = bool;
-using PossibleValues = std::vector<std::string>;
-using DefaultValues = std::vector<std::string>;
-using AttrValuesMap =
-    std::map<AttrName, std::tuple<IsReadOnly, PossibleValues, DefaultValues>>;
-
-/** @brief Get the possible values and the default values for the
- *         BIOSEnumeration and BIOSEnumerationReadOnly types
- *
- *  @return information needed to build the BIOS attribute table specific to
- *         BIOSEnumeration and BIOSEnumerationReadOnly types
- */
-const AttrValuesMap& getValues();
-
-using CurrentValues = std::vector<std::string>;
-
-/** @brief Get the current values for the BIOS Attribute
- *
- *  @param[in] attrName - BIOS attribute name
- *
- *  @return BIOS attribute value
- */
-CurrentValues getAttrValue(const AttrName& attrName);
-
-} // namespace bios_enum
-
-namespace bios_string
-{
-
-using IsReadOnly = bool;
-using StrType = uint8_t;
-using MinStrLen = uint16_t;
-using MaxStrLen = uint16_t;
-using DefaultStrLen = uint16_t;
-using DefaultStr = std::string;
-using AttrValuesMap =
-    std::map<AttrName, std::tuple<IsReadOnly, StrType, MinStrLen, MaxStrLen,
-                                  DefaultStrLen, DefaultStr>>;
-
-/** @brief Get the string related values and the default values for the
- *         BIOSString and BIOSStringReadOnly types
- *
- *  @return information needed to build the BIOS attribute table specific to
- *         BIOSString and BIOSStringReadOnly types
- */
-const AttrValuesMap& getValues();
-
-/** @brief Get the current values for the BIOS Attribute
- *
- *  @param[in] attrName - BIOS attribute name
- *
- *  @return BIOS attribute value
- */
-std::string getAttrValue(const AttrName& attrName);
-
-} // namespace bios_string
-
-namespace bios_integer
-{
-
-using IsReadOnly = bool;
-using LowerBound = uint64_t;
-using UpperBound = uint64_t;
-using ScalarIncrement = uint32_t;
-using DefaultValue = uint64_t;
-using AttrValues = std::tuple<IsReadOnly, LowerBound, UpperBound,
-                              ScalarIncrement, DefaultValue>;
-
-constexpr auto AttrIsReadOnly = 0;
-constexpr auto AttrLowerBound = 1;
-constexpr auto AttrUpperBound = 2;
-constexpr auto AttrScalarIncrement = 3;
-constexpr auto AttrDefaultValue = 4;
-
-using AttrValuesMap = std::map<AttrName, AttrValues>;
-
-/** @brief Get the values of all fields for the
- *         BIOSInteger and BIOSIntegerReadOnly types
- *
- *  @return information needed to build the BIOS attribute table specific to
- *         BIOSInteger and BIOSIntegerReadOnly types
- */
-const AttrValuesMap& getValues();
-
-/** @brief Get the current values for the BIOS Attribute
- *
- *  @param[in] attrName - BIOS attribute name
- *
- *  @return BIOS attribute value
- */
-uint64_t getAttrValue(const AttrName& attrName);
-
-} // namespace bios_integer
-
-} // namespace bios_parser
diff --git a/libpldmresponder/meson.build b/libpldmresponder/meson.build
index 88dfdab..c178269 100644
--- a/libpldmresponder/meson.build
+++ b/libpldmresponder/meson.build
@@ -9,7 +9,6 @@
   'base.cpp',
   'bios.cpp',
   'bios_table.cpp',
-  'bios_parser.cpp',
   'bios_attribute.cpp',
   'bios_string_attribute.cpp',
   'bios_integer_attribute.cpp',
diff --git a/test/libpldmresponder_bios_test.cpp b/test/libpldmresponder_bios_test.cpp
index ebef789..3ca0c38 100644
--- a/test/libpldmresponder_bios_test.cpp
+++ b/test/libpldmresponder_bios_test.cpp
@@ -1,5 +1,4 @@
 #include "libpldmresponder/bios.hpp"
-#include "libpldmresponder/bios_parser.hpp"
 #include "libpldmresponder/bios_table.hpp"
 
 #include <string.h>
@@ -18,7 +17,6 @@
 using namespace pldm::responder;
 using namespace pldm::responder::bios;
 using namespace pldm::responder::utils;
-using namespace bios_parser;
 
 TEST(epochToBCDTime, testTime)
 {
@@ -66,607 +64,4 @@
     timeSec = timeToEpoch(sec, min, hours, day, month, year);
 
     EXPECT_EQ(ret, timeSec);
-}
-
-TEST(GetBIOSStrings, allScenarios)
-{
-    using namespace bios_parser;
-    // All the BIOS Strings in the BIOS JSON config files.
-    Strings vec{"HMCManagedState",
-                "On",
-                "Off",
-                "FWBootSide",
-                "Perm",
-                "Temp",
-                "InbandCodeUpdate",
-                "Allowed",
-                "NotAllowed",
-                "CodeUpdatePolicy",
-                "Concurrent",
-                "Disruptive",
-                "VDD_AVSBUS_RAIL",
-                "SBE_IMAGE_MINIMUM_VALID_ECS",
-                "INTEGER_INVALID_CASE",
-                "str_example1",
-                "str_example2",
-                "str_example3"};
-
-    Strings nullVec{};
-
-    // Invalid directory
-    bios_parser::setupConfig("./bios_json_invalid");
-    auto strings = bios_parser::getStrings();
-    ASSERT_EQ(strings == nullVec, true);
-
-    bios_parser::setupConfig("./bios_jsons");
-    strings = bios_parser::getStrings();
-    std::sort(strings.begin(), strings.end());
-    std::sort(vec.begin(), vec.end());
-    ASSERT_EQ(strings == vec, true);
-}
-
-TEST(getAttrValue, enumScenarios)
-{
-    using namespace bios_parser::bios_enum;
-    // All the BIOS Strings in the BIOS JSON config files.
-    AttrValuesMap valueMap{
-        {"HMCManagedState", {false, {"On", "Off"}, {"On"}}},
-        {"FWBootSide", {false, {"Perm", "Temp"}, {"Perm"}}},
-        {"InbandCodeUpdate", {false, {"Allowed", "NotAllowed"}, {"Allowed"}}},
-        {"CodeUpdatePolicy",
-         {true, {"Concurrent", "Disruptive"}, {"Concurrent"}}}};
-
-    auto values = bios_parser::bios_enum::getValues();
-    ASSERT_EQ(valueMap == values, true);
-
-    bios_parser::bios_enum::CurrentValues cv{"Concurrent"};
-    auto value = bios_parser::bios_enum::getAttrValue("CodeUpdatePolicy");
-    ASSERT_EQ(value == cv, true);
-
-    // Invalid attribute name
-    ASSERT_THROW(bios_parser::bios_enum::getAttrValue("CodeUpdatePolic"),
-                 std::out_of_range);
-}
-
-TEST(getAttrValue, stringScenarios)
-{
-    // All the BIOS Strings in the BIOS JSON config files.
-    bios_parser::bios_string::AttrValuesMap valueMap{
-        {"str_example1", {false, 1, 1, 100, 3, "abc"}},
-        {"str_example2", {false, 2, 0, 100, 0, ""}},
-        {"str_example3", {true, 0, 1, 100, 2, "ef"}}};
-
-    auto values = bios_parser::bios_string::getValues();
-    ASSERT_EQ(valueMap == values, true);
-
-    // Test the attribute without dbus
-    std::string cv = "ef";
-    auto value = bios_parser::bios_string::getAttrValue("str_example3");
-    EXPECT_EQ(value, cv);
-
-    // Invalid attribute name
-    ASSERT_THROW(bios_parser::bios_string::getAttrValue("str_example"),
-                 std::out_of_range);
-}
-
-TEST(getAttrValue, integerScenarios)
-{
-    using namespace bios_parser::bios_integer;
-    AttrValuesMap valueMap{
-        {"VDD_AVSBUS_RAIL", {false, 0, 15, 1, 0}},
-        {"SBE_IMAGE_MINIMUM_VALID_ECS", {true, 1, 15, 1, 2}}};
-
-    auto values = getValues();
-    EXPECT_EQ(valueMap, values);
-    auto value = getAttrValue("SBE_IMAGE_MINIMUM_VALID_ECS");
-    EXPECT_EQ(value, 2);
-
-    EXPECT_THROW(getAttrValue("VDM"), std::out_of_range);
-}
-
-TEST(traverseBIOSTable, attrTableScenarios)
-{
-    std::vector<uint8_t> enumEntry{
-        0, 0, /* attr handle */
-        0,    /* attr type */
-        1, 0, /* attr name handle */
-        2,    /* number of possible value */
-        2, 0, /* possible value handle */
-        3, 0, /* possible value handle */
-        1,    /* number of default value */
-        0     /* defaut value string handle index */
-    };
-    std::vector<uint8_t> stringEntry{
-        4,   0,       /* attr handle */
-        1,            /* attr type */
-        12,  0,       /* attr name handle */
-        1,            /* string type */
-        1,   0,       /* minimum length of the string in bytes */
-        100, 0,       /* maximum length of the string in bytes */
-        3,   0,       /* length of default string in length */
-        'a', 'b', 'c' /* default string  */
-    };
-    std::vector<uint8_t> table;
-    table.insert(table.end(), enumEntry.begin(), enumEntry.end());
-    table.insert(table.end(), stringEntry.begin(), stringEntry.end());
-    auto padSize = ((table.size() % 4) ? (4 - table.size() % 4) : 0);
-
-    table.insert(table.end(), padSize, 0);
-    table.insert(table.end(), sizeof(uint32_t) /*checksum*/, 0);
-
-    pldm::responder::bios::traverseBIOSAttrTable(
-        table, [&](const struct pldm_bios_attr_table_entry* entry) {
-            int rc;
-            switch (entry->attr_type)
-            {
-                case 0:
-                    rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
-                    EXPECT_EQ(rc, 0);
-                    break;
-                case 1:
-                    rc = std::memcmp(entry, stringEntry.data(),
-                                     stringEntry.size());
-                    EXPECT_EQ(rc, 0);
-                    break;
-                default:
-                    break;
-            }
-        });
-}
-
-namespace fs = std::filesystem;
-class TestAllBIOSTables : public ::testing::Test
-{
-  public:
-    static void SetUpTestCase() // will execute once at the begining of all
-                                // TestAllBIOSTables objects
-    {
-        char tmpdir[] = "/tmp/allBIOSTables.XXXXXX";
-        biosPath = fs::path(mkdtemp(tmpdir));
-    }
-
-    static void TearDownTestCase() // will be executed once at th eend of all
-                                   // TestAllBIOSTables objects
-    {
-        fs::remove_all(biosPath);
-    }
-
-    static fs::path biosPath;
-};
-
-fs::path TestAllBIOSTables::biosPath;
-
-TEST_F(TestAllBIOSTables, GetBIOSTableTestBadRequest)
-{
-    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
-        requestPayload{};
-    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
-    struct pldm_get_bios_table_req* req =
-        (struct pldm_get_bios_table_req*)request->payload;
-    req->transfer_handle = 9;
-    req->transfer_op_flag = PLDM_GET_FIRSTPART;
-    req->table_type = 0xFF;
-
-    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
-
-    auto response = internal::buildBIOSTables(request, requestPayloadLength,
-                                              "./bios_jsons", biosPath.c_str());
-    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-
-    struct pldm_get_bios_table_resp* resp =
-        reinterpret_cast<struct pldm_get_bios_table_resp*>(
-            responsePtr->payload);
-
-    ASSERT_EQ(PLDM_INVALID_BIOS_TABLE_TYPE, resp->completion_code);
-}
-
-TEST_F(TestAllBIOSTables, buildBIOSTablesTestBadRequest)
-{
-    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
-        requestPayload{};
-    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
-    struct pldm_get_bios_table_req* req =
-        (struct pldm_get_bios_table_req*)request->payload;
-    req->transfer_handle = 9;
-    req->transfer_op_flag = PLDM_GET_FIRSTPART;
-    req->table_type = PLDM_BIOS_ATTR_VAL_TABLE;
-
-    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
-
-    auto response = internal::buildBIOSTables(request, requestPayloadLength,
-                                              "./bios_jsons", biosPath.c_str());
-    auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-    struct pldm_get_bios_table_resp* resp =
-        reinterpret_cast<struct pldm_get_bios_table_resp*>(
-            responsePtr->payload);
-    ASSERT_EQ(PLDM_BIOS_TABLE_UNAVAILABLE, resp->completion_code);
-
-    req->table_type = PLDM_BIOS_ATTR_TABLE;
-    response = internal::buildBIOSTables(request, requestPayloadLength,
-                                         "./bios_jsons", biosPath.c_str());
-    responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-    resp = reinterpret_cast<struct pldm_get_bios_table_resp*>(
-        responsePtr->payload);
-    ASSERT_EQ(PLDM_BIOS_TABLE_UNAVAILABLE, resp->completion_code);
-}
-
-TEST_F(TestAllBIOSTables, GetBIOSStringTableTestGoodRequest)
-{
-    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
-        requestPayload{};
-    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
-    struct pldm_get_bios_table_req* req =
-        (struct pldm_get_bios_table_req*)request->payload;
-    req->transfer_handle = 9;
-    req->transfer_op_flag = PLDM_GET_FIRSTPART;
-    req->table_type = PLDM_BIOS_STRING_TABLE;
-
-    Strings biosStrings = getStrings();
-    std::sort(biosStrings.begin(), biosStrings.end());
-    biosStrings.erase(std::unique(biosStrings.begin(), biosStrings.end()),
-                      biosStrings.end());
-
-    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
-    uint8_t times = 0;
-    while (times < 2)
-    { // first time fresh table second time existing table
-        auto response = internal::buildBIOSTables(
-            request, requestPayloadLength, "./bios_jsons", biosPath.c_str());
-        auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-
-        struct pldm_get_bios_table_resp* resp =
-            reinterpret_cast<struct pldm_get_bios_table_resp*>(
-                responsePtr->payload);
-
-        ASSERT_EQ(0, resp->completion_code);
-        ASSERT_EQ(0, resp->next_transfer_handle);
-        ASSERT_EQ(PLDM_START_AND_END, resp->transfer_flag);
-
-        uint16_t strLen = 0;
-        uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
-
-        for (auto elem : biosStrings)
-        {
-            struct pldm_bios_string_table_entry* ptr =
-                reinterpret_cast<struct pldm_bios_string_table_entry*>(
-                    tableData);
-            strLen = ptr->string_length;
-            ASSERT_EQ(strLen, elem.size());
-            ASSERT_EQ(0, memcmp(elem.c_str(), ptr->name, strLen));
-            tableData += (sizeof(pldm_bios_string_table_entry) - 1) + strLen;
-
-        } // end for
-        times++;
-    }
-}
-
-TEST_F(TestAllBIOSTables, getBIOSAttributeTableTestGoodRequest)
-{
-    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
-        requestPayload{};
-    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
-    struct pldm_get_bios_table_req* req =
-        (struct pldm_get_bios_table_req*)request->payload;
-    req->transfer_handle = 9;
-    req->transfer_op_flag = PLDM_GET_FIRSTPART;
-    req->table_type = PLDM_BIOS_ATTR_TABLE;
-
-    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
-
-    uint8_t times = 0;
-    while (times < 2)
-    { // first time fresh table second time existing table
-        auto response = internal::buildBIOSTables(
-            request, requestPayloadLength, "./bios_jsons", biosPath.c_str());
-        auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-
-        struct pldm_get_bios_table_resp* resp =
-            reinterpret_cast<struct pldm_get_bios_table_resp*>(
-                responsePtr->payload);
-
-        ASSERT_EQ(0, resp->completion_code);
-        ASSERT_EQ(0, resp->next_transfer_handle);
-        ASSERT_EQ(PLDM_START_AND_END, resp->transfer_flag);
-
-        uint32_t attrTableLen =
-            response.size() - sizeof(pldm_msg_hdr) -
-            (sizeof(resp->completion_code) +
-             sizeof(resp->next_transfer_handle) + sizeof(resp->transfer_flag));
-        uint32_t traversed = 0;
-        uint16_t attrHdl = 0;
-        uint16_t stringHdl = 0;
-        uint8_t attrType = 0;
-        uint8_t numPosVals = 0;
-        uint8_t numDefVals = 0;
-        uint8_t defIndex = 0;
-
-        uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
-        while (1)
-        {
-            struct pldm_bios_attr_table_entry* ptr =
-                reinterpret_cast<struct pldm_bios_attr_table_entry*>(tableData);
-            attrHdl = ptr->attr_handle;
-            attrType = ptr->attr_type;
-            EXPECT_EQ(0, attrHdl);
-            EXPECT_EQ(PLDM_BIOS_ENUMERATION_READ_ONLY, attrType);
-            stringHdl = ptr->string_handle;
-            EXPECT_EQ(stringHdl, 1);
-            tableData += sizeof(attrHdl) + sizeof(attrType) + sizeof(stringHdl);
-            numPosVals = *tableData;
-            EXPECT_EQ(numPosVals, 2);
-            traversed += sizeof(attrHdl) + sizeof(attrType) + sizeof(stringHdl);
-            traversed += sizeof(numPosVals);
-            PossibleValuesByHandle possiVals;
-            tableData++;
-            uint16_t* temp = reinterpret_cast<uint16_t*>(tableData);
-            uint32_t i = 0;
-            while (i < numPosVals)
-            {
-                uint16_t val = *temp;
-                possiVals.push_back(val);
-                temp++;
-                i++;
-            }
-            EXPECT_EQ(possiVals.size(), 2);
-            tableData += numPosVals * sizeof(stringHdl);
-            traversed += numPosVals * sizeof(stringHdl);
-            numDefVals = *tableData;
-            EXPECT_EQ(numDefVals, 1);
-            tableData += numDefVals * sizeof(defIndex);
-            traversed += numDefVals + sizeof(numDefVals);
-
-            break; // test for first row only
-
-            if ((attrTableLen - traversed) < 8)
-            {
-                // reached pad
-                break;
-            }
-
-        } // end while
-        times++;
-    }
-
-} // end TEST
-
-TEST_F(TestAllBIOSTables, getBIOSAttributeValueTableTestGoodRequest)
-{
-    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
-        requestPayload{};
-    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
-    struct pldm_get_bios_table_req* req =
-        (struct pldm_get_bios_table_req*)request->payload;
-    req->transfer_handle = 9;
-    req->transfer_op_flag = PLDM_GET_FIRSTPART;
-    req->table_type = PLDM_BIOS_ATTR_VAL_TABLE;
-
-    std::string attrName("CodeUpdatePolicy");
-    bios_enum::CurrentValues currVals = bios_enum::getAttrValue(attrName);
-
-    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
-
-    uint8_t times = 0;
-    while (times < 2)
-    { // first time frest table second time existing table
-        auto response = internal::buildBIOSTables(
-            request, requestPayloadLength, "./bios_jsons", biosPath.c_str());
-        auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-
-        struct pldm_get_bios_table_resp* resp =
-            reinterpret_cast<struct pldm_get_bios_table_resp*>(
-                responsePtr->payload);
-
-        ASSERT_EQ(0, resp->completion_code);
-        ASSERT_EQ(0, resp->next_transfer_handle);
-        ASSERT_EQ(PLDM_START_AND_END, resp->transfer_flag);
-
-        uint32_t attrValTableLen =
-            response.size() - sizeof(pldm_msg_hdr) -
-            (sizeof(resp->completion_code) +
-             sizeof(resp->next_transfer_handle) + sizeof(resp->transfer_flag));
-        uint32_t traversed = 0;
-        uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
-
-        uint16_t attrHdl;
-        uint8_t attrType;
-        uint8_t numCurrVals;
-        uint8_t currValStrIndex;
-
-        while (1)
-        {
-            struct pldm_bios_attr_val_table_entry* ptr =
-                reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
-                    tableData);
-            attrHdl = ptr->attr_handle;
-            attrType = ptr->attr_type;
-            EXPECT_EQ(0, attrHdl);
-            EXPECT_EQ(PLDM_BIOS_ENUMERATION_READ_ONLY, attrType);
-            tableData += sizeof(attrHdl) + sizeof(attrType);
-            traversed += sizeof(attrHdl) + sizeof(attrType);
-            numCurrVals = *tableData;
-            EXPECT_EQ(1, numCurrVals);
-            tableData += sizeof(numCurrVals);
-            traversed += sizeof(numCurrVals);
-            currValStrIndex = *tableData;
-            EXPECT_EQ(0, currValStrIndex);
-            tableData += numCurrVals;
-            traversed += numCurrVals;
-            break; // testing for first row
-            if ((attrValTableLen - traversed) < 8)
-            {
-                break;
-            }
-        }
-        times++;
-    }
-
-} // end TEST
-
-class TestSingleTypeBIOSTable : public ::testing::Test
-{
-  public:
-    void SetUp() override
-    { // will be executed before each individual test defined
-        // in TestSingleTypeBIOSTable
-        char tmpdir[] = "/tmp/singleTypeBIOSTable.XXXXXX";
-        destBIOSPath = fs::path(mkdtemp(tmpdir));
-    }
-
-    void TearDown() override
-    { // will be executed after each individual test
-        // defined in TestSingleTypeBIOSTable
-        fs::remove_all(destBIOSPath);
-    }
-
-    void CopySingleJsonFile(std::string file)
-    {
-        fs::path srcDir("./bios_jsons");
-        fs::path srcBIOSPath = srcDir / file;
-        std::filesystem::copy(srcBIOSPath, destBIOSPath);
-    }
-
-    fs::path destBIOSPath;
-};
-
-TEST_F(TestSingleTypeBIOSTable, getBIOSAttributeValueTableBasedOnStringTypeTest)
-{
-    // Copy string json file to the destination
-    TestSingleTypeBIOSTable::CopySingleJsonFile(bios_parser::bIOSStrJson);
-    auto fpath = TestSingleTypeBIOSTable::destBIOSPath.c_str();
-
-    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
-        requestPayload{};
-    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
-    struct pldm_get_bios_table_req* req =
-        (struct pldm_get_bios_table_req*)request->payload;
-
-    // Get string table with string json file only
-    req->transfer_handle = 9;
-    req->transfer_op_flag = PLDM_GET_FIRSTPART;
-    req->table_type = PLDM_BIOS_STRING_TABLE;
-
-    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
-    auto str_response =
-        internal::buildBIOSTables(request, requestPayloadLength, fpath, fpath);
-
-    // Get attribute table with string json file only
-    req->transfer_handle = 9;
-    req->transfer_op_flag = PLDM_GET_FIRSTPART;
-    req->table_type = PLDM_BIOS_ATTR_TABLE;
-
-    auto attr_response =
-        internal::buildBIOSTables(request, requestPayloadLength, fpath, fpath);
-
-    // Get attribute value table with string type
-    req->transfer_handle = 9;
-    req->transfer_op_flag = PLDM_GET_FIRSTPART;
-    req->table_type = PLDM_BIOS_ATTR_VAL_TABLE;
-
-    // Test attribute str_example3 here, which has no dbus
-    for (uint8_t times = 0; times < 2; times++)
-    { // first time first table second time existing table
-        auto response = internal::buildBIOSTables(request, requestPayloadLength,
-                                                  fpath, fpath);
-        auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-
-        struct pldm_get_bios_table_resp* resp =
-            reinterpret_cast<struct pldm_get_bios_table_resp*>(
-                responsePtr->payload);
-
-        ASSERT_EQ(0, resp->completion_code);
-        ASSERT_EQ(0, resp->next_transfer_handle);
-        ASSERT_EQ(PLDM_START_AND_END, resp->transfer_flag);
-
-        uint32_t attrValTableLen =
-            response.size() - sizeof(pldm_msg_hdr) -
-            (sizeof(struct pldm_get_bios_table_resp) - 1);
-        uint32_t traversed = 0;
-        uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
-
-        while (true)
-        {
-            struct pldm_bios_attr_val_table_entry* ptr =
-                reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
-                    tableData);
-            uint16_t attrHdl = ptr->attr_handle;
-            uint8_t attrType = ptr->attr_type;
-            EXPECT_EQ(PLDM_BIOS_STRING_READ_ONLY, attrType);
-            tableData += sizeof(attrHdl) + sizeof(attrType);
-            traversed += sizeof(attrHdl) + sizeof(attrType);
-            auto sizeDefaultStr = *(reinterpret_cast<uint16_t*>(tableData));
-            EXPECT_EQ(2, sizeDefaultStr);
-            tableData += sizeof(uint16_t);
-            traversed += sizeof(uint16_t);
-            EXPECT_EQ('e', *tableData);
-            EXPECT_EQ('f', *(tableData + 1));
-            tableData += sizeDefaultStr;
-            traversed += sizeDefaultStr;
-            break; // testing for first row
-            if ((attrValTableLen - traversed) < 8)
-            {
-                break;
-            }
-        }
-    }
-
-} // end TEST
-
-TEST_F(TestSingleTypeBIOSTable,
-       getBIOSAttributeValueTableBasedOnIntegerTypeTest)
-{
-    // Copy integer json file to the destination
-    TestSingleTypeBIOSTable::CopySingleJsonFile(bios_parser::bIOSIntegerJson);
-    auto fpath = TestSingleTypeBIOSTable::destBIOSPath.c_str();
-
-    std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
-        requestPayload{};
-    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
-    struct pldm_get_bios_table_req* req =
-        (struct pldm_get_bios_table_req*)request->payload;
-
-    // Get string table with integer json file only
-    req->transfer_handle = 9;
-    req->transfer_op_flag = PLDM_GET_FIRSTPART;
-    req->table_type = PLDM_BIOS_STRING_TABLE;
-
-    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
-    internal::buildBIOSTables(request, requestPayloadLength, fpath, fpath);
-
-    // Get attribute table with integer json file only
-    req->transfer_handle = 9;
-    req->transfer_op_flag = PLDM_GET_FIRSTPART;
-    req->table_type = PLDM_BIOS_ATTR_TABLE;
-
-    auto attr_response =
-        internal::buildBIOSTables(request, requestPayloadLength, fpath, fpath);
-
-    // Get attribute value table with integer type
-    req->transfer_handle = 9;
-    req->transfer_op_flag = PLDM_GET_FIRSTPART;
-    req->table_type = PLDM_BIOS_ATTR_VAL_TABLE;
-
-    // Test attribute SBE_IMAGE_MINIMUM_VALID_ECS here, which has no dbus
-    for (uint8_t times = 0; times < 2; times++)
-    { // first time first table second time existing table
-        auto response = internal::buildBIOSTables(request, requestPayloadLength,
-                                                  fpath, fpath);
-        auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-
-        struct pldm_get_bios_table_resp* resp =
-            reinterpret_cast<struct pldm_get_bios_table_resp*>(
-                responsePtr->payload);
-
-        EXPECT_EQ(0, resp->completion_code);
-        EXPECT_EQ(0, resp->next_transfer_handle);
-        EXPECT_EQ(PLDM_START_AND_END, resp->transfer_flag);
-        uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
-        auto ptr =
-            reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(tableData);
-        uint16_t attrHdl = ptr->attr_handle;
-        uint8_t attrType = ptr->attr_type;
-        EXPECT_EQ(PLDM_BIOS_INTEGER_READ_ONLY, attrType);
-        tableData += sizeof(attrHdl) + sizeof(attrType);
-        auto cv = *(reinterpret_cast<uint64_t*>(tableData));
-        EXPECT_EQ(2, cv);
-    }
-}
+}
\ No newline at end of file
