1 #include "attn_monitor.hpp"
2 
3 #include "attn_handler.hpp"
4 
5 #include <phosphor-logging/log.hpp>
6 
7 using namespace phosphor::logging;
8 
9 namespace attn
10 {
11 
12 /** @brief Register a callback for gpio event */
13 void AttnMonitor::scheduleGPIOEvent()
14 {
15     std::string logMessage = "[ATTN] ... waiting for events ...";
16     log<level::INFO>(logMessage.c_str());
17 
18     // Register async callback, note that callback is a
19     // lambda function with "this" pointer captured
20     iv_gpioEventDescriptor.async_wait(
21         boost::asio::posix::stream_descriptor::wait_read,
22         [this](const boost::system::error_code& ec) {
23             if (ec)
24             {
25                 std::string logMessage = "[ATTN] ATTN GPIO Async error: " +
26                                          std::string(ec.message());
27                 log<level::INFO>(logMessage.c_str());
28             }
29             else
30             {
31                 handleGPIOEvent(); // gpio trigger detected
32             }
33             return;
34         }); // register async callback
35 }
36 
37 /** @brief Handle the GPIO state change event */
38 void AttnMonitor::handleGPIOEvent()
39 {
40     gpiod_line_event gpioEvent;
41     std::string logMessage;
42 
43     if (gpiod_line_event_read_fd(iv_gpioEventDescriptor.native_handle(),
44                                  &gpioEvent) < 0)
45     {
46         logMessage = "[ATTN] ATTN GPIO Failed can't read file descriptor!";
47         log<level::INFO>(logMessage.c_str());
48     }
49     else
50     {
51         switch (gpiod_line_get_value(iv_gpioLine))
52         {
53             // active attention when gpio == 0
54             case 0:
55                 attnHandler(iv_breakpoints);
56                 break;
57 
58             // gpio == 1, GPIO handler should not be executing
59             case 1:
60                 logMessage = "[ATTN] ATTN GPIO sync!";
61                 log<level::INFO>(logMessage.c_str());
62                 break;
63 
64             // unexpected value
65             default:
66                 logMessage = "[ATTN] ATTN GPIO read unexpected valuel!";
67                 log<level::INFO>(logMessage.c_str());
68         }
69     }
70     scheduleGPIOEvent(); // continue monitoring gpio
71 }
72 
73 /** @brief Request a GPIO line for monitoring attention events */
74 void AttnMonitor::requestGPIOEvent()
75 {
76     if (0 != gpiod_line_request(iv_gpioLine, &iv_gpioConfig, 0))
77     {
78         std::string logMessage = "[ATTN] failed request for GPIO";
79         log<level::INFO>(logMessage.c_str());
80     }
81     else
82     {
83         int gpioLineFd;
84 
85         gpioLineFd = gpiod_line_event_get_fd(iv_gpioLine);
86         if (gpioLineFd < 0)
87         {
88             std::string logMessage = "[ATTN] failed to get file descriptor";
89             log<level::INFO>(logMessage.c_str());
90         }
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
103