blob: 7b5ca4359ca6bfea784118e0d0c8703a24ec7277 [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 Tanous23a21a12020-07-25 04:45:05 +000032inline void getResourceList(std::shared_ptr<AsyncResp> aResp,
33 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
Ed Tanous23a21a12020-07-25 04:45:05 +000072inline void
73 getCpuDataByInterface(std::shared_ptr<AsyncResp> aResp,
74 const InterfacesProperties& cpuInterfacesProperties)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020075{
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060076 BMCWEB_LOG_DEBUG << "Get CPU resources by interface.";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020077
Gunnar Mills1214b7e2020-06-04 10:11:30 -050078 const bool* present = nullptr;
79 const bool* functional = nullptr;
80 for (const auto& interface : cpuInterfacesProperties)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060081 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050082 for (const auto& property : interface.second)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060083 {
84 if (property.first == "ProcessorCoreCount")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020085 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050086 const uint16_t* coresCount =
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060087 std::get_if<uint16_t>(&property.second);
Ed Tanous883b3112018-12-06 16:13:35 -080088 if (coresCount == nullptr)
89 {
90 // Important property not in desired type
91 messages::internalError(aResp->res);
92 return;
93 }
94 if (*coresCount == 0)
95 {
96 // Slot is not populated, set status end return
97 aResp->res.jsonValue["Status"]["State"] = "Absent";
98 aResp->res.jsonValue["Status"]["Health"] = "OK";
99 // HTTP Code will be set up automatically, just return
100 return;
101 }
102
103 aResp->res.jsonValue["TotalCores"] = *coresCount;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200104 }
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600105 else if (property.first == "ProcessorType")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200106 {
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600107 aResp->res.jsonValue["Name"] = property.second;
108 }
109 else if (property.first == "Manufacturer")
110 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500111 const std::string* value =
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600112 std::get_if<std::string>(&property.second);
113 if (value != nullptr)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200114 {
115 aResp->res.jsonValue["Manufacturer"] = property.second;
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600116 // Otherwise would be unexpected.
117 if (value->find("Intel") != std::string::npos)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200118 {
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600119 aResp->res.jsonValue["ProcessorArchitecture"] = "x86";
120 aResp->res.jsonValue["InstructionSet"] = "x86-64";
121 }
122 else if (value->find("IBM") != std::string::npos)
123 {
124 aResp->res.jsonValue["ProcessorArchitecture"] = "Power";
125 aResp->res.jsonValue["InstructionSet"] = "PowerISA";
126 }
127 }
128 }
129 else if (property.first == "ProcessorMaxSpeed")
130 {
131 aResp->res.jsonValue["MaxSpeedMHz"] = property.second;
132 }
133 else if (property.first == "ProcessorThreadCount")
134 {
135 aResp->res.jsonValue["TotalThreads"] = property.second;
136 }
137 else if (property.first == "Model")
138 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500139 const std::string* value =
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600140 std::get_if<std::string>(&property.second);
141 if (value != nullptr)
142 {
143 aResp->res.jsonValue["Model"] = *value;
144 }
145 }
Gunnar Millsf9dcc112020-02-13 13:19:43 -0600146 else if (property.first == "PartNumber")
147 {
148 aResp->res.jsonValue["PartNumber"] = property.second;
149 }
150 else if (property.first == "SerialNumber")
151 {
152 aResp->res.jsonValue["SerialNumber"] = property.second;
153 }
154 else if (property.first == "Version")
155 {
156 aResp->res.jsonValue["Version"] = property.second;
157 }
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600158 else if (property.first == "Present")
159 {
160 present = std::get_if<bool>(&property.second);
161 }
162 else if (property.first == "Functional")
163 {
164 functional = std::get_if<bool>(&property.second);
165 }
166 }
167 }
168
169 if ((present == nullptr) || (functional == nullptr))
170 {
171 // Important property not in desired type
172 messages::internalError(aResp->res);
173 return;
174 }
175
176 if (*present == false)
177 {
178 aResp->res.jsonValue["Status"]["State"] = "Absent";
179 aResp->res.jsonValue["Status"]["Health"] = "OK";
180 }
181 else
182 {
183 aResp->res.jsonValue["Status"]["State"] = "Enabled";
184 if (*functional == true)
185 {
186 aResp->res.jsonValue["Status"]["Health"] = "OK";
187 }
188 else
189 {
190 aResp->res.jsonValue["Status"]["Health"] = "Critical";
191 }
192 }
193
194 return;
195}
196
Ed Tanous23a21a12020-07-25 04:45:05 +0000197inline void getCpuDataByService(std::shared_ptr<AsyncResp> aResp,
198 const std::string& cpuId,
199 const std::string& service,
200 const std::string& objPath)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600201{
202 BMCWEB_LOG_DEBUG << "Get available system cpu resources by service.";
203
204 crow::connections::systemBus->async_method_call(
205 [cpuId, service, objPath, aResp{std::move(aResp)}](
206 const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500207 const dbus::utility::ManagedObjectType& dbusData) {
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600208 if (ec)
209 {
210 BMCWEB_LOG_DEBUG << "DBUS response error";
211 messages::internalError(aResp->res);
212 return;
213 }
214 aResp->res.jsonValue["Id"] = cpuId;
215 aResp->res.jsonValue["Name"] = "Processor";
216 aResp->res.jsonValue["ProcessorType"] = "CPU";
217
218 std::string corePath = objPath + "/core";
219 size_t totalCores = 0;
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500220 for (const auto& object : dbusData)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600221 {
222 if (object.first.str == objPath)
223 {
224 getCpuDataByInterface(aResp, object.second);
225 }
226 else if (boost::starts_with(object.first.str, corePath))
227 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500228 for (const auto& interface : object.second)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600229 {
230 if (interface.first ==
231 "xyz.openbmc_project.Inventory.Item")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200232 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500233 for (const auto& property : interface.second)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600234 {
235 if (property.first == "Present")
236 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500237 const bool* present =
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600238 std::get_if<bool>(&property.second);
239 if (present != nullptr)
240 {
241 if (*present == true)
242 {
243 totalCores++;
244 }
245 }
246 }
247 }
Gunnar Millsb957ba52019-01-31 15:58:15 -0600248 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200249 }
250 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200251 }
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600252 // In getCpuDataByInterface(), state and health are set
253 // based on the present and functional status. If core
254 // count is zero, then it has a higher precedence.
255 if (totalCores == 0)
256 {
257 // Slot is not populated, set status end return
258 aResp->res.jsonValue["Status"]["State"] = "Absent";
259 aResp->res.jsonValue["Status"]["Health"] = "OK";
260 }
261 aResp->res.jsonValue["TotalCores"] = totalCores;
262 return;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200263 },
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600264 service, "/xyz/openbmc_project/inventory",
265 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200266}
267
Ed Tanous23a21a12020-07-25 04:45:05 +0000268inline void getCpuAssetData(std::shared_ptr<AsyncResp> aResp,
269 const std::string& service,
270 const std::string& objPath)
Zhikui Ren5e54a362020-07-13 15:31:38 -0700271{
272 BMCWEB_LOG_DEBUG << "Get Cpu Asset Data";
273 crow::connections::systemBus->async_method_call(
274 [objPath, aResp{std::move(aResp)}](
275 const boost::system::error_code ec,
276 const boost::container::flat_map<
277 std::string, std::variant<std::string, uint32_t, uint16_t,
278 bool>>& properties) {
279 if (ec)
280 {
281 BMCWEB_LOG_DEBUG << "DBUS response error";
282 messages::internalError(aResp->res);
283 return;
284 }
285
286 for (const auto& property : properties)
287 {
288 if (property.first == "SerialNumber")
289 {
290 const std::string* sn =
291 std::get_if<std::string>(&property.second);
292 if (sn != nullptr)
293 {
294 aResp->res.jsonValue["SerialNumber"] = *sn;
295 }
296 }
297 else if (property.first == "Model")
298 {
299 const std::string* model =
300 std::get_if<std::string>(&property.second);
301 if (model != nullptr)
302 {
303 aResp->res.jsonValue["Model"] = *model;
304 }
305 }
306 }
307 },
308 service, objPath, "org.freedesktop.DBus.Properties", "GetAll",
309 "xyz.openbmc_project.Inventory.Decorator.Asset");
310}
311
Ed Tanous23a21a12020-07-25 04:45:05 +0000312inline void getAcceleratorDataByService(std::shared_ptr<AsyncResp> aResp,
313 const std::string& acclrtrId,
314 const std::string& service,
315 const std::string& objPath)
Alpana Kumari32bee762019-04-25 04:47:57 -0500316{
317 BMCWEB_LOG_DEBUG
318 << "Get available system Accelerator resources by service.";
319 crow::connections::systemBus->async_method_call(
320 [acclrtrId, aResp{std::move(aResp)}](
321 const boost::system::error_code ec,
322 const boost::container::flat_map<
Santosh Puranik94e1b822019-07-24 04:48:32 -0500323 std::string, std::variant<std::string, uint32_t, uint16_t,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500324 bool>>& properties) {
Alpana Kumari32bee762019-04-25 04:47:57 -0500325 if (ec)
326 {
327 BMCWEB_LOG_DEBUG << "DBUS response error";
328 messages::internalError(aResp->res);
329 return;
330 }
331 aResp->res.jsonValue["Id"] = acclrtrId;
332 aResp->res.jsonValue["Name"] = "Processor";
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500333 const bool* accPresent = nullptr;
334 const bool* accFunctional = nullptr;
Alpana Kumari32bee762019-04-25 04:47:57 -0500335
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500336 for (const auto& property : properties)
Alpana Kumari32bee762019-04-25 04:47:57 -0500337 {
338 if (property.first == "Functional")
339 {
Santosh Puranik94e1b822019-07-24 04:48:32 -0500340 accFunctional = std::get_if<bool>(&property.second);
Alpana Kumari32bee762019-04-25 04:47:57 -0500341 }
342 else if (property.first == "Present")
343 {
Santosh Puranik94e1b822019-07-24 04:48:32 -0500344 accPresent = std::get_if<bool>(&property.second);
Alpana Kumari32bee762019-04-25 04:47:57 -0500345 }
346 }
347
Alpana Kumari657877c2020-02-24 02:24:07 -0600348 if ((accPresent != nullptr) && (*accPresent == false))
Alpana Kumari32bee762019-04-25 04:47:57 -0500349 {
Alpana Kumari657877c2020-02-24 02:24:07 -0600350 aResp->res.jsonValue["Status"]["State"] = "Absent";
351 aResp->res.jsonValue["Status"]["Health"] = "OK";
Alpana Kumari32bee762019-04-25 04:47:57 -0500352 }
353 else
354 {
Alpana Kumari657877c2020-02-24 02:24:07 -0600355 aResp->res.jsonValue["Status"]["State"] = "Enabled";
356
357 if ((accFunctional != nullptr) && (*accFunctional == false))
358 {
359 aResp->res.jsonValue["Status"]["Health"] = "Critical";
360 }
361 else
362 {
363 aResp->res.jsonValue["Status"]["Health"] = "OK";
364 }
Alpana Kumari32bee762019-04-25 04:47:57 -0500365 }
Alpana Kumari32bee762019-04-25 04:47:57 -0500366 aResp->res.jsonValue["ProcessorType"] = "Accelerator";
367 },
368 service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
369}
370
Ed Tanous23a21a12020-07-25 04:45:05 +0000371inline void getCpuData(std::shared_ptr<AsyncResp> aResp,
372 const std::string& cpuId,
373 const std::vector<const char*> inventoryItems)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200374{
375 BMCWEB_LOG_DEBUG << "Get available system cpu resources.";
Alpana Kumari32bee762019-04-25 04:47:57 -0500376
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200377 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -0800378 [cpuId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200379 const boost::system::error_code ec,
380 const boost::container::flat_map<
381 std::string, boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500382 std::string, std::vector<std::string>>>&
383 subtree) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200384 if (ec)
385 {
386 BMCWEB_LOG_DEBUG << "DBUS response error";
387 messages::internalError(aResp->res);
388 return;
389 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500390 for (const auto& object : subtree)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200391 {
392 if (boost::ends_with(object.first, cpuId))
393 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500394 for (const auto& service : object.second)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200395 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500396 for (const auto& inventory : service.second)
Zhikui Ren5e54a362020-07-13 15:31:38 -0700397 {
398 if (inventory == "xyz.openbmc_project."
399 "Inventory.Decorator.Asset")
400 {
401 getCpuAssetData(aResp, service.first,
402 object.first);
403 }
404 else if (inventory ==
405 "xyz.openbmc_project.Inventory.Item.Cpu")
Alpana Kumari32bee762019-04-25 04:47:57 -0500406 {
407 getCpuDataByService(aResp, cpuId, service.first,
408 object.first);
409 }
410 else if (inventory == "xyz.openbmc_project."
411 "Inventory.Item.Accelerator")
412 {
413 getAcceleratorDataByService(
414 aResp, cpuId, service.first, object.first);
415 }
Zhikui Ren5e54a362020-07-13 15:31:38 -0700416 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200417 }
Zhikui Ren5e54a362020-07-13 15:31:38 -0700418 return;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200419 }
420 }
421 // Object not found
422 messages::resourceNotFound(aResp->res, "Processor", cpuId);
423 return;
424 },
425 "xyz.openbmc_project.ObjectMapper",
426 "/xyz/openbmc_project/object_mapper",
427 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -0700428 "/xyz/openbmc_project/inventory", 0, inventoryItems);
429}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200430
James Feistc50e7c62020-07-27 15:39:36 -0700431using DimmProperty =
432 std::variant<std::string, std::vector<uint32_t>, std::vector<uint16_t>,
433 uint64_t, uint32_t, uint16_t, uint8_t, bool>;
434
435using DimmProperties = boost::container::flat_map<std::string, DimmProperty>;
436
437void dimmPropToHex(std::shared_ptr<AsyncResp> aResp, const char* key,
438 const std::pair<std::string, DimmProperty>& property)
439{
440 const uint16_t* value = std::get_if<uint16_t>(&property.second);
441 if (value == nullptr)
442 {
443 messages::internalError(aResp->res);
444 BMCWEB_LOG_DEBUG << "Invalid property type for " << property.first;
445 return;
446 }
447
448 aResp->res.jsonValue[key] = (boost::format("0x%04x") % *value).str();
449}
450
451void getPersistentMemoryProperties(std::shared_ptr<AsyncResp> aResp,
452 const DimmProperties& properties)
453{
454 for (const auto& property : properties)
455 {
456 if (property.first == "ModuleManufacturerID")
457 {
458 dimmPropToHex(aResp, "ModuleManufacturerID", property);
459 }
460 else if (property.first == "ModuleProductID")
461 {
462 dimmPropToHex(aResp, "ModuleProductID", property);
463 }
464 else if (property.first == "SubsystemVendorID")
465 {
466 dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID",
467 property);
468 }
469 else if (property.first == "SubsystemDeviceID")
470 {
471 dimmPropToHex(aResp, "MemorySubsystemControllerProductID",
472 property);
473 }
474 else if (property.first == "VolatileRegionSizeLimitInKiB")
475 {
476 const uint64_t* value = std::get_if<uint64_t>(&property.second);
477
478 if (value == nullptr)
479 {
480 messages::internalError(aResp->res);
481 BMCWEB_LOG_DEBUG << "Invalid property type for "
482 "VolatileRegionSizeLimitKiB";
483 continue;
484 }
485 aResp->res.jsonValue["VolatileRegionSizeLimitMiB"] = (*value) >> 10;
486 }
487 else if (property.first == "PmRegionSizeLimitInKiB")
488 {
489 const uint64_t* value = std::get_if<uint64_t>(&property.second);
490
491 if (value == nullptr)
492 {
493 messages::internalError(aResp->res);
494 BMCWEB_LOG_DEBUG
495 << "Invalid property type for PmRegioSizeLimitKiB";
496 continue;
497 }
498 aResp->res.jsonValue["PersistentRegionSizeLimitMiB"] =
499 (*value) >> 10;
500 }
501 else if (property.first == "VolatileSizeInKiB")
502 {
503 const uint64_t* value = std::get_if<uint64_t>(&property.second);
504
505 if (value == nullptr)
506 {
507 messages::internalError(aResp->res);
508 BMCWEB_LOG_DEBUG
509 << "Invalid property type for VolatileSizeInKiB";
510 continue;
511 }
512 aResp->res.jsonValue["VolatileSizeMiB"] = (*value) >> 10;
513 }
514 else if (property.first == "PmSizeInKiB")
515 {
516 const uint64_t* value = std::get_if<uint64_t>(&property.second);
517 if (value == nullptr)
518 {
519 messages::internalError(aResp->res);
520 BMCWEB_LOG_DEBUG << "Invalid property type for PmSizeInKiB";
521 continue;
522 }
523 aResp->res.jsonValue["NonVolatileSizeMiB"] = (*value) >> 10;
524 }
525 else if (property.first == "CacheSizeInKB")
526 {
527 const uint64_t* value = std::get_if<uint64_t>(&property.second);
528 if (value == nullptr)
529 {
530 messages::internalError(aResp->res);
531 BMCWEB_LOG_DEBUG << "Invalid property type for CacheSizeInKB";
532 continue;
533 }
534 aResp->res.jsonValue["CacheSizeMiB"] = (*value >> 10);
535 }
536
537 else if (property.first == "VoltaileRegionMaxSizeInKib")
538 {
539 const uint64_t* value = std::get_if<uint64_t>(&property.second);
540
541 if (value == nullptr)
542 {
543 messages::internalError(aResp->res);
544 BMCWEB_LOG_DEBUG << "Invalid property type for "
545 "VolatileRegionMaxSizeInKib";
546 continue;
547 }
548 aResp->res.jsonValue["VolatileRegionSizeMaxMiB"] = (*value) >> 10;
549 }
550 else if (property.first == "PmRegionMaxSizeInKiB")
551 {
552 const uint64_t* value = std::get_if<uint64_t>(&property.second);
553
554 if (value == nullptr)
555 {
556 messages::internalError(aResp->res);
557 BMCWEB_LOG_DEBUG
558 << "Invalid property type for PmRegionMaxSizeInKiB";
559 continue;
560 }
561 aResp->res.jsonValue["PersistentRegionSizeMaxMiB"] = (*value) >> 10;
562 }
563 else if (property.first == "AllocationIncrementInKiB")
564 {
565 const uint64_t* value = std::get_if<uint64_t>(&property.second);
566
567 if (value == nullptr)
568 {
569 messages::internalError(aResp->res);
570 BMCWEB_LOG_DEBUG << "Invalid property type for "
571 "AllocationIncrementInKiB";
572 continue;
573 }
574 aResp->res.jsonValue["AllocationIncrementMiB"] = (*value) >> 10;
575 }
576 else if (property.first == "AllocationAlignmentInKiB")
577 {
578 const uint64_t* value = std::get_if<uint64_t>(&property.second);
579
580 if (value == nullptr)
581 {
582 messages::internalError(aResp->res);
583 BMCWEB_LOG_DEBUG << "Invalid property type for "
584 "AllocationAlignmentInKiB";
585 continue;
586 }
587 aResp->res.jsonValue["AllocationAlignmentMiB"] = (*value) >> 10;
588 }
589 else if (property.first == "VolatileRegionNumberLimit")
590 {
591 aResp->res.jsonValue["VolatileRegionNumberLimit"] = property.second;
592 }
593 else if (property.first == "PmRegionNumberLimit")
594 {
595 aResp->res.jsonValue["PersistentRegionNumberLimit"] =
596 property.second;
597 }
598 else if (property.first == "SpareDeviceCount")
599 {
600 aResp->res.jsonValue["SpareDeviceCount"] = property.second;
601 }
602 else if (property.first == "IsSpareDeviceInUse")
603 {
604 aResp->res.jsonValue["IsSpareDeviceEnabled"] = property.second;
605 }
606 else if (property.first == "IsRankSpareEnabled")
607 {
608 aResp->res.jsonValue["IsRankSpareEnabled"] = property.second;
609 }
610 else if (property.first == "MaxAveragePowerLimitmW")
611 {
612 const auto* value =
613 std::get_if<std::vector<uint32_t>>(&property.second);
614 if (value == nullptr)
615 {
616 messages::internalError(aResp->res);
617 BMCWEB_LOG_DEBUG << "Invalid property type for "
618 "MaxAveragePowerLimitmW";
619 continue;
620 }
621 aResp->res.jsonValue["MaxTDPMilliWatts"] = *value;
622 }
623 else if (property.first == "CurrentSecurityState")
624 {
625 aResp->res.jsonValue["SecurityState"] = property.second;
626 }
627 else if (property.first == "ConfigurationLocked")
628 {
629 aResp->res.jsonValue["ConfigurationLocked"] = property.second;
630 }
631 else if (property.first == "AllowedMemoryModes")
632 {
633 const std::string* value =
634 std::get_if<std::string>(&property.second);
635 if (value == nullptr)
636 {
637 messages::internalError(aResp->res);
638 BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor";
639 continue;
640 }
641 constexpr const std::array<const char*, 3> values{"Volatile",
642 "PMEM", "Block"};
643
644 for (const char* v : values)
645 {
646 if (boost::ends_with(*value, v))
647 {
648 aResp->res.jsonValue["OperatingMemoryModes "] = v;
649 break;
650 }
651 }
652 }
653 else if (property.first == "MemoryMedia")
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 BMCWEB_LOG_DEBUG << "Invalid property type for MemoryMedia";
661 continue;
662 }
663 constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
664 "Intel3DXPoint"};
665
666 for (const char* v : values)
667 {
668 if (boost::ends_with(*value, v))
669 {
670 aResp->res.jsonValue["MemoryMedia"] = v;
671 break;
672 }
673 }
674 }
675 // PersistantMemory.PowerManagmentPolicy interface
676 else if (property.first == "AveragePowerBudgetmW" ||
677 property.first == "MaxTDPmW" ||
678 property.first == "PeakPowerBudgetmW" ||
679 property.first == "PolicyEnabled")
680 {
681 std::string name =
682 boost::replace_all_copy(property.first, "mW", "MilliWatts");
683 aResp->res.jsonValue["PowerManagementPolicy"][name] =
684 property.second;
685 }
686 // PersistantMemory.SecurityCapabilites interface
687 else if (property.first == "ConfigurationLockCapable" ||
688 property.first == "DataLockCapable" ||
689 property.first == "MaxPassphraseCount" ||
690 property.first == "PassphraseCapable" ||
691 property.first == "PassphraseLockLimit")
692 {
693 aResp->res.jsonValue["SecurityCapabilities"][property.first] =
694 property.second;
695 }
696 }
697}
698
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200699void getDimmDataByService(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500700 const std::string& dimmId, const std::string& service,
701 const std::string& objPath)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200702{
James Feist35e257a2020-06-05 13:30:51 -0700703 auto health = std::make_shared<HealthPopulate>(aResp);
704 health->selfPath = objPath;
705 health->populate();
706
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200707 BMCWEB_LOG_DEBUG << "Get available system components.";
708 crow::connections::systemBus->async_method_call(
James Feistc50e7c62020-07-27 15:39:36 -0700709 [dimmId, aResp{std::move(aResp)}](const boost::system::error_code ec,
710 const DimmProperties& properties) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200711 if (ec)
712 {
713 BMCWEB_LOG_DEBUG << "DBUS response error";
714 messages::internalError(aResp->res);
715
716 return;
717 }
718 aResp->res.jsonValue["Id"] = dimmId;
719 aResp->res.jsonValue["Name"] = "DIMM Slot";
720
721 const auto memorySizeProperty = properties.find("MemorySizeInKB");
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600722 if (memorySizeProperty != properties.end())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200723 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500724 const uint32_t* memorySize =
Ed Tanousabf2add2019-01-22 16:40:12 -0800725 std::get_if<uint32_t>(&memorySizeProperty->second);
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600726 if (memorySize == nullptr)
727 {
728 // Important property not in desired type
729 messages::internalError(aResp->res);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200730
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600731 return;
732 }
733 if (*memorySize == 0)
734 {
735 // Slot is not populated, set status end return
736 aResp->res.jsonValue["Status"]["State"] = "Absent";
737 aResp->res.jsonValue["Status"]["Health"] = "OK";
738 // HTTP Code will be set up automatically, just return
739 return;
740 }
741 aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200742 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200743 aResp->res.jsonValue["Status"]["State"] = "Enabled";
744 aResp->res.jsonValue["Status"]["Health"] = "OK";
745
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500746 for (const auto& property : properties)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200747 {
748 if (property.first == "MemoryDataWidth")
749 {
750 aResp->res.jsonValue["DataWidthBits"] = property.second;
751 }
Manojkiran Eda7e236ca2019-06-25 23:06:32 +0530752 else if (property.first == "PartNumber")
753 {
754 aResp->res.jsonValue["PartNumber"] = property.second;
755 }
756 else if (property.first == "SerialNumber")
757 {
758 aResp->res.jsonValue["SerialNumber"] = property.second;
759 }
760 else if (property.first == "Manufacturer")
761 {
762 aResp->res.jsonValue["Manufacturer"] = property.second;
763 }
James Feistc50e7c62020-07-27 15:39:36 -0700764 else if (property.first == "RevisionCode")
765 {
766 const uint16_t* value =
767 std::get_if<uint16_t>(&property.second);
768
769 if (value == nullptr)
770 {
771 messages::internalError(aResp->res);
772 BMCWEB_LOG_DEBUG
773 << "Invalid property type for RevisionCode";
774 continue;
775 }
776 aResp->res.jsonValue["FirmwareRevision"] =
777 std::to_string(*value);
778 }
779 else if (property.first == "MemoryTotalWidth")
780 {
781 aResp->res.jsonValue["BusWidthBits"] = property.second;
782 }
783 else if (property.first == "ECC")
784 {
785 const std::string* value =
786 std::get_if<std::string>(&property.second);
787 if (value == nullptr)
788 {
789 messages::internalError(aResp->res);
790 BMCWEB_LOG_DEBUG << "Invalid property type for ECC";
791 continue;
792 }
793 constexpr const std::array<const char*, 4> values{
794 "NoECC", "SingleBitECC", "MultiBitECC",
795 "AddressParity"};
796
797 for (const char* v : values)
798 {
799 if (boost::ends_with(*value, v))
800 {
801 aResp->res.jsonValue["ErrorCorrection"] = v;
802 break;
803 }
804 }
805 }
806 else if (property.first == "FormFactor")
807 {
808 const std::string* value =
809 std::get_if<std::string>(&property.second);
810 if (value == nullptr)
811 {
812 messages::internalError(aResp->res);
813 BMCWEB_LOG_DEBUG
814 << "Invalid property type for FormFactor";
815 continue;
816 }
817 constexpr const std::array<const char*, 11> values{
818 "RDIMM", "UDIMM", "SO_DIMM",
819 "LRDIMM", "Mini_RDIMM", "Mini_UDIMM",
820 "SO_RDIMM_72b", "SO_UDIMM_72b", "SO_DIMM_16b",
821 "SO_DIMM_32b", "Die"};
822
823 for (const char* v : values)
824 {
825 if (boost::ends_with(*value, v))
826 {
827 aResp->res.jsonValue["BaseModuleType"] = v;
828 break;
829 }
830 }
831 }
832 else if (property.first == "AllowedSpeedsMT")
833 {
834 aResp->res.jsonValue["AllowedSpeedsMHz"] = property.second;
835 }
836 else if (property.first == "MemoryAttributes")
837 {
838 const uint8_t* value =
839 std::get_if<uint8_t>(&property.second);
840
841 if (value == nullptr)
842 {
843 messages::internalError(aResp->res);
844 BMCWEB_LOG_DEBUG
845 << "Invalid property type for MemoryAttributes";
846 continue;
847 }
848 aResp->res.jsonValue["RankCount"] =
849 static_cast<uint64_t>(*value);
850 }
851 else if (property.first == "MemoryConfiguredSpeedInMhz")
852 {
853 aResp->res.jsonValue["OperatingSpeedMhz"] = property.second;
854 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200855 else if (property.first == "MemoryType")
856 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500857 const auto* value =
Ed Tanousabf2add2019-01-22 16:40:12 -0800858 std::get_if<std::string>(&property.second);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200859 if (value != nullptr)
860 {
James Feistc50e7c62020-07-27 15:39:36 -0700861 size_t idx = value->rfind(".");
862 if (idx == std::string::npos ||
863 idx + 1 >= value->size())
864 {
865 messages::internalError(aResp->res);
866 BMCWEB_LOG_DEBUG << "Invalid property type for "
867 "MemoryType";
868 }
869 std::string result = value->substr(idx + 1);
870 aResp->res.jsonValue["MemoryDeviceType"] = result;
871 if (value->find("DDR") != std::string::npos)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200872 {
873 aResp->res.jsonValue["MemoryType"] = "DRAM";
874 }
James Feistc50e7c62020-07-27 15:39:36 -0700875 else if (boost::ends_with(*value, "Logical"))
876 {
877 aResp->res.jsonValue["MemoryType"] = "IntelOptane";
878 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200879 }
880 }
James Feistc50e7c62020-07-27 15:39:36 -0700881 // memory location interface
882 else if (property.first == "Channel" ||
883 property.first == "MemoryController" ||
884 property.first == "Slot" || property.first == "Socket")
885 {
886 aResp->res.jsonValue["MemoryLocation"][property.first] =
887 property.second;
888 }
889 else
890 {
891 getPersistentMemoryProperties(aResp, properties);
892 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200893 }
894 },
895 service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
896}
897
Ed Tanous23a21a12020-07-25 04:45:05 +0000898inline void getDimmPartitionData(std::shared_ptr<AsyncResp> aResp,
899 const std::string& service,
900 const std::string& path)
James Feist45094ad2020-04-29 14:02:30 -0700901{
902 crow::connections::systemBus->async_method_call(
903 [aResp{std::move(aResp)}](
904 const boost::system::error_code ec,
905 const boost::container::flat_map<
906 std::string, std::variant<std::string, uint64_t, uint32_t,
907 bool>>& properties) {
908 if (ec)
909 {
910 BMCWEB_LOG_DEBUG << "DBUS response error";
911 messages::internalError(aResp->res);
912
913 return;
914 }
915
916 nlohmann::json& partition =
917 aResp->res.jsonValue["Regions"].emplace_back(
918 nlohmann::json::object());
919 for (const auto& [key, val] : properties)
920 {
921 if (key == "MemoryClassification")
922 {
923 partition[key] = val;
924 }
925 else if (key == "OffsetInKiB")
926 {
927 const uint64_t* value = std::get_if<uint64_t>(&val);
928 if (value == nullptr)
929 {
930 messages::internalError(aResp->res);
931 BMCWEB_LOG_DEBUG
932 << "Invalid property type for OffsetInKiB";
933 continue;
934 }
935
936 partition["OffsetMiB"] = (*value >> 10);
937 }
938 else if (key == "PartitionId")
939 {
940 partition["RegionId"] = val;
941 }
942
943 else if (key == "PassphraseState")
944 {
945 partition["PassphraseEnabled"] = val;
946 }
947 else if (key == "SizeInKiB")
948 {
949 const uint64_t* value = std::get_if<uint64_t>(&val);
950 if (value == nullptr)
951 {
952 messages::internalError(aResp->res);
953 BMCWEB_LOG_DEBUG
954 << "Invalid property type for SizeInKiB";
955 continue;
956 }
957 partition["SizeMiB"] = (*value >> 10);
958 }
959 }
960 },
961
962 service, path, "org.freedesktop.DBus.Properties", "GetAll",
963 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition");
964}
965
Ed Tanous23a21a12020-07-25 04:45:05 +0000966inline void getDimmData(std::shared_ptr<AsyncResp> aResp,
967 const std::string& dimmId)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200968{
969 BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
970 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -0800971 [dimmId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200972 const boost::system::error_code ec,
973 const boost::container::flat_map<
974 std::string, boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500975 std::string, std::vector<std::string>>>&
976 subtree) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200977 if (ec)
978 {
979 BMCWEB_LOG_DEBUG << "DBUS response error";
980 messages::internalError(aResp->res);
981
982 return;
983 }
James Feist45094ad2020-04-29 14:02:30 -0700984 bool found = false;
985 for (const auto& [path, object] : subtree)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200986 {
James Feist45094ad2020-04-29 14:02:30 -0700987 if (path.find(dimmId) != std::string::npos)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200988 {
James Feist45094ad2020-04-29 14:02:30 -0700989 for (const auto& [service, interfaces] : object)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200990 {
James Feist45094ad2020-04-29 14:02:30 -0700991 if (!found &&
992 (std::find(
993 interfaces.begin(), interfaces.end(),
994 "xyz.openbmc_project.Inventory.Item.Dimm") !=
995 interfaces.end()))
996 {
997 getDimmDataByService(aResp, dimmId, service, path);
998 found = true;
999 }
1000
1001 // partitions are separate as there can be multiple per
1002 // device, i.e.
1003 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
1004 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
1005 if (std::find(interfaces.begin(), interfaces.end(),
1006 "xyz.openbmc_project.Inventory.Item."
1007 "PersistentMemory.Partition") !=
1008 interfaces.end())
1009 {
1010 getDimmPartitionData(aResp, service, path);
1011 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001012 }
1013 }
1014 }
1015 // Object not found
James Feist45094ad2020-04-29 14:02:30 -07001016 if (!found)
1017 {
1018 messages::resourceNotFound(aResp->res, "Memory", dimmId);
1019 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001020 return;
1021 },
1022 "xyz.openbmc_project.ObjectMapper",
1023 "/xyz/openbmc_project/object_mapper",
1024 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -07001025 "/xyz/openbmc_project/inventory", 0,
James Feist45094ad2020-04-29 14:02:30 -07001026 std::array<const char*, 2>{
1027 "xyz.openbmc_project.Inventory.Item.Dimm",
1028 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"});
Ed Tanous271584a2019-07-09 16:24:22 -07001029}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001030
1031class ProcessorCollection : public Node
1032{
1033 public:
1034 /*
1035 * Default Constructor
1036 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001037 ProcessorCollection(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001038 Node(app, "/redfish/v1/Systems/system/Processors/")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001039 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001040 entityPrivileges = {
1041 {boost::beast::http::verb::get, {{"Login"}}},
1042 {boost::beast::http::verb::head, {{"Login"}}},
1043 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1044 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1045 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1046 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1047 }
1048
1049 private:
1050 /**
1051 * Functions triggers appropriate requests on DBus
1052 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001053 void doGet(crow::Response& res, const crow::Request&,
1054 const std::vector<std::string>&) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001055 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001056 res.jsonValue["@odata.type"] =
1057 "#ProcessorCollection.ProcessorCollection";
1058 res.jsonValue["Name"] = "Processor Collection";
Ed Tanous0f74e642018-11-12 15:17:05 -08001059
Ed Tanous029573d2019-02-01 10:57:49 -08001060 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Processors/";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001061 auto asyncResp = std::make_shared<AsyncResp>(res);
1062
Ed Tanous029573d2019-02-01 10:57:49 -08001063 getResourceList(asyncResp, "Processors",
Alpana Kumari32bee762019-04-25 04:47:57 -05001064 {"xyz.openbmc_project.Inventory.Item.Cpu",
1065 "xyz.openbmc_project.Inventory.Item.Accelerator"});
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001066 }
1067};
1068
1069class Processor : public Node
1070{
1071 public:
1072 /*
1073 * Default Constructor
1074 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001075 Processor(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001076 Node(app, "/redfish/v1/Systems/system/Processors/<str>/", std::string())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001077 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001078 entityPrivileges = {
1079 {boost::beast::http::verb::get, {{"Login"}}},
1080 {boost::beast::http::verb::head, {{"Login"}}},
1081 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1082 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1083 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1084 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1085 }
1086
1087 private:
1088 /**
1089 * Functions triggers appropriate requests on DBus
1090 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001091 void doGet(crow::Response& res, const crow::Request&,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001092 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001093 {
1094 // Check if there is required param, truly entering this shall be
1095 // impossible
1096 if (params.size() != 1)
1097 {
1098 messages::internalError(res);
1099
1100 res.end();
1101 return;
1102 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001103 const std::string& processorId = params[0];
Gunnar Millsf9dcc112020-02-13 13:19:43 -06001104 res.jsonValue["@odata.type"] = "#Processor.v1_7_0.Processor";
Ed Tanous029573d2019-02-01 10:57:49 -08001105 res.jsonValue["@odata.id"] =
Alpana Kumari32bee762019-04-25 04:47:57 -05001106 "/redfish/v1/Systems/system/Processors/" + processorId;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001107
Ed Tanous029573d2019-02-01 10:57:49 -08001108 auto asyncResp = std::make_shared<AsyncResp>(res);
1109
Alpana Kumari32bee762019-04-25 04:47:57 -05001110 getCpuData(asyncResp, processorId,
1111 {"xyz.openbmc_project.Inventory.Item.Cpu",
Zhikui Ren5e54a362020-07-13 15:31:38 -07001112 "xyz.openbmc_project.Inventory.Decorator.Asset",
Alpana Kumari32bee762019-04-25 04:47:57 -05001113 "xyz.openbmc_project.Inventory.Item.Accelerator"});
Ed Tanous029573d2019-02-01 10:57:49 -08001114 }
1115};
1116
1117class MemoryCollection : public Node
1118{
1119 public:
1120 /*
1121 * Default Constructor
1122 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001123 MemoryCollection(App& app) : Node(app, "/redfish/v1/Systems/system/Memory/")
Ed Tanous029573d2019-02-01 10:57:49 -08001124 {
1125 entityPrivileges = {
1126 {boost::beast::http::verb::get, {{"Login"}}},
1127 {boost::beast::http::verb::head, {{"Login"}}},
1128 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1129 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1130 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1131 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1132 }
1133
1134 private:
1135 /**
1136 * Functions triggers appropriate requests on DBus
1137 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001138 void doGet(crow::Response& res, const crow::Request&,
1139 const std::vector<std::string>&) override
Ed Tanous029573d2019-02-01 10:57:49 -08001140 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001141 res.jsonValue["@odata.type"] = "#MemoryCollection.MemoryCollection";
1142 res.jsonValue["Name"] = "Memory Module Collection";
James Feistc50e7c62020-07-27 15:39:36 -07001143 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Memory";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001144 auto asyncResp = std::make_shared<AsyncResp>(res);
1145
Ed Tanous029573d2019-02-01 10:57:49 -08001146 getResourceList(asyncResp, "Memory",
Alpana Kumari32bee762019-04-25 04:47:57 -05001147 {"xyz.openbmc_project.Inventory.Item.Dimm"});
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001148 }
1149};
1150
1151class Memory : public Node
1152{
1153 public:
1154 /*
1155 * Default Constructor
1156 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001157 Memory(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001158 Node(app, "/redfish/v1/Systems/system/Memory/<str>/", std::string())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001159 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001160 entityPrivileges = {
1161 {boost::beast::http::verb::get, {{"Login"}}},
1162 {boost::beast::http::verb::head, {{"Login"}}},
1163 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1164 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1165 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1166 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1167 }
1168
1169 private:
1170 /**
1171 * Functions triggers appropriate requests on DBus
1172 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001173 void doGet(crow::Response& res, const crow::Request&,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001174 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001175 {
1176 // Check if there is required param, truly entering this shall be
1177 // impossible
Ed Tanous029573d2019-02-01 10:57:49 -08001178 if (params.size() != 1)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001179 {
1180 messages::internalError(res);
1181 res.end();
1182 return;
1183 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001184 const std::string& dimmId = params[0];
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001185
James Feistc50e7c62020-07-27 15:39:36 -07001186 res.jsonValue["@odata.type"] = "#Memory.v1_7_0.Memory";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001187 res.jsonValue["@odata.id"] =
Ed Tanous029573d2019-02-01 10:57:49 -08001188 "/redfish/v1/Systems/system/Memory/" + dimmId;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001189 auto asyncResp = std::make_shared<AsyncResp>(res);
1190
Ed Tanous029573d2019-02-01 10:57:49 -08001191 getDimmData(asyncResp, dimmId);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001192 }
1193};
1194
1195} // namespace redfish