utility: Implement gpioSetValue function

Change-Id: I0336bfa4b9029c9dfc0d7038f881e4ac97bd71d6
Signed-off-by: Anthony Wilson <wilsonan@us.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index bf17ba0..e87486d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,7 +7,9 @@
 	chassiskill.cpp
 
 chassiskill_CXXFLAGS = \
-	$(PHOSPHOR_LOGGING_CFLAGS)
+	$(PHOSPHOR_LOGGING_CFLAGS) \
+	$(GPIOPLUS_FLAGS)
 
 chassiskill_LDFLAGS = \
-	$(PHOSPHOR_LOGGING_LIBS)
+	$(PHOSPHOR_LOGGING_LIBS) \
+	$(GPIOPLUS_LIBS)
diff --git a/configure.ac b/configure.ac
index d11bf6c..0ae6166 100644
--- a/configure.ac
+++ b/configure.ac
@@ -13,6 +13,8 @@
 # Check for libraries
 PKG_CHECK_MODULES([PHOSPHOR_LOGGING], [phosphor-logging],,\
     AC_MSG_ERROR(["Requires phosphor-logging package."]))
+PKG_CHECK_MODULES([GPIOPLUS], [gpioplus],,\
+    [AC_MSG_ERROR([Could not find gpioplus...openbmc/gpioplus package required])])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AX_CXX_COMPILE_STDCXX_17([noext])
diff --git a/utility.hpp b/utility.hpp
index 4990a1c..7e2eaff 100644
--- a/utility.hpp
+++ b/utility.hpp
@@ -1,5 +1,10 @@
 #pragma once
 
+#include <gpioplus/chip.hpp>
+#include <gpioplus/handle.hpp>
+#include <gpioplus/utility/aspeed.hpp>
+#include <phosphor-logging/log.hpp>
+#include <exception>
 #include <string>
 
 namespace utility
@@ -15,7 +20,40 @@
  */
 bool gpioSetValue(const std::string& gpioName, bool activeLow, bool asserted)
 {
-    /* TODO */
+    uint32_t gpioOffset;
+    try
+    {
+        gpioOffset = gpioplus::utility::aspeed::nameToOffset(gpioName);
+    }
+    catch(const std::logic_error& e)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+                            "Error in gpioplus - nameToOffset",
+                            phosphor::logging::entry("ERROR=%s", e.what()));
+        return false;
+    }
+
+    try
+    {
+        //TODO: openbmc/phosphor-power-control#1 - Handle cases where gpiochip
+        //      could be non-zero.
+        gpioplus::Chip chip(0);
+        gpioplus::HandleFlags flags(chip.getLineInfo(gpioOffset).flags);
+        flags.output = true;
+        gpioplus::Handle handle(chip, {{gpioOffset, 0}}, flags,
+                                "chassiskill");
+
+        bool value = (asserted ^ activeLow);
+        handle.setValues({value});
+    }
+    catch (const std::exception& e)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+                            "Error in gpioplus",
+                            phosphor::logging::entry("ERROR=%s", e.what()));
+        return false;
+    }
+
     return true;
 }