1 #pragma once
2 
3 #include <fstream>
4 #include <sdbusplus/bus.hpp>
5 #include <sdbusplus/server/object.hpp>
6 #include <string>
7 #include <xyz/openbmc_project/Led/Physical/server.hpp>
8 namespace phosphor
9 {
10 namespace led
11 {
12 /** @brief Acts as input and output file for the current LED power state.
13  *   Write "0" to trigger a LED OFF operation.
14  *   Write "255" to trigger a LED ON operation.
15  *   To know the current power state of the LED, a read on this
16  *   would give either 0 or 255 indicating if the LED is currently
17  *   Off / On AT THAT moment.
18  *   Example: /sys/class/leds/myled/brightness
19  */
20 constexpr auto BRIGHTNESS = "/brightness";
21 
22 /** @brief Assert LED by writing 255 */
23 constexpr auto ASSERT = "255";
24 
25 /** @brief De-assert by writing "0" */
26 constexpr auto DEASSERT = "0";
27 
28 /** @brief Write "timer" to this file telling the driver that
29  *   the intended operation is BLINK. When the value "timer" is written to
30  *   the file, 2 more files get auto generated and are named "delay_on" and
31  *   "delay_off"
32  *   To move away from blinking, write "none"
33  *   Example:  /sys/class/leds/myled/trigger
34  */
35 constexpr auto BLINKCTRL = "/trigger";
36 
37 /** @brief write number of milliseconds that the LED needs to be ON
38  *   while blinking. Default is 500 by the driver.
39  *   Example:  /sys/class/leds/myled/delay_on
40  */
41 constexpr auto DELAYON = "/delay_on";
42 
43 /** @brief Write number of milliseconds that the LED needs to be OFF
44  *   while blinking. Default is 500 by the driver.
45  *   Example:  /sys/class/leds/myled/delay_off
46  */
47 constexpr auto DELAYOFF = "/delay_off";
48 
49 /** @class Physical
50  *  @brief Responsible for applying actions on a particular physical LED
51  */
52 class Physical : public sdbusplus::server::object::object<
53                      sdbusplus::xyz::openbmc_project::Led::server::Physical>
54 {
55   public:
56     Physical() = delete;
57     ~Physical() = default;
58     Physical(const Physical&) = delete;
59     Physical& operator=(const Physical&) = delete;
60     Physical(Physical&&) = delete;
61     Physical& operator=(Physical&&) = delete;
62 
63     /** @brief Constructs LED object. Argument 'true' says that we hold off
64      *   from sending the signals since we need to do some house keeping and
65      *   only when we finish that, we are considered active and can then
66      *   broadcast the signal.
67      *
68      * @param[in] bus       - system dbus handler
69      * @param[in] objPath   - The Dbus path that hosts physical LED
70      * @param[in] ledPath   - sysfs path where this LED is exported
71      */
72     Physical(sdbusplus::bus::bus& bus, const std::string& objPath,
73              const std::string& ledPath) :
74 
75         sdbusplus::server::object::object<
76             sdbusplus::xyz::openbmc_project::Led::server::Physical>(
77             bus, objPath.c_str(), true),
78         path(ledPath)
79     {
80         // Suppose this is getting launched as part of BMC reboot, then we
81         // need to save what the micro-controller currently has.
82         setInitialState();
83 
84         // We are now ready.
85         emit_object_added();
86     }
87 
88     /** @brief Overloaded State Property Setter function
89      *
90      *  @param[in] value   -  One of OFF / ON / BLINK
91      *  @return            -  Success or exception thrown
92      */
93     Action state(Action value) override;
94 
95   private:
96     /** @brief File system location where this LED is exposed
97      *   Typically /sys/class/leds/<Led-Name>
98      */
99     std::string path;
100 
101     /** @brief Frequency range that the LED can operate on.
102      *  Will be removed when frequency is put into interface
103      */
104     uint32_t frequency;
105 
106     /** @brief Brightness described above */
107     std::string brightCtrl;
108 
109     /** @brief BlinkCtrl described above */
110     std::string blinkCtrl;
111 
112     /** @brief delay_on described above */
113     std::string delayOnCtrl;
114 
115     /** @brief delay_ff described above */
116     std::string delayOffCtrl;
117 
118     /** @brief reads sysfs and then setsup the parameteres accordingly
119      *
120      *  @return None
121      */
122     void setInitialState();
123 
124     /** @brief Applies the user triggered action on the LED
125      *   by writing to sysfs
126      *
127      *  @param [in] current - Current state of LED
128      *  @param [in] request - Requested state
129      *
130      *  @return None
131      */
132     void driveLED(Action current, Action request);
133 
134     /** @brief Sets the LED to either ON or OFF state
135      *
136      *  @param [in] action - Requested action. Could be OFF or ON
137      *  @return None
138      */
139     void stableStateOperation(Action action);
140 
141     /** @brief Sets the LED to BLINKING
142      *
143      *  @return None
144      */
145     void blinkOperation();
146 
147     /** @brief Generic file writer.
148      *   There are files like "brightness", "trigger" , "delay_on" and
149      *   "delay_off" that will tell what the LED driver needs to do.
150      *
151      *  @param[in] filename - Name of file to be written
152      *  @param[in] data     - Data to be written to
153      *  @return             - None
154      */
155     template <typename T>
156     auto write(const std::string& fileName, T&& data)
157     {
158         if (std::ifstream(fileName))
159         {
160             std::ofstream file(fileName, std::ios::out);
161             file << data;
162             file.close();
163         }
164         return;
165     }
166 
167     /** @brief Generic file reader.
168      *   There are files like "brightness", "trigger" , "delay_on" and
169      *   "delay_off" that will tell what the LED driver needs to do.
170      *
171      *  @param[in] filename - Name of file to be read
172      *  @return             - File content
173      */
174     template <typename T>
175     T read(const std::string& fileName)
176     {
177         T data = T();
178         if (std::ifstream(fileName))
179         {
180             std::ifstream file(fileName, std::ios::in);
181             file >> data;
182             file.close();
183         }
184         return data;
185     }
186 };
187 
188 } // namespace led
189 } // namespace phosphor
190