apphandler: catch exceptions in getting bmc state

If the xyz.openbmc_project.State.BMC interface is not provided by
anything in the inventory, provide a mechanism for specifying a default
state with regards to the BMC state.  The dev_id.json file now can have
a boolean field, availability, that sets the default that the Get Device
Id command should use in the event the interface is unavailable or that
there is a dbus error.

The default value for the state of the BMC is true.  Currently, the
service in OpenBMC providing the real value via the dbus interface
simply checks that a systemd target is Active.  The systemd target
checked is the one that starts all the OpenBmc default services,
including ipmid.

Signed-off-by: Patrick Venture <venture@google.com>
Change-Id: Iba2c8308544337490905b0b48ba95785e0d775d4
diff --git a/apphandler.cpp b/apphandler.cpp
index 648a390..42e9e4b 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -191,6 +191,20 @@
                BMC::BMCState::Ready;
 }
 
+bool getCurrentBmcStateWithFallback(const bool fallbackAvailability)
+{
+    try
+    {
+        return getCurrentBmcState();
+    }
+    catch (...)
+    {
+        // Nothing provided the BMC interface, therefore return whatever was
+        // configured as the default.
+        return fallbackAvailability;
+    }
+}
+
 namespace acpi_state
 {
 using namespace sdbusplus::xyz::openbmc_project::Control::Power::server;
@@ -581,6 +595,7 @@
         uint32_t aux;
     } devId;
     static bool dev_id_initialized = false;
+    static bool defaultActivationSetting = true;
     const char* filename = "/usr/share/ipmi-providers/dev_id.json";
     constexpr auto ipmiDevIdStateShift = 7;
     constexpr auto ipmiDevIdFw1Mask = ~(1 << ipmiDevIdStateShift);
@@ -628,6 +643,9 @@
                 devId.prodId = data.value("prod_id", 0);
                 devId.aux = data.value("aux", 0);
 
+                // Set the availablitity of the BMC.
+                defaultActivationSetting = data.value("availability", true);
+
                 // Don't read the file every time if successful
                 dev_id_initialized = true;
             }
@@ -646,7 +664,7 @@
 
     // Set availability to the actual current BMC state
     devId.fw[0] &= ipmiDevIdFw1Mask;
-    if (!getCurrentBmcState())
+    if (!getCurrentBmcStateWithFallback(defaultActivationSetting))
     {
         devId.fw[0] |= (1 << ipmiDevIdStateShift);
     }