Call defined target when GPIO line is asserted
Change-Id: Ia5445a8d6585acfec69783ba158c8d866d526e97
Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index 89fa2e4..777dffc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,5 +7,9 @@
monitor.cpp \
mainapp.cpp
-phosphor_gpio_monitor_LDFLAGS = $(SYSTEMD_LIBS) $(PHOSPHOR_LOGGING_LIBS)
-phosphor_gpio_monitor_CFLAGS = $(SYSTEMD_CFLAGS) $(PHOSPHOR_LOGGING_CFLAGS)
+phosphor_gpio_monitor_LDFLAGS = $(SYSTEMD_LIBS) \
+ $(SDBUSPLUS_LIBS) \
+ $(PHOSPHOR_LOGGING_LIBS)
+phosphor_gpio_monitor_CFLAGS = $(SYSTEMD_CFLAGS) \
+ $(SDBUSPLUS_CFLAGS) \
+ $(PHOSPHOR_LOGGING_CFLAGS)
diff --git a/configure.ac b/configure.ac
index 709ed05..c80d778 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,6 +21,8 @@
# Checks for modules
PKG_CHECK_MODULES([SYSTEMD], [libsystemd >= 221], ,[AC_MSG_ERROR([Could not find systemd...systemd developement package required])])
PKG_CHECK_MODULES([PHOSPHOR_LOGGING], [phosphor-logging],, [AC_MSG_ERROR([Could not find phosphor-logging...openbmc/phosphor-logging package required])])
+PKG_CHECK_MODULES([SDBUSPLUS], [sdbusplus],, [AC_MSG_ERROR([Could not find sdbusplus...openbmc/sdbusplus package required])])
+PKG_CHECK_MODULES([PHOSPHOR_DBUS_INTERFACES], [phosphor-dbus-interfaces],, [AC_MSG_ERROR([Could not find phosphor-dbus-interfaces...openbmc/phosphor-dbus-interfaces package required])])
# Create configured output
AC_CONFIG_FILES([Makefile])
diff --git a/mainapp.cpp b/mainapp.cpp
index 6290366..1dd7e80 100644
--- a/mainapp.cpp
+++ b/mainapp.cpp
@@ -75,8 +75,20 @@
// Create a monitor object and let it do all the rest
phosphor::gpio::Monitor monitor(path, std::stoi(key),
std::stoi(polarity), target, eventP);
- // Wait for events
- sd_event_loop(eventP.get());
+
+ // Wait for client requests until this application has processed
+ // at least one expected GPIO state change
+ while(!monitor.completed())
+ {
+ // -1 denotes wait for ever
+ r = sd_event_run(eventP.get(), (uint64_t)-1);
+ if (r < 0)
+ {
+ log<level::ERR>("Failure in processing request",
+ entry("ERROR=%s", strerror(-r)));
+ break;
+ }
+ }
return 0;
}
diff --git a/monitor.cpp b/monitor.cpp
index 5428c09..99eed03 100644
--- a/monitor.cpp
+++ b/monitor.cpp
@@ -17,11 +17,18 @@
#include <fcntl.h>
#include <phosphor-logging/log.hpp>
#include "monitor.hpp"
+#include "config.h"
+
namespace phosphor
{
namespace gpio
{
+// systemd service to kick start a target.
+constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
+constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1";
+constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
+
using namespace phosphor::logging;
// Populate the file descriptor for passed in device
@@ -59,8 +66,32 @@
int Monitor::processEvents(sd_event_source* es, int fd,
uint32_t revents, void* userData)
{
- // TODO. This calls into starting configured target
- log<level::INFO>("Callback handler called");
+ log<level::INFO>("GPIO line altered");
+ auto monitor = static_cast<Monitor*>(userData);
+ // TODO : Need a way to check if the GPIO state change is what we wanted
+ return monitor->analyzeEvent();
+}
+
+// Analyzes the GPIO event
+int Monitor::analyzeEvent()
+{
+ if(!target.empty())
+ {
+ auto bus = sdbusplus::bus::new_default();
+ auto method = bus.new_method_call(SYSTEMD_SERVICE,
+ SYSTEMD_ROOT,
+ SYSTEMD_INTERFACE,
+ "StartUnit");
+ method.append(target);
+ method.append("replace");
+
+ // If there is any error, an exception would be thrown from here.
+ bus.call_noreply(method);
+ }
+
+ // This marks the completion of handling the checkstop and app can exit
+ complete = true;
+
return 0;
}
diff --git a/monitor.hpp b/monitor.hpp
index 1027714..34803c1 100644
--- a/monitor.hpp
+++ b/monitor.hpp
@@ -4,6 +4,7 @@
#include <string>
#include <linux/input.h>
#include <systemd/sd-event.h>
+#include <sdbusplus/bus.hpp>
#include "file.hpp"
namespace phosphor
{
@@ -86,6 +87,12 @@
static int processEvents(sd_event_source* es, int fd,
uint32_t revents, void* userData);
+ /** @brief Returns the completion state of this handler */
+ inline auto completed() const
+ {
+ return complete;
+ }
+
private:
/** @brief Absolute path of GPIO input device */
const std::string& path;
@@ -111,11 +118,20 @@
/** @brief File descriptor manager */
FileDescriptor fd;
+ /** @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
+ *
+ * @return - For now, returns zero
+ */
+ int analyzeEvent();
};
} // namespace gpio