blob: 25bdce41e89f950449ad72e2014cfb392c91af8f [file] [log] [blame]
Ben Tyner73ac3682020-01-09 10:46:47 -06001#include "attn_monitor.hpp"
2
3#include "attn_handler.hpp"
4
Ben Tyner9ae5ca42020-02-28 13:13:50 -06005#include <logging.hpp>
Ben Tyner73ac3682020-01-09 10:46:47 -06006
7namespace attn
8{
9
10/** @brief Register a callback for gpio event */
11void AttnMonitor::scheduleGPIOEvent()
12{
Ben Tyner9ae5ca42020-02-28 13:13:50 -060013 std::string logMessage = "... waiting for events ...";
Ben Tyner73ac3682020-01-09 10:46:47 -060014 log<level::INFO>(logMessage.c_str());
15
16 // Register async callback, note that callback is a
17 // lambda function with "this" pointer captured
18 iv_gpioEventDescriptor.async_wait(
19 boost::asio::posix::stream_descriptor::wait_read,
20 [this](const boost::system::error_code& ec) {
21 if (ec)
22 {
Ben Tyner9ae5ca42020-02-28 13:13:50 -060023 std::string logMessage =
24 "GPIO Async wait error: " + std::string(ec.message());
Ben Tyner73ac3682020-01-09 10:46:47 -060025 log<level::INFO>(logMessage.c_str());
26 }
27 else
28 {
Ben Tyner117af992020-05-22 13:32:11 -050029 log<level::INFO>("Attention monitor detected active attention");
Ben Tyner73ac3682020-01-09 10:46:47 -060030 handleGPIOEvent(); // gpio trigger detected
31 }
32 return;
33 }); // register async callback
34}
35
36/** @brief Handle the GPIO state change event */
37void AttnMonitor::handleGPIOEvent()
38{
39 gpiod_line_event gpioEvent;
40 std::string logMessage;
41
42 if (gpiod_line_event_read_fd(iv_gpioEventDescriptor.native_handle(),
43 &gpioEvent) < 0)
44 {
Ben Tyner9ae5ca42020-02-28 13:13:50 -060045 logMessage = "GPIO line read failed";
Ben Tyner73ac3682020-01-09 10:46:47 -060046 log<level::INFO>(logMessage.c_str());
47 }
48 else
49 {
50 switch (gpiod_line_get_value(iv_gpioLine))
51 {
52 // active attention when gpio == 0
53 case 0:
Ben Tyner117af992020-05-22 13:32:11 -050054 logMessage = "Attention monitor calling attention handler";
55 log<level::INFO>(logMessage.c_str());
Ben Tyner3fb52e52020-03-31 10:10:07 -050056 attnHandler(iv_config);
Ben Tyner73ac3682020-01-09 10:46:47 -060057 break;
58
59 // gpio == 1, GPIO handler should not be executing
60 case 1:
Ben Tyner9ae5ca42020-02-28 13:13:50 -060061 logMessage = "GPIO handler out of sync";
Ben Tyner73ac3682020-01-09 10:46:47 -060062 log<level::INFO>(logMessage.c_str());
63 break;
64
65 // unexpected value
66 default:
Ben Tyner9ae5ca42020-02-28 13:13:50 -060067 logMessage = "GPIO line unexpected value";
Ben Tyner73ac3682020-01-09 10:46:47 -060068 log<level::INFO>(logMessage.c_str());
69 }
70 }
71 scheduleGPIOEvent(); // continue monitoring gpio
72}
73
74/** @brief Request a GPIO line for monitoring attention events */
75void AttnMonitor::requestGPIOEvent()
76{
77 if (0 != gpiod_line_request(iv_gpioLine, &iv_gpioConfig, 0))
78 {
Ben Tyner9ae5ca42020-02-28 13:13:50 -060079 std::string logMessage = "failed request for GPIO";
Ben Tyner73ac3682020-01-09 10:46:47 -060080 log<level::INFO>(logMessage.c_str());
81 }
82 else
83 {
84 int gpioLineFd;
85
86 gpioLineFd = gpiod_line_event_get_fd(iv_gpioLine);
87 if (gpioLineFd < 0)
88 {
Ben Tyner9ae5ca42020-02-28 13:13:50 -060089 std::string logMessage = "failed to get file descriptor";
Ben Tyner73ac3682020-01-09 10:46:47 -060090 log<level::INFO>(logMessage.c_str());
91 }
92 else
93 {
94 // Register file descriptor for monitoring
95 iv_gpioEventDescriptor.assign(gpioLineFd);
96
97 // Start monitoring
98 scheduleGPIOEvent();
99 }
100 }
101}
102
103} // namespace attn