blob: 34803c1111cc7a55d755a7c0eea593b84a76a64b [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 Subbannaba730132017-04-04 14:08:26 +05307#include <sdbusplus/bus.hpp>
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +05308#include "file.hpp"
9namespace phosphor
10{
11namespace gpio
12{
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +053013
14/* Need a custom deleter for freeing up sd_event */
15struct EventDeleter
16{
17 void operator()(sd_event* event) const
18 {
19 event = sd_event_unref(event);
20 }
21};
22using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
23
24/* Need a custom deleter for freeing up sd_event_source */
25struct EventSourceDeleter
26{
27 void operator()(sd_event_source* eventSource) const
28 {
29 eventSource = sd_event_source_unref(eventSource);
30 }
31};
32using EventSourcePtr = std::unique_ptr<sd_event_source, EventSourceDeleter>;
33
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +053034/** @class Monitor
35 * @brief Responsible for catching GPIO state change
36 * condition and taking actions
37 */
38class Monitor
39{
40 public:
41 Monitor() = delete;
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +053042 ~Monitor() = default;
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +053043 Monitor(const Monitor&) = delete;
44 Monitor& operator=(const Monitor&) = delete;
45 Monitor(Monitor&&) = delete;
46 Monitor& operator=(Monitor&&) = delete;
47
48 /** @brief Constructs Monitor object.
49 *
50 * @param[in] path - Path to gpio input device
51 * @param[in] key - GPIO key to monitor
52 * @param[in] polarity - GPIO assertion polarity to look for
53 * @param[in] target - systemd unit to be started on GPIO
54 * value change
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +053055 * @param[in] event - sd_event handler
56 * @param[in] handler - IO callback handler. Defaults to one in this
57 * class
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +053058 */
59 Monitor(const std::string& path,
60 decltype(input_event::code) key,
61 decltype(input_event::value) polarity,
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +053062 const std::string& target,
63 EventPtr& event,
64 sd_event_io_handler_t handler = Monitor::processEvents)
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +053065 : path(path),
66 key(key),
67 polarity(polarity),
68 target(target),
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +053069 event(event),
70 callbackHandler(handler),
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +053071 fd(openDevice())
72 {
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +053073 // And register callback handler when FD has some data
74 registerCallback();
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +053075 }
76
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +053077 /** @brief Callback handler when the FD has some activity on it
78 *
79 * @param[in] es - Populated event source
80 * @param[in] fd - Associated File descriptor
81 * @param[in] revents - Type of event
82 * @param[in] userData - User data that was passed during registration
83 *
84 * @return - 0 or positive number on success and negative
85 * errno otherwise
86 */
87 static int processEvents(sd_event_source* es, int fd,
88 uint32_t revents, void* userData);
89
Vishwanatha Subbannaba730132017-04-04 14:08:26 +053090 /** @brief Returns the completion state of this handler */
91 inline auto completed() const
92 {
93 return complete;
94 }
95
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +053096 private:
97 /** @brief Absolute path of GPIO input device */
98 const std::string& path;
99
100 /** @brief GPIO key code that is of interest */
101 decltype(input_event::code) key;
102
103 /** @brief GPIO key value that is of interest */
104 decltype(input_event::value) polarity;
105
106 /** @brief Systemd unit to be started when the condition is met */
107 const std::string& target;
108
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +0530109 /** @brief Monitor to sd_event */
110 EventPtr& event;
111
112 /** @brief event source */
113 EventSourcePtr eventSource;
114
115 /** @brief Callback handler when the FD has some data */
116 sd_event_io_handler_t callbackHandler;
117
118 /** @brief File descriptor manager */
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +0530119 FileDescriptor fd;
120
Vishwanatha Subbannaba730132017-04-04 14:08:26 +0530121 /** @brief Completion indicator */
122 bool complete = false;
123
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +0530124 /** @brief Opens the device and populates the descriptor */
125 int openDevice();
Vishwanatha Subbanna0b956032017-04-04 14:07:25 +0530126
127 /** @brief attaches FD to events and sets up callback handler */
128 void registerCallback();
Vishwanatha Subbannaba730132017-04-04 14:08:26 +0530129
130 /** @brief Analyzes the GPIO event and starts configured target
131 *
132 * @return - For now, returns zero
133 */
134 int analyzeEvent();
Vishwanatha Subbanna4902a102017-04-04 14:05:09 +0530135};
136
137} // namespace gpio
138} // namespace phosphor