blob: 0bdcc339c08eab0701347664f562ab62c62caeed [file] [log] [blame]
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +05301#pragma once
2
Alexander Hansen7ba70c82024-07-23 13:46:25 +02003#include "grouplayout.hpp"
Vishwanatha Subbannaed490732016-12-20 15:59:29 +05304#include "ledlayout.hpp"
George Liu1c737af2020-10-16 09:07:02 +08005#include "utils.hpp"
George Liua6c18f82020-06-22 10:50:04 +08006
Potin Laif1ed4792023-07-13 18:45:14 +08007#include <sdeventplus/event.hpp>
8#include <sdeventplus/utility/timer.hpp>
9
Patrick Williams858e5732025-05-14 15:25:07 -040010#include <chrono>
Patrick Venture91ac8d32018-11-01 17:03:22 -070011#include <set>
Andrew Geisslerd02c3cb2020-05-16 10:28:02 -050012#include <string>
Patrick Williamsf2044032022-03-17 05:12:30 -050013#include <unordered_map>
Patrick Venture91ac8d32018-11-01 17:03:22 -070014
Alexander Hansena6f9a412024-07-24 12:27:42 +020015// to better see what the string is representing
16using LedName = std::string;
17
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053018namespace phosphor
19{
20namespace led
21{
George Liu1c737af2020-10-16 09:07:02 +080022using namespace phosphor::led::utils;
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +053023
George Liu1f0b7152023-07-18 09:24:34 +080024static constexpr auto phyLedPath = "/xyz/openbmc_project/led/physical/";
25static constexpr auto phyLedIntf = "xyz.openbmc_project.Led.Physical";
George Liu87fd11c2020-11-23 16:40:14 +080026
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053027/** @class Manager
28 * @brief Manages group of LEDs and applies action on the elements of group
29 */
30class Manager
31{
Patrick Venture91ac8d32018-11-01 17:03:22 -070032 public:
33 /** @brief Only need the default Manager */
34 Manager() = delete;
35 ~Manager() = default;
36 Manager(const Manager&) = delete;
37 Manager& operator=(const Manager&) = delete;
38 Manager(Manager&&) = delete;
39 Manager& operator=(Manager&&) = delete;
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053040
Patrick Venture91ac8d32018-11-01 17:03:22 -070041 /** @brief Special comparator for finding set difference */
42 static bool ledComp(const phosphor::led::Layout::LedAction& left,
43 const phosphor::led::Layout::LedAction& right)
44 {
45 // Example :
46 // If FIRST_1 is {fan0, 1, 1} and FIRST_2 is {fan0, 2, 2},
47 // with default priority of Blink, this comparator would return
48 // false. But considering the priority, this comparator would need
49 // to return true so that we consider appropriate set and in
50 // this case its {fan0, 1, 1}
51 if (left.name == right.name)
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053052 {
George Liu349d22e2024-08-23 09:09:56 +080053 return left.action != right.action;
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053054 }
Patrick Venture91ac8d32018-11-01 17:03:22 -070055 return left.name < right.name;
56 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053057
Patrick Venture91ac8d32018-11-01 17:03:22 -070058 /** @brief Comparator for finding LEDs to be DeAsserted */
59 static bool ledLess(const phosphor::led::Layout::LedAction& left,
60 const phosphor::led::Layout::LedAction& right)
61 {
62 return left.name < right.name;
63 }
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053064
Patrick Venture91ac8d32018-11-01 17:03:22 -070065 /** @brief Comparator for helping unique_copy */
66 static bool ledEqual(const phosphor::led::Layout::LedAction& left,
67 const phosphor::led::Layout::LedAction& right)
68 {
69 return left.name == right.name;
70 }
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053071
Patrick Venture91ac8d32018-11-01 17:03:22 -070072 /** @brief static global map constructed at compile time */
Patrick Williams158b2c12022-03-17 05:57:44 -050073 const GroupMap& ledMap;
Vishwanatha Subbannaed490732016-12-20 15:59:29 +053074
Patrick Venture91ac8d32018-11-01 17:03:22 -070075 /** @brief Refer the user supplied LED layout and sdbusplus handler
76 *
77 * @param [in] bus - sdbusplus handler
Patrick Williams158b2c12022-03-17 05:57:44 -050078 * @param [in] GroupMap - LEDs group layout
Potin Laif1ed4792023-07-13 18:45:14 +080079 * @param [in] Event - sd event handler
Patrick Venture91ac8d32018-11-01 17:03:22 -070080 */
Potin Laif1ed4792023-07-13 18:45:14 +080081 Manager(
Patrick Williams4e93c862025-05-14 15:44:14 -040082 sdbusplus::bus_t&, const GroupMap& ledLayout,
Potin Laif1ed4792023-07-13 18:45:14 +080083 const sdeventplus::Event& event = sdeventplus::Event::get_default()) :
Patrick Williams4e93c862025-05-14 15:44:14 -040084 ledMap(ledLayout), timer(event, [this](auto&) { driveLedsHandler(); })
Patrick Venture91ac8d32018-11-01 17:03:22 -070085 {
86 // Nothing here
87 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053088
Alexander Hansena6f9a412024-07-24 12:27:42 +020089 /* create the resulting map from all currently asserted groups */
Alexander Hansen7ba70c82024-07-23 13:46:25 +020090 static auto getNewMap(std::set<const Layout::GroupLayout*> assertedGroups)
Alexander Hansena6f9a412024-07-24 12:27:42 +020091 -> std::map<LedName, Layout::LedAction>;
92
Patrick Venture91ac8d32018-11-01 17:03:22 -070093 /** @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 */
Patrick Williams158b2c12022-03-17 05:57:44 -0500103 bool setGroupState(const std::string& path, bool assert,
104 ActionSet& ledsAssert, ActionSet& ledsDeAssert);
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530105
Patrick Venture91ac8d32018-11-01 17:03:22 -0700106 /** @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 */
Patrick Williams158b2c12022-03-17 05:57:44 -0500114 void driveLEDs(ActionSet& ledsAssert, ActionSet& ledsDeAssert);
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530115
George Liu87fd11c2020-11-23 16:40:14 +0800116 /** @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
Potin Laif1ed4792023-07-13 18:45:14 +0800123 *
124 * @return: - 0: success, -1: LED set failed
George Liu87fd11c2020-11-23 16:40:14 +0800125 */
Patrick Williams858e5732025-05-14 15:25:07 -0400126 int drivePhysicalLED(const std::string& objPath, Layout::Action action,
127 uint8_t dutyOn, uint16_t period);
George Liu87fd11c2020-11-23 16:40:14 +0800128
George Liub6151622020-11-23 18:16:18 +0800129 /** @brief Set lamp test callback when enabled lamp test.
130 *
131 * @param[in] callBack - Custom callback when enabled lamp test
132 */
133 void setLampTestCallBack(
Patrick Williams158b2c12022-03-17 05:57:44 -0500134 std::function<bool(ActionSet& ledsAssert, ActionSet& ledsDeAssert)>
135 callBack);
George Liub6151622020-11-23 18:16:18 +0800136
Patrick Venture91ac8d32018-11-01 17:03:22 -0700137 private:
Patrick Venture91ac8d32018-11-01 17:03:22 -0700138 /** Map of physical LED path to service name */
George Liu391bec52024-08-22 20:10:55 +0800139 std::unordered_map<std::string, std::string> phyLeds;
Vishwanatha Subbannadcc3f382017-03-24 20:15:02 +0530140
Patrick Venture91ac8d32018-11-01 17:03:22 -0700141 /** @brief Pointers to groups that are in asserted state */
Alexander Hansen7ba70c82024-07-23 13:46:25 +0200142 std::set<const Layout::GroupLayout*> assertedGroups;
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530143
Alexander Hansena6f9a412024-07-24 12:27:42 +0200144 /** Map of led name to current state */
145 std::map<std::string, Layout::LedAction> ledStateMap;
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +0530146
George Liub6151622020-11-23 18:16:18 +0800147 /** @brief Custom callback when enabled lamp test */
Patrick Williams158b2c12022-03-17 05:57:44 -0500148 std::function<bool(ActionSet& ledsAssert, ActionSet& ledsDeAssert)>
George Liub6151622020-11-23 18:16:18 +0800149 lampTestCallBack;
150
Potin Laif1ed4792023-07-13 18:45:14 +0800151 /** @brief Timer used for LEDs handler callback*/
152 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer;
153
154 /** @brief Contains the required set of assert LEDs action */
155 ActionSet reqLedsAssert;
156
157 /** @brief Contains the required set of deassert LEDs action */
158 ActionSet reqLedsDeAssert;
159
Patrick Williams858e5732025-05-14 15:25:07 -0400160 /** @brief Map to store the last error time for physical LED paths */
161 std::unordered_map<std::string,
162 std::chrono::time_point<std::chrono::steady_clock>>
163 physicalLEDErrors;
164
Potin Laif1ed4792023-07-13 18:45:14 +0800165 /** @brief LEDs handler callback */
166 void driveLedsHandler();
167
Patrick Venture91ac8d32018-11-01 17:03:22 -0700168 /** @brief Returns action string based on enum
169 *
170 * @param[in] action - Action enum
171 *
172 * @return string equivalent of the passed in enumeration
173 */
174 static std::string getPhysicalAction(Layout::Action action);
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530175};
176
177} // namespace led
178} // namespace phosphor