blob: c4a2ef4ca65276e2df06b496173d4b06c91767d3 [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
Jiaqing Zhaofbe4fb62022-06-20 12:32:22 +0800142inline void
143 dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
144 const char* key,
145 const dbus::utility::DBusPropertiesMap::value_type& property,
146 const nlohmann::json::json_pointer& jsonPtr)
James Feistc50e7c62020-07-27 15:39:36 -0700147{
148 const uint16_t* value = std::get_if<uint16_t>(&property.second);
149 if (value == nullptr)
150 {
151 messages::internalError(aResp->res);
152 BMCWEB_LOG_DEBUG << "Invalid property type for " << property.first;
153 return;
154 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000155 aResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4);
James Feistc50e7c62020-07-27 15:39:36 -0700156}
157
zhanghch058d1b46d2021-04-01 11:18:24 +0800158inline void getPersistentMemoryProperties(
159 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Jiaqing Zhaofbe4fb62022-06-20 12:32:22 +0800160 const dbus::utility::DBusPropertiesMap::value_type& property,
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000161 const nlohmann::json::json_pointer& jsonPtr)
James Feistc50e7c62020-07-27 15:39:36 -0700162{
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800163 if (property.first == "ModuleManufacturerID")
James Feistc50e7c62020-07-27 15:39:36 -0700164 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000165 dimmPropToHex(aResp, "ModuleManufacturerID", property, jsonPtr);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800166 }
167 else if (property.first == "ModuleProductID")
168 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000169 dimmPropToHex(aResp, "ModuleProductID", property, jsonPtr);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800170 }
171 else if (property.first == "SubsystemVendorID")
172 {
173 dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID",
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000174 property, jsonPtr);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800175 }
176 else if (property.first == "SubsystemDeviceID")
177 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000178 dimmPropToHex(aResp, "MemorySubsystemControllerProductID", property,
179 jsonPtr);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800180 }
181 else if (property.first == "VolatileRegionSizeLimitInKiB")
182 {
183 const uint64_t* value = std::get_if<uint64_t>(&property.second);
James Feistc50e7c62020-07-27 15:39:36 -0700184
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800185 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700186 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800187 messages::internalError(aResp->res);
188 BMCWEB_LOG_DEBUG
189 << "Invalid property type for VolatileRegionSizeLimitKiB";
190 return;
191 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000192 aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] =
193 (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800194 }
195 else if (property.first == "PmRegionSizeLimitInKiB")
196 {
197 const uint64_t* value = std::get_if<uint64_t>(&property.second);
James Feistc50e7c62020-07-27 15:39:36 -0700198
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800199 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700200 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800201 messages::internalError(aResp->res);
202 BMCWEB_LOG_DEBUG << "Invalid property type for PmRegioSizeLimitKiB";
203 return;
204 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000205 aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] =
206 (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800207 }
208 else if (property.first == "VolatileSizeInKiB")
209 {
210 const uint64_t* value = std::get_if<uint64_t>(&property.second);
James Feistc50e7c62020-07-27 15:39:36 -0700211
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800212 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700213 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800214 messages::internalError(aResp->res);
215 BMCWEB_LOG_DEBUG << "Invalid property type for VolatileSizeInKiB";
216 return;
James Feistc50e7c62020-07-27 15:39:36 -0700217 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000218 aResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] = (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800219 }
220 else if (property.first == "PmSizeInKiB")
221 {
222 const uint64_t* value = std::get_if<uint64_t>(&property.second);
223 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700224 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800225 messages::internalError(aResp->res);
226 BMCWEB_LOG_DEBUG << "Invalid property type for PmSizeInKiB";
227 return;
James Feistc50e7c62020-07-27 15:39:36 -0700228 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000229 aResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] = (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800230 }
231 else if (property.first == "CacheSizeInKB")
232 {
233 const uint64_t* value = std::get_if<uint64_t>(&property.second);
234 if (value == nullptr)
235 {
236 messages::internalError(aResp->res);
237 BMCWEB_LOG_DEBUG << "Invalid property type for CacheSizeInKB";
238 return;
239 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000240 aResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] = (*value >> 10);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800241 }
James Feistc50e7c62020-07-27 15:39:36 -0700242
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800243 else if (property.first == "VoltaileRegionMaxSizeInKib")
244 {
245 const uint64_t* value = std::get_if<uint64_t>(&property.second);
James Feistc50e7c62020-07-27 15:39:36 -0700246
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800247 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700248 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800249 messages::internalError(aResp->res);
250 BMCWEB_LOG_DEBUG
251 << "Invalid property type for VolatileRegionMaxSizeInKib";
252 return;
253 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000254 aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] =
255 (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800256 }
257 else if (property.first == "PmRegionMaxSizeInKiB")
258 {
259 const uint64_t* value = std::get_if<uint64_t>(&property.second);
James Feistc50e7c62020-07-27 15:39:36 -0700260
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800261 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700262 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800263 messages::internalError(aResp->res);
264 BMCWEB_LOG_DEBUG
265 << "Invalid property type for PmRegionMaxSizeInKiB";
266 return;
267 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000268 aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] =
269 (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800270 }
271 else if (property.first == "AllocationIncrementInKiB")
272 {
273 const uint64_t* value = std::get_if<uint64_t>(&property.second);
James Feistc50e7c62020-07-27 15:39:36 -0700274
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800275 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700276 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800277 messages::internalError(aResp->res);
278 BMCWEB_LOG_DEBUG
279 << "Invalid property type for AllocationIncrementInKiB";
280 return;
281 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000282 aResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] =
283 (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800284 }
285 else if (property.first == "AllocationAlignmentInKiB")
286 {
287 const uint64_t* value = std::get_if<uint64_t>(&property.second);
James Feistc50e7c62020-07-27 15:39:36 -0700288
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800289 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700290 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800291 messages::internalError(aResp->res);
292 BMCWEB_LOG_DEBUG
293 << "Invalid property type for AllocationAlignmentInKiB";
294 return;
James Feistc50e7c62020-07-27 15:39:36 -0700295 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000296 aResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] =
297 (*value) >> 10;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800298 }
299 else if (property.first == "VolatileRegionNumberLimit")
300 {
301 const uint64_t* value = std::get_if<uint64_t>(&property.second);
302 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700303 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800304 messages::internalError(aResp->res);
305 return;
James Feistc50e7c62020-07-27 15:39:36 -0700306 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000307 aResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] = *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800308 }
309 else if (property.first == "PmRegionNumberLimit")
310 {
311 const uint64_t* value = std::get_if<uint64_t>(&property.second);
312 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700313 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800314 messages::internalError(aResp->res);
315 return;
James Feistc50e7c62020-07-27 15:39:36 -0700316 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000317 aResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] = *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800318 }
319 else if (property.first == "SpareDeviceCount")
320 {
321 const uint64_t* value = std::get_if<uint64_t>(&property.second);
322 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700323 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800324 messages::internalError(aResp->res);
325 return;
James Feistc50e7c62020-07-27 15:39:36 -0700326 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000327 aResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] = *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800328 }
329 else if (property.first == "IsSpareDeviceInUse")
330 {
331 const bool* value = std::get_if<bool>(&property.second);
332 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700333 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800334 messages::internalError(aResp->res);
335 return;
James Feistc50e7c62020-07-27 15:39:36 -0700336 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000337 aResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] = *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800338 }
339 else if (property.first == "IsRankSpareEnabled")
340 {
341 const bool* value = std::get_if<bool>(&property.second);
342 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700343 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800344 messages::internalError(aResp->res);
345 return;
James Feistc50e7c62020-07-27 15:39:36 -0700346 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000347 aResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] = *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800348 }
349 else if (property.first == "MaxAveragePowerLimitmW")
350 {
351 const auto* value =
352 std::get_if<std::vector<uint32_t>>(&property.second);
353 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700354 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800355 messages::internalError(aResp->res);
356 BMCWEB_LOG_DEBUG
357 << "Invalid property type for MaxAveragePowerLimitmW";
358 return;
James Feistc50e7c62020-07-27 15:39:36 -0700359 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000360 aResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] = *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800361 }
362 else if (property.first == "ConfigurationLocked")
363 {
364 const bool* value = std::get_if<bool>(&property.second);
365 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700366 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800367 messages::internalError(aResp->res);
368 return;
369 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000370 aResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] = *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800371 }
372 else if (property.first == "AllowedMemoryModes")
373 {
374 const std::string* value = std::get_if<std::string>(&property.second);
375 if (value == nullptr)
376 {
377 messages::internalError(aResp->res);
378 BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor";
379 return;
380 }
381 constexpr const std::array<const char*, 3> values{"Volatile", "PMEM",
382 "Block"};
James Feistc50e7c62020-07-27 15:39:36 -0700383
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800384 for (const char* v : values)
385 {
386 if (boost::ends_with(*value, v))
James Feistc50e7c62020-07-27 15:39:36 -0700387 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000388 aResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"].push_back(
389 v);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800390 break;
James Feistc50e7c62020-07-27 15:39:36 -0700391 }
392 }
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800393 }
394 else if (property.first == "MemoryMedia")
395 {
396 const std::string* value = std::get_if<std::string>(&property.second);
397 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700398 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800399 messages::internalError(aResp->res);
400 BMCWEB_LOG_DEBUG << "Invalid property type for MemoryMedia";
401 return;
402 }
403 constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
404 "Intel3DXPoint"};
James Feistc50e7c62020-07-27 15:39:36 -0700405
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800406 for (const char* v : values)
Ed Tanous5fb91ba2020-09-28 15:41:28 -0700407 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800408 if (boost::ends_with(*value, v))
Ed Tanous5fb91ba2020-09-28 15:41:28 -0700409 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000410 aResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v);
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800411 break;
Ed Tanous5fb91ba2020-09-28 15:41:28 -0700412 }
Ed Tanous5fb91ba2020-09-28 15:41:28 -0700413 }
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800414 }
415 // PersistantMemory.SecurityCapabilites interface
416 else if (property.first == "ConfigurationLockCapable" ||
417 property.first == "DataLockCapable" ||
418 property.first == "PassphraseCapable")
419 {
420 const bool* value = std::get_if<bool>(&property.second);
421 if (value == nullptr)
James Feistc50e7c62020-07-27 15:39:36 -0700422 {
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800423 messages::internalError(aResp->res);
424 return;
James Feistc50e7c62020-07-27 15:39:36 -0700425 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000426 aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"][property.first] =
427 *value;
Jiaqing Zhao80badf72022-03-18 17:48:53 +0800428 }
429 else if (property.first == "MaxPassphraseCount" ||
430 property.first == "PassphraseLockLimit")
431 {
432 const uint64_t* value = std::get_if<uint64_t>(&property.second);
433 if (value == nullptr)
434 {
435 messages::internalError(aResp->res);
436 return;
437 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000438 aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"][property.first] =
439 *value;
James Feistc50e7c62020-07-27 15:39:36 -0700440 }
441}
442
Nan Zhou9a5acea2022-05-17 21:12:43 +0000443inline void
444 assembleDimmProperties(std::string_view dimmId,
445 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000446 const dbus::utility::DBusPropertiesMap& properties,
447 const nlohmann::json::json_pointer& jsonPtr)
Nan Zhou9a5acea2022-05-17 21:12:43 +0000448{
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000449 aResp->res.jsonValue[jsonPtr]["Id"] = dimmId;
450 aResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot";
451 aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled";
452 aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK";
Nan Zhou9a5acea2022-05-17 21:12:43 +0000453
454 for (const auto& property : properties)
455 {
456 if (property.first == "MemoryDataWidth")
457 {
458 const uint16_t* value = std::get_if<uint16_t>(&property.second);
459 if (value == nullptr)
460 {
461 continue;
462 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000463 aResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000464 }
465 else if (property.first == "MemorySizeInKB")
466 {
467 const size_t* memorySize = std::get_if<size_t>(&property.second);
468 if (memorySize == nullptr)
469 {
470 // Important property not in desired type
471 messages::internalError(aResp->res);
472 return;
473 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000474 aResp->res.jsonValue[jsonPtr]["CapacityMiB"] = (*memorySize >> 10);
Nan Zhou9a5acea2022-05-17 21:12:43 +0000475 }
476 else if (property.first == "PartNumber")
477 {
478 const std::string* value =
479 std::get_if<std::string>(&property.second);
480 if (value == nullptr)
481 {
482 continue;
483 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000484 aResp->res.jsonValue[jsonPtr]["PartNumber"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000485 }
486 else if (property.first == "SerialNumber")
487 {
488 const std::string* value =
489 std::get_if<std::string>(&property.second);
490 if (value == nullptr)
491 {
492 continue;
493 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000494 aResp->res.jsonValue[jsonPtr]["SerialNumber"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000495 }
496 else if (property.first == "Manufacturer")
497 {
498 const std::string* value =
499 std::get_if<std::string>(&property.second);
500 if (value == nullptr)
501 {
502 continue;
503 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000504 aResp->res.jsonValue[jsonPtr]["Manufacturer"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000505 }
506 else if (property.first == "RevisionCode")
507 {
508 const uint16_t* value = std::get_if<uint16_t>(&property.second);
509
510 if (value == nullptr)
511 {
512 messages::internalError(aResp->res);
513 BMCWEB_LOG_DEBUG << "Invalid property type for RevisionCode";
514 return;
515 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000516 aResp->res.jsonValue[jsonPtr]["FirmwareRevision"] =
517 std::to_string(*value);
Nan Zhou9a5acea2022-05-17 21:12:43 +0000518 }
519 else if (property.first == "Present")
520 {
521 const bool* value = std::get_if<bool>(&property.second);
522 if (value == nullptr)
523 {
524 messages::internalError(aResp->res);
525 BMCWEB_LOG_DEBUG << "Invalid property type for Dimm Presence";
526 return;
527 }
528 if (!*value)
529 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000530 aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent";
Nan Zhou9a5acea2022-05-17 21:12:43 +0000531 }
532 }
533 else if (property.first == "MemoryTotalWidth")
534 {
535 const uint16_t* value = std::get_if<uint16_t>(&property.second);
536 if (value == nullptr)
537 {
538 continue;
539 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000540 aResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000541 }
542 else if (property.first == "ECC")
543 {
544 const std::string* value =
545 std::get_if<std::string>(&property.second);
546 if (value == nullptr)
547 {
548 messages::internalError(aResp->res);
549 BMCWEB_LOG_DEBUG << "Invalid property type for ECC";
550 return;
551 }
552 constexpr const std::array<const char*, 4> values{
553 "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};
554
555 for (const char* v : values)
556 {
557 if (boost::ends_with(*value, v))
558 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000559 aResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000560 break;
561 }
562 }
563 }
564 else if (property.first == "FormFactor")
565 {
566 const std::string* value =
567 std::get_if<std::string>(&property.second);
568 if (value == nullptr)
569 {
570 messages::internalError(aResp->res);
571 BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor";
572 return;
573 }
574 constexpr const std::array<const char*, 11> values{
575 "RDIMM", "UDIMM", "SO_DIMM", "LRDIMM",
576 "Mini_RDIMM", "Mini_UDIMM", "SO_RDIMM_72b", "SO_UDIMM_72b",
577 "SO_DIMM_16b", "SO_DIMM_32b", "Die"};
578
579 for (const char* v : values)
580 {
581 if (boost::ends_with(*value, v))
582 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000583 aResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000584 break;
585 }
586 }
587 }
588 else if (property.first == "AllowedSpeedsMT")
589 {
590 const std::vector<uint16_t>* value =
591 std::get_if<std::vector<uint16_t>>(&property.second);
592 if (value == nullptr)
593 {
594 continue;
595 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000596 nlohmann::json& jValue =
597 aResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"];
Nan Zhou9a5acea2022-05-17 21:12:43 +0000598 jValue = nlohmann::json::array();
599 for (uint16_t subVal : *value)
600 {
601 jValue.push_back(subVal);
602 }
603 }
604 else if (property.first == "MemoryAttributes")
605 {
606 const uint8_t* value = std::get_if<uint8_t>(&property.second);
607
608 if (value == nullptr)
609 {
610 messages::internalError(aResp->res);
611 BMCWEB_LOG_DEBUG
612 << "Invalid property type for MemoryAttributes";
613 return;
614 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000615 aResp->res.jsonValue[jsonPtr]["RankCount"] =
616 static_cast<uint64_t>(*value);
Nan Zhou9a5acea2022-05-17 21:12:43 +0000617 }
618 else if (property.first == "MemoryConfiguredSpeedInMhz")
619 {
620 const uint16_t* value = std::get_if<uint16_t>(&property.second);
621 if (value == nullptr)
622 {
623 continue;
624 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000625 aResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000626 }
627 else if (property.first == "MemoryType")
628 {
629 const auto* value = std::get_if<std::string>(&property.second);
630 if (value != nullptr)
631 {
632 std::string memoryDeviceType =
633 translateMemoryTypeToRedfish(*value);
634 // Values like "Unknown" or "Other" will return empty
635 // so just leave off
636 if (!memoryDeviceType.empty())
637 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000638 aResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] =
639 memoryDeviceType;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000640 }
641 if (value->find("DDR") != std::string::npos)
642 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000643 aResp->res.jsonValue[jsonPtr]["MemoryType"] = "DRAM";
Nan Zhou9a5acea2022-05-17 21:12:43 +0000644 }
645 else if (boost::ends_with(*value, "Logical"))
646 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000647 aResp->res.jsonValue[jsonPtr]["MemoryType"] = "IntelOptane";
Nan Zhou9a5acea2022-05-17 21:12:43 +0000648 }
649 }
650 }
651 // memory location interface
652 else if (property.first == "Channel" ||
653 property.first == "MemoryController" ||
654 property.first == "Slot" || property.first == "Socket")
655 {
656 const std::string* value =
657 std::get_if<std::string>(&property.second);
658 if (value == nullptr)
659 {
660 messages::internalError(aResp->res);
661 return;
662 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000663 aResp->res.jsonValue[jsonPtr]["MemoryLocation"][property.first] =
664 *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000665 }
666 else if (property.first == "SparePartNumber")
667 {
668 const std::string* value =
669 std::get_if<std::string>(&property.second);
670 if (value == nullptr)
671 {
672 messages::internalError(aResp->res);
673 return;
674 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000675 aResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000676 }
677 else if (property.first == "Model")
678 {
679 const std::string* value =
680 std::get_if<std::string>(&property.second);
681 if (value == nullptr)
682 {
683 messages::internalError(aResp->res);
684 return;
685 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000686 aResp->res.jsonValue[jsonPtr]["Model"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000687 }
688 else if (property.first == "LocationCode")
689 {
690 const std::string* value =
691 std::get_if<std::string>(&property.second);
692 if (value == nullptr)
693 {
694 messages::internalError(aResp->res);
695 return;
696 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000697 aResp->res.jsonValue[jsonPtr]["Location"]["PartLocation"]
698 ["ServiceLabel"] = *value;
Nan Zhou9a5acea2022-05-17 21:12:43 +0000699 }
700 else
701 {
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000702 getPersistentMemoryProperties(aResp, property, jsonPtr);
Nan Zhou9a5acea2022-05-17 21:12:43 +0000703 }
704 }
705}
706
zhanghch058d1b46d2021-04-01 11:18:24 +0800707inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp,
Ed Tanous80789c82020-08-19 09:19:09 -0700708 const std::string& dimmId,
709 const std::string& service,
710 const std::string& objPath)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200711{
James Feist35e257a2020-06-05 13:30:51 -0700712 auto health = std::make_shared<HealthPopulate>(aResp);
713 health->selfPath = objPath;
714 health->populate();
715
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200716 BMCWEB_LOG_DEBUG << "Get available system components.";
717 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -0800718 [dimmId, aResp{std::move(aResp)}](
719 const boost::system::error_code ec,
720 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700721 if (ec)
722 {
723 BMCWEB_LOG_DEBUG << "DBUS response error";
724 messages::internalError(aResp->res);
725 return;
726 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000727 assembleDimmProperties(dimmId, aResp, properties, ""_json_pointer);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200728 },
729 service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
730}
731
Nan Zhouef00d7d2022-05-20 21:22:32 +0000732inline void assembleDimmPartitionData(
733 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000734 const dbus::utility::DBusPropertiesMap& properties,
735 const nlohmann::json::json_pointer& regionPtr)
Nan Zhouef00d7d2022-05-20 21:22:32 +0000736{
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000737 nlohmann::json::object_t partition;
Nan Zhouef00d7d2022-05-20 21:22:32 +0000738 for (const auto& [key, val] : properties)
739 {
740 if (key == "MemoryClassification")
741 {
742 const std::string* value = std::get_if<std::string>(&val);
743 if (value == nullptr)
744 {
745 messages::internalError(aResp->res);
746 return;
747 }
748 partition[key] = *value;
749 }
750 else if (key == "OffsetInKiB")
751 {
752 const uint64_t* value = std::get_if<uint64_t>(&val);
753 if (value == nullptr)
754 {
755 messages::internalError(aResp->res);
756 return;
757 }
758
759 partition["OffsetMiB"] = (*value >> 10);
760 }
761 else if (key == "PartitionId")
762 {
763 const std::string* value = std::get_if<std::string>(&val);
764 if (value == nullptr)
765 {
766 messages::internalError(aResp->res);
767 return;
768 }
769 partition["RegionId"] = *value;
770 }
771
772 else if (key == "PassphraseState")
773 {
774 const bool* value = std::get_if<bool>(&val);
775 if (value == nullptr)
776 {
777 messages::internalError(aResp->res);
778 return;
779 }
780 partition["PassphraseEnabled"] = *value;
781 }
782 else if (key == "SizeInKiB")
783 {
784 const uint64_t* value = std::get_if<uint64_t>(&val);
785 if (value == nullptr)
786 {
787 messages::internalError(aResp->res);
788 BMCWEB_LOG_DEBUG << "Invalid property type for SizeInKiB";
789 return;
790 }
791 partition["SizeMiB"] = (*value >> 10);
792 }
793 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000794 aResp->res.jsonValue[regionPtr].emplace_back(std::move(partition));
Nan Zhouef00d7d2022-05-20 21:22:32 +0000795}
796
zhanghch058d1b46d2021-04-01 11:18:24 +0800797inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp,
Ed Tanous23a21a12020-07-25 04:45:05 +0000798 const std::string& service,
799 const std::string& path)
James Feist45094ad2020-04-29 14:02:30 -0700800{
801 crow::connections::systemBus->async_method_call(
802 [aResp{std::move(aResp)}](
803 const boost::system::error_code ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800804 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700805 if (ec)
806 {
807 BMCWEB_LOG_DEBUG << "DBUS response error";
808 messages::internalError(aResp->res);
James Feist45094ad2020-04-29 14:02:30 -0700809
Ed Tanous002d39b2022-05-31 08:59:27 -0700810 return;
811 }
Nan Zhoud7f04fd2022-05-01 01:11:07 +0000812 nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
813 assembleDimmPartitionData(aResp, properties, regionPtr);
James Feist45094ad2020-04-29 14:02:30 -0700814 },
815
816 service, path, "org.freedesktop.DBus.Properties", "GetAll",
817 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition");
818}
819
zhanghch058d1b46d2021-04-01 11:18:24 +0800820inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp,
Ed Tanous23a21a12020-07-25 04:45:05 +0000821 const std::string& dimmId)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200822{
823 BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
824 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -0800825 [dimmId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200826 const boost::system::error_code ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800827 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700828 if (ec)
829 {
830 BMCWEB_LOG_DEBUG << "DBUS response error";
831 messages::internalError(aResp->res);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200832
Ed Tanous002d39b2022-05-31 08:59:27 -0700833 return;
834 }
835 bool found = false;
Nan Zhou76686dc2022-06-17 23:01:51 +0000836 for (const auto& [rawPath, object] : subtree)
Ed Tanous002d39b2022-05-31 08:59:27 -0700837 {
Nan Zhou76686dc2022-06-17 23:01:51 +0000838 sdbusplus::message::object_path path(rawPath);
839 for (const auto& [service, interfaces] : object)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200840 {
Nan Zhou76686dc2022-06-17 23:01:51 +0000841 for (const auto& interface : interfaces)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200842 {
Nan Zhou76686dc2022-06-17 23:01:51 +0000843 if (interface ==
844 "xyz.openbmc_project.Inventory.Item.Dimm" &&
845 path.filename() == dimmId)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200846 {
Nan Zhou76686dc2022-06-17 23:01:51 +0000847 getDimmDataByService(aResp, dimmId, service, rawPath);
848 found = true;
849 }
James Feist45094ad2020-04-29 14:02:30 -0700850
Nan Zhou76686dc2022-06-17 23:01:51 +0000851 // partitions are separate as there can be multiple
852 // per
853 // device, i.e.
854 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
855 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
856 if (interface ==
857 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
858 path.parent_path().filename() == dimmId)
859 {
860 getDimmPartitionData(aResp, service, rawPath);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200861 }
862 }
863 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700864 }
865 // Object not found
866 if (!found)
867 {
868 messages::resourceNotFound(aResp->res, "Memory", dimmId);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200869 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700870 }
871 // Set @odata only if object is found
872 aResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
873 aResp->res.jsonValue["@odata.id"] =
874 "/redfish/v1/Systems/system/Memory/" + dimmId;
875 return;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200876 },
877 "xyz.openbmc_project.ObjectMapper",
878 "/xyz/openbmc_project/object_mapper",
879 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -0700880 "/xyz/openbmc_project/inventory", 0,
James Feist45094ad2020-04-29 14:02:30 -0700881 std::array<const char*, 2>{
882 "xyz.openbmc_project.Inventory.Item.Dimm",
883 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"});
Ed Tanous271584a2019-07-09 16:24:22 -0700884}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200885
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700886inline void requestRoutesMemoryCollection(App& app)
Ed Tanous029573d2019-02-01 10:57:49 -0800887{
Ed Tanous029573d2019-02-01 10:57:49 -0800888 /**
889 * Functions triggers appropriate requests on DBus
890 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700891 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/")
Ed Tanoused398212021-06-09 17:05:54 -0700892 .privileges(redfish::privileges::getMemoryCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700893 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700894 [&app](const crow::Request& req,
895 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000896 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700897 {
898 return;
899 }
900 asyncResp->res.jsonValue["@odata.type"] =
901 "#MemoryCollection.MemoryCollection";
902 asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
903 asyncResp->res.jsonValue["@odata.id"] =
904 "/redfish/v1/Systems/system/Memory";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200905
Ed Tanous002d39b2022-05-31 08:59:27 -0700906 collection_util::getCollectionMembers(
907 asyncResp, "/redfish/v1/Systems/system/Memory",
908 {"xyz.openbmc_project.Inventory.Item.Dimm"});
909 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700910}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200911
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700912inline void requestRoutesMemory(App& app)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200913{
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200914 /**
915 * Functions triggers appropriate requests on DBus
916 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700917 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700918 .privileges(redfish::privileges::getMemory)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700919 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700920 [&app](const crow::Request& req,
921 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
922 const std::string& dimmId) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000923 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700924 {
925 return;
926 }
927 getDimmData(asyncResp, dimmId);
928 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700929}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200930
931} // namespace redfish