Add new Location Indicator property

In ComputerSystem 1.13 and Chassis 1.14 as well as in many other
schemas IndicatorLED is replaced with LocationIndicatorActive.

LocationIndicatorActive is a bool while IndicatorLED had 3 states:
Lit, Blink, and off. Map Lit and Blink both to
LocationIndicatorActive true.

led.hpp was calling both enclosure_identify_blink and
enclosure_identify, continue this.

Keep the deprecated IndicatorLED and implement the new
LocationIndicatorActive property. Have both properties for
the time being. This new property makes the same calls.

This does add a new Redfish warning for the deprecated
IndicatorLED. Other warning are there today.

Tested: Validator passes
Could use help testing on Chassis. Our systems don't have a
IndicatorLED on chassis. See chassis bumped.
curl -k https://$bmc/redfish/v1/Systems/system
{
  "@odata.id": "/redfish/v1/Systems/system",
  "@odata.type": "#ComputerSystem.v1_13_0.ComputerSystem",
...
  "IndicatorLED": "Off",
  "LastResetTime": "2020-10-29T09:01:03+00:00",
  "Links": {
    "Chassis": [
      {
        "@odata.id": "/redfish/v1/Chassis/chassis"
      }
    ],
    "ManagedBy": [
      {
        "@odata.id": "/redfish/v1/Managers/bmc"
      }
    ]
  },
  "LocationIndicatorActive": false,

curl -X PATCH -d '{ "LocationIndicatorActive":true}' -k \
https://$bmc/redfish/v1/Systems/system

curl -X PATCH -d '{ "IndicatorLED":"Off"}' -k \
https://$bmc/redfish/v1/Systems/system

Change-Id: I105bed5794912c575aa9a00e0442461bfdee6180
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
diff --git a/redfish-core/lib/led.hpp b/redfish-core/lib/led.hpp
index 0cb522f..0fd1c9b 100644
--- a/redfish-core/lib/led.hpp
+++ b/redfish-core/lib/led.hpp
@@ -30,6 +30,7 @@
  *
  * @return None.
  */
+// TODO (Gunnar): Remove IndicatorLED after enough time has passed
 inline void getIndicatorLedState(const std::shared_ptr<AsyncResp>& aResp)
 {
     BMCWEB_LOG_DEBUG << "Get led groups";
@@ -98,6 +99,7 @@
  *
  * @return None.
  */
+// TODO (Gunnar): Remove IndicatorLED after enough time has passed
 inline void setIndicatorLedState(const std::shared_ptr<AsyncResp>& aResp,
                                  const std::string& ledState)
 {
@@ -152,4 +154,116 @@
         "xyz.openbmc_project.Led.Group", "Asserted",
         std::variant<bool>(ledBlinkng));
 }
+
+/**
+ * @brief Retrieves identify led group properties over dbus
+ *
+ * @param[in] aResp     Shared pointer for generating response message.
+ *
+ * @return None.
+ */
+inline void getLocationIndicatorActive(const std::shared_ptr<AsyncResp>& aResp)
+{
+    BMCWEB_LOG_DEBUG << "Get LocationIndicatorActive";
+    crow::connections::systemBus->async_method_call(
+        [aResp](const boost::system::error_code ec,
+                const std::variant<bool> asserted) {
+            // Some systems may not have enclosure_identify_blink object so
+            // proceed to get enclosure_identify state.
+            if (!ec)
+            {
+                const bool* blinking = std::get_if<bool>(&asserted);
+                if (!blinking)
+                {
+                    BMCWEB_LOG_DEBUG << "Get identity blinking LED failed";
+                    messages::internalError(aResp->res);
+                    return;
+                }
+                // Blinking ON, no need to check enclosure_identify assert.
+                if (*blinking)
+                {
+                    aResp->res.jsonValue["LocationIndicatorActive"] = true;
+                    return;
+                }
+            }
+            crow::connections::systemBus->async_method_call(
+                [aResp](const boost::system::error_code ec2,
+                        const std::variant<bool> asserted2) {
+                    if (!ec2)
+                    {
+                        const bool* ledOn = std::get_if<bool>(&asserted2);
+                        if (!ledOn)
+                        {
+                            BMCWEB_LOG_DEBUG
+                                << "Get enclosure identity led failed";
+                            messages::internalError(aResp->res);
+                            return;
+                        }
+
+                        if (*ledOn)
+                        {
+                            aResp->res.jsonValue["LocationIndicatorActive"] =
+                                true;
+                        }
+                        else
+                        {
+                            aResp->res.jsonValue["LocationIndicatorActive"] =
+                                false;
+                        }
+                    }
+                    return;
+                },
+                "xyz.openbmc_project.LED.GroupManager",
+                "/xyz/openbmc_project/led/groups/enclosure_identify",
+                "org.freedesktop.DBus.Properties", "Get",
+                "xyz.openbmc_project.Led.Group", "Asserted");
+        },
+        "xyz.openbmc_project.LED.GroupManager",
+        "/xyz/openbmc_project/led/groups/enclosure_identify_blink",
+        "org.freedesktop.DBus.Properties", "Get",
+        "xyz.openbmc_project.Led.Group", "Asserted");
+}
+
+/**
+ * @brief Sets identify led group properties
+ *
+ * @param[in] aResp     Shared pointer for generating response message.
+ * @param[in] ledState  LED state passed from request
+ *
+ * @return None.
+ */
+inline void setLocationIndicatorActive(const std::shared_ptr<AsyncResp>& aResp,
+                                       const bool ledState)
+{
+    BMCWEB_LOG_DEBUG << "Set LocationIndicatorActive";
+
+    crow::connections::systemBus->async_method_call(
+        [aResp, ledState](const boost::system::error_code ec) mutable {
+            if (ec)
+            {
+                // Some systems may not have enclosure_identify_blink object so
+                // lets set enclosure_identify state also if
+                // enclosure_identify_blink failed
+                crow::connections::systemBus->async_method_call(
+                    [aResp](const boost::system::error_code ec2) {
+                        if (ec2)
+                        {
+                            BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
+                            messages::internalError(aResp->res);
+                            return;
+                        }
+                    },
+                    "xyz.openbmc_project.LED.GroupManager",
+                    "/xyz/openbmc_project/led/groups/enclosure_identify",
+                    "org.freedesktop.DBus.Properties", "Set",
+                    "xyz.openbmc_project.Led.Group", "Asserted",
+                    std::variant<bool>(ledState));
+            }
+        },
+        "xyz.openbmc_project.LED.GroupManager",
+        "/xyz/openbmc_project/led/groups/enclosure_identify_blink",
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Led.Group", "Asserted",
+        std::variant<bool>(ledState));
+}
 } // namespace redfish