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