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