summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Mills <gmills@us.ibm.com>2017-07-27 15:22:42 -0500
committerGunnar Mills <gmills@us.ibm.com>2017-07-28 12:34:51 -0500
commit9925857a9ef0e47f105a21186a809a3b094461b3 (patch)
tree481de329c30d097c96e6aab93af86fff0f1d12e6
parent835dfb8877fd2e78281e22b8b08dc29e0e9ef5a5 (diff)
downloadphosphor-gpio-monitor-9925857a9ef0e47f105a21186a809a3b094461b3.tar.gz
phosphor-gpio-monitor-9925857a9ef0e47f105a21186a809a3b094461b3.zip
Refactor GPIO Monitor class
Refactor the GPIO Monitor class to use a common class, Evdev, to inherit from. Evdev does the basic libevdev handling. Change-Id: I427aa9720b0bbbea0284c0babcc03ece92e55f5e Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
-rw-r--r--Makefile.am3
-rw-r--r--evdev.hpp3
-rw-r--r--monitor.cpp55
-rw-r--r--monitor.hpp86
-rw-r--r--test/Makefile.am7
-rw-r--r--test/utest.cpp1
6 files changed, 16 insertions, 139 deletions
diff --git a/Makefile.am b/Makefile.am
index bbe24fc..fbe96e2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,15 +5,18 @@ noinst_HEADERS = monitor.hpp
phosphor_gpio_monitor_SOURCES = \
argument.cpp \
monitor.cpp \
+ evdev.cpp \
mainapp.cpp
phosphor_gpio_monitor_LDFLAGS = $(SYSTEMD_LIBS) \
$(SDBUSPLUS_LIBS) \
$(PHOSPHOR_LOGGING_LIBS) \
+ $(PHOSPHOR_DBUS_INTERFACES_LIBS) \
$(LIBEVDEV_LIBS)
phosphor_gpio_monitor_CXXFLAGS = $(SYSTEMD_CFLAGS) \
$(SDBUSPLUS_CFLAGS) \
+ $(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \
$(PHOSPHOR_LOGGING_CFLAGS) \
$(LIBEVDEV_CFLAGS)
diff --git a/evdev.hpp b/evdev.hpp
index b3189f1..353c593 100644
--- a/evdev.hpp
+++ b/evdev.hpp
@@ -70,8 +70,7 @@ class Evdev
* @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] handler - IO callback handler.
* @param[in] useEvDev - Whether to use EvDev to retrieve events
*/
Evdev(const std::string& path,
diff --git a/monitor.cpp b/monitor.cpp
index 632506b..5bc4742 100644
--- a/monitor.cpp
+++ b/monitor.cpp
@@ -31,59 +31,6 @@ constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
using namespace phosphor::logging;
-// Populate the file descriptor for passed in device
-int Monitor::openDevice()
-{
- using namespace phosphor::logging;
-
- int fd = open(path.c_str(), O_RDONLY | O_NONBLOCK);
- if (fd < 0)
- {
- log<level::ERR>("Failed to open device",
- entry("PATH=%s", path.c_str()));
- throw std::runtime_error("Failed to open device");
- }
- return fd;
-}
-
-// Attaches the FD to event loop and registers the callback handler
-void Monitor::registerCallback()
-{
- decltype(eventSource.get()) sourcePtr = nullptr;
- auto r = sd_event_add_io(event.get(), &sourcePtr, (fd)(),
- EPOLLIN, callbackHandler, this);
- eventSource.reset(sourcePtr);
-
- if (r < 0)
- {
- log<level::ERR>("Failed to register callback handler",
- entry("ERROR=%s", strerror(-r)));
- throw std::runtime_error("Failed to register callback handler");
- }
-}
-
-// Initializes the event device with the fd
-void Monitor::initEvDev()
-{
- if (device)
- {
- // Init can be done only once per device
- return;
- }
-
- struct libevdev* evdev = nullptr;
- auto rc = libevdev_new_from_fd((fd)(), &evdev);
- if (rc < 0)
- {
- log<level::ERR>("Failed to initialize evdev");
- throw std::runtime_error("Failed to initialize evdev");
- }
-
- // Packing in the unique_ptr
- device.reset(evdev);
- evdev = nullptr;
-}
-
// Callback handler when there is an activity on the FD
int Monitor::processEvents(sd_event_source* es, int fd,
uint32_t revents, void* userData)
@@ -107,7 +54,7 @@ void Monitor::analyzeEvent()
while (rc >= 0)
{
// Wait until no more events are available on the device.
- rc = libevdev_next_event(device.get(),
+ rc = libevdev_next_event(devicePtr.get(),
LIBEVDEV_READ_FLAG_NORMAL, &ev);
if (rc < 0)
{
diff --git a/monitor.hpp b/monitor.hpp
index bffb1d4..1dcef79 100644
--- a/monitor.hpp
+++ b/monitor.hpp
@@ -3,50 +3,20 @@
#include <unistd.h>
#include <string>
#include <linux/input.h>
-#include <libevdev/libevdev.h>
#include <systemd/sd-event.h>
#include <sdbusplus/bus.hpp>
-#include "file.hpp"
+#include "evdev.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 EvdevDeleter
-{
- void operator()(struct libevdev* device) const
- {
- libevdev_free(device);
- }
-};
-using EvdevPtr = std::unique_ptr<struct libevdev, EvdevDeleter>;
-
/** @class Monitor
* @brief Responsible for catching GPIO state change
- * condition and taking actions
+ * condition and starting systemd targets.
*/
-class Monitor
+class Monitor : public Evdev
{
public:
Monitor() = delete;
@@ -75,23 +45,9 @@ class Monitor
EventPtr& event,
sd_event_io_handler_t handler = Monitor::processEvents,
bool useEvDev = true)
- : path(path),
- key(key),
+ : Evdev(path, key, event, handler, useEvDev),
polarity(polarity),
- target(target),
- event(event),
- callbackHandler(handler),
- fd(openDevice())
- {
- if (useEvDev)
- {
- // If we are asked to use EvDev, do that initialization.
- initEvDev();
- }
-
- // And register callback handler when FD has some data
- registerCallback();
- }
+ target(target) {};
/** @brief Callback handler when the FD has some activity on it
*
@@ -113,47 +69,17 @@ class Monitor
}
private:
- /** @brief Absolute path of GPIO input device */
- const std::string& path;
-
- /** @brief GPIO key code that is of interest */
- decltype(input_event::code) key;
-
/** @brief GPIO key value that is of interest */
decltype(input_event::value) polarity;
/** @brief Systemd unit to be started when the condition is met */
const std::string& target;
- /** @brief Monitor to sd_event */
- EventPtr& event;
-
- /** @brief event source */
- EventSourcePtr eventSource;
-
- /** @brief Callback handler when the FD has some data */
- sd_event_io_handler_t callbackHandler;
-
- /** @brief File descriptor manager */
- FileDescriptor fd;
-
- /** event structure */
- EvdevPtr device;
-
/** @brief Completion indicator */
bool complete = false;
- /** @brief Opens the device and populates the descriptor */
- int openDevice();
-
- /** @brief attaches FD to events and sets up callback handler */
- void registerCallback();
-
/** @brief Analyzes the GPIO event and starts configured target */
void analyzeEvent();
-
- /** @brief Initializes evdev handle with the fd */
- void initEvDev();
};
} // namespace gpio
diff --git a/test/Makefile.am b/test/Makefile.am
index 5bd15e7..ff34005 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -7,7 +7,8 @@ TESTS = $(check_PROGRAMS)
# # Build/add utest to test suite
check_PROGRAMS = utest
utest_CPPFLAGS = -Igtest $(GTEST_CPPFLAGS) $(AM_CPPFLAGS) $(PHOSPHOR_LOGGING_CFLAGS) $(LIBEVDEV_CFLAGS)
-utest_CXXFLAGS = $(PTHREAD_CFLAGS)
-utest_LDFLAGS = -lgtest_main -lgtest $(PTHREAD_LIBS) $(OESDK_TESTCASE_FLAGS) $(SYSTEMD_LIBS) $(PHOSPHOR_LOGGING_LIBS) $(LIBEVDEV_LIBS)
+utest_CXXFLAGS = $(PTHREAD_CFLAGS) $(LIBEVDEV_CFLAGS) $(PHOSPHOR_DBUS_INTERFACES_CFLAGS)
+utest_LDFLAGS = -lgtest_main -lgtest $(PTHREAD_LIBS) $(OESDK_TESTCASE_FLAGS) $(SYSTEMD_LIBS) $(PHOSPHOR_LOGGING_LIBS) \
+$(LIBEVDEV_LIBS) $(PHOSPHOR_DBUS_INTERFACES_LIBS)
utest_SOURCES = utest.cpp
-utest_LDADD = $(top_builddir)/monitor.o
+utest_LDADD = $(top_builddir)/monitor.o $(top_srcdir)/evdev.cpp
diff --git a/test/utest.cpp b/test/utest.cpp
index 3728244..c6b6f18 100644
--- a/test/utest.cpp
+++ b/test/utest.cpp
@@ -5,6 +5,7 @@
#include <linux/input.h>
#include <gtest/gtest.h>
#include "monitor.hpp"
+#include "evdev.hpp"
using namespace phosphor::gpio;
OpenPOWER on IntegriCloud