1 #pragma once
2 
3 #include "error_reporter.hpp"
4 #include "fan.hpp"
5 #include "psensor.hpp"
6 #include "rpolicy.hpp"
7 
8 #include <nlohmann/json.hpp>
9 #include <sdbusplus/bus.hpp>
10 #include <sdeventplus/source/signal.hpp>
11 
12 #include <filesystem>
13 #include <memory>
14 #include <string>
15 #include <vector>
16 
17 namespace phosphor
18 {
19 namespace fan
20 {
21 namespace presence
22 {
23 
24 namespace fs = std::filesystem;
25 using json = nlohmann::json;
26 
27 constexpr auto confFileName = "config.json";
28 constexpr auto confAppName = "presence";
29 
30 using policies = std::vector<std::unique_ptr<RedundancyPolicy>>;
31 
32 constexpr auto fanPolicyFanPos = 0;
33 constexpr auto fanPolicySensorListPos = 1;
34 using fanPolicy = std::tuple<Fan, std::vector<std::unique_ptr<PresenceSensor>>>;
35 
36 // Presence method handler function
37 using methodHandler =
38     std::function<std::unique_ptr<PresenceSensor>(size_t, const json&)>;
39 // Presence redundancy policy handler function
40 using rpolicyHandler = std::function<std::unique_ptr<RedundancyPolicy>(
41     const fanPolicy&, std::unique_ptr<EEPROMDevice>)>;
42 
43 class JsonConfig
44 {
45   public:
46     JsonConfig() = delete;
47     JsonConfig(const JsonConfig&) = delete;
48     JsonConfig(JsonConfig&&) = delete;
49     JsonConfig& operator=(const JsonConfig&) = delete;
50     JsonConfig& operator=(JsonConfig&&) = delete;
51     ~JsonConfig() = default;
52 
53     /**
54      * Constructor
55      *
56      * @param[in] bus - sdbusplus bus object
57      */
58     explicit JsonConfig(sdbusplus::bus_t& bus);
59 
60     /**
61      * @brief Get the json config based fan presence policies
62      *
63      * @return - The fan presence policies
64      */
65     static const policies& get();
66 
67     /**
68      * @brief Callback function to handle receiving a HUP signal to
69      * reload the json configuration.
70      *
71      * @param[in] sigSrc - sd_event_source signal wrapper
72      * @param[in] sigInfo - signal info on signal fd
73      */
74     void sighupHandler(sdeventplus::source::Signal& /*sigSrc*/,
75                        const struct signalfd_siginfo* /*sigInfo*/);
76 
77     /**
78      * @brief Parses and populates the fan presence policies from
79      *        the json file and then starts the actual presence
80      *        detecting.
81      */
82     void start();
83 
84   private:
85     /* Fan presence policies */
86     static policies _policies;
87 
88     /* The sdbusplus bus object */
89     sdbusplus::bus_t& _bus;
90 
91     /* List of Fan objects to have presence policies */
92     std::vector<fanPolicy> _fans;
93 
94     /* Presence methods mapping to their associated handler function */
95     static const std::map<std::string, methodHandler> _methods;
96 
97     /**
98      * Presence redundancy policy mapping to their associated handler
99      * function
100      */
101     static const std::map<std::string, rpolicyHandler> _rpolicies;
102 
103     /**
104      * Class that handles reporting errors for missing fans.
105      */
106     std::unique_ptr<ErrorReporter> _reporter;
107 
108     /**
109      * Tracks if the config has already been loaded.
110      */
111     bool _loaded = false;
112 
113     /**
114      * @brief Process the json config to extract the defined fan presence
115      * policies.
116      *
117      * @param[in] jsonConf - parsed json configuration data
118      */
119     void process(const json& jsonConf);
120 
121     /**
122      * @brief Get the redundancy policy of presence detection for a fan
123      *
124      * @param[in] rpolicy - policy type to construct
125      * @param[in] fpolicy - fan policy object
126      * @param[in] eepromDevice - EEPROM device object
127      *
128      * @return - The constructed redundancy policy type for the fan
129      */
130     std::unique_ptr<RedundancyPolicy>
131         getPolicy(const json& rpolicy, const fanPolicy& fpolicy,
132                   std::unique_ptr<EEPROMDevice> eepromDevice);
133 };
134 
135 /**
136  * Methods of fan presence detection function declarations
137  */
138 namespace method
139 {
140 /**
141  * @brief Fan presence detection method by tach feedback
142  *
143  * @param[in] fanIndex - fan object index to add tach method
144  * @param[in] method - json properties for a tach method
145  *
146  * @return - A presence sensor to detect fan presence by tach feedback
147  */
148 std::unique_ptr<PresenceSensor> getTach(size_t fanIndex, const json& method);
149 
150 /**
151  * @brief Fan presence detection method by gpio
152  *
153  * @param[in] fanIndex - fan object index to add gpio method
154  * @param[in] method - json properties for a gpio method
155  *
156  * @return - A presence sensor to detect fan presence by gpio
157  */
158 std::unique_ptr<PresenceSensor> getGpio(size_t fanIndex, const json& method);
159 
160 } // namespace method
161 
162 /**
163  * Redundancy policies for fan presence detection function declarations
164  */
165 namespace rpolicy
166 {
167 /**
168  * @brief Create an `Anyof` redundancy policy on the created presence
169  * sensors for a fan
170  *
171  * @param[in] fan - fan policy object with the presence sensors for the fan
172  * @param[in] eepromDevice - EEPROM device object
173  *
174  * @return - An `Anyof` redundancy policy
175  */
176 std::unique_ptr<RedundancyPolicy>
177     getAnyof(const fanPolicy& fan, std::unique_ptr<EEPROMDevice> eepromDevice);
178 
179 /**
180  * @brief Create a `Fallback` redundancy policy on the created presence
181  * sensors for a fan
182  *
183  * @param[in] fan - fan policy object with the presence sensors for the fan
184  * @param[in] eepromDevice - EEPROM device object
185  *
186  * @return - A `Fallback` redundancy policy
187  */
188 std::unique_ptr<RedundancyPolicy>
189     getFallback(const fanPolicy& fan,
190                 std::unique_ptr<EEPROMDevice> eepromDevice);
191 
192 } // namespace rpolicy
193 
194 } // namespace presence
195 } // namespace fan
196 } // namespace phosphor
197