blob: 053d615d1011cbdf01b78d0eb7dec72bfda55d45 [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 Tyner18db69a2020-08-20 08:23:07 -050011 // std::string logMessage = "... waiting for events ...";
12 // 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 Tyner1965e502020-11-20 10:32:24 -060027 trace<level::INFO>("Attention GPIO active");
Ben Tyner73ac3682020-01-09 10:46:47 -060028 handleGPIOEvent(); // gpio trigger detected
29 }
30 return;
31 }); // register async callback
32}
33
34/** @brief Handle the GPIO state change event */
35void 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 {
Ben Tyner9ae5ca42020-02-28 13:13:50 -060043 logMessage = "GPIO line read failed";
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050044 trace<level::INFO>(logMessage.c_str());
Ben Tyner73ac3682020-01-09 10:46:47 -060045 }
46 else
47 {
48 switch (gpiod_line_get_value(iv_gpioLine))
49 {
50 // active attention when gpio == 0
51 case 0:
Ben Tyner3fb52e52020-03-31 10:10:07 -050052 attnHandler(iv_config);
Ben Tyner73ac3682020-01-09 10:46:47 -060053 break;
54
55 // gpio == 1, GPIO handler should not be executing
56 case 1:
Ben Tyner9ae5ca42020-02-28 13:13:50 -060057 logMessage = "GPIO handler out of sync";
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050058 trace<level::INFO>(logMessage.c_str());
Ben Tyner73ac3682020-01-09 10:46:47 -060059 break;
60
61 // unexpected value
62 default:
Ben Tyner9ae5ca42020-02-28 13:13:50 -060063 logMessage = "GPIO line unexpected value";
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050064 trace<level::INFO>(logMessage.c_str());
Ben Tyner73ac3682020-01-09 10:46:47 -060065 }
66 }
67 scheduleGPIOEvent(); // continue monitoring gpio
68}
69
70/** @brief Request a GPIO line for monitoring attention events */
71void AttnMonitor::requestGPIOEvent()
72{
73 if (0 != gpiod_line_request(iv_gpioLine, &iv_gpioConfig, 0))
74 {
Ben Tyner9ae5ca42020-02-28 13:13:50 -060075 std::string logMessage = "failed request for GPIO";
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050076 trace<level::INFO>(logMessage.c_str());
Ben Tyner73ac3682020-01-09 10:46:47 -060077 }
78 else
79 {
80 int gpioLineFd;
81
82 gpioLineFd = gpiod_line_event_get_fd(iv_gpioLine);
83 if (gpioLineFd < 0)
84 {
Ben Tyner9ae5ca42020-02-28 13:13:50 -060085 std::string logMessage = "failed to get file descriptor";
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050086 trace<level::INFO>(logMessage.c_str());
Ben Tyner73ac3682020-01-09 10:46:47 -060087 }
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