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