1 #pragma once
2 
3 #include <gpiod.h>
4 
5 #include <boost/asio/io_context.hpp>
6 #include <boost/asio/posix/stream_descriptor.hpp>
7 #include <map>
8 #include <vector>
9 
10 namespace phosphor
11 {
12 namespace gpio
13 {
14 
15 /** @class GpioMonitor
16  *  @brief Responsible for catching GPIO state change
17  *  condition and starting systemd targets.
18  */
19 class GpioMonitor
20 {
21   public:
22     GpioMonitor() = delete;
23     ~GpioMonitor() = default;
24     GpioMonitor(const GpioMonitor&) = delete;
25     GpioMonitor& operator=(const GpioMonitor&) = delete;
26     GpioMonitor(GpioMonitor&&) = delete;
27     GpioMonitor& operator=(GpioMonitor&&) = delete;
28 
29     /** @brief Constructs GpioMonitor object.
30      *
31      *  @param[in] line        - GPIO line from libgpiod
32      *  @param[in] config      - configuration of line with event
33      *  @param[in] io          - io service
34      *  @param[in] target      - systemd unit to be started on GPIO
35      *                           value change
36      *  @param[in] targets     - systemd units to be started on GPIO
37      *                           value change
38      *  @param[in] lineMsg     - GPIO line message to be used for log
39      *  @param[in] continueRun - Whether to continue after event occur
40      */
41     GpioMonitor(gpiod_line* line, gpiod_line_request_config& config,
42                 boost::asio::io_context& io, const std::string& target,
43                 const std::map<std::string, std::vector<std::string>>& targets,
44                 const std::string& lineMsg, bool continueRun) :
45         gpioLine(line),
46         gpioConfig(config), gpioEventDescriptor(io), target(target),
47         targets(targets), gpioLineMsg(lineMsg), continueAfterEvent(continueRun)
48     {
49         requestGPIOEvents();
50     };
51 
52   private:
53     /** @brief GPIO line */
54     gpiod_line* gpioLine;
55 
56     /** @brief GPIO line configuration */
57     gpiod_line_request_config gpioConfig;
58 
59     /** @brief GPIO event descriptor */
60     boost::asio::posix::stream_descriptor gpioEventDescriptor;
61 
62     /** @brief Systemd unit to be started when the condition is met */
63     const std::string target;
64 
65     /** @brief Multi systemd units to be started when the condition is met */
66     std::map<std::string, std::vector<std::string>> targets;
67 
68     /** @brief GPIO line name message */
69     std::string gpioLineMsg;
70 
71     /** @brief If the monitor should continue after event */
72     bool continueAfterEvent;
73 
74     /** @brief register handler for gpio event
75      *
76      *  @return  - 0 on success and -1 otherwise
77      */
78     int requestGPIOEvents();
79 
80     /** @brief Schedule an event handler for GPIO event to trigger */
81     void scheduleEventHandler();
82 
83     /** @brief Handle the GPIO event and starts configured target */
84     void gpioEventHandler();
85 };
86 
87 } // namespace gpio
88 } // namespace phosphor
89