Refactor GPIO Presence class
Refactor the GPIO Presence class to use a common class, Evdev,
to inherit from. Evdev does the basic libevdev handling.
A later commit moves monitor.hpp to this common class as well.
Change-Id: I3c872680c88f8f400fefe3af49eb9b84c7491ceb
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
diff --git a/evdev.hpp b/evdev.hpp
new file mode 100644
index 0000000..b3189f1
--- /dev/null
+++ b/evdev.hpp
@@ -0,0 +1,132 @@
+#pragma once
+#include <string>
+#include <systemd/sd-event.h>
+#include <libevdev/libevdev.h>
+#include "file.hpp"
+
+namespace phosphor
+{
+namespace gpio
+{
+
+/* Need a custom deleter for freeing up sd_event */
+struct EventDeleter
+{
+ void operator()(sd_event* event) const
+ {
+ event = sd_event_unref(event);
+ }
+};
+using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
+
+/* Need a custom deleter for freeing up sd_event_source */
+struct EventSourceDeleter
+{
+ void operator()(sd_event_source* eventSource) const
+ {
+ eventSource = sd_event_source_unref(eventSource);
+ }
+};
+using EventSourcePtr = std::unique_ptr<sd_event_source, EventSourceDeleter>;
+
+/* Need a custom deleter for freeing up evdev struct */
+struct FreeEvDev
+{
+ void operator()(struct libevdev* device) const
+ {
+ libevdev_free(device);
+ }
+};
+using EvdevPtr = std::unique_ptr<struct libevdev, FreeEvDev>;
+
+/** @class Evdev
+ * @brief Responsible for catching GPIO state changes conditions and taking
+ * actions
+ */
+class Evdev
+{
+
+ using Property = std::string;
+ using Value = sdbusplus::message::variant<bool, std::string>;
+ // Association between property and its value
+ using PropertyMap = std::map<Property, Value>;
+ using Interface = std::string;
+ // Association between interface and the D-Bus property
+ using InterfaceMap = std::map<Interface, PropertyMap>;
+ using Object = sdbusplus::message::object_path;
+ // Association between object and the interface
+ using ObjectMap = std::map<Object, InterfaceMap>;
+
+ public:
+ Evdev() = delete;
+ ~Evdev() = default;
+ Evdev(const Evdev&) = delete;
+ Evdev& operator=(const Evdev&) = delete;
+ Evdev(Evdev&&) = delete;
+ Evdev& operator=(Evdev&&) = delete;
+
+ /** @brief Constructs Evdev object.
+ *
+ * @param[in] path - Device path to read for GPIO pin state
+ * @param[in] key - GPIO key to monitor
+ * @param[in] event - sd_event handler
+ * @param[in] handler - IO callback handler. Defaults to one in this
+ * class
+ * @param[in] useEvDev - Whether to use EvDev to retrieve events
+ */
+ Evdev(const std::string& path,
+ const unsigned int key,
+ EventPtr& event,
+ sd_event_io_handler_t handler,
+ bool useEvDev = true) :
+ path(path),
+ key(key),
+ event(event),
+ callbackHandler(handler),
+ fd(openDevice())
+
+ {
+ if (useEvDev)
+ {
+ // If we are asked to use EvDev, do that initialization.
+ initEvDev();
+ }
+
+ // Register callback handler when FD has some data
+ registerCallback();
+ }
+
+ protected:
+ /** @brief Device path to read for GPIO pin state */
+ const std::string path;
+
+ /** @brief GPIO key to monitor */
+ const unsigned int key;
+
+ /** @brief Event structure */
+ EvdevPtr devicePtr;
+
+ /** @brief Monitor to sd_event */
+ EventPtr& event;
+
+ /** @brief Callback handler when the FD has some data */
+ sd_event_io_handler_t callbackHandler;
+
+ /** @brief event source */
+ EventSourcePtr eventSource;
+
+ /** @brief Opens the device and populates the descriptor */
+ int openDevice();
+
+ /** @brief attaches FD to events and sets up callback handler */
+ void registerCallback();
+
+ /** @brief File descriptor manager */
+ FileDescriptor fd;
+
+ /** @brief Initializes evdev handle with the fd */
+ void initEvDev();
+};
+
+} // namespace gpio
+} // namespace phosphor