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