173ac368aSBen Tyner #include "attn_monitor.hpp" 273ac368aSBen Tyner 373ac368aSBen Tyner #include "attn_handler.hpp" 473ac368aSBen Tyner 59ae5ca41SBen Tyner #include <logging.hpp> 673ac368aSBen Tyner 773ac368aSBen Tyner namespace attn 873ac368aSBen Tyner { 973ac368aSBen Tyner 1073ac368aSBen Tyner /** @brief Register a callback for gpio event */ 1173ac368aSBen Tyner void AttnMonitor::scheduleGPIOEvent() 1273ac368aSBen Tyner { 139ae5ca41SBen Tyner std::string logMessage = "... waiting for events ..."; 1473ac368aSBen Tyner log<level::INFO>(logMessage.c_str()); 1573ac368aSBen Tyner 1673ac368aSBen Tyner // Register async callback, note that callback is a 1773ac368aSBen Tyner // lambda function with "this" pointer captured 1873ac368aSBen Tyner iv_gpioEventDescriptor.async_wait( 1973ac368aSBen Tyner boost::asio::posix::stream_descriptor::wait_read, 2073ac368aSBen Tyner [this](const boost::system::error_code& ec) { 2173ac368aSBen Tyner if (ec) 2273ac368aSBen Tyner { 239ae5ca41SBen Tyner std::string logMessage = 249ae5ca41SBen Tyner "GPIO Async wait error: " + std::string(ec.message()); 2573ac368aSBen Tyner log<level::INFO>(logMessage.c_str()); 2673ac368aSBen Tyner } 2773ac368aSBen Tyner else 2873ac368aSBen Tyner { 2973ac368aSBen Tyner handleGPIOEvent(); // gpio trigger detected 3073ac368aSBen Tyner } 3173ac368aSBen Tyner return; 3273ac368aSBen Tyner }); // register async callback 3373ac368aSBen Tyner } 3473ac368aSBen Tyner 3573ac368aSBen Tyner /** @brief Handle the GPIO state change event */ 3673ac368aSBen Tyner void AttnMonitor::handleGPIOEvent() 3773ac368aSBen Tyner { 3873ac368aSBen Tyner gpiod_line_event gpioEvent; 3973ac368aSBen Tyner std::string logMessage; 4073ac368aSBen Tyner 4173ac368aSBen Tyner if (gpiod_line_event_read_fd(iv_gpioEventDescriptor.native_handle(), 4273ac368aSBen Tyner &gpioEvent) < 0) 4373ac368aSBen Tyner { 449ae5ca41SBen Tyner logMessage = "GPIO line read failed"; 4573ac368aSBen Tyner log<level::INFO>(logMessage.c_str()); 4673ac368aSBen Tyner } 4773ac368aSBen Tyner else 4873ac368aSBen Tyner { 4973ac368aSBen Tyner switch (gpiod_line_get_value(iv_gpioLine)) 5073ac368aSBen Tyner { 5173ac368aSBen Tyner // active attention when gpio == 0 5273ac368aSBen Tyner case 0: 53*3fb52e53SBen Tyner attnHandler(iv_config); 5473ac368aSBen Tyner break; 5573ac368aSBen Tyner 5673ac368aSBen Tyner // gpio == 1, GPIO handler should not be executing 5773ac368aSBen Tyner case 1: 589ae5ca41SBen Tyner logMessage = "GPIO handler out of sync"; 5973ac368aSBen Tyner log<level::INFO>(logMessage.c_str()); 6073ac368aSBen Tyner break; 6173ac368aSBen Tyner 6273ac368aSBen Tyner // unexpected value 6373ac368aSBen Tyner default: 649ae5ca41SBen Tyner logMessage = "GPIO line unexpected value"; 6573ac368aSBen Tyner log<level::INFO>(logMessage.c_str()); 6673ac368aSBen Tyner } 6773ac368aSBen Tyner } 6873ac368aSBen Tyner scheduleGPIOEvent(); // continue monitoring gpio 6973ac368aSBen Tyner } 7073ac368aSBen Tyner 7173ac368aSBen Tyner /** @brief Request a GPIO line for monitoring attention events */ 7273ac368aSBen Tyner void AttnMonitor::requestGPIOEvent() 7373ac368aSBen Tyner { 7473ac368aSBen Tyner if (0 != gpiod_line_request(iv_gpioLine, &iv_gpioConfig, 0)) 7573ac368aSBen Tyner { 769ae5ca41SBen Tyner std::string logMessage = "failed request for GPIO"; 7773ac368aSBen Tyner log<level::INFO>(logMessage.c_str()); 7873ac368aSBen Tyner } 7973ac368aSBen Tyner else 8073ac368aSBen Tyner { 8173ac368aSBen Tyner int gpioLineFd; 8273ac368aSBen Tyner 8373ac368aSBen Tyner gpioLineFd = gpiod_line_event_get_fd(iv_gpioLine); 8473ac368aSBen Tyner if (gpioLineFd < 0) 8573ac368aSBen Tyner { 869ae5ca41SBen Tyner std::string logMessage = "failed to get file descriptor"; 8773ac368aSBen Tyner log<level::INFO>(logMessage.c_str()); 8873ac368aSBen Tyner } 8973ac368aSBen Tyner else 9073ac368aSBen Tyner { 9173ac368aSBen Tyner // Register file descriptor for monitoring 9273ac368aSBen Tyner iv_gpioEventDescriptor.assign(gpioLineFd); 9373ac368aSBen Tyner 9473ac368aSBen Tyner // Start monitoring 9573ac368aSBen Tyner scheduleGPIOEvent(); 9673ac368aSBen Tyner } 9773ac368aSBen Tyner } 9873ac368aSBen Tyner } 9973ac368aSBen Tyner 10073ac368aSBen Tyner } // namespace attn 101