xref: /openbmc/phosphor-led-manager/manager/manager.hpp (revision ed80e885f8acbe565098177f844a42e038b90035)
1 #pragma once
2 
3 #include "ledlayout.hpp"
4 #include "utils.hpp"
5 
6 #include <map>
7 #include <set>
8 #include <string>
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     using group = std::set<phosphor::led::Layout::LedAction>;
72     using LedLayout = std::map<std::string, group>;
73 
74     /** @brief static global map constructed at compile time */
75     const LedLayout& ledMap;
76 
77     /** @brief Refer the user supplied LED layout and sdbusplus handler
78      *
79      *  @param [in] bus       - sdbusplus handler
80      *  @param [in] LedLayout - LEDs group layout
81      */
82     Manager(sdbusplus::bus::bus& bus, const LedLayout& ledLayout) :
83         ledMap(ledLayout), bus(bus)
84     {
85         // Nothing here
86     }
87 
88     /** @brief Given a group name, applies the action on the group
89      *
90      *  @param[in]  path          -  dbus path of group
91      *  @param[in]  assert        -  Could be true or false
92      *  @param[in]  ledsAssert    -  LEDs that are to be asserted new
93      *                               or to a different state
94      *  @param[in]  ledsDeAssert  -  LEDs that are to be Deasserted
95      *
96      *  @return                   -  Success or exception thrown
97      */
98     bool setGroupState(const std::string& path, bool assert, group& ledsAssert,
99                        group& ledsDeAssert);
100 
101     /** @brief Finds the set of LEDs to operate on and executes action
102      *
103      *  @param[in]  ledsAssert    -  LEDs that are to be asserted newly
104      *                               or to a different state
105      *  @param[in]  ledsDeAssert  -  LEDs that are to be Deasserted
106      *
107      *  @return: None
108      */
109     void driveLEDs(group& ledsAssert, group& ledsDeAssert);
110 
111     /** @brief Chooses appropriate action to be triggered on physical LED
112      *  and calls into function that applies the actual action.
113      *
114      *  @param[in]  objPath   -  D-Bus object path
115      *  @param[in]  action    -  Intended action to be triggered
116      *  @param[in]  dutyOn    -  Duty Cycle ON percentage
117      *  @param[in]  period    -  Time taken for one blink cycle
118      */
119     void drivePhysicalLED(const std::string& objPath, Layout::Action action,
120                           uint8_t dutyOn, const uint16_t period);
121 
122     /** @brief Set lamp test callback when enabled lamp test.
123      *
124      *  @param[in]  callBack   -  Custom callback when enabled lamp test
125      */
126     void setLampTestCallBack(
127         std::function<bool(group& ledsAssert, group& ledsDeAssert)> callBack);
128 
129   private:
130     /** @brief sdbusplus handler */
131     sdbusplus::bus::bus& bus;
132 
133     /** Map of physical LED path to service name */
134     std::map<std::string, std::string> phyLeds{};
135 
136     /** DBusHandler class handles the D-Bus operations */
137     DBusHandler dBusHandler;
138 
139     /** @brief Pointers to groups that are in asserted state */
140     std::set<const group*> assertedGroups;
141 
142     /** @brief Contains the highest priority actions for all
143      *         asserted LEDs.
144      */
145     group currentState;
146 
147     /** @brief Contains the set of all actions for asserted LEDs */
148     group combinedState;
149 
150     /** @brief Custom callback when enabled lamp test */
151     std::function<bool(group& ledsAssert, group& ledsDeAssert)>
152         lampTestCallBack;
153 
154     /** @brief Returns action string based on enum
155      *
156      *  @param[in]  action - Action enum
157      *
158      *  @return string equivalent of the passed in enumeration
159      */
160     static std::string getPhysicalAction(Layout::Action action);
161 };
162 
163 } // namespace led
164 } // namespace phosphor
165