| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 1 | /* | 
 | 2 | // Copyright (c) 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 | #pragma once | 
 | 17 |  | 
| Ed Tanous | 3ccb3ad | 2023-01-13 17:40:03 -0800 | [diff] [blame] | 18 | #include "app.hpp" | 
 | 19 | #include "dbus_singleton.hpp" | 
| George Liu | 7a1dbc4 | 2022-12-07 16:03:22 +0800 | [diff] [blame] | 20 | #include "dbus_utility.hpp" | 
| Matt Simmering | aaf08ac | 2023-10-04 08:41:01 -0700 | [diff] [blame] | 21 | #include "generated/enums/resource.hpp" | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 22 | #include "generated/enums/sensor.hpp" | 
| Ed Tanous | 3ccb3ad | 2023-01-13 17:40:03 -0800 | [diff] [blame] | 23 | #include "query.hpp" | 
 | 24 | #include "registries/privilege_registry.hpp" | 
| Ed Tanous | 50ebd4a | 2023-01-19 19:03:17 -0800 | [diff] [blame] | 25 | #include "str_utility.hpp" | 
| Ed Tanous | 3ccb3ad | 2023-01-13 17:40:03 -0800 | [diff] [blame] | 26 | #include "utils/dbus_utils.hpp" | 
 | 27 | #include "utils/json_utils.hpp" | 
 | 28 | #include "utils/query_param.hpp" | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 29 |  | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 30 | #include <boost/system/error_code.hpp> | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 31 | #include <boost/url/format.hpp> | 
| Jonathan Doman | 1e1e598 | 2021-06-11 09:36:17 -0700 | [diff] [blame] | 32 | #include <sdbusplus/asio/property.hpp> | 
| Krzysztof Grobelny | 86d89ed | 2022-08-29 14:49:20 +0200 | [diff] [blame] | 33 | #include <sdbusplus/unpack_properties.hpp> | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 34 |  | 
| George Liu | 7a1dbc4 | 2022-12-07 16:03:22 +0800 | [diff] [blame] | 35 | #include <array> | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 36 | #include <cmath> | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 37 | #include <iterator> | 
| Ed Tanous | 283860f | 2022-08-29 14:08:50 -0700 | [diff] [blame] | 38 | #include <limits> | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 39 | #include <map> | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 40 | #include <ranges> | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 41 | #include <set> | 
| Ed Tanous | 18f8f60 | 2023-07-18 10:07:23 -0700 | [diff] [blame] | 42 | #include <string> | 
| George Liu | 7a1dbc4 | 2022-12-07 16:03:22 +0800 | [diff] [blame] | 43 | #include <string_view> | 
| Ed Tanous | b5a7693 | 2020-09-29 16:16:58 -0700 | [diff] [blame] | 44 | #include <utility> | 
| Ed Tanous | abf2add | 2019-01-22 16:40:12 -0800 | [diff] [blame] | 45 | #include <variant> | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 46 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 47 | namespace redfish | 
 | 48 | { | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 49 |  | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 50 | namespace sensors | 
 | 51 | { | 
 | 52 | namespace node | 
 | 53 | { | 
 | 54 | static constexpr std::string_view power = "Power"; | 
 | 55 | static constexpr std::string_view sensors = "Sensors"; | 
 | 56 | static constexpr std::string_view thermal = "Thermal"; | 
 | 57 | } // namespace node | 
 | 58 |  | 
| Ed Tanous | 02da7c5 | 2022-02-27 00:09:02 -0800 | [diff] [blame] | 59 | // clang-format off | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 60 | namespace dbus | 
 | 61 | { | 
| Ed Tanous | cf9e417 | 2022-12-21 09:30:16 -0800 | [diff] [blame] | 62 | constexpr auto powerPaths = std::to_array<std::string_view>({ | 
| Ed Tanous | 02da7c5 | 2022-02-27 00:09:02 -0800 | [diff] [blame] | 63 |     "/xyz/openbmc_project/sensors/voltage", | 
 | 64 |     "/xyz/openbmc_project/sensors/power" | 
 | 65 | }); | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 66 |  | 
| Ed Tanous | cf9e417 | 2022-12-21 09:30:16 -0800 | [diff] [blame] | 67 | constexpr auto sensorPaths = std::to_array<std::string_view>({ | 
| Ed Tanous | 02da7c5 | 2022-02-27 00:09:02 -0800 | [diff] [blame] | 68 |     "/xyz/openbmc_project/sensors/power", | 
 | 69 |     "/xyz/openbmc_project/sensors/current", | 
 | 70 |     "/xyz/openbmc_project/sensors/airflow", | 
| Ed Tanous | 4e77766 | 2022-08-06 09:39:13 -0700 | [diff] [blame] | 71 |     "/xyz/openbmc_project/sensors/humidity", | 
| George Liu | e820493 | 2021-02-01 14:42:49 +0800 | [diff] [blame] | 72 | #ifdef BMCWEB_NEW_POWERSUBSYSTEM_THERMALSUBSYSTEM | 
| Ed Tanous | 02da7c5 | 2022-02-27 00:09:02 -0800 | [diff] [blame] | 73 |     "/xyz/openbmc_project/sensors/voltage", | 
 | 74 |     "/xyz/openbmc_project/sensors/fan_tach", | 
 | 75 |     "/xyz/openbmc_project/sensors/temperature", | 
 | 76 |     "/xyz/openbmc_project/sensors/fan_pwm", | 
 | 77 |     "/xyz/openbmc_project/sensors/altitude", | 
 | 78 |     "/xyz/openbmc_project/sensors/energy", | 
| George Liu | e820493 | 2021-02-01 14:42:49 +0800 | [diff] [blame] | 79 | #endif | 
| Ed Tanous | 02da7c5 | 2022-02-27 00:09:02 -0800 | [diff] [blame] | 80 |     "/xyz/openbmc_project/sensors/utilization" | 
 | 81 | }); | 
 | 82 |  | 
| Ed Tanous | cf9e417 | 2022-12-21 09:30:16 -0800 | [diff] [blame] | 83 | constexpr auto thermalPaths = std::to_array<std::string_view>({ | 
| Ed Tanous | 02da7c5 | 2022-02-27 00:09:02 -0800 | [diff] [blame] | 84 |     "/xyz/openbmc_project/sensors/fan_tach", | 
 | 85 |     "/xyz/openbmc_project/sensors/temperature", | 
 | 86 |     "/xyz/openbmc_project/sensors/fan_pwm" | 
 | 87 | }); | 
 | 88 |  | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 89 | } // namespace dbus | 
| Ed Tanous | 02da7c5 | 2022-02-27 00:09:02 -0800 | [diff] [blame] | 90 | // clang-format on | 
 | 91 |  | 
| Ed Tanous | cf9e417 | 2022-12-21 09:30:16 -0800 | [diff] [blame] | 92 | using sensorPair = | 
 | 93 |     std::pair<std::string_view, std::span<const std::string_view>>; | 
| Ed Tanous | 02da7c5 | 2022-02-27 00:09:02 -0800 | [diff] [blame] | 94 | static constexpr std::array<sensorPair, 3> paths = { | 
| Ed Tanous | cf9e417 | 2022-12-21 09:30:16 -0800 | [diff] [blame] | 95 |     {{node::power, dbus::powerPaths}, | 
 | 96 |      {node::sensors, dbus::sensorPaths}, | 
 | 97 |      {node::thermal, dbus::thermalPaths}}}; | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 98 |  | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 99 | inline sensor::ReadingType toReadingType(std::string_view sensorType) | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 100 | { | 
 | 101 |     if (sensorType == "voltage") | 
 | 102 |     { | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 103 |         return sensor::ReadingType::Voltage; | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 104 |     } | 
 | 105 |     if (sensorType == "power") | 
 | 106 |     { | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 107 |         return sensor::ReadingType::Power; | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 108 |     } | 
 | 109 |     if (sensorType == "current") | 
 | 110 |     { | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 111 |         return sensor::ReadingType::Current; | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 112 |     } | 
 | 113 |     if (sensorType == "fan_tach") | 
 | 114 |     { | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 115 |         return sensor::ReadingType::Rotational; | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 116 |     } | 
 | 117 |     if (sensorType == "temperature") | 
 | 118 |     { | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 119 |         return sensor::ReadingType::Temperature; | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 120 |     } | 
 | 121 |     if (sensorType == "fan_pwm" || sensorType == "utilization") | 
 | 122 |     { | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 123 |         return sensor::ReadingType::Percent; | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 124 |     } | 
| Gunnar Mills | 5deabed | 2022-04-20 13:43:45 -0600 | [diff] [blame] | 125 |     if (sensorType == "humidity") | 
 | 126 |     { | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 127 |         return sensor::ReadingType::Humidity; | 
| Gunnar Mills | 5deabed | 2022-04-20 13:43:45 -0600 | [diff] [blame] | 128 |     } | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 129 |     if (sensorType == "altitude") | 
 | 130 |     { | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 131 |         return sensor::ReadingType::Altitude; | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 132 |     } | 
 | 133 |     if (sensorType == "airflow") | 
 | 134 |     { | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 135 |         return sensor::ReadingType::AirFlow; | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 136 |     } | 
 | 137 |     if (sensorType == "energy") | 
 | 138 |     { | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 139 |         return sensor::ReadingType::EnergyJoules; | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 140 |     } | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 141 |     return sensor::ReadingType::Invalid; | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 142 | } | 
 | 143 |  | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 144 | inline std::string_view toReadingUnits(std::string_view sensorType) | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 145 | { | 
 | 146 |     if (sensorType == "voltage") | 
 | 147 |     { | 
 | 148 |         return "V"; | 
 | 149 |     } | 
 | 150 |     if (sensorType == "power") | 
 | 151 |     { | 
 | 152 |         return "W"; | 
 | 153 |     } | 
 | 154 |     if (sensorType == "current") | 
 | 155 |     { | 
 | 156 |         return "A"; | 
 | 157 |     } | 
 | 158 |     if (sensorType == "fan_tach") | 
 | 159 |     { | 
 | 160 |         return "RPM"; | 
 | 161 |     } | 
 | 162 |     if (sensorType == "temperature") | 
 | 163 |     { | 
 | 164 |         return "Cel"; | 
 | 165 |     } | 
| Gunnar Mills | 5deabed | 2022-04-20 13:43:45 -0600 | [diff] [blame] | 166 |     if (sensorType == "fan_pwm" || sensorType == "utilization" || | 
 | 167 |         sensorType == "humidity") | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 168 |     { | 
 | 169 |         return "%"; | 
 | 170 |     } | 
 | 171 |     if (sensorType == "altitude") | 
 | 172 |     { | 
 | 173 |         return "m"; | 
 | 174 |     } | 
 | 175 |     if (sensorType == "airflow") | 
 | 176 |     { | 
 | 177 |         return "cft_i/min"; | 
 | 178 |     } | 
 | 179 |     if (sensorType == "energy") | 
 | 180 |     { | 
 | 181 |         return "J"; | 
 | 182 |     } | 
 | 183 |     return ""; | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 184 | } | 
 | 185 | } // namespace sensors | 
 | 186 |  | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 187 | /** | 
| Kowalski, Kamil | 588c3f0 | 2018-04-03 14:55:27 +0200 | [diff] [blame] | 188 |  * SensorsAsyncResp | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 189 |  * Gathers data needed for response processing after async calls are done | 
 | 190 |  */ | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 191 | class SensorsAsyncResp | 
 | 192 | { | 
 | 193 |   public: | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 194 |     using DataCompleteCb = std::function<void( | 
 | 195 |         const boost::beast::http::status status, | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 196 |         const std::map<std::string, std::string>& uriToDbus)>; | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 197 |  | 
 | 198 |     struct SensorData | 
 | 199 |     { | 
 | 200 |         const std::string name; | 
 | 201 |         std::string uri; | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 202 |         const std::string dbusPath; | 
 | 203 |     }; | 
 | 204 |  | 
| Ed Tanous | 8a59281 | 2022-06-04 09:06:59 -0700 | [diff] [blame] | 205 |     SensorsAsyncResp(const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn, | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 206 |                      const std::string& chassisIdIn, | 
| Ed Tanous | cf9e417 | 2022-12-21 09:30:16 -0800 | [diff] [blame] | 207 |                      std::span<const std::string_view> typesIn, | 
| Ed Tanous | 02da7c5 | 2022-02-27 00:09:02 -0800 | [diff] [blame] | 208 |                      std::string_view subNode) : | 
| Ed Tanous | 8a59281 | 2022-06-04 09:06:59 -0700 | [diff] [blame] | 209 |         asyncResp(asyncRespIn), | 
| Nan Zhou | 928fefb | 2022-03-28 08:45:00 -0700 | [diff] [blame] | 210 |         chassisId(chassisIdIn), types(typesIn), chassisSubNode(subNode), | 
 | 211 |         efficientExpand(false) | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 212 |     {} | 
| Kowalski, Kamil | 588c3f0 | 2018-04-03 14:55:27 +0200 | [diff] [blame] | 213 |  | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 214 |     // Store extra data about sensor mapping and return it in callback | 
| Ed Tanous | 8a59281 | 2022-06-04 09:06:59 -0700 | [diff] [blame] | 215 |     SensorsAsyncResp(const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn, | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 216 |                      const std::string& chassisIdIn, | 
| Ed Tanous | cf9e417 | 2022-12-21 09:30:16 -0800 | [diff] [blame] | 217 |                      std::span<const std::string_view> typesIn, | 
| Ed Tanous | 02da7c5 | 2022-02-27 00:09:02 -0800 | [diff] [blame] | 218 |                      std::string_view subNode, | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 219 |                      DataCompleteCb&& creationComplete) : | 
| Ed Tanous | 8a59281 | 2022-06-04 09:06:59 -0700 | [diff] [blame] | 220 |         asyncResp(asyncRespIn), | 
| Nan Zhou | 928fefb | 2022-03-28 08:45:00 -0700 | [diff] [blame] | 221 |         chassisId(chassisIdIn), types(typesIn), chassisSubNode(subNode), | 
 | 222 |         efficientExpand(false), metadata{std::vector<SensorData>()}, | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 223 |         dataComplete{std::move(creationComplete)} | 
 | 224 |     {} | 
 | 225 |  | 
| Nan Zhou | 928fefb | 2022-03-28 08:45:00 -0700 | [diff] [blame] | 226 |     // sensor collections expand | 
| Ed Tanous | 8a59281 | 2022-06-04 09:06:59 -0700 | [diff] [blame] | 227 |     SensorsAsyncResp(const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn, | 
| Nan Zhou | 928fefb | 2022-03-28 08:45:00 -0700 | [diff] [blame] | 228 |                      const std::string& chassisIdIn, | 
| Ed Tanous | cf9e417 | 2022-12-21 09:30:16 -0800 | [diff] [blame] | 229 |                      std::span<const std::string_view> typesIn, | 
| Ed Tanous | 8a59281 | 2022-06-04 09:06:59 -0700 | [diff] [blame] | 230 |                      const std::string_view& subNode, bool efficientExpandIn) : | 
 | 231 |         asyncResp(asyncRespIn), | 
| Nan Zhou | 928fefb | 2022-03-28 08:45:00 -0700 | [diff] [blame] | 232 |         chassisId(chassisIdIn), types(typesIn), chassisSubNode(subNode), | 
| Ed Tanous | 8a59281 | 2022-06-04 09:06:59 -0700 | [diff] [blame] | 233 |         efficientExpand(efficientExpandIn) | 
| Nan Zhou | 928fefb | 2022-03-28 08:45:00 -0700 | [diff] [blame] | 234 |     {} | 
 | 235 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 236 |     ~SensorsAsyncResp() | 
 | 237 |     { | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 238 |         if (asyncResp->res.result() == | 
 | 239 |             boost::beast::http::status::internal_server_error) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 240 |         { | 
 | 241 |             // Reset the json object to clear out any data that made it in | 
 | 242 |             // before the error happened todo(ed) handle error condition with | 
 | 243 |             // proper code | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 244 |             asyncResp->res.jsonValue = nlohmann::json::object(); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 245 |         } | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 246 |  | 
 | 247 |         if (dataComplete && metadata) | 
 | 248 |         { | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 249 |             std::map<std::string, std::string> map; | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 250 |             if (asyncResp->res.result() == boost::beast::http::status::ok) | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 251 |             { | 
 | 252 |                 for (auto& sensor : *metadata) | 
 | 253 |                 { | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 254 |                     map.emplace(sensor.uri, sensor.dbusPath); | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 255 |                 } | 
 | 256 |             } | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 257 |             dataComplete(asyncResp->res.result(), map); | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 258 |         } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 259 |     } | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 260 |  | 
| Ed Tanous | ecd6a3a | 2022-01-07 09:18:40 -0800 | [diff] [blame] | 261 |     SensorsAsyncResp(const SensorsAsyncResp&) = delete; | 
 | 262 |     SensorsAsyncResp(SensorsAsyncResp&&) = delete; | 
 | 263 |     SensorsAsyncResp& operator=(const SensorsAsyncResp&) = delete; | 
 | 264 |     SensorsAsyncResp& operator=(SensorsAsyncResp&&) = delete; | 
 | 265 |  | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 266 |     void addMetadata(const nlohmann::json& sensorObject, | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 267 |                      const std::string& dbusPath) | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 268 |     { | 
 | 269 |         if (metadata) | 
 | 270 |         { | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 271 |             metadata->emplace_back(SensorData{ | 
 | 272 |                 sensorObject["Name"], sensorObject["@odata.id"], dbusPath}); | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 273 |         } | 
 | 274 |     } | 
 | 275 |  | 
 | 276 |     void updateUri(const std::string& name, const std::string& uri) | 
 | 277 |     { | 
 | 278 |         if (metadata) | 
 | 279 |         { | 
 | 280 |             for (auto& sensor : *metadata) | 
 | 281 |             { | 
 | 282 |                 if (sensor.name == name) | 
 | 283 |                 { | 
 | 284 |                     sensor.uri = uri; | 
 | 285 |                 } | 
 | 286 |             } | 
 | 287 |         } | 
 | 288 |     } | 
 | 289 |  | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 290 |     const std::shared_ptr<bmcweb::AsyncResp> asyncResp; | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 291 |     const std::string chassisId; | 
| Ed Tanous | cf9e417 | 2022-12-21 09:30:16 -0800 | [diff] [blame] | 292 |     const std::span<const std::string_view> types; | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 293 |     const std::string chassisSubNode; | 
| Nan Zhou | 928fefb | 2022-03-28 08:45:00 -0700 | [diff] [blame] | 294 |     const bool efficientExpand; | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 295 |  | 
 | 296 |   private: | 
 | 297 |     std::optional<std::vector<SensorData>> metadata; | 
 | 298 |     DataCompleteCb dataComplete; | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 299 | }; | 
 | 300 |  | 
 | 301 | /** | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 302 |  * Possible states for physical inventory leds | 
 | 303 |  */ | 
 | 304 | enum class LedState | 
 | 305 | { | 
 | 306 |     OFF, | 
 | 307 |     ON, | 
 | 308 |     BLINK, | 
 | 309 |     UNKNOWN | 
 | 310 | }; | 
 | 311 |  | 
 | 312 | /** | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 313 |  * D-Bus inventory item associated with one or more sensors. | 
 | 314 |  */ | 
 | 315 | class InventoryItem | 
 | 316 | { | 
 | 317 |   public: | 
| Ed Tanous | 4e23a44 | 2022-06-06 09:57:26 -0700 | [diff] [blame] | 318 |     explicit InventoryItem(const std::string& objPath) : objectPath(objPath) | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 319 |     { | 
 | 320 |         // Set inventory item name to last node of object path | 
| George Liu | 28aa8de | 2021-02-01 15:13:30 +0800 | [diff] [blame] | 321 |         sdbusplus::message::object_path path(objectPath); | 
 | 322 |         name = path.filename(); | 
 | 323 |         if (name.empty()) | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 324 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 325 |             BMCWEB_LOG_ERROR("Failed to find '/' in {}", objectPath); | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 326 |         } | 
 | 327 |     } | 
 | 328 |  | 
 | 329 |     std::string objectPath; | 
 | 330 |     std::string name; | 
| Ed Tanous | e05aec5 | 2022-01-25 10:28:56 -0800 | [diff] [blame] | 331 |     bool isPresent = true; | 
 | 332 |     bool isFunctional = true; | 
 | 333 |     bool isPowerSupply = false; | 
 | 334 |     int powerSupplyEfficiencyPercent = -1; | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 335 |     std::string manufacturer; | 
 | 336 |     std::string model; | 
 | 337 |     std::string partNumber; | 
 | 338 |     std::string serialNumber; | 
 | 339 |     std::set<std::string> sensors; | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 340 |     std::string ledObjectPath; | 
| Ed Tanous | e05aec5 | 2022-01-25 10:28:56 -0800 | [diff] [blame] | 341 |     LedState ledState = LedState::UNKNOWN; | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 342 | }; | 
 | 343 |  | 
 | 344 | /** | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 345 |  * @brief Get objects with connection necessary for sensors | 
| Kowalski, Kamil | 588c3f0 | 2018-04-03 14:55:27 +0200 | [diff] [blame] | 346 |  * @param SensorsAsyncResp Pointer to object holding response data | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 347 |  * @param sensorNames Sensors retrieved from chassis | 
 | 348 |  * @param callback Callback for processing gathered connections | 
 | 349 |  */ | 
 | 350 | template <typename Callback> | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 351 | void getObjectsWithConnection( | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 352 |     const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp, | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 353 |     const std::shared_ptr<std::set<std::string>>& sensorNames, | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 354 |     Callback&& callback) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 355 | { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 356 |     BMCWEB_LOG_DEBUG("getObjectsWithConnection enter"); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 357 |     const std::string path = "/xyz/openbmc_project/sensors"; | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 358 |     constexpr std::array<std::string_view, 1> interfaces = { | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 359 |         "xyz.openbmc_project.Sensor.Value"}; | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 360 |  | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 361 |     // Make call to ObjectMapper to find all sensors objects | 
 | 362 |     dbus::utility::getSubTree( | 
 | 363 |         path, 2, interfaces, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 364 |         [callback{std::forward<Callback>(callback)}, sensorsAsyncResp, | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 365 |          sensorNames](const boost::system::error_code& ec, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 366 |                       const dbus::utility::MapperGetSubTreeResponse& subtree) { | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 367 |         // Response handler for parsing objects subtree | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 368 |         BMCWEB_LOG_DEBUG("getObjectsWithConnection resp_handler enter"); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 369 |         if (ec) | 
 | 370 |         { | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 371 |             messages::internalError(sensorsAsyncResp->asyncResp->res); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 372 |             BMCWEB_LOG_ERROR( | 
 | 373 |                 "getObjectsWithConnection resp_handler: Dbus error {}", ec); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 374 |             return; | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 375 |         } | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 376 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 377 |         BMCWEB_LOG_DEBUG("Found {} subtrees", subtree.size()); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 378 |  | 
 | 379 |         // Make unique list of connections only for requested sensor types and | 
 | 380 |         // found in the chassis | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 381 |         std::set<std::string> connections; | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 382 |         std::set<std::pair<std::string, std::string>> objectsWithConnection; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 383 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 384 |         BMCWEB_LOG_DEBUG("sensorNames list count: {}", sensorNames->size()); | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 385 |         for (const std::string& tsensor : *sensorNames) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 386 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 387 |             BMCWEB_LOG_DEBUG("Sensor to find: {}", tsensor); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 388 |         } | 
 | 389 |  | 
 | 390 |         for (const std::pair< | 
 | 391 |                  std::string, | 
 | 392 |                  std::vector<std::pair<std::string, std::vector<std::string>>>>& | 
 | 393 |                  object : subtree) | 
 | 394 |         { | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 395 |             if (sensorNames->find(object.first) != sensorNames->end()) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 396 |             { | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 397 |                 for (const std::pair<std::string, std::vector<std::string>>& | 
 | 398 |                          objData : object.second) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 399 |                 { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 400 |                     BMCWEB_LOG_DEBUG("Adding connection: {}", objData.first); | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 401 |                     connections.insert(objData.first); | 
 | 402 |                     objectsWithConnection.insert( | 
 | 403 |                         std::make_pair(object.first, objData.first)); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 404 |                 } | 
 | 405 |             } | 
 | 406 |         } | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 407 |         BMCWEB_LOG_DEBUG("Found {} connections", connections.size()); | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 408 |         callback(std::move(connections), std::move(objectsWithConnection)); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 409 |         BMCWEB_LOG_DEBUG("getObjectsWithConnection resp_handler exit"); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 410 |     }); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 411 |     BMCWEB_LOG_DEBUG("getObjectsWithConnection exit"); | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 412 | } | 
 | 413 |  | 
 | 414 | /** | 
 | 415 |  * @brief Create connections necessary for sensors | 
 | 416 |  * @param SensorsAsyncResp Pointer to object holding response data | 
 | 417 |  * @param sensorNames Sensors retrieved from chassis | 
 | 418 |  * @param callback Callback for processing gathered connections | 
 | 419 |  */ | 
 | 420 | template <typename Callback> | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 421 | void getConnections(std::shared_ptr<SensorsAsyncResp> sensorsAsyncResp, | 
 | 422 |                     const std::shared_ptr<std::set<std::string>> sensorNames, | 
 | 423 |                     Callback&& callback) | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 424 | { | 
 | 425 |     auto objectsWithConnectionCb = | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 426 |         [callback](const std::set<std::string>& connections, | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 427 |                    const std::set<std::pair<std::string, std::string>>& | 
| Ed Tanous | 3174e4d | 2020-10-07 11:41:22 -0700 | [diff] [blame] | 428 |                    /*objectsWithConnection*/) { callback(connections); }; | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 429 |     getObjectsWithConnection(sensorsAsyncResp, sensorNames, | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 430 |                              std::move(objectsWithConnectionCb)); | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 431 | } | 
 | 432 |  | 
 | 433 | /** | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 434 |  * @brief Shrinks the list of sensors for processing | 
 | 435 |  * @param SensorsAysncResp  The class holding the Redfish response | 
 | 436 |  * @param allSensors  A list of all the sensors associated to the | 
 | 437 |  * chassis element (i.e. baseboard, front panel, etc...) | 
 | 438 |  * @param activeSensors A list that is a reduction of the incoming | 
 | 439 |  * allSensors list.  Eliminate Thermal sensors when a Power request is | 
 | 440 |  * made, and eliminate Power sensors when a Thermal request is made. | 
 | 441 |  */ | 
