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/chassis.hpp b/redfish-core/lib/chassis.hpp
index b718698..cd26849 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -288,7 +288,7 @@
}
asyncResp->res.jsonValue["@odata.type"] =
- "#Chassis.v1_10_0.Chassis";
+ "#Chassis.v1_14_0.Chassis";
asyncResp->res.jsonValue["@odata.id"] =
"/redfish/v1/Chassis/" + chassisId;
asyncResp->res.jsonValue["Name"] = "Chassis Collection";
@@ -318,6 +318,7 @@
interface) != interfaces2.end())
{
getIndicatorLedState(asyncResp);
+ getLocationIndicatorActive(asyncResp);
break;
}
}
@@ -381,7 +382,7 @@
// Couldn't find an object with that name. return an error
messages::resourceNotFound(
- asyncResp->res, "#Chassis.v1_10_0.Chassis", chassisId);
+ asyncResp->res, "#Chassis.v1_14_0.Chassis", chassisId);
},
"xyz.openbmc_project.ObjectMapper",
"/xyz/openbmc_project/object_mapper",
@@ -394,6 +395,7 @@
void doPatch(crow::Response& res, const crow::Request& req,
const std::vector<std::string>& params) override
{
+ std::optional<bool> locationIndicatorActive;
std::optional<std::string> indicatorLed;
auto asyncResp = std::make_shared<AsyncResp>(res);
@@ -402,12 +404,15 @@
return;
}
- if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed))
+ if (!json_util::readJson(req, res, "LocationIndicatorActive",
+ locationIndicatorActive, "IndicatorLED",
+ indicatorLed))
{
return;
}
- if (!indicatorLed)
+ // TODO (Gunnar): Remove IndicatorLED after enough time has passed
+ if (!locationIndicatorActive && !indicatorLed)
{
return; // delete this when we support more patch properties
}
@@ -419,7 +424,7 @@
const std::string& chassisId = params[0];
crow::connections::systemBus->async_method_call(
- [asyncResp, chassisId, indicatorLed](
+ [asyncResp, chassisId, locationIndicatorActive, indicatorLed](
const boost::system::error_code ec,
const crow::openbmc_mapper::GetSubTreeType& subtree) {
if (ec)
@@ -454,23 +459,35 @@
const std::vector<std::string>& interfaces3 =
connectionNames[0].second;
+ const std::array<const char*, 2> hasIndicatorLed = {
+ "xyz.openbmc_project.Inventory.Item.Panel",
+ "xyz.openbmc_project.Inventory.Item.Board."
+ "Motherboard"};
+ bool indicatorChassis = false;
+ for (const char* interface : hasIndicatorLed)
+ {
+ if (std::find(interfaces3.begin(), interfaces3.end(),
+ interface) != interfaces3.end())
+ {
+ indicatorChassis = true;
+ break;
+ }
+ }
+ if (locationIndicatorActive)
+ {
+ if (indicatorChassis)
+ {
+ setLocationIndicatorActive(
+ asyncResp, *locationIndicatorActive);
+ }
+ else
+ {
+ messages::propertyUnknown(
+ asyncResp->res, "LocationIndicatorActive");
+ }
+ }
if (indicatorLed)
{
- const std::array<const char*, 2> hasIndicatorLed = {
- "xyz.openbmc_project.Inventory.Item.Panel",
- "xyz.openbmc_project.Inventory.Item.Board."
- "Motherboard"};
- bool indicatorChassis = false;
- for (const char* interface : hasIndicatorLed)
- {
- if (std::find(interfaces3.begin(),
- interfaces3.end(),
- interface) != interfaces3.end())
- {
- indicatorChassis = true;
- break;
- }
- }
if (indicatorChassis)
{
setIndicatorLedState(asyncResp, *indicatorLed);
@@ -485,7 +502,7 @@
}
messages::resourceNotFound(
- asyncResp->res, "#Chassis.v1_10_0.Chassis", chassisId);
+ asyncResp->res, "#Chassis.v1_14_0.Chassis", chassisId);
},
"xyz.openbmc_project.ObjectMapper",
"/xyz/openbmc_project/object_mapper",
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
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index 5f9801b..ef178ed 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -1971,7 +1971,7 @@
void doGet(crow::Response& res, const crow::Request&,
const std::vector<std::string>&) override
{
- res.jsonValue["@odata.type"] = "#ComputerSystem.v1_12_0.ComputerSystem";
+ res.jsonValue["@odata.type"] = "#ComputerSystem.v1_13_0.ComputerSystem";
res.jsonValue["Name"] = "system";
res.jsonValue["Id"] = "system";
res.jsonValue["SystemType"] = "Physical";
@@ -2041,6 +2041,8 @@
{{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
});
+ getLocationIndicatorActive(asyncResp);
+ // TODO (Gunnar): Remove IndicatorLED after enough time has passed
getIndicatorLedState(asyncResp);
getComputerSystem(asyncResp, health);
getHostState(asyncResp);
@@ -2058,6 +2060,7 @@
void doPatch(crow::Response& res, const crow::Request& req,
const std::vector<std::string>&) override
{
+ std::optional<bool> locationIndicatorActive;
std::optional<std::string> indicatorLed;
std::optional<nlohmann::json> bootProps;
std::optional<nlohmann::json> wdtTimerProps;
@@ -2065,10 +2068,11 @@
std::optional<std::string> powerRestorePolicy;
auto asyncResp = std::make_shared<AsyncResp>(res);
- if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
- bootProps, "WatchdogTimer", wdtTimerProps,
- "PowerRestorePolicy", powerRestorePolicy,
- "AssetTag", assetTag))
+ if (!json_util::readJson(
+ req, res, "IndicatorLED", indicatorLed,
+ "LocationIndicatorActive", locationIndicatorActive, "Boot",
+ bootProps, "WatchdogTimer", wdtTimerProps, "PowerRestorePolicy",
+ powerRestorePolicy, "AssetTag", assetTag))
{
return;
}
@@ -2118,6 +2122,12 @@
}
}
+ if (locationIndicatorActive)
+ {
+ setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
+ }
+
+ // TODO (Gunnar): Remove IndicatorLED after enough time has passed
if (indicatorLed)
{
setIndicatorLedState(asyncResp, *indicatorLed);