blob: 25b35a5e8fc7274768fbddf575c322a1a36d6fb1 [file] [log] [blame]
Ben Tynerb797b3e2020-06-29 10:12:05 -05001#include <attn/attn_handler.hpp>
2#include <attn/attn_logging.hpp>
3#include <attn/attn_monitor.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 Tyner9ae5ca42020-02-28 13:13:50 -060011 std::string logMessage = "... waiting for events ...";
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050012 trace<level::INFO>(logMessage.c_str());
Ben Tyner73ac3682020-01-09 10:46:47 -060013
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 {
Ben Tyner9ae5ca42020-02-28 13:13:50 -060021 std::string logMessage =
22 "GPIO Async wait error: " + std::string(ec.message());
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050023 trace<level::INFO>(logMessage.c_str());
Ben Tyner73ac3682020-01-09 10:46:47 -060024 }
25 else
26 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050027 trace<level::INFO>(
28 "Attention monitor detected active attention");
Ben Tyner73ac3682020-01-09 10:46:47 -060029 handleGPIOEvent(); // gpio trigger detected
30 }
31 return;
32 }); // register async callback
33}
34
35/** @brief Handle the GPIO state change event */
36void 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 {
Ben Tyner9ae5ca42020-02-28 13:13:50 -060044 logMessage = "GPIO line read failed";
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050045 trace<level::INFO>(logMessage.c_str());
Ben Tyner73ac3682020-01-09 10:46:47 -060046 }
47 else
48 {
49 switch (gpiod_line_get_value(iv_gpioLine))
50 {
51 // active attention when gpio == 0
52 case 0:
Ben Tyner117af992020-05-22 13:32:11 -050053 logMessage = "Attention monitor calling attention handler";
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050054 trace<level::INFO>(logMessage.c_str());
Ben Tyner3fb52e52020-03-31 10:10:07 -050055 attnHandler(iv_config);
Ben Tyner73ac3682020-01-09 10:46:47 -060056 break;
57
58 // gpio == 1, GPIO handler should not be executing
59 case 1:
Ben Tyner9ae5ca42020-02-28 13:13:50 -060060 logMessage = "GPIO handler out of sync";
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050061 trace<level::INFO>(logMessage.c_str());
Ben Tyner73ac3682020-01-09 10:46:47 -060062 break;
63
64 // unexpected value
65 default:
Ben Tyner9ae5ca42020-02-28 13:13:50 -060066 logMessage = "GPIO line unexpected value";
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050067 trace<level::INFO>(logMessage.c_str());
Ben Tyner73ac3682020-01-09 10:46:47 -060068 }
69 }
70 scheduleGPIOEvent(); // continue monitoring gpio
71}
72
73/** @brief Request a GPIO line for monitoring attention events */
74void AttnMonitor::requestGPIOEvent()
75{
76 if (0 != gpiod_line_request(iv_gpioLine, &iv_gpioConfig, 0))
77 {
Ben Tyner9ae5ca42020-02-28 13:13:50 -060078 std::string logMessage = "failed request for GPIO";
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050079 trace<level::INFO>(logMessage.c_str());
Ben Tyner73ac3682020-01-09 10:46:47 -060080 }
81 else
82 {
83 int gpioLineFd;
84
85 gpioLineFd = gpiod_line_event_get_fd(iv_gpioLine);
86 if (gpioLineFd < 0)
87 {
Ben Tyner9ae5ca42020-02-28 13:13:50 -060088 std::string logMessage = "failed to get file descriptor";
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050089 trace<level::INFO>(logMessage.c_str());
Ben Tyner73ac3682020-01-09 10:46:47 -060090 }
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