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