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