| Ed Tanous | 23a21a1 | 2020-07-25 04:45:05 +0000 | [diff] [blame] | 442 | inline void reduceSensorList( | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 443 |     crow::Response& res, std::string_view chassisSubNode, | 
| Ed Tanous | cf9e417 | 2022-12-21 09:30:16 -0800 | [diff] [blame] | 444 |     std::span<const std::string_view> sensorTypes, | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 445 |     const std::vector<std::string>* allSensors, | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 446 |     const std::shared_ptr<std::set<std::string>>& activeSensors) | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 447 | { | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 448 |     if ((allSensors == nullptr) || (activeSensors == nullptr)) | 
 | 449 |     { | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 450 |         messages::resourceNotFound(res, chassisSubNode, | 
 | 451 |                                    chassisSubNode == sensors::node::thermal | 
 | 452 |                                        ? "Temperatures" | 
 | 453 |                                        : "Voltages"); | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 454 |  | 
 | 455 |         return; | 
 | 456 |     } | 
 | 457 |     if (allSensors->empty()) | 
 | 458 |     { | 
 | 459 |         // Nothing to do, the activeSensors object is also empty | 
 | 460 |         return; | 
 | 461 |     } | 
 | 462 |  | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 463 |     for (std::string_view type : sensorTypes) | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 464 |     { | 
 | 465 |         for (const std::string& sensor : *allSensors) | 
 | 466 |         { | 
| Ed Tanous | 11ba397 | 2022-07-11 09:50:41 -0700 | [diff] [blame] | 467 |             if (sensor.starts_with(type)) | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 468 |             { | 
 | 469 |                 activeSensors->emplace(sensor); | 
 | 470 |             } | 
 | 471 |         } | 
 | 472 |     } | 
 | 473 | } | 
 | 474 |  | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 475 | /* | 
 | 476 |  *Populates the top level collection for a given subnode.  Populates | 
 | 477 |  *SensorCollection, Power, or Thermal schemas. | 
 | 478 |  * | 
 | 479 |  * */ | 
 | 480 | inline void populateChassisNode(nlohmann::json& jsonValue, | 
 | 481 |                                 std::string_view chassisSubNode) | 
 | 482 | { | 
 | 483 |     if (chassisSubNode == sensors::node::power) | 
 | 484 |     { | 
 | 485 |         jsonValue["@odata.type"] = "#Power.v1_5_2.Power"; | 
 | 486 |     } | 
 | 487 |     else if (chassisSubNode == sensors::node::thermal) | 
 | 488 |     { | 
 | 489 |         jsonValue["@odata.type"] = "#Thermal.v1_4_0.Thermal"; | 
 | 490 |         jsonValue["Fans"] = nlohmann::json::array(); | 
 | 491 |         jsonValue["Temperatures"] = nlohmann::json::array(); | 
 | 492 |     } | 
 | 493 |     else if (chassisSubNode == sensors::node::sensors) | 
 | 494 |     { | 
 | 495 |         jsonValue["@odata.type"] = "#SensorCollection.SensorCollection"; | 
 | 496 |         jsonValue["Description"] = "Collection of Sensors for this Chassis"; | 
 | 497 |         jsonValue["Members"] = nlohmann::json::array(); | 
 | 498 |         jsonValue["Members@odata.count"] = 0; | 
 | 499 |     } | 
 | 500 |  | 
 | 501 |     if (chassisSubNode != sensors::node::sensors) | 
 | 502 |     { | 
 | 503 |         jsonValue["Id"] = chassisSubNode; | 
 | 504 |     } | 
 | 505 |     jsonValue["Name"] = chassisSubNode; | 
 | 506 | } | 
 | 507 |  | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 508 | /** | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 509 |  * @brief Retrieves requested chassis sensors and redundancy data from DBus . | 
| Kowalski, Kamil | 588c3f0 | 2018-04-03 14:55:27 +0200 | [diff] [blame] | 510 |  * @param SensorsAsyncResp   Pointer to object holding response data | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 511 |  * @param callback  Callback for next step in gathered sensor processing | 
 | 512 |  */ | 
 | 513 | template <typename Callback> | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 514 | void getChassis(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 515 |                 std::string_view chassisId, std::string_view chassisSubNode, | 
| Ed Tanous | cf9e417 | 2022-12-21 09:30:16 -0800 | [diff] [blame] | 516 |                 std::span<const std::string_view> sensorTypes, | 
 | 517 |                 Callback&& callback) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 518 | { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 519 |     BMCWEB_LOG_DEBUG("getChassis enter"); | 
| George Liu | 7a1dbc4 | 2022-12-07 16:03:22 +0800 | [diff] [blame] | 520 |     constexpr std::array<std::string_view, 2> interfaces = { | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 521 |         "xyz.openbmc_project.Inventory.Item.Board", | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 522 |         "xyz.openbmc_project.Inventory.Item.Chassis"}; | 
| George Liu | 7a1dbc4 | 2022-12-07 16:03:22 +0800 | [diff] [blame] | 523 |  | 
 | 524 |     // Get the Chassis Collection | 
 | 525 |     dbus::utility::getSubTreePaths( | 
 | 526 |         "/xyz/openbmc_project/inventory", 0, interfaces, | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 527 |         [callback{std::forward<Callback>(callback)}, asyncResp, | 
 | 528 |          chassisIdStr{std::string(chassisId)}, | 
 | 529 |          chassisSubNode{std::string(chassisSubNode)}, sensorTypes]( | 
| George Liu | 7a1dbc4 | 2022-12-07 16:03:22 +0800 | [diff] [blame] | 530 |             const boost::system::error_code& ec, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 531 |             const dbus::utility::MapperGetSubTreePathsResponse& chassisPaths) { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 532 |         BMCWEB_LOG_DEBUG("getChassis respHandler enter"); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 533 |         if (ec) | 
 | 534 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 535 |             BMCWEB_LOG_ERROR("getChassis respHandler DBUS error: {}", ec); | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 536 |             messages::internalError(asyncResp->res); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 537 |             return; | 
 | 538 |         } | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 539 |         const std::string* chassisPath = nullptr; | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 540 |         for (const std::string& chassis : chassisPaths) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 541 |         { | 
| George Liu | 28aa8de | 2021-02-01 15:13:30 +0800 | [diff] [blame] | 542 |             sdbusplus::message::object_path path(chassis); | 
| Ed Tanous | f8fe53e | 2022-06-30 15:55:45 -0700 | [diff] [blame] | 543 |             std::string chassisName = path.filename(); | 
| George Liu | 28aa8de | 2021-02-01 15:13:30 +0800 | [diff] [blame] | 544 |             if (chassisName.empty()) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 545 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 546 |                 BMCWEB_LOG_ERROR("Failed to find '/' in {}", chassis); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 547 |                 continue; | 
 | 548 |             } | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 549 |             if (chassisName == chassisIdStr) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 550 |             { | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 551 |                 chassisPath = &chassis; | 
 | 552 |                 break; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 553 |             } | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 554 |         } | 
 | 555 |         if (chassisPath == nullptr) | 
 | 556 |         { | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 557 |             messages::resourceNotFound(asyncResp->res, "Chassis", chassisIdStr); | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 558 |             return; | 
 | 559 |         } | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 560 |         populateChassisNode(asyncResp->res.jsonValue, chassisSubNode); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 561 |  | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 562 |         asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( | 
 | 563 |             "/redfish/v1/Chassis/{}/{}", chassisIdStr, chassisSubNode); | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 564 |  | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 565 |         // Get the list of all sensors for this Chassis element | 
 | 566 |         std::string sensorPath = *chassisPath + "/all_sensors"; | 
| George Liu | 6c3e945 | 2023-03-03 13:55:29 +0800 | [diff] [blame] | 567 |         dbus::utility::getAssociationEndPoints( | 
 | 568 |             sensorPath, | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 569 |             [asyncResp, chassisSubNode, sensorTypes, | 
| Ed Tanous | f94c4ec | 2022-01-06 12:44:41 -0800 | [diff] [blame] | 570 |              callback{std::forward<const Callback>(callback)}]( | 
| Ed Tanous | 8b24275 | 2023-06-27 17:17:13 -0700 | [diff] [blame] | 571 |                 const boost::system::error_code& ec2, | 
| George Liu | 6c3e945 | 2023-03-03 13:55:29 +0800 | [diff] [blame] | 572 |                 const dbus::utility::MapperEndPoints& nodeSensorList) { | 
| Ed Tanous | 8b24275 | 2023-06-27 17:17:13 -0700 | [diff] [blame] | 573 |             if (ec2) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 574 |             { | 
| Ed Tanous | 8b24275 | 2023-06-27 17:17:13 -0700 | [diff] [blame] | 575 |                 if (ec2.value() != EBADR) | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 576 |                 { | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 577 |                     messages::internalError(asyncResp->res); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 578 |                     return; | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 579 |                 } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 580 |             } | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 581 |             const std::shared_ptr<std::set<std::string>> culledSensorList = | 
 | 582 |                 std::make_shared<std::set<std::string>>(); | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 583 |             reduceSensorList(asyncResp->res, chassisSubNode, sensorTypes, | 
 | 584 |                              &nodeSensorList, culledSensorList); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 585 |             BMCWEB_LOG_DEBUG("Finishing with {}", culledSensorList->size()); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 586 |             callback(culledSensorList); | 
| George Liu | 7a1dbc4 | 2022-12-07 16:03:22 +0800 | [diff] [blame] | 587 |         }); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 588 |     }); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 589 |     BMCWEB_LOG_DEBUG("getChassis exit"); | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 590 | } | 
 | 591 |  | 
 | 592 | /** | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 593 |  * @brief Returns the Redfish State value for the specified inventory item. | 
 | 594 |  * @param inventoryItem D-Bus inventory item associated with a sensor. | 
| Matt Simmering | aaf08ac | 2023-10-04 08:41:01 -0700 | [diff] [blame] | 595 |  * @param sensorAvailable Boolean representing if D-Bus sensor is marked as | 
 | 596 |  * available. | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 597 |  * @return State value for inventory item. | 
| James Feist | 34dd179 | 2019-05-17 14:10:54 -0700 | [diff] [blame] | 598 |  */ | 
| Matt Simmering | aaf08ac | 2023-10-04 08:41:01 -0700 | [diff] [blame] | 599 | inline resource::State getState(const InventoryItem* inventoryItem, | 
 | 600 |                                 const bool sensorAvailable) | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 601 | { | 
 | 602 |     if ((inventoryItem != nullptr) && !(inventoryItem->isPresent)) | 
 | 603 |     { | 
| Matt Simmering | aaf08ac | 2023-10-04 08:41:01 -0700 | [diff] [blame] | 604 |         return resource::State::Absent; | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 605 |     } | 
| James Feist | 34dd179 | 2019-05-17 14:10:54 -0700 | [diff] [blame] | 606 |  | 
| Matt Simmering | aaf08ac | 2023-10-04 08:41:01 -0700 | [diff] [blame] | 607 |     if (!sensorAvailable) | 
 | 608 |     { | 
 | 609 |         return resource::State::UnavailableOffline; | 
 | 610 |     } | 
 | 611 |  | 
 | 612 |     return resource::State::Enabled; | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 613 | } | 
 | 614 |  | 
 | 615 | /** | 
 | 616 |  * @brief Returns the Redfish Health value for the specified sensor. | 
 | 617 |  * @param sensorJson Sensor JSON object. | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 618 |  * @param valuesDict Map of all sensor DBus values. | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 619 |  * @param inventoryItem D-Bus inventory item associated with the sensor.  Will | 
 | 620 |  * be nullptr if no associated inventory item was found. | 
 | 621 |  * @return Health value for sensor. | 
 | 622 |  */ | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 623 | inline std::string getHealth(nlohmann::json& sensorJson, | 
 | 624 |                              const dbus::utility::DBusPropertiesMap& valuesDict, | 
 | 625 |                              const InventoryItem* inventoryItem) | 
| James Feist | 34dd179 | 2019-05-17 14:10:54 -0700 | [diff] [blame] | 626 | { | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 627 |     // Get current health value (if any) in the sensor JSON object.  Some JSON | 
 | 628 |     // objects contain multiple sensors (such as PowerSupplies).  We want to set | 
 | 629 |     // the overall health to be the most severe of any of the sensors. | 
 | 630 |     std::string currentHealth; | 
 | 631 |     auto statusIt = sensorJson.find("Status"); | 
 | 632 |     if (statusIt != sensorJson.end()) | 
 | 633 |     { | 
 | 634 |         auto healthIt = statusIt->find("Health"); | 
 | 635 |         if (healthIt != statusIt->end()) | 
 | 636 |         { | 
 | 637 |             std::string* health = healthIt->get_ptr<std::string*>(); | 
 | 638 |             if (health != nullptr) | 
 | 639 |             { | 
 | 640 |                 currentHealth = *health; | 
 | 641 |             } | 
 | 642 |         } | 
 | 643 |     } | 
 | 644 |  | 
 | 645 |     // If current health in JSON object is already Critical, return that.  This | 
 | 646 |     // should override the sensor health, which might be less severe. | 
 | 647 |     if (currentHealth == "Critical") | 
 | 648 |     { | 
 | 649 |         return "Critical"; | 
 | 650 |     } | 
 | 651 |  | 
| Krzysztof Grobelny | c1343bf | 2022-08-31 13:15:26 +0200 | [diff] [blame] | 652 |     const bool* criticalAlarmHigh = nullptr; | 
 | 653 |     const bool* criticalAlarmLow = nullptr; | 
 | 654 |     const bool* warningAlarmHigh = nullptr; | 
 | 655 |     const bool* warningAlarmLow = nullptr; | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 656 |  | 
| Krzysztof Grobelny | c1343bf | 2022-08-31 13:15:26 +0200 | [diff] [blame] | 657 |     const bool success = sdbusplus::unpackPropertiesNoThrow( | 
 | 658 |         dbus_utils::UnpackErrorPrinter(), valuesDict, "CriticalAlarmHigh", | 
 | 659 |         criticalAlarmHigh, "CriticalAlarmLow", criticalAlarmLow, | 
 | 660 |         "WarningAlarmHigh", warningAlarmHigh, "WarningAlarmLow", | 
 | 661 |         warningAlarmLow); | 
 | 662 |  | 
 | 663 |     if (success) | 
| James Feist | 34dd179 | 2019-05-17 14:10:54 -0700 | [diff] [blame] | 664 |     { | 
| Krzysztof Grobelny | c1343bf | 2022-08-31 13:15:26 +0200 | [diff] [blame] | 665 |         // Check if sensor has critical threshold alarm | 
 | 666 |         if ((criticalAlarmHigh != nullptr && *criticalAlarmHigh) || | 
 | 667 |             (criticalAlarmLow != nullptr && *criticalAlarmLow)) | 
| James Feist | 34dd179 | 2019-05-17 14:10:54 -0700 | [diff] [blame] | 668 |         { | 
| Krzysztof Grobelny | c1343bf | 2022-08-31 13:15:26 +0200 | [diff] [blame] | 669 |             return "Critical"; | 
| James Feist | 34dd179 | 2019-05-17 14:10:54 -0700 | [diff] [blame] | 670 |         } | 
 | 671 |     } | 
 | 672 |  | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 673 |     // Check if associated inventory item is not functional | 
 | 674 |     if ((inventoryItem != nullptr) && !(inventoryItem->isFunctional)) | 
 | 675 |     { | 
 | 676 |         return "Critical"; | 
 | 677 |     } | 
 | 678 |  | 
| Krzysztof Grobelny | c1343bf | 2022-08-31 13:15:26 +0200 | [diff] [blame] | 679 |     // If current health in JSON object is already Warning, return that. This | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 680 |     // should override the sensor status, which might be less severe. | 
 | 681 |     if (currentHealth == "Warning") | 
 | 682 |     { | 
 | 683 |         return "Warning"; | 
 | 684 |     } | 
 | 685 |  | 
| Krzysztof Grobelny | c1343bf | 2022-08-31 13:15:26 +0200 | [diff] [blame] | 686 |     if (success) | 
| James Feist | 34dd179 | 2019-05-17 14:10:54 -0700 | [diff] [blame] | 687 |     { | 
| Krzysztof Grobelny | c1343bf | 2022-08-31 13:15:26 +0200 | [diff] [blame] | 688 |         // Check if sensor has warning threshold alarm | 
 | 689 |         if ((warningAlarmHigh != nullptr && *warningAlarmHigh) || | 
 | 690 |             (warningAlarmLow != nullptr && *warningAlarmLow)) | 
| James Feist | 34dd179 | 2019-05-17 14:10:54 -0700 | [diff] [blame] | 691 |         { | 
| Krzysztof Grobelny | c1343bf | 2022-08-31 13:15:26 +0200 | [diff] [blame] | 692 |             return "Warning"; | 
| James Feist | 34dd179 | 2019-05-17 14:10:54 -0700 | [diff] [blame] | 693 |         } | 
 | 694 |     } | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 695 |  | 
| James Feist | 34dd179 | 2019-05-17 14:10:54 -0700 | [diff] [blame] | 696 |     return "OK"; | 
 | 697 | } | 
 | 698 |  | 
| Ed Tanous | 23a21a1 | 2020-07-25 04:45:05 +0000 | [diff] [blame] | 699 | inline void setLedState(nlohmann::json& sensorJson, | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 700 |                         const InventoryItem* inventoryItem) | 
 | 701 | { | 
 | 702 |     if (inventoryItem != nullptr && !inventoryItem->ledObjectPath.empty()) | 
 | 703 |     { | 
 | 704 |         switch (inventoryItem->ledState) | 
 | 705 |         { | 
 | 706 |             case LedState::OFF: | 
 | 707 |                 sensorJson["IndicatorLED"] = "Off"; | 
 | 708 |                 break; | 
 | 709 |             case LedState::ON: | 
 | 710 |                 sensorJson["IndicatorLED"] = "Lit"; | 
 | 711 |                 break; | 
 | 712 |             case LedState::BLINK: | 
 | 713 |                 sensorJson["IndicatorLED"] = "Blinking"; | 
 | 714 |                 break; | 
| Ed Tanous | 4da0490 | 2024-03-19 11:32:44 -0700 | [diff] [blame] | 715 |             default: | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 716 |                 break; | 
 | 717 |         } | 
 | 718 |     } | 
 | 719 | } | 
 | 720 |  | 
