summaryrefslogtreecommitdiffstats
path: root/physical.hpp
blob: 36fbedcdb9ef4b3c5edff4a6b42fbe666bd8e7df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#pragma once

#include <string>
#include <fstream>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/object.hpp>
#include <xyz/openbmc_project/Led/Physical/server.hpp>
namespace phosphor
{
namespace led
{
/** @brief Acts as input and output file for the current LED power state.
 *   Write "0" to trigger a LED OFF operation.
 *   Write "255" to trigger a LED ON operation.
 *   To know the current power state of the LED, a read on this
 *   would give either 0 or 255 indicating if the LED is currently
 *   Off / On AT THAT moment.
 *   Example: /sys/class/leds/myled/brightness
 */
constexpr auto BRIGHTNESS = "/brightness";

/** @brief Assert LED by writing 255 */
constexpr auto ASSERT = "255";

/** @brief De-assert by writing "0" */
constexpr auto DEASSERT = "0";

/** @brief Write "timer" to this file telling the driver that
 *   the intended operation is BLINK. When the value "timer" is written to
 *   the file, 2 more files get auto generated and are named "delay_on" and
 *   "delay_off"
 *   To move away from blinking, write "none"
 *   Example:  /sys/class/leds/myled/trigger
 */
constexpr auto BLINKCTRL = "/trigger";

/** @brief write number of milliseconds that the LED needs to be ON
 *   while blinking. Default is 500 by the driver.
 *   Example:  /sys/class/leds/myled/delay_on
 */
constexpr auto DELAYON = "/delay_on";

/** @brief Write number of milliseconds that the LED needs to be OFF
 *   while blinking. Default is 500 by the driver.
 *   Example:  /sys/class/leds/myled/delay_off
 */
constexpr auto DELAYOFF = "/delay_off";

/** @class Physical
 *  @brief Responsible for applying actions on a particular physical LED
 */
class Physical : public sdbusplus::server::object::object<
    sdbusplus::xyz::openbmc_project::Led::server::Physical>
{
    public:
        Physical() = delete;
        ~Physical() = default;
        Physical(const Physical&) = delete;
        Physical& operator=(const Physical&) = delete;
        Physical(Physical&&) = delete;
        Physical& operator=(Physical&&) = delete;

        /** @brief Constructs LED object. Argument 'true' says that we hold off
         *   from sending the signals since we need to do some house keeping and
         *   only when we finish that, we are considered active and can then
         *   broadcast the signal.
         *
         * @param[in] bus       - system dbus handler
         * @param[in] objPath   - The Dbus path that hosts physical LED
         * @param[in] ledPath   - sysfs path where this LED is exported
         */
        Physical(sdbusplus::bus::bus& bus,
                const std::string& objPath,
                const std::string& ledPath) :

            sdbusplus::server::object::object<
                sdbusplus::xyz::openbmc_project::Led::server::Physical>(
                        bus, objPath.c_str(), true),
            path(ledPath)
        {
            // Suppose this is getting launched as part of BMC reboot, then we
            // need to save what the micro-controller currently has.
            setInitialState();

            // We are now ready.
            emit_object_added();
        }

        /** @brief Overloaded State Property Setter function
         *
         *  @param[in] value   -  One of OFF / ON / BLINK
         *  @return            -  Success or exception thrown
         */
        Action state(Action value) override;

    private:
        /** @brief File system location where this LED is exposed
         *   Typically /sys/class/leds/<Led-Name>
         */
        std::string path;

        /** @brief Frequency range that the LED can operate on.
         *  Will be removed when frequency is put into interface
         */
        uint32_t frequency;

        /** @brief Brightness described above */
        std::string brightCtrl;

        /** @brief BlinkCtrl described above */
        std::string blinkCtrl;

        /** @brief delay_on described above */
        std::string delayOnCtrl;

        /** @brief delay_ff described above */
        std::string delayOffCtrl;

        /** @brief reads sysfs and then setsup the parameteres accordingly
         *
         *  @return None
         */
        void setInitialState();

        /** @brief Applies the user triggered action on the LED
         *   by writing to sysfs
         *
         *  @param [in] current - Current state of LED
         *  @param [in] request - Requested state
         *
         *  @return None
         */
        void driveLED(Action current, Action request);

        /** @brief Sets the LED to either ON or OFF state
         *
         *  @param [in] action - Requested action. Could be OFF or ON
         *  @return None
         */
        void stableStateOperation(Action action);

        /** @brief Sets the LED to BLINKING
         *
         *  @return None
         */
        void blinkOperation();

        /** @brief Generic file writer.
         *   There are files like "brightness", "trigger" , "delay_on" and
         *   "delay_off" that will tell what the LED driver needs to do.
         *
         *  @param[in] filename - Name of file to be written
         *  @param[in] data     - Data to be written to
         *  @return             - None
         */
        template <typename T>
        auto write(const std::string& fileName, T&& data)
        {
            if(std::ifstream(fileName))
            {
                std::ofstream file(fileName, std::ios::out);
                file << data;
                file.close();
            }
            return;
        }

        /** @brief Generic file reader.
         *   There are files like "brightness", "trigger" , "delay_on" and
         *   "delay_off" that will tell what the LED driver needs to do.
         *
         *  @param[in] filename - Name of file to be read
         *  @return             - File content
         */
        template <typename T>
        T read(const std::string& fileName)
        {
            T data = T();
            if(std::ifstream(fileName))
            {
                std::ifstream file(fileName, std::ios::in);
                file >> data;
                file.close();
            }
            return data;
        }
};

} // namespace led
}
OpenPOWER on IntegriCloud