blob: 0a521746d8ed5d753b4a9eb0bb98188e45f5e22f [file] [log] [blame]
Vijay Khemkae2795302020-07-15 17:28:45 -07001#include <nlohmann/json.hpp>
Patrick Williams957e03c2021-09-02 16:38:42 -05002#include <phosphor-logging/lg2.hpp>
Vijay Khemkae2795302020-07-15 17:28:45 -07003#include <sdbusplus/bus.hpp>
Sui Chen670cc132021-04-13 09:27:22 -07004#include <sdbusplus/message.hpp>
Vijay Khemkab38fd582020-07-23 13:21:23 -07005#include <sdeventplus/clock.hpp>
Vijay Khemkae2795302020-07-15 17:28:45 -07006#include <sdeventplus/event.hpp>
Vijay Khemkab38fd582020-07-23 13:21:23 -07007#include <sdeventplus/utility/timer.hpp>
Sui Chen670cc132021-04-13 09:27:22 -07008#include <xyz/openbmc_project/Association/Definitions/server.hpp>
Vijay Khemkae2795302020-07-15 17:28:45 -07009#include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp>
10#include <xyz/openbmc_project/Sensor/Threshold/Warning/server.hpp>
11#include <xyz/openbmc_project/Sensor/Value/server.hpp>
12
Vijay Khemka15537762020-07-22 11:44:56 -070013#include <deque>
Vijay Khemkae2795302020-07-15 17:28:45 -070014#include <map>
15#include <string>
16
17namespace phosphor
18{
19namespace health
20{
21
22using Json = nlohmann::json;
23using ValueIface = sdbusplus::xyz::openbmc_project::Sensor::server::Value;
24
25using CriticalInterface =
26 sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Critical;
27
28using WarningInterface =
29 sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Warning;
30
Sui Chen670cc132021-04-13 09:27:22 -070031using AssociationDefinitionInterface =
32 sdbusplus::xyz::openbmc_project::Association::server::Definitions;
33
Vijay Khemkae2795302020-07-15 17:28:45 -070034using healthIfaces =
35 sdbusplus::server::object::object<ValueIface, CriticalInterface,
Sui Chen670cc132021-04-13 09:27:22 -070036 WarningInterface,
37 AssociationDefinitionInterface>;
38
39using AssociationTuple = std::tuple<std::string, std::string, std::string>;
Vijay Khemkae2795302020-07-15 17:28:45 -070040
Vijay Khemka15537762020-07-22 11:44:56 -070041struct HealthConfig
42{
43 std::string name;
44 uint16_t freq;
45 uint16_t windowSize;
46 double criticalHigh;
47 double warningHigh;
48 bool criticalLog;
49 bool warningLog;
50 std::string criticalTgt;
51 std::string warningTgt;
Bruceleequantatwaf9acbd2020-10-12 15:21:42 +080052 std::string path;
Vijay Khemka15537762020-07-22 11:44:56 -070053};
54
Vijay Khemkae2795302020-07-15 17:28:45 -070055class HealthSensor : public healthIfaces
56{
57 public:
58 HealthSensor() = delete;
59 HealthSensor(const HealthSensor&) = delete;
60 HealthSensor& operator=(const HealthSensor&) = delete;
61 HealthSensor(HealthSensor&&) = delete;
62 HealthSensor& operator=(HealthSensor&&) = delete;
63 virtual ~HealthSensor() = default;
64
65 /** @brief Constructs HealthSensor
66 *
67 * @param[in] bus - Handle to system dbus
68 * @param[in] objPath - The Dbus path of health sensor
69 */
Vijay Khemka15537762020-07-22 11:44:56 -070070 HealthSensor(sdbusplus::bus::bus& bus, const char* objPath,
Sui Chen670cc132021-04-13 09:27:22 -070071 HealthConfig& sensorConfig,
72 const std::vector<std::string>& bmcIds) :
Vijay Khemka15537762020-07-22 11:44:56 -070073 healthIfaces(bus, objPath),
Vijay Khemkab38fd582020-07-23 13:21:23 -070074 bus(bus), sensorConfig(sensorConfig),
75 timerEvent(sdeventplus::Event::get_default()),
76 readTimer(timerEvent, std::bind(&HealthSensor::readHealthSensor, this))
Vijay Khemka15537762020-07-22 11:44:56 -070077 {
Sui Chen670cc132021-04-13 09:27:22 -070078 initHealthSensor(bmcIds);
Vijay Khemka15537762020-07-22 11:44:56 -070079 }
Vijay Khemkae2795302020-07-15 17:28:45 -070080
Vijay Khemka15537762020-07-22 11:44:56 -070081 /** @brief list of sensor data values */
82 std::deque<double> valQueue;
Sui Chen670cc132021-04-13 09:27:22 -070083 /** @brief Initialize sensor, set default value and association */
84 void initHealthSensor(const std::vector<std::string>& bmcIds);
Vijay Khemkae2795302020-07-15 17:28:45 -070085 /** @brief Set sensor value utilization to health sensor D-bus */
Vijay Khemka15537762020-07-22 11:44:56 -070086 void setSensorValueToDbus(const double value);
Vijay Khemkae2795302020-07-15 17:28:45 -070087 /** @brief Set Sensor Threshold to D-bus at beginning */
Vijay Khemka15537762020-07-22 11:44:56 -070088 void setSensorThreshold(double criticalHigh, double warningHigh);
Vijay Khemkab7a7b8a2020-07-29 12:22:01 -070089 /** @brief Check Sensor threshold and update alarm and log */
90 void checkSensorThreshold(const double value);
Vijay Khemkae2795302020-07-15 17:28:45 -070091
92 private:
Vijay Khemkab38fd582020-07-23 13:21:23 -070093 /** @brief sdbusplus bus client connection. */
Vijay Khemkae2795302020-07-15 17:28:45 -070094 sdbusplus::bus::bus& bus;
Vijay Khemkab38fd582020-07-23 13:21:23 -070095 /** @brief Sensor config from config file */
Vijay Khemka15537762020-07-22 11:44:56 -070096 HealthConfig& sensorConfig;
Vijay Khemkab38fd582020-07-23 13:21:23 -070097 /** @brief the Event Loop structure */
98 sdeventplus::Event timerEvent;
99 /** @brief Sensor Read Timer */
100 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> readTimer;
Vijay Khemkab38fd582020-07-23 13:21:23 -0700101 /** @brief Read sensor at regular intrval */
102 void readHealthSensor();
Vijay Khemkae2795302020-07-15 17:28:45 -0700103};
104
105class HealthMon
106{
107 public:
108 HealthMon() = delete;
109 HealthMon(const HealthMon&) = delete;
110 HealthMon& operator=(const HealthMon&) = delete;
111 HealthMon(HealthMon&&) = delete;
112 HealthMon& operator=(HealthMon&&) = delete;
113 virtual ~HealthMon() = default;
114
115 /** @brief Constructs HealthMon
116 *
117 * @param[in] bus - Handle to system dbus
118 */
119 HealthMon(sdbusplus::bus::bus& bus) : bus(bus)
120 {
Patrick Williams957e03c2021-09-02 16:38:42 -0500121 PHOSPHOR_LOG2_USING;
Sui Chen670cc132021-04-13 09:27:22 -0700122 std::vector<std::string> bmcIds = {};
123
124 // Find all BMCs (DBus objects implementing the
125 // Inventory.Item.Bmc interface that may be created by
126 // configuring the Inventory Manager)
127 sdbusplus::message::message msg = bus.new_method_call(
128 "xyz.openbmc_project.ObjectMapper",
129 "/xyz/openbmc_project/object_mapper",
130 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths");
131
132 // Search term
133 msg.append("/xyz/openbmc_project/inventory/system");
134
135 // Limit the depth to 2. Example of "depth":
136 // /xyz/openbmc_project/inventory/system/chassis has a depth of 1
137 // since it has 1 '/' after "/xyz/openbmc_project/inventory/system".
138 msg.append(2);
139
140 // Must have the Inventory.Item.Bmc interface
141 msg.append(
142 std::vector<std::string>{"xyz.openbmc_project.Inventory.Item.Bmc"});
143
144 sdbusplus::message::message reply = bus.call(msg, 0);
145 if (reply.get_signature() == std::string("as"))
146 {
147 reply.read(bmcIds);
Patrick Williams957e03c2021-09-02 16:38:42 -0500148 info("BMC inventory found");
Sui Chen670cc132021-04-13 09:27:22 -0700149 }
150 else
151 {
Patrick Williams957e03c2021-09-02 16:38:42 -0500152 warning("Did not find BMC inventory, cannot create association");
Sui Chen670cc132021-04-13 09:27:22 -0700153 }
154
155 // Read JSON file
Vijay Khemkae2795302020-07-15 17:28:45 -0700156 sensorConfigs = getHealthConfig();
Sui Chen670cc132021-04-13 09:27:22 -0700157
158 // Create health sensors
159 createHealthSensors(bmcIds);
Vijay Khemkae2795302020-07-15 17:28:45 -0700160 }
161
Sui Chen670cc132021-04-13 09:27:22 -0700162 /** @brief Parse Health config JSON file */
Vijay Khemkae2795302020-07-15 17:28:45 -0700163 Json parseConfigFile(std::string configFile);
164
Sui Chen670cc132021-04-13 09:27:22 -0700165 /** @brief Read config for each health sensor component */
Vijay Khemkae2795302020-07-15 17:28:45 -0700166 void getConfigData(Json& data, HealthConfig& cfg);
167
168 /** @brief Map of the object HealthSensor */
169 std::unordered_map<std::string, std::shared_ptr<HealthSensor>>
170 healthSensors;
171
172 /** @brief Create sensors for health monitoring */
Sui Chen670cc132021-04-13 09:27:22 -0700173 void createHealthSensors(const std::vector<std::string>& bmcIds);
Vijay Khemkae2795302020-07-15 17:28:45 -0700174
175 private:
176 sdbusplus::bus::bus& bus;
177 std::vector<HealthConfig> sensorConfigs;
178 std::vector<HealthConfig> getHealthConfig();
179};
180
181} // namespace health
182} // namespace phosphor