| James Feist | 34dd179 | 2019-05-17 14:10:54 -0700 | [diff] [blame] | 721 | /** | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 722 |  * @brief Builds a json sensor representation of a sensor. | 
 | 723 |  * @param sensorName  The name of the sensor to be built | 
| Gunnar Mills | 274fad5 | 2018-06-13 15:45:36 -0500 | [diff] [blame] | 724 |  * @param sensorType  The type (temperature, fan_tach, etc) of the sensor to | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 725 |  * build | 
| Ed Tanous | 8ece0e4 | 2024-01-02 13:16:50 -0800 | [diff] [blame] | 726 |  * @param chassisSubNode The subnode (thermal, sensor, etc) of the sensor | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 727 |  * @param propertiesDict A dictionary of the properties to build the sensor | 
 | 728 |  * from. | 
 | 729 |  * @param sensorJson  The json object to fill | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 730 |  * @param inventoryItem D-Bus inventory item associated with the sensor.  Will | 
 | 731 |  * be nullptr if no associated inventory item was found. | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 732 |  */ | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 733 | inline void objectPropertiesToJson( | 
 | 734 |     std::string_view sensorName, std::string_view sensorType, | 
 | 735 |     std::string_view chassisSubNode, | 
 | 736 |     const dbus::utility::DBusPropertiesMap& propertiesDict, | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 737 |     nlohmann::json& sensorJson, InventoryItem* inventoryItem) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 738 | { | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 739 |     if (chassisSubNode == sensors::node::sensors) | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 740 |     { | 
| Ed Tanous | c71d612 | 2022-11-29 14:10:32 -0800 | [diff] [blame] | 741 |         std::string subNodeEscaped(sensorType); | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 742 |         auto remove = std::ranges::remove(subNodeEscaped, '_'); | 
 | 743 |         subNodeEscaped.erase(std::ranges::begin(remove), subNodeEscaped.end()); | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 744 |  | 
 | 745 |         // For sensors in SensorCollection we set Id instead of MemberId, | 
 | 746 |         // including power sensors. | 
 | 747 |         subNodeEscaped += '_'; | 
 | 748 |         subNodeEscaped += sensorName; | 
 | 749 |         sensorJson["Id"] = std::move(subNodeEscaped); | 
 | 750 |  | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 751 |         std::string sensorNameEs(sensorName); | 
 | 752 |         std::replace(sensorNameEs.begin(), sensorNameEs.end(), '_', ' '); | 
 | 753 |         sensorJson["Name"] = std::move(sensorNameEs); | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 754 |     } | 
 | 755 |     else if (sensorType != "power") | 
 | 756 |     { | 
 | 757 |         // Set MemberId and Name for non-power sensors.  For PowerSupplies and | 
 | 758 |         // PowerControl, those properties have more general values because | 
 | 759 |         // multiple sensors can be stored in the same JSON object. | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 760 |         std::string sensorNameEs(sensorName); | 
 | 761 |         std::replace(sensorNameEs.begin(), sensorNameEs.end(), '_', ' '); | 
 | 762 |         sensorJson["Name"] = std::move(sensorNameEs); | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 763 |     } | 
| Ed Tanous | e742b6c | 2019-05-03 15:06:53 -0700 | [diff] [blame] | 764 |  | 
| Matt Simmering | aaf08ac | 2023-10-04 08:41:01 -0700 | [diff] [blame] | 765 |     const bool* checkAvailable = nullptr; | 
 | 766 |     bool available = true; | 
 | 767 |     const bool success = sdbusplus::unpackPropertiesNoThrow( | 
 | 768 |         dbus_utils::UnpackErrorPrinter(), propertiesDict, "Available", | 
 | 769 |         checkAvailable); | 
 | 770 |     if (!success) | 
 | 771 |     { | 
 | 772 |         messages::internalError(); | 
 | 773 |     } | 
 | 774 |     if (checkAvailable != nullptr) | 
 | 775 |     { | 
 | 776 |         available = *checkAvailable; | 
 | 777 |     } | 
 | 778 |  | 
 | 779 |     sensorJson["Status"]["State"] = getState(inventoryItem, available); | 
| Patrick Williams | 89492a1 | 2023-05-10 07:51:34 -0500 | [diff] [blame] | 780 |     sensorJson["Status"]["Health"] = getHealth(sensorJson, propertiesDict, | 
 | 781 |                                                inventoryItem); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 782 |  | 
 | 783 |     // Parameter to set to override the type we get from dbus, and force it to | 
 | 784 |     // int, regardless of what is available.  This is used for schemas like fan, | 
 | 785 |     // that require integers, not floats. | 
 | 786 |     bool forceToInt = false; | 
 | 787 |  | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 788 |     nlohmann::json::json_pointer unit("/Reading"); | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 789 |     if (chassisSubNode == sensors::node::sensors) | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 790 |     { | 
| Shounak Mitra | 2a4ba19 | 2022-06-01 23:34:12 +0000 | [diff] [blame] | 791 |         sensorJson["@odata.type"] = "#Sensor.v1_2_0.Sensor"; | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 792 |  | 
| Ed Tanous | 0ec8b83 | 2022-03-14 14:56:47 -0700 | [diff] [blame] | 793 |         sensor::ReadingType readingType = sensors::toReadingType(sensorType); | 
 | 794 |         if (readingType == sensor::ReadingType::Invalid) | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 795 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 796 |             BMCWEB_LOG_ERROR("Redfish cannot map reading type for {}", | 
 | 797 |                              sensorType); | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 798 |         } | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 799 |         else | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 800 |         { | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 801 |             sensorJson["ReadingType"] = readingType; | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 802 |         } | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 803 |  | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 804 |         std::string_view readingUnits = sensors::toReadingUnits(sensorType); | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 805 |         if (readingUnits.empty()) | 
| Adrian Ambrożewicz | f8ede15 | 2020-06-02 13:26:33 +0200 | [diff] [blame] | 806 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 807 |             BMCWEB_LOG_ERROR("Redfish cannot map reading unit for {}", | 
 | 808 |                              sensorType); | 
| Wludzik, Jozef | c2bf7f9 | 2021-03-08 14:35:54 +0000 | [diff] [blame] | 809 |         } | 
 | 810 |         else | 
 | 811 |         { | 
 | 812 |             sensorJson["ReadingUnits"] = readingUnits; | 
| Adrian Ambrożewicz | f8ede15 | 2020-06-02 13:26:33 +0200 | [diff] [blame] | 813 |         } | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 814 |     } | 
 | 815 |     else if (sensorType == "temperature") | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 816 |     { | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 817 |         unit = "/ReadingCelsius"_json_pointer; | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 818 |         sensorJson["@odata.type"] = "#Thermal.v1_3_0.Temperature"; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 819 |         // TODO(ed) Documentation says that path should be type fan_tach, | 
 | 820 |         // implementation seems to implement fan | 
 | 821 |     } | 
 | 822 |     else if (sensorType == "fan" || sensorType == "fan_tach") | 
 | 823 |     { | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 824 |         unit = "/Reading"_json_pointer; | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 825 |         sensorJson["ReadingUnits"] = "RPM"; | 
 | 826 |         sensorJson["@odata.type"] = "#Thermal.v1_3_0.Fan"; | 
 | 827 |         setLedState(sensorJson, inventoryItem); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 828 |         forceToInt = true; | 
 | 829 |     } | 
| Ed Tanous | 6f6d0d3 | 2018-10-12 11:16:43 -0700 | [diff] [blame] | 830 |     else if (sensorType == "fan_pwm") | 
 | 831 |     { | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 832 |         unit = "/Reading"_json_pointer; | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 833 |         sensorJson["ReadingUnits"] = "Percent"; | 
 | 834 |         sensorJson["@odata.type"] = "#Thermal.v1_3_0.Fan"; | 
 | 835 |         setLedState(sensorJson, inventoryItem); | 
| Ed Tanous | 6f6d0d3 | 2018-10-12 11:16:43 -0700 | [diff] [blame] | 836 |         forceToInt = true; | 
 | 837 |     } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 838 |     else if (sensorType == "voltage") | 
 | 839 |     { | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 840 |         unit = "/ReadingVolts"_json_pointer; | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 841 |         sensorJson["@odata.type"] = "#Power.v1_0_0.Voltage"; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 842 |     } | 
| Ed Tanous | 2474adf | 2018-09-05 16:31:16 -0700 | [diff] [blame] | 843 |     else if (sensorType == "power") | 
 | 844 |     { | 
| Ed Tanous | 18f8f60 | 2023-07-18 10:07:23 -0700 | [diff] [blame] | 845 |         std::string lower; | 
 | 846 |         std::ranges::transform(sensorName, std::back_inserter(lower), | 
 | 847 |                                bmcweb::asciiToLower); | 
 | 848 |         if (lower == "total_power") | 
| Eddie James | 028f7eb | 2019-05-17 21:24:36 +0000 | [diff] [blame] | 849 |         { | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 850 |             sensorJson["@odata.type"] = "#Power.v1_0_0.PowerControl"; | 
| Gunnar Mills | 7ab06f4 | 2019-07-02 13:07:16 -0500 | [diff] [blame] | 851 |             // Put multiple "sensors" into a single PowerControl, so have | 
 | 852 |             // generic names for MemberId and Name. Follows Redfish mockup. | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 853 |             sensorJson["MemberId"] = "0"; | 
 | 854 |             sensorJson["Name"] = "Chassis Power Control"; | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 855 |             unit = "/PowerConsumedWatts"_json_pointer; | 
| Eddie James | 028f7eb | 2019-05-17 21:24:36 +0000 | [diff] [blame] | 856 |         } | 
| Ed Tanous | 18f8f60 | 2023-07-18 10:07:23 -0700 | [diff] [blame] | 857 |         else if (lower.find("input") != std::string::npos) | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 858 |         { | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 859 |             unit = "/PowerInputWatts"_json_pointer; | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 860 |         } | 
 | 861 |         else | 
 | 862 |         { | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 863 |             unit = "/PowerOutputWatts"_json_pointer; | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 864 |         } | 
| Ed Tanous | 2474adf | 2018-09-05 16:31:16 -0700 | [diff] [blame] | 865 |     } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 866 |     else | 
 | 867 |     { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 868 |         BMCWEB_LOG_ERROR("Redfish cannot map object type for {}", sensorName); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 869 |         return; | 
 | 870 |     } | 
 | 871 |     // Map of dbus interface name, dbus property name and redfish property_name | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 872 |     std::vector< | 
 | 873 |         std::tuple<const char*, const char*, nlohmann::json::json_pointer>> | 
 | 874 |         properties; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 875 |     properties.reserve(7); | 
 | 876 |  | 
 | 877 |     properties.emplace_back("xyz.openbmc_project.Sensor.Value", "Value", unit); | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 878 |  | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 879 |     if (chassisSubNode == sensors::node::sensors) | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 880 |     { | 
 | 881 |         properties.emplace_back( | 
 | 882 |             "xyz.openbmc_project.Sensor.Threshold.Warning", "WarningHigh", | 
 | 883 |             "/Thresholds/UpperCaution/Reading"_json_pointer); | 
 | 884 |         properties.emplace_back( | 
 | 885 |             "xyz.openbmc_project.Sensor.Threshold.Warning", "WarningLow", | 
 | 886 |             "/Thresholds/LowerCaution/Reading"_json_pointer); | 
 | 887 |         properties.emplace_back( | 
 | 888 |             "xyz.openbmc_project.Sensor.Threshold.Critical", "CriticalHigh", | 
 | 889 |             "/Thresholds/UpperCritical/Reading"_json_pointer); | 
 | 890 |         properties.emplace_back( | 
 | 891 |             "xyz.openbmc_project.Sensor.Threshold.Critical", "CriticalLow", | 
 | 892 |             "/Thresholds/LowerCritical/Reading"_json_pointer); | 
 | 893 |     } | 
 | 894 |     else if (sensorType != "power") | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 895 |     { | 
 | 896 |         properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning", | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 897 |                                 "WarningHigh", | 
 | 898 |                                 "/UpperThresholdNonCritical"_json_pointer); | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 899 |         properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning", | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 900 |                                 "WarningLow", | 
 | 901 |                                 "/LowerThresholdNonCritical"_json_pointer); | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 902 |         properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical", | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 903 |                                 "CriticalHigh", | 
 | 904 |                                 "/UpperThresholdCritical"_json_pointer); | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 905 |         properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical", | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 906 |                                 "CriticalLow", | 
 | 907 |                                 "/LowerThresholdCritical"_json_pointer); | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 908 |     } | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 909 |  | 
| Ed Tanous | 2474adf | 2018-09-05 16:31:16 -0700 | [diff] [blame] | 910 |     // TODO Need to get UpperThresholdFatal and LowerThresholdFatal | 
 | 911 |  | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 912 |     if (chassisSubNode == sensors::node::sensors) | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 913 |     { | 
 | 914 |         properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue", | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 915 |                                 "/ReadingRangeMin"_json_pointer); | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 916 |         properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue", | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 917 |                                 "/ReadingRangeMax"_json_pointer); | 
| George Liu | 51c35a8 | 2022-10-13 20:22:14 +0800 | [diff] [blame] | 918 |         properties.emplace_back("xyz.openbmc_project.Sensor.Accuracy", | 
 | 919 |                                 "Accuracy", "/Accuracy"_json_pointer); | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 920 |     } | 
 | 921 |     else if (sensorType == "temperature") | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 922 |     { | 
 | 923 |         properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue", | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 924 |                                 "/MinReadingRangeTemp"_json_pointer); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 925 |         properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue", | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 926 |                                 "/MaxReadingRangeTemp"_json_pointer); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 927 |     } | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 928 |     else if (sensorType != "power") | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 929 |     { | 
 | 930 |         properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue", | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 931 |                                 "/MinReadingRange"_json_pointer); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 932 |         properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue", | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 933 |                                 "/MaxReadingRange"_json_pointer); | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 934 |     } | 
 | 935 |  | 
| Anthony Wilson | 3929aca | 2019-07-19 15:42:33 -0500 | [diff] [blame] | 936 |     for (const std::tuple<const char*, const char*, | 
 | 937 |                           nlohmann::json::json_pointer>& p : properties) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 938 |     { | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 939 |         for (const auto& [valueName, valueVariant] : propertiesDict) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 940 |         { | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 941 |             if (valueName != std::get<1>(p)) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 942 |             { | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 943 |                 continue; | 
 | 944 |             } | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 945 |  | 
 | 946 |             // The property we want to set may be nested json, so use | 
 | 947 |             // a json_pointer for easy indexing into the json structure. | 
 | 948 |             const nlohmann::json::json_pointer& key = std::get<2>(p); | 
 | 949 |  | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 950 |             const double* doubleValue = std::get_if<double>(&valueVariant); | 
| Ed Tanous | 40e4f38 | 2022-08-09 18:42:51 -0700 | [diff] [blame] | 951 |             if (doubleValue == nullptr) | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 952 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 953 |                 BMCWEB_LOG_ERROR("Got value interface that wasn't double"); | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 954 |                 continue; | 
 | 955 |             } | 
| Ed Tanous | 283860f | 2022-08-29 14:08:50 -0700 | [diff] [blame] | 956 |             if (!std::isfinite(*doubleValue)) | 
 | 957 |             { | 
 | 958 |                 if (valueName == "Value") | 
 | 959 |                 { | 
 | 960 |                     // Readings are allowed to be NAN for unavailable;  coerce | 
 | 961 |                     // them to null in the json response. | 
 | 962 |                     sensorJson[key] = nullptr; | 
 | 963 |                     continue; | 
 | 964 |                 } | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 965 |                 BMCWEB_LOG_WARNING("Sensor value for {} was unexpectedly {}", | 
 | 966 |                                    valueName, *doubleValue); | 
| Ed Tanous | 283860f | 2022-08-29 14:08:50 -0700 | [diff] [blame] | 967 |                 continue; | 
 | 968 |             } | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 969 |             if (forceToInt) | 
 | 970 |             { | 
| Ed Tanous | 40e4f38 | 2022-08-09 18:42:51 -0700 | [diff] [blame] | 971 |                 sensorJson[key] = static_cast<int64_t>(*doubleValue); | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 972 |             } | 
 | 973 |             else | 
 | 974 |             { | 
| Ed Tanous | 40e4f38 | 2022-08-09 18:42:51 -0700 | [diff] [blame] | 975 |                 sensorJson[key] = *doubleValue; | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 976 |             } | 
 | 977 |         } | 
 | 978 |     } | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 979 | } | 
 | 980 |  | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 981 | /** | 
 | 982 |  * @brief Builds a json sensor representation of a sensor. | 
 | 983 |  * @param sensorName  The name of the sensor to be built | 
 | 984 |  * @param sensorType  The type (temperature, fan_tach, etc) of the sensor to | 
 | 985 |  * build | 
| Ed Tanous | 8ece0e4 | 2024-01-02 13:16:50 -0800 | [diff] [blame] | 986 |  * @param chassisSubNode The subnode (thermal, sensor, etc) of the sensor | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 987 |  * @param interfacesDict  A dictionary of the interfaces and properties of said | 
 | 988 |  * interfaces to be built from | 
 | 989 |  * @param sensorJson  The json object to fill | 
 | 990 |  * @param inventoryItem D-Bus inventory item associated with the sensor.  Will | 
 | 991 |  * be nullptr if no associated inventory item was found. | 
 | 992 |  */ | 
 | 993 | inline void objectInterfacesToJson( | 
 | 994 |     const std::string& sensorName, const std::string& sensorType, | 
 | 995 |     const std::string& chassisSubNode, | 
| Michael Shen | 80f79a4 | 2023-08-24 13:41:53 +0000 | [diff] [blame] | 996 |     const dbus::utility::DBusInterfacesMap& interfacesDict, | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 997 |     nlohmann::json& sensorJson, InventoryItem* inventoryItem) | 
 | 998 | { | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 999 |     for (const auto& [interface, valuesDict] : interfacesDict) | 
 | 1000 |     { | 
 | 1001 |         objectPropertiesToJson(sensorName, sensorType, chassisSubNode, | 
 | 1002 |                                valuesDict, sensorJson, inventoryItem); | 
 | 1003 |     } | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1004 |     BMCWEB_LOG_DEBUG("Added sensor {}", sensorName); | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 1005 | } | 
 | 1006 |  | 
