blob: 353c5934908dba930ec7a96a7b92c8bbd142dad8 [file] [log] [blame]
Gunnar Mills835dfb82017-07-26 16:15:21 -05001#pragma once
2#include <string>
3#include <systemd/sd-event.h>
4#include <libevdev/libevdev.h>
5#include "file.hpp"
6
7namespace phosphor
8{
9namespace gpio
10{
11
12/* Need a custom deleter for freeing up sd_event */
13struct EventDeleter
14{
15 void operator()(sd_event* event) const
16 {
17 event = sd_event_unref(event);
18 }
19};
20using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
21
22/* Need a custom deleter for freeing up sd_event_source */
23struct EventSourceDeleter
24{
25 void operator()(sd_event_source* eventSource) const
26 {
27 eventSource = sd_event_source_unref(eventSource);
28 }
29};
30using EventSourcePtr = std::unique_ptr<sd_event_source, EventSourceDeleter>;
31
32/* Need a custom deleter for freeing up evdev struct */
33struct FreeEvDev
34{
35 void operator()(struct libevdev* device) const
36 {
37 libevdev_free(device);
38 }
39};
40using EvdevPtr = std::unique_ptr<struct libevdev, FreeEvDev>;
41
42/** @class Evdev
43 * @brief Responsible for catching GPIO state changes conditions and taking
44 * actions
45 */
46class Evdev
47{
48
49 using Property = std::string;
50 using Value = sdbusplus::message::variant<bool, std::string>;
51 // Association between property and its value
52 using PropertyMap = std::map<Property, Value>;
53 using Interface = std::string;
54 // Association between interface and the D-Bus property
55 using InterfaceMap = std::map<Interface, PropertyMap>;
56 using Object = sdbusplus::message::object_path;
57 // Association between object and the interface
58 using ObjectMap = std::map<Object, InterfaceMap>;
59
60 public:
61 Evdev() = delete;
62 ~Evdev() = default;
63 Evdev(const Evdev&) = delete;
64 Evdev& operator=(const Evdev&) = delete;
65 Evdev(Evdev&&) = delete;
66 Evdev& operator=(Evdev&&) = delete;
67
68 /** @brief Constructs Evdev object.
69 *
70 * @param[in] path - Device path to read for GPIO pin state
71 * @param[in] key - GPIO key to monitor
72 * @param[in] event - sd_event handler
Gunnar Mills99258572017-07-27 15:22:42 -050073 * @param[in] handler - IO callback handler.
Gunnar Mills835dfb82017-07-26 16:15:21 -050074 * @param[in] useEvDev - Whether to use EvDev to retrieve events
75 */
76 Evdev(const std::string& path,
77 const unsigned int key,
78 EventPtr& event,
79 sd_event_io_handler_t handler,
80 bool useEvDev = true) :
81 path(path),
82 key(key),
83 event(event),
84 callbackHandler(handler),
85 fd(openDevice())
86
87 {
88 if (useEvDev)
89 {
90 // If we are asked to use EvDev, do that initialization.
91 initEvDev();
92 }
93
94 // Register callback handler when FD has some data
95 registerCallback();
96 }
97
98 protected:
99 /** @brief Device path to read for GPIO pin state */
100 const std::string path;
101
102 /** @brief GPIO key to monitor */
103 const unsigned int key;
104
105 /** @brief Event structure */
106 EvdevPtr devicePtr;
107
108 /** @brief Monitor to sd_event */
109 EventPtr& event;
110
111 /** @brief Callback handler when the FD has some data */
112 sd_event_io_handler_t callbackHandler;
113
114 /** @brief event source */
115 EventSourcePtr eventSource;
116
117 /** @brief Opens the device and populates the descriptor */
118 int openDevice();
119
120 /** @brief attaches FD to events and sets up callback handler */
121 void registerCallback();
122
123 /** @brief File descriptor manager */
124 FileDescriptor fd;
125
126 /** @brief Initializes evdev handle with the fd */
127 void initEvDev();
128};
129
130} // namespace gpio
131} // namespace phosphor