blob: 10277145333a880da6124159755c0843024f427a [file] [log] [blame]
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +05301#pragma once
2
3#include <unistd.h>
4#include <string>
5#include <linux/input.h>
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +05306#include <systemd/sd-event.h>
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +05307#include "file.hpp"
8namespace phosphor
9{
10namespace gpio
11{
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +053012
13/* Need a custom deleter for freeing up sd_event */
14struct EventDeleter
15{
16 void operator()(sd_event* event) const
17 {
18 event = sd_event_unref(event);
19 }
20};
21using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
22
23/* Need a custom deleter for freeing up sd_event_source */
24struct EventSourceDeleter
25{
26 void operator()(sd_event_source* eventSource) const
27 {
28 eventSource = sd_event_source_unref(eventSource);
29 }
30};
31using EventSourcePtr = std::unique_ptr<sd_event_source, EventSourceDeleter>;
32
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +053033/** @class Monitor
34 * @brief Responsible for catching GPIO state change
35 * condition and taking actions
36 */
37class Monitor
38{
39 public:
40 Monitor() = delete;
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +053041 ~Monitor() = default;
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +053042 Monitor(const Monitor&) = delete;
43 Monitor& operator=(const Monitor&) = delete;
44 Monitor(Monitor&&) = delete;
45 Monitor& operator=(Monitor&&) = delete;
46
47 /** @brief Constructs Monitor object.
48 *
49 * @param[in] path - Path to gpio input device
50 * @param[in] key - GPIO key to monitor
51 * @param[in] polarity - GPIO assertion polarity to look for
52 * @param[in] target - systemd unit to be started on GPIO
53 * value change
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +053054 * @param[in] event - sd_event handler
55 * @param[in] handler - IO callback handler. Defaults to one in this
56 * class
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +053057 */
58 Monitor(const std::string& path,
59 decltype(input_event::code) key,
60 decltype(input_event::value) polarity,
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +053061 const std::string& target,
62 EventPtr& event,
63 sd_event_io_handler_t handler = Monitor::processEvents)
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +053064 : path(path),
65 key(key),
66 polarity(polarity),
67 target(target),
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +053068 event(event),
69 callbackHandler(handler),
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +053070 fd(openDevice())
71 {
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +053072 // And register callback handler when FD has some data
73 registerCallback();
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +053074 }
75
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +053076 /** @brief Callback handler when the FD has some activity on it
77 *
78 * @param[in] es - Populated event source
79 * @param[in] fd - Associated File descriptor
80 * @param[in] revents - Type of event
81 * @param[in] userData - User data that was passed during registration
82 *
83 * @return - 0 or positive number on success and negative
84 * errno otherwise
85 */
86 static int processEvents(sd_event_source* es, int fd,
87 uint32_t revents, void* userData);
88
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +053089 private:
90 /** @brief Absolute path of GPIO input device */
91 const std::string& path;
92
93 /** @brief GPIO key code that is of interest */
94 decltype(input_event::code) key;
95
96 /** @brief GPIO key value that is of interest */
97 decltype(input_event::value) polarity;
98
99 /** @brief Systemd unit to be started when the condition is met */
100 const std::string& target;
101
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +0530102 /** @brief Monitor to sd_event */
103 EventPtr& event;
104
105 /** @brief event source */
106 EventSourcePtr eventSource;
107
108 /** @brief Callback handler when the FD has some data */
109 sd_event_io_handler_t callbackHandler;
110
111 /** @brief File descriptor manager */
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +0530112 FileDescriptor fd;
113
114 /** @brief Opens the device and populates the descriptor */
115 int openDevice();
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +0530116
117 /** @brief attaches FD to events and sets up callback handler */
118 void registerCallback();
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +0530119};
120
121} // namespace gpio
122} // namespace phosphor