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