| Ed Tanous | b5a7693 | 2020-09-29 16:16:58 -0700 | [diff] [blame] | 1007 | inline void populateFanRedundancy( | 
 | 1008 |     const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp) | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 1009 | { | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 1010 |     constexpr std::array<std::string_view, 1> interfaces = { | 
 | 1011 |         "xyz.openbmc_project.Control.FanRedundancy"}; | 
 | 1012 |     dbus::utility::getSubTree( | 
 | 1013 |         "/xyz/openbmc_project/control", 2, interfaces, | 
| Ed Tanous | b9d36b4 | 2022-02-26 21:42:46 -0800 | [diff] [blame] | 1014 |         [sensorsAsyncResp]( | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 1015 |             const boost::system::error_code& ec, | 
| Ed Tanous | b9d36b4 | 2022-02-26 21:42:46 -0800 | [diff] [blame] | 1016 |             const dbus::utility::MapperGetSubTreeResponse& resp) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1017 |         if (ec) | 
 | 1018 |         { | 
 | 1019 |             return; // don't have to have this interface | 
 | 1020 |         } | 
| George Liu | 6c3e945 | 2023-03-03 13:55:29 +0800 | [diff] [blame] | 1021 |         for (const std::pair<std::string, dbus::utility::MapperServiceMap>& | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1022 |                  pathPair : resp) | 
 | 1023 |         { | 
 | 1024 |             const std::string& path = pathPair.first; | 
| George Liu | 6c3e945 | 2023-03-03 13:55:29 +0800 | [diff] [blame] | 1025 |             const dbus::utility::MapperServiceMap& objDict = pathPair.second; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1026 |             if (objDict.empty()) | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 1027 |             { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1028 |                 continue; // this should be impossible | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 1029 |             } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1030 |  | 
 | 1031 |             const std::string& owner = objDict.begin()->first; | 
| George Liu | 6c3e945 | 2023-03-03 13:55:29 +0800 | [diff] [blame] | 1032 |             dbus::utility::getAssociationEndPoints( | 
 | 1033 |                 path + "/chassis", | 
 | 1034 |                 [path, owner, sensorsAsyncResp]( | 
| Ed Tanous | 8b24275 | 2023-06-27 17:17:13 -0700 | [diff] [blame] | 1035 |                     const boost::system::error_code& ec2, | 
| George Liu | 6c3e945 | 2023-03-03 13:55:29 +0800 | [diff] [blame] | 1036 |                     const dbus::utility::MapperEndPoints& endpoints) { | 
| Ed Tanous | 8b24275 | 2023-06-27 17:17:13 -0700 | [diff] [blame] | 1037 |                 if (ec2) | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 1038 |                 { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1039 |                     return; // if they don't have an association we | 
 | 1040 |                             // can't tell what chassis is | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 1041 |                 } | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 1042 |                 auto found = std::ranges::find_if( | 
 | 1043 |                     endpoints, [sensorsAsyncResp](const std::string& entry) { | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1044 |                     return entry.find(sensorsAsyncResp->chassisId) != | 
 | 1045 |                            std::string::npos; | 
 | 1046 |                 }); | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 1047 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1048 |                 if (found == endpoints.end()) | 
 | 1049 |                 { | 
 | 1050 |                     return; | 
 | 1051 |                 } | 
| Krzysztof Grobelny | 86d89ed | 2022-08-29 14:49:20 +0200 | [diff] [blame] | 1052 |                 sdbusplus::asio::getAllProperties( | 
 | 1053 |                     *crow::connections::systemBus, owner, path, | 
 | 1054 |                     "xyz.openbmc_project.Control.FanRedundancy", | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1055 |                     [path, sensorsAsyncResp]( | 
| Ed Tanous | 8b24275 | 2023-06-27 17:17:13 -0700 | [diff] [blame] | 1056 |                         const boost::system::error_code& ec3, | 
| Krzysztof Grobelny | 86d89ed | 2022-08-29 14:49:20 +0200 | [diff] [blame] | 1057 |                         const dbus::utility::DBusPropertiesMap& ret) { | 
| Ed Tanous | 8b24275 | 2023-06-27 17:17:13 -0700 | [diff] [blame] | 1058 |                     if (ec3) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1059 |                     { | 
 | 1060 |                         return; // don't have to have this | 
 | 1061 |                                 // interface | 
 | 1062 |                     } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1063 |  | 
| Krzysztof Grobelny | 86d89ed | 2022-08-29 14:49:20 +0200 | [diff] [blame] | 1064 |                     const uint8_t* allowedFailures = nullptr; | 
 | 1065 |                     const std::vector<std::string>* collection = nullptr; | 
 | 1066 |                     const std::string* status = nullptr; | 
 | 1067 |  | 
 | 1068 |                     const bool success = sdbusplus::unpackPropertiesNoThrow( | 
 | 1069 |                         dbus_utils::UnpackErrorPrinter(), ret, | 
 | 1070 |                         "AllowedFailures", allowedFailures, "Collection", | 
 | 1071 |                         collection, "Status", status); | 
 | 1072 |  | 
 | 1073 |                     if (!success) | 
 | 1074 |                     { | 
 | 1075 |                         messages::internalError( | 
 | 1076 |                             sensorsAsyncResp->asyncResp->res); | 
 | 1077 |                         return; | 
 | 1078 |                     } | 
 | 1079 |  | 
 | 1080 |                     if (allowedFailures == nullptr || collection == nullptr || | 
 | 1081 |                         status == nullptr) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1082 |                     { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1083 |                         BMCWEB_LOG_ERROR("Invalid redundancy interface"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1084 |                         messages::internalError( | 
 | 1085 |                             sensorsAsyncResp->asyncResp->res); | 
 | 1086 |                         return; | 
 | 1087 |                     } | 
 | 1088 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1089 |                     sdbusplus::message::object_path objectPath(path); | 
 | 1090 |                     std::string name = objectPath.filename(); | 
 | 1091 |                     if (name.empty()) | 
 | 1092 |                     { | 
 | 1093 |                         // this should be impossible | 
 | 1094 |                         messages::internalError( | 
 | 1095 |                             sensorsAsyncResp->asyncResp->res); | 
 | 1096 |                         return; | 
 | 1097 |                     } | 
| Ed Tanous | 18f8f60 | 2023-07-18 10:07:23 -0700 | [diff] [blame] | 1098 |                     std::ranges::replace(name, '_', ' '); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1099 |  | 
 | 1100 |                     std::string health; | 
 | 1101 |  | 
| Ed Tanous | 11ba397 | 2022-07-11 09:50:41 -0700 | [diff] [blame] | 1102 |                     if (status->ends_with("Full")) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1103 |                     { | 
 | 1104 |                         health = "OK"; | 
 | 1105 |                     } | 
| Ed Tanous | 11ba397 | 2022-07-11 09:50:41 -0700 | [diff] [blame] | 1106 |                     else if (status->ends_with("Degraded")) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1107 |                     { | 
 | 1108 |                         health = "Warning"; | 
 | 1109 |                     } | 
 | 1110 |                     else | 
 | 1111 |                     { | 
 | 1112 |                         health = "Critical"; | 
 | 1113 |                     } | 
 | 1114 |                     nlohmann::json::array_t redfishCollection; | 
 | 1115 |                     const auto& fanRedfish = | 
 | 1116 |                         sensorsAsyncResp->asyncResp->res.jsonValue["Fans"]; | 
 | 1117 |                     for (const std::string& item : *collection) | 
 | 1118 |                     { | 
| Ed Tanous | 8a59281 | 2022-06-04 09:06:59 -0700 | [diff] [blame] | 1119 |                         sdbusplus::message::object_path itemPath(item); | 
 | 1120 |                         std::string itemName = itemPath.filename(); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1121 |                         if (itemName.empty()) | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 1122 |                         { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1123 |                             continue; | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 1124 |                         } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1125 |                         /* | 
 | 1126 |                         todo(ed): merge patch that fixes the names | 
 | 1127 |                         std::replace(itemName.begin(), | 
 | 1128 |                                      itemName.end(), '_', ' ');*/ | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 1129 |                         auto schemaItem = std::ranges::find_if( | 
 | 1130 |                             fanRedfish, [itemName](const nlohmann::json& fan) { | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1131 |                             return fan["Name"] == itemName; | 
 | 1132 |                         }); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1133 |                         if (schemaItem != fanRedfish.end()) | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 1134 |                         { | 
| Ed Tanous | 8a59281 | 2022-06-04 09:06:59 -0700 | [diff] [blame] | 1135 |                             nlohmann::json::object_t collectionId; | 
 | 1136 |                             collectionId["@odata.id"] = | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1137 |                                 (*schemaItem)["@odata.id"]; | 
 | 1138 |                             redfishCollection.emplace_back( | 
| Ed Tanous | 8a59281 | 2022-06-04 09:06:59 -0700 | [diff] [blame] | 1139 |                                 std::move(collectionId)); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1140 |                         } | 
 | 1141 |                         else | 
 | 1142 |                         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1143 |                             BMCWEB_LOG_ERROR("failed to find fan in schema"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1144 |                             messages::internalError( | 
 | 1145 |                                 sensorsAsyncResp->asyncResp->res); | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 1146 |                             return; | 
 | 1147 |                         } | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1148 |                     } | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 1149 |  | 
| Patrick Williams | 89492a1 | 2023-05-10 07:51:34 -0500 | [diff] [blame] | 1150 |                     size_t minNumNeeded = collection->empty() | 
 | 1151 |                                               ? 0 | 
 | 1152 |                                               : collection->size() - | 
 | 1153 |                                                     *allowedFailures; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1154 |                     nlohmann::json& jResp = sensorsAsyncResp->asyncResp->res | 
 | 1155 |                                                 .jsonValue["Redundancy"]; | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 1156 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1157 |                     nlohmann::json::object_t redundancy; | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 1158 |                     boost::urls::url url = | 
 | 1159 |                         boost::urls::format("/redfish/v1/Chassis/{}/{}", | 
 | 1160 |                                             sensorsAsyncResp->chassisId, | 
 | 1161 |                                             sensorsAsyncResp->chassisSubNode); | 
| Willy Tu | eddfc43 | 2022-09-26 16:46:38 +0000 | [diff] [blame] | 1162 |                     url.set_fragment(("/Redundancy"_json_pointer / jResp.size()) | 
 | 1163 |                                          .to_string()); | 
 | 1164 |                     redundancy["@odata.id"] = std::move(url); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1165 |                     redundancy["@odata.type"] = "#Redundancy.v1_3_2.Redundancy"; | 
 | 1166 |                     redundancy["MinNumNeeded"] = minNumNeeded; | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1167 |                     redundancy["Mode"] = "N+m"; | 
 | 1168 |                     redundancy["Name"] = name; | 
 | 1169 |                     redundancy["RedundancySet"] = redfishCollection; | 
 | 1170 |                     redundancy["Status"]["Health"] = health; | 
 | 1171 |                     redundancy["Status"]["State"] = "Enabled"; | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 1172 |  | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 1173 |                     jResp.emplace_back(std::move(redundancy)); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1174 |                 }); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1175 |             }); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1176 |         } | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1177 |     }); | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 1178 | } | 
 | 1179 |  | 
| Ed Tanous | b5a7693 | 2020-09-29 16:16:58 -0700 | [diff] [blame] | 1180 | inline void | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 1181 |     sortJSONResponse(const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp) | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 1182 | { | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 1183 |     nlohmann::json& response = sensorsAsyncResp->asyncResp->res.jsonValue; | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 1184 |     std::array<std::string, 2> sensorHeaders{"Temperatures", "Fans"}; | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 1185 |     if (sensorsAsyncResp->chassisSubNode == sensors::node::power) | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 1186 |     { | 
 | 1187 |         sensorHeaders = {"Voltages", "PowerSupplies"}; | 
 | 1188 |     } | 
 | 1189 |     for (const std::string& sensorGroup : sensorHeaders) | 
 | 1190 |     { | 
 | 1191 |         nlohmann::json::iterator entry = response.find(sensorGroup); | 
 | 1192 |         if (entry != response.end()) | 
 | 1193 |         { | 
 | 1194 |             std::sort(entry->begin(), entry->end(), | 
| Ed Tanous | 02cad96 | 2022-06-30 16:50:15 -0700 | [diff] [blame] | 1195 |                       [](const nlohmann::json& c1, const nlohmann::json& c2) { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1196 |                 return c1["Name"] < c2["Name"]; | 
 | 1197 |             }); | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 1198 |  | 
 | 1199 |             // add the index counts to the end of each entry | 
 | 1200 |             size_t count = 0; | 
 | 1201 |             for (nlohmann::json& sensorJson : *entry) | 
 | 1202 |             { | 
 | 1203 |                 nlohmann::json::iterator odata = sensorJson.find("@odata.id"); | 
 | 1204 |                 if (odata == sensorJson.end()) | 
 | 1205 |                 { | 
 | 1206 |                     continue; | 
 | 1207 |                 } | 
 | 1208 |                 std::string* value = odata->get_ptr<std::string*>(); | 
 | 1209 |                 if (value != nullptr) | 
 | 1210 |                 { | 
| Willy Tu | eddfc43 | 2022-09-26 16:46:38 +0000 | [diff] [blame] | 1211 |                     *value += "/" + std::to_string(count); | 
| George Liu | 3e35c76 | 2023-03-08 16:56:38 +0800 | [diff] [blame] | 1212 |                     sensorJson["MemberId"] = std::to_string(count); | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 1213 |                     count++; | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 1214 |                     sensorsAsyncResp->updateUri(sensorJson["Name"], *value); | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 1215 |                 } | 
 | 1216 |             } | 
 | 1217 |         } | 
 | 1218 |     } | 
 | 1219 | } | 
 | 1220 |  | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 1221 | /** | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1222 |  * @brief Finds the inventory item with the specified object path. | 
 | 1223 |  * @param inventoryItems D-Bus inventory items associated with sensors. | 
 | 1224 |  * @param invItemObjPath D-Bus object path of inventory item. | 
 | 1225 |  * @return Inventory item within vector, or nullptr if no match found. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1226 |  */ | 
| Ed Tanous | 23a21a1 | 2020-07-25 04:45:05 +0000 | [diff] [blame] | 1227 | inline InventoryItem* findInventoryItem( | 
| Ed Tanous | b5a7693 | 2020-09-29 16:16:58 -0700 | [diff] [blame] | 1228 |     const std::shared_ptr<std::vector<InventoryItem>>& inventoryItems, | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1229 |     const std::string& invItemObjPath) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1230 | { | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1231 |     for (InventoryItem& inventoryItem : *inventoryItems) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1232 |     { | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1233 |         if (inventoryItem.objectPath == invItemObjPath) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1234 |         { | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1235 |             return &inventoryItem; | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1236 |         } | 
 | 1237 |     } | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1238 |     return nullptr; | 
 | 1239 | } | 
 | 1240 |  | 
 | 1241 | /** | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1242 |  * @brief Finds the inventory item associated with the specified sensor. | 
 | 1243 |  * @param inventoryItems D-Bus inventory items associated with sensors. | 
 | 1244 |  * @param sensorObjPath D-Bus object path of sensor. | 
 | 1245 |  * @return Inventory item within vector, or nullptr if no match found. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1246 |  */ | 
| Ed Tanous | 23a21a1 | 2020-07-25 04:45:05 +0000 | [diff] [blame] | 1247 | inline InventoryItem* findInventoryItemForSensor( | 
| Ed Tanous | b5a7693 | 2020-09-29 16:16:58 -0700 | [diff] [blame] | 1248 |     const std::shared_ptr<std::vector<InventoryItem>>& inventoryItems, | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1249 |     const std::string& sensorObjPath) | 
 | 1250 | { | 
 | 1251 |     for (InventoryItem& inventoryItem : *inventoryItems) | 
 | 1252 |     { | 
| Ed Tanous | db0d36e | 2023-06-30 10:37:05 -0700 | [diff] [blame] | 1253 |         if (inventoryItem.sensors.contains(sensorObjPath)) | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1254 |         { | 
 | 1255 |             return &inventoryItem; | 
 | 1256 |         } | 
 | 1257 |     } | 
 | 1258 |     return nullptr; | 
 | 1259 | } | 
 | 1260 |  | 
 | 1261 | /** | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1262 |  * @brief Finds the inventory item associated with the specified led path. | 
 | 1263 |  * @param inventoryItems D-Bus inventory items associated with sensors. | 
 | 1264 |  * @param ledObjPath D-Bus object path of led. | 
 | 1265 |  * @return Inventory item within vector, or nullptr if no match found. | 
 | 1266 |  */ | 
 | 1267 | inline InventoryItem* | 
 | 1268 |     findInventoryItemForLed(std::vector<InventoryItem>& inventoryItems, | 
 | 1269 |                             const std::string& ledObjPath) | 
 | 1270 | { | 
 | 1271 |     for (InventoryItem& inventoryItem : inventoryItems) | 
 | 1272 |     { | 
 | 1273 |         if (inventoryItem.ledObjectPath == ledObjPath) | 
 | 1274 |         { | 
 | 1275 |             return &inventoryItem; | 
 | 1276 |         } | 
 | 1277 |     } | 
 | 1278 |     return nullptr; | 
 | 1279 | } | 
 | 1280 |  | 
 | 1281 | /** | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1282 |  * @brief Adds inventory item and associated sensor to specified vector. | 
 | 1283 |  * | 
 | 1284 |  * Adds a new InventoryItem to the vector if necessary.  Searches for an | 
 | 1285 |  * existing InventoryItem with the specified object path.  If not found, one is | 
 | 1286 |  * added to the vector. | 
 | 1287 |  * | 
 | 1288 |  * Next, the specified sensor is added to the set of sensors associated with the | 
 | 1289 |  * InventoryItem. | 
 | 1290 |  * | 
 | 1291 |  * @param inventoryItems D-Bus inventory items associated with sensors. | 
 | 1292 |  * @param invItemObjPath D-Bus object path of inventory item. | 
 | 1293 |  * @param sensorObjPath D-Bus object path of sensor | 
 | 1294 |  */ | 
| Ed Tanous | b5a7693 | 2020-09-29 16:16:58 -0700 | [diff] [blame] | 1295 | inline void addInventoryItem( | 
 | 1296 |     const std::shared_ptr<std::vector<InventoryItem>>& inventoryItems, | 
 | 1297 |     const std::string& invItemObjPath, const std::string& sensorObjPath) | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1298 | { | 
 | 1299 |     // Look for inventory item in vector | 
| Patrick Williams | 89492a1 | 2023-05-10 07:51:34 -0500 | [diff] [blame] | 1300 |     InventoryItem* inventoryItem = findInventoryItem(inventoryItems, | 
 | 1301 |                                                      invItemObjPath); | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1302 |  | 
 | 1303 |     // If inventory item doesn't exist in vector, add it | 
 | 1304 |     if (inventoryItem == nullptr) | 
 | 1305 |     { | 
 | 1306 |         inventoryItems->emplace_back(invItemObjPath); | 
 | 1307 |         inventoryItem = &(inventoryItems->back()); | 
 | 1308 |     } | 
 | 1309 |  | 
 | 1310 |     // Add sensor to set of sensors associated with inventory item | 
 | 1311 |     inventoryItem->sensors.emplace(sensorObjPath); | 
 | 1312 | } | 
 | 1313 |  | 
 | 1314 | /** | 
 | 1315 |  * @brief Stores D-Bus data in the specified inventory item. | 
 | 1316 |  * | 
 | 1317 |  * Finds D-Bus data in the specified map of interfaces.  Stores the data in the | 
 | 1318 |  * specified InventoryItem. | 
 | 1319 |  * | 
 | 1320 |  * This data is later used to provide sensor property values in the JSON | 
 | 1321 |  * response. | 
 | 1322 |  * | 
 | 1323 |  * @param inventoryItem Inventory item where data will be stored. | 
 | 1324 |  * @param interfacesDict Map containing D-Bus interfaces and their properties | 
 | 1325 |  * for the specified inventory item. | 
 | 1326 |  */ | 
| Ed Tanous | 23a21a1 | 2020-07-25 04:45:05 +0000 | [diff] [blame] | 1327 | inline void storeInventoryItemData( | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1328 |     InventoryItem& inventoryItem, | 
| Michael Shen | 80f79a4 | 2023-08-24 13:41:53 +0000 | [diff] [blame] | 1329 |     const dbus::utility::DBusInterfacesMap& interfacesDict) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1330 | { | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1331 |     // Get properties from Inventory.Item interface | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1332 |  | 
| Ed Tanous | 9eb808c | 2022-01-25 10:19:23 -0800 | [diff] [blame] | 1333 |     for (const auto& [interface, values] : interfacesDict) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1334 |     { | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1335 |         if (interface == "xyz.openbmc_project.Inventory.Item") | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1336 |         { | 
| Ed Tanous | 9eb808c | 2022-01-25 10:19:23 -0800 | [diff] [blame] | 1337 |             for (const auto& [name, dbusValue] : values) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1338 |             { | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1339 |                 if (name == "Present") | 
 | 1340 |                 { | 
 | 1341 |                     const bool* value = std::get_if<bool>(&dbusValue); | 
 | 1342 |                     if (value != nullptr) | 
 | 1343 |                     { | 
 | 1344 |                         inventoryItem.isPresent = *value; | 
 | 1345 |                     } | 
 | 1346 |                 } | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1347 |             } | 
 | 1348 |         } | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1349 |         // Check if Inventory.Item.PowerSupply interface is present | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1350 |  | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1351 |         if (interface == "xyz.openbmc_project.Inventory.Item.PowerSupply") | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1352 |         { | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1353 |             inventoryItem.isPowerSupply = true; | 
 | 1354 |         } | 
 | 1355 |  | 
 | 1356 |         // Get properties from Inventory.Decorator.Asset interface | 
 | 1357 |         if (interface == "xyz.openbmc_project.Inventory.Decorator.Asset") | 
 | 1358 |         { | 
| Ed Tanous | 9eb808c | 2022-01-25 10:19:23 -0800 | [diff] [blame] | 1359 |             for (const auto& [name, dbusValue] : values) | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1360 |             { | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1361 |                 if (name == "Manufacturer") | 
 | 1362 |                 { | 
 | 1363 |                     const std::string* value = | 
 | 1364 |                         std::get_if<std::string>(&dbusValue); | 
 | 1365 |                     if (value != nullptr) | 
 | 1366 |                     { | 
 | 1367 |                         inventoryItem.manufacturer = *value; | 
 | 1368 |                     } | 
 | 1369 |                 } | 
 | 1370 |                 if (name == "Model") | 
 | 1371 |                 { | 
 | 1372 |                     const std::string* value = | 
 | 1373 |                         std::get_if<std::string>(&dbusValue); | 
 | 1374 |                     if (value != nullptr) | 
 | 1375 |                     { | 
 | 1376 |                         inventoryItem.model = *value; | 
 | 1377 |                     } | 
 | 1378 |                 } | 
 | 1379 |                 if (name == "SerialNumber") | 
 | 1380 |                 { | 
 | 1381 |                     const std::string* value = | 
 | 1382 |                         std::get_if<std::string>(&dbusValue); | 
 | 1383 |                     if (value != nullptr) | 
 | 1384 |                     { | 
 | 1385 |                         inventoryItem.serialNumber = *value; | 
 | 1386 |                     } | 
 | 1387 |                 } | 
 | 1388 |                 if (name == "PartNumber") | 
 | 1389 |                 { | 
 | 1390 |                     const std::string* value = | 
 | 1391 |                         std::get_if<std::string>(&dbusValue); | 
 | 1392 |                     if (value != nullptr) | 
 | 1393 |                     { | 
 | 1394 |                         inventoryItem.partNumber = *value; | 
 | 1395 |                     } | 
 | 1396 |                 } | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1397 |             } | 
 | 1398 |         } | 
 | 1399 |  | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1400 |         if (interface == | 
 | 1401 |             "xyz.openbmc_project.State.Decorator.OperationalStatus") | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1402 |         { | 
| Ed Tanous | 9eb808c | 2022-01-25 10:19:23 -0800 | [diff] [blame] | 1403 |             for (const auto& [name, dbusValue] : values) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1404 |             { | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1405 |                 if (name == "Functional") | 
 | 1406 |                 { | 
 | 1407 |                     const bool* value = std::get_if<bool>(&dbusValue); | 
 | 1408 |                     if (value != nullptr) | 
 | 1409 |                     { | 
 | 1410 |                         inventoryItem.isFunctional = *value; | 
 | 1411 |                     } | 
 | 1412 |                 } | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1413 |             } | 
 | 1414 |         } | 
 | 1415 |     } | 
 | 1416 | } | 
 | 1417 |  | 
 | 1418 | /** | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1419 |  * @brief Gets D-Bus data for inventory items associated with sensors. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1420 |  * | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1421 |  * Uses the specified connections (services) to obtain D-Bus data for inventory | 
 | 1422 |  * items associated with sensors.  Stores the resulting data in the | 
 | 1423 |  * inventoryItems vector. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1424 |  * | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1425 |  * This data is later used to provide sensor property values in the JSON | 
 | 1426 |  * response. | 
 | 1427 |  * | 
 | 1428 |  * Finds the inventory item data asynchronously.  Invokes callback when data has | 
 | 1429 |  * been obtained. | 
 | 1430 |  * | 
 | 1431 |  * The callback must have the following signature: | 
 | 1432 |  *   @code | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1433 |  *   callback(void) | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1434 |  *   @endcode | 
 | 1435 |  * | 
 | 1436 |  * This function is called recursively, obtaining data asynchronously from one | 
 | 1437 |  * connection in each call.  This ensures the callback is not invoked until the | 
 | 1438 |  * last asynchronous function has completed. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1439 |  * | 
 | 1440 |  * @param sensorsAsyncResp Pointer to object holding response data. | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1441 |  * @param inventoryItems D-Bus inventory items associated with sensors. | 
 | 1442 |  * @param invConnections Connections that provide data for the inventory items. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1443 |  * implements ObjectManager. | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1444 |  * @param callback Callback to invoke when inventory data has been obtained. | 
 | 1445 |  * @param invConnectionsIndex Current index in invConnections.  Only specified | 
 | 1446 |  * in recursive calls to this function. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1447 |  */ | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1448 | template <typename Callback> | 
 | 1449 | static void getInventoryItemsData( | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1450 |     std::shared_ptr<SensorsAsyncResp> sensorsAsyncResp, | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1451 |     std::shared_ptr<std::vector<InventoryItem>> inventoryItems, | 
| Ed Tanous | d009073 | 2022-10-04 17:22:56 -0700 | [diff] [blame] | 1452 |     std::shared_ptr<std::set<std::string>> invConnections, Callback&& callback, | 
 | 1453 |     size_t invConnectionsIndex = 0) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1454 | { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1455 |     BMCWEB_LOG_DEBUG("getInventoryItemsData enter"); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1456 |  | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1457 |     // If no more connections left, call callback | 
 | 1458 |     if (invConnectionsIndex >= invConnections->size()) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1459 |     { | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1460 |         callback(); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1461 |         BMCWEB_LOG_DEBUG("getInventoryItemsData exit"); | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1462 |         return; | 
 | 1463 |     } | 
 | 1464 |  | 
 | 1465 |     // Get inventory item data from current connection | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 1466 |     auto it = invConnections->begin(); | 
 | 1467 |     std::advance(it, invConnectionsIndex); | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1468 |     if (it != invConnections->end()) | 
 | 1469 |     { | 
 | 1470 |         const std::string& invConnection = *it; | 
 | 1471 |  | 
| George Liu | 5eb468d | 2023-06-20 17:03:24 +0800 | [diff] [blame] | 1472 |         // Get all object paths and their interfaces for current connection | 
 | 1473 |         sdbusplus::message::object_path path("/xyz/openbmc_project/inventory"); | 
 | 1474 |         dbus::utility::getManagedObjects( | 
 | 1475 |             invConnection, path, | 
 | 1476 |             [sensorsAsyncResp, inventoryItems, invConnections, | 
 | 1477 |              callback{std::forward<Callback>(callback)}, invConnectionsIndex]( | 
 | 1478 |                 const boost::system::error_code& ec, | 
 | 1479 |                 const dbus::utility::ManagedObjectType& resp) { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1480 |             BMCWEB_LOG_DEBUG("getInventoryItemsData respHandler enter"); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1481 |             if (ec) | 
 | 1482 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1483 |                 BMCWEB_LOG_ERROR( | 
 | 1484 |                     "getInventoryItemsData respHandler DBus error {}", ec); | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 1485 |                 messages::internalError(sensorsAsyncResp->asyncResp->res); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1486 |                 return; | 
 | 1487 |             } | 
 | 1488 |  | 
 | 1489 |             // Loop through returned object paths | 
 | 1490 |             for (const auto& objDictEntry : resp) | 
 | 1491 |             { | 
 | 1492 |                 const std::string& objPath = | 
 | 1493 |                     static_cast<const std::string&>(objDictEntry.first); | 
 | 1494 |  | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1495 |                 // If this object path is one of the specified inventory items | 
| Patrick Williams | 89492a1 | 2023-05-10 07:51:34 -0500 | [diff] [blame] | 1496 |                 InventoryItem* inventoryItem = findInventoryItem(inventoryItems, | 
 | 1497 |                                                                  objPath); | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1498 |                 if (inventoryItem != nullptr) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1499 |                 { | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1500 |                     // Store inventory data in InventoryItem | 
 | 1501 |                     storeInventoryItemData(*inventoryItem, objDictEntry.second); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1502 |                 } | 
 | 1503 |             } | 
 | 1504 |  | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1505 |             // Recurse to get inventory item data from next connection | 
 | 1506 |             getInventoryItemsData(sensorsAsyncResp, inventoryItems, | 
| Ed Tanous | d009073 | 2022-10-04 17:22:56 -0700 | [diff] [blame] | 1507 |                                   invConnections, std::move(callback), | 
 | 1508 |                                   invConnectionsIndex + 1); | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1509 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1510 |             BMCWEB_LOG_DEBUG("getInventoryItemsData respHandler exit"); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1511 |         }); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1512 |     } | 
 | 1513 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1514 |     BMCWEB_LOG_DEBUG("getInventoryItemsData exit"); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1515 | } | 
 | 1516 |  | 
 | 1517 | /** | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1518 |  * @brief Gets connections that provide D-Bus data for inventory items. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1519 |  * | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1520 |  * Gets the D-Bus connections (services) that provide data for the inventory | 
 | 1521 |  * items that are associated with sensors. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1522 |  * | 
 | 1523 |  * Finds the connections asynchronously.  Invokes callback when information has | 
 | 1524 |  * been obtained. | 
 | 1525 |  * | 
 | 1526 |  * The callback must have the following signature: | 
 | 1527 |  *   @code | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 1528 |  *   callback(std::shared_ptr<std::set<std::string>> invConnections) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1529 |  *   @endcode | 
 | 1530 |  * | 
 | 1531 |  * @param sensorsAsyncResp Pointer to object holding response data. | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1532 |  * @param inventoryItems D-Bus inventory items associated with sensors. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1533 |  * @param callback Callback to invoke when connections have been obtained. | 
 | 1534 |  */ | 
 | 1535 | template <typename Callback> | 
 | 1536 | static void getInventoryItemsConnections( | 
| Ed Tanous | b5a7693 | 2020-09-29 16:16:58 -0700 | [diff] [blame] | 1537 |     const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp, | 
 | 1538 |     const std::shared_ptr<std::vector<InventoryItem>>& inventoryItems, | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1539 |     Callback&& callback) | 
 | 1540 | { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1541 |     BMCWEB_LOG_DEBUG("getInventoryItemsConnections enter"); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1542 |  | 
 | 1543 |     const std::string path = "/xyz/openbmc_project/inventory"; | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 1544 |     constexpr std::array<std::string_view, 4> interfaces = { | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1545 |         "xyz.openbmc_project.Inventory.Item", | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1546 |         "xyz.openbmc_project.Inventory.Item.PowerSupply", | 
 | 1547 |         "xyz.openbmc_project.Inventory.Decorator.Asset", | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1548 |         "xyz.openbmc_project.State.Decorator.OperationalStatus"}; | 
 | 1549 |  | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 1550 |     // Make call to ObjectMapper to find all inventory items | 
 | 1551 |     dbus::utility::getSubTree( | 
 | 1552 |         path, 0, interfaces, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1553 |         [callback{std::forward<Callback>(callback)}, sensorsAsyncResp, | 
 | 1554 |          inventoryItems]( | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 1555 |             const boost::system::error_code& ec, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1556 |             const dbus::utility::MapperGetSubTreeResponse& subtree) { | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 1557 |         // Response handler for parsing output from GetSubTree | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1558 |         BMCWEB_LOG_DEBUG("getInventoryItemsConnections respHandler enter"); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1559 |         if (ec) | 
 | 1560 |         { | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 1561 |             messages::internalError(sensorsAsyncResp->asyncResp->res); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1562 |             BMCWEB_LOG_ERROR( | 
 | 1563 |                 "getInventoryItemsConnections respHandler DBus error {}", ec); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1564 |             return; | 
 | 1565 |         } | 
 | 1566 |  | 
 | 1567 |         // Make unique list of connections for desired inventory items | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 1568 |         std::shared_ptr<std::set<std::string>> invConnections = | 
 | 1569 |             std::make_shared<std::set<std::string>>(); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1570 |  | 
 | 1571 |         // Loop through objects from GetSubTree | 
 | 1572 |         for (const std::pair< | 
 | 1573 |                  std::string, | 
 | 1574 |                  std::vector<std::pair<std::string, std::vector<std::string>>>>& | 
 | 1575 |                  object : subtree) | 
 | 1576 |         { | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1577 |             // Check if object path is one of the specified inventory items | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1578 |             const std::string& objPath = object.first; | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1579 |             if (findInventoryItem(inventoryItems, objPath) != nullptr) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1580 |             { | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1581 |                 // Store all connections to inventory item | 
 | 1582 |                 for (const std::pair<std::string, std::vector<std::string>>& | 
 | 1583 |                          objData : object.second) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1584 |                 { | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1585 |                     const std::string& invConnection = objData.first; | 
 | 1586 |                     invConnections->insert(invConnection); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1587 |                 } | 
 | 1588 |             } | 
 | 1589 |         } | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1590 |  | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1591 |         callback(invConnections); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1592 |         BMCWEB_LOG_DEBUG("getInventoryItemsConnections respHandler exit"); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1593 |     }); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1594 |     BMCWEB_LOG_DEBUG("getInventoryItemsConnections exit"); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1595 | } | 
 | 1596 |  | 
 | 1597 | /** | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1598 |  * @brief Gets associations from sensors to inventory items. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1599 |  * | 
 | 1600 |  * Looks for ObjectMapper associations from the specified sensors to related | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1601 |  * inventory items. Then finds the associations from those inventory items to | 
 | 1602 |  * their LEDs, if any. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1603 |  * | 
 | 1604 |  * Finds the inventory items asynchronously.  Invokes callback when information | 
 | 1605 |  * has been obtained. | 
 | 1606 |  * | 
 | 1607 |  * The callback must have the following signature: | 
 | 1608 |  *   @code | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1609 |  *   callback(std::shared_ptr<std::vector<InventoryItem>> inventoryItems) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1610 |  *   @endcode | 
 | 1611 |  * | 
 | 1612 |  * @param sensorsAsyncResp Pointer to object holding response data. | 
 | 1613 |  * @param sensorNames All sensors within the current chassis. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1614 |  * implements ObjectManager. | 
 | 1615 |  * @param callback Callback to invoke when inventory items have been obtained. | 
 | 1616 |  */ | 
 | 1617 | template <typename Callback> | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1618 | static void getInventoryItemAssociations( | 
| Ed Tanous | b5a7693 | 2020-09-29 16:16:58 -0700 | [diff] [blame] | 1619 |     const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp, | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 1620 |     const std::shared_ptr<std::set<std::string>>& sensorNames, | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1621 |     Callback&& callback) | 
 | 1622 | { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1623 |     BMCWEB_LOG_DEBUG("getInventoryItemAssociations enter"); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1624 |  | 
| George Liu | 5eb468d | 2023-06-20 17:03:24 +0800 | [diff] [blame] | 1625 |     // Call GetManagedObjects on the ObjectMapper to get all associations | 
 | 1626 |     sdbusplus::message::object_path path("/"); | 
 | 1627 |     dbus::utility::getManagedObjects( | 
 | 1628 |         "xyz.openbmc_project.ObjectMapper", path, | 
| Ed Tanous | 02cad96 | 2022-06-30 16:50:15 -0700 | [diff] [blame] | 1629 |         [callback{std::forward<Callback>(callback)}, sensorsAsyncResp, | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 1630 |          sensorNames](const boost::system::error_code& ec, | 
| Ed Tanous | 02cad96 | 2022-06-30 16:50:15 -0700 | [diff] [blame] | 1631 |                       const dbus::utility::ManagedObjectType& resp) { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1632 |         BMCWEB_LOG_DEBUG("getInventoryItemAssociations respHandler enter"); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1633 |         if (ec) | 
 | 1634 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1635 |             BMCWEB_LOG_ERROR( | 
 | 1636 |                 "getInventoryItemAssociations respHandler DBus error {}", ec); | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 1637 |             messages::internalError(sensorsAsyncResp->asyncResp->res); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1638 |             return; | 
 | 1639 |         } | 
 | 1640 |  | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1641 |         // Create vector to hold list of inventory items | 
 | 1642 |         std::shared_ptr<std::vector<InventoryItem>> inventoryItems = | 
 | 1643 |             std::make_shared<std::vector<InventoryItem>>(); | 
 | 1644 |  | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1645 |         // Loop through returned object paths | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1646 |         std::string sensorAssocPath; | 
 | 1647 |         sensorAssocPath.reserve(128); // avoid memory allocations | 
 | 1648 |         for (const auto& objDictEntry : resp) | 
 | 1649 |         { | 
 | 1650 |             const std::string& objPath = | 
 | 1651 |                 static_cast<const std::string&>(objDictEntry.first); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1652 |  | 
 | 1653 |             // If path is inventory association for one of the specified sensors | 
 | 1654 |             for (const std::string& sensorName : *sensorNames) | 
 | 1655 |             { | 
 | 1656 |                 sensorAssocPath = sensorName; | 
 | 1657 |                 sensorAssocPath += "/inventory"; | 
 | 1658 |                 if (objPath == sensorAssocPath) | 
 | 1659 |                 { | 
 | 1660 |                     // Get Association interface for object path | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1661 |                     for (const auto& [interface, values] : objDictEntry.second) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1662 |                     { | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1663 |                         if (interface == "xyz.openbmc_project.Association") | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1664 |                         { | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1665 |                             for (const auto& [valueName, value] : values) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1666 |                             { | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1667 |                                 if (valueName == "endpoints") | 
 | 1668 |                                 { | 
 | 1669 |                                     const std::vector<std::string>* endpoints = | 
 | 1670 |                                         std::get_if<std::vector<std::string>>( | 
 | 1671 |                                             &value); | 
 | 1672 |                                     if ((endpoints != nullptr) && | 
 | 1673 |                                         !endpoints->empty()) | 
 | 1674 |                                     { | 
 | 1675 |                                         // Add inventory item to vector | 
 | 1676 |                                         const std::string& invItemPath = | 
 | 1677 |                                             endpoints->front(); | 
 | 1678 |                                         addInventoryItem(inventoryItems, | 
 | 1679 |                                                          invItemPath, | 
 | 1680 |                                                          sensorName); | 
 | 1681 |                                     } | 
 | 1682 |                                 } | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1683 |                             } | 
 | 1684 |                         } | 
 | 1685 |                     } | 
 | 1686 |                     break; | 
 | 1687 |                 } | 
 | 1688 |             } | 
 | 1689 |         } | 
 | 1690 |  | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1691 |         // Now loop through the returned object paths again, this time to | 
 | 1692 |         // find the leds associated with the inventory items we just found | 
 | 1693 |         std::string inventoryAssocPath; | 
 | 1694 |         inventoryAssocPath.reserve(128); // avoid memory allocations | 
 | 1695 |         for (const auto& objDictEntry : resp) | 
 | 1696 |         { | 
 | 1697 |             const std::string& objPath = | 
 | 1698 |                 static_cast<const std::string&>(objDictEntry.first); | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1699 |  | 
 | 1700 |             for (InventoryItem& inventoryItem : *inventoryItems) | 
 | 1701 |             { | 
 | 1702 |                 inventoryAssocPath = inventoryItem.objectPath; | 
 | 1703 |                 inventoryAssocPath += "/leds"; | 
 | 1704 |                 if (objPath == inventoryAssocPath) | 
 | 1705 |                 { | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1706 |                     for (const auto& [interface, values] : objDictEntry.second) | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1707 |                     { | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1708 |                         if (interface == "xyz.openbmc_project.Association") | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1709 |                         { | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1710 |                             for (const auto& [valueName, value] : values) | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1711 |                             { | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1712 |                                 if (valueName == "endpoints") | 
 | 1713 |                                 { | 
 | 1714 |                                     const std::vector<std::string>* endpoints = | 
 | 1715 |                                         std::get_if<std::vector<std::string>>( | 
 | 1716 |                                             &value); | 
 | 1717 |                                     if ((endpoints != nullptr) && | 
 | 1718 |                                         !endpoints->empty()) | 
 | 1719 |                                     { | 
 | 1720 |                                         // Add inventory item to vector | 
 | 1721 |                                         // Store LED path in inventory item | 
 | 1722 |                                         const std::string& ledPath = | 
 | 1723 |                                             endpoints->front(); | 
 | 1724 |                                         inventoryItem.ledObjectPath = ledPath; | 
 | 1725 |                                     } | 
 | 1726 |                                 } | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1727 |                             } | 
 | 1728 |                         } | 
 | 1729 |                     } | 
| Ed Tanous | 711ac7a | 2021-12-20 09:34:41 -0800 | [diff] [blame] | 1730 |  | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1731 |                     break; | 
 | 1732 |                 } | 
 | 1733 |             } | 
 | 1734 |         } | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 1735 |         callback(inventoryItems); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1736 |         BMCWEB_LOG_DEBUG("getInventoryItemAssociations respHandler exit"); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1737 |     }); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1738 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1739 |     BMCWEB_LOG_DEBUG("getInventoryItemAssociations exit"); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 1740 | } | 
 | 1741 |  | 
 | 1742 | /** | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1743 |  * @brief Gets D-Bus data for inventory item leds associated with sensors. | 
 | 1744 |  * | 
 | 1745 |  * Uses the specified connections (services) to obtain D-Bus data for inventory | 
 | 1746 |  * item leds associated with sensors.  Stores the resulting data in the | 
 | 1747 |  * inventoryItems vector. | 
 | 1748 |  * | 
 | 1749 |  * This data is later used to provide sensor property values in the JSON | 
 | 1750 |  * response. | 
 | 1751 |  * | 
 | 1752 |  * Finds the inventory item led data asynchronously.  Invokes callback when data | 
 | 1753 |  * has been obtained. | 
 | 1754 |  * | 
 | 1755 |  * The callback must have the following signature: | 
 | 1756 |  *   @code | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 1757 |  *   callback() | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1758 |  *   @endcode | 
 | 1759 |  * | 
 | 1760 |  * This function is called recursively, obtaining data asynchronously from one | 
 | 1761 |  * connection in each call.  This ensures the callback is not invoked until the | 
 | 1762 |  * last asynchronous function has completed. | 
 | 1763 |  * | 
 | 1764 |  * @param sensorsAsyncResp Pointer to object holding response data. | 
 | 1765 |  * @param inventoryItems D-Bus inventory items associated with sensors. | 
 | 1766 |  * @param ledConnections Connections that provide data for the inventory leds. | 
 | 1767 |  * @param callback Callback to invoke when inventory data has been obtained. | 
 | 1768 |  * @param ledConnectionsIndex Current index in ledConnections.  Only specified | 
 | 1769 |  * in recursive calls to this function. | 
 | 1770 |  */ | 
 | 1771 | template <typename Callback> | 
 | 1772 | void getInventoryLedData( | 
 | 1773 |     std::shared_ptr<SensorsAsyncResp> sensorsAsyncResp, | 
 | 1774 |     std::shared_ptr<std::vector<InventoryItem>> inventoryItems, | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 1775 |     std::shared_ptr<std::map<std::string, std::string>> ledConnections, | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1776 |     Callback&& callback, size_t ledConnectionsIndex = 0) | 
 | 1777 | { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1778 |     BMCWEB_LOG_DEBUG("getInventoryLedData enter"); | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1779 |  | 
 | 1780 |     // If no more connections left, call callback | 
 | 1781 |     if (ledConnectionsIndex >= ledConnections->size()) | 
 | 1782 |     { | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 1783 |         callback(); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1784 |         BMCWEB_LOG_DEBUG("getInventoryLedData exit"); | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1785 |         return; | 
 | 1786 |     } | 
 | 1787 |  | 
 | 1788 |     // Get inventory item data from current connection | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 1789 |     auto it = ledConnections->begin(); | 
 | 1790 |     std::advance(it, ledConnectionsIndex); | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1791 |     if (it != ledConnections->end()) | 
 | 1792 |     { | 
 | 1793 |         const std::string& ledPath = (*it).first; | 
 | 1794 |         const std::string& ledConnection = (*it).second; | 
 | 1795 |         // Response handler for Get State property | 
| Jonathan Doman | 1e1e598 | 2021-06-11 09:36:17 -0700 | [diff] [blame] | 1796 |         auto respHandler = | 
 | 1797 |             [sensorsAsyncResp, inventoryItems, ledConnections, ledPath, | 
| Ed Tanous | f94c4ec | 2022-01-06 12:44:41 -0800 | [diff] [blame] | 1798 |              callback{std::forward<Callback>(callback)}, ledConnectionsIndex]( | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 1799 |                 const boost::system::error_code& ec, const std::string& state) { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1800 |             BMCWEB_LOG_DEBUG("getInventoryLedData respHandler enter"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1801 |             if (ec) | 
 | 1802 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1803 |                 BMCWEB_LOG_ERROR( | 
 | 1804 |                     "getInventoryLedData respHandler DBus error {}", ec); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1805 |                 messages::internalError(sensorsAsyncResp->asyncResp->res); | 
 | 1806 |                 return; | 
 | 1807 |             } | 
 | 1808 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1809 |             BMCWEB_LOG_DEBUG("Led state: {}", state); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1810 |             // Find inventory item with this LED object path | 
 | 1811 |             InventoryItem* inventoryItem = | 
 | 1812 |                 findInventoryItemForLed(*inventoryItems, ledPath); | 
 | 1813 |             if (inventoryItem != nullptr) | 
 | 1814 |             { | 
 | 1815 |                 // Store LED state in InventoryItem | 
| Ed Tanous | 11ba397 | 2022-07-11 09:50:41 -0700 | [diff] [blame] | 1816 |                 if (state.ends_with("On")) | 
| Jonathan Doman | 1e1e598 | 2021-06-11 09:36:17 -0700 | [diff] [blame] | 1817 |                 { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1818 |                     inventoryItem->ledState = LedState::ON; | 
| Jonathan Doman | 1e1e598 | 2021-06-11 09:36:17 -0700 | [diff] [blame] | 1819 |                 } | 
| Ed Tanous | 11ba397 | 2022-07-11 09:50:41 -0700 | [diff] [blame] | 1820 |                 else if (state.ends_with("Blink")) | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1821 |                 { | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1822 |                     inventoryItem->ledState = LedState::BLINK; | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1823 |                 } | 
| Ed Tanous | 11ba397 | 2022-07-11 09:50:41 -0700 | [diff] [blame] | 1824 |                 else if (state.ends_with("Off")) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1825 |                 { | 
 | 1826 |                     inventoryItem->ledState = LedState::OFF; | 
 | 1827 |                 } | 
 | 1828 |                 else | 
 | 1829 |                 { | 
 | 1830 |                     inventoryItem->ledState = LedState::UNKNOWN; | 
 | 1831 |                 } | 
 | 1832 |             } | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1833 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1834 |             // Recurse to get LED data from next connection | 
 | 1835 |             getInventoryLedData(sensorsAsyncResp, inventoryItems, | 
 | 1836 |                                 ledConnections, std::move(callback), | 
 | 1837 |                                 ledConnectionsIndex + 1); | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1838 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1839 |             BMCWEB_LOG_DEBUG("getInventoryLedData respHandler exit"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1840 |         }; | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1841 |  | 
 | 1842 |         // Get the State property for the current LED | 
| Jonathan Doman | 1e1e598 | 2021-06-11 09:36:17 -0700 | [diff] [blame] | 1843 |         sdbusplus::asio::getProperty<std::string>( | 
 | 1844 |             *crow::connections::systemBus, ledConnection, ledPath, | 
 | 1845 |             "xyz.openbmc_project.Led.Physical", "State", | 
 | 1846 |             std::move(respHandler)); | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1847 |     } | 
 | 1848 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1849 |     BMCWEB_LOG_DEBUG("getInventoryLedData exit"); | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1850 | } | 
 | 1851 |  | 
 | 1852 | /** | 
 | 1853 |  * @brief Gets LED data for LEDs associated with given inventory items. | 
 | 1854 |  * | 
 | 1855 |  * Gets the D-Bus connections (services) that provide LED data for the LEDs | 
 | 1856 |  * associated with the specified inventory items.  Then gets the LED data from | 
 | 1857 |  * each connection and stores it in the inventory item. | 
 | 1858 |  * | 
 | 1859 |  * This data is later used to provide sensor property values in the JSON | 
 | 1860 |  * response. | 
 | 1861 |  * | 
 | 1862 |  * Finds the LED data asynchronously.  Invokes callback when information has | 
 | 1863 |  * been obtained. | 
 | 1864 |  * | 
 | 1865 |  * The callback must have the following signature: | 
 | 1866 |  *   @code | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 1867 |  *   callback() | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1868 |  *   @endcode | 
 | 1869 |  * | 
 | 1870 |  * @param sensorsAsyncResp Pointer to object holding response data. | 
 | 1871 |  * @param inventoryItems D-Bus inventory items associated with sensors. | 
 | 1872 |  * @param callback Callback to invoke when inventory items have been obtained. | 
 | 1873 |  */ | 
 | 1874 | template <typename Callback> | 
 | 1875 | void getInventoryLeds( | 
 | 1876 |     std::shared_ptr<SensorsAsyncResp> sensorsAsyncResp, | 
 | 1877 |     std::shared_ptr<std::vector<InventoryItem>> inventoryItems, | 
 | 1878 |     Callback&& callback) | 
 | 1879 | { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1880 |     BMCWEB_LOG_DEBUG("getInventoryLeds enter"); | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1881 |  | 
 | 1882 |     const std::string path = "/xyz/openbmc_project"; | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 1883 |     constexpr std::array<std::string_view, 1> interfaces = { | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1884 |         "xyz.openbmc_project.Led.Physical"}; | 
 | 1885 |  | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 1886 |     // Make call to ObjectMapper to find all inventory items | 
 | 1887 |     dbus::utility::getSubTree( | 
 | 1888 |         path, 0, interfaces, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1889 |         [callback{std::forward<Callback>(callback)}, sensorsAsyncResp, | 
 | 1890 |          inventoryItems]( | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 1891 |             const boost::system::error_code& ec, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 1892 |             const dbus::utility::MapperGetSubTreeResponse& subtree) { | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 1893 |         // Response handler for parsing output from GetSubTree | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1894 |         BMCWEB_LOG_DEBUG("getInventoryLeds respHandler enter"); | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1895 |         if (ec) | 
 | 1896 |         { | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 1897 |             messages::internalError(sensorsAsyncResp->asyncResp->res); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1898 |             BMCWEB_LOG_ERROR("getInventoryLeds respHandler DBus error {}", ec); | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1899 |             return; | 
 | 1900 |         } | 
 | 1901 |  | 
 | 1902 |         // Build map of LED object paths to connections | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 1903 |         std::shared_ptr<std::map<std::string, std::string>> ledConnections = | 
 | 1904 |             std::make_shared<std::map<std::string, std::string>>(); | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1905 |  | 
 | 1906 |         // Loop through objects from GetSubTree | 
 | 1907 |         for (const std::pair< | 
 | 1908 |                  std::string, | 
 | 1909 |                  std::vector<std::pair<std::string, std::vector<std::string>>>>& | 
 | 1910 |                  object : subtree) | 
 | 1911 |         { | 
 | 1912 |             // Check if object path is LED for one of the specified inventory | 
 | 1913 |             // items | 
 | 1914 |             const std::string& ledPath = object.first; | 
 | 1915 |             if (findInventoryItemForLed(*inventoryItems, ledPath) != nullptr) | 
 | 1916 |             { | 
 | 1917 |                 // Add mapping from ledPath to connection | 
 | 1918 |                 const std::string& connection = object.second.begin()->first; | 
 | 1919 |                 (*ledConnections)[ledPath] = connection; | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1920 |                 BMCWEB_LOG_DEBUG("Added mapping {} -> {}", ledPath, connection); | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1921 |             } | 
 | 1922 |         } | 
 | 1923 |  | 
 | 1924 |         getInventoryLedData(sensorsAsyncResp, inventoryItems, ledConnections, | 
 | 1925 |                             std::move(callback)); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1926 |         BMCWEB_LOG_DEBUG("getInventoryLeds respHandler exit"); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1927 |     }); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1928 |     BMCWEB_LOG_DEBUG("getInventoryLeds exit"); | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 1929 | } | 
 | 1930 |  | 
 | 1931 | /** | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 1932 |  * @brief Gets D-Bus data for Power Supply Attributes such as EfficiencyPercent | 
 | 1933 |  * | 
 | 1934 |  * Uses the specified connections (services) (currently assumes just one) to | 
 | 1935 |  * obtain D-Bus data for Power Supply Attributes. Stores the resulting data in | 
 | 1936 |  * the inventoryItems vector. Only stores data in Power Supply inventoryItems. | 
 | 1937 |  * | 
 | 1938 |  * This data is later used to provide sensor property values in the JSON | 
 | 1939 |  * response. | 
 | 1940 |  * | 
 | 1941 |  * Finds the Power Supply Attributes data asynchronously.  Invokes callback | 
 | 1942 |  * when data has been obtained. | 
 | 1943 |  * | 
 | 1944 |  * The callback must have the following signature: | 
 | 1945 |  *   @code | 
 | 1946 |  *   callback(std::shared_ptr<std::vector<InventoryItem>> inventoryItems) | 
 | 1947 |  *   @endcode | 
 | 1948 |  * | 
 | 1949 |  * @param sensorsAsyncResp Pointer to object holding response data. | 
 | 1950 |  * @param inventoryItems D-Bus inventory items associated with sensors. | 
 | 1951 |  * @param psAttributesConnections Connections that provide data for the Power | 
 | 1952 |  *        Supply Attributes | 
 | 1953 |  * @param callback Callback to invoke when data has been obtained. | 
 | 1954 |  */ | 
 | 1955 | template <typename Callback> | 
 | 1956 | void getPowerSupplyAttributesData( | 
| Ed Tanous | b5a7693 | 2020-09-29 16:16:58 -0700 | [diff] [blame] | 1957 |     const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp, | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 1958 |     std::shared_ptr<std::vector<InventoryItem>> inventoryItems, | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 1959 |     const std::map<std::string, std::string>& psAttributesConnections, | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 1960 |     Callback&& callback) | 
 | 1961 | { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1962 |     BMCWEB_LOG_DEBUG("getPowerSupplyAttributesData enter"); | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 1963 |  | 
 | 1964 |     if (psAttributesConnections.empty()) | 
 | 1965 |     { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1966 |         BMCWEB_LOG_DEBUG("Can't find PowerSupplyAttributes, no connections!"); | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 1967 |         callback(inventoryItems); | 
 | 1968 |         return; | 
 | 1969 |     } | 
 | 1970 |  | 
 | 1971 |     // Assuming just one connection (service) for now | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 1972 |     auto it = psAttributesConnections.begin(); | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 1973 |  | 
 | 1974 |     const std::string& psAttributesPath = (*it).first; | 
 | 1975 |     const std::string& psAttributesConnection = (*it).second; | 
 | 1976 |  | 
 | 1977 |     // Response handler for Get DeratingFactor property | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 1978 |     auto respHandler = [sensorsAsyncResp, inventoryItems, | 
 | 1979 |                         callback{std::forward<Callback>(callback)}]( | 
 | 1980 |                            const boost::system::error_code& ec, | 
 | 1981 |                            const uint32_t value) { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1982 |         BMCWEB_LOG_DEBUG("getPowerSupplyAttributesData respHandler enter"); | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 1983 |         if (ec) | 
 | 1984 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1985 |             BMCWEB_LOG_ERROR( | 
 | 1986 |                 "getPowerSupplyAttributesData respHandler DBus error {}", ec); | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 1987 |             messages::internalError(sensorsAsyncResp->asyncResp->res); | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 1988 |             return; | 
 | 1989 |         } | 
 | 1990 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 1991 |         BMCWEB_LOG_DEBUG("PS EfficiencyPercent value: {}", value); | 
| Jonathan Doman | 1e1e598 | 2021-06-11 09:36:17 -0700 | [diff] [blame] | 1992 |         // Store value in Power Supply Inventory Items | 
 | 1993 |         for (InventoryItem& inventoryItem : *inventoryItems) | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 1994 |         { | 
| Ed Tanous | 55f79e6 | 2022-01-25 11:26:16 -0800 | [diff] [blame] | 1995 |             if (inventoryItem.isPowerSupply) | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 1996 |             { | 
| Jonathan Doman | 1e1e598 | 2021-06-11 09:36:17 -0700 | [diff] [blame] | 1997 |                 inventoryItem.powerSupplyEfficiencyPercent = | 
 | 1998 |                     static_cast<int>(value); | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 1999 |             } | 
 | 2000 |         } | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2001 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2002 |         BMCWEB_LOG_DEBUG("getPowerSupplyAttributesData respHandler exit"); | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2003 |         callback(inventoryItems); | 
 | 2004 |     }; | 
 | 2005 |  | 
 | 2006 |     // Get the DeratingFactor property for the PowerSupplyAttributes | 
 | 2007 |     // Currently only property on the interface/only one we care about | 
