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