1 #include "gpio_monitor.hpp"
2
3 #include "constants.hpp"
4 #include "logger.hpp"
5 #include "types.hpp"
6 #include "utility/dbus_utility.hpp"
7 #include "utility/json_utility.hpp"
8
9 #include <boost/asio.hpp>
10 #include <boost/bind/bind.hpp>
11 #include <gpiod.hpp>
12
13 namespace vpd
14 {
handleChangeInGpioPin(const bool & i_isFruPresent)15 void GpioEventHandler::handleChangeInGpioPin(const bool& i_isFruPresent)
16 {
17 try
18 {
19 if (i_isFruPresent)
20 {
21 types::VPDMapVariant l_parsedVpd =
22 m_worker->parseVpdFile(m_fruPath);
23
24 if (std::holds_alternative<std::monostate>(l_parsedVpd))
25 {
26 throw std::runtime_error(
27 "VPD parsing failed for " + std::string(m_fruPath));
28 }
29
30 types::ObjectMap l_dbusObjectMap;
31 m_worker->populateDbus(l_parsedVpd, l_dbusObjectMap, m_fruPath);
32
33 if (l_dbusObjectMap.empty())
34 {
35 throw std::runtime_error("Failed to create D-bus object map.");
36 }
37
38 if (!dbusUtility::callPIM(move(l_dbusObjectMap)))
39 {
40 throw std::runtime_error("call PIM failed");
41 }
42 }
43 else
44 {
45 m_worker->deleteFruVpd(jsonUtility::getInventoryObjPathFromJson(
46 m_worker->getSysCfgJsonObj(), m_fruPath));
47 }
48 }
49 catch (std::exception& l_ex)
50 {
51 logging::logMessage(std::string(l_ex.what()));
52 }
53 }
54
handleTimerExpiry(const boost::system::error_code & i_errorCode,const std::shared_ptr<boost::asio::steady_timer> & i_timerObj)55 void GpioEventHandler::handleTimerExpiry(
56 const boost::system::error_code& i_errorCode,
57 const std::shared_ptr<boost::asio::steady_timer>& i_timerObj)
58 {
59 if (i_errorCode == boost::asio::error::operation_aborted)
60 {
61 logging::logMessage("Timer aborted for GPIO pin");
62 return;
63 }
64
65 if (i_errorCode)
66 {
67 logging::logMessage("Timer wait failed for gpio pin" +
68 std::string(i_errorCode.message()));
69 return;
70 }
71
72 bool l_currentPresencePinValue = jsonUtility::processGpioPresenceTag(
73 m_worker->getSysCfgJsonObj(), m_fruPath, "pollingRequired",
74 "hotPlugging");
75
76 if (m_prevPresencePinValue != l_currentPresencePinValue)
77 {
78 m_prevPresencePinValue = l_currentPresencePinValue;
79 handleChangeInGpioPin(l_currentPresencePinValue);
80 }
81
82 i_timerObj->expires_at(std::chrono::steady_clock::now() +
83 std::chrono::seconds(constants::VALUE_5));
84 i_timerObj->async_wait(
85 boost::bind(&GpioEventHandler::handleTimerExpiry, this,
86 boost::asio::placeholders::error, i_timerObj));
87 }
88
setEventHandlerForGpioPresence(const std::shared_ptr<boost::asio::io_context> & i_ioContext)89 void GpioEventHandler::setEventHandlerForGpioPresence(
90 const std::shared_ptr<boost::asio::io_context>& i_ioContext)
91 {
92 m_prevPresencePinValue = jsonUtility::processGpioPresenceTag(
93 m_worker->getSysCfgJsonObj(), m_fruPath, "pollingRequired",
94 "hotPlugging");
95
96 static std::vector<std::shared_ptr<boost::asio::steady_timer>> l_timers;
97
98 auto l_timerObj = make_shared<boost::asio::steady_timer>(
99 *i_ioContext, std::chrono::seconds(constants::VALUE_5));
100
101 l_timerObj->async_wait(
102 boost::bind(&GpioEventHandler::handleTimerExpiry, this,
103 boost::asio::placeholders::error, l_timerObj));
104
105 l_timers.push_back(l_timerObj);
106 }
107
initHandlerForGpio(const std::shared_ptr<boost::asio::io_context> & i_ioContext,const std::shared_ptr<Worker> & i_worker)108 void GpioMonitor::initHandlerForGpio(
109 const std::shared_ptr<boost::asio::io_context>& i_ioContext,
110 const std::shared_ptr<Worker>& i_worker)
111 {
112 std::vector<std::string> l_gpioPollingRequiredFrusList =
113 jsonUtility::getListOfGpioPollingFrus(m_sysCfgJsonObj);
114
115 for (const auto& l_fruPath : l_gpioPollingRequiredFrusList)
116 {
117 std::shared_ptr<GpioEventHandler> l_gpioEventHandlerObj =
118 std::make_shared<GpioEventHandler>(l_fruPath, i_worker,
119 i_ioContext);
120
121 m_gpioEventHandlerObjects.push_back(l_gpioEventHandlerObj);
122 }
123 }
124 } // namespace vpd
125