1 #pragma once
2 
3 #include <cstring>
4 #include <vector>
5 #include <functional>
6 #include <sdbusplus/bus.hpp>
7 #include "occ_pass_through.hpp"
8 #include "occ_status.hpp"
9 #include "powercap.hpp"
10 
11 namespace sdbusRule = sdbusplus::bus::match::rules;
12 namespace open_power
13 {
14 namespace occ
15 {
16 
17 /** @class Manager
18  *  @brief Builds and manages OCC objects
19  */
20 struct Manager
21 {
22     public:
23         Manager() = delete;
24         Manager(const Manager&) = delete;
25         Manager& operator=(const Manager&) = delete;
26         Manager(Manager&&) = delete;
27         Manager& operator=(Manager&&) = delete;
28         ~Manager() = default;
29 
30         /** @brief Adds OCC pass-through and status objects on the bus
31          *         when corresponding CPU inventory is created.
32          *
33          *  @param[in] bus   - handle to the bus
34          *  @param[in] event - Unique ptr reference to sd_event
35          */
36         Manager(sdbusplus::bus::bus& bus,
37                 EventPtr& event) :
38             bus(bus),
39             event(event)
40         {
41 #ifdef I2C_OCC
42             // I2C OCC status objects are initialized directly
43             initStatusObjects();
44 #else
45             findAndCreateObjects();
46 #endif
47         }
48 
49         inline auto getNumOCCs() const
50         {
51             return activeCount;
52         }
53 
54     private:
55         /** @brief Checks if the CPU inventory is present and if so, creates
56          *         the occ D-Bus objects. Else, registers a handler to be
57          *         called when inventory is created.
58          */
59         void findAndCreateObjects();
60 
61         /** @brief Callback that responds to cpu creation in the inventory -
62          *         by creating the needed objects.
63          *
64          *  @param[in] msg - bus message
65          *
66          *  @returns 0 to indicate success
67          */
68         int cpuCreated(sdbusplus::message::message& msg);
69 
70         /** @brief Create child OCC objects.
71          *
72          *  @param[in] occ - the occ name, such as occ0.
73          */
74         void createObjects(const std::string& occ);
75 
76         /** @brief Callback handler invoked by Status object when the OccActive
77          *         property is changed. This is needed to make sure that the
78          *         error detection is started only after all the OCCs are bound.
79          *         Similarly, when one of the OCC gets its OccActive property
80          *         un-set, then the OCC error detection needs to be stopped on
81          *         all the OCCs
82          *
83          *  @param[in] status - OccActive status
84          */
85         void statusCallBack(bool status);
86 
87         /** @brief Sends a Heartbeat command to host control command handler */
88         void sendHeartBeat();
89 
90         /** @brief reference to the bus */
91         sdbusplus::bus::bus& bus;
92 
93         /** @brief reference to sd_event wrapped in unique_ptr */
94         EventPtr& event;
95 
96         /** @brief OCC pass-through objects */
97         std::vector<std::unique_ptr<PassThrough>> passThroughObjects;
98 
99         /** @brief OCC Status objects */
100         std::vector<std::unique_ptr<Status>> statusObjects;
101 
102         /** @brief Power cap monitor and occ notification object */
103         std::unique_ptr<open_power::occ::powercap::PowerCap> pcap;
104 
105         /** @brief sbdbusplus match objects */
106         std::vector<sdbusplus::bus::match_t> cpuMatches;
107 
108         /** @brief Number of OCCs that are bound */
109         uint8_t activeCount = 0;
110 
111 #ifdef I2C_OCC
112         /** @brief Init Status objects for I2C OCC devices
113          *
114          * It iterates in /sys/bus/i2c/devices, finds all occ hwmon devices
115          * and creates status objects.
116          */
117         void initStatusObjects();
118 #endif
119 };
120 
121 } // namespace occ
122 } // namespace open_power
123