From dcc3f38fb677f57167f76a8f9e7f7cf4cfbf0c45 Mon Sep 17 00:00:00 2001 From: Vishwanatha Subbanna Date: Fri, 24 Mar 2017 20:15:02 +0530 Subject: LEDS: Get the service names for all physical LED dbus paths at once Previous code made a call to get the service name for every physical LED and that was a little costly. This patch changes it to get the service names of all the physical LED dbus paths and uses it. This is done everytime a group of LEDs are to be manipulated. Fixes openbmc/phosphor-led-manager#4 Change-Id: I5ce455f683a38eae7f9b383013f5729ec7dd7fae Signed-off-by: Vishwanatha Subbanna --- manager.cpp | 85 ++++++++++++++++++++++++++++++++++++++----------------------- manager.hpp | 14 ++++------ 2 files changed, 58 insertions(+), 41 deletions(-) diff --git a/manager.cpp b/manager.cpp index 7b5791a..26f00a5 100644 --- a/manager.cpp +++ b/manager.cpp @@ -82,12 +82,14 @@ 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 + // Map of physical LED dbus paths to their Service providers + populateObjectMap(); + + if (phyLeds.empty()) + { + // Error message is inside the map construction logic. + return; + } // This order of LED operation is important. if (ledsUpdate.size()) @@ -128,17 +130,24 @@ void Manager::drivePhysicalLED(const std::string& objPath, Layout::Action action, uint8_t dutyOn) { - auto service = getServiceName(objPath, PHY_LED_IFACE); - if (!service.empty()) + using namespace phosphor::logging; + + auto service = phyLeds.find(objPath); + if (service == phyLeds.end() || service->second.empty()) { - // If Blink, set its property - if (action == Layout::Action::Blink) - { - drivePhysicalLED(service, objPath, "DutyOn", dutyOn); - } - drivePhysicalLED(service, objPath, "State", - getPhysicalAction(action)); + log("No service providers for physical LED", + entry("PATH=%s",objPath.c_str())); + return; } + + // If Blink, set its property + if (action == Layout::Action::Blink) + { + drivePhysicalLED(service->second, objPath, "DutyOn", dutyOn); + } + drivePhysicalLED(service->second, objPath, "State", + getPhysicalAction(action)); + return; } /** @brief Returns action string based on enum */ @@ -163,9 +172,8 @@ std::string Manager::getPhysicalAction(Layout::Action action) } } -/** Given the LED dbus path and interface, returns the service name */ -std::string Manager::getServiceName(const std::string& objPath, - const std::string& interface) const +/** Populates a map with physical LED paths to its service providers */ +void Manager::populateObjectMap() { using namespace phosphor::logging; @@ -174,35 +182,48 @@ std::string Manager::getServiceName(const std::string& objPath, constexpr auto MAPPER_OBJ_PATH = "/xyz/openbmc_project/object_mapper"; constexpr auto MAPPER_IFACE = "xyz.openbmc_project.ObjectMapper"; + // Needed to be passed to get the SubTree level + auto depth = 0; + + // Clean start + phyLeds.clear(); + // Make a mapper call auto mapperCall = bus.new_method_call(MAPPER_BUSNAME, MAPPER_OBJ_PATH, - MAPPER_IFACE, "GetObject"); + MAPPER_IFACE, "GetSubTree"); // Cook rest of the things. - mapperCall.append(objPath); - mapperCall.append(std::vector({interface})); + mapperCall.append(PHY_LED_PATH); + mapperCall.append(depth); + mapperCall.append(std::vector({PHY_LED_IFACE})); auto reply = bus.call(mapperCall); if (reply.is_method_error()) { // Its okay if we do not see a corresponding physical LED. - log("Error looking up Physical LED service", - entry("PATH=%s",objPath.c_str())); - return ""; + log("Error looking up Physical LED services", + entry("PATH=%s",PHY_LED_PATH)); + return; } // Response by mapper in the case of success - std::map> serviceNames; + std::map>> objectTree; - // This is the service name for the passed in objpath - reply.read(serviceNames); - if (serviceNames.empty()) + // This is the dict of object paths - service names - interfaces + reply.read(objectTree); + if (objectTree.empty()) { - log("Physical LED lookup did not return any service", - entry("PATH=%s",objPath.c_str())); - return ""; + log("Physical LED lookup did not return any services", + entry("PATH=%s",PHY_LED_PATH)); + return; } - return serviceNames.begin()->first; + // Now construct our path -> Service name map. + for (const auto& iter : objectTree) + { + phyLeds.emplace(iter.first, iter.second.begin()->first); + } + return; } } // namespace led diff --git a/manager.hpp b/manager.hpp index 4adb229..1a75f8c 100644 --- a/manager.hpp +++ b/manager.hpp @@ -85,6 +85,9 @@ class Manager /** @brief sdbusplus handler */ sdbusplus::bus::bus& bus; + /** Map of physical LED path to service name */ + std::map phyLeds {}; + /** @brief Pointers to groups that are in asserted state */ std::set assertedGroups; @@ -138,15 +141,8 @@ class Manager return; } - /** @brief Finds the service name given a dbus object path and interface - * - * @param[in] objPath - dbus object path - * @param[in] interface - dbus interface - * - * @return: Service name or none - */ - std::string getServiceName(const std::string& objPath, - const std::string& interface) const; + /** @brief Populates map of Physical LED paths to service name */ + void populateObjectMap(); }; } // namespace led -- cgit v1.2.1