1*73ac368aSBen Tyner #include "attn_monitor.hpp" 2*73ac368aSBen Tyner 3*73ac368aSBen Tyner #include "attn_handler.hpp" 4*73ac368aSBen Tyner 5*73ac368aSBen Tyner #include <phosphor-logging/log.hpp> 6*73ac368aSBen Tyner 7*73ac368aSBen Tyner using namespace phosphor::logging; 8*73ac368aSBen Tyner 9*73ac368aSBen Tyner namespace attn 10*73ac368aSBen Tyner { 11*73ac368aSBen Tyner 12*73ac368aSBen Tyner /** @brief Register a callback for gpio event */ 13*73ac368aSBen Tyner void AttnMonitor::scheduleGPIOEvent() 14*73ac368aSBen Tyner { 15*73ac368aSBen Tyner std::string logMessage = "[ATTN] ... waiting for events ..."; 16*73ac368aSBen Tyner log<level::INFO>(logMessage.c_str()); 17*73ac368aSBen Tyner 18*73ac368aSBen Tyner // Register async callback, note that callback is a 19*73ac368aSBen Tyner // lambda function with "this" pointer captured 20*73ac368aSBen Tyner iv_gpioEventDescriptor.async_wait( 21*73ac368aSBen Tyner boost::asio::posix::stream_descriptor::wait_read, 22*73ac368aSBen Tyner [this](const boost::system::error_code& ec) { 23*73ac368aSBen Tyner if (ec) 24*73ac368aSBen Tyner { 25*73ac368aSBen Tyner std::string logMessage = "[ATTN] ATTN GPIO Async error: " + 26*73ac368aSBen Tyner std::string(ec.message()); 27*73ac368aSBen Tyner log<level::INFO>(logMessage.c_str()); 28*73ac368aSBen Tyner } 29*73ac368aSBen Tyner else 30*73ac368aSBen Tyner { 31*73ac368aSBen Tyner handleGPIOEvent(); // gpio trigger detected 32*73ac368aSBen Tyner } 33*73ac368aSBen Tyner return; 34*73ac368aSBen Tyner }); // register async callback 35*73ac368aSBen Tyner } 36*73ac368aSBen Tyner 37*73ac368aSBen Tyner /** @brief Handle the GPIO state change event */ 38*73ac368aSBen Tyner void AttnMonitor::handleGPIOEvent() 39*73ac368aSBen Tyner { 40*73ac368aSBen Tyner gpiod_line_event gpioEvent; 41*73ac368aSBen Tyner std::string logMessage; 42*73ac368aSBen Tyner 43*73ac368aSBen Tyner if (gpiod_line_event_read_fd(iv_gpioEventDescriptor.native_handle(), 44*73ac368aSBen Tyner &gpioEvent) < 0) 45*73ac368aSBen Tyner { 46*73ac368aSBen Tyner logMessage = "[ATTN] ATTN GPIO Failed can't read file descriptor!"; 47*73ac368aSBen Tyner log<level::INFO>(logMessage.c_str()); 48*73ac368aSBen Tyner } 49*73ac368aSBen Tyner else 50*73ac368aSBen Tyner { 51*73ac368aSBen Tyner switch (gpiod_line_get_value(iv_gpioLine)) 52*73ac368aSBen Tyner { 53*73ac368aSBen Tyner // active attention when gpio == 0 54*73ac368aSBen Tyner case 0: 55*73ac368aSBen Tyner attnHandler(); 56*73ac368aSBen Tyner break; 57*73ac368aSBen Tyner 58*73ac368aSBen Tyner // gpio == 1, GPIO handler should not be executing 59*73ac368aSBen Tyner case 1: 60*73ac368aSBen Tyner logMessage = "[ATTN] ATTN GPIO sync!"; 61*73ac368aSBen Tyner log<level::INFO>(logMessage.c_str()); 62*73ac368aSBen Tyner break; 63*73ac368aSBen Tyner 64*73ac368aSBen Tyner // unexpected value 65*73ac368aSBen Tyner default: 66*73ac368aSBen Tyner logMessage = "[ATTN] ATTN GPIO read unexpected valuel!"; 67*73ac368aSBen Tyner log<level::INFO>(logMessage.c_str()); 68*73ac368aSBen Tyner } 69*73ac368aSBen Tyner } 70*73ac368aSBen Tyner scheduleGPIOEvent(); // continue monitoring gpio 71*73ac368aSBen Tyner } 72*73ac368aSBen Tyner 73*73ac368aSBen Tyner /** @brief Request a GPIO line for monitoring attention events */ 74*73ac368aSBen Tyner void AttnMonitor::requestGPIOEvent() 75*73ac368aSBen Tyner { 76*73ac368aSBen Tyner if (0 != gpiod_line_request(iv_gpioLine, &iv_gpioConfig, 0)) 77*73ac368aSBen Tyner { 78*73ac368aSBen Tyner std::string logMessage = "[ATTN] failed request for GPIO"; 79*73ac368aSBen Tyner log<level::INFO>(logMessage.c_str()); 80*73ac368aSBen Tyner } 81*73ac368aSBen Tyner else 82*73ac368aSBen Tyner { 83*73ac368aSBen Tyner int gpioLineFd; 84*73ac368aSBen Tyner 85*73ac368aSBen Tyner gpioLineFd = gpiod_line_event_get_fd(iv_gpioLine); 86*73ac368aSBen Tyner if (gpioLineFd < 0) 87*73ac368aSBen Tyner { 88*73ac368aSBen Tyner std::string logMessage = "[ATTN] failed to get file descriptor"; 89*73ac368aSBen Tyner log<level::INFO>(logMessage.c_str()); 90*73ac368aSBen Tyner } 91*73ac368aSBen Tyner else 92*73ac368aSBen Tyner { 93*73ac368aSBen Tyner // Register file descriptor for monitoring 94*73ac368aSBen Tyner iv_gpioEventDescriptor.assign(gpioLineFd); 95*73ac368aSBen Tyner 96*73ac368aSBen Tyner // Start monitoring 97*73ac368aSBen Tyner scheduleGPIOEvent(); 98*73ac368aSBen Tyner } 99*73ac368aSBen Tyner } 100*73ac368aSBen Tyner } 101*73ac368aSBen Tyner 102*73ac368aSBen Tyner } // namespace attn 103