blob: ea0cee54fc2822948f0493f53b72da17c4907a71 [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>
21#include <node.hpp>
22#include <utils/json_utils.hpp>
23
24namespace redfish
25{
26
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060027using InterfacesProperties = boost::container::flat_map<
28 std::string,
29 boost::container::flat_map<std::string, dbus::utility::DbusVariantType>>;
30
Ed Tanous029573d2019-02-01 10:57:49 -080031void getResourceList(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -050032 const std::string& subclass,
33 const std::vector<const char*>& collectionName)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020034{
35 BMCWEB_LOG_DEBUG << "Get available system cpu/mem resources.";
36 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -080037 [subclass, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020038 const boost::system::error_code ec,
39 const boost::container::flat_map<
40 std::string, boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -050041 std::string, std::vector<std::string>>>&
42 subtree) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020043 if (ec)
44 {
45 BMCWEB_LOG_DEBUG << "DBUS response error";
46 messages::internalError(aResp->res);
47 return;
48 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -050049 nlohmann::json& members = aResp->res.jsonValue["Members"];
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020050 members = nlohmann::json::array();
51
Gunnar Mills1214b7e2020-06-04 10:11:30 -050052 for (const auto& object : subtree)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020053 {
54 auto iter = object.first.rfind("/");
55 if ((iter != std::string::npos) && (iter < object.first.size()))
56 {
57 members.push_back(
Ed Tanous029573d2019-02-01 10:57:49 -080058 {{"@odata.id", "/redfish/v1/Systems/system/" +
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020059 subclass + "/" +
60 object.first.substr(iter + 1)}});
61 }
62 }
63 aResp->res.jsonValue["Members@odata.count"] = members.size();
64 },
65 "xyz.openbmc_project.ObjectMapper",
66 "/xyz/openbmc_project/object_mapper",
67 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -070068 "/xyz/openbmc_project/inventory", 0, collectionName);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020069}
70
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060071void getCpuDataByInterface(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -050072 const InterfacesProperties& cpuInterfacesProperties)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020073{
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060074 BMCWEB_LOG_DEBUG << "Get CPU resources by interface.";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020075
Gunnar Mills1214b7e2020-06-04 10:11:30 -050076 const bool* present = nullptr;
77 const bool* functional = nullptr;
78 for (const auto& interface : cpuInterfacesProperties)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060079 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050080 for (const auto& property : interface.second)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060081 {
82 if (property.first == "ProcessorCoreCount")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020083 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050084 const uint16_t* coresCount =
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060085 std::get_if<uint16_t>(&property.second);
Ed Tanous883b3112018-12-06 16:13:35 -080086 if (coresCount == nullptr)
87 {
88 // Important property not in desired type
89 messages::internalError(aResp->res);
90 return;
91 }
92 if (*coresCount == 0)
93 {
94 // Slot is not populated, set status end return
95 aResp->res.jsonValue["Status"]["State"] = "Absent";
96 aResp->res.jsonValue["Status"]["Health"] = "OK";
97 // HTTP Code will be set up automatically, just return
98 return;
99 }
100
101 aResp->res.jsonValue["TotalCores"] = *coresCount;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200102 }
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600103 else if (property.first == "ProcessorType")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200104 {
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600105 aResp->res.jsonValue["Name"] = property.second;
106 }
107 else if (property.first == "Manufacturer")
108 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500109 const std::string* value =
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600110 std::get_if<std::string>(&property.second);
111 if (value != nullptr)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200112 {
113 aResp->res.jsonValue["Manufacturer"] = property.second;
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600114 // Otherwise would be unexpected.
115 if (value->find("Intel") != std::string::npos)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200116 {
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600117 aResp->res.jsonValue["ProcessorArchitecture"] = "x86";
118 aResp->res.jsonValue["InstructionSet"] = "x86-64";
119 }
120 else if (value->find("IBM") != std::string::npos)
121 {
122 aResp->res.jsonValue["ProcessorArchitecture"] = "Power";
123 aResp->res.jsonValue["InstructionSet"] = "PowerISA";
124 }
125 }
126 }
127 else if (property.first == "ProcessorMaxSpeed")
128 {
129 aResp->res.jsonValue["MaxSpeedMHz"] = property.second;
130 }
131 else if (property.first == "ProcessorThreadCount")
132 {
133 aResp->res.jsonValue["TotalThreads"] = property.second;
134 }
135 else if (property.first == "Model")
136 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500137 const std::string* value =
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600138 std::get_if<std::string>(&property.second);
139 if (value != nullptr)
140 {
141 aResp->res.jsonValue["Model"] = *value;
142 }
143 }
Gunnar Millsf9dcc112020-02-13 13:19:43 -0600144 else if (property.first == "PartNumber")
145 {
146 aResp->res.jsonValue["PartNumber"] = property.second;
147 }
148 else if (property.first == "SerialNumber")
149 {
150 aResp->res.jsonValue["SerialNumber"] = property.second;
151 }
152 else if (property.first == "Version")
153 {
154 aResp->res.jsonValue["Version"] = property.second;
155 }
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600156 else if (property.first == "Present")
157 {
158 present = std::get_if<bool>(&property.second);
159 }
160 else if (property.first == "Functional")
161 {
162 functional = std::get_if<bool>(&property.second);
163 }
164 }
165 }
166
167 if ((present == nullptr) || (functional == nullptr))
168 {
169 // Important property not in desired type
170 messages::internalError(aResp->res);
171 return;
172 }
173
174 if (*present == false)
175 {
176 aResp->res.jsonValue["Status"]["State"] = "Absent";
177 aResp->res.jsonValue["Status"]["Health"] = "OK";
178 }
179 else
180 {
181 aResp->res.jsonValue["Status"]["State"] = "Enabled";
182 if (*functional == true)
183 {
184 aResp->res.jsonValue["Status"]["Health"] = "OK";
185 }
186 else
187 {
188 aResp->res.jsonValue["Status"]["Health"] = "Critical";
189 }
190 }
191
192 return;
193}
194
195void getCpuDataByService(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500196 const std::string& cpuId, const std::string& service,
197 const std::string& objPath)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600198{
199 BMCWEB_LOG_DEBUG << "Get available system cpu resources by service.";
200
201 crow::connections::systemBus->async_method_call(
202 [cpuId, service, objPath, aResp{std::move(aResp)}](
203 const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500204 const dbus::utility::ManagedObjectType& dbusData) {
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600205 if (ec)
206 {
207 BMCWEB_LOG_DEBUG << "DBUS response error";
208 messages::internalError(aResp->res);
209 return;
210 }
211 aResp->res.jsonValue["Id"] = cpuId;
212 aResp->res.jsonValue["Name"] = "Processor";
213 aResp->res.jsonValue["ProcessorType"] = "CPU";
214
215 std::string corePath = objPath + "/core";
216 size_t totalCores = 0;
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500217 for (const auto& object : dbusData)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600218 {
219 if (object.first.str == objPath)
220 {
221 getCpuDataByInterface(aResp, object.second);
222 }
223 else if (boost::starts_with(object.first.str, corePath))
224 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500225 for (const auto& interface : object.second)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600226 {
227 if (interface.first ==
228 "xyz.openbmc_project.Inventory.Item")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200229 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500230 for (const auto& property : interface.second)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600231 {
232 if (property.first == "Present")
233 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500234 const bool* present =
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600235 std::get_if<bool>(&property.second);
236 if (present != nullptr)
237 {
238 if (*present == true)
239 {
240 totalCores++;
241 }
242 }
243 }
244 }
Gunnar Millsb957ba52019-01-31 15:58:15 -0600245 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200246 }
247 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200248 }
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600249 // In getCpuDataByInterface(), state and health are set
250 // based on the present and functional status. If core
251 // count is zero, then it has a higher precedence.
252 if (totalCores == 0)
253 {
254 // Slot is not populated, set status end return
255 aResp->res.jsonValue["Status"]["State"] = "Absent";
256 aResp->res.jsonValue["Status"]["Health"] = "OK";
257 }
258 aResp->res.jsonValue["TotalCores"] = totalCores;
259 return;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200260 },
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600261 service, "/xyz/openbmc_project/inventory",
262 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200263}
264
Zhikui Ren5e54a362020-07-13 15:31:38 -0700265void getCpuAssetData(std::shared_ptr<AsyncResp> aResp,
266 const std::string& service, const std::string& objPath)
267{
268 BMCWEB_LOG_DEBUG << "Get Cpu Asset Data";
269 crow::connections::systemBus->async_method_call(
270 [objPath, aResp{std::move(aResp)}](
271 const boost::system::error_code ec,
272 const boost::container::flat_map<
273 std::string, std::variant<std::string, uint32_t, uint16_t,
274 bool>>& properties) {
275 if (ec)
276 {
277 BMCWEB_LOG_DEBUG << "DBUS response error";
278 messages::internalError(aResp->res);
279 return;
280 }
281
282 for (const auto& property : properties)
283 {
284 if (property.first == "SerialNumber")
285 {
286 const std::string* sn =
287 std::get_if<std::string>(&property.second);
288 if (sn != nullptr)
289 {
290 aResp->res.jsonValue["SerialNumber"] = *sn;
291 }
292 }
293 else if (property.first == "Model")
294 {
295 const std::string* model =
296 std::get_if<std::string>(&property.second);
297 if (model != nullptr)
298 {
299 aResp->res.jsonValue["Model"] = *model;
300 }
301 }
302 }
303 },
304 service, objPath, "org.freedesktop.DBus.Properties", "GetAll",
305 "xyz.openbmc_project.Inventory.Decorator.Asset");
306}
307
Alpana Kumari32bee762019-04-25 04:47:57 -0500308void getAcceleratorDataByService(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500309 const std::string& acclrtrId,
310 const std::string& service,
311 const std::string& objPath)
Alpana Kumari32bee762019-04-25 04:47:57 -0500312{
313 BMCWEB_LOG_DEBUG
314 << "Get available system Accelerator resources by service.";
315 crow::connections::systemBus->async_method_call(
316 [acclrtrId, aResp{std::move(aResp)}](
317 const boost::system::error_code ec,
318 const boost::container::flat_map<
Santosh Puranik94e1b822019-07-24 04:48:32 -0500319 std::string, std::variant<std::string, uint32_t, uint16_t,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500320 bool>>& properties) {
Alpana Kumari32bee762019-04-25 04:47:57 -0500321 if (ec)
322 {
323 BMCWEB_LOG_DEBUG << "DBUS response error";
324 messages::internalError(aResp->res);
325 return;
326 }
327 aResp->res.jsonValue["Id"] = acclrtrId;
328 aResp->res.jsonValue["Name"] = "Processor";
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500329 const bool* accPresent = nullptr;
330 const bool* accFunctional = nullptr;
Alpana Kumari32bee762019-04-25 04:47:57 -0500331
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500332 for (const auto& property : properties)
Alpana Kumari32bee762019-04-25 04:47:57 -0500333 {
334 if (property.first == "Functional")
335 {
Santosh Puranik94e1b822019-07-24 04:48:32 -0500336 accFunctional = std::get_if<bool>(&property.second);
Alpana Kumari32bee762019-04-25 04:47:57 -0500337 }
338 else if (property.first == "Present")
339 {
Santosh Puranik94e1b822019-07-24 04:48:32 -0500340 accPresent = std::get_if<bool>(&property.second);
Alpana Kumari32bee762019-04-25 04:47:57 -0500341 }
342 }
343
Alpana Kumari657877c2020-02-24 02:24:07 -0600344 if ((accPresent != nullptr) && (*accPresent == false))
Alpana Kumari32bee762019-04-25 04:47:57 -0500345 {
Alpana Kumari657877c2020-02-24 02:24:07 -0600346 aResp->res.jsonValue["Status"]["State"] = "Absent";
347 aResp->res.jsonValue["Status"]["Health"] = "OK";
Alpana Kumari32bee762019-04-25 04:47:57 -0500348 }
349 else
350 {
Alpana Kumari657877c2020-02-24 02:24:07 -0600351 aResp->res.jsonValue["Status"]["State"] = "Enabled";
352
353 if ((accFunctional != nullptr) && (*accFunctional == false))
354 {
355 aResp->res.jsonValue["Status"]["Health"] = "Critical";
356 }
357 else
358 {
359 aResp->res.jsonValue["Status"]["Health"] = "OK";
360 }
Alpana Kumari32bee762019-04-25 04:47:57 -0500361 }
Alpana Kumari32bee762019-04-25 04:47:57 -0500362 aResp->res.jsonValue["ProcessorType"] = "Accelerator";
363 },
364 service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
365}
366
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500367void getCpuData(std::shared_ptr<AsyncResp> aResp, const std::string& cpuId,
368 const std::vector<const char*> inventoryItems)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200369{
370 BMCWEB_LOG_DEBUG << "Get available system cpu resources.";
Alpana Kumari32bee762019-04-25 04:47:57 -0500371
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200372 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -0800373 [cpuId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200374 const boost::system::error_code ec,
375 const boost::container::flat_map<
376 std::string, boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500377 std::string, std::vector<std::string>>>&
378 subtree) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200379 if (ec)
380 {
381 BMCWEB_LOG_DEBUG << "DBUS response error";
382 messages::internalError(aResp->res);
383 return;
384 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500385 for (const auto& object : subtree)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200386 {
387 if (boost::ends_with(object.first, cpuId))
388 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500389 for (const auto& service : object.second)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200390 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500391 for (const auto& inventory : service.second)
Zhikui Ren5e54a362020-07-13 15:31:38 -0700392 {
393 if (inventory == "xyz.openbmc_project."
394 "Inventory.Decorator.Asset")
395 {
396 getCpuAssetData(aResp, service.first,
397 object.first);
398 }
399 else if (inventory ==
400 "xyz.openbmc_project.Inventory.Item.Cpu")
Alpana Kumari32bee762019-04-25 04:47:57 -0500401 {
402 getCpuDataByService(aResp, cpuId, service.first,
403 object.first);
404 }
405 else if (inventory == "xyz.openbmc_project."
406 "Inventory.Item.Accelerator")
407 {
408 getAcceleratorDataByService(
409 aResp, cpuId, service.first, object.first);
410 }
Zhikui Ren5e54a362020-07-13 15:31:38 -0700411 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200412 }
Zhikui Ren5e54a362020-07-13 15:31:38 -0700413 return;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200414 }
415 }
416 // Object not found
417 messages::resourceNotFound(aResp->res, "Processor", cpuId);
418 return;
419 },
420 "xyz.openbmc_project.ObjectMapper",
421 "/xyz/openbmc_project/object_mapper",
422 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -0700423 "/xyz/openbmc_project/inventory", 0, inventoryItems);
424}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200425
426void getDimmDataByService(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500427 const std::string& dimmId, const std::string& service,
428 const std::string& objPath)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200429{
James Feist35e257a2020-06-05 13:30:51 -0700430 auto health = std::make_shared<HealthPopulate>(aResp);
431 health->selfPath = objPath;
432 health->populate();
433
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200434 BMCWEB_LOG_DEBUG << "Get available system components.";
435 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -0800436 [dimmId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200437 const boost::system::error_code ec,
438 const boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500439 std::string, std::variant<std::string, uint32_t, uint16_t>>&
440 properties) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200441 if (ec)
442 {
443 BMCWEB_LOG_DEBUG << "DBUS response error";
444 messages::internalError(aResp->res);
445
446 return;
447 }
448 aResp->res.jsonValue["Id"] = dimmId;
449 aResp->res.jsonValue["Name"] = "DIMM Slot";
450
451 const auto memorySizeProperty = properties.find("MemorySizeInKB");
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600452 if (memorySizeProperty != properties.end())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200453 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500454 const uint32_t* memorySize =
Ed Tanousabf2add2019-01-22 16:40:12 -0800455 std::get_if<uint32_t>(&memorySizeProperty->second);
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600456 if (memorySize == nullptr)
457 {
458 // Important property not in desired type
459 messages::internalError(aResp->res);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200460
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600461 return;
462 }
463 if (*memorySize == 0)
464 {
465 // Slot is not populated, set status end return
466 aResp->res.jsonValue["Status"]["State"] = "Absent";
467 aResp->res.jsonValue["Status"]["Health"] = "OK";
468 // HTTP Code will be set up automatically, just return
469 return;
470 }
471 aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200472 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200473 aResp->res.jsonValue["Status"]["State"] = "Enabled";
474 aResp->res.jsonValue["Status"]["Health"] = "OK";
475
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500476 for (const auto& property : properties)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200477 {
478 if (property.first == "MemoryDataWidth")
479 {
480 aResp->res.jsonValue["DataWidthBits"] = property.second;
481 }
Manojkiran Eda7e236ca2019-06-25 23:06:32 +0530482 else if (property.first == "PartNumber")
483 {
484 aResp->res.jsonValue["PartNumber"] = property.second;
485 }
486 else if (property.first == "SerialNumber")
487 {
488 aResp->res.jsonValue["SerialNumber"] = property.second;
489 }
490 else if (property.first == "Manufacturer")
491 {
492 aResp->res.jsonValue["Manufacturer"] = property.second;
493 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200494 else if (property.first == "MemoryType")
495 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500496 const auto* value =
Ed Tanousabf2add2019-01-22 16:40:12 -0800497 std::get_if<std::string>(&property.second);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200498 if (value != nullptr)
499 {
500 aResp->res.jsonValue["MemoryDeviceType"] = *value;
501 if (boost::starts_with(*value, "DDR"))
502 {
503 aResp->res.jsonValue["MemoryType"] = "DRAM";
504 }
505 }
506 }
507 }
508 },
509 service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
510}
511
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500512void getDimmData(std::shared_ptr<AsyncResp> aResp, const std::string& dimmId)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200513{
514 BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
515 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -0800516 [dimmId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200517 const boost::system::error_code ec,
518 const boost::container::flat_map<
519 std::string, boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500520 std::string, std::vector<std::string>>>&
521 subtree) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200522 if (ec)
523 {
524 BMCWEB_LOG_DEBUG << "DBUS response error";
525 messages::internalError(aResp->res);
526
527 return;
528 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500529 for (const auto& object : subtree)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200530 {
531 if (boost::ends_with(object.first, dimmId))
532 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500533 for (const auto& service : object.second)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200534 {
Ed Tanous029573d2019-02-01 10:57:49 -0800535 getDimmDataByService(aResp, dimmId, service.first,
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200536 object.first);
537 return;
538 }
539 }
540 }
541 // Object not found
542 messages::resourceNotFound(aResp->res, "Memory", dimmId);
543 return;
544 },
545 "xyz.openbmc_project.ObjectMapper",
546 "/xyz/openbmc_project/object_mapper",
547 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -0700548 "/xyz/openbmc_project/inventory", 0,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500549 std::array<const char*, 1>{"xyz.openbmc_project.Inventory.Item.Dimm"});
Ed Tanous271584a2019-07-09 16:24:22 -0700550}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200551
552class ProcessorCollection : public Node
553{
554 public:
555 /*
556 * Default Constructor
557 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500558 ProcessorCollection(CrowApp& app) :
Ed Tanous029573d2019-02-01 10:57:49 -0800559 Node(app, "/redfish/v1/Systems/system/Processors/")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200560 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200561 entityPrivileges = {
562 {boost::beast::http::verb::get, {{"Login"}}},
563 {boost::beast::http::verb::head, {{"Login"}}},
564 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
565 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
566 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
567 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
568 }
569
570 private:
571 /**
572 * Functions triggers appropriate requests on DBus
573 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500574 void doGet(crow::Response& res, const crow::Request& req,
575 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200576 {
Ed Tanous0f74e642018-11-12 15:17:05 -0800577 res.jsonValue["@odata.type"] =
578 "#ProcessorCollection.ProcessorCollection";
579 res.jsonValue["Name"] = "Processor Collection";
Ed Tanous0f74e642018-11-12 15:17:05 -0800580
Ed Tanous029573d2019-02-01 10:57:49 -0800581 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Processors/";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200582 auto asyncResp = std::make_shared<AsyncResp>(res);
583
Ed Tanous029573d2019-02-01 10:57:49 -0800584 getResourceList(asyncResp, "Processors",
Alpana Kumari32bee762019-04-25 04:47:57 -0500585 {"xyz.openbmc_project.Inventory.Item.Cpu",
586 "xyz.openbmc_project.Inventory.Item.Accelerator"});
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200587 }
588};
589
590class Processor : public Node
591{
592 public:
593 /*
594 * Default Constructor
595 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500596 Processor(CrowApp& app) :
Ed Tanous029573d2019-02-01 10:57:49 -0800597 Node(app, "/redfish/v1/Systems/system/Processors/<str>/", std::string())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200598 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200599 entityPrivileges = {
600 {boost::beast::http::verb::get, {{"Login"}}},
601 {boost::beast::http::verb::head, {{"Login"}}},
602 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
603 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
604 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
605 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
606 }
607
608 private:
609 /**
610 * Functions triggers appropriate requests on DBus
611 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500612 void doGet(crow::Response& res, const crow::Request& req,
613 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200614 {
615 // Check if there is required param, truly entering this shall be
616 // impossible
617 if (params.size() != 1)
618 {
619 messages::internalError(res);
620
621 res.end();
622 return;
623 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500624 const std::string& processorId = params[0];
Gunnar Millsf9dcc112020-02-13 13:19:43 -0600625 res.jsonValue["@odata.type"] = "#Processor.v1_7_0.Processor";
Ed Tanous029573d2019-02-01 10:57:49 -0800626 res.jsonValue["@odata.id"] =
Alpana Kumari32bee762019-04-25 04:47:57 -0500627 "/redfish/v1/Systems/system/Processors/" + processorId;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200628
Ed Tanous029573d2019-02-01 10:57:49 -0800629 auto asyncResp = std::make_shared<AsyncResp>(res);
630
Alpana Kumari32bee762019-04-25 04:47:57 -0500631 getCpuData(asyncResp, processorId,
632 {"xyz.openbmc_project.Inventory.Item.Cpu",
Zhikui Ren5e54a362020-07-13 15:31:38 -0700633 "xyz.openbmc_project.Inventory.Decorator.Asset",
Alpana Kumari32bee762019-04-25 04:47:57 -0500634 "xyz.openbmc_project.Inventory.Item.Accelerator"});
Ed Tanous029573d2019-02-01 10:57:49 -0800635 }
636};
637
638class MemoryCollection : public Node
639{
640 public:
641 /*
642 * Default Constructor
643 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500644 MemoryCollection(CrowApp& app) :
Ed Tanous029573d2019-02-01 10:57:49 -0800645 Node(app, "/redfish/v1/Systems/system/Memory/")
646 {
647 entityPrivileges = {
648 {boost::beast::http::verb::get, {{"Login"}}},
649 {boost::beast::http::verb::head, {{"Login"}}},
650 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
651 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
652 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
653 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
654 }
655
656 private:
657 /**
658 * Functions triggers appropriate requests on DBus
659 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500660 void doGet(crow::Response& res, const crow::Request& req,
661 const std::vector<std::string>& params) override
Ed Tanous029573d2019-02-01 10:57:49 -0800662 {
Ed Tanous0f74e642018-11-12 15:17:05 -0800663 res.jsonValue["@odata.type"] = "#MemoryCollection.MemoryCollection";
664 res.jsonValue["Name"] = "Memory Module Collection";
Ed Tanous029573d2019-02-01 10:57:49 -0800665 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Memory/";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200666 auto asyncResp = std::make_shared<AsyncResp>(res);
667
Ed Tanous029573d2019-02-01 10:57:49 -0800668 getResourceList(asyncResp, "Memory",
Alpana Kumari32bee762019-04-25 04:47:57 -0500669 {"xyz.openbmc_project.Inventory.Item.Dimm"});
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200670 }
671};
672
673class Memory : public Node
674{
675 public:
676 /*
677 * Default Constructor
678 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500679 Memory(CrowApp& app) :
Ed Tanous029573d2019-02-01 10:57:49 -0800680 Node(app, "/redfish/v1/Systems/system/Memory/<str>/", std::string())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200681 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200682 entityPrivileges = {
683 {boost::beast::http::verb::get, {{"Login"}}},
684 {boost::beast::http::verb::head, {{"Login"}}},
685 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
686 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
687 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
688 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
689 }
690
691 private:
692 /**
693 * Functions triggers appropriate requests on DBus
694 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500695 void doGet(crow::Response& res, const crow::Request& req,
696 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200697 {
698 // Check if there is required param, truly entering this shall be
699 // impossible
Ed Tanous029573d2019-02-01 10:57:49 -0800700 if (params.size() != 1)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200701 {
702 messages::internalError(res);
703 res.end();
704 return;
705 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500706 const std::string& dimmId = params[0];
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200707
Rapkiewicz, Pawelbb3d9942018-11-22 10:59:11 +0100708 res.jsonValue["@odata.type"] = "#Memory.v1_6_0.Memory";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200709 res.jsonValue["@odata.id"] =
Ed Tanous029573d2019-02-01 10:57:49 -0800710 "/redfish/v1/Systems/system/Memory/" + dimmId;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200711 auto asyncResp = std::make_shared<AsyncResp>(res);
712
Ed Tanous029573d2019-02-01 10:57:49 -0800713 getDimmData(asyncResp, dimmId);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200714 }
715};
716
717} // namespace redfish