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