1953315d2SPatrick Williams #pragma once
2953315d2SPatrick Williams 
3953315d2SPatrick Williams #include "ledlayout.hpp"
4953315d2SPatrick Williams #include "utils.hpp"
5953315d2SPatrick Williams 
6*f1ed4796SPotin Lai #include <sdeventplus/event.hpp>
7*f1ed4796SPotin Lai #include <sdeventplus/utility/timer.hpp>
8*f1ed4796SPotin Lai 
9953315d2SPatrick Williams #include <set>
10953315d2SPatrick Williams #include <string>
11f2044037SPatrick Williams #include <unordered_map>
12953315d2SPatrick Williams 
13953315d2SPatrick Williams namespace phosphor
14953315d2SPatrick Williams {
15953315d2SPatrick Williams namespace led
16953315d2SPatrick Williams {
17953315d2SPatrick Williams using namespace phosphor::led::utils;
18953315d2SPatrick Williams 
191f0b715aSGeorge Liu static constexpr auto phyLedPath = "/xyz/openbmc_project/led/physical/";
201f0b715aSGeorge Liu static constexpr auto phyLedIntf = "xyz.openbmc_project.Led.Physical";
21953315d2SPatrick Williams 
22953315d2SPatrick Williams /** @class Manager
23953315d2SPatrick Williams  *  @brief Manages group of LEDs and applies action on the elements of group
24953315d2SPatrick Williams  */
25953315d2SPatrick Williams class Manager
26953315d2SPatrick Williams {
27953315d2SPatrick Williams   public:
28953315d2SPatrick Williams     /** @brief Only need the default Manager */
29953315d2SPatrick Williams     Manager() = delete;
30953315d2SPatrick Williams     ~Manager() = default;
31953315d2SPatrick Williams     Manager(const Manager&) = delete;
32953315d2SPatrick Williams     Manager& operator=(const Manager&) = delete;
33953315d2SPatrick Williams     Manager(Manager&&) = delete;
34953315d2SPatrick Williams     Manager& operator=(Manager&&) = delete;
35953315d2SPatrick Williams 
36953315d2SPatrick Williams     /** @brief Special comparator for finding set difference */
ledComp(const phosphor::led::Layout::LedAction & left,const phosphor::led::Layout::LedAction & right)37953315d2SPatrick Williams     static bool ledComp(const phosphor::led::Layout::LedAction& left,
38953315d2SPatrick Williams                         const phosphor::led::Layout::LedAction& right)
39953315d2SPatrick Williams     {
40953315d2SPatrick Williams         // Example :
41953315d2SPatrick Williams         // If FIRST_1 is {fan0, 1, 1} and FIRST_2 is {fan0, 2, 2},
42953315d2SPatrick Williams         // with default priority of Blink, this comparator would return
43953315d2SPatrick Williams         // false. But considering the priority, this comparator would need
44953315d2SPatrick Williams         // to return true so that we consider appropriate set and in
45953315d2SPatrick Williams         // this case its {fan0, 1, 1}
46953315d2SPatrick Williams         if (left.name == right.name)
47953315d2SPatrick Williams         {
48953315d2SPatrick Williams             if (left.action == right.action)
49953315d2SPatrick Williams             {
50953315d2SPatrick Williams                 return false;
51953315d2SPatrick Williams             }
52953315d2SPatrick Williams             else
53953315d2SPatrick Williams             {
54953315d2SPatrick Williams                 return true;
55953315d2SPatrick Williams             }
56953315d2SPatrick Williams         }
57953315d2SPatrick Williams         return left.name < right.name;
58953315d2SPatrick Williams     }
59953315d2SPatrick Williams 
60953315d2SPatrick Williams     /** @brief Comparator for finding LEDs to be DeAsserted */
ledLess(const phosphor::led::Layout::LedAction & left,const phosphor::led::Layout::LedAction & right)61953315d2SPatrick Williams     static bool ledLess(const phosphor::led::Layout::LedAction& left,
62953315d2SPatrick Williams                         const phosphor::led::Layout::LedAction& right)
63953315d2SPatrick Williams     {
64953315d2SPatrick Williams         return left.name < right.name;
65953315d2SPatrick Williams     }
66953315d2SPatrick Williams 
67953315d2SPatrick Williams     /** @brief Comparator for helping unique_copy */
ledEqual(const phosphor::led::Layout::LedAction & left,const phosphor::led::Layout::LedAction & right)68953315d2SPatrick Williams     static bool ledEqual(const phosphor::led::Layout::LedAction& left,
69953315d2SPatrick Williams                          const phosphor::led::Layout::LedAction& right)
70953315d2SPatrick Williams     {
71953315d2SPatrick Williams         return left.name == right.name;
72953315d2SPatrick Williams     }
73953315d2SPatrick Williams 
74953315d2SPatrick Williams     /** @brief static global map constructed at compile time */
75158b2c14SPatrick Williams     const GroupMap& ledMap;
76953315d2SPatrick Williams 
77953315d2SPatrick Williams     /** @brief Refer the user supplied LED layout and sdbusplus handler
78953315d2SPatrick Williams      *
79953315d2SPatrick Williams      *  @param [in] bus       - sdbusplus handler
80158b2c14SPatrick Williams      *  @param [in] GroupMap - LEDs group layout
81*f1ed4796SPotin Lai      *  @param [in] Event    - sd event handler
82953315d2SPatrick Williams      */
Manager(sdbusplus::bus_t & bus,const GroupMap & ledLayout,const sdeventplus::Event & event=sdeventplus::Event::get_default ())83*f1ed4796SPotin Lai     Manager(
84*f1ed4796SPotin Lai         sdbusplus::bus_t& bus, const GroupMap& ledLayout,
85*f1ed4796SPotin Lai         const sdeventplus::Event& event = sdeventplus::Event::get_default()) :
86*f1ed4796SPotin Lai         ledMap(ledLayout),
87*f1ed4796SPotin Lai         bus(bus), timer(event, [this](auto&) { driveLedsHandler(); })
88953315d2SPatrick Williams     {
89953315d2SPatrick Williams         // Nothing here
90953315d2SPatrick Williams     }
91953315d2SPatrick Williams 
92953315d2SPatrick Williams     /** @brief Given a group name, applies the action on the group
93953315d2SPatrick Williams      *
94953315d2SPatrick Williams      *  @param[in]  path          -  dbus path of group
95953315d2SPatrick Williams      *  @param[in]  assert        -  Could be true or false
96953315d2SPatrick Williams      *  @param[in]  ledsAssert    -  LEDs that are to be asserted new
97953315d2SPatrick Williams      *                               or to a different state
98953315d2SPatrick Williams      *  @param[in]  ledsDeAssert  -  LEDs that are to be Deasserted
99953315d2SPatrick Williams      *
100953315d2SPatrick Williams      *  @return                   -  Success or exception thrown
101953315d2SPatrick Williams      */
102158b2c14SPatrick Williams     bool setGroupState(const std::string& path, bool assert,
103158b2c14SPatrick Williams                        ActionSet& ledsAssert, ActionSet& ledsDeAssert);
104953315d2SPatrick Williams 
105953315d2SPatrick Williams     /** @brief Finds the set of LEDs to operate on and executes action
106953315d2SPatrick Williams      *
107953315d2SPatrick Williams      *  @param[in]  ledsAssert    -  LEDs that are to be asserted newly
108953315d2SPatrick Williams      *                               or to a different state
109953315d2SPatrick Williams      *  @param[in]  ledsDeAssert  -  LEDs that are to be Deasserted
110953315d2SPatrick Williams      *
111953315d2SPatrick Williams      *  @return: None
112953315d2SPatrick Williams      */
113158b2c14SPatrick Williams     void driveLEDs(ActionSet& ledsAssert, ActionSet& ledsDeAssert);
114953315d2SPatrick Williams 
115953315d2SPatrick Williams     /** @brief Chooses appropriate action to be triggered on physical LED
116953315d2SPatrick Williams      *  and calls into function that applies the actual action.
117953315d2SPatrick Williams      *
118953315d2SPatrick Williams      *  @param[in]  objPath   -  D-Bus object path
119953315d2SPatrick Williams      *  @param[in]  action    -  Intended action to be triggered
120953315d2SPatrick Williams      *  @param[in]  dutyOn    -  Duty Cycle ON percentage
121953315d2SPatrick Williams      *  @param[in]  period    -  Time taken for one blink cycle
122*f1ed4796SPotin Lai      *
123*f1ed4796SPotin Lai      *  @return:              -  0: success, -1: LED set failed
124953315d2SPatrick Williams      */
125*f1ed4796SPotin Lai     int drivePhysicalLED(const std::string& objPath, Layout::Action action,
126953315d2SPatrick Williams                          uint8_t dutyOn, const uint16_t period);
127953315d2SPatrick Williams 
128953315d2SPatrick Williams     /** @brief Set lamp test callback when enabled lamp test.
129953315d2SPatrick Williams      *
130953315d2SPatrick Williams      *  @param[in]  callBack   -  Custom callback when enabled lamp test
131953315d2SPatrick Williams      */
132953315d2SPatrick Williams     void setLampTestCallBack(
133158b2c14SPatrick Williams         std::function<bool(ActionSet& ledsAssert, ActionSet& ledsDeAssert)>
134158b2c14SPatrick Williams             callBack);
135953315d2SPatrick Williams 
136953315d2SPatrick Williams   private:
137953315d2SPatrick Williams     /** @brief sdbusplus handler */
1383e073ba6SPatrick Williams     sdbusplus::bus_t& bus;
139953315d2SPatrick Williams 
140953315d2SPatrick Williams     /** Map of physical LED path to service name */
141f2044037SPatrick Williams     std::unordered_map<std::string, std::string> phyLeds{};
142953315d2SPatrick Williams 
143953315d2SPatrick Williams     /** DBusHandler class handles the D-Bus operations */
144953315d2SPatrick Williams     DBusHandler dBusHandler;
145953315d2SPatrick Williams 
146953315d2SPatrick Williams     /** @brief Pointers to groups that are in asserted state */
147158b2c14SPatrick Williams     std::set<const ActionSet*> assertedGroups;
148953315d2SPatrick Williams 
149953315d2SPatrick Williams     /** @brief Contains the highest priority actions for all
150953315d2SPatrick Williams      *         asserted LEDs.
151953315d2SPatrick Williams      */
152158b2c14SPatrick Williams     ActionSet currentState;
153953315d2SPatrick Williams 
154953315d2SPatrick Williams     /** @brief Contains the set of all actions for asserted LEDs */
155158b2c14SPatrick Williams     ActionSet combinedState;
156953315d2SPatrick Williams 
157953315d2SPatrick Williams     /** @brief Custom callback when enabled lamp test */
158158b2c14SPatrick Williams     std::function<bool(ActionSet& ledsAssert, ActionSet& ledsDeAssert)>
159953315d2SPatrick Williams         lampTestCallBack;
160953315d2SPatrick Williams 
161*f1ed4796SPotin Lai     /** @brief Timer used for LEDs handler callback*/
162*f1ed4796SPotin Lai     sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer;
163*f1ed4796SPotin Lai 
164*f1ed4796SPotin Lai     /** @brief Contains the required set of assert LEDs action */
165*f1ed4796SPotin Lai     ActionSet reqLedsAssert;
166*f1ed4796SPotin Lai 
167*f1ed4796SPotin Lai     /** @brief Contains the required set of deassert LEDs action */
168*f1ed4796SPotin Lai     ActionSet reqLedsDeAssert;
169*f1ed4796SPotin Lai 
170*f1ed4796SPotin Lai     /** @brief LEDs handler callback */
171*f1ed4796SPotin Lai     void driveLedsHandler();
172*f1ed4796SPotin Lai 
173953315d2SPatrick Williams     /** @brief Returns action string based on enum
174953315d2SPatrick Williams      *
175953315d2SPatrick Williams      *  @param[in]  action - Action enum
176953315d2SPatrick Williams      *
177953315d2SPatrick Williams      *  @return string equivalent of the passed in enumeration
178953315d2SPatrick Williams      */
179953315d2SPatrick Williams     static std::string getPhysicalAction(Layout::Action action);
180953315d2SPatrick Williams };
181953315d2SPatrick Williams 
182953315d2SPatrick Williams } // namespace led
183953315d2SPatrick Williams } // namespace phosphor
184