blob: 1f554ccfb6af86fd9e766c2a3bd65960efa04f74 [file] [log] [blame]
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001/*
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
Willy Tu13451e32023-05-24 16:08:18 -070018#include "bmcweb_config.h"
19
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080020#include "app.hpp"
21#include "dbus_utility.hpp"
James Feist35e257a2020-06-05 13:30:51 -070022#include "health.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080023#include "query.hpp"
24#include "registries/privilege_registry.hpp"
25#include "utils/collection.hpp"
26#include "utils/dbus_utils.hpp"
27#include "utils/hex_utils.hpp"
28#include "utils/json_utils.hpp"
James Feist35e257a2020-06-05 13:30:51 -070029
George Liue99073f2022-12-09 11:06:16 +080030#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070031#include <boost/url/format.hpp>
Nan Zhoud7f04fd2022-05-01 01:11:07 +000032#include <nlohmann/json.hpp>
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +020033#include <sdbusplus/asio/property.hpp>
34#include <sdbusplus/unpack_properties.hpp>
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020035
George Liu7a1dbc42022-12-07 16:03:22 +080036#include <array>
37#include <string_view>
38
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020039namespace redfish
40{
41
Gunnar Mills313efb12020-10-26 16:05:08 -050042inline std::string translateMemoryTypeToRedfish(const std::string& memoryType)
43{
44 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR")
45 {
46 return "DDR";
47 }
48 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2")
49 {
50 return "DDR2";
51 }
52 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3")
53 {
54 return "DDR3";
55 }
56 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4")
57 {
58 return "DDR4";
59 }
60 if (memoryType ==
61 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM")
62 {
63 return "DDR4E_SDRAM";
64 }
Mansi Joshi11a2f0f2021-07-19 14:33:27 +053065 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5")
66 {
67 return "DDR5";
68 }
Gunnar Mills313efb12020-10-26 16:05:08 -050069 if (memoryType ==
70 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM")
71 {
72 return "LPDDR4_SDRAM";
73 }
74 if (memoryType ==
75 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM")
76 {
77 return "LPDDR3_SDRAM";
78 }
79 if (memoryType ==
80 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM")
81 {
82 return "DDR2_SDRAM_FB_DIMM";
83 }
George Liu0fda0f12021-11-16 10:06:17 +080084 if (memoryType ==
85 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB")
Gunnar Mills313efb12020-10-26 16:05:08 -050086 {
87 return "DDR2_SDRAM_FB_DIMM_PROBE";
88 }
89 if (memoryType ==
90 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM")
91 {
92 return "DDR_SGRAM";
93 }
94 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM")
95 {
96 return "ROM";
97 }
98 if (memoryType ==
99 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM")
100 {
101 return "SDRAM";
102 }
103 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO")
104 {
105 return "EDO";
106 }
107 if (memoryType ==
108 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode")
109 {
110 return "FastPageMode";
111 }
112 if (memoryType ==
113 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble")
114 {
115 return "PipelinedNibble";
116 }
117 if (memoryType ==
118 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical")
119 {
120 return "Logical";
121 }
122 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM")
123 {
124 return "HBM";
125 }
126 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2")
127 {
128 return "HBM2";
129 }
Tyson Tuckerbearce34d512022-09-13 16:26:15 -0700130 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM3")
131 {
132 return "HBM3";
133 }
Gunnar Mills313efb12020-10-26 16:05:08 -0500134 // This is values like Other or Unknown
135 // Also D-Bus values:
136 // DRAM
137 // EDRAM
138 // VRAM
139 // SRAM
140 // RAM
141 // FLASH
142 // EEPROM
143 // FEPROM
144 // EPROM
145 // CDRAM
146 // ThreeDRAM
147 // RDRAM
148 // FBD2
149 // LPDDR_SDRAM
150 // LPDDR2_SDRAM
Mansi Joshi11a2f0f2021-07-19 14:33:27 +0530151 // LPDDR5_SDRAM
Gunnar Mills313efb12020-10-26 16:05:08 -0500152 return "";
153}
154
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200155inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
156 const char* key, const uint16_t* value,
157 const nlohmann::json::json_pointer& jsonPtr)
James Feistc50e7c62020-07-27 15:39:36 -0700158{
James Feistc50e7c62020-07-27 15:39:36 -0700159 if (value == nullptr)
160 {
James Feistc50e7c62020-07-27 15:39:36 -0700161 return;
162 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000163 aResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4);
James Feistc50e7c62020-07-27 15:39:36 -0700164}
165
zhanghch058d1b46d2021-04-01 11:18:24 +0800166inline void getPersistentMemoryProperties(
167 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200168 const dbus::utility::DBusPropertiesMap& properties,
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000169 const nlohmann::json::json_pointer& jsonPtr)
James Feistc50e7c62020-07-27 15:39:36 -0700170{
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200171 const uint16_t* moduleManufacturerID = nullptr;
172 const uint16_t* moduleProductID = nullptr;
173 const uint16_t* subsystemVendorID = nullptr;
174 const uint16_t* subsystemDeviceID = nullptr;
175 const uint64_t* volatileRegionSizeLimitInKiB = nullptr;
176 const uint64_t* pmRegionSizeLimitInKiB = nullptr;
177 const uint64_t* volatileSizeInKiB = nullptr;
178 const uint64_t* pmSizeInKiB = nullptr;
179 const uint64_t* cacheSizeInKB = nullptr;
180 const uint64_t* voltaileRegionMaxSizeInKib = nullptr;
181 const uint64_t* pmRegionMaxSizeInKiB = nullptr;
182 const uint64_t* allocationIncrementInKiB = nullptr;
183 const uint64_t* allocationAlignmentInKiB = nullptr;
184 const uint64_t* volatileRegionNumberLimit = nullptr;
185 const uint64_t* pmRegionNumberLimit = nullptr;
186 const uint64_t* spareDeviceCount = nullptr;
187 const bool* isSpareDeviceInUse = nullptr;
188 const bool* isRankSpareEnabled = nullptr;
189 const std::vector<uint32_t>* maxAveragePowerLimitmW = nullptr;
190 const bool* configurationLocked = nullptr;
191 const std::string* allowedMemoryModes = nullptr;
192 const std::string* memoryMedia = nullptr;
193 const bool* configurationLockCapable = nullptr;
194 const bool* dataLockCapable = nullptr;
195 const bool* passphraseCapable = nullptr;
196 const uint64_t* maxPassphraseCount = nullptr;
197 const uint64_t* passphraseLockLimit = nullptr;
James Feistc50e7c62020-07-27 15:39:36 -0700198
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200199 const bool success = sdbusplus::unpackPropertiesNoThrow(
200 dbus_utils::UnpackErrorPrinter(), properties, "ModuleManufacturerID",
201 moduleManufacturerID, "ModuleProductID", moduleProductID,
202 "SubsystemVendorID", subsystemVendorID, "SubsystemDeviceID",
203 subsystemDeviceID, "VolatileRegionSizeLimitInKiB",
204 volatileRegionSizeLimitInKiB, "PmRegionSizeLimitInKiB",
205 pmRegionSizeLimitInKiB, "VolatileSizeInKiB", volatileSizeInKiB,
206 "PmSizeInKiB", pmSizeInKiB, "CacheSizeInKB", cacheSizeInKB,
207 "VoltaileRegionMaxSizeInKib", voltaileRegionMaxSizeInKib,
208 "PmRegionMaxSizeInKiB", pmRegionMaxSizeInKiB,
209 "AllocationIncrementInKiB", allocationIncrementInKiB,
210 "AllocationAlignmentInKiB", allocationAlignmentInKiB,
211 "VolatileRegionNumberLimit", volatileRegionNumberLimit,
212 "PmRegionNumberLimit", pmRegionNumberLimit, "SpareDeviceCount",
213 spareDeviceCount, "IsSpareDeviceInUse", isSpareDeviceInUse,
214 "IsRankSpareEnabled", isRankSpareEnabled, "MaxAveragePowerLimitmW",
215 maxAveragePowerLimitmW, "ConfigurationLocked", configurationLocked,
216 "AllowedMemoryModes", allowedMemoryModes, "MemoryMedia", memoryMedia,
217 "ConfigurationLockCapable", configurationLockCapable, "DataLockCapable",
218 dataLockCapable, "PassphraseCapable", passphraseCapable,
219 "MaxPassphraseCount", maxPassphraseCount, "PassphraseLockLimit",
220 passphraseLockLimit);
221
222 if (!success)
223 {
224 messages::internalError(aResp->res);
225 return;
226 }
227
228 dimmPropToHex(aResp, "ModuleManufacturerID", moduleManufacturerID, jsonPtr);
229 dimmPropToHex(aResp, "ModuleProductID", moduleProductID, jsonPtr);
230 dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID",
231 subsystemVendorID, jsonPtr);
232 dimmPropToHex(aResp, "MemorySubsystemControllerProductID",
233 subsystemDeviceID, jsonPtr);
234
235 if (volatileRegionSizeLimitInKiB != nullptr)
236 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000237 aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] =
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200238 (*volatileRegionSizeLimitInKiB) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800239 }
James Feistc50e7c62020-07-27 15:39:36 -0700240
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200241 if (pmRegionSizeLimitInKiB != nullptr)
242 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000243 aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] =
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200244 (*pmRegionSizeLimitInKiB) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800245 }
James Feistc50e7c62020-07-27 15:39:36 -0700246
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200247 if (volatileSizeInKiB != nullptr)
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800248 {
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200249 aResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] =
250 (*volatileSizeInKiB) >> 10;
251 }
252
253 if (pmSizeInKiB != nullptr)
254 {
Patrick Williams89492a12023-05-10 07:51:34 -0500255 aResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] = (*pmSizeInKiB) >>
256 10;
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200257 }
258
259 if (cacheSizeInKB != nullptr)
260 {
261 aResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] = (*cacheSizeInKB >> 10);
262 }
263
264 if (voltaileRegionMaxSizeInKib != nullptr)
265 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000266 aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] =
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200267 (*voltaileRegionMaxSizeInKib) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800268 }
James Feistc50e7c62020-07-27 15:39:36 -0700269
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200270 if (pmRegionMaxSizeInKiB != nullptr)
271 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000272 aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] =
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200273 (*pmRegionMaxSizeInKiB) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800274 }
James Feistc50e7c62020-07-27 15:39:36 -0700275
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200276 if (allocationIncrementInKiB != nullptr)
277 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000278 aResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] =
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200279 (*allocationIncrementInKiB) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800280 }
James Feistc50e7c62020-07-27 15:39:36 -0700281
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200282 if (allocationAlignmentInKiB != nullptr)
283 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000284 aResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] =
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200285 (*allocationAlignmentInKiB) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800286 }
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200287
288 if (volatileRegionNumberLimit != nullptr)
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800289 {
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200290 aResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] =
291 *volatileRegionNumberLimit;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800292 }
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200293
294 if (pmRegionNumberLimit != nullptr)
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800295 {
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200296 aResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] =
297 *pmRegionNumberLimit;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800298 }
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200299
300 if (spareDeviceCount != nullptr)
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800301 {
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200302 aResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] = *spareDeviceCount;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800303 }
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200304
305 if (isSpareDeviceInUse != nullptr)
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800306 {
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200307 aResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] =
308 *isSpareDeviceInUse;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800309 }
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200310
311 if (isRankSpareEnabled != nullptr)
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800312 {
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200313 aResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] =
314 *isRankSpareEnabled;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800315 }
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200316
317 if (maxAveragePowerLimitmW != nullptr)
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800318 {
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200319 aResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] =
320 *maxAveragePowerLimitmW;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800321 }
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200322
323 if (configurationLocked != nullptr)
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800324 {
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200325 aResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] =
326 *configurationLocked;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800327 }
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200328
329 if (allowedMemoryModes != nullptr)
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800330 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800331 constexpr const std::array<const char*, 3> values{"Volatile", "PMEM",
332 "Block"};
James Feistc50e7c62020-07-27 15:39:36 -0700333
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800334 for (const char* v : values)
335 {
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200336 if (allowedMemoryModes->ends_with(v))
James Feistc50e7c62020-07-27 15:39:36 -0700337 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000338 aResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"].push_back(
339 v);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800340 break;
James Feistc50e7c62020-07-27 15:39:36 -0700341 }
342 }
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800343 }
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200344
345 if (memoryMedia != nullptr)
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800346 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800347 constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
348 "Intel3DXPoint"};
James Feistc50e7c62020-07-27 15:39:36 -0700349
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800350 for (const char* v : values)
Ed Tanous5fb91ba2020-09-28 15:41:28 -0700351 {
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200352 if (memoryMedia->ends_with(v))
Ed Tanous5fb91ba2020-09-28 15:41:28 -0700353 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000354 aResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800355 break;
Ed Tanous5fb91ba2020-09-28 15:41:28 -0700356 }
Ed Tanous5fb91ba2020-09-28 15:41:28 -0700357 }
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800358 }
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200359
360 if (configurationLockCapable != nullptr)
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800361 {
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200362 aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
363 ["ConfigurationLockCapable"] =
364 *configurationLockCapable;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800365 }
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200366
367 if (dataLockCapable != nullptr)
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800368 {
Patrick Williams89492a12023-05-10 07:51:34 -0500369 aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
370 ["DataLockCapable"] = *dataLockCapable;
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200371 }
372
373 if (passphraseCapable != nullptr)
374 {
Patrick Williams89492a12023-05-10 07:51:34 -0500375 aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
376 ["PassphraseCapable"] = *passphraseCapable;
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200377 }
378
379 if (maxPassphraseCount != nullptr)
380 {
Patrick Williams89492a12023-05-10 07:51:34 -0500381 aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
382 ["MaxPassphraseCount"] = *maxPassphraseCount;
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200383 }
384
385 if (passphraseLockLimit != nullptr)
386 {
Patrick Williams89492a12023-05-10 07:51:34 -0500387 aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
388 ["PassphraseLockLimit"] = *passphraseLockLimit;
James Feistc50e7c62020-07-27 15:39:36 -0700389 }
390}
391
Nan Zhou9a5acea2022-05-17 21:12:43 +0000392inline void
393 assembleDimmProperties(std::string_view dimmId,
394 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000395 const dbus::utility::DBusPropertiesMap& properties,
396 const nlohmann::json::json_pointer& jsonPtr)
Nan Zhou9a5acea2022-05-17 21:12:43 +0000397{
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000398 aResp->res.jsonValue[jsonPtr]["Id"] = dimmId;
399 aResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot";
400 aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled";
401 aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK";
Nan Zhou9a5acea2022-05-17 21:12:43 +0000402
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200403 const uint16_t* memoryDataWidth = nullptr;
404 const size_t* memorySizeInKB = nullptr;
405 const std::string* partNumber = nullptr;
406 const std::string* serialNumber = nullptr;
407 const std::string* manufacturer = nullptr;
408 const uint16_t* revisionCode = nullptr;
409 const bool* present = nullptr;
410 const uint16_t* memoryTotalWidth = nullptr;
411 const std::string* ecc = nullptr;
412 const std::string* formFactor = nullptr;
413 const std::vector<uint16_t>* allowedSpeedsMT = nullptr;
414 const uint8_t* memoryAttributes = nullptr;
415 const uint16_t* memoryConfiguredSpeedInMhz = nullptr;
416 const std::string* memoryType = nullptr;
417 const std::string* channel = nullptr;
418 const std::string* memoryController = nullptr;
419 const std::string* slot = nullptr;
420 const std::string* socket = nullptr;
421 const std::string* sparePartNumber = nullptr;
422 const std::string* model = nullptr;
423 const std::string* locationCode = nullptr;
424
425 const bool success = sdbusplus::unpackPropertiesNoThrow(
426 dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth",
427 memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber",
Nikhil Namjoshi656472d2022-09-13 20:54:44 +0000428 partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
429 "RevisionCode", revisionCode, "Present", present, "MemoryTotalWidth",
430 memoryTotalWidth, "ECC", ecc, "FormFactor", formFactor,
431 "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes",
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200432 memoryAttributes, "MemoryConfiguredSpeedInMhz",
433 memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel",
434 channel, "MemoryController", memoryController, "Slot", slot, "Socket",
435 socket, "SparePartNumber", sparePartNumber, "Model", model,
436 "LocationCode", locationCode);
437
438 if (!success)
Nan Zhou9a5acea2022-05-17 21:12:43 +0000439 {
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200440 messages::internalError(aResp->res);
441 return;
442 }
Nan Zhou9a5acea2022-05-17 21:12:43 +0000443
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200444 if (memoryDataWidth != nullptr)
445 {
446 aResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth;
447 }
Nan Zhou9a5acea2022-05-17 21:12:43 +0000448
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200449 if (memorySizeInKB != nullptr)
450 {
451 aResp->res.jsonValue[jsonPtr]["CapacityMiB"] = (*memorySizeInKB >> 10);
452 }
Nan Zhou9a5acea2022-05-17 21:12:43 +0000453
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200454 if (partNumber != nullptr)
455 {
456 aResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber;
457 }
Nan Zhou9a5acea2022-05-17 21:12:43 +0000458
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200459 if (serialNumber != nullptr)
460 {
461 aResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber;
462 }
463
464 if (manufacturer != nullptr)
465 {
466 aResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer;
467 }
468
469 if (revisionCode != nullptr)
470 {
471 aResp->res.jsonValue[jsonPtr]["FirmwareRevision"] =
472 std::to_string(*revisionCode);
473 }
474
475 if (present != nullptr && !*present)
476 {
477 aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent";
478 }
479
480 if (memoryTotalWidth != nullptr)
481 {
482 aResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth;
483 }
484
485 if (ecc != nullptr)
486 {
487 constexpr const std::array<const char*, 4> values{
488 "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};
489
490 for (const char* v : values)
Nan Zhou9a5acea2022-05-17 21:12:43 +0000491 {
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200492 if (ecc->ends_with(v))
Nan Zhou9a5acea2022-05-17 21:12:43 +0000493 {
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200494 aResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v;
495 break;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000496 }
Nan Zhou9a5acea2022-05-17 21:12:43 +0000497 }
498 }
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200499
500 if (formFactor != nullptr)
501 {
502 constexpr const std::array<const char*, 11> values{
503 "RDIMM", "UDIMM", "SO_DIMM", "LRDIMM",
504 "Mini_RDIMM", "Mini_UDIMM", "SO_RDIMM_72b", "SO_UDIMM_72b",
505 "SO_DIMM_16b", "SO_DIMM_32b", "Die"};
506
507 for (const char* v : values)
508 {
509 if (formFactor->ends_with(v))
510 {
511 aResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v;
512 break;
513 }
514 }
515 }
516
517 if (allowedSpeedsMT != nullptr)
518 {
519 nlohmann::json& jValue =
520 aResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"];
521 jValue = nlohmann::json::array();
522 for (uint16_t subVal : *allowedSpeedsMT)
523 {
524 jValue.push_back(subVal);
525 }
526 }
527
528 if (memoryAttributes != nullptr)
529 {
530 aResp->res.jsonValue[jsonPtr]["RankCount"] =
531 static_cast<uint64_t>(*memoryAttributes);
532 }
533
534 if (memoryConfiguredSpeedInMhz != nullptr)
535 {
536 aResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] =
537 *memoryConfiguredSpeedInMhz;
538 }
539
540 if (memoryType != nullptr)
541 {
542 std::string memoryDeviceType =
543 translateMemoryTypeToRedfish(*memoryType);
544 // Values like "Unknown" or "Other" will return empty
545 // so just leave off
546 if (!memoryDeviceType.empty())
547 {
548 aResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] =
549 memoryDeviceType;
550 }
551 if (memoryType->find("DDR") != std::string::npos)
552 {
553 aResp->res.jsonValue[jsonPtr]["MemoryType"] = "DRAM";
554 }
555 else if (memoryType->ends_with("Logical"))
556 {
557 aResp->res.jsonValue[jsonPtr]["MemoryType"] = "IntelOptane";
558 }
559 }
560
561 if (channel != nullptr)
562 {
563 aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] = *channel;
564 }
565
566 if (memoryController != nullptr)
567 {
568 aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["MemoryController"] =
569 *memoryController;
570 }
571
572 if (slot != nullptr)
573 {
574 aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot;
575 }
576
577 if (socket != nullptr)
578 {
579 aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket;
580 }
581
582 if (sparePartNumber != nullptr)
583 {
584 aResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber;
585 }
586
587 if (model != nullptr)
588 {
589 aResp->res.jsonValue[jsonPtr]["Model"] = *model;
590 }
591
592 if (locationCode != nullptr)
593 {
Patrick Williams89492a12023-05-10 07:51:34 -0500594 aResp->res.jsonValue[jsonPtr]["Location"]["PartLocation"]
595 ["ServiceLabel"] = *locationCode;
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200596 }
597
598 getPersistentMemoryProperties(aResp, properties, jsonPtr);
Nan Zhou9a5acea2022-05-17 21:12:43 +0000599}
600
zhanghch058d1b46d2021-04-01 11:18:24 +0800601inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp,
Ed Tanous80789c82020-08-19 09:19:09 -0700602 const std::string& dimmId,
603 const std::string& service,
604 const std::string& objPath)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200605{
Willy Tu13451e32023-05-24 16:08:18 -0700606 if constexpr (bmcwebEnableHealthPopulate)
607 {
608 auto health = std::make_shared<HealthPopulate>(aResp);
609 health->selfPath = objPath;
610 health->populate();
611 }
James Feist35e257a2020-06-05 13:30:51 -0700612
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200613 BMCWEB_LOG_DEBUG << "Get available system components.";
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200614 sdbusplus::asio::getAllProperties(
615 *crow::connections::systemBus, service, objPath, "",
Ed Tanousb9d36b42022-02-26 21:42:46 -0800616 [dimmId, aResp{std::move(aResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800617 const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800618 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700619 if (ec)
620 {
621 BMCWEB_LOG_DEBUG << "DBUS response error";
622 messages::internalError(aResp->res);
623 return;
624 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000625 assembleDimmProperties(dimmId, aResp, properties, ""_json_pointer);
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200626 });
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200627}
628
Nan Zhouef00d7d2022-05-20 21:22:32 +0000629inline void assembleDimmPartitionData(
630 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000631 const dbus::utility::DBusPropertiesMap& properties,
632 const nlohmann::json::json_pointer& regionPtr)
Nan Zhouef00d7d2022-05-20 21:22:32 +0000633{
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200634 const std::string* memoryClassification = nullptr;
635 const uint64_t* offsetInKiB = nullptr;
636 const std::string* partitionId = nullptr;
637 const bool* passphraseState = nullptr;
638 const uint64_t* sizeInKiB = nullptr;
639
640 const bool success = sdbusplus::unpackPropertiesNoThrow(
641 dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification",
642 memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId",
643 partitionId, "PassphraseState", passphraseState, "SizeInKiB",
644 sizeInKiB);
645
646 if (!success)
Nan Zhouef00d7d2022-05-20 21:22:32 +0000647 {
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200648 messages::internalError(aResp->res);
649 return;
Nan Zhouef00d7d2022-05-20 21:22:32 +0000650 }
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200651
652 nlohmann::json::object_t partition;
653
654 if (memoryClassification != nullptr)
655 {
656 partition["MemoryClassification"] = *memoryClassification;
657 }
658
659 if (offsetInKiB != nullptr)
660 {
661 partition["OffsetMiB"] = (*offsetInKiB >> 10);
662 }
663
664 if (partitionId != nullptr)
665 {
666 partition["RegionId"] = *partitionId;
667 }
668
669 if (passphraseState != nullptr)
670 {
671 partition["PassphraseEnabled"] = *passphraseState;
672 }
673
674 if (sizeInKiB != nullptr)
675 {
676 partition["SizeMiB"] = (*sizeInKiB >> 10);
677 }
678
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000679 aResp->res.jsonValue[regionPtr].emplace_back(std::move(partition));
Nan Zhouef00d7d2022-05-20 21:22:32 +0000680}
681
zhanghch058d1b46d2021-04-01 11:18:24 +0800682inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp,
Ed Tanous23a21a12020-07-25 04:45:05 +0000683 const std::string& service,
684 const std::string& path)
James Feist45094ad2020-04-29 14:02:30 -0700685{
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200686 sdbusplus::asio::getAllProperties(
687 *crow::connections::systemBus, service, path,
688 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition",
James Feist45094ad2020-04-29 14:02:30 -0700689 [aResp{std::move(aResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800690 const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800691 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700692 if (ec)
693 {
694 BMCWEB_LOG_DEBUG << "DBUS response error";
695 messages::internalError(aResp->res);
James Feist45094ad2020-04-29 14:02:30 -0700696
Ed Tanous002d39b2022-05-31 08:59:27 -0700697 return;
698 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000699 nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
700 assembleDimmPartitionData(aResp, properties, regionPtr);
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200701 }
James Feist45094ad2020-04-29 14:02:30 -0700702
Krzysztof Grobelnyc1343bf2022-08-31 13:15:26 +0200703 );
James Feist45094ad2020-04-29 14:02:30 -0700704}
705
zhanghch058d1b46d2021-04-01 11:18:24 +0800706inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp,
Ed Tanous23a21a12020-07-25 04:45:05 +0000707 const std::string& dimmId)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200708{
709 BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
George Liue99073f2022-12-09 11:06:16 +0800710 constexpr std::array<std::string_view, 2> dimmInterfaces = {
711 "xyz.openbmc_project.Inventory.Item.Dimm",
712 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"};
713 dbus::utility::getSubTree(
714 "/xyz/openbmc_project/inventory", 0, dimmInterfaces,
Ed Tanous029573d2019-02-01 10:57:49 -0800715 [dimmId, aResp{std::move(aResp)}](
George Liue99073f2022-12-09 11:06:16 +0800716 const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800717 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700718 if (ec)
719 {
720 BMCWEB_LOG_DEBUG << "DBUS response error";
721 messages::internalError(aResp->res);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200722
Ed Tanous002d39b2022-05-31 08:59:27 -0700723 return;
724 }
725 bool found = false;
Nan Zhou76686dc2022-06-17 23:01:51 +0000726 for (const auto& [rawPath, object] : subtree)
Ed Tanous002d39b2022-05-31 08:59:27 -0700727 {
Nan Zhou76686dc2022-06-17 23:01:51 +0000728 sdbusplus::message::object_path path(rawPath);
729 for (const auto& [service, interfaces] : object)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200730 {
Nan Zhou76686dc2022-06-17 23:01:51 +0000731 for (const auto& interface : interfaces)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200732 {
Nan Zhou76686dc2022-06-17 23:01:51 +0000733 if (interface ==
734 "xyz.openbmc_project.Inventory.Item.Dimm" &&
735 path.filename() == dimmId)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200736 {
Nan Zhou76686dc2022-06-17 23:01:51 +0000737 getDimmDataByService(aResp, dimmId, service, rawPath);
738 found = true;
739 }
James Feist45094ad2020-04-29 14:02:30 -0700740
Nan Zhou76686dc2022-06-17 23:01:51 +0000741 // partitions are separate as there can be multiple
742 // per
743 // device, i.e.
744 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
745 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
746 if (interface ==
747 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
748 path.parent_path().filename() == dimmId)
749 {
750 getDimmPartitionData(aResp, service, rawPath);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200751 }
752 }
753 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700754 }
755 // Object not found
756 if (!found)
757 {
758 messages::resourceNotFound(aResp->res, "Memory", dimmId);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200759 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700760 }
761 // Set @odata only if object is found
762 aResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700763 aResp->res.jsonValue["@odata.id"] =
764 boost::urls::format("/redfish/v1/Systems/system/Memory/{}", dimmId);
Ed Tanous002d39b2022-05-31 08:59:27 -0700765 return;
George Liue99073f2022-12-09 11:06:16 +0800766 });
Ed Tanous271584a2019-07-09 16:24:22 -0700767}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200768
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700769inline void requestRoutesMemoryCollection(App& app)
Ed Tanous029573d2019-02-01 10:57:49 -0800770{
Ed Tanous029573d2019-02-01 10:57:49 -0800771 /**
772 * Functions triggers appropriate requests on DBus
773 */
Ed Tanous22d268c2022-05-19 09:39:07 -0700774 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/")
Ed Tanoused398212021-06-09 17:05:54 -0700775 .privileges(redfish::privileges::getMemoryCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700776 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700777 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -0700778 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
779 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000780 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700781 {
782 return;
783 }
Ed Tanous22d268c2022-05-19 09:39:07 -0700784 if (systemName != "system")
785 {
786 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
787 systemName);
788 return;
789 }
790
Ed Tanous002d39b2022-05-31 08:59:27 -0700791 asyncResp->res.jsonValue["@odata.type"] =
792 "#MemoryCollection.MemoryCollection";
793 asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
794 asyncResp->res.jsonValue["@odata.id"] =
795 "/redfish/v1/Systems/system/Memory";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200796
George Liu7a1dbc42022-12-07 16:03:22 +0800797 constexpr std::array<std::string_view, 1> interfaces{
798 "xyz.openbmc_project.Inventory.Item.Dimm"};
Ed Tanous002d39b2022-05-31 08:59:27 -0700799 collection_util::getCollectionMembers(
Willy Tuae9031f2022-09-27 05:48:07 +0000800 asyncResp, boost::urls::url("/redfish/v1/Systems/system/Memory"),
George Liu7a1dbc42022-12-07 16:03:22 +0800801 interfaces);
Ed Tanous002d39b2022-05-31 08:59:27 -0700802 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700803}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200804
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700805inline void requestRoutesMemory(App& app)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200806{
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200807 /**
808 * Functions triggers appropriate requests on DBus
809 */
Ed Tanous22d268c2022-05-19 09:39:07 -0700810 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700811 .privileges(redfish::privileges::getMemory)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700812 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700813 [&app](const crow::Request& req,
814 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -0700815 const std::string& systemName, const std::string& dimmId) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000816 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700817 {
818 return;
819 }
Ed Tanous22d268c2022-05-19 09:39:07 -0700820 if (systemName != "system")
821 {
822 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
823 systemName);
824 return;
825 }
826
Ed Tanous002d39b2022-05-31 08:59:27 -0700827 getDimmData(asyncResp, dimmId);
828 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700829}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200830
831} // namespace redfish