| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1 | /* | 
 | 2 | // Copyright (c) 2017 2018 Intel Corporation | 
 | 3 | // | 
 | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 | // you may not use this file except in compliance with the License. | 
 | 6 | // You may obtain a copy of the License at | 
 | 7 | // | 
 | 8 | //      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 | // | 
 | 10 | // Unless required by applicable law or agreed to in writing, software | 
 | 11 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 | // See the License for the specific language governing permissions and | 
 | 14 | // limitations under the License. | 
 | 15 | */ | 
 | 16 |  | 
| Patrick Venture | 31b35d5 | 2019-10-20 13:25:16 -0700 | [diff] [blame] | 17 | #include "sensorcommands.hpp" | 
 | 18 |  | 
 | 19 | #include "commandutils.hpp" | 
 | 20 | #include "ipmi_to_redfish_hooks.hpp" | 
 | 21 | #include "sdrutils.hpp" | 
 | 22 | #include "sensorutils.hpp" | 
 | 23 | #include "storagecommands.hpp" | 
| Patrick Venture | c2a07d4 | 2020-05-30 16:35:03 -0700 | [diff] [blame] | 24 | #include "types.hpp" | 
| Patrick Venture | 31b35d5 | 2019-10-20 13:25:16 -0700 | [diff] [blame] | 25 |  | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 26 | #include <boost/algorithm/string.hpp> | 
 | 27 | #include <boost/container/flat_map.hpp> | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 28 | #include <ipmid/api.hpp> | 
 | 29 | #include <ipmid/utils.hpp> | 
 | 30 | #include <phosphor-logging/log.hpp> | 
 | 31 | #include <sdbusplus/bus.hpp> | 
 | 32 |  | 
 | 33 | #include <algorithm> | 
 | 34 | #include <array> | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 35 | #include <chrono> | 
 | 36 | #include <cmath> | 
| Patrick Venture | 5c2d26e | 2019-09-25 17:43:53 -0700 | [diff] [blame] | 37 | #include <cstring> | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 38 | #include <iostream> | 
| Patrick Venture | b10ec8b | 2019-09-25 16:39:14 -0700 | [diff] [blame] | 39 | #include <map> | 
| Patrick Venture | fd2a938 | 2019-09-25 17:47:25 -0700 | [diff] [blame] | 40 | #include <memory> | 
| Patrick Venture | c4e9de6 | 2019-09-25 17:40:54 -0700 | [diff] [blame] | 41 | #include <optional> | 
| Patrick Venture | e615402 | 2019-09-25 17:50:25 -0700 | [diff] [blame] | 42 | #include <stdexcept> | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 43 | #include <string> | 
| Patrick Venture | 38f46f2 | 2019-09-25 17:41:26 -0700 | [diff] [blame] | 44 | #include <utility> | 
| Patrick Venture | eb02a5c | 2019-09-25 17:44:43 -0700 | [diff] [blame] | 45 | #include <variant> | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 46 |  | 
 | 47 | namespace ipmi | 
 | 48 | { | 
 | 49 | using ManagedObjectType = | 
 | 50 |     std::map<sdbusplus::message::object_path, | 
 | 51 |              std::map<std::string, std::map<std::string, DbusVariant>>>; | 
 | 52 |  | 
| James Feist | 2569025 | 2019-12-23 12:25:49 -0800 | [diff] [blame] | 53 | static constexpr int sensorMapUpdatePeriod = 10; | 
| Alex Qiu | 09701ef | 2020-07-15 17:56:21 -0700 | [diff] [blame] | 54 | static constexpr int sensorMapSdrUpdatePeriod = 60; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 55 |  | 
 | 56 | constexpr size_t maxSDRTotalSize = | 
 | 57 |     76; // Largest SDR Record Size (type 01) + SDR Overheader Size | 
 | 58 | constexpr static const uint32_t noTimestamp = 0xFFFFFFFF; | 
 | 59 |  | 
 | 60 | static uint16_t sdrReservationID; | 
 | 61 | static uint32_t sdrLastAdd = noTimestamp; | 
 | 62 | static uint32_t sdrLastRemove = noTimestamp; | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 63 | static constexpr size_t lastRecordIndex = 0xFFFF; | 
| Johnathan Mantey | 2346b5d | 2021-08-06 11:21:10 -0700 | [diff] [blame] | 64 |  | 
 | 65 | // The IPMI spec defines four Logical Units (LUN), each capable of supporting | 
 | 66 | // 255 sensors. The 256 values assigned to LUN 2 are special and are not used | 
 | 67 | // for general purpose sensors. Each LUN reserves location 0xFF. The maximum | 
 | 68 | // number of IPMI sensors are LUN 0 + LUN 1 + LUN 2, less the reserved | 
 | 69 | // location. | 
 | 70 | static constexpr size_t maxIPMISensors = ((3 * 256) - (3 * 1)); | 
 | 71 |  | 
 | 72 | static constexpr size_t lun0MaxSensorNum = 0xfe; | 
 | 73 | static constexpr size_t lun1MaxSensorNum = 0x1fe; | 
 | 74 | static constexpr size_t lun3MaxSensorNum = 0x3fe; | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 75 | static constexpr int GENERAL_ERROR = -1; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 76 |  | 
| Richard Marian Thomaiyar | 01fbcb5 | 2018-11-19 22:04:34 +0530 | [diff] [blame] | 77 | SensorSubTree sensorTree; | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 78 |  | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 79 | static boost::container::flat_map<std::string, ManagedObjectType> SensorCache; | 
 | 80 |  | 
| Jason M. Bills | 17add59 | 2018-11-12 14:30:12 -0800 | [diff] [blame] | 81 | // Specify the comparison required to sort and find char* map objects | 
 | 82 | struct CmpStr | 
 | 83 | { | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 84 |     bool operator()(const char* a, const char* b) const | 
| Jason M. Bills | 17add59 | 2018-11-12 14:30:12 -0800 | [diff] [blame] | 85 |     { | 
 | 86 |         return std::strcmp(a, b) < 0; | 
 | 87 |     } | 
 | 88 | }; | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 89 | const static boost::container::flat_map<const char*, SensorUnits, CmpStr> | 
| Jason M. Bills | 17add59 | 2018-11-12 14:30:12 -0800 | [diff] [blame] | 90 |     sensorUnits{{{"temperature", SensorUnits::degreesC}, | 
 | 91 |                  {"voltage", SensorUnits::volts}, | 
 | 92 |                  {"current", SensorUnits::amps}, | 
 | 93 |                  {"fan_tach", SensorUnits::rpm}, | 
 | 94 |                  {"power", SensorUnits::watts}}}; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 95 |  | 
 | 96 | void registerSensorFunctions() __attribute__((constructor)); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 97 |  | 
 | 98 | static sdbusplus::bus::match::match sensorAdded( | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 99 |     *getSdBus(), | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 100 |     "type='signal',member='InterfacesAdded',arg0path='/xyz/openbmc_project/" | 
 | 101 |     "sensors/'", | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 102 |     [](sdbusplus::message::message& m) { | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 103 |         sensorTree.clear(); | 
 | 104 |         sdrLastAdd = std::chrono::duration_cast<std::chrono::seconds>( | 
 | 105 |                          std::chrono::system_clock::now().time_since_epoch()) | 
 | 106 |                          .count(); | 
 | 107 |     }); | 
 | 108 |  | 
 | 109 | static sdbusplus::bus::match::match sensorRemoved( | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 110 |     *getSdBus(), | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 111 |     "type='signal',member='InterfacesRemoved',arg0path='/xyz/openbmc_project/" | 
 | 112 |     "sensors/'", | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 113 |     [](sdbusplus::message::message& m) { | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 114 |         sensorTree.clear(); | 
 | 115 |         sdrLastRemove = std::chrono::duration_cast<std::chrono::seconds>( | 
 | 116 |                             std::chrono::system_clock::now().time_since_epoch()) | 
 | 117 |                             .count(); | 
 | 118 |     }); | 
 | 119 |  | 
| James Feist | 392786a | 2019-03-19 13:36:10 -0700 | [diff] [blame] | 120 | // this keeps track of deassertions for sensor event status command. A | 
 | 121 | // deasertion can only happen if an assertion was seen first. | 
 | 122 | static boost::container::flat_map< | 
 | 123 |     std::string, boost::container::flat_map<std::string, std::optional<bool>>> | 
 | 124 |     thresholdDeassertMap; | 
 | 125 |  | 
 | 126 | static sdbusplus::bus::match::match thresholdChanged( | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 127 |     *getSdBus(), | 
| James Feist | 392786a | 2019-03-19 13:36:10 -0700 | [diff] [blame] | 128 |     "type='signal',member='PropertiesChanged',interface='org.freedesktop.DBus." | 
 | 129 |     "Properties',arg0namespace='xyz.openbmc_project.Sensor.Threshold'", | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 130 |     [](sdbusplus::message::message& m) { | 
| James Feist | 392786a | 2019-03-19 13:36:10 -0700 | [diff] [blame] | 131 |         boost::container::flat_map<std::string, std::variant<bool, double>> | 
 | 132 |             values; | 
 | 133 |         m.read(std::string(), values); | 
 | 134 |  | 
 | 135 |         auto findAssert = | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 136 |             std::find_if(values.begin(), values.end(), [](const auto& pair) { | 
| James Feist | 392786a | 2019-03-19 13:36:10 -0700 | [diff] [blame] | 137 |                 return pair.first.find("Alarm") != std::string::npos; | 
 | 138 |             }); | 
 | 139 |         if (findAssert != values.end()) | 
 | 140 |         { | 
 | 141 |             auto ptr = std::get_if<bool>(&(findAssert->second)); | 
 | 142 |             if (ptr == nullptr) | 
 | 143 |             { | 
 | 144 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 145 |                     "thresholdChanged: Assert non bool"); | 
 | 146 |                 return; | 
 | 147 |             } | 
 | 148 |             if (*ptr) | 
 | 149 |             { | 
 | 150 |                 phosphor::logging::log<phosphor::logging::level::INFO>( | 
 | 151 |                     "thresholdChanged: Assert", | 
 | 152 |                     phosphor::logging::entry("SENSOR=%s", m.get_path())); | 
 | 153 |                 thresholdDeassertMap[m.get_path()][findAssert->first] = *ptr; | 
 | 154 |             } | 
 | 155 |             else | 
 | 156 |             { | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 157 |                 auto& value = | 
| James Feist | 392786a | 2019-03-19 13:36:10 -0700 | [diff] [blame] | 158 |                     thresholdDeassertMap[m.get_path()][findAssert->first]; | 
 | 159 |                 if (value) | 
 | 160 |                 { | 
 | 161 |                     phosphor::logging::log<phosphor::logging::level::INFO>( | 
 | 162 |                         "thresholdChanged: deassert", | 
 | 163 |                         phosphor::logging::entry("SENSOR=%s", m.get_path())); | 
 | 164 |                     value = *ptr; | 
 | 165 |                 } | 
 | 166 |             } | 
 | 167 |         } | 
 | 168 |     }); | 
 | 169 |  | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 170 | static void getSensorMaxMin(const SensorMap& sensorMap, double& max, | 
 | 171 |                             double& min) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 172 | { | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 173 |     max = 127; | 
 | 174 |     min = -128; | 
 | 175 |  | 
| James Feist | aecaef7 | 2019-04-26 10:30:32 -0700 | [diff] [blame] | 176 |     auto sensorObject = sensorMap.find("xyz.openbmc_project.Sensor.Value"); | 
 | 177 |     auto critical = | 
 | 178 |         sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical"); | 
 | 179 |     auto warning = | 
 | 180 |         sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning"); | 
 | 181 |  | 
 | 182 |     if (sensorObject != sensorMap.end()) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 183 |     { | 
| James Feist | aecaef7 | 2019-04-26 10:30:32 -0700 | [diff] [blame] | 184 |         auto maxMap = sensorObject->second.find("MaxValue"); | 
 | 185 |         auto minMap = sensorObject->second.find("MinValue"); | 
 | 186 |  | 
 | 187 |         if (maxMap != sensorObject->second.end()) | 
 | 188 |         { | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 189 |             max = std::visit(VariantToDoubleVisitor(), maxMap->second); | 
| James Feist | aecaef7 | 2019-04-26 10:30:32 -0700 | [diff] [blame] | 190 |         } | 
 | 191 |         if (minMap != sensorObject->second.end()) | 
 | 192 |         { | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 193 |             min = std::visit(VariantToDoubleVisitor(), minMap->second); | 
| James Feist | aecaef7 | 2019-04-26 10:30:32 -0700 | [diff] [blame] | 194 |         } | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 195 |     } | 
| James Feist | aecaef7 | 2019-04-26 10:30:32 -0700 | [diff] [blame] | 196 |     if (critical != sensorMap.end()) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 197 |     { | 
| James Feist | aecaef7 | 2019-04-26 10:30:32 -0700 | [diff] [blame] | 198 |         auto lower = critical->second.find("CriticalLow"); | 
 | 199 |         auto upper = critical->second.find("CriticalHigh"); | 
 | 200 |         if (lower != critical->second.end()) | 
 | 201 |         { | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 202 |             double value = std::visit(VariantToDoubleVisitor(), lower->second); | 
| James Feist | aecaef7 | 2019-04-26 10:30:32 -0700 | [diff] [blame] | 203 |             min = std::min(value, min); | 
 | 204 |         } | 
 | 205 |         if (upper != critical->second.end()) | 
 | 206 |         { | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 207 |             double value = std::visit(VariantToDoubleVisitor(), upper->second); | 
| James Feist | aecaef7 | 2019-04-26 10:30:32 -0700 | [diff] [blame] | 208 |             max = std::max(value, max); | 
 | 209 |         } | 
 | 210 |     } | 
 | 211 |     if (warning != sensorMap.end()) | 
 | 212 |     { | 
 | 213 |  | 
 | 214 |         auto lower = warning->second.find("WarningLow"); | 
 | 215 |         auto upper = warning->second.find("WarningHigh"); | 
 | 216 |         if (lower != warning->second.end()) | 
 | 217 |         { | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 218 |             double value = std::visit(VariantToDoubleVisitor(), lower->second); | 
| James Feist | aecaef7 | 2019-04-26 10:30:32 -0700 | [diff] [blame] | 219 |             min = std::min(value, min); | 
 | 220 |         } | 
 | 221 |         if (upper != warning->second.end()) | 
 | 222 |         { | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 223 |             double value = std::visit(VariantToDoubleVisitor(), upper->second); | 
| James Feist | aecaef7 | 2019-04-26 10:30:32 -0700 | [diff] [blame] | 224 |             max = std::max(value, max); | 
 | 225 |         } | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 226 |     } | 
 | 227 | } | 
 | 228 |  | 
