xref: /openbmc/phosphor-hwmon/mainloop.hpp (revision 043d32306e00484afc446a44789b61869ea14f84)
1 #pragma once
2 
3 #include "hwmonio.hpp"
4 #include "interface.hpp"
5 #include "sensor.hpp"
6 #include "sensorset.hpp"
7 #include "sysfs.hpp"
8 #include "timer.hpp"
9 #include "types.hpp"
10 
11 #include <experimental/any>
12 #include <experimental/optional>
13 #include <memory>
14 #include <sdbusplus/server.hpp>
15 #include <string>
16 #include <vector>
17 
18 static constexpr auto default_interval = 1000000;
19 
20 static constexpr auto sensorID = 0;
21 static constexpr auto sensorLabel = 1;
22 using SensorIdentifiers = std::tuple<std::string, std::string>;
23 
24 namespace optional_ns = std::experimental;
25 
26 /** @class MainLoop
27  *  @brief hwmon-readd main application loop.
28  */
29 class MainLoop
30 {
31   public:
32     MainLoop() = delete;
33     MainLoop(const MainLoop&) = delete;
34     MainLoop& operator=(const MainLoop&) = delete;
35     MainLoop(MainLoop&&) = default;
36     MainLoop& operator=(MainLoop&&) = default;
37     ~MainLoop() = default;
38 
39     /** @brief Constructor
40      *
41      *  @param[in] bus - sdbusplus bus client connection.
42      *  @param[in] param - the path parameter provided
43      *  @param[in] path - hwmon sysfs instance to manage
44      *  @param[in] devPath - physical device sysfs path.
45      *  @param[in] prefix - DBus busname prefix.
46      *  @param[in] root - DBus sensors namespace root.
47      *
48      *  Any DBus objects are created relative to the DBus
49      *  sensors namespace root.
50      *
51      *  At startup, the application will own a busname with
52      *  the format <prefix>.hwmon<n>.
53      */
54     MainLoop(sdbusplus::bus::bus&& bus, const std::string& param,
55              const std::string& path, const std::string& devPath,
56              const char* prefix, 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 =
71         std::tuple<SensorSet::mapped_type, std::string, ObjectInfo>;
72     using SensorState = std::map<SensorSet::key_type, mapped_type>;
73 
74     /** @brief Read hwmon sysfs entries */
75     void read();
76 
77     /** @brief Set up D-Bus object state */
78     void init();
79 
80     /** @brief sdbusplus bus client connection. */
81     sdbusplus::bus::bus _bus;
82     /** @brief sdbusplus freedesktop.ObjectManager storage. */
83     sdbusplus::server::manager::manager _manager;
84     /** @brief the parameter path used. */
85     std::string _pathParam;
86     /** @brief hwmon sysfs class path. */
87     std::string _hwmonRoot;
88     /** @brief hwmon sysfs instance. */
89     std::string _instance;
90     /** @brief physical device sysfs path. */
91     std::string _devPath;
92     /** @brief DBus busname prefix. */
93     const char* _prefix;
94     /** @brief DBus sensors namespace root. */
95     const char* _root;
96     /** @brief DBus object state. */
97     SensorState state;
98     /** @brief Sleep interval in microseconds. */
99     uint64_t _interval = default_interval;
100     /** @brief Hwmon sysfs access. */
101     hwmonio::HwmonIO ioAccess;
102     /** @brief Timer */
103     std::unique_ptr<phosphor::hwmon::Timer> timer;
104     /** @brief the sd_event structure */
105     sd_event* loop = nullptr;
106     /** @brief Store the specifications of sensor objects */
107     std::map<SensorSet::key_type, std::unique_ptr<sensor::Sensor>>
108         sensorObjects;
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
128         getIdentifiers(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>
139         getObject(SensorSet::container_t::const_reference sensor);
140 };
141