xref: /openbmc/phosphor-led-manager/manager/manager.hpp (revision a6f9a41ec99d92daf02fc820b17bc9505b183f8c)
1 #pragma once
2 
3 #include "ledlayout.hpp"
4 #include "utils.hpp"
5 
6 #include <sdeventplus/event.hpp>
7 #include <sdeventplus/utility/timer.hpp>
8 
9 #include <set>
10 #include <string>
11 #include <unordered_map>
12 
13 // to better see what the string is representing
14 using LedName = std::string;
15 
16 namespace phosphor
17 {
18 namespace led
19 {
20 using namespace phosphor::led::utils;
21 
22 static constexpr auto phyLedPath = "/xyz/openbmc_project/led/physical/";
23 static constexpr auto phyLedIntf = "xyz.openbmc_project.Led.Physical";
24 
25 /** @class Manager
26  *  @brief Manages group of LEDs and applies action on the elements of group
27  */
28 class Manager
29 {
30   public:
31     /** @brief Only need the default Manager */
32     Manager() = delete;
33     ~Manager() = default;
34     Manager(const Manager&) = delete;
35     Manager& operator=(const Manager&) = delete;
36     Manager(Manager&&) = delete;
37     Manager& operator=(Manager&&) = delete;
38 
39     /** @brief Special comparator for finding set difference */
40     static bool ledComp(const phosphor::led::Layout::LedAction& left,
41                         const phosphor::led::Layout::LedAction& right)
42     {
43         // Example :
44         // If FIRST_1 is {fan0, 1, 1} and FIRST_2 is {fan0, 2, 2},
45         // with default priority of Blink, this comparator would return
46         // false. But considering the priority, this comparator would need
47         // to return true so that we consider appropriate set and in
48         // this case its {fan0, 1, 1}
49         if (left.name == right.name)
50         {
51             if (left.action == right.action)
52             {
53                 return false;
54             }
55             else
56             {
57                 return true;
58             }
59         }
60         return left.name < right.name;
61     }
62 
63     /** @brief Comparator for finding LEDs to be DeAsserted */
64     static bool ledLess(const phosphor::led::Layout::LedAction& left,
65                         const phosphor::led::Layout::LedAction& right)
66     {
67         return left.name < right.name;
68     }
69 
70     /** @brief Comparator for helping unique_copy */
71     static bool ledEqual(const phosphor::led::Layout::LedAction& left,
72                          const phosphor::led::Layout::LedAction& right)
73     {
74         return left.name == right.name;
75     }
76 
77     /** @brief static global map constructed at compile time */
78     const GroupMap& ledMap;
79 
80     /** @brief Refer the user supplied LED layout and sdbusplus handler
81      *
82      *  @param [in] bus       - sdbusplus handler
83      *  @param [in] GroupMap - LEDs group layout
84      *  @param [in] Event    - sd event handler
85      */
86     Manager(
87         sdbusplus::bus_t& bus, const GroupMap& ledLayout,
88         const sdeventplus::Event& event = sdeventplus::Event::get_default()) :
89         ledMap(ledLayout), bus(bus),
90         timer(event, [this](auto&) { driveLedsHandler(); })
91     {
92         // Nothing here
93     }
94 
95     /* create the resulting map from all currently asserted groups */
96     static auto getNewMap(std::set<const ActionSet*> assertedGroups)
97         -> std::map<LedName, Layout::LedAction>;
98 
99     /** @brief Given a group name, applies the action on the group
100      *
101      *  @param[in]  path          -  dbus path of group
102      *  @param[in]  assert        -  Could be true or false
103      *  @param[in]  ledsAssert    -  LEDs that are to be asserted new
104      *                               or to a different state
105      *  @param[in]  ledsDeAssert  -  LEDs that are to be Deasserted
106      *
107      *  @return                   -  Success or exception thrown
108      */
109     bool setGroupState(const std::string& path, bool assert,
110                        ActionSet& ledsAssert, ActionSet& ledsDeAssert);
111 
112     /** @brief Finds the set of LEDs to operate on and executes action
113      *
114      *  @param[in]  ledsAssert    -  LEDs that are to be asserted newly
115      *                               or to a different state
116      *  @param[in]  ledsDeAssert  -  LEDs that are to be Deasserted
117      *
118      *  @return: None
119      */
120     void driveLEDs(ActionSet& ledsAssert, ActionSet& ledsDeAssert);
121 
122     /** @brief Chooses appropriate action to be triggered on physical LED
123      *  and calls into function that applies the actual action.
124      *
125      *  @param[in]  objPath   -  D-Bus object path
126      *  @param[in]  action    -  Intended action to be triggered
127      *  @param[in]  dutyOn    -  Duty Cycle ON percentage
128      *  @param[in]  period    -  Time taken for one blink cycle
129      *
130      *  @return:              -  0: success, -1: LED set failed
131      */
132     int drivePhysicalLED(const std::string& objPath, Layout::Action action,
133                          uint8_t dutyOn, const uint16_t period);
134 
135     /** @brief Set lamp test callback when enabled lamp test.
136      *
137      *  @param[in]  callBack   -  Custom callback when enabled lamp test
138      */
139     void setLampTestCallBack(
140         std::function<bool(ActionSet& ledsAssert, ActionSet& ledsDeAssert)>
141             callBack);
142 
143   private:
144     /** @brief sdbusplus handler */
145     sdbusplus::bus_t& bus;
146 
147     /** Map of physical LED path to service name */
148     std::unordered_map<std::string, std::string> phyLeds{};
149 
150     /** DBusHandler class handles the D-Bus operations */
151     DBusHandler dBusHandler;
152 
153     /** @brief Pointers to groups that are in asserted state */
154     std::set<const ActionSet*> assertedGroups;
155 
156     /** Map of led name to current state */
157     std::map<std::string, Layout::LedAction> ledStateMap;
158 
159     /** @brief Custom callback when enabled lamp test */
160     std::function<bool(ActionSet& ledsAssert, ActionSet& ledsDeAssert)>
161         lampTestCallBack;
162 
163     /** @brief Timer used for LEDs handler callback*/
164     sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer;
165 
166     /** @brief Contains the required set of assert LEDs action */
167     ActionSet reqLedsAssert;
168 
169     /** @brief Contains the required set of deassert LEDs action */
170     ActionSet reqLedsDeAssert;
171 
172     /** @brief LEDs handler callback */
173     void driveLedsHandler();
174 
175     /** @brief Returns action string based on enum
176      *
177      *  @param[in]  action - Action enum
178      *
179      *  @return string equivalent of the passed in enumeration
180      */
181     static std::string getPhysicalAction(Layout::Action action);
182 };
183 
184 } // namespace led
185 } // namespace phosphor
186