lamp test: Add vritual lamp test function
- This feature adds the functionality that enables force updating
certain physical LEDs and skip updating certain physical LEDs as
part of lamp test.
- This is a generic feature that gives more control over handing
physical LEDs.
Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I6f06ed103b1ceefdaa774b7a74a4a392609000ed
diff --git a/lamptest.cpp b/lamptest.cpp
index aaf73de..8220f96 100644
--- a/lamptest.cpp
+++ b/lamptest.cpp
@@ -1,5 +1,3 @@
-#include "config.h"
-
#include "lamptest.hpp"
#include <phosphor-logging/log.hpp>
@@ -10,6 +8,7 @@
{
using namespace phosphor::logging;
+using Json = nlohmann::json;
bool LampTest::processLEDUpdates(const Manager::group& ledsAssert,
const Manager::group& ledsDeAssert)
@@ -19,6 +18,34 @@
// stopped.
if (isLampTestRunning)
{
+ // Physical LEDs will be updated during lamp test
+ for (const auto& it : ledsDeAssert)
+ {
+ std::string path = std::string(PHY_LED_PATH) + it.name;
+ auto iter = std::find_if(
+ forceUpdateLEDs.begin(), forceUpdateLEDs.end(),
+ [&path](const auto& name) { return name == path; });
+
+ if (iter != forceUpdateLEDs.end())
+ {
+ manager.drivePhysicalLED(path, Layout::Action::Off, it.dutyOn,
+ it.period);
+ }
+ }
+
+ for (const auto& it : ledsAssert)
+ {
+ std::string path = std::string(PHY_LED_PATH) + it.name;
+ auto iter = std::find_if(
+ forceUpdateLEDs.begin(), forceUpdateLEDs.end(),
+ [&path](const auto& name) { return name == path; });
+
+ if (iter != forceUpdateLEDs.end())
+ {
+ manager.drivePhysicalLED(path, it.action, it.dutyOn, it.period);
+ }
+ }
+
updatedLEDsDuringLampTest.emplace(
std::make_pair(ledsAssert, ledsDeAssert));
return true;
@@ -41,6 +68,16 @@
// Set all the Physical action to Off
for (const auto& path : physicalLEDPaths)
{
+ auto iter =
+ std::find_if(skipUpdateLEDs.begin(), skipUpdateLEDs.end(),
+ [&path](const auto& skip) { return skip == path; });
+
+ if (iter != skipUpdateLEDs.end())
+ {
+ // Skip update physical path
+ continue;
+ }
+
manager.drivePhysicalLED(path, Layout::Action::Off, 0, 0);
}
@@ -70,6 +107,16 @@
for (const auto& path : physicalLEDPaths)
{
+ auto iter = std::find_if(
+ skipUpdateLEDs.begin(), skipUpdateLEDs.end(),
+ [&path](const auto& skipLed) { return skipLed == path; });
+
+ if (iter != skipUpdateLEDs.end())
+ {
+ // Physical LEDs will be skipped
+ continue;
+ }
+
// Reverse intercept path, Get the name of each member of physical led
// e.g: path = /xyz/openbmc_project/led/physical/front_fan
// name = front_fan
@@ -137,6 +184,16 @@
// Set all the Physical action to On for lamp test
for (const auto& path : physicalLEDPaths)
{
+ auto iter =
+ std::find_if(skipUpdateLEDs.begin(), skipUpdateLEDs.end(),
+ [&path](const auto& skip) { return skip == path; });
+
+ if (iter != skipUpdateLEDs.end())
+ {
+ // Skip update physical path
+ continue;
+ }
+
manager.drivePhysicalLED(path, Layout::Action::On, 0, 0);
}
}
@@ -173,8 +230,8 @@
void LampTest::restorePhysicalLedStates()
{
// restore physical LEDs states before lamp test
- Manager::group savedLEDStatesDeAssert{};
- manager.driveLEDs(physicalLEDStatesPriorToLampTest, savedLEDStatesDeAssert);
+ Manager::group ledsDeAssert{};
+ manager.driveLEDs(physicalLEDStatesPriorToLampTest, ledsDeAssert);
physicalLEDStatesPriorToLampTest.clear();
// restore physical LEDs states during lamp test
@@ -203,5 +260,42 @@
}
}
+void LampTest::getPhysicalLEDNamesFromJson(const fs::path& path)
+{
+ if (!fs::exists(path) || fs::is_empty(path))
+ {
+ log<level::INFO>("The file does not exist or is empty",
+ entry("FILE_PATH=%s", path.c_str()));
+ return;
+ }
+
+ try
+ {
+ std::ifstream jsonFile(path);
+ auto json = Json::parse(jsonFile);
+
+ // define the default JSON as empty
+ const std::vector<std::string> empty{};
+ auto forceLEDs = json.value("forceLEDs", empty);
+ for (auto& member : forceLEDs)
+ {
+ forceUpdateLEDs.push_back(PHY_LED_PATH + member);
+ }
+
+ auto skipLEDs = json.value("skipLEDs", empty);
+ for (auto& member : skipLEDs)
+ {
+ skipUpdateLEDs.push_back(PHY_LED_PATH + member);
+ }
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>("Failed to parse config file",
+ entry("ERROR=%s", e.what()),
+ entry("FILE_PATH=%s", path.c_str()));
+ }
+ return;
+}
+
} // namespace led
} // namespace phosphor