1 #pragma once 2 3 #include "ledlayout.hpp" 4 #include "utils.hpp" 5 6 #include <sdeventplus/event.hpp> 7 #include <sdeventplus/utility/timer.hpp> 8 9 #include <set> 10 #include <string> 11 #include <unordered_map> 12 13 namespace phosphor 14 { 15 namespace led 16 { 17 using namespace phosphor::led::utils; 18 19 static constexpr auto phyLedPath = "/xyz/openbmc_project/led/physical/"; 20 static constexpr auto phyLedIntf = "xyz.openbmc_project.Led.Physical"; 21 22 /** @class Manager 23 * @brief Manages group of LEDs and applies action on the elements of group 24 */ 25 class Manager 26 { 27 public: 28 /** @brief Only need the default Manager */ 29 Manager() = delete; 30 ~Manager() = default; 31 Manager(const Manager&) = delete; 32 Manager& operator=(const Manager&) = delete; 33 Manager(Manager&&) = delete; 34 Manager& operator=(Manager&&) = delete; 35 36 /** @brief Special comparator for finding set difference */ 37 static bool ledComp(const phosphor::led::Layout::LedAction& left, 38 const phosphor::led::Layout::LedAction& right) 39 { 40 // Example : 41 // If FIRST_1 is {fan0, 1, 1} and FIRST_2 is {fan0, 2, 2}, 42 // with default priority of Blink, this comparator would return 43 // false. But considering the priority, this comparator would need 44 // to return true so that we consider appropriate set and in 45 // this case its {fan0, 1, 1} 46 if (left.name == right.name) 47 { 48 if (left.action == right.action) 49 { 50 return false; 51 } 52 else 53 { 54 return true; 55 } 56 } 57 return left.name < right.name; 58 } 59 60 /** @brief Comparator for finding LEDs to be DeAsserted */ 61 static bool ledLess(const phosphor::led::Layout::LedAction& left, 62 const phosphor::led::Layout::LedAction& right) 63 { 64 return left.name < right.name; 65 } 66 67 /** @brief Comparator for helping unique_copy */ 68 static bool ledEqual(const phosphor::led::Layout::LedAction& left, 69 const phosphor::led::Layout::LedAction& right) 70 { 71 return left.name == right.name; 72 } 73 74 /** @brief static global map constructed at compile time */ 75 const GroupMap& ledMap; 76 77 /** @brief Refer the user supplied LED layout and sdbusplus handler 78 * 79 * @param [in] bus - sdbusplus handler 80 * @param [in] GroupMap - LEDs group layout 81 * @param [in] Event - sd event handler 82 */ 83 Manager( 84 sdbusplus::bus_t& bus, const GroupMap& ledLayout, 85 const sdeventplus::Event& event = sdeventplus::Event::get_default()) : 86 ledMap(ledLayout), 87 bus(bus), timer(event, [this](auto&) { driveLedsHandler(); }) 88 { 89 // Nothing here 90 } 91 92 /** @brief Given a group name, applies the action on the group 93 * 94 * @param[in] path - dbus path of group 95 * @param[in] assert - Could be true or false 96 * @param[in] ledsAssert - LEDs that are to be asserted new 97 * or to a different state 98 * @param[in] ledsDeAssert - LEDs that are to be Deasserted 99 * 100 * @return - Success or exception thrown 101 */ 102 bool setGroupState(const std::string& path, bool assert, 103 ActionSet& ledsAssert, ActionSet& ledsDeAssert); 104 105 /** @brief Finds the set of LEDs to operate on and executes action 106 * 107 * @param[in] ledsAssert - LEDs that are to be asserted newly 108 * or to a different state 109 * @param[in] ledsDeAssert - LEDs that are to be Deasserted 110 * 111 * @return: None 112 */ 113 void driveLEDs(ActionSet& ledsAssert, ActionSet& ledsDeAssert); 114 115 /** @brief Chooses appropriate action to be triggered on physical LED 116 * and calls into function that applies the actual action. 117 * 118 * @param[in] objPath - D-Bus object path 119 * @param[in] action - Intended action to be triggered 120 * @param[in] dutyOn - Duty Cycle ON percentage 121 * @param[in] period - Time taken for one blink cycle 122 * 123 * @return: - 0: success, -1: LED set failed 124 */ 125 int drivePhysicalLED(const std::string& objPath, Layout::Action action, 126 uint8_t dutyOn, const uint16_t period); 127 128 /** @brief Set lamp test callback when enabled lamp test. 129 * 130 * @param[in] callBack - Custom callback when enabled lamp test 131 */ 132 void setLampTestCallBack( 133 std::function<bool(ActionSet& ledsAssert, ActionSet& ledsDeAssert)> 134 callBack); 135 136 private: 137 /** @brief sdbusplus handler */ 138 sdbusplus::bus_t& bus; 139 140 /** Map of physical LED path to service name */ 141 std::unordered_map<std::string, std::string> phyLeds{}; 142 143 /** DBusHandler class handles the D-Bus operations */ 144 DBusHandler dBusHandler; 145 146 /** @brief Pointers to groups that are in asserted state */ 147 std::set<const ActionSet*> assertedGroups; 148 149 /** @brief Contains the highest priority actions for all 150 * asserted LEDs. 151 */ 152 ActionSet currentState; 153 154 /** @brief Contains the set of all actions for asserted LEDs */ 155 ActionSet combinedState; 156 157 /** @brief Custom callback when enabled lamp test */ 158 std::function<bool(ActionSet& ledsAssert, ActionSet& ledsDeAssert)> 159 lampTestCallBack; 160 161 /** @brief Timer used for LEDs handler callback*/ 162 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer; 163 164 /** @brief Contains the required set of assert LEDs action */ 165 ActionSet reqLedsAssert; 166 167 /** @brief Contains the required set of deassert LEDs action */ 168 ActionSet reqLedsDeAssert; 169 170 /** @brief LEDs handler callback */ 171 void driveLedsHandler(); 172 173 /** @brief Returns action string based on enum 174 * 175 * @param[in] action - Action enum 176 * 177 * @return string equivalent of the passed in enumeration 178 */ 179 static std::string getPhysicalAction(Layout::Action action); 180 }; 181 182 } // namespace led 183 } // namespace phosphor 184