| Jonathan Doman | 1e1e598 | 2021-06-11 09:36:17 -0700 | [diff] [blame] | 2008 |     sdbusplus::asio::getProperty<uint32_t>( | 
 | 2009 |         *crow::connections::systemBus, psAttributesConnection, psAttributesPath, | 
 | 2010 |         "xyz.openbmc_project.Control.PowerSupplyAttributes", "DeratingFactor", | 
 | 2011 |         std::move(respHandler)); | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2012 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2013 |     BMCWEB_LOG_DEBUG("getPowerSupplyAttributesData exit"); | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2014 | } | 
 | 2015 |  | 
 | 2016 | /** | 
 | 2017 |  * @brief Gets the Power Supply Attributes such as EfficiencyPercent | 
 | 2018 |  * | 
 | 2019 |  * Gets the D-Bus connection (service) that provides Power Supply Attributes | 
 | 2020 |  * data. Then gets the Power Supply Attributes data from the connection | 
 | 2021 |  * (currently just assumes 1 connection) and stores the data in the inventory | 
 | 2022 |  * item. | 
 | 2023 |  * | 
 | 2024 |  * This data is later used to provide sensor property values in the JSON | 
 | 2025 |  * response. DeratingFactor on D-Bus is mapped to EfficiencyPercent on Redfish. | 
 | 2026 |  * | 
 | 2027 |  * Finds the Power Supply Attributes data asynchronously. Invokes callback | 
 | 2028 |  * when information has been obtained. | 
 | 2029 |  * | 
 | 2030 |  * The callback must have the following signature: | 
 | 2031 |  *   @code | 
 | 2032 |  *   callback(std::shared_ptr<std::vector<InventoryItem>> inventoryItems) | 
 | 2033 |  *   @endcode | 
 | 2034 |  * | 
 | 2035 |  * @param sensorsAsyncResp Pointer to object holding response data. | 
 | 2036 |  * @param inventoryItems D-Bus inventory items associated with sensors. | 
 | 2037 |  * @param callback Callback to invoke when data has been obtained. | 
 | 2038 |  */ | 
 | 2039 | template <typename Callback> | 
 | 2040 | void getPowerSupplyAttributes( | 
 | 2041 |     std::shared_ptr<SensorsAsyncResp> sensorsAsyncResp, | 
 | 2042 |     std::shared_ptr<std::vector<InventoryItem>> inventoryItems, | 
 | 2043 |     Callback&& callback) | 
 | 2044 | { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2045 |     BMCWEB_LOG_DEBUG("getPowerSupplyAttributes enter"); | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2046 |  | 
 | 2047 |     // Only need the power supply attributes when the Power Schema | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 2048 |     if (sensorsAsyncResp->chassisSubNode != sensors::node::power) | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2049 |     { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2050 |         BMCWEB_LOG_DEBUG("getPowerSupplyAttributes exit since not Power"); | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2051 |         callback(inventoryItems); | 
 | 2052 |         return; | 
 | 2053 |     } | 
 | 2054 |  | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 2055 |     constexpr std::array<std::string_view, 1> interfaces = { | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2056 |         "xyz.openbmc_project.Control.PowerSupplyAttributes"}; | 
 | 2057 |  | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 2058 |     // Make call to ObjectMapper to find the PowerSupplyAttributes service | 
 | 2059 |     dbus::utility::getSubTree( | 
 | 2060 |         "/xyz/openbmc_project", 0, interfaces, | 
| Ed Tanous | b9d36b4 | 2022-02-26 21:42:46 -0800 | [diff] [blame] | 2061 |         [callback{std::forward<Callback>(callback)}, sensorsAsyncResp, | 
 | 2062 |          inventoryItems]( | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 2063 |             const boost::system::error_code& ec, | 
| Ed Tanous | b9d36b4 | 2022-02-26 21:42:46 -0800 | [diff] [blame] | 2064 |             const dbus::utility::MapperGetSubTreeResponse& subtree) { | 
| George Liu | e99073f | 2022-12-09 11:06:16 +0800 | [diff] [blame] | 2065 |         // Response handler for parsing output from GetSubTree | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2066 |         BMCWEB_LOG_DEBUG("getPowerSupplyAttributes respHandler enter"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2067 |         if (ec) | 
 | 2068 |         { | 
 | 2069 |             messages::internalError(sensorsAsyncResp->asyncResp->res); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2070 |             BMCWEB_LOG_ERROR( | 
 | 2071 |                 "getPowerSupplyAttributes respHandler DBus error {}", ec); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2072 |             return; | 
 | 2073 |         } | 
 | 2074 |         if (subtree.empty()) | 
 | 2075 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2076 |             BMCWEB_LOG_DEBUG("Can't find Power Supply Attributes!"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2077 |             callback(inventoryItems); | 
 | 2078 |             return; | 
 | 2079 |         } | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2080 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2081 |         // Currently we only support 1 power supply attribute, use this for | 
 | 2082 |         // all the power supplies. Build map of object path to connection. | 
 | 2083 |         // Assume just 1 connection and 1 path for now. | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 2084 |         std::map<std::string, std::string> psAttributesConnections; | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2085 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2086 |         if (subtree[0].first.empty() || subtree[0].second.empty()) | 
 | 2087 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2088 |             BMCWEB_LOG_DEBUG("Power Supply Attributes mapper error!"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2089 |             callback(inventoryItems); | 
 | 2090 |             return; | 
 | 2091 |         } | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2092 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2093 |         const std::string& psAttributesPath = subtree[0].first; | 
 | 2094 |         const std::string& connection = subtree[0].second.begin()->first; | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2095 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2096 |         if (connection.empty()) | 
 | 2097 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2098 |             BMCWEB_LOG_DEBUG("Power Supply Attributes mapper error!"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2099 |             callback(inventoryItems); | 
 | 2100 |             return; | 
 | 2101 |         } | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2102 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2103 |         psAttributesConnections[psAttributesPath] = connection; | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2104 |         BMCWEB_LOG_DEBUG("Added mapping {} -> {}", psAttributesPath, | 
 | 2105 |                          connection); | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2106 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2107 |         getPowerSupplyAttributesData(sensorsAsyncResp, inventoryItems, | 
 | 2108 |                                      psAttributesConnections, | 
 | 2109 |                                      std::move(callback)); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2110 |         BMCWEB_LOG_DEBUG("getPowerSupplyAttributes respHandler exit"); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2111 |     }); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2112 |     BMCWEB_LOG_DEBUG("getPowerSupplyAttributes exit"); | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2113 | } | 
 | 2114 |  | 
 | 2115 | /** | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2116 |  * @brief Gets inventory items associated with sensors. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 2117 |  * | 
 | 2118 |  * Finds the inventory items that are associated with the specified sensors. | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2119 |  * Then gets D-Bus data for the inventory items, such as presence and VPD. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 2120 |  * | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2121 |  * This data is later used to provide sensor property values in the JSON | 
 | 2122 |  * response. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 2123 |  * | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2124 |  * Finds the inventory items asynchronously.  Invokes callback when the | 
 | 2125 |  * inventory items have been obtained. | 
 | 2126 |  * | 
 | 2127 |  * The callback must have the following signature: | 
 | 2128 |  *   @code | 
 | 2129 |  *   callback(std::shared_ptr<std::vector<InventoryItem>> inventoryItems) | 
 | 2130 |  *   @endcode | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 2131 |  * | 
 | 2132 |  * @param sensorsAsyncResp Pointer to object holding response data. | 
 | 2133 |  * @param sensorNames All sensors within the current chassis. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 2134 |  * implements ObjectManager. | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2135 |  * @param callback Callback to invoke when inventory items have been obtained. | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 2136 |  */ | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2137 | template <typename Callback> | 
