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 <chrono> 11 #include <set> 12 #include <string> 13 #include <unordered_map> 14 15 // to better see what the string is representing 16 using LedName = std::string; 17 18 namespace phosphor 19 { 20 namespace led 21 { 22 using namespace phosphor::led::utils; 23 24 static constexpr auto phyLedPath = "/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 */ ledComp(const phosphor::led::Layout::LedAction & left,const phosphor::led::Layout::LedAction & right)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 return left.action != right.action; 53 } 54 return left.name < right.name; 55 } 56 57 /** @brief Comparator for finding LEDs to be DeAsserted */ ledLess(const phosphor::led::Layout::LedAction & left,const phosphor::led::Layout::LedAction & right)58 static bool ledLess(const phosphor::led::Layout::LedAction& left, 59 const phosphor::led::Layout::LedAction& right) 60 { 61 return left.name < right.name; 62 } 63 64 /** @brief Comparator for helping unique_copy */ ledEqual(const phosphor::led::Layout::LedAction & left,const phosphor::led::Layout::LedAction & right)65 static bool ledEqual(const phosphor::led::Layout::LedAction& left, 66 const phosphor::led::Layout::LedAction& right) 67 { 68 return left.name == right.name; 69 } 70 71 /** @brief static global map constructed at compile time */ 72 const GroupMap& ledMap; 73 74 /** @brief Refer the user supplied LED layout and sdbusplus handler 75 * 76 * @param [in] bus - sdbusplus handler 77 * @param [in] GroupMap - LEDs group layout 78 * @param [in] Event - sd event handler 79 */ Manager(sdbusplus::bus_t &,const GroupMap & ledLayout,const sdeventplus::Event & event=sdeventplus::Event::get_default ())80 Manager( 81 sdbusplus::bus_t&, const GroupMap& ledLayout, 82 const sdeventplus::Event& event = sdeventplus::Event::get_default()) : 83 ledMap(ledLayout), timer(event, [this](auto&) { driveLedsHandler(); }) 84 { 85 // Nothing here 86 } 87 88 /* create the resulting map from all currently asserted groups */ 89 static auto getNewMap(std::set<const Layout::GroupLayout*> assertedGroups) 90 -> std::map<LedName, Layout::LedAction>; 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, 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 /** Map of physical LED path to service name */ 138 std::unordered_map<std::string, std::string> phyLeds; 139 140 /** @brief Pointers to groups that are in asserted state */ 141 std::set<const Layout::GroupLayout*> assertedGroups; 142 143 /** Map of led name to current state */ 144 std::map<std::string, Layout::LedAction> ledStateMap; 145 146 /** @brief Custom callback when enabled lamp test */ 147 std::function<bool(ActionSet& ledsAssert, ActionSet& ledsDeAssert)> 148 lampTestCallBack; 149 150 /** @brief Timer used for LEDs handler callback*/ 151 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer; 152 153 /** @brief Contains the required set of assert LEDs action */ 154 ActionSet reqLedsAssert; 155 156 /** @brief Contains the required set of deassert LEDs action */ 157 ActionSet reqLedsDeAssert; 158 159 /** @brief Map to store the last error time for physical LED paths */ 160 std::unordered_map<std::string, 161 std::chrono::time_point<std::chrono::steady_clock>> 162 physicalLEDErrors; 163 164 /** @brief LEDs handler callback */ 165 void driveLedsHandler(); 166 167 /** @brief Returns action string based on enum 168 * 169 * @param[in] action - Action enum 170 * 171 * @return string equivalent of the passed in enumeration 172 */ 173 static std::string getPhysicalAction(Layout::Action action); 174 }; 175 176 } // namespace led 177 } // namespace phosphor 178