blob: a3ecfacb9a78cf0f4c6cbdce126f258574dfbe65 [file] [log] [blame]
Ben Tynerb797b3e2020-06-29 10:12:05 -05001#include <attn/attn_handler.hpp>
Ben Tynerb797b3e2020-06-29 10:12:05 -05002#include <attn/attn_monitor.hpp>
austinfcuibfa831a2022-01-26 15:37:07 -06003#include <util/trace.hpp>
Ben Tyner73ac3682020-01-09 10:46:47 -06004
5namespace attn
6{
7
8/** @brief Register a callback for gpio event */
9void AttnMonitor::scheduleGPIOEvent()
10{
Ben Tyner73ac3682020-01-09 10:46:47 -060011 // Register async callback, note that callback is a
12 // lambda function with "this" pointer captured
13 iv_gpioEventDescriptor.async_wait(
14 boost::asio::posix::stream_descriptor::wait_read,
15 [this](const boost::system::error_code& ec) {
16 if (ec)
17 {
austinfcuibfa831a2022-01-26 15:37:07 -060018 trace::err("GPIO Async wait error: %s", ec.message().c_str());
Ben Tyner73ac3682020-01-09 10:46:47 -060019 }
20 else
21 {
austinfcuibfa831a2022-01-26 15:37:07 -060022 trace::inf("Attention GPIO active");
Ben Tyner73ac3682020-01-09 10:46:47 -060023 handleGPIOEvent(); // gpio trigger detected
24 }
25 return;
26 }); // register async callback
27}
28
29/** @brief Handle the GPIO state change event */
30void AttnMonitor::handleGPIOEvent()
31{
32 gpiod_line_event gpioEvent;
Ben Tyner73ac3682020-01-09 10:46:47 -060033
34 if (gpiod_line_event_read_fd(iv_gpioEventDescriptor.native_handle(),
35 &gpioEvent) < 0)
36 {
austinfcuibfa831a2022-01-26 15:37:07 -060037 trace::err("GPIO line read failed");
Ben Tyner73ac3682020-01-09 10:46:47 -060038 }
39 else
40 {
41 switch (gpiod_line_get_value(iv_gpioLine))
42 {
43 // active attention when gpio == 0
44 case 0:
Ben Tyner3fb52e52020-03-31 10:10:07 -050045 attnHandler(iv_config);
Ben Tyner73ac3682020-01-09 10:46:47 -060046 break;
47
48 // gpio == 1, GPIO handler should not be executing
49 case 1:
austinfcuibfa831a2022-01-26 15:37:07 -060050 trace::inf("GPIO handler out of sync");
Ben Tyner73ac3682020-01-09 10:46:47 -060051 break;
52
53 // unexpected value
54 default:
austinfcuibfa831a2022-01-26 15:37:07 -060055 trace::inf("GPIO line unexpected value");
Ben Tyner73ac3682020-01-09 10:46:47 -060056 }
57 }
58 scheduleGPIOEvent(); // continue monitoring gpio
59}
60
61/** @brief Request a GPIO line for monitoring attention events */
62void AttnMonitor::requestGPIOEvent()
63{
64 if (0 != gpiod_line_request(iv_gpioLine, &iv_gpioConfig, 0))
65 {
austinfcuibfa831a2022-01-26 15:37:07 -060066 trace::err("failed request for GPIO");
Ben Tyner73ac3682020-01-09 10:46:47 -060067 }
68 else
69 {
70 int gpioLineFd;
71
72 gpioLineFd = gpiod_line_event_get_fd(iv_gpioLine);
73 if (gpioLineFd < 0)
74 {
austinfcuibfa831a2022-01-26 15:37:07 -060075 trace::err("failed to get file descriptor");
Ben Tyner73ac3682020-01-09 10:46:47 -060076 }
77 else
78 {
79 // Register file descriptor for monitoring
80 iv_gpioEventDescriptor.assign(gpioLineFd);
81
82 // Start monitoring
83 scheduleGPIOEvent();
84 }
85 }
86}
87
88} // namespace attn