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