| James Feist | 2569025 | 2019-12-23 12:25:49 -0800 | [diff] [blame] | 229 | static bool getSensorMap(boost::asio::yield_context yield, | 
 | 230 |                          std::string sensorConnection, std::string sensorPath, | 
| Alex Qiu | 09701ef | 2020-07-15 17:56:21 -0700 | [diff] [blame] | 231 |                          SensorMap& sensorMap, | 
 | 232 |                          int updatePeriod = sensorMapUpdatePeriod) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 233 | { | 
 | 234 |     static boost::container::flat_map< | 
 | 235 |         std::string, std::chrono::time_point<std::chrono::steady_clock>> | 
 | 236 |         updateTimeMap; | 
 | 237 |  | 
 | 238 |     auto updateFind = updateTimeMap.find(sensorConnection); | 
 | 239 |     auto lastUpdate = std::chrono::time_point<std::chrono::steady_clock>(); | 
 | 240 |     if (updateFind != updateTimeMap.end()) | 
 | 241 |     { | 
 | 242 |         lastUpdate = updateFind->second; | 
 | 243 |     } | 
 | 244 |  | 
 | 245 |     auto now = std::chrono::steady_clock::now(); | 
 | 246 |  | 
 | 247 |     if (std::chrono::duration_cast<std::chrono::seconds>(now - lastUpdate) | 
| Alex Qiu | 09701ef | 2020-07-15 17:56:21 -0700 | [diff] [blame] | 248 |             .count() > updatePeriod) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 249 |     { | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 250 |         std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
| James Feist | 2569025 | 2019-12-23 12:25:49 -0800 | [diff] [blame] | 251 |         boost::system::error_code ec; | 
 | 252 |         auto managedObjects = dbus->yield_method_call<ManagedObjectType>( | 
 | 253 |             yield, ec, sensorConnection.c_str(), "/", | 
 | 254 |             "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); | 
 | 255 |         if (ec) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 256 |         { | 
 | 257 |             phosphor::logging::log<phosphor::logging::level::ERR>( | 
| James Feist | 2569025 | 2019-12-23 12:25:49 -0800 | [diff] [blame] | 258 |                 "GetMangagedObjects for getSensorMap failed", | 
 | 259 |                 phosphor::logging::entry("ERROR=%s", ec.message().c_str())); | 
 | 260 |  | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 261 |             return false; | 
 | 262 |         } | 
 | 263 |  | 
 | 264 |         SensorCache[sensorConnection] = managedObjects; | 
| Alex Qiu | 09701ef | 2020-07-15 17:56:21 -0700 | [diff] [blame] | 265 |         // Update time after finish building the map which allow the | 
 | 266 |         // data to be cached for updatePeriod plus the build time. | 
 | 267 |         updateTimeMap[sensorConnection] = std::chrono::steady_clock::now(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 268 |     } | 
 | 269 |     auto connection = SensorCache.find(sensorConnection); | 
 | 270 |     if (connection == SensorCache.end()) | 
 | 271 |     { | 
 | 272 |         return false; | 
 | 273 |     } | 
 | 274 |     auto path = connection->second.find(sensorPath); | 
 | 275 |     if (path == connection->second.end()) | 
 | 276 |     { | 
 | 277 |         return false; | 
 | 278 |     } | 
 | 279 |     sensorMap = path->second; | 
 | 280 |  | 
 | 281 |     return true; | 
 | 282 | } | 
 | 283 |  | 
 | 284 | /* sensor commands */ | 
| James Feist | 7aaf3fe | 2019-06-25 11:52:11 -0700 | [diff] [blame] | 285 | namespace meHealth | 
 | 286 | { | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 287 | constexpr const char* busname = "xyz.openbmc_project.NodeManagerProxy"; | 
 | 288 | constexpr const char* path = "/xyz/openbmc_project/status/me"; | 
 | 289 | constexpr const char* interface = "xyz.openbmc_project.SetHealth"; | 
 | 290 | constexpr const char* method = "SetHealth"; | 
 | 291 | constexpr const char* critical = "critical"; | 
 | 292 | constexpr const char* warning = "warning"; | 
 | 293 | constexpr const char* ok = "ok"; | 
| James Feist | 7aaf3fe | 2019-06-25 11:52:11 -0700 | [diff] [blame] | 294 | } // namespace meHealth | 
 | 295 |  | 
 | 296 | static void setMeStatus(uint8_t eventData2, uint8_t eventData3, bool disable) | 
 | 297 | { | 
 | 298 |     constexpr const std::array<uint8_t, 10> critical = { | 
 | 299 |         0x1, 0x2, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xD, 0xE}; | 
 | 300 |     constexpr const std::array<uint8_t, 5> warning = {0x3, 0xA, 0x13, 0x19, | 
 | 301 |                                                       0x1A}; | 
 | 302 |  | 
 | 303 |     std::string state; | 
 | 304 |     if (std::find(critical.begin(), critical.end(), eventData2) != | 
 | 305 |         critical.end()) | 
 | 306 |     { | 
 | 307 |         state = meHealth::critical; | 
 | 308 |     } | 
 | 309 |     // special case 0x3 as we only care about a few states | 
 | 310 |     else if (eventData2 == 0x3) | 
 | 311 |     { | 
 | 312 |         if (eventData3 <= 0x2) | 
 | 313 |         { | 
 | 314 |             state = meHealth::warning; | 
 | 315 |         } | 
 | 316 |         else | 
 | 317 |         { | 
 | 318 |             return; | 
 | 319 |         } | 
 | 320 |     } | 
 | 321 |     else if (std::find(warning.begin(), warning.end(), eventData2) != | 
 | 322 |              warning.end()) | 
 | 323 |     { | 
 | 324 |         state = meHealth::warning; | 
 | 325 |     } | 
 | 326 |     else | 
 | 327 |     { | 
 | 328 |         return; | 
 | 329 |     } | 
 | 330 |     if (disable) | 
 | 331 |     { | 
 | 332 |         state = meHealth::ok; | 
 | 333 |     } | 
 | 334 |  | 
 | 335 |     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); | 
 | 336 |     auto setHealth = | 
 | 337 |         dbus->new_method_call(meHealth::busname, meHealth::path, | 
 | 338 |                               meHealth::interface, meHealth::method); | 
 | 339 |     setHealth.append(std::to_string(static_cast<size_t>(eventData2)), state); | 
 | 340 |     try | 
 | 341 |     { | 
 | 342 |         dbus->call(setHealth); | 
 | 343 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 344 |     catch (const sdbusplus::exception_t&) | 
| James Feist | 7aaf3fe | 2019-06-25 11:52:11 -0700 | [diff] [blame] | 345 |     { | 
 | 346 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 347 |             "Failed to set ME Health"); | 
 | 348 |     } | 
 | 349 | } | 
 | 350 |  | 
| Chalapathi Venkataramashetty | 989a13b | 2021-06-20 19:50:33 +0000 | [diff] [blame] | 351 | ipmi::RspType<> ipmiSenPlatformEvent(ipmi::Context::ptr ctx, | 
 | 352 |                                      ipmi::message::Payload& p) | 
| Jason M. Bills | ae6bdb1 | 2019-04-02 12:00:04 -0700 | [diff] [blame] | 353 | { | 
| James Feist | 7aaf3fe | 2019-06-25 11:52:11 -0700 | [diff] [blame] | 354 |     constexpr const uint8_t meId = 0x2C; | 
 | 355 |     constexpr const uint8_t meSensorNum = 0x17; | 
 | 356 |     constexpr const uint8_t disabled = 0x80; | 
 | 357 |  | 
| Sujoy Ray | 9e58cfe | 2021-11-01 13:17:27 -0700 | [diff] [blame] | 358 |     uint8_t sysgeneratorID = 0; | 
| Jason M. Bills | ae6bdb1 | 2019-04-02 12:00:04 -0700 | [diff] [blame] | 359 |     uint8_t evmRev = 0; | 
 | 360 |     uint8_t sensorType = 0; | 
 | 361 |     uint8_t sensorNum = 0; | 
 | 362 |     uint8_t eventType = 0; | 
 | 363 |     uint8_t eventData1 = 0; | 
 | 364 |     std::optional<uint8_t> eventData2 = 0; | 
 | 365 |     std::optional<uint8_t> eventData3 = 0; | 
| Sujoy Ray | 9e58cfe | 2021-11-01 13:17:27 -0700 | [diff] [blame] | 366 |     uint16_t generatorID = 0; | 
| Chalapathi Venkataramashetty | 989a13b | 2021-06-20 19:50:33 +0000 | [diff] [blame] | 367 |     ipmi::ChannelInfo chInfo; | 
| Jason M. Bills | ae6bdb1 | 2019-04-02 12:00:04 -0700 | [diff] [blame] | 368 |  | 
| Chalapathi Venkataramashetty | 989a13b | 2021-06-20 19:50:33 +0000 | [diff] [blame] | 369 |     if (ipmi::getChannelInfo(ctx->channel, chInfo) != ipmi::ccSuccess) | 
| Jason M. Bills | ae6bdb1 | 2019-04-02 12:00:04 -0700 | [diff] [blame] | 370 |     { | 
| Chalapathi Venkataramashetty | 989a13b | 2021-06-20 19:50:33 +0000 | [diff] [blame] | 371 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 372 |             "Failed to get Channel Info", | 
 | 373 |             phosphor::logging::entry("CHANNEL=%d", ctx->channel)); | 
 | 374 |         return ipmi::responseUnspecifiedError(); | 
| Jason M. Bills | ae6bdb1 | 2019-04-02 12:00:04 -0700 | [diff] [blame] | 375 |     } | 
| Chalapathi Venkataramashetty | 989a13b | 2021-06-20 19:50:33 +0000 | [diff] [blame] | 376 |  | 
 | 377 |     if (static_cast<ipmi::EChannelMediumType>(chInfo.mediumType) == | 
 | 378 |         ipmi::EChannelMediumType::systemInterface) | 
| Jason M. Bills | ae6bdb1 | 2019-04-02 12:00:04 -0700 | [diff] [blame] | 379 |     { | 
| Chalapathi Venkataramashetty | 989a13b | 2021-06-20 19:50:33 +0000 | [diff] [blame] | 380 |  | 
| Sujoy Ray | 9e58cfe | 2021-11-01 13:17:27 -0700 | [diff] [blame] | 381 |         p.unpack(sysgeneratorID, evmRev, sensorType, sensorNum, eventType, | 
| Jason M. Bills | ae6bdb1 | 2019-04-02 12:00:04 -0700 | [diff] [blame] | 382 |                  eventData1, eventData2, eventData3); | 
| Vernon Mauery | 5d24dda | 2022-04-13 15:11:10 -0700 | [diff] [blame] | 383 |         constexpr const uint8_t isSoftwareID = 0x01; | 
 | 384 |         if (!(sysgeneratorID & isSoftwareID)) | 
 | 385 |         { | 
 | 386 |             return ipmi::responseInvalidFieldRequest(); | 
 | 387 |         } | 
| Sujoy Ray | 9e58cfe | 2021-11-01 13:17:27 -0700 | [diff] [blame] | 388 |         // Refer to IPMI Spec Table 32: SEL Event Records | 
 | 389 |         generatorID = (ctx->channel << 12) // Channel | 
 | 390 |                       | (0x0 << 10)        // Reserved | 
 | 391 |                       | (0x0 << 8)         // 0x0 for sys-soft ID | 
| Vernon Mauery | 5d24dda | 2022-04-13 15:11:10 -0700 | [diff] [blame] | 392 |                       | sysgeneratorID; | 
| Jason M. Bills | ae6bdb1 | 2019-04-02 12:00:04 -0700 | [diff] [blame] | 393 |     } | 
| Chalapathi Venkataramashetty | 989a13b | 2021-06-20 19:50:33 +0000 | [diff] [blame] | 394 |     else | 
 | 395 |     { | 
 | 396 |  | 
 | 397 |         p.unpack(evmRev, sensorType, sensorNum, eventType, eventData1, | 
 | 398 |                  eventData2, eventData3); | 
| Sujoy Ray | 9e58cfe | 2021-11-01 13:17:27 -0700 | [diff] [blame] | 399 |         // Refer to IPMI Spec Table 32: SEL Event Records | 
 | 400 |         generatorID = (ctx->channel << 12)      // Channel | 
 | 401 |                       | (0x0 << 10)             // Reserved | 
 | 402 |                       | ((ctx->lun & 0x3) << 8) // Lun | 
 | 403 |                       | (ctx->rqSA << 1); | 
| Chalapathi Venkataramashetty | 989a13b | 2021-06-20 19:50:33 +0000 | [diff] [blame] | 404 |     } | 
 | 405 |  | 
| Jason M. Bills | ae6bdb1 | 2019-04-02 12:00:04 -0700 | [diff] [blame] | 406 |     if (!p.fullyUnpacked()) | 
 | 407 |     { | 
 | 408 |         return ipmi::responseReqDataLenInvalid(); | 
 | 409 |     } | 
 | 410 |  | 
| Chalapathi Venkataramashetty | 989a13b | 2021-06-20 19:50:33 +0000 | [diff] [blame] | 411 |     // Check for valid evmRev and Sensor Type(per Table 42 of spec) | 
 | 412 |     if (evmRev != 0x04) | 
 | 413 |     { | 
 | 414 |         return ipmi::responseInvalidFieldRequest(); | 
 | 415 |     } | 
 | 416 |     if ((sensorType > 0x2C) && (sensorType < 0xC0)) | 
 | 417 |     { | 
 | 418 |         return ipmi::responseInvalidFieldRequest(); | 
 | 419 |     } | 
 | 420 |  | 
| Jason M. Bills | 6dd8f04 | 2019-04-11 10:39:02 -0700 | [diff] [blame] | 421 |     // Send this request to the Redfish hooks to log it as a Redfish message | 
 | 422 |     // instead.  There is no need to add it to the SEL, so just return success. | 
 | 423 |     intel_oem::ipmi::sel::checkRedfishHooks( | 
 | 424 |         generatorID, evmRev, sensorType, sensorNum, eventType, eventData1, | 
 | 425 |         eventData2.value_or(0xFF), eventData3.value_or(0xFF)); | 
| Jason M. Bills | ae6bdb1 | 2019-04-02 12:00:04 -0700 | [diff] [blame] | 426 |  | 
| Vernon Mauery | ce3b757 | 2022-04-14 13:16:25 -0700 | [diff] [blame^] | 427 |     if (static_cast<uint8_t>(generatorID) == meId && sensorNum == meSensorNum && | 
| Sujoy Ray | 9e58cfe | 2021-11-01 13:17:27 -0700 | [diff] [blame] | 428 |         eventData2 && eventData3) | 
| James Feist | 7aaf3fe | 2019-06-25 11:52:11 -0700 | [diff] [blame] | 429 |     { | 
 | 430 |         setMeStatus(*eventData2, *eventData3, (eventType & disabled)); | 
 | 431 |     } | 
 | 432 |  | 
| Jason M. Bills | ae6bdb1 | 2019-04-02 12:00:04 -0700 | [diff] [blame] | 433 |     return ipmi::responseSuccess(); | 
 | 434 | } | 
 | 435 |  | 
