blob: 89960824561f13a4074fbb95021dab800c53749f [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
James Feist35e257a2020-06-05 13:30:51 -070018#include "health.hpp"
19
John Edward Broadbent7e860f12021-04-08 15:57:16 -070020#include <app.hpp>
Sui Chen7267c212022-05-17 14:49:28 -070021#include <boost/algorithm/string.hpp>
Ed Tanous168e20c2021-12-13 14:39:53 -080022#include <dbus_utility.hpp>
Nan Zhoud7f04fd2022-05-01 01:11:07 +000023#include <nlohmann/json.hpp>
Ed Tanous45ca1b82022-03-25 13:07:27 -070024#include <query.hpp>
Ed Tanoused398212021-06-09 17:05:54 -070025#include <registries/privilege_registry.hpp>
Gunnar Mills116bcc52020-10-14 15:23:42 -050026#include <utils/collection.hpp>
Ed Tanousf201ffb2021-10-09 14:49:28 -070027#include <utils/hex_utils.hpp>
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020028#include <utils/json_utils.hpp>
29
30namespace redfish
31{
32
Gunnar Mills313efb12020-10-26 16:05:08 -050033inline std::string translateMemoryTypeToRedfish(const std::string& memoryType)
34{
35 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR")
36 {
37 return "DDR";
38 }
39 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2")
40 {
41 return "DDR2";
42 }
43 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3")
44 {
45 return "DDR3";
46 }
47 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4")
48 {
49 return "DDR4";
50 }
51 if (memoryType ==
52 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM")
53 {
54 return "DDR4E_SDRAM";
55 }
Mansi Joshi11a2f0f2021-07-19 14:33:27 +053056 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5")
57 {
58 return "DDR5";
59 }
Gunnar Mills313efb12020-10-26 16:05:08 -050060 if (memoryType ==
61 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM")
62 {
63 return "LPDDR4_SDRAM";
64 }
65 if (memoryType ==
66 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM")
67 {
68 return "LPDDR3_SDRAM";
69 }
70 if (memoryType ==
71 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM")
72 {
73 return "DDR2_SDRAM_FB_DIMM";
74 }
George Liu0fda0f12021-11-16 10:06:17 +080075 if (memoryType ==
76 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB")
Gunnar Mills313efb12020-10-26 16:05:08 -050077 {
78 return "DDR2_SDRAM_FB_DIMM_PROBE";
79 }
80 if (memoryType ==
81 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM")
82 {
83 return "DDR_SGRAM";
84 }
85 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM")
86 {
87 return "ROM";
88 }
89 if (memoryType ==
90 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM")
91 {
92 return "SDRAM";
93 }
94 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO")
95 {
96 return "EDO";
97 }
98 if (memoryType ==
99 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode")
100 {
101 return "FastPageMode";
102 }
103 if (memoryType ==
104 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble")
105 {
106 return "PipelinedNibble";
107 }
108 if (memoryType ==
109 "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical")
110 {
111 return "Logical";
112 }
113 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM")
114 {
115 return "HBM";
116 }
117 if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2")
118 {
119 return "HBM2";
120 }
121 // This is values like Other or Unknown
122 // Also D-Bus values:
123 // DRAM
124 // EDRAM
125 // VRAM
126 // SRAM
127 // RAM
128 // FLASH
129 // EEPROM
130 // FEPROM
131 // EPROM
132 // CDRAM
133 // ThreeDRAM
134 // RDRAM
135 // FBD2
136 // LPDDR_SDRAM
137 // LPDDR2_SDRAM
Mansi Joshi11a2f0f2021-07-19 14:33:27 +0530138 // LPDDR5_SDRAM
Gunnar Mills313efb12020-10-26 16:05:08 -0500139 return "";
140}
141
Ed Tanous168e20c2021-12-13 14:39:53 -0800142inline void dimmPropToHex(
143 const std::shared_ptr<bmcweb::AsyncResp>& aResp, const char* key,
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000144 const std::pair<std::string, dbus::utility::DbusVariantType>& property,
145 const nlohmann::json::json_pointer& jsonPtr)
James Feistc50e7c62020-07-27 15:39:36 -0700146{
147 const uint16_t* value = std::get_if<uint16_t>(&property.second);
148 if (value == nullptr)
149 {
150 messages::internalError(aResp->res);
151 BMCWEB_LOG_DEBUG << "Invalid property type for " << property.first;
152 return;
153 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000154 aResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4);
James Feistc50e7c62020-07-27 15:39:36 -0700155}
156
zhanghch058d1b46d2021-04-01 11:18:24 +0800157inline void getPersistentMemoryProperties(
158 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000159 const std::pair<std::string, dbus::utility::DbusVariantType>& property,
160 const nlohmann::json::json_pointer& jsonPtr)
James Feistc50e7c62020-07-27 15:39:36 -0700161{
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800162 if (property.first == "ModuleManufacturerID")
James Feistc50e7c62020-07-27 15:39:36 -0700163 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000164 dimmPropToHex(aResp, "ModuleManufacturerID", property, jsonPtr);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800165 }
166 else if (property.first == "ModuleProductID")
167 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000168 dimmPropToHex(aResp, "ModuleProductID", property, jsonPtr);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800169 }
170 else if (property.first == "SubsystemVendorID")
171 {
172 dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID",
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000173 property, jsonPtr);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800174 }
175 else if (property.first == "SubsystemDeviceID")
176 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000177 dimmPropToHex(aResp, "MemorySubsystemControllerProductID", property,
178 jsonPtr);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800179 }
180 else if (property.first == "VolatileRegionSizeLimitInKiB")
181 {
182 const uint64_t* value = std::get_if<uint64_t>(&property.second);
James Feistc50e7c62020-07-27 15:39:36 -0700183
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800184 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700185 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800186 messages::internalError(aResp->res);
187 BMCWEB_LOG_DEBUG
188 << "Invalid property type for VolatileRegionSizeLimitKiB";
189 return;
190 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000191 aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] =
192 (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800193 }
194 else if (property.first == "PmRegionSizeLimitInKiB")
195 {
196 const uint64_t* value = std::get_if<uint64_t>(&property.second);
James Feistc50e7c62020-07-27 15:39:36 -0700197
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800198 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700199 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800200 messages::internalError(aResp->res);
201 BMCWEB_LOG_DEBUG << "Invalid property type for PmRegioSizeLimitKiB";
202 return;
203 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000204 aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] =
205 (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800206 }
207 else if (property.first == "VolatileSizeInKiB")
208 {
209 const uint64_t* value = std::get_if<uint64_t>(&property.second);
James Feistc50e7c62020-07-27 15:39:36 -0700210
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800211 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700212 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800213 messages::internalError(aResp->res);
214 BMCWEB_LOG_DEBUG << "Invalid property type for VolatileSizeInKiB";
215 return;
James Feistc50e7c62020-07-27 15:39:36 -0700216 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000217 aResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] = (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800218 }
219 else if (property.first == "PmSizeInKiB")
220 {
221 const uint64_t* value = std::get_if<uint64_t>(&property.second);
222 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700223 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800224 messages::internalError(aResp->res);
225 BMCWEB_LOG_DEBUG << "Invalid property type for PmSizeInKiB";
226 return;
James Feistc50e7c62020-07-27 15:39:36 -0700227 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000228 aResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] = (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800229 }
230 else if (property.first == "CacheSizeInKB")
231 {
232 const uint64_t* value = std::get_if<uint64_t>(&property.second);
233 if (value == nullptr)
234 {
235 messages::internalError(aResp->res);
236 BMCWEB_LOG_DEBUG << "Invalid property type for CacheSizeInKB";
237 return;
238 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000239 aResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] = (*value >> 10);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800240 }
James Feistc50e7c62020-07-27 15:39:36 -0700241
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800242 else if (property.first == "VoltaileRegionMaxSizeInKib")
243 {
244 const uint64_t* value = std::get_if<uint64_t>(&property.second);
James Feistc50e7c62020-07-27 15:39:36 -0700245
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800246 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700247 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800248 messages::internalError(aResp->res);
249 BMCWEB_LOG_DEBUG
250 << "Invalid property type for VolatileRegionMaxSizeInKib";
251 return;
252 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000253 aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] =
254 (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800255 }
256 else if (property.first == "PmRegionMaxSizeInKiB")
257 {
258 const uint64_t* value = std::get_if<uint64_t>(&property.second);
James Feistc50e7c62020-07-27 15:39:36 -0700259
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800260 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700261 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800262 messages::internalError(aResp->res);
263 BMCWEB_LOG_DEBUG
264 << "Invalid property type for PmRegionMaxSizeInKiB";
265 return;
266 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000267 aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] =
268 (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800269 }
270 else if (property.first == "AllocationIncrementInKiB")
271 {
272 const uint64_t* value = std::get_if<uint64_t>(&property.second);
James Feistc50e7c62020-07-27 15:39:36 -0700273
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800274 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700275 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800276 messages::internalError(aResp->res);
277 BMCWEB_LOG_DEBUG
278 << "Invalid property type for AllocationIncrementInKiB";
279 return;
280 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000281 aResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] =
282 (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800283 }
284 else if (property.first == "AllocationAlignmentInKiB")
285 {
286 const uint64_t* value = std::get_if<uint64_t>(&property.second);
James Feistc50e7c62020-07-27 15:39:36 -0700287
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800288 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700289 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800290 messages::internalError(aResp->res);
291 BMCWEB_LOG_DEBUG
292 << "Invalid property type for AllocationAlignmentInKiB";
293 return;
James Feistc50e7c62020-07-27 15:39:36 -0700294 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000295 aResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] =
296 (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800297 }
298 else if (property.first == "VolatileRegionNumberLimit")
299 {
300 const uint64_t* value = std::get_if<uint64_t>(&property.second);
301 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700302 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800303 messages::internalError(aResp->res);
304 return;
James Feistc50e7c62020-07-27 15:39:36 -0700305 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000306 aResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] = *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800307 }
308 else if (property.first == "PmRegionNumberLimit")
309 {
310 const uint64_t* value = std::get_if<uint64_t>(&property.second);
311 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700312 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800313 messages::internalError(aResp->res);
314 return;
James Feistc50e7c62020-07-27 15:39:36 -0700315 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000316 aResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] = *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800317 }
318 else if (property.first == "SpareDeviceCount")
319 {
320 const uint64_t* value = std::get_if<uint64_t>(&property.second);
321 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700322 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800323 messages::internalError(aResp->res);
324 return;
James Feistc50e7c62020-07-27 15:39:36 -0700325 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000326 aResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] = *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800327 }
328 else if (property.first == "IsSpareDeviceInUse")
329 {
330 const bool* value = std::get_if<bool>(&property.second);
331 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700332 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800333 messages::internalError(aResp->res);
334 return;
James Feistc50e7c62020-07-27 15:39:36 -0700335 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000336 aResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] = *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800337 }
338 else if (property.first == "IsRankSpareEnabled")
339 {
340 const bool* value = std::get_if<bool>(&property.second);
341 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700342 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800343 messages::internalError(aResp->res);
344 return;
James Feistc50e7c62020-07-27 15:39:36 -0700345 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000346 aResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] = *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800347 }
348 else if (property.first == "MaxAveragePowerLimitmW")
349 {
350 const auto* value =
351 std::get_if<std::vector<uint32_t>>(&property.second);
352 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700353 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800354 messages::internalError(aResp->res);
355 BMCWEB_LOG_DEBUG
356 << "Invalid property type for MaxAveragePowerLimitmW";
357 return;
James Feistc50e7c62020-07-27 15:39:36 -0700358 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000359 aResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] = *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800360 }
361 else if (property.first == "ConfigurationLocked")
362 {
363 const bool* value = std::get_if<bool>(&property.second);
364 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700365 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800366 messages::internalError(aResp->res);
367 return;
368 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000369 aResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] = *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800370 }
371 else if (property.first == "AllowedMemoryModes")
372 {
373 const std::string* value = std::get_if<std::string>(&property.second);
374 if (value == nullptr)
375 {
376 messages::internalError(aResp->res);
377 BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor";
378 return;
379 }
380 constexpr const std::array<const char*, 3> values{"Volatile", "PMEM",
381 "Block"};
James Feistc50e7c62020-07-27 15:39:36 -0700382
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800383 for (const char* v : values)
384 {
385 if (boost::ends_with(*value, v))
James Feistc50e7c62020-07-27 15:39:36 -0700386 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000387 aResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"].push_back(
388 v);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800389 break;
James Feistc50e7c62020-07-27 15:39:36 -0700390 }
391 }
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800392 }
393 else if (property.first == "MemoryMedia")
394 {
395 const std::string* value = std::get_if<std::string>(&property.second);
396 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700397 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800398 messages::internalError(aResp->res);
399 BMCWEB_LOG_DEBUG << "Invalid property type for MemoryMedia";
400 return;
401 }
402 constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
403 "Intel3DXPoint"};
James Feistc50e7c62020-07-27 15:39:36 -0700404
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800405 for (const char* v : values)
Ed Tanous5fb91ba2020-09-28 15:41:28 -0700406 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800407 if (boost::ends_with(*value, v))
Ed Tanous5fb91ba2020-09-28 15:41:28 -0700408 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000409 aResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800410 break;
Ed Tanous5fb91ba2020-09-28 15:41:28 -0700411 }
Ed Tanous5fb91ba2020-09-28 15:41:28 -0700412 }
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800413 }
414 // PersistantMemory.SecurityCapabilites interface
415 else if (property.first == "ConfigurationLockCapable" ||
416 property.first == "DataLockCapable" ||
417 property.first == "PassphraseCapable")
418 {
419 const bool* value = std::get_if<bool>(&property.second);
420 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700421 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800422 messages::internalError(aResp->res);
423 return;
James Feistc50e7c62020-07-27 15:39:36 -0700424 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000425 aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"][property.first] =
426 *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800427 }
428 else if (property.first == "MaxPassphraseCount" ||
429 property.first == "PassphraseLockLimit")
430 {
431 const uint64_t* value = std::get_if<uint64_t>(&property.second);
432 if (value == nullptr)
433 {
434 messages::internalError(aResp->res);
435 return;
436 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000437 aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"][property.first] =
438 *value;
James Feistc50e7c62020-07-27 15:39:36 -0700439 }
440}
441
Nan Zhou9a5acea2022-05-17 21:12:43 +0000442inline void
443 assembleDimmProperties(std::string_view dimmId,
444 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000445 const dbus::utility::DBusPropertiesMap& properties,
446 const nlohmann::json::json_pointer& jsonPtr)
Nan Zhou9a5acea2022-05-17 21:12:43 +0000447{
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000448 aResp->res.jsonValue[jsonPtr]["Id"] = dimmId;
449 aResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot";
450 aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled";
451 aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK";
Nan Zhou9a5acea2022-05-17 21:12:43 +0000452
453 for (const auto& property : properties)
454 {
455 if (property.first == "MemoryDataWidth")
456 {
457 const uint16_t* value = std::get_if<uint16_t>(&property.second);
458 if (value == nullptr)
459 {
460 continue;
461 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000462 aResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000463 }
464 else if (property.first == "MemorySizeInKB")
465 {
466 const size_t* memorySize = std::get_if<size_t>(&property.second);
467 if (memorySize == nullptr)
468 {
469 // Important property not in desired type
470 messages::internalError(aResp->res);
471 return;
472 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000473 aResp->res.jsonValue[jsonPtr]["CapacityMiB"] = (*memorySize >> 10);
Nan Zhou9a5acea2022-05-17 21:12:43 +0000474 }
475 else if (property.first == "PartNumber")
476 {
477 const std::string* value =
478 std::get_if<std::string>(&property.second);
479 if (value == nullptr)
480 {
481 continue;
482 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000483 aResp->res.jsonValue[jsonPtr]["PartNumber"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000484 }
485 else if (property.first == "SerialNumber")
486 {
487 const std::string* value =
488 std::get_if<std::string>(&property.second);
489 if (value == nullptr)
490 {
491 continue;
492 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000493 aResp->res.jsonValue[jsonPtr]["SerialNumber"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000494 }
495 else if (property.first == "Manufacturer")
496 {
497 const std::string* value =
498 std::get_if<std::string>(&property.second);
499 if (value == nullptr)
500 {
501 continue;
502 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000503 aResp->res.jsonValue[jsonPtr]["Manufacturer"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000504 }
505 else if (property.first == "RevisionCode")
506 {
507 const uint16_t* value = std::get_if<uint16_t>(&property.second);
508
509 if (value == nullptr)
510 {
511 messages::internalError(aResp->res);
512 BMCWEB_LOG_DEBUG << "Invalid property type for RevisionCode";
513 return;
514 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000515 aResp->res.jsonValue[jsonPtr]["FirmwareRevision"] =
516 std::to_string(*value);
Nan Zhou9a5acea2022-05-17 21:12:43 +0000517 }
518 else if (property.first == "Present")
519 {
520 const bool* value = std::get_if<bool>(&property.second);
521 if (value == nullptr)
522 {
523 messages::internalError(aResp->res);
524 BMCWEB_LOG_DEBUG << "Invalid property type for Dimm Presence";
525 return;
526 }
527 if (!*value)
528 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000529 aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent";
Nan Zhou9a5acea2022-05-17 21:12:43 +0000530 }
531 }
532 else if (property.first == "MemoryTotalWidth")
533 {
534 const uint16_t* value = std::get_if<uint16_t>(&property.second);
535 if (value == nullptr)
536 {
537 continue;
538 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000539 aResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000540 }
541 else if (property.first == "ECC")
542 {
543 const std::string* value =
544 std::get_if<std::string>(&property.second);
545 if (value == nullptr)
546 {
547 messages::internalError(aResp->res);
548 BMCWEB_LOG_DEBUG << "Invalid property type for ECC";
549 return;
550 }
551 constexpr const std::array<const char*, 4> values{
552 "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};
553
554 for (const char* v : values)
555 {
556 if (boost::ends_with(*value, v))
557 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000558 aResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000559 break;
560 }
561 }
562 }
563 else if (property.first == "FormFactor")
564 {
565 const std::string* value =
566 std::get_if<std::string>(&property.second);
567 if (value == nullptr)
568 {
569 messages::internalError(aResp->res);
570 BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor";
571 return;
572 }
573 constexpr const std::array<const char*, 11> values{
574 "RDIMM", "UDIMM", "SO_DIMM", "LRDIMM",
575 "Mini_RDIMM", "Mini_UDIMM", "SO_RDIMM_72b", "SO_UDIMM_72b",
576 "SO_DIMM_16b", "SO_DIMM_32b", "Die"};
577
578 for (const char* v : values)
579 {
580 if (boost::ends_with(*value, v))
581 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000582 aResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000583 break;
584 }
585 }
586 }
587 else if (property.first == "AllowedSpeedsMT")
588 {
589 const std::vector<uint16_t>* value =
590 std::get_if<std::vector<uint16_t>>(&property.second);
591 if (value == nullptr)
592 {
593 continue;
594 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000595 nlohmann::json& jValue =
596 aResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"];
Nan Zhou9a5acea2022-05-17 21:12:43 +0000597 jValue = nlohmann::json::array();
598 for (uint16_t subVal : *value)
599 {
600 jValue.push_back(subVal);
601 }
602 }
603 else if (property.first == "MemoryAttributes")
604 {
605 const uint8_t* value = std::get_if<uint8_t>(&property.second);
606
607 if (value == nullptr)
608 {
609 messages::internalError(aResp->res);
610 BMCWEB_LOG_DEBUG
611 << "Invalid property type for MemoryAttributes";
612 return;
613 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000614 aResp->res.jsonValue[jsonPtr]["RankCount"] =
615 static_cast<uint64_t>(*value);
Nan Zhou9a5acea2022-05-17 21:12:43 +0000616 }
617 else if (property.first == "MemoryConfiguredSpeedInMhz")
618 {
619 const uint16_t* value = std::get_if<uint16_t>(&property.second);
620 if (value == nullptr)
621 {
622 continue;
623 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000624 aResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000625 }
626 else if (property.first == "MemoryType")
627 {
628 const auto* value = std::get_if<std::string>(&property.second);
629 if (value != nullptr)
630 {
631 std::string memoryDeviceType =
632 translateMemoryTypeToRedfish(*value);
633 // Values like "Unknown" or "Other" will return empty
634 // so just leave off
635 if (!memoryDeviceType.empty())
636 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000637 aResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] =
638 memoryDeviceType;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000639 }
640 if (value->find("DDR") != std::string::npos)
641 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000642 aResp->res.jsonValue[jsonPtr]["MemoryType"] = "DRAM";
Nan Zhou9a5acea2022-05-17 21:12:43 +0000643 }
644 else if (boost::ends_with(*value, "Logical"))
645 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000646 aResp->res.jsonValue[jsonPtr]["MemoryType"] = "IntelOptane";
Nan Zhou9a5acea2022-05-17 21:12:43 +0000647 }
648 }
649 }
650 // memory location interface
651 else if (property.first == "Channel" ||
652 property.first == "MemoryController" ||
653 property.first == "Slot" || property.first == "Socket")
654 {
655 const std::string* value =
656 std::get_if<std::string>(&property.second);
657 if (value == nullptr)
658 {
659 messages::internalError(aResp->res);
660 return;
661 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000662 aResp->res.jsonValue[jsonPtr]["MemoryLocation"][property.first] =
663 *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000664 }
665 else if (property.first == "SparePartNumber")
666 {
667 const std::string* value =
668 std::get_if<std::string>(&property.second);
669 if (value == nullptr)
670 {
671 messages::internalError(aResp->res);
672 return;
673 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000674 aResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000675 }
676 else if (property.first == "Model")
677 {
678 const std::string* value =
679 std::get_if<std::string>(&property.second);
680 if (value == nullptr)
681 {
682 messages::internalError(aResp->res);
683 return;
684 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000685 aResp->res.jsonValue[jsonPtr]["Model"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000686 }
687 else if (property.first == "LocationCode")
688 {
689 const std::string* value =
690 std::get_if<std::string>(&property.second);
691 if (value == nullptr)
692 {
693 messages::internalError(aResp->res);
694 return;
695 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000696 aResp->res.jsonValue[jsonPtr]["Location"]["PartLocation"]
697 ["ServiceLabel"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000698 }
699 else
700 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000701 getPersistentMemoryProperties(aResp, property, jsonPtr);
Nan Zhou9a5acea2022-05-17 21:12:43 +0000702 }
703 }
704}
705
zhanghch058d1b46d2021-04-01 11:18:24 +0800706inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp,
Ed Tanous80789c82020-08-19 09:19:09 -0700707 const std::string& dimmId,
708 const std::string& service,
709 const std::string& objPath)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200710{
James Feist35e257a2020-06-05 13:30:51 -0700711 auto health = std::make_shared<HealthPopulate>(aResp);
712 health->selfPath = objPath;
713 health->populate();
714
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200715 BMCWEB_LOG_DEBUG << "Get available system components.";
716 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -0800717 [dimmId, aResp{std::move(aResp)}](
718 const boost::system::error_code ec,
719 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700720 if (ec)
721 {
722 BMCWEB_LOG_DEBUG << "DBUS response error";
723 messages::internalError(aResp->res);
724 return;
725 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000726 assembleDimmProperties(dimmId, aResp, properties, ""_json_pointer);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200727 },
728 service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
729}
730
Nan Zhouef00d7d2022-05-20 21:22:32 +0000731inline void assembleDimmPartitionData(
732 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000733 const dbus::utility::DBusPropertiesMap& properties,
734 const nlohmann::json::json_pointer& regionPtr)
Nan Zhouef00d7d2022-05-20 21:22:32 +0000735{
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000736 nlohmann::json::object_t partition;
Nan Zhouef00d7d2022-05-20 21:22:32 +0000737 for (const auto& [key, val] : properties)
738 {
739 if (key == "MemoryClassification")
740 {
741 const std::string* value = std::get_if<std::string>(&val);
742 if (value == nullptr)
743 {
744 messages::internalError(aResp->res);
745 return;
746 }
747 partition[key] = *value;
748 }
749 else if (key == "OffsetInKiB")
750 {
751 const uint64_t* value = std::get_if<uint64_t>(&val);
752 if (value == nullptr)
753 {
754 messages::internalError(aResp->res);
755 return;
756 }
757
758 partition["OffsetMiB"] = (*value >> 10);
759 }
760 else if (key == "PartitionId")
761 {
762 const std::string* value = std::get_if<std::string>(&val);
763 if (value == nullptr)
764 {
765 messages::internalError(aResp->res);
766 return;
767 }
768 partition["RegionId"] = *value;
769 }
770
771 else if (key == "PassphraseState")
772 {
773 const bool* value = std::get_if<bool>(&val);
774 if (value == nullptr)
775 {
776 messages::internalError(aResp->res);
777 return;
778 }
779 partition["PassphraseEnabled"] = *value;
780 }
781 else if (key == "SizeInKiB")
782 {
783 const uint64_t* value = std::get_if<uint64_t>(&val);
784 if (value == nullptr)
785 {
786 messages::internalError(aResp->res);
787 BMCWEB_LOG_DEBUG << "Invalid property type for SizeInKiB";
788 return;
789 }
790 partition["SizeMiB"] = (*value >> 10);
791 }
792 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000793 aResp->res.jsonValue[regionPtr].emplace_back(std::move(partition));
Nan Zhouef00d7d2022-05-20 21:22:32 +0000794}
795
zhanghch058d1b46d2021-04-01 11:18:24 +0800796inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp,
Ed Tanous23a21a12020-07-25 04:45:05 +0000797 const std::string& service,
798 const std::string& path)
James Feist45094ad2020-04-29 14:02:30 -0700799{
800 crow::connections::systemBus->async_method_call(
801 [aResp{std::move(aResp)}](
802 const boost::system::error_code ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800803 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700804 if (ec)
805 {
806 BMCWEB_LOG_DEBUG << "DBUS response error";
807 messages::internalError(aResp->res);
James Feist45094ad2020-04-29 14:02:30 -0700808
Ed Tanous002d39b2022-05-31 08:59:27 -0700809 return;
810 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000811 nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
812 assembleDimmPartitionData(aResp, properties, regionPtr);
James Feist45094ad2020-04-29 14:02:30 -0700813 },
814
815 service, path, "org.freedesktop.DBus.Properties", "GetAll",
816 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition");
817}
818
zhanghch058d1b46d2021-04-01 11:18:24 +0800819inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp,
Ed Tanous23a21a12020-07-25 04:45:05 +0000820 const std::string& dimmId)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200821{
822 BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
823 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -0800824 [dimmId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200825 const boost::system::error_code ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800826 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700827 if (ec)
828 {
829 BMCWEB_LOG_DEBUG << "DBUS response error";
830 messages::internalError(aResp->res);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200831
Ed Tanous002d39b2022-05-31 08:59:27 -0700832 return;
833 }
834 bool found = false;
Nan Zhou76686dc2022-06-17 23:01:51 +0000835 for (const auto& [rawPath, object] : subtree)
Ed Tanous002d39b2022-05-31 08:59:27 -0700836 {
Nan Zhou76686dc2022-06-17 23:01:51 +0000837 sdbusplus::message::object_path path(rawPath);
838 for (const auto& [service, interfaces] : object)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200839 {
Nan Zhou76686dc2022-06-17 23:01:51 +0000840 for (const auto& interface : interfaces)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200841 {
Nan Zhou76686dc2022-06-17 23:01:51 +0000842 if (interface ==
843 "xyz.openbmc_project.Inventory.Item.Dimm" &&
844 path.filename() == dimmId)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200845 {
Nan Zhou76686dc2022-06-17 23:01:51 +0000846 getDimmDataByService(aResp, dimmId, service, rawPath);
847 found = true;
848 }
James Feist45094ad2020-04-29 14:02:30 -0700849
Nan Zhou76686dc2022-06-17 23:01:51 +0000850 // partitions are separate as there can be multiple
851 // per
852 // device, i.e.
853 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
854 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
855 if (interface ==
856 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
857 path.parent_path().filename() == dimmId)
858 {
859 getDimmPartitionData(aResp, service, rawPath);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200860 }
861 }
862 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700863 }
864 // Object not found
865 if (!found)
866 {
867 messages::resourceNotFound(aResp->res, "Memory", dimmId);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200868 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700869 }
870 // Set @odata only if object is found
871 aResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
872 aResp->res.jsonValue["@odata.id"] =
873 "/redfish/v1/Systems/system/Memory/" + dimmId;
874 return;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200875 },
876 "xyz.openbmc_project.ObjectMapper",
877 "/xyz/openbmc_project/object_mapper",
878 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -0700879 "/xyz/openbmc_project/inventory", 0,
James Feist45094ad2020-04-29 14:02:30 -0700880 std::array<const char*, 2>{
881 "xyz.openbmc_project.Inventory.Item.Dimm",
882 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"});
Ed Tanous271584a2019-07-09 16:24:22 -0700883}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200884
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700885inline void requestRoutesMemoryCollection(App& app)
Ed Tanous029573d2019-02-01 10:57:49 -0800886{
Ed Tanous029573d2019-02-01 10:57:49 -0800887 /**
888 * Functions triggers appropriate requests on DBus
889 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700890 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/")
Ed Tanoused398212021-06-09 17:05:54 -0700891 .privileges(redfish::privileges::getMemoryCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700892 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700893 [&app](const crow::Request& req,
894 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000895 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700896 {
897 return;
898 }
899 asyncResp->res.jsonValue["@odata.type"] =
900 "#MemoryCollection.MemoryCollection";
901 asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
902 asyncResp->res.jsonValue["@odata.id"] =
903 "/redfish/v1/Systems/system/Memory";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200904
Ed Tanous002d39b2022-05-31 08:59:27 -0700905 collection_util::getCollectionMembers(
906 asyncResp, "/redfish/v1/Systems/system/Memory",
907 {"xyz.openbmc_project.Inventory.Item.Dimm"});
908 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700909}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200910
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700911inline void requestRoutesMemory(App& app)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200912{
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200913 /**
914 * Functions triggers appropriate requests on DBus
915 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700916 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700917 .privileges(redfish::privileges::getMemory)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700918 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700919 [&app](const crow::Request& req,
920 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
921 const std::string& dimmId) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000922 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700923 {
924 return;
925 }
926 getDimmData(asyncResp, dimmId);
927 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700928}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200929
930} // namespace redfish