| Ed Tanous | d009073 | 2022-10-04 17:22:56 -0700 | [diff] [blame] | 2138 | static void | 
 | 2139 |     getInventoryItems(std::shared_ptr<SensorsAsyncResp> sensorsAsyncResp, | 
 | 2140 |                       const std::shared_ptr<std::set<std::string>> sensorNames, | 
 | 2141 |                       Callback&& callback) | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 2142 | { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2143 |     BMCWEB_LOG_DEBUG("getInventoryItems enter"); | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2144 |     auto getInventoryItemAssociationsCb = | 
| Ed Tanous | d009073 | 2022-10-04 17:22:56 -0700 | [diff] [blame] | 2145 |         [sensorsAsyncResp, callback{std::forward<Callback>(callback)}]( | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2146 |             std::shared_ptr<std::vector<InventoryItem>> inventoryItems) { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2147 |         BMCWEB_LOG_DEBUG("getInventoryItemAssociationsCb enter"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2148 |         auto getInventoryItemsConnectionsCb = | 
| Ed Tanous | d009073 | 2022-10-04 17:22:56 -0700 | [diff] [blame] | 2149 |             [sensorsAsyncResp, inventoryItems, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2150 |              callback{std::forward<const Callback>(callback)}]( | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 2151 |                 std::shared_ptr<std::set<std::string>> invConnections) { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2152 |             BMCWEB_LOG_DEBUG("getInventoryItemsConnectionsCb enter"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2153 |             auto getInventoryItemsDataCb = [sensorsAsyncResp, inventoryItems, | 
 | 2154 |                                             callback{std::move(callback)}]() { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2155 |                 BMCWEB_LOG_DEBUG("getInventoryItemsDataCb enter"); | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2156 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2157 |                 auto getInventoryLedsCb = [sensorsAsyncResp, inventoryItems, | 
 | 2158 |                                            callback{std::move(callback)}]() { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2159 |                     BMCWEB_LOG_DEBUG("getInventoryLedsCb enter"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2160 |                     // Find Power Supply Attributes and get the data | 
 | 2161 |                     getPowerSupplyAttributes(sensorsAsyncResp, inventoryItems, | 
 | 2162 |                                              std::move(callback)); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2163 |                     BMCWEB_LOG_DEBUG("getInventoryLedsCb exit"); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 2164 |                 }; | 
 | 2165 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2166 |                 // Find led connections and get the data | 
 | 2167 |                 getInventoryLeds(sensorsAsyncResp, inventoryItems, | 
 | 2168 |                                  std::move(getInventoryLedsCb)); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2169 |                 BMCWEB_LOG_DEBUG("getInventoryItemsDataCb exit"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2170 |             }; | 
 | 2171 |  | 
 | 2172 |             // Get inventory item data from connections | 
 | 2173 |             getInventoryItemsData(sensorsAsyncResp, inventoryItems, | 
| Ed Tanous | d009073 | 2022-10-04 17:22:56 -0700 | [diff] [blame] | 2174 |                                   invConnections, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2175 |                                   std::move(getInventoryItemsDataCb)); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2176 |             BMCWEB_LOG_DEBUG("getInventoryItemsConnectionsCb exit"); | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 2177 |         }; | 
 | 2178 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2179 |         // Get connections that provide inventory item data | 
 | 2180 |         getInventoryItemsConnections(sensorsAsyncResp, inventoryItems, | 
 | 2181 |                                      std::move(getInventoryItemsConnectionsCb)); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2182 |         BMCWEB_LOG_DEBUG("getInventoryItemAssociationsCb exit"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2183 |     }; | 
 | 2184 |  | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2185 |     // Get associations from sensors to inventory items | 
| Ed Tanous | d009073 | 2022-10-04 17:22:56 -0700 | [diff] [blame] | 2186 |     getInventoryItemAssociations(sensorsAsyncResp, sensorNames, | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2187 |                                  std::move(getInventoryItemAssociationsCb)); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2188 |     BMCWEB_LOG_DEBUG("getInventoryItems exit"); | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2189 | } | 
 | 2190 |  | 
 | 2191 | /** | 
 | 2192 |  * @brief Returns JSON PowerSupply object for the specified inventory item. | 
 | 2193 |  * | 
 | 2194 |  * Searches for a JSON PowerSupply object that matches the specified inventory | 
 | 2195 |  * item.  If one is not found, a new PowerSupply object is added to the JSON | 
 | 2196 |  * array. | 
 | 2197 |  * | 
 | 2198 |  * Multiple sensors are often associated with one power supply inventory item. | 
 | 2199 |  * As a result, multiple sensor values are stored in one JSON PowerSupply | 
 | 2200 |  * object. | 
 | 2201 |  * | 
 | 2202 |  * @param powerSupplyArray JSON array containing Redfish PowerSupply objects. | 
 | 2203 |  * @param inventoryItem Inventory item for the power supply. | 
 | 2204 |  * @param chassisId Chassis that contains the power supply. | 
 | 2205 |  * @return JSON PowerSupply object for the specified inventory item. | 
 | 2206 |  */ | 
| Ed Tanous | 23a21a1 | 2020-07-25 04:45:05 +0000 | [diff] [blame] | 2207 | inline nlohmann::json& getPowerSupply(nlohmann::json& powerSupplyArray, | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2208 |                                       const InventoryItem& inventoryItem, | 
 | 2209 |                                       const std::string& chassisId) | 
 | 2210 | { | 
| Ed Tanous | 18f8f60 | 2023-07-18 10:07:23 -0700 | [diff] [blame] | 2211 |     std::string nameS; | 
| Alexander Hansen | 6f4bd29 | 2024-03-08 17:04:54 +0100 | [diff] [blame] | 2212 |     nameS.resize(inventoryItem.name.size()); | 
| Ed Tanous | 18f8f60 | 2023-07-18 10:07:23 -0700 | [diff] [blame] | 2213 |     std::ranges::replace_copy(inventoryItem.name, nameS.begin(), '_', ' '); | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2214 |     // Check if matching PowerSupply object already exists in JSON array | 
 | 2215 |     for (nlohmann::json& powerSupply : powerSupplyArray) | 
 | 2216 |     { | 
| Ed Tanous | 18f8f60 | 2023-07-18 10:07:23 -0700 | [diff] [blame] | 2217 |         nlohmann::json::iterator nameIt = powerSupply.find("Name"); | 
 | 2218 |         if (nameIt == powerSupply.end()) | 
 | 2219 |         { | 
 | 2220 |             continue; | 
 | 2221 |         } | 
 | 2222 |         const std::string* name = nameIt->get_ptr<std::string*>(); | 
 | 2223 |         if (name == nullptr) | 
 | 2224 |         { | 
 | 2225 |             continue; | 
 | 2226 |         } | 
 | 2227 |         if (nameS == *name) | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2228 |         { | 
 | 2229 |             return powerSupply; | 
 | 2230 |         } | 
 | 2231 |     } | 
 | 2232 |  | 
 | 2233 |     // Add new PowerSupply object to JSON array | 
 | 2234 |     powerSupplyArray.push_back({}); | 
 | 2235 |     nlohmann::json& powerSupply = powerSupplyArray.back(); | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 2236 |     boost::urls::url url = boost::urls::format("/redfish/v1/Chassis/{}/Power", | 
 | 2237 |                                                chassisId); | 
| Willy Tu | eddfc43 | 2022-09-26 16:46:38 +0000 | [diff] [blame] | 2238 |     url.set_fragment(("/PowerSupplies"_json_pointer).to_string()); | 
 | 2239 |     powerSupply["@odata.id"] = std::move(url); | 
| Ed Tanous | 18f8f60 | 2023-07-18 10:07:23 -0700 | [diff] [blame] | 2240 |     std::string escaped; | 
| Alexander Hansen | 6f4bd29 | 2024-03-08 17:04:54 +0100 | [diff] [blame] | 2241 |     escaped.resize(inventoryItem.name.size()); | 
| Ed Tanous | 18f8f60 | 2023-07-18 10:07:23 -0700 | [diff] [blame] | 2242 |     std::ranges::replace_copy(inventoryItem.name, escaped.begin(), '_', ' '); | 
 | 2243 |     powerSupply["Name"] = std::move(escaped); | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2244 |     powerSupply["Manufacturer"] = inventoryItem.manufacturer; | 
 | 2245 |     powerSupply["Model"] = inventoryItem.model; | 
 | 2246 |     powerSupply["PartNumber"] = inventoryItem.partNumber; | 
 | 2247 |     powerSupply["SerialNumber"] = inventoryItem.serialNumber; | 
| Anthony Wilson | d500549 | 2019-07-31 16:34:17 -0500 | [diff] [blame] | 2248 |     setLedState(powerSupply, &inventoryItem); | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2249 |  | 
| Gunnar Mills | 42cbe53 | 2019-08-15 15:26:54 -0500 | [diff] [blame] | 2250 |     if (inventoryItem.powerSupplyEfficiencyPercent >= 0) | 
 | 2251 |     { | 
 | 2252 |         powerSupply["EfficiencyPercent"] = | 
 | 2253 |             inventoryItem.powerSupplyEfficiencyPercent; | 
 | 2254 |     } | 
 | 2255 |  | 
| Matt Simmering | aaf08ac | 2023-10-04 08:41:01 -0700 | [diff] [blame] | 2256 |     powerSupply["Status"]["State"] = getState(&inventoryItem, true); | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2257 |     const char* health = inventoryItem.isFunctional ? "OK" : "Critical"; | 
 | 2258 |     powerSupply["Status"]["Health"] = health; | 
 | 2259 |  | 
 | 2260 |     return powerSupply; | 
| Shawn McCarney | 8fb49dd | 2019-06-12 17:47:00 -0500 | [diff] [blame] | 2261 | } | 
 | 2262 |  | 
 | 2263 | /** | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2264 |  * @brief Gets the values of the specified sensors. | 
 | 2265 |  * | 
 | 2266 |  * Stores the results as JSON in the SensorsAsyncResp. | 
 | 2267 |  * | 
 | 2268 |  * Gets the sensor values asynchronously.  Stores the results later when the | 
 | 2269 |  * information has been obtained. | 
 | 2270 |  * | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2271 |  * The sensorNames set contains all requested sensors for the current chassis. | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2272 |  * | 
 | 2273 |  * To minimize the number of DBus calls, the DBus method | 
 | 2274 |  * org.freedesktop.DBus.ObjectManager.GetManagedObjects() is used to get the | 
 | 2275 |  * values of all sensors provided by a connection (service). | 
 | 2276 |  * | 
 | 2277 |  * The connections set contains all the connections that provide sensor values. | 
 | 2278 |  * | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2279 |  * The InventoryItem vector contains D-Bus inventory items associated with the | 
 | 2280 |  * sensors.  Inventory item data is needed for some Redfish sensor properties. | 
 | 2281 |  * | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2282 |  * @param SensorsAsyncResp Pointer to object holding response data. | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2283 |  * @param sensorNames All requested sensors within the current chassis. | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2284 |  * @param connections Connections that provide sensor values. | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2285 |  * implements ObjectManager. | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2286 |  * @param inventoryItems Inventory items associated with the sensors. | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2287 |  */ | 
| Ed Tanous | 23a21a1 | 2020-07-25 04:45:05 +0000 | [diff] [blame] | 2288 | inline void getSensorData( | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 2289 |     const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp, | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 2290 |     const std::shared_ptr<std::set<std::string>>& sensorNames, | 
 | 2291 |     const std::set<std::string>& connections, | 
| Ed Tanous | b5a7693 | 2020-09-29 16:16:58 -0700 | [diff] [blame] | 2292 |     const std::shared_ptr<std::vector<InventoryItem>>& inventoryItems) | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2293 | { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2294 |     BMCWEB_LOG_DEBUG("getSensorData enter"); | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2295 |     // Get managed objects from all services exposing sensors | 
 | 2296 |     for (const std::string& connection : connections) | 
 | 2297 |     { | 
| George Liu | 5eb468d | 2023-06-20 17:03:24 +0800 | [diff] [blame] | 2298 |         sdbusplus::message::object_path sensorPath( | 
 | 2299 |             "/xyz/openbmc_project/sensors"); | 
 | 2300 |         dbus::utility::getManagedObjects( | 
 | 2301 |             connection, sensorPath, | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2302 |             [sensorsAsyncResp, sensorNames, | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 2303 |              inventoryItems](const boost::system::error_code& ec, | 
| Ed Tanous | 02cad96 | 2022-06-30 16:50:15 -0700 | [diff] [blame] | 2304 |                              const dbus::utility::ManagedObjectType& resp) { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2305 |             BMCWEB_LOG_DEBUG("getManagedObjectsCb enter"); | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2306 |             if (ec) | 
 | 2307 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2308 |                 BMCWEB_LOG_ERROR("getManagedObjectsCb DBUS error: {}", ec); | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 2309 |                 messages::internalError(sensorsAsyncResp->asyncResp->res); | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2310 |                 return; | 
 | 2311 |             } | 
 | 2312 |             // Go through all objects and update response with sensor data | 
 | 2313 |             for (const auto& objDictEntry : resp) | 
 | 2314 |             { | 
 | 2315 |                 const std::string& objPath = | 
 | 2316 |                     static_cast<const std::string&>(objDictEntry.first); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2317 |                 BMCWEB_LOG_DEBUG("getManagedObjectsCb parsing object {}", | 
 | 2318 |                                  objPath); | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2319 |  | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2320 |                 std::vector<std::string> split; | 
 | 2321 |                 // Reserve space for | 
 | 2322 |                 // /xyz/openbmc_project/sensors/<name>/<subname> | 
 | 2323 |                 split.reserve(6); | 
| Ed Tanous | 50ebd4a | 2023-01-19 19:03:17 -0800 | [diff] [blame] | 2324 |                 // NOLINTNEXTLINE | 
 | 2325 |                 bmcweb::split(split, objPath, '/'); | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2326 |                 if (split.size() < 6) | 
 | 2327 |                 { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2328 |                     BMCWEB_LOG_ERROR("Got path that isn't long enough {}", | 
 | 2329 |                                      objPath); | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2330 |                     continue; | 
 | 2331 |                 } | 
| Ed Tanous | 50ebd4a | 2023-01-19 19:03:17 -0800 | [diff] [blame] | 2332 |                 // These indexes aren't intuitive, as split puts an empty | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2333 |                 // string at the beginning | 
 | 2334 |                 const std::string& sensorType = split[4]; | 
 | 2335 |                 const std::string& sensorName = split[5]; | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2336 |                 BMCWEB_LOG_DEBUG("sensorName {} sensorType {}", sensorName, | 
 | 2337 |                                  sensorType); | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 2338 |                 if (sensorNames->find(objPath) == sensorNames->end()) | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2339 |                 { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2340 |                     BMCWEB_LOG_DEBUG("{} not in sensor list ", sensorName); | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2341 |                     continue; | 
 | 2342 |                 } | 
 | 2343 |  | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2344 |                 // Find inventory item (if any) associated with sensor | 
 | 2345 |                 InventoryItem* inventoryItem = | 
 | 2346 |                     findInventoryItemForSensor(inventoryItems, objPath); | 
 | 2347 |  | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2348 |                 const std::string& sensorSchema = | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 2349 |                     sensorsAsyncResp->chassisSubNode; | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2350 |  | 
 | 2351 |                 nlohmann::json* sensorJson = nullptr; | 
 | 2352 |  | 
| Nan Zhou | 928fefb | 2022-03-28 08:45:00 -0700 | [diff] [blame] | 2353 |                 if (sensorSchema == sensors::node::sensors && | 
 | 2354 |                     !sensorsAsyncResp->efficientExpand) | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2355 |                 { | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2356 |                     std::string sensorTypeEscaped(sensorType); | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 2357 |                     auto remove = std::ranges::remove(sensorTypeEscaped, '_'); | 
 | 2358 |  | 
 | 2359 |                     sensorTypeEscaped.erase(std::ranges::begin(remove), | 
 | 2360 |                                             sensorTypeEscaped.end()); | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2361 |                     std::string sensorId(sensorTypeEscaped); | 
 | 2362 |                     sensorId += "_"; | 
 | 2363 |                     sensorId += sensorName; | 
 | 2364 |  | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 2365 |                     sensorsAsyncResp->asyncResp->res.jsonValue["@odata.id"] = | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 2366 |                         boost::urls::format("/redfish/v1/Chassis/{}/{}/{}", | 
 | 2367 |                                             sensorsAsyncResp->chassisId, | 
 | 2368 |                                             sensorsAsyncResp->chassisSubNode, | 
 | 2369 |                                             sensorId); | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 2370 |                     sensorJson = &(sensorsAsyncResp->asyncResp->res.jsonValue); | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2371 |                 } | 
 | 2372 |                 else | 
 | 2373 |                 { | 
| Ed Tanous | 271584a | 2019-07-09 16:24:22 -0700 | [diff] [blame] | 2374 |                     std::string fieldName; | 
| Nan Zhou | 928fefb | 2022-03-28 08:45:00 -0700 | [diff] [blame] | 2375 |                     if (sensorsAsyncResp->efficientExpand) | 
 | 2376 |                     { | 
 | 2377 |                         fieldName = "Members"; | 
 | 2378 |                     } | 
 | 2379 |                     else if (sensorType == "temperature") | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2380 |                     { | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2381 |                         fieldName = "Temperatures"; | 
 | 2382 |                     } | 
 | 2383 |                     else if (sensorType == "fan" || sensorType == "fan_tach" || | 
 | 2384 |                              sensorType == "fan_pwm") | 
 | 2385 |                     { | 
 | 2386 |                         fieldName = "Fans"; | 
 | 2387 |                     } | 
 | 2388 |                     else if (sensorType == "voltage") | 
 | 2389 |                     { | 
 | 2390 |                         fieldName = "Voltages"; | 
 | 2391 |                     } | 
 | 2392 |                     else if (sensorType == "power") | 
 | 2393 |                     { | 
| Ed Tanous | 55f79e6 | 2022-01-25 11:26:16 -0800 | [diff] [blame] | 2394 |                         if (sensorName == "total_power") | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2395 |                         { | 
 | 2396 |                             fieldName = "PowerControl"; | 
 | 2397 |                         } | 
 | 2398 |                         else if ((inventoryItem != nullptr) && | 
 | 2399 |                                  (inventoryItem->isPowerSupply)) | 
 | 2400 |                         { | 
 | 2401 |                             fieldName = "PowerSupplies"; | 
 | 2402 |                         } | 
 | 2403 |                         else | 
 | 2404 |                         { | 
 | 2405 |                             // Other power sensors are in SensorCollection | 
 | 2406 |                             continue; | 
 | 2407 |                         } | 
 | 2408 |                     } | 
 | 2409 |                     else | 
 | 2410 |                     { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2411 |                         BMCWEB_LOG_ERROR("Unsure how to handle sensorType {}", | 
 | 2412 |                                          sensorType); | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2413 |                         continue; | 
 | 2414 |                     } | 
 | 2415 |  | 
 | 2416 |                     nlohmann::json& tempArray = | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 2417 |                         sensorsAsyncResp->asyncResp->res.jsonValue[fieldName]; | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2418 |                     if (fieldName == "PowerControl") | 
 | 2419 |                     { | 
 | 2420 |                         if (tempArray.empty()) | 
 | 2421 |                         { | 
 | 2422 |                             // Put multiple "sensors" into a single | 
 | 2423 |                             // PowerControl. Follows MemberId naming and | 
 | 2424 |                             // naming in power.hpp. | 
| Ed Tanous | 1476687 | 2022-03-15 10:44:42 -0700 | [diff] [blame] | 2425 |                             nlohmann::json::object_t power; | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 2426 |                             boost::urls::url url = boost::urls::format( | 
 | 2427 |                                 "/redfish/v1/Chassis/{}/{}", | 
| Willy Tu | eddfc43 | 2022-09-26 16:46:38 +0000 | [diff] [blame] | 2428 |                                 sensorsAsyncResp->chassisId, | 
 | 2429 |                                 sensorsAsyncResp->chassisSubNode); | 
 | 2430 |                             url.set_fragment((""_json_pointer / fieldName / "0") | 
 | 2431 |                                                  .to_string()); | 
 | 2432 |                             power["@odata.id"] = std::move(url); | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 2433 |                             tempArray.emplace_back(std::move(power)); | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2434 |                         } | 
 | 2435 |                         sensorJson = &(tempArray.back()); | 
 | 2436 |                     } | 
 | 2437 |                     else if (fieldName == "PowerSupplies") | 
 | 2438 |                     { | 
 | 2439 |                         if (inventoryItem != nullptr) | 
 | 2440 |                         { | 
 | 2441 |                             sensorJson = | 
 | 2442 |                                 &(getPowerSupply(tempArray, *inventoryItem, | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 2443 |                                                  sensorsAsyncResp->chassisId)); | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2444 |                         } | 
 | 2445 |                     } | 
| Nan Zhou | 928fefb | 2022-03-28 08:45:00 -0700 | [diff] [blame] | 2446 |                     else if (fieldName == "Members") | 
 | 2447 |                     { | 
| Ed Tanous | 677bb75 | 2022-09-15 10:52:19 -0700 | [diff] [blame] | 2448 |                         std::string sensorTypeEscaped(sensorType); | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 2449 |                         auto remove = std::ranges::remove(sensorTypeEscaped, | 
 | 2450 |                                                           '_'); | 
 | 2451 |                         sensorTypeEscaped.erase(std::ranges::begin(remove), | 
 | 2452 |                                                 sensorTypeEscaped.end()); | 
| Ed Tanous | 677bb75 | 2022-09-15 10:52:19 -0700 | [diff] [blame] | 2453 |                         std::string sensorId(sensorTypeEscaped); | 
 | 2454 |                         sensorId += "_"; | 
 | 2455 |                         sensorId += sensorName; | 
 | 2456 |  | 
| Ed Tanous | 1476687 | 2022-03-15 10:44:42 -0700 | [diff] [blame] | 2457 |                         nlohmann::json::object_t member; | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 2458 |                         member["@odata.id"] = boost::urls::format( | 
 | 2459 |                             "/redfish/v1/Chassis/{}/{}/{}", | 
| Ed Tanous | 677bb75 | 2022-09-15 10:52:19 -0700 | [diff] [blame] | 2460 |                             sensorsAsyncResp->chassisId, | 
 | 2461 |                             sensorsAsyncResp->chassisSubNode, sensorId); | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 2462 |                         tempArray.emplace_back(std::move(member)); | 
| Nan Zhou | 928fefb | 2022-03-28 08:45:00 -0700 | [diff] [blame] | 2463 |                         sensorJson = &(tempArray.back()); | 
 | 2464 |                     } | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2465 |                     else | 
 | 2466 |                     { | 
| Ed Tanous | 1476687 | 2022-03-15 10:44:42 -0700 | [diff] [blame] | 2467 |                         nlohmann::json::object_t member; | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 2468 |                         boost::urls::url url = boost::urls::format( | 
 | 2469 |                             "/redfish/v1/Chassis/{}/{}", | 
| Willy Tu | eddfc43 | 2022-09-26 16:46:38 +0000 | [diff] [blame] | 2470 |                             sensorsAsyncResp->chassisId, | 
 | 2471 |                             sensorsAsyncResp->chassisSubNode); | 
 | 2472 |                         url.set_fragment( | 
 | 2473 |                             (""_json_pointer / fieldName).to_string()); | 
 | 2474 |                         member["@odata.id"] = std::move(url); | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 2475 |                         tempArray.emplace_back(std::move(member)); | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2476 |                         sensorJson = &(tempArray.back()); | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2477 |                     } | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 2478 |                 } | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2479 |  | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2480 |                 if (sensorJson != nullptr) | 
 | 2481 |                 { | 
| Ed Tanous | 1d7c005 | 2022-08-09 12:32:26 -0700 | [diff] [blame] | 2482 |                     objectInterfacesToJson(sensorName, sensorType, | 
 | 2483 |                                            sensorsAsyncResp->chassisSubNode, | 
 | 2484 |                                            objDictEntry.second, *sensorJson, | 
 | 2485 |                                            inventoryItem); | 
 | 2486 |  | 
 | 2487 |                     std::string path = "/xyz/openbmc_project/sensors/"; | 
 | 2488 |                     path += sensorType; | 
 | 2489 |                     path += "/"; | 
 | 2490 |                     path += sensorName; | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2491 |                     sensorsAsyncResp->addMetadata(*sensorJson, path); | 
| Shawn McCarney | adc4f0d | 2019-07-24 09:21:50 -0500 | [diff] [blame] | 2492 |                 } | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2493 |             } | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 2494 |             if (sensorsAsyncResp.use_count() == 1) | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 2495 |             { | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 2496 |                 sortJSONResponse(sensorsAsyncResp); | 
| Nan Zhou | 928fefb | 2022-03-28 08:45:00 -0700 | [diff] [blame] | 2497 |                 if (sensorsAsyncResp->chassisSubNode == | 
 | 2498 |                         sensors::node::sensors && | 
 | 2499 |                     sensorsAsyncResp->efficientExpand) | 
 | 2500 |                 { | 
 | 2501 |                     sensorsAsyncResp->asyncResp->res | 
 | 2502 |                         .jsonValue["Members@odata.count"] = | 
 | 2503 |                         sensorsAsyncResp->asyncResp->res.jsonValue["Members"] | 
 | 2504 |                             .size(); | 
 | 2505 |                 } | 
 | 2506 |                 else if (sensorsAsyncResp->chassisSubNode == | 
 | 2507 |                          sensors::node::thermal) | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 2508 |                 { | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 2509 |                     populateFanRedundancy(sensorsAsyncResp); | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 2510 |                 } | 
| James Feist | 8bd25cc | 2019-03-15 15:14:00 -0700 | [diff] [blame] | 2511 |             } | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2512 |             BMCWEB_LOG_DEBUG("getManagedObjectsCb exit"); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2513 |         }); | 
| Ed Tanous | 23a21a1 | 2020-07-25 04:45:05 +0000 | [diff] [blame] | 2514 |     } | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2515 |     BMCWEB_LOG_DEBUG("getSensorData exit"); | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2516 | } | 
 | 2517 |  | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 2518 | inline void | 
 | 2519 |     processSensorList(const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp, | 
 | 2520 |                       const std::shared_ptr<std::set<std::string>>& sensorNames) | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2521 | { | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 2522 |     auto getConnectionCb = [sensorsAsyncResp, sensorNames]( | 
 | 2523 |                                const std::set<std::string>& connections) { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2524 |         BMCWEB_LOG_DEBUG("getConnectionCb enter"); | 
| Ed Tanous | d009073 | 2022-10-04 17:22:56 -0700 | [diff] [blame] | 2525 |         auto getInventoryItemsCb = | 
 | 2526 |             [sensorsAsyncResp, sensorNames, | 
 | 2527 |              connections](const std::shared_ptr<std::vector<InventoryItem>>& | 
 | 2528 |                               inventoryItems) { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2529 |             BMCWEB_LOG_DEBUG("getInventoryItemsCb enter"); | 
| Ed Tanous | d009073 | 2022-10-04 17:22:56 -0700 | [diff] [blame] | 2530 |             // Get sensor data and store results in JSON | 
 | 2531 |             getSensorData(sensorsAsyncResp, sensorNames, connections, | 
 | 2532 |                           inventoryItems); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2533 |             BMCWEB_LOG_DEBUG("getInventoryItemsCb exit"); | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2534 |         }; | 
 | 2535 |  | 
| Ed Tanous | d009073 | 2022-10-04 17:22:56 -0700 | [diff] [blame] | 2536 |         // Get inventory items associated with sensors | 
 | 2537 |         getInventoryItems(sensorsAsyncResp, sensorNames, | 
 | 2538 |                           std::move(getInventoryItemsCb)); | 
 | 2539 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2540 |         BMCWEB_LOG_DEBUG("getConnectionCb exit"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2541 |     }; | 
 | 2542 |  | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2543 |     // Get set of connections that provide sensor values | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 2544 |     getConnections(sensorsAsyncResp, sensorNames, std::move(getConnectionCb)); | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2545 | } | 
 | 2546 |  | 
| Shawn McCarney | de629b6 | 2019-03-08 10:42:51 -0600 | [diff] [blame] | 2547 | /** | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 2548 |  * @brief Entry point for retrieving sensors data related to requested | 
 | 2549 |  *        chassis. | 
| Kowalski, Kamil | 588c3f0 | 2018-04-03 14:55:27 +0200 | [diff] [blame] | 2550 |  * @param SensorsAsyncResp   Pointer to object holding response data | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 2551 |  */ | 
| Ed Tanous | b5a7693 | 2020-09-29 16:16:58 -0700 | [diff] [blame] | 2552 | inline void | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 2553 |     getChassisData(const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp) | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 2554 | { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2555 |     BMCWEB_LOG_DEBUG("getChassisData enter"); | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 2556 |     auto getChassisCb = | 
| Ed Tanous | 81ce609 | 2020-12-17 16:54:55 +0000 | [diff] [blame] | 2557 |         [sensorsAsyncResp]( | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 2558 |             const std::shared_ptr<std::set<std::string>>& sensorNames) { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2559 |         BMCWEB_LOG_DEBUG("getChassisCb enter"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2560 |         processSensorList(sensorsAsyncResp, sensorNames); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2561 |         BMCWEB_LOG_DEBUG("getChassisCb exit"); | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2562 |     }; | 
| Nan Zhou | 928fefb | 2022-03-28 08:45:00 -0700 | [diff] [blame] | 2563 |     // SensorCollection doesn't contain the Redundancy property | 
 | 2564 |     if (sensorsAsyncResp->chassisSubNode != sensors::node::sensors) | 
 | 2565 |     { | 
 | 2566 |         sensorsAsyncResp->asyncResp->res.jsonValue["Redundancy"] = | 
 | 2567 |             nlohmann::json::array(); | 
 | 2568 |     } | 
| Shawn McCarney | 26f0389 | 2019-05-03 13:20:24 -0500 | [diff] [blame] | 2569 |     // Get set of sensors in chassis | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 2570 |     getChassis(sensorsAsyncResp->asyncResp, sensorsAsyncResp->chassisId, | 
 | 2571 |                sensorsAsyncResp->chassisSubNode, sensorsAsyncResp->types, | 
 | 2572 |                std::move(getChassisCb)); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2573 |     BMCWEB_LOG_DEBUG("getChassisData exit"); | 
| Ed Tanous | 271584a | 2019-07-09 16:24:22 -0700 | [diff] [blame] | 2574 | } | 
| Lewanczyk, Dawid | 08777fb | 2018-03-22 23:33:49 +0100 | [diff] [blame] | 2575 |  | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 2576 | /** | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 2577 |  * @brief Find the requested sensorName in the list of all sensors supplied by | 
 | 2578 |  * the chassis node | 
 | 2579 |  * | 
 | 2580 |  * @param sensorName   The sensor name supplied in the PATCH request | 
 | 2581 |  * @param sensorsList  The list of sensors managed by the chassis node | 
 | 2582 |  * @param sensorsModified  The list of sensors that were found as a result of | 
 | 2583 |  *                         repeated calls to this function | 
 | 2584 |  */ | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 2585 | inline bool | 
 | 2586 |     findSensorNameUsingSensorPath(std::string_view sensorName, | 
| Ed Tanous | 02cad96 | 2022-06-30 16:50:15 -0700 | [diff] [blame] | 2587 |                                   const std::set<std::string>& sensorsList, | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 2588 |                                   std::set<std::string>& sensorsModified) | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 2589 | { | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 2590 |     for (const auto& chassisSensor : sensorsList) | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 2591 |     { | 
| George Liu | 28aa8de | 2021-02-01 15:13:30 +0800 | [diff] [blame] | 2592 |         sdbusplus::message::object_path path(chassisSensor); | 
| Ed Tanous | b00dcc2 | 2021-02-23 12:52:50 -0800 | [diff] [blame] | 2593 |         std::string thisSensorName = path.filename(); | 
| George Liu | 28aa8de | 2021-02-01 15:13:30 +0800 | [diff] [blame] | 2594 |         if (thisSensorName.empty()) | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 2595 |         { | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 2596 |             continue; | 
 | 2597 |         } | 
 | 2598 |         if (thisSensorName == sensorName) | 
 | 2599 |         { | 
 | 2600 |             sensorsModified.emplace(chassisSensor); | 
 | 2601 |             return true; | 
 | 2602 |         } | 
 | 2603 |     } | 
 | 2604 |     return false; | 
 | 2605 | } | 
 | 2606 |  | 
| Ed Tanous | c71d612 | 2022-11-29 14:10:32 -0800 | [diff] [blame] | 2607 | inline std::pair<std::string, std::string> | 
 | 2608 |     splitSensorNameAndType(std::string_view sensorId) | 
 | 2609 | { | 
 | 2610 |     size_t index = sensorId.find('_'); | 
 | 2611 |     if (index == std::string::npos) | 
 | 2612 |     { | 
 | 2613 |         return std::make_pair<std::string, std::string>("", ""); | 
 | 2614 |     } | 
 | 2615 |     std::string sensorType{sensorId.substr(0, index)}; | 
 | 2616 |     std::string sensorName{sensorId.substr(index + 1)}; | 
 | 2617 |     // fan_pwm and fan_tach need special handling | 
 | 2618 |     if (sensorType == "fantach" || sensorType == "fanpwm") | 
 | 2619 |     { | 
 | 2620 |         sensorType.insert(3, 1, '_'); | 
 | 2621 |     } | 
 | 2622 |     return std::make_pair(sensorType, sensorName); | 
 | 2623 | } | 
 | 2624 |  | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 2625 | /** | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 2626 |  * @brief Entry point for overriding sensor values of given sensor | 
 | 2627 |  * | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 2628 |  * @param sensorAsyncResp   response object | 
| Carol Wang | 4bb3dc3 | 2019-10-17 18:15:02 +0800 | [diff] [blame] | 2629 |  * @param allCollections   Collections extract from sensors' request patch info | 
| jayaprakash Mutyala | 91e130a | 2020-03-04 22:26:38 +0000 | [diff] [blame] | 2630 |  * @param chassisSubNode   Chassis Node for which the query has to happen | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 2631 |  */ | 
| Ed Tanous | 23a21a1 | 2020-07-25 04:45:05 +0000 | [diff] [blame] | 2632 | inline void setSensorsOverride( | 
| Ed Tanous | b5a7693 | 2020-09-29 16:16:58 -0700 | [diff] [blame] | 2633 |     const std::shared_ptr<SensorsAsyncResp>& sensorAsyncResp, | 
| Ed Tanous | 0885057 | 2024-03-06 15:09:17 -0800 | [diff] [blame] | 2634 |     std::unordered_map<std::string, std::vector<nlohmann::json::object_t>>& | 
| jayaprakash Mutyala | 397fd61 | 2020-02-06 23:33:34 +0000 | [diff] [blame] | 2635 |         allCollections) | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 2636 | { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2637 |     BMCWEB_LOG_INFO("setSensorsOverride for subNode{}", | 
 | 2638 |                     sensorAsyncResp->chassisSubNode); | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 2639 |  | 
| Ed Tanous | d02aad3 | 2024-02-13 14:43:34 -0800 | [diff] [blame] | 2640 |     std::string_view propertyValueName; | 
| Richard Marian Thomaiyar | f65af9e | 2019-02-13 23:35:05 +0530 | [diff] [blame] | 2641 |     std::unordered_map<std::string, std::pair<double, std::string>> overrideMap; | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 2642 |     std::string memberId; | 
| Ed Tanous | 543f440 | 2022-01-06 13:12:53 -0800 | [diff] [blame] | 2643 |     double value = 0.0; | 
| Richard Marian Thomaiyar | f65af9e | 2019-02-13 23:35:05 +0530 | [diff] [blame] | 2644 |     for (auto& collectionItems : allCollections) | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 2645 |     { | 
| Richard Marian Thomaiyar | f65af9e | 2019-02-13 23:35:05 +0530 | [diff] [blame] | 2646 |         if (collectionItems.first == "Temperatures") | 
 | 2647 |         { | 
 | 2648 |             propertyValueName = "ReadingCelsius"; | 
 | 2649 |         } | 
 | 2650 |         else if (collectionItems.first == "Fans") | 
 | 2651 |         { | 
 | 2652 |             propertyValueName = "Reading"; | 
 | 2653 |         } | 
 | 2654 |         else | 
 | 2655 |         { | 
 | 2656 |             propertyValueName = "ReadingVolts"; | 
 | 2657 |         } | 
 | 2658 |         for (auto& item : collectionItems.second) | 
 | 2659 |         { | 
| Ed Tanous | 0885057 | 2024-03-06 15:09:17 -0800 | [diff] [blame] | 2660 |             if (!json_util::readJsonObject( | 
 | 2661 |                     item, sensorAsyncResp->asyncResp->res, "MemberId", memberId, | 
 | 2662 |                     propertyValueName, value)) | 
| Richard Marian Thomaiyar | f65af9e | 2019-02-13 23:35:05 +0530 | [diff] [blame] | 2663 |             { | 
 | 2664 |                 return; | 
 | 2665 |             } | 
 | 2666 |             overrideMap.emplace(memberId, | 
 | 2667 |                                 std::make_pair(value, collectionItems.first)); | 
 | 2668 |         } | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 2669 |     } | 
| Carol Wang | 4bb3dc3 | 2019-10-17 18:15:02 +0800 | [diff] [blame] | 2670 |  | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2671 |     auto getChassisSensorListCb = | 
| Ed Tanous | d02aad3 | 2024-02-13 14:43:34 -0800 | [diff] [blame] | 2672 |         [sensorAsyncResp, overrideMap, | 
 | 2673 |          propertyValueNameStr = std::string(propertyValueName)]( | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 2674 |             const std::shared_ptr<std::set<std::string>>& sensorsList) { | 
| Johnathan Mantey | 49c53ac | 2019-05-02 09:22:38 -0700 | [diff] [blame] | 2675 |         // Match sensor names in the PATCH request to those managed by the | 
 | 2676 |         // chassis node | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 2677 |         const std::shared_ptr<std::set<std::string>> sensorNames = | 
 | 2678 |             std::make_shared<std::set<std::string>>(); | 
| Richard Marian Thomaiyar | f65af9e | 2019-02-13 23:35:05 +0530 | [diff] [blame] | 2679 |         for (const auto& item : overrideMap) | 
 | 2680 |         { | 
 | 2681 |             const auto& sensor = item.first; | 
| Ed Tanous | c71d612 | 2022-11-29 14:10:32 -0800 | [diff] [blame] | 2682 |             std::pair<std::string, std::string> sensorNameType = | 
 | 2683 |                 splitSensorNameAndType(sensor); | 
 | 2684 |             if (!findSensorNameUsingSensorPath(sensorNameType.second, | 
 | 2685 |                                                *sensorsList, *sensorNames)) | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 2686 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2687 |                 BMCWEB_LOG_INFO("Unable to find memberId {}", item.first); | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 2688 |                 messages::resourceNotFound(sensorAsyncResp->asyncResp->res, | 
| Richard Marian Thomaiyar | f65af9e | 2019-02-13 23:35:05 +0530 | [diff] [blame] | 2689 |                                            item.second.second, item.first); | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 2690 |                 return; | 
 | 2691 |             } | 
| Richard Marian Thomaiyar | f65af9e | 2019-02-13 23:35:05 +0530 | [diff] [blame] | 2692 |         } | 
 | 2693 |         // Get the connection to which the memberId belongs | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2694 |         auto getObjectsWithConnectionCb = | 
| Ed Tanous | d02aad3 | 2024-02-13 14:43:34 -0800 | [diff] [blame] | 2695 |             [sensorAsyncResp, overrideMap, propertyValueNameStr]( | 
 | 2696 |                 const std::set<std::string>& /*connections*/, | 
 | 2697 |                 const std::set<std::pair<std::string, std::string>>& | 
 | 2698 |                     objectsWithConnection) { | 
| Jayaprakash Mutyala | 4f277b5 | 2021-12-08 22:46:49 +0000 | [diff] [blame] | 2699 |             if (objectsWithConnection.size() != overrideMap.size()) | 
 | 2700 |             { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2701 |                 BMCWEB_LOG_INFO( | 
 | 2702 |                     "Unable to find all objects with proper connection {} requested {}", | 
 | 2703 |                     objectsWithConnection.size(), overrideMap.size()); | 
| Jayaprakash Mutyala | 4f277b5 | 2021-12-08 22:46:49 +0000 | [diff] [blame] | 2704 |                 messages::resourceNotFound(sensorAsyncResp->asyncResp->res, | 
 | 2705 |                                            sensorAsyncResp->chassisSubNode == | 
 | 2706 |                                                    sensors::node::thermal | 
 | 2707 |                                                ? "Temperatures" | 
 | 2708 |                                                : "Voltages", | 
 | 2709 |                                            "Count"); | 
 | 2710 |                 return; | 
 | 2711 |             } | 
 | 2712 |             for (const auto& item : objectsWithConnection) | 
 | 2713 |             { | 
 | 2714 |                 sdbusplus::message::object_path path(item.first); | 
 | 2715 |                 std::string sensorName = path.filename(); | 
 | 2716 |                 if (sensorName.empty()) | 
| Richard Marian Thomaiyar | f65af9e | 2019-02-13 23:35:05 +0530 | [diff] [blame] | 2717 |                 { | 
| Jayaprakash Mutyala | 4f277b5 | 2021-12-08 22:46:49 +0000 | [diff] [blame] | 2718 |                     messages::internalError(sensorAsyncResp->asyncResp->res); | 
| Richard Marian Thomaiyar | f65af9e | 2019-02-13 23:35:05 +0530 | [diff] [blame] | 2719 |                     return; | 
 | 2720 |                 } | 
| Ban Feng | 3f5eb75 | 2023-06-29 09:19:20 +0800 | [diff] [blame] | 2721 |                 std::string id = path.parent_path().filename(); | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 2722 |                 auto remove = std::ranges::remove(id, '_'); | 
 | 2723 |                 id.erase(std::ranges::begin(remove), id.end()); | 
| Ban Feng | 3f5eb75 | 2023-06-29 09:19:20 +0800 | [diff] [blame] | 2724 |                 id += "_"; | 
 | 2725 |                 id += sensorName; | 
| Richard Marian Thomaiyar | f65af9e | 2019-02-13 23:35:05 +0530 | [diff] [blame] | 2726 |  | 
| Ban Feng | 3f5eb75 | 2023-06-29 09:19:20 +0800 | [diff] [blame] | 2727 |                 const auto& iterator = overrideMap.find(id); | 
| Jayaprakash Mutyala | 4f277b5 | 2021-12-08 22:46:49 +0000 | [diff] [blame] | 2728 |                 if (iterator == overrideMap.end()) | 
 | 2729 |                 { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2730 |                     BMCWEB_LOG_INFO("Unable to find sensor object{}", | 
 | 2731 |                                     item.first); | 
| Jayaprakash Mutyala | 4f277b5 | 2021-12-08 22:46:49 +0000 | [diff] [blame] | 2732 |                     messages::internalError(sensorAsyncResp->asyncResp->res); | 
 | 2733 |                     return; | 
 | 2734 |                 } | 
| Ed Tanous | d02aad3 | 2024-02-13 14:43:34 -0800 | [diff] [blame] | 2735 |                 setDbusProperty(sensorAsyncResp->asyncResp, item.second, | 
 | 2736 |                                 item.first, "xyz.openbmc_project.Sensor.Value", | 
 | 2737 |                                 "Value", propertyValueNameStr, | 
 | 2738 |                                 iterator->second.first); | 
| Jayaprakash Mutyala | 4f277b5 | 2021-12-08 22:46:49 +0000 | [diff] [blame] | 2739 |             } | 
 | 2740 |         }; | 
| Richard Marian Thomaiyar | f65af9e | 2019-02-13 23:35:05 +0530 | [diff] [blame] | 2741 |         // Get object with connection for the given sensor name | 
 | 2742 |         getObjectsWithConnection(sensorAsyncResp, sensorNames, | 
 | 2743 |                                  std::move(getObjectsWithConnectionCb)); | 
 | 2744 |     }; | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 2745 |     // get full sensor list for the given chassisId and cross verify the sensor. | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 2746 |     getChassis(sensorAsyncResp->asyncResp, sensorAsyncResp->chassisId, | 
 | 2747 |                sensorAsyncResp->chassisSubNode, sensorAsyncResp->types, | 
 | 2748 |                std::move(getChassisSensorListCb)); | 
| Richard Marian Thomaiyar | 413961d | 2019-02-01 00:43:39 +0530 | [diff] [blame] | 2749 | } | 
 | 2750 |  | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 2751 | /** | 
 | 2752 |  * @brief Retrieves mapping of Redfish URIs to sensor value property to D-Bus | 
 | 2753 |  * path of the sensor. | 
 | 2754 |  * | 
 | 2755 |  * Function builds valid Redfish response for sensor query of given chassis and | 
 | 2756 |  * node. It then builds metadata about Redfish<->D-Bus correlations and provides | 
 | 2757 |  * it to caller in a callback. | 
 | 2758 |  * | 
 | 2759 |  * @param chassis   Chassis for which retrieval should be performed | 
 | 2760 |  * @param node  Node (group) of sensors. See sensors::node for supported values | 
 | 2761 |  * @param mapComplete   Callback to be called with retrieval result | 
 | 2762 |  */ | 
| Ed Tanous | 931edc7 | 2023-11-01 12:09:07 -0700 | [diff] [blame] | 2763 | template <typename Callback> | 
| Krzysztof Grobelny | 021d32c | 2021-10-29 16:00:07 +0200 | [diff] [blame] | 2764 | inline void retrieveUriToDbusMap(const std::string& chassis, | 
 | 2765 |                                  const std::string& node, | 
| Ed Tanous | 931edc7 | 2023-11-01 12:09:07 -0700 | [diff] [blame] | 2766 |                                  Callback&& mapComplete) | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 2767 | { | 
| Ed Tanous | 02da7c5 | 2022-02-27 00:09:02 -0800 | [diff] [blame] | 2768 |     decltype(sensors::paths)::const_iterator pathIt = | 
 | 2769 |         std::find_if(sensors::paths.cbegin(), sensors::paths.cend(), | 
 | 2770 |                      [&node](auto&& val) { return val.first == node; }); | 
 | 2771 |     if (pathIt == sensors::paths.cend()) | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 2772 |     { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2773 |         BMCWEB_LOG_ERROR("Wrong node provided : {}", node); | 
| Ed Tanous | 6804b5c | 2023-10-31 14:50:03 -0700 | [diff] [blame] | 2774 |         std::map<std::string, std::string> noop; | 
 | 2775 |         mapComplete(boost::beast::http::status::bad_request, noop); | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 2776 |         return; | 
 | 2777 |     } | 
| Krzysztof Grobelny | d51e072 | 2021-04-16 13:15:21 +0000 | [diff] [blame] | 2778 |  | 
| Nan Zhou | 72374eb | 2022-01-27 17:06:51 -0800 | [diff] [blame] | 2779 |     auto asyncResp = std::make_shared<bmcweb::AsyncResp>(); | 
| Ed Tanous | 931edc7 | 2023-11-01 12:09:07 -0700 | [diff] [blame] | 2780 |     auto callback = [asyncResp, | 
 | 2781 |                      mapCompleteCb{std::forward<Callback>(mapComplete)}]( | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 2782 |                         const boost::beast::http::status status, | 
 | 2783 |                         const std::map<std::string, std::string>& uriToDbus) { | 
 | 2784 |         mapCompleteCb(status, uriToDbus); | 
 | 2785 |     }; | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 2786 |  | 
 | 2787 |     auto resp = std::make_shared<SensorsAsyncResp>( | 
| Krzysztof Grobelny | d51e072 | 2021-04-16 13:15:21 +0000 | [diff] [blame] | 2788 |         asyncResp, chassis, pathIt->second, node, std::move(callback)); | 
| Adrian Ambrożewicz | a0ec28b | 2020-04-10 14:47:28 +0200 | [diff] [blame] | 2789 |     getChassisData(resp); | 
 | 2790 | } | 
 | 2791 |  | 
| Nan Zhou | bacb216 | 2022-04-06 11:28:32 -0700 | [diff] [blame] | 2792 | namespace sensors | 
 | 2793 | { | 
| Nan Zhou | 928fefb | 2022-03-28 08:45:00 -0700 | [diff] [blame] | 2794 |  | 
| Nan Zhou | bacb216 | 2022-04-06 11:28:32 -0700 | [diff] [blame] | 2795 | inline void getChassisCallback( | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2796 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 2797 |     std::string_view chassisId, std::string_view chassisSubNode, | 
| Nan Zhou | fe04d49 | 2022-06-22 17:10:41 +0000 | [diff] [blame] | 2798 |     const std::shared_ptr<std::set<std::string>>& sensorNames) | 
| Nan Zhou | bacb216 | 2022-04-06 11:28:32 -0700 | [diff] [blame] | 2799 | { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2800 |     BMCWEB_LOG_DEBUG("getChassisCallback enter "); | 
| Nan Zhou | bacb216 | 2022-04-06 11:28:32 -0700 | [diff] [blame] | 2801 |  | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2802 |     nlohmann::json& entriesArray = asyncResp->res.jsonValue["Members"]; | 
 | 2803 |     for (const std::string& sensor : *sensorNames) | 
| Nan Zhou | bacb216 | 2022-04-06 11:28:32 -0700 | [diff] [blame] | 2804 |     { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2805 |         BMCWEB_LOG_DEBUG("Adding sensor: {}", sensor); | 
| Nan Zhou | bacb216 | 2022-04-06 11:28:32 -0700 | [diff] [blame] | 2806 |  | 
 | 2807 |         sdbusplus::message::object_path path(sensor); | 
 | 2808 |         std::string sensorName = path.filename(); | 
 | 2809 |         if (sensorName.empty()) | 
 | 2810 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2811 |             BMCWEB_LOG_ERROR("Invalid sensor path: {}", sensor); | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2812 |             messages::internalError(asyncResp->res); | 
| Nan Zhou | bacb216 | 2022-04-06 11:28:32 -0700 | [diff] [blame] | 2813 |             return; | 
 | 2814 |         } | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2815 |         std::string type = path.parent_path().filename(); | 
 | 2816 |         // fan_tach has an underscore in it, so remove it to "normalize" the | 
 | 2817 |         // type in the URI | 
| Ed Tanous | 3544d2a | 2023-08-06 18:12:20 -0700 | [diff] [blame] | 2818 |         auto remove = std::ranges::remove(type, '_'); | 
 | 2819 |         type.erase(std::ranges::begin(remove), type.end()); | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2820 |  | 
| Ed Tanous | 1476687 | 2022-03-15 10:44:42 -0700 | [diff] [blame] | 2821 |         nlohmann::json::object_t member; | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2822 |         std::string id = type; | 
 | 2823 |         id += "_"; | 
 | 2824 |         id += sensorName; | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 2825 |         member["@odata.id"] = boost::urls::format( | 
 | 2826 |             "/redfish/v1/Chassis/{}/{}/{}", chassisId, chassisSubNode, id); | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2827 |  | 
| Patrick Williams | b2ba307 | 2023-05-12 10:27:39 -0500 | [diff] [blame] | 2828 |         entriesArray.emplace_back(std::move(member)); | 
| Nan Zhou | bacb216 | 2022-04-06 11:28:32 -0700 | [diff] [blame] | 2829 |     } | 
 | 2830 |  | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2831 |     asyncResp->res.jsonValue["Members@odata.count"] = entriesArray.size(); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2832 |     BMCWEB_LOG_DEBUG("getChassisCallback exit"); | 
| Nan Zhou | bacb216 | 2022-04-06 11:28:32 -0700 | [diff] [blame] | 2833 | } | 
| Nan Zhou | e6bd846 | 2022-06-01 04:35:35 +0000 | [diff] [blame] | 2834 |  | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 2835 | inline void handleSensorCollectionGet( | 
 | 2836 |     App& app, const crow::Request& req, | 
 | 2837 |     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 2838 |     const std::string& chassisId) | 
| Nan Zhou | de167a6 | 2022-06-01 04:47:45 +0000 | [diff] [blame] | 2839 | { | 
 | 2840 |     query_param::QueryCapabilities capabilities = { | 
 | 2841 |         .canDelegateExpandLevel = 1, | 
 | 2842 |     }; | 
 | 2843 |     query_param::Query delegatedQuery; | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 2844 |     if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp, | 
| Nan Zhou | de167a6 | 2022-06-01 04:47:45 +0000 | [diff] [blame] | 2845 |                                                   delegatedQuery, capabilities)) | 
 | 2846 |     { | 
 | 2847 |         return; | 
 | 2848 |     } | 
 | 2849 |  | 
 | 2850 |     if (delegatedQuery.expandType != query_param::ExpandType::None) | 
 | 2851 |     { | 
 | 2852 |         // we perform efficient expand. | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 2853 |         auto sensorsAsyncResp = std::make_shared<SensorsAsyncResp>( | 
 | 2854 |             asyncResp, chassisId, sensors::dbus::sensorPaths, | 
| Nan Zhou | de167a6 | 2022-06-01 04:47:45 +0000 | [diff] [blame] | 2855 |             sensors::node::sensors, | 
 | 2856 |             /*efficientExpand=*/true); | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 2857 |         getChassisData(sensorsAsyncResp); | 
| Nan Zhou | de167a6 | 2022-06-01 04:47:45 +0000 | [diff] [blame] | 2858 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2859 |         BMCWEB_LOG_DEBUG( | 
 | 2860 |             "SensorCollection doGet exit via efficient expand handler"); | 
| Nan Zhou | de167a6 | 2022-06-01 04:47:45 +0000 | [diff] [blame] | 2861 |         return; | 
| Ed Tanous | 0bad320 | 2022-06-02 13:53:59 -0700 | [diff] [blame] | 2862 |     } | 
| Nan Zhou | de167a6 | 2022-06-01 04:47:45 +0000 | [diff] [blame] | 2863 |  | 
| Nan Zhou | de167a6 | 2022-06-01 04:47:45 +0000 | [diff] [blame] | 2864 |     // We get all sensors as hyperlinkes in the chassis (this | 
 | 2865 |     // implies we reply on the default query parameters handler) | 
| Ed Tanous | ac106bf | 2023-06-07 09:24:59 -0700 | [diff] [blame] | 2866 |     getChassis(asyncResp, chassisId, sensors::node::sensors, dbus::sensorPaths, | 
 | 2867 |                std::bind_front(sensors::getChassisCallback, asyncResp, | 
 | 2868 |                                chassisId, sensors::node::sensors)); | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2869 | } | 
| Ed Tanous | 7f1cc26 | 2022-08-09 13:33:57 -0700 | [diff] [blame] | 2870 |  | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2871 | inline void | 
 | 2872 |     getSensorFromDbus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 2873 |                       const std::string& sensorPath, | 
 | 2874 |                       const ::dbus::utility::MapperGetObject& mapperResponse) | 
 | 2875 | { | 
 | 2876 |     if (mapperResponse.size() != 1) | 
 | 2877 |     { | 
 | 2878 |         messages::internalError(asyncResp->res); | 
 | 2879 |         return; | 
 | 2880 |     } | 
 | 2881 |     const auto& valueIface = *mapperResponse.begin(); | 
 | 2882 |     const std::string& connectionName = valueIface.first; | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2883 |     BMCWEB_LOG_DEBUG("Looking up {}", connectionName); | 
 | 2884 |     BMCWEB_LOG_DEBUG("Path {}", sensorPath); | 
| Krzysztof Grobelny | c1343bf | 2022-08-31 13:15:26 +0200 | [diff] [blame] | 2885 |  | 
 | 2886 |     sdbusplus::asio::getAllProperties( | 
 | 2887 |         *crow::connections::systemBus, connectionName, sensorPath, "", | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2888 |         [asyncResp, | 
| Ed Tanous | 5e7e2dc | 2023-02-16 10:37:01 -0800 | [diff] [blame] | 2889 |          sensorPath](const boost::system::error_code& ec, | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2890 |                      const ::dbus::utility::DBusPropertiesMap& valuesDict) { | 
 | 2891 |         if (ec) | 
 | 2892 |         { | 
 | 2893 |             messages::internalError(asyncResp->res); | 
 | 2894 |             return; | 
 | 2895 |         } | 
 | 2896 |         sdbusplus::message::object_path path(sensorPath); | 
 | 2897 |         std::string name = path.filename(); | 
 | 2898 |         path = path.parent_path(); | 
 | 2899 |         std::string type = path.filename(); | 
 | 2900 |         objectPropertiesToJson(name, type, sensors::node::sensors, valuesDict, | 
 | 2901 |                                asyncResp->res.jsonValue, nullptr); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2902 |     }); | 
| Nan Zhou | de167a6 | 2022-06-01 04:47:45 +0000 | [diff] [blame] | 2903 | } | 
 | 2904 |  | 
