Add support to set a GPIO either low or high

Change-Id: I07379f0cb63dc714cf538e4100f1a01077391f37
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/gpio.cpp b/gpio.cpp
index 32f4358..855718f 100644
--- a/gpio.cpp
+++ b/gpio.cpp
@@ -54,8 +54,26 @@
     return (data.values[0] == 0) ? Value::low : Value::high;
 }
 
+void GPIO::set(Value value)
+{
+    assert(direction == Direction::output);
 
-void GPIO::requestLine()
+    requestLine(value);
+
+    gpiohandle_data data{};
+    data.values[0] = static_cast<gpioValue_t>(value);
+
+    auto rc = ioctl(lineFD(), GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
+    if (rc == -1)
+    {
+        auto e = errno;
+        log<level::ERR>("Failed SET_LINE_VALUES ioctl",
+                        entry("ERRNO=%d", e));
+        elog<InternalFailure>();
+    }
+}
+
+void GPIO::requestLine(Value defaultValue)
 {
     //Only need to do this once
     if (lineFD)
@@ -86,6 +104,11 @@
     request.lineoffsets[0] = gpio;
     request.lines = 1;
 
+    if (direction == Direction::output)
+    {
+        request.default_values[0] = static_cast<gpioValue_t>(defaultValue);
+    }
+
     auto rc = ioctl(fd(), GPIO_GET_LINEHANDLE_IOCTL, &request);
     if (rc == -1)
     {
diff --git a/gpio.hpp b/gpio.hpp
index 2d3c6dd..04100da 100644
--- a/gpio.hpp
+++ b/gpio.hpp
@@ -75,12 +75,24 @@
          */
         Value read();
 
+        /**
+         * Sets the GPIO value to low or high
+         *
+         * Requests the GPIO line if it hasn't been done already.
+         *
+         * @param[in] Value - the value to set
+         */
+        void set(Value value);
+
     private:
 
         /**
          * Requests a GPIO line from the GPIO device
+         *
+         * @param[in] defaultValue - The default value, required for
+         *                           output GPIOs only.
          */
-        void requestLine();
+        void requestLine(Value defaultValue = Value::high);
 
         /**
          * The GPIO device name, like /dev/gpiochip0