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 { 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 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 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 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 try 113 { 114 std::vector<std::string> l_gpioPollingRequiredFrusList = 115 jsonUtility::getListOfGpioPollingFrus(m_sysCfgJsonObj); 116 117 for (const auto& l_fruPath : l_gpioPollingRequiredFrusList) 118 { 119 std::shared_ptr<GpioEventHandler> l_gpioEventHandlerObj = 120 std::make_shared<GpioEventHandler>(l_fruPath, i_worker, 121 i_ioContext); 122 123 m_gpioEventHandlerObjects.push_back(l_gpioEventHandlerObj); 124 } 125 } 126 catch (std::exception& l_ex) 127 { 128 // TODO log PEL for exception. 129 logging::logMessage(l_ex.what()); 130 } 131 } 132 } // namespace vpd 133