xref: /openbmc/dbus-sensors/src/fan/TachSensor.hpp (revision 18b6186e531ae37dd22b634c6530f793528473f4)
1d7be555eSGeorge Liu #pragma once
2d7be555eSGeorge Liu 
3d7be555eSGeorge Liu #include "PresenceGpio.hpp"
4d7be555eSGeorge Liu #include "Thresholds.hpp"
5*18b6186eSEd Tanous #include "Utils.hpp"
6d7be555eSGeorge Liu #include "sensor.hpp"
7d7be555eSGeorge Liu 
8*18b6186eSEd Tanous #include <boost/asio/io_context.hpp>
9d7be555eSGeorge Liu #include <boost/asio/random_access_file.hpp>
10*18b6186eSEd Tanous #include <boost/asio/steady_timer.hpp>
11d7be555eSGeorge Liu #include <boost/container/flat_map.hpp>
12d7be555eSGeorge Liu #include <phosphor-logging/lg2.hpp>
13*18b6186eSEd Tanous #include <sdbusplus/asio/connection.hpp>
14d7be555eSGeorge Liu #include <sdbusplus/asio/object_server.hpp>
15d7be555eSGeorge Liu 
16*18b6186eSEd Tanous #include <array>
17*18b6186eSEd Tanous #include <cstddef>
18d7be555eSGeorge Liu #include <memory>
19d7be555eSGeorge Liu #include <optional>
20d7be555eSGeorge Liu #include <string>
21d7be555eSGeorge Liu #include <utility>
22d7be555eSGeorge Liu #include <vector>
23d7be555eSGeorge Liu 
24d7be555eSGeorge Liu namespace redundancy
25d7be555eSGeorge Liu {
26d7be555eSGeorge Liu constexpr const char* full = "Full";
27d7be555eSGeorge Liu constexpr const char* degraded = "Degraded";
28d7be555eSGeorge Liu constexpr const char* failed = "Failed";
29d7be555eSGeorge Liu } // namespace redundancy
30d7be555eSGeorge Liu 
31d7be555eSGeorge Liu class RedundancySensor
32d7be555eSGeorge Liu {
33d7be555eSGeorge Liu   public:
34d7be555eSGeorge Liu     RedundancySensor(size_t count, const std::vector<std::string>& children,
35d7be555eSGeorge Liu                      sdbusplus::asio::object_server& objectServer,
36d7be555eSGeorge Liu                      const std::string& sensorConfiguration);
37d7be555eSGeorge Liu     ~RedundancySensor();
38d7be555eSGeorge Liu 
39d7be555eSGeorge Liu     void update(const std::string& name, bool failed);
40d7be555eSGeorge Liu 
41d7be555eSGeorge Liu   private:
42d7be555eSGeorge Liu     size_t count;
43d7be555eSGeorge Liu     std::string state = redundancy::full;
44d7be555eSGeorge Liu     std::shared_ptr<sdbusplus::asio::dbus_interface> iface;
45d7be555eSGeorge Liu     std::shared_ptr<sdbusplus::asio::dbus_interface> association;
46d7be555eSGeorge Liu     sdbusplus::asio::object_server& objectServer;
47d7be555eSGeorge Liu     boost::container::flat_map<std::string, bool> statuses;
48d7be555eSGeorge Liu 
logFanRedundancyLost()49d7be555eSGeorge Liu     static void logFanRedundancyLost()
50d7be555eSGeorge Liu     {
51d7be555eSGeorge Liu         const auto* msg = "OpenBMC.0.1.FanRedundancyLost";
52d7be555eSGeorge Liu         lg2::error("Fan Inserted", "REDFISH_MESSAGE_ID", msg);
53d7be555eSGeorge Liu     }
54d7be555eSGeorge Liu 
logFanRedundancyRestored()55d7be555eSGeorge Liu     static void logFanRedundancyRestored()
56d7be555eSGeorge Liu     {
57d7be555eSGeorge Liu         const auto* msg = "OpenBMC.0.1.FanRedundancyRegained";
58d7be555eSGeorge Liu         lg2::error("Fan Removed", "REDFISH_MESSAGE_ID", msg);
59d7be555eSGeorge Liu     }
60d7be555eSGeorge Liu };
61d7be555eSGeorge Liu 
62d7be555eSGeorge Liu class TachSensor :
63d7be555eSGeorge Liu     public Sensor,
64d7be555eSGeorge Liu     public std::enable_shared_from_this<TachSensor>
65d7be555eSGeorge Liu {
66d7be555eSGeorge Liu   public:
67d7be555eSGeorge Liu     TachSensor(const std::string& path, const std::string& objectType,
68d7be555eSGeorge Liu                sdbusplus::asio::object_server& objectServer,
69d7be555eSGeorge Liu                std::shared_ptr<sdbusplus::asio::connection>& conn,
70d7be555eSGeorge Liu                std::shared_ptr<PresenceGpio>& presence,
71d7be555eSGeorge Liu                std::optional<RedundancySensor>* redundancy,
72d7be555eSGeorge Liu                boost::asio::io_context& io, const std::string& fanName,
73d7be555eSGeorge Liu                std::vector<thresholds::Threshold>&& thresholds,
74d7be555eSGeorge Liu                const std::string& sensorConfiguration,
75d7be555eSGeorge Liu                const std::pair<double, double>& limits,
76d7be555eSGeorge Liu                const PowerState& powerState,
77d7be555eSGeorge Liu                const std::optional<std::string>& led);
78d7be555eSGeorge Liu     ~TachSensor() override;
79d7be555eSGeorge Liu     void setupRead();
80d7be555eSGeorge Liu 
81d7be555eSGeorge Liu   private:
82d7be555eSGeorge Liu     // Ordering is important here; readBuf is first so that it's not destroyed
83d7be555eSGeorge Liu     // while async operations from other member fields might still be using it.
84d7be555eSGeorge Liu     std::array<char, 128> readBuf{};
85d7be555eSGeorge Liu     sdbusplus::asio::object_server& objServer;
86d7be555eSGeorge Liu     std::optional<RedundancySensor>* redundancy;
87d7be555eSGeorge Liu     std::shared_ptr<PresenceGpio> presence;
88d7be555eSGeorge Liu     std::shared_ptr<sdbusplus::asio::dbus_interface> itemIface;
89d7be555eSGeorge Liu     std::shared_ptr<sdbusplus::asio::dbus_interface> itemAssoc;
90d7be555eSGeorge Liu     boost::asio::random_access_file inputDev;
91d7be555eSGeorge Liu     boost::asio::steady_timer waitTimer;
92d7be555eSGeorge Liu     std::string path;
93d7be555eSGeorge Liu     std::optional<std::string> led;
94d7be555eSGeorge Liu     bool ledState = false;
95d7be555eSGeorge Liu 
96d7be555eSGeorge Liu     void handleResponse(const boost::system::error_code& err, size_t bytesRead);
97d7be555eSGeorge Liu     void restartRead(size_t pollTime);
98d7be555eSGeorge Liu     void checkThresholds() override;
99d7be555eSGeorge Liu };
100