blob: 0ea5e87dfa4308f321d980616756f2d0d6da0103 [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
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020020#include <boost/container/flat_map.hpp>
James Feistc50e7c62020-07-27 15:39:36 -070021#include <boost/format.hpp>
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020022#include <node.hpp>
23#include <utils/json_utils.hpp>
24
25namespace redfish
26{
27
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060028using InterfacesProperties = boost::container::flat_map<
29 std::string,
30 boost::container::flat_map<std::string, dbus::utility::DbusVariantType>>;
31
Ed Tanous029573d2019-02-01 10:57:49 -080032void getResourceList(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -050033 const std::string& subclass,
34 const std::vector<const char*>& collectionName)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020035{
36 BMCWEB_LOG_DEBUG << "Get available system cpu/mem resources.";
37 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -080038 [subclass, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020039 const boost::system::error_code ec,
40 const boost::container::flat_map<
41 std::string, boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -050042 std::string, std::vector<std::string>>>&
43 subtree) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020044 if (ec)
45 {
46 BMCWEB_LOG_DEBUG << "DBUS response error";
47 messages::internalError(aResp->res);
48 return;
49 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -050050 nlohmann::json& members = aResp->res.jsonValue["Members"];
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020051 members = nlohmann::json::array();
52
Gunnar Mills1214b7e2020-06-04 10:11:30 -050053 for (const auto& object : subtree)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020054 {
55 auto iter = object.first.rfind("/");
56 if ((iter != std::string::npos) && (iter < object.first.size()))
57 {
58 members.push_back(
Ed Tanous029573d2019-02-01 10:57:49 -080059 {{"@odata.id", "/redfish/v1/Systems/system/" +
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020060 subclass + "/" +
61 object.first.substr(iter + 1)}});
62 }
63 }
64 aResp->res.jsonValue["Members@odata.count"] = members.size();
65 },
66 "xyz.openbmc_project.ObjectMapper",
67 "/xyz/openbmc_project/object_mapper",
68 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -070069 "/xyz/openbmc_project/inventory", 0, collectionName);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020070}
71
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060072void getCpuDataByInterface(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -050073 const InterfacesProperties& cpuInterfacesProperties)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020074{
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060075 BMCWEB_LOG_DEBUG << "Get CPU resources by interface.";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020076
Gunnar Mills1214b7e2020-06-04 10:11:30 -050077 const bool* present = nullptr;
78 const bool* functional = nullptr;
79 for (const auto& interface : cpuInterfacesProperties)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060080 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050081 for (const auto& property : interface.second)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060082 {
83 if (property.first == "ProcessorCoreCount")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020084 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050085 const uint16_t* coresCount =
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060086 std::get_if<uint16_t>(&property.second);
Ed Tanous883b3112018-12-06 16:13:35 -080087 if (coresCount == nullptr)
88 {
89 // Important property not in desired type
90 messages::internalError(aResp->res);
91 return;
92 }
93 if (*coresCount == 0)
94 {
95 // Slot is not populated, set status end return
96 aResp->res.jsonValue["Status"]["State"] = "Absent";
97 aResp->res.jsonValue["Status"]["Health"] = "OK";
98 // HTTP Code will be set up automatically, just return
99 return;
100 }
101
102 aResp->res.jsonValue["TotalCores"] = *coresCount;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200103 }
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600104 else if (property.first == "ProcessorType")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200105 {
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600106 aResp->res.jsonValue["Name"] = property.second;
107 }
108 else if (property.first == "Manufacturer")
109 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500110 const std::string* value =
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600111 std::get_if<std::string>(&property.second);
112 if (value != nullptr)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200113 {
114 aResp->res.jsonValue["Manufacturer"] = property.second;
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600115 // Otherwise would be unexpected.
116 if (value->find("Intel") != std::string::npos)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200117 {
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600118 aResp->res.jsonValue["ProcessorArchitecture"] = "x86";
119 aResp->res.jsonValue["InstructionSet"] = "x86-64";
120 }
121 else if (value->find("IBM") != std::string::npos)
122 {
123 aResp->res.jsonValue["ProcessorArchitecture"] = "Power";
124 aResp->res.jsonValue["InstructionSet"] = "PowerISA";
125 }
126 }
127 }
128 else if (property.first == "ProcessorMaxSpeed")
129 {
130 aResp->res.jsonValue["MaxSpeedMHz"] = property.second;
131 }
132 else if (property.first == "ProcessorThreadCount")
133 {
134 aResp->res.jsonValue["TotalThreads"] = property.second;
135 }
136 else if (property.first == "Model")
137 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500138 const std::string* value =
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600139 std::get_if<std::string>(&property.second);
140 if (value != nullptr)
141 {
142 aResp->res.jsonValue["Model"] = *value;
143 }
144 }
Gunnar Millsf9dcc112020-02-13 13:19:43 -0600145 else if (property.first == "PartNumber")
146 {
147 aResp->res.jsonValue["PartNumber"] = property.second;
148 }
149 else if (property.first == "SerialNumber")
150 {
151 aResp->res.jsonValue["SerialNumber"] = property.second;
152 }
153 else if (property.first == "Version")
154 {
155 aResp->res.jsonValue["Version"] = property.second;
156 }
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600157 else if (property.first == "Present")
158 {
159 present = std::get_if<bool>(&property.second);
160 }
161 else if (property.first == "Functional")
162 {
163 functional = std::get_if<bool>(&property.second);
164 }
165 }
166 }
167
168 if ((present == nullptr) || (functional == nullptr))
169 {
170 // Important property not in desired type
171 messages::internalError(aResp->res);
172 return;
173 }
174
175 if (*present == false)
176 {
177 aResp->res.jsonValue["Status"]["State"] = "Absent";
178 aResp->res.jsonValue["Status"]["Health"] = "OK";
179 }
180 else
181 {
182 aResp->res.jsonValue["Status"]["State"] = "Enabled";
183 if (*functional == true)
184 {
185 aResp->res.jsonValue["Status"]["Health"] = "OK";
186 }
187 else
188 {
189 aResp->res.jsonValue["Status"]["Health"] = "Critical";
190 }
191 }
192
193 return;
194}
195
196void getCpuDataByService(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500197 const std::string& cpuId, const std::string& service,
198 const std::string& objPath)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600199{
200 BMCWEB_LOG_DEBUG << "Get available system cpu resources by service.";
201
202 crow::connections::systemBus->async_method_call(
203 [cpuId, service, objPath, aResp{std::move(aResp)}](
204 const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500205 const dbus::utility::ManagedObjectType& dbusData) {
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600206 if (ec)
207 {
208 BMCWEB_LOG_DEBUG << "DBUS response error";
209 messages::internalError(aResp->res);
210 return;
211 }
212 aResp->res.jsonValue["Id"] = cpuId;
213 aResp->res.jsonValue["Name"] = "Processor";
214 aResp->res.jsonValue["ProcessorType"] = "CPU";
215
216 std::string corePath = objPath + "/core";
217 size_t totalCores = 0;
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500218 for (const auto& object : dbusData)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600219 {
220 if (object.first.str == objPath)
221 {
222 getCpuDataByInterface(aResp, object.second);
223 }
224 else if (boost::starts_with(object.first.str, corePath))
225 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500226 for (const auto& interface : object.second)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600227 {
228 if (interface.first ==
229 "xyz.openbmc_project.Inventory.Item")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200230 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500231 for (const auto& property : interface.second)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600232 {
233 if (property.first == "Present")
234 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500235 const bool* present =
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600236 std::get_if<bool>(&property.second);
237 if (present != nullptr)
238 {
239 if (*present == true)
240 {
241 totalCores++;
242 }
243 }
244 }
245 }
Gunnar Millsb957ba52019-01-31 15:58:15 -0600246 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200247 }
248 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200249 }
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600250 // In getCpuDataByInterface(), state and health are set
251 // based on the present and functional status. If core
252 // count is zero, then it has a higher precedence.
253 if (totalCores == 0)
254 {
255 // Slot is not populated, set status end return
256 aResp->res.jsonValue["Status"]["State"] = "Absent";
257 aResp->res.jsonValue["Status"]["Health"] = "OK";
258 }
259 aResp->res.jsonValue["TotalCores"] = totalCores;
260 return;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200261 },
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600262 service, "/xyz/openbmc_project/inventory",
263 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200264}
265
Zhikui Ren5e54a362020-07-13 15:31:38 -0700266void getCpuAssetData(std::shared_ptr<AsyncResp> aResp,
267 const std::string& service, const std::string& objPath)
268{
269 BMCWEB_LOG_DEBUG << "Get Cpu Asset Data";
270 crow::connections::systemBus->async_method_call(
271 [objPath, aResp{std::move(aResp)}](
272 const boost::system::error_code ec,
273 const boost::container::flat_map<
274 std::string, std::variant<std::string, uint32_t, uint16_t,
275 bool>>& properties) {
276 if (ec)
277 {
278 BMCWEB_LOG_DEBUG << "DBUS response error";
279 messages::internalError(aResp->res);
280 return;
281 }
282
283 for (const auto& property : properties)
284 {
285 if (property.first == "SerialNumber")
286 {
287 const std::string* sn =
288 std::get_if<std::string>(&property.second);
289 if (sn != nullptr)
290 {
291 aResp->res.jsonValue["SerialNumber"] = *sn;
292 }
293 }
294 else if (property.first == "Model")
295 {
296 const std::string* model =
297 std::get_if<std::string>(&property.second);
298 if (model != nullptr)
299 {
300 aResp->res.jsonValue["Model"] = *model;
301 }
302 }
303 }
304 },
305 service, objPath, "org.freedesktop.DBus.Properties", "GetAll",
306 "xyz.openbmc_project.Inventory.Decorator.Asset");
307}
308
Alpana Kumari32bee762019-04-25 04:47:57 -0500309void getAcceleratorDataByService(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500310 const std::string& acclrtrId,
311 const std::string& service,
312 const std::string& objPath)
Alpana Kumari32bee762019-04-25 04:47:57 -0500313{
314 BMCWEB_LOG_DEBUG
315 << "Get available system Accelerator resources by service.";
316 crow::connections::systemBus->async_method_call(
317 [acclrtrId, aResp{std::move(aResp)}](
318 const boost::system::error_code ec,
319 const boost::container::flat_map<
Santosh Puranik94e1b822019-07-24 04:48:32 -0500320 std::string, std::variant<std::string, uint32_t, uint16_t,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500321 bool>>& properties) {
Alpana Kumari32bee762019-04-25 04:47:57 -0500322 if (ec)
323 {
324 BMCWEB_LOG_DEBUG << "DBUS response error";
325 messages::internalError(aResp->res);
326 return;
327 }
328 aResp->res.jsonValue["Id"] = acclrtrId;
329 aResp->res.jsonValue["Name"] = "Processor";
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500330 const bool* accPresent = nullptr;
331 const bool* accFunctional = nullptr;
Alpana Kumari32bee762019-04-25 04:47:57 -0500332
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500333 for (const auto& property : properties)
Alpana Kumari32bee762019-04-25 04:47:57 -0500334 {
335 if (property.first == "Functional")
336 {
Santosh Puranik94e1b822019-07-24 04:48:32 -0500337 accFunctional = std::get_if<bool>(&property.second);
Alpana Kumari32bee762019-04-25 04:47:57 -0500338 }
339 else if (property.first == "Present")
340 {
Santosh Puranik94e1b822019-07-24 04:48:32 -0500341 accPresent = std::get_if<bool>(&property.second);
Alpana Kumari32bee762019-04-25 04:47:57 -0500342 }
343 }
344
Alpana Kumari657877c2020-02-24 02:24:07 -0600345 if ((accPresent != nullptr) && (*accPresent == false))
Alpana Kumari32bee762019-04-25 04:47:57 -0500346 {
Alpana Kumari657877c2020-02-24 02:24:07 -0600347 aResp->res.jsonValue["Status"]["State"] = "Absent";
348 aResp->res.jsonValue["Status"]["Health"] = "OK";
Alpana Kumari32bee762019-04-25 04:47:57 -0500349 }
350 else
351 {
Alpana Kumari657877c2020-02-24 02:24:07 -0600352 aResp->res.jsonValue["Status"]["State"] = "Enabled";
353
354 if ((accFunctional != nullptr) && (*accFunctional == false))
355 {
356 aResp->res.jsonValue["Status"]["Health"] = "Critical";
357 }
358 else
359 {
360 aResp->res.jsonValue["Status"]["Health"] = "OK";
361 }
Alpana Kumari32bee762019-04-25 04:47:57 -0500362 }
Alpana Kumari32bee762019-04-25 04:47:57 -0500363 aResp->res.jsonValue["ProcessorType"] = "Accelerator";
364 },
365 service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
366}
367
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500368void getCpuData(std::shared_ptr<AsyncResp> aResp, const std::string& cpuId,
369 const std::vector<const char*> inventoryItems)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200370{
371 BMCWEB_LOG_DEBUG << "Get available system cpu resources.";
Alpana Kumari32bee762019-04-25 04:47:57 -0500372
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200373 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -0800374 [cpuId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200375 const boost::system::error_code ec,
376 const boost::container::flat_map<
377 std::string, boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500378 std::string, std::vector<std::string>>>&
379 subtree) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200380 if (ec)
381 {
382 BMCWEB_LOG_DEBUG << "DBUS response error";
383 messages::internalError(aResp->res);
384 return;
385 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500386 for (const auto& object : subtree)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200387 {
388 if (boost::ends_with(object.first, cpuId))
389 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500390 for (const auto& service : object.second)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200391 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500392 for (const auto& inventory : service.second)
Zhikui Ren5e54a362020-07-13 15:31:38 -0700393 {
394 if (inventory == "xyz.openbmc_project."
395 "Inventory.Decorator.Asset")
396 {
397 getCpuAssetData(aResp, service.first,
398 object.first);
399 }
400 else if (inventory ==
401 "xyz.openbmc_project.Inventory.Item.Cpu")
Alpana Kumari32bee762019-04-25 04:47:57 -0500402 {
403 getCpuDataByService(aResp, cpuId, service.first,
404 object.first);
405 }
406 else if (inventory == "xyz.openbmc_project."
407 "Inventory.Item.Accelerator")
408 {
409 getAcceleratorDataByService(
410 aResp, cpuId, service.first, object.first);
411 }
Zhikui Ren5e54a362020-07-13 15:31:38 -0700412 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200413 }
Zhikui Ren5e54a362020-07-13 15:31:38 -0700414 return;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200415 }
416 }
417 // Object not found
418 messages::resourceNotFound(aResp->res, "Processor", cpuId);
419 return;
420 },
421 "xyz.openbmc_project.ObjectMapper",
422 "/xyz/openbmc_project/object_mapper",
423 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -0700424 "/xyz/openbmc_project/inventory", 0, inventoryItems);
425}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200426
James Feistc50e7c62020-07-27 15:39:36 -0700427using DimmProperty =
428 std::variant<std::string, std::vector<uint32_t>, std::vector<uint16_t>,
429 uint64_t, uint32_t, uint16_t, uint8_t, bool>;
430
431using DimmProperties = boost::container::flat_map<std::string, DimmProperty>;
432
433void dimmPropToHex(std::shared_ptr<AsyncResp> aResp, const char* key,
434 const std::pair<std::string, DimmProperty>& property)
435{
436 const uint16_t* value = std::get_if<uint16_t>(&property.second);
437 if (value == nullptr)
438 {
439 messages::internalError(aResp->res);
440 BMCWEB_LOG_DEBUG << "Invalid property type for " << property.first;
441 return;
442 }
443
444 aResp->res.jsonValue[key] = (boost::format("0x%04x") % *value).str();
445}
446
447void getPersistentMemoryProperties(std::shared_ptr<AsyncResp> aResp,
448 const DimmProperties& properties)
449{
450 for (const auto& property : properties)
451 {
452 if (property.first == "ModuleManufacturerID")
453 {
454 dimmPropToHex(aResp, "ModuleManufacturerID", property);
455 }
456 else if (property.first == "ModuleProductID")
457 {
458 dimmPropToHex(aResp, "ModuleProductID", property);
459 }
460 else if (property.first == "SubsystemVendorID")
461 {
462 dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID",
463 property);
464 }
465 else if (property.first == "SubsystemDeviceID")
466 {
467 dimmPropToHex(aResp, "MemorySubsystemControllerProductID",
468 property);
469 }
470 else if (property.first == "VolatileRegionSizeLimitInKiB")
471 {
472 const uint64_t* value = std::get_if<uint64_t>(&property.second);
473
474 if (value == nullptr)
475 {
476 messages::internalError(aResp->res);
477 BMCWEB_LOG_DEBUG << "Invalid property type for "
478 "VolatileRegionSizeLimitKiB";
479 continue;
480 }
481 aResp->res.jsonValue["VolatileRegionSizeLimitMiB"] = (*value) >> 10;
482 }
483 else if (property.first == "PmRegionSizeLimitInKiB")
484 {
485 const uint64_t* value = std::get_if<uint64_t>(&property.second);
486
487 if (value == nullptr)
488 {
489 messages::internalError(aResp->res);
490 BMCWEB_LOG_DEBUG
491 << "Invalid property type for PmRegioSizeLimitKiB";
492 continue;
493 }
494 aResp->res.jsonValue["PersistentRegionSizeLimitMiB"] =
495 (*value) >> 10;
496 }
497 else if (property.first == "VolatileSizeInKiB")
498 {
499 const uint64_t* value = std::get_if<uint64_t>(&property.second);
500
501 if (value == nullptr)
502 {
503 messages::internalError(aResp->res);
504 BMCWEB_LOG_DEBUG
505 << "Invalid property type for VolatileSizeInKiB";
506 continue;
507 }
508 aResp->res.jsonValue["VolatileSizeMiB"] = (*value) >> 10;
509 }
510 else if (property.first == "PmSizeInKiB")
511 {
512 const uint64_t* value = std::get_if<uint64_t>(&property.second);
513 if (value == nullptr)
514 {
515 messages::internalError(aResp->res);
516 BMCWEB_LOG_DEBUG << "Invalid property type for PmSizeInKiB";
517 continue;
518 }
519 aResp->res.jsonValue["NonVolatileSizeMiB"] = (*value) >> 10;
520 }
521 else if (property.first == "CacheSizeInKB")
522 {
523 const uint64_t* value = std::get_if<uint64_t>(&property.second);
524 if (value == nullptr)
525 {
526 messages::internalError(aResp->res);
527 BMCWEB_LOG_DEBUG << "Invalid property type for CacheSizeInKB";
528 continue;
529 }
530 aResp->res.jsonValue["CacheSizeMiB"] = (*value >> 10);
531 }
532
533 else if (property.first == "VoltaileRegionMaxSizeInKib")
534 {
535 const uint64_t* value = std::get_if<uint64_t>(&property.second);
536
537 if (value == nullptr)
538 {
539 messages::internalError(aResp->res);
540 BMCWEB_LOG_DEBUG << "Invalid property type for "
541 "VolatileRegionMaxSizeInKib";
542 continue;
543 }
544 aResp->res.jsonValue["VolatileRegionSizeMaxMiB"] = (*value) >> 10;
545 }
546 else if (property.first == "PmRegionMaxSizeInKiB")
547 {
548 const uint64_t* value = std::get_if<uint64_t>(&property.second);
549
550 if (value == nullptr)
551 {
552 messages::internalError(aResp->res);
553 BMCWEB_LOG_DEBUG
554 << "Invalid property type for PmRegionMaxSizeInKiB";
555 continue;
556 }
557 aResp->res.jsonValue["PersistentRegionSizeMaxMiB"] = (*value) >> 10;
558 }
559 else if (property.first == "AllocationIncrementInKiB")
560 {
561 const uint64_t* value = std::get_if<uint64_t>(&property.second);
562
563 if (value == nullptr)
564 {
565 messages::internalError(aResp->res);
566 BMCWEB_LOG_DEBUG << "Invalid property type for "
567 "AllocationIncrementInKiB";
568 continue;
569 }
570 aResp->res.jsonValue["AllocationIncrementMiB"] = (*value) >> 10;
571 }
572 else if (property.first == "AllocationAlignmentInKiB")
573 {
574 const uint64_t* value = std::get_if<uint64_t>(&property.second);
575
576 if (value == nullptr)
577 {
578 messages::internalError(aResp->res);
579 BMCWEB_LOG_DEBUG << "Invalid property type for "
580 "AllocationAlignmentInKiB";
581 continue;
582 }
583 aResp->res.jsonValue["AllocationAlignmentMiB"] = (*value) >> 10;
584 }
585 else if (property.first == "VolatileRegionNumberLimit")
586 {
587 aResp->res.jsonValue["VolatileRegionNumberLimit"] = property.second;
588 }
589 else if (property.first == "PmRegionNumberLimit")
590 {
591 aResp->res.jsonValue["PersistentRegionNumberLimit"] =
592 property.second;
593 }
594 else if (property.first == "SpareDeviceCount")
595 {
596 aResp->res.jsonValue["SpareDeviceCount"] = property.second;
597 }
598 else if (property.first == "IsSpareDeviceInUse")
599 {
600 aResp->res.jsonValue["IsSpareDeviceEnabled"] = property.second;
601 }
602 else if (property.first == "IsRankSpareEnabled")
603 {
604 aResp->res.jsonValue["IsRankSpareEnabled"] = property.second;
605 }
606 else if (property.first == "MaxAveragePowerLimitmW")
607 {
608 const auto* value =
609 std::get_if<std::vector<uint32_t>>(&property.second);
610 if (value == nullptr)
611 {
612 messages::internalError(aResp->res);
613 BMCWEB_LOG_DEBUG << "Invalid property type for "
614 "MaxAveragePowerLimitmW";
615 continue;
616 }
617 aResp->res.jsonValue["MaxTDPMilliWatts"] = *value;
618 }
619 else if (property.first == "CurrentSecurityState")
620 {
621 aResp->res.jsonValue["SecurityState"] = property.second;
622 }
623 else if (property.first == "ConfigurationLocked")
624 {
625 aResp->res.jsonValue["ConfigurationLocked"] = property.second;
626 }
627 else if (property.first == "AllowedMemoryModes")
628 {
629 const std::string* value =
630 std::get_if<std::string>(&property.second);
631 if (value == nullptr)
632 {
633 messages::internalError(aResp->res);
634 BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor";
635 continue;
636 }
637 constexpr const std::array<const char*, 3> values{"Volatile",
638 "PMEM", "Block"};
639
640 for (const char* v : values)
641 {
642 if (boost::ends_with(*value, v))
643 {
644 aResp->res.jsonValue["OperatingMemoryModes "] = v;
645 break;
646 }
647 }
648 }
649 else if (property.first == "MemoryMedia")
650 {
651 const std::string* value =
652 std::get_if<std::string>(&property.second);
653 if (value == nullptr)
654 {
655 messages::internalError(aResp->res);
656 BMCWEB_LOG_DEBUG << "Invalid property type for MemoryMedia";
657 continue;
658 }
659 constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
660 "Intel3DXPoint"};
661
662 for (const char* v : values)
663 {
664 if (boost::ends_with(*value, v))
665 {
666 aResp->res.jsonValue["MemoryMedia"] = v;
667 break;
668 }
669 }
670 }
671 // PersistantMemory.PowerManagmentPolicy interface
672 else if (property.first == "AveragePowerBudgetmW" ||
673 property.first == "MaxTDPmW" ||
674 property.first == "PeakPowerBudgetmW" ||
675 property.first == "PolicyEnabled")
676 {
677 std::string name =
678 boost::replace_all_copy(property.first, "mW", "MilliWatts");
679 aResp->res.jsonValue["PowerManagementPolicy"][name] =
680 property.second;
681 }
682 // PersistantMemory.SecurityCapabilites interface
683 else if (property.first == "ConfigurationLockCapable" ||
684 property.first == "DataLockCapable" ||
685 property.first == "MaxPassphraseCount" ||
686 property.first == "PassphraseCapable" ||
687 property.first == "PassphraseLockLimit")
688 {
689 aResp->res.jsonValue["SecurityCapabilities"][property.first] =
690 property.second;
691 }
692 }
693}
694
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200695void getDimmDataByService(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500696 const std::string& dimmId, const std::string& service,
697 const std::string& objPath)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200698{
James Feist35e257a2020-06-05 13:30:51 -0700699 auto health = std::make_shared<HealthPopulate>(aResp);
700 health->selfPath = objPath;
701 health->populate();
702
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200703 BMCWEB_LOG_DEBUG << "Get available system components.";
704 crow::connections::systemBus->async_method_call(
James Feistc50e7c62020-07-27 15:39:36 -0700705 [dimmId, aResp{std::move(aResp)}](const boost::system::error_code ec,
706 const DimmProperties& properties) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200707 if (ec)
708 {
709 BMCWEB_LOG_DEBUG << "DBUS response error";
710 messages::internalError(aResp->res);
711
712 return;
713 }
714 aResp->res.jsonValue["Id"] = dimmId;
715 aResp->res.jsonValue["Name"] = "DIMM Slot";
716
717 const auto memorySizeProperty = properties.find("MemorySizeInKB");
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600718 if (memorySizeProperty != properties.end())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200719 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500720 const uint32_t* memorySize =
Ed Tanousabf2add2019-01-22 16:40:12 -0800721 std::get_if<uint32_t>(&memorySizeProperty->second);
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600722 if (memorySize == nullptr)
723 {
724 // Important property not in desired type
725 messages::internalError(aResp->res);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200726
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600727 return;
728 }
729 if (*memorySize == 0)
730 {
731 // Slot is not populated, set status end return
732 aResp->res.jsonValue["Status"]["State"] = "Absent";
733 aResp->res.jsonValue["Status"]["Health"] = "OK";
734 // HTTP Code will be set up automatically, just return
735 return;
736 }
737 aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200738 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200739 aResp->res.jsonValue["Status"]["State"] = "Enabled";
740 aResp->res.jsonValue["Status"]["Health"] = "OK";
741
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500742 for (const auto& property : properties)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200743 {
744 if (property.first == "MemoryDataWidth")
745 {
746 aResp->res.jsonValue["DataWidthBits"] = property.second;
747 }
Manojkiran Eda7e236ca2019-06-25 23:06:32 +0530748 else if (property.first == "PartNumber")
749 {
750 aResp->res.jsonValue["PartNumber"] = property.second;
751 }
752 else if (property.first == "SerialNumber")
753 {
754 aResp->res.jsonValue["SerialNumber"] = property.second;
755 }
756 else if (property.first == "Manufacturer")
757 {
758 aResp->res.jsonValue["Manufacturer"] = property.second;
759 }
James Feistc50e7c62020-07-27 15:39:36 -0700760 else if (property.first == "RevisionCode")
761 {
762 const uint16_t* value =
763 std::get_if<uint16_t>(&property.second);
764
765 if (value == nullptr)
766 {
767 messages::internalError(aResp->res);
768 BMCWEB_LOG_DEBUG
769 << "Invalid property type for RevisionCode";
770 continue;
771 }
772 aResp->res.jsonValue["FirmwareRevision"] =
773 std::to_string(*value);
774 }
775 else if (property.first == "MemoryTotalWidth")
776 {
777 aResp->res.jsonValue["BusWidthBits"] = property.second;
778 }
779 else if (property.first == "ECC")
780 {
781 const std::string* value =
782 std::get_if<std::string>(&property.second);
783 if (value == nullptr)
784 {
785 messages::internalError(aResp->res);
786 BMCWEB_LOG_DEBUG << "Invalid property type for ECC";
787 continue;
788 }
789 constexpr const std::array<const char*, 4> values{
790 "NoECC", "SingleBitECC", "MultiBitECC",
791 "AddressParity"};
792
793 for (const char* v : values)
794 {
795 if (boost::ends_with(*value, v))
796 {
797 aResp->res.jsonValue["ErrorCorrection"] = v;
798 break;
799 }
800 }
801 }
802 else if (property.first == "FormFactor")
803 {
804 const std::string* value =
805 std::get_if<std::string>(&property.second);
806 if (value == nullptr)
807 {
808 messages::internalError(aResp->res);
809 BMCWEB_LOG_DEBUG
810 << "Invalid property type for FormFactor";
811 continue;
812 }
813 constexpr const std::array<const char*, 11> values{
814 "RDIMM", "UDIMM", "SO_DIMM",
815 "LRDIMM", "Mini_RDIMM", "Mini_UDIMM",
816 "SO_RDIMM_72b", "SO_UDIMM_72b", "SO_DIMM_16b",
817 "SO_DIMM_32b", "Die"};
818
819 for (const char* v : values)
820 {
821 if (boost::ends_with(*value, v))
822 {
823 aResp->res.jsonValue["BaseModuleType"] = v;
824 break;
825 }
826 }
827 }
828 else if (property.first == "AllowedSpeedsMT")
829 {
830 aResp->res.jsonValue["AllowedSpeedsMHz"] = property.second;
831 }
832 else if (property.first == "MemoryAttributes")
833 {
834 const uint8_t* value =
835 std::get_if<uint8_t>(&property.second);
836
837 if (value == nullptr)
838 {
839 messages::internalError(aResp->res);
840 BMCWEB_LOG_DEBUG
841 << "Invalid property type for MemoryAttributes";
842 continue;
843 }
844 aResp->res.jsonValue["RankCount"] =
845 static_cast<uint64_t>(*value);
846 }
847 else if (property.first == "MemoryConfiguredSpeedInMhz")
848 {
849 aResp->res.jsonValue["OperatingSpeedMhz"] = property.second;
850 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200851 else if (property.first == "MemoryType")
852 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500853 const auto* value =
Ed Tanousabf2add2019-01-22 16:40:12 -0800854 std::get_if<std::string>(&property.second);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200855 if (value != nullptr)
856 {
James Feistc50e7c62020-07-27 15:39:36 -0700857 size_t idx = value->rfind(".");
858 if (idx == std::string::npos ||
859 idx + 1 >= value->size())
860 {
861 messages::internalError(aResp->res);
862 BMCWEB_LOG_DEBUG << "Invalid property type for "
863 "MemoryType";
864 }
865 std::string result = value->substr(idx + 1);
866 aResp->res.jsonValue["MemoryDeviceType"] = result;
867 if (value->find("DDR") != std::string::npos)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200868 {
869 aResp->res.jsonValue["MemoryType"] = "DRAM";
870 }
James Feistc50e7c62020-07-27 15:39:36 -0700871 else if (boost::ends_with(*value, "Logical"))
872 {
873 aResp->res.jsonValue["MemoryType"] = "IntelOptane";
874 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200875 }
876 }
James Feistc50e7c62020-07-27 15:39:36 -0700877 // memory location interface
878 else if (property.first == "Channel" ||
879 property.first == "MemoryController" ||
880 property.first == "Slot" || property.first == "Socket")
881 {
882 aResp->res.jsonValue["MemoryLocation"][property.first] =
883 property.second;
884 }
885 else
886 {
887 getPersistentMemoryProperties(aResp, properties);
888 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200889 }
890 },
891 service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
892}
893
James Feist45094ad2020-04-29 14:02:30 -0700894void getDimmPartitionData(std::shared_ptr<AsyncResp> aResp,
895 const std::string& service, const std::string& path)
896{
897 crow::connections::systemBus->async_method_call(
898 [aResp{std::move(aResp)}](
899 const boost::system::error_code ec,
900 const boost::container::flat_map<
901 std::string, std::variant<std::string, uint64_t, uint32_t,
902 bool>>& properties) {
903 if (ec)
904 {
905 BMCWEB_LOG_DEBUG << "DBUS response error";
906 messages::internalError(aResp->res);
907
908 return;
909 }
910
911 nlohmann::json& partition =
912 aResp->res.jsonValue["Regions"].emplace_back(
913 nlohmann::json::object());
914 for (const auto& [key, val] : properties)
915 {
916 if (key == "MemoryClassification")
917 {
918 partition[key] = val;
919 }
920 else if (key == "OffsetInKiB")
921 {
922 const uint64_t* value = std::get_if<uint64_t>(&val);
923 if (value == nullptr)
924 {
925 messages::internalError(aResp->res);
926 BMCWEB_LOG_DEBUG
927 << "Invalid property type for OffsetInKiB";
928 continue;
929 }
930
931 partition["OffsetMiB"] = (*value >> 10);
932 }
933 else if (key == "PartitionId")
934 {
935 partition["RegionId"] = val;
936 }
937
938 else if (key == "PassphraseState")
939 {
940 partition["PassphraseEnabled"] = val;
941 }
942 else if (key == "SizeInKiB")
943 {
944 const uint64_t* value = std::get_if<uint64_t>(&val);
945 if (value == nullptr)
946 {
947 messages::internalError(aResp->res);
948 BMCWEB_LOG_DEBUG
949 << "Invalid property type for SizeInKiB";
950 continue;
951 }
952 partition["SizeMiB"] = (*value >> 10);
953 }
954 }
955 },
956
957 service, path, "org.freedesktop.DBus.Properties", "GetAll",
958 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition");
959}
960
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500961void getDimmData(std::shared_ptr<AsyncResp> aResp, const std::string& dimmId)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200962{
963 BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
964 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -0800965 [dimmId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200966 const boost::system::error_code ec,
967 const boost::container::flat_map<
968 std::string, boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500969 std::string, std::vector<std::string>>>&
970 subtree) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200971 if (ec)
972 {
973 BMCWEB_LOG_DEBUG << "DBUS response error";
974 messages::internalError(aResp->res);
975
976 return;
977 }
James Feist45094ad2020-04-29 14:02:30 -0700978 bool found = false;
979 for (const auto& [path, object] : subtree)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200980 {
James Feist45094ad2020-04-29 14:02:30 -0700981 if (path.find(dimmId) != std::string::npos)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200982 {
James Feist45094ad2020-04-29 14:02:30 -0700983 for (const auto& [service, interfaces] : object)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200984 {
James Feist45094ad2020-04-29 14:02:30 -0700985 if (!found &&
986 (std::find(
987 interfaces.begin(), interfaces.end(),
988 "xyz.openbmc_project.Inventory.Item.Dimm") !=
989 interfaces.end()))
990 {
991 getDimmDataByService(aResp, dimmId, service, path);
992 found = true;
993 }
994
995 // partitions are separate as there can be multiple per
996 // device, i.e.
997 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
998 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
999 if (std::find(interfaces.begin(), interfaces.end(),
1000 "xyz.openbmc_project.Inventory.Item."
1001 "PersistentMemory.Partition") !=
1002 interfaces.end())
1003 {
1004 getDimmPartitionData(aResp, service, path);
1005 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001006 }
1007 }
1008 }
1009 // Object not found
James Feist45094ad2020-04-29 14:02:30 -07001010 if (!found)
1011 {
1012 messages::resourceNotFound(aResp->res, "Memory", dimmId);
1013 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001014 return;
1015 },
1016 "xyz.openbmc_project.ObjectMapper",
1017 "/xyz/openbmc_project/object_mapper",
1018 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -07001019 "/xyz/openbmc_project/inventory", 0,
James Feist45094ad2020-04-29 14:02:30 -07001020 std::array<const char*, 2>{
1021 "xyz.openbmc_project.Inventory.Item.Dimm",
1022 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"});
Ed Tanous271584a2019-07-09 16:24:22 -07001023}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001024
1025class ProcessorCollection : public Node
1026{
1027 public:
1028 /*
1029 * Default Constructor
1030 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001031 ProcessorCollection(CrowApp& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001032 Node(app, "/redfish/v1/Systems/system/Processors/")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001033 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001034 entityPrivileges = {
1035 {boost::beast::http::verb::get, {{"Login"}}},
1036 {boost::beast::http::verb::head, {{"Login"}}},
1037 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1038 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1039 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1040 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1041 }
1042
1043 private:
1044 /**
1045 * Functions triggers appropriate requests on DBus
1046 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001047 void doGet(crow::Response& res, const crow::Request& req,
1048 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001049 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001050 res.jsonValue["@odata.type"] =
1051 "#ProcessorCollection.ProcessorCollection";
1052 res.jsonValue["Name"] = "Processor Collection";
Ed Tanous0f74e642018-11-12 15:17:05 -08001053
Ed Tanous029573d2019-02-01 10:57:49 -08001054 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Processors/";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001055 auto asyncResp = std::make_shared<AsyncResp>(res);
1056
Ed Tanous029573d2019-02-01 10:57:49 -08001057 getResourceList(asyncResp, "Processors",
Alpana Kumari32bee762019-04-25 04:47:57 -05001058 {"xyz.openbmc_project.Inventory.Item.Cpu",
1059 "xyz.openbmc_project.Inventory.Item.Accelerator"});
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001060 }
1061};
1062
1063class Processor : public Node
1064{
1065 public:
1066 /*
1067 * Default Constructor
1068 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001069 Processor(CrowApp& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001070 Node(app, "/redfish/v1/Systems/system/Processors/<str>/", std::string())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001071 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001072 entityPrivileges = {
1073 {boost::beast::http::verb::get, {{"Login"}}},
1074 {boost::beast::http::verb::head, {{"Login"}}},
1075 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1076 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1077 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1078 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1079 }
1080
1081 private:
1082 /**
1083 * Functions triggers appropriate requests on DBus
1084 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001085 void doGet(crow::Response& res, const crow::Request& req,
1086 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001087 {
1088 // Check if there is required param, truly entering this shall be
1089 // impossible
1090 if (params.size() != 1)
1091 {
1092 messages::internalError(res);
1093
1094 res.end();
1095 return;
1096 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001097 const std::string& processorId = params[0];
Gunnar Millsf9dcc112020-02-13 13:19:43 -06001098 res.jsonValue["@odata.type"] = "#Processor.v1_7_0.Processor";
Ed Tanous029573d2019-02-01 10:57:49 -08001099 res.jsonValue["@odata.id"] =
Alpana Kumari32bee762019-04-25 04:47:57 -05001100 "/redfish/v1/Systems/system/Processors/" + processorId;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001101
Ed Tanous029573d2019-02-01 10:57:49 -08001102 auto asyncResp = std::make_shared<AsyncResp>(res);
1103
Alpana Kumari32bee762019-04-25 04:47:57 -05001104 getCpuData(asyncResp, processorId,
1105 {"xyz.openbmc_project.Inventory.Item.Cpu",
Zhikui Ren5e54a362020-07-13 15:31:38 -07001106 "xyz.openbmc_project.Inventory.Decorator.Asset",
Alpana Kumari32bee762019-04-25 04:47:57 -05001107 "xyz.openbmc_project.Inventory.Item.Accelerator"});
Ed Tanous029573d2019-02-01 10:57:49 -08001108 }
1109};
1110
1111class MemoryCollection : public Node
1112{
1113 public:
1114 /*
1115 * Default Constructor
1116 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001117 MemoryCollection(CrowApp& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001118 Node(app, "/redfish/v1/Systems/system/Memory/")
1119 {
1120 entityPrivileges = {
1121 {boost::beast::http::verb::get, {{"Login"}}},
1122 {boost::beast::http::verb::head, {{"Login"}}},
1123 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1124 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1125 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1126 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1127 }
1128
1129 private:
1130 /**
1131 * Functions triggers appropriate requests on DBus
1132 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001133 void doGet(crow::Response& res, const crow::Request& req,
1134 const std::vector<std::string>& params) override
Ed Tanous029573d2019-02-01 10:57:49 -08001135 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001136 res.jsonValue["@odata.type"] = "#MemoryCollection.MemoryCollection";
1137 res.jsonValue["Name"] = "Memory Module Collection";
James Feistc50e7c62020-07-27 15:39:36 -07001138 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Memory";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001139 auto asyncResp = std::make_shared<AsyncResp>(res);
1140
Ed Tanous029573d2019-02-01 10:57:49 -08001141 getResourceList(asyncResp, "Memory",
Alpana Kumari32bee762019-04-25 04:47:57 -05001142 {"xyz.openbmc_project.Inventory.Item.Dimm"});
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001143 }
1144};
1145
1146class Memory : public Node
1147{
1148 public:
1149 /*
1150 * Default Constructor
1151 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001152 Memory(CrowApp& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001153 Node(app, "/redfish/v1/Systems/system/Memory/<str>/", std::string())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001154 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001155 entityPrivileges = {
1156 {boost::beast::http::verb::get, {{"Login"}}},
1157 {boost::beast::http::verb::head, {{"Login"}}},
1158 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1159 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1160 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1161 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1162 }
1163
1164 private:
1165 /**
1166 * Functions triggers appropriate requests on DBus
1167 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001168 void doGet(crow::Response& res, const crow::Request& req,
1169 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001170 {
1171 // Check if there is required param, truly entering this shall be
1172 // impossible
Ed Tanous029573d2019-02-01 10:57:49 -08001173 if (params.size() != 1)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001174 {
1175 messages::internalError(res);
1176 res.end();
1177 return;
1178 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001179 const std::string& dimmId = params[0];
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001180
James Feistc50e7c62020-07-27 15:39:36 -07001181 res.jsonValue["@odata.type"] = "#Memory.v1_7_0.Memory";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001182 res.jsonValue["@odata.id"] =
Ed Tanous029573d2019-02-01 10:57:49 -08001183 "/redfish/v1/Systems/system/Memory/" + dimmId;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001184 auto asyncResp = std::make_shared<AsyncResp>(res);
1185
Ed Tanous029573d2019-02-01 10:57:49 -08001186 getDimmData(asyncResp, dimmId);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001187 }
1188};
1189
1190} // namespace redfish