| Nan Zhou | e6bd846 | 2022-06-01 04:35:35 +0000 | [diff] [blame] | 2905 | inline void handleSensorGet(App& app, const crow::Request& req, | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2906 |                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
| Ed Tanous | 677bb75 | 2022-09-15 10:52:19 -0700 | [diff] [blame] | 2907 |                             const std::string& chassisId, | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2908 |                             const std::string& sensorId) | 
| Nan Zhou | e6bd846 | 2022-06-01 04:35:35 +0000 | [diff] [blame] | 2909 | { | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2910 |     if (!redfish::setUpRedfishRoute(app, req, asyncResp)) | 
| Nan Zhou | e6bd846 | 2022-06-01 04:35:35 +0000 | [diff] [blame] | 2911 |     { | 
 | 2912 |         return; | 
 | 2913 |     } | 
| Ed Tanous | c71d612 | 2022-11-29 14:10:32 -0800 | [diff] [blame] | 2914 |     std::pair<std::string, std::string> nameType = | 
 | 2915 |         splitSensorNameAndType(sensorId); | 
 | 2916 |     if (nameType.first.empty() || nameType.second.empty()) | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2917 |     { | 
 | 2918 |         messages::resourceNotFound(asyncResp->res, sensorId, "Sensor"); | 
 | 2919 |         return; | 
 | 2920 |     } | 
| Ed Tanous | c71d612 | 2022-11-29 14:10:32 -0800 | [diff] [blame] | 2921 |  | 
| Ed Tanous | ef4c65b | 2023-04-24 15:28:50 -0700 | [diff] [blame] | 2922 |     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( | 
 | 2923 |         "/redfish/v1/Chassis/{}/Sensors/{}", chassisId, sensorId); | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2924 |  | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2925 |     BMCWEB_LOG_DEBUG("Sensor doGet enter"); | 
| Nan Zhou | e6bd846 | 2022-06-01 04:35:35 +0000 | [diff] [blame] | 2926 |  | 
| George Liu | 2b73119 | 2023-01-11 16:27:13 +0800 | [diff] [blame] | 2927 |     constexpr std::array<std::string_view, 1> interfaces = { | 
| Nan Zhou | e6bd846 | 2022-06-01 04:35:35 +0000 | [diff] [blame] | 2928 |         "xyz.openbmc_project.Sensor.Value"}; | 
| Ed Tanous | c71d612 | 2022-11-29 14:10:32 -0800 | [diff] [blame] | 2929 |     std::string sensorPath = "/xyz/openbmc_project/sensors/" + nameType.first + | 
 | 2930 |                              '/' + nameType.second; | 
| Nan Zhou | e6bd846 | 2022-06-01 04:35:35 +0000 | [diff] [blame] | 2931 |     // Get a list of all of the sensors that implement Sensor.Value | 
 | 2932 |     // and get the path and service name associated with the sensor | 
| George Liu | 2b73119 | 2023-01-11 16:27:13 +0800 | [diff] [blame] | 2933 |     ::dbus::utility::getDbusObject( | 
 | 2934 |         sensorPath, interfaces, | 
| Myung Bae | aec0ec3 | 2023-05-31 15:10:01 -0500 | [diff] [blame] | 2935 |         [asyncResp, sensorId, | 
| George Liu | 2b73119 | 2023-01-11 16:27:13 +0800 | [diff] [blame] | 2936 |          sensorPath](const boost::system::error_code& ec, | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2937 |                      const ::dbus::utility::MapperGetObject& subtree) { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2938 |         BMCWEB_LOG_DEBUG("respHandler1 enter"); | 
| Myung Bae | aec0ec3 | 2023-05-31 15:10:01 -0500 | [diff] [blame] | 2939 |         if (ec == boost::system::errc::io_error) | 
 | 2940 |         { | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2941 |             BMCWEB_LOG_WARNING("Sensor not found from getSensorPaths"); | 
| Myung Bae | aec0ec3 | 2023-05-31 15:10:01 -0500 | [diff] [blame] | 2942 |             messages::resourceNotFound(asyncResp->res, sensorId, "Sensor"); | 
 | 2943 |             return; | 
 | 2944 |         } | 
| Nan Zhou | e6bd846 | 2022-06-01 04:35:35 +0000 | [diff] [blame] | 2945 |         if (ec) | 
 | 2946 |         { | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2947 |             messages::internalError(asyncResp->res); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2948 |             BMCWEB_LOG_ERROR( | 
 | 2949 |                 "Sensor getSensorPaths resp_handler: Dbus error {}", ec); | 
| Nan Zhou | e6bd846 | 2022-06-01 04:35:35 +0000 | [diff] [blame] | 2950 |             return; | 
 | 2951 |         } | 
| Ed Tanous | c1d019a | 2022-08-06 09:36:06 -0700 | [diff] [blame] | 2952 |         getSensorFromDbus(asyncResp, sensorPath, subtree); | 
| Ed Tanous | 62598e3 | 2023-07-17 17:06:25 -0700 | [diff] [blame] | 2953 |         BMCWEB_LOG_DEBUG("respHandler1 exit"); | 
| Patrick Williams | 5a39f77 | 2023-10-20 11:20:21 -0500 | [diff] [blame] | 2954 |     }); | 
| Nan Zhou | e6bd846 | 2022-06-01 04:35:35 +0000 | [diff] [blame] | 2955 | } | 
 | 2956 |  | 
