summaryrefslogtreecommitdiffstats
path: root/mainloop.hpp
blob: 4f7293d05dbbaf0a3ea6cb96e637356965f6384a (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
#pragma once

#include "hwmonio.hpp"
#include "interface.hpp"
#include "sensor.hpp"
#include "sensorset.hpp"
#include "sysfs.hpp"
#include "types.hpp"

#include <any>
#include <memory>
#include <optional>
#include <sdbusplus/server.hpp>
#include <sdeventplus/clock.hpp>
#include <sdeventplus/event.hpp>
#include <sdeventplus/utility/timer.hpp>
#include <string>
#include <vector>

static constexpr auto default_interval = 1000000;

static constexpr auto sensorID = 0;
static constexpr auto sensorLabel = 1;
using SensorIdentifiers = std::tuple<std::string, std::string>;

/** @class MainLoop
 *  @brief hwmon-readd main application loop.
 */
class MainLoop
{
  public:
    MainLoop() = delete;
    MainLoop(const MainLoop&) = delete;
    MainLoop& operator=(const MainLoop&) = delete;
    MainLoop(MainLoop&&) = delete;
    MainLoop& operator=(MainLoop&&) = delete;
    ~MainLoop() = default;

    /** @brief Constructor
     *
     *  @param[in] bus - sdbusplus bus client connection.
     *  @param[in] param - the path parameter provided
     *  @param[in] path - hwmon sysfs instance to manage
     *  @param[in] devPath - physical device sysfs path.
     *  @param[in] prefix - DBus busname prefix.
     *  @param[in] root - DBus sensors namespace root.
     *
     *  Any DBus objects are created relative to the DBus
     *  sensors namespace root.
     *
     *  At startup, the application will own a busname with
     *  the format <prefix>.hwmon<n>.
     */
    MainLoop(sdbusplus::bus::bus&& bus, const std::string& param,
             const std::string& path, const std::string& devPath,
             const char* prefix, const char* root);

    /** @brief Setup polling timer in a sd event loop and attach to D-Bus
     *         event loop.
     */
    void run();

    /** @brief Stop polling timer event loop from another thread.
     *
     *  Typically only used by testcases.
     */
    void shutdown() noexcept;

  private:
    using mapped_type =
        std::tuple<SensorSet::mapped_type, std::string, ObjectInfo>;
    using SensorState = std::map<SensorSet::key_type, mapped_type>;

    /** @brief Read hwmon sysfs entries */
    void read();

    /** @brief Set up D-Bus object state */
    void init();

    /** @brief sdbusplus bus client connection. */
    sdbusplus::bus::bus _bus;
    /** @brief sdbusplus freedesktop.ObjectManager storage. */
    sdbusplus::server::manager::manager _manager;
    /** @brief the parameter path used. */
    std::string _pathParam;
    /** @brief hwmon sysfs class path. */
    std::string _hwmonRoot;
    /** @brief hwmon sysfs instance. */
    std::string _instance;
    /** @brief physical device sysfs path. */
    std::string _devPath;
    /** @brief DBus busname prefix. */
    const char* _prefix;
    /** @brief DBus sensors namespace root. */
    const char* _root;
    /** @brief DBus object state. */
    SensorState _state;
    /** @brief Sleep interval in microseconds. */
    uint64_t _interval = default_interval;
    /** @brief Hwmon sysfs access. */
    hwmonio::HwmonIO _ioAccess;
    /** @brief the Event Loop structure */
    sdeventplus::Event _event;
    /** @brief Read Timer */
    sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> _timer;
    /** @brief Store the specifications of sensor objects */
    std::map<SensorSet::key_type, std::unique_ptr<sensor::Sensor>>
        _sensorObjects;

    /**
     * @brief Map of removed sensors
     */
    std::map<SensorSet::key_type, SensorSet::mapped_type> _rmSensors;

    /**
     * @brief Get the ID of the sensor
     *
     * @param[in] sensor - Sensor to get the ID of
     */
    std::string getID(SensorSet::container_t::const_reference sensor);

    /**
     * @brief Get the sensor identifiers
     *
     * @param[in] sensor - Sensor to get the identifiers of
     */
    SensorIdentifiers
        getIdentifiers(SensorSet::container_t::const_reference sensor);

    /**
     * @brief Used to create and add sensor objects
     *
     * @param[in] sensor - Sensor to create/add object for
     *
     * @return - Optional
     *     Object state data on success, nothing on failure
     */
    std::optional<ObjectStateData>
        getObject(SensorSet::container_t::const_reference sensor);
};
OpenPOWER on IntegriCloud