| James Feist | 0cd014a | 2019-04-08 15:04:33 -0700 | [diff] [blame] | 436 | ipmi::RspType<uint8_t, uint8_t, uint8_t, std::optional<uint8_t>> | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 437 |     ipmiSenGetSensorReading(ipmi::Context::ptr ctx, uint8_t sensnum) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 438 | { | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 439 |     std::string connection; | 
 | 440 |     std::string path; | 
 | 441 |  | 
| Chalapathi Venkataramashetty | 339fc56 | 2021-06-13 19:51:17 +0000 | [diff] [blame] | 442 |     if (sensnum == reservedSensorNumber) | 
 | 443 |     { | 
 | 444 |         return ipmi::responseInvalidFieldRequest(); | 
 | 445 |     } | 
 | 446 |  | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 447 |     auto status = getSensorConnection(ctx, sensnum, connection, path); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 448 |     if (status) | 
 | 449 |     { | 
| James Feist | 0cd014a | 2019-04-08 15:04:33 -0700 | [diff] [blame] | 450 |         return ipmi::response(status); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 451 |     } | 
 | 452 |  | 
 | 453 |     SensorMap sensorMap; | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 454 |     if (!getSensorMap(ctx->yield, connection, path, sensorMap)) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 455 |     { | 
| James Feist | 0cd014a | 2019-04-08 15:04:33 -0700 | [diff] [blame] | 456 |         return ipmi::responseResponseError(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 457 |     } | 
 | 458 |     auto sensorObject = sensorMap.find("xyz.openbmc_project.Sensor.Value"); | 
 | 459 |  | 
 | 460 |     if (sensorObject == sensorMap.end() || | 
 | 461 |         sensorObject->second.find("Value") == sensorObject->second.end()) | 
 | 462 |     { | 
| James Feist | 0cd014a | 2019-04-08 15:04:33 -0700 | [diff] [blame] | 463 |         return ipmi::responseResponseError(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 464 |     } | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 465 |     auto& valueVariant = sensorObject->second["Value"]; | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 466 |     double reading = std::visit(VariantToDoubleVisitor(), valueVariant); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 467 |  | 
| Yong Li | 1f2eb5e | 2019-05-23 14:07:17 +0800 | [diff] [blame] | 468 |     double max = 0; | 
 | 469 |     double min = 0; | 
| James Feist | aecaef7 | 2019-04-26 10:30:32 -0700 | [diff] [blame] | 470 |     getSensorMaxMin(sensorMap, max, min); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 471 |  | 
 | 472 |     int16_t mValue = 0; | 
 | 473 |     int16_t bValue = 0; | 
 | 474 |     int8_t rExp = 0; | 
 | 475 |     int8_t bExp = 0; | 
 | 476 |     bool bSigned = false; | 
 | 477 |  | 
 | 478 |     if (!getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned)) | 
 | 479 |     { | 
| James Feist | 0cd014a | 2019-04-08 15:04:33 -0700 | [diff] [blame] | 480 |         return ipmi::responseResponseError(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 481 |     } | 
 | 482 |  | 
| James Feist | 0cd014a | 2019-04-08 15:04:33 -0700 | [diff] [blame] | 483 |     uint8_t value = | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 484 |         scaleIPMIValueFromDouble(reading, mValue, rExp, bValue, bExp, bSigned); | 
| James Feist | 0cd014a | 2019-04-08 15:04:33 -0700 | [diff] [blame] | 485 |     uint8_t operation = | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 486 |         static_cast<uint8_t>(IPMISensorReadingByte2::sensorScanningEnable); | 
| James Feist | 0cd014a | 2019-04-08 15:04:33 -0700 | [diff] [blame] | 487 |     operation |= | 
| James Feist | 81a95c1 | 2019-03-01 15:08:28 -0800 | [diff] [blame] | 488 |         static_cast<uint8_t>(IPMISensorReadingByte2::eventMessagesEnable); | 
| James Feist | 1ee6ed8 | 2020-06-17 16:16:50 -0700 | [diff] [blame] | 489 |     bool notReading = std::isnan(reading); | 
 | 490 |  | 
 | 491 |     if (!notReading) | 
 | 492 |     { | 
 | 493 |         auto availableObject = | 
 | 494 |             sensorMap.find("xyz.openbmc_project.State.Decorator.Availability"); | 
 | 495 |         if (availableObject != sensorMap.end()) | 
 | 496 |         { | 
 | 497 |             auto findAvailable = availableObject->second.find("Available"); | 
 | 498 |             if (findAvailable != availableObject->second.end()) | 
 | 499 |             { | 
 | 500 |                 bool* available = std::get_if<bool>(&(findAvailable->second)); | 
 | 501 |                 if (available && !(*available)) | 
 | 502 |                 { | 
 | 503 |                     notReading = true; | 
 | 504 |                 } | 
 | 505 |             } | 
 | 506 |         } | 
 | 507 |     } | 
 | 508 |  | 
 | 509 |     if (notReading) | 
 | 510 |     { | 
 | 511 |         operation |= static_cast<uint8_t>( | 
 | 512 |             IPMISensorReadingByte2::readingStateUnavailable); | 
 | 513 |     } | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 514 |  | 
| Josh Lehan | 06aa21a | 2020-10-28 21:59:06 -0700 | [diff] [blame] | 515 |     int byteValue; | 
 | 516 |     if (bSigned) | 
 | 517 |     { | 
 | 518 |         byteValue = static_cast<int>(static_cast<int8_t>(value)); | 
 | 519 |     } | 
 | 520 |     else | 
 | 521 |     { | 
 | 522 |         byteValue = static_cast<int>(static_cast<uint8_t>(value)); | 
 | 523 |     } | 
 | 524 |  | 
 | 525 |     // Keep stats on the reading just obtained, even if it is "NaN" | 
 | 526 |     if (details::sdrStatsTable.updateReading(sensnum, reading, byteValue)) | 
 | 527 |     { | 
 | 528 |         // This is the first reading, show the coefficients | 
 | 529 |         double step = (max - min) / 255.0; | 
 | 530 |         std::cerr << "IPMI sensor " << details::sdrStatsTable.getName(sensnum) | 
 | 531 |                   << ": Range min=" << min << " max=" << max | 
 | 532 |                   << ", step=" << step | 
 | 533 |                   << ", Coefficients mValue=" << static_cast<int>(mValue) | 
 | 534 |                   << " rExp=" << static_cast<int>(rExp) | 
 | 535 |                   << " bValue=" << static_cast<int>(bValue) | 
 | 536 |                   << " bExp=" << static_cast<int>(bExp) | 
 | 537 |                   << " bSigned=" << static_cast<int>(bSigned) << "\n"; | 
 | 538 |     }; | 
 | 539 |  | 
| James Feist | 0cd014a | 2019-04-08 15:04:33 -0700 | [diff] [blame] | 540 |     uint8_t thresholds = 0; | 
 | 541 |  | 
 | 542 |     auto warningObject = | 
 | 543 |         sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning"); | 
 | 544 |     if (warningObject != sensorMap.end()) | 
 | 545 |     { | 
 | 546 |         auto alarmHigh = warningObject->second.find("WarningAlarmHigh"); | 
 | 547 |         auto alarmLow = warningObject->second.find("WarningAlarmLow"); | 
 | 548 |         if (alarmHigh != warningObject->second.end()) | 
 | 549 |         { | 
 | 550 |             if (std::get<bool>(alarmHigh->second)) | 
 | 551 |             { | 
 | 552 |                 thresholds |= static_cast<uint8_t>( | 
 | 553 |                     IPMISensorReadingByte3::upperNonCritical); | 
 | 554 |             } | 
 | 555 |         } | 
 | 556 |         if (alarmLow != warningObject->second.end()) | 
 | 557 |         { | 
 | 558 |             if (std::get<bool>(alarmLow->second)) | 
 | 559 |             { | 
 | 560 |                 thresholds |= static_cast<uint8_t>( | 
 | 561 |                     IPMISensorReadingByte3::lowerNonCritical); | 
 | 562 |             } | 
 | 563 |         } | 
 | 564 |     } | 
 | 565 |  | 
 | 566 |     auto criticalObject = | 
 | 567 |         sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical"); | 
 | 568 |     if (criticalObject != sensorMap.end()) | 
 | 569 |     { | 
 | 570 |         auto alarmHigh = criticalObject->second.find("CriticalAlarmHigh"); | 
 | 571 |         auto alarmLow = criticalObject->second.find("CriticalAlarmLow"); | 
 | 572 |         if (alarmHigh != criticalObject->second.end()) | 
 | 573 |         { | 
 | 574 |             if (std::get<bool>(alarmHigh->second)) | 
 | 575 |             { | 
 | 576 |                 thresholds |= | 
 | 577 |                     static_cast<uint8_t>(IPMISensorReadingByte3::upperCritical); | 
 | 578 |             } | 
 | 579 |         } | 
 | 580 |         if (alarmLow != criticalObject->second.end()) | 
 | 581 |         { | 
 | 582 |             if (std::get<bool>(alarmLow->second)) | 
 | 583 |             { | 
 | 584 |                 thresholds |= | 
 | 585 |                     static_cast<uint8_t>(IPMISensorReadingByte3::lowerCritical); | 
 | 586 |             } | 
 | 587 |         } | 
 | 588 |     } | 
 | 589 |  | 
 | 590 |     // no discrete as of today so optional byte is never returned | 
 | 591 |     return ipmi::responseSuccess(value, operation, thresholds, std::nullopt); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 592 | } | 
 | 593 |  | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 594 | /** @brief implements the Set Sensor threshold command | 
 | 595 |  *  @param sensorNumber        - sensor number | 
 | 596 |  *  @param lowerNonCriticalThreshMask | 
 | 597 |  *  @param lowerCriticalThreshMask | 
 | 598 |  *  @param lowerNonRecovThreshMask | 
 | 599 |  *  @param upperNonCriticalThreshMask | 
 | 600 |  *  @param upperCriticalThreshMask | 
 | 601 |  *  @param upperNonRecovThreshMask | 
 | 602 |  *  @param reserved | 
 | 603 |  *  @param lowerNonCritical    - lower non-critical threshold | 
 | 604 |  *  @param lowerCritical       - Lower critical threshold | 
 | 605 |  *  @param lowerNonRecoverable - Lower non recovarable threshold | 
 | 606 |  *  @param upperNonCritical    - Upper non-critical threshold | 
 | 607 |  *  @param upperCritical       - Upper critical | 
 | 608 |  *  @param upperNonRecoverable - Upper Non-recoverable | 
 | 609 |  * | 
 | 610 |  *  @returns IPMI completion code | 
 | 611 |  */ | 
 | 612 | ipmi::RspType<> ipmiSenSetSensorThresholds( | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 613 |     ipmi::Context::ptr ctx, uint8_t sensorNum, bool lowerNonCriticalThreshMask, | 
 | 614 |     bool lowerCriticalThreshMask, bool lowerNonRecovThreshMask, | 
 | 615 |     bool upperNonCriticalThreshMask, bool upperCriticalThreshMask, | 
 | 616 |     bool upperNonRecovThreshMask, uint2_t reserved, uint8_t lowerNonCritical, | 
 | 617 |     uint8_t lowerCritical, uint8_t lowerNonRecoverable, | 
 | 618 |     uint8_t upperNonCritical, uint8_t upperCritical, | 
 | 619 |     uint8_t upperNonRecoverable) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 620 | { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 621 |     constexpr uint8_t thresholdMask = 0xFF; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 622 |  | 
| Chalapathi Venkataramashetty | 339fc56 | 2021-06-13 19:51:17 +0000 | [diff] [blame] | 623 |     if (sensorNum == reservedSensorNumber) | 
 | 624 |     { | 
 | 625 |         return ipmi::responseInvalidFieldRequest(); | 
 | 626 |     } | 
 | 627 |  | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 628 |     if (reserved) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 629 |     { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 630 |         return ipmi::responseInvalidFieldRequest(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 631 |     } | 
 | 632 |  | 
 | 633 |     // lower nc and upper nc not suppported on any sensor | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 634 |     if (lowerNonRecovThreshMask || upperNonRecovThreshMask) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 635 |     { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 636 |         return ipmi::responseInvalidFieldRequest(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 637 |     } | 
 | 638 |  | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 639 |     // if none of the threshold mask are set, nothing to do | 
 | 640 |     if (!(lowerNonCriticalThreshMask | lowerCriticalThreshMask | | 
 | 641 |           lowerNonRecovThreshMask | upperNonCriticalThreshMask | | 
 | 642 |           upperCriticalThreshMask | upperNonRecovThreshMask)) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 643 |     { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 644 |         return ipmi::responseSuccess(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 645 |     } | 
 | 646 |  | 
 | 647 |     std::string connection; | 
 | 648 |     std::string path; | 
 | 649 |  | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 650 |     ipmi::Cc status = getSensorConnection(ctx, sensorNum, connection, path); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 651 |     if (status) | 
 | 652 |     { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 653 |         return ipmi::response(status); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 654 |     } | 
 | 655 |     SensorMap sensorMap; | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 656 |     if (!getSensorMap(ctx->yield, connection, path, sensorMap)) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 657 |     { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 658 |         return ipmi::responseResponseError(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 659 |     } | 
 | 660 |  | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 661 |     double max = 0; | 
 | 662 |     double min = 0; | 
| James Feist | aecaef7 | 2019-04-26 10:30:32 -0700 | [diff] [blame] | 663 |     getSensorMaxMin(sensorMap, max, min); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 664 |  | 
 | 665 |     int16_t mValue = 0; | 
 | 666 |     int16_t bValue = 0; | 
 | 667 |     int8_t rExp = 0; | 
 | 668 |     int8_t bExp = 0; | 
 | 669 |     bool bSigned = false; | 
 | 670 |  | 
 | 671 |     if (!getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned)) | 
 | 672 |     { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 673 |         return ipmi::responseResponseError(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 674 |     } | 
 | 675 |  | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 676 |     // store a vector of property name, value to set, and interface | 
 | 677 |     std::vector<std::tuple<std::string, uint8_t, std::string>> thresholdsToSet; | 
 | 678 |  | 
 | 679 |     // define the indexes of the tuple | 
 | 680 |     constexpr uint8_t propertyName = 0; | 
 | 681 |     constexpr uint8_t thresholdValue = 1; | 
 | 682 |     constexpr uint8_t interface = 2; | 
 | 683 |     // verifiy all needed fields are present | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 684 |     if (lowerCriticalThreshMask || upperCriticalThreshMask) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 685 |     { | 
 | 686 |         auto findThreshold = | 
 | 687 |             sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical"); | 
 | 688 |         if (findThreshold == sensorMap.end()) | 
 | 689 |         { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 690 |             return ipmi::responseInvalidFieldRequest(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 691 |         } | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 692 |         if (lowerCriticalThreshMask) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 693 |         { | 
 | 694 |             auto findLower = findThreshold->second.find("CriticalLow"); | 
 | 695 |             if (findLower == findThreshold->second.end()) | 
 | 696 |             { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 697 |                 return ipmi::responseInvalidFieldRequest(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 698 |             } | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 699 |             thresholdsToSet.emplace_back("CriticalLow", lowerCritical, | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 700 |                                          findThreshold->first); | 
 | 701 |         } | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 702 |         if (upperCriticalThreshMask) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 703 |         { | 
 | 704 |             auto findUpper = findThreshold->second.find("CriticalHigh"); | 
 | 705 |             if (findUpper == findThreshold->second.end()) | 
 | 706 |             { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 707 |                 return ipmi::responseInvalidFieldRequest(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 708 |             } | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 709 |             thresholdsToSet.emplace_back("CriticalHigh", upperCritical, | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 710 |                                          findThreshold->first); | 
 | 711 |         } | 
 | 712 |     } | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 713 |     if (lowerNonCriticalThreshMask || upperNonCriticalThreshMask) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 714 |     { | 
 | 715 |         auto findThreshold = | 
 | 716 |             sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning"); | 
 | 717 |         if (findThreshold == sensorMap.end()) | 
 | 718 |         { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 719 |             return ipmi::responseInvalidFieldRequest(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 720 |         } | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 721 |         if (lowerNonCriticalThreshMask) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 722 |         { | 
 | 723 |             auto findLower = findThreshold->second.find("WarningLow"); | 
 | 724 |             if (findLower == findThreshold->second.end()) | 
 | 725 |             { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 726 |                 return ipmi::responseInvalidFieldRequest(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 727 |             } | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 728 |             thresholdsToSet.emplace_back("WarningLow", lowerNonCritical, | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 729 |                                          findThreshold->first); | 
 | 730 |         } | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 731 |         if (upperNonCriticalThreshMask) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 732 |         { | 
 | 733 |             auto findUpper = findThreshold->second.find("WarningHigh"); | 
 | 734 |             if (findUpper == findThreshold->second.end()) | 
 | 735 |             { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 736 |                 return ipmi::responseInvalidFieldRequest(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 737 |             } | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 738 |             thresholdsToSet.emplace_back("WarningHigh", upperNonCritical, | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 739 |                                          findThreshold->first); | 
 | 740 |         } | 
 | 741 |     } | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 742 |     for (const auto& property : thresholdsToSet) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 743 |     { | 
 | 744 |         // from section 36.3 in the IPMI Spec, assume all linear | 
 | 745 |         double valueToSet = ((mValue * std::get<thresholdValue>(property)) + | 
| Josh Lehan | 86236a2 | 2019-11-18 17:53:33 -0800 | [diff] [blame] | 746 |                              (bValue * std::pow(10.0, bExp))) * | 
 | 747 |                             std::pow(10.0, rExp); | 
| Vernon Mauery | 15419dd | 2019-05-24 09:40:30 -0700 | [diff] [blame] | 748 |         setDbusProperty( | 
 | 749 |             *getSdBus(), connection, path, std::get<interface>(property), | 
 | 750 |             std::get<propertyName>(property), ipmi::Value(valueToSet)); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 751 |     } | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 752 |     return ipmi::responseSuccess(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 753 | } | 
 | 754 |  | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 755 | IPMIThresholds getIPMIThresholds(const SensorMap& sensorMap) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 756 | { | 
| James Feist | 902c4c5 | 2019-04-16 14:51:31 -0700 | [diff] [blame] | 757 |     IPMIThresholds resp; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 758 |     auto warningInterface = | 
 | 759 |         sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning"); | 
 | 760 |     auto criticalInterface = | 
 | 761 |         sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical"); | 
 | 762 |  | 
 | 763 |     if ((warningInterface != sensorMap.end()) || | 
 | 764 |         (criticalInterface != sensorMap.end())) | 
 | 765 |     { | 
 | 766 |         auto sensorPair = sensorMap.find("xyz.openbmc_project.Sensor.Value"); | 
 | 767 |  | 
 | 768 |         if (sensorPair == sensorMap.end()) | 
 | 769 |         { | 
 | 770 |             // should not have been able to find a sensor not implementing | 
 | 771 |             // the sensor object | 
| James Feist | 902c4c5 | 2019-04-16 14:51:31 -0700 | [diff] [blame] | 772 |             throw std::runtime_error("Invalid sensor map"); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 773 |         } | 
 | 774 |  | 
| Chen,Yugang | 606dd9f | 2019-07-01 10:37:30 +0800 | [diff] [blame] | 775 |         double max = 0; | 
 | 776 |         double min = 0; | 
| James Feist | aecaef7 | 2019-04-26 10:30:32 -0700 | [diff] [blame] | 777 |         getSensorMaxMin(sensorMap, max, min); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 778 |  | 
 | 779 |         int16_t mValue = 0; | 
 | 780 |         int16_t bValue = 0; | 
 | 781 |         int8_t rExp = 0; | 
 | 782 |         int8_t bExp = 0; | 
 | 783 |         bool bSigned = false; | 
 | 784 |  | 
 | 785 |         if (!getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned)) | 
 | 786 |         { | 
| James Feist | 902c4c5 | 2019-04-16 14:51:31 -0700 | [diff] [blame] | 787 |             throw std::runtime_error("Invalid sensor atrributes"); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 788 |         } | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 789 |         if (warningInterface != sensorMap.end()) | 
 | 790 |         { | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 791 |             auto& warningMap = warningInterface->second; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 792 |  | 
 | 793 |             auto warningHigh = warningMap.find("WarningHigh"); | 
 | 794 |             auto warningLow = warningMap.find("WarningLow"); | 
 | 795 |  | 
 | 796 |             if (warningHigh != warningMap.end()) | 
 | 797 |             { | 
| James Feist | 902c4c5 | 2019-04-16 14:51:31 -0700 | [diff] [blame] | 798 |  | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 799 |                 double value = | 
 | 800 |                     std::visit(VariantToDoubleVisitor(), warningHigh->second); | 
| James Feist | 902c4c5 | 2019-04-16 14:51:31 -0700 | [diff] [blame] | 801 |                 resp.warningHigh = scaleIPMIValueFromDouble( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 802 |                     value, mValue, rExp, bValue, bExp, bSigned); | 
 | 803 |             } | 
 | 804 |             if (warningLow != warningMap.end()) | 
 | 805 |             { | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 806 |                 double value = | 
 | 807 |                     std::visit(VariantToDoubleVisitor(), warningLow->second); | 
| James Feist | 902c4c5 | 2019-04-16 14:51:31 -0700 | [diff] [blame] | 808 |                 resp.warningLow = scaleIPMIValueFromDouble( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 809 |                     value, mValue, rExp, bValue, bExp, bSigned); | 
 | 810 |             } | 
 | 811 |         } | 
 | 812 |         if (criticalInterface != sensorMap.end()) | 
 | 813 |         { | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 814 |             auto& criticalMap = criticalInterface->second; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 815 |  | 
 | 816 |             auto criticalHigh = criticalMap.find("CriticalHigh"); | 
 | 817 |             auto criticalLow = criticalMap.find("CriticalLow"); | 
 | 818 |  | 
 | 819 |             if (criticalHigh != criticalMap.end()) | 
 | 820 |             { | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 821 |                 double value = | 
 | 822 |                     std::visit(VariantToDoubleVisitor(), criticalHigh->second); | 
| James Feist | 902c4c5 | 2019-04-16 14:51:31 -0700 | [diff] [blame] | 823 |                 resp.criticalHigh = scaleIPMIValueFromDouble( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 824 |                     value, mValue, rExp, bValue, bExp, bSigned); | 
 | 825 |             } | 
 | 826 |             if (criticalLow != criticalMap.end()) | 
 | 827 |             { | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 828 |                 double value = | 
 | 829 |                     std::visit(VariantToDoubleVisitor(), criticalLow->second); | 
| James Feist | 902c4c5 | 2019-04-16 14:51:31 -0700 | [diff] [blame] | 830 |                 resp.criticalLow = scaleIPMIValueFromDouble( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 831 |                     value, mValue, rExp, bValue, bExp, bSigned); | 
 | 832 |             } | 
 | 833 |         } | 
 | 834 |     } | 
| James Feist | 902c4c5 | 2019-04-16 14:51:31 -0700 | [diff] [blame] | 835 |     return resp; | 
 | 836 | } | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 837 |  | 
| James Feist | 902c4c5 | 2019-04-16 14:51:31 -0700 | [diff] [blame] | 838 | ipmi::RspType<uint8_t, // readable | 
 | 839 |               uint8_t, // lowerNCrit | 
 | 840 |               uint8_t, // lowerCrit | 
 | 841 |               uint8_t, // lowerNrecoverable | 
 | 842 |               uint8_t, // upperNC | 
 | 843 |               uint8_t, // upperCrit | 
 | 844 |               uint8_t> // upperNRecoverable | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 845 |     ipmiSenGetSensorThresholds(ipmi::Context::ptr ctx, uint8_t sensorNumber) | 
| James Feist | 902c4c5 | 2019-04-16 14:51:31 -0700 | [diff] [blame] | 846 | { | 
 | 847 |     std::string connection; | 
 | 848 |     std::string path; | 
 | 849 |  | 
| Chalapathi Venkataramashetty | 339fc56 | 2021-06-13 19:51:17 +0000 | [diff] [blame] | 850 |     if (sensorNumber == reservedSensorNumber) | 
 | 851 |     { | 
 | 852 |         return ipmi::responseInvalidFieldRequest(); | 
 | 853 |     } | 
 | 854 |  | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 855 |     auto status = getSensorConnection(ctx, sensorNumber, connection, path); | 
| James Feist | 902c4c5 | 2019-04-16 14:51:31 -0700 | [diff] [blame] | 856 |     if (status) | 
 | 857 |     { | 
 | 858 |         return ipmi::response(status); | 
 | 859 |     } | 
 | 860 |  | 
 | 861 |     SensorMap sensorMap; | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 862 |     if (!getSensorMap(ctx->yield, connection, path, sensorMap)) | 
| James Feist | 902c4c5 | 2019-04-16 14:51:31 -0700 | [diff] [blame] | 863 |     { | 
 | 864 |         return ipmi::responseResponseError(); | 
 | 865 |     } | 
 | 866 |  | 
 | 867 |     IPMIThresholds thresholdData; | 
 | 868 |     try | 
 | 869 |     { | 
 | 870 |         thresholdData = getIPMIThresholds(sensorMap); | 
 | 871 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 872 |     catch (const std::exception&) | 
| James Feist | 902c4c5 | 2019-04-16 14:51:31 -0700 | [diff] [blame] | 873 |     { | 
 | 874 |         return ipmi::responseResponseError(); | 
 | 875 |     } | 
 | 876 |  | 
 | 877 |     uint8_t readable = 0; | 
 | 878 |     uint8_t lowerNC = 0; | 
 | 879 |     uint8_t lowerCritical = 0; | 
 | 880 |     uint8_t lowerNonRecoverable = 0; | 
 | 881 |     uint8_t upperNC = 0; | 
 | 882 |     uint8_t upperCritical = 0; | 
 | 883 |     uint8_t upperNonRecoverable = 0; | 
 | 884 |  | 
 | 885 |     if (thresholdData.warningHigh) | 
 | 886 |     { | 
 | 887 |         readable |= | 
 | 888 |             1 << static_cast<uint8_t>(IPMIThresholdRespBits::upperNonCritical); | 
 | 889 |         upperNC = *thresholdData.warningHigh; | 
 | 890 |     } | 
 | 891 |     if (thresholdData.warningLow) | 
 | 892 |     { | 
 | 893 |         readable |= | 
 | 894 |             1 << static_cast<uint8_t>(IPMIThresholdRespBits::lowerNonCritical); | 
 | 895 |         lowerNC = *thresholdData.warningLow; | 
 | 896 |     } | 
 | 897 |  | 
 | 898 |     if (thresholdData.criticalHigh) | 
 | 899 |     { | 
 | 900 |         readable |= | 
 | 901 |             1 << static_cast<uint8_t>(IPMIThresholdRespBits::upperCritical); | 
 | 902 |         upperCritical = *thresholdData.criticalHigh; | 
 | 903 |     } | 
 | 904 |     if (thresholdData.criticalLow) | 
 | 905 |     { | 
 | 906 |         readable |= | 
 | 907 |             1 << static_cast<uint8_t>(IPMIThresholdRespBits::lowerCritical); | 
 | 908 |         lowerCritical = *thresholdData.criticalLow; | 
 | 909 |     } | 
 | 910 |  | 
 | 911 |     return ipmi::responseSuccess(readable, lowerNC, lowerCritical, | 
 | 912 |                                  lowerNonRecoverable, upperNC, upperCritical, | 
 | 913 |                                  upperNonRecoverable); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 914 | } | 
 | 915 |  | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 916 | /** @brief implements the get Sensor event enable command | 
 | 917 |  *  @param sensorNumber - sensor number | 
 | 918 |  * | 
 | 919 |  *  @returns IPMI completion code plus response data | 
 | 920 |  *   - enabled               - Sensor Event messages | 
 | 921 |  *   - assertionEnabledLsb   - Assertion event messages | 
 | 922 |  *   - assertionEnabledMsb   - Assertion event messages | 
 | 923 |  *   - deassertionEnabledLsb - Deassertion event messages | 
 | 924 |  *   - deassertionEnabledMsb - Deassertion event messages | 
 | 925 |  */ | 
 | 926 |  | 
 | 927 | ipmi::RspType<uint8_t, // enabled | 
 | 928 |               uint8_t, // assertionEnabledLsb | 
 | 929 |               uint8_t, // assertionEnabledMsb | 
 | 930 |               uint8_t, // deassertionEnabledLsb | 
 | 931 |               uint8_t> // deassertionEnabledMsb | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 932 |     ipmiSenGetSensorEventEnable(ipmi::Context::ptr ctx, uint8_t sensorNum) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 933 | { | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 934 |     std::string connection; | 
 | 935 |     std::string path; | 
 | 936 |  | 
| Patrick Venture | a41714c | 2019-09-25 16:59:41 -0700 | [diff] [blame] | 937 |     uint8_t enabled = 0; | 
 | 938 |     uint8_t assertionEnabledLsb = 0; | 
 | 939 |     uint8_t assertionEnabledMsb = 0; | 
 | 940 |     uint8_t deassertionEnabledLsb = 0; | 
 | 941 |     uint8_t deassertionEnabledMsb = 0; | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 942 |  | 
| Chalapathi Venkataramashetty | 339fc56 | 2021-06-13 19:51:17 +0000 | [diff] [blame] | 943 |     if (sensorNum == reservedSensorNumber) | 
 | 944 |     { | 
 | 945 |         return ipmi::responseInvalidFieldRequest(); | 
 | 946 |     } | 
 | 947 |  | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 948 |     auto status = getSensorConnection(ctx, sensorNum, connection, path); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 949 |     if (status) | 
 | 950 |     { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 951 |         return ipmi::response(status); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 952 |     } | 
 | 953 |  | 
 | 954 |     SensorMap sensorMap; | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 955 |     if (!getSensorMap(ctx->yield, connection, path, sensorMap)) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 956 |     { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 957 |         return ipmi::responseResponseError(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 958 |     } | 
 | 959 |  | 
 | 960 |     auto warningInterface = | 
 | 961 |         sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning"); | 
 | 962 |     auto criticalInterface = | 
 | 963 |         sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical"); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 964 |     if ((warningInterface != sensorMap.end()) || | 
 | 965 |         (criticalInterface != sensorMap.end())) | 
 | 966 |     { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 967 |         enabled = static_cast<uint8_t>( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 968 |             IPMISensorEventEnableByte2::sensorScanningEnable); | 
 | 969 |         if (warningInterface != sensorMap.end()) | 
 | 970 |         { | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 971 |             auto& warningMap = warningInterface->second; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 972 |  | 
 | 973 |             auto warningHigh = warningMap.find("WarningHigh"); | 
 | 974 |             auto warningLow = warningMap.find("WarningLow"); | 
 | 975 |             if (warningHigh != warningMap.end()) | 
 | 976 |             { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 977 |                 assertionEnabledLsb |= static_cast<uint8_t>( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 978 |                     IPMISensorEventEnableThresholds::upperNonCriticalGoingHigh); | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 979 |                 deassertionEnabledLsb |= static_cast<uint8_t>( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 980 |                     IPMISensorEventEnableThresholds::upperNonCriticalGoingLow); | 
 | 981 |             } | 
 | 982 |             if (warningLow != warningMap.end()) | 
 | 983 |             { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 984 |                 assertionEnabledLsb |= static_cast<uint8_t>( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 985 |                     IPMISensorEventEnableThresholds::lowerNonCriticalGoingLow); | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 986 |                 deassertionEnabledLsb |= static_cast<uint8_t>( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 987 |                     IPMISensorEventEnableThresholds::lowerNonCriticalGoingHigh); | 
 | 988 |             } | 
 | 989 |         } | 
 | 990 |         if (criticalInterface != sensorMap.end()) | 
 | 991 |         { | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 992 |             auto& criticalMap = criticalInterface->second; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 993 |  | 
 | 994 |             auto criticalHigh = criticalMap.find("CriticalHigh"); | 
 | 995 |             auto criticalLow = criticalMap.find("CriticalLow"); | 
 | 996 |  | 
 | 997 |             if (criticalHigh != criticalMap.end()) | 
 | 998 |             { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 999 |                 assertionEnabledMsb |= static_cast<uint8_t>( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1000 |                     IPMISensorEventEnableThresholds::upperCriticalGoingHigh); | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 1001 |                 deassertionEnabledMsb |= static_cast<uint8_t>( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1002 |                     IPMISensorEventEnableThresholds::upperCriticalGoingLow); | 
 | 1003 |             } | 
 | 1004 |             if (criticalLow != criticalMap.end()) | 
 | 1005 |             { | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 1006 |                 assertionEnabledLsb |= static_cast<uint8_t>( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1007 |                     IPMISensorEventEnableThresholds::lowerCriticalGoingLow); | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 1008 |                 deassertionEnabledLsb |= static_cast<uint8_t>( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1009 |                     IPMISensorEventEnableThresholds::lowerCriticalGoingHigh); | 
 | 1010 |             } | 
 | 1011 |         } | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1012 |     } | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 1013 |  | 
 | 1014 |     return ipmi::responseSuccess(enabled, assertionEnabledLsb, | 
 | 1015 |                                  assertionEnabledMsb, deassertionEnabledLsb, | 
 | 1016 |                                  deassertionEnabledMsb); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1017 | } | 
 | 1018 |  | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1019 | /** @brief implements the get Sensor event status command | 
 | 1020 |  *  @param sensorNumber - sensor number, FFh = reserved | 
 | 1021 |  * | 
 | 1022 |  *  @returns IPMI completion code plus response data | 
 | 1023 |  *   - sensorEventStatus - Sensor Event messages state | 
 | 1024 |  *   - assertions        - Assertion event messages | 
 | 1025 |  *   - deassertions      - Deassertion event messages | 
 | 1026 |  */ | 
 | 1027 | ipmi::RspType<uint8_t,         // sensorEventStatus | 
 | 1028 |               std::bitset<16>, // assertions | 
 | 1029 |               std::bitset<16>  // deassertion | 
 | 1030 |               > | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1031 |     ipmiSenGetSensorEventStatus(ipmi::Context::ptr ctx, uint8_t sensorNum) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1032 | { | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1033 |     if (sensorNum == reservedSensorNumber) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1034 |     { | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1035 |         return ipmi::responseInvalidFieldRequest(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1036 |     } | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1037 |  | 
 | 1038 |     std::string connection; | 
 | 1039 |     std::string path; | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1040 |     auto status = getSensorConnection(ctx, sensorNum, connection, path); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1041 |     if (status) | 
 | 1042 |     { | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1043 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1044 |             "ipmiSenGetSensorEventStatus: Sensor connection Error", | 
 | 1045 |             phosphor::logging::entry("SENSOR=%d", sensorNum)); | 
 | 1046 |         return ipmi::response(status); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1047 |     } | 
 | 1048 |  | 
 | 1049 |     SensorMap sensorMap; | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1050 |     if (!getSensorMap(ctx->yield, connection, path, sensorMap)) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1051 |     { | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1052 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1053 |             "ipmiSenGetSensorEventStatus: Sensor Mapping Error", | 
 | 1054 |             phosphor::logging::entry("SENSOR=%s", path.c_str())); | 
 | 1055 |         return ipmi::responseResponseError(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1056 |     } | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1057 |     auto warningInterface = | 
 | 1058 |         sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Warning"); | 
 | 1059 |     auto criticalInterface = | 
 | 1060 |         sensorMap.find("xyz.openbmc_project.Sensor.Threshold.Critical"); | 
 | 1061 |  | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1062 |     uint8_t sensorEventStatus = | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1063 |         static_cast<uint8_t>(IPMISensorEventEnableByte2::sensorScanningEnable); | 
 | 1064 |  | 
| James Feist | 392786a | 2019-03-19 13:36:10 -0700 | [diff] [blame] | 1065 |     std::optional<bool> criticalDeassertHigh = | 
 | 1066 |         thresholdDeassertMap[path]["CriticalAlarmHigh"]; | 
 | 1067 |     std::optional<bool> criticalDeassertLow = | 
 | 1068 |         thresholdDeassertMap[path]["CriticalAlarmLow"]; | 
 | 1069 |     std::optional<bool> warningDeassertHigh = | 
 | 1070 |         thresholdDeassertMap[path]["WarningAlarmHigh"]; | 
 | 1071 |     std::optional<bool> warningDeassertLow = | 
 | 1072 |         thresholdDeassertMap[path]["WarningAlarmLow"]; | 
 | 1073 |  | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1074 |     std::bitset<16> assertions = 0; | 
 | 1075 |     std::bitset<16> deassertions = 0; | 
 | 1076 |  | 
| James Feist | 392786a | 2019-03-19 13:36:10 -0700 | [diff] [blame] | 1077 |     if (criticalDeassertHigh && !*criticalDeassertHigh) | 
 | 1078 |     { | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1079 |         deassertions.set(static_cast<size_t>( | 
 | 1080 |             IPMIGetSensorEventEnableThresholds::upperCriticalGoingHigh)); | 
| James Feist | 392786a | 2019-03-19 13:36:10 -0700 | [diff] [blame] | 1081 |     } | 
 | 1082 |     if (criticalDeassertLow && !*criticalDeassertLow) | 
 | 1083 |     { | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1084 |         deassertions.set(static_cast<size_t>( | 
 | 1085 |             IPMIGetSensorEventEnableThresholds::upperCriticalGoingLow)); | 
| James Feist | 392786a | 2019-03-19 13:36:10 -0700 | [diff] [blame] | 1086 |     } | 
 | 1087 |     if (warningDeassertHigh && !*warningDeassertHigh) | 
 | 1088 |     { | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1089 |         deassertions.set(static_cast<size_t>( | 
 | 1090 |             IPMIGetSensorEventEnableThresholds::upperNonCriticalGoingHigh)); | 
| James Feist | 392786a | 2019-03-19 13:36:10 -0700 | [diff] [blame] | 1091 |     } | 
 | 1092 |     if (warningDeassertLow && !*warningDeassertLow) | 
 | 1093 |     { | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1094 |         deassertions.set(static_cast<size_t>( | 
 | 1095 |             IPMIGetSensorEventEnableThresholds::lowerNonCriticalGoingHigh)); | 
| James Feist | 392786a | 2019-03-19 13:36:10 -0700 | [diff] [blame] | 1096 |     } | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1097 |     if ((warningInterface != sensorMap.end()) || | 
 | 1098 |         (criticalInterface != sensorMap.end())) | 
 | 1099 |     { | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1100 |         sensorEventStatus = static_cast<size_t>( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1101 |             IPMISensorEventEnableByte2::eventMessagesEnable); | 
 | 1102 |         if (warningInterface != sensorMap.end()) | 
 | 1103 |         { | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 1104 |             auto& warningMap = warningInterface->second; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1105 |  | 
 | 1106 |             auto warningHigh = warningMap.find("WarningAlarmHigh"); | 
 | 1107 |             auto warningLow = warningMap.find("WarningAlarmLow"); | 
 | 1108 |             auto warningHighAlarm = false; | 
 | 1109 |             auto warningLowAlarm = false; | 
 | 1110 |  | 
 | 1111 |             if (warningHigh != warningMap.end()) | 
 | 1112 |             { | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 1113 |                 warningHighAlarm = std::get<bool>(warningHigh->second); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1114 |             } | 
 | 1115 |             if (warningLow != warningMap.end()) | 
 | 1116 |             { | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 1117 |                 warningLowAlarm = std::get<bool>(warningLow->second); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1118 |             } | 
 | 1119 |             if (warningHighAlarm) | 
 | 1120 |             { | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1121 |                 assertions.set( | 
 | 1122 |                     static_cast<size_t>(IPMIGetSensorEventEnableThresholds:: | 
 | 1123 |                                             upperNonCriticalGoingHigh)); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1124 |             } | 
 | 1125 |             if (warningLowAlarm) | 
 | 1126 |             { | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1127 |                 assertions.set( | 
 | 1128 |                     static_cast<size_t>(IPMIGetSensorEventEnableThresholds:: | 
 | 1129 |                                             lowerNonCriticalGoingLow)); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1130 |             } | 
 | 1131 |         } | 
 | 1132 |         if (criticalInterface != sensorMap.end()) | 
 | 1133 |         { | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 1134 |             auto& criticalMap = criticalInterface->second; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1135 |  | 
 | 1136 |             auto criticalHigh = criticalMap.find("CriticalAlarmHigh"); | 
 | 1137 |             auto criticalLow = criticalMap.find("CriticalAlarmLow"); | 
 | 1138 |             auto criticalHighAlarm = false; | 
 | 1139 |             auto criticalLowAlarm = false; | 
 | 1140 |  | 
 | 1141 |             if (criticalHigh != criticalMap.end()) | 
 | 1142 |             { | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 1143 |                 criticalHighAlarm = std::get<bool>(criticalHigh->second); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1144 |             } | 
 | 1145 |             if (criticalLow != criticalMap.end()) | 
 | 1146 |             { | 
| Vernon Mauery | 8166c8d | 2019-05-23 11:22:30 -0700 | [diff] [blame] | 1147 |                 criticalLowAlarm = std::get<bool>(criticalLow->second); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1148 |             } | 
 | 1149 |             if (criticalHighAlarm) | 
 | 1150 |             { | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1151 |                 assertions.set( | 
 | 1152 |                     static_cast<size_t>(IPMIGetSensorEventEnableThresholds:: | 
 | 1153 |                                             upperCriticalGoingHigh)); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1154 |             } | 
 | 1155 |             if (criticalLowAlarm) | 
 | 1156 |             { | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1157 |                 assertions.set(static_cast<size_t>( | 
 | 1158 |                     IPMIGetSensorEventEnableThresholds::lowerCriticalGoingLow)); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1159 |             } | 
 | 1160 |         } | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1161 |     } | 
 | 1162 |  | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1163 |     return ipmi::responseSuccess(sensorEventStatus, assertions, deassertions); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1164 | } | 
 | 1165 |  | 
| Johnathan Mantey | 2346b5d | 2021-08-06 11:21:10 -0700 | [diff] [blame] | 1166 | static inline uint16_t getNumberOfSensors(void) | 
 | 1167 | { | 
 | 1168 |     return sensorTree.size() > maxIPMISensors ? maxIPMISensors | 
 | 1169 |                                               : sensorTree.size(); | 
 | 1170 | } | 
 | 1171 |  | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1172 | static int getSensorDataRecord(ipmi::Context::ptr ctx, | 
 | 1173 |                                std::vector<uint8_t>& recordData, | 
 | 1174 |                                uint16_t recordID) | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1175 | { | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1176 |     size_t fruCount = 0; | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1177 |     ipmi::Cc ret = ipmi::storage::getFruSdrCount(ctx, fruCount); | 
 | 1178 |     if (ret != ipmi::ccSuccess) | 
 | 1179 |     { | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1180 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1181 |             "getSensorDataRecord: getFruSdrCount error"); | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1182 |         return GENERAL_ERROR; | 
 | 1183 |     } | 
 | 1184 |  | 
| Johnathan Mantey | 2346b5d | 2021-08-06 11:21:10 -0700 | [diff] [blame] | 1185 |     size_t lastRecord = getNumberOfSensors() + fruCount + | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1186 |                         ipmi::storage::type12Count + | 
 | 1187 |                         ipmi::storage::nmDiscoverySDRCount - 1; | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1188 |     if (recordID == lastRecordIndex) | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1189 |     { | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1190 |         recordID = lastRecord; | 
 | 1191 |     } | 
 | 1192 |     if (recordID > lastRecord) | 
 | 1193 |     { | 
 | 1194 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1195 |             "getSensorDataRecord: recordID > lastRecord error"); | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1196 |         return GENERAL_ERROR; | 
 | 1197 |     } | 
 | 1198 |  | 
| Johnathan Mantey | 2346b5d | 2021-08-06 11:21:10 -0700 | [diff] [blame] | 1199 |     if (recordID >= getNumberOfSensors()) | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1200 |     { | 
| Johnathan Mantey | 2346b5d | 2021-08-06 11:21:10 -0700 | [diff] [blame] | 1201 |         size_t fruIndex = recordID - getNumberOfSensors(); | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1202 |         size_t type12End = fruCount + ipmi::storage::type12Count; | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1203 |  | 
 | 1204 |         if (fruIndex >= type12End) | 
 | 1205 |         { | 
 | 1206 |             // NM discovery SDR | 
 | 1207 |             size_t nmDiscoveryIndex = fruIndex - type12End; | 
 | 1208 |             if (nmDiscoveryIndex >= ipmi::storage::nmDiscoverySDRCount) | 
 | 1209 |             { | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1210 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1211 |                     "getSensorDataRecord: NM DiscoveryIndex error"); | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1212 |                 return GENERAL_ERROR; | 
 | 1213 |             } | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1214 |             recordData = | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1215 |                 ipmi::storage::getNMDiscoverySDR(nmDiscoveryIndex, recordID); | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1216 |         } | 
 | 1217 |         else if (fruIndex >= fruCount) | 
 | 1218 |         { | 
 | 1219 |             // handle type 12 hardcoded records | 
 | 1220 |             size_t type12Index = fruIndex - fruCount; | 
 | 1221 |             if (type12Index >= ipmi::storage::type12Count) | 
 | 1222 |             { | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1223 |                 phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1224 |                     "getSensorDataRecord: type12Index error"); | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1225 |                 return GENERAL_ERROR; | 
 | 1226 |             } | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1227 |             recordData = ipmi::storage::getType12SDRs(type12Index, recordID); | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1228 |         } | 
 | 1229 |         else | 
 | 1230 |         { | 
 | 1231 |             // handle fru records | 
 | 1232 |             get_sdr::SensorDataFruRecord data; | 
 | 1233 |             ret = ipmi::storage::getFruSdrs(ctx, fruIndex, data); | 
 | 1234 |             if (ret != IPMI_CC_OK) | 
 | 1235 |             { | 
 | 1236 |                 return GENERAL_ERROR; | 
 | 1237 |             } | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1238 |             data.header.record_id_msb = recordID >> 8; | 
 | 1239 |             data.header.record_id_lsb = recordID & 0xFF; | 
 | 1240 |             recordData.insert(recordData.end(), (uint8_t*)&data, | 
 | 1241 |                               ((uint8_t*)&data) + sizeof(data)); | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1242 |         } | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1243 |  | 
 | 1244 |         return 0; | 
 | 1245 |     } | 
 | 1246 |  | 
| Johnathan Mantey | 2346b5d | 2021-08-06 11:21:10 -0700 | [diff] [blame] | 1247 |     // Perform a incremental scan of the SDR Record ID's and translate the | 
 | 1248 |     // first 765 SDR records (i.e. maxIPMISensors) into IPMI Sensor | 
 | 1249 |     // Numbers. The IPMI sensor numbers are not linear, and have a reserved | 
 | 1250 |     // gap at 0xff. This code creates 254 sensors per LUN, excepting LUN 2 | 
 | 1251 |     // which has special meaning. | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1252 |     std::string connection; | 
 | 1253 |     std::string path; | 
| Johnathan Mantey | b485b1e | 2021-07-28 15:08:30 -0700 | [diff] [blame] | 1254 |     uint16_t sensNumFromRecID{recordID}; | 
| Johnathan Mantey | 2346b5d | 2021-08-06 11:21:10 -0700 | [diff] [blame] | 1255 |     if ((recordID > lun0MaxSensorNum) && (recordID < lun1MaxSensorNum)) | 
| Johnathan Mantey | b485b1e | 2021-07-28 15:08:30 -0700 | [diff] [blame] | 1256 |     { | 
| Johnathan Mantey | 2346b5d | 2021-08-06 11:21:10 -0700 | [diff] [blame] | 1257 |         // LUN 0 has one reserved sensor number. Compensate here by adding one | 
 | 1258 |         // to the record ID | 
 | 1259 |         sensNumFromRecID = recordID + 1; | 
| Johnathan Mantey | b485b1e | 2021-07-28 15:08:30 -0700 | [diff] [blame] | 1260 |         ctx->lun = 1; | 
 | 1261 |     } | 
| Johnathan Mantey | 2346b5d | 2021-08-06 11:21:10 -0700 | [diff] [blame] | 1262 |     else if ((recordID >= lun1MaxSensorNum) && (recordID < maxIPMISensors)) | 
| Johnathan Mantey | b485b1e | 2021-07-28 15:08:30 -0700 | [diff] [blame] | 1263 |     { | 
| Johnathan Mantey | 2346b5d | 2021-08-06 11:21:10 -0700 | [diff] [blame] | 1264 |         // LUN 0, 1 have a reserved sensor number. Compensate here by adding 2 | 
 | 1265 |         // to the record ID. Skip all 256 sensors in LUN 2, as it has special | 
 | 1266 |         // rules governing its use. | 
 | 1267 |         sensNumFromRecID = recordID + (maxSensorsPerLUN + 1) + 2; | 
| Johnathan Mantey | b485b1e | 2021-07-28 15:08:30 -0700 | [diff] [blame] | 1268 |         ctx->lun = 3; | 
 | 1269 |     } | 
| Johnathan Mantey | b485b1e | 2021-07-28 15:08:30 -0700 | [diff] [blame] | 1270 |  | 
| Johnathan Mantey | 2346b5d | 2021-08-06 11:21:10 -0700 | [diff] [blame] | 1271 |     auto status = getSensorConnection( | 
 | 1272 |         ctx, static_cast<uint8_t>(sensNumFromRecID), connection, path); | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1273 |     if (status) | 
 | 1274 |     { | 
 | 1275 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1276 |             "getSensorDataRecord: getSensorConnection error"); | 
 | 1277 |         return GENERAL_ERROR; | 
 | 1278 |     } | 
 | 1279 |     SensorMap sensorMap; | 
 | 1280 |     if (!getSensorMap(ctx->yield, connection, path, sensorMap, | 
 | 1281 |                       sensorMapUpdatePeriod)) | 
 | 1282 |     { | 
 | 1283 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1284 |             "getSensorDataRecord: getSensorMap error"); | 
 | 1285 |         return GENERAL_ERROR; | 
 | 1286 |     } | 
 | 1287 |     uint16_t sensorNum = getSensorNumberFromPath(path); | 
| Johnathan Mantey | 2346b5d | 2021-08-06 11:21:10 -0700 | [diff] [blame] | 1288 |     // Return an error on LUN 2 assingments, and any sensor number beyond the | 
 | 1289 |     // range of LUN 3 | 
 | 1290 |     if (((sensorNum > lun1MaxSensorNum) && (sensorNum <= maxIPMISensors)) || | 
 | 1291 |         (sensorNum > lun3MaxSensorNum)) | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1292 |     { | 
 | 1293 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1294 |             "getSensorDataRecord: invalidSensorNumber"); | 
 | 1295 |         return GENERAL_ERROR; | 
 | 1296 |     } | 
 | 1297 |     uint8_t sensornumber = static_cast<uint8_t>(sensorNum); | 
 | 1298 |     uint8_t lun = static_cast<uint8_t>(sensorNum >> 8); | 
 | 1299 |  | 
| Johnathan Mantey | 2346b5d | 2021-08-06 11:21:10 -0700 | [diff] [blame] | 1300 |     if ((sensornumber != static_cast<uint8_t>(sensNumFromRecID)) && | 
 | 1301 |         (lun != ctx->lun)) | 
| Johnathan Mantey | b485b1e | 2021-07-28 15:08:30 -0700 | [diff] [blame] | 1302 |     { | 
 | 1303 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1304 |             "getSensorDataRecord: sensor record mismatch"); | 
 | 1305 |         return GENERAL_ERROR; | 
 | 1306 |     } | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1307 |     get_sdr::SensorDataFullRecord record = {0}; | 
 | 1308 |  | 
 | 1309 |     get_sdr::header::set_record_id( | 
 | 1310 |         recordID, reinterpret_cast<get_sdr::SensorDataRecordHeader*>(&record)); | 
 | 1311 |  | 
 | 1312 |     record.header.sdr_version = ipmiSdrVersion; | 
 | 1313 |     record.header.record_type = get_sdr::SENSOR_DATA_FULL_RECORD; | 
 | 1314 |     record.header.record_length = sizeof(get_sdr::SensorDataFullRecord) - | 
 | 1315 |                                   sizeof(get_sdr::SensorDataRecordHeader); | 
 | 1316 |     record.key.owner_id = 0x20; | 
 | 1317 |     record.key.owner_lun = lun; | 
 | 1318 |     record.key.sensor_number = sensornumber; | 
 | 1319 |  | 
 | 1320 |     record.body.sensor_capabilities = 0x68; // auto rearm - todo hysteresis | 
 | 1321 |     record.body.sensor_type = getSensorTypeFromPath(path); | 
 | 1322 |     std::string type = getSensorTypeStringFromPath(path); | 
 | 1323 |     auto typeCstr = type.c_str(); | 
 | 1324 |     auto findUnits = sensorUnits.find(typeCstr); | 
 | 1325 |     if (findUnits != sensorUnits.end()) | 
 | 1326 |     { | 
 | 1327 |         record.body.sensor_units_2_base = | 
 | 1328 |             static_cast<uint8_t>(findUnits->second); | 
 | 1329 |     } // else default 0x0 unspecified | 
 | 1330 |  | 
 | 1331 |     record.body.event_reading_type = getSensorEventTypeFromPath(path); | 
 | 1332 |  | 
 | 1333 |     auto sensorObject = sensorMap.find("xyz.openbmc_project.Sensor.Value"); | 
 | 1334 |     if (sensorObject == sensorMap.end()) | 
 | 1335 |     { | 
 | 1336 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1337 |             "getSensorDataRecord: sensorObject error"); | 
 | 1338 |         return GENERAL_ERROR; | 
 | 1339 |     } | 
 | 1340 |  | 
 | 1341 |     uint8_t entityId = 0; | 
 | 1342 |     uint8_t entityInstance = 0x01; | 
 | 1343 |  | 
 | 1344 |     // follow the association chain to get the parent board's entityid and | 
 | 1345 |     // entityInstance | 
 | 1346 |     updateIpmiFromAssociation(path, sensorMap, entityId, entityInstance); | 
 | 1347 |  | 
 | 1348 |     record.body.entity_id = entityId; | 
 | 1349 |     record.body.entity_instance = entityInstance; | 
 | 1350 |  | 
 | 1351 |     auto maxObject = sensorObject->second.find("MaxValue"); | 
 | 1352 |     auto minObject = sensorObject->second.find("MinValue"); | 
 | 1353 |  | 
 | 1354 |     // If min and/or max are left unpopulated, | 
 | 1355 |     // then default to what a signed byte would be, namely (-128,127) range. | 
 | 1356 |     auto max = static_cast<double>(std::numeric_limits<int8_t>::max()); | 
 | 1357 |     auto min = static_cast<double>(std::numeric_limits<int8_t>::lowest()); | 
 | 1358 |     if (maxObject != sensorObject->second.end()) | 
 | 1359 |     { | 
 | 1360 |         max = std::visit(VariantToDoubleVisitor(), maxObject->second); | 
 | 1361 |     } | 
 | 1362 |  | 
 | 1363 |     if (minObject != sensorObject->second.end()) | 
 | 1364 |     { | 
 | 1365 |         min = std::visit(VariantToDoubleVisitor(), minObject->second); | 
 | 1366 |     } | 
 | 1367 |  | 
 | 1368 |     int16_t mValue = 0; | 
 | 1369 |     int8_t rExp = 0; | 
 | 1370 |     int16_t bValue = 0; | 
 | 1371 |     int8_t bExp = 0; | 
 | 1372 |     bool bSigned = false; | 
 | 1373 |  | 
 | 1374 |     if (!getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned)) | 
 | 1375 |     { | 
 | 1376 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1377 |             "getSensorDataRecord: getSensorAttributes error"); | 
 | 1378 |         return GENERAL_ERROR; | 
 | 1379 |     } | 
 | 1380 |  | 
 | 1381 |     // The record.body is a struct SensorDataFullRecordBody | 
 | 1382 |     // from sensorhandler.hpp in phosphor-ipmi-host. | 
 | 1383 |     // The meaning of these bits appears to come from | 
 | 1384 |     // table 43.1 of the IPMI spec. | 
 | 1385 |     // The above 5 sensor attributes are stuffed in as follows: | 
 | 1386 |     // Byte 21 = AA000000 = analog interpretation, 10 signed, 00 unsigned | 
 | 1387 |     // Byte 22-24 are for other purposes | 
 | 1388 |     // Byte 25 = MMMMMMMM = LSB of M | 
 | 1389 |     // Byte 26 = MMTTTTTT = MSB of M (signed), and Tolerance | 
 | 1390 |     // Byte 27 = BBBBBBBB = LSB of B | 
 | 1391 |     // Byte 28 = BBAAAAAA = MSB of B (signed), and LSB of Accuracy | 
 | 1392 |     // Byte 29 = AAAAEE00 = MSB of Accuracy, exponent of Accuracy | 
 | 1393 |     // Byte 30 = RRRRBBBB = rExp (signed), bExp (signed) | 
 | 1394 |  | 
 | 1395 |     // apply M, B, and exponents, M and B are 10 bit values, exponents are 4 | 
 | 1396 |     record.body.m_lsb = mValue & 0xFF; | 
 | 1397 |  | 
 | 1398 |     uint8_t mBitSign = (mValue < 0) ? 1 : 0; | 
 | 1399 |     uint8_t mBitNine = (mValue & 0x0100) >> 8; | 
 | 1400 |  | 
 | 1401 |     // move the smallest bit of the MSB into place (bit 9) | 
 | 1402 |     // the MSbs are bits 7:8 in m_msb_and_tolerance | 
 | 1403 |     record.body.m_msb_and_tolerance = (mBitSign << 7) | (mBitNine << 6); | 
 | 1404 |  | 
 | 1405 |     record.body.b_lsb = bValue & 0xFF; | 
 | 1406 |  | 
 | 1407 |     uint8_t bBitSign = (bValue < 0) ? 1 : 0; | 
 | 1408 |     uint8_t bBitNine = (bValue & 0x0100) >> 8; | 
 | 1409 |  | 
 | 1410 |     // move the smallest bit of the MSB into place (bit 9) | 
 | 1411 |     // the MSbs are bits 7:8 in b_msb_and_accuracy_lsb | 
 | 1412 |     record.body.b_msb_and_accuracy_lsb = (bBitSign << 7) | (bBitNine << 6); | 
 | 1413 |  | 
 | 1414 |     uint8_t rExpSign = (rExp < 0) ? 1 : 0; | 
 | 1415 |     uint8_t rExpBits = rExp & 0x07; | 
 | 1416 |  | 
 | 1417 |     uint8_t bExpSign = (bExp < 0) ? 1 : 0; | 
 | 1418 |     uint8_t bExpBits = bExp & 0x07; | 
 | 1419 |  | 
 | 1420 |     // move rExp and bExp into place | 
 | 1421 |     record.body.r_b_exponents = | 
 | 1422 |         (rExpSign << 7) | (rExpBits << 4) | (bExpSign << 3) | bExpBits; | 
 | 1423 |  | 
 | 1424 |     // Set the analog reading byte interpretation accordingly | 
 | 1425 |     record.body.sensor_units_1 = (bSigned ? 1 : 0) << 7; | 
 | 1426 |  | 
 | 1427 |     // TODO(): Perhaps care about Tolerance, Accuracy, and so on | 
 | 1428 |     // These seem redundant, but derivable from the above 5 attributes | 
 | 1429 |     // Original comment said "todo fill out rest of units" | 
 | 1430 |  | 
 | 1431 |     // populate sensor name from path | 
 | 1432 |     std::string name; | 
 | 1433 |     size_t nameStart = path.rfind("/"); | 
 | 1434 |     if (nameStart != std::string::npos) | 
 | 1435 |     { | 
 | 1436 |         name = path.substr(nameStart + 1, std::string::npos - nameStart); | 
 | 1437 |     } | 
 | 1438 |  | 
 | 1439 |     std::replace(name.begin(), name.end(), '_', ' '); | 
 | 1440 |     if (name.size() > FULL_RECORD_ID_STR_MAX_LENGTH) | 
 | 1441 |     { | 
 | 1442 |         // try to not truncate by replacing common words | 
 | 1443 |         constexpr std::array<std::pair<const char*, const char*>, 2> | 
 | 1444 |             replaceWords = {std::make_pair("Output", "Out"), | 
 | 1445 |                             std::make_pair("Input", "In")}; | 
 | 1446 |         for (const auto& [find, replace] : replaceWords) | 
 | 1447 |         { | 
 | 1448 |             boost::replace_all(name, find, replace); | 
 | 1449 |         } | 
 | 1450 |  | 
 | 1451 |         name.resize(FULL_RECORD_ID_STR_MAX_LENGTH); | 
 | 1452 |     } | 
 | 1453 |     record.body.id_string_info = name.size(); | 
 | 1454 |     std::strncpy(record.body.id_string, name.c_str(), | 
 | 1455 |                  sizeof(record.body.id_string)); | 
 | 1456 |  | 
