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