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