| Josh Lehan | 06aa21a | 2020-10-28 21:59:06 -0700 | [diff] [blame] | 1457 |     // Remember the sensor name, as determined for this sensor number | 
 | 1458 |     details::sdrStatsTable.updateName(sensornumber, name); | 
 | 1459 |  | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1460 |     IPMIThresholds thresholdData; | 
 | 1461 |     try | 
 | 1462 |     { | 
 | 1463 |         thresholdData = getIPMIThresholds(sensorMap); | 
 | 1464 |     } | 
| Patrick Williams | bd51e6a | 2021-10-06 13:09:44 -0500 | [diff] [blame] | 1465 |     catch (const std::exception&) | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1466 |     { | 
 | 1467 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1468 |             "getSensorDataRecord: getIPMIThresholds error"); | 
 | 1469 |         return GENERAL_ERROR; | 
 | 1470 |     } | 
 | 1471 |  | 
 | 1472 |     if (thresholdData.criticalHigh) | 
 | 1473 |     { | 
 | 1474 |         record.body.upper_critical_threshold = *thresholdData.criticalHigh; | 
 | 1475 |         record.body.supported_deassertions[1] |= static_cast<uint8_t>( | 
 | 1476 |             IPMISensorEventEnableThresholds::criticalThreshold); | 
 | 1477 |         record.body.supported_deassertions[1] |= static_cast<uint8_t>( | 
 | 1478 |             IPMISensorEventEnableThresholds::upperCriticalGoingHigh); | 
 | 1479 |         record.body.supported_assertions[1] |= static_cast<uint8_t>( | 
 | 1480 |             IPMISensorEventEnableThresholds::upperCriticalGoingHigh); | 
 | 1481 |         record.body.discrete_reading_setting_mask[0] |= | 
 | 1482 |             static_cast<uint8_t>(IPMISensorReadingByte3::upperCritical); | 
 | 1483 |     } | 
 | 1484 |     if (thresholdData.warningHigh) | 
 | 1485 |     { | 
 | 1486 |         record.body.upper_noncritical_threshold = *thresholdData.warningHigh; | 
 | 1487 |         record.body.supported_deassertions[1] |= static_cast<uint8_t>( | 
 | 1488 |             IPMISensorEventEnableThresholds::nonCriticalThreshold); | 
 | 1489 |         record.body.supported_deassertions[0] |= static_cast<uint8_t>( | 
 | 1490 |             IPMISensorEventEnableThresholds::upperNonCriticalGoingHigh); | 
 | 1491 |         record.body.supported_assertions[0] |= static_cast<uint8_t>( | 
 | 1492 |             IPMISensorEventEnableThresholds::upperNonCriticalGoingHigh); | 
 | 1493 |         record.body.discrete_reading_setting_mask[0] |= | 
 | 1494 |             static_cast<uint8_t>(IPMISensorReadingByte3::upperNonCritical); | 
 | 1495 |     } | 
 | 1496 |     if (thresholdData.criticalLow) | 
 | 1497 |     { | 
 | 1498 |         record.body.lower_critical_threshold = *thresholdData.criticalLow; | 
 | 1499 |         record.body.supported_assertions[1] |= static_cast<uint8_t>( | 
 | 1500 |             IPMISensorEventEnableThresholds::criticalThreshold); | 
 | 1501 |         record.body.supported_deassertions[0] |= static_cast<uint8_t>( | 
 | 1502 |             IPMISensorEventEnableThresholds::lowerCriticalGoingLow); | 
 | 1503 |         record.body.supported_assertions[0] |= static_cast<uint8_t>( | 
 | 1504 |             IPMISensorEventEnableThresholds::lowerCriticalGoingLow); | 
 | 1505 |         record.body.discrete_reading_setting_mask[0] |= | 
 | 1506 |             static_cast<uint8_t>(IPMISensorReadingByte3::lowerCritical); | 
 | 1507 |     } | 
 | 1508 |     if (thresholdData.warningLow) | 
 | 1509 |     { | 
 | 1510 |         record.body.lower_noncritical_threshold = *thresholdData.warningLow; | 
 | 1511 |         record.body.supported_assertions[1] |= static_cast<uint8_t>( | 
 | 1512 |             IPMISensorEventEnableThresholds::nonCriticalThreshold); | 
 | 1513 |         record.body.supported_deassertions[0] |= static_cast<uint8_t>( | 
 | 1514 |             IPMISensorEventEnableThresholds::lowerNonCriticalGoingLow); | 
 | 1515 |         record.body.supported_assertions[0] |= static_cast<uint8_t>( | 
 | 1516 |             IPMISensorEventEnableThresholds::lowerNonCriticalGoingLow); | 
 | 1517 |         record.body.discrete_reading_setting_mask[0] |= | 
 | 1518 |             static_cast<uint8_t>(IPMISensorReadingByte3::lowerNonCritical); | 
 | 1519 |     } | 
 | 1520 |  | 
 | 1521 |     // everything that is readable is setable | 
 | 1522 |     record.body.discrete_reading_setting_mask[1] = | 
 | 1523 |         record.body.discrete_reading_setting_mask[0]; | 
 | 1524 |     recordData.insert(recordData.end(), (uint8_t*)&record, | 
 | 1525 |                       ((uint8_t*)&record) + sizeof(record)); | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1526 |     return 0; | 
 | 1527 | } | 
 | 1528 |  | 
 | 1529 | /** @brief implements the get SDR Info command | 
 | 1530 |  *  @param count - Operation | 
 | 1531 |  * | 
 | 1532 |  *  @returns IPMI completion code plus response data | 
 | 1533 |  *   - sdrCount - sensor/SDR count | 
 | 1534 |  *   - lunsAndDynamicPopulation - static/Dynamic sensor population flag | 
 | 1535 |  */ | 
 | 1536 | static ipmi::RspType<uint8_t, // respcount | 
 | 1537 |                      uint8_t, // dynamic population flags | 
 | 1538 |                      uint32_t // last time a sensor was added | 
 | 1539 |                      > | 
 | 1540 |     ipmiSensorGetDeviceSdrInfo(ipmi::Context::ptr ctx, | 
 | 1541 |                                std::optional<uint8_t> count) | 
 | 1542 | { | 
 | 1543 |     uint8_t sdrCount = 0; | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1544 |     uint16_t recordID = 0; | 
 | 1545 |     std::vector<uint8_t> record; | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1546 |     // Sensors are dynamically allocated, and there is at least one LUN | 
 | 1547 |     uint8_t lunsAndDynamicPopulation = 0x80; | 
 | 1548 |     constexpr uint8_t getSdrCount = 0x01; | 
 | 1549 |     constexpr uint8_t getSensorCount = 0x00; | 
 | 1550 |  | 
 | 1551 |     if (!getSensorSubtree(sensorTree) || sensorTree.empty()) | 
 | 1552 |     { | 
 | 1553 |         return ipmi::responseResponseError(); | 
 | 1554 |     } | 
| Johnathan Mantey | 2346b5d | 2021-08-06 11:21:10 -0700 | [diff] [blame] | 1555 |     uint16_t numSensors = getNumberOfSensors(); | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1556 |     if (count.value_or(0) == getSdrCount) | 
 | 1557 |     { | 
 | 1558 |         // Count the number of Type 1 SDR entries assigned to the LUN | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1559 |         while (!getSensorDataRecord(ctx, record, recordID++)) | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1560 |         { | 
 | 1561 |             get_sdr::SensorDataRecordHeader* hdr = | 
 | 1562 |                 reinterpret_cast<get_sdr::SensorDataRecordHeader*>( | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1563 |                     record.data()); | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1564 |             if (hdr->record_type == get_sdr::SENSOR_DATA_FULL_RECORD) | 
 | 1565 |             { | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1566 |                 get_sdr::SensorDataFullRecord* recordData = | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1567 |                     reinterpret_cast<get_sdr::SensorDataFullRecord*>( | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1568 |                         record.data()); | 
 | 1569 |                 if (ctx->lun == recordData->key.owner_lun) | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1570 |                 { | 
 | 1571 |                     sdrCount++; | 
 | 1572 |                 } | 
 | 1573 |             } | 
 | 1574 |         } | 
 | 1575 |     } | 
 | 1576 |     else if (count.value_or(0) == getSensorCount) | 
 | 1577 |     { | 
 | 1578 |         // Return the number of sensors attached to the LUN | 
 | 1579 |         if ((ctx->lun == 0) && (numSensors > 0)) | 
 | 1580 |         { | 
 | 1581 |             sdrCount = | 
 | 1582 |                 (numSensors > maxSensorsPerLUN) ? maxSensorsPerLUN : numSensors; | 
 | 1583 |         } | 
 | 1584 |         else if ((ctx->lun == 1) && (numSensors > maxSensorsPerLUN)) | 
 | 1585 |         { | 
 | 1586 |             sdrCount = (numSensors > (2 * maxSensorsPerLUN)) | 
 | 1587 |                            ? maxSensorsPerLUN | 
 | 1588 |                            : (numSensors - maxSensorsPerLUN) & maxSensorsPerLUN; | 
 | 1589 |         } | 
 | 1590 |         else if (ctx->lun == 3) | 
 | 1591 |         { | 
 | 1592 |             if (numSensors <= maxIPMISensors) | 
 | 1593 |             { | 
 | 1594 |                 sdrCount = | 
 | 1595 |                     (numSensors - (2 * maxSensorsPerLUN)) & maxSensorsPerLUN; | 
 | 1596 |             } | 
 | 1597 |             else | 
 | 1598 |             { | 
 | 1599 |                 // error | 
 | 1600 |                 throw std::out_of_range( | 
 | 1601 |                     "Maximum number of IPMI sensors exceeded."); | 
 | 1602 |             } | 
 | 1603 |         } | 
 | 1604 |     } | 
 | 1605 |     else | 
 | 1606 |     { | 
 | 1607 |         return ipmi::responseInvalidFieldRequest(); | 
 | 1608 |     } | 
 | 1609 |  | 
 | 1610 |     // Get Sensor count. This returns the number of sensors | 
 | 1611 |     if (numSensors > 0) | 
 | 1612 |     { | 
 | 1613 |         lunsAndDynamicPopulation |= 1; | 
 | 1614 |     } | 
 | 1615 |     if (numSensors > maxSensorsPerLUN) | 
 | 1616 |     { | 
 | 1617 |         lunsAndDynamicPopulation |= 2; | 
 | 1618 |     } | 
 | 1619 |     if (numSensors >= (maxSensorsPerLUN * 2)) | 
 | 1620 |     { | 
 | 1621 |         lunsAndDynamicPopulation |= 8; | 
 | 1622 |     } | 
 | 1623 |     if (numSensors > maxIPMISensors) | 
 | 1624 |     { | 
 | 1625 |         // error | 
 | 1626 |         throw std::out_of_range("Maximum number of IPMI sensors exceeded."); | 
 | 1627 |     } | 
 | 1628 |  | 
 | 1629 |     return ipmi::responseSuccess(sdrCount, lunsAndDynamicPopulation, | 
 | 1630 |                                  sdrLastAdd); | 
 | 1631 | } | 
 | 1632 |  | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1633 | /* end sensor commands */ | 
 | 1634 |  | 
 | 1635 | /* storage commands */ | 
 | 1636 |  | 
