xref: /openbmc/openpower-vpd-parser/vpd-manager/src/gpio_monitor.cpp (revision 7fea9f503fbdc0dce1ecf3bf684ac49ccf80ae89)
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