xref: /openbmc/phosphor-buttons/inc/button_handler.hpp (revision 33eb55003f19ec95a95bfdf2473a1457535c1ee1)
1 #pragma once
2 
3 #include "config.hpp"
4 #include "power_button_profile.hpp"
5 
6 #include <sdbusplus/bus.hpp>
7 #include <sdbusplus/bus/match.hpp>
8 
9 #include <algorithm>
10 #include <numeric>
11 #include <sstream>
12 #include <string>
13 
14 namespace phosphor
15 {
16 namespace button
17 {
18 enum class PowerEvent
19 {
20     powerPressed,
21     resetPressed,
22     powerReleased,
23     resetReleased
24 };
25 
26 enum class PwrCtl
27 {
28     chassisOn,
29     chassisOff,
30     chassisCycle,
31 };
32 
numberOfChassis()33 inline static size_t numberOfChassis()
34 {
35     return instances.size();
36 }
37 
38 /**
39  * @class Handler
40  *
41  * This class acts on the signals generated by the
42  * xyz.openbmc_project.Chassis.Buttons code when
43  * it detects button presses.
44  *
45  * There are 3 buttons supported - Power, ID, and Reset.
46  * As not all systems may implement each button, this class will
47  * check for that button on D-Bus before listening for its signals.
48  */
49 class Handler
50 {
51   public:
52     Handler() = delete;
53     ~Handler() = default;
54     Handler(const Handler&) = delete;
55     Handler& operator=(const Handler&) = delete;
56     Handler(Handler&&) = delete;
57     Handler& operator=(Handler&&) = delete;
58 
59     /**
60      * @brief Constructor
61      *
62      * @param[in] bus - sdbusplus connection object
63      */
64     explicit Handler(sdbusplus::bus_t& bus);
65 
66   private:
67     /**
68      * @brief The handler for a power button press
69      *
70      * It will do power action according to the pressing duration.
71      *
72      * @param[in] msg - sdbusplus message from signal
73      */
74     void powerReleased(sdbusplus::message_t& msg);
75 
76     /**
77      * @brief The handler for an ID button press
78      *
79      * Toggles the ID LED group
80      *
81      * @param[in] msg - sdbusplus message from signal
82      */
83     void idReleased(sdbusplus::message_t& msg);
84 
85     /**
86      * @brief The handler for a reset button press
87      *
88      * Reboots the host if it is powered on.
89      *
90      * @param[in] msg - sdbusplus message from signal
91      */
92     void resetReleased(sdbusplus::message_t& msg);
93 
94     /**
95      * @brief The handler for a OCP debug card host selector button press
96      *
97      * In multi host system increases host position by 1 up to max host
98      * position.
99      *
100      * @param[in] msg - sdbusplus message from signal
101      */
102 
103     void debugHostSelectorReleased(sdbusplus::message_t& msg);
104 
105     /**
106      * @brief Checks if system is powered on
107      *
108      * @return true if powered on, false else
109      */
110     bool poweredOn(size_t hostNumber) const;
111 
112     /*
113      * @return std::string - the D-Bus service name if found, else
114      *                       an empty string
115      */
116     std::string getService(const std::string& path,
117                            const std::string& interface) const;
118 
119     /**
120      * @brief gets the valid host selector value in multi host
121      * system
122      *
123      * @return size_t throws exception if host selector position is
124      * invalid or not available.
125      */
126 
127     size_t getHostSelectorValue();
128 
129     /**
130      * @brief Get host number string from the D-Bus object path based on event
131      * type
132      *
133      * @param powerEventType - The type of power event
134      * (powerReleased/resetReleased)
135      *
136      * @param objectPath - The DBus object path from which to extract host
137      * number
138      *
139      * @return std::string - Host number as a string
140      *
141      * @throws std::runtime_error if the event type is invalid or parsing fails
142      */
143 
144     std::string getHostNumStr(PowerEvent powerEventType,
145                               const std::string& objectPath) const;
146 
147     /**
148      * @brief increases the host selector position property
149      * by 1 upto max host selector position
150      *
151      * @return void
152      */
153 
154     void increaseHostSelectorPosition();
155     /**
156      * @brief checks if the system has multi host
157      * based on the host selector property availability
158      *
159      * @return bool returns true if multi host system
160      * else returns false.
161      */
162     bool isMultiHost();
163     /**
164      * @brief trigger the power ctrl event based on the
165      *  button press event type.
166      *
167      * @return void
168      */
169     void handlePowerEvent(PowerEvent powerEventType,
170                           const std::string& objectPath,
171                           std::chrono::microseconds duration);
172 
173     /**
174      * @brief sdbusplus connection object
175      */
176     sdbusplus::bus_t& bus;
177 
178     /**
179      * @brief Matches on the power button long press released signal
180      */
181     std::unique_ptr<sdbusplus::bus::match_t> powerButtonLongPressed;
182 
183     /**
184      * @brief Matches on the multi power button released signal
185      */
186     std::vector<std::unique_ptr<sdbusplus::bus::match_t>>
187         multiPowerButtonReleased;
188 
189     /**
190      * @brief Matches on the ID button released signal
191      */
192     std::unique_ptr<sdbusplus::bus::match_t> idButtonReleased;
193 
194     /**
195      * @brief Matches on the reset button released signal
196      */
197     std::unique_ptr<sdbusplus::bus::match_t> resetButtonReleased;
198 
199     /**
200      * @brief Matches on the ocp debug host selector  button released signal
201      */
202     std::unique_ptr<sdbusplus::bus::match_t> debugHSButtonReleased;
203 
204     /**
205      * @brief The custom power handler profile object.
206      */
207     std::unique_ptr<PowerButtonProfile> powerButtonProfile;
208 
209     /**
210      * @brief Flag to indicate multi power button mode(false) or host select
211      * button mode(true)
212      */
213     bool hostSelectButtonMode = false;
214 
215     /**
216      * @brief Flag to indicate if the button is a virtual button
217      */
218     bool virtualButton = false;
219 };
220 
221 } // namespace button
222 } // namespace phosphor
223