xref: /openbmc/phosphor-hwmon/mainloop.hpp (revision 47fb49ac)
1 #pragma once
2 
3 #include "average.hpp"
4 #include "hwmonio.hpp"
5 #include "interface.hpp"
6 #include "sensor.hpp"
7 #include "sensorset.hpp"
8 #include "sysfs.hpp"
9 #include "types.hpp"
10 
11 #include <sdbusplus/server.hpp>
12 #include <sdeventplus/clock.hpp>
13 #include <sdeventplus/event.hpp>
14 #include <sdeventplus/utility/timer.hpp>
15 
16 #include <any>
17 #include <future>
18 #include <memory>
19 #include <optional>
20 #include <string>
21 #include <vector>
22 
23 static constexpr auto default_interval = 1000000;
24 
25 static constexpr auto sensorID = 0;
26 static constexpr auto sensorLabel = 1;
27 static constexpr auto sensorAccuracy = 2;
28 static constexpr auto sensorPriority = 3;
29 using SensorIdentifiers =
30     std::tuple<std::string, std::string, std::string, std::string>;
31 
32 /** @class MainLoop
33  *  @brief hwmon-readd main application loop.
34  */
35 class MainLoop
36 {
37   public:
38     MainLoop() = delete;
39     MainLoop(const MainLoop&) = delete;
40     MainLoop& operator=(const MainLoop&) = delete;
41     MainLoop(MainLoop&&) = delete;
42     MainLoop& operator=(MainLoop&&) = delete;
43     ~MainLoop() = default;
44 
45     /** @brief Constructor
46      *
47      *  @param[in] bus - sdbusplus bus client connection.
48      *  @param[in] param - the path parameter provided
49      *  @param[in] path - hwmon sysfs instance to manage
50      *  @param[in] devPath - physical device sysfs path.
51      *  @param[in] prefix - DBus busname prefix.
52      *  @param[in] root - DBus sensors namespace root.
53      *  @param[in] instanceId - override value to identify instance on d-bus.
54      *
55      *  Any DBus objects are created relative to the DBus
56      *  sensors namespace root.
57      *
58      *  At startup, the application will own a busname with
59      *  the format <prefix>.hwmon<n>.
60      */
61     MainLoop(sdbusplus::bus_t&& bus, const std::string& param,
62              const std::string& path, const std::string& devPath,
63              const char* prefix, const char* root,
64              const std::string& instanceId,
65              const hwmonio::HwmonIOInterface* ioIntf);
66 
67     /** @brief Setup polling timer in a sd event loop and attach to D-Bus
68      *         event loop.
69      */
70     void run();
71 
72     /** @brief Stop polling timer event loop from another thread.
73      *
74      *  Typically only used by testcases.
75      */
76     void shutdown() noexcept;
77 
78     /** @brief Remove sensors slated for removal.
79      */
80     void removeSensors();
81 
82     /** @brief Attempt to add sensors back that had been removed.
83      */
84     void addDroppedSensors();
85 
86   private:
87     using mapped_type =
88         std::tuple<SensorSet::mapped_type, std::string, ObjectInfo>;
89     using SensorState = std::map<SensorSet::key_type, mapped_type>;
90 
91     /** @brief Read hwmon sysfs entries */
92     void read();
93 
94     /** @brief Set up D-Bus object state */
95     void init();
96 
97     /** @brief sdbusplus bus client connection. */
98     sdbusplus::bus_t _bus;
99     /** @brief sdbusplus freedesktop.ObjectManager storage. */
100     sdbusplus::server::manager_t _manager;
101     /** @brief the parameter path used. */
102     std::string _pathParam;
103     /** @brief hwmon sysfs class path. */
104     std::string _hwmonRoot;
105     /** @brief hwmon sysfs instance. */
106     std::string _instance;
107     /** @brief physical device sysfs path. */
108     std::string _devPath;
109     /** @brief DBus busname prefix. */
110     const char* _prefix;
111     /** @brief DBus sensors namespace root. */
112     const char* _root;
113     /** @brief DBus object state. */
114     SensorState _state;
115     /** @brief DBus instance id specified by command line. */
116     std::string _instanceId;
117     /** @brief Sleep interval in microseconds. */
118     uint64_t _interval = default_interval;
119     /** @brief Hwmon sysfs access. */
120     const hwmonio::HwmonIOInterface* _ioAccess;
121     /** @brief the Event Loop structure */
122     sdeventplus::Event _event;
123     /** @brief Read Timer */
124     sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> _timer;
125     /** @brief Store the specifications of sensor objects */
126     std::map<SensorSet::key_type, std::unique_ptr<sensor::Sensor>>
127         _sensorObjects;
128     /** @brief Store the async futures of timed out sensor objects */
129     sensor::TimedoutMap _timedoutMap;
130 
131     /**
132      * @brief Map of removed sensors
133      */
134     std::map<SensorSet::key_type, SensorSet::mapped_type> _rmSensors;
135 
136     /** @brief Object of class Average, to handle with average related process
137      */
138     Average _average;
139 
140     /**
141      * @brief Get the ID of the sensor
142      *
143      * @param[in] sensor - Sensor to get the ID of
144      */
145     std::string getID(SensorSet::container_t::const_reference sensor);
146 
147     /**
148      * @brief Get the sensor identifiers
149      *
150      * @param[in] sensor - Sensor to get the identifiers of
151      */
152     SensorIdentifiers
153         getIdentifiers(SensorSet::container_t::const_reference sensor);
154 
155     /**
156      * @brief Used to create and add sensor objects
157      *
158      * @param[in] sensor - Sensor to create/add object for
159      *
160      * @return - Optional
161      *     Object state data on success, nothing on failure
162      */
163     std::optional<ObjectStateData>
164         getObject(SensorSet::container_t::const_reference sensor);
165 };
166 
167 /** @brief Given a value and map of interfaces, update values and check
168  * thresholds.
169  */
170 void updateSensorInterfaces(InterfaceMap& ifaces, SensorValueType value);
171