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 return left.action != right.action; 53 } 54 return left.name < right.name; 55 } 56 57 /** @brief Comparator for finding LEDs to be DeAsserted */ 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 */ 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 */ 80 Manager( 81 sdbusplus::bus_t& bus, const GroupMap& ledLayout, 82 const sdeventplus::Event& event = sdeventplus::Event::get_default()) : 83 ledMap(ledLayout), bus(bus), 84 timer(event, [this](auto&) { driveLedsHandler(); }) 85 { 86 // Nothing here 87 } 88 89 /* create the resulting map from all currently asserted groups */ 90 static auto getNewMap(std::set<const Layout::GroupLayout*> assertedGroups) 91 -> std::map<LedName, Layout::LedAction>; 92 93 /** @brief Given a group name, applies the action on the group 94 * 95 * @param[in] path - dbus path of group 96 * @param[in] assert - Could be true or false 97 * @param[in] ledsAssert - LEDs that are to be asserted new 98 * or to a different state 99 * @param[in] ledsDeAssert - LEDs that are to be Deasserted 100 * 101 * @return - Success or exception thrown 102 */ 103 bool setGroupState(const std::string& path, bool assert, 104 ActionSet& ledsAssert, ActionSet& ledsDeAssert); 105 106 /** @brief Finds the set of LEDs to operate on and executes action 107 * 108 * @param[in] ledsAssert - LEDs that are to be asserted newly 109 * or to a different state 110 * @param[in] ledsDeAssert - LEDs that are to be Deasserted 111 * 112 * @return: None 113 */ 114 void driveLEDs(ActionSet& ledsAssert, ActionSet& ledsDeAssert); 115 116 /** @brief Chooses appropriate action to be triggered on physical LED 117 * and calls into function that applies the actual action. 118 * 119 * @param[in] objPath - D-Bus object path 120 * @param[in] action - Intended action to be triggered 121 * @param[in] dutyOn - Duty Cycle ON percentage 122 * @param[in] period - Time taken for one blink cycle 123 * 124 * @return: - 0: success, -1: LED set failed 125 */ 126 static int drivePhysicalLED(const std::string& objPath, 127 Layout::Action action, uint8_t dutyOn, 128 uint16_t period); 129 130 /** @brief Set lamp test callback when enabled lamp test. 131 * 132 * @param[in] callBack - Custom callback when enabled lamp test 133 */ 134 void setLampTestCallBack( 135 std::function<bool(ActionSet& ledsAssert, ActionSet& ledsDeAssert)> 136 callBack); 137 138 private: 139 /** @brief sdbusplus handler */ 140 sdbusplus::bus_t& bus; 141 142 /** Map of physical LED path to service name */ 143 std::unordered_map<std::string, std::string> phyLeds; 144 145 /** @brief Pointers to groups that are in asserted state */ 146 std::set<const Layout::GroupLayout*> assertedGroups; 147 148 /** Map of led name to current state */ 149 std::map<std::string, Layout::LedAction> ledStateMap; 150 151 /** @brief Custom callback when enabled lamp test */ 152 std::function<bool(ActionSet& ledsAssert, ActionSet& ledsDeAssert)> 153 lampTestCallBack; 154 155 /** @brief Timer used for LEDs handler callback*/ 156 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer; 157 158 /** @brief Contains the required set of assert LEDs action */ 159 ActionSet reqLedsAssert; 160 161 /** @brief Contains the required set of deassert LEDs action */ 162 ActionSet reqLedsDeAssert; 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