blob: d96287fd73014db305460882224300fbfec51d0b [file] [log] [blame]
Vijay Khemkae2795302020-07-15 17:28:45 -07001#include <nlohmann/json.hpp>
Sui Chen670cc132021-04-13 09:27:22 -07002#include <phosphor-logging/log.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
Sui Chen670cc132021-04-13 09:27:22 -070022using namespace phosphor::logging;
23
Vijay Khemkae2795302020-07-15 17:28:45 -070024using Json = nlohmann::json;
25using ValueIface = sdbusplus::xyz::openbmc_project::Sensor::server::Value;
26
27using CriticalInterface =
28 sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Critical;
29
30using WarningInterface =
31 sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Warning;
32
Sui Chen670cc132021-04-13 09:27:22 -070033using AssociationDefinitionInterface =
34 sdbusplus::xyz::openbmc_project::Association::server::Definitions;
35
Vijay Khemkae2795302020-07-15 17:28:45 -070036using healthIfaces =
37 sdbusplus::server::object::object<ValueIface, CriticalInterface,
Sui Chen670cc132021-04-13 09:27:22 -070038 WarningInterface,
39 AssociationDefinitionInterface>;
40
41using AssociationTuple = std::tuple<std::string, std::string, std::string>;
Vijay Khemkae2795302020-07-15 17:28:45 -070042
Vijay Khemka15537762020-07-22 11:44:56 -070043struct HealthConfig
44{
45 std::string name;
46 uint16_t freq;
47 uint16_t windowSize;
48 double criticalHigh;
49 double warningHigh;
50 bool criticalLog;
51 bool warningLog;
52 std::string criticalTgt;
53 std::string warningTgt;
Bruceleequantatwaf9acbd2020-10-12 15:21:42 +080054 std::string path;
Vijay Khemka15537762020-07-22 11:44:56 -070055};
56
Vijay Khemkae2795302020-07-15 17:28:45 -070057class HealthSensor : public healthIfaces
58{
59 public:
60 HealthSensor() = delete;
61 HealthSensor(const HealthSensor&) = delete;
62 HealthSensor& operator=(const HealthSensor&) = delete;
63 HealthSensor(HealthSensor&&) = delete;
64 HealthSensor& operator=(HealthSensor&&) = delete;
65 virtual ~HealthSensor() = default;
66
67 /** @brief Constructs HealthSensor
68 *
69 * @param[in] bus - Handle to system dbus
70 * @param[in] objPath - The Dbus path of health sensor
71 */
Vijay Khemka15537762020-07-22 11:44:56 -070072 HealthSensor(sdbusplus::bus::bus& bus, const char* objPath,
Sui Chen670cc132021-04-13 09:27:22 -070073 HealthConfig& sensorConfig,
74 const std::vector<std::string>& bmcIds) :
Vijay Khemka15537762020-07-22 11:44:56 -070075 healthIfaces(bus, objPath),
Vijay Khemkab38fd582020-07-23 13:21:23 -070076 bus(bus), sensorConfig(sensorConfig),
77 timerEvent(sdeventplus::Event::get_default()),
78 readTimer(timerEvent, std::bind(&HealthSensor::readHealthSensor, this))
Vijay Khemka15537762020-07-22 11:44:56 -070079 {
Sui Chen670cc132021-04-13 09:27:22 -070080 initHealthSensor(bmcIds);
Vijay Khemka15537762020-07-22 11:44:56 -070081 }
Vijay Khemkae2795302020-07-15 17:28:45 -070082
Vijay Khemka15537762020-07-22 11:44:56 -070083 /** @brief list of sensor data values */
84 std::deque<double> valQueue;
Sui Chen670cc132021-04-13 09:27:22 -070085 /** @brief Initialize sensor, set default value and association */
86 void initHealthSensor(const std::vector<std::string>& bmcIds);
Vijay Khemkae2795302020-07-15 17:28:45 -070087 /** @brief Set sensor value utilization to health sensor D-bus */
Vijay Khemka15537762020-07-22 11:44:56 -070088 void setSensorValueToDbus(const double value);
Vijay Khemkae2795302020-07-15 17:28:45 -070089 /** @brief Set Sensor Threshold to D-bus at beginning */
Vijay Khemka15537762020-07-22 11:44:56 -070090 void setSensorThreshold(double criticalHigh, double warningHigh);
Vijay Khemkab7a7b8a2020-07-29 12:22:01 -070091 /** @brief Check Sensor threshold and update alarm and log */
92 void checkSensorThreshold(const double value);
Vijay Khemkae2795302020-07-15 17:28:45 -070093
94 private:
Vijay Khemkab38fd582020-07-23 13:21:23 -070095 /** @brief sdbusplus bus client connection. */
Vijay Khemkae2795302020-07-15 17:28:45 -070096 sdbusplus::bus::bus& bus;
Vijay Khemkab38fd582020-07-23 13:21:23 -070097 /** @brief Sensor config from config file */
Vijay Khemka15537762020-07-22 11:44:56 -070098 HealthConfig& sensorConfig;
Vijay Khemkab38fd582020-07-23 13:21:23 -070099 /** @brief the Event Loop structure */
100 sdeventplus::Event timerEvent;
101 /** @brief Sensor Read Timer */
102 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> readTimer;
Vijay Khemkab38fd582020-07-23 13:21:23 -0700103 /** @brief Read sensor at regular intrval */
104 void readHealthSensor();
Vijay Khemkae2795302020-07-15 17:28:45 -0700105};
106
107class HealthMon
108{
109 public:
110 HealthMon() = delete;
111 HealthMon(const HealthMon&) = delete;
112 HealthMon& operator=(const HealthMon&) = delete;
113 HealthMon(HealthMon&&) = delete;
114 HealthMon& operator=(HealthMon&&) = delete;
115 virtual ~HealthMon() = default;
116
117 /** @brief Constructs HealthMon
118 *
119 * @param[in] bus - Handle to system dbus
120 */
121 HealthMon(sdbusplus::bus::bus& bus) : bus(bus)
122 {
Sui Chen670cc132021-04-13 09:27:22 -0700123 std::vector<std::string> bmcIds = {};
124
125 // Find all BMCs (DBus objects implementing the
126 // Inventory.Item.Bmc interface that may be created by
127 // configuring the Inventory Manager)
128 sdbusplus::message::message msg = bus.new_method_call(
129 "xyz.openbmc_project.ObjectMapper",
130 "/xyz/openbmc_project/object_mapper",
131 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths");
132
133 // Search term
134 msg.append("/xyz/openbmc_project/inventory/system");
135
136 // Limit the depth to 2. Example of "depth":
137 // /xyz/openbmc_project/inventory/system/chassis has a depth of 1
138 // since it has 1 '/' after "/xyz/openbmc_project/inventory/system".
139 msg.append(2);
140
141 // Must have the Inventory.Item.Bmc interface
142 msg.append(
143 std::vector<std::string>{"xyz.openbmc_project.Inventory.Item.Bmc"});
144
145 sdbusplus::message::message reply = bus.call(msg, 0);
146 if (reply.get_signature() == std::string("as"))
147 {
148 reply.read(bmcIds);
149 log<level::INFO>("BMC inventory found");
150 }
151 else
152 {
153 log<level::WARNING>(
154 "Did not find BMC inventory, cannot create association");
155 }
156
157 // Read JSON file
Vijay Khemkae2795302020-07-15 17:28:45 -0700158 sensorConfigs = getHealthConfig();
Sui Chen670cc132021-04-13 09:27:22 -0700159
160 // Create health sensors
161 createHealthSensors(bmcIds);
Vijay Khemkae2795302020-07-15 17:28:45 -0700162 }
163
Sui Chen670cc132021-04-13 09:27:22 -0700164 /** @brief Parse Health config JSON file */
Vijay Khemkae2795302020-07-15 17:28:45 -0700165 Json parseConfigFile(std::string configFile);
166
Sui Chen670cc132021-04-13 09:27:22 -0700167 /** @brief Read config for each health sensor component */
Vijay Khemkae2795302020-07-15 17:28:45 -0700168 void getConfigData(Json& data, HealthConfig& cfg);
169
170 /** @brief Map of the object HealthSensor */
171 std::unordered_map<std::string, std::shared_ptr<HealthSensor>>
172 healthSensors;
173
174 /** @brief Create sensors for health monitoring */
Sui Chen670cc132021-04-13 09:27:22 -0700175 void createHealthSensors(const std::vector<std::string>& bmcIds);
Vijay Khemkae2795302020-07-15 17:28:45 -0700176
177 private:
178 sdbusplus::bus::bus& bus;
179 std::vector<HealthConfig> sensorConfigs;
180 std::vector<HealthConfig> getHealthConfig();
181};
182
183} // namespace health
184} // namespace phosphor