| James Feist | 74c50c6 | 2019-08-14 14:18:41 -0700 | [diff] [blame] | 1637 | ipmi::RspType<uint8_t,  // sdr version | 
 | 1638 |               uint16_t, // record count | 
 | 1639 |               uint16_t, // free space | 
 | 1640 |               uint32_t, // most recent addition | 
 | 1641 |               uint32_t, // most recent erase | 
 | 1642 |               uint8_t   // operationSupport | 
 | 1643 |               > | 
| James Feist | 2569025 | 2019-12-23 12:25:49 -0800 | [diff] [blame] | 1644 |     ipmiStorageGetSDRRepositoryInfo(ipmi::Context::ptr ctx) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1645 | { | 
| James Feist | 74c50c6 | 2019-08-14 14:18:41 -0700 | [diff] [blame] | 1646 |     constexpr const uint16_t unspecifiedFreeSpace = 0xFFFF; | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1647 |     if (!getSensorSubtree(sensorTree) && sensorTree.empty()) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1648 |     { | 
| James Feist | 74c50c6 | 2019-08-14 14:18:41 -0700 | [diff] [blame] | 1649 |         return ipmi::responseResponseError(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1650 |     } | 
 | 1651 |  | 
| James Feist | 74c50c6 | 2019-08-14 14:18:41 -0700 | [diff] [blame] | 1652 |     size_t fruCount = 0; | 
| James Feist | 2569025 | 2019-12-23 12:25:49 -0800 | [diff] [blame] | 1653 |     ipmi::Cc ret = ipmi::storage::getFruSdrCount(ctx, fruCount); | 
| James Feist | 74c50c6 | 2019-08-14 14:18:41 -0700 | [diff] [blame] | 1654 |     if (ret != ipmi::ccSuccess) | 
 | 1655 |     { | 
 | 1656 |         return ipmi::response(ret); | 
 | 1657 |     } | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1658 |  | 
| sureshvijayv1 | d4b74b4 | 2021-10-08 10:49:18 +0530 | [diff] [blame] | 1659 |     uint16_t recordCount = getNumberOfSensors() + fruCount + | 
 | 1660 |                            ipmi::storage::type12Count + | 
 | 1661 |                            ipmi::storage::nmDiscoverySDRCount; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1662 |  | 
| James Feist | 74c50c6 | 2019-08-14 14:18:41 -0700 | [diff] [blame] | 1663 |     uint8_t operationSupport = static_cast<uint8_t>( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1664 |         SdrRepositoryInfoOps::overflow); // write not supported | 
| James Feist | 74c50c6 | 2019-08-14 14:18:41 -0700 | [diff] [blame] | 1665 |  | 
 | 1666 |     operationSupport |= | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1667 |         static_cast<uint8_t>(SdrRepositoryInfoOps::allocCommandSupported); | 
| James Feist | 74c50c6 | 2019-08-14 14:18:41 -0700 | [diff] [blame] | 1668 |     operationSupport |= static_cast<uint8_t>( | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1669 |         SdrRepositoryInfoOps::reserveSDRRepositoryCommandSupported); | 
| James Feist | 74c50c6 | 2019-08-14 14:18:41 -0700 | [diff] [blame] | 1670 |     return ipmi::responseSuccess(ipmiSdrVersion, recordCount, | 
 | 1671 |                                  unspecifiedFreeSpace, sdrLastAdd, | 
 | 1672 |                                  sdrLastRemove, operationSupport); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1673 | } | 
 | 1674 |  | 
| jayaprakash Mutyala | 6ae0818 | 2019-05-13 18:56:11 +0000 | [diff] [blame] | 1675 | /** @brief implements the get SDR allocation info command | 
 | 1676 |  * | 
 | 1677 |  *  @returns IPMI completion code plus response data | 
 | 1678 |  *   - allocUnits    - Number of possible allocation units | 
 | 1679 |  *   - allocUnitSize - Allocation unit size in bytes. | 
 | 1680 |  *   - allocUnitFree - Number of free allocation units | 
 | 1681 |  *   - allocUnitLargestFree - Largest free block in allocation units | 
 | 1682 |  *   - maxRecordSize    - Maximum record size in allocation units. | 
 | 1683 |  */ | 
 | 1684 | ipmi::RspType<uint16_t, // allocUnits | 
 | 1685 |               uint16_t, // allocUnitSize | 
 | 1686 |               uint16_t, // allocUnitFree | 
 | 1687 |               uint16_t, // allocUnitLargestFree | 
 | 1688 |               uint8_t   // maxRecordSize | 
 | 1689 |               > | 
 | 1690 |     ipmiStorageGetSDRAllocationInfo() | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1691 | { | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1692 |     // 0000h unspecified number of alloc units | 
| jayaprakash Mutyala | 6ae0818 | 2019-05-13 18:56:11 +0000 | [diff] [blame] | 1693 |     constexpr uint16_t allocUnits = 0; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1694 |  | 
| jayaprakash Mutyala | 6ae0818 | 2019-05-13 18:56:11 +0000 | [diff] [blame] | 1695 |     constexpr uint16_t allocUnitFree = 0; | 
 | 1696 |     constexpr uint16_t allocUnitLargestFree = 0; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1697 |     // only allow one block at a time | 
| jayaprakash Mutyala | 6ae0818 | 2019-05-13 18:56:11 +0000 | [diff] [blame] | 1698 |     constexpr uint8_t maxRecordSize = 1; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1699 |  | 
| jayaprakash Mutyala | 6ae0818 | 2019-05-13 18:56:11 +0000 | [diff] [blame] | 1700 |     return ipmi::responseSuccess(allocUnits, maxSDRTotalSize, allocUnitFree, | 
 | 1701 |                                  allocUnitLargestFree, maxRecordSize); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1702 | } | 
 | 1703 |  | 
| jayaprakash Mutyala | 6ae0818 | 2019-05-13 18:56:11 +0000 | [diff] [blame] | 1704 | /** @brief implements the reserve SDR command | 
 | 1705 |  *  @returns IPMI completion code plus response data | 
 | 1706 |  *   - sdrReservationID | 
 | 1707 |  */ | 
 | 1708 | ipmi::RspType<uint16_t> ipmiStorageReserveSDR() | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1709 | { | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1710 |     sdrReservationID++; | 
| James Feist | a80cb90 | 2019-02-14 13:05:25 -0800 | [diff] [blame] | 1711 |     if (sdrReservationID == 0) | 
 | 1712 |     { | 
 | 1713 |         sdrReservationID++; | 
 | 1714 |     } | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1715 |  | 
| jayaprakash Mutyala | 6ae0818 | 2019-05-13 18:56:11 +0000 | [diff] [blame] | 1716 |     return ipmi::responseSuccess(sdrReservationID); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1717 | } | 
 | 1718 |  | 
| James Feist | b49a98a | 2019-04-16 13:48:09 -0700 | [diff] [blame] | 1719 | ipmi::RspType<uint16_t,            // next record ID | 
 | 1720 |               std::vector<uint8_t> // payload | 
 | 1721 |               > | 
| James Feist | 2569025 | 2019-12-23 12:25:49 -0800 | [diff] [blame] | 1722 |     ipmiStorageGetSDR(ipmi::Context::ptr ctx, uint16_t reservationID, | 
 | 1723 |                       uint16_t recordID, uint8_t offset, uint8_t bytesToRead) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1724 | { | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1725 |     size_t fruCount = 0; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1726 |     // reservation required for partial reads with non zero offset into | 
 | 1727 |     // record | 
| James Feist | b49a98a | 2019-04-16 13:48:09 -0700 | [diff] [blame] | 1728 |     if ((sdrReservationID == 0 || reservationID != sdrReservationID) && offset) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1729 |     { | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1730 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1731 |             "ipmiStorageGetSDR: responseInvalidReservationId"); | 
| James Feist | b49a98a | 2019-04-16 13:48:09 -0700 | [diff] [blame] | 1732 |         return ipmi::responseInvalidReservationId(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1733 |     } | 
| James Feist | 2569025 | 2019-12-23 12:25:49 -0800 | [diff] [blame] | 1734 |     ipmi::Cc ret = ipmi::storage::getFruSdrCount(ctx, fruCount); | 
| James Feist | 74c50c6 | 2019-08-14 14:18:41 -0700 | [diff] [blame] | 1735 |     if (ret != ipmi::ccSuccess) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1736 |     { | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1737 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1738 |             "ipmiStorageGetSDR: getFruSdrCount error"); | 
| James Feist | b49a98a | 2019-04-16 13:48:09 -0700 | [diff] [blame] | 1739 |         return ipmi::response(ret); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1740 |     } | 
 | 1741 |  | 
| Johnathan Mantey | 2346b5d | 2021-08-06 11:21:10 -0700 | [diff] [blame] | 1742 |     size_t lastRecord = getNumberOfSensors() + fruCount + | 
| Yong Li | fee5e4c | 2020-01-17 19:36:29 +0800 | [diff] [blame] | 1743 |                         ipmi::storage::type12Count + | 
 | 1744 |                         ipmi::storage::nmDiscoverySDRCount - 1; | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1745 |     uint16_t nextRecordId = lastRecord > recordID ? recordID + 1 : 0XFFFF; | 
 | 1746 |  | 
 | 1747 |     if (!getSensorSubtree(sensorTree) && sensorTree.empty()) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1748 |     { | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1749 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1750 |             "ipmiStorageGetSDR: getSensorSubtree error"); | 
 | 1751 |         return ipmi::responseResponseError(); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1752 |     } | 
 | 1753 |  | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1754 |     std::vector<uint8_t> record; | 
 | 1755 |     if (getSensorDataRecord(ctx, record, recordID)) | 
 | 1756 |     { | 
 | 1757 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
 | 1758 |             "ipmiStorageGetSDR: fail to get SDR"); | 
 | 1759 |         return ipmi::responseInvalidFieldRequest(); | 
 | 1760 |     } | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1761 |     get_sdr::SensorDataRecordHeader* hdr = | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1762 |         reinterpret_cast<get_sdr::SensorDataRecordHeader*>(record.data()); | 
