1 #include <attn/attn_handler.hpp> 2 #include <attn/attn_logging.hpp> 3 #include <attn/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>("Attention GPIO active"); 28 handleGPIOEvent(); // gpio trigger detected 29 } 30 return; 31 }); // register async callback 32 } 33 34 /** @brief Handle the GPIO state change event */ 35 void AttnMonitor::handleGPIOEvent() 36 { 37 gpiod_line_event gpioEvent; 38 std::string logMessage; 39 40 if (gpiod_line_event_read_fd(iv_gpioEventDescriptor.native_handle(), 41 &gpioEvent) < 0) 42 { 43 logMessage = "GPIO line read failed"; 44 trace<level::INFO>(logMessage.c_str()); 45 } 46 else 47 { 48 switch (gpiod_line_get_value(iv_gpioLine)) 49 { 50 // active attention when gpio == 0 51 case 0: 52 attnHandler(iv_config); 53 break; 54 55 // gpio == 1, GPIO handler should not be executing 56 case 1: 57 logMessage = "GPIO handler out of sync"; 58 trace<level::INFO>(logMessage.c_str()); 59 break; 60 61 // unexpected value 62 default: 63 logMessage = "GPIO line unexpected value"; 64 trace<level::INFO>(logMessage.c_str()); 65 } 66 } 67 scheduleGPIOEvent(); // continue monitoring gpio 68 } 69 70 /** @brief Request a GPIO line for monitoring attention events */ 71 void AttnMonitor::requestGPIOEvent() 72 { 73 if (0 != gpiod_line_request(iv_gpioLine, &iv_gpioConfig, 0)) 74 { 75 std::string logMessage = "failed request for GPIO"; 76 trace<level::INFO>(logMessage.c_str()); 77 } 78 else 79 { 80 int gpioLineFd; 81 82 gpioLineFd = gpiod_line_event_get_fd(iv_gpioLine); 83 if (gpioLineFd < 0) 84 { 85 std::string logMessage = "failed to get file descriptor"; 86 trace<level::INFO>(logMessage.c_str()); 87 } 88 else 89 { 90 // Register file descriptor for monitoring 91 iv_gpioEventDescriptor.assign(gpioLineFd); 92 93 // Start monitoring 94 scheduleGPIOEvent(); 95 } 96 } 97 } 98 99 } // namespace attn 100