1*b797b3e1SBen Tyner #include <attn/attn_handler.hpp> 2*b797b3e1SBen Tyner #include <attn/attn_logging.hpp> 3*b797b3e1SBen Tyner #include <attn/attn_monitor.hpp> 473ac368aSBen Tyner 573ac368aSBen Tyner namespace attn 673ac368aSBen Tyner { 773ac368aSBen Tyner 873ac368aSBen Tyner /** @brief Register a callback for gpio event */ 973ac368aSBen Tyner void AttnMonitor::scheduleGPIOEvent() 1073ac368aSBen Tyner { 119ae5ca41SBen Tyner std::string logMessage = "... waiting for events ..."; 12b1ebfcb1SBen Tyner trace<level::INFO>(logMessage.c_str()); 1373ac368aSBen Tyner 1473ac368aSBen Tyner // Register async callback, note that callback is a 1573ac368aSBen Tyner // lambda function with "this" pointer captured 1673ac368aSBen Tyner iv_gpioEventDescriptor.async_wait( 1773ac368aSBen Tyner boost::asio::posix::stream_descriptor::wait_read, 1873ac368aSBen Tyner [this](const boost::system::error_code& ec) { 1973ac368aSBen Tyner if (ec) 2073ac368aSBen Tyner { 219ae5ca41SBen Tyner std::string logMessage = 229ae5ca41SBen Tyner "GPIO Async wait error: " + std::string(ec.message()); 23b1ebfcb1SBen Tyner trace<level::INFO>(logMessage.c_str()); 2473ac368aSBen Tyner } 2573ac368aSBen Tyner else 2673ac368aSBen Tyner { 27b1ebfcb1SBen Tyner trace<level::INFO>( 28b1ebfcb1SBen Tyner "Attention monitor detected active attention"); 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"; 45b1ebfcb1SBen Tyner trace<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: 53117af99bSBen Tyner logMessage = "Attention monitor calling attention handler"; 54b1ebfcb1SBen Tyner trace<level::INFO>(logMessage.c_str()); 553fb52e53SBen Tyner attnHandler(iv_config); 5673ac368aSBen Tyner break; 5773ac368aSBen Tyner 5873ac368aSBen Tyner // gpio == 1, GPIO handler should not be executing 5973ac368aSBen Tyner case 1: 609ae5ca41SBen Tyner logMessage = "GPIO handler out of sync"; 61b1ebfcb1SBen Tyner trace<level::INFO>(logMessage.c_str()); 6273ac368aSBen Tyner break; 6373ac368aSBen Tyner 6473ac368aSBen Tyner // unexpected value 6573ac368aSBen Tyner default: 669ae5ca41SBen Tyner logMessage = "GPIO line unexpected value"; 67b1ebfcb1SBen Tyner trace<level::INFO>(logMessage.c_str()); 6873ac368aSBen Tyner } 6973ac368aSBen Tyner } 7073ac368aSBen Tyner scheduleGPIOEvent(); // continue monitoring gpio 7173ac368aSBen Tyner } 7273ac368aSBen Tyner 7373ac368aSBen Tyner /** @brief Request a GPIO line for monitoring attention events */ 7473ac368aSBen Tyner void AttnMonitor::requestGPIOEvent() 7573ac368aSBen Tyner { 7673ac368aSBen Tyner if (0 != gpiod_line_request(iv_gpioLine, &iv_gpioConfig, 0)) 7773ac368aSBen Tyner { 789ae5ca41SBen Tyner std::string logMessage = "failed request for GPIO"; 79b1ebfcb1SBen Tyner trace<level::INFO>(logMessage.c_str()); 8073ac368aSBen Tyner } 8173ac368aSBen Tyner else 8273ac368aSBen Tyner { 8373ac368aSBen Tyner int gpioLineFd; 8473ac368aSBen Tyner 8573ac368aSBen Tyner gpioLineFd = gpiod_line_event_get_fd(iv_gpioLine); 8673ac368aSBen Tyner if (gpioLineFd < 0) 8773ac368aSBen Tyner { 889ae5ca41SBen Tyner std::string logMessage = "failed to get file descriptor"; 89b1ebfcb1SBen Tyner trace<level::INFO>(logMessage.c_str()); 9073ac368aSBen Tyner } 9173ac368aSBen Tyner else 9273ac368aSBen Tyner { 9373ac368aSBen Tyner // Register file descriptor for monitoring 9473ac368aSBen Tyner iv_gpioEventDescriptor.assign(gpioLineFd); 9573ac368aSBen Tyner 9673ac368aSBen Tyner // Start monitoring 9773ac368aSBen Tyner scheduleGPIOEvent(); 9873ac368aSBen Tyner } 9973ac368aSBen Tyner } 10073ac368aSBen Tyner } 10173ac368aSBen Tyner 10273ac368aSBen Tyner } // namespace attn 103