1 #pragma once
2 
3 #include "eeprom_device.hpp"
4 #include "fan.hpp"
5 
6 namespace phosphor
7 {
8 namespace fan
9 {
10 namespace presence
11 {
12 
13 class PresenceSensor;
14 
15 /**
16  * @class RedundancyPolicy
17  * @brief Redundancy policy interface.
18  *
19  * Provide concrete implementations of RedundancyPolicy to realize
20  * new redundancy logic.
21  *
22  * A fan can have multiple ways to detect whether or not it is present.
23  * The redundancy policy encapsulates the logic to aggregate those
24  * inputs into a single yes or no the fan is present.
25  */
26 class RedundancyPolicy
27 {
28   public:
29     RedundancyPolicy(const RedundancyPolicy&) = default;
30     RedundancyPolicy& operator=(const RedundancyPolicy&) = default;
31     RedundancyPolicy(RedundancyPolicy&&) = default;
32     RedundancyPolicy& operator=(RedundancyPolicy&&) = default;
33     virtual ~RedundancyPolicy() = default;
34 
35     /**
36      * @brief Construct a new Redundancy Policy.
37      *
38      * @param[in] fan - The fan associated with this policy.
39      * @param[in] eeprom - EEPROM device instance
40      */
41     explicit RedundancyPolicy(const Fan& f,
42                               std::unique_ptr<EEPROMDevice> eeprom) :
43         fan(f),
44         eepromDevice(std::move(eeprom))
45     {}
46 
47     /**
48      * @brief stateChanged
49      *
50      * Typically invoked by presence sensors to signify
51      * a change of presence.  Implementations should update
52      * the inventory and execute their policy logic.
53      *
54      * @param[in] present - The new state of the sensor.
55      * @param[in] sensor - The sensor that changed state.
56      */
57     virtual void stateChanged(bool present, PresenceSensor& sensor) = 0;
58 
59     /**
60      * @brief monitor
61      *
62      * Implementations should start monitoring the sensors
63      * associated with the fan.
64      */
65     virtual void monitor() = 0;
66 
67   protected:
68     /** @brief Fan name and inventory path. */
69     const Fan& fan;
70 
71     /**
72      * @brief Handles binding the EEPROM driver on fan plug
73      *        if configured to do so.
74      */
75     std::unique_ptr<EEPROMDevice> eepromDevice;
76 };
77 
78 /**
79  * @class PolicyAccess
80  * @brief Policy association.
81  *
82  * PolicyAccess can be used to associate a redundancy policy
83  * with something else.
84  *
85  * Wrap the type to be associated with a policy with PolicyAccess.
86  *
87  * @tparam T - The type to associate with a redundancy policy.
88  * @tparam Policy - An array type where the policy is stored.
89  */
90 template <typename T, typename Policy>
91 class PolicyAccess : public T
92 {
93   public:
94     PolicyAccess() = default;
95     PolicyAccess(const PolicyAccess&) = default;
96     PolicyAccess& operator=(const PolicyAccess&) = default;
97     PolicyAccess(PolicyAccess&&) = default;
98     PolicyAccess& operator=(PolicyAccess&&) = default;
99     ~PolicyAccess() = default;
100 
101     /**
102      * @brief Construct a new PolicyAccess wrapped object.
103      *
104      * @param[in] index - The array index in Policy.
105      * @tparam Args - Forwarded to wrapped type constructor.
106      */
107     template <typename... Args>
108     PolicyAccess(size_t index, Args&&... args) :
109         T(std::forward<Args>(args)...), policy(index)
110     {}
111 
112   private:
113     /**
114      * @brief Get the associated policy.
115      */
116     RedundancyPolicy& getPolicy() override
117     {
118         return *Policy::get()[policy];
119     }
120 
121     /** The associated policy index. */
122     size_t policy;
123 };
124 } // namespace presence
125 } // namespace fan
126 } // namespace phosphor
127