Check VPD collection mode in non field mode

This commit adds changes to read VPD collection mode in case system is
in not in field mode. In non field mode, VPD collection mode is
determined by reading u-boot variable "vpdmode".

Test:
```
- Put debug traces in worker constructor
- Install image on rainiest simics
- Check u-boot variable "fieldmode" is not defined
- Check u-boot variable "vpdmode" is not defined
- See worker is initialized with m_vpdCollectionMode = HARDWARE_MODE
- Check u-boot variable "fieldmode" is defined as "fieldmode=true"
- See worker is initialized with m_vpdCollectionMode = HARDWARE_MODE
- Check u-boot variable "fieldmode" is defined as "fieldmode=false"
- Check u-boot variable "vpdmode" is not defined
- See worker is initialized with m_vpdCollectionMode = HARDWARE_MODE
- Check u-boot variable "vpdmode" is defined as "vpdmode=hardware"
- See worker is initialized with m_vpdCollectionMode = HARDWARE_MODE
- Check u-boot variable "vpdmode" is defined as "vpdmode=file"
- See worker is initialized with m_vpdCollectionMode = FILE_MODE
- Check u-boot variable "vpdmode" is defined as "vpdmode=mixed"
- See worker is initialized with m_vpdCollectionMode = MIXED_MODE
```

Change-Id: I89e514c7c46cc409c0746cddfe66ce0a860220ee
Signed-off-by: Souvik Roy <souvikroyofficial10@gmail.com>
diff --git a/vpd-manager/include/utility/common_utility.hpp b/vpd-manager/include/utility/common_utility.hpp
index e1564f8..dc5da28 100644
--- a/vpd-manager/include/utility/common_utility.hpp
+++ b/vpd-manager/include/utility/common_utility.hpp
@@ -302,5 +302,53 @@
     return false;
 }
 
+/**
+ * @brief API to get VPD collection mode
+ *
+ * VPD collection mode can be hardware, mixed mode or file mode. This is
+ * determined by reading a u-boot variable.
+ *
+ * @param[out] o_errCode - To set error code in case of error.
+ *
+ * @return Hardware mode, mixed mode or file mode.
+ */
+inline types::VpdCollectionMode getVpdCollectionMode(
+    uint16_t& o_errCode) noexcept
+{
+    types::VpdCollectionMode l_result{types::VpdCollectionMode::DEFAULT_MODE};
+    try
+    {
+        std::vector<std::string> l_cmdOutput =
+            commonUtility::executeCmd("/sbin/fw_printenv vpdmode");
+
+        if (l_cmdOutput.size() > 0)
+        {
+            commonUtility::toLower(l_cmdOutput[0]);
+
+            // Remove the new line character from the string.
+            l_cmdOutput[0].erase(l_cmdOutput[0].length() - 1);
+
+            if (l_cmdOutput[0] == "vpdmode=hardware")
+            {
+                l_result = types::VpdCollectionMode::HARDWARE_MODE;
+            }
+            else if (l_cmdOutput[0] == "vpdmode=mixed")
+            {
+                l_result = types::VpdCollectionMode::MIXED_MODE;
+            }
+            else if (l_cmdOutput[0] == "vpdmode=file")
+            {
+                l_result = types::VpdCollectionMode::FILE_MODE;
+            }
+        }
+    }
+    catch (const std::exception& l_ex)
+    {
+        o_errCode = error_code::STANDARD_EXCEPTION;
+    }
+
+    return l_result;
+}
+
 } // namespace commonUtility
 } // namespace vpd
diff --git a/vpd-manager/oem-handler/ibm_handler.cpp b/vpd-manager/oem-handler/ibm_handler.cpp
index fdd4e5a..99acdc7 100644
--- a/vpd-manager/oem-handler/ibm_handler.cpp
+++ b/vpd-manager/oem-handler/ibm_handler.cpp
@@ -24,22 +24,39 @@
     m_ioContext(i_ioCon), m_asioConnection(i_asioConnection),
     m_logger(Logger::getLoggerInstance())
 {
+    uint16_t l_errCode{0};
+
+    // check VPD collection mode
+    const auto l_vpdCollectionMode =
+        commonUtility::isFieldModeEnabled()
+            ? types::VpdCollectionMode::DEFAULT_MODE
+            : commonUtility::getVpdCollectionMode(l_errCode);
+
+    if (l_errCode)
+    {
+        m_logger->logMessage(
+            "Error while trying to read VPD collection mode: " +
+            commonUtility::getErrCodeMsg(l_errCode));
+        l_errCode = 0;
+    }
+
     if (dbusUtility::isChassisPowerOn())
     {
         // At power on, less number of FRU(s) needs collection. we can scale
         // down the threads to reduce CPU utilization.
-        m_worker = std::make_shared<Worker>(INVENTORY_JSON_DEFAULT,
-                                            constants::VALUE_1);
+        m_worker = std::make_shared<Worker>(
+            INVENTORY_JSON_DEFAULT, constants::VALUE_1, l_vpdCollectionMode);
     }
     else
     {
         // Initialize with default configuration
-        m_worker = std::make_shared<Worker>(INVENTORY_JSON_DEFAULT);
+        m_worker = std::make_shared<Worker>(INVENTORY_JSON_DEFAULT,
+                                            constants::MAX_THREADS,
+                                            l_vpdCollectionMode);
     }
 
     // Set up minimal things that is needed before bus name is claimed.
     performInitialSetup();
-    uint16_t l_errCode = 0;
 
     if (!m_sysCfgJsonObj.empty() &&
         jsonUtility::isBackupAndRestoreRequired(m_sysCfgJsonObj, l_errCode))