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