xref: /openbmc/phosphor-hwmon/mainloop.hpp (revision 9c43106c5e71e9cc9d8778d92c7b6377e6926d7a)
1 #pragma once
2 
3 #include <string>
4 #include <vector>
5 #include <experimental/any>
6 #include <experimental/optional>
7 #include <memory>
8 #include <sdbusplus/server.hpp>
9 #include "types.hpp"
10 #include "hwmonio.hpp"
11 #include "sensorset.hpp"
12 #include "sysfs.hpp"
13 #include "interface.hpp"
14 #include "timer.hpp"
15 #include "sensor.hpp"
16 
17 static constexpr auto default_interval = 1000000;
18 
19 static constexpr auto sensorID = 0;
20 static constexpr auto sensorLabel = 1;
21 using SensorIdentifiers = std::tuple<std::string, std::string>;
22 
23 namespace optional_ns = std::experimental;
24 
25 /** @class MainLoop
26  *  @brief hwmon-readd main application loop.
27  */
28 class MainLoop
29 {
30     public:
31         MainLoop() = delete;
32         MainLoop(const MainLoop&) = delete;
33         MainLoop& operator=(const MainLoop&) = delete;
34         MainLoop(MainLoop&&) = default;
35         MainLoop& operator=(MainLoop&&) = default;
36         ~MainLoop() = default;
37 
38         /** @brief Constructor
39          *
40          *  @param[in] bus - sdbusplus bus client connection.
41          *  @param[in] param - the path parameter provided
42          *  @param[in] path - hwmon sysfs instance to manage
43          *  @param[in] devPath - physical device sysfs path.
44          *  @param[in] prefix - DBus busname prefix.
45          *  @param[in] root - DBus sensors namespace root.
46          *
47          *  Any DBus objects are created relative to the DBus
48          *  sensors namespace root.
49          *
50          *  At startup, the application will own a busname with
51          *  the format <prefix>.hwmon<n>.
52          */
53         MainLoop(
54             sdbusplus::bus::bus&& bus,
55             const std::string& param,
56             const std::string& path,
57             const std::string& devPath,
58             const char* prefix,
59             const char* root);
60 
61         /** @brief Setup polling timer in a sd event loop and attach to D-Bus
62          *         event loop.
63          */
64         void run();
65 
66         /** @brief Stop polling timer event loop from another thread.
67          *
68          *  Typically only used by testcases.
69          */
70         void shutdown() noexcept;
71 
72     private:
73         using mapped_type = std::tuple<SensorSet::mapped_type, std::string, ObjectInfo>;
74         using SensorState = std::map<SensorSet::key_type, mapped_type>;
75 
76         /** @brief Read hwmon sysfs entries */
77         void read();
78 
79         /** @brief Set up D-Bus object state */
80         void init();
81 
82         /** @brief sdbusplus bus client connection. */
83         sdbusplus::bus::bus _bus;
84         /** @brief sdbusplus freedesktop.ObjectManager storage. */
85         sdbusplus::server::manager::manager _manager;
86         /** @brief the parameter path used. */
87         std::string _pathParam;
88         /** @brief hwmon sysfs class path. */
89         std::string _hwmonRoot;
90         /** @brief hwmon sysfs instance. */
91         std::string _instance;
92         /** @brief physical device sysfs path. */
93         std::string _devPath;
94         /** @brief DBus busname prefix. */
95         const char* _prefix;
96         /** @brief DBus sensors namespace root. */
97         const char* _root;
98         /** @brief DBus object state. */
99         SensorState state;
100         /** @brief Sleep interval in microseconds. */
101         uint64_t _interval = default_interval;
102         /** @brief Hwmon sysfs access. */
103         hwmonio::HwmonIO ioAccess;
104         /** @brief Timer */
105         std::unique_ptr<phosphor::hwmon::Timer> timer;
106         /** @brief the sd_event structure */
107         sd_event* loop = nullptr;
108         /** @brief Store the specifications of sensor objects */
109         std::map<SensorSet::key_type,
110                  std::unique_ptr<sensor::Sensor>> sensorObjects;
111 
112         /**
113          * @brief Map of removed sensors
114          */
115         std::map<SensorSet::key_type, SensorSet::mapped_type> rmSensors;
116 
117         /**
118          * @brief Get the ID of the sensor
119          *
120          * @param[in] sensor - Sensor to get the ID of
121          */
122         std::string getID(SensorSet::container_t::const_reference sensor);
123 
124         /**
125          * @brief Get the sensor identifiers
126          *
127          * @param[in] sensor - Sensor to get the identifiers of
128          */
129         SensorIdentifiers getIdentifiers(
130                 SensorSet::container_t::const_reference sensor);
131 
132         /**
133          * @brief Used to create and add sensor objects
134          *
135          * @param[in] sensor - Sensor to create/add object for
136          *
137          * @return - Optional
138          *     Object state data on success, nothing on failure
139          */
140         optional_ns::optional<ObjectStateData> getObject(
141                 SensorSet::container_t::const_reference sensor);
142 };
143