xref: /openbmc/phosphor-gpio-monitor/monitor.hpp (revision bc4a4ff6e4d0688727d54e73356be617acf18035)
1 #pragma once
2 
3 #include <unistd.h>
4 #include <string>
5 #include <linux/input.h>
6 #include <systemd/sd-event.h>
7 #include <sdbusplus/bus.hpp>
8 #include "evdev.hpp"
9 
10 namespace phosphor
11 {
12 namespace gpio
13 {
14 
15 /** @class Monitor
16  *  @brief Responsible for catching GPIO state change
17  *  condition and starting systemd targets.
18  */
19 class Monitor : public Evdev
20 {
21     public:
22         Monitor() = delete;
23         ~Monitor() = default;
24         Monitor(const Monitor&) = delete;
25         Monitor& operator=(const Monitor&) = delete;
26         Monitor(Monitor&&) = delete;
27         Monitor& operator=(Monitor&&) = delete;
28 
29         /** @brief Constructs Monitor object.
30          *
31          *  @param[in] path     - Path to gpio input device
32          *  @param[in] key      - GPIO key to monitor
33          *  @param[in] polarity - GPIO assertion polarity to look for
34          *  @param[in] target   - systemd unit to be started on GPIO
35          *                        value change
36          *  @param[in] event    - sd_event handler
37          *  @param[in] continueRun - Whether to continue after key pressed
38          *  @param[in] handler  - IO callback handler. Defaults to one in this
39          *                        class
40          *  @param[in] useEvDev - Whether to use EvDev to retrieve events
41          */
42         Monitor(const std::string& path,
43                 decltype(input_event::code) key,
44                 decltype(input_event::value) polarity,
45                 const std::string& target,
46                 EventPtr& event,
47                 bool continueRun,
48                 sd_event_io_handler_t handler = Monitor::processEvents,
49                 bool useEvDev = true)
50             : Evdev(path, key, event, handler, useEvDev),
51               polarity(polarity),
52               target(target),
53               continueAfterKeyPress(continueRun) {};
54 
55         /** @brief Callback handler when the FD has some activity on it
56          *
57          *  @param[in] es       - Populated event source
58          *  @param[in] fd       - Associated File descriptor
59          *  @param[in] revents  - Type of event
60          *  @param[in] userData - User data that was passed during registration
61          *
62          *  @return             - 0 or positive number on success and negative
63          *                        errno otherwise
64          */
65         static int processEvents(sd_event_source* es, int fd,
66                                  uint32_t revents, void* userData);
67 
68         /** @brief Returns the completion state of this handler */
69         inline auto completed() const
70         {
71             return complete;
72         }
73 
74     private:
75         /** @brief GPIO key value that is of interest */
76         decltype(input_event::value) polarity;
77 
78         /** @brief Systemd unit to be started when the condition is met */
79         const std::string& target;
80 
81         /** @brief If the monitor should continue after key press */
82         bool continueAfterKeyPress;
83 
84         /** @brief Completion indicator */
85         bool complete = false;
86 
87         /** @brief Analyzes the GPIO event and starts configured target */
88         void analyzeEvent();
89 };
90 
91 } // namespace gpio
92 } // namespace phosphor
93