Fix parsing gpio config format issue

A recent change was submitted regarding addition of
new gpio config format to support group gpio config and
respective config parser change. This change caused
app crash for platforms using previous config format.

This is resolved with this fix by adding parser support for
both config formats.

Signed-off-by: Naveen Moses <naveen.mosess@hcl.com>
Change-Id: I891f22515cacc001e4b4690003849a05148c86c2
diff --git a/inc/button_factory.hpp b/inc/button_factory.hpp
index 81c8e47..1c513ef 100644
--- a/inc/button_factory.hpp
+++ b/inc/button_factory.hpp
@@ -54,8 +54,15 @@
     {
 
         // find matching name in the registry and call factory method.
-
-        return buttonIfaceRegistry.at(name)(bus, event, buttonCfg);
+        auto objectIter = buttonIfaceRegistry.find(name);
+        if (objectIter != buttonIfaceRegistry.end())
+        {
+            return objectIter->second(bus, event, buttonCfg);
+        }
+        else
+        {
+            return nullptr;
+        }
     }
 
   private:
diff --git a/src/main.cpp b/src/main.cpp
index a99c603..cfa224e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -55,23 +55,44 @@
     // load gpio config from gpio defs json file and create button interface
     // objects based on the button form factor type
 
-    for (auto groupGpioConfig : gpioDefs)
+    for (const auto& gpioConfig : gpioDefs)
     {
-        std::string formFactorName = groupGpioConfig["name"];
+        std::string formFactorName = gpioConfig["name"];
         buttonConfig buttonCfg;
-        auto groupGpio = groupGpioConfig["gpio_config"];
+        buttonCfg.formFactorName = formFactorName;
 
-        for (auto gpioConfig : groupGpio)
+        /* The folloing code checks if the gpio config read
+        from json file is single gpio config or group gpio config,
+        based on that further data is processed. */
+        if (gpioConfig.contains("group_gpio_config"))
+        {
+            const auto& groupGpio = gpioConfig["group_gpio_config"];
+
+            for (const auto& config : groupGpio)
+            {
+                gpioInfo gpioCfg;
+                gpioCfg.number = getGpioNum(config["pin"]);
+                gpioCfg.direction = config["direction"];
+                buttonCfg.gpios.push_back(gpioCfg);
+            }
+        }
+        else
         {
             gpioInfo gpioCfg;
             gpioCfg.number = getGpioNum(gpioConfig["pin"]);
             gpioCfg.direction = gpioConfig["direction"];
-            buttonCfg.formFactorName = formFactorName;
             buttonCfg.gpios.push_back(gpioCfg);
         }
-
-        buttonInterfaces.emplace_back(ButtonFactory::instance().createInstance(
-            formFactorName, bus, eventP, buttonCfg));
+        auto tempButtonIf = ButtonFactory::instance().createInstance(
+            formFactorName, bus, eventP, buttonCfg);
+        /* There are additional gpio configs present in some platforms
+         that are not supported in phosphor-buttons.
+        But they may be used by other applications. so skipping such configs
+        if present in gpio_defs.json file*/
+        if (tempButtonIf)
+        {
+            buttonInterfaces.emplace_back(std::move(tempButtonIf));
+        }
     }
 
     try