| Nan Zhou | bacb216 | 2022-04-06 11:28:32 -0700 | [diff] [blame] | 2957 | } // namespace sensors | 
 | 2958 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2959 | inline void requestRoutesSensorCollection(App& app) | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2960 | { | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2961 |     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Sensors/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 2962 |         .privileges(redfish::privileges::getSensorCollection) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2963 |         .methods(boost::beast::http::verb::get)( | 
| Nan Zhou | de167a6 | 2022-06-01 04:47:45 +0000 | [diff] [blame] | 2964 |             std::bind_front(sensors::handleSensorCollectionGet, std::ref(app))); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2965 | } | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2966 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2967 | inline void requestRoutesSensor(App& app) | 
 | 2968 | { | 
 | 2969 |     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Sensors/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 2970 |         .privileges(redfish::privileges::getSensor) | 
| Ed Tanous | 002d39b | 2022-05-31 08:59:27 -0700 | [diff] [blame] | 2971 |         .methods(boost::beast::http::verb::get)( | 
| Nan Zhou | e6bd846 | 2022-06-01 04:35:35 +0000 | [diff] [blame] | 2972 |             std::bind_front(sensors::handleSensorGet, std::ref(app))); | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 2973 | } | 
| Anthony Wilson | 95a3eca | 2019-06-11 10:44:47 -0500 | [diff] [blame] | 2974 |  | 
| Ed Tanous | 1abe55e | 2018-09-05 08:30:59 -0700 | [diff] [blame] | 2975 | } // namespace redfish |