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 int drivePhysicalLED(const std::string& objPath, Layout::Action action, 134 uint8_t dutyOn, const uint16_t period); 135 136 /** @brief Set lamp test callback when enabled lamp test. 137 * 138 * @param[in] callBack - Custom callback when enabled lamp test 139 */ 140 void setLampTestCallBack( 141 std::function<bool(ActionSet& ledsAssert, ActionSet& ledsDeAssert)> 142 callBack); 143 144 private: 145 /** @brief sdbusplus handler */ 146 sdbusplus::bus_t& bus; 147 148 /** Map of physical LED path to service name */ 149 std::unordered_map<std::string, std::string> phyLeds{}; 150 151 /** DBusHandler class handles the D-Bus operations */ 152 DBusHandler dBusHandler; 153 154 /** @brief Pointers to groups that are in asserted state */ 155 std::set<const Layout::GroupLayout*> assertedGroups; 156 157 /** Map of led name to current state */ 158 std::map<std::string, Layout::LedAction> ledStateMap; 159 160 /** @brief Custom callback when enabled lamp test */ 161 std::function<bool(ActionSet& ledsAssert, ActionSet& ledsDeAssert)> 162 lampTestCallBack; 163 164 /** @brief Timer used for LEDs handler callback*/ 165 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer; 166 167 /** @brief Contains the required set of assert LEDs action */ 168 ActionSet reqLedsAssert; 169 170 /** @brief Contains the required set of deassert LEDs action */ 171 ActionSet reqLedsDeAssert; 172 173 /** @brief LEDs handler callback */ 174 void driveLedsHandler(); 175 176 /** @brief Returns action string based on enum 177 * 178 * @param[in] action - Action enum 179 * 180 * @return string equivalent of the passed in enumeration 181 */ 182 static std::string getPhysicalAction(Layout::Action action); 183 }; 184 185 } // namespace led 186 } // namespace phosphor 187