Revamped code for VPD parser
The commit removes all the pre-existing code from the branch
and pushes the revamped code.
Major modification includes:
- Movement from multi exe to single daemon model.
- Multithreaded approach to parse FRU VPD.
- Better error handling.
- Refactored code for performance optimization.
Note: This code supports all the existing functionalities as it is.
Change-Id: I1ddce1f0725ac59020b72709689a1013643bda8b
Signed-off-by: Sunny Srivastava <sunnsr25@in.ibm.com>
diff --git a/vpd-manager/src/parser_factory.cpp b/vpd-manager/src/parser_factory.cpp
new file mode 100644
index 0000000..546e67b
--- /dev/null
+++ b/vpd-manager/src/parser_factory.cpp
@@ -0,0 +1,140 @@
+#include "parser_factory.hpp"
+
+#include "constants.hpp"
+#include "ddimm_parser.hpp"
+#include "exceptions.hpp"
+#include "ipz_parser.hpp"
+#include "isdimm_parser.hpp"
+#include "keyword_vpd_parser.hpp"
+
+namespace vpd
+{
+
+/**
+ * @brief Type of VPD formats.
+ */
+enum vpdType
+{
+ IPZ_VPD, /**< IPZ VPD type */
+ KEYWORD_VPD, /**< Keyword VPD type */
+ DDR4_DDIMM_MEMORY_VPD, /**< DDR4 DDIMM Memory VPD type */
+ DDR5_DDIMM_MEMORY_VPD, /**< DDR5 DDIMM Memory VPD type */
+ DDR4_ISDIMM_MEMORY_VPD, /**< DDR4 ISDIMM Memory VPD type */
+ DDR5_ISDIMM_MEMORY_VPD, /**< DDR5 ISDIMM Memory VPD type */
+ INVALID_VPD_FORMAT /**< Invalid VPD type */
+};
+
+/**
+ * @brief API to get the type of VPD.
+ *
+ * @param[in] i_vpdVector - VPD file content
+ *
+ * @return Type of VPD data, "INVALID_VPD_FORMAT" in case of unknown type.
+ */
+static vpdType vpdTypeCheck(const types::BinaryVector& i_vpdVector)
+{
+ if (i_vpdVector[constants::IPZ_DATA_START] == constants::IPZ_DATA_START_TAG)
+ {
+ return vpdType::IPZ_VPD;
+ }
+ else if (i_vpdVector[constants::KW_VPD_DATA_START] ==
+ constants::KW_VPD_START_TAG)
+ {
+ return vpdType::KEYWORD_VPD;
+ }
+ else if (((i_vpdVector[constants::SPD_BYTE_3] &
+ constants::SPD_BYTE_BIT_0_3_MASK) ==
+ constants::SPD_MODULE_TYPE_DDIMM))
+ {
+ std::string l_is11SFormat;
+ if (i_vpdVector.size() > (constants::DDIMM_11S_BARCODE_START +
+ constants::DDIMM_11S_BARCODE_LEN))
+ {
+ // Read first 3 Bytes to check the 11S bar code format
+ for (uint8_t l_index = 0; l_index < constants::DDIMM_11S_FORMAT_LEN;
+ l_index++)
+ {
+ l_is11SFormat +=
+ i_vpdVector[constants::DDIMM_11S_BARCODE_START + l_index];
+ }
+ }
+
+ if (l_is11SFormat.compare(constants::DDIMM_11S_BARCODE_START_TAG) == 0)
+ {
+ // DDIMM memory VPD format
+ if ((i_vpdVector[constants::SPD_BYTE_2] &
+ constants::SPD_BYTE_MASK) == constants::SPD_DRAM_TYPE_DDR5)
+ {
+ return vpdType::DDR5_DDIMM_MEMORY_VPD;
+ }
+
+ if ((i_vpdVector[constants::SPD_BYTE_2] &
+ constants::SPD_BYTE_MASK) == constants::SPD_DRAM_TYPE_DDR4)
+ {
+ return vpdType::DDR4_DDIMM_MEMORY_VPD;
+ }
+ }
+
+ logging::logMessage("11S format is not found in the DDIMM VPD.");
+ return vpdType::INVALID_VPD_FORMAT;
+ }
+ else if ((i_vpdVector[constants::SPD_BYTE_2] & constants::SPD_BYTE_MASK) ==
+ constants::SPD_DRAM_TYPE_DDR5)
+ {
+ // ISDIMM memory VPD format
+ return vpdType::DDR5_ISDIMM_MEMORY_VPD;
+ }
+ else if ((i_vpdVector[constants::SPD_BYTE_2] & constants::SPD_BYTE_MASK) ==
+ constants::SPD_DRAM_TYPE_DDR4)
+ {
+ // ISDIMM memory VPD format
+ return vpdType::DDR4_ISDIMM_MEMORY_VPD;
+ }
+
+ return vpdType::INVALID_VPD_FORMAT;
+}
+
+std::shared_ptr<ParserInterface> ParserFactory::getParser(
+ const types::BinaryVector& i_vpdVector, const std::string& i_vpdFilePath,
+ size_t i_vpdStartOffset)
+{
+ if (i_vpdVector.empty())
+ {
+ throw std::runtime_error("Empty VPD vector passed to parser factory");
+ }
+
+ vpdType l_type = vpdTypeCheck(i_vpdVector);
+
+ switch (l_type)
+ {
+ case vpdType::IPZ_VPD:
+ {
+ return std::make_shared<IpzVpdParser>(i_vpdVector, i_vpdFilePath,
+ i_vpdStartOffset);
+ }
+
+ case vpdType::KEYWORD_VPD:
+ {
+ return std::make_shared<KeywordVpdParser>(i_vpdVector);
+ }
+
+ case vpdType::DDR5_DDIMM_MEMORY_VPD:
+ case vpdType::DDR4_DDIMM_MEMORY_VPD:
+ {
+ return std::make_shared<DdimmVpdParser>(i_vpdVector);
+ }
+
+ case vpdType::DDR4_ISDIMM_MEMORY_VPD:
+ case vpdType::DDR5_ISDIMM_MEMORY_VPD:
+ {
+ // return shared pointer to class object.
+ logging::logMessage(
+ "ISDIMM parser selected for VPD path: " + i_vpdFilePath);
+ return std::make_shared<JedecSpdParser>(i_vpdVector);
+ }
+
+ default:
+ throw DataException("Unable to determine VPD format");
+ }
+}
+} // namespace vpd