blob: b155fac5fb3d68981861029c0c03ab30fc6f774a [file] [log] [blame]
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -05001#include "gpio_monitor.hpp"
2
3#include "constants.hpp"
Rekha Aparna017567a2025-08-13 02:07:06 -05004#include "error_codes.hpp"
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -05005#include "logger.hpp"
6#include "types.hpp"
7#include "utility/dbus_utility.hpp"
8#include "utility/json_utility.hpp"
Rekha Aparna017567a2025-08-13 02:07:06 -05009#include "utility/vpd_specific_utility.hpp"
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050010
11#include <boost/asio.hpp>
12#include <boost/bind/bind.hpp>
13#include <gpiod.hpp>
14
15namespace vpd
16{
17void 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 {
Rekha Aparna017567a2025-08-13 02:07:06 -050047 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);
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050059 }
60 }
61 catch (std::exception& l_ex)
62 {
63 logging::logMessage(std::string(l_ex.what()));
64 }
65}
66
67void 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
Sunny Srivastava84c3d232025-09-03 00:47:10 -050084 uint16_t l_errCode = 0;
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050085 bool l_currentPresencePinValue = jsonUtility::processGpioPresenceTag(
86 m_worker->getSysCfgJsonObj(), m_fruPath, "pollingRequired",
Sunny Srivastava84c3d232025-09-03 00:47:10 -050087 "hotPlugging", l_errCode);
88
89 if (l_errCode && l_errCode != error_code::DEVICE_NOT_PRESENT)
90 {
91 logging::logMessage("processGpioPresenceTag returned false for FRU [" +
92 m_fruPath + "] Due to error. Reason: " +
93 vpdSpecificUtility::getErrCodeMsg(l_errCode));
94 }
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050095
96 if (m_prevPresencePinValue != l_currentPresencePinValue)
97 {
98 m_prevPresencePinValue = l_currentPresencePinValue;
99 handleChangeInGpioPin(l_currentPresencePinValue);
100 }
101
102 i_timerObj->expires_at(std::chrono::steady_clock::now() +
103 std::chrono::seconds(constants::VALUE_5));
104 i_timerObj->async_wait(
105 boost::bind(&GpioEventHandler::handleTimerExpiry, this,
106 boost::asio::placeholders::error, i_timerObj));
107}
108
109void GpioEventHandler::setEventHandlerForGpioPresence(
110 const std::shared_ptr<boost::asio::io_context>& i_ioContext)
111{
Sunny Srivastava84c3d232025-09-03 00:47:10 -0500112 uint16_t l_errCode = 0;
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500113 m_prevPresencePinValue = jsonUtility::processGpioPresenceTag(
114 m_worker->getSysCfgJsonObj(), m_fruPath, "pollingRequired",
Sunny Srivastava84c3d232025-09-03 00:47:10 -0500115 "hotPlugging", l_errCode);
116
117 if (l_errCode && l_errCode != error_code::DEVICE_NOT_PRESENT)
118 {
119 logging::logMessage("processGpioPresenceTag returned false for FRU [" +
120 m_fruPath + "] Due to error. Reason: " +
121 vpdSpecificUtility::getErrCodeMsg(l_errCode));
122 }
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500123
124 static std::vector<std::shared_ptr<boost::asio::steady_timer>> l_timers;
125
126 auto l_timerObj = make_shared<boost::asio::steady_timer>(
127 *i_ioContext, std::chrono::seconds(constants::VALUE_5));
128
129 l_timerObj->async_wait(
130 boost::bind(&GpioEventHandler::handleTimerExpiry, this,
131 boost::asio::placeholders::error, l_timerObj));
132
133 l_timers.push_back(l_timerObj);
134}
135
136void GpioMonitor::initHandlerForGpio(
137 const std::shared_ptr<boost::asio::io_context>& i_ioContext,
138 const std::shared_ptr<Worker>& i_worker)
139{
RekhaAparna017fea9f52025-02-17 04:14:02 -0600140 std::vector<std::string> l_gpioPollingRequiredFrusList =
141 jsonUtility::getListOfGpioPollingFrus(m_sysCfgJsonObj);
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500142
RekhaAparna017fea9f52025-02-17 04:14:02 -0600143 for (const auto& l_fruPath : l_gpioPollingRequiredFrusList)
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500144 {
RekhaAparna017fea9f52025-02-17 04:14:02 -0600145 std::shared_ptr<GpioEventHandler> l_gpioEventHandlerObj =
146 std::make_shared<GpioEventHandler>(l_fruPath, i_worker,
147 i_ioContext);
148
149 m_gpioEventHandlerObjects.push_back(l_gpioEventHandlerObj);
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500150 }
151}
152} // namespace vpd