| Kuiying Wang | b910987 | 2021-01-15 15:54:59 +0800 | [diff] [blame] | 1763 |     if (!hdr) | 
 | 1764 |     { | 
 | 1765 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1766 |             "ipmiStorageGetSDR: record header is null"); | 
 | 1767 |         return ipmi::responseSuccess(nextRecordId, record); | 
| Kuiying Wang | b910987 | 2021-01-15 15:54:59 +0800 | [diff] [blame] | 1768 |     } | 
 | 1769 |  | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1770 |     size_t sdrLength = | 
 | 1771 |         sizeof(get_sdr::SensorDataRecordHeader) + hdr->record_length; | 
 | 1772 |     if (sdrLength < (offset + bytesToRead)) | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1773 |     { | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1774 |         bytesToRead = sdrLength - offset; | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1775 |     } | 
 | 1776 |  | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1777 |     uint8_t* respStart = reinterpret_cast<uint8_t*>(hdr) + offset; | 
| Kuiying Wang | b910987 | 2021-01-15 15:54:59 +0800 | [diff] [blame] | 1778 |     if (!respStart) | 
 | 1779 |     { | 
 | 1780 |         phosphor::logging::log<phosphor::logging::level::ERR>( | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1781 |             "ipmiStorageGetSDR: record is null"); | 
 | 1782 |         return ipmi::responseSuccess(nextRecordId, record); | 
| Kuiying Wang | b910987 | 2021-01-15 15:54:59 +0800 | [diff] [blame] | 1783 |     } | 
| James Feist | b49a98a | 2019-04-16 13:48:09 -0700 | [diff] [blame] | 1784 |     std::vector<uint8_t> recordData(respStart, respStart + bytesToRead); | 
| Kuiying Wang | 17eadbf | 2021-02-06 23:38:22 +0800 | [diff] [blame] | 1785 |  | 
| James Feist | b49a98a | 2019-04-16 13:48:09 -0700 | [diff] [blame] | 1786 |     return ipmi::responseSuccess(nextRecordId, recordData); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1787 | } | 
 | 1788 | /* end storage commands */ | 
 | 1789 |  | 
 | 1790 | void registerSensorFunctions() | 
 | 1791 | { | 
| Jason M. Bills | ae6bdb1 | 2019-04-02 12:00:04 -0700 | [diff] [blame] | 1792 |     // <Platform Event> | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 1793 |     ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnSensor, | 
 | 1794 |                           ipmi::sensor_event::cmdPlatformEvent, | 
 | 1795 |                           ipmi::Privilege::Operator, ipmiSenPlatformEvent); | 
