Only create buttons when their GPIOs are defined

Look in /etc/default/obmc/gpio/gpio_defs.json to see
if the GPIO for a button is defined, and only create
the button object if it is.

This is how a system implementer can specify which
button objects are needed for their particular system.

Change-Id: I359f87875b6bb5741fdf4718b30b0f5b4552a528
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/src/gpio.cpp b/src/gpio.cpp
index b78d2bc..27fc74d 100644
--- a/src/gpio.cpp
+++ b/src/gpio.cpp
@@ -21,13 +21,19 @@
 
 #include <experimental/filesystem>
 #include <fstream>
+#include <nlohmann/json.hpp>
 #include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
 #include <xyz/openbmc_project/Common/error.hpp>
 
 const static constexpr char* SYSMGR_SERVICE = "org.openbmc.managers.System";
 const static constexpr char* SYSMGR_OBJ_PATH = "/org/openbmc/managers/System";
 const static constexpr char* SYSMGR_INTERFACE = "org.openbmc.managers.System";
 
+static constexpr auto gpioDefs = "/etc/default/obmc/gpio/gpio_defs.json";
+
+using namespace phosphor::logging;
+
 void closeGpio(int fd)
 {
     if (fd > 0)
@@ -36,6 +42,32 @@
     }
 }
 
+bool gpioDefined(const std::string& gpioName)
+{
+    try
+    {
+        std::ifstream gpios{gpioDefs};
+        auto json = nlohmann::json::parse(gpios, nullptr, true);
+        auto defs = json["gpio_definitions"];
+
+        auto gpio =
+            std::find_if(defs.begin(), defs.end(), [&gpioName](const auto g) {
+                return gpioName == g["name"];
+            });
+
+        if (gpio != defs.end())
+        {
+            return true;
+        }
+    }
+    catch (std::exception& e)
+    {
+        log<level::ERR>("Error parsing GPIO JSON", entry("ERROR=%s", e.what()),
+                        entry("GPIO_NAME=%s", gpioName.c_str()));
+    }
+    return false;
+}
+
 int configGpio(const char* gpioName, int* fd, sdbusplus::bus::bus& bus)
 {
     auto method = bus.new_method_call(SYSMGR_SERVICE, SYSMGR_OBJ_PATH,
@@ -47,8 +79,7 @@
 
     if (result.is_method_error())
     {
-        phosphor::logging::log<phosphor::logging::level::ERR>(
-            "bus call error!");
+        log<level::ERR>("bus call error!");
         return -1;
     }
 
@@ -71,9 +102,7 @@
 
     if (std::experimental::filesystem::exists(fullPath))
     {
-        phosphor::logging::log<phosphor::logging::level::INFO>(
-            "GPIO exported",
-            phosphor::logging::entry("PATH=%s", devPath.c_str()));
+        log<level::INFO>("GPIO exported", entry("PATH=%s", devPath.c_str()));
     }
     else
     {
@@ -89,10 +118,9 @@
 
         catch (const std::exception& e)
         {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "Error in writing!",
-                phosphor::logging::entry("PATH=%s", devPath.c_str()),
-                phosphor::logging::entry("NUM=%d", gpioNum));
+            log<level::ERR>("Error in writing!",
+                            entry("PATH=%s", devPath.c_str()),
+                            entry("NUM=%d", gpioNum));
             return -1;
         }
     }
@@ -113,9 +141,8 @@
 
         catch (const std::exception& e)
         {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "Error in reading!",
-                phosphor::logging::entry("PATH=%s", devPath.c_str()));
+            log<level::ERR>("Error in reading!",
+                            entry("PATH=%s", devPath.c_str()));
             return -1;
         }
 
@@ -133,8 +160,7 @@
 
         catch (const std::exception& e)
         {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "Error in writing!");
+            log<level::ERR>("Error in writing!");
             return -1;
         }
     }
@@ -152,8 +178,7 @@
 
         catch (const std::exception& e)
         {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "Error in writing!");
+            log<level::ERR>("Error in writing!");
             return -1;
         }
     }
@@ -174,8 +199,7 @@
 
         catch (const std::exception& e)
         {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "Error in writing!");
+            log<level::ERR>("Error in writing!");
             return -1;
         }
     }
@@ -187,7 +211,7 @@
 
     if (*fd < 0)
     {
-        phosphor::logging::log<phosphor::logging::level::ERR>("open error!");
+        log<level::ERR>("open error!");
         return -1;
     }