blob: ed5e64172547df6a107d6f21af115dea3f28e5f9 [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 std::string state = "";
332
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500333 for (const auto& property : properties)
Alpana Kumari32bee762019-04-25 04:47:57 -0500334 {
335 if (property.first == "Functional")
336 {
Santosh Puranik94e1b822019-07-24 04:48:32 -0500337 accFunctional = std::get_if<bool>(&property.second);
Alpana Kumari32bee762019-04-25 04:47:57 -0500338 }
339 else if (property.first == "Present")
340 {
Santosh Puranik94e1b822019-07-24 04:48:32 -0500341 accPresent = std::get_if<bool>(&property.second);
Alpana Kumari32bee762019-04-25 04:47:57 -0500342 }
343 }
344
345 if (!accPresent || !accFunctional)
346 {
347 BMCWEB_LOG_DEBUG << "Required properties missing in DBUS "
348 "response";
349 messages::internalError(aResp->res);
350 return;
351 }
352
Santosh Puranik94e1b822019-07-24 04:48:32 -0500353 if (*accPresent && *accFunctional)
Alpana Kumari32bee762019-04-25 04:47:57 -0500354 {
355 state = "Enabled";
356 }
Santosh Puranik94e1b822019-07-24 04:48:32 -0500357 else if (*accPresent)
Alpana Kumari32bee762019-04-25 04:47:57 -0500358 {
359 state = "UnavailableOffline";
360 }
361 else
362 {
363 state = "Absent";
364 }
365 aResp->res.jsonValue["Status"]["State"] = state;
366 aResp->res.jsonValue["Status"]["Health"] = "OK";
367 aResp->res.jsonValue["ProcessorType"] = "Accelerator";
368 },
369 service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
370}
371
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500372void getCpuData(std::shared_ptr<AsyncResp> aResp, 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
431void getDimmDataByService(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500432 const std::string& dimmId, const std::string& service,
433 const std::string& objPath)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200434{
James Feist35e257a2020-06-05 13:30:51 -0700435 auto health = std::make_shared<HealthPopulate>(aResp);
436 health->selfPath = objPath;
437 health->populate();
438
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200439 BMCWEB_LOG_DEBUG << "Get available system components.";
440 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -0800441 [dimmId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200442 const boost::system::error_code ec,
443 const boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500444 std::string, std::variant<std::string, uint32_t, uint16_t>>&
445 properties) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200446 if (ec)
447 {
448 BMCWEB_LOG_DEBUG << "DBUS response error";
449 messages::internalError(aResp->res);
450
451 return;
452 }
453 aResp->res.jsonValue["Id"] = dimmId;
454 aResp->res.jsonValue["Name"] = "DIMM Slot";
455
456 const auto memorySizeProperty = properties.find("MemorySizeInKB");
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600457 if (memorySizeProperty != properties.end())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200458 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500459 const uint32_t* memorySize =
Ed Tanousabf2add2019-01-22 16:40:12 -0800460 std::get_if<uint32_t>(&memorySizeProperty->second);
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600461 if (memorySize == nullptr)
462 {
463 // Important property not in desired type
464 messages::internalError(aResp->res);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200465
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600466 return;
467 }
468 if (*memorySize == 0)
469 {
470 // Slot is not populated, set status end return
471 aResp->res.jsonValue["Status"]["State"] = "Absent";
472 aResp->res.jsonValue["Status"]["Health"] = "OK";
473 // HTTP Code will be set up automatically, just return
474 return;
475 }
476 aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200477 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200478 aResp->res.jsonValue["Status"]["State"] = "Enabled";
479 aResp->res.jsonValue["Status"]["Health"] = "OK";
480
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500481 for (const auto& property : properties)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200482 {
483 if (property.first == "MemoryDataWidth")
484 {
485 aResp->res.jsonValue["DataWidthBits"] = property.second;
486 }
Manojkiran Eda7e236ca2019-06-25 23:06:32 +0530487 else if (property.first == "PartNumber")
488 {
489 aResp->res.jsonValue["PartNumber"] = property.second;
490 }
491 else if (property.first == "SerialNumber")
492 {
493 aResp->res.jsonValue["SerialNumber"] = property.second;
494 }
495 else if (property.first == "Manufacturer")
496 {
497 aResp->res.jsonValue["Manufacturer"] = property.second;
498 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200499 else if (property.first == "MemoryType")
500 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500501 const auto* value =
Ed Tanousabf2add2019-01-22 16:40:12 -0800502 std::get_if<std::string>(&property.second);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200503 if (value != nullptr)
504 {
505 aResp->res.jsonValue["MemoryDeviceType"] = *value;
506 if (boost::starts_with(*value, "DDR"))
507 {
508 aResp->res.jsonValue["MemoryType"] = "DRAM";
509 }
510 }
511 }
512 }
513 },
514 service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
515}
516
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500517void getDimmData(std::shared_ptr<AsyncResp> aResp, const std::string& dimmId)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200518{
519 BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
520 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -0800521 [dimmId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200522 const boost::system::error_code ec,
523 const boost::container::flat_map<
524 std::string, boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500525 std::string, std::vector<std::string>>>&
526 subtree) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200527 if (ec)
528 {
529 BMCWEB_LOG_DEBUG << "DBUS response error";
530 messages::internalError(aResp->res);
531
532 return;
533 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500534 for (const auto& object : subtree)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200535 {
536 if (boost::ends_with(object.first, dimmId))
537 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500538 for (const auto& service : object.second)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200539 {
Ed Tanous029573d2019-02-01 10:57:49 -0800540 getDimmDataByService(aResp, dimmId, service.first,
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200541 object.first);
542 return;
543 }
544 }
545 }
546 // Object not found
547 messages::resourceNotFound(aResp->res, "Memory", dimmId);
548 return;
549 },
550 "xyz.openbmc_project.ObjectMapper",
551 "/xyz/openbmc_project/object_mapper",
552 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -0700553 "/xyz/openbmc_project/inventory", 0,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500554 std::array<const char*, 1>{"xyz.openbmc_project.Inventory.Item.Dimm"});
Ed Tanous271584a2019-07-09 16:24:22 -0700555}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200556
557class ProcessorCollection : public Node
558{
559 public:
560 /*
561 * Default Constructor
562 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500563 ProcessorCollection(CrowApp& app) :
Ed Tanous029573d2019-02-01 10:57:49 -0800564 Node(app, "/redfish/v1/Systems/system/Processors/")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200565 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200566 entityPrivileges = {
567 {boost::beast::http::verb::get, {{"Login"}}},
568 {boost::beast::http::verb::head, {{"Login"}}},
569 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
570 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
571 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
572 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
573 }
574
575 private:
576 /**
577 * Functions triggers appropriate requests on DBus
578 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500579 void doGet(crow::Response& res, const crow::Request& req,
580 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200581 {
Ed Tanous0f74e642018-11-12 15:17:05 -0800582 res.jsonValue["@odata.type"] =
583 "#ProcessorCollection.ProcessorCollection";
584 res.jsonValue["Name"] = "Processor Collection";
Ed Tanous0f74e642018-11-12 15:17:05 -0800585
Ed Tanous029573d2019-02-01 10:57:49 -0800586 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Processors/";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200587 auto asyncResp = std::make_shared<AsyncResp>(res);
588
Ed Tanous029573d2019-02-01 10:57:49 -0800589 getResourceList(asyncResp, "Processors",
Alpana Kumari32bee762019-04-25 04:47:57 -0500590 {"xyz.openbmc_project.Inventory.Item.Cpu",
591 "xyz.openbmc_project.Inventory.Item.Accelerator"});
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200592 }
593};
594
595class Processor : public Node
596{
597 public:
598 /*
599 * Default Constructor
600 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500601 Processor(CrowApp& app) :
Ed Tanous029573d2019-02-01 10:57:49 -0800602 Node(app, "/redfish/v1/Systems/system/Processors/<str>/", std::string())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200603 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200604 entityPrivileges = {
605 {boost::beast::http::verb::get, {{"Login"}}},
606 {boost::beast::http::verb::head, {{"Login"}}},
607 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
608 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
609 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
610 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
611 }
612
613 private:
614 /**
615 * Functions triggers appropriate requests on DBus
616 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500617 void doGet(crow::Response& res, const crow::Request& req,
618 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200619 {
620 // Check if there is required param, truly entering this shall be
621 // impossible
622 if (params.size() != 1)
623 {
624 messages::internalError(res);
625
626 res.end();
627 return;
628 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500629 const std::string& processorId = params[0];
Gunnar Millsf9dcc112020-02-13 13:19:43 -0600630 res.jsonValue["@odata.type"] = "#Processor.v1_7_0.Processor";
Ed Tanous029573d2019-02-01 10:57:49 -0800631 res.jsonValue["@odata.id"] =
Alpana Kumari32bee762019-04-25 04:47:57 -0500632 "/redfish/v1/Systems/system/Processors/" + processorId;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200633
Ed Tanous029573d2019-02-01 10:57:49 -0800634 auto asyncResp = std::make_shared<AsyncResp>(res);
635
Alpana Kumari32bee762019-04-25 04:47:57 -0500636 getCpuData(asyncResp, processorId,
637 {"xyz.openbmc_project.Inventory.Item.Cpu",
Zhikui Ren5e54a362020-07-13 15:31:38 -0700638 "xyz.openbmc_project.Inventory.Decorator.Asset",
Alpana Kumari32bee762019-04-25 04:47:57 -0500639 "xyz.openbmc_project.Inventory.Item.Accelerator"});
Ed Tanous029573d2019-02-01 10:57:49 -0800640 }
641};
642
643class MemoryCollection : public Node
644{
645 public:
646 /*
647 * Default Constructor
648 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500649 MemoryCollection(CrowApp& app) :
Ed Tanous029573d2019-02-01 10:57:49 -0800650 Node(app, "/redfish/v1/Systems/system/Memory/")
651 {
652 entityPrivileges = {
653 {boost::beast::http::verb::get, {{"Login"}}},
654 {boost::beast::http::verb::head, {{"Login"}}},
655 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
656 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
657 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
658 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
659 }
660
661 private:
662 /**
663 * Functions triggers appropriate requests on DBus
664 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500665 void doGet(crow::Response& res, const crow::Request& req,
666 const std::vector<std::string>& params) override
Ed Tanous029573d2019-02-01 10:57:49 -0800667 {
Ed Tanous0f74e642018-11-12 15:17:05 -0800668 res.jsonValue["@odata.type"] = "#MemoryCollection.MemoryCollection";
669 res.jsonValue["Name"] = "Memory Module Collection";
Ed Tanous029573d2019-02-01 10:57:49 -0800670 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Memory/";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200671 auto asyncResp = std::make_shared<AsyncResp>(res);
672
Ed Tanous029573d2019-02-01 10:57:49 -0800673 getResourceList(asyncResp, "Memory",
Alpana Kumari32bee762019-04-25 04:47:57 -0500674 {"xyz.openbmc_project.Inventory.Item.Dimm"});
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200675 }
676};
677
678class Memory : public Node
679{
680 public:
681 /*
682 * Default Constructor
683 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500684 Memory(CrowApp& app) :
Ed Tanous029573d2019-02-01 10:57:49 -0800685 Node(app, "/redfish/v1/Systems/system/Memory/<str>/", std::string())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200686 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200687 entityPrivileges = {
688 {boost::beast::http::verb::get, {{"Login"}}},
689 {boost::beast::http::verb::head, {{"Login"}}},
690 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
691 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
692 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
693 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
694 }
695
696 private:
697 /**
698 * Functions triggers appropriate requests on DBus
699 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500700 void doGet(crow::Response& res, const crow::Request& req,
701 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200702 {
703 // Check if there is required param, truly entering this shall be
704 // impossible
Ed Tanous029573d2019-02-01 10:57:49 -0800705 if (params.size() != 1)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200706 {
707 messages::internalError(res);
708 res.end();
709 return;
710 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500711 const std::string& dimmId = params[0];
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200712
Rapkiewicz, Pawelbb3d9942018-11-22 10:59:11 +0100713 res.jsonValue["@odata.type"] = "#Memory.v1_6_0.Memory";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200714 res.jsonValue["@odata.id"] =
Ed Tanous029573d2019-02-01 10:57:49 -0800715 "/redfish/v1/Systems/system/Memory/" + dimmId;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200716 auto asyncResp = std::make_shared<AsyncResp>(res);
717
Ed Tanous029573d2019-02-01 10:57:49 -0800718 getDimmData(asyncResp, dimmId);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200719 }
720};
721
722} // namespace redfish