blob: eb7781b02c9e603f5b794df6dd154b10f52f9327 [file] [log] [blame]
Gunnar Mills835dfb82017-07-26 16:15:21 -05001#pragma once
Gunnar Mills835dfb82017-07-26 16:15:21 -05002#include "file.hpp"
3
Patrick Venturedace6802018-11-01 16:52:10 -07004#include <libevdev/libevdev.h>
5#include <systemd/sd-event.h>
6
7#include <map>
8#include <memory>
9#include <sdbusplus/message.hpp>
10#include <string>
11
Gunnar Mills835dfb82017-07-26 16:15:21 -050012namespace phosphor
13{
14namespace gpio
15{
16
17/* Need a custom deleter for freeing up sd_event */
18struct EventDeleter
19{
20 void operator()(sd_event* event) const
21 {
22 event = sd_event_unref(event);
23 }
24};
25using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
26
27/* Need a custom deleter for freeing up sd_event_source */
28struct EventSourceDeleter
29{
30 void operator()(sd_event_source* eventSource) const
31 {
32 eventSource = sd_event_source_unref(eventSource);
33 }
34};
35using EventSourcePtr = std::unique_ptr<sd_event_source, EventSourceDeleter>;
36
37/* Need a custom deleter for freeing up evdev struct */
38struct FreeEvDev
39{
40 void operator()(struct libevdev* device) const
41 {
42 libevdev_free(device);
43 }
44};
45using EvdevPtr = std::unique_ptr<struct libevdev, FreeEvDev>;
46
47/** @class Evdev
48 * @brief Responsible for catching GPIO state changes conditions and taking
49 * actions
50 */
51class Evdev
52{
53
Patrick Venturedace6802018-11-01 16:52:10 -070054 using Property = std::string;
55 using Value = sdbusplus::message::variant<bool, std::string>;
56 // Association between property and its value
57 using PropertyMap = std::map<Property, Value>;
58 using Interface = std::string;
59 // Association between interface and the D-Bus property
60 using InterfaceMap = std::map<Interface, PropertyMap>;
61 using Object = sdbusplus::message::object_path;
62 // Association between object and the interface
63 using ObjectMap = std::map<Object, InterfaceMap>;
Gunnar Mills835dfb82017-07-26 16:15:21 -050064
Patrick Venturedace6802018-11-01 16:52:10 -070065 public:
66 Evdev() = delete;
67 ~Evdev() = default;
68 Evdev(const Evdev&) = delete;
69 Evdev& operator=(const Evdev&) = delete;
70 Evdev(Evdev&&) = delete;
71 Evdev& operator=(Evdev&&) = delete;
Gunnar Mills835dfb82017-07-26 16:15:21 -050072
Patrick Venturedace6802018-11-01 16:52:10 -070073 /** @brief Constructs Evdev object.
74 *
75 * @param[in] path - Device path to read for GPIO pin state
76 * @param[in] key - GPIO key to monitor
77 * @param[in] event - sd_event handler
78 * @param[in] handler - IO callback handler.
79 * @param[in] useEvDev - Whether to use EvDev to retrieve events
80 */
81 Evdev(const std::string& path, const unsigned int key, EventPtr& event,
82 sd_event_io_handler_t handler, bool useEvDev = true) :
83 path(path),
84 key(key), event(event), callbackHandler(handler), fd(openDevice())
Gunnar Mills835dfb82017-07-26 16:15:21 -050085
Patrick Venturedace6802018-11-01 16:52:10 -070086 {
87 if (useEvDev)
Gunnar Mills835dfb82017-07-26 16:15:21 -050088 {
Patrick Venturedace6802018-11-01 16:52:10 -070089 // If we are asked to use EvDev, do that initialization.
90 initEvDev();
Gunnar Mills835dfb82017-07-26 16:15:21 -050091 }
92
Patrick Venturedace6802018-11-01 16:52:10 -070093 // Register callback handler when FD has some data
94 registerCallback();
95 }
Gunnar Mills835dfb82017-07-26 16:15:21 -050096
Patrick Venturedace6802018-11-01 16:52:10 -070097 protected:
98 /** @brief Device path to read for GPIO pin state */
99 const std::string path;
Gunnar Mills835dfb82017-07-26 16:15:21 -0500100
Patrick Venturedace6802018-11-01 16:52:10 -0700101 /** @brief GPIO key to monitor */
102 const unsigned int key;
Gunnar Mills835dfb82017-07-26 16:15:21 -0500103
Patrick Venturedace6802018-11-01 16:52:10 -0700104 /** @brief Event structure */
105 EvdevPtr devicePtr;
Gunnar Mills835dfb82017-07-26 16:15:21 -0500106
Patrick Venturedace6802018-11-01 16:52:10 -0700107 /** @brief Monitor to sd_event */
108 EventPtr& event;
Gunnar Mills835dfb82017-07-26 16:15:21 -0500109
Patrick Venturedace6802018-11-01 16:52:10 -0700110 /** @brief Callback handler when the FD has some data */
111 sd_event_io_handler_t callbackHandler;
Gunnar Mills835dfb82017-07-26 16:15:21 -0500112
Patrick Venturedace6802018-11-01 16:52:10 -0700113 /** @brief event source */
114 EventSourcePtr eventSource;
Gunnar Mills835dfb82017-07-26 16:15:21 -0500115
Patrick Venturedace6802018-11-01 16:52:10 -0700116 /** @brief Opens the device and populates the descriptor */
117 int openDevice();
Gunnar Mills835dfb82017-07-26 16:15:21 -0500118
Patrick Venturedace6802018-11-01 16:52:10 -0700119 /** @brief attaches FD to events and sets up callback handler */
120 void registerCallback();
Gunnar Mills835dfb82017-07-26 16:15:21 -0500121
Patrick Venturedace6802018-11-01 16:52:10 -0700122 /** @brief File descriptor manager */
123 FileDescriptor fd;
124
125 /** @brief Initializes evdev handle with the fd */
126 void initEvDev();
Gunnar Mills835dfb82017-07-26 16:15:21 -0500127};
128
129} // namespace gpio
130} // namespace phosphor