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