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