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/gpio_monitor.cpp b/vpd-manager/src/gpio_monitor.cpp
new file mode 100644
index 0000000..521037c
--- /dev/null
+++ b/vpd-manager/src/gpio_monitor.cpp
@@ -0,0 +1,131 @@
+#include "gpio_monitor.hpp"
+
+#include "constants.hpp"
+#include "logger.hpp"
+#include "types.hpp"
+#include "utility/dbus_utility.hpp"
+#include "utility/json_utility.hpp"
+
+#include <boost/asio.hpp>
+#include <boost/bind/bind.hpp>
+#include <gpiod.hpp>
+
+namespace vpd
+{
+void GpioEventHandler::handleChangeInGpioPin(const bool& i_isFruPresent)
+{
+ try
+ {
+ if (i_isFruPresent)
+ {
+ types::VPDMapVariant l_parsedVpd =
+ m_worker->parseVpdFile(m_fruPath);
+
+ if (std::holds_alternative<std::monostate>(l_parsedVpd))
+ {
+ throw std::runtime_error(
+ "VPD parsing failed for " + std::string(m_fruPath));
+ }
+
+ types::ObjectMap l_dbusObjectMap;
+ m_worker->populateDbus(l_parsedVpd, l_dbusObjectMap, m_fruPath);
+
+ if (l_dbusObjectMap.empty())
+ {
+ throw std::runtime_error("Failed to create D-bus object map.");
+ }
+
+ if (!dbusUtility::callPIM(move(l_dbusObjectMap)))
+ {
+ throw std::runtime_error("call PIM failed");
+ }
+ }
+ else
+ {
+ // TODO -- Add implementation to Delete FRU if FRU is not present.
+ }
+ }
+ catch (std::exception& l_ex)
+ {
+ logging::logMessage(std::string(l_ex.what()));
+ }
+}
+
+void GpioEventHandler::handleTimerExpiry(
+ const boost::system::error_code& i_errorCode,
+ const std::shared_ptr<boost::asio::steady_timer>& i_timerObj)
+{
+ if (i_errorCode == boost::asio::error::operation_aborted)
+ {
+ logging::logMessage("Timer aborted for GPIO pin");
+ return;
+ }
+
+ if (i_errorCode)
+ {
+ logging::logMessage("Timer wait failed for gpio pin" +
+ std::string(i_errorCode.message()));
+ return;
+ }
+
+ bool l_currentPresencePinValue = jsonUtility::processGpioPresenceTag(
+ m_worker->getSysCfgJsonObj(), m_fruPath, "pollingRequired",
+ "hotPlugging");
+
+ if (m_prevPresencePinValue != l_currentPresencePinValue)
+ {
+ m_prevPresencePinValue = l_currentPresencePinValue;
+ handleChangeInGpioPin(l_currentPresencePinValue);
+ }
+
+ i_timerObj->expires_at(std::chrono::steady_clock::now() +
+ std::chrono::seconds(constants::VALUE_5));
+ i_timerObj->async_wait(
+ boost::bind(&GpioEventHandler::handleTimerExpiry, this,
+ boost::asio::placeholders::error, i_timerObj));
+}
+
+void GpioEventHandler::setEventHandlerForGpioPresence(
+ const std::shared_ptr<boost::asio::io_context>& i_ioContext)
+{
+ m_prevPresencePinValue = jsonUtility::processGpioPresenceTag(
+ m_worker->getSysCfgJsonObj(), m_fruPath, "pollingRequired",
+ "hotPlugging");
+
+ static std::vector<std::shared_ptr<boost::asio::steady_timer>> l_timers;
+
+ auto l_timerObj = make_shared<boost::asio::steady_timer>(
+ *i_ioContext, std::chrono::seconds(constants::VALUE_5));
+
+ l_timerObj->async_wait(
+ boost::bind(&GpioEventHandler::handleTimerExpiry, this,
+ boost::asio::placeholders::error, l_timerObj));
+
+ l_timers.push_back(l_timerObj);
+}
+
+void GpioMonitor::initHandlerForGpio(
+ const std::shared_ptr<boost::asio::io_context>& i_ioContext,
+ const std::shared_ptr<Worker>& i_worker)
+{
+ try
+ {
+ std::vector<std::string> l_gpioPollingRequiredFrusList =
+ jsonUtility::getListOfGpioPollingFrus(m_sysCfgJsonObj);
+
+ for (const auto& l_fruPath : l_gpioPollingRequiredFrusList)
+ {
+ std::shared_ptr<GpioEventHandler> l_gpioEventHandlerObj =
+ std::make_shared<GpioEventHandler>(l_fruPath, i_worker,
+ i_ioContext);
+
+ m_gpioEventHandlerObjects.push_back(l_gpioEventHandlerObj);
+ }
+ }
+ catch (std::exception& l_ex)
+ {
+ // TODO log PEL for exception.
+ logging::logMessage(l_ex.what());
+ }
+}
+} // namespace vpd