blob: 4f387fc1edc1aed045909843783871d5f2450282 [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
Ed Tanous80789c82020-08-19 09:19:09 -0700437inline void dimmPropToHex(std::shared_ptr<AsyncResp> aResp, const char* key,
438 const std::pair<std::string, DimmProperty>& property)
James Feistc50e7c62020-07-27 15:39:36 -0700439{
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
Ed Tanous80789c82020-08-19 09:19:09 -0700451inline void getPersistentMemoryProperties(std::shared_ptr<AsyncResp> aResp,
452 const DimmProperties& properties)
James Feistc50e7c62020-07-27 15:39:36 -0700453{
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
Ed Tanous80789c82020-08-19 09:19:09 -0700699inline void getDimmDataByService(std::shared_ptr<AsyncResp> aResp,
700 const std::string& dimmId,
701 const std::string& service,
702 const std::string& objPath)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200703{
James Feist35e257a2020-06-05 13:30:51 -0700704 auto health = std::make_shared<HealthPopulate>(aResp);
705 health->selfPath = objPath;
706 health->populate();
707
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200708 BMCWEB_LOG_DEBUG << "Get available system components.";
709 crow::connections::systemBus->async_method_call(
James Feistc50e7c62020-07-27 15:39:36 -0700710 [dimmId, aResp{std::move(aResp)}](const boost::system::error_code ec,
711 const DimmProperties& properties) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200712 if (ec)
713 {
714 BMCWEB_LOG_DEBUG << "DBUS response error";
715 messages::internalError(aResp->res);
716
717 return;
718 }
719 aResp->res.jsonValue["Id"] = dimmId;
720 aResp->res.jsonValue["Name"] = "DIMM Slot";
721
722 const auto memorySizeProperty = properties.find("MemorySizeInKB");
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600723 if (memorySizeProperty != properties.end())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200724 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500725 const uint32_t* memorySize =
Ed Tanousabf2add2019-01-22 16:40:12 -0800726 std::get_if<uint32_t>(&memorySizeProperty->second);
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600727 if (memorySize == nullptr)
728 {
729 // Important property not in desired type
730 messages::internalError(aResp->res);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200731
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600732 return;
733 }
734 if (*memorySize == 0)
735 {
736 // Slot is not populated, set status end return
737 aResp->res.jsonValue["Status"]["State"] = "Absent";
738 aResp->res.jsonValue["Status"]["Health"] = "OK";
739 // HTTP Code will be set up automatically, just return
740 return;
741 }
742 aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200743 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200744 aResp->res.jsonValue["Status"]["State"] = "Enabled";
745 aResp->res.jsonValue["Status"]["Health"] = "OK";
746
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500747 for (const auto& property : properties)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200748 {
749 if (property.first == "MemoryDataWidth")
750 {
751 aResp->res.jsonValue["DataWidthBits"] = property.second;
752 }
Manojkiran Eda7e236ca2019-06-25 23:06:32 +0530753 else if (property.first == "PartNumber")
754 {
755 aResp->res.jsonValue["PartNumber"] = property.second;
756 }
757 else if (property.first == "SerialNumber")
758 {
759 aResp->res.jsonValue["SerialNumber"] = property.second;
760 }
761 else if (property.first == "Manufacturer")
762 {
763 aResp->res.jsonValue["Manufacturer"] = property.second;
764 }
James Feistc50e7c62020-07-27 15:39:36 -0700765 else if (property.first == "RevisionCode")
766 {
767 const uint16_t* value =
768 std::get_if<uint16_t>(&property.second);
769
770 if (value == nullptr)
771 {
772 messages::internalError(aResp->res);
773 BMCWEB_LOG_DEBUG
774 << "Invalid property type for RevisionCode";
775 continue;
776 }
777 aResp->res.jsonValue["FirmwareRevision"] =
778 std::to_string(*value);
779 }
780 else if (property.first == "MemoryTotalWidth")
781 {
782 aResp->res.jsonValue["BusWidthBits"] = property.second;
783 }
784 else if (property.first == "ECC")
785 {
786 const std::string* value =
787 std::get_if<std::string>(&property.second);
788 if (value == nullptr)
789 {
790 messages::internalError(aResp->res);
791 BMCWEB_LOG_DEBUG << "Invalid property type for ECC";
792 continue;
793 }
794 constexpr const std::array<const char*, 4> values{
795 "NoECC", "SingleBitECC", "MultiBitECC",
796 "AddressParity"};
797
798 for (const char* v : values)
799 {
800 if (boost::ends_with(*value, v))
801 {
802 aResp->res.jsonValue["ErrorCorrection"] = v;
803 break;
804 }
805 }
806 }
807 else if (property.first == "FormFactor")
808 {
809 const std::string* value =
810 std::get_if<std::string>(&property.second);
811 if (value == nullptr)
812 {
813 messages::internalError(aResp->res);
814 BMCWEB_LOG_DEBUG
815 << "Invalid property type for FormFactor";
816 continue;
817 }
818 constexpr const std::array<const char*, 11> values{
819 "RDIMM", "UDIMM", "SO_DIMM",
820 "LRDIMM", "Mini_RDIMM", "Mini_UDIMM",
821 "SO_RDIMM_72b", "SO_UDIMM_72b", "SO_DIMM_16b",
822 "SO_DIMM_32b", "Die"};
823
824 for (const char* v : values)
825 {
826 if (boost::ends_with(*value, v))
827 {
828 aResp->res.jsonValue["BaseModuleType"] = v;
829 break;
830 }
831 }
832 }
833 else if (property.first == "AllowedSpeedsMT")
834 {
835 aResp->res.jsonValue["AllowedSpeedsMHz"] = property.second;
836 }
837 else if (property.first == "MemoryAttributes")
838 {
839 const uint8_t* value =
840 std::get_if<uint8_t>(&property.second);
841
842 if (value == nullptr)
843 {
844 messages::internalError(aResp->res);
845 BMCWEB_LOG_DEBUG
846 << "Invalid property type for MemoryAttributes";
847 continue;
848 }
849 aResp->res.jsonValue["RankCount"] =
850 static_cast<uint64_t>(*value);
851 }
852 else if (property.first == "MemoryConfiguredSpeedInMhz")
853 {
854 aResp->res.jsonValue["OperatingSpeedMhz"] = property.second;
855 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200856 else if (property.first == "MemoryType")
857 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500858 const auto* value =
Ed Tanousabf2add2019-01-22 16:40:12 -0800859 std::get_if<std::string>(&property.second);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200860 if (value != nullptr)
861 {
James Feistc50e7c62020-07-27 15:39:36 -0700862 size_t idx = value->rfind(".");
863 if (idx == std::string::npos ||
864 idx + 1 >= value->size())
865 {
866 messages::internalError(aResp->res);
867 BMCWEB_LOG_DEBUG << "Invalid property type for "
868 "MemoryType";
869 }
870 std::string result = value->substr(idx + 1);
871 aResp->res.jsonValue["MemoryDeviceType"] = result;
872 if (value->find("DDR") != std::string::npos)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200873 {
874 aResp->res.jsonValue["MemoryType"] = "DRAM";
875 }
James Feistc50e7c62020-07-27 15:39:36 -0700876 else if (boost::ends_with(*value, "Logical"))
877 {
878 aResp->res.jsonValue["MemoryType"] = "IntelOptane";
879 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200880 }
881 }
James Feistc50e7c62020-07-27 15:39:36 -0700882 // memory location interface
883 else if (property.first == "Channel" ||
884 property.first == "MemoryController" ||
885 property.first == "Slot" || property.first == "Socket")
886 {
887 aResp->res.jsonValue["MemoryLocation"][property.first] =
888 property.second;
889 }
890 else
891 {
892 getPersistentMemoryProperties(aResp, properties);
893 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200894 }
895 },
896 service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
897}
898
Ed Tanous23a21a12020-07-25 04:45:05 +0000899inline void getDimmPartitionData(std::shared_ptr<AsyncResp> aResp,
900 const std::string& service,
901 const std::string& path)
James Feist45094ad2020-04-29 14:02:30 -0700902{
903 crow::connections::systemBus->async_method_call(
904 [aResp{std::move(aResp)}](
905 const boost::system::error_code ec,
906 const boost::container::flat_map<
907 std::string, std::variant<std::string, uint64_t, uint32_t,
908 bool>>& properties) {
909 if (ec)
910 {
911 BMCWEB_LOG_DEBUG << "DBUS response error";
912 messages::internalError(aResp->res);
913
914 return;
915 }
916
917 nlohmann::json& partition =
918 aResp->res.jsonValue["Regions"].emplace_back(
919 nlohmann::json::object());
920 for (const auto& [key, val] : properties)
921 {
922 if (key == "MemoryClassification")
923 {
924 partition[key] = val;
925 }
926 else if (key == "OffsetInKiB")
927 {
928 const uint64_t* value = std::get_if<uint64_t>(&val);
929 if (value == nullptr)
930 {
931 messages::internalError(aResp->res);
932 BMCWEB_LOG_DEBUG
933 << "Invalid property type for OffsetInKiB";
934 continue;
935 }
936
937 partition["OffsetMiB"] = (*value >> 10);
938 }
939 else if (key == "PartitionId")
940 {
941 partition["RegionId"] = val;
942 }
943
944 else if (key == "PassphraseState")
945 {
946 partition["PassphraseEnabled"] = val;
947 }
948 else if (key == "SizeInKiB")
949 {
950 const uint64_t* value = std::get_if<uint64_t>(&val);
951 if (value == nullptr)
952 {
953 messages::internalError(aResp->res);
954 BMCWEB_LOG_DEBUG
955 << "Invalid property type for SizeInKiB";
956 continue;
957 }
958 partition["SizeMiB"] = (*value >> 10);
959 }
960 }
961 },
962
963 service, path, "org.freedesktop.DBus.Properties", "GetAll",
964 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition");
965}
966
Ed Tanous23a21a12020-07-25 04:45:05 +0000967inline void getDimmData(std::shared_ptr<AsyncResp> aResp,
968 const std::string& dimmId)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200969{
970 BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
971 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -0800972 [dimmId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200973 const boost::system::error_code ec,
974 const boost::container::flat_map<
975 std::string, boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500976 std::string, std::vector<std::string>>>&
977 subtree) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200978 if (ec)
979 {
980 BMCWEB_LOG_DEBUG << "DBUS response error";
981 messages::internalError(aResp->res);
982
983 return;
984 }
James Feist45094ad2020-04-29 14:02:30 -0700985 bool found = false;
986 for (const auto& [path, object] : subtree)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200987 {
James Feist45094ad2020-04-29 14:02:30 -0700988 if (path.find(dimmId) != std::string::npos)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200989 {
James Feist45094ad2020-04-29 14:02:30 -0700990 for (const auto& [service, interfaces] : object)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200991 {
James Feist45094ad2020-04-29 14:02:30 -0700992 if (!found &&
993 (std::find(
994 interfaces.begin(), interfaces.end(),
995 "xyz.openbmc_project.Inventory.Item.Dimm") !=
996 interfaces.end()))
997 {
998 getDimmDataByService(aResp, dimmId, service, path);
999 found = true;
1000 }
1001
1002 // partitions are separate as there can be multiple per
1003 // device, i.e.
1004 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
1005 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
1006 if (std::find(interfaces.begin(), interfaces.end(),
1007 "xyz.openbmc_project.Inventory.Item."
1008 "PersistentMemory.Partition") !=
1009 interfaces.end())
1010 {
1011 getDimmPartitionData(aResp, service, path);
1012 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001013 }
1014 }
1015 }
1016 // Object not found
James Feist45094ad2020-04-29 14:02:30 -07001017 if (!found)
1018 {
1019 messages::resourceNotFound(aResp->res, "Memory", dimmId);
1020 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001021 return;
1022 },
1023 "xyz.openbmc_project.ObjectMapper",
1024 "/xyz/openbmc_project/object_mapper",
1025 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -07001026 "/xyz/openbmc_project/inventory", 0,
James Feist45094ad2020-04-29 14:02:30 -07001027 std::array<const char*, 2>{
1028 "xyz.openbmc_project.Inventory.Item.Dimm",
1029 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"});
Ed Tanous271584a2019-07-09 16:24:22 -07001030}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001031
1032class ProcessorCollection : public Node
1033{
1034 public:
1035 /*
1036 * Default Constructor
1037 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001038 ProcessorCollection(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001039 Node(app, "/redfish/v1/Systems/system/Processors/")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001040 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001041 entityPrivileges = {
1042 {boost::beast::http::verb::get, {{"Login"}}},
1043 {boost::beast::http::verb::head, {{"Login"}}},
1044 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1045 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1046 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1047 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1048 }
1049
1050 private:
1051 /**
1052 * Functions triggers appropriate requests on DBus
1053 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001054 void doGet(crow::Response& res, const crow::Request&,
1055 const std::vector<std::string>&) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001056 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001057 res.jsonValue["@odata.type"] =
1058 "#ProcessorCollection.ProcessorCollection";
1059 res.jsonValue["Name"] = "Processor Collection";
Ed Tanous0f74e642018-11-12 15:17:05 -08001060
Ed Tanous029573d2019-02-01 10:57:49 -08001061 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Processors/";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001062 auto asyncResp = std::make_shared<AsyncResp>(res);
1063
Ed Tanous029573d2019-02-01 10:57:49 -08001064 getResourceList(asyncResp, "Processors",
Alpana Kumari32bee762019-04-25 04:47:57 -05001065 {"xyz.openbmc_project.Inventory.Item.Cpu",
1066 "xyz.openbmc_project.Inventory.Item.Accelerator"});
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001067 }
1068};
1069
1070class Processor : public Node
1071{
1072 public:
1073 /*
1074 * Default Constructor
1075 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001076 Processor(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001077 Node(app, "/redfish/v1/Systems/system/Processors/<str>/", std::string())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001078 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001079 entityPrivileges = {
1080 {boost::beast::http::verb::get, {{"Login"}}},
1081 {boost::beast::http::verb::head, {{"Login"}}},
1082 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1083 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1084 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1085 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1086 }
1087
1088 private:
1089 /**
1090 * Functions triggers appropriate requests on DBus
1091 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001092 void doGet(crow::Response& res, const crow::Request&,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001093 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001094 {
1095 // Check if there is required param, truly entering this shall be
1096 // impossible
1097 if (params.size() != 1)
1098 {
1099 messages::internalError(res);
1100
1101 res.end();
1102 return;
1103 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001104 const std::string& processorId = params[0];
Gunnar Millsf9dcc112020-02-13 13:19:43 -06001105 res.jsonValue["@odata.type"] = "#Processor.v1_7_0.Processor";
Ed Tanous029573d2019-02-01 10:57:49 -08001106 res.jsonValue["@odata.id"] =
Alpana Kumari32bee762019-04-25 04:47:57 -05001107 "/redfish/v1/Systems/system/Processors/" + processorId;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001108
Ed Tanous029573d2019-02-01 10:57:49 -08001109 auto asyncResp = std::make_shared<AsyncResp>(res);
1110
Alpana Kumari32bee762019-04-25 04:47:57 -05001111 getCpuData(asyncResp, processorId,
1112 {"xyz.openbmc_project.Inventory.Item.Cpu",
Zhikui Ren5e54a362020-07-13 15:31:38 -07001113 "xyz.openbmc_project.Inventory.Decorator.Asset",
Alpana Kumari32bee762019-04-25 04:47:57 -05001114 "xyz.openbmc_project.Inventory.Item.Accelerator"});
Ed Tanous029573d2019-02-01 10:57:49 -08001115 }
1116};
1117
1118class MemoryCollection : public Node
1119{
1120 public:
1121 /*
1122 * Default Constructor
1123 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001124 MemoryCollection(App& app) : Node(app, "/redfish/v1/Systems/system/Memory/")
Ed Tanous029573d2019-02-01 10:57:49 -08001125 {
1126 entityPrivileges = {
1127 {boost::beast::http::verb::get, {{"Login"}}},
1128 {boost::beast::http::verb::head, {{"Login"}}},
1129 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1130 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1131 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1132 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1133 }
1134
1135 private:
1136 /**
1137 * Functions triggers appropriate requests on DBus
1138 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001139 void doGet(crow::Response& res, const crow::Request&,
1140 const std::vector<std::string>&) override
Ed Tanous029573d2019-02-01 10:57:49 -08001141 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001142 res.jsonValue["@odata.type"] = "#MemoryCollection.MemoryCollection";
1143 res.jsonValue["Name"] = "Memory Module Collection";
James Feistc50e7c62020-07-27 15:39:36 -07001144 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Memory";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001145 auto asyncResp = std::make_shared<AsyncResp>(res);
1146
Ed Tanous029573d2019-02-01 10:57:49 -08001147 getResourceList(asyncResp, "Memory",
Alpana Kumari32bee762019-04-25 04:47:57 -05001148 {"xyz.openbmc_project.Inventory.Item.Dimm"});
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001149 }
1150};
1151
1152class Memory : public Node
1153{
1154 public:
1155 /*
1156 * Default Constructor
1157 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001158 Memory(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001159 Node(app, "/redfish/v1/Systems/system/Memory/<str>/", std::string())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001160 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001161 entityPrivileges = {
1162 {boost::beast::http::verb::get, {{"Login"}}},
1163 {boost::beast::http::verb::head, {{"Login"}}},
1164 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1165 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1166 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1167 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1168 }
1169
1170 private:
1171 /**
1172 * Functions triggers appropriate requests on DBus
1173 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001174 void doGet(crow::Response& res, const crow::Request&,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001175 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001176 {
1177 // Check if there is required param, truly entering this shall be
1178 // impossible
Ed Tanous029573d2019-02-01 10:57:49 -08001179 if (params.size() != 1)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001180 {
1181 messages::internalError(res);
1182 res.end();
1183 return;
1184 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001185 const std::string& dimmId = params[0];
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001186
James Feistc50e7c62020-07-27 15:39:36 -07001187 res.jsonValue["@odata.type"] = "#Memory.v1_7_0.Memory";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001188 res.jsonValue["@odata.id"] =
Ed Tanous029573d2019-02-01 10:57:49 -08001189 "/redfish/v1/Systems/system/Memory/" + dimmId;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001190 auto asyncResp = std::make_shared<AsyncResp>(res);
1191
Ed Tanous029573d2019-02-01 10:57:49 -08001192 getDimmData(asyncResp, dimmId);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001193 }
1194};
1195
1196} // namespace redfish