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