blob: 053a6a7c21220b7cb9ed1c9495c8acd8a259009e [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 Venture91ac8d32018-11-01 17:03:22 -070010#include <set>
Andrew Geisslerd02c3cb2020-05-16 10:28:02 -050011#include <string>
Patrick Williamsf2044032022-03-17 05:12:30 -050012#include <unordered_map>
Patrick Venture91ac8d32018-11-01 17:03:22 -070013
Alexander Hansena6f9a412024-07-24 12:27:42 +020014// to better see what the string is representing
15using LedName = std::string;
16
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053017namespace phosphor
18{
19namespace led
20{
George Liu1c737af2020-10-16 09:07:02 +080021using namespace phosphor::led::utils;
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +053022
George Liu1f0b7152023-07-18 09:24:34 +080023static constexpr auto phyLedPath = "/xyz/openbmc_project/led/physical/";
24static constexpr auto phyLedIntf = "xyz.openbmc_project.Led.Physical";
George Liu87fd11c2020-11-23 16:40:14 +080025
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053026/** @class Manager
27 * @brief Manages group of LEDs and applies action on the elements of group
28 */
29class Manager
30{
Patrick Venture91ac8d32018-11-01 17:03:22 -070031 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;
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053039
Patrick Venture91ac8d32018-11-01 17:03:22 -070040 /** @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)
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053051 {
Patrick Venture91ac8d32018-11-01 17:03:22 -070052 if (left.action == right.action)
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053053 {
Patrick Venture91ac8d32018-11-01 17:03:22 -070054 return false;
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053055 }
Patrick Venture91ac8d32018-11-01 17:03:22 -070056 else
57 {
58 return true;
59 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053060 }
Patrick Venture91ac8d32018-11-01 17:03:22 -070061 return left.name < right.name;
62 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053063
Patrick Venture91ac8d32018-11-01 17:03:22 -070064 /** @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 }
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053070
Patrick Venture91ac8d32018-11-01 17:03:22 -070071 /** @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 }
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053077
Patrick Venture91ac8d32018-11-01 17:03:22 -070078 /** @brief static global map constructed at compile time */
Patrick Williams158b2c12022-03-17 05:57:44 -050079 const GroupMap& ledMap;
Vishwanatha Subbannaed490732016-12-20 15:59:29 +053080
Patrick Venture91ac8d32018-11-01 17:03:22 -070081 /** @brief Refer the user supplied LED layout and sdbusplus handler
82 *
83 * @param [in] bus - sdbusplus handler
Patrick Williams158b2c12022-03-17 05:57:44 -050084 * @param [in] GroupMap - LEDs group layout
Potin Laif1ed4792023-07-13 18:45:14 +080085 * @param [in] Event - sd event handler
Patrick Venture91ac8d32018-11-01 17:03:22 -070086 */
Potin Laif1ed4792023-07-13 18:45:14 +080087 Manager(
88 sdbusplus::bus_t& bus, const GroupMap& ledLayout,
89 const sdeventplus::Event& event = sdeventplus::Event::get_default()) :
Patrick Williams543ac9f2024-08-16 15:19:59 -040090 ledMap(ledLayout), bus(bus),
91 timer(event, [this](auto&) { driveLedsHandler(); })
Patrick Venture91ac8d32018-11-01 17:03:22 -070092 {
93 // Nothing here
94 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053095
Alexander Hansena6f9a412024-07-24 12:27:42 +020096 /* create the resulting map from all currently asserted groups */
Alexander Hansen7ba70c82024-07-23 13:46:25 +020097 static auto getNewMap(std::set<const Layout::GroupLayout*> assertedGroups)
Alexander Hansena6f9a412024-07-24 12:27:42 +020098 -> std::map<LedName, Layout::LedAction>;
99
Patrick Venture91ac8d32018-11-01 17:03:22 -0700100 /** @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 */
Patrick Williams158b2c12022-03-17 05:57:44 -0500110 bool setGroupState(const std::string& path, bool assert,
111 ActionSet& ledsAssert, ActionSet& ledsDeAssert);
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530112
Patrick Venture91ac8d32018-11-01 17:03:22 -0700113 /** @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 */
Patrick Williams158b2c12022-03-17 05:57:44 -0500121 void driveLEDs(ActionSet& ledsAssert, ActionSet& ledsDeAssert);
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530122
George Liu87fd11c2020-11-23 16:40:14 +0800123 /** @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
Potin Laif1ed4792023-07-13 18:45:14 +0800130 *
131 * @return: - 0: success, -1: LED set failed
George Liu87fd11c2020-11-23 16:40:14 +0800132 */
George Liuf0592552024-08-23 09:46:17 +0800133 static int drivePhysicalLED(const std::string& objPath,
134 Layout::Action action, uint8_t dutyOn,
135 const uint16_t period);
George Liu87fd11c2020-11-23 16:40:14 +0800136
George Liub6151622020-11-23 18:16:18 +0800137 /** @brief Set lamp test callback when enabled lamp test.
138 *
139 * @param[in] callBack - Custom callback when enabled lamp test
140 */
141 void setLampTestCallBack(
Patrick Williams158b2c12022-03-17 05:57:44 -0500142 std::function<bool(ActionSet& ledsAssert, ActionSet& ledsDeAssert)>
143 callBack);
George Liub6151622020-11-23 18:16:18 +0800144
Patrick Venture91ac8d32018-11-01 17:03:22 -0700145 private:
146 /** @brief sdbusplus handler */
Patrick Williams3e073ba2022-07-22 19:26:52 -0500147 sdbusplus::bus_t& bus;
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530148
Patrick Venture91ac8d32018-11-01 17:03:22 -0700149 /** Map of physical LED path to service name */
George Liu391bec52024-08-22 20:10:55 +0800150 std::unordered_map<std::string, std::string> phyLeds;
Vishwanatha Subbannadcc3f382017-03-24 20:15:02 +0530151
Patrick Venture91ac8d32018-11-01 17:03:22 -0700152 /** @brief Pointers to groups that are in asserted state */
Alexander Hansen7ba70c82024-07-23 13:46:25 +0200153 std::set<const Layout::GroupLayout*> assertedGroups;
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530154
Alexander Hansena6f9a412024-07-24 12:27:42 +0200155 /** Map of led name to current state */
156 std::map<std::string, Layout::LedAction> ledStateMap;
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +0530157
George Liub6151622020-11-23 18:16:18 +0800158 /** @brief Custom callback when enabled lamp test */
Patrick Williams158b2c12022-03-17 05:57:44 -0500159 std::function<bool(ActionSet& ledsAssert, ActionSet& ledsDeAssert)>
George Liub6151622020-11-23 18:16:18 +0800160 lampTestCallBack;
161
Potin Laif1ed4792023-07-13 18:45:14 +0800162 /** @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
Patrick Venture91ac8d32018-11-01 17:03:22 -0700174 /** @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);
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530181};
182
183} // namespace led
184} // namespace phosphor