blob: 2cb1ddeff8a5c6927d48af7d22220ec611f7da38 [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
Patrick Williams39084b42023-05-10 07:50:58 -05007#include <sdbusplus/message.hpp>
8
Patrick Venturedace6802018-11-01 16:52:10 -07009#include <map>
10#include <memory>
Patrick Venturedace6802018-11-01 16:52:10 -070011#include <string>
12
Gunnar Mills835dfb82017-07-26 16:15:21 -050013namespace phosphor
14{
15namespace gpio
16{
17
18/* Need a custom deleter for freeing up sd_event */
19struct EventDeleter
20{
21 void operator()(sd_event* event) const
22 {
George Liu9b4c6cf2023-08-03 11:01:27 +080023 sd_event_unref(event);
Gunnar Mills835dfb82017-07-26 16:15:21 -050024 }
25};
26using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
27
28/* Need a custom deleter for freeing up sd_event_source */
29struct EventSourceDeleter
30{
31 void operator()(sd_event_source* eventSource) const
32 {
George Liu9b4c6cf2023-08-03 11:01:27 +080033 sd_event_source_unref(eventSource);
Gunnar Mills835dfb82017-07-26 16:15:21 -050034 }
35};
36using EventSourcePtr = std::unique_ptr<sd_event_source, EventSourceDeleter>;
37
38/* Need a custom deleter for freeing up evdev struct */
39struct FreeEvDev
40{
41 void operator()(struct libevdev* device) const
42 {
43 libevdev_free(device);
44 }
45};
46using EvdevPtr = std::unique_ptr<struct libevdev, FreeEvDev>;
47
48/** @class Evdev
49 * @brief Responsible for catching GPIO state changes conditions and taking
50 * actions
51 */
52class Evdev
53{
Patrick Venturedace6802018-11-01 16:52:10 -070054 using Property = std::string;
Patrick Williams3ce88a72020-06-03 06:02:48 -050055 using Value = std::variant<bool, std::string>;
Patrick Venturedace6802018-11-01 16:52:10 -070056 // 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