summaryrefslogtreecommitdiffstats
path: root/monitor.hpp
blob: 771492a9ec9aa00b038c8152584cb0a6f9ba421d (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
#pragma once

#include "evdev.hpp"

#include <linux/input.h>
#include <systemd/sd-event.h>
#include <unistd.h>

#include <sdbusplus/bus.hpp>
#include <string>

namespace phosphor
{
namespace gpio
{

/** @class Monitor
 *  @brief Responsible for catching GPIO state change
 *  condition and starting systemd targets.
 */
class Monitor : public Evdev
{
  public:
    Monitor() = delete;
    ~Monitor() = default;
    Monitor(const Monitor&) = delete;
    Monitor& operator=(const Monitor&) = delete;
    Monitor(Monitor&&) = delete;
    Monitor& operator=(Monitor&&) = delete;

    /** @brief Constructs Monitor object.
     *
     *  @param[in] path     - Path to gpio input device
     *  @param[in] key      - GPIO key to monitor
     *  @param[in] polarity - GPIO assertion polarity to look for
     *  @param[in] target   - systemd unit to be started on GPIO
     *                        value change
     *  @param[in] event    - sd_event handler
     *  @param[in] continueRun - Whether to continue after key pressed
     *  @param[in] handler  - IO callback handler. Defaults to one in this
     *                        class
     *  @param[in] useEvDev - Whether to use EvDev to retrieve events
     */
    Monitor(const std::string& path, decltype(input_event::code) key,
            decltype(input_event::value) polarity, const std::string& target,
            EventPtr& event, bool continueRun,
            sd_event_io_handler_t handler = Monitor::processEvents,
            bool useEvDev = true) :
        Evdev(path, key, event, handler, useEvDev),
        polarity(polarity), target(target),
        continueAfterKeyPress(continueRun){};

    /** @brief Callback handler when the FD has some activity on it
     *
     *  @param[in] es       - Populated event source
     *  @param[in] fd       - Associated File descriptor
     *  @param[in] revents  - Type of event
     *  @param[in] userData - User data that was passed during registration
     *
     *  @return             - 0 or positive number on success and negative
     *                        errno otherwise
     */
    static int processEvents(sd_event_source* es, int fd, uint32_t revents,
                             void* userData);

    /** @brief Returns the completion state of this handler */
    inline auto completed() const
    {
        return complete;
    }

  private:
    /** @brief GPIO key value that is of interest */
    decltype(input_event::value) polarity;

    /** @brief Systemd unit to be started when the condition is met */
    const std::string& target;

    /** @brief If the monitor should continue after key press */
    bool continueAfterKeyPress;

    /** @brief Completion indicator */
    bool complete = false;

    /** @brief Analyzes the GPIO event and starts configured target */
    void analyzeEvent();
};

} // namespace gpio
} // namespace phosphor
OpenPOWER on IntegriCloud