diff options
Diffstat (limited to 'manager.cpp')
-rw-r--r-- | manager.cpp | 99 |
1 files changed, 93 insertions, 6 deletions
diff --git a/manager.cpp b/manager.cpp index e4137d3..44b0480 100644 --- a/manager.cpp +++ b/manager.cpp @@ -1,6 +1,7 @@ #include <iostream> #include <string> #include <algorithm> +#include <phosphor-logging/log.hpp> #include "manager.hpp" namespace phosphor { @@ -80,6 +81,13 @@ bool Manager::setGroupState(const std::string& path, bool assert, void Manager::driveLEDs(group& ledsAssert, group& ledsDeAssert, group& ledsUpdate) { + // For now, physical LED is driven by xyz.openbmc_project.Led.Controller + // at /xyz/openbmc_project/led/physical. However, its possible that in the + // future, the physical LEDs are driven by different dbus services. + // when that happens, service name needs to be obtained everytime a + // particular LED would be targeted as opposed to getting one now and then + // using it for all + // This order of LED operation is important. if (ledsUpdate.size()) { @@ -87,8 +95,8 @@ void Manager::driveLEDs(group& ledsAssert, group& ledsDeAssert, << std::endl; for (const auto& it: ledsUpdate) { - std::cout << "\t{" << it.name << "::" << it.action << "}" - << std::endl; + std::string objPath = std::string(PHY_LED_PATH) + it.name; + drivePhysicalLED(objPath, it.action, it.dutyOn); } } @@ -97,8 +105,8 @@ void Manager::driveLEDs(group& ledsAssert, group& ledsDeAssert, std::cout << "De-Asserting LEDs" << std::endl; for (const auto& it: ledsDeAssert) { - std::cout << "\t{" << it.name << "::" << it.action << "}" - << std::endl; + std::string objPath = std::string(PHY_LED_PATH) + it.name; + drivePhysicalLED(objPath, Layout::Action::Off, it.dutyOn); } } @@ -107,12 +115,91 @@ void Manager::driveLEDs(group& ledsAssert, group& ledsDeAssert, std::cout << "Asserting LEDs" << std::endl; for (const auto& it: ledsAssert) { - std::cout << "\t{" << it.name << "::" << it.action << "}" - << std::endl; + std::string objPath = std::string(PHY_LED_PATH) + it.name; + drivePhysicalLED(objPath, it.action, it.dutyOn); } } return; } +// Calls into driving physical LED post choosing the action +void Manager::drivePhysicalLED(const std::string& objPath, + Layout::Action action, + uint8_t dutyOn) +{ + auto service = getServiceName(objPath, PHY_LED_IFACE); + if (!service.empty()) + { + // If Blink, set its property + if (action == Layout::Action::Blink) + { + drivePhysicalLED(service, objPath, "DutyOn", dutyOn); + } + drivePhysicalLED(service, objPath, "State", + getPhysicalAction(action)); + } +} + +/** @brief Returns action string based on enum */ +const char* const Manager::getPhysicalAction(Layout::Action action) +{ + // TODO : When this is moved over to using libdus interfaces, this code will + // away. https://github.com/openbmc/phosphor-led-manager/issues/2 + if(action == Layout::Action::On) + { + return "xyz.openbmc_project.Led.Physical.Action.On"; + } + else if(action == Layout::Action::Blink) + { + return "xyz.openbmc_project.Led.Physical.Action.Blink"; + } + else + { + return "xyz.openbmc_project.Led.Physical.Action.Off"; + } +} + +/** Given the LED dbus path and interface, returns the service name */ +std::string Manager::getServiceName(const std::string& objPath, + const std::string& interface) const +{ + using namespace phosphor::logging; + + // Mapper dbus constructs + constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper"; + constexpr auto MAPPER_OBJ_PATH = "/xyz/openbmc_project/ObjectMapper"; + constexpr auto MAPPER_IFACE = "xyz.openbmc_project.ObjectMapper"; + + // Make a mapper call + auto mapperCall = bus.new_method_call(MAPPER_BUSNAME, MAPPER_OBJ_PATH, + MAPPER_IFACE, "GetObject"); + // Cook rest of the things. + mapperCall.append(objPath); + mapperCall.append(std::vector<std::string>({interface})); + + auto reply = bus.call(mapperCall); + if (reply.is_method_error()) + { + // Its okay if we do not see a corresponding physical LED. + log<level::INFO>("Error looking up Physical LED service", + entry("PATH=%s",objPath.c_str())); + return ""; + } + + // Response by mapper in the case of success + std::map<std::string, std::vector<std::string>> serviceNames; + + // This is the service name for the passed in objpath + reply.read(serviceNames); + if (serviceNames.empty()) + { + log<level::INFO>("Physical LED lookup did not return any service", + entry("PATH=%s",objPath.c_str())); + return ""; + } + + return serviceNames.begin()->first; +} + } // namespace led } // namespace phosphor |