| Jason M. Bills | ae6bdb1 | 2019-04-02 12:00:04 -0700 | [diff] [blame] | 1796 |  | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1797 |     // <Get Sensor Reading> | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 1798 |     ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnSensor, | 
 | 1799 |                           ipmi::sensor_event::cmdGetSensorReading, | 
 | 1800 |                           ipmi::Privilege::User, ipmiSenGetSensorReading); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1801 |  | 
 | 1802 |     // <Get Sensor Threshold> | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 1803 |     ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnSensor, | 
 | 1804 |                           ipmi::sensor_event::cmdGetSensorThreshold, | 
 | 1805 |                           ipmi::Privilege::User, ipmiSenGetSensorThresholds); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1806 |  | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 1807 |     // <Set Sensor Threshold> | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 1808 |     ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnSensor, | 
 | 1809 |                           ipmi::sensor_event::cmdSetSensorThreshold, | 
 | 1810 |                           ipmi::Privilege::Operator, | 
 | 1811 |                           ipmiSenSetSensorThresholds); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1812 |  | 
 | 1813 |     // <Get Sensor Event Enable> | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 1814 |     ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnSensor, | 
 | 1815 |                           ipmi::sensor_event::cmdGetSensorEventEnable, | 
| jayaprakash Mutyala | 39fa93f | 2019-05-13 12:16:30 +0000 | [diff] [blame] | 1816 |                           ipmi::Privilege::User, ipmiSenGetSensorEventEnable); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1817 |  | 
 | 1818 |     // <Get Sensor Event Status> | 
