blob: d22e36d5aeda1abe13116bf3aa05997f3d0afd80 [file] [log] [blame]
James Feist6ef20402019-01-07 16:45:08 -08001#pragma once
Ed Tanous9b4a20e2022-09-06 08:47:11 -07002#include <boost/asio/steady_timer.hpp>
James Feist6ef20402019-01-07 16:45:08 -08003#include <boost/container/flat_map.hpp>
Ed Tanous8a57ec02020-10-09 12:46:52 -07004#include <sensor.hpp>
James Feist38fb5982020-05-28 10:09:54 -07005
James Feist6ef20402019-01-07 16:45:08 -08006#include <chrono>
7#include <limits>
Patrick Venturefd6ba732019-10-31 14:27:39 -07008#include <memory>
9#include <optional>
10#include <string>
James Feist6ef20402019-01-07 16:45:08 -080011#include <vector>
12
Ed Tanous828c5a62024-02-09 16:59:22 -080013constexpr const char* sensorType = "IpmbSensor";
14constexpr const char* sdrInterface = "IpmbDevice";
15
James Feist6ef20402019-01-07 16:45:08 -080016enum class IpmbType
17{
Ed Tanousa771f6a2022-01-14 09:36:51 -080018 none,
James Feist6ef20402019-01-07 16:45:08 -080019 meSensor,
20 PXE1410CVR,
21 IR38363VR,
Vijay Khemka682a5cb2019-07-18 17:34:03 -070022 ADM1278HSC,
James Feist6ef20402019-01-07 16:45:08 -080023 mpsVR
24};
25
Vijay Khemka682a5cb2019-07-18 17:34:03 -070026enum class IpmbSubType
27{
Ed Tanousa771f6a2022-01-14 09:36:51 -080028 none,
Vijay Khemka682a5cb2019-07-18 17:34:03 -070029 temp,
30 curr,
31 power,
Adrian Ambrożewicz45e92772020-06-04 13:59:55 +020032 volt,
33 util
Vijay Khemka682a5cb2019-07-18 17:34:03 -070034};
35
James Feistd7ae29a2020-06-25 15:42:46 -070036enum class ReadingFormat
37{
38 byte0,
39 byte3,
40 elevenBit,
41 elevenBitShift,
Jayashree-D37322572021-03-19 17:40:56 +053042 linearElevenBit
James Feistd7ae29a2020-06-25 15:42:46 -070043};
44
Adrian Ambrożewicz58e02ef2020-08-06 14:42:38 +020045namespace ipmi
46{
47namespace sensor
48{
49constexpr uint8_t netFn = 0x04;
50constexpr uint8_t getSensorReading = 0x2d;
51
Patrick Williamsd02ad492023-05-08 09:15:21 -050052static inline bool isValid(const std::vector<uint8_t>& data)
Adrian Ambrożewicz58e02ef2020-08-06 14:42:38 +020053{
Ed Tanous8a57ec02020-10-09 12:46:52 -070054 constexpr auto readingUnavailableBit = 5;
Adrian Ambrożewicz58e02ef2020-08-06 14:42:38 +020055
56 // Proper 'Get Sensor Reading' response has at least 4 bytes, including
57 // Completion Code. Our IPMB stack strips Completion Code from payload so we
58 // compare here against the rest of payload
59 if (data.size() < 3)
60 {
61 return false;
62 }
63
64 // Per IPMI 'Get Sensor Reading' specification
Ed Tanous2049bd22022-07-09 07:20:26 -070065 if ((data[1] & (1 << readingUnavailableBit)) != 0)
Adrian Ambrożewicz58e02ef2020-08-06 14:42:38 +020066 {
67 return false;
68 }
69
70 return true;
71}
72
73} // namespace sensor
74namespace me_bridge
75{
76constexpr uint8_t netFn = 0x2e;
77constexpr uint8_t sendRawPmbus = 0xd9;
78} // namespace me_bridge
79} // namespace ipmi
80
Vikash Chandola1f847972022-09-28 09:47:32 +000081using IpmbMethodType =
82 std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>;
83
84struct IpmbSensor :
85 public Sensor,
86 public std::enable_shared_from_this<IpmbSensor>
James Feist6ef20402019-01-07 16:45:08 -080087{
James Feistd8705872019-02-08 13:26:09 -080088 IpmbSensor(std::shared_ptr<sdbusplus::asio::connection>& conn,
Ed Tanous1f978632023-02-28 18:16:39 -080089 boost::asio::io_context& io, const std::string& name,
James Feistd8705872019-02-08 13:26:09 -080090 const std::string& sensorConfiguration,
91 sdbusplus::asio::object_server& objectServer,
Ed Tanous2049bd22022-07-09 07:20:26 -070092 std::vector<thresholds::Threshold>&& thresholdData,
93 uint8_t deviceAddress, uint8_t hostSMbusIndex, float pollRate,
94 std::string& sensorTypeName);
Ed Tanous8a57ec02020-10-09 12:46:52 -070095 ~IpmbSensor() override;
James Feist6ef20402019-01-07 16:45:08 -080096
Ed Tanous201a1012024-04-03 18:07:28 -070097 void checkThresholds() override;
98 void read();
99 void init();
100 std::string getSubTypeUnits() const;
101 void loadDefaults();
102 void runInitCmd();
Ed Tanous828c5a62024-02-09 16:59:22 -0800103 static bool processReading(ReadingFormat readingFormat, uint8_t command,
104 const std::vector<uint8_t>& data, double& resp,
105 size_t errCount);
Jayashree Dhanapal84189752022-03-07 12:51:54 +0530106 void parseConfigValues(const SensorBaseConfigMap& entry);
107 bool sensorClassType(const std::string& sensorClass);
108 void sensorSubType(const std::string& sensorTypeName);
James Feist6ef20402019-01-07 16:45:08 -0800109
Ed Tanousa771f6a2022-01-14 09:36:51 -0800110 IpmbType type = IpmbType::none;
111 IpmbSubType subType = IpmbSubType::none;
112 double scaleVal = 1.0;
113 double offsetVal = 0.0;
114 uint8_t commandAddress = 0;
115 uint8_t netfn = 0;
116 uint8_t command = 0;
117 uint8_t deviceAddress = 0;
118 uint8_t errorCount = 0;
119 uint8_t hostSMbusIndex = 0;
James Feist6ef20402019-01-07 16:45:08 -0800120 std::vector<uint8_t> commandData;
121 std::optional<uint8_t> initCommand;
122 std::vector<uint8_t> initData;
Jayashree-D9f6d4fd2021-04-13 18:27:22 +0530123 int sensorPollMs;
James Feist6ef20402019-01-07 16:45:08 -0800124
Ed Tanousa771f6a2022-01-14 09:36:51 -0800125 ReadingFormat readingFormat = ReadingFormat::byte0;
James Feist6ef20402019-01-07 16:45:08 -0800126
127 private:
Ed Tanous201a1012024-04-03 18:07:28 -0700128 void sendIpmbRequest();
James Feistd8705872019-02-08 13:26:09 -0800129 sdbusplus::asio::object_server& objectServer;
Ed Tanous9b4a20e2022-09-06 08:47:11 -0700130 boost::asio::steady_timer waitTimer;
Vikash Chandola1f847972022-09-28 09:47:32 +0000131 void ipmbRequestCompletionCb(const boost::system::error_code& ec,
132 const IpmbMethodType& response);
Vijay Khemka682a5cb2019-07-18 17:34:03 -0700133};
Ed Tanous828c5a62024-02-09 16:59:22 -0800134
135void createSensors(
136 boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
137 boost::container::flat_map<std::string, std::shared_ptr<IpmbSensor>>&
138 sensors,
139 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection);
140
141void interfaceRemoved(
142 sdbusplus::message_t& message,
143 boost::container::flat_map<std::string, std::shared_ptr<IpmbSensor>>&
144 sensors);