| jayaprakash Mutyala | ccf88f6 | 2019-05-13 16:57:16 +0000 | [diff] [blame] | 1819 |     ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnSensor, | 
 | 1820 |                           ipmi::sensor_event::cmdGetSensorEventStatus, | 
 | 1821 |                           ipmi::Privilege::User, ipmiSenGetSensorEventStatus); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1822 |  | 
 | 1823 |     // register all storage commands for both Sensor and Storage command | 
 | 1824 |     // versions | 
 | 1825 |  | 
 | 1826 |     // <Get SDR Repository Info> | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 1827 |     ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnStorage, | 
 | 1828 |                           ipmi::storage::cmdGetSdrRepositoryInfo, | 
 | 1829 |                           ipmi::Privilege::User, | 
 | 1830 |                           ipmiStorageGetSDRRepositoryInfo); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1831 |  | 
| Johnathan Mantey | 308c3a8 | 2020-07-22 11:50:54 -0700 | [diff] [blame] | 1832 |     // <Get Device SDR Info> | 
 | 1833 |     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor, | 
 | 1834 |                           ipmi::sensor_event::cmdGetDeviceSdrInfo, | 
 | 1835 |                           ipmi::Privilege::User, ipmiSensorGetDeviceSdrInfo); | 
 | 1836 |  | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1837 |     // <Get SDR Allocation Info> | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 1838 |     ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnStorage, | 
 | 1839 |                           ipmi::storage::cmdGetSdrRepositoryAllocInfo, | 
 | 1840 |                           ipmi::Privilege::User, | 
 | 1841 |                           ipmiStorageGetSDRAllocationInfo); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1842 |  | 
 | 1843 |     // <Reserve SDR Repo> | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 1844 |     ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnSensor, | 
 | 1845 |                           ipmi::sensor_event::cmdReserveDeviceSdrRepository, | 
| jayaprakash Mutyala | 6ae0818 | 2019-05-13 18:56:11 +0000 | [diff] [blame] | 1846 |                           ipmi::Privilege::User, ipmiStorageReserveSDR); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1847 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 1848 |     ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnStorage, | 
 | 1849 |                           ipmi::storage::cmdReserveSdrRepository, | 
 | 1850 |                           ipmi::Privilege::User, ipmiStorageReserveSDR); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1851 |  | 
 | 1852 |     // <Get Sdr> | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 1853 |     ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnSensor, | 
 | 1854 |                           ipmi::sensor_event::cmdGetDeviceSdr, | 
 | 1855 |                           ipmi::Privilege::User, ipmiStorageGetSDR); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1856 |  | 
| Vernon Mauery | 98bbf69 | 2019-09-16 11:14:59 -0700 | [diff] [blame] | 1857 |     ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnStorage, | 
 | 1858 |                           ipmi::storage::cmdGetSdr, ipmi::Privilege::User, | 
 | 1859 |                           ipmiStorageGetSDR); | 
| Jason M. Bills | 3f7c5e4 | 2018-10-03 14:00:41 -0700 | [diff] [blame] | 1860 | } | 
 | 1861 | } // namespace ipmi |